uint8_t *q;
test_card.vfmt = *format;
- test_card.width = 720;
- test_card.height = 576;
+ test_card.width = *width == 0 ? 720 : *width;
+ test_card.height = *height == 0 ? 576 : *height;
switch( *format )
{
return ret;
}
+void *memfill( void *dst, void *src, int l, int elements )
+{
+ int i = 0;
+ for ( i = 0; i < elements; i ++ )
+ dst = memcpy( dst, src, l ) + l;
+ return dst;
+}
+
+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;
+
+ // 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;
+
+ // Calculate a middle and possibly invalid pointer in the input
+ uint8_t *in_middle = input + istride * ( iheight / 2 ) + ( iwidth / 2 ) * 2;
+ int in_line = - in_y_range * istride - in_x_range * 2;
+
+ uint8_t black[ 2 ] = { 16, 128 };
+
+ // Loop for the entirety of our output height.
+ for ( y = - out_y_range; y < out_y_range ; y ++ )
+ {
+ // Start at the beginning of the line
+ out_ptr = out_line;
+
+ if ( abs( y ) < iheight / 2 )
+ {
+ // Fill the outer part with black
+ out_ptr = memfill( out_ptr, black, 2, out_x_range - in_x_range );
+
+ // We're in the input range for this row.
+ memcpy( out_ptr, in_middle + in_line, 4 * in_x_range );
+ out_ptr += 4 * in_x_range;
+
+ // Fill the outer part with black
+ out_ptr = memfill( out_ptr, black, 2, out_x_range - in_x_range );
+
+ // Move to next input line
+ in_line += istride;
+ }
+ else
+ {
+ // Fill whole line with black
+ out_ptr = memfill( out_ptr, black, 2, owidth );
+ }
+
+ // 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 );
+ 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 = malloc( owidth * oheight * 2 );
+
+ // Call the generic resize
+ mlt_resize_yuv422( output, owidth, oheight, input, iwidth, iheight );
+
+ // Now update the frame
+ mlt_properties_set_data( properties, "image", output, owidth * oheight * 2, free, NULL );
+ mlt_properties_set_int( properties, "width", owidth );
+ mlt_properties_set_int( properties, "height", oheight );
+
+ // 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 = malloc( owidth * oheight * 2 );
+
+ // Calculate strides
+ int istride = iwidth * 2;
+ int ostride = owidth * 2;
+
+ // Coordinates (0,0 is middle of output)
+ int y, x;
+
+ // 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
+ uint8_t *out_line = output;
+ 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;
+ uint8_t *in_ptr;
+
+ // Generate the affine transform scaling values
+ float scale_width = ( float )iwidth / ( float )owidth;
+ float scale_height = ( float )iheight / ( float )oheight;
+
+ // Loop for the entirety of our output height.
+ for ( y = - out_y_range; y < out_y_range ; y ++ )
+ {
+ // Calculate the derived y value
+ dy = scale_height * y;
+
+ // Start at the beginning of the line
+ out_ptr = out_line;
+
+ // Pointer to the middle of the input line
+ in_line = in_middle + dy * istride;
+
+ // Loop for the entirety of our output row.
+ for ( x = - out_x_range; x < out_x_range; x += 1 )
+ {
+ // Calculated the derived x
+ dx = scale_width * x;
+
+ // Check if x and y are in the valid input range.
+ if ( abs( dx ) < in_x_range && abs( dy ) < in_y_range )
+ {
+ // We're in the input range for this row.
+ in_ptr = in_line + ( dx >> 1 ) * 4 - 2 * ( x & 1 );
+ *out_ptr ++ = *in_ptr ++;
+ *out_ptr ++ = *in_ptr ++;
+ }
+ else
+ {
+ // We're not in the input range for this row.
+ *out_ptr ++ = 16;
+ *out_ptr ++ = 128;
+ }
+ }
+
+ // Move to next output line
+ out_line += ostride;
+ }
+
+ // Now update the frame
+ mlt_properties_set_data( properties, "image", output, owidth * oheight * 2, free, 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;
+}
+