]> git.sesse.net Git - mlt/blobdiff - src/melt/melt.c
fix infinite loop regression with consumer producer on xml (3458967)
[mlt] / src / melt / melt.c
index 5ff487ea1e94cf0690e383baf4628370269e5ef8..8b221cadbdd0cffe4d71fb1720694a10be0e3cb7 100644 (file)
@@ -262,7 +262,49 @@ static mlt_consumer create_consumer( mlt_profile profile, char *id )
 static void load_consumer( mlt_consumer *consumer, mlt_profile profile, int argc, char **argv )
 {
        int i;
+       int multi = 0;
+
        for ( i = 1; i < argc; i ++ )
+               multi += !strcmp( argv[ i ], "-consumer" );
+
+       if ( multi > 1 )
+       {
+               // If there is more than one -consumer use the 'multi' consumer.
+               int k = 0;
+               char key[20];
+
+               if ( *consumer )
+                       mlt_consumer_close( *consumer );
+               *consumer = create_consumer( profile, "multi" );
+               mlt_properties properties = MLT_CONSUMER_PROPERTIES( *consumer );
+               for ( i = 1; i < argc; i ++ )
+               {
+                       if ( !strcmp( argv[ i ], "-consumer" ) && argv[ i + 1 ])
+                       {
+                               // Create a properties object for each sub-consumer
+                               mlt_properties new_props = mlt_properties_new();
+                               snprintf( key, sizeof(key), "%d", k++ );
+                               mlt_properties_set_data( properties, key, new_props, 0,
+                                       (mlt_destructor) mlt_properties_close, NULL );
+                               if ( strchr( argv[i + 1], ':' ) )
+                               {
+                                       char *temp = strdup( argv[++i] );
+                                       char *service = temp;
+                                       char *target = strchr( temp, ':' );
+                                       *target++ = 0;
+                                       mlt_properties_set( new_props, "mlt_service", service );
+                                       mlt_properties_set( new_props, "target", target );
+                               }
+                               else
+                               {
+                                       mlt_properties_set( new_props, "mlt_service", argv[ ++i ] );
+                               }
+                               while ( argv[ i + 1 ] && strchr( argv[ i + 1 ], '=' ) )
+                                       mlt_properties_parse( new_props, argv[ ++ i ] );
+                       }
+               }
+       }
+       else for ( i = 1; i < argc; i ++ )
        {
                if ( !strcmp( argv[ i ], "-consumer" ) )
                {
@@ -272,7 +314,7 @@ static void load_consumer( mlt_consumer *consumer, mlt_profile profile, int argc
                        if ( *consumer )
                        {
                                mlt_properties properties = MLT_CONSUMER_PROPERTIES( *consumer );
-                               while ( argv[ i + 1 ] != NULL && strstr( argv[ i + 1 ], "=" ) )
+                               while ( argv[ i + 1 ] != NULL && strchr( argv[ i + 1 ], '=' ) )
                                        mlt_properties_parse( properties, argv[ ++ i ] );
                        }
                }
@@ -354,8 +396,9 @@ static void transport( mlt_producer producer, mlt_consumer consumer )
                                        int current_position = mlt_producer_position( producer );
                                        if ( current_position > last_position )
                                        {
-                                               fprintf( stderr, "Current Frame: %10d, percentage: %10d\r",
-                                                       current_position, 100 * current_position / total_length );
+                                               fprintf( stderr, "Current Frame: %10d, percentage: %10d%c",
+                                                       current_position, 100 * current_position / total_length,
+                                                       progress == 2 ? '\n' : '\r' );
                                                last_position = current_position;
                                        }
                                }
@@ -659,6 +702,10 @@ int main( int argc, char **argv )
                {
                        is_progress = 1;
                }
+               else if ( !strcmp( argv[ i ], "-progress2" ) )
+               {
+                       is_progress = 2;
+               }
                // Look for the query option
                else if ( !strcmp( argv[ i ], "-query" ) )
                {
@@ -780,6 +827,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 +924,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 );