From e18889396357c2ecb0dd17ed1f8455c58b501250 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sat, 11 Jan 2020 00:01:55 +0900 Subject: [PATCH] d3d11: Don't register decoders if unavailable DXVA requires a hardware interface but may not be available, such as in the case of VMs or when the GPU vendor does not provide a decoder interface. --- sys/d3d11/gstd3d11h264dec.c | 37 +++++++++++++++++++++++++++++++++++++ sys/d3d11/gstd3d11h264dec.h | 4 ++++ sys/d3d11/gstd3d11h265dec.c | 35 +++++++++++++++++++++++++++++++++++ sys/d3d11/gstd3d11h265dec.h | 4 ++++ sys/d3d11/gstd3d11vp9dec.c | 35 +++++++++++++++++++++++++++++++++++ sys/d3d11/gstd3d11vp9dec.h | 4 ++++ sys/d3d11/plugin.c | 16 ++++++++++------ 7 files changed, 129 insertions(+), 6 deletions(-) diff --git a/sys/d3d11/gstd3d11h264dec.c b/sys/d3d11/gstd3d11h264dec.c index b2ef1f8754..966206df7c 100644 --- a/sys/d3d11/gstd3d11h264dec.c +++ b/sys/d3d11/gstd3d11h264dec.c @@ -1206,3 +1206,40 @@ gst_d3d11_h264_dec_decode_slice (GstH264Decoder * decoder, return TRUE; } + +void +gst_d3d11_h264_dec_register (GstPlugin * plugin, GstD3D11Device * device, + guint rank) +{ + GstD3D11Decoder *decoder; + GstVideoInfo info; + gboolean ret; + static const GUID *supported_profiles[] = { + &GST_GUID_D3D11_DECODER_PROFILE_H264_IDCT_FGT, + &GST_GUID_D3D11_DECODER_PROFILE_H264_VLD_NOFGT, + &GST_GUID_D3D11_DECODER_PROFILE_H264_VLD_FGT + }; + + decoder = gst_d3d11_decoder_new (device); + if (!decoder) { + GST_WARNING_OBJECT (device, "decoder interface unavailable"); + return; + } + + /* FIXME: DXVA does not provide API for query supported resolution + * maybe we need some tries per standard resolution (e.g., HD, FullHD ...) + * to check supported resolution */ + gst_video_info_set_format (&info, GST_VIDEO_FORMAT_NV12, 1280, 720); + + ret = gst_d3d11_decoder_open (decoder, GST_D3D11_CODEC_H264, + &info, NUM_OUTPUT_VIEW, supported_profiles, + G_N_ELEMENTS (supported_profiles)); + gst_object_unref (decoder); + + if (!ret) { + GST_WARNING_OBJECT (device, "cannot open decoder device"); + return; + } + + gst_element_register (plugin, "d3d11h264dec", rank, GST_TYPE_D3D11_H264_DEC); +} diff --git a/sys/d3d11/gstd3d11h264dec.h b/sys/d3d11/gstd3d11h264dec.h index 13a80198e4..388668aebc 100644 --- a/sys/d3d11/gstd3d11h264dec.h +++ b/sys/d3d11/gstd3d11h264dec.h @@ -80,6 +80,10 @@ struct _GstD3D11H264DecClass GType gst_d3d11_h264_dec_get_type (void); +void gst_d3d11_h264_dec_register (GstPlugin * plugin, + GstD3D11Device * device, + guint rank); + G_END_DECLS #endif /* __GST_D3D11_H264_DEC_H__ */ diff --git a/sys/d3d11/gstd3d11h265dec.c b/sys/d3d11/gstd3d11h265dec.c index 94f0bf8cd8..fec9d48846 100644 --- a/sys/d3d11/gstd3d11h265dec.c +++ b/sys/d3d11/gstd3d11h265dec.c @@ -1423,3 +1423,38 @@ gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder, return TRUE; } + +void +gst_d3d11_h265_dec_register (GstPlugin * plugin, GstD3D11Device * device, + guint rank) +{ + GstD3D11Decoder *decoder; + GstVideoInfo info; + gboolean ret; + static const GUID *supported_profiles[] = { + &GST_GUID_D3D11_DECODER_PROFILE_HEVC_VLD_MAIN, + }; + + decoder = gst_d3d11_decoder_new (device); + if (!decoder) { + GST_WARNING_OBJECT (device, "decoder interface unavailable"); + return; + } + + /* FIXME: DXVA does not provide API for query supported resolution + * maybe we need some tries per standard resolution (e.g., HD, FullHD ...) + * to check supported resolution */ + gst_video_info_set_format (&info, GST_VIDEO_FORMAT_NV12, 1280, 720); + + ret = gst_d3d11_decoder_open (decoder, GST_D3D11_CODEC_H265, + &info, NUM_OUTPUT_VIEW, supported_profiles, + G_N_ELEMENTS (supported_profiles)); + gst_object_unref (decoder); + + if (!ret) { + GST_WARNING_OBJECT (device, "cannot open decoder device"); + return; + } + + gst_element_register (plugin, "d3d11h265dec", rank, GST_TYPE_D3D11_H265_DEC); +} diff --git a/sys/d3d11/gstd3d11h265dec.h b/sys/d3d11/gstd3d11h265dec.h index 71febf923f..33c9c2df16 100644 --- a/sys/d3d11/gstd3d11h265dec.h +++ b/sys/d3d11/gstd3d11h265dec.h @@ -81,6 +81,10 @@ struct _GstD3D11H265DecClass GType gst_d3d11_h265_dec_get_type (void); +void gst_d3d11_h265_dec_register (GstPlugin * plugin, + GstD3D11Device * device, + guint rank); + G_END_DECLS #endif /* __GST_D3D11_H265_DEC_H__ */ diff --git a/sys/d3d11/gstd3d11vp9dec.c b/sys/d3d11/gstd3d11vp9dec.c index d047e059ad..ea83c2eca8 100644 --- a/sys/d3d11/gstd3d11vp9dec.c +++ b/sys/d3d11/gstd3d11vp9dec.c @@ -1188,3 +1188,38 @@ gst_d3d11_vp9_dec_end_picture (GstVp9Decoder * decoder, GstVp9Picture * picture) return TRUE; } + +void +gst_d3d11_vp9_dec_register (GstPlugin * plugin, GstD3D11Device * device, + guint rank) +{ + GstD3D11Decoder *decoder; + GstVideoInfo info; + gboolean ret; + static const GUID *supported_profiles[] = { + &GST_GUID_D3D11_DECODER_PROFILE_VP9_VLD_PROFILE0, + }; + + decoder = gst_d3d11_decoder_new (device); + if (!decoder) { + GST_WARNING_OBJECT (device, "decoder interface unavailable"); + return; + } + + /* FIXME: DXVA does not provide API for query supported resolution + * maybe we need some tries per standard resolution (e.g., HD, FullHD ...) + * to check supported resolution */ + gst_video_info_set_format (&info, GST_VIDEO_FORMAT_NV12, 1280, 720); + + ret = gst_d3d11_decoder_open (decoder, GST_D3D11_CODEC_VP9, + &info, NUM_OUTPUT_VIEW, supported_profiles, + G_N_ELEMENTS (supported_profiles)); + gst_object_unref (decoder); + + if (!ret) { + GST_WARNING_OBJECT (device, "cannot open decoder device"); + return; + } + + gst_element_register (plugin, "d3d11vp9dec", rank, GST_TYPE_D3D11_VP9_DEC); +} diff --git a/sys/d3d11/gstd3d11vp9dec.h b/sys/d3d11/gstd3d11vp9dec.h index ee8001503d..61442fa9d3 100644 --- a/sys/d3d11/gstd3d11vp9dec.h +++ b/sys/d3d11/gstd3d11vp9dec.h @@ -67,6 +67,10 @@ struct _GstD3D11Vp9DecClass GType gst_d3d11_vp9_dec_get_type (void); +void gst_d3d11_vp9_dec_register (GstPlugin * plugin, + GstD3D11Device * device, + guint rank); + G_END_DECLS #endif /* __GST_D3D11_VP9_DEC_H__ */ diff --git a/sys/d3d11/plugin.c b/sys/d3d11/plugin.c index b57c780467..c715caa7ab 100644 --- a/sys/d3d11/plugin.c +++ b/sys/d3d11/plugin.c @@ -92,6 +92,8 @@ plugin_init (GstPlugin * plugin) #ifdef HAVE_DXVA_H /* DXVA2 API is availble since Windows 8 */ if (gst_d3d11_is_windows_8_or_greater ()) { + GstD3D11Device *device; + GST_DEBUG_CATEGORY_INIT (gst_d3d11_h264_dec_debug, "d3d11h264dec", 0, "Direct3D11 H.264 Video Decoder"); GST_DEBUG_CATEGORY_INIT (gst_d3d11_vp9_dec_debug, @@ -99,12 +101,14 @@ plugin_init (GstPlugin * plugin) GST_DEBUG_CATEGORY_INIT (gst_d3d11_h265_dec_debug, "d3d11h265dec", 0, "Direct3D11 H.265 Video Decoder"); - gst_element_register (plugin, - "d3d11h264dec", GST_RANK_SECONDARY, GST_TYPE_D3D11_H264_DEC); - gst_element_register (plugin, - "d3d11vp9dec", GST_RANK_SECONDARY, GST_TYPE_D3D11_VP9_DEC); - gst_element_register (plugin, - "d3d11h265dec", GST_RANK_SECONDARY, GST_TYPE_D3D11_H265_DEC); + device = gst_d3d11_device_new (0); + if (device) { + gst_d3d11_h264_dec_register (plugin, device, GST_RANK_SECONDARY); + gst_d3d11_h265_dec_register (plugin, device, GST_RANK_SECONDARY); + gst_d3d11_vp9_dec_register (plugin, device, GST_RANK_SECONDARY); + + gst_object_unref (device); + } } #endif