}
static void
-clear_shader_resource (GstD3D11Device * device, GstD3D11ColorConvert * self)
+gst_d3d11_color_convert_clear_shader_resource (GstD3D11ColorConvert * self)
{
gint i;
}
static void
-gst_d3d11_color_convert_clear_shader_resource (GstD3D11ColorConvert * self)
-{
- GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (self);
-
- if (filter->device) {
- gst_d3d11_device_thread_add (filter->device,
- (GstD3D11DeviceThreadFunc) clear_shader_resource, self);
- }
-}
-
-static void
gst_d3d11_color_convert_dispose (GObject * object)
{
GstD3D11ColorConvert *self = GST_D3D11_COLOR_CONVERT (object);
}
}
-typedef struct
-{
- GstD3D11ColorConvert *self;
- GstBuffer *in_buf;
- GstBuffer *out_buf;
-
- gboolean ret;
-} DoConvertData;
-
-static void
-do_convert (GstD3D11Device * device, DoConvertData * data)
+static GstFlowReturn
+gst_d3d11_color_convert_transform (GstBaseTransform * trans,
+ GstBuffer * inbuf, GstBuffer * outbuf)
{
- GstD3D11ColorConvert *self = data->self;
- GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (self);
+ GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
+ GstD3D11ColorConvert *self = GST_D3D11_COLOR_CONVERT (trans);
ID3D11DeviceContext *context_handle;
ID3D11ShaderResourceView *resource_view[GST_VIDEO_MAX_PLANES] = { NULL, };
ID3D11RenderTargetView *render_view[GST_VIDEO_MAX_PLANES] = { NULL, };
gint i, j, view_index;
gboolean copy_input = FALSE;
gboolean copy_output = FALSE;
+ GstD3D11Device *device = filter->device;
context_handle = gst_d3d11_device_get_device_context_handle (device);
view_index = 0;
- for (i = 0; i < gst_buffer_n_memory (data->in_buf); i++) {
- GstMemory *mem = gst_buffer_peek_memory (data->in_buf, i);
+ for (i = 0; i < gst_buffer_n_memory (inbuf); i++) {
+ GstMemory *mem = gst_buffer_peek_memory (inbuf, i);
GstD3D11Memory *d3d11_mem;
GstMapInfo info;
if (!create_shader_input_resource (self, device,
self->in_d3d11_format, &filter->in_info)) {
GST_ERROR_OBJECT (self, "Failed to configure fallback input texture");
- data->ret = FALSE;
- return;
+ return GST_FLOW_ERROR;
}
break;
}
/* if input memory has no resource view,
* copy texture into our fallback texture */
if (copy_input) {
- for (i = 0; i < gst_buffer_n_memory (data->in_buf); i++) {
- GstMemory *mem = gst_buffer_peek_memory (data->in_buf, i);
+ gst_d3d11_device_lock (device);
+ for (i = 0; i < gst_buffer_n_memory (inbuf); i++) {
+ GstMemory *mem = gst_buffer_peek_memory (inbuf, i);
GstD3D11Memory *d3d11_mem;
g_assert (gst_is_d3d11_memory (mem));
(ID3D11Resource *) self->in_texture[i], 0, 0, 0, 0,
(ID3D11Resource *) d3d11_mem->texture, 0, NULL);
}
+ gst_d3d11_device_unlock (device);
}
view_index = 0;
- for (i = 0; i < gst_buffer_n_memory (data->out_buf); i++) {
- GstMemory *mem = gst_buffer_peek_memory (data->out_buf, i);
+ for (i = 0; i < gst_buffer_n_memory (outbuf); i++) {
+ GstMemory *mem = gst_buffer_peek_memory (outbuf, i);
GstD3D11Memory *d3d11_mem;
g_assert (gst_is_d3d11_memory (mem));
if (!create_shader_output_resource (self, device, self->out_d3d11_format,
&filter->out_info)) {
GST_ERROR_OBJECT (self, "Failed to configure fallback output texture");
- data->ret = FALSE;
- return;
+ return GST_FLOW_ERROR;
}
break;
}
}
- data->ret = gst_d3d11_color_converter_convert (self->converter,
- copy_input ? self->shader_resource_view : resource_view,
- copy_output ? self->render_target_view : render_view);
+ if (!gst_d3d11_color_converter_convert (self->converter,
+ copy_input ? self->shader_resource_view : resource_view,
+ copy_output ? self->render_target_view : render_view)) {
+ GST_ERROR_OBJECT (self, "Failed to convert");
+
+ return GST_FLOW_ERROR;
+ }
- if (data->ret && copy_output) {
- for (i = 0; i < gst_buffer_n_memory (data->out_buf); i++) {
- GstMemory *mem = gst_buffer_peek_memory (data->out_buf, i);
+ if (copy_output) {
+ gst_d3d11_device_lock (device);
+ for (i = 0; i < gst_buffer_n_memory (outbuf); i++) {
+ GstMemory *mem = gst_buffer_peek_memory (outbuf, i);
GstD3D11Memory *d3d11_mem;
g_assert (gst_is_d3d11_memory (mem));
(ID3D11Resource *) d3d11_mem->texture, 0, 0, 0, 0,
(ID3D11Resource *) self->out_texture[i], 0, NULL);
}
+ gst_d3d11_device_unlock (device);
}
-}
-
-static GstFlowReturn
-gst_d3d11_color_convert_transform (GstBaseTransform * trans,
- GstBuffer * inbuf, GstBuffer * outbuf)
-{
- GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
- GstD3D11ColorConvert *self = GST_D3D11_COLOR_CONVERT (trans);
- DoConvertData data;
-
- data.self = self;
- data.in_buf = inbuf;
- data.out_buf = outbuf;
- data.ret = TRUE;
-
- gst_d3d11_device_thread_add (filter->device,
- (GstD3D11DeviceThreadFunc) do_convert, &data);
-
- if (!data.ret)
- return GST_FLOW_ERROR;
return GST_FLOW_OK;
}
goto clear;
}
+ gst_d3d11_device_lock (device);
hr = ID3D11DeviceContext_Map (context_handle,
(ID3D11Resource *) const_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
if (!gst_d3d11_result (hr)) {
GST_ERROR ("Couldn't map constant buffer, hr: 0x%x", (guint) hr);
data->ret = FALSE;
+ gst_d3d11_device_unlock (device);
goto clear;
}
ID3D11DeviceContext_Unmap (context_handle,
(ID3D11Resource *) const_buffer, 0);
+ gst_d3d11_device_unlock (device);
}
input_desc[0].SemanticName = "POSITION";
goto clear;
}
+ gst_d3d11_device_lock (device);
hr = ID3D11DeviceContext_Map (context_handle,
(ID3D11Resource *) vertex_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
if (!gst_d3d11_result (hr)) {
GST_ERROR ("Couldn't map vertex buffer, hr: 0x%x", (guint) hr);
data->ret = FALSE;
+ gst_d3d11_device_unlock (device);
goto clear;
}
GST_ERROR ("Couldn't map index buffer, hr: 0x%x", (guint) hr);
ID3D11DeviceContext_Unmap (context_handle,
(ID3D11Resource *) vertex_buffer, 0);
+ gst_d3d11_device_unlock (device);
data->ret = FALSE;
goto clear;
}
(ID3D11Resource *) vertex_buffer, 0);
ID3D11DeviceContext_Unmap (context_handle,
(ID3D11Resource *) index_buffer, 0);
+ gst_d3d11_device_unlock (device);
self->quad = gst_d3d11_quad_new (device,
ps, vs, layout, sampler, const_buffer, vertex_buffer, sizeof (VertexData),
data.self = converter;
data.in_info = in_info;
data.out_info = out_info;
- gst_d3d11_device_thread_add (device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_color_convert_setup_shader, &data);
+ gst_d3d11_color_convert_setup_shader (device, &data);
if (!data.ret || !converter->quad) {
GST_ERROR ("Couldn't setup shader");
g_free (converter);
}
-typedef struct
-{
- GstD3D11ColorConverter *self;
- ID3D11ShaderResourceView *srv[GST_VIDEO_MAX_PLANES];
- ID3D11RenderTargetView *rtv[GST_VIDEO_MAX_PLANES];
-
- gboolean ret;
-} DoConvertData;
-
-static void
-do_convert (GstD3D11Device * device, DoConvertData * data)
-{
- GstD3D11ColorConverter *self = data->self;
-
- data->ret =
- gst_d3d11_draw_quad (self->quad, &self->viewport, 1,
- data->srv, self->num_input_view, data->rtv, self->num_output_view);
-}
-
gboolean
gst_d3d11_color_converter_convert (GstD3D11ColorConverter * converter,
ID3D11ShaderResourceView * srv[GST_VIDEO_MAX_PLANES],
ID3D11RenderTargetView * rtv[GST_VIDEO_MAX_PLANES])
{
- DoConvertData data = { 0, };
- gint i;
-
g_return_val_if_fail (converter != NULL, FALSE);
g_return_val_if_fail (srv != NULL, FALSE);
g_return_val_if_fail (rtv != NULL, FALSE);
- data.self = converter;
-
- for (i = 0; i < converter->num_input_view; i++)
- data.srv[i] = srv[i];
-
- for (i = 0; i < converter->num_output_view; i++)
- data.rtv[i] = rtv[i];
-
- data.ret = TRUE;
-
- gst_d3d11_device_thread_add (converter->device,
- (GstD3D11DeviceThreadFunc) do_convert, &data);
-
- return data.ret;
+ return gst_d3d11_draw_quad (converter->quad, &converter->viewport, 1,
+ srv, converter->num_input_view, rtv, converter->num_output_view);
}
gboolean
GstD3D11DXGIFactoryVersion factory_ver;
D3D_FEATURE_LEVEL feature_level;
- ID3D11VideoDevice *video_device;
- ID3D11VideoContext *video_context;
-
- GMutex lock;
- GCond cond;
- GThread *thread;
- GThread *active_thread;
- GMainLoop *loop;
- GMainContext *main_context;
+ GRecMutex extern_lock;
#ifdef HAVE_D3D11SDKLAYER_H
ID3D11Debug *debug;
static void gst_d3d11_device_dispose (GObject * object);
static void gst_d3d11_device_finalize (GObject * object);
-static gpointer gst_d3d11_device_thread_func (gpointer data);
-
#ifdef HAVE_D3D11SDKLAYER_H
static gboolean
gst_d3d11_device_enable_debug_layer (void)
priv = gst_d3d11_device_get_instance_private (self);
priv->adapter = DEFAULT_ADAPTER;
- g_mutex_init (&priv->lock);
- g_cond_init (&priv->cond);
-
- priv->main_context = g_main_context_new ();
- priv->loop = g_main_loop_new (priv->main_context, FALSE);
+ g_rec_mutex_init (&priv->extern_lock);
self->priv = priv;
}
priv->factory = factory;
-
#ifdef HAVE_D3D11SDKLAYER_H
if ((d3d11_flags & D3D11_CREATE_DEVICE_DEBUG) == D3D11_CREATE_DEVICE_DEBUG) {
ID3D11Debug *debug;
hr = ID3D11Device_QueryInterface (priv->device,
&IID_ID3D11InfoQueue, (void **) &info_queue);
if (SUCCEEDED (hr)) {
- GSource *source;
-
GST_DEBUG_OBJECT (self, "D3D11InfoQueue interface available");
priv->info_queue = info_queue;
-
- source = g_idle_source_new ();
- g_source_set_callback (source, (GSourceFunc) gst_d3d11_device_get_message,
- self, NULL);
-
- g_source_attach (source, priv->main_context);
- g_source_unref (source);
}
}
#endif
IDXGIAdapter1_Release (adapter);
- g_mutex_lock (&priv->lock);
- priv->thread = g_thread_new ("GstD3D11Device",
- (GThreadFunc) gst_d3d11_device_thread_func, self);
- while (!g_main_loop_is_running (priv->loop))
- g_cond_wait (&priv->cond, &priv->lock);
- g_mutex_unlock (&priv->lock);
-
G_OBJECT_CLASS (parent_class)->constructed (object);
return;
priv->device_context = NULL;
}
- 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->factory) {
IDXGIFactory1_Release (priv->factory);
priv->factory = NULL;
}
-
- if (priv->loop) {
- g_main_loop_quit (priv->loop);
- }
-
- if (priv->thread) {
- g_thread_join (priv->thread);
- priv->thread = NULL;
- }
-
- if (priv->loop) {
- g_main_loop_unref (priv->loop);
- priv->loop = NULL;
- }
-
- if (priv->main_context) {
- g_main_context_unref (priv->main_context);
- priv->main_context = NULL;
- }
#ifdef HAVE_D3D11SDKLAYER_H
if (priv->debug) {
ID3D11Debug_ReportLiveDeviceObjects (priv->debug,
GST_LOG_OBJECT (self, "finalize");
- g_mutex_clear (&priv->lock);
- g_cond_clear (&priv->cond);
+ g_rec_mutex_clear (&priv->extern_lock);
g_free (priv->description);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-static gboolean
-running_cb (gpointer user_data)
-{
- GstD3D11Device *self = GST_D3D11_DEVICE (user_data);
- GstD3D11DevicePrivate *priv = self->priv;
-
- GST_TRACE_OBJECT (self, "Main loop running now");
-
- g_mutex_lock (&priv->lock);
- g_cond_signal (&priv->cond);
- g_mutex_unlock (&priv->lock);
-
- return G_SOURCE_REMOVE;
-}
-
-static gpointer
-gst_d3d11_device_thread_func (gpointer data)
-{
- GstD3D11Device *self = GST_D3D11_DEVICE (data);
- GstD3D11DevicePrivate *priv = self->priv;
- GSource *source;
-
- GST_DEBUG_OBJECT (self, "Enter loop");
- g_main_context_push_thread_default (priv->main_context);
-
- source = g_idle_source_new ();
- g_source_set_callback (source, (GSourceFunc) running_cb, self, NULL);
- g_source_attach (source, priv->main_context);
- g_source_unref (source);
-
- priv->active_thread = g_thread_self ();
- g_main_loop_run (priv->loop);
-
- g_main_context_pop_thread_default (priv->main_context);
-
- GST_DEBUG_OBJECT (self, "Exit loop");
-
- return NULL;
-}
-
/**
* gst_d3d11_device_new:
* @adapter: the index of adapter for creating d3d11 device
return device->priv->feature_level;
}
-typedef struct
-{
- GstD3D11Device *device;
- GstD3D11DeviceThreadFunc func;
-
- gpointer data;
- gboolean fired;
-} MessageData;
-
-static gboolean
-gst_d3d11_device_message_callback (MessageData * msg)
-{
- GstD3D11Device *self = msg->device;
- GstD3D11DevicePrivate *priv = self->priv;
-
- msg->func (self, msg->data);
-
- g_mutex_lock (&priv->lock);
- msg->fired = TRUE;
- g_cond_broadcast (&priv->cond);
- g_mutex_unlock (&priv->lock);
-
- return G_SOURCE_REMOVE;
-}
-
-/**
- * gst_d3d11_device_thread_add:
- * @device: a #GstD3D11Device
- * @func: (scope call): a #GstD3D11DeviceThreadFunc
- * @data: (closure): user data to call @func with
- *
- * Execute @func in the D3DDevice thread of @device with @data
- *
- * MT-safe
- */
-void
-gst_d3d11_device_thread_add (GstD3D11Device * device,
- GstD3D11DeviceThreadFunc func, gpointer data)
-{
- gst_d3d11_device_thread_add_full (device,
- G_PRIORITY_DEFAULT, func, data, NULL);
-}
-
-/**
- * gst_d3d11_device_thread_add_full:
- * @device: a #GstD3D11Device
- * @priority: the priority at which to run @func
- * @func: (scope call): a #GstD3D11DeviceThreadFunc
- * @data: (closure): user data to call @func with
- * @notify: (nullable): a function to call when @data is no longer in use, or %NULL.
- *
- * Execute @func in the D3DDevice thread of @device with @data with specified
- * @priority
- *
- * MT-safe
- */
-void
-gst_d3d11_device_thread_add_full (GstD3D11Device * device,
- gint priority, GstD3D11DeviceThreadFunc func, gpointer data,
- GDestroyNotify notify)
-{
- GstD3D11DevicePrivate *priv;
- MessageData msg = { 0, };
-
- g_return_if_fail (GST_IS_D3D11_DEVICE (device));
- g_return_if_fail (func != NULL);
-
- priv = device->priv;
-
- if (priv->active_thread == g_thread_self ()) {
- func (device, data);
- return;
- }
-
- msg.device = gst_object_ref (device);
- msg.func = func;
- msg.data = data;
- msg.fired = FALSE;
-
- g_main_context_invoke_full (priv->main_context, priority,
- (GSourceFunc) gst_d3d11_device_message_callback, &msg, notify);
-
- g_mutex_lock (&priv->lock);
- while (!msg.fired)
- g_cond_wait (&priv->cond, &priv->lock);
- g_mutex_unlock (&priv->lock);
-
- gst_object_unref (device);
-}
-
-typedef struct
-{
- IDXGISwapChain *swap_chain;
- const DXGI_SWAP_CHAIN_DESC *desc;
-} CreateSwapChainData;
-
-static void
-gst_d3d11_device_create_swap_chain_internal (GstD3D11Device * device,
- CreateSwapChainData * data)
-{
- GstD3D11DevicePrivate *priv = device->priv;
- HRESULT hr;
-
- hr = IDXGIFactory1_CreateSwapChain (priv->factory, (IUnknown *) priv->device,
- (DXGI_SWAP_CHAIN_DESC *) data->desc, &data->swap_chain);
-
- if (!gst_d3d11_result (hr)) {
- GST_ERROR_OBJECT (device, "Cannot create SwapChain Object: 0x%x",
- (guint) hr);
- data->swap_chain = NULL;
- }
-}
-
/**
* gst_d3d11_device_create_swap_chain:
* @device: a #GstD3D11Device
gst_d3d11_device_create_swap_chain (GstD3D11Device * device,
const DXGI_SWAP_CHAIN_DESC * desc)
{
- CreateSwapChainData data = { 0, };
+ GstD3D11DevicePrivate *priv;
+ HRESULT hr;
+ IDXGISwapChain *swap_chain = NULL;
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
- data.swap_chain = NULL;
- data.desc = desc;
-
- gst_d3d11_device_thread_add (device, (GstD3D11DeviceThreadFunc)
- gst_d3d11_device_create_swap_chain_internal, &data);
-
- return data.swap_chain;
-}
-
-#if (DXGI_HEADER_VERSION >= 2)
-typedef struct
-{
- IDXGISwapChain1 *swap_chain;
- HWND hwnd;
- const DXGI_SWAP_CHAIN_DESC1 *desc;
- const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc;
- IDXGIOutput *output;
-} CreateSwapChainForHwndData;
-
-static void
-gst_d3d11_device_create_swap_chain_for_hwnd_internal (GstD3D11Device * device,
- CreateSwapChainForHwndData * data)
-{
- GstD3D11DevicePrivate *priv = device->priv;
- HRESULT hr;
+ priv = device->priv;
- hr = IDXGIFactory2_CreateSwapChainForHwnd ((IDXGIFactory2 *) priv->factory,
- (IUnknown *) priv->device, data->hwnd, data->desc, data->fullscreen_desc,
- data->output, &data->swap_chain);
+ gst_d3d11_device_lock (device);
+ hr = IDXGIFactory1_CreateSwapChain (priv->factory, (IUnknown *) priv->device,
+ (DXGI_SWAP_CHAIN_DESC *) desc, &swap_chain);
+ gst_d3d11_device_unlock (device);
if (!gst_d3d11_result (hr)) {
GST_ERROR_OBJECT (device, "Cannot create SwapChain Object: 0x%x",
(guint) hr);
- data->swap_chain = NULL;
+ swap_chain = NULL;
}
+
+ return swap_chain;
}
+#if (DXGI_HEADER_VERSION >= 2)
/**
* gst_d3d11_device_create_swap_chain_for_hwnd:
* @device: a #GstD3D11Device
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC * fullscreen_desc,
IDXGIOutput * output)
{
- CreateSwapChainForHwndData data = { 0, };
+ GstD3D11DevicePrivate *priv;
+ IDXGISwapChain1 *swap_chain = NULL;
+ HRESULT hr;
g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
- data.swap_chain = NULL;
- data.hwnd = hwnd;
- data.desc = desc;
- data.fullscreen_desc = fullscreen_desc;
- data.output = output;
+ priv = device->priv;
- gst_d3d11_device_thread_add (device, (GstD3D11DeviceThreadFunc)
- gst_d3d11_device_create_swap_chain_for_hwnd_internal, &data);
+ gst_d3d11_device_lock (device);
+ hr = IDXGIFactory2_CreateSwapChainForHwnd ((IDXGIFactory2 *) priv->factory,
+ (IUnknown *) priv->device, hwnd, desc, fullscreen_desc,
+ output, &swap_chain);
+ gst_d3d11_device_unlock (device);
- return data.swap_chain;
-}
-#endif
+ if (!gst_d3d11_result (hr)) {
+ GST_ERROR_OBJECT (device, "Cannot create SwapChain Object: 0x%x",
+ (guint) hr);
+ swap_chain = NULL;
+ }
-static void
-gst_d3d11_device_release_swap_chain_internal (GstD3D11Device * device,
- IDXGISwapChain * swap_chain)
-{
- IDXGISwapChain_Release (swap_chain);
+ return swap_chain;
}
+#endif
/**
* gst_d3d11_device_release_swap_chain:
* @swap_chain: a IDXGISwapChain
*
* Release a @swap_chain from device thread
- *
*/
void
gst_d3d11_device_release_swap_chain (GstD3D11Device * device,
IDXGISwapChain * swap_chain)
{
g_return_if_fail (GST_IS_D3D11_DEVICE (device));
+ g_return_if_fail (swap_chain != NULL);
- gst_d3d11_device_thread_add (device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_device_release_swap_chain_internal,
- swap_chain);
+ gst_d3d11_device_lock (device);
+ IDXGISwapChain_Release (swap_chain);
+ gst_d3d11_device_unlock (device);
}
-typedef struct
+ID3D11Texture2D *
+gst_d3d11_device_create_texture (GstD3D11Device * device,
+ const D3D11_TEXTURE2D_DESC * desc,
+ const D3D11_SUBRESOURCE_DATA * inital_data)
{
+ GstD3D11DevicePrivate *priv;
+ HRESULT hr;
ID3D11Texture2D *texture;
- const D3D11_TEXTURE2D_DESC *desc;
- const D3D11_SUBRESOURCE_DATA *inital_data;
-} CreateTextureData;
-static void
-gst_d3d11_device_create_texture_internal (GstD3D11Device * device,
- CreateTextureData * data)
-{
- GstD3D11DevicePrivate *priv = device->priv;
- HRESULT hr;
+ g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
+ g_return_val_if_fail (desc != NULL, NULL);
- hr = ID3D11Device_CreateTexture2D (priv->device, data->desc,
- data->inital_data, &data->texture);
- if (!gst_d3d11_result (hr)) {
- const D3D11_TEXTURE2D_DESC *desc = data->desc;
+ priv = device->priv;
+ hr = ID3D11Device_CreateTexture2D (priv->device, desc, inital_data, &texture);
+ if (!gst_d3d11_result (hr)) {
GST_ERROR ("Failed to create texture (0x%x)", (guint) hr);
GST_WARNING ("Direct3D11 Allocation params");
GST_WARNING ("\tBindFlags 0x%x", desc->BindFlags);
GST_WARNING ("\tCPUAccessFlags 0x%x", desc->CPUAccessFlags);
GST_WARNING ("\tMiscFlags 0x%x", desc->MiscFlags);
- data->texture = NULL;
+ texture = NULL;
}
+
+ return texture;
}
-ID3D11Texture2D *
-gst_d3d11_device_create_texture (GstD3D11Device * device,
- const D3D11_TEXTURE2D_DESC * desc,
- const D3D11_SUBRESOURCE_DATA * inital_data)
+void
+gst_d3d11_device_release_texture (GstD3D11Device * device,
+ ID3D11Texture2D * texture)
{
- CreateTextureData data;
+ g_return_if_fail (GST_IS_D3D11_DEVICE (device));
+ g_return_if_fail (texture != NULL);
- g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
- g_return_val_if_fail (desc != NULL, NULL);
+ ID3D11Texture2D_Release (texture);
+}
- data.texture = NULL;
- data.desc = desc;
- data.inital_data = inital_data;
+void
+gst_d3d11_device_lock (GstD3D11Device * device)
+{
+ GstD3D11DevicePrivate *priv;
- gst_d3d11_device_thread_add (device, (GstD3D11DeviceThreadFunc)
- gst_d3d11_device_create_texture_internal, &data);
+ g_return_if_fail (GST_IS_D3D11_DEVICE (device));
- return data.texture;
-}
+ priv = device->priv;
-static void
-gst_d3d11_device_release_texture_internal (GstD3D11Device * device,
- ID3D11Texture2D * texture)
-{
- ID3D11Texture2D_Release (texture);
+ GST_TRACE_OBJECT (device, "device locking");
+ g_rec_mutex_lock (&priv->extern_lock);
+ GST_TRACE_OBJECT (device, "device locked");
}
void
-gst_d3d11_device_release_texture (GstD3D11Device * device,
- ID3D11Texture2D * texture)
+gst_d3d11_device_unlock (GstD3D11Device * device)
{
+ GstD3D11DevicePrivate *priv;
+
g_return_if_fail (GST_IS_D3D11_DEVICE (device));
- g_return_if_fail (texture != NULL);
- gst_d3d11_device_thread_add (device, (GstD3D11DeviceThreadFunc)
- gst_d3d11_device_release_texture_internal, texture);
+ priv = device->priv;
+
+ g_rec_mutex_unlock (&priv->extern_lock);
+ GST_TRACE_OBJECT (device, "device unlocked");
}
void gst_d3d11_device_release_swap_chain (GstD3D11Device * device,
IDXGISwapChain * swap_chain);
-void gst_d3d11_device_thread_add (GstD3D11Device * device,
- GstD3D11DeviceThreadFunc func,
- gpointer data);
-
-void gst_d3d11_device_thread_add_full (GstD3D11Device * device,
- gint priority,
- GstD3D11DeviceThreadFunc func,
- gpointer data,
- GDestroyNotify notify);
-
ID3D11Texture2D * gst_d3d11_device_create_texture (GstD3D11Device * device,
const D3D11_TEXTURE2D_DESC * desc,
const D3D11_SUBRESOURCE_DATA *inital_data);
void gst_d3d11_device_release_texture (GstD3D11Device * device,
ID3D11Texture2D * texture);
+void gst_d3d11_device_lock (GstD3D11Device * device);
+
+void gst_d3d11_device_unlock (GstD3D11Device * device);
+
G_END_DECLS
#endif /* __GST_D3D11_DEVICE_H__ */
query);
}
-typedef struct
-{
- GstD3D11BaseFilter *filter;
- GstBuffer *inbuf;
- GstBuffer *outbuf;
- GstFlowReturn ret;
-} UploadTransformData;
-
-static void
-download_transform (GstD3D11Device * device, UploadTransformData * data)
+static GstFlowReturn
+gst_d3d11_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
+ GstBuffer * outbuf)
{
+ GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
GstVideoFrame in_frame, out_frame;
- GstD3D11BaseFilter *filter = data->filter;
gint i;
- if (!gst_video_frame_map (&in_frame, &filter->in_info, data->inbuf,
+ if (!gst_video_frame_map (&in_frame, &filter->in_info, inbuf,
GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))
goto invalid_buffer;
- if (!gst_video_frame_map (&out_frame, &filter->out_info, data->outbuf,
+ if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF)) {
gst_video_frame_unmap (&in_frame);
goto invalid_buffer;
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (&in_frame); i++) {
if (!gst_video_frame_copy_plane (&out_frame, &in_frame, i)) {
GST_ERROR_OBJECT (filter, "Couldn't copy %dth plane", i);
- data->ret = GST_FLOW_ERROR;
- return;
+ return GST_FLOW_ERROR;
}
}
gst_video_frame_unmap (&out_frame);
gst_video_frame_unmap (&in_frame);
- data->ret = GST_FLOW_OK;
- return;
+ return GST_FLOW_OK;
/* ERRORS */
invalid_buffer:
{
GST_ELEMENT_WARNING (filter, CORE, NOT_IMPLEMENTED, (NULL),
("invalid video buffer received"));
- data->ret = GST_FLOW_ERROR;
- return;
+ return GST_FLOW_ERROR;
}
}
-
-static GstFlowReturn
-gst_d3d11_download_transform (GstBaseTransform * trans, GstBuffer * inbuf,
- GstBuffer * outbuf)
-{
- GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
- GstMemory *mem;
- GstD3D11Device *device;
- UploadTransformData data;
-
- mem = gst_buffer_peek_memory (inbuf, 0);
- if (gst_is_d3d11_memory (mem)) {
- GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
- device = dmem->device;
- } else {
- device = filter->device;
- }
-
- data.filter = filter;
- data.inbuf = inbuf;
- data.outbuf = outbuf;
- data.ret = GST_FLOW_OK;
-
- gst_d3d11_device_thread_add (device,
- (GstD3D11DeviceThreadFunc) download_transform, &data);
-
- return data.ret;
-}
return NULL;
}
-typedef struct
-{
- GstCaps *caps;
- D3D11_FORMAT_SUPPORT flags;
-} SupportCapsData;
-
-static void
-gst_d3d11_device_get_supported_caps_internal (GstD3D11Device * device,
- SupportCapsData * data)
+/**
+ * gst_d3d11_device_get_supported_caps:
+ * @device: a #GstD3DDevice
+ * @flags: D3D11_FORMAT_SUPPORT flags
+ *
+ * Check supported format with given flags
+ *
+ * Returns: a #GstCaps representing supported format
+ */
+GstCaps *
+gst_d3d11_device_get_supported_caps (GstD3D11Device * device,
+ D3D11_FORMAT_SUPPORT flags)
{
ID3D11Device *d3d11_device;
HRESULT hr;
GstCaps *supported_caps;
GstD3D11Format *format_list;
+ g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
+
d3d11_device = gst_d3d11_device_get_device_handle (device);
g_value_init (&v_list, GST_TYPE_LIST);
hr = ID3D11Device_CheckFormatSupport (d3d11_device,
format_list[i].dxgi_format, &format_support);
- if (SUCCEEDED (hr) && ((format_support & data->flags) == data->flags)) {
+ if (SUCCEEDED (hr) && ((format_support & flags) == flags)) {
GValue v_str = G_VALUE_INIT;
g_value_init (&v_str, G_TYPE_STRING);
GST_LOG_OBJECT (device, "d3d11 device can support %s with flags 0x%x",
- gst_video_format_to_string (format), data->flags);
+ gst_video_format_to_string (format), flags);
g_value_set_string (&v_str, gst_video_format_to_string (format));
gst_value_list_append_and_take_value (&v_list, &v_str);
}
gst_caps_set_features_simple (supported_caps,
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_D3D11_MEMORY));
- data->caps = supported_caps;
-}
-
-/**
- * gst_d3d11_device_get_supported_caps:
- * @device: a #GstD3DDevice
- * @flags: D3D11_FORMAT_SUPPORT flags
- *
- * Check supported format with given flags
- *
- * Returns: a #GstCaps representing supported format
- */
-GstCaps *
-gst_d3d11_device_get_supported_caps (GstD3D11Device * device,
- D3D11_FORMAT_SUPPORT flags)
-{
- SupportCapsData data;
-
- g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), NULL);
-
- data.caps = NULL;
- data.flags = flags;
-
- gst_d3d11_device_thread_add (device, (GstD3D11DeviceThreadFunc)
- gst_d3d11_device_get_supported_caps_internal, &data);
-
- return data.caps;
+ return supported_caps;
}
return gst_d3d11_device_create_texture (device, &desc, NULL);
}
-typedef struct
+static gboolean
+map_cpu_access_data (GstD3D11Memory * dmem, D3D11_MAP map_type)
{
- ID3D11Resource *dst;
- ID3D11Resource *src;
-} D3D11CopyTextureData;
-
-static void
-copy_texture (GstD3D11Device * device, D3D11CopyTextureData * data)
-{
- ID3D11DeviceContext *device_context =
- gst_d3d11_device_get_device_context_handle (device);
-
- ID3D11DeviceContext_CopySubresourceRegion (device_context,
- data->dst, 0, 0, 0, 0, data->src, 0, NULL);
-}
-
-typedef struct
-{
- GstD3D11Memory *mem;
- D3D11_MAP map_type;
-
- gboolean ret;
-} D3D11MapData;
-
-static void
-map_cpu_access_data (GstD3D11Device * device, D3D11MapData * map_data)
-{
- GstD3D11Memory *dmem = map_data->mem;
HRESULT hr;
+ gboolean ret = TRUE;
ID3D11Resource *texture = (ID3D11Resource *) dmem->texture;
ID3D11Resource *staging = (ID3D11Resource *) dmem->staging;
ID3D11DeviceContext *device_context =
- gst_d3d11_device_get_device_context_handle (device);
+ gst_d3d11_device_get_device_context_handle (dmem->device);
+ gst_d3d11_device_lock (dmem->device);
if (GST_MEMORY_FLAG_IS_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD)) {
ID3D11DeviceContext_CopySubresourceRegion (device_context,
staging, 0, 0, 0, 0, texture, 0, NULL);
}
hr = ID3D11DeviceContext_Map (device_context,
- staging, 0, map_data->map_type, 0, &dmem->map);
+ staging, 0, map_type, 0, &dmem->map);
if (!gst_d3d11_result (hr)) {
GST_ERROR_OBJECT (GST_MEMORY_CAST (dmem)->allocator,
"Failed to map staging texture (0x%x)", (guint) hr);
- map_data->ret = FALSE;
+ ret = FALSE;
}
- map_data->ret = TRUE;
+ gst_d3d11_device_unlock (dmem->device);
+
+ return ret;
}
static gpointer
if ((flags & GST_MAP_D3D11) == GST_MAP_D3D11) {
if (dmem->staging &&
GST_MEMORY_FLAG_IS_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD)) {
- D3D11CopyTextureData data;
-
- data.dst = (ID3D11Resource *) dmem->texture;
- data.src = (ID3D11Resource *) dmem->staging;
-
- gst_d3d11_device_thread_add (dmem->device,
- (GstD3D11DeviceThreadFunc) copy_texture, &data);
+ ID3D11DeviceContext *device_context =
+ gst_d3d11_device_get_device_context_handle (dmem->device);
+
+ gst_d3d11_device_lock (dmem->device);
+ ID3D11DeviceContext_CopySubresourceRegion (device_context,
+ (ID3D11Resource *) dmem->texture, 0, 0, 0, 0,
+ (ID3D11Resource *) dmem->staging, 0, NULL);
+ gst_d3d11_device_unlock (dmem->device);
}
GST_MEMORY_FLAG_UNSET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD);
}
if (dmem->cpu_map_count == 0) {
- D3D11MapData map_data;
+ D3D11_MAP map_type;
/* Allocate staging texture for CPU access */
if (!dmem->staging) {
GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD);
}
- map_data.mem = dmem;
- map_data.map_type = gst_map_flags_to_d3d11 (flags);
-
- gst_d3d11_device_thread_add (dmem->device, (GstD3D11DeviceThreadFunc)
- map_cpu_access_data, &map_data);
+ map_type = gst_map_flags_to_d3d11 (flags);
- if (!map_data.ret) {
+ if (!map_cpu_access_data (dmem, map_type)) {
GST_ERROR_OBJECT (mem->allocator, "Couldn't map staging texture");
g_mutex_unlock (&dmem->lock);
}
static void
-unmap_cpu_access_data (GstD3D11Device * device, gpointer data)
+unmap_cpu_access_data (GstD3D11Memory * dmem)
{
- GstD3D11Memory *dmem = (GstD3D11Memory *) data;
ID3D11Resource *staging = (ID3D11Resource *) dmem->staging;
ID3D11DeviceContext *device_context =
- gst_d3d11_device_get_device_context_handle (device);
+ gst_d3d11_device_get_device_context_handle (dmem->device);
+ gst_d3d11_device_lock (dmem->device);
ID3D11DeviceContext_Unmap (device_context, staging, 0);
+ gst_d3d11_device_unlock (dmem->device);
}
static void
return;
}
- gst_d3d11_device_thread_add (dmem->device, (GstD3D11DeviceThreadFunc)
- unmap_cpu_access_data, dmem);
+ unmap_cpu_access_data (dmem);
g_mutex_unlock (&dmem->lock);
}
}
static void
-release_texture (GstD3D11Device * device, GstD3D11Memory * mem)
+gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem)
{
+ GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
gint i;
for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
- if (mem->render_target_view[i])
- ID3D11RenderTargetView_Release (mem->render_target_view[i]);
- mem->render_target_view[i] = NULL;
+ if (dmem->render_target_view[i])
+ ID3D11RenderTargetView_Release (dmem->render_target_view[i]);
+ dmem->render_target_view[i] = NULL;
- if (mem->shader_resource_view[i])
- ID3D11ShaderResourceView_Release (mem->shader_resource_view[i]);
- mem->shader_resource_view[i] = NULL;
+ if (dmem->shader_resource_view[i])
+ ID3D11ShaderResourceView_Release (dmem->shader_resource_view[i]);
+ dmem->shader_resource_view[i] = NULL;
}
- if (mem->texture)
- ID3D11Texture2D_Release (mem->texture);
+ if (dmem->texture)
+ ID3D11Texture2D_Release (dmem->texture);
- if (mem->staging)
- ID3D11Texture2D_Release (mem->staging);
-}
-
-static void
-gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem)
-{
- GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
- GstD3D11Device *device = dmem->device;
+ if (dmem->staging)
+ ID3D11Texture2D_Release (dmem->staging);
- gst_d3d11_device_thread_add (device,
- (GstD3D11DeviceThreadFunc) release_texture, dmem);
-
- gst_object_unref (device);
+ gst_clear_object (&dmem->device);
g_mutex_clear (&dmem->lock);
g_free (dmem);
return allocator;
}
-typedef struct
-{
- ID3D11Resource *texture;
- D3D11_TEXTURE2D_DESC *desc;
- D3D11_MAP map_mode;
-
- gint stride[GST_VIDEO_MAX_PLANES];
- gsize size;
-
- gboolean ret;
-} CalSizeData;
-
-static void
-calculate_mem_size (GstD3D11Device * device, CalSizeData * data)
+static gboolean
+calculate_mem_size (GstD3D11Device * device, ID3D11Texture2D * texture,
+ D3D11_TEXTURE2D_DESC * desc, D3D11_MAP map_type,
+ gint stride[GST_VIDEO_MAX_PLANES], gsize * size)
{
HRESULT hr;
+ gboolean ret = TRUE;
D3D11_MAPPED_SUBRESOURCE map;
gsize offset[GST_VIDEO_MAX_PLANES];
ID3D11DeviceContext *device_context =
gst_d3d11_device_get_device_context_handle (device);
+ gst_d3d11_device_lock (device);
hr = ID3D11DeviceContext_Map (device_context,
- data->texture, 0, data->map_mode, 0, &map);
+ (ID3D11Resource *) texture, 0, map_type, 0, &map);
if (!gst_d3d11_result (hr)) {
GST_ERROR_OBJECT (device, "Failed to map texture (0x%x)", (guint) hr);
- data->ret = FALSE;
+ gst_d3d11_device_unlock (device);
+ return FALSE;
}
- data->ret = gst_d3d11_dxgi_format_get_size (data->desc->Format,
- data->desc->Width, data->desc->Height, map.RowPitch,
- offset, data->stride, &data->size);
+ ret = gst_d3d11_dxgi_format_get_size (desc->Format,
+ desc->Width, desc->Height, map.RowPitch, offset, stride, size);
+
+ ID3D11DeviceContext_Unmap (device_context, (ID3D11Resource *) texture, 0);
+ gst_d3d11_device_unlock (device);
- ID3D11DeviceContext_Unmap (device_context, data->texture, 0);
+ return ret;
}
static void
-create_shader_resource_views (GstD3D11Device * device, GstD3D11Memory * mem)
+create_shader_resource_views (GstD3D11Memory * mem)
{
gint i;
HRESULT hr;
D3D11_SHADER_RESOURCE_VIEW_DESC resource_desc = { 0, };
DXGI_FORMAT formats[GST_VIDEO_MAX_PLANES] = { DXGI_FORMAT_UNKNOWN, };
- device_handle = gst_d3d11_device_get_device_handle (device);
+ device_handle = gst_d3d11_device_get_device_handle (mem->device);
switch (mem->desc.Format) {
case DXGI_FORMAT_B8G8R8A8_UNORM:
&mem->shader_resource_view[i]);
if (!gst_d3d11_result (hr)) {
- GST_ERROR_OBJECT (device,
+ GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator,
"Failed to create %dth resource view (0x%x)", i, (guint) hr);
goto error;
}
}
static void
-create_render_target_views (GstD3D11Device * device, GstD3D11Memory * mem)
+create_render_target_views (GstD3D11Memory * mem)
{
gint i;
HRESULT hr;
D3D11_RENDER_TARGET_VIEW_DESC render_desc = { 0, };
DXGI_FORMAT formats[GST_VIDEO_MAX_PLANES] = { DXGI_FORMAT_UNKNOWN, };
- device_handle = gst_d3d11_device_get_device_handle (device);
+ device_handle = gst_d3d11_device_get_device_handle (mem->device);
switch (mem->desc.Format) {
case DXGI_FORMAT_B8G8R8A8_UNORM:
(ID3D11Resource *) mem->texture, &render_desc,
&mem->render_target_view[i]);
if (!gst_d3d11_result (hr)) {
- GST_ERROR_OBJECT (device,
+ GST_ERROR_OBJECT (GST_MEMORY_CAST (mem)->allocator,
"Failed to create %dth render target view (0x%x)", i, (guint) hr);
goto error;
}
/* per plane, allocated staging texture to calculate actual size,
* stride, and offset */
if (is_first) {
- CalSizeData data;
+ ID3D11Texture2D *target;
+ D3D11_MAP map_type;
gint num_plane;
+ gint stride[GST_VIDEO_MAX_PLANES];
+ gsize mem_size;
gint i;
if (desc->Usage == D3D11_USAGE_DEFAULT) {
goto error;
}
- data.texture = (ID3D11Resource *) staging;
- data.map_mode = D3D11_MAP_READ;
+ target = staging;
+ map_type = D3D11_MAP_READ;
} else if (desc->Usage == D3D11_USAGE_DYNAMIC) {
- data.texture = (ID3D11Resource *) texture;
- data.map_mode = D3D11_MAP_WRITE_DISCARD;
+ target = texture;
+ map_type = D3D11_MAP_WRITE_DISCARD;
} else {
g_assert_not_reached ();
}
- data.desc = desc;
-
- gst_d3d11_device_thread_add (device,
- (GstD3D11DeviceThreadFunc) calculate_mem_size, &data);
+ if (!calculate_mem_size (device, target, desc, map_type, stride, &mem_size))
+ goto error;
num_plane = gst_d3d11_dxgi_format_n_planes (desc->Format);
for (i = 0; i < num_plane; i++) {
- params->stride[params->plane + i] = data.stride[i];
+ params->stride[params->plane + i] = stride[i];
}
- *size = data.size;
+ *size = mem_size;
}
mem = g_new0 (GstD3D11Memory, 1);
return FALSE;
}
- gst_d3d11_device_thread_add (mem->device,
- (GstD3D11DeviceThreadFunc) create_shader_resource_views, mem);
+ create_shader_resource_views (mem);
return ! !mem->num_shader_resource_views;
}
return FALSE;
}
- gst_d3d11_device_thread_add (mem->device,
- (GstD3D11DeviceThreadFunc) create_render_target_views, mem);
+ create_render_target_views (mem);
return ! !mem->num_render_target_views;
}
return ret;
}
-typedef struct
-{
- const gchar *source;
- ID3D11PixelShader *shader;
- gboolean ret;
-} CreatePSData;
-
-static void
-create_pixel_shader (GstD3D11Device * device, CreatePSData * data)
+gboolean
+gst_d3d11_create_pixel_shader (GstD3D11Device * device,
+ const gchar * source, ID3D11PixelShader ** shader)
{
ID3DBlob *ps_blob;
ID3D11Device *device_handle;
HRESULT hr;
- data->ret = TRUE;
+ g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
+ g_return_val_if_fail (source != NULL, FALSE);
+ g_return_val_if_fail (shader != NULL, FALSE);
- ps_blob = compile_shader (device, data->source, TRUE);
+ gst_d3d11_device_lock (device);
+ ps_blob = compile_shader (device, source, TRUE);
if (!ps_blob) {
GST_ERROR ("Failed to compile pixel shader");
- data->ret = FALSE;
- return;
+ gst_d3d11_device_unlock (device);
+ return FALSE;
}
device_handle = gst_d3d11_device_get_device_handle (device);
hr = ID3D11Device_CreatePixelShader (device_handle,
(gpointer) ID3D10Blob_GetBufferPointer (ps_blob),
- ID3D10Blob_GetBufferSize (ps_blob), NULL, &data->shader);
+ ID3D10Blob_GetBufferSize (ps_blob), NULL, shader);
if (!gst_d3d11_result (hr)) {
GST_ERROR ("could not create pixel shader, hr: 0x%x", (guint) hr);
- data->ret = FALSE;
+ gst_d3d11_device_unlock (device);
+ return FALSE;
}
ID3D10Blob_Release (ps_blob);
-}
-
-gboolean
-gst_d3d11_create_pixel_shader (GstD3D11Device * device,
- const gchar * source, ID3D11PixelShader ** shader)
-{
- CreatePSData data = { 0, };
+ gst_d3d11_device_unlock (device);
- g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
- g_return_val_if_fail (source != NULL, FALSE);
- g_return_val_if_fail (shader != NULL, FALSE);
-
- data.source = source;
-
- gst_d3d11_device_thread_add (device,
- (GstD3D11DeviceThreadFunc) create_pixel_shader, &data);
-
- *shader = data.shader;
- return data.ret;
+ return TRUE;
}
-typedef struct
-{
- const gchar *source;
- const D3D11_INPUT_ELEMENT_DESC *input_desc;
- guint desc_len;
- ID3D11VertexShader *shader;
- ID3D11InputLayout *layout;
- gboolean ret;
-} CreateVSData;
-
-static void
-create_vertex_shader (GstD3D11Device * device, CreateVSData * data)
+gboolean
+gst_d3d11_create_vertex_shader (GstD3D11Device * device, const gchar * source,
+ const D3D11_INPUT_ELEMENT_DESC * input_desc, guint desc_len,
+ ID3D11VertexShader ** shader, ID3D11InputLayout ** layout)
{
ID3DBlob *vs_blob;
ID3D11Device *device_handle;
HRESULT hr;
ID3D11VertexShader *vshader = NULL;
ID3D11InputLayout *in_layout = NULL;
+ gboolean ret = FALSE;
- data->ret = TRUE;
+ g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
+ g_return_val_if_fail (source != NULL, FALSE);
+ g_return_val_if_fail (input_desc != NULL, FALSE);
+ g_return_val_if_fail (desc_len > 0, FALSE);
+ g_return_val_if_fail (shader != NULL, FALSE);
+ g_return_val_if_fail (layout != NULL, FALSE);
- vs_blob = compile_shader (device, data->source, FALSE);
+ gst_d3d11_device_lock (device);
+ vs_blob = compile_shader (device, source, FALSE);
if (!vs_blob) {
GST_ERROR ("Failed to compile shader code");
- data->ret = FALSE;
- return;
+ goto done;
}
device_handle = gst_d3d11_device_get_device_handle (device);
if (!gst_d3d11_result (hr)) {
GST_ERROR ("could not create vertex shader, hr: 0x%x", (guint) hr);
ID3D10Blob_Release (vs_blob);
- data->ret = FALSE;
- return;
+ goto done;
}
- hr = ID3D11Device_CreateInputLayout (device_handle, data->input_desc,
- data->desc_len, (gpointer) ID3D10Blob_GetBufferPointer (vs_blob),
+ hr = ID3D11Device_CreateInputLayout (device_handle, input_desc,
+ desc_len, (gpointer) ID3D10Blob_GetBufferPointer (vs_blob),
ID3D10Blob_GetBufferSize (vs_blob), &in_layout);
if (!gst_d3d11_result (hr)) {
GST_ERROR ("could not create input layout shader, hr: 0x%x", (guint) hr);
ID3D10Blob_Release (vs_blob);
ID3D11VertexShader_Release (vshader);
- data->ret = FALSE;
- return;
+ goto done;
}
ID3D10Blob_Release (vs_blob);
- data->shader = vshader;
- data->layout = in_layout;
-}
-
-gboolean
-gst_d3d11_create_vertex_shader (GstD3D11Device * device, const gchar * source,
- const D3D11_INPUT_ELEMENT_DESC * input_desc, guint desc_len,
- ID3D11VertexShader ** shader, ID3D11InputLayout ** layout)
-{
- CreateVSData data = { 0, };
-
- g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), FALSE);
- g_return_val_if_fail (source != NULL, FALSE);
- g_return_val_if_fail (input_desc != NULL, FALSE);
- g_return_val_if_fail (desc_len > 0, FALSE);
- g_return_val_if_fail (shader != NULL, FALSE);
- g_return_val_if_fail (layout != NULL, FALSE);
+ *shader = vshader;
+ *layout = in_layout;
- data.source = source;
- data.input_desc = input_desc;
- data.desc_len = desc_len;
+ ret = TRUE;
- gst_d3d11_device_thread_add (device,
- (GstD3D11DeviceThreadFunc) create_vertex_shader, &data);
+done:
+ gst_d3d11_device_unlock (device);
- *shader = data.shader;
- *layout = data.layout;
- return data.ret;
+ return ret;
}
struct _GstD3D11Quad
return quad;
}
-static void
-quad_free (GstD3D11Device * device, GstD3D11Quad * quad)
+void
+gst_d3d11_quad_free (GstD3D11Quad * quad)
{
+ g_return_if_fail (quad != NULL);
+
if (quad->ps)
ID3D11PixelShader_Release (quad->ps);
if (quad->vs)
ID3D11Buffer_Release (quad->vertex_buffer);
if (quad->index_buffer)
ID3D11Buffer_Release (quad->index_buffer);
+
+ gst_clear_object (&quad->device);
+ g_free (quad);
}
-void
-gst_d3d11_quad_free (GstD3D11Quad * quad)
+gboolean
+gst_d3d11_draw_quad (GstD3D11Quad * quad,
+ D3D11_VIEWPORT viewport[GST_VIDEO_MAX_PLANES], guint num_viewport,
+ ID3D11ShaderResourceView * srv[GST_VIDEO_MAX_PLANES], guint num_srv,
+ ID3D11RenderTargetView * rtv[GST_VIDEO_MAX_PLANES], guint num_rtv)
{
- g_return_if_fail (quad != NULL);
+ gboolean ret;
- if (quad->device) {
- gst_d3d11_device_thread_add (quad->device,
- (GstD3D11DeviceThreadFunc) quad_free, quad);
+ g_return_val_if_fail (quad != NULL, FALSE);
- gst_object_unref (quad->device);
- }
+ gst_d3d11_device_lock (quad->device);
+ ret = gst_d3d11_draw_quad_unlocked (quad, viewport, num_viewport,
+ srv, num_srv, rtv, num_viewport);
+ gst_d3d11_device_unlock (quad->device);
- g_free (quad);
+ return ret;
}
-typedef struct
-{
- GstD3D11Quad *quad;
- D3D11_VIEWPORT viewport[GST_VIDEO_MAX_PLANES];
- guint num_viewport;
- ID3D11ShaderResourceView *srv[GST_VIDEO_MAX_PLANES];
- guint num_srv;
- ID3D11RenderTargetView *rtv[GST_VIDEO_MAX_PLANES];
- guint num_rtv;
-
- gboolean ret;
-} DrawQuadData;
-
-static void
-gst_d3d11_draw_quad_internal (GstD3D11Device * device, DrawQuadData * data)
+gboolean
+gst_d3d11_draw_quad_unlocked (GstD3D11Quad * quad,
+ D3D11_VIEWPORT viewport[GST_VIDEO_MAX_PLANES], guint num_viewport,
+ ID3D11ShaderResourceView * srv[GST_VIDEO_MAX_PLANES], guint num_srv,
+ ID3D11RenderTargetView * rtv[GST_VIDEO_MAX_PLANES], guint num_rtv)
{
ID3D11DeviceContext *context_handle;
UINT offsets = 0;
ID3D11ShaderResourceView *clear_view[GST_VIDEO_MAX_PLANES] = { NULL, };
- GstD3D11Quad *quad = data->quad;
+
+ g_return_val_if_fail (quad != NULL, FALSE);
+ g_return_val_if_fail (viewport != NULL, FALSE);
+ g_return_val_if_fail (num_viewport <= GST_VIDEO_MAX_PLANES, FALSE);
+ g_return_val_if_fail (srv != NULL, FALSE);
+ g_return_val_if_fail (num_srv <= GST_VIDEO_MAX_PLANES, FALSE);
+ g_return_val_if_fail (rtv != NULL, FALSE);
+ g_return_val_if_fail (num_rtv <= GST_VIDEO_MAX_PLANES, FALSE);
context_handle = gst_d3d11_device_get_device_context_handle (quad->device);
ID3D11DeviceContext_PSSetSamplers (context_handle, 0, 1, &quad->sampler);
ID3D11DeviceContext_VSSetShader (context_handle, quad->vs, NULL, 0);
ID3D11DeviceContext_PSSetShader (context_handle, quad->ps, NULL, 0);
- ID3D11DeviceContext_RSSetViewports (context_handle,
- data->num_viewport, data->viewport);
+ ID3D11DeviceContext_RSSetViewports (context_handle, num_viewport, viewport);
if (quad->const_buffer)
ID3D11DeviceContext_PSSetConstantBuffers (context_handle,
0, 1, &quad->const_buffer);
- ID3D11DeviceContext_PSSetShaderResources (context_handle,
- 0, data->num_srv, data->srv);
- ID3D11DeviceContext_OMSetRenderTargets (context_handle,
- data->num_rtv, data->rtv, NULL);
+ ID3D11DeviceContext_PSSetShaderResources (context_handle, 0, num_srv, srv);
+ ID3D11DeviceContext_OMSetRenderTargets (context_handle, num_rtv, rtv, NULL);
ID3D11DeviceContext_DrawIndexed (context_handle, quad->index_count, 0, 0);
ID3D11DeviceContext_PSSetShaderResources (context_handle,
- 0, data->num_srv, clear_view);
-
- data->ret = TRUE;
-}
-
-gboolean
-gst_d3d11_draw_quad (GstD3D11Quad * quad,
- D3D11_VIEWPORT viewport[GST_VIDEO_MAX_PLANES], guint num_viewport,
- ID3D11ShaderResourceView * srv[GST_VIDEO_MAX_PLANES], guint num_srv,
- ID3D11RenderTargetView * rtv[GST_VIDEO_MAX_PLANES], guint num_rtv)
-{
- DrawQuadData data = { 0, };
- gint i;
-
- g_return_val_if_fail (quad != NULL, FALSE);
- g_return_val_if_fail (viewport != NULL, FALSE);
- g_return_val_if_fail (num_viewport <= GST_VIDEO_MAX_PLANES, FALSE);
- g_return_val_if_fail (srv != NULL, FALSE);
- g_return_val_if_fail (num_srv <= GST_VIDEO_MAX_PLANES, FALSE);
- g_return_val_if_fail (rtv != NULL, FALSE);
- g_return_val_if_fail (num_rtv <= GST_VIDEO_MAX_PLANES, FALSE);
-
- data.quad = quad;
- for (i = 0; i < num_viewport; i++)
- data.viewport[i] = viewport[i];
- data.num_viewport = num_viewport;
-
- for (i = 0; i < num_srv; i++)
- data.srv[i] = srv[i];
- data.num_srv = num_srv;
-
- for (i = 0; i < num_rtv; i++)
- data.rtv[i] = rtv[i];
- data.num_rtv = num_rtv;
-
- data.ret = TRUE;
-
- gst_d3d11_device_thread_add (quad->device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_draw_quad_internal, &data);
+ 0, num_srv, clear_view);
+ ID3D11DeviceContext_OMSetRenderTargets (context_handle, 0, NULL, NULL);
- return data.ret;
+ return TRUE;
}
ID3D11RenderTargetView *rtv[GST_VIDEO_MAX_PLANES],
guint num_rtv);
+gboolean gst_d3d11_draw_quad_unlocked (GstD3D11Quad * quad,
+ D3D11_VIEWPORT viewport[GST_VIDEO_MAX_PLANES],
+ guint num_viewport,
+ ID3D11ShaderResourceView *srv[GST_VIDEO_MAX_PLANES],
+ guint num_srv,
+ ID3D11RenderTargetView *rtv[GST_VIDEO_MAX_PLANES],
+ guint num_rtv);
+
G_END_DECLS
#endif /* __GST_D3D11_SHADER_H__ */
query);
}
-typedef struct
-{
- GstD3D11BaseFilter *filter;
- GstBuffer *inbuf;
- GstBuffer *outbuf;
- GstFlowReturn ret;
-} UploadTransformData;
-
-static void
-upload_transform_dynamic (GstD3D11Device * device, UploadTransformData * data)
+static GstFlowReturn
+upload_transform_dynamic (GstD3D11BaseFilter * filter,
+ GstD3D11Device * device, GstBuffer * inbuf, GstBuffer * outbuf)
{
GstVideoFrame in_frame;
- GstD3D11BaseFilter *filter = data->filter;
gint i, j, k;
+ GstFlowReturn ret = GST_FLOW_OK;
ID3D11DeviceContext *device_context =
gst_d3d11_device_get_device_context_handle (device);
- data->ret = GST_FLOW_OK;
-
- if (!gst_video_frame_map (&in_frame, &filter->in_info, data->inbuf,
+ if (!gst_video_frame_map (&in_frame, &filter->in_info, inbuf,
GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))
goto invalid_buffer;
- for (i = 0, j = 0; i < gst_buffer_n_memory (data->outbuf); i++) {
+ gst_d3d11_device_lock (device);
+ for (i = 0, j = 0; i < gst_buffer_n_memory (outbuf); i++) {
GstD3D11Memory *dmem =
- (GstD3D11Memory *) gst_buffer_peek_memory (data->outbuf, i);
+ (GstD3D11Memory *) gst_buffer_peek_memory (outbuf, i);
D3D11_MAPPED_SUBRESOURCE map;
HRESULT hr;
D3D11_TEXTURE2D_DESC *desc = &dmem->desc;
if (!gst_d3d11_result (hr)) {
GST_ERROR_OBJECT (filter,
"Failed to map staging texture (0x%x)", (guint) hr);
- data->ret = GST_FLOW_ERROR;
+ gst_d3d11_device_unlock (device);
+ ret = GST_FLOW_ERROR;
goto done;
}
ID3D11DeviceContext_Unmap (device_context,
(ID3D11Resource *) dmem->texture, 0);
}
+ gst_d3d11_device_unlock (device);
done:
gst_video_frame_unmap (&in_frame);
- data->ret = GST_FLOW_OK;
- return;
+ return ret;
/* ERRORS */
invalid_buffer:
{
GST_ELEMENT_WARNING (filter, CORE, NOT_IMPLEMENTED, (NULL),
("invalid video buffer received"));
- data->ret = GST_FLOW_ERROR;
- return;
+ return GST_FLOW_ERROR;
}
}
-static void
-upload_transform (GstD3D11Device * device, UploadTransformData * data)
+static GstFlowReturn
+upload_transform (GstD3D11BaseFilter * filter, GstBuffer * inbuf,
+ GstBuffer * outbuf)
{
GstVideoFrame in_frame, out_frame;
- GstD3D11BaseFilter *filter = data->filter;
gint i;
+ GstFlowReturn ret = GST_FLOW_OK;
- if (!gst_video_frame_map (&in_frame, &filter->in_info, data->inbuf,
+ if (!gst_video_frame_map (&in_frame, &filter->in_info, inbuf,
GST_MAP_READ | GST_VIDEO_FRAME_MAP_FLAG_NO_REF))
goto invalid_buffer;
- if (!gst_video_frame_map (&out_frame, &filter->out_info, data->outbuf,
+ if (!gst_video_frame_map (&out_frame, &filter->out_info, outbuf,
GST_MAP_WRITE | GST_VIDEO_FRAME_MAP_FLAG_NO_REF)) {
gst_video_frame_unmap (&in_frame);
goto invalid_buffer;
for (i = 0; i < GST_VIDEO_FRAME_N_PLANES (&in_frame); i++) {
if (!gst_video_frame_copy_plane (&out_frame, &in_frame, i)) {
GST_ERROR_OBJECT (filter, "Couldn't copy %dth plane", i);
- data->ret = GST_FLOW_ERROR;
- return;
+ ret = GST_FLOW_ERROR;
+ break;
}
}
gst_video_frame_unmap (&out_frame);
gst_video_frame_unmap (&in_frame);
- data->ret = GST_FLOW_OK;
- return;
+ return ret;
/* ERRORS */
invalid_buffer:
{
GST_ELEMENT_WARNING (filter, CORE, NOT_IMPLEMENTED, (NULL),
("invalid video buffer received"));
- data->ret = GST_FLOW_ERROR;
- return;
+ return GST_FLOW_ERROR;
}
}
GstD3D11BaseFilter *filter = GST_D3D11_BASE_FILTER (trans);
GstMemory *mem;
GstD3D11Device *device;
- UploadTransformData data;
- gboolean to_dynamic = FALSE;
mem = gst_buffer_peek_memory (outbuf, 0);
if (gst_is_d3d11_memory (mem)) {
GstD3D11Memory *dmem = (GstD3D11Memory *) mem;
device = dmem->device;
- if (dmem->desc.Usage == D3D11_USAGE_DYNAMIC)
- to_dynamic = TRUE;
- } else {
- device = filter->device;
- }
-
- data.filter = filter;
- data.inbuf = inbuf;
- data.outbuf = outbuf;
- data.ret = GST_FLOW_OK;
-
- if (to_dynamic) {
- gst_d3d11_device_thread_add (device,
- (GstD3D11DeviceThreadFunc) upload_transform_dynamic, &data);
- } else {
- gst_d3d11_device_thread_add (device,
- (GstD3D11DeviceThreadFunc) upload_transform, &data);
+ if (dmem->desc.Usage == D3D11_USAGE_DYNAMIC) {
+ return upload_transform_dynamic (filter, device, inbuf, outbuf);
+ }
}
- return data.ret;
+ return upload_transform (filter, inbuf, outbuf);
}
#define gst_d3d11_window_parent_class parent_class
G_DEFINE_TYPE (GstD3D11Window, gst_d3d11_window, GST_TYPE_OBJECT);
-typedef struct
-{
- GstD3D11Window *window;
- GstVideoRectangle *rect;
- GstBuffer *buffer;
-
- GstFlowReturn ret;
-} FramePresentData;
-
static void gst_d3d11_window_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_d3d11_window_get_property (GObject * object, guint prop_id,
static void gst_d3d11_window_dispose (GObject * object);
static void gst_d3d11_window_finalize (GObject * object);
static gpointer gst_d3d11_window_thread_func (gpointer data);
-static gboolean _create_window (GstD3D11Window * self);
-static void _open_window (GstD3D11Window * self);
-static void _close_window (GstD3D11Window * self);
+static gboolean gst_d3d11_window_create_internal_window (GstD3D11Window * self);
+static void gst_d3d11_window_close_internal_window (GstD3D11Window * self);
static void release_external_win_id (GstD3D11Window * self);
-static void _present_on_device_thread (GstD3D11Device * device,
- FramePresentData * data);
+static GstFlowReturn gst_d3d111_window_present (GstD3D11Window * self,
+ GstBuffer * buffer);
static void
gst_d3d11_window_class_init (GstD3D11WindowClass * klass)
}
if (self->device) {
- gst_d3d11_device_thread_add (self->device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_window_release_resources, self);
+ gst_d3d11_window_release_resources (self->device, self);
}
if (self->converter) {
GST_DEBUG_OBJECT (self, "Enter loop");
g_main_context_push_thread_default (self->main_context);
- self->created = _create_window (self);
+ self->created = gst_d3d11_window_create_internal_window (self);
source = g_idle_source_new ();
g_source_set_callback (source, (GSourceFunc) running_cb, self, NULL);
g_source_attach (source, self->main_context);
g_source_unref (source);
- if (self->created)
- _open_window (self);
-
g_main_loop_run (self->loop);
- if (self->created)
- _close_window (self);
+ gst_d3d11_window_close_internal_window (self);
g_main_context_pop_thread_default (self->main_context);
}
static void
-_open_window (GstD3D11Window * self)
-{
- self->msg_io_channel = g_io_channel_win32_new_messages (0);
- self->msg_source = g_io_create_watch (self->msg_io_channel, G_IO_IN);
- g_source_set_callback (self->msg_source, (GSourceFunc) msg_cb, self, NULL);
- g_source_attach (self->msg_source, self->main_context);
-}
-
-static void
-_close_window (GstD3D11Window * self)
+gst_d3d11_window_close_internal_window (GstD3D11Window * self)
{
if (self->internal_win_id) {
RemoveProp (self->internal_win_id, D3D11_WINDOW_PROP_NAME);
}
static gboolean
-_create_window (GstD3D11Window * self)
+gst_d3d11_window_create_internal_window (GstD3D11Window * self)
{
WNDCLASSEX wc;
ATOM atom = 0;
GST_LOG_OBJECT (self,
"Created a internal d3d11 window %p", self->internal_win_id);
+ self->msg_io_channel =
+ g_io_channel_win32_new_messages ((guintptr) self->internal_win_id);
+ self->msg_source = g_io_create_watch (self->msg_io_channel, G_IO_IN);
+ g_source_set_callback (self->msg_source, (GSourceFunc) msg_cb, self, NULL);
+ g_source_attach (self->msg_source, self->main_context);
+
return TRUE;
}
static void
-gst_d3d11_window_on_resize (GstD3D11Device * device, GstD3D11Window * window)
+gst_d3d11_window_on_resize (GstD3D11Window * window, gboolean redraw)
{
HRESULT hr;
ID3D11Device *d3d11_dev;
guint width, height;
D3D11_TEXTURE2D_DESC desc;
DXGI_SWAP_CHAIN_DESC swap_desc;
- ID3D11Texture2D *backbuffer;
+ ID3D11Texture2D *backbuffer = NULL;
+ gst_d3d11_device_lock (window->device);
if (!window->swap_chain)
- return;
+ goto done;
- d3d11_dev = gst_d3d11_device_get_device_handle (device);
+ d3d11_dev = gst_d3d11_device_get_device_handle (window->device);
if (window->rtv) {
ID3D11RenderTargetView_Release (window->rtv);
window->rtv = NULL;
}
+ window->pending_resize = FALSE;
+
/* Set zero width and height here. dxgi will decide client area by itself */
IDXGISwapChain_GetDesc (window->swap_chain, &swap_desc);
hr = IDXGISwapChain_ResizeBuffers (window->swap_chain,
0, 0, 0, DXGI_FORMAT_UNKNOWN, swap_desc.Flags);
if (!gst_d3d11_result (hr)) {
GST_ERROR_OBJECT (window, "Couldn't resize buffers, hr: 0x%x", (guint) hr);
- return;
+ goto done;
}
hr = IDXGISwapChain_GetBuffer (window->swap_chain,
if (!gst_d3d11_result (hr)) {
GST_ERROR_OBJECT (window,
"Cannot get backbuffer from swapchain, hr: 0x%x", (guint) hr);
- return;
+ goto done;
}
ID3D11Texture2D_GetDesc (backbuffer, &desc);
goto done;
}
- if (window->cached_buffer) {
- FramePresentData present_data = { 0, };
-
- present_data.window = window;
- present_data.rect = &window->rect;
- present_data.buffer = window->cached_buffer;
- GST_DEBUG_OBJECT (window, "redraw cached buffer");
-
- _present_on_device_thread (window->device, &present_data);
- }
+ if (redraw)
+ gst_d3d111_window_present (window, NULL);
done:
- ID3D11Texture2D_Release (backbuffer);
-}
+ if (backbuffer)
+ ID3D11Texture2D_Release (backbuffer);
-static void
-gst_d3d11_window_on_size (GstD3D11Window * self,
- HWND hWnd, WPARAM wParam, LPARAM lParam)
-{
- gst_d3d11_device_thread_add_full (self->device, G_PRIORITY_HIGH,
- (GstD3D11DeviceThreadFunc) gst_d3d11_window_on_resize, self, NULL);
+ gst_d3d11_device_unlock (window->device);
}
static void
{
switch (uMsg) {
case WM_SIZE:
- gst_d3d11_window_on_size (self, hWnd, wParam, lParam);
+ gst_d3d11_window_on_resize (self, TRUE);
break;
case WM_CLOSE:
if (self->internal_win_id) {
ShowWindow (self->internal_win_id, SW_HIDE);
- _close_window (self);
+ gst_d3d11_window_close_internal_window (self);
}
break;
case WM_KEYDOWN:
gst_d3d11_window_handle_window_proc (self, hWnd, uMsg, wParam, lParam);
}
+ if (uMsg == WM_SIZE)
+ return 0;
+
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
}
#endif
-typedef struct
-{
- GstD3D11Window *self;
- HWND hwnd;
- IDXGISwapChain *swap_chain;
-} MakeWindowAssociationData;
-
static void
-gst_d3d11_window_disable_alt_enter (GstD3D11Device * device,
- MakeWindowAssociationData * data)
+gst_d3d11_window_disable_alt_enter (GstD3D11Window * window,
+ IDXGISwapChain * swap_chain, HWND hwnd)
{
IDXGIFactory1 *factory = NULL;
HRESULT hr;
- hr = IDXGISwapChain_GetParent (data->swap_chain, &IID_IDXGIFactory1,
+ hr = IDXGISwapChain_GetParent (swap_chain, &IID_IDXGIFactory1,
(void **) &factory);
if (!gst_d3d11_result (hr) || !factory) {
- GST_WARNING_OBJECT (data->self,
+ GST_WARNING_OBJECT (window,
"Cannot get parent dxgi factory for swapchain %p, hr: 0x%x",
- data->swap_chain, (guint) hr);
+ swap_chain, (guint) hr);
return;
}
hr = IDXGIFactory1_MakeWindowAssociation (factory,
- data->hwnd, DXGI_MWA_NO_ALT_ENTER);
+ hwnd, DXGI_MWA_NO_ALT_ENTER);
if (!gst_d3d11_result (hr)) {
- GST_WARNING_OBJECT (data->self,
+ GST_WARNING_OBJECT (window,
"MakeWindowAssociation failure, hr: 0x%x", (guint) hr);
}
{
DXGI_SWAP_CHAIN_DESC desc = { 0, };
GstCaps *render_caps;
- MakeWindowAssociationData mwa_data = { 0, };
UINT swapchain_flags = 0;
DXGI_SWAP_EFFECT swap_effect = DXGI_SWAP_EFFECT_DISCARD;
#if (DXGI_HEADER_VERSION >= 5)
#endif
if (window->swap_chain) {
- gst_d3d11_device_thread_add (window->device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_window_release_resources, window);
+ gst_d3d11_device_lock (window->device);
+ gst_d3d11_window_release_resources (window->device, window);
+ gst_d3d11_device_unlock (window->device);
}
window->aspect_ratio_n = aspect_ratio_n;
}
/* disable alt+enter here. It should be manually handled */
- mwa_data.self = window;
- mwa_data.swap_chain = window->swap_chain;
- mwa_data.hwnd = desc.OutputWindow;
- gst_d3d11_device_thread_add (window->device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_window_disable_alt_enter, &mwa_data);
+ gst_d3d11_device_lock (window->device);
+ gst_d3d11_window_disable_alt_enter (window,
+ window->swap_chain, desc.OutputWindow);
+ gst_d3d11_device_unlock (window->device);
#if (DXGI_HEADER_VERSION >= 5)
if (swapchain4_available) {
}
#endif
- gst_d3d11_device_thread_add (window->device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_window_on_resize, window);
+ gst_d3d11_window_on_resize (window, FALSE);
if (!window->rtv) {
- gst_d3d11_device_thread_add (window->device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_window_release_resources, window);
+ gst_d3d11_window_release_resources (window->device, window);
GST_ERROR_OBJECT (window, "Failed to setup internal resources");
g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED,
"Failed to setup internal resources");
/* TODO: resize window and view */
}
-void
-gst_d3d11_window_get_surface_dimensions (GstD3D11Window * window,
- guint * width, guint * height)
+static GstFlowReturn
+gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer)
{
- g_return_if_fail (GST_IS_D3D11_WINDOW (window));
-
- if (width)
- *width = window->surface_width;
- if (height)
- *height = window->surface_height;
-}
-
-static void
-_present_on_device_thread (GstD3D11Device * device, FramePresentData * data)
-{
- GstD3D11Window *self = data->window;
- ID3D11DeviceContext *device_context;
HRESULT hr;
- UINT present_flags = DXGI_PRESENT_DO_NOT_WAIT;
+ UINT present_flags = 0;
- device_context = gst_d3d11_device_get_device_context_handle (device);
- gst_buffer_replace (&self->cached_buffer, data->buffer);
+ if (buffer) {
+ gst_buffer_replace (&self->cached_buffer, buffer);
+ }
if (self->cached_buffer) {
ID3D11ShaderResourceView *srv[GST_VIDEO_MAX_PLANES];
gst_d3d11_color_converter_update_rect (self->converter, &rect);
gst_d3d11_color_converter_convert (self->converter, srv, &self->rtv);
- }
+
#if (DXGI_HEADER_VERSION >= 5)
- if (self->allow_tearing) {
- present_flags |= DXGI_PRESENT_ALLOW_TEARING;
- }
+ if (self->allow_tearing) {
+ present_flags |= DXGI_PRESENT_ALLOW_TEARING;
+ }
#endif
- hr = IDXGISwapChain_Present (self->swap_chain, 0, present_flags);
+ hr = IDXGISwapChain_Present (self->swap_chain, 0, present_flags);
- if (!gst_d3d11_result (hr)) {
- GST_WARNING_OBJECT (self, "Direct3D cannot present texture, hr: 0x%x",
- (guint) hr);
+ if (!gst_d3d11_result (hr)) {
+ GST_WARNING_OBJECT (self, "Direct3D cannot present texture, hr: 0x%x",
+ (guint) hr);
+ }
}
- data->ret = GST_FLOW_OK;
+ return GST_FLOW_OK;
}
GstFlowReturn
gst_d3d11_window_render (GstD3D11Window * window, GstBuffer * buffer,
GstVideoRectangle * rect)
{
- FramePresentData data;
GstMemory *mem;
+ GstFlowReturn ret;
g_return_val_if_fail (GST_IS_D3D11_WINDOW (window), GST_FLOW_ERROR);
g_return_val_if_fail (rect != NULL, GST_FLOW_ERROR);
GST_OBJECT_LOCK (window);
if (window->pending_resize) {
- gst_d3d11_device_thread_add (window->device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_window_on_resize, window);
- window->pending_resize = FALSE;
+ gst_d3d11_window_on_resize (window, FALSE);
}
GST_OBJECT_UNLOCK (window);
- data.window = window;
- data.rect = rect;
- data.buffer = buffer;
- data.ret = GST_FLOW_OK;
-
- gst_d3d11_device_thread_add (window->device,
- (GstD3D11DeviceThreadFunc) _present_on_device_thread, &data);
+ gst_d3d11_device_lock (window->device);
+ ret = gst_d3d111_window_present (window, buffer);
+ gst_d3d11_device_unlock (window->device);
- return data.ret;
-}
-
-static void
-gst_d3d11_window_flush_internal (GstD3D11Device * device,
- GstD3D11Window * window)
-{
- gst_clear_buffer (&window->cached_buffer);
+ return ret;
}
gboolean
{
g_return_val_if_fail (GST_IS_D3D11_WINDOW (window), FALSE);
- gst_d3d11_device_thread_add (window->device,
- (GstD3D11DeviceThreadFunc) gst_d3d11_window_flush_internal, window);
+ gst_clear_buffer (&window->cached_buffer);
return TRUE;
}
gint x, gint y,
gint width, gint height);
-void gst_d3d11_window_get_surface_dimensions (GstD3D11Window * window,
- guint * width,
- guint * height);
-
gboolean gst_d3d11_window_prepare (GstD3D11Window * window,
guint width,
guint height,