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.
This commit is contained in:
Jan Schmidt 2005-02-15 14:12:11 +00:00
parent 1636a1c814
commit ec937dfcea
5 changed files with 175 additions and 43 deletions

View file

@ -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> 2005-02-15 Tim-Philipp Müller <tim at centricular dot net>
* gst/speed/demo-mp3.c: (time_tick_cb), (main): * gst/speed/demo-mp3.c: (time_tick_cb), (main):

View file

@ -48,6 +48,7 @@ MotifWmHints, MwmHints;
static void gst_ximagesink_buffer_free (GstBuffer * buffer); static void gst_ximagesink_buffer_free (GstBuffer * buffer);
static void gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink, static void gst_ximagesink_ximage_destroy (GstXImageSink * ximagesink,
GstXImage * ximage); GstXImage * ximage);
static void gst_ximagesink_send_pending_navigation (GstXImageSink * ximagesink);
/* ElementFactory information */ /* ElementFactory information */
static GstElementDetails gst_ximagesink_details = static GstElementDetails gst_ximagesink_details =
@ -1156,6 +1157,7 @@ gst_ximagesink_chain (GstPad * pad, GstData * data)
gst_buffer_unref (buf); gst_buffer_unref (buf);
gst_ximagesink_handle_xevents (ximagesink, pad); gst_ximagesink_handle_xevents (ximagesink, pad);
gst_ximagesink_send_pending_navigation (ximagesink);
g_mutex_unlock (ximagesink->stream_lock); g_mutex_unlock (ximagesink->stream_lock);
} }
@ -1257,40 +1259,78 @@ gst_ximagesink_interface_init (GstImplementsInterfaceClass * klass)
klass->supported = gst_ximagesink_interface_supported; 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 static void
gst_ximagesink_navigation_send_event (GstNavigation * navigation, gst_ximagesink_navigation_send_event (GstNavigation * navigation,
GstStructure * structure) GstStructure * structure)
{ {
GstXImageSink *ximagesink = GST_XIMAGESINK (navigation); GstXImageSink *ximagesink = GST_XIMAGESINK (navigation);
GstEvent *event; 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 = gst_event_new (GST_EVENT_NAVIGATION);
event->event_data.structure.structure = structure; event->event_data.structure.structure = structure;
/* We are not converting the pointer coordinates as there's no hardware g_mutex_lock (ximagesink->nav_lock);
scaling done here. The only possible scaling is done by videoscale and ximagesink->pend_nav_events =
videoscale will have to catch those events and tranform the coordinates g_slist_prepend (ximagesink->pend_nav_events, event);
to match the applied scaling. So here we just add the offset if the image g_mutex_unlock (ximagesink->nav_lock);
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);
} }
static void static void
@ -1561,6 +1601,19 @@ gst_ximagesink_finalize (GObject * object)
g_mutex_free (ximagesink->pool_lock); g_mutex_free (ximagesink->pool_lock);
ximagesink->pool_lock = NULL; 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); G_OBJECT_CLASS (parent_class)->finalize (object);
} }
@ -1605,6 +1658,9 @@ gst_ximagesink_init (GstXImageSink * ximagesink)
ximagesink->par = NULL; 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_THREAD_SUGGESTED);
GST_FLAG_SET (ximagesink, GST_ELEMENT_EVENT_AWARE); GST_FLAG_SET (ximagesink, GST_ELEMENT_EVENT_AWARE);
} }

View file

@ -132,6 +132,9 @@ struct _GstXImageSink {
gboolean synchronous; gboolean synchronous;
gboolean sw_scaling_failed; gboolean sw_scaling_failed;
GMutex *nav_lock;
GSList *pend_nav_events;
}; };
struct _GstXImageSinkClass { struct _GstXImageSinkClass {

View file

@ -49,7 +49,8 @@ MotifWmHints, MwmHints;
static void gst_xvimagesink_buffer_free (GstBuffer * buffer); static void gst_xvimagesink_buffer_free (GstBuffer * buffer);
static void gst_xvimagesink_xvimage_destroy (GstXvImageSink * xvimagesink, static void gst_xvimagesink_xvimage_destroy (GstXvImageSink * xvimagesink,
GstXvImage * xvimage); GstXvImage * xvimage);
static void
gst_xvimagesink_send_pending_navigation (GstXvImageSink * xvimagesink);
/* ElementFactory information */ /* ElementFactory information */
static GstElementDetails gst_xvimagesink_details = static GstElementDetails gst_xvimagesink_details =
@ -1466,6 +1467,7 @@ gst_xvimagesink_chain (GstPad * pad, GstData * data)
gst_buffer_unref (buf); gst_buffer_unref (buf);
gst_xvimagesink_handle_xevents (xvimagesink, pad); gst_xvimagesink_handle_xevents (xvimagesink, pad);
gst_xvimagesink_send_pending_navigation (xvimagesink);
g_mutex_unlock (xvimagesink->stream_lock); g_mutex_unlock (xvimagesink->stream_lock);
} }
@ -1571,34 +1573,70 @@ gst_xvimagesink_interface_init (GstImplementsInterfaceClass * klass)
klass->supported = gst_xvimagesink_interface_supported; 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 static void
gst_xvimagesink_navigation_send_event (GstNavigation * navigation, gst_xvimagesink_navigation_send_event (GstNavigation * navigation,
GstStructure * structure) GstStructure * structure)
{ {
GstXvImageSink *xvimagesink = GST_XVIMAGESINK (navigation); GstXvImageSink *xvimagesink = GST_XVIMAGESINK (navigation);
GstEvent *event; GstEvent *event;
double x, y;
if (!GST_PAD_PEER (GST_VIDEOSINK_PAD (xvimagesink)))
return;
event = gst_event_new (GST_EVENT_NAVIGATION); event = gst_event_new (GST_EVENT_NAVIGATION);
event->event_data.structure.structure = structure; event->event_data.structure.structure = structure;
/* Converting pointer coordinates to the non scaled geometry */ g_mutex_lock (xvimagesink->nav_lock);
if (gst_structure_get_double (structure, "pointer_x", &x)) { xvimagesink->pend_nav_events =
x *= xvimagesink->video_width; g_slist_prepend (xvimagesink->pend_nav_events, event);
x /= xvimagesink->xwindow->width; g_mutex_unlock (xvimagesink->nav_lock);
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);
} }
static void static void
@ -1951,6 +1989,19 @@ gst_xvimagesink_finalize (GObject * object)
g_mutex_free (xvimagesink->pool_lock); g_mutex_free (xvimagesink->pool_lock);
xvimagesink->pool_lock = NULL; 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); 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_THREAD_SUGGESTED);
GST_FLAG_SET (xvimagesink, GST_ELEMENT_EVENT_AWARE); GST_FLAG_SET (xvimagesink, GST_ELEMENT_EVENT_AWARE);
xvimagesink->nav_lock = g_mutex_new ();
xvimagesink->pend_nav_events = NULL;
} }
static void static void

View file

@ -154,6 +154,9 @@ struct _GstXvImageSink {
GSList *image_pool; GSList *image_pool;
gboolean synchronous; gboolean synchronous;
GMutex *nav_lock;
GSList *pend_nav_events;
}; };
struct _GstXvImageSinkClass { struct _GstXvImageSinkClass {