flowcombiner: add a gst_flow_combiner_clear() method
authorJonas Holmberg <jonashg@axis.com>
Thu, 25 Sep 2014 12:54:23 +0000 (14:54 +0200)
committerTim-Philipp Müller <tim@centricular.com>
Thu, 25 Sep 2014 14:40:42 +0000 (15:40 +0100)
https://bugzilla.gnome.org/show_bug.cgi?id=737359

API: gst_flow_combiner_clear()

docs/libs/gstreamer-libs-sections.txt
libs/gst/base/gstflowcombiner.c
libs/gst/base/gstflowcombiner.h
tests/check/libs/flowcombiner.c
win32/common/libgstbase.def

index 1b52239..c4d1cf7 100644 (file)
@@ -763,6 +763,7 @@ gst_flow_combiner_free
 gst_flow_combiner_update_flow
 gst_flow_combiner_add_pad
 gst_flow_combiner_remove_pad
+gst_flow_combiner_clear
 <SUBSECTION Standard>
 GST_TYPE_FLOW_COMBINER
 <SUBSECTION Private>
index e21f6c2..bbde72e 100644 (file)
@@ -41,9 +41,7 @@
  * Please be aware that this struct isn't thread safe as its designed to be
  *  used by demuxers, those usually will have a single thread operating it.
  *
- * None of these functions will take refs on the passed #GstPad<!-- -->s, it
- * is the caller's responsibility to make sure that the #GstPad exists as long
- * as this struct exists.
+ * These functions will take refs on the passed #GstPad<!-- -->s.
  *
  * Aside from reducing the user's code size, the main advantage of using this
  * helper struct is to follow the standard rules for #GstFlowReturn combination.
@@ -140,6 +138,26 @@ gst_flow_combiner_unref (GstFlowCombiner * combiner)
   }
 }
 
+/**
+ * gst_flow_combiner_clear:
+ * @combiner: the #GstFlowCombiner to clear
+ *
+ * Removes all pads from a #GstFlowCombiner and resets it to its initial state.
+ *
+ * Since: 1.6
+ */
+void
+gst_flow_combiner_clear (GstFlowCombiner * combiner)
+{
+  GstPad *pad;
+
+  g_return_if_fail (combiner != NULL);
+
+  while ((pad = g_queue_pop_head (&combiner->pads)))
+    gst_object_unref (pad);
+  combiner->last_ret = GST_FLOW_OK;
+}
+
 static GstFlowReturn
 gst_flow_combiner_get_flow (GstFlowCombiner * combiner)
 {
index 43c37e3..692618e 100644 (file)
@@ -51,6 +51,8 @@ void              gst_flow_combiner_add_pad    (GstFlowCombiner * combiner, GstP
 
 void              gst_flow_combiner_remove_pad (GstFlowCombiner * combiner, GstPad * pad);
 
+void              gst_flow_combiner_clear (GstFlowCombiner * combiner);
+
 GType             gst_flow_combiner_get_type (void);
 
 G_END_DECLS
index 372a7fc..6c634c1 100644 (file)
@@ -152,6 +152,86 @@ GST_START_TEST (test_combined_flows)
 }
 
 GST_END_TEST;
+
+GST_START_TEST (test_clear)
+{
+  GstFlowCombiner *combiner;
+  GstPad *pad;
+  GstPad *peer;
+  GstSegment segment;
+  GstFlowReturn ret;
+
+  combiner = gst_flow_combiner_new ();
+
+  /* add a pad and make it return _FLUSHING */
+  pad = gst_pad_new ("src1", GST_PAD_SRC);
+  peer = gst_pad_new ("sink1", GST_PAD_SINK);
+  gst_pad_set_chain_function (peer, _sink_chain);
+  gst_pad_link (pad, peer);
+  gst_pad_set_active (peer, TRUE);
+  gst_pad_set_active (pad, TRUE);
+  gst_segment_init (&segment, GST_FORMAT_BYTES);
+  gst_pad_push_event (pad, gst_event_new_stream_start ("test1"));
+  gst_pad_push_event (pad, gst_event_new_segment (&segment));
+  gst_flow_combiner_add_pad (combiner, pad);
+  sink_flowret = GST_FLOW_FLUSHING;
+  fail_unless_equals_int (gst_pad_push (pad, gst_buffer_new ()),
+      GST_FLOW_FLUSHING);
+
+  /* the combined flow is _FLUSHING */
+  ret = gst_flow_combiner_update_flow (combiner, GST_FLOW_FLUSHING);
+  fail_unless_equals_int (ret, GST_FLOW_FLUSHING);
+  gst_object_unref (pad);
+  gst_object_unref (peer);
+
+  /* add one more pad and make it return _OK */
+  pad = gst_pad_new ("src2", GST_PAD_SRC);
+  peer = gst_pad_new ("sink2", GST_PAD_SINK);
+  gst_pad_set_chain_function (peer, _sink_chain);
+  gst_pad_link (pad, peer);
+  gst_pad_set_active (peer, TRUE);
+  gst_pad_set_active (pad, TRUE);
+  gst_segment_init (&segment, GST_FORMAT_BYTES);
+  gst_pad_push_event (pad, gst_event_new_stream_start ("test2"));
+  gst_pad_push_event (pad, gst_event_new_segment (&segment));
+  gst_flow_combiner_add_pad (combiner, pad);
+  sink_flowret = GST_FLOW_OK;
+  fail_unless_equals_int (gst_pad_push (pad, gst_buffer_new ()), GST_FLOW_OK);
+
+  /* the combined flow is _FLUSHING because of the first pad */
+  ret = gst_flow_combiner_update_flow (combiner, GST_FLOW_OK);
+  fail_unless_equals_int (ret, GST_FLOW_FLUSHING);
+  gst_object_unref (pad);
+  gst_object_unref (peer);
+
+  /* clear the combiner */
+  gst_flow_combiner_clear (combiner);
+
+  /* add a pad and make it return _OK */
+  pad = gst_pad_new ("src3", GST_PAD_SRC);
+  peer = gst_pad_new ("sink3", GST_PAD_SINK);
+  gst_pad_set_chain_function (peer, _sink_chain);
+  gst_pad_link (pad, peer);
+  gst_pad_set_active (peer, TRUE);
+  gst_pad_set_active (pad, TRUE);
+  gst_segment_init (&segment, GST_FORMAT_BYTES);
+  gst_pad_push_event (pad, gst_event_new_stream_start ("test3"));
+  gst_pad_push_event (pad, gst_event_new_segment (&segment));
+  gst_flow_combiner_add_pad (combiner, pad);
+  sink_flowret = GST_FLOW_OK;
+  fail_unless_equals_int (gst_pad_push (pad, gst_buffer_new ()), GST_FLOW_OK);
+
+  /* the combined flow is _OK since the other pads have been removed */
+  ret = gst_flow_combiner_update_flow (combiner, GST_FLOW_OK);
+  fail_unless_equals_int (ret, GST_FLOW_OK);
+  gst_object_unref (pad);
+  gst_object_unref (peer);
+
+  gst_flow_combiner_free (combiner);
+}
+
+GST_END_TEST;
+
 static Suite *
 flow_combiner_suite (void)
 {
@@ -160,6 +240,7 @@ flow_combiner_suite (void)
 
   suite_add_tcase (s, tc_chain);
   tcase_add_test (tc_chain, test_combined_flows);
+  tcase_add_test (tc_chain, test_clear);
 
   return s;
 }
index 92c3500..7c71520 100644 (file)
@@ -271,6 +271,7 @@ EXPORTS
        gst_flow_combiner_new
        gst_flow_combiner_remove_pad
        gst_flow_combiner_update_flow
+       gst_flow_combiner_clear
        gst_push_src_get_type
        gst_queue_array_drop_element
        gst_queue_array_find