diff options
author | Jan Schmidt <thaytan@mad.scientist.com> | 2005-02-15 14:12:11 +0000 |
---|---|---|
committer | Jan Schmidt <thaytan@mad.scientist.com> | 2005-02-15 14:12:11 +0000 |
commit | ec937dfcea2f2ce6c15b2d42a0b347fbdb9fda4c (patch) | |
tree | 9170ceabf6c38451429ad8aedb30ed5362bdc137 | |
parent | 1636a1c8148eaab187fac6dbff23781e9d9fa651 (diff) | |
download | gstreamer-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-- | ChangeLog | 16 | ||||
-rw-r--r-- | sys/ximage/ximagesink.c | 104 | ||||
-rw-r--r-- | sys/ximage/ximagesink.h | 3 | ||||
-rw-r--r-- | sys/xvimage/xvimagesink.c | 92 | ||||
-rw-r--r-- | sys/xvimage/xvimagesink.h | 3 |
5 files changed, 175 insertions, 43 deletions
@@ -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 { |