/* For drawing on user texture */
gboolean drawing;
GstBuffer *current_buffer;
- GRecMutex draw_lock;
+ GRecMutex lock;
gchar *title;
};
+#define GST_D3D11_VIDEO_SINK_GET_LOCK(d) (&(GST_D3D11_VIDEO_SINK_CAST(d)->lock))
+#define GST_D3D11_VIDEO_SINK_LOCK(d) G_STMT_START { \
+ GST_TRACE_OBJECT (d, "Locking from thread %p", g_thread_self()); \
+ g_rec_mutex_lock (GST_D3D11_VIDEO_SINK_GET_LOCK (d)); \
+ GST_TRACE_OBJECT (d, "Locked from thread %p", g_thread_self()); \
+ } G_STMT_END
+
+#define GST_D3D11_VIDEO_SINK_UNLOCK(d) G_STMT_START { \
+ GST_TRACE_OBJECT (d, "Unlocking from thread %p", g_thread_self()); \
+ g_rec_mutex_unlock (GST_D3D11_VIDEO_SINK_GET_LOCK (d)); \
+ } G_STMT_END
+
static void gst_d3d11_videosink_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_d3d11_videosink_get_property (GObject * object, guint prop_id,
self->fullscreen = DEFAULT_FULLSCREEN;
self->draw_on_shared_texture = DEFAULT_DRAW_ON_SHARED_TEXTURE;
- g_rec_mutex_init (&self->draw_lock);
+ g_rec_mutex_init (&self->lock);
}
static void
{
GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (object);
- GST_OBJECT_LOCK (self);
+ GST_D3D11_VIDEO_SINK_LOCK (self);
switch (prop_id) {
case PROP_ADAPTER:
self->adapter = g_value_get_int (value);
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
- GST_OBJECT_UNLOCK (self);
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
}
static void
{
GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (object);
+ GST_D3D11_VIDEO_SINK_LOCK (self);
switch (prop_id) {
case PROP_ADAPTER:
g_value_set_int (value, self->adapter);
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
}
static void
{
GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (object);
- g_rec_mutex_clear (&self->draw_lock);
+ g_rec_mutex_clear (&self->lock);
g_free (self->title);
G_OBJECT_CLASS (parent_class)->finalize (object);
self->caps_updated = FALSE;
- if (!gst_d3d11_video_sink_prepare_window (self))
- goto no_window;
+ GST_D3D11_VIDEO_SINK_LOCK (self);
+ if (!gst_d3d11_video_sink_prepare_window (self)) {
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
+
+ GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, (nullptr),
+ ("Failed to open window."));
+
+ return FALSE;
+ }
- if (!gst_video_info_from_caps (&self->info, caps))
- goto invalid_format;
+ if (!gst_video_info_from_caps (&self->info, caps)) {
+ GST_DEBUG_OBJECT (self,
+ "Could not locate image format from caps %" GST_PTR_FORMAT, caps);
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
+ return FALSE;
+ }
video_width = GST_VIDEO_INFO_WIDTH (&self->info);
video_height = GST_VIDEO_INFO_HEIGHT (&self->info);
* convert video width and height to a display width and height
* using wd / hd = wv / hv * PARv / PARd */
- /* TODO: Get display PAR */
-
if (!gst_video_calculate_display_ratio (&num, &den, video_width,
- video_height, video_par_n, video_par_d, display_par_n, display_par_d))
- goto no_disp_ratio;
+ video_height, video_par_n, video_par_d, display_par_n,
+ display_par_d)) {
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
+
+ GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, (nullptr),
+ ("Error calculating the output display ratio of the video."));
+ return FALSE;
+ }
GST_DEBUG_OBJECT (self,
"video width/height: %dx%d, calculated display ratio: %d/%d format: %s",
self->video_width = video_width;
self->video_height = video_height;
- if (GST_VIDEO_SINK_WIDTH (self) <= 0 || GST_VIDEO_SINK_HEIGHT (self) <= 0)
- goto no_display_size;
+ if (GST_VIDEO_SINK_WIDTH (self) <= 0 || GST_VIDEO_SINK_HEIGHT (self) <= 0) {
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
+
+ GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, (nullptr),
+ ("Error calculating the output display ratio of the video."));
+ return FALSE;
+ }
- GST_OBJECT_LOCK (self);
if (self->pending_render_rect) {
GstVideoRectangle rect = self->render_rect;
self->pending_render_rect = FALSE;
- GST_OBJECT_UNLOCK (self);
-
gst_d3d11_window_set_render_rectangle (self->window, &rect);
- } else {
- GST_OBJECT_UNLOCK (self);
}
if (!gst_d3d11_window_prepare (self->window, GST_VIDEO_SINK_WIDTH (self),
GST_VIDEO_SINK_HEIGHT (self), caps, &error)) {
GstMessage *error_msg;
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
+
GST_ERROR_OBJECT (self, "cannot create swapchain");
error_msg = gst_message_new_error (GST_OBJECT_CAST (self),
error, "Failed to prepare d3d11window");
g_clear_pointer (&self->title, g_free);
}
- return TRUE;
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
- /* ERRORS */
-invalid_format:
- {
- GST_DEBUG_OBJECT (self,
- "Could not locate image format from caps %" GST_PTR_FORMAT, caps);
- return FALSE;
- }
-no_window:
- {
- GST_ELEMENT_ERROR (self, RESOURCE, NOT_FOUND, (NULL),
- ("Failed to open window."));
- return FALSE;
- }
-no_disp_ratio:
- {
- GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, (NULL),
- ("Error calculating the output display ratio of the video."));
- return FALSE;
- }
-no_display_size:
- {
- GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, (NULL),
- ("Error calculating the output display ratio of the video."));
- return FALSE;
- }
+ return TRUE;
}
static void
return TRUE;
}
+/* called with lock */
static gboolean
gst_d3d11_video_sink_prepare_window (GstD3D11VideoSink * self)
{
return FALSE;
}
- GST_OBJECT_LOCK (self);
g_object_set (self->window,
"force-aspect-ratio", self->force_aspect_ratio,
"fullscreen-toggle-mode", self->fullscreen_toggle_mode,
"fullscreen", self->fullscreen,
"enable-navigation-events", self->enable_navigation_events, NULL);
- GST_OBJECT_UNLOCK (self);
g_signal_connect (self->window, "key-event",
G_CALLBACK (gst_d3d11_video_sink_key_event), self);
GST_DEBUG_OBJECT (self, "Stop");
+ GST_D3D11_VIDEO_SINK_LOCK (self);
if (self->window)
gst_d3d11_window_unprepare (self->window);
- gst_clear_object (&self->device);
gst_clear_object (&self->window);
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
+
+ gst_clear_object (&self->device);
g_clear_pointer (&self->title, g_free);
{
GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink);
+ GST_D3D11_VIDEO_SINK_LOCK (self);
if (self->window)
gst_d3d11_window_unlock (self->window);
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
return TRUE;
}
{
GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (sink);
+ GST_D3D11_VIDEO_SINK_LOCK (self);
if (self->window)
gst_d3d11_window_unlock_stop (self->window);
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
return TRUE;
}
title_string = std::string (title);
}
+ GST_D3D11_VIDEO_SINK_LOCK (self);
if (self->window) {
gst_d3d11_window_set_title (self->window, title_string.c_str ());
} else {
g_free (self->title);
self->title = g_strdup (title_string.c_str ());
}
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
g_free (title);
}
gst_d3d11_window_show (self->window);
if (self->draw_on_shared_texture) {
- g_rec_mutex_lock (&self->draw_lock);
+ GST_D3D11_VIDEO_SINK_LOCK (self);
self->current_buffer = buf;
self->drawing = TRUE;
GST_LOG_OBJECT (self, "End drawing");
self->drawing = FALSE;
self->current_buffer = nullptr;
- g_rec_mutex_unlock (&self->draw_lock);
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
} else {
ret = gst_d3d11_window_render (self->window, buf);
}
GST_DEBUG_OBJECT (self,
"render rect x: %d, y: %d, width: %d, height %d", x, y, width, height);
- GST_OBJECT_LOCK (self);
+ GST_D3D11_VIDEO_SINK_LOCK (self);
if (self->window) {
GstVideoRectangle rect;
rect.h = height;
self->render_rect = rect;
- GST_OBJECT_UNLOCK (self);
gst_d3d11_window_set_render_rectangle (self->window, &rect);
} else {
self->render_rect.w = width;
self->render_rect.h = height;
self->pending_render_rect = TRUE;
- GST_OBJECT_UNLOCK (self);
}
+
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
}
static void
{
GstD3D11VideoSink *self = GST_D3D11_VIDEO_SINK (overlay);
- if (self->window && self->window->swap_chain) {
- gst_d3d11_window_render (self->window, NULL);
- }
+ GST_D3D11_VIDEO_SINK_LOCK (self);
+ if (self->window && self->window->swap_chain)
+ gst_d3d11_window_render (self->window, nullptr);
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
}
static void
return FALSE;
}
- g_rec_mutex_lock (&self->draw_lock);
+ GST_D3D11_VIDEO_SINK_LOCK (self);
if (!self->drawing || !self->current_buffer) {
GST_WARNING_OBJECT (self, "Nothing to draw");
- g_rec_mutex_unlock (&self->draw_lock);
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
return FALSE;
}
ret = gst_d3d11_window_render_on_shared_handle (self->window,
self->current_buffer, shared_handle, texture_misc_flags, acquire_key,
release_key);
- g_rec_mutex_unlock (&self->draw_lock);
+ GST_D3D11_VIDEO_SINK_UNLOCK (self);
return ret == GST_FLOW_OK;
}