[Mplayer-cvslog] CVS: main/libmpcodecs vd_cyuv.c,1.4,1.5

Arpi of Ize arpi at mplayerhq.hu
Sat Sep 28 01:07:16 CEST 2002


Update of /cvsroot/mplayer/main/libmpcodecs
In directory mail:/var/tmp.root/cvs-serv30691

Modified Files:
	vd_cyuv.c 
Log Message:
decoder merged, using mpi now. support for stride, and outfmt 411p,422p


Index: vd_cyuv.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/vd_cyuv.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- vd_cyuv.c	30 Aug 2002 21:44:20 -0000	1.4
+++ vd_cyuv.c	27 Sep 2002 23:07:05 -0000	1.5
@@ -1,3 +1,21 @@
+/* ------------------------------------------------------------------------
+ * Creative YUV Video Decoder
+ *
+ * Dr. Tim Ferguson, 2001.
+ * For more details on the algorithm:
+ *         http://www.csse.monash.edu.au/~timf/videocodec.html
+ *
+ * Code restructured, and adopted to MPlayer's mpi by A'rpi, 2002.
+ *
+ * This is a very simple predictive coder.  A video frame is coded in YUV411
+ * format.  The first pixel of each scanline is coded using the upper four
+ * bits of its absolute value.  Subsequent pixels for the scanline are coded
+ * using the difference between the last pixel and the current pixel (DPCM).
+ * The DPCM values are coded using a 16 entry table found at the start of the
+ * frame.  Thus four bits per component are used and are as follows:
+ *     UY VY YY UY VY YY UY VY...
+ * ------------------------------------------------------------------------ */
+
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -23,34 +41,89 @@
 
 // init driver
 static int init(sh_video_t *sh){
-    return mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_UYVY);
+    return mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_411P);
 }
 
 // uninit driver
 static void uninit(sh_video_t *sh){
 }
 
-//mp_image_t* mpcodecs_get_image(sh_video_t *sh, int mp_imgtype, int mp_imgflag, int w, int h);
-
-void decode_cyuv(
-  unsigned char *buf,
-  int size,
-  unsigned char *frame,
-  int width,
-  int height,
-  int format);
-
 // decode a frame
 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
     mp_image_t* mpi;
-    if(len<=0) return NULL; // skipped frame
+    unsigned int xpos, ypos;
+    unsigned char *delta_y_tbl = ((unsigned char*)data)+16;
+    unsigned char *delta_c_tbl = ((unsigned char*)data)+32;
+    unsigned char *ptr = ((unsigned char*)data)+48;
+
+    if(len<=48) return NULL; // skipped/broken frame
     
-    mpi=mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, 0, 
+    mpi=mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
 	sh->disp_w, sh->disp_h);
     if(!mpi) return NULL;
 
-    decode_cyuv(data, len, mpi->planes[0], sh->disp_w, sh->disp_h,
-      sh->codec->outfmt[sh->outfmtidx]);
+    for(ypos = 0; ypos < mpi->h; ypos++){
+	    unsigned int i;
+	    unsigned char cur_Y1,cur_Y2,cur_U,cur_V;
+	    unsigned char *frame=mpi->planes[0]+mpi->stride[0]*ypos;
+	    unsigned char *uframe=mpi->planes[1]+mpi->stride[1]*ypos;
+	    unsigned char *vframe=mpi->planes[2]+mpi->stride[2]*ypos;
+
+	    for(xpos = 0; xpos < mpi->w; xpos += 2){
+
+			if(xpos&2){
+			    i = *(ptr++);
+			    cur_Y1 = (cur_Y2 + delta_y_tbl[i & 0x0f])/* & 0xff*/;
+			    cur_Y2 = (cur_Y1 + delta_y_tbl[i >> 4])/* & 0xff*/;
+			} else {
+			    if(xpos == 0) {	/* first pixels in scanline */
+				cur_U = *(ptr++);
+				cur_Y1= (cur_U & 0x0f) << 4;
+				cur_U = cur_U & 0xf0;
+				cur_V = *(ptr++);
+				cur_Y2= (cur_Y1 + delta_y_tbl[cur_V & 0x0f])/* & 0xff*/;
+				cur_V = cur_V & 0xf0;
+			    } else {	/* subsequent pixels in scanline */
+				i = *(ptr++);
+				cur_U = (cur_U + delta_c_tbl[i >> 4])/* & 0xff*/;
+				cur_Y1= (cur_Y2 + delta_y_tbl[i & 0x0f])/* & 0xff*/;
+				i = *(ptr++);
+				cur_V = (cur_V + delta_c_tbl[i >> 4])/* & 0xff*/;
+				cur_Y2= (cur_Y1 + delta_y_tbl[i & 0x0f])/* & 0xff*/;
+			    }
+			}
+			
+			// ok, store the pixels:
+			switch(mpi->imgfmt){
+			case IMGFMT_YUY2:
+				*frame++ = cur_Y1;
+				*frame++ = cur_U;
+				*frame++ = cur_Y2;
+				*frame++ = cur_V;
+				break;
+			case IMGFMT_UYVY:
+				*frame++ = cur_U;
+				*frame++ = cur_Y1;
+				*frame++ = cur_V;
+				*frame++ = cur_Y2;
+				break;
+			case IMGFMT_422P:
+				*uframe++ = cur_U;
+				*vframe++ = cur_V;
+				*frame++ = cur_Y1;
+				*frame++ = cur_Y2;
+				break;
+			case IMGFMT_411P:
+				if(!(xpos&2)){
+				    *uframe++ = cur_U;
+				    *vframe++ = cur_V;
+				}
+				*frame++ = cur_Y1;
+				*frame++ = cur_Y2;
+				break;
+			}
+	    } // xpos
+    } // ypos
 
     return mpi;
 }




More information about the MPlayer-cvslog mailing list