Use a reasonable default for unspecified YUV colorspace
This commit is contained in:
parent
240158f3e8
commit
c3e4481d56
@ -558,7 +558,7 @@ static int D3D_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_P
|
||||
}
|
||||
|
||||
texturedata->shader = SHADER_YUV;
|
||||
texturedata->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace);
|
||||
texturedata->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8);
|
||||
if (texturedata->shader_params == NULL) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
|
@ -1297,7 +1297,7 @@ static int D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
SDL_SetProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_D3D11_TEXTURE_V_POINTER, textureData->mainTextureV);
|
||||
|
||||
textureData->shader = SHADER_YUV;
|
||||
textureData->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace);
|
||||
textureData->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8);
|
||||
if (!textureData->shader_params) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
@ -1306,6 +1306,8 @@ static int D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
texture->format == SDL_PIXELFORMAT_NV21 ||
|
||||
texture->format == SDL_PIXELFORMAT_P010 ||
|
||||
texture->format == SDL_PIXELFORMAT_P016) {
|
||||
int bits_per_pixel;
|
||||
|
||||
textureData->nv12 = SDL_TRUE;
|
||||
|
||||
switch (texture->format) {
|
||||
@ -1328,7 +1330,18 @@ static int D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
/* This should never happen because of the check above */
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
textureData->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace);
|
||||
switch (texture->format) {
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
bits_per_pixel = 10;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_P016:
|
||||
bits_per_pixel = 16;
|
||||
break;
|
||||
default:
|
||||
bits_per_pixel = 8;
|
||||
break;
|
||||
}
|
||||
textureData->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!textureData->shader_params) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
|
@ -1641,7 +1641,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
SDL_SetProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_D3D12_TEXTURE_V_POINTER, textureData->mainTextureV);
|
||||
|
||||
textureData->shader = SHADER_YUV;
|
||||
textureData->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace);
|
||||
textureData->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8);
|
||||
if (!textureData->shader_params) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
@ -1652,7 +1652,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
textureData->nv12 = SDL_TRUE;
|
||||
|
||||
textureData->shader = (texture->format == SDL_PIXELFORMAT_NV12 ? SHADER_NV12 : SHADER_NV21);
|
||||
textureData->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace);
|
||||
textureData->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8);
|
||||
if (!textureData->shader_params) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
|
@ -1822,10 +1822,10 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
|
||||
constantdata = [mtlbufconstantstaging contents];
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_IDENTITY, identitytransform, sizeof(identitytransform));
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, halfpixeltransform, sizeof(halfpixeltransform));
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT601_LIMITED, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT601_LIMITED), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT601_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT601_FULL), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT709_LIMITED, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT709_LIMITED), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT709_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT709_FULL), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT601_LIMITED, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT601_LIMITED, 0, 0, 8), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT601_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT601_FULL, 0, 0, 8), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT709_LIMITED, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT709_LIMITED, 0, 0, 8), YCbCr_shader_matrix_size);
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT709_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT709_FULL, 0, 0, 8), YCbCr_shader_matrix_size);
|
||||
|
||||
mtlbufquadindicesstaging = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModeShared];
|
||||
|
||||
|
@ -680,7 +680,7 @@ static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Pr
|
||||
data->shader = SHADER_NV21_RA;
|
||||
}
|
||||
}
|
||||
data->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace);
|
||||
data->shader_params = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8);
|
||||
if (!data->shader_params) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
|
@ -629,7 +629,7 @@ static int GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source,
|
||||
#if SDL_HAVE_YUV
|
||||
case GLES2_IMAGESOURCE_TEXTURE_YUV:
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV;
|
||||
shader_params = SDL_GetYCbCRtoRGBConversionMatrix(colorspace);
|
||||
shader_params = SDL_GetYCbCRtoRGBConversionMatrix(colorspace, 0, 0, 8);
|
||||
if (!shader_params) {
|
||||
SDL_SetError("Unsupported YUV colorspace");
|
||||
goto fault;
|
||||
@ -641,7 +641,7 @@ static int GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source,
|
||||
} else {
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA;
|
||||
}
|
||||
shader_params = SDL_GetYCbCRtoRGBConversionMatrix(colorspace);
|
||||
shader_params = SDL_GetYCbCRtoRGBConversionMatrix(colorspace, 0, 0, 8);
|
||||
if (!shader_params) {
|
||||
SDL_SetError("Unsupported YUV colorspace");
|
||||
goto fault;
|
||||
@ -653,7 +653,7 @@ static int GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source,
|
||||
} else {
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_RA;
|
||||
}
|
||||
shader_params = SDL_GetYCbCRtoRGBConversionMatrix(colorspace);
|
||||
shader_params = SDL_GetYCbCRtoRGBConversionMatrix(colorspace, 0, 0, 8);
|
||||
if (!shader_params) {
|
||||
SDL_SetError("Unsupported YUV colorspace");
|
||||
goto fault;
|
||||
@ -1548,7 +1548,7 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
}
|
||||
SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_U_NUMBER, data->texture_u);
|
||||
|
||||
if (!SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace)) {
|
||||
if (!SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8)) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
} else if (data->nv12) {
|
||||
@ -1573,7 +1573,7 @@ static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
|
||||
}
|
||||
SDL_SetNumberProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_OPENGLES2_TEXTURE_UV_NUMBER, data->texture_u);
|
||||
|
||||
if (!SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace)) {
|
||||
if (!SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8)) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
}
|
||||
|
@ -764,88 +764,126 @@ float SDL_PQfromNits(float v)
|
||||
return SDL_powf(num / den, m2);
|
||||
}
|
||||
|
||||
const float *SDL_GetYCbCRtoRGBConversionMatrix(SDL_Colorspace colorspace)
|
||||
/* This is a helpful tool for deriving these:
|
||||
* https://kdashg.github.io/misc/colors/from-coeffs.html
|
||||
*/
|
||||
static const float mat_BT601_Limited_8bit[] = {
|
||||
-0.0627451017f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
|
||||
1.1644f, 0.0000f, 1.5960f, 0.0f, /* Rcoeff */
|
||||
1.1644f, -0.3918f, -0.8130f, 0.0f, /* Gcoeff */
|
||||
1.1644f, 2.0172f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
|
||||
static const float mat_BT601_Full_8bit[] = {
|
||||
0.0f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
|
||||
1.0000f, 0.0000f, 1.4020f, 0.0f, /* Rcoeff */
|
||||
1.0000f, -0.3441f, -0.7141f, 0.0f, /* Gcoeff */
|
||||
1.0000f, 1.7720f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
|
||||
static const float mat_BT709_Limited_8bit[] = {
|
||||
-0.0627451017f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
|
||||
1.1644f, 0.0000f, 1.7927f, 0.0f, /* Rcoeff */
|
||||
1.1644f, -0.2132f, -0.5329f, 0.0f, /* Gcoeff */
|
||||
1.1644f, 2.1124f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
|
||||
static const float mat_BT709_Full_8bit[] = {
|
||||
0.0f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
|
||||
1.0000f, 0.0000f, 1.5748f, 0.0f, /* Rcoeff */
|
||||
1.0000f, -0.1873f, -0.4681f, 0.0f, /* Gcoeff */
|
||||
1.0000f, 1.8556f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
|
||||
static const float mat_BT2020_Limited_10bit[] = {
|
||||
-0.062561095f, -0.500488759f, -0.500488759f, 0.0f, /* offset */
|
||||
1.1678f, 0.0000f, 1.6836f, 0.0f, /* Rcoeff */
|
||||
1.1678f, -0.1879f, -0.6523f, 0.0f, /* Gcoeff */
|
||||
1.1678f, 2.1481f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
|
||||
static const float mat_BT2020_Full_10bit[] = {
|
||||
0.0f, -0.500488759f, -0.500488759f, 0.0f, /* offset */
|
||||
1.0000f, 0.0000f, 1.4760f, 0.0f, /* Rcoeff */
|
||||
1.0000f, -0.1647f, -0.5719f, 0.0f, /* Gcoeff */
|
||||
1.0000f, 1.8832f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
|
||||
static const float *SDL_GetBT601ConversionMatrix( SDL_Colorspace colorspace )
|
||||
{
|
||||
/* This is a helpful tool for deriving these:
|
||||
* https://kdashg.github.io/misc/colors/from-coeffs.html
|
||||
*/
|
||||
static const float mat_BT601_Limited_8bit[] = {
|
||||
-0.0627451017f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
|
||||
1.1644f, 0.0000f, 1.5960f, 0.0f, /* Rcoeff */
|
||||
1.1644f, -0.3918f, -0.8130f, 0.0f, /* Gcoeff */
|
||||
1.1644f, 2.0172f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
switch (SDL_COLORSPACERANGE(colorspace)) {
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
case SDL_COLOR_RANGE_UNKNOWN:
|
||||
return mat_BT601_Limited_8bit;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return mat_BT601_Full_8bit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const float mat_BT601_Full_8bit[] = {
|
||||
0.0f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
|
||||
1.0000f, 0.0000f, 1.4020f, 0.0f, /* Rcoeff */
|
||||
1.0000f, -0.3441f, -0.7141f, 0.0f, /* Gcoeff */
|
||||
1.0000f, 1.7720f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
static const float *SDL_GetBT709ConversionMatrix(SDL_Colorspace colorspace)
|
||||
{
|
||||
switch (SDL_COLORSPACERANGE(colorspace)) {
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
case SDL_COLOR_RANGE_UNKNOWN:
|
||||
return mat_BT709_Limited_8bit;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return mat_BT709_Full_8bit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const float mat_BT709_Limited_8bit[] = {
|
||||
-0.0627451017f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
|
||||
1.1644f, 0.0000f, 1.7927f, 0.0f, /* Rcoeff */
|
||||
1.1644f, -0.2132f, -0.5329f, 0.0f, /* Gcoeff */
|
||||
1.1644f, 2.1124f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
static const float *SDL_GetBT2020ConversionMatrix(SDL_Colorspace colorspace)
|
||||
{
|
||||
switch (SDL_COLORSPACERANGE(colorspace)) {
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
case SDL_COLOR_RANGE_UNKNOWN:
|
||||
return mat_BT2020_Limited_10bit;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return mat_BT2020_Full_10bit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const float mat_BT709_Full_8bit[] = {
|
||||
0.0f, -0.501960814f, -0.501960814f, 0.0f, /* offset */
|
||||
1.0000f, 0.0000f, 1.5748f, 0.0f, /* Rcoeff */
|
||||
1.0000f, -0.1873f, -0.4681f, 0.0f, /* Gcoeff */
|
||||
1.0000f, 1.8556f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
|
||||
static const float mat_BT2020_Limited_10bit[] = {
|
||||
-0.062561095f, -0.500488759f, -0.500488759f, 0.0f, /* offset */
|
||||
1.1678f, 0.0000f, 1.6836f, 0.0f, /* Rcoeff */
|
||||
1.1678f, -0.1879f, -0.6523f, 0.0f, /* Gcoeff */
|
||||
1.1678f, 2.1481f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
|
||||
static const float mat_BT2020_Full_10bit[] = {
|
||||
0.0f, -0.500488759f, -0.500488759f, 0.0f, /* offset */
|
||||
1.0000f, 0.0000f, 1.4760f, 0.0f, /* Rcoeff */
|
||||
1.0000f, -0.1647f, -0.5719f, 0.0f, /* Gcoeff */
|
||||
1.0000f, 1.8832f, 0.0000f, 0.0f, /* Bcoeff */
|
||||
};
|
||||
const float *SDL_GetYCbCRtoRGBConversionMatrix(SDL_Colorspace colorspace, int w, int h, int bits_per_pixel)
|
||||
{
|
||||
const int YUV_SD_THRESHOLD = 576;
|
||||
|
||||
switch (SDL_COLORSPACEMATRIX(colorspace)) {
|
||||
case SDL_MATRIX_COEFFICIENTS_BT601:
|
||||
switch (SDL_COLORSPACERANGE(colorspace)) {
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
return mat_BT601_Limited_8bit;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return mat_BT601_Full_8bit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
return SDL_GetBT601ConversionMatrix(colorspace);
|
||||
|
||||
case SDL_MATRIX_COEFFICIENTS_BT709:
|
||||
switch (SDL_COLORSPACERANGE(colorspace)) {
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
return mat_BT709_Limited_8bit;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return mat_BT709_Full_8bit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
return SDL_GetBT709ConversionMatrix(colorspace);
|
||||
|
||||
/* FIXME: Are these the same? */
|
||||
case SDL_MATRIX_COEFFICIENTS_BT2020_NCL:
|
||||
case SDL_MATRIX_COEFFICIENTS_BT2020_CL:
|
||||
switch (SDL_COLORSPACERANGE(colorspace)) {
|
||||
case SDL_COLOR_RANGE_LIMITED:
|
||||
return mat_BT2020_Limited_10bit;
|
||||
break;
|
||||
case SDL_COLOR_RANGE_FULL:
|
||||
return mat_BT2020_Full_10bit;
|
||||
break;
|
||||
return SDL_GetBT2020ConversionMatrix(colorspace);
|
||||
|
||||
case SDL_MATRIX_COEFFICIENTS_UNSPECIFIED:
|
||||
switch (bits_per_pixel) {
|
||||
case 8:
|
||||
if (h <= YUV_SD_THRESHOLD) {
|
||||
return SDL_GetBT601ConversionMatrix(colorspace);
|
||||
} else {
|
||||
return SDL_GetBT709ConversionMatrix(colorspace);
|
||||
}
|
||||
case 10:
|
||||
case 16:
|
||||
return SDL_GetBT2020ConversionMatrix(colorspace);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ extern float SDL_sRGBtoNits(float v);
|
||||
extern float SDL_sRGBfromNits(float v);
|
||||
extern float SDL_PQtoNits(float v);
|
||||
extern float SDL_PQfromNits(float v);
|
||||
extern const float *SDL_GetYCbCRtoRGBConversionMatrix(SDL_Colorspace colorspace);
|
||||
extern const float *SDL_GetYCbCRtoRGBConversionMatrix(SDL_Colorspace colorspace, int w, int h, int bits_per_pixel);
|
||||
extern const float *SDL_GetColorPrimariesConversionMatrix(SDL_ColorPrimaries src, SDL_ColorPrimaries dst);
|
||||
extern void SDL_ConvertColorPrimaries(float *fR, float *fG, float *fB, const float *matrix);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user