vlc | branch: master | Steve Lhomme <[email protected]> | 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); } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
