]> git.sesse.net Git - mlt/commitdiff
Add consumer element to xml producer.
authorDan Dennedy <dan@dennedy.org>
Sat, 1 Oct 2011 21:21:25 +0000 (14:21 -0700)
committerDan Dennedy <dan@dennedy.org>
Sat, 1 Oct 2011 21:21:25 +0000 (14:21 -0700)
src/melt/melt.c
src/modules/core/producer_melt.c
src/modules/xml/mlt-xml.dtd
src/modules/xml/producer_xml.c

index 5ff487ea1e94cf0690e383baf4628370269e5ef8..a9283690111944cf104011ef6d1f8f449dd7e4c8 100644 (file)
@@ -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 );
index 69bcad8c0a1cdeb9993e56838bcae849232e61bf..1a5789fd5477da2029bb60c90079ad3648803f2f 100644 (file)
@@ -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;
 }
index f2bbfc20cbadec2c41611fe1f79809041fd7f481..30fa78ebba8c69fe2d5eb89d10c95a2fa30dfa78 100644 (file)
@@ -2,7 +2,7 @@
 
 <!-- MLT XML DTD v0.2.0 -->
 
-<!ELEMENT mlt (profile | producer | playlist | tractor | multitrack)+ >
+<!ELEMENT mlt (profile | producer | playlist | tractor | multitrack | consumer)+ >
 <!ATTLIST mlt
     LC_NUMERIC CDATA    #IMPLIED
     version    CDATA    #IMPLIED
@@ -83,3 +83,8 @@
 <!ATTLIST track
     producer IDREF    #IMPLIED
 >
+<!ELEMENT consumer (property)* >
+<!ATTLIST consumer
+    id       ID       #IMPLIED
+    mlt_service  CDATA    #IMPLIED
+>
index b9c55e2850ba488cda8a4568b72d727d4704e9b1..18ed90c0ffaa46409be179ba6a3af6ff894b5089 100644 (file)
@@ -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
        {