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; GUID decoder_profile;
/* For device specific workaround */ /* For device specific workaround */
gboolean is_xbox_device; gboolean can_direct_rendering;
/* for internal shader */ /* for internal shader */
GstD3D11ColorConverter *converter; GstD3D11ColorConverter *converter;
@ -636,6 +636,7 @@ gst_d3d11_decoder_open (GstD3D11Decoder * decoder, GstD3D11Codec codec,
gint i; gint i;
guint aligned_width, aligned_height; guint aligned_width, aligned_height;
guint alignment; guint alignment;
GstD3D11DeviceVendor vendor;
g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE); g_return_val_if_fail (GST_IS_D3D11_DECODER (decoder), FALSE);
g_return_val_if_fail (codec > GST_D3D11_CODEC_NONE, 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); 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 /* NOTE: other dxva implementations (ffmpeg and vlc) do this
* and they say the required alignment were mentioned by dxva spec. * 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) { switch (codec) {
case GST_D3D11_CODEC_H265: case GST_D3D11_CODEC_H265:
/* See directx_va_Setup() impl. in vlc */ /* See directx_va_Setup() impl. in vlc */
if (!priv->is_xbox_device) if (vendor != GST_D3D11_DEVICE_VENDOR_XBOX)
alignment = 128; alignment = 128;
else else
alignment = 16; alignment = 16;
@ -1605,10 +1621,7 @@ gst_d3d11_decoder_supports_direct_rendering (GstD3D11Decoder * decoder)
priv = decoder->priv; priv = decoder->priv;
/* FIXME: Need to figure out Xbox device's behavior return priv->can_direct_rendering;
* https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1312
*/
return !priv->is_xbox_device;
} }
/* Keep sync with chromium and keep in sorted order. /* 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; return ret;
} }
gboolean GstD3D11DeviceVendor
gst_d3d11_is_xbox_device (GstD3D11Device * device) gst_d3d11_get_device_vendor (GstD3D11Device * device)
{ {
guint device_id = 0; guint device_id = 0;
guint vendor_id = 0; guint vendor_id = 0;
gchar *desc = NULL; 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_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
g_object_get (device, "device-id", &device_id, "vendor-id", &vendor_id, g_object_get (device, "device-id", &device_id, "vendor-id", &vendor_id,
"description", &desc, NULL); "description", &desc, NULL);
if (device_id == 0 && vendor_id == 0 && desc && g_strrstr (desc, "SraKmd")) switch (vendor_id) {
ret = TRUE; 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); g_free (desc);
return ret; return vendor;
} }
static gchar * static gchar *

View file

@ -27,6 +27,16 @@
G_BEGIN_DECLS 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, gboolean gst_d3d11_handle_set_context (GstElement * element,
GstContext * context, GstContext * context,
gint adapter, 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_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, gboolean _gst_d3d11_result (HRESULT hr,
GstD3D11Device * device, 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 /* FIXME: need to verify video processor on Xbox
* https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1312 * 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 = window->processor =
gst_d3d11_video_processor_new (window->device, gst_d3d11_video_processor_new (window->device,
GST_VIDEO_INFO_WIDTH (&window->info), GST_VIDEO_INFO_WIDTH (&window->info),