From 6159bd78fa8e72c784747776a2c4c63d9c461ff5 Mon Sep 17 00:00:00 2001 From: lilo_booter Date: Fri, 13 Feb 2004 15:29:34 +0000 Subject: [PATCH] Defaults for PAL/NTSC on producers and consumers git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@145 d19143bc-622f-0410-bfdd-b5b2a6649095 --- docs/testing-20040110.txt | 1 - src/framework/mlt_consumer.c | 99 +++++++++++++++++++++++++++++- src/framework/mlt_consumer.h | 1 + src/framework/mlt_frame.c | 24 +++++++- src/framework/mlt_producer.c | 8 ++- src/modules/avformat/producer_avformat.c | 14 +++- src/modules/dv/consumer_libdv.c | 30 +++------ src/modules/dv/producer_libdv.c | 31 +++++++--- src/modules/gtk2/producer_pango.c | 10 ++- src/modules/gtk2/producer_pixbuf.c | 1 - src/modules/sdl/consumer_sdl.c | 36 +++-------- src/modules/westley/consumer_westley.c | 3 - 12 files changed, 188 insertions(+), 70 deletions(-) diff --git a/docs/testing-20040110.txt b/docs/testing-20040110.txt index 622300b..f1d7360 100644 --- a/docs/testing-20040110.txt +++ b/docs/testing-20040110.txt @@ -15,7 +15,6 @@ Not Implemented NLS USET points=ignore USET eof=terminate -XFER Incorrect Behaviour diff --git a/src/framework/mlt_consumer.c b/src/framework/mlt_consumer.c index 6c751aa..f0e21e3 100644 --- a/src/framework/mlt_consumer.c +++ b/src/framework/mlt_consumer.c @@ -20,6 +20,9 @@ #include "config.h" #include "mlt_consumer.h" +#include "mlt_factory.h" +#include "mlt_producer.h" +#include "mlt_frame.h" #include #include #include @@ -29,9 +32,38 @@ int mlt_consumer_init( mlt_consumer this, void *child ) { + int error = 0; memset( this, 0, sizeof( struct mlt_consumer_s ) ); this->child = child; - return mlt_service_init( &this->parent, this ); + error = mlt_service_init( &this->parent, this ); + if ( error == 0 ) + { + // Get the properties from the service + mlt_properties properties = mlt_service_properties( &this->parent ); + + // Get the normalisation preference + char *normalisation = getenv( "MLT_NORMALISATION" ); + + // Deal with normalisation + if ( normalisation == NULL || strcmp( normalisation, "NTSC" ) ) + { + mlt_properties_set( properties, "normalisation", "PAL" ); + mlt_properties_set_double( properties, "fps", 25.0 ); + mlt_properties_set_int( properties, "width", 720 ); + mlt_properties_set_int( properties, "height", 576 ); + } + else + { + mlt_properties_set( properties, "normalisation", "NTSC" ); + mlt_properties_set_double( properties, "fps", 30000.0 / 1001.0 ); + mlt_properties_set_int( properties, "width", 720 ); + mlt_properties_set_int( properties, "height", 480 ); + } + + // Default rescaler for all consumers + mlt_properties_set( properties, "rescale", "bilinear" ); + } + return error; } /** Get the parent service object. @@ -63,11 +95,68 @@ int mlt_consumer_connect( mlt_consumer this, mlt_service producer ) int mlt_consumer_start( mlt_consumer this ) { + // Get the properies + mlt_properties properties = mlt_consumer_properties( this ); + + // Determine if there's a test card producer + char *test_card = mlt_properties_get( properties, "test_card" ); + + // Deal with it now. + if ( test_card != NULL ) + { + // Create a test card producer + mlt_producer producer = mlt_factory_producer( "fezzik", test_card ); + + // Do we have a producer + if ( producer != NULL ) + { + // Set the test card on the consumer + mlt_properties_set_data( properties, "test_card_producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); + } + } + + // Start the service if ( this->start != NULL ) return this->start( this ); + return 0; } +/** Protected method :-/ for consumer to get frames from connected service +*/ + +mlt_frame mlt_consumer_get_frame( mlt_consumer this ) +{ + // Frame to return + mlt_frame frame = NULL; + + // Get the service assoicated to the consumer + mlt_service service = mlt_consumer_service( this ); + + // Get the frame + if ( mlt_service_get_frame( service, &frame, 0 ) == 0 ) + { + // Get the consumer properties + mlt_properties properties = mlt_consumer_properties( this ); + + // Get the frame properties + mlt_properties frame_properties = mlt_frame_properties( frame ); + + // Attach the test frame producer to it. + mlt_producer test_card = mlt_properties_get_data( properties, "test_card_producer", NULL ); + mlt_properties_set_data( frame_properties, "test_card_producer", test_card, 0, NULL, NULL ); + + // Attach the rescale property + if ( mlt_properties_get( properties, "rescale" ) != NULL ) + mlt_properties_set( frame_properties, "rescale.interp", mlt_properties_get( properties, "rescale" ) ); + + // TODO: Aspect ratio and other jiggery pokery + } + + // Return the frame + return frame; +} + /** Stop the consumer. */ @@ -83,8 +172,16 @@ int mlt_consumer_stop( mlt_consumer this ) int mlt_consumer_is_stopped( mlt_consumer this ) { + // Get the properies + mlt_properties properties = mlt_consumer_properties( this ); + + // Stop the consumer if ( this->is_stopped != NULL ) return this->is_stopped( this ); + + // Kill the test card + mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL ); + return 0; } diff --git a/src/framework/mlt_consumer.h b/src/framework/mlt_consumer.h index 6c4164b..5dce836 100644 --- a/src/framework/mlt_consumer.h +++ b/src/framework/mlt_consumer.h @@ -50,6 +50,7 @@ extern mlt_service mlt_consumer_service( mlt_consumer this ); extern mlt_properties mlt_consumer_properties( mlt_consumer this ); extern int mlt_consumer_connect( mlt_consumer this, mlt_service producer ); extern int mlt_consumer_start( mlt_consumer this ); +extern mlt_frame mlt_consumer_get_frame( mlt_consumer this ); extern int mlt_consumer_stop( mlt_consumer this ); extern int mlt_consumer_is_stopped( mlt_consumer this ); extern void mlt_consumer_close( mlt_consumer ); diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 7e661fe..3b5c556 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -20,6 +20,7 @@ #include "config.h" #include "mlt_frame.h" +#include "mlt_producer.h" #include #include #include @@ -154,6 +155,7 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for { mlt_properties properties = mlt_frame_properties( this ); mlt_get_image get_image = mlt_frame_pop_get_image( this ); + mlt_producer producer = mlt_properties_get_data( properties, "test_card_producer", NULL ); if ( get_image != NULL ) { @@ -166,6 +168,26 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for *width = mlt_properties_get_int( properties, "width" ); *height = mlt_properties_get_int( properties, "height" ); } + else if ( producer != NULL ) + { + mlt_frame test_frame = NULL; + mlt_service_get_frame( mlt_producer_service( producer ), &test_frame, 0 ); + if ( test_frame != NULL ) + { + mlt_frame_get_image( test_frame, buffer, format, width, height, writable ); + mlt_properties_inherit( mlt_frame_properties( this ), mlt_frame_properties( test_frame ) ); + mlt_properties_set_data( properties, "test_card_frame", test_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); + + mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL ); + mlt_properties_set_int( properties, "width", *width ); + mlt_properties_set_int( properties, "height", *height ); + } + else + { + mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL ); + mlt_frame_get_image( this, buffer, format, width, height, writable ); + } + } else { uint8_t *p; @@ -211,7 +233,7 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for case mlt_image_yuv420p: size = size * 3 / 2; *buffer = malloc( size ); - if ( *buffer ) + if ( *buffer ) memset( *buffer, 255, size ); break; } diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index 6441155..55cd06a 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -51,6 +51,9 @@ int mlt_producer_init( mlt_producer this, void *child ) // Initialise the service if ( mlt_service_init( &this->parent, this ) == 0 ) { + // Get the normalisation preference + char *normalisation = getenv( "MLT_NORMALISATION" ); + // The parent is the service mlt_service parent = &this->parent; @@ -61,7 +64,10 @@ int mlt_producer_init( mlt_producer this, void *child ) mlt_properties_set( properties, "mlt_type", "mlt_producer" ); mlt_properties_set_position( properties, "_position", 0.0 ); mlt_properties_set_double( properties, "_frame", 0 ); - mlt_properties_set_double( properties, "fps", 25.0 ); + if ( normalisation == NULL || strcmp( normalisation, "NTSC" ) ) + mlt_properties_set_double( properties, "fps", 25.0 ); + else + mlt_properties_set_double( properties, "fps", 30000.0 / 1001.0 ); mlt_properties_set_double( properties, "_speed", 1.0 ); mlt_properties_set_position( properties, "in", 0 ); mlt_properties_set_position( properties, "out", 1799999 ); diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index d5e6c7e..3186007 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -469,14 +469,14 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame ) // Get the video_index int index = mlt_properties_get_int( properties, "video_index" ); + // Get the frame properties + mlt_properties frame_properties = mlt_frame_properties( frame ); + // Lock the mutex now pthread_mutex_lock( &avformat_mutex ); if ( context != NULL && index != -1 ) { - // Get the frame properties - mlt_properties frame_properties = mlt_frame_properties( frame ); - // Get the video stream AVStream *stream = context->streams[ index ]; @@ -527,6 +527,14 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame ) mlt_frame_push_get_image( frame, producer_get_image ); mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL ); } + else + { + mlt_properties_set_int( frame_properties, "test_image", 1 ); + } + } + else + { + mlt_properties_set_int( frame_properties, "test_image", 1 ); } // Unlock the mutex now diff --git a/src/modules/dv/consumer_libdv.c b/src/modules/dv/consumer_libdv.c index 3d6f6f1..3b57638 100644 --- a/src/modules/dv/consumer_libdv.c +++ b/src/modules/dv/consumer_libdv.c @@ -60,11 +60,9 @@ mlt_consumer consumer_libdv_init( char *arg ) // Assign close callback this->close = consumer_close; - // Interpret the constructor argument - if ( arg == NULL || !strcmp( arg, "PAL" ) ) - mlt_properties_set_double( properties, "fps", 25 ); - else - mlt_properties_set_double( properties, "fps", 29.97 ); + // Interpret the argument + if ( arg != NULL ) + mlt_properties_set( properties, "target", arg ); // Set the encode and output handling method mlt_properties_set_data( properties, "video", consumer_encode_video, 0, NULL, NULL ); @@ -132,6 +130,10 @@ static int consumer_stop( mlt_consumer this ) // Wait for termination pthread_join( *thread, NULL ); + + // Close the output file :-) - this is obtuse - doesn't matter if output file + // exists or not - the destructor will kick in if it does + mlt_properties_set_data( properties, "output_file", NULL, 0, NULL, NULL ); } return 0; @@ -176,10 +178,6 @@ static dv_encoder_t *libdv_get_encoder( mlt_consumer this, mlt_frame frame ) // Store the encoder on the properties mlt_properties_set_data( this_properties, "dv_encoder", encoder, 0, ( mlt_destructor )dv_encoder_free, NULL ); - - // Convenience for image dimensions - mlt_properties_set_int( this_properties, "width", 720 ); - mlt_properties_set_int( this_properties, "height", fps == 25 ? 576 : 480 ); } // Return the encoder @@ -211,9 +209,6 @@ static int consumer_encode_video( mlt_consumer this, uint8_t *dv_frame, mlt_fram uint8_t *image = NULL; int is_test = 0; - if ( mlt_properties_get( this_properties, "rescale" ) != NULL ) - mlt_properties_set( mlt_frame_properties( frame ), "rescale.interp", mlt_properties_get( this_properties, "rescale" ) ); - // Get the image mlt_frame_get_image( frame, &image, &fmt, &width, &height, 0 ); @@ -374,17 +369,14 @@ static void *consumer_thread( void *arg ) // Allocate a single PAL frame for encoding uint8_t *dv_frame = malloc( frame_size_625_50 ); - // Get the service associated to the consumer - mlt_service service = mlt_consumer_service( this ); - - // Define a frame pointer - mlt_frame frame; - // Loop while running while( mlt_properties_get_int( properties, "running" ) ) { // Get the frame - if ( mlt_service_get_frame( service, &frame, 0 ) == 0 ) + mlt_frame frame = mlt_consumer_get_frame( this ); + + // Check that we have a frame to work with + if ( frame != NULL ) { // Obtain the dv_encoder if ( libdv_get_encoder( this, frame ) != NULL ) diff --git a/src/modules/dv/producer_libdv.c b/src/modules/dv/producer_libdv.c index 3da5de3..5f9e962 100644 --- a/src/modules/dv/producer_libdv.c +++ b/src/modules/dv/producer_libdv.c @@ -70,10 +70,19 @@ mlt_producer producer_libdv_init( char *filename ) // Open the file if specified this->fd = open( filename, O_RDONLY ); - producer_collect_info( this ); - // Set the resource property (required for all producers) - mlt_properties_set( properties, "resource", filename ); + // Collect info + if ( this->fd != -1 && producer_collect_info( this ) ) + { + // Set the resource property (required for all producers) + mlt_properties_set( properties, "resource", filename ); + } + else + { + // Reject this file + mlt_producer_close( producer ); + producer = NULL; + } // Return the producer return producer; @@ -130,10 +139,16 @@ static int producer_collect_info( producer_libdv this ) // Calculate default in/out points double fps = this->is_pal ? 25 : 30000.0 / 1001.0; - mlt_properties_set_double( properties, "fps", fps ); - mlt_properties_set_position( properties, "length", this->frames_in_file ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", this->frames_in_file - 1 ); + if ( mlt_properties_get_double( properties, "fps" ) == fps ) + { + mlt_properties_set_position( properties, "length", this->frames_in_file ); + mlt_properties_set_position( properties, "in", 0 ); + mlt_properties_set_position( properties, "out", this->frames_in_file - 1 ); + } + else + { + valid = 0; + } // Parse the header for meta info dv_parse_header( this->dv_decoder, dv_data ); @@ -321,7 +336,7 @@ static void producer_close( mlt_producer parent ) //dv_decoder_free( this->dv_decoder ); // Close the file - if ( this->fd != 0 ) + if ( this->fd > 0 ) close( this->fd ); // Close the parent diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c index 90d6818..c293d86 100644 --- a/src/modules/gtk2/producer_pango.c +++ b/src/modules/gtk2/producer_pango.c @@ -72,7 +72,6 @@ mlt_producer producer_pango_init( const char *filename ) mlt_properties properties = mlt_producer_properties( &this->parent ); // Set the default properties - mlt_properties_set_int( properties, "video_standard", mlt_video_standard_pal ); mlt_properties_set( properties, "fgcolour", "0xffffffff" ); mlt_properties_set( properties, "bgcolour", "0x00000000" ); mlt_properties_set_int( properties, "align", pango_align_left ); @@ -85,15 +84,18 @@ mlt_producer producer_pango_init( const char *filename ) mlt_properties_set( properties, "resource", "pango" ); mlt_properties_set( properties, "markup", "" ); } - else if ( filename[ 0 ] == '+' ) + else if ( filename[ 0 ] == '+' || strstr( filename, "/+" ) ) { - char *markup = strdup( filename + 1 ); + char *copy = strdup( filename + 1 ); + char *markup = copy; + if ( strstr( markup, "/+" ) ) + markup = strstr( markup, "/+" ) + 2; ( *strrchr( markup, '.' ) ) = '\0'; while ( strchr( markup, '~' ) ) ( *strchr( markup, '~' ) ) = '\n'; mlt_properties_set( properties, "resource", ( char * )filename ); mlt_properties_set( properties, "markup", markup ); - free( markup ); + free( copy ); } else { diff --git a/src/modules/gtk2/producer_pixbuf.c b/src/modules/gtk2/producer_pixbuf.c index 699550d..63817f7 100644 --- a/src/modules/gtk2/producer_pixbuf.c +++ b/src/modules/gtk2/producer_pixbuf.c @@ -64,7 +64,6 @@ mlt_producer producer_pixbuf_init( char *filename ) // Set the default properties mlt_properties_set( properties, "resource", filename ); - mlt_properties_set_int( properties, "video_standard", mlt_video_standard_pal ); mlt_properties_set_int( properties, "ttl", 25 ); // Obtain filenames diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index 3d4f531..1c82193 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -98,28 +98,14 @@ mlt_consumer consumer_sdl_init( char *arg ) pthread_mutex_init( &this->audio_mutex, NULL ); pthread_cond_init( &this->audio_cond, NULL); - // Default fps - mlt_properties_set_double( this->properties, "fps", 25 ); - // Default scaler (for now we'll use nearest) mlt_properties_set( this->properties, "rescale", "nearest" ); // process actual param - if ( arg == NULL || !strcmp( arg, "PAL" ) ) - { - this->width = 720; - this->height = 576; - } - else if ( !strcmp( arg, "NTSC" ) ) - { - this->width = 720; - this->height = 480; - mlt_properties_set_double( this->properties, "fps", 29.97 ); - } - else if ( sscanf( arg, "%dx%d", &this->width, &this->height ) != 2 ) + if ( arg == NULL || sscanf( arg, "%dx%d", &this->width, &this->height ) != 2 ) { - this->width = 720; - this->height = 576; + this->width = mlt_properties_get_int( this->properties, "width" ); + this->height = mlt_properties_get_int( this->properties, "height" ); } // Default window size and aspect ratio @@ -345,9 +331,6 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame ) } this->queue[ this->count ++ ] = frame; - if ( mlt_properties_get( properties, "rescale" ) != NULL ) - mlt_properties_set( mlt_frame_properties( frame ), "rescale.interp", mlt_properties_get( properties, "rescale" ) ); - if ( this->playing ) { // We're working on the oldest frame now @@ -491,12 +474,6 @@ static void *consumer_thread( void *arg ) // Get the consumer mlt_consumer consumer = &this->parent; - // Get the service assoicated to the consumer - mlt_service service = mlt_consumer_service( consumer ); - - // Define a frame pointer - mlt_frame frame; - // internal intialization int init_audio = 1; @@ -509,8 +486,11 @@ static void *consumer_thread( void *arg ) // Loop until told not to while( this->running ) { - // Get a frame from the service (should never return anything other than 0) - if ( mlt_service_get_frame( service, &frame, 0 ) == 0 ) + // Get a frame from the attached producer + mlt_frame frame = mlt_consumer_get_frame( consumer ); + + // Ensure that we have a frame + if ( frame != NULL ) { init_audio = consumer_play_audio( this, frame, init_audio ); consumer_play_video( this, frame ); diff --git a/src/modules/westley/consumer_westley.c b/src/modules/westley/consumer_westley.c index c1e68c1..2d7d83c 100644 --- a/src/modules/westley/consumer_westley.c +++ b/src/modules/westley/consumer_westley.c @@ -46,9 +46,6 @@ mlt_consumer consumer_westley_init( char *arg ) // If no malloc'd and consumer init ok if ( this != NULL && mlt_consumer_init( this, NULL ) == 0 ) { - // We have stuff to clean up, so override the close method - //parent->close = consumer_close; - // Allow thread to be started/stopped this->start = consumer_start; this->is_stopped = consumer_is_stopped; -- 1.7.4.4