[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