]> git.sesse.net Git - ffmpeg/blob - libavformat/applehttp.c
lavf: use designated initializers for AVClasses.
[ffmpeg] / libavformat / applehttp.c
1 /*
2  * Apple HTTP Live Streaming demuxer
3  * Copyright (c) 2010 Martin Storsjo
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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 #include "libavutil/avstring.h"
29 #include "libavutil/intreadwrite.h"
30 #include "libavutil/opt.h"
31 #include "avformat.h"
32 #include "internal.h"
33 #include <unistd.h>
34 #include "avio_internal.h"
35 #include "url.h"
36
37 #define INITIAL_BUFFER_SIZE 32768
38
39 /*
40  * An apple http stream consists of a playlist with media segment files,
41  * played sequentially. There may be several playlists with the same
42  * video content, in different bandwidth variants, that are played in
43  * parallel (preferrably only one bandwidth variant at a time). In this case,
44  * the user supplied the url to a main playlist that only lists the variant
45  * playlists.
46  *
47  * If the main playlist doesn't point at any variants, we still create
48  * one anonymous toplevel variant for this, to maintain the structure.
49  */
50
51 enum KeyType {
52     KEY_NONE,
53     KEY_AES_128,
54 };
55
56 struct segment {
57     int duration;
58     char url[MAX_URL_SIZE];
59     char key[MAX_URL_SIZE];
60     enum KeyType key_type;
61     uint8_t iv[16];
62 };
63
64 /*
65  * Each variant has its own demuxer. If it currently is active,
66  * it has an open AVIOContext too, and potentially an AVPacket
67  * containing the next packet from this stream.
68  */
69 struct variant {
70     int bandwidth;
71     char url[MAX_URL_SIZE];
72     AVIOContext pb;
73     uint8_t* read_buffer;
74     URLContext *input;
75     AVFormatContext *parent;
76     int index;
77     AVFormatContext *ctx;
78     AVPacket pkt;
79     int stream_offset;
80
81     int finished;
82     int target_duration;
83     int start_seq_no;
84     int n_segments;
85     struct segment **segments;
86     int needed, cur_needed;
87     int cur_seq_no;
88     int64_t last_load_time;
89
90     char key_url[MAX_URL_SIZE];
91     uint8_t key[16];
92 };
93
94 typedef struct AppleHTTPContext {
95     int n_variants;
96     struct variant **variants;
97     int cur_seq_no;
98     int end_of_segment;
99     int first_packet;
100 } AppleHTTPContext;
101
102 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
103 {
104     int len = ff_get_line(s, buf, maxlen);
105     while (len > 0 && isspace(buf[len - 1]))
106         buf[--len] = '\0';
107     return len;
108 }
109
110 static void free_segment_list(struct variant *var)
111 {
112     int i;
113     for (i = 0; i < var->n_segments; i++)
114         av_free(var->segments[i]);
115     av_freep(&var->segments);
116     var->n_segments = 0;
117 }
118
119 static void free_variant_list(AppleHTTPContext *c)
120 {
121     int i;
122     for (i = 0; i < c->n_variants; i++) {
123         struct variant *var = c->variants[i];
124         free_segment_list(var);
125         av_free_packet(&var->pkt);
126         av_free(var->pb.buffer);
127         if (var->input)
128             ffurl_close(var->input);
129         if (var->ctx) {
130             var->ctx->pb = NULL;
131             av_close_input_file(var->ctx);
132         }
133         av_free(var);
134     }
135     av_freep(&c->variants);
136     c->n_variants = 0;
137 }
138
139 /*
140  * Used to reset a statically allocated AVPacket to a clean slate,
141  * containing no data.
142  */
143 static void reset_packet(AVPacket *pkt)
144 {
145     av_init_packet(pkt);
146     pkt->data = NULL;
147 }
148
149 static struct variant *new_variant(AppleHTTPContext *c, int bandwidth,
150                                    const char *url, const char *base)
151 {
152     struct variant *var = av_mallocz(sizeof(struct variant));
153     if (!var)
154         return NULL;
155     reset_packet(&var->pkt);
156     var->bandwidth = bandwidth;
157     ff_make_absolute_url(var->url, sizeof(var->url), base, url);
158     dynarray_add(&c->variants, &c->n_variants, var);
159     return var;
160 }
161
162 struct variant_info {
163     char bandwidth[20];
164 };
165
166 static void handle_variant_args(struct variant_info *info, const char *key,
167                                 int key_len, char **dest, int *dest_len)
168 {
169     if (!strncmp(key, "BANDWIDTH=", key_len)) {
170         *dest     =        info->bandwidth;
171         *dest_len = sizeof(info->bandwidth);
172     }
173 }
174
175 struct key_info {
176      char uri[MAX_URL_SIZE];
177      char method[10];
178      char iv[35];
179 };
180
181 static void handle_key_args(struct key_info *info, const char *key,
182                             int key_len, char **dest, int *dest_len)
183 {
184     if (!strncmp(key, "METHOD=", key_len)) {
185         *dest     =        info->method;
186         *dest_len = sizeof(info->method);
187     } else if (!strncmp(key, "URI=", key_len)) {
188         *dest     =        info->uri;
189         *dest_len = sizeof(info->uri);
190     } else if (!strncmp(key, "IV=", key_len)) {
191         *dest     =        info->iv;
192         *dest_len = sizeof(info->iv);
193     }
194 }
195
196 static int parse_playlist(AppleHTTPContext *c, const char *url,
197                           struct variant *var, AVIOContext *in)
198 {
199     int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
200     enum KeyType key_type = KEY_NONE;
201     uint8_t iv[16] = "";
202     int has_iv = 0;
203     char key[MAX_URL_SIZE];
204     char line[1024];
205     const char *ptr;
206     int close_in = 0;
207
208     if (!in) {
209         close_in = 1;
210         if ((ret = avio_open(&in, url, AVIO_FLAG_READ)) < 0)
211             return ret;
212     }
213
214     read_chomp_line(in, line, sizeof(line));
215     if (strcmp(line, "#EXTM3U")) {
216         ret = AVERROR_INVALIDDATA;
217         goto fail;
218     }
219
220     if (var) {
221         free_segment_list(var);
222         var->finished = 0;
223     }
224     while (!in->eof_reached) {
225         read_chomp_line(in, line, sizeof(line));
226         if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
227             struct variant_info info = {{0}};
228             is_variant = 1;
229             ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
230                                &info);
231             bandwidth = atoi(info.bandwidth);
232         } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
233             struct key_info info = {{0}};
234             ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
235                                &info);
236             key_type = KEY_NONE;
237             has_iv = 0;
238             if (!strcmp(info.method, "AES-128"))
239                 key_type = KEY_AES_128;
240             if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
241                 ff_hex_to_data(iv, info.iv + 2);
242                 has_iv = 1;
243             }
244             av_strlcpy(key, info.uri, sizeof(key));
245         } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
246             if (!var) {
247                 var = new_variant(c, 0, url, NULL);
248                 if (!var) {
249                     ret = AVERROR(ENOMEM);
250                     goto fail;
251                 }
252             }
253             var->target_duration = atoi(ptr);
254         } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
255             if (!var) {
256                 var = new_variant(c, 0, url, NULL);
257                 if (!var) {
258                     ret = AVERROR(ENOMEM);
259                     goto fail;
260                 }
261             }
262             var->start_seq_no = atoi(ptr);
263         } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
264             if (var)
265                 var->finished = 1;
266         } else if (av_strstart(line, "#EXTINF:", &ptr)) {
267             is_segment = 1;
268             duration   = atoi(ptr);
269         } else if (av_strstart(line, "#", NULL)) {
270             continue;
271         } else if (line[0]) {
272             if (is_variant) {
273                 if (!new_variant(c, bandwidth, line, url)) {
274                     ret = AVERROR(ENOMEM);
275                     goto fail;
276                 }
277                 is_variant = 0;
278                 bandwidth  = 0;
279             }
280             if (is_segment) {
281                 struct segment *seg;
282                 if (!var) {
283                     var = new_variant(c, 0, url, NULL);
284                     if (!var) {
285                         ret = AVERROR(ENOMEM);
286                         goto fail;
287                     }
288                 }
289                 seg = av_malloc(sizeof(struct segment));
290                 if (!seg) {
291                     ret = AVERROR(ENOMEM);
292                     goto fail;
293                 }
294                 seg->duration = duration;
295                 seg->key_type = key_type;
296                 if (has_iv) {
297                     memcpy(seg->iv, iv, sizeof(iv));
298                 } else {
299                     int seq = var->start_seq_no + var->n_segments;
300                     memset(seg->iv, 0, sizeof(seg->iv));
301                     AV_WB32(seg->iv + 12, seq);
302                 }
303                 ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);
304                 ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
305                 dynarray_add(&var->segments, &var->n_segments, seg);
306                 is_segment = 0;
307             }
308         }
309     }
310     if (var)
311         var->last_load_time = av_gettime();
312
313 fail:
314     if (close_in)
315         avio_close(in);
316     return ret;
317 }
318
319 static int open_input(struct variant *var)
320 {
321     struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
322     if (seg->key_type == KEY_NONE) {
323         return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ);
324     } else if (seg->key_type == KEY_AES_128) {
325         char iv[33], key[33], url[MAX_URL_SIZE];
326         int ret;
327         if (strcmp(seg->key, var->key_url)) {
328             URLContext *uc;
329             if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ) == 0) {
330                 if (ffurl_read_complete(uc, var->key, sizeof(var->key))
331                     != sizeof(var->key)) {
332                     av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
333                            seg->key);
334                 }
335                 ffurl_close(uc);
336             } else {
337                 av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
338                        seg->key);
339             }
340             av_strlcpy(var->key_url, seg->key, sizeof(var->key_url));
341         }
342         ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
343         ff_data_to_hex(key, var->key, sizeof(var->key), 0);
344         iv[32] = key[32] = '\0';
345         if (strstr(seg->url, "://"))
346             snprintf(url, sizeof(url), "crypto+%s", seg->url);
347         else
348             snprintf(url, sizeof(url), "crypto:%s", seg->url);
349         if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ)) < 0)
350             return ret;
351         av_set_string3(var->input->priv_data, "key", key, 0, NULL);
352         av_set_string3(var->input->priv_data, "iv", iv, 0, NULL);
353         if ((ret = ffurl_connect(var->input)) < 0) {
354             ffurl_close(var->input);
355             var->input = NULL;
356             return ret;
357         }
358         return 0;
359     }
360     return AVERROR(ENOSYS);
361 }
362
363 static int read_data(void *opaque, uint8_t *buf, int buf_size)
364 {
365     struct variant *v = opaque;
366     AppleHTTPContext *c = v->parent->priv_data;
367     int ret, i;
368
369 restart:
370     if (!v->input) {
371 reload:
372         /* If this is a live stream and target_duration has elapsed since
373          * the last playlist reload, reload the variant playlists now. */
374         if (!v->finished &&
375             av_gettime() - v->last_load_time >= v->target_duration*1000000 &&
376             (ret = parse_playlist(c, v->url, v, NULL)) < 0)
377                 return ret;
378         if (v->cur_seq_no < v->start_seq_no) {
379             av_log(NULL, AV_LOG_WARNING,
380                    "skipping %d segments ahead, expired from playlists\n",
381                    v->start_seq_no - v->cur_seq_no);
382             v->cur_seq_no = v->start_seq_no;
383         }
384         if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
385             if (v->finished)
386                 return AVERROR_EOF;
387             while (av_gettime() - v->last_load_time <
388                    v->target_duration*1000000) {
389                 if (url_interrupt_cb())
390                     return AVERROR_EXIT;
391                 usleep(100*1000);
392             }
393             /* Enough time has elapsed since the last reload */
394             goto reload;
395         }
396
397         ret = open_input(v);
398         if (ret < 0)
399             return ret;
400     }
401     ret = ffurl_read(v->input, buf, buf_size);
402     if (ret > 0)
403         return ret;
404     if (ret < 0 && ret != AVERROR_EOF)
405         return ret;
406     ffurl_close(v->input);
407     v->input = NULL;
408     v->cur_seq_no++;
409
410     c->end_of_segment = 1;
411     c->cur_seq_no = v->cur_seq_no;
412
413     if (v->ctx) {
414         v->needed = 0;
415         for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
416              i++) {
417             if (v->parent->streams[i]->discard < AVDISCARD_ALL)
418                 v->needed = 1;
419         }
420     }
421     if (!v->needed) {
422         av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
423                v->index);
424         return AVERROR_EOF;
425     }
426     goto restart;
427 }
428
429 static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)
430 {
431     AppleHTTPContext *c = s->priv_data;
432     int ret = 0, i, j, stream_offset = 0;
433
434     if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
435         goto fail;
436
437     if (c->n_variants == 0) {
438         av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
439         ret = AVERROR_EOF;
440         goto fail;
441     }
442     /* If the playlist only contained variants, parse each individual
443      * variant playlist. */
444     if (c->n_variants > 1 || c->variants[0]->n_segments == 0) {
445         for (i = 0; i < c->n_variants; i++) {
446             struct variant *v = c->variants[i];
447             if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
448                 goto fail;
449         }
450     }
451
452     if (c->variants[0]->n_segments == 0) {
453         av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
454         ret = AVERROR_EOF;
455         goto fail;
456     }
457
458     /* If this isn't a live stream, calculate the total duration of the
459      * stream. */
460     if (c->variants[0]->finished) {
461         int64_t duration = 0;
462         for (i = 0; i < c->variants[0]->n_segments; i++)
463             duration += c->variants[0]->segments[i]->duration;
464         s->duration = duration * AV_TIME_BASE;
465     }
466
467     /* Open the demuxer for each variant */
468     for (i = 0; i < c->n_variants; i++) {
469         struct variant *v = c->variants[i];
470         AVInputFormat *in_fmt = NULL;
471         char bitrate_str[20];
472         if (v->n_segments == 0)
473             continue;
474
475         v->index  = i;
476         v->needed = 1;
477         v->parent = s;
478
479         /* If this is a live stream with more than 3 segments, start at the
480          * third last segment. */
481         v->cur_seq_no = v->start_seq_no;
482         if (!v->finished && v->n_segments > 3)
483             v->cur_seq_no = v->start_seq_no + v->n_segments - 3;
484
485         v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
486         ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, v,
487                           read_data, NULL, NULL);
488         v->pb.seekable = 0;
489         ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url,
490                                     NULL, 0, 0);
491         if (ret < 0)
492             goto fail;
493         ret = av_open_input_stream(&v->ctx, &v->pb, v->segments[0]->url,
494                                    in_fmt, NULL);
495         if (ret < 0)
496             goto fail;
497         v->stream_offset = stream_offset;
498         snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
499         /* Create new AVStreams for each stream in this variant */
500         for (j = 0; j < v->ctx->nb_streams; j++) {
501             AVStream *st = av_new_stream(s, i);
502             if (!st) {
503                 ret = AVERROR(ENOMEM);
504                 goto fail;
505             }
506             avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
507             if (v->bandwidth)
508                 av_metadata_set2(&st->metadata, "variant_bitrate", bitrate_str,
509                                  0);
510         }
511         stream_offset += v->ctx->nb_streams;
512     }
513
514     c->first_packet = 1;
515
516     return 0;
517 fail:
518     free_variant_list(c);
519     return ret;
520 }
521
522 static int recheck_discard_flags(AVFormatContext *s, int first)
523 {
524     AppleHTTPContext *c = s->priv_data;
525     int i, changed = 0;
526
527     /* Check if any new streams are needed */
528     for (i = 0; i < c->n_variants; i++)
529         c->variants[i]->cur_needed = 0;;
530
531     for (i = 0; i < s->nb_streams; i++) {
532         AVStream *st = s->streams[i];
533         struct variant *var = c->variants[s->streams[i]->id];
534         if (st->discard < AVDISCARD_ALL)
535             var->cur_needed = 1;
536     }
537     for (i = 0; i < c->n_variants; i++) {
538         struct variant *v = c->variants[i];
539         if (v->cur_needed && !v->needed) {
540             v->needed = 1;
541             changed = 1;
542             v->cur_seq_no = c->cur_seq_no;
543             v->pb.eof_reached = 0;
544             av_log(s, AV_LOG_INFO, "Now receiving variant %d\n", i);
545         } else if (first && !v->cur_needed && v->needed) {
546             if (v->input)
547                 ffurl_close(v->input);
548             v->input = NULL;
549             v->needed = 0;
550             changed = 1;
551             av_log(s, AV_LOG_INFO, "No longer receiving variant %d\n", i);
552         }
553     }
554     return changed;
555 }
556
557 static int applehttp_read_packet(AVFormatContext *s, AVPacket *pkt)
558 {
559     AppleHTTPContext *c = s->priv_data;
560     int ret, i, minvariant = -1;
561
562     if (c->first_packet) {
563         recheck_discard_flags(s, 1);
564         c->first_packet = 0;
565     }
566
567 start:
568     c->end_of_segment = 0;
569     for (i = 0; i < c->n_variants; i++) {
570         struct variant *var = c->variants[i];
571         /* Make sure we've got one buffered packet from each open variant
572          * stream */
573         if (var->needed && !var->pkt.data) {
574             ret = av_read_frame(var->ctx, &var->pkt);
575             if (ret < 0) {
576                 if (!var->pb.eof_reached)
577                     return ret;
578                 reset_packet(&var->pkt);
579             }
580         }
581         /* Check if this stream has the packet with the lowest dts */
582         if (var->pkt.data) {
583             if (minvariant < 0 ||
584                 var->pkt.dts < c->variants[minvariant]->pkt.dts)
585                 minvariant = i;
586         }
587     }
588     if (c->end_of_segment) {
589         if (recheck_discard_flags(s, 0))
590             goto start;
591     }
592     /* If we got a packet, return it */
593     if (minvariant >= 0) {
594         *pkt = c->variants[minvariant]->pkt;
595         pkt->stream_index += c->variants[minvariant]->stream_offset;
596         reset_packet(&c->variants[minvariant]->pkt);
597         return 0;
598     }
599     return AVERROR_EOF;
600 }
601
602 static int applehttp_close(AVFormatContext *s)
603 {
604     AppleHTTPContext *c = s->priv_data;
605
606     free_variant_list(c);
607     return 0;
608 }
609
610 static int applehttp_read_seek(AVFormatContext *s, int stream_index,
611                                int64_t timestamp, int flags)
612 {
613     AppleHTTPContext *c = s->priv_data;
614     int i, j, ret;
615
616     if ((flags & AVSEEK_FLAG_BYTE) || !c->variants[0]->finished)
617         return AVERROR(ENOSYS);
618
619     timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
620                                s->streams[stream_index]->time_base.den :
621                                AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
622                                AV_ROUND_DOWN : AV_ROUND_UP);
623     ret = AVERROR(EIO);
624     for (i = 0; i < c->n_variants; i++) {
625         /* Reset reading */
626         struct variant *var = c->variants[i];
627         int64_t pos = 0;
628         if (var->input) {
629             ffurl_close(var->input);
630             var->input = NULL;
631         }
632         av_free_packet(&var->pkt);
633         reset_packet(&var->pkt);
634         var->pb.eof_reached = 0;
635
636         /* Locate the segment that contains the target timestamp */
637         for (j = 0; j < var->n_segments; j++) {
638             if (timestamp >= pos &&
639                 timestamp < pos + var->segments[j]->duration) {
640                 var->cur_seq_no = var->start_seq_no + j;
641                 ret = 0;
642                 break;
643             }
644             pos += var->segments[j]->duration;
645         }
646     }
647     return ret;
648 }
649
650 static int applehttp_probe(AVProbeData *p)
651 {
652     /* Require #EXTM3U at the start, and either one of the ones below
653      * somewhere for a proper match. */
654     if (strncmp(p->buf, "#EXTM3U", 7))
655         return 0;
656     if (strstr(p->buf, "#EXT-X-STREAM-INF:")     ||
657         strstr(p->buf, "#EXT-X-TARGETDURATION:") ||
658         strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:"))
659         return AVPROBE_SCORE_MAX;
660     return 0;
661 }
662
663 AVInputFormat ff_applehttp_demuxer = {
664     "applehttp",
665     NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming format"),
666     sizeof(AppleHTTPContext),
667     applehttp_probe,
668     applehttp_read_header,
669     applehttp_read_packet,
670     applehttp_close,
671     applehttp_read_seek,
672 };