tests: Enable hls m3u8 unit test with meson build
[platform/upstream/gstreamer.git] / tests / check / elements / hlsdemux_m3u8.c
1 /* GStreamer
2  *
3  * unit test for hlsdemux
4  *
5  * Copyright (C) <2012> Fluendo S.A <support@fluendo.com>
6  *  Authors: Andoni Morales Alastruey <amorales@fluendo.com>
7  * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #include <gst/check/gstcheck.h>
26
27 #undef GST_CAT_DEFAULT
28 #include "m3u8.h"
29 #include "m3u8.c"
30
31 GST_DEBUG_CATEGORY (hls_debug);
32
33 static const gchar *INVALID_PLAYLIST = "#EXTM3 UINVALID";
34
35 static const gchar *ON_DEMAND_PLAYLIST = "#EXTM3U \n\
36 #EXT-X-TARGETDURATION:10\n\
37 #EXTINF:10,Test\n\
38 http://media.example.com/001.ts\n\
39 #EXTINF:10,Test\n\
40 http://media.example.com/002.ts\n\
41 #EXTINF:10,Test\n\
42 http://media.example.com/003.ts\n\
43 #EXTINF:10,Test\n\
44 http://media.example.com/004.ts\n\
45 #EXT-X-ENDLIST";
46
47 static const gchar *DOUBLES_PLAYLIST = "#EXTM3U \n\
48 #EXT-X-TARGETDURATION:10\n\
49 #EXTINF:10.321,Test\n\
50 http://media.example.com/001.ts\n\
51 #EXTINF:9.6789,Test\n\
52 http://media.example.com/002.ts\n\
53 #EXTINF:10.2344,Test\n\
54 http://media.example.com/003.ts\n\
55 #EXTINF:9.92,Test\n\
56 http://media.example.com/004.ts\n\
57 #EXT-X-ENDLIST";
58
59 static const gchar *LIVE_PLAYLIST = "#EXTM3U\n\
60 #EXT-X-TARGETDURATION:8\n\
61 #EXT-X-MEDIA-SEQUENCE:2680\n\
62 \n\
63 #EXTINF:8,\n\
64 https://priv.example.com/fileSequence2680.ts\n\
65 #EXTINF:8,\n\
66 https://priv.example.com/fileSequence2681.ts\n\
67 #EXTINF:8,\n\
68 https://priv.example.com/fileSequence2682.ts\n\
69 #EXTINF:8,\n\
70 https://priv.example.com/fileSequence2683.ts";
71
72 static const gchar *LIVE_ROTATED_PLAYLIST = "#EXTM3U\n\
73 #EXT-X-TARGETDURATION:8\n\
74 #EXT-X-MEDIA-SEQUENCE:3001\n\
75 \n\
76 #EXTINF:8,\n\
77 https://priv.example.com/fileSequence3001.ts\n\
78 #EXTINF:8,\n\
79 https://priv.example.com/fileSequence3002.ts\n\
80 #EXTINF:8,\n\
81 https://priv.example.com/fileSequence3003.ts\n\
82 #EXTINF:8,\n\
83 https://priv.example.com/fileSequence3004.ts";
84
85 static const gchar *VARIANT_PLAYLIST = "#EXTM3U \n\
86 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=128000\n\
87 http://example.com/low.m3u8\n\
88 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000\n\
89 http://example.com/mid.m3u8\n\
90 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=768000\n\
91 http://example.com/hi.m3u8\n\
92 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS=\"mp4a.40.5\"\n\
93 http://example.com/audio-only.m3u8";
94
95 static const gchar *VARIANT_PLAYLIST_WITH_URI_MISSING = "#EXTM3U \n\
96 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=128000\n\
97 http://example.com/low.m3u8\n\
98 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000\n\
99 \n\
100 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=768000\n\
101 http://example.com/hi.m3u8\n\
102 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS=\"mp4a.40.5\"\n\
103 http://example.com/audio-only.m3u8";
104
105 static const gchar *EMPTY_LINES_VARIANT_PLAYLIST = "#EXTM3U \n\
106 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=128000\n\n\
107 http://example.com/low.m3u8\n\n\
108 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000\n\n\
109 http://example.com/mid.m3u8\n\n\
110 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=768000\n\n\
111 http://example.com/hi.m3u8\n\n\
112 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS=\"mp4a.40.5\"\n\n\
113 http://example.com/audio-only.m3u8";
114
115 static const gchar *WINDOWS_EMPTY_LINES_VARIANT_PLAYLIST = "#EXTM3U \r\n\
116 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=128000\r\n\r\n\
117 http://example.com/low.m3u8\r\n\r\n\
118 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000\r\n\r\n\
119 http://example.com/mid.m3u8\r\n\r\n\
120 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=768000\r\n\r\n\
121 http://example.com/hi.m3u8\r\n\r\n\
122 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS=\"mp4a.40.5\"\r\n\r\n\
123 http://example.com/audio-only.m3u8";
124
125 static const gchar *EMPTY_LINES_PLAYLIST = "#EXTM3U \n\n\
126 #EXT-X-TARGETDURATION:10\n\
127 #EXTINF:10,Testr\n\n\
128 http://media.example.com/001.ts\n\n\
129 #EXTINF:10,Test\n\n\
130 http://media.example.com/002.ts\n\n\
131 #EXTINF:10,Test\n\n\
132 http://media.example.com/003.ts\n\n\
133 #EXTINF:10,Test\n\n\
134 http://media.example.com/004.ts\n\n\
135 #EXT-X-ENDLIST";
136
137 static const gchar *WINDOWS_EMPTY_LINES_PLAYLIST = "#EXTM3U \r\n\
138 #EXT-X-TARGETDURATION:10\r\n\r\n\
139 #EXTINF:10,Test\r\n\r\n\
140 http://media.example.com/001.ts\r\n\r\n\
141 #EXTINF:10,Test\r\n\r\n\
142 http://media.example.com/002.ts\r\n\r\n\
143 #EXTINF:10,Test\r\n\r\n\
144 http://media.example.com/003.ts\r\n\r\n\
145 #EXTINF:10,Test\r\n\r\n\
146 http://media.example.com/004.ts\r\n\r\n\
147 #EXT-X-ENDLIST";
148
149 static const gchar *BYTE_RANGES_PLAYLIST = "#EXTM3U \n\
150 #EXT-X-TARGETDURATION:40\n\
151 #EXTINF:10,Test\n\
152 #EXT-X-BYTERANGE:1000@100\n\
153 http://media.example.com/all.ts\n\
154 #EXTINF:10,Test\n\
155 #EXT-X-BYTERANGE:1000@1000\n\
156 http://media.example.com/all.ts\n\
157 #EXTINF:10,Test\n\
158 #EXT-X-BYTERANGE:1000@2000\n\
159 http://media.example.com/all.ts\n\
160 #EXTINF:10,Test\n\
161 #EXT-X-BYTERANGE:1000@3000\n\
162 http://media.example.com/all.ts\n\
163 #EXT-X-ENDLIST";
164
165 static const gchar *BYTE_RANGES_ACC_OFFSET_PLAYLIST = "#EXTM3U \n\
166 #EXT-X-TARGETDURATION:40\n\
167 #EXTINF:10,Test\n\
168 #EXT-X-BYTERANGE:1000\n\
169 http://media.example.com/all.ts\n\
170 #EXTINF:10,Test\n\
171 #EXT-X-BYTERANGE:1000\n\
172 http://media.example.com/all.ts\n\
173 #EXTINF:10,Test\n\
174 #EXT-X-BYTERANGE:1000\n\
175 http://media.example.com/all.ts\n\
176 #EXTINF:10,Test\n\
177 #EXT-X-BYTERANGE:1000\n\
178 http://media.example.com/all.ts\n\
179 #EXT-X-ENDLIST";
180
181 #if 0
182 static const gchar *ALTERNATE_AUDIO_PLAYLIST = "#EXTM3U\n\
183 #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"aac\",NAME=\"English\",\
184   DEFAULT=YES,AUTOSELECT=YES,LANGUAGE=\"en\" \n\
185 #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"aac\",NAME=\"Deutsche\",\
186   DEFAULT=NO,AUTOSELECT=YES,LANGUAGE=\"de\",\
187   URI=\"http://localhost/main/german-audio.m3u8\"\n\
188 #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"aac\",NAME=\"Commentary\",\
189   DEFAULT=NO,AUTOSELECT=NO,\
190   URI=\"http://localhost/commentary/audio-only.m3u8\"\n\
191 #EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS=\"avc1.42001f\",AUDIO=\"aac\"\n\
192 low/video-only.m3u8\n\
193 #EXT-X-STREAM-INF:BANDWIDTH=256000,CODECS=\"avc1.42001f\",AUDIO=\"aac\"\n\
194 mid/video-only.m3u8\n\
195 #EXT-X-STREAM-INF:BANDWIDTH=768000,CODECS=\"avc1.42001f\",AUDIO=\"aac\"\n\
196 hi/video-only.m3u8\n\
197 #EXT-X-STREAM-INF:BANDWIDTH=65000,CODECS=\"mp4a.40.5\",AUDIO=\"aac\"\n\
198 main/english-audio.m3u8";
199
200 static const gchar *ALT_AUDIO_PLAYLIST_WITH_VIDEO_AUDIO = "#EXTM3U\n\
201 #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"aac\",NAME=\"English\",\
202   DEFAULT=YES,AUTOSELECT=YES,LANGUAGE=\"en\" \n\
203 #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"aac\",NAME=\"Deutsche\",\
204   DEFAULT=NO,AUTOSELECT=YES,LANGUAGE=\"de\",\
205   URI=\"http://localhost/main/german-audio.m3u8\"\n\
206 #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"aac\",NAME=\"Commentary\",\
207   DEFAULT=NO,AUTOSELECT=NO,\
208   URI=\"http://localhost/commentary/audio-only.m3u8\"\n\
209 #EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS=\"avc1.42001f, mp4a.40.5\",AUDIO=\"aac\"\n\
210 low/video-audio.m3u8\n\
211 #EXT-X-STREAM-INF:BANDWIDTH=256000,CODECS=\"avc1.42001f, mp4a.40.5\",AUDIO=\"aac\"\n\
212 mid/video-audio.m3u8\n\
213 #EXT-X-STREAM-INF:BANDWIDTH=768000,CODECS=\"avc1.42001f, mp4a.40.5\",AUDIO=\"aac\"\n\
214 hi/video-audio.m3u8\n\
215 #EXT-X-STREAM-INF:BANDWIDTH=65000,CODECS=\"mp4a.40.5\",AUDIO=\"aac\"\n\
216 main/english-audio.m3u8";
217
218 static const gchar *ON_DEMAND_LOW_VIDEO_ONLY_PLAYLIST = "#EXTM3U \n\
219 #EXT-X-TARGETDURATION:10\n\
220 #EXTINF:10,Test\n\
221 http://media.example.com/low/video-only-001.ts\n\
222 #EXTINF:10,Test\n\
223 http://media.example.com/low/video-only-002.ts\n\
224 #EXTINF:10,Test\n\
225 http://media.example.com/low/video-only-003.ts\n\
226 #EXTINF:10,Test\n\
227 http://media.example.com/low/video-only-004.ts\n\
228 #EXT-X-ENDLIST";
229
230 static const gchar *ON_DEMAND_MID_VIDEO_ONLY_PLAYLIST = "#EXTM3U \n\
231 #EXT-X-TARGETDURATION:10\n\
232 #EXTINF:10,Test\n\
233 http://media.example.com/mid/video-only-001.ts\n\
234 #EXTINF:10,Test\n\
235 http://media.example.com/mid/video-only-002.ts\n\
236 #EXTINF:10,Test\n\
237 http://media.example.com/mid/video-only-003.ts\n\
238 #EXTINF:10,Test\n\
239 http://media.example.com/mid/video-only-004.ts\n\
240 #EXT-X-ENDLIST";
241
242 static const gchar *ON_DEMAND_ENGLISH_PLAYLIST = "#EXTM3U \n\
243 #EXT-X-TARGETDURATION:10\n\
244 #EXTINF:10,Test\n\
245 http://media.example.com/audio/english-001.ts\n\
246 #EXTINF:10,Test\n\
247 http://media.example.com/audio/english-002.ts\n\
248 #EXTINF:10,Test\n\
249 http://media.example.com/audio/english-003.ts\n\
250 #EXTINF:10,Test\n\
251 http://media.example.com/audio/english-004.ts\n\
252 #EXT-X-ENDLIST";
253
254 static const gchar *ON_DEMAND_GERMAN_PLAYLIST = "#EXTM3U \n\
255 #EXT-X-TARGETDURATION:10\n\
256 #EXTINF:10,Test\n\
257 http://media.example.com/audio/german-001.ts\n\
258 #EXTINF:10,Test\n\
259 http://media.example.com/audio/german-002.ts\n\
260 #EXTINF:10,Test\n\
261 http://media.example.com/audio/german-003.ts\n\
262 #EXTINF:10,Test\n\
263 http://media.example.com/audio/german-004.ts\n\
264 #EXT-X-ENDLIST";
265
266 static const gchar *SUBTITLES_PLAYLIST = "#EXTM3U\n\
267 #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"English\",\
268   DEFAULT=YES,LANGUAGE=\"en\",\
269   URI=\"http://localhost/main/subs-en.m3u8\"\n\
270 #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"Deutsche\",\
271   DEFAULT=NO,LANGUAGE=\"de\",\
272   URI=\"http://localhost/main/subs-de.m3u8\"\n\
273 #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"Spanish\",\
274   DEFAULT=NO,LANGUAGE=\"es\",\
275   URI=\"http://localhost/main/subs-es.m3u8\"\n\
276 #EXT-X-STREAM-INF:BANDWIDTH=128000,CODECS=\"avc1.42001f, mp4a.40.5\",SUBTITLES=\"subs\"\n\
277 low/video-audio.m3u8\n\
278 #EXT-X-STREAM-INF:BANDWIDTH=256000,CODECS=\"avc1.42001f, mp4a.40.5\",SUBTITLES=\"subs\"\n\
279 mid/video-audio.m3u8\n\
280 #EXT-X-STREAM-INF:BANDWIDTH=768000,CODECS=\"avc1.42001f, mp4a.40.5\",SUBTITLES=\"subs\"\n\
281 hi/video-audio.m3u8";
282 #endif
283
284 static const gchar *AES_128_ENCRYPTED_PLAYLIST = "#EXTM3U \n\
285 #EXT-X-TARGETDURATION:10\n\
286 #EXTINF:10,Test\n\
287 http://media.example.com/mid/video-only-001.ts\n\
288 #EXT-X-KEY:METHOD=NONE\n\
289 #EXTINF:10,Test\n\
290 http://media.example.com/mid/video-only-002.ts\n\
291 #EXT-X-KEY:METHOD=AES-128,URI=\"https://priv.example.com/key.bin\"\n\
292 #EXTINF:10,Test\n\
293 http://media.example.com/mid/video-only-003.ts\n\
294 #EXT-X-KEY:METHOD=AES-128,URI=\"https://priv.example.com/key2.bin\",IV=0x00000000000000000000000000000001\n\
295 #EXTINF:10,Test\n\
296 http://media.example.com/mid/video-only-004.ts\n\
297 #EXTINF:10,Test\n\
298 http://media.example.com/mid/video-only-005.ts\n\
299 #EXT-X-ENDLIST";
300
301 static const gchar *WINDOWS_LINE_ENDINGS_PLAYLIST = "#EXTM3U \r\n\
302 #EXT-X-TARGETDURATION:10\r\n\
303 #EXTINF:10,Test\r\n\
304 http://media.example.com/001.ts\r\n\
305 #EXTINF:10,Test\r\n\
306 http://media.example.com/002.ts\r\n\
307 #EXTINF:10,Test\r\n\
308 http://media.example.com/003.ts\r\n\
309 #EXTINF:10,Test\r\n\
310 http://media.example.com/004.ts\r\n\
311 #EXT-X-ENDLIST";
312
313 static const gchar *WINDOWS_LINE_ENDINGS_VARIANT_PLAYLIST = "#EXTM3U \r\n\
314 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=128000\r\n\
315 http://example.com/low.m3u8\r\n\
316 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000\r\n\
317 http://example.com/mid.m3u8\r\n\
318 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=768000\r\n\
319 http://example.com/hi.m3u8\r\n\
320 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS=\"mp4a.40.5\"\r\n\
321 http://example.com/audio-only.m3u8";
322
323 static GstHLSMasterPlaylist *
324 load_playlist (const gchar * data)
325 {
326   GstHLSMasterPlaylist *master;
327
328   master = gst_hls_master_playlist_new_from_data (g_strdup (data),
329       "http://localhost/test.m3u8");
330   fail_unless (master != NULL);
331
332   return master;
333 }
334
335 GST_START_TEST (test_load_main_playlist_invalid)
336 {
337   GstHLSMasterPlaylist *master;
338
339   master =
340       gst_hls_master_playlist_new_from_data (g_strdup (INVALID_PLAYLIST), NULL);
341   fail_unless (master == NULL);
342 }
343
344 GST_END_TEST;
345
346 GST_START_TEST (test_load_main_playlist_rendition)
347 {
348   GstHLSMasterPlaylist *master;
349   GstHLSVariantStream *variant;
350
351   master = load_playlist (ON_DEMAND_PLAYLIST);
352   variant = master->default_variant;
353
354   assert_equals_int (g_list_length (variant->m3u8->files), 4);
355   assert_equals_int (master->version, 0);
356
357   gst_hls_master_playlist_unref (master);
358 }
359
360 GST_END_TEST;
361
362 static void
363 do_test_load_main_playlist_variant (const gchar * playlist)
364 {
365   GstHLSMasterPlaylist *master;
366   GstHLSVariantStream *stream;
367   GList *tmp;
368
369   master = gst_hls_master_playlist_new_from_data (g_strdup (playlist), NULL);
370   fail_unless (master != NULL);
371
372   assert_equals_int (g_list_length (master->variants), 4);
373
374   /* Audio-Only */
375   tmp = g_list_first (master->variants);
376   stream = tmp->data;
377   assert_equals_int (stream->bandwidth, 65000);
378   assert_equals_int (stream->program_id, 1);
379   assert_equals_string (stream->uri, "http://example.com/audio-only.m3u8");
380   assert_equals_string (stream->codecs, "mp4a.40.5");
381
382   /* Low */
383   tmp = g_list_next (tmp);
384   stream = tmp->data;
385   assert_equals_int (stream->bandwidth, 128000);
386   assert_equals_int (stream->program_id, 1);
387   assert_equals_string (stream->uri, "http://example.com/low.m3u8");
388
389   /* Mid */
390   tmp = g_list_next (tmp);
391   stream = tmp->data;
392   assert_equals_int (stream->bandwidth, 256000);
393   assert_equals_int (stream->program_id, 1);
394   assert_equals_string (stream->uri, "http://example.com/mid.m3u8");
395
396   /* High */
397   tmp = g_list_next (tmp);
398   stream = tmp->data;
399   assert_equals_int (stream->bandwidth, 768000);
400   assert_equals_int (stream->program_id, 1);
401   assert_equals_string (stream->uri, "http://example.com/hi.m3u8");
402
403   /* Check the first playlist is selected */
404   assert_equals_int (master->default_variant != NULL, TRUE);
405   assert_equals_int (master->default_variant->bandwidth, 128000);
406
407   gst_hls_master_playlist_unref (master);
408 }
409
410 GST_START_TEST (test_load_main_playlist_variant)
411 {
412   do_test_load_main_playlist_variant (VARIANT_PLAYLIST);
413 }
414
415 GST_END_TEST;
416
417 GST_START_TEST (test_load_main_playlist_variant_with_missing_uri)
418 {
419   GstHLSMasterPlaylist *master;
420
421   master = load_playlist (VARIANT_PLAYLIST_WITH_URI_MISSING);
422   assert_equals_int (g_list_length (master->variants), 3);
423   gst_hls_master_playlist_unref (master);
424 }
425
426 GST_END_TEST;
427
428 GST_START_TEST (test_load_windows_line_endings_variant_playlist)
429 {
430   do_test_load_main_playlist_variant (WINDOWS_LINE_ENDINGS_VARIANT_PLAYLIST);
431 }
432
433 GST_END_TEST;
434
435 GST_START_TEST (test_load_main_playlist_with_empty_lines)
436 {
437   do_test_load_main_playlist_variant (EMPTY_LINES_VARIANT_PLAYLIST);
438 }
439
440 GST_END_TEST;
441
442 GST_START_TEST (test_load_windows_main_playlist_with_empty_lines)
443 {
444   do_test_load_main_playlist_variant (WINDOWS_EMPTY_LINES_VARIANT_PLAYLIST);
445 }
446
447 GST_END_TEST;
448
449 static void
450 check_on_demand_playlist (const gchar * data)
451 {
452   GstHLSMasterPlaylist *master;
453   GstM3U8 *pl;
454   GstM3U8MediaFile *file;
455
456   master = load_playlist (data);
457   pl = master->default_variant->m3u8;
458
459   /* Sequence should be 0 as it's an ondemand playlist */
460   assert_equals_int (pl->sequence, 0);
461   /* Check that we are not live */
462   assert_equals_int (gst_m3u8_is_live (pl), FALSE);
463   /* Check number of entries */
464   assert_equals_int (g_list_length (pl->files), 4);
465   /* Check first media segments */
466   file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
467   assert_equals_string (file->uri, "http://media.example.com/001.ts");
468   assert_equals_int (file->sequence, 0);
469   /* Check last media segments */
470   file = GST_M3U8_MEDIA_FILE (g_list_last (pl->files)->data);
471   assert_equals_string (file->uri, "http://media.example.com/004.ts");
472   assert_equals_int (file->sequence, 3);
473
474   gst_hls_master_playlist_unref (master);
475 }
476
477 GST_START_TEST (test_on_demand_playlist)
478 {
479   check_on_demand_playlist (ON_DEMAND_PLAYLIST);
480 }
481
482 GST_END_TEST;
483
484 GST_START_TEST (test_windows_line_endings_playlist)
485 {
486   check_on_demand_playlist (WINDOWS_LINE_ENDINGS_PLAYLIST);
487 }
488
489 GST_END_TEST;
490
491 GST_START_TEST (test_empty_lines_playlist)
492 {
493   check_on_demand_playlist (EMPTY_LINES_PLAYLIST);
494 }
495
496 GST_END_TEST;
497
498 GST_START_TEST (test_windows_empty_lines_playlist)
499 {
500   check_on_demand_playlist (WINDOWS_EMPTY_LINES_PLAYLIST);
501 }
502
503 GST_END_TEST;
504
505 GST_START_TEST (test_live_playlist)
506 {
507   GstHLSMasterPlaylist *master;
508   GstM3U8 *pl;
509   GstM3U8MediaFile *file;
510   gint64 start = -1;
511   gint64 stop = -1;
512
513   master = load_playlist (LIVE_PLAYLIST);
514
515   pl = master->default_variant->m3u8;
516   /* Check that we are live */
517   assert_equals_int (gst_m3u8_is_live (pl), TRUE);
518   assert_equals_int (pl->sequence, 2680);
519   /* Check number of entries */
520   assert_equals_int (g_list_length (pl->files), 4);
521   /* Check first media segments */
522   file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
523   assert_equals_string (file->uri,
524       "https://priv.example.com/fileSequence2680.ts");
525   assert_equals_int (file->sequence, 2680);
526   /* Check last media segments */
527   file = GST_M3U8_MEDIA_FILE (g_list_last (pl->files)->data);
528   assert_equals_string (file->uri,
529       "https://priv.example.com/fileSequence2683.ts");
530   assert_equals_int (file->sequence, 2683);
531   fail_unless (gst_m3u8_get_seek_range (pl, &start, &stop));
532   assert_equals_int64 (start, 0);
533   assert_equals_float (stop / (double) GST_SECOND, 8.0);
534
535   gst_hls_master_playlist_unref (master);
536 }
537
538 GST_END_TEST;
539
540 /* This test is for live sreams in which we pause the stream for more than the
541  * DVR window and we resume playback. The playlist has rotated completely and
542  * there is a jump in the media sequence that must be handled correctly. */
543 GST_START_TEST (test_live_playlist_rotated)
544 {
545   GstHLSMasterPlaylist *master;
546   GstM3U8 *pl;
547   GstM3U8MediaFile *file;
548   gboolean ret;
549
550   master = load_playlist (LIVE_PLAYLIST);
551   pl = master->default_variant->m3u8;
552
553   assert_equals_int (pl->sequence, 2680);
554   /* Check first media segments */
555   file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
556   assert_equals_int (file->sequence, 2680);
557
558   ret = gst_m3u8_update (pl, g_strdup (LIVE_ROTATED_PLAYLIST));
559   assert_equals_int (ret, TRUE);
560   file = gst_m3u8_get_next_fragment (pl, TRUE, NULL, NULL);
561   fail_unless (file != NULL);
562   gst_m3u8_media_file_unref (file);
563
564   /* FIXME: Sequence should last - 3. Should it? */
565   assert_equals_int (pl->sequence, 3001);
566   /* Check first media segments */
567   file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
568   assert_equals_int (file->sequence, 3001);
569
570   gst_hls_master_playlist_unref (master);
571 }
572
573 GST_END_TEST;
574
575 GST_START_TEST (test_playlist_with_doubles_duration)
576 {
577   GstHLSMasterPlaylist *master;
578   GstM3U8 *pl;
579   GstM3U8MediaFile *file;
580   gint64 start = -1;
581   gint64 stop = -1;
582
583   master = load_playlist (DOUBLES_PLAYLIST);
584   pl = master->default_variant->m3u8;
585
586   /* Check first media segments */
587   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 0));
588   assert_equals_float (file->duration / (double) GST_SECOND, 10.321);
589   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 1));
590   assert_equals_float (file->duration / (double) GST_SECOND, 9.6789);
591   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 2));
592   assert_equals_float (file->duration / (double) GST_SECOND, 10.2344);
593   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 3));
594   assert_equals_float (file->duration / (double) GST_SECOND, 9.92);
595   fail_unless (gst_m3u8_get_seek_range (pl, &start, &stop));
596   assert_equals_int64 (start, 0);
597   assert_equals_float (stop / (double) GST_SECOND,
598       10.321 + 9.6789 + 10.2344 + 9.92);
599
600   gst_hls_master_playlist_unref (master);
601 }
602
603 GST_END_TEST;
604
605 GST_START_TEST (test_playlist_with_encryption)
606 {
607   GstHLSMasterPlaylist *master;
608   GstM3U8 *pl;
609   GstM3U8MediaFile *file;
610   guint8 iv1[16] = { 0, };
611   guint8 iv2[16] = { 0, };
612
613   iv1[15] = 1;
614   iv2[15] = 2;
615
616   master = load_playlist (AES_128_ENCRYPTED_PLAYLIST);
617   pl = master->default_variant->m3u8;
618
619   assert_equals_int (g_list_length (pl->files), 5);
620
621   /* Check all media segments */
622   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 0));
623   fail_unless (file->key == NULL);
624
625   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 1));
626   fail_unless (file->key == NULL);
627
628   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 2));
629   fail_unless (file->key != NULL);
630   assert_equals_string (file->key, "https://priv.example.com/key.bin");
631   fail_unless (memcmp (&file->iv, iv2, 16) == 0);
632
633   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 3));
634   fail_unless (file->key != NULL);
635   assert_equals_string (file->key, "https://priv.example.com/key2.bin");
636   fail_unless (memcmp (&file->iv, iv1, 16) == 0);
637
638   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 4));
639   fail_unless (file->key != NULL);
640   assert_equals_string (file->key, "https://priv.example.com/key2.bin");
641   fail_unless (memcmp (&file->iv, iv1, 16) == 0);
642
643   gst_hls_master_playlist_unref (master);
644 }
645
646 GST_END_TEST;
647
648
649 GST_START_TEST (test_update_invalid_playlist)
650 {
651   GstHLSMasterPlaylist *master;
652   GstM3U8 *pl;
653   gboolean ret;
654
655   /* Test updates in on-demand playlists */
656   master = load_playlist (ON_DEMAND_PLAYLIST);
657   pl = master->default_variant->m3u8;
658   assert_equals_int (g_list_length (pl->files), 4);
659   ret = gst_m3u8_update (pl, g_strdup ("#INVALID"));
660   assert_equals_int (ret, FALSE);
661
662   gst_hls_master_playlist_unref (master);
663 }
664
665 GST_END_TEST;
666
667 GST_START_TEST (test_update_playlist)
668 {
669   GstHLSMasterPlaylist *master;
670   GstM3U8 *pl;
671   gchar *live_pl;
672   gboolean ret;
673
674   /* Test updates in on-demand playlists */
675   master = load_playlist (ON_DEMAND_PLAYLIST);
676   pl = master->default_variant->m3u8;
677   assert_equals_int (g_list_length (pl->files), 4);
678   ret = gst_m3u8_update (pl, g_strdup (ON_DEMAND_PLAYLIST));
679   assert_equals_int (ret, TRUE);
680   assert_equals_int (g_list_length (pl->files), 4);
681   gst_hls_master_playlist_unref (master);
682
683   /* Test updates in live playlists */
684   master = load_playlist (LIVE_PLAYLIST);
685   pl = master->default_variant->m3u8;
686   assert_equals_int (g_list_length (pl->files), 4);
687   /* Add a new entry to the playlist and check the update */
688   live_pl = g_strdup_printf ("%s\n%s\n%s", LIVE_PLAYLIST, "#EXTINF:8",
689       "https://priv.example.com/fileSequence2683.ts");
690   ret = gst_m3u8_update (pl, live_pl);
691   assert_equals_int (ret, TRUE);
692   assert_equals_int (g_list_length (pl->files), 5);
693   /* Test sliding window */
694   ret = gst_m3u8_update (pl, g_strdup (LIVE_PLAYLIST));
695   assert_equals_int (ret, TRUE);
696   assert_equals_int (g_list_length (pl->files), 4);
697   gst_hls_master_playlist_unref (master);
698 }
699
700 GST_END_TEST;
701
702 GST_START_TEST (test_playlist_media_files)
703 {
704   GstHLSMasterPlaylist *master;
705   GstM3U8 *pl;
706   GstM3U8MediaFile *file;
707
708   master = load_playlist (ON_DEMAND_PLAYLIST);
709   pl = master->default_variant->m3u8;
710
711   /* Check number of entries */
712   assert_equals_int (g_list_length (pl->files), 4);
713   /* Check first media segments */
714   file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
715   assert_equals_string (file->uri, "http://media.example.com/001.ts");
716   assert_equals_int (file->sequence, 0);
717   assert_equals_float (file->duration, 10 * (double) GST_SECOND);
718   assert_equals_int (file->offset, 0);
719   assert_equals_int (file->size, -1);
720   assert_equals_string (file->title, "Test");
721
722   gst_hls_master_playlist_unref (master);
723 }
724
725 GST_END_TEST;
726
727 GST_START_TEST (test_playlist_byte_range_media_files)
728 {
729   GstHLSMasterPlaylist *master;
730   GstM3U8 *pl;
731   GstM3U8MediaFile *file;
732
733   master = load_playlist (BYTE_RANGES_PLAYLIST);
734   pl = master->default_variant->m3u8;
735
736   /* Check number of entries */
737   assert_equals_int (g_list_length (pl->files), 4);
738   /* Check first media segments */
739   file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
740   assert_equals_string (file->uri, "http://media.example.com/all.ts");
741   assert_equals_int (file->sequence, 0);
742   assert_equals_float (file->duration, 10 * (double) GST_SECOND);
743   assert_equals_int (file->offset, 100);
744   assert_equals_int (file->size, 1000);
745   /* Check last media segments */
746   file = GST_M3U8_MEDIA_FILE (g_list_last (pl->files)->data);
747   assert_equals_string (file->uri, "http://media.example.com/all.ts");
748   assert_equals_int (file->sequence, 3);
749   assert_equals_float (file->duration, 10 * (double) GST_SECOND);
750   assert_equals_int (file->offset, 3000);
751   assert_equals_int (file->size, 1000);
752
753   gst_hls_master_playlist_unref (master);
754
755
756   master = load_playlist (BYTE_RANGES_ACC_OFFSET_PLAYLIST);
757   pl = master->default_variant->m3u8;
758
759   /* Check number of entries */
760   assert_equals_int (g_list_length (pl->files), 4);
761   /* Check first media segments */
762   file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
763   assert_equals_string (file->uri, "http://media.example.com/all.ts");
764   assert_equals_int (file->sequence, 0);
765   assert_equals_float (file->duration, 10 * (double) GST_SECOND);
766   assert_equals_int (file->offset, 0);
767   assert_equals_int (file->size, 1000);
768   /* Check last media segments */
769   file = GST_M3U8_MEDIA_FILE (g_list_last (pl->files)->data);
770   assert_equals_string (file->uri, "http://media.example.com/all.ts");
771   assert_equals_int (file->sequence, 3);
772   assert_equals_float (file->duration, 10 * (double) GST_SECOND);
773   assert_equals_int (file->offset, 3000);
774   assert_equals_int (file->size, 1000);
775
776   gst_hls_master_playlist_unref (master);
777 }
778
779 GST_END_TEST;
780
781 GST_START_TEST (test_get_next_fragment)
782 {
783   GstHLSMasterPlaylist *master;
784   GstM3U8 *pl;
785   GstM3U8MediaFile *mf;
786   gboolean discontinous;
787   GstClockTime timestamp;
788
789   master = load_playlist (BYTE_RANGES_PLAYLIST);
790   pl = master->default_variant->m3u8;
791
792   /* Check the next fragment */
793   mf = gst_m3u8_get_next_fragment (pl, TRUE, &timestamp, &discontinous);
794   fail_unless (mf != NULL);
795   assert_equals_int (discontinous, FALSE);
796   assert_equals_string (mf->uri, "http://media.example.com/all.ts");
797   assert_equals_uint64 (timestamp, 0);
798   assert_equals_uint64 (mf->duration, 10 * GST_SECOND);
799   assert_equals_uint64 (mf->offset, 100);
800   assert_equals_uint64 (mf->offset + mf->size, 1100);
801   gst_m3u8_media_file_unref (mf);
802
803   gst_m3u8_advance_fragment (pl, TRUE);
804
805   /* Check next media segments */
806   mf = gst_m3u8_get_next_fragment (pl, TRUE, &timestamp, &discontinous);
807   fail_unless (mf != NULL);
808   assert_equals_int (discontinous, FALSE);
809   assert_equals_string (mf->uri, "http://media.example.com/all.ts");
810   assert_equals_uint64 (timestamp, 10 * GST_SECOND);
811   assert_equals_uint64 (mf->duration, 10 * GST_SECOND);
812   assert_equals_uint64 (mf->offset, 1000);
813   assert_equals_uint64 (mf->offset + mf->size, 2000);
814   gst_m3u8_media_file_unref (mf);
815
816   gst_m3u8_advance_fragment (pl, TRUE);
817
818   /* Check next media segments */
819   mf = gst_m3u8_get_next_fragment (pl, TRUE, &timestamp, &discontinous);
820   assert_equals_int (discontinous, FALSE);
821   assert_equals_string (mf->uri, "http://media.example.com/all.ts");
822   assert_equals_uint64 (timestamp, 20 * GST_SECOND);
823   assert_equals_uint64 (mf->duration, 10 * GST_SECOND);
824   assert_equals_uint64 (mf->offset, 2000);
825   assert_equals_uint64 (mf->offset + mf->size, 3000);
826   gst_m3u8_media_file_unref (mf);
827
828   gst_hls_master_playlist_unref (master);
829 }
830
831 GST_END_TEST;
832
833 GST_START_TEST (test_get_duration)
834 {
835   GstHLSMasterPlaylist *master;
836   GstM3U8 *pl;
837
838   /* Test duration for on-demand playlists */
839   master = load_playlist (ON_DEMAND_PLAYLIST);
840   pl = master->default_variant->m3u8;
841
842   assert_equals_uint64 (gst_m3u8_get_duration (pl), 40 * GST_SECOND);
843   gst_hls_master_playlist_unref (master);
844
845   /* Test duration for live playlists */
846   master = load_playlist (LIVE_PLAYLIST);
847   pl = master->default_variant->m3u8;
848   assert_equals_uint64 (gst_m3u8_get_duration (pl), GST_CLOCK_TIME_NONE);
849
850   gst_hls_master_playlist_unref (master);
851 }
852
853 GST_END_TEST;
854
855 GST_START_TEST (test_get_target_duration)
856 {
857   GstHLSMasterPlaylist *master;
858   GstM3U8 *pl;
859
860   master = load_playlist (ON_DEMAND_PLAYLIST);
861   pl = master->default_variant->m3u8;
862
863   assert_equals_uint64 (gst_m3u8_get_target_duration (pl), 10 * GST_SECOND);
864
865   gst_hls_master_playlist_unref (master);
866 }
867
868 GST_END_TEST;
869
870
871 GST_START_TEST (test_get_stream_for_bitrate)
872 {
873   GstHLSMasterPlaylist *master;
874   GstHLSVariantStream *stream;
875
876   master = load_playlist (VARIANT_PLAYLIST);
877   stream = gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 0);
878
879   assert_equals_int (stream->bandwidth, 65000);
880
881   stream =
882       gst_hls_master_playlist_get_variant_for_bitrate (master, NULL,
883       G_MAXINT32);
884   assert_equals_int (stream->bandwidth, 768000);
885   stream =
886       gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 300000);
887   assert_equals_int (stream->bandwidth, 256000);
888   stream =
889       gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 500000);
890   assert_equals_int (stream->bandwidth, 256000);
891   stream =
892       gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 255000);
893   assert_equals_int (stream->bandwidth, 128000);
894
895   gst_hls_master_playlist_unref (master);
896 }
897
898 GST_END_TEST;
899
900 #if 0
901 static void
902 do_test_seek (GstM3U8Client * client, guint seek_pos, gint pos)
903 {
904   GstClockTime cur_pos;
905   gboolean ret;
906
907   ret = gst_m3u8_client_seek (client, seek_pos * GST_SECOND);
908   if (pos == -1) {
909     assert_equals_int (ret, FALSE);
910     return;
911   }
912   assert_equals_int (ret, TRUE);
913   gst_m3u8_client_get_current_position (client, &cur_pos, NULL);
914   assert_equals_uint64 (cur_pos, pos * GST_SECOND);
915 }
916
917 GST_START_TEST (test_seek)
918 {
919   GstM3U8Client *client;
920
921   master = load_playlist (ON_DEMAND_PLAYLIST);
922
923   /* Test seek in the middle of a fragment */
924   do_test_seek (client, 1, 0);
925   do_test_seek (client, 11, 10);
926   do_test_seek (client, 22, 20);
927   do_test_seek (client, 39, 30);
928
929   /* Test exact seeks */
930   do_test_seek (client, 0, 0);
931   do_test_seek (client, 10, 10);
932   do_test_seek (client, 20, 20);
933   do_test_seek (client, 30, 30);
934
935   /* Test invalid seeks (end if list should be 30 + 10) */
936   do_test_seek (client, 39, 30);
937   do_test_seek (client, 40, -1);
938   gst_hls_master_playlist_unref (master);
939
940   /* Test seeks on a live playlist */
941   master = load_playlist (LIVE_PLAYLIST);
942   do_test_seek (client, 0, 0);
943
944   do_test_seek (client, 8, 8);
945   do_test_seek (client, 20, 16);
946   do_test_seek (client, 30, 24);
947
948   do_test_seek (client, 3000, -1);
949   gst_hls_master_playlist_unref (master);
950 }
951
952 GST_END_TEST;
953
954 GST_START_TEST (test_alternate_audio_playlist)
955 {
956   GstM3U8Client *client;
957   GstM3U8Media *media;
958   GList *alternates;
959
960   master = load_playlist (ALTERNATE_AUDIO_PLAYLIST);
961
962   assert_equals_int (g_list_length (client->main->streams), 4);
963   assert_equals_int (g_hash_table_size (client->main->video_rendition_groups),
964       0);
965   assert_equals_int (g_hash_table_size (client->main->audio_rendition_groups),
966       1);
967   assert_equals_int (g_hash_table_size (client->
968           selected_stream->audio_alternates), 3);
969   assert_equals_int (g_hash_table_size (client->
970           selected_stream->video_alternates), 0);
971
972   alternates =
973       g_hash_table_lookup (client->main->audio_rendition_groups, "aac");
974   assert_equals_int (alternates != NULL, TRUE);
975   media = GST_M3U8_MEDIA (g_list_nth_data (alternates, 0));
976   assert_equals_int (media->media_type, GST_M3U8_MEDIA_TYPE_AUDIO);
977   assert_equals_string (media->group_id, "aac");
978   assert_equals_string (media->name, "English");
979   assert_equals_string (media->language, "en");
980   assert_equals_string (media->uri, "http://localhost/main/english-audio.m3u8");
981   assert_equals_string (media->uri, GST_M3U8 (media->playlist)->uri);
982   assert_equals_int (media->is_default, TRUE);
983   assert_equals_int (media->autoselect, TRUE);
984
985   assert_equals_int (g_hash_table_size (client->
986           selected_stream->audio_alternates), 3);
987   /* Check the list of audio alternates */
988   alternates = gst_m3u8_client_get_alternates (client,
989       GST_M3U8_MEDIA_TYPE_AUDIO);
990   assert_equals_int (g_list_length (alternates), 3);
991   /* Default comes always first */
992   assert_equals_string (g_list_nth_data (alternates, 0), "English");
993   assert_equals_string (g_list_nth_data (alternates, 1), "Commentary");
994   assert_equals_string (g_list_nth_data (alternates, 2), "Deutsche");
995
996   gst_hls_master_playlist_unref (master);
997 }
998
999 GST_END_TEST;
1000
1001 GST_START_TEST (test_subtitles_playlist)
1002 {
1003   GstM3U8Client *client;
1004   GstM3U8Media *media;
1005   GList *alternates;
1006
1007   master = load_playlist (SUBTITLES_PLAYLIST);
1008
1009   assert_equals_int (g_list_length (client->main->streams), 3);
1010   assert_equals_int (g_hash_table_size (client->main->video_rendition_groups),
1011       0);
1012   assert_equals_int (g_hash_table_size (client->main->audio_rendition_groups),
1013       0);
1014   assert_equals_int (g_hash_table_size (client->main->subtt_rendition_groups),
1015       1);
1016   assert_equals_int (g_hash_table_size (client->
1017           selected_stream->audio_alternates), 0);
1018   assert_equals_int (g_hash_table_size (client->
1019           selected_stream->video_alternates), 0);
1020   assert_equals_int (g_hash_table_size (client->
1021           selected_stream->subtt_alternates), 3);
1022
1023   alternates =
1024       g_hash_table_lookup (client->main->subtt_rendition_groups, "subs");
1025   assert_equals_int (alternates != NULL, TRUE);
1026   media = GST_M3U8_MEDIA (g_list_nth_data (alternates, 0));
1027   assert_equals_int (media->media_type, GST_M3U8_MEDIA_TYPE_SUBTITLES);
1028   assert_equals_string (media->group_id, "subs");
1029   assert_equals_string (media->name, "English");
1030   assert_equals_string (media->language, "en");
1031   assert_equals_string (media->uri, "http://localhost/main/subs-en.m3u8");
1032   assert_equals_string (media->uri, GST_M3U8 (media->playlist)->uri);
1033   assert_equals_int (media->is_default, TRUE);
1034   assert_equals_int (media->autoselect, FALSE);
1035
1036   /* Check the list of subtitles */
1037   alternates = gst_m3u8_client_get_alternates (client,
1038       GST_M3U8_MEDIA_TYPE_SUBTITLES);
1039   assert_equals_int (g_list_length (alternates), 3);
1040   assert_equals_string (g_list_nth_data (alternates, 0), "Deutsche");
1041   assert_equals_string (g_list_nth_data (alternates, 1), "Spanish");
1042   assert_equals_string (g_list_nth_data (alternates, 2), "English");
1043
1044   gst_hls_master_playlist_unref (master);
1045 }
1046
1047 GST_END_TEST;
1048 GST_START_TEST (test_select_subs_alternate)
1049 {
1050   GstM3U8Client *client;
1051   const gchar *a_uri, *v_uri, *s_uri;
1052   gboolean ret;
1053
1054   /* Check with a playlist with alternative audio renditions where the video
1055    * stream is video-only and therefor we always have 2 playlists, one for
1056    * video and another one for audio */
1057   master = load_playlist (SUBTITLES_PLAYLIST);
1058   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1059   assert_equals_int (a_uri == NULL, TRUE);
1060   assert_equals_int (s_uri != NULL, TRUE);
1061   assert_equals_string (s_uri, "http://localhost/main/subs-de.m3u8");
1062   assert_equals_int (v_uri != NULL, TRUE);
1063   assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1064
1065   ret =
1066       gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_SUBTITLES,
1067       "English");
1068   assert_equals_int (ret, TRUE);
1069   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1070   assert_equals_int (a_uri == NULL, TRUE);
1071   assert_equals_int (v_uri != NULL, TRUE);
1072   assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1073   assert_equals_int (s_uri != NULL, TRUE);
1074   assert_equals_string (s_uri, "http://localhost/main/subs-en.m3u8");
1075
1076   ret =
1077       gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_SUBTITLES,
1078       "Spanish");
1079   assert_equals_int (ret, TRUE);
1080   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1081   assert_equals_int (a_uri == NULL, TRUE);
1082   assert_equals_int (v_uri != NULL, TRUE);
1083   assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1084   assert_equals_int (s_uri != NULL, TRUE);
1085   assert_equals_string (s_uri, "http://localhost/main/subs-es.m3u8");
1086
1087   ret =
1088       gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_SUBTITLES,
1089       NULL);
1090   assert_equals_int (ret, TRUE);
1091   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1092   assert_equals_int (a_uri == NULL, TRUE);
1093   assert_equals_int (v_uri != NULL, TRUE);
1094   assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1095   assert_equals_int (s_uri == NULL, TRUE);
1096
1097   gst_hls_master_playlist_unref (master);
1098 }
1099
1100 GST_END_TEST;
1101 GST_START_TEST (test_select_alternate)
1102 {
1103   GstM3U8Client *client;
1104   const gchar *a_uri, *v_uri, *s_uri;
1105   gboolean ret;
1106
1107   /* Check with a playlist with alternative audio renditions where the video
1108    * stream is video-only and therefor we always have 2 playlists, one for
1109    * video and another one for audio */
1110   master = load_playlist (ALTERNATE_AUDIO_PLAYLIST);
1111   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1112   assert_equals_int (a_uri != NULL, TRUE);
1113   assert_equals_string (a_uri, "http://localhost/main/english-audio.m3u8");
1114   assert_equals_int (v_uri != NULL, TRUE);
1115   assert_equals_string (v_uri, "http://localhost/low/video-only.m3u8");
1116   assert_equals_int (s_uri == NULL, TRUE);
1117
1118   ret =
1119       gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_AUDIO,
1120       "Deutsche");
1121   assert_equals_int (ret, TRUE);
1122   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1123   assert_equals_int (a_uri != NULL, TRUE);
1124   assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1125   assert_equals_int (v_uri != NULL, TRUE);
1126   assert_equals_string (v_uri, "http://localhost/low/video-only.m3u8");
1127   assert_equals_int (s_uri == NULL, TRUE);
1128
1129   /* Check that selecting the audio-only fallback stream we only have the audio
1130    * uri */
1131   gst_m3u8_client_set_current (client,
1132       GST_M3U8_STREAM (client->main->streams->data));
1133   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1134   assert_equals_int (a_uri != NULL, TRUE);
1135   assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1136   assert_equals_int (v_uri == NULL, TRUE);
1137   assert_equals_int (s_uri == NULL, TRUE);
1138
1139   gst_hls_master_playlist_unref (master);
1140
1141   /* Now check with a playlist with alternative audio renditions where the
1142    * video * stream has the default audio rendition muxed and therefore we
1143    * only have 2 playlists when the audio alternative rendition is not the
1144    * default one */
1145   master = load_playlist (ALT_AUDIO_PLAYLIST_WITH_VIDEO_AUDIO);
1146   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1147   assert_equals_int (a_uri == NULL, TRUE);
1148   assert_equals_int (v_uri != NULL, TRUE);
1149   assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1150   assert_equals_int (s_uri == NULL, TRUE);
1151
1152   /* Check that selecting the audio-only fallback stream we only have the audio
1153    * uri */
1154   gst_m3u8_client_set_current (client,
1155       GST_M3U8_STREAM (client->main->streams->data));
1156   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1157   assert_equals_int (a_uri != NULL, TRUE);
1158   assert_equals_string (a_uri, "http://localhost/main/english-audio.m3u8");
1159   assert_equals_int (v_uri == NULL, TRUE);
1160   assert_equals_int (s_uri == NULL, TRUE);
1161
1162   /* Get back to the audio-video stream */
1163   gst_m3u8_client_set_current (client,
1164       GST_M3U8_STREAM (client->main->streams->next->data));
1165   /* Now set a different audio and check that we have 2 playlists */
1166   ret =
1167       gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_AUDIO,
1168       "Deutsche");
1169   assert_equals_int (ret, TRUE);
1170   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1171   assert_equals_int (a_uri != NULL, TRUE);
1172   assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1173   assert_equals_int (v_uri != NULL, TRUE);
1174   assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1175   assert_equals_int (s_uri == NULL, TRUE);
1176
1177   gst_hls_master_playlist_unref (master);
1178 }
1179
1180 GST_END_TEST;
1181
1182 GST_START_TEST (test_simulation)
1183 {
1184   GstM3U8Client *client;
1185   const gchar *a_uri, *v_uri, *s_uri;
1186   GstFragment *a_frag, *v_frag, *s_frag;
1187   gboolean ret;
1188
1189   master = load_playlist (ALTERNATE_AUDIO_PLAYLIST);
1190   /* The default selection should be audio-only, which only has audio and not
1191    * video */
1192   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1193   assert_equals_int (a_uri != NULL, TRUE);
1194   assert_equals_string (a_uri, "http://localhost/main/english-audio.m3u8");
1195   assert_equals_int (v_uri != NULL, TRUE);
1196   assert_equals_string (v_uri, "http://localhost/low/video-only.m3u8");
1197   assert_equals_int (s_uri == NULL, TRUE);
1198
1199   /* Update the playlists */
1200   ret = gst_m3u8_update (client,
1201       g_strdup (ON_DEMAND_LOW_VIDEO_ONLY_PLAYLIST),
1202       g_strdup (ON_DEMAND_ENGLISH_PLAYLIST), NULL);
1203   assert_equals_int (ret, TRUE);
1204   assert_equals_int (g_list_length (client->selected_stream->selected_video->
1205           files), 4);
1206   assert_equals_int (g_list_length (client->selected_stream->selected_audio->
1207           files), 4);
1208
1209   /* Get the first fragment */
1210   gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1211   assert_equals_int (v_frag != NULL, TRUE);
1212   assert_equals_int (a_frag != NULL, TRUE);
1213   assert_equals_string (v_frag->name,
1214       "http://media.example.com/low/video-only-001.ts");
1215   assert_equals_string (a_frag->name,
1216       "http://media.example.com/audio/english-001.ts");
1217   g_object_unref (v_frag);
1218   g_object_unref (a_frag);
1219
1220   /* Get the next fragment */
1221   gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1222   assert_equals_int (v_frag != NULL, TRUE);
1223   assert_equals_int (a_frag != NULL, TRUE);
1224   assert_equals_string (v_frag->name,
1225       "http://media.example.com/low/video-only-002.ts");
1226   assert_equals_string (a_frag->name,
1227       "http://media.example.com/audio/english-002.ts");
1228   g_object_unref (v_frag);
1229   g_object_unref (a_frag);
1230
1231   /* Switch to German audio */
1232   ret =
1233       gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_AUDIO,
1234       "Deutsche");
1235   assert_equals_int (ret, TRUE);
1236   /* Get the new uri's */
1237   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1238   assert_equals_int (a_uri != NULL, TRUE);
1239   assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1240   /* On demand  so the uri does not need to be downloaded again */
1241   assert_equals_int (v_uri == NULL, TRUE);
1242   assert_equals_int (s_uri == NULL, TRUE);
1243   /* Update the new uri's */
1244   ret =
1245       gst_m3u8_update (client,
1246       g_strdup (ON_DEMAND_LOW_VIDEO_ONLY_PLAYLIST),
1247       g_strdup (ON_DEMAND_GERMAN_PLAYLIST), NULL);
1248   assert_equals_int (ret, TRUE);
1249   gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1250   assert_equals_int (s_frag == NULL, TRUE);
1251   assert_equals_int (v_frag != NULL, TRUE);
1252   assert_equals_int (a_frag != NULL, TRUE);
1253   assert_equals_string (a_frag->name,
1254       "http://media.example.com/audio/german-003.ts");
1255   assert_equals_string (v_frag->name,
1256       "http://media.example.com/low/video-only-003.ts");
1257   g_object_unref (v_frag);
1258   g_object_unref (a_frag);
1259
1260   /* Switch to a higher bitrate */
1261   gst_m3u8_client_set_current (client,
1262       gst_m3u8_client_get_stream_for_bitrate (client, 260000));
1263   gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1264   assert_equals_int (a_uri != NULL, TRUE);
1265   assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1266   assert_equals_int (v_uri != NULL, TRUE);
1267   assert_equals_string (v_uri, "http://localhost/mid/video-only.m3u8");
1268   assert_equals_int (s_uri == NULL, TRUE);
1269   ret =
1270       gst_m3u8_update (client,
1271       g_strdup (ON_DEMAND_MID_VIDEO_ONLY_PLAYLIST),
1272       g_strdup (ON_DEMAND_GERMAN_PLAYLIST), NULL);
1273   assert_equals_int (ret, TRUE);
1274   gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1275   assert_equals_int (s_frag == NULL, TRUE);
1276   assert_equals_int (a_frag != NULL, TRUE);
1277   assert_equals_int (v_frag != NULL, TRUE);
1278   assert_equals_string (a_frag->name,
1279       "http://media.example.com/audio/german-004.ts");
1280   assert_equals_string (v_frag->name,
1281       "http://media.example.com/mid/video-only-004.ts");
1282   g_object_unref (v_frag);
1283   g_object_unref (a_frag);
1284
1285   /* Seek to the beginning */
1286   gst_m3u8_client_seek (client, 0);
1287   gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1288   assert_equals_int (s_frag == NULL, TRUE);
1289   assert_equals_int (a_frag != NULL, TRUE);
1290   assert_equals_int (v_frag != NULL, TRUE);
1291   assert_equals_string (a_frag->name,
1292       "http://media.example.com/audio/german-001.ts");
1293   assert_equals_string (v_frag->name,
1294       "http://media.example.com/mid/video-only-001.ts");
1295   g_object_unref (v_frag);
1296   g_object_unref (a_frag);
1297
1298   /* Select English audio again */
1299   ret =
1300       gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_AUDIO,
1301       "English");
1302   assert_equals_int (ret, TRUE);
1303   gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1304   assert_equals_int (s_frag == NULL, TRUE);
1305   assert_equals_int (a_frag != NULL, TRUE);
1306   assert_equals_int (v_frag != NULL, TRUE);
1307   assert_equals_string (a_frag->name,
1308       "http://media.example.com/audio/english-002.ts");
1309   assert_equals_string (v_frag->name,
1310       "http://media.example.com/mid/video-only-002.ts");
1311   g_object_unref (v_frag);
1312   g_object_unref (a_frag);
1313
1314   /* Go to the audio-only fallback */
1315   gst_m3u8_client_set_current (client,
1316       gst_m3u8_client_get_stream_for_bitrate (client, 20000));
1317   gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1318   assert_equals_int (s_frag == NULL, TRUE);
1319   assert_equals_int (a_frag != NULL, TRUE);
1320   assert_equals_int (v_frag == NULL, TRUE);
1321   assert_equals_string (a_frag->name,
1322       "http://media.example.com/audio/english-003.ts");
1323   g_object_unref (a_frag);
1324
1325   /* Go to mid again */
1326   gst_m3u8_client_set_current (client,
1327       gst_m3u8_client_get_stream_for_bitrate (client, 260000));
1328   gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1329   assert_equals_int (s_frag == NULL, TRUE);
1330   assert_equals_int (a_frag != NULL, TRUE);
1331   assert_equals_int (v_frag != NULL, TRUE);
1332   assert_equals_string (a_frag->name,
1333       "http://media.example.com/audio/english-004.ts");
1334   assert_equals_string (v_frag->name,
1335       "http://media.example.com/mid/video-only-004.ts");
1336   g_object_unref (a_frag);
1337   g_object_unref (v_frag);
1338
1339   /* End of stream */
1340   ret = gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1341   assert_equals_int (ret, FALSE);
1342
1343   gst_hls_master_playlist_unref (master);
1344 }
1345
1346 GST_END_TEST;
1347 #endif
1348
1349 GST_START_TEST (test_url_with_slash_query_param)
1350 {
1351   static const gchar *MASTER_PLAYLIST = "#EXTM3U \n"
1352       "#EXT-X-VERSION:4\n"
1353       "#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=1251135, CODECS=\"avc1.42001f, mp4a.40.2\", RESOLUTION=640x352\n"
1354       "1251/media.m3u8?acl=/*1054559_h264_1500k.mp4\n";
1355   GstHLSMasterPlaylist *master;
1356   GstHLSVariantStream *stream;
1357   GstM3U8 *media;
1358
1359   master = load_playlist (MASTER_PLAYLIST);
1360
1361   assert_equals_int (g_list_length (master->variants), 1);
1362   stream = g_list_nth_data (master->variants, 0);
1363   media = stream->m3u8;
1364
1365   assert_equals_string (media->uri,
1366       "http://localhost/1251/media.m3u8?acl=/*1054559_h264_1500k.mp4");
1367   gst_hls_master_playlist_unref (master);
1368 }
1369
1370 GST_END_TEST;
1371
1372 GST_START_TEST (test_stream_inf_tag)
1373 {
1374   static const gchar *MASTER_PLAYLIST = "#EXTM3U \n"
1375       "#EXT-X-VERSION:4\n"
1376       "#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=1251135, CODECS=\"avc1.42001f, mp4a.40.2\", RESOLUTION=640x352\n"
1377       "media.m3u8\n";
1378   GstHLSMasterPlaylist *master;
1379   GstHLSVariantStream *stream;
1380
1381   master = load_playlist (MASTER_PLAYLIST);
1382
1383   assert_equals_int (g_list_length (master->variants), 1);
1384   stream = g_list_nth_data (master->variants, 0);
1385
1386   assert_equals_int64 (stream->program_id, 1);
1387   assert_equals_int64 (stream->width, 640);
1388   assert_equals_int64 (stream->height, 352);
1389   assert_equals_int64 (stream->bandwidth, 1251135);
1390   assert_equals_string (stream->codecs, "avc1.42001f, mp4a.40.2");
1391   gst_hls_master_playlist_unref (master);
1392 }
1393
1394 GST_END_TEST;
1395
1396 static Suite *
1397 hlsdemux_suite (void)
1398 {
1399   Suite *s = suite_create ("hlsdemux_m3u8");
1400   TCase *tc_m3u8 = tcase_create ("m3u8client");
1401
1402   GST_DEBUG_CATEGORY_INIT (hls_debug, "hlsdemux_m3u", 0, "hlsdemux m3u test");
1403
1404   suite_add_tcase (s, tc_m3u8);
1405   tcase_add_test (tc_m3u8, test_load_main_playlist_invalid);
1406   tcase_add_test (tc_m3u8, test_load_main_playlist_rendition);
1407   tcase_add_test (tc_m3u8, test_load_main_playlist_variant);
1408   tcase_add_test (tc_m3u8, test_load_main_playlist_variant_with_missing_uri);
1409   tcase_add_test (tc_m3u8, test_load_windows_line_endings_variant_playlist);
1410   tcase_add_test (tc_m3u8, test_load_main_playlist_with_empty_lines);
1411   tcase_add_test (tc_m3u8, test_load_windows_main_playlist_with_empty_lines);
1412   tcase_add_test (tc_m3u8, test_on_demand_playlist);
1413   tcase_add_test (tc_m3u8, test_windows_line_endings_playlist);
1414   tcase_add_test (tc_m3u8, test_windows_empty_lines_playlist);
1415   tcase_add_test (tc_m3u8, test_empty_lines_playlist);
1416   tcase_add_test (tc_m3u8, test_live_playlist);
1417   tcase_add_test (tc_m3u8, test_live_playlist_rotated);
1418   tcase_add_test (tc_m3u8, test_playlist_with_doubles_duration);
1419   tcase_add_test (tc_m3u8, test_playlist_with_encryption);
1420   tcase_add_test (tc_m3u8, test_update_invalid_playlist);
1421   tcase_add_test (tc_m3u8, test_update_playlist);
1422   tcase_add_test (tc_m3u8, test_playlist_media_files);
1423   tcase_add_test (tc_m3u8, test_playlist_byte_range_media_files);
1424   tcase_add_test (tc_m3u8, test_get_next_fragment);
1425   tcase_add_test (tc_m3u8, test_get_duration);
1426   tcase_add_test (tc_m3u8, test_get_target_duration);
1427   tcase_add_test (tc_m3u8, test_get_stream_for_bitrate);
1428 #if 0
1429   tcase_add_test (tc_m3u8, test_seek);
1430   tcase_add_test (tc_m3u8, test_alternate_audio_playlist);
1431   tcase_add_test (tc_m3u8, test_subtitles_playlist);
1432   tcase_add_test (tc_m3u8, test_select_alternate);
1433   tcase_add_test (tc_m3u8, test_select_subs_alternate);
1434   tcase_add_test (tc_m3u8, test_simulation);
1435 #endif
1436   tcase_add_test (tc_m3u8, test_url_with_slash_query_param);
1437   tcase_add_test (tc_m3u8, test_stream_inf_tag);
1438   return s;
1439 }
1440
1441 GST_CHECK_MAIN (hlsdemux);