From: lilo_booter Date: Thu, 15 Sep 2005 20:34:47 +0000 (+0000) Subject: src/framework/mlt_frame.c X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=2a04e5dceebd174e24be42da8643a815640db27d;p=mlt src/framework/mlt_frame.c + 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 --- diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 57c53b80..1e080fa8 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -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 diff --git a/src/framework/mlt_frame.h b/src/framework/mlt_frame.h index d131c67b..18b1e608 100644 --- a/src/framework/mlt_frame.h +++ b/src/framework/mlt_frame.h @@ -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)\ diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index 3f7a01b2..aece92b9 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -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; diff --git a/src/modules/avformat/configure b/src/modules/avformat/configure index ce10ddf2..c80628f7 100755 --- a/src/modules/avformat/configure +++ b/src/modules/avformat/configure @@ -15,7 +15,7 @@ FFMPEG/avformat options: EOF else - targetos=$(uname -s) + targetos=$(uname -s) case $targetos in Darwin) export LIBSUF=.dylib diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index efd52061..b589468b 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -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 ); diff --git a/src/modules/core/filter_mirror.c b/src/modules/core/filter_mirror.c index a9678914..430e401f 100644 --- a/src/modules/core/filter_mirror.c +++ b/src/modules/core/filter_mirror.c @@ -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 ]; diff --git a/src/modules/core/producer_colour.c b/src/modules/core/producer_colour.c index 75e7aa92..9f504f76 100644 --- a/src/modules/core/producer_colour.c +++ b/src/modules/core/producer_colour.c @@ -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 ) diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index 4b514e01..11fd9585 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -27,7 +27,7 @@ #include #include -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 ) { diff --git a/src/modules/plus/filter_sepia.c b/src/modules/plus/filter_sepia.c index 07ab2682..4aa0dbc0 100644 --- a/src/modules/plus/filter_sepia.c +++ b/src/modules/plus/filter_sepia.c @@ -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; + } } } diff --git a/src/modules/plus/transition_affine.c b/src/modules/plus/transition_affine.c index 83d1cdef..89958210 100644 --- a/src/modules/plus/transition_affine.c +++ b/src/modules/plus/transition_affine.c @@ -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 ); diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index 2d46db0b..2d2d8ac6 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -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 );