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; }
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; }
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 ); } } }
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; }
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; }
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; }
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; }
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; }
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; }
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 ); }
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; }
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 ); }
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 ); } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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 )); }
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 ); } }
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; }
static void stop_handler(int signum) { if ( melt ) { mlt_properties properties = MLT_PRODUCER_PROPERTIES( melt ); mlt_properties_set_int( properties, "done", 1 ); } }
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; }
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; }
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 ); }
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 ); }
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; }
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; }