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