From d7ae73d25cf5a38a3a8153ae52409fcbef16bb22 Mon Sep 17 00:00:00 2001 From: ddennedy Date: Wed, 3 Mar 2004 05:31:01 +0000 Subject: [PATCH] some bugfixes, filter_shape producer, pixbuf takes svg xml, fezzik can take a service name git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@183 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/framework/mlt_frame.c | 96 ++++---------------- src/modules/core/filter_region.c | 106 ++++++++++++++++++++- src/modules/core/transition_composite.c | 20 ++--- src/modules/fezzik/producer_fezzik.c | 4 + src/modules/gtk2/producer_pixbuf.c | 156 +++++++++++++++++++------------ src/modules/westley/producer_westley.c | 3 +- 6 files changed, 226 insertions(+), 159 deletions(-) diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 3221f40..d5a1252 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -259,7 +259,7 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for q = p + size; while ( p != NULL && p != q ) { - *p ++ = 255; + *p ++ = 235; *p ++ = 128; } break; @@ -326,12 +326,12 @@ void mlt_frame_close( mlt_frame this ) y = (306*r + 601*g + 117*b) >> 10;\ u = ((-172*r - 340*g + 512*b) >> 10) + 128;\ v = ((512*r - 429*g - 83*b) >> 10) + 128;\ - y = y < 0 ? 0 : y;\ - u = u < 0 ? 0 : u;\ - v = v < 0 ? 0 : v;\ - y = y > 255 ? 255 : y;\ - u = u > 255 ? 255 : u;\ - v = v > 255 ? 255 : v + y = y < 16 ? 16 : y;\ + u = u < 16 ? 16 : u;\ + v = v < 16 ? 16 : v;\ + y = y > 235 ? 235 : y;\ + u = u > 240 ? 240 : u;\ + v = v > 240 ? 240 : v int mlt_convert_rgb24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha ) { @@ -483,7 +483,7 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input elements = blank_elements; while ( elements -- ) { - *out_line ++ = 0; + *out_line ++ = 16; *out_line ++ = 128; } @@ -500,7 +500,7 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input elements = inactive_width; while ( elements -- ) { - *out_ptr ++ = 0; + *out_ptr ++ = 16; *out_ptr ++ = 128; } @@ -512,7 +512,7 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input elements = inactive_width; while ( elements -- ) { - *out_ptr ++ = 0; + *out_ptr ++ = 16; *out_ptr ++ = 128; } @@ -527,7 +527,7 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input elements = blank_elements; while ( elements -- ) { - *out_line ++ = 0; + *out_line ++ = 16; *out_line ++ = 128; } } @@ -663,22 +663,18 @@ uint8_t *mlt_frame_rescale_yuv422( mlt_frame this, int owidth, int oheight ) int mlt_frame_mix_audio( mlt_frame this, mlt_frame that, float weight_start, float weight_end, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) { int ret = 0; - int16_t *p_src, *p_dest; int16_t *src, *dest; - //static int16_t *extra_src = NULL, *extra_dest = NULL; - static int extra_src_samples = 0, extra_dest_samples = 0; int frequency_src = *frequency, frequency_dest = *frequency; int channels_src = *channels, channels_dest = *channels; int samples_src = *samples, samples_dest = *samples; int i, j; double d = 0, s = 0; - mlt_frame_get_audio( this, &p_dest, format, &frequency_dest, &channels_dest, &samples_dest ); + mlt_frame_get_audio( this, &dest, format, &frequency_dest, &channels_dest, &samples_dest ); //fprintf( stderr, "mix: frame dest samples %d channels %d position %lld\n", samples_dest, channels_dest, mlt_properties_get_position( mlt_frame_properties( this ), "_position" ) ); - mlt_frame_get_audio( that, &p_src, format, &frequency_src, &channels_src, &samples_src ); + mlt_frame_get_audio( that, &src, format, &frequency_src, &channels_src, &samples_src ); //fprintf( stderr, "mix: frame src samples %d channels %d\n", samples_src, channels_src ); - src = p_src; - dest = p_dest; + if ( channels_src > 6 ) channels_src = 0; if ( channels_dest > 6 ) @@ -688,34 +684,10 @@ int mlt_frame_mix_audio( mlt_frame this, mlt_frame that, float weight_start, flo if ( samples_dest > 4000 ) samples_dest = 0; -#if 0 - // Append new samples to leftovers - if ( extra_dest_samples > 0 ) - { - fprintf( stderr, "prepending %d samples to dest\n", extra_dest_samples ); - dest = realloc( extra_dest, ( samples_dest + extra_dest_samples ) * 2 * channels_dest ); - memcpy( &extra_dest[ extra_dest_samples * channels_dest ], p_dest, samples_dest * 2 * channels_dest ); - } - else - dest = p_dest; - if ( extra_src_samples > 0 ) - { - fprintf( stderr, "prepending %d samples to src\n", extra_src_samples ); - src = realloc( extra_src, ( samples_src + extra_src_samples ) * 2 * channels_src ); - memcpy( &extra_src[ extra_src_samples * channels_src ], p_src, samples_src * 2 * channels_src ); - } - else - src = p_src; -#endif - - // determine number of samples to process - if ( samples_src + extra_src_samples < samples_dest + extra_dest_samples ) - *samples = samples_src + extra_src_samples; - else if ( samples_dest + extra_dest_samples < samples_src + extra_src_samples ) - *samples = samples_dest + extra_dest_samples; - + // determine number of samples to process + *samples = samples_src < samples_dest ? samples_src : samples_dest; *channels = channels_src < channels_dest ? channels_src : channels_dest; - *buffer = p_dest; + *buffer = dest; *frequency = frequency_dest; // Compute a smooth ramp over start to end @@ -736,40 +708,6 @@ int mlt_frame_mix_audio( mlt_frame this, mlt_frame that, float weight_start, flo weight += weight_step; } - // We have to copy --sigh - if ( dest != p_dest ) - memcpy( p_dest, dest, *samples * 2 * *channels ); - -#if 0 - // Store the leftovers - if ( samples_src + extra_src_samples < samples_dest + extra_dest_samples ) - { - extra_dest_samples = ( samples_dest + extra_dest_samples ) - ( samples_src + extra_src_samples ); - size_t size = extra_dest_samples * 2 * channels_dest; - fprintf( stderr, "storing %d samples from dest\n", extra_dest_samples ); - if ( extra_dest ) - free( extra_dest ); - extra_dest = malloc( size ); - if ( extra_dest ) - memcpy( extra_dest, &p_dest[ ( samples_dest - extra_dest_samples - 1 ) * channels_dest ], size ); - else - extra_dest_samples = 0; - } - else if ( samples_dest + extra_dest_samples < samples_src + extra_src_samples ) - { - extra_src_samples = ( samples_src + extra_src_samples ) - ( samples_dest + extra_dest_samples ); - size_t size = extra_src_samples * 2 * channels_src; - fprintf( stderr, "storing %d samples from src\n", extra_dest_samples ); - if ( extra_src ) - free( extra_src ); - extra_src = malloc( size ); - if ( extra_src ) - memcpy( extra_src, &p_src[ ( samples_src - extra_src_samples - 1 ) * channels_src ], size ); - else - extra_src_samples = 0; - } -#endif - return ret; } diff --git a/src/modules/core/filter_region.c b/src/modules/core/filter_region.c index d45d621..8e11f37 100644 --- a/src/modules/core/filter_region.c +++ b/src/modules/core/filter_region.c @@ -85,6 +85,15 @@ static int create_instance( mlt_filter this, char *name, char *value, int count return error; } +static uint8_t *filter_get_alpha_mask( mlt_frame this ) +{ + // Obtain properties of frame + mlt_properties properties = mlt_frame_properties( this ); + + // Return the alpha mask + return mlt_properties_get_data( properties, "alpha", NULL ); +} + /** Do it :-). */ @@ -188,11 +197,98 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // Get the b frame and process with composite if successful mlt_transition_process( composite, frame, b_frame ); - // Get the image - error = mlt_frame_get_image( frame, image, format, width, height, 0 ); + // See if we have a shape producer + // Copy the alpha mask from the shape frame to the b_frame + char *resource = mlt_properties_get( properties, "resource" ); + + if ( strcmp( resource, "rectangle" ) != 0 ) + { + if ( strcmp( resource, "circle" ) == 0 ) + { + resource = strdup( "pixbuf" ); + mlt_properties_set( properties, "producer.resource", "" ); + } + + // Get the producer from the filter + mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); + + if ( producer == NULL ) + { + // Get the factory producer service + char *factory = mlt_properties_get( properties, "factory" ); + + // Create the producer + producer = mlt_factory_producer( factory, resource ); - // Close the b frame - mlt_frame_close( b_frame ); + // If we have one + if ( producer != NULL ) + { + // Get the producer properties + mlt_properties producer_properties = mlt_producer_properties( producer ); + + // Ensure that we loop + mlt_properties_set( producer_properties, "eof", "loop" ); + + // Now pass all producer. properties on the filter down + mlt_properties_pass( producer_properties, properties, "producer." ); + + // Register the producer for reuse/destruction + mlt_properties_set_data( properties, "producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); + } + } + + if ( producer != NULL ) + { + // We will get the alpha frame from the producer + mlt_frame shape_frame = NULL; + + // Get the unique id of the filter (used to reacquire the producer position) + char *name = mlt_properties_get( properties, "_unique_id" ); + + // Get the original producer position + mlt_position position = mlt_properties_get_position( mlt_frame_properties( frame ), name ); + + // Make sure the producer is in the correct position + mlt_producer_seek( producer, position ); + + // Get the shape frame + if ( mlt_service_get_frame( mlt_producer_service( producer ), &shape_frame, 0 ) == 0 ) + { + int region_width = mlt_properties_get_int( mlt_frame_properties( b_frame ), "width" ); + int region_height = mlt_properties_get_int( mlt_frame_properties( b_frame ), "height" ); + + // Get the shape image to trigger alpha creation + mlt_properties_set( mlt_frame_properties( shape_frame ), "distort", "true" ); + error = mlt_frame_get_image( shape_frame, image, format, ®ion_width, ®ion_height, 1 ); + + // Only override any existing b_frame alpha if the shape has an alpha + if ( mlt_frame_get_alpha_mask( shape_frame ) != NULL ) + { + // Set the b_frame alpha from the shape frame + mlt_properties_set_data( mlt_frame_properties( b_frame ), "alpha", mlt_frame_get_alpha_mask( shape_frame ), 0 , NULL, NULL ); + b_frame->get_alpha_mask = filter_get_alpha_mask; + } + + // Get the image + error = mlt_frame_get_image( frame, image, format, width, height, 0 ); + + // Close the b frame + mlt_frame_close( b_frame ); + b_frame = NULL; + + // Close the shape frame + mlt_frame_close( shape_frame ); + } + } + } + if ( b_frame != NULL ) + { + // Get the image + error = mlt_frame_get_image( frame, image, format, width, height, 0 ); + + // Close the b frame + mlt_frame_close( b_frame ); + } } return error; @@ -230,6 +326,8 @@ mlt_filter filter_region_init( void *arg ) // Assign the filter process method this->process = filter_process; + mlt_properties_set( properties, "factory", "fezzik" ); + // Resource defines the shape of the region mlt_properties_set( properties, "resource", arg == NULL ? "rectangle" : arg ); } diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index df7fab1..d9c1bf4 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -152,8 +152,6 @@ static void geometry_calculate( struct geometry_s *output, struct geometry_s *in output->y = in->y + ( out->y - in->y ) * position; output->w = in->w + ( out->w - in->w ) * position; output->h = in->h + ( out->h - in->h ) * position; - output->sw = output->w; - output->sh = output->h; output->mix = in->mix + ( out->mix - in->mix ) * position; output->distort = in->distort; @@ -499,6 +497,11 @@ static int get_b_frame_image( mlt_transition this, mlt_frame b_frame, uint8_t ** geometry->sw = scaled_width; geometry->sh = scaled_height; } + else + { + geometry->sw = geometry->w; + geometry->sh = geometry->h; + } // We want to ensure that we bypass resize now... mlt_properties_set( b_props, "distort", "true" ); @@ -527,15 +530,6 @@ static int get_b_frame_image( mlt_transition this, mlt_frame b_frame, uint8_t ** } -static uint8_t *transition_get_alpha_mask( mlt_frame this ) -{ - // Obtain properties of frame - mlt_properties properties = mlt_frame_properties( this ); - - // Return the alpha mask - return mlt_properties_get_data( properties, "alpha", NULL ); -} - struct geometry_s *composite_calculate( struct geometry_s *result, mlt_transition this, mlt_frame a_frame, float position ) { // Get the properties from the transition @@ -610,8 +604,8 @@ mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame ) // Need to scale down to actual dimensions x = result.x * width / result.nw ; y = result.y * height / result.nh; - w = result.sw * width / result.nw; - h = result.sh * height / result.nh; + w = result.w * width / result.nw; + h = result.h * height / result.nh; x &= 0xfffffffe; w &= 0xfffffffe; diff --git a/src/modules/fezzik/producer_fezzik.c b/src/modules/fezzik/producer_fezzik.c index 3147512..bcc801c 100644 --- a/src/modules/fezzik/producer_fezzik.c +++ b/src/modules/fezzik/producer_fezzik.c @@ -83,6 +83,10 @@ static mlt_producer create_producer( char *file ) if ( result == NULL ) result = mlt_factory_producer( "avformat", file ); + // 4th - allow explicit construction + if ( result == NULL ) + result = mlt_factory_producer( file, NULL ); + return result; } diff --git a/src/modules/gtk2/producer_pixbuf.c b/src/modules/gtk2/producer_pixbuf.c index cd32429..5e341fe 100644 --- a/src/modules/gtk2/producer_pixbuf.c +++ b/src/modules/gtk2/producer_pixbuf.c @@ -62,7 +62,7 @@ static int filter_files( const struct dirent *de ) mlt_producer producer_pixbuf_init( char *filename ) { producer_pixbuf this = calloc( sizeof( struct producer_pixbuf_s ), 1 ); - if ( filename != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) + if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) { mlt_producer producer = &this->parent; @@ -77,66 +77,6 @@ mlt_producer producer_pixbuf_init( char *filename ) mlt_properties_set( properties, "resource", filename ); mlt_properties_set_int( properties, "ttl", 25 ); - // Obtain filenames - if ( strchr( filename, '%' ) != NULL ) - { - // handle picture sequences - int i = 0; - int gap = 0; - char full[1024]; - - while ( gap < 100 ) - { - struct stat buf; - snprintf( full, 1023, filename, i ++ ); - if ( stat( full, &buf ) == 0 ) - { - this->filenames = realloc( this->filenames, sizeof( char * ) * ( this->count + 1 ) ); - this->filenames[ this->count ++ ] = strdup( full ); - gap = 0; - } - else - { - gap ++; - } - } - mlt_properties_set_position( properties, "out", this->count * 250 ); - } - else if ( strstr( filename, "/.all." ) != NULL ) - { - char *dir_name = strdup( filename ); - char *extension = strrchr( filename, '.' ); - *( strstr( dir_name, "/.all." ) + 1 ) = '\0'; - char fullname[ 1024 ]; - strcpy( fullname, dir_name ); - struct dirent **de = NULL; - int n = scandir( fullname, &de, filter_files, alphasort ); - int i; - struct stat info; - - for (i = 0; i < n; i++ ) - { - snprintf( fullname, 1023, "%s%s", dir_name, de[i]->d_name ); - - if ( lstat( fullname, &info ) == 0 && - ( S_ISREG( info.st_mode ) || ( strstr( fullname, extension ) && info.st_mode | S_IXUSR ) ) ) - { - this->filenames = realloc( this->filenames, sizeof( char * ) * ( this->count + 1 ) ); - this->filenames[ this->count ++ ] = strdup( fullname ); - } - free( de[ i ] ); - } - - free( de ); - free( dir_name ); - } - else - { - this->filenames = realloc( this->filenames, sizeof( char * ) * ( this->count + 1 ) ); - this->filenames[ this->count ++ ] = strdup( filename ); - mlt_properties_set_position( properties, "out", 250 ); - } - // Initialise gobject types g_type_init(); @@ -329,6 +269,95 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i // Get the real structure for this producer producer_pixbuf this = producer->child; + if ( this->count == 0 && mlt_properties_get( mlt_producer_properties( producer ), "resource" ) != NULL ) + { + mlt_properties properties = mlt_producer_properties( producer ); + char *filename = mlt_properties_get( properties, "resource" ); + + // Obtain filenames + if ( strchr( filename, '%' ) != NULL ) + { + // handle picture sequences + int i = 0; + int gap = 0; + char full[1024]; + + while ( gap < 100 ) + { + struct stat buf; + snprintf( full, 1023, filename, i ++ ); + if ( stat( full, &buf ) == 0 ) + { + this->filenames = realloc( this->filenames, sizeof( char * ) * ( this->count + 1 ) ); + this->filenames[ this->count ++ ] = strdup( full ); + gap = 0; + } + else + { + gap ++; + } + } + mlt_properties_set_position( properties, "out", this->count * 250 ); + } + else if ( strstr( filename, "/.all." ) != NULL ) + { + char *dir_name = strdup( filename ); + char *extension = strrchr( filename, '.' ); + *( strstr( dir_name, "/.all." ) + 1 ) = '\0'; + char fullname[ 1024 ]; + strcpy( fullname, dir_name ); + struct dirent **de = NULL; + int n = scandir( fullname, &de, filter_files, alphasort ); + int i; + struct stat info; + + for (i = 0; i < n; i++ ) + { + snprintf( fullname, 1023, "%s%s", dir_name, de[i]->d_name ); + + if ( lstat( fullname, &info ) == 0 && + ( S_ISREG( info.st_mode ) || ( strstr( fullname, extension ) && info.st_mode | S_IXUSR ) ) ) + { + this->filenames = realloc( this->filenames, sizeof( char * ) * ( this->count + 1 ) ); + this->filenames[ this->count ++ ] = strdup( fullname ); + } + free( de[ i ] ); + } + + free( de ); + free( dir_name ); + } + else if ( strstr( filename, " -1 ) + { + // Write the svg into the temp file + ssize_t remaining_bytes = strlen( filename ); + while ( remaining_bytes > 0 ) + remaining_bytes -= write( fd, filename + strlen( filename ) - remaining_bytes, remaining_bytes ); + close( fd ); + + this->filenames = realloc( this->filenames, sizeof( char * ) * ( this->count + 1 ) ); + this->filenames[ this->count ++ ] = strdup( fullname ); + + mlt_properties_set_position( properties, "out", 250 ); + + // Teehe - when the producer closes, delete the temp file and the space allo + mlt_properties_set_data( properties, "__temporary_file__", this->filenames[ this->count - 1 ], 0, ( mlt_destructor )unlink, NULL ); + } + } + else + { + this->filenames = realloc( this->filenames, sizeof( char * ) * ( this->count + 1 ) ); + this->filenames[ this->count ++ ] = strdup( filename ); + mlt_properties_set_position( properties, "out", 250 ); + } + } + // Generate a frame *frame = mlt_frame_init( ); @@ -372,6 +401,11 @@ static void producer_close( mlt_producer parent ) mlt_pool_release( this->image ); parent->close = NULL; mlt_producer_close( parent ); + while ( *this->filenames ) + { + free( *this->filenames ); + this->filenames++; + } free( this ); } diff --git a/src/modules/westley/producer_westley.c b/src/modules/westley/producer_westley.c index 808d5ad..f7dd080 100644 --- a/src/modules/westley/producer_westley.c +++ b/src/modules/westley/producer_westley.c @@ -391,8 +391,7 @@ static void on_end_producer( deserialise_context context, const xmlChar *name ) } if ( service == NULL && mlt_properties_get( properties, "mlt_service" ) != NULL ) { - service = MLT_SERVICE( mlt_factory_producer( mlt_properties_get( properties, "mlt_service" ), - mlt_properties_get( properties, "resource" ) ) ); + service = MLT_SERVICE( mlt_factory_producer( "fezzik", mlt_properties_get( properties, "mlt_service" ) ) ); } track_service( context->destructors, service, (mlt_destructor) mlt_producer_close ); -- 1.7.4.4