James Almer: > With this, callers can signal supported encoders to reinitialize using certain > parameters, which should allow for more graceful (but potentially more limited > in scope) reinitialization than closing and reopening the encoder, or even > simply on-the-fly changes of trivial values that would not require any kind > or flushing or reinitialization by the encoder. > > Signed-off-by: James Almer <jamr...@gmail.com> > ---
I don't really see the big improvement over closing+reopening the encoder. > libavcodec/codec_internal.h | 2 ++ > libavcodec/encode.c | 69 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 71 insertions(+) > > diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h > index 5b2db74590..e38402d2f5 100644 > --- a/libavcodec/codec_internal.h > +++ b/libavcodec/codec_internal.h > @@ -243,6 +243,8 @@ typedef struct FFCodec { > */ > void (*flush)(struct AVCodecContext *); > > + int (*reconf)(struct AVCodecContext *); > + > /** > * Decoding only, a comma-separated list of bitstream filters to apply to > * packets before decoding. > diff --git a/libavcodec/encode.c b/libavcodec/encode.c > index 3baf5b8103..187b4015f1 100644 > --- a/libavcodec/encode.c > +++ b/libavcodec/encode.c > @@ -31,6 +31,7 @@ > > #include "avcodec.h" > #include "avcodec_internal.h" > +#include "bytestream.h" > #include "codec_desc.h" > #include "codec_internal.h" > #include "encode.h" > @@ -59,6 +60,69 @@ static EncodeContext *encode_ctx(AVCodecInternal *avci) > return (EncodeContext*)avci; > } > > +static int apply_param_change(AVCodecContext *avctx, const AVFrame *frame) > +{ > + int ret = AVERROR_BUG; > + const AVFrameSideData *sd; > + GetByteContext gbc; > + uint32_t flags; > + > + sd = av_frame_get_side_data(frame, AV_FRAME_DATA_PARAM_CHANGE); > + if (!sd) > + return 0; > + > + if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { > + av_log(avctx, AV_LOG_ERROR, "This encoder does not support parameter > " > + "changes, but PARAM_CHANGE side data was sent to it.\n"); > + ret = AVERROR(EINVAL); > + goto fail2; > + } > + > + if (sd->size < 4) > + goto fail; > + > + bytestream2_init(&gbc, sd->data, sd->size); > + flags = bytestream2_get_le32(&gbc); > + > + if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { > + if (frame->sample_rate <= 0 || frame->sample_rate > INT_MAX) { > + av_log(avctx, AV_LOG_ERROR, "Invalid sample rate"); > + ret = AVERROR_INVALIDDATA; > + goto fail2; > + } > + avctx->sample_rate = frame->sample_rate; > + } > + if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { > + av_image_check_size2(frame->width, frame->height, avctx->max_pixels, > avctx->pix_fmt, 0, avctx); > + if (ret < 0) { > + av_log(avctx, AV_LOG_ERROR, "Invalid dimensions"); > + goto fail2; > + } > + avctx->width = frame->width; > + avctx->height = frame->height; > + } > + > + if (flags) { > + ret = 0; > + if (ffcodec(avctx->codec)->reconf) > + ret = ffcodec(avctx->codec)->reconf(avctx); > + if (ret < 0) > + goto fail2; > + } > + > + return 0; > +fail: > + av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); > + ret = AVERROR_INVALIDDATA; > +fail2: > + if (ret < 0) { > + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); > + if (avctx->err_recognition & AV_EF_EXPLODE) > + return ret; > + } > + return 0; > +} > + > int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size) > { > if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { > @@ -205,6 +269,7 @@ int avcodec_encode_subtitle(AVCodecContext *avctx, > uint8_t *buf, int buf_size, > int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame) > { > AVCodecInternal *avci = avctx->internal; > + int ret; > > if (avci->draining) > return AVERROR_EOF; > @@ -229,6 +294,10 @@ FF_DISABLE_DEPRECATION_WARNINGS > FF_ENABLE_DEPRECATION_WARNINGS > #endif > > + ret = apply_param_change(avctx, frame); > + if (ret < 0) > + return ret; > + > return 0; > } > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".