[vlc-commits] d3d11va: attempt to get the decoding buffer slices from the decoder pool
Steve Lhomme
git at videolan.org
Sun Oct 9 10:46:25 CEST 2016
vlc | branch: master | Steve Lhomme <robux4 at videolabs.io> | Tue Oct 4 16:15:49 2016 +0200| [75d656c77964f6df86cb744d8d88b1c4b90d582d] | committer: Jean-Baptiste Kempf
d3d11va: attempt to get the decoding buffer slices from the decoder pool
Only works if the slice indices start from 0 which is not the case because
of the reserved pictures in the pool
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=75d656c77964f6df86cb744d8d88b1c4b90d582d
---
modules/codec/avcodec/d3d11va.c | 143 +++++++++++++++++++++++++++++++---------
1 file changed, 112 insertions(+), 31 deletions(-)
diff --git a/modules/codec/avcodec/d3d11va.c b/modules/codec/avcodec/d3d11va.c
index d4ea55f..5831c6e 100644
--- a/modules/codec/avcodec/d3d11va.c
+++ b/modules/codec/avcodec/d3d11va.c
@@ -43,6 +43,7 @@
#include <vlc_charset.h>
#include <vlc_filter.h>
#include <vlc_modules.h>
+#include <vlc_codec.h>
#include "directx_va.h"
@@ -118,6 +119,10 @@ struct vlc_va_sys_t
ID3D11DeviceContext *d3dctx;
HANDLE context_mutex;
+ /* pool */
+ bool b_extern_pool;
+ picture_t *extern_pics[MAX_SURFACE_COUNT];
+
/* Video decoder */
D3D11_VIDEO_DECODER_CONFIG cfg;
@@ -454,6 +459,7 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
sys->d3dctx = p_sys->context;
sys->d3dvidctx = d3dvidctx;
+ sys->b_extern_pool = true;
assert(p_sys->texture != NULL);
D3D11_TEXTURE2D_DESC dstDesc;
@@ -957,45 +963,117 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
ID3D10Multithread_Release(pMultithread);
}
- D3D11_TEXTURE2D_DESC texDesc;
- ZeroMemory(&texDesc, sizeof(texDesc));
- texDesc.Width = dx_sys->surface_width;
- texDesc.Height = dx_sys->surface_height;
- texDesc.MipLevels = 1;
- texDesc.Format = sys->render;
- texDesc.SampleDesc.Count = 1;
- texDesc.MiscFlags = 0;
- texDesc.ArraySize = dx_sys->surface_count;
- texDesc.Usage = D3D11_USAGE_DEFAULT;
- texDesc.BindFlags = D3D11_BIND_DECODER;
- texDesc.CPUAccessFlags = 0;
-
- ID3D11Texture2D *p_texture;
- hr = ID3D11Device_CreateTexture2D( (ID3D11Device*) dx_sys->d3ddev, &texDesc, NULL, &p_texture );
- if (FAILED(hr)) {
- msg_Err(va, "CreateTexture2D %d failed. (hr=0x%0lx)", dx_sys->surface_count, hr);
- dx_sys->surface_count = 0;
- return VLC_EGENERIC;
- }
-
D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
ZeroMemory(&viewDesc, sizeof(viewDesc));
viewDesc.DecodeProfile = dx_sys->input;
viewDesc.ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D;
- int surface_count = dx_sys->surface_count;
- for (dx_sys->surface_count = 0; dx_sys->surface_count < surface_count; dx_sys->surface_count++) {
- viewDesc.Texture2D.ArraySlice = dx_sys->surface_count;
+ if (sys->b_extern_pool)
+ {
+ 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 );
+ sys->extern_pics[surface_idx] = pic;
+ dx_sys->hw_surface[surface_idx] = NULL;
+ if (pic==NULL)
+ {
+ msg_Warn(va, "not enough decoder pictures %d out of %d", surface_idx, dx_sys->surface_count);
+ sys->b_extern_pool = false;
+ break;
+ }
- hr = ID3D11VideoDevice_CreateVideoDecoderOutputView( (ID3D11VideoDevice*) dx_sys->d3ddec,
- (ID3D11Resource*) p_texture,
- &viewDesc,
- (ID3D11VideoDecoderOutputView**) &dx_sys->hw_surface[dx_sys->surface_count] );
+ D3D11_TEXTURE2D_DESC texDesc;
+ ID3D11Texture2D_GetDesc(pic->p_sys->texture, &texDesc);
+ if (texDesc.ArraySize < dx_sys->surface_count)
+ {
+ msg_Warn(va, "not enough decoding slices in the texture (%d/%d)",
+ texDesc.ArraySize, dx_sys->surface_count);
+ sys->b_extern_pool = false;
+ break;
+ }
+ assert(texDesc.Format == sys->render);
+ assert(texDesc.BindFlags & D3D11_BIND_DECODER);
+
+ if (pic->p_sys->slice_index != surface_idx)
+ {
+ msg_Warn(va, "d3d11va requires decoding slices to be the first in the texture (%d/%d)",
+ pic->p_sys->slice_index, surface_idx);
+ sys->b_extern_pool = false;
+ break;
+ }
+
+ viewDesc.Texture2D.ArraySlice = pic->p_sys->slice_index;
+ hr = ID3D11VideoDevice_CreateVideoDecoderOutputView( (ID3D11VideoDevice*) dx_sys->d3ddec,
+ (ID3D11Resource*) pic->p_sys->texture,
+ &viewDesc,
+ &pic->p_sys->decoder );
+ if (FAILED(hr)) {
+ msg_Warn(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%0lx)", surface_idx, hr);
+ sys->b_extern_pool = false;
+ break;
+ }
+ sys->dx_sys.hw_surface[surface_idx] = pic->p_sys->decoder;
+ }
+
+ if (!sys->b_extern_pool)
+ {
+ for (size_t i = 0; i < surface_idx; ++i)
+ {
+ if (dx_sys->hw_surface[i])
+ {
+ ID3D11VideoDecoderOutputView_Release(dx_sys->hw_surface[i]);
+ dx_sys->hw_surface[i] = NULL;
+ }
+ if (sys->extern_pics[i])
+ {
+ sys->extern_pics[i]->p_sys->decoder = NULL;
+ picture_Release(sys->extern_pics[i]);
+ sys->extern_pics[i] = NULL;
+ }
+ }
+ }
+ else
+ msg_Dbg(va, "using external surface pool");
+ }
+
+ if (!sys->b_extern_pool)
+ {
+ D3D11_TEXTURE2D_DESC texDesc;
+ ZeroMemory(&texDesc, sizeof(texDesc));
+ texDesc.Width = dx_sys->surface_width;
+ texDesc.Height = dx_sys->surface_height;
+ texDesc.MipLevels = 1;
+ texDesc.Format = sys->render;
+ texDesc.SampleDesc.Count = 1;
+ texDesc.MiscFlags = 0;
+ texDesc.ArraySize = dx_sys->surface_count;
+ texDesc.Usage = D3D11_USAGE_DEFAULT;
+ texDesc.BindFlags = D3D11_BIND_DECODER;
+ texDesc.CPUAccessFlags = 0;
+
+ ID3D11Texture2D *p_texture;
+ hr = ID3D11Device_CreateTexture2D( (ID3D11Device*) dx_sys->d3ddev, &texDesc, NULL, &p_texture );
if (FAILED(hr)) {
- msg_Err(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%0lx)", dx_sys->surface_count, hr);
- ID3D11Texture2D_Release(p_texture);
+ msg_Err(va, "CreateTexture2D %d failed. (hr=0x%0lx)", dx_sys->surface_count, hr);
+ dx_sys->surface_count = 0;
return VLC_EGENERIC;
}
+
+ int surface_count = dx_sys->surface_count;
+ for (dx_sys->surface_count = 0; dx_sys->surface_count < surface_count; dx_sys->surface_count++) {
+ sys->extern_pics[dx_sys->surface_count] = NULL;
+ viewDesc.Texture2D.ArraySlice = dx_sys->surface_count;
+
+ hr = ID3D11VideoDevice_CreateVideoDecoderOutputView( (ID3D11VideoDevice*) dx_sys->d3ddec,
+ (ID3D11Resource*) p_texture,
+ &viewDesc,
+ (ID3D11VideoDecoderOutputView**) &dx_sys->hw_surface[dx_sys->surface_count] );
+ if (FAILED(hr)) {
+ msg_Err(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%0lx)", dx_sys->surface_count, hr);
+ ID3D11Texture2D_Release(p_texture);
+ return VLC_EGENERIC;
+ }
+ }
}
msg_Dbg(va, "ID3D11VideoDecoderOutputView succeed with %d surfaces (%dx%d)",
dx_sys->surface_count, dx_sys->surface_width, dx_sys->surface_height);
@@ -1073,7 +1151,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, const video_forma
static void DxDestroySurfaces(vlc_va_t *va)
{
directx_sys_t *dx_sys = &va->sys->dx_sys;
- if (dx_sys->surface_count) {
+ if (dx_sys->surface_count && !va->sys->b_extern_pool) {
ID3D11Resource *p_texture;
ID3D11VideoDecoderOutputView_GetResource( (ID3D11VideoDecoderOutputView*) dx_sys->hw_surface[0], &p_texture );
ID3D11Resource_Release(p_texture);
@@ -1095,6 +1173,9 @@ static void DestroyPicture(picture_t *picture)
static picture_t *DxAllocPicture(vlc_va_t *va, const video_format_t *fmt, unsigned index)
{
vlc_va_sys_t *sys = va->sys;
+ if (sys->b_extern_pool)
+ return sys->extern_pics[index];
+
video_format_t src_fmt = *fmt;
src_fmt.i_chroma = sys->i_chroma;
picture_sys_t *pic_sys = calloc(1, sizeof(*pic_sys));
More information about the vlc-commits
mailing list