]> git.sesse.net Git - vlc/blob - modules/stream_filter/httplive.c
489a359d0683990f27f5b5d51e7d9b6545725948
[vlc] / modules / stream_filter / httplive.c
1 /*****************************************************************************
2  * httplive.c: HTTP Live Streaming stream filter
3  *****************************************************************************
4  * Copyright (C) 2010-2011 M2X BV
5  * $Id$
6  *
7  * Author: Jean-Paul Saman <jpsaman _AT_ videolan _DOT_ org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <limits.h>
32 #include <errno.h>
33
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36
37 #include <assert.h>
38
39 #include <vlc_threads.h>
40 #include <vlc_arrays.h>
41 #include <vlc_stream.h>
42 #include <vlc_url.h>
43 #include <vlc_memory.h>
44
45 /*****************************************************************************
46  * Module descriptor
47  *****************************************************************************/
48 static int  Open (vlc_object_t *);
49 static void Close(vlc_object_t *);
50
51 vlc_module_begin()
52     set_category(CAT_INPUT)
53     set_subcategory(SUBCAT_INPUT_STREAM_FILTER)
54     set_description(N_("Http Live Streaming stream filter"))
55     set_capability("stream_filter", 20)
56     set_callbacks(Open, Close)
57 vlc_module_end()
58
59 /*****************************************************************************
60  *
61  *****************************************************************************/
62 typedef struct segment_s
63 {
64     int         sequence;   /* unique sequence number */
65     int         duration;   /* segment duration (seconds) */
66     uint64_t    size;       /* segment size in bytes */
67     uint64_t    bandwidth;  /* bandwidth usage of segments (bits per second)*/
68
69     vlc_url_t   url;
70     vlc_mutex_t lock;
71     block_t     *data;      /* data */
72 } segment_t;
73
74 typedef struct hls_stream_s
75 {
76     int         id;         /* program id */
77     int         version;    /* protocol version should be 1 */
78     int         sequence;   /* media sequence number */
79     int         duration;   /* maximum duration per segment (ms) */
80     uint64_t    bandwidth;  /* bandwidth usage of segments (bits per second)*/
81     uint64_t    size;       /* stream length (segment->duration * hls->bandwidth/8) */
82
83     vlc_array_t *segments;  /* list of segments */
84     vlc_url_t   url;        /* uri to m3u8 */
85     vlc_mutex_t lock;
86     bool        b_cache;    /* allow caching */
87 } hls_stream_t;
88
89 struct stream_sys_t
90 {
91     vlc_url_t     m3u8;         /* M3U8 url */
92     vlc_thread_t  reload;       /* HLS m3u8 reload thread */
93     vlc_thread_t  thread;       /* HLS segment download thread */
94
95     block_t      *peeked;
96
97     /* */
98     vlc_array_t  *hls_stream;   /* bandwidth adaptation */
99     uint64_t      bandwidth;    /* measured bandwidth (bits per second) */
100
101     /* Download */
102     struct hls_download_s
103     {
104         int         stream;     /* current hls_stream  */
105         int         segment;    /* current segment for downloading */
106         int         seek;       /* segment requested by seek (default -1) */
107         vlc_mutex_t lock_wait;  /* protect segment download counter */
108         vlc_cond_t  wait;       /* some condition to wait on */
109     } download;
110
111     /* Playback */
112     struct hls_playback_s
113     {
114         uint64_t    offset;     /* current offset in media */
115         int         stream;     /* current hls_stream  */
116         int         segment;    /* current segment for playback */
117     } playback;
118
119     /* Playlist */
120     struct hls_playlist_s
121     {
122         mtime_t     last;       /* playlist last loaded */
123         mtime_t     wakeup;     /* next reload time */
124         int         tries;      /* times it was not changed */
125     } playlist;
126
127     /* state */
128     bool        b_cache;    /* can cache files */
129     bool        b_meta;     /* meta playlist */
130     bool        b_live;     /* live stream? or vod? */
131     bool        b_error;    /* parsing error */
132 };
133
134 /****************************************************************************
135  * Local prototypes
136  ****************************************************************************/
137 static int  Read   (stream_t *, void *p_read, unsigned int i_read);
138 static int  Peek   (stream_t *, const uint8_t **pp_peek, unsigned int i_peek);
139 static int  Control(stream_t *, int i_query, va_list);
140
141 static ssize_t read_M3U8_from_stream(stream_t *s, uint8_t **buffer);
142 static ssize_t read_M3U8_from_url(stream_t *s, vlc_url_t *url, uint8_t **buffer);
143 static char *ReadLine(uint8_t *buffer, uint8_t **pos, size_t len);
144
145 static int hls_Download(stream_t *s, segment_t *segment);
146
147 static void* hls_Thread(void *);
148 static void* hls_Reload(void *);
149
150 static segment_t *segment_GetSegment(hls_stream_t *hls, int wanted);
151 static void segment_Free(segment_t *segment);
152
153 /****************************************************************************
154  *
155  ****************************************************************************/
156 static const char *const ext[] = {
157     "#EXT-X-TARGETDURATION",
158     "#EXT-X-MEDIA-SEQUENCE",
159     "#EXT-X-KEY",
160     "#EXT-X-ALLOW-CACHE",
161     "#EXT-X-ENDLIST",
162     "#EXT-X-STREAM-INF",
163     "#EXT-X-DISCONTINUITY",
164     "#EXT-X-VERSION"
165 };
166
167 static bool isHTTPLiveStreaming(stream_t *s)
168 {
169     const uint8_t *peek, *peek_end;
170
171     int64_t i_size = stream_Peek(s->p_source, &peek, 46);
172     if (i_size < 1)
173         return false;
174
175     if (strncasecmp((const char*)peek, "#EXTM3U", 7) != 0)
176         return false;
177
178     /* Parse stream and search for
179      * EXT-X-TARGETDURATION or EXT-X-STREAM-INF tag, see
180      * http://tools.ietf.org/html/draft-pantos-http-live-streaming-04#page-8 */
181     peek_end = peek + i_size;
182     while(peek <= peek_end)
183     {
184         if (*peek == '#')
185         {
186             for (unsigned int i = 0; i < ARRAY_SIZE(ext); i++)
187             {
188                 char *p = strstr((const char*)peek, ext[i]);
189                 if (p != NULL)
190                     return true;
191             }
192         }
193         peek++;
194     };
195
196     return false;
197 }
198
199 /* HTTP Live Streaming */
200 static hls_stream_t *hls_New(vlc_array_t *hls_stream, const int id, const uint64_t bw, const char *uri)
201 {
202     hls_stream_t *hls = (hls_stream_t *)malloc(sizeof(hls_stream_t));
203     if (hls == NULL) return NULL;
204
205     hls->id = id;
206     hls->bandwidth = bw;
207     hls->duration = -1;/* unknown */
208     hls->size = 0;
209     hls->sequence = 0; /* default is 0 */
210     hls->version = 1;  /* default protocol version */
211     hls->b_cache = true;
212     vlc_UrlParse(&hls->url, uri, 0);
213     hls->segments = vlc_array_new();
214     vlc_array_append(hls_stream, hls);
215     vlc_mutex_init(&hls->lock);
216     return hls;
217 }
218
219 static void hls_Free(hls_stream_t *hls)
220 {
221     vlc_mutex_destroy(&hls->lock);
222
223     if (hls->segments)
224     {
225         for (int n = 0; n < vlc_array_count(hls->segments); n++)
226         {
227             segment_t *segment = (segment_t *)vlc_array_item_at_index(hls->segments, n);
228             if (segment) segment_Free(segment);
229         }
230         vlc_array_destroy(hls->segments);
231     }
232
233     vlc_UrlClean(&hls->url);
234     free(hls);
235     hls = NULL;
236 }
237
238 static hls_stream_t *hls_Get(vlc_array_t *hls_stream, const int wanted)
239 {
240     int count = vlc_array_count(hls_stream);
241     if (count <= 0)
242         return NULL;
243     if ((wanted < 0) || (wanted >= count))
244         return NULL;
245     return (hls_stream_t *) vlc_array_item_at_index(hls_stream, wanted);
246 }
247
248 static inline hls_stream_t *hls_GetFirst(vlc_array_t *hls_stream)
249 {
250     return (hls_stream_t*) hls_Get(hls_stream, 0);
251 }
252
253 static hls_stream_t *hls_GetLast(vlc_array_t *hls_stream)
254 {
255     int count = vlc_array_count(hls_stream);
256     if (count <= 0)
257         return NULL;
258     count--;
259     return (hls_stream_t *) hls_Get(hls_stream, count);
260 }
261
262 static hls_stream_t *hls_Find(vlc_array_t *hls_stream, hls_stream_t *hls_new)
263 {
264     int count = vlc_array_count(hls_stream);
265     for (int n = 0; n < count; n++)
266     {
267         hls_stream_t *hls = vlc_array_item_at_index(hls_stream, n);
268         if (hls)
269         {
270             /* compare */
271             if ((hls->id == hls_new->id) &&
272                 (hls->bandwidth == hls_new->bandwidth))
273                 return hls;
274         }
275     }
276     return NULL;
277 }
278
279 static uint64_t hls_GetStreamSize(hls_stream_t *hls)
280 {
281     /* NOTE: Stream size is calculated based on segment duration and
282      * HLS stream bandwidth from the .m3u8 file. If these are not correct
283      * then the deviation from exact byte size will be big and the seek/
284      * progressbar will not behave entirely as one expects. */
285     uint64_t size = 0UL;
286     int count = vlc_array_count(hls->segments);
287     for (int n = 0; n < count; n++)
288     {
289         segment_t *segment = segment_GetSegment(hls, n);
290         if (segment)
291         {
292             size += (segment->duration * (hls->bandwidth / 8));
293         }
294     }
295     return size;
296 }
297
298 /* Segment */
299 static segment_t *segment_New(hls_stream_t* hls, const int duration, const char *uri)
300 {
301     segment_t *segment = (segment_t *)malloc(sizeof(segment_t));
302     if (segment == NULL)
303         return NULL;
304
305     segment->duration = duration; /* seconds */
306     segment->size = 0; /* bytes */
307     segment->sequence = 0;
308     segment->bandwidth = 0;
309     vlc_UrlParse(&segment->url, uri, 0);
310     segment->data = NULL;
311     vlc_array_append(hls->segments, segment);
312     vlc_mutex_init(&segment->lock);
313     return segment;
314 }
315
316 static void segment_Free(segment_t *segment)
317 {
318     vlc_mutex_destroy(&segment->lock);
319
320     vlc_UrlClean(&segment->url);
321     if (segment->data)
322         block_Release(segment->data);
323     free(segment);
324     segment = NULL;
325 }
326
327 static segment_t *segment_GetSegment(hls_stream_t *hls, const int wanted)
328 {
329     assert(hls);
330
331     int count = vlc_array_count(hls->segments);
332     if (count <= 0)
333         return NULL;
334     if ((wanted < 0) || (wanted >= count))
335         return NULL;
336     return (segment_t *) vlc_array_item_at_index(hls->segments, wanted);
337 }
338
339 static segment_t *segment_Find(hls_stream_t *hls, const int sequence)
340 {
341     assert(hls);
342
343     int count = vlc_array_count(hls->segments);
344     if (count <= 0) return NULL;
345     for (int n = 0; n < count; n++)
346     {
347         segment_t *segment = vlc_array_item_at_index(hls->segments, n);
348         if (segment == NULL) break;
349         if (segment->sequence == sequence)
350             return segment;
351     }
352     return NULL;
353 }
354
355 static int ChooseSegment(stream_t *s, const int current)
356 {
357     stream_sys_t *p_sys = (stream_sys_t *)s->p_sys;
358     hls_stream_t *hls = hls_Get(p_sys->hls_stream, current);
359     if (hls == NULL) return 0;
360
361     /* Choose a segment to start which is no closer than
362      * 3 times the target duration from the end of the playlist.
363      */
364     int wanted = 0;
365     int duration = 0;
366     int sequence = 0;
367     int count = vlc_array_count(hls->segments);
368     int i = p_sys->b_live ? count - 1 : 0;
369
370     while((i >= 0) && (i < count) && vlc_object_alive(s))
371     {
372         segment_t *segment = segment_GetSegment(hls, i);
373         assert(segment);
374
375         if (segment->duration > hls->duration)
376         {
377             msg_Err(s, "EXTINF:%d duration is larger than EXT-X-TARGETDURATION:%d",
378                     segment->duration, hls->duration);
379         }
380
381         duration += segment->duration;
382         if (duration >= 3 * hls->duration)
383         {
384             /* Start point found */
385             wanted = p_sys->b_live ? i : 0;
386             sequence = segment->sequence;
387             break;
388         }
389
390         if (p_sys->b_live)
391             i-- ;
392         else
393           i++;
394     }
395
396     msg_Info(s, "Choose segment %d/%d (sequence=%d)", wanted, count, sequence);
397     return wanted;
398 }
399
400 /* Parsing */
401 static char *parse_Attributes(const char *line, const char *attr)
402 {
403     char *p;
404     char *begin = (char *) line;
405     char *end = begin + strlen(line);
406
407     /* Find start of attributes */
408     if ((p = strchr(begin, ':' )) == NULL)
409         return NULL;
410
411     begin = p;
412     do
413     {
414         if (strncasecmp(begin, attr, strlen(attr)) == 0)
415         {
416             /* <attr>=<value>[,]* */
417             p = strchr(begin, ',');
418             begin += strlen(attr) + 1;
419             if (begin >= end)
420                 return NULL;
421             if (p == NULL) /* last attribute */
422                 return strndup(begin, end - begin);
423             /* copy till ',' */
424             return strndup(begin, p - begin);
425         }
426         begin++;
427     } while(begin < end);
428
429     return NULL;
430 }
431
432 static char *relative_URI(stream_t *s, const char *uri, const char *path)
433 {
434     stream_sys_t *p_sys = s->p_sys;
435
436     char *p = strchr(uri, ':');
437     if (p != NULL)
438         return NULL;
439
440     if (p_sys->m3u8.psz_path == NULL)
441         return NULL;
442
443     char *psz_path = strdup(p_sys->m3u8.psz_path);
444     if (psz_path == NULL) return NULL;
445     p = strrchr(psz_path, '/');
446     if (p) *p = '\0';
447
448     char *psz_uri = NULL;
449     if (p_sys->m3u8.psz_password || p_sys->m3u8.psz_username)
450     {
451         if (asprintf(&psz_uri, "%s://%s:%s@%s:%d%s/%s", p_sys->m3u8.psz_protocol,
452                      p_sys->m3u8.psz_username, p_sys->m3u8.psz_password,
453                      p_sys->m3u8.psz_host, p_sys->m3u8.i_port,
454                      path ? path : psz_path, uri) < 0)
455             goto fail;
456     }
457     else
458     {
459         if (asprintf(&psz_uri, "%s://%s:%d%s/%s", p_sys->m3u8.psz_protocol,
460                      p_sys->m3u8.psz_host, p_sys->m3u8.i_port,
461                      path ? path : psz_path, uri) < 0)
462            goto fail;
463     }
464     free(psz_path);
465     return psz_uri;
466
467 fail:
468     free(psz_path);
469     return NULL;
470 }
471
472 static char *ConstructUrl(vlc_url_t *url)
473 {
474     if ((url->psz_protocol == NULL) ||
475         (url->psz_path == NULL))
476         return NULL;
477
478     if (url->i_port <= 0)
479     {
480         if (strncmp(url->psz_protocol, "https", 5) == 0)
481             url->i_port = 443;
482         else
483             url->i_port = 80;
484     }
485
486     char *psz_url = NULL;
487     if (url->psz_password || url->psz_username)
488     {
489         if (asprintf(&psz_url, "%s://%s:%s@%s:%d%s",
490                      url->psz_protocol,
491                      url->psz_username, url->psz_password,
492                      url->psz_host, url->i_port, url->psz_path) < 0)
493             return NULL;
494     }
495     else
496     {
497         if (asprintf(&psz_url, "%s://%s:%d%s",
498                      url->psz_protocol,
499                      url->psz_host, url->i_port, url->psz_path) < 0)
500             return NULL;
501     }
502
503     return psz_url;
504 }
505
506 static int parse_SegmentInformation(hls_stream_t *hls, char *p_read, int *duration)
507 {
508     assert(hls);
509     assert(p_read);
510
511     /* strip of #EXTINF: */
512     char *p_next = NULL;
513     char *token = strtok_r(p_read, ":", &p_next);
514     if (token == NULL)
515         return VLC_EGENERIC;
516
517     /* read duration */
518     token = strtok_r(NULL, ",", &p_next);
519     if (token == NULL)
520         return VLC_EGENERIC;
521
522     int value;
523     if (hls->version < 3)
524     {
525        value = strtol(token, NULL, 10);
526        if (errno == ERANGE)
527        {
528            *duration = -1;
529            return VLC_EGENERIC;
530        }
531        *duration = value;
532     }
533     else
534     {
535         double d = strtod(token, (char **) NULL);
536         if (errno == ERANGE)
537         {
538             *duration = -1;
539             return VLC_EGENERIC;
540         }
541         if ((d) - ((int)d) >= 0.5)
542             value = ((int)d) + 1;
543         else
544             value = ((int)d);
545     }
546
547     /* Ignore the rest of the line */
548
549     return VLC_SUCCESS;
550 }
551
552 static int parse_AddSegment(stream_t *s, hls_stream_t *hls, const int duration, const char *uri)
553 {
554     assert(hls);
555     assert(uri);
556
557     /* Store segment information */
558     char *psz_path = NULL;
559     if (hls->url.psz_path != NULL)
560     {
561         psz_path = strdup(hls->url.psz_path);
562         if (psz_path == NULL)
563             return VLC_ENOMEM;
564         char *p = strrchr(psz_path, '/');
565         if (p) *p = '\0';
566     }
567     char *psz_uri = relative_URI(s, uri, psz_path);
568     free(psz_path);
569
570     vlc_mutex_lock(&hls->lock);
571     segment_t *segment = segment_New(hls, duration, psz_uri ? psz_uri : uri);
572     if (segment)
573         segment->sequence = hls->sequence + vlc_array_count(hls->segments) - 1;
574     vlc_mutex_unlock(&hls->lock);
575
576     free(psz_uri);
577     return segment ? VLC_SUCCESS : VLC_ENOMEM;
578 }
579
580 static int parse_TargetDuration(stream_t *s, hls_stream_t *hls, char *p_read)
581 {
582     assert(hls);
583
584     int duration = -1;
585     int ret = sscanf(p_read, "#EXT-X-TARGETDURATION:%d", &duration);
586     if (ret != 1)
587     {
588         msg_Err(s, "expected #EXT-X-TARGETDURATION:<s>");
589         return VLC_EGENERIC;
590     }
591
592     hls->duration = duration; /* seconds */
593     return VLC_SUCCESS;
594 }
595
596 static int parse_StreamInformation(stream_t *s, vlc_array_t **hls_stream,
597                                    hls_stream_t **hls, char *p_read, const char *uri)
598 {
599     int id;
600     uint64_t bw;
601     char *attr;
602
603     assert(*hls == NULL);
604
605     attr = parse_Attributes(p_read, "PROGRAM-ID");
606     if (attr == NULL)
607     {
608         msg_Err(s, "#EXT-X-STREAM-INF: expected PROGRAM-ID=<value>");
609         return VLC_EGENERIC;
610     }
611     id = atol(attr);
612     free(attr);
613
614     attr = parse_Attributes(p_read, "BANDWIDTH");
615     if (attr == NULL)
616     {
617         msg_Err(s, "#EXT-X-STREAM-INF: expected BANDWIDTH=<value>");
618         return VLC_EGENERIC;
619     }
620     bw = atoll(attr);
621     free(attr);
622
623     if (bw == 0)
624     {
625         msg_Err(s, "#EXT-X-STREAM-INF: bandwidth cannot be 0");
626         return VLC_EGENERIC;
627     }
628
629     msg_Info(s, "bandwidth adaptation detected (program-id=%d, bandwidth=%"PRIu64").", id, bw);
630
631     char *psz_uri = relative_URI(s, uri, NULL);
632
633     *hls = hls_New(*hls_stream, id, bw, psz_uri ? psz_uri : uri);
634
635     free(psz_uri);
636
637     return (*hls == NULL) ? VLC_ENOMEM : VLC_SUCCESS;
638 }
639
640 static int parse_MediaSequence(stream_t *s, hls_stream_t *hls, char *p_read)
641 {
642     assert(hls);
643
644     int sequence;
645     int ret = sscanf(p_read, "#EXT-X-MEDIA-SEQUENCE:%d", &sequence);
646     if (ret != 1)
647     {
648         msg_Err(s, "expected #EXT-X-MEDIA-SEQUENCE:<s>");
649         return VLC_EGENERIC;
650     }
651
652     if (hls->sequence > 0)
653         msg_Err(s, "EXT-X-MEDIA-SEQUENCE already present in playlist (new=%d, old=%d)",
654                     sequence, hls->sequence);
655
656     hls->sequence = sequence;
657     return VLC_SUCCESS;
658 }
659
660 static int parse_Key(stream_t *s, hls_stream_t *hls, char *p_read)
661 {
662     assert(hls);
663
664     /* #EXT-X-KEY:METHOD=<method>[,URI="<URI>"][,IV=<IV>] */
665     int err = VLC_SUCCESS;
666     char *attr = parse_Attributes(p_read, "METHOD");
667     if (attr == NULL)
668     {
669         msg_Err(s, "#EXT-X-KEY: expected METHOD=<value>");
670         return err;
671     }
672
673     if (strncasecmp(attr, "NONE", 4) == 0)
674     {
675
676         char *uri = parse_Attributes(p_read, "URI");
677         if (uri != NULL)
678         {
679             msg_Err(s, "#EXT-X-KEY: URI not expected");
680             err = VLC_EGENERIC;
681         }
682         free(uri);
683         /* IV is only supported in version 2 and above */
684         if (hls->version >= 2)
685         {
686             char *iv = parse_Attributes(p_read, "IV");
687             if (iv != NULL)
688             {
689                 msg_Err(s, "#EXT-X-KEY: IV not expected");
690                 err = VLC_EGENERIC;
691             }
692             free(iv);
693         }
694     }
695     else
696     {
697         msg_Warn(s, "playback of encrypted HTTP Live media is not supported.");
698         err = VLC_EGENERIC;
699     }
700     free(attr);
701     return err;
702 }
703
704 static int parse_ProgramDateTime(stream_t *s, hls_stream_t *hls, char *p_read)
705 {
706     VLC_UNUSED(hls);
707     msg_Dbg(s, "tag not supported: #EXT-X-PROGRAM-DATE-TIME %s", p_read);
708     return VLC_SUCCESS;
709 }
710
711 static int parse_AllowCache(stream_t *s, hls_stream_t *hls, char *p_read)
712 {
713     assert(hls);
714
715     char answer[4] = "\0";
716     int ret = sscanf(p_read, "#EXT-X-ALLOW-CACHE:%3s", answer);
717     if (ret != 1)
718     {
719         msg_Err(s, "#EXT-X-ALLOW-CACHE, ignoring ...");
720         return VLC_EGENERIC;
721     }
722
723     hls->b_cache = (strncmp(answer, "NO", 2) != 0);
724     return VLC_SUCCESS;
725 }
726
727 static int parse_Version(stream_t *s, hls_stream_t *hls, char *p_read)
728 {
729     assert(hls);
730
731     int version;
732     int ret = sscanf(p_read, "#EXT-X-VERSION:%d", &version);
733     if (ret != 1)
734     {
735         msg_Err(s, "#EXT-X-VERSION: no protocol version found, should be version 1.");
736         return VLC_EGENERIC;
737     }
738
739     /* Check version */
740     hls->version = version;
741     if (hls->version != 1)
742     {
743         msg_Err(s, "#EXT-X-VERSION should be version 1 iso %d", version);
744         return VLC_EGENERIC;
745     }
746     return VLC_SUCCESS;
747 }
748
749 static int parse_EndList(stream_t *s, hls_stream_t *hls)
750 {
751     assert(hls);
752
753     s->p_sys->b_live = false;
754     msg_Info(s, "video on demand (vod) mode");
755     return VLC_SUCCESS;
756 }
757
758 static int parse_Discontinuity(stream_t *s, hls_stream_t *hls, char *p_read)
759 {
760     assert(hls);
761
762     /* FIXME: Do we need to act on discontinuity ?? */
763     msg_Dbg(s, "#EXT-X-DISCONTINUITY %s", p_read);
764     return VLC_SUCCESS;
765 }
766
767 /* The http://tools.ietf.org/html/draft-pantos-http-live-streaming-04#page-8
768  * document defines the following new tags: EXT-X-TARGETDURATION,
769  * EXT-X-MEDIA-SEQUENCE, EXT-X-KEY, EXT-X-PROGRAM-DATE-TIME, EXT-X-
770  * ALLOW-CACHE, EXT-X-STREAM-INF, EXT-X-ENDLIST, EXT-X-DISCONTINUITY,
771  * and EXT-X-VERSION.
772  */
773 static int parse_M3U8(stream_t *s, vlc_array_t *streams, uint8_t *buffer, const ssize_t len)
774 {
775     stream_sys_t *p_sys = s->p_sys;
776     uint8_t *p_read, *p_begin, *p_end;
777
778     assert(streams);
779     assert(buffer);
780
781     msg_Dbg(s, "parse_M3U8\n%s", buffer);
782     p_begin = buffer;
783     p_end = p_begin + len;
784
785     char *line = ReadLine(p_begin, &p_read, p_end - p_begin);
786     if (line == NULL)
787         return VLC_ENOMEM;
788     p_begin = p_read;
789
790     if (strncmp(line, "#EXTM3U", 7) != 0)
791     {
792         msg_Err(s, "missing #EXTM3U tag .. aborting");
793         free(line);
794         return VLC_EGENERIC;
795     }
796
797     free(line);
798     line = NULL;
799
800     /* What is the version ? */
801     int version = 1;
802     uint8_t *p = (uint8_t *)strstr((const char *)buffer, "#EXT-X-VERSION:");
803     if (p != NULL)
804     {
805         uint8_t *tmp = NULL;
806         char *psz_version = ReadLine(p, &tmp, p_end - p);
807         if (psz_version == NULL)
808             return VLC_ENOMEM;
809         int ret = sscanf((const char*)psz_version, "#EXT-X-VERSION:%d", &version);
810         if (ret != 1)
811         {
812             msg_Warn(s, "#EXT-X-VERSION: no protocol version found, assuming version 1.");
813             version = 1;
814         }
815         free(psz_version);
816         p = NULL;
817     }
818
819     /* Is it a live stream ? */
820     p_sys->b_live = (strstr((const char *)buffer, "#EXT-X-ENDLIST") == NULL) ? true : false;
821
822     /* Is it a meta index file ? */
823     bool b_meta = (strstr((const char *)buffer, "#EXT-X-STREAM-INF") == NULL) ? false : true;
824
825     int err = VLC_SUCCESS;
826
827     if (b_meta)
828     {
829         msg_Info(s, "Meta playlist");
830
831         /* M3U8 Meta Index file */
832         do {
833             /* Next line */
834             line = ReadLine(p_begin, &p_read, p_end - p_begin);
835             if (line == NULL)
836                 break;
837             p_begin = p_read;
838
839             /* */
840             if (strncmp(line, "#EXT-X-STREAM-INF", 17) == 0)
841             {
842                 p_sys->b_meta = true;
843                 char *uri = ReadLine(p_begin, &p_read, p_end - p_begin);
844                 if (uri == NULL)
845                     err = VLC_ENOMEM;
846                 else
847                 {
848                     hls_stream_t *hls = NULL;
849                     err = parse_StreamInformation(s, &streams, &hls, line, uri);
850                     free(uri);
851
852                     /* Download playlist file from server */
853                     uint8_t *buf = NULL;
854                     ssize_t len = read_M3U8_from_url(s, &hls->url, &buf);
855                     if (len < 0)
856                         err = VLC_EGENERIC;
857                     else
858                     {
859                         /* Parse HLS m3u8 content. */
860                         err = parse_M3U8(s, streams, buf, len);
861                         free(buf);
862                     }
863
864                     if (hls)
865                     {
866                         hls->version = version;
867                         if (!p_sys->b_live)
868                             hls->size = hls_GetStreamSize(hls); /* Stream size (approximate) */
869                     }
870                 }
871                 p_begin = p_read;
872             }
873
874             free(line);
875             line = NULL;
876
877             if (p_begin >= p_end)
878                 break;
879
880         } while ((err == VLC_SUCCESS) && vlc_object_alive(s));
881
882     }
883     else
884     {
885         msg_Info(s, "%s Playlist HLS protocol version: %d", p_sys->b_live ? "Live": "VOD", version);
886
887         hls_stream_t *hls = NULL;
888         if (p_sys->b_meta)
889             hls = hls_GetLast(streams);
890         else
891         {
892             /* No Meta playlist used */
893             hls = hls_New(streams, 0, -1, NULL);
894             if (hls)
895             {
896                 /* Get TARGET-DURATION first */
897                 p = (uint8_t *)strstr((const char *)buffer, "#EXT-X-TARGETDURATION:");
898                 if (p)
899                 {
900                     uint8_t *p_rest = NULL;
901                     char *psz_duration = ReadLine(p, &p_rest,  p_end - p);
902                     if (psz_duration == NULL)
903                         return VLC_EGENERIC;
904                     err = parse_TargetDuration(s, hls, psz_duration);
905                     free(psz_duration);
906                     p = NULL;
907                 }
908
909                 /* Store version */
910                 hls->version = version;
911             }
912             else return VLC_ENOMEM;
913         }
914         assert(hls);
915
916         /* */
917         int segment_duration = -1;
918         do
919         {
920             /* Next line */
921             line = ReadLine(p_begin, &p_read, p_end - p_begin);
922             if (line == NULL)
923                 break;
924             p_begin = p_read;
925
926             if (strncmp(line, "#EXTINF", 7) == 0)
927                 err = parse_SegmentInformation(hls, line, &segment_duration);
928             else if (strncmp(line, "#EXT-X-TARGETDURATION", 21) == 0)
929                 err = parse_TargetDuration(s, hls, line);
930             else if (strncmp(line, "#EXT-X-MEDIA-SEQUENCE", 21) == 0)
931                 err = parse_MediaSequence(s, hls, line);
932             else if (strncmp(line, "#EXT-X-KEY", 10) == 0)
933                 err = parse_Key(s, hls, line);
934             else if (strncmp(line, "#EXT-X-PROGRAM-DATE-TIME", 24) == 0)
935                 err = parse_ProgramDateTime(s, hls, line);
936             else if (strncmp(line, "#EXT-X-ALLOW-CACHE", 18) == 0)
937                 err = parse_AllowCache(s, hls, line);
938             else if (strncmp(line, "#EXT-X-DISCONTINUITY", 20) == 0)
939                 err = parse_Discontinuity(s, hls, line);
940             else if (strncmp(line, "#EXT-X-VERSION", 14) == 0)
941                 err = parse_Version(s, hls, line);
942             else if (strncmp(line, "#EXT-X-ENDLIST", 14) == 0)
943                 err = parse_EndList(s, hls);
944             else if ((strncmp(line, "#", 1) != 0) && (*line != '\0') )
945             {
946                 err = parse_AddSegment(s, hls, segment_duration, line);
947                 segment_duration = -1; /* reset duration */
948             }
949
950             free(line);
951             line = NULL;
952
953             if (p_begin >= p_end)
954                 break;
955
956         } while ((err == VLC_SUCCESS) && vlc_object_alive(s));
957
958         free(line);
959     }
960
961     return err;
962 }
963
964 static int get_HTTPLiveMetaPlaylist(stream_t *s, vlc_array_t **streams)
965 {
966     stream_sys_t *p_sys = s->p_sys;
967     assert(*streams);
968
969     /* Download new playlist file from server */
970     uint8_t *buffer = NULL;
971     ssize_t len = read_M3U8_from_url(s, &p_sys->m3u8, &buffer);
972     if (len < 0)
973         return VLC_EGENERIC;
974
975     /* Parse HLS m3u8 content. */
976     int err = parse_M3U8(s, *streams, buffer, len);
977     free(buffer);
978
979     return err;
980 }
981
982 /* Reload playlist */
983 static int hls_UpdatePlaylist(stream_t *s, hls_stream_t *hls_new, hls_stream_t **hls)
984 {
985     int count = vlc_array_count(hls_new->segments);
986
987     msg_Info(s, "updating hls stream (program-id=%d, bandwidth=%"PRIu64") has %d segments",
988              hls_new->id, hls_new->bandwidth, count);
989     for (int n = 0; n < count; n++)
990     {
991         segment_t *p = segment_GetSegment(hls_new, n);
992         if (p == NULL) return VLC_EGENERIC;
993
994         vlc_mutex_lock(&(*hls)->lock);
995         segment_t *segment = segment_Find(*hls, p->sequence);
996         if (segment)
997         {
998             /* they should be the same */
999             if ((p->sequence != segment->sequence) ||
1000                 (p->duration != segment->duration) ||
1001                 (strcmp(p->url.psz_path, segment->url.psz_path) != 0))
1002             {
1003                 msg_Err(s, "existing segment found with different content - resetting");
1004                 msg_Err(s, "- sequence: new=%d, old=%d", p->sequence, segment->sequence);
1005                 msg_Err(s, "- duration: new=%d, old=%d", p->duration, segment->duration);
1006                 msg_Err(s, "- file: new=%s", p->url.psz_path);
1007                 msg_Err(s, "        old=%s", segment->url.psz_path);
1008
1009                 /* Resetting content */
1010                 segment->sequence = p->sequence;
1011                 segment->duration = p->duration;
1012                 vlc_UrlClean(&segment->url);
1013                 vlc_UrlParse(&segment->url, p->url.psz_buffer, 0);
1014                 segment_Free(p);
1015             }
1016         }
1017         else
1018         {
1019             int last = vlc_array_count((*hls)->segments) - 1;
1020             segment_t *l = segment_GetSegment(*hls, last);
1021             if (l == NULL) goto fail_and_unlock;
1022
1023             if ((l->sequence + 1) != p->sequence)
1024             {
1025                 msg_Err(s, "gap in sequence numbers found: new=%d expected %d",
1026                         p->sequence, l->sequence+1);
1027             }
1028             vlc_array_append((*hls)->segments, p);
1029             msg_Info(s, "- segment %d appended", p->sequence);
1030         }
1031         vlc_mutex_unlock(&(*hls)->lock);
1032     }
1033     return VLC_SUCCESS;
1034
1035 fail_and_unlock:
1036     vlc_mutex_unlock(&(*hls)->lock);
1037     return VLC_EGENERIC;
1038 }
1039
1040 static int hls_ReloadPlaylist(stream_t *s)
1041 {
1042     stream_sys_t *p_sys = s->p_sys;
1043
1044     vlc_array_t *hls_streams = vlc_array_new();
1045     if (hls_streams == NULL)
1046         return VLC_ENOMEM;
1047
1048     msg_Info(s, "Reloading HLS live meta playlist");
1049
1050     if (get_HTTPLiveMetaPlaylist(s, &hls_streams) != VLC_SUCCESS)
1051     {
1052         /* Free hls streams */
1053         for (int i = 0; i < vlc_array_count(hls_streams); i++)
1054         {
1055             hls_stream_t *hls;
1056             hls = (hls_stream_t *)vlc_array_item_at_index(hls_streams, i);
1057             if (hls) hls_Free(hls);
1058         }
1059         vlc_array_destroy(hls_streams);
1060
1061         msg_Err(s, "reloading playlist failed");
1062         return VLC_EGENERIC;
1063     }
1064
1065     /* merge playlists */
1066     int count = vlc_array_count(hls_streams);
1067     for (int n = 0; n < count; n++)
1068     {
1069         hls_stream_t *hls_new = hls_Get(hls_streams, n);
1070         if (hls_new == NULL)
1071             continue;
1072
1073         hls_stream_t *hls_old = hls_Find(p_sys->hls_stream, hls_new);
1074         if (hls_old == NULL)
1075         {   /* new hls stream - append */
1076             vlc_array_append(p_sys->hls_stream, hls_new);
1077             msg_Info(s, "new HLS stream appended (id=%d, bandwidth=%"PRIu64")",
1078                      hls_new->id, hls_new->bandwidth);
1079         }
1080         else if (hls_UpdatePlaylist(s, hls_new, &hls_old) != VLC_SUCCESS)
1081             msg_Info(s, "failed updating HLS stream (id=%d, bandwidth=%"PRIu64")",
1082                      hls_new->id, hls_new->bandwidth);
1083     }
1084
1085     vlc_array_destroy(hls_streams);
1086     return VLC_SUCCESS;
1087 }
1088
1089 /****************************************************************************
1090  * hls_Thread
1091  ****************************************************************************/
1092 static int BandwidthAdaptation(stream_t *s, int progid, uint64_t *bandwidth)
1093 {
1094     stream_sys_t *p_sys = s->p_sys;
1095     int candidate = -1;
1096     uint64_t bw = *bandwidth;
1097     uint64_t bw_candidate = 0;
1098
1099     int count = vlc_array_count(p_sys->hls_stream);
1100     for (int n = 0; n < count; n++)
1101     {
1102         /* Select best bandwidth match */
1103         hls_stream_t *hls = hls_Get(p_sys->hls_stream, n);
1104         if (hls == NULL) break;
1105
1106         /* only consider streams with the same PROGRAM-ID */
1107         if (hls->id == progid)
1108         {
1109             if ((bw >= hls->bandwidth) && (bw_candidate < hls->bandwidth))
1110             {
1111                 msg_Dbg(s, "candidate %d bandwidth (bits/s) %"PRIu64" >= %"PRIu64,
1112                          n, bw, hls->bandwidth); /* bits / s */
1113                 bw_candidate = hls->bandwidth;
1114                 candidate = n; /* possible candidate */
1115             }
1116         }
1117     }
1118     *bandwidth = bw_candidate;
1119     return candidate;
1120 }
1121
1122 static int Download(stream_t *s, hls_stream_t *hls, segment_t *segment, int *cur_stream)
1123 {
1124     stream_sys_t *p_sys = s->p_sys;
1125
1126     assert(hls);
1127     assert(segment);
1128
1129     vlc_mutex_lock(&segment->lock);
1130     if (segment->data != NULL)
1131     {
1132         /* Segment already downloaded */
1133         vlc_mutex_unlock(&segment->lock);
1134         return VLC_SUCCESS;
1135     }
1136
1137     /* sanity check - can we download this segment on time? */
1138     if ((p_sys->bandwidth > 0) && (hls->bandwidth > 0))
1139     {
1140         uint64_t size = (segment->duration * hls->bandwidth); /* bits */
1141         int estimated = (int)(size / p_sys->bandwidth);
1142         if (estimated > segment->duration)
1143         {
1144             msg_Warn(s,"downloading of segment %d takes %ds, which is longer than its playback (%ds)",
1145                         segment->sequence, estimated, segment->duration);
1146         }
1147     }
1148
1149     mtime_t start = mdate();
1150     if (hls_Download(s, segment) != VLC_SUCCESS)
1151     {
1152         vlc_mutex_unlock(&segment->lock);
1153         return VLC_EGENERIC;
1154     }
1155     mtime_t duration = mdate() - start;
1156
1157     vlc_mutex_unlock(&segment->lock);
1158
1159     msg_Info(s, "downloaded segment %d from stream %d",
1160                 segment->sequence, *cur_stream);
1161
1162     /* check for division by zero */
1163     double ms = (double)duration / 1000.0; /* ms */
1164     if (ms <= 0.0)
1165         return VLC_SUCCESS;
1166
1167     uint64_t bw = ((double)(segment->size * 8) / ms) * 1000; /* bits / s */
1168     p_sys->bandwidth = bw;
1169     if (p_sys->b_meta && (hls->bandwidth != bw))
1170     {
1171         int newstream = BandwidthAdaptation(s, hls->id, &bw);
1172
1173         /* FIXME: we need an average here */
1174         if ((newstream >= 0) && (newstream != *cur_stream))
1175         {
1176             msg_Info(s, "detected %s bandwidth (%"PRIu64") stream",
1177                      (bw >= hls->bandwidth) ? "faster" : "lower", bw);
1178             *cur_stream = newstream;
1179         }
1180     }
1181     return VLC_SUCCESS;
1182 }
1183
1184 static void* hls_Thread(void *p_this)
1185 {
1186     stream_t *s = (stream_t *)p_this;
1187     stream_sys_t *p_sys = s->p_sys;
1188
1189     int canc = vlc_savecancel();
1190
1191     while (vlc_object_alive(s))
1192     {
1193         hls_stream_t *hls = hls_Get(p_sys->hls_stream, p_sys->download.stream);
1194         assert(hls);
1195
1196         /* Sliding window (~60 seconds worth of movie) */
1197         vlc_mutex_lock(&hls->lock);
1198         int count = vlc_array_count(hls->segments);
1199         vlc_mutex_unlock(&hls->lock);
1200
1201         /* Is there a new segment to process? */
1202         if ((!p_sys->b_live && (p_sys->playback.segment < (count - 6))) ||
1203             (p_sys->download.segment >= count))
1204         {
1205             /* wait */
1206             vlc_mutex_lock(&p_sys->download.lock_wait);
1207             while (((p_sys->download.segment - p_sys->playback.segment > 6) ||
1208                     (p_sys->download.segment >= count)) &&
1209                    (p_sys->download.seek == -1))
1210             {
1211                 vlc_cond_wait(&p_sys->download.wait, &p_sys->download.lock_wait);
1212                 if (p_sys->b_live /*&& (mdate() >= p_sys->playlist.wakeup)*/)
1213                     break;
1214                 if (!vlc_object_alive(s))
1215                     break;
1216             }
1217             /* */
1218             if (p_sys->download.seek >= 0)
1219             {
1220                 p_sys->download.segment = p_sys->download.seek;
1221                 p_sys->download.seek = -1;
1222             }
1223             vlc_mutex_unlock(&p_sys->download.lock_wait);
1224         }
1225
1226         if (!vlc_object_alive(s)) break;
1227
1228         vlc_mutex_lock(&hls->lock);
1229         segment_t *segment = segment_GetSegment(hls, p_sys->download.segment);
1230         vlc_mutex_unlock(&hls->lock);
1231
1232         if ((segment != NULL) &&
1233             (Download(s, hls, segment, &p_sys->download.stream) != VLC_SUCCESS))
1234         {
1235             if (!vlc_object_alive(s)) break;
1236
1237             if (!p_sys->b_live)
1238             {
1239                 p_sys->b_error = true;
1240                 break;
1241             }
1242         }
1243
1244         /* download succeeded */
1245         /* determine next segment to download */
1246         vlc_mutex_lock(&p_sys->download.lock_wait);
1247         if (p_sys->download.seek >= 0)
1248         {
1249             p_sys->download.segment = p_sys->download.seek;
1250             p_sys->download.seek = -1;
1251         }
1252         else if (p_sys->download.segment < count)
1253             p_sys->download.segment++;
1254         vlc_cond_signal(&p_sys->download.wait);
1255         vlc_mutex_unlock(&p_sys->download.lock_wait);
1256     }
1257
1258     vlc_restorecancel(canc);
1259     return NULL;
1260 }
1261
1262 static void* hls_Reload(void *p_this)
1263 {
1264     stream_t *s = (stream_t *)p_this;
1265     stream_sys_t *p_sys = s->p_sys;
1266
1267     assert(p_sys->b_live);
1268
1269     int canc = vlc_savecancel();
1270
1271     while (vlc_object_alive(s))
1272     {
1273         double wait = 1;
1274         mtime_t now = mdate();
1275         if (now >= p_sys->playlist.wakeup)
1276         {
1277             /* reload the m3u8 */
1278             if (hls_ReloadPlaylist(s) != VLC_SUCCESS)
1279             {
1280                 /* No change in playlist, then backoff */
1281                 p_sys->playlist.tries++;
1282                 if (p_sys->playlist.tries == 1) wait = 0.5;
1283                 else if (p_sys->playlist.tries == 2) wait = 1;
1284                 else if (p_sys->playlist.tries >= 3) wait = 3;
1285             }
1286             else p_sys->playlist.tries = 0;
1287
1288             hls_stream_t *hls = hls_Get(p_sys->hls_stream, p_sys->download.stream);
1289             assert(hls);
1290
1291             /* determine next time to update playlist */
1292             p_sys->playlist.last = now;
1293             p_sys->playlist.wakeup = now + ((mtime_t)(hls->duration * wait)
1294                                                    * (mtime_t)1000000);
1295         }
1296
1297         mwait(p_sys->playlist.wakeup);
1298     }
1299
1300     vlc_restorecancel(canc);
1301     return NULL;
1302 }
1303
1304 static int Prefetch(stream_t *s, int *current)
1305 {
1306     stream_sys_t *p_sys = s->p_sys;
1307     int stream;
1308
1309     /* Try to pick best matching stream */;
1310 again:
1311     stream = *current;
1312
1313     hls_stream_t *hls = hls_Get(p_sys->hls_stream, *current);
1314     if (hls == NULL)
1315         return VLC_EGENERIC;
1316
1317     segment_t *segment = segment_GetSegment(hls, p_sys->download.segment);
1318     if (segment == NULL )
1319         return VLC_EGENERIC;
1320
1321     if (Download(s, hls, segment, current) != VLC_SUCCESS)
1322         return VLC_EGENERIC;
1323
1324     /* Found better bandwidth match, try again */
1325     if (*current != stream)
1326         goto again;
1327
1328     /* Download first 2 segments of this HLS stream */
1329     stream = *current;
1330     for (int i = 0; i < 2; i++)
1331     {
1332         segment_t *segment = segment_GetSegment(hls, p_sys->download.segment);
1333         if (segment == NULL )
1334             return VLC_EGENERIC;
1335
1336         if (segment->data)
1337         {
1338             p_sys->download.segment++;
1339             continue;
1340         }
1341
1342         if (Download(s, hls, segment, current) != VLC_SUCCESS)
1343             return VLC_EGENERIC;
1344
1345         p_sys->download.segment++;
1346
1347         /* adapt bandwidth? */
1348         if (*current != stream)
1349         {
1350             hls_stream_t *hls = hls_Get(p_sys->hls_stream, *current);
1351             if (hls == NULL)
1352                 return VLC_EGENERIC;
1353
1354              stream = *current;
1355         }
1356     }
1357
1358     return VLC_SUCCESS;
1359 }
1360
1361 /****************************************************************************
1362  *
1363  ****************************************************************************/
1364 static int hls_Download(stream_t *s, segment_t *segment)
1365 {
1366     assert(segment);
1367
1368     /* Construct URL */
1369     char *psz_url = ConstructUrl(&segment->url);
1370     if (psz_url == NULL)
1371            return VLC_ENOMEM;
1372
1373     stream_t *p_ts = stream_UrlNew(s, psz_url);
1374     free(psz_url);
1375     if (p_ts == NULL)
1376         return VLC_EGENERIC;
1377
1378     segment->size = stream_Size(p_ts);
1379     assert(segment->size > 0);
1380
1381     segment->data = block_Alloc(segment->size);
1382     if (segment->data == NULL)
1383     {
1384         stream_Delete(p_ts);
1385         return VLC_ENOMEM;
1386     }
1387
1388     assert(segment->data->i_buffer == segment->size);
1389
1390     ssize_t length = 0, curlen = 0;
1391     uint64_t size;
1392     do
1393     {
1394         size = stream_Size(p_ts);
1395         if (size > segment->size)
1396         {
1397             msg_Dbg(s, "size changed %"PRIu64, segment->size);
1398             segment->data = block_Realloc(segment->data, 0, size);
1399             if (segment->data == NULL)
1400             {
1401                 stream_Delete(p_ts);
1402                 return VLC_ENOMEM;
1403             }
1404             segment->size = size;
1405             assert(segment->data->i_buffer == segment->size);
1406         }
1407         length = stream_Read(p_ts, segment->data->p_buffer + curlen, segment->size - curlen);
1408         if (length <= 0)
1409             break;
1410         curlen += length;
1411     } while (vlc_object_alive(s));
1412
1413     stream_Delete(p_ts);
1414     return VLC_SUCCESS;
1415 }
1416
1417 /* Read M3U8 file */
1418 static ssize_t read_M3U8_from_stream(stream_t *s, uint8_t **buffer)
1419 {
1420     int64_t total_bytes = 0;
1421     int64_t total_allocated = 0;
1422     uint8_t *p = NULL;
1423
1424     while (1)
1425     {
1426         char buf[4096];
1427         int64_t bytes;
1428
1429         bytes = stream_Read(s, buf, sizeof(buf));
1430         if (bytes == 0)
1431             break;      /* EOF ? */
1432         else if (bytes < 0)
1433             return bytes;
1434
1435         if ( (total_bytes + bytes + 1) > total_allocated )
1436         {
1437             if (total_allocated)
1438                 total_allocated *= 2;
1439             else
1440                 total_allocated = __MIN(bytes+1, sizeof(buf));
1441
1442             p = realloc_or_free(p, total_allocated);
1443             if (p == NULL)
1444                 return VLC_ENOMEM;
1445         }
1446
1447         memcpy(p+total_bytes, buf, bytes);
1448         total_bytes += bytes;
1449     }
1450
1451     if (total_allocated == 0)
1452         return VLC_EGENERIC;
1453
1454     p[total_bytes] = '\0';
1455     *buffer = p;
1456
1457     return total_bytes;
1458 }
1459
1460 static ssize_t read_M3U8_from_url(stream_t *s, vlc_url_t *url, uint8_t **buffer)
1461 {
1462     assert(*buffer == NULL);
1463
1464     /* Construct URL */
1465     char *psz_url = ConstructUrl(url);
1466     if (psz_url == NULL)
1467            return VLC_ENOMEM;
1468
1469     stream_t *p_m3u8 = stream_UrlNew(s, psz_url);
1470     free(psz_url);
1471     if (p_m3u8 == NULL)
1472         return VLC_EGENERIC;
1473
1474     ssize_t size = read_M3U8_from_stream(p_m3u8, buffer);
1475     stream_Delete(p_m3u8);
1476
1477     return size;
1478 }
1479
1480 static char *ReadLine(uint8_t *buffer, uint8_t **pos, const size_t len)
1481 {
1482     assert(buffer);
1483
1484     char *line = NULL;
1485     uint8_t *begin = buffer;
1486     uint8_t *p = begin;
1487     uint8_t *end = p + len;
1488
1489     while (p < end)
1490     {
1491         if ((*p == '\n') || (*p == '\0'))
1492             break;
1493         p++;
1494     }
1495
1496     /* copy line excluding \n or \0 */
1497     line = strndup((char *)begin, p - begin);
1498
1499     if (*p == '\0')
1500         *pos = end;
1501     else
1502     {
1503         /* next pass start after \n */
1504         p++;
1505         *pos = p;
1506     }
1507
1508     return line;
1509 }
1510
1511 /****************************************************************************
1512  * Open
1513  ****************************************************************************/
1514 static int Open(vlc_object_t *p_this)
1515 {
1516     stream_t *s = (stream_t*)p_this;
1517     stream_sys_t *p_sys;
1518
1519     if (!isHTTPLiveStreaming(s))
1520         return VLC_EGENERIC;
1521
1522     msg_Info(p_this, "HTTP Live Streaming (%s)", s->psz_path);
1523
1524     /* */
1525     s->p_sys = p_sys = calloc(1, sizeof(*p_sys));
1526     if (p_sys == NULL)
1527         return VLC_ENOMEM;
1528
1529     char *psz_uri = NULL;
1530     if (asprintf(&psz_uri,"%s://%s", s->psz_access, s->psz_path) < 0)
1531     {
1532         free(p_sys);
1533         return VLC_ENOMEM;
1534     }
1535     vlc_UrlParse(&p_sys->m3u8, psz_uri, 0);
1536     free(psz_uri);
1537
1538     p_sys->bandwidth = -1;
1539     p_sys->b_live = true;
1540     p_sys->b_meta = false;
1541     p_sys->b_error = false;
1542
1543     p_sys->hls_stream = vlc_array_new();
1544     if (p_sys->hls_stream == NULL)
1545     {
1546         vlc_UrlClean(&p_sys->m3u8);
1547         free(p_sys);
1548         return VLC_ENOMEM;
1549     }
1550
1551     /* */
1552     s->pf_read = Read;
1553     s->pf_peek = Peek;
1554     s->pf_control = Control;
1555
1556     /* Parse HLS m3u8 content. */
1557     uint8_t *buffer = NULL;
1558     ssize_t len = read_M3U8_from_stream(s->p_source, &buffer);
1559     if (len < 0)
1560         goto fail;
1561     if (parse_M3U8(s, p_sys->hls_stream, buffer, len) != VLC_SUCCESS)
1562     {
1563         free(buffer);
1564         goto fail;
1565     }
1566     free(buffer);
1567
1568     /* Choose first HLS stream to start with */
1569     int current = p_sys->playback.stream = 0;
1570     p_sys->playback.segment = p_sys->download.segment = ChooseSegment(s, current);
1571
1572     if (p_sys->b_live && (p_sys->playback.segment < 0))
1573     {
1574         msg_Warn(s, "less data than 3 times 'target duration' available for live playback, playback may stall");
1575     }
1576
1577     if (Prefetch(s, &current) != VLC_SUCCESS)
1578     {
1579         msg_Err(s, "fetching first segment failed.");
1580         goto fail;
1581     }
1582
1583
1584     p_sys->download.stream = current;
1585     p_sys->playback.stream = current;
1586     p_sys->download.seek = -1;
1587
1588     vlc_mutex_init(&p_sys->download.lock_wait);
1589     vlc_cond_init(&p_sys->download.wait);
1590
1591     /* Initialize HLS live stream */
1592     if (p_sys->b_live)
1593     {
1594         hls_stream_t *hls = hls_Get(p_sys->hls_stream, current);
1595         p_sys->playlist.last = mdate();
1596         p_sys->playlist.wakeup = p_sys->playlist.last +
1597                 ((mtime_t)hls->duration * UINT64_C(1000000));
1598
1599         if (vlc_clone(&p_sys->reload, hls_Reload, s, VLC_THREAD_PRIORITY_LOW))
1600         {
1601             goto fail_thread;
1602         }
1603     }
1604
1605     if (vlc_clone(&p_sys->thread, hls_Thread, s, VLC_THREAD_PRIORITY_INPUT))
1606     {
1607         if (p_sys->b_live)
1608             vlc_join(p_sys->reload, NULL);
1609         goto fail_thread;
1610     }
1611
1612     return VLC_SUCCESS;
1613
1614 fail_thread:
1615     vlc_mutex_destroy(&p_sys->download.lock_wait);
1616     vlc_cond_destroy(&p_sys->download.wait);
1617
1618 fail:
1619     /* Free hls streams */
1620     for (int i = 0; i < vlc_array_count(p_sys->hls_stream); i++)
1621     {
1622         hls_stream_t *hls;
1623         hls = (hls_stream_t *)vlc_array_item_at_index(p_sys->hls_stream, i);
1624         if (hls) hls_Free(hls);
1625     }
1626     vlc_array_destroy(p_sys->hls_stream);
1627
1628     /* */
1629     vlc_UrlClean(&p_sys->m3u8);
1630     free(p_sys);
1631     return VLC_EGENERIC;
1632 }
1633
1634 /****************************************************************************
1635  * Close
1636  ****************************************************************************/
1637 static void Close(vlc_object_t *p_this)
1638 {
1639     stream_t *s = (stream_t*)p_this;
1640     stream_sys_t *p_sys = s->p_sys;
1641
1642     assert(p_sys->hls_stream);
1643
1644     /* */
1645     vlc_mutex_lock(&p_sys->download.lock_wait);
1646     vlc_cond_signal(&p_sys->download.wait);
1647     vlc_mutex_unlock(&p_sys->download.lock_wait);
1648
1649     /* */
1650     if (p_sys->b_live)
1651         vlc_join(p_sys->reload, NULL);
1652     vlc_join(p_sys->thread, NULL);
1653     vlc_mutex_destroy(&p_sys->download.lock_wait);
1654     vlc_cond_destroy(&p_sys->download.wait);
1655
1656     /* Free hls streams */
1657     for (int i = 0; i < vlc_array_count(p_sys->hls_stream); i++)
1658     {
1659         hls_stream_t *hls;
1660         hls = (hls_stream_t *)vlc_array_item_at_index(p_sys->hls_stream, i);
1661         if (hls) hls_Free(hls);
1662     }
1663     vlc_array_destroy(p_sys->hls_stream);
1664
1665     /* */
1666     vlc_UrlClean(&p_sys->m3u8);
1667     if (p_sys->peeked)
1668         block_Release (p_sys->peeked);
1669     free(p_sys);
1670 }
1671
1672 /****************************************************************************
1673  * Stream filters functions
1674  ****************************************************************************/
1675 static segment_t *GetSegment(stream_t *s)
1676 {
1677     stream_sys_t *p_sys = s->p_sys;
1678     segment_t *segment = NULL;
1679
1680     /* Is this segment of the current HLS stream ready? */
1681     hls_stream_t *hls = hls_Get(p_sys->hls_stream, p_sys->playback.stream);
1682     if (hls != NULL)
1683     {
1684         vlc_mutex_lock(&hls->lock);
1685         segment = segment_GetSegment(hls, p_sys->playback.segment);
1686         if (segment != NULL)
1687         {
1688             /* This segment is ready? */
1689             if (segment->data != NULL)
1690             {
1691                 p_sys->b_cache = hls->b_cache;
1692                 vlc_mutex_unlock(&hls->lock);
1693                 goto check;
1694             }
1695         }
1696         vlc_mutex_unlock(&hls->lock);
1697     }
1698
1699     /* Was the HLS stream changed to another bitrate? */
1700     int i_stream = 0;
1701     segment = NULL;
1702     while(vlc_object_alive(s))
1703     {
1704         /* Is the next segment ready */
1705         hls_stream_t *hls = hls_Get(p_sys->hls_stream, i_stream);
1706         if (hls == NULL)
1707             return NULL;
1708
1709         vlc_mutex_lock(&hls->lock);
1710         segment = segment_GetSegment(hls, p_sys->playback.segment);
1711         if (segment == NULL)
1712         {
1713             vlc_mutex_unlock(&hls->lock);
1714             break;
1715         }
1716
1717         vlc_mutex_lock(&p_sys->download.lock_wait);
1718         int i_segment = p_sys->download.segment;
1719         vlc_mutex_unlock(&p_sys->download.lock_wait);
1720
1721         /* This segment is ready? */
1722         if ((segment->data != NULL) &&
1723             (p_sys->playback.segment < i_segment))
1724         {
1725             p_sys->playback.stream = i_stream;
1726             p_sys->b_cache = hls->b_cache;
1727             vlc_mutex_unlock(&hls->lock);
1728             goto check;
1729         }
1730         vlc_mutex_unlock(&hls->lock);
1731
1732         if (!p_sys->b_meta)
1733             break;
1734
1735         /* Was the stream changed to another bitrate? */
1736         i_stream++;
1737         if (i_stream >= vlc_array_count(p_sys->hls_stream))
1738             break;
1739     }
1740     /* */
1741     return NULL;
1742
1743 check:
1744     /* sanity check */
1745     if (segment->data->i_buffer == 0)
1746     {
1747         vlc_mutex_lock(&hls->lock);
1748         int count = vlc_array_count(hls->segments);
1749         vlc_mutex_unlock(&hls->lock);
1750
1751         if ((p_sys->download.segment - p_sys->playback.segment == 0) &&
1752             ((count != p_sys->download.segment) || p_sys->b_live))
1753             msg_Err(s, "playback will stall");
1754         else if ((p_sys->download.segment - p_sys->playback.segment < 3) &&
1755                  ((count != p_sys->download.segment) || p_sys->b_live))
1756             msg_Warn(s, "playback in danger of stalling");
1757     }
1758     return segment;
1759 }
1760
1761 static ssize_t hls_Read(stream_t *s, uint8_t *p_read, unsigned int i_read)
1762 {
1763     stream_sys_t *p_sys = s->p_sys;
1764     ssize_t copied = 0;
1765
1766     do
1767     {
1768         /* Determine next segment to read. If this is a meta playlist and
1769          * bandwidth conditions changed, then the stream might have switched
1770          * to another bandwidth. */
1771         segment_t *segment = GetSegment(s);
1772         if (segment == NULL)
1773             break;
1774
1775         vlc_mutex_lock(&segment->lock);
1776         if (segment->data->i_buffer == 0)
1777         {
1778             if (!p_sys->b_cache || p_sys->b_live)
1779             {
1780                 block_Release(segment->data);
1781                 segment->data = NULL;
1782             }
1783             else
1784             {   /* reset playback pointer to start of buffer */
1785                 uint64_t size = segment->size - segment->data->i_buffer;
1786                 if (size > 0)
1787                 {
1788                     segment->data->i_buffer += size;
1789                     segment->data->p_buffer -= size;
1790                 }
1791             }
1792             p_sys->playback.segment++;
1793             vlc_mutex_unlock(&segment->lock);
1794
1795             /* signal download thread */
1796             vlc_mutex_lock(&p_sys->download.lock_wait);
1797             vlc_cond_signal(&p_sys->download.wait);
1798             vlc_mutex_unlock(&p_sys->download.lock_wait);
1799             continue;
1800         }
1801
1802         if (segment->size == segment->data->i_buffer)
1803             msg_Info(s, "playing segment %d from stream %d",
1804                      segment->sequence, p_sys->playback.stream);
1805
1806         ssize_t len = -1;
1807         if (i_read <= segment->data->i_buffer)
1808             len = i_read;
1809         else if (i_read > segment->data->i_buffer)
1810             len = segment->data->i_buffer;
1811
1812         if (len > 0)
1813         {
1814             memcpy(p_read + copied, segment->data->p_buffer, len);
1815             segment->data->i_buffer -= len;
1816             segment->data->p_buffer += len;
1817             copied += len;
1818             i_read -= len;
1819         }
1820         vlc_mutex_unlock(&segment->lock);
1821
1822     } while ((i_read > 0) && vlc_object_alive(s));
1823
1824     return copied;
1825 }
1826
1827 static int Read(stream_t *s, void *buffer, unsigned int i_read)
1828 {
1829     stream_sys_t *p_sys = s->p_sys;
1830     ssize_t length = 0;
1831
1832     assert(p_sys->hls_stream);
1833
1834     if (p_sys->b_error)
1835         return 0;
1836
1837     if (buffer == NULL)
1838     {
1839         /* caller skips data, get big enough buffer */
1840         msg_Warn(s, "buffer is NULL (allocate %d)", i_read);
1841         buffer = calloc(1, i_read);
1842         if (buffer == NULL)
1843             return 0; /* NO MEMORY left*/
1844     }
1845
1846     length = hls_Read(s, (uint8_t*) buffer, i_read);
1847     if (length < 0)
1848         return 0;
1849
1850     p_sys->playback.offset += length;
1851     return length;
1852 }
1853
1854 static int Peek(stream_t *s, const uint8_t **pp_peek, unsigned int i_peek)
1855 {
1856     stream_sys_t *p_sys = s->p_sys;
1857     segment_t *segment;
1858     unsigned int len = i_peek;
1859
1860     segment = GetSegment(s);
1861     if (segment == NULL)
1862     {
1863         msg_Err(s, "segment %d should have been available (stream %d)",
1864                 p_sys->playback.segment, p_sys->playback.stream);
1865         return 0; /* eof? */
1866     }
1867
1868     vlc_mutex_lock(&segment->lock);
1869
1870     size_t i_buff = segment->data->i_buffer;
1871     uint8_t *p_buff = segment->data->p_buffer;
1872
1873     if (i_peek < i_buff)
1874     {
1875         *pp_peek = p_buff;
1876         vlc_mutex_unlock(&segment->lock);
1877         return i_peek;
1878     }
1879
1880     else /* This will seldom be run */
1881     {
1882         /* remember segment to read */
1883         int peek_segment = p_sys->playback.segment;
1884         size_t curlen = 0;
1885         segment_t *nsegment;
1886         p_sys->playback.segment++;
1887         block_t *peeked = p_sys->peeked;
1888
1889         if (peeked == NULL)
1890             peeked = block_Alloc (i_peek);
1891         else if (peeked->i_buffer < i_peek)
1892             peeked = block_Realloc (peeked, 0, i_peek);
1893         if (peeked == NULL)
1894             return 0;
1895
1896         memcpy(peeked->p_buffer, p_buff, i_buff);
1897         curlen = i_buff;
1898         len -= i_buff;
1899         vlc_mutex_unlock(&segment->lock);
1900
1901         i_buff = peeked->i_buffer;
1902         p_buff = peeked->p_buffer;
1903         *pp_peek = p_buff;
1904
1905         while ((curlen < i_peek) && vlc_object_alive(s))
1906         {
1907             nsegment = GetSegment(s);
1908             if (nsegment == NULL)
1909             {
1910                 msg_Err(s, "segment %d should have been available (stream %d)",
1911                         p_sys->playback.segment, p_sys->playback.stream);
1912                 /* restore segment to read */
1913                 p_sys->playback.segment = peek_segment;
1914                 return curlen; /* eof? */
1915             }
1916
1917             vlc_mutex_lock(&nsegment->lock);
1918
1919             if (len < nsegment->data->i_buffer)
1920             {
1921                 memcpy(p_buff + curlen, nsegment->data->p_buffer, len);
1922                 curlen += len;
1923             }
1924             else
1925             {
1926                 size_t i_nbuff = nsegment->data->i_buffer;
1927                 memcpy(p_buff + curlen, nsegment->data->p_buffer, i_nbuff);
1928                 curlen += i_nbuff;
1929                 len -= i_nbuff;
1930
1931                 p_sys->playback.segment++;
1932             }
1933
1934             vlc_mutex_unlock(&nsegment->lock);
1935         }
1936
1937         /* restore segment to read */
1938         p_sys->playback.segment = peek_segment;
1939         return curlen;
1940     }
1941 }
1942
1943 static bool hls_MaySeek(stream_t *s)
1944 {
1945     stream_sys_t *p_sys = s->p_sys;
1946
1947     if (p_sys->hls_stream == NULL)
1948         return false;
1949
1950     hls_stream_t *hls = hls_Get(p_sys->hls_stream, p_sys->playback.stream);
1951     if (hls == NULL) return false;
1952
1953     if (p_sys->b_live)
1954     {
1955         vlc_mutex_lock(&hls->lock);
1956         int count = vlc_array_count(hls->segments);
1957         vlc_mutex_unlock(&hls->lock);
1958
1959         vlc_mutex_lock(&p_sys->download.lock_wait);
1960         bool may_seek = (p_sys->download.segment < (count - 2));
1961         vlc_mutex_unlock(&p_sys->download.lock_wait);
1962         return may_seek;
1963     }
1964     return true;
1965 }
1966
1967 static uint64_t GetStreamSize(stream_t *s)
1968 {
1969     stream_sys_t *p_sys = s->p_sys;
1970
1971     if (p_sys->b_live)
1972         return 0;
1973
1974     hls_stream_t *hls = hls_Get(p_sys->hls_stream, p_sys->playback.stream);
1975     if (hls == NULL) return 0;
1976
1977     vlc_mutex_lock(&hls->lock);
1978     uint64_t size = hls->size;
1979     vlc_mutex_unlock(&hls->lock);
1980
1981     return size;
1982 }
1983
1984 static int segment_Seek(stream_t *s, const uint64_t pos)
1985 {
1986     stream_sys_t *p_sys = s->p_sys;
1987
1988     hls_stream_t *hls = hls_Get(p_sys->hls_stream, p_sys->playback.stream);
1989     if (hls == NULL)
1990         return VLC_EGENERIC;
1991
1992     vlc_mutex_lock(&hls->lock);
1993
1994     bool b_found = false;
1995     uint64_t length = 0;
1996     uint64_t size = hls->size;
1997     int count = vlc_array_count(hls->segments);
1998
1999     for (int n = 0; n < count; n++)
2000     {
2001         segment_t *segment = vlc_array_item_at_index(hls->segments, n);
2002         if (segment == NULL)
2003         {
2004             vlc_mutex_unlock(&hls->lock);
2005             return VLC_EGENERIC;
2006         }
2007
2008         vlc_mutex_lock(&segment->lock);
2009         length += segment->duration * (hls->bandwidth/8);
2010         vlc_mutex_unlock(&segment->lock);
2011
2012         if (!b_found && (pos <= length))
2013         {
2014             if (count - n >= 3)
2015             {
2016                 p_sys->playback.segment = n;
2017                 b_found = true;
2018                 break;
2019             }
2020             /* Do not search in last 3 segments */
2021             vlc_mutex_unlock(&hls->lock);
2022             return VLC_EGENERIC;
2023         }
2024     }
2025
2026     /* */
2027     if (!b_found && (pos >= size))
2028     {
2029         p_sys->playback.segment = count - 1;
2030         b_found = true;
2031     }
2032
2033     /* */
2034     if (b_found)
2035     {
2036         /* restore segment to start position */
2037         segment_t *segment = segment_GetSegment(hls, p_sys->playback.segment);
2038         if (segment == NULL)
2039         {
2040             vlc_mutex_unlock(&hls->lock);
2041             return VLC_EGENERIC;
2042         }
2043
2044         vlc_mutex_lock(&segment->lock);
2045         if (segment->data)
2046         {
2047             uint64_t size = segment->size -segment->data->i_buffer;
2048             if (size > 0)
2049             {
2050                 segment->data->i_buffer += size;
2051                 segment->data->p_buffer -= size;
2052             }
2053         }
2054         vlc_mutex_unlock(&segment->lock);
2055
2056         /* start download at current playback segment */
2057         vlc_mutex_unlock(&hls->lock);
2058
2059         /* Wake up download thread */
2060         vlc_mutex_lock(&p_sys->download.lock_wait);
2061         p_sys->download.seek = p_sys->playback.segment;
2062         vlc_cond_signal(&p_sys->download.wait);
2063         vlc_mutex_unlock(&p_sys->download.lock_wait);
2064
2065         /* Wait for download to be finished */
2066         vlc_mutex_lock(&p_sys->download.lock_wait);
2067         msg_Info(s, "seek to segment %d", p_sys->playback.segment);
2068         while (((p_sys->download.seek != -1) ||
2069                 (p_sys->download.segment - p_sys->playback.segment < 3)) &&
2070                 (p_sys->download.segment < (count - 6)))
2071         {
2072             vlc_cond_wait(&p_sys->download.wait, &p_sys->download.lock_wait);
2073             if (!vlc_object_alive(s) || s->b_error) break;
2074         }
2075         vlc_mutex_unlock(&p_sys->download.lock_wait);
2076
2077         return VLC_SUCCESS;
2078     }
2079     vlc_mutex_unlock(&hls->lock);
2080
2081     return b_found ? VLC_SUCCESS : VLC_EGENERIC;
2082 }
2083
2084 static int Control(stream_t *s, int i_query, va_list args)
2085 {
2086     stream_sys_t *p_sys = s->p_sys;
2087
2088     switch (i_query)
2089     {
2090         case STREAM_CAN_SEEK:
2091         case STREAM_CAN_FASTSEEK:
2092             *(va_arg (args, bool *)) = hls_MaySeek(s);
2093             break;
2094         case STREAM_GET_POSITION:
2095             *(va_arg (args, uint64_t *)) = p_sys->playback.offset;
2096             break;
2097         case STREAM_SET_POSITION:
2098             if (hls_MaySeek(s))
2099             {
2100                 uint64_t pos = (uint64_t)va_arg(args, uint64_t);
2101                 if (segment_Seek(s, pos) == VLC_SUCCESS)
2102                 {
2103                     p_sys->playback.offset = pos;
2104                     break;
2105                 }
2106             }
2107             return VLC_EGENERIC;
2108         case STREAM_GET_SIZE:
2109             *(va_arg (args, uint64_t *)) = GetStreamSize(s);
2110             break;
2111         default:
2112             return VLC_EGENERIC;
2113     }
2114     return VLC_SUCCESS;
2115 }