From 64effe78e76ec434606962a83a250c3b1ab5d612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Tue, 21 Feb 2012 20:43:48 +0000 Subject: [PATCH 1/5] tests: make datetime test more reliably when comparing two almost identical nows Account for rounding errors in some places, and that two nows are not always entirely identical, so allow some leeway when comparing microseconds and seconds. Ran into this too often, esp. when the system is under load. --- tests/check/gst/gstdatetime.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/check/gst/gstdatetime.c b/tests/check/gst/gstdatetime.c index ccc692f8ce..10f1c607f9 100644 --- a/tests/check/gst/gstdatetime.c +++ b/tests/check/gst/gstdatetime.c @@ -24,11 +24,13 @@ #include #include -#define ASSERT_TIME(dt,H,M,S) G_STMT_START { \ - assert_equals_int ((H), gst_date_time_get_hour ((dt))); \ - assert_equals_int ((M), gst_date_time_get_minute ((dt))); \ - assert_equals_int ((S), gst_date_time_get_second ((dt))); \ -} G_STMT_END +#define assert_almost_equals_int(a, b) \ +G_STMT_START { \ + int first = a; \ + int second = b; \ + fail_unless(ABS (first - second) <= 1, \ + "'" #a "' (%d) is not almost equal to '" #b"' (%d)", first, second); \ +} G_STMT_END; GST_START_TEST (test_GstDateTime_now) { @@ -49,7 +51,7 @@ GST_START_TEST (test_GstDateTime_now) assert_equals_int (gst_date_time_get_day (dt), tm.tm_mday); assert_equals_int (gst_date_time_get_hour (dt), tm.tm_hour); assert_equals_int (gst_date_time_get_minute (dt), tm.tm_min); - assert_equals_int (gst_date_time_get_second (dt), tm.tm_sec); + assert_almost_equals_int (gst_date_time_get_second (dt), tm.tm_sec); gst_date_time_unref (dt); } @@ -177,7 +179,7 @@ GST_START_TEST (test_GstDateTime_get_microsecond) g_get_current_time (&tv); dt = gst_date_time_new (0, 2010, 7, 15, 11, 12, 13 + (tv.tv_usec / 1000000.0)); - assert_equals_int (tv.tv_usec, gst_date_time_get_microsecond (dt)); + assert_almost_equals_int (tv.tv_usec, gst_date_time_get_microsecond (dt)); gst_date_time_unref (dt); } @@ -252,7 +254,7 @@ GST_START_TEST (test_GstDateTime_utc_now) assert_equals_int (tm.tm_mday, gst_date_time_get_day (dt)); assert_equals_int (tm.tm_hour, gst_date_time_get_hour (dt)); assert_equals_int (tm.tm_min, gst_date_time_get_minute (dt)); - assert_equals_int (tm.tm_sec, gst_date_time_get_second (dt)); + assert_almost_equals_int (tm.tm_sec, gst_date_time_get_second (dt)); gst_date_time_unref (dt); } From 823807c5f0e6cf6ca28268eda1c61d2454ff9b79 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 27 Feb 2012 13:35:10 +0100 Subject: [PATCH 2/5] Suppress deprecation warnings in selected files, for g_value_array_* mostly --- gst/gstquery.c | 5 +++++ tools/gst-inspect.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/gst/gstquery.c b/gst/gstquery.c index 2b1c382294..d9c48f8b91 100644 --- a/gst/gstquery.c +++ b/gst/gstquery.c @@ -61,6 +61,11 @@ * Last reviewed on 2006-02-14 (0.10.4) */ + +/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #include "gst_private.h" #include "gstinfo.h" #include "gstquery.h" diff --git a/tools/gst-inspect.c b/tools/gst-inspect.c index 75e5181cb2..f8d2f2f6f1 100644 --- a/tools/gst-inspect.c +++ b/tools/gst-inspect.c @@ -21,6 +21,10 @@ * Boston, MA 02111-1307, USA. */ +/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray + * with newer GLib versions (>= 2.31.0) */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + #ifdef HAVE_CONFIG_H # include "config.h" #endif From 9fd063e4048f90ffce5f97ee5d11006e0426988a Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Tue, 28 Feb 2012 20:36:59 +0100 Subject: [PATCH 3/5] collectpads2: add more logging --- libs/gst/base/gstcollectpads2.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libs/gst/base/gstcollectpads2.c b/libs/gst/base/gstcollectpads2.c index fc051d454d..8a6f5da83b 100644 --- a/libs/gst/base/gstcollectpads2.c +++ b/libs/gst/base/gstcollectpads2.c @@ -1328,7 +1328,7 @@ gst_collect_pads2_set_waiting (GstCollectPads2 * pads, GstCollectData2 * data, /* Do something only on a change and if not locked */ if (!GST_COLLECT_PADS2_STATE_IS_SET (data, GST_COLLECT_PADS2_STATE_LOCKED) && (GST_COLLECT_PADS2_STATE_IS_SET (data, GST_COLLECT_PADS2_STATE_WAITING) != - ! !waiting)) { + !!waiting)) { /* Set waiting state for this pad */ if (waiting) GST_COLLECT_PADS2_STATE_SET (data, GST_COLLECT_PADS2_STATE_WAITING); @@ -1703,8 +1703,8 @@ gst_collect_pads2_event (GstPad * pad, GstEvent * event) pads = data->collect; - GST_DEBUG ("Got %s event on pad %s:%s", GST_EVENT_TYPE_NAME (event), - GST_DEBUG_PAD_NAME (data->pad)); + GST_DEBUG_OBJECT (data->pad, "Got %s event on sink pad from %s", + GST_EVENT_TYPE_NAME (event), GST_OBJECT_NAME (GST_EVENT_SRC (event))); GST_OBJECT_LOCK (pads); event_func = pads->priv->event_func; @@ -1718,8 +1718,10 @@ gst_collect_pads2_event (GstPad * pad, GstEvent * event) /* forward event to unblock check_collected */ if (event_func) res = event_func (pads, data, event, event_user_data); - if (!res) + if (!res) { + GST_DEBUG_OBJECT (pad, "forwarding flush start"); res = gst_pad_event_default (pad, event); + } /* now unblock the chain function. * no cond per pad, so they all unblock, @@ -1857,8 +1859,10 @@ forward_or_default: } if (event_func) res = event_func (pads, data, event, event_user_data); - if (!res) + if (!res) { + GST_DEBUG_OBJECT (pad, "forwarding %s", GST_EVENT_TYPE_NAME (event)); res = gst_pad_event_default (pad, event); + } if (need_unlock) GST_COLLECT_PADS2_STREAM_UNLOCK (pads); goto done; From ac03c328d51e6d1a80da098fa8a2a1938536ea27 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Wed, 29 Feb 2012 08:44:04 +0100 Subject: [PATCH 4/5] consistencychecker: also check for duplicated flush_starts --- libs/gst/check/gstconsistencychecker.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/gst/check/gstconsistencychecker.c b/libs/gst/check/gstconsistencychecker.c index ded047e1db..94e665eca3 100644 --- a/libs/gst/check/gstconsistencychecker.c +++ b/libs/gst/check/gstconsistencychecker.c @@ -58,6 +58,9 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data, GST_DEBUG_OBJECT (pad, "%s", GST_EVENT_TYPE_NAME (event)); switch (GST_EVENT_TYPE (event)) { case GST_EVENT_FLUSH_START: + /* FIXME : not 100% sure about whether getting two flush_start in a row + * is valid */ + fail_if (consist->flushing, "Received another FLUSH_START"); consist->flushing = TRUE; break; case GST_EVENT_FLUSH_STOP: From 43a6f5a63d63a441394e4521da7ec4f484522276 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Wed, 29 Feb 2012 21:57:00 +0100 Subject: [PATCH 5/5] 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. --- libs/gst/check/gstconsistencychecker.c | 139 ++++++++++++++++++++++--- libs/gst/check/gstconsistencychecker.h | 8 +- 2 files changed, 128 insertions(+), 19 deletions(-) diff --git a/libs/gst/check/gstconsistencychecker.c b/libs/gst/check/gstconsistencychecker.c index 94e665eca3..d916ef1922 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,13 +193,37 @@ 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 ec88af701e..4cbf3f8bb3 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