| /* 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 guint64 |
| duration_to_ms (guint year, guint month, guint day, guint hour, guint minute, |
| guint second, guint millisecond) |
| { |
| guint64 days = (guint64) year * 365 + (guint64) month * 30 + day; |
| guint64 hours = days * 24 + hour; |
| guint64 minutes = hours * 60 + minute; |
| guint64 seconds = minutes * 60 + second; |
| guint64 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, (gint) 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\"" |
| " schemaLocation=\"TestSchemaLocation\"" |
| " xmlns:xsi=\"TestNamespaceXSI\"" |
| " xmlns:ext=\"TestNamespaceEXT\"" |
| " id=\"testId\"" |
| " type=\"static\"" |
| " availabilityStartTime=\"2015-03-24T1:10:50\"" |
| " availabilityEndTime=\"2015-03-24T1:10:50.123456\"" |
| " 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, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| assert_equals_string (mpdclient->mpd_node->default_namespace, |
| "urn:mpeg:dash:schema:mpd:2011"); |
| assert_equals_string (mpdclient->mpd_node->namespace_xsi, "TestNamespaceXSI"); |
| assert_equals_string (mpdclient->mpd_node->namespace_ext, "TestNamespaceEXT"); |
| assert_equals_string (mpdclient->mpd_node->schemaLocation, |
| "TestSchemaLocation"); |
| 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); |
| assert_equals_int (gst_date_time_get_microsecond (availabilityStartTime), 0); |
| |
| 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_int (gst_date_time_get_microsecond (availabilityEndTime), |
| 123456); |
| |
| assert_equals_uint64 (mpdclient->mpd_node->mediaPresentationDuration, |
| duration_to_ms (0, 1, 2, 12, 10, 20, 500)); |
| |
| assert_equals_uint64 (mpdclient->mpd_node->minimumUpdatePeriod, |
| duration_to_ms (0, 1, 2, 12, 10, 20, 500)); |
| |
| assert_equals_uint64 (mpdclient->mpd_node->minBufferTime, |
| duration_to_ms (0, 1, 2, 12, 10, 20, 500)); |
| |
| assert_equals_uint64 (mpdclient->mpd_node->timeShiftBufferDepth, |
| duration_to_ms (0, 1, 2, 12, 10, 20, 500)); |
| |
| assert_equals_uint64 (mpdclient->mpd_node->suggestedPresentationDelay, |
| duration_to_ms (0, 1, 2, 12, 10, 20, 500)); |
| |
| assert_equals_uint64 (mpdclient->mpd_node->maxSegmentDuration, |
| duration_to_ms (0, 1, 2, 12, 10, 20, 500)); |
| |
| assert_equals_uint64 (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_programInformation) |
| { |
| 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, (gint) 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_baseURL) |
| { |
| 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, (gint) 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, (gint) 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, (gint) 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, (gint) 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_uint64 (metricsRangeNode->starttime, |
| duration_to_ms (0, 1, 2, 12, 10, 20, 500)); |
| assert_equals_uint64 (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, (gint) 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 Period attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period) |
| { |
| GstPeriodNode *periodNode; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period id=\"TestId\"" |
| " start=\"P0Y1M2DT12H10M20.1234567S\"" |
| " duration=\"P0Y1M2DT12H10M20.7654321S\"" |
| " bitstreamSwitching=\"true\"></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| assert_equals_string (periodNode->id, "TestId"); |
| assert_equals_uint64 (periodNode->start, |
| duration_to_ms (0, 1, 2, 12, 10, 20, 123)); |
| assert_equals_uint64 (periodNode->duration, |
| duration_to_ms (0, 1, 2, 12, 10, 20, 765)); |
| assert_equals_int (periodNode->bitstreamSwitching, 1); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period baseURL attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_baseURL) |
| { |
| GstPeriodNode *periodNode; |
| 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\">" |
| " <Period>" |
| " <BaseURL serviceLocation=\"TestServiceLocation\"" |
| " byteRange=\"TestByteRange\">TestBaseURL</BaseURL>" |
| " </Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| baseURL = (GstBaseURL *) periodNode->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 Period SegmentBase attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_segmentBase) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentBaseType *segmentBase; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentBase timescale=\"123456\"" |
| " presentationTimeOffset=\"123456789\"" |
| " indexRange=\"100-200\"" |
| " indexRangeExact=\"true\">" |
| " </SegmentBase></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentBase = periodNode->SegmentBase; |
| assert_equals_uint64 (segmentBase->timescale, 123456); |
| assert_equals_uint64 (segmentBase->presentationTimeOffset, 123456789); |
| assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 100); |
| assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 200); |
| assert_equals_int (segmentBase->indexRangeExact, 1); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentBase Initialization attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_segmentBase_initialization) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentBaseType *segmentBase; |
| GstURLType *initialization; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentBase>" |
| " <Initialisation sourceURL=\"TestSourceURL\"" |
| " range=\"100-200\">" |
| " </Initialisation></SegmentBase></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentBase = periodNode->SegmentBase; |
| initialization = segmentBase->Initialization; |
| assert_equals_string (initialization->sourceURL, "TestSourceURL"); |
| assert_equals_uint64 (initialization->range->first_byte_pos, 100); |
| assert_equals_uint64 (initialization->range->last_byte_pos, 200); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentBase RepresentationIndex attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_segmentBase_representationIndex) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentBaseType *segmentBase; |
| GstURLType *representationIndex; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentBase>" |
| " <RepresentationIndex sourceURL=\"TestSourceURL\"" |
| " range=\"100-200\">" |
| " </RepresentationIndex></SegmentBase></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentBase = periodNode->SegmentBase; |
| representationIndex = segmentBase->RepresentationIndex; |
| assert_equals_string (representationIndex->sourceURL, "TestSourceURL"); |
| assert_equals_uint64 (representationIndex->range->first_byte_pos, 100); |
| assert_equals_uint64 (representationIndex->range->last_byte_pos, 200); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentList attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_segmentList) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentListNode *segmentList; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period><SegmentList duration=\"1\"></SegmentList></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentList = periodNode->SegmentList; |
| fail_if (segmentList == NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentList MultipleSegmentBaseType attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_segmentList_multipleSegmentBaseType) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentListNode *segmentList; |
| GstMultSegmentBaseType *multSegBaseType; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentList duration=\"10\"" |
| " startNumber=\"11\">" |
| " </SegmentList></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentList = periodNode->SegmentList; |
| multSegBaseType = segmentList->MultSegBaseType; |
| assert_equals_uint64 (multSegBaseType->duration, 10); |
| assert_equals_uint64 (multSegBaseType->startNumber, 11); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentList MultipleSegmentBaseType SegmentBaseType |
| * attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentBaseType) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentListNode *segmentList; |
| GstMultSegmentBaseType *multSegBaseType; |
| GstSegmentBaseType *segBaseType; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentList timescale=\"10\"" |
| " duration=\"1\"" |
| " presentationTimeOffset=\"11\"" |
| " indexRange=\"20-21\"" |
| " indexRangeExact=\"false\">" |
| " </SegmentList></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentList = periodNode->SegmentList; |
| multSegBaseType = segmentList->MultSegBaseType; |
| segBaseType = multSegBaseType->SegBaseType; |
| assert_equals_uint64 (segBaseType->timescale, 10); |
| assert_equals_uint64 (segBaseType->presentationTimeOffset, 11); |
| assert_equals_uint64 (segBaseType->indexRange->first_byte_pos, 20); |
| assert_equals_uint64 (segBaseType->indexRange->last_byte_pos, 21); |
| assert_equals_int (segBaseType->indexRangeExact, FALSE); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentList MultipleSegmentBaseType SegmentTimeline |
| * attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentListNode *segmentList; |
| GstMultSegmentBaseType *multSegBaseType; |
| GstSegmentTimelineNode *segmentTimeline; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentList>" |
| " <SegmentTimeline>" |
| " </SegmentTimeline></SegmentList></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentList = periodNode->SegmentList; |
| multSegBaseType = segmentList->MultSegBaseType; |
| segmentTimeline = multSegBaseType->SegmentTimeline; |
| fail_if (segmentTimeline == NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentList MultipleSegmentBaseType SegmentTimeline S |
| * attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline_s) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentListNode *segmentList; |
| GstMultSegmentBaseType *multSegBaseType; |
| GstSegmentTimelineNode *segmentTimeline; |
| GstSNode *sNode; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentList>" |
| " <SegmentTimeline>" |
| " <S t=\"1\" d=\"2\" r=\"3\">" |
| " </S></SegmentTimeline></SegmentList></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentList = periodNode->SegmentList; |
| multSegBaseType = segmentList->MultSegBaseType; |
| segmentTimeline = multSegBaseType->SegmentTimeline; |
| sNode = (GstSNode *) g_queue_peek_head (&segmentTimeline->S); |
| assert_equals_uint64 (sNode->t, 1); |
| assert_equals_uint64 (sNode->d, 2); |
| assert_equals_uint64 (sNode->r, 3); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentList MultipleSegmentBaseType BitstreamSwitching |
| * attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_segmentList_multipleSegmentBaseType_bitstreamSwitching) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentListNode *segmentList; |
| GstMultSegmentBaseType *multSegBaseType; |
| GstURLType *bitstreamSwitching; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentList duration=\"0\">" |
| " <BitstreamSwitching sourceURL=\"TestSourceURL\"" |
| " range=\"100-200\">" |
| " </BitstreamSwitching></SegmentList></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentList = periodNode->SegmentList; |
| multSegBaseType = segmentList->MultSegBaseType; |
| bitstreamSwitching = multSegBaseType->BitstreamSwitching; |
| assert_equals_string (bitstreamSwitching->sourceURL, "TestSourceURL"); |
| assert_equals_uint64 (bitstreamSwitching->range->first_byte_pos, 100); |
| assert_equals_uint64 (bitstreamSwitching->range->last_byte_pos, 200); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentList SegmentURL attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_segmentList_segmentURL) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentListNode *segmentList; |
| GstSegmentURLNode *segmentURL; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentList duration=\"1\">" |
| " <SegmentURL media=\"TestMedia\"" |
| " mediaRange=\"100-200\"" |
| " index=\"TestIndex\"" |
| " indexRange=\"300-400\">" |
| " </SegmentURL></SegmentList></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentList = periodNode->SegmentList; |
| segmentURL = (GstSegmentURLNode *) segmentList->SegmentURL->data; |
| assert_equals_string (segmentURL->media, "TestMedia"); |
| assert_equals_uint64 (segmentURL->mediaRange->first_byte_pos, 100); |
| assert_equals_uint64 (segmentURL->mediaRange->last_byte_pos, 200); |
| assert_equals_string (segmentURL->index, "TestIndex"); |
| assert_equals_uint64 (segmentURL->indexRange->first_byte_pos, 300); |
| assert_equals_uint64 (segmentURL->indexRange->last_byte_pos, 400); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentTemplate attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_segmentTemplate) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentTemplateNode *segmentTemplate; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentTemplate media=\"TestMedia\"" |
| " duration=\"0\"" |
| " index=\"TestIndex\"" |
| " initialization=\"TestInitialization\"" |
| " bitstreamSwitching=\"TestBitstreamSwitching\">" |
| " </SegmentTemplate></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentTemplate = periodNode->SegmentTemplate; |
| assert_equals_string (segmentTemplate->media, "TestMedia"); |
| assert_equals_string (segmentTemplate->index, "TestIndex"); |
| assert_equals_string (segmentTemplate->initialization, "TestInitialization"); |
| assert_equals_string (segmentTemplate->bitstreamSwitching, |
| "TestBitstreamSwitching"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentTemplate MultipleSegmentBaseType attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentTemplateNode *segmentTemplate; |
| GstMultSegmentBaseType *multSegBaseType; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentTemplate duration=\"10\"" |
| " startNumber=\"11\">" |
| " </SegmentTemplate></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentTemplate = periodNode->SegmentTemplate; |
| multSegBaseType = segmentTemplate->MultSegBaseType; |
| assert_equals_uint64 (multSegBaseType->duration, 10); |
| assert_equals_uint64 (multSegBaseType->startNumber, 11); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentTemplate MultipleSegmentBaseType SegmentBaseType |
| * attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentBaseType) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentTemplateNode *segmentTemplate; |
| GstMultSegmentBaseType *multSegBaseType; |
| GstSegmentBaseType *segBaseType; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentTemplate timescale=\"123456\"" |
| " duration=\"1\"" |
| " presentationTimeOffset=\"123456789\"" |
| " indexRange=\"100-200\"" |
| " indexRangeExact=\"true\">" |
| " </SegmentTemplate></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentTemplate = periodNode->SegmentTemplate; |
| multSegBaseType = segmentTemplate->MultSegBaseType; |
| segBaseType = multSegBaseType->SegBaseType; |
| assert_equals_uint64 (segBaseType->timescale, 123456); |
| assert_equals_uint64 (segBaseType->presentationTimeOffset, 123456789); |
| assert_equals_uint64 (segBaseType->indexRange->first_byte_pos, 100); |
| assert_equals_uint64 (segBaseType->indexRange->last_byte_pos, 200); |
| assert_equals_int (segBaseType->indexRangeExact, TRUE); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentTemplate MultipleSegmentBaseType SegmentTimeline |
| * attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentTemplateNode *segmentTemplate; |
| GstMultSegmentBaseType *multSegBaseType; |
| GstSegmentTimelineNode *segmentTimeline; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentTemplate>" |
| " <SegmentTimeline>" |
| " </SegmentTimeline></SegmentTemplate></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentTemplate = periodNode->SegmentTemplate; |
| multSegBaseType = segmentTemplate->MultSegBaseType; |
| segmentTimeline = (GstSegmentTimelineNode *) multSegBaseType->SegmentTimeline; |
| fail_if (segmentTimeline == NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentTemplate MultipleSegmentBaseType SegmentTimeline |
| * S attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline_s) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentTemplateNode *segmentTemplate; |
| GstMultSegmentBaseType *multSegBaseType; |
| GstSegmentTimelineNode *segmentTimeline; |
| GstSNode *sNode; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentTemplate>" |
| " <SegmentTimeline>" |
| " <S t=\"1\" d=\"2\" r=\"3\">" |
| " </S></SegmentTimeline></SegmentTemplate></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentTemplate = periodNode->SegmentTemplate; |
| multSegBaseType = segmentTemplate->MultSegBaseType; |
| segmentTimeline = (GstSegmentTimelineNode *) multSegBaseType->SegmentTimeline; |
| sNode = (GstSNode *) g_queue_peek_head (&segmentTimeline->S); |
| assert_equals_uint64 (sNode->t, 1); |
| assert_equals_uint64 (sNode->d, 2); |
| assert_equals_uint64 (sNode->r, 3); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period SegmentTemplate MultipleSegmentBaseType |
| * BitstreamSwitching attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_bitstreamSwitching) |
| { |
| GstPeriodNode *periodNode; |
| GstSegmentTemplateNode *segmentTemplate; |
| GstMultSegmentBaseType *multSegBaseType; |
| GstURLType *bitstreamSwitching; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentTemplate duration=\"1\">" |
| " <BitstreamSwitching sourceURL=\"TestSourceURL\"" |
| " range=\"100-200\">" |
| " </BitstreamSwitching></SegmentTemplate></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| segmentTemplate = periodNode->SegmentTemplate; |
| multSegBaseType = segmentTemplate->MultSegBaseType; |
| bitstreamSwitching = multSegBaseType->BitstreamSwitching; |
| assert_equals_string (bitstreamSwitching->sourceURL, "TestSourceURL"); |
| assert_equals_uint64 (bitstreamSwitching->range->first_byte_pos, 100); |
| assert_equals_uint64 (bitstreamSwitching->range->last_byte_pos, 200); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet id=\"7\"" |
| " group=\"8\"" |
| " lang=\"en\"" |
| " contentType=\"TestContentType\"" |
| " par=\"4:3\"" |
| " minBandwidth=\"100\"" |
| " maxBandwidth=\"200\"" |
| " minWidth=\"1000\"" |
| " maxWidth=\"2000\"" |
| " minHeight=\"1100\"" |
| " maxHeight=\"2100\"" |
| " minFrameRate=\"25/123\"" |
| " maxFrameRate=\"26\"" |
| " segmentAlignment=\"2\"" |
| " subsegmentAlignment=\"false\"" |
| " subsegmentStartsWithSAP=\"6\"" |
| " bitstreamSwitching=\"false\">" |
| " </AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| assert_equals_uint64 (adaptationSet->id, 7); |
| assert_equals_uint64 (adaptationSet->group, 8); |
| assert_equals_string (adaptationSet->lang, "en"); |
| assert_equals_string (adaptationSet->contentType, "TestContentType"); |
| assert_equals_uint64 (adaptationSet->par->num, 4); |
| assert_equals_uint64 (adaptationSet->par->den, 3); |
| assert_equals_uint64 (adaptationSet->minBandwidth, 100); |
| assert_equals_uint64 (adaptationSet->maxBandwidth, 200); |
| assert_equals_uint64 (adaptationSet->minWidth, 1000); |
| assert_equals_uint64 (adaptationSet->maxWidth, 2000); |
| assert_equals_uint64 (adaptationSet->minHeight, 1100); |
| assert_equals_uint64 (adaptationSet->maxHeight, 2100); |
| assert_equals_uint64 (adaptationSet->RepresentationBase->minFrameRate->num, |
| 25); |
| assert_equals_uint64 (adaptationSet->RepresentationBase->minFrameRate->den, |
| 123); |
| assert_equals_uint64 (adaptationSet->RepresentationBase->maxFrameRate->num, |
| 26); |
| assert_equals_uint64 (adaptationSet->RepresentationBase->maxFrameRate->den, |
| 1); |
| assert_equals_int (adaptationSet->segmentAlignment->flag, 1); |
| assert_equals_uint64 (adaptationSet->segmentAlignment->value, 2); |
| assert_equals_int (adaptationSet->subsegmentAlignment->flag, 0); |
| assert_equals_uint64 (adaptationSet->subsegmentAlignment->value, 0); |
| assert_equals_int (adaptationSet->subsegmentStartsWithSAP, 6); |
| assert_equals_int (adaptationSet->bitstreamSwitching, 0); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet RepresentationBase attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_representationBase) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationBaseType *representationBase; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet profiles=\"TestProfiles\"" |
| " width=\"100\"" |
| " height=\"200\"" |
| " sar=\"10:20\"" |
| " frameRate=\"30/40\"" |
| " audioSamplingRate=\"TestAudioSamplingRate\"" |
| " mimeType=\"TestMimeType\"" |
| " segmentProfiles=\"TestSegmentProfiles\"" |
| " codecs=\"TestCodecs\"" |
| " maximumSAPPeriod=\"3.4\"" |
| " startWithSAP=\"0\"" |
| " maxPlayoutRate=\"1.2\"" |
| " codingDependency=\"false\"" |
| " scanType=\"progressive\">" |
| " </AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representationBase = adaptationSet->RepresentationBase; |
| assert_equals_string (representationBase->profiles, "TestProfiles"); |
| assert_equals_uint64 (representationBase->width, 100); |
| assert_equals_uint64 (representationBase->height, 200); |
| assert_equals_uint64 (representationBase->sar->num, 10); |
| assert_equals_uint64 (representationBase->sar->den, 20); |
| assert_equals_uint64 (representationBase->frameRate->num, 30); |
| assert_equals_uint64 (representationBase->frameRate->den, 40); |
| assert_equals_string (representationBase->audioSamplingRate, |
| "TestAudioSamplingRate"); |
| assert_equals_string (representationBase->mimeType, "TestMimeType"); |
| assert_equals_string (representationBase->segmentProfiles, |
| "TestSegmentProfiles"); |
| assert_equals_string (representationBase->codecs, "TestCodecs"); |
| assert_equals_float (representationBase->maximumSAPPeriod, 3.4); |
| assert_equals_int (representationBase->startWithSAP, GST_SAP_TYPE_0); |
| assert_equals_float (representationBase->maxPlayoutRate, 1.2); |
| assert_equals_float (representationBase->codingDependency, 0); |
| assert_equals_string (representationBase->scanType, "progressive"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet RepresentationBase FramePacking attributes |
| * |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_adaptationSet_representationBase_framePacking) { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationBaseType *representationBase; |
| GstDescriptorType *framePacking; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <FramePacking schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </FramePacking></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representationBase = adaptationSet->RepresentationBase; |
| framePacking = (GstDescriptorType *) representationBase->FramePacking->data; |
| assert_equals_string (framePacking->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (framePacking->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet RepresentationBase |
| * AudioChannelConfiguration attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_adaptationSet_representationBase_audioChannelConfiguration) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationBaseType *representationBase; |
| GstDescriptorType *audioChannelConfiguration; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <AudioChannelConfiguration schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </AudioChannelConfiguration></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representationBase = adaptationSet->RepresentationBase; |
| audioChannelConfiguration = |
| (GstDescriptorType *) representationBase->AudioChannelConfiguration->data; |
| assert_equals_string (audioChannelConfiguration->schemeIdUri, |
| "TestSchemeIdUri"); |
| assert_equals_string (audioChannelConfiguration->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet RepresentationBase ContentProtection |
| * attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_adaptationSet_representationBase_contentProtection) { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationBaseType *representationBase; |
| GstDescriptorType *contentProtection; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <ContentProtection schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </ContentProtection></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representationBase = adaptationSet->RepresentationBase; |
| contentProtection = |
| (GstDescriptorType *) representationBase->ContentProtection->data; |
| assert_equals_string (contentProtection->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (contentProtection->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing ContentProtection element that has no value attribute |
| */ |
| GST_START_TEST (dash_mpdparser_contentProtection_no_value) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationBaseType *representationBase; |
| GstDescriptorType *contentProtection; |
| const gchar *xml = |
| "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <ContentProtection schemeIdUri=\"urn:mpeg:dash:mp4protection:2011\" value=\"cenc\"/>" |
| " <ContentProtection xmlns:mas=\"urn:marlin:mas:1-0:services:schemas:mpd\" schemeIdUri=\"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4\">" |
| " <mas:MarlinContentIds>" |
| " <mas:MarlinContentId>urn:marlin:kid:02020202020202020202020202020202</mas:MarlinContentId>" |
| " </mas:MarlinContentIds>" |
| " </ContentProtection>" "</AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| gchar *str; |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representationBase = adaptationSet->RepresentationBase; |
| assert_equals_int (g_list_length (representationBase->ContentProtection), 2); |
| contentProtection = |
| (GstDescriptorType *) g_list_nth (representationBase->ContentProtection, |
| 1)->data; |
| assert_equals_string (contentProtection->schemeIdUri, |
| "urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4"); |
| fail_if (contentProtection->value == NULL); |
| /* We can't do a simple compare of value (which should be an XML dump |
| of the ContentProtection element), because the whitespace |
| formatting from xmlDump might differ between versions of libxml */ |
| str = strstr (contentProtection->value, "<ContentProtection"); |
| fail_if (str == NULL); |
| str = strstr (contentProtection->value, "<mas:MarlinContentIds>"); |
| fail_if (str == NULL); |
| str = strstr (contentProtection->value, "<mas:MarlinContentId>"); |
| fail_if (str == NULL); |
| str = |
| strstr (contentProtection->value, |
| "urn:marlin:kid:02020202020202020202020202020202"); |
| fail_if (str == NULL); |
| str = strstr (contentProtection->value, "</ContentProtection>"); |
| fail_if (str == NULL); |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing ContentProtection element that has no value attribute |
| * nor an XML encoding |
| */ |
| GST_START_TEST (dash_mpdparser_contentProtection_no_value_no_encoding) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationBaseType *representationBase; |
| GstDescriptorType *contentProtection; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <ContentProtection schemeIdUri=\"urn:mpeg:dash:mp4protection:2011\" value=\"cenc\"/>" |
| " <ContentProtection xmlns:mas=\"urn:marlin:mas:1-0:services:schemas:mpd\" schemeIdUri=\"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4\">" |
| " <mas:MarlinContentIds>" |
| " <mas:MarlinContentId>urn:marlin:kid:02020202020202020202020202020202</mas:MarlinContentId>" |
| " </mas:MarlinContentIds>" |
| " </ContentProtection>" "</AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representationBase = adaptationSet->RepresentationBase; |
| assert_equals_int (g_list_length (representationBase->ContentProtection), 2); |
| contentProtection = |
| (GstDescriptorType *) g_list_nth (representationBase->ContentProtection, |
| 1)->data; |
| assert_equals_string (contentProtection->schemeIdUri, |
| "urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4"); |
| fail_if (contentProtection->value == NULL); |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Accessibility attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_accessibility) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstDescriptorType *accessibility; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Accessibility schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </Accessibility></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| accessibility = (GstDescriptorType *) adaptationSet->Accessibility->data; |
| assert_equals_string (accessibility->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (accessibility->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Role attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_role) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstDescriptorType *role; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Role schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </Role></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| role = (GstDescriptorType *) adaptationSet->Role->data; |
| assert_equals_string (role->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (role->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Rating attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_rating) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstDescriptorType *rating; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Rating schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </Rating></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| rating = (GstDescriptorType *) adaptationSet->Rating->data; |
| assert_equals_string (rating->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (rating->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Viewpoint attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_viewpoint) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstDescriptorType *viewpoint; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Viewpoint schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </Viewpoint></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| viewpoint = (GstDescriptorType *) adaptationSet->Viewpoint->data; |
| assert_equals_string (viewpoint->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (viewpoint->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet ContentComponent attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstContentComponentNode *contentComponent; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <ContentComponent id=\"1\"" |
| " lang=\"en\"" |
| " contentType=\"TestContentType\"" |
| " par=\"10:20\">" |
| " </ContentComponent></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| contentComponent = (GstContentComponentNode *) |
| adaptationSet->ContentComponents->data; |
| assert_equals_uint64 (contentComponent->id, 1); |
| assert_equals_string (contentComponent->lang, "en"); |
| assert_equals_string (contentComponent->contentType, "TestContentType"); |
| assert_equals_uint64 (contentComponent->par->num, 10); |
| assert_equals_uint64 (contentComponent->par->den, 20); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet ContentComponent Accessibility attributes |
| * |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_adaptationSet_contentComponent_accessibility) { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstContentComponentNode *contentComponent; |
| GstDescriptorType *accessibility; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <ContentComponent>" |
| " <Accessibility schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </Accessibility>" |
| " </ContentComponent></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| contentComponent = (GstContentComponentNode *) |
| adaptationSet->ContentComponents->data; |
| accessibility = (GstDescriptorType *) contentComponent->Accessibility->data; |
| assert_equals_string (accessibility->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (accessibility->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet ContentComponent Role attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_role) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstContentComponentNode *contentComponent; |
| GstDescriptorType *role; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <ContentComponent>" |
| " <Role schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </Role></ContentComponent></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| contentComponent = (GstContentComponentNode *) |
| adaptationSet->ContentComponents->data; |
| role = (GstDescriptorType *) contentComponent->Role->data; |
| assert_equals_string (role->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (role->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet ContentComponent Rating attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_rating) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstContentComponentNode *contentComponent; |
| GstDescriptorType *rating; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <ContentComponent>" |
| " <Rating schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </Rating>" |
| " </ContentComponent></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| contentComponent = (GstContentComponentNode *) |
| adaptationSet->ContentComponents->data; |
| rating = (GstDescriptorType *) contentComponent->Rating->data; |
| assert_equals_string (rating->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (rating->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet ContentComponent Viewpoint attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_viewpoint) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstContentComponentNode *contentComponent; |
| GstDescriptorType *viewpoint; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <ContentComponent>" |
| " <Viewpoint schemeIdUri=\"TestSchemeIdUri\"" |
| " value=\"TestValue\">" |
| " </Viewpoint>" |
| " </ContentComponent></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| contentComponent = (GstContentComponentNode *) |
| adaptationSet->ContentComponents->data; |
| viewpoint = (GstDescriptorType *) contentComponent->Viewpoint->data; |
| assert_equals_string (viewpoint->schemeIdUri, "TestSchemeIdUri"); |
| assert_equals_string (viewpoint->value, "TestValue"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet BaseURL attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_baseURL) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| 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\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <BaseURL serviceLocation=\"TestServiceLocation\"" |
| " byteRange=\"TestByteRange\">TestBaseURL</BaseURL>" |
| " </AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| baseURL = (GstBaseURL *) adaptationSet->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 Period AdaptationSet SegmentBase attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentBase) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstSegmentBaseType *segmentBase; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <SegmentBase timescale=\"123456\"" |
| " presentationTimeOffset=\"123456789\"" |
| " indexRange=\"100-200\"" |
| " indexRangeExact=\"true\">" |
| " </SegmentBase></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| segmentBase = adaptationSet->SegmentBase; |
| assert_equals_uint64 (segmentBase->timescale, 123456); |
| assert_equals_uint64 (segmentBase->presentationTimeOffset, 123456789); |
| assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 100); |
| assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 200); |
| assert_equals_int (segmentBase->indexRangeExact, TRUE); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet SegmentBase Initialization attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentBase_initialization) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstSegmentBaseType *segmentBase; |
| GstURLType *initialization; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <SegmentBase>" |
| " <Initialisation sourceURL=\"TestSourceURL\"" |
| " range=\"100-200\">" |
| " </Initialisation></SegmentBase></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| segmentBase = adaptationSet->SegmentBase; |
| initialization = segmentBase->Initialization; |
| assert_equals_string (initialization->sourceURL, "TestSourceURL"); |
| assert_equals_uint64 (initialization->range->first_byte_pos, 100); |
| assert_equals_uint64 (initialization->range->last_byte_pos, 200); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet SegmentBase RepresentationIndex attributes |
| * |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_adaptationSet_segmentBase_representationIndex) { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstSegmentBaseType *segmentBase; |
| GstURLType *representationIndex; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <SegmentBase>" |
| " <RepresentationIndex sourceURL=\"TestSourceURL\"" |
| " range=\"100-200\">" |
| " </RepresentationIndex>" |
| " </SegmentBase></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| segmentBase = adaptationSet->SegmentBase; |
| representationIndex = segmentBase->RepresentationIndex; |
| assert_equals_string (representationIndex->sourceURL, "TestSourceURL"); |
| assert_equals_uint64 (representationIndex->range->first_byte_pos, 100); |
| assert_equals_uint64 (representationIndex->range->last_byte_pos, 200); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet SegmentList attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentList) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstSegmentListNode *segmentList; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <SegmentList duration=\"1\"></SegmentList></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| segmentList = adaptationSet->SegmentList; |
| fail_if (segmentList == NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet SegmentTemplate attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentTemplate) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstSegmentTemplateNode *segmentTemplate; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <SegmentTemplate media=\"TestMedia\"" |
| " duration=\"1\"" |
| " index=\"TestIndex\"" |
| " initialization=\"TestInitialization\"" |
| " bitstreamSwitching=\"TestBitstreamSwitching\">" |
| " </SegmentTemplate></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| segmentTemplate = adaptationSet->SegmentTemplate; |
| assert_equals_string (segmentTemplate->media, "TestMedia"); |
| assert_equals_string (segmentTemplate->index, "TestIndex"); |
| assert_equals_string (segmentTemplate->initialization, "TestInitialization"); |
| assert_equals_string (segmentTemplate->bitstreamSwitching, |
| "TestBitstreamSwitching"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| |
| /* |
| * Test parsing Period AdaptationSet SegmentTemplate attributes with |
| * inheritance |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentTemplate_inherit) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstSegmentTemplateNode *segmentTemplate; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <SegmentTemplate media=\"ParentMedia\" duration=\"1\" " |
| " initialization=\"ParentInitialization\">" |
| " </SegmentTemplate>" |
| " <AdaptationSet>" |
| " <SegmentTemplate media=\"TestMedia\"" |
| " duration=\"1\"" |
| " index=\"TestIndex\"" |
| " bitstreamSwitching=\"TestBitstreamSwitching\">" |
| " </SegmentTemplate></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| segmentTemplate = adaptationSet->SegmentTemplate; |
| assert_equals_string (segmentTemplate->media, "TestMedia"); |
| assert_equals_string (segmentTemplate->index, "TestIndex"); |
| assert_equals_string (segmentTemplate->initialization, |
| "ParentInitialization"); |
| assert_equals_string (segmentTemplate->bitstreamSwitching, |
| "TestBitstreamSwitching"); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Representation attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_representation) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationNode *representation; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Representation id=\"Test_Id\"" |
| " bandwidth=\"100\"" |
| " qualityRanking=\"200\"" |
| " dependencyId=\"one two three\"" |
| " mediaStreamStructureId=\"\">" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representation = (GstRepresentationNode *) |
| adaptationSet->Representations->data; |
| assert_equals_string (representation->id, "Test_Id"); |
| assert_equals_uint64 (representation->bandwidth, 100); |
| assert_equals_uint64 (representation->qualityRanking, 200); |
| assert_equals_string (representation->dependencyId[0], "one"); |
| assert_equals_string (representation->dependencyId[1], "two"); |
| assert_equals_string (representation->dependencyId[2], "three"); |
| assert_equals_pointer (representation->dependencyId[3], NULL); |
| assert_equals_pointer (representation->mediaStreamStructureId[0], NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Representation RepresentationBaseType attributes |
| * |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_adaptationSet_representation_representationBase) { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationNode *representation; |
| GstRepresentationBaseType *representationBase; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Representation>" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representation = (GstRepresentationNode *) |
| adaptationSet->Representations->data; |
| representationBase = (GstRepresentationBaseType *) |
| representation->RepresentationBase; |
| fail_if (representationBase == NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Representation BaseURL attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_baseURL) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationNode *representation; |
| 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\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Representation>" |
| " <BaseURL serviceLocation=\"TestServiceLocation\"" |
| " byteRange=\"TestByteRange\">TestBaseURL</BaseURL>" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representation = (GstRepresentationNode *) |
| adaptationSet->Representations->data; |
| baseURL = (GstBaseURL *) representation->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 Period AdaptationSet Representation SubRepresentation attributes |
| * |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_adaptationSet_representation_subRepresentation) { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationNode *representation; |
| GstSubRepresentationNode *subRepresentation; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Representation>" |
| " <SubRepresentation level=\"100\"" |
| " dependencyLevel=\"1 2 3\"" |
| " bandwidth=\"200\"" |
| " contentComponent=\"content1 content2\">" |
| " </SubRepresentation>" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representation = (GstRepresentationNode *) |
| adaptationSet->Representations->data; |
| subRepresentation = (GstSubRepresentationNode *) |
| representation->SubRepresentations->data; |
| assert_equals_uint64 (subRepresentation->level, 100); |
| assert_equals_uint64 (subRepresentation->size, 3); |
| assert_equals_uint64 (subRepresentation->dependencyLevel[0], 1); |
| assert_equals_uint64 (subRepresentation->dependencyLevel[1], 2); |
| assert_equals_uint64 (subRepresentation->dependencyLevel[2], 3); |
| assert_equals_uint64 (subRepresentation->bandwidth, 200); |
| assert_equals_string (subRepresentation->contentComponent[0], "content1"); |
| assert_equals_string (subRepresentation->contentComponent[1], "content2"); |
| assert_equals_pointer (subRepresentation->contentComponent[2], NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Representation SubRepresentation |
| * RepresentationBase attributes |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_adaptationSet_representation_subRepresentation_representationBase) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationNode *representation; |
| GstSubRepresentationNode *subRepresentation; |
| GstRepresentationBaseType *representationBase; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Representation>" |
| " <SubRepresentation>" |
| " </SubRepresentation>" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representation = (GstRepresentationNode *) |
| adaptationSet->Representations->data; |
| subRepresentation = (GstSubRepresentationNode *) |
| representation->SubRepresentations->data; |
| representationBase = (GstRepresentationBaseType *) |
| subRepresentation->RepresentationBase; |
| fail_if (representationBase == NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Representation SegmentBase attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_segmentBase) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationNode *representation; |
| GstSegmentBaseType *segmentBase; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Representation>" |
| " <SegmentBase>" |
| " </SegmentBase>" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representation = (GstRepresentationNode *) |
| adaptationSet->Representations->data; |
| segmentBase = representation->SegmentBase; |
| fail_if (segmentBase == NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Representation SegmentList attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_segmentList) |
| { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationNode *representation; |
| GstSegmentListNode *segmentList; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Representation>" |
| " <SegmentList duration=\"1\">" |
| " </SegmentList>" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representation = (GstRepresentationNode *) |
| adaptationSet->Representations->data; |
| segmentList = representation->SegmentList; |
| fail_if (segmentList == NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period AdaptationSet Representation SegmentTemplate attributes |
| * |
| */ |
| GST_START_TEST |
| (dash_mpdparser_period_adaptationSet_representation_segmentTemplate) { |
| GstPeriodNode *periodNode; |
| GstAdaptationSetNode *adaptationSet; |
| GstRepresentationNode *representation; |
| GstSegmentTemplateNode *segmentTemplate; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period>" |
| " <AdaptationSet>" |
| " <Representation>" |
| " <SegmentTemplate duration=\"1\">" |
| " </SegmentTemplate>" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data; |
| representation = (GstRepresentationNode *) |
| adaptationSet->Representations->data; |
| segmentTemplate = representation->SegmentTemplate; |
| fail_if (segmentTemplate == NULL); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing Period Subset attributes |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_subset) |
| { |
| GstPeriodNode *periodNode; |
| GstSubsetNode *subset; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period><Subset contains=\"1 2 3\"></Subset></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data; |
| subset = (GstSubsetNode *) periodNode->Subsets->data; |
| assert_equals_uint64 (subset->size, 3); |
| assert_equals_uint64 (subset->contains[0], 1); |
| assert_equals_uint64 (subset->contains[1], 2); |
| assert_equals_uint64 (subset->contains[2], 3); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing UTCTiming elements |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_utctiming) |
| { |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:http-xsdate:2014\" value=\"http://time.akamai.com/?iso http://example.time/xsdate\"/>" |
| "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:direct:2014\" value=\"2002-05-30T09:30:10Z \"/>" |
| "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:ntp:2014\" value=\"0.europe.pool.ntp.org 1.europe.pool.ntp.org 2.europe.pool.ntp.org 3.europe.pool.ntp.org\"/>" |
| "</MPD>"; |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| GstMPDUTCTimingType selected_method; |
| gchar **urls; |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| |
| assert_equals_int (ret, TRUE); |
| fail_if (mpdclient->mpd_node == NULL); |
| fail_if (mpdclient->mpd_node->UTCTiming == NULL); |
| assert_equals_int (g_list_length (mpdclient->mpd_node->UTCTiming), 3); |
| urls = |
| gst_mpd_client_get_utc_timing_sources (mpdclient, |
| GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE, &selected_method); |
| fail_if (urls == NULL); |
| assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE); |
| assert_equals_int (g_strv_length (urls), 2); |
| assert_equals_string (urls[0], "http://time.akamai.com/?iso"); |
| assert_equals_string (urls[1], "http://example.time/xsdate"); |
| urls = |
| gst_mpd_client_get_utc_timing_sources (mpdclient, |
| GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE | GST_MPD_UTCTIMING_TYPE_HTTP_ISO, |
| &selected_method); |
| fail_if (urls == NULL); |
| assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE); |
| urls = |
| gst_mpd_client_get_utc_timing_sources (mpdclient, |
| GST_MPD_UTCTIMING_TYPE_DIRECT, NULL); |
| fail_if (urls == NULL); |
| assert_equals_int (g_strv_length (urls), 1); |
| assert_equals_string (urls[0], "2002-05-30T09:30:10Z "); |
| urls = |
| gst_mpd_client_get_utc_timing_sources (mpdclient, |
| GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE | GST_MPD_UTCTIMING_TYPE_DIRECT, |
| &selected_method); |
| fail_if (urls == NULL); |
| assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE); |
| urls = |
| gst_mpd_client_get_utc_timing_sources (mpdclient, |
| GST_MPD_UTCTIMING_TYPE_NTP, &selected_method); |
| fail_if (urls == NULL); |
| assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_NTP); |
| assert_equals_int (g_strv_length (urls), 4); |
| assert_equals_string (urls[0], "0.europe.pool.ntp.org"); |
| assert_equals_string (urls[1], "1.europe.pool.ntp.org"); |
| assert_equals_string (urls[2], "2.europe.pool.ntp.org"); |
| assert_equals_string (urls[3], "3.europe.pool.ntp.org"); |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing invalid UTCTiming values: |
| * - elements with no schemeIdUri property should be rejected |
| * - elements with no value property should be rejected |
| * - elements with unrecognised UTCTiming scheme should be rejected |
| * - elements with empty values should be rejected |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_utctiming_invalid_value) |
| { |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| "<UTCTiming invalid_schemeIdUri=\"dummy.uri.scheme\" value=\"dummy value\"/>" |
| "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:ntp:2014\" invalid_value=\"dummy value\"/>" |
| "<UTCTiming schemeIdUri=\"dummy.uri.scheme\" value=\"dummy value\"/>" |
| "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:ntp:2014\" value=\"\"/>" |
| "</MPD>"; |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| |
| assert_equals_int (ret, TRUE); |
| fail_if (mpdclient->mpd_node == NULL); |
| fail_if (mpdclient->mpd_node->UTCTiming != NULL); |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test parsing the type property: value "dynamic" |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_type_dynamic) |
| { |
| gboolean isLive; |
| |
| 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, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| isLive = gst_mpd_client_is_live (mpdclient); |
| assert_equals_int (isLive, 1); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Validate gst_mpdparser_build_URL_from_template function |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_template_parsing) |
| { |
| const gchar *id = "TestId"; |
| guint number = 7; |
| guint bandwidth = 2500; |
| guint64 time = 100; |
| gchar *result; |
| |
| struct TestUrl |
| { |
| const gchar *urlTemplate; |
| const gchar *expectedResponse; |
| }; |
| |
| /* various test scenarios to attempt */ |
| struct TestUrl testUrl[] = { |
| {"", NULL}, /* empty string for template */ |
| {"$$", "$"}, /* escaped $ */ |
| {"Number", "Number"}, /* string similar with an identifier, but without $ */ |
| {"Number$Number$", "Number7"}, /* Number identifier */ |
| {"Number$Number$$$", "Number7$"}, /* Number identifier followed by $$ */ |
| {"Number$Number$Number$Number$", "Number7Number7"}, /* series of "Number" string and Number identifier */ |
| {"Representation$RepresentationID$", "RepresentationTestId"}, /* RepresentationID identifier */ |
| {"TestMedia$Bandwidth$$$test", "TestMedia2500$test"}, /* Bandwidth identifier */ |
| {"TestMedia$Time$", "TestMedia100"}, /* Time identifier */ |
| {"TestMedia$Time", NULL}, /* Identifier not finished with $ */ |
| {"Time$Time%d$", NULL}, /* usage of %d (no width) */ |
| {"Time$Time%0d$", "Time100"}, /* usage of format smaller than number of digits */ |
| {"Time$Time%01d$", "Time100"}, /* usage of format smaller than number of digits */ |
| {"Time$Time%05d$", "Time00100"}, /* usage of format bigger than number of digits */ |
| {"Time$Time%05dtest$", "Time00100test"}, /* usage extra text in format */ |
| {"Time$Time%3d$", NULL}, /* incorrect format: width does not start with 0 */ |
| {"Time$Time%0-4d$", NULL}, /* incorrect format: width is not a number */ |
| {"Time$Time%0$", NULL}, /* incorrect format: no d, x or u */ |
| {"Time$Time1%01d$", NULL}, /* incorrect format: does not start with % after identifier */ |
| {"$Bandwidth%/init.mp4v", NULL}, /* incorrect identifier: not finished with $ */ |
| {"$Number%/$Time$.mp4v", NULL}, /* incorrect number of $ separators */ |
| {"$RepresentationID1$", NULL}, /* incorrect identifier */ |
| {"$Bandwidth1$", NULL}, /* incorrect identifier */ |
| {"$Number1$", NULL}, /* incorrect identifier */ |
| {"$RepresentationID%01d$", NULL}, /* incorrect format: RepresentationID does not support formatting */ |
| {"Time$Time%05u$", NULL}, /* %u format */ |
| {"Time$Time%05x$", NULL}, /* %x format */ |
| {"Time$Time%05utest$", NULL}, /* %u format followed by text */ |
| {"Time$Time%05xtest$", NULL}, /* %x format followed by text */ |
| {"Time$Time%05xtest%$", NULL}, /* second % character in format */ |
| }; |
| |
| guint count = sizeof (testUrl) / sizeof (testUrl[0]); |
| for (int i = 0; i < count; i++) { |
| result = |
| gst_mpdparser_build_URL_from_template (testUrl[i].urlTemplate, id, |
| number, bandwidth, time); |
| assert_equals_string (result, testUrl[i].expectedResponse); |
| g_free (result); |
| } |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test handling isoff ondemand profile |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_isoff_ondemand_profile) |
| { |
| gboolean hasOnDemandProfile; |
| |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| hasOnDemandProfile = gst_mpd_client_has_isoff_ondemand_profile (mpdclient); |
| assert_equals_int (hasOnDemandProfile, 1); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test handling GstDateTime |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_GstDateTime) |
| { |
| gint64 delta; |
| GstDateTime *time1; |
| GstDateTime *time2; |
| GstDateTime *time3; |
| GDateTime *g_time2; |
| GDateTime *g_time3; |
| |
| time1 = gst_date_time_new_from_iso8601_string ("2012-06-23T23:30:59Z"); |
| time2 = gst_date_time_new_from_iso8601_string ("2012-06-23T23:31:00Z"); |
| |
| delta = gst_mpd_client_calculate_time_difference (time1, time2); |
| assert_equals_int64 (delta, 1 * GST_SECOND); |
| |
| time3 = |
| gst_mpd_client_add_time_difference (time1, GST_TIME_AS_USECONDS (delta)); |
| |
| /* convert to GDateTime in order to compare time2 and time 3 */ |
| g_time2 = gst_date_time_to_g_date_time (time2); |
| g_time3 = gst_date_time_to_g_date_time (time3); |
| fail_if (g_date_time_compare (g_time2, g_time3) != 0); |
| |
| gst_date_time_unref (time1); |
| gst_date_time_unref (time2); |
| gst_date_time_unref (time3); |
| g_date_time_unref (g_time2); |
| g_date_time_unref (g_time3); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test bitstreamSwitching inheritance from Period to AdaptationSet |
| * |
| * Description of bistreamSwitching attribute in Period: |
| * "When set to ‘true’, this is equivalent as if the |
| * AdaptationSet@bitstreamSwitching for each Adaptation Set contained in this |
| * Period is set to 'true'. In this case, the AdaptationSet@bitstreamSwitching |
| * attribute shall not be set to 'false' for any Adaptation Set in this Period" |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_bitstreamSwitching_inheritance) |
| { |
| GList *adaptationSets; |
| GstAdaptationSetNode *adapt_set; |
| guint activeStreams; |
| GstActiveStream *activeStream; |
| GstCaps *caps; |
| GstStructure *s; |
| gboolean bitstreamSwitchingFlag; |
| |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period id=\"Period0\"" |
| " duration=\"P0Y0M1DT1H1M1S\"" |
| " bitstreamSwitching=\"true\">" |
| " <AdaptationSet id=\"1\"" |
| " mimeType=\"video/mp4\">" |
| " <Representation>" |
| " </Representation>" |
| " </AdaptationSet>" |
| " <AdaptationSet id=\"2\"" |
| " mimeType=\"audio\"" |
| " bitstreamSwitching=\"false\">" |
| " <Representation>" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| /* process the xml data */ |
| ret = gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE, |
| -1, NULL); |
| assert_equals_int (ret, TRUE); |
| |
| /* get the list of adaptation sets of the first period */ |
| adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient); |
| fail_if (adaptationSets == NULL); |
| |
| /* setup streaming from the first adaptation set */ |
| adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0); |
| fail_if (adapt_set == NULL); |
| ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set); |
| assert_equals_int (ret, TRUE); |
| |
| /* setup streaming from the second adaptation set */ |
| adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 1); |
| fail_if (adapt_set == NULL); |
| ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set); |
| assert_equals_int (ret, TRUE); |
| |
| /* 2 active streams */ |
| activeStreams = gst_mpdparser_get_nb_active_stream (mpdclient); |
| assert_equals_int (activeStreams, 2); |
| |
| /* get details of the first active stream */ |
| activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0); |
| fail_if (activeStream == NULL); |
| |
| assert_equals_int (activeStream->mimeType, GST_STREAM_VIDEO); |
| caps = gst_mpd_client_get_stream_caps (activeStream); |
| fail_unless (caps != NULL); |
| s = gst_caps_get_structure (caps, 0); |
| assert_equals_string (gst_structure_get_name (s), "video/quicktime"); |
| gst_caps_unref (caps); |
| |
| /* inherited from Period's bitstreamSwitching */ |
| bitstreamSwitchingFlag = |
| gst_mpd_client_get_bitstream_switching_flag (activeStream); |
| assert_equals_int (bitstreamSwitchingFlag, TRUE); |
| |
| /* get details of the second active stream */ |
| activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 1); |
| fail_if (activeStream == NULL); |
| |
| assert_equals_int (activeStream->mimeType, GST_STREAM_AUDIO); |
| caps = gst_mpd_client_get_stream_caps (activeStream); |
| fail_unless (caps != NULL); |
| s = gst_caps_get_structure (caps, 0); |
| assert_equals_string (gst_structure_get_name (s), "audio"); |
| gst_caps_unref (caps); |
| |
| /* set to FALSE in our example, but overwritten to TRUE by Period's |
| * bitstreamSwitching |
| */ |
| bitstreamSwitchingFlag = |
| gst_mpd_client_get_bitstream_switching_flag (activeStream); |
| assert_equals_int (bitstreamSwitchingFlag, TRUE); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test various duration formats |
| */ |
| GST_START_TEST (dash_mpdparser_various_duration_formats) |
| { |
| GstPeriodNode *periodNode; |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"" |
| " availabilityStartTime=\"2015-03-24T0:0:0\"" |
| " mediaPresentationDuration=\"P100Y\">" |
| " <Period id=\"Period0\" start=\"PT1S\"></Period>" |
| " <Period id=\"Period1\" start=\"PT1.5S\"></Period>" |
| " <Period id=\"Period2\" start=\"PT1,7S\"></Period>" |
| " <Period id=\"Period3\" start=\"PT1M\"></Period>" |
| " <Period id=\"Period4\" start=\"PT1H\"></Period>" |
| " <Period id=\"Period5\" start=\"P1D\"></Period>" |
| " <Period id=\"Period6\" start=\"P1M\"></Period>" |
| " <Period id=\"Period7\" start=\"P1Y\"></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| ret = |
| gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE, |
| -1, NULL); |
| assert_equals_int (ret, TRUE); |
| |
| periodNode = |
| (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 0); |
| assert_equals_string (periodNode->id, "Period0"); |
| assert_equals_uint64 (periodNode->start, |
| duration_to_ms (0, 0, 0, 0, 0, 1, 0)); |
| |
| periodNode = |
| (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 1); |
| assert_equals_string (periodNode->id, "Period1"); |
| assert_equals_uint64 (periodNode->start, |
| duration_to_ms (0, 0, 0, 0, 0, 1, 500)); |
| |
| periodNode = |
| (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 2); |
| assert_equals_string (periodNode->id, "Period2"); |
| assert_equals_uint64 (periodNode->start, |
| duration_to_ms (0, 0, 0, 0, 0, 1, 700)); |
| |
| periodNode = |
| (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 3); |
| assert_equals_string (periodNode->id, "Period3"); |
| assert_equals_uint64 (periodNode->start, |
| duration_to_ms (0, 0, 0, 0, 1, 0, 0)); |
| |
| periodNode = |
| (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 4); |
| assert_equals_string (periodNode->id, "Period4"); |
| assert_equals_uint64 (periodNode->start, |
| duration_to_ms (0, 0, 0, 1, 0, 0, 0)); |
| |
| periodNode = |
| (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 5); |
| assert_equals_string (periodNode->id, "Period5"); |
| assert_equals_uint64 (periodNode->start, |
| duration_to_ms (0, 0, 1, 0, 0, 0, 0)); |
| |
| periodNode = |
| (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 6); |
| assert_equals_string (periodNode->id, "Period6"); |
| assert_equals_uint64 (periodNode->start, |
| duration_to_ms (0, 1, 0, 0, 0, 0, 0)); |
| |
| periodNode = |
| (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 7); |
| assert_equals_string (periodNode->id, "Period7"); |
| assert_equals_uint64 (periodNode->start, |
| duration_to_ms (1, 0, 0, 0, 0, 0, 0)); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test media presentation setup |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_setup_media_presentation) |
| { |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period id=\"Period0\"" |
| " duration=\"P0Y0M1DT1H1M1S\"></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| /* process the xml data */ |
| ret = |
| gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE, |
| -1, NULL); |
| assert_equals_int (ret, TRUE); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test setting a stream |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_setup_streaming) |
| { |
| GList *adaptationSets; |
| GstAdaptationSetNode *adapt_set; |
| |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period id=\"Period0\"" |
| " duration=\"P0Y0M1DT1H1M1S\">" |
| " <AdaptationSet id=\"1\"" |
| " mimeType=\"video/mp4\">" |
| " <Representation>" |
| " </Representation></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| /* process the xml data */ |
| ret = |
| gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE, |
| -1, NULL); |
| assert_equals_int (ret, TRUE); |
| |
| /* get the first adaptation set of the first period */ |
| adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient); |
| fail_if (adaptationSets == NULL); |
| adapt_set = (GstAdaptationSetNode *) adaptationSets->data; |
| fail_if (adapt_set == NULL); |
| |
| /* setup streaming from the adaptation set */ |
| ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set); |
| assert_equals_int (ret, TRUE); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test handling Period selection |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_period_selection) |
| { |
| const gchar *periodName; |
| guint periodIndex; |
| |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"" |
| " mediaPresentationDuration=\"P0Y0M1DT1H4M3S\">" |
| " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\"></Period>" |
| " <Period id=\"Period1\"></Period>" |
| " <Period id=\"Period2\" start=\"P0Y0M1DT1H3M3S\"></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| /* period_idx should be 0 and we should have no active periods */ |
| assert_equals_uint64 (mpdclient->period_idx, 0); |
| fail_unless (mpdclient->periods == NULL); |
| |
| /* process the xml data */ |
| ret = |
| gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE, |
| -1, NULL); |
| assert_equals_int (ret, TRUE); |
| |
| /* check the periods */ |
| fail_unless (mpdclient->periods != NULL); |
| periodName = gst_mpd_client_get_period_id (mpdclient); |
| assert_equals_string (periodName, "Period0"); |
| |
| ret = gst_mpd_client_set_period_index (mpdclient, 1); |
| assert_equals_int (ret, TRUE); |
| periodName = gst_mpd_client_get_period_id (mpdclient); |
| assert_equals_string (periodName, "Period1"); |
| |
| ret = gst_mpd_client_set_period_index (mpdclient, 2); |
| assert_equals_int (ret, TRUE); |
| periodName = gst_mpd_client_get_period_id (mpdclient); |
| assert_equals_string (periodName, "Period2"); |
| |
| ret = gst_mpd_client_has_next_period (mpdclient); |
| assert_equals_int (ret, FALSE); |
| ret = gst_mpd_client_has_previous_period (mpdclient); |
| assert_equals_int (ret, TRUE); |
| |
| ret = gst_mpd_client_set_period_index (mpdclient, 0); |
| assert_equals_int (ret, TRUE); |
| ret = gst_mpd_client_has_next_period (mpdclient); |
| assert_equals_int (ret, TRUE); |
| ret = gst_mpd_client_has_previous_period (mpdclient); |
| assert_equals_int (ret, FALSE); |
| |
| ret = gst_mpd_client_set_period_id (mpdclient, "Period1"); |
| assert_equals_int (ret, TRUE); |
| periodIndex = gst_mpd_client_get_period_index (mpdclient); |
| assert_equals_uint64 (periodIndex, 1); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test handling Period selection based on time |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_get_period_at_time) |
| { |
| guint periodIndex; |
| GstDateTime *time; |
| |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"" |
| " availabilityStartTime=\"2015-03-24T0:0:0\"" |
| " mediaPresentationDuration=\"P0Y0M1DT1H4M3S\">" |
| " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\"></Period>" |
| " <Period id=\"Period1\"></Period>" |
| " <Period id=\"Period2\" start=\"P0Y0M1DT1H3M3S\"></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| /* process the xml data */ |
| ret = |
| gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE, |
| -1, NULL); |
| assert_equals_int (ret, TRUE); |
| |
| /* request period for a time before availabilityStartTime, expect period index 0 */ |
| time = gst_date_time_new_from_iso8601_string ("2015-03-23T23:30:59Z"); |
| periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time); |
| gst_date_time_unref (time); |
| assert_equals_int (periodIndex, 0); |
| |
| /* request period for a time from period 0 */ |
| time = gst_date_time_new_from_iso8601_string ("2015-03-24T23:30:59Z"); |
| periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time); |
| gst_date_time_unref (time); |
| assert_equals_int (periodIndex, 0); |
| |
| /* request period for a time from period 1 */ |
| time = gst_date_time_new_from_iso8601_string ("2015-03-25T1:1:1Z"); |
| periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time); |
| gst_date_time_unref (time); |
| assert_equals_int (periodIndex, 1); |
| |
| /* request period for a time from period 2 */ |
| time = gst_date_time_new_from_iso8601_string ("2015-03-25T1:3:3Z"); |
| periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time); |
| gst_date_time_unref (time); |
| assert_equals_int (periodIndex, 2); |
| |
| /* request period for a time after mediaPresentationDuration, expect period index G_MAXUINT */ |
| time = gst_date_time_new_from_iso8601_string ("2015-03-25T1:4:3Z"); |
| periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time); |
| gst_date_time_unref (time); |
| assert_equals_int (periodIndex, G_MAXUINT); |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test handling Adaptation sets |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_adaptationSet_handling) |
| { |
| const gchar *periodName; |
| guint adaptation_sets_count; |
| GList *adaptationSets; |
| guint count = 0; |
| |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">" |
| " <AdaptationSet id=\"1\"></AdaptationSet>" |
| " </Period>" |
| " <Period id=\"Period1\" duration=\"P0Y0M1DT1H1M1S\">" |
| " <AdaptationSet id=\"10\"></AdaptationSet>" |
| " <AdaptationSet id=\"11\"></AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| /* process the xml data */ |
| ret = |
| gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE, |
| -1, NULL); |
| assert_equals_int (ret, TRUE); |
| |
| /* period0 has 1 adaptation set */ |
| fail_unless (mpdclient->periods != NULL); |
| periodName = gst_mpd_client_get_period_id (mpdclient); |
| assert_equals_string (periodName, "Period0"); |
| adaptation_sets_count = gst_mpdparser_get_nb_adaptationSet (mpdclient); |
| assert_equals_int (adaptation_sets_count, 1); |
| |
| /* period1 has 2 adaptation set */ |
| ret = gst_mpd_client_set_period_id (mpdclient, "Period1"); |
| assert_equals_int (ret, TRUE); |
| adaptation_sets_count = gst_mpdparser_get_nb_adaptationSet (mpdclient); |
| assert_equals_int (adaptation_sets_count, 2); |
| |
| /* check the id for the 2 adaptation sets from period 1 */ |
| adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient); |
| fail_if (adaptationSets == NULL); |
| |
| for (GList * it = adaptationSets; it; it = g_list_next (it)) { |
| GstAdaptationSetNode *adapt_set; |
| adapt_set = (GstAdaptationSetNode *) it->data; |
| fail_if (adapt_set == NULL); |
| |
| assert_equals_int (adapt_set->id, 10 + count); |
| count++; |
| } |
| |
| gst_mpd_client_free (mpdclient); |
| } |
| |
| GST_END_TEST; |
| |
| /* |
| * Test handling Representation selection |
| * |
| */ |
| GST_START_TEST (dash_mpdparser_representation_selection) |
| { |
| GList *adaptationSets; |
| GstAdaptationSetNode *adaptationSetNode; |
| GList *representations; |
| gint represendationIndex; |
| |
| const gchar *xml = |
| "<?xml version=\"1.0\"?>" |
| "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"" |
| " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">" |
| " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">" |
| " <AdaptationSet id=\"1\" mimeType=\"video/mp4\">" |
| " <Representation id=\"v0\" bandwidth=\"500000\"></Representation>" |
| " <Representation id=\"v1\" bandwidth=\"250000\"></Representation>" |
| " </AdaptationSet></Period></MPD>"; |
| |
| gboolean ret; |
| GstMpdClient *mpdclient = gst_mpd_client_new (); |
| |
| ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml)); |
| assert_equals_int (ret, TRUE); |
| |
| /* process the xml data */ |
| ret = |
| gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE, |
| -1, NULL); |
| assert_equals_int (ret, TRUE); |
| |
| adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient); |
| fail_if (adaptationSets == NULL); |
| |
| adaptationSetNode = adaptationSets->data; |
| fail_if (adaptationSetNode == NULL); |
| assert_equals_int (adaptationSetNode->id, 1); |
| |
| representations = adaptationSetNode->Representations; |
| fail_if (representations == NULL); |
| |
|