Added support for full range BT.709 YUV conversion
Also added simple colorspace testing to testyuv.
This commit is contained in:
@@ -171,8 +171,10 @@ static bool GetYUVConversionType(SDL_Colorspace colorspace, YCbCrType *yuv_type)
|
||||
if (SDL_ISCOLORSPACE_MATRIX_BT709(colorspace)) {
|
||||
if (SDL_ISCOLORSPACE_LIMITED_RANGE(colorspace)) {
|
||||
*yuv_type = YCBCR_709_LIMITED;
|
||||
return true;
|
||||
} else {
|
||||
*yuv_type = YCBCR_709_FULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SDL_ISCOLORSPACE_MATRIX_BT2020_NCL(colorspace)) {
|
||||
@@ -691,6 +693,13 @@ static struct RGB2YUVFactors RGB2YUVFactorTables[] = {
|
||||
{ -0.1482f, -0.2910f, 0.4392f },
|
||||
{ 0.4392f, -0.3678f, -0.0714f },
|
||||
},
|
||||
// ITU-R BT.709-6 full range
|
||||
{
|
||||
0,
|
||||
{ 0.2126f, 0.7152f, 0.0722f },
|
||||
{ -0.1141f, -0.3839f, 0.498f },
|
||||
{ 0.498f, -0.4524f, -0.0457f },
|
||||
},
|
||||
// ITU-R BT.709-6
|
||||
{
|
||||
16,
|
||||
@@ -707,7 +716,7 @@ static struct RGB2YUVFactors RGB2YUVFactorTables[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static bool SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, SDL_PixelFormat dst_format, void *dst, int dst_pitch, YCbCrType yuv_type)
|
||||
static bool SDL_ConvertPixels_XRGB8888_to_YUV(int width, int height, const void *src, int src_pitch, SDL_PixelFormat dst_format, void *dst, int dst_pitch, YCbCrType yuv_type)
|
||||
{
|
||||
const int src_pitch_x_2 = src_pitch * 2;
|
||||
const int height_half = height / 2;
|
||||
@@ -718,9 +727,9 @@ static bool SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void
|
||||
|
||||
const struct RGB2YUVFactors *cvt = &RGB2YUVFactorTables[yuv_type];
|
||||
|
||||
#define MAKE_Y(r, g, b) (Uint8)((int)(cvt->y[0] * (r) + cvt->y[1] * (g) + cvt->y[2] * (b) + 0.5f) + cvt->y_offset)
|
||||
#define MAKE_U(r, g, b) (Uint8)((int)(cvt->u[0] * (r) + cvt->u[1] * (g) + cvt->u[2] * (b) + 0.5f) + 128)
|
||||
#define MAKE_V(r, g, b) (Uint8)((int)(cvt->v[0] * (r) + cvt->v[1] * (g) + cvt->v[2] * (b) + 0.5f) + 128)
|
||||
#define MAKE_Y(r, g, b) (Uint8)SDL_clamp(((int)(cvt->y[0] * (r) + cvt->y[1] * (g) + cvt->y[2] * (b) + 0.5f) + cvt->y_offset), 0, 255)
|
||||
#define MAKE_U(r, g, b) (Uint8)SDL_clamp(((int)(cvt->u[0] * (r) + cvt->u[1] * (g) + cvt->u[2] * (b) + 0.5f) + 128), 0, 255)
|
||||
#define MAKE_V(r, g, b) (Uint8)SDL_clamp(((int)(cvt->v[0] * (r) + cvt->v[1] * (g) + cvt->v[2] * (b) + 0.5f) + 128), 0, 255)
|
||||
|
||||
#define READ_2x2_PIXELS \
|
||||
const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \
|
||||
@@ -1149,9 +1158,9 @@ bool SDL_ConvertPixels_RGB_to_YUV(int width, int height,
|
||||
#endif
|
||||
|
||||
// ARGB8888 to FOURCC
|
||||
if (src_format == SDL_PIXELFORMAT_ARGB8888 &&
|
||||
if ((src_format == SDL_PIXELFORMAT_ARGB8888 || src_format == SDL_PIXELFORMAT_XRGB8888) &&
|
||||
SDL_COLORSPACEPRIMARIES(src_colorspace) == SDL_COLORSPACEPRIMARIES(dst_colorspace)) {
|
||||
return SDL_ConvertPixels_ARGB8888_to_YUV(width, height, src, src_pitch, dst_format, dst, dst_pitch, yuv_type);
|
||||
return SDL_ConvertPixels_XRGB8888_to_YUV(width, height, src, src_pitch, dst_format, dst, dst_pitch, yuv_type);
|
||||
}
|
||||
|
||||
if (dst_format == SDL_PIXELFORMAT_P010) {
|
||||
@@ -1194,15 +1203,15 @@ bool SDL_ConvertPixels_RGB_to_YUV(int width, int height,
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert src/src_format to tmp/ARGB8888
|
||||
result = SDL_ConvertPixelsAndColorspace(width, height, src_format, src_colorspace, src_properties, src, src_pitch, SDL_PIXELFORMAT_ARGB8888, dst_colorspace, dst_properties, tmp, tmp_pitch);
|
||||
// convert src/src_format to tmp/XRGB8888
|
||||
result = SDL_ConvertPixelsAndColorspace(width, height, src_format, src_colorspace, src_properties, src, src_pitch, SDL_PIXELFORMAT_XRGB8888, SDL_COLORSPACE_SRGB, 0, tmp, tmp_pitch);
|
||||
if (!result) {
|
||||
SDL_free(tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
// convert tmp/ARGB8888 to dst/FOURCC
|
||||
result = SDL_ConvertPixels_ARGB8888_to_YUV(width, height, tmp, tmp_pitch, dst_format, dst, dst_pitch, yuv_type);
|
||||
// convert tmp/XRGB8888 to dst/FOURCC
|
||||
result = SDL_ConvertPixels_XRGB8888_to_YUV(width, height, tmp, tmp_pitch, dst_format, dst, dst_pitch, yuv_type);
|
||||
SDL_free(tmp);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ typedef enum
|
||||
{
|
||||
YCBCR_601_FULL,
|
||||
YCBCR_601_LIMITED,
|
||||
YCBCR_709_FULL,
|
||||
YCBCR_709_LIMITED,
|
||||
YCBCR_2020_NCL_FULL,
|
||||
} YCbCrType;
|
||||
|
||||
@@ -40,22 +40,26 @@ typedef struct
|
||||
// for ITU-R BT.2020 values are assuming RGB is encoded using full 10-bit range ([0-1]<->[0-1023])
|
||||
// all values are rounded to the fourth decimal
|
||||
|
||||
static const YUV2RGBParam YUV2RGB[4] = {
|
||||
static const YUV2RGBParam YUV2RGB[] = {
|
||||
// ITU-T T.871 (JPEG)
|
||||
{/*.y_shift=*/ 0, /*.y_factor=*/ V(1.0), /*.v_r_factor=*/ V(1.402), /*.u_g_factor=*/ -V(0.3441), /*.v_g_factor=*/ -V(0.7141), /*.u_b_factor=*/ V(1.772)},
|
||||
// ITU-R BT.601-7
|
||||
{/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.596), /*.u_g_factor=*/ -V(0.3918), /*.v_g_factor=*/ -V(0.813), /*.u_b_factor=*/ V(2.0172)},
|
||||
// ITU-R BT.709-6 full range
|
||||
{/*.y_shift=*/ 0, /*.y_factor=*/ V(1.0), /*.v_r_factor=*/ V(1.581), /*.u_g_factor=*/ -V(0.1881), /*.v_g_factor=*/ -V(0.47), /*.u_b_factor=*/ V(1.8629)},
|
||||
// ITU-R BT.709-6
|
||||
{/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.7927), /*.u_g_factor=*/ -V(0.2132), /*.v_g_factor=*/ -V(0.5329), /*.u_b_factor=*/ V(2.1124)},
|
||||
// ITU-R BT.2020 10-bit full range
|
||||
{/*.y_shift=*/ 0, /*.y_factor=*/ V(1.0), /*.v_r_factor=*/ V(1.4760), /*.u_g_factor=*/ -V(0.1647), /*.v_g_factor=*/ -V(0.5719), /*.u_b_factor=*/ V(1.8832) }
|
||||
};
|
||||
|
||||
static const RGB2YUVParam RGB2YUV[4] = {
|
||||
static const RGB2YUVParam RGB2YUV[] = {
|
||||
// ITU-T T.871 (JPEG)
|
||||
{/*.y_shift=*/ 0, /*.matrix=*/ {{V(0.299), V(0.587), V(0.114)}, {-V(0.1687), -V(0.3313), V(0.5)}, {V(0.5), -V(0.4187), -V(0.0813)}}},
|
||||
// ITU-R BT.601-7
|
||||
{/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.2568), V(0.5041), V(0.0979)}, {-V(0.1482), -V(0.291), V(0.4392)}, {V(0.4392), -V(0.3678), -V(0.0714)}}},
|
||||
// ITU-R BT.709-6 full range
|
||||
{/*.y_shift=*/ 0, /*.matrix=*/ {{V(0.2126), V(0.7152), V(0.0722)}, {-V(0.1141), -V(0.3839), V(0.498)}, {V(0.498), -V(0.4524), -V(0.0457)}}},
|
||||
// ITU-R BT.709-6
|
||||
{/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.1826), V(0.6142), V(0.062)}, {-V(0.1006), -V(0.3386), V(0.4392)}, {V(0.4392), -V(0.3989), -V(0.0403)}}},
|
||||
// ITU-R BT.2020 10-bit full range
|
||||
|
||||
Reference in New Issue
Block a user