]> git.sesse.net Git - mlt/commitdiff
Consumer valerie, pushes, and assorted modifications
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Fri, 17 Sep 2004 12:15:22 +0000 (12:15 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Fri, 17 Sep 2004 12:15:22 +0000 (12:15 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@418 d19143bc-622f-0410-bfdd-b5b2a6649095

33 files changed:
src/framework/mlt_service.c
src/framework/mlt_service.h
src/miracle/miracle_connection.c
src/miracle/miracle_local.c
src/miracle/miracle_unit.c
src/miracle/miracle_unit.h
src/miracle/miracle_unit_commands.c
src/miracle/miracle_unit_commands.h
src/modules/avformat/Makefile
src/modules/core/filter_watermark.c
src/modules/core/producer_colour.c
src/modules/core/transition_region.c
src/modules/gtk2/factory.c
src/modules/inigo/producer_inigo.c
src/modules/plus/transition_affine.c
src/modules/sdl/consumer_sdl.c
src/modules/sox/Makefile
src/modules/valerie/Makefile [new file with mode: 0644]
src/modules/valerie/configure [new file with mode: 0755]
src/modules/valerie/consumer_valerie.c [new file with mode: 0644]
src/modules/valerie/consumer_valerie.h [new file with mode: 0644]
src/modules/valerie/factory.c [new file with mode: 0644]
src/modules/westley/configure
src/modules/westley/consumer_westley.c
src/modules/westley/factory.c
src/modules/westley/producer_westley.c
src/modules/westley/producer_westley.h
src/valerie/Makefile
src/valerie/valerie.c
src/valerie/valerie.h
src/valerie/valerie_parser.c
src/valerie/valerie_parser.h
src/valerie/valerie_remote.c

index bc0cf33bc6e0d9f2a56232a39906cff625858b91..9ea9b668d481e070a1f694426fcd4c0428e89f54 100644 (file)
@@ -263,21 +263,31 @@ mlt_properties mlt_service_properties( mlt_service self )
 /** Recursively apply attached filters
 */
 
-static void apply_filters( mlt_service this, mlt_frame frame, int index )
+void mlt_service_apply_filters( mlt_service this, mlt_frame frame, int index )
 {
-       mlt_properties properties = mlt_service_properties( this );
-       mlt_service_base *base = this->local;
        int i;
+       mlt_properties frame_properties = mlt_frame_properties( frame );
+       mlt_properties filter_properties = mlt_service_properties( this );
+       mlt_service_base *base = this->local;
+       mlt_position position = mlt_properties_get_position( frame_properties, "_position" );
 
-       if ( mlt_properties_get_int( properties, "_filter_private" ) == 0 )
+       if ( index == 0 || mlt_properties_get_int( filter_properties, "_filter_private" ) == 0 )
        {
                // Process the frame with the attached filters
                for ( i = 0; i < base->filter_count; i ++ )
                {
                        if ( base->filters[ i ] != NULL )
                        {
-                               mlt_filter_process( base->filters[ i ], frame );
-                               apply_filters( mlt_filter_service( base->filters[ i ] ), frame, index );
+                               mlt_properties properties = mlt_filter_properties( base->filters[ i ] );
+                               mlt_position in = mlt_properties_get_position( properties, "in" );
+                               mlt_position out = mlt_properties_get_position( properties, "out" );
+                               if ( ( in == 0 && out == 0 ) || ( position >= in && position <= out ) )
+                               {
+                                       mlt_properties_set_position( frame_properties, "_position", position - in );
+                                       mlt_filter_process( base->filters[ i ], frame );
+                                       mlt_service_apply_filters( mlt_filter_service( base->filters[ i ] ), frame, index + 1 );
+                                       mlt_properties_set_position( frame_properties, "_position", position + in );
+                               }
                        }
                }
        }
@@ -292,7 +302,7 @@ int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index )
        {
                int result = this->get_frame( this, frame, index );
                if ( result == 0 )
-                       apply_filters( this, *frame, index );
+                       mlt_service_apply_filters( this, *frame, 1 );
                return result;
        }
        *frame = mlt_frame_init( );
index 47cd929c2f63886511968268ba0973f159115dd7..00e500155581513d2a0cf9a5fec6e2417a133a50 100644 (file)
@@ -52,6 +52,7 @@ extern mlt_service mlt_service_consumer( mlt_service self );
 extern mlt_service mlt_service_producer( mlt_service self );
 extern int mlt_service_attach( mlt_service self, mlt_filter filter );
 extern int mlt_service_detach( mlt_service self, mlt_filter filter );
+extern void mlt_service_apply_filters( mlt_service self, mlt_frame frame, int index );
 extern mlt_filter mlt_service_filter( mlt_service self, int index );
 
 extern void mlt_service_close( mlt_service self );
index 82a5b5913233ece076f3a6c4897396b09e0c4ea8..6bf496cfcbdbd8165ef72a56aec5bd38f44a197e 100644 (file)
@@ -223,7 +223,35 @@ void *parser_thread( void *arg )
 
                while( !error && connection_read( fd, command, 1024 ) )
                {
-                       if ( strncmp( command, "STATUS", 6 ) )
+                       if ( !strncmp( command, "PUSH ", 5 ) )
+                       {
+                               char temp[ 20 ];
+                               int bytes;
+                               char *buffer = NULL;
+                               int total = 0;
+                               mlt_service service = NULL;
+
+                               connection_read( fd, temp, 20 );
+                               bytes = atoi( temp );
+                               buffer = malloc( bytes + 1 );
+                               while ( total < bytes )
+                               {
+                                       int count = read( fd, buffer + total, bytes - total );
+                                       if ( count >= 0 )
+                                               total += count;
+                                       else
+                                               break;
+                               }
+                               buffer[ bytes ] = '\0';
+                               if ( bytes > 0 && total == bytes )
+                                       service = ( mlt_service )mlt_factory_producer( "westley-xml", buffer );
+                               response = valerie_parser_push( parser, command, service );
+                               error = connection_send( fd, response );
+                               valerie_response_close( response );
+                               mlt_service_close( service );
+                               free( buffer );
+                       }
+                       else if ( strncmp( command, "STATUS", 6 ) )
                        {
                                response = valerie_parser_execute( parser, command );
                                miracle_log( LOG_INFO, "%s \"%s\" %d", address, command, valerie_response_get_error_code( response ) );
index 374d5fd479c052501b75c564cae9e9a5652ecaa3..9f3e706e09d45aa37d28b9da012a4364428bbf2d 100644 (file)
@@ -60,6 +60,7 @@ typedef struct
 
 static valerie_response miracle_local_connect( miracle_local );
 static valerie_response miracle_local_execute( miracle_local, char * );
+static valerie_response miracle_local_push( miracle_local, char *, mlt_service );
 static void miracle_local_close( miracle_local );
 response_codes miracle_help( command_argument arg );
 response_codes miracle_run( command_argument arg );
@@ -79,6 +80,7 @@ valerie_parser miracle_parser_init_local( )
 
                parser->connect = (parser_connect)miracle_local_connect;
                parser->execute = (parser_execute)miracle_local_execute;
+               parser->push = (parser_push)miracle_local_push;
                parser->close = (parser_close)miracle_local_close;
                parser->real = local;
 
@@ -497,6 +499,46 @@ static valerie_response miracle_local_execute( miracle_local local, char *comman
        return cmd.response;
 }
 
+static valerie_response miracle_local_push( miracle_local local, char *command, mlt_service service )
+{
+       command_argument_t cmd;
+       cmd.parser = local->parser;
+       cmd.response = valerie_response_init( );
+       cmd.tokeniser = valerie_tokeniser_init( );
+       cmd.command = command;
+       cmd.unit = -1;
+       cmd.argument = NULL;
+       cmd.root_dir = local->root_dir;
+
+       /* Set the default error */
+       miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+       /* Parse the command */
+       if ( valerie_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 )
+       {
+               int index = 0;
+               int position = 1;
+
+               /* Strip quotes from all tokens */
+               for ( index = 0; index < valerie_tokeniser_count( cmd.tokeniser ); index ++ )
+                       valerie_util_strip( valerie_tokeniser_get_string( cmd.tokeniser, index ), '\"' );
+
+               cmd.unit = miracle_command_parse_unit( &cmd, position );
+               if ( cmd.unit == -1 )
+                       miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG );
+               position ++;
+
+               miracle_push( &cmd, service );
+               miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+               free( cmd.argument );
+       }
+
+       valerie_tokeniser_close( cmd.tokeniser );
+
+       return cmd.response;
+}
+
 /** Close the parser.
 */
 
index 2fe0c7a978a0ccc8bee0a5ca5c30585fa1d17e8c..18f19acab386a937c051e249b4ae4fdb3259888f 100644 (file)
@@ -69,7 +69,7 @@ miracle_unit miracle_unit_init( int index, char *constructor )
                mlt_playlist playlist = mlt_playlist_init( );
                this = calloc( sizeof( miracle_unit_t ), 1 );
                this->properties = mlt_properties_new( );
-               this->producers = mlt_properties_new( );
+               this->old_playlist = mlt_playlist_init( );
                mlt_properties_init( this->properties, this );
                mlt_properties_set_int( this->properties, "unit", index );
                mlt_properties_set_int( this->properties, "generation", 0 );
@@ -84,6 +84,19 @@ miracle_unit miracle_unit_init( int index, char *constructor )
        return this;
 }
 
+static void copy_playlist( mlt_playlist dest, mlt_playlist src )
+{
+       int i;
+
+       for ( i = 0; i < mlt_playlist_count( src ); i ++ )
+       {
+               mlt_playlist_clip_info info;
+               mlt_playlist_get_clip_info( src, &info, i );
+               if ( info.producer != NULL )
+                       mlt_playlist_append_io( dest, info.producer, info.frame_in, info.frame_out );
+       }
+}
+
 static char *strip_root( miracle_unit unit, char *file )
 {
        mlt_properties properties = unit->properties;
@@ -142,33 +155,12 @@ void miracle_unit_set_notifier( miracle_unit this, valerie_notifier notifier, ch
        miracle_unit_status_communicate( this );
 }
 
-static mlt_producer create_producer( char *file )
-{
-       return mlt_factory_producer( "fezzik", file );
-}
-
 /** Create or locate a producer for the file specified.
 */
 
 static mlt_producer locate_producer( miracle_unit unit, char *file )
 {
-       // Get the unit properties
-       mlt_properties properties = unit->producers;
-
-       // Check if we already have loaded this file
-       mlt_producer result = mlt_properties_get_data( properties, file, NULL );
-
-       if ( result == NULL )
-       {
-               // Create the producer
-               result = create_producer( file );
-
-               // Now store the result
-               if ( result != NULL )
-                       mlt_properties_set_data( properties, file, result, 0, ( mlt_destructor )mlt_producer_close, NULL );
-       }
-
-       return result;
+       return mlt_factory_producer( "fezzik", file );
 }
 
 /** Update the generation count.
@@ -190,14 +182,11 @@ static void clear_unit( miracle_unit unit )
        mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
        mlt_producer producer = mlt_playlist_producer( playlist );
 
+       mlt_playlist_clear( unit->old_playlist );
+       copy_playlist( unit->old_playlist, playlist );
        mlt_playlist_clear( playlist );
        mlt_producer_seek( producer, 0 );
 
-       if ( unit->old_producers != NULL )
-               mlt_properties_close( unit->old_producers );
-       unit->old_producers = unit->producers;
-       unit->producers = mlt_properties_new( );
-
        update_generation( unit );
 }
 
@@ -215,16 +204,15 @@ static void clean_unit( miracle_unit unit )
        double speed = mlt_producer_get_speed( producer );
        mlt_playlist_get_clip_info( playlist, &info, current );
 
-       if ( info.resource != NULL )
+       if ( info.producer != NULL )
        {
-               void *instance = mlt_properties_get_data( unit->producers, info.resource, NULL );
+               mlt_properties_inc_ref( mlt_producer_properties( info.producer ) );
                position -= info.start;
-               mlt_properties_set_data( unit->producers, info.resource, instance, 0, NULL, NULL );
                clear_unit( unit );
-               mlt_playlist_append_io( playlist, instance, info.frame_in, info.frame_out );
-               mlt_properties_set_data( unit->producers, info.resource, instance, 0, ( mlt_destructor )mlt_producer_close, NULL );
+               mlt_playlist_append_io( playlist, info.producer, info.frame_in, info.frame_out );
                mlt_producer_seek( producer, position );
                mlt_producer_set_speed( producer, speed );
+               mlt_producer_close( info.producer );
        }
        
        update_generation( unit );
@@ -245,10 +233,14 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response )
        for ( i = 0; i < mlt_playlist_count( playlist ); i ++ )
        {
                mlt_playlist_clip_info info;
+               char *title;
                mlt_playlist_get_clip_info( playlist , &info, i );
+               title = mlt_properties_get( mlt_producer_properties( info.producer ), "title" );
+               if ( title == NULL )
+                       title = strip_root( unit, info.resource );
                valerie_response_printf( response, 10240, "%d \"%s\" %d %d %d %d %.2f\n", 
                                                                 i, 
-                                                                strip_root( unit, info.resource ), 
+                                                                title,
                                                                 info.frame_in, 
                                                                 info.frame_out,
                                                                 info.frame_count, 
@@ -269,20 +261,20 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response )
 
 valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, int32_t in, int32_t out, int flush )
 {
-       // Now try to create an producer
-       mlt_producer instance = create_producer( clip );
+       // Now try to create a producer
+       mlt_producer instance = locate_producer( unit, clip );
 
        if ( instance != NULL )
        {
                clear_unit( unit );
                mlt_properties properties = unit->properties;
-               mlt_properties_set_data( unit->producers, clip, instance, 0, ( mlt_destructor )mlt_producer_close, NULL );
                mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
                mlt_consumer consumer = mlt_properties_get_data( unit->properties, "consumer", NULL );
                mlt_consumer_purge( consumer );
                mlt_playlist_append_io( playlist, instance, in, out );
                miracle_log( LOG_DEBUG, "loaded clip %s", clip );
                miracle_unit_status_communicate( unit );
+               mlt_producer_close( instance );
                return valerie_ok;
        }
 
@@ -302,6 +294,7 @@ valerie_error_code miracle_unit_insert( miracle_unit unit, char *clip, int index
                miracle_log( LOG_DEBUG, "inserted clip %s at %d", clip, index );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
+               mlt_producer_close( instance );
                return valerie_ok;
        }
 
@@ -369,12 +362,30 @@ valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, int32_t i
                miracle_log( LOG_DEBUG, "appended clip %s", clip );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
+               mlt_producer_close( instance );
                return valerie_ok;
        }
 
        return valerie_invalid_file;
 }
 
+/** Add an mlt_service to the playlist
+
+    \param unit A miracle_unit handle.
+    \param service the service to add
+*/
+
+valerie_error_code miracle_unit_append_service( miracle_unit unit, mlt_service service )
+{
+       mlt_properties properties = unit->properties;
+       mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
+       mlt_playlist_append( playlist, ( mlt_producer )service );
+       miracle_log( LOG_DEBUG, "appended clip" );
+       update_generation( unit );
+       miracle_unit_status_communicate( unit );
+       return valerie_ok;
+}
+
 /** Start playing the unit.
 
     \todo error handling
@@ -433,23 +444,28 @@ int miracle_unit_transfer( miracle_unit dest_unit, miracle_unit src_unit )
        mlt_playlist dest_playlist = mlt_properties_get_data( dest_properties, "playlist", NULL );
        mlt_properties src_properties = src_unit->properties;
        mlt_playlist src_playlist = mlt_properties_get_data( src_properties, "playlist", NULL );
+       mlt_playlist tmp_playlist = mlt_playlist_init( );
 
        for ( i = 0; i < mlt_playlist_count( src_playlist ); i ++ )
        {
                mlt_playlist_clip_info info;
                mlt_playlist_get_clip_info( src_playlist, &info, i );
-               mlt_producer producer = locate_producer( dest_unit, info.resource );
-               if ( producer != NULL )
-               {
-                       mlt_playlist_append_io( dest_playlist, producer, info.frame_in, info.frame_out );
-                       if ( i == 0 )
-                       {
-                               miracle_unit_change_position( dest_unit, mlt_playlist_count( dest_playlist ) - 1, 0 );
-                               clean_unit( dest_unit );
-                       }
-               }
+               if ( info.producer != NULL )
+                       mlt_playlist_append_io( tmp_playlist, info.producer, info.frame_in, info.frame_out );
+       }
+
+       clear_unit( src_unit );
+
+       for ( i = 0; i < mlt_playlist_count( tmp_playlist ); i ++ )
+       {
+               mlt_playlist_clip_info info;
+               mlt_playlist_get_clip_info( tmp_playlist, &info, i );
+               if ( info.producer != NULL )
+                       mlt_playlist_append_io( dest_playlist, info.producer, info.frame_in, info.frame_out );
        }
 
+       mlt_playlist_close( tmp_playlist );
+
        return 0;
 }
 
@@ -483,14 +499,17 @@ int miracle_unit_get_status( miracle_unit unit, valerie_status status )
 
                if ( info.resource != NULL && strcmp( info.resource, "" ) )
                {
-                       strncpy( status->clip, strip_root( unit, info.resource ), sizeof( status->clip ) );
+                       char *title = mlt_properties_get( mlt_producer_properties( info.producer ), "title" );
+                       if ( title == NULL )
+                               title = strip_root( unit, info.resource );
+                       strncpy( status->clip, title, sizeof( status->clip ) );
                        status->speed = (int)( mlt_producer_get_speed( producer ) * 1000.0 );
                        status->fps = mlt_producer_get_fps( producer );
                        status->in = info.frame_in;
                        status->out = info.frame_out;
                        status->position = mlt_producer_position( clip );
                        status->length = mlt_producer_get_length( clip );
-                       strncpy( status->tail_clip, strip_root( unit, info.resource ), sizeof( status->tail_clip ) );
+                       strncpy( status->tail_clip, title, sizeof( status->tail_clip ) );
                        status->tail_in = info.frame_in;
                        status->tail_out = info.frame_out;
                        status->tail_position = mlt_producer_position( clip );
@@ -702,10 +721,8 @@ void miracle_unit_close( miracle_unit unit )
        {
                miracle_log( LOG_DEBUG, "closing unit..." );
                miracle_unit_terminate( unit );
-               if ( unit->old_producers != NULL )
-                       mlt_properties_close( unit->old_producers );
+               mlt_playlist_close( unit->old_playlist );
                mlt_properties_close( unit->properties );
-               mlt_properties_close( unit->producers );
                free( unit );
                miracle_log( LOG_DEBUG, "... unit closed." );
        }
index 3ba87513ab3f6a1c92d4ac323c1a8c24a0b3f8eb..7879268135f114067ff4e6c7ccbf21a4c87003e2 100644 (file)
@@ -34,8 +34,7 @@ extern "C"
 typedef struct
 {
        mlt_properties properties;
-       mlt_properties producers;
-       mlt_properties old_producers;
+       mlt_playlist old_playlist;
 } 
 miracle_unit_t, *miracle_unit;
 
@@ -45,6 +44,7 @@ extern void                 miracle_unit_allow_stdin( miracle_unit unit, int fla
 extern valerie_error_code   miracle_unit_load( miracle_unit unit, char *clip, int32_t in, int32_t out, int flush );
 extern valerie_error_code      miracle_unit_insert( miracle_unit unit, char *clip, int index, int32_t in, int32_t out );
 extern valerie_error_code   miracle_unit_append( miracle_unit unit, char *clip, int32_t in, int32_t out );
+extern valerie_error_code   miracle_unit_append_service( miracle_unit unit, mlt_service service );
 extern valerie_error_code      miracle_unit_remove( miracle_unit unit, int index );
 extern valerie_error_code      miracle_unit_clean( miracle_unit unit );
 extern valerie_error_code      miracle_unit_clear( miracle_unit unit );
index 53966d46a0c939ef897395f4ed7873e0999af0c9..c810c0a3bfa882cea56c25b428c00bbfb506e34c 100644 (file)
@@ -254,6 +254,15 @@ int miracle_append( command_argument cmd_arg )
        return RESPONSE_SUCCESS;
 }
 
+int miracle_push( command_argument cmd_arg, mlt_service service )
+{
+       miracle_unit unit = miracle_get_unit(cmd_arg->unit);
+       if ( unit != NULL && service != NULL )
+               if ( miracle_unit_append_service( unit, service ) == valerie_ok )
+                       return RESPONSE_SUCCESS;
+       return RESPONSE_BAD_FILE;
+}
+
 int miracle_play( command_argument cmd_arg )
 {
        miracle_unit unit = miracle_get_unit(cmd_arg->unit);
index b4bde3a1b7943dc1bb105e0f89c326e1e2120775..461c51a328e31eb49e5e5ac7ed6a84cd5e2cff3e 100644 (file)
@@ -50,6 +50,7 @@ extern response_codes miracle_get_unit_status( command_argument );
 extern response_codes miracle_set_unit_property( command_argument );
 extern response_codes miracle_get_unit_property( command_argument );
 extern response_codes miracle_transfer( command_argument );
+extern response_codes miracle_push( command_argument, mlt_service );
 
 #ifdef __cplusplus
 }
index 6f25d6f30ddbf7bb27c8ef207279b15a55c67e6d..aba87afffb7462ac2939eaf13de7c47c13e243ed 100644 (file)
@@ -32,6 +32,7 @@ dist-clean:   clean
                rm -f .depend
 
 clean: 
+               if [ $(LOCAL_FFMPEG) ] ; then $(MAKE) -C ffmpeg clean ; fi
                rm -f $(OBJS) $(TARGET) 
 
 install: all
index 883db6928995884c09e36633a870785c7af786c5..f4a87ea6277eb360b9c560fe96bdec517146b031 100644 (file)
@@ -134,6 +134,10 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                {
                        if ( mlt_properties_get_int( properties, "reverse" ) == 0 )
                        {
+                               // Apply all filters that are attached to this filter to the b frame
+                               mlt_service_apply_filters( mlt_filter_service( this ), b_frame, 0 );
+
+                               // Process the frame
                                mlt_transition_process( composite, frame, b_frame );
 
                                // Get the image
@@ -147,6 +151,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                                mlt_properties_set( a_props, "rescale.interp", "nearest" );
                                mlt_properties_set( b_props, "rescale.interp", "nearest" );
                                mlt_properties_set_int( b_props, "consumer_aspect_ratio", 1 );
+                               mlt_service_apply_filters( mlt_filter_service( this ), frame, 0 );
                                error = mlt_frame_get_image( b_frame, image, format, width, height, 1 );
                                mlt_properties_set_data( b_props, "image", *image, 0, NULL, NULL );
                                mlt_properties_set_data( a_props, "image", *image, *width * *height * 2, mlt_pool_release, NULL );
@@ -203,6 +208,8 @@ mlt_filter filter_watermark_init( void *arg )
                mlt_properties_set( properties, "factory", "fezzik" );
                if ( arg != NULL )
                        mlt_properties_set( properties, "resource", arg );
+               // Ensure that attached filters are handled privately
+               mlt_properties_set_int( properties, "_filter_private", 1 );
        }
        return this;
 }
index 29bde448814828e990c25fe378a52cc4b41a4854..2cc677905a2fe4b4772a7f23eda68c1aab1c3a23 100644 (file)
@@ -60,6 +60,9 @@ rgba_color parse_color( char *color )
 {
        rgba_color result = { 0xff, 0xff, 0xff, 0xff };
 
+       if ( strchr( color, '/' ) )
+               color = strrchr( color, '/' ) + 1;
+
        if ( !strncmp( color, "0x", 2 ) )
        {
                unsigned int temp = 0;
index aa7b660aeb388ad29520f9c5877aa2ce55b09f39..1e2f8246e680ffac2db8abe3b84de39a08701cae 100644 (file)
@@ -129,23 +129,6 @@ static uint8_t *filter_get_alpha_mask( mlt_frame this )
        return alpha;
 }
 
-static void apply_filters( mlt_filter this, mlt_frame frame, int index )
-{
-       mlt_service service = mlt_filter_service( this );
-       mlt_properties properties = mlt_filter_properties( this );
-       int i;
-
-       if ( index == 0 || mlt_properties_get_int( properties, "_filter_private" ) == 0 )
-       {
-               mlt_filter filter = NULL;
-               for ( i = 0; ( filter = mlt_service_filter( service, i ) ) != NULL; i ++ )
-               {
-                       mlt_filter_process( filter, frame );
-                       apply_filters( filter, frame, 1 );
-               }
-       }
-}
-
 /** Do it :-).
 */
 
@@ -317,7 +300,7 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                // Allow filters to be attached to a region filter
                filter = mlt_properties_get_data( properties, "_region_filter", NULL );
                if ( filter != NULL )
-                       apply_filters( filter, b_frame, 0 );
+                       mlt_service_apply_filters( mlt_filter_service( filter ), b_frame, 0 );
 
                // Hmm - this is probably going to go wrong....
                mlt_frame_set_position( frame, position );
index 554a6004302199ae303f1351f00461a6da6806e7..82ed3d4235e6866b8f996ff91a4bbe30ddecf667 100644 (file)
@@ -19,7 +19,7 @@
  */
 
 #include <string.h>
-
+#include <gdk-pixbuf/gdk-pixbuf.h>
 #include "producer_pixbuf.h"
 #include "producer_pango.h"
 #include "filter_rescale.h"
index 212aea8d627bf60cef9e3365aa87aa0aca794220..ce25564ce12cd9f8b0ee0d9637abb3d975f75082 100644 (file)
@@ -129,6 +129,7 @@ mlt_producer producer_inigo_init( char **argv )
        mlt_field field = mlt_tractor_field( tractor );
        mlt_properties field_properties = mlt_field_properties( field );
        mlt_multitrack multitrack = mlt_tractor_multitrack( tractor );
+       char *title = NULL;
 
        // We need to track the number of registered filters
        mlt_properties_set_int( field_properties, "registered", 0 );
@@ -265,6 +266,8 @@ mlt_producer producer_inigo_init( char **argv )
                {
                        if ( producer != NULL )
                                mlt_playlist_append( playlist, producer );
+                       if ( title == NULL )
+                               title = argv[ i ];
                        producer = create_producer( field, argv[ i ] );
                        if ( producer != NULL )
                        {
@@ -303,6 +306,8 @@ mlt_producer producer_inigo_init( char **argv )
        mlt_properties_set_position( props, "length", mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) + 1 );
        mlt_producer_set_in_and_out( prod, 0, mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) );
        mlt_properties_set_double( props, "fps", mlt_producer_get_fps( mlt_multitrack_producer( multitrack ) ) );
+       if ( title != NULL )
+               mlt_properties_set( props, "title", strchr( title, '/' ) ? strrchr( title, '/' ) + 1 : title );
 
        return prod;
 }
index f95b1483955438455715b42a58ba5a58623d5df2..6154771348658f25dd13e21792493449d1cd42b0 100644 (file)
@@ -634,8 +634,10 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
                                        {
                                                mix = ( float )*( alpha + dy * b_width + dx ) / 255.0;
                                                dx += dx & 1;
-                                               *p ++ = *p * ( 1 - mix ) + mix * *( b_image + dy * b_stride + ( dx << 1 ) );
-                                               *p ++ = *p * ( 1 - mix ) + mix * *( b_image + dy * b_stride + ( dx << 1 ) + ( ( x & 1 ) << 1 ) + 1 );
+                                               *p = *p * ( 1 - mix ) + mix * *( b_image + dy * b_stride + ( dx << 1 ) );
+                                               p ++;
+                                               *p = *p * ( 1 - mix ) + mix * *( b_image + dy * b_stride + ( dx << 1 ) + ( ( x & 1 ) << 1 ) + 1 );
+                                               p ++;
                                        }
                                }
                                else
index dfce3d1ad10a3268192f6726af71f65e3c1a427d..3b940438ca19da3ed7cea7c340fd907f8a027e70 100644 (file)
@@ -433,15 +433,14 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame )
                }
        
                if ( width != this->width || height != this->height || 
-                        ( int )( this->last_frame_aspect * 1000 ) != ( int )( mlt_frame_get_aspect_ratio( frame ) * 1000 ) )
+                        ( ( int )( this->last_frame_aspect * 1000 ) != ( int )( mlt_frame_get_aspect_ratio( frame ) * 1000 ) &&
+                        ( mlt_frame_get_aspect_ratio( frame ) != 1.0 || this->last_frame_aspect == 0.0 ) ) )
+
                {
-                       if ( mlt_frame_get_aspect_ratio( frame ) != 1.0 || this->last_frame_aspect == 0.0 )
-                       {
-                               this->width = width;
-                               this->height = height;
-                               this->last_frame_aspect = mlt_frame_get_aspect_ratio( frame );
-                               changed = 1;
-                       }
+                       this->width = width;
+                       this->height = height;
+                       this->last_frame_aspect = mlt_frame_get_aspect_ratio( frame );
+                       changed = 1;
                }
 
                if ( this->sdl_screen == NULL || changed )
index fa78655343a1581e3430543acceb3f6a801cf8d3..e156567c719114afd7e3dae8730fe9d855fe9793 100644 (file)
@@ -9,7 +9,7 @@ CFLAGS += -I../../ -I/usr/include/sox
 
 LDFLAGS += -lst -lpopt -lvorbis -logg -lvorbisfile -lvorbisenc
 
-LDFLAGS+=-L../../framework -lmlt -lmad
+LDFLAGS+=-L../../framework -lmlt -lmp3lame
 
 SRCS := $(OBJS:.o=.c)
 
diff --git a/src/modules/valerie/Makefile b/src/modules/valerie/Makefile
new file mode 100644 (file)
index 0000000..9cd7e57
--- /dev/null
@@ -0,0 +1,33 @@
+include ../../../config.mak
+
+TARGET = ../libmltvalerie.so
+
+OBJS = factory.o \
+          consumer_valerie.o
+
+CFLAGS += -I../../ 
+
+LDFLAGS+=-L../../valerie -lvalerie -L../../framework -lmlt
+
+SRCS := $(OBJS:.o=.c)
+
+all:   $(TARGET)
+
+$(TARGET): $(OBJS)
+               $(CC) -shared -o $@ $(OBJS) $(LDFLAGS)
+
+depend:        $(SRCS)
+               $(CC) -MM $(CFLAGS) $^ 1>.depend
+
+dist-clean:    clean
+               rm -f .depend
+
+clean: 
+               rm -f $(OBJS) $(TARGET) 
+
+install: all
+       install -m 755 $(TARGET) "$(prefix)/share/mlt/modules"
+
+ifneq ($(wildcard .depend),)
+include .depend
+endif
diff --git a/src/modules/valerie/configure b/src/modules/valerie/configure
new file mode 100755 (executable)
index 0000000..1ebe527
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+if [ "$help" != "1" ]
+then
+
+cat << EOF >> ../consumers.dat
+valerie                        libmltvalerie.so
+EOF
+
+fi
+
diff --git a/src/modules/valerie/consumer_valerie.c b/src/modules/valerie/consumer_valerie.c
new file mode 100644 (file)
index 0000000..e473584
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * consumer_westley.c -- a libxml2 serialiser of mlt service networks
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Dan Dennedy <dan@dennedy.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "consumer_valerie.h"
+#include <valerie/valerie.h>
+#include <valerie/valerie_remote.h>
+#include <framework/mlt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+
+static int consumer_is_stopped( mlt_consumer this );
+static int consumer_start( mlt_consumer this );
+
+/** This is what will be called by the factory
+*/
+
+mlt_consumer consumer_valerie_init( char *arg )
+{
+       // Create the consumer object
+       mlt_consumer this = calloc( sizeof( struct mlt_consumer_s ), 1 );
+
+       // If no malloc'd and consumer init ok
+       if ( this != NULL && mlt_consumer_init( this, NULL ) == 0 )
+       {
+               // Allow thread to be started/stopped
+               this->start = consumer_start;
+               this->is_stopped = consumer_is_stopped;
+
+               mlt_properties_set( mlt_consumer_properties( this ), "server", arg == NULL ? "localhost" : arg );
+               mlt_properties_set_int( mlt_consumer_properties( this ), "port", 5250 );
+               mlt_properties_set_int( mlt_consumer_properties( this ), "unit", 0 );
+               mlt_properties_set( mlt_consumer_properties( this ), "command", "append" );
+
+               // Return the consumer produced
+               return this;
+       }
+
+       // malloc or consumer init failed
+       free( this );
+
+       // Indicate failure
+       return NULL;
+}
+
+static int consumer_start( mlt_consumer this )
+{
+       // Get the producer service
+       mlt_service service = mlt_service_producer( mlt_consumer_service( this ) );
+
+       // Get the properties object
+       mlt_properties properties = mlt_consumer_properties( this );
+
+       // Get all the properties now
+       char *server = mlt_properties_get( properties, "server" );
+       int port = mlt_properties_get_int( properties, "port" );
+       char *command = mlt_properties_get( properties, "command" );
+       int unit = mlt_properties_get_int( properties, "unit" );
+       char *title = mlt_properties_get( properties, "title" );
+
+       // If this is a reuse, then a valerie object will exist
+       valerie connection = mlt_properties_get_data( properties, "connection", NULL );
+
+       if ( service != NULL )
+       {
+               // Initiate the connection if required
+               if ( connection == NULL )
+               {
+                       valerie_parser parser = valerie_parser_init_remote( server, port );
+                       connection = valerie_init( parser );
+                       if ( valerie_connect( connection ) == valerie_ok )
+                       {
+                               mlt_properties_set_data( properties, "connection", connection, 0, ( mlt_destructor )valerie_close, NULL );
+                               mlt_properties_set_data( properties, "parser", parser, 0, ( mlt_destructor )valerie_parser_close, NULL );
+                       }
+                       else
+                       {
+                               fprintf( stderr, "Unable to connect to the server at %s:%d\n", server, port );
+                               valerie_close( connection );
+                               valerie_parser_close( parser );
+                               connection = NULL;
+                       }
+               }
+
+               // If we have connection, push the service over
+               if ( connection != NULL )
+               {
+                       int error;
+
+                       // Set the title if provided
+                       if ( title != NULL )
+                               mlt_properties_set( mlt_service_properties( service ), "title", title );
+                       else if ( mlt_properties_get( mlt_service_properties( service ), "title" ) == NULL )
+                               mlt_properties_set( mlt_service_properties( service ), "title", "Anonymous Submission" );
+
+                       // Push the service
+                       error = valerie_unit_push( connection, unit, command, service );
+
+                       // Report error
+                       if ( error != valerie_ok )
+                               fprintf( stderr, "Push failed on %s:%d %s u%d (%d)\n", server, port, command, unit, error );
+               }
+       }
+       
+       mlt_consumer_stop( this );
+       mlt_consumer_stopped( this );
+
+       return 0;
+}
+
+static int consumer_is_stopped( mlt_consumer this )
+{
+       return 1;
+}
diff --git a/src/modules/valerie/consumer_valerie.h b/src/modules/valerie/consumer_valerie.h
new file mode 100644 (file)
index 0000000..8fa274c
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * consumer_valerie.h -- pushes a service via valerie
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@telenet.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CONSUMER_VALERIE_H_
+#define _CONSUMER_VALERIE_H_
+
+#include <framework/mlt_consumer.h>
+
+extern mlt_consumer consumer_valerie_init( char * );
+
+#endif
diff --git a/src/modules/valerie/factory.c b/src/modules/valerie/factory.c
new file mode 100644 (file)
index 0000000..5a5de3a
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * factory.c -- the factory method interfaces
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include "consumer_valerie.h"
+
+void *mlt_create_producer( char *id, void *arg )
+{
+       return NULL;
+}
+
+void *mlt_create_filter( char *id, void *arg )
+{
+       return NULL;
+}
+
+void *mlt_create_transition( char *id, void *arg )
+{
+       return NULL;
+}
+
+void *mlt_create_consumer( char *id, void *arg )
+{
+       if ( !strcmp( id, "valerie" ) )
+               return consumer_valerie_init( arg );
+       return NULL;
+}
+
index ac2e83f485092ac55e20746c1dfbee9568cced88..af068dd89389c3f0a361c6b1ab07d4c8132f5377 100755 (executable)
@@ -5,6 +5,7 @@ then
 
 cat << EOF >> ../producers.dat
 westley                        libmltwestley.so
+westley-xml            libmltwestley.so
 EOF
 
 cat << EOF >> ../consumers.dat
index bfb8591051ef9a8e29435726e47163d94f435d7f..4d095f8809051af76f6e55181014a0b91c8f9256 100644 (file)
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
+#include <unistd.h>
 #include <libxml/tree.h>
 
 #define ID_SIZE 128
@@ -40,6 +41,7 @@ struct serialise_context_s
        int transition_count;
        int pass;
        mlt_properties hide_map;
+       char *root;
 };
 typedef struct serialise_context_s* serialise_context;
 
@@ -165,7 +167,7 @@ mlt_consumer consumer_westley_init( char *arg )
        return NULL;
 }
 
-static inline void serialise_properties( mlt_properties properties, xmlNode *node )
+static inline void serialise_properties( serialise_context context, mlt_properties properties, xmlNode *node )
 {
        int i;
        xmlNode *p;
@@ -181,12 +183,17 @@ static inline void serialise_properties( mlt_properties properties, xmlNode *nod
                         strcmp( name, "in" ) != 0 &&
                         strcmp( name, "out" ) != 0 && 
                         strcmp( name, "id" ) != 0 && 
+                        strcmp( name, "root" ) != 0 && 
                         strcmp( name, "width" ) != 0 &&
                         strcmp( name, "height" ) != 0 )
                {
+                       char *value = mlt_properties_get_value( properties, i );
                        p = xmlNewChild( node, NULL, "property", NULL );
                        xmlNewProp( p, "name", mlt_properties_get_name( properties, i ) );
-                       xmlNodeSetContent( p, mlt_properties_get_value( properties, i ) );
+                       if ( strcmp( context->root, "" ) && !strncmp( value, context->root, strlen( context->root ) ) )
+                               xmlNodeSetContent( p, value + strlen( context->root ) + 1 );
+                       else
+                               xmlNodeSetContent( p, value );
                }
        }
 }
@@ -207,9 +214,19 @@ static inline void serialise_service_filters( serialise_context context, mlt_ser
                        char *id = westley_get_id( context, mlt_filter_service( filter ), westley_filter );
                        if ( id != NULL )
                        {
+                               int in = mlt_properties_get_position( properties, "in" );
+                               int out = mlt_properties_get_position( properties, "out" );
                                p = xmlNewChild( node, NULL, "filter", NULL );
                                xmlNewProp( p, "id", id );
-                               serialise_properties( properties, p );
+                               if ( in != 0 || out != 0 )
+                               {
+                                       char temp[ 20 ];
+                                       sprintf( temp, "%d", in );
+                                       xmlNewProp( p, "in", temp );
+                                       sprintf( temp, "%d", out );
+                                       xmlNewProp( p, "out", temp );
+                               }
+                               serialise_properties( context, properties, p );
                                serialise_service_filters( context, mlt_filter_service( filter ), p );
                        }
                }
@@ -232,7 +249,7 @@ static void serialise_producer( serialise_context context, mlt_service service,
 
                // Set the id
                xmlNewProp( child, "id", id );
-               serialise_properties( properties, child );
+               serialise_properties( context, properties, child );
                serialise_service_filters( context, service, child );
 
                // Add producer to the map
@@ -418,7 +435,7 @@ static void serialise_filter( serialise_context context, mlt_service service, xm
                xmlNewProp( child, "in", mlt_properties_get( properties, "in" ) );
                xmlNewProp( child, "out", mlt_properties_get( properties, "out" ) );
 
-               serialise_properties( properties, child );
+               serialise_properties( context, properties, child );
                serialise_service_filters( context, service, child );
        }
 }
@@ -445,7 +462,7 @@ static void serialise_transition( serialise_context context, mlt_service service
                xmlNewProp( child, "in", mlt_properties_get( properties, "in" ) );
                xmlNewProp( child, "out", mlt_properties_get( properties, "out" ) );
 
-               serialise_properties( properties, child );
+               serialise_properties( context, properties, child );
                serialise_service_filters( context, service, child );
        }
 }
@@ -519,12 +536,28 @@ static void serialise_service( serialise_context context, mlt_service service, x
 
 xmlDocPtr westley_make_doc( mlt_service service )
 {
+       mlt_properties properties = mlt_service_properties( service );
        xmlDocPtr doc = xmlNewDoc( "1.0" );
        xmlNodePtr root = xmlNewNode( NULL, "westley" );
        struct serialise_context_s *context = calloc( 1, sizeof( struct serialise_context_s ) );
        
        xmlDocSetRootElement( doc, root );
-               
+
+       // If we have root, then deal with it now
+       if ( mlt_properties_get( properties, "root" ) != NULL )
+       {
+               xmlNewProp( root, "root", mlt_properties_get( properties, "root" ) );
+               context->root = strdup( mlt_properties_get( properties, "root" ) );
+       }
+       else
+       {
+               context->root = strdup( "" );
+       }
+
+       // Assign a title property
+       if ( mlt_properties_get( properties, "title" ) != NULL )
+               xmlNewProp( root, "title", mlt_properties_get( properties, "title" ) );
+
        // Construct the context maps
        context->id_map = mlt_properties_new();
        context->hide_map = mlt_properties_new();
@@ -544,12 +577,12 @@ xmlDocPtr westley_make_doc( mlt_service service )
        // Cleanup resource
        mlt_properties_close( context->id_map );
        mlt_properties_close( context->hide_map );
+       free( context->root );
        free( context );
        
        return doc;
 }
 
-
 static int consumer_start( mlt_consumer this )
 {
        xmlDocPtr doc = NULL;
@@ -558,15 +591,49 @@ static int consumer_start( mlt_consumer this )
        mlt_service service = mlt_service_producer( mlt_consumer_service( this ) );
        if ( service != NULL )
        {
-               char *resource =  mlt_properties_get( mlt_consumer_properties( this ), "resource" );
+               mlt_properties properties = mlt_consumer_properties( this );
+               char *resource =  mlt_properties_get( properties, "resource" );
+
+               // Set the title if provided
+               if ( mlt_properties_get( properties, "title" ) )
+                       mlt_properties_set( mlt_service_properties( service ), "title", mlt_properties_get( properties, "title" ) );
+               else if ( mlt_properties_get( mlt_service_properties( service ), "title" ) == NULL )
+                       mlt_properties_set( mlt_service_properties( service ), "title", "Anonymous Submission" );
 
+               // Check for a root on the consumer properties and pass to service
+               if ( mlt_properties_get( properties, "root" ) )
+                       mlt_properties_set( mlt_service_properties( service ), "root", mlt_properties_get( properties, "root" ) );
+
+               // Specify roots in other cases...
+               if ( resource != NULL && mlt_properties_get( properties, "root" ) == NULL )
+               {
+                       // Get the current working directory
+                       char *cwd = getcwd( NULL, 0 );
+                       mlt_properties_set( mlt_service_properties( service ), "root", cwd );
+                       free( cwd );
+               }
+
+               // Make the document
                doc = westley_make_doc( service );
-               
+
+               // Handle the output
                if ( resource == NULL || !strcmp( resource, "" ) )
+               {
                        xmlDocFormatDump( stdout, doc, 1 );
+               }
+               else if ( !strcmp( resource, "buffer" ) )
+               {
+                       xmlChar *buffer = NULL;
+                       int length = 0;
+                       xmlDocDumpMemory( doc, &buffer, &length );
+                       mlt_properties_set_data( properties, "buffer", buffer, length, xmlFree, NULL );
+               }
                else
+               {
                        xmlSaveFormatFile( resource, doc, 1 );
+               }
                
+               // Close the document
                xmlFreeDoc( doc );
        }
        
index e60cd566f9e6c06bd26499a3d1c1dad65ba1ef85..4e88388673148a756258cf5c40293bb2e1fd7002 100644 (file)
@@ -26,7 +26,9 @@
 void *mlt_create_producer( char *id, void *arg )
 {
        if ( !strcmp( id, "westley" ) )
-               return producer_westley_init( arg );
+               return producer_westley_init( 0, arg );
+       if ( !strcmp( id, "westley-xml" ) )
+               return producer_westley_init( 1, arg );
        return NULL;
 }
 
index 8705035a21245b96c4495afe818e430d0b35def5..46fd80965a476b1181cf397a465582e8419607af 100644 (file)
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <unistd.h>
 
 #include <libxml/parser.h>
 #include <libxml/parserInternals.h> // for xmlCreateFileParserCtxt
@@ -172,13 +173,14 @@ static inline void qualify_property( deserialise_context context, mlt_properties
        if ( resource != NULL )
        {
                // Qualify file name properties 
-               char *root = mlt_properties_get( context->producer_map, "_root" );
-               if ( root != NULL )
+               char *root = mlt_properties_get( context->producer_map, "root" );
+               if ( root != NULL && strcmp( root, "" ) )
                {
-                       char *full_resource = malloc( strlen( root ) + strlen( resource ) + 1 );
-                       if ( resource[ 0 ] != '/' )
+                       char *full_resource = malloc( strlen( root ) + strlen( resource ) + 2 );
+                       if ( resource[ 0 ] != '/' && strchr( resource, ':' ) == NULL )
                        {
                                strcpy( full_resource, root );
+                               strcat( full_resource, "/" );
                                strcat( full_resource, resource );
                        }
                        else
@@ -1000,6 +1002,9 @@ static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **at
                on_start_transition( context, name, atts );
        else if ( strcmp( name, "property" ) == 0 )
                on_start_property( context, name, atts );
+       else if ( strcmp( name, "westley" ) == 0 )
+               for ( ; atts != NULL && *atts != NULL; atts += 2 )
+                       mlt_properties_set( context->producer_map, ( char * )atts[ 0 ], ( char * )atts[ 1 ] );
 }
 
 static void on_end_element( void *ctx, const xmlChar *name )
@@ -1213,9 +1218,9 @@ static void parse_url( mlt_properties properties, char *url )
                mlt_properties_set( properties, name, value );
 }
 
-mlt_producer producer_westley_init( char *url )
+mlt_producer producer_westley_init( int info, char *data )
 {
-       if ( url == NULL )
+       if ( data == NULL )
                return NULL;
        xmlSAXHandler *sax = calloc( 1, sizeof( xmlSAXHandler ) );
        struct deserialise_context_s *context = calloc( 1, sizeof( struct deserialise_context_s ) );
@@ -1223,28 +1228,43 @@ mlt_producer producer_westley_init( char *url )
        int i = 0;
        struct _xmlParserCtxt *xmlcontext;
        int well_formed = 0;
-       char *filename = strdup( url );
+       char *filename = NULL;
        
        context->producer_map = mlt_properties_new();
        context->destructors = mlt_properties_new();
        context->params = mlt_properties_new();
 
-       // Decode URL and parse parameters      
-       parse_url( context->params, url_decode( filename, url ) );
+       // Decode URL and parse parameters
+       mlt_properties_set( context->producer_map, "root", "" );
+       if ( info == 0 )
+       {
+               filename = strdup( data );
+               parse_url( context->params, url_decode( filename, data ) );
 
-       // 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
+               if ( strchr( filename, '/' ) )
+               {
+                       char *root = NULL;
+                       mlt_properties_set( context->producer_map, "root", filename );
+                       root = mlt_properties_get( context->producer_map, "root" );
+                       *( strrchr( root, '/' ) ) = '\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';
+                       // If we don't have an absolute path here, we're heading for disaster...
+                       if ( root[ 0 ] != '/' )
+                       {
+                               char *cwd = getcwd( NULL, 0 );
+                               char *real = malloc( strlen( cwd ) + strlen( root ) + 2 );
+                               sprintf( real, "%s/%s", cwd, root );
+                               mlt_properties_set( context->producer_map, "root", real );
+                               free( real );
+                               free( cwd );
+                       }
+               }
        }
 
+       // We need to track the number of registered filters
+       mlt_properties_set_int( context->destructors, "registered", 0 );
+
        // Setup SAX callbacks
        sax->startElement = on_start_element;
        sax->endElement = on_end_element;
@@ -1259,7 +1279,11 @@ mlt_producer producer_westley_init( char *url )
        xmlSubstituteEntitiesDefault( 1 );
        // This is used to facilitate entity substitution in the SAX parser
        context->entity_doc = xmlNewDoc( "1.0" );
-       xmlcontext = xmlCreateFileParserCtxt( filename );
+       if ( info == 0 )
+               xmlcontext = xmlCreateFileParserCtxt( filename );
+       else
+               xmlcontext = xmlCreateMemoryParserCtxt( data, strlen( data ) );
+
        xmlcontext->sax = sax;
        xmlcontext->_private = ( void* )context;
        
@@ -1296,6 +1320,7 @@ mlt_producer producer_westley_init( char *url )
        
        if ( well_formed && service != NULL )
        {
+               char *title = mlt_properties_get( context->producer_map, "title" );
                
                // Need the complete producer list for various reasons
                properties = context->destructors;
@@ -1318,10 +1343,15 @@ mlt_producer producer_westley_init( char *url )
                // 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 );
+
+               // Handle deep copies
                if ( getenv( "MLT_WESTLEY_DEEP" ) == NULL )
                {
                        // Now assign additional properties
-                       mlt_properties_set( properties, "resource", url );
+                       if ( info == 0 )
+                               mlt_properties_set( properties, "resource", data );
 
                        // This tells consumer_westley not to deep copy
                        mlt_properties_set( properties, "westley", "was here" );
index 979a0d7a34a2b513b689e4089b4c51cea8898d4c..8f8a4850040982f1ac034a5056aa105607258dec 100644 (file)
@@ -23,6 +23,6 @@
 
 #include <framework/mlt_producer.h>
 
-extern mlt_producer producer_westley_init( char *filename );
+extern mlt_producer producer_westley_init( int type, char *data );
 
 #endif
index 67b6cf7015d4818fa96e7f74e1a0c7118538abab..8d96f0c8299059b721f0c88c9b23cacd8d4646d2 100644 (file)
@@ -24,7 +24,8 @@ INCS = valerie.h \
 
 SRCS := $(OBJS:.o=.c)
 
-LDFLAGS += -lpthread
+CFLAGS += -I.. -rdynamic
+LDFLAGS += -L ../framework -lmlt -lpthread
 
 all: $(TARGET)
 
index ba8e228025d5f8798f9d33eb397530aea2b32b56..8499f440b8e05a9bbfba46dee4631c8c2d8d56d0 100644 (file)
@@ -145,6 +145,37 @@ valerie_error_code valerie_execute( valerie this, size_t size, char *format, ...
        return error;
 }
 
+/** Execute a command.
+*/
+
+valerie_error_code valerie_push( valerie this, mlt_service service, size_t size, char *format, ... )
+{
+       valerie_error_code error = valerie_server_unavailable;
+       char *command = malloc( size );
+       if ( this != NULL && command != NULL )
+       {
+               va_list list;
+               va_start( list, format );
+               if ( vsnprintf( command, size, format, list ) != 0 )
+               {
+                       valerie_response response = valerie_parser_push( this->parser, command, service );
+                       valerie_set_last_response( this, response );
+                       error = valerie_get_error_code( this, response );
+               }
+               else
+               {
+                       error = valerie_invalid_command;
+               }
+               va_end( list );
+       }
+       else
+       {
+               error = valerie_malloc_failed;
+       }
+       free( command );
+       return error;
+}
+
 /** Set a global property.
 */
 
@@ -252,6 +283,14 @@ valerie_error_code valerie_unit_append( valerie this, int unit, char *file, int3
        return valerie_execute( this, 10240, "APND U%d \"%s\" %d %d", unit, file, in, out );
 }
 
+/** Push a service on to a unit.
+*/
+
+valerie_error_code valerie_unit_push( valerie this, int unit, char *command, mlt_service service )
+{
+       return valerie_push( this, service, 10240, "PUSH U%d %s", unit, command );
+}
+
 /** Clean the unit - this function removes all but the currently playing clip.
 */
 
index 663b6c2af011afe312acd03d811f722ad7a698d6..eb3c9bf8da2504e58d2e7125aca97178544c5305 100644 (file)
@@ -24,6 +24,9 @@
 /* System header files */
 #include <limits.h>
 
+/* MLT Header files. */
+#include <framework/mlt.h>
+
 /* Application header files */
 #include "valerie_parser.h"
 #include "valerie_status.h"
@@ -94,6 +97,7 @@ extern valerie_error_code valerie_unit_load_clipped( valerie, int, char *, int32
 extern valerie_error_code valerie_unit_load_back( valerie, int, char * );
 extern valerie_error_code valerie_unit_load_back_clipped( valerie, int, char *, int32_t, int32_t );
 extern valerie_error_code valerie_unit_append( valerie, int, char *, int32_t, int32_t );
+extern valerie_error_code valerie_unit_push( valerie, int, char *, mlt_service );
 extern valerie_error_code valerie_unit_clean( valerie, int );
 extern valerie_error_code valerie_unit_clear( valerie, int );
 extern valerie_error_code valerie_unit_clip_move( valerie, int, valerie_clip_offset, int, valerie_clip_offset, int );
@@ -246,6 +250,7 @@ extern char *valerie_error_description( valerie_error_code );
 
 /* Courtesy functions. */
 extern valerie_error_code valerie_execute( valerie, size_t, char *, ... );
+extern valerie_error_code valerie_push( valerie, mlt_service, size_t, char *, ... );
 
 /* Close function. */
 extern void valerie_close( valerie );
index 4ead1c043015398d5c8768f30c9eb843c5f4c50e..2b90fedc4342ab432946fa7f8ae2d5484794800a 100644 (file)
@@ -44,6 +44,14 @@ valerie_response valerie_parser_execute( valerie_parser parser, char *command )
        return parser->execute( parser->real, command );
 }
 
+/** Push a service via the parser.
+*/
+
+valerie_response valerie_parser_push( valerie_parser parser, char *command, mlt_service service )
+{
+       return parser->push( parser->real, command, service );
+}
+
 /** Execute a formatted command via the parser.
 */
 
index 71446d9057d40eaaca245ac5f870149834ee2d74..3e1a17b75247296bc56e281787bbcb4f18248376 100644 (file)
@@ -21,6 +21,9 @@
 #ifndef _VALERIE_PARSER_H_
 #define _VALERIE_PARSER_H_
 
+/* MLT Header files */
+#include <framework/mlt.h>
+
 /* Application header files */
 #include "valerie_response.h"
 #include "valerie_notifier.h"
@@ -35,6 +38,7 @@ extern "C"
 
 typedef valerie_response (*parser_connect)( void * );
 typedef valerie_response (*parser_execute)( void *, char * );
+typedef valerie_response (*parser_push)( void *, char *, mlt_service );
 typedef void (*parser_close)( void * );
 
 /** Structure for the valerie parser.
@@ -44,6 +48,7 @@ typedef struct
 {
        parser_connect connect;
        parser_execute execute;
+       parser_push push;
        parser_close close;
        void *real;
        valerie_notifier notifier;
@@ -54,6 +59,7 @@ typedef struct
 */
 
 extern valerie_response valerie_parser_connect( valerie_parser );
+extern valerie_response valerie_parser_push( valerie_parser, char *, mlt_service );
 extern valerie_response valerie_parser_execute( valerie_parser, char * );
 extern valerie_response valerie_parser_executef( valerie_parser, char *, ... );
 extern valerie_response valerie_parser_run( valerie_parser, char * );
index 4b5023e5f3ba2b6d9d53d3881ee388c10657290e..f77003536dc4a2d3642f95ac416ae907aa9fb258 100644 (file)
@@ -27,6 +27,7 @@
 #include <pthread.h>
 
 /* Application header files */
+#include <framework/mlt.h>
 #include "valerie_remote.h"
 #include "valerie_socket.h"
 #include "valerie_tokeniser.h"
@@ -54,6 +55,7 @@ typedef struct
 
 static valerie_response valerie_remote_connect( valerie_remote );
 static valerie_response valerie_remote_execute( valerie_remote, char * );
+static valerie_response valerie_remote_push( valerie_remote, char *, mlt_service );
 static void valerie_remote_close( valerie_remote );
 static int valerie_remote_read_response( valerie_socket, valerie_response );
 
@@ -62,21 +64,19 @@ static int valerie_remote_read_response( valerie_socket, valerie_response );
 
 valerie_parser valerie_parser_init_remote( char *server, int port )
 {
-       valerie_parser parser = malloc( sizeof( valerie_parser_t ) );
-       valerie_remote remote = malloc( sizeof( valerie_remote_t ) );
+       valerie_parser parser = calloc( 1, sizeof( valerie_parser_t ) );
+       valerie_remote remote = calloc( 1, sizeof( valerie_remote_t ) );
 
        if ( parser != NULL )
        {
-               memset( parser, 0, sizeof( valerie_parser_t ) );
-
                parser->connect = (parser_connect)valerie_remote_connect;
                parser->execute = (parser_execute)valerie_remote_execute;
+               parser->push = (parser_push)valerie_remote_push;
                parser->close = (parser_close)valerie_remote_close;
                parser->real = remote;
 
                if ( remote != NULL )
                {
-                       memset( remote, 0, sizeof( valerie_remote_t ) );
                        remote->parser = parser;
                        remote->server = strdup( server );
                        remote->port = port;
@@ -194,6 +194,37 @@ static valerie_response valerie_remote_execute( valerie_remote remote, char *com
        return response;
 }
 
+/** Push a producer to the server.
+*/
+
+static valerie_response valerie_remote_push( valerie_remote remote, char *command, mlt_service service )
+{
+       valerie_response response = NULL;
+       pthread_mutex_lock( &remote->mutex );
+       if ( valerie_socket_write_data( remote->socket, command, strlen( command ) ) == strlen( command ) )
+       {
+               mlt_consumer consumer = mlt_factory_consumer( "westley", "buffer" );
+               mlt_properties properties = mlt_consumer_properties( consumer );
+               char temp[ 20 ];
+               char *buffer = NULL;
+               int length = 0;
+               mlt_consumer_connect( consumer, service );
+               response = valerie_response_init( );
+               valerie_socket_write_data( remote->socket, "\r\n", 2 );
+               mlt_consumer_start( consumer );
+               buffer = mlt_properties_get_data( properties, "buffer", &length );
+               sprintf( temp, "%d", length );
+               valerie_socket_write_data( remote->socket, temp, strlen( temp ) );
+               valerie_socket_write_data( remote->socket, "\r\n", 2 );
+               valerie_socket_write_data( remote->socket, buffer, length );
+               valerie_socket_write_data( remote->socket, "\r\n", 2 );
+               valerie_remote_read_response( remote->socket, response );
+               mlt_consumer_close( consumer );
+       }
+       pthread_mutex_unlock( &remote->mutex );
+       return response;
+}
+
 /** Disconnect.
 */
 
@@ -201,7 +232,8 @@ static void valerie_remote_disconnect( valerie_remote remote )
 {
        if ( remote != NULL && remote->terminated )
        {
-               pthread_join( remote->thread, NULL );
+               if ( remote->connected )
+                       pthread_join( remote->thread, NULL );
                valerie_socket_close( remote->status );
                valerie_socket_close( remote->socket );
                remote->connected = 0;