示例#1
0
mlt_producer producer_consumer_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
	mlt_producer self = mlt_producer_new( profile );

	// Encapsulate the real producer
	mlt_profile temp_profile = mlt_profile_clone( profile );
	temp_profile->is_explicit = 0;
	mlt_producer real_producer = mlt_factory_producer( temp_profile, NULL, arg );

	if ( self && real_producer )
	{
		// Override some producer methods
		self->close = ( mlt_destructor )producer_close;
		self->get_frame = get_frame;
		
		// Get the properties of this producer
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( self );
		mlt_properties_set( properties, "resource", arg );
		mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( real_producer ), "out, length" );

		// Done with the producer - will re-open later when we have the profile property
		mlt_producer_close( real_producer );
	}
	else
	{
		if ( self )
			mlt_producer_close( self );
		if ( real_producer )
			mlt_producer_close( real_producer );

		self = NULL;
	}
	mlt_profile_close( temp_profile );
	return self;
}
示例#2
0
int mlt_producer_set_in_and_out( mlt_producer self, mlt_position in, mlt_position out )
{
	mlt_properties properties = MLT_PRODUCER_PROPERTIES( self );

	// Correct ins and outs if necessary
	if ( in < 0 )
		in = 0;
	else if ( in >= mlt_producer_get_length( self ) )
		in = mlt_producer_get_length( self ) - 1;

	if ( ( out < 0 || out >= mlt_producer_get_length( self ) ) && !mlt_producer_is_blank( self ) )
		out = mlt_producer_get_length( self ) - 1;
	else if ( ( out < 0 || out >= mlt_producer_get_length( self ) ) && mlt_producer_is_blank( self ) )
		mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( self ), "length", out + 1 );
	else if ( out < 0 )
		out = 0;

	// Swap ins and outs if wrong
	if ( out < in )
	{
		mlt_position t = in;
		in = out;
		out = t;
	}

	// Set the values
	mlt_events_block( properties, properties );
	mlt_properties_set_position( properties, "in", in );
	mlt_events_unblock( properties, properties );
	mlt_properties_set_position( properties, "out", out );

	return 0;
}
示例#3
0
void mlt_producer_close( mlt_producer self )
{
	if ( self != NULL && mlt_properties_dec_ref( MLT_PRODUCER_PROPERTIES( self ) ) <= 0 )
	{
		self->parent.close = NULL;

		if ( self->close != NULL )
		{
			self->close( self->close_object );
		}
		else
		{
			int destroy = mlt_producer_is_cut( self );

#if _MLT_PRODUCER_CHECKS_ == 1
			// Show debug info
			mlt_properties_debug( MLT_PRODUCER_PROPERTIES( self ), "Producer closing", stderr );
#endif

#ifdef _MLT_PRODUCER_CHECKS_
			// Show current stats - these should match when the app is closed
			mlt_log( MLT_PRODUCER_SERVICE( self ), MLT_LOG_DEBUG, "Producers created %d, destroyed %d\n", producers_created, ++producers_destroyed );
#endif

			mlt_service_close( &self->parent );

			if ( destroy )
				free( self );
		}
	}
}
示例#4
0
mlt_producer mlt_producer_cut( mlt_producer self, int in, int out )
{
	mlt_producer result = mlt_producer_new( mlt_service_profile( MLT_PRODUCER_SERVICE( self ) ) );
	mlt_producer parent = mlt_producer_cut_parent( self );
	mlt_properties properties = MLT_PRODUCER_PROPERTIES( result );
	mlt_properties parent_props = MLT_PRODUCER_PROPERTIES( parent );

	mlt_properties_set_lcnumeric( properties,
		mlt_properties_get_lcnumeric( MLT_PRODUCER_PROPERTIES( self ) ) );

	mlt_events_block( MLT_PRODUCER_PROPERTIES( result ), MLT_PRODUCER_PROPERTIES( result ) );
	// Special case - allow for a cut of the entire producer (this will squeeze all other cuts to 0)
	if ( in <= 0 )
		in = 0;
	if ( ( out < 0 || out >= mlt_producer_get_length( parent ) ) && !mlt_producer_is_blank( self ) )
		out = mlt_producer_get_length( parent ) - 1;

	mlt_properties_inc_ref( parent_props );
	mlt_properties_set_int( properties, "_cut", 1 );
	mlt_properties_set_data( properties, "_cut_parent", parent, 0, ( mlt_destructor )mlt_producer_close, NULL );
	mlt_properties_set_position( properties, "length", mlt_properties_get_position( parent_props, "length" ) );
	mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( parent_props, "aspect_ratio" ) );
	mlt_producer_set_in_and_out( result, in, out );

	return result;
}
示例#5
0
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;
}
示例#6
0
static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index )
{
	// Get the mutiltrack object
	mlt_multitrack self = parent->child;

	// Check if we have a track for this index
	if ( index >= 0 && index < self->count && self->list[ index ] != NULL )
	{
		// Get the producer for this track
		mlt_producer producer = self->list[ index ]->producer;

		// Get the track hide property
		int hide = mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( producer ) ), "hide" );

		// Obtain the current position
		mlt_position position = mlt_producer_frame( parent );

		// Get the parent properties
		mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( parent );

		// Get the speed
		double speed = mlt_properties_get_double( producer_properties, "_speed" );

		// Make sure we're at the same point
		mlt_producer_seek( producer, position );

		// Get the frame from the producer
		mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), frame, 0 );

		// Indicate speed of this producer
		mlt_properties properties = MLT_FRAME_PROPERTIES( *frame );
		mlt_properties_set_double( properties, "_speed", speed );
		mlt_frame_set_position( *frame, position );
		mlt_properties_set_int( properties, "hide", hide );
	}
	else
	{
		// Generate a test frame
		*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( parent ) );

		// Update position on the frame we're creating
		mlt_frame_set_position( *frame, mlt_producer_position( parent ) );

		// Move on to the next frame
		if ( index >= self->count )
		{
			// Let tractor know if we've reached the end
			mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "last_track", 1 );

			// Move to the next frame
			mlt_producer_prepare_next( parent );
		}
	}

	return 0;
}
示例#7
0
int mlt_multitrack_insert( mlt_multitrack self, mlt_producer producer, int track )
{
	if ( track >= self->count )
		return mlt_multitrack_connect( self, producer, track );

	// Connect to the producer to ourselves at the specified track
	int result = mlt_service_insert_producer( MLT_MULTITRACK_SERVICE( self ), MLT_PRODUCER_SERVICE( producer ), track );

	if ( result == 0 )
	{
		// Resize the producer list if needed.
		if ( self->count + 1 > self->size )
		{
			int new_size = self->size + 10;
			self->list = realloc( self->list, new_size * sizeof( mlt_track ) );
			if ( self->list )
			{
				memset( &self->list[ self->size ], 0, new_size - self->size );
				self->size = new_size;
			}
		}

		if ( self->list )
		{
			// Move all of the list elements following track N down by 1.
			memmove( &self->list[ track + 1 ], &self->list[ track ],
					( self->count - track ) * sizeof ( mlt_track ) );
			self->count ++;

			// Assign the track in our list.
			self->list[ track ] = malloc( sizeof( struct mlt_track_s ) );
			self->list[ track ]->producer = producer;
			self->list[ track ]->event = mlt_events_listen( MLT_PRODUCER_PROPERTIES( producer ), self,
										 "producer-changed", ( mlt_listener )mlt_multitrack_listener );
			mlt_properties_inc_ref( MLT_PRODUCER_PROPERTIES( producer ) );
			mlt_event_inc_ref( self->list[ track ]->event );

			// TODO: Move this into producer_avformat.c when mlt_events broadcasting is available.
			if ( self->count > mlt_service_cache_get_size( MLT_MULTITRACK_SERVICE( self ), "producer_avformat" ) )
				mlt_service_cache_set_size( MLT_MULTITRACK_SERVICE( self ), "producer_avformat", self->count + 1 );

			// Refresh our stats
			mlt_multitrack_refresh( self );
		}
		else
		{
			result = -1;
		}
	}

	return result;
}
示例#8
0
mlt_producer mlt_producer_new( mlt_profile profile )
{
	mlt_producer self = malloc( sizeof( struct mlt_producer_s ) );
	if ( self )
	{
		if ( mlt_producer_init( self, NULL ) == 0 )
		{
			mlt_properties_set_data( MLT_PRODUCER_PROPERTIES( self ), "_profile", profile, 0, NULL, NULL );
			mlt_properties_set_double( MLT_PRODUCER_PROPERTIES( self ), "aspect_ratio", mlt_profile_sar( profile ) );
		}
	}
	return self;
}
示例#9
0
int mlt_multitrack_connect( mlt_multitrack self, mlt_producer producer, int track )
{
	// Connect to the producer to ourselves at the specified track
	int result = mlt_service_connect_producer( MLT_MULTITRACK_SERVICE( self ), MLT_PRODUCER_SERVICE( producer ), track );

	if ( result == 0 )
	{
		mlt_track current_track = ( track < self->count )? self->list[ track ] : NULL;
		// Resize the producer list if need be
		if ( track >= self->size )
		{
			int i;
			self->list = realloc( self->list, ( track + 10 ) * sizeof( mlt_track ) );
			for ( i = self->size; i < track + 10; i ++ )
				self->list[ i ] = NULL;
			self->size = track + 10;
		}

		if ( current_track )
		{
			mlt_event_close( current_track->event );
			mlt_producer_close( current_track->producer );
		}
		else
		{
			self->list[ track ] = malloc( sizeof( struct mlt_track_s ) );
		}

		// Assign the track in our list here
		self->list[ track ]->producer = producer;
		self->list[ track ]->event = mlt_events_listen( MLT_PRODUCER_PROPERTIES( producer ), self,
									 "producer-changed", ( mlt_listener )mlt_multitrack_listener );
		mlt_properties_inc_ref( MLT_PRODUCER_PROPERTIES( producer ) );
		mlt_event_inc_ref( self->list[ track ]->event );

		// Increment the track count if need be
		if ( track >= self->count )
		{
			self->count = track + 1;

			// TODO: Move this into producer_avformat.c when mlt_events broadcasting is available.
			if ( self->count > mlt_service_cache_get_size( MLT_MULTITRACK_SERVICE( self ), "producer_avformat" ) )
				mlt_service_cache_set_size( MLT_MULTITRACK_SERVICE( self ), "producer_avformat", self->count + 1 );
		}

		// Refresh our stats
		mlt_multitrack_refresh( self );
	}

	return result;
}
示例#10
0
static void add_clock_to_frame( mlt_producer producer, mlt_frame frame, time_info* info )
{
	mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) );
	mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
	uint8_t* image = NULL;
	mlt_image_format format = mlt_image_rgb24a;
	int size = 0;
	int width = profile->width;
	int height = profile->height;
	int line_width = LINE_WIDTH_RATIO * (width > height ? height : width) / 100;
	int radius = (width > height ? height : width) / 2;
	char* direction = mlt_properties_get( producer_properties, "direction" );
	int clock_angle = 0;

	mlt_frame_get_image( frame, &image, &format, &width, &height, 1 );

	// Calculate the angle for the clock.
	int frames = info->frames;
	if( !strcmp( direction, "down" ) )
	{
		frames = info->fps - info->frames - 1;
	}
	clock_angle = (frames + 1) * 360 / info->fps;

	draw_clock( image, profile, clock_angle, line_width );
	draw_cross( image, profile, line_width );
	draw_ring( image, profile, ( radius * OUTER_RING_RATIO ) / 100, line_width );
	draw_ring( image, profile, ( radius * INNER_RING_RATIO ) / 100, line_width );

	size = mlt_image_format_size( format, width, height, NULL );
	mlt_frame_set_image( frame, image, size, mlt_pool_release );
}
示例#11
0
文件: mlt_tractor.c 项目: elfring/mlt
mlt_tractor mlt_tractor_new( )
{
	mlt_tractor self = calloc( 1, sizeof( struct mlt_tractor_s ) );
	if ( self != NULL )
	{
		mlt_producer producer = &self->parent;
		if ( mlt_producer_init( producer, self ) == 0 )
		{
			mlt_multitrack multitrack = mlt_multitrack_init( );
			mlt_field field = mlt_field_new( multitrack, self );
			mlt_properties props = MLT_PRODUCER_PROPERTIES( producer );

			mlt_properties_set( props, "resource", "<tractor>" );
			mlt_properties_set( props, "mlt_type", "mlt_producer" );
			mlt_properties_set( props, "mlt_service", "tractor" );
			mlt_properties_set_position( props, "in", 0 );
			mlt_properties_set_position( props, "out", 0 );
			mlt_properties_set_position( props, "length", 0 );
			mlt_properties_set_data( props, "multitrack", multitrack, 0, ( mlt_destructor )mlt_multitrack_close, NULL );
			mlt_properties_set_data( props, "field", field, 0, ( mlt_destructor )mlt_field_close, NULL );

			mlt_events_listen( MLT_MULTITRACK_PROPERTIES( multitrack ), self, "producer-changed", ( mlt_listener )mlt_tractor_listener );

			producer->get_frame = producer_get_frame;
			producer->close = ( mlt_destructor )mlt_tractor_close;
			producer->close_object = self;
		}
		else
		{
			free( self );
			self = NULL;
		}
	}
	return self;
}
示例#12
0
static void get_time_info( mlt_producer producer, mlt_frame frame, time_info* info )
{
	mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
	mlt_position position = mlt_frame_original_position( frame );

	info->fps = ceil( mlt_producer_get_fps( producer ) );

	char* direction = mlt_properties_get( producer_properties, "direction" );
	if( !strcmp( direction, "down" ) )
	{
		mlt_position length = mlt_properties_get_int( producer_properties, "length" );
		info->position = length - 1 - position;
	}
	else
	{
		info->position = position;
	}

	char* tc_str = NULL;
	if( mlt_properties_get_int( producer_properties, "drop" ) )
	{
		tc_str = mlt_properties_frames_to_time( producer_properties, info->position, mlt_time_smpte_df );
	}
	else
	{
		tc_str = mlt_properties_frames_to_time( producer_properties, info->position, mlt_time_smpte_ndf );
	}
	sscanf( tc_str, "%02d:%02d:%02d%c%d", &info->hours, &info->minutes, &info->seconds, &info->sep, &info->frames );
}
示例#13
0
static void add_text_to_bg( mlt_producer producer, mlt_frame bg_frame, mlt_frame text_frame )
{
	mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
	mlt_transition transition = mlt_properties_get_data( producer_properties, "_transition", NULL );

	if( !transition )
	{
		mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) );
		transition = mlt_factory_transition( profile, "composite", NULL );

		// Save the transition for future use.
		mlt_properties_set_data( producer_properties, "_transition", transition, 0, ( mlt_destructor )mlt_transition_close, NULL );

		// Configure the transition.
		mlt_properties transition_properties = MLT_TRANSITION_PROPERTIES( transition );
		mlt_properties_set( transition_properties, "geometry", "0%/0%:100%x100%:100" );
		mlt_properties_set( transition_properties, "halign", "center" );
		mlt_properties_set( transition_properties, "valign", "middle" );
	}

	if( transition && bg_frame && text_frame )
	{
		// Apply the transition.
		mlt_transition_process( transition, bg_frame, text_frame );
	}
}
示例#14
0
int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
{
	// Generate a frame
	*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );

	if ( *frame != NULL )
	{
		// Obtain properties of frame and producer
		mlt_properties properties = MLT_FRAME_PROPERTIES( *frame );

		// Obtain properties of producer
		mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );

		// Set the producer on the frame properties
		mlt_properties_set_data( properties, "producer_frei0r", producer, 0, NULL, NULL );

		// Update timecode on the frame we're creating
		mlt_frame_set_position( *frame, mlt_producer_position( producer ) );

		// Set producer-specific frame properties
		mlt_properties_set_int( properties, "progressive", 1 );
		mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) );
		mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );

		// Push the get_image method
		mlt_frame_push_get_image( *frame, producer_get_image );
	}

	// Calculate the next timecode
	mlt_producer_prepare_next( producer );

	return 0;
}
示例#15
0
static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
{
	
	// Obtain properties of frame
	mlt_properties properties = MLT_FRAME_PROPERTIES( frame );

	// Obtain the producer for this frame
	mlt_producer producer = mlt_properties_get_data( properties, "producer_frei0r", NULL );

	// Obtain properties of producer
	mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );

	// Allocate the image
	int size = *width * ( *height + 1 ) * 2;

	// Allocate the image
	*buffer = mlt_pool_alloc( size );

	// Update the frame
	mlt_properties_set_data( properties, "image", *buffer, size, mlt_pool_release, NULL );
	mlt_properties_set_int( properties, "width", *width );
	mlt_properties_set_int( properties, "height", *height );

	*format = mlt_image_yuv422;
	if ( *buffer != NULL )
	{
		mlt_position in = mlt_producer_get_in( producer );
		mlt_position out = mlt_producer_get_out( producer );
		mlt_position time = mlt_frame_get_position( frame );
		double position = ( double )( time - in ) / ( double )( out - in + 1 );
		process_frei0r_item( producer_type , position, producer_props, frame , buffer, format , width , height , writable );
	}

    return 0;
}
示例#16
0
mlt_producer producer_vorbis_init( mlt_profile profile, mlt_service_type type, const char *id, char *file )
{
	mlt_producer this = NULL;

	// Check that we have a non-NULL argument
	if ( file != NULL )
	{
		// Construct the producer
		this = calloc( 1, sizeof( struct mlt_producer_s ) );

		// Initialise it
		if ( mlt_producer_init( this, NULL ) == 0 )
		{
			// Get the properties
			mlt_properties properties = MLT_PRODUCER_PROPERTIES( this );

			// Set the resource property (required for all producers)
			mlt_properties_set( properties, "resource", file );

			// Register our get_frame implementation
			this->get_frame = producer_get_frame;

			// Open the file
			if ( producer_open( this, profile, file ) != 0 )
			{
				// Clean up
				mlt_producer_close( this );
				this = NULL;
			}
		}
	}

	return this;
}
示例#17
0
文件: producer_ladspa.c 项目: aib/mlt
mlt_producer producer_ladspa_init( mlt_profile profile, mlt_service_type type, const char* id, char* arg )
{
	// Create a new producer object
	mlt_producer producer = mlt_producer_new( profile );

	if ( producer != NULL )
	{
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );

		producer->get_frame = producer_get_frame;
		producer->close = ( mlt_destructor )producer_close;

		// Save the plugin ID.
		if ( !strncmp( id, "ladspa.", 7 ) )
		{
			mlt_properties_set( properties, "_pluginid", id + 7 );
		}

		// Make sure the plugin ID is valid.
		unsigned long plugin_id = mlt_properties_get_int64( properties, "_pluginid" );
		if( plugin_id < 1000 || plugin_id > 0x00FFFFFF )
		{
			producer_close( producer );
			producer = NULL;
		}
	}
	return producer;
}
示例#18
0
static bool check_qimage( mlt_properties frame_properties )
{
	mlt_producer producer = static_cast<mlt_producer>( mlt_properties_get_data( frame_properties, "_producer_qtext", NULL ) );
	mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer );
	QImage* qImg = static_cast<QImage*>( mlt_properties_get_data( producer_properties, "_qimg", NULL ) );
	QSize target_size( mlt_properties_get_int( frame_properties, "rescale_width" ),
					   mlt_properties_get_int( frame_properties, "rescale_height" ) );
	QSize native_size( mlt_properties_get_int( frame_properties, "meta.media.width" ),
					   mlt_properties_get_int( frame_properties, "meta.media.height" ) );

	// Check if the last image signature is different from the path signature
	// for this frame.
	char* last_img_sig = mlt_properties_get( producer_properties, "_img_sig" );
	char* path_sig = mlt_properties_get( frame_properties, "_path_sig" );

	if( !last_img_sig || strcmp( path_sig, last_img_sig ) )
	{
		mlt_properties_set( producer_properties, "_img_sig", path_sig );
		return true;
	}

	// Check if the last image size matches the requested image size
	QSize output_size = target_size;
	if( output_size.isEmpty() )
	{
		output_size = native_size;
	}
	if( output_size != qImg->size() )
	{
		return true;
	}

	return false;
}
示例#19
0
mlt_producer producer_ppm_init( mlt_profile profile, mlt_service_type type, const char *id, char *command )
{
	producer_ppm this = calloc( sizeof( struct producer_ppm_s ), 1 );
	if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 )
	{
		mlt_producer producer = &this->parent;
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );

		producer->get_frame = producer_get_frame;
		producer->close = ( mlt_destructor )producer_close;

		if ( command != NULL )
		{
			mlt_properties_set( properties, "resource", command );
			this->command = strdup( command );
		}
		else
		{
			mlt_properties_set( properties, "resource", "ppm test" );
		}

		return producer;
	}
	free( this );
	return NULL;
}
示例#20
0
文件: mlt_tractor.c 项目: elfring/mlt
mlt_tractor mlt_tractor_init( )
{
	mlt_tractor self = calloc( 1, sizeof( struct mlt_tractor_s ) );
	if ( self != NULL )
	{
		mlt_producer producer = &self->parent;
		if ( mlt_producer_init( producer, self ) == 0 )
		{
			mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );

			mlt_properties_set( properties, "resource", "<tractor>" );
			mlt_properties_set( properties, "mlt_type", "mlt_producer" );
			mlt_properties_set( properties, "mlt_service", "tractor" );
			mlt_properties_set_int( properties, "in", 0 );
			mlt_properties_set_int( properties, "out", -1 );
			mlt_properties_set_int( properties, "length", 0 );

			producer->get_frame = producer_get_frame;
			producer->close = ( mlt_destructor )mlt_tractor_close;
			producer->close_object = self;
		}
		else
		{
			free( self );
			self = NULL;
		}
	}
	return self;
}
示例#21
0
static void property_changed( mlt_properties owner, mlt_consumer self, char *name )
{
	mlt_properties properties = MLT_PRODUCER_PROPERTIES(self);
	context cx = mlt_properties_get_data( properties, "context", NULL );

	if ( !cx )
		return;

	if ( name == strstr( name, CONSUMER_PROPERTIES_PREFIX ) )
		mlt_properties_set(MLT_CONSUMER_PROPERTIES( cx->consumer ), name + strlen( CONSUMER_PROPERTIES_PREFIX ),
			mlt_properties_get( properties, name ));

	if ( name == strstr( name, PRODUCER_PROPERTIES_PREFIX ) )
		mlt_properties_set(MLT_PRODUCER_PROPERTIES( cx->producer ), name + strlen( PRODUCER_PROPERTIES_PREFIX ),
			mlt_properties_get( properties, name ));
}
示例#22
0
extern void make_tempfile( producer_qimage self, const char *xml )
{
	// Generate a temporary file for the svg
	QTemporaryFile tempFile( "mlt.XXXXXX" );

	tempFile.setAutoRemove( false );
	if ( tempFile.open() )
	{
		// Write the svg into the temp file
		char *fullname = tempFile.fileName().toUtf8().data();

		// Strip leading crap
		while ( xml[0] != '<' )
			xml++;

		qint64 remaining_bytes = strlen( xml );
		while ( remaining_bytes > 0 )
			remaining_bytes -= tempFile.write( xml + strlen( xml ) - remaining_bytes, remaining_bytes );
		tempFile.close();

		mlt_properties_set( self->filenames, "0", fullname );

		mlt_properties_set_data( MLT_PRODUCER_PROPERTIES( &self->parent ), "__temporary_file__",
			fullname, 0, ( mlt_destructor )unlink, NULL );
	}
}
示例#23
0
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;
}
示例#24
0
文件: melt.c 项目: hrshadhin/mlt
static void stop_handler(int signum)
{
    if ( melt )
    {
        mlt_properties properties = MLT_PRODUCER_PROPERTIES( melt );
        mlt_properties_set_int( properties, "done", 1 );
    }
}
示例#25
0
mlt_producer mlt_producer_cut_parent( mlt_producer self )
{
	mlt_properties properties = MLT_PRODUCER_PROPERTIES( self );
	if ( mlt_producer_is_cut( self ) )
		return mlt_properties_get_data( properties, "_cut_parent", NULL );
	else
		return self;
}
示例#26
0
static QImage* reorient_with_exif( producer_qimage self, int image_idx, QImage *qimage )
{
#ifdef USE_EXIF
	mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( &self->parent );
	ExifData *d = exif_data_new_from_file( mlt_properties_get_value( self->filenames, image_idx ) );
	ExifEntry *entry;
	int exif_orientation = 0;
	/* get orientation and rotate image accordingly if necessary */
	if (d) {
		if ( ( entry = exif_content_get_entry ( d->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION ) ) )
			exif_orientation = exif_get_short (entry->data, exif_data_get_byte_order (d));

		/* Free the EXIF data */
		exif_data_unref(d);
	}

	// Remember EXIF value, might be useful for someone
	mlt_properties_set_int( producer_props, "_exif_orientation" , exif_orientation );

	if ( exif_orientation > 1 )
	{
		  // Rotate image according to exif data
		  QImage processed;
		  QMatrix matrix;

		  switch ( exif_orientation ) {
		  case 2:
			  matrix.scale( -1, 1 );
			  break;
		  case 3:
			  matrix.rotate( 180 );
			  break;
		  case 4:
			  matrix.scale( 1, -1 );
			  break;
		  case 5:
			  matrix.rotate( 270 );
			  matrix.scale( -1, 1 );
			  break;
		  case 6:
			  matrix.rotate( 90 );
			  break;
		  case 7:
			  matrix.rotate( 90 );
			  matrix.scale( -1, 1 );
			  break;
		  case 8:
			  matrix.rotate( 270 );
			  break;
		  }
		  processed = qimage->transformed( matrix );
		  delete qimage;
		  qimage = new QImage( processed );
	}
#endif
	return qimage;
}
示例#27
0
int mlt_producer_is_blank( mlt_producer self )
{
	if ( self )
	{
		const char *resource = mlt_properties_get( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( self ) ), "resource" );
		return ( resource && !strcmp( "blank", resource ) );
	}
	return ( self == NULL );
}
示例#28
0
static void mlt_producer_set_clones( mlt_producer self, int clones )
{
	mlt_producer parent = mlt_producer_cut_parent( self );
	mlt_properties properties = MLT_PRODUCER_PROPERTIES( parent );
	int existing = mlt_properties_get_int( properties, "_clones" );
	int i = 0;
	char key[ 25 ];

	// If the number of existing clones is different, then create/remove as necessary
	if ( existing != clones )
	{
		if ( existing < clones )
		{
			for ( i = existing; i < clones; i ++ )
			{
				mlt_producer clone = mlt_producer_clone( parent );
				sprintf( key, "_clone.%d", i );
				mlt_properties_set_data( properties, key, clone, 0, ( mlt_destructor )mlt_producer_close, NULL );
			}
		}
		else
		{
			for ( i = clones; i < existing; i ++ )
			{
				sprintf( key, "_clone.%d", i );
				mlt_properties_set_data( properties, key, NULL, 0, NULL, NULL );
			}
		}
	}

	// Ensure all properties on the parent are passed to the clones
	for ( i = 0; i < clones; i ++ )
	{
		mlt_producer clone = NULL;
		sprintf( key, "_clone.%d", i );
		clone = mlt_properties_get_data( properties, key, NULL );
		if ( clone != NULL )
			mlt_properties_pass( MLT_PRODUCER_PROPERTIES( clone ), properties, "" );
	}

	// Update the number of clones on the properties
	mlt_properties_set_int( properties, "_clones", clones );
}
示例#29
0
int mlt_producer_clear( mlt_producer self )
{
	if ( self != NULL )
	{
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( self );
		mlt_events_block( properties, properties );
		mlt_properties_set_position( properties, "in", 0 );
		mlt_events_unblock( properties, properties );
		mlt_properties_set_position( properties, "out", -1 );
	}
	return 0;
}
示例#30
0
mlt_producer producer_qimage_init( mlt_profile profile, mlt_service_type type, const char *id, char *filename )
{
	producer_qimage self = calloc( sizeof( struct producer_qimage_s ), 1 );
	if ( self != NULL && mlt_producer_init( &self->parent, self ) == 0 )
	{
		mlt_producer producer = &self->parent;

		// Get the properties interface
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( &self->parent );
	
		// Callback registration
#ifdef USE_KDE
		init_qimage();
#endif
		producer->get_frame = producer_get_frame;
		producer->close = ( mlt_destructor )producer_close;

		// Set the default properties
		mlt_properties_set( properties, "resource", filename );
		mlt_properties_set_int( properties, "ttl", 25 );
		mlt_properties_set_int( properties, "aspect_ratio", 1 );
		mlt_properties_set_int( properties, "progressive", 1 );
		mlt_properties_set_int( properties, "seekable", 1 );

		// Validate the resource
		if ( filename )
			load_filenames( self, properties );
		if ( self->count )
		{
			mlt_frame frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) );
			if ( frame )
			{
				mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
				mlt_properties_set_data( frame_properties, "producer_qimage", self, 0, NULL, NULL );
				mlt_frame_set_position( frame, mlt_producer_position( producer ) );
				mlt_properties_set_position( frame_properties, "qimage_position", mlt_producer_position( producer ) );
				refresh_qimage( self, frame );
				mlt_cache_item_close( self->qimage_cache );
				mlt_frame_close( frame );
			}
		}
		if ( self->current_width == 0 )
		{
			producer_close( producer );
			producer = NULL;
		}
		return producer;
	}
	free( self );
	return NULL;
}