Home | History | Annotate | Download | only in test
      1 /********************************************************************************
      2  *                                                                              *
      3  * Test of the overlay used for moved pictures, test more closed to real life.  *
      4  * Running trojan moose :) Coded by Mike Gorchak.                               *
      5  *                                                                              *
      6  ********************************************************************************/
      7 
      8 #include <stdlib.h>
      9 #include <stdio.h>
     10 #include <string.h>
     11 
     12 #include "SDL.h"
     13 
     14 #define MOOSEPIC_W 64
     15 #define MOOSEPIC_H 88
     16 
     17 #define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H)
     18 #define MOOSEFRAMES_COUNT 10
     19 
     20 SDL_Color MooseColors[84]={
     21     { 49,  49,  49}, { 66,  24,   0}, { 66,  33,   0}, { 66,  66,  66},
     22     { 66, 115,  49}, { 74,  33,   0}, { 74,  41,  16}, { 82,  33,   8},
     23     { 82,  41,   8}, { 82,  49,  16}, { 82,  82,  82}, { 90,  41,   8},
     24     { 90,  41,  16}, { 90,  57,  24}, { 99,  49,  16}, { 99,  66,  24},
     25     { 99,  66,  33}, { 99,  74,  33}, {107,  57,  24}, {107,  82,  41},
     26     {115,  57,  33}, {115,  66,  33}, {115,  66,  41}, {115,  74,   0},
     27     {115,  90,  49}, {115, 115, 115}, {123,  82,   0}, {123,  99,  57},
     28     {132,  66,  41}, {132,  74,  41}, {132,  90,   8}, {132,  99,  33},
     29     {132,  99,  66}, {132, 107,  66}, {140,  74,  49}, {140,  99,  16},
     30     {140, 107,  74}, {140, 115,  74}, {148, 107,  24}, {148, 115,  82},
     31     {148, 123,  74}, {148, 123,  90}, {156, 115,  33}, {156, 115,  90},
     32     {156, 123,  82}, {156, 132,  82}, {156, 132,  99}, {156, 156, 156},
     33     {165, 123,  49}, {165, 123,  90}, {165, 132,  82}, {165, 132,  90},
     34     {165, 132,  99}, {165, 140,  90}, {173, 132,  57}, {173, 132,  99},
     35     {173, 140, 107}, {173, 140, 115}, {173, 148,  99}, {173, 173, 173},
     36     {181, 140,  74}, {181, 148, 115}, {181, 148, 123}, {181, 156, 107},
     37     {189, 148, 123}, {189, 156,  82}, {189, 156, 123}, {189, 156, 132},
     38     {189, 189, 189}, {198, 156, 123}, {198, 165, 132}, {206, 165,  99},
     39     {206, 165, 132}, {206, 173, 140}, {206, 206, 206}, {214, 173, 115},
     40     {214, 173, 140}, {222, 181, 148}, {222, 189, 132}, {222, 189, 156},
     41     {222, 222, 222}, {231, 198, 165}, {231, 231, 231}, {239, 206, 173}
     42 };
     43 
     44 
     45 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
     46 static void quit(int rc)
     47 {
     48 	SDL_Quit();
     49 	exit(rc);
     50 }
     51 
     52 /* All RGB2YUV conversion code and some other parts of code has been taken from testoverlay.c */
     53 
     54 /* NOTE: These RGB conversion functions are not intended for speed,
     55          only as examples.
     56 */
     57 
     58 void RGBtoYUV(Uint8 *rgb, int *yuv, int monochrome, int luminance)
     59 {
     60     if (monochrome)
     61     {
     62 #if 1 /* these are the two formulas that I found on the FourCC site... */
     63         yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
     64         yuv[1] = 128;
     65         yuv[2] = 128;
     66 #else
     67         yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
     68         yuv[1] = 128;
     69         yuv[2] = 128;
     70 #endif
     71     }
     72     else
     73     {
     74 #if 1 /* these are the two formulas that I found on the FourCC site... */
     75         yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
     76         yuv[1] = (rgb[2]-yuv[0])*0.565 + 128;
     77         yuv[2] = (rgb[0]-yuv[0])*0.713 + 128;
     78 #else
     79         yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
     80         yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]);
     81         yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
     82 #endif
     83     }
     84 
     85     if (luminance!=100)
     86     {
     87         yuv[0]=yuv[0]*luminance/100;
     88         if (yuv[0]>255)
     89             yuv[0]=255;
     90     }
     91 }
     92 
     93 void ConvertRGBtoYV12(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
     94 {
     95 	int x,y;
     96 	int yuv[3];
     97 	Uint8 *p,*op[3];
     98 
     99 	SDL_LockSurface(s);
    100 	SDL_LockYUVOverlay(o);
    101 
    102 	/* Convert */
    103 	for(y=0; y<s->h && y<o->h; y++)
    104 	{
    105 		p=((Uint8 *) s->pixels)+s->pitch*y;
    106 		op[0]=o->pixels[0]+o->pitches[0]*y;
    107 		op[1]=o->pixels[1]+o->pitches[1]*(y/2);
    108 		op[2]=o->pixels[2]+o->pitches[2]*(y/2);
    109 		for(x=0; x<s->w && x<o->w; x++)
    110 		{
    111 			RGBtoYUV(p, yuv, monochrome, luminance);
    112 			*(op[0]++)=yuv[0];
    113 			if(x%2==0 && y%2==0)
    114 			{
    115 				*(op[1]++)=yuv[2];
    116 				*(op[2]++)=yuv[1];
    117 			}
    118 			p+=s->format->BytesPerPixel;
    119 		}
    120 	}
    121 
    122 	SDL_UnlockYUVOverlay(o);
    123 	SDL_UnlockSurface(s);
    124 }
    125 
    126 void ConvertRGBtoIYUV(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
    127 {
    128 	int x,y;
    129 	int yuv[3];
    130 	Uint8 *p,*op[3];
    131 
    132 	SDL_LockSurface(s);
    133 	SDL_LockYUVOverlay(o);
    134 
    135 	/* Convert */
    136 	for(y=0; y<s->h && y<o->h; y++)
    137 	{
    138 		p=((Uint8 *) s->pixels)+s->pitch*y;
    139 		op[0]=o->pixels[0]+o->pitches[0]*y;
    140 		op[1]=o->pixels[1]+o->pitches[1]*(y/2);
    141 		op[2]=o->pixels[2]+o->pitches[2]*(y/2);
    142 		for(x=0; x<s->w && x<o->w; x++)
    143 		{
    144 			RGBtoYUV(p,yuv, monochrome, luminance);
    145 			*(op[0]++)=yuv[0];
    146 			if(x%2==0 && y%2==0)
    147 			{
    148 				*(op[1]++)=yuv[1];
    149 				*(op[2]++)=yuv[2];
    150 			}
    151 			p+=s->format->BytesPerPixel;
    152 		}
    153 	}
    154 
    155 	SDL_UnlockYUVOverlay(o);
    156 	SDL_UnlockSurface(s);
    157 }
    158 
    159 void ConvertRGBtoUYVY(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
    160 {
    161 	int x,y;
    162 	int yuv[3];
    163 	Uint8 *p,*op;
    164 
    165 	SDL_LockSurface(s);
    166 	SDL_LockYUVOverlay(o);
    167 
    168 	for(y=0; y<s->h && y<o->h; y++)
    169 	{
    170 		p=((Uint8 *) s->pixels)+s->pitch*y;
    171 		op=o->pixels[0]+o->pitches[0]*y;
    172 		for(x=0; x<s->w && x<o->w; x++)
    173 		{
    174 			RGBtoYUV(p, yuv, monochrome, luminance);
    175 			if(x%2==0)
    176 			{
    177 				*(op++)=yuv[1];
    178 				*(op++)=yuv[0];
    179 				*(op++)=yuv[2];
    180 			}
    181 			else
    182 				*(op++)=yuv[0];
    183 
    184 			p+=s->format->BytesPerPixel;
    185 		}
    186 	}
    187 
    188 	SDL_UnlockYUVOverlay(o);
    189 	SDL_UnlockSurface(s);
    190 }
    191 
    192 void ConvertRGBtoYVYU(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
    193 {
    194 	int x,y;
    195 	int yuv[3];
    196 	Uint8 *p,*op;
    197 
    198 	SDL_LockSurface(s);
    199 	SDL_LockYUVOverlay(o);
    200 
    201 	for(y=0; y<s->h && y<o->h; y++)
    202 	{
    203 		p=((Uint8 *) s->pixels)+s->pitch*y;
    204 		op=o->pixels[0]+o->pitches[0]*y;
    205 		for(x=0; x<s->w && x<o->w; x++)
    206 		{
    207 			RGBtoYUV(p,yuv, monochrome, luminance);
    208 			if(x%2==0)
    209 			{
    210 				*(op++)=yuv[0];
    211 				*(op++)=yuv[2];
    212 				op[1]=yuv[1];
    213 			}
    214 			else
    215 			{
    216 				*op=yuv[0];
    217 				op+=2;
    218 			}
    219 
    220 			p+=s->format->BytesPerPixel;
    221 		}
    222 	}
    223 
    224 	SDL_UnlockYUVOverlay(o);
    225 	SDL_UnlockSurface(s);
    226 }
    227 
    228 void ConvertRGBtoYUY2(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
    229 {
    230 	int x,y;
    231 	int yuv[3];
    232 	Uint8 *p,*op;
    233 
    234 	SDL_LockSurface(s);
    235 	SDL_LockYUVOverlay(o);
    236 
    237 	for(y=0; y<s->h && y<o->h; y++)
    238 	{
    239 		p=((Uint8 *) s->pixels)+s->pitch*y;
    240 		op=o->pixels[0]+o->pitches[0]*y;
    241 		for(x=0; x<s->w && x<o->w; x++)
    242 		{
    243 			RGBtoYUV(p,yuv, monochrome, luminance);
    244 			if(x%2==0)
    245 			{
    246 				*(op++)=yuv[0];
    247 				*(op++)=yuv[1];
    248 				op[1]=yuv[2];
    249 			}
    250 			else
    251 			{
    252 				*op=yuv[0];
    253 				op+=2;
    254 			}
    255 
    256 			p+=s->format->BytesPerPixel;
    257 		}
    258 	}
    259 
    260 	SDL_UnlockYUVOverlay(o);
    261 	SDL_UnlockSurface(s);
    262 }
    263 
    264 static void PrintUsage(char *argv0)
    265 {
    266     fprintf(stderr, "Usage: %s [arg] [arg] [arg] ...\n", argv0);
    267     fprintf(stderr, "\n");
    268     fprintf(stderr, "Where 'arg' is any of the following options:\n");
    269     fprintf(stderr, "\n");
    270     fprintf(stderr, "	-fps <frames per second>\n");
    271     fprintf(stderr, "	-format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n");
    272     fprintf(stderr, "	-scale <scale factor> (initial scale of the overlay)\n");
    273     fprintf(stderr, "	-help (shows this help)\n");
    274     fprintf(stderr, "\n");
    275     fprintf(stderr, "Press ESC to exit, or SPACE to freeze the movie while application running.\n");
    276     fprintf(stderr, "\n");
    277 }
    278 
    279 int main(int argc, char **argv)
    280 {
    281     Uint8* RawMooseData;
    282     SDL_RWops* handle;
    283     SDL_Surface* screen;
    284     SDL_Surface* MooseFrame[MOOSEFRAMES_COUNT];
    285     SDL_Overlay* overlay;
    286     SDL_Rect overlayrect;
    287     SDL_Event event;
    288     Uint32 lastftick;
    289     int paused=0;
    290     int resized=0;
    291     int i;
    292     int fps=12;
    293     int fpsdelay;
    294     int overlay_format=SDL_YUY2_OVERLAY;
    295     int scale=5;
    296 
    297     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0)
    298     {
    299         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
    300         return 3;
    301     }
    302 
    303     while ( argc > 1 )
    304     {
    305         if (strcmp(argv[1], "-fps")== 0)
    306         {
    307             if (argv[2])
    308             {
    309                 fps = atoi(argv[2]);
    310                 if (fps==0)
    311                 {
    312                     fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
    313                     quit(10);
    314                 }
    315                 if ((fps<0) || (fps>1000))
    316                 {
    317                     fprintf(stderr, "The -fps option must be in range from 1 to 1000, default is 12.\n");
    318                     quit(10);
    319                 }
    320                 argv += 2;
    321                 argc -= 2;
    322             }
    323             else
    324             {
    325                 fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
    326                 quit(10);
    327             }
    328         } else
    329         if (strcmp(argv[1], "-format") == 0)
    330         {
    331             if (argv[2])
    332             {
    333                 if (!strcmp(argv[2],"YV12"))
    334                     overlay_format = SDL_YV12_OVERLAY;
    335                 else if(!strcmp(argv[2],"IYUV"))
    336                     overlay_format = SDL_IYUV_OVERLAY;
    337                 else if(!strcmp(argv[2],"YUY2"))
    338                     overlay_format = SDL_YUY2_OVERLAY;
    339                 else if(!strcmp(argv[2],"UYVY"))
    340                     overlay_format = SDL_UYVY_OVERLAY;
    341                 else if(!strcmp(argv[2],"YVYU"))
    342                     overlay_format = SDL_YVYU_OVERLAY;
    343                 else
    344                 {
    345                     fprintf(stderr, "The -format option %s is not recognized, see help for info.\n", argv[2]);
    346                     quit(10);
    347                 }
    348                 argv += 2;
    349                 argc -= 2;
    350             }
    351             else
    352             {
    353                 fprintf(stderr, "The -format option requires an argument, default is YUY2.\n");
    354                 quit(10);
    355             }
    356         } else
    357         if (strcmp(argv[1], "-scale") == 0)
    358         {
    359             if (argv[2])
    360             {
    361                 scale = atoi(argv[2]);
    362                 if (scale==0)
    363                 {
    364                     fprintf(stderr, "The -scale option requires an argument [from 1 to 50], default is 5.\n");
    365                     quit(10);
    366                 }
    367                 if ((scale<0) || (scale>50))
    368                 {
    369                     fprintf(stderr, "The -scale option must be in range from 1 to 50, default is 5.\n");
    370                     quit(10);
    371                 }
    372                 argv += 2;
    373                 argc -= 2;
    374             }
    375             else
    376             {
    377                 fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n");
    378                 quit(10);
    379             }
    380         } else
    381         if ((strcmp(argv[1], "-help") == 0 ) || (strcmp(argv[1], "-h") == 0))
    382         {
    383             PrintUsage(argv[0]);
    384             quit(0);
    385         } else
    386         {
    387             fprintf(stderr, "Unrecognized option: %s.\n", argv[1]);
    388             quit(10);
    389         }
    390         break;
    391     }
    392 
    393     RawMooseData=(Uint8*)malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT);
    394     if (RawMooseData==NULL)
    395     {
    396         fprintf(stderr, "Can't allocate memory for movie !\n");
    397         free(RawMooseData);
    398         quit(1);
    399     }
    400 
    401     /* load the trojan moose images */
    402     handle=SDL_RWFromFile("moose.dat", "rb");
    403     if (handle==NULL)
    404     {
    405         fprintf(stderr, "Can't find the file moose.dat !\n");
    406         free(RawMooseData);
    407         quit(2);
    408     }
    409 
    410     SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT);
    411 
    412     SDL_RWclose(handle);
    413 
    414     /* Set video mode */
    415     if ( (screen=SDL_SetVideoMode(MOOSEPIC_W*scale, MOOSEPIC_H*scale, 0, SDL_RESIZABLE | SDL_SWSURFACE)) == NULL )
    416     {
    417         fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
    418         free(RawMooseData);
    419         quit(4);
    420     }
    421 
    422     /* Set the window manager title bar */
    423     SDL_WM_SetCaption("SDL test overlay: running moose", "testoverlay2");
    424 
    425     for (i=0; i<MOOSEFRAMES_COUNT; i++)
    426     {
    427         MooseFrame[i]=SDL_CreateRGBSurfaceFrom(RawMooseData+i*MOOSEFRAME_SIZE, MOOSEPIC_W,
    428                                                MOOSEPIC_H, 8, MOOSEPIC_W, 0, 0, 0, 0);
    429         if (MooseFrame[i]==NULL)
    430         {
    431             fprintf(stderr, "Couldn't create SDL_Surfaces:%s\n", SDL_GetError());
    432             free(RawMooseData);
    433             quit(5);
    434         }
    435         SDL_SetColors(MooseFrame[i], MooseColors, 0, 84);
    436 
    437 	{
    438 		SDL_Surface *newsurf;
    439 		SDL_PixelFormat format;
    440 
    441 		format.palette=NULL;
    442 		format.BitsPerPixel=32;
    443 		format.BytesPerPixel=4;
    444 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
    445 		format.Rshift=0;
    446 		format.Gshift=8;
    447 		format.Bshift=16;
    448 #else
    449 		format.Rshift=24;
    450 		format.Gshift=16;
    451 		format.Bshift=8;
    452 #endif
    453 		format.Ashift=0;
    454 		format.Rmask=0xff<<format.Rshift;
    455 		format.Gmask=0xff<<format.Gshift;
    456 		format.Bmask=0xff<<format.Bshift;
    457 		format.Amask=0;
    458 		format.Rloss=0;
    459 		format.Gloss=0;
    460 		format.Bloss=0;
    461 		format.Aloss=8;
    462 		format.colorkey=0;
    463 		format.alpha=0;
    464 
    465 		newsurf=SDL_ConvertSurface(MooseFrame[i], &format, SDL_SWSURFACE);
    466 		if(!newsurf)
    467 		{
    468                     fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n", SDL_GetError());
    469                     quit(6);
    470 		}
    471 		SDL_FreeSurface(MooseFrame[i]);
    472 		MooseFrame[i]=newsurf;
    473 	}
    474     }
    475 
    476     free(RawMooseData);
    477 
    478     overlay=SDL_CreateYUVOverlay(MOOSEPIC_W, MOOSEPIC_H, overlay_format, screen);
    479     if (!overlay)
    480     {
    481         fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
    482         quit(7);
    483     }
    484 
    485     printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes,
    486            overlay->hw_overlay?"hardware":"software",
    487            overlay->format==SDL_YV12_OVERLAY?"YV12":
    488            overlay->format==SDL_IYUV_OVERLAY?"IYUV":
    489            overlay->format==SDL_YUY2_OVERLAY?"YUY2":
    490            overlay->format==SDL_UYVY_OVERLAY?"UYVY":
    491            overlay->format==SDL_YVYU_OVERLAY?"YVYU":
    492            "Unknown");
    493 
    494     for(i=0; i<overlay->planes; i++)
    495     {
    496         printf("  plane %d: pitch=%d\n", i, overlay->pitches[i]);
    497     }
    498 
    499     overlayrect.x=0;
    500     overlayrect.y=0;
    501     overlayrect.w=MOOSEPIC_W*scale;
    502     overlayrect.h=MOOSEPIC_H*scale;
    503 
    504     /* set the start frame */
    505     i=0;
    506     fpsdelay=1000/fps;
    507 
    508     /* Ignore key up events, they don't even get filtered */
    509     SDL_EventState(SDL_KEYUP, SDL_IGNORE);
    510 
    511     lastftick=SDL_GetTicks();
    512 
    513     /* Loop, waiting for QUIT or RESIZE */
    514     while (1)
    515     {
    516         if (SDL_PollEvent(&event))
    517         {
    518             switch (event.type)
    519             {
    520                 case SDL_VIDEORESIZE:
    521                      screen=SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_RESIZABLE | SDL_SWSURFACE);
    522                      overlayrect.w=event.resize.w;
    523                      overlayrect.h=event.resize.h;
    524                      if (paused)
    525                      {
    526                          resized=1;
    527                      }
    528                      break;
    529                 case SDL_MOUSEBUTTONDOWN:
    530                      overlayrect.x = event.button.x - overlayrect.w/2;
    531                      overlayrect.y = event.button.y - overlayrect.h/2;
    532                      break;
    533                 case SDL_KEYDOWN:
    534                      if (event.key.keysym.sym == SDLK_SPACE)
    535                      {
    536                          paused=!paused;
    537                          break;
    538                      }
    539                      if (event.key.keysym.sym != SDLK_ESCAPE)
    540                      {
    541                          break;
    542                      }
    543                 case SDL_QUIT:
    544                      SDL_FreeYUVOverlay(overlay);
    545                      for (i=0; i<MOOSEFRAMES_COUNT; i++)
    546                      {
    547                          SDL_FreeSurface(MooseFrame[i]);
    548                      }
    549                      quit(0);
    550             }
    551         }
    552 
    553         if ((!paused)||(resized))
    554         {
    555             if (((SDL_GetTicks()-lastftick)>fpsdelay)||(resized))
    556             {
    557                 lastftick=SDL_GetTicks();
    558 
    559                 switch (overlay_format)
    560                 {
    561                     case SDL_YUY2_OVERLAY:
    562                          ConvertRGBtoYUY2(MooseFrame[i], overlay, 0, 100);
    563                          break;
    564                     case SDL_YV12_OVERLAY:
    565                          ConvertRGBtoYV12(MooseFrame[i], overlay, 0, 100);
    566                          break;
    567                     case SDL_UYVY_OVERLAY:
    568                          ConvertRGBtoUYVY(MooseFrame[i], overlay, 0, 100);
    569                          break;
    570                     case SDL_YVYU_OVERLAY:
    571                          ConvertRGBtoYVYU(MooseFrame[i], overlay, 0, 100);
    572                          break;
    573                     case SDL_IYUV_OVERLAY:
    574                          ConvertRGBtoIYUV(MooseFrame[i], overlay, 0, 100);
    575                          break;
    576                 }
    577 
    578                 SDL_DisplayYUVOverlay(overlay, &overlayrect);
    579                 if (!resized)
    580                 {
    581                     i++;
    582                     if (i==10)
    583                     {
    584                         i=0;
    585                     }
    586                 }
    587                 else
    588                 {
    589                     resized=0;
    590                 }
    591             }
    592         }
    593         /* kind of timeslice to OS */
    594         SDL_Delay(1);
    595     }
    596 
    597 	SDL_Quit();
    598     return 0;
    599 }
    600 
    601