testoverlay.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:11k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

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