]> git.sesse.net Git - mlt/commitdiff
Extendable factories; general producer related modifications; westley storage; sdl_st...
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Thu, 25 Nov 2004 13:41:20 +0000 (13:41 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Thu, 25 Nov 2004 13:41:20 +0000 (13:41 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@536 d19143bc-622f-0410-bfdd-b5b2a6649095

src/framework/mlt_factory.c
src/framework/mlt_factory.h
src/framework/mlt_multitrack.c
src/framework/mlt_playlist.c
src/framework/mlt_producer.c
src/framework/mlt_properties.c
src/framework/mlt_service.c
src/framework/mlt_tractor.c
src/modules/sdl/consumer_sdl_still.c
src/modules/westley/consumer_westley.c
src/modules/westley/producer_westley.c

index dbaf2dbd58f7bdbb01e6c28e46c890cf9de85940..8766fd6dfb0b21e41aecf6079b1d090a378fd15b 100644 (file)
@@ -36,8 +36,24 @@ static mlt_repository producers = NULL;
 static mlt_repository filters = NULL;
 static mlt_repository transitions = NULL;
 static mlt_repository consumers = NULL;
+static mlt_properties event_object = NULL;
 static int unique_id = 0;
 
+/** Event transmitters.
+*/
+
+static void mlt_factory_create_request( mlt_listener listener, mlt_properties owner, mlt_service this, void **args )
+{
+       if ( listener != NULL )
+               listener( owner, this, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service * )args[ 2 ] );
+}
+
+static void mlt_factory_create_done( mlt_listener listener, mlt_properties owner, mlt_service this, void **args )
+{
+       if ( listener != NULL )
+               listener( owner, this, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service )args[ 2 ] );
+}
+
 /** Construct the factories.
 */
 
@@ -60,6 +76,18 @@ int mlt_factory_init( char *prefix )
                // Initialise the pool
                mlt_pool_init( );
 
+               // Create and set up the events object
+               event_object = mlt_properties_new( );
+               mlt_events_init( event_object );
+               mlt_events_register( event_object, "producer-create-request", ( mlt_transmitter )mlt_factory_create_request );
+               mlt_events_register( event_object, "producer-create-done", ( mlt_transmitter )mlt_factory_create_done );
+               mlt_events_register( event_object, "filter-create-request", ( mlt_transmitter )mlt_factory_create_request );
+               mlt_events_register( event_object, "filter-create-done", ( mlt_transmitter )mlt_factory_create_done );
+               mlt_events_register( event_object, "transition-create-request", ( mlt_transmitter )mlt_factory_create_request );
+               mlt_events_register( event_object, "transition-create-done", ( mlt_transmitter )mlt_factory_create_done );
+               mlt_events_register( event_object, "consumer-create-request", ( mlt_transmitter )mlt_factory_create_request );
+               mlt_events_register( event_object, "consumer-create-done", ( mlt_transmitter )mlt_factory_create_done );
+
                // Create the global properties
                global_properties = mlt_properties_new( );
                mlt_properties_set_or_default( global_properties, "MLT_NORMALISATION", getenv( "MLT_NORMALISATION" ), "PAL" );
@@ -83,6 +111,14 @@ int mlt_factory_init( char *prefix )
        return 0;
 }
 
+/** Fetch the events object.
+*/
+
+mlt_properties mlt_factory_event_object( )
+{
+       return event_object;
+}
+
 /** Fetch the prefix used in this instance.
 */
 
@@ -110,16 +146,22 @@ mlt_producer mlt_factory_producer( char *service, void *input )
        if ( service == NULL )
                service = mlt_environment( "MLT_PRODUCER" );
 
-       // Try to instantiate via the specified service
-       obj = mlt_repository_fetch( producers, service, input );
+       // Offer the application the chance to 'create'
+       mlt_events_fire( event_object, "producer-create-request", service, input, &obj, NULL );
 
-       if ( obj != NULL )
+       // Try to instantiate via the specified service
+       if ( obj == NULL )
        {
-               mlt_properties properties = mlt_producer_properties( obj );
-               mlt_properties_set_int( properties, "_unique_id", ++ unique_id );
-               mlt_properties_set( properties, "mlt_type", "producer" );
-               if ( mlt_properties_get_int( properties, "_mlt_service_hidden" ) == 0 )
-                       mlt_properties_set( properties, "mlt_service", service );
+               obj = mlt_repository_fetch( producers, service, input );
+               mlt_events_fire( event_object, "producer-create-done", service, input, obj, NULL );
+               if ( obj != NULL )
+               {
+                       mlt_properties properties = mlt_producer_properties( obj );
+                       mlt_properties_set_int( properties, "_unique_id", ++ unique_id );
+                       mlt_properties_set( properties, "mlt_type", "producer" );
+                       if ( mlt_properties_get_int( properties, "_mlt_service_hidden" ) == 0 )
+                               mlt_properties_set( properties, "mlt_service", service );
+               }
        }
        return obj;
 }
@@ -129,7 +171,17 @@ mlt_producer mlt_factory_producer( char *service, void *input )
 
 mlt_filter mlt_factory_filter( char *service, void *input )
 {
-       mlt_filter obj = mlt_repository_fetch( filters, service, input );
+       mlt_filter obj = NULL;
+
+       // Offer the application the chance to 'create'
+       mlt_events_fire( event_object, "filter-create-request", service, input, &obj, NULL );
+
+       if ( obj == NULL )
+       {
+               obj = mlt_repository_fetch( filters, service, input );
+               mlt_events_fire( event_object, "filter-create-done", service, input, obj, NULL );
+       }
+
        if ( obj != NULL )
        {
                mlt_properties properties = mlt_filter_properties( obj );
@@ -145,7 +197,17 @@ mlt_filter mlt_factory_filter( char *service, void *input )
 
 mlt_transition mlt_factory_transition( char *service, void *input )
 {
-       mlt_transition obj = mlt_repository_fetch( transitions, service, input );
+       mlt_transition obj = NULL;
+
+       // Offer the application the chance to 'create'
+       mlt_events_fire( event_object, "transition-create-request", service, input, &obj, NULL );
+
+       if ( obj == NULL )
+       {
+               obj = mlt_repository_fetch( transitions, service, input );
+               mlt_events_fire( event_object, "transition-create-done", service, input, obj, NULL );
+       }
+
        if ( obj != NULL )
        {
                mlt_properties properties = mlt_transition_properties( obj );
@@ -166,7 +228,14 @@ mlt_consumer mlt_factory_consumer( char *service, void *input )
        if ( service == NULL )
                service = mlt_environment( "MLT_CONSUMER" );
 
-       obj = mlt_repository_fetch( consumers, service, input );
+       // Offer the application the chance to 'create'
+       mlt_events_fire( event_object, "consumer-create-request", service, input, &obj, NULL );
+
+       if ( obj == NULL )
+       {
+               obj = mlt_repository_fetch( consumers, service, input );
+               mlt_events_fire( event_object, "consumer-create-done", service, input, obj, NULL );
+       }
 
        if ( obj != NULL )
        {
@@ -198,6 +267,7 @@ void mlt_factory_close( )
 {
        if ( mlt_prefix != NULL )
        {
+               mlt_properties_close( event_object );
                mlt_repository_close( producers );
                mlt_repository_close( filters );
                mlt_repository_close( transitions );
index e2842ce277a02397f71724932de1283592e6f400..219e5f50902835a4dce2e02505e0981efedae6a1 100644 (file)
@@ -26,6 +26,7 @@
 extern int mlt_factory_init( char *prefix );
 extern const char *mlt_factory_prefix( );
 extern char *mlt_environment( char *name );
+extern mlt_properties mlt_factory_event_object( );
 extern mlt_producer mlt_factory_producer( char *name, void *input );
 extern mlt_filter mlt_factory_filter( char *name, void *input );
 extern mlt_transition mlt_factory_transition( char *name, void *input );
index d274dbcd5609ea6456cd38e54347c0ec80b8b137..7e16e04d95591fc8405380a63773d06ea1e5d1be 100644 (file)
@@ -70,6 +70,10 @@ mlt_multitrack mlt_multitrack_init( )
                        mlt_properties_set_data( properties, "multitrack", this, 0, NULL, NULL );
                        mlt_properties_set( properties, "log_id", "multitrack" );
                        mlt_properties_set( properties, "resource", "<multitrack>" );
+                       mlt_properties_set_int( properties, "in", 0 );
+                       mlt_properties_set_int( properties, "out", -1 );
+                       mlt_properties_set_int( properties, "length", 0 );
+                       producer->close = ( mlt_destructor )mlt_multitrack_close;
                }
                else
                {
@@ -459,6 +463,7 @@ void mlt_multitrack_close( mlt_multitrack this )
                }
 
                // Close the producer
+               this->parent.close = NULL;
                mlt_producer_close( &this->parent );
 
                // Free the list
index 2cf7e86ea114954e76b18995649f0bd74151d6f9..e59b05caf6f25e6e359b1a9513a0cd84ad467c29 100644 (file)
@@ -1359,9 +1359,6 @@ int mlt_playlist_move_region( mlt_playlist this, int position, int length, int n
 {
        if ( this != NULL )
        {
-               mlt_playlist temp = mlt_playlist_init( );
-               int original_size = mlt_producer_get_playtime( mlt_playlist_producer( temp ) );
-               mlt_playlist_close( temp );
        }
        return 0;
 }
index 50d12220801b3c1204f9fbf6d01de1977ebdbe82..58594b8ca321e51a38669ae593cbcfacb50b67ca 100644 (file)
@@ -196,14 +196,12 @@ mlt_producer mlt_producer_cut( mlt_producer this, int in, int out )
        if ( in <= 0 )
                in = 0;
        if ( ( out < 0 || out >= mlt_producer_get_playtime( parent ) ) && !mlt_producer_is_blank( this ) )
-               out = mlt_producer_get_playtime( parent );
+               out = mlt_producer_get_playtime( parent ) - 1;
 
        mlt_properties_inc_ref( parent_props );
        mlt_properties_set_int( properties, "_cut", 1 );
        mlt_properties_set_data( properties, "_cut_parent", parent, 0, ( mlt_destructor )mlt_producer_close, NULL );
        mlt_properties_set_position( properties, "length", mlt_properties_get_position( parent_props, "length" ) );
-       mlt_properties_set_position( properties, "in", 0 );
-       mlt_properties_set_position( properties, "out", 0 );
        mlt_producer_set_in_and_out( result, in, out );
 
        return result;
@@ -313,14 +311,14 @@ int mlt_producer_set_in_and_out( mlt_producer this, mlt_position in, mlt_positio
        // Correct ins and outs if necessary
        if ( in < 0 )
                in = 0;
-       else if ( in > mlt_producer_get_length( this ) )
-               in = mlt_producer_get_length( this );
+       else if ( in >= mlt_producer_get_length( this ) )
+               in = mlt_producer_get_length( this ) - 1;
 
        if ( out < 0 )
                out = 0;
-       else if ( out > mlt_producer_get_length( this ) && !mlt_producer_is_blank( this ) )
-               out = mlt_producer_get_length( this );
-       else if ( out >= mlt_producer_get_length( this ) - 1 && mlt_producer_is_blank( this ) )
+       else if ( out >= mlt_producer_get_length( this ) && !mlt_producer_is_blank( this ) )
+               out = mlt_producer_get_length( this ) - 1;
+       else if ( out >= mlt_producer_get_length( this ) && mlt_producer_is_blank( this ) )
                mlt_properties_set_position( mlt_producer_properties( this ), "length", out + 1 );
 
        // Swap ins and outs if wrong
@@ -544,6 +542,8 @@ static mlt_producer mlt_producer_clone( mlt_producer this )
        char *resource = mlt_properties_get( properties, "resource" );
        char *service = mlt_properties_get( properties, "mlt_service" );
 
+       mlt_events_block( mlt_factory_event_object( ), mlt_factory_event_object( ) );
+
        if ( service != NULL )
                clone = mlt_factory_producer( service, resource );
 
@@ -553,6 +553,8 @@ static mlt_producer mlt_producer_clone( mlt_producer this )
        if ( clone != NULL )
                mlt_properties_inherit( mlt_producer_properties( clone ), properties );
 
+       mlt_events_unblock( mlt_factory_event_object( ), mlt_factory_event_object( ) );
+
        return clone;
 }
 
index e84ee0725bf8adcb261237b23b16772a01eaff40..0bad06be18bba415f69acee8b31da234365e56f1 100644 (file)
@@ -666,7 +666,7 @@ void mlt_properties_dump( mlt_properties this, FILE *output )
 
 void mlt_properties_debug( mlt_properties this, char *title, FILE *output )
 {
-       fprintf( stderr, "%s: ", title );
+       fprintf( output, "%s: ", title );
        if ( this != NULL )
        {
                property_list *list = this->local;
@@ -679,7 +679,7 @@ void mlt_properties_debug( mlt_properties this, char *title, FILE *output )
                                fprintf( output, ", %s=%p", list->name[ i ], mlt_properties_get_data( this, list->name[ i ], NULL ) );
                fprintf( output, " ]" );
        }
-       fprintf( stderr, "\n" );
+       fprintf( output, "\n" );
 }
 
 /** Close the list.
index afc671d8c1a423c8f4be1855494fd4d667f04537..93ee56b8167ea4278a619a4445e9e5b1cf9edde3 100644 (file)
@@ -380,7 +380,6 @@ int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index )
                }
                else
                {
-                       fprintf( stderr, "Ugh case\n" );
                        mlt_service_close( this );
                }
                return result;
index 6ad86fcd7145ad6729237978cf0c7de4f1ecf518..92533debdcefcc616e8f8b9993b518bf1eca3d60 100644 (file)
@@ -55,9 +55,14 @@ mlt_tractor mlt_tractor_init( )
                mlt_producer producer = &this->parent;
                if ( mlt_producer_init( producer, this ) == 0 )
                {
-                       mlt_properties_set( mlt_producer_properties( producer ), "resource", "<tractor>" );
-                       mlt_properties_set( mlt_producer_properties( producer ), "mlt_type", "mlt_producer" );
-                       mlt_properties_set( mlt_producer_properties( producer ), "mlt_service", "tractor" );
+                       mlt_properties properties = mlt_producer_properties( producer );
+
+                       mlt_properties_set( properties, "resource", "<tractor>" );
+                       mlt_properties_set( properties, "mlt_type", "mlt_producer" );
+                       mlt_properties_set( properties, "mlt_service", "tractor" );
+                       mlt_properties_set_int( properties, "in", 0 );
+                       mlt_properties_set_int( properties, "out", -1 );
+                       mlt_properties_set_int( properties, "length", 0 );
 
                        producer->get_frame = producer_get_frame;
                        producer->close = ( mlt_destructor )mlt_tractor_close;
index 13f73ee52a0c29084ea11ba551a04f865f098b6e..3ac12c0f65011f4e825fe2ecc2f3ce660827ce8a 100644 (file)
@@ -533,7 +533,7 @@ static void *consumer_thread( void *arg )
 
        // internal intialization
        mlt_frame frame = NULL;
-       struct timespec tm = { 0, 1000000 };
+       struct timespec tm = { 0, 10000000 };
 
        if ( mlt_properties_get_int( mlt_consumer_properties( consumer ), "sdl_started" ) == 0 )
        {
index 63e320e5b7342bf3f282bae8c3003042d2fef6d6..a5aaaf86b848f131ab4abe120246af6100d6398b 100644 (file)
@@ -42,6 +42,7 @@ struct serialise_context_s
        int pass;
        mlt_properties hide_map;
        char *root;
+       char *store;
 };
 typedef struct serialise_context_s* serialise_context;
 
@@ -198,6 +199,31 @@ static inline void serialise_properties( serialise_context context, mlt_properti
        }
 }
 
+static inline void serialise_store_properties( serialise_context context, mlt_properties properties, xmlNode *node )
+{
+       int i;
+       xmlNode *p;
+       
+       // Enumerate the properties
+       for ( i = 0; context->store != NULL && i < mlt_properties_count( properties ); i++ )
+       {
+               char *name = mlt_properties_get_name( properties, i );
+               if ( !strncmp( name, context->store, strlen( context->store ) ) )
+               {
+                       char *value = mlt_properties_get_value( properties, i );
+                       if ( value != NULL )
+                       {
+                               p = xmlNewChild( node, NULL, "property", NULL );
+                               xmlNewProp( p, "name", mlt_properties_get_name( properties, i ) );
+                               if ( context->root != NULL && strcmp( context->root, "" ) && !strncmp( value, context->root, strlen( context->root ) ) )
+                                       xmlNodeSetContent( p, value + strlen( context->root ) + 1 );
+                               else
+                                       xmlNodeSetContent( p, value );
+                       }
+               }
+       }
+}
+
 static inline void serialise_service_filters( serialise_context context, mlt_service service, xmlNode *node )
 {
        int i;
@@ -353,6 +379,9 @@ static void serialise_playlist( serialise_context context, mlt_service service,
                // Set the id
                xmlNewProp( child, "id", id );
 
+               // Store application specific properties
+               serialise_store_properties( context, properties, child );
+
                // Add producer to the map
                mlt_properties_set_int( context->hide_map, id, mlt_properties_get_int( properties, "hide" ) );
        
@@ -425,6 +454,9 @@ static void serialise_tractor( serialise_context context, mlt_service service, x
                xmlNewProp( child, "in", mlt_properties_get( properties, "in" ) );
                xmlNewProp( child, "out", mlt_properties_get( properties, "out" ) );
 
+               // Store application specific properties
+               serialise_store_properties( context, mlt_service_properties( service ), child );
+
                // Recurse on connected producer
                serialise_service( context, mlt_service_producer( service ), child );
                serialise_service_filters( context, service, child );
@@ -569,7 +601,7 @@ static void serialise_service( serialise_context context, mlt_service service, x
        }
 }
 
-xmlDocPtr westley_make_doc( mlt_service service )
+xmlDocPtr westley_make_doc( mlt_consumer consumer, mlt_service service )
 {
        mlt_properties properties = mlt_service_properties( service );
        xmlDocPtr doc = xmlNewDoc( "1.0" );
@@ -589,6 +621,9 @@ xmlDocPtr westley_make_doc( mlt_service service )
                context->root = strdup( "" );
        }
 
+       // Assign the additional 'storage' pattern for properties
+       context->store = mlt_properties_get( mlt_consumer_properties( consumer ), "store" );
+
        // Assign a title property
        if ( mlt_properties_get( properties, "title" ) != NULL )
                xmlNewProp( root, "title", mlt_properties_get( properties, "title" ) );
@@ -649,7 +684,7 @@ static int consumer_start( mlt_consumer this )
                }
 
                // Make the document
-               doc = westley_make_doc( service );
+               doc = westley_make_doc( this, service );
 
                // Handle the output
                if ( resource == NULL || !strcmp( resource, "" ) )
index 40e94c14ce8c07f3341309de0f49359d923aa4ce..2f3a458149342c60c99ee08d9e472454feaaa53b 100644 (file)
@@ -292,17 +292,9 @@ static void on_start_tractor( deserialise_context context, const xmlChar *name,
 
        track_service( context->destructors, service, (mlt_destructor) mlt_tractor_close );
 
-       mlt_properties_set_position( properties, "length", 0 );
-
        for ( ; atts != NULL && *atts != NULL; atts += 2 )
                mlt_properties_set( mlt_service_properties( service ), (char*) atts[0], (char*) atts[1] );
 
-       if ( mlt_properties_get_position( properties, "length" ) < mlt_properties_get_position( properties, "out" ) )
-       {
-               mlt_position length = mlt_properties_get_position( properties, "out" ) + 1;
-               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 );
        
@@ -348,7 +340,6 @@ static void on_start_multitrack( deserialise_context context, const xmlChar *nam
        {
                mlt_service service = MLT_SERVICE( mlt_tractor_multitrack( MLT_TRACTOR( parent ) ) );
                mlt_properties properties = mlt_service_properties( service );
-               mlt_properties_set_position( properties, "length", 0 );
                for ( ; atts != NULL && *atts != NULL; atts += 2 )
                        mlt_properties_set( properties, (char*) atts[0], (char*) atts[1] );
 
@@ -381,8 +372,6 @@ static void on_start_playlist( deserialise_context context, const xmlChar *name,
 
        track_service( context->destructors, service, (mlt_destructor) mlt_playlist_close );
 
-       mlt_properties_set_position( properties, "length", 0 );
-
        for ( ; atts != NULL && *atts != NULL; atts += 2 )
        {
                mlt_properties_set( properties, ( char* )atts[0], ( char* )atts[1] );
@@ -408,18 +397,8 @@ static void on_end_playlist( deserialise_context context, const xmlChar *name )
        {
                mlt_properties properties = mlt_service_properties( service );
                mlt_position in = mlt_properties_get_position( properties, "in" );
-               mlt_position out;
+               mlt_position out = mlt_properties_get_position( properties, "out" );
 
-               if ( mlt_properties_get( properties, "_westley.out" ) != NULL )
-                       out = mlt_properties_get_position( properties, "_westley.out" );
-               else
-                       out = mlt_properties_get_position( properties, "length" ) - 1;
-
-               if ( mlt_properties_get_position( properties, "length" ) < out )
-                       mlt_properties_set_position( properties, "length", out  + 1 );
-
-               mlt_producer_set_in_and_out( MLT_PRODUCER( service ), in, out );
-       
                // See if the playlist should be added to a playlist or multitrack
                if ( add_producer( context, service, in, out ) == 0 )
                        context_push_service( context, service, type );
@@ -730,8 +709,6 @@ static void on_end_track( deserialise_context context, const xmlChar *name )
                        if ( mlt_properties_get( track_props, "in" ) != NULL ||
                                 mlt_properties_get( track_props, "out" ) != NULL )
                        {
-                               if ( mlt_properties_get( track_props, "out" ) == NULL )
-                                       mlt_properties_set_position( track_props, "out", mlt_properties_get_position( track_props, "length" ) - 1 );
                                mlt_producer cut = mlt_producer_cut( MLT_PRODUCER( producer ),
                                        mlt_properties_get_position( track_props, "in" ),
                                        mlt_properties_get_position( track_props, "out" ) );
@@ -1324,6 +1301,18 @@ mlt_producer producer_westley_init( int info, char *data )
        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 );
+               free( context );
+               free( sax );
+               free( filename );
+               return NULL;
+       }
+
        xmlcontext->sax = sax;
        xmlcontext->_private = ( void* )context;
        
@@ -1380,9 +1369,6 @@ mlt_producer producer_westley_init( int info, char *data )
                // Set this var to service properties for convenience
                properties = mlt_service_properties( service );
        
-               // make the returned service destroy the connected services
-               mlt_properties_set_data( properties, "__destructors__", context->destructors, 0, (mlt_destructor) mlt_properties_close, NULL );
-
                // Assign the title
                mlt_properties_set( properties, "title", title );
 
@@ -1410,15 +1396,13 @@ mlt_producer producer_westley_init( int info, char *data )
        {
                // Return null if not well formed
                service = NULL;
-               
-               // Clean up
-               mlt_properties_close( context->destructors );
        }
 
        // Clean up
        mlt_properties_close( context->producer_map );
        if ( context->params != NULL )
                mlt_properties_close( context->params );
+       mlt_properties_close( context->destructors );
        free( context );
        free( filename );