testoverlay2.c (14066B)
1/* 2 Copyright (C) 1997-2014 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/******************************************************************************** 13 * * 14 * Test of the overlay used for moved pictures, test more closed to real life. * 15 * Running trojan moose :) Coded by Mike Gorchak. * 16 * * 17 ********************************************************************************/ 18 19#include <stdlib.h> 20#include <stdio.h> 21#include <string.h> 22 23#include "SDL.h" 24 25#define MOOSEPIC_W 64 26#define MOOSEPIC_H 88 27 28#define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H) 29#define MOOSEFRAMES_COUNT 10 30 31SDL_Color MooseColors[84] = { 32 {49, 49, 49} 33 , {66, 24, 0} 34 , {66, 33, 0} 35 , {66, 66, 66} 36 , 37 {66, 115, 49} 38 , {74, 33, 0} 39 , {74, 41, 16} 40 , {82, 33, 8} 41 , 42 {82, 41, 8} 43 , {82, 49, 16} 44 , {82, 82, 82} 45 , {90, 41, 8} 46 , 47 {90, 41, 16} 48 , {90, 57, 24} 49 , {99, 49, 16} 50 , {99, 66, 24} 51 , 52 {99, 66, 33} 53 , {99, 74, 33} 54 , {107, 57, 24} 55 , {107, 82, 41} 56 , 57 {115, 57, 33} 58 , {115, 66, 33} 59 , {115, 66, 41} 60 , {115, 74, 0} 61 , 62 {115, 90, 49} 63 , {115, 115, 115} 64 , {123, 82, 0} 65 , {123, 99, 57} 66 , 67 {132, 66, 41} 68 , {132, 74, 41} 69 , {132, 90, 8} 70 , {132, 99, 33} 71 , 72 {132, 99, 66} 73 , {132, 107, 66} 74 , {140, 74, 49} 75 , {140, 99, 16} 76 , 77 {140, 107, 74} 78 , {140, 115, 74} 79 , {148, 107, 24} 80 , {148, 115, 82} 81 , 82 {148, 123, 74} 83 , {148, 123, 90} 84 , {156, 115, 33} 85 , {156, 115, 90} 86 , 87 {156, 123, 82} 88 , {156, 132, 82} 89 , {156, 132, 99} 90 , {156, 156, 156} 91 , 92 {165, 123, 49} 93 , {165, 123, 90} 94 , {165, 132, 82} 95 , {165, 132, 90} 96 , 97 {165, 132, 99} 98 , {165, 140, 90} 99 , {173, 132, 57} 100 , {173, 132, 99} 101 , 102 {173, 140, 107} 103 , {173, 140, 115} 104 , {173, 148, 99} 105 , {173, 173, 173} 106 , 107 {181, 140, 74} 108 , {181, 148, 115} 109 , {181, 148, 123} 110 , {181, 156, 107} 111 , 112 {189, 148, 123} 113 , {189, 156, 82} 114 , {189, 156, 123} 115 , {189, 156, 132} 116 , 117 {189, 189, 189} 118 , {198, 156, 123} 119 , {198, 165, 132} 120 , {206, 165, 99} 121 , 122 {206, 165, 132} 123 , {206, 173, 140} 124 , {206, 206, 206} 125 , {214, 173, 115} 126 , 127 {214, 173, 140} 128 , {222, 181, 148} 129 , {222, 189, 132} 130 , {222, 189, 156} 131 , 132 {222, 222, 222} 133 , {231, 198, 165} 134 , {231, 231, 231} 135 , {239, 206, 173} 136}; 137 138 139/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 140static void 141quit(int rc) 142{ 143 SDL_Quit(); 144 exit(rc); 145} 146 147/* All RGB2YUV conversion code and some other parts of code has been taken from testoverlay.c */ 148 149/* NOTE: These RGB conversion functions are not intended for speed, 150 only as examples. 151*/ 152 153void 154RGBtoYUV(Uint8 * rgb, int *yuv, int monochrome, int luminance) 155{ 156 if (monochrome) { 157#if 1 /* these are the two formulas that I found on the FourCC site... */ 158 yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]); 159 yuv[1] = 128; 160 yuv[2] = 128; 161#else 162 yuv[0] = (int)(0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16; 163 yuv[1] = 128; 164 yuv[2] = 128; 165#endif 166 } else { 167#if 1 /* these are the two formulas that I found on the FourCC site... */ 168 yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]); 169 yuv[1] = (int)((rgb[2] - yuv[0]) * 0.565 + 128); 170 yuv[2] = (int)((rgb[0] - yuv[0]) * 0.713 + 128); 171#else 172 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16; 173 yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]); 174 yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]); 175#endif 176 } 177 178 if (luminance != 100) { 179 yuv[0] = yuv[0] * luminance / 100; 180 if (yuv[0] > 255) 181 yuv[0] = 255; 182 } 183} 184 185void 186ConvertRGBtoYV12(Uint8 *rgb, Uint8 *out, int w, int h, 187 int monochrome, int luminance) 188{ 189 int x, y; 190 int yuv[3]; 191 Uint8 *op[3]; 192 193 op[0] = out; 194 op[1] = op[0] + w*h; 195 op[2] = op[1] + w*h/4; 196 for (y = 0; y < h; ++y) { 197 for (x = 0; x < w; ++x) { 198 RGBtoYUV(rgb, yuv, monochrome, luminance); 199 *(op[0]++) = yuv[0]; 200 if (x % 2 == 0 && y % 2 == 0) { 201 *(op[1]++) = yuv[2]; 202 *(op[2]++) = yuv[1]; 203 } 204 rgb += 3; 205 } 206 } 207} 208 209void 210ConvertRGBtoNV12(Uint8 *rgb, Uint8 *out, int w, int h, 211 int monochrome, int luminance) 212{ 213 int x, y; 214 int yuv[3]; 215 Uint8 *op[2]; 216 217 op[0] = out; 218 op[1] = op[0] + w*h; 219 for (y = 0; y < h; ++y) { 220 for (x = 0; x < w; ++x) { 221 RGBtoYUV(rgb, yuv, monochrome, luminance); 222 *(op[0]++) = yuv[0]; 223 if (x % 2 == 0 && y % 2 == 0) { 224 *(op[1]++) = yuv[1]; 225 *(op[1]++) = yuv[2]; 226 } 227 rgb += 3; 228 } 229 } 230} 231 232static void 233PrintUsage(char *argv0) 234{ 235 SDL_Log("Usage: %s [arg] [arg] [arg] ...\n", argv0); 236 SDL_Log("\n"); 237 SDL_Log("Where 'arg' is any of the following options:\n"); 238 SDL_Log("\n"); 239 SDL_Log(" -fps <frames per second>\n"); 240 SDL_Log(" -nodelay\n"); 241 SDL_Log(" -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n"); 242 SDL_Log(" -scale <scale factor> (initial scale of the overlay)\n"); 243 SDL_Log(" -help (shows this help)\n"); 244 SDL_Log("\n"); 245 SDL_Log("Press ESC to exit, or SPACE to freeze the movie while application running.\n"); 246 SDL_Log("\n"); 247} 248 249int 250main(int argc, char **argv) 251{ 252 Uint8 *RawMooseData; 253 SDL_RWops *handle; 254 int window_w; 255 int window_h; 256 SDL_Window *window; 257 SDL_Renderer *renderer; 258 Uint8 MooseFrame[MOOSEFRAMES_COUNT][MOOSEFRAME_SIZE*2]; 259 SDL_Texture *MooseTexture; 260 SDL_Rect displayrect; 261 SDL_Event event; 262 int paused = 0; 263 int i, j; 264 int fps = 12; 265 int fpsdelay; 266 int nodelay = 0; 267#ifdef TEST_NV12 268 Uint32 pixel_format = SDL_PIXELFORMAT_NV12; 269#else 270 Uint32 pixel_format = SDL_PIXELFORMAT_YV12; 271#endif 272 int scale = 5; 273 SDL_bool done = SDL_FALSE; 274 275 /* Enable standard application logging */ 276 SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); 277 278 if (SDL_Init(SDL_INIT_VIDEO) < 0) { 279 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); 280 return 3; 281 } 282 283 while (argc > 1) { 284 if (strcmp(argv[1], "-fps") == 0) { 285 if (argv[2]) { 286 fps = atoi(argv[2]); 287 if (fps == 0) { 288 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, 289 "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); 290 quit(10); 291 } 292 if ((fps < 0) || (fps > 1000)) { 293 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, 294 "The -fps option must be in range from 1 to 1000, default is 12.\n"); 295 quit(10); 296 } 297 argv += 2; 298 argc -= 2; 299 } else { 300 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, 301 "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); 302 quit(10); 303 } 304 } else if (strcmp(argv[1], "-nodelay") == 0) { 305 nodelay = 1; 306 argv += 1; 307 argc -= 1; 308 } else if (strcmp(argv[1], "-scale") == 0) { 309 if (argv[2]) { 310 scale = atoi(argv[2]); 311 if (scale == 0) { 312 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, 313 "The -scale option requires an argument [from 1 to 50], default is 5.\n"); 314 quit(10); 315 } 316 if ((scale < 0) || (scale > 50)) { 317 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, 318 "The -scale option must be in range from 1 to 50, default is 5.\n"); 319 quit(10); 320 } 321 argv += 2; 322 argc -= 2; 323 } else { 324 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, 325 "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); 326 quit(10); 327 } 328 } else if ((strcmp(argv[1], "-help") == 0) 329 || (strcmp(argv[1], "-h") == 0)) { 330 PrintUsage(argv[0]); 331 quit(0); 332 } else { 333 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unrecognized option: %s.\n", argv[1]); 334 quit(10); 335 } 336 break; 337 } 338 339 RawMooseData = (Uint8 *) malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT); 340 if (RawMooseData == NULL) { 341 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't allocate memory for movie !\n"); 342 free(RawMooseData); 343 quit(1); 344 } 345 346 /* load the trojan moose images */ 347 handle = SDL_RWFromFile("moose.dat", "rb"); 348 if (handle == NULL) { 349 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n"); 350 free(RawMooseData); 351 quit(2); 352 } 353 354 SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT); 355 356 SDL_RWclose(handle); 357 358 /* Create the window and renderer */ 359 window_w = MOOSEPIC_W * scale; 360 window_h = MOOSEPIC_H * scale; 361 window = SDL_CreateWindow("Happy Moose", 362 SDL_WINDOWPOS_UNDEFINED, 363 SDL_WINDOWPOS_UNDEFINED, 364 window_w, window_h, 365 SDL_WINDOW_RESIZABLE); 366 if (!window) { 367 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create window: %s\n", SDL_GetError()); 368 free(RawMooseData); 369 quit(4); 370 } 371 372 renderer = SDL_CreateRenderer(window, -1, 0); 373 if (!renderer) { 374 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create renderer: %s\n", SDL_GetError()); 375 free(RawMooseData); 376 quit(4); 377 } 378 379 MooseTexture = SDL_CreateTexture(renderer, pixel_format, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H); 380 if (!MooseTexture) { 381 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError()); 382 free(RawMooseData); 383 quit(5); 384 } 385 /* Uncomment this to check vertex color with a YUV texture */ 386 /* SDL_SetTextureColorMod(MooseTexture, 0xff, 0x80, 0x80); */ 387 388 for (i = 0; i < MOOSEFRAMES_COUNT; i++) { 389 Uint8 MooseFrameRGB[MOOSEFRAME_SIZE*3]; 390 Uint8 *rgb; 391 Uint8 *frame; 392 393 rgb = MooseFrameRGB; 394 frame = RawMooseData + i * MOOSEFRAME_SIZE; 395 for (j = 0; j < MOOSEFRAME_SIZE; ++j) { 396 rgb[0] = MooseColors[frame[j]].r; 397 rgb[1] = MooseColors[frame[j]].g; 398 rgb[2] = MooseColors[frame[j]].b; 399 rgb += 3; 400 } 401 switch (pixel_format) { 402 case SDL_PIXELFORMAT_YV12: 403 ConvertRGBtoYV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100); 404 break; 405 case SDL_PIXELFORMAT_NV12: 406 ConvertRGBtoNV12(MooseFrameRGB, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, 0, 100); 407 break; 408 default: 409 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unsupported pixel format\n"); 410 break; 411 } 412 } 413 414 free(RawMooseData); 415 416 /* set the start frame */ 417 i = 0; 418 if (nodelay) { 419 fpsdelay = 0; 420 } else { 421 fpsdelay = 1000 / fps; 422 } 423 424 displayrect.x = 0; 425 displayrect.y = 0; 426 displayrect.w = window_w; 427 displayrect.h = window_h; 428 429 /* Ignore key up events, they don't even get filtered */ 430 SDL_EventState(SDL_KEYUP, SDL_IGNORE); 431 432 /* Loop, waiting for QUIT or RESIZE */ 433 while (!done) { 434 while (SDL_PollEvent(&event)) { 435 switch (event.type) { 436 case SDL_WINDOWEVENT: 437 if (event.window.event == SDL_WINDOWEVENT_RESIZED) { 438 SDL_RenderSetViewport(renderer, NULL); 439 displayrect.w = window_w = event.window.data1; 440 displayrect.h = window_h = event.window.data2; 441 } 442 break; 443 case SDL_MOUSEBUTTONDOWN: 444 displayrect.x = event.button.x - window_w / 2; 445 displayrect.y = event.button.y - window_h / 2; 446 break; 447 case SDL_MOUSEMOTION: 448 if (event.motion.state) { 449 displayrect.x = event.motion.x - window_w / 2; 450 displayrect.y = event.motion.y - window_h / 2; 451 } 452 break; 453 case SDL_KEYDOWN: 454 if (event.key.keysym.sym == SDLK_SPACE) { 455 paused = !paused; 456 break; 457 } 458 if (event.key.keysym.sym != SDLK_ESCAPE) { 459 break; 460 } 461 case SDL_QUIT: 462 done = SDL_TRUE; 463 break; 464 } 465 } 466 SDL_Delay(fpsdelay); 467 468 if (!paused) { 469 i = (i + 1) % MOOSEFRAMES_COUNT; 470 471 SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W*SDL_BYTESPERPIXEL(pixel_format)); 472 } 473 SDL_RenderClear(renderer); 474 SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect); 475 SDL_RenderPresent(renderer); 476 } 477 SDL_DestroyRenderer(renderer); 478 quit(0); 479 return 0; 480} 481 482/* vi: set ts=4 sw=4 expandtab: */