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; }
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; }
void mlt_tractor_refresh( mlt_tractor self ) { mlt_multitrack multitrack = mlt_tractor_multitrack( self ); mlt_properties multitrack_props = MLT_MULTITRACK_PROPERTIES( multitrack ); mlt_properties properties = MLT_TRACTOR_PROPERTIES( self ); mlt_events_block( multitrack_props, properties ); mlt_events_block( properties, properties ); mlt_multitrack_refresh( multitrack ); mlt_properties_set_position( properties, "in", 0 ); mlt_properties_set_position( properties, "out", mlt_properties_get_position( multitrack_props, "out" ) ); mlt_events_unblock( properties, properties ); mlt_events_unblock( multitrack_props, properties ); mlt_properties_set_position( properties, "length", mlt_properties_get_position( multitrack_props, "length" ) ); }
int mlt_multitrack_disconnect( mlt_multitrack self, int track ) { int error = -1; if ( self && self->list && track >= 0 && track < self->count ) { // Disconnect the track producer. error = mlt_service_disconnect_producer( MLT_MULTITRACK_SERVICE(self), track ); if ( !error ) { // Release references on track. if ( self->list[ track ] ) { mlt_producer_close( self->list[ track ]->producer ); mlt_event_close( self->list[ track ]->event ); if ( track + 1 >= self-> count ) { free( self->list[ track ] ); self->list[ track ] = NULL; } } // Contract the list of tracks. for ( ; track + 1 < self->count; track ++ ) { if ( self->list[ track ] && self->list[ track + 1 ] ) { self->list[ track ]->producer = self->list[ track + 1 ]->producer; self->list[ track ]->event = self->list[ track + 1 ]->event; } } self->count --; // Recalculate the duration. mlt_multitrack_refresh( self ); } } return error; }
static void mlt_multitrack_listener( mlt_producer producer, mlt_multitrack self ) { mlt_multitrack_refresh( self ); }