From: Stefan Sauer Date: Wed, 29 Feb 2012 20:57:00 +0000 (+0100) Subject: consitencychecker: add handling for sink-pads X-Git-Tag: RELEASE-0.11.3~1^2~19 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=43a6f5a63d63a441394e4521da7ec4f484522276;p=platform%2Fupstream%2Fgstreamer.git consitencychecker: add handling for sink-pads Add a pad-probe for sink-pads. One can now add extra pads (belonging to the same element) to a checker. This allows us to extend the checks. --- diff --git a/libs/gst/check/gstconsistencychecker.c b/libs/gst/check/gstconsistencychecker.c index 94e665e..d916ef1 100644 --- a/libs/gst/check/gstconsistencychecker.c +++ b/libs/gst/check/gstconsistencychecker.c @@ -3,6 +3,7 @@ * unit testing helper lib * * Copyright (C) 2009 Edward Hervey + * Copyright (C) 2012 Stefan Sauer * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -34,17 +35,29 @@ struct _GstStreamConsistency { - gboolean flushing; - gboolean newsegment; - gboolean eos; - gulong probeid; - GstPad *pad; + /* FIXME: do we want to track some states per pad? */ + volatile gboolean flushing; + volatile gboolean newsegment; + volatile gboolean eos; + volatile gboolean expect_flush; + GstObject *parent; + GList *pads; }; +typedef struct _GstStreamConsistencyProbe +{ + GstPad *pad; + gulong probeid; +} GstStreamConsistencyProbe; + + static gboolean source_pad_data_cb (GstPad * pad, GstMiniObject * data, GstStreamConsistency * consist) { + GST_DEBUG_OBJECT (pad, "%p: %d %d %d %d", consist, consist->flushing, + consist->newsegment, consist->eos, consist->expect_flush); + if (GST_IS_BUFFER (data)) { GST_DEBUG_OBJECT (pad, "Buffer %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (GST_BUFFER (data)))); @@ -68,9 +81,11 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data, fail_unless (consist->flushing, "Received a FLUSH_STOP without a FLUSH_START"); fail_if (consist->eos, "Received a FLUSH_STOP after an EOS"); - consist->flushing = FALSE; + consist->flushing = consist->expect_flush = FALSE; break; case GST_EVENT_NEWSEGMENT: + fail_if ((consist->expect_flush && consist->flushing), + "Received NEWSEGMENT while in a flushing seek"); consist->newsegment = TRUE; consist->eos = FALSE; break; @@ -96,6 +111,69 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data, return TRUE; } +static gboolean +sink_pad_data_cb (GstPad * pad, GstMiniObject * data, + GstStreamConsistency * consist) +{ + GST_DEBUG_OBJECT (pad, "%p: %d %d %d %d", consist, consist->flushing, + consist->newsegment, consist->eos, consist->expect_flush); + + if (GST_IS_BUFFER (data)) { + GST_DEBUG_OBJECT (pad, "Buffer %" GST_TIME_FORMAT, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (GST_BUFFER (data)))); + /* If an EOS went through, a buffer would be invalid */ + fail_if (consist->eos, "Buffer received after EOS"); + /* Buffers need to be preceded by a newsegment event */ + fail_unless (consist->newsegment, "Buffer received without newsegment"); + } else if (GST_IS_EVENT (data)) { + GstEvent *event = (GstEvent *) data; + + GST_DEBUG_OBJECT (pad, "%s", GST_EVENT_TYPE_NAME (event)); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_SEEK: + { + GstSeekFlags flags; + + gst_event_parse_seek (event, NULL, NULL, &flags, NULL, NULL, NULL, + NULL); + consist->expect_flush = + ((flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH); + break; + } + case GST_EVENT_NEWSEGMENT: + fail_if ((consist->expect_flush && consist->flushing), + "Received NEWSEGMENT while in a flushing seek"); + consist->newsegment = TRUE; + consist->eos = FALSE; + break; + default: + /* FIXME : Figure out what to do for other events */ + break; + } + } + + return TRUE; +} + +static void +add_pad (GstStreamConsistency * consist, GstPad * pad) +{ + GstStreamConsistencyProbe *p; + GstPadDirection dir; + + p = g_new0 (GstStreamConsistencyProbe, 1); + p->pad = g_object_ref (pad); + dir = gst_pad_get_direction (pad); + if (dir == GST_PAD_SRC) { + p->probeid = + gst_pad_add_data_probe (pad, (GCallback) source_pad_data_cb, consist); + } else if (dir == GST_PAD_SINK) { + p->probeid = + gst_pad_add_data_probe (pad, (GCallback) sink_pad_data_cb, consist); + } + consist->pads = g_list_prepend (consist->pads, p); +} + /** * gst_consistency_checker_new: * @pad: The #GstPad on which the dataflow will be checked. @@ -103,13 +181,10 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data, * Sets up a data probe on the given pad which will raise assertions if the * data flow is inconsistent. * - * Currently only works for source pads. - * * Returns: A #GstStreamConsistency structure used to track data flow. * * Since: 0.10.24 */ - GstStreamConsistency * gst_consistency_checker_new (GstPad * pad) { @@ -118,14 +193,38 @@ gst_consistency_checker_new (GstPad * pad) g_return_val_if_fail (pad != NULL, NULL); consist = g_new0 (GstStreamConsistency, 1); - consist->pad = g_object_ref (pad); - consist->probeid = - gst_pad_add_data_probe (pad, (GCallback) source_pad_data_cb, consist); + if (!consist->pads) { + consist->parent = GST_OBJECT_PARENT (pad); + } + add_pad (consist, pad); return consist; } /** + * gst_consistency_checker_add_pad: + * @consist: The #GstStreamConsistency handle + * @pad: The #GstPad on which the dataflow will be checked. + * + * Sets up a data probe on the given pad which will raise assertions if the + * data flow is inconsistent. + * + * Returns: %TRUE if the pad was added + * + * Since: 0.10.37 + */ +gboolean +gst_consistency_checker_add_pad (GstStreamConsistency * consist, GstPad * pad) +{ + g_return_val_if_fail (consist != NULL, FALSE); + g_return_val_if_fail (pad != NULL, FALSE); + g_return_val_if_fail (GST_OBJECT_PARENT (pad) == consist->parent, FALSE); + + add_pad (consist, pad); + return TRUE; +} + +/** * gst_consistency_checker_reset: * @consist: The #GstStreamConsistency to reset. * @@ -146,7 +245,7 @@ gst_consistency_checker_reset (GstStreamConsistency * consist) * gst_consistency_checker_free: * @consist: The #GstStreamConsistency to free. * - * Frees the allocated data and probe associated with @consist. + * Frees the allocated data and probes associated with @consist. * * Since: 0.10.24 */ @@ -154,8 +253,16 @@ gst_consistency_checker_reset (GstStreamConsistency * consist) void gst_consistency_checker_free (GstStreamConsistency * consist) { - /* Remove the data probe */ - gst_pad_remove_data_probe (consist->pad, consist->probeid); - g_object_unref (consist->pad); + GList *node; + GstStreamConsistencyProbe *p; + + /* Remove the data probes */ + for (node = consist->pads; node; node = g_list_next (node)) { + p = (GstStreamConsistencyProbe *) node->data; + gst_pad_remove_data_probe (p->pad, p->probeid); + g_object_unref (p->pad); + g_free (p); + } + g_list_free (consist->pads); g_free (consist); } diff --git a/libs/gst/check/gstconsistencychecker.h b/libs/gst/check/gstconsistencychecker.h index ec88af7..4cbf3f8 100644 --- a/libs/gst/check/gstconsistencychecker.h +++ b/libs/gst/check/gstconsistencychecker.h @@ -37,11 +37,13 @@ G_BEGIN_DECLS typedef struct _GstStreamConsistency GstStreamConsistency; -GstStreamConsistency * gst_consistency_checker_new (GstPad * pad); +GstStreamConsistency * gst_consistency_checker_new (GstPad * pad); +gboolean gst_consistency_checker_add_pad (GstStreamConsistency * consist, + GstPad * pad); -void gst_consistency_checker_reset (GstStreamConsistency * consist); +void gst_consistency_checker_reset (GstStreamConsistency * consist); -void gst_consistency_checker_free (GstStreamConsistency * consist); +void gst_consistency_checker_free (GstStreamConsistency * consist); G_END_DECLS