Mercurial > sdl-ios-xcode
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 |