]> 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 526e95c9df085edc553aa9f9d681c15538c7df2c..086657f4263d6ab9f7363c7a25c7ed8f24dae35e 100644 (file)
@@ -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" );
@@ -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
        {