mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-09-17 02:32:04 +00:00
testyuv: verify the YUV surface locking path
Also implemented YUV surface locking for Vulkan
This commit is contained in:
@@ -73,12 +73,13 @@ SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(SDL_PixelFormat format, SDL_Colorspac
|
||||
}
|
||||
|
||||
// Find the pitch and offset values for the texture
|
||||
const int bpp = SDL_BYTESPERPIXEL(format);
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
swdata->pitches[0] = w * SDL_BYTESPERPIXEL(format);
|
||||
swdata->pitches[1] = ((w + 1) / 2) * SDL_BYTESPERPIXEL(format);
|
||||
swdata->pitches[0] = w * bpp;
|
||||
swdata->pitches[1] = (((swdata->pitches[0] / bpp) + 1) / 2) * bpp;
|
||||
swdata->pitches[2] = swdata->pitches[1];
|
||||
swdata->planes[0] = swdata->pixels;
|
||||
swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
|
||||
@@ -86,7 +87,7 @@ SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(SDL_PixelFormat format, SDL_Colorspac
|
||||
break;
|
||||
case SDL_PIXELFORMAT_I444:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
swdata->pitches[0] = w * SDL_BYTESPERPIXEL(format);
|
||||
swdata->pitches[0] = w * bpp;
|
||||
swdata->pitches[1] = swdata->pitches[0];
|
||||
swdata->pitches[2] = swdata->pitches[1];
|
||||
swdata->planes[0] = swdata->pixels;
|
||||
@@ -127,6 +128,8 @@ bool SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture *swdata, void **pixels,
|
||||
bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
const void *pixels, int pitch)
|
||||
{
|
||||
const int bpp = SDL_BYTESPERPIXEL(swdata->format);
|
||||
|
||||
switch (swdata->format) {
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
@@ -134,17 +137,16 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
if (rect->x == 0 && rect->y == 0 &&
|
||||
rect->w == swdata->w && rect->h == swdata->h && pitch == swdata->pitches[0]) {
|
||||
SDL_memcpy(swdata->pixels, pixels,
|
||||
(size_t)(swdata->h * swdata->w) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2));
|
||||
(size_t)(swdata->h * swdata->w * bpp) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2) * bpp);
|
||||
} else {
|
||||
Uint8 *src, *dst;
|
||||
int row;
|
||||
size_t length;
|
||||
const int bpp = SDL_BYTESPERPIXEL(swdata->format);
|
||||
const int UVpitch = ((pitch / bpp + 1) / 2) * bpp;
|
||||
|
||||
// Copy the Y plane
|
||||
src = (Uint8 *)pixels;
|
||||
dst = swdata->pixels + rect->y * swdata->w + rect->x;
|
||||
dst = swdata->pixels + rect->y * swdata->w * bpp + rect->x * bpp;
|
||||
length = rect->w * bpp;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
@@ -154,8 +156,8 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
|
||||
// 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;
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0];
|
||||
dst += (rect->y / 2) * swdata->pitches[1] + (rect->x / 2) * bpp;
|
||||
length = ((rect->w + 1) / 2) * bpp;
|
||||
for (row = 0; row < (rect->h + 1) / 2; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
@@ -165,9 +167,8 @@ bool SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
|
||||
// Copy the next plane
|
||||
src = (Uint8 *)pixels + rect->h * pitch + ((rect->h + 1) / 2) * UVpitch;
|
||||
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;
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0] + ((rect->h + 1) / 2) * swdata->pitches[1];
|
||||
dst += (rect->y / 2) * swdata->pitches[2] + (rect->x / 2) * bpp;
|
||||
length = ((rect->w + 1) / 2) * bpp;
|
||||
for (row = 0; row < (rect->h + 1) / 2; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
@@ -185,12 +186,11 @@ 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;
|
||||
dst += rect->y * swdata->pitches[0] + rect->x *bpp;
|
||||
dst += rect->y * swdata->pitches[0] + rect->x * bpp;
|
||||
length = rect->w * bpp;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
@@ -403,7 +403,7 @@ bool SDL_SW_LockYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Unsupported YUV format");
|
||||
break;
|
||||
}
|
||||
|
||||
if (rect) {
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "../SDL_d3dmath.h"
|
||||
#include "../../video/SDL_pixels_c.h"
|
||||
#include "../../video/SDL_yuv_c.h"
|
||||
#include "SDL_shaders_vulkan.h"
|
||||
|
||||
#define SET_ERROR_CODE(message, rc) \
|
||||
@@ -267,6 +268,8 @@ typedef struct
|
||||
// Pipeline layout with immutable sampler descriptor set layout
|
||||
VkPipelineLayout pipelineLayoutYcbcr;
|
||||
|
||||
Uint8 *pixels;
|
||||
int pitch;
|
||||
} VULKAN_TextureData;
|
||||
|
||||
// Pipeline State Object data
|
||||
@@ -2872,6 +2875,7 @@ static void VULKAN_DestroyTexture(SDL_Renderer *renderer,
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(textureData->pixels);
|
||||
SDL_free(textureData);
|
||||
texture->internal = NULL;
|
||||
}
|
||||
@@ -3105,6 +3109,28 @@ static bool VULKAN_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
return SDL_SetError("texture is already locked");
|
||||
}
|
||||
|
||||
bool yuv = (textureData->descriptorSetLayoutYcbcr != VK_NULL_HANDLE);
|
||||
if (yuv) {
|
||||
// It's more efficient to upload directly...
|
||||
if (!textureData->pixels) {
|
||||
size_t size, calculated_pitch;
|
||||
if (!SDL_CalculateYUVSize(texture->format, texture->w, texture->h, &size, &calculated_pitch)) {
|
||||
return false;
|
||||
}
|
||||
textureData->pitch = (int)calculated_pitch;
|
||||
textureData->pixels = (Uint8 *)SDL_malloc(size);
|
||||
if (!textureData->pixels) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
textureData->lockedRect = *rect;
|
||||
*pixels =
|
||||
(void *)(textureData->pixels + rect->y * textureData->pitch +
|
||||
rect->x * SDL_BYTESPERPIXEL(texture->format));
|
||||
*pitch = textureData->pitch;
|
||||
return true;
|
||||
}
|
||||
|
||||
VkDeviceSize pixelSize = VULKAN_GetBytesPerPixel(textureData->mainImage.format, 0);
|
||||
VkDeviceSize length = rect->w * pixelSize;
|
||||
VkDeviceSize stagingBufferSize = length * rect->h;
|
||||
@@ -3142,6 +3168,15 @@ static void VULKAN_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
return;
|
||||
}
|
||||
|
||||
bool yuv = (textureData->descriptorSetLayoutYcbcr != VK_NULL_HANDLE);
|
||||
if (yuv) {
|
||||
const SDL_Rect *rect = &textureData->lockedRect;
|
||||
const Uint8 *pixels = textureData->pixels + rect->y * textureData->pitch + rect->x * SDL_BYTESPERPIXEL(texture->format);
|
||||
|
||||
VULKAN_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch);
|
||||
return;
|
||||
}
|
||||
|
||||
VULKAN_EnsureCommandBuffer(rendererData);
|
||||
|
||||
// Make sure the destination is in the correct resource state
|
||||
|
||||
299
test/testyuv.c
299
test/testyuv.c
@@ -373,7 +373,266 @@ done:
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool create_textures(SDL_Renderer *renderer, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool monochrome, int luminance, SDL_Texture *output[3])
|
||||
// Copied from SDL_yuv_sw.c to verify functionality
|
||||
|
||||
struct SW_YUVTexture
|
||||
{
|
||||
SDL_PixelFormat format;
|
||||
int w, h;
|
||||
Uint8 *pixels;
|
||||
int pitches[3];
|
||||
Uint8 *planes[3];
|
||||
};
|
||||
|
||||
typedef struct SW_YUVTexture SW_YUVTexture;
|
||||
|
||||
static SW_YUVTexture *SW_CreateYUVTexture(SDL_PixelFormat format, int w, int h, void *pixels, int pitch)
|
||||
{
|
||||
SW_YUVTexture *swdata;
|
||||
|
||||
switch (format) {
|
||||
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:
|
||||
case SDL_PIXELFORMAT_YVYU:
|
||||
case SDL_PIXELFORMAT_NV12:
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("Unsupported YUV format");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
swdata = (SW_YUVTexture *)SDL_calloc(1, sizeof(*swdata));
|
||||
if (!swdata) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
swdata->format = format;
|
||||
swdata->w = w;
|
||||
swdata->h = h;
|
||||
swdata->pixels = (Uint8 *)pixels;
|
||||
|
||||
// Find the pitch and offset values for the texture
|
||||
const int bpp = SDL_BYTESPERPIXEL(format);
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_I0FL:
|
||||
swdata->pitches[0] = pitch;
|
||||
swdata->pitches[1] = (((swdata->pitches[0] / bpp) + 1) / 2) * bpp;
|
||||
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);
|
||||
break;
|
||||
case SDL_PIXELFORMAT_I444:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
swdata->pitches[0] = w * bpp;
|
||||
swdata->pitches[1] = swdata->pitches[0];
|
||||
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;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_YUY2:
|
||||
case SDL_PIXELFORMAT_UYVY:
|
||||
case SDL_PIXELFORMAT_YVYU:
|
||||
swdata->pitches[0] = ((w + 1) / 2) * 4;
|
||||
swdata->planes[0] = swdata->pixels;
|
||||
break;
|
||||
case SDL_PIXELFORMAT_NV12:
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
swdata->pitches[0] = w;
|
||||
swdata->pitches[1] = 2 * ((swdata->pitches[0] + 1) / 2);
|
||||
swdata->planes[0] = swdata->pixels;
|
||||
swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
|
||||
break;
|
||||
|
||||
default:
|
||||
SDL_assert(!"We should never get here (caught above)");
|
||||
break;
|
||||
}
|
||||
|
||||
// We're all done..
|
||||
return swdata;
|
||||
}
|
||||
|
||||
static bool SW_UpdateYUVTexture(SW_YUVTexture *swdata, const SDL_Rect *rect, const void *pixels, int pitch)
|
||||
{
|
||||
const int bpp = SDL_BYTESPERPIXEL(swdata->format);
|
||||
|
||||
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,
|
||||
(size_t)(swdata->h * swdata->w * bpp) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2) * bpp);
|
||||
} else {
|
||||
Uint8 *src, *dst;
|
||||
int row;
|
||||
size_t length;
|
||||
const int UVpitch = ((pitch / bpp + 1) / 2) * bpp;
|
||||
|
||||
// Copy the Y plane
|
||||
src = (Uint8 *)pixels;
|
||||
dst = swdata->pixels + rect->y * swdata->w * bpp + rect->x * bpp;
|
||||
length = rect->w * bpp;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
dst += swdata->pitches[0];
|
||||
}
|
||||
|
||||
// Copy the next plane
|
||||
src = (Uint8 *)pixels + rect->h * pitch;
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0];
|
||||
dst += (rect->y / 2) * swdata->pitches[1] + (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 += UVpitch;
|
||||
dst += swdata->pitches[1];
|
||||
}
|
||||
|
||||
// Copy the next plane
|
||||
src = (Uint8 *)pixels + rect->h * pitch + ((rect->h + 1) / 2) * UVpitch;
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0] + ((rect->h + 1) / 2) * swdata->pitches[1];
|
||||
dst += (rect->y / 2) * swdata->pitches[2] + (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 += UVpitch;
|
||||
dst += swdata->pitches[2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_PIXELFORMAT_I444:
|
||||
case SDL_PIXELFORMAT_I4FL:
|
||||
if (rect->x == 0 && rect->y == 0 &&
|
||||
rect->w == swdata->w && rect->h == swdata->h && pitch == swdata->pitches[0]) {
|
||||
SDL_memcpy(swdata->pixels, pixels, (size_t)(swdata->h * pitch * 3));
|
||||
} else {
|
||||
Uint8 *src, *dst;
|
||||
int row;
|
||||
size_t length;
|
||||
|
||||
// Copy the Y plane
|
||||
src = (Uint8 *)pixels;
|
||||
dst = swdata->pixels;
|
||||
dst += rect->y * swdata->pitches[0] + rect->x * bpp;
|
||||
length = rect->w * bpp;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
dst += swdata->pitches[0];
|
||||
}
|
||||
|
||||
// Copy the next plane
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0];
|
||||
dst += rect->y * swdata->pitches[1] + rect->x * bpp;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
dst += swdata->pitches[1];
|
||||
}
|
||||
|
||||
// Copy the next plane
|
||||
dst = swdata->pixels + swdata->h * swdata->pitches[0] + swdata->h * swdata->pitches[1];
|
||||
dst += rect->y * swdata->pitches[2] + rect->x * bpp;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
dst += swdata->pitches[2];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SDL_PIXELFORMAT_YUY2:
|
||||
case SDL_PIXELFORMAT_UYVY:
|
||||
case SDL_PIXELFORMAT_YVYU:
|
||||
{
|
||||
Uint8 *src, *dst;
|
||||
int row;
|
||||
size_t length;
|
||||
|
||||
src = (Uint8 *)pixels;
|
||||
dst =
|
||||
swdata->planes[0] + rect->y * swdata->pitches[0] +
|
||||
rect->x * 2;
|
||||
length = 4 * (((size_t)rect->w + 1) / 2);
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
dst += swdata->pitches[0];
|
||||
}
|
||||
} break;
|
||||
case SDL_PIXELFORMAT_NV12:
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
{
|
||||
if (rect->x == 0 && rect->y == 0 && rect->w == swdata->w && rect->h == swdata->h) {
|
||||
SDL_memcpy(swdata->pixels, pixels,
|
||||
(size_t)(swdata->h * swdata->w) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2));
|
||||
} else {
|
||||
|
||||
Uint8 *src, *dst;
|
||||
int row;
|
||||
size_t length;
|
||||
|
||||
// Copy the Y plane
|
||||
src = (Uint8 *)pixels;
|
||||
dst = swdata->pixels + rect->y * swdata->w + rect->x;
|
||||
length = rect->w;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
dst += swdata->w;
|
||||
}
|
||||
|
||||
// Copy the next plane
|
||||
src = (Uint8 *)pixels + rect->h * pitch;
|
||||
dst = swdata->pixels + swdata->h * swdata->w;
|
||||
dst += 2 * ((rect->y + 1) / 2) * ((swdata->w + 1) / 2) + 2 * (rect->x / 2);
|
||||
length = 2 * (((size_t)rect->w + 1) / 2);
|
||||
for (row = 0; row < (rect->h + 1) / 2; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += 2 * ((pitch + 1) / 2);
|
||||
dst += 2 * ((swdata->w + 1) / 2);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
return SDL_SetError("Unsupported YUV format");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SW_DestroyYUVTexture(SW_YUVTexture *swdata)
|
||||
{
|
||||
if (swdata) {
|
||||
SDL_free(swdata);
|
||||
}
|
||||
}
|
||||
|
||||
static bool update_locked_texture(SDL_PixelFormat format, int w, int h, const void *pixels, int pitch, void *output_pixels, int output_pitch)
|
||||
{
|
||||
SW_YUVTexture *swdata = SW_CreateYUVTexture(format, w, h, output_pixels, output_pitch);
|
||||
if (!swdata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_Rect rect = { 0, 0, w, h };
|
||||
bool result = SW_UpdateYUVTexture(swdata, &rect, pixels, pitch);
|
||||
SW_DestroyYUVTexture(swdata);
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool create_textures(SDL_Renderer *renderer, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool lock, bool monochrome, int luminance, SDL_Texture *output[3])
|
||||
{
|
||||
SDL_Colorspace rgb_colorspace = SDL_COLORSPACE_SRGB;
|
||||
SDL_Colorspace yuv_colorspace;
|
||||
@@ -556,6 +815,19 @@ static bool create_textures(SDL_Renderer *renderer, SDL_Surface *original, SDL_P
|
||||
SDL_UpdateNVTexture(output[2], NULL, plane0, Ypitch, plane1, UVpitch);
|
||||
SDL_free(plane0);
|
||||
SDL_free(plane1);
|
||||
} else if (lock) {
|
||||
void *dst;
|
||||
int dst_pitch;
|
||||
if (!SDL_LockTexture(output[2], NULL, &dst, &dst_pitch)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock YUV texture: %s", SDL_GetError());
|
||||
goto done;
|
||||
}
|
||||
bool updated = update_locked_texture(yuv_format, original->w, original->h, raw_yuv, pitch, dst, dst_pitch);
|
||||
SDL_UnlockTexture(output[2]);
|
||||
if (!updated) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't update YUV texture: %s", SDL_GetError());
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
SDL_UpdateTexture(output[2], NULL, raw_yuv, pitch);
|
||||
}
|
||||
@@ -610,12 +882,12 @@ static bool check_output(SDL_Renderer *renderer, SDL_Surface *original, SDL_Text
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool run_single_format_test(SDL_Renderer *renderer, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar)
|
||||
static bool run_single_format_test(SDL_Renderer *renderer, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool lock)
|
||||
{
|
||||
SDL_Texture *output[3];
|
||||
bool result = true;
|
||||
|
||||
if (!create_textures(renderer, original, yuv_format, rgb_format, planar, false, 100, output)) {
|
||||
if (!create_textures(renderer, original, yuv_format, rgb_format, planar, lock, false, 100, output)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -668,7 +940,7 @@ static bool run_all_format_test(SDL_Window *window, const char *requested_render
|
||||
{ YUV_CONVERSION_JPEG, "JPEG" },
|
||||
{ YUV_CONVERSION_BT601, "BT601" },
|
||||
{ YUV_CONVERSION_BT709, "BT709" },
|
||||
{ YUV_CONVERSION_BT2020, "BT2020" }
|
||||
//{ YUV_CONVERSION_BT2020, "BT2020" }
|
||||
};
|
||||
bool quit = false;
|
||||
bool result = true;
|
||||
@@ -700,10 +972,13 @@ static bool run_all_format_test(SDL_Window *window, const char *requested_render
|
||||
SDL_PixelFormat rgb_format = rgb_formats[n];
|
||||
|
||||
SDL_Log("Testing: %s %s %s %s (planar)", renderer_name, colorspaces[j].name, SDL_GetPixelFormatName(yuv_format), SDL_GetPixelFormatName(rgb_format));
|
||||
result &= run_single_format_test(renderer, original, yuv_format, rgb_format, true);
|
||||
result &= run_single_format_test(renderer, original, yuv_format, rgb_format, true, false);
|
||||
|
||||
SDL_Log("Testing: %s %s %s %s (packed)", renderer_name, colorspaces[j].name, SDL_GetPixelFormatName(yuv_format), SDL_GetPixelFormatName(rgb_format));
|
||||
result &= run_single_format_test(renderer, original, yuv_format, rgb_format, false);
|
||||
result &= run_single_format_test(renderer, original, yuv_format, rgb_format, false, false);
|
||||
|
||||
SDL_Log("Testing: %s %s %s %s (locked)", renderer_name, colorspaces[j].name, SDL_GetPixelFormatName(yuv_format), SDL_GetPixelFormatName(rgb_format));
|
||||
result &= run_single_format_test(renderer, original, yuv_format, rgb_format, false, true);
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
@@ -720,7 +995,7 @@ static bool run_all_format_test(SDL_Window *window, const char *requested_render
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool run_interactive(SDL_Window *window, const char *renderer_name, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool monochrome, int luminance)
|
||||
static bool run_interactive(SDL_Window *window, const char *renderer_name, SDL_Surface *original, SDL_PixelFormat yuv_format, SDL_PixelFormat rgb_format, bool planar, bool lock, bool monochrome, int luminance)
|
||||
{
|
||||
const char *titles[3] = { "ORIGINAL", "SOFTWARE", "HARDWARE" };
|
||||
char title[128];
|
||||
@@ -739,7 +1014,7 @@ static bool run_interactive(SDL_Window *window, const char *renderer_name, SDL_S
|
||||
renderer_name = SDL_GetRendererName(renderer);
|
||||
|
||||
SDL_Texture *output[3];
|
||||
if (!create_textures(renderer, original, yuv_format, rgb_format, planar, monochrome, luminance, output)) {
|
||||
if (!create_textures(renderer, original, yuv_format, rgb_format, planar, lock, monochrome, luminance, output)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -865,6 +1140,7 @@ int main(int argc, char **argv)
|
||||
Uint32 yuv_format = SDL_PIXELFORMAT_YV12;
|
||||
Uint32 rgb_format = SDL_PIXELFORMAT_RGBX8888;
|
||||
bool planar = false;
|
||||
bool lock = false;
|
||||
bool monochrome = false;
|
||||
int luminance = 100;
|
||||
int i;
|
||||
@@ -964,6 +1240,9 @@ int main(int argc, char **argv)
|
||||
} else if (SDL_strcmp(argv[i], "--planar") == 0) {
|
||||
planar = true;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp(argv[i], "--lock") == 0) {
|
||||
lock = true;
|
||||
consumed = 1;
|
||||
} else if (SDL_strcmp(argv[i], "--monochrome") == 0) {
|
||||
monochrome = true;
|
||||
consumed = 1;
|
||||
@@ -989,7 +1268,7 @@ int main(int argc, char **argv)
|
||||
"[--jpeg|--bt601|--bt709|--auto]",
|
||||
"[--yv12|--iyuv|--i444|--yuy2|--uyvy|--yvyu|--nv12|--nv21|--p010|--i4fl]",
|
||||
"[--rgb555|--rgb565|--rgb24|--argb|--abgr|--rgba|--bgra]",
|
||||
"[--monochrome] [--luminance N%] [--planar]",
|
||||
"[--monochrome] [--luminance N%] [--planar] [--lock]",
|
||||
"[--automated] [--colorspace-test] [--renderer NAME]",
|
||||
"[sample.png]",
|
||||
NULL,
|
||||
@@ -1047,7 +1326,7 @@ int main(int argc, char **argv)
|
||||
result = 5;
|
||||
}
|
||||
} else {
|
||||
if (!run_interactive(window, renderer_name, original, yuv_format, rgb_format, planar, monochrome, luminance)) {
|
||||
if (!run_interactive(window, renderer_name, original, yuv_format, rgb_format, planar, lock, monochrome, luminance)) {
|
||||
result = 5;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user