diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt index 1b52239065..c4d1cf776a 100644 --- a/docs/libs/gstreamer-libs-sections.txt +++ b/docs/libs/gstreamer-libs-sections.txt @@ -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 GST_TYPE_FLOW_COMBINER diff --git a/libs/gst/base/gstflowcombiner.c b/libs/gst/base/gstflowcombiner.c index e21f6c21ef..bbde72eed6 100644 --- a/libs/gst/base/gstflowcombiner.c +++ b/libs/gst/base/gstflowcombiner.c @@ -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 #GstPads, 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 #GstPads. * * 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) { diff --git a/libs/gst/base/gstflowcombiner.h b/libs/gst/base/gstflowcombiner.h index 43c37e3a4f..692618eacb 100644 --- a/libs/gst/base/gstflowcombiner.h +++ b/libs/gst/base/gstflowcombiner.h @@ -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 diff --git a/tests/check/libs/flowcombiner.c b/tests/check/libs/flowcombiner.c index 372a7fc6be..6c634c17a4 100644 --- a/tests/check/libs/flowcombiner.c +++ b/tests/check/libs/flowcombiner.c @@ -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; } diff --git a/win32/common/libgstbase.def b/win32/common/libgstbase.def index 92c35007ab..7c7152016f 100644 --- a/win32/common/libgstbase.def +++ b/win32/common/libgstbase.def @@ -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