mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +00:00
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:
parent
1636a1c814
commit
ec937dfcea
5 changed files with 175 additions and 43 deletions
16
ChangeLog
16
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>
|
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):
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue