[FFmpeg-devel] [PATCH 4/5] fftools/ffmpeg: flush and recreate encoder instance if resolution changes
Fu, Linjie
linjie.fu at intel.com
Wed Jun 10 06:12:02 EEST 2020
> From: Devin Heitmueller <devin.heitmueller at ltnglobal.com>
> Sent: Tuesday, June 9, 2020 23:47
> To: FFmpeg development discussions and patches <ffmpeg-
> devel at ffmpeg.org>
> Cc: Fu, Linjie <linjie.fu at intel.com>
> Subject: Re: [FFmpeg-devel] [PATCH 4/5] fftools/ffmpeg: flush and recreate
> encoder instance if resolution changes
>
> On Tue, Jun 9, 2020 at 4:53 AM Linjie Fu <linjie.fu at intel.com> wrote:
> >
> > Signed-off-by: Linjie Fu <linjie.fu at intel.com>
> > ---
> > Should be squashed with:
> > https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=1434
> >
> > fftools/ffmpeg.c | 11 +++++++++++
> > 1 file changed, 11 insertions(+)
> >
> > diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
> > index 5859781..8cdd532 100644
> > --- a/fftools/ffmpeg.c
> > +++ b/fftools/ffmpeg.c
> > @@ -130,6 +130,7 @@ static void do_video_stats(OutputStream *ost, int
> frame_size);
> > static BenchmarkTimeStamps get_benchmark_time_stamps(void);
> > static int64_t getmaxrss(void);
> > static int ifilter_has_all_input_formats(FilterGraph *fg);
> > +static void flush_encoders(void);
> >
> > static int run_as_daemon = 0;
> > static int nb_frames_dup = 0;
> > @@ -1058,11 +1059,21 @@ static void do_video_out(OutputFile *of,
> >
> > if (next_picture && (enc->width != next_picture->width ||
> > enc->height != next_picture->height)) {
> > + flush_encoders();
> > + avcodec_flush_buffers(enc);
> > if (!(enc->codec->capabilities &
> AV_CODEC_CAP_VARIABLE_DIMENSIONS)) {
> > av_log(NULL, AV_LOG_ERROR, "Variable dimension encoding "
> > "is not supported by %s.\n", enc->codec->name);
> > goto error;
> > }
> > +
> > + enc->width = next_picture->width;
> > + enc->height = next_picture->height;
>
> Perhaps from a workflow standpoint it makes more sense to move the
> code which changes the encoder parameters to after where you close the
> existing encoder (i.e. between the close and init calls). I can't
> think of a specific case where this might break a downstream encoder,
That's the reason I simply set the width/height ahead.
> but it seems like a good practice to only have the parameters applied
> to the new encoder instance.
Indeed, fixed locally.
> > +
> > + if (enc->codec->close(enc) < 0)
> > + goto error;
> > + if (enc->codec->init(enc) < 0)
> > + goto error;
> > }
> >
> > if (ost->source_index >= 0)
>
> In general do we really think this is a safe thing to do? Does
> something also need to be propagated to the output as well? I know
> that this would break use cases like the decklink output where the
> frame resolution suddenly changes in the middle of the stream without
> calling the output's write_header() routine.
Yes, noticed the constraints in sequence header and container.
Since resolution changing is allowed in single bitstream, one global header is not
enough anymore as Nicolas has pointed out in [1].
Hence as to the container level, for the formats with AVFMT_GLOBALHEADER flag,
we should place sps/pps information in key frame instead of in extradata.
(e.g. disable AV_CODEC_FLAG_GLOBAL_HEADER)
- if (oc->oformat->flags & AVFMT_GLOBALHEADER)
+ if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->autoscale)
ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
Verified this works, at least for containers like mp4.
- Linjie
[1] https://patchwork.ffmpeg.org/project/ffmpeg/patch/1591606685-4450-1-git-send-email-linjie.fu@intel.com/#55293
More information about the ffmpeg-devel
mailing list