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 const gchar *MAP_TAG_PLAYLIST = "#EXTM3U \n\
324 #EXT-X-VERSION:7\n\
325 #EXT-X-MAP:URI=\"init1.mp4\",BYTERANGE=\"50@50\"\n\
326 #EXTINF:6.00000,\n\
327 #EXT-X-BYTERANGE:100@50\n\
328 main.mp4\n\
329 #EXTINF:6.00000,\n\
330 #EXT-X-BYTERANGE:100@150\n\
331 main.mp4\n\
332 #EXT-X-MAP:URI=\"init2.mp4\"\n\
333 #EXTINF:6.00000,\n\
334 #EXT-X-BYTERANGE:100@300\n\
335 main.mp4\n\
336 #EXT-X-ENDLIST";
337
338 static GstHLSMasterPlaylist *
load_playlist(const gchar * data)339 load_playlist (const gchar * data)
340 {
341 GstHLSMasterPlaylist *master;
342
343 master = gst_hls_master_playlist_new_from_data (g_strdup (data),
344 "http://localhost/test.m3u8");
345 fail_unless (master != NULL);
346
347 return master;
348 }
349
GST_START_TEST(test_load_main_playlist_invalid)350 GST_START_TEST (test_load_main_playlist_invalid)
351 {
352 GstHLSMasterPlaylist *master;
353
354 master =
355 gst_hls_master_playlist_new_from_data (g_strdup (INVALID_PLAYLIST), NULL);
356 fail_unless (master == NULL);
357 }
358
359 GST_END_TEST;
360
GST_START_TEST(test_load_main_playlist_rendition)361 GST_START_TEST (test_load_main_playlist_rendition)
362 {
363 GstHLSMasterPlaylist *master;
364 GstHLSVariantStream *variant;
365
366 master = load_playlist (ON_DEMAND_PLAYLIST);
367 variant = master->default_variant;
368
369 assert_equals_int (g_list_length (variant->m3u8->files), 4);
370 assert_equals_int (master->version, 0);
371
372 gst_hls_master_playlist_unref (master);
373 }
374
375 GST_END_TEST;
376
377 static void
do_test_load_main_playlist_variant(const gchar * playlist)378 do_test_load_main_playlist_variant (const gchar * playlist)
379 {
380 GstHLSMasterPlaylist *master;
381 GstHLSVariantStream *stream;
382 GList *tmp;
383
384 master = gst_hls_master_playlist_new_from_data (g_strdup (playlist), NULL);
385 fail_unless (master != NULL);
386
387 assert_equals_int (g_list_length (master->variants), 4);
388
389 /* Audio-Only */
390 tmp = g_list_first (master->variants);
391 stream = tmp->data;
392 assert_equals_int (stream->bandwidth, 65000);
393 assert_equals_int (stream->program_id, 1);
394 assert_equals_string (stream->uri, "http://example.com/audio-only.m3u8");
395 assert_equals_string (stream->codecs, "mp4a.40.5");
396
397 /* Low */
398 tmp = g_list_next (tmp);
399 stream = tmp->data;
400 assert_equals_int (stream->bandwidth, 128000);
401 assert_equals_int (stream->program_id, 1);
402 assert_equals_string (stream->uri, "http://example.com/low.m3u8");
403
404 /* Mid */
405 tmp = g_list_next (tmp);
406 stream = tmp->data;
407 assert_equals_int (stream->bandwidth, 256000);
408 assert_equals_int (stream->program_id, 1);
409 assert_equals_string (stream->uri, "http://example.com/mid.m3u8");
410
411 /* High */
412 tmp = g_list_next (tmp);
413 stream = tmp->data;
414 assert_equals_int (stream->bandwidth, 768000);
415 assert_equals_int (stream->program_id, 1);
416 assert_equals_string (stream->uri, "http://example.com/hi.m3u8");
417
418 /* Check the first playlist is selected */
419 assert_equals_int (master->default_variant != NULL, TRUE);
420 assert_equals_int (master->default_variant->bandwidth, 128000);
421
422 gst_hls_master_playlist_unref (master);
423 }
424
GST_START_TEST(test_load_main_playlist_variant)425 GST_START_TEST (test_load_main_playlist_variant)
426 {
427 do_test_load_main_playlist_variant (VARIANT_PLAYLIST);
428 }
429
430 GST_END_TEST;
431
GST_START_TEST(test_load_main_playlist_variant_with_missing_uri)432 GST_START_TEST (test_load_main_playlist_variant_with_missing_uri)
433 {
434 GstHLSMasterPlaylist *master;
435
436 master = load_playlist (VARIANT_PLAYLIST_WITH_URI_MISSING);
437 assert_equals_int (g_list_length (master->variants), 3);
438 gst_hls_master_playlist_unref (master);
439 }
440
441 GST_END_TEST;
442
GST_START_TEST(test_load_windows_line_endings_variant_playlist)443 GST_START_TEST (test_load_windows_line_endings_variant_playlist)
444 {
445 do_test_load_main_playlist_variant (WINDOWS_LINE_ENDINGS_VARIANT_PLAYLIST);
446 }
447
448 GST_END_TEST;
449
GST_START_TEST(test_load_main_playlist_with_empty_lines)450 GST_START_TEST (test_load_main_playlist_with_empty_lines)
451 {
452 do_test_load_main_playlist_variant (EMPTY_LINES_VARIANT_PLAYLIST);
453 }
454
455 GST_END_TEST;
456
GST_START_TEST(test_load_windows_main_playlist_with_empty_lines)457 GST_START_TEST (test_load_windows_main_playlist_with_empty_lines)
458 {
459 do_test_load_main_playlist_variant (WINDOWS_EMPTY_LINES_VARIANT_PLAYLIST);
460 }
461
462 GST_END_TEST;
463
464 static void
check_on_demand_playlist(const gchar * data)465 check_on_demand_playlist (const gchar * data)
466 {
467 GstHLSMasterPlaylist *master;
468 GstM3U8 *pl;
469 GstM3U8MediaFile *file;
470
471 master = load_playlist (data);
472 pl = master->default_variant->m3u8;
473
474 /* Sequence should be 0 as it's an ondemand playlist */
475 assert_equals_int (pl->sequence, 0);
476 /* Check that we are not live */
477 assert_equals_int (gst_m3u8_is_live (pl), FALSE);
478 /* Check number of entries */
479 assert_equals_int (g_list_length (pl->files), 4);
480 /* Check first media segments */
481 file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
482 assert_equals_string (file->uri, "http://media.example.com/001.ts");
483 assert_equals_int (file->sequence, 0);
484 /* Check last media segments */
485 file = GST_M3U8_MEDIA_FILE (g_list_last (pl->files)->data);
486 assert_equals_string (file->uri, "http://media.example.com/004.ts");
487 assert_equals_int (file->sequence, 3);
488
489 gst_hls_master_playlist_unref (master);
490 }
491
GST_START_TEST(test_on_demand_playlist)492 GST_START_TEST (test_on_demand_playlist)
493 {
494 check_on_demand_playlist (ON_DEMAND_PLAYLIST);
495 }
496
497 GST_END_TEST;
498
GST_START_TEST(test_windows_line_endings_playlist)499 GST_START_TEST (test_windows_line_endings_playlist)
500 {
501 check_on_demand_playlist (WINDOWS_LINE_ENDINGS_PLAYLIST);
502 }
503
504 GST_END_TEST;
505
GST_START_TEST(test_empty_lines_playlist)506 GST_START_TEST (test_empty_lines_playlist)
507 {
508 check_on_demand_playlist (EMPTY_LINES_PLAYLIST);
509 }
510
511 GST_END_TEST;
512
GST_START_TEST(test_windows_empty_lines_playlist)513 GST_START_TEST (test_windows_empty_lines_playlist)
514 {
515 check_on_demand_playlist (WINDOWS_EMPTY_LINES_PLAYLIST);
516 }
517
518 GST_END_TEST;
519
GST_START_TEST(test_live_playlist)520 GST_START_TEST (test_live_playlist)
521 {
522 GstHLSMasterPlaylist *master;
523 GstM3U8 *pl;
524 GstM3U8MediaFile *file;
525 gint64 start = -1;
526 gint64 stop = -1;
527
528 master = load_playlist (LIVE_PLAYLIST);
529
530 pl = master->default_variant->m3u8;
531 /* Check that we are live */
532 assert_equals_int (gst_m3u8_is_live (pl), TRUE);
533 assert_equals_int (pl->sequence, 2680);
534 /* Check number of entries */
535 assert_equals_int (g_list_length (pl->files), 4);
536 /* Check first media segments */
537 file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
538 assert_equals_string (file->uri,
539 "https://priv.example.com/fileSequence2680.ts");
540 assert_equals_int (file->sequence, 2680);
541 /* Check last media segments */
542 file = GST_M3U8_MEDIA_FILE (g_list_last (pl->files)->data);
543 assert_equals_string (file->uri,
544 "https://priv.example.com/fileSequence2683.ts");
545 assert_equals_int (file->sequence, 2683);
546 fail_unless (gst_m3u8_get_seek_range (pl, &start, &stop));
547 assert_equals_int64 (start, 0);
548 assert_equals_float (stop / (double) GST_SECOND, 8.0);
549
550 gst_hls_master_playlist_unref (master);
551 }
552
553 GST_END_TEST;
554
555 /* This test is for live sreams in which we pause the stream for more than the
556 * DVR window and we resume playback. The playlist has rotated completely and
557 * there is a jump in the media sequence that must be handled correctly. */
GST_START_TEST(test_live_playlist_rotated)558 GST_START_TEST (test_live_playlist_rotated)
559 {
560 GstHLSMasterPlaylist *master;
561 GstM3U8 *pl;
562 GstM3U8MediaFile *file;
563 gboolean ret;
564
565 master = load_playlist (LIVE_PLAYLIST);
566 pl = master->default_variant->m3u8;
567
568 assert_equals_int (pl->sequence, 2680);
569 /* Check first media segments */
570 file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
571 assert_equals_int (file->sequence, 2680);
572
573 ret = gst_m3u8_update (pl, g_strdup (LIVE_ROTATED_PLAYLIST));
574 assert_equals_int (ret, TRUE);
575 file = gst_m3u8_get_next_fragment (pl, TRUE, NULL, NULL);
576 fail_unless (file != NULL);
577 gst_m3u8_media_file_unref (file);
578
579 /* FIXME: Sequence should last - 3. Should it? */
580 assert_equals_int (pl->sequence, 3001);
581 /* Check first media segments */
582 file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
583 assert_equals_int (file->sequence, 3001);
584
585 gst_hls_master_playlist_unref (master);
586 }
587
588 GST_END_TEST;
589
GST_START_TEST(test_playlist_with_doubles_duration)590 GST_START_TEST (test_playlist_with_doubles_duration)
591 {
592 GstHLSMasterPlaylist *master;
593 GstM3U8 *pl;
594 GstM3U8MediaFile *file;
595 gint64 start = -1;
596 gint64 stop = -1;
597
598 master = load_playlist (DOUBLES_PLAYLIST);
599 pl = master->default_variant->m3u8;
600
601 /* Check first media segments */
602 file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 0));
603 assert_equals_float (file->duration / (double) GST_SECOND, 10.321);
604 file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 1));
605 assert_equals_float (file->duration / (double) GST_SECOND, 9.6789);
606 file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 2));
607 assert_equals_float (file->duration / (double) GST_SECOND, 10.2344);
608 file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 3));
609 assert_equals_float (file->duration / (double) GST_SECOND, 9.92);
610 fail_unless (gst_m3u8_get_seek_range (pl, &start, &stop));
611 assert_equals_int64 (start, 0);
612 assert_equals_float (stop / (double) GST_SECOND,
613 10.321 + 9.6789 + 10.2344 + 9.92);
614
615 gst_hls_master_playlist_unref (master);
616 }
617
618 GST_END_TEST;
619
GST_START_TEST(test_playlist_with_encryption)620 GST_START_TEST (test_playlist_with_encryption)
621 {
622 GstHLSMasterPlaylist *master;
623 GstM3U8 *pl;
624 GstM3U8MediaFile *file;
625 guint8 iv1[16] = { 0, };
626 guint8 iv2[16] = { 0, };
627
628 iv1[15] = 1;
629 iv2[15] = 2;
630
631 master = load_playlist (AES_128_ENCRYPTED_PLAYLIST);
632 pl = master->default_variant->m3u8;
633
634 assert_equals_int (g_list_length (pl->files), 5);
635
636 /* Check all media segments */
637 file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 0));
638 fail_unless (file->key == NULL);
639
640 file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 1));
641 fail_unless (file->key == NULL);
642
643 file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 2));
644 fail_unless (file->key != NULL);
645 assert_equals_string (file->key, "https://priv.example.com/key.bin");
646 fail_unless (memcmp (&file->iv, iv2, 16) == 0);
647
648 file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 3));
649 fail_unless (file->key != NULL);
650 assert_equals_string (file->key, "https://priv.example.com/key2.bin");
651 fail_unless (memcmp (&file->iv, iv1, 16) == 0);
652
653 file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 4));
654 fail_unless (file->key != NULL);
655 assert_equals_string (file->key, "https://priv.example.com/key2.bin");
656 fail_unless (memcmp (&file->iv, iv1, 16) == 0);
657
658 gst_hls_master_playlist_unref (master);
659 }
660
661 GST_END_TEST;
662
663
GST_START_TEST(test_update_invalid_playlist)664 GST_START_TEST (test_update_invalid_playlist)
665 {
666 GstHLSMasterPlaylist *master;
667 GstM3U8 *pl;
668 gboolean ret;
669
670 /* Test updates in on-demand playlists */
671 master = load_playlist (ON_DEMAND_PLAYLIST);
672 pl = master->default_variant->m3u8;
673 assert_equals_int (g_list_length (pl->files), 4);
674 ret = gst_m3u8_update (pl, g_strdup ("#INVALID"));
675 assert_equals_int (ret, FALSE);
676
677 gst_hls_master_playlist_unref (master);
678 }
679
680 GST_END_TEST;
681
GST_START_TEST(test_update_playlist)682 GST_START_TEST (test_update_playlist)
683 {
684 GstHLSMasterPlaylist *master;
685 GstM3U8 *pl;
686 gchar *live_pl;
687 gboolean ret;
688
689 /* Test updates in on-demand playlists */
690 master = load_playlist (ON_DEMAND_PLAYLIST);
691 pl = master->default_variant->m3u8;
692 assert_equals_int (g_list_length (pl->files), 4);
693 ret = gst_m3u8_update (pl, g_strdup (ON_DEMAND_PLAYLIST));
694 assert_equals_int (ret, TRUE);
695 assert_equals_int (g_list_length (pl->files), 4);
696 gst_hls_master_playlist_unref (master);
697
698 /* Test updates in live playlists */
699 master = load_playlist (LIVE_PLAYLIST);
700 pl = master->default_variant->m3u8;
701 assert_equals_int (g_list_length (pl->files), 4);
702 /* Add a new entry to the playlist and check the update */
703 live_pl = g_strdup_printf ("%s\n%s\n%s", LIVE_PLAYLIST, "#EXTINF:8",
704 "https://priv.example.com/fileSequence2683.ts");
705 ret = gst_m3u8_update (pl, live_pl);
706 assert_equals_int (ret, TRUE);
707 assert_equals_int (g_list_length (pl->files), 5);
708 /* Test sliding window */
709 ret = gst_m3u8_update (pl, g_strdup (LIVE_PLAYLIST));
710 assert_equals_int (ret, TRUE);
711 assert_equals_int (g_list_length (pl->files), 4);
712 gst_hls_master_playlist_unref (master);
713 }
714
715 GST_END_TEST;
716
GST_START_TEST(test_playlist_media_files)717 GST_START_TEST (test_playlist_media_files)
718 {
719 GstHLSMasterPlaylist *master;
720 GstM3U8 *pl;
721 GstM3U8MediaFile *file;
722
723 master = load_playlist (ON_DEMAND_PLAYLIST);
724 pl = master->default_variant->m3u8;
725
726 /* Check number of entries */
727 assert_equals_int (g_list_length (pl->files), 4);
728 /* Check first media segments */
729 file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
730 assert_equals_string (file->uri, "http://media.example.com/001.ts");
731 assert_equals_int (file->sequence, 0);
732 assert_equals_float (file->duration, 10 * (double) GST_SECOND);
733 assert_equals_int (file->offset, 0);
734 assert_equals_int (file->size, -1);
735 assert_equals_string (file->title, "Test");
736
737 gst_hls_master_playlist_unref (master);
738 }
739
740 GST_END_TEST;
741
GST_START_TEST(test_playlist_byte_range_media_files)742 GST_START_TEST (test_playlist_byte_range_media_files)
743 {
744 GstHLSMasterPlaylist *master;
745 GstM3U8 *pl;
746 GstM3U8MediaFile *file;
747
748 master = load_playlist (BYTE_RANGES_PLAYLIST);
749 pl = master->default_variant->m3u8;
750
751 /* Check number of entries */
752 assert_equals_int (g_list_length (pl->files), 4);
753 /* Check first media segments */
754 file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
755 assert_equals_string (file->uri, "http://media.example.com/all.ts");
756 assert_equals_int (file->sequence, 0);
757 assert_equals_float (file->duration, 10 * (double) GST_SECOND);
758 assert_equals_int (file->offset, 100);
759 assert_equals_int (file->size, 1000);
760 /* Check last media segments */
761 file = GST_M3U8_MEDIA_FILE (g_list_last (pl->files)->data);
762 assert_equals_string (file->uri, "http://media.example.com/all.ts");
763 assert_equals_int (file->sequence, 3);
764 assert_equals_float (file->duration, 10 * (double) GST_SECOND);
765 assert_equals_int (file->offset, 3000);
766 assert_equals_int (file->size, 1000);
767
768 gst_hls_master_playlist_unref (master);
769
770
771 master = load_playlist (BYTE_RANGES_ACC_OFFSET_PLAYLIST);
772 pl = master->default_variant->m3u8;
773
774 /* Check number of entries */
775 assert_equals_int (g_list_length (pl->files), 4);
776 /* Check first media segments */
777 file = GST_M3U8_MEDIA_FILE (g_list_first (pl->files)->data);
778 assert_equals_string (file->uri, "http://media.example.com/all.ts");
779 assert_equals_int (file->sequence, 0);
780 assert_equals_float (file->duration, 10 * (double) GST_SECOND);
781 assert_equals_int (file->offset, 0);
782 assert_equals_int (file->size, 1000);
783 /* Check last media segments */
784 file = GST_M3U8_MEDIA_FILE (g_list_last (pl->files)->data);
785 assert_equals_string (file->uri, "http://media.example.com/all.ts");
786 assert_equals_int (file->sequence, 3);
787 assert_equals_float (file->duration, 10 * (double) GST_SECOND);
788 assert_equals_int (file->offset, 3000);
789 assert_equals_int (file->size, 1000);
790
791 gst_hls_master_playlist_unref (master);
792 }
793
794 GST_END_TEST;
795
GST_START_TEST(test_get_next_fragment)796 GST_START_TEST (test_get_next_fragment)
797 {
798 GstHLSMasterPlaylist *master;
799 GstM3U8 *pl;
800 GstM3U8MediaFile *mf;
801 gboolean discontinuous;
802 GstClockTime timestamp;
803
804 master = load_playlist (BYTE_RANGES_PLAYLIST);
805 pl = master->default_variant->m3u8;
806
807 /* Check the next fragment */
808 mf = gst_m3u8_get_next_fragment (pl, TRUE, ×tamp, &discontinuous);
809 fail_unless (mf != NULL);
810 assert_equals_int (discontinuous, FALSE);
811 assert_equals_string (mf->uri, "http://media.example.com/all.ts");
812 assert_equals_uint64 (timestamp, 0);
813 assert_equals_uint64 (mf->duration, 10 * GST_SECOND);
814 assert_equals_uint64 (mf->offset, 100);
815 assert_equals_uint64 (mf->offset + mf->size, 1100);
816 gst_m3u8_media_file_unref (mf);
817
818 gst_m3u8_advance_fragment (pl, TRUE);
819
820 /* Check next media segments */
821 mf = gst_m3u8_get_next_fragment (pl, TRUE, ×tamp, &discontinuous);
822 fail_unless (mf != NULL);
823 assert_equals_int (discontinuous, FALSE);
824 assert_equals_string (mf->uri, "http://media.example.com/all.ts");
825 assert_equals_uint64 (timestamp, 10 * GST_SECOND);
826 assert_equals_uint64 (mf->duration, 10 * GST_SECOND);
827 assert_equals_uint64 (mf->offset, 1000);
828 assert_equals_uint64 (mf->offset + mf->size, 2000);
829 gst_m3u8_media_file_unref (mf);
830
831 gst_m3u8_advance_fragment (pl, TRUE);
832
833 /* Check next media segments */
834 mf = gst_m3u8_get_next_fragment (pl, TRUE, ×tamp, &discontinuous);
835 assert_equals_int (discontinuous, FALSE);
836 assert_equals_string (mf->uri, "http://media.example.com/all.ts");
837 assert_equals_uint64 (timestamp, 20 * GST_SECOND);
838 assert_equals_uint64 (mf->duration, 10 * GST_SECOND);
839 assert_equals_uint64 (mf->offset, 2000);
840 assert_equals_uint64 (mf->offset + mf->size, 3000);
841 gst_m3u8_media_file_unref (mf);
842
843 gst_hls_master_playlist_unref (master);
844 }
845
846 GST_END_TEST;
847
GST_START_TEST(test_get_duration)848 GST_START_TEST (test_get_duration)
849 {
850 GstHLSMasterPlaylist *master;
851 GstM3U8 *pl;
852
853 /* Test duration for on-demand playlists */
854 master = load_playlist (ON_DEMAND_PLAYLIST);
855 pl = master->default_variant->m3u8;
856
857 assert_equals_uint64 (gst_m3u8_get_duration (pl), 40 * GST_SECOND);
858 gst_hls_master_playlist_unref (master);
859
860 /* Test duration for live playlists */
861 master = load_playlist (LIVE_PLAYLIST);
862 pl = master->default_variant->m3u8;
863 assert_equals_uint64 (gst_m3u8_get_duration (pl), GST_CLOCK_TIME_NONE);
864
865 gst_hls_master_playlist_unref (master);
866 }
867
868 GST_END_TEST;
869
GST_START_TEST(test_get_target_duration)870 GST_START_TEST (test_get_target_duration)
871 {
872 GstHLSMasterPlaylist *master;
873 GstM3U8 *pl;
874
875 master = load_playlist (ON_DEMAND_PLAYLIST);
876 pl = master->default_variant->m3u8;
877
878 assert_equals_uint64 (gst_m3u8_get_target_duration (pl), 10 * GST_SECOND);
879
880 gst_hls_master_playlist_unref (master);
881 }
882
883 GST_END_TEST;
884
885
GST_START_TEST(test_get_stream_for_bitrate)886 GST_START_TEST (test_get_stream_for_bitrate)
887 {
888 GstHLSMasterPlaylist *master;
889 GstHLSVariantStream *stream;
890
891 master = load_playlist (VARIANT_PLAYLIST);
892 stream = gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 0);
893
894 assert_equals_int (stream->bandwidth, 65000);
895
896 stream =
897 gst_hls_master_playlist_get_variant_for_bitrate (master, NULL,
898 G_MAXINT32);
899 assert_equals_int (stream->bandwidth, 768000);
900 stream =
901 gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 300000);
902 assert_equals_int (stream->bandwidth, 256000);
903 stream =
904 gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 500000);
905 assert_equals_int (stream->bandwidth, 256000);
906 stream =
907 gst_hls_master_playlist_get_variant_for_bitrate (master, NULL, 255000);
908 assert_equals_int (stream->bandwidth, 128000);
909
910 gst_hls_master_playlist_unref (master);
911 }
912
913 GST_END_TEST;
914
915 #if 0
916 static void
917 do_test_seek (GstM3U8Client * client, guint seek_pos, gint pos)
918 {
919 GstClockTime cur_pos;
920 gboolean ret;
921
922 ret = gst_m3u8_client_seek (client, seek_pos * GST_SECOND);
923 if (pos == -1) {
924 assert_equals_int (ret, FALSE);
925 return;
926 }
927 assert_equals_int (ret, TRUE);
928 gst_m3u8_client_get_current_position (client, &cur_pos, NULL);
929 assert_equals_uint64 (cur_pos, pos * GST_SECOND);
930 }
931
932 GST_START_TEST (test_seek)
933 {
934 GstM3U8Client *client;
935
936 master = load_playlist (ON_DEMAND_PLAYLIST);
937
938 /* Test seek in the middle of a fragment */
939 do_test_seek (client, 1, 0);
940 do_test_seek (client, 11, 10);
941 do_test_seek (client, 22, 20);
942 do_test_seek (client, 39, 30);
943
944 /* Test exact seeks */
945 do_test_seek (client, 0, 0);
946 do_test_seek (client, 10, 10);
947 do_test_seek (client, 20, 20);
948 do_test_seek (client, 30, 30);
949
950 /* Test invalid seeks (end if list should be 30 + 10) */
951 do_test_seek (client, 39, 30);
952 do_test_seek (client, 40, -1);
953 gst_hls_master_playlist_unref (master);
954
955 /* Test seeks on a live playlist */
956 master = load_playlist (LIVE_PLAYLIST);
957 do_test_seek (client, 0, 0);
958
959 do_test_seek (client, 8, 8);
960 do_test_seek (client, 20, 16);
961 do_test_seek (client, 30, 24);
962
963 do_test_seek (client, 3000, -1);
964 gst_hls_master_playlist_unref (master);
965 }
966
967 GST_END_TEST;
968
969 GST_START_TEST (test_alternate_audio_playlist)
970 {
971 GstM3U8Client *client;
972 GstM3U8Media *media;
973 GList *alternates;
974
975 master = load_playlist (ALTERNATE_AUDIO_PLAYLIST);
976
977 assert_equals_int (g_list_length (client->main->streams), 4);
978 assert_equals_int (g_hash_table_size (client->main->video_rendition_groups),
979 0);
980 assert_equals_int (g_hash_table_size (client->main->audio_rendition_groups),
981 1);
982 assert_equals_int (g_hash_table_size (client->
983 selected_stream->audio_alternates), 3);
984 assert_equals_int (g_hash_table_size (client->
985 selected_stream->video_alternates), 0);
986
987 alternates =
988 g_hash_table_lookup (client->main->audio_rendition_groups, "aac");
989 assert_equals_int (alternates != NULL, TRUE);
990 media = GST_M3U8_MEDIA (g_list_nth_data (alternates, 0));
991 assert_equals_int (media->media_type, GST_M3U8_MEDIA_TYPE_AUDIO);
992 assert_equals_string (media->group_id, "aac");
993 assert_equals_string (media->name, "English");
994 assert_equals_string (media->language, "en");
995 assert_equals_string (media->uri, "http://localhost/main/english-audio.m3u8");
996 assert_equals_string (media->uri, GST_M3U8 (media->playlist)->uri);
997 assert_equals_int (media->is_default, TRUE);
998 assert_equals_int (media->autoselect, TRUE);
999
1000 assert_equals_int (g_hash_table_size (client->
1001 selected_stream->audio_alternates), 3);
1002 /* Check the list of audio alternates */
1003 alternates = gst_m3u8_client_get_alternates (client,
1004 GST_M3U8_MEDIA_TYPE_AUDIO);
1005 assert_equals_int (g_list_length (alternates), 3);
1006 /* Default comes always first */
1007 assert_equals_string (g_list_nth_data (alternates, 0), "English");
1008 assert_equals_string (g_list_nth_data (alternates, 1), "Commentary");
1009 assert_equals_string (g_list_nth_data (alternates, 2), "Deutsche");
1010
1011 gst_hls_master_playlist_unref (master);
1012 }
1013
1014 GST_END_TEST;
1015
1016 GST_START_TEST (test_subtitles_playlist)
1017 {
1018 GstM3U8Client *client;
1019 GstM3U8Media *media;
1020 GList *alternates;
1021
1022 master = load_playlist (SUBTITLES_PLAYLIST);
1023
1024 assert_equals_int (g_list_length (client->main->streams), 3);
1025 assert_equals_int (g_hash_table_size (client->main->video_rendition_groups),
1026 0);
1027 assert_equals_int (g_hash_table_size (client->main->audio_rendition_groups),
1028 0);
1029 assert_equals_int (g_hash_table_size (client->main->subtt_rendition_groups),
1030 1);
1031 assert_equals_int (g_hash_table_size (client->
1032 selected_stream->audio_alternates), 0);
1033 assert_equals_int (g_hash_table_size (client->
1034 selected_stream->video_alternates), 0);
1035 assert_equals_int (g_hash_table_size (client->
1036 selected_stream->subtt_alternates), 3);
1037
1038 alternates =
1039 g_hash_table_lookup (client->main->subtt_rendition_groups, "subs");
1040 assert_equals_int (alternates != NULL, TRUE);
1041 media = GST_M3U8_MEDIA (g_list_nth_data (alternates, 0));
1042 assert_equals_int (media->media_type, GST_M3U8_MEDIA_TYPE_SUBTITLES);
1043 assert_equals_string (media->group_id, "subs");
1044 assert_equals_string (media->name, "English");
1045 assert_equals_string (media->language, "en");
1046 assert_equals_string (media->uri, "http://localhost/main/subs-en.m3u8");
1047 assert_equals_string (media->uri, GST_M3U8 (media->playlist)->uri);
1048 assert_equals_int (media->is_default, TRUE);
1049 assert_equals_int (media->autoselect, FALSE);
1050
1051 /* Check the list of subtitles */
1052 alternates = gst_m3u8_client_get_alternates (client,
1053 GST_M3U8_MEDIA_TYPE_SUBTITLES);
1054 assert_equals_int (g_list_length (alternates), 3);
1055 assert_equals_string (g_list_nth_data (alternates, 0), "Deutsche");
1056 assert_equals_string (g_list_nth_data (alternates, 1), "Spanish");
1057 assert_equals_string (g_list_nth_data (alternates, 2), "English");
1058
1059 gst_hls_master_playlist_unref (master);
1060 }
1061
1062 GST_END_TEST;
1063 GST_START_TEST (test_select_subs_alternate)
1064 {
1065 GstM3U8Client *client;
1066 const gchar *a_uri, *v_uri, *s_uri;
1067 gboolean ret;
1068
1069 /* Check with a playlist with alternative audio renditions where the video
1070 * stream is video-only and therefor we always have 2 playlists, one for
1071 * video and another one for audio */
1072 master = load_playlist (SUBTITLES_PLAYLIST);
1073 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1074 assert_equals_int (a_uri == NULL, TRUE);
1075 assert_equals_int (s_uri != NULL, TRUE);
1076 assert_equals_string (s_uri, "http://localhost/main/subs-de.m3u8");
1077 assert_equals_int (v_uri != NULL, TRUE);
1078 assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1079
1080 ret =
1081 gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_SUBTITLES,
1082 "English");
1083 assert_equals_int (ret, TRUE);
1084 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1085 assert_equals_int (a_uri == NULL, TRUE);
1086 assert_equals_int (v_uri != NULL, TRUE);
1087 assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1088 assert_equals_int (s_uri != NULL, TRUE);
1089 assert_equals_string (s_uri, "http://localhost/main/subs-en.m3u8");
1090
1091 ret =
1092 gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_SUBTITLES,
1093 "Spanish");
1094 assert_equals_int (ret, TRUE);
1095 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1096 assert_equals_int (a_uri == NULL, TRUE);
1097 assert_equals_int (v_uri != NULL, TRUE);
1098 assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1099 assert_equals_int (s_uri != NULL, TRUE);
1100 assert_equals_string (s_uri, "http://localhost/main/subs-es.m3u8");
1101
1102 ret =
1103 gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_SUBTITLES,
1104 NULL);
1105 assert_equals_int (ret, TRUE);
1106 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1107 assert_equals_int (a_uri == NULL, TRUE);
1108 assert_equals_int (v_uri != NULL, TRUE);
1109 assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1110 assert_equals_int (s_uri == NULL, TRUE);
1111
1112 gst_hls_master_playlist_unref (master);
1113 }
1114
1115 GST_END_TEST;
1116 GST_START_TEST (test_select_alternate)
1117 {
1118 GstM3U8Client *client;
1119 const gchar *a_uri, *v_uri, *s_uri;
1120 gboolean ret;
1121
1122 /* Check with a playlist with alternative audio renditions where the video
1123 * stream is video-only and therefor we always have 2 playlists, one for
1124 * video and another one for audio */
1125 master = load_playlist (ALTERNATE_AUDIO_PLAYLIST);
1126 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1127 assert_equals_int (a_uri != NULL, TRUE);
1128 assert_equals_string (a_uri, "http://localhost/main/english-audio.m3u8");
1129 assert_equals_int (v_uri != NULL, TRUE);
1130 assert_equals_string (v_uri, "http://localhost/low/video-only.m3u8");
1131 assert_equals_int (s_uri == NULL, TRUE);
1132
1133 ret =
1134 gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_AUDIO,
1135 "Deutsche");
1136 assert_equals_int (ret, TRUE);
1137 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1138 assert_equals_int (a_uri != NULL, TRUE);
1139 assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1140 assert_equals_int (v_uri != NULL, TRUE);
1141 assert_equals_string (v_uri, "http://localhost/low/video-only.m3u8");
1142 assert_equals_int (s_uri == NULL, TRUE);
1143
1144 /* Check that selecting the audio-only fallback stream we only have the audio
1145 * uri */
1146 gst_m3u8_client_set_current (client,
1147 GST_M3U8_STREAM (client->main->streams->data));
1148 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1149 assert_equals_int (a_uri != NULL, TRUE);
1150 assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1151 assert_equals_int (v_uri == NULL, TRUE);
1152 assert_equals_int (s_uri == NULL, TRUE);
1153
1154 gst_hls_master_playlist_unref (master);
1155
1156 /* Now check with a playlist with alternative audio renditions where the
1157 * video * stream has the default audio rendition muxed and therefore we
1158 * only have 2 playlists when the audio alternative rendition is not the
1159 * default one */
1160 master = load_playlist (ALT_AUDIO_PLAYLIST_WITH_VIDEO_AUDIO);
1161 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1162 assert_equals_int (a_uri == NULL, TRUE);
1163 assert_equals_int (v_uri != NULL, TRUE);
1164 assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1165 assert_equals_int (s_uri == NULL, TRUE);
1166
1167 /* Check that selecting the audio-only fallback stream we only have the audio
1168 * uri */
1169 gst_m3u8_client_set_current (client,
1170 GST_M3U8_STREAM (client->main->streams->data));
1171 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1172 assert_equals_int (a_uri != NULL, TRUE);
1173 assert_equals_string (a_uri, "http://localhost/main/english-audio.m3u8");
1174 assert_equals_int (v_uri == NULL, TRUE);
1175 assert_equals_int (s_uri == NULL, TRUE);
1176
1177 /* Get back to the audio-video stream */
1178 gst_m3u8_client_set_current (client,
1179 GST_M3U8_STREAM (client->main->streams->next->data));
1180 /* Now set a different audio and check that we have 2 playlists */
1181 ret =
1182 gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_AUDIO,
1183 "Deutsche");
1184 assert_equals_int (ret, TRUE);
1185 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1186 assert_equals_int (a_uri != NULL, TRUE);
1187 assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1188 assert_equals_int (v_uri != NULL, TRUE);
1189 assert_equals_string (v_uri, "http://localhost/low/video-audio.m3u8");
1190 assert_equals_int (s_uri == NULL, TRUE);
1191
1192 gst_hls_master_playlist_unref (master);
1193 }
1194
1195 GST_END_TEST;
1196
1197 GST_START_TEST (test_simulation)
1198 {
1199 GstM3U8Client *client;
1200 const gchar *a_uri, *v_uri, *s_uri;
1201 GstFragment *a_frag, *v_frag, *s_frag;
1202 gboolean ret;
1203
1204 master = load_playlist (ALTERNATE_AUDIO_PLAYLIST);
1205 /* The default selection should be audio-only, which only has audio and not
1206 * video */
1207 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1208 assert_equals_int (a_uri != NULL, TRUE);
1209 assert_equals_string (a_uri, "http://localhost/main/english-audio.m3u8");
1210 assert_equals_int (v_uri != NULL, TRUE);
1211 assert_equals_string (v_uri, "http://localhost/low/video-only.m3u8");
1212 assert_equals_int (s_uri == NULL, TRUE);
1213
1214 /* Update the playlists */
1215 ret = gst_m3u8_update (client,
1216 g_strdup (ON_DEMAND_LOW_VIDEO_ONLY_PLAYLIST),
1217 g_strdup (ON_DEMAND_ENGLISH_PLAYLIST), NULL);
1218 assert_equals_int (ret, TRUE);
1219 assert_equals_int (g_list_length (client->selected_stream->selected_video->
1220 files), 4);
1221 assert_equals_int (g_list_length (client->selected_stream->selected_audio->
1222 files), 4);
1223
1224 /* Get the first fragment */
1225 gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1226 assert_equals_int (v_frag != NULL, TRUE);
1227 assert_equals_int (a_frag != NULL, TRUE);
1228 assert_equals_string (v_frag->name,
1229 "http://media.example.com/low/video-only-001.ts");
1230 assert_equals_string (a_frag->name,
1231 "http://media.example.com/audio/english-001.ts");
1232 g_object_unref (v_frag);
1233 g_object_unref (a_frag);
1234
1235 /* Get the next fragment */
1236 gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1237 assert_equals_int (v_frag != NULL, TRUE);
1238 assert_equals_int (a_frag != NULL, TRUE);
1239 assert_equals_string (v_frag->name,
1240 "http://media.example.com/low/video-only-002.ts");
1241 assert_equals_string (a_frag->name,
1242 "http://media.example.com/audio/english-002.ts");
1243 g_object_unref (v_frag);
1244 g_object_unref (a_frag);
1245
1246 /* Switch to German audio */
1247 ret =
1248 gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_AUDIO,
1249 "Deutsche");
1250 assert_equals_int (ret, TRUE);
1251 /* Get the new uri's */
1252 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1253 assert_equals_int (a_uri != NULL, TRUE);
1254 assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1255 /* On demand so the uri does not need to be downloaded again */
1256 assert_equals_int (v_uri == NULL, TRUE);
1257 assert_equals_int (s_uri == NULL, TRUE);
1258 /* Update the new uri's */
1259 ret =
1260 gst_m3u8_update (client,
1261 g_strdup (ON_DEMAND_LOW_VIDEO_ONLY_PLAYLIST),
1262 g_strdup (ON_DEMAND_GERMAN_PLAYLIST), NULL);
1263 assert_equals_int (ret, TRUE);
1264 gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1265 assert_equals_int (s_frag == NULL, TRUE);
1266 assert_equals_int (v_frag != NULL, TRUE);
1267 assert_equals_int (a_frag != NULL, TRUE);
1268 assert_equals_string (a_frag->name,
1269 "http://media.example.com/audio/german-003.ts");
1270 assert_equals_string (v_frag->name,
1271 "http://media.example.com/low/video-only-003.ts");
1272 g_object_unref (v_frag);
1273 g_object_unref (a_frag);
1274
1275 /* Switch to a higher bitrate */
1276 gst_m3u8_client_set_current (client,
1277 gst_m3u8_client_get_stream_for_bitrate (client, 260000));
1278 gst_m3u8_client_get_current_uri (client, &v_uri, &a_uri, &s_uri);
1279 assert_equals_int (a_uri != NULL, TRUE);
1280 assert_equals_string (a_uri, "http://localhost/main/german-audio.m3u8");
1281 assert_equals_int (v_uri != NULL, TRUE);
1282 assert_equals_string (v_uri, "http://localhost/mid/video-only.m3u8");
1283 assert_equals_int (s_uri == NULL, TRUE);
1284 ret =
1285 gst_m3u8_update (client,
1286 g_strdup (ON_DEMAND_MID_VIDEO_ONLY_PLAYLIST),
1287 g_strdup (ON_DEMAND_GERMAN_PLAYLIST), NULL);
1288 assert_equals_int (ret, TRUE);
1289 gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1290 assert_equals_int (s_frag == NULL, TRUE);
1291 assert_equals_int (a_frag != NULL, TRUE);
1292 assert_equals_int (v_frag != NULL, TRUE);
1293 assert_equals_string (a_frag->name,
1294 "http://media.example.com/audio/german-004.ts");
1295 assert_equals_string (v_frag->name,
1296 "http://media.example.com/mid/video-only-004.ts");
1297 g_object_unref (v_frag);
1298 g_object_unref (a_frag);
1299
1300 /* Seek to the beginning */
1301 gst_m3u8_client_seek (client, 0);
1302 gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1303 assert_equals_int (s_frag == NULL, TRUE);
1304 assert_equals_int (a_frag != NULL, TRUE);
1305 assert_equals_int (v_frag != NULL, TRUE);
1306 assert_equals_string (a_frag->name,
1307 "http://media.example.com/audio/german-001.ts");
1308 assert_equals_string (v_frag->name,
1309 "http://media.example.com/mid/video-only-001.ts");
1310 g_object_unref (v_frag);
1311 g_object_unref (a_frag);
1312
1313 /* Select English audio again */
1314 ret =
1315 gst_m3u8_client_set_alternate (client, GST_M3U8_MEDIA_TYPE_AUDIO,
1316 "English");
1317 assert_equals_int (ret, TRUE);
1318 gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1319 assert_equals_int (s_frag == NULL, TRUE);
1320 assert_equals_int (a_frag != NULL, TRUE);
1321 assert_equals_int (v_frag != NULL, TRUE);
1322 assert_equals_string (a_frag->name,
1323 "http://media.example.com/audio/english-002.ts");
1324 assert_equals_string (v_frag->name,
1325 "http://media.example.com/mid/video-only-002.ts");
1326 g_object_unref (v_frag);
1327 g_object_unref (a_frag);
1328
1329 /* Go to the audio-only fallback */
1330 gst_m3u8_client_set_current (client,
1331 gst_m3u8_client_get_stream_for_bitrate (client, 20000));
1332 gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1333 assert_equals_int (s_frag == NULL, TRUE);
1334 assert_equals_int (a_frag != NULL, TRUE);
1335 assert_equals_int (v_frag == NULL, TRUE);
1336 assert_equals_string (a_frag->name,
1337 "http://media.example.com/audio/english-003.ts");
1338 g_object_unref (a_frag);
1339
1340 /* Go to mid again */
1341 gst_m3u8_client_set_current (client,
1342 gst_m3u8_client_get_stream_for_bitrate (client, 260000));
1343 gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1344 assert_equals_int (s_frag == NULL, TRUE);
1345 assert_equals_int (a_frag != NULL, TRUE);
1346 assert_equals_int (v_frag != NULL, TRUE);
1347 assert_equals_string (a_frag->name,
1348 "http://media.example.com/audio/english-004.ts");
1349 assert_equals_string (v_frag->name,
1350 "http://media.example.com/mid/video-only-004.ts");
1351 g_object_unref (a_frag);
1352 g_object_unref (v_frag);
1353
1354 /* End of stream */
1355 ret = gst_m3u8_client_get_next_fragment (client, &v_frag, &a_frag, &s_frag);
1356 assert_equals_int (ret, FALSE);
1357
1358 gst_hls_master_playlist_unref (master);
1359 }
1360
1361 GST_END_TEST;
1362 #endif
1363
GST_START_TEST(test_url_with_slash_query_param)1364 GST_START_TEST (test_url_with_slash_query_param)
1365 {
1366 static const gchar *MASTER_PLAYLIST = "#EXTM3U \n"
1367 "#EXT-X-VERSION:4\n"
1368 "#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=1251135, CODECS=\"avc1.42001f, mp4a.40.2\", RESOLUTION=640x352\n"
1369 "1251/media.m3u8?acl=/*1054559_h264_1500k.mp4\n";
1370 GstHLSMasterPlaylist *master;
1371 GstHLSVariantStream *stream;
1372 GstM3U8 *media;
1373
1374 master = load_playlist (MASTER_PLAYLIST);
1375
1376 assert_equals_int (g_list_length (master->variants), 1);
1377 stream = g_list_nth_data (master->variants, 0);
1378 media = stream->m3u8;
1379
1380 assert_equals_string (media->uri,
1381 "http://localhost/1251/media.m3u8?acl=/*1054559_h264_1500k.mp4");
1382 gst_hls_master_playlist_unref (master);
1383 }
1384
1385 GST_END_TEST;
1386
GST_START_TEST(test_stream_inf_tag)1387 GST_START_TEST (test_stream_inf_tag)
1388 {
1389 static const gchar *MASTER_PLAYLIST = "#EXTM3U \n"
1390 "#EXT-X-VERSION:4\n"
1391 "#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=1251135, CODECS=\"avc1.42001f, mp4a.40.2\", RESOLUTION=640x352\n"
1392 "media.m3u8\n";
1393 GstHLSMasterPlaylist *master;
1394 GstHLSVariantStream *stream;
1395
1396 master = load_playlist (MASTER_PLAYLIST);
1397
1398 assert_equals_int (g_list_length (master->variants), 1);
1399 stream = g_list_nth_data (master->variants, 0);
1400
1401 assert_equals_int64 (stream->program_id, 1);
1402 assert_equals_int64 (stream->width, 640);
1403 assert_equals_int64 (stream->height, 352);
1404 assert_equals_int64 (stream->bandwidth, 1251135);
1405 assert_equals_string (stream->codecs, "avc1.42001f, mp4a.40.2");
1406 gst_hls_master_playlist_unref (master);
1407 }
1408
1409 GST_END_TEST;
1410
GST_START_TEST(test_map_tag)1411 GST_START_TEST (test_map_tag)
1412 {
1413 GstHLSMasterPlaylist *master;
1414 GstHLSVariantStream *stream;
1415 GstM3U8 *m3u8;
1416 GList *files, *walk;
1417 GstM3U8MediaFile *seg1, *seg2, *seg3;
1418 GstM3U8InitFile *init1, *init2;
1419
1420 /* Test EXT-X-MAP tag
1421 * This M3U8 has two EXT-X-MAP tag.
1422 * the first one is applied to the 1st and 2nd segments, and the other is
1423 * applied only to the 3rd segment
1424 */
1425
1426 master = load_playlist (MAP_TAG_PLAYLIST);
1427
1428 assert_equals_int (master->is_simple, TRUE);
1429 assert_equals_int (g_list_length (master->variants), 1);
1430 stream = g_list_nth_data (master->variants, 0);
1431
1432 m3u8 = stream->m3u8;
1433 fail_unless (m3u8 != NULL);
1434
1435 files = m3u8->files;
1436 fail_unless (m3u8 != NULL);
1437 assert_equals_int (g_list_length (files), 3);
1438 for (walk = files; walk; walk = g_list_next (walk)) {
1439 GstM3U8MediaFile *file = (GstM3U8MediaFile *) walk->data;
1440
1441 GstM3U8InitFile *init_file = file->init_file;
1442 fail_unless (init_file != NULL);
1443 fail_unless (init_file->uri != NULL);
1444 }
1445
1446 seg1 = g_list_nth_data (files, 0);
1447 seg2 = g_list_nth_data (files, 1);
1448 seg3 = g_list_nth_data (files, 2);
1449
1450 /* Segment 1 and 2 share the identical init segment */
1451 fail_unless (seg1->init_file == seg2->init_file);
1452 assert_equals_int (seg1->init_file->ref_count, 2);
1453
1454 fail_unless (seg2->init_file != seg3->init_file);
1455 assert_equals_int (seg3->init_file->ref_count, 1);
1456
1457 init1 = seg1->init_file;
1458 init2 = seg3->init_file;
1459
1460 fail_unless (g_strcmp0 (init1->uri, init2->uri));
1461 assert_equals_int (init1->offset, 50);
1462 assert_equals_int (init1->size, 50);
1463
1464 assert_equals_int (init2->offset, 0);
1465 assert_equals_int (init2->size, -1);
1466
1467 gst_hls_master_playlist_unref (master);
1468 }
1469
1470 GST_END_TEST;
1471
1472 static Suite *
hlsdemux_suite(void)1473 hlsdemux_suite (void)
1474 {
1475 Suite *s = suite_create ("hlsdemux_m3u8");
1476 TCase *tc_m3u8 = tcase_create ("m3u8client");
1477
1478 GST_DEBUG_CATEGORY_INIT (hls_debug, "hlsdemux_m3u", 0, "hlsdemux m3u test");
1479
1480 suite_add_tcase (s, tc_m3u8);
1481 tcase_add_test (tc_m3u8, test_load_main_playlist_invalid);
1482 tcase_add_test (tc_m3u8, test_load_main_playlist_rendition);
1483 tcase_add_test (tc_m3u8, test_load_main_playlist_variant);
1484 tcase_add_test (tc_m3u8, test_load_main_playlist_variant_with_missing_uri);
1485 tcase_add_test (tc_m3u8, test_load_windows_line_endings_variant_playlist);
1486 tcase_add_test (tc_m3u8, test_load_main_playlist_with_empty_lines);
1487 tcase_add_test (tc_m3u8, test_load_windows_main_playlist_with_empty_lines);
1488 tcase_add_test (tc_m3u8, test_on_demand_playlist);
1489 tcase_add_test (tc_m3u8, test_windows_line_endings_playlist);
1490 tcase_add_test (tc_m3u8, test_windows_empty_lines_playlist);
1491 tcase_add_test (tc_m3u8, test_empty_lines_playlist);
1492 tcase_add_test (tc_m3u8, test_live_playlist);
1493 tcase_add_test (tc_m3u8, test_live_playlist_rotated);
1494 tcase_add_test (tc_m3u8, test_playlist_with_doubles_duration);
1495 tcase_add_test (tc_m3u8, test_playlist_with_encryption);
1496 tcase_add_test (tc_m3u8, test_update_invalid_playlist);
1497 tcase_add_test (tc_m3u8, test_update_playlist);
1498 tcase_add_test (tc_m3u8, test_playlist_media_files);
1499 tcase_add_test (tc_m3u8, test_playlist_byte_range_media_files);
1500 tcase_add_test (tc_m3u8, test_get_next_fragment);
1501 tcase_add_test (tc_m3u8, test_get_duration);
1502 tcase_add_test (tc_m3u8, test_get_target_duration);
1503 tcase_add_test (tc_m3u8, test_get_stream_for_bitrate);
1504 #if 0
1505 tcase_add_test (tc_m3u8, test_seek);
1506 tcase_add_test (tc_m3u8, test_alternate_audio_playlist);
1507 tcase_add_test (tc_m3u8, test_subtitles_playlist);
1508 tcase_add_test (tc_m3u8, test_select_alternate);
1509 tcase_add_test (tc_m3u8, test_select_subs_alternate);
1510 tcase_add_test (tc_m3u8, test_simulation);
1511 #endif
1512 tcase_add_test (tc_m3u8, test_url_with_slash_query_param);
1513 tcase_add_test (tc_m3u8, test_stream_inf_tag);
1514 tcase_add_test (tc_m3u8, test_map_tag);
1515 return s;
1516 }
1517
1518 GST_CHECK_MAIN (hlsdemux);
1519