Re: [libav-devel] [PATCH 01/10] lavc: Add support for external hardware frame pool initialisation

2017-08-18 Thread Anton Khirnov
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 ).
> 
> 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 - xxx - lavc 58.x+1.0 - avcodec.h
> +  Add AVCodecContext.init_hw_frames and AVCodecContext.extra_hw_frames.
> +
>  2017-xx-xx - xxx - 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 AVP

Re: [libav-devel] [PATCH 01/10] lavc: Add support for external hardware frame pool initialisation

2017-08-07 Thread wm4
On Sat,  5 Aug 2017 23:53:02 +0100
Mark Thompson  wrote:

> 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 ).
> 
> 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 - xxx - lavc 58.x+1.0 - avcodec.h
> +  Add AVCodecContext.init_hw_frames and AVCodecContext.extra_hw_frames.
> +
>  2017-xx-xx - xxx - 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.
> + */
> +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.
> + *
> + * T