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.
This commit is contained in:
Thiago Santos 2015-12-24 09:27:33 -03:00
parent 5bc6769532
commit aec407435d
4 changed files with 101 additions and 3 deletions

View file

@ -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 */

View file

@ -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;

View file

@ -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);

View file

@ -91,6 +91,19 @@ typedef struct _GstAdaptiveDemuxTestCallbacks
void (*appsink_eos) (GstAdaptiveDemuxTestEngine *engine,
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