1 /* GStreamer
2 * Copyright (C) 2010 Marc-Andre Lureau <marcandre.lureau@gmail.com>
3 * Copyright (C) 2010 Andoni Morales Alastruey <ylatuya@gmail.com>
4 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
5 * Author: Youness Alaoui <youness.alaoui@collabora.co.uk>, Collabora Ltd.
6 * Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
7 * Copyright (C) 2014 Sebastian Dröge <sebastian@centricular.com>
8 * Copyright (C) 2015 Tim-Philipp Müller <tim@centricular.com>
9 *
10 * Gsthlsdemux.c:
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation; either
15 * version 2 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
21 *
22 * You should have received a copy of the GNU Library General Public
23 * License along with this library; if not, write to the
24 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 * Boston, MA 02110-1301, USA.
26 */
27 /**
28 * SECTION:element-hlsdemux
29 * @title: hlsdemux
30 *
31 * HTTP Live Streaming demuxer element.
32 *
33 * ## Example launch line
34 * |[
35 * gst-launch-1.0 souphttpsrc location=http://devimages.apple.com/iphone/samples/bipbop/gear4/prog_index.m3u8 ! hlsdemux ! decodebin ! videoconvert ! videoscale ! autovideosink
36 * ]|
37 *
38 */
39
40 #ifdef HAVE_CONFIG_H
41 # include "config.h"
42 #endif
43
44 #include <string.h>
45 #include <gst/base/gsttypefindhelper.h>
46 #include "gsthlselements.h"
47 #include "gsthlsdemux.h"
48
49 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src_%u",
50 GST_PAD_SRC,
51 GST_PAD_SOMETIMES,
52 GST_STATIC_CAPS_ANY);
53
54 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
55 GST_PAD_SINK,
56 GST_PAD_ALWAYS,
57 GST_STATIC_CAPS ("application/x-hls"));
58
59 GST_DEBUG_CATEGORY (gst_hls_demux_debug);
60 #define GST_CAT_DEFAULT gst_hls_demux_debug
61
62 #define GST_M3U8_CLIENT_LOCK(l) /* FIXME */
63 #define GST_M3U8_CLIENT_UNLOCK(l) /* FIXME */
64
65 #ifdef OHOS_EXT_FUNC
66 // ohos.ext.func.0028
67 #define MAX_BITRATE_NUM 100
68 #endif
69
70 /* GObject */
71 static void gst_hls_demux_finalize (GObject * obj);
72
73 /* GstElement */
74 static GstStateChangeReturn
75 gst_hls_demux_change_state (GstElement * element, GstStateChange transition);
76
77 /* GstHLSDemux */
78 static gboolean gst_hls_demux_update_playlist (GstHLSDemux * demux,
79 gboolean update, GError ** err);
80 static gchar *gst_hls_src_buf_to_utf8_playlist (GstBuffer * buf);
81
82 /* FIXME: the return value is never used? */
83 static gboolean gst_hls_demux_change_playlist (GstHLSDemux * demux,
84 guint max_bitrate, gboolean * changed);
85 static GstBuffer *gst_hls_demux_decrypt_fragment (GstHLSDemux * demux,
86 GstHLSDemuxStream * stream, GstBuffer * encrypted_buffer, GError ** err);
87 static gboolean
88 gst_hls_demux_stream_decrypt_start (GstHLSDemuxStream * stream,
89 const guint8 * key_data, const guint8 * iv_data);
90 static void gst_hls_demux_stream_decrypt_end (GstHLSDemuxStream * stream);
91
92 static gboolean gst_hls_demux_is_live (GstAdaptiveDemux * demux);
93 static GstClockTime gst_hls_demux_get_duration (GstAdaptiveDemux * demux);
94 static gint64 gst_hls_demux_get_manifest_update_interval (GstAdaptiveDemux *
95 demux);
96 static gboolean gst_hls_demux_process_manifest (GstAdaptiveDemux * demux,
97 GstBuffer * buf);
98 static GstFlowReturn gst_hls_demux_update_manifest (GstAdaptiveDemux * demux);
99 static gboolean gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek);
100 static GstFlowReturn gst_hls_demux_stream_seek (GstAdaptiveDemuxStream *
101 stream, gboolean forward, GstSeekFlags flags, GstClockTime ts,
102 GstClockTime * final_ts);
103 static gboolean
104 gst_hls_demux_start_fragment (GstAdaptiveDemux * demux,
105 GstAdaptiveDemuxStream * stream);
106 static GstFlowReturn gst_hls_demux_finish_fragment (GstAdaptiveDemux * demux,
107 GstAdaptiveDemuxStream * stream);
108 static GstFlowReturn gst_hls_demux_data_received (GstAdaptiveDemux * demux,
109 GstAdaptiveDemuxStream * stream, GstBuffer * buffer);
110 static void gst_hls_demux_stream_free (GstAdaptiveDemuxStream * stream);
111 static gboolean gst_hls_demux_stream_has_next_fragment (GstAdaptiveDemuxStream *
112 stream);
113 static GstFlowReturn gst_hls_demux_advance_fragment (GstAdaptiveDemuxStream *
114 stream);
115 static GstFlowReturn gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream
116 * stream);
117 static gboolean gst_hls_demux_select_bitrate (GstAdaptiveDemuxStream * stream,
118 guint64 bitrate);
119 static void gst_hls_demux_reset (GstAdaptiveDemux * demux);
120 static gboolean gst_hls_demux_get_live_seek_range (GstAdaptiveDemux * demux,
121 gint64 * start, gint64 * stop);
122 static GstM3U8 *gst_hls_demux_stream_get_m3u8 (GstHLSDemuxStream * hls_stream);
123 static void gst_hls_demux_set_current_variant (GstHLSDemux * hlsdemux,
124 GstHLSVariantStream * variant);
125
126 #ifdef OHOS_EXT_FUNC
127 // ohos.ext.func.0028
128 static gboolean gst_hls_demux_get_bitrate_info(GstAdaptiveDemux * demux,
129 GstAdaptiveDemuxBitrateInfo * bitrate_info);
130 #endif
131
132 #define gst_hls_demux_parent_class parent_class
133 G_DEFINE_TYPE (GstHLSDemux, gst_hls_demux, GST_TYPE_ADAPTIVE_DEMUX);
134 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (hlsdemux, "hlsdemux", GST_RANK_PRIMARY,
135 GST_TYPE_HLS_DEMUX, hls_element_init (plugin));
136
137 static void
gst_hls_demux_finalize(GObject * obj)138 gst_hls_demux_finalize (GObject * obj)
139 {
140 GstHLSDemux *demux = GST_HLS_DEMUX (obj);
141
142 gst_hls_demux_reset (GST_ADAPTIVE_DEMUX_CAST (demux));
143 g_mutex_clear (&demux->keys_lock);
144 if (demux->keys) {
145 g_hash_table_unref (demux->keys);
146 demux->keys = NULL;
147 }
148
149 G_OBJECT_CLASS (parent_class)->finalize (obj);
150 }
151
152 static void
gst_hls_demux_class_init(GstHLSDemuxClass * klass)153 gst_hls_demux_class_init (GstHLSDemuxClass * klass)
154 {
155 GObjectClass *gobject_class;
156 GstElementClass *element_class;
157 GstAdaptiveDemuxClass *adaptivedemux_class;
158
159 gobject_class = (GObjectClass *) klass;
160 element_class = (GstElementClass *) klass;
161 adaptivedemux_class = (GstAdaptiveDemuxClass *) klass;
162
163 gobject_class->finalize = gst_hls_demux_finalize;
164
165 element_class->change_state = GST_DEBUG_FUNCPTR (gst_hls_demux_change_state);
166
167 gst_element_class_add_static_pad_template (element_class, &srctemplate);
168 gst_element_class_add_static_pad_template (element_class, &sinktemplate);
169
170 gst_element_class_set_static_metadata (element_class,
171 "HLS Demuxer",
172 "Codec/Demuxer/Adaptive",
173 "HTTP Live Streaming demuxer",
174 "Marc-Andre Lureau <marcandre.lureau@gmail.com>\n"
175 "Andoni Morales Alastruey <ylatuya@gmail.com>");
176
177 adaptivedemux_class->is_live = gst_hls_demux_is_live;
178 adaptivedemux_class->get_live_seek_range = gst_hls_demux_get_live_seek_range;
179 adaptivedemux_class->get_duration = gst_hls_demux_get_duration;
180 adaptivedemux_class->get_manifest_update_interval =
181 gst_hls_demux_get_manifest_update_interval;
182 adaptivedemux_class->process_manifest = gst_hls_demux_process_manifest;
183 adaptivedemux_class->update_manifest = gst_hls_demux_update_manifest;
184 adaptivedemux_class->reset = gst_hls_demux_reset;
185 adaptivedemux_class->seek = gst_hls_demux_seek;
186 adaptivedemux_class->stream_seek = gst_hls_demux_stream_seek;
187 adaptivedemux_class->stream_has_next_fragment =
188 gst_hls_demux_stream_has_next_fragment;
189 adaptivedemux_class->stream_advance_fragment = gst_hls_demux_advance_fragment;
190 adaptivedemux_class->stream_update_fragment_info =
191 gst_hls_demux_update_fragment_info;
192 adaptivedemux_class->stream_select_bitrate = gst_hls_demux_select_bitrate;
193 adaptivedemux_class->stream_free = gst_hls_demux_stream_free;
194
195 adaptivedemux_class->start_fragment = gst_hls_demux_start_fragment;
196 adaptivedemux_class->finish_fragment = gst_hls_demux_finish_fragment;
197 adaptivedemux_class->data_received = gst_hls_demux_data_received;
198
199 #ifdef OHOS_EXT_FUNC
200 // ohos.ext.func.0028
201 adaptivedemux_class->get_bitrate_info = gst_hls_demux_get_bitrate_info;
202 #endif
203
204 GST_DEBUG_CATEGORY_INIT (gst_hls_demux_debug, "hlsdemux", 0,
205 "hlsdemux element");
206 }
207
208 static void
gst_hls_demux_init(GstHLSDemux * demux)209 gst_hls_demux_init (GstHLSDemux * demux)
210 {
211 gst_adaptive_demux_set_stream_struct_size (GST_ADAPTIVE_DEMUX_CAST (demux),
212 sizeof (GstHLSDemuxStream));
213
214 demux->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
215 g_mutex_init (&demux->keys_lock);
216 }
217
218 static GstStateChangeReturn
gst_hls_demux_change_state(GstElement * element,GstStateChange transition)219 gst_hls_demux_change_state (GstElement * element, GstStateChange transition)
220 {
221 GstStateChangeReturn ret;
222 GstHLSDemux *demux = GST_HLS_DEMUX (element);
223
224 switch (transition) {
225 case GST_STATE_CHANGE_READY_TO_PAUSED:
226 gst_hls_demux_reset (GST_ADAPTIVE_DEMUX_CAST (demux));
227 break;
228 default:
229 break;
230 }
231
232 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
233
234 switch (transition) {
235 case GST_STATE_CHANGE_PAUSED_TO_READY:
236 gst_hls_demux_reset (GST_ADAPTIVE_DEMUX_CAST (demux));
237 g_hash_table_remove_all (demux->keys);
238 break;
239 default:
240 break;
241 }
242 return ret;
243 }
244
245 static GstPad *
gst_hls_demux_create_pad(GstHLSDemux * hlsdemux)246 gst_hls_demux_create_pad (GstHLSDemux * hlsdemux)
247 {
248 gchar *name;
249 GstPad *pad;
250
251 name = g_strdup_printf ("src_%u", hlsdemux->srcpad_counter++);
252 pad = gst_pad_new_from_static_template (&srctemplate, name);
253 g_free (name);
254
255 return pad;
256 }
257
258 static guint64
gst_hls_demux_get_bitrate(GstHLSDemux * hlsdemux)259 gst_hls_demux_get_bitrate (GstHLSDemux * hlsdemux)
260 {
261 GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (hlsdemux);
262
263 /* FIXME !!!
264 *
265 * No, there isn't a single output :D */
266
267 /* Valid because hlsdemux only has a single output */
268 if (demux->streams) {
269 GstAdaptiveDemuxStream *stream = demux->streams->data;
270 return stream->current_download_rate;
271 }
272
273 return 0;
274 }
275
276 static void
gst_hls_demux_stream_clear_pending_data(GstHLSDemuxStream * hls_stream)277 gst_hls_demux_stream_clear_pending_data (GstHLSDemuxStream * hls_stream)
278 {
279 if (hls_stream->pending_encrypted_data)
280 gst_adapter_clear (hls_stream->pending_encrypted_data);
281 gst_buffer_replace (&hls_stream->pending_decrypted_buffer, NULL);
282 gst_buffer_replace (&hls_stream->pending_typefind_buffer, NULL);
283 gst_buffer_replace (&hls_stream->pending_pcr_buffer, NULL);
284 hls_stream->current_offset = -1;
285 gst_hls_demux_stream_decrypt_end (hls_stream);
286 }
287
288 static void
gst_hls_demux_clear_all_pending_data(GstHLSDemux * hlsdemux)289 gst_hls_demux_clear_all_pending_data (GstHLSDemux * hlsdemux)
290 {
291 GstAdaptiveDemux *demux = (GstAdaptiveDemux *) hlsdemux;
292 GList *walk;
293
294 for (walk = demux->streams; walk != NULL; walk = walk->next) {
295 GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (walk->data);
296 gst_hls_demux_stream_clear_pending_data (hls_stream);
297 }
298 }
299
300 #if 0
301 static void
302 gst_hls_demux_set_current (GstHLSDemux * self, GstM3U8 * m3u8)
303 {
304 GST_M3U8_CLIENT_LOCK (self);
305 if (m3u8 != self->current) {
306 self->current = m3u8;
307 self->current->duration = GST_CLOCK_TIME_NONE;
308 self->current->current_file = NULL;
309
310 #if 0
311 // FIXME: this makes no sense after we just set self->current=m3u8 above (tpm)
312 // also, these values don't necessarily align between different lists
313 m3u8->current_file_duration = self->current->current_file_duration;
314 m3u8->sequence = self->current->sequence;
315 m3u8->sequence_position = self->current->sequence_position;
316 m3u8->highest_sequence_number = self->current->highest_sequence_number;
317 m3u8->first_file_start = self->current->first_file_start;
318 m3u8->last_file_end = self->current->last_file_end;
319 #endif
320 }
321 GST_M3U8_CLIENT_UNLOCK (self);
322 }
323 #endif
324
325 #define SEEK_UPDATES_PLAY_POSITION(r, start_type, stop_type) \
326 ((r >= 0 && start_type != GST_SEEK_TYPE_NONE) || \
327 (r < 0 && stop_type != GST_SEEK_TYPE_NONE))
328
329 #define IS_SNAP_SEEK(f) (f & (GST_SEEK_FLAG_SNAP_BEFORE | \
330 GST_SEEK_FLAG_SNAP_AFTER | \
331 GST_SEEK_FLAG_SNAP_NEAREST | \
332 GST_SEEK_FLAG_TRICKMODE_KEY_UNITS | \
333 GST_SEEK_FLAG_KEY_UNIT))
334
335 static gboolean
gst_hls_demux_seek(GstAdaptiveDemux * demux,GstEvent * seek)336 gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
337 {
338 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
339 GstFormat format;
340 GstSeekFlags flags;
341 GstSeekType start_type, stop_type;
342 gint64 start, stop;
343 gdouble rate, old_rate;
344 GList *walk;
345 GstClockTime current_pos, target_pos, final_pos;
346 guint64 bitrate;
347
348 gst_event_parse_seek (seek, &rate, &format, &flags, &start_type, &start,
349 &stop_type, &stop);
350
351 if (!SEEK_UPDATES_PLAY_POSITION (rate, start_type, stop_type)) {
352 /* nothing to do if we don't have to update the current position */
353 return TRUE;
354 }
355
356 old_rate = demux->segment.rate;
357
358 bitrate = gst_hls_demux_get_bitrate (hlsdemux);
359
360 /* Use I-frame variants for trick modes */
361 if (hlsdemux->master->iframe_variants != NULL
362 && rate < -1.0 && old_rate >= -1.0 && old_rate <= 1.0) {
363 GError *err = NULL;
364
365 /* Switch to I-frame variant */
366 gst_hls_demux_set_current_variant (hlsdemux,
367 hlsdemux->master->iframe_variants->data);
368 gst_uri_downloader_reset (demux->downloader);
369 if (!gst_hls_demux_update_playlist (hlsdemux, FALSE, &err)) {
370 GST_ELEMENT_ERROR_FROM_ERROR (hlsdemux, "Could not switch playlist", err);
371 return FALSE;
372 }
373 //hlsdemux->discont = TRUE;
374
375 gst_hls_demux_change_playlist (hlsdemux, bitrate / ABS (rate), NULL);
376 } else if (rate > -1.0 && rate <= 1.0 && (old_rate < -1.0 || old_rate > 1.0)) {
377 GError *err = NULL;
378 /* Switch to normal variant */
379 gst_hls_demux_set_current_variant (hlsdemux,
380 hlsdemux->master->variants->data);
381 gst_uri_downloader_reset (demux->downloader);
382 if (!gst_hls_demux_update_playlist (hlsdemux, FALSE, &err)) {
383 GST_ELEMENT_ERROR_FROM_ERROR (hlsdemux, "Could not switch playlist", err);
384 return FALSE;
385 }
386 //hlsdemux->discont = TRUE;
387 /* TODO why not continue using the same? that was being used up to now? */
388 gst_hls_demux_change_playlist (hlsdemux, bitrate, NULL);
389 }
390
391 target_pos = rate < 0 ? stop : start;
392 final_pos = target_pos;
393
394 /* properly cleanup pending decryption status */
395 if (flags & GST_SEEK_FLAG_FLUSH) {
396 gst_hls_demux_clear_all_pending_data (hlsdemux);
397 }
398
399 for (walk = demux->streams; walk; walk = g_list_next (walk)) {
400 GstAdaptiveDemuxStream *stream =
401 GST_ADAPTIVE_DEMUX_STREAM_CAST (walk->data);
402
403 gst_hls_demux_stream_seek (stream, rate >= 0, flags, target_pos,
404 ¤t_pos);
405
406 /* FIXME: use minimum position always ? */
407 if (final_pos > current_pos)
408 final_pos = current_pos;
409 }
410
411 if (IS_SNAP_SEEK (flags)) {
412 if (rate >= 0)
413 gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
414 final_pos, stop_type, stop, NULL);
415 else
416 gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
417 start, stop_type, final_pos, NULL);
418 }
419
420 return TRUE;
421 }
422
423 static GstFlowReturn
gst_hls_demux_stream_seek(GstAdaptiveDemuxStream * stream,gboolean forward,GstSeekFlags flags,GstClockTime ts,GstClockTime * final_ts)424 gst_hls_demux_stream_seek (GstAdaptiveDemuxStream * stream, gboolean forward,
425 GstSeekFlags flags, GstClockTime ts, GstClockTime * final_ts)
426 {
427 GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
428 GList *walk;
429 GstClockTime current_pos;
430 gint64 current_sequence;
431 gboolean snap_after, snap_nearest;
432 GstM3U8MediaFile *file = NULL;
433
434 current_sequence = 0;
435 current_pos = gst_m3u8_is_live (hls_stream->playlist) ?
436 hls_stream->playlist->first_file_start : 0;
437
438 /* Snap to segment boundary. Improves seek performance on slow machines. */
439 snap_nearest =
440 (flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST;
441 snap_after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
442
443 GST_M3U8_CLIENT_LOCK (hlsdemux->client);
444 /* FIXME: Here we need proper discont handling */
445 for (walk = hls_stream->playlist->files; walk; walk = walk->next) {
446 file = walk->data;
447
448 current_sequence = file->sequence;
449 if ((forward && snap_after) || snap_nearest) {
450 if (current_pos >= ts)
451 break;
452 if (snap_nearest && ts - current_pos < file->duration / 2)
453 break;
454 } else if (!forward && snap_after) {
455 /* check if the next fragment is our target, in this case we want to
456 * start from the previous fragment */
457 GstClockTime next_pos = current_pos + file->duration;
458
459 if (next_pos <= ts && ts < next_pos + file->duration) {
460 break;
461 }
462 } else if (current_pos <= ts && ts < current_pos + file->duration) {
463 break;
464 }
465 current_pos += file->duration;
466 }
467
468 if (walk == NULL) {
469 GST_DEBUG_OBJECT (stream->pad, "seeking further than track duration");
470 current_sequence++;
471 }
472
473 GST_DEBUG_OBJECT (stream->pad, "seeking to sequence %u",
474 (guint) current_sequence);
475 hls_stream->reset_pts = TRUE;
476 hls_stream->playlist->sequence = current_sequence;
477 hls_stream->playlist->current_file = walk;
478 hls_stream->playlist->sequence_position = current_pos;
479 GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
480
481 /* Play from the end of the current selected segment */
482 if (file) {
483 if (!forward && IS_SNAP_SEEK (flags))
484 current_pos += file->duration;
485 }
486
487 /* update stream's segment position */
488 stream->segment.position = current_pos;
489
490 if (final_ts)
491 *final_ts = current_pos;
492
493 return GST_FLOW_OK;
494 }
495
496 static GstFlowReturn
gst_hls_demux_update_manifest(GstAdaptiveDemux * demux)497 gst_hls_demux_update_manifest (GstAdaptiveDemux * demux)
498 {
499 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
500 if (!gst_hls_demux_update_playlist (hlsdemux, TRUE, NULL))
501 return GST_FLOW_ERROR;
502
503 return GST_FLOW_OK;
504 }
505
506 static void
create_stream_for_playlist(GstAdaptiveDemux * demux,GstM3U8 * playlist,gboolean is_primary_playlist,gboolean selected)507 create_stream_for_playlist (GstAdaptiveDemux * demux, GstM3U8 * playlist,
508 gboolean is_primary_playlist, gboolean selected)
509 {
510 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
511 GstHLSDemuxStream *hlsdemux_stream;
512 GstAdaptiveDemuxStream *stream;
513
514 if (!selected) {
515 /* FIXME: Later, create the stream but mark not-selected */
516 GST_LOG_OBJECT (demux, "Ignoring not-selected stream");
517 return;
518 }
519
520 GST_DEBUG_OBJECT (demux,
521 "is_primary_playlist:%d selected:%d playlist name '%s'",
522 is_primary_playlist, selected, playlist->name);
523
524 stream = gst_adaptive_demux_stream_new (demux,
525 gst_hls_demux_create_pad (hlsdemux));
526
527 hlsdemux_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
528
529 hlsdemux_stream->stream_type = GST_HLS_TSREADER_NONE;
530
531 hlsdemux_stream->playlist = gst_m3u8_ref (playlist);
532 hlsdemux_stream->is_primary_playlist = is_primary_playlist;
533
534 hlsdemux_stream->do_typefind = TRUE;
535 hlsdemux_stream->reset_pts = TRUE;
536 }
537
538 static GstHLSDemuxStream *
find_adaptive_stream_for_playlist(GstAdaptiveDemux * demux,GstM3U8 * playlist)539 find_adaptive_stream_for_playlist (GstAdaptiveDemux * demux, GstM3U8 * playlist)
540 {
541 GList *tmp;
542
543 GST_DEBUG_OBJECT (demux, "Looking for existing stream for '%s' %s",
544 playlist->name, playlist->uri);
545
546 for (tmp = demux->streams; tmp; tmp = tmp->next) {
547 GstHLSDemuxStream *hlsstream = (GstHLSDemuxStream *) tmp->data;
548 if (hlsstream->playlist == playlist)
549 return hlsstream;
550 }
551
552 return NULL;
553 }
554
555 /* Returns TRUE if the previous and current (to switch to) variant are compatible.
556 *
557 * That is:
558 * * They have the same number of streams
559 * * The streams are of the same type
560 */
561 static gboolean
new_variant_is_compatible(GstAdaptiveDemux * demux)562 new_variant_is_compatible (GstAdaptiveDemux * demux)
563 {
564 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
565 GstHLSVariantStream *previous = hlsdemux->previous_variant;
566 GstHLSVariantStream *current = hlsdemux->current_variant;
567 gint i;
568
569 GST_DEBUG_OBJECT (demux,
570 "Checking whether new variant is compatible with previous");
571
572 for (i = 0; i < GST_HLS_N_MEDIA_TYPES; ++i) {
573 GList *mlist = current->media[i];
574 if (g_list_length (previous->media[i]) != g_list_length (current->media[i])) {
575 GST_LOG_OBJECT (demux, "Number of medias for type %s don't match",
576 gst_hls_media_type_get_name (i));
577 return FALSE;
578 }
579
580 /* Check if all new media were present in previous (if not there are new ones) */
581 while (mlist != NULL) {
582 GstHLSMedia *media = mlist->data;
583 if (!gst_hls_variant_find_matching_media (previous, media)) {
584 GST_LOG_OBJECT (demux,
585 "New stream of type %s present. Variant not compatible",
586 gst_hls_media_type_get_name (i));
587 return FALSE;
588 }
589 mlist = mlist->next;
590 }
591
592 /* Check if all old media are present in current (if not some have gone) */
593 mlist = previous->media[i];
594 while (mlist != NULL) {
595 GstHLSMedia *media = mlist->data;
596 if (!gst_hls_variant_find_matching_media (current, media)) {
597 GST_LOG_OBJECT (demux,
598 "Old stream of type %s gone. Variant not compatible",
599 gst_hls_media_type_get_name (i));
600 return FALSE;
601 }
602 mlist = mlist->next;
603 }
604 }
605
606 GST_DEBUG_OBJECT (demux, "Variants are compatible");
607
608 return TRUE;
609 }
610
611 static gboolean
gst_hls_demux_setup_streams(GstAdaptiveDemux * demux)612 gst_hls_demux_setup_streams (GstAdaptiveDemux * demux)
613 {
614 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
615 GstHLSVariantStream *playlist = hlsdemux->current_variant;
616 gint i;
617
618 if (playlist == NULL) {
619 GST_WARNING_OBJECT (demux, "Can't configure streams - no variant selected");
620 return FALSE;
621 }
622
623 GST_DEBUG_OBJECT (demux, "Setting up streams");
624 if (hlsdemux->streams_aware && hlsdemux->previous_variant &&
625 new_variant_is_compatible (demux)) {
626 GstHLSDemuxStream *hlsstream;
627 GST_DEBUG_OBJECT (demux, "Have a previous variant, Re-using streams");
628
629 /* Carry over the main playlist */
630 hlsstream =
631 find_adaptive_stream_for_playlist (demux,
632 hlsdemux->previous_variant->m3u8);
633 if (G_UNLIKELY (hlsstream == NULL))
634 goto no_match_error;
635
636 gst_m3u8_unref (hlsstream->playlist);
637 hlsstream->playlist = gst_m3u8_ref (playlist->m3u8);
638
639 for (i = 0; i < GST_HLS_N_MEDIA_TYPES; ++i) {
640 GList *mlist = playlist->media[i];
641 while (mlist != NULL) {
642 GstHLSMedia *media = mlist->data;
643 GstHLSMedia *old_media =
644 gst_hls_variant_find_matching_media (hlsdemux->previous_variant,
645 media);
646
647 if (G_UNLIKELY (old_media == NULL)) {
648 GST_FIXME_OBJECT (demux, "Handle new stream !");
649 goto no_match_error;
650 }
651 if (!g_strcmp0 (media->uri, old_media->uri))
652 GST_DEBUG_OBJECT (demux, "Identical stream !");
653 if (media->mtype == GST_HLS_MEDIA_TYPE_AUDIO ||
654 media->mtype == GST_HLS_MEDIA_TYPE_VIDEO) {
655 hlsstream =
656 find_adaptive_stream_for_playlist (demux, old_media->playlist);
657 if (!hlsstream)
658 goto no_match_error;
659
660 GST_DEBUG_OBJECT (demux, "Found matching stream");
661 gst_m3u8_unref (hlsstream->playlist);
662 hlsstream->playlist = gst_m3u8_ref (media->playlist);
663 } else {
664 GST_DEBUG_OBJECT (demux, "Skipping stream of type %s",
665 gst_hls_media_type_get_name (media->mtype));
666 }
667
668 mlist = mlist->next;
669 }
670 }
671
672 return TRUE;
673 }
674
675 /* FIXME : This seems wrong and assumes there's only one stream :( */
676 gst_hls_demux_clear_all_pending_data (hlsdemux);
677
678 /* 1 output for the main playlist */
679 create_stream_for_playlist (demux, playlist->m3u8, TRUE, TRUE);
680
681 for (i = 0; i < GST_HLS_N_MEDIA_TYPES; ++i) {
682 GList *mlist = playlist->media[i];
683 while (mlist != NULL) {
684 GstHLSMedia *media = mlist->data;
685
686 if (media->uri == NULL /* || media->mtype != GST_HLS_MEDIA_TYPE_AUDIO */ ) {
687 /* No uri means this is a placeholder for a stream
688 * contained in another mux */
689 GST_LOG_OBJECT (demux, "Skipping stream %s type %s with no URI",
690 media->name, gst_hls_media_type_get_name (media->mtype));
691 mlist = mlist->next;
692 continue;
693 }
694 GST_LOG_OBJECT (demux, "media of type %s - %s, uri: %s",
695 gst_hls_media_type_get_name (i), media->name, media->uri);
696 create_stream_for_playlist (demux, media->playlist, FALSE,
697 (media->mtype == GST_HLS_MEDIA_TYPE_VIDEO
698 || media->mtype == GST_HLS_MEDIA_TYPE_AUDIO));
699
700 mlist = mlist->next;
701 }
702 }
703
704 return TRUE;
705
706 no_match_error:
707 {
708 /* POST ERROR MESSAGE */
709 GST_ERROR_OBJECT (demux, "Should not happen ! Could not find old stream");
710 return FALSE;
711 }
712 }
713
714 static const gchar *
gst_adaptive_demux_get_manifest_ref_uri(GstAdaptiveDemux * d)715 gst_adaptive_demux_get_manifest_ref_uri (GstAdaptiveDemux * d)
716 {
717 return d->manifest_base_uri ? d->manifest_base_uri : d->manifest_uri;
718 }
719
720 static void
gst_hls_demux_set_current_variant(GstHLSDemux * hlsdemux,GstHLSVariantStream * variant)721 gst_hls_demux_set_current_variant (GstHLSDemux * hlsdemux,
722 GstHLSVariantStream * variant)
723 {
724 if (hlsdemux->current_variant == variant || variant == NULL)
725 return;
726
727 if (hlsdemux->current_variant != NULL) {
728 gint i;
729
730 //#warning FIXME: Syncing fragments across variants
731 // should be done based on media timestamps, and
732 // discont-sequence-numbers not sequence numbers.
733 variant->m3u8->sequence_position =
734 hlsdemux->current_variant->m3u8->sequence_position;
735 variant->m3u8->sequence = hlsdemux->current_variant->m3u8->sequence;
736
737 GST_DEBUG_OBJECT (hlsdemux,
738 "Switching Variant. Copying over sequence %" G_GINT64_FORMAT
739 " and sequence_pos %" GST_TIME_FORMAT, variant->m3u8->sequence,
740 GST_TIME_ARGS (variant->m3u8->sequence_position));
741
742 for (i = 0; i < GST_HLS_N_MEDIA_TYPES; ++i) {
743 GList *mlist = hlsdemux->current_variant->media[i];
744
745 while (mlist != NULL) {
746 GstHLSMedia *old_media = mlist->data;
747 GstHLSMedia *new_media =
748 gst_hls_variant_find_matching_media (variant, old_media);
749
750 if (new_media) {
751 GST_LOG_OBJECT (hlsdemux, "Found matching GstHLSMedia");
752 GST_LOG_OBJECT (hlsdemux, "old_media '%s' '%s'", old_media->name,
753 old_media->uri);
754 GST_LOG_OBJECT (hlsdemux, "new_media '%s' '%s'", new_media->name,
755 new_media->uri);
756 new_media->playlist->sequence = old_media->playlist->sequence;
757 new_media->playlist->sequence_position =
758 old_media->playlist->sequence_position;
759 } else {
760 GST_LOG_OBJECT (hlsdemux,
761 "Didn't find a matching variant for '%s' '%s'", old_media->name,
762 old_media->uri);
763 }
764 mlist = mlist->next;
765 }
766 }
767
768 if (hlsdemux->previous_variant)
769 gst_hls_variant_stream_unref (hlsdemux->previous_variant);
770 /* Steal the reference */
771 hlsdemux->previous_variant = hlsdemux->current_variant;
772 }
773
774 hlsdemux->current_variant = gst_hls_variant_stream_ref (variant);
775
776 }
777
778 static gboolean
gst_hls_demux_process_manifest(GstAdaptiveDemux * demux,GstBuffer * buf)779 gst_hls_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf)
780 {
781 GstHLSVariantStream *variant;
782 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
783 gchar *playlist = NULL;
784
785 GST_INFO_OBJECT (demux, "Initial playlist location: %s (base uri: %s)",
786 demux->manifest_uri, demux->manifest_base_uri);
787
788 playlist = gst_hls_src_buf_to_utf8_playlist (buf);
789 if (playlist == NULL) {
790 GST_WARNING_OBJECT (demux, "Error validating initial playlist");
791 return FALSE;
792 }
793
794 GST_M3U8_CLIENT_LOCK (self);
795 hlsdemux->master = gst_hls_master_playlist_new_from_data (playlist,
796 gst_adaptive_demux_get_manifest_ref_uri (demux));
797
798 if (hlsdemux->master == NULL || hlsdemux->master->variants == NULL) {
799 /* In most cases, this will happen if we set a wrong url in the
800 * source element and we have received the 404 HTML response instead of
801 * the playlist */
802 GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Invalid playlist."),
803 ("Could not parse playlist. Check if the URL is correct."));
804 GST_M3U8_CLIENT_UNLOCK (self);
805 return FALSE;
806 }
807
808 /* select the initial variant stream */
809 if (demux->connection_speed == 0) {
810 variant = hlsdemux->master->default_variant;
811 } else {
812 variant =
813 gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master,
814 NULL, demux->connection_speed);
815 }
816
817 if (variant) {
818 GST_INFO_OBJECT (hlsdemux, "selected %s", variant->name);
819 gst_hls_demux_set_current_variant (hlsdemux, variant); // FIXME: inline?
820 }
821
822 /* get the selected media playlist (unless the initial list was one already) */
823 if (!hlsdemux->master->is_simple) {
824 GError *err = NULL;
825
826 if (!gst_hls_demux_update_playlist (hlsdemux, FALSE, &err)) {
827 GST_ELEMENT_ERROR_FROM_ERROR (demux, "Could not fetch media playlist",
828 err);
829 GST_M3U8_CLIENT_UNLOCK (self);
830 return FALSE;
831 }
832 }
833 GST_M3U8_CLIENT_UNLOCK (self);
834
835 return gst_hls_demux_setup_streams (demux);
836 }
837
838 static GstClockTime
gst_hls_demux_get_duration(GstAdaptiveDemux * demux)839 gst_hls_demux_get_duration (GstAdaptiveDemux * demux)
840 {
841 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
842 GstClockTime duration = GST_CLOCK_TIME_NONE;
843
844 if (hlsdemux->current_variant != NULL)
845 duration = gst_m3u8_get_duration (hlsdemux->current_variant->m3u8);
846
847 return duration;
848 }
849
850 static gboolean
gst_hls_demux_is_live(GstAdaptiveDemux * demux)851 gst_hls_demux_is_live (GstAdaptiveDemux * demux)
852 {
853 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
854 gboolean is_live = FALSE;
855
856 if (hlsdemux->current_variant)
857 is_live = gst_hls_variant_stream_is_live (hlsdemux->current_variant);
858
859 return is_live;
860 }
861
862 static const GstHLSKey *
gst_hls_demux_get_key(GstHLSDemux * demux,const gchar * key_url,const gchar * referer,gboolean allow_cache)863 gst_hls_demux_get_key (GstHLSDemux * demux, const gchar * key_url,
864 const gchar * referer, gboolean allow_cache)
865 {
866 GstFragment *key_fragment;
867 GstBuffer *key_buffer;
868 GstHLSKey *key;
869 GError *err = NULL;
870
871 GST_LOG_OBJECT (demux, "Looking up key for key url %s", key_url);
872
873 g_mutex_lock (&demux->keys_lock);
874
875 key = g_hash_table_lookup (demux->keys, key_url);
876
877 if (key != NULL) {
878 GST_LOG_OBJECT (demux, "Found key for key url %s in key cache", key_url);
879 goto out;
880 }
881
882 GST_INFO_OBJECT (demux, "Fetching key %s", key_url);
883
884 key_fragment =
885 gst_uri_downloader_fetch_uri (GST_ADAPTIVE_DEMUX (demux)->downloader,
886 key_url, referer, FALSE, FALSE, allow_cache, &err);
887
888 if (key_fragment == NULL) {
889 GST_WARNING_OBJECT (demux, "Failed to download key to decrypt data: %s",
890 err ? err->message : "error");
891 g_clear_error (&err);
892 goto out;
893 }
894
895 key_buffer = gst_fragment_get_buffer (key_fragment);
896
897 key = g_new0 (GstHLSKey, 1);
898 if (gst_buffer_extract (key_buffer, 0, key->data, 16) < 16)
899 GST_WARNING_OBJECT (demux, "Download decryption key is too short!");
900
901 g_hash_table_insert (demux->keys, g_strdup (key_url), key);
902
903 gst_buffer_unref (key_buffer);
904 g_object_unref (key_fragment);
905
906 out:
907
908 g_mutex_unlock (&demux->keys_lock);
909
910 if (key != NULL)
911 GST_MEMDUMP_OBJECT (demux, "Key", key->data, 16);
912
913 return key;
914 }
915
916 static gboolean
gst_hls_demux_start_fragment(GstAdaptiveDemux * demux,GstAdaptiveDemuxStream * stream)917 gst_hls_demux_start_fragment (GstAdaptiveDemux * demux,
918 GstAdaptiveDemuxStream * stream)
919 {
920 GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
921 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
922 const GstHLSKey *key;
923 GstM3U8 *m3u8;
924
925 gst_hls_demux_stream_clear_pending_data (hls_stream);
926
927 /* Init the timestamp reader for this fragment */
928 gst_hlsdemux_tsreader_init (&hls_stream->tsreader);
929 /* Reset the stream type if we already know it */
930 gst_hlsdemux_tsreader_set_type (&hls_stream->tsreader,
931 hls_stream->stream_type);
932
933 /* If no decryption is needed, there's nothing to be done here */
934 if (hls_stream->current_key == NULL)
935 return TRUE;
936
937 m3u8 = gst_hls_demux_stream_get_m3u8 (hls_stream);
938
939 key = gst_hls_demux_get_key (hlsdemux, hls_stream->current_key,
940 m3u8->uri, m3u8->allowcache);
941
942 if (key == NULL)
943 goto key_failed;
944
945 if (!gst_hls_demux_stream_decrypt_start (hls_stream, key->data,
946 hls_stream->current_iv))
947 goto decrypt_start_failed;
948
949 return TRUE;
950
951 key_failed:
952 {
953 GST_ELEMENT_ERROR (demux, STREAM, DECRYPT_NOKEY,
954 ("Couldn't retrieve key for decryption"), (NULL));
955 GST_WARNING_OBJECT (demux, "Failed to decrypt data");
956 return FALSE;
957 }
958 decrypt_start_failed:
959 {
960 GST_ELEMENT_ERROR (demux, STREAM, DECRYPT, ("Failed to start decrypt"),
961 ("Couldn't set key and IV or plugin was built without crypto library"));
962 return FALSE;
963 }
964 }
965
966 static GstHLSTSReaderType
caps_to_reader(const GstCaps * caps)967 caps_to_reader (const GstCaps * caps)
968 {
969 const GstStructure *s = gst_caps_get_structure (caps, 0);
970
971 if (gst_structure_has_name (s, "video/mpegts"))
972 return GST_HLS_TSREADER_MPEGTS;
973 if (gst_structure_has_name (s, "application/x-id3"))
974 return GST_HLS_TSREADER_ID3;
975
976 return GST_HLS_TSREADER_NONE;
977 }
978
979 static GstFlowReturn
gst_hls_demux_handle_buffer(GstAdaptiveDemux * demux,GstAdaptiveDemuxStream * stream,GstBuffer * buffer,gboolean at_eos)980 gst_hls_demux_handle_buffer (GstAdaptiveDemux * demux,
981 GstAdaptiveDemuxStream * stream, GstBuffer * buffer, gboolean at_eos)
982 {
983 GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream); // FIXME: pass HlsStream into function
984 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
985 GstClockTime first_pcr, last_pcr;
986 GstTagList *tags;
987
988 if (buffer == NULL)
989 return GST_FLOW_OK;
990
991 if (G_UNLIKELY (hls_stream->do_typefind)) {
992 GstCaps *caps = NULL;
993 guint buffer_size;
994 GstTypeFindProbability prob = GST_TYPE_FIND_NONE;
995 GstMapInfo info;
996
997 if (hls_stream->pending_typefind_buffer)
998 buffer = gst_buffer_append (hls_stream->pending_typefind_buffer, buffer);
999 hls_stream->pending_typefind_buffer = NULL;
1000
1001 gst_buffer_map (buffer, &info, GST_MAP_READ);
1002 buffer_size = info.size;
1003
1004 /* Typefind could miss if buffer is too small. In this case we
1005 * will retry later */
1006 if (buffer_size >= (2 * 1024) || at_eos) {
1007 caps =
1008 gst_type_find_helper_for_data (GST_OBJECT_CAST (hlsdemux), info.data,
1009 info.size, &prob);
1010 }
1011
1012 if (G_UNLIKELY (!caps)) {
1013 /* Won't need this mapping any more all paths return inside this if() */
1014 gst_buffer_unmap (buffer, &info);
1015
1016 /* Only fail typefinding if we already a good amount of data
1017 * and we still don't know the type */
1018 if (buffer_size > (2 * 1024 * 1024) || at_eos) {
1019 GST_ELEMENT_ERROR (hlsdemux, STREAM, TYPE_NOT_FOUND,
1020 ("Could not determine type of stream"), (NULL));
1021 gst_buffer_unref (buffer);
1022 return GST_FLOW_NOT_NEGOTIATED;
1023 }
1024
1025 hls_stream->pending_typefind_buffer = buffer;
1026
1027 return GST_FLOW_OK;
1028 }
1029
1030 GST_DEBUG_OBJECT (stream->pad,
1031 "Typefind result: %" GST_PTR_FORMAT " prob:%d", caps, prob);
1032
1033 hls_stream->stream_type = caps_to_reader (caps);
1034 gst_hlsdemux_tsreader_set_type (&hls_stream->tsreader,
1035 hls_stream->stream_type);
1036
1037 gst_adaptive_demux_stream_set_caps (stream, caps);
1038
1039 hls_stream->do_typefind = FALSE;
1040
1041 gst_buffer_unmap (buffer, &info);
1042 }
1043 g_assert (hls_stream->pending_typefind_buffer == NULL);
1044
1045 // Accumulate this buffer
1046 if (hls_stream->pending_pcr_buffer) {
1047 buffer = gst_buffer_append (hls_stream->pending_pcr_buffer, buffer);
1048 hls_stream->pending_pcr_buffer = NULL;
1049 }
1050
1051 if (!gst_hlsdemux_tsreader_find_pcrs (&hls_stream->tsreader, &buffer,
1052 &first_pcr, &last_pcr, &tags)
1053 && !at_eos) {
1054 // Store this buffer for later
1055 hls_stream->pending_pcr_buffer = buffer;
1056 return GST_FLOW_OK;
1057 }
1058
1059 if (tags) {
1060 gst_adaptive_demux_stream_set_tags (stream, tags);
1061 /* run typefind again on the trimmed buffer */
1062 hls_stream->do_typefind = TRUE;
1063 return gst_hls_demux_handle_buffer (demux, stream, buffer, at_eos);
1064 }
1065
1066 if (buffer) {
1067 buffer = gst_buffer_make_writable (buffer);
1068 GST_BUFFER_OFFSET (buffer) = hls_stream->current_offset;
1069 hls_stream->current_offset += gst_buffer_get_size (buffer);
1070 GST_BUFFER_OFFSET_END (buffer) = hls_stream->current_offset;
1071 return gst_adaptive_demux_stream_push_buffer (stream, buffer);
1072 }
1073 return GST_FLOW_OK;
1074 }
1075
1076 static GstFlowReturn
gst_hls_demux_finish_fragment(GstAdaptiveDemux * demux,GstAdaptiveDemuxStream * stream)1077 gst_hls_demux_finish_fragment (GstAdaptiveDemux * demux,
1078 GstAdaptiveDemuxStream * stream)
1079 {
1080 GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream); // FIXME: pass HlsStream into function
1081 GstFlowReturn ret = GST_FLOW_OK;
1082
1083 if (hls_stream->current_key)
1084 gst_hls_demux_stream_decrypt_end (hls_stream);
1085
1086 if (stream->last_ret == GST_FLOW_OK) {
1087 if (hls_stream->pending_decrypted_buffer) {
1088 if (hls_stream->current_key) {
1089 GstMapInfo info;
1090 gssize unpadded_size;
1091
1092 /* Handle pkcs7 unpadding here */
1093 gst_buffer_map (hls_stream->pending_decrypted_buffer, &info,
1094 GST_MAP_READ);
1095 unpadded_size = info.size - info.data[info.size - 1];
1096 gst_buffer_unmap (hls_stream->pending_decrypted_buffer, &info);
1097
1098 gst_buffer_resize (hls_stream->pending_decrypted_buffer, 0,
1099 unpadded_size);
1100 }
1101
1102 ret =
1103 gst_hls_demux_handle_buffer (demux, stream,
1104 hls_stream->pending_decrypted_buffer, TRUE);
1105 hls_stream->pending_decrypted_buffer = NULL;
1106 }
1107
1108 if (ret == GST_FLOW_OK || ret == GST_FLOW_NOT_LINKED) {
1109 if (G_UNLIKELY (hls_stream->pending_typefind_buffer)) {
1110 GstBuffer *buf = hls_stream->pending_typefind_buffer;
1111 hls_stream->pending_typefind_buffer = NULL;
1112
1113 gst_hls_demux_handle_buffer (demux, stream, buf, TRUE);
1114 }
1115
1116 if (hls_stream->pending_pcr_buffer) {
1117 GstBuffer *buf = hls_stream->pending_pcr_buffer;
1118 hls_stream->pending_pcr_buffer = NULL;
1119
1120 ret = gst_hls_demux_handle_buffer (demux, stream, buf, TRUE);
1121 }
1122
1123 GST_LOG_OBJECT (stream->pad,
1124 "Fragment PCRs were %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
1125 GST_TIME_ARGS (hls_stream->tsreader.first_pcr),
1126 GST_TIME_ARGS (hls_stream->tsreader.last_pcr));
1127 }
1128 }
1129
1130 if (G_UNLIKELY (stream->downloading_header || stream->downloading_index))
1131 return GST_FLOW_OK;
1132
1133 gst_hls_demux_stream_clear_pending_data (hls_stream);
1134
1135 if (ret == GST_FLOW_OK || ret == GST_FLOW_NOT_LINKED)
1136 return gst_adaptive_demux_stream_advance_fragment (demux, stream,
1137 stream->fragment.duration);
1138 return ret;
1139 }
1140
1141 static GstFlowReturn
gst_hls_demux_data_received(GstAdaptiveDemux * demux,GstAdaptiveDemuxStream * stream,GstBuffer * buffer)1142 gst_hls_demux_data_received (GstAdaptiveDemux * demux,
1143 GstAdaptiveDemuxStream * stream, GstBuffer * buffer)
1144 {
1145 GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
1146 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
1147
1148 if (hls_stream->current_offset == -1)
1149 hls_stream->current_offset = 0;
1150
1151 /* Is it encrypted? */
1152 if (hls_stream->current_key) {
1153 GError *err = NULL;
1154 gsize size;
1155 GstBuffer *tmp_buffer;
1156
1157 if (hls_stream->pending_encrypted_data == NULL)
1158 hls_stream->pending_encrypted_data = gst_adapter_new ();
1159
1160 gst_adapter_push (hls_stream->pending_encrypted_data, buffer);
1161 size = gst_adapter_available (hls_stream->pending_encrypted_data);
1162
1163 /* must be a multiple of 16 */
1164 size &= (~0xF);
1165
1166 if (size == 0) {
1167 return GST_FLOW_OK;
1168 }
1169
1170 buffer = gst_adapter_take_buffer (hls_stream->pending_encrypted_data, size);
1171 buffer =
1172 gst_hls_demux_decrypt_fragment (hlsdemux, hls_stream, buffer, &err);
1173 if (buffer == NULL) {
1174 GST_ELEMENT_ERROR (demux, STREAM, DECODE, ("Failed to decrypt buffer"),
1175 ("decryption failed %s", err->message));
1176 g_error_free (err);
1177 return GST_FLOW_ERROR;
1178 }
1179
1180 tmp_buffer = hls_stream->pending_decrypted_buffer;
1181 hls_stream->pending_decrypted_buffer = buffer;
1182 buffer = tmp_buffer;
1183 }
1184
1185 return gst_hls_demux_handle_buffer (demux, stream, buffer, FALSE);
1186 }
1187
1188 #ifdef OHOS_EXT_FUNC
1189 // ohos.ext.func.0028
gst_hls_demux_get_bitrate_info(GstAdaptiveDemux * demux,GstAdaptiveDemuxBitrateInfo * bitrate_info)1190 static gboolean gst_hls_demux_get_bitrate_info(GstAdaptiveDemux * demux,
1191 GstAdaptiveDemuxBitrateInfo * bitrate_info)
1192 {
1193 GstHLSDemux *hls_demux = GST_HLS_DEMUX_CAST (demux);
1194 gint idx = 0;
1195 GList *rep_list = NULL;
1196 GList *list = NULL;
1197 GstHLSVariantStream *representation = NULL;
1198
1199 if ((hls_demux->master == NULL) || (hls_demux->master->variants == NULL)) {
1200 return FALSE;
1201 }
1202
1203 rep_list = hls_demux->master->variants;
1204 bitrate_info->bitrate_num = g_list_length (rep_list);
1205 GST_INFO_OBJECT (hls_demux, "there are %u bitrate num", bitrate_info->bitrate_num);
1206 if ((bitrate_info->bitrate_num == 0) || (bitrate_info->bitrate_num > MAX_BITRATE_NUM)) {
1207 GST_WARNING_OBJECT (hls_demux, "bitrate_num(%u) is error", bitrate_info->bitrate_num);
1208 return FALSE;
1209 }
1210
1211 bitrate_info->bitrate_list = g_malloc0 (sizeof(guint) * bitrate_info->bitrate_num);
1212 if (bitrate_info->bitrate_list == NULL) {
1213 GST_ERROR_OBJECT (hls_demux, "bitrate_list alloc failed");
1214 return FALSE;
1215 }
1216
1217 for (list = g_list_first(hls_demux->master->variants); list != NULL; list = g_list_next(list)) {
1218 representation = (GstHLSVariantStream *)list->data;
1219 if (representation != NULL) {
1220 bitrate_info->bitrate_list[idx] = (guint) representation->bandwidth;
1221 GST_INFO_OBJECT (hls_demux, "video bitrate[%d]:[%d]", idx, representation->bandwidth);
1222 }
1223 idx++;
1224 }
1225
1226 return TRUE;
1227 }
1228 #endif
1229
1230 static void
gst_hls_demux_stream_free(GstAdaptiveDemuxStream * stream)1231 gst_hls_demux_stream_free (GstAdaptiveDemuxStream * stream)
1232 {
1233 GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
1234
1235 if (hls_stream->playlist) {
1236 gst_m3u8_unref (hls_stream->playlist);
1237 hls_stream->playlist = NULL;
1238 }
1239
1240 if (hls_stream->pending_encrypted_data)
1241 g_object_unref (hls_stream->pending_encrypted_data);
1242
1243 gst_buffer_replace (&hls_stream->pending_decrypted_buffer, NULL);
1244 gst_buffer_replace (&hls_stream->pending_typefind_buffer, NULL);
1245 gst_buffer_replace (&hls_stream->pending_pcr_buffer, NULL);
1246
1247 if (hls_stream->current_key) {
1248 g_free (hls_stream->current_key);
1249 hls_stream->current_key = NULL;
1250 }
1251 if (hls_stream->current_iv) {
1252 g_free (hls_stream->current_iv);
1253 hls_stream->current_iv = NULL;
1254 }
1255 gst_hls_demux_stream_decrypt_end (hls_stream);
1256 }
1257
1258 static GstM3U8 *
gst_hls_demux_stream_get_m3u8(GstHLSDemuxStream * hlsdemux_stream)1259 gst_hls_demux_stream_get_m3u8 (GstHLSDemuxStream * hlsdemux_stream)
1260 {
1261 GstM3U8 *m3u8;
1262
1263 m3u8 = hlsdemux_stream->playlist;
1264
1265 return m3u8;
1266 }
1267
1268 static gboolean
gst_hls_demux_stream_has_next_fragment(GstAdaptiveDemuxStream * stream)1269 gst_hls_demux_stream_has_next_fragment (GstAdaptiveDemuxStream * stream)
1270 {
1271 gboolean has_next;
1272 GstM3U8 *m3u8;
1273
1274 m3u8 = gst_hls_demux_stream_get_m3u8 (GST_HLS_DEMUX_STREAM_CAST (stream));
1275
1276 has_next = gst_m3u8_has_next_fragment (m3u8, stream->demux->segment.rate > 0);
1277
1278 return has_next;
1279 }
1280
1281 static GstFlowReturn
gst_hls_demux_advance_fragment(GstAdaptiveDemuxStream * stream)1282 gst_hls_demux_advance_fragment (GstAdaptiveDemuxStream * stream)
1283 {
1284 GstHLSDemuxStream *hlsdemux_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
1285 GstM3U8 *m3u8;
1286
1287 m3u8 = gst_hls_demux_stream_get_m3u8 (hlsdemux_stream);
1288
1289 gst_m3u8_advance_fragment (m3u8, stream->demux->segment.rate > 0);
1290 hlsdemux_stream->reset_pts = FALSE;
1291
1292 return GST_FLOW_OK;
1293 }
1294
1295 static GstFlowReturn
gst_hls_demux_update_fragment_info(GstAdaptiveDemuxStream * stream)1296 gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream * stream)
1297 {
1298 GstHLSDemuxStream *hlsdemux_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
1299 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (stream->demux);
1300 GstM3U8MediaFile *file;
1301 GstClockTime sequence_pos;
1302 gboolean discont, forward;
1303 GstM3U8 *m3u8;
1304
1305 m3u8 = gst_hls_demux_stream_get_m3u8 (hlsdemux_stream);
1306
1307 forward = (stream->demux->segment.rate > 0);
1308 file = gst_m3u8_get_next_fragment (m3u8, forward, &sequence_pos, &discont);
1309
1310 if (file == NULL) {
1311 GST_INFO_OBJECT (hlsdemux, "This playlist doesn't contain more fragments");
1312 return GST_FLOW_EOS;
1313 }
1314
1315 if (GST_ADAPTIVE_DEMUX_STREAM_NEED_HEADER (stream) && file->init_file) {
1316 GstM3U8InitFile *header_file = file->init_file;
1317 stream->fragment.header_uri = g_strdup (header_file->uri);
1318 stream->fragment.header_range_start = header_file->offset;
1319 if (header_file->size != -1) {
1320 stream->fragment.header_range_end =
1321 header_file->offset + header_file->size - 1;
1322 } else {
1323 stream->fragment.header_range_end = -1;
1324 }
1325 }
1326
1327 if (stream->discont)
1328 discont = TRUE;
1329
1330 /* set up our source for download */
1331 if (hlsdemux_stream->reset_pts || discont
1332 || stream->demux->segment.rate < 0.0) {
1333 stream->fragment.timestamp = sequence_pos;
1334 } else {
1335 stream->fragment.timestamp = GST_CLOCK_TIME_NONE;
1336 }
1337
1338 g_free (hlsdemux_stream->current_key);
1339 hlsdemux_stream->current_key = g_strdup (file->key);
1340 g_free (hlsdemux_stream->current_iv);
1341 hlsdemux_stream->current_iv = g_memdup2 (file->iv, sizeof (file->iv));
1342
1343 g_free (stream->fragment.uri);
1344 stream->fragment.uri = g_strdup (file->uri);
1345
1346 GST_DEBUG_OBJECT (hlsdemux, "Stream %p URI now %s", stream, file->uri);
1347
1348 stream->fragment.range_start = file->offset;
1349 if (file->size != -1)
1350 stream->fragment.range_end = file->offset + file->size - 1;
1351 else
1352 stream->fragment.range_end = -1;
1353
1354 stream->fragment.duration = file->duration;
1355
1356 if (discont)
1357 stream->discont = TRUE;
1358
1359 gst_m3u8_media_file_unref (file);
1360
1361 return GST_FLOW_OK;
1362 }
1363
1364 static gboolean
gst_hls_demux_select_bitrate(GstAdaptiveDemuxStream * stream,guint64 bitrate)1365 gst_hls_demux_select_bitrate (GstAdaptiveDemuxStream * stream, guint64 bitrate)
1366 {
1367 GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX_CAST (stream->demux);
1368 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (stream->demux);
1369 GstHLSDemuxStream *hls_stream = GST_HLS_DEMUX_STREAM_CAST (stream);
1370
1371 gboolean changed = FALSE;
1372
1373 GST_M3U8_CLIENT_LOCK (hlsdemux->client);
1374 if (hlsdemux->master == NULL || hlsdemux->master->is_simple) {
1375 GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
1376 return FALSE;
1377 }
1378 GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
1379
1380 if (hls_stream->is_primary_playlist == FALSE) {
1381 GST_LOG_OBJECT (hlsdemux,
1382 "Stream %p Not choosing new bitrate - not the primary stream", stream);
1383 return FALSE;
1384 }
1385
1386 gst_hls_demux_change_playlist (hlsdemux, bitrate / MAX (1.0,
1387 ABS (demux->segment.rate)), &changed);
1388 if (changed)
1389 gst_hls_demux_setup_streams (GST_ADAPTIVE_DEMUX_CAST (hlsdemux));
1390 return changed;
1391 }
1392
1393 static void
gst_hls_demux_reset(GstAdaptiveDemux * ademux)1394 gst_hls_demux_reset (GstAdaptiveDemux * ademux)
1395 {
1396 GstHLSDemux *demux = GST_HLS_DEMUX_CAST (ademux);
1397
1398 GST_DEBUG_OBJECT (demux, "resetting");
1399
1400 GST_M3U8_CLIENT_LOCK (hlsdemux->client);
1401 if (demux->master) {
1402 gst_hls_master_playlist_unref (demux->master);
1403 demux->master = NULL;
1404 }
1405 if (demux->current_variant != NULL) {
1406 gst_hls_variant_stream_unref (demux->current_variant);
1407 demux->current_variant = NULL;
1408 }
1409 if (demux->previous_variant != NULL) {
1410 gst_hls_variant_stream_unref (demux->previous_variant);
1411 demux->previous_variant = NULL;
1412 }
1413 demux->srcpad_counter = 0;
1414 demux->streams_aware = GST_OBJECT_PARENT (demux)
1415 && GST_OBJECT_FLAG_IS_SET (GST_OBJECT_PARENT (demux),
1416 GST_BIN_FLAG_STREAMS_AWARE);
1417 GST_DEBUG_OBJECT (demux, "Streams aware : %d", demux->streams_aware);
1418
1419 gst_hls_demux_clear_all_pending_data (demux);
1420 GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
1421 }
1422
1423 static gchar *
gst_hls_src_buf_to_utf8_playlist(GstBuffer * buf)1424 gst_hls_src_buf_to_utf8_playlist (GstBuffer * buf)
1425 {
1426 GstMapInfo info;
1427 gchar *playlist;
1428
1429 if (!gst_buffer_map (buf, &info, GST_MAP_READ))
1430 goto map_error;
1431
1432 if (!g_utf8_validate ((gchar *) info.data, info.size, NULL))
1433 goto validate_error;
1434
1435 /* alloc size + 1 to end with a null character */
1436 playlist = g_malloc0 (info.size + 1);
1437 memcpy (playlist, info.data, info.size);
1438
1439 gst_buffer_unmap (buf, &info);
1440 return playlist;
1441
1442 validate_error:
1443 gst_buffer_unmap (buf, &info);
1444 map_error:
1445 return NULL;
1446 }
1447
1448 static gint
gst_hls_demux_find_variant_match(const GstHLSVariantStream * a,const GstHLSVariantStream * b)1449 gst_hls_demux_find_variant_match (const GstHLSVariantStream * a,
1450 const GstHLSVariantStream * b)
1451 {
1452 if (g_strcmp0 (a->name, b->name) == 0 &&
1453 a->bandwidth == b->bandwidth &&
1454 a->program_id == b->program_id &&
1455 g_strcmp0 (a->codecs, b->codecs) == 0 &&
1456 a->width == b->width &&
1457 a->height == b->height && a->iframe == b->iframe) {
1458 return 0;
1459 }
1460
1461 return 1;
1462 }
1463
1464 /* Update the master playlist, which contains the list of available
1465 * variants */
1466 static gboolean
gst_hls_demux_update_variant_playlist(GstHLSDemux * hlsdemux,gchar * data,const gchar * uri,const gchar * base_uri)1467 gst_hls_demux_update_variant_playlist (GstHLSDemux * hlsdemux, gchar * data,
1468 const gchar * uri, const gchar * base_uri)
1469 {
1470 GstHLSMasterPlaylist *new_master, *old;
1471 gboolean ret = FALSE;
1472 GList *l, *unmatched_lists;
1473 GstHLSVariantStream *new_variant;
1474
1475 new_master = gst_hls_master_playlist_new_from_data (data, base_uri ? base_uri : uri); // FIXME: check which uri to use here
1476
1477 if (new_master == NULL)
1478 return ret;
1479
1480 if (new_master->is_simple) {
1481 // FIXME: we should be able to support this though, in the unlikely
1482 // case that it changed?
1483 GST_ERROR
1484 ("Cannot update variant playlist: New playlist is not a variant playlist");
1485 gst_hls_master_playlist_unref (new_master);
1486 return FALSE;
1487 }
1488
1489 GST_M3U8_CLIENT_LOCK (self);
1490
1491 if (hlsdemux->master->is_simple) {
1492 GST_ERROR
1493 ("Cannot update variant playlist: Current playlist is not a variant playlist");
1494 gst_hls_master_playlist_unref (new_master);
1495 goto out;
1496 }
1497
1498 /* Now see if the variant playlist still has the same lists */
1499 unmatched_lists = g_list_copy (hlsdemux->master->variants);
1500 for (l = new_master->variants; l != NULL; l = l->next) {
1501 GList *match = g_list_find_custom (unmatched_lists, l->data,
1502 (GCompareFunc) gst_hls_demux_find_variant_match);
1503
1504 if (match) {
1505 GstHLSVariantStream *variant = l->data;
1506 GstHLSVariantStream *old = match->data;
1507
1508 unmatched_lists = g_list_delete_link (unmatched_lists, match);
1509 /* FIXME: Deal with losing position due to missing an update */
1510 variant->m3u8->sequence_position = old->m3u8->sequence_position;
1511 variant->m3u8->sequence = old->m3u8->sequence;
1512 }
1513 }
1514
1515 if (unmatched_lists != NULL) {
1516 GST_WARNING ("Unable to match all playlists");
1517
1518 for (l = unmatched_lists; l != NULL; l = l->next) {
1519 if (l->data == hlsdemux->current_variant) {
1520 GST_WARNING ("Unable to match current playlist");
1521 }
1522 }
1523
1524 g_list_free (unmatched_lists);
1525 }
1526
1527 /* Switch out the variant playlist */
1528 old = hlsdemux->master;
1529
1530 // FIXME: check all this and also switch of variants, if anything needs updating
1531 hlsdemux->master = new_master;
1532
1533 if (hlsdemux->current_variant == NULL) {
1534 new_variant = new_master->default_variant;
1535 } else {
1536 /* Find the same variant in the new playlist */
1537 new_variant =
1538 gst_hls_master_playlist_get_matching_variant (new_master,
1539 hlsdemux->current_variant);
1540 }
1541
1542 /* Use the function to set the current variant, as it copies over data */
1543 if (new_variant != NULL)
1544 gst_hls_demux_set_current_variant (hlsdemux, new_variant);
1545
1546 gst_hls_master_playlist_unref (old);
1547
1548 ret = (hlsdemux->current_variant != NULL);
1549 out:
1550 GST_M3U8_CLIENT_UNLOCK (self);
1551
1552 return ret;
1553 }
1554
1555 static gboolean
gst_hls_demux_update_rendition_manifest(GstHLSDemux * demux,GstHLSMedia * media,GError ** err)1556 gst_hls_demux_update_rendition_manifest (GstHLSDemux * demux,
1557 GstHLSMedia * media, GError ** err)
1558 {
1559 GstAdaptiveDemux *adaptive_demux = GST_ADAPTIVE_DEMUX (demux);
1560 GstFragment *download;
1561 GstBuffer *buf;
1562 gchar *playlist;
1563 const gchar *main_uri;
1564 GstM3U8 *m3u8;
1565 gchar *uri = media->uri;
1566
1567 main_uri = gst_adaptive_demux_get_manifest_ref_uri (adaptive_demux);
1568 download =
1569 gst_uri_downloader_fetch_uri (adaptive_demux->downloader, uri, main_uri,
1570 TRUE, TRUE, TRUE, err);
1571
1572 if (download == NULL)
1573 return FALSE;
1574
1575 m3u8 = media->playlist;
1576
1577 /* Set the base URI of the playlist to the redirect target if any */
1578 if (download->redirect_permanent && download->redirect_uri) {
1579 gst_m3u8_set_uri (m3u8, download->redirect_uri, NULL, media->name);
1580 } else {
1581 gst_m3u8_set_uri (m3u8, download->uri, download->redirect_uri, media->name);
1582 }
1583
1584 buf = gst_fragment_get_buffer (download);
1585 playlist = gst_hls_src_buf_to_utf8_playlist (buf);
1586 gst_buffer_unref (buf);
1587 g_object_unref (download);
1588
1589 if (playlist == NULL) {
1590 GST_WARNING_OBJECT (demux, "Couldn't validate playlist encoding");
1591 g_set_error (err, GST_STREAM_ERROR, GST_STREAM_ERROR_WRONG_TYPE,
1592 "Couldn't validate playlist encoding");
1593 return FALSE;
1594 }
1595
1596 if (!gst_m3u8_update (m3u8, playlist)) {
1597 GST_WARNING_OBJECT (demux, "Couldn't update playlist");
1598 g_set_error (err, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
1599 "Couldn't update playlist");
1600 return FALSE;
1601 }
1602
1603 return TRUE;
1604 }
1605
1606 static gboolean
gst_hls_demux_update_playlist(GstHLSDemux * demux,gboolean update,GError ** err)1607 gst_hls_demux_update_playlist (GstHLSDemux * demux, gboolean update,
1608 GError ** err)
1609 {
1610 GstAdaptiveDemux *adaptive_demux = GST_ADAPTIVE_DEMUX (demux);
1611 GstFragment *download;
1612 GstBuffer *buf;
1613 gchar *playlist;
1614 gboolean main_checked = FALSE;
1615 const gchar *main_uri;
1616 GstM3U8 *m3u8;
1617 gchar *uri;
1618 gint i;
1619
1620 retry:
1621 uri = gst_m3u8_get_uri (demux->current_variant->m3u8);
1622 main_uri = gst_adaptive_demux_get_manifest_ref_uri (adaptive_demux);
1623 download =
1624 gst_uri_downloader_fetch_uri (adaptive_demux->downloader, uri, main_uri,
1625 TRUE, TRUE, TRUE, err);
1626 if (download == NULL) {
1627 gchar *base_uri;
1628
1629 if (!update || main_checked || demux->master->is_simple
1630 || !gst_adaptive_demux_is_running (GST_ADAPTIVE_DEMUX_CAST (demux))) {
1631 g_free (uri);
1632 return FALSE;
1633 }
1634 g_clear_error (err);
1635 GST_INFO_OBJECT (demux,
1636 "Updating playlist %s failed, attempt to refresh variant playlist %s",
1637 uri, main_uri);
1638 download =
1639 gst_uri_downloader_fetch_uri (adaptive_demux->downloader,
1640 main_uri, NULL, TRUE, TRUE, TRUE, err);
1641 if (download == NULL) {
1642 g_free (uri);
1643 return FALSE;
1644 }
1645
1646 buf = gst_fragment_get_buffer (download);
1647 playlist = gst_hls_src_buf_to_utf8_playlist (buf);
1648 gst_buffer_unref (buf);
1649
1650 if (playlist == NULL) {
1651 GST_WARNING_OBJECT (demux,
1652 "Failed to validate variant playlist encoding");
1653 g_free (uri);
1654 g_object_unref (download);
1655 g_set_error (err, GST_STREAM_ERROR, GST_STREAM_ERROR_WRONG_TYPE,
1656 "Couldn't validate playlist encoding");
1657 return FALSE;
1658 }
1659
1660 g_free (uri);
1661 if (download->redirect_permanent && download->redirect_uri) {
1662 uri = download->redirect_uri;
1663 base_uri = NULL;
1664 } else {
1665 uri = download->uri;
1666 base_uri = download->redirect_uri;
1667 }
1668
1669 if (!gst_hls_demux_update_variant_playlist (demux, playlist, uri, base_uri)) {
1670 GST_WARNING_OBJECT (demux, "Failed to update the variant playlist");
1671 g_object_unref (download);
1672 g_set_error (err, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
1673 "Couldn't update playlist");
1674 return FALSE;
1675 }
1676
1677 g_object_unref (download);
1678
1679 main_checked = TRUE;
1680 goto retry;
1681 }
1682 g_free (uri);
1683
1684 m3u8 = demux->current_variant->m3u8;
1685
1686 /* Set the base URI of the playlist to the redirect target if any */
1687 if (download->redirect_permanent && download->redirect_uri) {
1688 gst_m3u8_set_uri (m3u8, download->redirect_uri, NULL,
1689 demux->current_variant->name);
1690 } else {
1691 gst_m3u8_set_uri (m3u8, download->uri, download->redirect_uri,
1692 demux->current_variant->name);
1693 }
1694
1695 buf = gst_fragment_get_buffer (download);
1696 playlist = gst_hls_src_buf_to_utf8_playlist (buf);
1697 gst_buffer_unref (buf);
1698 g_object_unref (download);
1699
1700 if (playlist == NULL) {
1701 GST_WARNING_OBJECT (demux, "Couldn't validate playlist encoding");
1702 g_set_error (err, GST_STREAM_ERROR, GST_STREAM_ERROR_WRONG_TYPE,
1703 "Couldn't validate playlist encoding");
1704 return FALSE;
1705 }
1706
1707 if (!gst_m3u8_update (m3u8, playlist)) {
1708 GST_WARNING_OBJECT (demux, "Couldn't update playlist");
1709 g_set_error (err, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
1710 "Couldn't update playlist");
1711 return FALSE;
1712 }
1713
1714 for (i = 0; i < GST_HLS_N_MEDIA_TYPES; ++i) {
1715 GList *mlist = demux->current_variant->media[i];
1716
1717 while (mlist != NULL) {
1718 GstHLSMedia *media = mlist->data;
1719
1720 if (media->uri == NULL) {
1721 /* No uri means this is a placeholder for a stream
1722 * contained in another mux */
1723 mlist = mlist->next;
1724 continue;
1725 }
1726 GST_LOG_OBJECT (demux,
1727 "Updating playlist for media of type %d - %s, uri: %s", i,
1728 media->name, media->uri);
1729
1730 if (!gst_hls_demux_update_rendition_manifest (demux, media, err))
1731 return FALSE;
1732
1733 mlist = mlist->next;
1734 }
1735 }
1736
1737 /* If it's a live source, do not let the sequence number go beyond
1738 * three fragments before the end of the list */
1739 if (update == FALSE && gst_m3u8_is_live (m3u8)) {
1740 gint64 last_sequence, first_sequence;
1741
1742 GST_M3U8_CLIENT_LOCK (demux->client);
1743 last_sequence =
1744 GST_M3U8_MEDIA_FILE (g_list_last (m3u8->files)->data)->sequence;
1745 first_sequence =
1746 GST_M3U8_MEDIA_FILE (g_list_first (m3u8->files)->data)->sequence;
1747
1748 GST_DEBUG_OBJECT (demux,
1749 "sequence:%" G_GINT64_FORMAT " , first_sequence:%" G_GINT64_FORMAT
1750 " , last_sequence:%" G_GINT64_FORMAT, m3u8->sequence,
1751 first_sequence, last_sequence);
1752 if (m3u8->sequence > last_sequence - 3) {
1753 //demux->need_segment = TRUE;
1754 /* Make sure we never go below the minimum sequence number */
1755 m3u8->sequence = MAX (first_sequence, last_sequence - 3);
1756 GST_DEBUG_OBJECT (demux,
1757 "Sequence is beyond playlist. Moving back to %" G_GINT64_FORMAT,
1758 m3u8->sequence);
1759 }
1760 GST_M3U8_CLIENT_UNLOCK (demux->client);
1761 } else if (!gst_m3u8_is_live (m3u8)) {
1762 GstClockTime current_pos, target_pos;
1763 guint sequence = 0;
1764 GList *walk;
1765
1766 /* Sequence numbers are not guaranteed to be the same in different
1767 * playlists, so get the correct fragment here based on the current
1768 * position
1769 */
1770 GST_M3U8_CLIENT_LOCK (demux->client);
1771
1772 /* Valid because hlsdemux only has a single output */
1773 if (GST_ADAPTIVE_DEMUX_CAST (demux)->streams) {
1774 GstAdaptiveDemuxStream *stream =
1775 GST_ADAPTIVE_DEMUX_CAST (demux)->streams->data;
1776 target_pos = stream->segment.position;
1777 } else {
1778 target_pos = 0;
1779 }
1780 if (GST_CLOCK_TIME_IS_VALID (m3u8->sequence_position)) {
1781 target_pos = MAX (target_pos, m3u8->sequence_position);
1782 }
1783
1784 GST_LOG_OBJECT (demux, "Looking for sequence position %"
1785 GST_TIME_FORMAT " in updated playlist", GST_TIME_ARGS (target_pos));
1786
1787 current_pos = 0;
1788 for (walk = m3u8->files; walk; walk = walk->next) {
1789 GstM3U8MediaFile *file = walk->data;
1790
1791 sequence = file->sequence;
1792 if (current_pos <= target_pos
1793 && target_pos < current_pos + file->duration) {
1794 break;
1795 }
1796 current_pos += file->duration;
1797 }
1798 /* End of playlist */
1799 if (!walk)
1800 sequence++;
1801 m3u8->sequence = sequence;
1802 m3u8->sequence_position = current_pos;
1803 GST_M3U8_CLIENT_UNLOCK (demux->client);
1804 }
1805
1806 return TRUE;
1807 }
1808
1809 static gboolean
gst_hls_demux_change_playlist(GstHLSDemux * demux,guint max_bitrate,gboolean * changed)1810 gst_hls_demux_change_playlist (GstHLSDemux * demux, guint max_bitrate,
1811 gboolean * changed)
1812 {
1813 GstHLSVariantStream *lowest_variant, *lowest_ivariant;
1814 GstHLSVariantStream *previous_variant, *new_variant;
1815 gint old_bandwidth, new_bandwidth;
1816 GstAdaptiveDemux *adaptive_demux = GST_ADAPTIVE_DEMUX_CAST (demux);
1817 GstAdaptiveDemuxStream *stream;
1818
1819 g_return_val_if_fail (adaptive_demux->streams != NULL, FALSE);
1820
1821 stream = adaptive_demux->streams->data;
1822
1823 /* Make sure we keep a reference in case we need to switch back */
1824 previous_variant = gst_hls_variant_stream_ref (demux->current_variant);
1825 new_variant =
1826 gst_hls_master_playlist_get_variant_for_bitrate (demux->master,
1827 demux->current_variant, max_bitrate);
1828
1829 GST_M3U8_CLIENT_LOCK (demux->client);
1830
1831 retry_failover_protection:
1832 old_bandwidth = previous_variant->bandwidth;
1833 new_bandwidth = new_variant->bandwidth;
1834
1835 /* Don't do anything else if the playlist is the same */
1836 if (new_bandwidth == old_bandwidth) {
1837 GST_M3U8_CLIENT_UNLOCK (demux->client);
1838 gst_hls_variant_stream_unref (previous_variant);
1839 return TRUE;
1840 }
1841
1842 GST_M3U8_CLIENT_UNLOCK (demux->client);
1843
1844 gst_hls_demux_set_current_variant (demux, new_variant);
1845
1846 GST_INFO_OBJECT (demux, "Client was on %dbps, max allowed is %dbps, switching"
1847 " to bitrate %dbps", old_bandwidth, max_bitrate, new_bandwidth);
1848
1849 if (gst_hls_demux_update_playlist (demux, TRUE, NULL)) {
1850 const gchar *main_uri;
1851 gchar *uri;
1852
1853 uri = gst_m3u8_get_uri (new_variant->m3u8);
1854 main_uri = gst_adaptive_demux_get_manifest_ref_uri (adaptive_demux);
1855 gst_element_post_message (GST_ELEMENT_CAST (demux),
1856 gst_message_new_element (GST_OBJECT_CAST (demux),
1857 gst_structure_new (GST_ADAPTIVE_DEMUX_STATISTICS_MESSAGE_NAME,
1858 "manifest-uri", G_TYPE_STRING,
1859 main_uri, "uri", G_TYPE_STRING,
1860 uri, "bitrate", G_TYPE_INT, new_bandwidth, NULL)));
1861 g_free (uri);
1862 if (changed)
1863 *changed = TRUE;
1864 stream->discont = TRUE;
1865 } else if (gst_adaptive_demux_is_running (GST_ADAPTIVE_DEMUX_CAST (demux))) {
1866 GstHLSVariantStream *failover_variant = NULL;
1867 GList *failover;
1868
1869 GST_INFO_OBJECT (demux, "Unable to update playlist. Switching back");
1870 GST_M3U8_CLIENT_LOCK (demux->client);
1871
1872 /* we find variants by bitrate by going from highest to lowest, so it's
1873 * possible that there's another variant with the same bitrate before the
1874 * one selected which we can use as failover */
1875 failover = g_list_find (demux->master->variants, new_variant);
1876 if (failover != NULL)
1877 failover = failover->prev;
1878 if (failover != NULL)
1879 failover_variant = failover->data;
1880 if (failover_variant && new_bandwidth == failover_variant->bandwidth) {
1881 new_variant = failover_variant;
1882 goto retry_failover_protection;
1883 }
1884
1885 GST_M3U8_CLIENT_UNLOCK (demux->client);
1886 gst_hls_demux_set_current_variant (demux, previous_variant);
1887 /* Try a lower bitrate (or stop if we just tried the lowest) */
1888 if (previous_variant->iframe) {
1889 lowest_ivariant = demux->master->iframe_variants->data;
1890 if (new_bandwidth == lowest_ivariant->bandwidth)
1891 return FALSE;
1892 } else {
1893 lowest_variant = demux->master->variants->data;
1894 if (new_bandwidth == lowest_variant->bandwidth)
1895 return FALSE;
1896 }
1897 return gst_hls_demux_change_playlist (demux, new_bandwidth - 1, changed);
1898 }
1899
1900 gst_hls_variant_stream_unref (previous_variant);
1901 return TRUE;
1902 }
1903
1904 #if defined(HAVE_OPENSSL)
1905 static gboolean
gst_hls_demux_stream_decrypt_start(GstHLSDemuxStream * stream,const guint8 * key_data,const guint8 * iv_data)1906 gst_hls_demux_stream_decrypt_start (GstHLSDemuxStream * stream,
1907 const guint8 * key_data, const guint8 * iv_data)
1908 {
1909 EVP_CIPHER_CTX *ctx;
1910 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1911 EVP_CIPHER_CTX_init (&stream->aes_ctx);
1912 ctx = &stream->aes_ctx;
1913 #else
1914 stream->aes_ctx = EVP_CIPHER_CTX_new ();
1915 ctx = stream->aes_ctx;
1916 #endif
1917 if (!EVP_DecryptInit_ex (ctx, EVP_aes_128_cbc (), NULL, key_data, iv_data))
1918 return FALSE;
1919 EVP_CIPHER_CTX_set_padding (ctx, 0);
1920 return TRUE;
1921 }
1922
1923 static gboolean
decrypt_fragment(GstHLSDemuxStream * stream,gsize length,const guint8 * encrypted_data,guint8 * decrypted_data)1924 decrypt_fragment (GstHLSDemuxStream * stream, gsize length,
1925 const guint8 * encrypted_data, guint8 * decrypted_data)
1926 {
1927 int len, flen = 0;
1928 EVP_CIPHER_CTX *ctx;
1929
1930 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1931 ctx = &stream->aes_ctx;
1932 #else
1933 ctx = stream->aes_ctx;
1934 #endif
1935
1936 if (G_UNLIKELY (length > G_MAXINT || length % 16 != 0))
1937 return FALSE;
1938
1939 len = (int) length;
1940 if (!EVP_DecryptUpdate (ctx, decrypted_data, &len, encrypted_data, len))
1941 return FALSE;
1942 EVP_DecryptFinal_ex (ctx, decrypted_data + len, &flen);
1943 g_return_val_if_fail (len + flen == length, FALSE);
1944 return TRUE;
1945 }
1946
1947 static void
gst_hls_demux_stream_decrypt_end(GstHLSDemuxStream * stream)1948 gst_hls_demux_stream_decrypt_end (GstHLSDemuxStream * stream)
1949 {
1950 #if OPENSSL_VERSION_NUMBER < 0x10100000L
1951 EVP_CIPHER_CTX_cleanup (&stream->aes_ctx);
1952 #else
1953 EVP_CIPHER_CTX_free (stream->aes_ctx);
1954 stream->aes_ctx = NULL;
1955 #endif
1956 }
1957
1958 #elif defined(HAVE_NETTLE)
1959 static gboolean
gst_hls_demux_stream_decrypt_start(GstHLSDemuxStream * stream,const guint8 * key_data,const guint8 * iv_data)1960 gst_hls_demux_stream_decrypt_start (GstHLSDemuxStream * stream,
1961 const guint8 * key_data, const guint8 * iv_data)
1962 {
1963 aes128_set_decrypt_key (&stream->aes_ctx.ctx, key_data);
1964 CBC_SET_IV (&stream->aes_ctx, iv_data);
1965
1966 return TRUE;
1967 }
1968
1969 static gboolean
decrypt_fragment(GstHLSDemuxStream * stream,gsize length,const guint8 * encrypted_data,guint8 * decrypted_data)1970 decrypt_fragment (GstHLSDemuxStream * stream, gsize length,
1971 const guint8 * encrypted_data, guint8 * decrypted_data)
1972 {
1973 if (length % 16 != 0)
1974 return FALSE;
1975
1976 CBC_DECRYPT (&stream->aes_ctx, aes128_decrypt, length, decrypted_data,
1977 encrypted_data);
1978
1979 return TRUE;
1980 }
1981
1982 static void
gst_hls_demux_stream_decrypt_end(GstHLSDemuxStream * stream)1983 gst_hls_demux_stream_decrypt_end (GstHLSDemuxStream * stream)
1984 {
1985 /* NOP */
1986 }
1987
1988 #elif defined(HAVE_LIBGCRYPT)
1989 static gboolean
gst_hls_demux_stream_decrypt_start(GstHLSDemuxStream * stream,const guint8 * key_data,const guint8 * iv_data)1990 gst_hls_demux_stream_decrypt_start (GstHLSDemuxStream * stream,
1991 const guint8 * key_data, const guint8 * iv_data)
1992 {
1993 gcry_error_t err = 0;
1994 gboolean ret = FALSE;
1995
1996 err =
1997 gcry_cipher_open (&stream->aes_ctx, GCRY_CIPHER_AES128,
1998 GCRY_CIPHER_MODE_CBC, 0);
1999 if (err)
2000 goto out;
2001 err = gcry_cipher_setkey (stream->aes_ctx, key_data, 16);
2002 if (err)
2003 goto out;
2004 err = gcry_cipher_setiv (stream->aes_ctx, iv_data, 16);
2005 if (!err)
2006 ret = TRUE;
2007
2008 out:
2009 if (!ret)
2010 if (stream->aes_ctx)
2011 gcry_cipher_close (stream->aes_ctx);
2012
2013 return ret;
2014 }
2015
2016 static gboolean
decrypt_fragment(GstHLSDemuxStream * stream,gsize length,const guint8 * encrypted_data,guint8 * decrypted_data)2017 decrypt_fragment (GstHLSDemuxStream * stream, gsize length,
2018 const guint8 * encrypted_data, guint8 * decrypted_data)
2019 {
2020 gcry_error_t err = 0;
2021
2022 err = gcry_cipher_decrypt (stream->aes_ctx, decrypted_data, length,
2023 encrypted_data, length);
2024
2025 return err == 0;
2026 }
2027
2028 static void
gst_hls_demux_stream_decrypt_end(GstHLSDemuxStream * stream)2029 gst_hls_demux_stream_decrypt_end (GstHLSDemuxStream * stream)
2030 {
2031 if (stream->aes_ctx) {
2032 gcry_cipher_close (stream->aes_ctx);
2033 stream->aes_ctx = NULL;
2034 }
2035 }
2036
2037 #else
2038 /* NO crypto available */
2039 static gboolean
gst_hls_demux_stream_decrypt_start(GstHLSDemuxStream * stream,const guint8 * key_data,const guint8 * iv_data)2040 gst_hls_demux_stream_decrypt_start (GstHLSDemuxStream * stream,
2041 const guint8 * key_data, const guint8 * iv_data)
2042 {
2043 GST_ERROR ("No crypto available");
2044 return FALSE;
2045 }
2046
2047 static gboolean
decrypt_fragment(GstHLSDemuxStream * stream,gsize length,const guint8 * encrypted_data,guint8 * decrypted_data)2048 decrypt_fragment (GstHLSDemuxStream * stream, gsize length,
2049 const guint8 * encrypted_data, guint8 * decrypted_data)
2050 {
2051 GST_ERROR ("Cannot decrypt fragment, no crypto available");
2052 return FALSE;
2053 }
2054
2055 static void
gst_hls_demux_stream_decrypt_end(GstHLSDemuxStream * stream)2056 gst_hls_demux_stream_decrypt_end (GstHLSDemuxStream * stream)
2057 {
2058 return;
2059 }
2060 #endif
2061
2062 static GstBuffer *
gst_hls_demux_decrypt_fragment(GstHLSDemux * demux,GstHLSDemuxStream * stream,GstBuffer * encrypted_buffer,GError ** err)2063 gst_hls_demux_decrypt_fragment (GstHLSDemux * demux, GstHLSDemuxStream * stream,
2064 GstBuffer * encrypted_buffer, GError ** err)
2065 {
2066 GstBuffer *decrypted_buffer = NULL;
2067 GstMapInfo encrypted_info, decrypted_info;
2068
2069 decrypted_buffer =
2070 gst_buffer_new_allocate (NULL, gst_buffer_get_size (encrypted_buffer),
2071 NULL);
2072
2073 gst_buffer_map (encrypted_buffer, &encrypted_info, GST_MAP_READ);
2074 gst_buffer_map (decrypted_buffer, &decrypted_info, GST_MAP_WRITE);
2075
2076 if (!decrypt_fragment (stream, encrypted_info.size,
2077 encrypted_info.data, decrypted_info.data))
2078 goto decrypt_error;
2079
2080
2081 gst_buffer_unmap (decrypted_buffer, &decrypted_info);
2082 gst_buffer_unmap (encrypted_buffer, &encrypted_info);
2083
2084 gst_buffer_unref (encrypted_buffer);
2085
2086 return decrypted_buffer;
2087
2088 decrypt_error:
2089 GST_ERROR_OBJECT (demux, "Failed to decrypt fragment");
2090 g_set_error (err, GST_STREAM_ERROR, GST_STREAM_ERROR_DECRYPT,
2091 "Failed to decrypt fragment");
2092
2093 gst_buffer_unmap (decrypted_buffer, &decrypted_info);
2094 gst_buffer_unmap (encrypted_buffer, &encrypted_info);
2095
2096 gst_buffer_unref (encrypted_buffer);
2097 gst_buffer_unref (decrypted_buffer);
2098
2099 return NULL;
2100 }
2101
2102 static gint64
gst_hls_demux_get_manifest_update_interval(GstAdaptiveDemux * demux)2103 gst_hls_demux_get_manifest_update_interval (GstAdaptiveDemux * demux)
2104 {
2105 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
2106 GstClockTime target_duration;
2107
2108 if (hlsdemux->current_variant) {
2109 target_duration =
2110 gst_m3u8_get_target_duration (hlsdemux->current_variant->m3u8);
2111 } else {
2112 target_duration = 5 * GST_SECOND;
2113 }
2114
2115 return gst_util_uint64_scale (target_duration, G_USEC_PER_SEC, GST_SECOND);
2116 }
2117
2118 static gboolean
gst_hls_demux_get_live_seek_range(GstAdaptiveDemux * demux,gint64 * start,gint64 * stop)2119 gst_hls_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
2120 gint64 * stop)
2121 {
2122 GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
2123 gboolean ret = FALSE;
2124
2125 if (hlsdemux->current_variant) {
2126 ret =
2127 gst_m3u8_get_seek_range (hlsdemux->current_variant->m3u8, start, stop);
2128 }
2129
2130 return ret;
2131 }
2132