From ffba1dc02b3c808dcf023351a0ed5dcca3fc1513 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 1 Aug 2003 11:00:03 +0000 Subject: [PATCH] make the h263 decoder more error tolerant Originally committed as revision 2099 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/h263.c | 9 ++++++--- libavcodec/h263dec.c | 16 +++++++++------- libavcodec/mpegvideo.c | 14 ++++++++------ 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/libavcodec/h263.c b/libavcodec/h263.c index 9d1f5992a1..3f48418131 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -2500,6 +2500,8 @@ static int h263_decode_gob_header(MpegEncContext *s) return -1; s->mb_x= 0; s->mb_y= s->gob_index* s->gob_number; + if(s->mb_y >= s->mb_height) + return -1; #ifdef DEBUG fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", s->gob_number, gfid, s->qscale); #endif @@ -4069,7 +4071,7 @@ int h263_decode_picture_header(MpegEncContext *s) startcode= get_bits(&s->gb, 22-8); - for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>0; i--) { + for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>24; i-=8) { startcode = ((startcode << 8) | get_bits(&s->gb, 8)) & 0x003FFFFF; if(startcode == 0x20) @@ -4116,8 +4118,6 @@ int h263_decode_picture_header(MpegEncContext *s) if (!width) return -1; - s->width = width; - s->height = height; s->pict_type = I_TYPE + get_bits1(&s->gb); s->unrestricted_mv = get_bits1(&s->gb); @@ -4137,6 +4137,9 @@ int h263_decode_picture_header(MpegEncContext *s) } s->qscale = get_bits(&s->gb, 5); skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ + + s->width = width; + s->height = height; } else { int ufep; diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 332eb3b3b7..0bd2ab3395 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -470,6 +470,15 @@ retry: } else { ret = h263_decode_picture_header(s); } + + if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_size); + + /* skip if the header was thrashed */ + if (ret < 0){ + fprintf(stderr, "header damaged\n"); + return -1; + } + avctx->has_b_frames= !s->low_delay; if(s->workaround_bugs&FF_BUG_AUTODETECT){ @@ -604,13 +613,6 @@ retry: if((s->codec_id==CODEC_ID_H263 || s->codec_id==CODEC_ID_H263P)) s->gob_index = ff_h263_get_gob_height(s); - - if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_size); - /* skip if the header was thrashed */ - if (ret < 0){ - fprintf(stderr, "header damaged\n"); - return -1; - } // for hurry_up==5 s->current_picture.pict_type= s->pict_type; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 6a3b5c7185..f7525bffd0 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1004,6 +1004,14 @@ alloc: if(s->next_picture_ptr) s->next_picture= *s->next_picture_ptr; if(s->new_picture_ptr ) s->new_picture = *s->new_picture_ptr; + if(s->pict_type != I_TYPE && s->last_picture_ptr==NULL){ + fprintf(stderr, "warning: first frame is no keyframe\n"); + assert(s->pict_type != B_TYPE); //these should have been dropped if we dont have a reference + goto alloc; + } + + assert(s->pict_type == I_TYPE || (s->last_picture_ptr && s->last_picture_ptr->data[0])); + if(s->picture_structure!=PICT_FRAME){ int i; for(i=0; i<4; i++){ @@ -1015,12 +1023,6 @@ alloc: s->next_picture.linesize[i] *=2; } } - - if(s->pict_type != I_TYPE && s->last_picture_ptr==NULL){ - fprintf(stderr, "warning: first frame is no keyframe\n"); - assert(s->pict_type != B_TYPE); //these should have been dropped if we dont have a reference - goto alloc; - } } s->hurry_up= s->avctx->hurry_up;