2 /* Bring up a window and play with it */
10 #define NOTICE(X) printf("%s", X);
12 #define WINDOW_WIDTH 640
13 #define WINDOW_HEIGHT 480
17 SDL_Surface
*screen
, *pic
;
24 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
25 static void quit(int rc
)
31 /* NOTE: These RGB conversion functions are not intended for speed,
35 void RGBtoYUV(Uint8
*rgb
, int *yuv
, int monochrome
, int luminance
)
39 #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];
44 yuv
[0] = (0.257 * rgb
[0]) + (0.504 * rgb
[1]) + (0.098 * rgb
[2]) + 16;
51 #if 1 /* these are the two formulas that I found on the FourCC site... */
52 yuv
[0] = 0.299*rgb
[0] + 0.587*rgb
[1] + 0.114*rgb
[2];
53 yuv
[1] = (rgb
[2]-yuv
[0])*0.565 + 128;
54 yuv
[2] = (rgb
[0]-yuv
[0])*0.713 + 128;
56 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]);
58 yuv
[2] = 128 + (0.439 * rgb
[0]) - (0.368 * rgb
[1]) - (0.071 * rgb
[2]);
64 yuv
[0]=yuv
[0]*luminance
/100;
69 /* clamp values...if you need to, we don't seem to have a need */
81 void ConvertRGBtoYV12(SDL_Surface
*s
, SDL_Overlay
*o
, int monochrome
, int luminance
)
88 SDL_LockYUVOverlay(o
);
90 /* Black initialization */
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));
98 for(y
=0; y
<s
->h
&& y
<o
->h
; y
++)
100 p
=((Uint8
*) s
->pixels
)+s
->pitch
*y
;
101 op
[0]=o
->pixels
[0]+o
->pitches
[0]*y
;
102 op
[1]=o
->pixels
[1]+o
->pitches
[1]*(y
/2);
103 op
[2]=o
->pixels
[2]+o
->pitches
[2]*(y
/2);
104 for(x
=0; x
<s
->w
&& x
<o
->w
; x
++)
106 RGBtoYUV(p
, yuv
, monochrome
, luminance
);
113 p
+=s
->format
->BytesPerPixel
;
117 SDL_UnlockYUVOverlay(o
);
118 SDL_UnlockSurface(s
);
121 void ConvertRGBtoIYUV(SDL_Surface
*s
, SDL_Overlay
*o
, int monochrome
, int luminance
)
128 SDL_LockYUVOverlay(o
);
130 /* Black initialization */
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));
138 for(y
=0; y
<s
->h
&& y
<o
->h
; y
++)
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
++)
146 RGBtoYUV(p
,yuv
, monochrome
, luminance
);
153 p
+=s
->format
->BytesPerPixel
;
157 SDL_UnlockYUVOverlay(o
);
158 SDL_UnlockSurface(s
);
161 void ConvertRGBtoUYVY(SDL_Surface
*s
, SDL_Overlay
*o
, int monochrome
, int luminance
)
168 SDL_LockYUVOverlay(o
);
170 for(y
=0; y
<s
->h
&& y
<o
->h
; y
++)
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
++)
176 RGBtoYUV(p
, yuv
, monochrome
, luminance
);
186 p
+=s
->format
->BytesPerPixel
;
190 SDL_UnlockYUVOverlay(o
);
191 SDL_UnlockSurface(s
);
194 void ConvertRGBtoYVYU(SDL_Surface
*s
, SDL_Overlay
*o
, int monochrome
, int luminance
)
201 SDL_LockYUVOverlay(o
);
203 for(y
=0; y
<s
->h
&& y
<o
->h
; y
++)
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
++)
209 RGBtoYUV(p
,yuv
, monochrome
, luminance
);
222 p
+=s
->format
->BytesPerPixel
;
226 SDL_UnlockYUVOverlay(o
);
227 SDL_UnlockSurface(s
);
230 void ConvertRGBtoYUY2(SDL_Surface
*s
, SDL_Overlay
*o
, int monochrome
, int luminance
)
237 SDL_LockYUVOverlay(o
);
239 for(y
=0; y
<s
->h
&& y
<o
->h
; y
++)
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
++)
245 RGBtoYUV(p
,yuv
, monochrome
, luminance
);
258 p
+=s
->format
->BytesPerPixel
;
262 SDL_UnlockYUVOverlay(o
);
263 SDL_UnlockSurface(s
);
276 for(i
=0; i
<h
-rect
.h
&& i
<w
-rect
.w
; i
++)
280 SDL_DisplayYUVOverlay(overlay
,&rect
);
290 for(i
=0; i
<disp
; i
++)
296 SDL_DisplayYUVOverlay(overlay
,&rect
);
299 printf("Displayed %d times.\n",i
);
302 static void PrintUsage(char *argv0
)
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");
321 int main(int argc
, char **argv
)
323 char *argv0
= argv
[0];
327 Uint32 video_flags
, overlay_format
;
334 /* Set default options and check command-line */
344 overlay_format
= SDL_YV12_OVERLAY
;
347 if ( strcmp(argv
[1], "-delay") == 0 ) {
349 delay
= atoi(argv
[2]);
354 "The -delay option requires an argument\n");
358 if ( strcmp(argv
[1], "-width") == 0 ) {
359 if ( argv
[2] && ((w
= atoi(argv
[2])) > 0) ) {
364 "The -width option requires an argument\n");
368 if ( strcmp(argv
[1], "-height") == 0 ) {
369 if ( argv
[2] && ((h
= atoi(argv
[2])) > 0) ) {
374 "The -height option requires an argument\n");
378 if ( strcmp(argv
[1], "-bpp") == 0 ) {
380 desired_bpp
= atoi(argv
[2]);
385 "The -bpp option requires an argument\n");
389 if ( strcmp(argv
[1], "-lum") == 0 ) {
391 luminance
= atoi(argv
[2]);
396 "The -lum option requires an argument\n");
400 if ( strcmp(argv
[1], "-format") == 0 ) {
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
;
414 fprintf(stderr
, "The -format option %s is not recognized\n",argv
[2]);
421 "The -format option requires an argument\n");
425 if ( strcmp(argv
[1], "-hw") == 0 ) {
426 video_flags
|= SDL_HWSURFACE
;
430 if ( strcmp(argv
[1], "-flip") == 0 ) {
431 video_flags
|= SDL_DOUBLEBUF
;
435 if ( strcmp(argv
[1], "-scale") == 0 ) {
440 if ( strcmp(argv
[1], "-mono") == 0 ) {
445 if (( strcmp(argv
[1], "-help") == 0 ) || (strcmp(argv
[1], "-h") == 0)) {
449 if ( strcmp(argv
[1], "-fullscreen") == 0 ) {
450 video_flags
|= SDL_FULLSCREEN
;
456 if ( SDL_Init(SDL_INIT_VIDEO
) < 0 ) {
458 "Couldn't initialize SDL: %s\n", SDL_GetError());
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());
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");
479 /* Set the window manager title bar */
480 SDL_WM_SetCaption("SDL test overlay", "testoverlay");
483 bmpfile
=(argv
[1]?argv
[1]:"sample.bmp");
484 pic
= SDL_LoadBMP(bmpfile
);
486 fprintf(stderr
, "Couldn't load %s: %s\n", bmpfile
,
491 /* Convert the picture to 32bits, for easy conversion */
493 SDL_Surface
*newsurf
;
494 SDL_PixelFormat format
;
497 format
.BitsPerPixel
=32;
498 format
.BytesPerPixel
=4;
499 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
509 format
.Rmask
=0xff<<format
.Rshift
;
510 format
.Gmask
=0xff<<format
.Gshift
;
511 format
.Bmask
=0xff<<format
.Bshift
;
520 newsurf
=SDL_ConvertSurface(pic
, &format
, SDL_SWSURFACE
);
523 fprintf(stderr
, "Couldn't convert picture to 32bits RGB: %s\n",
527 SDL_FreeSurface(pic
);
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());
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":
545 for(i
=0; i
<overlay
->planes
; i
++)
547 printf(" plane %d: pitch=%d\n", i
, overlay
->pitches
[i
]);
550 /* Convert to YUV, and draw to the overlay */
552 then
= SDL_GetTicks();
554 switch(overlay
->format
)
556 case SDL_YV12_OVERLAY
:
557 ConvertRGBtoYV12(pic
,overlay
,monochrome
,luminance
);
559 case SDL_UYVY_OVERLAY
:
560 ConvertRGBtoUYVY(pic
,overlay
,monochrome
,luminance
);
562 case SDL_YVYU_OVERLAY
:
563 ConvertRGBtoYVYU(pic
,overlay
,monochrome
,luminance
);
565 case SDL_YUY2_OVERLAY
:
566 ConvertRGBtoYUY2(pic
,overlay
,monochrome
,luminance
);
568 case SDL_IYUV_OVERLAY
:
569 ConvertRGBtoIYUV(pic
,overlay
,monochrome
,luminance
);
572 printf("cannot convert RGB picture to obtained YUV format!\n");
577 now
= SDL_GetTicks();
578 printf("Conversion Time: %d milliseconds\n", now
-then
);
581 /* Do all the drawing work */
583 then
= SDL_GetTicks();
587 now
= SDL_GetTicks();
588 printf("Time: %d milliseconds\n", now
-then
);
590 SDL_Delay(delay
*1000);