comparison test/testoverlay.c @ 1662:782fd950bd46 SDL-1.3

Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API. WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid. The code is now run through a consistent indent format: indent -i4 -nut -nsc -br -ce The headers are being converted to automatically generate doxygen documentation.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 28 May 2006 13:04:16 +0000
parents 4d3bb026cd16
children 4da1ee79c9af
comparison
equal deleted inserted replaced
1661:281d3f4870e5 1662:782fd950bd46
20 int monochrome; 20 int monochrome;
21 int luminance; 21 int luminance;
22 int w, h; 22 int w, h;
23 23
24 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 24 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
25 static void quit(int rc) 25 static void
26 { 26 quit (int rc)
27 SDL_Quit(); 27 {
28 exit(rc); 28 SDL_Quit ();
29 exit (rc);
29 } 30 }
30 31
31 /* NOTE: These RGB conversion functions are not intended for speed, 32 /* NOTE: These RGB conversion functions are not intended for speed,
32 only as examples. 33 only as examples.
33 */ 34 */
34 35
35 void RGBtoYUV(Uint8 *rgb, int *yuv, int monochrome, int luminance) 36 void
36 { 37 RGBtoYUV (Uint8 * rgb, int *yuv, int monochrome, int luminance)
37 if (monochrome) 38 {
38 { 39 if (monochrome) {
39 #if 1 /* these are the two formulas that I found on the FourCC site... */ 40 #if 1 /* these are the two formulas that I found on the FourCC site... */
40 yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2]; 41 yuv[0] = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2];
41 yuv[1] = 128; 42 yuv[1] = 128;
42 yuv[2] = 128; 43 yuv[2] = 128;
43 #else 44 #else
44 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16; 45 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
45 yuv[1] = 128; 46 yuv[1] = 128;
46 yuv[2] = 128; 47 yuv[2] = 128;
47 #endif 48 #endif
48 } 49 } else {
49 else 50 #if 1 /* these are the two formulas that I found on the FourCC site... */
50 { 51 yuv[0] = 0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2];
51 #if 1 /* these are the two formulas that I found on the FourCC site... */ 52 yuv[1] = (rgb[2] - yuv[0]) * 0.565 + 128;
52 yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2]; 53 yuv[2] = (rgb[0] - yuv[0]) * 0.713 + 128;
53 yuv[1] = (rgb[2]-yuv[0])*0.565 + 128;
54 yuv[2] = (rgb[0]-yuv[0])*0.713 + 128;
55 #else 54 #else
56 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16; 55 yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
57 yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]); 56 yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]);
58 yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]); 57 yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
59 #endif 58 #endif
60 } 59 }
61 60
62 if (luminance!=100) 61 if (luminance != 100) {
63 { 62 yuv[0] = yuv[0] * luminance / 100;
64 yuv[0]=yuv[0]*luminance/100; 63 if (yuv[0] > 255)
65 if (yuv[0]>255) 64 yuv[0] = 255;
66 yuv[0]=255;
67 } 65 }
68 66
69 /* clamp values...if you need to, we don't seem to have a need */ 67 /* clamp values...if you need to, we don't seem to have a need */
70 /* 68 /*
71 for(i=0;i<3;i++) 69 for(i=0;i<3;i++)
70 {
71 if(yuv[i]<0)
72 yuv[i]=0;
73 if(yuv[i]>255)
74 yuv[i]=255;
75 }
76 */
77 }
78
79 void
80 ConvertRGBtoYV12 (SDL_Surface * s, SDL_Overlay * o, int monochrome,
81 int luminance)
82 {
83 int x, y;
84 int yuv[3];
85 Uint8 *p, *op[3];
86
87 SDL_LockSurface (s);
88 SDL_LockYUVOverlay (o);
89
90 /* Black initialization */
91 /*
92 memset(o->pixels[0],0,o->pitches[0]*o->h);
93 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2));
94 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2));
95 */
96
97 /* Convert */
98 for (y = 0; y < s->h && y < o->h; y++) {
99 p = ((Uint8 *) s->pixels) + s->pitch * y;
100 op[0] = o->pixels[0] + o->pitches[0] * y;
101 op[1] = o->pixels[1] + o->pitches[1] * (y / 2);
102 op[2] = o->pixels[2] + o->pitches[2] * (y / 2);
103 for (x = 0; x < s->w && x < o->w; x++) {
104 RGBtoYUV (p, yuv, monochrome, luminance);
105 *(op[0]++) = yuv[0];
106 if (x % 2 == 0 && y % 2 == 0) {
107 *(op[1]++) = yuv[2];
108 *(op[2]++) = yuv[1];
109 }
110 p += s->format->BytesPerPixel;
111 }
112 }
113
114 SDL_UnlockYUVOverlay (o);
115 SDL_UnlockSurface (s);
116 }
117
118 void
119 ConvertRGBtoIYUV (SDL_Surface * s, SDL_Overlay * o, int monochrome,
120 int luminance)
121 {
122 int x, y;
123 int yuv[3];
124 Uint8 *p, *op[3];
125
126 SDL_LockSurface (s);
127 SDL_LockYUVOverlay (o);
128
129 /* Black initialization */
130 /*
131 memset(o->pixels[0],0,o->pitches[0]*o->h);
132 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2));
133 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2));
134 */
135
136 /* Convert */
137 for (y = 0; y < s->h && y < o->h; y++) {
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 RGBtoYUV (p, yuv, monochrome, luminance);
144 *(op[0]++) = yuv[0];
145 if (x % 2 == 0 && y % 2 == 0) {
146 *(op[1]++) = yuv[1];
147 *(op[2]++) = yuv[2];
148 }
149 p += s->format->BytesPerPixel;
150 }
151 }
152
153 SDL_UnlockYUVOverlay (o);
154 SDL_UnlockSurface (s);
155 }
156
157 void
158 ConvertRGBtoUYVY (SDL_Surface * s, SDL_Overlay * o, int monochrome,
159 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 p = ((Uint8 *) s->pixels) + s->pitch * y;
170 op = o->pixels[0] + o->pitches[0] * y;
171 for (x = 0; x < s->w && x < o->w; x++) {
172 RGBtoYUV (p, yuv, monochrome, luminance);
173 if (x % 2 == 0) {
174 *(op++) = yuv[1];
175 *(op++) = yuv[0];
176 *(op++) = yuv[2];
177 } else
178 *(op++) = yuv[0];
179
180 p += s->format->BytesPerPixel;
181 }
182 }
183
184 SDL_UnlockYUVOverlay (o);
185 SDL_UnlockSurface (s);
186 }
187
188 void
189 ConvertRGBtoYVYU (SDL_Surface * s, SDL_Overlay * o, int monochrome,
190 int luminance)
191 {
192 int x, y;
193 int yuv[3];
194 Uint8 *p, *op;
195
196 SDL_LockSurface (s);
197 SDL_LockYUVOverlay (o);
198
199 for (y = 0; y < s->h && y < o->h; y++) {
200 p = ((Uint8 *) s->pixels) + s->pitch * y;
201 op = o->pixels[0] + o->pitches[0] * y;
202 for (x = 0; x < s->w && x < o->w; x++) {
203 RGBtoYUV (p, yuv, monochrome, luminance);
204 if (x % 2 == 0) {
205 *(op++) = yuv[0];
206 *(op++) = yuv[2];
207 op[1] = yuv[1];
208 } else {
209 *op = yuv[0];
210 op += 2;
211 }
212
213 p += s->format->BytesPerPixel;
214 }
215 }
216
217 SDL_UnlockYUVOverlay (o);
218 SDL_UnlockSurface (s);
219 }
220
221 void
222 ConvertRGBtoYUY2 (SDL_Surface * s, SDL_Overlay * o, int monochrome,
223 int luminance)
224 {
225 int x, y;
226 int yuv[3];
227 Uint8 *p, *op;
228
229 SDL_LockSurface (s);
230 SDL_LockYUVOverlay (o);
231
232 for (y = 0; y < s->h && y < o->h; y++) {
233 p = ((Uint8 *) s->pixels) + s->pitch * y;
234 op = o->pixels[0] + o->pitches[0] * y;
235 for (x = 0; x < s->w && x < o->w; x++) {
236 RGBtoYUV (p, yuv, monochrome, luminance);
237 if (x % 2 == 0) {
238 *(op++) = yuv[0];
239 *(op++) = yuv[1];
240 op[1] = yuv[2];
241 } else {
242 *op = yuv[0];
243 op += 2;
244 }
245
246 p += s->format->BytesPerPixel;
247 }
248 }
249
250 SDL_UnlockYUVOverlay (o);
251 SDL_UnlockSurface (s);
252 }
253
254 void
255 Draw ()
256 {
257 SDL_Rect rect;
258 int i;
259 int disp;
260
261 if (!scale) {
262 rect.w = overlay->w;
263 rect.h = overlay->h;
264 for (i = 0; i < h - rect.h && i < w - rect.w; i++) {
265 rect.x = i;
266 rect.y = i;
267 SDL_DisplayYUVOverlay (overlay, &rect);
268 }
269 } else {
270 rect.w = overlay->w / 2;
271 rect.h = overlay->h / 2;
272 rect.x = (w - rect.w) / 2;
273 rect.y = (h - rect.h) / 2;
274 disp = rect.y - 1;
275 for (i = 0; i < disp; i++) {
276 rect.w += 2;
277 rect.h += 2;
278 rect.x--;
279 rect.y--;
280 SDL_DisplayYUVOverlay (overlay, &rect);
281 }
282 }
283 printf ("Displayed %d times.\n", i);
284 }
285
286 static void
287 PrintUsage (char *argv0)
288 {
289 fprintf (stderr, "Usage: %s [arg] [arg] [arg] ...\n", argv0);
290 fprintf (stderr, "Where 'arg' is one of:\n");
291 fprintf (stderr, " -delay <seconds>\n");
292 fprintf (stderr, " -width <pixels>\n");
293 fprintf (stderr, " -height <pixels>\n");
294 fprintf (stderr, " -bpp <bits>\n");
295 fprintf (stderr,
296 " -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n");
297 fprintf (stderr, " -hw\n");
298 fprintf (stderr, " -flip\n");
299 fprintf (stderr,
300 " -scale (test scaling features, from 50%% upto window size)\n");
301 fprintf (stderr, " -mono (use monochromatic RGB2YUV conversion)\n");
302 fprintf (stderr,
303 " -lum <perc> (use luminance correction during RGB2YUV conversion,\n");
304 fprintf (stderr,
305 " from 0%% to unlimited, normal is 100%%)\n");
306 fprintf (stderr, " -help (shows this help)\n");
307 fprintf (stderr, " -fullscreen (test overlay in fullscreen mode)\n");
308 }
309
310 int
311 main (int argc, char **argv)
312 {
313 char *argv0 = argv[0];
314 int flip;
315 int delay;
316 int desired_bpp;
317 Uint32 video_flags, overlay_format;
318 char *bmpfile;
319 #ifdef BENCHMARK_SDL
320 Uint32 then, now;
321 #endif
322 int i;
323
324 /* Set default options and check command-line */
325 flip = 0;
326 scale = 0;
327 monochrome = 0;
328 luminance = 100;
329 delay = 1;
330 w = WINDOW_WIDTH;
331 h = WINDOW_HEIGHT;
332 desired_bpp = 0;
333 video_flags = 0;
334 overlay_format = SDL_YV12_OVERLAY;
335
336 while (argc > 1) {
337 if (strcmp (argv[1], "-delay") == 0) {
338 if (argv[2]) {
339 delay = atoi (argv[2]);
340 argv += 2;
341 argc -= 2;
342 } else {
343 fprintf (stderr, "The -delay option requires an argument\n");
344 return (1);
345 }
346 } else if (strcmp (argv[1], "-width") == 0) {
347 if (argv[2] && ((w = atoi (argv[2])) > 0)) {
348 argv += 2;
349 argc -= 2;
350 } else {
351 fprintf (stderr, "The -width option requires an argument\n");
352 return (1);
353 }
354 } else if (strcmp (argv[1], "-height") == 0) {
355 if (argv[2] && ((h = atoi (argv[2])) > 0)) {
356 argv += 2;
357 argc -= 2;
358 } else {
359 fprintf (stderr, "The -height option requires an argument\n");
360 return (1);
361 }
362 } else if (strcmp (argv[1], "-bpp") == 0) {
363 if (argv[2]) {
364 desired_bpp = atoi (argv[2]);
365 argv += 2;
366 argc -= 2;
367 } else {
368 fprintf (stderr, "The -bpp option requires an argument\n");
369 return (1);
370 }
371 } else if (strcmp (argv[1], "-lum") == 0) {
372 if (argv[2]) {
373 luminance = atoi (argv[2]);
374 argv += 2;
375 argc -= 2;
376 } else {
377 fprintf (stderr, "The -lum option requires an argument\n");
378 return (1);
379 }
380 } else if (strcmp (argv[1], "-format") == 0) {
381 if (argv[2]) {
382 if (!strcmp (argv[2], "YV12"))
383 overlay_format = SDL_YV12_OVERLAY;
384 else if (!strcmp (argv[2], "IYUV"))
385 overlay_format = SDL_IYUV_OVERLAY;
386 else if (!strcmp (argv[2], "YUY2"))
387 overlay_format = SDL_YUY2_OVERLAY;
388 else if (!strcmp (argv[2], "UYVY"))
389 overlay_format = SDL_UYVY_OVERLAY;
390 else if (!strcmp (argv[2], "YVYU"))
391 overlay_format = SDL_YVYU_OVERLAY;
392 else {
393 fprintf (stderr,
394 "The -format option %s is not recognized\n",
395 argv[2]);
396 return (1);
397 }
398 argv += 2;
399 argc -= 2;
400 } else {
401 fprintf (stderr, "The -format option requires an argument\n");
402 return (1);
403 }
404 } else if (strcmp (argv[1], "-hw") == 0) {
405 video_flags |= SDL_HWSURFACE;
406 argv += 1;
407 argc -= 1;
408 } else if (strcmp (argv[1], "-flip") == 0) {
409 video_flags |= SDL_DOUBLEBUF;
410 argv += 1;
411 argc -= 1;
412 } else if (strcmp (argv[1], "-scale") == 0) {
413 scale = 1;
414 argv += 1;
415 argc -= 1;
416 } else if (strcmp (argv[1], "-mono") == 0) {
417 monochrome = 1;
418 argv += 1;
419 argc -= 1;
420 } else if ((strcmp (argv[1], "-help") == 0)
421 || (strcmp (argv[1], "-h") == 0)) {
422 PrintUsage (argv0);
423 return (1);
424 } else if (strcmp (argv[1], "-fullscreen") == 0) {
425 video_flags |= SDL_FULLSCREEN;
426 argv += 1;
427 argc -= 1;
428 } else
429 break;
430 }
431 if (SDL_Init (SDL_INIT_VIDEO) < 0) {
432 fprintf (stderr, "Couldn't initialize SDL: %s\n", SDL_GetError ());
433 return (1);
434 }
435
436 /* Initialize the display */
437 screen = SDL_SetVideoMode (w, h, desired_bpp, video_flags);
438 if (screen == NULL) {
439 fprintf (stderr, "Couldn't set %dx%dx%d video mode: %s\n",
440 w, h, desired_bpp, SDL_GetError ());
441 quit (1);
442 }
443 printf ("Set%s %dx%dx%d mode\n",
444 screen->flags & SDL_FULLSCREEN ? " fullscreen" : "",
445 screen->w, screen->h, screen->format->BitsPerPixel);
446 printf ("(video surface located in %s memory)\n",
447 (screen->flags & SDL_HWSURFACE) ? "video" : "system");
448 if (screen->flags & SDL_DOUBLEBUF) {
449 printf ("Double-buffering enabled\n");
450 flip = 1;
451 }
452
453 /* Set the window manager title bar */
454 SDL_WM_SetCaption ("SDL test overlay", "testoverlay");
455
456 /* Load picture */
457 bmpfile = (argv[1] ? argv[1] : "sample.bmp");
458 pic = SDL_LoadBMP (bmpfile);
459 if (pic == NULL) {
460 fprintf (stderr, "Couldn't load %s: %s\n", bmpfile, SDL_GetError ());
461 quit (1);
462 }
463
464 /* Convert the picture to 32bits, for easy conversion */
72 { 465 {
73 if(yuv[i]<0) 466 SDL_Surface *newsurf;
74 yuv[i]=0; 467 SDL_PixelFormat format;
75 if(yuv[i]>255) 468
76 yuv[i]=255; 469 format.palette = NULL;
77 } 470 format.BitsPerPixel = 32;
78 */ 471 format.BytesPerPixel = 4;
79 } 472 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
80 473 format.Rshift = 0;
81 void ConvertRGBtoYV12(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance) 474 format.Gshift = 8;
82 { 475 format.Bshift = 16;
83 int x,y; 476 #else
84 int yuv[3]; 477 format.Rshift = 24;
85 Uint8 *p,*op[3]; 478 format.Gshift = 16;
86 479 format.Bshift = 8;
87 SDL_LockSurface(s); 480 #endif
88 SDL_LockYUVOverlay(o); 481 format.Ashift = 0;
89 482 format.Rmask = 0xff << format.Rshift;
90 /* Black initialization */ 483 format.Gmask = 0xff << format.Gshift;
91 /* 484 format.Bmask = 0xff << format.Bshift;
92 memset(o->pixels[0],0,o->pitches[0]*o->h); 485 format.Amask = 0;
93 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2)); 486 format.Rloss = 0;
94 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2)); 487 format.Gloss = 0;
95 */ 488 format.Bloss = 0;
96 489 format.Aloss = 8;
97 /* Convert */ 490 format.colorkey = 0;
98 for(y=0; y<s->h && y<o->h; y++) 491 format.alpha = 0;
99 { 492
100 p=((Uint8 *) s->pixels)+s->pitch*y; 493 newsurf = SDL_ConvertSurface (pic, &format, SDL_SWSURFACE);
101 op[0]=o->pixels[0]+o->pitches[0]*y; 494 if (!newsurf) {
102 op[1]=o->pixels[1]+o->pitches[1]*(y/2); 495 fprintf (stderr, "Couldn't convert picture to 32bits RGB: %s\n",
103 op[2]=o->pixels[2]+o->pitches[2]*(y/2); 496 SDL_GetError ());
104 for(x=0; x<s->w && x<o->w; x++) 497 quit (1);
105 { 498 }
106 RGBtoYUV(p, yuv, monochrome, luminance); 499 SDL_FreeSurface (pic);
107 *(op[0]++)=yuv[0]; 500 pic = newsurf;
108 if(x%2==0 && y%2==0) 501 }
109 { 502
110 *(op[1]++)=yuv[2]; 503 /* Create the overlay */
111 *(op[2]++)=yuv[1]; 504 overlay = SDL_CreateYUVOverlay (pic->w, pic->h, overlay_format, screen);
112 } 505 if (overlay == NULL) {
113 p+=s->format->BytesPerPixel; 506 fprintf (stderr, "Couldn't create overlay: %s\n", SDL_GetError ());
114 } 507 quit (1);
115 } 508 }
116 509 printf ("Created %dx%dx%d %s %s overlay\n", overlay->w, overlay->h,
117 SDL_UnlockYUVOverlay(o); 510 overlay->planes, overlay->hw_overlay ? "hardware" : "software",
118 SDL_UnlockSurface(s); 511 overlay->format == SDL_YV12_OVERLAY ? "YV12" : overlay->format ==
119 } 512 SDL_IYUV_OVERLAY ? "IYUV" : overlay->format ==
120 513 SDL_YUY2_OVERLAY ? "YUY2" : overlay->format ==
121 void ConvertRGBtoIYUV(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance) 514 SDL_UYVY_OVERLAY ? "UYVY" : overlay->format ==
122 { 515 SDL_YVYU_OVERLAY ? "YVYU" : "Unknown");
123 int x,y; 516 for (i = 0; i < overlay->planes; i++) {
124 int yuv[3]; 517 printf (" plane %d: pitch=%d\n", i, overlay->pitches[i]);
125 Uint8 *p,*op[3]; 518 }
126 519
127 SDL_LockSurface(s); 520 /* Convert to YUV, and draw to the overlay */
128 SDL_LockYUVOverlay(o);
129
130 /* Black initialization */
131 /*
132 memset(o->pixels[0],0,o->pitches[0]*o->h);
133 memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2));
134 memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2));
135 */
136
137 /* Convert */
138 for(y=0; y<s->h && y<o->h; y++)
139 {
140 p=((Uint8 *) s->pixels)+s->pitch*y;
141 op[0]=o->pixels[0]+o->pitches[0]*y;
142 op[1]=o->pixels[1]+o->pitches[1]*(y/2);
143 op[2]=o->pixels[2]+o->pitches[2]*(y/2);
144 for(x=0; x<s->w && x<o->w; x++)
145 {
146 RGBtoYUV(p,yuv, monochrome, luminance);
147 *(op[0]++)=yuv[0];
148 if(x%2==0 && y%2==0)
149 {
150 *(op[1]++)=yuv[1];
151 *(op[2]++)=yuv[2];
152 }
153 p+=s->format->BytesPerPixel;
154 }
155 }
156
157 SDL_UnlockYUVOverlay(o);
158 SDL_UnlockSurface(s);
159 }
160
161 void ConvertRGBtoUYVY(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
162 {
163 int x,y;
164 int yuv[3];
165 Uint8 *p,*op;
166
167 SDL_LockSurface(s);
168 SDL_LockYUVOverlay(o);
169
170 for(y=0; y<s->h && y<o->h; y++)
171 {
172 p=((Uint8 *) s->pixels)+s->pitch*y;
173 op=o->pixels[0]+o->pitches[0]*y;
174 for(x=0; x<s->w && x<o->w; x++)
175 {
176 RGBtoYUV(p, yuv, monochrome, luminance);
177 if(x%2==0)
178 {
179 *(op++)=yuv[1];
180 *(op++)=yuv[0];
181 *(op++)=yuv[2];
182 }
183 else
184 *(op++)=yuv[0];
185
186 p+=s->format->BytesPerPixel;
187 }
188 }
189
190 SDL_UnlockYUVOverlay(o);
191 SDL_UnlockSurface(s);
192 }
193
194 void ConvertRGBtoYVYU(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
195 {
196 int x,y;
197 int yuv[3];
198 Uint8 *p,*op;
199
200 SDL_LockSurface(s);
201 SDL_LockYUVOverlay(o);
202
203 for(y=0; y<s->h && y<o->h; y++)
204 {
205 p=((Uint8 *) s->pixels)+s->pitch*y;
206 op=o->pixels[0]+o->pitches[0]*y;
207 for(x=0; x<s->w && x<o->w; x++)
208 {
209 RGBtoYUV(p,yuv, monochrome, luminance);
210 if(x%2==0)
211 {
212 *(op++)=yuv[0];
213 *(op++)=yuv[2];
214 op[1]=yuv[1];
215 }
216 else
217 {
218 *op=yuv[0];
219 op+=2;
220 }
221
222 p+=s->format->BytesPerPixel;
223 }
224 }
225
226 SDL_UnlockYUVOverlay(o);
227 SDL_UnlockSurface(s);
228 }
229
230 void ConvertRGBtoYUY2(SDL_Surface *s, SDL_Overlay *o, int monochrome, int luminance)
231 {
232 int x,y;
233 int yuv[3];
234 Uint8 *p,*op;
235
236 SDL_LockSurface(s);
237 SDL_LockYUVOverlay(o);
238
239 for(y=0; y<s->h && y<o->h; y++)
240 {
241 p=((Uint8 *) s->pixels)+s->pitch*y;
242 op=o->pixels[0]+o->pitches[0]*y;
243 for(x=0; x<s->w && x<o->w; x++)
244 {
245 RGBtoYUV(p,yuv, monochrome, luminance);
246 if(x%2==0)
247 {
248 *(op++)=yuv[0];
249 *(op++)=yuv[1];
250 op[1]=yuv[2];
251 }
252 else
253 {
254 *op=yuv[0];
255 op+=2;
256 }
257
258 p+=s->format->BytesPerPixel;
259 }
260 }
261
262 SDL_UnlockYUVOverlay(o);
263 SDL_UnlockSurface(s);
264 }
265
266 void Draw()
267 {
268 SDL_Rect rect;
269 int i;
270 int disp;
271
272 if(!scale)
273 {
274 rect.w=overlay->w;
275 rect.h=overlay->h;
276 for(i=0; i<h-rect.h && i<w-rect.w; i++)
277 {
278 rect.x=i;
279 rect.y=i;
280 SDL_DisplayYUVOverlay(overlay,&rect);
281 }
282 }
283 else
284 {
285 rect.w=overlay->w/2;
286 rect.h=overlay->h/2;
287 rect.x=(w-rect.w)/2;
288 rect.y=(h-rect.h)/2;
289 disp=rect.y-1;
290 for(i=0; i<disp; i++)
291 {
292 rect.w+=2;
293 rect.h+=2;
294 rect.x--;
295 rect.y--;
296 SDL_DisplayYUVOverlay(overlay,&rect);
297 }
298 }
299 printf("Displayed %d times.\n",i);
300 }
301
302 static void PrintUsage(char *argv0)
303 {
304 fprintf(stderr, "Usage: %s [arg] [arg] [arg] ...\n", argv0);
305 fprintf(stderr, "Where 'arg' is one of:\n");
306 fprintf(stderr, " -delay <seconds>\n");
307 fprintf(stderr, " -width <pixels>\n");
308 fprintf(stderr, " -height <pixels>\n");
309 fprintf(stderr, " -bpp <bits>\n");
310 fprintf(stderr, " -format <fmt> (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n");
311 fprintf(stderr, " -hw\n");
312 fprintf(stderr, " -flip\n");
313 fprintf(stderr, " -scale (test scaling features, from 50%% upto window size)\n");
314 fprintf(stderr, " -mono (use monochromatic RGB2YUV conversion)\n");
315 fprintf(stderr, " -lum <perc> (use luminance correction during RGB2YUV conversion,\n");
316 fprintf(stderr, " from 0%% to unlimited, normal is 100%%)\n");
317 fprintf(stderr, " -help (shows this help)\n");
318 fprintf(stderr, " -fullscreen (test overlay in fullscreen mode)\n");
319 }
320
321 int main(int argc, char **argv)
322 {
323 char *argv0 = argv[0];
324 int flip;
325 int delay;
326 int desired_bpp;
327 Uint32 video_flags, overlay_format;
328 char *bmpfile;
329 #ifdef BENCHMARK_SDL 521 #ifdef BENCHMARK_SDL
330 Uint32 then, now; 522 then = SDL_GetTicks ();
331 #endif 523 #endif
332 int i; 524 switch (overlay->format) {
333 525 case SDL_YV12_OVERLAY:
334 /* Set default options and check command-line */ 526 ConvertRGBtoYV12 (pic, overlay, monochrome, luminance);
335 flip = 0; 527 break;
336 scale=0; 528 case SDL_UYVY_OVERLAY:
337 monochrome=0; 529 ConvertRGBtoUYVY (pic, overlay, monochrome, luminance);
338 luminance=100; 530 break;
339 delay = 1; 531 case SDL_YVYU_OVERLAY:
340 w = WINDOW_WIDTH; 532 ConvertRGBtoYVYU (pic, overlay, monochrome, luminance);
341 h = WINDOW_HEIGHT; 533 break;
342 desired_bpp = 0; 534 case SDL_YUY2_OVERLAY:
343 video_flags = 0; 535 ConvertRGBtoYUY2 (pic, overlay, monochrome, luminance);
344 overlay_format = SDL_YV12_OVERLAY; 536 break;
345 537 case SDL_IYUV_OVERLAY:
346 while ( argc > 1 ) { 538 ConvertRGBtoIYUV (pic, overlay, monochrome, luminance);
347 if ( strcmp(argv[1], "-delay") == 0 ) { 539 break;
348 if ( argv[2] ) { 540 default:
349 delay = atoi(argv[2]); 541 printf ("cannot convert RGB picture to obtained YUV format!\n");
350 argv += 2; 542 quit (1);
351 argc -= 2; 543 break;
352 } else { 544 }
353 fprintf(stderr,
354 "The -delay option requires an argument\n");
355 return(1);
356 }
357 } else
358 if ( strcmp(argv[1], "-width") == 0 ) {
359 if ( argv[2] && ((w = atoi(argv[2])) > 0) ) {
360 argv += 2;
361 argc -= 2;
362 } else {
363 fprintf(stderr,
364 "The -width option requires an argument\n");
365 return(1);
366 }
367 } else
368 if ( strcmp(argv[1], "-height") == 0 ) {
369 if ( argv[2] && ((h = atoi(argv[2])) > 0) ) {
370 argv += 2;
371 argc -= 2;
372 } else {
373 fprintf(stderr,
374 "The -height option requires an argument\n");
375 return(1);
376 }
377 } else
378 if ( strcmp(argv[1], "-bpp") == 0 ) {
379 if ( argv[2] ) {
380 desired_bpp = atoi(argv[2]);
381 argv += 2;
382 argc -= 2;
383 } else {
384 fprintf(stderr,
385 "The -bpp option requires an argument\n");
386 return(1);
387 }
388 } else
389 if ( strcmp(argv[1], "-lum") == 0 ) {
390 if ( argv[2] ) {
391 luminance = atoi(argv[2]);
392 argv += 2;
393 argc -= 2;
394 } else {
395 fprintf(stderr,
396 "The -lum option requires an argument\n");
397 return(1);
398 }
399 } else
400 if ( strcmp(argv[1], "-format") == 0 ) {
401 if ( argv[2] ) {
402 if(!strcmp(argv[2],"YV12"))
403 overlay_format = SDL_YV12_OVERLAY;
404 else if(!strcmp(argv[2],"IYUV"))
405 overlay_format = SDL_IYUV_OVERLAY;
406 else if(!strcmp(argv[2],"YUY2"))
407 overlay_format = SDL_YUY2_OVERLAY;
408 else if(!strcmp(argv[2],"UYVY"))
409 overlay_format = SDL_UYVY_OVERLAY;
410 else if(!strcmp(argv[2],"YVYU"))
411 overlay_format = SDL_YVYU_OVERLAY;
412 else
413 {
414 fprintf(stderr, "The -format option %s is not recognized\n",argv[2]);
415 return(1);
416 }
417 argv += 2;
418 argc -= 2;
419 } else {
420 fprintf(stderr,
421 "The -format option requires an argument\n");
422 return(1);
423 }
424 } else
425 if ( strcmp(argv[1], "-hw") == 0 ) {
426 video_flags |= SDL_HWSURFACE;
427 argv += 1;
428 argc -= 1;
429 } else
430 if ( strcmp(argv[1], "-flip") == 0 ) {
431 video_flags |= SDL_DOUBLEBUF;
432 argv += 1;
433 argc -= 1;
434 } else
435 if ( strcmp(argv[1], "-scale") == 0 ) {
436 scale = 1;
437 argv += 1;
438 argc -= 1;
439 } else
440 if ( strcmp(argv[1], "-mono") == 0 ) {
441 monochrome = 1;
442 argv += 1;
443 argc -= 1;
444 } else
445 if (( strcmp(argv[1], "-help") == 0 ) || (strcmp(argv[1], "-h") == 0)) {
446 PrintUsage(argv0);
447 return(1);
448 } else
449 if ( strcmp(argv[1], "-fullscreen") == 0 ) {
450 video_flags |= SDL_FULLSCREEN;
451 argv += 1;
452 argc -= 1;
453 } else
454 break;
455 }
456 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
457 fprintf(stderr,
458 "Couldn't initialize SDL: %s\n", SDL_GetError());
459 return(1);
460 }
461
462 /* Initialize the display */
463 screen = SDL_SetVideoMode(w, h, desired_bpp, video_flags);
464 if ( screen == NULL ) {
465 fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
466 w, h, desired_bpp, SDL_GetError());
467 quit(1);
468 }
469 printf("Set%s %dx%dx%d mode\n",
470 screen->flags & SDL_FULLSCREEN ? " fullscreen" : "",
471 screen->w, screen->h, screen->format->BitsPerPixel);
472 printf("(video surface located in %s memory)\n",
473 (screen->flags&SDL_HWSURFACE) ? "video" : "system");
474 if ( screen->flags & SDL_DOUBLEBUF ) {
475 printf("Double-buffering enabled\n");
476 flip = 1;
477 }
478
479 /* Set the window manager title bar */
480 SDL_WM_SetCaption("SDL test overlay", "testoverlay");
481
482 /* Load picture */
483 bmpfile=(argv[1]?argv[1]:"sample.bmp");
484 pic = SDL_LoadBMP(bmpfile);
485 if ( pic == NULL ) {
486 fprintf(stderr, "Couldn't load %s: %s\n", bmpfile,
487 SDL_GetError());
488 quit(1);
489 }
490
491 /* Convert the picture to 32bits, for easy conversion */
492 {
493 SDL_Surface *newsurf;
494 SDL_PixelFormat format;
495
496 format.palette=NULL;
497 format.BitsPerPixel=32;
498 format.BytesPerPixel=4;
499 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
500 format.Rshift=0;
501 format.Gshift=8;
502 format.Bshift=16;
503 #else
504 format.Rshift=24;
505 format.Gshift=16;
506 format.Bshift=8;
507 #endif
508 format.Ashift=0;
509 format.Rmask=0xff<<format.Rshift;
510 format.Gmask=0xff<<format.Gshift;
511 format.Bmask=0xff<<format.Bshift;
512 format.Amask=0;
513 format.Rloss=0;
514 format.Gloss=0;
515 format.Bloss=0;
516 format.Aloss=8;
517 format.colorkey=0;
518 format.alpha=0;
519
520 newsurf=SDL_ConvertSurface(pic, &format, SDL_SWSURFACE);
521 if(!newsurf)
522 {
523 fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n",
524 SDL_GetError());
525 quit(1);
526 }
527 SDL_FreeSurface(pic);
528 pic=newsurf;
529 }
530
531 /* Create the overlay */
532 overlay = SDL_CreateYUVOverlay(pic->w, pic->h, overlay_format, screen);
533 if ( overlay == NULL ) {
534 fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
535 quit(1);
536 }
537 printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes,
538 overlay->hw_overlay?"hardware":"software",
539 overlay->format==SDL_YV12_OVERLAY?"YV12":
540 overlay->format==SDL_IYUV_OVERLAY?"IYUV":
541 overlay->format==SDL_YUY2_OVERLAY?"YUY2":
542 overlay->format==SDL_UYVY_OVERLAY?"UYVY":
543 overlay->format==SDL_YVYU_OVERLAY?"YVYU":
544 "Unknown");
545 for(i=0; i<overlay->planes; i++)
546 {
547 printf(" plane %d: pitch=%d\n", i, overlay->pitches[i]);
548 }
549
550 /* Convert to YUV, and draw to the overlay */
551 #ifdef BENCHMARK_SDL 545 #ifdef BENCHMARK_SDL
552 then = SDL_GetTicks(); 546 now = SDL_GetTicks ();
553 #endif 547 printf ("Conversion Time: %d milliseconds\n", now - then);
554 switch(overlay->format) 548 #endif
555 { 549
556 case SDL_YV12_OVERLAY: 550 /* Do all the drawing work */
557 ConvertRGBtoYV12(pic,overlay,monochrome,luminance);
558 break;
559 case SDL_UYVY_OVERLAY:
560 ConvertRGBtoUYVY(pic,overlay,monochrome,luminance);
561 break;
562 case SDL_YVYU_OVERLAY:
563 ConvertRGBtoYVYU(pic,overlay,monochrome,luminance);
564 break;
565 case SDL_YUY2_OVERLAY:
566 ConvertRGBtoYUY2(pic,overlay,monochrome,luminance);
567 break;
568 case SDL_IYUV_OVERLAY:
569 ConvertRGBtoIYUV(pic,overlay,monochrome,luminance);
570 break;
571 default:
572 printf("cannot convert RGB picture to obtained YUV format!\n");
573 quit(1);
574 break;
575 }
576 #ifdef BENCHMARK_SDL 551 #ifdef BENCHMARK_SDL
577 now = SDL_GetTicks(); 552 then = SDL_GetTicks ();
578 printf("Conversion Time: %d milliseconds\n", now-then); 553 #endif
579 #endif 554 Draw ();
580
581 /* Do all the drawing work */
582 #ifdef BENCHMARK_SDL 555 #ifdef BENCHMARK_SDL
583 then = SDL_GetTicks(); 556 now = SDL_GetTicks ();
584 #endif 557 printf ("Time: %d milliseconds\n", now - then);
585 Draw(); 558 #endif
586 #ifdef BENCHMARK_SDL 559 SDL_Delay (delay * 1000);
587 now = SDL_GetTicks(); 560 SDL_Quit ();
588 printf("Time: %d milliseconds\n", now-then); 561 return (0);
589 #endif 562 }
590 SDL_Delay(delay*1000);
591 SDL_Quit();
592 return(0);
593 }
594