[FFmpeg-devel] [PATCH] d3d11va: let user can create SRV from output

Hendrik Leppkes h.leppkes at gmail.com
Wed Mar 9 09:20:46 EET 2022


On Wed, Mar 9, 2022 at 7:56 AM Wang Chuan <ouchuanm at outlook.com> wrote:
>
> Starting from Windows 8, users can create SRV from video resource
> and bind it to shaders directly. This can avoid unnecessary memcpy
> (ID3D11DeviceContext::CopyResource, etc), so create texture with
> [D3D11_BIND_SHADER_RESOURCE] as decoder's output if possible.
>
> Signed-off-by: Wang Chuan <ouchuanm at outlook.com>
> ---
>   libavcodec/dxva2.c            |  2 +-
>   libavutil/hwcontext_d3d11va.c | 10 ++++++++++
>   2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
> index 568d686f39..15b25d793c 100644
> --- a/libavcodec/dxva2.c
> +++ b/libavcodec/dxva2.c
> @@ -645,7 +645,7 @@ int ff_dxva2_common_frame_params(AVCodecContext *avctx,
>       if (frames_ctx->format == AV_PIX_FMT_D3D11) {
>           AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
>   -        frames_hwctx->BindFlags |= D3D11_BIND_DECODER;
> +        frames_hwctx->BindFlags |= (D3D11_BIND_DECODER |
> D3D11_BIND_SHADER_RESOURCE);
>       }
>   #endif
>   diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c
> index 8ab96bad25..97ffd745bd 100644
> --- a/libavutil/hwcontext_d3d11va.c
> +++ b/libavutil/hwcontext_d3d11va.c
> @@ -203,6 +203,11 @@ static AVBufferRef
> *d3d11va_alloc_single(AVHWFramesContext *ctx)
>       };
>        hr = ID3D11Device_CreateTexture2D(device_hwctx->device, &texDesc,
> NULL, &tex);
> +    if (FAILED(hr) && (texDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) {
> +        av_log(ctx, AV_LOG_ERROR, "Could not create the texture with
> [D3D11_BIND_SHADER_RESOURCE] flag");
> +        texDesc.BindFlags &= ~D3D11_BIND_SHADER_RESOURCE;
> +        hr = ID3D11Device_CreateTexture2D(device_hwctx->device,
> &texDesc, NULL, &tex);
> +    }
>       if (FAILED(hr)) {
>           av_log(ctx, AV_LOG_ERROR, "Could not create the texture
> (%lx)\n", (long)hr);
>           return NULL;
> @@ -278,6 +283,11 @@ static int d3d11va_frames_init(AVHWFramesContext *ctx)
>           }
>       } else if (!(texDesc.BindFlags & D3D11_BIND_RENDER_TARGET) &&
> texDesc.ArraySize > 0) {
>           hr = ID3D11Device_CreateTexture2D(device_hwctx->device,
> &texDesc, NULL, &hwctx->texture);
> +        if (FAILED(hr) && (texDesc.BindFlags &
> D3D11_BIND_SHADER_RESOURCE)) {
> +            av_log(ctx, AV_LOG_ERROR, "Could not create the texture
> with [D3D11_BIND_SHADER_RESOURCE] flag");
> +            texDesc.BindFlags &= ~D3D11_BIND_SHADER_RESOURCE;
> +            hr = ID3D11Device_CreateTexture2D(device_hwctx->device,
> &texDesc, NULL, &hwctx->texture);
> +        }

I really don't like these fallbacks. If a caller requests a certain
set of flags, it should fullfill these, or fail, and not change them.
Especially special-casing this one flag just makes it extra iffy, and
I know why you added it, but that doesn't help.

IMHO, its also not entirely unreasonable that if you require anything
but the default flags, to let the user just manage their own frames
context, the effort required is not that high and there is never a set
of flags you can set that'll cover every use case (for example, I use
surface sharing, thats not set by default either).

- Hendrik


More information about the ffmpeg-devel mailing list