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