summaryrefslogtreecommitdiffstats
path: root/libmpcodecs
diff options
context:
space:
mode:
authorarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-09-27 23:07:05 +0000
committerarpi <arpi@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-09-27 23:07:05 +0000
commitd97d29a54f272cdfd2b097d9d8a2e900547555b0 (patch)
treea1373fcb601bced6e0eb6ec5c6ce31857fac73fb /libmpcodecs
parent5bda0616478f50e3465687038178c7fc827a49d4 (diff)
downloadmpv-d97d29a54f272cdfd2b097d9d8a2e900547555b0.tar.bz2
mpv-d97d29a54f272cdfd2b097d9d8a2e900547555b0.tar.xz
decoder merged, using mpi now. support for stride, and outfmt 411p,422p
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@7520 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs')
-rw-r--r--libmpcodecs/vd_cyuv.c103
1 files changed, 88 insertions, 15 deletions
diff --git a/libmpcodecs/vd_cyuv.c b/libmpcodecs/vd_cyuv.c
index 1b1f9399d9..49f2456cc0 100644
--- a/libmpcodecs/vd_cyuv.c
+++ b/libmpcodecs/vd_cyuv.c
@@ -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 @@ static int control(sh_video_t *sh,int cmd,void* arg,...){
// 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;
}