[FFmpeg-devel] [PATCH v2] dxva: wait until D3D11 buffer copies are done before submitting them
Marton Balint
cus at passwd.hu
Wed Aug 5 10:55:04 EEST 2020
On Wed, 5 Aug 2020, Steve Lhomme wrote:
> When used aggressively, calling SubmitDecoderBuffers() just after
> ReleaseDecoderBuffer() may have the buffers not used properly and created
> decoding artifacts.
> It's likely due to the time to copy the submitted buffer in CPU mapped memory
> to GPU memory. SubmitDecoderBuffers() doesn't appear to wait for the state
> of the buffer submitted to become "ready".
Is this an API bug or the code is not using the API properly? Please
clarify this in the commit message if you can.
>
> For now it's not supported in the legacy API using AVD3D11VAContext, we need to
> add a ID3D11DeviceContext in there as it cannot be derived from the other
> interfaces we provide (ID3D11VideoContext is not a kind of ID3D11DeviceContext).
> ---
> libavcodec/dxva2.c | 33 +++++++++++++++++++++++++++++++++
> libavcodec/dxva2_internal.h | 2 ++
> 2 files changed, 35 insertions(+)
>
> diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
> index 32416112bf..1a0e5b69b2 100644
> --- a/libavcodec/dxva2.c
> +++ b/libavcodec/dxva2.c
> @@ -692,6 +692,12 @@ int ff_dxva2_decode_init(AVCodecContext *avctx)
> d3d11_ctx->surface = sctx->d3d11_views;
> d3d11_ctx->workaround = sctx->workaround;
> d3d11_ctx->context_mutex = INVALID_HANDLE_VALUE;
> +
> + D3D11_QUERY_DESC query = { 0 };
> + query.Query = D3D11_QUERY_EVENT;
> + if (FAILED(ID3D11Device_CreateQuery(device_hwctx->device, &query,
> + (ID3D11Query**)&sctx->wait_copies)))
> + sctx->wait_copies = NULL;
> }
> #endif
>
> @@ -729,6 +735,8 @@ int ff_dxva2_decode_uninit(AVCodecContext *avctx)
> av_buffer_unref(&sctx->decoder_ref);
>
> #if CONFIG_D3D11VA
> + if (sctx->wait_copies)
> + ID3D11Asynchronous_Release(sctx->wait_copies);
> for (i = 0; i < sctx->nb_d3d11_views; i++) {
> if (sctx->d3d11_views[i])
> ID3D11VideoDecoderOutputView_Release(sctx->d3d11_views[i]);
> @@ -932,6 +940,12 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
>
> #if CONFIG_D3D11VA
> if (ff_dxva2_is_d3d11(avctx)) {
> + if (sctx->wait_copies) {
> + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
> + AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
> + ID3D11DeviceContext_Begin(device_hwctx->device_context, sctx->wait_copies);
> + }
> +
> buffer = &buffer11[buffer_count];
> type = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
> }
> @@ -1005,9 +1019,28 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
>
> #if CONFIG_D3D11VA
> if (ff_dxva2_is_d3d11(avctx))
> + {
coding style, same line opening brackets
> + int maxWait = 10;
You can push this initialization (and maybe the comment below) one block
down as far as I see.
> + /* wait until all the buffer release is done copying data to the GPU
> + * before doing the submit command */
> + if (sctx->wait_copies) {
> + AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
> + AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
> + ID3D11DeviceContext_End(device_hwctx->device_context, sctx->wait_copies);
> +
> + while (maxWait-- && S_FALSE ==
> + ID3D11DeviceContext_GetData(device_hwctx->device_context,
> + sctx->wait_copies, NULL, 0, 0)) {
> + ff_dxva2_unlock(avctx);
> + SleepEx(2, TRUE);
> + ff_dxva2_lock(avctx);
> + }
> + }
> +
> hr = ID3D11VideoContext_SubmitDecoderBuffers(D3D11VA_CONTEXT(ctx)->video_context,
> D3D11VA_CONTEXT(ctx)->decoder,
> buffer_count, buffer11);
> + }
> #endif
> #if CONFIG_DXVA2
> if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
> index b822af59cd..c44e8e09b0 100644
> --- a/libavcodec/dxva2_internal.h
> +++ b/libavcodec/dxva2_internal.h
> @@ -81,6 +81,8 @@ typedef struct FFDXVASharedContext {
> ID3D11VideoDecoderOutputView **d3d11_views;
> int nb_d3d11_views;
> ID3D11Texture2D *d3d11_texture;
> +
> + ID3D11Asynchronous *wait_copies;
> #endif
>
Regards,
Marton
More information about the ffmpeg-devel
mailing list