]> git.sesse.net Git - mlt/commitdiff
src/framework/mlt_frame.c
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Thu, 15 Sep 2005 20:34:47 +0000 (20:34 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Thu, 15 Sep 2005 20:34:47 +0000 (20:34 +0000)
+ Removed unecessary even pixel position and width dependency
+ Rewrote resize methods to accomodate uneven widths

src/framework/mlt_frame.h
+ Correct RGB2YUV - now 2^10 based and range checks removed (not needed)

src/framework/mlt_producer.c
+ Check for unspecified eof property

src/modules/avformat/producer_avformat.c
+ Provide forced aspect ratio property

src/modules/core/filter_mirror.c
+ Correction for uneven width

src/modules/core/producer_colour.c
+ Corrections for aspect ratio (default to 0) and allow override
+ Corrections for uneven width

src/modules/core/transition_composite.c
+ Corrections for uneven pixel position and width
+ Removed deprecated operator code

src/modules/plus/filter_sepia.c
+ Corrections for uneven width

src/modules/plus/transition_affine.c
+ Corrections for uneven width

src/modules/sdl/consumer_sdl.c
+ Corrections for uneven width

git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@825 d19143bc-622f-0410-bfdd-b5b2a6649095

src/framework/mlt_frame.c
src/framework/mlt_frame.h
src/framework/mlt_producer.c
src/modules/avformat/configure
src/modules/avformat/producer_avformat.c
src/modules/core/filter_mirror.c
src/modules/core/producer_colour.c
src/modules/core/transition_composite.c
src/modules/plus/filter_sepia.c
src/modules/plus/transition_affine.c
src/modules/sdl/consumer_sdl.c

index 57c53b80eebcc964a66b4c51748584658fd641bc..1e080fa80948876d87860459fbc249ab595cc79e 100644 (file)
@@ -263,8 +263,6 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for
        mlt_producer producer = mlt_properties_get_data( properties, "test_card_producer", NULL );
        int error = 0;
 
-       *width = *width >> 1 << 1;
-       
        if ( get_image != NULL )
        {
                mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 );
@@ -645,75 +643,27 @@ uint8_t *mlt_resize_alpha( uint8_t *input, int owidth, int oheight, int iwidth,
 
        if ( input != NULL && ( iwidth != owidth || iheight != oheight ) && ( owidth > 6 && oheight > 6 ) )
        {
-               iwidth = iwidth - ( iwidth % 2 );
-               owidth = owidth - ( owidth % 2 );
+               uint8_t *in_line = input;
+               uint8_t *out_line;
 
                output = mlt_pool_alloc( owidth * oheight );
+               memset( output, 0, owidth * oheight );
 
-               // Coordinates (0,0 is middle of output)
-               int y;
-
-               // Calculate ranges
-               int out_x_range = owidth / 2;
-               int out_y_range = oheight / 2;
-               int in_x_range = iwidth / 2 < out_x_range ? iwidth / 2 : out_x_range;
-               int in_y_range = iheight / 2 < out_y_range ? iheight / 2 : out_y_range;
-
-               // Output pointers
-               uint8_t *out_line = output;
-               uint8_t *out_ptr = out_line;
-
-               // Calculate a middle and possibly invalid pointer in the input
-               uint8_t *in_middle = input + iwidth * ( iheight / 2 ) + ( iwidth / 2 );
-               int in_line = - in_y_range * iwidth - in_x_range;
-
-               int elements;
-
-               // Fill whole section with black
-               y = out_y_range - ( iheight / 2 );
-               int blank_elements = owidth * y;
-               elements = blank_elements;
-               while ( elements -- )
-                       *out_line ++ = 0;
-
-               int active_width = iwidth;
-               int inactive_width = out_x_range - in_x_range;
-               uint8_t *p = NULL;
-               uint8_t *end = NULL;
+               out_line = output + ( ( oheight - iheight ) / 2 ) * owidth;
+               out_line += 2 * ( int )( ( owidth - iwidth ) / 2 );
 
                // Loop for the entirety of our output height.
                while ( iheight -- )
                {
-                       // Start at the beginning of the line
-                       out_ptr = out_line;
-
-                       // Fill the outer part with black
-                       elements = inactive_width;
-                       while ( elements -- )
-                               *out_ptr ++ = 0;
-
                        // We're in the input range for this row.
-                       p = in_middle + in_line;
-                       end = out_ptr + active_width;
-                       while ( out_ptr != end )
-                               *out_ptr ++ = *p ++;
-
-                       // Fill the outer part with black
-                       elements = inactive_width;
-                       while ( elements -- )
-                               *out_ptr ++ = 0;
-       
+                       memcpy( out_line, input, iwidth );
+
                        // Move to next input line
                        in_line += iwidth;
 
                        // Move to next output line
                        out_line += owidth;
                }
-
-               // Fill whole section with black
-               elements = blank_elements;
-               while ( elements -- )
-                       *out_line ++ = 0;
        }
 
        return output;
@@ -725,11 +675,6 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input
        int istride = iwidth * 2;
        int ostride = owidth * 2;
 
-       iwidth = iwidth - ( iwidth % 2 );
-       owidth = owidth - ( owidth % 2 );
-       //iheight = iheight - ( iheight % 2 );
-       //oheight = oheight - ( oheight % 2 );
-       
        // Optimisation point
        if ( output == NULL || input == NULL || ( owidth <= 6 || oheight <= 6 || iwidth <= 6 || oheight <= 6 ) )
        {
@@ -741,93 +686,33 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input
                return;
        }
 
-       // Coordinates (0,0 is middle of output)
-       int y;
-
-       // Calculate ranges
-       int out_x_range = owidth / 2;
-       int out_y_range = oheight / 2;
-       int in_x_range = iwidth / 2 < out_x_range ? iwidth / 2 : out_x_range;
-       int in_y_range = iheight / 2 < out_y_range ? iheight / 2 : out_y_range;
-
-       // Output pointers
-       uint8_t *out_line = output;
-       uint8_t *out_ptr = out_line;
-
-       // Calculate a middle and possibly invalid pointer in the input
-       uint8_t *in_middle = input + istride * ( iheight / 2 ) + iwidth;
-       int in_line = - in_y_range * istride - in_x_range * 2;
+       uint8_t *in_line = input;
+       uint8_t *out_line;
 
-       int elements;
+       int size = owidth * oheight;
+       uint8_t *p = output;
 
-       // Fill whole section with black
-       y = out_y_range - ( iheight / 2 );
-       int blank_elements = ostride * y / 2;
-       elements = blank_elements;
-       while ( elements -- )
+       while( size -- )
        {
-               *out_line ++ = 16;
-               *out_line ++ = 128;
-       }
-
-       int active_width = 2 * iwidth;
-       int left_inactive_width = out_x_range - in_x_range;
-       int right_inactive_width = left_inactive_width;
-       uint8_t *p = NULL;
-       uint8_t *end = NULL;
-
-       if ( in_line % 4 )
-       {
-               active_width -= 2;
-               in_middle += 2;
-               right_inactive_width += 2;
+               *p ++ = 16;
+               *p ++ = 128;
        }
 
+       out_line = output + ( ( oheight - iheight ) / 2 ) * ostride;
+       out_line += 4 * ( int )( ( owidth - iwidth ) / 4 );
+               
        // Loop for the entirety of our output height.
        while ( iheight -- )
        {
-               // Start at the beginning of the line
-               out_ptr = out_line;
-
-               // Fill the outer part with black
-               elements = left_inactive_width;
-               while ( elements -- )
-               {
-                       *out_ptr ++ = 16;
-                       *out_ptr ++ = 128;
-               }
-
                // We're in the input range for this row.
-               p = in_middle + in_line;
-               end = out_ptr + active_width;
-               while ( out_ptr != end )
-               {
-                       *out_ptr ++ = *p ++;
-                       *out_ptr ++ = *p ++;
-               }
-
-               // Fill the outer part with black
-               elements = right_inactive_width;
-               while ( elements -- )
-               {
-                       *out_ptr ++ = 16;
-                       *out_ptr ++ = 128;
-               }
+               memcpy( out_line, in_line, istride );
 
-               // Move to next input line
-               in_line += istride;
+               // Move to next input line
+               in_line += istride;
 
-               // Move to next output line
-               out_line += ostride;
+               // Move to next output line
+               out_line += ostride;
        }
-
-       // Fill whole section with black
-       elements = blank_elements;
-       while ( elements -- )
-       {
-               *out_line ++ = 16;
-               *out_line ++ = 128;
-       }
 }
 
 /** A resizing function for yuv422 frames - this does not rescale, but simply
index d131c67b5fc89b5012995caf419fb036c59f2b53..18b1e608edb1e1e642e5bce7ac91b9e1c18b2ce0 100644 (file)
@@ -86,15 +86,9 @@ extern int64_t mlt_sample_calculator_to_now( float fps, int frequency, int64_t p
 
 /* 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)\
-  y = ((257*r + 504*g + 98*b) >> 10) + 16;\
-  u = ((-148*r - 291*g + 439*b) >> 10) + 128;\
-  v = ((439*r - 368*g - 71*b) >> 10) + 128;\
-  y = y < 16 ? 16 : y;\
-  u = u < 16 ? 16 : u;\
-  v = v < 16 ? 16 : v;\
-  y = y > 235 ? 235 : y;\
-  u = u > 240 ? 240 : u;\
-  v = v > 240 ? 240 : v
+  y = ((263*r + 516*g + 100*b) >> 10) + 16;\
+  u = ((-152*r - 298*g + 450*b) >> 10) + 128;\
+  v = ((450*r - 377*g - 73*b) >> 10) + 128;
 
 /* this macro assumes the user has already scaled their rgb down into the broadcast limits */
 #define RGB2YUV_UNSCALED(r, g, b, y, u, v)\
index 3f7a01b257fce41a05269608f59a6d68d3c3d94b..aece92b9a91582983b8fc680571e8d24e1746f87 100644 (file)
@@ -253,7 +253,7 @@ int mlt_producer_seek( mlt_producer this, mlt_position position )
        {
                position = 0;
        }
-       else if ( use_points && !strcmp( eof, "pause" ) && position >= mlt_producer_get_playtime( this ) )
+       else if ( use_points && ( eof == NULL || !strcmp( eof, "pause" ) ) && position >= mlt_producer_get_playtime( this ) )
        {
                mlt_producer_set_speed( this, 0 );
                position = mlt_producer_get_playtime( this ) - 1;
index ce10ddf212964c3259fd716784959db0b97c6c6c..c80628f7982e379fe1f42ef7df299ad390a73a3a 100755 (executable)
@@ -15,7 +15,7 @@ FFMPEG/avformat options:
 EOF
 
 else
-        targetos=$(uname -s)
+       targetos=$(uname -s)
        case $targetos in
        Darwin)
                export LIBSUF=.dylib
index efd520615178120ffae90ffb23f18f1d9704603a..b589468b0239c8b6d5415cacd54d5ba23b68aefb 100644 (file)
@@ -679,18 +679,24 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
                {
                        double source_fps = 0;
                        int norm_aspect_ratio = mlt_properties_get_int( properties, "norm_aspect_ratio" );
+                       double force_aspect_ratio = mlt_properties_get_double( properties, "force_aspect_ratio" );
+                       double aspect_ratio;
 
                        // XXX: We won't know the real aspect ratio until an image is decoded
                        // but we do need it now (to satisfy filter_resize) - take a guess based
                        // on pal/ntsc
-                       if ( !norm_aspect_ratio && codec_context->sample_aspect_ratio.num > 0 )
+                       if ( force_aspect_ratio > 0.0 )
                        {
-                               mlt_properties_set_double( properties, "aspect_ratio", av_q2d( codec_context->sample_aspect_ratio ) );
+                               aspect_ratio = force_aspect_ratio;
+                       }
+                       else if ( !norm_aspect_ratio && codec_context->sample_aspect_ratio.num > 0 )
+                       {
+                               aspect_ratio = av_q2d( codec_context->sample_aspect_ratio );
                        }
                        else
                        {
                                int is_pal = mlt_properties_get_double( properties, "fps" ) == 25.0;
-                               mlt_properties_set_double( properties, "aspect_ratio", is_pal ? 59.0/54.0 : 10.0/11.0 );
+                               aspect_ratio = is_pal ? 59.0/54.0 : 10.0/11.0;
                        }
 
                        // Determine the fps
@@ -699,10 +705,12 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
                        // We'll use fps if it's available
                        if ( source_fps > 0 && source_fps < 30 )
                                mlt_properties_set_double( properties, "source_fps", source_fps );
+                       mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio );
                        
                        // Set the width and height
                        mlt_properties_set_int( frame_properties, "width", codec_context->width );
                        mlt_properties_set_int( frame_properties, "height", codec_context->height );
+                       mlt_properties_set_double( frame_properties, "aspect_ratio", aspect_ratio );
 
                        mlt_frame_push_get_image( frame, producer_get_image );
                        mlt_properties_set_data( frame_properties, "avformat_producer", this, 0, NULL, NULL );
index a9678914f33858b8c6717e120f91422abbe87562..430e401ff59568ddf29a272cf4614458365b5673 100644 (file)
@@ -62,6 +62,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                        uint8_t *a = NULL;
                        uint8_t *b = NULL;
                        int i;
+                       int uneven_w = ( *width % 2 ) * 2;
                        for ( i = 0; i < *height; i ++ )
                        {
                                p = ( uint8_t * )*image + i * *width * 2;
@@ -73,9 +74,9 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                                        while ( p < q )
                                        {
                                                *p ++ = *( q - 2 );
-                                               *p ++ = *( q - 3 );
+                                               *p ++ = *( q - 3 - uneven_w );
                                                *p ++ = *( q - 4 );
-                                               *p ++ = *( q - 1 );
+                                               *p ++ = *( q - 1 - uneven_w );
                                                q -= 4;
                                                *a ++ = *b --;
                                                *a ++ = *b --;
@@ -86,9 +87,9 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                                        while ( p < q )
                                        {
                                                *( q - 2 ) = *p ++;
-                                               *( q - 3 ) = *p ++;
+                                               *( q - 3 - uneven_w ) = *p ++;
                                                *( q - 4 ) = *p ++;
-                                               *( q - 1 ) = *p ++;
+                                               *( q - 1 - uneven_w ) = *p ++;
                                                q -= 4;
                                                *b -- = *a ++;
                                                *b -- = *a ++;
@@ -139,6 +140,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                        uint8_t *b = NULL;
                        int i;
                        int j;
+                       int uneven_w = ( *width % 2 ) * 2;
                        for ( i = 0; i < *height; i ++ )
                        {
                                p = ( uint8_t * )*image + i * *width * 2;
@@ -151,9 +153,9 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                                        while ( j -- )
                                        {
                                                *p ++ = *( q - 2 );
-                                               *p ++ = *( q - 3 );
+                                               *p ++ = *( q - 3 - uneven_w );
                                                *p ++ = *( q - 4 );
-                                               *p ++ = *( q - 1 );
+                                               *p ++ = *( q - 1 - uneven_w );
                                                q -= 4;
                                                *a ++ = *b --;
                                                *a ++ = *b --;
@@ -164,9 +166,9 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                                        while ( j -- )
                                        {
                                                *( q - 2 ) = *p ++;
-                                               *( q - 3 ) = *p ++;
+                                               *( q - 3 - uneven_w ) = *p ++;
                                                *( q - 4 ) = *p ++;
-                                               *( q - 1 ) = *p ++;
+                                               *( q - 1 - uneven_w ) = *p ++;
                                                q -= 4;
                                                *b -- = *a ++;
                                                *b -- = *a ++;
@@ -183,6 +185,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                        int j;
                        uint8_t *a = NULL;
                        uint8_t *b = NULL;
+                       int uneven_w = ( *width % 2 ) * 2;
                        for ( i = 0; i < *height; i ++ )
                        {
                                p = ( uint8_t * )*image + ( i + 1 ) * *width * 2;
@@ -195,9 +198,9 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                                        while ( j -- )
                                        {
                                                *q ++ = *( p - 2 );
-                                               *q ++ = *( p - 3 );
+                                               *q ++ = *( p - 3 - uneven_w );
                                                *q ++ = *( p - 4 );
-                                               *q ++ = *( p - 1 );
+                                               *q ++ = *( p - 1 - uneven_w );
                                                p -= 4;
                                                *b ++ = *a --;
                                                *b ++ = *a --;
@@ -208,9 +211,9 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                                        while ( j -- )
                                        {
                                                *( p - 2 ) = *q ++;
-                                               *( p - 3 ) = *q ++;
+                                               *( p - 3 - uneven_w ) = *q ++;
                                                *( p - 4 ) = *q ++;
-                                               *( p - 1 ) = *q ++;
+                                               *( p - 1 - uneven_w ) = *q ++;
                                                p -= 4;
                                                *a -- = *b ++;
                                                *a -- = *b ++;
@@ -227,6 +230,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                        uint8_t *a = NULL;
                        uint8_t *b = NULL;
                        uint8_t c;
+                       int uneven_w = ( *width % 2 ) * 2;
                        for ( i = 0; i < *height; i ++ )
                        {
                                p = ( uint8_t * )*image + i * *width * 2;
@@ -236,13 +240,13 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                                while ( p < q )
                                {
                                        t[ 0 ] = p[ 0 ];
-                                       t[ 1 ] = p[ 1 ];
+                                       t[ 1 ] = p[ 1 + uneven_w ];
                                        t[ 2 ] = p[ 2 ];
-                                       t[ 3 ] = p[ 3 ];
+                                       t[ 3 ] = p[ 3 + uneven_w ];
                                        *p ++ = *( q - 2 );
-                                       *p ++ = *( q - 3 );
+                                       *p ++ = *( q - 3 - uneven_w );
                                        *p ++ = *( q - 4 );
-                                       *p ++ = *( q - 1 );
+                                       *p ++ = *( q - 1 - uneven_w );
                                        *( -- q ) = t[ 3 ];
                                        *( -- q ) = t[ 0 ];
                                        *( -- q ) = t[ 1 ];
index 75e7aa920790272b9689cc1e1692b2c2feb61e08..9f504f767c81aad8fd96811e705f2857929ee333 100644 (file)
@@ -50,6 +50,7 @@ mlt_producer producer_colour_init( char *colour )
                // Set the default properties
                mlt_properties_set( properties, "resource", colour == NULL ? "0x000000ff" : colour );
                mlt_properties_set( properties, "_resource", "" );
+               mlt_properties_set_double( properties, "aspect_ratio", 0 );
                
                return producer;
        }
@@ -135,7 +136,11 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        {
                // Color the image
                uint8_t y, u, v;
-               int i = 0;
+               int i = *height;
+               int j = 0;
+               int uneven = *width % 2;
+               int count = ( *width - uneven ) / 2;
+               uint8_t *p = NULL;
 
                // Allocate the image
                size = *width * *height * 2;
@@ -149,12 +154,23 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 
                RGB2YUV( color.r, color.g, color.b, y, u, v );
 
-               while ( i < size )
+               p = image;
+
+               while ( i -- )
                {
-                       image[ i ++ ] = y;
-                       image[ i ++ ] = u;
-                       image[ i ++ ] = y;
-                       image[ i ++ ] = v;
+                       j = count;
+                       while ( j -- )
+                       {
+                               *p ++ = y;
+                               *p ++ = u;
+                               *p ++ = y;
+                               *p ++ = v;
+                       }
+                       if ( uneven )
+                       {
+                               *p ++ = y;
+                               *p ++ = u;
+                       }
                }
        }
 
@@ -212,7 +228,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
 
                // Set producer-specific frame properties
                mlt_properties_set_int( properties, "progressive", 1 );
-               mlt_properties_set_double( properties, "aspect_ratio", 0 );
+               mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) );
 
                // colour is an alias for resource
                if ( mlt_properties_get( producer_props, "colour" ) != NULL )
index 4b514e010532710a4db36ce18700bf1b1f08f1b6..11fd958569f87d3bac74773acded53a3f14ddace 100644 (file)
@@ -27,7 +27,7 @@
 #include <string.h>
 #include <math.h>
 
-typedef void ( *composite_line_fn )( uint8_t *dest, uint8_t *src, int width_src, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int softness );
+typedef void ( *composite_line_fn )( uint8_t *dest, uint8_t *src, int width_src, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int softness, int uneven );
 
 /** Geometry struct.
 */
@@ -370,12 +370,13 @@ static void luma_read_yuv422( uint8_t *image, uint16_t **map, int width, int hei
 /** Composite a source line over a destination line
 */
 
-static void composite_line_yuv( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness )
+static void composite_line_yuv( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness, int uneven_x )
 {
        register int j;
        register int a;
        register int mix;
-       
+       int uneven_w = width % 2;
+
        for ( j = 0; j < width; j ++ )
        {
                a = *alpha_b ++;
@@ -383,19 +384,31 @@ static void composite_line_yuv( uint8_t *dest, uint8_t *src, int width, uint8_t
                mix = ( mix * a ) >> 8;
                *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
                dest++;
-               *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               *dest = ( *( src ++ + uneven_x ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               dest++;
+               *alpha_a = mix | *alpha_a;
+               alpha_a ++;
+       }
+
+       if ( uneven_w )
+       {
+               a = *alpha_b ++;
+               mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
+               mix = ( mix * a ) >> 8;
+               *dest = ( *src ++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
                dest++;
                *alpha_a = mix | *alpha_a;
                alpha_a ++;
        }
 }
 
-static void composite_line_yuv_or( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness )
+static void composite_line_yuv_or( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness, int uneven_x )
 {
        register int j;
        register int a;
        register int mix;
-       
+       int uneven_w = width % 2;
+
        for ( j = 0; j < width; j ++ )
        {
                a = *alpha_b ++ | *alpha_a;
@@ -403,19 +416,31 @@ static void composite_line_yuv_or( uint8_t *dest, uint8_t *src, int width, uint8
                mix = ( mix * a ) >> 8;
                *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
                dest++;
-               *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               *dest = ( *( src ++ + uneven_x ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
                dest++;
                *alpha_a = mix | *alpha_a;
                alpha_a ++;
        }
+
+       if ( uneven_w )
+       {
+               a = *alpha_b ++ | *alpha_a;
+               mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
+               mix = ( mix * a ) >> 8;
+               *dest = ( *( src ++ + uneven_x ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               dest++;
+               *alpha_a = mix | *alpha_a;
+               alpha_a ++;
+       }       
 }
 
-static void composite_line_yuv_and( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness )
+static void composite_line_yuv_and( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness, int uneven_x )
 {
        register int j;
        register int a;
        register int mix;
-       
+       int uneven_w = width % 2;
+
        for ( j = 0; j < width; j ++ )
        {
                a = *alpha_b ++ & *alpha_a;
@@ -423,19 +448,31 @@ static void composite_line_yuv_and( uint8_t *dest, uint8_t *src, int width, uint
                mix = ( mix * a ) >> 8;
                *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
                dest++;
-               *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               *dest = ( *( src ++ ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
                dest++;
                *alpha_a = mix | *alpha_a;
                alpha_a ++;
        }
+
+       if ( uneven_w )
+       {
+               a = *alpha_b ++ & *alpha_a;
+               mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
+               mix = ( mix * a ) >> 8;
+               *dest = ( *src ++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               dest++;
+               *alpha_a = mix | *alpha_a;
+               alpha_a ++;
+       }       
 }
 
-static void composite_line_yuv_xor( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness )
+static void composite_line_yuv_xor( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a,  int weight, uint16_t *luma, int softness, int uneven_x )
 {
        register int j;
        register int a;
        register int mix;
-       
+       int uneven_w = width % 2;
+
        for ( j = 0; j < width; j ++ )
        {
                a = *alpha_b ++ ^ *alpha_a;
@@ -443,11 +480,22 @@ static void composite_line_yuv_xor( uint8_t *dest, uint8_t *src, int width, uint
                mix = ( mix * a ) >> 8;
                *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
                dest++;
-               *dest = ( *src++ * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               *dest = ( *( src ++ + uneven_x ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
                dest++;
                *alpha_a = mix | *alpha_a;
                alpha_a ++;
        }
+
+       if ( uneven_w )
+       {
+               a = *alpha_b ++ ^ *alpha_a;
+               mix = ( luma == NULL ) ? weight : smoothstep( luma[ j ], luma[ j ] + softness, weight + softness );
+               mix = ( mix * a ) >> 8;
+               *dest = ( *( src ++ + uneven_x ) * mix + *dest * ( ( 1 << 16 ) - mix ) ) >> 16;
+               dest++;
+               *alpha_a = mix | *alpha_a;
+               alpha_a ++;
+       }       
 }
 
 /** Composite function.
@@ -467,7 +515,7 @@ static int composite_yuv( uint8_t *p_dest, int width_dest, int height_dest, uint
        // Adjust to consumer scale
        int x = rint( 0.5 + geometry.item.x * width_dest / geometry.nw );
        int y = rint( 0.5 + geometry.item.y * height_dest / geometry.nh );
-       int x_uneven = x & 1;
+       int uneven_x = 2 * ( x % 2 );
 
        // optimization points - no work to do
        if ( width_src <= 0 || height_src <= 0 )
@@ -540,18 +588,13 @@ static int composite_yuv( uint8_t *p_dest, int width_dest, int height_dest, uint
        int alpha_b_stride = stride_src / bpp;
        int alpha_a_stride = stride_dest / bpp;
 
-       // Make sure than x and w are even
-       if ( x_uneven )
-       {
-               p_src += 2;
-               width_src --;
-               alpha_a ++;
-       }
+       // Incorrect, but keeps noise away?
+       height_src --;
 
        // now do the compositing only to cropped extents
        for ( i = 0; i < height_src; i += step )
        {
-               line_fn( p_dest, p_src, width_src, alpha_b, alpha_a, weight, p_luma, softness );
+               line_fn( p_dest, p_src, width_src, alpha_b, alpha_a, weight, p_luma, softness, uneven_x );
 
                p_src += stride_src;
                p_dest += stride_dest;
@@ -807,32 +850,43 @@ static mlt_geometry composite_calculate( mlt_transition this, struct geometry_s
        int normalised_width = mlt_properties_get_int( a_props, "normalised_width" );
        int normalised_height = mlt_properties_get_int( a_props, "normalised_height" );
 
-       // Now parse the geometries
-       if ( start == NULL )
-       {
-               // Parse the transitions properties
-               start = transition_parse_keys( this, normalised_width, normalised_height );
+       char *name = mlt_properties_get( properties, "_unique_id" );
+       char key[ 256 ];
 
-               // Assign to properties to ensure we get destroyed
-               mlt_properties_set_data( properties, "geometries", start, 0, ( mlt_destructor )mlt_geometry_close, NULL );
+       sprintf( key, "%s.in", name );
+       if ( mlt_properties_get( a_props, key ) )
+       {
+               sscanf( mlt_properties_get( a_props, key ), "%f,%f,%f,%f,%f,%d,%d", &result->item.x, &result->item.y, &result->item.w, &result->item.h, &result->item.mix, &result->nw, &result->nh );
        }
        else
        {
-               int length = mlt_transition_get_out( this ) - mlt_transition_get_in( this ) + 1;
-               double cycle = mlt_properties_get_double( properties, "cycle" );
-               if ( cycle > 1 )
-                       length = cycle;
-               else if ( cycle > 0 )
-                       length *= cycle;
-               mlt_geometry_refresh( start, mlt_properties_get( properties, "geometry" ), length, normalised_width, normalised_height );
-       }
+               // Now parse the geometries
+               if ( start == NULL )
+               {
+                       // Parse the transitions properties
+                       start = transition_parse_keys( this, normalised_width, normalised_height );
+
+                       // Assign to properties to ensure we get destroyed
+                       mlt_properties_set_data( properties, "geometries", start, 0, ( mlt_destructor )mlt_geometry_close, NULL );
+               }
+               else
+               {
+                       int length = mlt_transition_get_out( this ) - mlt_transition_get_in( this ) + 1;
+                       double cycle = mlt_properties_get_double( properties, "cycle" );
+                       if ( cycle > 1 )
+                               length = cycle;
+                       else if ( cycle > 0 )
+                               length *= cycle;
+                       mlt_geometry_refresh( start, mlt_properties_get( properties, "geometry" ), length, normalised_width, normalised_height );
+               }
 
-       // Do the calculation
-       geometry_calculate( this, result, position );
+               // Do the calculation
+               geometry_calculate( this, result, position );
 
-       // Assign normalised info
-       result->nw = normalised_width;
-       result->nh = normalised_height;
+               // Assign normalised info
+               result->nw = normalised_width;
+               result->nh = normalised_height;
+       }
 
        // Now parse the alignment
        result->halign = alignment_parse( mlt_properties_get( properties, "halign" ) );
@@ -865,6 +919,10 @@ mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame, mlt_pos
        // Get the position
        int position = position_calculate( this, frame_position );
 
+       // Get the unique id of the transition
+       char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" );
+       char key[ 256 ];
+
        // Destination image
        uint8_t *dest = NULL;
 
@@ -889,10 +947,8 @@ mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame, mlt_pos
        // Will need to know region to copy
        struct geometry_s result;
 
-       double delta = delta_calculate( this, a_frame, frame_position );
-
        // Calculate the region now
-       composite_calculate( this, &result, a_frame, position + delta / 2 );
+       composite_calculate( this, &result, a_frame, position );
 
        // Need to scale down to actual dimensions
        x = rint( 0.5 + result.item.x * width / result.nw );
@@ -900,19 +956,18 @@ mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame, mlt_pos
        w = rint( 0.5 + result.item.w * width / result.nw );
        h = rint( 0.5 + result.item.h * height / result.nh );
 
-       // Make sure that x and w are even
-       if ( x & 1 )
+       if ( x % 2 )
        {
                x --;
-               w += 2;
-               if ( w & 1 )
-                       w --;
-       }
-       else if ( w & 1 )
-       {
                w ++;
        }
 
+       // Store the key
+       sprintf( key, "%s.in=%d,%d,%d,%d,%f,%d,%d", name, x, y, w, h, result.item.mix, width, height );
+       mlt_properties_parse( a_props, key );
+       sprintf( key, "%s.out=%d,%d,%d,%d,%f,%d,%d", name, x, y, w, h, result.item.mix, width, height );
+       mlt_properties_parse( a_props, key );
+
        ds = w * 2;
        ss = width * 2;
 
@@ -1102,14 +1157,6 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
 
                        composite_line_fn line_fn = composite_line_yuv;
 
-                       // Silly - this isn't a good solution - deprecating
-                       if ( mlt_properties_get_int( properties, "or" ) )
-                               line_fn = composite_line_yuv_or;
-                       if ( mlt_properties_get_int( properties, "and" ) )
-                               line_fn = composite_line_yuv_and;
-                       if ( mlt_properties_get_int( properties, "xor" ) )
-                               line_fn = composite_line_yuv_xor;
-
                        // Replacement and override
                        if ( operator != NULL )
                        {
index 07ab2682507f0bb80b16a1c69195c973fcaa7b9b..4aa0dbc0088e7225b565c9307626cd48b1cfd5cb 100644 (file)
@@ -38,23 +38,35 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *
        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 && *image && *format == mlt_image_yuv422 )
        {
                // We modify the whole image
                uint8_t *p = *image;
-               uint8_t *q = *image + *height * *width * 2;
+               int h = *height;
+               int uneven = *width % 2;
+               int w = ( *width - uneven ) / 2;
+               int t;
 
                // Get u and v values
                int u = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "u" );
                int v = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "v" );
 
                // Loop through image
-               while ( p != q )
+               while( h -- )
                {
-                       p ++;
-                       *p ++ = u;
-                       p ++;
-                       *p ++ = v;
+                       t = w;
+                       while( t -- )
+                       {
+                               p ++;
+                               *p ++ = u;
+                               p ++;
+                               *p ++ = v;
+                       }
+                       if ( uneven )
+                       {
+                               p ++;
+                               *p ++ = u;
+                       }
                }
        }
 
index 83d1cdefece7ce324e25f5632985f135541be3fd..899582108864d1e3d8c64945d71998dfd9e44b7a 100644 (file)
@@ -473,9 +473,6 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
 
                get_affine( &affine, this, ( float )position );
 
-               lower_x -= ( lower_x & 1 );
-               upper_x -= ( upper_x & 1 );
-
                q = *image;
 
                dz = MapZ( affine.matrix, 0, 0 );
index 2d46db0be281c901d20cf909bb811d87e9e6172a..2d2d8ac63f4f9a5092ce38e2aa3b5560864aca2a 100644 (file)
@@ -534,6 +534,7 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame )
                        
                        this->rect.x = ( this->window_width - this->rect.w ) / 2;
                        this->rect.y = ( this->window_height - this->rect.h ) / 2;
+                       this->rect.x -= this->rect.x % 2;
 
                        mlt_properties_set_int( this->properties, "rect_x", this->rect.x );
                        mlt_properties_set_int( this->properties, "rect_y", this->rect.y );