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".

Reply via email to