X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Fwestley%2Fproducer_westley.c;h=094558be945d5ddaa5fad986cef8a84cf2f91d1b;hb=23571c330fd1644833dcb73661ac987eda177200;hp=ad21f93c46734ddd7bb375ae58edea485dd4e4a5;hpb=dc57bd7b4020663b49149f44f1607c4d78c4d2d5;p=melted diff --git a/src/modules/westley/producer_westley.c b/src/modules/westley/producer_westley.c index ad21f93..094558b 100644 --- a/src/modules/westley/producer_westley.c +++ b/src/modules/westley/producer_westley.c @@ -18,7 +18,9 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// TODO: destroy unreferenced producers +// TODO: destroy unreferenced producers (they are currently destroyed +// when the returned producer is closed). +// TODO: try using XmlReader interface to avoid global context issues in sax. #include "producer_westley.h" #include @@ -91,6 +93,9 @@ static void on_start_tractor( deserialise_context context, const xmlChar *name, mlt_properties_set_position( properties, "length", length ); } + if ( mlt_properties_get( properties, "id" ) != NULL ) + mlt_properties_set_data( context->producer_map, mlt_properties_get( properties, "id" ), service, 0, NULL, NULL ); + context_push_service( context, service ); } @@ -121,6 +126,8 @@ static void on_start_playlist( deserialise_context context, const xmlChar *name, for ( ; atts != NULL && *atts != NULL; atts += 2 ) { mlt_properties_set( properties, ( char* )atts[0], ( char* )atts[1] ); + + // Out will be overwritten later as we append, so we need to save it if ( strcmp( atts[ 0 ], "out" ) == 0 ) mlt_properties_set( properties, "_westley.out", ( char* )atts[ 1 ] ); } @@ -166,15 +173,23 @@ static void on_start_blank( deserialise_context context, const xmlChar *name, co static void on_start_entry_track( deserialise_context context, const xmlChar *name, const xmlChar **atts) { - // Look for the producer attribute + // Use a dummy service to hold properties to allow arbitratry nesting + mlt_service service = calloc( 1, sizeof( struct mlt_service_s ) ); + mlt_service_init( service, NULL ); + + // Push the dummy service onto the stack + context_push_service( context, service ); + for ( ; atts != NULL && *atts != NULL; atts += 2 ) { - if ( strcmp( atts[0], "producer" ) == 0 ) + mlt_properties_set( mlt_service_properties( service ), (char*) atts[0], (char*) atts[1] ); + + // Look for the producer attribute + if ( strcmp( atts[ 0 ], "producer" ) == 0 ) { if ( mlt_properties_get_data( context->producer_map, (char*) atts[1], NULL ) != NULL ) // Push the referenced producer onto the stack context_push_service( context, MLT_SERVICE( mlt_properties_get_data( context->producer_map, (char*) atts[1], NULL ) ) ); - break; } } } @@ -270,6 +285,9 @@ static void on_end_track( deserialise_context context, const xmlChar *name ) // Get the producer from the stack mlt_service producer = context_pop_service( context ); + // Get the dummy track service from the stack + mlt_service track = context_pop_service( context ); + // Get the multitrack from the stack mlt_service service = context_pop_service( context ); @@ -278,8 +296,19 @@ static void on_end_track( deserialise_context context, const xmlChar *name ) MLT_PRODUCER( producer ), mlt_multitrack_count( MLT_MULTITRACK( service ) ) ); + // Set producer i/o if specified + if ( mlt_properties_get( mlt_service_properties( track ), "in" ) != NULL || + mlt_properties_get( mlt_service_properties( track ), "out" ) != NULL ) + { + mlt_producer_set_in_and_out( MLT_PRODUCER( producer ), + mlt_properties_get_position( mlt_service_properties( track ), "in" ), + mlt_properties_get_position( mlt_service_properties( track ), "out" ) ); + } + // Push the multitrack back onto the stack context_push_service( context, service ); + + mlt_service_close( track ); } static void on_end_entry( deserialise_context context, const xmlChar *name ) @@ -287,17 +316,30 @@ static void on_end_entry( deserialise_context context, const xmlChar *name ) // Get the producer from the stack mlt_service producer = context_pop_service( context ); + // Get the dummy entry service from the stack + mlt_service entry = context_pop_service( context ); + // Get the playlist from the stack mlt_service service = context_pop_service( context ); // Append the producer to the playlist - mlt_playlist_append_io( MLT_PLAYLIST( service ), - MLT_PRODUCER( producer ), - mlt_properties_get_position( mlt_service_properties( producer ), "in" ), - mlt_properties_get_position( mlt_service_properties( producer ), "out" ) ); + if ( mlt_properties_get( mlt_service_properties( entry ), "in" ) != NULL || + mlt_properties_get( mlt_service_properties( entry ), "out" ) != NULL ) + { + mlt_playlist_append_io( MLT_PLAYLIST( service ), + MLT_PRODUCER( producer ), + mlt_properties_get_position( mlt_service_properties( entry ), "in" ), + mlt_properties_get_position( mlt_service_properties( entry ), "out" ) ); + } + else + { + mlt_playlist_append( MLT_PLAYLIST( service ), MLT_PRODUCER( producer ) ); + } // Push the playlist back onto the stack context_push_service( context, service ); + + mlt_service_close( entry ); } static void on_end_tractor( deserialise_context context, const xmlChar *name ) @@ -334,13 +376,27 @@ static void on_end_producer( deserialise_context context, const xmlChar *name ) if ( properties == NULL ) return; - // Instatiate the producer - service = MLT_SERVICE( mlt_factory_producer( "fezzik", mlt_properties_get( properties, "resource" ) ) ); - - if ( service == NULL && mlt_properties_get( properties, "mlt_service" ) != NULL ) + // Instantiate the producer + if ( mlt_properties_get( properties, "mlt_service" ) != NULL ) { - service = MLT_SERVICE( mlt_factory_producer( mlt_properties_get( properties, "mlt_service" ), - mlt_properties_get( properties, "resource" ) ) ); + service = MLT_SERVICE( mlt_factory_producer( "fezzik", mlt_properties_get( properties, "mlt_service" ) ) ); + } + if ( service == NULL && mlt_properties_get( properties, "resource" ) != NULL ) + { + char *root = mlt_properties_get( context->producer_map, "_root" ); + char *resource = mlt_properties_get( properties, "resource" ); + char *full_resource = malloc( strlen( root ) + strlen( resource ) + 1 ); + if ( resource[ 0 ] != '/' ) + { + strcpy( full_resource, root ); + strcat( full_resource, resource ); + } + else + { + strcpy( full_resource, resource ); + } + service = MLT_SERVICE( mlt_factory_producer( "fezzik", full_resource ) ); + free( full_resource ); } track_service( context->destructors, service, (mlt_destructor) mlt_producer_close ); @@ -399,7 +455,7 @@ static void on_end_filter( deserialise_context context, const xmlChar *name ) properties = mlt_service_properties( service ); // Set in and out -//fprintf( stderr, "setting filter in %lld out %lld\n", mlt_properties_get_position( properties, "in" ), mlt_properties_get_position( properties, "out" ) ); +//fprintf( stderr, "setting filter in %d out %d\n", mlt_properties_get_position( properties, "in" ), mlt_properties_get_position( properties, "out" ) ); mlt_filter_set_in_and_out( MLT_FILTER( service ), mlt_properties_get_position( properties, "in" ), mlt_properties_get_position( properties, "out" ) ); @@ -418,7 +474,7 @@ static void on_end_filter( deserialise_context context, const xmlChar *name ) context_push_service( context, tractor ); } -//fprintf( stderr, "setting filter in %lld out %lld\n", mlt_properties_get_position( properties, "in" ), mlt_properties_get_position( properties, "out" ) ); +//fprintf( stderr, "setting filter in %d out %d\n", mlt_properties_get_position( properties, "in" ), mlt_properties_get_position( properties, "out" ) ); // If a producer alias is in the producer_map, get it snprintf( key, 10, "%p", producer ); if ( mlt_properties_get_data( context->producer_map, key, NULL ) != NULL ) @@ -545,7 +601,6 @@ static void on_characters( void *ctx, const xmlChar *ch, int len ) mlt_producer producer_westley_init( char *filename ) { - static int init = 0; xmlSAXHandler *sax = calloc( 1, sizeof( xmlSAXHandler ) ); struct deserialise_context_s *context = calloc( 1, sizeof( struct deserialise_context_s ) ); mlt_properties properties = NULL; @@ -553,17 +608,27 @@ mlt_producer producer_westley_init( char *filename ) context->producer_map = mlt_properties_new(); context->destructors = mlt_properties_new(); + // We need to track the number of registered filters mlt_properties_set_int( context->destructors, "registered", 0 ); + + // We need the directory prefix which was used for the westley + mlt_properties_set( context->producer_map, "_root", "" ); + if ( strchr( filename, '/' ) ) + { + char *root = NULL; + mlt_properties_set( context->producer_map, "_root", filename ); + root = mlt_properties_get( context->producer_map, "_root" ); + *( strrchr( root, '/' ) + 1 ) = '\0'; + } + sax->startElement = on_start_element; sax->endElement = on_end_element; sax->characters = on_characters; + sax->cdataBlock = on_characters; - if ( !init ) - { - xmlInitParser(); - //init = 1; - } + // I REALLY DON'T GET THIS - HOW THE HELL CAN YOU REFERENCE A WESTLEY IN A WESTLEY??? + xmlInitParser(); xmlSAXUserParseFile( sax, context, filename ); @@ -610,10 +675,9 @@ mlt_producer producer_westley_init( char *filename ) mlt_properties_close( context->producer_map ); //free( context ); free( sax ); - xmlCleanupParser(); + //xmlCleanupParser(); xmlMemoryDump( ); return MLT_PRODUCER( service ); } -