+}
+
+static void on_end_producer( deserialise_context context, const xmlChar *name )
+{
+ enum service_type type;
+ mlt_service service = context_pop_service( context, &type );
+ mlt_properties properties = mlt_service_properties( service );
+
+ if ( service != NULL && type == mlt_dummy_producer_type )
+ {
+ mlt_service producer = NULL;
+
+ 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 )
+ {
+ char temp[ 1024 ];
+ strncpy( temp, mlt_properties_get( properties, "mlt_service" ), 1024 );
+ if ( resource != NULL )
+ {
+ strcat( temp, ":" );
+ strncat( temp, resource, 1023 - strlen( temp ) );
+ }
+ producer = MLT_SERVICE( mlt_factory_producer( "fezzik", temp ) );
+ }
+
+ // Just in case the plugin requested doesn't exist...
+ if ( producer == NULL && resource != NULL )
+ producer = MLT_SERVICE( mlt_factory_producer( "fezzik", resource ) );
+
+ // Track this producer
+ track_service( context->destructors, producer, (mlt_destructor) mlt_producer_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" );
+
+ // Handle in/out properties separately
+ mlt_position in = -1;
+ mlt_position out = -1;
+
+ // Get in
+ if ( mlt_properties_get( properties, "in" ) != NULL )
+ in = mlt_properties_get_position( properties, "in" );
+ // Let Kino-SMIL clipBegin be a synonym for in
+ if ( mlt_properties_get( properties, "clipBegin" ) != NULL )
+ in = mlt_properties_get_position( properties, "clipBegin" );
+ // Get out
+ if ( mlt_properties_get( properties, "out" ) != NULL )
+ out = mlt_properties_get_position( properties, "out" );
+ // Let Kino-SMIL clipEnd be a synonym for out
+ if ( mlt_properties_get( properties, "clipEnd" ) != NULL )
+ out = mlt_properties_get_position( properties, "clipEnd" );
+
+ // Remove in and out
+ mlt_properties_set( properties, "in", NULL );
+ mlt_properties_set( properties, "out", NULL );
+
+ // Inherit the properties
+ mlt_properties_inherit( mlt_service_properties( producer ), properties );
+
+ // Attach all filters from service onto producer
+ attach_filters( producer, service );
+
+ // Add the producer to the producer map
+ if ( mlt_properties_get( properties, "id" ) != NULL )
+ mlt_properties_set_data( context->producer_map, mlt_properties_get(properties, "id"), producer, 0, NULL, NULL );
+
+ // See if the producer should be added to a playlist or multitrack
+ if ( add_producer( context, producer, in, out ) == 0 )
+ {
+ // Otherwise, set in and out on...
+ if ( in != -1 || out != -1 )
+ {
+ // Get the parent service
+ enum service_type type;
+ mlt_service parent = context_pop_service( context, &type );
+ if ( parent != NULL )
+ {
+ // Get the parent properties
+ properties = mlt_service_properties( parent );
+
+ char *resource = mlt_properties_get( properties, "resource" );
+
+ // Put the parent producer back
+ context_push_service( context, parent, type );
+
+ // If the parent is a track or entry
+ if ( resource && ( strcmp( resource, "<entry>" ) == 0 ) )
+ {
+ mlt_properties_set_position( properties, "in", in );
+ mlt_properties_set_position( properties, "out", out );
+ }
+ else
+ {
+ // Otherwise, set in and out on producer directly
+ mlt_producer_set_in_and_out( MLT_PRODUCER( service ), in, out );
+ }
+ }
+ else
+ {
+ // Otherwise, set in and out on producer directly
+ mlt_producer_set_in_and_out( MLT_PRODUCER( producer ), in, out );
+ }
+ }
+
+ // Push the producer onto the stack
+ context_push_service( context, producer, mlt_producer_type );
+ }
+
+ mlt_service_close( service );