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