d3d11: d3d11decoder: Use DXGI adapter LUID

... instead of index of DXGI adapter.

The order of IDXGIAdapter1 enumerated via IDXGIFactory1::EnumAdapters1
can be varying even there's no rebooting in case that GPU preference order
is updated by user (for example, it can be done by using NVIDIA Control Panel
in case of multi-GPU laptop system) and eGPU is another possible case.

So, for an element which requires fixed target GPU requirement,
index based device enumeration is unreliable.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1098>
This commit is contained in:
Seungha Yang 2021-10-08 22:37:20 +09:00
parent 98b82ef286
commit 5707e487cf
8 changed files with 71 additions and 97 deletions

View file

@ -501,8 +501,8 @@ gst_d3d11_av1_dec_set_context (GstElement * element, GstContext * context)
GstD3D11AV1DecClass *klass = GST_D3D11_AV1_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
gst_d3d11_handle_set_context (element, context, cdata->adapter,
&inner->device);
gst_d3d11_handle_set_context_for_adapter_luid (element,
context, cdata->adapter_luid, &inner->device);
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
@ -515,18 +515,9 @@ gst_d3d11_av1_dec_open (GstVideoDecoder * decoder)
GstD3D11AV1DecClass *klass = GST_D3D11_AV1_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
if (!gst_d3d11_ensure_element_data (GST_ELEMENT_CAST (self), cdata->adapter,
&inner->device)) {
GST_ERROR_OBJECT (self, "Cannot create d3d11device");
return FALSE;
}
inner->d3d11_decoder = gst_d3d11_decoder_new (inner->device,
GST_DXVA_CODEC_AV1);
if (!inner->d3d11_decoder) {
GST_ERROR_OBJECT (self, "Cannot create d3d11 decoder");
gst_clear_object (&inner->device);
if (!gst_d3d11_decoder_proxy_open (decoder,
cdata, &inner->device, &inner->d3d11_decoder)) {
GST_ERROR_OBJECT (self, "Failed to open decoder");
return FALSE;
}

View file

@ -2090,7 +2090,7 @@ gst_d3d11_decoder_supports_resolution (GstD3D11Device * device,
enum
{
PROP_DECODER_ADAPTER = 1,
PROP_DECODER_ADAPTER_LUID = 1,
PROP_DECODER_DEVICE_ID,
PROP_DECODER_VENDOR_ID,
};
@ -2101,7 +2101,6 @@ struct _GstD3D11DecoderClassData
GstCaps *sink_caps;
GstCaps *src_caps;
gchar *description;
GstDXVACodec codec;
};
/**
@ -2126,13 +2125,12 @@ gst_d3d11_decoder_class_data_new (GstD3D11Device * device, GstDXVACodec codec,
ret = g_new0 (GstD3D11DecoderClassData, 1);
ret->codec = codec;
/* class data will be leaked if the element never gets instantiated */
GST_MINI_OBJECT_FLAG_SET (sink_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
GST_MINI_OBJECT_FLAG_SET (src_caps, GST_MINI_OBJECT_FLAG_MAY_BE_LEAKED);
g_object_get (device, "adapter", &ret->subclass_data.adapter,
ret->subclass_data.codec = codec;
g_object_get (device, "adapter-luid", &ret->subclass_data.adapter_luid,
"device-id", &ret->subclass_data.device_id,
"vendor-id", &ret->subclass_data.vendor_id,
"description", &ret->description, nullptr);
@ -2174,10 +2172,10 @@ gst_d3d11_decoder_proxy_class_init (GstElementClass * klass,
std::string description;
const gchar *codec_name;
g_object_class_install_property (gobject_class, PROP_DECODER_ADAPTER,
g_param_spec_uint ("adapter", "Adapter",
"DXGI Adapter index for creating device",
0, G_MAXUINT32, cdata->adapter,
g_object_class_install_property (gobject_class, PROP_DECODER_ADAPTER_LUID,
g_param_spec_int64 ("adapter-luid", "Adapter LUID",
"DXGI Adapter LUID (Locally Unique Identifier) of created device",
G_MININT64, G_MAXINT64, cdata->adapter_luid,
(GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_DECODER_DEVICE_ID,
@ -2190,7 +2188,7 @@ gst_d3d11_decoder_proxy_class_init (GstElementClass * klass,
"DXGI Vendor ID", 0, G_MAXUINT32, 0,
(GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));
codec_name = gst_dxva_codec_to_string (data->codec);
codec_name = gst_dxva_codec_to_string (cdata->codec);
long_name = "Direct3D11/DXVA " + std::string (codec_name) + " " +
std::string (data->description) + " Decoder";
description = "Direct3D11/DXVA based " + std::string (codec_name) +
@ -2215,8 +2213,8 @@ gst_d3d11_decoder_proxy_get_property (GObject * object, guint prop_id,
GstD3D11DecoderSubClassData * subclass_data)
{
switch (prop_id) {
case PROP_DECODER_ADAPTER:
g_value_set_uint (value, subclass_data->adapter);
case PROP_DECODER_ADAPTER_LUID:
g_value_set_int64 (value, subclass_data->adapter_luid);
break;
case PROP_DECODER_DEVICE_ID:
g_value_set_uint (value, subclass_data->device_id);
@ -2229,3 +2227,27 @@ gst_d3d11_decoder_proxy_get_property (GObject * object, guint prop_id,
break;
}
}
gboolean
gst_d3d11_decoder_proxy_open (GstVideoDecoder * videodec,
GstD3D11DecoderSubClassData * subclass_data, GstD3D11Device ** device,
GstD3D11Decoder ** decoder)
{
GstElement *elem = GST_ELEMENT (videodec);
if (!gst_d3d11_ensure_element_data_for_adapter_luid (elem,
subclass_data->adapter_luid, device)) {
GST_ERROR_OBJECT (elem, "Cannot create d3d11device");
return FALSE;
}
*decoder = gst_d3d11_decoder_new (*device, subclass_data->codec);
if (*decoder == nullptr) {
GST_ERROR_OBJECT (elem, "Cannot create d3d11 decoder");
gst_clear_object (device);
return FALSE;
}
return TRUE;
}

View file

@ -48,7 +48,8 @@ typedef enum
typedef struct
{
guint adapter;
GstDXVACodec codec;
gint64 adapter_luid;
guint device_id;
guint vendor_id;
} GstD3D11DecoderSubClassData;
@ -157,6 +158,11 @@ void gst_d3d11_decoder_proxy_get_property (GObject * object,
GParamSpec * pspec,
GstD3D11DecoderSubClassData * subclass_data);
gboolean gst_d3d11_decoder_proxy_open (GstVideoDecoder * videodec,
GstD3D11DecoderSubClassData * subclass_data,
GstD3D11Device ** device,
GstD3D11Decoder ** decoder);
G_END_DECLS
#endif /* __GST_D3D11_DECODER_H__ */

View file

@ -236,8 +236,8 @@ gst_d3d11_h264_dec_set_context (GstElement * element, GstContext * context)
GstD3D11H264DecClass *klass = GST_D3D11_H264_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
gst_d3d11_handle_set_context (element, context, cdata->adapter,
&inner->device);
gst_d3d11_handle_set_context_for_adapter_luid (element,
context, cdata->adapter_luid, &inner->device);
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
@ -267,18 +267,9 @@ gst_d3d11_h264_dec_open (GstVideoDecoder * decoder)
GstD3D11H264DecClass *klass = GST_D3D11_H264_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
if (!gst_d3d11_ensure_element_data (GST_ELEMENT_CAST (self), cdata->adapter,
&inner->device)) {
GST_ERROR_OBJECT (self, "Cannot create d3d11device");
return FALSE;
}
inner->d3d11_decoder = gst_d3d11_decoder_new (inner->device,
GST_DXVA_CODEC_H264);
if (!inner->d3d11_decoder) {
GST_ERROR_OBJECT (self, "Cannot create d3d11 decoder");
gst_clear_object (&inner->device);
if (!gst_d3d11_decoder_proxy_open (decoder,
cdata, &inner->device, &inner->d3d11_decoder)) {
GST_ERROR_OBJECT (self, "Failed to open decoder");
return FALSE;
}

View file

@ -203,8 +203,8 @@ gst_d3d11_h265_dec_set_context (GstElement * element, GstContext * context)
GstD3D11H265DecClass *klass = GST_D3D11_H265_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
gst_d3d11_handle_set_context (element, context, cdata->adapter,
&inner->device);
gst_d3d11_handle_set_context_for_adapter_luid (element,
context, cdata->adapter_luid, &inner->device);
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
@ -217,18 +217,9 @@ gst_d3d11_h265_dec_open (GstVideoDecoder * decoder)
GstD3D11H265DecClass *klass = GST_D3D11_H265_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
if (!gst_d3d11_ensure_element_data (GST_ELEMENT_CAST (self), cdata->adapter,
&inner->device)) {
GST_ERROR_OBJECT (self, "Cannot create d3d11device");
return FALSE;
}
inner->d3d11_decoder = gst_d3d11_decoder_new (inner->device,
GST_DXVA_CODEC_H265);
if (!inner->d3d11_decoder) {
GST_ERROR_OBJECT (self, "Cannot create d3d11 decoder");
gst_clear_object (&inner->device);
if (!gst_d3d11_decoder_proxy_open (decoder,
cdata, &inner->device, &inner->d3d11_decoder)) {
GST_ERROR_OBJECT (self, "Failed to open decoder");
return FALSE;
}

View file

@ -215,8 +215,8 @@ gst_d3d11_mpeg2_dec_set_context (GstElement * element, GstContext * context)
GstD3D11Mpeg2DecClass *klass = GST_D3D11_MPEG2_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
gst_d3d11_handle_set_context (element, context, cdata->adapter,
&inner->device);
gst_d3d11_handle_set_context_for_adapter_luid (element,
context, cdata->adapter_luid, &inner->device);
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
@ -229,18 +229,9 @@ gst_d3d11_mpeg2_dec_open (GstVideoDecoder * decoder)
GstD3D11Mpeg2DecClass *klass = GST_D3D11_MPEG2_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
if (!gst_d3d11_ensure_element_data (GST_ELEMENT_CAST (self), cdata->adapter,
&inner->device)) {
GST_ERROR_OBJECT (self, "Cannot create d3d11device");
return FALSE;
}
inner->d3d11_decoder = gst_d3d11_decoder_new (inner->device,
GST_DXVA_CODEC_MPEG2);
if (!inner->d3d11_decoder) {
GST_ERROR_OBJECT (self, "Cannot create d3d11 decoder");
gst_clear_object (&inner->device);
if (!gst_d3d11_decoder_proxy_open (decoder,
cdata, &inner->device, &inner->d3d11_decoder)) {
GST_ERROR_OBJECT (self, "Failed to open decoder");
return FALSE;
}

View file

@ -199,8 +199,8 @@ gst_d3d11_vp8_dec_set_context (GstElement * element, GstContext * context)
GstD3D11Vp8DecClass *klass = GST_D3D11_VP8_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
gst_d3d11_handle_set_context (element, context, cdata->adapter,
&inner->device);
gst_d3d11_handle_set_context_for_adapter_luid (element,
context, cdata->adapter_luid, &inner->device);
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
@ -213,18 +213,9 @@ gst_d3d11_vp8_dec_open (GstVideoDecoder * decoder)
GstD3D11Vp8DecClass *klass = GST_D3D11_VP8_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
if (!gst_d3d11_ensure_element_data (GST_ELEMENT_CAST (self), cdata->adapter,
&inner->device)) {
GST_ERROR_OBJECT (self, "Cannot create d3d11device");
return FALSE;
}
inner->d3d11_decoder = gst_d3d11_decoder_new (inner->device,
GST_DXVA_CODEC_VP8);
if (!inner->d3d11_decoder) {
GST_ERROR_OBJECT (self, "Cannot create d3d11 decoder");
gst_clear_object (&inner->device);
if (!gst_d3d11_decoder_proxy_open (decoder,
cdata, &inner->device, &inner->d3d11_decoder)) {
GST_ERROR_OBJECT (self, "Failed to open decoder");
return FALSE;
}

View file

@ -234,8 +234,8 @@ gst_d3d11_vp9_dec_set_context (GstElement * element, GstContext * context)
GstD3D11Vp9DecClass *klass = GST_D3D11_VP9_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
gst_d3d11_handle_set_context (element, context, cdata->adapter,
&inner->device);
gst_d3d11_handle_set_context_for_adapter_luid (element,
context, cdata->adapter_luid, &inner->device);
GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
}
@ -248,18 +248,9 @@ gst_d3d11_vp9_dec_open (GstVideoDecoder * decoder)
GstD3D11Vp9DecClass *klass = GST_D3D11_VP9_DEC_GET_CLASS (self);
GstD3D11DecoderSubClassData *cdata = &klass->class_data;
if (!gst_d3d11_ensure_element_data (GST_ELEMENT_CAST (self), cdata->adapter,
&inner->device)) {
GST_ERROR_OBJECT (self, "Cannot create d3d11device");
return FALSE;
}
inner->d3d11_decoder = gst_d3d11_decoder_new (inner->device,
GST_DXVA_CODEC_VP9);
if (!inner->d3d11_decoder) {
GST_ERROR_OBJECT (self, "Cannot create d3d11 decoder");
gst_clear_object (&inner->device);
if (!gst_d3d11_decoder_proxy_open (decoder,
cdata, &inner->device, &inner->d3d11_decoder)) {
GST_ERROR_OBJECT (self, "Failed to open decoder");
return FALSE;
}