[xiph-commits] r16617 - trunk/theora/examples

gmaxwell at svn.xiph.org gmaxwell at svn.xiph.org
Mon Oct 5 13:23:45 PDT 2009


Author: gmaxwell
Date: 2009-10-05 13:23:44 -0700 (Mon, 05 Oct 2009)
New Revision: 16617

Modified:
   trunk/theora/examples/player_example.c
Log:
Add software YUV->RGB for 4:4:4 to player example because SDL YUV overlay does not support this mode.

Modified: trunk/theora/examples/player_example.c
===================================================================
--- trunk/theora/examples/player_example.c	2009-10-05 03:19:05 UTC (rev 16616)
+++ trunk/theora/examples/player_example.c	2009-10-05 20:23:44 UTC (rev 16617)
@@ -109,7 +109,14 @@
 SDL_Surface *screen;
 SDL_Overlay *yuv_overlay;
 SDL_Rect rect;
+unsigned char *RGBbuffer;
 
+static int lu_Y[256];
+static int lu_R[256];
+static int lu_GU[256];
+static int lu_GV[256];
+static int lu_B[256];
+
 /* single frame video buffering */
 int          videobuf_ready=0;
 ogg_int64_t  videobuf_granulepos=-1;
@@ -159,6 +166,18 @@
 int          audiofd=-1;
 ogg_int64_t  audiofd_timer_calibrate=-1;
 
+static void init_yuv2rgb() {
+  int i;
+  for(i=0;i<256;i++)
+  {
+    lu_Y[i]  = (int)(  1.1644*(i- 16)*32768.0+0.5)+(1<<14);
+    lu_R[i]  = (int)(   1.596*(i-128)*32768.0+0.5);
+    lu_GU[i] = (int)(-0.39176*(i-128)*32768.0+0.5); 
+    lu_GV[i] = (int)(-0.81297*(i-128)*32768.0+0.5);
+    lu_B[i]  = (int)(  2.0172*(i-128)*32768.0+0.5);
+  }
+}
+
 static void open_audio(){
   audio_buf_info info;
   int format=AFMT_S16_NE; /* host endian */
@@ -326,13 +345,17 @@
     yuv_overlay = SDL_CreateYUVOverlay(w, h,
                                      SDL_YUY2_OVERLAY,
                                      screen);
-  else
+  else if (px_fmt==TH_PF_444) {
+    RGBbuffer = calloc(sizeof(char),w*h*4);
+    fprintf(stderr,"warning: SDL does not support YUV 4:4:4, using slow software conversion.\n");
+    init_yuv2rgb();
+  } else
     yuv_overlay = SDL_CreateYUVOverlay(w, h,
                                      SDL_YV12_OVERLAY,
                                      screen);
   
-  if ( yuv_overlay == NULL ) {
-    fprintf(stderr, "SDL: Couldn't create SDL_yuv_overlay: %s\n",
+  if ( (yuv_overlay == NULL && px_fmt!=TH_PF_444) || (screen == NULL && px_fmt==TH_PF_444) ) {
+    fprintf(stderr, "SDL: xCouldn't create SDL_yuv_overlay: %s\n",
             SDL_GetError());
     exit(1);
   }
@@ -341,7 +364,8 @@
   rect.w = w;
   rect.h = h;
 
-  SDL_DisplayYUVOverlay(yuv_overlay, &rect);
+  if (px_fmt!=TH_PF_444)
+    SDL_DisplayYUVOverlay(yuv_overlay, &rect);
 }
 
 static void video_write(void){
@@ -353,7 +377,7 @@
   if ( SDL_MUSTLOCK(screen) ) {
     if ( SDL_LockSurface(screen) < 0 ) return;
   }
-  if (SDL_LockYUVOverlay(yuv_overlay) < 0) return;
+  if (px_fmt!=TH_PF_444 && SDL_LockYUVOverlay(yuv_overlay) < 0) return;
 
   /* let's draw the data on a SDL screen (*screen) */
   /* deal with border stride */
@@ -379,6 +403,27 @@
         out[j*4+3] = in_v[j];
       }
     }
+  } else if (px_fmt==TH_PF_444){
+    SDL_Surface *output;
+    for(i=0;i<screen->h;i++) {
+      int j;
+      unsigned char *in_y  = (unsigned char *)yuv[0].data+y_offset+yuv[0].stride*i;
+      unsigned char *in_u  = (unsigned char *)yuv[1].data+y_offset+yuv[1].stride*i;
+      unsigned char *in_v  = (unsigned char *)yuv[2].data+y_offset+yuv[2].stride*i;
+      unsigned char *out = RGBbuffer+(screen->w*i*4);
+      for (j=0;j<screen->w;j++) {
+        int r, g, b;
+        int y = lu_Y[in_y[j]];
+        b=(y + lu_B[in_u[j]])>>15;
+        out[j*4]     = ((b) > 255 ? 255 : (b) < 0 ? 0 : (b));
+        g=(y + lu_GV[in_v[j]] + lu_GU[in_u[j]])>>15;
+        out[j*4+1]   = ((g) > 255 ? 255 : (g) < 0 ? 0 : (g));
+        r=(y + lu_R[in_v[j]])>>15;
+        out[j*4+2]   = ((r) > 255 ? 255 : (r) < 0 ? 0 : (r));
+      }  
+      output=SDL_CreateRGBSurfaceFrom(RGBbuffer,screen->w,screen->h,32,4*screen->w,0,0,0,0);
+      SDL_BlitSurface(output,NULL,screen,NULL);
+    }
   } else {
     uv_offset=(ti.pic_x/2)+(yuv[1].stride)*(ti.pic_y/2);
     for(i=0;i<yuv_overlay->h;i++)
@@ -399,12 +444,13 @@
   if ( SDL_MUSTLOCK(screen) ) {
     SDL_UnlockSurface(screen);
   }
-  SDL_UnlockYUVOverlay(yuv_overlay);
-
-
-  /* Show, baby, show! */
-  SDL_DisplayYUVOverlay(yuv_overlay, &rect);
-
+  if (px_fmt!=TH_PF_444) {
+    SDL_UnlockYUVOverlay(yuv_overlay);
+    /* Show, baby, show! */
+    SDL_DisplayYUVOverlay(yuv_overlay, &rect);
+  } else { 
+    SDL_Flip(screen);
+  }
 }
 /* dump the theora (or vorbis) comment header */
 static int dump_comments(th_comment *tc){



More information about the commits mailing list