[FFmpeg-cvslog] mpeg4: support frame parameter changes with frame-mt

Janne Grunau git at videolan.org
Thu Sep 20 04:44:41 CEST 2012


ffmpeg | branch: master | Janne Grunau <janne-libav at jannau.net> | Tue Sep 18 15:48:14 2012 +0200| [8701f4f8e8a7aa71c39f0917472d22bf6a1f0f43] | committer: Janne Grunau

mpeg4: support frame parameter changes with frame-mt

Adds a flag context_reinit to MpegEncContext to relieable 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.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=8701f4f8e8a7aa71c39f0917472d22bf6a1f0f43
---

 libavcodec/h263dec.c       |   25 +++++++++++++------------
 libavcodec/mpeg4videodec.c |    3 +++
 libavcodec/mpegvideo.c     |    9 +++++++++
 libavcodec/mpegvideo.h     |    4 ++++
 4 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 8e6085b..ba7fb8a 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -434,13 +434,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,21 +570,29 @@ 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) {
-        /* H.263 could change picture size any time */
+    if (!avctx->coded_width || !avctx->coded_height) {
         ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
 
         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 (s->width  != avctx->coded_width  ||
+        s->height != avctx->coded_height ||
+        s->context_reinit) {
+        /* H.263 could change picture size any time */
+        s->context_reinit = 0;
+
+        avcodec_set_dimensions(avctx, s->width, s->height);
+
+        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))
         s->gob_index = ff_h263_get_gob_height(s);
 
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 27cae9f..4a4998c 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -1600,6 +1600,9 @@ 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 && s->height &&
+                    (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 f9f5c52..5033135 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 ? \



More information about the ffmpeg-cvslog mailing list