comparison test/testoverlay.c @ 277:255c7ee077cb

Added a YUV overlay test program (thanks Jon!)
author Sam Lantinga <slouken@libsdl.org>
date Thu, 14 Feb 2002 00:47:46 +0000
parents
children e8063c656626
comparison
equal deleted inserted replaced
276:8af85680ca0a 277:255c7ee077cb
1
2 /* Bring up a window and play with it */
3
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7
8 #define BENCHMARK_SDL
9
10 #define NOTICE(X) printf("%s", X);
11
12 #include "SDL.h"
13
14 SDL_Surface *screen, *pic;
15 SDL_Overlay *overlay;
16 int scale;
17
18 /* NOTE: These RGB conversion functions are not intended for speed,
19 only as examples.
20 */
21
22 void RGBtoYUV(Uint8 *rgb, int *yuv)
23 {
24 int i;
25 #if 1 /* these are the two formulas that I found on the FourCC site... */
26 yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
27 yuv[1] = (rgb[2]-yuv[0])*0.565 + 128;
28 yuv[2] = (rgb[0]-yuv[0])*0.713 + 128;
29 #else
30 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
31 yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]);
32 yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
33 #endif
34 /* clamp values...if you need to, we don't seem to have a need */
35 /*
36 for(i=0;i<3;i++)
37 {
38 if(yuv[i]<0)
39 yuv[i]=0;
40 if(yuv[i]>255)
41 yuv[i]=255;
42 }
43 */
44 }
45
46 ConvertRGBtoYV12(SDL_Surface *s, SDL_Overlay *o)
47 {
48 int x,y;
49 int yuv[3];
50 Uint8 *p,*op[3];
51
52 SDL_LockSurface(s);
53 SDL_LockYUVOverlay(o);
54
55 /* Black initialization */
56 /*
57 memset(o->pixels[0],0,o->pitches[0]*o->h);
58 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2));
59 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2));
60 */
61
62 /* Convert */
63 for(y=0; y<s->h && y<o->h; y++)
64 {
65 p=s->pixels+s->pitch*y;
66 op[0]=o->pixels[0]+o->pitches[0]*y;
67 op[1]=o->pixels[1]+o->pitches[1]*(y/2);
68 op[2]=o->pixels[2]+o->pitches[2]*(y/2);
69 for(x=0; x<s->w && x<o->w; x++)
70 {
71 RGBtoYUV(p,yuv);
72 *(op[0]++)=yuv[0];
73 if(x%2==0 && y%2==0)
74 {
75 *(op[1]++)=yuv[2];
76 *(op[2]++)=yuv[1];
77 }
78 p+=s->format->BytesPerPixel;
79 }
80 }
81
82 SDL_UnlockYUVOverlay(o);
83 SDL_UnlockSurface(s);
84 }
85
86 ConvertRGBtoIYUV(SDL_Surface *s, SDL_Overlay *o)
87 {
88 int x,y;
89 int yuv[3];
90 Uint8 *p,*op[3];
91
92 SDL_LockSurface(s);
93 SDL_LockYUVOverlay(o);
94
95 /* Black initialization */
96 /*
97 memset(o->pixels[0],0,o->pitches[0]*o->h);
98 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2));
99 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2));
100 */
101
102 /* Convert */
103 for(y=0; y<s->h && y<o->h; y++)
104 {
105 p=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);
112 *(op[0]++)=yuv[0];
113 if(x%2==0 && y%2==0)
114 {
115 *(op[1]++)=yuv[1];
116 *(op[2]++)=yuv[2];
117 }
118 p+=s->format->BytesPerPixel;
119 }
120 }
121
122 SDL_UnlockYUVOverlay(o);
123 SDL_UnlockSurface(s);
124 }
125
126 ConvertRGBtoUYVY(SDL_Surface *s, SDL_Overlay *o)
127 {
128 int x,y;
129 int yuv[3];
130 Uint8 *p,*op;
131
132 SDL_LockSurface(s);
133 SDL_LockYUVOverlay(o);
134
135 for(y=0; y<s->h && y<o->h; y++)
136 {
137 p=s->pixels+s->pitch*y;
138 op=o->pixels[0]+o->pitches[0]*y;
139 for(x=0; x<s->w && x<o->w; x++)
140 {
141 RGBtoYUV(p,yuv);
142 if(x%2==0)
143 {
144 *(op++)=yuv[1];
145 *(op++)=yuv[0];
146 *(op++)=yuv[2];
147 }
148 else
149 *(op++)=yuv[0];
150
151 p+=s->format->BytesPerPixel;
152 }
153 }
154
155 SDL_UnlockYUVOverlay(o);
156 SDL_UnlockSurface(s);
157 }
158
159 ConvertRGBtoYVYU(SDL_Surface *s, SDL_Overlay *o)
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=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);
175 if(x%2==0)
176 {
177 *(op++)=yuv[0];
178 *(op++)=yuv[2];
179 op[1]=yuv[1];
180 }
181 else
182 {
183 *op=yuv[0];
184 op+=2;
185 }
186
187 p+=s->format->BytesPerPixel;
188 }
189 }
190
191 SDL_UnlockYUVOverlay(o);
192 SDL_UnlockSurface(s);
193 }
194
195 ConvertRGBtoYUY2(SDL_Surface *s, SDL_Overlay *o)
196 {
197 int x,y;
198 int yuv[3];
199 Uint8 *p,*op;
200
201 SDL_LockSurface(s);
202 SDL_LockYUVOverlay(o);
203
204 for(y=0; y<s->h && y<o->h; y++)
205 {
206 p=s->pixels+s->pitch*y;
207 op=o->pixels[0]+o->pitches[0]*y;
208 for(x=0; x<s->w && x<o->w; x++)
209 {
210 RGBtoYUV(p,yuv);
211 if(x%2==0)
212 {
213 *(op++)=yuv[0];
214 *(op++)=yuv[1];
215 op[1]=yuv[2];
216 }
217 else
218 {
219 *op=yuv[0];
220 op+=2;
221 }
222
223 p+=s->format->BytesPerPixel;
224 }
225 }
226
227 SDL_UnlockYUVOverlay(o);
228 SDL_UnlockSurface(s);
229 }
230
231 void Draw()
232 {
233 SDL_Rect rect;
234 int i;
235
236 if(!scale)
237 {
238 rect.w=overlay->w;
239 rect.h=overlay->h;
240 for(i=0; i<200; i++)
241 {
242 rect.x=i;
243 rect.y=i;
244 SDL_DisplayYUVOverlay(overlay,&rect);
245 }
246 }
247 else
248 {
249 rect.w=screen->w;
250 rect.h=screen->h;
251 for(i=0; i<200; i++)
252 {
253 rect.x=i-199;
254 rect.y=i-199;
255 SDL_DisplayYUVOverlay(overlay,&rect);
256 }
257 }
258 printf("Displayed %d times.\n",i);
259 }
260
261 int main(int argc, char **argv)
262 {
263 int flip;
264 int w, h;
265 int delay;
266 int desired_bpp;
267 Uint32 video_flags, overlay_format;
268 char *bmpfile;
269 #ifdef BENCHMARK_SDL
270 Uint32 then, now;
271 #endif
272 int i;
273
274 /* Set default options and check command-line */
275 flip = 0;
276 scale=0;
277 delay = 1;
278 w = 640;
279 h = 480;
280 desired_bpp = 0;
281 video_flags = 0;
282 overlay_format = SDL_YV12_OVERLAY;
283
284 while ( argc > 1 ) {
285 if ( strcmp(argv[1], "-delay") == 0 ) {
286 if ( argv[2] ) {
287 delay = atoi(argv[2]);
288 argv += 2;
289 argc -= 2;
290 } else {
291 fprintf(stderr,
292 "The -delay option requires an argument\n");
293 exit(1);
294 }
295 } else
296 if ( strcmp(argv[1], "-width") == 0 ) {
297 if ( argv[2] && ((w = atoi(argv[2])) > 0) ) {
298 argv += 2;
299 argc -= 2;
300 } else {
301 fprintf(stderr,
302 "The -width option requires an argument\n");
303 exit(1);
304 }
305 } else
306 if ( strcmp(argv[1], "-height") == 0 ) {
307 if ( argv[2] && ((h = atoi(argv[2])) > 0) ) {
308 argv += 2;
309 argc -= 2;
310 } else {
311 fprintf(stderr,
312 "The -height option requires an argument\n");
313 exit(1);
314 }
315 } else
316 if ( strcmp(argv[1], "-bpp") == 0 ) {
317 if ( argv[2] ) {
318 desired_bpp = atoi(argv[2]);
319 argv += 2;
320 argc -= 2;
321 } else {
322 fprintf(stderr,
323 "The -bpp option requires an argument\n");
324 exit(1);
325 }
326 } else
327 if ( strcmp(argv[1], "-format") == 0 ) {
328 if ( argv[2] ) {
329 if(!strcmp(argv[2],"YV12"))
330 overlay_format = SDL_YV12_OVERLAY;
331 else if(!strcmp(argv[2],"IYUV"))
332 overlay_format = SDL_IYUV_OVERLAY;
333 else if(!strcmp(argv[2],"YUY2"))
334 overlay_format = SDL_YUY2_OVERLAY;
335 else if(!strcmp(argv[2],"UYVY"))
336 overlay_format = SDL_UYVY_OVERLAY;
337 else if(!strcmp(argv[2],"YVYU"))
338 overlay_format = SDL_YVYU_OVERLAY;
339 else
340 {
341 fprintf(stderr, "The -format option %s is not recognized\n",argv[2]);
342 exit(1);
343 }
344 argv += 2;
345 argc -= 2;
346 } else {
347 fprintf(stderr,
348 "The -format option requires an argument\n");
349 exit(1);
350 }
351 } else
352 if ( strcmp(argv[1], "-hw") == 0 ) {
353 video_flags |= SDL_HWSURFACE;
354 argv += 1;
355 argc -= 1;
356 } else
357 if ( strcmp(argv[1], "-flip") == 0 ) {
358 video_flags |= SDL_DOUBLEBUF;
359 argv += 1;
360 argc -= 1;
361 } else
362 if ( strcmp(argv[1], "-scale") == 0 ) {
363 scale = 1;
364 argv += 1;
365 argc -= 1;
366 } else
367 if ( strcmp(argv[1], "-fullscreen") == 0 ) {
368 video_flags |= SDL_FULLSCREEN;
369 argv += 1;
370 argc -= 1;
371 } else
372 break;
373 }
374 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
375 fprintf(stderr,
376 "Couldn't initialize SDL: %s\n", SDL_GetError());
377 exit(1);
378 }
379 atexit(SDL_Quit); /* Clean up on exit */
380
381 /* Initialize the display */
382 screen = SDL_SetVideoMode(w, h, desired_bpp, video_flags);
383 if ( screen == NULL ) {
384 fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
385 w, h, desired_bpp, SDL_GetError());
386 exit(1);
387 }
388 printf("Set%s %dx%dx%d mode\n",
389 screen->flags & SDL_FULLSCREEN ? " fullscreen" : "",
390 screen->w, screen->h, screen->format->BitsPerPixel);
391 printf("(video surface located in %s memory)\n",
392 (screen->flags&SDL_HWSURFACE) ? "video" : "system");
393 if ( screen->flags & SDL_DOUBLEBUF ) {
394 printf("Double-buffering enabled\n");
395 flip = 1;
396 }
397
398 /* Set the window manager title bar */
399 SDL_WM_SetCaption("SDL test overlay", "testoverlay");
400
401 /* Load picture */
402 bmpfile=(argv[1]?argv[1]:"sample.bmp");
403 pic = SDL_LoadBMP(bmpfile);
404 if ( pic == NULL ) {
405 fprintf(stderr, "Couldn't load %s: %s\n", bmpfile,
406 SDL_GetError());
407 exit(1);
408 }
409
410 /* Convert the picture to 32bits, for easy conversion */
411 {
412 SDL_Surface *newsurf;
413 SDL_PixelFormat format;
414
415 format.palette=NULL;
416 format.BitsPerPixel=32;
417 format.BytesPerPixel=4;
418 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
419 format.Rshift=0;
420 format.Gshift=8;
421 format.Bshift=16;
422 #else
423 format.Rshift=24;
424 format.Gshift=16;
425 format.Bshift=8;
426 #endif
427 format.Ashift=0;
428 format.Rmask=0xff<<format.Rshift;
429 format.Gmask=0xff<<format.Gshift;
430 format.Bmask=0xff<<format.Bshift;
431 format.Amask=0;
432 format.Rloss=0;
433 format.Gloss=0;
434 format.Bloss=0;
435 format.Aloss=8;
436 format.colorkey=0;
437 format.alpha=0;
438
439 newsurf=SDL_ConvertSurface(pic, &format, SDL_SWSURFACE);
440 if(!newsurf)
441 {
442 fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n",
443 SDL_GetError());
444 exit(1);
445 }
446 SDL_FreeSurface(pic);
447 pic=newsurf;
448 }
449
450 /* Create the overlay */
451 overlay = SDL_CreateYUVOverlay(pic->w, pic->h, overlay_format, screen);
452 if ( overlay == NULL ) {
453 fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
454 exit(1);
455 }
456 printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes,
457 overlay->hw_overlay?"hardware":"software",
458 overlay->format==SDL_YV12_OVERLAY?"YV12":
459 overlay->format==SDL_IYUV_OVERLAY?"IYUV":
460 overlay->format==SDL_YUY2_OVERLAY?"YUY2":
461 overlay->format==SDL_UYVY_OVERLAY?"UYVY":
462 overlay->format==SDL_YVYU_OVERLAY?"YVYU":
463 "Unknown");
464 for(i=0; i<overlay->planes; i++)
465 {
466 printf(" plane %d: pitch=%d\n", i, overlay->pitches[i]);
467 }
468
469 /* Convert to YUV, and draw to the overlay */
470 #ifdef BENCHMARK_SDL
471 then = SDL_GetTicks();
472 #endif
473 switch(overlay->format)
474 {
475 case SDL_YV12_OVERLAY:
476 ConvertRGBtoYV12(pic,overlay);
477 break;
478 case SDL_UYVY_OVERLAY:
479 ConvertRGBtoUYVY(pic,overlay);
480 break;
481 case SDL_YVYU_OVERLAY:
482 ConvertRGBtoYVYU(pic,overlay);
483 break;
484 case SDL_YUY2_OVERLAY:
485 ConvertRGBtoYUY2(pic,overlay);
486 break;
487 case SDL_IYUV_OVERLAY:
488 ConvertRGBtoIYUV(pic,overlay);
489 break;
490 default:
491 printf("cannot convert RGB picture to obtained YUV format!\n");
492 exit(1);
493 break;
494 }
495 #ifdef BENCHMARK_SDL
496 now = SDL_GetTicks();
497 printf("Conversion Time: %d milliseconds\n", now-then);
498 #endif
499
500 /* Do all the drawing work */
501 #ifdef BENCHMARK_SDL
502 then = SDL_GetTicks();
503 #endif
504 Draw();
505 #ifdef BENCHMARK_SDL
506 now = SDL_GetTicks();
507 printf("Time: %d milliseconds\n", now-then);
508 #endif
509 SDL_Delay(delay*1000);
510 return(0);
511 }
512