hls.c 24.1 KB
Newer Older
1 2 3 4
/*
 * Apple HTTP Live Streaming demuxer
 * Copyright (c) 2010 Martin Storsjo
 *
5
 * This file is part of Libav.
6
 *
7
 * Libav is free software; you can redistribute it and/or
8 9 10 11
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
12
 * Libav is distributed in the hope that it will be useful,
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * 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 20 21 22 23 24 25 26 27 28
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Apple HTTP Live Streaming demuxer
 * http://tools.ietf.org/html/draft-pantos-http-live-streaming
 */

#include "libavutil/avstring.h"
29
#include "libavutil/intreadwrite.h"
30
#include "libavutil/mathematics.h"
31
#include "libavutil/opt.h"
32
#include "libavutil/dict.h"
33
#include "libavutil/time.h"
34 35
#include "avformat.h"
#include "internal.h"
36
#include "avio_internal.h"
37
#include "url.h"
38 39

#define INITIAL_BUFFER_SIZE 32768
40 41 42 43 44 45 46 47 48 49 50 51 52

/*
 * An apple http stream consists of a playlist with media segment files,
 * played sequentially. There may be several playlists with the same
 * video content, in different bandwidth variants, that are played in
 * parallel (preferrably only one bandwidth variant at a time). In this case,
 * the user supplied the url to a main playlist that only lists the variant
 * playlists.
 *
 * If the main playlist doesn't point at any variants, we still create
 * one anonymous toplevel variant for this, to maintain the structure.
 */

53 54 55 56 57
enum KeyType {
    KEY_NONE,
    KEY_AES_128,
};

58 59 60
struct segment {
    int duration;
    char url[MAX_URL_SIZE];
61 62 63
    char key[MAX_URL_SIZE];
    enum KeyType key_type;
    uint8_t iv[16];
64 65 66 67
};

/*
 * Each variant has its own demuxer. If it currently is active,
68
 * it has an open AVIOContext too, and potentially an AVPacket
69 70 71 72 73
 * containing the next packet from this stream.
 */
struct variant {
    int bandwidth;
    char url[MAX_URL_SIZE];
74 75 76 77 78
    AVIOContext pb;
    uint8_t* read_buffer;
    URLContext *input;
    AVFormatContext *parent;
    int index;
79 80 81 82
    AVFormatContext *ctx;
    AVPacket pkt;
    int stream_offset;

83 84
    int finished;
    int target_duration;
85 86 87
    int start_seq_no;
    int n_segments;
    struct segment **segments;
88 89 90
    int needed, cur_needed;
    int cur_seq_no;
    int64_t last_load_time;
91 92 93

    char key_url[MAX_URL_SIZE];
    uint8_t key[16];
94 95
};

96
typedef struct HLSContext {
97 98 99
    int n_variants;
    struct variant **variants;
    int cur_seq_no;
100 101
    int end_of_segment;
    int first_packet;
102
    int64_t first_timestamp;
103 104
    int64_t seek_timestamp;
    int seek_flags;
105
    AVIOInterruptCB *interrupt_callback;
106
} HLSContext;
107

108
static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
{
    int len = ff_get_line(s, buf, maxlen);
    while (len > 0 && isspace(buf[len - 1]))
        buf[--len] = '\0';
    return len;
}

static void free_segment_list(struct variant *var)
{
    int i;
    for (i = 0; i < var->n_segments; i++)
        av_free(var->segments[i]);
    av_freep(&var->segments);
    var->n_segments = 0;
}

125
static void free_variant_list(HLSContext *c)
126 127 128 129 130 131
{
    int i;
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        free_segment_list(var);
        av_free_packet(&var->pkt);
132 133
        av_free(var->pb.buffer);
        if (var->input)
134
            ffurl_close(var->input);
135 136
        if (var->ctx) {
            var->ctx->pb = NULL;
137
            avformat_close_input(&var->ctx);
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
        }
        av_free(var);
    }
    av_freep(&c->variants);
    c->n_variants = 0;
}

/*
 * Used to reset a statically allocated AVPacket to a clean slate,
 * containing no data.
 */
static void reset_packet(AVPacket *pkt)
{
    av_init_packet(pkt);
    pkt->data = NULL;
}

155
static struct variant *new_variant(HLSContext *c, int bandwidth,
156 157 158 159 160 161 162
                                   const char *url, const char *base)
{
    struct variant *var = av_mallocz(sizeof(struct variant));
    if (!var)
        return NULL;
    reset_packet(&var->pkt);
    var->bandwidth = bandwidth;
163
    ff_make_absolute_url(var->url, sizeof(var->url), base, url);
164 165 166 167 168 169 170 171 172 173 174
    dynarray_add(&c->variants, &c->n_variants, var);
    return var;
}

struct variant_info {
    char bandwidth[20];
};

static void handle_variant_args(struct variant_info *info, const char *key,
                                int key_len, char **dest, int *dest_len)
{
175
    if (!strncmp(key, "BANDWIDTH=", key_len)) {
176 177 178 179 180
        *dest     =        info->bandwidth;
        *dest_len = sizeof(info->bandwidth);
    }
}

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
struct key_info {
     char uri[MAX_URL_SIZE];
     char method[10];
     char iv[35];
};

static void handle_key_args(struct key_info *info, const char *key,
                            int key_len, char **dest, int *dest_len)
{
    if (!strncmp(key, "METHOD=", key_len)) {
        *dest     =        info->method;
        *dest_len = sizeof(info->method);
    } else if (!strncmp(key, "URI=", key_len)) {
        *dest     =        info->uri;
        *dest_len = sizeof(info->uri);
    } else if (!strncmp(key, "IV=", key_len)) {
        *dest     =        info->iv;
        *dest_len = sizeof(info->iv);
    }
}

202
static int parse_playlist(HLSContext *c, const char *url,
203
                          struct variant *var, AVIOContext *in)
204 205
{
    int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0;
206 207 208
    enum KeyType key_type = KEY_NONE;
    uint8_t iv[16] = "";
    int has_iv = 0;
209
    char key[MAX_URL_SIZE] = "";
210 211 212 213 214 215
    char line[1024];
    const char *ptr;
    int close_in = 0;

    if (!in) {
        close_in = 1;
216 217
        if ((ret = avio_open2(&in, url, AVIO_FLAG_READ,
                              c->interrupt_callback, NULL)) < 0)
218 219 220 221 222 223 224 225 226
            return ret;
    }

    read_chomp_line(in, line, sizeof(line));
    if (strcmp(line, "#EXTM3U")) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

227
    if (var) {
228
        free_segment_list(var);
229 230
        var->finished = 0;
    }
Anton Khirnov's avatar
Anton Khirnov committed
231
    while (!in->eof_reached) {
232 233 234 235 236 237 238
        read_chomp_line(in, line, sizeof(line));
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
            struct variant_info info = {{0}};
            is_variant = 1;
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
                               &info);
            bandwidth = atoi(info.bandwidth);
239 240 241 242 243 244 245 246 247 248 249 250 251
        } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
            struct key_info info = {{0}};
            ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
                               &info);
            key_type = KEY_NONE;
            has_iv = 0;
            if (!strcmp(info.method, "AES-128"))
                key_type = KEY_AES_128;
            if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
                ff_hex_to_data(iv, info.iv + 2);
                has_iv = 1;
            }
            av_strlcpy(key, info.uri, sizeof(key));
252
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
253 254 255 256 257 258 259 260
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->target_duration = atoi(ptr);
261 262 263 264 265 266 267 268 269 270
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
            if (!var) {
                var = new_variant(c, 0, url, NULL);
                if (!var) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
            }
            var->start_seq_no = atoi(ptr);
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
271 272
            if (var)
                var->finished = 1;
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
            is_segment = 1;
            duration   = atoi(ptr);
        } else if (av_strstart(line, "#", NULL)) {
            continue;
        } else if (line[0]) {
            if (is_variant) {
                if (!new_variant(c, bandwidth, line, url)) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                is_variant = 0;
                bandwidth  = 0;
            }
            if (is_segment) {
                struct segment *seg;
                if (!var) {
                    var = new_variant(c, 0, url, NULL);
                    if (!var) {
                        ret = AVERROR(ENOMEM);
                        goto fail;
                    }
                }
                seg = av_malloc(sizeof(struct segment));
                if (!seg) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                seg->duration = duration;
302 303 304 305 306 307 308 309 310
                seg->key_type = key_type;
                if (has_iv) {
                    memcpy(seg->iv, iv, sizeof(iv));
                } else {
                    int seq = var->start_seq_no + var->n_segments;
                    memset(seg->iv, 0, sizeof(seg->iv));
                    AV_WB32(seg->iv + 12, seq);
                }
                ff_make_absolute_url(seg->key, sizeof(seg->key), url, key);
311
                ff_make_absolute_url(seg->url, sizeof(seg->url), url, line);
312 313 314 315 316
                dynarray_add(&var->segments, &var->n_segments, seg);
                is_segment = 0;
            }
        }
    }
317 318
    if (var)
        var->last_load_time = av_gettime();
319 320 321

fail:
    if (close_in)
322
        avio_close(in);
323 324 325
    return ret;
}

326 327 328 329
static int open_input(struct variant *var)
{
    struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
    if (seg->key_type == KEY_NONE) {
330
        return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ,
331
                          &var->parent->interrupt_callback, NULL);
332 333 334 335 336
    } else if (seg->key_type == KEY_AES_128) {
        char iv[33], key[33], url[MAX_URL_SIZE];
        int ret;
        if (strcmp(seg->key, var->key_url)) {
            URLContext *uc;
337
            if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ,
338
                           &var->parent->interrupt_callback, NULL) == 0) {
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
                if (ffurl_read_complete(uc, var->key, sizeof(var->key))
                    != sizeof(var->key)) {
                    av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
                           seg->key);
                }
                ffurl_close(uc);
            } else {
                av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
                       seg->key);
            }
            av_strlcpy(var->key_url, seg->key, sizeof(var->key_url));
        }
        ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
        ff_data_to_hex(key, var->key, sizeof(var->key), 0);
        iv[32] = key[32] = '\0';
        if (strstr(seg->url, "://"))
            snprintf(url, sizeof(url), "crypto+%s", seg->url);
        else
            snprintf(url, sizeof(url), "crypto:%s", seg->url);
358 359
        if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ,
                               &var->parent->interrupt_callback)) < 0)
360
            return ret;
361 362
        av_opt_set(var->input->priv_data, "key", key, 0);
        av_opt_set(var->input->priv_data, "iv", iv, 0);
363
        if ((ret = ffurl_connect(var->input, NULL)) < 0) {
364 365 366 367 368 369 370 371 372
            ffurl_close(var->input);
            var->input = NULL;
            return ret;
        }
        return 0;
    }
    return AVERROR(ENOSYS);
}

373 374 375
static int read_data(void *opaque, uint8_t *buf, int buf_size)
{
    struct variant *v = opaque;
376
    HLSContext *c = v->parent->priv_data;
377 378 379 380
    int ret, i;

restart:
    if (!v->input) {
381
        /* If this is a live stream and the reload interval has elapsed since
382
         * the last playlist reload, reload the variant playlists now. */
383 384 385 386 387
        int64_t reload_interval = v->n_segments > 0 ?
                                  v->segments[v->n_segments - 1]->duration :
                                  v->target_duration;
        reload_interval *= 1000000;

388
reload:
389
        if (!v->finished &&
390 391
            av_gettime() - v->last_load_time >= reload_interval) {
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
392
                return ret;
393 394 395 396 397
            /* If we need to reload the playlist again below (if
             * there's still no more segments), switch to a reload
             * interval of half the target duration. */
            reload_interval = v->target_duration * 500000;
        }
398 399 400 401 402 403 404 405 406
        if (v->cur_seq_no < v->start_seq_no) {
            av_log(NULL, AV_LOG_WARNING,
                   "skipping %d segments ahead, expired from playlists\n",
                   v->start_seq_no - v->cur_seq_no);
            v->cur_seq_no = v->start_seq_no;
        }
        if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
            if (v->finished)
                return AVERROR_EOF;
407
            while (av_gettime() - v->last_load_time < reload_interval) {
408
                if (ff_check_interrupt(c->interrupt_callback))
409
                    return AVERROR_EXIT;
410
                av_usleep(100*1000);
411 412 413 414 415
            }
            /* Enough time has elapsed since the last reload */
            goto reload;
        }

416
        ret = open_input(v);
417 418 419
        if (ret < 0)
            return ret;
    }
420
    ret = ffurl_read(v->input, buf, buf_size);
421 422
    if (ret > 0)
        return ret;
423
    ffurl_close(v->input);
424 425 426 427 428 429
    v->input = NULL;
    v->cur_seq_no++;

    c->end_of_segment = 1;
    c->cur_seq_no = v->cur_seq_no;

430
    if (v->ctx && v->ctx->nb_streams) {
431 432 433 434 435 436
        v->needed = 0;
        for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
             i++) {
            if (v->parent->streams[i]->discard < AVDISCARD_ALL)
                v->needed = 1;
        }
437 438 439 440 441 442 443 444 445
    }
    if (!v->needed) {
        av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n",
               v->index);
        return AVERROR_EOF;
    }
    goto restart;
}

446
static int hls_read_header(AVFormatContext *s)
447
{
448
    HLSContext *c = s->priv_data;
449 450
    int ret = 0, i, j, stream_offset = 0;

451 452
    c->interrupt_callback = &s->interrupt_callback;

453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
    if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
        goto fail;

    if (c->n_variants == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }
    /* If the playlist only contained variants, parse each individual
     * variant playlist. */
    if (c->n_variants > 1 || c->variants[0]->n_segments == 0) {
        for (i = 0; i < c->n_variants; i++) {
            struct variant *v = c->variants[i];
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)
                goto fail;
        }
    }

    if (c->variants[0]->n_segments == 0) {
        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
        ret = AVERROR_EOF;
        goto fail;
    }

    /* If this isn't a live stream, calculate the total duration of the
     * stream. */
479
    if (c->variants[0]->finished) {
480
        int64_t duration = 0;
481 482 483 484 485 486 487 488
        for (i = 0; i < c->variants[0]->n_segments; i++)
            duration += c->variants[0]->segments[i]->duration;
        s->duration = duration * AV_TIME_BASE;
    }

    /* Open the demuxer for each variant */
    for (i = 0; i < c->n_variants; i++) {
        struct variant *v = c->variants[i];
489
        AVInputFormat *in_fmt = NULL;
490
        char bitrate_str[20];
491 492
        if (v->n_segments == 0)
            continue;
493

494 495 496 497 498
        if (!(v->ctx = avformat_alloc_context())) {
            ret = AVERROR(ENOMEM);
            goto fail;
        }

499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
        v->index  = i;
        v->needed = 1;
        v->parent = s;

        /* If this is a live stream with more than 3 segments, start at the
         * third last segment. */
        v->cur_seq_no = v->start_seq_no;
        if (!v->finished && v->n_segments > 3)
            v->cur_seq_no = v->start_seq_no + v->n_segments - 3;

        v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
        ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, v,
                          read_data, NULL, NULL);
        v->pb.seekable = 0;
        ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url,
                                    NULL, 0, 0);
515 516 517 518 519 520 521
        if (ret < 0) {
            /* Free the ctx - it isn't initialized properly at this point,
             * so avformat_close_input shouldn't be called. If
             * avformat_open_input fails below, it frees and zeros the
             * context, so it doesn't need any special treatment like this. */
            avformat_free_context(v->ctx);
            v->ctx = NULL;
522
            goto fail;
523
        }
524 525
        v->ctx->pb       = &v->pb;
        ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
526 527 528
        if (ret < 0)
            goto fail;
        v->stream_offset = stream_offset;
529
        snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
530 531
        /* Create new AVStreams for each stream in this variant */
        for (j = 0; j < v->ctx->nb_streams; j++) {
532
            AVStream *st = avformat_new_stream(s, NULL);
533 534 535 536
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
537
            st->id = i;
538
            avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);
539
            if (v->bandwidth)
540
                av_dict_set(&st->metadata, "variant_bitrate", bitrate_str,
541
                                 0);
542 543 544 545
        }
        stream_offset += v->ctx->nb_streams;
    }

546
    c->first_packet = 1;
547
    c->first_timestamp = AV_NOPTS_VALUE;
548
    c->seek_timestamp  = AV_NOPTS_VALUE;
549 550 551 552 553 554 555

    return 0;
fail:
    free_variant_list(c);
    return ret;
}

556
static int recheck_discard_flags(AVFormatContext *s, int first)
557
{
558
    HLSContext *c = s->priv_data;
559
    int i, changed = 0;
560

561 562 563 564 565 566 567 568 569
    /* Check if any new streams are needed */
    for (i = 0; i < c->n_variants; i++)
        c->variants[i]->cur_needed = 0;;

    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
        struct variant *var = c->variants[s->streams[i]->id];
        if (st->discard < AVDISCARD_ALL)
            var->cur_needed = 1;
570
    }
571 572 573 574 575 576 577 578 579 580
    for (i = 0; i < c->n_variants; i++) {
        struct variant *v = c->variants[i];
        if (v->cur_needed && !v->needed) {
            v->needed = 1;
            changed = 1;
            v->cur_seq_no = c->cur_seq_no;
            v->pb.eof_reached = 0;
            av_log(s, AV_LOG_INFO, "Now receiving variant %d\n", i);
        } else if (first && !v->cur_needed && v->needed) {
            if (v->input)
581
                ffurl_close(v->input);
582 583 584 585
            v->input = NULL;
            v->needed = 0;
            changed = 1;
            av_log(s, AV_LOG_INFO, "No longer receiving variant %d\n", i);
586 587
        }
    }
588
    return changed;
589 590
}

591
static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
592
{
593
    HLSContext *c = s->priv_data;
594
    int ret, i, minvariant = -1;
595

596 597 598
    if (c->first_packet) {
        recheck_discard_flags(s, 1);
        c->first_packet = 0;
599
    }
600

601
start:
602
    c->end_of_segment = 0;
603 604 605 606
    for (i = 0; i < c->n_variants; i++) {
        struct variant *var = c->variants[i];
        /* Make sure we've got one buffered packet from each open variant
         * stream */
607
        if (var->needed && !var->pkt.data) {
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638
            while (1) {
                int64_t ts_diff;
                AVStream *st;
                ret = av_read_frame(var->ctx, &var->pkt);
                if (ret < 0) {
                    if (!var->pb.eof_reached)
                        return ret;
                    reset_packet(&var->pkt);
                    break;
                } else {
                    if (c->first_timestamp == AV_NOPTS_VALUE)
                        c->first_timestamp = var->pkt.dts;
                }

                if (c->seek_timestamp == AV_NOPTS_VALUE)
                    break;

                if (var->pkt.dts == AV_NOPTS_VALUE) {
                    c->seek_timestamp = AV_NOPTS_VALUE;
                    break;
                }

                st = var->ctx->streams[var->pkt.stream_index];
                ts_diff = av_rescale_rnd(var->pkt.dts, AV_TIME_BASE,
                                         st->time_base.den, AV_ROUND_DOWN) -
                          c->seek_timestamp;
                if (ts_diff >= 0 && (c->seek_flags  & AVSEEK_FLAG_ANY ||
                                     var->pkt.flags & AV_PKT_FLAG_KEY)) {
                    c->seek_timestamp = AV_NOPTS_VALUE;
                    break;
                }
639 640 641 642 643 644 645 646 647
            }
        }
        /* Check if this stream has the packet with the lowest dts */
        if (var->pkt.data) {
            if (minvariant < 0 ||
                var->pkt.dts < c->variants[minvariant]->pkt.dts)
                minvariant = i;
        }
    }
648 649 650 651
    if (c->end_of_segment) {
        if (recheck_discard_flags(s, 0))
            goto start;
    }
652 653 654 655 656 657 658
    /* If we got a packet, return it */
    if (minvariant >= 0) {
        *pkt = c->variants[minvariant]->pkt;
        pkt->stream_index += c->variants[minvariant]->stream_offset;
        reset_packet(&c->variants[minvariant]->pkt);
        return 0;
    }
659
    return AVERROR_EOF;
660 661
}

662
static int hls_close(AVFormatContext *s)
663
{
664
    HLSContext *c = s->priv_data;
665 666 667 668 669

    free_variant_list(c);
    return 0;
}

670
static int hls_read_seek(AVFormatContext *s, int stream_index,
671 672
                               int64_t timestamp, int flags)
{
673
    HLSContext *c = s->priv_data;
674
    int i, j, ret;
675

676
    if ((flags & AVSEEK_FLAG_BYTE) || !c->variants[0]->finished)
677 678
        return AVERROR(ENOSYS);

679 680 681 682 683 684
    c->seek_flags     = flags;
    c->seek_timestamp = stream_index < 0 ? timestamp :
                        av_rescale_rnd(timestamp, AV_TIME_BASE,
                                       s->streams[stream_index]->time_base.den,
                                       flags & AVSEEK_FLAG_BACKWARD ?
                                       AV_ROUND_DOWN : AV_ROUND_UP);
685 686 687 688
    timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ?
                               s->streams[stream_index]->time_base.den :
                               AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
                               AV_ROUND_DOWN : AV_ROUND_UP);
689 690 691 692 693
    if (s->duration < c->seek_timestamp) {
        c->seek_timestamp = AV_NOPTS_VALUE;
        return AVERROR(EIO);
    }

694
    ret = AVERROR(EIO);
695
    for (i = 0; i < c->n_variants; i++) {
696
        /* Reset reading */
697
        struct variant *var = c->variants[i];
698 699 700 701
        int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
                      av_rescale_rnd(c->first_timestamp, 1,
                          stream_index >= 0 ? s->streams[stream_index]->time_base.den : AV_TIME_BASE,
                          flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
702
        if (var->input) {
703
            ffurl_close(var->input);
704
            var->input = NULL;
705 706 707
        }
        av_free_packet(&var->pkt);
        reset_packet(&var->pkt);
708
        var->pb.eof_reached = 0;
709 710 711 712
        /* Clear any buffered data */
        var->pb.buf_end = var->pb.buf_ptr = var->pb.buffer;
        /* Reset the pos, to let the mpegts demuxer know we've seeked. */
        var->pb.pos = 0;
713

714 715 716 717 718 719 720 721 722
        /* Locate the segment that contains the target timestamp */
        for (j = 0; j < var->n_segments; j++) {
            if (timestamp >= pos &&
                timestamp < pos + var->segments[j]->duration) {
                var->cur_seq_no = var->start_seq_no + j;
                ret = 0;
                break;
            }
            pos += var->segments[j]->duration;
723
        }
724 725
        if (ret)
            c->seek_timestamp = AV_NOPTS_VALUE;
726
    }
727
    return ret;
728 729
}

730
static int hls_probe(AVProbeData *p)
731 732 733 734 735 736 737 738 739 740 741 742
{
    /* Require #EXTM3U at the start, and either one of the ones below
     * somewhere for a proper match. */
    if (strncmp(p->buf, "#EXTM3U", 7))
        return 0;
    if (strstr(p->buf, "#EXT-X-STREAM-INF:")     ||
        strstr(p->buf, "#EXT-X-TARGETDURATION:") ||
        strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:"))
        return AVPROBE_SCORE_MAX;
    return 0;
}

743
AVInputFormat ff_hls_demuxer = {
744
    .name           = "hls,applehttp",
745
    .long_name      = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
746 747 748 749 750 751
    .priv_data_size = sizeof(HLSContext),
    .read_probe     = hls_probe,
    .read_header    = hls_read_header,
    .read_packet    = hls_read_packet,
    .read_close     = hls_close,
    .read_seek      = hls_read_seek,
752
};