videomixer2: Fix race condition where a src setcaps is ignored

If both pads receive data at the same time, they will both get their
sink_setcaps called which will call the src_setcaps, but there is
a race condition where the second one might not be called.
Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=683842
This commit is contained in:
Youness Alaoui 2012-09-13 00:10:00 +00:00 committed by Sebastian Dröge
parent 5742352e10
commit 13328bc129
2 changed files with 14 additions and 0 deletions

View file

@ -102,6 +102,12 @@ GST_DEBUG_CATEGORY_STATIC (gst_videomixer2_debug);
(g_mutex_lock(GST_VIDEO_MIXER2_GET_LOCK (mix))) (g_mutex_lock(GST_VIDEO_MIXER2_GET_LOCK (mix)))
#define GST_VIDEO_MIXER2_UNLOCK(mix) \ #define GST_VIDEO_MIXER2_UNLOCK(mix) \
(g_mutex_unlock(GST_VIDEO_MIXER2_GET_LOCK (mix))) (g_mutex_unlock(GST_VIDEO_MIXER2_GET_LOCK (mix)))
#define GST_VIDEO_MIXER2_GET_SETCAPS_LOCK(mix) \
(&GST_VIDEO_MIXER2(mix)->setcaps_lock)
#define GST_VIDEO_MIXER2_SETCAPS_LOCK(mix) \
(g_mutex_lock(GST_VIDEO_MIXER2_GET_SETCAPS_LOCK (mix)))
#define GST_VIDEO_MIXER2_SETCAPS_UNLOCK(mix) \
(g_mutex_unlock(GST_VIDEO_MIXER2_GET_SETCAPS_LOCK (mix)))
#define FORMATS " { AYUV, BGRA, ARGB, RGBA, ABGR, Y444, Y42B, YUY2, UYVY, "\ #define FORMATS " { AYUV, BGRA, ARGB, RGBA, ABGR, Y444, Y42B, YUY2, UYVY, "\
" YVYU, I420, YV12, NV12, NV21, Y41B, RGB, BGR, xRGB, xBGR, "\ " YVYU, I420, YV12, NV12, NV21, Y41B, RGB, BGR, xRGB, xBGR, "\
@ -174,6 +180,7 @@ gst_videomixer2_update_src_caps (GstVideoMixer2 * mix)
gint best_fps_n = -1, best_fps_d = -1; gint best_fps_n = -1, best_fps_d = -1;
gboolean ret = TRUE; gboolean ret = TRUE;
GST_VIDEO_MIXER2_SETCAPS_LOCK (mix);
GST_VIDEO_MIXER2_LOCK (mix); GST_VIDEO_MIXER2_LOCK (mix);
for (l = mix->sinkpads; l; l = l->next) { for (l = mix->sinkpads; l; l = l->next) {
@ -281,6 +288,7 @@ gst_videomixer2_update_src_caps (GstVideoMixer2 * mix)
} }
done: done:
GST_VIDEO_MIXER2_SETCAPS_UNLOCK (mix);
return ret; return ret;
} }
@ -1883,6 +1891,7 @@ gst_videomixer2_finalize (GObject * o)
gst_object_unref (mix->collect); gst_object_unref (mix->collect);
g_mutex_clear (&mix->lock); g_mutex_clear (&mix->lock);
g_mutex_clear (&mix->setcaps_lock);
G_OBJECT_CLASS (parent_class)->finalize (o); G_OBJECT_CLASS (parent_class)->finalize (o);
} }
@ -2023,6 +2032,7 @@ gst_videomixer2_init (GstVideoMixer2 * mix)
(GstCollectPadsClipFunction) gst_videomixer2_sink_clip, mix); (GstCollectPadsClipFunction) gst_videomixer2_sink_clip, mix);
g_mutex_init (&mix->lock); g_mutex_init (&mix->lock);
g_mutex_init (&mix->setcaps_lock);
/* initialize variables */ /* initialize variables */
gst_videomixer2_reset (mix); gst_videomixer2_reset (mix);
} }

View file

@ -76,6 +76,10 @@ struct _GstVideoMixer2
/* Lock to prevent the state to change while blending */ /* Lock to prevent the state to change while blending */
GMutex lock; GMutex lock;
/* Lock to prevent two src setcaps from happening at the same time */
GMutex setcaps_lock;
/* Sink pads using Collect Pads 2*/ /* Sink pads using Collect Pads 2*/
GstCollectPads *collect; GstCollectPads *collect;