mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +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;
|
||||
ID3D11DeviceContext *device_context;
|
||||
|
||||
ID3D11VideoDevice *video_device;
|
||||
ID3D11VideoContext *video_context;
|
||||
|
||||
IDXGIFactory1 *factory;
|
||||
GstD3D11Format format_table[GST_D3D11_N_FORMATS];
|
||||
|
||||
GRecMutex extern_lock;
|
||||
GMutex resource_lock;
|
||||
|
||||
#if HAVE_D3D11SDKLAYERS_H
|
||||
ID3D11Debug *d3d11_debug;
|
||||
|
@ -409,6 +413,7 @@ gst_d3d11_device_init (GstD3D11Device * self)
|
|||
priv->adapter = DEFAULT_ADAPTER;
|
||||
|
||||
g_rec_mutex_init (&priv->extern_lock);
|
||||
g_mutex_init (&priv->resource_lock);
|
||||
|
||||
self->priv = priv;
|
||||
}
|
||||
|
@ -894,6 +899,16 @@ gst_d3d11_device_dispose (GObject * object)
|
|||
|
||||
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) {
|
||||
ID3D11Device_Release (priv->device);
|
||||
priv->device = NULL;
|
||||
|
@ -952,6 +967,7 @@ gst_d3d11_device_finalize (GObject * object)
|
|||
GST_LOG_OBJECT (self, "finalize");
|
||||
|
||||
g_rec_mutex_clear (&priv->extern_lock);
|
||||
g_mutex_clear (&priv->resource_lock);
|
||||
g_free (priv->description);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
|
@ -1046,6 +1062,72 @@ gst_d3d11_device_get_dxgi_factory_handle (GstD3D11Device * device)
|
|||
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:
|
||||
* @device: a #GstD3D11Device
|
||||
|
|
|
@ -71,6 +71,12 @@ ID3D11DeviceContext * gst_d3d11_device_get_device_context_handle (GstD3D11Device
|
|||
GST_D3D11_API
|
||||
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
|
||||
void gst_d3d11_device_lock (GstD3D11Device * device);
|
||||
|
||||
|
|
|
@ -150,43 +150,31 @@ gst_d3d11_decoder_constructed (GObject * object)
|
|||
{
|
||||
GstD3D11Decoder *self = GST_D3D11_DECODER (object);
|
||||
GstD3D11DecoderPrivate *priv = self->priv;
|
||||
HRESULT hr;
|
||||
ID3D11Device *device_handle;
|
||||
ID3D11DeviceContext *device_context_handle;
|
||||
ID3D11VideoDevice *video_device;
|
||||
ID3D11VideoContext *video_context;
|
||||
|
||||
if (!priv->device) {
|
||||
GST_ERROR_OBJECT (self, "No D3D11Device available");
|
||||
return;
|
||||
}
|
||||
|
||||
device_handle = gst_d3d11_device_get_device_handle (priv->device);
|
||||
device_context_handle =
|
||||
gst_d3d11_device_get_device_context_handle (priv->device);
|
||||
|
||||
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;
|
||||
|
||||
video_device = gst_d3d11_device_get_video_device_handle (priv->device);
|
||||
if (!video_device) {
|
||||
GST_ERROR_OBJECT (self, "ID3D11VideoDevice is not available");
|
||||
return;
|
||||
}
|
||||
|
||||
hr = device_context_handle->
|
||||
QueryInterface (IID_PPV_ARGS (&priv->video_context));
|
||||
if (!gst_d3d11_result (hr, priv->device) || !priv->video_context) {
|
||||
GST_WARNING_OBJECT (self, "Cannot create VideoContext Object: 0x%x",
|
||||
(guint) hr);
|
||||
priv->video_context = NULL;
|
||||
|
||||
goto fail;
|
||||
video_context = gst_d3d11_device_get_video_context_handle (priv->device);
|
||||
if (!video_context) {
|
||||
GST_ERROR_OBJECT (self, "ID3D11VideoContext is not available");
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
priv->video_device = video_device;
|
||||
video_device->AddRef ();
|
||||
|
||||
fail:
|
||||
GST_D3D11_CLEAR_COM (priv->video_device);
|
||||
GST_D3D11_CLEAR_COM (priv->video_context);
|
||||
priv->video_context = video_context;
|
||||
video_context->AddRef ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -603,27 +603,26 @@ gst_d3d11_deinterlace_set_context (GstElement * element, GstContext * context)
|
|||
static gboolean
|
||||
gst_d3d11_deinterlace_open (GstD3D11Deinterlace * self)
|
||||
{
|
||||
HRESULT hr;
|
||||
ID3D11Device *device_handle;
|
||||
ID3D11DeviceContext *context_handle;
|
||||
/* *INDENT-OFF* */
|
||||
ComPtr<ID3D11VideoDevice> video_device;
|
||||
ComPtr<ID3D11VideoContext> video_context;
|
||||
/* *INDENT-ON* */
|
||||
ID3D11VideoDevice *video_device;
|
||||
ID3D11VideoContext *video_context;
|
||||
|
||||
device_handle = gst_d3d11_device_get_device_handle (self->device);
|
||||
context_handle = gst_d3d11_device_get_device_context_handle (self->device);
|
||||
|
||||
hr = device_handle->QueryInterface (IID_PPV_ARGS (&video_device));
|
||||
if (!gst_d3d11_result (hr, self->device))
|
||||
video_device = gst_d3d11_device_get_video_device_handle (self->device);
|
||||
if (!video_device) {
|
||||
GST_ERROR_OBJECT (self, "ID3D11VideoDevice is not availale");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hr = context_handle->QueryInterface (IID_PPV_ARGS (&video_context));
|
||||
if (!gst_d3d11_result (hr, self->device))
|
||||
video_context = gst_d3d11_device_get_video_context_handle (self->device);
|
||||
if (!video_context) {
|
||||
GST_ERROR_OBJECT (self, "ID3D11VideoContext is not available");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
self->video_device = video_device.Detach ();
|
||||
self->video_context = video_context.Detach ();
|
||||
self->video_device = video_device;
|
||||
video_device->AddRef ();
|
||||
|
||||
self->video_context = video_context;
|
||||
video_context->AddRef ();
|
||||
|
||||
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)
|
||||
{
|
||||
GstD3D11VideoProcessor *self;
|
||||
ID3D11Device *device_handle;
|
||||
ID3D11DeviceContext *context_handle;
|
||||
ID3D11VideoDevice *video_device;
|
||||
ID3D11VideoContext *video_context;
|
||||
HRESULT hr;
|
||||
D3D11_VIDEO_PROCESSOR_CONTENT_DESC desc;
|
||||
|
||||
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);
|
||||
context_handle = gst_d3d11_device_get_device_context_handle (device);
|
||||
video_context = gst_d3d11_device_get_video_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->device = (GstD3D11Device *) gst_object_ref (device);
|
||||
|
||||
hr = device_handle->QueryInterface (IID_PPV_ARGS (&self->video_device));
|
||||
if (!gst_d3d11_result (hr, device))
|
||||
goto fail;
|
||||
self->video_device = video_device;
|
||||
video_device->AddRef ();
|
||||
|
||||
hr = context_handle->QueryInterface (IID_PPV_ARGS (&self->video_context));
|
||||
if (!gst_d3d11_result (hr, device))
|
||||
goto fail;
|
||||
self->video_context = video_context;
|
||||
video_context->AddRef ();
|
||||
|
||||
/* FIXME: Add support intelace */
|
||||
desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;
|
||||
|
|
Loading…
Reference in a new issue