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