From: lilo_booter Date: Thu, 15 Jan 2004 11:17:45 +0000 (+0000) Subject: partial corrections to serialisation X-Git-Url: http://research.m1stereo.tv/gitweb?a=commitdiff_plain;h=c28f352daacca421f977bca75eefd36a73189dac;p=melted partial corrections to serialisation git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@79 d19143bc-622f-0410-bfdd-b5b2a6649095 --- diff --git a/mlt/src/framework/mlt_frame.c b/mlt/src/framework/mlt_frame.c index 1c36cf0..f8f0787 100644 --- a/mlt/src/framework/mlt_frame.c +++ b/mlt/src/framework/mlt_frame.c @@ -93,8 +93,7 @@ int mlt_frame_is_test_audio( mlt_frame this ) double mlt_frame_get_aspect_ratio( mlt_frame this ) { - mlt_properties properties = mlt_frame_properties( this ); - return mlt_properties_get_double( properties, "aspect_ratio" ); + return mlt_properties_get_double( mlt_frame_properties( this ), "aspect_ratio" ); } /** Set the aspect ratio of the frame. @@ -102,8 +101,7 @@ double mlt_frame_get_aspect_ratio( mlt_frame this ) int mlt_frame_set_aspect_ratio( mlt_frame this, double value ) { - mlt_properties properties = mlt_frame_properties( this ); - return mlt_properties_set_double( properties, "aspect_ratio", value ); + return mlt_properties_set_double( mlt_frame_properties( this ), "aspect_ratio", value ); } /** Get the position of this frame. @@ -111,8 +109,7 @@ int mlt_frame_set_aspect_ratio( mlt_frame this, double value ) mlt_position mlt_frame_get_position( mlt_frame this ) { - mlt_properties properties = mlt_frame_properties( this ); - return mlt_properties_get_position( properties, "position" ); + return mlt_properties_get_position( mlt_frame_properties( this ), "position" ); } /** Set the position of this frame. @@ -120,8 +117,7 @@ mlt_position mlt_frame_get_position( mlt_frame this ) int mlt_frame_set_position( mlt_frame this, mlt_position value ) { - mlt_properties properties = mlt_frame_properties( this ); - return mlt_properties_set_position( properties, "position", value ); + return mlt_properties_set_position( mlt_frame_properties( this ), "position", value ); } /** Stack a get_image callback. diff --git a/mlt/src/framework/mlt_multitrack.c b/mlt/src/framework/mlt_multitrack.c index 59b2383..28d598f 100644 --- a/mlt/src/framework/mlt_multitrack.c +++ b/mlt/src/framework/mlt_multitrack.c @@ -61,6 +61,7 @@ mlt_multitrack mlt_multitrack_init( ) producer->get_frame = producer_get_frame; mlt_properties_set_data( properties, "multitrack", this, 0, NULL, NULL ); mlt_properties_set( properties, "log_id", "multitrack" ); + mlt_properties_set( properties, "resource", "" ); } else { diff --git a/mlt/src/framework/mlt_playlist.c b/mlt/src/framework/mlt_playlist.c index ff9e273..8bdbe4b 100644 --- a/mlt/src/framework/mlt_playlist.c +++ b/mlt/src/framework/mlt_playlist.c @@ -81,6 +81,7 @@ mlt_playlist mlt_playlist_init( ) // Specify the eof condition mlt_properties_set( mlt_playlist_properties( this ), "eof", "pause" ); + mlt_properties_set( mlt_playlist_properties( this ), "resource", "" ); } return this; @@ -175,6 +176,8 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer this->list[ this->count ]->frame_out = out; this->list[ this->count ]->frame_count = out - in + 1; + mlt_properties_set( mlt_producer_properties( producer ), "eof", "continue" ); + mlt_producer_set_speed( producer, 0 ); this->count ++; diff --git a/mlt/src/framework/mlt_producer.c b/mlt/src/framework/mlt_producer.c index f4e5bd5..c8a3e69 100644 --- a/mlt/src/framework/mlt_producer.c +++ b/mlt/src/framework/mlt_producer.c @@ -61,7 +61,8 @@ int mlt_producer_init( mlt_producer this, void *child ) mlt_properties_set_position( properties, "out", 1799999 ); mlt_properties_set_position( properties, "length", 1800000 ); mlt_properties_set_double( properties, "aspect_ratio", 4.0 / 3.0 ); - mlt_properties_set( properties, "log_id", "multitrack" ); + mlt_properties_set( properties, "eof", "pause" ); + mlt_properties_set( properties, "resource", "" ); // Override service get_frame parent->get_frame = producer_get_frame; @@ -91,10 +92,13 @@ mlt_properties mlt_producer_properties( mlt_producer this ) int mlt_producer_seek( mlt_producer this, mlt_position position ) { + // Determine eof handling + char *eof = mlt_properties_get( mlt_producer_properties( this ), "eof" ); + // Check bounds if ( position < 0 ) position = 0; - else if ( position > mlt_producer_get_playtime( this ) ) + else if ( !strcmp( eof, "pause" ) && position >= mlt_producer_get_playtime( this ) ) position = mlt_producer_get_playtime( this ) - 1; // Set the position @@ -119,7 +123,11 @@ mlt_position mlt_producer_position( mlt_producer this ) mlt_position mlt_producer_frame( mlt_producer this ) { - return mlt_properties_get_double( mlt_producer_properties( this ), "frame" ); + //char *resource = mlt_properties_get( mlt_producer_properties( this ), "resource" ); + //mlt_position frame = mlt_properties_get_position( mlt_producer_properties( this ), "frame" ); + //mlt_position position = mlt_properties_get_position( mlt_producer_properties( this ), "position" ); + //fprintf( stderr, "%s: %lld %lld\n", resource, frame, position ); + return mlt_properties_get_position( mlt_producer_properties( this ), "frame" ); } /** Set the playing speed. @@ -214,7 +222,7 @@ mlt_position mlt_producer_get_length( mlt_producer this ) void mlt_producer_prepare_next( mlt_producer this ) { - mlt_producer_seek( this, mlt_producer_frame( this ) + mlt_producer_get_speed( this ) ); + mlt_producer_seek( this, mlt_producer_position( this ) + mlt_producer_get_speed( this ) ); } /** Get a frame. @@ -225,13 +233,11 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind int result = 1; mlt_producer this = service->child; + // Determine eof handling + char *eof = mlt_properties_get( mlt_producer_properties( this ), "eof" ); + // A properly instatiated producer will have a get_frame method... - if ( this->get_frame != NULL ) - { - // Get the frame from the implementation - result = this->get_frame( this, frame, index ); - } - else + if ( this->get_frame == NULL || ( !strcmp( eof, "continue" ) && mlt_producer_position( this ) > mlt_producer_get_out( this ) ) ) { // Generate a test frame *frame = mlt_frame_init( ); @@ -242,6 +248,11 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind // Calculate the next position mlt_producer_prepare_next( this ); } + else + { + // Get the frame from the implementation + result = this->get_frame( this, frame, index ); + } // Copy the fps and speed of the producer onto the frame mlt_properties properties = mlt_frame_properties( *frame ); diff --git a/mlt/src/framework/mlt_properties.c b/mlt/src/framework/mlt_properties.c index d047da0..a0f39f2 100644 --- a/mlt/src/framework/mlt_properties.c +++ b/mlt/src/framework/mlt_properties.c @@ -342,13 +342,9 @@ void mlt_properties_close( mlt_properties this ) property_list *list = this->private; int index = 0; - int debug = mlt_properties_get_int( this, "debug" ); - // Clean up names and values for ( index = 0; index < list->count; index ++ ) { - if ( debug ) - fprintf( stderr, "closing %s\n", list->name[ index ] ); free( list->name[ index ] ); mlt_property_close( list->value[ index ] ); } diff --git a/mlt/src/framework/mlt_tractor.c b/mlt/src/framework/mlt_tractor.c index 8d6247d..72f9e72 100644 --- a/mlt/src/framework/mlt_tractor.c +++ b/mlt/src/framework/mlt_tractor.c @@ -55,6 +55,7 @@ mlt_tractor mlt_tractor_init( ) if ( mlt_producer_init( producer, this ) == 0 ) { producer->get_frame = producer_get_frame; + mlt_properties_set( mlt_producer_properties( producer ), "resource", "" ); } else { @@ -119,6 +120,8 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra int looking = 1; int done = 0; mlt_frame temp = NULL; + mlt_frame store[ 10 ]; + int count = 0; // Get the properties of the parent producer mlt_properties properties = mlt_producer_properties( parent ); @@ -154,25 +157,28 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra // Use this as output if we don't have one already *frame = temp; } - else if ( ( !mlt_frame_is_test_card( temp ) || !mlt_frame_is_test_audio( temp ) ) && - mlt_producer_frame( parent ) == mlt_properties_get_position( mlt_frame_properties( temp ), "position" ) ) + else if ( ( !mlt_frame_is_test_card( temp ) || !mlt_frame_is_test_audio( temp ) ) && looking && + mlt_producer_position( parent ) == mlt_properties_get_position( mlt_frame_properties( temp ), "position" ) ) { *frame = temp; looking = 0; } - else if ( ( !mlt_frame_is_test_card( temp ) || !mlt_frame_is_test_audio( temp ) ) && looking ) - { - // This is the one we want and we can stop looking - *frame = temp; - looking = 0; - } else { - // We discard all other frames - mlt_frame_close( temp ); + // We store all other frames for now + store[ count ++ ] = temp; } } + // Now place all the unused frames on to the properties (will be destroyed automatically) + while ( count -- ) + { + mlt_properties frame_properties = mlt_frame_properties( *frame ); + char label[ 30 ]; + sprintf( label, "tractor_%d", count ); + mlt_properties_set_data( frame_properties, label, store[ count ], 0, ( mlt_destructor )mlt_frame_close, NULL ); + } + // Prepare the next frame mlt_producer_prepare_next( parent ); diff --git a/mlt/src/framework/mlt_transition.c b/mlt/src/framework/mlt_transition.c index 5071550..b4024fb 100644 --- a/mlt/src/framework/mlt_transition.c +++ b/mlt/src/framework/mlt_transition.c @@ -103,8 +103,7 @@ void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_po int mlt_transition_get_a_track( mlt_transition this ) { - mlt_properties properties = mlt_transition_properties( this ); - return mlt_properties_get_int( properties, "a_track" ); + return mlt_properties_get_int( mlt_transition_properties( this ), "a_track" ); } /** Get the index of the b track. @@ -112,8 +111,7 @@ int mlt_transition_get_a_track( mlt_transition this ) int mlt_transition_get_b_track( mlt_transition this ) { - mlt_properties properties = mlt_transition_properties( this ); - return mlt_properties_get_int( properties, "b_track" ); + return mlt_properties_get_int( mlt_transition_properties( this ), "b_track" ); } /** Get the in point. @@ -121,8 +119,7 @@ int mlt_transition_get_b_track( mlt_transition this ) mlt_position mlt_transition_get_in( mlt_transition this ) { - mlt_properties properties = mlt_transition_properties( this ); - return mlt_properties_get_position( properties, "in" ); + return mlt_properties_get_position( mlt_transition_properties( this ), "in" ); } /** Get the out point. @@ -130,32 +127,20 @@ mlt_position mlt_transition_get_in( mlt_transition this ) mlt_position mlt_transition_get_out( mlt_transition this ) { - mlt_properties properties = mlt_transition_properties( this ); - return mlt_properties_get_position( properties, "out" ); + return mlt_properties_get_position( mlt_transition_properties( this ), "out" ); } /** Process the frame. + + If we have no process method (unlikely), we simply return the a_frame unmolested. */ static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame ) { if ( this->process == NULL ) - { - if ( !mlt_frame_is_test_card( a_frame ) ) - { - mlt_frame_close( b_frame ); - return a_frame; - } - else - { - mlt_frame_close( a_frame ); - return b_frame; - } - } + return a_frame; else - { return this->process( this, a_frame, b_frame ); - } } /** Get a frame from this filter. @@ -165,14 +150,12 @@ static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt method for all tracks, we have to take special care that we only obtain the a and b frames once - we do this on the first call to get a frame from either a or b. - After that, we have 3 cases to resolve: + After that, we have 2 cases to resolve: 1) if the track is the a_track and we're in the time zone, then we need to call the - process method to do the effect on the frame (we assign NULL to the a_frame and - b_frames here) otherwise, we pass on the a_frame unmolested; - 2) if the track is the b_track and we're the in the time zone OR the b_frame is NULL, - then we generate a test card frame, otherwise we pass on the b frame unmolested; - 3) For all other tracks, we get the frames on demand. + process method to do the effect on the frame and remember we've passed it on + otherwise, we pass on the a_frame unmolested; + 2) For all other tracks, we get the frames on demand. */ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int index ) @@ -187,11 +170,12 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i mlt_position out = mlt_properties_get_position( properties, "out" ); // Fetch a and b frames together... - if ( ( index == a_track || index == b_track ) && - ( this->a_frame == NULL && this->b_frame == NULL ) ) + if ( ( index == a_track || index == b_track ) && !( this->a_held || this->b_held ) ) { mlt_service_get_frame( this->producer, &this->a_frame, a_track ); mlt_service_get_frame( this->producer, &this->b_frame, b_track ); + this->a_held = 1; + this->b_held = 1; } // Special case track processing @@ -199,45 +183,25 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i { // Determine if we're in the right time zone mlt_position position = mlt_frame_get_position( this->a_frame ); - if ( position >= in && position < out ) + if ( position >= in && position <= out ) { // Process the transition *frame = transition_process( this, this->a_frame, this->b_frame ); - - // Important - NULL both frames now so that we know they're done... - this->a_frame = NULL; - this->b_frame = NULL; + this->a_held = 0; } else { // Pass on the 'a frame' and remember that we've done it *frame = this->a_frame; - this->a_frame = NULL; - } + this->a_held = 0; + } return 0; } if ( index == b_track ) { - if ( this->b_frame == NULL ) - { - // We're *probably* in the zone and the a frame has been requested - *frame = mlt_frame_init( ); - } - else - { - mlt_position position = mlt_frame_get_position( this->b_frame ); - if ( position >= in && position < out ) - { - // We're in the zone, but the 'a frame' has not been requested yet - *frame = mlt_frame_init( ); - } - else - { - // We're out of the zone, pass on b and remember that we've done it - *frame = this->b_frame; - this->b_frame = NULL; - } - } + // Pass on the 'b frame' and remember that we've done it + *frame = this->b_frame; + this->b_held = 0; return 0; } else diff --git a/mlt/src/framework/mlt_transition.h b/mlt/src/framework/mlt_transition.h index c297bdb..1dad6c1 100644 --- a/mlt/src/framework/mlt_transition.h +++ b/mlt/src/framework/mlt_transition.h @@ -46,6 +46,8 @@ struct mlt_transition_s // Private mlt_frame a_frame; mlt_frame b_frame; + int a_held; + int b_held; }; /** Public final methods diff --git a/mlt/src/inigo/inigo.c b/mlt/src/inigo/inigo.c index fa76e64..6a12605 100644 --- a/mlt/src/inigo/inigo.c +++ b/mlt/src/inigo/inigo.c @@ -227,7 +227,6 @@ int main( int argc, char **argv ) // Transport functionality transport( inigo ); - } else if ( store != NULL ) { diff --git a/mlt/src/modules/core/transition_composite.c b/mlt/src/modules/core/transition_composite.c index c2ba62d..ef896a9 100644 --- a/mlt/src/modules/core/transition_composite.c +++ b/mlt/src/modules/core/transition_composite.c @@ -69,9 +69,6 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form *width = mlt_properties_get_int( a_props, "width" ); *height = mlt_properties_get_int( a_props, "height" ); *image = mlt_properties_get_data( a_props, "image", NULL ); - - // Close the b_frame - mlt_frame_close( b_frame ); } else if ( a_props != NULL ) { diff --git a/mlt/src/modules/core/transition_luma.c b/mlt/src/modules/core/transition_luma.c index fc712ea..5e0dd0f 100644 --- a/mlt/src/modules/core/transition_luma.c +++ b/mlt/src/modules/core/transition_luma.c @@ -176,9 +176,6 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form *height = mlt_properties_get_int( a_props, "height" ); *image = mlt_properties_get_data( a_props, "image", NULL ); - // Close the b_frame - mlt_frame_close( b_frame ); - previous_mix = mix; return 0; @@ -342,7 +339,7 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram mlt_position in = mlt_transition_get_in( transition ); mlt_position out = mlt_transition_get_out( transition ); mlt_position time = mlt_frame_get_position( b_frame ); - double pos = ( (double)time - (double)in ) / ( (double)out - (double)in + 1 ); + double pos = ( double )( time - in ) / ( double )( out - in + 1 ); // Set the b frame properties mlt_properties_set_double( b_props, "mix", pos ); diff --git a/mlt/src/modules/inigo/producer_inigo.c b/mlt/src/modules/inigo/producer_inigo.c index 62e02b2..5c60e29 100644 --- a/mlt/src/modules/inigo/producer_inigo.c +++ b/mlt/src/modules/inigo/producer_inigo.c @@ -44,6 +44,7 @@ static mlt_producer parse_inigo( char *file ) } mlt_producer result = producer_inigo_init( args ); + if ( result != NULL ) { mlt_properties properties = mlt_producer_properties( result ); @@ -135,11 +136,6 @@ static mlt_transition create_transition( mlt_field field, char *id, int track ) return transition; } -static void set_properties( mlt_properties properties, char *namevalue ) -{ - mlt_properties_parse( properties, namevalue ); -} - mlt_producer producer_inigo_init( char **argv ) { int i; @@ -203,7 +199,7 @@ mlt_producer producer_inigo_init( char **argv ) } else if ( strstr( argv[ i ], "=" ) ) { - set_properties( properties, argv[ i ] ); + mlt_properties_parse( properties, argv[ i ] ); } else if ( argv[ i ][ 0 ] != '-' ) { @@ -247,6 +243,7 @@ mlt_producer producer_inigo_init( char **argv ) mlt_properties_set_data( props, "multitrack", multitrack, 0, NULL, NULL ); mlt_properties_set_data( props, "field", field, 0, NULL, NULL ); mlt_properties_set_data( props, "group", group, 0, NULL, NULL ); + mlt_properties_set_position( props, "length", mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) + 1 ); mlt_producer_set_in_and_out( prod, 0, mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) ); mlt_properties_set_double( props, "fps", mlt_producer_get_fps( mlt_multitrack_producer( multitrack ) ) ); diff --git a/mlt/src/tests/charlie.c b/mlt/src/tests/charlie.c index bcd4dae..f4086e4 100644 --- a/mlt/src/tests/charlie.c +++ b/mlt/src/tests/charlie.c @@ -11,7 +11,12 @@ mlt_producer create_producer( char *file ) mlt_producer result = NULL; // 1st Line preferences - if ( strstr( file, ".mpg" ) ) + if ( strstr( file, ".inigo" ) ) + { + char *args[ 2 ] = { file, NULL }; + result = mlt_factory_producer( "inigo", args ); + } + else if ( strstr( file, ".mpg" ) ) result = mlt_factory_producer( "mcmpeg", file ); else if ( strstr( file, ".mpeg" ) ) result = mlt_factory_producer( "mcmpeg", file ); @@ -104,20 +109,6 @@ void track_service( mlt_field field, void *service, mlt_destructor destructor ) mlt_properties_set_int( properties, "registered", ++ registered ); } -mlt_filter create_filter( mlt_field field, char *id, int track ) -{ - char *arg = strchr( id, ':' ); - if ( arg != NULL ) - *arg ++ = '\0'; - mlt_filter filter = mlt_factory_filter( id, arg ); - if ( filter != NULL ) - { - mlt_field_plant_filter( field, filter, track ); - track_service( field, filter, ( mlt_destructor )mlt_filter_close ); - } - return filter; -} - void set_properties( mlt_service service, char *namevalue ) { mlt_properties properties = mlt_service_properties( service ); @@ -143,10 +134,8 @@ int main( int argc, char **argv ) int i; mlt_service service = NULL; mlt_consumer consumer = NULL; - mlt_multitrack multitrack = NULL; mlt_producer producer = NULL; mlt_playlist playlist = NULL; - mlt_field field = NULL; // Construct the factory mlt_factory_init( getenv( "MLT_REPOSITORY" ) ); @@ -154,31 +143,15 @@ int main( int argc, char **argv ) // Set up containers playlist = mlt_playlist_init( ); - // Construct the field - field = mlt_field_init( ); - - // We need to track the number of registered filters - mlt_properties properties = mlt_field_properties( field ); - mlt_properties_set_int( properties, "registered", 0 ); - - // Get the multitrack from the field - multitrack = mlt_field_multitrack( field ); - // Parse the arguments for ( i = 1; i < argc; i ++ ) { if ( !strcmp( argv[ i ], "-consumer" ) ) { - consumer = create_consumer( argv[ ++ i ], mlt_multitrack_producer( multitrack ) ); + consumer = create_consumer( argv[ ++ i ], mlt_playlist_producer( playlist ) ); if ( consumer != NULL ) service = mlt_consumer_service( consumer ); } - else if ( !strcmp( argv[ i ], "-filter" ) ) - { - mlt_filter filter = create_filter( field, argv[ ++ i ], 0 ); - if ( filter != NULL ) - service = mlt_filter_service( filter ); - } else if ( !strstr( argv[ i ], "=" ) ) { if ( producer != NULL ) @@ -195,25 +168,21 @@ int main( int argc, char **argv ) // If we have no consumer, default to sdl if ( consumer == NULL ) - consumer = create_consumer( "sdl", mlt_multitrack_producer( multitrack ) ); + consumer = create_consumer( "sdl", mlt_playlist_producer( playlist ) ); // Connect producer to playlist if ( producer != NULL ) mlt_playlist_append( playlist, producer ); - // Connect multitrack to producer - mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist ), 0 ); - - // Connect consumer to tractor - mlt_consumer_connect( consumer, mlt_field_service( field ) ); + // Connect consumer to playlist + mlt_consumer_connect( consumer, mlt_playlist_service( playlist ) ); // Transport functionality - transport( mlt_multitrack_producer( multitrack ) ); + transport( mlt_playlist_producer( playlist ) ); // Close the services mlt_consumer_close( consumer ); - mlt_field_close( field ); - mlt_producer_close( producer ); + mlt_playlist_close( playlist ); // Close the factory mlt_factory_close( ); diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 1c36cf0..f8f0787 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -93,8 +93,7 @@ int mlt_frame_is_test_audio( mlt_frame this ) double mlt_frame_get_aspect_ratio( mlt_frame this ) { - mlt_properties properties = mlt_frame_properties( this ); - return mlt_properties_get_double( properties, "aspect_ratio" ); + return mlt_properties_get_double( mlt_frame_properties( this ), "aspect_ratio" ); } /** Set the aspect ratio of the frame. @@ -102,8 +101,7 @@ double mlt_frame_get_aspect_ratio( mlt_frame this ) int mlt_frame_set_aspect_ratio( mlt_frame this, double value ) { - mlt_properties properties = mlt_frame_properties( this ); - return mlt_properties_set_double( properties, "aspect_ratio", value ); + return mlt_properties_set_double( mlt_frame_properties( this ), "aspect_ratio", value ); } /** Get the position of this frame. @@ -111,8 +109,7 @@ int mlt_frame_set_aspect_ratio( mlt_frame this, double value ) mlt_position mlt_frame_get_position( mlt_frame this ) { - mlt_properties properties = mlt_frame_properties( this ); - return mlt_properties_get_position( properties, "position" ); + return mlt_properties_get_position( mlt_frame_properties( this ), "position" ); } /** Set the position of this frame. @@ -120,8 +117,7 @@ mlt_position mlt_frame_get_position( mlt_frame this ) int mlt_frame_set_position( mlt_frame this, mlt_position value ) { - mlt_properties properties = mlt_frame_properties( this ); - return mlt_properties_set_position( properties, "position", value ); + return mlt_properties_set_position( mlt_frame_properties( this ), "position", value ); } /** Stack a get_image callback. diff --git a/src/framework/mlt_multitrack.c b/src/framework/mlt_multitrack.c index 59b2383..28d598f 100644 --- a/src/framework/mlt_multitrack.c +++ b/src/framework/mlt_multitrack.c @@ -61,6 +61,7 @@ mlt_multitrack mlt_multitrack_init( ) producer->get_frame = producer_get_frame; mlt_properties_set_data( properties, "multitrack", this, 0, NULL, NULL ); mlt_properties_set( properties, "log_id", "multitrack" ); + mlt_properties_set( properties, "resource", "" ); } else { diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c index ff9e273..8bdbe4b 100644 --- a/src/framework/mlt_playlist.c +++ b/src/framework/mlt_playlist.c @@ -81,6 +81,7 @@ mlt_playlist mlt_playlist_init( ) // Specify the eof condition mlt_properties_set( mlt_playlist_properties( this ), "eof", "pause" ); + mlt_properties_set( mlt_playlist_properties( this ), "resource", "" ); } return this; @@ -175,6 +176,8 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer this->list[ this->count ]->frame_out = out; this->list[ this->count ]->frame_count = out - in + 1; + mlt_properties_set( mlt_producer_properties( producer ), "eof", "continue" ); + mlt_producer_set_speed( producer, 0 ); this->count ++; diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index f4e5bd5..c8a3e69 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -61,7 +61,8 @@ int mlt_producer_init( mlt_producer this, void *child ) mlt_properties_set_position( properties, "out", 1799999 ); mlt_properties_set_position( properties, "length", 1800000 ); mlt_properties_set_double( properties, "aspect_ratio", 4.0 / 3.0 ); - mlt_properties_set( properties, "log_id", "multitrack" ); + mlt_properties_set( properties, "eof", "pause" ); + mlt_properties_set( properties, "resource", "" ); // Override service get_frame parent->get_frame = producer_get_frame; @@ -91,10 +92,13 @@ mlt_properties mlt_producer_properties( mlt_producer this ) int mlt_producer_seek( mlt_producer this, mlt_position position ) { + // Determine eof handling + char *eof = mlt_properties_get( mlt_producer_properties( this ), "eof" ); + // Check bounds if ( position < 0 ) position = 0; - else if ( position > mlt_producer_get_playtime( this ) ) + else if ( !strcmp( eof, "pause" ) && position >= mlt_producer_get_playtime( this ) ) position = mlt_producer_get_playtime( this ) - 1; // Set the position @@ -119,7 +123,11 @@ mlt_position mlt_producer_position( mlt_producer this ) mlt_position mlt_producer_frame( mlt_producer this ) { - return mlt_properties_get_double( mlt_producer_properties( this ), "frame" ); + //char *resource = mlt_properties_get( mlt_producer_properties( this ), "resource" ); + //mlt_position frame = mlt_properties_get_position( mlt_producer_properties( this ), "frame" ); + //mlt_position position = mlt_properties_get_position( mlt_producer_properties( this ), "position" ); + //fprintf( stderr, "%s: %lld %lld\n", resource, frame, position ); + return mlt_properties_get_position( mlt_producer_properties( this ), "frame" ); } /** Set the playing speed. @@ -214,7 +222,7 @@ mlt_position mlt_producer_get_length( mlt_producer this ) void mlt_producer_prepare_next( mlt_producer this ) { - mlt_producer_seek( this, mlt_producer_frame( this ) + mlt_producer_get_speed( this ) ); + mlt_producer_seek( this, mlt_producer_position( this ) + mlt_producer_get_speed( this ) ); } /** Get a frame. @@ -225,13 +233,11 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind int result = 1; mlt_producer this = service->child; + // Determine eof handling + char *eof = mlt_properties_get( mlt_producer_properties( this ), "eof" ); + // A properly instatiated producer will have a get_frame method... - if ( this->get_frame != NULL ) - { - // Get the frame from the implementation - result = this->get_frame( this, frame, index ); - } - else + if ( this->get_frame == NULL || ( !strcmp( eof, "continue" ) && mlt_producer_position( this ) > mlt_producer_get_out( this ) ) ) { // Generate a test frame *frame = mlt_frame_init( ); @@ -242,6 +248,11 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind // Calculate the next position mlt_producer_prepare_next( this ); } + else + { + // Get the frame from the implementation + result = this->get_frame( this, frame, index ); + } // Copy the fps and speed of the producer onto the frame mlt_properties properties = mlt_frame_properties( *frame ); diff --git a/src/framework/mlt_properties.c b/src/framework/mlt_properties.c index d047da0..a0f39f2 100644 --- a/src/framework/mlt_properties.c +++ b/src/framework/mlt_properties.c @@ -342,13 +342,9 @@ void mlt_properties_close( mlt_properties this ) property_list *list = this->private; int index = 0; - int debug = mlt_properties_get_int( this, "debug" ); - // Clean up names and values for ( index = 0; index < list->count; index ++ ) { - if ( debug ) - fprintf( stderr, "closing %s\n", list->name[ index ] ); free( list->name[ index ] ); mlt_property_close( list->value[ index ] ); } diff --git a/src/framework/mlt_tractor.c b/src/framework/mlt_tractor.c index 8d6247d..72f9e72 100644 --- a/src/framework/mlt_tractor.c +++ b/src/framework/mlt_tractor.c @@ -55,6 +55,7 @@ mlt_tractor mlt_tractor_init( ) if ( mlt_producer_init( producer, this ) == 0 ) { producer->get_frame = producer_get_frame; + mlt_properties_set( mlt_producer_properties( producer ), "resource", "" ); } else { @@ -119,6 +120,8 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra int looking = 1; int done = 0; mlt_frame temp = NULL; + mlt_frame store[ 10 ]; + int count = 0; // Get the properties of the parent producer mlt_properties properties = mlt_producer_properties( parent ); @@ -154,25 +157,28 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra // Use this as output if we don't have one already *frame = temp; } - else if ( ( !mlt_frame_is_test_card( temp ) || !mlt_frame_is_test_audio( temp ) ) && - mlt_producer_frame( parent ) == mlt_properties_get_position( mlt_frame_properties( temp ), "position" ) ) + else if ( ( !mlt_frame_is_test_card( temp ) || !mlt_frame_is_test_audio( temp ) ) && looking && + mlt_producer_position( parent ) == mlt_properties_get_position( mlt_frame_properties( temp ), "position" ) ) { *frame = temp; looking = 0; } - else if ( ( !mlt_frame_is_test_card( temp ) || !mlt_frame_is_test_audio( temp ) ) && looking ) - { - // This is the one we want and we can stop looking - *frame = temp; - looking = 0; - } else { - // We discard all other frames - mlt_frame_close( temp ); + // We store all other frames for now + store[ count ++ ] = temp; } } + // Now place all the unused frames on to the properties (will be destroyed automatically) + while ( count -- ) + { + mlt_properties frame_properties = mlt_frame_properties( *frame ); + char label[ 30 ]; + sprintf( label, "tractor_%d", count ); + mlt_properties_set_data( frame_properties, label, store[ count ], 0, ( mlt_destructor )mlt_frame_close, NULL ); + } + // Prepare the next frame mlt_producer_prepare_next( parent ); diff --git a/src/framework/mlt_transition.c b/src/framework/mlt_transition.c index 5071550..b4024fb 100644 --- a/src/framework/mlt_transition.c +++ b/src/framework/mlt_transition.c @@ -103,8 +103,7 @@ void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_po int mlt_transition_get_a_track( mlt_transition this ) { - mlt_properties properties = mlt_transition_properties( this ); - return mlt_properties_get_int( properties, "a_track" ); + return mlt_properties_get_int( mlt_transition_properties( this ), "a_track" ); } /** Get the index of the b track. @@ -112,8 +111,7 @@ int mlt_transition_get_a_track( mlt_transition this ) int mlt_transition_get_b_track( mlt_transition this ) { - mlt_properties properties = mlt_transition_properties( this ); - return mlt_properties_get_int( properties, "b_track" ); + return mlt_properties_get_int( mlt_transition_properties( this ), "b_track" ); } /** Get the in point. @@ -121,8 +119,7 @@ int mlt_transition_get_b_track( mlt_transition this ) mlt_position mlt_transition_get_in( mlt_transition this ) { - mlt_properties properties = mlt_transition_properties( this ); - return mlt_properties_get_position( properties, "in" ); + return mlt_properties_get_position( mlt_transition_properties( this ), "in" ); } /** Get the out point. @@ -130,32 +127,20 @@ mlt_position mlt_transition_get_in( mlt_transition this ) mlt_position mlt_transition_get_out( mlt_transition this ) { - mlt_properties properties = mlt_transition_properties( this ); - return mlt_properties_get_position( properties, "out" ); + return mlt_properties_get_position( mlt_transition_properties( this ), "out" ); } /** Process the frame. + + If we have no process method (unlikely), we simply return the a_frame unmolested. */ static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame ) { if ( this->process == NULL ) - { - if ( !mlt_frame_is_test_card( a_frame ) ) - { - mlt_frame_close( b_frame ); - return a_frame; - } - else - { - mlt_frame_close( a_frame ); - return b_frame; - } - } + return a_frame; else - { return this->process( this, a_frame, b_frame ); - } } /** Get a frame from this filter. @@ -165,14 +150,12 @@ static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt method for all tracks, we have to take special care that we only obtain the a and b frames once - we do this on the first call to get a frame from either a or b. - After that, we have 3 cases to resolve: + After that, we have 2 cases to resolve: 1) if the track is the a_track and we're in the time zone, then we need to call the - process method to do the effect on the frame (we assign NULL to the a_frame and - b_frames here) otherwise, we pass on the a_frame unmolested; - 2) if the track is the b_track and we're the in the time zone OR the b_frame is NULL, - then we generate a test card frame, otherwise we pass on the b frame unmolested; - 3) For all other tracks, we get the frames on demand. + process method to do the effect on the frame and remember we've passed it on + otherwise, we pass on the a_frame unmolested; + 2) For all other tracks, we get the frames on demand. */ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int index ) @@ -187,11 +170,12 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i mlt_position out = mlt_properties_get_position( properties, "out" ); // Fetch a and b frames together... - if ( ( index == a_track || index == b_track ) && - ( this->a_frame == NULL && this->b_frame == NULL ) ) + if ( ( index == a_track || index == b_track ) && !( this->a_held || this->b_held ) ) { mlt_service_get_frame( this->producer, &this->a_frame, a_track ); mlt_service_get_frame( this->producer, &this->b_frame, b_track ); + this->a_held = 1; + this->b_held = 1; } // Special case track processing @@ -199,45 +183,25 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i { // Determine if we're in the right time zone mlt_position position = mlt_frame_get_position( this->a_frame ); - if ( position >= in && position < out ) + if ( position >= in && position <= out ) { // Process the transition *frame = transition_process( this, this->a_frame, this->b_frame ); - - // Important - NULL both frames now so that we know they're done... - this->a_frame = NULL; - this->b_frame = NULL; + this->a_held = 0; } else { // Pass on the 'a frame' and remember that we've done it *frame = this->a_frame; - this->a_frame = NULL; - } + this->a_held = 0; + } return 0; } if ( index == b_track ) { - if ( this->b_frame == NULL ) - { - // We're *probably* in the zone and the a frame has been requested - *frame = mlt_frame_init( ); - } - else - { - mlt_position position = mlt_frame_get_position( this->b_frame ); - if ( position >= in && position < out ) - { - // We're in the zone, but the 'a frame' has not been requested yet - *frame = mlt_frame_init( ); - } - else - { - // We're out of the zone, pass on b and remember that we've done it - *frame = this->b_frame; - this->b_frame = NULL; - } - } + // Pass on the 'b frame' and remember that we've done it + *frame = this->b_frame; + this->b_held = 0; return 0; } else diff --git a/src/framework/mlt_transition.h b/src/framework/mlt_transition.h index c297bdb..1dad6c1 100644 --- a/src/framework/mlt_transition.h +++ b/src/framework/mlt_transition.h @@ -46,6 +46,8 @@ struct mlt_transition_s // Private mlt_frame a_frame; mlt_frame b_frame; + int a_held; + int b_held; }; /** Public final methods diff --git a/src/inigo/inigo.c b/src/inigo/inigo.c index fa76e64..6a12605 100644 --- a/src/inigo/inigo.c +++ b/src/inigo/inigo.c @@ -227,7 +227,6 @@ int main( int argc, char **argv ) // Transport functionality transport( inigo ); - } else if ( store != NULL ) { diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index c2ba62d..ef896a9 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -69,9 +69,6 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form *width = mlt_properties_get_int( a_props, "width" ); *height = mlt_properties_get_int( a_props, "height" ); *image = mlt_properties_get_data( a_props, "image", NULL ); - - // Close the b_frame - mlt_frame_close( b_frame ); } else if ( a_props != NULL ) { diff --git a/src/modules/core/transition_luma.c b/src/modules/core/transition_luma.c index fc712ea..5e0dd0f 100644 --- a/src/modules/core/transition_luma.c +++ b/src/modules/core/transition_luma.c @@ -176,9 +176,6 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form *height = mlt_properties_get_int( a_props, "height" ); *image = mlt_properties_get_data( a_props, "image", NULL ); - // Close the b_frame - mlt_frame_close( b_frame ); - previous_mix = mix; return 0; @@ -342,7 +339,7 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram mlt_position in = mlt_transition_get_in( transition ); mlt_position out = mlt_transition_get_out( transition ); mlt_position time = mlt_frame_get_position( b_frame ); - double pos = ( (double)time - (double)in ) / ( (double)out - (double)in + 1 ); + double pos = ( double )( time - in ) / ( double )( out - in + 1 ); // Set the b frame properties mlt_properties_set_double( b_props, "mix", pos ); diff --git a/src/modules/inigo/producer_inigo.c b/src/modules/inigo/producer_inigo.c index 62e02b2..5c60e29 100644 --- a/src/modules/inigo/producer_inigo.c +++ b/src/modules/inigo/producer_inigo.c @@ -44,6 +44,7 @@ static mlt_producer parse_inigo( char *file ) } mlt_producer result = producer_inigo_init( args ); + if ( result != NULL ) { mlt_properties properties = mlt_producer_properties( result ); @@ -135,11 +136,6 @@ static mlt_transition create_transition( mlt_field field, char *id, int track ) return transition; } -static void set_properties( mlt_properties properties, char *namevalue ) -{ - mlt_properties_parse( properties, namevalue ); -} - mlt_producer producer_inigo_init( char **argv ) { int i; @@ -203,7 +199,7 @@ mlt_producer producer_inigo_init( char **argv ) } else if ( strstr( argv[ i ], "=" ) ) { - set_properties( properties, argv[ i ] ); + mlt_properties_parse( properties, argv[ i ] ); } else if ( argv[ i ][ 0 ] != '-' ) { @@ -247,6 +243,7 @@ mlt_producer producer_inigo_init( char **argv ) mlt_properties_set_data( props, "multitrack", multitrack, 0, NULL, NULL ); mlt_properties_set_data( props, "field", field, 0, NULL, NULL ); mlt_properties_set_data( props, "group", group, 0, NULL, NULL ); + mlt_properties_set_position( props, "length", mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) + 1 ); mlt_producer_set_in_and_out( prod, 0, mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) ); mlt_properties_set_double( props, "fps", mlt_producer_get_fps( mlt_multitrack_producer( multitrack ) ) ); diff --git a/src/tests/charlie.c b/src/tests/charlie.c index bcd4dae..f4086e4 100644 --- a/src/tests/charlie.c +++ b/src/tests/charlie.c @@ -11,7 +11,12 @@ mlt_producer create_producer( char *file ) mlt_producer result = NULL; // 1st Line preferences - if ( strstr( file, ".mpg" ) ) + if ( strstr( file, ".inigo" ) ) + { + char *args[ 2 ] = { file, NULL }; + result = mlt_factory_producer( "inigo", args ); + } + else if ( strstr( file, ".mpg" ) ) result = mlt_factory_producer( "mcmpeg", file ); else if ( strstr( file, ".mpeg" ) ) result = mlt_factory_producer( "mcmpeg", file ); @@ -104,20 +109,6 @@ void track_service( mlt_field field, void *service, mlt_destructor destructor ) mlt_properties_set_int( properties, "registered", ++ registered ); } -mlt_filter create_filter( mlt_field field, char *id, int track ) -{ - char *arg = strchr( id, ':' ); - if ( arg != NULL ) - *arg ++ = '\0'; - mlt_filter filter = mlt_factory_filter( id, arg ); - if ( filter != NULL ) - { - mlt_field_plant_filter( field, filter, track ); - track_service( field, filter, ( mlt_destructor )mlt_filter_close ); - } - return filter; -} - void set_properties( mlt_service service, char *namevalue ) { mlt_properties properties = mlt_service_properties( service ); @@ -143,10 +134,8 @@ int main( int argc, char **argv ) int i; mlt_service service = NULL; mlt_consumer consumer = NULL; - mlt_multitrack multitrack = NULL; mlt_producer producer = NULL; mlt_playlist playlist = NULL; - mlt_field field = NULL; // Construct the factory mlt_factory_init( getenv( "MLT_REPOSITORY" ) ); @@ -154,31 +143,15 @@ int main( int argc, char **argv ) // Set up containers playlist = mlt_playlist_init( ); - // Construct the field - field = mlt_field_init( ); - - // We need to track the number of registered filters - mlt_properties properties = mlt_field_properties( field ); - mlt_properties_set_int( properties, "registered", 0 ); - - // Get the multitrack from the field - multitrack = mlt_field_multitrack( field ); - // Parse the arguments for ( i = 1; i < argc; i ++ ) { if ( !strcmp( argv[ i ], "-consumer" ) ) { - consumer = create_consumer( argv[ ++ i ], mlt_multitrack_producer( multitrack ) ); + consumer = create_consumer( argv[ ++ i ], mlt_playlist_producer( playlist ) ); if ( consumer != NULL ) service = mlt_consumer_service( consumer ); } - else if ( !strcmp( argv[ i ], "-filter" ) ) - { - mlt_filter filter = create_filter( field, argv[ ++ i ], 0 ); - if ( filter != NULL ) - service = mlt_filter_service( filter ); - } else if ( !strstr( argv[ i ], "=" ) ) { if ( producer != NULL ) @@ -195,25 +168,21 @@ int main( int argc, char **argv ) // If we have no consumer, default to sdl if ( consumer == NULL ) - consumer = create_consumer( "sdl", mlt_multitrack_producer( multitrack ) ); + consumer = create_consumer( "sdl", mlt_playlist_producer( playlist ) ); // Connect producer to playlist if ( producer != NULL ) mlt_playlist_append( playlist, producer ); - // Connect multitrack to producer - mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist ), 0 ); - - // Connect consumer to tractor - mlt_consumer_connect( consumer, mlt_field_service( field ) ); + // Connect consumer to playlist + mlt_consumer_connect( consumer, mlt_playlist_service( playlist ) ); // Transport functionality - transport( mlt_multitrack_producer( multitrack ) ); + transport( mlt_playlist_producer( playlist ) ); // Close the services mlt_consumer_close( consumer ); - mlt_field_close( field ); - mlt_producer_close( producer ); + mlt_playlist_close( playlist ); // Close the factory mlt_factory_close( );