[vlc-commits] d3d11_surface: create the output video context for CPU to D3D11 converters
Steve Lhomme
git at videolan.org
Mon Dec 2 13:42:45 CET 2019
vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Wed Nov 13 10:54:29 2019 +0100| [c8d2030aa6e9e52866f44f21c5dcc25cff613531] | committer: Steve Lhomme
d3d11_surface: create the output video context for CPU to D3D11 converters
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c8d2030aa6e9e52866f44f21c5dcc25cff613531
---
modules/hw/d3d11/d3d11_surface.c | 82 ++++++++++++++++++++++++++++++----------
1 file changed, 61 insertions(+), 21 deletions(-)
diff --git a/modules/hw/d3d11/d3d11_surface.c b/modules/hw/d3d11/d3d11_surface.c
index 8b24f34bdf..81fd0f2fdf 100644
--- a/modules/hw/d3d11/d3d11_surface.c
+++ b/modules/hw/d3d11/d3d11_surface.c
@@ -697,18 +697,63 @@ int D3D11OpenCPUConverter( vlc_object_t *obj )
return VLC_EGENERIC;
}
- d3d11_device_t d3d_dev;
- D3D11_TEXTURE2D_DESC texDesc;
- D3D11_FilterHoldInstance(p_filter, &d3d_dev, &texDesc);
- if (unlikely(!d3d_dev.d3dcontext))
+ vlc_decoder_device *dec_device = filter_HoldDecoderDeviceType( p_filter, VLC_DECODER_DEVICE_D3D11VA );
+ if (dec_device == NULL)
+ {
+ msg_Err(p_filter, "Missing decoder device");
+ return VLC_EGENERIC;
+ }
+ d3d11_decoder_device_t *devsys = GetD3D11OpaqueDevice(dec_device);
+ if (unlikely(devsys == NULL))
+ {
+ msg_Err(p_filter, "Incompatible decoder device %d", dec_device->type);
+ vlc_decoder_device_Release(dec_device);
+ return VLC_EGENERIC;
+ }
+
+ p_sys = vlc_obj_calloc(obj, 1, sizeof(filter_sys_t));
+ if (!p_sys) {
+ vlc_decoder_device_Release(dec_device);
+ return VLC_ENOMEM;
+ }
+
+ HRESULT hr = D3D11_CreateDeviceExternal(p_filter, devsys->device, true, &p_sys->d3d_dev);
+ if (FAILED(hr) || unlikely(!p_sys->d3d_dev.d3dcontext))
{
msg_Dbg(p_filter, "D3D11 opaque without a texture");
+ vlc_decoder_device_Release(dec_device);
return VLC_EGENERIC;
}
video_format_Init(&fmt_staging, 0);
- vlc_fourcc_t d3d_fourcc = DxgiFormatFourcc(texDesc.Format);
+ p_filter->vctx_out = vlc_video_context_Create(dec_device, VLC_VIDEO_CONTEXT_D3D11VA,
+ sizeof(d3d11_video_context_t), &d3d11_vctx_ops);
+ vlc_decoder_device_Release(dec_device);
+
+ if ( p_filter->vctx_out == NULL )
+ {
+ msg_Dbg(p_filter, "no video context");
+ goto done;
+ }
+
+ d3d11_video_context_t *vctx_sys = GetD3D11ContextPrivate( p_filter->vctx_out );
+ switch( p_filter->fmt_in.video.i_chroma ) {
+ case VLC_CODEC_I420:
+ case VLC_CODEC_YV12:
+ case VLC_CODEC_NV12:
+ vctx_sys->format = DXGI_FORMAT_NV12;
+ break;
+ case VLC_CODEC_I420_10L:
+ case VLC_CODEC_P010:
+ vctx_sys->format = DXGI_FORMAT_P010;
+ break;
+ default:
+ vlc_assert_unreachable();
+ }
+ vctx_sys->device = p_sys->d3d_dev.d3dcontext;
+
+ vlc_fourcc_t d3d_fourcc = DxgiFormatFourcc(vctx_sys->format);
if (d3d_fourcc == 0)
goto done;
@@ -721,13 +766,11 @@ int D3D11OpenCPUConverter( vlc_object_t *obj )
goto done;
}
res.p_sys = res_sys;
- res_sys->context = d3d_dev.d3dcontext;
- res_sys->formatTexture = texDesc.Format;
+ res_sys->context = p_sys->d3d_dev.d3dcontext;
+ res_sys->formatTexture = vctx_sys->format;
video_format_Copy(&fmt_staging, &p_filter->fmt_out.video);
fmt_staging.i_chroma = d3d_fourcc;
- fmt_staging.i_height = texDesc.Height;
- fmt_staging.i_width = texDesc.Width;
picture_t *p_dst = picture_NewFromResource(&fmt_staging, &res);
if (p_dst == NULL) {
@@ -737,16 +780,20 @@ int D3D11OpenCPUConverter( vlc_object_t *obj )
picture_sys_d3d11_t *p_dst_sys = p_dst->p_sys;
picture_Setup(p_dst, &p_dst->format);
+ D3D11_TEXTURE2D_DESC texDesc;
+ texDesc.Format = vctx_sys->format;
texDesc.MipLevels = 1;
texDesc.SampleDesc.Count = 1;
+ texDesc.SampleDesc.Quality = 0;
texDesc.MiscFlags = 0;
texDesc.ArraySize = 1;
texDesc.Usage = D3D11_USAGE_STAGING;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
texDesc.BindFlags = 0;
+ texDesc.Width = p_dst->format.i_width;
texDesc.Height = p_dst->format.i_height; /* make sure we match picture_Setup() */
- HRESULT hr = ID3D11Device_CreateTexture2D( d3d_dev.d3ddevice, &texDesc, NULL, &texture);
+ hr = ID3D11Device_CreateTexture2D( p_sys->d3d_dev.d3ddevice, &texDesc, NULL, &texture);
if (FAILED(hr)) {
msg_Err(p_filter, "Failed to create a %s staging texture to extract surface pixels (hr=0x%lX)", DxgiFormatToStr(texDesc.Format), hr );
goto done;
@@ -762,12 +809,6 @@ int D3D11OpenCPUConverter( vlc_object_t *obj )
goto done;
}
- p_sys = vlc_obj_calloc(obj, 1, sizeof(filter_sys_t));
- if (!p_sys) {
- err = VLC_ENOMEM;
- goto done;
- }
-
if (D3D11_Create(p_filter, &p_sys->hd3d, false) != VLC_SUCCESS)
{
msg_Warn(p_filter, "cannot load d3d11.dll, aborting");
@@ -787,11 +828,8 @@ done:
DeleteFilter( p_cpu_filter );
if (texture)
ID3D11Texture2D_Release(texture);
- D3D11_FilterReleaseInstance(&d3d_dev);
- }
- else
- {
- p_sys->d3d_dev = d3d_dev;
+ vlc_video_context_Release(p_filter->vctx_out);
+ D3D11_ReleaseDevice(&p_sys->d3d_dev);
}
return err;
}
@@ -819,5 +857,7 @@ void D3D11CloseCPUConverter( vlc_object_t *obj )
filter_sys_t *p_sys = p_filter->p_sys;
DeleteFilter(p_sys->filter);
picture_Release(p_sys->staging_pic);
+ vlc_video_context_Release(p_filter->vctx_out);
+ D3D11_ReleaseDevice(&p_sys->d3d_dev);
D3D11_Destroy(&p_sys->hd3d);
}
More information about the vlc-commits
mailing list