]> git.sesse.net Git - mlt/blobdiff - src/modules/xml/producer_xml.c
Add xml_retain property support to xml module.
[mlt] / src / modules / xml / producer_xml.c
index 29caa136f6df6c8b1d276997bec892b3e452fed2..086657f4263d6ab9f7363c7a25c7ed8f24dae35e 100644 (file)
@@ -154,7 +154,7 @@ static mlt_service context_pop_service( deserialise_context context, enum servic
 {
        mlt_service result = NULL;
        
-       if ( type ) *type = invalid_type;
+       if ( type ) *type = mlt_invalid_type;
        if ( context->stack_service_size > 0 )
        {
                result = context->stack_service[ -- context->stack_service_size ];
@@ -543,13 +543,13 @@ static void on_end_producer( deserialise_context context, const xmlChar *name )
                mlt_service producer = NULL;
 
                qualify_property( context, properties, "resource" );
-               char *resource = trim( mlt_properties_get( properties, "resource" ) );
+               char *resource = mlt_properties_get( properties, "resource" );
 
                // Let Kino-SMIL src be a synonym for resource
                if ( resource == NULL )
                {
                        qualify_property( context, properties, "src" );
-                       resource = trim( mlt_properties_get( properties, "src" ) );
+                       resource = mlt_properties_get( properties, "src" );
                }
 
                // Instantiate the producer
@@ -590,7 +590,8 @@ static void on_end_producer( deserialise_context context, const xmlChar *name )
                // Track this producer
                track_service( context->destructors, producer, (mlt_destructor) mlt_producer_close );
                mlt_properties_set_lcnumeric( MLT_SERVICE_PROPERTIES( producer ), context->lc_numeric );
-               context->seekable &= mlt_properties_get_int( MLT_SERVICE_PROPERTIES( producer ), "seekable" );
+               if ( mlt_properties_get( MLT_SERVICE_PROPERTIES( producer ), "seekable" ) )
+                       context->seekable &= mlt_properties_get_int( MLT_SERVICE_PROPERTIES( producer ), "seekable" );
 
                // Propagate the properties
                qualify_property( context, properties, "resource" );
@@ -643,7 +644,7 @@ static void on_end_producer( deserialise_context context, const xmlChar *name )
                                        // Get the parent properties
                                        properties = MLT_SERVICE_PROPERTIES( parent );
                                
-                                       char *resource = trim( mlt_properties_get( properties, "resource" ) );
+                                       char *resource = mlt_properties_get( properties, "resource" );
                                
                                        // Put the parent producer back
                                        context_push_service( context, parent, type );
@@ -731,7 +732,7 @@ static void on_start_entry( deserialise_context context, const xmlChar *name, co
        if ( mlt_properties_get_data( temp, "producer", NULL ) != NULL )
        {
                mlt_playlist_clip_info info;
-               enum service_type parent_type = invalid_type;
+               enum service_type parent_type = mlt_invalid_type;
                mlt_service parent = context_pop_service( context, &parent_type );
                mlt_producer producer = mlt_properties_get_data( temp, "producer", NULL );
 
@@ -774,7 +775,7 @@ static void on_start_entry( deserialise_context context, const xmlChar *name, co
 static void on_end_entry( deserialise_context context, const xmlChar *name )
 {
        // Get the entry from the stack
-       enum service_type entry_type = invalid_type;
+       enum service_type entry_type = mlt_invalid_type;
        mlt_service entry = context_pop_service( context, &entry_type );
 
        if ( entry == NULL && entry_type != mlt_entry_type )
@@ -817,7 +818,7 @@ static void on_end_track( deserialise_context context, const xmlChar *name )
        if ( track != NULL && track_type == mlt_entry_type )
        {
                mlt_properties track_props = MLT_SERVICE_PROPERTIES( track );
-               enum service_type parent_type = invalid_type;
+               enum service_type parent_type = mlt_invalid_type;
                mlt_service parent = context_pop_service( context, &parent_type );
                mlt_multitrack multitrack = NULL;
 
@@ -903,7 +904,7 @@ static void on_end_filter( deserialise_context context, const xmlChar *name )
        mlt_service service = context_pop_service( context, &type );
        mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
 
-       enum service_type parent_type = invalid_type;
+       enum service_type parent_type = mlt_invalid_type;
        mlt_service parent = context_pop_service( context, &parent_type );
 
        if ( service != NULL && type == mlt_dummy_filter_type )
@@ -993,7 +994,7 @@ static void on_end_transition( deserialise_context context, const xmlChar *name
        mlt_service service = context_pop_service( context, &type );
        mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
 
-       enum service_type parent_type = invalid_type;
+       enum service_type parent_type = mlt_invalid_type;
        mlt_service parent = context_pop_service( context, &parent_type );
 
        if ( service != NULL && type == mlt_dummy_transition_type )
@@ -1093,7 +1094,7 @@ static void on_end_consumer( deserialise_context context, const xmlChar *name )
                {
                        qualify_property( context, properties, "resource" );
                        qualify_property( context, properties, "target" );
-                       char *resource = trim( mlt_properties_get( properties, "resource" ) );
+                       char *resource = mlt_properties_get( properties, "resource" );
 
                        if ( context->multi_consumer > 1 || context->qglsl )
                        {
@@ -1567,6 +1568,47 @@ static int file_exists( char *file )
        return exists;
 }
 
+// This function will add remaing services in the context service stack marked
+// with a "xml_retain" property to a property named "xml_retain" on the returned
+// service. The property is a mlt_properties data property.
+
+static void retain_services( struct deserialise_context_s *context, mlt_service service )
+{
+       mlt_properties retain_list = mlt_properties_new();
+       enum service_type type;
+       mlt_service retain_service = context_pop_service( context, &type );
+
+       while ( retain_service )
+       {
+               mlt_properties retain_properties = MLT_SERVICE_PROPERTIES( retain_service );
+               
+               if ( mlt_properties_get_int( retain_properties, "xml_retain" ) )
+               {
+                       // Remove the retained service from the destructors list.
+                       int i;
+                       for ( i = mlt_properties_count( context->destructors ) - 1; i >= 1; i -- )
+                       {
+                               const char *name = mlt_properties_get_name( context->destructors, i );
+                               if ( mlt_properties_get_data_at( context->destructors, i, NULL ) == retain_service )
+                               {
+                                       mlt_properties_set_data( context->destructors, name, retain_service, 0, NULL, NULL );
+                                       break;
+                               }
+                       }
+                       const char *name = mlt_properties_get( retain_properties, "id" );
+                       if ( name )
+                               mlt_properties_set_data( retain_list, name, retain_service, 0,
+                                       (mlt_destructor) mlt_service_close, NULL );
+               }
+               retain_service = context_pop_service( context, &type );
+       }
+       if ( mlt_properties_count( retain_list ) > 0 )
+       {
+               mlt_properties_set_data( MLT_SERVICE_PROPERTIES(service), "xml_retain", retain_list, 0,
+                       (mlt_destructor) mlt_properties_close, NULL );
+       }
+}
+
 mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype, const char *id, char *data )
 {
        xmlSAXHandler *sax, *sax_orig;
@@ -1709,7 +1751,7 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
        // may exist when trying to load glsl. or movit. services.
        // The "if requested" part can come from query string qglsl=1 or when
        // a service beginning with glsl. or movit. appears in the XML.
-       if ( mlt_properties_get_int( context->params, "qglsl" ) )
+       if ( mlt_properties_get_int( context->params, "qglsl" ) && strcmp( id, "xml-nogl" ) )
                context->qglsl = mlt_factory_consumer( profile, "qglsl", NULL );
 
        // Setup SAX callbacks for second pass
@@ -1815,6 +1857,8 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
                        (mlt_destructor) mlt_consumer_close, NULL );
 
                mlt_properties_set_int( properties, "seekable", context->seekable );
+
+               retain_services( context, service );
        }
        else
        {