]> git.sesse.net Git - mlt/commitdiff
westley serialises with entry in/out; full field, aspect, and colour space normalisat...
authorddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Mon, 16 Feb 2004 17:03:54 +0000 (17:03 +0000)
committerddennedy <ddennedy@d19143bc-622f-0410-bfdd-b5b2a6649095>
Mon, 16 Feb 2004 17:03:54 +0000 (17:03 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@147 d19143bc-622f-0410-bfdd-b5b2a6649095

16 files changed:
src/framework/mlt_consumer.c
src/framework/mlt_frame.c
src/framework/mlt_producer.c
src/modules/avformat/producer_avformat.c
src/modules/core/filter_resize.c
src/modules/core/producer_ppm.c
src/modules/core/producer_ppm.h
src/modules/core/transition_composite.c
src/modules/core/transition_luma.c
src/modules/dv/producer_libdv.c
src/modules/ffmpeg/producer_ffmpeg.c
src/modules/gtk2/filter_rescale.c
src/modules/gtk2/producer_pango.c
src/modules/gtk2/producer_pixbuf.c
src/modules/sdl/consumer_sdl.c
src/modules/westley/consumer_westley.c

index 67578e6feda62dba530190a154386896fbd4971d..92a95fe18ce70f35a26c5ac7431a76f60a2a00e8 100644 (file)
@@ -51,6 +51,7 @@ int mlt_consumer_init( mlt_consumer this, void *child )
                        mlt_properties_set_double( properties, "fps", 25.0 );
                        mlt_properties_set_int( properties, "width", 720 );
                        mlt_properties_set_int( properties, "height", 576 );
+                       mlt_properties_set_int( properties, "progressive", 0 );
                }
                else
                {
@@ -58,7 +59,9 @@ int mlt_consumer_init( mlt_consumer this, void *child )
                        mlt_properties_set_double( properties, "fps", 30000.0 / 1001.0 );
                        mlt_properties_set_int( properties, "width", 720 );
                        mlt_properties_set_int( properties, "height", 480 );
+                       mlt_properties_set_int( properties, "progressive", 0 );
                }
+               mlt_properties_set_double( properties, "aspect_ratio", 4.0 / 3.0 );
 
                // Default rescaler for all consumers
                mlt_properties_set( properties, "rescale", "bilinear" );
@@ -105,6 +108,7 @@ int mlt_consumer_start( mlt_consumer this )
        if ( test_card != NULL )
        {
                // Create a test card producer
+               // TODO: do we want to use fezzik here?
                mlt_producer producer = mlt_factory_producer( "fezzik", test_card );
 
                // Do we have a producer
@@ -151,6 +155,8 @@ mlt_frame mlt_consumer_get_frame( mlt_consumer this )
                        mlt_properties_set( frame_properties, "rescale.interp", mlt_properties_get( properties, "rescale" ) );
 
                // TODO: Aspect ratio and other jiggery pokery
+               mlt_properties_set_double( frame_properties, "consumer_aspect_ratio", mlt_properties_get_double( properties, "aspect_ratio" ) );
+               
        }
 
        // Return the frame
index 3b5c556b5521cf82a4ba372b16aa2fedf22990f8..cbc80744d712c966ee76edc100199a7eb9bb04c5 100644 (file)
@@ -208,19 +208,25 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for
                                *buffer = NULL;
                                break;
                        case mlt_image_rgb24:
+                               // IRRIGATE ME
                                size *= 3;
+                               size += *width * 3;
                                *buffer = malloc( size );
                                if ( *buffer )
                                        memset( *buffer, 255, size );
                                break;
                        case mlt_image_rgb24a:
+                               // IRRIGATE ME
                                size *= 4;
+                               size += *width * 4;
                                *buffer = malloc( size );
                                if ( *buffer )
                                        memset( *buffer, 255, size );
                                break;
                        case mlt_image_yuv422:
+                               // IRRIGATE ME
                                size *= 2;
+                               size += *width * 2;
                                *buffer = malloc( size );
                                p = *buffer;
                                q = p + size;
@@ -511,21 +517,20 @@ uint8_t *mlt_frame_resize_yuv422( mlt_frame this, int owidth, int oheight )
        if ( iwidth != owidth || iheight != oheight )
        {
                // Create the output image
-               uint8_t *output = malloc( owidth * oheight * 2 );
+               // IRRIGATE ME
+               uint8_t *output = malloc( owidth * ( oheight + 1 ) * 2 );
 
                // Call the generic resize
                mlt_resize_yuv422( output, owidth, oheight, input, iwidth, iheight );
 
                // Now update the frame
-               mlt_properties_set_data( properties, "image", output, owidth * oheight * 2, free, NULL );
+               mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, free, NULL );
                mlt_properties_set_int( properties, "width", owidth );
                mlt_properties_set_int( properties, "height", oheight );
-               mlt_frame_set_aspect_ratio( this, 4.0/3.0/*( float )owidth / oheight*/ );
 
                // Return the output
                return output;
        }
-
        // No change, return input
        return input;
 }
@@ -548,7 +553,8 @@ uint8_t *mlt_frame_rescale_yuv422( mlt_frame this, int owidth, int oheight )
        if ( iwidth != owidth || iheight != oheight )
        {
                // Create the output image
-               uint8_t *output = malloc( owidth * oheight * 2 );
+               // IRRIGATE ME
+               uint8_t *output = malloc( owidth * ( oheight + 1 ) * 2 );
 
                // Calculate strides
                int istride = iwidth * 2;
index 55cd06aa71ac058050a8e46ac828921e90917114..c4508ba6bdb34bbaec63d76bc025ba9ce0f6ac2f 100644 (file)
@@ -255,8 +255,6 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind
        char *eof = mlt_properties_get( mlt_producer_properties( this ), "eof" );
 
        // A properly instatiated producer will have a get_frame method...
-//fprintf( stderr, "PRODUCER get_frame %p eof %s pos %lld out %lld\n",
-//this->get_frame, eof, mlt_producer_position( this ), mlt_producer_get_out( this ) );
        if ( this->get_frame == NULL || ( !strcmp( eof, "continue" ) && mlt_producer_position( this ) > mlt_producer_get_out( this ) ) )
        {
                // Generate a test frame
index 3186007c86e03ca56874014e30309d760d9777e8..6333c550f9aa5f4344a831521299b00c3ec33d56 100644 (file)
@@ -184,7 +184,9 @@ static int producer_open( mlt_producer this, char *file )
        pthread_mutex_lock( &avformat_mutex );
 
        // Now attempt to open the file
-       error = av_open_input_file( &context, file, NULL, 0, NULL ) < 0;
+       error = av_open_input_file( &context, file, NULL, 0, NULL );
+//     fprintf( stderr, "AVFORMAT: open %d %s\n", error, file );
+       error = error < 0;
 
        // If successful, then try to get additional info
        if ( error == 0 )
@@ -333,6 +335,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        if ( output == NULL )
        {
                int size = avpicture_get_size( PIX_FMT_YUV422, *width, *height );
+               // IRRIGATE ME
+               size += *width * 2;
                uint8_t *buf = malloc( size );
                output = malloc( sizeof( AVPicture ) );
                avpicture_fill( output, buf, PIX_FMT_YUV422, *width, *height );
@@ -373,6 +377,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                uint8_t *image = mlt_properties_get_data( properties, "current_image", &size );
 
                // Duplicate it
+               // IRRIGATE ME
                *buffer = malloc( size );
                memcpy( *buffer, image, size );
 
@@ -432,11 +437,13 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 
                        if ( image == NULL || size != *width * *height * 2 )
                        {
-                               size = *width * *height * 2;
+                               size = *width * ( *height + 1 ) * 2;
+                               // IRRIGATE ME
                                image = malloc( size );
                                mlt_properties_set_data( properties, "current_image", image, size, free, NULL );
                        }
 
+                       // IRRIGATE ME
                        *buffer = malloc( size );
                        img_convert( output, PIX_FMT_YUV422, (AVPicture *)&frame, codec_context->pix_fmt, *width, *height );
                        memcpy( image, output->data[ 0 ], size );
@@ -498,6 +505,7 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
                                double aspect_ratio = 0;
 
                                // Set aspect ratio
+                               fprintf( stderr, "AVFORMAT: sample aspect %d\n", codec_context->sample_aspect_ratio.num );
                                if ( codec_context->sample_aspect_ratio.num == 0) 
                                        aspect_ratio = 0;
                                else
index 537ce505aedfb64e9604b43e5017f04152cbe227..be1e23f8cbf867f7fcf236e8fe32621d5dd97319 100644 (file)
 
 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
 {
+       mlt_properties properties = mlt_frame_properties( this );
        int owidth = *width;
        int oheight = *height;
-       mlt_frame_get_image( this, image, format, &owidth, &oheight, 0 );
+       
+       mlt_frame_get_image( this, image, format, &owidth, &oheight, writable );
+       
        if ( *width == 0 )
                *width = 720;
        if ( *height == 0 )
                *height = 576;
-       if ( !strcmp( mlt_properties_get( mlt_frame_properties( this ), "resize.scale" ), "affine" ) )
+               
+       // Correct field order if needed
+       if ( mlt_properties_get_int( properties, "top_field_first" ) == 1 )
+       {
+               // Get the input image, width and height
+               int size;
+               uint8_t *image = mlt_properties_get_data( properties, "image", &size );
+
+               // Keep the original image around to be destroyed on frame close
+               mlt_properties_rename( properties, "image", "original_image" );
+
+               // Offset the image pointer by one line
+               image += owidth * 2;
+               size -= owidth * 2;
+
+               // Set the new image pointer with no destructor
+               mlt_properties_set_data( properties, "image", image, size, NULL, NULL );
+
+               // Set the normalised field order
+               mlt_properties_set_int( properties, "top_field_first", 0 );
+       }
+
+       if ( !strcmp( mlt_properties_get( properties, "resize.scale" ), "affine" ) )
                *image = mlt_frame_rescale_yuv422( this, *width, *height );
-       else
+       else if ( strcmp( mlt_properties_get( properties, "resize.scale" ), "none" ) != 0 )
                *image = mlt_frame_resize_yuv422( this, *width, *height );
+       else
+       {
+               *width = owidth;
+               *height = oheight;
+       }
        return 0;
 }
 
index c929d2572e7dc7de4dcb512297bfcb712755a68a..ce7c500f06b74320193df0ad79b615078de28988 100644 (file)
@@ -19,7 +19,9 @@
  */
 
 #include "producer_ppm.h"
+
 #include <framework/mlt_frame.h>
+
 #include <stdlib.h>
 #include <string.h>
 
@@ -81,9 +83,10 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma
                // Convert to requested format
                if ( *format == mlt_image_yuv422 )
                {
-                       uint8_t *image = malloc( *width * *height * 2 );
+                       // IRRIGATE ME
+                       uint8_t *image = malloc( *width * ( *height + 1 ) * 2 );
                        mlt_convert_rgb24_to_yuv422( rgb, *width, *height, *width * 3, image );
-                       mlt_properties_set_data( properties, "image", image, *width * *height * 2, free, NULL );
+                       mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 2, free, NULL );
                        *buffer = image;
                }
                else if ( *format == mlt_image_rgb24 )
@@ -222,16 +225,19 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        {
 
                // Allocate an image
-               uint8_t *image = malloc( width * height * 3 );
+               // IRRIGATE ME
+               uint8_t *image = malloc( width * ( height + 1 ) * 3 );
                
                // Read it
                fread( image, width * height * 3, 1, video );
 
                // Pass the data on the frame properties
-               mlt_properties_set_data( properties, "image", image, width * height * 3, free, NULL );
+               mlt_properties_set_data( properties, "image", image, width * ( height + 1 ) * 3, free, NULL );
                mlt_properties_set_int( properties, "width", width );
                mlt_properties_set_int( properties, "height", height );
                mlt_properties_set_int( properties, "has_image", 1 );
+               mlt_properties_set_int( properties, "progressive", 1 );
+               mlt_properties_set_double( properties, "aspect_ratio", ( double )width  / height );
 
                // Push the image callback
                mlt_frame_push_get_image( *frame, producer_get_image );
index 205d546747d900ff5f53aa06c2f2d73e088cb53d..7d19d1b85ac3651a00676cd6bd05c6d87a6d314e 100644 (file)
@@ -22,7 +22,6 @@
 #define _PRODUCER_PPM_H_
 
 #include <framework/mlt_producer.h>
-#include <stdio.h>
 
 extern mlt_producer producer_ppm_init( void *command );
 
index 106b193a20df5a28b7586a43f48804482b2fbca8..efa251c3ece08c4de6bc85fdf397611a045d9154 100644 (file)
@@ -105,6 +105,8 @@ static int composite_yuv( uint8_t *p_dest, mlt_image_format format_dest, int wid
        int x = ( int )( ( float )width_dest * geometry.x / 100 );
        int y = ( int )( ( float )height_dest * geometry.y / 100 );
        float weight = geometry.mix / 100;
+
+       // Compute the dimensioning rectangle
        int width_src = ( int )( ( float )width_dest * geometry.w / 100 );
        int height_src = ( int )( ( float )height_dest * geometry.h / 100 );
 
@@ -115,26 +117,54 @@ static int composite_yuv( uint8_t *p_dest, mlt_image_format format_dest, int wid
        if ( mlt_properties_get( properties, "distort" ) == NULL &&
                 mlt_properties_get( mlt_frame_properties( that ), "real_width" ) != NULL )
        {
-               int width_b = mlt_properties_get_int( mlt_frame_properties( that ), "real_width" );
-               int height_b = mlt_properties_get_int( mlt_frame_properties( that ), "real_height" );
+               int width_b = mlt_properties_get_double( b_props, "real_width" );
+               int height_b = mlt_properties_get_double( b_props, "real_height" );
+
+               // See if we need to normalise pixel aspect ratio
+               // We can use consumer_aspect_ratio because the a_frame will take on this aspect
+               double aspect = mlt_properties_get_double( b_props, "consumer_aspect_ratio" );
+               if ( aspect != 0 )
+               {
+                       // Derive the consumer pixel aspect
+                       double oaspect = aspect / ( double )width_dest * height_dest;
+
+                       // Get the b frame pixel aspect - usually 1
+                       double iaspect = mlt_properties_get_double( b_props, "aspect_ratio" ) / width_b * height_b;
+
+                       // Normalise pixel aspect
+                       if ( iaspect != 0 && iaspect != oaspect )
+                               width_b = iaspect / oaspect * ( double )width_b + 0.5;
+                               
+                       // Tell rescale not to normalise display aspect
+                       mlt_frame_set_aspect_ratio( that, aspect );
+               }
 
+               // Constrain the overlay to the dimensioning rectangle
                if ( width_b < width_src )
                        width_src = width_b;
                if ( height_b < height_src )
                        height_src = height_b;
-               mlt_properties_set( mlt_frame_properties( that ), "rescale.interp", "none" );
+
+               // Adjust overall scale for consumer
+               double consumer_scale = mlt_properties_get_double( b_props, "consumer_scale" );
+               if ( consumer_scale > 0 )
+               {
+                       width_src = consumer_scale * width_src + 0.5;
+                       height_src = consumer_scale * height_src + 0.5;
+               }
        }
-       else if ( mlt_properties_get( mlt_frame_properties( that ), "real_width" ) != NULL )
+       else if ( mlt_properties_get( b_props, "real_width" ) != NULL )
        {
-               mlt_properties_set( mlt_frame_properties( that ), "rescale.interp", "none" );
+               // Tell rescale not to normalise display aspect
+               mlt_properties_set_double( b_props, "consumer_aspect_ratio", 0 );
        }
 
        x -= x % 2;
 
+       // optimization points - no work to do
        if ( width_src <= 0 || height_src <= 0 )
                return ret;
 
-       // optimization point - no work to do
        if ( ( x < 0 && -x >= width_src ) || ( y < 0 && -y >= height_src ) )
                return ret;
 
@@ -256,6 +286,13 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
                // Do the calculation
                geometry_calculate( &result, &start, &end, position );
 
+               // Since we are the consumer of the b_frame, we must pass along these
+               // consumer properties from the a_frame
+               mlt_properties_set_double( b_props, "consumer_aspect_ratio",
+                       mlt_properties_get_double( mlt_frame_properties( a_frame ), "consumer_aspect_ratio" ) );
+               mlt_properties_set_double( b_props, "consumer_scale",
+                       mlt_properties_get_double( mlt_frame_properties( a_frame ), "consumer_scale" ) );
+               
                // Composite the b_frame on the a_frame
                composite_yuv( *image, *format, *width, *height, b_frame, result );
        }
index 0cd3741471f31a1a860ae9f1edd88e6e251e5e14..ebc89154137dd7fa873cb7e05a881f42f15748bd 100644 (file)
@@ -253,6 +253,13 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form
        int top_field_first =  mlt_properties_get_int( b_props, "top_field_first" );
        int reverse = mlt_properties_get_int( b_props, "luma.reverse" );
 
+       // Since we are the consumer of the b_frame, we must pass along this
+       // consumer property from the a_frame
+       mlt_properties_set_double( b_props, "consumer_aspect_ratio",
+               mlt_properties_get_double( mlt_frame_properties( this ), "consumer_aspect_ratio" ) );
+       mlt_properties_set_double( b_props, "consumer_scale",
+               mlt_properties_get_double( mlt_frame_properties( this ), "consumer_scale" ) );
+               
        // Honour the reverse here
        mix = reverse ? 1 - mix : mix;
 
@@ -332,7 +339,9 @@ static void luma_read_pgm( FILE *f, float **map, int *width, int *height )
 
                // determine if this is one or two bytes per pixel
                bpp = maxval > 255 ? 2 : 1;
-                       // allocate temporary storage for the raw data
+               
+               // allocate temporary storage for the raw data
+               // IRRIGATE ME
                data = malloc( *width * *height * bpp );
                if ( data == NULL )
                        break;
@@ -342,6 +351,7 @@ static void luma_read_pgm( FILE *f, float **map, int *width, int *height )
                        break;
                
                // allocate the luma bitmap
+               // IRRIGATE ME
                *map =  p = (float*) malloc( *width * *height * sizeof( float ) );
                if ( *map == NULL )
                        break;
index 5f9e9623933da885d76bddfd857535bd8b8050b1..dc675f72d9232260f111285eab56f612e1b734ba 100644 (file)
@@ -111,6 +111,7 @@ static int read_frame( int fd, uint8_t* frame_buf, int *isPAL )
 static int producer_collect_info( producer_libdv this )
 {
        int valid = 0;
+       // IRRIGATE ME
        uint8_t *dv_data = malloc( frame_size_625_50 );
 
        if ( dv_data != NULL )
@@ -186,10 +187,11 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma
        if ( *format == mlt_image_yuv422 )
        {
                // Allocate an image
-               uint8_t *image = malloc( *width * *height * 2 );
+               // IRRIGATE ME
+               uint8_t *image = malloc( *width * ( *height + 1 ) * 2 );
 
                // Pass to properties for clean up
-               mlt_properties_set_data( properties, "image", image, *width * *height * 2, free, NULL );
+               mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 2, free, NULL );
 
                // Decode the image
                pitches[ 0 ] = *width * 2;
@@ -202,10 +204,11 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma
        else if ( *format == mlt_image_rgb24 )
        {
                // Allocate an image
-               uint8_t *image = malloc( *width * *height * 3 );
+               // IRRIGATE ME
+               uint8_t *image = malloc( *width * ( *height + 1 ) * 3 );
 
                // Pass to properties for clean up
-               mlt_properties_set_data( properties, "image", image, *width * *height * 3, free, NULL );
+               mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 3, free, NULL );
 
                // Decode the frame
                pitches[ 0 ] = 720 * 3;
index 2432529ee091125884d0c311f605aa295758c5de..729b270f565aac95fa6df6d65ab4262f13b6363f 100644 (file)
@@ -465,7 +465,8 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        if ( video != NULL && read_ffmpeg_header( this, &width, &height ) == 2 )
        {
                // Allocate an image
-               uint8_t *image = malloc( width * height * 2 );
+               // IRRIGATE ME
+               uint8_t *image = malloc( width * ( height + 1 ) * 2 );
                
                // Read it
                while( skip -- )
@@ -482,7 +483,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_convert_yuv420p_to_yuv422( this->buffer, width, height, width, image );
 
                // Pass the data on the frame properties
-               mlt_properties_set_data( properties, "image", image, width * height * 2, free, NULL );
+               mlt_properties_set_data( properties, "image", image, width * ( height + 1 ) * 2, free, NULL );
                mlt_properties_set_int( properties, "width", width );
                mlt_properties_set_int( properties, "height", height );
                mlt_properties_set_int( properties, "has_image", 1 );
index 31ebac4acdc31272b1e33ca6981f0f36bdc01c3b..526b58a3dddab60bf1fc6931ec9e03b39f9f0922 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
+
 /** Do it :-).
 */
 
@@ -56,26 +57,34 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        else if ( strcmp( interps, "hyper" ) == 0 )
                interp = PIXOPS_INTERP_HYPER;
 
-       mlt_frame_get_image( this, &input, format, &iwidth, &iheight, 0 );
+       mlt_frame_get_image( this, &input, format, &iwidth, &iheight, writable );
 
-       if ( o_aspect_ratio != 0 && o_aspect_ratio != i_aspect_ratio && mlt_properties_get_int( properties, "distort" ) == 0 )
+       if ( o_aspect_ratio != 0 && o_aspect_ratio != i_aspect_ratio && mlt_properties_get( properties, "distort" ) == NULL )
        {
-               // Determine maximum size within the aspect ratio:
+               int temp_width = i_aspect_ratio / o_aspect_ratio * owidth + 0.5;
 
-               if ( ( owidth * i_aspect_ratio * o_aspect_ratio ) > owidth )
-                       oheight *= o_aspect_ratio / i_aspect_ratio;
+               // Determine maximum size within the aspect ratio:
+               if ( temp_width > owidth )
+                       if ( i_aspect_ratio > o_aspect_ratio )
+                               oheight = o_aspect_ratio / i_aspect_ratio * oheight + 0.5;
+                       else
+                               oheight = i_aspect_ratio / o_aspect_ratio * oheight + 0.5;
                else
-                       owidth *= i_aspect_ratio * o_aspect_ratio;
-               //fprintf( stderr, "rescale: from %dx%d (aspect %f) to %dx%d (aspect %f)\n", iwidth, iheight, i_aspect_ratio, owidth, oheight, o_aspect_ratio );
+                       owidth = temp_width;
+                       
+               // Tell frame we have conformed the aspect to the consumer
+               mlt_frame_set_aspect_ratio( this, o_aspect_ratio );
        }
-       
-       // If width and height are correct, don't do anything
-       if ( strcmp( interps, "none" ) && input != NULL && ( iwidth != owidth || iheight != oheight ) )
+       //fprintf( stderr, "rescale: from %dx%d (aspect %f) to %dx%d (aspect %f)\n", iwidth, iheight, i_aspect_ratio, owidth, oheight, o_aspect_ratio );
+
+       if ( input != NULL )
        {
-               if ( *format == mlt_image_yuv422 )
+               // If width and height are correct, don't do anything
+               if ( *format == mlt_image_yuv422 && strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) )
                {
                        // Create the output image
-                       uint8_t *output = malloc( owidth * oheight * 2 );
+                       // IRRIGATE ME
+                       uint8_t *output = malloc( owidth * ( oheight + 1 ) * 2 );
 
                        // Calculate strides
                        int istride = iwidth * 2;
@@ -84,7 +93,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                        yuv422_scale_simple( output, owidth, oheight, ostride, input, iwidth, iheight, istride, interp );
                
                        // Now update the frame
-                       mlt_properties_set_data( properties, "image", output, owidth * oheight * 2, free, NULL );
+                       mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, free, NULL );
                        mlt_properties_set_int( properties, "width", owidth );
                        mlt_properties_set_int( properties, "height", oheight );
 
@@ -94,31 +103,84 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                else if ( *format == mlt_image_rgb24 || *format == mlt_image_rgb24a )
                {
                        int bpp = (*format == mlt_image_rgb24a ? 4 : 3 );
-                       GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( input, GDK_COLORSPACE_RGB,
-                               (*format == mlt_image_rgb24a), 24, iwidth, iheight,
-                               iwidth * bpp, NULL, NULL );
-                       GdkPixbuf *scaled = gdk_pixbuf_scale_simple( pixbuf, owidth, oheight, interp );
-
-                       // Create the output image
-                       uint8_t *output = malloc( owidth * oheight * bpp );
-
-                       int i;
-                       for ( i = 0; i < oheight; i++ )
-                               memcpy( output + i * owidth * bpp,
-                                               gdk_pixbuf_get_pixels( scaled ) + i * gdk_pixbuf_get_rowstride( scaled ),
-                                               gdk_pixbuf_get_width( scaled ) * bpp );
-
-                       g_object_unref( pixbuf );
-                       g_object_unref( scaled );
                        
+                       // Create the yuv image
+                       // IRRIGATE ME
+                       uint8_t *output = malloc( owidth * ( oheight + 1 ) * 2 );
+
+                       if ( strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) )
+                       {
+                               GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( input, GDK_COLORSPACE_RGB,
+                                       ( *format == mlt_image_rgb24a ), 8, iwidth, iheight,
+                                       iwidth * bpp, NULL, NULL );
+
+                               GdkPixbuf *scaled = gdk_pixbuf_scale_simple( pixbuf, owidth, oheight, interp );
+                               g_object_unref( pixbuf );
+                               
+                               // Extract YUV422 and alpha
+                               if ( bpp == 4 )
+                               {
+                                       // Allocate the alpha mask
+                                       // IRRIGATE ME
+                                       uint8_t *alpha = malloc( owidth * ( oheight + 1 ) );
+
+                                       // Convert the image and extract alpha
+                                       mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( scaled ),
+                                                                                 owidth, oheight,
+                                                                                 gdk_pixbuf_get_rowstride( scaled ),
+                                                                                 output, alpha );
+
+                                       mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), free, NULL );
+                               }
+                               else
+                               {
+                                       // No alpha to extract
+                                       mlt_convert_rgb24_to_yuv422( gdk_pixbuf_get_pixels( scaled ),
+                                                                                owidth, oheight,
+                                                                                gdk_pixbuf_get_rowstride( scaled ),
+                                                                                output );
+                               }
+                               g_object_unref( scaled );
+                       }
+                       else
+                       {
+                               // Extract YUV422 and alpha
+                               if ( bpp == 4 )
+                               {
+                                       // Allocate the alpha mask
+                                       // IRRIGATE ME
+                                       uint8_t *alpha = malloc( owidth * ( oheight + 1 ) );
+
+                                       // Convert the image and extract alpha
+                                       mlt_convert_rgb24a_to_yuv422( input,
+                                                                                 owidth, oheight,
+                                                                                 owidth * 4,
+                                                                                 output, alpha );
+
+                                       mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), free, NULL );
+                               }
+                               else
+                               {
+                                       // No alpha to extract
+                                       mlt_convert_rgb24_to_yuv422( input,
+                                                                                owidth, oheight,
+                                                                                owidth * 3,
+                                                                                output );
+                               }
+                       }
+
                        // Now update the frame
-                       mlt_properties_set_data( properties, "image", output, owidth * oheight * bpp, free, NULL );
+                       mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, free, NULL );
                        mlt_properties_set_int( properties, "width", owidth );
                        mlt_properties_set_int( properties, "height", oheight );
 
                        // Return the output
+                       *width = owidth;
+                       *height = oheight;
                        *image = output;
                }
+               else
+                       *image = input;
        }
        else
                *image = input;
@@ -126,6 +188,15 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        return 0;
 }
 
+static uint8_t *producer_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 );
+}
+
 /** Filter processing.
 */
 
@@ -134,6 +205,9 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
        mlt_frame_push_get_image( frame, filter_get_image );
        mlt_properties_set( mlt_frame_properties( frame ), "rescale.interp",
                mlt_properties_get( mlt_filter_properties( this ), "interpolation" ) );
+               
+       // Set alpha call back
+       frame->get_alpha_mask = producer_get_alpha_mask;
        return frame;
 }
 
index c293d86f334d7f96b375c43c7cda88f4b0e2574d..a626a9db60e78e02295444ccdb9f7ca527a532f6 100644 (file)
@@ -32,7 +32,6 @@ struct producer_pango_s
        int width;
        int height;
        uint8_t *image;
-       uint8_t *alpha;
        char *fgcolor;
        char *bgcolor;
        int   align;
@@ -267,16 +266,23 @@ static void refresh_image( mlt_frame frame, int width, int height )
                        // Store the width/height of the pixbuf temporarily
                        this->width = gdk_pixbuf_get_width( pixbuf );
                        this->height = gdk_pixbuf_get_height( pixbuf );
+
+                       mlt_properties_set_int( producer_props, "bpp", gdk_pixbuf_get_has_alpha( pixbuf ) ? 4 : 3 );
                }
        }
        else if ( this->image == NULL || width != this->width || height != this->height )
        {
                pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL );
+               mlt_properties_set_int( producer_props, "bpp", gdk_pixbuf_get_has_alpha( pixbuf ) ? 4 : 3 );
        }
 
+       int bpp = mlt_properties_get_int( producer_props, "bpp" );
+
        // If we have a pixbuf and a valid width
        if ( pixbuf && width > 0 )
        {
+               int i;
+               
                // Note - the original pixbuf is already safe and ready for destruction
                pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, GDK_INTERP_HYPER );
 
@@ -284,39 +290,21 @@ static void refresh_image( mlt_frame frame, int width, int height )
                this->width = gdk_pixbuf_get_width( pixbuf );
                this->height = gdk_pixbuf_get_height( pixbuf );
 
-               // Allocate/define image and alpha
-               uint8_t *image = malloc( this->width * this->height * 2 );
-               uint8_t *alpha = NULL;
+               // Allocate/define image
+               // IRRIGATE ME
+               uint8_t *image = malloc( this->width * ( this->height + 1 )* bpp );
 
-               // Extract YUV422 and alpha
-               if ( gdk_pixbuf_get_has_alpha( pixbuf ) )
-               {
-                       // Allocate the alpha mask
-                       alpha = malloc( this->width * this->height );
-
-                       // Convert the image
-                       mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
-                                                                                 this->width, this->height,
-                                                                                 gdk_pixbuf_get_rowstride( pixbuf ),
-                                                                                 image, alpha );
-               }
-               else
-               { 
-                       // No alpha to extract
-                       mlt_convert_rgb24_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
-                                                                                this->width, this->height,
-                                                                                gdk_pixbuf_get_rowstride( pixbuf ),
-                                                                                image );
-               }
+               for ( i = 0; i < height; i++ )
+                       memcpy( image + i * width * bpp,
+                               gdk_pixbuf_get_pixels( pixbuf ) + i * gdk_pixbuf_get_rowstride( pixbuf ),
+                               gdk_pixbuf_get_width( pixbuf ) * bpp );
 
                // Finished with pixbuf now
                g_object_unref( pixbuf );
                
-               // if single picture, reference the image and alpha in the producer
+               // reference the image in the producer
                free( this->image );
                this->image = image;
-               free( this->alpha );
-               this->alpha = alpha;
        }
 
        // Set width/height
@@ -325,9 +313,8 @@ static void refresh_image( mlt_frame frame, int width, int height )
        mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "real_width" ) );
        mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "real_height" ) );
 
-       // pass the image and alpha data without destructor
-       mlt_properties_set_data( properties, "image", this->image, this->width * this->height * 2, NULL, NULL );
-       mlt_properties_set_data( properties, "alpha", this->alpha, this->width * this->height, NULL, NULL );
+       // pass the image data without destructor
+       mlt_properties_set_data( properties, "image", this->image, this->width * ( this->height + 1 ) * bpp, NULL, NULL );
 }
 
 static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
@@ -338,6 +325,10 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        // Refresh the image
        refresh_image( frame, *width, *height );
 
+       // Determine format
+       mlt_producer this = mlt_properties_get_data( properties, "producer_pango", NULL );
+       *format = ( mlt_properties_get_int( mlt_producer_properties( this ), "bpp" ) == 4 ) ? mlt_image_rgb24a : mlt_image_rgb24;
+
        // May need to know the size of the image to clone it
        int size = 0;
 
@@ -352,6 +343,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        if ( writable )
        {
                // Clone our image
+               // IRRIGATE ME
                uint8_t *copy = malloc( size );
                memcpy( copy, image, size );
 
@@ -368,15 +360,6 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        return 0;
 }
 
-static uint8_t *producer_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 );
-}
-
 static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
 {
        producer_pango this = producer->child;
@@ -393,8 +376,9 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        // Refresh the pango image
        refresh_image( *frame, 0, 0 );
 
-       // Set alpha mask call back
-       ( *frame )->get_alpha_mask = producer_get_alpha_mask;
+       // Set producer-specific frame properties
+       mlt_properties_set_int( properties, "progressive", 1 );
+       mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( properties, "real_width" ) / mlt_properties_get_double( properties, "real_height" ) );
 
        // Stack the get image callback
        mlt_frame_push_get_image( *frame, producer_get_image );
@@ -412,7 +396,6 @@ static void producer_close( mlt_producer parent )
 {
        producer_pango this = parent->child;
        free( this->image );
-       free( this->alpha );
        free( this->fgcolor );
        free( this->bgcolor );
        free( this->markup );
index 63817f7581107e147bb48bef8582a8a0f069b722..cc474248bd503eb64a80ce52246481145581a157 100644 (file)
@@ -144,7 +144,7 @@ static void refresh_image( mlt_frame frame, int width, int height )
        // Obtain properties of frame
        mlt_properties properties = mlt_frame_properties( frame );
 
-       // Obtain the producer pango for this frame
+       // Obtain the producer for this frame
        producer_pixbuf this = mlt_properties_get_data( properties, "producer_pixbuf", NULL );
 
        // Obtain the producer 
@@ -168,14 +168,11 @@ static void refresh_image( mlt_frame frame, int width, int height )
                if ( width != this->width || height != this->height )
                {
                        pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL );
+                       mlt_properties_set_int( producer_props, "bpp", gdk_pixbuf_get_has_alpha( pixbuf ) ? 4 : 3 );
                }
        }
        else 
        {
-               free( this->image );
-               this->image = NULL;
-               free( this->alpha );
-               this->alpha = NULL;
                this->image_idx = image_idx;
                pixbuf = gdk_pixbuf_new_from_file( this->filenames[ image_idx ], &error );
 
@@ -190,50 +187,41 @@ static void refresh_image( mlt_frame frame, int width, int height )
                        // Store the width/height of the pixbuf temporarily
                        this->width = gdk_pixbuf_get_width( pixbuf );
                        this->height = gdk_pixbuf_get_height( pixbuf );
+                       
+                       mlt_properties_set_int( producer_props, "bpp", gdk_pixbuf_get_has_alpha( pixbuf ) ? 4 : 3 );
                }
        }
 
+       int bpp = mlt_properties_get_int( producer_props, "bpp" );
+       
        // If we have a pixbuf
        if ( pixbuf && width > 0 )
        {
+               int i;
+               //fprintf( stderr, "SCALING PIXBUF from %dx%d to %dx%d\n", gdk_pixbuf_get_width( pixbuf ), gdk_pixbuf_get_height( pixbuf ), width, height );
+               
                // Note - the original pixbuf is already safe and ready for destruction
                pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, GDK_INTERP_HYPER );
-
+               
                // Store width and height
                this->width = gdk_pixbuf_get_width( pixbuf );
                this->height = gdk_pixbuf_get_height( pixbuf );
+               
+               // Allocate/define image
+               // IRRIGATE ME
+               uint8_t *image = malloc( width * ( height + 1 ) * bpp );
 
-               // Allocate/define image and alpha
-               uint8_t *image = malloc( this->width * this->height * 2 );
-               uint8_t *alpha = NULL;
-
-               // Extract YUV422 and alpha
-               if ( gdk_pixbuf_get_has_alpha( pixbuf ) )
-               {
-                       // Allocate the alpha mask
-                       alpha = malloc( this->width * this->height );
-
-                       // Convert the image
-                       mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
-                                                                                 this->width, this->height,
-                                                                                 gdk_pixbuf_get_rowstride( pixbuf ),
-                                                                                 image, alpha );
-               }
-               else
-               { 
-                       // No alpha to extract
-                       mlt_convert_rgb24_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
-                                                                                this->width, this->height,
-                                                                                gdk_pixbuf_get_rowstride( pixbuf ),
-                                                                                image );
-               }
+               for ( i = 0; i < height; i++ )
+                       memcpy( image + i * width * bpp,
+                               gdk_pixbuf_get_pixels( pixbuf ) + i * gdk_pixbuf_get_rowstride( pixbuf ),
+                               gdk_pixbuf_get_width( pixbuf ) * bpp );
 
                // Finished with pixbuf now
                g_object_unref( pixbuf );
 
-               // Pass alpha and image on properties with or without destructor
+               // Pass image on properties with or without destructor
+               free( this->image );
                this->image = image;
-               this->alpha = alpha;
        }
 
        // Set width/height of frame
@@ -242,9 +230,8 @@ static void refresh_image( mlt_frame frame, int width, int height )
        mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "real_width" ) );
        mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "real_height" ) );
 
-       // pass the image and alpha data without destructor
-       mlt_properties_set_data( properties, "image", this->image, this->width * this->height * 2, NULL, NULL );
-       mlt_properties_set_data( properties, "alpha", this->alpha, this->width * this->height, NULL, NULL );
+       // pass the image data without destructor
+       mlt_properties_set_data( properties, "image", this->image, this->width * ( this->height + 1 ) * bpp, NULL, NULL );
 }
 
 static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
@@ -255,6 +242,10 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        // Refresh the image
        refresh_image( frame, *width, *height );
 
+       // Determine format
+       mlt_producer this = mlt_properties_get_data( properties, "producer_pixbuf", NULL );
+       *format = ( mlt_properties_get_int( mlt_producer_properties( this ), "bpp" ) == 4 ) ? mlt_image_rgb24a : mlt_image_rgb24;
+
        // May need to know the size of the image to clone it
        int size = 0;
 
@@ -270,9 +261,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        // The fault is not in the design of mlt, but in the implementation of pixbuf...
        //if ( writable )
        {
-               size = *width * *height * 2;
-
                // Clone our image
+               // IRRIGATE ME
                uint8_t *copy = malloc( size );
                memcpy( copy, image, size );
 
@@ -289,15 +279,6 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        return 0;
 }
 
-static uint8_t *producer_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 );
-}
-
 static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
 {
        // Get the real structure for this producer
@@ -312,11 +293,12 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        // Set the producer on the frame properties
        mlt_properties_set_data( properties, "producer_pixbuf", this, 0, NULL, NULL );
 
-       // Refresh the pango image
+       // Refresh the image
        refresh_image( *frame, 0, 0 );
 
-       // Set alpha call back
-       ( *frame )->get_alpha_mask = producer_get_alpha_mask;
+       // Set producer-specific frame properties
+       mlt_properties_set_int( properties, "progressive", 1 );
+       mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( properties, "real_width" ) / mlt_properties_get_double( properties, "real_height" ) );
 
        // Push the get_image method
        mlt_frame_push_get_image( *frame, producer_get_image );
@@ -331,7 +313,6 @@ static void producer_close( mlt_producer parent )
 {
        producer_pixbuf this = parent->child;
        free( this->image );
-       free( this->alpha );
        parent->close = NULL;
        mlt_producer_close( parent );
        free( this );
index 1c8219370217974e2dba89a1185415ceab945572..9d82aacb8589dbfe2af16424ebcdd5385f5ddd8b 100644 (file)
@@ -101,6 +101,9 @@ mlt_consumer consumer_sdl_init( char *arg )
                // Default scaler (for now we'll use nearest)
                mlt_properties_set( this->properties, "rescale", "nearest" );
 
+               // Get aspect ratio
+               this->aspect_ratio = mlt_properties_get_double( this->properties, "aspect_ratio" );
+               
                // process actual param
                if ( arg == NULL || sscanf( arg, "%dx%d", &this->width, &this->height ) != 2 )
                {
@@ -108,11 +111,10 @@ mlt_consumer consumer_sdl_init( char *arg )
                        this->height = mlt_properties_get_int( this->properties, "height" );
                }
 
-               // Default window size and aspect ratio
-               this->aspect_ratio = 4.0 / 3.0;
+               // Default window size
                this->window_width = (int)( (float)this->height * this->aspect_ratio ) + 1;
                this->window_height = this->height;
-
+               
                // Set the sdl flags
                this->sdl_flags = SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_HWACCEL | SDL_RESIZABLE;
 
@@ -458,7 +460,12 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame )
                mlt_frame_close( frame );
 
        if ( this->count )
+       {
+               // Tell the producers about our scale relative to the normalisation
+               mlt_properties_set_double( mlt_frame_properties( this->queue[ this->count - 1 ] ), "consumer_scale",
+                       ( double )height / mlt_properties_get_double( properties, "height" ) );
                mlt_frame_get_image( this->queue[ this->count - 1 ], &image, &vfmt, &width, &height, 0 );
+       }
 
        return 0;
 }
@@ -492,6 +499,10 @@ static void *consumer_thread( void *arg )
                // Ensure that we have a frame
                if ( frame != NULL )
                {
+                       // SDL adapts display aspect, but set this so pixel aspect can be normalised
+                       mlt_properties_set_double( mlt_frame_properties( frame ), "consumer_aspect_ratio",
+                               mlt_frame_get_aspect_ratio( frame ) );
+                       
                        init_audio = consumer_play_audio( this, frame, init_audio );
                        consumer_play_video( this, frame );
                }
index 2d7d83c4a55cadbcb496380996e971d9a57c2bf9..ebe504a2be79cbdf23e7b234553dd1fb6cf83859 100644 (file)
@@ -222,9 +222,6 @@ static void serialise_service( serialise_context context, mlt_service service, x
                                        else
                                                strncpy( id, mlt_properties_get( properties, "id" ), ID_SIZE );
 
-                                       xmlNewProp( child, "in", mlt_properties_get( properties, "in" ) );
-                                       xmlNewProp( child, "out", mlt_properties_get( properties, "out" ) );
-
                                        // Add producer to the map
                                        snprintf( key, 10, "%p", service );
                                        mlt_properties_set( context->producer_map, key, id );
@@ -247,6 +244,8 @@ static void serialise_service( serialise_context context, mlt_service service, x
                                                                xmlNode *entry = xmlNewChild( child, NULL, "entry", NULL );
                                                                snprintf( key, 10, "%p", MLT_SERVICE( info.producer ) );
                                                                xmlNewProp( entry, "producer", mlt_properties_get( context->producer_map, key ) );
+                                                               xmlNewProp( entry, "in", mlt_properties_get( mlt_producer_properties( info.producer ), "in" ) );
+                                                               xmlNewProp( entry, "out", mlt_properties_get( mlt_producer_properties( info.producer ), "out" ) );
                                                        }
                                                }
                                        }