[FFmpeg-devel] [PATCH v2] dxva: wait until D3D11 buffer copies are done before submitting them
Steve Lhomme
robux4 at ycbcr.xyz
Wed Aug 5 11:43:46 EEST 2020
On 2020-08-05 9:55, Marton Balint wrote:
>
>
> 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.
I do not know. The documentation on SubmitDecoderBuffers or
ReleaseDecoderBuffer doesn't say anything about that. Maybe the driver
documentation that manufacturers use have more information, but I don't
have it.
>>
>> 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
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
More information about the ffmpeg-devel
mailing list