1 | /* |
2 | Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org> |
3 | |
4 | This software is provided 'as-is', without any express or implied |
5 | warranty. In no event will the authors be held liable for any damages |
6 | arising from the use of this software. |
7 | |
8 | Permission is granted to anyone to use this software for any purpose, |
9 | including commercial applications, and to alter it and redistribute it |
10 | freely. |
11 | */ |
12 | #include <stdlib.h> |
13 | #include <stdio.h> |
14 | #include <string.h> |
15 | |
16 | #include "SDL.h" |
17 | #include "SDL_test_font.h" |
18 | #include "testyuv_cvt.h" |
19 | |
20 | |
21 | /* 422 (YUY2, etc) formats are the largest */ |
22 | #define MAX_YUV_SURFACE_SIZE(W, H, P) (H*4*(W+P+1)/2) |
23 | |
24 | |
25 | /* Return true if the YUV format is packed pixels */ |
26 | static SDL_bool is_packed_yuv_format(Uint32 format) |
27 | { |
28 | return (format == SDL_PIXELFORMAT_YUY2 || |
29 | format == SDL_PIXELFORMAT_UYVY || |
30 | format == SDL_PIXELFORMAT_YVYU); |
31 | } |
32 | |
33 | /* Create a surface with a good pattern for verifying YUV conversion */ |
34 | static SDL_Surface *generate_test_pattern(int pattern_size) |
35 | { |
36 | SDL_Surface *pattern = SDL_CreateRGBSurfaceWithFormat(0, pattern_size, pattern_size, 0, SDL_PIXELFORMAT_RGB24); |
37 | |
38 | if (pattern) { |
39 | int i, x, y; |
40 | Uint8 *p, c; |
41 | const int thickness = 2; /* Important so 2x2 blocks of color are the same, to avoid Cr/Cb interpolation over pixels */ |
42 | |
43 | /* R, G, B in alternating horizontal bands */ |
44 | for (y = 0; y < pattern->h; y += thickness) { |
45 | for (i = 0; i < thickness; ++i) { |
46 | p = (Uint8 *)pattern->pixels + (y + i) * pattern->pitch + ((y/thickness) % 3); |
47 | for (x = 0; x < pattern->w; ++x) { |
48 | *p = 0xFF; |
49 | p += 3; |
50 | } |
51 | } |
52 | } |
53 | |
54 | /* Black and white in alternating vertical bands */ |
55 | c = 0xFF; |
56 | for (x = 1*thickness; x < pattern->w; x += 2*thickness) { |
57 | for (i = 0; i < thickness; ++i) { |
58 | p = (Uint8 *)pattern->pixels + (x + i)*3; |
59 | for (y = 0; y < pattern->h; ++y) { |
60 | SDL_memset(p, c, 3); |
61 | p += pattern->pitch; |
62 | } |
63 | } |
64 | if (c) { |
65 | c = 0x00; |
66 | } else { |
67 | c = 0xFF; |
68 | } |
69 | } |
70 | } |
71 | return pattern; |
72 | } |
73 | |
74 | static SDL_bool verify_yuv_data(Uint32 format, const Uint8 *yuv, int yuv_pitch, SDL_Surface *surface) |
75 | { |
76 | const int tolerance = 20; |
77 | const int size = (surface->h * surface->pitch); |
78 | Uint8 *rgb; |
79 | SDL_bool result = SDL_FALSE; |
80 | |
81 | rgb = (Uint8 *)SDL_malloc(size); |
82 | if (!rgb) { |
83 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory" ); |
84 | return SDL_FALSE; |
85 | } |
86 | |
87 | if (SDL_ConvertPixels(surface->w, surface->h, format, yuv, yuv_pitch, surface->format->format, rgb, surface->pitch) == 0) { |
88 | int x, y; |
89 | result = SDL_TRUE; |
90 | for (y = 0; y < surface->h; ++y) { |
91 | const Uint8 *actual = rgb + y * surface->pitch; |
92 | const Uint8 *expected = (const Uint8 *)surface->pixels + y * surface->pitch; |
93 | for (x = 0; x < surface->w; ++x) { |
94 | int deltaR = (int)actual[0] - expected[0]; |
95 | int deltaG = (int)actual[1] - expected[1]; |
96 | int deltaB = (int)actual[2] - expected[2]; |
97 | int distance = (deltaR * deltaR + deltaG * deltaG + deltaB * deltaB); |
98 | if (distance > tolerance) { |
99 | 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); |
100 | result = SDL_FALSE; |
101 | } |
102 | actual += 3; |
103 | expected += 3; |
104 | } |
105 | } |
106 | } else { |
107 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n" , SDL_GetPixelFormatName(format), SDL_GetPixelFormatName(surface->format->format), SDL_GetError()); |
108 | } |
109 | SDL_free(rgb); |
110 | |
111 | return result; |
112 | } |
113 | |
114 | static int run_automated_tests(int pattern_size, int ) |
115 | { |
116 | const Uint32 formats[] = { |
117 | SDL_PIXELFORMAT_YV12, |
118 | SDL_PIXELFORMAT_IYUV, |
119 | SDL_PIXELFORMAT_NV12, |
120 | SDL_PIXELFORMAT_NV21, |
121 | SDL_PIXELFORMAT_YUY2, |
122 | SDL_PIXELFORMAT_UYVY, |
123 | SDL_PIXELFORMAT_YVYU |
124 | }; |
125 | int i, j; |
126 | SDL_Surface *pattern = generate_test_pattern(pattern_size); |
127 | const int yuv_len = MAX_YUV_SURFACE_SIZE(pattern->w, pattern->h, extra_pitch); |
128 | Uint8 *yuv1 = (Uint8 *)SDL_malloc(yuv_len); |
129 | Uint8 *yuv2 = (Uint8 *)SDL_malloc(yuv_len); |
130 | int yuv1_pitch, yuv2_pitch; |
131 | int result = -1; |
132 | |
133 | if (!pattern || !yuv1 || !yuv2) { |
134 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't allocate test surfaces" ); |
135 | goto done; |
136 | } |
137 | |
138 | /* Verify conversion from YUV formats */ |
139 | for (i = 0; i < SDL_arraysize(formats); ++i) { |
140 | if (!ConvertRGBtoYUV(formats[i], pattern->pixels, pattern->pitch, yuv1, pattern->w, pattern->h, SDL_GetYUVConversionModeForResolution(pattern->w, pattern->h), 0, 100)) { |
141 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "ConvertRGBtoYUV() doesn't support converting to %s\n" , SDL_GetPixelFormatName(formats[i])); |
142 | goto done; |
143 | } |
144 | yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w); |
145 | if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) { |
146 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to RGB\n" , SDL_GetPixelFormatName(formats[i])); |
147 | goto done; |
148 | } |
149 | } |
150 | |
151 | /* Verify conversion to YUV formats */ |
152 | for (i = 0; i < SDL_arraysize(formats); ++i) { |
153 | yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch; |
154 | if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) { |
155 | 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()); |
156 | goto done; |
157 | } |
158 | if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) { |
159 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from RGB to %s\n" , SDL_GetPixelFormatName(formats[i])); |
160 | goto done; |
161 | } |
162 | } |
163 | |
164 | /* Verify conversion between YUV formats */ |
165 | for (i = 0; i < SDL_arraysize(formats); ++i) { |
166 | for (j = 0; j < SDL_arraysize(formats); ++j) { |
167 | yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch; |
168 | yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch; |
169 | if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) { |
170 | 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()); |
171 | goto done; |
172 | } |
173 | if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv2, yuv2_pitch) < 0) { |
174 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n" , SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError()); |
175 | goto done; |
176 | } |
177 | if (!verify_yuv_data(formats[j], yuv2, yuv2_pitch, pattern)) { |
178 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n" , SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j])); |
179 | goto done; |
180 | } |
181 | } |
182 | } |
183 | |
184 | /* Verify conversion between YUV formats in-place */ |
185 | for (i = 0; i < SDL_arraysize(formats); ++i) { |
186 | for (j = 0; j < SDL_arraysize(formats); ++j) { |
187 | if (is_packed_yuv_format(formats[i]) != is_packed_yuv_format(formats[j])) { |
188 | /* Can't change plane vs packed pixel layout in-place */ |
189 | continue; |
190 | } |
191 | |
192 | yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch; |
193 | yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch; |
194 | if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) { |
195 | 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()); |
196 | goto done; |
197 | } |
198 | if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv1, yuv2_pitch) < 0) { |
199 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n" , SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError()); |
200 | goto done; |
201 | } |
202 | if (!verify_yuv_data(formats[j], yuv1, yuv2_pitch, pattern)) { |
203 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n" , SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j])); |
204 | goto done; |
205 | } |
206 | } |
207 | } |
208 | |
209 | |
210 | result = 0; |
211 | |
212 | done: |
213 | SDL_free(yuv1); |
214 | SDL_free(yuv2); |
215 | SDL_FreeSurface(pattern); |
216 | return result; |
217 | } |
218 | |
219 | int |
220 | main(int argc, char **argv) |
221 | { |
222 | struct { |
223 | SDL_bool enable_intrinsics; |
224 | int pattern_size; |
225 | int ; |
226 | } automated_test_params[] = { |
227 | /* Test: even width and height */ |
228 | { SDL_FALSE, 2, 0 }, |
229 | { SDL_FALSE, 4, 0 }, |
230 | /* Test: odd width and height */ |
231 | { SDL_FALSE, 1, 0 }, |
232 | { SDL_FALSE, 3, 0 }, |
233 | /* Test: even width and height, extra pitch */ |
234 | { SDL_FALSE, 2, 3 }, |
235 | { SDL_FALSE, 4, 3 }, |
236 | /* Test: odd width and height, extra pitch */ |
237 | { SDL_FALSE, 1, 3 }, |
238 | { SDL_FALSE, 3, 3 }, |
239 | /* Test: even width and height with intrinsics */ |
240 | { SDL_TRUE, 32, 0 }, |
241 | /* Test: odd width and height with intrinsics */ |
242 | { SDL_TRUE, 33, 0 }, |
243 | { SDL_TRUE, 37, 0 }, |
244 | /* Test: even width and height with intrinsics, extra pitch */ |
245 | { SDL_TRUE, 32, 3 }, |
246 | /* Test: odd width and height with intrinsics, extra pitch */ |
247 | { SDL_TRUE, 33, 3 }, |
248 | { SDL_TRUE, 37, 3 }, |
249 | }; |
250 | int arg = 1; |
251 | const char *filename; |
252 | SDL_Surface *original; |
253 | SDL_Surface *converted; |
254 | SDL_Window *window; |
255 | SDL_Renderer *renderer; |
256 | SDL_Texture *output[3]; |
257 | const char *titles[3] = { "ORIGINAL" , "SOFTWARE" , "HARDWARE" }; |
258 | char title[128]; |
259 | const char *yuv_name; |
260 | const char *yuv_mode; |
261 | Uint32 rgb_format = SDL_PIXELFORMAT_RGBX8888; |
262 | Uint32 yuv_format = SDL_PIXELFORMAT_YV12; |
263 | int current = 0; |
264 | int pitch; |
265 | Uint8 *raw_yuv; |
266 | Uint32 then, now, i, iterations = 100; |
267 | SDL_bool should_run_automated_tests = SDL_FALSE; |
268 | |
269 | while (argv[arg] && *argv[arg] == '-') { |
270 | if (SDL_strcmp(argv[arg], "--jpeg" ) == 0) { |
271 | SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_JPEG); |
272 | } else if (SDL_strcmp(argv[arg], "--bt601" ) == 0) { |
273 | SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT601); |
274 | } else if (SDL_strcmp(argv[arg], "--bt709" ) == 0) { |
275 | SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT709); |
276 | } else if (SDL_strcmp(argv[arg], "--auto" ) == 0) { |
277 | SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_AUTOMATIC); |
278 | } else if (SDL_strcmp(argv[arg], "--yv12" ) == 0) { |
279 | yuv_format = SDL_PIXELFORMAT_YV12; |
280 | } else if (SDL_strcmp(argv[arg], "--iyuv" ) == 0) { |
281 | yuv_format = SDL_PIXELFORMAT_IYUV; |
282 | } else if (SDL_strcmp(argv[arg], "--yuy2" ) == 0) { |
283 | yuv_format = SDL_PIXELFORMAT_YUY2; |
284 | } else if (SDL_strcmp(argv[arg], "--uyvy" ) == 0) { |
285 | yuv_format = SDL_PIXELFORMAT_UYVY; |
286 | } else if (SDL_strcmp(argv[arg], "--yvyu" ) == 0) { |
287 | yuv_format = SDL_PIXELFORMAT_YVYU; |
288 | } else if (SDL_strcmp(argv[arg], "--nv12" ) == 0) { |
289 | yuv_format = SDL_PIXELFORMAT_NV12; |
290 | } else if (SDL_strcmp(argv[arg], "--nv21" ) == 0) { |
291 | yuv_format = SDL_PIXELFORMAT_NV21; |
292 | } else if (SDL_strcmp(argv[arg], "--rgb555" ) == 0) { |
293 | rgb_format = SDL_PIXELFORMAT_RGB555; |
294 | } else if (SDL_strcmp(argv[arg], "--rgb565" ) == 0) { |
295 | rgb_format = SDL_PIXELFORMAT_RGB565; |
296 | } else if (SDL_strcmp(argv[arg], "--rgb24" ) == 0) { |
297 | rgb_format = SDL_PIXELFORMAT_RGB24; |
298 | } else if (SDL_strcmp(argv[arg], "--argb" ) == 0) { |
299 | rgb_format = SDL_PIXELFORMAT_ARGB8888; |
300 | } else if (SDL_strcmp(argv[arg], "--abgr" ) == 0) { |
301 | rgb_format = SDL_PIXELFORMAT_ABGR8888; |
302 | } else if (SDL_strcmp(argv[arg], "--rgba" ) == 0) { |
303 | rgb_format = SDL_PIXELFORMAT_RGBA8888; |
304 | } else if (SDL_strcmp(argv[arg], "--bgra" ) == 0) { |
305 | rgb_format = SDL_PIXELFORMAT_BGRA8888; |
306 | } else if (SDL_strcmp(argv[arg], "--automated" ) == 0) { |
307 | should_run_automated_tests = SDL_TRUE; |
308 | } else { |
309 | 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]); |
310 | return 1; |
311 | } |
312 | ++arg; |
313 | } |
314 | |
315 | /* Run automated tests */ |
316 | if (should_run_automated_tests) { |
317 | for (i = 0; i < SDL_arraysize(automated_test_params); ++i) { |
318 | SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Running automated test, pattern size %d, extra pitch %d, intrinsics %s\n" , |
319 | automated_test_params[i].pattern_size, |
320 | automated_test_params[i].extra_pitch, |
321 | automated_test_params[i].enable_intrinsics ? "enabled" : "disabled" ); |
322 | if (run_automated_tests(automated_test_params[i].pattern_size, automated_test_params[i].extra_pitch) < 0) { |
323 | return 2; |
324 | } |
325 | } |
326 | return 0; |
327 | } |
328 | |
329 | if (argv[arg]) { |
330 | filename = argv[arg]; |
331 | } else { |
332 | filename = "testyuv.bmp" ; |
333 | } |
334 | original = SDL_ConvertSurfaceFormat(SDL_LoadBMP(filename), SDL_PIXELFORMAT_RGB24, 0); |
335 | if (!original) { |
336 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n" , filename, SDL_GetError()); |
337 | return 3; |
338 | } |
339 | |
340 | raw_yuv = SDL_calloc(1, MAX_YUV_SURFACE_SIZE(original->w, original->h, 0)); |
341 | ConvertRGBtoYUV(yuv_format, original->pixels, original->pitch, raw_yuv, original->w, original->h, |
342 | SDL_GetYUVConversionModeForResolution(original->w, original->h), |
343 | 0, 100); |
344 | pitch = CalculateYUVPitch(yuv_format, original->w); |
345 | |
346 | converted = SDL_CreateRGBSurfaceWithFormat(0, original->w, original->h, 0, rgb_format); |
347 | if (!converted) { |
348 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create converted surface: %s\n" , SDL_GetError()); |
349 | return 3; |
350 | } |
351 | |
352 | then = SDL_GetTicks(); |
353 | for ( i = 0; i < iterations; ++i ) { |
354 | SDL_ConvertPixels(original->w, original->h, yuv_format, raw_yuv, pitch, rgb_format, converted->pixels, converted->pitch); |
355 | } |
356 | now = SDL_GetTicks(); |
357 | SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "%d iterations in %d ms, %.2fms each\n" , iterations, (now - then), (float)(now - then)/iterations); |
358 | |
359 | window = SDL_CreateWindow("YUV test" , |
360 | SDL_WINDOWPOS_UNDEFINED, |
361 | SDL_WINDOWPOS_UNDEFINED, |
362 | original->w, original->h, |
363 | 0); |
364 | if (!window) { |
365 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n" , SDL_GetError()); |
366 | return 4; |
367 | } |
368 | |
369 | renderer = SDL_CreateRenderer(window, -1, 0); |
370 | if (!renderer) { |
371 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n" , SDL_GetError()); |
372 | return 4; |
373 | } |
374 | |
375 | output[0] = SDL_CreateTextureFromSurface(renderer, original); |
376 | output[1] = SDL_CreateTextureFromSurface(renderer, converted); |
377 | output[2] = SDL_CreateTexture(renderer, yuv_format, SDL_TEXTUREACCESS_STREAMING, original->w, original->h); |
378 | if (!output[0] || !output[1] || !output[2]) { |
379 | SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n" , SDL_GetError()); |
380 | return 5; |
381 | } |
382 | SDL_UpdateTexture(output[2], NULL, raw_yuv, pitch); |
383 | |
384 | yuv_name = SDL_GetPixelFormatName(yuv_format); |
385 | if (SDL_strncmp(yuv_name, "SDL_PIXELFORMAT_" , 16) == 0) { |
386 | yuv_name += 16; |
387 | } |
388 | |
389 | switch (SDL_GetYUVConversionModeForResolution(original->w, original->h)) { |
390 | case SDL_YUV_CONVERSION_JPEG: |
391 | yuv_mode = "JPEG" ; |
392 | break; |
393 | case SDL_YUV_CONVERSION_BT601: |
394 | yuv_mode = "BT.601" ; |
395 | break; |
396 | case SDL_YUV_CONVERSION_BT709: |
397 | yuv_mode = "BT.709" ; |
398 | break; |
399 | default: |
400 | yuv_mode = "UNKNOWN" ; |
401 | break; |
402 | } |
403 | |
404 | { int done = 0; |
405 | while ( !done ) |
406 | { |
407 | SDL_Event event; |
408 | while (SDL_PollEvent(&event) > 0) { |
409 | if (event.type == SDL_QUIT) { |
410 | done = 1; |
411 | } |
412 | if (event.type == SDL_KEYDOWN) { |
413 | if (event.key.keysym.sym == SDLK_ESCAPE) { |
414 | done = 1; |
415 | } else if (event.key.keysym.sym == SDLK_LEFT) { |
416 | --current; |
417 | } else if (event.key.keysym.sym == SDLK_RIGHT) { |
418 | ++current; |
419 | } |
420 | } |
421 | if (event.type == SDL_MOUSEBUTTONDOWN) { |
422 | if (event.button.x < (original->w/2)) { |
423 | --current; |
424 | } else { |
425 | ++current; |
426 | } |
427 | } |
428 | } |
429 | |
430 | /* Handle wrapping */ |
431 | if (current < 0) { |
432 | current += SDL_arraysize(output); |
433 | } |
434 | if (current >= SDL_arraysize(output)) { |
435 | current -= SDL_arraysize(output); |
436 | } |
437 | |
438 | SDL_RenderClear(renderer); |
439 | SDL_RenderCopy(renderer, output[current], NULL, NULL); |
440 | SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); |
441 | if (current == 0) { |
442 | SDLTest_DrawString(renderer, 4, 4, titles[current]); |
443 | } else { |
444 | SDL_snprintf(title, sizeof(title), "%s %s %s" , titles[current], yuv_name, yuv_mode); |
445 | SDLTest_DrawString(renderer, 4, 4, title); |
446 | } |
447 | SDL_RenderPresent(renderer); |
448 | SDL_Delay(10); |
449 | } |
450 | } |
451 | SDL_Quit(); |
452 | return 0; |
453 | } |
454 | |
455 | /* vi: set ts=4 sw=4 expandtab: */ |
456 | |