[FFmpeg-soc] [soc]: r366 - in rv40: rv40.c rv40data.h

kostya subversion at mplayerhq.hu
Tue Jul 10 07:44:11 CEST 2007


Author: kostya
Date: Tue Jul 10 07:44:11 2007
New Revision: 366

Log:
More decoding functions

Modified:
   rv40/rv40.c
   rv40/rv40data.h

Modified: rv40/rv40.c
==============================================================================
--- rv40/rv40.c	(original)
+++ rv40/rv40.c	Tue Jul 10 07:44:11 2007
@@ -38,6 +38,11 @@
 typedef struct RV40DecContext{
     MpegEncContext s;
     int mb_bits;             ///< bits needed to read MB offet in slice header
+    int intra_types[16];     ///< block types
+    int block_start;         ///< start of slice in blocks
+    int block_end;           ///< end of slice in blocks
+    int ptype;               ///< picture type
+    int quant;               ///< quantizer
 }RV40DecContext;
 
 
@@ -376,6 +381,20 @@ static inline void rv40_decode_block(DCT
     }
 }
 
+/**
+ * Dequantize ordinary 4x4 block
+ * @todo optimize
+ */
+static inline void rv40_dequant4x4(DCTELEM *block, int offset, int Qdc, int Q)
+{
+    int i, j;
+
+    block[0] = (block[0] * Qdc + 8) >> 4;
+    for(i = 0; i < 4; i++)
+        for(j = 0; j < 4; j++)
+            if(i || j)
+                block[j + i*8] = (block[j + i*8] * Q + 8) >> 4;
+}
 /** @} */ //block functions
 
 
@@ -425,21 +444,25 @@ static void rv40_parse_picture_size(GetB
 
 static int rv40_parse_slice_header(RV40DecContext *r, GetBitContext *gb)
 {
-    int ptype, quant, w, h, mb_bits, mb_start;
+    int t, mb_bits;
+    int w, h;
 
     if(get_bits1(gb))
         return -1;
-    ptype = get_bits(gb, 2);
-    quant = get_bits(gb, 5);
+    r->ptype = get_bits(gb, 2);
+    r->quant = get_bits(gb, 5);
     if(get_bits(gb, 2))
         return -1;
     get_bits(gb, 2); /// ???
     if(get_bits1(gb))
         return -1;
-    get_bits(gb, 13); /// ???
+    t = get_bits(gb, 13); /// ???
     rv40_parse_picture_size(gb, &w, &h);
-    mb_bits = av_log2(r->s.mb_width) + av_log2(r->s.mb_height);
-    mb_start = get_bits(gb, mb_bits);
+    r->s.avctx->coded_width  = w;
+    r->s.avctx->coded_height = h;
+    mb_bits = av_log2(t)+1;
+    r->block_start = get_bits(gb, mb_bits);
+    r->block_end = r->block_start+70;
     return 0;
 }
 
@@ -513,27 +536,76 @@ static int rv40_decode_macroblock(RV40De
 {
     MpegEncContext *s = &r->s;
     GetBitContext *gb = &s->gb;
+    DSPContext *dsp = &s->dsp;
     int q, cbp;
-    int i;
+    int i, x, y;
+    uint8_t *Y;
+    int luma_vlc, chroma_vlc;
+    int is16 = 0;
+    DCTELEM block16[64];
 
     q = decode210(gb);
     switch(q){
-    case 0:
+    case 0: // 16x16 block
+        is16 = 1;
         break;
     case 1:
         break;
     case 2:
+        av_log(NULL,0,"Need DQUANT\n");
         // q = decode_dquant(gb);
         break;
     }
-    //rv40_decode_intra_types(r, gb);
-    cbp = rv40_decode_cbp(gb, &intra_vlcs[2], 0);
+    if(!is16){
+        rv40_decode_intra_types(r, gb, r->intra_types);
+        chroma_vlc = 0;
+        luma_vlc   = 1;
+    }else{
+        x = get_bits(gb, 2);
+        if(x==3)
+            av_log(NULL,0,"Got type 3 for Intra16x16\n");
+        for(i = 0; i < 16; i++)
+            r->intra_types[i] = x;
+        chroma_vlc = 0;
+        luma_vlc   = 2;
+    }
+    cbp = rv40_decode_cbp(gb, &intra_vlcs[2], is16);
 
-    // decode 24 4x4 blocks to fill one macroblock
-    for(i = 0; i < 24; i++, cbp >>= 1){
+    if(is16){
+        memset(block16, 0, sizeof(block16));
+        rv40_decode_block(block16, gb, &intra_vlcs[2], 3, 0);
+    }
+
+    for(i = 0; i < 16; i++, cbp >>= 1){
         if(!(cbp & 1)) continue;
-        rv40_decode_block(s->block[i>>2] + (i&1)*2 + (i&2)*4, gb, &intra_vlcs[2], 2, 0);
+        x = (i & 1) << 2;
+        y = (i & 2) << 4;
+        rv40_decode_block(s->block[i>>2] + x + y, gb, &intra_vlcs[2], luma_vlc, 0);
+        rv40_dequant4x4(s->block[i>>2] + x + y, r->quant, rv40_luma_quant[0][r->quant],rv40_luma_quant[0][r->quant]);
+
+        s->block[i>>2][x+y] += 256;
+        rv40_intra_inv_transform(s->block[i>>2], x+y);
     }
+    for(; i < 24; i++, cbp >>= 1){
+        if(!(cbp & 1)) continue;
+        x = (i & 1) << 2;
+        y = (i & 2) << 4;
+        rv40_decode_block(s->block[i>>2] + x + y, gb, &intra_vlcs[2], chroma_vlc, 1);
+        rv40_dequant4x4(s->block[i>>2] + x + y, r->quant, rv40_chroma_quant[0][r->quant],rv40_chroma_quant[1][r->quant]);
+
+        s->block[i>>2][x+y] += 256;
+        rv40_intra_inv_transform(s->block[i>>2], x+y);
+    }
+    Y = s->dest[0];
+    dsp->put_pixels_clamped(s->block[0], Y, s->current_picture.linesize[0]);
+    dsp->put_pixels_clamped(s->block[1], Y + 8, s->current_picture.linesize[0]);
+    Y += s->current_picture.linesize[0] * 8;
+    dsp->put_pixels_clamped(s->block[2], Y, s->current_picture.linesize[0]);
+    dsp->put_pixels_clamped(s->block[3], Y + 8, s->current_picture.linesize[0]);
+
+    dsp->put_pixels_clamped(s->block[4], s->dest[1], s->current_picture.linesize[1]);
+    dsp->put_pixels_clamped(s->block[5], s->dest[2], s->current_picture.linesize[2]);
+
     return 0;
 }
 
@@ -541,19 +613,28 @@ static int rv40_decode_slice(RV40DecCont
 {
     MpegEncContext *s = &r->s;
 
-    ff_er_add_slice(s, 0, slice_start, s->mb_width - 1, slice_end - 1, (AC_END|DC_END|MV_END));
+    ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
+
+    memset(r->intra_types, -1, 16 * sizeof(int));
     s->first_slice_line = 1;
-    for(s->mb_y = slice_start; s->mb_y < slice_end; s->mb_y++) {
-        for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
-            ff_init_block_index(s);
-            ff_update_block_index(s);
-            s->dsp.clear_blocks(s->block[0]);
+    s->resync_mb_x= s->mb_x;
+    ff_init_block_index(s);
+    for(s->mb_num_left= slice_end-slice_start; s->mb_num_left>0; s->mb_num_left--) {
+        ff_update_block_index(s);
+        s->dsp.clear_blocks(s->block[0]);
 
-            rv40_decode_macroblock(r);
-        }
+        rv40_decode_macroblock(r);
         ff_draw_horiz_band(s, s->mb_y * 16, 16);
-        s->first_slice_line = 0;
+        if (++s->mb_x == s->mb_width) {
+            s->mb_x = 0;
+            s->mb_y++;
+            ff_init_block_index(s);
+        }
+        if(s->mb_x == s->resync_mb_x)
+            s->first_slice_line=0;
     }
+    //ff_er_add_slice(s, slice_start % s->mb_width, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
+
     return 0;
 }
 
@@ -582,6 +663,8 @@ static int rv40_decode_init(AVCodecConte
     r->s.avctx = avctx;
     avctx->flags |= CODEC_FLAG_EMU_EDGE;
     r->s.flags |= CODEC_FLAG_EMU_EDGE;
+    avctx->pix_fmt = PIX_FMT_YUV420P;
+    s->low_delay = 1;
 
     if (MPV_common_init(s) < 0)
         return -1;
@@ -601,8 +684,8 @@ static int rv40_decode_frame(AVCodecCont
     RV40DecContext *r = avctx->priv_data;
     MpegEncContext *s = &r->s;
     AVFrame *pict = data;
+    int res;
 
-return 0;
     /* no supplementary picture */
     if (buf_size == 0) {
         /* special case for last picture */
@@ -624,6 +707,10 @@ return 0;
     }
 
     init_get_bits(&s->gb, buf, buf_size*8);
+    rv40_parse_slice_header(r, &r->s.gb);
+    s->pict_type = r->ptype+1;
+    if(s->pict_type != I_TYPE) return -1;
+    init_get_bits(&s->gb, buf, buf_size*8);
 
     // for hurry_up==5
     s->current_picture.pict_type= s->pict_type;
@@ -656,7 +743,20 @@ return 0;
 
     ff_er_frame_start(s);
 
-///XXX: do actual decoding of slices
+    s->mb_x = s->mb_y = 0;
+
+{
+int starts[] = { 0x000, 0x046, 0x08A, 0x0BF, 0x0FE, 0x13E, 0x190, 0x205, 0x244, 0x29D, 0x2A8};
+int i;
+//    do{
+    for(i=0; i < 10; i++){
+        if(rv40_parse_slice_header(r, &r->s.gb) < 0) break;
+        res = rv40_decode_slice(r, starts[i], starts[i+1]);
+    }
+//    }while(res);
+}
+    s->pict_type = r->ptype;
+    s->current_picture.pict_type = s->pict_type;
 
     ff_er_frame_end(s);
 

Modified: rv40/rv40data.h
==============================================================================
--- rv40/rv40data.h	(original)
+++ rv40/rv40data.h	Tue Jul 10 07:44:11 2007
@@ -105,4 +105,25 @@ static const uint16_t rv40_aic_table_ind
  0x112, 0x116, 0x221
 };
 
+/**
+ * Luma quantizer values
+ * Second table is used for inter blocks
+ */
+static uint8_t rv40_luma_quant[2][32] = {
+ {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 22, 22, 22, 22 },
+ {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 20, 21, 21, 22, 23, 23, 23, 24, 24, 24, 24 }
+};
+
+/**
+ * Chroma quantizer values
+ * Second table is used for DC-only blocks
+ */
+static uint8_t rv40_chroma_quant[2][32] = {
+ {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 17, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25 },
+ {  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,
+   14, 15, 15, 16, 17, 18, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23 }
+};
 #endif /* RV40DATA_H */



More information about the FFmpeg-soc mailing list