mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-13 21:28:01 +02:00
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.
This commit is contained in:
parent
01fc5d6609
commit
8701f4f8e8
@ -434,13 +434,6 @@ retry:
|
|||||||
if (ret < 0){
|
if (ret < 0){
|
||||||
av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
|
av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
|
||||||
return -1;
|
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;
|
avctx->has_b_frames= !s->low_delay;
|
||||||
@ -577,21 +570,29 @@ retry:
|
|||||||
/* FIXME: By the way H263 decoder is evolving it should have */
|
/* FIXME: By the way H263 decoder is evolving it should have */
|
||||||
/* an H263EncContext */
|
/* an H263EncContext */
|
||||||
|
|
||||||
if ( s->width != avctx->coded_width
|
if (!avctx->coded_width || !avctx->coded_height) {
|
||||||
|| s->height != avctx->coded_height) {
|
|
||||||
/* H.263 could change picture size any time */
|
|
||||||
ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
|
ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
|
||||||
|
|
||||||
s->parse_context.buffer=0;
|
s->parse_context.buffer=0;
|
||||||
ff_MPV_common_end(s);
|
ff_MPV_common_end(s);
|
||||||
s->parse_context= pc;
|
s->parse_context= pc;
|
||||||
}
|
|
||||||
if (!s->context_initialized) {
|
|
||||||
avcodec_set_dimensions(avctx, s->width, s->height);
|
avcodec_set_dimensions(avctx, s->width, s->height);
|
||||||
|
|
||||||
goto retry;
|
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))
|
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);
|
s->gob_index = ff_h263_get_gob_height(s);
|
||||||
|
|
||||||
|
@ -1600,6 +1600,9 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
|
|||||||
height = get_bits(gb, 13);
|
height = get_bits(gb, 13);
|
||||||
skip_bits1(gb); /* marker */
|
skip_bits1(gb); /* marker */
|
||||||
if(width && height && !(s->width && s->codec_tag == AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */
|
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->width = width;
|
||||||
s->height = height;
|
s->height = height;
|
||||||
}
|
}
|
||||||
|
@ -550,6 +550,15 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
|
|||||||
ff_MPV_common_init(s);
|
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_height = s1->avctx->coded_height;
|
||||||
s->avctx->coded_width = s1->avctx->coded_width;
|
s->avctx->coded_width = s1->avctx->coded_width;
|
||||||
s->avctx->width = s1->avctx->width;
|
s->avctx->width = s1->avctx->width;
|
||||||
|
@ -703,6 +703,10 @@ typedef struct MpegEncContext {
|
|||||||
|
|
||||||
/* temp buffers for rate control */
|
/* temp buffers for rate control */
|
||||||
float *cplx_tab, *bits_tab;
|
float *cplx_tab, *bits_tab;
|
||||||
|
|
||||||
|
/* flag to indicate a reinitialization is required, e.g. after
|
||||||
|
* a frame size change */
|
||||||
|
int context_reinit;
|
||||||
} MpegEncContext;
|
} MpegEncContext;
|
||||||
|
|
||||||
#define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \
|
#define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \
|
||||||
|
Loading…
Reference in New Issue
Block a user