Hi,

this patch has so far survived fuzzing since yesterday evening without
hang or crash.

Janne

---8<---
Adds a flag context_reinit to MpegEncContext to releable keep track
of frame parameter changes which require a context reinitialization.
This is required for broken inputs which change the frame size but
error out before the context can be reinitialized.
---
 libavcodec/h263dec.c       | 26 +++++++-------------------
 libavcodec/mpeg4videodec.c |  2 ++
 libavcodec/mpegvideo.c     |  9 +++++++++
 libavcodec/mpegvideo.h     |  4 ++++
 4 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 8e6085b..e70d118 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -384,9 +384,6 @@ uint64_t time= rdtsc();
             return buf_size;
     }
 
-
-retry:
-
     if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 
5.01+/xvid frame reorder
         init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8);
     }else
@@ -434,13 +431,6 @@ retry:
     if (ret < 0){
         av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
         return -1;
-    } else if ((s->width  != avctx->coded_width  ||
-                s->height != avctx->coded_height ||
-                (s->width  + 15) >> 4 != s->mb_width ||
-                (s->height + 15) >> 4 != s->mb_height) &&
-               (HAVE_THREADS && (s->avctx->active_thread_type & 
FF_THREAD_FRAME))) {
-        av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc 
changing with threads is", 0);
-        return AVERROR_PATCHWELCOME;   // width / height changed during 
parallelized decoding
     }
 
     avctx->has_b_frames= !s->low_delay;
@@ -577,19 +567,17 @@ retry:
         /* FIXME: By the way H263 decoder is evolving it should have */
         /* an H263EncContext                                         */
 
-    if (   s->width  != avctx->coded_width
-        || s->height != avctx->coded_height) {
+    if (s->width  != avctx->coded_width  ||
+        s->height != avctx->coded_height ||
+        s->context_reinit) {
         /* H.263 could change picture size any time */
-        ParseContext pc= s->parse_context; //FIXME move these demuxng hack to 
avformat
+        s->context_reinit = 0;
 
-        s->parse_context.buffer=0;
-        ff_MPV_common_end(s);
-        s->parse_context= pc;
-    }
-    if (!s->context_initialized) {
         avcodec_set_dimensions(avctx, s->width, s->height);
 
-        goto retry;
+        if ((ret = ff_MPV_common_frame_size_change(s)))
+            return ret;
+
     }
 
     if((s->codec_id==AV_CODEC_ID_H263 || s->codec_id==AV_CODEC_ID_H263P || 
s->codec_id == AV_CODEC_ID_H263I))
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 27cae9f..6eceb39 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -1600,6 +1600,8 @@ static int decode_vol_header(MpegEncContext *s, 
GetBitContext *gb){
             height = get_bits(gb, 13);
             skip_bits1(gb);   /* marker */
             if(width && height && !(s->width && s->codec_tag == 
AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */
+                if (s->width != width || s->height != height)
+                    s->context_reinit = 1;
                 s->width = width;
                 s->height = height;
             }
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 20e11cf..6b2acb0 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -550,6 +550,15 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
         ff_MPV_common_init(s);
     }
 
+    if (s->height != s1->height || s->width != s1->width || s->context_reinit) 
{
+        int err;
+        s->context_reinit = 0;
+        s->height = s1->height;
+        s->width  = s1->width;
+        if ((err = ff_MPV_common_frame_size_change(s)) < 0)
+            return err;
+    }
+
     s->avctx->coded_height  = s1->avctx->coded_height;
     s->avctx->coded_width   = s1->avctx->coded_width;
     s->avctx->width         = s1->avctx->width;
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 88a1059..4c220ec 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -703,6 +703,10 @@ typedef struct MpegEncContext {
 
     /* temp buffers for rate control */
     float *cplx_tab, *bits_tab;
+
+    /* flag to indicate a reinitialization is required, e.g. after
+     * a frame size change */
+    int context_reinit;
 } MpegEncContext;
 
 #define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \
-- 
1.7.12

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to