diff options
author | Janne Grunau <janne-libav@jannau.net> | 2012-09-18 17:48:14 +0400 |
---|---|---|
committer | Janne Grunau <janne-libav@jannau.net> | 2012-09-19 21:58:15 +0400 |
commit | 8701f4f8e8a7aa71c39f0917472d22bf6a1f0f43 (patch) | |
tree | 8f8ba7cfff9d11c2754e740cf1f887d977af8f33 | |
parent | 01fc5d6609e31539684785295d6c10b84d70b215 (diff) |
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.
-rw-r--r-- | libavcodec/h263dec.c | 25 | ||||
-rw-r--r-- | libavcodec/mpeg4videodec.c | 3 | ||||
-rw-r--r-- | libavcodec/mpegvideo.c | 9 | ||||
-rw-r--r-- | libavcodec/mpegvideo.h | 4 |
4 files changed, 29 insertions, 12 deletions
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 8e6085beeb..ba7fb8ae12 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 27cae9f846..4a4998cdaa 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 f9f5c5263f..50331356fe 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 88a1059102..4c220ecb0a 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 ? \ |