]> git.sesse.net Git - mlt/commitdiff
Massive refactoring of image conversion.
authorDan Dennedy <dan@dennedy.org>
Fri, 3 Jul 2009 21:55:15 +0000 (14:55 -0700)
committerDan Dennedy <dan@dennedy.org>
Fri, 3 Jul 2009 21:55:15 +0000 (14:55 -0700)
This drops all image color space and pixel format conversions from the
mlt_frame class. Instead, it adds a convert_image virtual function to
the mlt_frame class that is called within mlt_frame_get_image(). The
newly added imageconvert filter sets that virtual function and contains
the various conversion routines. The loader producer automatically
attaches this filter to the producer it creates.

Signed-off-by: Dan Dennedy <dan@dennedy.org>
66 files changed:
configure
docs/policies.txt
src/framework/mlt.h
src/framework/mlt_frame.c
src/framework/mlt_frame.h
src/framework/mlt_log.c
src/modules/avformat/filter_avcolour_space.c
src/modules/avformat/filter_avdeinterlace.c
src/modules/avformat/filter_swscale.c
src/modules/avformat/producer_avformat.c
src/modules/core/Makefile
src/modules/core/factory.c
src/modules/core/filter_brightness.c
src/modules/core/filter_crop.c
src/modules/core/filter_gamma.c
src/modules/core/filter_greyscale.c
src/modules/core/filter_imageconvert.c [new file with mode: 0644]
src/modules/core/filter_luma.c
src/modules/core/filter_mirror.c
src/modules/core/filter_obscure.c
src/modules/core/filter_rescale.c
src/modules/core/filter_resize.c
src/modules/core/filter_watermark.c
src/modules/core/loader.ini
src/modules/core/producer_colour.c
src/modules/core/producer_consumer.c
src/modules/core/producer_ppm.c
src/modules/core/transition_luma.c
src/modules/effectv/filter_burn.c
src/modules/frei0r/filter_frei0r.c
src/modules/frei0r/frei0r_helper.c
src/modules/frei0r/frei0r_helper.h
src/modules/frei0r/producer_frei0r.c
src/modules/frei0r/transition_frei0r.c
src/modules/gtk2/filter_rescale.c
src/modules/gtk2/producer_pango.c
src/modules/gtk2/producer_pixbuf.c
src/modules/kdenlive/filter_boxblur.c
src/modules/kdenlive/filter_wave.c
src/modules/kdenlive/producer_framebuffer.c
src/modules/motion_est/filter_crop_detect.c
src/modules/motion_est/filter_motion_est.c
src/modules/motion_est/filter_vismv.c
src/modules/motion_est/producer_slowmotion.c
src/modules/oldfilm/filter_dust.c
src/modules/oldfilm/filter_grain.c
src/modules/oldfilm/filter_lines.c
src/modules/oldfilm/filter_oldfilm.c
src/modules/oldfilm/filter_tcolor.c
src/modules/oldfilm/filter_vignette.c
src/modules/plus/filter_affine.c
src/modules/plus/filter_charcoal.c
src/modules/plus/filter_invert.c
src/modules/plus/filter_sepia.c
src/modules/plus/transition_affine.c
src/modules/qimage/producer_qimage.c
src/modules/qimage/qimage_wrapper.cpp
src/modules/qimage/qimage_wrapper.h
src/modules/sdl/consumer_sdl.c
src/modules/sdl/consumer_sdl_still.c
src/modules/sdl/producer_sdl_image.c
src/modules/vmfx/filter_chroma.c
src/modules/vmfx/filter_chroma_hold.c
src/modules/vmfx/filter_mono.c
src/modules/vmfx/filter_shape.c
src/modules/xine/filter_deinterlace.c

index 0ce1fb8fa75f60b31046ce4b64e6d210c4ebd9cc..3315473c1738f62d7c6a16121c82068f672d7bf9 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
 #!/bin/sh
 
-export version=0.4.4
-export soversion=1
+export version=0.4.5
+export soversion=2
 
 show_help()
 {
index 470bf6e0d19823da2b61dd665b71775f3bc297ab..60ba1db5ac78d384e65ae8b282f50fdc2616026c 100644 (file)
@@ -50,6 +50,13 @@ copyright the MLT integration code as your own. However, if you have heavily
 modified the original code beyond nearly all recognition, you can copyright it
 as your own and attribute the original author as inspiration.
 
+A producer should validate its input and return NULL on failure.
+
+A filter or transition should express the image format it wants before calling
+mlt_frame_get_image(). It should expect to receive what it requested as long
+as it is yuv422, rgb24, or rgb24a and you are using the imageconvert filter
+(typically via the loader producer and its loader.ini file).
+
 Bug Reporting:
 First preference is to use the SourceForge tracker:
 http://sourceforge.net/tracker/?group_id=96039&atid=613414
index e073fbc948fd1d254ad995ed18c1efb5f7e1d893..bad3688c76718d31f0926a3f8cfb1d22bf7a9ee3 100644 (file)
@@ -23,8 +23,8 @@
 #ifndef _MLT_H_
 #define _MLT_H_
 
-#define LIBMLT_VERSION_INT ((0<<16)+(4<<8)+4)
-#define LIBMLT_VERSION     0.4.4
+#define LIBMLT_VERSION_INT ((0<<16)+(4<<8)+5)
+#define LIBMLT_VERSION     0.4.5
 
 #ifdef __cplusplus
 extern "C"
index 0899b06505cb292cc64da90b935129695504c3af..6bd5442c164aebb72f9064f821c6ea95809a2360 100644 (file)
@@ -25,6 +25,7 @@
 #include "mlt_producer.h"
 #include "mlt_factory.h"
 #include "mlt_profile.h"
+#include "mlt_log.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -244,6 +245,20 @@ void mlt_frame_replace_image( mlt_frame this, uint8_t *image, mlt_image_format f
        this->get_alpha_mask = NULL;
 }
 
+const char * mlt_image_format_name( mlt_image_format format )
+{
+       switch ( format )
+       {
+               case mlt_image_none:    return "none";
+               case mlt_image_rgb24:   return "rgb24";
+               case mlt_image_rgb24a:  return "rgb24a";
+               case mlt_image_yuv422:  return "yuv422";
+               case mlt_image_yuv420p: return "yuv420p";
+               case mlt_image_opengl:  return "opengl";
+       }
+       return "invalid";
+}
+
 /** Get the image associated to the frame.
 */
 
@@ -252,41 +267,46 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for
        mlt_properties properties = MLT_FRAME_PROPERTIES( this );
        mlt_get_image get_image = mlt_frame_pop_get_image( this );
        mlt_producer producer = mlt_properties_get_data( properties, "test_card_producer", NULL );
+       mlt_image_format requested_format = *format;
        int error = 0;
 
-       if ( get_image != NULL )
+       if ( get_image )
        {
                mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 );
                mlt_position position = mlt_frame_get_position( this );
-               error = get_image( this, buffer, format, width, height, writable );
+               error = get_image( this, buffer, format, width, height, writable );
                mlt_properties_set_int( properties, "width", *width );
                mlt_properties_set_int( properties, "height", *height );
                mlt_properties_set_int( properties, "format", *format );
                mlt_frame_set_position( this, position );
+               if ( this->convert_image )
+                       this->convert_image( this, buffer, format, requested_format );
        }
-       else if ( mlt_properties_get_data( properties, "image", NULL ) != NULL )
+       else if ( mlt_properties_get_data( properties, "image", NULL ) )
        {
                *format = mlt_properties_get_int( properties, "format" );
                *buffer = mlt_properties_get_data( properties, "image", NULL );
                *width = mlt_properties_get_int( properties, "width" );
                *height = mlt_properties_get_int( properties, "height" );
+               if ( this->convert_image )
+                       this->convert_image( this, buffer, format, requested_format );
        }
-       else if ( producer != NULL )
+       else if ( producer )
        {
                mlt_frame test_frame = NULL;
                mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &test_frame, 0 );
-               if ( test_frame != NULL )
+               if ( test_frame )
                {
                        mlt_properties test_properties = MLT_FRAME_PROPERTIES( test_frame );
                        mlt_properties_set_double( test_properties, "consumer_aspect_ratio", mlt_properties_get_double( properties, "consumer_aspect_ratio" ) );
                        mlt_properties_set( test_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) );
                        mlt_frame_get_image( test_frame, buffer, format, width, height, writable );
                        mlt_properties_set_data( properties, "test_card_frame", test_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
-                       mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL );
-                       mlt_properties_set_int( properties, "width", *width );
-                       mlt_properties_set_int( properties, "height", *height );
-                       mlt_properties_set_int( properties, "format", *format );
                        mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( test_frame ) );
+//                     mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL );
+//                     mlt_properties_set_int( properties, "width", *width );
+//                     mlt_properties_set_int( properties, "height", *height );
+//                     mlt_properties_set_int( properties, "format", *format );
                }
                else
                {
@@ -519,591 +539,6 @@ void mlt_frame_close( mlt_frame this )
 
 /***** convenience functions *****/
 
-int mlt_convert_yuv422_to_rgb24a( uint8_t *yuv, uint8_t *rgba, unsigned int total )
-{
-       int ret = 0;
-       int yy, uu, vv;
-       int r,g,b;
-       total /= 2;
-       while (total--)
-       {
-               yy = yuv[0];
-               uu = yuv[1];
-               vv = yuv[3];
-               YUV2RGB(yy, uu, vv, r, g, b);
-               rgba[0] = r;
-               rgba[1] = g;
-               rgba[2] = b;
-               rgba[3] = 255;
-               yy = yuv[2];
-               YUV2RGB(yy, uu, vv, r, g, b);
-               rgba[4] = r;
-               rgba[5] = g;
-               rgba[6] = b;
-               rgba[7] = 255;
-               yuv += 4;
-               rgba += 8;
-       }
-       return ret;
-}
-
-int mlt_convert_rgb24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha )
-{
-       int ret = 0;
-       register int y0, y1, u0, u1, v0, v1;
-       register int r, g, b;
-       register uint8_t *d = yuv;
-       register int i, j;
-
-       if ( alpha )
-       for ( i = 0; i < height; i++ )
-       {
-               register uint8_t *s = rgba + ( stride * i );
-               for ( j = 0; j < ( width / 2 ); j++ )
-               {
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       *alpha++ = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       *alpha++ = *s++;
-                       RGB2YUV (r, g, b, y1, u1 , v1);
-                       *d++ = y0;
-                       *d++ = (u0+u1) >> 1;
-                       *d++ = y1;
-                       *d++ = (v0+v1) >> 1;
-               }
-               if ( width % 2 )
-               {
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       *alpha++ = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       *d++ = y0;
-                       *d++ = u0;
-               }
-       }
-       else
-       for ( i = 0; i < height; i++ )
-       {
-               register uint8_t *s = rgba + ( stride * i );
-               for ( j = 0; j < ( width / 2 ); j++ )
-               {
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       s++;
-                       RGB2YUV (r, g, b, y1, u1 , v1);
-                       *d++ = y0;
-                       *d++ = (u0+u1) >> 1;
-                       *d++ = y1;
-                       *d++ = (v0+v1) >> 1;
-               }
-               if ( width % 2 )
-               {
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       *d++ = y0;
-                       *d++ = u0;
-               }
-       }
-
-       return ret;
-}
-
-int mlt_convert_rgb24_to_yuv422( uint8_t *rgb, int width, int height, int stride, uint8_t *yuv )
-{
-       int ret = 0;
-       register int y0, y1, u0, u1, v0, v1;
-       register int r, g, b;
-       register uint8_t *d = yuv;
-       register int i, j;
-
-       for ( i = 0; i < height; i++ )
-       {
-               register uint8_t *s = rgb + ( stride * i );
-               for ( j = 0; j < ( width / 2 ); j++ )
-               {
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       RGB2YUV (r, g, b, y1, u1 , v1);
-                       *d++ = y0;
-                       *d++ = (u0+u1) >> 1;
-                       *d++ = y1;
-                       *d++ = (v0+v1) >> 1;
-               }
-               if ( width % 2 )
-               {
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       *d++ = y0;
-                       *d++ = u0;
-               }
-       }
-       return ret;
-}
-
-int mlt_convert_bgr24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha )
-{
-       int ret = 0;
-       register int y0, y1, u0, u1, v0, v1;
-       register int r, g, b;
-       register uint8_t *d = yuv;
-       register int i, j;
-
-       if ( alpha )
-       for ( i = 0; i < height; i++ )
-       {
-               register uint8_t *s = rgba + ( stride * i );
-               for ( j = 0; j < ( width / 2 ); j++ )
-               {
-                       b = *s++;
-                       g = *s++;
-                       r = *s++;
-                       *alpha++ = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       b = *s++;
-                       g = *s++;
-                       r = *s++;
-                       *alpha++ = *s++;
-                       RGB2YUV (r, g, b, y1, u1 , v1);
-                       *d++ = y0;
-                       *d++ = (u0+u1) >> 1;
-                       *d++ = y1;
-                       *d++ = (v0+v1) >> 1;
-               }
-               if ( width % 2 )
-               {
-                       b = *s++;
-                       g = *s++;
-                       r = *s++;
-                       *alpha++ = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       *d++ = y0;
-                       *d++ = u0;
-               }
-       }
-       else
-       for ( i = 0; i < height; i++ )
-       {
-               register uint8_t *s = rgba + ( stride * i );
-               for ( j = 0; j < ( width / 2 ); j++ )
-               {
-                       b = *s++;
-                       g = *s++;
-                       r = *s++;
-                       s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       b = *s++;
-                       g = *s++;
-                       r = *s++;
-                       s++;
-                       RGB2YUV (r, g, b, y1, u1 , v1);
-                       *d++ = y0;
-                       *d++ = (u0+u1) >> 1;
-                       *d++ = y1;
-                       *d++ = (v0+v1) >> 1;
-               }
-               if ( width % 2 )
-               {
-                       b = *s++;
-                       g = *s++;
-                       r = *s++;
-                       s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       *d++ = y0;
-                       *d++ = u0;
-               }
-       }
-       return ret;
-}
-
-int mlt_convert_bgr24_to_yuv422( uint8_t *rgb, int width, int height, int stride, uint8_t *yuv )
-{
-       int ret = 0;
-       register int y0, y1, u0, u1, v0, v1;
-       register int r, g, b;
-       register uint8_t *d = yuv;
-       register int i, j;
-
-       for ( i = 0; i < height; i++ )
-       {
-               register uint8_t *s = rgb + ( stride * i );
-               for ( j = 0; j < ( width / 2 ); j++ )
-               {
-                       b = *s++;
-                       g = *s++;
-                       r = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       b = *s++;
-                       g = *s++;
-                       r = *s++;
-                       RGB2YUV (r, g, b, y1, u1 , v1);
-                       *d++ = y0;
-                       *d++ = (u0+u1) >> 1;
-                       *d++ = y1;
-                       *d++ = (v0+v1) >> 1;
-               }
-               if ( width % 2 )
-               {
-                       b = *s++;
-                       g = *s++;
-                       r = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       *d++ = y0;
-                       *d++ = u0;
-               }
-       }
-       return ret;
-}
-
-int mlt_convert_argb_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha )
-{
-       int ret = 0;
-       register int y0, y1, u0, u1, v0, v1;
-       register int r, g, b;
-       register uint8_t *d = yuv;
-       register int i, j;
-
-       if ( alpha )
-       for ( i = 0; i < height; i++ )
-       {
-               register uint8_t *s = rgba + ( stride * i );
-               for ( j = 0; j < ( width / 2 ); j++ )
-               {
-                       *alpha++ = *s++;
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       *alpha++ = *s++;
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       RGB2YUV (r, g, b, y1, u1 , v1);
-                       *d++ = y0;
-                       *d++ = (u0+u1) >> 1;
-                       *d++ = y1;
-                       *d++ = (v0+v1) >> 1;
-               }
-               if ( width % 2 )
-               {
-                       *alpha++ = *s++;
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       *d++ = y0;
-                       *d++ = u0;
-               }
-       }
-       else
-       for ( i = 0; i < height; i++ )
-       {
-               register uint8_t *s = rgba + ( stride * i );
-               for ( j = 0; j < ( width / 2 ); j++ )
-               {
-                       s++;
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       s++;
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       RGB2YUV (r, g, b, y1, u1 , v1);
-                       *d++ = y0;
-                       *d++ = (u0+u1) >> 1;
-                       *d++ = y1;
-                       *d++ = (v0+v1) >> 1;
-               }
-               if ( width % 2 )
-               {
-                       s++;
-                       r = *s++;
-                       g = *s++;
-                       b = *s++;
-                       RGB2YUV (r, g, b, y0, u0 , v0);
-                       *d++ = y0;
-                       *d++ = u0;
-               }
-       }
-       return ret;
-}
-
-int mlt_convert_yuv420p_to_yuv422( uint8_t *yuv420p, int width, int height, int stride, uint8_t *yuv )
-{
-       int ret = 0;
-       register int i, j;
-
-       int half = width >> 1;
-
-       uint8_t *Y = yuv420p;
-       uint8_t *U = Y + width * height;
-       uint8_t *V = U + width * height / 4;
-
-       register uint8_t *d = yuv;
-
-       for ( i = 0; i < height; i++ )
-       {
-               register uint8_t *u = U + ( i / 2 ) * ( half );
-               register uint8_t *v = V + ( i / 2 ) * ( half );
-
-               for ( j = 0; j < half; j++ )
-               {
-                       *d ++ = *Y ++;
-                       *d ++ = *u ++;
-                       *d ++ = *Y ++;
-                       *d ++ = *v ++;
-               }
-       }
-       return ret;
-}
-
-uint8_t *mlt_resize_alpha( uint8_t *input, int owidth, int oheight, int iwidth, int iheight, uint8_t alpha_value )
-{
-       uint8_t *output = NULL;
-
-       if ( input != NULL && ( iwidth != owidth || iheight != oheight ) && ( owidth > 6 && oheight > 6 ) )
-       {
-               uint8_t *out_line;
-               int offset_x = ( owidth - iwidth ) / 2;
-               int offset_y = ( oheight - iheight ) / 2;
-               int iused = iwidth;
-
-               output = mlt_pool_alloc( owidth * oheight );
-               memset( output, alpha_value, owidth * oheight );
-
-               offset_x -= offset_x % 2;
-
-               out_line = output + offset_y * owidth;
-               out_line += offset_x;
-
-               // Loop for the entirety of our output height.
-               while ( iheight -- )
-               {
-                       // We're in the input range for this row.
-                       memcpy( out_line, input, iused );
-
-                       // Move to next input line
-                       input += iwidth;
-
-                       // Move to next output line
-                       out_line += owidth;
-               }
-       }
-
-       return output;
-}
-
-void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input, int iwidth, int iheight )
-{
-       // Calculate strides
-       int istride = iwidth * 2;
-       int ostride = owidth * 2;
-       int offset_x = ( owidth - iwidth );
-       int offset_y = ( oheight - iheight ) / 2;
-       uint8_t *in_line = input;
-       uint8_t *out_line;
-       int size = owidth * oheight;
-       uint8_t *p = output;
-
-       // Optimisation point
-       if ( output == NULL || input == NULL || ( owidth <= 6 || oheight <= 6 || iwidth <= 6 || oheight <= 6 ) )
-       {
-               return;
-       }
-       else if ( iwidth == owidth && iheight == oheight )
-       {
-               memcpy( output, input, iheight * istride );
-               return;
-       }
-
-       while( size -- )
-       {
-               *p ++ = 16;
-               *p ++ = 128;
-       }
-
-       offset_x -= offset_x % 4;
-
-       out_line = output + offset_y * ostride;
-       out_line += offset_x;
-
-       // Loop for the entirety of our output height.
-       while ( iheight -- )
-       {
-               // We're in the input range for this row.
-               memcpy( out_line, in_line, iwidth * 2 );
-
-               // Move to next input line
-               in_line += istride;
-
-               // Move to next output line
-               out_line += ostride;
-       }
-}
-
-/** A resizing function for yuv422 frames - this does not rescale, but simply
-       resizes. It assumes yuv422 images available on the frame so use with care.
-*/
-
-uint8_t *mlt_frame_resize_yuv422( mlt_frame this, int owidth, int oheight )
-{
-       // Get properties
-       mlt_properties properties = MLT_FRAME_PROPERTIES( this );
-
-       // Get the input image, width and height
-       uint8_t *input = mlt_properties_get_data( properties, "image", NULL );
-       uint8_t *alpha = mlt_frame_get_alpha_mask( this );
-
-       int iwidth = mlt_properties_get_int( properties, "width" );
-       int iheight = mlt_properties_get_int( properties, "height" );
-
-       // If width and height are correct, don't do anything
-       if ( iwidth != owidth || iheight != oheight )
-       {
-               uint8_t alpha_value = mlt_properties_get_int( properties, "resize_alpha" );
-
-               // Create the output image
-               uint8_t *output = mlt_pool_alloc( 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 + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL );
-               mlt_properties_set_int( properties, "width", owidth );
-               mlt_properties_set_int( properties, "height", oheight );
-
-               // We should resize the alpha too
-               alpha = mlt_resize_alpha( alpha, owidth, oheight, iwidth, iheight, alpha_value );
-               if ( alpha != NULL )
-               {
-                       mlt_properties_set_data( properties, "alpha", alpha, owidth * oheight, ( mlt_destructor )mlt_pool_release, NULL );
-                       this->get_alpha_mask = NULL;
-               }
-
-               // Return the output
-               return output;
-       }
-       // No change, return input
-       return input;
-}
-
-/** A rescaling function for yuv422 frames - low quality, and provided for testing
-       only. It assumes yuv422 images available on the frame so use with care.
-*/
-
-uint8_t *mlt_frame_rescale_yuv422( mlt_frame this, int owidth, int oheight )
-{
-       // Get properties
-       mlt_properties properties = MLT_FRAME_PROPERTIES( this );
-
-       // Get the input image, width and height
-       uint8_t *input = mlt_properties_get_data( properties, "image", NULL );
-       int iwidth = mlt_properties_get_int( properties, "width" );
-       int iheight = mlt_properties_get_int( properties, "height" );
-
-       // If width and height are correct, don't do anything
-       if ( iwidth != owidth || iheight != oheight )
-       {
-               // Create the output image
-               uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 );
-
-               // Calculate strides
-               int istride = iwidth * 2;
-               int ostride = owidth * 2;
-
-               iwidth = iwidth - ( iwidth % 4 );
-
-               // Derived coordinates
-               int dy, dx;
-
-       // Calculate ranges
-       int out_x_range = owidth / 2;
-       int out_y_range = oheight / 2;
-       int in_x_range = iwidth / 2;
-       int in_y_range = iheight / 2;
-
-       // Output pointers
-       register uint8_t *out_line = output;
-       register uint8_t *out_ptr;
-
-       // Calculate a middle pointer
-       uint8_t *in_middle = input + istride * in_y_range + in_x_range * 2;
-       uint8_t *in_line;
-
-               // Generate the affine transform scaling values
-               register int scale_width = ( iwidth << 16 ) / owidth;
-               register int scale_height = ( iheight << 16 ) / oheight;
-               register int base = 0;
-
-               int outer = out_x_range * scale_width;
-               int bottom = out_y_range * scale_height;
-
-       // Loop for the entirety of our output height.
-       for ( dy = - bottom; dy < bottom; dy += scale_height )
-       {
-               // Start at the beginning of the line
-               out_ptr = out_line;
-
-               // Pointer to the middle of the input line
-               in_line = in_middle + ( dy >> 16 ) * istride;
-
-               // Loop for the entirety of our output row.
-               for ( dx = - outer; dx < outer; dx += scale_width )
-               {
-                               base = dx >> 15;
-                               base &= 0xfffffffe;
-                               *out_ptr ++ = *( in_line + base );
-                               base &= 0xfffffffc;
-                               *out_ptr ++ = *( in_line + base + 1 );
-                               dx += scale_width;
-                               base = dx >> 15;
-                               base &= 0xfffffffe;
-                               *out_ptr ++ = *( in_line + base );
-                               base &= 0xfffffffc;
-                               *out_ptr ++ = *( in_line + base + 3 );
-               }
-
-               // Move to next output line
-               out_line += ostride;
-       }
-
-               // Now update the frame
-               mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL );
-               mlt_properties_set_int( properties, "width", owidth );
-               mlt_properties_set_int( properties, "height", oheight );
-
-               // Return the output
-               return output;
-       }
-
-       // No change, return input
-       return input;
-}
-
 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;
index bd586a74b35622ba095d1fac2aad1e4fb9801a38..91aa79f435641000dcdeda02e255ce5bce8a0391 100644 (file)
@@ -59,6 +59,7 @@ struct mlt_frame_s
 
        /* Virtual methods */
        uint8_t * ( *get_alpha_mask )( mlt_frame self );
+       int ( *convert_image )( mlt_frame self, uint8_t **image, mlt_image_format *input, mlt_image_format output );
 
        /* Private properties */
        mlt_deque stack_image;
@@ -99,20 +100,11 @@ extern mlt_producer mlt_frame_get_original_producer( mlt_frame self );
 extern void mlt_frame_close( mlt_frame self );
 
 /* convenience functions */
-extern int mlt_convert_yuv422_to_rgb24a( uint8_t *yuv, uint8_t *rgba, unsigned int total );
-extern int mlt_convert_rgb24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha );
-extern int mlt_convert_rgb24_to_yuv422( uint8_t *rgb, int width, int height, int stride, uint8_t *yuv );
-extern int mlt_convert_bgr24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha );
-extern int mlt_convert_argb_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha );
-extern int mlt_convert_bgr24_to_yuv422( uint8_t *rgb, int width, int height, int stride, uint8_t *yuv );
-extern int mlt_convert_yuv420p_to_yuv422( uint8_t *yuv420p, int width, int height, int stride, uint8_t *yuv );
-extern uint8_t *mlt_frame_resize_yuv422( mlt_frame self, int owidth, int oheight );
-extern uint8_t *mlt_frame_rescale_yuv422( mlt_frame self, int owidth, int oheight );
-extern void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input, int iwidth, int iheight );
 extern int mlt_frame_mix_audio( mlt_frame self, mlt_frame that, float weight_start, float weight_end, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples  );
 extern int mlt_frame_combine_audio( mlt_frame self, mlt_frame that, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples  );
 extern int mlt_sample_calculator( float fps, int frequency, int64_t position );
 extern int64_t mlt_sample_calculator_to_now( float fps, int frequency, int64_t position );
+extern const char * mlt_image_format_name( mlt_image_format format );
 
 /** This macro scales rgb into the yuv gamut - y is scaled by 219/255 and uv by 224/255. */
 #define RGB2YUV(r, g, b, y, u, v)\
index 6fb6233ed19ee6cf973889dd4b2a7b2ce6715cff..568b2d71b7fc0ce243b720f541c435b08a09fed0 100644 (file)
@@ -38,11 +38,17 @@ void default_callback( void* ptr, int level, const char* fmt, va_list vl )
        if ( print_prefix && properties )
        {
                char *mlt_type = mlt_properties_get( properties, "mlt_type" );
+               char *mlt_service = mlt_properties_get( properties, "mlt_service" );
                char *resource = mlt_properties_get( properties, "resource" );
        
-               if ( resource && *resource && resource[0] == '<' && resource[ strlen(resource) - 1 ] == '>' )
-                       mlt_type = resource;
-               fprintf( stderr, "[%s @ %p]", mlt_type, ptr );
+               if ( !( resource && *resource && resource[0] == '<' && resource[ strlen(resource) - 1 ] == '>' ) )
+                       mlt_type = mlt_properties_get( properties, "mlt_type" );
+               if ( mlt_service )
+                       fprintf( stderr, "[%s %s] ", mlt_type, mlt_service );
+               else
+                       fprintf( stderr, "[%s %p] ", mlt_type, ptr );
+               if ( resource )
+                       fprintf( stderr, "%s\n    ", resource );
        }
        print_prefix = strstr( fmt, "\n" ) != NULL;
        vfprintf( stderr, fmt, vl );
index 7ca8e49307a9451745a5a4438aa3360558c94d6a..1cee5f9c2f72162bb09f24869e55cf9ccf9ce7c1 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <framework/mlt_filter.h>
 #include <framework/mlt_frame.h>
+#include <framework/mlt_log.h>
 
 // ffmpeg Header files
 #include <avformat.h>
@@ -28,7 +29,6 @@
 #endif
 
 #if LIBAVUTIL_VERSION_INT < (50<<16)
-#define PIX_FMT_RGB32 PIX_FMT_RGBA32
 #define PIX_FMT_YUYV422 PIX_FMT_YUV422
 #endif
 
@@ -53,7 +53,8 @@ static inline int convert_mlt_to_av_cs( mlt_image_format format )
                        value = PIX_FMT_RGB24;
                        break;
                case mlt_image_rgb24a:
-                       value = PIX_FMT_RGB32;
+               case mlt_image_opengl:
+                       value = PIX_FMT_RGBA;
                        break;
                case mlt_image_yuv422:
                        value = PIX_FMT_YUYV422;
@@ -61,16 +62,15 @@ static inline int convert_mlt_to_av_cs( mlt_image_format format )
                case mlt_image_yuv420p:
                        value = PIX_FMT_YUV420P;
                        break;
-               case mlt_image_opengl:
                case mlt_image_none:
-                       fprintf( stderr, "Invalid format...\n" );
+                       mlt_log_error( NULL, "[filter avcolour_space] Invalid format\n" );
                        break;
        }
 
        return value;
 }
 
-static inline void convert_image( uint8_t *out, uint8_t *in, int out_fmt, int in_fmt, int width, int height )
+static inline void av_convert_image( uint8_t *out, uint8_t *in, int out_fmt, int in_fmt, int width, int height )
 {
        AVPicture input;
        AVPicture output;
@@ -90,111 +90,110 @@ static inline void convert_image( uint8_t *out, uint8_t *in, int out_fmt, int in
 /** Do it :-).
 */
 
-static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+// static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, mlt_image_format output_format )
 {
-       mlt_filter filter = mlt_frame_pop_service( this );
-       mlt_properties properties = MLT_FRAME_PROPERTIES( this );
-       int output_format = *format;
-       mlt_image_format forced = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "forced" );
+       mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+       int width = mlt_properties_get_int( properties, "width" );
+       int height = mlt_properties_get_int( properties, "height" );
        int error = 0;
 
-       // Allow this filter to force processing in a colour space other than requested
-       *format = forced != 0 ? forced : *format;
-   
-       error = mlt_frame_get_image( this, image, format, width, height, 0 );
-
-       if ( error == 0 && *format != output_format && *image != NULL && output_format != mlt_image_opengl )
+       if ( *format != output_format )
        {
-               int in_fmt = convert_mlt_to_av_cs( *format );
-               int out_fmt = convert_mlt_to_av_cs( output_format );
-               int size = avpicture_get_size( out_fmt, *width, *height );
-               uint8_t *output = mlt_pool_alloc( size );
-               convert_image( output, *image, out_fmt, in_fmt, *width, *height );
-
-               // Special case for alpha rgb input
-               if ( *format == mlt_image_rgb24a )
+               mlt_log_debug( NULL, "[filter avcolour_space] %s -> %s\n",
+                       mlt_image_format_name( *format ), mlt_image_format_name( output_format ) );
+               if ( output_format != mlt_image_opengl )
                {
-                       register uint8_t *alpha = mlt_frame_get_alpha_mask( this );
-                       register int len = *width * *height;
-                       register uint8_t *bits = *image;
-                       register int n = ( len + 7 ) / 8;
-
-                       if( !is_big_endian( ) )
-                               bits += 3;
-
-                       // Extract alpha mask from the image using Duff's Device
-                       switch( len % 8 )
-                       {
-                               case 0: do { *alpha ++ = *bits; bits += 4;
-                               case 7:          *alpha ++ = *bits; bits += 4;
-                               case 6:          *alpha ++ = *bits; bits += 4;
-                               case 5:          *alpha ++ = *bits; bits += 4;
-                               case 4:          *alpha ++ = *bits; bits += 4;
-                               case 3:          *alpha ++ = *bits; bits += 4;
-                               case 2:          *alpha ++ = *bits; bits += 4;
-                               case 1:          *alpha ++ = *bits; bits += 4;
-                                               }
-                                               while( --n );
-                       }
-               }
-
-               // Update the output
-               *image = output;
-               *format = output_format;
-               mlt_properties_set_data( properties, "image", output, size, mlt_pool_release, NULL );
-               mlt_properties_set_int( properties, "format", output_format );
-
-               // Special case for alpha rgb output
-               if ( *format == mlt_image_rgb24a )
-               {
-                       // Fetch the alpha
-                       register uint8_t *alpha = mlt_frame_get_alpha_mask( this );
-
-                       if ( alpha != NULL )
+                       int in_fmt = convert_mlt_to_av_cs( *format );
+                       int out_fmt = convert_mlt_to_av_cs( output_format );
+                       int size = avpicture_get_size( out_fmt, width, height );
+                       uint8_t *output = mlt_pool_alloc( size );
+                       av_convert_image( output, *image, out_fmt, in_fmt, width, height );
+       
+                       // Special case for alpha rgb input
+                       //if ( *format == mlt_image_rgb24a || *format == mlt_image_opengl )
+if (0)
                        {
+                               register uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
+                               register int len = width * height;
                                register uint8_t *bits = *image;
-                               register int len = *width * *height;
                                register int n = ( len + 7 ) / 8;
-                               
+       
                                if( !is_big_endian( ) )
                                        bits += 3;
-
-                               // Merge the alpha mask into the RGB image using Duff's Device
+       
+                               // Extract alpha mask from the image using Duff's Device
                                switch( len % 8 )
                                {
-                                       case 0: do { *bits = *alpha++; bits += 4;
-                                       case 7:          *bits = *alpha++; bits += 4;
-                                       case 6:          *bits = *alpha++; bits += 4;
-                                       case 5:          *bits = *alpha++; bits += 4;
-                                       case 4:          *bits = *alpha++; bits += 4;
-                                       case 3:          *bits = *alpha++; bits += 4;
-                                       case 2:          *bits = *alpha++; bits += 4;
-                                       case 1:          *bits = *alpha++; bits += 4;
+                                       case 0: do { *alpha ++ = *bits; bits += 4;
+                                       case 7:          *alpha ++ = *bits; bits += 4;
+                                       case 6:          *alpha ++ = *bits; bits += 4;
+                                       case 5:          *alpha ++ = *bits; bits += 4;
+                                       case 4:          *alpha ++ = *bits; bits += 4;
+                                       case 3:          *alpha ++ = *bits; bits += 4;
+                                       case 2:          *alpha ++ = *bits; bits += 4;
+                                       case 1:          *alpha ++ = *bits; bits += 4;
                                                        }
                                                        while( --n );
                                }
                        }
+       
+                       // Update the output
+                       *image = output;
+                       *format = output_format;
+                       mlt_properties_set_data( properties, "image", output, size, mlt_pool_release, NULL );
+                       mlt_properties_set_int( properties, "format", output_format );
+       
+                       // Special case for alpha rgb output
+//                     if ( output_format == mlt_image_rgb24a )
+if (0)
+                       {
+                               // Fetch the alpha
+                               register uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
+       
+                               if ( alpha != NULL )
+                               {
+                                       register uint8_t *bits = *image;
+                                       register int len = width * height;
+                                       register int n = ( len + 7 ) / 8;
+                                       
+                                       if( !is_big_endian( ) )
+                                               bits += 3;
+       
+                                       // Merge the alpha mask into the RGB image using Duff's Device
+                                       switch( len % 8 )
+                                       {
+                                               case 0: do { *bits = *alpha++; bits += 4;
+                                               case 7:          *bits = *alpha++; bits += 4;
+                                               case 6:          *bits = *alpha++; bits += 4;
+                                               case 5:          *bits = *alpha++; bits += 4;
+                                               case 4:          *bits = *alpha++; bits += 4;
+                                               case 3:          *bits = *alpha++; bits += 4;
+                                               case 2:          *bits = *alpha++; bits += 4;
+                                               case 1:          *bits = *alpha++; bits += 4;
+                                                               }
+                                                               while( --n );
+                                       }
+                               }
+                       }
                }
-       }
-       else if ( error == 0 && *format != output_format && *image != NULL && output_format == mlt_image_opengl )
-       {
-               if ( *format == mlt_image_yuv422 )
+               else if ( *format == mlt_image_yuv422 ) // && output_format == mlt_image_opengl
                {
-                       int size = *width * *height * 4;
+                       int size = width * height * 4;
                        uint8_t *output = mlt_pool_alloc( size );
-                       int h = *height;
-                       int w = *width;
+                       int h = height;
+                       int w = width;
                        uint8_t *o = output + size;
                        int ostride = w * 4;
                        uint8_t *p = *image;
-                       uint8_t *alpha = mlt_frame_get_alpha_mask( this ) + *width * *height;
+                       uint8_t *alpha = mlt_frame_get_alpha_mask( frame ) + width * height;
                        int r, g, b;
 
                        while( h -- )
                        {
-                               w = *width;
+                               w = width;
                                o -= ostride;
-                               alpha -= *width;
+                               alpha -= width;
                                while( w >= 2 )
                                {
                                        YUV2RGB( *p, *( p + 1 ), *( p + 3 ), r, g, b );
@@ -211,7 +210,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                                        p += 4;
                                }
                                o -= ostride;
-                               alpha -= *width;
+                               alpha -= width;
                        }
 
                        mlt_properties_set_data( properties, "image", output, size, mlt_pool_release, NULL );
@@ -220,7 +219,6 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                        *format = output_format;
                }
        }
-
        return error;
 }
 
@@ -229,8 +227,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 
 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
 {
-       mlt_frame_push_service( frame, this );
-       mlt_frame_push_get_image( frame, filter_get_image );
+       frame->convert_image = convert_image;
        return frame;
 }
 
index d4afa3509506cc3ae59f800a485af44fe6530aef..4a46ce4b862baa29723dd7df8066505d0d65e484 100644 (file)
@@ -307,7 +307,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                 writable = !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" );
 
        // Get the input image
-       error = mlt_frame_get_image( this, image, format, width, height, writable );
+       *format = mlt_image_yuv422;
+       error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
        // Check that we want progressive and we aren't already progressive
        if ( deinterlace && *format == mlt_image_yuv422 && *image != NULL && !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" ) )
@@ -316,11 +317,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                AVPicture *output = mlt_pool_alloc( sizeof( AVPicture ) );
 
                // Fill the picture
-               if ( *format == mlt_image_yuv422 )
-               {
-                       avpicture_fill( output, *image, PIX_FMT_YUYV422, *width, *height );
-                       mlt_avpicture_deinterlace( output, output, PIX_FMT_YUYV422, *width, *height );
-               }
+               avpicture_fill( output, *image, PIX_FMT_YUYV422, *width, *height );
+               mlt_avpicture_deinterlace( output, output, PIX_FMT_YUYV422, *width, *height );
 
                // Free the picture
                mlt_pool_release( output );
index d1266aeaeed5c97d5285d915ef685ce75855a3a0..a3ef5253330c8723aa73bfcf8709eeb772070fa4 100644 (file)
 #define PIX_FMT_YUYV422 PIX_FMT_YUV422
 #endif
 
-static inline int is_big_endian( )
-{
-       union { int i; char c[ 4 ]; } big_endian_test;
-       big_endian_test.i = 1;
-
-       return big_endian_test.c[ 0 ] != 1;
-}
-
 static inline int convert_mlt_to_av_cs( mlt_image_format format )
 {
        int value = 0;
@@ -56,6 +48,7 @@ static inline int convert_mlt_to_av_cs( mlt_image_format format )
                        value = PIX_FMT_RGB24;
                        break;
                case mlt_image_rgb24a:
+               case mlt_image_opengl:
                        value = PIX_FMT_RGB32;
                        break;
                case mlt_image_yuv422:
@@ -64,7 +57,6 @@ static inline int convert_mlt_to_av_cs( mlt_image_format format )
                case mlt_image_yuv420p:
                        value = PIX_FMT_YUV420P;
                        break;
-               case mlt_image_opengl:
                case mlt_image_none:
                        fprintf( stderr, "Invalid format...\n" );
                        break;
@@ -73,7 +65,7 @@ static inline int convert_mlt_to_av_cs( mlt_image_format format )
        return value;
 }
 
-static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight )
+static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight )
 {
        // Get the properties
        mlt_properties properties = MLT_FRAME_PROPERTIES( this );
@@ -102,35 +94,37 @@ static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iform
        else if ( strcmp( interps, "spline" ) == 0 )
                interp = SWS_SPLINE;
 
-       AVPicture input;
-       AVPicture output;
-       uint8_t *outbuf = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 );
+       // Determine the bytes per pixel
+       int bpp;
+       switch ( *format )
+       {
+               case mlt_image_yuv422:
+                       bpp = 2;
+                       break;
+               case mlt_image_rgb24:
+                       bpp = 3;
+                       break;
+               case mlt_image_rgb24a:
+               case mlt_image_opengl:
+                       bpp = 4;
+                       break;
+               default:
+                       // XXX: we only know how to rescale packed formats
+                       return 1;
+       }
 
        // Convert the pixel formats
-       iformat = convert_mlt_to_av_cs( iformat );
-       oformat = convert_mlt_to_av_cs( oformat );
-
-       avpicture_fill( &input, *image, iformat, iwidth, iheight );
-       avpicture_fill( &output, outbuf, oformat, owidth, oheight );
+       int avformat = convert_mlt_to_av_cs( *format );
 
-       // Extract the alpha channel
-       if ( iformat == PIX_FMT_RGB32 && oformat == PIX_FMT_YUYV422 )
-       {
-               // Allocate the alpha mask
-               uint8_t *alpha = mlt_pool_alloc( iwidth * ( iheight + 1 ) );
-               if ( alpha )
-               {
-                       // Convert the image and extract alpha
-                       mlt_convert_rgb24a_to_yuv422( *image, iwidth, iheight, iwidth * 4, outbuf, alpha );
-                       mlt_properties_set_data( properties, "alpha", alpha, iwidth * ( iheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL );
-                       iformat = PIX_FMT_YUYV422;
-                       avpicture_fill( &input, outbuf, iformat, iwidth, iheight );
-                       avpicture_fill( &output, *image, oformat, owidth, oheight );
-               }
-       }
+       // Fill out the AVPictures
+       AVPicture input;
+       AVPicture output;
+       uint8_t *outbuf = mlt_pool_alloc( owidth * ( oheight + 1 ) * bpp );
+       avpicture_fill( &input, *image, avformat, iwidth, iheight );
+       avpicture_fill( &output, outbuf, avformat, owidth, oheight );
 
        // Create the context and output image
-       struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL);
+       struct SwsContext *context = sws_getContext( iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
        assert(context);
 
        // Perform the scaling
@@ -138,7 +132,7 @@ static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iform
        sws_freeContext( context );
 
        // Now update the frame
-       mlt_properties_set_data( properties, "image", output.data[0], owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL );
+       mlt_properties_set_data( properties, "image", output.data[0], owidth * ( oheight + 1 ) * bpp, ( mlt_destructor )mlt_pool_release, NULL );
        mlt_properties_set_int( properties, "width", owidth );
        mlt_properties_set_int( properties, "height", oheight );
 
@@ -154,11 +148,11 @@ static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iform
                uint8_t *alpha = mlt_frame_get_alpha_mask( this );
                if ( alpha )
                {
-                       iformat = oformat = PIX_FMT_GRAY8;
-                       struct SwsContext *context = sws_getContext( iwidth, iheight, iformat, owidth, oheight, oformat, interp, NULL, NULL, NULL);
-                       avpicture_fill( &input, alpha, iformat, iwidth, iheight );
+                       avformat = PIX_FMT_GRAY8;
+                       struct SwsContext *context = sws_getContext( iwidth, iheight, avformat, owidth, oheight, avformat, interp, NULL, NULL, NULL);
+                       avpicture_fill( &input, alpha, avformat, iwidth, iheight );
                        outbuf = mlt_pool_alloc( owidth * oheight );
-                       avpicture_fill( &output, outbuf, oformat, owidth, oheight );
+                       avpicture_fill( &output, outbuf, avformat, owidth, oheight );
 
                        // Perform the scaling
                        sws_scale( context, input.data, input.linesize, 0, iheight, output.data, output.linesize);
index caaaaebf56e7b92c5fabe0f625a8a141e2a1d361..5b2919dc82e7989db24bb4a8bf993f04abab77a1 100644 (file)
@@ -41,6 +41,7 @@
 #include <pthread.h>
 
 #if LIBAVUTIL_VERSION_INT < (50<<16)
+#define PIX_FMT_RGB32 PIX_FMT_RGBA32
 #define PIX_FMT_YUYV422 PIX_FMT_YUV422
 #endif
 
@@ -611,6 +612,16 @@ static inline void convert_image( AVFrame *frame, uint8_t *buffer, int pix_fmt,
                        output.data, output.linesize);
                sws_freeContext( context );
        }
+       else if ( *format == mlt_image_rgb24a || *format == mlt_image_opengl )
+       {
+               struct SwsContext *context = sws_getContext( width, height, pix_fmt,
+                       width, height, PIX_FMT_RGBA, SWS_FAST_BILINEAR, NULL, NULL, NULL);
+               AVPicture output;
+               avpicture_fill( &output, buffer, PIX_FMT_RGBA, width, height );
+               sws_scale( context, frame->data, frame->linesize, 0, height,
+                       output.data, output.linesize);
+               sws_freeContext( context );
+       }
        else
        {
                struct SwsContext *context = sws_getContext( width, height, pix_fmt,
@@ -639,6 +650,12 @@ static inline void convert_image( AVFrame *frame, uint8_t *buffer, int pix_fmt,
                avpicture_fill( &output, buffer, PIX_FMT_RGB24, width, height );
                img_convert( &output, PIX_FMT_RGB24, (AVPicture *)frame, pix_fmt, width, height );
        }
+       else if ( format == mlt_image_rgb24a || format == mlt_image_opengl )
+       {
+               AVPicture output;
+               avpicture_fill( &output, buffer, PIX_FMT_RGB32, width, height );
+               img_convert( &output, PIX_FMT_RGB32, (AVPicture *)frame, pix_fmt, width, height );
+       }
        else
        {
                AVPicture output;
@@ -673,6 +690,10 @@ static int allocate_buffer( mlt_properties frame_properties, AVCodecContext *cod
                case mlt_image_rgb24:
                        size = *width * ( *height + 1 ) * 3;
                        break;
+               case mlt_image_rgb24a:
+               case mlt_image_opengl:
+                       size = *width * ( *height + 1 ) * 4;
+                       break;
                default:
                        *format = mlt_image_yuv422;
                        size = *width * ( *height + 1 ) * 2;
@@ -881,7 +902,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                                if ( allocate_buffer( frame_properties, codec_context, buffer, format, width, height ) )
                                {
                                        convert_image( av_frame, *buffer, codec_context->pix_fmt, format, *width, *height );
-                                       mlt_properties_set_int( frame_properties, "progressive", !av_frame->interlaced_frame );
+                                       if ( !mlt_properties_get( properties, "force_progressive" ) )
+                                               mlt_properties_set_int( frame_properties, "progressive", !av_frame->interlaced_frame );
                                        mlt_properties_set_int( properties, "top_field_first", av_frame->top_field_first );
                                        mlt_properties_set_int( properties, "_current_position", int_position );
                                        mlt_properties_set_int( properties, "_got_picture", 1 );
@@ -1062,6 +1084,8 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
                        mlt_properties_set_int( frame_properties, "real_width", codec_context->width );
                        mlt_properties_set_int( frame_properties, "real_height", codec_context->height );
                        mlt_properties_set_double( frame_properties, "aspect_ratio", aspect_ratio );
+                       if ( mlt_properties_get( properties, "force_progressive" ) )
+                               mlt_properties_set_int( frame_properties, "progressive", mlt_properties_get_int( properties, "force_progressive" ) );
 
                        mlt_frame_push_get_image( frame, producer_get_image );
                        mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
index 3572821a9bbee715f4c1a4210417dcd66d4893c4..3d7c7024d884c0a8ef19af51b0c6350ec3f14f05 100644 (file)
@@ -16,6 +16,7 @@ OBJS = factory.o \
           filter_data_show.o \
           filter_gamma.o \
           filter_greyscale.o \
+          filter_imageconvert.o \
           filter_luma.o \
           filter_mirror.o \
           filter_mono.o \
index 5d84e1322546b9336d7f38006f04562f1722e4a4..e6ae88965203641ffad284ccf60c50861f78c89d 100644 (file)
@@ -29,6 +29,7 @@ extern mlt_filter filter_data_feed_init( mlt_profile profile, mlt_service_type t
 extern mlt_filter filter_data_show_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
 extern mlt_filter filter_gamma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
 extern mlt_filter filter_greyscale_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
+extern mlt_filter filter_imageconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
 extern mlt_filter filter_luma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
 extern mlt_filter filter_mirror_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
 extern mlt_filter filter_mono_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg );
@@ -60,6 +61,7 @@ MLT_REPOSITORY
        MLT_REGISTER( filter_type, "gamma", filter_gamma_init );
        MLT_REGISTER( filter_type, "greyscale", filter_greyscale_init );
        MLT_REGISTER( filter_type, "grayscale", filter_greyscale_init );
+       MLT_REGISTER( filter_type, "imageconvert", filter_imageconvert_init );
        MLT_REGISTER( filter_type, "luma", filter_luma_init );
        MLT_REGISTER( filter_type, "mirror", filter_mirror_init );
        MLT_REGISTER( filter_type, "mono", filter_mono_init );
index 07dce1c8160cdeef12d00a9cf194dc58c2187f31..891f4b39864cee627dc1eb2d01417cb34d3965ed 100644 (file)
 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
 {
        // Get the image
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
        // Only process if we have no error and a valid colour space
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                // Get the brightness level
                double level = mlt_properties_get_double( MLT_FRAME_PROPERTIES( this ), "brightness" );
index 9068144a37b13d830dadac4d6c8f8abc53b88e51..ca1668f71359d6b7ee53941b3a179c3f2573ba7c 100644 (file)
@@ -58,19 +58,23 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                *height = mlt_properties_get_int( properties, "normalised_height" );
        }
 
-       // Now get the image
-       error = mlt_frame_get_image( this, image, format, width, height, writable );
-
        int left    = mlt_properties_get_int( properties, "crop.left" );
        int right   = mlt_properties_get_int( properties, "crop.right" );
        int top     = mlt_properties_get_int( properties, "crop.top" );
        int bottom  = mlt_properties_get_int( properties, "crop.bottom" );
+
+       // We only know how to process yuv422 at the moment
+       if ( left || right || top || bottom )
+               *format = mlt_image_yuv422;
+
+       // Now get the image
+       error = mlt_frame_get_image( this, image, format, width, height, writable );
+
        int owidth  = *width - left - right;
        int oheight = *height - top - bottom;
 
-       // We only know how to process yuv422 at the moment
        if ( ( owidth != *width || oheight != *height ) &&
-               error == 0 && *format == mlt_image_yuv422 && *image != NULL && owidth > 0 && oheight > 0 )
+               error == 0 && *image != NULL && owidth > 0 && oheight > 0 )
        {
                // Provides a manual override for misreported field order
                if ( mlt_properties_get( properties, "meta.top_field_first" ) )
index e4fe15b3dd491c4c0389519f79dcd88618722ef2..08cfdcaab8a901ae099a8d6613049d9df170d4d3 100644 (file)
 
 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
 {
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                // Get the gamma value
                double gamma = mlt_properties_get_double( MLT_FRAME_PROPERTIES( this ), "gamma" );
index fd618c09aa02140c0e42dfbebde81b196f4fc466..4d25abccb48e04d16482505467b842c5995813b8 100644 (file)
@@ -29,8 +29,9 @@
 
 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
 {
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                uint8_t *p = *image;
                uint8_t *q = *image + *width * *height * 2;
diff --git a/src/modules/core/filter_imageconvert.c b/src/modules/core/filter_imageconvert.c
new file mode 100644 (file)
index 0000000..dc07db7
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * filter_imageconvert.c -- colorspace and pixel format converter
+ * Copyright (C) 2009 Ushodaya Enterprises Limited
+ * Author: Dan Dennedy <dan@dennedy.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <framework/mlt_filter.h>
+#include <framework/mlt_frame.h>
+#include <framework/mlt_log.h>
+#include <framework/mlt_pool.h>
+
+#include <stdlib.h>
+
+
+static int convert_yuv422_to_rgb24a( uint8_t *yuv, uint8_t *rgba, unsigned int total )
+{
+       int ret = 0;
+       int yy, uu, vv;
+       int r,g,b;
+       total /= 2;
+       while (total--)
+       {
+               yy = yuv[0];
+               uu = yuv[1];
+               vv = yuv[3];
+               YUV2RGB(yy, uu, vv, r, g, b);
+               rgba[0] = r;
+               rgba[1] = g;
+               rgba[2] = b;
+               rgba[3] = 255;
+               yy = yuv[2];
+               YUV2RGB(yy, uu, vv, r, g, b);
+               rgba[4] = r;
+               rgba[5] = g;
+               rgba[6] = b;
+               rgba[7] = 255;
+               yuv += 4;
+               rgba += 8;
+       }
+       return ret;
+}
+
+static int convert_yuv422_to_rgb24( uint8_t *yuv, uint8_t *rgb, unsigned int total )
+{
+       int ret = 0;
+       int yy, uu, vv;
+       int r,g,b;
+       total /= 2;
+       while (total--) 
+       {
+               yy = yuv[0];
+               uu = yuv[1];
+               vv = yuv[3];
+               YUV2RGB(yy, uu, vv, r, g, b);
+               rgb[0] = r;
+               rgb[1] = g;
+               rgb[2] = b;
+               yy = yuv[2];
+               YUV2RGB(yy, uu, vv, r, g, b);
+               rgb[3] = r;
+               rgb[4] = g;
+               rgb[5] = b;
+               yuv += 4;
+               rgb += 6;
+       }
+       return ret;
+}
+
+static int convert_rgb24a_to_yuv422( uint8_t *rgba, int width, int height, int stride, uint8_t *yuv, uint8_t *alpha )
+{
+       int ret = 0;
+       register int y0, y1, u0, u1, v0, v1;
+       register int r, g, b;
+       register uint8_t *d = yuv;
+       register int i, j;
+
+       if ( alpha )
+       for ( i = 0; i < height; i++ )
+       {
+               register uint8_t *s = rgba + ( stride * i );
+               for ( j = 0; j < ( width / 2 ); j++ )
+               {
+                       r = *s++;
+                       g = *s++;
+                       b = *s++;
+                       *alpha++ = *s++;
+                       RGB2YUV (r, g, b, y0, u0 , v0);
+                       r = *s++;
+                       g = *s++;
+                       b = *s++;
+                       *alpha++ = *s++;
+                       RGB2YUV (r, g, b, y1, u1 , v1);
+                       *d++ = y0;
+                       *d++ = (u0+u1) >> 1;
+                       *d++ = y1;
+                       *d++ = (v0+v1) >> 1;
+               }
+               if ( width % 2 )
+               {
+                       r = *s++;
+                       g = *s++;
+                       b = *s++;
+                       *alpha++ = *s++;
+                       RGB2YUV (r, g, b, y0, u0 , v0);
+                       *d++ = y0;
+                       *d++ = u0;
+               }
+       }
+       else
+       for ( i = 0; i < height; i++ )
+       {
+               register uint8_t *s = rgba + ( stride * i );
+               for ( j = 0; j < ( width / 2 ); j++ )
+               {
+                       r = *s++;
+                       g = *s++;
+                       b = *s++;
+                       s++;
+                       RGB2YUV (r, g, b, y0, u0 , v0);
+                       r = *s++;
+                       g = *s++;
+                       b = *s++;
+                       s++;
+                       RGB2YUV (r, g, b, y1, u1 , v1);
+                       *d++ = y0;
+                       *d++ = (u0+u1) >> 1;
+                       *d++ = y1;
+                       *d++ = (v0+v1) >> 1;
+               }
+               if ( width % 2 )
+               {
+                       r = *s++;
+                       g = *s++;
+                       b = *s++;
+                       s++;
+                       RGB2YUV (r, g, b, y0, u0 , v0);
+                       *d++ = y0;
+                       *d++ = u0;
+               }
+       }
+
+       return ret;
+}
+
+static int convert_rgb24_to_yuv422( uint8_t *rgb, int width, int height, int stride, uint8_t *yuv )
+{
+       int ret = 0;
+       register int y0, y1, u0, u1, v0, v1;
+       register int r, g, b;
+       register uint8_t *d = yuv;
+       register int i, j;
+
+       for ( i = 0; i < height; i++ )
+       {
+               register uint8_t *s = rgb + ( stride * i );
+               for ( j = 0; j < ( width / 2 ); j++ )
+               {
+                       r = *s++;
+                       g = *s++;
+                       b = *s++;
+                       RGB2YUV (r, g, b, y0, u0 , v0);
+                       r = *s++;
+                       g = *s++;
+                       b = *s++;
+                       RGB2YUV (r, g, b, y1, u1 , v1);
+                       *d++ = y0;
+                       *d++ = (u0+u1) >> 1;
+                       *d++ = y1;
+                       *d++ = (v0+v1) >> 1;
+               }
+               if ( width % 2 )
+               {
+                       r = *s++;
+                       g = *s++;
+                       b = *s++;
+                       RGB2YUV (r, g, b, y0, u0 , v0);
+                       *d++ = y0;
+                       *d++ = u0;
+               }
+       }
+       return ret;
+}
+
+static int convert_yuv420p_to_yuv422( uint8_t *yuv420p, int width, int height, uint8_t *yuv )
+{
+       int ret = 0;
+       register int i, j;
+
+       int half = width >> 1;
+
+       uint8_t *Y = yuv420p;
+       uint8_t *U = Y + width * height;
+       uint8_t *V = U + width * height / 4;
+
+       register uint8_t *d = yuv;
+
+       for ( i = 0; i < height; i++ )
+       {
+               register uint8_t *u = U + ( i / 2 ) * ( half );
+               register uint8_t *v = V + ( i / 2 ) * ( half );
+
+               for ( j = 0; j < half; j++ )
+               {
+                       *d ++ = *Y ++;
+                       *d ++ = *u ++;
+                       *d ++ = *Y ++;
+                       *d ++ = *v ++;
+               }
+       }
+       return ret;
+}
+
+static int convert_rgb24_to_rgb24a( uint8_t *rgb, uint8_t *rgba, int total )
+{
+       uint8_t *s = rgb;
+       uint8_t *d = rgba;
+       while ( total-- )
+       {
+               *d++ = s[0];
+               *d++ = s[1];
+               *d++ = s[2];
+               *d++ = 0xff;
+               s += 3;
+       }
+       return 0;
+}
+
+static int convert_rgb24a_to_rgb24( uint8_t *rgba, uint8_t *rgb, int total, uint8_t *alpha )
+{
+       uint8_t *s = rgba;
+       uint8_t *d = rgb;
+       while ( total-- )
+       {
+               *d++ = s[0];
+               *d++ = s[1];
+               *d++ = s[2];
+               *alpha++ = s[3];
+               s += 4;
+       }
+       return 0;
+}
+
+static int convert_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, mlt_image_format requested_format )
+{
+       int error = 0;
+       mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+       int width = mlt_properties_get_int( properties, "width" );
+       int height = mlt_properties_get_int( properties, "height" );
+
+       if ( *format != requested_format )
+       {
+               mlt_log_debug( NULL, "[filter imageconvert] %s -> %s\n",
+                       mlt_image_format_name( *format ), mlt_image_format_name( requested_format ) );
+               switch ( *format )
+               {
+               case mlt_image_yuv422:
+                       switch ( requested_format )
+                       {
+                       case mlt_image_rgb24:
+                       {
+                               uint8_t *rgb = mlt_pool_alloc( width * height * 3 );
+                               error = convert_yuv422_to_rgb24( *buffer, rgb, width * height );
+                               if ( error )
+                               {
+                                       mlt_pool_release( rgb );
+                               }
+                               else
+                               {
+                                       mlt_properties_set_data( properties, "image", rgb, width * height * 3, mlt_pool_release, NULL );
+                                       *buffer = rgb;
+                                       *format = mlt_image_rgb24;
+                               }
+                               break;
+                       }
+                       case mlt_image_rgb24a:
+                       case mlt_image_opengl:
+                       {
+                               uint8_t *rgba = mlt_pool_alloc( width * height * 4 );
+                               error = convert_yuv422_to_rgb24a( *buffer, rgba, width * height );
+                               if ( error )
+                               {
+                                       mlt_pool_release( rgba );
+                               }
+                               else
+                               {
+                                       mlt_properties_set_data( properties, "image", rgba, width * height * 4, mlt_pool_release, NULL );
+                                       *buffer = rgba;
+                                       *format = requested_format;
+                               }
+                               break;
+                       }
+                       default:
+                               error = 1;
+                       }
+                       break;
+               case mlt_image_rgb24:
+                       switch ( requested_format )
+                       {
+                       case mlt_image_yuv422:
+                       {
+                               uint8_t *yuv = mlt_pool_alloc( width * height * 2 );
+                               error = convert_rgb24_to_yuv422( *buffer, width, height, width * 3, yuv );
+                               if ( error )
+                               {
+                                       mlt_pool_release( yuv );
+                               }
+                               else
+                               {
+                                       mlt_properties_set_data( properties, "image", yuv, width * height * 2, mlt_pool_release, NULL );
+                                       *buffer = yuv;
+                                       *format = mlt_image_yuv422;
+                               }
+                               break;
+                       }
+                       case mlt_image_rgb24a:
+                       case mlt_image_opengl:
+                       {
+                               uint8_t *rgba = mlt_pool_alloc( width * height * 4 );
+                               error = convert_rgb24_to_rgb24a( *buffer, rgba, width * height );
+                               if ( error )
+                               {
+                                       mlt_pool_release( rgba );
+                               }
+                               else
+                               {
+                                       mlt_properties_set_data( properties, "image", rgba, width * height * 4, mlt_pool_release, NULL );
+                                       *buffer = rgba;
+                                       *format = requested_format;
+                               }
+                               break;
+                       }
+                       default:
+                               error = 1;
+                       }
+                       break;
+               case mlt_image_rgb24a:
+               case mlt_image_opengl:
+                       switch ( requested_format )
+                       {
+                       case mlt_image_yuv422:
+                       {
+                               uint8_t *yuv = mlt_pool_alloc( width * height * 2 );
+                               uint8_t *alpha = mlt_pool_alloc( width * height );
+                               error = convert_rgb24a_to_yuv422( *buffer, width, height, width * 4, yuv, alpha );
+                               if ( error )
+                               {
+                                       mlt_pool_release( yuv );
+                                       mlt_pool_release( alpha );
+                               }
+                               else
+                               {
+                                       mlt_properties_set_data( properties, "image", yuv, width * height * 2, mlt_pool_release, NULL );
+                                       mlt_properties_set_data( properties, "alpha", alpha, width * height, mlt_pool_release, NULL );
+                                       *buffer = yuv;
+                                       *format = mlt_image_yuv422;
+                               }
+                               break;
+                       }
+                       case mlt_image_rgb24:
+                       {
+                               uint8_t *rgb = mlt_pool_alloc( width * height * 3 );
+                               uint8_t *alpha = mlt_pool_alloc( width * height );
+                               error = convert_rgb24a_to_rgb24( *buffer, rgb, width * height, alpha );
+                               if ( error )
+                               {
+                                       mlt_pool_release( rgb );
+                                       mlt_pool_release( alpha );
+                               }
+                               else
+                               {
+                                       mlt_properties_set_data( properties, "image", rgb, width * height * 3, mlt_pool_release, NULL );
+                                       mlt_properties_set_data( properties, "alpha", alpha, width * height, mlt_pool_release, NULL );
+                                       *buffer = rgb;
+                                       *format = mlt_image_rgb24;
+                               }
+                               break;
+                       }
+                       case mlt_image_rgb24a:
+                       case mlt_image_opengl:
+                               *format = requested_format;
+                               break;
+                       default:
+                               error = 1;
+                       }
+                       break;
+               case mlt_image_yuv420p:
+                       switch ( requested_format )
+                       {
+                       case mlt_image_rgb24:
+                       case mlt_image_rgb24a:
+                       case mlt_image_opengl:
+                       case mlt_image_yuv422:
+                       {
+                               uint8_t *yuv = mlt_pool_alloc( width * height * 2 );
+                               int error = convert_yuv420p_to_yuv422( *buffer, width, height, yuv );
+                               if ( error )
+                               {
+                                       mlt_pool_release( yuv );
+                               }
+                               else
+                               {
+                                       mlt_properties_set_data( properties, "image", yuv, width * height * 2, mlt_pool_release, NULL );
+                                       *buffer = yuv;
+                                       *format = mlt_image_yuv422;
+                               }
+                               switch ( requested_format )
+                               {
+                               case mlt_image_yuv422:
+                                       break;
+                               case mlt_image_rgb24:
+                               case mlt_image_rgb24a:
+                               case mlt_image_opengl:
+                                       error = convert_image( frame, buffer, format, requested_format );
+                                       break;
+                               default:
+                                       error = 1;
+                                       break;
+                               }
+                               break;
+                       }
+                       default:
+                               error = 1;
+                       }
+                       break;
+               default:
+                       error = 1;
+               }
+       }
+       if ( !error )
+               mlt_properties_set_int( properties, "format", *format );
+
+       return error;
+}
+
+/** Filter processing.
+*/
+
+static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+{
+       frame->convert_image = convert_image;
+       return frame;
+}
+
+/** Constructor for the filter.
+*/
+
+mlt_filter filter_imageconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
+{
+       mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 );
+       if ( mlt_filter_init( this, this ) == 0 )
+       {
+               this->process = filter_process;
+       }
+       return this;
+}
index f05d6c405d06502080116b73c9ac9374db690052..04f52a2a8ec534e8d35be7caa0b9174eae188c3b 100644 (file)
@@ -43,6 +43,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        
        if ( out == 0 )
                out = 24;
+       *format = mlt_image_yuv422;
 
        if ( b_frame == NULL || mlt_properties_get_int( b_frame_props, "width" ) != *width || mlt_properties_get_int( b_frame_props, "height" ) != *height )
        {
index 3dd6dbfc11cc1428bc68b64bcd5fcd8c620fbcbe..813aeef87b54b72593ae734b40f28fe449418b21 100644 (file)
@@ -43,13 +43,14 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
        int reverse = mlt_properties_get_int( properties, "reverse" );
 
        // Get the image
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( frame, image, format, width, height, 1 );
 
        // Get the alpha
        uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
 
        // If we have an image of the right colour space
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                // We'll KISS here
                int hh = *height / 2;
index 7256f6ccac9b9bb4782429081ef843e4f85f63d0..8ccebba522b0357a9d257df55634cc89528cb55e 100644 (file)
@@ -236,10 +236,11 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
        mlt_filter this = mlt_frame_pop_service( frame );
 
        // Get the image from the frame
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( frame, image, format, width, height, 1 );
 
        // Get the image from the frame
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                if ( this != NULL )
                {
index f4594d8bc61b4c0ba1b39c00240f698ea12ecbab..540e0ca6ff9f1fa0497ded099c1b2437f0d58e94 100644 (file)
 
 #include <framework/mlt_filter.h>
 #include <framework/mlt_frame.h>
+#include <framework/mlt_log.h>
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <math.h>
 
-typedef int ( *image_scaler )( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight );
+/** virtual function declaration for an image scaler
+ *
+ * image scaler implementations are expected to support the following in and out formats:
+ * yuv422 -> yuv422
+ * rgb24 -> rgb24
+ * rgb24a -> rgb24a
+ * rgb24 -> yuv422
+ * rgb24a -> yuv422
+ */
 
-static void scale_alpha( mlt_frame this, int iwidth, int iheight, int owidth, int oheight );
+typedef int ( *image_scaler )( mlt_frame this, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight );
 
-static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight )
+static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight )
 {
        // Get the properties
        mlt_properties properties = MLT_FRAME_PROPERTIES( this );
 
-       // Get the rescaling interpolsation
-       char *interps = mlt_properties_get( properties, "rescale.interp" );
+       // Convert the image to yuv422
+       *format = mlt_image_yuv422;
+       mlt_frame_get_image( this, image, format, &iwidth, &iheight, 0 );
 
-       // Carry out the rescaling
-       if ( iformat == mlt_image_yuv422 && oformat == mlt_image_yuv422 )
-       {
-               // Scale the frame
-               mlt_frame_rescale_yuv422( this, owidth, oheight );
-               
-               // Return the output
-               *image = mlt_properties_get_data( properties, "image", NULL );
-       }
-       else if ( iformat == mlt_image_rgb24 || iformat == mlt_image_rgb24a )
-       {
-               int bpp = (iformat == mlt_image_rgb24a ? 4 : 3 );
-                       
-               // Create the yuv image
-               uint8_t *output = mlt_pool_alloc( iwidth * ( iheight + 1 ) * 2 );
+       // Create the output image
+       uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 );
 
-               if ( strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) )
-               {
-                       // Extract YUV422 and alpha
-                       if ( bpp == 4 )
-                       {
-                               // Allocate the alpha mask
-                               uint8_t *alpha = mlt_pool_alloc( iwidth * ( iheight + 1 ) );
+       // Calculate strides
+       int istride = iwidth * 2;
+       int ostride = owidth * 2;
+       iwidth = iwidth - ( iwidth % 4 );
 
-                               // Convert the image and extract alpha
-                               mlt_convert_rgb24a_to_yuv422( *image, iwidth, iheight, iwidth * 4, output, alpha );
+       // Derived coordinates
+       int dy, dx;
 
-                               mlt_properties_set_data( properties, "alpha", alpha, iwidth * ( iheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL );
+       // Calculate ranges
+       int out_x_range = owidth / 2;
+       int out_y_range = oheight / 2;
+       int in_x_range = iwidth / 2;
+       int in_y_range = iheight / 2;
 
-                               scale_alpha( this, iwidth, iheight, owidth, oheight );
-                       }
-                       else
-                       {
-                               // No alpha to extract
-                               mlt_convert_rgb24_to_yuv422( *image, iwidth, iheight, iwidth * 3, output );
-                       }
+       // Output pointers
+       register uint8_t *out_line = output;
+       register uint8_t *out_ptr;
 
-                       mlt_properties_set_data( properties, "image", output, iwidth * ( iheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL );
+       // Calculate a middle pointer
+       uint8_t *in_middle = *image + istride * in_y_range + in_x_range * 2;
+       uint8_t *in_line;
 
-                       // Scale the frame
-                       output = mlt_frame_rescale_yuv422( this, owidth, oheight );
+       // Generate the affine transform scaling values
+       register int scale_width = ( iwidth << 16 ) / owidth;
+       register int scale_height = ( iheight << 16 ) / oheight;
+       register int base = 0;
 
-               }
-               else
-               {
-                       // Extract YUV422 and alpha
-                       if ( bpp == 4 )
-                       {
-                               // Allocate the alpha mask
-                               uint8_t *alpha = mlt_pool_alloc( owidth * ( oheight + 1 ) );
+       int outer = out_x_range * scale_width;
+       int bottom = out_y_range * scale_height;
 
-                               // Convert the image and extract alpha
-                               mlt_convert_rgb24a_to_yuv422( *image, owidth, oheight, owidth * 4, output, alpha );
+       // Loop for the entirety of our output height.
+       for ( dy = - bottom; dy < bottom; dy += scale_height )
+       {
+               // Start at the beginning of the line
+               out_ptr = out_line;
 
-                               mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL );
+               // Pointer to the middle of the input line
+               in_line = in_middle + ( dy >> 16 ) * istride;
 
-                               scale_alpha( this, iwidth, iheight, owidth, oheight );
-                       }
-                       else
-                       {
-                               // No alpha to extract
-                               mlt_convert_rgb24_to_yuv422( *image, owidth, oheight, owidth * 3, output );
-                       }
+               // Loop for the entirety of our output row.
+               for ( dx = - outer; dx < outer; dx += scale_width )
+               {
+                       base = dx >> 15;
+                       base &= 0xfffffffe;
+                       *out_ptr ++ = *( in_line + base );
+                       base &= 0xfffffffc;
+                       *out_ptr ++ = *( in_line + base + 1 );
+                       dx += scale_width;
+                       base = dx >> 15;
+                       base &= 0xfffffffe;
+                       *out_ptr ++ = *( in_line + base );
+                       base &= 0xfffffffc;
+                       *out_ptr ++ = *( in_line + base + 3 );
                }
-
-               // Now update the frame
-               mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL );
-               mlt_properties_set_int( properties, "width", owidth );
-               mlt_properties_set_int( properties, "height", oheight );
-
-               *image = output;
+               // Move to next output line
+               out_line += ostride;
        }
+       // Now update the frame
+       mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor ) mlt_pool_release, NULL );
+       mlt_properties_set_int( properties, "width", owidth );
+       mlt_properties_set_int( properties, "height", oheight );
 
+       *image = output;
        return 0;
 }
 
@@ -172,7 +176,6 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                int owidth = *width;
                int oheight = *height;
                char *interps = mlt_properties_get( properties, "rescale.interp" );
-               int wanted_format = *format;
 
                // Default from the scaler if not specifed on the frame
                if ( interps == NULL )
@@ -189,7 +192,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                }
        
                // Let the producer know what we are actually requested to obtain
-               if ( *format == mlt_image_yuv422 && strcmp( interps, "none" ) )
+               if ( strcmp( interps, "none" ) )
                {
                        mlt_properties_set_int( properties, "rescale_width", *width );
                        mlt_properties_set_int( properties, "rescale_height", *height );
@@ -212,53 +215,25 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                // Get rescale interpretation again, in case the producer wishes to override scaling
                interps = mlt_properties_get( properties, "rescale.interp" );
        
-               if ( *image != NULL && ( *format != mlt_image_yuv422 || ( iwidth != owidth || iheight != oheight ) ) )
+               if ( *image && strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) )
                {
-                       // If the colour space is correct and scaling is off, do nothing
-                       if ( *format == mlt_image_yuv422 && !strcmp( interps, "none" ) )
-                       {
-                               *width = iwidth;
-                               *height = iheight;
-                       }
-                       else if ( *format == mlt_image_yuv422 )
-                       {
-                               // Call the local scaler
-                               scaler_method( this, image, *format, mlt_image_yuv422, iwidth, iheight, owidth, oheight );
-                               *width = owidth;
-                               *height = oheight;
-                       }
-                       else if ( *format == mlt_image_rgb24 && wanted_format == mlt_image_rgb24 )
-                       {
-                               // Call the local scaler
-                               scaler_method( this, image, *format, mlt_image_rgb24, iwidth, iheight, owidth, oheight );
+                       mlt_log_debug( MLT_FILTER_SERVICE( filter ), "%dx%d -> %dx%d (%s)\n",
+                               iwidth, iheight, owidth, oheight, mlt_image_format_name( *format ) );
 
-                               // Return the output
-                               *width = owidth;
-                               *height = oheight;
-                       }
-                       else if ( *format == mlt_image_rgb24 || *format == mlt_image_rgb24a )
+                       // If valid colorspace
+                       if ( *format == mlt_image_yuv422 || *format == mlt_image_rgb24 ||
+                            *format == mlt_image_rgb24a || *format == mlt_image_opengl )
                        {
-                               // Call the local scaler
-                               scaler_method( this, image, *format, mlt_image_yuv422, iwidth, iheight, owidth, oheight );
-
-                               // Return the output
-                               *format = mlt_image_yuv422;
+                               // Call the virtual function
+                               scaler_method( this, image, format, iwidth, iheight, owidth, oheight );
                                *width = owidth;
                                *height = oheight;
                        }
-                       else
-                       {
-                               *width = iwidth;
-                               *height = iheight;
-                       }
-                       if ( *width == owidth )
-                       {
-                               // Scale the alpha channel only if exists and not correct size
-                               int alpha_size = 0;
-                               mlt_properties_get_data( properties, "alpha", &alpha_size );
-                               if ( alpha_size > 0 && alpha_size != ( owidth * oheight ) && alpha_size != ( owidth * ( oheight + 1 ) ) )
-                                       scale_alpha( this, iwidth, iheight, owidth, oheight );
-                       }
+                       // Scale the alpha channel only if exists and not correct size
+                       int alpha_size = 0;
+                       mlt_properties_get_data( properties, "alpha", &alpha_size );
+                       if ( alpha_size > 0 && alpha_size != ( owidth * oheight ) && alpha_size != ( owidth * ( oheight + 1 ) ) )
+                               scale_alpha( this, iwidth, iheight, owidth, oheight );
                }
                else
                {
index 68244bfc652426d95a0b3a99876e72528337428c..e57c90ff47518a65e60341aeeac6f541b3740412 100644 (file)
@@ -36,6 +36,145 @@ static inline void swap_bytes( uint8_t *upper, uint8_t *lower )
        *upper = t;
 }
 
+static uint8_t *resize_alpha( uint8_t *input, int owidth, int oheight, int iwidth, int iheight, uint8_t alpha_value )
+{
+       uint8_t *output = NULL;
+
+       if ( input != NULL && ( iwidth != owidth || iheight != oheight ) && ( owidth > 6 && oheight > 6 ) )
+       {
+               uint8_t *out_line;
+               int offset_x = ( owidth - iwidth ) / 2;
+               int offset_y = ( oheight - iheight ) / 2;
+               int iused = iwidth;
+
+               output = mlt_pool_alloc( owidth * oheight );
+               memset( output, alpha_value, owidth * oheight );
+
+               offset_x -= offset_x % 2;
+
+               out_line = output + offset_y * owidth;
+               out_line += offset_x;
+
+               // Loop for the entirety of our output height.
+               while ( iheight -- )
+               {
+                       // We're in the input range for this row.
+                       memcpy( out_line, input, iused );
+
+                       // Move to next input line
+                       input += iwidth;
+
+                       // Move to next output line
+                       out_line += owidth;
+               }
+       }
+
+       return output;
+}
+
+static void resize_image( uint8_t *output, int owidth, int oheight, uint8_t *input, int iwidth, int iheight, int bpp )
+{
+       // Calculate strides
+       int istride = iwidth * bpp;
+       int ostride = owidth * bpp;
+       int offset_x = ( owidth - iwidth ) / 2 * bpp;
+       int offset_y = ( oheight - iheight ) / 2;
+       uint8_t *in_line = input;
+       uint8_t *out_line;
+       int size = owidth * oheight;
+       uint8_t *p = output;
+
+       // Optimisation point
+       if ( output == NULL || input == NULL || ( owidth <= 6 || oheight <= 6 || iwidth <= 6 || oheight <= 6 ) )
+       {
+               return;
+       }
+       else if ( iwidth == owidth && iheight == oheight )
+       {
+               memcpy( output, input, iheight * istride );
+               return;
+       }
+
+       if ( bpp == 2 )
+       {
+               while( size -- )
+               {
+                       *p ++ = 16;
+                       *p ++ = 128;
+               }
+               offset_x -= offset_x % 4;
+       }
+       else
+       {
+               size *= bpp;
+               while ( size-- )
+                       *p ++ = 0;
+       }
+
+       out_line = output + offset_y * ostride;
+       out_line += offset_x;
+
+       // Loop for the entirety of our output height.
+       while ( iheight -- )
+       {
+               // We're in the input range for this row.
+               memcpy( out_line, in_line, iwidth * bpp );
+
+               // Move to next input line
+               in_line += istride;
+
+               // Move to next output line
+               out_line += ostride;
+       }
+}
+
+/** A resizing function for yuv422 frames - this does not rescale, but simply
+       resizes. It assumes yuv422 images available on the frame so use with care.
+*/
+
+static uint8_t *frame_resize_image( mlt_frame this, int owidth, int oheight, int bpp )
+{
+       // Get properties
+       mlt_properties properties = MLT_FRAME_PROPERTIES( this );
+
+       // Get the input image, width and height
+       uint8_t *input = mlt_properties_get_data( properties, "image", NULL );
+       uint8_t *alpha = mlt_frame_get_alpha_mask( this );
+
+       int iwidth = mlt_properties_get_int( properties, "width" );
+       int iheight = mlt_properties_get_int( properties, "height" );
+
+       // If width and height are correct, don't do anything
+       if ( iwidth != owidth || iheight != oheight )
+       {
+               uint8_t alpha_value = mlt_properties_get_int( properties, "resize_alpha" );
+
+               // Create the output image
+               uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * bpp );
+
+               // Call the generic resize
+               resize_image( output, owidth, oheight, input, iwidth, iheight, bpp );
+
+               // Now update the frame
+               mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * bpp, ( mlt_destructor )mlt_pool_release, NULL );
+               mlt_properties_set_int( properties, "width", owidth );
+               mlt_properties_set_int( properties, "height", oheight );
+
+               // We should resize the alpha too
+               alpha = resize_alpha( alpha, owidth, oheight, iwidth, iheight, alpha_value );
+               if ( alpha != NULL )
+               {
+                       mlt_properties_set_data( properties, "alpha", alpha, owidth * oheight, ( mlt_destructor )mlt_pool_release, NULL );
+                       this->get_alpha_mask = NULL;
+               }
+
+               // Return the output
+               return output;
+       }
+       // No change, return input
+       return input;
+}
+
 /** Do it :-).
 */
 
@@ -120,11 +259,28 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        // Now get the image
        error = mlt_frame_get_image( this, image, format, &owidth, &oheight, writable );
 
-       // We only know how to process yuv422 at the moment
-       if ( error == 0 && *format == mlt_image_yuv422 && *image != NULL )
+       if ( error == 0 && *image )
        {
                // Get the requested scale operation
                char *op = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "scale" );
+               int bpp;
+
+               switch ( *format )
+               {
+                       case mlt_image_yuv422:
+                               bpp = 2;
+                               break;
+                       case mlt_image_rgb24:
+                               bpp = 3;
+                               break;
+                       case mlt_image_rgb24a:
+                       case mlt_image_opengl:
+                               bpp = 4;
+                               break;
+                       default:
+                               // XXX: we only know how to resize packed formats
+                               return 1;
+               }
 
                // Provides a manual override for misreported field order
                if ( mlt_properties_get( properties, "meta.top_field_first" ) )
@@ -136,8 +292,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                        // Get the input image, width and height
                        int size;
                        uint8_t *image = mlt_properties_get_data( properties, "image", &size );
-                       uint8_t *ptr = image + owidth * 2;
-                       memmove( ptr, image, size - owidth * 2 );
+                       uint8_t *ptr = image + owidth * bpp;
+                       memmove( ptr, image, size - owidth * bpp );
                        
                        // Set the normalised field order
                        mlt_properties_set_int( properties, "top_field_first", 0 );
@@ -146,11 +302,12 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 
                if ( !strcmp( op, "affine" ) )
                {
-                       *image = mlt_frame_rescale_yuv422( this, *width, *height );
+                       // TODO: Determine where this is needed and find a different way
+                       // *image = mlt_frame_rescale_image( this, *width, *height, bpp );
                }
                else if ( strcmp( op, "none" ) != 0 )
                {
-                       *image = mlt_frame_resize_yuv422( this, *width, *height );
+                       *image = frame_resize_image( this, *width, *height, bpp );
                }
                else
                {
index f1ab0e41ee9180c3631940beef76d91be5eefab1..e1e95d62f6cf3b6f34d0915b53ddfba3069919f2 100644 (file)
@@ -165,6 +165,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                                mlt_properties_set_int( b_props, "distort", 1 );
                        }
 
+                       *format = mlt_image_yuv422;
                        if ( mlt_properties_get_int( properties, "reverse" ) == 0 )
                        {
                                // Apply all filters that are attached to this filter to the b frame
index bcb2560814223756557dab761f7eb784a02a514a..cf7b62ec772fe54db5a509e4da5f3a1d0e82375a 100644 (file)
@@ -6,9 +6,15 @@
 # The names of the services on the right dictate the preference used (if unavailable
 # the second and third are applied as applicable).
 
+# image filters
 crop=crop:1
 deinterlace=deinterlace,avdeinterlace
 rescaler=mcrescale,gtkrescale,rescale,swscale
 resizer=resize
+imageconverter=imageconvert,avcolour_space
+
+# audio filters
 resampler=resample,soxresample,avresample
+
+# metadata filters
 data=data_feed:attr_check
index ac4200178d5615023385fb159e61efde30d6e043..ad2a5ae092aca3a1c1da95e27e6f07a1ba241d7e 100644 (file)
@@ -93,9 +93,6 @@ rgba_color parse_color( char *color, unsigned int color_int )
 
 static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
 {
-       // May need to know the size of the image to clone it
-       int size = 0;
-       
        // Obtain properties of frame
        mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
 
@@ -110,9 +107,11 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        char *then = mlt_properties_get( producer_props, "_resource" );
 
        // Get the current image and dimensions cached in the producer
+       int size = 0;
        uint8_t *image = mlt_properties_get_data( producer_props, "image", &size );
        int current_width = mlt_properties_get_int( producer_props, "_width" );
        int current_height = mlt_properties_get_int( producer_props, "_height" );
+       mlt_image_format current_format = mlt_properties_get_int( producer_props, "_format" );
 
        // Parse the colour
        if ( now && strchr( now, '/' ) )
@@ -123,78 +122,105 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        rgba_color color = parse_color( now, mlt_properties_get_int( producer_props, "resource" ) );
 
        // See if we need to regenerate
-       if ( strcmp( now, then ) || *width != current_width || *height != current_height )
+       if ( strcmp( now, then ) || *width != current_width || *height != current_height || *format != current_format )
        {
                // Color the image
-               uint8_t y, u, v;
-               int i = *height;
-               int j = 0;
-               int uneven = *width % 2;
-               int count = ( *width - uneven ) / 2;
-               uint8_t *p = NULL;
+               int i = *width * *height + 1;
+               int bpp;
+
+               switch ( *format )
+               {
+                       case mlt_image_rgb24:
+                               bpp = 3;
+                               break;
+                       case mlt_image_rgb24a:
+                       case mlt_image_opengl:
+                               bpp = 4;
+                               break;
+                       default:
+                               bpp = 2;
+                               *format = mlt_image_yuv422;
+                               break;
+               }
 
                // Allocate the image
-               size = *width * *height * 2;
-               image = mlt_pool_alloc( size );
+               size = *width * *height * bpp;
+               uint8_t *p = image = mlt_pool_alloc( size );
 
                // Update the producer
                mlt_properties_set_data( producer_props, "image", image, size, mlt_pool_release, NULL );
                mlt_properties_set_int( producer_props, "_width", *width );
                mlt_properties_set_int( producer_props, "_height", *height );
+               mlt_properties_set_int( producer_props, "_format", *format );
                mlt_properties_set( producer_props, "_resource", now );
 
-               RGB2YUV( color.r, color.g, color.b, y, u, v );
-
-               p = image;
-
-               while ( i -- )
+               switch ( *format )
                {
-                       j = count;
-                       while ( j -- )
+               case mlt_image_yuv422:
+               {
+                       int uneven = *width % 2;
+                       int count = ( *width - uneven ) / 2 + 1;
+                       uint8_t y, u, v;
+
+                       RGB2YUV( color.r, color.g, color.b, y, u, v );
+                       i = *height + 1;
+                       while ( --i )
                        {
-                               *p ++ = y;
-                               *p ++ = u;
-                               *p ++ = y;
-                               *p ++ = v;
+                               int j = count;
+                               while ( --j )
+                               {
+                                       *p ++ = y;
+                                       *p ++ = u;
+                                       *p ++ = y;
+                                       *p ++ = v;
+                               }
+                               if ( uneven )
+                               {
+                                       *p ++ = y;
+                                       *p ++ = u;
+                               }
                        }
-                       if ( uneven )
+                       break;
+               }
+               case mlt_image_rgb24:
+                       while ( --i )
+                       {
+                               *p ++ = color.r;
+                               *p ++ = color.g;
+                               *p ++ = color.b;
+                       }
+                       break;
+               case mlt_image_rgb24a:
+               case mlt_image_opengl:
+                       while ( --i )
                        {
-                               *p ++ = y;
-                               *p ++ = u;
+                               *p ++ = color.r;
+                               *p ++ = color.g;
+                               *p ++ = color.b;
+                               *p ++ = color.a;
                        }
+                       break;
+               default:
+                       break;
                }
        }
 
-       // Update the frame
-       mlt_properties_set_int( properties, "width", *width );
-       mlt_properties_set_int( properties, "height", *height );
-       
-       // Clone if necessary (deemed always necessary)
-       if ( 1 )
-       {
-               // Create the alpha channel
-               uint8_t *alpha = mlt_pool_alloc( size >> 1 );
+       // Create the alpha channel
+       int alpha_size = *width * *height;
+       uint8_t *alpha = mlt_pool_alloc( alpha_size );
 
-               // Clone our image
-               uint8_t *copy = mlt_pool_alloc( size );
-               memcpy( copy, image, size );
+       // Initialise the alpha
+       if ( alpha )
+               memset( alpha, color.a, alpha_size );
 
-               // We're going to pass the copy on
-               image = copy;
-
-               // Initialise the alpha
-               if ( alpha )
-                       memset( alpha, color.a, size >> 1 );
-
-               // Now update properties so we free the copy after
-               mlt_properties_set_data( properties, "image", copy, size, mlt_pool_release, NULL );
-               mlt_properties_set_data( properties, "alpha", alpha, size >> 1, mlt_pool_release, NULL );
-               mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) );
-       }
+       // Clone our image
+       *buffer = mlt_pool_alloc( size );
+       memcpy( *buffer, image, size );
 
-       // Pass on the image
-       *buffer = image;
-       *format = mlt_image_yuv422;
+       // Now update properties so we free the copy after
+       mlt_properties_set_data( properties, "image", *buffer, size, mlt_pool_release, NULL );
+       mlt_properties_set_data( properties, "alpha", alpha, alpha_size, mlt_pool_release, NULL );
+       mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) );
 
        return 0;
 }
index 9f4992cb2515c75d99c317fee9af79ad2d33d960..4baa186f39e814cb5185e025d21f58a3e4566ca4 100644 (file)
@@ -46,7 +46,8 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format
        int result = mlt_frame_get_image( nested_frame, image, format, width, height, writable );
 
        // Allocate the image
-       int size = *width * *height * ( *format == mlt_image_yuv422 ? 2 : *format == mlt_image_rgb24 ? 3 : *format == mlt_image_rgb24a ? 4 : ( 3 / 2 ) );
+       int size = *width * *height * ( *format == mlt_image_yuv422 ? 2 : *format == mlt_image_rgb24 ? 3 :
+               ( *format == mlt_image_rgb24a || *format == mlt_image_opengl ) ? 4 : ( 3 / 2 ) );
        uint8_t *new_image = mlt_pool_alloc( size );
 
        // Update the frame
index 0121579065dcc265bfaeab8fceb88fc2333bfd7c..faa279266d6f839a934fadb8bc2f7a00e22f4fbd 100644 (file)
@@ -73,24 +73,10 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma
        if ( mlt_properties_get_int( properties, "has_image" ) )
        {
                // Get the RGB image
-               uint8_t *rgb = mlt_properties_get_data( properties, "image", NULL );
-
-               // Get width and height
+               *buffer = mlt_properties_get_data( properties, "image", NULL );
                *width = mlt_properties_get_int( properties, "width" );
                *height = mlt_properties_get_int( properties, "height" );
-
-               // Convert to requested format
-               if ( *format == mlt_image_yuv422 )
-               {
-                       uint8_t *image = mlt_pool_alloc( *width * ( *height + 1 ) * 2 );
-                       mlt_convert_rgb24_to_yuv422( rgb, *width, *height, *width * 3, image );
-                       mlt_properties_set_data( properties, "image", image, *width * ( *height + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL );
-                       *buffer = image;
-               }
-               else if ( *format == mlt_image_rgb24 )
-               {
-                       *buffer = rgb;
-               }
+               *format = mlt_image_rgb24;
        }
        else
        {
@@ -113,7 +99,7 @@ FILE *producer_ppm_run_video( producer_ppm this )
                        char command[ 1024 ];
                        float fps = mlt_producer_get_fps( &this->parent );
                        float position = mlt_producer_position( &this->parent );
-                       sprintf( command, "ffmpeg -i \"%s\" -ss %f -f imagepipe -r %f -img ppm - 2>/dev/null", this->command, position, fps );
+                       sprintf( command, "ffmpeg -i \"%s\" -ss %f -f image2pipe -r %f -vcodec ppm - 2>/dev/null", this->command, position, fps );
                        this->video = popen( command, "r" );
                }
        }
index 3a4eb1685eb3ec1aadae0086a3181e7ccad1fd0c..acd15f1bfe65889a1cff3fdbe285816e82cfffd5 100644 (file)
@@ -137,9 +137,6 @@ static void luma_composite( mlt_frame a_frame, mlt_frame b_frame, int luma_width
        int stride_dest;
        uint16_t weight = 0;
 
-       format_src = mlt_image_yuv422;
-       format_dest = mlt_image_yuv422;
-
        if ( mlt_properties_get( &a_frame->parent, "distort" ) )
                mlt_properties_set( &b_frame->parent, "distort", mlt_properties_get( &a_frame->parent, "distort" ) );
        mlt_properties_set_int( &b_frame->parent, "consumer_deinterlace", mlt_properties_get_int( &a_frame->parent, "consumer_deinterlace" ) );
@@ -348,12 +345,6 @@ static void luma_read_yuv422( uint8_t *image, uint16_t **map, int width, int hei
                *p++ = ( image[ i ] - 16 ) * 299; // 299 = 65535 / 219
 }
 
-/** Generate a luma map from a YUV image.
-*/
-static void luma_read_rgb24( uint8_t *image, uint16_t **map, int width, int height )
-{
-}
-
 /** Get the image.
 */
 
@@ -470,11 +461,8 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
                                        mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 );
 
                                        // Generate the luma map
-                                       if ( luma_image != NULL && luma_format == mlt_image_yuv422 )
+                                       if ( luma_image != NULL )
                                                luma_read_yuv422( luma_image, &luma_bitmap, luma_width, luma_height );
-                                               
-                                       else if ( luma_image != NULL && luma_format == mlt_image_rgb24 )
-                                               luma_read_rgb24( luma_image, &luma_bitmap, luma_width, luma_height );
                                        
                                        // Set the transition properties
                                        mlt_properties_set_int( properties, "width", luma_width );
index 967e263091554e73beb82ba331e86a41d4540bfd..8747d2beb88bc38ea0d0ca3f00bdb4b22e1a3f5a 100644 (file)
@@ -71,10 +71,11 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        mlt_filter filter = mlt_frame_pop_service( this );
 
        // Get the image
+       *format = mlt_image_rgb24a;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
        // Only process if we have no error and a valid colour space
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                // Get the "Burn the foreground" value
                int burn_foreground = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "foreground" );
@@ -90,15 +91,12 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                int video_height = *height;
                int video_area = video_width * video_height;
                // We need to create a new frame as this effect modifies the input
-               RGB32 *dest = mlt_pool_alloc( video_area * sizeof(RGB32) );
-               RGB32 *src = (RGB32*)dest;
+               RGB32 *dest = (RGB32*)*image;
+               RGB32 *src = (RGB32*)*image;
 
                unsigned char v, w;
                RGB32 a, b;
 
-               mlt_convert_yuv422_to_rgb24a(*image, (uint8_t *)dest, video_area);
-
-
                diff = mlt_properties_get_data( MLT_FILTER_PROPERTIES( filter ), 
                                                "_diff", NULL );
                if (diff == NULL)
@@ -170,11 +168,6 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                        }
                        i += 2;
                }
-
-               mlt_convert_rgb24a_to_yuv422((uint8_t *)dest, *width, *height, *width * sizeof(RGB32), 
-                               *image, NULL );
-
-               mlt_pool_release(dest);
        }
 
        return error;
index a2880f154a0f382c97c03dbd07ad3dd36ce7331c..eb699d324f050544a4715bb322dbb349a3987552 100644 (file)
@@ -25,16 +25,18 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 {
 
        mlt_filter filter = mlt_frame_pop_service( this );
-       int error = mlt_frame_get_image( this, image, format, width, height, 1 );
+       *format = mlt_image_rgb24a;
+       mlt_log_debug( MLT_FILTER_SERVICE( filter ), "frei0r %dx%d\n", *width, *height );
+       int error = mlt_frame_get_image( this, image, format, width, height, 0 );
        
-       if ( error == 0 && *image && *format == mlt_image_yuv422 )
+       if ( error == 0 && *image )
        {
                mlt_position in = mlt_filter_get_in( filter );
                mlt_position out = mlt_filter_get_out( filter );
                mlt_position time = mlt_frame_get_position( this );
                double position = ( double )( time - in ) / ( double )( out - in + 1 );
                
-               process_frei0r_item( filter_type , position, MLT_FILTER_PROPERTIES ( filter ), this , image, format , width , height , writable );
+               process_frei0r_item( filter_type, position, MLT_FILTER_PROPERTIES ( filter ), this, image, width, height );
                
        }
 
@@ -49,8 +51,7 @@ mlt_frame filter_process( mlt_filter this, mlt_frame frame )
        return frame;
 }
 
-void filter_close( mlt_filter this ){
-       
+void filter_close( mlt_filter this )
+{
        destruct( MLT_FILTER_PROPERTIES ( this ) );
-       
 }
index e42b06e301afa7c668357a62bac113d29b215e41..148d679d49654b41157cb650be0f7d433485b4bc 100644 (file)
@@ -31,8 +31,8 @@ static void parse_color( int color, f0r_param_color_t *fcolor )
        fcolor->b /= 255;
 }
 
-int process_frei0r_item( mlt_service_type type,  double position , mlt_properties prop , mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ){
-
+int process_frei0r_item( mlt_service_type type, double position, mlt_properties prop, mlt_frame this, uint8_t **image, int *width, int *height )
+{
        int i=0;
        f0r_instance_t ( *f0r_construct ) ( unsigned int , unsigned int ) =  mlt_properties_get_data(  prop , "f0r_construct" ,NULL);
        void (*f0r_update)(f0r_instance_t instance, double time, const uint32_t* inframe, uint32_t* outframe)=mlt_properties_get_data(  prop , "f0r_update" ,NULL);
@@ -101,35 +101,17 @@ int process_frei0r_item( mlt_service_type type,  double position , mlt_propertie
        }
 
        int video_area = *width * *height;
-       uint32_t *img_a;
-
-       if ( type != producer_type )
-           img_a = mlt_pool_alloc( video_area * sizeof(uint32_t) );
-       uint32_t *img_b = mlt_pool_alloc( video_area * sizeof(uint32_t) );
+       uint32_t *result = mlt_pool_alloc( video_area * sizeof(uint32_t) );
 
        if (type==producer_type) {
-               f0r_update ( inst , position , NULL , img_b );
-               mlt_convert_rgb24a_to_yuv422((uint8_t *)img_b , *width, *height, *width * sizeof(uint32_t),*image, NULL);
+               f0r_update (inst, position, NULL, result );
        } else if (type==filter_type) {
-               mlt_convert_yuv422_to_rgb24a(*image, (uint8_t *)img_a, video_area);
-               f0r_update ( inst , position , img_a , img_b );
-               mlt_convert_rgb24a_to_yuv422((uint8_t *)img_b , *width, *height, *width * sizeof(uint32_t),
-                                                                                               *image, NULL );
+               f0r_update ( inst, position, (uint32_t *)image[0], result );
        } else if (type==transition_type && f0r_update2 ){
-               uint32_t *result = mlt_pool_alloc( video_area * sizeof(uint32_t) );
-
-               mlt_convert_yuv422_to_rgb24a ( image[0] , (uint8_t *)img_a , video_area );
-               mlt_convert_yuv422_to_rgb24a ( image[1] , (uint8_t *)img_b , video_area );
-               f0r_update2 ( inst , position , img_a , img_b , NULL , result );
-
-               uint8_t * image_ptr=mlt_properties_get_data(MLT_FRAME_PROPERTIES(this), "image", NULL );
-               if (image_ptr)
-                   mlt_convert_rgb24a_to_yuv422((uint8_t *)result, *width, *height, *width * sizeof(uint32_t), image_ptr , NULL );
-
-               mlt_pool_release(result);
-       }
-       if ( type != producer_type ) mlt_pool_release(img_a);
-       mlt_pool_release(img_b);
+               f0r_update2 ( inst, position, (uint32_t *)image[0], (uint32_t *)image[1], NULL, result );
+       }
+       *image = (uint8_t*) result;
+       mlt_properties_set_data(MLT_FRAME_PROPERTIES(this), "image", result, video_area * sizeof(uint32_t), mlt_pool_release, NULL);
 
        return 0;
 }
index aee4a5d2060b550881265588c25fea96ae202cae..2b9176642610612aa2606a7f9706039ed56f82b4 100644 (file)
@@ -18,5 +18,6 @@
  */
 #include <framework/mlt.h>
 
-int process_frei0r_item( mlt_service_type type,  double position , mlt_properties prop , mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable );
+int process_frei0r_item( mlt_service_type, double position, mlt_properties,
+       mlt_frame, uint8_t **image, int *width, int *height );
 void destruct (mlt_properties prop );
index ae1a26d8a1664da03e06cd6f5f5651dc08aa51d6..0f16c862d3cfc50b9e985791475138bc32114ef7 100644 (file)
@@ -37,7 +37,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer );
 
        // Allocate the image
-       int size = *width * ( *height + 1 ) * 2;
+       int size = *width * ( *height + 1 ) * 4;
 
        // Allocate the image
        *buffer = mlt_pool_alloc( size );
@@ -47,14 +47,14 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        mlt_properties_set_int( properties, "width", *width );
        mlt_properties_set_int( properties, "height", *height );
 
-       *format = mlt_image_yuv422;
+       *format = mlt_image_rgb24a;
        if ( *buffer != NULL )
        {
                mlt_position in = mlt_producer_get_in( producer );
                mlt_position out = mlt_producer_get_out( producer );
                mlt_position time = mlt_frame_get_position( frame );
                double position = ( double )( time - in ) / ( double )( out - in + 1 );
-               process_frei0r_item( producer_type , position, producer_props, frame , buffer, format , width , height , writable );
+               process_frei0r_item( producer_type, position, producer_props, frame, buffer, width, height );
        }
 
     return 0;
index 4fb6846e5e232924746557f78d0670606ef47e57..e9a75d8c116b3fed5c397d2291b6dffd4df5fe11 100644 (file)
  
 static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ){
        
-       if (*format!=mlt_image_yuv422 ){
-               return -1;
-       }
-       
        mlt_frame b_frame = mlt_frame_pop_frame( a_frame );
        mlt_transition transition = mlt_frame_pop_service( a_frame );
        mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
@@ -50,8 +46,9 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
        
        uint8_t *images[]={NULL,NULL,NULL};
 
-       mlt_frame_get_image( a_frame, &images[0], format, width, height, 1 );
-       mlt_frame_get_image( b_frame, &images[1], format, width, height, 1 );
+       *format = mlt_image_rgb24a;
+       mlt_frame_get_image( a_frame, &images[0], format, width, height, 0 );
+       mlt_frame_get_image( b_frame, &images[1], format, width, height, 0 );
        
        mlt_position in = mlt_transition_get_in( transition );
        mlt_position out = mlt_transition_get_out( transition );
@@ -62,7 +59,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
 
        float pos=( float )( position - in ) / ( float )( out - in + 1 );
        
-       process_frei0r_item( transition_type , pos , properties, !invert ? a_frame : b_frame , images , format, width,height, writable );
+       process_frei0r_item( transition_type, pos, properties, !invert ? a_frame : b_frame, images, width, height );
        
        *width = mlt_properties_get_int( !invert ? a_props : b_props, "width" );
         *height = mlt_properties_get_int( !invert ? a_props : b_props, "height" );
index e3b6d17a8f81a3d64978f1ad5c2181548dbfb821..a6719267e39310f1f6ede72ec4cc2c6f77cc08bc 100644 (file)
@@ -29,7 +29,7 @@
 #include <stdlib.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
-static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iformat, mlt_image_format oformat, int iwidth, int iheight, int owidth, int oheight )
+static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format *format, int iwidth, int iheight, int owidth, int oheight )
 {
        // Get the properties
        mlt_properties properties = MLT_FRAME_PROPERTIES( this );
@@ -48,7 +48,9 @@ static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iform
                interp = PIXOPS_INTERP_HYPER;
 
        // Carry out the rescaling
-       if ( iformat == mlt_image_yuv422 && oformat == mlt_image_yuv422 )
+       switch ( *format )
+       {
+       case mlt_image_yuv422:
        {
                // Create the output image
                uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 );
@@ -66,67 +68,58 @@ static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iform
 
                // Return the output
                *image = output;
+               break;
        }
-       else if ( iformat == mlt_image_rgb24 || iformat == mlt_image_rgb24a )
+       case mlt_image_rgb24:
+       case mlt_image_rgb24a:
+       case mlt_image_opengl:
        {
-               int bpp = (iformat == mlt_image_rgb24a ? 4 : 3 );
-                       
-               // Create the yuv image
-               uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * 2 );
+               int bpp = ( *format == mlt_image_rgb24 ? 3 : 4 );
+
+               // Create the output image
+               uint8_t *output = mlt_pool_alloc( owidth * ( oheight + 1 ) * bpp );
 
                if ( strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) )
                {
                        GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( *image, GDK_COLORSPACE_RGB,
-                               ( iformat == mlt_image_rgb24a ), 8, iwidth, iheight,
+                               ( *format == mlt_image_rgb24a || *format == mlt_image_opengl ), 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
-                               uint8_t *alpha = mlt_pool_alloc( 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 ), ( mlt_destructor )mlt_pool_release, NULL );
-                       }
-                       else
+                       int src_stride = gdk_pixbuf_get_rowstride( scaled );
+                       int dst_stride = owidth * bpp;
+                       if ( src_stride != dst_stride )
                        {
-                               // 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
-                               uint8_t *alpha = mlt_pool_alloc( owidth * ( oheight + 1 ) );
-
-                               // Convert the image and extract alpha
-                               mlt_convert_rgb24a_to_yuv422( *image, owidth, oheight, owidth * 4, output, alpha );
-
-                               mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL );
+                               int y = oheight;
+                               uint8_t *src = gdk_pixbuf_get_pixels( scaled );
+                               uint8_t *dst = output;
+                               while ( y-- )
+                               {
+                                       memcpy( dst, src, dst_stride );
+                                       dst += dst_stride;
+                                       src += src_stride;
+                               }
                        }
                        else
                        {
-                               // No alpha to extract
-                               mlt_convert_rgb24_to_yuv422( *image, owidth, oheight, owidth * 3, output );
+                               memcpy( output, gdk_pixbuf_get_pixels( scaled ), owidth * oheight * bpp );
                        }
-               }
 
-               // Now update the frame
-               mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * 2, ( mlt_destructor )mlt_pool_release, NULL );
-               mlt_properties_set_int( properties, "width", owidth );
-               mlt_properties_set_int( properties, "height", oheight );
+                       g_object_unref( scaled );
 
-               *image = output;
+                       // Now update the frame
+                       mlt_properties_set_data( properties, "image", output, owidth * ( oheight + 1 ) * bpp, ( mlt_destructor )mlt_pool_release, NULL );
+                       mlt_properties_set_int( properties, "width", owidth );
+                       mlt_properties_set_int( properties, "height", oheight );
+       
+                       // Return the output
+                       *image = output;
+               }
+               break;
+       }
+       default:
+               break;
        }
 
        return 0;
index 3398e79a285cce6f19fca18d76e6ad10310881ba..1df060501d68a9c677228fd39c0b5bf18d9a8512 100644 (file)
@@ -44,10 +44,9 @@ static pthread_mutex_t pango_mutex = PTHREAD_MUTEX_INITIALIZER;
 struct producer_pango_s
 {
        struct mlt_producer_s parent;
-       int width;
-       int height;
-       uint8_t *image;
-       uint8_t *alpha;
+       int   width;
+       int   height;
+       GdkPixbuf *pixbuf;
        char *fgcolor;
        char *bgcolor;
        int   align;
@@ -55,7 +54,7 @@ struct producer_pango_s
        char *markup;
        char *text;
        char *font;
-       int weight;
+       int   weight;
 };
 
 // special color type used by internal pango routines
@@ -312,7 +311,7 @@ static int iconv_utf8( mlt_properties properties, const char *prop_name, const c
 
 static void refresh_image( mlt_frame frame, int width, int height )
 {
-       // Pixbuf 
+       // Pixbuf
        GdkPixbuf *pixbuf = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "pixbuf", NULL );
 
        // Obtain properties of frame
@@ -381,10 +380,9 @@ static void refresh_image( mlt_frame frame, int width, int height )
                rgba_color fgcolor = parse_color( this->fgcolor );
                rgba_color bgcolor = parse_color( this->bgcolor );
 
-               mlt_pool_release( this->image );
-               mlt_pool_release( this->alpha );
-               this->image = NULL;
-               this->alpha = NULL;
+               if ( this->pixbuf )
+                       g_object_unref( this->pixbuf );
+               this->pixbuf = NULL;
 
                // Convert from specified encoding to UTF-8
                if ( encoding != NULL && !strncaseeq( encoding, "utf-8", 5 ) && !strncaseeq( encoding, "utf8", 4 ) )
@@ -419,13 +417,11 @@ static void refresh_image( mlt_frame frame, int width, int height )
                        this->height = gdk_pixbuf_get_height( pixbuf );
                }
        }
-       else if ( pixbuf == NULL && ( width > 0 && ( this->image == NULL || width != this->width || height != this->height ) ) )
+       else if ( pixbuf == NULL && width > 0 && ( this->pixbuf == NULL || width != this->width || height != this->height ) )
        {
-               mlt_pool_release( this->image );
-               mlt_pool_release( this->alpha );
-               this->image = NULL;
-               this->alpha = NULL;
-
+               if ( this->pixbuf )
+                       g_object_unref( this->pixbuf );
+               this->pixbuf = NULL;
                pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL );
        }
 
@@ -445,24 +441,11 @@ static void refresh_image( mlt_frame frame, int width, int height )
 // fprintf(stderr,"%s: scaling from %dx%d to %dx%d\n", __FILE__, this->width, this->height, width, height);
 
                // Note - the original pixbuf is already safe and ready for destruction
-               pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, interp );
+               this->pixbuf = gdk_pixbuf_scale_simple( pixbuf, width, height, interp );
 
                // Store width and height
                this->width = width;
                this->height = height;
-
-               // Allocate/define image
-               this->image = mlt_pool_alloc( width * ( height + 1 ) * 2 );
-               this->alpha = mlt_pool_alloc( 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 ),
-                                                                         this->image, this->alpha );
-
-               // Finished with pixbuf now
-               g_object_unref( pixbuf );
        }
 
        // Set width/height
@@ -470,24 +453,15 @@ static void refresh_image( mlt_frame frame, int width, int height )
        mlt_properties_set_int( properties, "height", this->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 data without destructor
-       mlt_properties_set_data( properties, "image", this->image, this->width * ( this->height + 1 ) * 2, NULL, NULL );
-       mlt_properties_set_data( properties, "alpha", this->alpha, this->width * this->height, NULL, NULL );
 }
 
 static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
 {
+       producer_pango this = ( producer_pango ) mlt_frame_pop_service( frame );
+
        // Obtain properties of frame
        mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
 
-       // We need to know the size of the image to clone it
-       int image_size = 0;
-       int alpha_size = 0;
-
-       // Alpha channel
-       uint8_t *alpha = NULL;
-
        *width = mlt_properties_get_int( properties, "rescale_width" );
        *height = mlt_properties_get_int( properties, "rescale_height" );
 
@@ -495,43 +469,30 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        pthread_mutex_lock( &pango_mutex );
        refresh_image( frame, *width, *height );
 
-       // Get the image
-       *buffer = mlt_properties_get_data( properties, "image", &image_size );
-       alpha = mlt_properties_get_data( properties, "alpha", &alpha_size );
-
        // Get width and height
-       *width = mlt_properties_get_int( properties, "width" );
-       *height = mlt_properties_get_int( properties, "height" );
+       *width = this->width;
+       *height = this->height;
 
        // Always clone here to allow 'animated' text
-       if ( *buffer != NULL )
+       if ( this->pixbuf )
        {
-               // Clone the image and the alpha
-               uint8_t *image_copy = mlt_pool_alloc( image_size );
-               uint8_t *alpha_copy = mlt_pool_alloc( alpha_size );
-
-               memcpy( image_copy, *buffer, image_size );
-
-               // Copy or default the alpha
-               if ( alpha != NULL )
-                       memcpy( alpha_copy, alpha, alpha_size );
-               else
-                       memset( alpha_copy, 255, alpha_size );
+               // Clone the image
+               int image_size = this->width * this->height * 4;
+               *buffer = mlt_pool_alloc( image_size );
+               memcpy( *buffer, gdk_pixbuf_get_pixels( this->pixbuf ), image_size );
 
                // Now update properties so we free the copy after
-               mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL );
-               mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL );
-
-               // We're going to pass the copy on
-               *buffer = image_copy;
+               mlt_properties_set_data( properties, "image", *buffer, image_size, mlt_pool_release, NULL );
+               *format = mlt_image_rgb24a;
        }
        else
        {
                // TODO: Review all cases of invalid images
                *buffer = mlt_pool_alloc( 50 * 50 * 2 );
-               mlt_properties_set_data( properties, "image", *buffer, image_size, mlt_pool_release, NULL );
+               mlt_properties_set_data( properties, "image", *buffer, 50 * 50 * 2, mlt_pool_release, NULL );
                *width = 50;
                *height = 50;
+               *format = mlt_image_yuv422;
        }
 
        pthread_mutex_unlock( &pango_mutex );
@@ -539,15 +500,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;
@@ -574,10 +526,8 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        mlt_properties_set_int( properties, "progressive", 1 );
        mlt_properties_set_double( properties, "aspect_ratio", 1 );
 
-       // Set alpha call back
-       ( *frame )->get_alpha_mask = producer_get_alpha_mask;
-
        // Stack the get image callback
+       mlt_frame_push_service( *frame, this );
        mlt_frame_push_get_image( *frame, producer_get_image );
 
        // Calculate the next timecode
@@ -589,8 +539,8 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
 static void producer_close( mlt_producer parent )
 {
        producer_pango this = parent->child;
-       mlt_pool_release( this->image );
-       mlt_pool_release( this->alpha );
+       if ( this->pixbuf )
+               g_object_unref( this->pixbuf );
        free( this->fgcolor );
        free( this->bgcolor );
        free( this->markup );
index b72e9c827ba4ffb6af6c24b12a929e15ac81ca87..e9395ec93704eda9a28cca66725443b1695b16fb 100644 (file)
@@ -49,10 +49,9 @@ struct producer_pixbuf_s
        int pixbuf_idx;
        int width;
        int height;
+       int alpha;
        uint8_t *image;
-       uint8_t *alpha;
        mlt_cache_item image_cache;
-       mlt_cache_item alpha_cache;
        pthread_mutex_t mutex;
 };
 
@@ -217,10 +216,6 @@ static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int
        this->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" );
        this->image = mlt_cache_item_data( this->image_cache, NULL );
 
-       // restore alpha channel
-       this->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha" );
-       this->alpha = mlt_cache_item_data( this->alpha_cache, NULL );
-
        // Check if user wants us to reload the image
        if ( mlt_properties_get_int( producer_props, "force_reload" ) ) 
        {
@@ -265,7 +260,7 @@ static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int
                        mlt_properties_set_int( producer_props, "_real_width", mlt_properties_get_int( cached_props, "real_width" ) );
                        mlt_properties_set_int( producer_props, "_real_height", mlt_properties_get_int( cached_props, "real_height" ) );
                        this->image = mlt_properties_get_data( cached_props, "image", NULL );
-                       this->alpha = mlt_properties_get_data( cached_props, "alpha", NULL );
+                       this->alpha = mlt_properties_get_int( cached_props, "alpha" );
 
                        if ( width != 0 && ( width != this->width || height != this->height ) )
                                this->image = NULL;
@@ -324,37 +319,33 @@ static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int
                this->height = height;
                
                // Allocate/define image
-               this->image = mlt_pool_alloc( width * ( height + 1 ) * 2 );
-               if ( !use_cache )
-                       mlt_cache_item_close( this->image_cache );
-               mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image", this->image, width * ( height + 1 ) * 2, mlt_pool_release );
-               this->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" );
-               this->image_idx = image_idx;
+               this->alpha = gdk_pixbuf_get_has_alpha( pixbuf );
+               int src_stride = gdk_pixbuf_get_rowstride( pixbuf );
+               int dst_stride = this->width * ( this->alpha ? 4 : 3 );
+               int image_size = dst_stride * ( height + 1 );
+               this->image = mlt_pool_alloc( image_size );
 
-               // Extract YUV422 and alpha
-               if ( gdk_pixbuf_get_has_alpha( pixbuf ) )
+               if ( src_stride != dst_stride )
                {
-                       // Allocate the alpha mask
-                       this->alpha = mlt_pool_alloc( this->width * this->height );
-                       if ( !use_cache )
-                               mlt_cache_item_close( this->alpha_cache );
-                       mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha", this->alpha, width * height, mlt_pool_release );
-                       this->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.alpha" );
-
-                       // Convert the image
-                       mlt_convert_rgb24a_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
-                                                                                 this->width, this->height,
-                                                                                 gdk_pixbuf_get_rowstride( pixbuf ),
-                                                                                 this->image, this->alpha );
+                       int y = this->height;
+                       uint8_t *src = gdk_pixbuf_get_pixels( pixbuf );
+                       uint8_t *dst = this->image;
+                       while ( y-- )
+                       {
+                               memcpy( dst, src, dst_stride );
+                               dst += dst_stride;
+                               src += src_stride;
+                       }
                }
                else
-               { 
-                       // No alpha to extract
-                       mlt_convert_rgb24_to_yuv422( gdk_pixbuf_get_pixels( pixbuf ),
-                                                                                this->width, this->height,
-                                                                                gdk_pixbuf_get_rowstride( pixbuf ),
-                                                                                this->image );
+               {
+                       memcpy( this->image, gdk_pixbuf_get_pixels( pixbuf ), src_stride * height );
                }
+               if ( !use_cache )
+                       mlt_cache_item_close( this->image_cache );
+               mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image", this->image, image_size, mlt_pool_release );
+               this->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "pixbuf.image" );
+               this->image_idx = image_idx;
 
                // Finished with pixbuf now
                g_object_unref( pixbuf );
@@ -369,7 +360,6 @@ static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int
        {
                pthread_mutex_unlock( &this->mutex );
                mlt_cache_item_close( this->image_cache );
-               mlt_cache_item_close( this->alpha_cache );
        }
 
        // Set width/height of frame
@@ -386,8 +376,8 @@ static void refresh_image( producer_pixbuf this, mlt_frame frame, int width, int
                mlt_properties_set_int( cached_props, "height", this->height );
                mlt_properties_set_int( cached_props, "real_width", mlt_properties_get_int( producer_props, "_real_width" ) );
                mlt_properties_set_int( cached_props, "real_height", mlt_properties_get_int( producer_props, "_real_height" ) );
-               mlt_properties_set_data( cached_props, "image", this->image, this->width * ( this->height + 1 ) * 2, mlt_pool_release, NULL );
-               mlt_properties_set_data( cached_props, "alpha", this->alpha, this->width * this->height, mlt_pool_release, NULL );
+               mlt_properties_set_data( cached_props, "image", this->image, this->width * ( this->alpha ? 4 : 3 ) * this->height, mlt_pool_release, NULL );
+               mlt_properties_set_int( cached_props, "alpha", this->alpha );
                mlt_properties_set_data( cache, image_key, cached, 0, ( mlt_destructor )mlt_frame_close, NULL );
        }
 
@@ -408,84 +398,43 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        // Refresh the image
        refresh_image( this, frame, *width, *height );
 
-       // Get the image size
-       int image_size = this->width * ( this->height + 1 ) * 2;
-       int alpha_size = this->width * this->height;
-
        // Get width and height (may have changed during the refresh)
-       *width = mlt_properties_get_int( properties, "width" );
-       *height = mlt_properties_get_int( properties, "height" );
+       *width = this->width;
+       *height = this->height;
 
        // NB: Cloning is necessary with this producer (due to processing of images ahead of use)
        // The fault is not in the design of mlt, but in the implementation of the pixbuf producer...
        if ( this->image )
        {
-               if ( *format == mlt_image_yuv422 || *format == mlt_image_yuv420p )
-               {
-                       // Clone the image and the alpha
-                       uint8_t *image_copy = mlt_pool_alloc( image_size );
-                       uint8_t *alpha_copy = mlt_pool_alloc( alpha_size );
-
-                       memcpy( image_copy, this->image, image_size );
-
-                       // Copy or default the alpha
-                       if ( this->alpha != NULL )
-                               memcpy( alpha_copy, this->alpha, alpha_size );
-                       else
-                               memset( alpha_copy, 255, alpha_size );
-
-                       // Now update properties so we free the copy after
-                       mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL );
-                       mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL );
-
-                       // We're going to pass the copy on
-                       *buffer = image_copy;
-               }
-               else if ( *format == mlt_image_rgb24a )
-               {
-                       // Clone the image and the alpha
-                       image_size = *width * ( *height + 1 ) * 4;
-                       alpha_size = *width * ( *height + 1 );
-                       uint8_t *image_copy = mlt_pool_alloc( image_size );
-                       uint8_t *alpha_copy = mlt_pool_alloc( alpha_size );
-
-                       mlt_convert_yuv422_to_rgb24a( this->image, image_copy, (*width)*(*height) );
-
-                       // Now update properties so we free the copy after
-                       mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL );
-                       mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL );
-
-                       // We're going to pass the copy on
-                       *buffer = image_copy;
-               }
-
+               // Clone the image
+               int image_size = this->width * this->height * ( this->alpha ? 4 :3 );
+               uint8_t *image_copy = mlt_pool_alloc( image_size );
+               memcpy( image_copy, this->image, image_size );
+               // Now update properties so we free the copy after
+               mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL );
+               // We're going to pass the copy on
+               *buffer = image_copy;
+               *format = this->alpha ? mlt_image_rgb24a : mlt_image_rgb24;
+               mlt_log_debug( MLT_PRODUCER_SERVICE( &this->parent ), "%dx%d (%s)\n",
+                       this->width, this->height, mlt_image_format_name( *format ) );
        }
        else
        {
                // TODO: Review all cases of invalid images
                *buffer = mlt_pool_alloc( 50 * 50 * 2 );
-               mlt_properties_set_data( properties, "image", *buffer, image_size, mlt_pool_release, NULL );
+               mlt_properties_set_data( properties, "image", *buffer, 50 * 50 * 2, mlt_pool_release, NULL );
                *width = 50;
                *height = 50;
+               *format = mlt_image_yuv422;
        }
 
        // Release references and locks
        pthread_mutex_unlock( &this->mutex );
        mlt_cache_item_close( this->image_cache );
-       mlt_cache_item_close( this->alpha_cache );
 
        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
@@ -521,9 +470,6 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( producer_properties, "progressive" ) );
                mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_properties, "aspect_ratio" ) );
 
-               // Set alpha call back
-               ( *frame )->get_alpha_mask = producer_get_alpha_mask;
-
                // Push the get_image method
                mlt_frame_push_get_image( *frame, producer_get_image );
        }
index f1d54259c4821c9e86c70e68d64c87772bef4eba..ab318df365ac08a553fdd08513c4730e30385f2b 100644 (file)
@@ -163,12 +163,13 @@ static void DoBoxBlur(uint8_t *yuv, int32_t *rgb, unsigned int width, unsigned i
 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
 {
        // Get the image
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
        short hori = mlt_properties_get_int(MLT_FRAME_PROPERTIES( this ), "hori" );
        short vert = mlt_properties_get_int(MLT_FRAME_PROPERTIES( this ), "vert" );
 
        // Only process if we have no error and a valid colour space
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                double factor = mlt_properties_get_double( MLT_FRAME_PROPERTIES( this ), "boxblur" );
                if (factor != 0) {
@@ -178,7 +179,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
                        DoBoxBlur (*image, rgb, *width, h, (int) factor*hori, (int) factor*vert);
                        mlt_pool_release (rgb);
                }
-       }
+       }
        return error;
 }
 
index d01944f1521107f4c3081561ec6abef4599fc019..1cb27dd332e623c86235e33b9481d94d32f71807 100644 (file)
@@ -63,24 +63,24 @@ static void DoWave(uint8_t *src, int src_w, int src_h, uint8_t *dst, mlt_positio
 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
 {
        // Get the image
-       int error = mlt_frame_get_image( this, image, format, width, height, 1 );
+       *format = mlt_image_yuv422;
+       int error = mlt_frame_get_image( this, image, format, width, height, 0 );
        mlt_position position = mlt_frame_get_position( this );
 
        // Only process if we have no error and a valid colour space
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                double factor = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "wave" );
                int speed = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "speed" );
-               int deformX = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "deformX" );
-               int deformY = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "deformY" );
-               if (factor != 0) {
+               int deformX = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "deformX" );
+               int deformY = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "deformY" );
+               if (factor != 0) {
                        int image_size = *width * (*height + 1) * 2;
-                       uint8_t *dest = mlt_pool_alloc (image_size);
-                       DoWave(*image, *width, (*height + 1), dest, position, speed, factor, deformX, deformY);
-                       memcpy(*image, dest, image_size);
-                       mlt_pool_release(dest);
-               }
-       }
+                       *image = mlt_pool_alloc (image_size);
+                       DoWave(*image, *width, (*height + 1), *image, position, speed, factor, deformX, deformY);
+                       mlt_properties_set_data( MLT_FRAME_PROPERTIES( this ), "image", *image, image_size, mlt_pool_release, NULL );
+               }
+       }
 
        return error;
 }
index a96ca3a791679fa08a94695f8cfd8c83c61edc8d..0249a443cfa176ea30275ebecef29513f32eb4a5 100644 (file)
@@ -116,6 +116,9 @@ static int framebuffer_get_image( mlt_frame this, uint8_t **image, mlt_image_for
                case mlt_image_rgb24:
                        size = *width * ( *height + 1 ) * 3;
                        break;
+               case mlt_image_rgb24a:
+                       size = *width * ( *height + 1 ) * 4;
+                       break;
                default:
                        *format = mlt_image_yuv422;
                        size = *width * ( *height + 1 ) * 2;
@@ -133,7 +136,7 @@ static int framebuffer_get_image( mlt_frame this, uint8_t **image, mlt_image_for
        }
 
        // Which frames are buffered?
-       uint8_t *first_image = mlt_properties_get_data( first_frame_properties, "image", NULL );
+       uint8_t *first_image = mlt_properties_get_data( first_frame_properties, "image", &size );
        if( first_image == NULL )
        {
                mlt_properties props = MLT_FRAME_PROPERTIES( this );
index 8165141a380ae20b2f29989096d06dbdb29936e9..c1f91071e0fac7c16313d52d31581d3c34970840 100644 (file)
@@ -87,17 +87,9 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        // There is no way to detect a crop for sure, so make up an arbitrary one
        int thresh = mlt_properties_get_int( properties, "thresh" );
 
-       int xstride, ystride;
-
-       switch( *format ) {
-               case mlt_image_yuv422:
-                       xstride = 2;
-                       ystride = 2 * *width;
-                       break;
-               default:
-                       fprintf(stderr, "image format not supported by filter_crop_detect\n");
-                       return -1;
-       }
+       *format = mlt_image_yuv422;
+       int xstride = 2;
+       int ystride = 2 * *width;
 
        int x, y, average_brightness, deviation; // Scratch variables
        uint8_t *q;
index 6e8b021880e0938cebe6bf4cfe34293c2cf6718b..25cfe524dd9da9bb4d0629190fcbe1b484a878f5 100644 (file)
@@ -787,6 +787,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
 
 
        // Get the new image and frame number
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( frame, image, format, width, height, 1 );
 
        #ifdef BENCHMARK
@@ -869,17 +870,8 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                c->former_vectors_valid = 0;
                memset( c->former_vectors, 0, c->mv_size );
 
-               // Calculate the size of our steps (the number of bytes that seperate adjacent pixels in X and Y direction)
-               switch( *format ) {
-                       case mlt_image_yuv422:
-                               c->xstride = 2;
-                               c->ystride = c->xstride * *width;
-                               break;
-                       default:
-                               // I don't know
-                               fprintf(stderr, "\"I am unfamiliar with your new fangled pixel format!\" -filter_motion_est\n");
-                               return -1;
-               }
+               c->xstride = 2;
+               c->ystride = c->xstride * *width;
 
                // Allocate a cache for the previous frame's image
                c->former_image = mlt_pool_alloc( *width * *height * 2 );
index eb0d9870a0488afaa508127ded5404ec11ffa964..90de5e13abe403ab0df361222d229bb492c741d7 100644 (file)
@@ -75,6 +75,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
        mlt_properties properties = MLT_FRAME_PROPERTIES(frame);
 
        // Get the new image
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( frame, image, format, width, height, 1 );
 
        if( error != 0 )
index 016b5d59b05d87bbe1e8ba1a16fcbd4d27d2c635..d08d4b55d959ba27aa14b0659268ad4f0fed9a1a 100644 (file)
@@ -163,17 +163,10 @@ static int slowmotion_get_image( mlt_frame this, uint8_t **image, mlt_image_form
        mlt_properties second_frame_properties = MLT_FRAME_PROPERTIES( second_frame );
 
        // image stride
-       int size, xstride, ystride;
-       switch( *format ){
-               case mlt_image_yuv422:
-                       size = *width * *height * 2;
-                       xstride = 2;
-                       ystride = 2 * *width;
-                       break;
-               default:
-                       fprintf(stderr, "Unsupported image format\n");
-                       return -1;
-       }
+       *format = mlt_image_yuv422;
+       int size = *width * *height * 2;
+       int xstride = 2;
+       int ystride = 2 * *width;
 
        uint8_t *output = mlt_properties_get_data( producer_properties, "output_buffer", 0 );
        if( output == NULL )
index fc62024f0c5655f6e11325a3f2fb05c2a00c939d..140b759d369288c24d8c780140c5c0b51cb54564 100644 (file)
@@ -70,7 +70,8 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        mlt_position out = mlt_filter_get_out( filter );
        mlt_position time = mlt_frame_get_position( this );
        double position = ( double )( time - in ) / ( double )( out - in + 1 );
-
+       
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );       
        // load svg
        mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
@@ -156,7 +157,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        }
        if (piccount>0 )
                return 0;
-       if ( error == 0 && *image && *format == mlt_image_yuv422 )
+       if ( error == 0 && *image )
        {
 
                int h = *height;
index 296da5a89b054bb042f7ecdac58cb5c13664cc41..1095d1a1b2eaf2f480771a839fd05f656ae7dccd 100644 (file)
@@ -30,9 +30,10 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 {
 
        mlt_filter filter = mlt_frame_pop_service( this );
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
        
-       if ( error == 0 && *image && *format == mlt_image_yuv422 )
+       if ( error == 0 && *image )
        {
                int h = *height;
                int w = *width;
index 7d3e415ee16c57035e954f055406c9ec761ad4d0..bd77c2397d7e56ec26b2952a117deefd3c0045cf 100644 (file)
@@ -28,9 +28,10 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 {
 
        mlt_filter filter = mlt_frame_pop_service( this );
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
-       if ( error == 0 && *image && *format == mlt_image_yuv422 )
+       if ( error == 0 && *image )
        {
                int h = *height;
                int w = *width;
index 11a6c3e9e00c7d6486e32b6c589f23371328687e..398aa44b0b9fbe3eb5296954fab2cfd967940de5 100644 (file)
@@ -29,9 +29,10 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 {
 
        mlt_filter filter = mlt_frame_pop_service( this );
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
        
-       if (  error == 0 && *image && *format == mlt_image_yuv422 )
+       if (  error == 0 && *image )
        {
                int h = *height;
                int w = *width;
index 824f107ed764e5bcc2928542b1760fd90d0b675e..86b2bbcc2f56fc5e2571b162a641e9969a4ab167 100644 (file)
@@ -31,9 +31,10 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 {
 
        mlt_filter filter = mlt_frame_pop_service( this );
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
-       if ( error == 0 && *image && *format == mlt_image_yuv422 )
+       if ( error == 0 && *image )
        {
 
                double over_cr = mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "oversaturate_cr" )/100.0;
index e9e3f5d0f814a44086b990deeeac8b4a98869b34..2788470e38febe64fae0b42f5abf82a1952782bc 100644 (file)
@@ -35,9 +35,10 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 {
        
        mlt_filter filter = mlt_frame_pop_service( this );
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
-       if ( error == 0 && *image && *format == mlt_image_yuv422 )
+       if ( error == 0 && *image )
        {
                mlt_position in = mlt_filter_get_in( filter );
                //mlt_position out = mlt_filter_get_out( filter );
index 0ba2f9d5cc10141d3b9244ffa7afa0e04394e5b6..1c05fbd64b0eb6ea51a367828deb99f67e7467c1 100644 (file)
@@ -37,10 +37,12 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
 
        // Get the image
-       int error = 0; //mlt_frame_get_image( this, image, format, width, height, 0 );
+       int error = 0;
+       *format = mlt_image_yuv422;
+       //mlt_frame_get_image( this, image, format, width, height, 0 );
 
        // Only process if we have no error and a valid colour space
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL );
                mlt_transition transition = mlt_properties_get_data( properties, "transition", NULL );
index e99981a56add6ddeb096bb95e24eb8574224f39b..3c7c22cd74f9baca6d291ac401939323b87e84b9 100644 (file)
@@ -72,10 +72,11 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        mlt_filter filter = mlt_frame_pop_service( this );
 
        // Get the image
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
        // Only process if we have no error and a valid colour space
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                // Get the charcoal scatter value
                int x_scatter = mlt_properties_get_double( MLT_FILTER_PROPERTIES( filter ), "x_scatter" );
index 4385fc8674fba567cdf788160ded5ed198becf79..f283073948b6c2a003cc222e63f84c71d14eb67f 100644 (file)
@@ -39,10 +39,11 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        // Get the image
        mlt_filter filter = mlt_frame_pop_service( this );
        int mask = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "alpha" );
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
        // Only process if we have no error and a valid colour space
-       if ( error == 0 && *format == mlt_image_yuv422 )
+       if ( error == 0 )
        {
                uint8_t *p = *image;
                uint8_t *q = *image + *width * *height * 2;
index aa20b23a71a8c3546b8b02c5a790bf43243d168e..bb675651f1cbec59596a3c1ea7e65d70580ef648 100644 (file)
@@ -34,10 +34,11 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        mlt_filter filter = mlt_frame_pop_service( this );
 
        // Get the image
+       *format = mlt_image_yuv422;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
 
        // Only process if we have no error and a valid colour space
-       if ( error == 0 && *image && *format == mlt_image_yuv422 )
+       if ( error == 0 && *image )
        {
                // We modify the whole image
                uint8_t *p = *image;
index 719705618605edc4c6d9c8cc6bb041d00c8e2d57..a9a813dafaa18229b0e3a1e9f1e33f4da8d58916 100644 (file)
@@ -401,6 +401,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
                position = abs( position - length );
 
        // Fetch the a frame image
+       *format = mlt_image_yuv422;
        mlt_frame_get_image( a_frame, image, format, width, height, 1 );
 
        // Calculate the region now
index d2af3677a4da8f05493116bab049dd1dc717b925..bf7db6fe7780f4d069a5cb009420a4fd280522cd 100644 (file)
@@ -184,83 +184,43 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        // Refresh the image
        refresh_qimage( this, frame, *width, *height );
 
-       // We need to know the size of the image to clone it
-       int image_size = this->current_width * ( this->current_height + 1 ) * 2;
-       int alpha_size = this->current_width * this->current_height;
-
        // Get width and height (may have changed during the refresh)
        *width = mlt_properties_get_int( properties, "width" );
        *height = mlt_properties_get_int( properties, "height" );
 
        // NB: Cloning is necessary with this producer (due to processing of images ahead of use)
        // The fault is not in the design of mlt, but in the implementation of the qimage producer...
-       if ( this->current_image != NULL )
+       if ( this->current_image )
        {
-               if ( *format == mlt_image_yuv422 || *format == mlt_image_yuv420p )
-               {
-                       // Clone the image and the alpha
-                       uint8_t *image_copy = mlt_pool_alloc( image_size );
-                       uint8_t *alpha_copy = mlt_pool_alloc( alpha_size );
-
-                       memcpy( image_copy, this->current_image, image_size );
-
-                       // Copy or default the alpha
-                       if ( this->current_alpha )
-                               memcpy( alpha_copy, this->current_alpha, alpha_size );
-                       else
-                               memset( alpha_copy, 255, alpha_size );
-
-                       // Now update properties so we free the copy after
-                       mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL );
-                       mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL );
-
-                       // We're going to pass the copy on
-                       *buffer = image_copy;
-               }
-               else if ( *format == mlt_image_rgb24a )
-               {
-                       // Clone the image and the alpha
-                       image_size = *width * ( *height + 1 ) * 4;
-                       alpha_size = *width * ( *height + 1 );
-                       uint8_t *image_copy = mlt_pool_alloc( image_size );
-                       uint8_t *alpha_copy = mlt_pool_alloc( alpha_size );
-
-                       mlt_convert_yuv422_to_rgb24a(this->current_image, image_copy, (*width)*(*height));
-
-                       // Now update properties so we free the copy after
-                       mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL );
-                       mlt_properties_set_data( properties, "alpha", alpha_copy, alpha_size, mlt_pool_release, NULL );
-
-                       // We're going to pass the copy on
-                       *buffer = image_copy;
-               }
+               // Clone the image and the alpha
+               int image_size = this->current_width * ( this->current_height + 1 ) * ( this->has_alpha ? 4 :3 );
+               uint8_t *image_copy = mlt_pool_alloc( image_size );
+               memcpy( image_copy, this->current_image, image_size );
+               // Now update properties so we free the copy after
+               mlt_properties_set_data( properties, "image", image_copy, image_size, mlt_pool_release, NULL );
+               // We're going to pass the copy on
+               *buffer = image_copy;
+               *format = this->has_alpha ? mlt_image_rgb24a : mlt_image_rgb24;
+               mlt_log_debug( MLT_PRODUCER_SERVICE( &this->parent ), "%dx%d (%s)\n", 
+                       this->current_width, this->current_height, mlt_image_format_name( *format ) );
        }
        else
        {
                // TODO: Review all cases of invalid images
                *buffer = mlt_pool_alloc( 50 * 50 * 2 );
-               mlt_properties_set_data( properties, "image", *buffer, image_size, mlt_pool_release, NULL );
+               mlt_properties_set_data( properties, "image", *buffer, 50 * 50 * 2, mlt_pool_release, NULL );
                *width = 50;
                *height = 50;
+               *format = mlt_image_yuv422;
        }
 
        // Release references and locks
        pthread_mutex_unlock( &this->mutex );
        mlt_cache_item_close( this->image_cache );
-       mlt_cache_item_close( this->alpha_cache );
 
        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
@@ -296,9 +256,6 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( producer_properties, "progressive" ) );
                mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_properties, "aspect_ratio" ) );
 
-               // Set alpha call back
-               ( *frame )->get_alpha_mask = producer_get_alpha_mask;
-
                // Push the get_image method
                mlt_frame_push_get_image( *frame, producer_get_image );
        }
index 6c038f64610b537f9c23519d435e0e93977cb053..ed52681cc8453ebdcf202f8d680a26c0b47989f7 100644 (file)
@@ -39,6 +39,7 @@
 #include <QtGui/QImage>
 #include <QtCore/QSysInfo>
 #include <QtCore/QMutex>
+#include <QtCore/QtEndian>
 #endif
 
 
@@ -96,10 +97,6 @@ void refresh_qimage( producer_qimage self, mlt_frame frame, int width, int heigh
        self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.image" );
        self->current_image = static_cast<uint8_t*>( mlt_cache_item_data( self->image_cache, NULL ) );
 
-       // restore alpha channel
-       self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.alpha" );
-       self->current_alpha = static_cast<uint8_t*>( mlt_cache_item_data( self->alpha_cache, NULL ) );
-
        // Check if user wants us to reload the image
        if ( mlt_properties_get_int( producer_props, "force_reload" ) ) 
        {
@@ -149,7 +146,7 @@ void refresh_qimage( producer_qimage self, mlt_frame frame, int width, int heigh
                        mlt_properties_set_int( producer_props, "_real_width", mlt_properties_get_int( cached_props, "real_width" ) );
                        mlt_properties_set_int( producer_props, "_real_height", mlt_properties_get_int( cached_props, "real_height" ) );
                        self->current_image = ( uint8_t * )mlt_properties_get_data( cached_props, "image", NULL );
-                       self->current_alpha = ( uint8_t * )mlt_properties_get_data( cached_props, "alpha", NULL );
+                       self->has_alpha = mlt_properties_get_int( cached_props, "alpha" );
 
                        if ( width != 0 && ( width != self->current_width || height != self->current_height ) )
                                self->current_image = NULL;
@@ -204,61 +201,52 @@ void refresh_qimage( producer_qimage self, mlt_frame frame, int width, int heigh
 
 #ifdef USE_QT4
                // Note - the original qimage is already safe and ready for destruction
-               QImage scaled = interp == 0 ? qimage->scaled( QSize( width, height)) : qimage->scaled( QSize(width, height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+               QImage scaled = interp == 0 ? qimage->scaled( QSize( width, height ) ) :
+                       qimage->scaled( QSize(width, height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
                QImage temp;
-               bool hasAlpha = scaled.hasAlphaChannel();
-               if (hasAlpha)
-                   temp = scaled.convertToFormat(QImage::Format_ARGB32);
-               else 
-                   temp = scaled.convertToFormat(QImage::Format_RGB888);
+               self->has_alpha = scaled.hasAlphaChannel();
 #endif
 
 #ifdef USE_QT3
                // Note - the original qimage is already safe and ready for destruction
-               QImage scaled = interp == 0 ? qimage->scale( width, height, QImage::ScaleFree ) : qimage->smoothScale( width, height, QImage::ScaleFree );
-               QImage temp = scaled.convertDepth( 32 );
-               bool hasAlpha = true;
+               QImage scaled = interp == 0 ? qimage->scale( width, height, QImage::ScaleFree ) :
+                       qimage->smoothScale( width, height, QImage::ScaleFree );
+               self->has_alpha = 1;
 #endif
 
                // Store width and height
                self->current_width = width;
                self->current_height = height;
-               
+
                // Allocate/define image
-               self->current_image = ( uint8_t * )mlt_pool_alloc( width * ( height + 1 ) * 2 );
+               int dst_stride = width * ( self->has_alpha ? 4 : 3 );
+               int image_size = dst_stride * ( height + 1 );
+               self->current_image = ( uint8_t * )mlt_pool_alloc( image_size );
+
+               // Copy the image
+               int y = self->current_height + 1;
+               uint8_t *dst = self->current_image;
+               while ( --y )
+               {
+                       QRgb *src = (QRgb*) scaled.scanLine( self->current_height - y );
+                       int x = self->current_width + 1;
+                       while ( --x )
+                       {
+                               *dst++ = qRed(*src);
+                               *dst++ = qGreen(*src);
+                               *dst++ = qBlue(*src);
+                               if ( self->has_alpha ) *dst++ = qAlpha(*src);
+                               ++src;
+                       }
+               }
+
+               // Update the cache
                if ( !use_cache )
                        mlt_cache_item_close( self->image_cache );
-               mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.image", self->current_image, width * ( height + 1 ) * 2, mlt_pool_release );
+               mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.image", self->current_image, image_size, mlt_pool_release );
                self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.image" );
                self->image_idx = image_idx;
 
-               if (!hasAlpha) {
-                       mlt_convert_rgb24_to_yuv422( temp.bits(), self->current_width, self->current_height, temp.bytesPerLine(), self->current_image ); 
-               }
-               else {
-                       // Allocate the alpha mask
-                       self->current_alpha = ( uint8_t * )mlt_pool_alloc( width * height );
-                       if ( !use_cache )
-                               mlt_cache_item_close( self->alpha_cache );
-                       mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.alpha", self->current_alpha, width * height, mlt_pool_release );
-                       self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.alpha" );
-
-#ifdef USE_QT4
-                       if ( QSysInfo::ByteOrder == QSysInfo::BigEndian )
-                               mlt_convert_argb_to_yuv422( temp.bits( ), self->current_width, self->current_height, temp.bytesPerLine(), self->current_image, self->current_alpha );
-                       else
-                               mlt_convert_bgr24a_to_yuv422( temp.bits( ), self->current_width, self->current_height, temp.bytesPerLine( ), self->current_image, self->current_alpha );
-#endif
-
-#ifdef USE_QT3
-                       // Convert the image
-                       if ( QImage::systemByteOrder( ) == QImage::BigEndian )
-                               mlt_convert_argb_to_yuv422( temp.bits( ), self->current_width, self->current_height, temp.bytesPerLine( ), self->current_image, self->current_alpha );
-                       else
-                               mlt_convert_bgr24a_to_yuv422( temp.bits( ), self->current_width, self->current_height, temp.bytesPerLine( ), self->current_image, self->current_alpha );
-#endif
-               }
-
                // Ensure we update the cache when we need to
                update_cache = use_cache;
        }
@@ -269,7 +257,6 @@ void refresh_qimage( producer_qimage self, mlt_frame frame, int width, int heigh
        {
                pthread_mutex_unlock( &self->mutex );
                mlt_cache_item_close( self->image_cache );
-               mlt_cache_item_close( self->alpha_cache );
        }
 
        // Set width/height of frame
@@ -286,8 +273,10 @@ void refresh_qimage( producer_qimage self, mlt_frame frame, int width, int heigh
                mlt_properties_set_int( cached_props, "height", self->current_height );
                mlt_properties_set_int( cached_props, "real_width", mlt_properties_get_int( producer_props, "_real_width" ) );
                mlt_properties_set_int( cached_props, "real_height", mlt_properties_get_int( producer_props, "_real_height" ) );
-               mlt_properties_set_data( cached_props, "image", self->current_image, self->current_width * ( self->current_height + 1 ) * 2, mlt_pool_release, NULL );
-               mlt_properties_set_data( cached_props, "alpha", self->current_alpha, self->current_width * self->current_height, mlt_pool_release, NULL );
+               mlt_properties_set_data( cached_props, "image", self->current_image,
+                       self->current_width * ( self->current_height + 1 ) * ( self->has_alpha ? 4 : 3 ),
+                       mlt_pool_release, NULL );
+               mlt_properties_set_int( cached_props, "alpha", self->has_alpha );
                mlt_properties_set_data( cache, image_key, cached, 0, ( mlt_destructor )mlt_frame_close, NULL );
        }
        g_mutex.unlock();
index c87b193041197c201bee7e5a1076a6e65ef887ea..22b1110b4aae2af21613b74cc37625858ffb4b89 100644 (file)
@@ -41,11 +41,10 @@ struct producer_qimage_s
        int image_idx;
        int qimage_idx;
        uint8_t *current_image;
-       uint8_t *current_alpha;
+       int has_alpha;
        int current_width;
        int current_height;
        mlt_cache_item image_cache;
-       mlt_cache_item alpha_cache;
        pthread_mutex_t mutex;
 };
 
index 38322370235bbf8aa1b26f4c4c5e8992bba79b7a..13c4a0c2895caaf174190281f16b8262f9ce8aaf 100644 (file)
@@ -64,7 +64,6 @@ struct consumer_sdl_s
        SDL_Rect rect;
        uint8_t *buffer;
        int bpp;
-       int filtered;
 };
 
 /** Forward references to static functions.
@@ -183,20 +182,6 @@ int consumer_start( mlt_consumer parent )
 
                this->bpp = mlt_properties_get_int( this->properties, "bpp" );
 
-               // Attach a colour space converter
-               if ( preview_off && !this->filtered )
-               {
-                       mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( parent ) );
-                       mlt_filter filter = mlt_factory_filter( profile, "avcolour_space", NULL );
-                       if ( filter )
-                       {
-                               mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "forced", mlt_image_yuv422 );
-                               mlt_service_attach( MLT_CONSUMER_SERVICE( parent ), filter );
-                               mlt_filter_close( filter );
-                       }
-                       this->filtered = 1;
-               }
-       
                if ( sdl_started == 0 && display_off == 0 )
                {
                        if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 )
index 3efd8f4eb63c389338bfcac4eb7d7c23c2eeee3e..755dd9ac073b9960ec49aa63ed02031b4d9e61ed 100644 (file)
@@ -23,6 +23,7 @@
 #include <framework/mlt_deque.h>
 #include <framework/mlt_factory.h>
 #include <framework/mlt_filter.h>
+#include <framework/mlt_log.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -54,7 +55,6 @@ struct consumer_sdl_s
        uint8_t *buffer;
        int last_position;
        mlt_producer last_producer;
-       int filtered;
 };
 
 /** Forward references to static functions.
@@ -96,9 +96,6 @@ mlt_consumer consumer_sdl_still_init( mlt_profile profile, mlt_service_type type
                // We're always going to run this in non-realtime mode
                mlt_properties_set( this->properties, "real_time", "0" );
 
-               // Default progressive true
-               mlt_properties_set_int( this->properties, "progressive", 1 );
-
                // Ensure we don't join on a non-running object
                this->joined = 1;
                
@@ -151,17 +148,6 @@ static int consumer_start( mlt_consumer parent )
                int preview_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "preview_off" );
                int sdl_started = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" );
 
-               // Attach a colour space converter
-               if ( !this->filtered )
-               {
-                       mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( parent ) );
-                       mlt_filter filter = mlt_factory_filter( profile, "avcolour_space", NULL );
-                       mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "forced", mlt_image_yuv422 );
-                       mlt_service_attach( MLT_CONSUMER_SERVICE( parent ), filter );
-                       mlt_filter_close( filter );
-                       this->filtered = 1;
-               }
-       
                consumer_stop( parent );
 
                this->last_position = -1;
@@ -439,23 +425,21 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame )
                SDL_FillRect( this->sdl_screen, NULL, color >> 8 );
                changed = 1;
        }
-       else
-       {
-               changed = 1;
-       }
 
        if ( changed == 0 &&
                 this->last_position == mlt_frame_get_position( frame ) &&
-                this->last_producer == mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "_producer", NULL ) )
+                this->last_producer == mlt_frame_get_original_producer( frame ) )
        {
                sdl_unlock_display( );
                if ( unlock != NULL ) unlock( );
+               struct timespec tm = { 0, 100000 };
+               nanosleep( &tm, NULL );
                return 0;
        }
 
        // Update last frame shown info
        this->last_position = mlt_frame_get_position( frame );
-       this->last_producer = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "_producer", NULL );
+       this->last_producer = mlt_frame_get_original_producer( frame );
 
        // Get the image, width and height
        mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 );
@@ -539,21 +523,10 @@ static void *consumer_thread( void *arg )
        // Get the consumer
        mlt_consumer consumer = &this->parent;
        mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
-
-       // internal intialization
        mlt_frame frame = NULL;
-       mlt_image_format vfmt = mlt_image_rgb24a;
-       int height = this->height;
-       int width = this->width;
-       uint8_t *image = NULL;
 
        // Allow the hosting app to provide the preview
        int preview_off = mlt_properties_get_int( properties, "preview_off" );
-       mlt_image_format preview_format = mlt_properties_get_int( properties, "preview_format" );
-
-       // Check if a specific colour space has been requested
-       if ( preview_off && preview_format != mlt_image_none )
-               vfmt = preview_format;
 
        // Loop until told not to
        while( this->running )
@@ -570,6 +543,16 @@ static void *consumer_thread( void *arg )
                        }
                        else
                        {
+                               mlt_image_format vfmt = mlt_image_rgb24a;
+                               int height = this->height;
+                               int width = this->width;
+                               uint8_t *image = NULL;
+                               mlt_image_format preview_format = mlt_properties_get_int( properties, "preview_format" );
+
+                               // Check if a specific colour space has been requested
+                               if ( preview_off && preview_format != mlt_image_none )
+                                       vfmt = preview_format;
+                       
                                mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 );
                                mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "format", vfmt );
                                mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
index 19f4f4b0e2e37d1bd763f9e9b3794ec689ca49c7..0d6246643488e79289e86df0cf250976e3471e2b 100644 (file)
@@ -38,13 +38,10 @@ static int producer_get_image( mlt_frame frame, uint8_t **image, mlt_image_forma
        mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
        SDL_Surface *surface = mlt_properties_get_data( properties, "surface", NULL );
        SDL_Surface *converted = NULL;
-       uint8_t *alpha;
 
        *width = surface->w;
        *height = surface->h;
-       *format = mlt_image_yuv422;
-       *image = mlt_pool_alloc( *width * *height * 2 );
-       alpha = mlt_pool_alloc( *width * *height );
+       int image_size = *width * *height * 3;
 
        if ( surface->format->BitsPerPixel != 32 && surface->format->BitsPerPixel != 24 )
        {
@@ -63,15 +60,19 @@ static int producer_get_image( mlt_frame frame, uint8_t **image, mlt_image_forma
        switch( surface->format->BitsPerPixel )
        {
                case 32:
-                       mlt_convert_rgb24a_to_yuv422( surface->pixels, *width, *height, surface->pitch, *image, alpha );
+                       *format = mlt_image_rgb24a;
+                       image_size = *width * *height * 4;
+                       *image = mlt_pool_alloc( image_size );
+                       memcpy( *image, surface->pixels, image_size );
                        break;
                case 24:
-                       mlt_convert_rgb24_to_yuv422( surface->pixels, *width, *height, surface->pitch, *image );
-                       memset( alpha, 255, *width * *height );
+                       *format = mlt_image_rgb24;
+                       *image = mlt_pool_alloc( image_size );
+                       memcpy( *image, surface->pixels, image_size );
                        break;
                default:
-                       mlt_convert_rgb24_to_yuv422( converted->pixels, *width, *height, converted->pitch, *image );
-                       memset( alpha, 255, *width * *height );
+                       *image = mlt_pool_alloc( image_size );
+                       memcpy( *image, converted->pixels, image_size );
                        break;
        }
 
@@ -79,8 +80,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **image, mlt_image_forma
                SDL_FreeSurface( converted );
 
        // Update the frame
-       mlt_properties_set_data( properties, "image", *image, *width * *height * 2, mlt_pool_release, NULL );
-       mlt_properties_set_data( properties, "alpha", alpha, *width * *height, mlt_pool_release, NULL );
+       mlt_properties_set_data( properties, "image", *image, image_size, mlt_pool_release, NULL );
        mlt_properties_set_int( properties, "width", *width );
        mlt_properties_set_int( properties, "height", *height );
 
index de54135cf6017e0fa216fba2ab7abbb741478234..df8c4bfb29bcfbb82c03f2140d20c035d5704ac4 100644 (file)
@@ -53,6 +53,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
 
        RGB2YUV( r, g, b, y, u, v );
 
+       *format = mlt_image_yuv422;
        if ( mlt_frame_get_image( frame, image, format, width, height, writable ) == 0 )
        {
                uint8_t *alpha = mlt_frame_get_alpha_mask( frame );
index 07ca4a800e25b218d87bdfbba9c881fd71af4006..d375faa5ad0e78f523e73f1ddd712e4d12f30027 100644 (file)
@@ -53,6 +53,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
 
        RGB2YUV( r, g, b, y, u, v );
 
+       *format = mlt_image_yuv422;
        if ( mlt_frame_get_image( frame, image, format, width, height, writable ) == 0 )
        {
                uint8_t alpha = 0;
index f7ea11d0088ad7c3f492957ba3bc69dbf24ef1f1..7e75f94090b5c58bfed10b6becdf451ba693e423 100644 (file)
@@ -35,6 +35,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        int invert = mlt_deque_pop_back_int( MLT_FRAME_IMAGE_STACK( this ) );
 
        // Render the frame
+       *format = mlt_image_yuv422;
        if ( mlt_frame_get_image( this, image, format, width, height, writable ) == 0 )
        {
                uint8_t *p = *image;
index fdd33e435233bb34eaf30077ca83fe187d903473..00b0ed082538d743719d39c260a562960b019131 100644 (file)
@@ -49,6 +49,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        int invert = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "invert" ) * 255;
 
        // Render the frame
+       *format = mlt_image_yuv422;
        if ( mlt_frame_get_image( this, image, format, width, height, writable ) == 0 && ( !use_luminance || ( int )mix != 1 ) )
        {
                // Get the alpha mask of the source
index 01871cf3348ce23a1b355d86be4b1213a4c3a1d9..840b5f072a8e877d2a3e2fed0f766f664690cf89 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <framework/mlt_filter.h>
+#include <framework/mlt_log.h>
 #include "deinterlace.h"
 
 #include <framework/mlt_frame.h>
@@ -33,19 +34,25 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
 {
        int error = 0;
        int deinterlace = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "consumer_deinterlace" );
+       int progressive = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" );
        
        // Pop the service off the stack
        mlt_filter filter = mlt_frame_pop_service( this );
 
        // Determine if we need a writable version or not
        if ( deinterlace && !writable )
-                writable = !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" );
+                writable = !progressive;
 
        // Get the input image
+       if ( deinterlace && !progressive )
+               *format = mlt_image_yuv422;
+       mlt_log_debug( MLT_FILTER_SERVICE( filter ), "xine.deinterlace %d prog %d format %s\n",
+               deinterlace, progressive, mlt_image_format_name( *format ) );
        error = mlt_frame_get_image( this, image, format, width, height, writable );
+       progressive = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" );
 
        // Check that we want progressive and we aren't already progressive
-       if ( deinterlace && *format == mlt_image_yuv422 && *image != NULL && !mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "progressive" ) )
+       if ( deinterlace && *format == mlt_image_yuv422 && *image && !progressive )
        {
                // Determine deinterlace method
                char *method_str = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "method" );