[vlc-devel] [PATCH 05/15] d3d11va: use the picture from the decoder pool directly
Steve Lhomme
robux4 at videolabs.io
Wed Feb 8 14:26:52 CET 2017
From: Steve Lhomme <robUx4 at videolabs.io>
No need to extract into a secondary one to send to the vout and so a
CopySubresourceRegion() for every frame decoded.
Rework the mutex locking as in this new case we don't do anything in
Extract() anymore.
--
replaces https://patches.videolan.org/patch/15193/
- use the proper version numbers for FFmpeg/libav
- use a define for the proper usable versions
---
modules/codec/avcodec/d3d11va.c | 74 +++++++++++++++++++++++++++++++++++------
1 file changed, 63 insertions(+), 11 deletions(-)
diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index 4e90d86..c33f77c 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -70,6 +70,13 @@ vlc_module_end()
#define pf_CreateDevice D3D11CreateDevice
#endif
+/*
+ * In this mode libavcodec doesn't need the whole array on texture on startup
+ * So we get the surfaces from the decoder pool when needed. We don't need to
+ * extract the decoded surface into the decoder picture anymore.
+ */
+#define D3D11_DIRECT_DECODE LIBAVCODEC_VERSION_CHECK( 57, 30, 3, 72, 101 )
+
#include <initguid.h> /* must be last included to not redefine existing GUIDs */
/* dxva2api.h GUIDs: http://msdn.microsoft.com/en-us/library/windows/desktop/ms697067(v=vs100).aspx
@@ -247,16 +254,16 @@ static int Extract(vlc_va_t *va, picture_t *output, uint8_t *data)
assert(p_sys_out->texture != NULL);
- if( sys->context_mutex != INVALID_HANDLE_VALUE ) {
- WaitForSingleObjectEx( sys->context_mutex, INFINITE, FALSE );
- }
-
#ifdef ID3D11VideoContext_VideoProcessorBlt
if (sys->videoProcessor)
{
picture_sys_t *p_sys_in = surface->p_pic->p_sys;
assert(p_sys_in->decoder == src);
+ if( sys->context_mutex != INVALID_HANDLE_VALUE ) {
+ WaitForSingleObjectEx( sys->context_mutex, INFINITE, FALSE );
+ }
+
// extract the decoded video to a the output Texture
if (p_sys_out->decoder == NULL)
{
@@ -289,15 +296,25 @@ static int Extract(vlc_va_t *va, picture_t *output, uint8_t *data)
{
msg_Err(va, "Failed to process the video. (hr=0x%lX)", hr);
ret = VLC_EGENERIC;
- goto done;
+ }
+done:
+ if( sys->context_mutex != INVALID_HANDLE_VALUE ) {
+ ReleaseMutex( sys->context_mutex );
}
}
+#endif
+#if !D3D11_DIRECT_DECODE
+#ifdef ID3D11VideoContext_VideoProcessorBlt
else
#endif
{
picture_sys_t *p_sys_in = surface->p_pic->p_sys;
assert(p_sys_in->decoder == src);
+ if( sys->context_mutex != INVALID_HANDLE_VALUE ) {
+ WaitForSingleObjectEx( sys->context_mutex, INFINITE, FALSE );
+ }
+
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
ID3D11VideoDecoderOutputView_GetDesc( src, &viewDesc );
@@ -313,7 +330,11 @@ static int Extract(vlc_va_t *va, picture_t *output, uint8_t *data)
p_sys_in->resource,
viewDesc.Texture2D.ArraySlice,
©Box);
+ if( sys->context_mutex != INVALID_HANDLE_VALUE ) {
+ ReleaseMutex( sys->context_mutex );
+ }
}
+#endif
}
break;
case VLC_CODEC_YV12:
@@ -327,12 +348,6 @@ static int Extract(vlc_va_t *va, picture_t *output, uint8_t *data)
break;
}
-
-done:
- if( sys->context_mutex != INVALID_HANDLE_VALUE ) {
- ReleaseMutex( sys->context_mutex );
- }
-
return ret;
}
@@ -356,7 +371,36 @@ static int CheckDevice(vlc_va_t *va)
static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
{
+#if D3D11_DIRECT_DECODE
+ picture_sys_t *p_sys = pic->p_sys;
+ if (p_sys->decoder == NULL)
+ {
+ HRESULT hr;
+
+ directx_sys_t *dx_sys = &va->sys->dx_sys;
+
+ D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
+ ZeroMemory(&viewDesc, sizeof(viewDesc));
+ viewDesc.DecodeProfile = dx_sys->input;
+ viewDesc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
+ viewDesc.Texture2D.ArraySlice = p_sys->slice_index;
+
+ hr = ID3D11VideoDevice_CreateVideoDecoderOutputView( (ID3D11VideoDevice*) dx_sys->d3ddec,
+ (ID3D11Resource*) p_sys->texture,
+ &viewDesc,
+ &p_sys->decoder );
+ if (FAILED(hr)) {
+ msg_Warn(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%0lx)", p_sys->slice_index, hr);
+ p_sys->decoder = NULL;
+ }
+ }
+ if (p_sys->decoder == NULL)
+ return VLC_EGENERIC;
+ *data = p_sys->decoder;
+ return VLC_SUCCESS;
+#else
return directx_va_Get(va, &va->sys->dx_sys, pic, data);
+#endif
}
static void Close(vlc_va_t *va, AVCodecContext *ctx)
@@ -487,7 +531,11 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
va->description = DxDescribe(dx_sys);
va->setup = Setup;
va->get = Get;
+#if D3D11_DIRECT_DECODE
+ va->release = NULL;
+#else
va->release = directx_va_Release;
+#endif
va->extract = Extract;
return VLC_SUCCESS;
@@ -962,6 +1010,9 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
if (sys->b_extern_pool)
{
+#if D3D11_DIRECT_DECODE
+ dx_sys->surface_count = 0;
+#else
size_t surface_idx;
for (surface_idx = 0; surface_idx < dx_sys->surface_count; surface_idx++) {
picture_t *pic = decoder_NewPicture( (decoder_t*) va->obj.parent );
@@ -1027,6 +1078,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
}
}
else
+#endif
msg_Dbg(va, "using external surface pool");
}
--
2.10.2
More information about the vlc-devel
mailing list