Re: [libav-devel] [PATCH 01/10] lavc: Add support for external hardware frame pool initialisation
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
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