test/testoverlay.c
changeset 277 255c7ee077cb
child 569 e8063c656626
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/test/testoverlay.c	Thu Feb 14 00:47:46 2002 +0000
     1.3 @@ -0,0 +1,512 @@
     1.4 +
     1.5 +/* Bring up a window and play with it */
     1.6 +
     1.7 +#include <stdlib.h>
     1.8 +#include <stdio.h>
     1.9 +#include <string.h>
    1.10 +
    1.11 +#define BENCHMARK_SDL
    1.12 +
    1.13 +#define NOTICE(X)	printf("%s", X);
    1.14 +
    1.15 +#include "SDL.h"
    1.16 +
    1.17 +SDL_Surface *screen, *pic;
    1.18 +SDL_Overlay *overlay;
    1.19 +int scale;
    1.20 +
    1.21 +/* NOTE: These RGB conversion functions are not intended for speed,
    1.22 +         only as examples.
    1.23 +*/
    1.24 +
    1.25 +void RGBtoYUV(Uint8 *rgb, int *yuv)
    1.26 +{
    1.27 +	int i;
    1.28 +#if 1 /* these are the two formulas that I found on the FourCC site... */
    1.29 +	yuv[0] = 0.299*rgb[0] + 0.587*rgb[1] + 0.114*rgb[2];
    1.30 +	yuv[1] = (rgb[2]-yuv[0])*0.565 + 128;
    1.31 +	yuv[2] = (rgb[0]-yuv[0])*0.713 + 128;
    1.32 +#else
    1.33 +	yuv[0] = (0.257 * rgb[0]) + (0.504 * rgb[1]) + (0.098 * rgb[2]) + 16;
    1.34 +	yuv[1] = 128 - (0.148 * rgb[0]) - (0.291 * rgb[1]) + (0.439 * rgb[2]);
    1.35 +	yuv[2] = 128 + (0.439 * rgb[0]) - (0.368 * rgb[1]) - (0.071 * rgb[2]);
    1.36 +#endif
    1.37 +	/* clamp values...if you need to, we don't seem to have a need */
    1.38 +	/*
    1.39 +	for(i=0;i<3;i++)
    1.40 +	{
    1.41 +		if(yuv[i]<0)
    1.42 +			yuv[i]=0;
    1.43 +		if(yuv[i]>255)
    1.44 +			yuv[i]=255;
    1.45 +	}
    1.46 +	*/
    1.47 +}
    1.48 +
    1.49 +ConvertRGBtoYV12(SDL_Surface *s, SDL_Overlay *o)
    1.50 +{
    1.51 +	int x,y;
    1.52 +	int yuv[3];
    1.53 +	Uint8 *p,*op[3];
    1.54 +
    1.55 +	SDL_LockSurface(s);
    1.56 +	SDL_LockYUVOverlay(o);
    1.57 +
    1.58 +	/* Black initialization */
    1.59 +	/*
    1.60 +	memset(o->pixels[0],0,o->pitches[0]*o->h);
    1.61 +	memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2));
    1.62 +	memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2));
    1.63 +	*/
    1.64 +
    1.65 +	/* Convert */
    1.66 +	for(y=0; y<s->h && y<o->h; y++)
    1.67 +	{
    1.68 +		p=s->pixels+s->pitch*y;
    1.69 +		op[0]=o->pixels[0]+o->pitches[0]*y;
    1.70 +		op[1]=o->pixels[1]+o->pitches[1]*(y/2);
    1.71 +		op[2]=o->pixels[2]+o->pitches[2]*(y/2);
    1.72 +		for(x=0; x<s->w && x<o->w; x++)
    1.73 +		{
    1.74 +			RGBtoYUV(p,yuv);
    1.75 +			*(op[0]++)=yuv[0];
    1.76 +			if(x%2==0 && y%2==0)
    1.77 +			{
    1.78 +				*(op[1]++)=yuv[2];
    1.79 +				*(op[2]++)=yuv[1];
    1.80 +			}
    1.81 +			p+=s->format->BytesPerPixel;
    1.82 +		}
    1.83 +	}
    1.84 +
    1.85 +	SDL_UnlockYUVOverlay(o);
    1.86 +	SDL_UnlockSurface(s);
    1.87 +}
    1.88 +
    1.89 +ConvertRGBtoIYUV(SDL_Surface *s, SDL_Overlay *o)
    1.90 +{
    1.91 +	int x,y;
    1.92 +	int yuv[3];
    1.93 +	Uint8 *p,*op[3];
    1.94 +
    1.95 +	SDL_LockSurface(s);
    1.96 +	SDL_LockYUVOverlay(o);
    1.97 +
    1.98 +	/* Black initialization */
    1.99 +	/*
   1.100 +	memset(o->pixels[0],0,o->pitches[0]*o->h);
   1.101 +	memset(o->pixels[1],128,o->pitches[1]*((o->h+1)/2));
   1.102 +	memset(o->pixels[2],128,o->pitches[2]*((o->h+1)/2));
   1.103 +	*/
   1.104 +
   1.105 +	/* Convert */
   1.106 +	for(y=0; y<s->h && y<o->h; y++)
   1.107 +	{
   1.108 +		p=s->pixels+s->pitch*y;
   1.109 +		op[0]=o->pixels[0]+o->pitches[0]*y;
   1.110 +		op[1]=o->pixels[1]+o->pitches[1]*(y/2);
   1.111 +		op[2]=o->pixels[2]+o->pitches[2]*(y/2);
   1.112 +		for(x=0; x<s->w && x<o->w; x++)
   1.113 +		{
   1.114 +			RGBtoYUV(p,yuv);
   1.115 +			*(op[0]++)=yuv[0];
   1.116 +			if(x%2==0 && y%2==0)
   1.117 +			{
   1.118 +				*(op[1]++)=yuv[1];
   1.119 +				*(op[2]++)=yuv[2];
   1.120 +			}
   1.121 +			p+=s->format->BytesPerPixel;
   1.122 +		}
   1.123 +	}
   1.124 +
   1.125 +	SDL_UnlockYUVOverlay(o);
   1.126 +	SDL_UnlockSurface(s);
   1.127 +}
   1.128 +
   1.129 +ConvertRGBtoUYVY(SDL_Surface *s, SDL_Overlay *o)
   1.130 +{
   1.131 +	int x,y;
   1.132 +	int yuv[3];
   1.133 +	Uint8 *p,*op;
   1.134 +
   1.135 +	SDL_LockSurface(s);
   1.136 +	SDL_LockYUVOverlay(o);
   1.137 +
   1.138 +	for(y=0; y<s->h && y<o->h; y++)
   1.139 +	{
   1.140 +		p=s->pixels+s->pitch*y;
   1.141 +		op=o->pixels[0]+o->pitches[0]*y;
   1.142 +		for(x=0; x<s->w && x<o->w; x++)
   1.143 +		{
   1.144 +			RGBtoYUV(p,yuv);
   1.145 +			if(x%2==0)
   1.146 +			{
   1.147 +				*(op++)=yuv[1];
   1.148 +				*(op++)=yuv[0];
   1.149 +				*(op++)=yuv[2];
   1.150 +			}
   1.151 +			else
   1.152 +				*(op++)=yuv[0];
   1.153 +
   1.154 +			p+=s->format->BytesPerPixel;
   1.155 +		}
   1.156 +	}
   1.157 +
   1.158 +	SDL_UnlockYUVOverlay(o);
   1.159 +	SDL_UnlockSurface(s);
   1.160 +}
   1.161 +
   1.162 +ConvertRGBtoYVYU(SDL_Surface *s, SDL_Overlay *o)
   1.163 +{
   1.164 +	int x,y;
   1.165 +	int yuv[3];
   1.166 +	Uint8 *p,*op;
   1.167 +
   1.168 +	SDL_LockSurface(s);
   1.169 +	SDL_LockYUVOverlay(o);
   1.170 +
   1.171 +	for(y=0; y<s->h && y<o->h; y++)
   1.172 +	{
   1.173 +		p=s->pixels+s->pitch*y;
   1.174 +		op=o->pixels[0]+o->pitches[0]*y;
   1.175 +		for(x=0; x<s->w && x<o->w; x++)
   1.176 +		{
   1.177 +			RGBtoYUV(p,yuv);
   1.178 +			if(x%2==0)
   1.179 +			{
   1.180 +				*(op++)=yuv[0];
   1.181 +				*(op++)=yuv[2];
   1.182 +				op[1]=yuv[1];
   1.183 +			}
   1.184 +			else
   1.185 +			{
   1.186 +				*op=yuv[0];
   1.187 +				op+=2;
   1.188 +			}
   1.189 +
   1.190 +			p+=s->format->BytesPerPixel;
   1.191 +		}
   1.192 +	}
   1.193 +
   1.194 +	SDL_UnlockYUVOverlay(o);
   1.195 +	SDL_UnlockSurface(s);
   1.196 +}
   1.197 +
   1.198 +ConvertRGBtoYUY2(SDL_Surface *s, SDL_Overlay *o)
   1.199 +{
   1.200 +	int x,y;
   1.201 +	int yuv[3];
   1.202 +	Uint8 *p,*op;
   1.203 +
   1.204 +	SDL_LockSurface(s);
   1.205 +	SDL_LockYUVOverlay(o);
   1.206 +
   1.207 +	for(y=0; y<s->h && y<o->h; y++)
   1.208 +	{
   1.209 +		p=s->pixels+s->pitch*y;
   1.210 +		op=o->pixels[0]+o->pitches[0]*y;
   1.211 +		for(x=0; x<s->w && x<o->w; x++)
   1.212 +		{
   1.213 +			RGBtoYUV(p,yuv);
   1.214 +			if(x%2==0)
   1.215 +			{
   1.216 +				*(op++)=yuv[0];
   1.217 +				*(op++)=yuv[1];
   1.218 +				op[1]=yuv[2];
   1.219 +			}
   1.220 +			else
   1.221 +			{
   1.222 +				*op=yuv[0];
   1.223 +				op+=2;
   1.224 +			}
   1.225 +
   1.226 +			p+=s->format->BytesPerPixel;
   1.227 +		}
   1.228 +	}
   1.229 +
   1.230 +	SDL_UnlockYUVOverlay(o);
   1.231 +	SDL_UnlockSurface(s);
   1.232 +}
   1.233 +
   1.234 +void Draw()
   1.235 +{
   1.236 +	SDL_Rect rect;
   1.237 +	int i;
   1.238 +
   1.239 +	if(!scale)
   1.240 +	{
   1.241 +		rect.w=overlay->w;
   1.242 +		rect.h=overlay->h;
   1.243 +		for(i=0; i<200; i++)
   1.244 +		{
   1.245 +			rect.x=i;
   1.246 +			rect.y=i;
   1.247 +			SDL_DisplayYUVOverlay(overlay,&rect);
   1.248 +		}
   1.249 +	}
   1.250 +	else
   1.251 +	{
   1.252 +		rect.w=screen->w;
   1.253 +		rect.h=screen->h;
   1.254 +		for(i=0; i<200; i++)
   1.255 +		{
   1.256 +			rect.x=i-199;
   1.257 +			rect.y=i-199;
   1.258 +			SDL_DisplayYUVOverlay(overlay,&rect);
   1.259 +		}
   1.260 +	}
   1.261 +	printf("Displayed %d times.\n",i);
   1.262 +}
   1.263 +
   1.264 +int main(int argc, char **argv)
   1.265 +{
   1.266 +	int flip;
   1.267 +	int w, h;
   1.268 +	int delay;
   1.269 +	int desired_bpp;
   1.270 +	Uint32 video_flags, overlay_format;
   1.271 +	char *bmpfile;
   1.272 +#ifdef BENCHMARK_SDL
   1.273 +	Uint32 then, now;
   1.274 +#endif
   1.275 +	int i;
   1.276 +
   1.277 +	/* Set default options and check command-line */
   1.278 +	flip = 0;
   1.279 +	scale=0;
   1.280 +	delay = 1;
   1.281 +	w = 640;
   1.282 +	h = 480;
   1.283 +	desired_bpp = 0;
   1.284 +	video_flags = 0;
   1.285 +	overlay_format = SDL_YV12_OVERLAY;
   1.286 +
   1.287 +	while ( argc > 1 ) {
   1.288 +		if ( strcmp(argv[1], "-delay") == 0 ) {
   1.289 +			if ( argv[2] ) {
   1.290 +				delay = atoi(argv[2]);
   1.291 +				argv += 2;
   1.292 +				argc -= 2;
   1.293 +			} else {
   1.294 +				fprintf(stderr,
   1.295 +				"The -delay option requires an argument\n");
   1.296 +				exit(1);
   1.297 +			}
   1.298 +		} else
   1.299 +		if ( strcmp(argv[1], "-width") == 0 ) {
   1.300 +			if ( argv[2] && ((w = atoi(argv[2])) > 0) ) {
   1.301 +				argv += 2;
   1.302 +				argc -= 2;
   1.303 +			} else {
   1.304 +				fprintf(stderr,
   1.305 +				"The -width option requires an argument\n");
   1.306 +				exit(1);
   1.307 +			}
   1.308 +		} else
   1.309 +		if ( strcmp(argv[1], "-height") == 0 ) {
   1.310 +			if ( argv[2] && ((h = atoi(argv[2])) > 0) ) {
   1.311 +				argv += 2;
   1.312 +				argc -= 2;
   1.313 +			} else {
   1.314 +				fprintf(stderr,
   1.315 +				"The -height option requires an argument\n");
   1.316 +				exit(1);
   1.317 +			}
   1.318 +		} else
   1.319 +		if ( strcmp(argv[1], "-bpp") == 0 ) {
   1.320 +			if ( argv[2] ) {
   1.321 +				desired_bpp = atoi(argv[2]);
   1.322 +				argv += 2;
   1.323 +				argc -= 2;
   1.324 +			} else {
   1.325 +				fprintf(stderr,
   1.326 +				"The -bpp option requires an argument\n");
   1.327 +				exit(1);
   1.328 +			}
   1.329 +		} else
   1.330 +		if ( strcmp(argv[1], "-format") == 0 ) {
   1.331 +			if ( argv[2] ) {
   1.332 +				if(!strcmp(argv[2],"YV12"))
   1.333 +					overlay_format = SDL_YV12_OVERLAY;
   1.334 +				else if(!strcmp(argv[2],"IYUV"))
   1.335 +					overlay_format = SDL_IYUV_OVERLAY;
   1.336 +				else if(!strcmp(argv[2],"YUY2"))
   1.337 +					overlay_format = SDL_YUY2_OVERLAY;
   1.338 +				else if(!strcmp(argv[2],"UYVY"))
   1.339 +					overlay_format = SDL_UYVY_OVERLAY;
   1.340 +				else if(!strcmp(argv[2],"YVYU"))
   1.341 +					overlay_format = SDL_YVYU_OVERLAY;
   1.342 +				else
   1.343 +				{
   1.344 +					fprintf(stderr, "The -format option %s is not recognized\n",argv[2]);
   1.345 +					exit(1);
   1.346 +				}
   1.347 +				argv += 2;
   1.348 +				argc -= 2;
   1.349 +			} else {
   1.350 +				fprintf(stderr,
   1.351 +				"The -format option requires an argument\n");
   1.352 +				exit(1);
   1.353 +			}
   1.354 +		} else
   1.355 +		if ( strcmp(argv[1], "-hw") == 0 ) {
   1.356 +			video_flags |= SDL_HWSURFACE;
   1.357 +			argv += 1;
   1.358 +			argc -= 1;
   1.359 +		} else
   1.360 +		if ( strcmp(argv[1], "-flip") == 0 ) {
   1.361 +			video_flags |= SDL_DOUBLEBUF;
   1.362 +			argv += 1;
   1.363 +			argc -= 1;
   1.364 +		} else
   1.365 +		if ( strcmp(argv[1], "-scale") == 0 ) {
   1.366 +			scale = 1;
   1.367 +			argv += 1;
   1.368 +			argc -= 1;
   1.369 +		} else
   1.370 +		if ( strcmp(argv[1], "-fullscreen") == 0 ) {
   1.371 +			video_flags |= SDL_FULLSCREEN;
   1.372 +			argv += 1;
   1.373 +			argc -= 1;
   1.374 +		} else
   1.375 +			break;
   1.376 +	}
   1.377 +	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
   1.378 +		fprintf(stderr,
   1.379 +			"Couldn't initialize SDL: %s\n", SDL_GetError());
   1.380 +		exit(1);
   1.381 +	}
   1.382 +	atexit(SDL_Quit);			/* Clean up on exit */
   1.383 +
   1.384 +	/* Initialize the display */
   1.385 +	screen = SDL_SetVideoMode(w, h, desired_bpp, video_flags);
   1.386 +	if ( screen == NULL ) {
   1.387 +		fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
   1.388 +					w, h, desired_bpp, SDL_GetError());
   1.389 +		exit(1);
   1.390 +	}
   1.391 +	printf("Set%s %dx%dx%d mode\n",
   1.392 +			screen->flags & SDL_FULLSCREEN ? " fullscreen" : "",
   1.393 +			screen->w, screen->h, screen->format->BitsPerPixel);
   1.394 +	printf("(video surface located in %s memory)\n",
   1.395 +			(screen->flags&SDL_HWSURFACE) ? "video" : "system");
   1.396 +	if ( screen->flags & SDL_DOUBLEBUF ) {
   1.397 +		printf("Double-buffering enabled\n");
   1.398 +		flip = 1;
   1.399 +	}
   1.400 +
   1.401 +	/* Set the window manager title bar */
   1.402 +	SDL_WM_SetCaption("SDL test overlay", "testoverlay");
   1.403 +
   1.404 +	/* Load picture */
   1.405 +	bmpfile=(argv[1]?argv[1]:"sample.bmp");
   1.406 +	pic = SDL_LoadBMP(bmpfile);
   1.407 +	if ( pic == NULL ) {
   1.408 +		fprintf(stderr, "Couldn't load %s: %s\n", bmpfile,
   1.409 +							SDL_GetError());
   1.410 +		exit(1);
   1.411 +	}
   1.412 +
   1.413 +	/* Convert the picture to 32bits, for easy conversion */
   1.414 +	{
   1.415 +		SDL_Surface *newsurf;
   1.416 +		SDL_PixelFormat format;
   1.417 +
   1.418 +		format.palette=NULL;
   1.419 +		format.BitsPerPixel=32;
   1.420 +		format.BytesPerPixel=4;
   1.421 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
   1.422 +		format.Rshift=0;
   1.423 +		format.Gshift=8;
   1.424 +		format.Bshift=16;
   1.425 +#else
   1.426 +		format.Rshift=24;
   1.427 +		format.Gshift=16;
   1.428 +		format.Bshift=8;
   1.429 +#endif
   1.430 +		format.Ashift=0;
   1.431 +		format.Rmask=0xff<<format.Rshift;
   1.432 +		format.Gmask=0xff<<format.Gshift;
   1.433 +		format.Bmask=0xff<<format.Bshift;
   1.434 +		format.Amask=0;
   1.435 +		format.Rloss=0;
   1.436 +		format.Gloss=0;
   1.437 +		format.Bloss=0;
   1.438 +		format.Aloss=8;
   1.439 +		format.colorkey=0;
   1.440 +		format.alpha=0;
   1.441 +
   1.442 +		newsurf=SDL_ConvertSurface(pic, &format, SDL_SWSURFACE);
   1.443 +		if(!newsurf)
   1.444 +		{
   1.445 +			fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n",
   1.446 +							SDL_GetError());
   1.447 +			exit(1);
   1.448 +		}
   1.449 +		SDL_FreeSurface(pic);
   1.450 +		pic=newsurf;
   1.451 +	}
   1.452 +	
   1.453 +	/* Create the overlay */
   1.454 +	overlay = SDL_CreateYUVOverlay(pic->w, pic->h, overlay_format, screen);
   1.455 +	if ( overlay == NULL ) {
   1.456 +		fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
   1.457 +		exit(1);
   1.458 +	}
   1.459 +	printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes,
   1.460 +			overlay->hw_overlay?"hardware":"software",
   1.461 +			overlay->format==SDL_YV12_OVERLAY?"YV12":
   1.462 +			overlay->format==SDL_IYUV_OVERLAY?"IYUV":
   1.463 +			overlay->format==SDL_YUY2_OVERLAY?"YUY2":
   1.464 +			overlay->format==SDL_UYVY_OVERLAY?"UYVY":
   1.465 +			overlay->format==SDL_YVYU_OVERLAY?"YVYU":
   1.466 +			"Unknown");
   1.467 +	for(i=0; i<overlay->planes; i++)
   1.468 +	{
   1.469 +		printf("  plane %d: pitch=%d\n", i, overlay->pitches[i]);
   1.470 +	}
   1.471 +	
   1.472 +	/* Convert to YUV, and draw to the overlay */
   1.473 +#ifdef BENCHMARK_SDL
   1.474 +	then = SDL_GetTicks();
   1.475 +#endif
   1.476 +	switch(overlay->format)
   1.477 +	{
   1.478 +		case SDL_YV12_OVERLAY:
   1.479 +			ConvertRGBtoYV12(pic,overlay);
   1.480 +			break;
   1.481 +		case SDL_UYVY_OVERLAY:
   1.482 +			ConvertRGBtoUYVY(pic,overlay);
   1.483 +			break;
   1.484 +		case SDL_YVYU_OVERLAY:
   1.485 +			ConvertRGBtoYVYU(pic,overlay);
   1.486 +			break;
   1.487 +		case SDL_YUY2_OVERLAY:
   1.488 +			ConvertRGBtoYUY2(pic,overlay);
   1.489 +			break;
   1.490 +		case SDL_IYUV_OVERLAY:
   1.491 +			ConvertRGBtoIYUV(pic,overlay);
   1.492 +			break;
   1.493 +		default:
   1.494 +			printf("cannot convert RGB picture to obtained YUV format!\n");
   1.495 +			exit(1);
   1.496 +			break;
   1.497 +	}
   1.498 +#ifdef BENCHMARK_SDL
   1.499 +	now = SDL_GetTicks();
   1.500 +	printf("Conversion Time: %d milliseconds\n", now-then);
   1.501 +#endif
   1.502 +	
   1.503 +	/* Do all the drawing work */
   1.504 +#ifdef BENCHMARK_SDL
   1.505 +	then = SDL_GetTicks();
   1.506 +#endif
   1.507 +	Draw();
   1.508 +#ifdef BENCHMARK_SDL
   1.509 +	now = SDL_GetTicks();
   1.510 +	printf("Time: %d milliseconds\n", now-then);
   1.511 +#endif
   1.512 +	SDL_Delay(delay*1000);
   1.513 +	return(0);
   1.514 +}
   1.515 +