changeset 1021:2d7c9f5738de libavcodec

trying to fix mb skip bug in mpeg1/2 if slices are not used
author michaelni
date Mon, 20 Jan 2003 20:37:24 +0000
parents 617e3531d3fb
children d651df667898
files mpeg12.c mpegvideo.c mpegvideo.h
diffstat 3 files changed, 24 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/mpeg12.c	Mon Jan 20 20:33:08 2003 +0000
+++ b/mpeg12.c	Mon Jan 20 20:37:24 2003 +0000
@@ -767,6 +767,8 @@
     
     dprintf("decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
 
+    assert(s->mb_skiped==0);
+
     if (--s->mb_incr != 0) {
         /* skip mb */
         s->mb_intra = 0;
@@ -779,15 +781,18 @@
             s->mv[0][0][0] = s->mv[0][0][1] = 0;
             s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0;
             s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0;
+            s->mb_skiped = 1;
         } else {
             /* if B type, reuse previous vectors and directions */
             s->mv[0][0][0] = s->last_mv[0][0][0];
             s->mv[0][0][1] = s->last_mv[0][0][1];
             s->mv[1][0][0] = s->last_mv[1][0][0];
             s->mv[1][0][1] = s->last_mv[1][0][1];
+
+            if((s->mv[0][0][0]|s->mv[0][0][1]|s->mv[1][0][0]|s->mv[1][0][1])==0) 
+                s->mb_skiped = 1;
         }
 
-        s->mb_skiped = 1;
         return 0;
     }
 
@@ -1670,7 +1675,7 @@
             return DECODE_SLICE_FATAL_ERROR;
             
         if(s->avctx->debug&FF_DEBUG_PICT_INFO){
-             printf("qp:%d fc:%d%d%d%d %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", 
+             printf("qp:%d fc:%2d%2d%2d%2d %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n", 
                  s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1],
                  s->pict_type == I_TYPE ? "I" : (s->pict_type == P_TYPE ? "P" : (s->pict_type == B_TYPE ? "B" : "S")), 
                  s->progressive_sequence ? "pro" :"", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"", 
--- a/mpegvideo.c	Mon Jan 20 20:33:08 2003 +0000
+++ b/mpegvideo.c	Mon Jan 20 20:37:24 2003 +0000
@@ -20,6 +20,7 @@
  */
  
 #include <ctype.h>
+#include <limits.h>
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
@@ -322,6 +323,12 @@
         pic->qstride= s->mb_width;
     }
     
+    //it might be nicer if the application would keep track of these but it would require a API change
+    memmove(s->prev_pict_types+1, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE-1);
+    s->prev_pict_types[0]= s->pict_type;
+    if(pic->age < PREV_PICT_TYPES_BUFFER_SIZE && s->prev_pict_types[pic->age] == B_TYPE)
+        pic->age= INT_MAX; // skiped MBs in b frames are quite rare in mpeg1/2 and its a bit tricky to skip them anyway
+    
     return 0;
 fail: //for the CHECKED_ALLOCZ macro
     return -1;
@@ -479,6 +486,7 @@
     /* init macroblock skip table */
     CHECKED_ALLOCZ(s->mbskip_table, s->mb_num+1);
     //Note the +1 is for a quicker mpeg4 slice_end detection
+    CHECKED_ALLOCZ(s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE);
     
     s->block= s->blocks[0];
 
@@ -518,6 +526,7 @@
     av_freep(&s->me.score_map);
     
     av_freep(&s->mbskip_table);
+    av_freep(&s->prev_pict_types);
     av_freep(&s->bitstream_buffer);
     av_freep(&s->tex_pb_buffer);
     av_freep(&s->pb2_buffer);
@@ -2016,14 +2025,13 @@
                 if(*mbskip_ptr >99) *mbskip_ptr= 99;
 
                 /* if previous was skipped too, then nothing to do !  */
-                if (*mbskip_ptr >= age){
-//if(s->pict_type!=B_TYPE && s->mb_x==0) printf("\n");
-//if(s->pict_type!=B_TYPE) printf("%d%d ", *mbskip_ptr, age);
-                    if(s->pict_type!=B_TYPE) return;
-                    if(s->avctx->draw_horiz_band==NULL && *mbskip_ptr > age) return; 
-                    /* we dont draw complete frames here so we cant skip */
+                if (*mbskip_ptr >= age && s->current_picture.reference){
+                    return;
                 }
-            } else {
+            } else if(!s->current_picture.reference){
+                (*mbskip_ptr) ++; /* increase counter so the age can be compared cleanly */
+                if(*mbskip_ptr >99) *mbskip_ptr= 99;
+            } else{
                 *mbskip_ptr = 0; /* not skipped */
             }
         }else
--- a/mpegvideo.h	Mon Jan 20 20:33:08 2003 +0000
+++ b/mpegvideo.h	Mon Jan 20 20:37:24 2003 +0000
@@ -229,6 +229,8 @@
     UINT8 *coded_block;          /* used for coded block pattern prediction (msmpeg4v3, wmv1)*/
     INT16 (*ac_val[3])[16];      /* used for for mpeg4 AC prediction, all 3 arrays must be continuous */
     int ac_pred;
+    uint8_t *prev_pict_types;   /* previous picture types in bitstream order, used for mb skip */
+#define PREV_PICT_TYPES_BUFFER_SIZE 256
     int mb_skiped;              /* MUST BE SET only during DECODING */
     UINT8 *mbskip_table;        /* used to avoid copy if macroblock skipped (for black regions for example) 
                                    and used for b-frame encoding & decoding (contains skip table of next P Frame) */