From 14c9b8743fc800daab96eaffa77859cde83d7892 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Sat, 1 Oct 2011 14:21:25 -0700 Subject: [PATCH] Add consumer element to xml producer. --- src/melt/melt.c | 16 +++++++++ src/modules/core/producer_melt.c | 8 +++++ src/modules/xml/mlt-xml.dtd | 7 +++- src/modules/xml/producer_xml.c | 61 ++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/melt/melt.c b/src/melt/melt.c index 5ff487ea..a9283690 100644 --- a/src/melt/melt.c +++ b/src/melt/melt.c @@ -780,6 +780,18 @@ query_all: // The producer or auto-profile could have changed the profile. load_consumer( &consumer, profile, argc, argv ); + // See if producer has consumer already attached + if ( !store && !consumer ) + { + consumer = MLT_CONSUMER( mlt_service_consumer( MLT_PRODUCER_SERVICE( melt ) ) ); + if ( consumer ) + { + mlt_properties_inc_ref( MLT_CONSUMER_PROPERTIES(consumer) ); // because we explicitly close it + mlt_properties_set_data( MLT_CONSUMER_PROPERTIES(consumer), + "transport_callback", transport_action, 0, NULL, NULL ); + } + } + // If we have no consumer, default to sdl if ( store == NULL && consumer == NULL ) consumer = create_consumer( profile, NULL ); @@ -865,6 +877,10 @@ query_all: show_usage( argv[0] ); } + // Disconnect producer from consumer to prevent ref cycles from closing services + if ( consumer ) + mlt_consumer_connect( consumer, NULL ); + // Close the producer if ( melt != NULL ) mlt_producer_close( melt ); diff --git a/src/modules/core/producer_melt.c b/src/modules/core/producer_melt.c index 69bcad8c..1a5789fd 100644 --- a/src/modules/core/producer_melt.c +++ b/src/modules/core/producer_melt.c @@ -470,5 +470,13 @@ mlt_producer producer_melt_init( mlt_profile profile, mlt_service_type type, con if ( title != NULL ) mlt_properties_set( props, "title", strchr( title, '/' ) ? strrchr( title, '/' ) + 1 : title ); + // If the last producer has a consumer property connect it tractor + if ( producer ) + { + mlt_consumer consumer = mlt_properties_get_data( MLT_PRODUCER_PROPERTIES(producer), "consumer", NULL ); + if ( consumer ) + mlt_consumer_connect( consumer, MLT_PRODUCER_SERVICE(prod) ); + } + return prod; } diff --git a/src/modules/xml/mlt-xml.dtd b/src/modules/xml/mlt-xml.dtd index f2bbfc20..30fa78eb 100644 --- a/src/modules/xml/mlt-xml.dtd +++ b/src/modules/xml/mlt-xml.dtd @@ -2,7 +2,7 @@ - + + + diff --git a/src/modules/xml/producer_xml.c b/src/modules/xml/producer_xml.c index b9c55e28..18ed90c0 100644 --- a/src/modules/xml/producer_xml.c +++ b/src/modules/xml/producer_xml.c @@ -60,6 +60,7 @@ enum service_type mlt_dummy_filter_type, mlt_dummy_transition_type, mlt_dummy_producer_type, + mlt_dummy_consumer_type }; struct deserialise_context_s @@ -84,6 +85,7 @@ struct deserialise_context_s mlt_profile profile; int pass; char *lc_numeric; + mlt_consumer consumer; }; typedef struct deserialise_context_s *deserialise_context; @@ -1049,6 +1051,56 @@ static void on_end_transition( deserialise_context context, const xmlChar *name } } +static void on_start_consumer( deserialise_context context, const xmlChar *name, const xmlChar **atts) +{ + if ( context->pass == 1 ) + { + mlt_consumer consumer = mlt_consumer_new( context->profile ); + mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer ); + + mlt_properties_set_lcnumeric( properties, context->lc_numeric ); + context_push_service( context, MLT_CONSUMER_SERVICE(consumer), mlt_dummy_consumer_type ); + + // Set the properties from attributes + for ( ; atts != NULL && *atts != NULL; atts += 2 ) + mlt_properties_set( properties, (const char*) atts[0], (const char*) atts[1] ); + } +} + +static void on_end_consumer( deserialise_context context, const xmlChar *name ) +{ + if ( context->pass == 1 ) + { + // Get the consumer from the stack + enum service_type type; + mlt_service service = context_pop_service( context, &type ); + + if ( service && type == mlt_dummy_consumer_type ) + { + mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); + qualify_property( context, properties, "resource" ); + char *resource = mlt_properties_get( properties, "resource" ); + + // Instantiate the consumer + context->consumer = mlt_factory_consumer( context->profile, mlt_properties_get( properties, "mlt_service" ), resource ); + if ( context->consumer ) + { + // Track this consumer + track_service( context->destructors, MLT_CONSUMER_SERVICE(context->consumer), (mlt_destructor) mlt_consumer_close ); + mlt_properties_set_lcnumeric( MLT_CONSUMER_PROPERTIES(context->consumer), context->lc_numeric ); + + // Propogate the properties + qualify_property( context, properties, "target" ); + + // Inherit the properties + mlt_properties_inherit( MLT_CONSUMER_PROPERTIES(context->consumer), properties ); + } + // Close the dummy + mlt_service_close( service ); + } + } +} + static void on_start_property( deserialise_context context, const xmlChar *name, const xmlChar **atts) { enum service_type type; @@ -1181,6 +1233,8 @@ static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **at on_start_transition( context, name, atts ); else if ( xmlStrcmp( name, _x("property") ) == 0 ) on_start_property( context, name, atts ); + else if ( xmlStrcmp( name, _x("consumer") ) == 0 ) + on_start_consumer( context, name, atts ); else if ( xmlStrcmp( name, _x("westley") ) == 0 || xmlStrcmp( name, _x("mlt") ) == 0 ) { for ( ; atts != NULL && *atts != NULL; atts += 2 ) @@ -1219,6 +1273,8 @@ static void on_end_element( void *ctx, const xmlChar *name ) on_end_filter( context, name ); else if ( xmlStrcmp( name, _x("transition") ) == 0 ) on_end_transition( context, name ); + else if ( xmlStrcmp( name, _x("consumer") ) == 0 ) + on_end_consumer( context, name ); context->branch[ context->depth ] = 0; context->depth --; @@ -1621,6 +1677,11 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype, mlt_properties_set( properties, "_xml", "was here" ); mlt_properties_set_int( properties, "_mlt_service_hidden", 1 ); } + + // Make consumer available + mlt_properties_inc_ref( MLT_CONSUMER_PROPERTIES( context->consumer ) ); + mlt_properties_set_data( properties, "consumer", context->consumer, 0, + (mlt_destructor) mlt_consumer_close, NULL ); } else { -- 2.39.2