Quoting Mark Thompson (2017-08-06 00:53:02)
> This can be used to refine the parameters of lavc-created hardware frames
> contexts - this is useful for APIs which require some use information to
> to be supplied at create time, such as DXVA2 and D3D11VA. (Suggested by
> wm4 <[email protected]>).
>
> Also adds a field extra_hw_frames, which supports simple cases where the
> only modification to the default parameters required is to increase the
> size of a fixed-size pool.
> ---
> As discussed quite a while ago.
>
>
> doc/APIchanges | 3 +++
> libavcodec/avcodec.h | 36 ++++++++++++++++++++++++++++++++++++
> libavcodec/decode.c | 24 ++++++++++++++++++++++++
> libavcodec/internal.h | 17 +++++++++++++++++
> libavcodec/options_table.h | 1 +
> 5 files changed, 81 insertions(+)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 463247f48..c111d08ad 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -13,6 +13,9 @@ libavutil: 2017-03-23
>
> API changes, most recent first:
>
> +2017-xx-xx - xxxxxxx - lavc 58.x+1.0 - avcodec.h
> + Add AVCodecContext.init_hw_frames and AVCodecContext.extra_hw_frames.
> +
> 2017-xx-xx - xxxxxxx - lavu 56.4.0 - imgutils.h
> Add av_image_fill_black().
>
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 162f1abe4..847b7f139 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -2725,6 +2725,42 @@ typedef struct AVCodecContext {
> * AVCodecContext.get_format callback)
> */
> int hwaccel_flags;
> +
> + /**
> + * Video decoding only. If set by the user, this will be called when
> + * new hardware frames need to be allocated following a get_format()
> + * callback which indicated that hardware decoding should be used but
> + * did not set s->hw_frames_ctx.
> + *
> + * When called, s->hw_frames_ctx will be allocated on the device in
> + * s->hw_device_ctx and have basic parameters set (required pool size,
> + * frame dimensions and surface format). The user can then further
> + * refine the parameters as required for their use-case - for example,
> + * by setting API-specific values in AVHWFramesContext.hwctx, or by
> + * increasing the size of allocated frames to meet some external
> + * constraint. Do not call av_hwframe_ctx_init() from this callback -
> + * it will be called later by lavc.
> + *
> + * This function should normally return zero. If it encounters some
> + * error (e.g. if the user knows that frames of the requested form will
> + * not be usable), it must return a negative error code and decoder
> + * initialisation will then fail, returning control to the user.
This should be clarified - will it call get_format() again like it does
when hwaccel init fails or will decoding fail?
> + */
> + int (*init_hw_frames)(struct AVCodecContext *s);
> +
> + /**
> + * Video decoding only. Sets the number of extra hardware frames which
> + * the decoder will allocate for use by the caller. This is only used
> + * if hw_device_ctx is set.
> + *
> + * Some hardware decoders require all frames that they will use for
> + * output to be defined in advance before decoding starts. For such
> + * decoders, the hardware frame pool must therefore be of a fixed size.
> + * The extra frames set here are on top of any number that the decoder
> + * needs internally in order to operate normally (for example, frames
> + * used as reference pictures).
> + */
> + int extra_hw_frames;
> } AVCodecContext;
>
> /**
> diff --git a/libavcodec/decode.c b/libavcodec/decode.c
> index c76ee6696..6d6088eaa 100644
> --- a/libavcodec/decode.c
> +++ b/libavcodec/decode.c
> @@ -767,6 +767,30 @@ int ff_get_format(AVCodecContext *avctx, const enum
> AVPixelFormat *fmt)
> return ret;
> }
>
> +int ff_init_hw_frames(AVCodecContext *avctx)
> +{
> + AVHWFramesContext *frames;
> + int err;
> +
> + // Must already be set by caller.
> + av_assert0(avctx->hw_frames_ctx);
> +
> + frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
> +
> + if (avctx->init_hw_frames) {
> + err = avctx->init_hw_frames(avctx);
> + if (err < 0)
> + return err;
> + } else if (frames->initial_pool_size == 0) {
> + // Dynamically allocation is necessarily supported.
> + } else {
> + if (avctx->extra_hw_frames >= 0)
> + frames->initial_pool_size += avctx->extra_hw_frames;
> + }
> +
> + return 0;
> +}
> +
> static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame)
> {
> FramePool *pool = avctx->internal->pool;
> diff --git a/libavcodec/internal.h b/libavcodec/internal.h
> index 403fb4a09..023d94285 100644
> --- a/libavcodec/internal.h
> +++ b/libavcodec/internal.h
> @@ -276,6 +276,23 @@ int ff_side_data_update_matrix_encoding(AVFrame *frame,
> int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt);
>
> /**
> + * Perform any additional setup required for hardware frames.
> + *
> + * This calls avctx->init_hw_frames() if set, and in that case all setup
> + * will be performed by the user.
> + * If unset, it will set default values which may be influenced by other
> + * user settings (such as avctx->extra_hw_frames).
> + *
> + * avctx->hw_frames_ctx must be set before calling this function.
> + * Inside avctx->hw_frames_ctx, the fields format, sw_format, width and
> + * height must be set. If dynamically allocated pools are not supported,
> + * then initial_pool_size must also be set, to the minimum hardware frame
> + * pool size necessary for decode (taking into account reference frames
> + * and delay as appropriate).
> + */
> +int ff_init_hw_frames(AVCodecContext *avctx);
Please don't use internal.h as a dump for everything, this belongs in
hwaccel.h
--
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel