mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-09-17 02:32:04 +00:00
Added SDL_PIXELFORMAT_I0FL
This commit is contained in:
@@ -364,6 +364,7 @@ typedef enum SDL_PackedLayout
|
||||
((format) == SDL_PIXELFORMAT_UYVY) || \
|
||||
((format) == SDL_PIXELFORMAT_YVYU) || \
|
||||
((format) == SDL_PIXELFORMAT_P010) || \
|
||||
((format) == SDL_PIXELFORMAT_I0FL) || \
|
||||
((format) == SDL_PIXELFORMAT_I4FL)) ? 2 : 1) : (((format) >> 0) & 0xFF))
|
||||
|
||||
|
||||
@@ -676,6 +677,8 @@ typedef enum SDL_PixelFormat
|
||||
/* SDL_DEFINE_PIXELFOURCC('I', '4', '4', '4'), */
|
||||
SDL_PIXELFORMAT_P010 = 0x30313050u, /**< YUV 4:2:0 16-bit planar mode: Y + U/V interleaved (2 planes) */
|
||||
/* SDL_DEFINE_PIXELFOURCC('P', '0', '1', '0'), */
|
||||
SDL_PIXELFORMAT_I0FL = 0x4c463049u, /**< YUV 4:2:0 16-bit planar mode: Y + U + V (3 planes) */
|
||||
/* SDL_DEFINE_PIXELFOURCC('I', '0', 'F', 'L'), */
|
||||
SDL_PIXELFORMAT_I4FL = 0x4c463449u, /**< YUV 4:4:4 16-bit planar mode: Y + U + V (3 planes) */
|
||||
/* SDL_DEFINE_PIXELFOURCC('I', '4', 'F', 'L'), */
|
||||
SDL_PIXELFORMAT_EXTERNAL_OES = 0x2053454fu, /**< Android video texture format */
|
||||
|
||||
@@ -2498,8 +2498,9 @@ bool SDL_UpdateYUVTexture(SDL_Texture *texture, const SDL_Rect *rect,
|
||||
CHECK_PARAM(texture->format != SDL_PIXELFORMAT_YV12 &&
|
||||
texture->format != SDL_PIXELFORMAT_IYUV &&
|
||||
texture->format != SDL_PIXELFORMAT_I444 &&
|
||||
texture->format != SDL_PIXELFORMAT_I0FL &&
|
||||
texture->format != SDL_PIXELFORMAT_I4FL) {
|
||||
return SDL_SetError("Texture format must be YV12, IYUV, I444, or I4FL");
|
||||
return SDL_SetError("Texture format must be YV12, IYUV, I444, I0FL, or I4FL");
|
||||
}
|
||||
|
||||
real_rect.x = 0;
|
||||
|
||||
@@ -36,6 +36,7 @@ SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(SDL_PixelFormat format, SDL_Colorspac
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_I444:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
case SDL_PIXELFORMAT_YUY2:
|
||||
case SDL_PIXELFORMAT_UYVY:
|
||||
@@ -75,9 +76,10 @@ SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(SDL_PixelFormat format, SDL_Colorspac
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
swdata->pitches[0] = w;
|
||||
swdata->pitches[1] = (swdata->pitches[0] + 1) / 2;
|
||||
swdata->pitches[2] = (swdata->pitches[0] + 1) / 2;
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
swdata->pitches[0] = w * SDL_BYTESPERPIXEL(format);
|
||||
swdata->pitches[1] = ((w + 1) / 2) * SDL_BYTESPERPIXEL(format);
|
||||
swdata->pitches[2] = swdata->pitches[1];
|
||||
swdata->planes[0] = swdata->pixels;
|
||||
swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
|
||||
swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * ((h + 1) / 2);
|
||||
@@ -128,6 +130,7 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
switch (swdata->format) {
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
if (rect->x == 0 && rect->y == 0 &&
|
||||
rect->w == swdata->w && rect->h == swdata->h && pitch == swdata->pitches[0]) {
|
||||
SDL_memcpy(swdata->pixels, pixels,
|
||||
@@ -136,26 +139,27 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
Uint8 *src, *dst;
|
||||
int row;
|
||||
size_t length;
|
||||
const int bpp = SDL_BYTESPERPIXEL(swdata->format);
|
||||
|
||||
// Copy the Y plane
|
||||
src = (Uint8 *)pixels;
|
||||
dst = swdata->pixels + rect->y * swdata->w + rect->x;
|
||||
length = rect->w;
|
||||
length = rect->w * bpp;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
dst += swdata->w;
|
||||
dst += swdata->pitches[0];
|
||||
}
|
||||
|
||||
// Copy the next plane
|
||||
src = (Uint8 *)pixels + rect->h * pitch;
|
||||
dst = swdata->pixels + swdata->h * swdata->w;
|
||||
dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
|
||||
length = (rect->w + 1) / 2;
|
||||
length = ((rect->w + 1) / 2) * bpp;
|
||||
for (row = 0; row < (rect->h + 1) / 2; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += (pitch + 1) / 2;
|
||||
dst += (swdata->w + 1) / 2;
|
||||
dst += swdata->pitches[1];
|
||||
}
|
||||
|
||||
// Copy the next plane
|
||||
@@ -163,11 +167,11 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
dst = swdata->pixels + swdata->h * swdata->w +
|
||||
((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
|
||||
dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
|
||||
length = (rect->w + 1) / 2;
|
||||
length = ((rect->w + 1) / 2) * bpp;
|
||||
for (row = 0; row < (rect->h + 1) / 2; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += (pitch + 1) / 2;
|
||||
dst += (swdata->w + 1) / 2;
|
||||
dst += swdata->pitches[2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -285,7 +289,7 @@ bool SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *re
|
||||
// Copy the Y plane
|
||||
src = Yplane;
|
||||
dst = swdata->pixels + rect->y * swdata->pitches[0] + rect->x * bpp;
|
||||
length = rect->w;
|
||||
length = rect->w * bpp;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += Ypitch;
|
||||
@@ -305,18 +309,18 @@ bool SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *re
|
||||
dst += swdata->pitches[1];
|
||||
}
|
||||
} else {
|
||||
if (swdata->format == SDL_PIXELFORMAT_IYUV) {
|
||||
dst = swdata->pixels + swdata->h * swdata->w;
|
||||
if (swdata->format == SDL_PIXELFORMAT_IYUV ||
|
||||
swdata->format == SDL_PIXELFORMAT_I0FL) {
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0];
|
||||
} else {
|
||||
dst = swdata->pixels + swdata->h * swdata->w +
|
||||
((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0] + ((swdata->h + 1) / 2) * swdata->pitches[1];
|
||||
}
|
||||
dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
|
||||
length = (rect->w + 1) / 2;
|
||||
dst += rect->y / 2 * ((swdata->w + 1) / 2) * bpp + (rect->x / 2) * bpp;
|
||||
length = ((rect->w + 1) / 2) * bpp;
|
||||
for (row = 0; row < (rect->h + 1) / 2; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += Upitch;
|
||||
dst += (swdata->w + 1) / 2;
|
||||
dst += swdata->pitches[1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,17 +338,16 @@ bool SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *re
|
||||
}
|
||||
} else {
|
||||
if (swdata->format == SDL_PIXELFORMAT_YV12) {
|
||||
dst = swdata->pixels + swdata->h * swdata->w;
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0];
|
||||
} else {
|
||||
dst = swdata->pixels + swdata->h * swdata->w +
|
||||
((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0] + ((swdata->h + 1) / 2) * swdata->pitches[1];
|
||||
}
|
||||
dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
|
||||
length = (rect->w + 1) / 2;
|
||||
dst += rect->y / 2 * ((swdata->w + 1) / 2) * bpp + (rect->x / 2) * bpp;
|
||||
length = ((rect->w + 1) / 2) * bpp;
|
||||
for (row = 0; row < (rect->h + 1) / 2; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += Vpitch;
|
||||
dst += (swdata->w + 1) / 2;
|
||||
dst += swdata->pitches[2];
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -273,6 +273,7 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 outpu
|
||||
return DXGI_FORMAT_NV12;
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
return DXGI_FORMAT_P010;
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
return DXGI_FORMAT_R16_UNORM;
|
||||
default:
|
||||
@@ -1272,7 +1273,8 @@ static bool D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_IYUV) {
|
||||
texture->format == SDL_PIXELFORMAT_IYUV ||
|
||||
texture->format == SDL_PIXELFORMAT_I0FL) {
|
||||
textureData->yuv = true;
|
||||
|
||||
textureDesc.Width = (textureDesc.Width + 1) / 2;
|
||||
@@ -1306,14 +1308,14 @@ static bool D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
}
|
||||
SDL_SetPointerProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_D3D11_TEXTURE_V_POINTER, textureData->mainTextureV);
|
||||
|
||||
textureData->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8);
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_I0FL) ? 16 : 8;
|
||||
textureData->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!textureData->YCbCr_matrix) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
}
|
||||
if (texture->format == SDL_PIXELFORMAT_I444 ||
|
||||
texture->format == SDL_PIXELFORMAT_I4FL) {
|
||||
|
||||
textureData->yuv = true;
|
||||
|
||||
if (!GetTextureProperty(create_props, SDL_PROP_TEXTURE_CREATE_D3D11_TEXTURE_U_POINTER, &textureData->mainTextureU)) {
|
||||
@@ -1344,7 +1346,7 @@ static bool D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
}
|
||||
SDL_SetPointerProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_D3D11_TEXTURE_V_POINTER, textureData->mainTextureV);
|
||||
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_I444) ? 8 : 16;
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_I4FL) ? 16 : 8;
|
||||
textureData->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!textureData->YCbCr_matrix) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
@@ -1353,18 +1355,9 @@ static bool D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
if (texture->format == SDL_PIXELFORMAT_NV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_NV21 ||
|
||||
texture->format == SDL_PIXELFORMAT_P010) {
|
||||
int bits_per_pixel;
|
||||
|
||||
textureData->nv12 = true;
|
||||
|
||||
switch (texture->format) {
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
bits_per_pixel = 10;
|
||||
break;
|
||||
default:
|
||||
bits_per_pixel = 8;
|
||||
break;
|
||||
}
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_P010) ? 10 : 8;
|
||||
textureData->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!textureData->YCbCr_matrix) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
@@ -1616,7 +1609,7 @@ static bool D3D11_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
}
|
||||
} else {
|
||||
int Ypitch = srcPitch;
|
||||
int UVpitch = ((Ypitch + 1) / 2);
|
||||
int UVpitch = ((Ypitch + 1 * SDL_BYTESPERPIXEL(texture->format)) / 2);
|
||||
const Uint8 *plane0 = (const Uint8 *)srcPixels;
|
||||
const Uint8 *plane1 = plane0 + rect->h * Ypitch;
|
||||
const Uint8 *plane2 = plane1 + ((rect->h + 1) / 2) * UVpitch;
|
||||
@@ -2232,6 +2225,7 @@ static void D3D11_SetupShaderConstants(SDL_Renderer *renderer, const SDL_RenderC
|
||||
constants->texture_type = TEXTURETYPE_NV12;
|
||||
constants->input_type = INPUTTYPE_HDR10;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
constants->texture_type = TEXTURETYPE_YUV;
|
||||
constants->input_type = INPUTTYPE_HDR10;
|
||||
@@ -3079,6 +3073,7 @@ static bool D3D11_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_P010);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I0FL);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I4FL);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -335,6 +335,7 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(SDL_PixelFormat format, Uin
|
||||
return DXGI_FORMAT_NV12;
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
return DXGI_FORMAT_P010;
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
return DXGI_FORMAT_R16_UNORM;
|
||||
default:
|
||||
@@ -1691,7 +1692,8 @@ static bool D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_IYUV) {
|
||||
texture->format == SDL_PIXELFORMAT_IYUV ||
|
||||
texture->format == SDL_PIXELFORMAT_I0FL) {
|
||||
textureData->yuv = true;
|
||||
|
||||
textureDesc.Width = (textureDesc.Width + 1) / 2;
|
||||
@@ -1735,7 +1737,8 @@ static bool D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
textureData->mainResourceStateV = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
SDL_SetPointerProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_D3D12_TEXTURE_V_POINTER, textureData->mainTextureV);
|
||||
|
||||
textureData->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8);
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_I0FL) ? 16 : 8;
|
||||
textureData->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!textureData->YCbCr_matrix) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
@@ -1783,7 +1786,7 @@ static bool D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
textureData->mainResourceStateV = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
SDL_SetPointerProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_D3D12_TEXTURE_V_POINTER, textureData->mainTextureV);
|
||||
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_I444) ? 8 : 16;
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_I4FL) ? 16 : 8;
|
||||
textureData->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!textureData->YCbCr_matrix) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
@@ -1793,18 +1796,9 @@ static bool D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
if (texture->format == SDL_PIXELFORMAT_NV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_NV21 ||
|
||||
texture->format == SDL_PIXELFORMAT_P010) {
|
||||
int bits_per_pixel;
|
||||
|
||||
textureData->nv12 = true;
|
||||
|
||||
switch (texture->format) {
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
bits_per_pixel = 10;
|
||||
break;
|
||||
default:
|
||||
bits_per_pixel = 8;
|
||||
break;
|
||||
}
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_P010) ? 10 : 8;
|
||||
textureData->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!textureData->YCbCr_matrix) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
@@ -2084,15 +2078,17 @@ static bool D3D12_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
const int bpp = SDL_BYTESPERPIXEL(texture->format);
|
||||
|
||||
// Skip to the correct offset into the next texture
|
||||
srcPixels = (const void *)((const Uint8 *)srcPixels + rect->h * srcPitch);
|
||||
if (!D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureV : textureData->mainTextureU, 0, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1) / 2, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateV : &textureData->mainResourceStateU)) {
|
||||
if (!D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureV : textureData->mainTextureU, 0, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1 * bpp) / 2, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateV : &textureData->mainResourceStateU)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip to the correct offset into the next texture
|
||||
srcPixels = (const void *)((const Uint8 *)srcPixels + ((rect->h + 1) / 2) * ((srcPitch + 1) / 2));
|
||||
if (!D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureU : textureData->mainTextureV, 0, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1) / 2, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateU : &textureData->mainResourceStateV)) {
|
||||
srcPixels = (const void *)((const Uint8 *)srcPixels + ((rect->h + 1) / 2) * ((srcPitch + 1 * bpp) / 2));
|
||||
if (!D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureU : textureData->mainTextureV, 0, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1 * bpp) / 2, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateU : &textureData->mainResourceStateV)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2692,6 +2688,7 @@ static void D3D12_SetupShaderConstants(SDL_Renderer *renderer, const SDL_RenderC
|
||||
constants->texture_type = TEXTURETYPE_NV12;
|
||||
constants->input_type = INPUTTYPE_HDR10;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
constants->texture_type = TEXTURETYPE_YUV;
|
||||
constants->input_type = INPUTTYPE_HDR10;
|
||||
@@ -3685,6 +3682,7 @@ bool D3D12_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Proper
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_P010);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I0FL);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I4FL);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -294,6 +294,7 @@ static bool GPU_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_
|
||||
format = SDL_GPU_TEXTUREFORMAT_R8_UNORM;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
format = SDL_GPU_TEXTUREFORMAT_R16_UNORM;
|
||||
break;
|
||||
@@ -324,7 +325,8 @@ static bool GPU_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_
|
||||
data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
|
||||
size = (size_t)texture->h * data->pitch;
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_IYUV) {
|
||||
texture->format == SDL_PIXELFORMAT_IYUV ||
|
||||
texture->format == SDL_PIXELFORMAT_I0FL) {
|
||||
// Need to add size for the U and V planes
|
||||
size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2);
|
||||
}
|
||||
@@ -378,7 +380,8 @@ static bool GPU_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_
|
||||
|
||||
#ifdef SDL_HAVE_YUV
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_IYUV) {
|
||||
texture->format == SDL_PIXELFORMAT_IYUV ||
|
||||
texture->format == SDL_PIXELFORMAT_I0FL) {
|
||||
data->yuv = true;
|
||||
|
||||
tci.width = (tci.width + 1) / 2;
|
||||
@@ -406,7 +409,8 @@ static bool GPU_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_
|
||||
}
|
||||
SDL_SetPointerProperty(props, SDL_PROP_TEXTURE_GPU_TEXTURE_V_POINTER, data->textureV);
|
||||
|
||||
data->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, 8);
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_I0FL) ? 16 : 8;
|
||||
data->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!data->YCbCr_matrix) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
}
|
||||
@@ -437,7 +441,7 @@ static bool GPU_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_
|
||||
}
|
||||
SDL_SetPointerProperty(props, SDL_PROP_TEXTURE_GPU_TEXTURE_V_POINTER, data->textureU);
|
||||
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_I444) ? 8 : 16;
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_I4FL) ? 16 : 8;
|
||||
data->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!data->YCbCr_matrix) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
@@ -446,8 +450,6 @@ static bool GPU_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_
|
||||
if (texture->format == SDL_PIXELFORMAT_NV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_NV21 ||
|
||||
texture->format == SDL_PIXELFORMAT_P010) {
|
||||
int bits_per_pixel;
|
||||
|
||||
data->nv12 = true;
|
||||
|
||||
data->textureNV = SDL_GetPointerProperty(create_props, SDL_PROP_TEXTURE_CREATE_GPU_TEXTURE_UV_POINTER, NULL);
|
||||
@@ -469,14 +471,7 @@ static bool GPU_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_
|
||||
}
|
||||
SDL_SetPointerProperty(props, SDL_PROP_TEXTURE_GPU_TEXTURE_UV_POINTER, data->textureNV);
|
||||
|
||||
switch (texture->format) {
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
bits_per_pixel = 10;
|
||||
break;
|
||||
default:
|
||||
bits_per_pixel = 8;
|
||||
break;
|
||||
}
|
||||
const int bits_per_pixel = (texture->format == SDL_PIXELFORMAT_P010) ? 10 : 8;
|
||||
data->YCbCr_matrix = SDL_GetYCbCRtoRGBConversionMatrix(texture->colorspace, texture->w, texture->h, bits_per_pixel);
|
||||
if (!data->YCbCr_matrix) {
|
||||
return SDL_SetError("Unsupported YUV colorspace");
|
||||
@@ -590,7 +585,7 @@ static bool GPU_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, cons
|
||||
retval &= GPU_UpdateTextureInternal(renderdata, cpass, data->textureV, bpp, rect->x, rect->y, rect->w, rect->h, Vplane, pitch);
|
||||
} else {
|
||||
int Ypitch = pitch;
|
||||
int UVpitch = ((Ypitch + 1) / 2);
|
||||
int UVpitch = ((Ypitch + 1 * SDL_BYTESPERPIXEL(texture->format)) / 2);
|
||||
const Uint8 *Yplane = (const Uint8 *)pixels;
|
||||
const Uint8 *Uplane = Yplane + rect->h * Ypitch;
|
||||
const Uint8 *Vplane = Uplane + ((rect->h + 1) / 2) * UVpitch;
|
||||
@@ -944,6 +939,7 @@ static void CalculateAdvancedShaderConstants(SDL_Renderer *renderer, const SDL_R
|
||||
constants->texture_type = TEXTURETYPE_NV12;
|
||||
constants->input_type = INPUTTYPE_HDR10;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
constants->texture_type = TEXTURETYPE_YUV;
|
||||
constants->input_type = INPUTTYPE_HDR10;
|
||||
@@ -1912,6 +1908,7 @@ static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_P010);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I0FL);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I4FL);
|
||||
|
||||
SDL_SetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 16384);
|
||||
|
||||
@@ -762,6 +762,7 @@ static bool METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
pixfmt = MTLPixelFormatR8Unorm;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
pixfmt = MTLPixelFormatR16Unorm;
|
||||
break;
|
||||
@@ -806,7 +807,7 @@ static bool METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
|
||||
SDL_SetPointerProperty(SDL_GetTextureProperties(texture), SDL_PROP_TEXTURE_METAL_TEXTURE_POINTER, (__bridge void *)mtltexture);
|
||||
|
||||
#ifdef SDL_HAVE_YUV
|
||||
BOOL yuv = (texture->format == SDL_PIXELFORMAT_IYUV || texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_I444 || texture->format == SDL_PIXELFORMAT_I4FL);
|
||||
BOOL yuv = (texture->format == SDL_PIXELFORMAT_IYUV || texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_I444 || texture->format == SDL_PIXELFORMAT_I0FL || texture->format == SDL_PIXELFORMAT_I4FL);
|
||||
BOOL nv12 = (texture->format == SDL_PIXELFORMAT_NV12 || texture->format == SDL_PIXELFORMAT_NV21 || texture->format == SDL_PIXELFORMAT_P010);
|
||||
|
||||
if (yuv) {
|
||||
@@ -1008,7 +1009,7 @@ static bool METAL_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
UVpitch = pitch;
|
||||
UVrect = *rect;
|
||||
} else {
|
||||
UVpitch = (pitch + 1) / 2;
|
||||
UVpitch = (pitch + 1 * SDL_BYTESPERPIXEL(texture->format)) / 2;
|
||||
UVrect.x = rect->x / 2;
|
||||
UVrect.y = rect->y / 2;
|
||||
UVrect.w = (rect->w + 1) / 2;
|
||||
@@ -1517,6 +1518,7 @@ static void SetupShaderConstants(SDL_Renderer *renderer, const SDL_RenderCommand
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_I444:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
constants->texture_type = TEXTURETYPE_YUV;
|
||||
break;
|
||||
@@ -2622,6 +2624,7 @@ static bool METAL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_P010);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I0FL);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I4FL);
|
||||
|
||||
#if defined(SDL_PLATFORM_MACOS) || TARGET_OS_MACCATALYST
|
||||
|
||||
@@ -433,6 +433,7 @@ static int VULKAN_VkFormatGetNumPlanes(VkFormat vkFormat)
|
||||
switch (vkFormat) {
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
|
||||
return 3;
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
|
||||
@@ -455,6 +456,7 @@ static VkDeviceSize VULKAN_GetBytesPerPixel(VkFormat vkFormat, int plane)
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
|
||||
case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
|
||||
return 1;
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
|
||||
case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
|
||||
return 2;
|
||||
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
|
||||
@@ -485,6 +487,8 @@ static VkFormat SDLPixelFormatToVkTextureFormat(SDL_PixelFormat format, Uint32 o
|
||||
return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
return VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16;
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
return VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM;
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
return VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM;
|
||||
default:
|
||||
@@ -2665,6 +2669,7 @@ static bool VULKAN_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, S
|
||||
texture->format == SDL_PIXELFORMAT_NV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_NV21 ||
|
||||
texture->format == SDL_PIXELFORMAT_P010 ||
|
||||
texture->format == SDL_PIXELFORMAT_I0FL ||
|
||||
texture->format == SDL_PIXELFORMAT_I4FL) {
|
||||
const uint32_t YUV_SD_THRESHOLD = 576;
|
||||
|
||||
@@ -3008,7 +3013,7 @@ static bool VULKAN_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
return VULKAN_UpdateTextureYUV(renderer, texture, rect, plane0, srcPitch, plane1, srcPitch, plane2, srcPitch);
|
||||
} else {
|
||||
int Ypitch = srcPitch;
|
||||
int UVpitch = ((Ypitch + 1) / 2);
|
||||
int UVpitch = ((Ypitch + 1 * SDL_BYTESPERPIXEL(texture->format)) / 2);
|
||||
const Uint8 *plane0 = (const Uint8 *)srcPixels;
|
||||
const Uint8 *plane1 = plane0 + rect->h * Ypitch;
|
||||
const Uint8 *plane2 = plane1 + ((rect->h + 1) / 2) * UVpitch;
|
||||
@@ -3497,6 +3502,7 @@ static void VULKAN_SetupShaderConstants(SDL_Renderer *renderer, const SDL_Render
|
||||
constants->input_type = INPUTTYPE_SRGB;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
constants->input_type = INPUTTYPE_HDR10;
|
||||
break;
|
||||
@@ -4722,6 +4728,7 @@ static bool VULKAN_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SD
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV12);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_NV21);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_P010);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I0FL);
|
||||
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_I4FL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -216,6 +216,7 @@ const char *SDL_GetPixelFormatName(SDL_PixelFormat format)
|
||||
CASE(SDL_PIXELFORMAT_NV21)
|
||||
CASE(SDL_PIXELFORMAT_P010)
|
||||
CASE(SDL_PIXELFORMAT_I444)
|
||||
CASE(SDL_PIXELFORMAT_I0FL)
|
||||
CASE(SDL_PIXELFORMAT_I4FL)
|
||||
CASE(SDL_PIXELFORMAT_EXTERNAL_OES)
|
||||
CASE(SDL_PIXELFORMAT_MJPG)
|
||||
@@ -856,7 +857,7 @@ SDL_Colorspace SDL_GetDefaultColorspaceForFormat(SDL_PixelFormat format)
|
||||
if (SDL_ISPIXELFORMAT_FOURCC(format)) {
|
||||
if (format == SDL_PIXELFORMAT_MJPG) {
|
||||
return SDL_COLORSPACE_SRGB;
|
||||
} else if (format == SDL_PIXELFORMAT_P010 || format == SDL_PIXELFORMAT_I4FL) {
|
||||
} else if (format == SDL_PIXELFORMAT_P010 || format == SDL_PIXELFORMAT_I0FL || format == SDL_PIXELFORMAT_I4FL) {
|
||||
return SDL_COLORSPACE_HDR10;
|
||||
} else {
|
||||
return SDL_COLORSPACE_YUV_DEFAULT;
|
||||
|
||||
@@ -34,7 +34,12 @@ static bool IsPlanar1x1Format(SDL_PixelFormat format)
|
||||
|
||||
static bool IsPlanar2x2Format(SDL_PixelFormat format)
|
||||
{
|
||||
return format == SDL_PIXELFORMAT_YV12 || format == SDL_PIXELFORMAT_IYUV || format == SDL_PIXELFORMAT_NV12 || format == SDL_PIXELFORMAT_NV21 || format == SDL_PIXELFORMAT_P010;
|
||||
return format == SDL_PIXELFORMAT_YV12 ||
|
||||
format == SDL_PIXELFORMAT_IYUV ||
|
||||
format == SDL_PIXELFORMAT_NV12 ||
|
||||
format == SDL_PIXELFORMAT_NV21 ||
|
||||
format == SDL_PIXELFORMAT_P010 ||
|
||||
format == SDL_PIXELFORMAT_I0FL;
|
||||
}
|
||||
|
||||
static bool IsPacked4Format(Uint32 format)
|
||||
@@ -65,16 +70,19 @@ bool SDL_CalculateYUVSize(SDL_PixelFormat format, int w, int h, size_t *size, si
|
||||
sz_plane_chroma = sz_plane;
|
||||
} else if (IsPlanar2x2Format(format)) {
|
||||
{
|
||||
/* sz_plane == w * h; */
|
||||
/* sz_plane == w * h * bpp; */
|
||||
size_t s1;
|
||||
if (!SDL_size_mul_check_overflow(w, h, &s1)) {
|
||||
return SDL_SetError("width * height would overflow");
|
||||
}
|
||||
sz_plane = (int) s1;
|
||||
if (!SDL_size_mul_check_overflow(s1, SDL_BYTESPERPIXEL(format), &s1)) {
|
||||
return SDL_SetError("width * height * bpp would overflow");
|
||||
}
|
||||
sz_plane = (int)s1;
|
||||
}
|
||||
|
||||
{
|
||||
/* sz_plane_chroma == ((w + 1) / 2) * ((h + 1) / 2); */
|
||||
/* sz_plane_chroma == ((w + 1) / 2) * ((h + 1) / 2) * bpp; */
|
||||
size_t s1, s2, s3;
|
||||
if (!SDL_size_add_check_overflow(w, 1, &s1)) {
|
||||
return SDL_SetError("width + 1 would overflow");
|
||||
@@ -87,7 +95,10 @@ bool SDL_CalculateYUVSize(SDL_PixelFormat format, int w, int h, size_t *size, si
|
||||
if (!SDL_size_mul_check_overflow(s1, s2, &s3)) {
|
||||
return SDL_SetError("width * height would overflow");
|
||||
}
|
||||
sz_plane_chroma = (int) s3;
|
||||
if (!SDL_size_mul_check_overflow(s3, SDL_BYTESPERPIXEL(format), &s3)) {
|
||||
return SDL_SetError("width * height * bpp would overflow");
|
||||
}
|
||||
sz_plane_chroma = (int)s3;
|
||||
}
|
||||
} else {
|
||||
/* sz_plane_packed == ((w + 1) / 2) * h; */
|
||||
@@ -105,8 +116,9 @@ bool SDL_CalculateYUVSize(SDL_PixelFormat format, int w, int h, size_t *size, si
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_YV12: /**< Planar mode: Y + V + U (3 planes) */
|
||||
case SDL_PIXELFORMAT_IYUV: /**< Planar mode: Y + U + V (3 planes) */
|
||||
case SDL_PIXELFORMAT_I444:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
case SDL_PIXELFORMAT_I444: /**< Planar mode: Y + U + V (3 planes) */
|
||||
case SDL_PIXELFORMAT_I0FL: /**< Planar mode: Y + U + V (3 planes) */
|
||||
case SDL_PIXELFORMAT_I4FL: /**< Planar mode: Y + U + V (3 planes) */
|
||||
|
||||
if (pitch) {
|
||||
*pitch = w * SDL_BYTESPERPIXEL(format);
|
||||
@@ -223,9 +235,10 @@ static bool GetYUVPlanes(int width, int height, SDL_PixelFormat format, const vo
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
pitches[0] = yuv_pitch;
|
||||
pitches[1] = (pitches[0] + 1) / 2;
|
||||
pitches[2] = (pitches[0] + 1) / 2;
|
||||
pitches[1] = (pitches[0] + 1 * SDL_BYTESPERPIXEL(format)) / 2;
|
||||
pitches[2] = pitches[1];
|
||||
planes[0] = (const Uint8 *)yuv;
|
||||
planes[1] = planes[0] + pitches[0] * height;
|
||||
planes[2] = planes[1] + pitches[1] * ((height + 1) / 2);
|
||||
@@ -273,6 +286,7 @@ static bool GetYUVPlanes(int width, int height, SDL_PixelFormat format, const vo
|
||||
break;
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_I444:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
*y = planes[0];
|
||||
*y_stride = pitches[0];
|
||||
@@ -635,6 +649,16 @@ static bool yuv_rgb_std(
|
||||
}
|
||||
}
|
||||
|
||||
if (src_format == SDL_PIXELFORMAT_I0FL) {
|
||||
switch (dst_format) {
|
||||
case SDL_PIXELFORMAT_RGB48:
|
||||
yuvi0fl_rgb48_std(width, height, (const uint16_t *)y, (const uint16_t *)u, (const uint16_t *)v, y_stride, uv_stride, rgb, rgb_stride, yuv_type);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (src_format == SDL_PIXELFORMAT_I4FL) {
|
||||
switch (dst_format) {
|
||||
case SDL_PIXELFORMAT_RGB48:
|
||||
@@ -702,7 +726,7 @@ bool SDL_ConvertPixels_YUV_to_RGB(int width, int height,
|
||||
return result;
|
||||
}
|
||||
|
||||
if (src_format == SDL_PIXELFORMAT_I4FL && dst_format != SDL_PIXELFORMAT_RGB48) {
|
||||
if ((src_format == SDL_PIXELFORMAT_I0FL || src_format == SDL_PIXELFORMAT_I4FL) && dst_format != SDL_PIXELFORMAT_RGB48) {
|
||||
bool result;
|
||||
void *tmp;
|
||||
int tmp_pitch = (width * 3 * sizeof(Uint16));
|
||||
|
||||
@@ -175,6 +175,11 @@ static uint16_t clamp16(int32_t v)
|
||||
#undef YUV_BITS
|
||||
#define YUV_BITS 16
|
||||
|
||||
#define STD_FUNCTION_NAME yuvi0fl_rgb48_std
|
||||
#define YUV_FORMAT YUV_FORMAT_420
|
||||
#define RGB_FORMAT RGB_FORMAT_RGB48
|
||||
#include "yuv_rgb_std_func.h"
|
||||
|
||||
#define STD_FUNCTION_NAME yuvi4fl_rgb48_std
|
||||
#define YUV_FORMAT YUV_FORMAT_444
|
||||
#define RGB_FORMAT RGB_FORMAT_RGB48
|
||||
|
||||
@@ -159,6 +159,12 @@ void yuvp010_xbgr2101010_std(
|
||||
uint8_t *rgb, uint32_t rgb_stride,
|
||||
YCbCrType yuv_type);
|
||||
|
||||
void yuvi0fl_rgb48_std(
|
||||
uint32_t width, uint32_t height,
|
||||
const uint16_t *y, const uint16_t *u, const uint16_t *v, uint32_t y_stride, uint32_t uv_stride,
|
||||
uint8_t *rgb, uint32_t rgb_stride,
|
||||
YCbCrType yuv_type);
|
||||
|
||||
void yuvi4fl_rgb48_std(
|
||||
uint32_t width, uint32_t height,
|
||||
const uint16_t *y, const uint16_t *u, const uint16_t *v, uint32_t y_stride, uint32_t uv_stride,
|
||||
|
||||
@@ -640,6 +640,14 @@ SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I444_ARRAY, !SDL_ISPIXELFORMAT_ARRAY(SDL
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I444_10BIT, !SDL_ISPIXELFORMAT_10BIT(SDL_PIXELFORMAT_I444));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I444_FLOAT, !SDL_ISPIXELFORMAT_FLOAT(SDL_PIXELFORMAT_I444));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I444_ALPHA, !SDL_ISPIXELFORMAT_ALPHA(SDL_PIXELFORMAT_I444));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I0FL_FORMAT, SDL_PIXELFORMAT_I0FL == SDL_DEFINE_PIXELFOURCC('I', '0', 'F', 'L'));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I0FL_FOURCC, SDL_ISPIXELFORMAT_FOURCC(SDL_PIXELFORMAT_I0FL));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I0FL_INDEXED, !SDL_ISPIXELFORMAT_INDEXED(SDL_PIXELFORMAT_I0FL));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I0FL_PACKED, !SDL_ISPIXELFORMAT_PACKED(SDL_PIXELFORMAT_I0FL));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I0FL_ARRAY, !SDL_ISPIXELFORMAT_ARRAY(SDL_PIXELFORMAT_I0FL));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I0FL_10BIT, !SDL_ISPIXELFORMAT_10BIT(SDL_PIXELFORMAT_I0FL));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I0FL_FLOAT, !SDL_ISPIXELFORMAT_FLOAT(SDL_PIXELFORMAT_I0FL));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I0FL_ALPHA, !SDL_ISPIXELFORMAT_ALPHA(SDL_PIXELFORMAT_I0FL));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I4FL_FORMAT, SDL_PIXELFORMAT_I4FL == SDL_DEFINE_PIXELFOURCC('I', '4', 'F', 'L'));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I4FL_FOURCC, SDL_ISPIXELFORMAT_FOURCC(SDL_PIXELFORMAT_I4FL));
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PIXELFORMAT_I4FL_INDEXED, !SDL_ISPIXELFORMAT_INDEXED(SDL_PIXELFORMAT_I4FL));
|
||||
|
||||
@@ -415,16 +415,16 @@ static bool create_textures(SDL_Renderer *renderer, SDL_Surface *original, SDL_P
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s", SDL_GetError());
|
||||
goto done;
|
||||
}
|
||||
if (planar && (yuv_format == SDL_PIXELFORMAT_YV12 || yuv_format == SDL_PIXELFORMAT_IYUV)) {
|
||||
if (planar && (yuv_format == SDL_PIXELFORMAT_YV12 || yuv_format == SDL_PIXELFORMAT_IYUV || yuv_format == SDL_PIXELFORMAT_I0FL)) {
|
||||
const int Yrows = original->h;
|
||||
const int UVrows = ((original->h + 1) / 2);
|
||||
const int src_Ypitch = pitch;
|
||||
const int src_UVpitch = ((pitch + 1) / 2);
|
||||
const int src_UVpitch = ((pitch + 1 * SDL_BYTESPERPIXEL(yuv_format)) / 2);
|
||||
const Uint8 *src_plane0 = (const Uint8 *)raw_yuv;
|
||||
const Uint8 *src_plane1 = src_plane0 + Yrows * src_Ypitch;
|
||||
const Uint8 *src_plane2 = src_plane1 + UVrows * src_UVpitch;
|
||||
const int Ypitch = pitch + 37;
|
||||
const int UVpitch = ((Ypitch + 1) / 2);
|
||||
const int UVpitch = ((Ypitch + 1 * SDL_BYTESPERPIXEL(yuv_format)) / 2);
|
||||
Uint8 *plane0 = (Uint8 *)SDL_calloc(1, Yrows * Ypitch);
|
||||
Uint8 *plane1 = (Uint8 *)SDL_calloc(1, UVrows * UVpitch);
|
||||
Uint8 *plane2 = (Uint8 *)SDL_calloc(1, UVrows * UVpitch);
|
||||
@@ -929,6 +929,11 @@ int main(int argc, char **argv)
|
||||
rgb_format = SDL_PIXELFORMAT_XBGR2101010;
|
||||
SetYUVConversionMode(YUV_CONVERSION_BT2020);
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp(argv[i], "--i0fl") == 0) {
|
||||
yuv_format = SDL_PIXELFORMAT_I0FL;
|
||||
rgb_format = SDL_PIXELFORMAT_XBGR2101010;
|
||||
SetYUVConversionMode(YUV_CONVERSION_BT2020);
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp(argv[i], "--i4fl") == 0) {
|
||||
yuv_format = SDL_PIXELFORMAT_I4FL;
|
||||
rgb_format = SDL_PIXELFORMAT_XBGR2101010;
|
||||
|
||||
@@ -277,112 +277,123 @@ static void ConvertRGBtoPlanar2x2(Uint32 format, Uint8 *src, int pitch, Uint8 *o
|
||||
Uint8 *rgb1, *rgb2;
|
||||
int rgb_row_advance = (pitch - w * 3) + pitch;
|
||||
int UV_advance;
|
||||
int yuv_bits;
|
||||
int yuv_bytes_per_pixel = SDL_BYTESPERPIXEL(format);
|
||||
|
||||
rgb1 = src;
|
||||
rgb2 = src + pitch;
|
||||
|
||||
Y1 = out;
|
||||
Y2 = Y1 + w;
|
||||
Y2 = Y1 + w * yuv_bytes_per_pixel;
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
yuv_bits = 8;
|
||||
V = (Y1 + h * w);
|
||||
U = V + ((h + 1) / 2) * ((w + 1) / 2);
|
||||
UV_advance = 1;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
yuv_bits = 8;
|
||||
U = (Y1 + h * w);
|
||||
V = U + ((h + 1) / 2) * ((w + 1) / 2);
|
||||
UV_advance = 1;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_NV12:
|
||||
yuv_bits = 8;
|
||||
U = (Y1 + h * w);
|
||||
V = U + 1;
|
||||
UV_advance = 2;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
yuv_bits = 8;
|
||||
V = (Y1 + h * w);
|
||||
U = V + 1;
|
||||
UV_advance = 2;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
yuv_bits = 16;
|
||||
U = (Y1 + h * w * yuv_bytes_per_pixel);
|
||||
V = U + ((h + 1) / 2) * ((w + 1) / 2) * yuv_bytes_per_pixel;
|
||||
UV_advance = 1;
|
||||
break;
|
||||
default:
|
||||
SDL_assert(!"Unsupported planar YUV format");
|
||||
return;
|
||||
}
|
||||
|
||||
#define COPY_VALUE(X, V, ADVANCE) \
|
||||
do { \
|
||||
if (format == SDL_PIXELFORMAT_I0FL) { \
|
||||
*(Uint16 *)X = (Uint16)V; \
|
||||
} else { \
|
||||
*X = (Uint8)V; \
|
||||
} \
|
||||
X += ADVANCE * yuv_bytes_per_pixel; \
|
||||
} while (0)
|
||||
|
||||
for (y = 0; y < (h - 1); y += 2) {
|
||||
for (x = 0; x < (w - 1); x += 2) {
|
||||
RGBtoYUV(rgb1, 8, yuv[0], 8, mode, monochrome, luminance);
|
||||
RGBtoYUV(rgb1, 8, yuv[0], yuv_bits, mode, monochrome, luminance);
|
||||
rgb1 += 3;
|
||||
*Y1++ = (Uint8)yuv[0][0];
|
||||
COPY_VALUE(Y1, yuv[0][0], 1);
|
||||
|
||||
RGBtoYUV(rgb1, 8, yuv[1], 8, mode, monochrome, luminance);
|
||||
RGBtoYUV(rgb1, 8, yuv[1], yuv_bits, mode, monochrome, luminance);
|
||||
rgb1 += 3;
|
||||
*Y1++ = (Uint8)yuv[1][0];
|
||||
COPY_VALUE(Y1, yuv[1][0], 1);
|
||||
|
||||
RGBtoYUV(rgb2, 8, yuv[2], 8, mode, monochrome, luminance);
|
||||
RGBtoYUV(rgb2, 8, yuv[2], yuv_bits, mode, monochrome, luminance);
|
||||
rgb2 += 3;
|
||||
*Y2++ = (Uint8)yuv[2][0];
|
||||
COPY_VALUE(Y2, yuv[2][0], 1);
|
||||
|
||||
RGBtoYUV(rgb2, 8, yuv[3], 8, mode, monochrome, luminance);
|
||||
RGBtoYUV(rgb2, 8, yuv[3], yuv_bits, mode, monochrome, luminance);
|
||||
rgb2 += 3;
|
||||
*Y2++ = (Uint8)yuv[3][0];
|
||||
COPY_VALUE(Y2, yuv[3][0], 1);
|
||||
|
||||
*U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1] + yuv[2][1] + yuv[3][1]) / 4.0f + 0.5f);
|
||||
U += UV_advance;
|
||||
|
||||
*V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2] + yuv[2][2] + yuv[3][2]) / 4.0f + 0.5f);
|
||||
V += UV_advance;
|
||||
COPY_VALUE(U, SDL_floorf((yuv[0][1] + yuv[1][1] + yuv[2][1] + yuv[3][1]) / 4.0f + 0.5f), UV_advance);
|
||||
COPY_VALUE(V, SDL_floorf((yuv[0][2] + yuv[1][2] + yuv[2][2] + yuv[3][2]) / 4.0f + 0.5f), UV_advance);
|
||||
}
|
||||
/* Last column */
|
||||
if (x == (w - 1)) {
|
||||
RGBtoYUV(rgb1, 8, yuv[0], 8, mode, monochrome, luminance);
|
||||
RGBtoYUV(rgb1, 8, yuv[0], yuv_bits, mode, monochrome, luminance);
|
||||
rgb1 += 3;
|
||||
*Y1++ = (Uint8)yuv[0][0];
|
||||
COPY_VALUE(Y1, yuv[0][0], 1);
|
||||
|
||||
RGBtoYUV(rgb2, 8, yuv[2], 8, mode, monochrome, luminance);
|
||||
RGBtoYUV(rgb2, 8, yuv[2], yuv_bits, mode, monochrome, luminance);
|
||||
rgb2 += 3;
|
||||
*Y2++ = (Uint8)yuv[2][0];
|
||||
COPY_VALUE(Y2, yuv[2][0], 1);
|
||||
|
||||
*U = (Uint8)SDL_floorf((yuv[0][1] + yuv[2][1]) / 2.0f + 0.5f);
|
||||
U += UV_advance;
|
||||
|
||||
*V = (Uint8)SDL_floorf((yuv[0][2] + yuv[2][2]) / 2.0f + 0.5f);
|
||||
V += UV_advance;
|
||||
COPY_VALUE(U, SDL_floorf((yuv[0][1] + yuv[2][1]) / 2.0f + 0.5f), UV_advance);
|
||||
COPY_VALUE(V, SDL_floorf((yuv[0][2] + yuv[2][2]) / 2.0f + 0.5f), UV_advance);
|
||||
}
|
||||
Y1 += w;
|
||||
Y2 += w;
|
||||
Y1 += w * yuv_bytes_per_pixel;
|
||||
Y2 += w * yuv_bytes_per_pixel;
|
||||
rgb1 += rgb_row_advance;
|
||||
rgb2 += rgb_row_advance;
|
||||
}
|
||||
/* Last row */
|
||||
if (y == (h - 1)) {
|
||||
for (x = 0; x < (w - 1); x += 2) {
|
||||
RGBtoYUV(rgb1, 8, yuv[0], 8, mode, monochrome, luminance);
|
||||
RGBtoYUV(rgb1, 8, yuv[0], yuv_bits, mode, monochrome, luminance);
|
||||
rgb1 += 3;
|
||||
*Y1++ = (Uint8)yuv[0][0];
|
||||
COPY_VALUE(Y1, yuv[0][0], 1);
|
||||
|
||||
RGBtoYUV(rgb1, 8, yuv[1], 8, mode, monochrome, luminance);
|
||||
RGBtoYUV(rgb1, 8, yuv[1], yuv_bits, mode, monochrome, luminance);
|
||||
rgb1 += 3;
|
||||
*Y1++ = (Uint8)yuv[1][0];
|
||||
COPY_VALUE(Y1, yuv[1][0], 1);
|
||||
|
||||
*U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1]) / 2.0f + 0.5f);
|
||||
U += UV_advance;
|
||||
|
||||
*V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2]) / 2.0f + 0.5f);
|
||||
V += UV_advance;
|
||||
COPY_VALUE(U, SDL_floorf((yuv[0][1] + yuv[1][1]) / 2.0f + 0.5f), UV_advance);
|
||||
COPY_VALUE(V, SDL_floorf((yuv[0][2] + yuv[1][2]) / 2.0f + 0.5f), UV_advance);
|
||||
}
|
||||
/* Last column */
|
||||
if (x == (w - 1)) {
|
||||
RGBtoYUV(rgb1, 8, yuv[0], 8, mode, monochrome, luminance);
|
||||
*Y1++ = (Uint8)yuv[0][0];
|
||||
COPY_VALUE(Y1, yuv[0][0], 1);
|
||||
|
||||
*U = (Uint8)yuv[0][1];
|
||||
U += UV_advance;
|
||||
|
||||
*V = (Uint8)yuv[0][2];
|
||||
V += UV_advance;
|
||||
COPY_VALUE(U, yuv[0][1], UV_advance);
|
||||
COPY_VALUE(V, yuv[0][2], UV_advance);
|
||||
}
|
||||
}
|
||||
#undef COPY_VALUE
|
||||
}
|
||||
|
||||
static Uint16 Pack10to16(int v)
|
||||
@@ -575,6 +586,7 @@ bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, in
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_NV12:
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
ConvertRGBtoPlanar2x2(format, src, pitch, out, w, h, mode, monochrome, luminance);
|
||||
return true;
|
||||
case SDL_PIXELFORMAT_YUY2:
|
||||
@@ -591,6 +603,7 @@ int CalculateYUVPitch(Uint32 format, int width)
|
||||
{
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_P010:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
return width * 2;
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
|
||||
Reference in New Issue
Block a user