Use YUV colorspaces instead of a global YUV conversion mode
Fixes https://github.com/libsdl-org/SDL/issues/8669
This commit is contained in:
@@ -397,18 +397,19 @@ static AVCodecContext *OpenVideoStream(AVFormatContext *ic, int stream, const AV
|
||||
return context;
|
||||
}
|
||||
|
||||
static void SetYUVConversionMode(AVFrame *frame)
|
||||
static SDL_Colorspace GetFrameColorspace(AVFrame *frame)
|
||||
{
|
||||
SDL_YUV_CONVERSION_MODE mode = SDL_YUV_CONVERSION_AUTOMATIC;
|
||||
SDL_Colorspace colorspace = SDL_COLORSPACE_SRGB;
|
||||
|
||||
if (frame && (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUYV422 || frame->format == AV_PIX_FMT_UYVY422)) {
|
||||
if (frame->color_range == AVCOL_RANGE_JPEG)
|
||||
mode = SDL_YUV_CONVERSION_JPEG;
|
||||
else if (frame->colorspace == AVCOL_SPC_BT709)
|
||||
mode = SDL_YUV_CONVERSION_BT709;
|
||||
else if (frame->colorspace == AVCOL_SPC_BT470BG || frame->colorspace == AVCOL_SPC_SMPTE170M)
|
||||
mode = SDL_YUV_CONVERSION_BT601;
|
||||
colorspace = SDL_DEFINE_COLORSPACE(SDL_COLOR_TYPE_YCBCR,
|
||||
frame->color_range,
|
||||
frame->color_primaries,
|
||||
frame->color_trc,
|
||||
frame->colorspace,
|
||||
frame->chroma_location);
|
||||
}
|
||||
SDL_SetYUVConversionMode(mode); /* FIXME: no support for linear transfer */
|
||||
return colorspace;
|
||||
}
|
||||
|
||||
static void SDLCALL FreeSwsContextContainer(void *userdata, void *value)
|
||||
@@ -436,11 +437,18 @@ static SDL_bool GetTextureForMemoryFrame(AVFrame *frame, SDL_Texture **texture)
|
||||
SDL_DestroyTexture(*texture);
|
||||
}
|
||||
|
||||
SDL_PropertiesID props = SDL_CreateProperties();
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, GetFrameColorspace(frame));
|
||||
if (frame_format == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
*texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, frame->width, frame->height);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, SDL_PIXELFORMAT_ARGB8888);
|
||||
} else {
|
||||
*texture = SDL_CreateTexture(renderer, frame_format, SDL_TEXTUREACCESS_STREAMING, frame->width, frame->height);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, frame_format);
|
||||
}
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STREAMING);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, frame->width);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, frame->height);
|
||||
*texture = SDL_CreateTextureWithProperties(renderer, props);
|
||||
SDL_DestroyProperties(props);
|
||||
if (!*texture) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
@@ -489,7 +497,6 @@ static SDL_bool GetTextureForMemoryFrame(AVFrame *frame, SDL_Texture **texture)
|
||||
frame->data[1] + frame->linesize[1] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[1],
|
||||
frame->data[2] + frame->linesize[2] * (AV_CEIL_RSHIFT(frame->height, 1) - 1), -frame->linesize[2]);
|
||||
}
|
||||
SetYUVConversionMode(frame);
|
||||
break;
|
||||
default:
|
||||
if (frame->linesize[0] < 0) {
|
||||
@@ -527,11 +534,16 @@ static SDL_bool GetTextureForDRMFrame(AVFrame *frame, SDL_Texture **texture)
|
||||
} else {
|
||||
/* First time set up for NV12 textures */
|
||||
SDL_SetHint("SDL_RENDER_OPENGL_NV12_RG_SHADER", "1");
|
||||
|
||||
SetYUVConversionMode(frame);
|
||||
}
|
||||
|
||||
*texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_NV12, SDL_TEXTUREACCESS_STATIC, frame->width, frame->height);
|
||||
props = SDL_CreateProperties();
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, GetFrameColorspace(frame));
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, SDL_PIXELFORMAT_NV12);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, frame->width);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, frame->height);
|
||||
*texture = SDL_CreateTextureWithProperties(renderer, props);
|
||||
SDL_DestroyProperties(props);
|
||||
if (!*texture) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
@@ -617,12 +629,16 @@ static SDL_bool GetTextureForD3D11Frame(AVFrame *frame, SDL_Texture **texture)
|
||||
if (!*texture || (UINT)texture_width != desc.Width || (UINT)texture_height != desc.Height) {
|
||||
if (*texture) {
|
||||
SDL_DestroyTexture(*texture);
|
||||
} else {
|
||||
/* First time set up for NV12 textures */
|
||||
SetYUVConversionMode(frame);
|
||||
}
|
||||
|
||||
*texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_NV12, SDL_TEXTUREACCESS_STATIC, desc.Width, desc.Height);
|
||||
SDL_PropertiesID props = SDL_CreateProperties();
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_COLORSPACE_NUMBER, GetFrameColorspace(frame));
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_FORMAT_NUMBER, SDL_PIXELFORMAT_NV12);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_ACCESS_NUMBER, SDL_TEXTUREACCESS_STATIC);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_WIDTH_NUMBER, desc.Width);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_TEXTURE_CREATE_HEIGHT_NUMBER, desc.Height);
|
||||
*texture = SDL_CreateTextureWithProperties(renderer, props);
|
||||
SDL_DestroyProperties(props);
|
||||
if (!*texture) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ static SDL_Surface *generate_test_pattern(int pattern_size)
|
||||
return pattern;
|
||||
}
|
||||
|
||||
static SDL_bool verify_yuv_data(Uint32 format, const Uint8 *yuv, int yuv_pitch, SDL_Surface *surface)
|
||||
static SDL_bool verify_yuv_data(Uint32 format, SDL_Colorspace colorspace, const Uint8 *yuv, int yuv_pitch, SDL_Surface *surface)
|
||||
{
|
||||
const int tolerance = 20;
|
||||
const int size = (surface->h * surface->pitch);
|
||||
@@ -78,7 +78,7 @@ static SDL_bool verify_yuv_data(Uint32 format, const Uint8 *yuv, int yuv_pitch,
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (SDL_ConvertPixels(surface->w, surface->h, format, yuv, yuv_pitch, surface->format->format, rgb, surface->pitch) == 0) {
|
||||
if (SDL_ConvertPixelsAndColorspace(surface->w, surface->h, format, colorspace, yuv, yuv_pitch, surface->format->format, SDL_COLORSPACE_SRGB, rgb, surface->pitch) == 0) {
|
||||
int x, y;
|
||||
result = SDL_TRUE;
|
||||
for (y = 0; y < surface->h; ++y) {
|
||||
@@ -116,12 +116,19 @@ static int run_automated_tests(int pattern_size, int extra_pitch)
|
||||
SDL_PIXELFORMAT_UYVY,
|
||||
SDL_PIXELFORMAT_YVYU
|
||||
};
|
||||
const SDL_Colorspace colorspaces[] = {
|
||||
SDL_COLORSPACE_BT601_FULL,
|
||||
SDL_COLORSPACE_BT601_LIMITED,
|
||||
SDL_COLORSPACE_BT709_LIMITED
|
||||
};
|
||||
int i, j;
|
||||
SDL_Surface *pattern = generate_test_pattern(pattern_size);
|
||||
const int yuv_len = MAX_YUV_SURFACE_SIZE(pattern->w, pattern->h, extra_pitch);
|
||||
Uint8 *yuv1 = (Uint8 *)SDL_malloc(yuv_len);
|
||||
Uint8 *yuv2 = (Uint8 *)SDL_malloc(yuv_len);
|
||||
int yuv1_pitch, yuv2_pitch;
|
||||
YUV_CONVERSION_MODE mode;
|
||||
SDL_Colorspace colorspace;
|
||||
int result = -1;
|
||||
|
||||
if (!pattern || !yuv1 || !yuv2) {
|
||||
@@ -129,14 +136,18 @@ static int run_automated_tests(int pattern_size, int extra_pitch)
|
||||
goto done;
|
||||
}
|
||||
|
||||
mode = GetYUVConversionModeForResolution(pattern->w, pattern->h);
|
||||
SDL_assert(mode < SDL_arraysize(colorspaces));
|
||||
colorspace = colorspaces[mode];
|
||||
|
||||
/* Verify conversion from YUV formats */
|
||||
for (i = 0; i < SDL_arraysize(formats); ++i) {
|
||||
if (!ConvertRGBtoYUV(formats[i], pattern->pixels, pattern->pitch, yuv1, pattern->w, pattern->h, SDL_GetYUVConversionModeForResolution(pattern->w, pattern->h), 0, 100)) {
|
||||
if (!ConvertRGBtoYUV(formats[i], pattern->pixels, pattern->pitch, yuv1, pattern->w, pattern->h, mode, 0, 100)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "ConvertRGBtoYUV() doesn't support converting to %s\n", SDL_GetPixelFormatName(formats[i]));
|
||||
goto done;
|
||||
}
|
||||
yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w);
|
||||
if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) {
|
||||
if (!verify_yuv_data(formats[i], colorspace, yuv1, yuv1_pitch, pattern)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to RGB\n", SDL_GetPixelFormatName(formats[i]));
|
||||
goto done;
|
||||
}
|
||||
@@ -145,11 +156,11 @@ static int run_automated_tests(int pattern_size, int extra_pitch)
|
||||
/* Verify conversion to YUV formats */
|
||||
for (i = 0; i < SDL_arraysize(formats); ++i) {
|
||||
yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch;
|
||||
if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) {
|
||||
if (SDL_ConvertPixelsAndColorspace(pattern->w, pattern->h, pattern->format->format, SDL_COLORSPACE_SRGB, pattern->pixels, pattern->pitch, formats[i], colorspace, yuv1, yuv1_pitch) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError());
|
||||
goto done;
|
||||
}
|
||||
if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) {
|
||||
if (!verify_yuv_data(formats[i], colorspace, yuv1, yuv1_pitch, pattern)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from RGB to %s\n", SDL_GetPixelFormatName(formats[i]));
|
||||
goto done;
|
||||
}
|
||||
@@ -160,15 +171,15 @@ static int run_automated_tests(int pattern_size, int extra_pitch)
|
||||
for (j = 0; j < SDL_arraysize(formats); ++j) {
|
||||
yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch;
|
||||
yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch;
|
||||
if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) {
|
||||
if (SDL_ConvertPixelsAndColorspace(pattern->w, pattern->h, pattern->format->format, SDL_COLORSPACE_SRGB, pattern->pixels, pattern->pitch, formats[i], colorspace, yuv1, yuv1_pitch) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError());
|
||||
goto done;
|
||||
}
|
||||
if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv2, yuv2_pitch) < 0) {
|
||||
if (SDL_ConvertPixelsAndColorspace(pattern->w, pattern->h, formats[i], colorspace, yuv1, yuv1_pitch, formats[j], colorspace, yuv2, yuv2_pitch) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError());
|
||||
goto done;
|
||||
}
|
||||
if (!verify_yuv_data(formats[j], yuv2, yuv2_pitch, pattern)) {
|
||||
if (!verify_yuv_data(formats[j], colorspace, yuv2, yuv2_pitch, pattern)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]));
|
||||
goto done;
|
||||
}
|
||||
@@ -185,15 +196,15 @@ static int run_automated_tests(int pattern_size, int extra_pitch)
|
||||
|
||||
yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch;
|
||||
yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch;
|
||||
if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) {
|
||||
if (SDL_ConvertPixelsAndColorspace(pattern->w, pattern->h, pattern->format->format, SDL_COLORSPACE_SRGB, pattern->pixels, pattern->pitch, formats[i], colorspace, yuv1, yuv1_pitch) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError());
|
||||
goto done;
|
||||
}
|
||||
if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv1, yuv2_pitch) < 0) {
|
||||
if (SDL_ConvertPixelsAndColorspace(pattern->w, pattern->h, formats[i], colorspace, yuv1, yuv1_pitch, formats[j], colorspace, yuv1, yuv2_pitch) < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError());
|
||||
goto done;
|
||||
}
|
||||
if (!verify_yuv_data(formats[j], yuv1, yuv2_pitch, pattern)) {
|
||||
if (!verify_yuv_data(formats[j], colorspace, yuv1, yuv2_pitch, pattern)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]));
|
||||
goto done;
|
||||
}
|
||||
@@ -277,16 +288,16 @@ int main(int argc, char **argv)
|
||||
consumed = SDLTest_CommonArg(state, i);
|
||||
if (!consumed) {
|
||||
if (SDL_strcmp(argv[i], "--jpeg") == 0) {
|
||||
SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_JPEG);
|
||||
SetYUVConversionMode(YUV_CONVERSION_JPEG);
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp(argv[i], "--bt601") == 0) {
|
||||
SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT601);
|
||||
SetYUVConversionMode(YUV_CONVERSION_BT601);
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp(argv[i], "--bt709") == 0) {
|
||||
SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT709);
|
||||
SetYUVConversionMode(YUV_CONVERSION_BT709);
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp(argv[i], "--auto") == 0) {
|
||||
SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_AUTOMATIC);
|
||||
SetYUVConversionMode(YUV_CONVERSION_AUTOMATIC);
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp(argv[i], "--yv12") == 0) {
|
||||
yuv_format = SDL_PIXELFORMAT_YV12;
|
||||
@@ -379,7 +390,7 @@ int main(int argc, char **argv)
|
||||
|
||||
raw_yuv = SDL_calloc(1, MAX_YUV_SURFACE_SIZE(original->w, original->h, 0));
|
||||
ConvertRGBtoYUV(yuv_format, original->pixels, original->pitch, raw_yuv, original->w, original->h,
|
||||
SDL_GetYUVConversionModeForResolution(original->w, original->h),
|
||||
GetYUVConversionModeForResolution(original->w, original->h),
|
||||
0, 100);
|
||||
pitch = CalculateYUVPitch(yuv_format, original->w);
|
||||
|
||||
@@ -422,14 +433,14 @@ int main(int argc, char **argv)
|
||||
yuv_name += 16;
|
||||
}
|
||||
|
||||
switch (SDL_GetYUVConversionModeForResolution(original->w, original->h)) {
|
||||
case SDL_YUV_CONVERSION_JPEG:
|
||||
switch (GetYUVConversionModeForResolution(original->w, original->h)) {
|
||||
case YUV_CONVERSION_JPEG:
|
||||
yuv_mode = "JPEG";
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT601:
|
||||
case YUV_CONVERSION_BT601:
|
||||
yuv_mode = "BT.601";
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT709:
|
||||
case YUV_CONVERSION_BT709:
|
||||
yuv_mode = "BT.709";
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -14,14 +14,41 @@
|
||||
|
||||
#include "testyuv_cvt.h"
|
||||
|
||||
#define YUV_SD_THRESHOLD 576
|
||||
|
||||
static YUV_CONVERSION_MODE YUV_ConversionMode = YUV_CONVERSION_BT601;
|
||||
|
||||
void SetYUVConversionMode(YUV_CONVERSION_MODE mode)
|
||||
{
|
||||
YUV_ConversionMode = mode;
|
||||
}
|
||||
|
||||
YUV_CONVERSION_MODE GetYUVConversionMode(void)
|
||||
{
|
||||
return YUV_ConversionMode;
|
||||
}
|
||||
|
||||
YUV_CONVERSION_MODE GetYUVConversionModeForResolution(int width, int height)
|
||||
{
|
||||
YUV_CONVERSION_MODE mode = GetYUVConversionMode();
|
||||
if (mode == YUV_CONVERSION_AUTOMATIC) {
|
||||
if (height <= YUV_SD_THRESHOLD) {
|
||||
mode = YUV_CONVERSION_BT601;
|
||||
} else {
|
||||
mode = YUV_CONVERSION_BT709;
|
||||
}
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
static float clip3(float x, float y, float z)
|
||||
{
|
||||
return (z < x) ? x : ((z > y) ? y : z);
|
||||
}
|
||||
|
||||
static void RGBtoYUV(const Uint8 *rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
|
||||
static void RGBtoYUV(const Uint8 *rgb, int *yuv, YUV_CONVERSION_MODE mode, int monochrome, int luminance)
|
||||
{
|
||||
if (mode == SDL_YUV_CONVERSION_JPEG) {
|
||||
if (mode == YUV_CONVERSION_JPEG) {
|
||||
/* Full range YUV */
|
||||
yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]);
|
||||
yuv[1] = (int)((rgb[2] - yuv[0]) * 0.565 + 128);
|
||||
@@ -37,7 +64,7 @@ static void RGBtoYUV(const Uint8 *rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, i
|
||||
*/
|
||||
float S, Z, R, G, B, L, Kr, Kb, Y, U, V;
|
||||
|
||||
if (mode == SDL_YUV_CONVERSION_BT709) {
|
||||
if (mode == YUV_CONVERSION_BT709) {
|
||||
/* BT.709 */
|
||||
Kr = 0.2126f;
|
||||
Kb = 0.0722f;
|
||||
@@ -75,7 +102,7 @@ static void RGBtoYUV(const Uint8 *rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, i
|
||||
}
|
||||
}
|
||||
|
||||
static void ConvertRGBtoPlanar2x2(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
|
||||
static void ConvertRGBtoPlanar2x2(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, YUV_CONVERSION_MODE mode, int monochrome, int luminance)
|
||||
{
|
||||
int x, y;
|
||||
int yuv[4][3];
|
||||
@@ -191,7 +218,7 @@ static void ConvertRGBtoPlanar2x2(Uint32 format, Uint8 *src, int pitch, Uint8 *o
|
||||
}
|
||||
}
|
||||
|
||||
static void ConvertRGBtoPacked4(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
|
||||
static void ConvertRGBtoPacked4(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, YUV_CONVERSION_MODE mode, int monochrome, int luminance)
|
||||
{
|
||||
int x, y;
|
||||
int yuv[2][3];
|
||||
@@ -261,7 +288,7 @@ static void ConvertRGBtoPacked4(Uint32 format, Uint8 *src, int pitch, Uint8 *out
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
|
||||
SDL_bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, YUV_CONVERSION_MODE mode, int monochrome, int luminance)
|
||||
{
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
|
||||
@@ -12,5 +12,15 @@
|
||||
|
||||
/* These functions are designed for testing correctness, not for speed */
|
||||
|
||||
extern SDL_bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance);
|
||||
typedef enum
|
||||
{
|
||||
YUV_CONVERSION_JPEG, /**< Full range JPEG */
|
||||
YUV_CONVERSION_BT601, /**< BT.601 (the default) */
|
||||
YUV_CONVERSION_BT709, /**< BT.709 */
|
||||
YUV_CONVERSION_AUTOMATIC /**< BT.601 for SD content, BT.709 for HD content */
|
||||
} YUV_CONVERSION_MODE;
|
||||
|
||||
extern void SetYUVConversionMode(YUV_CONVERSION_MODE mode);
|
||||
extern YUV_CONVERSION_MODE GetYUVConversionModeForResolution(int width, int height);
|
||||
extern SDL_bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, YUV_CONVERSION_MODE mode, int monochrome, int luminance);
|
||||
extern int CalculateYUVPitch(Uint32 format, int width);
|
||||
|
||||
Reference in New Issue
Block a user