提交 f943e138 编写于 作者: M Michael Niedermayer

trying to fix mb skip bug in mpeg1/2 if slices are not used

Originally committed as revision 1482 to svn://svn.ffmpeg.org/ffmpeg/trunk
上级 d0162d09
...@@ -767,6 +767,8 @@ static int mpeg_decode_mb(MpegEncContext *s, ...@@ -767,6 +767,8 @@ static int mpeg_decode_mb(MpegEncContext *s,
dprintf("decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y); dprintf("decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
assert(s->mb_skiped==0);
if (--s->mb_incr != 0) { if (--s->mb_incr != 0) {
/* skip mb */ /* skip mb */
s->mb_intra = 0; s->mb_intra = 0;
...@@ -779,15 +781,18 @@ static int mpeg_decode_mb(MpegEncContext *s, ...@@ -779,15 +781,18 @@ static int mpeg_decode_mb(MpegEncContext *s,
s->mv[0][0][0] = s->mv[0][0][1] = 0; 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][0][0] = s->last_mv[0][0][1] = 0;
s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0; s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0;
s->mb_skiped = 1;
} else { } else {
/* if B type, reuse previous vectors and directions */ /* if B type, reuse previous vectors and directions */
s->mv[0][0][0] = s->last_mv[0][0][0]; s->mv[0][0][0] = s->last_mv[0][0][0];
s->mv[0][0][1] = s->last_mv[0][0][1]; 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][0] = s->last_mv[1][0][0];
s->mv[1][0][1] = s->last_mv[1][0][1]; 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; return 0;
} }
...@@ -1670,7 +1675,7 @@ static int mpeg_decode_slice(AVCodecContext *avctx, ...@@ -1670,7 +1675,7 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
return DECODE_SLICE_FATAL_ERROR; return DECODE_SLICE_FATAL_ERROR;
if(s->avctx->debug&FF_DEBUG_PICT_INFO){ 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->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->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" :"", s->progressive_sequence ? "pro" :"", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"",
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
*/ */
#include <ctype.h> #include <ctype.h>
#include <limits.h>
#include "avcodec.h" #include "avcodec.h"
#include "dsputil.h" #include "dsputil.h"
#include "mpegvideo.h" #include "mpegvideo.h"
...@@ -322,6 +323,12 @@ static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){ ...@@ -322,6 +323,12 @@ static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){
pic->qstride= s->mb_width; 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; return 0;
fail: //for the CHECKED_ALLOCZ macro fail: //for the CHECKED_ALLOCZ macro
return -1; return -1;
...@@ -479,6 +486,7 @@ int MPV_common_init(MpegEncContext *s) ...@@ -479,6 +486,7 @@ int MPV_common_init(MpegEncContext *s)
/* init macroblock skip table */ /* init macroblock skip table */
CHECKED_ALLOCZ(s->mbskip_table, s->mb_num+1); CHECKED_ALLOCZ(s->mbskip_table, s->mb_num+1);
//Note the +1 is for a quicker mpeg4 slice_end detection //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]; s->block= s->blocks[0];
...@@ -518,6 +526,7 @@ void MPV_common_end(MpegEncContext *s) ...@@ -518,6 +526,7 @@ void MPV_common_end(MpegEncContext *s)
av_freep(&s->me.score_map); av_freep(&s->me.score_map);
av_freep(&s->mbskip_table); av_freep(&s->mbskip_table);
av_freep(&s->prev_pict_types);
av_freep(&s->bitstream_buffer); av_freep(&s->bitstream_buffer);
av_freep(&s->tex_pb_buffer); av_freep(&s->tex_pb_buffer);
av_freep(&s->pb2_buffer); av_freep(&s->pb2_buffer);
...@@ -2016,14 +2025,13 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) ...@@ -2016,14 +2025,13 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
if(*mbskip_ptr >99) *mbskip_ptr= 99; if(*mbskip_ptr >99) *mbskip_ptr= 99;
/* if previous was skipped too, then nothing to do ! */ /* if previous was skipped too, then nothing to do ! */
if (*mbskip_ptr >= age){ if (*mbskip_ptr >= age && s->current_picture.reference){
//if(s->pict_type!=B_TYPE && s->mb_x==0) printf("\n"); return;
//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 */
} }
} 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 */ *mbskip_ptr = 0; /* not skipped */
} }
}else }else
......
...@@ -229,6 +229,8 @@ typedef struct MpegEncContext { ...@@ -229,6 +229,8 @@ typedef struct MpegEncContext {
UINT8 *coded_block; /* used for coded block pattern prediction (msmpeg4v3, wmv1)*/ 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 */ INT16 (*ac_val[3])[16]; /* used for for mpeg4 AC prediction, all 3 arrays must be continuous */
int ac_pred; 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 */ int mb_skiped; /* MUST BE SET only during DECODING */
UINT8 *mbskip_table; /* used to avoid copy if macroblock skipped (for black regions for example) 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) */ and used for b-frame encoding & decoding (contains skip table of next P Frame) */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册