Merge remote branch 'qatar/master'
[ffmpeg.git] / libavformat / applehttp.c
1 /*
2  * Apple HTTP Live Streaming demuxer
3  * Copyright (c) 2010 Martin Storsjo
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file
24  * Apple HTTP Live Streaming demuxer
25  * http://tools.ietf.org/html/draft-pantos-http-live-streaming
26  */
27
28 #define _XOPEN_SOURCE 600
29 #include "libavutil/avstring.h"
30 #include "avformat.h"
31 #include "internal.h"
32 #include <unistd.h>
33 #include "avio_internal.h"
34 #include "url.h"
35
36 #define INITIAL_BUFFER_SIZE 32768
37
38 /*
39  * An apple http stream consists of a playlist with media segment files,
40  * played sequentially. There may be several playlists with the same
41  * video content, in different bandwidth variants, that are played in
42  * parallel (preferrably only one bandwidth variant at a time). In this case,
43  * the user supplied the url to a main playlist that only lists the variant
44  * playlists.
45  *
46  * If the main playlist doesn't point at any variants, we still create
47  * one anonymous toplevel variant for this, to maintain the structure.
48  */
49
50 struct segment {
51     int duration;
52     char url[MAX_URL_SIZE];
53 };
54
55 /*
56  * Each variant has its own demuxer. If it currently is active,
57  * it has an open AVIOContext too, and potentially an AVPacket
58  * containing the next packet from this stream.
59  */
60 struct variant {
61     int bandwidth;
62     char url[MAX_URL_SIZE];
63     AVIOContext pb;
64     uint8_t* read_buffer;
65     URLContext *input;
66     AVFormatContext *parent;
67     int index;
68     AVFormatContext *ctx;
69     AVPacket pkt;
70     int stream_offset;
71
72     int finished;
73     int target_duration;
74     int start_seq_no;
75     int n_segments;
76     struct segment **segments;
77     int needed, cur_needed;
78     int cur_seq_no;
79     int64_t last_load_time;
80 };
81
82 typedef struct AppleHTTPContext {
83     int n_variants;
84     struct variant **variants;
85     int cur_seq_no;
86     int end_of_segment;
87     int first_packet;
88 } AppleHTTPContext;
89
90 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
91 {
92     int len = ff_get_line(s, buf, maxlen);
93     while (len > 0 && isspace(buf[len - 1]))
94         buf[--len] = '\0';
95     return len;
96 }
97
98 static void free_segment_list(struct variant *var)
99 {
100     int i;
101     for (i = 0; i < var->n_segments; i++)
102         av_free(var->segments[i]);
103     av_freep(&var->segments);
104     var->n_segments = 0;
105 }
106
107 static void free_variant_list(AppleHTTPContext *c)
108 {
109     int i;
110     for (i = 0; i < c->n_variants; i++) {
111         struct variant *var = c->variants[i];
112         free_segment_list(var);
113         av_free_packet(&var->pkt);
114         av_free(var->pb.buffer);
115         if (var->input)
116             ffurl_close(var->input);
117         if (var->ctx) {
118             var->ctx->pb = NULL;
119             av_close_input_file(var->ctx);
120         }
121         av_free(var);
122     }
123     av_freep(&c->variants);
124     c->n_variants = 0;
125 }
126
127 /*
128  * Used to reset a statically allocated AVPacket to a clean slate,
129  * containing no data.
130  */
131 static void reset_packet(AVPacket *pkt)
132 {
133     av_init_packet(pkt);
134     pkt->data = NULL;
135 }
136
137 static struct variant *new_variant(AppleHTTPContext *c, int bandwidth,
138                                    const char *url, const char *base)
139 {
140     struct variant *var = av_mallocz(sizeof(struct variant));
141     if (!var)
142         return NULL;
143     reset_packet(&var->pkt);
144     var->bandwidth = bandwidth;
145     ff_make_absolute_url(var->url, sizeof(var->url), base, url);
146     dynarray_add(&c->variants, &c->n_variants, var);
147     return var;
148 }
149
150 struct variant_info {
151     char bandwidth[20];
152 };
153
154 static void handle_variant_args(struct variant_info *info, const char *key,
155                                 int key_len, char **dest, int *dest_len)
156 {
157     if (!strncmp(key, "BANDWIDTH=", key_len)) {
158         *dest     =        info->bandwidth;
159         *dest_len = sizeof(info->bandwidth);
160     }
161 }
162
163 static int parse_playlist(AppleHTTPContext *c, const char *url,
164                           struct variant *var, AVIOContext *in)
165 {
166     int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
167     char line[1024];
168     const char *ptr;
169     int close_in = 0;
170
171     if (!in) {
172         close_in = 1;
173         if ((ret = avio_open(&in, url, AVIO_FLAG_READ)) < 0)
174             return ret;
175     }
176
177     read_chomp_line(in, line, sizeof(line));
178     if (strcmp(line, "#EXTM3U")) {
179         ret = AVERROR_INVALIDDATA;
180         goto fail;
181     }
182
183     if (var) {
184         free_segment_list(var);
185         var->finished = 0;
186     }
187     while (!url_feof(in)) {
188         read_chomp_line(in, line, sizeof(line));
189         if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
190             struct variant_info info = {{0}};
191             is_variant = 1;
192             ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
193                                &info);
194             bandwidth = atoi(info.bandwidth);
195         } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
196             if (!var) {
197                 var = new_variant(c, 0, url, NULL);
198                 if (!var) {
199                     ret = AVERROR(ENOMEM);
200                     goto fail;
201                 }
202             }
203             var->target_duration = atoi(ptr);
204         } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
205             if (!var) {
206                 var = new_variant(c, 0, url, NULL);
207                 if (!var) {
208                     ret = AVERROR(ENOMEM);
209                     goto fail;
210                 }
211             }
212             var->start_seq_no = atoi(ptr);
213         } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
214             if (var)
215                 var->finished = 1;
216         } else if (av_strstart(line, "#EXTINF:", &ptr)) {
217             is_segment = 1;
218             duration   = atoi(ptr);
219         } else if (av_strstart(line, "#", NULL)) {
220             continue;
221         } else if (line[0]) {
222             if (is_variant) {
223                 if (!new_variant(c, bandwidth, line, url)) {
224                     ret = AVERROR(ENOMEM);
225                     goto fail;
226                 }
227                 is_variant = 0;
228                 bandwidth  = 0;
229             }
230             if (is_segment) {
231                 struct segment *seg;
232                 if (!var) {
233                     var = new_variant(c, 0, url, NULL);
234                     if (!var) {
235                         ret = AVERROR(ENOMEM);
236                         goto fail;
237                     }
238                 }
239                 seg = av_malloc(sizeof(struct segment));
240                 if (!seg) {
241                     ret = AVERROR(ENOMEM);
242                     goto fail;
243                 }
244                 seg->duration = duration;
245                 ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
246                 dynarray_add(&var->segments, &var->n_segments, seg);
247                 is_segment = 0;
248             }
249         }
250     }
251     if (var)
252         var->last_load_time = av_gettime();
253
254 fail:
255     if (close_in)
256         avio_close(in);
257     return ret;
258 }
259
260 static int read_data(void *opaque, uint8_t *buf, int buf_size)
261 {
262     struct variant *v = opaque;
263     AppleHTTPContext *c = v->parent->priv_data;
264     int ret, i;
265
266 restart:
267     if (!v->input) {
268 reload:
269         /* If this is a live stream and target_duration has elapsed since
270          * the last playlist reload, reload the variant playlists now. */
271         if (!v->finished &&
272             av_gettime() - v->last_load_time >= v->target_duration*1000000 &&
273             (ret = parse_playlist(c, v->url, v, NULL)) < 0)
274                 return ret;
275         if (v->cur_seq_no < v->start_seq_no) {
276             av_log(NULL, AV_LOG_WARNING,
277                    "skipping %d segments ahead, expired from playlists\n",
278                    v->start_seq_no - v->cur_seq_no);
279             v->cur_seq_no = v->start_seq_no;
280         }
281         if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
282             if (v->finished)
283                 return AVERROR_EOF;
284             while (av_gettime() - v->last_load_time <
285                    v->target_duration*1000000) {
286                 if (url_interrupt_cb())
287                     return AVERROR_EXIT;
288                 usleep(100*1000);
289             }
290             /* Enough time has elapsed since the last reload */
291             goto reload;
292         }
293
294         ret = ffurl_open(&v->input,
295                          v->segments[v->cur_seq_no - v->start_seq_no]->url,
296                          AVIO_FLAG_READ);
297         if (ret < 0)
298             return ret;
299     }
300     ret = ffurl_read(v->input, buf, buf_size);
301     if (ret > 0)
302         return ret;
303     if (ret < 0 && ret != AVERROR_EOF)
304         return ret;
305     ffurl_close(v->input);
306     v->input = NULL;
307     v->cur_seq_no++;
308
309     c->end_of_segment = 1;
310     c->cur_seq_no = v->cur_seq_no;
311
312     if (v->ctx) {
313         v->needed = 0;
314         for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
315              i++) {
316             if (v->parent->streams[i]->discard < AVDISCARD_ALL)
317                 v->needed = 1;
318         }
319     }
320     if (!v->needed) {
321         av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
322                v->index);
323         return AVERROR_EOF;
324     }
325     goto restart;
326 }
327
328 static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
329 {
330     AppleHTTPContext *c = s->priv_data;
331     int ret = 0, i, j, stream_offset = 0;
332
333     if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
334         goto fail;
335
336     if (c->n_variants == 0) {
337         av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
338         ret = AVERROR_EOF;
339         goto fail;
340     }
341     /* If the playlist only contained variants, parse each individual
342      * variant playlist. */
343     if (c->n_variants > 1 || c->variants[0]->n_segments == 0) {
344         for (i = 0; i < c->n_variants; i++) {
345             struct variant *v = c->variants[i];
346             if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
347                 goto fail;
348         }
349     }
350
351     if (c->variants[0]->n_segments == 0) {
352         av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
353         ret = AVERROR_EOF;
354         goto fail;
355     }
356
357     /* If this isn't a live stream, calculate the total duration of the
358      * stream. */
359     if (c->variants[0]->finished) {
360         int64_t duration = 0;
361         for (i = 0; i < c->variants[0]->n_segments; i++)
362             duration += c->variants[0]->segments[i]->duration;
363         s->duration = duration * AV_TIME_BASE;
364     }
365
366     /* Open the demuxer for each variant */
367     for (i = 0; i < c->n_variants; i++) {
368         struct variant *v = c->variants[i];
369         AVInputFormat *in_fmt = NULL;
370         char bitrate_str[20];
371         if (v->n_segments == 0)
372             continue;
373
374         v->index  = i;
375         v->needed = 1;
376         v->parent = s;
377
378         /* If this is a live stream with more than 3 segments, start at the
379          * third last segment. */
380         v->cur_seq_no = v->start_seq_no;
381         if (!v->finished && v->n_segments > 3)
382             v->cur_seq_no = v->start_seq_no + v->n_segments - 3;
383
384         v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
385         ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, v,
386                           read_data, NULL, NULL);
387         v->pb.seekable = 0;
388         ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url,
389                                     NULL, 0, 0);
390         if (ret < 0)
391             goto fail;
392         ret = av_open_input_stream(&v->ctx, &v->pb, v->segments[0]->url,
393                                    in_fmt, NULL);
394         if (ret < 0)
395             goto fail;
396         v->stream_offset = stream_offset;
397         snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
398         /* Create new AVStreams for each stream in this variant */
399         for (j = 0; j < v->ctx->nb_streams; j++) {
400             AVStream *st = av_new_stream(s, i);
401             if (!st) {
402                 ret = AVERROR(ENOMEM);
403                 goto fail;
404             }
405             avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
406             av_metadata_set2(&st->metadata, "variant_bitrate", bitrate_str, 0);
407         }
408         stream_offset += v->ctx->nb_streams;
409     }
410
411     c->first_packet = 1;
412
413     return 0;
414 fail:
415     free_variant_list(c);
416     return ret;
417 }
418
419 static int recheck_discard_flags(AVFormatContext *s, int first)
420 {
421     AppleHTTPContext *c = s->priv_data;
422     int i, changed = 0;
423
424     /* Check if any new streams are needed */
425     for (i = 0; i < c->n_variants; i++)
426         c->variants[i]->cur_needed = 0;;
427
428     for (i = 0; i < s->nb_streams; i++) {
429         AVStream *st = s->streams[i];
430         struct variant *var = c->variants[s->streams[i]->id];
431         if (st->discard < AVDISCARD_ALL)
432             var->cur_needed = 1;
433     }
434     for (i = 0; i < c->n_variants; i++) {
435         struct variant *v = c->variants[i];
436         if (v->cur_needed && !v->needed) {
437             v->needed = 1;
438             changed = 1;
439             v->cur_seq_no = c->cur_seq_no;
440             v->pb.eof_reached = 0;
441             av_log(s, AV_LOG_INFO, "Now receiving variant %d\n", i);
442         } else if (first && !v->cur_needed && v->needed) {
443             if (v->input)
444                 ffurl_close(v->input);
445             v->input = NULL;
446             v->needed = 0;
447             changed = 1;
448             av_log(s, AV_LOG_INFO, "No longer receiving variant %d\n", i);
449         }
450     }
451     return changed;
452 }
453
454 static int applehttp_read_packet(AVFormatContext *s, AVPacket *pkt)
455 {
456     AppleHTTPContext *c = s->priv_data;
457     int ret, i, minvariant = -1;
458
459     if (c->first_packet) {
460         recheck_discard_flags(s, 1);
461         c->first_packet = 0;
462     }
463
464 start:
465     c->end_of_segment = 0;
466     for (i = 0; i < c->n_variants; i++) {
467         struct variant *var = c->variants[i];
468         /* Make sure we've got one buffered packet from each open variant
469          * stream */
470         if (var->needed && !var->pkt.data) {
471             ret = av_read_frame(var->ctx, &var->pkt);
472             if (ret < 0) {
473                 if (!url_feof(&var->pb))
474                     return ret;
475                 reset_packet(&var->pkt);
476             }
477         }
478         /* Check if this stream has the packet with the lowest dts */
479         if (var->pkt.data) {
480             if (minvariant < 0 ||
481                 var->pkt.dts < c->variants[minvariant]->pkt.dts)
482                 minvariant = i;
483         }
484     }
485     if (c->end_of_segment) {
486         if (recheck_discard_flags(s, 0))
487             goto start;
488     }
489     /* If we got a packet, return it */
490     if (minvariant >= 0) {
491         *pkt = c->variants[minvariant]->pkt;
492         pkt->stream_index += c->variants[minvariant]->stream_offset;
493         reset_packet(&c->variants[minvariant]->pkt);
494         return 0;
495     }
496     return AVERROR_EOF;
497 }
498
499 static int applehttp_close(AVFormatContext *s)
500 {
501     AppleHTTPContext *c = s->priv_data;
502
503     free_variant_list(c);
504     return 0;
505 }
506
507 static int applehttp_read_seek(AVFormatContext *s, int stream_index,
508                                int64_t timestamp, int flags)
509 {
510     AppleHTTPContext *c = s->priv_data;
511     int i, j, ret;
512
513     if ((flags & AVSEEK_FLAG_BYTE) || !c->variants[0]->finished)
514         return AVERROR(ENOSYS);
515
516     timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
517                                s->streams[stream_index]->time_base.den :
518                                AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
519                                AV_ROUND_DOWN : AV_ROUND_UP);
520     ret = AVERROR(EIO);
521     for (i = 0; i < c->n_variants; i++) {
522         /* Reset reading */
523         struct variant *var = c->variants[i];
524         int64_t pos = 0;
525         if (var->input) {
526             ffurl_close(var->input);
527             var->input = NULL;
528         }
529         av_free_packet(&var->pkt);
530         reset_packet(&var->pkt);
531         var->pb.eof_reached = 0;
532
533         /* Locate the segment that contains the target timestamp */
534         for (j = 0; j < var->n_segments; j++) {
535             if (timestamp >= pos &&
536                 timestamp < pos + var->segments[j]->duration) {
537                 var->cur_seq_no = var->start_seq_no + j;
538                 ret = 0;
539                 break;
540             }
541             pos += var->segments[j]->duration;
542         }
543     }
544     return ret;
545 }
546
547 static int applehttp_probe(AVProbeData *p)
548 {
549     /* Require #EXTM3U at the start, and either one of the ones below
550      * somewhere for a proper match. */
551     if (strncmp(p->buf, "#EXTM3U", 7))
552         return 0;
553     if (strstr(p->buf, "#EXT-X-STREAM-INF:")     ||
554         strstr(p->buf, "#EXT-X-TARGETDURATION:") ||
555         strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:"))
556         return AVPROBE_SCORE_MAX;
557     return 0;
558 }
559
560 AVInputFormat ff_applehttp_demuxer = {
561     "applehttp",
562     NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming format"),
563     sizeof(AppleHTTPContext),
564     applehttp_probe,
565     applehttp_read_header,
566     applehttp_read_packet,
567     applehttp_close,
568     applehttp_read_seek,
569 };