summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorin Apostol <florin.apostol@oregan.net>2015-06-05 17:20:20 +0100
committerThiago Santos <thiagoss@osg.samsung.com>2015-06-08 13:17:49 -0300
commit8b18be5bfb7544915cb55b031a7b77787f64e3a2 (patch)
treefc765e41aabbf08fec514a0d9c8a725bb39461ab
parent7b8d819d186156f35ec67c47b6d42cd72685d6c2 (diff)
downloadgstreamer-plugins-bad-8b18be5bfb7544915cb55b031a7b77787f64e3a2.tar.gz
tests: dashdemux: add unit tests for checking the parsing of MPD element
Create a dash test target and add unit tests that check the parsing of attributes of the MPD element and the following child elements: - baseURL - program information - location - metrics These tests check the compliance of parts of the MPD parser in the dashdemux element against the DASH specification [1]. [1] http://standards.iso.org/ittf/PubliclyAvailableStandards/c065274_ISO_IEC_23009-1_2014_Electronic_inserts.zip http://standards.iso.org/ittf/PubliclyAvailableStandards/c065274_ISO_IEC_23009-1_2014.zip https://bugzilla.gnome.org/show_bug.cgi?id=750390
-rw-r--r--tests/check/Makefile.am11
-rw-r--r--tests/check/elements/.gitignore1
-rw-r--r--tests/check/elements/dash_mpd.c454
3 files changed, 466 insertions, 0 deletions
diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am
index 04e5d5df8..e51bb0360 100644
--- a/tests/check/Makefile.am
+++ b/tests/check/Makefile.am
@@ -40,6 +40,12 @@ else
check_assrender =
endif
+if USE_DASH
+check_dash = elements/dash_mpd
+else
+check_dash =
+endif
+
if USE_FAAC
check_faac = elements/faac
else
@@ -222,6 +228,7 @@ noinst_PROGRAMS = \
check_PROGRAMS = \
generic/states \
$(check_assrender) \
+ $(check_dash) \
$(check_faac) \
$(check_faad) \
$(check_voaacenc) \
@@ -428,6 +435,10 @@ elements_mpg123audiodec_LDADD = \
elements_uvch264demux_CFLAGS = -DUVCH264DEMUX_DATADIR="$(srcdir)/elements/uvch264demux_data" \
$(AM_CFLAGS)
+elements_dash_mpd_CFLAGS = $(AM_CFLAGS) $(LIBXML2_CFLAGS)
+elements_dash_mpd_LDADD = $(LDADD) $(LIBXML2_LIBS)
+elements_dash_mpd_SOURCES = elements/dash_mpd.c
+
pipelines_streamheader_CFLAGS = $(GIO_CFLAGS) $(AM_CFLAGS)
pipelines_streamheader_LDADD = $(GIO_LIBS) $(LDADD)
diff --git a/tests/check/elements/.gitignore b/tests/check/elements/.gitignore
index 1c5d0a924..4fe8ea386 100644
--- a/tests/check/elements/.gitignore
+++ b/tests/check/elements/.gitignore
@@ -15,6 +15,7 @@ curlftpsink
curlsftpsink
curlhttpsink
curlsmtpsink
+dash_mpd
dataurisrc
faac
faad
diff --git a/tests/check/elements/dash_mpd.c b/tests/check/elements/dash_mpd.c
new file mode 100644
index 000000000..a30baf4c0
--- /dev/null
+++ b/tests/check/elements/dash_mpd.c
@@ -0,0 +1,454 @@
+/* GStreamer unit test for MPEG-DASH
+ *
+ * Copyright (c) <2015> YouView TV Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "../../ext/dash/gstmpdparser.c"
+#undef GST_CAT_DEFAULT
+
+#include <gst/check/gstcheck.h>
+
+GST_DEBUG_CATEGORY (gst_dash_demux_debug);
+
+/*
+ * compute the number of milliseconds contained in a duration value specified by
+ * year, month, day, hour, minute, second, millisecond
+ *
+ * This function must use the same conversion algorithm implemented in
+ * gst_mpdparser_get_xml_prop_duration from gstmpdparser.c file.
+ */
+static gint64
+duration_to_ms (guint year, guint month, guint day, guint hour, guint minute,
+ guint second, guint millisecond)
+{
+ gint64 days = (gint64) year * 365 + month * 30 + day;
+ gint64 hours = days * 24 + hour;
+ gint64 minutes = hours * 60 + minute;
+ gint64 seconds = minutes * 60 + second;
+ gint64 ms = seconds * 1000 + millisecond;
+ return ms;
+}
+
+/*
+ * Test to ensure a simple mpd file successfully parses.
+ *
+ */
+GST_START_TEST (dash_mpdparser_validsimplempd)
+{
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"> </MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, TRUE);
+ /* check that unset elements with default values are properly configured */
+ assert_equals_int (mpdclient->mpd_node->type, GST_MPD_FILE_TYPE_STATIC);
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing the MPD attributes.
+ *
+ */
+GST_START_TEST (dash_mpdparser_mpd)
+{
+ GstDateTime *availabilityStartTime;
+ GstDateTime *availabilityEndTime;
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
+ " id=\"testId\""
+ " type=\"static\""
+ " availabilityStartTime=\"2015-03-24T1:10:50\""
+ " availabilityEndTime=\"2015-03-24T1:10:50\""
+ " mediaPresentationDuration=\"P0Y1M2DT12H10M20.5S\""
+ " minimumUpdatePeriod=\"P0Y1M2DT12H10M20.5S\""
+ " minBufferTime=\"P0Y1M2DT12H10M20.5S\""
+ " timeShiftBufferDepth=\"P0Y1M2DT12H10M20.5S\""
+ " suggestedPresentationDelay=\"P0Y1M2DT12H10M20.5S\""
+ " maxSegmentDuration=\"P0Y1M2DT12H10M20.5S\""
+ " maxSubsegmentDuration=\"P0Y1M2DT12H10M20.5S\"></MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, TRUE);
+
+ assert_equals_string (mpdclient->mpd_node->id, "testId");
+
+ assert_equals_int (mpdclient->mpd_node->type, GST_MPD_FILE_TYPE_STATIC);
+
+ availabilityStartTime = mpdclient->mpd_node->availabilityStartTime;
+ assert_equals_int (gst_date_time_get_year (availabilityStartTime), 2015);
+ assert_equals_int (gst_date_time_get_month (availabilityStartTime), 3);
+ assert_equals_int (gst_date_time_get_day (availabilityStartTime), 24);
+ assert_equals_int (gst_date_time_get_hour (availabilityStartTime), 1);
+ assert_equals_int (gst_date_time_get_minute (availabilityStartTime), 10);
+ assert_equals_int (gst_date_time_get_second (availabilityStartTime), 50);
+
+ availabilityEndTime = mpdclient->mpd_node->availabilityEndTime;
+ assert_equals_int (gst_date_time_get_year (availabilityEndTime), 2015);
+ assert_equals_int (gst_date_time_get_month (availabilityEndTime), 3);
+ assert_equals_int (gst_date_time_get_day (availabilityEndTime), 24);
+ assert_equals_int (gst_date_time_get_hour (availabilityEndTime), 1);
+ assert_equals_int (gst_date_time_get_minute (availabilityEndTime), 10);
+ assert_equals_int (gst_date_time_get_second (availabilityEndTime), 50);
+
+ assert_equals_int64 (mpdclient->mpd_node->mediaPresentationDuration,
+ duration_to_ms (0, 1, 2, 12, 10, 20, 500));
+
+ assert_equals_int64 (mpdclient->mpd_node->minimumUpdatePeriod,
+ duration_to_ms (0, 1, 2, 12, 10, 20, 500));
+
+ assert_equals_int64 (mpdclient->mpd_node->minBufferTime,
+ duration_to_ms (0, 1, 2, 12, 10, 20, 500));
+
+ assert_equals_int64 (mpdclient->mpd_node->timeShiftBufferDepth,
+ duration_to_ms (0, 1, 2, 12, 10, 20, 500));
+
+ assert_equals_int64 (mpdclient->mpd_node->suggestedPresentationDelay,
+ duration_to_ms (0, 1, 2, 12, 10, 20, 500));
+
+ assert_equals_int64 (mpdclient->mpd_node->maxSegmentDuration,
+ duration_to_ms (0, 1, 2, 12, 10, 20, 500));
+
+ assert_equals_int64 (mpdclient->mpd_node->maxSubsegmentDuration,
+ duration_to_ms (0, 1, 2, 12, 10, 20, 500));
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing the ProgramInformation attributes
+ *
+ */
+GST_START_TEST (dash_mpdparser_program_information)
+{
+ GstProgramInformationNode *program;
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
+ "<ProgramInformation lang=\"en\""
+ " moreInformationURL=\"TestMoreInformationUrl\">"
+ "<Title>TestTitle</Title>"
+ "<Source>TestSource</Source>"
+ "<Copyright>TestCopyright</Copyright> </ProgramInformation> </MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, TRUE);
+ program =
+ (GstProgramInformationNode *) mpdclient->mpd_node->ProgramInfo->data;
+ assert_equals_string (program->lang, "en");
+ assert_equals_string (program->moreInformationURL, "TestMoreInformationUrl");
+ assert_equals_string (program->Title, "TestTitle");
+ assert_equals_string (program->Source, "TestSource");
+ assert_equals_string (program->Copyright, "TestCopyright");
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing the BaseURL attributes
+ *
+ */
+GST_START_TEST (dash_mpdparser_base_URL)
+{
+ GstBaseURL *baseURL;
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
+ "<BaseURL serviceLocation=\"TestServiceLocation\""
+ " byteRange=\"TestByteRange\">TestBaseURL</BaseURL></MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, TRUE);
+ baseURL = (GstBaseURL *) mpdclient->mpd_node->BaseURLs->data;
+ assert_equals_string (baseURL->baseURL, "TestBaseURL");
+ assert_equals_string (baseURL->serviceLocation, "TestServiceLocation");
+ assert_equals_string (baseURL->byteRange, "TestByteRange");
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing the location attributes
+ *
+ */
+GST_START_TEST (dash_mpdparser_location)
+{
+ const gchar *location;
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
+ "<Location>TestLocation</Location></MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, TRUE);
+ location = (gchar *) mpdclient->mpd_node->Locations->data;
+ assert_equals_string (location, "TestLocation");
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing metrics attributes
+ *
+ */
+GST_START_TEST (dash_mpdparser_metrics)
+{
+ GstMetricsNode *metricsNode;
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
+ "<Metrics metrics=\"TestMetric\"></Metrics></MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, TRUE);
+ metricsNode = (GstMetricsNode *) mpdclient->mpd_node->Metrics->data;
+ assert_equals_string (metricsNode->metrics, "TestMetric");
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing metrics range attributes
+ *
+ */
+GST_START_TEST (dash_mpdparser_metrics_range)
+{
+ GstMetricsNode *metricsNode;
+ GstMetricsRangeNode *metricsRangeNode;
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
+ "<Metrics><Range starttime=\"P0Y1M2DT12H10M20.5S\""
+ " duration=\"P0Y1M2DT12H10M20.1234567S\"></Range></Metrics></MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, TRUE);
+ metricsNode = (GstMetricsNode *) mpdclient->mpd_node->Metrics->data;
+ assert_equals_pointer (metricsNode->metrics, NULL);
+ metricsRangeNode = (GstMetricsRangeNode *) metricsNode->MetricsRanges->data;
+ assert_equals_int64 (metricsRangeNode->starttime,
+ duration_to_ms (0, 1, 2, 12, 10, 20, 500));
+ assert_equals_int64 (metricsRangeNode->duration,
+ duration_to_ms (0, 1, 2, 12, 10, 20, 123));
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing metrics reporting attributes
+ *
+ */
+GST_START_TEST (dash_mpdparser_metrics_reporting)
+{
+ GstMetricsNode *metricsNode;
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
+ "<Metrics><Reporting></Reporting></Metrics></MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, TRUE);
+ metricsNode = (GstMetricsNode *) mpdclient->mpd_node->Metrics->data;
+ assert_equals_pointer (metricsNode->metrics, NULL);
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing the type property: value "dynamic"
+ *
+ */
+GST_START_TEST (dash_mpdparser_type_dynamic)
+{
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD type=\"dynamic\" xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"> </MPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, TRUE);
+ assert_equals_int (mpdclient->mpd_node->type, GST_MPD_FILE_TYPE_DYNAMIC);
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing empty xml string
+ *
+ */
+GST_START_TEST (dash_mpdparser_missing_xml)
+{
+ const gchar *xml = "";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, FALSE);
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing an xml with no mpd tag
+ *
+ */
+GST_START_TEST (dash_mpdparser_missing_mpd)
+{
+ const gchar *xml = "<?xml version=\"1.0\"?>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, FALSE);
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * Test parsing an MPD with a wrong end tag
+ */
+GST_START_TEST (dash_mpdparser_no_end_tag)
+{
+ const gchar *xml =
+ "<?xml version=\"1.0\"?>"
+ "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
+ " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"> </NPD>";
+
+ gboolean ret;
+ GstMpdClient *mpdclient = gst_mpd_client_new ();
+
+ ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
+
+ assert_equals_int (ret, FALSE);
+
+ gst_mpd_client_free (mpdclient);
+}
+
+GST_END_TEST;
+
+/*
+ * create a test suite containing all dash testcases
+ */
+static Suite *
+dash_suite (void)
+{
+ Suite *s = suite_create ("dash");
+ TCase *tc_simpleMPD = tcase_create ("simpleMPD");
+ TCase *tc_negativeTests = tcase_create ("negativeTests");
+
+ GST_DEBUG_CATEGORY_INIT (gst_dash_demux_debug, "gst_dash_demux_debug", 0,
+ "mpeg dash tests");
+
+ /* test parsing the simplest possible mpd */
+ tcase_add_test (tc_simpleMPD, dash_mpdparser_validsimplempd);
+
+ /* tests parsing attributes from each element type */
+ tcase_add_test (tc_simpleMPD, dash_mpdparser_mpd);
+ tcase_add_test (tc_simpleMPD, dash_mpdparser_program_information);
+ tcase_add_test (tc_simpleMPD, dash_mpdparser_base_URL);
+ tcase_add_test (tc_simpleMPD, dash_mpdparser_location);
+ tcase_add_test (tc_simpleMPD, dash_mpdparser_metrics);
+ tcase_add_test (tc_simpleMPD, dash_mpdparser_metrics_range);
+ tcase_add_test (tc_simpleMPD, dash_mpdparser_metrics_reporting);
+
+ /* tests checking other possible values for attributes */
+ tcase_add_test (tc_simpleMPD, dash_mpdparser_type_dynamic);
+
+ /* tests checking the parsing of missing/incomplete attributes of xml */
+ tcase_add_test (tc_negativeTests, dash_mpdparser_missing_xml);
+ tcase_add_test (tc_negativeTests, dash_mpdparser_missing_mpd);
+ tcase_add_test (tc_negativeTests, dash_mpdparser_no_end_tag);
+
+ suite_add_tcase (s, tc_simpleMPD);
+ suite_add_tcase (s, tc_negativeTests);
+
+ return s;
+}
+
+GST_CHECK_MAIN (dash);