X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Fwestley%2Fproducer_westley.c;h=8c7d9ca64fc740bc1e2903f3a9ec1ad5a63bfb81;hb=0bd5d91026b8bd143f957f119d61d5fedd45cf70;hp=ff5ba41315772780b2fd0d175f9e17eea8ab5095;hpb=73345685f05e06c7b2c6a9d2b5c6bcf1c642d82b;p=melted diff --git a/src/modules/westley/producer_westley.c b/src/modules/westley/producer_westley.c index ff5ba41..8c7d9ca 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 * @@ -118,7 +118,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 ) { @@ -205,6 +207,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 ); @@ -342,6 +350,18 @@ static void on_end_entry( deserialise_context context, const xmlChar *name ) context_push_service( context, service ); } +static void on_end_tractor( deserialise_context context, const xmlChar *name ) +{ + // Get and discard the last producer + mlt_producer multitrack = MLT_PRODUCER( context_pop_service( context ) ); + + // Inherit the producer's properties + mlt_properties properties = mlt_producer_properties( multitrack ); + mlt_properties_set_position( properties, "length", mlt_producer_get_out( multitrack ) + 1 ); + mlt_producer_set_in_and_out( multitrack, 0, mlt_producer_get_out( multitrack ) ); + mlt_properties_set_double( properties, "fps", mlt_producer_get_fps( multitrack ) ); +} + static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **atts) { deserialise_context context = ( deserialise_context ) ctx; @@ -377,17 +397,17 @@ static void on_end_element( void *ctx, const xmlChar *name ) else if ( strcmp( name, "entry" ) == 0 ) on_end_entry( context, name ); else if ( strcmp( name, "tractor" ) == 0 ) - { - // Discard the last producer - context_pop_service( context ); - } + on_end_tractor( context, 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(); @@ -396,16 +416,56 @@ 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 ); + + // 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 ); return MLT_PRODUCER( service );