const xmlChar *publicId;
const xmlChar *systemId;
mlt_properties params;
+ mlt_deque filter_queue;
+ int in_producer;
};
typedef struct deserialise_context_s *deserialise_context;
}
+// Prepend the property value with the document root
+static inline void qualify_property( deserialise_context context, mlt_properties properties, char *name )
+{
+ char *resource = mlt_properties_get( properties, name );
+ if ( resource != NULL )
+ {
+ // Qualify file name properties
+ char *root = mlt_properties_get( context->producer_map, "_root" );
+ if ( root != NULL )
+ {
+ 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 );
+ }
+ mlt_properties_set( properties, name, full_resource );
+ free( full_resource );
+ }
+ }
+}
+
+
// Forward declarations
static void on_end_track( deserialise_context context, const xmlChar *name );
static void on_end_entry( deserialise_context context, const xmlChar *name );
{
mlt_properties properties = context->producer_properties = mlt_properties_new();
+ context->in_producer ++;
+
for ( ; atts != NULL && *atts != NULL; atts += 2 )
{
mlt_properties_set( properties, (char*) atts[0], (char*) atts[1] );
static void on_start_filter( deserialise_context context, const xmlChar *name, const xmlChar **atts)
{
- mlt_properties properties = context->producer_properties = mlt_properties_new();
+ mlt_properties properties = mlt_properties_new();
+
+ if ( context->in_producer != 0 )
+ mlt_deque_push_front( context->filter_queue, context->producer_properties );
+
+ context->producer_properties = properties;
// Set the properties
for ( ; atts != NULL && *atts != NULL; atts += 2 )
mlt_properties properties = context->producer_properties;
mlt_service service = NULL;
+ context->in_producer --;
+
if ( properties == NULL )
return;
+ qualify_property( context, properties, "resource" );
char *resource = mlt_properties_get( properties, "resource" );
// Let Kino-SMIL src be a synonym for resource
if ( resource == NULL )
+ {
+ qualify_property( context, properties, "src" );
resource = mlt_properties_get( properties, "src" );
-
+ }
+
// Instantiate the producer
if ( mlt_properties_get( properties, "mlt_service" ) != NULL )
{
}
if ( service == NULL && resource != NULL )
{
- char *root = mlt_properties_get( context->producer_map, "_root" );
- 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 );
+ service = MLT_SERVICE( mlt_factory_producer( "fezzik", resource ) );
}
+
if ( service == NULL )
return;
track_service( context->destructors, service, (mlt_destructor) mlt_producer_close );
}
}
+ // Allow for embedded filters
+ while( mlt_deque_count( context->filter_queue ) )
+ {
+ mlt_properties filter_properties = mlt_deque_pop_front( context->filter_queue );
+ mlt_properties_debug( filter_properties, "Filter?", stderr );
+ mlt_filter filter = mlt_factory_filter( mlt_properties_get( filter_properties, "mlt_service" ), NULL );
+ if ( filter != NULL )
+ {
+ track_service( context->destructors, filter, (mlt_destructor) mlt_filter_close );
+ qualify_property( context, filter_properties, "resource" );
+ qualify_property( context, filter_properties, "luma" );
+ qualify_property( context, filter_properties, "luma.resource" );
+ qualify_property( context, filter_properties, "composite.luma" );
+ qualify_property( context, filter_properties, "producer.resource" );
+ mlt_properties_inherit( mlt_filter_properties( filter ), filter_properties );
+ mlt_properties_close( filter_properties );
+ mlt_producer_attach( MLT_PRODUCER( service ), filter );
+ }
+ }
+
// Push the producer onto the stack
context_push_service( context, service );
}
static void on_end_filter( deserialise_context context, const xmlChar *name )
{
mlt_properties properties = context->producer_properties;
+ if ( context->in_producer )
+ {
+ mlt_deque_push_back( context->filter_queue, properties );
+ context->producer_properties = mlt_deque_pop_front( context->filter_queue );
+ return;
+ }
+
if ( properties == NULL )
return;
mlt_properties_set_position( properties, "out", mlt_producer_get_out( MLT_PRODUCER( producer ) ) );
// Propogate the properties
+ qualify_property( context, properties, "resource" );
+ qualify_property( context, properties, "luma" );
+ qualify_property( context, properties, "luma.resource" );
+ qualify_property( context, properties, "composite.luma" );
+ qualify_property( context, properties, "producer.resource" );
mlt_properties_inherit( mlt_service_properties( service ), properties );
mlt_properties_close( properties );
context->producer_properties = NULL;
track_service( context->destructors, service, (mlt_destructor) mlt_transition_close );
// Propogate the properties
+ qualify_property( context, properties, "resource" );
+ qualify_property( context, properties, "luma" );
+ qualify_property( context, properties, "luma.resource" );
+ qualify_property( context, properties, "composite.luma" );
+ qualify_property( context, properties, "producer.resource" );
mlt_properties_inherit( mlt_service_properties( service ), properties );
mlt_properties_close( properties );
context->producer_properties = NULL;
context->producer_map = mlt_properties_new();
context->destructors = mlt_properties_new();
context->params = mlt_properties_new();
+ context->filter_queue = mlt_deque_init();
// Decode URL and parse parameters
parse_url( context->params, url_decode( filename, url ) );
mlt_properties_close( context->producer_map );
if ( context->params != NULL )
mlt_properties_close( context->params );
+ mlt_deque_close( context->filter_queue );
free( context );
free( filename );