コード例 #1
0
ファイル: mlt_producer.c プロジェクト: jliljebl/mlt
int mlt_producer_seek( mlt_producer self, mlt_position position )
{
	// Determine eof handling
	mlt_properties properties = MLT_PRODUCER_PROPERTIES( self );
	char *eof = mlt_properties_get( properties, "eof" );
	int use_points = 1 - mlt_properties_get_int( properties, "ignore_points" );

	// Recursive behaviour for cuts - repositions parent and then repositions cut
	// hence no return on this condition
	if ( mlt_producer_is_cut( self ) )
		mlt_producer_seek( mlt_producer_cut_parent( self ), position + mlt_producer_get_in( self ) );

	// Check bounds
	if ( position < 0 || mlt_producer_get_playtime( self ) == 0 )
	{
		position = 0;
	}
	else if ( use_points && ( eof == NULL || !strcmp( eof, "pause" ) ) && position >= mlt_producer_get_playtime( self ) )
	{
		mlt_producer_set_speed( self, 0 );
		position = mlt_producer_get_playtime( self ) - 1;
	}
	else if ( use_points && eof && !strcmp( eof, "loop" ) && position >= mlt_producer_get_playtime( self ) )
	{
		position = (int)position % (int)mlt_producer_get_playtime( self );
	}

	// Set the position
	mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( self ), "_position", position );

	// Calculate the absolute frame
	mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( self ), "_frame", use_points * mlt_producer_get_in( self ) + position );

	return 0;
}
コード例 #2
0
ファイル: mlt_producer.c プロジェクト: jliljebl/mlt
static int on_start_producer( mlt_parser self, mlt_producer object )
{
	mlt_properties properties = mlt_parser_properties( self );
	mlt_properties producers = mlt_properties_get_data( properties, "producers", NULL );
	mlt_producer parent = mlt_producer_cut_parent( object );
	if ( mlt_service_identify( ( mlt_service )mlt_producer_cut_parent( object ) ) == producer_type && mlt_producer_is_cut( object ) )
	{
		int ref_count = 0;
		clip_references *old_refs = NULL;
		clip_references *refs = NULL;
		char key[ 50 ];
		int count = 0;
		track_info *info = peek( self );
		sprintf( key, "%p", parent );
		mlt_properties_get_data( producers, key, &count );
		mlt_properties_set_data( producers, key, parent, ++ count, NULL, NULL );
		old_refs = mlt_properties_get_data( properties, key, &ref_count );
		refs = malloc( ( ref_count + 1 ) * sizeof( clip_references ) );
		if ( old_refs != NULL )
			memcpy( refs, old_refs, ref_count * sizeof( clip_references ) );
		mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( object ), "_clone", -1 );
		refs[ ref_count ].cut = object;
		refs[ ref_count ].start = info->position;
		refs[ ref_count ].end = info->position + mlt_producer_get_playtime( object ) - 1;
		mlt_properties_set_data( properties, key, refs, ++ ref_count, free, NULL );
		info->position += mlt_producer_get_playtime( object );
		info->length += mlt_producer_get_playtime( object );
	}
	return 0;
}
コード例 #3
0
ファイル: hello.c プロジェクト: rayl/MLT
mlt_producer create_tracks( int argc, char **argv )
{
	// Create the field
	mlt_field field = mlt_field_init( );

	// Obtain the multitrack
	mlt_multitrack multitrack = mlt_field_multitrack( field );

	// Obtain the tractor
	mlt_tractor tractor = mlt_field_tractor( field );

	// Obtain a composite transition
	mlt_transition transition = mlt_factory_transition( "composite", "10%,10%:15%x15%" );

	// Create track 0
	mlt_producer track0 = create_playlist( argc, argv );

	// Get the length of track0
	mlt_position length = mlt_producer_get_playtime( track0 );

	// Create the watermark track
	mlt_producer track1 = mlt_factory_producer( NULL, "pango:" );

	// Get the properties of track1
	mlt_properties properties = mlt_producer_properties( track1 );

	// Set the properties
	mlt_properties_set( properties, "text", "Hello\nWorld" );
	mlt_properties_set_position( properties, "in", 0 );
	mlt_properties_set_position( properties, "out", length - 1 );
	mlt_properties_set_position( properties, "length", length );

	// Now set the properties on the transition
	properties = mlt_transition_properties( transition );
	mlt_properties_set_position( properties, "in", 0 );
	mlt_properties_set_position( properties, "out", length - 1 );

	// Add our tracks to the multitrack
	mlt_multitrack_connect( multitrack, track0, 0 );
	mlt_multitrack_connect( multitrack, track1, 1 );

	// Now plant the transition
	mlt_field_plant_transition( field, transition, 0, 1 );

	// Now set the properties on the transition
	properties = mlt_tractor_properties( tractor );

	// Ensure clean up and set properties correctly
	mlt_properties_set_data( properties, "multitrack", multitrack, 0, ( mlt_destructor )mlt_multitrack_close, NULL );
	mlt_properties_set_data( properties, "field", field, 0, ( mlt_destructor )mlt_field_close, NULL );
	mlt_properties_set_data( properties, "track0", track0, 0, ( mlt_destructor )mlt_producer_close, NULL );
	mlt_properties_set_data( properties, "track1", track1, 0, ( mlt_destructor )mlt_producer_close, NULL );
	mlt_properties_set_data( properties, "transition", transition, 0, ( mlt_destructor )mlt_transition_close, NULL );
	mlt_properties_set_position( properties, "length", length );
	mlt_properties_set_position( properties, "out", length - 1 );

	// Return the tractor
	return mlt_tractor_producer( tractor );
}
コード例 #4
0
ファイル: VEditMltRun.cpp プロジェクト: amongll/AVFX
uint32_t MltRuntime::get_frame_length() throw (Exception)
{
	Lock lk(&run_lock);
	if (producer)
		return mlt_producer_get_playtime(producer);
	else
		throw_error_v(ErrorRuntimeStatusError, "not loaded.");
}
コード例 #5
0
ファイル: mlt_multitrack.c プロジェクト: vpinon/mlt
void mlt_multitrack_refresh( mlt_multitrack self )
{
	int i = 0;

	// Obtain the properties of this multitrack
	mlt_properties properties = MLT_MULTITRACK_PROPERTIES( self );

	// We need to ensure that the multitrack reports the longest track as its length
	mlt_position length = 0;

	// Obtain stats on all connected services
	for ( i = 0; i < self->count; i ++ )
	{
		// Get the producer from this index
		mlt_track track = self->list[ i ];
		mlt_producer producer = track->producer;

		// If it's allocated then, update our stats
		if ( producer != NULL )
		{
			// If we have more than 1 track, we must be in continue mode
			if ( self->count > 1 )
				mlt_properties_set( MLT_PRODUCER_PROPERTIES( producer ), "eof", "continue" );

			// Determine the longest length
			//if ( !mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "hide" ) )
				length = mlt_producer_get_playtime( producer ) > length ? mlt_producer_get_playtime( producer ) : length;
		}
	}

	// Update multitrack properties now - we'll not destroy the in point here
	mlt_events_block( properties, properties );
	mlt_properties_set_position( properties, "length", length );
	mlt_events_unblock( properties, properties );
	mlt_properties_set_position( properties, "out", length - 1 );
}
コード例 #6
0
ファイル: producer_decklink.cpp プロジェクト: gmarco/mlt-orig
static int get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
    DeckLinkProducer* decklink = (DeckLinkProducer*) producer->child;
    mlt_position pos = mlt_producer_position( producer );
    mlt_position end = mlt_producer_get_playtime( producer );
    end = ( mlt_producer_get_length( producer ) < end ? mlt_producer_get_length( producer ) : end ) - 1;

    // Re-open if needed
    if ( !decklink && pos < end )
    {
        producer->child = decklink = new DeckLinkProducer();
        decklink->setProducer( producer );
        decklink->open(	mlt_properties_get_int( MLT_PRODUCER_PROPERTIES(producer), "resource" ) );
    }

    // Start if needed
    if ( decklink )
    {
        decklink->start( mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ) );

        // Get the next frame from the decklink object
        if ( ( *frame = decklink->getFrame() ))
        {
            // Add audio and video getters
            mlt_frame_push_audio( *frame, (void*) get_audio );
            mlt_frame_push_get_image( *frame, get_image );
        }
    }
    if ( !*frame )
        *frame = mlt_frame_init( MLT_PRODUCER_SERVICE(producer) );

    // Calculate the next timecode
    mlt_producer_prepare_next( producer );

    // Close DeckLink if at end
    if ( pos >= end && decklink )
    {
        decklink->stop();
        delete decklink;
        producer->child = NULL;
    }

    return 0;
}
コード例 #7
0
ファイル: consumer_sdl_preview.c プロジェクト: amongll/AVFX
static void *consumer_thread( void *arg )
{
	// Identify the arg
	consumer_sdl self = arg;

	// Get the consumer
	mlt_consumer consumer = &self->parent;

	// Get the properties
	mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );

	// internal intialization
	mlt_frame frame = NULL;
	int last_position = -1;
	int eos = 0;
	int eos_threshold = 20;
	if ( self->play )
		eos_threshold = eos_threshold + mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( self->play ), "buffer" );

	// Determine if the application is dealing with the preview
	int preview_off = mlt_properties_get_int( properties, "preview_off" );

	pthread_mutex_lock( &self->refresh_mutex );
	self->refresh_count = 0;
	pthread_mutex_unlock( &self->refresh_mutex );

	// Loop until told not to
	while( self->running )
	{
		// Get a frame from the attached producer
		frame = mlt_consumer_get_frame( consumer );

		// Ensure that we have a frame
		if ( self->running && frame != NULL )
		{
			// Get the speed of the frame
			double speed = mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" );

			// Lock during the operation
			mlt_service_lock( MLT_CONSUMER_SERVICE( consumer ) );

			// Get refresh request for the current frame
			int refresh = mlt_properties_get_int( properties, "refresh" );

			// Decrement refresh and clear changed
			mlt_events_block( properties, properties );
			mlt_properties_set_int( properties, "refresh", 0 );
			mlt_events_unblock( properties, properties );

			// Unlock after the operation
			mlt_service_unlock( MLT_CONSUMER_SERVICE( consumer ) );

			// Set the changed property on this frame for the benefit of still
			mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "refresh", refresh );

			// Make sure the recipient knows that this frame isn't really rendered
			mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "rendered", 0 );

			// Optimisation to reduce latency
			if ( speed == 1.0 )
			{
				if ( last_position != -1 && last_position + 1 != mlt_frame_get_position( frame ) )
					mlt_consumer_purge( self->play );
				last_position = mlt_frame_get_position( frame );
			}
			else
			{
				//mlt_consumer_purge( self->play );
				last_position = -1;
			}

			// If we aren't playing normally, then use the still
			if ( speed != 1 )
			{
				mlt_producer producer = MLT_PRODUCER( mlt_service_get_producer( MLT_CONSUMER_SERVICE( consumer ) ) );
				mlt_position duration = producer? mlt_producer_get_playtime( producer ) : -1;
				int pause = 0;

#ifndef SKIP_WAIT_EOS
				if ( self->active == self->play )
				{
					// Do not interrupt the play consumer near the end
					if ( duration - self->last_position > eos_threshold )
					{
						// Get a new frame at the sought position
						mlt_frame_close( frame );
						if ( producer )
							mlt_producer_seek( producer, self->last_position );
						frame = mlt_consumer_get_frame( consumer );
						pause = 1;
					}
					else
					{
						// Send frame with speed 0 to stop it
						if ( frame && !mlt_consumer_is_stopped( self->play ) )
						{
							mlt_consumer_put_frame( self->play, frame );
							frame = NULL;
							eos = 1;
						}

						// Check for end of stream
						if ( mlt_consumer_is_stopped( self->play ) )
						{
							// Stream has ended
							mlt_log_verbose( MLT_CONSUMER_SERVICE( consumer ), "END OF STREAM\n" );
							pause = 1;
							eos = 0; // reset eos indicator
						}
						else
						{
							// Prevent a tight busy loop
							struct timespec tm = { 0, 100000L }; // 100 usec
							nanosleep( &tm, NULL );
						}
					}
				}
#else
				pause = self->active == self->play;
#endif
				if ( pause )
				{
					// Start the still consumer
					if ( !mlt_consumer_is_stopped( self->play ) )
						mlt_consumer_stop( self->play );
					self->last_speed = speed;
					self->active = self->still;
					self->ignore_change = 0;
					mlt_consumer_start( self->still );
				}
				// Send the frame to the active child
				if ( frame && !eos )
				{
					mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "refresh", 1 );
					if ( self->active )
						mlt_consumer_put_frame( self->active, frame );
				}
				if ( pause && speed == 0.0 )
				{
					mlt_events_fire( properties, "consumer-sdl-paused", NULL );
				}
			}
			// Allow a little grace time before switching consumers on speed changes
			else if ( self->ignore_change -- > 0 && self->active != NULL && !mlt_consumer_is_stopped( self->active ) )
			{
				mlt_consumer_put_frame( self->active, frame );
			}
			// Otherwise use the normal player
			else
			{
				if ( !mlt_consumer_is_stopped( self->still ) )
					mlt_consumer_stop( self->still );
				if ( mlt_consumer_is_stopped( self->play ) )
				{
					self->last_speed = speed;
					self->active = self->play;
					self->ignore_change = 0;
					mlt_consumer_start( self->play );
				}
				if ( self->play )
					mlt_consumer_put_frame( self->play, frame );
			}

			// Copy the rectangle info from the active consumer
			if ( self->running && preview_off == 0 && self->active )
			{
				mlt_properties active = MLT_CONSUMER_PROPERTIES( self->active );
				mlt_service_lock( MLT_CONSUMER_SERVICE( consumer ) );
				mlt_properties_set_int( properties, "rect_x", mlt_properties_get_int( active, "rect_x" ) );
				mlt_properties_set_int( properties, "rect_y", mlt_properties_get_int( active, "rect_y" ) );
				mlt_properties_set_int( properties, "rect_w", mlt_properties_get_int( active, "rect_w" ) );
				mlt_properties_set_int( properties, "rect_h", mlt_properties_get_int( active, "rect_h" ) );
				mlt_service_unlock( MLT_CONSUMER_SERVICE( consumer ) );
			}

			if ( self->active == self->still )
			{
				pthread_mutex_lock( &self->refresh_mutex );
				if ( self->running && speed == 0 && self->refresh_count <= 0 )
				{
					mlt_events_fire( properties, "consumer-sdl-paused", NULL );
					pthread_cond_wait( &self->refresh_cond, &self->refresh_mutex );
				}
				self->refresh_count --;
				pthread_mutex_unlock( &self->refresh_mutex );
			}
		}
		else
		{
			if ( frame ) mlt_frame_close( frame );
			mlt_consumer_put_frame( self->active, NULL );
			self->running = 0;
		}
	}

	if ( self->play ) mlt_consumer_stop( self->play );
	if ( self->still ) mlt_consumer_stop( self->still );

	return NULL;
}
コード例 #8
0
ファイル: producer_framebuffer.c プロジェクト: mcfrisk/mlt
static int framebuffer_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
{

	// Get the filter object and properties
	mlt_producer producer = mlt_frame_pop_service( frame );
	int index = ( int )mlt_frame_pop_service( frame );
	mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );

	mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) );

	// Frame properties objects
	mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
	mlt_frame first_frame = mlt_properties_get_data( properties, "first_frame", NULL );

	// Get producer parameters
	int strobe = mlt_properties_get_int( properties, "strobe" );
	int freeze = mlt_properties_get_int( properties, "freeze" );
	int freeze_after = mlt_properties_get_int( properties, "freeze_after" );
	int freeze_before = mlt_properties_get_int( properties, "freeze_before" );
	int in = mlt_properties_get_position( properties, "in" );

	// Determine the position
	mlt_position first_position = (first_frame != NULL) ? mlt_frame_get_position( first_frame ) : -1;
	mlt_position need_first = freeze;

	if ( !freeze || freeze_after || freeze_before )
	{
		double prod_speed = mlt_properties_get_double( properties, "_speed" );
		double actual_position = in + prod_speed * (double) mlt_producer_position( producer );

		if ( mlt_properties_get_int( properties, "reverse" ) )
			actual_position = mlt_producer_get_playtime( producer ) - actual_position;

		if ( strobe < 2 )
		{
			need_first = floor( actual_position );
		}
		else
		{
			// Strobe effect wanted, calculate frame position
			need_first = floor( actual_position );
			need_first -= need_first % strobe;
		}
		if ( freeze )
		{
			if ( freeze_after && need_first > freeze ) need_first = freeze;
			else if ( freeze_before && need_first < freeze ) need_first = freeze;
		}
	}
	
	// Determine output buffer size
	*width = mlt_properties_get_int( frame_properties, "width" );
	*height = mlt_properties_get_int( frame_properties, "height" );
	int size = mlt_image_format_size( *format, *width, *height, NULL );

	// Get output buffer
	int buffersize = 0;
        int alphasize = *width * *height;
	uint8_t *output = mlt_properties_get_data( properties, "output_buffer", &buffersize );
        uint8_t *output_alpha = mlt_properties_get_data( properties, "output_alpha", NULL );
	if( buffersize == 0 || buffersize != size )
	{
		// invalidate cached frame
		first_position = -1;
	}

	if ( need_first != first_position )
	{
		// invalidate cached frame
		first_position = -1;
		
		// Bust the cached frame
		mlt_properties_set_data( properties, "first_frame", NULL, 0, NULL, NULL );
		first_frame = NULL;
	}

	if ( output && first_position != -1 ) {
		// Using the cached frame
	  	uint8_t *image_copy = mlt_pool_alloc( size );
		memcpy( image_copy, output, size );
                uint8_t *alpha_copy = mlt_pool_alloc( alphasize );
                memcpy( alpha_copy, output_alpha, alphasize );

		// Set the output image
		*image = image_copy;
		mlt_frame_set_image( frame, image_copy, size, mlt_pool_release );
                mlt_frame_set_alpha( frame, alpha_copy, alphasize, mlt_pool_release );

		*width = mlt_properties_get_int( properties, "_output_width" );
		*height = mlt_properties_get_int( properties, "_output_height" );
		*format = mlt_properties_get_int( properties, "_output_format" );

		mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
		return 0;
	}

	// Get the cached frame
	if ( first_frame == NULL )
	{
		// Get the frame to cache from the real producer
		mlt_producer real_producer = mlt_properties_get_data( properties, "producer", NULL );

		// Seek the producer to the correct place
		mlt_producer_seek( real_producer, need_first );

		// Get the frame
		mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &first_frame, index );

		// Cache the frame
		mlt_properties_set_data( properties, "first_frame", first_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
	}
	mlt_properties first_frame_properties = MLT_FRAME_PROPERTIES( first_frame );


	// Which frames are buffered?
	uint8_t *first_image = mlt_properties_get_data( first_frame_properties, "image", NULL );
        uint8_t *first_alpha = mlt_properties_get_data( first_frame_properties, "alpha", NULL );
	if ( !first_image )
	{
		mlt_properties_set( first_frame_properties, "rescale.interp", mlt_properties_get( frame_properties, "rescale.interp" ) );

		int error = mlt_frame_get_image( first_frame, &first_image, format, width, height, writable );

		if ( error != 0 ) {
			mlt_log_error( MLT_PRODUCER_SERVICE( producer ), "first_image == NULL get image died\n" );
			mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
			return error;
		}
		output = mlt_pool_alloc( size );
		memcpy( output, first_image, size );
		// Let someone else clean up
		mlt_properties_set_data( properties, "output_buffer", output, size, mlt_pool_release, NULL ); 
		mlt_properties_set_int( properties, "_output_width", *width );
		mlt_properties_set_int( properties, "_output_height", *height );
		mlt_properties_set_int( properties, "_output_format", *format );
	
	}

	if ( !first_alpha )
        {
                alphasize = *width * *height;
                first_alpha = mlt_frame_get_alpha_mask( first_frame );
                output_alpha = mlt_pool_alloc( alphasize );
                memcpy( output_alpha, first_alpha, alphasize );
                mlt_properties_set_data( properties, "output_alpha", output_alpha, alphasize, mlt_pool_release, NULL ); 
        }

	mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );

	// Create a copy
	uint8_t *image_copy = mlt_pool_alloc( size );
	memcpy( image_copy, first_image, size );
        uint8_t *alpha_copy = mlt_pool_alloc( alphasize );
        memcpy( alpha_copy, first_alpha, alphasize );

	// Set the output image
	*image = image_copy;
	mlt_frame_set_image( frame, *image, size, mlt_pool_release );

	mlt_frame_set_alpha( frame, alpha_copy, alphasize, mlt_pool_release );

	return 0;
}
コード例 #9
0
ファイル: service_manager.cpp プロジェクト: metellius/webvfx
 bool isPositionValid(mlt_position position) {
     return position < mlt_producer_get_playtime(producer);
 }