-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;
-}
-