Revert "New SDL2 test files"

This reverts commit eafed06a29.
This commit is contained in:
mazmazz 2018-08-31 11:58:18 -04:00
parent af9e2365b9
commit 31d5735964
5 changed files with 0 additions and 893 deletions

View File

@ -1,122 +0,0 @@
cmake_minimum_required(VERSION 2.8.11)
project(SDL2 C)
# Global settings for all of the test targets
# FIXME: is this wrong?
remove_definitions(-DUSING_GENERATED_CONFIG_H)
link_libraries(SDL2_test SDL2-static)
# FIXME: Parent directory CMakeLists.txt only sets these for mingw/cygwin,
# but we need them for VS as well.
if(WINDOWS)
link_libraries(SDL2main)
add_definitions(-Dmain=SDL_main)
endif()
add_executable(checkkeys checkkeys.c)
add_executable(loopwave loopwave.c)
add_executable(loopwavequeue loopwavequeue.c)
add_executable(testresample testresample.c)
add_executable(testaudioinfo testaudioinfo.c)
file(GLOB TESTAUTOMATION_SOURCE_FILES testautomation*.c)
add_executable(testautomation ${TESTAUTOMATION_SOURCE_FILES})
add_executable(testmultiaudio testmultiaudio.c)
add_executable(testaudiohotplug testaudiohotplug.c)
add_executable(testaudiocapture testaudiocapture.c)
add_executable(testatomic testatomic.c)
add_executable(testintersections testintersections.c)
add_executable(testrelative testrelative.c)
add_executable(testhittesting testhittesting.c)
add_executable(testdraw2 testdraw2.c)
add_executable(testdrawchessboard testdrawchessboard.c)
add_executable(testdropfile testdropfile.c)
add_executable(testerror testerror.c)
add_executable(testfile testfile.c)
add_executable(testgamecontroller testgamecontroller.c)
add_executable(testgesture testgesture.c)
add_executable(testgl2 testgl2.c)
add_executable(testgles testgles.c)
add_executable(testgles2 testgles2.c)
add_executable(testhaptic testhaptic.c)
add_executable(testhotplug testhotplug.c)
add_executable(testrumble testrumble.c)
add_executable(testthread testthread.c)
add_executable(testiconv testiconv.c)
add_executable(testime testime.c)
add_executable(testjoystick testjoystick.c)
add_executable(testkeys testkeys.c)
add_executable(testloadso testloadso.c)
add_executable(testlock testlock.c)
if(APPLE)
add_executable(testnative testnative.c
testnativecocoa.m
testnativex11.c)
elseif(WINDOWS)
add_executable(testnative testnative.c testnativew32.c)
elseif(UNIX)
add_executable(testnative testnative.c testnativex11.c)
endif()
add_executable(testoverlay2 testoverlay2.c testyuv_cvt.c)
add_executable(testplatform testplatform.c)
add_executable(testpower testpower.c)
add_executable(testfilesystem testfilesystem.c)
add_executable(testrendertarget testrendertarget.c)
add_executable(testscale testscale.c)
add_executable(testsem testsem.c)
add_executable(testshader testshader.c)
add_executable(testshape testshape.c)
add_executable(testsprite2 testsprite2.c)
add_executable(testspriteminimal testspriteminimal.c)
add_executable(teststreaming teststreaming.c)
add_executable(testtimer testtimer.c)
add_executable(testver testver.c)
add_executable(testviewport testviewport.c)
add_executable(testwm2 testwm2.c)
add_executable(testyuv testyuv.c testyuv_cvt.c)
add_executable(torturethread torturethread.c)
add_executable(testrendercopyex testrendercopyex.c)
add_executable(testmessage testmessage.c)
add_executable(testdisplayinfo testdisplayinfo.c)
add_executable(testqsort testqsort.c)
add_executable(testbounds testbounds.c)
add_executable(testcustomcursor testcustomcursor.c)
add_executable(controllermap controllermap.c)
add_executable(testvulkan testvulkan.c)
# HACK: Dummy target to cause the resource files to be copied to the build directory.
# Need to make it an executable so we can use the TARGET_FILE_DIR generator expression.
# This is needed so they get copied to the correct Debug/Release subdirectory in Xcode.
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/resources_dummy.c "int main(int argc, const char **argv){ return 1; }\n")
add_executable(SDL2_test_resoureces ${CMAKE_CURRENT_BINARY_DIR}/resources_dummy.c)
file(GLOB RESOURCE_FILES *.bmp *.wav)
foreach(RESOURCE_FILE ${RESOURCE_FILES})
add_custom_command(TARGET SDL2_test_resoureces POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILE} $<TARGET_FILE_DIR:SDL2_test_resoureces>)
endforeach(RESOURCE_FILE)
file(COPY ${RESOURCE_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
# TODO: Might be easier to make all targets depend on the resources...?
add_dependencies(testscale SDL2_test_resoureces)
add_dependencies(testrendercopyex SDL2_test_resoureces)
add_dependencies(controllermap SDL2_test_resoureces)
add_dependencies(testyuv SDL2_test_resoureces)
add_dependencies(testgamecontroller SDL2_test_resoureces)
add_dependencies(testshape SDL2_test_resoureces)
add_dependencies(testshader SDL2_test_resoureces)
add_dependencies(testnative SDL2_test_resoureces)
add_dependencies(testspriteminimal SDL2_test_resoureces)
add_dependencies(testautomation SDL2_test_resoureces)
add_dependencies(testcustomcursor SDL2_test_resoureces)
add_dependencies(testrendertarget SDL2_test_resoureces)
add_dependencies(testsprite2 SDL2_test_resoureces)
add_dependencies(loopwave SDL2_test_resoureces)
add_dependencies(loopwavequeue SDL2_test_resoureces)
add_dependencies(testresample SDL2_test_resoureces)
add_dependencies(testaudiohotplug SDL2_test_resoureces)
add_dependencies(testmultiaudio SDL2_test_resoureces)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 KiB

View File

@ -1,455 +0,0 @@
/*
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL.h"
#include "SDL_test_font.h"
#include "testyuv_cvt.h"
/* 422 (YUY2, etc) formats are the largest */
#define MAX_YUV_SURFACE_SIZE(W, H, P) (H*4*(W+P+1)/2)
/* Return true if the YUV format is packed pixels */
static SDL_bool is_packed_yuv_format(Uint32 format)
{
return (format == SDL_PIXELFORMAT_YUY2 ||
format == SDL_PIXELFORMAT_UYVY ||
format == SDL_PIXELFORMAT_YVYU);
}
/* Create a surface with a good pattern for verifying YUV conversion */
static SDL_Surface *generate_test_pattern(int pattern_size)
{
SDL_Surface *pattern = SDL_CreateRGBSurfaceWithFormat(0, pattern_size, pattern_size, 0, SDL_PIXELFORMAT_RGB24);
if (pattern) {
int i, x, y;
Uint8 *p, c;
const int thickness = 2; /* Important so 2x2 blocks of color are the same, to avoid Cr/Cb interpolation over pixels */
/* R, G, B in alternating horizontal bands */
for (y = 0; y < pattern->h; y += thickness) {
for (i = 0; i < thickness; ++i) {
p = (Uint8 *)pattern->pixels + (y + i) * pattern->pitch + ((y/thickness) % 3);
for (x = 0; x < pattern->w; ++x) {
*p = 0xFF;
p += 3;
}
}
}
/* Black and white in alternating vertical bands */
c = 0xFF;
for (x = 1*thickness; x < pattern->w; x += 2*thickness) {
for (i = 0; i < thickness; ++i) {
p = (Uint8 *)pattern->pixels + (x + i)*3;
for (y = 0; y < pattern->h; ++y) {
SDL_memset(p, c, 3);
p += pattern->pitch;
}
}
if (c) {
c = 0x00;
} else {
c = 0xFF;
}
}
}
return pattern;
}
static SDL_bool verify_yuv_data(Uint32 format, const Uint8 *yuv, int yuv_pitch, SDL_Surface *surface)
{
const int tolerance = 20;
const int size = (surface->h * surface->pitch);
Uint8 *rgb;
SDL_bool result = SDL_FALSE;
rgb = (Uint8 *)SDL_malloc(size);
if (!rgb) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory");
return SDL_FALSE;
}
if (SDL_ConvertPixels(surface->w, surface->h, format, yuv, yuv_pitch, surface->format->format, rgb, surface->pitch) == 0) {
int x, y;
result = SDL_TRUE;
for (y = 0; y < surface->h; ++y) {
const Uint8 *actual = rgb + y * surface->pitch;
const Uint8 *expected = (const Uint8 *)surface->pixels + y * surface->pitch;
for (x = 0; x < surface->w; ++x) {
int deltaR = (int)actual[0] - expected[0];
int deltaG = (int)actual[1] - expected[1];
int deltaB = (int)actual[2] - expected[2];
int distance = (deltaR * deltaR + deltaG * deltaG + deltaB * deltaB);
if (distance > tolerance) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Pixel at %d,%d was 0x%.2x,0x%.2x,0x%.2x, expected 0x%.2x,0x%.2x,0x%.2x, distance = %d\n", x, y, actual[0], actual[1], actual[2], expected[0], expected[1], expected[2], distance);
result = SDL_FALSE;
}
actual += 3;
expected += 3;
}
}
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(format), SDL_GetPixelFormatName(surface->format->format), SDL_GetError());
}
SDL_free(rgb);
return result;
}
static int run_automated_tests(int pattern_size, int extra_pitch)
{
const Uint32 formats[] = {
SDL_PIXELFORMAT_YV12,
SDL_PIXELFORMAT_IYUV,
SDL_PIXELFORMAT_NV12,
SDL_PIXELFORMAT_NV21,
SDL_PIXELFORMAT_YUY2,
SDL_PIXELFORMAT_UYVY,
SDL_PIXELFORMAT_YVYU
};
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;
int result = -1;
if (!pattern || !yuv1 || !yuv2) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't allocate test surfaces");
goto done;
}
/* 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)) {
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)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to RGB\n", SDL_GetPixelFormatName(formats[i]));
goto done;
}
}
/* 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) {
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)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from RGB to %s\n", SDL_GetPixelFormatName(formats[i]));
goto done;
}
}
/* Verify conversion between YUV formats */
for (i = 0; i < SDL_arraysize(formats); ++i) {
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) {
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) {
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)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]));
goto done;
}
}
}
/* Verify conversion between YUV formats in-place */
for (i = 0; i < SDL_arraysize(formats); ++i) {
for (j = 0; j < SDL_arraysize(formats); ++j) {
if (is_packed_yuv_format(formats[i]) != is_packed_yuv_format(formats[j])) {
/* Can't change plane vs packed pixel layout in-place */
continue;
}
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) {
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) {
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)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]));
goto done;
}
}
}
result = 0;
done:
SDL_free(yuv1);
SDL_free(yuv2);
SDL_FreeSurface(pattern);
return result;
}
int
main(int argc, char **argv)
{
struct {
SDL_bool enable_intrinsics;
int pattern_size;
int extra_pitch;
} automated_test_params[] = {
/* Test: even width and height */
{ SDL_FALSE, 2, 0 },
{ SDL_FALSE, 4, 0 },
/* Test: odd width and height */
{ SDL_FALSE, 1, 0 },
{ SDL_FALSE, 3, 0 },
/* Test: even width and height, extra pitch */
{ SDL_FALSE, 2, 3 },
{ SDL_FALSE, 4, 3 },
/* Test: odd width and height, extra pitch */
{ SDL_FALSE, 1, 3 },
{ SDL_FALSE, 3, 3 },
/* Test: even width and height with intrinsics */
{ SDL_TRUE, 32, 0 },
/* Test: odd width and height with intrinsics */
{ SDL_TRUE, 33, 0 },
{ SDL_TRUE, 37, 0 },
/* Test: even width and height with intrinsics, extra pitch */
{ SDL_TRUE, 32, 3 },
/* Test: odd width and height with intrinsics, extra pitch */
{ SDL_TRUE, 33, 3 },
{ SDL_TRUE, 37, 3 },
};
int arg = 1;
const char *filename;
SDL_Surface *original;
SDL_Surface *converted;
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *output[3];
const char *titles[3] = { "ORIGINAL", "SOFTWARE", "HARDWARE" };
char title[128];
const char *yuv_name;
const char *yuv_mode;
Uint32 rgb_format = SDL_PIXELFORMAT_RGBX8888;
Uint32 yuv_format = SDL_PIXELFORMAT_YV12;
int current = 0;
int pitch;
Uint8 *raw_yuv;
Uint32 then, now, i, iterations = 100;
SDL_bool should_run_automated_tests = SDL_FALSE;
while (argv[arg] && *argv[arg] == '-') {
if (SDL_strcmp(argv[arg], "--jpeg") == 0) {
SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_JPEG);
} else if (SDL_strcmp(argv[arg], "--bt601") == 0) {
SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT601);
} else if (SDL_strcmp(argv[arg], "--bt709") == 0) {
SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT709);
} else if (SDL_strcmp(argv[arg], "--auto") == 0) {
SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_AUTOMATIC);
} else if (SDL_strcmp(argv[arg], "--yv12") == 0) {
yuv_format = SDL_PIXELFORMAT_YV12;
} else if (SDL_strcmp(argv[arg], "--iyuv") == 0) {
yuv_format = SDL_PIXELFORMAT_IYUV;
} else if (SDL_strcmp(argv[arg], "--yuy2") == 0) {
yuv_format = SDL_PIXELFORMAT_YUY2;
} else if (SDL_strcmp(argv[arg], "--uyvy") == 0) {
yuv_format = SDL_PIXELFORMAT_UYVY;
} else if (SDL_strcmp(argv[arg], "--yvyu") == 0) {
yuv_format = SDL_PIXELFORMAT_YVYU;
} else if (SDL_strcmp(argv[arg], "--nv12") == 0) {
yuv_format = SDL_PIXELFORMAT_NV12;
} else if (SDL_strcmp(argv[arg], "--nv21") == 0) {
yuv_format = SDL_PIXELFORMAT_NV21;
} else if (SDL_strcmp(argv[arg], "--rgb555") == 0) {
rgb_format = SDL_PIXELFORMAT_RGB555;
} else if (SDL_strcmp(argv[arg], "--rgb565") == 0) {
rgb_format = SDL_PIXELFORMAT_RGB565;
} else if (SDL_strcmp(argv[arg], "--rgb24") == 0) {
rgb_format = SDL_PIXELFORMAT_RGB24;
} else if (SDL_strcmp(argv[arg], "--argb") == 0) {
rgb_format = SDL_PIXELFORMAT_ARGB8888;
} else if (SDL_strcmp(argv[arg], "--abgr") == 0) {
rgb_format = SDL_PIXELFORMAT_ABGR8888;
} else if (SDL_strcmp(argv[arg], "--rgba") == 0) {
rgb_format = SDL_PIXELFORMAT_RGBA8888;
} else if (SDL_strcmp(argv[arg], "--bgra") == 0) {
rgb_format = SDL_PIXELFORMAT_BGRA8888;
} else if (SDL_strcmp(argv[arg], "--automated") == 0) {
should_run_automated_tests = SDL_TRUE;
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Usage: %s [--jpeg|--bt601|-bt709|--auto] [--yv12|--iyuv|--yuy2|--uyvy|--yvyu|--nv12|--nv21] [--rgb555|--rgb565|--rgb24|--argb|--abgr|--rgba|--bgra] [image_filename]\n", argv[0]);
return 1;
}
++arg;
}
/* Run automated tests */
if (should_run_automated_tests) {
for (i = 0; i < SDL_arraysize(automated_test_params); ++i) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Running automated test, pattern size %d, extra pitch %d, intrinsics %s\n",
automated_test_params[i].pattern_size,
automated_test_params[i].extra_pitch,
automated_test_params[i].enable_intrinsics ? "enabled" : "disabled");
if (run_automated_tests(automated_test_params[i].pattern_size, automated_test_params[i].extra_pitch) < 0) {
return 2;
}
}
return 0;
}
if (argv[arg]) {
filename = argv[arg];
} else {
filename = "testyuv.bmp";
}
original = SDL_ConvertSurfaceFormat(SDL_LoadBMP(filename), SDL_PIXELFORMAT_RGB24, 0);
if (!original) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
return 3;
}
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),
0, 100);
pitch = CalculateYUVPitch(yuv_format, original->w);
converted = SDL_CreateRGBSurfaceWithFormat(0, original->w, original->h, 0, rgb_format);
if (!converted) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create converted surface: %s\n", SDL_GetError());
return 3;
}
then = SDL_GetTicks();
for ( i = 0; i < iterations; ++i ) {
SDL_ConvertPixels(original->w, original->h, yuv_format, raw_yuv, pitch, rgb_format, converted->pixels, converted->pitch);
}
now = SDL_GetTicks();
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "%d iterations in %d ms, %.2fms each\n", iterations, (now - then), (float)(now - then)/iterations);
window = SDL_CreateWindow("YUV test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
original->w, original->h,
0);
if (!window) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
return 4;
}
renderer = SDL_CreateRenderer(window, -1, 0);
if (!renderer) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
return 4;
}
output[0] = SDL_CreateTextureFromSurface(renderer, original);
output[1] = SDL_CreateTextureFromSurface(renderer, converted);
output[2] = SDL_CreateTexture(renderer, yuv_format, SDL_TEXTUREACCESS_STREAMING, original->w, original->h);
if (!output[0] || !output[1] || !output[2]) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError());
return 5;
}
SDL_UpdateTexture(output[2], NULL, raw_yuv, pitch);
yuv_name = SDL_GetPixelFormatName(yuv_format);
if (SDL_strncmp(yuv_name, "SDL_PIXELFORMAT_", 16) == 0) {
yuv_name += 16;
}
switch (SDL_GetYUVConversionModeForResolution(original->w, original->h)) {
case SDL_YUV_CONVERSION_JPEG:
yuv_mode = "JPEG";
break;
case SDL_YUV_CONVERSION_BT601:
yuv_mode = "BT.601";
break;
case SDL_YUV_CONVERSION_BT709:
yuv_mode = "BT.709";
break;
default:
yuv_mode = "UNKNOWN";
break;
}
{ int done = 0;
while ( !done )
{
SDL_Event event;
while (SDL_PollEvent(&event) > 0) {
if (event.type == SDL_QUIT) {
done = 1;
}
if (event.type == SDL_KEYDOWN) {
if (event.key.keysym.sym == SDLK_ESCAPE) {
done = 1;
} else if (event.key.keysym.sym == SDLK_LEFT) {
--current;
} else if (event.key.keysym.sym == SDLK_RIGHT) {
++current;
}
}
if (event.type == SDL_MOUSEBUTTONDOWN) {
if (event.button.x < (original->w/2)) {
--current;
} else {
++current;
}
}
}
/* Handle wrapping */
if (current < 0) {
current += SDL_arraysize(output);
}
if (current >= SDL_arraysize(output)) {
current -= SDL_arraysize(output);
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, output[current], NULL, NULL);
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
if (current == 0) {
SDLTest_DrawString(renderer, 4, 4, titles[current]);
} else {
SDL_snprintf(title, sizeof(title), "%s %s %s", titles[current], yuv_name, yuv_mode);
SDLTest_DrawString(renderer, 4, 4, title);
}
SDL_RenderPresent(renderer);
SDL_Delay(10);
}
}
SDL_Quit();
return 0;
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,300 +0,0 @@
/*
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
#include "SDL.h"
#include "testyuv_cvt.h"
static float clip3(float x, float y, float z)
{
return ((z < x) ? x : ((z > y) ? y : z));
}
static void RGBtoYUV(Uint8 * rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
{
if (mode == SDL_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);
yuv[2] = (int)((rgb[0] - yuv[0]) * 0.713 + 128);
} else {
// This formula is from Microsoft's documentation:
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx
// L = Kr * R + Kb * B + (1 - Kr - Kb) * G
// Y = floor(2^(M-8) * (219*(L-Z)/S + 16) + 0.5);
// U = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(B-L) / ((1-Kb)*S) + 128) + 0.5));
// V = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(R-L) / ((1-Kr)*S) + 128) + 0.5));
float S, Z, R, G, B, L, Kr, Kb, Y, U, V;
if (mode == SDL_YUV_CONVERSION_BT709) {
/* BT.709 */
Kr = 0.2126f;
Kb = 0.0722f;
} else {
/* BT.601 */
Kr = 0.299f;
Kb = 0.114f;
}
S = 255.0f;
Z = 0.0f;
R = rgb[0];
G = rgb[1];
B = rgb[2];
L = Kr * R + Kb * B + (1 - Kr - Kb) * G;
Y = (Uint8)SDL_floorf((219*(L-Z)/S + 16) + 0.5f);
U = (Uint8)clip3(0, 255, SDL_floorf((112.0f*(B-L) / ((1.0f-Kb)*S) + 128) + 0.5f));
V = (Uint8)clip3(0, 255, SDL_floorf((112.0f*(R-L) / ((1.0f-Kr)*S) + 128) + 0.5f));
yuv[0] = (Uint8)Y;
yuv[1] = (Uint8)U;
yuv[2] = (Uint8)V;
}
if (monochrome) {
yuv[1] = 128;
yuv[2] = 128;
}
if (luminance != 100) {
yuv[0] = yuv[0] * luminance / 100;
if (yuv[0] > 255)
yuv[0] = 255;
}
}
static void ConvertRGBtoPlanar2x2(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
{
int x, y;
int yuv[4][3];
Uint8 *Y1, *Y2, *U, *V;
Uint8 *rgb1, *rgb2;
int rgb_row_advance = (pitch - w*3) + pitch;
int UV_advance;
rgb1 = src;
rgb2 = src + pitch;
Y1 = out;
Y2 = Y1 + w;
switch (format) {
case SDL_PIXELFORMAT_YV12:
V = (Y1 + h * w);
U = V + ((h + 1)/2)*((w + 1)/2);
UV_advance = 1;
break;
case SDL_PIXELFORMAT_IYUV:
U = (Y1 + h * w);
V = U + ((h + 1)/2)*((w + 1)/2);
UV_advance = 1;
break;
case SDL_PIXELFORMAT_NV12:
U = (Y1 + h * w);
V = U + 1;
UV_advance = 2;
break;
case SDL_PIXELFORMAT_NV21:
V = (Y1 + h * w);
U = V + 1;
UV_advance = 2;
break;
default:
SDL_assert(!"Unsupported planar YUV format");
return;
}
for (y = 0; y < (h - 1); y += 2) {
for (x = 0; x < (w - 1); x += 2) {
RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
rgb1 += 3;
*Y1++ = (Uint8)yuv[0][0];
RGBtoYUV(rgb1, yuv[1], mode, monochrome, luminance);
rgb1 += 3;
*Y1++ = (Uint8)yuv[1][0];
RGBtoYUV(rgb2, yuv[2], mode, monochrome, luminance);
rgb2 += 3;
*Y2++ = (Uint8)yuv[2][0];
RGBtoYUV(rgb2, yuv[3], mode, monochrome, luminance);
rgb2 += 3;
*Y2++ = (Uint8)yuv[3][0];
*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;
}
/* Last column */
if (x == (w - 1)) {
RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
rgb1 += 3;
*Y1++ = (Uint8)yuv[0][0];
RGBtoYUV(rgb2, yuv[2], mode, monochrome, luminance);
rgb2 += 3;
*Y2++ = (Uint8)yuv[2][0];
*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;
}
Y1 += w;
Y2 += w;
rgb1 += rgb_row_advance;
rgb2 += rgb_row_advance;
}
/* Last row */
if (y == (h - 1)) {
for (x = 0; x < (w - 1); x += 2) {
RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
rgb1 += 3;
*Y1++ = (Uint8)yuv[0][0];
RGBtoYUV(rgb1, yuv[1], mode, monochrome, luminance);
rgb1 += 3;
*Y1++ = (Uint8)yuv[1][0];
*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;
}
/* Last column */
if (x == (w - 1)) {
RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance);
*Y1++ = (Uint8)yuv[0][0];
*U = (Uint8)yuv[0][1];
U += UV_advance;
*V = (Uint8)yuv[0][2];
V += UV_advance;
}
}
}
static void ConvertRGBtoPacked4(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
{
int x, y;
int yuv[2][3];
Uint8 *Y1, *Y2, *U, *V;
Uint8 *rgb;
int rgb_row_advance = (pitch - w*3);
rgb = src;
switch (format) {
case SDL_PIXELFORMAT_YUY2:
Y1 = out;
U = out+1;
Y2 = out+2;
V = out+3;
break;
case SDL_PIXELFORMAT_UYVY:
U = out;
Y1 = out+1;
V = out+2;
Y2 = out+3;
break;
case SDL_PIXELFORMAT_YVYU:
Y1 = out;
V = out+1;
Y2 = out+2;
U = out+3;
break;
default:
SDL_assert(!"Unsupported packed YUV format");
return;
}
for (y = 0; y < h; ++y) {
for (x = 0; x < (w - 1); x += 2) {
RGBtoYUV(rgb, yuv[0], mode, monochrome, luminance);
rgb += 3;
*Y1 = (Uint8)yuv[0][0];
Y1 += 4;
RGBtoYUV(rgb, yuv[1], mode, monochrome, luminance);
rgb += 3;
*Y2 = (Uint8)yuv[1][0];
Y2 += 4;
*U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1])/2.0f + 0.5f);
U += 4;
*V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2])/2.0f + 0.5f);
V += 4;
}
/* Last column */
if (x == (w - 1)) {
RGBtoYUV(rgb, yuv[0], mode, monochrome, luminance);
rgb += 3;
*Y2 = *Y1 = (Uint8)yuv[0][0];
Y1 += 4;
Y2 += 4;
*U = (Uint8)yuv[0][1];
U += 4;
*V = (Uint8)yuv[0][2];
V += 4;
}
rgb += rgb_row_advance;
}
}
SDL_bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance)
{
switch (format)
{
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_NV12:
case SDL_PIXELFORMAT_NV21:
ConvertRGBtoPlanar2x2(format, src, pitch, out, w, h, mode, monochrome, luminance);
return SDL_TRUE;
case SDL_PIXELFORMAT_YUY2:
case SDL_PIXELFORMAT_UYVY:
case SDL_PIXELFORMAT_YVYU:
ConvertRGBtoPacked4(format, src, pitch, out, w, h, mode, monochrome, luminance);
return SDL_TRUE;
default:
return SDL_FALSE;
}
}
int CalculateYUVPitch(Uint32 format, int width)
{
switch (format)
{
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_NV12:
case SDL_PIXELFORMAT_NV21:
return width;
case SDL_PIXELFORMAT_YUY2:
case SDL_PIXELFORMAT_UYVY:
case SDL_PIXELFORMAT_YVYU:
return 4*((width + 1)/2);
default:
return 0;
}
}
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -1,16 +0,0 @@
/*
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
/* 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);
extern int CalculateYUVPitch(Uint32 format, int width);