mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
d3d11device: Hold ID3D11VideoDevice and ID3D11VideoContext object
... instead of QueryInterface-ing per elements. Note that ID3D11VideoDevice and ID3D11VideoContext objects might not be available if device doesn't support video interface. So GstD3D11Device object will create those objects only when requested. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2079>
This commit is contained in:
parent
b08310f748
commit
615f52f2f7
5 changed files with 134 additions and 52 deletions
|
@ -103,10 +103,14 @@ struct _GstD3D11DevicePrivate
|
||||||
ID3D11Device *device;
|
ID3D11Device *device;
|
||||||
ID3D11DeviceContext *device_context;
|
ID3D11DeviceContext *device_context;
|
||||||
|
|
||||||
|
ID3D11VideoDevice *video_device;
|
||||||
|
ID3D11VideoContext *video_context;
|
||||||
|
|
||||||
IDXGIFactory1 *factory;
|
IDXGIFactory1 *factory;
|
||||||
GstD3D11Format format_table[GST_D3D11_N_FORMATS];
|
GstD3D11Format format_table[GST_D3D11_N_FORMATS];
|
||||||
|
|
||||||
GRecMutex extern_lock;
|
GRecMutex extern_lock;
|
||||||
|
GMutex resource_lock;
|
||||||
|
|
||||||
#if HAVE_D3D11SDKLAYERS_H
|
#if HAVE_D3D11SDKLAYERS_H
|
||||||
ID3D11Debug *d3d11_debug;
|
ID3D11Debug *d3d11_debug;
|
||||||
|
@ -409,6 +413,7 @@ gst_d3d11_device_init (GstD3D11Device * self)
|
||||||
priv->adapter = DEFAULT_ADAPTER;
|
priv->adapter = DEFAULT_ADAPTER;
|
||||||
|
|
||||||
g_rec_mutex_init (&priv->extern_lock);
|
g_rec_mutex_init (&priv->extern_lock);
|
||||||
|
g_mutex_init (&priv->resource_lock);
|
||||||
|
|
||||||
self->priv = priv;
|
self->priv = priv;
|
||||||
}
|
}
|
||||||
|
@ -894,6 +899,16 @@ gst_d3d11_device_dispose (GObject * object)
|
||||||
|
|
||||||
GST_LOG_OBJECT (self, "dispose");
|
GST_LOG_OBJECT (self, "dispose");
|
||||||
|
|
||||||
|
if (priv->video_device) {
|
||||||
|
ID3D11VideoDevice_Release (priv->video_device);
|
||||||
|
priv->video_device = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->video_context) {
|
||||||
|
ID3D11VideoContext_Release (priv->video_context);
|
||||||
|
priv->video_context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->device) {
|
if (priv->device) {
|
||||||
ID3D11Device_Release (priv->device);
|
ID3D11Device_Release (priv->device);
|
||||||
priv->device = NULL;
|
priv->device = NULL;
|
||||||
|
@ -952,6 +967,7 @@ gst_d3d11_device_finalize (GObject * object)
|
||||||
GST_LOG_OBJECT (self, "finalize");
|
GST_LOG_OBJECT (self, "finalize");
|
||||||
|
|
||||||
g_rec_mutex_clear (&priv->extern_lock);
|
g_rec_mutex_clear (&priv->extern_lock);
|
||||||
|
g_mutex_clear (&priv->resource_lock);
|
||||||
g_free (priv->description);
|
g_free (priv->description);
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||||
|
@ -1046,6 +1062,72 @@ gst_d3d11_device_get_dxgi_factory_handle (GstD3D11Device * device)
|
||||||
return device->priv->factory;
|
return device->priv->factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_d3d11_device_get_video_device_handle:
|
||||||
|
* @device: a #GstD3D11Device
|
||||||
|
*
|
||||||
|
* Used for various D3D11 APIs directly. Caller must not destroy returned device
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* Returns: (nullable) (transfer none) : the ID3D11VideoDevice handle or %NULL
|
||||||
|
* if ID3D11VideoDevice is unavailable.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
ID3D11VideoDevice *
|
||||||
|
gst_d3d11_device_get_video_device_handle (GstD3D11Device * device)
|
||||||
|
{
|
||||||
|
GstD3D11DevicePrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
|
||||||
|
|
||||||
|
priv = device->priv;
|
||||||
|
g_mutex_lock (&priv->resource_lock);
|
||||||
|
if (!priv->video_device) {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = ID3D11Device_QueryInterface (priv->device, &IID_ID3D11VideoDevice,
|
||||||
|
(void **) &priv->video_device);
|
||||||
|
gst_d3d11_result (hr, device);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (&priv->resource_lock);
|
||||||
|
|
||||||
|
return priv->video_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_d3d11_device_get_video_context_handle:
|
||||||
|
* @device: a #GstD3D11Device
|
||||||
|
*
|
||||||
|
* Used for various D3D11 APIs directly. Caller must not destroy returned device
|
||||||
|
* object.
|
||||||
|
*
|
||||||
|
* Returns: (nullable) (transfer none): the ID3D11VideoContext handle or %NULL
|
||||||
|
* if ID3D11VideoContext is unavailable.
|
||||||
|
*
|
||||||
|
* Since: 1.20
|
||||||
|
*/
|
||||||
|
ID3D11VideoContext *
|
||||||
|
gst_d3d11_device_get_video_context_handle (GstD3D11Device * device)
|
||||||
|
{
|
||||||
|
GstD3D11DevicePrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
|
||||||
|
|
||||||
|
priv = device->priv;
|
||||||
|
g_mutex_lock (&priv->resource_lock);
|
||||||
|
if (!priv->video_context) {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = ID3D11DeviceContext_QueryInterface (priv->device_context,
|
||||||
|
&IID_ID3D11VideoContext, (void **) &priv->video_context);
|
||||||
|
gst_d3d11_result (hr, device);
|
||||||
|
}
|
||||||
|
g_mutex_unlock (&priv->resource_lock);
|
||||||
|
|
||||||
|
return priv->video_context;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_d3d11_device_lock:
|
* gst_d3d11_device_lock:
|
||||||
* @device: a #GstD3D11Device
|
* @device: a #GstD3D11Device
|
||||||
|
|
|
@ -71,6 +71,12 @@ ID3D11DeviceContext * gst_d3d11_device_get_device_context_handle (GstD3D11Device
|
||||||
GST_D3D11_API
|
GST_D3D11_API
|
||||||
IDXGIFactory1 * gst_d3d11_device_get_dxgi_factory_handle (GstD3D11Device * device);
|
IDXGIFactory1 * gst_d3d11_device_get_dxgi_factory_handle (GstD3D11Device * device);
|
||||||
|
|
||||||
|
GST_D3D11_API
|
||||||
|
ID3D11VideoDevice * gst_d3d11_device_get_video_device_handle (GstD3D11Device * device);
|
||||||
|
|
||||||
|
GST_D3D11_API
|
||||||
|
ID3D11VideoContext * gst_d3d11_device_get_video_context_handle (GstD3D11Device * device);
|
||||||
|
|
||||||
GST_D3D11_API
|
GST_D3D11_API
|
||||||
void gst_d3d11_device_lock (GstD3D11Device * device);
|
void gst_d3d11_device_lock (GstD3D11Device * device);
|
||||||
|
|
||||||
|
|
|
@ -150,43 +150,31 @@ gst_d3d11_decoder_constructed (GObject * object)
|
||||||
{
|
{
|
||||||
GstD3D11Decoder *self = GST_D3D11_DECODER (object);
|
GstD3D11Decoder *self = GST_D3D11_DECODER (object);
|
||||||
GstD3D11DecoderPrivate *priv = self->priv;
|
GstD3D11DecoderPrivate *priv = self->priv;
|
||||||
HRESULT hr;
|
ID3D11VideoDevice *video_device;
|
||||||
ID3D11Device *device_handle;
|
ID3D11VideoContext *video_context;
|
||||||
ID3D11DeviceContext *device_context_handle;
|
|
||||||
|
|
||||||
if (!priv->device) {
|
if (!priv->device) {
|
||||||
GST_ERROR_OBJECT (self, "No D3D11Device available");
|
GST_ERROR_OBJECT (self, "No D3D11Device available");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_handle = gst_d3d11_device_get_device_handle (priv->device);
|
video_device = gst_d3d11_device_get_video_device_handle (priv->device);
|
||||||
device_context_handle =
|
if (!video_device) {
|
||||||
gst_d3d11_device_get_device_context_handle (priv->device);
|
GST_ERROR_OBJECT (self, "ID3D11VideoDevice is not available");
|
||||||
|
|
||||||
hr = device_handle->QueryInterface (IID_PPV_ARGS (&priv->video_device));
|
|
||||||
if (!gst_d3d11_result (hr, priv->device) || !priv->video_device) {
|
|
||||||
GST_WARNING_OBJECT (self, "Cannot create VideoDevice Object: 0x%x",
|
|
||||||
(guint) hr);
|
|
||||||
priv->video_device = NULL;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = device_context_handle->
|
video_context = gst_d3d11_device_get_video_context_handle (priv->device);
|
||||||
QueryInterface (IID_PPV_ARGS (&priv->video_context));
|
if (!video_context) {
|
||||||
if (!gst_d3d11_result (hr, priv->device) || !priv->video_context) {
|
GST_ERROR_OBJECT (self, "ID3D11VideoContext is not available");
|
||||||
GST_WARNING_OBJECT (self, "Cannot create VideoContext Object: 0x%x",
|
return;
|
||||||
(guint) hr);
|
|
||||||
priv->video_context = NULL;
|
|
||||||
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
priv->video_device = video_device;
|
||||||
|
video_device->AddRef ();
|
||||||
|
|
||||||
fail:
|
priv->video_context = video_context;
|
||||||
GST_D3D11_CLEAR_COM (priv->video_device);
|
video_context->AddRef ();
|
||||||
GST_D3D11_CLEAR_COM (priv->video_context);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -603,27 +603,26 @@ gst_d3d11_deinterlace_set_context (GstElement * element, GstContext * context)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_d3d11_deinterlace_open (GstD3D11Deinterlace * self)
|
gst_d3d11_deinterlace_open (GstD3D11Deinterlace * self)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
ID3D11VideoDevice *video_device;
|
||||||
ID3D11Device *device_handle;
|
ID3D11VideoContext *video_context;
|
||||||
ID3D11DeviceContext *context_handle;
|
|
||||||
/* *INDENT-OFF* */
|
|
||||||
ComPtr<ID3D11VideoDevice> video_device;
|
|
||||||
ComPtr<ID3D11VideoContext> video_context;
|
|
||||||
/* *INDENT-ON* */
|
|
||||||
|
|
||||||
device_handle = gst_d3d11_device_get_device_handle (self->device);
|
video_device = gst_d3d11_device_get_video_device_handle (self->device);
|
||||||
context_handle = gst_d3d11_device_get_device_context_handle (self->device);
|
if (!video_device) {
|
||||||
|
GST_ERROR_OBJECT (self, "ID3D11VideoDevice is not availale");
|
||||||
hr = device_handle->QueryInterface (IID_PPV_ARGS (&video_device));
|
|
||||||
if (!gst_d3d11_result (hr, self->device))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
hr = context_handle->QueryInterface (IID_PPV_ARGS (&video_context));
|
video_context = gst_d3d11_device_get_video_context_handle (self->device);
|
||||||
if (!gst_d3d11_result (hr, self->device))
|
if (!video_context) {
|
||||||
|
GST_ERROR_OBJECT (self, "ID3D11VideoContext is not available");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
self->video_device = video_device.Detach ();
|
self->video_device = video_device;
|
||||||
self->video_context = video_context.Detach ();
|
video_device->AddRef ();
|
||||||
|
|
||||||
|
self->video_context = video_context;
|
||||||
|
video_context->AddRef ();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,28 +68,35 @@ gst_d3d11_video_processor_new (GstD3D11Device * device, guint in_width,
|
||||||
guint in_height, guint out_width, guint out_height)
|
guint in_height, guint out_width, guint out_height)
|
||||||
{
|
{
|
||||||
GstD3D11VideoProcessor *self;
|
GstD3D11VideoProcessor *self;
|
||||||
ID3D11Device *device_handle;
|
ID3D11VideoDevice *video_device;
|
||||||
ID3D11DeviceContext *context_handle;
|
ID3D11VideoContext *video_context;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc;
|
D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
|
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
|
||||||
|
|
||||||
memset (&desc, 0, sizeof (desc));
|
video_device = gst_d3d11_device_get_video_device_handle (device);
|
||||||
|
if (!video_device) {
|
||||||
|
GST_WARNING_OBJECT (device, "ID3D11VideoDevice is not available");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
device_handle = gst_d3d11_device_get_device_handle (device);
|
video_context = gst_d3d11_device_get_video_context_handle (device);
|
||||||
context_handle = gst_d3d11_device_get_device_context_handle (device);
|
if (!video_context) {
|
||||||
|
GST_WARNING_OBJECT (device, "ID3D11VideoContext is not availale");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&desc, 0, sizeof (desc));
|
||||||
|
|
||||||
self = g_new0 (GstD3D11VideoProcessor, 1);
|
self = g_new0 (GstD3D11VideoProcessor, 1);
|
||||||
self->device = (GstD3D11Device *) gst_object_ref (device);
|
self->device = (GstD3D11Device *) gst_object_ref (device);
|
||||||
|
|
||||||
hr = device_handle->QueryInterface (IID_PPV_ARGS (&self->video_device));
|
self->video_device = video_device;
|
||||||
if (!gst_d3d11_result (hr, device))
|
video_device->AddRef ();
|
||||||
goto fail;
|
|
||||||
|
|
||||||
hr = context_handle->QueryInterface (IID_PPV_ARGS (&self->video_context));
|
self->video_context = video_context;
|
||||||
if (!gst_d3d11_result (hr, device))
|
video_context->AddRef ();
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* FIXME: Add support intelace */
|
/* FIXME: Add support intelace */
|
||||||
desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;
|
desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;
|
||||||
|
|
Loading…
Reference in a new issue