X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmodules%2Fwestley%2Fproducer_westley.c;h=265475a064f32b4d8ef671263327f3e8a9d3c23c;hb=42bd0aedb6d3d65bedb98479adcdbaeb326dfee9;hp=2bd3204107b01e2273e8438d29b0b968d5615e8e;hpb=dfcac1bf1428068f68b700d872452d9aa80a8a1d;p=mlt diff --git a/src/modules/westley/producer_westley.c b/src/modules/westley/producer_westley.c index 2bd32041..265475a0 100644 --- a/src/modules/westley/producer_westley.c +++ b/src/modules/westley/producer_westley.c @@ -1,5 +1,5 @@ /* - * producer_libdv.c -- a libxml2 parser of mlt service networks + * producer_westley.c -- a libxml2 parser of mlt service networks * Copyright (C) 2003-2004 Ushodaya Enterprises Limited * Author: Dan Dennedy * @@ -75,12 +75,21 @@ static void track_service( mlt_properties properties, void *service, mlt_destruc static void on_start_tractor( deserialise_context context, const xmlChar *name, const xmlChar **atts) { mlt_service service = mlt_tractor_service( mlt_tractor_init() ); + mlt_properties properties = mlt_service_properties( service ); track_service( context->destructors, service, (mlt_destructor) mlt_tractor_close ); + mlt_properties_set_position( properties, "length", 0 ); + for ( ; atts != NULL && *atts != NULL; atts += 2 ) mlt_properties_set( mlt_service_properties( service ), (char*) atts[0], (char*) atts[1] ); + if ( mlt_properties_get_position( properties, "length" ) < mlt_properties_get_position( properties, "out" ) ) + { + mlt_position length = mlt_properties_get_position( properties, "out" ) + 1; + mlt_properties_set_position( properties, "length", length ); + } + context_push_service( context, service ); } @@ -103,12 +112,20 @@ static void on_start_playlist( deserialise_context context, const xmlChar *name, track_service( context->destructors, service, (mlt_destructor) mlt_playlist_close ); + mlt_properties_set_position( properties, "length", 0 ); + for ( ; atts != NULL && *atts != NULL; atts += 2 ) mlt_properties_set( properties, (char*) atts[0], (char*) atts[1] ); if ( mlt_properties_get( properties, "id" ) != NULL ) mlt_properties_set_data( context->producer_map, mlt_properties_get( properties, "id" ), service, 0, NULL, NULL ); + if ( mlt_properties_get_position( properties, "length" ) < mlt_properties_get_position( properties, "out" ) ) + { + mlt_position length = mlt_properties_get_position( properties, "out" ) + 1; + mlt_properties_set_position( properties, "length", length ); + } + context_push_service( context, service ); } @@ -118,7 +135,9 @@ static void on_start_producer( deserialise_context context, const xmlChar *name, mlt_service service = NULL; for ( ; atts != NULL && *atts != NULL; atts += 2 ) + { mlt_properties_set( properties, (char*) atts[0], (char*) atts[1] ); + } if ( mlt_properties_get( properties, "mlt_service" ) != NULL ) { @@ -161,7 +180,7 @@ static void on_start_blank( deserialise_context context, const xmlChar *name, co } // Append a blank to the playlist - mlt_playlist_blank( MLT_PLAYLIST( service ), length ); + mlt_playlist_blank( MLT_PLAYLIST( service ), length - 1 ); // Push the playlist back onto the stack context_push_service( context, service ); @@ -205,6 +224,12 @@ static void on_start_filter( deserialise_context context, const xmlChar *name, c mlt_filter_connect( MLT_FILTER( service ), producer, mlt_properties_get_int( properties, "track" ) ); + // Set in and out from producer if non existant + if ( mlt_properties_get( properties, "in" ) == NULL ) + mlt_properties_set_position( properties, "in", mlt_producer_get_in( MLT_PRODUCER( producer ) ) ); + if ( mlt_properties_get( properties, "out" ) == NULL ) + mlt_properties_set_position( properties, "out", mlt_producer_get_out( MLT_PRODUCER( producer ) ) ); + // Propogate the properties mlt_properties_inherit( mlt_service_properties( service ), properties ); mlt_properties_close( properties ); @@ -344,7 +369,7 @@ static void on_end_entry( deserialise_context context, const xmlChar *name ) static void on_end_tractor( deserialise_context context, const xmlChar *name ) { - // Discard the last producer + // Get and discard the last producer mlt_producer multitrack = MLT_PRODUCER( context_pop_service( context ) ); // Inherit the producer's properties @@ -395,8 +420,11 @@ static void on_end_element( void *ctx, const xmlChar *name ) mlt_producer producer_westley_init( char *filename ) { + static int init = 0; xmlSAXHandler *sax = calloc( 1, sizeof( xmlSAXHandler ) ); struct deserialise_context_s *context = calloc( 1, sizeof( struct deserialise_context_s ) ); + mlt_properties properties = NULL; + int i = 0; context->producer_map = mlt_properties_new(); context->destructors = mlt_properties_new(); @@ -405,19 +433,60 @@ mlt_producer producer_westley_init( char *filename ) sax->startElement = on_start_element; sax->endElement = on_end_element; - xmlInitParser(); + if ( !init ) + { + xmlInitParser(); + //init = 1; + } + xmlSAXUserParseFile( sax, context, filename ); - xmlCleanupParser(); - free( sax ); - mlt_properties_close( context->producer_map ); + // Need the complete producer list for various reasons + properties = context->destructors; + // Get the last producer on the stack mlt_service service = context_pop_service( context ); - // make the returned service destroy the connected services - mlt_properties_set_data( mlt_service_properties( service ), "__destructors__", context->destructors, 0, (mlt_destructor) mlt_properties_close, NULL ); - free( context ); - mlt_properties_set( mlt_service_properties( service ), "resource", filename ); + // Do we actually have a producer here? + if ( service != NULL ) + { + // Now make sure we don't have a reference to the service in the properties + for ( i = mlt_properties_count( properties ) - 1; i >= 1; i -- ) + { + char *name = mlt_properties_get_name( properties, i ); + if ( mlt_properties_get_data( properties, name, NULL ) == service ) + { + mlt_properties_set_data( properties, name, service, 0, NULL, NULL ); + break; + } + } + + // We are done referencing destructor property list + // Set this var to service properties for convenience + properties = mlt_service_properties( service ); + + // make the returned service destroy the connected services + mlt_properties_set_data( properties, "__destructors__", context->destructors, 0, (mlt_destructor) mlt_properties_close, NULL ); + + // Now assign additional properties + mlt_properties_set( properties, "resource", filename ); + + // This tells consumer_westley not to deep copy + mlt_properties_set( properties, "westley", "was here" ); + } + else + { + // Clean up + mlt_properties_close( properties ); + } + + free( context->stack_service ); + mlt_properties_close( context->producer_map ); + //free( context ); + free( sax ); + xmlCleanupParser(); + xmlMemoryDump( ); + return MLT_PRODUCER( service ); }