]> git.sesse.net Git - mlt/blobdiff - src/modules/xml/producer_xml.c
Fix XML and melt producers producer_avformat cache size.
[mlt] / src / modules / xml / producer_xml.c
index b7c1fd6cd83046e23516d671e1429ee064cd563f..bc73f49c561092a3f2a151d414d9f95c10755ab8 100644 (file)
@@ -83,6 +83,7 @@ struct deserialise_context_s
        mlt_properties params;
        mlt_profile profile;
        int pass;
+       char *lc_numeric;
 };
 typedef struct deserialise_context_s *deserialise_context;
 
@@ -128,6 +129,8 @@ static int context_push_service( deserialise_context this, mlt_service that, enu
 static mlt_service context_pop_service( deserialise_context this, enum service_type *type )
 {
        mlt_service result = NULL;
+       
+       *type = invalid_type;
        if ( this->stack_service_size > 0 )
        {
                result = this->stack_service[ -- this->stack_service_size ];
@@ -309,6 +312,8 @@ static void on_start_profile( deserialise_context context, const xmlChar *name,
                                p->progressive = my_profile->progressive;
                                p->sample_aspect_den = my_profile->sample_aspect_den;
                                p->sample_aspect_num = my_profile->sample_aspect_num;
+                               p->colorspace = my_profile->colorspace;
+                               p->is_explicit = 1;
                                mlt_profile_close( my_profile );
                        }
                }
@@ -317,6 +322,7 @@ static void on_start_profile( deserialise_context context, const xmlChar *name,
                        if ( p->description )
                                free( p->description );
                        p->description = strdup( _s(atts[ 1 ]) );
+                       p->is_explicit = 1;
                }
                else if ( xmlStrcmp( atts[ 0 ], _x("display_aspect_den") ) == 0 )
                        p->display_aspect_den = strtol( _s(atts[ 1 ]), NULL, 0 );
@@ -336,6 +342,8 @@ static void on_start_profile( deserialise_context context, const xmlChar *name,
                        p->frame_rate_num = strtol( _s(atts[ 1 ]), NULL, 0 );
                else if ( xmlStrcmp( atts[ 0 ], _x("frame_rate_den") ) == 0 )
                        p->frame_rate_den = strtol( _s(atts[ 1 ]), NULL, 0 );
+               else if ( xmlStrcmp( atts[ 0 ], _x("colorspace") ) == 0 )
+                       p->colorspace = strtol( _s(atts[ 1 ]), NULL, 0 );
        }
 }
 
@@ -346,6 +354,7 @@ static void on_start_tractor( deserialise_context context, const xmlChar *name,
        mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
 
        track_service( context->destructors, service, (mlt_destructor) mlt_tractor_close );
+       mlt_properties_set_lcnumeric( MLT_SERVICE_PROPERTIES( service ), context->lc_numeric );
 
        for ( ; atts != NULL && *atts != NULL; atts += 2 )
                mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), (const char*) atts[0], atts[1] == NULL ? "" : (const char*) atts[1] );
@@ -393,6 +402,7 @@ static void on_start_multitrack( deserialise_context context, const xmlChar *nam
                tractor = mlt_tractor_new( );
                parent = MLT_TRACTOR_SERVICE( tractor );
                track_service( context->destructors, parent, (mlt_destructor) mlt_tractor_close );
+               mlt_properties_set_lcnumeric( MLT_SERVICE_PROPERTIES( parent ), context->lc_numeric );
                type = mlt_tractor_type;
 
                // Flag it as a synthesised tractor for clean up later
@@ -474,7 +484,7 @@ static void on_end_playlist( deserialise_context context, const xmlChar *name )
        }
        else
        {
-               fprintf( stderr, "Invalid state of playlist end\n" );
+               fprintf( stderr, "Invalid state of playlist end %d\n", type );
        }
 }
 
@@ -553,14 +563,20 @@ static void on_end_producer( deserialise_context context, const xmlChar *name )
                // Instantiate the producer
                if ( mlt_properties_get( properties, "mlt_service" ) != NULL )
                {
-                       char temp[ 1024 ];
-                       strncpy( temp, mlt_properties_get( properties, "mlt_service" ), 1024 );
-                       if ( resource != NULL )
+                       char *service_name = mlt_properties_get( properties, "mlt_service" );
+                       if ( resource )
                        {
+                               char *temp = calloc( 1, strlen( service_name ) + strlen( resource ) + 2 );
+                               strcat( temp, service_name );
                                strcat( temp, ":" );
-                               strncat( temp, resource, 1023 - strlen( temp ) );
+                               strcat( temp, resource );
+                               producer = MLT_SERVICE( mlt_factory_producer( context->profile, NULL, temp ) );
+                               free( temp );
+                       }
+                       else
+                       {
+                               producer = MLT_SERVICE( mlt_factory_producer( context->profile, NULL, service_name ) );
                        }
-                       producer = MLT_SERVICE( mlt_factory_producer( context->profile, NULL, temp ) );
                }
 
                // Just in case the plugin requested doesn't exist...
@@ -575,6 +591,7 @@ 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 );
 
                // Propogate the properties
                qualify_property( context, properties, "resource" );
@@ -862,6 +879,10 @@ static void on_end_track( deserialise_context context, const xmlChar *name )
                                else if ( strcmp( hide_s, "both" ) == 0 )
                                        mlt_properties_set_int( producer_props, "hide", 3 );
                        }
+
+                       // Set the size of the producer_avformat cache to the number of tracks.
+                       if ( multitrack->count > mlt_service_cache_get_size( MLT_MULTITRACK_SERVICE(multitrack), "producer_avformat" ) )
+                               mlt_service_cache_set_size( MLT_MULTITRACK_SERVICE(multitrack), "producer_avformat", multitrack->count + 2 );
                }
 
                if ( parent != NULL )
@@ -905,6 +926,7 @@ static void on_end_filter( deserialise_context context, const xmlChar *name )
                mlt_properties filter_props = MLT_SERVICE_PROPERTIES( filter );
 
                track_service( context->destructors, filter, (mlt_destructor) mlt_filter_close );
+               mlt_properties_set_lcnumeric( MLT_SERVICE_PROPERTIES( filter ), context->lc_numeric );
 
                // Propogate the properties
                qualify_property( context, properties, "resource" );
@@ -981,6 +1003,7 @@ static void on_end_transition( deserialise_context context, const xmlChar *name
                mlt_properties effect_props = MLT_SERVICE_PROPERTIES( effect );
 
                track_service( context->destructors, effect, (mlt_destructor) mlt_transition_close );
+               mlt_properties_set_lcnumeric( MLT_SERVICE_PROPERTIES( effect ), context->lc_numeric );
 
                // Propogate the properties
                qualify_property( context, properties, "resource" );
@@ -1082,6 +1105,10 @@ static void on_end_property( deserialise_context context, const xmlChar *name )
                        // Serialise the tree to get value
                        xmlDocDumpMemory( context->value_doc, &value, &size );
                        mlt_properties_set( properties, context->property, _s(value) );
+#ifdef WIN32
+                       xmlFreeFunc xmlFree = NULL;
+                       xmlMemGet( &xmlFree, NULL, NULL, NULL);
+#endif
                        xmlFree( value );
                        xmlFreeDoc( context->value_doc );
                        context->value_doc = NULL;
@@ -1117,7 +1144,7 @@ static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **at
        context->depth ++;
        
        // Build a tree from nodes within a property value
-       if ( context->is_value == 1 )
+       if ( context->is_value == 1 && context->pass == 1 )
        {
                xmlNodePtr node = xmlNewNode( NULL, name );
                
@@ -1159,8 +1186,15 @@ static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **at
        else if ( xmlStrcmp( name, _x("property") ) == 0 )
                on_start_property( context, name, atts );
        else if ( xmlStrcmp( name, _x("westley") ) == 0 || xmlStrcmp( name, _x("mlt") ) == 0 )
+       {
                for ( ; atts != NULL && *atts != NULL; atts += 2 )
-                       mlt_properties_set( context->producer_map, ( const char * )atts[ 0 ], ( const char * )atts[ 1 ] );
+               {
+                       if ( xmlStrcmp( atts[0], _x("LC_NUMERIC") ) )
+                               mlt_properties_set( context->producer_map, _s( atts[0] ), _s(atts[1] ) );
+                       else if ( !context->lc_numeric )
+                               context->lc_numeric = strdup( _s( atts[1] ) );
+               }
+       }
 }
 
 static void on_end_element( void *ctx, const xmlChar *name )
@@ -1169,7 +1203,7 @@ static void on_end_element( void *ctx, const xmlChar *name )
        deserialise_context context = ( deserialise_context )( xmlcontext->_private );
        
 //printf("on_end_element: %s\n", name );
-       if ( context->is_value == 1 && xmlStrcmp( name, _x("property") ) != 0 )
+       if ( context->is_value == 1 && context->pass == 1 && xmlStrcmp( name, _x("property") ) != 0 )
                context_pop_node( context );
        else if ( xmlStrcmp( name, _x("multitrack") ) == 0 )
                on_end_multitrack( context, name );
@@ -1486,6 +1520,8 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
        xmlcontext->sax = NULL;
        xmlcontext->_private = NULL;
        xmlFreeParserCtxt( xmlcontext );
+       context->stack_node_size = 0;
+       context->stack_service_size = 0;
 
        // Setup the second pass
        context->pass ++;
@@ -1556,7 +1592,7 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
                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 )
+                       if ( mlt_properties_get_data_at( properties, i, NULL ) == service )
                        {
                                mlt_properties_set_data( properties, name, service, 0, NULL, NULL );
                                break;
@@ -1601,6 +1637,8 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
        if ( context->params != NULL )
                mlt_properties_close( context->params );
        mlt_properties_close( context->destructors );
+       if ( context->lc_numeric )
+               free( context->lc_numeric );
        free( context );
        free( filename );