[FFmpeg-soc] [soc]: r609 - rv40/rv40.c

kostya subversion at mplayerhq.hu
Sun Aug 5 12:09:54 CEST 2007


Author: kostya
Date: Sun Aug  5 12:09:54 2007
New Revision: 609

Log:
Correct P-frame bitstream parsing:
* Correct names for some macroblock types
* Correct choosing of previous block type for reading of current one
* Set correct values for block decoding in case of inter blocks
 


Modified:
   rv40/rv40.c

Modified: rv40/rv40.c
==============================================================================
--- rv40/rv40.c	(original)
+++ rv40/rv40.c	Sun Aug  5 12:09:54 2007
@@ -38,15 +38,15 @@
 
 /** Translation of RV40 macroblock types to lavc ones */
 static const int rv40_mb_type_to_lavc[12] = {
-    MB_TYPE_INTRA, MB_TYPE_16x16, MB_TYPE_16x16,   MB_TYPE_8x8,
-    MB_TYPE_16x16, MB_TYPE_16x16, MB_TYPE_SKIP,    MB_TYPE_DIRECT2,
-    MB_TYPE_16x8,  MB_TYPE_8x16,  MB_TYPE_DIRECT2, MB_TYPE_16x16
+    MB_TYPE_INTRA, MB_TYPE_INTRA16x16, MB_TYPE_16x16,   MB_TYPE_8x8,
+    MB_TYPE_16x16, MB_TYPE_16x16,      MB_TYPE_SKIP,    MB_TYPE_DIRECT2,
+    MB_TYPE_16x8,  MB_TYPE_8x16,       MB_TYPE_DIRECT2, MB_TYPE_16x16
 };
 
 /** RV40 Macroblock types */
 enum RV40BlockTypes{
-    RV40_MB_TYPE_0,
-    RV40_MB_TYPE_1,
+    RV40_MB_TYPE_INTRA,
+    RV40_MB_TYPE_INTRA16x16,
     RV40_MB_P_16x16,
     RV40_MB_P_8x8,
     RV40_MB_B_FORWARD, //XXX: maybe vice versa
@@ -56,7 +56,8 @@ enum RV40BlockTypes{
     RV40_MB_P_16x8,
     RV40_MB_P_8x16,
     RV40_MB_B_DIRECT,
-    RV40_MB_P_1MV, //XXX: unknown
+    RV40_MB_P_MIX16x16, // inter 16x16 block very similar to Intra16x16
+    RV40_MB_TYPES
 };
 
 /**
@@ -671,9 +672,11 @@ static int rv40_decode_mb_info(RV40DecCo
 {
     MpegEncContext *s = &r->s;
     GetBitContext *gb = &s->gb;
-    int q;
+    int q, i;
     int prev_type = 0;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+    int blocks[RV40_MB_TYPES];
+    int count = 0;
 
     if(!r->skip_blocks)
         r->skip_blocks = get_omega(gb);
@@ -681,9 +684,25 @@ static int rv40_decode_mb_info(RV40DecCo
     if(--r->skip_blocks)
          return RV40_MB_SKIP;
 
+    memset(blocks, 0, sizeof(blocks));
     if(s->pict_type == P_TYPE){
-        if(s->mb_y) prev_type = r->mb_type[mb_pos - s->mb_stride];
-        if(s->mb_x) prev_type = r->mb_type[mb_pos - 1];
+        if(!s->first_slice_line){
+            blocks[r->mb_type[mb_pos - s->mb_stride]]++;
+            if(s->mb_x)
+                blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++;
+            if(s->mb_x-1 < s->mb_width)
+                blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++;
+            if(s->mb_x == s->resync_mb_x && (s->mb_y-1) == s->resync_mb_y)
+                blocks[r->mb_type[mb_pos - s->mb_stride - 1]]--; //that's another slice
+        }
+        if(s->mb_x && !(s->first_slice_line && s->mb_x == s->resync_mb_x))
+            blocks[r->mb_type[mb_pos - 1]]++;
+        for(i = 0; i < RV40_MB_TYPES; i++){
+            if(blocks[i] > count){
+                count = blocks[i];
+                prev_type = i;
+            }
+        }
         if(prev_type == RV40_MB_SKIP) prev_type = RV40_MB_P_16x16;
         prev_type = block_num_to_ptype_vlc_num[prev_type];
         q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
@@ -710,8 +729,8 @@ static int rv40_decode_mv(RV40DecContext
     int i;
 
     switch(block_type){
-    case RV40_MB_TYPE_0:
-    case RV40_MB_TYPE_1:
+    case RV40_MB_TYPE_INTRA:
+    case RV40_MB_TYPE_INTRA16x16:
     case RV40_MB_SKIP:
         return 0;
     case RV40_MB_B_INTERP:
@@ -719,7 +738,7 @@ static int rv40_decode_mv(RV40DecContext
     case RV40_MB_P_16x16:
     case RV40_MB_B_FORWARD:
     case RV40_MB_B_BACKWARD:
-    case RV40_MB_P_1MV:
+    case RV40_MB_P_MIX16x16:
         mv[0][0] = get_omega(gb);
         mv[0][1] = get_omega(gb);
         break;
@@ -884,6 +903,7 @@ static int rv40_decode_mb_header(RV40Dec
     GetBitContext *gb = &s->gb;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int i, t;
+    int cbp;
 
     if(!r->prev_si.type){
         r->is16 = 0;
@@ -900,6 +920,18 @@ static int rv40_decode_mb_header(RV40Dec
         }
         s->current_picture_ptr->mb_type[mb_pos] = r->is16 ? MB_TYPE_INTRA16x16 : MB_TYPE_INTRA;
     }else{
+        r->block_type = rv40_decode_mb_info(r);
+        s->current_picture_ptr->mb_type[mb_pos] = rv40_mb_type_to_lavc[r->block_type];
+        r->mb_type[mb_pos] = (r->block_type == RV40_MB_SKIP) ? RV40_MB_P_16x16 : r->block_type;
+        r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]);
+        if(r->block_type == RV40_MB_SKIP){
+            for(i = 0; i < 16; i++)
+                intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0;
+            return 0;
+        }
+        rv40_decode_mv(r, r->block_type);
+        r->chroma_vlc = 1;
+        r->luma_vlc   = 0;
     }
     if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
         if(!r->is16){
@@ -913,8 +945,19 @@ static int rv40_decode_mb_header(RV40Dec
             r->chroma_vlc = 0;
             r->luma_vlc   = 2;
         }
+        r->cur_vlcs = choose_vlc_set(r->prev_si.quant, r->prev_si.vlc_set, 0);
+    }else{
+        for(i = 0; i < 16; i++)
+            intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0;
+        r->cur_vlcs = choose_vlc_set(r->prev_si.quant, r->prev_si.vlc_set, 1);
+        if(r->mb_type[mb_pos] == RV40_MB_P_MIX16x16){
+            r->is16 = 1;
+            r->chroma_vlc = 1;
+            r->luma_vlc   = 2;
+            r->cur_vlcs = choose_vlc_set(r->prev_si.quant, r->prev_si.vlc_set, 0);
+        }
     }
-    return rv40_decode_cbp(gb, r->cur_vlcs, !r->prev_si.type && r->is16);
+    return rv40_decode_cbp(gb, r->cur_vlcs, r->is16);
 }
 
 static int rv40_decode_macroblock(RV40DecContext *r, int *intra_types)
@@ -947,6 +990,8 @@ static int rv40_decode_macroblock(RV40De
             rv40_intra_inv_transform(s->block[blknum], blkoff);
         }
     }
+    if(r->block_type == RV40_MB_P_MIX16x16)
+        r->cur_vlcs = choose_vlc_set(r->prev_si.quant, r->prev_si.vlc_set, 1);
     for(; i < 24; i++, cbp >>= 1){
         if(!(cbp & 1)) continue;
         blknum = ((i & 4) >> 2) + 4;



More information about the FFmpeg-soc mailing list