]> git.sesse.net Git - mlt/commitdiff
reorganized consumer_westley.
authorddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Thu, 25 Mar 2004 17:59:15 +0000 (17:59 +0000)
committerddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Thu, 25 Mar 2004 17:59:15 +0000 (17:59 +0000)
added branch tracking and other bugfixes to producer_westley.

git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@244 d19143bc-622f-0410-bfdd-b5b2a6649095

demo/mlt_push
demo/new.westley
src/modules/westley/consumer_westley.c
src/modules/westley/producer_westley.c

index 546d0b605a0c90a43ab62b7b35e200dd496fb7f4..c21ccc1543d7eed38f0f84f1173deb43eeac1bd9 100644 (file)
@@ -16,5 +16,5 @@ composite in=50 out=75 a_track=0 b_track=2 \
 start=-100%,0:100%x100%:100 \
 end=0,0:100%x100%:100 \
 -transition \
-mix start=1 end=0 in=50 out=75 a_track=2 b_track=1 \
+mix:-1 in=50 out=75 a_track=1 b_track=2 \
 $*
index 70d34a35c6a5271fd92266f65a22e6d50398f45c..e5005b9f32b1f31d4258be90abc976b051b40977 100644 (file)
@@ -10,7 +10,7 @@
          </playlist>
          <playlist>
                <blank length="25"/>
-               <producer id="bar" in="100" out="199">
+               <producer id="bar" in="100" out="149">
                  <property name="resource">clip3.mpeg</property>
                </producer>
                <entry out="99" producer="bar"/>
@@ -38,7 +38,7 @@
          </playlist>
          <playlist>
                <blank length="25"/>
-               <producer id="bar" in="100" out="199">
+               <producer id="bar" in="100" out="149">
                  <property name="resource">clip3.mpeg</property>
                </producer>
                <entry out="99" producer="bar"/>
index d31cccfa832232e30797fbfce6f86ae66308821d..0b15204c7fd1fee51e7a67a7e0dec13619a5351c 100644 (file)
@@ -155,11 +155,11 @@ static void serialise_multitrack( serialise_context context, mlt_service service
                for ( i = 0; i < mlt_multitrack_count( MLT_MULTITRACK( service ) ); i++ )
                        serialise_service( context, MLT_SERVICE( mlt_multitrack_track( MLT_MULTITRACK( service ), i ) ), node );
        }
-               
        else
        {
+               // Create the multitrack node
                child = xmlNewChild( node, NULL, "multitrack", NULL );
-       
+               
                // Set the id
                if ( mlt_properties_get( properties, "id" ) == NULL )
                {
@@ -202,9 +202,11 @@ static void serialise_playlist( serialise_context context, mlt_service service,
                {
                        if ( ! mlt_playlist_get_clip_info( MLT_PLAYLIST( service ), &info, i ) )
                        {
-                               if ( info.producer && strcmp( mlt_properties_get( mlt_producer_properties( info.producer ), "mlt_service" ), "blank" ) != 0 )
+                               if ( info.producer != NULL )
                                {
-                                       serialise_service( context, MLT_SERVICE( info.producer ), node );
+                                       char *service_s = mlt_properties_get( mlt_producer_properties( info.producer ), "mlt_service" );
+                                       if ( service_s != NULL && strcmp( service_s, "blank" ) != 0 )
+                                               serialise_service( context, MLT_SERVICE( info.producer ), node );
                                }
                        }
                }
@@ -230,7 +232,8 @@ static void serialise_playlist( serialise_context context, mlt_service service,
                {
                        if ( ! mlt_playlist_get_clip_info( MLT_PLAYLIST( service ), &info, i ) )
                        {
-                               if ( strcmp( mlt_properties_get( mlt_producer_properties( info.producer ), "mlt_service" ), "blank" ) == 0 )
+                               char *service_s = mlt_properties_get( mlt_producer_properties( info.producer ), "mlt_service" );
+                               if ( service_s != NULL && strcmp( service_s, "blank" ) == 0 )
                                {
                                        char length[ 20 ];
                                        length[ 19 ] = '\0';
@@ -405,52 +408,63 @@ static void serialise_service( serialise_context context, mlt_service service, x
        }
 }
 
+xmlDocPtr westley_make_doc( mlt_service service )
+{
+       xmlDocPtr doc = xmlNewDoc( "1.0" );
+       xmlNodePtr root = xmlNewNode( NULL, "westley" );
+       struct serialise_context_s *context = calloc( 1, sizeof( struct serialise_context_s ) );
+       
+       xmlDocSetRootElement( doc, root );
+               
+       // Construct the context maps
+       context->producer_map = mlt_properties_new();
+       context->hide_map = mlt_properties_new();
+       
+       // Ensure producer is a framework producer
+       mlt_properties_set( mlt_service_properties( service ), "mlt_type", "mlt_producer" );
+
+       // In pass one, we serialise the end producers and playlists,
+       // adding them to a map keyed by address.
+       serialise_service( context, service, root );
+
+       // In pass two, we serialise the tractor and reference the
+       // producers and playlists
+       context->pass++;
+       serialise_service( context, service, root );
+
+       // Cleanup resource
+       mlt_properties_close( context->producer_map );
+       mlt_properties_close( context->hide_map );
+       free( context );
+       
+       return doc;
+}
+
+
 static int consumer_start( mlt_consumer this )
 {
        mlt_service inigo = NULL;
-       xmlDoc *doc = xmlNewDoc( "1.0" );
-       xmlNode *root = xmlNewNode( NULL, "westley" );
-       xmlDocSetRootElement( doc, root );
+       xmlDocPtr doc = NULL;
        
        // Get the producer service
        mlt_service service = mlt_service_get_producer( mlt_consumer_service( this ) );
        if ( service != NULL )
        {
-               struct serialise_context_s *context = calloc( 1, sizeof( struct serialise_context_s ) );
-               
-               // Construct the context maps
-               context->producer_map = mlt_properties_new();
-               context->hide_map = mlt_properties_new();
-               
                // Remember inigo
                if ( mlt_properties_get( mlt_service_properties( service ), "mlt_service" ) != NULL &&
                                strcmp( mlt_properties_get( mlt_service_properties( service ), "mlt_service" ), "inigo" ) == 0 )
                        inigo = service;
                
-               // Ensure producer is a framework producer
-               mlt_properties_set( mlt_service_properties( service ), "mlt_type", "mlt_producer" );
-
-               // In pass one, we serialise the end producers and playlists,
-               // adding them to a map keyed by address.
-               serialise_service( context, service, root );
-
-               // In pass two, we serialise the tractor and reference the
-               // producers and playlists
-               context->pass++;
-               serialise_service( context, service, root );
-
-               // Cleanup resource
-               mlt_properties_close( context->producer_map );
-               mlt_properties_close( context->hide_map );
-               free( context );
+               doc = westley_make_doc( service );
                
                if ( mlt_properties_get( mlt_consumer_properties( this ), "resource" ) == NULL )
                        xmlDocFormatDump( stdout, doc, 1 );
                else
                        xmlSaveFormatFile( mlt_properties_get( mlt_consumer_properties( this ), "resource" ), doc, 1 );
+               
+               xmlFreeDoc( doc );
        }
-
-       xmlFreeDoc( doc );
+       
        mlt_consumer_stop( this );
 
        return 0;
index 89ca817f04848d1e760763b8d1d9a3ce89b969ef..4ddc892b7424915f9d9ff7bf255ff3a3f2cc1b88 100644 (file)
 #include <libxml/tree.h>
 
 #define STACK_SIZE 1000
+#define BRANCH_SIG_LEN 4000
+
+#undef DEBUG
+#ifdef DEBUG
+extern xmlDocPtr westley_make_doc( mlt_service service );
+#endif
 
 struct deserialise_context_s
 {
@@ -47,9 +53,25 @@ struct deserialise_context_s
        xmlNodePtr stack_node[ STACK_SIZE ];
        int stack_node_size;
        xmlDocPtr entity_doc;
+       int depth;
+       int branch[ STACK_SIZE ];
 };
 typedef struct deserialise_context_s *deserialise_context;
 
+/** Convert the numerical current branch address to a dot-delimited string.
+*/
+static char *serialise_branch( deserialise_context this, char *s )
+{
+       int i;
+       
+       s[0] = 0;
+       for ( i = 0; i < this->depth; i++ )
+       {
+               int len = strlen( s );
+               snprintf( s + len, BRANCH_SIG_LEN - len, "%d.", this->branch[ i ] );
+       }
+       return s;
+}
 
 /** Push a service.
 */
@@ -58,7 +80,16 @@ static int context_push_service( deserialise_context this, mlt_service that )
 {
        int ret = this->stack_service_size >= STACK_SIZE - 1;
        if ( ret == 0 )
-               this->stack_service[ this->stack_service_size ++ ] = that;
+       {
+               this->stack_service[ this->stack_service_size++ ] = that;
+               
+               // Record the tree branch on which this service lives
+               if ( mlt_properties_get( mlt_service_properties( that ), "_westley_branch" ) == NULL )
+               {
+                       char s[ BRANCH_SIG_LEN ];
+                       mlt_properties_set( mlt_service_properties( that ), "_westley_branch", serialise_branch( this, s ) );
+               }
+       }
        return ret;
 }
 
@@ -298,48 +329,58 @@ static int add_producer( deserialise_context context, mlt_service service, mlt_p
 {
        // Get the parent producer
        mlt_service producer = context_pop_service( context );
+
        if ( producer != NULL )
        {
-               char *resource = mlt_properties_get( mlt_service_properties( producer ), "resource" );
-               
-               // Put the parent producer back
-               context_push_service( context, producer );
-                       
-               // If the parent producer is a multitrack or playlist (not a track or entry)
-               if ( resource && ( strcmp( resource, "<playlist>" ) == 0 ||
-                       strcmp( resource, "<multitrack>" ) == 0 ) )
+               char current_branch[ BRANCH_SIG_LEN ];
+               char *service_branch = mlt_properties_get( mlt_service_properties( producer ), "_westley_branch" );
+
+               // Validate the producer from the stack is an ancestor and not predecessor
+               serialise_branch( context, current_branch );
+               if ( service_branch != NULL && strncmp( service_branch, current_branch, strlen( service_branch ) ) == 0 )
                {
-                       if ( strcmp( resource, "<playlist>" ) == 0 )
-                       {
-                               // Append this producer to the playlist
-                               mlt_playlist_append_io( MLT_PLAYLIST( producer ), 
-                                       MLT_PRODUCER( service ), in, out );
-                       }
-                       else
-                       {
-                               mlt_properties properties = mlt_service_properties( service );
-                               
-                               // Set this producer on the multitrack
-                               mlt_multitrack_connect( MLT_MULTITRACK( producer ),
-                                       MLT_PRODUCER( service ),
-                                       mlt_multitrack_count( MLT_MULTITRACK( producer ) ) );
+                       char *resource = mlt_properties_get( mlt_service_properties( producer ), "resource" );
+                       
+                       // Put the parent producer back
+                       context_push_service( context, producer );
                                
-                               // Set the hide state of the track producer
-                               char *hide_s = mlt_properties_get( properties, "hide" );
-                               if ( hide_s != NULL )
+                       // If the parent producer is a multitrack or playlist (not a track or entry)
+                       if ( resource && ( strcmp( resource, "<playlist>" ) == 0 ||
+                               strcmp( resource, "<multitrack>" ) == 0 ) )
+                       {
+//printf( "add_producer: current branch %s service branch %s (%d)\n", current_branch, service_branch, strncmp( service_branch, current_branch, strlen( service_branch ) ) );
+                               if ( strcmp( resource, "<playlist>" ) == 0 )
                                {
-                                       if ( strcmp( hide_s, "video" ) == 0 )
-                                               mlt_properties_set_int( properties, "hide", 1 );
-                                       else if ( strcmp( hide_s, "audio" ) == 0 )
-                                               mlt_properties_set_int( properties, "hide", 2 );
-                                       else if ( strcmp( hide_s, "both" ) == 0 )
-                                               mlt_properties_set_int( properties, "hide", 3 );
+                                       // Append this producer to the playlist
+                                       mlt_playlist_append_io( MLT_PLAYLIST( producer ), 
+                                               MLT_PRODUCER( service ), in, out );
                                }
-
+                               else
+                               {
+                                       mlt_properties properties = mlt_service_properties( service );
+                                       
+                                       // Set this producer on the multitrack
+                                       mlt_multitrack_connect( MLT_MULTITRACK( producer ),
+                                               MLT_PRODUCER( service ),
+                                               mlt_multitrack_count( MLT_MULTITRACK( producer ) ) );
+                                       
+                                       // Set the hide state of the track producer
+                                       char *hide_s = mlt_properties_get( properties, "hide" );
+                                       if ( hide_s != NULL )
+                                       {
+                                               if ( strcmp( hide_s, "video" ) == 0 )
+                                                       mlt_properties_set_int( properties, "hide", 1 );
+                                               else if ( strcmp( hide_s, "audio" ) == 0 )
+                                                       mlt_properties_set_int( properties, "hide", 2 );
+                                               else if ( strcmp( hide_s, "both" ) == 0 )
+                                                       mlt_properties_set_int( properties, "hide", 3 );
+                                       }
+       
+                               }
+                               // Normally, the enclosing entry or track will pop this service off
+                               // In its absence we do not push it on.
+                               return 1;
                        }
-                       // Normally, the enclosing entry or track will pop this service off
-                       // In its absence we do not push it on.
-                       return 1;
                }
        }
        return 0;
@@ -351,7 +392,7 @@ static void on_end_multitrack( deserialise_context context, const xmlChar *name
        mlt_service producer = context_pop_service( context );
        if ( producer == NULL )
                return;
-
+       
        // Get the tractor from the stack
        mlt_service service = context_pop_service( context );
        
@@ -361,9 +402,14 @@ static void on_end_multitrack( deserialise_context context, const xmlChar *name
                resource = mlt_properties_get( mlt_service_properties( service ), "resource" );
        if ( service == NULL || resource == NULL || strcmp( resource, "<tractor>" ) )
        {
+//printf("creating a tractor\n");
+               char current_branch[ BRANCH_SIG_LEN ];
+               
                // Put the anonymous service back onto the stack!
-               context_push_service( context, service );
+               if ( service != NULL )
+                       context_push_service( context, service );
                
+               // Fabricate the tractor
                service = mlt_tractor_service( mlt_tractor_init() );
                track_service( context->destructors, service, (mlt_destructor) mlt_tractor_close );
                
@@ -372,6 +418,8 @@ static void on_end_multitrack( deserialise_context context, const xmlChar *name
                mlt_properties_set_position( properties, "length", mlt_producer_get_out( MLT_PRODUCER( producer ) ) + 1 );
                mlt_producer_set_in_and_out( MLT_PRODUCER( service ), 0, mlt_producer_get_out( MLT_PRODUCER( producer ) ) );
                mlt_properties_set_double( properties, "fps", mlt_producer_get_fps( MLT_PRODUCER( producer ) ) );
+               
+               mlt_properties_set( properties, "_westley_branch", serialise_branch( context, current_branch ) );
        }
        
        // Connect the tractor to the multitrack
@@ -379,7 +427,7 @@ static void on_end_multitrack( deserialise_context context, const xmlChar *name
        mlt_properties_set_data( mlt_service_properties( service ), "multitrack",
                MLT_MULTITRACK( producer ), 0, NULL, NULL );
 
-       // See if the producer should be added to a playlist or multitrack
+       // See if the tractor should be added to a playlist or multitrack
        add_producer( context, service, 0, mlt_producer_get_out( MLT_PRODUCER( producer ) ) );
        
        // Always push the multitrack back onto the stack for filters and transitions
@@ -835,6 +883,10 @@ static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **at
        struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx;
        deserialise_context context = ( deserialise_context )( xmlcontext->_private );
        
+//printf("on_start_element: %s\n", name );
+       context->branch[ context->depth ] ++;
+       context->depth ++;
+       
        // Build a tree from nodes within a property value
        if ( context->is_value == 1 )
        {
@@ -882,6 +934,7 @@ static void on_end_element( void *ctx, const xmlChar *name )
        struct _xmlParserCtxt *xmlcontext = ( struct _xmlParserCtxt* )ctx;
        deserialise_context context = ( deserialise_context )( xmlcontext->_private );
        
+//printf("on_end_element: %s\n", name );
        if ( context->is_value == 1 && strcmp( name, "property" ) != 0 )
                context_pop_node( context );
        else if ( strcmp( name, "multitrack" ) == 0 )
@@ -902,6 +955,9 @@ static void on_end_element( void *ctx, const xmlChar *name )
                on_end_filter( context, name );
        else if ( strcmp( name, "transition" ) == 0 )
                on_end_transition( context, name );
+
+       context->branch[ context->depth ] = 0;
+       context->depth --;
 }
 
 static void on_characters( void *ctx, const xmlChar *ch, int len )
@@ -1012,12 +1068,20 @@ mlt_producer producer_westley_init( char *filename )
                // Verify it is a producer service (mlt_type="mlt_producer")
                // (producer, playlist, multitrack)
                char *type = mlt_properties_get( mlt_service_properties( service ), "mlt_type" );
-               if ( type == NULL || ( strcmp( type, "mlt_producer" ) != 0 ) )
+               if ( type == NULL || ( strcmp( type, "mlt_producer" ) != 0 && strcmp( type, "producer" ) != 0 ) )
                        service = NULL;
        }
 
+#ifdef DEBUG
+       xmlDocPtr doc = westley_make_doc( service );
+       xmlDocFormatDump( stdout, doc, 1 );
+       xmlFreeDoc( doc );
+       service = NULL;
+#endif
+       
        if ( well_formed && service != NULL )
        {
+               
                // Need the complete producer list for various reasons
                properties = context->destructors;