From aec407435dda76e1a32590ec75264adf4bc26993 Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Thu, 24 Dec 2015 09:27:33 -0300 Subject: [PATCH] tests: adaptive_demux: add function to be able to check demuxer events Allows writing tests that verify that events are correct. Useful to monitor and check segments after seeks, for example. --- tests/check/elements/adaptive_demux_common.c | 52 ++++++++++++++++++++++++++++ tests/check/elements/adaptive_demux_common.h | 5 ++- tests/check/elements/adaptive_demux_engine.c | 34 ++++++++++++++++-- tests/check/elements/adaptive_demux_engine.h | 13 +++++++ 4 files changed, 101 insertions(+), 3 deletions(-) diff --git a/tests/check/elements/adaptive_demux_common.c b/tests/check/elements/adaptive_demux_common.c index 0fedfb9..e3c4199 100644 --- a/tests/check/elements/adaptive_demux_common.c +++ b/tests/check/elements/adaptive_demux_common.c @@ -346,6 +346,44 @@ testSeekAdaptiveDemuxSendsData (GstAdaptiveDemuxTestEngine * engine, return TRUE; } +static void +testSeekAdaptiveAppSinkEvent (GstAdaptiveDemuxTestEngine * engine, + GstAdaptiveDemuxTestOutputStream * stream, + GstEvent * event, gpointer user_data) +{ + GstAdaptiveDemuxTestCase *testData = GST_ADAPTIVE_DEMUX_TEST_CASE (user_data); + GstAdaptiveDemuxTestExpectedOutput *testOutputStreamData; + guint index = 0; + + testOutputStreamData = + gst_adaptive_demux_test_find_test_data_by_stream (testData, stream, + &index); + fail_unless (testOutputStreamData != NULL); + + if (testData->seek_event && GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT + && testOutputStreamData->post_seek_segment.format != GST_FORMAT_UNDEFINED + && gst_event_get_seqnum (event) == + gst_event_get_seqnum (testData->seek_event)) { + const GstSegment *seek_segment; + + gst_event_parse_segment (event, &seek_segment); + fail_unless (seek_segment->format == + testOutputStreamData->post_seek_segment.format); + fail_unless (seek_segment->rate == + testOutputStreamData->post_seek_segment.rate); + fail_unless (seek_segment->start == + testOutputStreamData->post_seek_segment.start); + fail_unless (seek_segment->stop == + testOutputStreamData->post_seek_segment.stop); + fail_unless (seek_segment->base == + testOutputStreamData->post_seek_segment.base); + fail_unless (seek_segment->time == + testOutputStreamData->post_seek_segment.time); + + testOutputStreamData->segment_verification_needed = FALSE; + } +} + /* callback called when main_loop detects a state changed event */ static void testSeekOnStateChanged (GstBus * bus, GstMessage * msg, gpointer user_data) @@ -392,6 +430,18 @@ testSeekPreTestCallback (GstAdaptiveDemuxTestEngine * engine, G_CALLBACK (testSeekOnStateChanged), testData); } +static void +testSeekPostTestCallback (GstAdaptiveDemuxTestEngine * engine, + gpointer user_data) +{ + GstAdaptiveDemuxTestCase *testData = GST_ADAPTIVE_DEMUX_TEST_CASE (user_data); + for (GList * walk = testData->output_streams; walk; walk = g_list_next (walk)) { + GstAdaptiveDemuxTestExpectedOutput *td = walk->data; + + fail_if (td->segment_verification_needed); + } +} + /* function to check total size of data received by AppSink * will be called when AppSink receives eos. */ @@ -429,7 +479,9 @@ gst_adaptive_demux_test_seek (const gchar * element_name, GstAdaptiveDemuxTestCallbacks cb = { 0 }; cb.appsink_received_data = gst_adaptive_demux_test_check_received_data; cb.appsink_eos = gst_adaptive_demux_test_check_size_of_received_data; + cb.appsink_event = testSeekAdaptiveAppSinkEvent; cb.pre_test = testSeekPreTestCallback; + cb.post_test = testSeekPostTestCallback; cb.demux_sent_data = testSeekAdaptiveDemuxSendsData; gst_adaptive_demux_test_run (element_name, manifest_uri, &cb, testData); /* the call to g_object_unref of testData will clean up the seek task */ diff --git a/tests/check/elements/adaptive_demux_common.h b/tests/check/elements/adaptive_demux_common.h index ed7317c..fa8bde0 100644 --- a/tests/check/elements/adaptive_demux_common.h +++ b/tests/check/elements/adaptive_demux_common.h @@ -72,6 +72,9 @@ typedef struct _GstAdaptiveDemuxTestExpectedOutput guint64 expected_size; /* the expected data on this stream (optional) */ const guint8* expected_data; + + GstSegment post_seek_segment; + gboolean segment_verification_needed; } GstAdaptiveDemuxTestExpectedOutput; typedef struct _GstAdaptiveDemuxTestCaseClass GstAdaptiveDemuxTestCaseClass; @@ -102,7 +105,7 @@ typedef struct _GstAdaptiveDemuxTestCase GCond test_task_state_cond; /* seek test will wait for this amount of bytes to be sent by - * demux to AppSink before triggering a seek request + * demux to AppSink before triggering a seek request */ guint64 threshold_for_seek; GstEvent *seek_event; diff --git a/tests/check/elements/adaptive_demux_engine.c b/tests/check/elements/adaptive_demux_engine.c index 9c77708..880d259 100644 --- a/tests/check/elements/adaptive_demux_engine.c +++ b/tests/check/elements/adaptive_demux_engine.c @@ -142,6 +142,30 @@ on_appSinkEOS (GstAppSink * appsink, gpointer user_data) GST_TEST_UNLOCK (priv); } +static GstPadProbeReturn +on_appsink_event (GstPad * pad, GstPadProbeInfo * info, gpointer data) +{ + GstAdaptiveDemuxTestEnginePrivate *priv = + (GstAdaptiveDemuxTestEnginePrivate *) data; + GstAdaptiveDemuxTestOutputStream *stream = NULL; + GstEvent *event; + + event = GST_PAD_PROBE_INFO_EVENT (info); + GST_DEBUG ("Received event %" GST_PTR_FORMAT " on pad %" GST_PTR_FORMAT, + event, pad); + + if (priv->callbacks->appsink_event) { + GST_TEST_LOCK (priv); + stream = getTestOutputDataByPad (priv, pad, TRUE); + GST_TEST_UNLOCK (priv); + priv->callbacks->appsink_event (&priv->engine, stream, event, + priv->user_data); + } + + return GST_PAD_PROBE_OK; +} + + /* callback called when demux sends data to AppSink */ static GstPadProbeReturn on_demux_sent_data (GstPad * pad, GstPadProbeInfo * info, gpointer data) @@ -155,13 +179,13 @@ on_demux_sent_data (GstPad * pad, GstPadProbeInfo * info, gpointer data) GST_TEST_LOCK (priv); stream = getTestOutputDataByPad (priv, pad, TRUE); + GST_TEST_UNLOCK (priv); if (priv->callbacks->demux_sent_data) { (*priv->callbacks->demux_sent_data) (&priv->engine, stream, buffer, priv->user_data); } - GST_TEST_UNLOCK (priv); return GST_PAD_PROBE_OK; } @@ -215,7 +239,7 @@ on_demuxNewPad (GstElement * demux, GstPad * pad, gpointer user_data) GstElement *sink; gboolean ret; gchar *name; - GstPad *internal_pad; + GstPad *internal_pad, *appsink_pad; GstAppSinkCallbacks appSinkCallbacks; GstAdaptiveDemuxTestOutputStream *stream; GObjectClass *gobject_class; @@ -242,6 +266,12 @@ on_demuxNewPad (GstElement * demux, GstPad * pad, gpointer user_data) gst_app_sink_set_callbacks (GST_APP_SINK (sink), &appSinkCallbacks, priv, NULL); + appsink_pad = gst_element_get_static_pad (sink, "sink"); + gst_pad_add_probe (pad, + GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_FLUSH, + (GstPadProbeCallback) on_appsink_event, priv, NULL); + gst_object_unref (appsink_pad); + gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, (GstPadProbeCallback) on_demux_sent_data, priv, NULL); diff --git a/tests/check/elements/adaptive_demux_engine.h b/tests/check/elements/adaptive_demux_engine.h index 267d7e8..8231c56 100644 --- a/tests/check/elements/adaptive_demux_engine.h +++ b/tests/check/elements/adaptive_demux_engine.h @@ -92,6 +92,19 @@ typedef struct _GstAdaptiveDemuxTestCallbacks GstAdaptiveDemuxTestOutputStream * stream, gpointer user_data); /** + * appsink_event: called when an event is received by appsink + * @engine: #GstAdaptiveDemuxTestEngine + * @stream: #GstAdaptiveDemuxTestOutputStream + * @event: the #GstEvent that was pushed in the demuxer pad + * @user_data: the user_data passed to gst_adaptive_demux_test_run() + * + * Can be used by a test to do some checks on the events + */ + void (*appsink_event) (GstAdaptiveDemuxTestEngine *engine, + GstAdaptiveDemuxTestOutputStream * stream, + GstEvent * event, gpointer user_data); + + /** * demux_pad_added: called each time the demux creates a new pad * @engine: #GstAdaptiveDemuxTestEngine * @stream: the #GstAdaptiveDemuxTestOutputStream that has been created -- 2.7.4