some bugfixes, filter_shape producer, pixbuf takes svg xml, fezzik can take a service...
authorddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 3 Mar 2004 05:31:01 +0000 (05:31 +0000)
committerddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 3 Mar 2004 05:31:01 +0000 (05:31 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@183 d19143bc-622f-0410-bfdd-b5b2a6649095

src/framework/mlt_frame.c
src/modules/core/filter_region.c
src/modules/core/transition_composite.c
src/modules/fezzik/producer_fezzik.c
src/modules/gtk2/producer_pixbuf.c
src/modules/westley/producer_westley.c

index 3221f40..d5a1252 100644 (file)
@@ -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;
 }
 
index d45d621..8e11f37 100644 (file)
@@ -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", "<svg width='100' height='100'><circle cx='50' cy='50' r='50' fill='black'/></svg>" );
+                       }
+
+                       // 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, &region_width, &region_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 );
        }
index df7fab1..d9c1bf4 100644 (file)
@@ -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;
index 3147512..bcc801c 100644 (file)
@@ -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;
 }
 
index cd32429..5e341fe 100644 (file)
@@ -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, "<svg" ) )
+               {
+                       // Generate a temporary file for the svg
+                       char fullname[ 1024 ] = "/tmp/mlt.XXXXXX";
+                       int fd = mkstemp( fullname );
+
+                       if ( fd > -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 );
 }
 
index 808d5ad..f7dd080 100644 (file)
@@ -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 );