1 /* GStreamer unit test for MPEG-DASH
3 * Copyright (c) <2015> YouView TV Ltd
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
21 #include "../../ext/dash/gstmpdparser.c"
22 #undef GST_CAT_DEFAULT
24 #include <gst/check/gstcheck.h>
26 GST_DEBUG_CATEGORY (gst_dash_demux_debug);
29 * compute the number of milliseconds contained in a duration value specified by
30 * year, month, day, hour, minute, second, millisecond
32 * This function must use the same conversion algorithm implemented in
33 * gst_mpdparser_get_xml_prop_duration from gstmpdparser.c file.
36 duration_to_ms (guint year, guint month, guint day, guint hour, guint minute,
37 guint second, guint millisecond)
39 guint64 days = (guint64) year * 365 + (guint64) month * 30 + day;
40 guint64 hours = days * 24 + hour;
41 guint64 minutes = hours * 60 + minute;
42 guint64 seconds = minutes * 60 + second;
43 guint64 ms = seconds * 1000 + millisecond;
48 duration_to_clocktime (guint year, guint month, guint day, guint hour,
49 guint minute, guint second, guint millisecond)
51 return (GST_MSECOND * duration_to_ms (year, month, day, hour, minute, second,
56 * Test to ensure a simple mpd file successfully parses.
59 GST_START_TEST (dash_mpdparser_validsimplempd)
62 "<?xml version=\"1.0\"?>"
63 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
64 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"> </MPD>";
67 GstMpdClient *mpdclient = gst_mpd_client_new ();
69 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
70 assert_equals_int (ret, TRUE);
72 /* check that unset elements with default values are properly configured */
73 assert_equals_int (mpdclient->mpd_node->type, GST_MPD_FILE_TYPE_STATIC);
75 gst_mpd_client_free (mpdclient);
81 * Test parsing the MPD attributes.
84 GST_START_TEST (dash_mpdparser_mpd)
86 GstDateTime *availabilityStartTime;
87 GstDateTime *availabilityEndTime;
89 "<?xml version=\"1.0\"?>"
90 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
91 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
92 " schemaLocation=\"TestSchemaLocation\""
93 " xmlns:xsi=\"TestNamespaceXSI\""
94 " xmlns:ext=\"TestNamespaceEXT\""
97 " availabilityStartTime=\"2015-03-24T1:10:50\""
98 " availabilityEndTime=\"2015-03-24T1:10:50.123456\""
99 " mediaPresentationDuration=\"P0Y1M2DT12H10M20.5S\""
100 " minimumUpdatePeriod=\"P0Y1M2DT12H10M20.5S\""
101 " minBufferTime=\"P0Y1M2DT12H10M20.5S\""
102 " timeShiftBufferDepth=\"P0Y1M2DT12H10M20.5S\""
103 " suggestedPresentationDelay=\"P0Y1M2DT12H10M20.5S\""
104 " maxSegmentDuration=\"P0Y1M2DT12H10M20.5S\""
105 " maxSubsegmentDuration=\"P0Y1M2DT12H10M20.5S\"></MPD>";
108 GstMpdClient *mpdclient = gst_mpd_client_new ();
110 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
111 assert_equals_int (ret, TRUE);
113 assert_equals_string (mpdclient->mpd_node->default_namespace,
114 "urn:mpeg:dash:schema:mpd:2011");
115 assert_equals_string (mpdclient->mpd_node->namespace_xsi, "TestNamespaceXSI");
116 assert_equals_string (mpdclient->mpd_node->namespace_ext, "TestNamespaceEXT");
117 assert_equals_string (mpdclient->mpd_node->schemaLocation,
118 "TestSchemaLocation");
119 assert_equals_string (mpdclient->mpd_node->id, "testId");
121 assert_equals_int (mpdclient->mpd_node->type, GST_MPD_FILE_TYPE_STATIC);
123 availabilityStartTime = mpdclient->mpd_node->availabilityStartTime;
124 assert_equals_int (gst_date_time_get_year (availabilityStartTime), 2015);
125 assert_equals_int (gst_date_time_get_month (availabilityStartTime), 3);
126 assert_equals_int (gst_date_time_get_day (availabilityStartTime), 24);
127 assert_equals_int (gst_date_time_get_hour (availabilityStartTime), 1);
128 assert_equals_int (gst_date_time_get_minute (availabilityStartTime), 10);
129 assert_equals_int (gst_date_time_get_second (availabilityStartTime), 50);
130 assert_equals_int (gst_date_time_get_microsecond (availabilityStartTime), 0);
132 availabilityEndTime = mpdclient->mpd_node->availabilityEndTime;
133 assert_equals_int (gst_date_time_get_year (availabilityEndTime), 2015);
134 assert_equals_int (gst_date_time_get_month (availabilityEndTime), 3);
135 assert_equals_int (gst_date_time_get_day (availabilityEndTime), 24);
136 assert_equals_int (gst_date_time_get_hour (availabilityEndTime), 1);
137 assert_equals_int (gst_date_time_get_minute (availabilityEndTime), 10);
138 assert_equals_int (gst_date_time_get_second (availabilityEndTime), 50);
139 assert_equals_int (gst_date_time_get_microsecond (availabilityEndTime),
142 assert_equals_uint64 (mpdclient->mpd_node->mediaPresentationDuration,
143 duration_to_ms (0, 1, 2, 12, 10, 20, 500));
145 assert_equals_uint64 (mpdclient->mpd_node->minimumUpdatePeriod,
146 duration_to_ms (0, 1, 2, 12, 10, 20, 500));
148 assert_equals_uint64 (mpdclient->mpd_node->minBufferTime,
149 duration_to_ms (0, 1, 2, 12, 10, 20, 500));
151 assert_equals_uint64 (mpdclient->mpd_node->timeShiftBufferDepth,
152 duration_to_ms (0, 1, 2, 12, 10, 20, 500));
154 assert_equals_uint64 (mpdclient->mpd_node->suggestedPresentationDelay,
155 duration_to_ms (0, 1, 2, 12, 10, 20, 500));
157 assert_equals_uint64 (mpdclient->mpd_node->maxSegmentDuration,
158 duration_to_ms (0, 1, 2, 12, 10, 20, 500));
160 assert_equals_uint64 (mpdclient->mpd_node->maxSubsegmentDuration,
161 duration_to_ms (0, 1, 2, 12, 10, 20, 500));
163 gst_mpd_client_free (mpdclient);
169 * Test parsing the ProgramInformation attributes
172 GST_START_TEST (dash_mpdparser_programInformation)
174 GstProgramInformationNode *program;
176 "<?xml version=\"1.0\"?>"
177 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
178 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
179 " <ProgramInformation lang=\"en\""
180 " moreInformationURL=\"TestMoreInformationUrl\">"
181 " <Title>TestTitle</Title>"
182 " <Source>TestSource</Source>"
183 " <Copyright>TestCopyright</Copyright>"
184 " </ProgramInformation> </MPD>";
187 GstMpdClient *mpdclient = gst_mpd_client_new ();
189 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
190 assert_equals_int (ret, TRUE);
193 (GstProgramInformationNode *) mpdclient->mpd_node->ProgramInfo->data;
194 assert_equals_string (program->lang, "en");
195 assert_equals_string (program->moreInformationURL, "TestMoreInformationUrl");
196 assert_equals_string (program->Title, "TestTitle");
197 assert_equals_string (program->Source, "TestSource");
198 assert_equals_string (program->Copyright, "TestCopyright");
200 gst_mpd_client_free (mpdclient);
206 * Test parsing the BaseURL attributes
209 GST_START_TEST (dash_mpdparser_baseURL)
213 "<?xml version=\"1.0\"?>"
214 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
215 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
216 " <BaseURL serviceLocation=\"TestServiceLocation\""
217 " byteRange=\"TestByteRange\">TestBaseURL</BaseURL></MPD>";
220 GstMpdClient *mpdclient = gst_mpd_client_new ();
222 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
223 assert_equals_int (ret, TRUE);
225 baseURL = (GstBaseURL *) mpdclient->mpd_node->BaseURLs->data;
226 assert_equals_string (baseURL->baseURL, "TestBaseURL");
227 assert_equals_string (baseURL->serviceLocation, "TestServiceLocation");
228 assert_equals_string (baseURL->byteRange, "TestByteRange");
230 gst_mpd_client_free (mpdclient);
236 * Test parsing the Location attributes
239 GST_START_TEST (dash_mpdparser_location)
241 const gchar *location;
243 "<?xml version=\"1.0\"?>"
244 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
245 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
246 " <Location>TestLocation</Location></MPD>";
249 GstMpdClient *mpdclient = gst_mpd_client_new ();
251 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
252 assert_equals_int (ret, TRUE);
254 location = (gchar *) mpdclient->mpd_node->Locations->data;
255 assert_equals_string (location, "TestLocation");
257 gst_mpd_client_free (mpdclient);
263 * Test parsing Metrics attributes
266 GST_START_TEST (dash_mpdparser_metrics)
268 GstMetricsNode *metricsNode;
270 "<?xml version=\"1.0\"?>"
271 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
272 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
273 " <Metrics metrics=\"TestMetric\"></Metrics></MPD>";
276 GstMpdClient *mpdclient = gst_mpd_client_new ();
278 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
279 assert_equals_int (ret, TRUE);
281 metricsNode = (GstMetricsNode *) mpdclient->mpd_node->Metrics->data;
282 assert_equals_string (metricsNode->metrics, "TestMetric");
284 gst_mpd_client_free (mpdclient);
290 * Test parsing Metrics Range attributes
293 GST_START_TEST (dash_mpdparser_metrics_range)
295 GstMetricsNode *metricsNode;
296 GstMetricsRangeNode *metricsRangeNode;
298 "<?xml version=\"1.0\"?>"
299 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
300 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
302 " <Range starttime=\"P0Y1M2DT12H10M20.5S\""
303 " duration=\"P0Y1M2DT12H10M20.1234567S\">"
304 " </Range></Metrics></MPD>";
307 GstMpdClient *mpdclient = gst_mpd_client_new ();
309 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
310 assert_equals_int (ret, TRUE);
312 metricsNode = (GstMetricsNode *) mpdclient->mpd_node->Metrics->data;
313 assert_equals_pointer (metricsNode->metrics, NULL);
314 metricsRangeNode = (GstMetricsRangeNode *) metricsNode->MetricsRanges->data;
315 assert_equals_uint64 (metricsRangeNode->starttime,
316 duration_to_ms (0, 1, 2, 12, 10, 20, 500));
317 assert_equals_uint64 (metricsRangeNode->duration,
318 duration_to_ms (0, 1, 2, 12, 10, 20, 123));
320 gst_mpd_client_free (mpdclient);
326 * Test parsing Metrics Reporting attributes
329 GST_START_TEST (dash_mpdparser_metrics_reporting)
331 GstMetricsNode *metricsNode;
333 "<?xml version=\"1.0\"?>"
334 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
335 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
336 " <Metrics><Reporting></Reporting></Metrics></MPD>";
339 GstMpdClient *mpdclient = gst_mpd_client_new ();
341 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
342 assert_equals_int (ret, TRUE);
344 metricsNode = (GstMetricsNode *) mpdclient->mpd_node->Metrics->data;
345 assert_equals_pointer (metricsNode->metrics, NULL);
347 gst_mpd_client_free (mpdclient);
353 * Test parsing Period attributes
356 GST_START_TEST (dash_mpdparser_period)
358 GstPeriodNode *periodNode;
360 "<?xml version=\"1.0\"?>"
361 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
362 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
363 " <Period id=\"TestId\""
364 " start=\"P0Y1M2DT12H10M20.1234567S\""
365 " duration=\"P0Y1M2DT12H10M20.7654321S\""
366 " bitstreamSwitching=\"true\"></Period></MPD>";
369 GstMpdClient *mpdclient = gst_mpd_client_new ();
371 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
372 assert_equals_int (ret, TRUE);
374 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
375 assert_equals_string (periodNode->id, "TestId");
376 assert_equals_uint64 (periodNode->start,
377 duration_to_ms (0, 1, 2, 12, 10, 20, 123));
378 assert_equals_uint64 (periodNode->duration,
379 duration_to_ms (0, 1, 2, 12, 10, 20, 765));
380 assert_equals_int (periodNode->bitstreamSwitching, 1);
382 gst_mpd_client_free (mpdclient);
388 * Test parsing Period baseURL attributes
391 GST_START_TEST (dash_mpdparser_period_baseURL)
393 GstPeriodNode *periodNode;
396 "<?xml version=\"1.0\"?>"
397 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
398 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
400 " <BaseURL serviceLocation=\"TestServiceLocation\""
401 " byteRange=\"TestByteRange\">TestBaseURL</BaseURL>"
405 GstMpdClient *mpdclient = gst_mpd_client_new ();
407 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
408 assert_equals_int (ret, TRUE);
410 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
411 baseURL = (GstBaseURL *) periodNode->BaseURLs->data;
412 assert_equals_string (baseURL->baseURL, "TestBaseURL");
413 assert_equals_string (baseURL->serviceLocation, "TestServiceLocation");
414 assert_equals_string (baseURL->byteRange, "TestByteRange");
416 gst_mpd_client_free (mpdclient);
422 * Test parsing Period SegmentBase attributes
425 GST_START_TEST (dash_mpdparser_period_segmentBase)
427 GstPeriodNode *periodNode;
428 GstSegmentBaseType *segmentBase;
430 "<?xml version=\"1.0\"?>"
431 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
432 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
434 " <SegmentBase timescale=\"123456\""
435 " presentationTimeOffset=\"123456789\""
436 " indexRange=\"100-200\""
437 " indexRangeExact=\"true\">"
438 " </SegmentBase></Period></MPD>";
441 GstMpdClient *mpdclient = gst_mpd_client_new ();
443 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
444 assert_equals_int (ret, TRUE);
446 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
447 segmentBase = periodNode->SegmentBase;
448 assert_equals_uint64 (segmentBase->timescale, 123456);
449 assert_equals_uint64 (segmentBase->presentationTimeOffset, 123456789);
450 assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 100);
451 assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 200);
452 assert_equals_int (segmentBase->indexRangeExact, 1);
454 gst_mpd_client_free (mpdclient);
460 * Test parsing Period SegmentBase Initialization attributes
463 GST_START_TEST (dash_mpdparser_period_segmentBase_initialization)
465 GstPeriodNode *periodNode;
466 GstSegmentBaseType *segmentBase;
467 GstURLType *initialization;
469 "<?xml version=\"1.0\"?>"
470 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
471 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
474 " <Initialisation sourceURL=\"TestSourceURL\""
475 " range=\"100-200\">"
476 " </Initialisation></SegmentBase></Period></MPD>";
479 GstMpdClient *mpdclient = gst_mpd_client_new ();
481 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
482 assert_equals_int (ret, TRUE);
484 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
485 segmentBase = periodNode->SegmentBase;
486 initialization = segmentBase->Initialization;
487 assert_equals_string (initialization->sourceURL, "TestSourceURL");
488 assert_equals_uint64 (initialization->range->first_byte_pos, 100);
489 assert_equals_uint64 (initialization->range->last_byte_pos, 200);
491 gst_mpd_client_free (mpdclient);
497 * Test parsing Period SegmentBase RepresentationIndex attributes
500 GST_START_TEST (dash_mpdparser_period_segmentBase_representationIndex)
502 GstPeriodNode *periodNode;
503 GstSegmentBaseType *segmentBase;
504 GstURLType *representationIndex;
506 "<?xml version=\"1.0\"?>"
507 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
508 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
511 " <RepresentationIndex sourceURL=\"TestSourceURL\""
512 " range=\"100-200\">"
513 " </RepresentationIndex></SegmentBase></Period></MPD>";
516 GstMpdClient *mpdclient = gst_mpd_client_new ();
518 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
519 assert_equals_int (ret, TRUE);
521 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
522 segmentBase = periodNode->SegmentBase;
523 representationIndex = segmentBase->RepresentationIndex;
524 assert_equals_string (representationIndex->sourceURL, "TestSourceURL");
525 assert_equals_uint64 (representationIndex->range->first_byte_pos, 100);
526 assert_equals_uint64 (representationIndex->range->last_byte_pos, 200);
528 gst_mpd_client_free (mpdclient);
534 * Test parsing Period SegmentList attributes
537 GST_START_TEST (dash_mpdparser_period_segmentList)
539 GstPeriodNode *periodNode;
540 GstSegmentListNode *segmentList;
542 "<?xml version=\"1.0\"?>"
543 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
544 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
545 " <Period><SegmentList duration=\"1\"></SegmentList></Period></MPD>";
548 GstMpdClient *mpdclient = gst_mpd_client_new ();
550 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
551 assert_equals_int (ret, TRUE);
553 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
554 segmentList = periodNode->SegmentList;
555 fail_if (segmentList == NULL);
557 gst_mpd_client_free (mpdclient);
563 * Test parsing Period SegmentList MultipleSegmentBaseType attributes
566 GST_START_TEST (dash_mpdparser_period_segmentList_multipleSegmentBaseType)
568 GstPeriodNode *periodNode;
569 GstSegmentListNode *segmentList;
570 GstMultSegmentBaseType *multSegBaseType;
572 "<?xml version=\"1.0\"?>"
573 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
574 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
576 " <SegmentList duration=\"10\""
577 " startNumber=\"11\">"
578 " </SegmentList></Period></MPD>";
581 GstMpdClient *mpdclient = gst_mpd_client_new ();
583 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
584 assert_equals_int (ret, TRUE);
586 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
587 segmentList = periodNode->SegmentList;
588 multSegBaseType = segmentList->MultSegBaseType;
589 assert_equals_uint64 (multSegBaseType->duration, 10);
590 assert_equals_uint64 (multSegBaseType->startNumber, 11);
592 gst_mpd_client_free (mpdclient);
598 * Test parsing Period SegmentList MultipleSegmentBaseType SegmentBaseType
602 (dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentBaseType)
604 GstPeriodNode *periodNode;
605 GstSegmentListNode *segmentList;
606 GstMultSegmentBaseType *multSegBaseType;
607 GstSegmentBaseType *segBaseType;
609 "<?xml version=\"1.0\"?>"
610 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
611 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
613 " <SegmentList timescale=\"10\""
615 " presentationTimeOffset=\"11\""
616 " indexRange=\"20-21\""
617 " indexRangeExact=\"false\">"
618 " </SegmentList></Period></MPD>";
621 GstMpdClient *mpdclient = gst_mpd_client_new ();
623 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
624 assert_equals_int (ret, TRUE);
626 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
627 segmentList = periodNode->SegmentList;
628 multSegBaseType = segmentList->MultSegBaseType;
629 segBaseType = multSegBaseType->SegBaseType;
630 assert_equals_uint64 (segBaseType->timescale, 10);
631 assert_equals_uint64 (segBaseType->presentationTimeOffset, 11);
632 assert_equals_uint64 (segBaseType->indexRange->first_byte_pos, 20);
633 assert_equals_uint64 (segBaseType->indexRange->last_byte_pos, 21);
634 assert_equals_int (segBaseType->indexRangeExact, FALSE);
636 gst_mpd_client_free (mpdclient);
642 * Test parsing Period SegmentList MultipleSegmentBaseType SegmentTimeline
646 (dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline)
648 GstPeriodNode *periodNode;
649 GstSegmentListNode *segmentList;
650 GstMultSegmentBaseType *multSegBaseType;
651 GstSegmentTimelineNode *segmentTimeline;
653 "<?xml version=\"1.0\"?>"
654 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
655 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
659 " </SegmentTimeline></SegmentList></Period></MPD>";
662 GstMpdClient *mpdclient = gst_mpd_client_new ();
664 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
665 assert_equals_int (ret, TRUE);
667 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
668 segmentList = periodNode->SegmentList;
669 multSegBaseType = segmentList->MultSegBaseType;
670 segmentTimeline = multSegBaseType->SegmentTimeline;
671 fail_if (segmentTimeline == NULL);
673 gst_mpd_client_free (mpdclient);
679 * Test parsing Period SegmentList MultipleSegmentBaseType SegmentTimeline S
683 (dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline_s)
685 GstPeriodNode *periodNode;
686 GstSegmentListNode *segmentList;
687 GstMultSegmentBaseType *multSegBaseType;
688 GstSegmentTimelineNode *segmentTimeline;
691 "<?xml version=\"1.0\"?>"
692 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
693 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
697 " <S t=\"1\" d=\"2\" r=\"3\">"
698 " </S></SegmentTimeline></SegmentList></Period></MPD>";
701 GstMpdClient *mpdclient = gst_mpd_client_new ();
703 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
704 assert_equals_int (ret, TRUE);
706 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
707 segmentList = periodNode->SegmentList;
708 multSegBaseType = segmentList->MultSegBaseType;
709 segmentTimeline = multSegBaseType->SegmentTimeline;
710 sNode = (GstSNode *) g_queue_peek_head (&segmentTimeline->S);
711 assert_equals_uint64 (sNode->t, 1);
712 assert_equals_uint64 (sNode->d, 2);
713 assert_equals_uint64 (sNode->r, 3);
715 gst_mpd_client_free (mpdclient);
721 * Test parsing Period SegmentList MultipleSegmentBaseType BitstreamSwitching
725 (dash_mpdparser_period_segmentList_multipleSegmentBaseType_bitstreamSwitching)
727 GstPeriodNode *periodNode;
728 GstSegmentListNode *segmentList;
729 GstMultSegmentBaseType *multSegBaseType;
730 GstURLType *bitstreamSwitching;
732 "<?xml version=\"1.0\"?>"
733 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
734 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
736 " <SegmentList duration=\"0\">"
737 " <BitstreamSwitching sourceURL=\"TestSourceURL\""
738 " range=\"100-200\">"
739 " </BitstreamSwitching></SegmentList></Period></MPD>";
742 GstMpdClient *mpdclient = gst_mpd_client_new ();
744 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
745 assert_equals_int (ret, TRUE);
747 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
748 segmentList = periodNode->SegmentList;
749 multSegBaseType = segmentList->MultSegBaseType;
750 bitstreamSwitching = multSegBaseType->BitstreamSwitching;
751 assert_equals_string (bitstreamSwitching->sourceURL, "TestSourceURL");
752 assert_equals_uint64 (bitstreamSwitching->range->first_byte_pos, 100);
753 assert_equals_uint64 (bitstreamSwitching->range->last_byte_pos, 200);
755 gst_mpd_client_free (mpdclient);
761 * Test parsing Period SegmentList SegmentURL attributes
764 GST_START_TEST (dash_mpdparser_period_segmentList_segmentURL)
766 GstPeriodNode *periodNode;
767 GstSegmentListNode *segmentList;
768 GstSegmentURLNode *segmentURL;
770 "<?xml version=\"1.0\"?>"
771 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
772 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
774 " <SegmentList duration=\"1\">"
775 " <SegmentURL media=\"TestMedia\""
776 " mediaRange=\"100-200\""
777 " index=\"TestIndex\""
778 " indexRange=\"300-400\">"
779 " </SegmentURL></SegmentList></Period></MPD>";
782 GstMpdClient *mpdclient = gst_mpd_client_new ();
784 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
785 assert_equals_int (ret, TRUE);
787 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
788 segmentList = periodNode->SegmentList;
789 segmentURL = (GstSegmentURLNode *) segmentList->SegmentURL->data;
790 assert_equals_string (segmentURL->media, "TestMedia");
791 assert_equals_uint64 (segmentURL->mediaRange->first_byte_pos, 100);
792 assert_equals_uint64 (segmentURL->mediaRange->last_byte_pos, 200);
793 assert_equals_string (segmentURL->index, "TestIndex");
794 assert_equals_uint64 (segmentURL->indexRange->first_byte_pos, 300);
795 assert_equals_uint64 (segmentURL->indexRange->last_byte_pos, 400);
797 gst_mpd_client_free (mpdclient);
803 * Test parsing Period SegmentTemplate attributes
806 GST_START_TEST (dash_mpdparser_period_segmentTemplate)
808 GstPeriodNode *periodNode;
809 GstSegmentTemplateNode *segmentTemplate;
811 "<?xml version=\"1.0\"?>"
812 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
813 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
815 " <SegmentTemplate media=\"TestMedia\""
817 " index=\"TestIndex\""
818 " initialization=\"TestInitialization\""
819 " bitstreamSwitching=\"TestBitstreamSwitching\">"
820 " </SegmentTemplate></Period></MPD>";
823 GstMpdClient *mpdclient = gst_mpd_client_new ();
825 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
826 assert_equals_int (ret, TRUE);
828 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
829 segmentTemplate = periodNode->SegmentTemplate;
830 assert_equals_string (segmentTemplate->media, "TestMedia");
831 assert_equals_string (segmentTemplate->index, "TestIndex");
832 assert_equals_string (segmentTemplate->initialization, "TestInitialization");
833 assert_equals_string (segmentTemplate->bitstreamSwitching,
834 "TestBitstreamSwitching");
836 gst_mpd_client_free (mpdclient);
842 * Test parsing Period SegmentTemplate attributes where a
843 * presentationTimeOffset attribute has been specified
846 GST_START_TEST (dash_mpdparser_period_segmentTemplateWithPresentationTimeOffset)
849 "<?xml version=\"1.0\"?>"
850 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
851 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
852 " <Period start=\"PT1M\" duration=\"PT40S\">"
854 " bitstreamSwitching=\"false\""
855 " mimeType=\"video/mp4\""
856 " contentType=\"video\">"
857 " <SegmentTemplate media=\"$RepresentationID$/TestMedia-$Time$.mp4\""
858 " index=\"$RepresentationID$/TestIndex.mp4\""
860 " presentationTimeOffset=\"6000\""
861 " initialization=\"$RepresentationID$/TestInitialization\""
862 " bitstreamSwitching=\"true\">"
864 " <S d=\"400\" r=\"9\" t=\"100\"/>"
865 " </SegmentTimeline></SegmentTemplate>"
866 " <Representation bandwidth=\"95866\" frameRate=\"90000/3600\""
867 " id=\"vrep\" /></AdaptationSet></Period></MPD>";
870 GList *adaptationSets;
871 GstAdaptationSetNode *adapt_set;
872 GstActiveStream *activeStream;
873 GstMediaFragmentInfo fragment;
874 GstClockTime expectedDuration;
875 GstClockTime expectedTimestamp;
876 GstMpdClient *mpdclient;
877 GstPeriodNode *periodNode;
878 GstSegmentTemplateNode *segmentTemplate;
880 mpdclient = gst_mpd_client_new ();
881 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
882 assert_equals_int (ret, TRUE);
885 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
887 assert_equals_int (ret, TRUE);
890 (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 0);
891 fail_if (periodNode == NULL);
893 /* get the list of adaptation sets of the first period */
894 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
895 fail_if (adaptationSets == NULL);
897 /* setup streaming from the first adaptation set */
898 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
899 fail_if (adapt_set == NULL);
900 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
901 assert_equals_int (ret, TRUE);
902 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
903 fail_if (activeStream == NULL);
905 segmentTemplate = adapt_set->SegmentTemplate;
906 fail_if (segmentTemplate == NULL);
907 assert_equals_string (segmentTemplate->media,
908 "$RepresentationID$/TestMedia-$Time$.mp4");
909 assert_equals_string (segmentTemplate->index,
910 "$RepresentationID$/TestIndex.mp4");
911 assert_equals_string (segmentTemplate->initialization,
912 "$RepresentationID$/TestInitialization");
913 assert_equals_string (segmentTemplate->bitstreamSwitching, "true");
915 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
916 assert_equals_int (ret, TRUE);
917 expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 4, 0);
918 /* start = Period@start + S@t - presentationTimeOffset */
919 expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 1, 0);
920 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
921 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
922 /* the $Time$ expansion uses the @t value, without including
923 Period@start or presentationTimeOffset */
924 assert_equals_string (fragment.uri, "/vrep/TestMedia-100.mp4");
925 gst_media_fragment_info_clear (&fragment);
927 gst_mpd_client_free (mpdclient);
933 * Test parsing Period SegmentTemplate MultipleSegmentBaseType attributes
936 GST_START_TEST (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType)
938 GstPeriodNode *periodNode;
939 GstSegmentTemplateNode *segmentTemplate;
940 GstMultSegmentBaseType *multSegBaseType;
942 "<?xml version=\"1.0\"?>"
943 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
944 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
946 " <SegmentTemplate duration=\"10\""
947 " startNumber=\"11\">"
948 " </SegmentTemplate></Period></MPD>";
951 GstMpdClient *mpdclient = gst_mpd_client_new ();
953 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
954 assert_equals_int (ret, TRUE);
956 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
957 segmentTemplate = periodNode->SegmentTemplate;
958 multSegBaseType = segmentTemplate->MultSegBaseType;
959 assert_equals_uint64 (multSegBaseType->duration, 10);
960 assert_equals_uint64 (multSegBaseType->startNumber, 11);
962 gst_mpd_client_free (mpdclient);
968 * Test parsing Period SegmentTemplate MultipleSegmentBaseType SegmentBaseType
972 (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentBaseType)
974 GstPeriodNode *periodNode;
975 GstSegmentTemplateNode *segmentTemplate;
976 GstMultSegmentBaseType *multSegBaseType;
977 GstSegmentBaseType *segBaseType;
979 "<?xml version=\"1.0\"?>"
980 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
981 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
983 " <SegmentTemplate timescale=\"123456\""
985 " presentationTimeOffset=\"123456789\""
986 " indexRange=\"100-200\""
987 " indexRangeExact=\"true\">"
988 " </SegmentTemplate></Period></MPD>";
991 GstMpdClient *mpdclient = gst_mpd_client_new ();
993 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
994 assert_equals_int (ret, TRUE);
996 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
997 segmentTemplate = periodNode->SegmentTemplate;
998 multSegBaseType = segmentTemplate->MultSegBaseType;
999 segBaseType = multSegBaseType->SegBaseType;
1000 assert_equals_uint64 (segBaseType->timescale, 123456);
1001 assert_equals_uint64 (segBaseType->presentationTimeOffset, 123456789);
1002 assert_equals_uint64 (segBaseType->indexRange->first_byte_pos, 100);
1003 assert_equals_uint64 (segBaseType->indexRange->last_byte_pos, 200);
1004 assert_equals_int (segBaseType->indexRangeExact, TRUE);
1006 gst_mpd_client_free (mpdclient);
1012 * Test parsing Period SegmentTemplate MultipleSegmentBaseType SegmentTimeline
1016 (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline)
1018 GstPeriodNode *periodNode;
1019 GstSegmentTemplateNode *segmentTemplate;
1020 GstMultSegmentBaseType *multSegBaseType;
1021 GstSegmentTimelineNode *segmentTimeline;
1023 "<?xml version=\"1.0\"?>"
1024 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1025 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1027 " <SegmentTemplate>"
1028 " <SegmentTimeline>"
1029 " </SegmentTimeline></SegmentTemplate></Period></MPD>";
1032 GstMpdClient *mpdclient = gst_mpd_client_new ();
1034 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1035 assert_equals_int (ret, TRUE);
1037 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1038 segmentTemplate = periodNode->SegmentTemplate;
1039 multSegBaseType = segmentTemplate->MultSegBaseType;
1040 segmentTimeline = (GstSegmentTimelineNode *) multSegBaseType->SegmentTimeline;
1041 fail_if (segmentTimeline == NULL);
1043 gst_mpd_client_free (mpdclient);
1049 * Test parsing Period SegmentTemplate MultipleSegmentBaseType SegmentTimeline
1053 (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline_s)
1055 GstPeriodNode *periodNode;
1056 GstSegmentTemplateNode *segmentTemplate;
1057 GstMultSegmentBaseType *multSegBaseType;
1058 GstSegmentTimelineNode *segmentTimeline;
1061 "<?xml version=\"1.0\"?>"
1062 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1063 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1065 " <SegmentTemplate>"
1066 " <SegmentTimeline>"
1067 " <S t=\"1\" d=\"2\" r=\"3\">"
1068 " </S></SegmentTimeline></SegmentTemplate></Period></MPD>";
1071 GstMpdClient *mpdclient = gst_mpd_client_new ();
1073 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1074 assert_equals_int (ret, TRUE);
1076 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1077 segmentTemplate = periodNode->SegmentTemplate;
1078 multSegBaseType = segmentTemplate->MultSegBaseType;
1079 segmentTimeline = (GstSegmentTimelineNode *) multSegBaseType->SegmentTimeline;
1080 sNode = (GstSNode *) g_queue_peek_head (&segmentTimeline->S);
1081 assert_equals_uint64 (sNode->t, 1);
1082 assert_equals_uint64 (sNode->d, 2);
1083 assert_equals_uint64 (sNode->r, 3);
1085 gst_mpd_client_free (mpdclient);
1091 * Test parsing Period SegmentTemplate MultipleSegmentBaseType
1092 * BitstreamSwitching attributes
1095 (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_bitstreamSwitching)
1097 GstPeriodNode *periodNode;
1098 GstSegmentTemplateNode *segmentTemplate;
1099 GstMultSegmentBaseType *multSegBaseType;
1100 GstURLType *bitstreamSwitching;
1102 "<?xml version=\"1.0\"?>"
1103 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1104 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1106 " <SegmentTemplate duration=\"1\">"
1107 " <BitstreamSwitching sourceURL=\"TestSourceURL\""
1108 " range=\"100-200\">"
1109 " </BitstreamSwitching></SegmentTemplate></Period></MPD>";
1112 GstMpdClient *mpdclient = gst_mpd_client_new ();
1114 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1115 assert_equals_int (ret, TRUE);
1117 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1118 segmentTemplate = periodNode->SegmentTemplate;
1119 multSegBaseType = segmentTemplate->MultSegBaseType;
1120 bitstreamSwitching = multSegBaseType->BitstreamSwitching;
1121 assert_equals_string (bitstreamSwitching->sourceURL, "TestSourceURL");
1122 assert_equals_uint64 (bitstreamSwitching->range->first_byte_pos, 100);
1123 assert_equals_uint64 (bitstreamSwitching->range->last_byte_pos, 200);
1125 gst_mpd_client_free (mpdclient);
1131 * Test parsing Period AdaptationSet attributes
1134 GST_START_TEST (dash_mpdparser_period_adaptationSet)
1136 GstPeriodNode *periodNode;
1137 GstAdaptationSetNode *adaptationSet;
1139 "<?xml version=\"1.0\"?>"
1140 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1141 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1143 " <AdaptationSet id=\"7\""
1146 " contentType=\"TestContentType\""
1148 " minBandwidth=\"100\""
1149 " maxBandwidth=\"200\""
1150 " minWidth=\"1000\""
1151 " maxWidth=\"2000\""
1152 " minHeight=\"1100\""
1153 " maxHeight=\"2100\""
1154 " minFrameRate=\"25/123\""
1155 " maxFrameRate=\"26\""
1156 " segmentAlignment=\"2\""
1157 " subsegmentAlignment=\"false\""
1158 " subsegmentStartsWithSAP=\"6\""
1159 " bitstreamSwitching=\"false\">"
1160 " </AdaptationSet></Period></MPD>";
1163 GstMpdClient *mpdclient = gst_mpd_client_new ();
1165 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1166 assert_equals_int (ret, TRUE);
1168 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1169 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1170 assert_equals_uint64 (adaptationSet->id, 7);
1171 assert_equals_uint64 (adaptationSet->group, 8);
1172 assert_equals_string (adaptationSet->lang, "en");
1173 assert_equals_string (adaptationSet->contentType, "TestContentType");
1174 assert_equals_uint64 (adaptationSet->par->num, 4);
1175 assert_equals_uint64 (adaptationSet->par->den, 3);
1176 assert_equals_uint64 (adaptationSet->minBandwidth, 100);
1177 assert_equals_uint64 (adaptationSet->maxBandwidth, 200);
1178 assert_equals_uint64 (adaptationSet->minWidth, 1000);
1179 assert_equals_uint64 (adaptationSet->maxWidth, 2000);
1180 assert_equals_uint64 (adaptationSet->minHeight, 1100);
1181 assert_equals_uint64 (adaptationSet->maxHeight, 2100);
1182 assert_equals_uint64 (adaptationSet->RepresentationBase->minFrameRate->num,
1184 assert_equals_uint64 (adaptationSet->RepresentationBase->minFrameRate->den,
1186 assert_equals_uint64 (adaptationSet->RepresentationBase->maxFrameRate->num,
1188 assert_equals_uint64 (adaptationSet->RepresentationBase->maxFrameRate->den,
1190 assert_equals_int (adaptationSet->segmentAlignment->flag, 1);
1191 assert_equals_uint64 (adaptationSet->segmentAlignment->value, 2);
1192 assert_equals_int (adaptationSet->subsegmentAlignment->flag, 0);
1193 assert_equals_uint64 (adaptationSet->subsegmentAlignment->value, 0);
1194 assert_equals_int (adaptationSet->subsegmentStartsWithSAP, 6);
1195 assert_equals_int (adaptationSet->bitstreamSwitching, 0);
1197 gst_mpd_client_free (mpdclient);
1203 * Test parsing Period AdaptationSet RepresentationBase attributes
1206 GST_START_TEST (dash_mpdparser_period_adaptationSet_representationBase)
1208 GstPeriodNode *periodNode;
1209 GstAdaptationSetNode *adaptationSet;
1210 GstRepresentationBaseType *representationBase;
1212 "<?xml version=\"1.0\"?>"
1213 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1214 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1216 " <AdaptationSet profiles=\"TestProfiles\""
1220 " frameRate=\"30/40\""
1221 " audioSamplingRate=\"TestAudioSamplingRate\""
1222 " mimeType=\"TestMimeType\""
1223 " segmentProfiles=\"TestSegmentProfiles\""
1224 " codecs=\"TestCodecs\""
1225 " maximumSAPPeriod=\"3.4\""
1226 " startWithSAP=\"0\""
1227 " maxPlayoutRate=\"1.2\""
1228 " codingDependency=\"false\""
1229 " scanType=\"progressive\">"
1230 " </AdaptationSet></Period></MPD>";
1233 GstMpdClient *mpdclient = gst_mpd_client_new ();
1235 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1236 assert_equals_int (ret, TRUE);
1238 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1239 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1240 representationBase = adaptationSet->RepresentationBase;
1241 assert_equals_string (representationBase->profiles, "TestProfiles");
1242 assert_equals_uint64 (representationBase->width, 100);
1243 assert_equals_uint64 (representationBase->height, 200);
1244 assert_equals_uint64 (representationBase->sar->num, 10);
1245 assert_equals_uint64 (representationBase->sar->den, 20);
1246 assert_equals_uint64 (representationBase->frameRate->num, 30);
1247 assert_equals_uint64 (representationBase->frameRate->den, 40);
1248 assert_equals_string (representationBase->audioSamplingRate,
1249 "TestAudioSamplingRate");
1250 assert_equals_string (representationBase->mimeType, "TestMimeType");
1251 assert_equals_string (representationBase->segmentProfiles,
1252 "TestSegmentProfiles");
1253 assert_equals_string (representationBase->codecs, "TestCodecs");
1254 assert_equals_float (representationBase->maximumSAPPeriod, 3.4);
1255 assert_equals_int (representationBase->startWithSAP, GST_SAP_TYPE_0);
1256 assert_equals_float (representationBase->maxPlayoutRate, 1.2);
1257 assert_equals_float (representationBase->codingDependency, 0);
1258 assert_equals_string (representationBase->scanType, "progressive");
1260 gst_mpd_client_free (mpdclient);
1266 * Test parsing Period AdaptationSet RepresentationBase FramePacking attributes
1270 (dash_mpdparser_period_adaptationSet_representationBase_framePacking) {
1271 GstPeriodNode *periodNode;
1272 GstAdaptationSetNode *adaptationSet;
1273 GstRepresentationBaseType *representationBase;
1274 GstDescriptorType *framePacking;
1276 "<?xml version=\"1.0\"?>"
1277 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1278 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1281 " <FramePacking schemeIdUri=\"TestSchemeIdUri\""
1282 " value=\"TestValue\">"
1283 " </FramePacking></AdaptationSet></Period></MPD>";
1286 GstMpdClient *mpdclient = gst_mpd_client_new ();
1288 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1289 assert_equals_int (ret, TRUE);
1291 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1292 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1293 representationBase = adaptationSet->RepresentationBase;
1294 framePacking = (GstDescriptorType *) representationBase->FramePacking->data;
1295 assert_equals_string (framePacking->schemeIdUri, "TestSchemeIdUri");
1296 assert_equals_string (framePacking->value, "TestValue");
1298 gst_mpd_client_free (mpdclient);
1304 * Test parsing Period AdaptationSet RepresentationBase
1305 * AudioChannelConfiguration attributes
1308 (dash_mpdparser_period_adaptationSet_representationBase_audioChannelConfiguration)
1310 GstPeriodNode *periodNode;
1311 GstAdaptationSetNode *adaptationSet;
1312 GstRepresentationBaseType *representationBase;
1313 GstDescriptorType *audioChannelConfiguration;
1315 "<?xml version=\"1.0\"?>"
1316 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1317 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1320 " <AudioChannelConfiguration schemeIdUri=\"TestSchemeIdUri\""
1321 " value=\"TestValue\">"
1322 " </AudioChannelConfiguration></AdaptationSet></Period></MPD>";
1325 GstMpdClient *mpdclient = gst_mpd_client_new ();
1327 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1328 assert_equals_int (ret, TRUE);
1330 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1331 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1332 representationBase = adaptationSet->RepresentationBase;
1333 audioChannelConfiguration =
1334 (GstDescriptorType *) representationBase->AudioChannelConfiguration->data;
1335 assert_equals_string (audioChannelConfiguration->schemeIdUri,
1337 assert_equals_string (audioChannelConfiguration->value, "TestValue");
1339 gst_mpd_client_free (mpdclient);
1345 * Test parsing Period AdaptationSet RepresentationBase ContentProtection
1349 (dash_mpdparser_period_adaptationSet_representationBase_contentProtection) {
1350 GstPeriodNode *periodNode;
1351 GstAdaptationSetNode *adaptationSet;
1352 GstRepresentationBaseType *representationBase;
1353 GstDescriptorType *contentProtection;
1355 "<?xml version=\"1.0\"?>"
1356 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1357 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1360 " <ContentProtection schemeIdUri=\"TestSchemeIdUri\""
1361 " value=\"TestValue\">"
1362 " </ContentProtection></AdaptationSet></Period></MPD>";
1365 GstMpdClient *mpdclient = gst_mpd_client_new ();
1367 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1368 assert_equals_int (ret, TRUE);
1370 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1371 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1372 representationBase = adaptationSet->RepresentationBase;
1374 (GstDescriptorType *) representationBase->ContentProtection->data;
1375 assert_equals_string (contentProtection->schemeIdUri, "TestSchemeIdUri");
1376 assert_equals_string (contentProtection->value, "TestValue");
1378 gst_mpd_client_free (mpdclient);
1384 * Test parsing ContentProtection element that has no value attribute
1386 GST_START_TEST (dash_mpdparser_contentProtection_no_value)
1388 GstPeriodNode *periodNode;
1389 GstAdaptationSetNode *adaptationSet;
1390 GstRepresentationBaseType *representationBase;
1391 GstDescriptorType *contentProtection;
1393 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1394 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1395 " xmlns:mspr=\"urn:microsoft:playready\""
1396 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1399 " <ContentProtection schemeIdUri=\"urn:mpeg:dash:mp4protection:2011\" value=\"cenc\"/>"
1400 " <ContentProtection xmlns:mas=\"urn:marlin:mas:1-0:services:schemas:mpd\" schemeIdUri=\"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4\">"
1401 " <mas:MarlinContentIds>"
1402 " <mas:MarlinContentId>urn:marlin:kid:02020202020202020202020202020202</mas:MarlinContentId>"
1403 " </mas:MarlinContentIds>"
1404 " </ContentProtection>"
1405 " <ContentProtection schemeIdUri=\"urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95\" value=\"MSPR 2.0\">"
1406 " <mspr:pro>dGVzdA==</mspr:pro>"
1407 " </ContentProtection>" "</AdaptationSet></Period></MPD>";
1410 GstMpdClient *mpdclient = gst_mpd_client_new ();
1413 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1414 assert_equals_int (ret, TRUE);
1416 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1417 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1418 representationBase = adaptationSet->RepresentationBase;
1419 assert_equals_int (g_list_length (representationBase->ContentProtection), 3);
1421 (GstDescriptorType *) g_list_nth (representationBase->ContentProtection,
1423 assert_equals_string (contentProtection->schemeIdUri,
1424 "urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4");
1425 fail_if (contentProtection->value == NULL);
1426 /* We can't do a simple compare of value (which should be an XML dump
1427 of the ContentProtection element), because the whitespace
1428 formatting from xmlDump might differ between versions of libxml */
1429 str = strstr (contentProtection->value, "<ContentProtection");
1430 fail_if (str == NULL);
1431 str = strstr (contentProtection->value, "<mas:MarlinContentIds>");
1432 fail_if (str == NULL);
1433 str = strstr (contentProtection->value, "<mas:MarlinContentId>");
1434 fail_if (str == NULL);
1436 strstr (contentProtection->value,
1437 "urn:marlin:kid:02020202020202020202020202020202");
1438 fail_if (str == NULL);
1439 str = strstr (contentProtection->value, "</ContentProtection>");
1440 fail_if (str == NULL);
1441 gst_mpd_client_free (mpdclient);
1447 * Test parsing ContentProtection element that has no value attribute
1448 * nor an XML encoding
1450 GST_START_TEST (dash_mpdparser_contentProtection_no_value_no_encoding)
1452 GstPeriodNode *periodNode;
1453 GstAdaptationSetNode *adaptationSet;
1454 GstRepresentationBaseType *representationBase;
1455 GstDescriptorType *contentProtection;
1457 "<?xml version=\"1.0\"?>"
1458 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1459 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1462 " <ContentProtection schemeIdUri=\"urn:mpeg:dash:mp4protection:2011\" value=\"cenc\"/>"
1463 " <ContentProtection xmlns:mas=\"urn:marlin:mas:1-0:services:schemas:mpd\" schemeIdUri=\"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4\">"
1464 " <mas:MarlinContentIds>"
1465 " <mas:MarlinContentId>urn:marlin:kid:02020202020202020202020202020202</mas:MarlinContentId>"
1466 " </mas:MarlinContentIds>"
1467 " </ContentProtection>" "</AdaptationSet></Period></MPD>";
1470 GstMpdClient *mpdclient = gst_mpd_client_new ();
1472 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1473 assert_equals_int (ret, TRUE);
1475 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1476 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1477 representationBase = adaptationSet->RepresentationBase;
1478 assert_equals_int (g_list_length (representationBase->ContentProtection), 2);
1480 (GstDescriptorType *) g_list_nth (representationBase->ContentProtection,
1482 assert_equals_string (contentProtection->schemeIdUri,
1483 "urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4");
1484 fail_if (contentProtection->value == NULL);
1485 gst_mpd_client_free (mpdclient);
1491 * Test parsing Period AdaptationSet Accessibility attributes
1494 GST_START_TEST (dash_mpdparser_period_adaptationSet_accessibility)
1496 GstPeriodNode *periodNode;
1497 GstAdaptationSetNode *adaptationSet;
1498 GstDescriptorType *accessibility;
1500 "<?xml version=\"1.0\"?>"
1501 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1502 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1505 " <Accessibility schemeIdUri=\"TestSchemeIdUri\""
1506 " value=\"TestValue\">"
1507 " </Accessibility></AdaptationSet></Period></MPD>";
1510 GstMpdClient *mpdclient = gst_mpd_client_new ();
1512 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1513 assert_equals_int (ret, TRUE);
1515 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1516 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1517 accessibility = (GstDescriptorType *) adaptationSet->Accessibility->data;
1518 assert_equals_string (accessibility->schemeIdUri, "TestSchemeIdUri");
1519 assert_equals_string (accessibility->value, "TestValue");
1521 gst_mpd_client_free (mpdclient);
1527 * Test parsing Period AdaptationSet Role attributes
1530 GST_START_TEST (dash_mpdparser_period_adaptationSet_role)
1532 GstPeriodNode *periodNode;
1533 GstAdaptationSetNode *adaptationSet;
1534 GstDescriptorType *role;
1536 "<?xml version=\"1.0\"?>"
1537 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1538 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1541 " <Role schemeIdUri=\"TestSchemeIdUri\""
1542 " value=\"TestValue\">"
1543 " </Role></AdaptationSet></Period></MPD>";
1546 GstMpdClient *mpdclient = gst_mpd_client_new ();
1548 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1549 assert_equals_int (ret, TRUE);
1551 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1552 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1553 role = (GstDescriptorType *) adaptationSet->Role->data;
1554 assert_equals_string (role->schemeIdUri, "TestSchemeIdUri");
1555 assert_equals_string (role->value, "TestValue");
1557 gst_mpd_client_free (mpdclient);
1563 * Test parsing Period AdaptationSet Rating attributes
1566 GST_START_TEST (dash_mpdparser_period_adaptationSet_rating)
1568 GstPeriodNode *periodNode;
1569 GstAdaptationSetNode *adaptationSet;
1570 GstDescriptorType *rating;
1572 "<?xml version=\"1.0\"?>"
1573 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1574 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1577 " <Rating schemeIdUri=\"TestSchemeIdUri\""
1578 " value=\"TestValue\">"
1579 " </Rating></AdaptationSet></Period></MPD>";
1582 GstMpdClient *mpdclient = gst_mpd_client_new ();
1584 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1585 assert_equals_int (ret, TRUE);
1587 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1588 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1589 rating = (GstDescriptorType *) adaptationSet->Rating->data;
1590 assert_equals_string (rating->schemeIdUri, "TestSchemeIdUri");
1591 assert_equals_string (rating->value, "TestValue");
1593 gst_mpd_client_free (mpdclient);
1599 * Test parsing Period AdaptationSet Viewpoint attributes
1602 GST_START_TEST (dash_mpdparser_period_adaptationSet_viewpoint)
1604 GstPeriodNode *periodNode;
1605 GstAdaptationSetNode *adaptationSet;
1606 GstDescriptorType *viewpoint;
1608 "<?xml version=\"1.0\"?>"
1609 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1610 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1613 " <Viewpoint schemeIdUri=\"TestSchemeIdUri\""
1614 " value=\"TestValue\">"
1615 " </Viewpoint></AdaptationSet></Period></MPD>";
1618 GstMpdClient *mpdclient = gst_mpd_client_new ();
1620 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1621 assert_equals_int (ret, TRUE);
1623 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1624 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1625 viewpoint = (GstDescriptorType *) adaptationSet->Viewpoint->data;
1626 assert_equals_string (viewpoint->schemeIdUri, "TestSchemeIdUri");
1627 assert_equals_string (viewpoint->value, "TestValue");
1629 gst_mpd_client_free (mpdclient);
1635 * Test parsing Period AdaptationSet ContentComponent attributes
1638 GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent)
1640 GstPeriodNode *periodNode;
1641 GstAdaptationSetNode *adaptationSet;
1642 GstContentComponentNode *contentComponent;
1644 "<?xml version=\"1.0\"?>"
1645 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1646 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1649 " <ContentComponent id=\"1\""
1651 " contentType=\"TestContentType\""
1653 " </ContentComponent></AdaptationSet></Period></MPD>";
1656 GstMpdClient *mpdclient = gst_mpd_client_new ();
1658 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1659 assert_equals_int (ret, TRUE);
1661 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1662 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1663 contentComponent = (GstContentComponentNode *)
1664 adaptationSet->ContentComponents->data;
1665 assert_equals_uint64 (contentComponent->id, 1);
1666 assert_equals_string (contentComponent->lang, "en");
1667 assert_equals_string (contentComponent->contentType, "TestContentType");
1668 assert_equals_uint64 (contentComponent->par->num, 10);
1669 assert_equals_uint64 (contentComponent->par->den, 20);
1671 gst_mpd_client_free (mpdclient);
1677 * Test parsing Period AdaptationSet ContentComponent Accessibility attributes
1681 (dash_mpdparser_period_adaptationSet_contentComponent_accessibility) {
1682 GstPeriodNode *periodNode;
1683 GstAdaptationSetNode *adaptationSet;
1684 GstContentComponentNode *contentComponent;
1685 GstDescriptorType *accessibility;
1687 "<?xml version=\"1.0\"?>"
1688 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1689 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1692 " <ContentComponent>"
1693 " <Accessibility schemeIdUri=\"TestSchemeIdUri\""
1694 " value=\"TestValue\">"
1696 " </ContentComponent></AdaptationSet></Period></MPD>";
1699 GstMpdClient *mpdclient = gst_mpd_client_new ();
1701 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1702 assert_equals_int (ret, TRUE);
1704 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1705 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1706 contentComponent = (GstContentComponentNode *)
1707 adaptationSet->ContentComponents->data;
1708 accessibility = (GstDescriptorType *) contentComponent->Accessibility->data;
1709 assert_equals_string (accessibility->schemeIdUri, "TestSchemeIdUri");
1710 assert_equals_string (accessibility->value, "TestValue");
1712 gst_mpd_client_free (mpdclient);
1718 * Test parsing Period AdaptationSet ContentComponent Role attributes
1721 GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_role)
1723 GstPeriodNode *periodNode;
1724 GstAdaptationSetNode *adaptationSet;
1725 GstContentComponentNode *contentComponent;
1726 GstDescriptorType *role;
1728 "<?xml version=\"1.0\"?>"
1729 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1730 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1733 " <ContentComponent>"
1734 " <Role schemeIdUri=\"TestSchemeIdUri\""
1735 " value=\"TestValue\">"
1736 " </Role></ContentComponent></AdaptationSet></Period></MPD>";
1739 GstMpdClient *mpdclient = gst_mpd_client_new ();
1741 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1742 assert_equals_int (ret, TRUE);
1744 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1745 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1746 contentComponent = (GstContentComponentNode *)
1747 adaptationSet->ContentComponents->data;
1748 role = (GstDescriptorType *) contentComponent->Role->data;
1749 assert_equals_string (role->schemeIdUri, "TestSchemeIdUri");
1750 assert_equals_string (role->value, "TestValue");
1752 gst_mpd_client_free (mpdclient);
1758 * Test parsing Period AdaptationSet ContentComponent Rating attributes
1761 GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_rating)
1763 GstPeriodNode *periodNode;
1764 GstAdaptationSetNode *adaptationSet;
1765 GstContentComponentNode *contentComponent;
1766 GstDescriptorType *rating;
1768 "<?xml version=\"1.0\"?>"
1769 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1770 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1773 " <ContentComponent>"
1774 " <Rating schemeIdUri=\"TestSchemeIdUri\""
1775 " value=\"TestValue\">"
1777 " </ContentComponent></AdaptationSet></Period></MPD>";
1780 GstMpdClient *mpdclient = gst_mpd_client_new ();
1782 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1783 assert_equals_int (ret, TRUE);
1785 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1786 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1787 contentComponent = (GstContentComponentNode *)
1788 adaptationSet->ContentComponents->data;
1789 rating = (GstDescriptorType *) contentComponent->Rating->data;
1790 assert_equals_string (rating->schemeIdUri, "TestSchemeIdUri");
1791 assert_equals_string (rating->value, "TestValue");
1793 gst_mpd_client_free (mpdclient);
1799 * Test parsing Period AdaptationSet ContentComponent Viewpoint attributes
1802 GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_viewpoint)
1804 GstPeriodNode *periodNode;
1805 GstAdaptationSetNode *adaptationSet;
1806 GstContentComponentNode *contentComponent;
1807 GstDescriptorType *viewpoint;
1809 "<?xml version=\"1.0\"?>"
1810 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1811 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1814 " <ContentComponent>"
1815 " <Viewpoint schemeIdUri=\"TestSchemeIdUri\""
1816 " value=\"TestValue\">"
1818 " </ContentComponent></AdaptationSet></Period></MPD>";
1821 GstMpdClient *mpdclient = gst_mpd_client_new ();
1823 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1824 assert_equals_int (ret, TRUE);
1826 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1827 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1828 contentComponent = (GstContentComponentNode *)
1829 adaptationSet->ContentComponents->data;
1830 viewpoint = (GstDescriptorType *) contentComponent->Viewpoint->data;
1831 assert_equals_string (viewpoint->schemeIdUri, "TestSchemeIdUri");
1832 assert_equals_string (viewpoint->value, "TestValue");
1834 gst_mpd_client_free (mpdclient);
1840 * Test parsing Period AdaptationSet BaseURL attributes
1843 GST_START_TEST (dash_mpdparser_period_adaptationSet_baseURL)
1845 GstPeriodNode *periodNode;
1846 GstAdaptationSetNode *adaptationSet;
1847 GstBaseURL *baseURL;
1849 "<?xml version=\"1.0\"?>"
1850 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1851 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1854 " <BaseURL serviceLocation=\"TestServiceLocation\""
1855 " byteRange=\"TestByteRange\">TestBaseURL</BaseURL>"
1856 " </AdaptationSet></Period></MPD>";
1859 GstMpdClient *mpdclient = gst_mpd_client_new ();
1861 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1862 assert_equals_int (ret, TRUE);
1864 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1865 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1866 baseURL = (GstBaseURL *) adaptationSet->BaseURLs->data;
1867 assert_equals_string (baseURL->baseURL, "TestBaseURL");
1868 assert_equals_string (baseURL->serviceLocation, "TestServiceLocation");
1869 assert_equals_string (baseURL->byteRange, "TestByteRange");
1871 gst_mpd_client_free (mpdclient);
1877 * Test parsing Period AdaptationSet SegmentBase attributes
1880 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentBase)
1882 GstPeriodNode *periodNode;
1883 GstAdaptationSetNode *adaptationSet;
1884 GstSegmentBaseType *segmentBase;
1886 "<?xml version=\"1.0\"?>"
1887 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1888 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1891 " <SegmentBase timescale=\"123456\""
1892 " presentationTimeOffset=\"123456789\""
1893 " indexRange=\"100-200\""
1894 " indexRangeExact=\"true\">"
1895 " </SegmentBase></AdaptationSet></Period></MPD>";
1898 GstMpdClient *mpdclient = gst_mpd_client_new ();
1900 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1901 assert_equals_int (ret, TRUE);
1903 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1904 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1905 segmentBase = adaptationSet->SegmentBase;
1906 assert_equals_uint64 (segmentBase->timescale, 123456);
1907 assert_equals_uint64 (segmentBase->presentationTimeOffset, 123456789);
1908 assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 100);
1909 assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 200);
1910 assert_equals_int (segmentBase->indexRangeExact, TRUE);
1912 gst_mpd_client_free (mpdclient);
1918 * Test parsing Period AdaptationSet SegmentBase Initialization attributes
1921 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentBase_initialization)
1923 GstPeriodNode *periodNode;
1924 GstAdaptationSetNode *adaptationSet;
1925 GstSegmentBaseType *segmentBase;
1926 GstURLType *initialization;
1928 "<?xml version=\"1.0\"?>"
1929 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1930 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1934 " <Initialisation sourceURL=\"TestSourceURL\""
1935 " range=\"100-200\">"
1936 " </Initialisation></SegmentBase></AdaptationSet></Period></MPD>";
1939 GstMpdClient *mpdclient = gst_mpd_client_new ();
1941 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1942 assert_equals_int (ret, TRUE);
1944 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1945 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1946 segmentBase = adaptationSet->SegmentBase;
1947 initialization = segmentBase->Initialization;
1948 assert_equals_string (initialization->sourceURL, "TestSourceURL");
1949 assert_equals_uint64 (initialization->range->first_byte_pos, 100);
1950 assert_equals_uint64 (initialization->range->last_byte_pos, 200);
1952 gst_mpd_client_free (mpdclient);
1958 * Test parsing Period AdaptationSet SegmentBase RepresentationIndex attributes
1962 (dash_mpdparser_period_adaptationSet_segmentBase_representationIndex) {
1963 GstPeriodNode *periodNode;
1964 GstAdaptationSetNode *adaptationSet;
1965 GstSegmentBaseType *segmentBase;
1966 GstURLType *representationIndex;
1968 "<?xml version=\"1.0\"?>"
1969 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1970 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1974 " <RepresentationIndex sourceURL=\"TestSourceURL\""
1975 " range=\"100-200\">"
1976 " </RepresentationIndex>"
1977 " </SegmentBase></AdaptationSet></Period></MPD>";
1980 GstMpdClient *mpdclient = gst_mpd_client_new ();
1982 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
1983 assert_equals_int (ret, TRUE);
1985 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
1986 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
1987 segmentBase = adaptationSet->SegmentBase;
1988 representationIndex = segmentBase->RepresentationIndex;
1989 assert_equals_string (representationIndex->sourceURL, "TestSourceURL");
1990 assert_equals_uint64 (representationIndex->range->first_byte_pos, 100);
1991 assert_equals_uint64 (representationIndex->range->last_byte_pos, 200);
1993 gst_mpd_client_free (mpdclient);
1999 * Test parsing Period AdaptationSet SegmentList attributes
2002 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentList)
2004 GstPeriodNode *periodNode;
2005 GstAdaptationSetNode *adaptationSet;
2006 GstSegmentListNode *segmentList;
2008 "<?xml version=\"1.0\"?>"
2009 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2010 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2013 " <SegmentList duration=\"1\"></SegmentList></AdaptationSet></Period></MPD>";
2016 GstMpdClient *mpdclient = gst_mpd_client_new ();
2018 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2019 assert_equals_int (ret, TRUE);
2021 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2022 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2023 segmentList = adaptationSet->SegmentList;
2024 fail_if (segmentList == NULL);
2026 gst_mpd_client_free (mpdclient);
2032 * Test parsing Period AdaptationSet SegmentTemplate attributes
2035 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentTemplate)
2037 GstPeriodNode *periodNode;
2038 GstAdaptationSetNode *adaptationSet;
2039 GstSegmentTemplateNode *segmentTemplate;
2041 "<?xml version=\"1.0\"?>"
2042 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2043 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2046 " <SegmentTemplate media=\"TestMedia\""
2048 " index=\"TestIndex\""
2049 " initialization=\"TestInitialization\""
2050 " bitstreamSwitching=\"TestBitstreamSwitching\">"
2051 " </SegmentTemplate></AdaptationSet></Period></MPD>";
2054 GstMpdClient *mpdclient = gst_mpd_client_new ();
2056 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2057 assert_equals_int (ret, TRUE);
2059 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2060 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2061 segmentTemplate = adaptationSet->SegmentTemplate;
2062 assert_equals_string (segmentTemplate->media, "TestMedia");
2063 assert_equals_string (segmentTemplate->index, "TestIndex");
2064 assert_equals_string (segmentTemplate->initialization, "TestInitialization");
2065 assert_equals_string (segmentTemplate->bitstreamSwitching,
2066 "TestBitstreamSwitching");
2068 gst_mpd_client_free (mpdclient);
2075 (dash_mpdparser_period_adaptationSet_representation_segmentTemplate_inherit)
2077 GstPeriodNode *periodNode;
2078 GstAdaptationSetNode *adaptationSet;
2079 GstRepresentationNode *representation;
2080 GstSegmentTemplateNode *segmentTemplate;
2082 "<?xml version=\"1.0\"?>"
2083 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2084 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2086 " <SegmentTemplate media=\"ParentMedia\" duration=\"1\" "
2087 " initialization=\"ParentInitialization\">"
2088 " </SegmentTemplate>"
2090 " <Representation id=\"1\" bandwidth=\"5000\">"
2091 " <SegmentTemplate media=\"TestMedia\""
2092 " index=\"TestIndex\""
2093 " bitstreamSwitching=\"TestBitstreamSwitching\">"
2094 " </SegmentTemplate></Representation></AdaptationSet></Period></MPD>";
2097 GstMpdClient *mpdclient = gst_mpd_client_new ();
2099 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2100 assert_equals_int (ret, TRUE);
2102 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2103 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2105 (GstRepresentationNode *) adaptationSet->Representations->data;
2106 segmentTemplate = representation->SegmentTemplate;
2107 assert_equals_string (segmentTemplate->media, "TestMedia");
2108 assert_equals_string (segmentTemplate->index, "TestIndex");
2109 assert_equals_string (segmentTemplate->initialization,
2110 "ParentInitialization");
2111 assert_equals_string (segmentTemplate->bitstreamSwitching,
2112 "TestBitstreamSwitching");
2114 gst_mpd_client_free (mpdclient);
2120 (dash_mpdparser_period_adaptationSet_representation_segmentBase_inherit) {
2121 GstPeriodNode *periodNode;
2122 GstAdaptationSetNode *adaptationSet;
2123 GstRepresentationNode *representation;
2124 GstSegmentBaseType *segmentBase;
2126 "<?xml version=\"1.0\"?>"
2127 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2128 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2130 " <SegmentBase timescale=\"123456\""
2131 " presentationTimeOffset=\"123456789\""
2132 " indexRange=\"100-200\""
2133 " indexRangeExact=\"true\">"
2134 " <Initialisation sourceURL=\"TestSourceURL\""
2135 " range=\"100-200\" />"
2138 " <Representation id=\"1\" bandwidth=\"5000\">"
2140 " </SegmentBase></Representation></AdaptationSet></Period></MPD>";
2143 GstMpdClient *mpdclient = gst_mpd_client_new ();
2145 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2146 assert_equals_int (ret, TRUE);
2148 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2149 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2151 (GstRepresentationNode *) adaptationSet->Representations->data;
2152 segmentBase = representation->SegmentBase;
2153 assert_equals_int (segmentBase->timescale, 123456);
2155 gst_mpd_client_free (mpdclient);
2161 * Test parsing Period AdaptationSet SegmentTemplate attributes with
2164 GST_START_TEST (dash_mpdparser_adapt_repr_segmentTemplate_inherit)
2166 GstPeriodNode *periodNode;
2167 GstAdaptationSetNode *adaptationSet;
2168 GstSegmentTemplateNode *segmentTemplate;
2169 GstRepresentationNode *representation;
2170 GstMultSegmentBaseType *multSegBaseType;
2171 GstSegmentBaseType *segBaseType;
2173 "<?xml version=\"1.0\"?>"
2174 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2175 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2176 " <Period duration=\"PT0H5M0.000S\">"
2177 " <AdaptationSet maxWidth=\"1280\" maxHeight=\"720\" maxFrameRate=\"50\">"
2178 " <SegmentTemplate initialization=\"set1_init.mp4\"/>"
2179 " <Representation id=\"1\" mimeType=\"video/mp4\" codecs=\"avc1.640020\" "
2180 " width=\"1280\" height=\"720\" frameRate=\"50\" bandwidth=\"30000\">"
2181 " <SegmentTemplate timescale=\"12800\" media=\"track1_$Number$.m4s\" startNumber=\"1\" duration=\"25600\"/>"
2182 " </Representation></AdaptationSet></Period></MPD>";
2185 GstMpdClient *mpdclient = gst_mpd_client_new ();
2187 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2188 assert_equals_int (ret, TRUE);
2190 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2191 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2192 representation = (GstRepresentationNode *)
2193 adaptationSet->Representations->data;
2194 segmentTemplate = representation->SegmentTemplate;
2195 fail_if (segmentTemplate == NULL);
2196 multSegBaseType = segmentTemplate->MultSegBaseType;
2197 segBaseType = multSegBaseType->SegBaseType;
2199 assert_equals_uint64 (segBaseType->timescale, 12800);
2200 assert_equals_uint64 (multSegBaseType->duration, 25600);
2201 assert_equals_uint64 (multSegBaseType->startNumber, 1);
2202 assert_equals_string (segmentTemplate->media, "track1_$Number$.m4s");
2203 assert_equals_string (segmentTemplate->initialization, "set1_init.mp4");
2205 gst_mpd_client_free (mpdclient);
2210 * Test parsing Period AdaptationSet SegmentTemplate attributes with
2213 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentTemplate_inherit)
2215 GstPeriodNode *periodNode;
2216 GstAdaptationSetNode *adaptationSet;
2217 GstSegmentTemplateNode *segmentTemplate;
2219 "<?xml version=\"1.0\"?>"
2220 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2221 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2223 " <SegmentTemplate media=\"ParentMedia\" duration=\"1\" "
2224 " initialization=\"ParentInitialization\">"
2225 " </SegmentTemplate>"
2227 " <SegmentTemplate media=\"TestMedia\""
2229 " index=\"TestIndex\""
2230 " bitstreamSwitching=\"TestBitstreamSwitching\">"
2231 " </SegmentTemplate></AdaptationSet></Period></MPD>";
2234 GstMpdClient *mpdclient = gst_mpd_client_new ();
2236 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2237 assert_equals_int (ret, TRUE);
2239 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2240 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2241 segmentTemplate = adaptationSet->SegmentTemplate;
2242 assert_equals_string (segmentTemplate->media, "TestMedia");
2243 assert_equals_string (segmentTemplate->index, "TestIndex");
2244 assert_equals_string (segmentTemplate->initialization,
2245 "ParentInitialization");
2246 assert_equals_string (segmentTemplate->bitstreamSwitching,
2247 "TestBitstreamSwitching");
2249 gst_mpd_client_free (mpdclient);
2255 * Test parsing Period AdaptationSet Representation attributes
2258 GST_START_TEST (dash_mpdparser_period_adaptationSet_representation)
2260 GstPeriodNode *periodNode;
2261 GstAdaptationSetNode *adaptationSet;
2262 GstRepresentationNode *representation;
2264 "<?xml version=\"1.0\"?>"
2265 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2266 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2269 " <Representation id=\"Test_Id\""
2270 " bandwidth=\"100\""
2271 " qualityRanking=\"200\""
2272 " dependencyId=\"one two three\""
2273 " mediaStreamStructureId=\"\">"
2274 " </Representation></AdaptationSet></Period></MPD>";
2277 GstMpdClient *mpdclient = gst_mpd_client_new ();
2279 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2280 assert_equals_int (ret, TRUE);
2282 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2283 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2284 representation = (GstRepresentationNode *)
2285 adaptationSet->Representations->data;
2286 assert_equals_string (representation->id, "Test_Id");
2287 assert_equals_uint64 (representation->bandwidth, 100);
2288 assert_equals_uint64 (representation->qualityRanking, 200);
2289 assert_equals_string (representation->dependencyId[0], "one");
2290 assert_equals_string (representation->dependencyId[1], "two");
2291 assert_equals_string (representation->dependencyId[2], "three");
2292 assert_equals_pointer (representation->dependencyId[3], NULL);
2293 assert_equals_pointer (representation->mediaStreamStructureId[0], NULL);
2295 gst_mpd_client_free (mpdclient);
2301 * Test parsing Period AdaptationSet Representation RepresentationBaseType attributes
2305 (dash_mpdparser_period_adaptationSet_representation_representationBase) {
2306 GstPeriodNode *periodNode;
2307 GstAdaptationSetNode *adaptationSet;
2308 GstRepresentationNode *representation;
2309 GstRepresentationBaseType *representationBase;
2311 "<?xml version=\"1.0\"?>"
2312 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2313 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2316 " <Representation id=\"1\" bandwidth=\"250000\">"
2317 " </Representation></AdaptationSet></Period></MPD>";
2320 GstMpdClient *mpdclient = gst_mpd_client_new ();
2322 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2323 assert_equals_int (ret, TRUE);
2325 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2326 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2327 representation = (GstRepresentationNode *)
2328 adaptationSet->Representations->data;
2329 representationBase = (GstRepresentationBaseType *)
2330 representation->RepresentationBase;
2331 fail_if (representationBase == NULL);
2333 gst_mpd_client_free (mpdclient);
2339 * Test parsing Period AdaptationSet Representation BaseURL attributes
2342 GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_baseURL)
2344 GstPeriodNode *periodNode;
2345 GstAdaptationSetNode *adaptationSet;
2346 GstRepresentationNode *representation;
2347 GstBaseURL *baseURL;
2349 "<?xml version=\"1.0\"?>"
2350 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2351 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2354 " <Representation id=\"1\" bandwidth=\"250000\">"
2355 " <BaseURL serviceLocation=\"TestServiceLocation\""
2356 " byteRange=\"TestByteRange\">TestBaseURL</BaseURL>"
2357 " </Representation></AdaptationSet></Period></MPD>";
2360 GstMpdClient *mpdclient = gst_mpd_client_new ();
2362 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2363 assert_equals_int (ret, TRUE);
2365 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2366 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2367 representation = (GstRepresentationNode *)
2368 adaptationSet->Representations->data;
2369 baseURL = (GstBaseURL *) representation->BaseURLs->data;
2370 assert_equals_string (baseURL->baseURL, "TestBaseURL");
2371 assert_equals_string (baseURL->serviceLocation, "TestServiceLocation");
2372 assert_equals_string (baseURL->byteRange, "TestByteRange");
2374 gst_mpd_client_free (mpdclient);
2380 * Test parsing Period AdaptationSet Representation SubRepresentation attributes
2384 (dash_mpdparser_period_adaptationSet_representation_subRepresentation) {
2385 GstPeriodNode *periodNode;
2386 GstAdaptationSetNode *adaptationSet;
2387 GstRepresentationNode *representation;
2388 GstSubRepresentationNode *subRepresentation;
2390 "<?xml version=\"1.0\"?>"
2391 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2392 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2395 " <Representation id=\"1\" bandwidth=\"250000\">"
2396 " <SubRepresentation level=\"100\""
2397 " dependencyLevel=\"1 2 3\""
2398 " bandwidth=\"200\""
2399 " contentComponent=\"content1 content2\">"
2400 " </SubRepresentation>"
2401 " </Representation></AdaptationSet></Period></MPD>";
2404 GstMpdClient *mpdclient = gst_mpd_client_new ();
2406 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2407 assert_equals_int (ret, TRUE);
2409 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2410 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2411 representation = (GstRepresentationNode *)
2412 adaptationSet->Representations->data;
2413 subRepresentation = (GstSubRepresentationNode *)
2414 representation->SubRepresentations->data;
2415 assert_equals_uint64 (subRepresentation->level, 100);
2416 assert_equals_uint64 (subRepresentation->size, 3);
2417 assert_equals_uint64 (subRepresentation->dependencyLevel[0], 1);
2418 assert_equals_uint64 (subRepresentation->dependencyLevel[1], 2);
2419 assert_equals_uint64 (subRepresentation->dependencyLevel[2], 3);
2420 assert_equals_uint64 (subRepresentation->bandwidth, 200);
2421 assert_equals_string (subRepresentation->contentComponent[0], "content1");
2422 assert_equals_string (subRepresentation->contentComponent[1], "content2");
2423 assert_equals_pointer (subRepresentation->contentComponent[2], NULL);
2425 gst_mpd_client_free (mpdclient);
2431 * Test parsing Period AdaptationSet Representation SubRepresentation
2432 * RepresentationBase attributes
2435 (dash_mpdparser_period_adaptationSet_representation_subRepresentation_representationBase)
2437 GstPeriodNode *periodNode;
2438 GstAdaptationSetNode *adaptationSet;
2439 GstRepresentationNode *representation;
2440 GstSubRepresentationNode *subRepresentation;
2441 GstRepresentationBaseType *representationBase;
2443 "<?xml version=\"1.0\"?>"
2444 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2445 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2448 " <Representation id=\"1\" bandwidth=\"250000\">"
2449 " <SubRepresentation>"
2450 " </SubRepresentation>"
2451 " </Representation></AdaptationSet></Period></MPD>";
2454 GstMpdClient *mpdclient = gst_mpd_client_new ();
2456 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2457 assert_equals_int (ret, TRUE);
2459 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2460 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2461 representation = (GstRepresentationNode *)
2462 adaptationSet->Representations->data;
2463 subRepresentation = (GstSubRepresentationNode *)
2464 representation->SubRepresentations->data;
2465 representationBase = (GstRepresentationBaseType *)
2466 subRepresentation->RepresentationBase;
2467 fail_if (representationBase == NULL);
2469 gst_mpd_client_free (mpdclient);
2475 * Test parsing Period AdaptationSet Representation SegmentBase attributes
2478 GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_segmentBase)
2480 GstPeriodNode *periodNode;
2481 GstAdaptationSetNode *adaptationSet;
2482 GstRepresentationNode *representation;
2483 GstSegmentBaseType *segmentBase;
2485 "<?xml version=\"1.0\"?>"
2486 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2487 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2490 " <Representation id=\"1\" bandwidth=\"250000\">"
2493 " </Representation></AdaptationSet></Period></MPD>";
2496 GstMpdClient *mpdclient = gst_mpd_client_new ();
2498 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2499 assert_equals_int (ret, TRUE);
2501 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2502 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2503 representation = (GstRepresentationNode *)
2504 adaptationSet->Representations->data;
2505 segmentBase = representation->SegmentBase;
2506 fail_if (segmentBase == NULL);
2508 gst_mpd_client_free (mpdclient);
2514 * Test parsing Period AdaptationSet Representation SegmentList attributes
2517 GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_segmentList)
2519 GstPeriodNode *periodNode;
2520 GstAdaptationSetNode *adaptationSet;
2521 GstRepresentationNode *representation;
2522 GstSegmentListNode *segmentList;
2524 "<?xml version=\"1.0\"?>"
2525 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2526 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2529 " <Representation id=\"1\" bandwidth=\"250000\">"
2530 " <SegmentList duration=\"1\">"
2532 " </Representation></AdaptationSet></Period></MPD>";
2535 GstMpdClient *mpdclient = gst_mpd_client_new ();
2537 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2538 assert_equals_int (ret, TRUE);
2540 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2541 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2542 representation = (GstRepresentationNode *)
2543 adaptationSet->Representations->data;
2544 segmentList = representation->SegmentList;
2545 fail_if (segmentList == NULL);
2547 gst_mpd_client_free (mpdclient);
2553 * Test parsing Period AdaptationSet Representation SegmentTemplate attributes
2557 (dash_mpdparser_period_adaptationSet_representation_segmentTemplate) {
2558 GstPeriodNode *periodNode;
2559 GstAdaptationSetNode *adaptationSet;
2560 GstRepresentationNode *representation;
2561 GstSegmentTemplateNode *segmentTemplate;
2563 "<?xml version=\"1.0\"?>"
2564 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2565 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2568 " <Representation id=\"1\" bandwidth=\"250000\">"
2569 " <SegmentTemplate duration=\"1\">"
2570 " </SegmentTemplate>"
2571 " </Representation></AdaptationSet></Period></MPD>";
2574 GstMpdClient *mpdclient = gst_mpd_client_new ();
2576 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2577 assert_equals_int (ret, TRUE);
2579 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2580 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
2581 representation = (GstRepresentationNode *)
2582 adaptationSet->Representations->data;
2583 segmentTemplate = representation->SegmentTemplate;
2584 fail_if (segmentTemplate == NULL);
2586 gst_mpd_client_free (mpdclient);
2592 * Test parsing Period Subset attributes
2595 GST_START_TEST (dash_mpdparser_period_subset)
2597 GstPeriodNode *periodNode;
2598 GstSubsetNode *subset;
2600 "<?xml version=\"1.0\"?>"
2601 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2602 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2603 " <Period><Subset contains=\"1 2 3\"></Subset></Period></MPD>";
2606 GstMpdClient *mpdclient = gst_mpd_client_new ();
2608 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2609 assert_equals_int (ret, TRUE);
2611 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
2612 subset = (GstSubsetNode *) periodNode->Subsets->data;
2613 assert_equals_uint64 (subset->size, 3);
2614 assert_equals_uint64 (subset->contains[0], 1);
2615 assert_equals_uint64 (subset->contains[1], 2);
2616 assert_equals_uint64 (subset->contains[2], 3);
2618 gst_mpd_client_free (mpdclient);
2624 * Test parsing UTCTiming elements
2627 GST_START_TEST (dash_mpdparser_utctiming)
2630 "<?xml version=\"1.0\"?>"
2631 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2632 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2633 "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:http-xsdate:2014\" value=\"http://time.akamai.com/?iso http://example.time/xsdate\"/>"
2634 "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:direct:2014\" value=\"2002-05-30T09:30:10Z \"/>"
2635 "<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\"/>"
2638 GstMpdClient *mpdclient = gst_mpd_client_new ();
2639 GstMPDUTCTimingType selected_method;
2642 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2644 assert_equals_int (ret, TRUE);
2645 fail_if (mpdclient->mpd_node == NULL);
2646 fail_if (mpdclient->mpd_node->UTCTiming == NULL);
2647 assert_equals_int (g_list_length (mpdclient->mpd_node->UTCTiming), 3);
2649 gst_mpd_client_get_utc_timing_sources (mpdclient,
2650 GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE, &selected_method);
2651 fail_if (urls == NULL);
2652 assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE);
2653 assert_equals_int (g_strv_length (urls), 2);
2654 assert_equals_string (urls[0], "http://time.akamai.com/?iso");
2655 assert_equals_string (urls[1], "http://example.time/xsdate");
2657 gst_mpd_client_get_utc_timing_sources (mpdclient,
2658 GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE | GST_MPD_UTCTIMING_TYPE_HTTP_ISO,
2660 fail_if (urls == NULL);
2661 assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE);
2663 gst_mpd_client_get_utc_timing_sources (mpdclient,
2664 GST_MPD_UTCTIMING_TYPE_DIRECT, NULL);
2665 fail_if (urls == NULL);
2666 assert_equals_int (g_strv_length (urls), 1);
2667 assert_equals_string (urls[0], "2002-05-30T09:30:10Z ");
2669 gst_mpd_client_get_utc_timing_sources (mpdclient,
2670 GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE | GST_MPD_UTCTIMING_TYPE_DIRECT,
2672 fail_if (urls == NULL);
2673 assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE);
2675 gst_mpd_client_get_utc_timing_sources (mpdclient,
2676 GST_MPD_UTCTIMING_TYPE_NTP, &selected_method);
2677 fail_if (urls == NULL);
2678 assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_NTP);
2679 assert_equals_int (g_strv_length (urls), 4);
2680 assert_equals_string (urls[0], "0.europe.pool.ntp.org");
2681 assert_equals_string (urls[1], "1.europe.pool.ntp.org");
2682 assert_equals_string (urls[2], "2.europe.pool.ntp.org");
2683 assert_equals_string (urls[3], "3.europe.pool.ntp.org");
2684 gst_mpd_client_free (mpdclient);
2690 * Test parsing invalid UTCTiming values:
2691 * - elements with no schemeIdUri property should be rejected
2692 * - elements with no value property should be rejected
2693 * - elements with unrecognised UTCTiming scheme should be rejected
2694 * - elements with empty values should be rejected
2697 GST_START_TEST (dash_mpdparser_utctiming_invalid_value)
2700 "<?xml version=\"1.0\"?>"
2701 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2702 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2703 "<UTCTiming invalid_schemeIdUri=\"dummy.uri.scheme\" value=\"dummy value\"/>"
2704 "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:ntp:2014\" invalid_value=\"dummy value\"/>"
2705 "<UTCTiming schemeIdUri=\"dummy.uri.scheme\" value=\"dummy value\"/>"
2706 "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:ntp:2014\" value=\"\"/>"
2709 GstMpdClient *mpdclient = gst_mpd_client_new ();
2711 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2713 assert_equals_int (ret, TRUE);
2714 fail_if (mpdclient->mpd_node == NULL);
2715 fail_if (mpdclient->mpd_node->UTCTiming != NULL);
2716 gst_mpd_client_free (mpdclient);
2722 * Test parsing the type property: value "dynamic"
2725 GST_START_TEST (dash_mpdparser_type_dynamic)
2730 "<?xml version=\"1.0\"?>"
2731 "<MPD type=\"dynamic\" xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2732 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"> </MPD>";
2735 GstMpdClient *mpdclient = gst_mpd_client_new ();
2737 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2738 assert_equals_int (ret, TRUE);
2740 isLive = gst_mpd_client_is_live (mpdclient);
2741 assert_equals_int (isLive, 1);
2743 gst_mpd_client_free (mpdclient);
2749 * Validate gst_mpdparser_build_URL_from_template function
2752 GST_START_TEST (dash_mpdparser_template_parsing)
2754 const gchar *id = "TestId";
2756 guint bandwidth = 2500;
2762 const gchar *urlTemplate;
2763 const gchar *expectedResponse;
2766 /* various test scenarios to attempt */
2767 struct TestUrl testUrl[] = {
2768 {"", NULL}, /* empty string for template */
2769 {"$$", "$"}, /* escaped $ */
2770 {"Number", "Number"}, /* string similar with an identifier, but without $ */
2771 {"Number$Number$", "Number7"}, /* Number identifier */
2772 {"Number$Number$$$", "Number7$"}, /* Number identifier followed by $$ */
2773 {"Number$Number$Number$Number$", "Number7Number7"}, /* series of "Number" string and Number identifier */
2774 {"Representation$RepresentationID$", "RepresentationTestId"}, /* RepresentationID identifier */
2775 {"TestMedia$Bandwidth$$$test", "TestMedia2500$test"}, /* Bandwidth identifier */
2776 {"TestMedia$Time$", "TestMedia100"}, /* Time identifier */
2777 {"TestMedia$Time", NULL}, /* Identifier not finished with $ */
2778 {"Time$Time%d$", NULL}, /* usage of %d (no width) */
2779 {"Time$Time%0d$", "Time100"}, /* usage of format smaller than number of digits */
2780 {"Time$Time%01d$", "Time100"}, /* usage of format smaller than number of digits */
2781 {"Time$Time%05d$", "Time00100"}, /* usage of format bigger than number of digits */
2782 {"Time$Time%05dtest$", "Time00100test"}, /* usage extra text in format */
2783 {"Time$Time%3d$", NULL}, /* incorrect format: width does not start with 0 */
2784 {"Time$Time%0-4d$", NULL}, /* incorrect format: width is not a number */
2785 {"Time$Time%0$", NULL}, /* incorrect format: no d, x or u */
2786 {"Time$Time1%01d$", NULL}, /* incorrect format: does not start with % after identifier */
2787 {"$Bandwidth%/init.mp4v", NULL}, /* incorrect identifier: not finished with $ */
2788 {"$Number%/$Time$.mp4v", NULL}, /* incorrect number of $ separators */
2789 {"$RepresentationID1$", NULL}, /* incorrect identifier */
2790 {"$Bandwidth1$", NULL}, /* incorrect identifier */
2791 {"$Number1$", NULL}, /* incorrect identifier */
2792 {"$RepresentationID%01d$", NULL}, /* incorrect format: RepresentationID does not support formatting */
2793 {"Time$Time%05u$", NULL}, /* %u format */
2794 {"Time$Time%05x$", NULL}, /* %x format */
2795 {"Time$Time%05utest$", NULL}, /* %u format followed by text */
2796 {"Time$Time%05xtest$", NULL}, /* %x format followed by text */
2797 {"Time$Time%05xtest%$", NULL}, /* second % character in format */
2800 guint count = sizeof (testUrl) / sizeof (testUrl[0]);
2803 for (i = 0; i < count; i++) {
2805 gst_mpdparser_build_URL_from_template (testUrl[i].urlTemplate, id,
2806 number, bandwidth, time);
2807 assert_equals_string (result, testUrl[i].expectedResponse);
2815 * Test handling isoff ondemand profile
2818 GST_START_TEST (dash_mpdparser_isoff_ondemand_profile)
2820 gboolean hasOnDemandProfile;
2823 "<?xml version=\"1.0\"?>"
2824 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2825 " profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"></MPD>";
2828 GstMpdClient *mpdclient = gst_mpd_client_new ();
2830 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2831 assert_equals_int (ret, TRUE);
2833 hasOnDemandProfile = gst_mpd_client_has_isoff_ondemand_profile (mpdclient);
2834 assert_equals_int (hasOnDemandProfile, 1);
2836 gst_mpd_client_free (mpdclient);
2842 * Test handling GstDateTime
2845 GST_START_TEST (dash_mpdparser_GstDateTime)
2854 time1 = gst_date_time_new_from_iso8601_string ("2012-06-23T23:30:59Z");
2855 time2 = gst_date_time_new_from_iso8601_string ("2012-06-23T23:31:00Z");
2857 delta = gst_mpd_client_calculate_time_difference (time1, time2);
2858 assert_equals_int64 (delta, 1 * GST_SECOND);
2861 gst_mpd_client_add_time_difference (time1, GST_TIME_AS_USECONDS (delta));
2863 /* convert to GDateTime in order to compare time2 and time 3 */
2864 g_time2 = gst_date_time_to_g_date_time (time2);
2865 g_time3 = gst_date_time_to_g_date_time (time3);
2866 fail_if (g_date_time_compare (g_time2, g_time3) != 0);
2868 gst_date_time_unref (time1);
2869 gst_date_time_unref (time2);
2870 gst_date_time_unref (time3);
2871 g_date_time_unref (g_time2);
2872 g_date_time_unref (g_time3);
2878 * Test bitstreamSwitching inheritance from Period to AdaptationSet
2880 * Description of bistreamSwitching attribute in Period:
2881 * "When set to ‘true’, this is equivalent as if the
2882 * AdaptationSet@bitstreamSwitching for each Adaptation Set contained in this
2883 * Period is set to 'true'. In this case, the AdaptationSet@bitstreamSwitching
2884 * attribute shall not be set to 'false' for any Adaptation Set in this Period"
2887 GST_START_TEST (dash_mpdparser_bitstreamSwitching_inheritance)
2889 GList *adaptationSets;
2890 GstAdaptationSetNode *adapt_set;
2891 guint activeStreams;
2892 GstActiveStream *activeStream;
2895 gboolean bitstreamSwitchingFlag;
2898 "<?xml version=\"1.0\"?>"
2899 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2900 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2901 " <Period id=\"Period0\""
2902 " duration=\"P0Y0M1DT1H1M1S\""
2903 " bitstreamSwitching=\"true\">"
2904 " <AdaptationSet id=\"1\""
2905 " mimeType=\"video/mp4\">"
2906 " <Representation id=\"1\" bandwidth=\"250000\">"
2907 " </Representation>"
2909 " <AdaptationSet id=\"2\""
2910 " mimeType=\"audio\""
2911 " bitstreamSwitching=\"false\">"
2912 " <Representation id=\"2\" bandwidth=\"250000\">"
2913 " </Representation></AdaptationSet></Period></MPD>";
2916 GstMpdClient *mpdclient = gst_mpd_client_new ();
2918 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
2919 assert_equals_int (ret, TRUE);
2921 /* process the xml data */
2922 ret = gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
2924 assert_equals_int (ret, TRUE);
2926 /* get the list of adaptation sets of the first period */
2927 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
2928 fail_if (adaptationSets == NULL);
2930 /* setup streaming from the first adaptation set */
2931 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
2932 fail_if (adapt_set == NULL);
2933 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
2934 assert_equals_int (ret, TRUE);
2936 /* setup streaming from the second adaptation set */
2937 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 1);
2938 fail_if (adapt_set == NULL);
2939 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
2940 assert_equals_int (ret, TRUE);
2942 /* 2 active streams */
2943 activeStreams = gst_mpdparser_get_nb_active_stream (mpdclient);
2944 assert_equals_int (activeStreams, 2);
2946 /* get details of the first active stream */
2947 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
2948 fail_if (activeStream == NULL);
2950 assert_equals_int (activeStream->mimeType, GST_STREAM_VIDEO);
2951 caps = gst_mpd_client_get_stream_caps (activeStream);
2952 fail_unless (caps != NULL);
2953 s = gst_caps_get_structure (caps, 0);
2954 assert_equals_string (gst_structure_get_name (s), "video/quicktime");
2955 gst_caps_unref (caps);
2957 /* inherited from Period's bitstreamSwitching */
2958 bitstreamSwitchingFlag =
2959 gst_mpd_client_get_bitstream_switching_flag (activeStream);
2960 assert_equals_int (bitstreamSwitchingFlag, TRUE);
2962 /* get details of the second active stream */
2963 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 1);
2964 fail_if (activeStream == NULL);
2966 assert_equals_int (activeStream->mimeType, GST_STREAM_AUDIO);
2967 caps = gst_mpd_client_get_stream_caps (activeStream);
2968 fail_unless (caps != NULL);
2969 s = gst_caps_get_structure (caps, 0);
2970 assert_equals_string (gst_structure_get_name (s), "audio");
2971 gst_caps_unref (caps);
2973 /* set to FALSE in our example, but overwritten to TRUE by Period's
2974 * bitstreamSwitching
2976 bitstreamSwitchingFlag =
2977 gst_mpd_client_get_bitstream_switching_flag (activeStream);
2978 assert_equals_int (bitstreamSwitchingFlag, TRUE);
2980 gst_mpd_client_free (mpdclient);
2986 * Test various duration formats
2988 GST_START_TEST (dash_mpdparser_various_duration_formats)
2990 GstPeriodNode *periodNode;
2992 "<?xml version=\"1.0\"?>"
2993 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2994 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
2995 " availabilityStartTime=\"2015-03-24T0:0:0\""
2996 " mediaPresentationDuration=\"P100Y\">"
2997 " <Period id=\"Period0\" start=\"PT1S\"></Period>"
2998 " <Period id=\"Period1\" start=\"PT1.5S\"></Period>"
2999 " <Period id=\"Period2\" start=\"PT1,7S\"></Period>"
3000 " <Period id=\"Period3\" start=\"PT1M\"></Period>"
3001 " <Period id=\"Period4\" start=\"PT1H\"></Period>"
3002 " <Period id=\"Period5\" start=\"P1D\"></Period>"
3003 " <Period id=\"Period6\" start=\"P1M\"></Period>"
3004 " <Period id=\"Period7\" start=\"P1Y\"></Period></MPD>";
3007 GstMpdClient *mpdclient = gst_mpd_client_new ();
3009 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3010 assert_equals_int (ret, TRUE);
3013 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3015 assert_equals_int (ret, TRUE);
3018 (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 0);
3019 assert_equals_string (periodNode->id, "Period0");
3020 assert_equals_uint64 (periodNode->start,
3021 duration_to_ms (0, 0, 0, 0, 0, 1, 0));
3024 (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 1);
3025 assert_equals_string (periodNode->id, "Period1");
3026 assert_equals_uint64 (periodNode->start,
3027 duration_to_ms (0, 0, 0, 0, 0, 1, 500));
3030 (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 2);
3031 assert_equals_string (periodNode->id, "Period2");
3032 assert_equals_uint64 (periodNode->start,
3033 duration_to_ms (0, 0, 0, 0, 0, 1, 700));
3036 (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 3);
3037 assert_equals_string (periodNode->id, "Period3");
3038 assert_equals_uint64 (periodNode->start,
3039 duration_to_ms (0, 0, 0, 0, 1, 0, 0));
3042 (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 4);
3043 assert_equals_string (periodNode->id, "Period4");
3044 assert_equals_uint64 (periodNode->start,
3045 duration_to_ms (0, 0, 0, 1, 0, 0, 0));
3048 (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 5);
3049 assert_equals_string (periodNode->id, "Period5");
3050 assert_equals_uint64 (periodNode->start,
3051 duration_to_ms (0, 0, 1, 0, 0, 0, 0));
3054 (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 6);
3055 assert_equals_string (periodNode->id, "Period6");
3056 assert_equals_uint64 (periodNode->start,
3057 duration_to_ms (0, 1, 0, 0, 0, 0, 0));
3060 (GstPeriodNode *) g_list_nth_data (mpdclient->mpd_node->Periods, 7);
3061 assert_equals_string (periodNode->id, "Period7");
3062 assert_equals_uint64 (periodNode->start,
3063 duration_to_ms (1, 0, 0, 0, 0, 0, 0));
3065 gst_mpd_client_free (mpdclient);
3071 * Test media presentation setup
3074 GST_START_TEST (dash_mpdparser_setup_media_presentation)
3077 "<?xml version=\"1.0\"?>"
3078 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3079 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3080 " <Period id=\"Period0\""
3081 " duration=\"P0Y0M1DT1H1M1S\"></Period></MPD>";
3084 GstMpdClient *mpdclient = gst_mpd_client_new ();
3086 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3087 assert_equals_int (ret, TRUE);
3089 /* process the xml data */
3091 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3093 assert_equals_int (ret, TRUE);
3095 gst_mpd_client_free (mpdclient);
3101 * Test setting a stream
3104 GST_START_TEST (dash_mpdparser_setup_streaming)
3106 GList *adaptationSets;
3107 GstAdaptationSetNode *adapt_set;
3110 "<?xml version=\"1.0\"?>"
3111 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3112 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3113 " <Period id=\"Period0\""
3114 " duration=\"P0Y0M1DT1H1M1S\">"
3115 " <AdaptationSet id=\"1\""
3116 " mimeType=\"video/mp4\">"
3117 " <Representation id=\"1\" bandwidth=\"250000\">"
3118 " </Representation></AdaptationSet></Period></MPD>";
3121 GstMpdClient *mpdclient = gst_mpd_client_new ();
3123 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3124 assert_equals_int (ret, TRUE);
3126 /* process the xml data */
3128 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3130 assert_equals_int (ret, TRUE);
3132 /* get the first adaptation set of the first period */
3133 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
3134 fail_if (adaptationSets == NULL);
3135 adapt_set = (GstAdaptationSetNode *) adaptationSets->data;
3136 fail_if (adapt_set == NULL);
3138 /* setup streaming from the adaptation set */
3139 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
3140 assert_equals_int (ret, TRUE);
3142 gst_mpd_client_free (mpdclient);
3148 * Test handling Period selection
3151 GST_START_TEST (dash_mpdparser_period_selection)
3153 const gchar *periodName;
3157 "<?xml version=\"1.0\"?>"
3158 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3159 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
3160 " mediaPresentationDuration=\"P0Y0M1DT1H4M3S\">"
3161 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\"></Period>"
3162 " <Period id=\"Period1\"></Period>"
3163 " <Period id=\"Period2\" start=\"P0Y0M1DT1H3M3S\"></Period></MPD>";
3166 GstMpdClient *mpdclient = gst_mpd_client_new ();
3168 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3169 assert_equals_int (ret, TRUE);
3171 /* period_idx should be 0 and we should have no active periods */
3172 assert_equals_uint64 (mpdclient->period_idx, 0);
3173 fail_unless (mpdclient->periods == NULL);
3175 /* process the xml data */
3177 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3179 assert_equals_int (ret, TRUE);
3181 /* check the periods */
3182 fail_unless (mpdclient->periods != NULL);
3183 periodName = gst_mpd_client_get_period_id (mpdclient);
3184 assert_equals_string (periodName, "Period0");
3186 ret = gst_mpd_client_set_period_index (mpdclient, 1);
3187 assert_equals_int (ret, TRUE);
3188 periodName = gst_mpd_client_get_period_id (mpdclient);
3189 assert_equals_string (periodName, "Period1");
3191 ret = gst_mpd_client_set_period_index (mpdclient, 2);
3192 assert_equals_int (ret, TRUE);
3193 periodName = gst_mpd_client_get_period_id (mpdclient);
3194 assert_equals_string (periodName, "Period2");
3196 ret = gst_mpd_client_has_next_period (mpdclient);
3197 assert_equals_int (ret, FALSE);
3198 ret = gst_mpd_client_has_previous_period (mpdclient);
3199 assert_equals_int (ret, TRUE);
3201 ret = gst_mpd_client_set_period_index (mpdclient, 0);
3202 assert_equals_int (ret, TRUE);
3203 ret = gst_mpd_client_has_next_period (mpdclient);
3204 assert_equals_int (ret, TRUE);
3205 ret = gst_mpd_client_has_previous_period (mpdclient);
3206 assert_equals_int (ret, FALSE);
3208 ret = gst_mpd_client_set_period_id (mpdclient, "Period1");
3209 assert_equals_int (ret, TRUE);
3210 periodIndex = gst_mpd_client_get_period_index (mpdclient);
3211 assert_equals_uint64 (periodIndex, 1);
3213 gst_mpd_client_free (mpdclient);
3219 * Test handling Period selection based on time
3222 GST_START_TEST (dash_mpdparser_get_period_at_time)
3228 "<?xml version=\"1.0\"?>"
3229 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3230 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
3231 " availabilityStartTime=\"2015-03-24T0:0:0\""
3232 " mediaPresentationDuration=\"P0Y0M1DT1H4M3S\">"
3233 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\"></Period>"
3234 " <Period id=\"Period1\"></Period>"
3235 " <Period id=\"Period2\" start=\"P0Y0M1DT1H3M3S\"></Period></MPD>";
3238 GstMpdClient *mpdclient = gst_mpd_client_new ();
3240 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3241 assert_equals_int (ret, TRUE);
3243 /* process the xml data */
3245 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3247 assert_equals_int (ret, TRUE);
3249 /* request period for a time before availabilityStartTime, expect period index 0 */
3250 time = gst_date_time_new_from_iso8601_string ("2015-03-23T23:30:59Z");
3251 periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time);
3252 gst_date_time_unref (time);
3253 assert_equals_int (periodIndex, 0);
3255 /* request period for a time from period 0 */
3256 time = gst_date_time_new_from_iso8601_string ("2015-03-24T23:30:59Z");
3257 periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time);
3258 gst_date_time_unref (time);
3259 assert_equals_int (periodIndex, 0);
3261 /* request period for a time from period 1 */
3262 time = gst_date_time_new_from_iso8601_string ("2015-03-25T1:1:1Z");
3263 periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time);
3264 gst_date_time_unref (time);
3265 assert_equals_int (periodIndex, 1);
3267 /* request period for a time from period 2 */
3268 time = gst_date_time_new_from_iso8601_string ("2015-03-25T1:3:3Z");
3269 periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time);
3270 gst_date_time_unref (time);
3271 assert_equals_int (periodIndex, 2);
3273 /* request period for a time after mediaPresentationDuration, expect period index G_MAXUINT */
3274 time = gst_date_time_new_from_iso8601_string ("2015-03-25T1:4:3Z");
3275 periodIndex = gst_mpd_client_get_period_index_at_time (mpdclient, time);
3276 gst_date_time_unref (time);
3277 assert_equals_int (periodIndex, G_MAXUINT);
3279 gst_mpd_client_free (mpdclient);
3285 * Test handling Adaptation sets
3288 GST_START_TEST (dash_mpdparser_adaptationSet_handling)
3290 const gchar *periodName;
3291 guint adaptation_sets_count;
3292 GList *adaptationSets, *it;
3296 "<?xml version=\"1.0\"?>"
3297 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3298 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3299 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3300 " <AdaptationSet id=\"1\"></AdaptationSet>"
3302 " <Period id=\"Period1\" duration=\"P0Y0M1DT1H1M1S\">"
3303 " <AdaptationSet id=\"10\"></AdaptationSet>"
3304 " <AdaptationSet id=\"11\"></AdaptationSet></Period></MPD>";
3307 GstMpdClient *mpdclient = gst_mpd_client_new ();
3309 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3310 assert_equals_int (ret, TRUE);
3312 /* process the xml data */
3314 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3316 assert_equals_int (ret, TRUE);
3318 /* period0 has 1 adaptation set */
3319 fail_unless (mpdclient->periods != NULL);
3320 periodName = gst_mpd_client_get_period_id (mpdclient);
3321 assert_equals_string (periodName, "Period0");
3322 adaptation_sets_count = gst_mpdparser_get_nb_adaptationSet (mpdclient);
3323 assert_equals_int (adaptation_sets_count, 1);
3325 /* period1 has 2 adaptation set */
3326 ret = gst_mpd_client_set_period_id (mpdclient, "Period1");
3327 assert_equals_int (ret, TRUE);
3328 adaptation_sets_count = gst_mpdparser_get_nb_adaptationSet (mpdclient);
3329 assert_equals_int (adaptation_sets_count, 2);
3331 /* check the id for the 2 adaptation sets from period 1 */
3332 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
3333 fail_if (adaptationSets == NULL);
3335 for (it = adaptationSets; it; it = g_list_next (it)) {
3336 GstAdaptationSetNode *adapt_set;
3337 adapt_set = (GstAdaptationSetNode *) it->data;
3338 fail_if (adapt_set == NULL);
3340 assert_equals_int (adapt_set->id, 10 + count);
3344 gst_mpd_client_free (mpdclient);
3350 * Test handling Representation selection
3353 GST_START_TEST (dash_mpdparser_representation_selection)
3355 GList *adaptationSets;
3356 GstAdaptationSetNode *adaptationSetNode;
3357 GList *representations;
3358 gint represendationIndex;
3361 "<?xml version=\"1.0\"?>"
3362 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3363 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3364 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3365 " <AdaptationSet id=\"1\" mimeType=\"video/mp4\">"
3366 " <Representation id=\"v0\" bandwidth=\"500000\"></Representation>"
3367 " <Representation id=\"v1\" bandwidth=\"250000\"></Representation>"
3368 " </AdaptationSet></Period></MPD>";
3371 GstMpdClient *mpdclient = gst_mpd_client_new ();
3373 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3374 assert_equals_int (ret, TRUE);
3376 /* process the xml data */
3378 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3380 assert_equals_int (ret, TRUE);
3382 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
3383 fail_if (adaptationSets == NULL);
3385 adaptationSetNode = adaptationSets->data;
3386 fail_if (adaptationSetNode == NULL);
3387 assert_equals_int (adaptationSetNode->id, 1);
3389 representations = adaptationSetNode->Representations;
3390 fail_if (representations == NULL);
3392 represendationIndex =
3393 gst_mpdparser_get_rep_idx_with_min_bandwidth (representations);
3394 assert_equals_int (represendationIndex, 1);
3396 represendationIndex =
3397 gst_mpdparser_get_rep_idx_with_max_bandwidth (representations, 0, 0, 0, 0,
3399 assert_equals_int (represendationIndex, 1);
3401 represendationIndex =
3402 gst_mpdparser_get_rep_idx_with_max_bandwidth (representations, 100000, 0,
3404 assert_equals_int (represendationIndex, -1);
3406 represendationIndex =
3407 gst_mpdparser_get_rep_idx_with_max_bandwidth (representations, 300000, 0,
3409 assert_equals_int (represendationIndex, 1);
3411 represendationIndex =
3412 gst_mpdparser_get_rep_idx_with_max_bandwidth (representations, 500000, 0,
3414 assert_equals_int (represendationIndex, 0);
3416 gst_mpd_client_free (mpdclient);
3422 * Test handling Active stream selection
3425 GST_START_TEST (dash_mpdparser_activeStream_selection)
3427 GList *adaptationSets;
3428 GstAdaptationSetNode *adapt_set;
3429 guint activeStreams;
3430 GstActiveStream *activeStream;
3433 "<?xml version=\"1.0\"?>"
3434 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3435 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3436 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3437 " <AdaptationSet id=\"1\" mimeType=\"video/mp4\">"
3438 " <Representation id=\"1\" bandwidth=\"250000\">"
3439 " </Representation>"
3441 " <AdaptationSet id=\"2\" mimeType=\"audio\">"
3442 " <Representation id=\"2\" bandwidth=\"250000\">"
3443 " </Representation>"
3445 " <AdaptationSet id=\"3\" mimeType=\"application\">"
3446 " <Representation id=\"3\" bandwidth=\"250000\">"
3447 " </Representation></AdaptationSet></Period></MPD>";
3450 GstMpdClient *mpdclient = gst_mpd_client_new ();
3452 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3453 assert_equals_int (ret, TRUE);
3455 /* process the xml data */
3457 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3459 assert_equals_int (ret, TRUE);
3461 /* get the list of adaptation sets of the first period */
3462 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
3463 fail_if (adaptationSets == NULL);
3465 /* no active streams yet */
3466 activeStreams = gst_mpdparser_get_nb_active_stream (mpdclient);
3467 assert_equals_int (activeStreams, 0);
3469 /* setup streaming from the first adaptation set */
3470 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
3471 fail_if (adapt_set == NULL);
3472 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
3473 assert_equals_int (ret, TRUE);
3475 /* 1 active streams */
3476 activeStreams = gst_mpdparser_get_nb_active_stream (mpdclient);
3477 assert_equals_int (activeStreams, 1);
3479 /* setup streaming from the second adaptation set */
3480 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 1);
3481 fail_if (adapt_set == NULL);
3482 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
3483 assert_equals_int (ret, TRUE);
3485 /* 2 active streams */
3486 activeStreams = gst_mpdparser_get_nb_active_stream (mpdclient);
3487 assert_equals_int (activeStreams, 2);
3489 /* setup streaming from the third adaptation set */
3490 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 2);
3491 fail_if (adapt_set == NULL);
3492 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
3493 assert_equals_int (ret, TRUE);
3495 /* 3 active streams */
3496 activeStreams = gst_mpdparser_get_nb_active_stream (mpdclient);
3497 assert_equals_int (activeStreams, 3);
3499 /* get details of the first active stream */
3500 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
3501 fail_if (activeStream == NULL);
3502 assert_equals_int (activeStream->mimeType, GST_STREAM_VIDEO);
3504 /* get details of the second active stream */
3505 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 1);
3506 fail_if (activeStream == NULL);
3507 assert_equals_int (activeStream->mimeType, GST_STREAM_AUDIO);
3509 /* get details of the third active stream */
3510 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 2);
3511 fail_if (activeStream == NULL);
3512 assert_equals_int (activeStream->mimeType, GST_STREAM_APPLICATION);
3514 gst_mpd_client_free (mpdclient);
3520 * Test getting Active stream parameters
3523 GST_START_TEST (dash_mpdparser_activeStream_parameters)
3525 GList *adaptationSets;
3526 GstAdaptationSetNode *adapt_set;
3527 guint activeStreams;
3528 GstActiveStream *activeStream;
3531 gboolean bitstreamSwitchingFlag;
3532 guint videoStreamWidth;
3533 guint videoStreamHeight;
3534 guint audioStreamRate;
3535 guint audioChannelsCount;
3538 "<?xml version=\"1.0\"?>"
3539 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3540 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3541 " <Period id=\"Period0\""
3542 " duration=\"P0Y0M1DT1H1M1S\">"
3543 " <AdaptationSet id=\"1\""
3544 " mimeType=\"video/mp4\""
3547 " bitstreamSwitching=\"true\""
3548 " audioSamplingRate=\"48000\">"
3549 " <Representation id=\"1\" bandwidth=\"250000\">"
3550 " </Representation></AdaptationSet></Period></MPD>";
3553 GstMpdClient *mpdclient = gst_mpd_client_new ();
3555 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3556 assert_equals_int (ret, TRUE);
3558 /* process the xml data */
3560 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3562 assert_equals_int (ret, TRUE);
3564 /* get the list of adaptation sets of the first period */
3565 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
3566 fail_if (adaptationSets == NULL);
3568 /* setup streaming from the first adaptation set */
3569 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
3570 fail_if (adapt_set == NULL);
3571 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
3572 assert_equals_int (ret, TRUE);
3574 /* 1 active streams */
3575 activeStreams = gst_mpdparser_get_nb_active_stream (mpdclient);
3576 assert_equals_int (activeStreams, 1);
3578 /* get details of the first active stream */
3579 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
3580 fail_if (activeStream == NULL);
3582 assert_equals_int (activeStream->mimeType, GST_STREAM_VIDEO);
3583 caps = gst_mpd_client_get_stream_caps (activeStream);
3584 fail_unless (caps != NULL);
3585 s = gst_caps_get_structure (caps, 0);
3586 assert_equals_string (gst_structure_get_name (s), "video/quicktime");
3587 gst_caps_unref (caps);
3589 bitstreamSwitchingFlag =
3590 gst_mpd_client_get_bitstream_switching_flag (activeStream);
3591 assert_equals_int (bitstreamSwitchingFlag, 1);
3593 videoStreamWidth = gst_mpd_client_get_video_stream_width (activeStream);
3594 assert_equals_int (videoStreamWidth, 320);
3596 videoStreamHeight = gst_mpd_client_get_video_stream_height (activeStream);
3597 assert_equals_int (videoStreamHeight, 240);
3599 audioStreamRate = gst_mpd_client_get_audio_stream_rate (activeStream);
3600 assert_equals_int (audioStreamRate, 48000);
3602 audioChannelsCount =
3603 gst_mpd_client_get_audio_stream_num_channels (activeStream);
3604 assert_equals_int (audioChannelsCount, 0);
3606 gst_mpd_client_free (mpdclient);
3612 * Test getting number and list of audio languages
3615 GST_START_TEST (dash_mpdparser_get_audio_languages)
3617 GList *adaptationSets;
3618 GstAdaptationSetNode *adapt_set;
3619 guint activeStreams;
3620 guint adaptationSetsCount;
3621 GList *languages = NULL;
3622 guint languagesCount;
3625 "<?xml version=\"1.0\"?>"
3626 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3627 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3628 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3629 " <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3630 " <Representation id=\"1\" bandwidth=\"250000\">"
3631 " </Representation>"
3633 " <AdaptationSet id=\"2\" mimeType=\"video/mp4\">"
3634 " <Representation id=\"2\" bandwidth=\"250000\">"
3635 " </Representation>"
3637 " <AdaptationSet id=\"3\" mimeType=\"audio\" lang=\"fr\">"
3638 " <Representation id=\"3\" bandwidth=\"250000\">"
3639 " </Representation></AdaptationSet></Period></MPD>";
3642 GstMpdClient *mpdclient = gst_mpd_client_new ();
3645 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3646 assert_equals_int (ret, TRUE);
3648 /* process the xml data */
3650 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3652 assert_equals_int (ret, TRUE);
3654 /* get the list of adaptation sets of the first period */
3655 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
3656 fail_if (adaptationSets == NULL);
3658 /* setup streaming from all adaptation sets */
3659 adaptationSetsCount = gst_mpdparser_get_nb_adaptationSet (mpdclient);
3660 for (i = 0; i < adaptationSetsCount; i++) {
3661 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, i);
3662 fail_if (adapt_set == NULL);
3663 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
3664 assert_equals_int (ret, TRUE);
3666 activeStreams = gst_mpdparser_get_nb_active_stream (mpdclient);
3667 assert_equals_int (activeStreams, adaptationSetsCount);
3670 gst_mpdparser_get_list_and_nb_of_audio_language (mpdclient, &languages);
3671 assert_equals_int (languagesCount, 2);
3672 assert_equals_string ((gchar *) g_list_nth_data (languages, 0), "en");
3673 assert_equals_string ((gchar *) g_list_nth_data (languages, 1), "fr");
3675 g_list_free (languages);
3677 gst_mpd_client_free (mpdclient);
3683 * Tests getting the base URL
3686 static GstMpdClient *
3687 setup_mpd_client (const gchar * xml)
3689 GList *adaptationSets;
3690 GstAdaptationSetNode *adapt_set;
3691 guint activeStreams;
3692 guint adaptationSetsCount;
3694 GstMpdClient *mpdclient = gst_mpd_client_new ();
3697 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
3698 assert_equals_int (ret, TRUE);
3700 /* process the xml data */
3702 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3704 assert_equals_int (ret, TRUE);
3706 /* get the list of adaptation sets of the first period */
3707 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
3708 fail_if (adaptationSets == NULL);
3710 /* setup streaming from all adaptation sets */
3711 adaptationSetsCount = gst_mpdparser_get_nb_adaptationSet (mpdclient);
3712 for (i = 0; i < adaptationSetsCount; i++) {
3713 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, i);
3714 fail_if (adapt_set == NULL);
3715 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
3716 assert_equals_int (ret, TRUE);
3718 activeStreams = gst_mpdparser_get_nb_active_stream (mpdclient);
3719 assert_equals_int (activeStreams, adaptationSetsCount);
3724 GST_START_TEST (dash_mpdparser_get_baseURL1)
3726 const gchar *baseURL;
3728 "<?xml version=\"1.0\"?>"
3729 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3730 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3731 " <BaseURL>http://example.com/</BaseURL>"
3732 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3733 " <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3734 " <Representation id=\"1\" bandwidth=\"250000\">"
3735 " </Representation></AdaptationSet></Period></MPD>";
3737 GstMpdClient *mpdclient = setup_mpd_client (xml);
3739 baseURL = gst_mpdparser_get_baseURL (mpdclient, 0);
3740 fail_if (baseURL == NULL);
3741 assert_equals_string (baseURL, "http://example.com/");
3743 gst_mpd_client_free (mpdclient);
3749 GST_START_TEST (dash_mpdparser_get_baseURL2)
3751 const gchar *baseURL;
3753 "<?xml version=\"1.0\"?>"
3754 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3755 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3756 " <BaseURL>mpd_base_url/</BaseURL>"
3757 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3758 " <BaseURL> /period_base_url/</BaseURL>"
3759 " <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3760 " <BaseURL>adaptation_base_url</BaseURL>"
3761 " <Representation id=\"1\" bandwidth=\"250000\">"
3762 " <BaseURL>representation_base_url</BaseURL>"
3763 " </Representation></AdaptationSet></Period></MPD>";
3765 GstMpdClient *mpdclient = setup_mpd_client (xml);
3767 /* test baseURL. Its value should be computed like this:
3768 * - start with xml url (null)
3769 * - set it to the value from MPD's BaseURL element: "mpd_base_url/"
3770 * - update the value with BaseURL element from Period. Because Period's
3771 * baseURL is absolute (starts with /) it will overwrite the current value
3772 * for baseURL. So, baseURL becomes "/period_base_url/"
3773 * - update the value with BaseURL element from AdaptationSet. Because this
3774 * is a relative url, it will update the current value. baseURL becomes
3775 * "/period_base_url/adaptation_base_url"
3776 * - update the value with BaseURL element from Representation. Because this
3777 * is a relative url, it will update the current value. Because the current
3778 * value does not end in /, everything after the last / will be overwritten.
3779 * baseURL becomes "/period_base_url/representation_base_url"
3781 baseURL = gst_mpdparser_get_baseURL (mpdclient, 0);
3782 fail_if (baseURL == NULL);
3783 assert_equals_string (baseURL, "/period_base_url/representation_base_url");
3785 gst_mpd_client_free (mpdclient);
3791 GST_START_TEST (dash_mpdparser_get_baseURL3)
3793 const gchar *baseURL;
3795 "<?xml version=\"1.0\"?>"
3796 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3797 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3798 " <BaseURL>mpd_base_url/</BaseURL>"
3799 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3800 " <BaseURL> /period_base_url/</BaseURL>"
3801 " <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3802 " <BaseURL>adaptation_base_url</BaseURL>"
3803 " <Representation id=\"1\" bandwidth=\"250000\">"
3804 " <BaseURL>/representation_base_url</BaseURL>"
3805 " </Representation></AdaptationSet></Period></MPD>";
3807 GstMpdClient *mpdclient = setup_mpd_client (xml);
3809 /* test baseURL. Its value should be computed like this:
3810 * - start with xml url (null)
3811 * - set it to the value from MPD's BaseURL element: "mpd_base_url/"
3812 * - update the value with BaseURL element from Period. Because Period's
3813 * baseURL is absolute (starts with /) it will overwrite the current value
3814 * for baseURL. So, baseURL becomes "/period_base_url/"
3815 * - update the value with BaseURL element from AdaptationSet. Because this
3816 * is a relative url, it will update the current value. baseURL becomes
3817 * "/period_base_url/adaptation_base_url"
3818 * - update the value with BaseURL element from Representation. Because this
3819 * is an absolute url, it will replace everything again"
3821 baseURL = gst_mpdparser_get_baseURL (mpdclient, 0);
3822 fail_if (baseURL == NULL);
3823 assert_equals_string (baseURL, "/representation_base_url");
3825 gst_mpd_client_free (mpdclient);
3831 GST_START_TEST (dash_mpdparser_get_baseURL4)
3833 const gchar *baseURL;
3835 "<?xml version=\"1.0\"?>"
3836 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3837 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3838 " <BaseURL>mpd_base_url/</BaseURL>"
3839 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3840 " <BaseURL> /period_base_url/</BaseURL>"
3841 " <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3842 " <BaseURL>adaptation_base_url/</BaseURL>"
3843 " <Representation id=\"1\" bandwidth=\"250000\">"
3844 " <BaseURL>representation_base_url/</BaseURL>"
3845 " </Representation></AdaptationSet></Period></MPD>";
3847 GstMpdClient *mpdclient = setup_mpd_client (xml);
3849 /* test baseURL. Its value should be computed like this:
3850 * - start with xml url (null)
3851 * - set it to the value from MPD's BaseURL element: "mpd_base_url/"
3852 * - update the value with BaseURL element from Period. Because Period's
3853 * baseURL is absolute (starts with /) it will overwrite the current value
3854 * for baseURL. So, baseURL becomes "/period_base_url/"
3855 * - update the value with BaseURL element from AdaptationSet. Because this
3856 * is a relative url, it will update the current value. baseURL becomes
3857 * "/period_base_url/adaptation_base_url/"
3858 * - update the value with BaseURL element from Representation. Because this
3859 * is an relative url, it will update the current value."
3861 baseURL = gst_mpdparser_get_baseURL (mpdclient, 0);
3862 fail_if (baseURL == NULL);
3863 assert_equals_string (baseURL,
3864 "/period_base_url/adaptation_base_url/representation_base_url/");
3866 gst_mpd_client_free (mpdclient);
3871 /* test multiple BaseUrl entries per section */
3872 GST_START_TEST (dash_mpdparser_get_baseURL5)
3874 GstPeriodNode *periodNode;
3875 GstAdaptationSetNode *adaptationSet;
3876 GstRepresentationNode *representation;
3877 const gchar *baseURL;
3878 GstBaseURL *gstBaseURL;
3881 "<?xml version=\"1.0\"?>"
3882 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3883 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3884 " <BaseURL>/mpd_base_url1/</BaseURL>"
3885 " <BaseURL>/mpd_base_url2/</BaseURL>"
3886 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3887 " <BaseURL> period_base_url1/</BaseURL>"
3888 " <BaseURL> period_base_url2/</BaseURL>"
3889 " <BaseURL> period_base_url3/</BaseURL>"
3890 " <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3891 " <BaseURL>adaptation_base_url1/</BaseURL>"
3892 " <BaseURL>adaptation_base_url2/</BaseURL>"
3893 " <BaseURL>adaptation_base_url3/</BaseURL>"
3894 " <BaseURL>adaptation_base_url4/</BaseURL>"
3895 " <Representation id=\"1\" bandwidth=\"250000\">"
3896 " <BaseURL>representation_base_url1/</BaseURL>"
3897 " <BaseURL>representation_base_url2/</BaseURL>"
3898 " <BaseURL>representation_base_url3/</BaseURL>"
3899 " <BaseURL>representation_base_url4/</BaseURL>"
3900 " <BaseURL>representation_base_url5/</BaseURL>"
3901 " </Representation></AdaptationSet></Period></MPD>";
3903 GstMpdClient *mpdclient = setup_mpd_client (xml);
3905 assert_equals_int (g_list_length (mpdclient->mpd_node->BaseURLs), 2);
3906 gstBaseURL = g_list_nth_data (mpdclient->mpd_node->BaseURLs, 0);
3907 assert_equals_string (gstBaseURL->baseURL, "/mpd_base_url1/");
3908 gstBaseURL = g_list_nth_data (mpdclient->mpd_node->BaseURLs, 1);
3909 assert_equals_string (gstBaseURL->baseURL, "/mpd_base_url2/");
3911 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
3912 assert_equals_int (g_list_length (periodNode->BaseURLs), 3);
3913 gstBaseURL = g_list_nth_data (periodNode->BaseURLs, 0);
3914 assert_equals_string (gstBaseURL->baseURL, " period_base_url1/");
3915 gstBaseURL = g_list_nth_data (periodNode->BaseURLs, 1);
3916 assert_equals_string (gstBaseURL->baseURL, " period_base_url2/");
3917 gstBaseURL = g_list_nth_data (periodNode->BaseURLs, 2);
3918 assert_equals_string (gstBaseURL->baseURL, " period_base_url3/");
3920 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
3921 assert_equals_int (g_list_length (adaptationSet->BaseURLs), 4);
3922 gstBaseURL = g_list_nth_data (adaptationSet->BaseURLs, 0);
3923 assert_equals_string (gstBaseURL->baseURL, "adaptation_base_url1/");
3924 gstBaseURL = g_list_nth_data (adaptationSet->BaseURLs, 1);
3925 assert_equals_string (gstBaseURL->baseURL, "adaptation_base_url2/");
3926 gstBaseURL = g_list_nth_data (adaptationSet->BaseURLs, 2);
3927 assert_equals_string (gstBaseURL->baseURL, "adaptation_base_url3/");
3928 gstBaseURL = g_list_nth_data (adaptationSet->BaseURLs, 3);
3929 assert_equals_string (gstBaseURL->baseURL, "adaptation_base_url4/");
3931 representation = (GstRepresentationNode *)
3932 adaptationSet->Representations->data;
3933 assert_equals_int (g_list_length (representation->BaseURLs), 5);
3934 gstBaseURL = g_list_nth_data (representation->BaseURLs, 0);
3935 assert_equals_string (gstBaseURL->baseURL, "representation_base_url1/");
3936 gstBaseURL = g_list_nth_data (representation->BaseURLs, 1);
3937 assert_equals_string (gstBaseURL->baseURL, "representation_base_url2/");
3938 gstBaseURL = g_list_nth_data (representation->BaseURLs, 2);
3939 assert_equals_string (gstBaseURL->baseURL, "representation_base_url3/");
3940 gstBaseURL = g_list_nth_data (representation->BaseURLs, 3);
3941 assert_equals_string (gstBaseURL->baseURL, "representation_base_url4/");
3942 gstBaseURL = g_list_nth_data (representation->BaseURLs, 4);
3943 assert_equals_string (gstBaseURL->baseURL, "representation_base_url5/");
3945 /* test baseURL. Its value should be computed like this:
3946 * - start with xml url (null)
3947 * - set it to the value from MPD's BaseURL element: "/mpd_base_url1/"
3948 * - update the value with BaseURL element from Period. Because this
3949 * is a relative url, it will update the current value. baseURL becomes
3950 * "/mpd_base_url1/period_base_url1/"
3951 * - update the value with BaseURL element from AdaptationSet. Because this
3952 * is a relative url, it will update the current value. baseURL becomes
3953 * "/mpd_base_url1/period_base_url1/adaptation_base_url1/"
3954 * - update the value with BaseURL element from Representation. Because this
3955 * is an relative url, it will update the current value."
3957 baseURL = gst_mpdparser_get_baseURL (mpdclient, 0);
3958 fail_if (baseURL == NULL);
3959 assert_equals_string (baseURL,
3960 "/mpd_base_url1/period_base_url1/adaptation_base_url1/representation_base_url1/");
3962 gst_mpd_client_free (mpdclient);
3967 /* test no BaseURL */
3968 GST_START_TEST (dash_mpdparser_get_baseURL6)
3970 const gchar *baseURL;
3972 "<?xml version=\"1.0\"?>"
3973 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3974 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3975 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3976 " <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3977 " <Representation id=\"1\" bandwidth=\"250000\">"
3978 " </Representation></AdaptationSet></Period></MPD>";
3980 GstMpdClient *mpdclient = setup_mpd_client (xml);
3982 baseURL = gst_mpdparser_get_baseURL (mpdclient, 0);
3983 fail_if (baseURL == NULL);
3984 assert_equals_string (baseURL, "");
3986 gst_mpd_client_free (mpdclient);
3991 /* BaseURL: test that the path is made absolute (a / is prepended if needed */
3992 GST_START_TEST (dash_mpdparser_get_baseURL7)
3994 const gchar *baseURL;
3996 "<?xml version=\"1.0\"?>"
3997 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3998 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3999 " <BaseURL>x/example.com/</BaseURL>"
4000 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
4001 " <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
4002 " <Representation id=\"1\" bandwidth=\"250000\">"
4003 " </Representation></AdaptationSet></Period></MPD>";
4005 GstMpdClient *mpdclient;
4007 mpdclient = setup_mpd_client (xml);
4009 baseURL = gst_mpdparser_get_baseURL (mpdclient, 0);
4010 fail_if (baseURL == NULL);
4011 assert_equals_string (baseURL, "/x/example.com/");
4013 gst_mpd_client_free (mpdclient);
4018 /* BaseURL: test that a / is not prepended if the string contains ':'
4019 * This tests uris with schema present */
4020 GST_START_TEST (dash_mpdparser_get_baseURL8)
4022 const gchar *baseURL;
4024 "<?xml version=\"1.0\"?>"
4025 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4026 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
4027 " <BaseURL>x:y/example.com/</BaseURL>"
4028 " <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
4029 " <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
4030 " <Representation id=\"1\" bandwidth=\"250000\">"
4031 " </Representation></AdaptationSet></Period></MPD>";
4033 GstMpdClient *mpdclient = setup_mpd_client (xml);
4035 baseURL = gst_mpdparser_get_baseURL (mpdclient, 0);
4036 fail_if (baseURL == NULL);
4037 assert_equals_string (baseURL, "x:y/example.com/");
4039 gst_mpd_client_free (mpdclient);
4045 * Test getting mediaPresentationDuration
4048 GST_START_TEST (dash_mpdparser_get_mediaPresentationDuration)
4050 GstClockTime mediaPresentationDuration;
4053 "<?xml version=\"1.0\"?>"
4054 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4055 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4056 " mediaPresentationDuration=\"P0Y0M0DT0H0M3S\"></MPD>";
4059 GstMpdClient *mpdclient = gst_mpd_client_new ();
4061 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4062 assert_equals_int (ret, TRUE);
4064 mediaPresentationDuration =
4065 gst_mpd_client_get_media_presentation_duration (mpdclient);
4066 assert_equals_uint64 (mediaPresentationDuration, 3000000000);
4068 gst_mpd_client_free (mpdclient);
4074 * Test getting streamPresentationOffset
4077 GST_START_TEST (dash_mpdparser_get_streamPresentationOffset)
4079 GList *adaptationSets;
4080 GstAdaptationSetNode *adapt_set;
4081 GstClockTime offset;
4083 "<?xml version=\"1.0\"?>"
4084 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4085 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4086 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4088 " <AdaptationSet mimeType=\"video/mp4\">"
4089 " <SegmentBase timescale=\"1000\" presentationTimeOffset=\"3000\">"
4091 " <Representation id=\"1\" bandwidth=\"250000\">"
4092 " </Representation></AdaptationSet></Period></MPD>";
4095 GstMpdClient *mpdclient = gst_mpd_client_new ();
4097 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4098 assert_equals_int (ret, TRUE);
4100 /* process the xml data */
4102 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4104 assert_equals_int (ret, TRUE);
4106 /* get the list of adaptation sets of the first period */
4107 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
4108 fail_if (adaptationSets == NULL);
4110 /* setup streaming from the first adaptation set */
4111 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4112 fail_if (adapt_set == NULL);
4113 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
4114 assert_equals_int (ret, TRUE);
4116 /* test the stream presentation time offset */
4117 offset = gst_mpd_parser_get_stream_presentation_offset (mpdclient, 0);
4118 /* seems to be set only for template segments, so here it is 0 */
4119 assert_equals_int (offset, 0);
4121 gst_mpd_client_free (mpdclient);
4127 * Test handling segments
4130 GST_START_TEST (dash_mpdparser_segments)
4132 GList *adaptationSets;
4133 GstAdaptationSetNode *adapt_set;
4134 gboolean hasNextSegment;
4135 GstActiveStream *activeStream;
4137 GstDateTime *segmentAvailability;
4138 GstDateTime *gst_time;
4142 "<?xml version=\"1.0\"?>"
4143 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4145 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4146 " availabilityStartTime=\"2015-03-24T0:0:0\""
4147 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4148 " <Period id=\"Period0\" start=\"P0Y0M0DT0H0M10S\">"
4149 " <AdaptationSet mimeType=\"video/mp4\">"
4150 " <Representation id=\"1\" bandwidth=\"250000\">"
4151 " <SegmentList duration=\"45\">"
4152 " <SegmentURL media=\"TestMedia1\""
4153 " mediaRange=\"10-20\""
4154 " index=\"TestIndex1\""
4155 " indexRange=\"30-40\">"
4157 " <SegmentURL media=\"TestMedia2\""
4158 " mediaRange=\"20-30\""
4159 " index=\"TestIndex2\""
4160 " indexRange=\"40-50\">"
4163 " </Representation></AdaptationSet></Period></MPD>";
4166 GstMpdClient *mpdclient = gst_mpd_client_new ();
4168 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4169 assert_equals_int (ret, TRUE);
4171 /* process the xml data */
4173 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4175 assert_equals_int (ret, TRUE);
4177 /* get the list of adaptation sets of the first period */
4178 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
4179 fail_if (adaptationSets == NULL);
4181 /* setup streaming from the first adaptation set */
4182 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4183 fail_if (adapt_set == NULL);
4184 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
4185 assert_equals_int (ret, TRUE);
4187 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
4188 fail_if (activeStream == NULL);
4190 /* segment_index 0, segment_count 2.
4191 * Has next segment and can advance to next segment
4194 gst_mpd_client_has_next_segment (mpdclient, activeStream, TRUE);
4195 assert_equals_int (hasNextSegment, 1);
4196 flow = gst_mpd_client_advance_segment (mpdclient, activeStream, TRUE);
4197 assert_equals_int (flow, GST_FLOW_OK);
4199 /* segment_index 1, segment_count 2.
4200 * Does not have next segment and can not advance to next segment
4203 gst_mpd_client_has_next_segment (mpdclient, activeStream, TRUE);
4204 assert_equals_int (hasNextSegment, 0);
4205 flow = gst_mpd_client_advance_segment (mpdclient, activeStream, TRUE);
4206 assert_equals_int (flow, GST_FLOW_EOS);
4208 /* go to first segment */
4209 gst_mpd_client_seek_to_first_segment (mpdclient);
4211 /* segment_index 0, segment_count 2.
4212 * Has next segment and can advance to next segment
4215 gst_mpd_client_has_next_segment (mpdclient, activeStream, TRUE);
4216 assert_equals_int (hasNextSegment, 1);
4217 flow = gst_mpd_client_advance_segment (mpdclient, activeStream, TRUE);
4218 assert_equals_int (flow, GST_FLOW_OK);
4220 /* segment_index 1, segment_count 2
4221 * Does not have next segment
4224 gst_mpd_client_has_next_segment (mpdclient, activeStream, TRUE);
4225 assert_equals_int (hasNextSegment, 0);
4227 /* segment index is still 1 */
4229 gst_mpd_client_has_next_segment (mpdclient, activeStream, TRUE);
4230 assert_equals_int (hasNextSegment, 0);
4232 /* each segment has a duration of 0 hours, 0 min 45 seconds
4233 * segment index is 1.
4234 * Start time is at the beginning of segment 1, so 1 * segment_duration = 1 * 45s
4235 * Availability start time is at the end of the segment, so we add duration (45s)
4236 * We also add period start time (10s)
4237 * So, availability start time for segment 1 is: 10 (period start) +
4238 * 45 (segment start) + 45 (duration) = 1'40s
4240 segmentAvailability =
4241 gst_mpd_client_get_next_segment_availability_start_time (mpdclient,
4243 assert_equals_int (gst_date_time_get_year (segmentAvailability), 2015);
4244 assert_equals_int (gst_date_time_get_month (segmentAvailability), 3);
4245 assert_equals_int (gst_date_time_get_day (segmentAvailability), 24);
4246 assert_equals_int (gst_date_time_get_hour (segmentAvailability), 0);
4247 assert_equals_int (gst_date_time_get_minute (segmentAvailability), 1);
4248 assert_equals_int (gst_date_time_get_second (segmentAvailability), 40);
4249 gst_date_time_unref (segmentAvailability);
4252 gst_time = gst_date_time_new_from_iso8601_string ("2015-03-24T0:0:20Z");
4253 g_time = gst_date_time_to_g_date_time (gst_time);
4254 ret = gst_mpd_client_seek_to_time (mpdclient, g_time);
4255 assert_equals_int (ret, 1);
4256 gst_date_time_unref (gst_time);
4257 g_date_time_unref (g_time);
4259 /* segment index is now 0 */
4261 gst_mpd_client_has_next_segment (mpdclient, activeStream, TRUE);
4262 assert_equals_int (hasNextSegment, 1);
4264 gst_mpd_client_free (mpdclient);
4270 * Test handling headers
4273 GST_START_TEST (dash_mpdparser_headers)
4275 GList *adaptationSets;
4276 GstAdaptationSetNode *adapt_set;
4282 "<?xml version=\"1.0\"?>"
4283 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4285 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4286 " availabilityStartTime=\"2015-03-24T0:0:0\""
4287 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4288 " <Period id=\"Period0\">"
4289 " <AdaptationSet mimeType=\"video/mp4\">"
4290 " <Representation id=\"1\" bandwidth=\"250000\">"
4291 " <SegmentBase indexRange=\"10-20\">"
4292 " <Initialization sourceURL=\"TestSourceUrl\""
4293 " range=\"100-200\">"
4294 " </Initialization>"
4295 " <RepresentationIndex sourceURL=\"TestSourceIndex\">"
4296 " </RepresentationIndex>"
4298 " </Representation></AdaptationSet></Period></MPD>";
4301 GstMpdClient *mpdclient = gst_mpd_client_new ();
4303 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4304 assert_equals_int (ret, TRUE);
4306 /* process the xml data */
4308 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4310 assert_equals_int (ret, TRUE);
4312 /* get the list of adaptation sets of the first period */
4313 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
4314 fail_if (adaptationSets == NULL);
4316 /* setup streaming from the first adaptation set */
4317 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4318 fail_if (adapt_set == NULL);
4319 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
4320 assert_equals_int (ret, TRUE);
4322 /* get segment url and range from segment Initialization */
4324 gst_mpd_client_get_next_header (mpdclient, &uri, 0, &range_start,
4326 assert_equals_int (ret, TRUE);
4327 assert_equals_string (uri, "TestSourceUrl");
4328 assert_equals_int64 (range_start, 100);
4329 assert_equals_int64 (range_end, 200);
4332 /* get segment url and range from segment indexRange */
4334 gst_mpd_client_get_next_header_index (mpdclient, &uri, 0, &range_start,
4336 assert_equals_int (ret, TRUE);
4337 assert_equals_string (uri, "TestSourceIndex");
4338 assert_equals_int64 (range_start, 10);
4339 assert_equals_int64 (range_end, 20);
4342 gst_mpd_client_free (mpdclient);
4348 * Test handling fragments
4351 GST_START_TEST (dash_mpdparser_fragments)
4353 GList *adaptationSets;
4354 GstAdaptationSetNode *adapt_set;
4355 GstMediaFragmentInfo fragment;
4356 GstActiveStream *activeStream;
4357 GstClockTime nextFragmentDuration;
4358 GstClockTime nextFragmentTimestamp;
4359 GstClockTime nextFragmentTimestampEnd;
4360 GstClockTime periodStartTime;
4361 GstClockTime expectedDuration;
4362 GstClockTime expectedTimestamp;
4363 GstClockTime expectedTimestampEnd;
4366 "<?xml version=\"1.0\"?>"
4367 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4368 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4369 " availabilityStartTime=\"2015-03-24T0:0:0\""
4370 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4371 " <Period id=\"Period0\" start=\"P0Y0M0DT0H0M10S\">"
4372 " <AdaptationSet mimeType=\"video/mp4\">"
4373 " <Representation id=\"1\" bandwidth=\"250000\">"
4374 " </Representation></AdaptationSet></Period></MPD>";
4377 GstMpdClient *mpdclient = gst_mpd_client_new ();
4379 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4380 assert_equals_int (ret, TRUE);
4382 /* process the xml data */
4384 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4386 assert_equals_int (ret, TRUE);
4388 /* get the list of adaptation sets of the first period */
4389 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
4390 fail_if (adaptationSets == NULL);
4392 /* setup streaming from the first adaptation set */
4393 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4394 fail_if (adapt_set == NULL);
4395 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
4396 assert_equals_int (ret, TRUE);
4397 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
4398 fail_if (activeStream == NULL);
4400 /* expected duration of the next fragment */
4401 expectedDuration = duration_to_ms (0, 0, 0, 3, 3, 20, 0);
4402 expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 0, 0);
4403 expectedTimestampEnd = duration_to_ms (0, 0, 0, 3, 3, 20, 0);
4405 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
4406 assert_equals_int (ret, TRUE);
4407 assert_equals_string (fragment.uri, "");
4408 assert_equals_int64 (fragment.range_start, 0);
4409 assert_equals_int64 (fragment.range_end, -1);
4410 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4411 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4412 gst_media_fragment_info_clear (&fragment);
4414 periodStartTime = gst_mpd_parser_get_period_start_time (mpdclient);
4415 assert_equals_uint64 (periodStartTime, 10 * GST_SECOND);
4417 nextFragmentDuration =
4418 gst_mpd_client_get_next_fragment_duration (mpdclient, activeStream);
4419 assert_equals_uint64 (nextFragmentDuration, expectedDuration * GST_MSECOND);
4422 gst_mpd_client_get_next_fragment_timestamp (mpdclient, 0,
4423 &nextFragmentTimestamp);
4424 assert_equals_int (ret, TRUE);
4425 assert_equals_uint64 (nextFragmentTimestamp, expectedTimestamp * GST_MSECOND);
4428 gst_mpd_client_get_last_fragment_timestamp_end (mpdclient, 0,
4429 &nextFragmentTimestampEnd);
4430 assert_equals_int (ret, TRUE);
4431 assert_equals_uint64 (nextFragmentTimestampEnd,
4432 expectedTimestampEnd * GST_MSECOND);
4434 gst_mpd_client_free (mpdclient);
4440 * Test inheriting segmentBase from parent
4443 GST_START_TEST (dash_mpdparser_inherited_segmentBase)
4445 GstPeriodNode *periodNode;
4446 GstSegmentBaseType *segmentBase;
4447 GstAdaptationSetNode *adaptationSet;
4448 GstRepresentationNode *representation;
4450 "<?xml version=\"1.0\"?>"
4451 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4452 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
4455 " <SegmentBase timescale=\"100\">"
4457 " <Representation id=\"1\" bandwidth=\"250000\">"
4458 " <SegmentBase timescale=\"200\">"
4460 " </Representation></AdaptationSet></Period></MPD>";
4463 GstMpdClient *mpdclient = gst_mpd_client_new ();
4465 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4466 assert_equals_int (ret, TRUE);
4468 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
4469 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
4470 representation = (GstRepresentationNode *)
4471 adaptationSet->Representations->data;
4473 /* test segment base from adaptation set */
4474 segmentBase = adaptationSet->SegmentBase;
4475 assert_equals_uint64 (segmentBase->timescale, 100);
4477 /* test segment base from representation */
4478 segmentBase = representation->SegmentBase;
4479 assert_equals_uint64 (segmentBase->timescale, 200);
4481 gst_mpd_client_free (mpdclient);
4487 * Test inheriting segmentURL from parent
4490 GST_START_TEST (dash_mpdparser_inherited_segmentURL)
4492 GList *adaptationSets;
4493 GstAdaptationSetNode *adapt_set;
4494 GstActiveStream *activeStream;
4495 GstMediaFragmentInfo fragment;
4496 GstClockTime expectedDuration;
4497 GstClockTime expectedTimestamp;
4501 "<?xml version=\"1.0\"?>"
4502 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4503 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4504 " availabilityStartTime=\"2015-03-24T0:0:0\""
4505 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4507 " <AdaptationSet mimeType=\"video/mp4\">"
4508 " <SegmentList duration=\"100\">"
4509 " <SegmentURL media=\"TestMediaAdaptation\""
4510 " mediaRange=\"10-20\""
4511 " index=\"TestIndexAdaptation\""
4512 " indexRange=\"30-40\">"
4515 " <Representation id=\"1\" bandwidth=\"250000\">"
4516 " <SegmentList duration=\"110\">"
4517 " <SegmentURL media=\"TestMediaRep\""
4518 " mediaRange=\"100-200\""
4519 " index=\"TestIndexRep\""
4520 " indexRange=\"300-400\">"
4523 " </Representation></AdaptationSet></Period></MPD>";
4526 GstMpdClient *mpdclient = gst_mpd_client_new ();
4528 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4529 assert_equals_int (ret, TRUE);
4531 /* process the xml data */
4533 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4535 assert_equals_int (ret, TRUE);
4537 /* get the list of adaptation sets of the first period */
4538 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
4539 fail_if (adaptationSets == NULL);
4541 /* setup streaming from the first adaptation set */
4542 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4543 fail_if (adapt_set == NULL);
4544 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
4545 assert_equals_int (ret, TRUE);
4547 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
4548 fail_if (activeStream == NULL);
4550 /* expected duration of the next fragment
4551 * Segment duration was set to 100 in AdaptationSet and to 110 in Representation
4552 * We expect duration to be 110
4554 expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 110, 0);
4555 expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 0, 0);
4557 /* the representation contains 1 segment (the one from Representation) */
4559 /* check first segment */
4560 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
4561 assert_equals_int (ret, TRUE);
4562 assert_equals_string (fragment.uri, "/TestMediaRep");
4563 assert_equals_int64 (fragment.range_start, 100);
4564 assert_equals_int64 (fragment.range_end, 200);
4565 assert_equals_string (fragment.index_uri, "/TestIndexRep");
4566 assert_equals_int64 (fragment.index_range_start, 300);
4567 assert_equals_int64 (fragment.index_range_end, 400);
4568 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4569 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4570 gst_media_fragment_info_clear (&fragment);
4572 /* try to advance to next segment. Should fail */
4573 flow = gst_mpd_client_advance_segment (mpdclient, activeStream, TRUE);
4574 assert_equals_int (flow, GST_FLOW_EOS);
4576 gst_mpd_client_free (mpdclient);
4585 GST_START_TEST (dash_mpdparser_segment_list)
4587 GList *adaptationSets;
4588 GstAdaptationSetNode *adapt_set;
4589 GstActiveStream *activeStream;
4590 GstMediaFragmentInfo fragment;
4591 GstClockTime expectedDuration;
4592 GstClockTime expectedTimestamp;
4594 "<?xml version=\"1.0\"?>"
4595 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4596 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4597 " availabilityStartTime=\"2015-03-24T0:0:0\""
4598 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4599 " <Period start=\"P0Y0M0DT0H0M10S\">"
4600 " <AdaptationSet mimeType=\"video/mp4\">"
4601 " <Representation id=\"1\" bandwidth=\"250000\">"
4602 " <SegmentList duration=\"12000\">"
4603 " <SegmentURL media=\"TestMedia\""
4604 " mediaRange=\"100-200\""
4605 " index=\"TestIndex\""
4606 " indexRange=\"300-400\">"
4609 " </Representation></AdaptationSet></Period></MPD>";
4612 GstMpdClient *mpdclient = gst_mpd_client_new ();
4614 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4615 assert_equals_int (ret, TRUE);
4617 /* process the xml data */
4619 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4621 assert_equals_int (ret, TRUE);
4623 /* get the list of adaptation sets of the first period */
4624 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
4625 fail_if (adaptationSets == NULL);
4627 /* setup streaming from the first adaptation set */
4628 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4629 fail_if (adapt_set == NULL);
4630 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
4631 assert_equals_int (ret, TRUE);
4633 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
4634 fail_if (activeStream == NULL);
4636 /* expected duration of the next fragment
4637 * Segment duration was set larger than period duration (12000 vs 11000).
4638 * We expect it to be limited to period duration.
4640 expectedDuration = duration_to_ms (0, 0, 0, 3, 3, 20, 0);
4641 expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 10, 0);
4643 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
4644 assert_equals_int (ret, TRUE);
4645 assert_equals_string (fragment.uri, "/TestMedia");
4646 assert_equals_int64 (fragment.range_start, 100);
4647 assert_equals_int64 (fragment.range_end, 200);
4648 assert_equals_string (fragment.index_uri, "/TestIndex");
4649 assert_equals_int64 (fragment.index_range_start, 300);
4650 assert_equals_int64 (fragment.index_range_end, 400);
4651 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4652 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4654 gst_media_fragment_info_clear (&fragment);
4656 gst_mpd_client_free (mpdclient);
4662 * Test segment template
4665 GST_START_TEST (dash_mpdparser_segment_template)
4667 GList *adaptationSets;
4668 GstAdaptationSetNode *adapt_set;
4669 GstActiveStream *activeStream;
4670 GstMediaFragmentInfo fragment;
4671 GstClockTime expectedDuration;
4672 GstClockTime expectedTimestamp;
4673 GstClockTime periodStartTime;
4674 GstClockTime offset;
4675 GstClockTime lastFragmentTimestampEnd;
4677 "<?xml version=\"1.0\"?>"
4678 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4679 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4680 " availabilityStartTime=\"2015-03-24T0:0:0\""
4681 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4682 " <Period start=\"P0Y0M0DT0H0M10S\">"
4683 " <AdaptationSet mimeType=\"video/mp4\">"
4684 " <Representation id=\"repId\" bandwidth=\"250000\">"
4685 " <SegmentTemplate duration=\"12000\""
4686 " presentationTimeOffset=\"15\""
4687 " media=\"TestMedia_rep=$RepresentationID$number=$Number$bandwidth=$Bandwidth$time=$Time$\""
4688 " index=\"TestIndex\">"
4689 " </SegmentTemplate>"
4690 " </Representation></AdaptationSet></Period></MPD>";
4693 GstMpdClient *mpdclient = gst_mpd_client_new ();
4695 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4696 assert_equals_int (ret, TRUE);
4698 /* process the xml data */
4700 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4702 assert_equals_int (ret, TRUE);
4704 /* get the list of adaptation sets of the first period */
4705 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
4706 fail_if (adaptationSets == NULL);
4708 /* setup streaming from the first adaptation set */
4709 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4710 fail_if (adapt_set == NULL);
4711 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
4712 assert_equals_int (ret, TRUE);
4714 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
4715 fail_if (activeStream == NULL);
4717 /* expected duration of the next fragment
4718 * Segment duration was set larger than period duration (12000 vs 11000).
4719 * We expect it to not be limited to period duration.
4721 expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 12000, 0);
4723 /* while the period starts at 10ms, the fragment timestamp is supposed to be
4724 * 0ms. timestamps are starting from 0 at every period, and only the overall
4725 * composition of periods should consider the period start timestamp. In
4726 * dashdemux this is done by mapping the 0 fragment timestamp to a stream
4727 * time equal to the period start time.
4729 expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 0, 0);
4731 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
4732 assert_equals_int (ret, TRUE);
4733 assert_equals_string (fragment.uri,
4734 "/TestMedia_rep=repIdnumber=1bandwidth=250000time=0");
4735 assert_equals_int64 (fragment.range_start, 0);
4736 assert_equals_int64 (fragment.range_end, -1);
4737 assert_equals_string (fragment.index_uri, "/TestIndex");
4738 assert_equals_int64 (fragment.index_range_start, 0);
4739 assert_equals_int64 (fragment.index_range_end, -1);
4740 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4741 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4743 periodStartTime = gst_mpd_parser_get_period_start_time (mpdclient);
4744 assert_equals_uint64 (periodStartTime, 10 * GST_SECOND);
4746 offset = gst_mpd_parser_get_stream_presentation_offset (mpdclient, 0);
4747 assert_equals_uint64 (offset, 15 * GST_SECOND);
4749 gst_media_fragment_info_clear (&fragment);
4752 * Period starts at 10s.
4753 * MPD has a duration of 3h3m30s, so period duration is 3h3m20s.
4754 * We expect the last fragment to end at period start + period duration: 3h3m30s
4756 expectedTimestamp = duration_to_ms (0, 0, 0, 3, 3, 30, 0);
4757 gst_mpd_client_get_last_fragment_timestamp_end (mpdclient, 0,
4758 &lastFragmentTimestampEnd);
4759 assert_equals_uint64 (lastFragmentTimestampEnd,
4760 expectedTimestamp * GST_MSECOND);
4762 gst_mpd_client_free (mpdclient);
4768 * Test segment timeline
4771 GST_START_TEST (dash_mpdparser_segment_timeline)
4773 GList *adaptationSets;
4774 GstAdaptationSetNode *adapt_set;
4775 GstActiveStream *activeStream;
4776 GstMediaFragmentInfo fragment;
4777 GstClockTime expectedDuration;
4778 GstClockTime expectedTimestamp;
4780 GstDateTime *segmentAvailability;
4783 "<?xml version=\"1.0\"?>"
4784 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4785 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4786 " availabilityStartTime=\"2015-03-24T0:0:0\""
4787 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4788 " <Period start=\"P0Y0M0DT0H0M10S\">"
4789 " <AdaptationSet mimeType=\"video/mp4\">"
4791 " <SegmentTimeline>"
4792 " <S t=\"10\" d=\"20\" r=\"30\"></S>"
4793 " </SegmentTimeline>"
4795 " <Representation id=\"1\" bandwidth=\"250000\">"
4797 " <SegmentTimeline>"
4798 " <S t=\"3\" d=\"2\" r=\"1\"></S>"
4799 " <S t=\"10\" d=\"3\" r=\"0\"></S>"
4800 " </SegmentTimeline>"
4801 " <SegmentURL media=\"TestMedia0\""
4802 " index=\"TestIndex0\">"
4804 " <SegmentURL media=\"TestMedia1\""
4805 " index=\"TestIndex1\">"
4808 " </Representation></AdaptationSet></Period></MPD>";
4811 GstMpdClient *mpdclient = gst_mpd_client_new ();
4813 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4814 assert_equals_int (ret, TRUE);
4816 /* process the xml data */
4818 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4820 assert_equals_int (ret, TRUE);
4822 /* get the list of adaptation sets of the first period */
4823 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
4824 fail_if (adaptationSets == NULL);
4826 /* setup streaming from the first adaptation set */
4827 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4828 fail_if (adapt_set == NULL);
4829 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
4830 assert_equals_int (ret, TRUE);
4832 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
4833 fail_if (activeStream == NULL);
4835 /* expected duration of the next fragment */
4836 expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 2, 0);
4837 expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 13, 0);
4839 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
4840 assert_equals_int (ret, TRUE);
4841 assert_equals_string (fragment.uri, "/TestMedia0");
4842 assert_equals_string (fragment.index_uri, "/TestIndex0");
4843 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4844 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4845 gst_media_fragment_info_clear (&fragment);
4847 /* first segment starts at 3s and has a duration of 2s.
4848 * We also add period start time (10s) so we expect a segment availability
4851 segmentAvailability =
4852 gst_mpd_client_get_next_segment_availability_start_time (mpdclient,
4854 fail_unless (segmentAvailability != NULL);
4855 assert_equals_int (gst_date_time_get_year (segmentAvailability), 2015);
4856 assert_equals_int (gst_date_time_get_month (segmentAvailability), 3);
4857 assert_equals_int (gst_date_time_get_day (segmentAvailability), 24);
4858 assert_equals_int (gst_date_time_get_hour (segmentAvailability), 0);
4859 assert_equals_int (gst_date_time_get_minute (segmentAvailability), 0);
4860 assert_equals_int (gst_date_time_get_second (segmentAvailability), 15);
4861 gst_date_time_unref (segmentAvailability);
4863 /* advance to next segment */
4864 flow = gst_mpd_client_advance_segment (mpdclient, activeStream, TRUE);
4865 assert_equals_int (flow, GST_FLOW_OK);
4867 /* second segment starts after first ends */
4868 expectedTimestamp = expectedTimestamp + expectedDuration;
4870 /* check second segment.
4871 * It is a repeat of first segmentURL, because "r" in SegmentTimeline is 1
4873 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
4874 assert_equals_int (ret, TRUE);
4875 assert_equals_string (fragment.uri, "/TestMedia0");
4876 assert_equals_string (fragment.index_uri, "/TestIndex0");
4877 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4878 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4879 gst_media_fragment_info_clear (&fragment);
4881 /* first segment starts at 3s and has a duration of 2s.
4882 * Second segment starts when the first ends (5s) and has a duration of 2s,
4884 * We also add period start time (10s) so we expect a segment availability
4887 segmentAvailability =
4888 gst_mpd_client_get_next_segment_availability_start_time (mpdclient,
4890 fail_unless (segmentAvailability != NULL);
4891 assert_equals_int (gst_date_time_get_year (segmentAvailability), 2015);
4892 assert_equals_int (gst_date_time_get_month (segmentAvailability), 3);
4893 assert_equals_int (gst_date_time_get_day (segmentAvailability), 24);
4894 assert_equals_int (gst_date_time_get_hour (segmentAvailability), 0);
4895 assert_equals_int (gst_date_time_get_minute (segmentAvailability), 0);
4896 assert_equals_int (gst_date_time_get_second (segmentAvailability), 17);
4897 gst_date_time_unref (segmentAvailability);
4899 /* advance to next segment */
4900 flow = gst_mpd_client_advance_segment (mpdclient, activeStream, TRUE);
4901 assert_equals_int (flow, GST_FLOW_OK);
4903 /* third segment has a small gap after the second ends (t=10) */
4904 expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 3, 0);
4905 expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 20, 0);
4907 /* check third segment */
4908 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
4909 assert_equals_int (ret, TRUE);
4910 assert_equals_string (fragment.uri, "/TestMedia1");
4911 assert_equals_string (fragment.index_uri, "/TestIndex1");
4912 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4913 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4914 gst_media_fragment_info_clear (&fragment);
4916 /* Third segment starts at 10s and has a duration of 3s so it ends at 13s.
4917 * We also add period start time (10s) so we expect a segment availability
4920 segmentAvailability =
4921 gst_mpd_client_get_next_segment_availability_start_time (mpdclient,
4923 fail_unless (segmentAvailability != NULL);
4924 assert_equals_int (gst_date_time_get_year (segmentAvailability), 2015);
4925 assert_equals_int (gst_date_time_get_month (segmentAvailability), 3);
4926 assert_equals_int (gst_date_time_get_day (segmentAvailability), 24);
4927 assert_equals_int (gst_date_time_get_hour (segmentAvailability), 0);
4928 assert_equals_int (gst_date_time_get_minute (segmentAvailability), 0);
4929 assert_equals_int (gst_date_time_get_second (segmentAvailability), 23);
4930 gst_date_time_unref (segmentAvailability);
4932 gst_mpd_client_free (mpdclient);
4938 * Test SegmentList with multiple inherited segmentURLs
4941 GST_START_TEST (dash_mpdparser_multiple_inherited_segmentURL)
4943 GList *adaptationSets;
4944 GstAdaptationSetNode *adapt_set;
4945 GstActiveStream *activeStream;
4946 GstMediaFragmentInfo fragment;
4947 GstClockTime expectedDuration;
4948 GstClockTime expectedTimestamp;
4952 * Period duration is 30 seconds
4953 * Period start is 10 seconds. Thus, period duration is 20 seconds.
4955 * There are 2 segments in the AdaptationSet segment list and 2 in the
4956 * Representation's segment list.
4957 * Segment duration is 5s for the Adaptation segments and 8s for
4958 * Representation segments.
4959 * Separately, each segment list (duration 2*5=10 or 2*8=16) fits comfortably
4960 * in the Period's 20s duration.
4962 * We expect the Representation segments to overwrite the AdaptationSet segments.
4965 "<?xml version=\"1.0\"?>"
4966 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4967 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4968 " availabilityStartTime=\"2015-03-24T0:0:0\""
4969 " mediaPresentationDuration=\"P0Y0M0DT0H0M30S\">"
4971 " <AdaptationSet mimeType=\"video/mp4\">"
4972 " <SegmentList duration=\"5\">"
4974 " media=\"TestMedia0\" mediaRange=\"10-20\""
4975 " index=\"TestIndex0\" indexRange=\"100-200\""
4978 " media=\"TestMedia1\" mediaRange=\"20-30\""
4979 " index=\"TestIndex1\" indexRange=\"200-300\""
4982 " <Representation id=\"1\" bandwidth=\"250000\">"
4983 " <SegmentList duration=\"8\">"
4985 " media=\"TestMedia2\" mediaRange=\"30-40\""
4986 " index=\"TestIndex2\" indexRange=\"300-400\""
4989 " media=\"TestMedia3\" mediaRange=\"40-50\""
4990 " index=\"TestIndex3\" indexRange=\"400-500\""
4993 " </Representation></AdaptationSet></Period></MPD>";
4996 GstMpdClient *mpdclient = gst_mpd_client_new ();
4998 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
4999 assert_equals_int (ret, TRUE);
5001 /* process the xml data */
5002 ret = gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5004 assert_equals_int (ret, TRUE);
5006 /* get the list of adaptation sets of the first period */
5007 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
5008 fail_if (adaptationSets == NULL);
5010 /* setup streaming from the first adaptation set */
5011 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
5012 fail_if (adapt_set == NULL);
5013 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
5014 assert_equals_int (ret, TRUE);
5016 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
5017 fail_if (activeStream == NULL);
5019 expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 8, 0);
5020 expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 0, 0);
5022 /* the representation contains 2 segments defined in the Representation
5024 * Both will have the duration specified in the Representation (8)
5027 /* check first segment */
5028 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
5029 assert_equals_int (ret, TRUE);
5030 assert_equals_string (fragment.uri, "/TestMedia2");
5031 assert_equals_int64 (fragment.range_start, 30);
5032 assert_equals_int64 (fragment.range_end, 40);
5033 assert_equals_string (fragment.index_uri, "/TestIndex2");
5034 assert_equals_int64 (fragment.index_range_start, 300);
5035 assert_equals_int64 (fragment.index_range_end, 400);
5036 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
5037 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
5038 gst_media_fragment_info_clear (&fragment);
5040 /* advance to next segment */
5041 flow = gst_mpd_client_advance_segment (mpdclient, activeStream, TRUE);
5042 assert_equals_int (flow, GST_FLOW_OK);
5044 /* second segment starts after previous ends */
5045 expectedTimestamp = expectedTimestamp + expectedDuration;
5047 /* check second segment */
5048 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
5049 assert_equals_int (ret, TRUE);
5050 assert_equals_string (fragment.uri, "/TestMedia3");
5051 assert_equals_int64 (fragment.range_start, 40);
5052 assert_equals_int64 (fragment.range_end, 50);
5053 assert_equals_string (fragment.index_uri, "/TestIndex3");
5054 assert_equals_int64 (fragment.index_range_start, 400);
5055 assert_equals_int64 (fragment.index_range_end, 500);
5056 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
5057 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
5058 gst_media_fragment_info_clear (&fragment);
5060 /* try to advance to the next segment. There isn't any, so it should fail */
5061 flow = gst_mpd_client_advance_segment (mpdclient, activeStream, TRUE);
5062 assert_equals_int (flow, GST_FLOW_EOS);
5064 gst_mpd_client_free (mpdclient);
5070 * Test SegmentList with multiple segmentURL
5073 GST_START_TEST (dash_mpdparser_multipleSegmentURL)
5075 GList *adaptationSets;
5076 GstAdaptationSetNode *adapt_set;
5077 GstActiveStream *activeStream;
5078 GstMediaFragmentInfo fragment;
5079 GstClockTime expectedDuration;
5080 GstClockTime expectedTimestamp;
5084 * Period duration is 30 seconds
5085 * Period start is 10 seconds. Thus, period duration is 20 seconds.
5087 * Segment duration is 25 seconds. There are 2 segments in the list.
5088 * We expect first segment to have a duration of 20 seconds (limited by the period)
5089 * and the second segment to not exist.
5092 "<?xml version=\"1.0\"?>"
5093 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5094 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5095 " availabilityStartTime=\"2015-03-24T0:0:0\""
5096 " mediaPresentationDuration=\"P0Y0M0DT0H0M30S\">"
5097 "<Period start=\"P0Y0M0DT0H0M10S\">"
5098 " <AdaptationSet mimeType=\"video/mp4\">"
5099 " <Representation id=\"1\" bandwidth=\"250000\">"
5100 " <SegmentList duration=\"25\">"
5102 " media=\"TestMedia0\" mediaRange=\"10-20\""
5103 " index=\"TestIndex0\" indexRange=\"100-200\""
5106 " media=\"TestMedia1\" mediaRange=\"20-30\""
5107 " index=\"TestIndex1\" indexRange=\"200-300\""
5110 " </Representation></AdaptationSet></Period></MPD>";
5113 GstMpdClient *mpdclient = gst_mpd_client_new ();
5115 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5116 assert_equals_int (ret, TRUE);
5118 /* process the xml data */
5120 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5122 assert_equals_int (ret, TRUE);
5124 /* get the list of adaptation sets of the first period */
5125 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
5126 fail_if (adaptationSets == NULL);
5128 /* setup streaming from the first adaptation set */
5129 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
5130 fail_if (adapt_set == NULL);
5131 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
5132 assert_equals_int (ret, TRUE);
5134 activeStream = gst_mpdparser_get_active_stream_by_index (mpdclient, 0);
5135 fail_if (activeStream == NULL);
5137 expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 20, 0);
5138 expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 10, 0);
5140 /* the representation contains 2 segments. The first is partially
5141 * clipped, and the second entirely (and thus discarded).
5144 /* check first segment */
5145 ret = gst_mpd_client_get_next_fragment (mpdclient, 0, &fragment);
5146 assert_equals_int (ret, TRUE);
5147 assert_equals_string (fragment.uri, "/TestMedia0");
5148 assert_equals_int64 (fragment.range_start, 10);
5149 assert_equals_int64 (fragment.range_end, 20);
5150 assert_equals_string (fragment.index_uri, "/TestIndex0");
5151 assert_equals_int64 (fragment.index_range_start, 100);
5152 assert_equals_int64 (fragment.index_range_end, 200);
5153 assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
5154 assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
5155 gst_media_fragment_info_clear (&fragment);
5157 /* advance to next segment */
5158 flow = gst_mpd_client_advance_segment (mpdclient, activeStream, TRUE);
5159 assert_equals_int (flow, GST_FLOW_EOS);
5161 gst_mpd_client_free (mpdclient);
5167 * Test parsing empty xml string
5170 GST_START_TEST (dash_mpdparser_missing_xml)
5172 const gchar *xml = "";
5175 GstMpdClient *mpdclient = gst_mpd_client_new ();
5177 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5178 assert_equals_int (ret, FALSE);
5180 gst_mpd_client_free (mpdclient);
5186 * Test parsing an xml with no mpd tag
5189 GST_START_TEST (dash_mpdparser_missing_mpd)
5191 const gchar *xml = "<?xml version=\"1.0\"?>";
5194 GstMpdClient *mpdclient = gst_mpd_client_new ();
5196 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5197 assert_equals_int (ret, FALSE);
5199 gst_mpd_client_free (mpdclient);
5205 * Test parsing an MPD with a wrong end tag
5207 GST_START_TEST (dash_mpdparser_no_end_tag)
5210 "<?xml version=\"1.0\"?>"
5211 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5212 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"> </NPD>";
5215 GstMpdClient *mpdclient = gst_mpd_client_new ();
5217 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5218 assert_equals_int (ret, FALSE);
5220 gst_mpd_client_free (mpdclient);
5226 * Test parsing an MPD with no default namespace
5228 GST_START_TEST (dash_mpdparser_no_default_namespace)
5231 "<?xml version=\"1.0\"?>"
5232 "<MPD profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"></MPD>";
5235 GstMpdClient *mpdclient = gst_mpd_client_new ();
5237 ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
5238 assert_equals_int (ret, TRUE);
5240 gst_mpd_client_free (mpdclient);
5246 * Test handling wrong period duration during attempts to
5247 * infer a period duration from the start time of the next period
5249 GST_START_TEST (dash_mpdparser_wrong_period_duration_inferred_from_next_period)
5251 const gchar *periodName;
5254 "<?xml version=\"1.0\"?>"
5255 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5256 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5257 " availabilityStartTime=\"2015-03-24T0:0:0\""
5258 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
5259 " <Period id=\"Period0\" duration=\"P0Y0M0DT1H1M0S\"></Period>"
5260 " <Period id=\"Period1\"></Period>"
5261 " <Period id=\"Period2\" start=\"P0Y0M0DT0H0M10S\"></Period></MPD>";
5264 GstMpdClient *mpdclient = gst_mpd_client_new ();
5266 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5267 assert_equals_int (ret, TRUE);
5269 /* period_idx should be 0 and we should have no active periods */
5270 assert_equals_uint64 (mpdclient->period_idx, 0);
5271 fail_unless (mpdclient->periods == NULL);
5273 /* process the xml data */
5275 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5277 assert_equals_int (ret, TRUE);
5279 /* Period0 should be present */
5280 fail_unless (mpdclient->periods != NULL);
5281 periodName = gst_mpd_client_get_period_id (mpdclient);
5282 assert_equals_string (periodName, "Period0");
5284 /* Period1 should not be present due to wrong duration */
5285 ret = gst_mpd_client_set_period_index (mpdclient, 1);
5286 assert_equals_int (ret, FALSE);
5288 gst_mpd_client_free (mpdclient);
5294 * Test handling wrong period duration during attempts to
5295 * infer a period duration from the mediaPresentationDuration
5298 (dash_mpdparser_wrong_period_duration_inferred_from_next_mediaPresentationDuration)
5301 "<?xml version=\"1.0\"?>"
5302 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5303 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5304 " availabilityStartTime=\"2015-03-24T0:0:0\""
5305 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
5306 " <Period id=\"Period0\" start=\"P0Y0M0DT4H0M0S\"></Period></MPD>";
5309 GstMpdClient *mpdclient = gst_mpd_client_new ();
5311 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5312 assert_equals_int (ret, TRUE);
5314 /* period_idx should be 0 and we should have no active periods */
5315 assert_equals_uint64 (mpdclient->period_idx, 0);
5316 fail_unless (mpdclient->periods == NULL);
5318 /* process the xml data
5319 * should fail due to wrong duration in Period0 (start > mediaPresentationDuration)
5322 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5324 assert_equals_int (ret, FALSE);
5326 gst_mpd_client_free (mpdclient);
5331 GST_START_TEST (dash_mpdparser_whitespace_strings)
5333 fail_unless (gst_mpdparser_validate_no_whitespace ("") == TRUE);
5334 fail_unless (gst_mpdparser_validate_no_whitespace ("/") == TRUE);
5335 fail_unless (gst_mpdparser_validate_no_whitespace (" ") == FALSE);
5336 fail_unless (gst_mpdparser_validate_no_whitespace ("aaaaaaaa ") == FALSE);
5337 fail_unless (gst_mpdparser_validate_no_whitespace ("a\ta") == FALSE);
5338 fail_unless (gst_mpdparser_validate_no_whitespace ("a\ra") == FALSE);
5339 fail_unless (gst_mpdparser_validate_no_whitespace ("a\na") == FALSE);
5344 GST_START_TEST (dash_mpdparser_rfc1738_strings)
5346 fail_unless (gst_mpdparser_validate_rfc1738_url ("/") == TRUE);
5347 fail_unless (gst_mpdparser_validate_rfc1738_url (" ") == FALSE);
5348 fail_unless (gst_mpdparser_validate_rfc1738_url ("aaaaaaaa ") == FALSE);
5350 fail_unless (gst_mpdparser_validate_rfc1738_url ("") == TRUE);
5351 fail_unless (gst_mpdparser_validate_rfc1738_url ("a") == TRUE);
5352 fail_unless (gst_mpdparser_validate_rfc1738_url
5353 (";:@&=aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789$-_.+!*'(),%AA")
5355 fail_unless (gst_mpdparser_validate_rfc1738_url
5356 (";:@&=aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789$-_.+!*'(),/%AA")
5358 fail_unless (gst_mpdparser_validate_rfc1738_url
5359 (";:@&=aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789$-_.+!*'(),% ")
5361 fail_unless (gst_mpdparser_validate_rfc1738_url ("%AA") == TRUE);
5362 fail_unless (gst_mpdparser_validate_rfc1738_url ("%A") == FALSE);
5363 fail_unless (gst_mpdparser_validate_rfc1738_url ("%") == FALSE);
5364 fail_unless (gst_mpdparser_validate_rfc1738_url ("%XA") == FALSE);
5365 fail_unless (gst_mpdparser_validate_rfc1738_url ("%AX") == FALSE);
5366 fail_unless (gst_mpdparser_validate_rfc1738_url ("%XX") == FALSE);
5367 fail_unless (gst_mpdparser_validate_rfc1738_url ("\001") == FALSE);
5373 * Test negative period duration
5375 GST_START_TEST (dash_mpdparser_negative_period_duration)
5378 "<?xml version=\"1.0\"?>"
5379 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5380 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5381 " availabilityStartTime=\"2015-03-24T0:0:0\""
5382 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
5383 " <Period id=\"Period0\""
5384 " start=\"P0Y0M0DT1H0M0S\""
5385 " duration=\"-PT10S\">"
5386 " </Period><Period id=\"Period1\"></Period></MPD>";
5389 GstMpdClient *mpdclient = gst_mpd_client_new ();
5391 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5392 assert_equals_int (ret, TRUE);
5394 /* process the xml data
5395 * should fail due to negative duration of Period0
5397 ret = gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5399 assert_equals_int (ret, FALSE);
5401 gst_mpd_client_free (mpdclient);
5407 * Test parsing negative values from attributes that should be unsigned
5410 GST_START_TEST (dash_mpdparser_read_unsigned_from_negative_values)
5412 GstPeriodNode *periodNode;
5413 GstSegmentBaseType *segmentBase;
5414 GstAdaptationSetNode *adaptationSet;
5415 GstRepresentationNode *representation;
5416 GstSubRepresentationNode *subRepresentation;
5419 "<?xml version=\"1.0\"?>"
5420 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5421 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5422 " availabilityStartTime=\"2015--1-13T12:25:37\">"
5423 " <Period start=\"-P-2015Y\" duration=\"-P-5M\">"
5424 " <SegmentBase presentationTimeOffset=\"-10\""
5426 " indexRange=\"1--10\">"
5428 " <AdaptationSet par=\"-1:7\""
5429 " minFrameRate=\" -1\""
5430 " segmentAlignment=\"-4\">"
5431 " <Representation id=\"1\" bandwidth=\"250000\">"
5432 " <SubRepresentation dependencyLevel=\"1 -2 3\">"
5433 " </SubRepresentation>"
5434 " </Representation></AdaptationSet></Period></MPD>";
5437 GstMpdClient *mpdclient = gst_mpd_client_new ();
5439 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5440 assert_equals_int (ret, TRUE);
5442 periodNode = (GstPeriodNode *) mpdclient->mpd_node->Periods->data;
5443 segmentBase = periodNode->SegmentBase;
5444 adaptationSet = (GstAdaptationSetNode *) periodNode->AdaptationSets->data;
5445 representation = (GstRepresentationNode *)
5446 adaptationSet->Representations->data;
5447 subRepresentation = (GstSubRepresentationNode *)
5448 representation->SubRepresentations->data;
5450 /* availabilityStartTime parsing should fail */
5451 fail_if (mpdclient->mpd_node->availabilityStartTime != NULL);
5453 /* Period start parsing should fail */
5454 assert_equals_int64 (periodNode->start, -1);
5456 /* Period duration parsing should fail */
5457 assert_equals_int64 (periodNode->duration, -1);
5459 /* expect negative value to be rejected and presentationTimeOffset to be 0 */
5460 assert_equals_uint64 (segmentBase->presentationTimeOffset, 0);
5461 assert_equals_uint64 (segmentBase->timescale, 1);
5462 fail_if (segmentBase->indexRange != NULL);
5464 /* par ratio parsing should fail */
5465 fail_if (adaptationSet->par != NULL);
5467 /* minFrameRate parsing should fail */
5468 fail_if (adaptationSet->RepresentationBase->minFrameRate != NULL);
5470 /* segmentAlignment parsing should fail */
5471 fail_if (adaptationSet->segmentAlignment != NULL);
5473 /* dependency level parsing should fail */
5474 fail_if (subRepresentation->dependencyLevel != NULL);
5476 gst_mpd_client_free (mpdclient);
5482 * Test negative mediaPresentationDuration duration
5484 GST_START_TEST (dash_mpdparser_negative_mediaPresentationDuration)
5487 "<?xml version=\"1.0\"?>"
5488 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5489 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5490 " availabilityStartTime=\"2015-03-24T0:0:0\""
5491 " mediaPresentationDuration=\"-P0Y0M0DT3H3M30S\">"
5492 " <Period id=\"Period0\" start=\"P0Y0M0DT1H0M0S\"></Period></MPD>";
5495 GstMpdClient *mpdclient = gst_mpd_client_new ();
5497 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5498 assert_equals_int (ret, TRUE);
5500 /* process the xml data
5501 * should fail due to negative duration of mediaPresentationDuration
5503 ret = gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5505 assert_equals_int (ret, FALSE);
5507 gst_mpd_client_free (mpdclient);
5513 * Test parsing an MPD with no profiles
5515 GST_START_TEST (dash_mpdparser_no_profiles)
5518 "<?xml version=\"1.0\"?>"
5519 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"></MPD>";
5522 GstMpdClient *mpdclient = gst_mpd_client_new ();
5524 ret = gst_mpd_parse (mpdclient, xml, strlen (xml));
5526 assert_equals_int (ret, TRUE);
5528 gst_mpd_client_free (mpdclient);
5534 * Test S node list greater than SegmentURL list
5537 GST_START_TEST (dash_mpdparser_unmatched_segmentTimeline_segmentURL)
5539 GList *adaptationSets;
5540 GstAdaptationSetNode *adapt_set;
5543 "<?xml version=\"1.0\"?>"
5544 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5545 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5546 " availabilityStartTime=\"2015-03-24T0:0:0\""
5547 " mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
5548 " <Period start=\"P0Y0M0DT0H0M10S\">"
5549 " <AdaptationSet mimeType=\"video/mp4\">"
5550 " <Representation id=\"1\" bandwidth=\"250000\">"
5552 " <SegmentTimeline>"
5553 " <S t=\"3\" d=\"2\" r=\"1\"></S>"
5554 " <S t=\"10\" d=\"3\" r=\"0\"></S>"
5555 " </SegmentTimeline>"
5556 " <SegmentURL media=\"TestMedia0\""
5557 " index=\"TestIndex0\">"
5560 " </Representation></AdaptationSet></Period></MPD>";
5563 GstMpdClient *mpdclient = gst_mpd_client_new ();
5565 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5566 assert_equals_int (ret, TRUE);
5568 /* process the xml data */
5569 ret = gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5571 assert_equals_int (ret, TRUE);
5573 /* get the list of adaptation sets of the first period */
5574 adaptationSets = gst_mpd_client_get_adaptation_sets (mpdclient);
5575 fail_if (adaptationSets == NULL);
5577 adapt_set = (GstAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
5578 fail_if (adapt_set == NULL);
5580 /* setup streaming from the first adaptation set.
5581 * Should fail because the second S node does not have a matching
5584 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set);
5585 assert_equals_int (ret, FALSE);
5587 gst_mpd_client_free (mpdclient);
5593 * Test parsing of the default presentation delay property
5595 GST_START_TEST (dash_mpdparser_default_presentation_delay)
5598 "<?xml version=\"1.0\"?>"
5599 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5600 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5601 " maxSegmentDuration=\"PT2S\">"
5602 " <Period id=\"Period0\" start=\"P0S\"></Period></MPD>";
5605 GstMpdClient *mpdclient = gst_mpd_client_new ();
5608 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5609 assert_equals_int (ret, TRUE);
5610 value = gst_mpd_client_parse_default_presentation_delay (mpdclient, "5s");
5611 assert_equals_int64 (value, 5000);
5612 value = gst_mpd_client_parse_default_presentation_delay (mpdclient, "5S");
5613 assert_equals_int64 (value, 5000);
5615 gst_mpd_client_parse_default_presentation_delay (mpdclient, "5 seconds");
5616 assert_equals_int64 (value, 5000);
5617 value = gst_mpd_client_parse_default_presentation_delay (mpdclient, "2500ms");
5618 assert_equals_int64 (value, 2500);
5619 value = gst_mpd_client_parse_default_presentation_delay (mpdclient, "3f");
5620 assert_equals_int64 (value, 6000);
5621 value = gst_mpd_client_parse_default_presentation_delay (mpdclient, "3F");
5622 assert_equals_int64 (value, 6000);
5623 value = gst_mpd_client_parse_default_presentation_delay (mpdclient, "");
5624 assert_equals_int64 (value, 0);
5625 value = gst_mpd_client_parse_default_presentation_delay (mpdclient, "10");
5626 assert_equals_int64 (value, 0);
5628 gst_mpd_client_parse_default_presentation_delay (mpdclient,
5630 assert_equals_int64 (value, 0);
5632 gst_mpd_client_free (mpdclient);
5637 GST_START_TEST (dash_mpdparser_duration)
5641 fail_unless (gst_mpdparser_parse_duration ("", &v) == FALSE);
5642 fail_unless (gst_mpdparser_parse_duration (" ", &v) == FALSE);
5643 fail_unless (gst_mpdparser_parse_duration ("0", &v) == FALSE);
5644 fail_unless (gst_mpdparser_parse_duration ("D-1", &v) == FALSE);
5645 fail_unless (gst_mpdparser_parse_duration ("T", &v) == FALSE);
5647 fail_unless (gst_mpdparser_parse_duration ("P", &v) == TRUE);
5648 fail_unless (gst_mpdparser_parse_duration ("PT", &v) == TRUE);
5649 fail_unless (gst_mpdparser_parse_duration ("PX", &v) == FALSE);
5650 fail_unless (gst_mpdparser_parse_duration ("PPT", &v) == FALSE);
5651 fail_unless (gst_mpdparser_parse_duration ("PTT", &v) == FALSE);
5653 fail_unless (gst_mpdparser_parse_duration ("P1D", &v) == TRUE);
5654 fail_unless (gst_mpdparser_parse_duration ("P1D1D", &v) == FALSE);
5655 fail_unless (gst_mpdparser_parse_duration ("P1D1M", &v) == FALSE);
5656 fail_unless (gst_mpdparser_parse_duration ("P1M1D", &v) == TRUE);
5657 fail_unless (gst_mpdparser_parse_duration ("P1M1D1M", &v) == FALSE);
5658 fail_unless (gst_mpdparser_parse_duration ("P1M1D1D", &v) == FALSE);
5660 fail_unless (gst_mpdparser_parse_duration ("P0M0D", &v) == TRUE);
5661 fail_unless (gst_mpdparser_parse_duration ("P-1M", &v) == FALSE);
5662 fail_unless (gst_mpdparser_parse_duration ("P15M", &v) == FALSE);
5663 fail_unless (gst_mpdparser_parse_duration ("P-1D", &v) == FALSE);
5664 fail_unless (gst_mpdparser_parse_duration ("P35D", &v) == FALSE);
5665 fail_unless (gst_mpdparser_parse_duration ("P-1Y", &v) == FALSE);
5666 fail_unless (gst_mpdparser_parse_duration ("PT-1H", &v) == FALSE);
5667 fail_unless (gst_mpdparser_parse_duration ("PT25H", &v) == FALSE);
5668 fail_unless (gst_mpdparser_parse_duration ("PT-1M", &v) == FALSE);
5669 fail_unless (gst_mpdparser_parse_duration ("PT65M", &v) == FALSE);
5670 fail_unless (gst_mpdparser_parse_duration ("PT-1S", &v) == FALSE);
5671 /* seconds are allowed to be larger than 60 */
5672 fail_unless (gst_mpdparser_parse_duration ("PT65S", &v) == TRUE);
5674 fail_unless (gst_mpdparser_parse_duration ("PT1.1H", &v) == FALSE);
5675 fail_unless (gst_mpdparser_parse_duration ("PT1-1H", &v) == FALSE);
5676 fail_unless (gst_mpdparser_parse_duration ("PT1-H", &v) == FALSE);
5677 fail_unless (gst_mpdparser_parse_duration ("PT-H", &v) == FALSE);
5678 fail_unless (gst_mpdparser_parse_duration ("PTH", &v) == FALSE);
5679 fail_unless (gst_mpdparser_parse_duration ("PT0", &v) == FALSE);
5680 fail_unless (gst_mpdparser_parse_duration ("PT1.1S", &v) == TRUE);
5681 fail_unless (gst_mpdparser_parse_duration ("PT1.1.1S", &v) == FALSE);
5683 fail_unless (gst_mpdparser_parse_duration ("P585Y", &v) == FALSE);
5684 fail_unless (gst_mpdparser_parse_duration ("P584Y", &v) == TRUE);
5686 fail_unless (gst_mpdparser_parse_duration (" P10DT8H", &v) == TRUE);
5687 fail_unless (gst_mpdparser_parse_duration ("P10D T8H", &v) == FALSE);
5688 fail_unless (gst_mpdparser_parse_duration ("P10DT8H ", &v) == TRUE);
5694 * Test that the maximum_segment_duration correctly implements the
5695 * rules in the DASH specification
5697 GST_START_TEST (dash_mpdparser_maximum_segment_duration)
5699 const gchar *xml_template =
5700 "<?xml version=\"1.0\"?>"
5701 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5702 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5703 " availabilityStartTime=\"2015-03-24T0:0:0\""
5705 " mediaPresentationDuration=\"P100Y\">"
5706 " <Period id=\"Period0\" start=\"PT0S\">"
5707 " <AdaptationSet mimeType=\"video/mp4\" >"
5708 " <SegmentTemplate timescale=\"90000\" initialization=\"$RepresentationID$/Header.m4s\" media=\"$RepresentationID$/$Number$.m4s\" duration=\"360000\" />"
5709 " <Representation id=\"video1\" width=\"576\" height=\"324\" frameRate=\"25\" sar=\"1:1\" bandwidth=\"900000\" codecs=\"avc1.4D401E\"/>"
5711 " <AdaptationSet mimeType=\"audio/mp4\" >"
5712 " <SegmentTemplate timescale=\"90000\" initialization=\"$RepresentationID$/Header.m4s\" media=\"$RepresentationID$/$Number$.m4s\" duration=\"340000\" />"
5713 " <Representation id=\"audio1\" audioSamplingRate=\"22050\" bandwidth=\"29600\" codecs=\"mp4a.40.2\">"
5714 " <AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"2\"/>"
5715 " </Representation>" " </AdaptationSet>" " </Period></MPD>";
5717 GstMpdClient *mpdclient;
5720 GList *adapt_sets, *iter;
5722 xml = g_strdup_printf (xml_template, "maxSegmentDuration=\"PT4.5S\"");
5723 mpdclient = gst_mpd_client_new ();
5724 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5726 assert_equals_int (ret, TRUE);
5728 assert_equals_uint64 (mpdclient->mpd_node->maxSegmentDuration,
5729 duration_to_ms (0, 0, 0, 0, 0, 4, 500));
5730 dur = gst_mpd_client_get_maximum_segment_duration (mpdclient);
5731 assert_equals_uint64 (dur, duration_to_clocktime (0, 0, 0, 0, 0, 4, 500));
5732 gst_mpd_client_free (mpdclient);
5734 /* now parse without the maxSegmentDuration attribute, to check that
5735 gst_mpd_client_get_maximum_segment_duration uses the maximum
5736 duration of any segment
5738 xml = g_strdup_printf (xml_template, "");
5739 mpdclient = gst_mpd_client_new ();
5740 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5742 assert_equals_int (ret, TRUE);
5744 gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5746 assert_equals_int (ret, TRUE);
5747 adapt_sets = gst_mpd_client_get_adaptation_sets (mpdclient);
5748 for (iter = adapt_sets; iter; iter = g_list_next (iter)) {
5749 GstAdaptationSetNode *adapt_set_node = iter->data;
5751 ret = gst_mpd_client_setup_streaming (mpdclient, adapt_set_node);
5752 assert_equals_int (ret, TRUE);
5754 dur = gst_mpd_client_get_maximum_segment_duration (mpdclient);
5755 assert_equals_uint64 (dur, duration_to_clocktime (0, 0, 0, 0, 0, 4, 0));
5756 gst_mpd_client_free (mpdclient);
5762 * Test parsing of Perioud using @xlink:href attribute
5765 #define STRINGIFY_(x) #x
5766 #define STRINGIFY(x) STRINGIFY_ (x)
5767 #define REMOTEDIR STRINGIFY (DASH_MPD_DATADIR)
5768 #define XLINK_SINGLE_PERIOD_FILENAME REMOTEDIR "/xlink_single_period.period"
5769 #define XLINK_DOUBLE_PERIOD_FILENAME REMOTEDIR "/xlink_double_period.period"
5771 GST_START_TEST (dash_mpdparser_xlink_period)
5773 GstPeriodNode *periodNode;
5774 GstUriDownloader *downloader;
5775 GstMpdClient *mpdclient;
5776 GList *period_list, *iter;
5778 gchar *xml_joined, *file_uri_single_period, *file_uri_double_period;
5779 const gchar *xml_frag_start =
5780 "<?xml version=\"1.0\"?>"
5781 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5782 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
5783 " <Period id=\"Period0\" duration=\"PT5S\"></Period>";
5785 const gchar *xml_uri_front = " <Period xlink:href=\"";
5787 const gchar *xml_uri_rear =
5789 " xlink:actuate=\"onRequest\""
5790 " xmlns:xlink=\"http://www.w3.org/1999/xlink\"></Period>";
5792 const gchar *xml_frag_end = "</MPD>";
5794 /* XLINK_ONE_PERIOD_FILENAME
5796 * <Period id="xlink-single-period-Period1" duration="PT10S" xmlns="urn:mpeg:dash:schema:mpd:2011"></Period>
5799 /* XLINK_TWO_PERIODS_FILENAME
5801 * <Period id="xlink-double-period-Period1" duration="PT10S" xmlns="urn:mpeg:dash:schema:mpd:2011"></Period>
5802 * <Period id="xlink-double-period-Period2" duration="PT20S" xmlns="urn:mpeg:dash:schema:mpd:2011"></Period>
5806 mpdclient = gst_mpd_client_new ();
5807 downloader = gst_uri_downloader_new ();
5809 gst_mpd_client_set_uri_downloader (mpdclient, downloader);
5811 file_uri_single_period =
5812 gst_filename_to_uri (XLINK_SINGLE_PERIOD_FILENAME, NULL);
5813 file_uri_double_period =
5814 gst_filename_to_uri (XLINK_DOUBLE_PERIOD_FILENAME, NULL);
5816 /* constructs inital mpd using external xml uri */
5817 /* For invalid URI, mpdparser should be ignore it */
5818 xml_joined = g_strjoin ("", xml_frag_start,
5819 xml_uri_front, "http://404/ERROR/XML.period", xml_uri_rear,
5820 xml_uri_front, (const char *) file_uri_single_period, xml_uri_rear,
5821 xml_uri_front, (const char *) file_uri_double_period, xml_uri_rear,
5822 xml_frag_end, NULL);
5824 ret = gst_mpd_parse (mpdclient, xml_joined, (gint) strlen (xml_joined));
5825 assert_equals_int (ret, TRUE);
5827 period_list = mpdclient->mpd_node->Periods;
5828 /* only count periods on initial mpd (external xml does not parsed yet) */
5829 assert_equals_int (g_list_length (period_list), 4);
5831 /* process the xml data */
5832 ret = gst_mpd_client_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5834 assert_equals_int (ret, TRUE);
5836 period_list = mpdclient->mpd_node->Periods;
5837 assert_equals_int (g_list_length (period_list), 4);
5840 periodNode = (GstPeriodNode *) iter->data;
5841 assert_equals_string (periodNode->id, "Period0");
5844 periodNode = (GstPeriodNode *) iter->data;
5845 assert_equals_string (periodNode->id, "xlink-single-period-Period1");
5848 periodNode = (GstPeriodNode *) iter->data;
5849 assert_equals_string (periodNode->id, "xlink-double-period-Period1");
5852 periodNode = (GstPeriodNode *) iter->data;
5853 assert_equals_string (periodNode->id, "xlink-double-period-Period2");
5855 gst_mpd_client_free (mpdclient);
5856 g_object_unref (downloader);
5857 g_free (file_uri_single_period);
5858 g_free (file_uri_double_period);
5859 g_free (xml_joined);
5866 * Test parsing xsd:datetime with timezoneoffset.
5869 GST_START_TEST (dash_mpdparser_datetime_with_tz_offset)
5871 GstDateTime *availabilityStartTime;
5872 GstDateTime *availabilityEndTime;
5874 "<?xml version=\"1.0\"?>"
5875 "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5876 " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5877 " schemaLocation=\"TestSchemaLocation\""
5878 " xmlns:xsi=\"TestNamespaceXSI\""
5879 " xmlns:ext=\"TestNamespaceEXT\""
5882 " availabilityStartTime=\"2015-03-24T1:10:50+08:00\""
5883 " availabilityEndTime=\"2015-03-24T1:10:50.123456-04:30\""
5884 " mediaPresentationDuration=\"P0Y1M2DT12H10M20.5S\""
5885 " minimumUpdatePeriod=\"P0Y1M2DT12H10M20.5S\""
5886 " minBufferTime=\"P0Y1M2DT12H10M20.5S\""
5887 " timeShiftBufferDepth=\"P0Y1M2DT12H10M20.5S\""
5888 " suggestedPresentationDelay=\"P0Y1M2DT12H10M20.5S\""
5889 " maxSegmentDuration=\"P0Y1M2DT12H10M20.5S\""
5890 " maxSubsegmentDuration=\"P0Y1M2DT12H10M20.5S\"></MPD>";
5893 GstMpdClient *mpdclient = gst_mpd_client_new ();
5895 ret = gst_mpd_parse (mpdclient, xml, (gint) strlen (xml));
5896 assert_equals_int (ret, TRUE);
5898 availabilityStartTime = mpdclient->mpd_node->availabilityStartTime;
5899 assert_equals_int (gst_date_time_get_year (availabilityStartTime), 2015);
5900 assert_equals_int (gst_date_time_get_month (availabilityStartTime), 3);
5901 assert_equals_int (gst_date_time_get_day (availabilityStartTime), 24);
5902 assert_equals_int (gst_date_time_get_hour (availabilityStartTime), 1);
5903 assert_equals_int (gst_date_time_get_minute (availabilityStartTime), 10);
5904 assert_equals_int (gst_date_time_get_second (availabilityStartTime), 50);
5905 assert_equals_int (gst_date_time_get_microsecond (availabilityStartTime), 0);
5906 assert_equals_float (gst_date_time_get_time_zone_offset
5907 (availabilityStartTime), 8.0);
5909 availabilityEndTime = mpdclient->mpd_node->availabilityEndTime;
5910 assert_equals_int (gst_date_time_get_year (availabilityEndTime), 2015);
5911 assert_equals_int (gst_date_time_get_month (availabilityEndTime), 3);
5912 assert_equals_int (gst_date_time_get_day (availabilityEndTime), 24);
5913 assert_equals_int (gst_date_time_get_hour (availabilityEndTime), 1);
5914 assert_equals_int (gst_date_time_get_minute (availabilityEndTime), 10);
5915 assert_equals_int (gst_date_time_get_second (availabilityEndTime), 50);
5916 assert_equals_int (gst_date_time_get_microsecond (availabilityEndTime),
5918 assert_equals_float (gst_date_time_get_time_zone_offset (availabilityEndTime),
5921 gst_mpd_client_free (mpdclient);
5929 * create a test suite containing all dash testcases
5934 Suite *s = suite_create ("dash");
5935 TCase *tc_simpleMPD = tcase_create ("simpleMPD");
5936 TCase *tc_complexMPD = tcase_create ("complexMPD");
5937 TCase *tc_negativeTests = tcase_create ("negativeTests");
5938 TCase *tc_stringTests = tcase_create ("stringTests");
5939 TCase *tc_duration = tcase_create ("duration");
5941 GST_DEBUG_CATEGORY_INIT (gst_dash_demux_debug, "gst_dash_demux_debug", 0,
5944 /* test parsing the simplest possible mpd */
5945 tcase_add_test (tc_simpleMPD, dash_mpdparser_validsimplempd);
5947 /* tests parsing attributes from each element type */
5948 tcase_add_test (tc_simpleMPD, dash_mpdparser_mpd);
5949 tcase_add_test (tc_simpleMPD, dash_mpdparser_datetime_with_tz_offset);
5950 tcase_add_test (tc_simpleMPD, dash_mpdparser_programInformation);
5951 tcase_add_test (tc_simpleMPD, dash_mpdparser_baseURL);
5952 tcase_add_test (tc_simpleMPD, dash_mpdparser_location);
5953 tcase_add_test (tc_simpleMPD, dash_mpdparser_metrics);
5954 tcase_add_test (tc_simpleMPD, dash_mpdparser_metrics_range);
5955 tcase_add_test (tc_simpleMPD, dash_mpdparser_metrics_reporting);
5956 tcase_add_test (tc_simpleMPD, dash_mpdparser_period);
5957 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_baseURL);
5958 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_segmentBase);
5959 tcase_add_test (tc_simpleMPD,
5960 dash_mpdparser_period_segmentBase_initialization);
5961 tcase_add_test (tc_simpleMPD,
5962 dash_mpdparser_period_segmentBase_representationIndex);
5963 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_segmentList);
5964 tcase_add_test (tc_simpleMPD,
5965 dash_mpdparser_period_segmentList_multipleSegmentBaseType);
5966 tcase_add_test (tc_simpleMPD,
5967 dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentBaseType);
5968 tcase_add_test (tc_simpleMPD,
5969 dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline);
5970 tcase_add_test (tc_simpleMPD,
5971 dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline_s);
5972 tcase_add_test (tc_simpleMPD,
5973 dash_mpdparser_period_segmentList_multipleSegmentBaseType_bitstreamSwitching);
5974 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_segmentList_segmentURL);
5975 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_segmentTemplate);
5976 tcase_add_test (tc_simpleMPD,
5977 dash_mpdparser_period_segmentTemplateWithPresentationTimeOffset);
5978 tcase_add_test (tc_simpleMPD,
5979 dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType);
5980 tcase_add_test (tc_simpleMPD,
5981 dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentBaseType);
5982 tcase_add_test (tc_simpleMPD,
5983 dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline);
5984 tcase_add_test (tc_simpleMPD,
5985 dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline_s);
5986 tcase_add_test (tc_simpleMPD,
5987 dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_bitstreamSwitching);
5988 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet);
5989 tcase_add_test (tc_simpleMPD,
5990 dash_mpdparser_period_adaptationSet_representationBase);
5991 tcase_add_test (tc_simpleMPD,
5992 dash_mpdparser_period_adaptationSet_representationBase_framePacking);
5993 tcase_add_test (tc_simpleMPD,
5994 dash_mpdparser_adapt_repr_segmentTemplate_inherit);
5995 tcase_add_test (tc_simpleMPD,
5996 dash_mpdparser_period_adaptationSet_representationBase_audioChannelConfiguration);
5997 tcase_add_test (tc_simpleMPD,
5998 dash_mpdparser_period_adaptationSet_representationBase_contentProtection);
5999 tcase_add_test (tc_simpleMPD, dash_mpdparser_contentProtection_no_value);
6000 tcase_add_test (tc_simpleMPD,
6001 dash_mpdparser_contentProtection_no_value_no_encoding);
6002 tcase_add_test (tc_simpleMPD,
6003 dash_mpdparser_period_adaptationSet_accessibility);
6004 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_role);
6005 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_rating);
6006 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_viewpoint);
6007 tcase_add_test (tc_simpleMPD,
6008 dash_mpdparser_period_adaptationSet_contentComponent);
6009 tcase_add_test (tc_simpleMPD,
6010 dash_mpdparser_period_adaptationSet_contentComponent_accessibility);
6011 tcase_add_test (tc_simpleMPD,
6012 dash_mpdparser_period_adaptationSet_contentComponent_role);
6013 tcase_add_test (tc_simpleMPD,
6014 dash_mpdparser_period_adaptationSet_contentComponent_rating);
6015 tcase_add_test (tc_simpleMPD,
6016 dash_mpdparser_period_adaptationSet_contentComponent_viewpoint);
6017 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_baseURL);
6018 tcase_add_test (tc_simpleMPD,
6019 dash_mpdparser_period_adaptationSet_segmentBase);
6020 tcase_add_test (tc_simpleMPD,
6021 dash_mpdparser_period_adaptationSet_segmentBase_initialization);
6022 tcase_add_test (tc_simpleMPD,
6023 dash_mpdparser_period_adaptationSet_segmentBase_representationIndex);
6024 tcase_add_test (tc_simpleMPD,
6025 dash_mpdparser_period_adaptationSet_segmentList);
6026 tcase_add_test (tc_simpleMPD,
6027 dash_mpdparser_period_adaptationSet_segmentTemplate);
6028 tcase_add_test (tc_simpleMPD,
6029 dash_mpdparser_period_adaptationSet_segmentTemplate_inherit);
6030 tcase_add_test (tc_simpleMPD,
6031 dash_mpdparser_period_adaptationSet_representation);
6032 tcase_add_test (tc_simpleMPD,
6033 dash_mpdparser_period_adaptationSet_representation_representationBase);
6034 tcase_add_test (tc_simpleMPD,
6035 dash_mpdparser_period_adaptationSet_representation_baseURL);
6036 tcase_add_test (tc_simpleMPD,
6037 dash_mpdparser_period_adaptationSet_representation_subRepresentation);
6038 tcase_add_test (tc_simpleMPD,
6039 dash_mpdparser_period_adaptationSet_representation_subRepresentation_representationBase);
6040 tcase_add_test (tc_simpleMPD,
6041 dash_mpdparser_period_adaptationSet_representation_segmentBase);
6042 tcase_add_test (tc_simpleMPD,
6043 dash_mpdparser_period_adaptationSet_representation_segmentList);
6044 tcase_add_test (tc_simpleMPD,
6045 dash_mpdparser_period_adaptationSet_representation_segmentTemplate);
6046 tcase_add_test (tc_simpleMPD,
6047 dash_mpdparser_period_adaptationSet_representation_segmentTemplate_inherit);
6048 tcase_add_test (tc_simpleMPD,
6049 dash_mpdparser_period_adaptationSet_representation_segmentBase_inherit);
6050 tcase_add_test (tc_simpleMPD, dash_mpdparser_period_subset);
6051 tcase_add_test (tc_simpleMPD, dash_mpdparser_utctiming);
6052 tcase_add_test (tc_simpleMPD, dash_mpdparser_utctiming_invalid_value);
6054 /* tests checking other possible values for attributes */
6055 tcase_add_test (tc_simpleMPD, dash_mpdparser_type_dynamic);
6056 tcase_add_test (tc_simpleMPD, dash_mpdparser_template_parsing);
6057 tcase_add_test (tc_simpleMPD, dash_mpdparser_isoff_ondemand_profile);
6058 tcase_add_test (tc_simpleMPD, dash_mpdparser_GstDateTime);
6059 tcase_add_test (tc_simpleMPD, dash_mpdparser_bitstreamSwitching_inheritance);
6060 tcase_add_test (tc_simpleMPD, dash_mpdparser_various_duration_formats);
6061 tcase_add_test (tc_simpleMPD, dash_mpdparser_default_presentation_delay);
6063 /* tests checking xlink attributes */
6064 tcase_add_test (tc_simpleMPD, dash_mpdparser_xlink_period);
6066 /* tests checking the MPD management
6067 * (eg. setting active streams, obtaining attributes values)
6069 tcase_add_test (tc_complexMPD, dash_mpdparser_setup_media_presentation);
6070 tcase_add_test (tc_complexMPD, dash_mpdparser_setup_streaming);
6071 tcase_add_test (tc_complexMPD, dash_mpdparser_period_selection);
6072 tcase_add_test (tc_complexMPD, dash_mpdparser_get_period_at_time);
6073 tcase_add_test (tc_complexMPD, dash_mpdparser_adaptationSet_handling);
6074 tcase_add_test (tc_complexMPD, dash_mpdparser_representation_selection);
6075 tcase_add_test (tc_complexMPD, dash_mpdparser_multipleSegmentURL);
6076 tcase_add_test (tc_complexMPD, dash_mpdparser_activeStream_selection);
6077 tcase_add_test (tc_complexMPD, dash_mpdparser_activeStream_parameters);
6078 tcase_add_test (tc_complexMPD, dash_mpdparser_get_audio_languages);
6079 tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL1);
6080 tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL2);
6081 tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL3);
6082 tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL4);
6083 tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL5);
6084 tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL6);
6085 tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL7);
6086 tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL8);
6087 tcase_add_test (tc_complexMPD, dash_mpdparser_get_mediaPresentationDuration);
6088 tcase_add_test (tc_complexMPD, dash_mpdparser_get_streamPresentationOffset);
6089 tcase_add_test (tc_complexMPD, dash_mpdparser_segments);
6090 tcase_add_test (tc_complexMPD, dash_mpdparser_headers);
6091 tcase_add_test (tc_complexMPD, dash_mpdparser_fragments);
6092 tcase_add_test (tc_complexMPD, dash_mpdparser_inherited_segmentBase);
6093 tcase_add_test (tc_complexMPD, dash_mpdparser_inherited_segmentURL);
6094 tcase_add_test (tc_complexMPD, dash_mpdparser_segment_list);
6095 tcase_add_test (tc_complexMPD, dash_mpdparser_segment_template);
6096 tcase_add_test (tc_complexMPD, dash_mpdparser_segment_timeline);
6097 tcase_add_test (tc_complexMPD, dash_mpdparser_multiple_inherited_segmentURL);
6099 /* tests checking the parsing of missing/incomplete attributes of xml */
6100 tcase_add_test (tc_negativeTests, dash_mpdparser_missing_xml);
6101 tcase_add_test (tc_negativeTests, dash_mpdparser_missing_mpd);
6102 tcase_add_test (tc_negativeTests, dash_mpdparser_no_end_tag);
6103 tcase_add_test (tc_negativeTests, dash_mpdparser_no_profiles);
6104 tcase_add_test (tc_negativeTests, dash_mpdparser_no_default_namespace);
6105 tcase_add_test (tc_negativeTests,
6106 dash_mpdparser_wrong_period_duration_inferred_from_next_period);
6107 tcase_add_test (tc_negativeTests,
6108 dash_mpdparser_wrong_period_duration_inferred_from_next_mediaPresentationDuration);
6109 tcase_add_test (tc_negativeTests, dash_mpdparser_negative_period_duration);
6110 tcase_add_test (tc_negativeTests,
6111 dash_mpdparser_read_unsigned_from_negative_values);
6112 tcase_add_test (tc_negativeTests,
6113 dash_mpdparser_negative_mediaPresentationDuration);
6114 tcase_add_test (tc_negativeTests,
6115 dash_mpdparser_unmatched_segmentTimeline_segmentURL);
6117 tcase_add_test (tc_stringTests, dash_mpdparser_whitespace_strings);
6118 tcase_add_test (tc_stringTests, dash_mpdparser_rfc1738_strings);
6120 tcase_add_test (tc_duration, dash_mpdparser_duration);
6121 tcase_add_test (tc_duration, dash_mpdparser_maximum_segment_duration);
6123 suite_add_tcase (s, tc_simpleMPD);
6124 suite_add_tcase (s, tc_complexMPD);
6125 suite_add_tcase (s, tc_negativeTests);
6126 suite_add_tcase (s, tc_stringTests);
6127 suite_add_tcase (s, tc_duration);
6132 GST_CHECK_MAIN (dash);