d3d11decoder: Disable zero-copy for Qualcomm devices

Qualcomm driver looks buggy in zero-copy scenario. Even if we disable
zero-copy, device-to-device memory copy will be used with d3d11videosink
which should be fast enough.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1432>
This commit is contained in:
Seungha Yang 2020-07-12 01:22:55 +09:00
parent c0e809d6b8
commit 495ed45d05
4 changed files with 58 additions and 15 deletions

View file

@ -93,7 +93,7 @@ struct _GstD3D11DecoderPrivate
GUID decoder_profile;
/* For device specific workaround */
gboolean is_xbox_device;
gboolean can_direct_rendering;
/* for internal shader */
GstD3D11ColorConverter *converter;
@ -636,6 +636,7 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec,
gint i;
guint aligned_width, aligned_height;
guint alignment;
GstD3D11DeviceVendor vendor;
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
g_return_val_if_fail (codec > GST_D3D11_CODEC_NONE, FALSE);
@ -676,7 +677,22 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec,
gst_d3d11_decoder_reset_unlocked (decoder);
priv->is_xbox_device = gst_d3d11_is_xbox_device (priv->device);
priv->can_direct_rendering = TRUE;
vendor = gst_d3d11_get_device_vendor (priv->device);
switch (vendor) {
case GST_D3D11_DEVICE_VENDOR_XBOX:
case GST_D3D11_DEVICE_VENDOR_QUALCOMM:
/* FIXME: Need to figure out Xbox device's behavior
* https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1312
*
* Qualcomm driver seems to be buggy in zero-copy scenario
*/
priv->can_direct_rendering = FALSE;
break;
default:
break;
}
/* NOTE: other dxva implementations (ffmpeg and vlc) do this
* and they say the required alignment were mentioned by dxva spec.
@ -686,7 +702,7 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec,
switch (codec) {
case GST_D3D11_CODEC_H265:
/* See directx_va_Setup() impl. in vlc */
if (!priv->is_xbox_device)
if (vendor != GST_D3D11_DEVICE_VENDOR_XBOX)
alignment = 128;
else
alignment = 16;
@ -1605,10 +1621,7 @@ gst_d3d11_decoder_supports_direct_rendering (GstD3D11Decoder * decoder)
priv = decoder->priv;
/* FIXME: Need to figure out Xbox device's behavior
* https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1312
*/
return !priv->is_xbox_device;
return priv->can_direct_rendering;
}
/* Keep sync with chromium and keep in sorted order.

View file

@ -346,25 +346,44 @@ gst_d3d11_is_windows_8_or_greater (void)
return ret;
}
gboolean
gst_d3d11_is_xbox_device (GstD3D11Device * device)
GstD3D11DeviceVendor
gst_d3d11_get_device_vendor (GstD3D11Device * device)
{
guint device_id = 0;
guint vendor_id = 0;
gchar *desc = NULL;
gboolean ret = FALSE;
GstD3D11DeviceVendor vendor = GST_D3D11_DEVICE_VENDOR_UNKNOWN;
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
g_object_get (device, "device-id", &device_id, "vendor-id", &vendor_id,
"description", &desc, NULL);
if (device_id == 0 && vendor_id == 0 && desc && g_strrstr (desc, "SraKmd"))
ret = TRUE;
switch (vendor_id) {
case 0:
if (device_id == 0 && desc && g_strrstr (desc, "SraKmd"))
vendor = GST_D3D11_DEVICE_VENDOR_XBOX;
break;
case 0x1002:
case 0x1022:
vendor = GST_D3D11_DEVICE_VENDOR_AMD;
break;
case 0x8086:
vendor = GST_D3D11_DEVICE_VENDOR_INTEL;
break;
case 0x10de:
vendor = GST_D3D11_DEVICE_VENDOR_NVIDIA;
break;
case 0x4d4f4351:
vendor = GST_D3D11_DEVICE_VENDOR_QUALCOMM;
break;
default:
break;
}
g_free (desc);
return ret;
return vendor;
}
static gchar *

View file

@ -27,6 +27,16 @@
G_BEGIN_DECLS
typedef enum
{
GST_D3D11_DEVICE_VENDOR_UNKNOWN = 0,
GST_D3D11_DEVICE_VENDOR_AMD,
GST_D3D11_DEVICE_VENDOR_INTEL,
GST_D3D11_DEVICE_VENDOR_NVIDIA,
GST_D3D11_DEVICE_VENDOR_QUALCOMM,
GST_D3D11_DEVICE_VENDOR_XBOX,
} GstD3D11DeviceVendor;
gboolean gst_d3d11_handle_set_context (GstElement * element,
GstContext * context,
gint adapter,
@ -42,7 +52,7 @@ gboolean gst_d3d11_ensure_element_data (GstElement * element,
gboolean gst_d3d11_is_windows_8_or_greater (void);
gboolean gst_d3d11_is_xbox_device (GstD3D11Device * device);
GstD3D11DeviceVendor gst_d3d11_get_device_vendor (GstD3D11Device * device);
gboolean _gst_d3d11_result (HRESULT hr,
GstD3D11Device * device,

View file

@ -668,7 +668,8 @@ gst_d3d11_window_prepare (GstD3D11Window * window, guint display_width,
/* FIXME: need to verify video processor on Xbox
* https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1312
*/
if (!gst_d3d11_is_xbox_device (window->device)) {
if (gst_d3d11_get_device_vendor (window->device) !=
GST_D3D11_DEVICE_VENDOR_XBOX) {
window->processor =
gst_d3d11_video_processor_new (window->device,
GST_VIDEO_INFO_WIDTH (&window->info),