]> git.sesse.net Git - mlt/commitdiff
Add (de)serialization of profile to XML.
authorDan Dennedy <dan@dennedy.org>
Sun, 29 Aug 2010 05:35:25 +0000 (22:35 -0700)
committerDan Dennedy <dan@dennedy.org>
Thu, 7 Oct 2010 05:19:13 +0000 (22:19 -0700)
In addition to the 'profile' element, one can also set the 'profile'
attribute of the root element to a named profile.

src/modules/xml/consumer_xml.c
src/modules/xml/mlt-xml.dtd
src/modules/xml/producer_xml.c

index fae400b0a8170b2b391d25411307aa1a95cb3f16..880fbc0a22ce42b43e5540045355397be3c39690 100644 (file)
@@ -630,7 +630,10 @@ xmlDocPtr xml_make_doc( mlt_consumer consumer, mlt_service service )
        xmlDocPtr doc = xmlNewDoc( _x("1.0") );
        xmlNodePtr root = xmlNewNode( NULL, _x("mlt") );
        struct serialise_context_s *context = calloc( 1, sizeof( struct serialise_context_s ) );
-       
+       xmlNodePtr profile_node = xmlNewChild( root, NULL, _x("profile"), NULL );
+       mlt_profile profile = mlt_service_profile( service );
+       char tmpstr[ 32 ];
+
        xmlDocSetRootElement( doc, root );
 
        // If we have root, then deal with it now
@@ -652,6 +655,27 @@ xmlDocPtr xml_make_doc( mlt_consumer consumer, mlt_service service )
                xmlNewProp( root, _x("title"), _x(mlt_properties_get( properties, "title" )) );
        mlt_properties_set_int( properties, "global_feed", 1 );
 
+       // Add a profile child element
+       xmlNewProp( profile_node, _x("description"), _x(profile->description) );
+       sprintf( tmpstr, "%d", profile->width );
+       xmlNewProp( profile_node, _x("width"), _x(tmpstr) );
+       sprintf( tmpstr, "%d", profile->height );
+       xmlNewProp( profile_node, _x("height"), _x(tmpstr) );
+       sprintf( tmpstr, "%d", profile->progressive );
+       xmlNewProp( profile_node, _x("progressive"), _x(tmpstr) );
+       sprintf( tmpstr, "%d", profile->sample_aspect_num );
+       xmlNewProp( profile_node, _x("sample_aspect_num"), _x(tmpstr) );
+       sprintf( tmpstr, "%d", profile->sample_aspect_den );
+       xmlNewProp( profile_node, _x("sample_aspect_den"), _x(tmpstr) );
+       sprintf( tmpstr, "%d", profile->display_aspect_num );
+       xmlNewProp( profile_node, _x("display_aspect_num"), _x(tmpstr) );
+       sprintf( tmpstr, "%d", profile->display_aspect_den );
+       xmlNewProp( profile_node, _x("display_aspect_den"), _x(tmpstr) );
+       sprintf( tmpstr, "%d", profile->frame_rate_num );
+       xmlNewProp( profile_node, _x("frame_rate_num"), _x(tmpstr) );
+       sprintf( tmpstr, "%d", profile->frame_rate_den );
+       xmlNewProp( profile_node, _x("frame_rate_den"), _x(tmpstr) );
+
        // Construct the context maps
        context->id_map = mlt_properties_new();
        context->hide_map = mlt_properties_new();
index bb7e1610c27e12d5c946cc73cc3fd20604ed7f31..6c1dc2ba7409b2aedb026b09e583fa59dba16f95 100644 (file)
@@ -1,8 +1,22 @@
 <?xml version='1.0' encoding='utf-8'?>
 
-<!-- MLT XML DTD v0.1.0 -->
+<!-- MLT XML DTD v0.2.0 -->
 
-<!ELEMENT mlt (producer | playlist | tractor | multitrack)+ >
+<!ELEMENT mlt (profile | producer | playlist | tractor | multitrack)+ >
+<!ELEMENT profile EMPTY >
+<!ATTLIST profile
+    name               CDATA    #IMPLIED
+    description        CDATA    #IMPLIED
+    display_aspect_den CDATA    #IMPLIED
+    display_aspect_num CDATA    #IMPLIED
+    frame_rate_den     CDATA    #REQUIRED
+    frame_rate_num     CDATA    #REQUIRED
+    height             CDATA    #REQUIRED
+    progressive        CDATA    #REQUIRED
+    sample_aspect_den  CDATA    #REQUIRED
+    sample_aspect_num  CDATA    #REQUIRED
+    width              CDATA    #REQUIRED
+>
 <!ELEMENT property ANY >
 <!ATTLIST property 
     name     CDATA    #REQUIRED
index bce62b87a0b1b76e8dfeb3bb97ef3db478a14917..b7c1fd6cd83046e23516d671e1429ee064cd563f 100644 (file)
@@ -82,6 +82,7 @@ struct deserialise_context_s
        const xmlChar *systemId;
        mlt_properties params;
        mlt_profile profile;
+       int pass;
 };
 typedef struct deserialise_context_s *deserialise_context;
 
@@ -288,6 +289,56 @@ static void attach_filters( mlt_service this, mlt_service that )
        }
 }
 
+static void on_start_profile( deserialise_context context, const xmlChar *name, const xmlChar **atts)
+{
+       mlt_profile p = context->profile;
+       for ( ; atts != NULL && *atts != NULL; atts += 2 )
+       {
+               if ( xmlStrcmp( atts[ 0 ], _x("name") ) == 0 || xmlStrcmp( atts[ 0 ], _x("profile") ) == 0 )
+               {
+                       mlt_profile my_profile = mlt_profile_init( _s(atts[ 1 ]) );
+                       if ( my_profile )
+                       {
+                               p->description = strdup( my_profile->description );
+                               p->display_aspect_den = my_profile->display_aspect_den;
+                               p->display_aspect_num = my_profile->display_aspect_num;
+                               p->frame_rate_den = my_profile->frame_rate_den;
+                               p->frame_rate_num = my_profile->frame_rate_num;
+                               p->width = my_profile->width;
+                               p->height = my_profile->height;
+                               p->progressive = my_profile->progressive;
+                               p->sample_aspect_den = my_profile->sample_aspect_den;
+                               p->sample_aspect_num = my_profile->sample_aspect_num;
+                               mlt_profile_close( my_profile );
+                       }
+               }
+               else if ( xmlStrcmp( atts[ 0 ], _x("description") ) == 0 )
+               {
+                       if ( p->description )
+                               free( p->description );
+                       p->description = strdup( _s(atts[ 1 ]) );
+               }
+               else if ( xmlStrcmp( atts[ 0 ], _x("display_aspect_den") ) == 0 )
+                       p->display_aspect_den = strtol( _s(atts[ 1 ]), NULL, 0 );
+               else if ( xmlStrcmp( atts[ 0 ], _x("display_aspect_num") ) == 0 )
+                       p->display_aspect_num = strtol( _s(atts[ 1 ]), NULL, 0 );
+               else if ( xmlStrcmp( atts[ 0 ], _x("sample_aspect_num") ) == 0 )
+                       p->sample_aspect_num = strtol( _s(atts[ 1 ]), NULL, 0 );
+               else if ( xmlStrcmp( atts[ 0 ], _x("sample_aspect_den") ) == 0 )
+                       p->sample_aspect_den = strtol( _s(atts[ 1 ]), NULL, 0 );
+               else if ( xmlStrcmp( atts[ 0 ], _x("width") ) == 0 )
+                       p->width = strtol( _s(atts[ 1 ]), NULL, 0 );
+               else if ( xmlStrcmp( atts[ 0 ], _x("height") ) == 0 )
+                       p->height = strtol( _s(atts[ 1 ]), NULL, 0 );
+               else if ( xmlStrcmp( atts[ 0 ], _x("progressive") ) == 0 )
+                       p->progressive = strtol( _s(atts[ 1 ]), NULL, 0 );
+               else if ( xmlStrcmp( atts[ 0 ], _x("frame_rate_num") ) == 0 )
+                       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 );
+       }
+}
+
 static void on_start_tractor( deserialise_context context, const xmlChar *name, const xmlChar **atts)
 {
        mlt_tractor tractor = mlt_tractor_new( );
@@ -1054,6 +1105,14 @@ static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **at
        deserialise_context context = ( deserialise_context )( xmlcontext->_private );
        
 //printf("on_start_element: %s\n", name );
+       if ( context->pass == 0 )
+       {
+               if ( xmlStrcmp( name, _x("mlt") ) == 0 ||
+                    xmlStrcmp( name, _x("profile") ) == 0 ||
+                    xmlStrcmp( name, _x("profileinfo") ) == 0 )
+                       on_start_profile( context, name, atts );
+               return;
+       }
        context->branch[ context->depth ] ++;
        context->depth ++;
        
@@ -1395,12 +1454,6 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
 
        // Setup SAX callbacks
        sax->startElement = on_start_element;
-       sax->endElement = on_end_element;
-       sax->characters = on_characters;
-       sax->cdataBlock = on_characters;
-       sax->internalSubset = on_internal_subset;
-       sax->entityDecl = on_entity_declaration;
-       sax->getEntity = on_get_entity;
 
        // Setup libxml2 SAX parsing
        xmlInitParser(); 
@@ -1424,19 +1477,53 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype,
                return NULL;
        }
 
+       // Parse
        xmlcontext->sax = sax;
-       xmlcontext->_private = ( void* )context;
+       xmlcontext->_private = ( void* )context;        
+       xmlParseDocument( xmlcontext );
        
+       // Cleanup after parsing
+       xmlcontext->sax = NULL;
+       xmlcontext->_private = NULL;
+       xmlFreeParserCtxt( xmlcontext );
+
+       // Setup the second pass
+       context->pass ++;
+       if ( info == 0 )
+               xmlcontext = xmlCreateFileParserCtxt( filename );
+       else
+               xmlcontext = xmlCreateMemoryParserCtxt( data, strlen( data ) );
+
+       // Invalid context - clean up and return NULL
+       if ( xmlcontext == NULL )
+       {
+               mlt_properties_close( context->producer_map );
+               mlt_properties_close( context->destructors );
+               mlt_properties_close( context->params );
+               xmlFreeDoc( context->entity_doc );
+               free( context );
+               free( sax );
+               free( filename );
+               return NULL;
+       }
+
+       // Setup SAX callbacks
+       sax->endElement = on_end_element;
+       sax->characters = on_characters;
+       sax->cdataBlock = on_characters;
+       sax->internalSubset = on_internal_subset;
+       sax->entityDecl = on_entity_declaration;
+       sax->getEntity = on_get_entity;
+
        // Parse
+       xmlcontext->sax = sax;
+       xmlcontext->_private = ( void* )context;
        xmlParseDocument( xmlcontext );
        well_formed = xmlcontext->wellFormed;
-       
+
        // Cleanup after parsing
        xmlFreeDoc( context->entity_doc );
        free( sax );
-       xmlcontext->sax = NULL;
-       xmlcontext->_private = NULL;
-       xmlFreeParserCtxt( xmlcontext );
        xmlMemoryDump( ); // for debugging
 
        // Get the last producer on the stack