diff --git a/ChangeLog b/ChangeLog index 8667337786..c74755a4d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-02-16 Jan Schmidt + + * 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 * gst/speed/demo-mp3.c: (time_tick_cb), (main): diff --git a/sys/ximage/ximagesink.c b/sys/ximage/ximagesink.c index 05d5213223..20ae85d2df 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 dcbc82ce15..0f994ba8e4 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 2154fb2eb2..dcc9d2e985 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 f04f28276b..56025a2884 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 {