5444f852ecf06cd5b727c508f897d6cb911d4454
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / tests / check / elements / dash_mpd.c
1 /* GStreamer unit test for MPEG-DASH
2  *
3  * Copyright (c) <2015> YouView TV Ltd
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 #include "../../ext/adaptivedemux2/dash/gstmpdparser.c"
22 #include "../../ext/adaptivedemux2/dash/gstxmlhelper.c"
23 #include "../../ext/adaptivedemux2/dash/gstmpdhelper.c"
24 #include "../../ext/adaptivedemux2/dash/gstmpdnode.c"
25 #include "../../ext/adaptivedemux2/dash/gstmpdrepresentationbasenode.c"
26 #include "../../ext/adaptivedemux2/dash/gstmpdmultsegmentbasenode.c"
27 #include "../../ext/adaptivedemux2/dash/gstmpdrootnode.c"
28 #include "../../ext/adaptivedemux2/dash/gstmpdbaseurlnode.c"
29 #include "../../ext/adaptivedemux2/dash/gstmpdutctimingnode.c"
30 #include "../../ext/adaptivedemux2/dash/gstmpdmetricsnode.c"
31 #include "../../ext/adaptivedemux2/dash/gstmpdmetricsrangenode.c"
32 #include "../../ext/adaptivedemux2/dash/gstmpdsnode.c"
33 #include "../../ext/adaptivedemux2/dash/gstmpdsegmenttimelinenode.c"
34 #include "../../ext/adaptivedemux2/dash/gstmpdsegmenttemplatenode.c"
35 #include "../../ext/adaptivedemux2/dash/gstmpdsegmenturlnode.c"
36 #include "../../ext/adaptivedemux2/dash/gstmpdsegmentlistnode.c"
37 #include "../../ext/adaptivedemux2/dash/gstmpdsegmentbasenode.c"
38 #include "../../ext/adaptivedemux2/dash/gstmpdperiodnode.c"
39 #include "../../ext/adaptivedemux2/dash/gstmpdsubrepresentationnode.c"
40 #include "../../ext/adaptivedemux2/dash/gstmpdrepresentationnode.c"
41 #include "../../ext/adaptivedemux2/dash/gstmpdcontentcomponentnode.c"
42 #include "../../ext/adaptivedemux2/dash/gstmpdadaptationsetnode.c"
43 #include "../../ext/adaptivedemux2/dash/gstmpdsubsetnode.c"
44 #include "../../ext/adaptivedemux2/dash/gstmpdprograminformationnode.c"
45 #include "../../ext/adaptivedemux2/dash/gstmpdlocationnode.c"
46 #include "../../ext/adaptivedemux2/dash/gstmpdreportingnode.c"
47 #include "../../ext/adaptivedemux2/dash/gstmpdurltypenode.c"
48 #include "../../ext/adaptivedemux2/dash/gstmpddescriptortypenode.c"
49 #include "../../ext/adaptivedemux2/dash/gstmpdclient.c"
50 #undef GST_CAT_DEFAULT
51
52 #include <gst/check/gstcheck.h>
53
54 GST_DEBUG_CATEGORY (gst_dash_demux2_debug);
55
56 /*
57  * Linker liked to complain about missing downloadhelper_* symbols.
58  * The tests below don't actually use them, so this stub is intended to
59  * get rid of those warnings. Linker doesn't seem to complain anymore.
60  */
61 DownloadRequest *
62 downloadhelper_fetch_uri (DownloadHelper * dh, const gchar * uri,
63     const gchar * referer, DownloadFlags flags, GError ** err)
64 {
65   g_assert_not_reached ();
66 }
67
68 /*
69  * compute the number of milliseconds contained in a duration value specified by
70  * year, month, day, hour, minute, second, millisecond
71  *
72  * This function must use the same conversion algorithm implemented in
73  * gst_xml_helper_get_prop_duration from gstmpdparser.c file.
74  */
75 static guint64
76 duration_to_ms (guint year, guint month, guint day, guint hour, guint minute,
77     guint second, guint millisecond)
78 {
79   guint64 days = (guint64) year * 365 + (guint64) month * 30 + day;
80   guint64 hours = days * 24 + hour;
81   guint64 minutes = hours * 60 + minute;
82   guint64 seconds = minutes * 60 + second;
83   guint64 ms = seconds * 1000 + millisecond;
84   return ms;
85 }
86
87 static GstClockTime
88 duration_to_clocktime (guint year, guint month, guint day, guint hour,
89     guint minute, guint second, guint millisecond)
90 {
91   return (GST_MSECOND * duration_to_ms (year, month, day, hour, minute, second,
92           millisecond));
93 }
94
95 /*
96  * Test to ensure a simple mpd file successfully parses.
97  *
98  */
99 GST_START_TEST (dash_mpdparser_validsimplempd)
100 {
101   const gchar *xml =
102       "<?xml version=\"1.0\"?>"
103       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
104       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"> </MPD>";
105
106   gboolean ret;
107   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
108
109   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
110   assert_equals_int (ret, TRUE);
111
112   /* check that unset elements with default values are properly configured */
113   assert_equals_int (mpdclient->mpd_root_node->type, GST_MPD_FILE_TYPE_STATIC);
114
115   gst_mpd_client2_free (mpdclient);
116 }
117
118 GST_END_TEST;
119
120 /*
121  * Test parsing the MPD attributes.
122  *
123  */
124 GST_START_TEST (dash_mpdparser_mpd)
125 {
126   GstDateTime *availabilityStartTime;
127   GstDateTime *availabilityEndTime;
128   const gchar *xml =
129       "<?xml version=\"1.0\"?>"
130       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
131       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
132       "     schemaLocation=\"TestSchemaLocation\""
133       "     xmlns:xsi=\"TestNamespaceXSI\""
134       "     xmlns:ext=\"TestNamespaceEXT\""
135       "     id=\"testId\""
136       "     type=\"static\""
137       "     availabilityStartTime=\"2015-03-24T1:10:50\""
138       "     availabilityEndTime=\"2015-03-24T1:10:50.123456\""
139       "     mediaPresentationDuration=\"P0Y1M2DT12H10M20.5S\""
140       "     minimumUpdatePeriod=\"P0Y1M2DT12H10M20.5S\""
141       "     minBufferTime=\"P0Y1M2DT12H10M20.5S\""
142       "     timeShiftBufferDepth=\"P0Y1M2DT12H10M20.5S\""
143       "     suggestedPresentationDelay=\"P0Y1M2DT12H10M20.5S\""
144       "     maxSegmentDuration=\"P0Y1M2DT12H10M20.5S\""
145       "     maxSubsegmentDuration=\"P0Y1M2DT12H10M20.5S\"></MPD>";
146
147   gboolean ret;
148   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
149
150   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
151   assert_equals_int (ret, TRUE);
152
153   assert_equals_string (mpdclient->mpd_root_node->default_namespace,
154       "urn:mpeg:dash:schema:mpd:2011");
155   assert_equals_string (mpdclient->mpd_root_node->namespace_xsi,
156       "TestNamespaceXSI");
157   assert_equals_string (mpdclient->mpd_root_node->namespace_ext,
158       "TestNamespaceEXT");
159   assert_equals_string (mpdclient->mpd_root_node->schemaLocation,
160       "TestSchemaLocation");
161   assert_equals_string (mpdclient->mpd_root_node->id, "testId");
162
163   assert_equals_int (mpdclient->mpd_root_node->type, GST_MPD_FILE_TYPE_STATIC);
164
165   availabilityStartTime = mpdclient->mpd_root_node->availabilityStartTime;
166   assert_equals_int (gst_date_time_get_year (availabilityStartTime), 2015);
167   assert_equals_int (gst_date_time_get_month (availabilityStartTime), 3);
168   assert_equals_int (gst_date_time_get_day (availabilityStartTime), 24);
169   assert_equals_int (gst_date_time_get_hour (availabilityStartTime), 1);
170   assert_equals_int (gst_date_time_get_minute (availabilityStartTime), 10);
171   assert_equals_int (gst_date_time_get_second (availabilityStartTime), 50);
172   assert_equals_int (gst_date_time_get_microsecond (availabilityStartTime), 0);
173
174   availabilityEndTime = mpdclient->mpd_root_node->availabilityEndTime;
175   assert_equals_int (gst_date_time_get_year (availabilityEndTime), 2015);
176   assert_equals_int (gst_date_time_get_month (availabilityEndTime), 3);
177   assert_equals_int (gst_date_time_get_day (availabilityEndTime), 24);
178   assert_equals_int (gst_date_time_get_hour (availabilityEndTime), 1);
179   assert_equals_int (gst_date_time_get_minute (availabilityEndTime), 10);
180   assert_equals_int (gst_date_time_get_second (availabilityEndTime), 50);
181   assert_equals_int (gst_date_time_get_microsecond (availabilityEndTime),
182       123456);
183
184   assert_equals_uint64 (mpdclient->mpd_root_node->mediaPresentationDuration,
185       duration_to_ms (0, 1, 2, 12, 10, 20, 500));
186
187   assert_equals_uint64 (mpdclient->mpd_root_node->minimumUpdatePeriod,
188       duration_to_ms (0, 1, 2, 12, 10, 20, 500));
189
190   assert_equals_uint64 (mpdclient->mpd_root_node->minBufferTime,
191       duration_to_ms (0, 1, 2, 12, 10, 20, 500));
192
193   assert_equals_uint64 (mpdclient->mpd_root_node->timeShiftBufferDepth,
194       duration_to_ms (0, 1, 2, 12, 10, 20, 500));
195
196   assert_equals_uint64 (mpdclient->mpd_root_node->suggestedPresentationDelay,
197       duration_to_ms (0, 1, 2, 12, 10, 20, 500));
198
199   assert_equals_uint64 (mpdclient->mpd_root_node->maxSegmentDuration,
200       duration_to_ms (0, 1, 2, 12, 10, 20, 500));
201
202   assert_equals_uint64 (mpdclient->mpd_root_node->maxSubsegmentDuration,
203       duration_to_ms (0, 1, 2, 12, 10, 20, 500));
204
205   gst_mpd_client2_free (mpdclient);
206 }
207
208 GST_END_TEST;
209
210 /*
211  * Test parsing the ProgramInformation attributes
212  *
213  */
214 GST_START_TEST (dash_mpdparser_programInformation)
215 {
216   GstMPDProgramInformationNode *program;
217   const gchar *xml =
218       "<?xml version=\"1.0\"?>"
219       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
220       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
221       "  <ProgramInformation lang=\"en\""
222       "                      moreInformationURL=\"TestMoreInformationUrl\">"
223       "    <Title>TestTitle</Title>"
224       "    <Source>TestSource</Source>"
225       "    <Copyright>TestCopyright</Copyright>"
226       "  </ProgramInformation> </MPD>";
227
228   gboolean ret;
229   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
230
231   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
232   assert_equals_int (ret, TRUE);
233
234   program =
235       (GstMPDProgramInformationNode *) mpdclient->mpd_root_node->ProgramInfos->
236       data;
237   assert_equals_string (program->lang, "en");
238   assert_equals_string (program->moreInformationURL, "TestMoreInformationUrl");
239   assert_equals_string (program->Title, "TestTitle");
240   assert_equals_string (program->Source, "TestSource");
241   assert_equals_string (program->Copyright, "TestCopyright");
242
243   gst_mpd_client2_free (mpdclient);
244 }
245
246 GST_END_TEST;
247
248 /*
249  * Test parsing the BaseURL attributes
250  *
251  */
252 GST_START_TEST (dash_mpdparser_baseURL)
253 {
254   GstMPDBaseURLNode *baseURL;
255   const gchar *xml =
256       "<?xml version=\"1.0\"?>"
257       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
258       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
259       "  <BaseURL serviceLocation=\"TestServiceLocation\""
260       "     byteRange=\"TestByteRange\">TestBaseURL</BaseURL></MPD>";
261
262   gboolean ret;
263   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
264
265   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
266   assert_equals_int (ret, TRUE);
267
268   baseURL = (GstMPDBaseURLNode *) mpdclient->mpd_root_node->BaseURLs->data;
269   assert_equals_string (baseURL->baseURL, "TestBaseURL");
270   assert_equals_string (baseURL->serviceLocation, "TestServiceLocation");
271   assert_equals_string (baseURL->byteRange, "TestByteRange");
272
273   gst_mpd_client2_free (mpdclient);
274 }
275
276 GST_END_TEST;
277
278 /*
279  * Test parsing the Location attributes
280  *
281  */
282 GST_START_TEST (dash_mpdparser_location)
283 {
284   GstMPDLocationNode *location;
285   const gchar *xml =
286       "<?xml version=\"1.0\"?>"
287       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
288       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
289       "  <Location>TestLocation</Location></MPD>";
290
291   gboolean ret;
292   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
293
294   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
295   assert_equals_int (ret, TRUE);
296
297   location = (GstMPDLocationNode *) mpdclient->mpd_root_node->Locations->data;
298   assert_equals_string (location->location, "TestLocation");
299
300   gst_mpd_client2_free (mpdclient);
301 }
302
303 GST_END_TEST;
304
305 /*
306  * Test parsing Metrics attributes
307  *
308  */
309 GST_START_TEST (dash_mpdparser_metrics)
310 {
311   GstMPDMetricsNode *metricsNode;
312   const gchar *xml =
313       "<?xml version=\"1.0\"?>"
314       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
315       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
316       "  <Metrics metrics=\"TestMetric\"></Metrics></MPD>";
317
318   gboolean ret;
319   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
320
321   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
322   assert_equals_int (ret, TRUE);
323
324   metricsNode = (GstMPDMetricsNode *) mpdclient->mpd_root_node->Metrics->data;
325   assert_equals_string (metricsNode->metrics, "TestMetric");
326
327   gst_mpd_client2_free (mpdclient);
328 }
329
330 GST_END_TEST;
331
332 /*
333  * Test parsing Metrics Range attributes
334  *
335  */
336 GST_START_TEST (dash_mpdparser_metrics_range)
337 {
338   GstMPDMetricsNode *metricsNode;
339   GstMPDMetricsRangeNode *metricsRangeNode;
340   const gchar *xml =
341       "<?xml version=\"1.0\"?>"
342       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
343       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
344       "  <Metrics>"
345       "    <Range starttime=\"P0Y1M2DT12H10M20.5S\""
346       "           duration=\"P0Y1M2DT12H10M20.1234567S\">"
347       "    </Range></Metrics></MPD>";
348
349   gboolean ret;
350   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
351
352   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
353   assert_equals_int (ret, TRUE);
354
355   metricsNode = (GstMPDMetricsNode *) mpdclient->mpd_root_node->Metrics->data;
356   assert_equals_pointer (metricsNode->metrics, NULL);
357   metricsRangeNode =
358       (GstMPDMetricsRangeNode *) metricsNode->MetricsRanges->data;
359   assert_equals_uint64 (metricsRangeNode->starttime, duration_to_ms (0, 1, 2,
360           12, 10, 20, 500));
361   assert_equals_uint64 (metricsRangeNode->duration, duration_to_ms (0, 1, 2, 12,
362           10, 20, 123));
363
364   gst_mpd_client2_free (mpdclient);
365 }
366
367 GST_END_TEST;
368
369 /*
370  * Test parsing Metrics Reporting attributes
371  *
372  */
373 GST_START_TEST (dash_mpdparser_metrics_reporting)
374 {
375   GstMPDMetricsNode *metricsNode;
376   const gchar *xml =
377       "<?xml version=\"1.0\"?>"
378       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
379       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
380       "  <Metrics><Reporting></Reporting></Metrics></MPD>";
381
382   gboolean ret;
383   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
384
385   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
386   assert_equals_int (ret, TRUE);
387
388   metricsNode = (GstMPDMetricsNode *) mpdclient->mpd_root_node->Metrics->data;
389   assert_equals_pointer (metricsNode->metrics, NULL);
390
391   gst_mpd_client2_free (mpdclient);
392 }
393
394 GST_END_TEST;
395
396 /*
397  * Test parsing Period attributes
398  *
399  */
400 GST_START_TEST (dash_mpdparser_period)
401 {
402   GstMPDPeriodNode *periodNode;
403   const gchar *xml =
404       "<?xml version=\"1.0\"?>"
405       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
406       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
407       "  <Period id=\"TestId\""
408       "          start=\"P0Y1M2DT12H10M20.1234567S\""
409       "          duration=\"P0Y1M2DT12H10M20.7654321S\""
410       "          bitstreamSwitching=\"true\"></Period></MPD>";
411
412   gboolean ret;
413   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
414
415   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
416   assert_equals_int (ret, TRUE);
417
418   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
419   assert_equals_string (periodNode->id, "TestId");
420   assert_equals_uint64 (periodNode->start,
421       duration_to_ms (0, 1, 2, 12, 10, 20, 123));
422   assert_equals_uint64 (periodNode->duration,
423       duration_to_ms (0, 1, 2, 12, 10, 20, 765));
424   assert_equals_int (periodNode->bitstreamSwitching, 1);
425
426   gst_mpd_client2_free (mpdclient);
427 }
428
429 GST_END_TEST;
430
431 /*
432  * Test parsing Period baseURL attributes
433  *
434  */
435 GST_START_TEST (dash_mpdparser_period_baseURL)
436 {
437   GstMPDPeriodNode *periodNode;
438   GstMPDBaseURLNode *baseURL;
439   const gchar *xml =
440       "<?xml version=\"1.0\"?>"
441       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
442       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
443       "  <Period>"
444       "    <BaseURL serviceLocation=\"TestServiceLocation\""
445       "             byteRange=\"TestByteRange\">TestBaseURL</BaseURL>"
446       "  </Period></MPD>";
447
448   gboolean ret;
449   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
450
451   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
452   assert_equals_int (ret, TRUE);
453
454   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
455   baseURL = (GstMPDBaseURLNode *) periodNode->BaseURLs->data;
456   assert_equals_string (baseURL->baseURL, "TestBaseURL");
457   assert_equals_string (baseURL->serviceLocation, "TestServiceLocation");
458   assert_equals_string (baseURL->byteRange, "TestByteRange");
459
460   gst_mpd_client2_free (mpdclient);
461 }
462
463 GST_END_TEST;
464
465 /*
466  * Test parsing Period SegmentBase attributes
467  *
468  */
469 GST_START_TEST (dash_mpdparser_period_segmentBase)
470 {
471   GstMPDPeriodNode *periodNode;
472   GstMPDSegmentBaseNode *segmentBase;
473   const gchar *xml =
474       "<?xml version=\"1.0\"?>"
475       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
476       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
477       "  <Period>"
478       "    <SegmentBase timescale=\"123456\""
479       "                 presentationTimeOffset=\"123456789\""
480       "                 indexRange=\"100-200\""
481       "                 indexRangeExact=\"true\">"
482       "    </SegmentBase></Period></MPD>";
483
484   gboolean ret;
485   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
486
487   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
488   assert_equals_int (ret, TRUE);
489
490   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
491   segmentBase = periodNode->SegmentBase;
492   assert_equals_uint64 (segmentBase->timescale, 123456);
493   assert_equals_uint64 (segmentBase->presentationTimeOffset, 123456789);
494   assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 100);
495   assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 200);
496   assert_equals_int (segmentBase->indexRangeExact, 1);
497
498   gst_mpd_client2_free (mpdclient);
499 }
500
501 GST_END_TEST;
502
503 /*
504  * Test parsing Period SegmentBase Initialization attributes
505  *
506  */
507 GST_START_TEST (dash_mpdparser_period_segmentBase_initialization)
508 {
509   GstMPDPeriodNode *periodNode;
510   GstMPDSegmentBaseNode *segmentBase;
511   GstMPDURLTypeNode *initialization;
512   const gchar *xml =
513       "<?xml version=\"1.0\"?>"
514       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
515       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
516       "  <Period>"
517       "    <SegmentBase>"
518       "      <Initialisation sourceURL=\"TestSourceURL\""
519       "                      range=\"100-200\">"
520       "      </Initialisation></SegmentBase></Period></MPD>";
521
522   gboolean ret;
523   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
524
525   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
526   assert_equals_int (ret, TRUE);
527
528   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
529   segmentBase = periodNode->SegmentBase;
530   initialization = segmentBase->Initialization;
531   assert_equals_string (initialization->sourceURL, "TestSourceURL");
532   assert_equals_uint64 (initialization->range->first_byte_pos, 100);
533   assert_equals_uint64 (initialization->range->last_byte_pos, 200);
534
535   gst_mpd_client2_free (mpdclient);
536 }
537
538 GST_END_TEST;
539
540 /*
541  * Test parsing Period SegmentBase RepresentationIndex attributes
542  *
543  */
544 GST_START_TEST (dash_mpdparser_period_segmentBase_representationIndex)
545 {
546   GstMPDPeriodNode *periodNode;
547   GstMPDSegmentBaseNode *segmentBase;
548   GstMPDURLTypeNode *representationIndex;
549   const gchar *xml =
550       "<?xml version=\"1.0\"?>"
551       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
552       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
553       "  <Period>"
554       "    <SegmentBase>"
555       "      <RepresentationIndex sourceURL=\"TestSourceURL\""
556       "                           range=\"100-200\">"
557       "      </RepresentationIndex></SegmentBase></Period></MPD>";
558
559   gboolean ret;
560   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
561
562   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
563   assert_equals_int (ret, TRUE);
564
565   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
566   segmentBase = periodNode->SegmentBase;
567   representationIndex = segmentBase->RepresentationIndex;
568   assert_equals_string (representationIndex->sourceURL, "TestSourceURL");
569   assert_equals_uint64 (representationIndex->range->first_byte_pos, 100);
570   assert_equals_uint64 (representationIndex->range->last_byte_pos, 200);
571
572   gst_mpd_client2_free (mpdclient);
573 }
574
575 GST_END_TEST;
576
577 /*
578  * Test parsing Period SegmentList attributes
579  *
580  */
581 GST_START_TEST (dash_mpdparser_period_segmentList)
582 {
583   GstMPDPeriodNode *periodNode;
584   GstMPDSegmentListNode *segmentList;
585   const gchar *xml =
586       "<?xml version=\"1.0\"?>"
587       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
588       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
589       "  <Period><SegmentList duration=\"1\"></SegmentList></Period></MPD>";
590
591   gboolean ret;
592   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
593
594   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
595   assert_equals_int (ret, TRUE);
596
597   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
598   segmentList = periodNode->SegmentList;
599   fail_if (segmentList == NULL);
600
601   gst_mpd_client2_free (mpdclient);
602 }
603
604 GST_END_TEST;
605
606 /*
607  * Test parsing Period SegmentList MultipleSegmentBaseType attributes
608  *
609  */
610 GST_START_TEST (dash_mpdparser_period_segmentList_multipleSegmentBaseType)
611 {
612   GstMPDPeriodNode *periodNode;
613   GstMPDSegmentListNode *segmentList;
614
615   const gchar *xml =
616       "<?xml version=\"1.0\"?>"
617       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
618       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
619       "  <Period>"
620       "    <SegmentList duration=\"10\""
621       "                 startNumber=\"11\">"
622       "    </SegmentList></Period></MPD>";
623
624   gboolean ret;
625   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
626
627   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
628   assert_equals_int (ret, TRUE);
629
630   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
631   segmentList = periodNode->SegmentList;
632
633   assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->duration,
634       10);
635   assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
636       (segmentList)->startNumber, 11);
637
638   gst_mpd_client2_free (mpdclient);
639 }
640
641 GST_END_TEST;
642
643 /*
644  * Test parsing Period SegmentList MultipleSegmentBaseType SegmentBaseType
645  * attributes
646  */
647 GST_START_TEST
648     (dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentBaseType)
649 {
650   GstMPDPeriodNode *periodNode;
651   GstMPDSegmentListNode *segmentList;
652   GstMPDSegmentBaseNode *segmentBase;
653   const gchar *xml =
654       "<?xml version=\"1.0\"?>"
655       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
656       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
657       "  <Period>"
658       "    <SegmentList timescale=\"10\""
659       "                 duration=\"1\""
660       "                 presentationTimeOffset=\"11\""
661       "                 indexRange=\"20-21\""
662       "                 indexRangeExact=\"false\">"
663       "    </SegmentList></Period></MPD>";
664
665   gboolean ret;
666   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
667
668   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
669   assert_equals_int (ret, TRUE);
670
671   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
672   segmentList = periodNode->SegmentList;
673   segmentBase = GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->SegmentBase;
674   assert_equals_uint64 (segmentBase->timescale, 10);
675   assert_equals_uint64 (segmentBase->presentationTimeOffset, 11);
676   assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 20);
677   assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 21);
678   assert_equals_int (segmentBase->indexRangeExact, FALSE);
679
680   gst_mpd_client2_free (mpdclient);
681 }
682
683 GST_END_TEST;
684
685 /*
686  * Test parsing Period SegmentList MultipleSegmentBaseType SegmentTimeline
687  * attributes
688  */
689 GST_START_TEST
690     (dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline)
691 {
692   GstMPDPeriodNode *periodNode;
693   GstMPDSegmentListNode *segmentList;
694   GstMPDSegmentTimelineNode *segmentTimeline;
695   const gchar *xml =
696       "<?xml version=\"1.0\"?>"
697       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
698       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
699       "  <Period>"
700       "    <SegmentList>"
701       "      <SegmentTimeline>"
702       "      </SegmentTimeline></SegmentList></Period></MPD>";
703
704   gboolean ret;
705   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
706
707   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
708   assert_equals_int (ret, TRUE);
709
710   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
711   segmentList = periodNode->SegmentList;
712   segmentTimeline =
713       GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->SegmentTimeline;
714   fail_if (segmentTimeline == NULL);
715
716   gst_mpd_client2_free (mpdclient);
717 }
718
719 GST_END_TEST;
720
721 /*
722  * Test parsing Period SegmentList MultipleSegmentBaseType SegmentTimeline S
723  * attributes
724  */
725 GST_START_TEST
726     (dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline_s)
727 {
728   GstMPDPeriodNode *periodNode;
729   GstMPDSegmentListNode *segmentList;
730   GstMPDSegmentTimelineNode *segmentTimeline;
731   GstMPDSNode *sNode;
732   const gchar *xml =
733       "<?xml version=\"1.0\"?>"
734       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
735       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
736       "  <Period>"
737       "    <SegmentList>"
738       "      <SegmentTimeline>"
739       "        <S t=\"1\" d=\"2\" r=\"3\">"
740       "        </S></SegmentTimeline></SegmentList></Period></MPD>";
741
742   gboolean ret;
743   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
744
745   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
746   assert_equals_int (ret, TRUE);
747
748   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
749   segmentList = periodNode->SegmentList;
750   segmentTimeline =
751       GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->SegmentTimeline;
752   sNode = (GstMPDSNode *) g_queue_peek_head (&segmentTimeline->S);
753   assert_equals_uint64 (sNode->t, 1);
754   assert_equals_uint64 (sNode->d, 2);
755   assert_equals_uint64 (sNode->r, 3);
756
757   gst_mpd_client2_free (mpdclient);
758 }
759
760 GST_END_TEST;
761
762 /*
763  * Test parsing Period SegmentList MultipleSegmentBaseType BitstreamSwitching
764  * attributes
765  */
766 GST_START_TEST
767     (dash_mpdparser_period_segmentList_multipleSegmentBaseType_bitstreamSwitching)
768 {
769   GstMPDPeriodNode *periodNode;
770   GstMPDSegmentListNode *segmentList;
771   GstMPDURLTypeNode *bitstreamSwitching;
772   const gchar *xml =
773       "<?xml version=\"1.0\"?>"
774       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
775       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
776       "  <Period>"
777       "    <SegmentList duration=\"0\">"
778       "      <BitstreamSwitching sourceURL=\"TestSourceURL\""
779       "                          range=\"100-200\">"
780       "      </BitstreamSwitching></SegmentList></Period></MPD>";
781
782   gboolean ret;
783   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
784
785   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
786   assert_equals_int (ret, TRUE);
787
788   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
789   segmentList = periodNode->SegmentList;
790
791   bitstreamSwitching =
792       GST_MPD_MULT_SEGMENT_BASE_NODE (segmentList)->BitstreamSwitching;
793   assert_equals_string (bitstreamSwitching->sourceURL, "TestSourceURL");
794   assert_equals_uint64 (bitstreamSwitching->range->first_byte_pos, 100);
795   assert_equals_uint64 (bitstreamSwitching->range->last_byte_pos, 200);
796
797   gst_mpd_client2_free (mpdclient);
798 }
799
800 GST_END_TEST;
801
802 /*
803  * Test parsing Period SegmentList SegmentURL attributes
804  *
805  */
806 GST_START_TEST (dash_mpdparser_period_segmentList_segmentURL)
807 {
808   GstMPDPeriodNode *periodNode;
809   GstMPDSegmentListNode *segmentList;
810   GstMPDSegmentURLNode *segmentURL;
811   const gchar *xml =
812       "<?xml version=\"1.0\"?>"
813       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
814       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
815       "  <Period>"
816       "    <SegmentList duration=\"1\">"
817       "      <SegmentURL media=\"TestMedia\""
818       "                  mediaRange=\"100-200\""
819       "                  index=\"TestIndex\""
820       "                  indexRange=\"300-400\">"
821       "      </SegmentURL></SegmentList></Period></MPD>";
822
823   gboolean ret;
824   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
825
826   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
827   assert_equals_int (ret, TRUE);
828
829   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
830   segmentList = periodNode->SegmentList;
831   segmentURL = (GstMPDSegmentURLNode *) segmentList->SegmentURL->data;
832   assert_equals_string (segmentURL->media, "TestMedia");
833   assert_equals_uint64 (segmentURL->mediaRange->first_byte_pos, 100);
834   assert_equals_uint64 (segmentURL->mediaRange->last_byte_pos, 200);
835   assert_equals_string (segmentURL->index, "TestIndex");
836   assert_equals_uint64 (segmentURL->indexRange->first_byte_pos, 300);
837   assert_equals_uint64 (segmentURL->indexRange->last_byte_pos, 400);
838
839   gst_mpd_client2_free (mpdclient);
840 }
841
842 GST_END_TEST;
843
844 /*
845  * Test parsing Period SegmentTemplate attributes
846  *
847  */
848 GST_START_TEST (dash_mpdparser_period_segmentTemplate)
849 {
850   GstMPDPeriodNode *periodNode;
851   GstMPDSegmentTemplateNode *segmentTemplate;
852   const gchar *xml =
853       "<?xml version=\"1.0\"?>"
854       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
855       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
856       "  <Period>"
857       "    <SegmentTemplate media=\"TestMedia\""
858       "                     duration=\"0\""
859       "                     index=\"TestIndex\""
860       "                     initialization=\"TestInitialization\""
861       "                     bitstreamSwitching=\"TestBitstreamSwitching\">"
862       "    </SegmentTemplate></Period></MPD>";
863
864   gboolean ret;
865   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
866
867   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
868   assert_equals_int (ret, TRUE);
869
870   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
871   segmentTemplate = periodNode->SegmentTemplate;
872   assert_equals_string (segmentTemplate->media, "TestMedia");
873   assert_equals_string (segmentTemplate->index, "TestIndex");
874   assert_equals_string (segmentTemplate->initialization, "TestInitialization");
875   assert_equals_string (segmentTemplate->bitstreamSwitching,
876       "TestBitstreamSwitching");
877
878   gst_mpd_client2_free (mpdclient);
879 }
880
881 GST_END_TEST;
882
883 /*
884  * Test parsing Period SegmentTemplate attributes where a
885  * presentationTimeOffset attribute has been specified
886  *
887  */
888 GST_START_TEST (dash_mpdparser_period_segmentTemplateWithPresentationTimeOffset)
889 {
890   const gchar *xml =
891       "<?xml version=\"1.0\"?>"
892       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
893       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
894       "  <Period start=\"PT1M\" duration=\"PT40S\">"
895       "    <AdaptationSet"
896       "      bitstreamSwitching=\"false\""
897       "      mimeType=\"video/mp4\""
898       "      contentType=\"video\">"
899       "      <SegmentTemplate media=\"$RepresentationID$/TestMedia-$Time$.mp4\""
900       "                     index=\"$RepresentationID$/TestIndex.mp4\""
901       "                     timescale=\"100\""
902       "                     presentationTimeOffset=\"6000\""
903       "                     initialization=\"$RepresentationID$/TestInitialization\""
904       "                     bitstreamSwitching=\"true\">"
905       "        <SegmentTimeline>"
906       "          <S d=\"400\" r=\"9\" t=\"100\"/>"
907       "        </SegmentTimeline></SegmentTemplate>"
908       "      <Representation bandwidth=\"95866\" frameRate=\"90000/3600\""
909       "        id=\"vrep\" /></AdaptationSet></Period></MPD>";
910
911   gboolean ret;
912   GList *adaptationSets;
913   GstMPDAdaptationSetNode *adapt_set;
914   GstActiveStream *activeStream;
915   GstMediaFragmentInfo fragment;
916   GstClockTime expectedDuration;
917   GstClockTime expectedTimestamp;
918   GstMPDClient2 *mpdclient;
919   GstMPDPeriodNode *periodNode;
920   GstMPDSegmentTemplateNode *segmentTemplate;
921
922   mpdclient = gst_mpd_client2_new ();
923   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
924   assert_equals_int (ret, TRUE);
925
926   ret =
927       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
928       -1, NULL);
929   assert_equals_int (ret, TRUE);
930
931   periodNode =
932       (GstMPDPeriodNode *) g_list_nth_data (mpdclient->mpd_root_node->Periods,
933       0);
934   fail_if (periodNode == NULL);
935
936   /* get the list of adaptation sets of the first period */
937   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
938   fail_if (adaptationSets == NULL);
939
940   /* setup streaming from the first adaptation set */
941   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
942   fail_if (adapt_set == NULL);
943   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
944   assert_equals_int (ret, TRUE);
945   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
946   fail_if (activeStream == NULL);
947
948   segmentTemplate = adapt_set->SegmentTemplate;
949   fail_if (segmentTemplate == NULL);
950   assert_equals_string (segmentTemplate->media,
951       "$RepresentationID$/TestMedia-$Time$.mp4");
952   assert_equals_string (segmentTemplate->index,
953       "$RepresentationID$/TestIndex.mp4");
954   assert_equals_string (segmentTemplate->initialization,
955       "$RepresentationID$/TestInitialization");
956   assert_equals_string (segmentTemplate->bitstreamSwitching, "true");
957
958   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
959   assert_equals_int (ret, TRUE);
960   expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 4, 0);
961   /* start = Period@start + S@t - presentationTimeOffset */
962   expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 1, 0);
963   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
964   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
965   /* the $Time$ expansion uses the @t value, without including
966      Period@start or presentationTimeOffset */
967   assert_equals_string (fragment.uri, "/vrep/TestMedia-100.mp4");
968   gst_mpdparser_media_fragment_info_clear (&fragment);
969
970   gst_mpd_client2_free (mpdclient);
971 }
972
973 GST_END_TEST;
974
975 /*
976  * Test parsing Period SegmentTemplate MultipleSegmentBaseType attributes
977  *
978  */
979 GST_START_TEST (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType)
980 {
981   GstMPDPeriodNode *periodNode;
982   GstMPDSegmentTemplateNode *segmentTemplate;
983   const gchar *xml =
984       "<?xml version=\"1.0\"?>"
985       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
986       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
987       "  <Period>"
988       "    <SegmentTemplate duration=\"10\""
989       "                     startNumber=\"11\">"
990       "    </SegmentTemplate></Period></MPD>";
991
992   gboolean ret;
993   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
994
995   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
996   assert_equals_int (ret, TRUE);
997
998   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
999   segmentTemplate = periodNode->SegmentTemplate;
1000
1001   assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
1002       (segmentTemplate)->duration, 10);
1003   assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
1004       (segmentTemplate)->startNumber, 11);
1005
1006   gst_mpd_client2_free (mpdclient);
1007 }
1008
1009 GST_END_TEST;
1010
1011 /*
1012  * Test parsing Period SegmentTemplate MultipleSegmentBaseType SegmentBaseType
1013  * attributes
1014  */
1015 GST_START_TEST
1016     (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentBaseType)
1017 {
1018   GstMPDPeriodNode *periodNode;
1019   GstMPDSegmentTemplateNode *segmentTemplate;
1020   GstMPDSegmentBaseNode *segmentBase;
1021   const gchar *xml =
1022       "<?xml version=\"1.0\"?>"
1023       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1024       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1025       "  <Period>"
1026       "    <SegmentTemplate timescale=\"123456\""
1027       "                     duration=\"1\""
1028       "                     presentationTimeOffset=\"123456789\""
1029       "                     indexRange=\"100-200\""
1030       "                     indexRangeExact=\"true\">"
1031       "    </SegmentTemplate></Period></MPD>";
1032
1033   gboolean ret;
1034   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1035
1036   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1037   assert_equals_int (ret, TRUE);
1038
1039   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1040   segmentTemplate = periodNode->SegmentTemplate;
1041   segmentBase = GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->SegmentBase;
1042   assert_equals_uint64 (segmentBase->timescale, 123456);
1043   assert_equals_uint64 (segmentBase->presentationTimeOffset, 123456789);
1044   assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 100);
1045   assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 200);
1046   assert_equals_int (segmentBase->indexRangeExact, TRUE);
1047
1048   gst_mpd_client2_free (mpdclient);
1049 }
1050
1051 GST_END_TEST;
1052
1053 /*
1054  * Test parsing Period SegmentTemplate MultipleSegmentBaseType SegmentTimeline
1055  * attributes
1056  */
1057 GST_START_TEST
1058     (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline)
1059 {
1060   GstMPDPeriodNode *periodNode;
1061   GstMPDSegmentTemplateNode *segmentTemplate;
1062   GstMPDSegmentTimelineNode *segmentTimeline;
1063   const gchar *xml =
1064       "<?xml version=\"1.0\"?>"
1065       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1066       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1067       "  <Period>"
1068       "    <SegmentTemplate>"
1069       "      <SegmentTimeline>"
1070       "      </SegmentTimeline></SegmentTemplate></Period></MPD>";
1071
1072   gboolean ret;
1073   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1074
1075   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1076   assert_equals_int (ret, TRUE);
1077
1078   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1079   segmentTemplate = periodNode->SegmentTemplate;
1080
1081   segmentTimeline = (GstMPDSegmentTimelineNode *)
1082       GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->SegmentTimeline;
1083   fail_if (segmentTimeline == NULL);
1084
1085   gst_mpd_client2_free (mpdclient);
1086 }
1087
1088 GST_END_TEST;
1089
1090 /*
1091  * Test parsing Period SegmentTemplate MultipleSegmentBaseType SegmentTimeline
1092  * S attributes
1093  */
1094 GST_START_TEST
1095     (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline_s)
1096 {
1097   GstMPDPeriodNode *periodNode;
1098   GstMPDSegmentTemplateNode *segmentTemplate;
1099   GstMPDSegmentTimelineNode *segmentTimeline;
1100   GstMPDSNode *sNode;
1101   const gchar *xml =
1102       "<?xml version=\"1.0\"?>"
1103       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1104       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1105       "  <Period>"
1106       "    <SegmentTemplate>"
1107       "      <SegmentTimeline>"
1108       "        <S t=\"1\" d=\"2\" r=\"3\">"
1109       "        </S></SegmentTimeline></SegmentTemplate></Period></MPD>";
1110
1111   gboolean ret;
1112   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1113
1114   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1115   assert_equals_int (ret, TRUE);
1116
1117   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1118   segmentTemplate = periodNode->SegmentTemplate;
1119   segmentTimeline = (GstMPDSegmentTimelineNode *)
1120       GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->SegmentTimeline;
1121   sNode = (GstMPDSNode *) g_queue_peek_head (&segmentTimeline->S);
1122   assert_equals_uint64 (sNode->t, 1);
1123   assert_equals_uint64 (sNode->d, 2);
1124   assert_equals_uint64 (sNode->r, 3);
1125
1126   gst_mpd_client2_free (mpdclient);
1127 }
1128
1129 GST_END_TEST;
1130
1131 /*
1132  * Test parsing Period SegmentTemplate MultipleSegmentBaseType
1133  * BitstreamSwitching attributes
1134  */
1135 GST_START_TEST
1136     (dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_bitstreamSwitching)
1137 {
1138   GstMPDPeriodNode *periodNode;
1139   GstMPDSegmentTemplateNode *segmentTemplate;
1140   GstMPDURLTypeNode *bitstreamSwitching;
1141   const gchar *xml =
1142       "<?xml version=\"1.0\"?>"
1143       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1144       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1145       "  <Period>"
1146       "    <SegmentTemplate duration=\"1\">"
1147       "      <BitstreamSwitching sourceURL=\"TestSourceURL\""
1148       "                          range=\"100-200\">"
1149       "      </BitstreamSwitching></SegmentTemplate></Period></MPD>";
1150
1151   gboolean ret;
1152   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1153
1154   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1155   assert_equals_int (ret, TRUE);
1156
1157   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1158   segmentTemplate = periodNode->SegmentTemplate;
1159   bitstreamSwitching =
1160       GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->BitstreamSwitching;
1161   assert_equals_string (bitstreamSwitching->sourceURL, "TestSourceURL");
1162   assert_equals_uint64 (bitstreamSwitching->range->first_byte_pos, 100);
1163   assert_equals_uint64 (bitstreamSwitching->range->last_byte_pos, 200);
1164
1165   gst_mpd_client2_free (mpdclient);
1166 }
1167
1168 GST_END_TEST;
1169
1170 /*
1171  * Test parsing Period AdaptationSet attributes
1172  *
1173  */
1174 GST_START_TEST (dash_mpdparser_period_adaptationSet)
1175 {
1176   GstMPDPeriodNode *periodNode;
1177   GstMPDAdaptationSetNode *adaptationSet;
1178   const gchar *xml =
1179       "<?xml version=\"1.0\"?>"
1180       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1181       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1182       "  <Period>"
1183       "    <AdaptationSet id=\"7\""
1184       "                   group=\"8\""
1185       "                   lang=\"en\""
1186       "                   contentType=\"TestContentType\""
1187       "                   par=\"4:3\""
1188       "                   minBandwidth=\"100\""
1189       "                   maxBandwidth=\"200\""
1190       "                   minWidth=\"1000\""
1191       "                   maxWidth=\"2000\""
1192       "                   minHeight=\"1100\""
1193       "                   maxHeight=\"2100\""
1194       "                   minFrameRate=\"25/123\""
1195       "                   maxFrameRate=\"26\""
1196       "                   segmentAlignment=\"2\""
1197       "                   subsegmentAlignment=\"false\""
1198       "                   subsegmentStartsWithSAP=\"6\""
1199       "                   bitstreamSwitching=\"false\">"
1200       "    </AdaptationSet></Period></MPD>";
1201
1202   gboolean ret;
1203   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1204
1205   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1206   assert_equals_int (ret, TRUE);
1207
1208   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1209   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1210   assert_equals_uint64 (adaptationSet->id, 7);
1211   assert_equals_uint64 (adaptationSet->group, 8);
1212   assert_equals_string (adaptationSet->lang, "en");
1213   assert_equals_string (adaptationSet->contentType, "TestContentType");
1214   assert_equals_uint64 (adaptationSet->par->num, 4);
1215   assert_equals_uint64 (adaptationSet->par->den, 3);
1216   assert_equals_uint64 (adaptationSet->minBandwidth, 100);
1217   assert_equals_uint64 (adaptationSet->maxBandwidth, 200);
1218   assert_equals_uint64 (adaptationSet->minWidth, 1000);
1219   assert_equals_uint64 (adaptationSet->maxWidth, 2000);
1220   assert_equals_uint64 (adaptationSet->minHeight, 1100);
1221   assert_equals_uint64 (adaptationSet->maxHeight, 2100);
1222   assert_equals_uint64 (GST_MPD_REPRESENTATION_BASE_NODE
1223       (adaptationSet)->minFrameRate->num, 25);
1224   assert_equals_uint64 (GST_MPD_REPRESENTATION_BASE_NODE
1225       (adaptationSet)->minFrameRate->den, 123);
1226   assert_equals_uint64 (GST_MPD_REPRESENTATION_BASE_NODE
1227       (adaptationSet)->maxFrameRate->num, 26);
1228   assert_equals_uint64 (GST_MPD_REPRESENTATION_BASE_NODE
1229       (adaptationSet)->maxFrameRate->den, 1);
1230   assert_equals_int (adaptationSet->segmentAlignment->flag, 1);
1231   assert_equals_uint64 (adaptationSet->segmentAlignment->value, 2);
1232   assert_equals_int (adaptationSet->subsegmentAlignment->flag, 0);
1233   assert_equals_uint64 (adaptationSet->subsegmentAlignment->value, 0);
1234   assert_equals_int (adaptationSet->subsegmentStartsWithSAP, 6);
1235   assert_equals_int (adaptationSet->bitstreamSwitching, 0);
1236
1237   gst_mpd_client2_free (mpdclient);
1238 }
1239
1240 GST_END_TEST;
1241
1242 /*
1243  * Test parsing Period AdaptationSet RepresentationBase attributes
1244  *
1245  */
1246 GST_START_TEST (dash_mpdparser_period_adaptationSet_representationBase)
1247 {
1248   GstMPDPeriodNode *periodNode;
1249   GstMPDAdaptationSetNode *adaptationSet;
1250   GstMPDRepresentationBaseNode *representationBase;
1251   const gchar *xml =
1252       "<?xml version=\"1.0\"?>"
1253       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1254       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1255       "  <Period>"
1256       "    <AdaptationSet profiles=\"TestProfiles\""
1257       "                   width=\"100\""
1258       "                   height=\"200\""
1259       "                   sar=\"10:20\""
1260       "                   frameRate=\"30/40\""
1261       "                   audioSamplingRate=\"TestAudioSamplingRate\""
1262       "                   mimeType=\"TestMimeType\""
1263       "                   segmentProfiles=\"TestSegmentProfiles\""
1264       "                   codecs=\"TestCodecs\""
1265       "                   maximumSAPPeriod=\"3.4\""
1266       "                   startWithSAP=\"0\""
1267       "                   maxPlayoutRate=\"1.2\""
1268       "                   codingDependency=\"false\""
1269       "                   scanType=\"progressive\">"
1270       "    </AdaptationSet></Period></MPD>";
1271
1272   gboolean ret;
1273   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1274
1275   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1276   assert_equals_int (ret, TRUE);
1277
1278   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1279   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1280   representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
1281   assert_equals_string (representationBase->profiles, "TestProfiles");
1282   assert_equals_uint64 (representationBase->width, 100);
1283   assert_equals_uint64 (representationBase->height, 200);
1284   assert_equals_uint64 (representationBase->sar->num, 10);
1285   assert_equals_uint64 (representationBase->sar->den, 20);
1286   assert_equals_uint64 (representationBase->frameRate->num, 30);
1287   assert_equals_uint64 (representationBase->frameRate->den, 40);
1288   assert_equals_string (representationBase->audioSamplingRate,
1289       "TestAudioSamplingRate");
1290   assert_equals_string (representationBase->mimeType, "TestMimeType");
1291   assert_equals_string (representationBase->segmentProfiles,
1292       "TestSegmentProfiles");
1293   assert_equals_string (representationBase->codecs, "TestCodecs");
1294   assert_equals_float (representationBase->maximumSAPPeriod, 3.4);
1295   assert_equals_int (representationBase->startWithSAP, GST_SAP_TYPE_0);
1296   assert_equals_float (representationBase->maxPlayoutRate, 1.2);
1297   assert_equals_float (representationBase->codingDependency, 0);
1298   assert_equals_string (representationBase->scanType, "progressive");
1299
1300   gst_mpd_client2_free (mpdclient);
1301 }
1302
1303 GST_END_TEST;
1304
1305 /*
1306  * Test parsing Period AdaptationSet RepresentationBase FramePacking attributes
1307  *
1308  */
1309 GST_START_TEST
1310     (dash_mpdparser_period_adaptationSet_representationBase_framePacking) {
1311   GstMPDPeriodNode *periodNode;
1312   GstMPDAdaptationSetNode *adaptationSet;
1313   GstMPDRepresentationBaseNode *representationBase;
1314   GstMPDDescriptorTypeNode *framePacking;
1315   const gchar *xml =
1316       "<?xml version=\"1.0\"?>"
1317       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1318       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1319       "  <Period>"
1320       "    <AdaptationSet>"
1321       "      <FramePacking schemeIdUri=\"TestSchemeIdUri\""
1322       "                    value=\"TestValue\">"
1323       "      </FramePacking></AdaptationSet></Period></MPD>";
1324
1325   gboolean ret;
1326   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1327
1328   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1329   assert_equals_int (ret, TRUE);
1330
1331   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1332   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1333   representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
1334   framePacking =
1335       (GstMPDDescriptorTypeNode *) representationBase->FramePacking->data;
1336   assert_equals_string (framePacking->schemeIdUri, "TestSchemeIdUri");
1337   assert_equals_string (framePacking->value, "TestValue");
1338
1339   gst_mpd_client2_free (mpdclient);
1340 }
1341
1342 GST_END_TEST;
1343
1344 /*
1345  * Test parsing Period AdaptationSet RepresentationBase
1346  * AudioChannelConfiguration attributes
1347  */
1348 GST_START_TEST
1349     (dash_mpdparser_period_adaptationSet_representationBase_audioChannelConfiguration)
1350 {
1351   GstMPDPeriodNode *periodNode;
1352   GstMPDAdaptationSetNode *adaptationSet;
1353   GstMPDRepresentationBaseNode *representationBase;
1354   GstMPDDescriptorTypeNode *audioChannelConfiguration;
1355   const gchar *xml =
1356       "<?xml version=\"1.0\"?>"
1357       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1358       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1359       "  <Period>"
1360       "    <AdaptationSet>"
1361       "      <AudioChannelConfiguration schemeIdUri=\"TestSchemeIdUri\""
1362       "                                 value=\"TestValue\">"
1363       "      </AudioChannelConfiguration></AdaptationSet></Period></MPD>";
1364
1365   gboolean ret;
1366   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1367
1368   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1369   assert_equals_int (ret, TRUE);
1370
1371   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1372   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1373   representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
1374   audioChannelConfiguration = (GstMPDDescriptorTypeNode *)
1375       representationBase->AudioChannelConfiguration->data;
1376   assert_equals_string (audioChannelConfiguration->schemeIdUri,
1377       "TestSchemeIdUri");
1378   assert_equals_string (audioChannelConfiguration->value, "TestValue");
1379
1380   gst_mpd_client2_free (mpdclient);
1381 }
1382
1383 GST_END_TEST;
1384
1385 /*
1386  * Test parsing Period AdaptationSet RepresentationBase ContentProtection
1387  * attributes
1388  */
1389 GST_START_TEST
1390     (dash_mpdparser_period_adaptationSet_representationBase_contentProtection) {
1391   GstMPDPeriodNode *periodNode;
1392   GstMPDAdaptationSetNode *adaptationSet;
1393   GstMPDRepresentationBaseNode *representationBase;
1394   GstMPDDescriptorTypeNode *contentProtection;
1395   const gchar *xml =
1396       "<?xml version=\"1.0\"?>"
1397       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1398       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1399       "  <Period>"
1400       "    <AdaptationSet>"
1401       "      <ContentProtection schemeIdUri=\"TestSchemeIdUri\""
1402       "                         value=\"TestValue\">"
1403       "      </ContentProtection></AdaptationSet></Period></MPD>";
1404
1405   gboolean ret;
1406   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1407
1408   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1409   assert_equals_int (ret, TRUE);
1410
1411   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1412   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1413   representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
1414   contentProtection =
1415       (GstMPDDescriptorTypeNode *) representationBase->ContentProtection->data;
1416   assert_equals_string (contentProtection->schemeIdUri, "TestSchemeIdUri");
1417   assert_equals_string (contentProtection->value, "TestValue");
1418
1419   gst_mpd_client2_free (mpdclient);
1420 }
1421
1422 GST_END_TEST;
1423
1424 /*
1425  * Test parsing ContentProtection element that has no value attribute
1426  */
1427 GST_START_TEST (dash_mpdparser_contentProtection_no_value)
1428 {
1429   GstMPDPeriodNode *periodNode;
1430   GstMPDAdaptationSetNode *adaptationSet;
1431   GstMPDRepresentationBaseNode *representationBase;
1432   GstMPDDescriptorTypeNode *contentProtection;
1433   const gchar *xml =
1434       "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1435       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1436       "     xmlns:mspr=\"urn:microsoft:playready\""
1437       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1438       "  <Period>"
1439       "    <AdaptationSet>"
1440       "      <ContentProtection schemeIdUri=\"urn:mpeg:dash:mp4protection:2011\" value=\"cenc\"/>"
1441       "      <ContentProtection xmlns:mas=\"urn:marlin:mas:1-0:services:schemas:mpd\" schemeIdUri=\"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4\">"
1442       "       <mas:MarlinContentIds>"
1443       "         <mas:MarlinContentId>urn:marlin:kid:02020202020202020202020202020202</mas:MarlinContentId>"
1444       "       </mas:MarlinContentIds>"
1445       "      </ContentProtection>"
1446       "      <ContentProtection schemeIdUri=\"urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95\" value=\"MSPR 2.0\">"
1447       "        <mspr:pro>dGVzdA==</mspr:pro>"
1448       "     </ContentProtection>" "</AdaptationSet></Period></MPD>";
1449
1450   gboolean ret;
1451   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1452   gchar *str;
1453
1454   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1455   assert_equals_int (ret, TRUE);
1456
1457   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1458   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1459   representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
1460   assert_equals_int (g_list_length (representationBase->ContentProtection), 3);
1461   contentProtection = (GstMPDDescriptorTypeNode *)
1462       g_list_nth (representationBase->ContentProtection, 1)->data;
1463   assert_equals_string (contentProtection->schemeIdUri,
1464       "urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4");
1465   fail_if (contentProtection->value == NULL);
1466   /* We can't do a simple compare of value (which should be an XML dump
1467      of the ContentProtection element), because the whitespace
1468      formatting from xmlDump might differ between versions of libxml */
1469   str = strstr (contentProtection->value, "<ContentProtection");
1470   fail_if (str == NULL);
1471   str = strstr (contentProtection->value, "<mas:MarlinContentIds>");
1472   fail_if (str == NULL);
1473   str = strstr (contentProtection->value, "<mas:MarlinContentId>");
1474   fail_if (str == NULL);
1475   str =
1476       strstr (contentProtection->value,
1477       "urn:marlin:kid:02020202020202020202020202020202");
1478   fail_if (str == NULL);
1479   str = strstr (contentProtection->value, "</ContentProtection>");
1480   fail_if (str == NULL);
1481   gst_mpd_client2_free (mpdclient);
1482 }
1483
1484 GST_END_TEST;
1485
1486 /*
1487  * Test parsing ContentProtection element that has no value attribute
1488  * nor an XML encoding
1489  */
1490 GST_START_TEST (dash_mpdparser_contentProtection_no_value_no_encoding)
1491 {
1492   GstMPDPeriodNode *periodNode;
1493   GstMPDAdaptationSetNode *adaptationSet;
1494   GstMPDRepresentationBaseNode *representationBase;
1495   GstMPDDescriptorTypeNode *contentProtection;
1496   const gchar *xml =
1497       "<?xml version=\"1.0\"?>"
1498       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1499       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1500       "  <Period>"
1501       "    <AdaptationSet>"
1502       "      <ContentProtection schemeIdUri=\"urn:mpeg:dash:mp4protection:2011\" value=\"cenc\"/>"
1503       "      <ContentProtection xmlns:mas=\"urn:marlin:mas:1-0:services:schemas:mpd\" schemeIdUri=\"urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4\">"
1504       "       <mas:MarlinContentIds>"
1505       "         <mas:MarlinContentId>urn:marlin:kid:02020202020202020202020202020202</mas:MarlinContentId>"
1506       "       </mas:MarlinContentIds>"
1507       "     </ContentProtection>" "</AdaptationSet></Period></MPD>";
1508
1509   gboolean ret;
1510   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1511
1512   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1513   assert_equals_int (ret, TRUE);
1514
1515   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1516   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1517   representationBase = GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet);
1518   assert_equals_int (g_list_length (representationBase->ContentProtection), 2);
1519   contentProtection = (GstMPDDescriptorTypeNode *)
1520       g_list_nth (representationBase->ContentProtection, 1)->data;
1521   assert_equals_string (contentProtection->schemeIdUri,
1522       "urn:uuid:5e629af5-38da-4063-8977-97ffbd9902d4");
1523   fail_if (contentProtection->value == NULL);
1524   gst_mpd_client2_free (mpdclient);
1525 }
1526
1527 GST_END_TEST;
1528
1529 /*
1530  * Test parsing Period AdaptationSet Accessibility attributes
1531  *
1532  */
1533 GST_START_TEST (dash_mpdparser_period_adaptationSet_accessibility)
1534 {
1535   GstMPDPeriodNode *periodNode;
1536   GstMPDAdaptationSetNode *adaptationSet;
1537   GstMPDDescriptorTypeNode *accessibility;
1538   const gchar *xml =
1539       "<?xml version=\"1.0\"?>"
1540       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1541       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1542       "  <Period>"
1543       "    <AdaptationSet>"
1544       "      <Accessibility schemeIdUri=\"TestSchemeIdUri\""
1545       "                     value=\"TestValue\">"
1546       "      </Accessibility></AdaptationSet></Period></MPD>";
1547
1548   gboolean ret;
1549   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1550
1551   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1552   assert_equals_int (ret, TRUE);
1553
1554   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1555   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1556   accessibility =
1557       (GstMPDDescriptorTypeNode *) adaptationSet->Accessibility->data;
1558   assert_equals_string (accessibility->schemeIdUri, "TestSchemeIdUri");
1559   assert_equals_string (accessibility->value, "TestValue");
1560
1561   gst_mpd_client2_free (mpdclient);
1562 }
1563
1564 GST_END_TEST;
1565
1566 /*
1567  * Test parsing Period AdaptationSet Role attributes
1568  *
1569  */
1570 GST_START_TEST (dash_mpdparser_period_adaptationSet_role)
1571 {
1572   GstMPDPeriodNode *periodNode;
1573   GstMPDAdaptationSetNode *adaptationSet;
1574   GstMPDDescriptorTypeNode *role;
1575   const gchar *xml =
1576       "<?xml version=\"1.0\"?>"
1577       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1578       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1579       "  <Period>"
1580       "    <AdaptationSet>"
1581       "      <Role schemeIdUri=\"TestSchemeIdUri\""
1582       "            value=\"TestValue\">"
1583       "      </Role></AdaptationSet></Period></MPD>";
1584
1585   gboolean ret;
1586   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1587
1588   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1589   assert_equals_int (ret, TRUE);
1590
1591   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1592   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1593   role = (GstMPDDescriptorTypeNode *) adaptationSet->Role->data;
1594   assert_equals_string (role->schemeIdUri, "TestSchemeIdUri");
1595   assert_equals_string (role->value, "TestValue");
1596
1597   gst_mpd_client2_free (mpdclient);
1598 }
1599
1600 GST_END_TEST;
1601
1602 /*
1603  * Test parsing Period AdaptationSet Rating attributes
1604  *
1605  */
1606 GST_START_TEST (dash_mpdparser_period_adaptationSet_rating)
1607 {
1608   GstMPDPeriodNode *periodNode;
1609   GstMPDAdaptationSetNode *adaptationSet;
1610   GstMPDDescriptorTypeNode *rating;
1611   const gchar *xml =
1612       "<?xml version=\"1.0\"?>"
1613       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1614       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1615       "  <Period>"
1616       "    <AdaptationSet>"
1617       "      <Rating schemeIdUri=\"TestSchemeIdUri\""
1618       "              value=\"TestValue\">"
1619       "      </Rating></AdaptationSet></Period></MPD>";
1620
1621   gboolean ret;
1622   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1623
1624   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1625   assert_equals_int (ret, TRUE);
1626
1627   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1628   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1629   rating = (GstMPDDescriptorTypeNode *) adaptationSet->Rating->data;
1630   assert_equals_string (rating->schemeIdUri, "TestSchemeIdUri");
1631   assert_equals_string (rating->value, "TestValue");
1632
1633   gst_mpd_client2_free (mpdclient);
1634 }
1635
1636 GST_END_TEST;
1637
1638 /*
1639  * Test parsing Period AdaptationSet Viewpoint attributes
1640  *
1641  */
1642 GST_START_TEST (dash_mpdparser_period_adaptationSet_viewpoint)
1643 {
1644   GstMPDPeriodNode *periodNode;
1645   GstMPDAdaptationSetNode *adaptationSet;
1646   GstMPDDescriptorTypeNode *viewpoint;
1647   const gchar *xml =
1648       "<?xml version=\"1.0\"?>"
1649       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1650       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1651       "  <Period>"
1652       "    <AdaptationSet>"
1653       "      <Viewpoint schemeIdUri=\"TestSchemeIdUri\""
1654       "                 value=\"TestValue\">"
1655       "      </Viewpoint></AdaptationSet></Period></MPD>";
1656
1657   gboolean ret;
1658   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1659
1660   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1661   assert_equals_int (ret, TRUE);
1662
1663   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1664   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1665   viewpoint = (GstMPDDescriptorTypeNode *) adaptationSet->Viewpoint->data;
1666   assert_equals_string (viewpoint->schemeIdUri, "TestSchemeIdUri");
1667   assert_equals_string (viewpoint->value, "TestValue");
1668
1669   gst_mpd_client2_free (mpdclient);
1670 }
1671
1672 GST_END_TEST;
1673
1674 /*
1675  * Test parsing Period AdaptationSet ContentComponent attributes
1676  *
1677  */
1678 GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent)
1679 {
1680   GstMPDPeriodNode *periodNode;
1681   GstMPDAdaptationSetNode *adaptationSet;
1682   GstMPDContentComponentNode *contentComponent;
1683   const gchar *xml =
1684       "<?xml version=\"1.0\"?>"
1685       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1686       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1687       "  <Period>"
1688       "    <AdaptationSet>"
1689       "      <ContentComponent id=\"1\""
1690       "                        lang=\"en\""
1691       "                        contentType=\"TestContentType\""
1692       "                        par=\"10:20\">"
1693       "      </ContentComponent></AdaptationSet></Period></MPD>";
1694
1695   gboolean ret;
1696   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1697
1698   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1699   assert_equals_int (ret, TRUE);
1700
1701   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1702   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1703   contentComponent = (GstMPDContentComponentNode *)
1704       adaptationSet->ContentComponents->data;
1705   assert_equals_uint64 (contentComponent->id, 1);
1706   assert_equals_string (contentComponent->lang, "en");
1707   assert_equals_string (contentComponent->contentType, "TestContentType");
1708   assert_equals_uint64 (contentComponent->par->num, 10);
1709   assert_equals_uint64 (contentComponent->par->den, 20);
1710
1711   gst_mpd_client2_free (mpdclient);
1712 }
1713
1714 GST_END_TEST;
1715
1716 /*
1717  * Test parsing Period AdaptationSet ContentComponent Accessibility attributes
1718  *
1719  */
1720 GST_START_TEST
1721     (dash_mpdparser_period_adaptationSet_contentComponent_accessibility) {
1722   GstMPDPeriodNode *periodNode;
1723   GstMPDAdaptationSetNode *adaptationSet;
1724   GstMPDContentComponentNode *contentComponent;
1725   GstMPDDescriptorTypeNode *accessibility;
1726   const gchar *xml =
1727       "<?xml version=\"1.0\"?>"
1728       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1729       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1730       "  <Period>"
1731       "    <AdaptationSet>"
1732       "      <ContentComponent>"
1733       "        <Accessibility schemeIdUri=\"TestSchemeIdUri\""
1734       "                       value=\"TestValue\">"
1735       "        </Accessibility>"
1736       "      </ContentComponent></AdaptationSet></Period></MPD>";
1737
1738   gboolean ret;
1739   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1740
1741   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1742   assert_equals_int (ret, TRUE);
1743
1744   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1745   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1746   contentComponent = (GstMPDContentComponentNode *)
1747       adaptationSet->ContentComponents->data;
1748   accessibility =
1749       (GstMPDDescriptorTypeNode *) contentComponent->Accessibility->data;
1750   assert_equals_string (accessibility->schemeIdUri, "TestSchemeIdUri");
1751   assert_equals_string (accessibility->value, "TestValue");
1752
1753   gst_mpd_client2_free (mpdclient);
1754 }
1755
1756 GST_END_TEST;
1757
1758 /*
1759  * Test parsing Period AdaptationSet ContentComponent Role attributes
1760  *
1761  */
1762 GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_role)
1763 {
1764   GstMPDPeriodNode *periodNode;
1765   GstMPDAdaptationSetNode *adaptationSet;
1766   GstMPDContentComponentNode *contentComponent;
1767   GstMPDDescriptorTypeNode *role;
1768   const gchar *xml =
1769       "<?xml version=\"1.0\"?>"
1770       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1771       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1772       "  <Period>"
1773       "    <AdaptationSet>"
1774       "      <ContentComponent>"
1775       "        <Role schemeIdUri=\"TestSchemeIdUri\""
1776       "              value=\"TestValue\">"
1777       "        </Role></ContentComponent></AdaptationSet></Period></MPD>";
1778
1779   gboolean ret;
1780   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1781
1782   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1783   assert_equals_int (ret, TRUE);
1784
1785   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1786   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1787   contentComponent = (GstMPDContentComponentNode *)
1788       adaptationSet->ContentComponents->data;
1789   role = (GstMPDDescriptorTypeNode *) contentComponent->Role->data;
1790   assert_equals_string (role->schemeIdUri, "TestSchemeIdUri");
1791   assert_equals_string (role->value, "TestValue");
1792
1793   gst_mpd_client2_free (mpdclient);
1794 }
1795
1796 GST_END_TEST;
1797
1798 /*
1799  * Test parsing Period AdaptationSet ContentComponent Rating attributes
1800  *
1801  */
1802 GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_rating)
1803 {
1804   GstMPDPeriodNode *periodNode;
1805   GstMPDAdaptationSetNode *adaptationSet;
1806   GstMPDContentComponentNode *contentComponent;
1807   GstMPDDescriptorTypeNode *rating;
1808   const gchar *xml =
1809       "<?xml version=\"1.0\"?>"
1810       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1811       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1812       "  <Period>"
1813       "    <AdaptationSet>"
1814       "      <ContentComponent>"
1815       "        <Rating schemeIdUri=\"TestSchemeIdUri\""
1816       "                value=\"TestValue\">"
1817       "        </Rating>"
1818       "      </ContentComponent></AdaptationSet></Period></MPD>";
1819
1820   gboolean ret;
1821   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1822
1823   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1824   assert_equals_int (ret, TRUE);
1825
1826   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1827   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1828   contentComponent = (GstMPDContentComponentNode *)
1829       adaptationSet->ContentComponents->data;
1830   rating = (GstMPDDescriptorTypeNode *) contentComponent->Rating->data;
1831   assert_equals_string (rating->schemeIdUri, "TestSchemeIdUri");
1832   assert_equals_string (rating->value, "TestValue");
1833
1834   gst_mpd_client2_free (mpdclient);
1835 }
1836
1837 GST_END_TEST;
1838
1839 /*
1840  * Test parsing Period AdaptationSet ContentComponent Viewpoint attributes
1841  *
1842  */
1843 GST_START_TEST (dash_mpdparser_period_adaptationSet_contentComponent_viewpoint)
1844 {
1845   GstMPDPeriodNode *periodNode;
1846   GstMPDAdaptationSetNode *adaptationSet;
1847   GstMPDContentComponentNode *contentComponent;
1848   GstMPDDescriptorTypeNode *viewpoint;
1849   const gchar *xml =
1850       "<?xml version=\"1.0\"?>"
1851       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1852       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1853       "  <Period>"
1854       "    <AdaptationSet>"
1855       "      <ContentComponent>"
1856       "        <Viewpoint schemeIdUri=\"TestSchemeIdUri\""
1857       "                   value=\"TestValue\">"
1858       "        </Viewpoint>"
1859       "      </ContentComponent></AdaptationSet></Period></MPD>";
1860
1861   gboolean ret;
1862   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1863
1864   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1865   assert_equals_int (ret, TRUE);
1866
1867   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1868   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1869   contentComponent = (GstMPDContentComponentNode *)
1870       adaptationSet->ContentComponents->data;
1871   viewpoint = (GstMPDDescriptorTypeNode *) contentComponent->Viewpoint->data;
1872   assert_equals_string (viewpoint->schemeIdUri, "TestSchemeIdUri");
1873   assert_equals_string (viewpoint->value, "TestValue");
1874
1875   gst_mpd_client2_free (mpdclient);
1876 }
1877
1878 GST_END_TEST;
1879
1880 /*
1881  * Test parsing Period AdaptationSet BaseURL attributes
1882  *
1883  */
1884 GST_START_TEST (dash_mpdparser_period_adaptationSet_baseURL)
1885 {
1886   GstMPDPeriodNode *periodNode;
1887   GstMPDAdaptationSetNode *adaptationSet;
1888   GstMPDBaseURLNode *baseURL;
1889   const gchar *xml =
1890       "<?xml version=\"1.0\"?>"
1891       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1892       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1893       "  <Period>"
1894       "    <AdaptationSet>"
1895       "      <BaseURL serviceLocation=\"TestServiceLocation\""
1896       "               byteRange=\"TestByteRange\">TestBaseURL</BaseURL>"
1897       "    </AdaptationSet></Period></MPD>";
1898
1899   gboolean ret;
1900   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1901
1902   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1903   assert_equals_int (ret, TRUE);
1904
1905   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1906   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1907   baseURL = (GstMPDBaseURLNode *) adaptationSet->BaseURLs->data;
1908   assert_equals_string (baseURL->baseURL, "TestBaseURL");
1909   assert_equals_string (baseURL->serviceLocation, "TestServiceLocation");
1910   assert_equals_string (baseURL->byteRange, "TestByteRange");
1911
1912   gst_mpd_client2_free (mpdclient);
1913 }
1914
1915 GST_END_TEST;
1916
1917 /*
1918  * Test parsing Period AdaptationSet SegmentBase attributes
1919  *
1920  */
1921 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentBase)
1922 {
1923   GstMPDPeriodNode *periodNode;
1924   GstMPDAdaptationSetNode *adaptationSet;
1925   GstMPDSegmentBaseNode *segmentBase;
1926   const gchar *xml =
1927       "<?xml version=\"1.0\"?>"
1928       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1929       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1930       "  <Period>"
1931       "    <AdaptationSet>"
1932       "      <SegmentBase timescale=\"123456\""
1933       "                   presentationTimeOffset=\"123456789\""
1934       "                   indexRange=\"100-200\""
1935       "                   indexRangeExact=\"true\">"
1936       "      </SegmentBase></AdaptationSet></Period></MPD>";
1937
1938   gboolean ret;
1939   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1940
1941   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1942   assert_equals_int (ret, TRUE);
1943
1944   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1945   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1946   segmentBase = adaptationSet->SegmentBase;
1947   assert_equals_uint64 (segmentBase->timescale, 123456);
1948   assert_equals_uint64 (segmentBase->presentationTimeOffset, 123456789);
1949   assert_equals_uint64 (segmentBase->indexRange->first_byte_pos, 100);
1950   assert_equals_uint64 (segmentBase->indexRange->last_byte_pos, 200);
1951   assert_equals_int (segmentBase->indexRangeExact, TRUE);
1952
1953   gst_mpd_client2_free (mpdclient);
1954 }
1955
1956 GST_END_TEST;
1957
1958 /*
1959  * Test parsing Period AdaptationSet SegmentBase Initialization attributes
1960  *
1961  */
1962 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentBase_initialization)
1963 {
1964   GstMPDPeriodNode *periodNode;
1965   GstMPDAdaptationSetNode *adaptationSet;
1966   GstMPDSegmentBaseNode *segmentBase;
1967   GstMPDURLTypeNode *initialization;
1968   const gchar *xml =
1969       "<?xml version=\"1.0\"?>"
1970       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
1971       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
1972       "  <Period>"
1973       "    <AdaptationSet>"
1974       "      <SegmentBase>"
1975       "        <Initialisation sourceURL=\"TestSourceURL\""
1976       "                        range=\"100-200\">"
1977       "        </Initialisation></SegmentBase></AdaptationSet></Period></MPD>";
1978
1979   gboolean ret;
1980   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
1981
1982   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
1983   assert_equals_int (ret, TRUE);
1984
1985   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
1986   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
1987   segmentBase = adaptationSet->SegmentBase;
1988   initialization = segmentBase->Initialization;
1989   assert_equals_string (initialization->sourceURL, "TestSourceURL");
1990   assert_equals_uint64 (initialization->range->first_byte_pos, 100);
1991   assert_equals_uint64 (initialization->range->last_byte_pos, 200);
1992
1993   gst_mpd_client2_free (mpdclient);
1994 }
1995
1996 GST_END_TEST;
1997
1998 /*
1999  * Test parsing Period AdaptationSet SegmentBase RepresentationIndex attributes
2000  *
2001  */
2002 GST_START_TEST
2003     (dash_mpdparser_period_adaptationSet_segmentBase_representationIndex) {
2004   GstMPDPeriodNode *periodNode;
2005   GstMPDAdaptationSetNode *adaptationSet;
2006   GstMPDSegmentBaseNode *segmentBase;
2007   GstMPDURLTypeNode *representationIndex;
2008   const gchar *xml =
2009       "<?xml version=\"1.0\"?>"
2010       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2011       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2012       "  <Period>"
2013       "    <AdaptationSet>"
2014       "      <SegmentBase>"
2015       "        <RepresentationIndex sourceURL=\"TestSourceURL\""
2016       "                             range=\"100-200\">"
2017       "        </RepresentationIndex>"
2018       "      </SegmentBase></AdaptationSet></Period></MPD>";
2019
2020   gboolean ret;
2021   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2022
2023   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2024   assert_equals_int (ret, TRUE);
2025
2026   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2027   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2028   segmentBase = adaptationSet->SegmentBase;
2029   representationIndex = segmentBase->RepresentationIndex;
2030   assert_equals_string (representationIndex->sourceURL, "TestSourceURL");
2031   assert_equals_uint64 (representationIndex->range->first_byte_pos, 100);
2032   assert_equals_uint64 (representationIndex->range->last_byte_pos, 200);
2033
2034   gst_mpd_client2_free (mpdclient);
2035 }
2036
2037 GST_END_TEST;
2038
2039 /*
2040  * Test parsing Period AdaptationSet SegmentList attributes
2041  *
2042  */
2043 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentList)
2044 {
2045   GstMPDPeriodNode *periodNode;
2046   GstMPDAdaptationSetNode *adaptationSet;
2047   GstMPDSegmentListNode *segmentList;
2048   const gchar *xml =
2049       "<?xml version=\"1.0\"?>"
2050       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2051       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2052       "  <Period>"
2053       "    <AdaptationSet>"
2054       "      <SegmentList duration=\"1\"></SegmentList></AdaptationSet></Period></MPD>";
2055
2056   gboolean ret;
2057   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2058
2059   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2060   assert_equals_int (ret, TRUE);
2061
2062   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2063   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2064   segmentList = adaptationSet->SegmentList;
2065   fail_if (segmentList == NULL);
2066
2067   gst_mpd_client2_free (mpdclient);
2068 }
2069
2070 GST_END_TEST;
2071
2072 /*
2073  * Test parsing Period AdaptationSet SegmentTemplate attributes
2074  *
2075  */
2076 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentTemplate)
2077 {
2078   GstMPDPeriodNode *periodNode;
2079   GstMPDAdaptationSetNode *adaptationSet;
2080   GstMPDSegmentTemplateNode *segmentTemplate;
2081   const gchar *xml =
2082       "<?xml version=\"1.0\"?>"
2083       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2084       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2085       "  <Period>"
2086       "    <AdaptationSet>"
2087       "      <SegmentTemplate media=\"TestMedia\""
2088       "                       duration=\"1\""
2089       "                       index=\"TestIndex\""
2090       "                       initialization=\"TestInitialization\""
2091       "                       bitstreamSwitching=\"TestBitstreamSwitching\">"
2092       "      </SegmentTemplate></AdaptationSet></Period></MPD>";
2093
2094   gboolean ret;
2095   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2096
2097   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2098   assert_equals_int (ret, TRUE);
2099
2100   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2101   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2102   segmentTemplate = adaptationSet->SegmentTemplate;
2103   assert_equals_string (segmentTemplate->media, "TestMedia");
2104   assert_equals_string (segmentTemplate->index, "TestIndex");
2105   assert_equals_string (segmentTemplate->initialization, "TestInitialization");
2106   assert_equals_string (segmentTemplate->bitstreamSwitching,
2107       "TestBitstreamSwitching");
2108
2109   gst_mpd_client2_free (mpdclient);
2110 }
2111
2112 GST_END_TEST;
2113
2114
2115 GST_START_TEST
2116     (dash_mpdparser_period_adaptationSet_representation_segmentTemplate_inherit)
2117 {
2118   GstMPDPeriodNode *periodNode;
2119   GstMPDAdaptationSetNode *adaptationSet;
2120   GstMPDRepresentationNode *representation;
2121   GstMPDSegmentTemplateNode *segmentTemplate;
2122   const gchar *xml =
2123       "<?xml version=\"1.0\"?>"
2124       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2125       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2126       "  <Period>"
2127       "    <SegmentTemplate media=\"ParentMedia\" duration=\"1\" "
2128       "                     initialization=\"ParentInitialization\">"
2129       "    </SegmentTemplate>"
2130       "    <AdaptationSet>"
2131       "      <Representation id=\"1\" bandwidth=\"5000\">"
2132       "      <SegmentTemplate media=\"TestMedia\""
2133       "                       index=\"TestIndex\""
2134       "                       bitstreamSwitching=\"TestBitstreamSwitching\">"
2135       "      </SegmentTemplate></Representation></AdaptationSet></Period></MPD>";
2136
2137   gboolean ret;
2138   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2139
2140   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2141   assert_equals_int (ret, TRUE);
2142
2143   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2144   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2145   representation =
2146       (GstMPDRepresentationNode *) adaptationSet->Representations->data;
2147   segmentTemplate = representation->SegmentTemplate;
2148   assert_equals_string (segmentTemplate->media, "TestMedia");
2149   assert_equals_string (segmentTemplate->index, "TestIndex");
2150   assert_equals_string (segmentTemplate->initialization,
2151       "ParentInitialization");
2152   assert_equals_string (segmentTemplate->bitstreamSwitching,
2153       "TestBitstreamSwitching");
2154
2155   gst_mpd_client2_free (mpdclient);
2156 }
2157
2158 GST_END_TEST;
2159
2160 GST_START_TEST
2161     (dash_mpdparser_period_adaptationSet_representation_segmentBase_inherit) {
2162   GstMPDPeriodNode *periodNode;
2163   GstMPDAdaptationSetNode *adaptationSet;
2164   GstMPDRepresentationNode *representation;
2165   GstMPDSegmentBaseNode *segmentBase;
2166   const gchar *xml =
2167       "<?xml version=\"1.0\"?>"
2168       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2169       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2170       "  <Period>"
2171       "    <SegmentBase timescale=\"123456\""
2172       "                 presentationTimeOffset=\"123456789\""
2173       "                 indexRange=\"100-200\""
2174       "                 indexRangeExact=\"true\">"
2175       "      <Initialisation sourceURL=\"TestSourceURL\""
2176       "                      range=\"100-200\" />"
2177       "    </SegmentBase>"
2178       "    <AdaptationSet>"
2179       "      <Representation id=\"1\" bandwidth=\"5000\">"
2180       "      <SegmentBase>"
2181       "      </SegmentBase></Representation></AdaptationSet></Period></MPD>";
2182
2183   gboolean ret;
2184   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2185
2186   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2187   assert_equals_int (ret, TRUE);
2188
2189   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2190   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2191   representation =
2192       (GstMPDRepresentationNode *) adaptationSet->Representations->data;
2193   segmentBase = representation->SegmentBase;
2194   assert_equals_int (segmentBase->timescale, 123456);
2195
2196   gst_mpd_client2_free (mpdclient);
2197 }
2198
2199 GST_END_TEST;
2200
2201 /*
2202  * Test parsing Period AdaptationSet SegmentTemplate attributes with
2203  * inheritance
2204  */
2205 GST_START_TEST (dash_mpdparser_adapt_repr_segmentTemplate_inherit)
2206 {
2207   GstMPDPeriodNode *periodNode;
2208   GstMPDAdaptationSetNode *adaptationSet;
2209   GstMPDSegmentTemplateNode *segmentTemplate;
2210   GstMPDRepresentationNode *representation;
2211   GstMPDSegmentBaseNode *segmentBase;
2212   const gchar *xml =
2213       "<?xml version=\"1.0\"?>"
2214       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2215       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2216       "  <Period duration=\"PT0H5M0.000S\">"
2217       "    <AdaptationSet maxWidth=\"1280\" maxHeight=\"720\" maxFrameRate=\"50\">"
2218       "      <SegmentTemplate initialization=\"set1_init.mp4\"/>"
2219       "      <Representation id=\"1\" mimeType=\"video/mp4\" codecs=\"avc1.640020\" "
2220       "          width=\"1280\" height=\"720\" frameRate=\"50\" bandwidth=\"30000\">"
2221       "        <SegmentTemplate timescale=\"12800\" media=\"track1_$Number$.m4s\" startNumber=\"1\" duration=\"25600\"/>"
2222       "  </Representation></AdaptationSet></Period></MPD>";
2223
2224   gboolean ret;
2225   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2226
2227   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2228   assert_equals_int (ret, TRUE);
2229
2230   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2231   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2232   representation = (GstMPDRepresentationNode *)
2233       adaptationSet->Representations->data;
2234   segmentTemplate = representation->SegmentTemplate;
2235   fail_if (segmentTemplate == NULL);
2236   segmentBase = GST_MPD_MULT_SEGMENT_BASE_NODE (segmentTemplate)->SegmentBase;
2237
2238   assert_equals_uint64 (segmentBase->timescale, 12800);
2239   assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
2240       (segmentTemplate)->duration, 25600);
2241   assert_equals_uint64 (GST_MPD_MULT_SEGMENT_BASE_NODE
2242       (segmentTemplate)->startNumber, 1);
2243   assert_equals_string (segmentTemplate->media, "track1_$Number$.m4s");
2244   assert_equals_string (segmentTemplate->initialization, "set1_init.mp4");
2245
2246   gst_mpd_client2_free (mpdclient);
2247 }
2248
2249 GST_END_TEST;
2250 /*
2251  * Test parsing Period AdaptationSet SegmentTemplate attributes with
2252  * inheritance
2253  */
2254 GST_START_TEST (dash_mpdparser_period_adaptationSet_segmentTemplate_inherit)
2255 {
2256   GstMPDPeriodNode *periodNode;
2257   GstMPDAdaptationSetNode *adaptationSet;
2258   GstMPDSegmentTemplateNode *segmentTemplate;
2259   const gchar *xml =
2260       "<?xml version=\"1.0\"?>"
2261       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2262       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2263       "  <Period>"
2264       "    <SegmentTemplate media=\"ParentMedia\" duration=\"1\" "
2265       "                     initialization=\"ParentInitialization\">"
2266       "    </SegmentTemplate>"
2267       "    <AdaptationSet>"
2268       "      <SegmentTemplate media=\"TestMedia\""
2269       "                       duration=\"1\""
2270       "                       index=\"TestIndex\""
2271       "                       bitstreamSwitching=\"TestBitstreamSwitching\">"
2272       "      </SegmentTemplate></AdaptationSet></Period></MPD>";
2273
2274   gboolean ret;
2275   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2276
2277   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2278   assert_equals_int (ret, TRUE);
2279
2280   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2281   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2282   segmentTemplate = adaptationSet->SegmentTemplate;
2283   assert_equals_string (segmentTemplate->media, "TestMedia");
2284   assert_equals_string (segmentTemplate->index, "TestIndex");
2285   assert_equals_string (segmentTemplate->initialization,
2286       "ParentInitialization");
2287   assert_equals_string (segmentTemplate->bitstreamSwitching,
2288       "TestBitstreamSwitching");
2289
2290   gst_mpd_client2_free (mpdclient);
2291 }
2292
2293 GST_END_TEST;
2294
2295 /*
2296  * Test parsing Period AdaptationSet Representation attributes
2297  *
2298  */
2299 GST_START_TEST (dash_mpdparser_period_adaptationSet_representation)
2300 {
2301   GstMPDPeriodNode *periodNode;
2302   GstMPDAdaptationSetNode *adaptationSet;
2303   GstMPDRepresentationNode *representation;
2304   const gchar *xml =
2305       "<?xml version=\"1.0\"?>"
2306       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2307       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2308       "  <Period>"
2309       "    <AdaptationSet>"
2310       "      <Representation id=\"Test_Id\""
2311       "                      bandwidth=\"100\""
2312       "                      qualityRanking=\"200\""
2313       "                      dependencyId=\"one two three\""
2314       "                      mediaStreamStructureId=\"\">"
2315       "      </Representation></AdaptationSet></Period></MPD>";
2316
2317   gboolean ret;
2318   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2319
2320   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2321   assert_equals_int (ret, TRUE);
2322
2323   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2324   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2325   representation = (GstMPDRepresentationNode *)
2326       adaptationSet->Representations->data;
2327   assert_equals_string (representation->id, "Test_Id");
2328   assert_equals_uint64 (representation->bandwidth, 100);
2329   assert_equals_uint64 (representation->qualityRanking, 200);
2330   assert_equals_string (representation->dependencyId[0], "one");
2331   assert_equals_string (representation->dependencyId[1], "two");
2332   assert_equals_string (representation->dependencyId[2], "three");
2333   assert_equals_pointer (representation->dependencyId[3], NULL);
2334   assert_equals_pointer (representation->mediaStreamStructureId[0], NULL);
2335
2336   gst_mpd_client2_free (mpdclient);
2337 }
2338
2339 GST_END_TEST;
2340
2341 /*
2342  * Test parsing Period AdaptationSet Representation RepresentationBaseType attributes
2343  *
2344  */
2345 GST_START_TEST
2346     (dash_mpdparser_period_adaptationSet_representation_representationBase) {
2347   GstMPDPeriodNode *periodNode;
2348   GstMPDAdaptationSetNode *adaptationSet;
2349   GstMPDRepresentationNode *representation;
2350
2351   const gchar *xml =
2352       "<?xml version=\"1.0\"?>"
2353       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2354       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2355       "  <Period>"
2356       "    <AdaptationSet>"
2357       "      <Representation id=\"1\" bandwidth=\"250000\">"
2358       "      </Representation></AdaptationSet></Period></MPD>";
2359
2360   gboolean ret;
2361   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2362
2363   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2364   assert_equals_int (ret, TRUE);
2365
2366   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2367   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2368   representation = (GstMPDRepresentationNode *)
2369       adaptationSet->Representations->data;
2370
2371   fail_if (representation == NULL);
2372
2373   gst_mpd_client2_free (mpdclient);
2374 }
2375
2376 GST_END_TEST;
2377
2378 /*
2379  * Test parsing Period AdaptationSet Representation BaseURL attributes
2380  *
2381  */
2382 GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_baseURL)
2383 {
2384   GstMPDPeriodNode *periodNode;
2385   GstMPDAdaptationSetNode *adaptationSet;
2386   GstMPDRepresentationNode *representation;
2387   GstMPDBaseURLNode *baseURL;
2388   const gchar *xml =
2389       "<?xml version=\"1.0\"?>"
2390       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2391       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2392       "  <Period>"
2393       "    <AdaptationSet>"
2394       "      <Representation id=\"1\" bandwidth=\"250000\">"
2395       "        <BaseURL serviceLocation=\"TestServiceLocation\""
2396       "                 byteRange=\"TestByteRange\">TestBaseURL</BaseURL>"
2397       "      </Representation></AdaptationSet></Period></MPD>";
2398
2399   gboolean ret;
2400   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2401
2402   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2403   assert_equals_int (ret, TRUE);
2404
2405   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2406   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2407   representation = (GstMPDRepresentationNode *)
2408       adaptationSet->Representations->data;
2409   baseURL = (GstMPDBaseURLNode *) representation->BaseURLs->data;
2410   assert_equals_string (baseURL->baseURL, "TestBaseURL");
2411   assert_equals_string (baseURL->serviceLocation, "TestServiceLocation");
2412   assert_equals_string (baseURL->byteRange, "TestByteRange");
2413
2414   gst_mpd_client2_free (mpdclient);
2415 }
2416
2417 GST_END_TEST;
2418
2419 /*
2420  * Test parsing Period AdaptationSet Representation SubRepresentation attributes
2421  *
2422  */
2423 GST_START_TEST
2424     (dash_mpdparser_period_adaptationSet_representation_subRepresentation) {
2425   GstMPDPeriodNode *periodNode;
2426   GstMPDAdaptationSetNode *adaptationSet;
2427   GstMPDRepresentationNode *representation;
2428   GstMPDSubRepresentationNode *subRepresentation;
2429   const gchar *xml =
2430       "<?xml version=\"1.0\"?>"
2431       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2432       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2433       "  <Period>"
2434       "    <AdaptationSet>"
2435       "      <Representation id=\"1\" bandwidth=\"250000\">"
2436       "        <SubRepresentation level=\"100\""
2437       "                           dependencyLevel=\"1 2 3\""
2438       "                           bandwidth=\"200\""
2439       "                           contentComponent=\"content1 content2\">"
2440       "        </SubRepresentation>"
2441       "      </Representation></AdaptationSet></Period></MPD>";
2442
2443   gboolean ret;
2444   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2445
2446   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2447   assert_equals_int (ret, TRUE);
2448
2449   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2450   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2451   representation = (GstMPDRepresentationNode *)
2452       adaptationSet->Representations->data;
2453   subRepresentation = (GstMPDSubRepresentationNode *)
2454       representation->SubRepresentations->data;
2455   assert_equals_uint64 (subRepresentation->level, 100);
2456   assert_equals_uint64 (subRepresentation->dependencyLevel_size, 3);
2457   assert_equals_uint64 (subRepresentation->dependencyLevel[0], 1);
2458   assert_equals_uint64 (subRepresentation->dependencyLevel[1], 2);
2459   assert_equals_uint64 (subRepresentation->dependencyLevel[2], 3);
2460   assert_equals_uint64 (subRepresentation->bandwidth, 200);
2461   assert_equals_string (subRepresentation->contentComponent[0], "content1");
2462   assert_equals_string (subRepresentation->contentComponent[1], "content2");
2463   assert_equals_pointer (subRepresentation->contentComponent[2], NULL);
2464
2465   gst_mpd_client2_free (mpdclient);
2466 }
2467
2468 GST_END_TEST;
2469
2470 /*
2471  * Test parsing Period AdaptationSet Representation SubRepresentation
2472  * RepresentationBase attributes
2473  */
2474 GST_START_TEST
2475     (dash_mpdparser_period_adaptationSet_representation_subRepresentation_representationBase)
2476 {
2477   GstMPDPeriodNode *periodNode;
2478   GstMPDAdaptationSetNode *adaptationSet;
2479   GstMPDRepresentationNode *representation;
2480   GstMPDSubRepresentationNode *subRepresentation;
2481
2482   const gchar *xml =
2483       "<?xml version=\"1.0\"?>"
2484       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2485       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2486       "  <Period>"
2487       "    <AdaptationSet>"
2488       "      <Representation id=\"1\" bandwidth=\"250000\">"
2489       "        <SubRepresentation>"
2490       "        </SubRepresentation>"
2491       "      </Representation></AdaptationSet></Period></MPD>";
2492
2493   gboolean ret;
2494   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2495
2496   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2497   assert_equals_int (ret, TRUE);
2498
2499   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2500   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2501   representation = (GstMPDRepresentationNode *)
2502       adaptationSet->Representations->data;
2503   subRepresentation = (GstMPDSubRepresentationNode *)
2504       representation->SubRepresentations->data;
2505
2506   fail_if (subRepresentation == NULL);
2507
2508   gst_mpd_client2_free (mpdclient);
2509 }
2510
2511 GST_END_TEST;
2512
2513 /*
2514  * Test parsing Period AdaptationSet Representation SegmentBase attributes
2515  *
2516  */
2517 GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_segmentBase)
2518 {
2519   GstMPDPeriodNode *periodNode;
2520   GstMPDAdaptationSetNode *adaptationSet;
2521   GstMPDRepresentationNode *representation;
2522   GstMPDSegmentBaseNode *segmentBase;
2523   const gchar *xml =
2524       "<?xml version=\"1.0\"?>"
2525       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2526       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2527       "  <Period>"
2528       "    <AdaptationSet>"
2529       "      <Representation id=\"1\" bandwidth=\"250000\">"
2530       "        <SegmentBase>"
2531       "        </SegmentBase>"
2532       "      </Representation></AdaptationSet></Period></MPD>";
2533
2534   gboolean ret;
2535   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2536
2537   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2538   assert_equals_int (ret, TRUE);
2539
2540   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2541   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2542   representation = (GstMPDRepresentationNode *)
2543       adaptationSet->Representations->data;
2544   segmentBase = representation->SegmentBase;
2545   fail_if (segmentBase == NULL);
2546
2547   gst_mpd_client2_free (mpdclient);
2548 }
2549
2550 GST_END_TEST;
2551
2552 /*
2553  * Test parsing Period AdaptationSet Representation SegmentList attributes
2554  *
2555  */
2556 GST_START_TEST (dash_mpdparser_period_adaptationSet_representation_segmentList)
2557 {
2558   GstMPDPeriodNode *periodNode;
2559   GstMPDAdaptationSetNode *adaptationSet;
2560   GstMPDRepresentationNode *representation;
2561   GstMPDSegmentListNode *segmentList;
2562   const gchar *xml =
2563       "<?xml version=\"1.0\"?>"
2564       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2565       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2566       "  <Period>"
2567       "    <AdaptationSet>"
2568       "      <Representation id=\"1\" bandwidth=\"250000\">"
2569       "        <SegmentList duration=\"1\">"
2570       "        </SegmentList>"
2571       "      </Representation></AdaptationSet></Period></MPD>";
2572
2573   gboolean ret;
2574   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2575
2576   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2577   assert_equals_int (ret, TRUE);
2578
2579   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2580   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2581   representation = (GstMPDRepresentationNode *)
2582       adaptationSet->Representations->data;
2583   segmentList = representation->SegmentList;
2584   fail_if (segmentList == NULL);
2585
2586   gst_mpd_client2_free (mpdclient);
2587 }
2588
2589 GST_END_TEST;
2590
2591 /*
2592  * Test parsing Period AdaptationSet Representation SegmentTemplate attributes
2593  *
2594  */
2595 GST_START_TEST
2596     (dash_mpdparser_period_adaptationSet_representation_segmentTemplate) {
2597   GstMPDPeriodNode *periodNode;
2598   GstMPDAdaptationSetNode *adaptationSet;
2599   GstMPDRepresentationNode *representation;
2600   GstMPDSegmentTemplateNode *segmentTemplate;
2601   const gchar *xml =
2602       "<?xml version=\"1.0\"?>"
2603       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2604       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2605       "  <Period>"
2606       "    <AdaptationSet>"
2607       "      <Representation id=\"1\" bandwidth=\"250000\">"
2608       "        <SegmentTemplate duration=\"1\">"
2609       "        </SegmentTemplate>"
2610       "      </Representation></AdaptationSet></Period></MPD>";
2611
2612   gboolean ret;
2613   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2614
2615   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2616   assert_equals_int (ret, TRUE);
2617
2618   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2619   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
2620   representation = (GstMPDRepresentationNode *)
2621       adaptationSet->Representations->data;
2622   segmentTemplate = representation->SegmentTemplate;
2623   fail_if (segmentTemplate == NULL);
2624
2625   gst_mpd_client2_free (mpdclient);
2626 }
2627
2628 GST_END_TEST;
2629
2630 /*
2631  * Test parsing Period Subset attributes
2632  *
2633  */
2634 GST_START_TEST (dash_mpdparser_period_subset)
2635 {
2636   GstMPDPeriodNode *periodNode;
2637   GstMPDSubsetNode *subset;
2638   const gchar *xml =
2639       "<?xml version=\"1.0\"?>"
2640       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2641       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2642       "  <Period><Subset contains=\"1 2 3\"></Subset></Period></MPD>";
2643
2644   gboolean ret;
2645   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2646
2647   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2648   assert_equals_int (ret, TRUE);
2649
2650   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
2651   subset = (GstMPDSubsetNode *) periodNode->Subsets->data;
2652   assert_equals_uint64 (subset->contains_size, 3);
2653   assert_equals_uint64 (subset->contains[0], 1);
2654   assert_equals_uint64 (subset->contains[1], 2);
2655   assert_equals_uint64 (subset->contains[2], 3);
2656
2657   gst_mpd_client2_free (mpdclient);
2658 }
2659
2660 GST_END_TEST;
2661
2662 /*
2663  * Test parsing UTCTiming elements
2664  *
2665  */
2666 GST_START_TEST (dash_mpdparser_utctiming)
2667 {
2668   const gchar *xml =
2669       "<?xml version=\"1.0\"?>"
2670       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2671       " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2672       "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:http-xsdate:2014\" value=\"http://time.akamai.com/?iso http://example.time/xsdate\"/>"
2673       "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:direct:2014\" value=\"2002-05-30T09:30:10Z \"/>"
2674       "<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\"/>"
2675       "</MPD>";
2676   gboolean ret;
2677   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2678   GstMPDUTCTimingType selected_method;
2679   gchar **urls;
2680
2681   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2682
2683   assert_equals_int (ret, TRUE);
2684   fail_if (mpdclient->mpd_root_node == NULL);
2685   fail_if (mpdclient->mpd_root_node->UTCTimings == NULL);
2686   assert_equals_int (g_list_length (mpdclient->mpd_root_node->UTCTimings), 3);
2687   urls =
2688       gst_mpd_client2_get_utc_timing_sources (mpdclient,
2689       GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE, &selected_method);
2690   fail_if (urls == NULL);
2691   assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE);
2692   assert_equals_int (g_strv_length (urls), 2);
2693   assert_equals_string (urls[0], "http://time.akamai.com/?iso");
2694   assert_equals_string (urls[1], "http://example.time/xsdate");
2695   urls =
2696       gst_mpd_client2_get_utc_timing_sources (mpdclient,
2697       GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE | GST_MPD_UTCTIMING_TYPE_HTTP_ISO,
2698       &selected_method);
2699   fail_if (urls == NULL);
2700   assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE);
2701   urls =
2702       gst_mpd_client2_get_utc_timing_sources (mpdclient,
2703       GST_MPD_UTCTIMING_TYPE_DIRECT, NULL);
2704   fail_if (urls == NULL);
2705   assert_equals_int (g_strv_length (urls), 1);
2706   assert_equals_string (urls[0], "2002-05-30T09:30:10Z ");
2707   urls =
2708       gst_mpd_client2_get_utc_timing_sources (mpdclient,
2709       GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE | GST_MPD_UTCTIMING_TYPE_DIRECT,
2710       &selected_method);
2711   fail_if (urls == NULL);
2712   assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE);
2713   urls =
2714       gst_mpd_client2_get_utc_timing_sources (mpdclient,
2715       GST_MPD_UTCTIMING_TYPE_NTP, &selected_method);
2716   fail_if (urls == NULL);
2717   assert_equals_int (selected_method, GST_MPD_UTCTIMING_TYPE_NTP);
2718   assert_equals_int (g_strv_length (urls), 4);
2719   assert_equals_string (urls[0], "0.europe.pool.ntp.org");
2720   assert_equals_string (urls[1], "1.europe.pool.ntp.org");
2721   assert_equals_string (urls[2], "2.europe.pool.ntp.org");
2722   assert_equals_string (urls[3], "3.europe.pool.ntp.org");
2723   gst_mpd_client2_free (mpdclient);
2724 }
2725
2726 GST_END_TEST;
2727
2728 /*
2729  * Test parsing invalid UTCTiming values:
2730  * - elements with no schemeIdUri property should be rejected
2731  * - elements with no value property should be rejected
2732  * - elements with unrecognised UTCTiming scheme should be rejected
2733  * - elements with empty values should be rejected
2734  *
2735  */
2736 GST_START_TEST (dash_mpdparser_utctiming_invalid_value)
2737 {
2738   const gchar *xml =
2739       "<?xml version=\"1.0\"?>"
2740       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2741       " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2742       "<UTCTiming invalid_schemeIdUri=\"dummy.uri.scheme\" value=\"dummy value\"/>"
2743       "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:ntp:2014\" invalid_value=\"dummy value\"/>"
2744       "<UTCTiming schemeIdUri=\"dummy.uri.scheme\" value=\"dummy value\"/>"
2745       "<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:ntp:2014\" value=\"\"/>"
2746       "</MPD>";
2747   gboolean ret;
2748   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2749
2750   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2751
2752   assert_equals_int (ret, TRUE);
2753   fail_if (mpdclient->mpd_root_node == NULL);
2754   fail_if (mpdclient->mpd_root_node->UTCTimings != NULL);
2755   gst_mpd_client2_free (mpdclient);
2756 }
2757
2758 GST_END_TEST;
2759
2760 /*
2761  * Test parsing the type property: value "dynamic"
2762  *
2763  */
2764 GST_START_TEST (dash_mpdparser_type_dynamic)
2765 {
2766   gboolean isLive;
2767
2768   const gchar *xml =
2769       "<?xml version=\"1.0\"?>"
2770       "<MPD type=\"dynamic\" xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2771       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"> </MPD>";
2772
2773   gboolean ret;
2774   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2775
2776   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2777   assert_equals_int (ret, TRUE);
2778
2779   isLive = gst_mpd_client2_is_live (mpdclient);
2780   assert_equals_int (isLive, 1);
2781
2782   gst_mpd_client2_free (mpdclient);
2783 }
2784
2785 GST_END_TEST;
2786
2787 /*
2788  * Validate gst_mpdparser_build_URL_from_template function
2789  *
2790  */
2791 GST_START_TEST (dash_mpdparser_template_parsing)
2792 {
2793   const gchar *id = "TestId";
2794   guint number = 7;
2795   guint bandwidth = 2500;
2796   guint64 time = 100;
2797   gchar *result;
2798
2799   struct TestUrl
2800   {
2801     const gchar *urlTemplate;
2802     const gchar *expectedResponse;
2803   };
2804
2805   /* various test scenarios to attempt */
2806   struct TestUrl testUrl[] = {
2807     {"", NULL},                 /* empty string for template */
2808     {"$$", "$"},                /* escaped $ */
2809     {"Number", "Number"},       /* string similar with an identifier, but without $ */
2810     {"Number$Number$", "Number7"},      /* Number identifier */
2811     {"Number$Number$$$", "Number7$"},   /* Number identifier followed by $$ */
2812     {"Number$Number$Number$Number$", "Number7Number7"}, /* series of "Number" string and Number identifier */
2813     {"Representation$RepresentationID$", "RepresentationTestId"},       /* RepresentationID identifier */
2814     {"TestMedia$Bandwidth$$$test", "TestMedia2500$test"},       /* Bandwidth identifier */
2815     {"TestMedia$Time$", "TestMedia100"},        /* Time identifier */
2816     {"TestMedia$Time", NULL},   /* Identifier not finished with $ */
2817     {"Time$Time%d$", NULL},     /* usage of %d (no width) */
2818     {"Time$Time%0d$", "Time100"},       /* usage of format smaller than number of digits */
2819     {"Time$Time%01d$", "Time100"},      /* usage of format smaller than number of digits */
2820     {"Time$Time%05d$", "Time00100"},    /* usage of format bigger than number of digits */
2821     {"Time$Time%05dtest$", "Time00100test"},    /* usage extra text in format */
2822     {"Time$Time%3d$", NULL},    /* incorrect format: width does not start with 0 */
2823     {"Time$Time%0-4d$", NULL},  /* incorrect format: width is not a number */
2824     {"Time$Time%0$", NULL},     /* incorrect format: no d, x or u */
2825     {"Time$Time1%01d$", NULL},  /* incorrect format: does not start with % after identifier */
2826     {"$Bandwidth%/init.mp4v", NULL},    /* incorrect identifier: not finished with $ */
2827     {"$Number%/$Time$.mp4v", NULL},     /* incorrect number of $ separators */
2828     {"$RepresentationID1$", NULL},      /* incorrect identifier */
2829     {"$Bandwidth1$", NULL},     /* incorrect identifier */
2830     {"$Number1$", NULL},        /* incorrect identifier */
2831     {"$RepresentationID%01d$", NULL},   /* incorrect format: RepresentationID does not support formatting */
2832     {"Time$Time%05u$", NULL},   /* %u format */
2833     {"Time$Time%05x$", NULL},   /* %x format */
2834     {"Time$Time%05utest$", NULL},       /* %u format followed by text */
2835     {"Time$Time%05xtest$", NULL},       /* %x format followed by text */
2836     {"Time$Time%05xtest%$", NULL},      /* second % character in format */
2837   };
2838
2839   guint count = sizeof (testUrl) / sizeof (testUrl[0]);
2840   gint i;
2841
2842   for (i = 0; i < count; i++) {
2843     result =
2844         gst_mpdparser_build_URL_from_template (testUrl[i].urlTemplate, id,
2845         number, bandwidth, time);
2846     assert_equals_string (result, testUrl[i].expectedResponse);
2847     g_free (result);
2848   }
2849 }
2850
2851 GST_END_TEST;
2852
2853 /*
2854  * Test handling isoff ondemand profile
2855  *
2856  */
2857 GST_START_TEST (dash_mpdparser_isoff_ondemand_profile)
2858 {
2859   gboolean hasOnDemandProfile;
2860
2861   const gchar *xml =
2862       "<?xml version=\"1.0\"?>"
2863       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2864       "     profiles=\"urn:mpeg:dash:profile:isoff-on-demand:2011\"></MPD>";
2865
2866   gboolean ret;
2867   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2868
2869   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2870   assert_equals_int (ret, TRUE);
2871
2872   hasOnDemandProfile = gst_mpd_client2_has_isoff_ondemand_profile (mpdclient);
2873   assert_equals_int (hasOnDemandProfile, 1);
2874
2875   gst_mpd_client2_free (mpdclient);
2876 }
2877
2878 GST_END_TEST;
2879
2880 /*
2881  * Test handling GstDateTime
2882  *
2883  */
2884 GST_START_TEST (dash_mpdparser_GstDateTime)
2885 {
2886   gint64 delta;
2887   GstDateTime *time1;
2888   GstDateTime *time2;
2889   GstDateTime *time3;
2890   GDateTime *g_time2;
2891   GDateTime *g_time3;
2892
2893   time1 = gst_date_time_new_from_iso8601_string ("2012-06-23T23:30:59Z");
2894   time2 = gst_date_time_new_from_iso8601_string ("2012-06-23T23:31:00Z");
2895
2896   delta = gst_mpd_client2_calculate_time_difference (time1, time2);
2897   assert_equals_int64 (delta, 1 * GST_SECOND);
2898
2899   time3 = gst_mpd_client2_add_time_difference (time1, delta);
2900
2901   /* convert to GDateTime in order to compare time2 and time 3 */
2902   g_time2 = gst_date_time_to_g_date_time (time2);
2903   g_time3 = gst_date_time_to_g_date_time (time3);
2904   fail_if (g_date_time_compare (g_time2, g_time3) != 0);
2905
2906   gst_date_time_unref (time1);
2907   gst_date_time_unref (time2);
2908   gst_date_time_unref (time3);
2909   g_date_time_unref (g_time2);
2910   g_date_time_unref (g_time3);
2911 }
2912
2913 GST_END_TEST;
2914
2915 /*
2916  * Test bitstreamSwitching inheritance from Period to AdaptationSet
2917  *
2918  * Description of bistreamSwitching attribute in Period:
2919  * "When set to â€˜true’, this is equivalent as if the
2920  * AdaptationSet@bitstreamSwitching for each Adaptation Set contained in this
2921  * Period is set to 'true'. In this case, the AdaptationSet@bitstreamSwitching
2922  * attribute shall not be set to 'false' for any Adaptation Set in this Period"
2923  *
2924  */
2925 GST_START_TEST (dash_mpdparser_bitstreamSwitching_inheritance)
2926 {
2927   GList *adaptationSets;
2928   GstMPDAdaptationSetNode *adapt_set;
2929   guint activeStreams;
2930   GstActiveStream *activeStream;
2931   GstCaps *caps;
2932   GstStructure *s;
2933   gboolean bitstreamSwitchingFlag;
2934
2935   const gchar *xml =
2936       "<?xml version=\"1.0\"?>"
2937       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
2938       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
2939       "  <Period id=\"Period0\""
2940       "          duration=\"P0Y0M1DT1H1M1S\""
2941       "          bitstreamSwitching=\"true\">"
2942       "    <AdaptationSet id=\"1\""
2943       "                   mimeType=\"video/mp4\">"
2944       "      <Representation id=\"1\" bandwidth=\"250000\">"
2945       "      </Representation>"
2946       "    </AdaptationSet>"
2947       "    <AdaptationSet id=\"2\""
2948       "                   mimeType=\"audio\""
2949       "                   bitstreamSwitching=\"false\">"
2950       "      <Representation id=\"2\" bandwidth=\"250000\">"
2951       "      </Representation></AdaptationSet></Period></MPD>";
2952
2953   gboolean ret;
2954   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
2955
2956   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
2957   assert_equals_int (ret, TRUE);
2958
2959   /* process the xml data */
2960   ret =
2961       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
2962       -1, NULL);
2963   assert_equals_int (ret, TRUE);
2964
2965   /* get the list of adaptation sets of the first period */
2966   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
2967   fail_if (adaptationSets == NULL);
2968
2969   /* setup streaming from the first adaptation set */
2970   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
2971   fail_if (adapt_set == NULL);
2972   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
2973   assert_equals_int (ret, TRUE);
2974
2975   /* setup streaming from the second adaptation set */
2976   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 1);
2977   fail_if (adapt_set == NULL);
2978   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
2979   assert_equals_int (ret, TRUE);
2980
2981   /* 2 active streams */
2982   activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
2983   assert_equals_int (activeStreams, 2);
2984
2985   /* get details of the first active stream */
2986   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
2987   fail_if (activeStream == NULL);
2988
2989   assert_equals_int (activeStream->mimeType, GST_STREAM_VIDEO);
2990   caps = gst_mpd_client2_get_stream_caps (activeStream);
2991   fail_unless (caps != NULL);
2992   s = gst_caps_get_structure (caps, 0);
2993   assert_equals_string (gst_structure_get_name (s), "video/quicktime");
2994   gst_caps_unref (caps);
2995
2996   /* inherited from Period's bitstreamSwitching */
2997   bitstreamSwitchingFlag =
2998       gst_mpd_client2_get_bitstream_switching_flag (activeStream);
2999   assert_equals_int (bitstreamSwitchingFlag, TRUE);
3000
3001   /* get details of the second active stream */
3002   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 1);
3003   fail_if (activeStream == NULL);
3004
3005   assert_equals_int (activeStream->mimeType, GST_STREAM_AUDIO);
3006   caps = gst_mpd_client2_get_stream_caps (activeStream);
3007   fail_unless (caps != NULL);
3008   s = gst_caps_get_structure (caps, 0);
3009   assert_equals_string (gst_structure_get_name (s), "audio");
3010   gst_caps_unref (caps);
3011
3012   /* set to FALSE in our example, but overwritten to TRUE by Period's
3013    * bitstreamSwitching
3014    */
3015   bitstreamSwitchingFlag =
3016       gst_mpd_client2_get_bitstream_switching_flag (activeStream);
3017   assert_equals_int (bitstreamSwitchingFlag, TRUE);
3018
3019   gst_mpd_client2_free (mpdclient);
3020 }
3021
3022 GST_END_TEST;
3023
3024 /*
3025  * Test various duration formats
3026  */
3027 GST_START_TEST (dash_mpdparser_various_duration_formats)
3028 {
3029   GstMPDPeriodNode *periodNode;
3030   const gchar *xml =
3031       "<?xml version=\"1.0\"?>"
3032       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3033       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
3034       "     availabilityStartTime=\"2015-03-24T0:0:0\""
3035       "     mediaPresentationDuration=\"P100Y\">"
3036       "  <Period id=\"Period0\" start=\"PT1S\"></Period>"
3037       "  <Period id=\"Period1\" start=\"PT1.5S\"></Period>"
3038       "  <Period id=\"Period2\" start=\"PT1,7S\"></Period>"
3039       "  <Period id=\"Period3\" start=\"PT1M\"></Period>"
3040       "  <Period id=\"Period4\" start=\"PT1H\"></Period>"
3041       "  <Period id=\"Period5\" start=\"P1D\"></Period>"
3042       "  <Period id=\"Period6\" start=\"P1M\"></Period>"
3043       "  <Period id=\"Period7\" start=\"P1Y\"></Period></MPD>";
3044
3045   gboolean ret;
3046   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3047
3048   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3049   assert_equals_int (ret, TRUE);
3050
3051   ret =
3052       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3053       -1, NULL);
3054   assert_equals_int (ret, TRUE);
3055
3056   periodNode =
3057       (GstMPDPeriodNode *) g_list_nth_data (mpdclient->mpd_root_node->Periods,
3058       0);
3059   assert_equals_string (periodNode->id, "Period0");
3060   assert_equals_uint64 (periodNode->start,
3061       duration_to_ms (0, 0, 0, 0, 0, 1, 0));
3062
3063   periodNode =
3064       (GstMPDPeriodNode *) g_list_nth_data (mpdclient->mpd_root_node->Periods,
3065       1);
3066   assert_equals_string (periodNode->id, "Period1");
3067   assert_equals_uint64 (periodNode->start,
3068       duration_to_ms (0, 0, 0, 0, 0, 1, 500));
3069
3070   periodNode =
3071       (GstMPDPeriodNode *) g_list_nth_data (mpdclient->mpd_root_node->Periods,
3072       2);
3073   assert_equals_string (periodNode->id, "Period2");
3074   assert_equals_uint64 (periodNode->start,
3075       duration_to_ms (0, 0, 0, 0, 0, 1, 700));
3076
3077   periodNode =
3078       (GstMPDPeriodNode *) g_list_nth_data (mpdclient->mpd_root_node->Periods,
3079       3);
3080   assert_equals_string (periodNode->id, "Period3");
3081   assert_equals_uint64 (periodNode->start,
3082       duration_to_ms (0, 0, 0, 0, 1, 0, 0));
3083
3084   periodNode =
3085       (GstMPDPeriodNode *) g_list_nth_data (mpdclient->mpd_root_node->Periods,
3086       4);
3087   assert_equals_string (periodNode->id, "Period4");
3088   assert_equals_uint64 (periodNode->start,
3089       duration_to_ms (0, 0, 0, 1, 0, 0, 0));
3090
3091   periodNode =
3092       (GstMPDPeriodNode *) g_list_nth_data (mpdclient->mpd_root_node->Periods,
3093       5);
3094   assert_equals_string (periodNode->id, "Period5");
3095   assert_equals_uint64 (periodNode->start,
3096       duration_to_ms (0, 0, 1, 0, 0, 0, 0));
3097
3098   periodNode =
3099       (GstMPDPeriodNode *) g_list_nth_data (mpdclient->mpd_root_node->Periods,
3100       6);
3101   assert_equals_string (periodNode->id, "Period6");
3102   assert_equals_uint64 (periodNode->start,
3103       duration_to_ms (0, 1, 0, 0, 0, 0, 0));
3104
3105   periodNode =
3106       (GstMPDPeriodNode *) g_list_nth_data (mpdclient->mpd_root_node->Periods,
3107       7);
3108   assert_equals_string (periodNode->id, "Period7");
3109   assert_equals_uint64 (periodNode->start,
3110       duration_to_ms (1, 0, 0, 0, 0, 0, 0));
3111
3112   gst_mpd_client2_free (mpdclient);
3113 }
3114
3115 GST_END_TEST;
3116
3117 /*
3118  * Test media presentation setup
3119  *
3120  */
3121 GST_START_TEST (dash_mpdparser_setup_media_presentation)
3122 {
3123   const gchar *xml =
3124       "<?xml version=\"1.0\"?>"
3125       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3126       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3127       "  <Period id=\"Period0\""
3128       "          duration=\"P0Y0M1DT1H1M1S\"></Period></MPD>";
3129
3130   gboolean ret;
3131   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3132
3133   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3134   assert_equals_int (ret, TRUE);
3135
3136   /* process the xml data */
3137   ret =
3138       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3139       -1, NULL);
3140   assert_equals_int (ret, TRUE);
3141
3142   gst_mpd_client2_free (mpdclient);
3143 }
3144
3145 GST_END_TEST;
3146
3147 /*
3148  * Test setting a stream
3149  *
3150  */
3151 GST_START_TEST (dash_mpdparser_setup_streaming)
3152 {
3153   GList *adaptationSets;
3154   GstMPDAdaptationSetNode *adapt_set;
3155
3156   const gchar *xml =
3157       "<?xml version=\"1.0\"?>"
3158       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3159       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3160       "  <Period id=\"Period0\""
3161       "          duration=\"P0Y0M1DT1H1M1S\">"
3162       "    <AdaptationSet id=\"1\""
3163       "                   mimeType=\"video/mp4\">"
3164       "      <Representation id=\"1\" bandwidth=\"250000\">"
3165       "      </Representation></AdaptationSet></Period></MPD>";
3166
3167   gboolean ret;
3168   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3169
3170   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3171   assert_equals_int (ret, TRUE);
3172
3173   /* process the xml data */
3174   ret =
3175       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3176       -1, NULL);
3177   assert_equals_int (ret, TRUE);
3178
3179   /* get the first adaptation set of the first period */
3180   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
3181   fail_if (adaptationSets == NULL);
3182   adapt_set = (GstMPDAdaptationSetNode *) adaptationSets->data;
3183   fail_if (adapt_set == NULL);
3184
3185   /* setup streaming from the adaptation set */
3186   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
3187   assert_equals_int (ret, TRUE);
3188
3189   gst_mpd_client2_free (mpdclient);
3190 }
3191
3192 GST_END_TEST;
3193
3194 /*
3195  * Test handling Period selection
3196  *
3197  */
3198 GST_START_TEST (dash_mpdparser_period_selection)
3199 {
3200   const gchar *periodName;
3201   guint periodIndex;
3202
3203   const gchar *xml =
3204       "<?xml version=\"1.0\"?>"
3205       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3206       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
3207       "     mediaPresentationDuration=\"P0Y0M1DT1H4M3S\">"
3208       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\"></Period>"
3209       "  <Period id=\"Period1\"></Period>"
3210       "  <Period id=\"Period2\" start=\"P0Y0M1DT1H3M3S\"></Period></MPD>";
3211
3212   gboolean ret;
3213   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3214
3215   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3216   assert_equals_int (ret, TRUE);
3217
3218   /* period_idx should be 0 and we should have no active periods */
3219   assert_equals_uint64 (mpdclient->period_idx, 0);
3220   fail_unless (mpdclient->periods == NULL);
3221
3222   /* process the xml data */
3223   ret =
3224       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3225       -1, NULL);
3226   assert_equals_int (ret, TRUE);
3227
3228   /* check the periods */
3229   fail_unless (mpdclient->periods != NULL);
3230   periodName = gst_mpd_client2_get_period_id (mpdclient);
3231   assert_equals_string (periodName, "Period0");
3232
3233   ret = gst_mpd_client2_set_period_index (mpdclient, 1);
3234   assert_equals_int (ret, TRUE);
3235   periodName = gst_mpd_client2_get_period_id (mpdclient);
3236   assert_equals_string (periodName, "Period1");
3237
3238   ret = gst_mpd_client2_set_period_index (mpdclient, 2);
3239   assert_equals_int (ret, TRUE);
3240   periodName = gst_mpd_client2_get_period_id (mpdclient);
3241   assert_equals_string (periodName, "Period2");
3242
3243   ret = gst_mpd_client2_has_next_period (mpdclient);
3244   assert_equals_int (ret, FALSE);
3245   ret = gst_mpd_client2_has_previous_period (mpdclient);
3246   assert_equals_int (ret, TRUE);
3247
3248   ret = gst_mpd_client2_set_period_index (mpdclient, 0);
3249   assert_equals_int (ret, TRUE);
3250   ret = gst_mpd_client2_has_next_period (mpdclient);
3251   assert_equals_int (ret, TRUE);
3252   ret = gst_mpd_client2_has_previous_period (mpdclient);
3253   assert_equals_int (ret, FALSE);
3254
3255   ret = gst_mpd_client2_set_period_id (mpdclient, "Period1");
3256   assert_equals_int (ret, TRUE);
3257   periodIndex = gst_mpd_client2_get_period_index (mpdclient);
3258   assert_equals_uint64 (periodIndex, 1);
3259
3260   gst_mpd_client2_free (mpdclient);
3261 }
3262
3263 GST_END_TEST;
3264
3265 /*
3266  * Test handling Period selection based on time
3267  *
3268  */
3269 GST_START_TEST (dash_mpdparser_get_period_at_time)
3270 {
3271   guint periodIndex;
3272   GstDateTime *time;
3273
3274   const gchar *xml =
3275       "<?xml version=\"1.0\"?>"
3276       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3277       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
3278       "     availabilityStartTime=\"2015-03-24T0:0:0\""
3279       "     mediaPresentationDuration=\"P0Y0M1DT1H4M3S\">"
3280       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\"></Period>"
3281       "  <Period id=\"Period1\"></Period>"
3282       "  <Period id=\"Period2\" start=\"P0Y0M1DT1H3M3S\"></Period></MPD>";
3283
3284   gboolean ret;
3285   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3286
3287   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3288   assert_equals_int (ret, TRUE);
3289
3290   /* process the xml data */
3291   ret =
3292       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3293       -1, NULL);
3294   assert_equals_int (ret, TRUE);
3295
3296   /* request period for a time before availabilityStartTime, expect period index 0 */
3297   time = gst_date_time_new_from_iso8601_string ("2015-03-23T23:30:59Z");
3298   periodIndex = gst_mpd_client2_get_period_index_at_time (mpdclient, time);
3299   gst_date_time_unref (time);
3300   assert_equals_int (periodIndex, 0);
3301
3302   /* request period for a time from period 0 */
3303   time = gst_date_time_new_from_iso8601_string ("2015-03-24T23:30:59Z");
3304   periodIndex = gst_mpd_client2_get_period_index_at_time (mpdclient, time);
3305   gst_date_time_unref (time);
3306   assert_equals_int (periodIndex, 0);
3307
3308   /* request period for a time from period 1 */
3309   time = gst_date_time_new_from_iso8601_string ("2015-03-25T1:1:1Z");
3310   periodIndex = gst_mpd_client2_get_period_index_at_time (mpdclient, time);
3311   gst_date_time_unref (time);
3312   assert_equals_int (periodIndex, 1);
3313
3314   /* request period for a time from period 2 */
3315   time = gst_date_time_new_from_iso8601_string ("2015-03-25T1:3:3Z");
3316   periodIndex = gst_mpd_client2_get_period_index_at_time (mpdclient, time);
3317   gst_date_time_unref (time);
3318   assert_equals_int (periodIndex, 2);
3319
3320   /* request period for a time after mediaPresentationDuration, expect period index G_MAXUINT */
3321   time = gst_date_time_new_from_iso8601_string ("2015-03-25T1:4:3Z");
3322   periodIndex = gst_mpd_client2_get_period_index_at_time (mpdclient, time);
3323   gst_date_time_unref (time);
3324   assert_equals_int (periodIndex, G_MAXUINT);
3325
3326   gst_mpd_client2_free (mpdclient);
3327 }
3328
3329 GST_END_TEST;
3330
3331 /*
3332  * Test handling Adaptation sets
3333  *
3334  */
3335 GST_START_TEST (dash_mpdparser_adaptationSet_handling)
3336 {
3337   const gchar *periodName;
3338   guint adaptation_sets_count;
3339   GList *adaptationSets, *it;
3340   guint count = 0;
3341
3342   const gchar *xml =
3343       "<?xml version=\"1.0\"?>"
3344       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3345       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3346       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3347       "    <AdaptationSet id=\"1\"></AdaptationSet>"
3348       "  </Period>"
3349       "  <Period id=\"Period1\" duration=\"P0Y0M1DT1H1M1S\">"
3350       "    <AdaptationSet id=\"10\"></AdaptationSet>"
3351       "    <AdaptationSet id=\"11\"></AdaptationSet></Period></MPD>";
3352
3353   gboolean ret;
3354   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3355
3356   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3357   assert_equals_int (ret, TRUE);
3358
3359   /* process the xml data */
3360   ret =
3361       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3362       -1, NULL);
3363   assert_equals_int (ret, TRUE);
3364
3365   /* period0 has 1 adaptation set */
3366   fail_unless (mpdclient->periods != NULL);
3367   periodName = gst_mpd_client2_get_period_id (mpdclient);
3368   assert_equals_string (periodName, "Period0");
3369   adaptation_sets_count = gst_mpd_client2_get_nb_adaptationSet (mpdclient);
3370   assert_equals_int (adaptation_sets_count, 1);
3371
3372   /* period1 has 2 adaptation set */
3373   ret = gst_mpd_client2_set_period_id (mpdclient, "Period1");
3374   assert_equals_int (ret, TRUE);
3375   adaptation_sets_count = gst_mpd_client2_get_nb_adaptationSet (mpdclient);
3376   assert_equals_int (adaptation_sets_count, 2);
3377
3378   /* check the id for the 2 adaptation sets from period 1 */
3379   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
3380   fail_if (adaptationSets == NULL);
3381
3382   for (it = adaptationSets; it; it = g_list_next (it)) {
3383     GstMPDAdaptationSetNode *adapt_set;
3384     adapt_set = (GstMPDAdaptationSetNode *) it->data;
3385     fail_if (adapt_set == NULL);
3386
3387     assert_equals_int (adapt_set->id, 10 + count);
3388     count++;
3389   }
3390
3391   gst_mpd_client2_free (mpdclient);
3392 }
3393
3394 GST_END_TEST;
3395
3396 /*
3397  * Test handling Representation selection
3398  *
3399  */
3400 GST_START_TEST (dash_mpdparser_representation_selection)
3401 {
3402   GList *adaptationSets;
3403   GstMPDAdaptationSetNode *adaptationSetNode;
3404   GList *representations;
3405   gint represendationIndex;
3406
3407   const gchar *xml =
3408       "<?xml version=\"1.0\"?>"
3409       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3410       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3411       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3412       "    <AdaptationSet id=\"1\" mimeType=\"video/mp4\">"
3413       "      <Representation id=\"v0\" bandwidth=\"500000\"></Representation>"
3414       "      <Representation id=\"v1\" bandwidth=\"250000\"></Representation>"
3415       "    </AdaptationSet></Period></MPD>";
3416
3417   gboolean ret;
3418   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3419
3420   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3421   assert_equals_int (ret, TRUE);
3422
3423   /* process the xml data */
3424   ret =
3425       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3426       -1, NULL);
3427   assert_equals_int (ret, TRUE);
3428
3429   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
3430   fail_if (adaptationSets == NULL);
3431
3432   adaptationSetNode = adaptationSets->data;
3433   fail_if (adaptationSetNode == NULL);
3434   assert_equals_int (adaptationSetNode->id, 1);
3435
3436   representations = adaptationSetNode->Representations;
3437   fail_if (representations == NULL);
3438
3439   represendationIndex =
3440       gst_mpd_client2_get_rep_idx_with_min_bandwidth (representations);
3441   assert_equals_int (represendationIndex, 1);
3442
3443   represendationIndex =
3444       gst_mpd_client2_get_rep_idx_with_max_bandwidth (representations, 0, 0, 0,
3445       0, 1);
3446   assert_equals_int (represendationIndex, 1);
3447
3448   represendationIndex =
3449       gst_mpd_client2_get_rep_idx_with_max_bandwidth (representations, 100000,
3450       0, 0, 0, 1);
3451   assert_equals_int (represendationIndex, -1);
3452
3453   represendationIndex =
3454       gst_mpd_client2_get_rep_idx_with_max_bandwidth (representations, 300000,
3455       0, 0, 0, 1);
3456   assert_equals_int (represendationIndex, 1);
3457
3458   represendationIndex =
3459       gst_mpd_client2_get_rep_idx_with_max_bandwidth (representations, 500000,
3460       0, 0, 0, 1);
3461   assert_equals_int (represendationIndex, 0);
3462
3463   gst_mpd_client2_free (mpdclient);
3464 }
3465
3466 GST_END_TEST;
3467
3468 /*
3469  * Test handling Active stream selection
3470  *
3471  */
3472 GST_START_TEST (dash_mpdparser_activeStream_selection)
3473 {
3474   GList *adaptationSets;
3475   GstMPDAdaptationSetNode *adapt_set;
3476   guint activeStreams;
3477   GstActiveStream *activeStream;
3478
3479   const gchar *xml =
3480       "<?xml version=\"1.0\"?>"
3481       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3482       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3483       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3484       "    <AdaptationSet id=\"1\" mimeType=\"video/mp4\">"
3485       "      <Representation id=\"1\" bandwidth=\"250000\">"
3486       "      </Representation>"
3487       "    </AdaptationSet>"
3488       "    <AdaptationSet id=\"2\" mimeType=\"audio\">"
3489       "      <Representation id=\"2\" bandwidth=\"250000\">"
3490       "      </Representation>"
3491       "    </AdaptationSet>"
3492       "    <AdaptationSet id=\"3\" mimeType=\"application\">"
3493       "      <Representation id=\"3\" bandwidth=\"250000\">"
3494       "      </Representation></AdaptationSet></Period></MPD>";
3495
3496   gboolean ret;
3497   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3498
3499   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3500   assert_equals_int (ret, TRUE);
3501
3502   /* process the xml data */
3503   ret =
3504       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3505       -1, NULL);
3506   assert_equals_int (ret, TRUE);
3507
3508   /* get the list of adaptation sets of the first period */
3509   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
3510   fail_if (adaptationSets == NULL);
3511
3512   /* no active streams yet */
3513   activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
3514   assert_equals_int (activeStreams, 0);
3515
3516   /* setup streaming from the first adaptation set */
3517   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
3518   fail_if (adapt_set == NULL);
3519   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
3520   assert_equals_int (ret, TRUE);
3521
3522   /* 1 active streams */
3523   activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
3524   assert_equals_int (activeStreams, 1);
3525
3526   /* setup streaming from the second adaptation set */
3527   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 1);
3528   fail_if (adapt_set == NULL);
3529   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
3530   assert_equals_int (ret, TRUE);
3531
3532   /* 2 active streams */
3533   activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
3534   assert_equals_int (activeStreams, 2);
3535
3536   /* setup streaming from the third adaptation set */
3537   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 2);
3538   fail_if (adapt_set == NULL);
3539   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
3540   assert_equals_int (ret, TRUE);
3541
3542   /* 3 active streams */
3543   activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
3544   assert_equals_int (activeStreams, 3);
3545
3546   /* get details of the first active stream */
3547   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
3548   fail_if (activeStream == NULL);
3549   assert_equals_int (activeStream->mimeType, GST_STREAM_VIDEO);
3550
3551   /* get details of the second active stream */
3552   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 1);
3553   fail_if (activeStream == NULL);
3554   assert_equals_int (activeStream->mimeType, GST_STREAM_AUDIO);
3555
3556   /* get details of the third active stream */
3557   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 2);
3558   fail_if (activeStream == NULL);
3559   assert_equals_int (activeStream->mimeType, GST_STREAM_APPLICATION);
3560
3561   gst_mpd_client2_free (mpdclient);
3562 }
3563
3564 GST_END_TEST;
3565
3566 /*
3567  * Test getting Active stream parameters
3568  *
3569  */
3570 GST_START_TEST (dash_mpdparser_activeStream_parameters)
3571 {
3572   GList *adaptationSets;
3573   GstMPDAdaptationSetNode *adapt_set;
3574   guint activeStreams;
3575   GstActiveStream *activeStream;
3576   GstCaps *caps;
3577   GstStructure *s;
3578   gboolean bitstreamSwitchingFlag;
3579   guint videoStreamWidth;
3580   guint videoStreamHeight;
3581   guint audioStreamRate;
3582   guint audioChannelsCount;
3583
3584   const gchar *xml =
3585       "<?xml version=\"1.0\"?>"
3586       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3587       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3588       "  <Period id=\"Period0\""
3589       "          duration=\"P0Y0M1DT1H1M1S\">"
3590       "    <AdaptationSet id=\"1\""
3591       "                   mimeType=\"video/mp4\""
3592       "                   width=\"320\""
3593       "                   height=\"240\""
3594       "                   bitstreamSwitching=\"true\""
3595       "                   audioSamplingRate=\"48000\">"
3596       "      <Representation id=\"1\" bandwidth=\"250000\">"
3597       "      </Representation></AdaptationSet></Period></MPD>";
3598
3599   gboolean ret;
3600   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3601
3602   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3603   assert_equals_int (ret, TRUE);
3604
3605   /* process the xml data */
3606   ret =
3607       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3608       -1, NULL);
3609   assert_equals_int (ret, TRUE);
3610
3611   /* get the list of adaptation sets of the first period */
3612   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
3613   fail_if (adaptationSets == NULL);
3614
3615   /* setup streaming from the first adaptation set */
3616   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
3617   fail_if (adapt_set == NULL);
3618   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
3619   assert_equals_int (ret, TRUE);
3620
3621   /* 1 active streams */
3622   activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
3623   assert_equals_int (activeStreams, 1);
3624
3625   /* get details of the first active stream */
3626   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
3627   fail_if (activeStream == NULL);
3628
3629   assert_equals_int (activeStream->mimeType, GST_STREAM_VIDEO);
3630   caps = gst_mpd_client2_get_stream_caps (activeStream);
3631   fail_unless (caps != NULL);
3632   s = gst_caps_get_structure (caps, 0);
3633   assert_equals_string (gst_structure_get_name (s), "video/quicktime");
3634   gst_caps_unref (caps);
3635
3636   bitstreamSwitchingFlag =
3637       gst_mpd_client2_get_bitstream_switching_flag (activeStream);
3638   assert_equals_int (bitstreamSwitchingFlag, 1);
3639
3640   videoStreamWidth = gst_mpd_client2_get_video_stream_width (activeStream);
3641   assert_equals_int (videoStreamWidth, 320);
3642
3643   videoStreamHeight = gst_mpd_client2_get_video_stream_height (activeStream);
3644   assert_equals_int (videoStreamHeight, 240);
3645
3646   audioStreamRate = gst_mpd_client2_get_audio_stream_rate (activeStream);
3647   assert_equals_int (audioStreamRate, 48000);
3648
3649   audioChannelsCount =
3650       gst_mpd_client2_get_audio_stream_num_channels (activeStream);
3651   assert_equals_int (audioChannelsCount, 0);
3652
3653   gst_mpd_client2_free (mpdclient);
3654 }
3655
3656 GST_END_TEST;
3657
3658 /*
3659  * Test getting number and list of audio languages
3660  *
3661  */
3662 GST_START_TEST (dash_mpdparser_get_audio_languages)
3663 {
3664   GList *adaptationSets;
3665   GstMPDAdaptationSetNode *adapt_set;
3666   guint activeStreams;
3667   guint adaptationSetsCount;
3668   GList *languages = NULL;
3669   guint languagesCount;
3670
3671   const gchar *xml =
3672       "<?xml version=\"1.0\"?>"
3673       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3674       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3675       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3676       "    <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3677       "      <Representation id=\"1\" bandwidth=\"250000\">"
3678       "      </Representation>"
3679       "    </AdaptationSet>"
3680       "    <AdaptationSet id=\"2\" mimeType=\"video/mp4\">"
3681       "      <Representation id=\"2\" bandwidth=\"250000\">"
3682       "      </Representation>"
3683       "    </AdaptationSet>"
3684       "    <AdaptationSet id=\"3\" mimeType=\"audio\" lang=\"fr\">"
3685       "      <Representation id=\"3\" bandwidth=\"250000\">"
3686       "      </Representation></AdaptationSet></Period></MPD>";
3687
3688   gboolean ret;
3689   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3690   gint i;
3691
3692   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3693   assert_equals_int (ret, TRUE);
3694
3695   /* process the xml data */
3696   ret =
3697       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3698       -1, NULL);
3699   assert_equals_int (ret, TRUE);
3700
3701   /* get the list of adaptation sets of the first period */
3702   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
3703   fail_if (adaptationSets == NULL);
3704
3705   /* setup streaming from all adaptation sets */
3706   adaptationSetsCount = gst_mpd_client2_get_nb_adaptationSet (mpdclient);
3707   for (i = 0; i < adaptationSetsCount; i++) {
3708     adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, i);
3709     fail_if (adapt_set == NULL);
3710     ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
3711     assert_equals_int (ret, TRUE);
3712   }
3713   activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
3714   assert_equals_int (activeStreams, adaptationSetsCount);
3715
3716   languagesCount =
3717       gst_mpd_client2_get_list_and_nb_of_audio_language (mpdclient, &languages);
3718   assert_equals_int (languagesCount, 2);
3719   assert_equals_string ((gchar *) g_list_nth_data (languages, 0), "en");
3720   assert_equals_string ((gchar *) g_list_nth_data (languages, 1), "fr");
3721
3722   g_list_free (languages);
3723
3724   gst_mpd_client2_free (mpdclient);
3725 }
3726
3727 GST_END_TEST;
3728
3729 /*
3730  * Tests getting the base URL
3731  *
3732  */
3733 static GstMPDClient2 *
3734 setup_mpd_client (const gchar * xml)
3735 {
3736   GList *adaptationSets;
3737   GstMPDAdaptationSetNode *adapt_set;
3738   guint activeStreams;
3739   guint adaptationSetsCount;
3740   gboolean ret;
3741   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
3742   gint i;
3743
3744   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
3745   assert_equals_int (ret, TRUE);
3746
3747   /* process the xml data */
3748   ret =
3749       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
3750       -1, NULL);
3751   assert_equals_int (ret, TRUE);
3752
3753   /* get the list of adaptation sets of the first period */
3754   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
3755   fail_if (adaptationSets == NULL);
3756
3757   /* setup streaming from all adaptation sets */
3758   adaptationSetsCount = gst_mpd_client2_get_nb_adaptationSet (mpdclient);
3759   for (i = 0; i < adaptationSetsCount; i++) {
3760     adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, i);
3761     fail_if (adapt_set == NULL);
3762     ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
3763     assert_equals_int (ret, TRUE);
3764   }
3765   activeStreams = gst_mpd_client2_get_nb_active_stream (mpdclient);
3766   assert_equals_int (activeStreams, adaptationSetsCount);
3767
3768   return mpdclient;
3769 }
3770
3771 GST_START_TEST (dash_mpdparser_get_baseURL1)
3772 {
3773   const gchar *baseURL;
3774   const gchar *xml =
3775       "<?xml version=\"1.0\"?>"
3776       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3777       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3778       "  <BaseURL>http://example.com/</BaseURL>"
3779       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3780       "    <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3781       "      <Representation id=\"1\" bandwidth=\"250000\">"
3782       "      </Representation></AdaptationSet></Period></MPD>";
3783
3784   GstMPDClient2 *mpdclient = setup_mpd_client (xml);
3785
3786   baseURL = gst_mpd_client2_get_baseURL (mpdclient, 0);
3787   fail_if (baseURL == NULL);
3788   assert_equals_string (baseURL, "http://example.com/");
3789
3790   gst_mpd_client2_free (mpdclient);
3791 }
3792
3793 GST_END_TEST;
3794
3795
3796 GST_START_TEST (dash_mpdparser_get_baseURL2)
3797 {
3798   const gchar *baseURL;
3799   const gchar *xml =
3800       "<?xml version=\"1.0\"?>"
3801       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3802       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3803       "  <BaseURL>mpd_base_url/</BaseURL>"
3804       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3805       "    <BaseURL> /period_base_url/</BaseURL>"
3806       "    <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3807       "      <BaseURL>adaptation_base_url</BaseURL>"
3808       "      <Representation id=\"1\" bandwidth=\"250000\">"
3809       "        <BaseURL>representation_base_url</BaseURL>"
3810       "      </Representation></AdaptationSet></Period></MPD>";
3811
3812   GstMPDClient2 *mpdclient = setup_mpd_client (xml);
3813
3814   /* test baseURL. Its value should be computed like this:
3815    *  - start with xml url (null)
3816    *  - set it to the value from MPD's BaseURL element: "mpd_base_url/"
3817    *  - update the value with BaseURL element from Period. Because Period's
3818    * baseURL is absolute (starts with /) it will overwrite the current value
3819    * for baseURL. So, baseURL becomes "/period_base_url/"
3820    *  - update the value with BaseURL element from AdaptationSet. Because this
3821    * is a relative url, it will update the current value. baseURL becomes
3822    * "/period_base_url/adaptation_base_url"
3823    *  - update the value with BaseURL element from Representation. Because this
3824    * is a relative url, it will update the current value. Because the current
3825    * value does not end in /, everything after the last / will be overwritten.
3826    * baseURL becomes "/period_base_url/representation_base_url"
3827    */
3828   baseURL = gst_mpd_client2_get_baseURL (mpdclient, 0);
3829   fail_if (baseURL == NULL);
3830   assert_equals_string (baseURL, "/period_base_url/representation_base_url");
3831
3832   gst_mpd_client2_free (mpdclient);
3833 }
3834
3835 GST_END_TEST;
3836
3837
3838 GST_START_TEST (dash_mpdparser_get_baseURL3)
3839 {
3840   const gchar *baseURL;
3841   const gchar *xml =
3842       "<?xml version=\"1.0\"?>"
3843       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3844       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3845       "  <BaseURL>mpd_base_url/</BaseURL>"
3846       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3847       "    <BaseURL> /period_base_url/</BaseURL>"
3848       "    <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3849       "      <BaseURL>adaptation_base_url</BaseURL>"
3850       "      <Representation id=\"1\" bandwidth=\"250000\">"
3851       "        <BaseURL>/representation_base_url</BaseURL>"
3852       "      </Representation></AdaptationSet></Period></MPD>";
3853
3854   GstMPDClient2 *mpdclient = setup_mpd_client (xml);
3855
3856   /* test baseURL. Its value should be computed like this:
3857    *  - start with xml url (null)
3858    *  - set it to the value from MPD's BaseURL element: "mpd_base_url/"
3859    *  - update the value with BaseURL element from Period. Because Period's
3860    * baseURL is absolute (starts with /) it will overwrite the current value
3861    * for baseURL. So, baseURL becomes "/period_base_url/"
3862    *  - update the value with BaseURL element from AdaptationSet. Because this
3863    * is a relative url, it will update the current value. baseURL becomes
3864    * "/period_base_url/adaptation_base_url"
3865    *  - update the value with BaseURL element from Representation. Because this
3866    * is an absolute url, it will replace everything again"
3867    */
3868   baseURL = gst_mpd_client2_get_baseURL (mpdclient, 0);
3869   fail_if (baseURL == NULL);
3870   assert_equals_string (baseURL, "/representation_base_url");
3871
3872   gst_mpd_client2_free (mpdclient);
3873 }
3874
3875 GST_END_TEST;
3876
3877
3878 GST_START_TEST (dash_mpdparser_get_baseURL4)
3879 {
3880   const gchar *baseURL;
3881   const gchar *xml =
3882       "<?xml version=\"1.0\"?>"
3883       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3884       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3885       "  <BaseURL>mpd_base_url/</BaseURL>"
3886       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3887       "    <BaseURL> /period_base_url/</BaseURL>"
3888       "    <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3889       "      <BaseURL>adaptation_base_url/</BaseURL>"
3890       "      <Representation id=\"1\" bandwidth=\"250000\">"
3891       "        <BaseURL>representation_base_url/</BaseURL>"
3892       "      </Representation></AdaptationSet></Period></MPD>";
3893
3894   GstMPDClient2 *mpdclient = setup_mpd_client (xml);
3895
3896   /* test baseURL. Its value should be computed like this:
3897    *  - start with xml url (null)
3898    *  - set it to the value from MPD's BaseURL element: "mpd_base_url/"
3899    *  - update the value with BaseURL element from Period. Because Period's
3900    * baseURL is absolute (starts with /) it will overwrite the current value
3901    * for baseURL. So, baseURL becomes "/period_base_url/"
3902    *  - update the value with BaseURL element from AdaptationSet. Because this
3903    * is a relative url, it will update the current value. baseURL becomes
3904    * "/period_base_url/adaptation_base_url/"
3905    *  - update the value with BaseURL element from Representation. Because this
3906    * is an relative url, it will update the current value."
3907    */
3908   baseURL = gst_mpd_client2_get_baseURL (mpdclient, 0);
3909   fail_if (baseURL == NULL);
3910   assert_equals_string (baseURL,
3911       "/period_base_url/adaptation_base_url/representation_base_url/");
3912
3913   gst_mpd_client2_free (mpdclient);
3914 }
3915
3916 GST_END_TEST;
3917
3918 /* test multiple BaseUrl entries per section */
3919 GST_START_TEST (dash_mpdparser_get_baseURL5)
3920 {
3921   GstMPDPeriodNode *periodNode;
3922   GstMPDAdaptationSetNode *adaptationSet;
3923   GstMPDRepresentationNode *representation;
3924   const gchar *baseURL;
3925   GstMPDBaseURLNode *gstBaseURL;
3926
3927   const gchar *xml =
3928       "<?xml version=\"1.0\"?>"
3929       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
3930       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
3931       "  <BaseURL>/mpd_base_url1/</BaseURL>"
3932       "  <BaseURL>/mpd_base_url2/</BaseURL>"
3933       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
3934       "    <BaseURL> period_base_url1/</BaseURL>"
3935       "    <BaseURL> period_base_url2/</BaseURL>"
3936       "    <BaseURL> period_base_url3/</BaseURL>"
3937       "    <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
3938       "      <BaseURL>adaptation_base_url1/</BaseURL>"
3939       "      <BaseURL>adaptation_base_url2/</BaseURL>"
3940       "      <BaseURL>adaptation_base_url3/</BaseURL>"
3941       "      <BaseURL>adaptation_base_url4/</BaseURL>"
3942       "      <Representation id=\"1\" bandwidth=\"250000\">"
3943       "        <BaseURL>representation_base_url1/</BaseURL>"
3944       "        <BaseURL>representation_base_url2/</BaseURL>"
3945       "        <BaseURL>representation_base_url3/</BaseURL>"
3946       "        <BaseURL>representation_base_url4/</BaseURL>"
3947       "        <BaseURL>representation_base_url5/</BaseURL>"
3948       "      </Representation></AdaptationSet></Period></MPD>";
3949
3950   GstMPDClient2 *mpdclient = setup_mpd_client (xml);
3951
3952   assert_equals_int (g_list_length (mpdclient->mpd_root_node->BaseURLs), 2);
3953   gstBaseURL = g_list_nth_data (mpdclient->mpd_root_node->BaseURLs, 0);
3954   assert_equals_string (gstBaseURL->baseURL, "/mpd_base_url1/");
3955   gstBaseURL = g_list_nth_data (mpdclient->mpd_root_node->BaseURLs, 1);
3956   assert_equals_string (gstBaseURL->baseURL, "/mpd_base_url2/");
3957
3958   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
3959   assert_equals_int (g_list_length (periodNode->BaseURLs), 3);
3960   gstBaseURL = g_list_nth_data (periodNode->BaseURLs, 0);
3961   assert_equals_string (gstBaseURL->baseURL, " period_base_url1/");
3962   gstBaseURL = g_list_nth_data (periodNode->BaseURLs, 1);
3963   assert_equals_string (gstBaseURL->baseURL, " period_base_url2/");
3964   gstBaseURL = g_list_nth_data (periodNode->BaseURLs, 2);
3965   assert_equals_string (gstBaseURL->baseURL, " period_base_url3/");
3966
3967   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
3968   assert_equals_int (g_list_length (adaptationSet->BaseURLs), 4);
3969   gstBaseURL = g_list_nth_data (adaptationSet->BaseURLs, 0);
3970   assert_equals_string (gstBaseURL->baseURL, "adaptation_base_url1/");
3971   gstBaseURL = g_list_nth_data (adaptationSet->BaseURLs, 1);
3972   assert_equals_string (gstBaseURL->baseURL, "adaptation_base_url2/");
3973   gstBaseURL = g_list_nth_data (adaptationSet->BaseURLs, 2);
3974   assert_equals_string (gstBaseURL->baseURL, "adaptation_base_url3/");
3975   gstBaseURL = g_list_nth_data (adaptationSet->BaseURLs, 3);
3976   assert_equals_string (gstBaseURL->baseURL, "adaptation_base_url4/");
3977
3978   representation = (GstMPDRepresentationNode *)
3979       adaptationSet->Representations->data;
3980   assert_equals_int (g_list_length (representation->BaseURLs), 5);
3981   gstBaseURL = g_list_nth_data (representation->BaseURLs, 0);
3982   assert_equals_string (gstBaseURL->baseURL, "representation_base_url1/");
3983   gstBaseURL = g_list_nth_data (representation->BaseURLs, 1);
3984   assert_equals_string (gstBaseURL->baseURL, "representation_base_url2/");
3985   gstBaseURL = g_list_nth_data (representation->BaseURLs, 2);
3986   assert_equals_string (gstBaseURL->baseURL, "representation_base_url3/");
3987   gstBaseURL = g_list_nth_data (representation->BaseURLs, 3);
3988   assert_equals_string (gstBaseURL->baseURL, "representation_base_url4/");
3989   gstBaseURL = g_list_nth_data (representation->BaseURLs, 4);
3990   assert_equals_string (gstBaseURL->baseURL, "representation_base_url5/");
3991
3992   /* test baseURL. Its value should be computed like this:
3993    *  - start with xml url (null)
3994    *  - set it to the value from MPD's BaseURL element: "/mpd_base_url1/"
3995    *  - update the value with BaseURL element from Period. Because this
3996    * is a relative url, it will update the current value. baseURL becomes
3997    * "/mpd_base_url1/period_base_url1/"
3998    *  - update the value with BaseURL element from AdaptationSet. Because this
3999    * is a relative url, it will update the current value. baseURL becomes
4000    * "/mpd_base_url1/period_base_url1/adaptation_base_url1/"
4001    *  - update the value with BaseURL element from Representation. Because this
4002    * is an relative url, it will update the current value."
4003    */
4004   baseURL = gst_mpd_client2_get_baseURL (mpdclient, 0);
4005   fail_if (baseURL == NULL);
4006   assert_equals_string (baseURL,
4007       "/mpd_base_url1/period_base_url1/adaptation_base_url1/representation_base_url1/");
4008
4009   gst_mpd_client2_free (mpdclient);
4010 }
4011
4012 GST_END_TEST;
4013
4014 /* test no BaseURL */
4015 GST_START_TEST (dash_mpdparser_get_baseURL6)
4016 {
4017   const gchar *baseURL;
4018   const gchar *xml =
4019       "<?xml version=\"1.0\"?>"
4020       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4021       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
4022       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
4023       "    <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
4024       "      <Representation id=\"1\" bandwidth=\"250000\">"
4025       "      </Representation></AdaptationSet></Period></MPD>";
4026
4027   GstMPDClient2 *mpdclient = setup_mpd_client (xml);
4028
4029   baseURL = gst_mpd_client2_get_baseURL (mpdclient, 0);
4030   fail_if (baseURL == NULL);
4031   assert_equals_string (baseURL, "");
4032
4033   gst_mpd_client2_free (mpdclient);
4034 }
4035
4036 GST_END_TEST;
4037
4038 /* BaseURL: test that the path is made absolute (a / is prepended if needed */
4039 GST_START_TEST (dash_mpdparser_get_baseURL7)
4040 {
4041   const gchar *baseURL;
4042   const gchar *xml =
4043       "<?xml version=\"1.0\"?>"
4044       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4045       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
4046       "  <BaseURL>x/example.com/</BaseURL>"
4047       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
4048       "    <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
4049       "      <Representation id=\"1\" bandwidth=\"250000\">"
4050       "      </Representation></AdaptationSet></Period></MPD>";
4051
4052   GstMPDClient2 *mpdclient;
4053
4054   mpdclient = setup_mpd_client (xml);
4055
4056   baseURL = gst_mpd_client2_get_baseURL (mpdclient, 0);
4057   fail_if (baseURL == NULL);
4058   assert_equals_string (baseURL, "/x/example.com/");
4059
4060   gst_mpd_client2_free (mpdclient);
4061 }
4062
4063 GST_END_TEST;
4064
4065 /* BaseURL: test that a / is not prepended if the string contains ':'
4066  * This tests uris with schema present */
4067 GST_START_TEST (dash_mpdparser_get_baseURL8)
4068 {
4069   const gchar *baseURL;
4070   const gchar *xml =
4071       "<?xml version=\"1.0\"?>"
4072       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4073       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
4074       "  <BaseURL>x:y/example.com/</BaseURL>"
4075       "  <Period id=\"Period0\" duration=\"P0Y0M1DT1H1M1S\">"
4076       "    <AdaptationSet id=\"1\" mimeType=\"audio\" lang=\"en\">"
4077       "      <Representation id=\"1\" bandwidth=\"250000\">"
4078       "      </Representation></AdaptationSet></Period></MPD>";
4079
4080   GstMPDClient2 *mpdclient = setup_mpd_client (xml);
4081
4082   baseURL = gst_mpd_client2_get_baseURL (mpdclient, 0);
4083   fail_if (baseURL == NULL);
4084   assert_equals_string (baseURL, "x:y/example.com/");
4085
4086   gst_mpd_client2_free (mpdclient);
4087 }
4088
4089 GST_END_TEST;
4090
4091 /*
4092  * Test getting mediaPresentationDuration
4093  *
4094  */
4095 GST_START_TEST (dash_mpdparser_get_mediaPresentationDuration)
4096 {
4097   GstClockTime mediaPresentationDuration;
4098
4099   const gchar *xml =
4100       "<?xml version=\"1.0\"?>"
4101       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4102       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4103       "     mediaPresentationDuration=\"P0Y0M0DT0H0M3S\"></MPD>";
4104
4105   gboolean ret;
4106   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4107
4108   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4109   assert_equals_int (ret, TRUE);
4110
4111   mediaPresentationDuration =
4112       gst_mpd_client2_get_media_presentation_duration (mpdclient);
4113   assert_equals_uint64 (mediaPresentationDuration, 3000000000);
4114
4115   gst_mpd_client2_free (mpdclient);
4116 }
4117
4118 GST_END_TEST;
4119
4120 /*
4121  * Test getting streamPresentationOffset
4122  *
4123  */
4124 GST_START_TEST (dash_mpdparser_get_streamPresentationOffset)
4125 {
4126   GList *adaptationSets;
4127   GstMPDAdaptationSetNode *adapt_set;
4128   GstClockTime offset;
4129   const gchar *xml =
4130       "<?xml version=\"1.0\"?>"
4131       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4132       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4133       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4134       "  <Period>"
4135       "    <AdaptationSet mimeType=\"video/mp4\">"
4136       "      <SegmentBase timescale=\"1000\" presentationTimeOffset=\"3000\">"
4137       "      </SegmentBase>"
4138       "      <Representation id=\"1\" bandwidth=\"250000\">"
4139       "      </Representation></AdaptationSet></Period></MPD>";
4140
4141   gboolean ret;
4142   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4143
4144   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4145   assert_equals_int (ret, TRUE);
4146
4147   /* process the xml data */
4148   ret =
4149       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4150       -1, NULL);
4151   assert_equals_int (ret, TRUE);
4152
4153   /* get the list of adaptation sets of the first period */
4154   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
4155   fail_if (adaptationSets == NULL);
4156
4157   /* setup streaming from the first adaptation set */
4158   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4159   fail_if (adapt_set == NULL);
4160   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
4161   assert_equals_int (ret, TRUE);
4162
4163   /* test the stream presentation time offset */
4164   offset = gst_mpd_client2_get_stream_presentation_offset (mpdclient, 0);
4165   /* seems to be set only for template segments, so here it is 0 */
4166   assert_equals_int (offset, 0);
4167
4168   gst_mpd_client2_free (mpdclient);
4169 }
4170
4171 GST_END_TEST;
4172
4173 /*
4174  * Test handling segments
4175  *
4176  */
4177 GST_START_TEST (dash_mpdparser_segments)
4178 {
4179   GList *adaptationSets;
4180   GstMPDAdaptationSetNode *adapt_set;
4181   gboolean hasNextSegment;
4182   GstActiveStream *activeStream;
4183   GstFlowReturn flow;
4184   GstDateTime *segmentAvailability;
4185   GstDateTime *gst_time;
4186   GDateTime *g_time;
4187
4188   const gchar *xml =
4189       "<?xml version=\"1.0\"?>"
4190       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4191       "     type=\"dynamic\""
4192       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4193       "     availabilityStartTime=\"2015-03-24T0:0:0\""
4194       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4195       "  <Period id=\"Period0\" start=\"P0Y0M0DT0H0M10S\">"
4196       "    <AdaptationSet mimeType=\"video/mp4\">"
4197       "      <Representation id=\"1\" bandwidth=\"250000\">"
4198       "        <SegmentList duration=\"45\">"
4199       "          <SegmentURL media=\"TestMedia1\""
4200       "                      mediaRange=\"10-20\""
4201       "                      index=\"TestIndex1\""
4202       "                      indexRange=\"30-40\">"
4203       "          </SegmentURL>"
4204       "          <SegmentURL media=\"TestMedia2\""
4205       "                      mediaRange=\"20-30\""
4206       "                      index=\"TestIndex2\""
4207       "                      indexRange=\"40-50\">"
4208       "          </SegmentURL>"
4209       "        </SegmentList>"
4210       "      </Representation></AdaptationSet></Period></MPD>";
4211
4212   gboolean ret;
4213   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4214
4215   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4216   assert_equals_int (ret, TRUE);
4217
4218   /* process the xml data */
4219   ret =
4220       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4221       -1, NULL);
4222   assert_equals_int (ret, TRUE);
4223
4224   /* get the list of adaptation sets of the first period */
4225   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
4226   fail_if (adaptationSets == NULL);
4227
4228   /* setup streaming from the first adaptation set */
4229   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4230   fail_if (adapt_set == NULL);
4231   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
4232   assert_equals_int (ret, TRUE);
4233
4234   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
4235   fail_if (activeStream == NULL);
4236
4237   /* segment_index 0, segment_count 2.
4238    * Has next segment and can advance to next segment
4239    */
4240   hasNextSegment =
4241       gst_mpd_client2_has_next_segment (mpdclient, activeStream, TRUE);
4242   assert_equals_int (hasNextSegment, 1);
4243   flow = gst_mpd_client2_advance_segment (mpdclient, activeStream, TRUE);
4244   assert_equals_int (flow, GST_FLOW_OK);
4245
4246   /* segment_index 1, segment_count 2.
4247    * Does not have next segment and can not advance to next segment
4248    */
4249   hasNextSegment =
4250       gst_mpd_client2_has_next_segment (mpdclient, activeStream, TRUE);
4251   assert_equals_int (hasNextSegment, 0);
4252   flow = gst_mpd_client2_advance_segment (mpdclient, activeStream, TRUE);
4253   assert_equals_int (flow, GST_FLOW_EOS);
4254
4255   /* go to first segment */
4256   gst_mpd_client2_seek_to_first_segment (mpdclient);
4257
4258   /* segment_index 0, segment_count 2.
4259    * Has next segment and can advance to next segment
4260    */
4261   hasNextSegment =
4262       gst_mpd_client2_has_next_segment (mpdclient, activeStream, TRUE);
4263   assert_equals_int (hasNextSegment, 1);
4264   flow = gst_mpd_client2_advance_segment (mpdclient, activeStream, TRUE);
4265   assert_equals_int (flow, GST_FLOW_OK);
4266
4267   /* segment_index 1, segment_count 2
4268    * Does not have next segment
4269    */
4270   hasNextSegment =
4271       gst_mpd_client2_has_next_segment (mpdclient, activeStream, TRUE);
4272   assert_equals_int (hasNextSegment, 0);
4273
4274   /* segment index is still 1 */
4275   hasNextSegment =
4276       gst_mpd_client2_has_next_segment (mpdclient, activeStream, TRUE);
4277   assert_equals_int (hasNextSegment, 0);
4278
4279   /* each segment has a duration of 0 hours, 0 min 45 seconds
4280    * segment index is 1.
4281    * Start time is at the beginning of segment 1, so 1 * segment_duration = 1 * 45s
4282    * Availability start time is at the end of the segment, so we add duration (45s)
4283    * We also add period start time (10s)
4284    * So, availability start time for segment 1 is: 10 (period start) +
4285    * 45 (segment start) + 45 (duration) = 1'40s
4286    */
4287   segmentAvailability =
4288       gst_mpd_client2_get_next_segment_availability_start_time (mpdclient,
4289       activeStream);
4290   assert_equals_int (gst_date_time_get_year (segmentAvailability), 2015);
4291   assert_equals_int (gst_date_time_get_month (segmentAvailability), 3);
4292   assert_equals_int (gst_date_time_get_day (segmentAvailability), 24);
4293   assert_equals_int (gst_date_time_get_hour (segmentAvailability), 0);
4294   assert_equals_int (gst_date_time_get_minute (segmentAvailability), 1);
4295   assert_equals_int (gst_date_time_get_second (segmentAvailability), 40);
4296   gst_date_time_unref (segmentAvailability);
4297
4298   /* seek to time */
4299   gst_time = gst_date_time_new_from_iso8601_string ("2015-03-24T0:0:20Z");
4300   g_time = gst_date_time_to_g_date_time (gst_time);
4301   ret = gst_mpd_client2_seek_to_time (mpdclient, g_time);
4302   assert_equals_int (ret, 1);
4303   gst_date_time_unref (gst_time);
4304   g_date_time_unref (g_time);
4305
4306   /* segment index is now 0 */
4307   hasNextSegment =
4308       gst_mpd_client2_has_next_segment (mpdclient, activeStream, TRUE);
4309   assert_equals_int (hasNextSegment, 1);
4310
4311   gst_mpd_client2_free (mpdclient);
4312 }
4313
4314 GST_END_TEST;
4315
4316 /*
4317  * Test handling headers
4318  *
4319  */
4320 GST_START_TEST (dash_mpdparser_headers)
4321 {
4322   GList *adaptationSets;
4323   GstMPDAdaptationSetNode *adapt_set;
4324   gchar *uri;
4325   gint64 range_start;
4326   gint64 range_end;
4327
4328   const gchar *xml =
4329       "<?xml version=\"1.0\"?>"
4330       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4331       "     type=\"dynamic\""
4332       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4333       "     availabilityStartTime=\"2015-03-24T0:0:0\""
4334       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4335       "  <Period id=\"Period0\">"
4336       "    <AdaptationSet mimeType=\"video/mp4\">"
4337       "      <Representation id=\"1\" bandwidth=\"250000\">"
4338       "        <SegmentBase indexRange=\"10-20\">"
4339       "          <Initialization sourceURL=\"TestSourceUrl\""
4340       "                          range=\"100-200\">"
4341       "          </Initialization>"
4342       "          <RepresentationIndex sourceURL=\"TestSourceIndex\">"
4343       "          </RepresentationIndex>"
4344       "        </SegmentBase>"
4345       "      </Representation></AdaptationSet></Period></MPD>";
4346
4347   gboolean ret;
4348   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4349
4350   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4351   assert_equals_int (ret, TRUE);
4352
4353   /* process the xml data */
4354   ret =
4355       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4356       -1, NULL);
4357   assert_equals_int (ret, TRUE);
4358
4359   /* get the list of adaptation sets of the first period */
4360   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
4361   fail_if (adaptationSets == NULL);
4362
4363   /* setup streaming from the first adaptation set */
4364   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4365   fail_if (adapt_set == NULL);
4366   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
4367   assert_equals_int (ret, TRUE);
4368
4369   /* get segment url and range from segment Initialization */
4370   ret =
4371       gst_mpd_client2_get_next_header (mpdclient, &uri, 0, &range_start,
4372       &range_end);
4373   assert_equals_int (ret, TRUE);
4374   assert_equals_string (uri, "TestSourceUrl");
4375   assert_equals_int64 (range_start, 100);
4376   assert_equals_int64 (range_end, 200);
4377   g_free (uri);
4378
4379   /* get segment url and range from segment indexRange */
4380   ret =
4381       gst_mpd_client2_get_next_header_index (mpdclient, &uri, 0, &range_start,
4382       &range_end);
4383   assert_equals_int (ret, TRUE);
4384   assert_equals_string (uri, "TestSourceIndex");
4385   assert_equals_int64 (range_start, 10);
4386   assert_equals_int64 (range_end, 20);
4387   g_free (uri);
4388
4389   gst_mpd_client2_free (mpdclient);
4390 }
4391
4392 GST_END_TEST;
4393
4394 /*
4395  * Test handling fragments
4396  *
4397  */
4398 GST_START_TEST (dash_mpdparser_fragments)
4399 {
4400   GList *adaptationSets;
4401   GstMPDAdaptationSetNode *adapt_set;
4402   GstMediaFragmentInfo fragment;
4403   GstActiveStream *activeStream;
4404   GstClockTime nextFragmentDuration;
4405   GstClockTime nextFragmentTimestamp;
4406   GstClockTime nextFragmentTimestampEnd;
4407   GstClockTime periodStartTime;
4408   GstClockTime expectedDuration;
4409   GstClockTime expectedTimestamp;
4410   GstClockTime expectedTimestampEnd;
4411
4412   const gchar *xml =
4413       "<?xml version=\"1.0\"?>"
4414       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4415       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4416       "     availabilityStartTime=\"2015-03-24T0:0:0\""
4417       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4418       "  <Period id=\"Period0\" start=\"P0Y0M0DT0H0M10S\">"
4419       "    <AdaptationSet mimeType=\"video/mp4\">"
4420       "      <Representation id=\"1\" bandwidth=\"250000\">"
4421       "      </Representation></AdaptationSet></Period></MPD>";
4422
4423   gboolean ret;
4424   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4425
4426   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4427   assert_equals_int (ret, TRUE);
4428
4429   /* process the xml data */
4430   ret =
4431       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4432       -1, NULL);
4433   assert_equals_int (ret, TRUE);
4434
4435   /* get the list of adaptation sets of the first period */
4436   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
4437   fail_if (adaptationSets == NULL);
4438
4439   /* setup streaming from the first adaptation set */
4440   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4441   fail_if (adapt_set == NULL);
4442   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
4443   assert_equals_int (ret, TRUE);
4444   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
4445   fail_if (activeStream == NULL);
4446
4447   /* expected duration of the next fragment */
4448   expectedDuration = duration_to_ms (0, 0, 0, 3, 3, 20, 0);
4449   expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 0, 0);
4450   expectedTimestampEnd = duration_to_ms (0, 0, 0, 3, 3, 20, 0);
4451
4452   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
4453   assert_equals_int (ret, TRUE);
4454   assert_equals_string (fragment.uri, "");
4455   assert_equals_int64 (fragment.range_start, 0);
4456   assert_equals_int64 (fragment.range_end, -1);
4457   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4458   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4459   gst_mpdparser_media_fragment_info_clear (&fragment);
4460
4461   periodStartTime = gst_mpd_client2_get_period_start_time (mpdclient);
4462   assert_equals_uint64 (periodStartTime, 10 * GST_SECOND);
4463
4464   nextFragmentDuration =
4465       gst_mpd_client2_get_next_fragment_duration (mpdclient, activeStream);
4466   assert_equals_uint64 (nextFragmentDuration, expectedDuration * GST_MSECOND);
4467
4468   ret =
4469       gst_mpd_client2_get_next_fragment_timestamp (mpdclient, 0,
4470       &nextFragmentTimestamp);
4471   assert_equals_int (ret, TRUE);
4472   assert_equals_uint64 (nextFragmentTimestamp, expectedTimestamp * GST_MSECOND);
4473
4474   ret =
4475       gst_mpd_client2_get_last_fragment_timestamp_end (mpdclient, 0,
4476       &nextFragmentTimestampEnd);
4477   assert_equals_int (ret, TRUE);
4478   assert_equals_uint64 (nextFragmentTimestampEnd,
4479       expectedTimestampEnd * GST_MSECOND);
4480
4481   gst_mpd_client2_free (mpdclient);
4482 }
4483
4484 GST_END_TEST;
4485
4486 /*
4487  * Test inheriting segmentBase from parent
4488  *
4489  */
4490 GST_START_TEST (dash_mpdparser_inherited_segmentBase)
4491 {
4492   GstMPDPeriodNode *periodNode;
4493   GstMPDSegmentBaseNode *segmentBase;
4494   GstMPDAdaptationSetNode *adaptationSet;
4495   GstMPDRepresentationNode *representation;
4496   const gchar *xml =
4497       "<?xml version=\"1.0\"?>"
4498       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4499       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\">"
4500       "  <Period>"
4501       "    <AdaptationSet>"
4502       "      <SegmentBase timescale=\"100\">"
4503       "      </SegmentBase>"
4504       "      <Representation id=\"1\" bandwidth=\"250000\">"
4505       "        <SegmentBase timescale=\"200\">"
4506       "        </SegmentBase>"
4507       "      </Representation></AdaptationSet></Period></MPD>";
4508
4509   gboolean ret;
4510   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4511
4512   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4513   assert_equals_int (ret, TRUE);
4514
4515   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
4516   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
4517   representation = (GstMPDRepresentationNode *)
4518       adaptationSet->Representations->data;
4519
4520   /* test segment base from adaptation set */
4521   segmentBase = adaptationSet->SegmentBase;
4522   assert_equals_uint64 (segmentBase->timescale, 100);
4523
4524   /* test segment base from representation */
4525   segmentBase = representation->SegmentBase;
4526   assert_equals_uint64 (segmentBase->timescale, 200);
4527
4528   gst_mpd_client2_free (mpdclient);
4529 }
4530
4531 GST_END_TEST;
4532
4533 /*
4534  * Test inheriting segmentURL from parent
4535  *
4536  */
4537 GST_START_TEST (dash_mpdparser_inherited_segmentURL)
4538 {
4539   GList *adaptationSets;
4540   GstMPDAdaptationSetNode *adapt_set;
4541   GstActiveStream *activeStream;
4542   GstMediaFragmentInfo fragment;
4543   GstClockTime expectedDuration;
4544   GstClockTime expectedTimestamp;
4545   GstFlowReturn flow;
4546
4547   const gchar *xml =
4548       "<?xml version=\"1.0\"?>"
4549       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4550       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4551       "     availabilityStartTime=\"2015-03-24T0:0:0\""
4552       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4553       "  <Period>"
4554       "    <AdaptationSet mimeType=\"video/mp4\">"
4555       "      <SegmentList duration=\"100\">"
4556       "        <SegmentURL media=\"TestMediaAdaptation\""
4557       "                    mediaRange=\"10-20\""
4558       "                    index=\"TestIndexAdaptation\""
4559       "                    indexRange=\"30-40\">"
4560       "        </SegmentURL>"
4561       "      </SegmentList>"
4562       "      <Representation id=\"1\" bandwidth=\"250000\">"
4563       "        <SegmentList duration=\"110\">"
4564       "          <SegmentURL media=\"TestMediaRep\""
4565       "                      mediaRange=\"100-200\""
4566       "                      index=\"TestIndexRep\""
4567       "                      indexRange=\"300-400\">"
4568       "          </SegmentURL>"
4569       "        </SegmentList>"
4570       "      </Representation></AdaptationSet></Period></MPD>";
4571
4572   gboolean ret;
4573   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4574
4575   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4576   assert_equals_int (ret, TRUE);
4577
4578   /* process the xml data */
4579   ret =
4580       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4581       -1, NULL);
4582   assert_equals_int (ret, TRUE);
4583
4584   /* get the list of adaptation sets of the first period */
4585   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
4586   fail_if (adaptationSets == NULL);
4587
4588   /* setup streaming from the first adaptation set */
4589   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4590   fail_if (adapt_set == NULL);
4591   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
4592   assert_equals_int (ret, TRUE);
4593
4594   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
4595   fail_if (activeStream == NULL);
4596
4597   /* expected duration of the next fragment
4598    * Segment duration was set to 100 in AdaptationSet and to 110 in Representation
4599    * We expect duration to be 110
4600    */
4601   expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 110, 0);
4602   expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 0, 0);
4603
4604   /* the representation contains 1 segment (the one from Representation) */
4605
4606   /* check first segment */
4607   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
4608   assert_equals_int (ret, TRUE);
4609   assert_equals_string (fragment.uri, "/TestMediaRep");
4610   assert_equals_int64 (fragment.range_start, 100);
4611   assert_equals_int64 (fragment.range_end, 200);
4612   assert_equals_string (fragment.index_uri, "/TestIndexRep");
4613   assert_equals_int64 (fragment.index_range_start, 300);
4614   assert_equals_int64 (fragment.index_range_end, 400);
4615   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4616   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4617   gst_mpdparser_media_fragment_info_clear (&fragment);
4618
4619   /* try to advance to next segment. Should fail */
4620   flow = gst_mpd_client2_advance_segment (mpdclient, activeStream, TRUE);
4621   assert_equals_int (flow, GST_FLOW_EOS);
4622
4623   gst_mpd_client2_free (mpdclient);
4624 }
4625
4626 GST_END_TEST;
4627
4628 /*
4629  * Test segment list
4630  *
4631  */
4632 GST_START_TEST (dash_mpdparser_segment_list)
4633 {
4634   GList *adaptationSets;
4635   GstMPDAdaptationSetNode *adapt_set;
4636   GstActiveStream *activeStream;
4637   GstMediaFragmentInfo fragment;
4638   GstClockTime expectedDuration;
4639   GstClockTime expectedTimestamp;
4640   const gchar *xml =
4641       "<?xml version=\"1.0\"?>"
4642       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4643       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4644       "     availabilityStartTime=\"2015-03-24T0:0:0\""
4645       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4646       "  <Period start=\"P0Y0M0DT0H0M10S\">"
4647       "    <AdaptationSet mimeType=\"video/mp4\">"
4648       "      <Representation id=\"1\" bandwidth=\"250000\">"
4649       "        <SegmentList duration=\"12000\">"
4650       "          <SegmentURL media=\"TestMedia\""
4651       "                      mediaRange=\"100-200\""
4652       "                      index=\"TestIndex\""
4653       "                      indexRange=\"300-400\">"
4654       "          </SegmentURL>"
4655       "        </SegmentList>"
4656       "      </Representation></AdaptationSet></Period></MPD>";
4657
4658   gboolean ret;
4659   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4660
4661   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4662   assert_equals_int (ret, TRUE);
4663
4664   /* process the xml data */
4665   ret =
4666       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4667       -1, NULL);
4668   assert_equals_int (ret, TRUE);
4669
4670   /* get the list of adaptation sets of the first period */
4671   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
4672   fail_if (adaptationSets == NULL);
4673
4674   /* setup streaming from the first adaptation set */
4675   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4676   fail_if (adapt_set == NULL);
4677   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
4678   assert_equals_int (ret, TRUE);
4679
4680   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
4681   fail_if (activeStream == NULL);
4682
4683   /* expected duration of the next fragment
4684    * Segment duration was set larger than period duration (12000 vs 11000).
4685    * We expect it to be limited to period duration.
4686    */
4687   expectedDuration = duration_to_ms (0, 0, 0, 3, 3, 20, 0);
4688   expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 10, 0);
4689
4690   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
4691   assert_equals_int (ret, TRUE);
4692   assert_equals_string (fragment.uri, "/TestMedia");
4693   assert_equals_int64 (fragment.range_start, 100);
4694   assert_equals_int64 (fragment.range_end, 200);
4695   assert_equals_string (fragment.index_uri, "/TestIndex");
4696   assert_equals_int64 (fragment.index_range_start, 300);
4697   assert_equals_int64 (fragment.index_range_end, 400);
4698   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4699   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4700
4701   gst_mpdparser_media_fragment_info_clear (&fragment);
4702
4703   gst_mpd_client2_free (mpdclient);
4704 }
4705
4706 GST_END_TEST;
4707
4708 /*
4709  * Test segment template
4710  *
4711  */
4712 GST_START_TEST (dash_mpdparser_segment_template)
4713 {
4714   GList *adaptationSets;
4715   GstMPDAdaptationSetNode *adapt_set;
4716   GstActiveStream *activeStream;
4717   GstMediaFragmentInfo fragment;
4718   GstClockTime expectedDuration;
4719   GstClockTime expectedTimestamp;
4720   GstClockTime periodStartTime;
4721   GstClockTime offset;
4722   GstClockTime lastFragmentTimestampEnd;
4723   const gchar *xml =
4724       "<?xml version=\"1.0\"?>"
4725       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4726       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4727       "     availabilityStartTime=\"2015-03-24T0:0:0\""
4728       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4729       "  <Period start=\"P0Y0M0DT0H0M10S\">"
4730       "    <AdaptationSet mimeType=\"video/mp4\">"
4731       "      <Representation id=\"repId\" bandwidth=\"250000\">"
4732       "        <SegmentTemplate duration=\"12000\""
4733       "                         presentationTimeOffset=\"15\""
4734       "                         media=\"TestMedia_rep=$RepresentationID$number=$Number$bandwidth=$Bandwidth$time=$Time$\""
4735       "                         index=\"TestIndex\">"
4736       "        </SegmentTemplate>"
4737       "      </Representation></AdaptationSet></Period></MPD>";
4738
4739   gboolean ret;
4740   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4741
4742   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4743   assert_equals_int (ret, TRUE);
4744
4745   /* process the xml data */
4746   ret =
4747       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4748       -1, NULL);
4749   assert_equals_int (ret, TRUE);
4750
4751   /* get the list of adaptation sets of the first period */
4752   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
4753   fail_if (adaptationSets == NULL);
4754
4755   /* setup streaming from the first adaptation set */
4756   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4757   fail_if (adapt_set == NULL);
4758   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
4759   assert_equals_int (ret, TRUE);
4760
4761   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
4762   fail_if (activeStream == NULL);
4763
4764   /* expected duration of the next fragment
4765    * Segment duration was set larger than period duration (12000 vs 11000).
4766    * We expect it to not be limited to period duration.
4767    */
4768   expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 12000, 0);
4769
4770   /* while the period starts at 10ms, the fragment timestamp is supposed to be
4771    * 0ms. timestamps are starting from 0 at every period, and only the overall
4772    * composition of periods should consider the period start timestamp. In
4773    * dashdemux this is done by mapping the 0 fragment timestamp to a stream
4774    * time equal to the period start time.
4775    */
4776   expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 0, 0);
4777
4778   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
4779   assert_equals_int (ret, TRUE);
4780   assert_equals_string (fragment.uri,
4781       "/TestMedia_rep=repIdnumber=1bandwidth=250000time=0");
4782   assert_equals_int64 (fragment.range_start, 0);
4783   assert_equals_int64 (fragment.range_end, -1);
4784   assert_equals_string (fragment.index_uri, "/TestIndex");
4785   assert_equals_int64 (fragment.index_range_start, 0);
4786   assert_equals_int64 (fragment.index_range_end, -1);
4787   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4788   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4789
4790   periodStartTime = gst_mpd_client2_get_period_start_time (mpdclient);
4791   assert_equals_uint64 (periodStartTime, 10 * GST_SECOND);
4792
4793   offset = gst_mpd_client2_get_stream_presentation_offset (mpdclient, 0);
4794   assert_equals_uint64 (offset, 15 * GST_SECOND);
4795
4796   gst_mpdparser_media_fragment_info_clear (&fragment);
4797
4798   /*
4799    * Period starts at 10s.
4800    * MPD has a duration of 3h3m30s, so period duration is 3h3m20s.
4801    * We expect the last fragment to end at period start + period duration: 3h3m30s
4802    */
4803   expectedTimestamp = duration_to_ms (0, 0, 0, 3, 3, 30, 0);
4804   ret = gst_mpd_client2_get_last_fragment_timestamp_end (mpdclient, 0,
4805       &lastFragmentTimestampEnd);
4806   assert_equals_int (ret, TRUE);
4807   assert_equals_uint64 (lastFragmentTimestampEnd,
4808       expectedTimestamp * GST_MSECOND);
4809
4810   gst_mpd_client2_free (mpdclient);
4811 }
4812
4813 GST_END_TEST;
4814
4815 /*
4816  * Test segment timeline
4817  *
4818  */
4819 GST_START_TEST (dash_mpdparser_segment_timeline)
4820 {
4821   GList *adaptationSets;
4822   GstMPDAdaptationSetNode *adapt_set;
4823   GstActiveStream *activeStream;
4824   GstMediaFragmentInfo fragment;
4825   GstClockTime expectedDuration;
4826   GstClockTime expectedTimestamp;
4827   GstFlowReturn flow;
4828   GstDateTime *segmentAvailability;
4829
4830   const gchar *xml =
4831       "<?xml version=\"1.0\"?>"
4832       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
4833       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
4834       "     availabilityStartTime=\"2015-03-24T0:0:0\""
4835       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
4836       "  <Period start=\"P0Y0M0DT0H0M10S\">"
4837       "    <AdaptationSet mimeType=\"video/mp4\">"
4838       "      <SegmentList>"
4839       "        <SegmentTimeline>"
4840       "          <S t=\"10\"  d=\"20\" r=\"30\"></S>"
4841       "        </SegmentTimeline>"
4842       "      </SegmentList>"
4843       "      <Representation id=\"1\" bandwidth=\"250000\">"
4844       "        <SegmentList>"
4845       "          <SegmentTimeline>"
4846       "            <S t=\"3\"  d=\"2\" r=\"1\"></S>"
4847       "            <S t=\"10\" d=\"3\" r=\"0\"></S>"
4848       "          </SegmentTimeline>"
4849       "          <SegmentURL media=\"TestMedia0\""
4850       "                      index=\"TestIndex0\">"
4851       "          </SegmentURL>"
4852       "          <SegmentURL media=\"TestMedia1\""
4853       "                      index=\"TestIndex1\">"
4854       "          </SegmentURL>"
4855       "        </SegmentList>"
4856       "      </Representation></AdaptationSet></Period></MPD>";
4857
4858   gboolean ret;
4859   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
4860
4861   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
4862   assert_equals_int (ret, TRUE);
4863
4864   /* process the xml data */
4865   ret =
4866       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
4867       -1, NULL);
4868   assert_equals_int (ret, TRUE);
4869
4870   /* get the list of adaptation sets of the first period */
4871   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
4872   fail_if (adaptationSets == NULL);
4873
4874   /* setup streaming from the first adaptation set */
4875   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
4876   fail_if (adapt_set == NULL);
4877   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
4878   assert_equals_int (ret, TRUE);
4879
4880   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
4881   fail_if (activeStream == NULL);
4882
4883   /* expected duration of the next fragment */
4884   expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 2, 0);
4885   expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 13, 0);
4886
4887   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
4888   assert_equals_int (ret, TRUE);
4889   assert_equals_string (fragment.uri, "/TestMedia0");
4890   assert_equals_string (fragment.index_uri, "/TestIndex0");
4891   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4892   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4893   gst_mpdparser_media_fragment_info_clear (&fragment);
4894
4895   /* first segment starts at 3s and has a duration of 2s.
4896    * We also add period start time (10s) so we expect a segment availability
4897    * start time of 15s
4898    */
4899   segmentAvailability =
4900       gst_mpd_client2_get_next_segment_availability_start_time (mpdclient,
4901       activeStream);
4902   fail_unless (segmentAvailability != NULL);
4903   assert_equals_int (gst_date_time_get_year (segmentAvailability), 2015);
4904   assert_equals_int (gst_date_time_get_month (segmentAvailability), 3);
4905   assert_equals_int (gst_date_time_get_day (segmentAvailability), 24);
4906   assert_equals_int (gst_date_time_get_hour (segmentAvailability), 0);
4907   assert_equals_int (gst_date_time_get_minute (segmentAvailability), 0);
4908   assert_equals_int (gst_date_time_get_second (segmentAvailability), 15);
4909   gst_date_time_unref (segmentAvailability);
4910
4911   /* advance to next segment */
4912   flow = gst_mpd_client2_advance_segment (mpdclient, activeStream, TRUE);
4913   assert_equals_int (flow, GST_FLOW_OK);
4914
4915   /* second segment starts after first ends */
4916   expectedTimestamp = expectedTimestamp + expectedDuration;
4917
4918   /* check second segment.
4919    * It is a repeat of first segmentURL, because "r" in SegmentTimeline is 1
4920    */
4921   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
4922   assert_equals_int (ret, TRUE);
4923   assert_equals_string (fragment.uri, "/TestMedia0");
4924   assert_equals_string (fragment.index_uri, "/TestIndex0");
4925   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4926   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4927   gst_mpdparser_media_fragment_info_clear (&fragment);
4928
4929   /* first segment starts at 3s and has a duration of 2s.
4930    * Second segment starts when the first ends (5s) and has a duration of 2s,
4931    * so it ends at 7s.
4932    * We also add period start time (10s) so we expect a segment availability
4933    * start time of 17s
4934    */
4935   segmentAvailability =
4936       gst_mpd_client2_get_next_segment_availability_start_time (mpdclient,
4937       activeStream);
4938   fail_unless (segmentAvailability != NULL);
4939   assert_equals_int (gst_date_time_get_year (segmentAvailability), 2015);
4940   assert_equals_int (gst_date_time_get_month (segmentAvailability), 3);
4941   assert_equals_int (gst_date_time_get_day (segmentAvailability), 24);
4942   assert_equals_int (gst_date_time_get_hour (segmentAvailability), 0);
4943   assert_equals_int (gst_date_time_get_minute (segmentAvailability), 0);
4944   assert_equals_int (gst_date_time_get_second (segmentAvailability), 17);
4945   gst_date_time_unref (segmentAvailability);
4946
4947   /* advance to next segment */
4948   flow = gst_mpd_client2_advance_segment (mpdclient, activeStream, TRUE);
4949   assert_equals_int (flow, GST_FLOW_OK);
4950
4951   /* third segment has a small gap after the second ends  (t=10) */
4952   expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 3, 0);
4953   expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 20, 0);
4954
4955   /* check third segment */
4956   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
4957   assert_equals_int (ret, TRUE);
4958   assert_equals_string (fragment.uri, "/TestMedia1");
4959   assert_equals_string (fragment.index_uri, "/TestIndex1");
4960   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
4961   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
4962   gst_mpdparser_media_fragment_info_clear (&fragment);
4963
4964   /* Third segment starts at 10s and has a duration of 3s so it ends at 13s.
4965    * We also add period start time (10s) so we expect a segment availability
4966    * start time of 23s
4967    */
4968   segmentAvailability =
4969       gst_mpd_client2_get_next_segment_availability_start_time (mpdclient,
4970       activeStream);
4971   fail_unless (segmentAvailability != NULL);
4972   assert_equals_int (gst_date_time_get_year (segmentAvailability), 2015);
4973   assert_equals_int (gst_date_time_get_month (segmentAvailability), 3);
4974   assert_equals_int (gst_date_time_get_day (segmentAvailability), 24);
4975   assert_equals_int (gst_date_time_get_hour (segmentAvailability), 0);
4976   assert_equals_int (gst_date_time_get_minute (segmentAvailability), 0);
4977   assert_equals_int (gst_date_time_get_second (segmentAvailability), 23);
4978   gst_date_time_unref (segmentAvailability);
4979
4980   gst_mpd_client2_free (mpdclient);
4981 }
4982
4983 GST_END_TEST;
4984
4985 /*
4986  * Test SegmentList with multiple inherited segmentURLs
4987  *
4988  */
4989 GST_START_TEST (dash_mpdparser_multiple_inherited_segmentURL)
4990 {
4991   GList *adaptationSets;
4992   GstMPDAdaptationSetNode *adapt_set;
4993   GstActiveStream *activeStream;
4994   GstMediaFragmentInfo fragment;
4995   GstClockTime expectedDuration;
4996   GstClockTime expectedTimestamp;
4997   GstFlowReturn flow;
4998
4999   /*
5000    * Period duration is 30 seconds
5001    * Period start is 10 seconds. Thus, period duration is 20 seconds.
5002    *
5003    * There are 2 segments in the AdaptationSet segment list and 2 in the
5004    * Representation's segment list.
5005    * Segment duration is 5s for the Adaptation segments and 8s for
5006    * Representation segments.
5007    * Separately, each segment list (duration 2*5=10 or 2*8=16) fits comfortably
5008    * in the Period's 20s duration.
5009    *
5010    * We expect the Representation segments to overwrite the AdaptationSet segments.
5011    */
5012   const gchar *xml =
5013       "<?xml version=\"1.0\"?>"
5014       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5015       " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5016       " availabilityStartTime=\"2015-03-24T0:0:0\""
5017       " mediaPresentationDuration=\"P0Y0M0DT0H0M30S\">"
5018       "<Period>"
5019       "  <AdaptationSet mimeType=\"video/mp4\">"
5020       "    <SegmentList duration=\"5\">"
5021       "      <SegmentURL"
5022       "         media=\"TestMedia0\" mediaRange=\"10-20\""
5023       "         index=\"TestIndex0\" indexRange=\"100-200\""
5024       "      ></SegmentURL>"
5025       "      <SegmentURL"
5026       "         media=\"TestMedia1\" mediaRange=\"20-30\""
5027       "         index=\"TestIndex1\" indexRange=\"200-300\""
5028       "      ></SegmentURL>"
5029       "    </SegmentList>"
5030       "    <Representation id=\"1\" bandwidth=\"250000\">"
5031       "      <SegmentList duration=\"8\">"
5032       "        <SegmentURL"
5033       "           media=\"TestMedia2\" mediaRange=\"30-40\""
5034       "           index=\"TestIndex2\" indexRange=\"300-400\""
5035       "        ></SegmentURL>"
5036       "        <SegmentURL"
5037       "           media=\"TestMedia3\" mediaRange=\"40-50\""
5038       "           index=\"TestIndex3\" indexRange=\"400-500\""
5039       "        ></SegmentURL>"
5040       "      </SegmentList>"
5041       "    </Representation></AdaptationSet></Period></MPD>";
5042
5043   gboolean ret;
5044   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5045
5046   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5047   assert_equals_int (ret, TRUE);
5048
5049   /* process the xml data */
5050   ret =
5051       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5052       -1, NULL);
5053   assert_equals_int (ret, TRUE);
5054
5055   /* get the list of adaptation sets of the first period */
5056   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
5057   fail_if (adaptationSets == NULL);
5058
5059   /* setup streaming from the first adaptation set */
5060   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
5061   fail_if (adapt_set == NULL);
5062   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
5063   assert_equals_int (ret, TRUE);
5064
5065   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
5066   fail_if (activeStream == NULL);
5067
5068   expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 8, 0);
5069   expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 0, 0);
5070
5071   /* the representation contains 2 segments defined in the Representation
5072    *
5073    * Both will have the duration specified in the Representation (8)
5074    */
5075
5076   /* check first segment */
5077   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
5078   assert_equals_int (ret, TRUE);
5079   assert_equals_string (fragment.uri, "/TestMedia2");
5080   assert_equals_int64 (fragment.range_start, 30);
5081   assert_equals_int64 (fragment.range_end, 40);
5082   assert_equals_string (fragment.index_uri, "/TestIndex2");
5083   assert_equals_int64 (fragment.index_range_start, 300);
5084   assert_equals_int64 (fragment.index_range_end, 400);
5085   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
5086   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
5087   gst_mpdparser_media_fragment_info_clear (&fragment);
5088
5089   /* advance to next segment */
5090   flow = gst_mpd_client2_advance_segment (mpdclient, activeStream, TRUE);
5091   assert_equals_int (flow, GST_FLOW_OK);
5092
5093   /* second segment starts after previous ends */
5094   expectedTimestamp = expectedTimestamp + expectedDuration;
5095
5096   /* check second segment */
5097   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
5098   assert_equals_int (ret, TRUE);
5099   assert_equals_string (fragment.uri, "/TestMedia3");
5100   assert_equals_int64 (fragment.range_start, 40);
5101   assert_equals_int64 (fragment.range_end, 50);
5102   assert_equals_string (fragment.index_uri, "/TestIndex3");
5103   assert_equals_int64 (fragment.index_range_start, 400);
5104   assert_equals_int64 (fragment.index_range_end, 500);
5105   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
5106   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
5107   gst_mpdparser_media_fragment_info_clear (&fragment);
5108
5109   /* try to advance to the next segment. There isn't any, so it should fail */
5110   flow = gst_mpd_client2_advance_segment (mpdclient, activeStream, TRUE);
5111   assert_equals_int (flow, GST_FLOW_EOS);
5112
5113   gst_mpd_client2_free (mpdclient);
5114 }
5115
5116 GST_END_TEST;
5117
5118 /*
5119  * Test SegmentList with multiple segmentURL
5120  *
5121  */
5122 GST_START_TEST (dash_mpdparser_multipleSegmentURL)
5123 {
5124   GList *adaptationSets;
5125   GstMPDAdaptationSetNode *adapt_set;
5126   GstActiveStream *activeStream;
5127   GstMediaFragmentInfo fragment;
5128   GstClockTime expectedDuration;
5129   GstClockTime expectedTimestamp;
5130   GstFlowReturn flow;
5131
5132   /*
5133    * Period duration is 30 seconds
5134    * Period start is 10 seconds. Thus, period duration is 20 seconds.
5135    *
5136    * Segment duration is 25 seconds. There are 2 segments in the list.
5137    * We expect first segment to have a duration of 20 seconds (limited by the period)
5138    * and the second segment to not exist.
5139    */
5140   const gchar *xml =
5141       "<?xml version=\"1.0\"?>"
5142       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5143       " profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5144       " availabilityStartTime=\"2015-03-24T0:0:0\""
5145       " mediaPresentationDuration=\"P0Y0M0DT0H0M30S\">"
5146       "<Period start=\"P0Y0M0DT0H0M10S\">"
5147       "  <AdaptationSet mimeType=\"video/mp4\">"
5148       "    <Representation id=\"1\" bandwidth=\"250000\">"
5149       "      <SegmentList duration=\"25\">"
5150       "        <SegmentURL"
5151       "           media=\"TestMedia0\" mediaRange=\"10-20\""
5152       "           index=\"TestIndex0\" indexRange=\"100-200\""
5153       "        ></SegmentURL>"
5154       "        <SegmentURL"
5155       "           media=\"TestMedia1\" mediaRange=\"20-30\""
5156       "           index=\"TestIndex1\" indexRange=\"200-300\""
5157       "        ></SegmentURL>"
5158       "      </SegmentList>"
5159       "    </Representation></AdaptationSet></Period></MPD>";
5160
5161   gboolean ret;
5162   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5163
5164   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5165   assert_equals_int (ret, TRUE);
5166
5167   /* process the xml data */
5168   ret =
5169       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5170       -1, NULL);
5171   assert_equals_int (ret, TRUE);
5172
5173   /* get the list of adaptation sets of the first period */
5174   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
5175   fail_if (adaptationSets == NULL);
5176
5177   /* setup streaming from the first adaptation set */
5178   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
5179   fail_if (adapt_set == NULL);
5180   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
5181   assert_equals_int (ret, TRUE);
5182
5183   activeStream = gst_mpd_client2_get_active_stream_by_index (mpdclient, 0);
5184   fail_if (activeStream == NULL);
5185
5186   expectedDuration = duration_to_ms (0, 0, 0, 0, 0, 20, 0);
5187   expectedTimestamp = duration_to_ms (0, 0, 0, 0, 0, 10, 0);
5188
5189   /* the representation contains 2 segments. The first is partially
5190    * clipped, and the second entirely (and thus discarded).
5191    */
5192
5193   /* check first segment */
5194   ret = gst_mpd_client2_get_next_fragment (mpdclient, 0, &fragment);
5195   assert_equals_int (ret, TRUE);
5196   assert_equals_string (fragment.uri, "/TestMedia0");
5197   assert_equals_int64 (fragment.range_start, 10);
5198   assert_equals_int64 (fragment.range_end, 20);
5199   assert_equals_string (fragment.index_uri, "/TestIndex0");
5200   assert_equals_int64 (fragment.index_range_start, 100);
5201   assert_equals_int64 (fragment.index_range_end, 200);
5202   assert_equals_uint64 (fragment.duration, expectedDuration * GST_MSECOND);
5203   assert_equals_uint64 (fragment.timestamp, expectedTimestamp * GST_MSECOND);
5204   gst_mpdparser_media_fragment_info_clear (&fragment);
5205
5206   /* advance to next segment */
5207   flow = gst_mpd_client2_advance_segment (mpdclient, activeStream, TRUE);
5208   assert_equals_int (flow, GST_FLOW_EOS);
5209
5210   gst_mpd_client2_free (mpdclient);
5211 }
5212
5213 GST_END_TEST;
5214
5215 /*
5216  * Test parsing empty xml string
5217  *
5218  */
5219 GST_START_TEST (dash_mpdparser_missing_xml)
5220 {
5221   const gchar *xml = "";
5222
5223   gboolean ret;
5224   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5225
5226   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5227   assert_equals_int (ret, FALSE);
5228
5229   gst_mpd_client2_free (mpdclient);
5230 }
5231
5232 GST_END_TEST;
5233
5234 /*
5235  * Test parsing an xml with no mpd tag
5236  *
5237  */
5238 GST_START_TEST (dash_mpdparser_missing_mpd)
5239 {
5240   const gchar *xml = "<?xml version=\"1.0\"?>";
5241
5242   gboolean ret;
5243   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5244
5245   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5246   assert_equals_int (ret, FALSE);
5247
5248   gst_mpd_client2_free (mpdclient);
5249 }
5250
5251 GST_END_TEST;
5252
5253 /*
5254  * Test parsing an MPD with a wrong end tag
5255  */
5256 GST_START_TEST (dash_mpdparser_no_end_tag)
5257 {
5258   const gchar *xml =
5259       "<?xml version=\"1.0\"?>"
5260       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5261       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"> </NPD>";
5262
5263   gboolean ret;
5264   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5265
5266   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5267   assert_equals_int (ret, FALSE);
5268
5269   gst_mpd_client2_free (mpdclient);
5270 }
5271
5272 GST_END_TEST;
5273
5274 /*
5275  * Test parsing an MPD with no default namespace
5276  */
5277 GST_START_TEST (dash_mpdparser_no_default_namespace)
5278 {
5279   const gchar *xml =
5280       "<?xml version=\"1.0\"?>"
5281       "<MPD profiles=\"urn:mpeg:dash:profile:isoff-main:2011\"></MPD>";
5282
5283   gboolean ret;
5284   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5285
5286   ret = gst_mpd_client2_parse (mpdclient, xml, strlen (xml));
5287   assert_equals_int (ret, TRUE);
5288
5289   gst_mpd_client2_free (mpdclient);
5290 }
5291
5292 GST_END_TEST;
5293
5294 /*
5295  * Test handling wrong period duration during attempts to
5296  * infer a period duration from the start time of the next period
5297  */
5298 GST_START_TEST (dash_mpdparser_wrong_period_duration_inferred_from_next_period)
5299 {
5300   const gchar *periodName;
5301
5302   const gchar *xml =
5303       "<?xml version=\"1.0\"?>"
5304       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5305       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5306       "     availabilityStartTime=\"2015-03-24T0:0:0\""
5307       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
5308       "  <Period id=\"Period0\" duration=\"P0Y0M0DT1H1M0S\"></Period>"
5309       "  <Period id=\"Period1\"></Period>"
5310       "  <Period id=\"Period2\" start=\"P0Y0M0DT0H0M10S\"></Period></MPD>";
5311
5312   gboolean ret;
5313   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5314
5315   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5316   assert_equals_int (ret, TRUE);
5317
5318   /* period_idx should be 0 and we should have no active periods */
5319   assert_equals_uint64 (mpdclient->period_idx, 0);
5320   fail_unless (mpdclient->periods == NULL);
5321
5322   /* process the xml data */
5323   ret =
5324       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5325       -1, NULL);
5326   assert_equals_int (ret, TRUE);
5327
5328   /* Period0 should be present */
5329   fail_unless (mpdclient->periods != NULL);
5330   periodName = gst_mpd_client2_get_period_id (mpdclient);
5331   assert_equals_string (periodName, "Period0");
5332
5333   /* Period1 should not be present due to wrong duration */
5334   ret = gst_mpd_client2_set_period_index (mpdclient, 1);
5335   assert_equals_int (ret, FALSE);
5336
5337   gst_mpd_client2_free (mpdclient);
5338 }
5339
5340 GST_END_TEST;
5341
5342 /*
5343  * Test handling wrong period duration during attempts to
5344  * infer a period duration from the mediaPresentationDuration
5345  */
5346 GST_START_TEST
5347     (dash_mpdparser_wrong_period_duration_inferred_from_next_mediaPresentationDuration)
5348 {
5349   const gchar *xml =
5350       "<?xml version=\"1.0\"?>"
5351       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5352       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5353       "     availabilityStartTime=\"2015-03-24T0:0:0\""
5354       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
5355       "  <Period id=\"Period0\" start=\"P0Y0M0DT4H0M0S\"></Period></MPD>";
5356
5357   gboolean ret;
5358   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5359
5360   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5361   assert_equals_int (ret, TRUE);
5362
5363   /* period_idx should be 0 and we should have no active periods */
5364   assert_equals_uint64 (mpdclient->period_idx, 0);
5365   fail_unless (mpdclient->periods == NULL);
5366
5367   /* process the xml data
5368    * should fail due to wrong duration in Period0 (start > mediaPresentationDuration)
5369    */
5370   ret =
5371       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5372       -1, NULL);
5373   assert_equals_int (ret, FALSE);
5374
5375   gst_mpd_client2_free (mpdclient);
5376 }
5377
5378 GST_END_TEST;
5379
5380 GST_START_TEST (dash_mpdparser_whitespace_strings)
5381 {
5382   fail_unless (_mpd_helper_validate_no_whitespace ("") == TRUE);
5383   fail_unless (_mpd_helper_validate_no_whitespace ("/") == TRUE);
5384   fail_unless (_mpd_helper_validate_no_whitespace (" ") == FALSE);
5385   fail_unless (_mpd_helper_validate_no_whitespace ("aaaaaaaa ") == FALSE);
5386   fail_unless (_mpd_helper_validate_no_whitespace ("a\ta") == FALSE);
5387   fail_unless (_mpd_helper_validate_no_whitespace ("a\ra") == FALSE);
5388   fail_unless (_mpd_helper_validate_no_whitespace ("a\na") == FALSE);
5389 }
5390
5391 GST_END_TEST;
5392
5393 GST_START_TEST (dash_mpdparser_rfc1738_strings)
5394 {
5395   fail_unless (gst_mpdparser_validate_rfc1738_url ("/") == TRUE);
5396   fail_unless (gst_mpdparser_validate_rfc1738_url (" ") == FALSE);
5397   fail_unless (gst_mpdparser_validate_rfc1738_url ("aaaaaaaa ") == FALSE);
5398
5399   fail_unless (gst_mpdparser_validate_rfc1738_url ("") == TRUE);
5400   fail_unless (gst_mpdparser_validate_rfc1738_url ("a") == TRUE);
5401   fail_unless (gst_mpdparser_validate_rfc1738_url
5402       (";:@&=aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789$-_.+!*'(),%AA")
5403       == TRUE);
5404   fail_unless (gst_mpdparser_validate_rfc1738_url
5405       (";:@&=aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789$-_.+!*'(),/%AA")
5406       == TRUE);
5407   fail_unless (gst_mpdparser_validate_rfc1738_url
5408       (";:@&=aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789$-_.+!*'(),% ")
5409       == FALSE);
5410   fail_unless (gst_mpdparser_validate_rfc1738_url ("%AA") == TRUE);
5411   fail_unless (gst_mpdparser_validate_rfc1738_url ("%A") == FALSE);
5412   fail_unless (gst_mpdparser_validate_rfc1738_url ("%") == FALSE);
5413   fail_unless (gst_mpdparser_validate_rfc1738_url ("%XA") == FALSE);
5414   fail_unless (gst_mpdparser_validate_rfc1738_url ("%AX") == FALSE);
5415   fail_unless (gst_mpdparser_validate_rfc1738_url ("%XX") == FALSE);
5416   fail_unless (gst_mpdparser_validate_rfc1738_url ("\001") == FALSE);
5417 }
5418
5419 GST_END_TEST;
5420
5421 /*
5422  * Test negative period duration
5423  */
5424 GST_START_TEST (dash_mpdparser_negative_period_duration)
5425 {
5426   const gchar *xml =
5427       "<?xml version=\"1.0\"?>"
5428       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5429       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5430       "     availabilityStartTime=\"2015-03-24T0:0:0\""
5431       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
5432       "  <Period id=\"Period0\""
5433       "          start=\"P0Y0M0DT1H0M0S\""
5434       "          duration=\"-PT10S\">"
5435       "  </Period><Period id=\"Period1\"></Period></MPD>";
5436
5437   gboolean ret;
5438   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5439
5440   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5441   assert_equals_int (ret, TRUE);
5442
5443   /* process the xml data
5444    * should fail due to negative duration of Period0
5445    */
5446   ret =
5447       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5448       -1, NULL);
5449   assert_equals_int (ret, FALSE);
5450
5451   gst_mpd_client2_free (mpdclient);
5452 }
5453
5454 GST_END_TEST;
5455
5456 /*
5457  * Test parsing negative values from attributes that should be unsigned
5458  *
5459  */
5460 GST_START_TEST (dash_mpdparser_read_unsigned_from_negative_values)
5461 {
5462   GstMPDPeriodNode *periodNode;
5463   GstMPDSegmentBaseNode *segmentBase;
5464   GstMPDAdaptationSetNode *adaptationSet;
5465   GstMPDRepresentationNode *representation;
5466   GstMPDSubRepresentationNode *subRepresentation;
5467
5468   const gchar *xml =
5469       "<?xml version=\"1.0\"?>"
5470       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5471       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5472       "     availabilityStartTime=\"2015--1-13T12:25:37\">"
5473       "  <Period start=\"-P-2015Y\" duration=\"-P-5M\">"
5474       "    <SegmentBase presentationTimeOffset=\"-10\""
5475       "                 timescale=\"-5\""
5476       "                 indexRange=\"1--10\">"
5477       "    </SegmentBase>"
5478       "    <AdaptationSet par=\"-1:7\""
5479       "                   minFrameRate=\" -1\""
5480       "                   segmentAlignment=\"-4\">"
5481       "      <Representation id=\"1\" bandwidth=\"250000\">"
5482       "        <SubRepresentation dependencyLevel=\"1 -2 3\">"
5483       "        </SubRepresentation>"
5484       "      </Representation></AdaptationSet></Period></MPD>";
5485
5486   gboolean ret;
5487   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5488
5489   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5490   assert_equals_int (ret, TRUE);
5491
5492   periodNode = (GstMPDPeriodNode *) mpdclient->mpd_root_node->Periods->data;
5493   segmentBase = periodNode->SegmentBase;
5494   adaptationSet = (GstMPDAdaptationSetNode *) periodNode->AdaptationSets->data;
5495   representation = (GstMPDRepresentationNode *)
5496       adaptationSet->Representations->data;
5497   subRepresentation = (GstMPDSubRepresentationNode *)
5498       representation->SubRepresentations->data;
5499
5500   /* availabilityStartTime parsing should fail */
5501   fail_if (mpdclient->mpd_root_node->availabilityStartTime != NULL);
5502
5503   /* Period start parsing should fail */
5504   assert_equals_int64 (periodNode->start, -1);
5505
5506   /* Period duration parsing should fail */
5507   assert_equals_int64 (periodNode->duration, -1);
5508
5509   /* expect negative value to be rejected and presentationTimeOffset to be 0 */
5510   assert_equals_uint64 (segmentBase->presentationTimeOffset, 0);
5511   assert_equals_uint64 (segmentBase->timescale, 1);
5512   fail_if (segmentBase->indexRange != NULL);
5513
5514   /* par ratio parsing should fail */
5515   fail_if (adaptationSet->par != NULL);
5516
5517   /* minFrameRate parsing should fail */
5518   fail_if (GST_MPD_REPRESENTATION_BASE_NODE (adaptationSet)->minFrameRate !=
5519       NULL);
5520
5521   /* segmentAlignment parsing should fail */
5522   fail_if (adaptationSet->segmentAlignment != NULL);
5523
5524   /* dependency level parsing should fail */
5525   fail_if (subRepresentation->dependencyLevel != NULL);
5526
5527   gst_mpd_client2_free (mpdclient);
5528 }
5529
5530 GST_END_TEST;
5531
5532 /*
5533  * Test negative mediaPresentationDuration duration
5534  */
5535 GST_START_TEST (dash_mpdparser_negative_mediaPresentationDuration)
5536 {
5537   const gchar *xml =
5538       "<?xml version=\"1.0\"?>"
5539       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5540       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5541       "     availabilityStartTime=\"2015-03-24T0:0:0\""
5542       "     mediaPresentationDuration=\"-P0Y0M0DT3H3M30S\">"
5543       "  <Period id=\"Period0\" start=\"P0Y0M0DT1H0M0S\"></Period></MPD>";
5544
5545   gboolean ret;
5546   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5547
5548   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5549   assert_equals_int (ret, TRUE);
5550
5551   /* process the xml data
5552    * should fail due to negative duration of mediaPresentationDuration
5553    */
5554   ret =
5555       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5556       -1, NULL);
5557   assert_equals_int (ret, FALSE);
5558
5559   gst_mpd_client2_free (mpdclient);
5560 }
5561
5562 GST_END_TEST;
5563
5564 /*
5565  * Test parsing an MPD with no profiles
5566  */
5567 GST_START_TEST (dash_mpdparser_no_profiles)
5568 {
5569   const gchar *xml =
5570       "<?xml version=\"1.0\"?>"
5571       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\"></MPD>";
5572
5573   gboolean ret;
5574   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5575
5576   ret = gst_mpd_client2_parse (mpdclient, xml, strlen (xml));
5577
5578   assert_equals_int (ret, TRUE);
5579
5580   gst_mpd_client2_free (mpdclient);
5581 }
5582
5583 GST_END_TEST;
5584
5585 /*
5586  * Test S node list greater than SegmentURL list
5587  *
5588  */
5589 GST_START_TEST (dash_mpdparser_unmatched_segmentTimeline_segmentURL)
5590 {
5591   GList *adaptationSets;
5592   GstMPDAdaptationSetNode *adapt_set;
5593
5594   const gchar *xml =
5595       "<?xml version=\"1.0\"?>"
5596       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5597       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5598       "     availabilityStartTime=\"2015-03-24T0:0:0\""
5599       "     mediaPresentationDuration=\"P0Y0M0DT3H3M30S\">"
5600       "  <Period start=\"P0Y0M0DT0H0M10S\">"
5601       "    <AdaptationSet mimeType=\"video/mp4\">"
5602       "      <Representation id=\"1\" bandwidth=\"250000\">"
5603       "        <SegmentList>"
5604       "          <SegmentTimeline>"
5605       "            <S t=\"3\"  d=\"2\" r=\"1\"></S>"
5606       "            <S t=\"10\" d=\"3\" r=\"0\"></S>"
5607       "          </SegmentTimeline>"
5608       "          <SegmentURL media=\"TestMedia0\""
5609       "                      index=\"TestIndex0\">"
5610       "          </SegmentURL>"
5611       "        </SegmentList>"
5612       "      </Representation></AdaptationSet></Period></MPD>";
5613
5614   gboolean ret;
5615   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5616
5617   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5618   assert_equals_int (ret, TRUE);
5619
5620   /* process the xml data */
5621   ret =
5622       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5623       -1, NULL);
5624   assert_equals_int (ret, TRUE);
5625
5626   /* get the list of adaptation sets of the first period */
5627   adaptationSets = gst_mpd_client2_get_adaptation_sets (mpdclient);
5628   fail_if (adaptationSets == NULL);
5629
5630   adapt_set = (GstMPDAdaptationSetNode *) g_list_nth_data (adaptationSets, 0);
5631   fail_if (adapt_set == NULL);
5632
5633   /* setup streaming from the first adaptation set.
5634    * Should fail because the second S node does not have a  matching
5635    * SegmentURL node
5636    */
5637   ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set);
5638   assert_equals_int (ret, FALSE);
5639
5640   gst_mpd_client2_free (mpdclient);
5641 }
5642
5643 GST_END_TEST;
5644
5645 /*
5646  * Test parsing of the default presentation delay property
5647  */
5648 GST_START_TEST (dash_mpdparser_default_presentation_delay)
5649 {
5650   const gchar *xml =
5651       "<?xml version=\"1.0\"?>"
5652       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5653       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5654       "     maxSegmentDuration=\"PT2S\">"
5655       "  <Period id=\"Period0\" start=\"P0S\"></Period></MPD>";
5656
5657   gboolean ret;
5658   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5659   gint64 value;
5660
5661   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5662   assert_equals_int (ret, TRUE);
5663   value = gst_mpd_client2_parse_default_presentation_delay (mpdclient, "5s");
5664   assert_equals_int64 (value, 5000);
5665   value = gst_mpd_client2_parse_default_presentation_delay (mpdclient, "5S");
5666   assert_equals_int64 (value, 5000);
5667   value =
5668       gst_mpd_client2_parse_default_presentation_delay (mpdclient, "5 seconds");
5669   assert_equals_int64 (value, 5000);
5670   value =
5671       gst_mpd_client2_parse_default_presentation_delay (mpdclient, "2500ms");
5672   assert_equals_int64 (value, 2500);
5673   value = gst_mpd_client2_parse_default_presentation_delay (mpdclient, "3f");
5674   assert_equals_int64 (value, 6000);
5675   value = gst_mpd_client2_parse_default_presentation_delay (mpdclient, "3F");
5676   assert_equals_int64 (value, 6000);
5677   value = gst_mpd_client2_parse_default_presentation_delay (mpdclient, "");
5678   assert_equals_int64 (value, 0);
5679   value = gst_mpd_client2_parse_default_presentation_delay (mpdclient, "10");
5680   assert_equals_int64 (value, 0);
5681   value =
5682       gst_mpd_client2_parse_default_presentation_delay (mpdclient,
5683       "not a number");
5684   assert_equals_int64 (value, 0);
5685
5686   gst_mpd_client2_free (mpdclient);
5687 }
5688
5689 GST_END_TEST;
5690
5691 GST_START_TEST (dash_mpdparser_duration)
5692 {
5693   guint64 v;
5694
5695   fail_unless (_mpd_helper_parse_duration ("", &v) == FALSE);
5696   fail_unless (_mpd_helper_parse_duration (" ", &v) == FALSE);
5697   fail_unless (_mpd_helper_parse_duration ("0", &v) == FALSE);
5698   fail_unless (_mpd_helper_parse_duration ("D-1", &v) == FALSE);
5699   fail_unless (_mpd_helper_parse_duration ("T", &v) == FALSE);
5700
5701   fail_unless (_mpd_helper_parse_duration ("P", &v) == TRUE);
5702   fail_unless (_mpd_helper_parse_duration ("PT", &v) == TRUE);
5703   fail_unless (_mpd_helper_parse_duration ("PX", &v) == FALSE);
5704   fail_unless (_mpd_helper_parse_duration ("PPT", &v) == FALSE);
5705   fail_unless (_mpd_helper_parse_duration ("PTT", &v) == FALSE);
5706
5707   fail_unless (_mpd_helper_parse_duration ("P1D", &v) == TRUE);
5708   fail_unless (_mpd_helper_parse_duration ("P1D1D", &v) == FALSE);
5709   fail_unless (_mpd_helper_parse_duration ("P1D1M", &v) == FALSE);
5710   fail_unless (_mpd_helper_parse_duration ("P1M1D", &v) == TRUE);
5711   fail_unless (_mpd_helper_parse_duration ("P1M1D1M", &v) == FALSE);
5712   fail_unless (_mpd_helper_parse_duration ("P1M1D1D", &v) == FALSE);
5713
5714   fail_unless (_mpd_helper_parse_duration ("P0M0D", &v) == TRUE);
5715   fail_unless (_mpd_helper_parse_duration ("P-1M", &v) == FALSE);
5716   fail_unless (_mpd_helper_parse_duration ("P15M", &v) == FALSE);
5717   fail_unless (_mpd_helper_parse_duration ("P-1D", &v) == FALSE);
5718   fail_unless (_mpd_helper_parse_duration ("P35D", &v) == FALSE);
5719   fail_unless (_mpd_helper_parse_duration ("P-1Y", &v) == FALSE);
5720   fail_unless (_mpd_helper_parse_duration ("PT-1H", &v) == FALSE);
5721   fail_unless (_mpd_helper_parse_duration ("PT25H", &v) == FALSE);
5722   fail_unless (_mpd_helper_parse_duration ("PT-1M", &v) == FALSE);
5723   fail_unless (_mpd_helper_parse_duration ("PT65M", &v) == FALSE);
5724   fail_unless (_mpd_helper_parse_duration ("PT-1S", &v) == FALSE);
5725   /* seconds are allowed to be larger than 60 */
5726   fail_unless (_mpd_helper_parse_duration ("PT65S", &v) == TRUE);
5727
5728   fail_unless (_mpd_helper_parse_duration ("PT1.1H", &v) == FALSE);
5729   fail_unless (_mpd_helper_parse_duration ("PT1-1H", &v) == FALSE);
5730   fail_unless (_mpd_helper_parse_duration ("PT1-H", &v) == FALSE);
5731   fail_unless (_mpd_helper_parse_duration ("PT-H", &v) == FALSE);
5732   fail_unless (_mpd_helper_parse_duration ("PTH", &v) == FALSE);
5733   fail_unless (_mpd_helper_parse_duration ("PT0", &v) == FALSE);
5734   fail_unless (_mpd_helper_parse_duration ("PT1.1S", &v) == TRUE);
5735   fail_unless (_mpd_helper_parse_duration ("PT1.1.1S", &v) == FALSE);
5736
5737   fail_unless (_mpd_helper_parse_duration ("P585Y", &v) == FALSE);
5738   fail_unless (_mpd_helper_parse_duration ("P584Y", &v) == TRUE);
5739
5740   fail_unless (_mpd_helper_parse_duration (" P10DT8H", &v) == TRUE);
5741   fail_unless (_mpd_helper_parse_duration ("P10D T8H", &v) == FALSE);
5742   fail_unless (_mpd_helper_parse_duration ("P10DT8H ", &v) == TRUE);
5743 }
5744
5745 GST_END_TEST;
5746
5747 /*
5748  * Test that the maximum_segment_duration correctly implements the
5749  * rules in the DASH specification
5750  */
5751 GST_START_TEST (dash_mpdparser_maximum_segment_duration)
5752 {
5753   const gchar *xml_template =
5754       "<?xml version=\"1.0\"?>"
5755       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5756       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5757       "     availabilityStartTime=\"2015-03-24T0:0:0\""
5758       "     %s "
5759       "     mediaPresentationDuration=\"P100Y\">"
5760       "  <Period id=\"Period0\" start=\"PT0S\">"
5761       "    <AdaptationSet mimeType=\"video/mp4\" >"
5762       "      <SegmentTemplate timescale=\"90000\" initialization=\"$RepresentationID$/Header.m4s\" media=\"$RepresentationID$/$Number$.m4s\" duration=\"360000\" />"
5763       "      <Representation id=\"video1\" width=\"576\" height=\"324\" frameRate=\"25\" sar=\"1:1\" bandwidth=\"900000\" codecs=\"avc1.4D401E\"/>"
5764       "    </AdaptationSet>"
5765       "      <AdaptationSet mimeType=\"audio/mp4\" >"
5766       "        <SegmentTemplate timescale=\"90000\" initialization=\"$RepresentationID$/Header.m4s\" media=\"$RepresentationID$/$Number$.m4s\" duration=\"340000\" />"
5767       "        <Representation id=\"audio1\" audioSamplingRate=\"22050\" bandwidth=\"29600\" codecs=\"mp4a.40.2\">"
5768       "        <AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"2\"/>"
5769       "      </Representation>" "    </AdaptationSet>" "  </Period></MPD>";
5770   gboolean ret;
5771   GstMPDClient2 *mpdclient;
5772   gchar *xml;
5773   GstClockTime dur;
5774   GList *adapt_sets, *iter;
5775
5776   xml = g_strdup_printf (xml_template, "maxSegmentDuration=\"PT4.5S\"");
5777   mpdclient = gst_mpd_client2_new ();
5778   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5779   g_free (xml);
5780   assert_equals_int (ret, TRUE);
5781
5782   assert_equals_uint64 (mpdclient->mpd_root_node->maxSegmentDuration,
5783       duration_to_ms (0, 0, 0, 0, 0, 4, 500));
5784   dur = gst_mpd_client2_get_maximum_segment_duration (mpdclient);
5785   assert_equals_uint64 (dur, duration_to_clocktime (0, 0, 0, 0, 0, 4, 500));
5786   gst_mpd_client2_free (mpdclient);
5787
5788   /* now parse without the maxSegmentDuration attribute, to check that
5789      gst_mpd_client2_get_maximum_segment_duration uses the maximum
5790      duration of any segment
5791    */
5792   xml = g_strdup_printf (xml_template, "");
5793   mpdclient = gst_mpd_client2_new ();
5794   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5795   g_free (xml);
5796   assert_equals_int (ret, TRUE);
5797   ret =
5798       gst_mpd_client2_setup_media_presentation (mpdclient, GST_CLOCK_TIME_NONE,
5799       -1, NULL);
5800   assert_equals_int (ret, TRUE);
5801   adapt_sets = gst_mpd_client2_get_adaptation_sets (mpdclient);
5802   for (iter = adapt_sets; iter; iter = g_list_next (iter)) {
5803     GstMPDAdaptationSetNode *adapt_set_node = iter->data;
5804
5805     ret = gst_mpd_client2_setup_streaming (mpdclient, adapt_set_node);
5806     assert_equals_int (ret, TRUE);
5807   }
5808   dur = gst_mpd_client2_get_maximum_segment_duration (mpdclient);
5809   assert_equals_uint64 (dur, duration_to_clocktime (0, 0, 0, 0, 0, 4, 0));
5810   gst_mpd_client2_free (mpdclient);
5811 }
5812
5813 GST_END_TEST;
5814
5815 /*
5816  * Test parsing xsd:datetime with timezoneoffset.
5817  *
5818  */
5819 GST_START_TEST (dash_mpdparser_datetime_with_tz_offset)
5820 {
5821   GstDateTime *availabilityStartTime;
5822   GstDateTime *availabilityEndTime;
5823   const gchar *xml =
5824       "<?xml version=\"1.0\"?>"
5825       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5826       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5827       "     schemaLocation=\"TestSchemaLocation\""
5828       "     xmlns:xsi=\"TestNamespaceXSI\""
5829       "     xmlns:ext=\"TestNamespaceEXT\""
5830       "     id=\"testId\""
5831       "     type=\"static\""
5832       "     availabilityStartTime=\"2015-03-24T1:10:50+08:00\""
5833       "     availabilityEndTime=\"2015-03-24T1:10:50.123456-04:30\""
5834       "     mediaPresentationDuration=\"P0Y1M2DT12H10M20.5S\""
5835       "     minimumUpdatePeriod=\"P0Y1M2DT12H10M20.5S\""
5836       "     minBufferTime=\"P0Y1M2DT12H10M20.5S\""
5837       "     timeShiftBufferDepth=\"P0Y1M2DT12H10M20.5S\""
5838       "     suggestedPresentationDelay=\"P0Y1M2DT12H10M20.5S\""
5839       "     maxSegmentDuration=\"P0Y1M2DT12H10M20.5S\""
5840       "     maxSubsegmentDuration=\"P0Y1M2DT12H10M20.5S\"></MPD>";
5841
5842   gboolean ret;
5843   GstMPDClient2 *mpdclient = gst_mpd_client2_new ();
5844
5845   ret = gst_mpd_client2_parse (mpdclient, xml, (gint) strlen (xml));
5846   assert_equals_int (ret, TRUE);
5847
5848   availabilityStartTime = mpdclient->mpd_root_node->availabilityStartTime;
5849   assert_equals_int (gst_date_time_get_year (availabilityStartTime), 2015);
5850   assert_equals_int (gst_date_time_get_month (availabilityStartTime), 3);
5851   assert_equals_int (gst_date_time_get_day (availabilityStartTime), 24);
5852   assert_equals_int (gst_date_time_get_hour (availabilityStartTime), 1);
5853   assert_equals_int (gst_date_time_get_minute (availabilityStartTime), 10);
5854   assert_equals_int (gst_date_time_get_second (availabilityStartTime), 50);
5855   assert_equals_int (gst_date_time_get_microsecond (availabilityStartTime), 0);
5856   assert_equals_float (gst_date_time_get_time_zone_offset
5857       (availabilityStartTime), 8.0);
5858
5859   availabilityEndTime = mpdclient->mpd_root_node->availabilityEndTime;
5860   assert_equals_int (gst_date_time_get_year (availabilityEndTime), 2015);
5861   assert_equals_int (gst_date_time_get_month (availabilityEndTime), 3);
5862   assert_equals_int (gst_date_time_get_day (availabilityEndTime), 24);
5863   assert_equals_int (gst_date_time_get_hour (availabilityEndTime), 1);
5864   assert_equals_int (gst_date_time_get_minute (availabilityEndTime), 10);
5865   assert_equals_int (gst_date_time_get_second (availabilityEndTime), 50);
5866   assert_equals_int (gst_date_time_get_microsecond (availabilityEndTime),
5867       123456);
5868   assert_equals_float (gst_date_time_get_time_zone_offset (availabilityEndTime),
5869       -4.5);
5870
5871   gst_mpd_client2_free (mpdclient);
5872 }
5873
5874 GST_END_TEST;
5875
5876 /*
5877  * Test generate xml content.
5878  *
5879  */
5880 GST_START_TEST (dash_mpdparser_check_mpd_xml_generator)
5881 {
5882   const gchar *xml =
5883       "<?xml version=\"1.0\"?>"
5884       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
5885       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
5886       "     schemaLocation=\"TestSchemaLocation\""
5887       "     xmlns:xsi=\"TestNamespaceXSI\""
5888       "     xmlns:ext=\"TestNamespaceEXT\""
5889       "     id=\"testId\""
5890       "     type=\"static\""
5891       "     availabilityStartTime=\"2015-03-24T1:10:50+08:00\""
5892       "     availabilityEndTime=\"2015-03-24T1:10:50.123456-04:30\""
5893       "     mediaPresentationDuration=\"P0Y1M2DT12H10M20.5S\""
5894       "     minimumUpdatePeriod=\"P0Y1M2DT12H10M20.5S\""
5895       "     minBufferTime=\"P0Y1M2DT12H10M20.5S\""
5896       "     timeShiftBufferDepth=\"P0Y1M2DT12H10M20.5S\""
5897       "     suggestedPresentationDelay=\"P0Y1M2DT12H10M20.5S\""
5898       "     maxSegmentDuration=\"P0Y1M2DT12H10M20.5S\""
5899       "     maxSubsegmentDuration=\"P0Y1M2DT12H10M20.5S\">"
5900       "     <BaseURL serviceLocation=\"TestServiceLocation\""
5901       "     byteRange=\"TestByteRange\">TestBaseURL</BaseURL>"
5902       "     <Location>TestLocation</Location>"
5903       "     <ProgramInformation lang=\"en\""
5904       "     moreInformationURL=\"TestMoreInformationUrl\">"
5905       "     <Title>TestTitle</Title>"
5906       "     <Source>TestSource</Source>"
5907       "     <Copyright>TestCopyright</Copyright>"
5908       "     </ProgramInformation>"
5909       "     <Metrics metrics=\"TestMetric\"><Range starttime=\"P0Y1M2DT12H10M20.5S\""
5910       "           duration=\"P0Y1M2DT12H10M20.1234567S\">"
5911       "    </Range></Metrics>"
5912       "  <Period>"
5913       "    <AdaptationSet>"
5914       "      <Representation id=\"1\" bandwidth=\"250000\">"
5915       "        <SegmentTemplate duration=\"1\">"
5916       "        </SegmentTemplate>"
5917       "      </Representation></AdaptationSet></Period>" "     </MPD>";
5918
5919   gboolean ret;
5920   gchar *new_xml;
5921   gint new_xml_size;
5922   GstMPDClient2 *first_mpdclient = NULL;
5923   GstMPDClient2 *second_mpdclient = NULL;
5924   GstMPDBaseURLNode *first_baseURL, *second_baseURL;
5925   GstMPDLocationNode *first_location, *second_location;
5926   GstMPDProgramInformationNode *first_prog_info, *second_prog_info;
5927   GstMPDMetricsNode *first_metrics, *second_metrics;
5928   GstMPDMetricsRangeNode *first_metrics_range, *second_metrics_range;
5929
5930   first_mpdclient = gst_mpd_client2_new ();
5931
5932   ret = gst_mpd_client2_parse (first_mpdclient, xml, (gint) strlen (xml));
5933   assert_equals_int (ret, TRUE);
5934
5935   ret =
5936       gst_mpd_client2_get_xml_content (first_mpdclient, &new_xml,
5937       &new_xml_size);
5938   assert_equals_int (ret, TRUE);
5939
5940   second_mpdclient = gst_mpd_client2_new ();
5941
5942   ret = gst_mpd_client2_parse (second_mpdclient, new_xml, new_xml_size);
5943   assert_equals_int (ret, TRUE);
5944   g_free (new_xml);
5945
5946   /* assert that parameters are equal */
5947   assert_equals_string (first_mpdclient->mpd_root_node->default_namespace,
5948       second_mpdclient->mpd_root_node->default_namespace);
5949   assert_equals_string (first_mpdclient->mpd_root_node->namespace_xsi,
5950       second_mpdclient->mpd_root_node->namespace_xsi);
5951   assert_equals_string (first_mpdclient->mpd_root_node->namespace_ext,
5952       second_mpdclient->mpd_root_node->namespace_ext);
5953   assert_equals_string (first_mpdclient->mpd_root_node->schemaLocation,
5954       second_mpdclient->mpd_root_node->schemaLocation);
5955   assert_equals_string (first_mpdclient->mpd_root_node->id,
5956       second_mpdclient->mpd_root_node->id);
5957   assert_equals_string (first_mpdclient->mpd_root_node->profiles,
5958       second_mpdclient->mpd_root_node->profiles);
5959   assert_equals_uint64 (first_mpdclient->
5960       mpd_root_node->mediaPresentationDuration,
5961       second_mpdclient->mpd_root_node->mediaPresentationDuration);
5962   assert_equals_uint64 (first_mpdclient->mpd_root_node->minimumUpdatePeriod,
5963       second_mpdclient->mpd_root_node->minimumUpdatePeriod);
5964   assert_equals_uint64 (first_mpdclient->mpd_root_node->minBufferTime,
5965       second_mpdclient->mpd_root_node->minBufferTime);
5966   assert_equals_uint64 (first_mpdclient->mpd_root_node->timeShiftBufferDepth,
5967       second_mpdclient->mpd_root_node->timeShiftBufferDepth);
5968   assert_equals_uint64 (first_mpdclient->
5969       mpd_root_node->suggestedPresentationDelay,
5970       second_mpdclient->mpd_root_node->suggestedPresentationDelay);
5971   assert_equals_uint64 (first_mpdclient->mpd_root_node->maxSegmentDuration,
5972       second_mpdclient->mpd_root_node->maxSegmentDuration);
5973   assert_equals_uint64 (first_mpdclient->mpd_root_node->maxSubsegmentDuration,
5974       second_mpdclient->mpd_root_node->maxSubsegmentDuration);
5975
5976   /* baseURLs */
5977   first_baseURL =
5978       (GstMPDBaseURLNode *) first_mpdclient->mpd_root_node->BaseURLs->data;
5979   second_baseURL =
5980       (GstMPDBaseURLNode *) second_mpdclient->mpd_root_node->BaseURLs->data;
5981   assert_equals_string (first_baseURL->baseURL, second_baseURL->baseURL);
5982   assert_equals_string (first_baseURL->serviceLocation,
5983       second_baseURL->serviceLocation);
5984   assert_equals_string (first_baseURL->byteRange, second_baseURL->byteRange);
5985
5986   /* locations */
5987   first_location =
5988       (GstMPDLocationNode *) first_mpdclient->mpd_root_node->Locations->data;
5989   second_location =
5990       (GstMPDLocationNode *) second_mpdclient->mpd_root_node->Locations->data;
5991   assert_equals_string (first_location->location, second_location->location);
5992
5993   /* ProgramInformation */
5994   first_prog_info =
5995       (GstMPDProgramInformationNode *) first_mpdclient->mpd_root_node->
5996       ProgramInfos->data;
5997   second_prog_info =
5998       (GstMPDProgramInformationNode *) second_mpdclient->mpd_root_node->
5999       ProgramInfos->data;
6000   assert_equals_string (first_prog_info->lang, second_prog_info->lang);
6001   assert_equals_string (first_prog_info->moreInformationURL,
6002       second_prog_info->moreInformationURL);
6003   assert_equals_string (first_prog_info->Title, second_prog_info->Title);
6004   assert_equals_string (first_prog_info->Source, second_prog_info->Source);
6005   assert_equals_string (first_prog_info->Copyright,
6006       second_prog_info->Copyright);
6007
6008   /* Metrics */
6009   first_metrics =
6010       (GstMPDMetricsNode *) first_mpdclient->mpd_root_node->Metrics->data;
6011   second_metrics =
6012       (GstMPDMetricsNode *) second_mpdclient->mpd_root_node->Metrics->data;
6013   assert_equals_string (first_metrics->metrics, second_metrics->metrics);
6014
6015   /* Metrics Range */
6016   first_metrics_range =
6017       (GstMPDMetricsRangeNode *) first_metrics->MetricsRanges->data;
6018   second_metrics_range =
6019       (GstMPDMetricsRangeNode *) second_metrics->MetricsRanges->data;
6020   assert_equals_uint64 (first_metrics_range->starttime,
6021       second_metrics_range->starttime);
6022   assert_equals_uint64 (first_metrics_range->duration,
6023       second_metrics_range->duration);
6024
6025   gst_mpd_client2_free (first_mpdclient);
6026   gst_mpd_client2_free (second_mpdclient);
6027 }
6028
6029 GST_END_TEST;
6030
6031 /*
6032  * Test add mpd content with mpd_client set methods
6033  *
6034  */
6035 GST_START_TEST (dash_mpdparser_check_mpd_client_set_methods)
6036 {
6037   const gchar *xml =
6038       "<?xml version=\"1.0\"?>"
6039       "<MPD xmlns=\"urn:mpeg:dash:schema:mpd:2011\""
6040       "     profiles=\"urn:mpeg:dash:profile:isoff-main:2011\""
6041       "     schemaLocation=\"TestSchemaLocation\""
6042       "     xmlns:xsi=\"TestNamespaceXSI\""
6043       "     xmlns:ext=\"TestNamespaceEXT\""
6044       "     id=\"testId\""
6045       "     type=\"static\""
6046       "     availabilityStartTime=\"2015-03-24T1:10:50+08:00\""
6047       "     availabilityEndTime=\"2015-03-24T1:10:50.123456-04:30\""
6048       "     mediaPresentationDuration=\"P0Y1M2DT12H10M20.5S\""
6049       "     minimumUpdatePeriod=\"P0Y1M2DT12H10M20.5S\""
6050       "     minBufferTime=\"P0Y1M2DT12H10M20.5S\""
6051       "     timeShiftBufferDepth=\"P0Y1M2DT12H10M20.5S\""
6052       "     suggestedPresentationDelay=\"P0Y1M2DT12H10M20.5S\""
6053       "     maxSegmentDuration=\"P0Y1M2DT12H10M20.5S\""
6054       "     maxSubsegmentDuration=\"P0Y1M2DT12H10M20.5S\">"
6055       "     <BaseURL serviceLocation=\"TestServiceLocation\""
6056       "     byteRange=\"TestByteRange\">TestBaseURL</BaseURL>"
6057       "     <Location>TestLocation</Location>"
6058       "     <ProgramInformation lang=\"en\""
6059       "     moreInformationURL=\"TestMoreInformationUrl\">"
6060       "     <Title>TestTitle</Title>"
6061       "     <Source>TestSource</Source>"
6062       "     <Copyright>TestCopyright</Copyright>"
6063       "     </ProgramInformation>"
6064       "     <Metrics metrics=\"TestMetric\"><Range starttime=\"P0Y1M2DT12H10M20.5S\""
6065       "           duration=\"P0Y1M2DT12H10M20.1234567S\">"
6066       "    </Range></Metrics>"
6067       "  <Period id=\"TestId\" start=\"PT1M\" duration=\"PT40S\""
6068       "          bitstreamSwitching=\"true\">"
6069       "    <AdaptationSet id=\"9\" contentType=\"video\" mimeType=\"video\">"
6070       "      <Representation id=\"audio_1\" "
6071       "                      bandwidth=\"100\""
6072       "                      qualityRanking=\"200\""
6073       "                      width=\"640\""
6074       "                      height=\"480\""
6075       "                      codecs=\"avc1\""
6076       "                      audioSamplingRate=\"44100\""
6077       "                      mimeType=\"audio/mp4\">"
6078       "        <SegmentList duration=\"15\" startNumber=\"11\">"
6079       "          <SegmentURL media=\"segment001.ts\"></SegmentURL>"
6080       "          <SegmentURL media=\"segment002.ts\"></SegmentURL>"
6081       "        </SegmentList>"
6082       "      </Representation></AdaptationSet></Period>" "     </MPD>";
6083   gboolean ret;
6084   gchar *period_id;
6085   guint adaptation_set_id;
6086   gchar *representation_id;
6087   GstMPDClient2 *first_mpdclient = NULL;
6088   GstMPDClient2 *second_mpdclient = NULL;
6089   GstMPDBaseURLNode *first_baseURL, *second_baseURL;
6090   GstMPDPeriodNode *first_period, *second_period;
6091   GstMPDAdaptationSetNode *first_adap_set, *second_adap_set;
6092   GstMPDRepresentationNode *first_rep, *second_rep;
6093   GstMPDSegmentListNode *first_seg_list, *second_seg_list;
6094   GstMPDSegmentURLNode *first_seg_url, *second_seg_url;
6095
6096   first_mpdclient = gst_mpd_client2_new ();
6097
6098   ret = gst_mpd_client2_parse (first_mpdclient, xml, (gint) strlen (xml));
6099   assert_equals_int (ret, TRUE);
6100
6101   second_mpdclient = gst_mpd_client2_new ();
6102   gst_mpd_client2_set_root_node (second_mpdclient,
6103       "default-namespace", "urn:mpeg:dash:schema:mpd:2011",
6104       "profiles", "urn:mpeg:dash:profile:isoff-main:2011",
6105       "schema-location", "TestSchemaLocation",
6106       "namespace-xsi", "TestNamespaceXSI",
6107       "namespace-ext", "TestNamespaceEXT", "id", "testId", NULL);
6108   gst_mpd_client2_add_baseurl_node (second_mpdclient,
6109       "url", "TestBaseURL",
6110       "service-location", "TestServiceLocation",
6111       "byte-range", "TestByteRange", NULL);
6112   period_id = gst_mpd_client2_set_period_node (second_mpdclient, (gchar *) "TestId", "start", (guint64) 60000,  // ms
6113       "duration", (guint64) 40000, "bitstream-switching", 1, NULL);
6114   adaptation_set_id =
6115       gst_mpd_client2_set_adaptation_set_node (second_mpdclient, period_id, 9,
6116       "content-type", "video", "mime-type", "video", NULL);
6117
6118   representation_id =
6119       gst_mpd_client2_set_representation_node (second_mpdclient, period_id,
6120       adaptation_set_id, (gchar *) "audio_1", "bandwidth", 100,
6121       "quality-ranking", 200, "mime-type", "audio/mp4", "width", 640, "height",
6122       480, "codecs", "avc1", "audio-sampling-rate", 44100, NULL);
6123
6124   gst_mpd_client2_set_segment_list (second_mpdclient, period_id,
6125       adaptation_set_id, representation_id, "duration", 15, "start-number", 11,
6126       NULL);
6127   gst_mpd_client2_add_segment_url (second_mpdclient, period_id,
6128       adaptation_set_id, representation_id, "media", "segment001.ts", NULL);
6129   gst_mpd_client2_add_segment_url (second_mpdclient, period_id,
6130       adaptation_set_id, representation_id, "media", "segment002.ts", NULL);
6131
6132   /* assert that parameters are equal */
6133   assert_equals_string (first_mpdclient->mpd_root_node->default_namespace,
6134       second_mpdclient->mpd_root_node->default_namespace);
6135   assert_equals_string (first_mpdclient->mpd_root_node->namespace_xsi,
6136       second_mpdclient->mpd_root_node->namespace_xsi);
6137   assert_equals_string (first_mpdclient->mpd_root_node->namespace_ext,
6138       second_mpdclient->mpd_root_node->namespace_ext);
6139   assert_equals_string (first_mpdclient->mpd_root_node->schemaLocation,
6140       second_mpdclient->mpd_root_node->schemaLocation);
6141   assert_equals_string (first_mpdclient->mpd_root_node->id,
6142       second_mpdclient->mpd_root_node->id);
6143   assert_equals_string (first_mpdclient->mpd_root_node->profiles,
6144       second_mpdclient->mpd_root_node->profiles);
6145
6146
6147   /* baseURLs */
6148   first_baseURL =
6149       (GstMPDBaseURLNode *) first_mpdclient->mpd_root_node->BaseURLs->data;
6150   second_baseURL =
6151       (GstMPDBaseURLNode *) second_mpdclient->mpd_root_node->BaseURLs->data;
6152   assert_equals_string (first_baseURL->baseURL, second_baseURL->baseURL);
6153   assert_equals_string (first_baseURL->serviceLocation,
6154       second_baseURL->serviceLocation);
6155   assert_equals_string (first_baseURL->byteRange, second_baseURL->byteRange);
6156
6157   /* Period */
6158   first_period =
6159       (GstMPDPeriodNode *) first_mpdclient->mpd_root_node->Periods->data;
6160   second_period =
6161       (GstMPDPeriodNode *) second_mpdclient->mpd_root_node->Periods->data;
6162
6163   assert_equals_string (first_period->id, second_period->id);
6164   assert_equals_int64 (first_period->start, second_period->start);
6165   assert_equals_int64 (first_period->duration, second_period->duration);
6166   assert_equals_int (first_period->bitstreamSwitching,
6167       second_period->bitstreamSwitching);
6168
6169   /* Adaptation set */
6170   first_adap_set =
6171       (GstMPDAdaptationSetNode *) first_period->AdaptationSets->data;
6172   second_adap_set =
6173       (GstMPDAdaptationSetNode *) second_period->AdaptationSets->data;
6174
6175   assert_equals_int (first_adap_set->id, second_adap_set->id);
6176   assert_equals_string (first_adap_set->contentType,
6177       second_adap_set->contentType);
6178   assert_equals_string (GST_MPD_REPRESENTATION_BASE_NODE
6179       (first_adap_set)->mimeType,
6180       GST_MPD_REPRESENTATION_BASE_NODE (second_adap_set)->mimeType);
6181
6182   /* Representation */
6183   first_rep =
6184       (GstMPDRepresentationNode *) first_adap_set->Representations->data;
6185   second_rep =
6186       (GstMPDRepresentationNode *) second_adap_set->Representations->data;
6187   assert_equals_string (first_rep->id, second_rep->id);
6188   assert_equals_int (first_rep->bandwidth, second_rep->bandwidth);
6189   assert_equals_int (first_rep->qualityRanking, second_rep->qualityRanking);
6190   assert_equals_string (GST_MPD_REPRESENTATION_BASE_NODE (first_rep)->mimeType,
6191       GST_MPD_REPRESENTATION_BASE_NODE (second_rep)->mimeType);
6192
6193   assert_equals_int (GST_MPD_REPRESENTATION_BASE_NODE (first_rep)->width,
6194       GST_MPD_REPRESENTATION_BASE_NODE (second_rep)->width);
6195
6196   assert_equals_int (GST_MPD_REPRESENTATION_BASE_NODE (first_rep)->height,
6197       GST_MPD_REPRESENTATION_BASE_NODE (second_rep)->height);
6198
6199   assert_equals_string (GST_MPD_REPRESENTATION_BASE_NODE (first_rep)->codecs,
6200       GST_MPD_REPRESENTATION_BASE_NODE (second_rep)->codecs);
6201
6202   assert_equals_string (GST_MPD_REPRESENTATION_BASE_NODE
6203       (first_rep)->audioSamplingRate,
6204       GST_MPD_REPRESENTATION_BASE_NODE (second_rep)->audioSamplingRate);
6205
6206   /*SegmentList */
6207   first_seg_list = (GstMPDSegmentListNode *) first_rep->SegmentList;
6208   second_seg_list = (GstMPDSegmentListNode *) second_rep->SegmentList;
6209   assert_equals_int (GST_MPD_MULT_SEGMENT_BASE_NODE (first_seg_list)->duration,
6210       GST_MPD_MULT_SEGMENT_BASE_NODE (second_seg_list)->duration);
6211   assert_equals_int (GST_MPD_MULT_SEGMENT_BASE_NODE
6212       (first_seg_list)->startNumber,
6213       GST_MPD_MULT_SEGMENT_BASE_NODE (second_seg_list)->startNumber);
6214
6215   first_seg_url = (GstMPDSegmentURLNode *) first_seg_list->SegmentURL->data;
6216   second_seg_url = (GstMPDSegmentURLNode *) second_seg_list->SegmentURL->data;
6217
6218   assert_equals_string (first_seg_url->media, second_seg_url->media);
6219
6220
6221   gst_mpd_client2_free (first_mpdclient);
6222   gst_mpd_client2_free (second_mpdclient);
6223 }
6224
6225 GST_END_TEST;
6226
6227 /*
6228  * create a test suite containing all dash testcases
6229  */
6230 static Suite *
6231 dash_suite (void)
6232 {
6233   Suite *s = suite_create ("dash");
6234   TCase *tc_simpleMPD = tcase_create ("simpleMPD");
6235   TCase *tc_complexMPD = tcase_create ("complexMPD");
6236   TCase *tc_negativeTests = tcase_create ("negativeTests");
6237   TCase *tc_stringTests = tcase_create ("stringTests");
6238   TCase *tc_duration = tcase_create ("duration");
6239
6240   GST_DEBUG_CATEGORY_INIT (gst_dash_demux2_debug, "gst_dash_demux2_debug", 0,
6241       "mpeg dashdemux2 tests");
6242
6243   /* test parsing the simplest possible mpd */
6244   tcase_add_test (tc_simpleMPD, dash_mpdparser_validsimplempd);
6245
6246   /* test parsing the simplest possible mpd */
6247   tcase_add_test (tc_simpleMPD, dash_mpdparser_check_mpd_xml_generator);
6248
6249   /* test mpd client set methods */
6250   tcase_add_test (tc_simpleMPD, dash_mpdparser_check_mpd_client_set_methods);
6251
6252   /* tests parsing attributes from each element type */
6253   tcase_add_test (tc_simpleMPD, dash_mpdparser_mpd);
6254   tcase_add_test (tc_simpleMPD, dash_mpdparser_datetime_with_tz_offset);
6255   tcase_add_test (tc_simpleMPD, dash_mpdparser_programInformation);
6256   tcase_add_test (tc_simpleMPD, dash_mpdparser_baseURL);
6257   tcase_add_test (tc_simpleMPD, dash_mpdparser_location);
6258   tcase_add_test (tc_simpleMPD, dash_mpdparser_metrics);
6259   tcase_add_test (tc_simpleMPD, dash_mpdparser_metrics_range);
6260   tcase_add_test (tc_simpleMPD, dash_mpdparser_metrics_reporting);
6261   tcase_add_test (tc_simpleMPD, dash_mpdparser_period);
6262   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_baseURL);
6263   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_segmentBase);
6264   tcase_add_test (tc_simpleMPD,
6265       dash_mpdparser_period_segmentBase_initialization);
6266   tcase_add_test (tc_simpleMPD,
6267       dash_mpdparser_period_segmentBase_representationIndex);
6268   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_segmentList);
6269   tcase_add_test (tc_simpleMPD,
6270       dash_mpdparser_period_segmentList_multipleSegmentBaseType);
6271   tcase_add_test (tc_simpleMPD,
6272       dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentBaseType);
6273   tcase_add_test (tc_simpleMPD,
6274       dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline);
6275   tcase_add_test (tc_simpleMPD,
6276       dash_mpdparser_period_segmentList_multipleSegmentBaseType_segmentTimeline_s);
6277   tcase_add_test (tc_simpleMPD,
6278       dash_mpdparser_period_segmentList_multipleSegmentBaseType_bitstreamSwitching);
6279   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_segmentList_segmentURL);
6280   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_segmentTemplate);
6281   tcase_add_test (tc_simpleMPD,
6282       dash_mpdparser_period_segmentTemplateWithPresentationTimeOffset);
6283   tcase_add_test (tc_simpleMPD,
6284       dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType);
6285   tcase_add_test (tc_simpleMPD,
6286       dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentBaseType);
6287   tcase_add_test (tc_simpleMPD,
6288       dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline);
6289   tcase_add_test (tc_simpleMPD,
6290       dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_segmentTimeline_s);
6291   tcase_add_test (tc_simpleMPD,
6292       dash_mpdparser_period_segmentTemplate_multipleSegmentBaseType_bitstreamSwitching);
6293   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet);
6294   tcase_add_test (tc_simpleMPD,
6295       dash_mpdparser_period_adaptationSet_representationBase);
6296   tcase_add_test (tc_simpleMPD,
6297       dash_mpdparser_period_adaptationSet_representationBase_framePacking);
6298   tcase_add_test (tc_simpleMPD,
6299       dash_mpdparser_adapt_repr_segmentTemplate_inherit);
6300   tcase_add_test (tc_simpleMPD,
6301       dash_mpdparser_period_adaptationSet_representationBase_audioChannelConfiguration);
6302   tcase_add_test (tc_simpleMPD,
6303       dash_mpdparser_period_adaptationSet_representationBase_contentProtection);
6304   tcase_add_test (tc_simpleMPD, dash_mpdparser_contentProtection_no_value);
6305   tcase_add_test (tc_simpleMPD,
6306       dash_mpdparser_contentProtection_no_value_no_encoding);
6307   tcase_add_test (tc_simpleMPD,
6308       dash_mpdparser_period_adaptationSet_accessibility);
6309   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_role);
6310   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_rating);
6311   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_viewpoint);
6312   tcase_add_test (tc_simpleMPD,
6313       dash_mpdparser_period_adaptationSet_contentComponent);
6314   tcase_add_test (tc_simpleMPD,
6315       dash_mpdparser_period_adaptationSet_contentComponent_accessibility);
6316   tcase_add_test (tc_simpleMPD,
6317       dash_mpdparser_period_adaptationSet_contentComponent_role);
6318   tcase_add_test (tc_simpleMPD,
6319       dash_mpdparser_period_adaptationSet_contentComponent_rating);
6320   tcase_add_test (tc_simpleMPD,
6321       dash_mpdparser_period_adaptationSet_contentComponent_viewpoint);
6322   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_adaptationSet_baseURL);
6323   tcase_add_test (tc_simpleMPD,
6324       dash_mpdparser_period_adaptationSet_segmentBase);
6325   tcase_add_test (tc_simpleMPD,
6326       dash_mpdparser_period_adaptationSet_segmentBase_initialization);
6327   tcase_add_test (tc_simpleMPD,
6328       dash_mpdparser_period_adaptationSet_segmentBase_representationIndex);
6329   tcase_add_test (tc_simpleMPD,
6330       dash_mpdparser_period_adaptationSet_segmentList);
6331   tcase_add_test (tc_simpleMPD,
6332       dash_mpdparser_period_adaptationSet_segmentTemplate);
6333   tcase_add_test (tc_simpleMPD,
6334       dash_mpdparser_period_adaptationSet_segmentTemplate_inherit);
6335   tcase_add_test (tc_simpleMPD,
6336       dash_mpdparser_period_adaptationSet_representation);
6337   tcase_add_test (tc_simpleMPD,
6338       dash_mpdparser_period_adaptationSet_representation_representationBase);
6339   tcase_add_test (tc_simpleMPD,
6340       dash_mpdparser_period_adaptationSet_representation_baseURL);
6341   tcase_add_test (tc_simpleMPD,
6342       dash_mpdparser_period_adaptationSet_representation_subRepresentation);
6343   tcase_add_test (tc_simpleMPD,
6344       dash_mpdparser_period_adaptationSet_representation_subRepresentation_representationBase);
6345   tcase_add_test (tc_simpleMPD,
6346       dash_mpdparser_period_adaptationSet_representation_segmentBase);
6347   tcase_add_test (tc_simpleMPD,
6348       dash_mpdparser_period_adaptationSet_representation_segmentList);
6349   tcase_add_test (tc_simpleMPD,
6350       dash_mpdparser_period_adaptationSet_representation_segmentTemplate);
6351   tcase_add_test (tc_simpleMPD,
6352       dash_mpdparser_period_adaptationSet_representation_segmentTemplate_inherit);
6353   tcase_add_test (tc_simpleMPD,
6354       dash_mpdparser_period_adaptationSet_representation_segmentBase_inherit);
6355   tcase_add_test (tc_simpleMPD, dash_mpdparser_period_subset);
6356   tcase_add_test (tc_simpleMPD, dash_mpdparser_utctiming);
6357   tcase_add_test (tc_simpleMPD, dash_mpdparser_utctiming_invalid_value);
6358
6359   /* tests checking other possible values for attributes */
6360   tcase_add_test (tc_simpleMPD, dash_mpdparser_type_dynamic);
6361   tcase_add_test (tc_simpleMPD, dash_mpdparser_template_parsing);
6362   tcase_add_test (tc_simpleMPD, dash_mpdparser_isoff_ondemand_profile);
6363   tcase_add_test (tc_simpleMPD, dash_mpdparser_GstDateTime);
6364   tcase_add_test (tc_simpleMPD, dash_mpdparser_bitstreamSwitching_inheritance);
6365   tcase_add_test (tc_simpleMPD, dash_mpdparser_various_duration_formats);
6366   tcase_add_test (tc_simpleMPD, dash_mpdparser_default_presentation_delay);
6367
6368   /* tests checking the MPD management
6369    * (eg. setting active streams, obtaining attributes values)
6370    */
6371   tcase_add_test (tc_complexMPD, dash_mpdparser_setup_media_presentation);
6372   tcase_add_test (tc_complexMPD, dash_mpdparser_setup_streaming);
6373   tcase_add_test (tc_complexMPD, dash_mpdparser_period_selection);
6374   tcase_add_test (tc_complexMPD, dash_mpdparser_get_period_at_time);
6375   tcase_add_test (tc_complexMPD, dash_mpdparser_adaptationSet_handling);
6376   tcase_add_test (tc_complexMPD, dash_mpdparser_representation_selection);
6377   tcase_add_test (tc_complexMPD, dash_mpdparser_multipleSegmentURL);
6378   tcase_add_test (tc_complexMPD, dash_mpdparser_activeStream_selection);
6379   tcase_add_test (tc_complexMPD, dash_mpdparser_activeStream_parameters);
6380   tcase_add_test (tc_complexMPD, dash_mpdparser_get_audio_languages);
6381   tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL1);
6382   tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL2);
6383   tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL3);
6384   tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL4);
6385   tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL5);
6386   tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL6);
6387   tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL7);
6388   tcase_add_test (tc_complexMPD, dash_mpdparser_get_baseURL8);
6389   tcase_add_test (tc_complexMPD, dash_mpdparser_get_mediaPresentationDuration);
6390   tcase_add_test (tc_complexMPD, dash_mpdparser_get_streamPresentationOffset);
6391   tcase_add_test (tc_complexMPD, dash_mpdparser_segments);
6392   tcase_add_test (tc_complexMPD, dash_mpdparser_headers);
6393   tcase_add_test (tc_complexMPD, dash_mpdparser_fragments);
6394   tcase_add_test (tc_complexMPD, dash_mpdparser_inherited_segmentBase);
6395   tcase_add_test (tc_complexMPD, dash_mpdparser_inherited_segmentURL);
6396   tcase_add_test (tc_complexMPD, dash_mpdparser_segment_list);
6397   tcase_add_test (tc_complexMPD, dash_mpdparser_segment_template);
6398   tcase_add_test (tc_complexMPD, dash_mpdparser_segment_timeline);
6399   tcase_add_test (tc_complexMPD, dash_mpdparser_multiple_inherited_segmentURL);
6400
6401   /* tests checking the parsing of missing/incomplete attributes of xml */
6402   tcase_add_test (tc_negativeTests, dash_mpdparser_missing_xml);
6403   tcase_add_test (tc_negativeTests, dash_mpdparser_missing_mpd);
6404   tcase_add_test (tc_negativeTests, dash_mpdparser_no_end_tag);
6405   tcase_add_test (tc_negativeTests, dash_mpdparser_no_profiles);
6406   tcase_add_test (tc_negativeTests, dash_mpdparser_no_default_namespace);
6407   tcase_add_test (tc_negativeTests,
6408       dash_mpdparser_wrong_period_duration_inferred_from_next_period);
6409   tcase_add_test (tc_negativeTests,
6410       dash_mpdparser_wrong_period_duration_inferred_from_next_mediaPresentationDuration);
6411   tcase_add_test (tc_negativeTests, dash_mpdparser_negative_period_duration);
6412   tcase_add_test (tc_negativeTests,
6413       dash_mpdparser_read_unsigned_from_negative_values);
6414   tcase_add_test (tc_negativeTests,
6415       dash_mpdparser_negative_mediaPresentationDuration);
6416   tcase_add_test (tc_negativeTests,
6417       dash_mpdparser_unmatched_segmentTimeline_segmentURL);
6418
6419   tcase_add_test (tc_stringTests, dash_mpdparser_whitespace_strings);
6420   tcase_add_test (tc_stringTests, dash_mpdparser_rfc1738_strings);
6421
6422   tcase_add_test (tc_duration, dash_mpdparser_duration);
6423   tcase_add_test (tc_duration, dash_mpdparser_maximum_segment_duration);
6424
6425   suite_add_tcase (s, tc_simpleMPD);
6426   suite_add_tcase (s, tc_complexMPD);
6427   suite_add_tcase (s, tc_negativeTests);
6428   suite_add_tcase (s, tc_stringTests);
6429   suite_add_tcase (s, tc_duration);
6430
6431   return s;
6432 }
6433
6434 GST_CHECK_MAIN (dash);