audiomixer: Avoid race in caps negotiation
authorOlivier CrĂȘte <olivier.crete@collabora.com>
Thu, 22 Jan 2015 00:32:34 +0000 (19:32 -0500)
committerThibault Saunier <tsaunier@gnome.org>
Thu, 29 Jan 2015 09:24:18 +0000 (10:24 +0100)
With the current audiomixer, the input caps need to be the same,
otherwise there is an unavoidable race in the caps negotiation. So
enforce that using capsfilters

https://bugzilla.gnome.org/show_bug.cgi?id=742684

tests/check/elements/audiomixer.c

index bb8c8da..b56a388 100644 (file)
@@ -587,11 +587,12 @@ test_live_seeking_try_audiosrc (const gchar * factory_name)
 /* test failing seeks on live-sources */
 GST_START_TEST (test_live_seeking)
 {
-  GstElement *bin, *src1 =
-      NULL, *src2, *ac1, *ac2, *q1, *q2, *audiomixer, *sink;
+  GstElement *bin, *src1 = NULL, *cf, *src2, *audiomixer, *sink;
+  GstCaps *caps;
   GstBus *bus;
   gboolean res;
   GstPad *srcpad;
+  GstPad *sinkpad;
   gint i;
   GstStateChangeReturn state_res;
   GstStreamConsistency *consist;
@@ -624,32 +625,44 @@ GST_START_TEST (test_live_seeking)
     g_object_set (src1, "num-buffers", 4, "blocksize", 44100, NULL);
   }
 
-  ac1 = gst_element_factory_make ("audioconvert", "ac1");
-  q1 = gst_element_factory_make ("queue", "q1");
-  src2 = gst_element_factory_make ("audiotestsrc", "src2");
-  g_object_set (src2, "wave", 4, NULL); /* silence */
-  ac2 = gst_element_factory_make ("audioconvert", "ac2");
-  q2 = gst_element_factory_make ("queue", "q2");
   audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
+  cf = gst_element_factory_make ("capsfilter", "capsfilter");
   sink = gst_element_factory_make ("fakesink", "sink");
-  gst_bin_add_many (GST_BIN (bin), src1, ac1, q1, src2, ac2, q2, audiomixer,
-      sink, NULL);
 
-  res = gst_element_link (src1, ac1);
-  fail_unless (res == TRUE, NULL);
-  res = gst_element_link (ac1, q1);
-  fail_unless (res == TRUE, NULL);
-  res = gst_element_link (q1, audiomixer);
-  fail_unless (res == TRUE, NULL);
-  res = gst_element_link (src2, ac2);
+  gst_bin_add_many (GST_BIN (bin), src1, cf, audiomixer, sink, NULL);
+  res = gst_element_link (src1, cf);
   fail_unless (res == TRUE, NULL);
-  res = gst_element_link (ac2, q2);
-  fail_unless (res == TRUE, NULL);
-  res = gst_element_link (q2, audiomixer);
+  res = gst_element_link (cf, audiomixer);
   fail_unless (res == TRUE, NULL);
   res = gst_element_link (audiomixer, sink);
   fail_unless (res == TRUE, NULL);
 
+  gst_element_set_state (bin, GST_STATE_PLAYING);
+  /* wait for completion */
+  state_res =
+      gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
+      GST_CLOCK_TIME_NONE);
+  ck_assert_int_ne (state_res, GST_STATE_CHANGE_FAILURE);
+
+  sinkpad = gst_element_get_static_pad (sink, "sink");
+  fail_unless (sinkpad != NULL);
+  caps = gst_pad_get_current_caps (sinkpad);
+  fail_unless (caps != NULL);
+  gst_object_unref (sinkpad);
+
+  gst_element_set_state (bin, GST_STATE_NULL);
+
+  g_object_set (cf, "caps", caps, NULL);
+
+  src2 = gst_element_factory_make ("audiotestsrc", "src2");
+  g_object_set (src2, "wave", 4, NULL); /* silence */
+  gst_bin_add (GST_BIN (bin), src2);
+
+  res = gst_element_link_filtered (src2, audiomixer, caps);
+  fail_unless (res == TRUE, NULL);
+
+  gst_caps_unref (caps);
+
   play_seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
       GST_SEEK_FLAG_FLUSH,
       GST_SEEK_TYPE_SET, (GstClockTime) 0,