d3d11: Don't register decoders if unavailable
authorSeungha Yang <seungha.yang@navercorp.com>
Fri, 10 Jan 2020 15:01:55 +0000 (00:01 +0900)
committerSeungha Yang <seungha.yang@navercorp.com>
Sat, 11 Jan 2020 08:42:04 +0000 (17:42 +0900)
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
sys/d3d11/gstd3d11h264dec.h
sys/d3d11/gstd3d11h265dec.c
sys/d3d11/gstd3d11h265dec.h
sys/d3d11/gstd3d11vp9dec.c
sys/d3d11/gstd3d11vp9dec.h
sys/d3d11/plugin.c

index b2ef1f8..966206d 100644 (file)
@@ -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);
+}
index 13a8019..388668a 100644 (file)
@@ -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__ */
index 94f0bf8..fec9d48 100644 (file)
@@ -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);
+}
index 71febf9..33c9c2d 100644 (file)
@@ -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__ */
index d047e05..ea83c2e 100644 (file)
@@ -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);
+}
index ee80015..61442fa 100644 (file)
@@ -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__ */
index b57c780..c715caa 100644 (file)
@@ -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