summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@mad.scientist.com>2005-02-15 14:12:11 +0000
committerJan Schmidt <thaytan@mad.scientist.com>2005-02-15 14:12:11 +0000
commitec937dfcea2f2ce6c15b2d42a0b347fbdb9fda4c (patch)
tree9170ceabf6c38451429ad8aedb30ed5362bdc137
parent1636a1c8148eaab187fac6dbff23781e9d9fa651 (diff)
downloadgstreamer-plugins-base-ec937dfcea2f2ce6c15b2d42a0b347fbdb9fda4c.tar.gz
sys/: Use a mutex protected list to marshal navigation events into the stream thread from whichever thread sends them.
Original commit message from CVS: * sys/ximage/ximagesink.c: (gst_ximagesink_chain), (gst_ximagesink_send_pending_navigation), (gst_ximagesink_navigation_send_event), (gst_ximagesink_finalize), (gst_ximagesink_init): * sys/ximage/ximagesink.h: * sys/xvimage/xvimagesink.c: (gst_xvimagesink_chain), (gst_xvimagesink_send_pending_navigation), (gst_xvimagesink_navigation_send_event), (gst_xvimagesink_finalize), (gst_xvimagesink_init): * sys/xvimage/xvimagesink.h: Use a mutex protected list to marshal navigation events into the stream thread from whichever thread sends them.
-rw-r--r--ChangeLog16
-rw-r--r--sys/ximage/ximagesink.c104
-rw-r--r--sys/ximage/ximagesink.h3
-rw-r--r--sys/xvimage/xvimagesink.c92
-rw-r--r--sys/xvimage/xvimagesink.h3
5 files changed, 175 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index 866733778..c74755a4d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2005-02-16 Jan Schmidt <thaytan@mad.scientist.com>
+
+ * sys/ximage/ximagesink.c: (gst_ximagesink_chain),
+ (gst_ximagesink_send_pending_navigation),
+ (gst_ximagesink_navigation_send_event), (gst_ximagesink_finalize),
+ (gst_ximagesink_init):
+ * sys/ximage/ximagesink.h:
+ * sys/xvimage/xvimagesink.c: (gst_xvimagesink_chain),
+ (gst_xvimagesink_send_pending_navigation),
+ (gst_xvimagesink_navigation_send_event),
+ (gst_xvimagesink_finalize), (gst_xvimagesink_init):
+ * sys/xvimage/xvimagesink.h:
+ Use a mutex protected list to marshal navigation
+ events into the stream thread from whichever thread
+ sends them.
+
2005-02-15 Tim-Philipp Müller <tim at centricular dot net>
* gst/speed/demo-mp3.c: (time_tick_cb), (main):
diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c
index 05d521322..20ae85d2d 100644
--- a/sys/ximage/ximagesink.c
+++ b/sys/ximage/ximagesink.c
@@ -48,6 +48,7 @@ MotifWmHints, MwmHints;
static void gst_ximagesink_buffer_free (GstBuffer * buffer);
static void gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink,
GstXImage * ximage);
+static void gst_ximagesink_send_pending_navigation (GstXImageSink * ximagesink);
/* ElementFactory information */
static GstElementDetails gst_ximagesink_details =
@@ -1156,6 +1157,7 @@ gst_ximagesink_chain (GstPad * pad, GstData * data)
gst_buffer_unref (buf);
gst_ximagesink_handle_xevents (ximagesink, pad);
+ gst_ximagesink_send_pending_navigation (ximagesink);
g_mutex_unlock (ximagesink->stream_lock);
}
@@ -1257,40 +1259,78 @@ gst_ximagesink_interface_init (GstImplementsInterfaceClass * klass)
klass->supported = gst_ximagesink_interface_supported;
}
+/*
+ * This function is called with the stream-lock held
+ */
+static void
+gst_ximagesink_send_pending_navigation (GstXImageSink * ximagesink)
+{
+ GSList *cur;
+ GSList *pend_events;
+
+ g_mutex_lock (ximagesink->nav_lock);
+ pend_events = ximagesink->pend_nav_events;
+ ximagesink->pend_nav_events = NULL;
+ g_mutex_unlock (ximagesink->nav_lock);
+
+ cur = pend_events;
+ while (cur) {
+ GstEvent *event = cur->data;
+ GstStructure *structure;
+ double x, y;
+ gint x_offset, y_offset;
+
+ if (event) {
+ structure = event->event_data.structure.structure;
+
+ if (!GST_PAD_PEER (GST_VIDEOSINK_PAD (ximagesink))) {
+ gst_event_unref (event);
+ cur = g_slist_next (cur);
+ continue;
+ }
+
+ /* We are not converting the pointer coordinates as there's no hardware
+ scaling done here. The only possible scaling is done by videoscale and
+ videoscale will have to catch those events and tranform the coordinates
+ to match the applied scaling. So here we just add the offset if the image
+ is centered in the window. */
+
+ x_offset = ximagesink->xwindow->width - GST_VIDEOSINK_WIDTH (ximagesink);
+ y_offset =
+ ximagesink->xwindow->height - GST_VIDEOSINK_HEIGHT (ximagesink);
+
+ if (gst_structure_get_double (structure, "pointer_x", &x)) {
+ x -= x_offset / 2;
+ gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
+ }
+ if (gst_structure_get_double (structure, "pointer_y", &y)) {
+ y -= y_offset / 2;
+ gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
+ }
+
+ gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (ximagesink)),
+ event);
+ }
+ cur = g_slist_next (cur);
+ }
+
+ g_slist_free (pend_events);
+}
+
static void
gst_ximagesink_navigation_send_event (GstNavigation * navigation,
GstStructure * structure)
{
GstXImageSink *ximagesink = GST_XIMAGESINK (navigation);
GstEvent *event;
- gint x_offset, y_offset;
- double x, y;
-
- if (!GST_PAD_PEER (GST_VIDEOSINK_PAD (ximagesink)))
- return;
event = gst_event_new (GST_EVENT_NAVIGATION);
event->event_data.structure.structure = structure;
- /* We are not converting the pointer coordinates as there's no hardware
- scaling done here. The only possible scaling is done by videoscale and
- videoscale will have to catch those events and tranform the coordinates
- to match the applied scaling. So here we just add the offset if the image
- is centered in the window. */
-
- x_offset = ximagesink->xwindow->width - GST_VIDEOSINK_WIDTH (ximagesink);
- y_offset = ximagesink->xwindow->height - GST_VIDEOSINK_HEIGHT (ximagesink);
-
- if (gst_structure_get_double (structure, "pointer_x", &x)) {
- x -= x_offset / 2;
- gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
- }
- if (gst_structure_get_double (structure, "pointer_y", &y)) {
- y -= y_offset / 2;
- gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
- }
-
- gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (ximagesink)), event);
+ g_mutex_lock (ximagesink->nav_lock);
+ ximagesink->pend_nav_events =
+ g_slist_prepend (ximagesink->pend_nav_events, event);
+ g_mutex_unlock (ximagesink->nav_lock);
}
static void
@@ -1561,6 +1601,19 @@ gst_ximagesink_finalize (GObject * object)
g_mutex_free (ximagesink->pool_lock);
ximagesink->pool_lock = NULL;
}
+ if (ximagesink->nav_lock) {
+ g_mutex_free (ximagesink->nav_lock);
+ ximagesink->nav_lock = NULL;
+ }
+
+ while (ximagesink->pend_nav_events) {
+ GstEvent *event = ximagesink->pend_nav_events->data;
+
+ ximagesink->pend_nav_events =
+ g_slist_delete_link (ximagesink->pend_nav_events,
+ ximagesink->pend_nav_events);
+ gst_event_unref (event);
+ }
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -1605,6 +1658,9 @@ gst_ximagesink_init (GstXImageSink * ximagesink)
ximagesink->par = NULL;
+ ximagesink->nav_lock = g_mutex_new ();
+ ximagesink->pend_nav_events = NULL;
+
GST_FLAG_SET (ximagesink, GST_ELEMENT_THREAD_SUGGESTED);
GST_FLAG_SET (ximagesink, GST_ELEMENT_EVENT_AWARE);
}
diff --git a/sys/ximage/ximagesink.h b/sys/ximage/ximagesink.h
index dcbc82ce1..0f994ba8e 100644
--- a/sys/ximage/ximagesink.h
+++ b/sys/ximage/ximagesink.h
@@ -132,6 +132,9 @@ struct _GstXImageSink {
gboolean synchronous;
gboolean sw_scaling_failed;
+
+ GMutex *nav_lock;
+ GSList *pend_nav_events;
};
struct _GstXImageSinkClass {
diff --git a/sys/xvimage/xvimagesink.c b/sys/xvimage/xvimagesink.c
index 2154fb2eb..dcc9d2e98 100644
--- a/sys/xvimage/xvimagesink.c
+++ b/sys/xvimage/xvimagesink.c
@@ -49,7 +49,8 @@ MotifWmHints, MwmHints;
static void gst_xvimagesink_buffer_free (GstBuffer * buffer);
static void gst_xvimagesink_xvimage_destroy (GstXvImageSink * xvimagesink,
GstXvImage * xvimage);
-
+static void
+gst_xvimagesink_send_pending_navigation (GstXvImageSink * xvimagesink);
/* ElementFactory information */
static GstElementDetails gst_xvimagesink_details =
@@ -1466,6 +1467,7 @@ gst_xvimagesink_chain (GstPad * pad, GstData * data)
gst_buffer_unref (buf);
gst_xvimagesink_handle_xevents (xvimagesink, pad);
+ gst_xvimagesink_send_pending_navigation (xvimagesink);
g_mutex_unlock (xvimagesink->stream_lock);
}
@@ -1571,34 +1573,70 @@ gst_xvimagesink_interface_init (GstImplementsInterfaceClass * klass)
klass->supported = gst_xvimagesink_interface_supported;
}
+/*
+ * This function is called with the stream-lock held
+ */
+static void
+gst_xvimagesink_send_pending_navigation (GstXvImageSink * xvimagesink)
+{
+ GSList *cur;
+ GSList *pend_events;
+
+ g_mutex_lock (xvimagesink->nav_lock);
+ pend_events = xvimagesink->pend_nav_events;
+ xvimagesink->pend_nav_events = NULL;
+ g_mutex_unlock (xvimagesink->nav_lock);
+
+ cur = pend_events;
+ while (cur) {
+ GstEvent *event = cur->data;
+ GstStructure *structure;
+ double x, y;
+
+ if (event) {
+ structure = event->event_data.structure.structure;
+
+ if (!GST_PAD_PEER (GST_VIDEOSINK_PAD (xvimagesink))) {
+ gst_event_unref (event);
+ cur = g_slist_next (cur);
+ continue;
+ }
+
+ /* Converting pointer coordinates to the non scaled geometry */
+ if (gst_structure_get_double (structure, "pointer_x", &x)) {
+ x *= xvimagesink->video_width;
+ x /= xvimagesink->xwindow->width;
+ gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
+ }
+ if (gst_structure_get_double (structure, "pointer_y", &y)) {
+ y *= xvimagesink->video_height;
+ y /= xvimagesink->xwindow->height;
+ gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
+ }
+
+ gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (xvimagesink)),
+ event);
+ }
+ cur = g_slist_next (cur);
+ }
+
+ g_slist_free (pend_events);
+}
+
static void
gst_xvimagesink_navigation_send_event (GstNavigation * navigation,
GstStructure * structure)
{
GstXvImageSink *xvimagesink = GST_XVIMAGESINK (navigation);
GstEvent *event;
- double x, y;
-
- if (!GST_PAD_PEER (GST_VIDEOSINK_PAD (xvimagesink)))
- return;
event = gst_event_new (GST_EVENT_NAVIGATION);
event->event_data.structure.structure = structure;
- /* Converting pointer coordinates to the non scaled geometry */
- if (gst_structure_get_double (structure, "pointer_x", &x)) {
- x *= xvimagesink->video_width;
- x /= xvimagesink->xwindow->width;
- gst_structure_set (structure, "pointer_x", G_TYPE_DOUBLE, x, NULL);
- }
- if (gst_structure_get_double (structure, "pointer_y", &y)) {
- y *= xvimagesink->video_height;
- y /= xvimagesink->xwindow->height;
- gst_structure_set (structure, "pointer_y", G_TYPE_DOUBLE, y, NULL);
- }
-
- gst_pad_send_event (gst_pad_get_peer (GST_VIDEOSINK_PAD (xvimagesink)),
- event);
+ g_mutex_lock (xvimagesink->nav_lock);
+ xvimagesink->pend_nav_events =
+ g_slist_prepend (xvimagesink->pend_nav_events, event);
+ g_mutex_unlock (xvimagesink->nav_lock);
}
static void
@@ -1951,6 +1989,19 @@ gst_xvimagesink_finalize (GObject * object)
g_mutex_free (xvimagesink->pool_lock);
xvimagesink->pool_lock = NULL;
}
+ if (xvimagesink->nav_lock) {
+ g_mutex_free (xvimagesink->nav_lock);
+ xvimagesink->nav_lock = NULL;
+ }
+
+ while (xvimagesink->pend_nav_events) {
+ GstEvent *event = xvimagesink->pend_nav_events->data;
+
+ xvimagesink->pend_nav_events =
+ g_slist_delete_link (xvimagesink->pend_nav_events,
+ xvimagesink->pend_nav_events);
+ gst_event_unref (event);
+ }
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -2001,6 +2052,9 @@ gst_xvimagesink_init (GstXvImageSink * xvimagesink)
GST_FLAG_SET (xvimagesink, GST_ELEMENT_THREAD_SUGGESTED);
GST_FLAG_SET (xvimagesink, GST_ELEMENT_EVENT_AWARE);
+
+ xvimagesink->nav_lock = g_mutex_new ();
+ xvimagesink->pend_nav_events = NULL;
}
static void
diff --git a/sys/xvimage/xvimagesink.h b/sys/xvimage/xvimagesink.h
index f04f28276..56025a288 100644
--- a/sys/xvimage/xvimagesink.h
+++ b/sys/xvimage/xvimagesink.h
@@ -154,6 +154,9 @@ struct _GstXvImageSink {
GSList *image_pool;
gboolean synchronous;
+
+ GMutex *nav_lock;
+ GSList *pend_nav_events;
};
struct _GstXvImageSinkClass {