Coverage Report

Created: 2026-10-28 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/hls.c
Line
Count
Source
1
/*
2
 * Apple HTTP Live Streaming demuxer
3
 * Copyright (c) 2010 Martin Storsjo
4
 * Copyright (c) 2013 Anssi Hannula
5
 * Copyright (c) 2021 Nachiket Tarate
6
 *
7
 * This file is part of FFmpeg.
8
 *
9
 * FFmpeg is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * FFmpeg 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 GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with FFmpeg; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 */
23
24
/**
25
 * @file
26
 * Apple HTTP Live Streaming demuxer
27
 * https://www.rfc-editor.org/rfc/rfc8216.txt
28
 */
29
30
#include "config_components.h"
31
32
#include "libavformat/http.h"
33
#include "libavutil/aes.h"
34
#include "libavutil/avstring.h"
35
#include "libavutil/avassert.h"
36
#include "libavutil/intreadwrite.h"
37
#include "libavutil/mathematics.h"
38
#include "libavutil/mem.h"
39
#include "libavutil/opt.h"
40
#include "libavutil/dict.h"
41
#include "libavutil/time.h"
42
#include "libavutil/tree.h"
43
#include "avformat.h"
44
#include "demux.h"
45
#include "internal.h"
46
#include "avio_internal.h"
47
#include "id3v2.h"
48
#include "url.h"
49
50
#include "hls_sample_encryption.h"
51
52
431
#define INITIAL_BUFFER_SIZE 32768
53
54
#define MAX_FIELD_LEN 64
55
#define MAX_CHARACTERISTICS_LEN 512
56
57
0
#define MPEG_TIME_BASE 90000
58
0
#define MPEG_TIME_BASE_Q (AVRational){1, MPEG_TIME_BASE}
59
60
0
#define PACKED_AUDIO_FORMATS "aac,ac3,eac3,mp3"
61
62
/*
63
 * An apple http stream consists of a playlist with media segment files,
64
 * played sequentially. There may be several playlists with the same
65
 * video content, in different bandwidth variants, that are played in
66
 * parallel (preferably only one bandwidth variant at a time). In this case,
67
 * the user supplied the url to a main playlist that only lists the variant
68
 * playlists.
69
 *
70
 * If the main playlist doesn't point at any variants, we still create
71
 * one anonymous toplevel variant for this, to maintain the structure.
72
 */
73
74
enum KeyType {
75
    KEY_NONE,
76
    KEY_AES_128,
77
    KEY_SAMPLE_AES
78
};
79
80
struct segment {
81
    int64_t duration;
82
    int64_t url_offset;
83
    int64_t size;
84
    char *url;
85
    char *key;
86
    enum KeyType key_type;
87
    uint8_t iv[16];
88
    /* associated Media Initialization Section, treated as a segment */
89
    struct segment *init_section;
90
};
91
92
struct rendition;
93
struct rendition_group;
94
struct variant;
95
96
enum PlaylistType {
97
    PLS_TYPE_UNSPECIFIED,
98
    PLS_TYPE_EVENT,
99
    PLS_TYPE_VOD
100
};
101
102
/*
103
 * Each playlist has its own demuxer. If it currently is active,
104
 * it has an open AVIOContext too, and potentially an AVPacket
105
 * containing the next packet from this stream.
106
 */
107
struct playlist {
108
    char url[MAX_URL_SIZE];
109
    FFIOContext pb;
110
    AVIOContext *input;
111
    int input_read_done;
112
    int64_t input_end; /* end of the byte range requested on input, or -1 */
113
    AVIOContext *input_next;
114
    int input_next_requested;
115
    int64_t input_next_end;
116
    AVFormatContext *parent;
117
    int index;
118
    AVFormatContext *ctx;
119
    AVPacket *pkt;
120
    int has_noheader_flag;
121
122
    /* main demuxer streams associated with this playlist
123
     * indexed by the subdemuxer stream indexes */
124
    AVStream **main_streams;
125
    int n_main_streams;
126
127
    int finished;
128
    enum PlaylistType type;
129
    int64_t target_duration;
130
    int64_t start_seq_no;
131
    int time_offset_flag;
132
    int64_t start_time_offset;
133
    int n_segments;
134
    struct segment **segments;
135
    int needed;
136
    int broken;
137
    int64_t cur_seq_no;
138
    int64_t last_seq_no;
139
    int64_t first_read_seq_no;
140
    int m3u8_hold_counters;
141
    int64_t cur_seg_offset;
142
    int64_t last_load_time;
143
144
    /* Currently active Media Initialization Section */
145
    struct segment *cur_init_section;
146
    uint8_t *init_sec_buf;
147
    unsigned int init_sec_buf_size;
148
    unsigned int init_sec_data_len;
149
    unsigned int init_sec_buf_read_offset;
150
151
    char key_url[MAX_URL_SIZE];
152
    uint8_t key[16];
153
154
    /* ID3 timestamp handling (elementary audio streams have ID3 timestamps
155
     * (and possibly other ID3 tags) in the beginning of each segment) */
156
    int is_id3_timestamped; /* -1: not yet known */
157
    int64_t id3_mpegts_timestamp; /* in mpegts tb */
158
    int64_t id3_offset; /* in stream original tb */
159
    uint8_t* id3_buf; /* temp buffer for id3 parsing */
160
    unsigned int id3_buf_size;
161
    AVDictionary *id3_initial; /* data from first id3 tag */
162
    int id3_found; /* ID3 tag found at some point */
163
    int id3_changed; /* ID3 tag data has changed at some point */
164
    ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */
165
166
    HLSAudioSetupInfo audio_setup_info;
167
168
    /* Constant offset of this playlist's DTS baseline relative to
169
     * c->first_timestamp. */
170
    int64_t ts_offset;
171
    int64_t seek_timestamp;
172
    int seek_flags;
173
    int seek_stream_index; /* into subdemuxer stream array */
174
175
    /* Renditions associated with this playlist, if any.
176
     * Alternative rendition playlists have a single rendition associated
177
     * with them, and variant main Media Playlists may have
178
     * multiple (playlist-less) renditions associated with them. */
179
    int n_renditions;
180
    struct rendition **renditions;
181
182
    /* The last variant this playlist was added to and the last rendition
183
     * group whose renditions were added to it. */
184
    struct variant *last_variant;
185
    struct rendition_group *last_group;
186
187
    /* Media Initialization Sections (EXT-X-MAP) associated with this
188
     * playlist, if any. */
189
    int n_init_sections;
190
    struct segment **init_sections;
191
    int is_subtitle; /* Indicates if it's a subtitle playlist */
192
193
    /* Some HLS streams repeat the current timed-ID3 metadata at every segment
194
     * boundary so late-joining clients get a fresh copy. Track the last seen
195
     * value to avoid raising AVSTREAM_EVENT_FLAG_METADATA_UPDATED spuriously
196
     * on those duplicates. timed_id3_stream_index is the subdemuxer stream
197
     * index of the first timed-ID3 stream seen; -1 if none. */
198
    AVDictionary *timed_id3_metadata;
199
    int timed_id3_stream_index;
200
};
201
202
/*
203
 * Renditions are e.g. alternative subtitle or audio streams.
204
 * The rendition may either be an external playlist or it may be
205
 * contained in the main Media Playlist of the variant (in which case
206
 * playlist is NULL).
207
 */
208
struct rendition {
209
    enum AVMediaType type;
210
    struct playlist *playlist;
211
    char language[MAX_FIELD_LEN];
212
    char name[MAX_FIELD_LEN];
213
    int disposition;
214
};
215
216
struct variant {
217
    int bandwidth;
218
219
    /* every variant contains at least the main Media Playlist in index 0 */
220
    int n_playlists;
221
    struct playlist **playlists;
222
223
    char audio_group[MAX_FIELD_LEN];
224
    char video_group[MAX_FIELD_LEN];
225
    char subtitles_group[MAX_FIELD_LEN];
226
};
227
228
/*
229
 * The renditions with the same TYPE and GROUP-ID, which variants reference
230
 * by the group id.
231
 */
232
struct rendition_group {
233
    enum AVMediaType type;
234
    char id[MAX_FIELD_LEN];
235
236
    /* playlists of the external renditions */
237
    int n_playlists;
238
    struct playlist **playlists;
239
240
    /* renditions that are part of the variant main Media Playlists */
241
    int n_renditions;
242
    struct rendition **renditions;
243
244
    /* variants that reference the group */
245
    int n_variants;
246
    struct variant **variants;
247
};
248
249
typedef struct HLSContext {
250
    AVClass *class;
251
    AVFormatContext *ctx;
252
    int n_variants;
253
    struct variant **variants;
254
    int n_playlists;
255
    struct playlist **playlists;
256
    struct AVTreeNode *playlists_by_url;
257
    int n_renditions;
258
    struct rendition **renditions;
259
    int n_rendition_groups;
260
    struct rendition_group **rendition_groups;
261
    struct AVTreeNode *rendition_groups_by_id;
262
263
    int64_t cur_seq_no;
264
    int m3u8_hold_counters;
265
    int live_start_index;
266
    int prefer_x_start;
267
    int master_time_offset_flag; ///< EXT-X-START was set by the Master Playlist
268
    int first_packet;
269
    int64_t first_timestamp;
270
    struct playlist *first_timestamp_pls;
271
    int first_timestamp_locked;
272
    int64_t cur_timestamp;
273
    AVIOInterruptCB *interrupt_callback;
274
    AVDictionary *avio_opts;
275
    AVDictionary *seg_format_opts;
276
    char *allowed_extensions;
277
    char *allowed_segment_extensions;
278
    int extension_picky;
279
    int max_reload;
280
    int http_persistent;
281
    int http_multiple;
282
    int http_seekable;
283
    int seg_max_retry;
284
    AVIOContext *playlist_pb;
285
    HLSCryptoContext  crypto_ctx;
286
} HLSContext;
287
288
static void free_segment_dynarray(struct segment **segments, int n_segments)
289
16.5k
{
290
16.5k
    int i;
291
24.1k
    for (i = 0; i < n_segments; i++) {
292
7.64k
        av_freep(&segments[i]->key);
293
7.64k
        av_freep(&segments[i]->url);
294
7.64k
        av_freep(&segments[i]);
295
7.64k
    }
296
16.5k
}
297
298
static void free_segment_list(struct playlist *pls)
299
11.9k
{
300
11.9k
    free_segment_dynarray(pls->segments, pls->n_segments);
301
11.9k
    av_freep(&pls->segments);
302
11.9k
    pls->n_segments = 0;
303
11.9k
}
304
305
static void free_init_section_list(struct playlist *pls)
306
11.9k
{
307
11.9k
    int i;
308
14.3k
    for (i = 0; i < pls->n_init_sections; i++) {
309
2.36k
        av_freep(&pls->init_sections[i]->key);
310
2.36k
        av_freep(&pls->init_sections[i]->url);
311
2.36k
        av_freep(&pls->init_sections[i]);
312
2.36k
    }
313
11.9k
    av_freep(&pls->init_sections);
314
11.9k
    pls->n_init_sections = 0;
315
11.9k
}
316
317
static void free_playlist_list(HLSContext *c)
318
4.56k
{
319
4.56k
    int i;
320
16.5k
    for (i = 0; i < c->n_playlists; i++) {
321
11.9k
        struct playlist *pls = c->playlists[i];
322
11.9k
        free_segment_list(pls);
323
11.9k
        free_init_section_list(pls);
324
11.9k
        av_freep(&pls->main_streams);
325
11.9k
        av_freep(&pls->renditions);
326
11.9k
        av_freep(&pls->id3_buf);
327
11.9k
        av_dict_free(&pls->id3_initial);
328
11.9k
        av_dict_free(&pls->timed_id3_metadata);
329
11.9k
        ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
330
11.9k
        av_freep(&pls->init_sec_buf);
331
11.9k
        av_packet_free(&pls->pkt);
332
11.9k
        av_freep(&pls->pb.pub.buffer);
333
11.9k
        ff_format_io_close(c->ctx, &pls->input);
334
11.9k
        pls->input_read_done = 0;
335
11.9k
        ff_format_io_close(c->ctx, &pls->input_next);
336
11.9k
        pls->input_next_requested = 0;
337
11.9k
        if (pls->ctx) {
338
9.47k
            pls->ctx->pb = NULL;
339
9.47k
            avformat_close_input(&pls->ctx);
340
9.47k
        }
341
11.9k
        av_free(pls);
342
11.9k
    }
343
4.56k
    av_freep(&c->playlists);
344
4.56k
    c->n_playlists = 0;
345
4.56k
    av_tree_destroy(c->playlists_by_url);
346
4.56k
    c->playlists_by_url = NULL;
347
4.56k
}
348
349
static void free_variant_list(HLSContext *c)
350
4.56k
{
351
4.56k
    int i;
352
288k
    for (i = 0; i < c->n_variants; i++) {
353
284k
        struct variant *var = c->variants[i];
354
284k
        av_freep(&var->playlists);
355
284k
        av_free(var);
356
284k
    }
357
4.56k
    av_freep(&c->variants);
358
4.56k
    c->n_variants = 0;
359
4.56k
}
360
361
static void free_rendition_list(HLSContext *c)
362
4.56k
{
363
4.56k
    int i;
364
30.6k
    for (i = 0; i < c->n_renditions; i++)
365
26.0k
        av_freep(&c->renditions[i]);
366
4.56k
    av_freep(&c->renditions);
367
4.56k
    c->n_renditions = 0;
368
5.76k
    for (i = 0; i < c->n_rendition_groups; i++) {
369
1.20k
        av_freep(&c->rendition_groups[i]->playlists);
370
1.20k
        av_freep(&c->rendition_groups[i]->renditions);
371
1.20k
        av_freep(&c->rendition_groups[i]->variants);
372
1.20k
        av_freep(&c->rendition_groups[i]);
373
1.20k
    }
374
4.56k
    av_freep(&c->rendition_groups);
375
4.56k
    c->n_rendition_groups = 0;
376
4.56k
    av_tree_destroy(c->rendition_groups_by_id);
377
4.56k
    c->rendition_groups_by_id = NULL;
378
4.56k
}
379
380
static int cmp_url_playlist(const void *key, const void *b)
381
801k
{
382
801k
    const struct playlist *pls = b;
383
801k
    return strcmp(key, pls->url);
384
801k
}
385
386
static int cmp_playlist_url(const void *a, const void *b)
387
44.0k
{
388
44.0k
    const struct playlist *pa = a, *pb = b;
389
44.0k
    return strcmp(pa->url, pb->url);
390
44.0k
}
391
392
static struct playlist *new_playlist(HLSContext *c, const char *url,
393
                                     const char *base)
394
289k
{
395
289k
    struct playlist *pls;
396
289k
    struct AVTreeNode *node;
397
289k
    char abs_url[MAX_URL_SIZE];
398
399
289k
    ff_make_absolute_url(abs_url, sizeof(abs_url), base, url);
400
289k
    if (!abs_url[0])
401
40
        return NULL;
402
403
    /* the same URL in several variants or renditions shares one playlist */
404
289k
    pls = av_tree_find(c->playlists_by_url, abs_url, cmp_url_playlist, NULL);
405
289k
    if (pls)
406
277k
        return pls;
407
408
11.9k
    pls  = av_mallocz(sizeof(struct playlist));
409
11.9k
    node = av_tree_node_alloc();
410
11.9k
    if (!pls || !node)
411
0
        goto fail;
412
413
11.9k
    pls->pkt = av_packet_alloc();
414
11.9k
    if (!pls->pkt)
415
0
        goto fail;
416
417
11.9k
    av_strlcpy(pls->url, abs_url, sizeof(pls->url));
418
11.9k
    pls->ts_offset = AV_NOPTS_VALUE;
419
11.9k
    pls->seek_timestamp = AV_NOPTS_VALUE;
420
11.9k
    pls->first_read_seq_no = -1;
421
422
11.9k
    pls->is_id3_timestamped = -1;
423
11.9k
    pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
424
11.9k
    pls->timed_id3_stream_index = -1;
425
426
11.9k
    if (av_dynarray_add_nofree(&c->playlists, &c->n_playlists, pls) < 0)
427
0
        goto fail;
428
11.9k
    av_tree_insert(&c->playlists_by_url, pls, cmp_playlist_url, &node);
429
11.9k
    return pls;
430
431
0
fail:
432
0
    if (pls)
433
0
        av_packet_free(&pls->pkt);
434
0
    av_free(pls);
435
0
    av_free(node);
436
0
    return NULL;
437
11.9k
}
438
439
struct variant_info {
440
    char bandwidth[20];
441
    /* variant group ids: */
442
    char audio[MAX_FIELD_LEN];
443
    char video[MAX_FIELD_LEN];
444
    char subtitles[MAX_FIELD_LEN];
445
};
446
447
static struct variant *new_variant(HLSContext *c, struct variant_info *info,
448
                                   const char *url, const char *base)
449
284k
{
450
284k
    struct variant *var;
451
284k
    struct playlist *pls;
452
453
284k
    pls = new_playlist(c, url, base);
454
284k
    if (!pls)
455
40
        return NULL;
456
457
284k
    var = av_mallocz(sizeof(struct variant));
458
284k
    if (!var)
459
0
        return NULL;
460
461
284k
    if (info) {
462
282k
        var->bandwidth = atoi(info->bandwidth);
463
282k
        strcpy(var->audio_group, info->audio);
464
282k
        strcpy(var->video_group, info->video);
465
282k
        strcpy(var->subtitles_group, info->subtitles);
466
282k
    }
467
468
284k
    dynarray_add(&c->variants, &c->n_variants, var);
469
284k
    dynarray_add(&var->playlists, &var->n_playlists, pls);
470
284k
    return var;
471
284k
}
472
473
static void handle_variant_args(void *context, const char *key,
474
                                int key_len, char **dest, int *dest_len)
475
22.3k
{
476
22.3k
    struct variant_info *info = context;
477
22.3k
    if (!strncmp(key, "BANDWIDTH=", key_len)) {
478
359
        *dest     =        info->bandwidth;
479
359
        *dest_len = sizeof(info->bandwidth);
480
21.9k
    } else if (!strncmp(key, "AUDIO=", key_len)) {
481
1.99k
        *dest     =        info->audio;
482
1.99k
        *dest_len = sizeof(info->audio);
483
19.9k
    } else if (!strncmp(key, "VIDEO=", key_len)) {
484
8.90k
        *dest     =        info->video;
485
8.90k
        *dest_len = sizeof(info->video);
486
11.0k
    } else if (!strncmp(key, "SUBTITLES=", key_len)) {
487
4.66k
        *dest     =        info->subtitles;
488
4.66k
        *dest_len = sizeof(info->subtitles);
489
4.66k
    }
490
22.3k
}
491
492
struct key_info {
493
     char uri[MAX_URL_SIZE];
494
     char method[11];
495
     char iv[35];
496
};
497
498
static void handle_key_args(void *context, const char *key,
499
                            int key_len, char **dest, int *dest_len)
500
5.80k
{
501
5.80k
    struct key_info *info = context;
502
5.80k
    if (!strncmp(key, "METHOD=", key_len)) {
503
1.27k
        *dest     =        info->method;
504
1.27k
        *dest_len = sizeof(info->method);
505
4.53k
    } else if (!strncmp(key, "URI=", key_len)) {
506
459
        *dest     =        info->uri;
507
459
        *dest_len = sizeof(info->uri);
508
4.07k
    } else if (!strncmp(key, "IV=", key_len)) {
509
2.80k
        *dest     =        info->iv;
510
2.80k
        *dest_len = sizeof(info->iv);
511
2.80k
    }
512
5.80k
}
513
514
struct init_section_info {
515
    char uri[MAX_URL_SIZE];
516
    char byterange[32];
517
};
518
519
static struct segment *new_init_section(struct playlist *pls,
520
                                        struct init_section_info *info,
521
                                        const char *url_base)
522
2.48k
{
523
2.48k
    struct segment *sec;
524
2.48k
    char tmp_str[MAX_URL_SIZE], *ptr = tmp_str;
525
526
2.48k
    if (!info->uri[0])
527
80
        return NULL;
528
529
2.40k
    sec = av_mallocz(sizeof(*sec));
530
2.40k
    if (!sec)
531
0
        return NULL;
532
533
2.40k
    if (!av_strncasecmp(info->uri, "data:", 5)) {
534
227
        ptr = info->uri;
535
2.18k
    } else {
536
2.18k
        ff_make_absolute_url(tmp_str, sizeof(tmp_str), url_base, info->uri);
537
2.18k
        if (!tmp_str[0]) {
538
0
            av_free(sec);
539
0
            return NULL;
540
0
        }
541
2.18k
    }
542
2.40k
    sec->url = av_strdup(ptr);
543
2.40k
    if (!sec->url) {
544
0
        av_free(sec);
545
0
        return NULL;
546
0
    }
547
548
2.40k
    if (info->byterange[0]) {
549
987
        sec->size = strtoll(info->byterange, NULL, 10);
550
987
        ptr = strchr(info->byterange, '@');
551
987
        if (ptr)
552
596
            sec->url_offset = strtoll(ptr+1, NULL, 10);
553
987
        if (sec->size < 0 || sec->url_offset < 0 || sec->size > INT64_MAX - sec->url_offset) {
554
41
            av_freep(&sec->url);
555
41
            av_free(sec);
556
41
            return NULL;
557
41
        }
558
1.42k
    } else {
559
        /* the entire file is the init section */
560
1.42k
        sec->size = -1;
561
1.42k
    }
562
563
2.36k
    dynarray_add(&pls->init_sections, &pls->n_init_sections, sec);
564
565
2.36k
    return sec;
566
2.40k
}
567
568
static void handle_init_section_args(void *context, const char *key,
569
                                     int key_len, char **dest, int *dest_len)
570
5.81k
{
571
5.81k
    struct init_section_info *info = context;
572
5.81k
    if (!strncmp(key, "URI=", key_len)) {
573
3.58k
        *dest     =        info->uri;
574
3.58k
        *dest_len = sizeof(info->uri);
575
3.58k
    } else if (!strncmp(key, "BYTERANGE=", key_len)) {
576
996
        *dest     =        info->byterange;
577
996
        *dest_len = sizeof(info->byterange);
578
996
    }
579
5.81k
}
580
581
struct rendition_info {
582
    char type[16];
583
    char uri[MAX_URL_SIZE];
584
    char group_id[MAX_FIELD_LEN];
585
    char language[MAX_FIELD_LEN];
586
    char assoc_language[MAX_FIELD_LEN];
587
    char name[MAX_FIELD_LEN];
588
    char defaultr[4];
589
    char forced[4];
590
    char characteristics[MAX_CHARACTERISTICS_LEN];
591
};
592
593
static int cmp_rendition_group(const void *a, const void *b)
594
61.8k
{
595
61.8k
    const struct rendition_group *ga = a, *gb = b;
596
597
61.8k
    if (ga->type != gb->type)
598
10.2k
        return FFDIFFSIGN(ga->type, gb->type);
599
51.5k
    return strcmp(ga->id, gb->id);
600
61.8k
}
601
602
static struct rendition_group *find_rendition_group(HLSContext *c,
603
                                                    enum AVMediaType type,
604
                                                    const char *id)
605
40.3k
{
606
40.3k
    struct rendition_group key = { .type = type };
607
608
40.3k
    av_strlcpy(key.id, id, sizeof(key.id));
609
40.3k
    return av_tree_find(c->rendition_groups_by_id, &key, cmp_rendition_group, NULL);
610
40.3k
}
611
612
static struct rendition_group *new_rendition_group(HLSContext *c,
613
                                                   enum AVMediaType type,
614
                                                   const char *id)
615
26.0k
{
616
26.0k
    struct rendition_group *group = find_rendition_group(c, type, id);
617
26.0k
    struct AVTreeNode *node;
618
619
26.0k
    if (group)
620
24.8k
        return group;
621
622
1.20k
    group = av_mallocz(sizeof(*group));
623
1.20k
    node  = av_tree_node_alloc();
624
1.20k
    if (!group || !node ||
625
1.20k
        av_dynarray_add_nofree(&c->rendition_groups, &c->n_rendition_groups, group) < 0) {
626
0
        av_free(group);
627
0
        av_free(node);
628
0
        return NULL;
629
0
    }
630
1.20k
    group->type = type;
631
1.20k
    av_strlcpy(group->id, id, sizeof(group->id));
632
1.20k
    av_tree_insert(&c->rendition_groups_by_id, group, cmp_rendition_group, &node);
633
1.20k
    return group;
634
1.20k
}
635
636
static int new_rendition(HLSContext *c, struct rendition_info *info,
637
                         const char *url_base)
638
35.3k
{
639
35.3k
    struct rendition_group *group;
640
35.3k
    struct rendition *rend;
641
35.3k
    enum AVMediaType type = AVMEDIA_TYPE_UNKNOWN;
642
35.3k
    char *characteristic;
643
35.3k
    char *chr_ptr;
644
35.3k
    char *saveptr;
645
35.3k
    int ret;
646
647
35.3k
    if (!strcmp(info->type, "AUDIO"))
648
17.0k
        type = AVMEDIA_TYPE_AUDIO;
649
18.3k
    else if (!strcmp(info->type, "VIDEO"))
650
7.32k
        type = AVMEDIA_TYPE_VIDEO;
651
10.9k
    else if (!strcmp(info->type, "SUBTITLES"))
652
2.10k
        type = AVMEDIA_TYPE_SUBTITLE;
653
8.88k
    else if (!strcmp(info->type, "CLOSED-CAPTIONS"))
654
        /* CLOSED-CAPTIONS is ignored since we do not support CEA-608 CC in
655
         * AVC SEI RBSP anyway */
656
455
        return 0;
657
658
34.8k
    if (type == AVMEDIA_TYPE_UNKNOWN) {
659
8.43k
        av_log(c->ctx, AV_LOG_WARNING, "Can't support the type: %s\n", info->type);
660
8.43k
        return 0;
661
8.43k
    }
662
663
    /* URI is mandatory for subtitles as per spec */
664
26.4k
    if (type == AVMEDIA_TYPE_SUBTITLE && !info->uri[0]) {
665
406
        av_log(c->ctx, AV_LOG_ERROR, "The URI tag is REQUIRED for subtitle.\n");
666
406
        return 0;
667
406
    }
668
669
26.0k
    group = new_rendition_group(c, type, info->group_id);
670
26.0k
    if (!group)
671
0
        return AVERROR(ENOMEM);
672
673
26.0k
    rend = av_mallocz(sizeof(struct rendition));
674
26.0k
    if (!rend)
675
0
        return AVERROR(ENOMEM);
676
677
26.0k
    ret = av_dynarray_add_nofree(&c->renditions, &c->n_renditions, rend);
678
26.0k
    if (ret < 0) {
679
0
        av_free(rend);
680
0
        return ret;
681
0
    }
682
683
26.0k
    rend->type = type;
684
26.0k
    strcpy(rend->language, info->language);
685
26.0k
    strcpy(rend->name, info->name);
686
687
    /* add the playlist if this is an external rendition */
688
26.0k
    if (info->uri[0]) {
689
5.17k
        rend->playlist = new_playlist(c, info->uri, url_base);
690
5.17k
        if (rend->playlist) {
691
5.17k
            if (type == AVMEDIA_TYPE_SUBTITLE) {
692
1.70k
                rend->playlist->is_subtitle = 1;
693
1.70k
                rend->playlist->is_id3_timestamped = 0;
694
1.70k
            }
695
5.17k
            ret = av_dynarray_add_nofree(&rend->playlist->renditions,
696
5.17k
                                         &rend->playlist->n_renditions, rend);
697
5.17k
            if (ret < 0)
698
0
                return ret;
699
5.17k
        }
700
5.17k
    }
701
26.0k
    if (rend->playlist)
702
5.17k
        ret = av_dynarray_add_nofree(&group->playlists, &group->n_playlists, rend->playlist);
703
20.8k
    else
704
20.8k
        ret = av_dynarray_add_nofree(&group->renditions, &group->n_renditions, rend);
705
26.0k
    if (ret < 0)
706
0
        return ret;
707
708
26.0k
    if (info->assoc_language[0]) {
709
3.60k
        size_t langlen = strlen(rend->language);
710
3.60k
        if (langlen < sizeof(rend->language) - 3) {
711
3.40k
            size_t assoc_len;
712
3.40k
            rend->language[langlen] = ',';
713
3.40k
            assoc_len = av_strlcpy(rend->language + langlen + 1,
714
3.40k
                                   info->assoc_language,
715
3.40k
                                   sizeof(rend->language) - langlen - 1);
716
3.40k
            if (langlen + assoc_len + 2 > sizeof(rend->language)) // truncation occurred
717
260
                av_log(c->ctx, AV_LOG_WARNING, "Truncated rendition language: %s\n",
718
260
                       info->assoc_language);
719
3.40k
        }
720
3.60k
    }
721
722
26.0k
    if (!strcmp(info->defaultr, "YES"))
723
245
        rend->disposition |= AV_DISPOSITION_DEFAULT;
724
26.0k
    if (!strcmp(info->forced, "YES"))
725
332
        rend->disposition |= AV_DISPOSITION_FORCED;
726
727
26.0k
    chr_ptr = info->characteristics;
728
27.6k
    while ((characteristic = av_strtok(chr_ptr, ",", &saveptr))) {
729
1.64k
        if (!strcmp(characteristic, "public.accessibility.describes-music-and-sound"))
730
360
            rend->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;
731
1.28k
        else if (!strcmp(characteristic, "public.accessibility.describes-video"))
732
222
            rend->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
733
734
1.64k
        chr_ptr = NULL;
735
1.64k
    }
736
737
26.0k
    return 0;
738
26.0k
}
739
740
static void handle_rendition_args(void *vinfo, const char *key,
741
                                  int key_len, char **dest, int *dest_len)
742
59.9k
{
743
59.9k
    struct rendition_info *info = vinfo;
744
745
59.9k
    if (!strncmp(key, "TYPE=", key_len)) {
746
30.8k
        *dest     =        info->type;
747
30.8k
        *dest_len = sizeof(info->type);
748
30.8k
    } else if (!strncmp(key, "URI=", key_len)) {
749
6.70k
        *dest     =        info->uri;
750
6.70k
        *dest_len = sizeof(info->uri);
751
22.3k
    } else if (!strncmp(key, "GROUP-ID=", key_len)) {
752
4.40k
        *dest     =        info->group_id;
753
4.40k
        *dest_len = sizeof(info->group_id);
754
17.9k
    } else if (!strncmp(key, "LANGUAGE=", key_len)) {
755
503
        *dest     =        info->language;
756
503
        *dest_len = sizeof(info->language);
757
17.4k
    } else if (!strncmp(key, "ASSOC-LANGUAGE=", key_len)) {
758
4.50k
        *dest     =        info->assoc_language;
759
4.50k
        *dest_len = sizeof(info->assoc_language);
760
12.9k
    } else if (!strncmp(key, "NAME=", key_len)) {
761
411
        *dest     =        info->name;
762
411
        *dest_len = sizeof(info->name);
763
12.5k
    } else if (!strncmp(key, "DEFAULT=", key_len)) {
764
527
        *dest     =        info->defaultr;
765
527
        *dest_len = sizeof(info->defaultr);
766
11.9k
    } else if (!strncmp(key, "FORCED=", key_len)) {
767
782
        *dest     =        info->forced;
768
782
        *dest_len = sizeof(info->forced);
769
11.1k
    } else if (!strncmp(key, "CHARACTERISTICS=", key_len)) {
770
1.95k
        *dest     =        info->characteristics;
771
1.95k
        *dest_len = sizeof(info->characteristics);
772
1.95k
    }
773
    /*
774
     * ignored:
775
     * - AUTOSELECT: client may autoselect based on e.g. system language
776
     * - INSTREAM-ID: EIA-608 closed caption number ("CC1".."CC4")
777
     */
778
59.9k
}
779
780
/* used by parse_playlist to allocate a new variant+playlist when the
781
 * playlist is detected to be a Media Playlist (not Master Playlist)
782
 * and we have no parent Master Playlist (parsing of which would have
783
 * allocated the variant and playlist already)
784
 * *pls == NULL  => Master Playlist or parentless Media Playlist
785
 * *pls != NULL => parented Media Playlist, playlist+variant allocated */
786
static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url)
787
11.8k
{
788
11.8k
    if (*pls)
789
10.7k
        return 0;
790
1.08k
    struct variant *var = new_variant(c, NULL, url, NULL);
791
1.08k
    if (!var)
792
40
        return AVERROR(ENOMEM);
793
1.04k
    *pls = var->playlists[0];
794
1.04k
    return 0;
795
1.08k
}
796
797
static int is_native_http(AVIOContext *pb)
798
0
{
799
0
#if !CONFIG_HTTP_PROTOCOL
800
0
    return 0;
801
#else
802
    URLContext *uc = ffio_geturlcontext(pb);
803
    return uc && !strncmp(uc->prot->name, "http", 4);
804
#endif
805
0
}
806
807
static int open_url_keepalive(AVFormatContext *s, AVIOContext **pb,
808
                              const char *url, AVDictionary **options)
809
0
{
810
#if !CONFIG_HTTP_PROTOCOL
811
0
    return AVERROR_PROTOCOL_NOT_FOUND;
812
#else
813
    int ret;
814
    URLContext *uc = ffio_geturlcontext(*pb);
815
0
    av_assert0(uc);
816
0
    (*pb)->eof_reached = 0;
817
0
    ret = ff_http_do_new_request2(uc, url, options);
818
0
    if (ret < 0) {
819
0
        ff_format_io_close(s, pb);
820
0
    }
821
0
    return ret;
822
#endif
823
0
}
Unexecuted instantiation: hls.c:open_url_keepalive
Unexecuted instantiation: hls.c:open_url_keepalive
824
825
static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url,
826
                    AVDictionary **opts, AVDictionary *opts2, int *is_http_out)
827
11.1k
{
828
11.1k
    HLSContext *c = s->priv_data;
829
11.1k
    AVDictionary *tmp = NULL;
830
11.1k
    const char *proto_name = NULL;
831
11.1k
    int ret;
832
11.1k
    int is_http = 0;
833
834
11.1k
    if (av_strstart(url, "crypto", NULL)) {
835
390
        if (url[6] == '+' || url[6] == ':')
836
152
            proto_name = avio_find_protocol_name(url + 7);
837
10.7k
    } else if (av_strstart(url, "data", NULL)) {
838
859
        if (url[4] == '+' || url[4] == ':')
839
697
            proto_name = avio_find_protocol_name(url + 5);
840
859
    }
841
842
11.1k
    if (!proto_name)
843
11.1k
        proto_name = avio_find_protocol_name(url);
844
845
11.1k
    if (!proto_name)
846
11.1k
        return AVERROR_INVALIDDATA;
847
848
    // only http(s) & file are allowed
849
0
    if (av_strstart(proto_name, "file", NULL)) {
850
0
        if (strcmp(c->allowed_extensions, "ALL") && !av_match_ext(url, c->allowed_extensions)) {
851
0
            av_log(s, AV_LOG_ERROR,
852
0
                "Filename extension of \'%s\' is not a common multimedia extension, blocked for security reasons.\n"
853
0
                "If you wish to override this adjust allowed_extensions, you can set it to \'ALL\' to allow all\n",
854
0
                url);
855
0
            return AVERROR_INVALIDDATA;
856
0
        }
857
0
    } else if (av_strstart(proto_name, "http", NULL)) {
858
0
        is_http = 1;
859
0
    } else if (av_strstart(proto_name, "data", NULL)) {
860
0
        ;
861
0
    } else
862
0
        return AVERROR_INVALIDDATA;
863
864
0
    if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] == ':')
865
0
        ;
866
0
    else if (av_strstart(url, "crypto", NULL) && !strncmp(proto_name, url + 7, strlen(proto_name)) && url[7 + strlen(proto_name)] == ':')
867
0
        ;
868
0
    else if (av_strstart(url, "data", NULL) && !strncmp(proto_name, url + 5, strlen(proto_name)) && url[5 + strlen(proto_name)] == ':')
869
0
        ;
870
0
    else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5))
871
0
        return AVERROR_INVALIDDATA;
872
873
0
    av_dict_copy(&tmp, *opts, 0);
874
0
    av_dict_copy(&tmp, opts2, 0);
875
876
0
    if (is_http && c->http_persistent && is_native_http(*pb)) {
877
0
        ret = open_url_keepalive(c->ctx, pb, url, &tmp);
878
0
        if (ret == AVERROR_EXIT) {
879
0
            av_dict_free(&tmp);
880
0
            return ret;
881
0
        } else if (ret < 0) {
882
0
            if (ret != AVERROR_EOF)
883
0
                av_log(s, AV_LOG_WARNING,
884
0
                    "keepalive request failed for '%s' with error: '%s' when opening url, retrying with new connection\n",
885
0
                    url, av_err2str(ret));
886
0
            av_dict_copy(&tmp, *opts, 0);
887
0
            av_dict_copy(&tmp, opts2, 0);
888
0
            ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp);
889
0
        }
890
0
    } else {
891
0
        av_assert0(!*pb);
892
0
        ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp);
893
0
    }
894
0
    if (ret >= 0) {
895
        // update cookies on http response with setcookies.
896
0
        char *new_cookies = NULL;
897
898
0
        if (!(s->flags & AVFMT_FLAG_CUSTOM_IO))
899
0
            av_opt_get(*pb, "cookies", AV_OPT_SEARCH_CHILDREN, (uint8_t**)&new_cookies);
900
901
0
        if (new_cookies)
902
0
            av_dict_set(opts, "cookies", new_cookies, AV_DICT_DONT_STRDUP_VAL);
903
0
    }
904
905
0
    av_dict_free(&tmp);
906
907
0
    if (is_http_out)
908
0
        *is_http_out = is_http;
909
910
0
    return ret;
911
0
}
912
913
static int test_segment(AVFormatContext *s, const AVInputFormat *in_fmt, struct playlist *pls, struct segment *seg)
914
7.90k
{
915
7.90k
    HLSContext *c = s->priv_data;
916
7.90k
    int matchA = 3;
917
7.90k
    int matchF = 0;
918
919
7.90k
    if (!c->extension_picky)
920
0
        return 0;
921
922
7.90k
    if (strcmp(c->allowed_segment_extensions, "ALL"))
923
7.90k
        matchA =      av_match_ext    (seg->url, c->allowed_segment_extensions)
924
7.90k
                 + 2*(ff_match_url_ext(seg->url, c->allowed_segment_extensions) > 0);
925
926
7.90k
    if (!matchA) {
927
127
        av_log(s, AV_LOG_ERROR, "URL %s is not in allowed_segment_extensions, consider updating hls.c and submitting a patch to ffmpeg-devel, if this should be added\n", seg->url);
928
127
        return AVERROR_INVALIDDATA;
929
127
    }
930
931
7.77k
    if (in_fmt) {
932
129
        if (in_fmt->extensions) {
933
129
            matchF =      av_match_ext(    seg->url, in_fmt->extensions)
934
129
                     + 2*(ff_match_url_ext(seg->url, in_fmt->extensions) > 0);
935
            // Youtube uses aac files with .ts extension
936
129
            if(av_match_name("mp4", in_fmt->name) || av_match_name("aac", in_fmt->name)) {
937
0
                matchF |=      av_match_ext(    seg->url, "ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts,cmfv,cmfa")
938
0
                          + 2*(ff_match_url_ext(seg->url, "ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts,cmfv,cmfa") > 0);
939
0
            }
940
129
        } else if (!strcmp(in_fmt->name, "mpegts")) {
941
0
            const char *str = "ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts"
942
0
                              ",html" // https://flash1.bogulus.cfd/
943
0
                            ;
944
0
            matchF =      av_match_ext(    seg->url, str)
945
0
                     + 2*(ff_match_url_ext(seg->url, str) > 0);
946
0
        } else if (!strcmp(in_fmt->name, "webvtt")) {
947
0
            matchF =      av_match_ext(    seg->url, "vtt,webvtt")
948
0
                     + 2*(ff_match_url_ext(seg->url, "vtt,webvtt") > 0);
949
0
        }
950
951
129
        if (!(matchA & matchF)) {
952
4
            av_log(s, AV_LOG_ERROR, "detected format %s extension %s mismatches allowed extensions in url %s\n", in_fmt->name, in_fmt->extensions ? in_fmt->extensions : "none", seg->url);
953
4
            return AVERROR_INVALIDDATA;
954
4
        }
955
129
    }
956
957
7.77k
    return 0;
958
7.77k
}
959
960
static int parse_playlist(HLSContext *c, const char *url,
961
                          struct playlist *pls, AVIOContext *in)
962
15.0k
{
963
15.0k
    int ret = 0, is_segment = 0, is_variant = 0;
964
15.0k
    int64_t duration = 0;
965
15.0k
    enum KeyType key_type = KEY_NONE;
966
15.0k
    uint8_t iv[16] = "";
967
15.0k
    int has_iv = 0;
968
15.0k
    char key[MAX_URL_SIZE] = "";
969
15.0k
    char line[MAX_URL_SIZE];
970
15.0k
    const char *ptr;
971
15.0k
    int close_in = 0;
972
15.0k
    int64_t seg_offset = 0;
973
15.0k
    int64_t seg_size = -1;
974
15.0k
    uint8_t *new_url = NULL;
975
15.0k
    struct variant_info variant_info;
976
15.0k
    char tmp_str[MAX_URL_SIZE];
977
15.0k
    struct segment *cur_init_section = NULL;
978
15.0k
    int is_http = av_strstart(url, "http", NULL);
979
15.0k
    struct segment **prev_segments = NULL;
980
15.0k
    int prev_n_segments = 0;
981
15.0k
    int64_t prev_start_seq_no = -1;
982
15.0k
    int64_t load_start = av_gettime_relative();
983
15.0k
    int64_t start_time_offset = 0;
984
15.0k
    int time_offset_flag = 0;
985
15.0k
    int finished = 0;
986
987
15.0k
    if (is_http && !in && c->http_persistent && c->playlist_pb) {
988
0
        in = c->playlist_pb;
989
0
        ret = open_url_keepalive(c->ctx, &c->playlist_pb, url, NULL);
990
0
        if (ret == AVERROR_EXIT) {
991
0
            return ret;
992
0
        } else if (ret < 0) {
993
0
            if (ret != AVERROR_EOF)
994
0
                av_log(c->ctx, AV_LOG_WARNING,
995
0
                    "keepalive request failed for '%s' with error: '%s' when parsing playlist\n",
996
0
                    url, av_err2str(ret));
997
0
            in = NULL;
998
0
        }
999
0
    }
1000
1001
15.0k
    if (!in) {
1002
10.4k
        AVDictionary *opts = NULL;
1003
10.4k
        av_dict_copy(&opts, c->avio_opts, 0);
1004
1005
10.4k
        if (c->http_persistent)
1006
0
            av_dict_set(&opts, "multiple_requests", "1", 0);
1007
1008
10.4k
        ret = open_url(c->ctx, &in, url, &opts, NULL, NULL);
1009
10.4k
        av_dict_free(&opts);
1010
10.4k
        if (ret < 0)
1011
10.4k
            return ret;
1012
1013
0
        if (is_http && c->http_persistent && is_native_http(in))
1014
0
            c->playlist_pb = in;
1015
0
        else
1016
0
            close_in = 1;
1017
0
    }
1018
1019
4.56k
    if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
1020
0
        url = new_url;
1021
1022
4.56k
    ff_get_chomp_line(in, line, sizeof(line));
1023
4.56k
    if (strcmp(line, "#EXTM3U")) {
1024
254
        ret = AVERROR_INVALIDDATA;
1025
254
        goto fail;
1026
254
    }
1027
1028
4.30k
    if (pls) {
1029
0
        prev_start_seq_no = pls->start_seq_no;
1030
0
        prev_segments = pls->segments;
1031
0
        prev_n_segments = pls->n_segments;
1032
0
        pls->segments = NULL;
1033
0
        pls->n_segments = 0;
1034
1035
0
        pls->finished = 0;
1036
0
        pls->type = PLS_TYPE_UNSPECIFIED;
1037
0
    }
1038
3.84M
    while (!avio_feof(in)) {
1039
3.84M
        ff_get_chomp_line(in, line, sizeof(line));
1040
3.84M
        if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
1041
284k
            if (pls) {
1042
21
                av_log(c->ctx, AV_LOG_ERROR,
1043
21
                       "Master Playlist tag found in a Media Playlist\n");
1044
21
                ret = AVERROR_INVALIDDATA;
1045
21
                goto fail;
1046
21
            }
1047
284k
            is_variant = 1;
1048
284k
            memset(&variant_info, 0, sizeof(variant_info));
1049
284k
            ff_parse_key_value(ptr, handle_variant_args, &variant_info);
1050
3.56M
        } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
1051
4.41k
            struct key_info info = {{0}};
1052
4.41k
            ff_parse_key_value(ptr, handle_key_args, &info);
1053
4.41k
            key_type = KEY_NONE;
1054
4.41k
            has_iv = 0;
1055
4.41k
            if (!strcmp(info.method, "AES-128"))
1056
293
                key_type = KEY_AES_128;
1057
4.41k
            if (!strcmp(info.method, "SAMPLE-AES"))
1058
514
                key_type = KEY_SAMPLE_AES;
1059
4.41k
            if (!av_strncasecmp(info.iv, "0x", 2)) {
1060
1.70k
                ff_hex_to_data(iv, info.iv + 2);
1061
1.70k
                has_iv = 1;
1062
1.70k
            }
1063
4.41k
            av_strlcpy(key, info.uri, sizeof(key));
1064
3.55M
        } else if (av_strstart(line, "#EXT-X-MEDIA:", &ptr)) {
1065
35.3k
            struct rendition_info info = {{0}};
1066
35.3k
            if (pls) {
1067
20
                av_log(c->ctx, AV_LOG_ERROR,
1068
20
                       "Master Playlist tag found in a Media Playlist\n");
1069
20
                ret = AVERROR_INVALIDDATA;
1070
20
                goto fail;
1071
20
            }
1072
35.3k
            ff_parse_key_value(ptr, handle_rendition_args, &info);
1073
35.3k
            ret = new_rendition(c, &info, url);
1074
35.3k
            if (ret < 0)
1075
0
                goto fail;
1076
3.52M
        } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
1077
527
            int64_t t;
1078
527
            ret = ensure_playlist(c, &pls, url);
1079
527
            if (ret < 0)
1080
1
                goto fail;
1081
526
            t = strtoll(ptr, NULL, 10);
1082
526
            if (t < 0 || t >= INT64_MAX / AV_TIME_BASE) {
1083
79
                ret = AVERROR_INVALIDDATA;
1084
79
                goto fail;
1085
79
            }
1086
447
            pls->target_duration = t * AV_TIME_BASE;
1087
3.52M
        } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
1088
1.01k
            uint64_t seq_no;
1089
1.01k
            ret = ensure_playlist(c, &pls, url);
1090
1.01k
            if (ret < 0)
1091
2
                goto fail;
1092
1.01k
            seq_no = strtoull(ptr, NULL, 10);
1093
1.01k
            if (seq_no > INT64_MAX/2) {
1094
636
                av_log(c->ctx, AV_LOG_DEBUG, "MEDIA-SEQUENCE higher than "
1095
636
                        "INT64_MAX/2, mask out the highest bit\n");
1096
636
                seq_no &= INT64_MAX/2;
1097
636
            }
1098
1.01k
            pls->start_seq_no = seq_no;
1099
3.52M
        } else if (av_strstart(line, "#EXT-X-PLAYLIST-TYPE:", &ptr)) {
1100
0
            ret = ensure_playlist(c, &pls, url);
1101
0
            if (ret < 0)
1102
0
                goto fail;
1103
0
            if (!strcmp(ptr, "EVENT"))
1104
0
                pls->type = PLS_TYPE_EVENT;
1105
0
            else if (!strcmp(ptr, "VOD"))
1106
0
                pls->type = PLS_TYPE_VOD;
1107
3.52M
        } else if (av_strstart(line, "#EXT-X-MAP:", &ptr)) {
1108
2.50k
            struct init_section_info info = {{0}};
1109
2.50k
            ret = ensure_playlist(c, &pls, url);
1110
2.50k
            if (ret < 0)
1111
13
                goto fail;
1112
2.48k
            ff_parse_key_value(ptr, handle_init_section_args, &info);
1113
2.48k
            cur_init_section = new_init_section(pls, &info, url);
1114
2.48k
            if (!cur_init_section) {
1115
121
                ret = AVERROR(ENOMEM);
1116
121
                goto fail;
1117
121
            }
1118
2.36k
            cur_init_section->key_type = key_type;
1119
2.36k
            if (has_iv) {
1120
232
                memcpy(cur_init_section->iv, iv, sizeof(iv));
1121
2.13k
            } else {
1122
2.13k
                int64_t seq = pls->start_seq_no + pls->n_segments;
1123
2.13k
                memset(cur_init_section->iv, 0, sizeof(cur_init_section->iv));
1124
2.13k
                AV_WB64(cur_init_section->iv + 8, seq);
1125
2.13k
            }
1126
1127
2.36k
            if (key_type != KEY_NONE) {
1128
502
                ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
1129
502
                if (!tmp_str[0]) {
1130
0
                    av_free(cur_init_section);
1131
0
                    ret = AVERROR_INVALIDDATA;
1132
0
                    goto fail;
1133
0
                }
1134
502
                cur_init_section->key = av_strdup(tmp_str);
1135
502
                if (!cur_init_section->key) {
1136
0
                    av_free(cur_init_section);
1137
0
                    ret = AVERROR(ENOMEM);
1138
0
                    goto fail;
1139
0
                }
1140
1.86k
            } else {
1141
1.86k
                cur_init_section->key = NULL;
1142
1.86k
            }
1143
1144
3.51M
        } else if (av_strstart(line, "#EXT-X-START:", &ptr)) {
1145
199
            const char *time_offset_value = NULL;
1146
199
            if (av_strstart(ptr, "TIME-OFFSET=", &time_offset_value)) {
1147
0
                double offset = strtod(time_offset_value, NULL) * AV_TIME_BASE;
1148
0
                if (offset >= -0x1p63 && offset < 0x1p63) {
1149
0
                    start_time_offset = offset;
1150
0
                    time_offset_flag  = 1;
1151
0
                } else {
1152
0
                    av_log(c->ctx, AV_LOG_WARNING, "TIME-OFFSET value is"
1153
0
                                                    "invalid, it will be ignored");
1154
0
                }
1155
199
            } else {
1156
199
                av_log(c->ctx, AV_LOG_WARNING, "#EXT-X-START value is"
1157
199
                                                "invalid, it will be ignored");
1158
199
                continue;
1159
199
            }
1160
3.51M
        } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
1161
0
            finished = 1;
1162
3.51M
        } else if (av_strstart(line, "#EXTINF:", &ptr)) {
1163
8.28k
            double d = atof(ptr) * AV_TIME_BASE;
1164
8.28k
            if (d < 0 || d > INT64_MAX || isnan(d)) {
1165
276
                av_log(c->ctx, AV_LOG_WARNING, "EXTINF %f unsupported\n", d / AV_TIME_BASE);
1166
276
                d = 0;
1167
276
            }
1168
8.28k
            duration = d;
1169
8.28k
            is_segment = 1;
1170
3.50M
        } else if (av_strstart(line, "#EXT-X-BYTERANGE:", &ptr)) {
1171
2.03k
            seg_size = strtoll(ptr, NULL, 10);
1172
2.03k
            ptr = strchr(ptr, '@');
1173
2.03k
            if (ptr)
1174
529
                seg_offset = strtoll(ptr+1, NULL, 10);
1175
2.03k
            if (seg_size < 0 || seg_offset > INT64_MAX - seg_size) {
1176
124
                ret = AVERROR_INVALIDDATA;
1177
124
                goto fail;
1178
124
            }
1179
3.50M
        } else if (av_strstart(line, "#", NULL)) {
1180
59.7k
            av_log(c->ctx, AV_LOG_VERBOSE, "Skip ('%s')\n", line);
1181
59.7k
            continue;
1182
3.44M
        } else if (line[0]) {
1183
491k
            if (is_variant) {
1184
282k
                if (!new_variant(c, &variant_info, line, url)) {
1185
0
                    ret = AVERROR(ENOMEM);
1186
0
                    goto fail;
1187
0
                }
1188
282k
                is_variant = 0;
1189
282k
            }
1190
491k
            if (is_segment) {
1191
7.80k
                struct segment *seg;
1192
7.80k
                ret = ensure_playlist(c, &pls, url);
1193
7.80k
                if (ret < 0)
1194
24
                    goto fail;
1195
7.77k
                seg = av_malloc(sizeof(struct segment));
1196
7.77k
                if (!seg) {
1197
0
                    ret = AVERROR(ENOMEM);
1198
0
                    goto fail;
1199
0
                }
1200
7.77k
                if (has_iv) {
1201
3.56k
                    memcpy(seg->iv, iv, sizeof(iv));
1202
4.21k
                } else {
1203
4.21k
                    uint64_t seq = pls->start_seq_no + (uint64_t)pls->n_segments;
1204
4.21k
                    memset(seg->iv, 0, sizeof(seg->iv));
1205
4.21k
                    AV_WB64(seg->iv + 8, seq);
1206
4.21k
                }
1207
1208
7.77k
                if (key_type != KEY_NONE) {
1209
353
                    ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
1210
353
                    if (!tmp_str[0]) {
1211
0
                        ret = AVERROR_INVALIDDATA;
1212
0
                        av_free(seg);
1213
0
                        goto fail;
1214
0
                    }
1215
353
                    seg->key = av_strdup(tmp_str);
1216
353
                    if (!seg->key) {
1217
0
                        av_free(seg);
1218
0
                        ret = AVERROR(ENOMEM);
1219
0
                        goto fail;
1220
0
                    }
1221
7.42k
                } else {
1222
7.42k
                    seg->key = NULL;
1223
7.42k
                }
1224
1225
7.77k
                ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, line);
1226
7.77k
                if (!tmp_str[0]) {
1227
0
                    ret = AVERROR_INVALIDDATA;
1228
0
                    if (seg->key)
1229
0
                        av_free(seg->key);
1230
0
                    av_free(seg);
1231
0
                    goto fail;
1232
0
                }
1233
7.77k
                seg->url = av_strdup(tmp_str);
1234
7.77k
                if (!seg->url) {
1235
0
                    av_free(seg->key);
1236
0
                    av_free(seg);
1237
0
                    ret = AVERROR(ENOMEM);
1238
0
                    goto fail;
1239
0
                }
1240
1241
7.77k
                ret = test_segment(c->ctx, pls->ctx ? pls->ctx->iformat : NULL, pls, seg);
1242
7.77k
                if (ret < 0) {
1243
127
                    av_free(seg->url);
1244
127
                    av_free(seg->key);
1245
127
                    av_free(seg);
1246
127
                    goto fail;
1247
127
                }
1248
1249
7.64k
                if (duration < 0.001 * AV_TIME_BASE) {
1250
7.35k
                    av_log(c->ctx, AV_LOG_WARNING, "Cannot get correct #EXTINF value of segment %s,"
1251
7.35k
                                    " set to default value to 1ms.\n", seg->url);
1252
7.35k
                    duration = 0.001 * AV_TIME_BASE;
1253
7.35k
                }
1254
7.64k
                seg->duration = duration;
1255
7.64k
                seg->key_type = key_type;
1256
7.64k
                dynarray_add(&pls->segments, &pls->n_segments, seg);
1257
7.64k
                is_segment = 0;
1258
1259
7.64k
                seg->size = seg_size;
1260
7.64k
                if (seg_size >= 0) {
1261
660
                    seg->url_offset = seg_offset;
1262
660
                    seg_offset += seg_size;
1263
660
                    seg_size = -1;
1264
6.98k
                } else {
1265
6.98k
                    seg->url_offset = 0;
1266
6.98k
                    seg_offset = 0;
1267
6.98k
                }
1268
1269
7.64k
                seg->init_section = cur_init_section;
1270
7.64k
            }
1271
491k
        }
1272
3.84M
    }
1273
3.77k
    if (prev_segments) {
1274
0
        if (pls->start_seq_no > prev_start_seq_no && c->first_timestamp != AV_NOPTS_VALUE &&
1275
0
            c->first_timestamp_pls == pls) {
1276
0
            int64_t prev_timestamp = c->first_timestamp;
1277
0
            int i;
1278
0
            int64_t diff = pls->start_seq_no - prev_start_seq_no;
1279
0
            for (i = 0; i < prev_n_segments && i < diff; i++) {
1280
0
                c->first_timestamp += prev_segments[i]->duration;
1281
0
            }
1282
0
            av_log(c->ctx, AV_LOG_DEBUG, "Media sequence change (%"PRId64" -> %"PRId64")"
1283
0
                   " reflected in first_timestamp: %"PRId64" -> %"PRId64"\n",
1284
0
                   prev_start_seq_no, pls->start_seq_no,
1285
0
                   prev_timestamp, c->first_timestamp);
1286
0
        } else if (pls->start_seq_no < prev_start_seq_no) {
1287
0
            av_log(c->ctx, AV_LOG_WARNING, "Media sequence changed unexpectedly: %"PRId64" -> %"PRId64"\n",
1288
0
                   prev_start_seq_no, pls->start_seq_no);
1289
0
        }
1290
0
    }
1291
1292
    /* Media Playlist tags may precede the first tag that allocates the
1293
     * playlist. */
1294
3.77k
    if (pls && finished)
1295
0
        pls->finished = 1;
1296
1297
    /* EXT-X-START is valid in both playlist types. A value from the Master
1298
     * Playlist applies to all its Media Playlists, which then ignore their
1299
     * own (RFC 8216 4.3.5). */
1300
3.77k
    if (time_offset_flag && !c->master_time_offset_flag) {
1301
0
        if (pls) {
1302
0
            pls->start_time_offset = start_time_offset;
1303
0
            pls->time_offset_flag  = 1;
1304
0
        } else {
1305
0
            c->master_time_offset_flag = 1;
1306
0
            for (int i = 0; i < c->n_playlists; i++) {
1307
0
                c->playlists[i]->start_time_offset = start_time_offset;
1308
0
                c->playlists[i]->time_offset_flag  = 1;
1309
0
            }
1310
0
        }
1311
0
    }
1312
1313
4.56k
fail:
1314
4.56k
    free_segment_dynarray(prev_segments, prev_n_segments);
1315
4.56k
    av_freep(&prev_segments);
1316
4.56k
    if (pls)
1317
1.04k
        pls->last_load_time = load_start;
1318
4.56k
    av_free(new_url);
1319
4.56k
    if (close_in)
1320
0
        ff_format_io_close(c->ctx, &in);
1321
4.56k
    c->ctx->ctx_flags = c->ctx->ctx_flags & ~(unsigned)AVFMTCTX_UNSEEKABLE;
1322
4.56k
    if (!c->n_variants || !c->variants[0]->n_playlists ||
1323
2.20k
        !c->variants[0]->playlists[0]->n_segments)
1324
4.10k
        c->ctx->ctx_flags |= AVFMTCTX_UNSEEKABLE;
1325
1326
4.56k
    if (c->n_variants && c->variants[0]->n_playlists &&
1327
2.20k
        c->variants[0]->playlists[0]->type == PLS_TYPE_EVENT &&
1328
0
        !c->variants[0]->playlists[0]->finished) {
1329
0
        struct playlist *p = c->variants[0]->playlists[0];
1330
0
        int64_t duration = 0;
1331
0
        for (int i = 0; i < p->n_segments; i++)
1332
0
            duration += p->segments[i]->duration;
1333
0
        c->ctx->duration = duration;
1334
0
    }
1335
1336
4.56k
    return ret;
1337
3.77k
}
1338
1339
static struct segment *current_segment(struct playlist *pls)
1340
2.00k
{
1341
2.00k
    int64_t n = pls->cur_seq_no - pls->start_seq_no;
1342
2.00k
    if (n >= pls->n_segments)
1343
0
        return NULL;
1344
2.00k
    return pls->segments[n];
1345
2.00k
}
1346
1347
static struct segment *next_segment(struct playlist *pls)
1348
357
{
1349
357
    int64_t n = pls->cur_seq_no - pls->start_seq_no + 1;
1350
357
    if (n >= pls->n_segments)
1351
166
        return NULL;
1352
191
    return pls->segments[n];
1353
357
}
1354
1355
/* True if 'next' is an unencrypted byte range that directly follows 'cur' in
1356
 * the same resource and ends within the range requested up to 'end', so that
1357
 * it is read on from the input of 'cur' (i.e. consecutive EXT-X-BYTERANGE
1358
 * segments). */
1359
static int segment_continues(const struct segment *cur,
1360
                             const struct segment *next, int64_t end)
1361
207
{
1362
207
    return cur && next &&
1363
207
           cur->size >= 0 && next->size >= 0 &&
1364
188
           next->url_offset == cur->url_offset + cur->size &&
1365
142
           next->url_offset + next->size <= end &&
1366
142
           cur->key_type == KEY_NONE && next->key_type == KEY_NONE &&
1367
134
           next->init_section == cur->init_section &&
1368
130
           !strcmp(next->url, cur->url);
1369
207
}
1370
1371
static int64_t range_end(struct playlist *pls, const struct segment *seg)
1372
357
{
1373
357
    int64_t n = pls->cur_seq_no - pls->start_seq_no + 1;
1374
1375
357
    if (seg == next_segment(pls))
1376
0
        n++;
1377
357
    else if (seg != current_segment(pls))
1378
9
        return seg->url_offset + seg->size;
1379
378
    for (; n < pls->n_segments &&
1380
207
           segment_continues(seg, pls->segments[n], INT64_MAX); n++)
1381
30
        seg = pls->segments[n];
1382
348
    return seg->url_offset + seg->size;
1383
357
}
1384
1385
static int read_from_url(struct playlist *pls, struct segment *seg,
1386
                         uint8_t *buf, int buf_size)
1387
0
{
1388
0
    int ret;
1389
1390
     /* limit read if the segment was only a part of a file */
1391
0
    if (seg->size >= 0)
1392
0
        buf_size = FFMIN(buf_size, seg->size - pls->cur_seg_offset);
1393
1394
0
    ret = avio_read(pls->input, buf, buf_size);
1395
0
    if (ret > 0)
1396
0
        pls->cur_seg_offset += ret;
1397
1398
0
    return ret;
1399
0
}
1400
1401
/* Parse the raw ID3 data and pass contents to caller */
1402
static void parse_id3(AVFormatContext *s, AVIOContext *pb,
1403
                      AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info,
1404
                      ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta)
1405
0
{
1406
0
    static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp";
1407
0
    static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription";
1408
0
    ID3v2ExtraMeta *meta;
1409
1410
0
    ff_id3v2_read_dict(NULL, pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta);
1411
0
    for (meta = *extra_meta; meta; meta = meta->next) {
1412
0
        if (!strcmp(meta->tag, "PRIV")) {
1413
0
            ID3v2ExtraMetaPRIV *priv = &meta->data.priv;
1414
0
            if (priv->datasize == 8 && !av_strncasecmp(priv->owner, id3_priv_owner_ts, 44)) {
1415
                /* 33-bit MPEG timestamp */
1416
0
                int64_t ts = AV_RB64(priv->data);
1417
0
                av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts);
1418
0
                if ((ts & ~((1ULL << 33) - 1)) == 0)
1419
0
                    *dts = ts;
1420
0
                else
1421
0
                    av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts);
1422
0
            } else if (priv->datasize >= 8 && !av_strncasecmp(priv->owner, id3_priv_owner_audio_setup, 36)) {
1423
0
                ff_hls_senc_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize);
1424
0
            }
1425
0
        } else if (!strcmp(meta->tag, "APIC") && apic)
1426
0
            *apic = &meta->data.apic;
1427
0
    }
1428
0
}
1429
1430
/* Check if the ID3 metadata contents have changed */
1431
static int id3_has_changed_values(struct playlist *pls, AVDictionary *metadata,
1432
                                  ID3v2ExtraMetaAPIC *apic)
1433
0
{
1434
0
    const AVDictionaryEntry *entry = NULL;
1435
0
    const AVDictionaryEntry *oldentry;
1436
    /* check that no keys have changed values */
1437
0
    while ((entry = av_dict_iterate(metadata, entry))) {
1438
0
        oldentry = av_dict_get(pls->id3_initial, entry->key, NULL, AV_DICT_MATCH_CASE);
1439
0
        if (!oldentry || strcmp(oldentry->value, entry->value) != 0)
1440
0
            return 1;
1441
0
    }
1442
1443
    /* check if apic appeared */
1444
0
    if (apic && (pls->ctx->nb_streams != 2 || !pls->ctx->streams[1]->attached_pic.data))
1445
0
        return 1;
1446
1447
0
    if (apic) {
1448
0
        int size = pls->ctx->streams[1]->attached_pic.size;
1449
0
        if (size != apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE)
1450
0
            return 1;
1451
1452
0
        if (memcmp(apic->buf->data, pls->ctx->streams[1]->attached_pic.data, size) != 0)
1453
0
            return 1;
1454
0
    }
1455
1456
0
    return 0;
1457
0
}
1458
1459
/* Parse ID3 data and handle the found data */
1460
static void handle_id3(AVIOContext *pb, struct playlist *pls)
1461
0
{
1462
0
    AVDictionary *metadata = NULL;
1463
0
    ID3v2ExtraMetaAPIC *apic = NULL;
1464
0
    ID3v2ExtraMeta *extra_meta = NULL;
1465
0
    int64_t timestamp = AV_NOPTS_VALUE;
1466
1467
0
    parse_id3(pls->ctx, pb, &metadata, &timestamp, &pls->audio_setup_info, &apic, &extra_meta);
1468
1469
0
    if (timestamp != AV_NOPTS_VALUE) {
1470
0
        pls->id3_mpegts_timestamp = timestamp;
1471
0
        pls->id3_offset = 0;
1472
0
    }
1473
1474
0
    if (!pls->id3_found) {
1475
        /* initial ID3 tags */
1476
0
        av_assert0(!pls->id3_deferred_extra);
1477
0
        pls->id3_found = 1;
1478
1479
        /* get picture attachment and set text metadata */
1480
0
        if (pls->ctx->nb_streams) {
1481
0
            if (av_match_name(pls->ctx->iformat->name, PACKED_AUDIO_FORMATS))
1482
0
                ff_id3v2_parse_apic(pls->ctx, extra_meta);
1483
0
        } else
1484
            /* demuxer not yet opened, defer picture attachment */
1485
0
            pls->id3_deferred_extra = extra_meta;
1486
1487
0
        ff_id3v2_parse_priv_dict(&metadata, extra_meta);
1488
0
        av_dict_copy(&pls->ctx->metadata, metadata, 0);
1489
0
        pls->id3_initial = metadata;
1490
1491
0
    } else {
1492
0
        if (!pls->id3_changed && id3_has_changed_values(pls, metadata, apic)) {
1493
0
            avpriv_report_missing_feature(pls->parent, "Changing ID3 metadata in HLS audio elementary stream");
1494
0
            pls->id3_changed = 1;
1495
0
        }
1496
0
        av_dict_free(&metadata);
1497
0
    }
1498
1499
0
    if (pls->id3_deferred_extra != extra_meta)
1500
0
        ff_id3v2_free_extra_meta(&extra_meta);
1501
0
}
1502
1503
static void intercept_id3(struct playlist *pls, uint8_t *buf,
1504
                         int buf_size, int *len)
1505
0
{
1506
    /* intercept id3 tags, we do not want to pass them to the raw
1507
     * demuxer on all segment switches */
1508
0
    int bytes;
1509
0
    int id3_buf_pos = 0;
1510
0
    int fill_buf = 0;
1511
0
    struct segment *seg = current_segment(pls);
1512
1513
    /* gather all the id3 tags */
1514
0
    while (1) {
1515
        /* see if we can retrieve enough data for ID3 header */
1516
0
        if (*len < ID3v2_HEADER_SIZE && buf_size >= ID3v2_HEADER_SIZE) {
1517
0
            bytes = read_from_url(pls, seg, buf + *len, ID3v2_HEADER_SIZE - *len);
1518
0
            if (bytes > 0) {
1519
1520
0
                if (bytes == ID3v2_HEADER_SIZE - *len)
1521
                    /* no EOF yet, so fill the caller buffer again after
1522
                     * we have stripped the ID3 tags */
1523
0
                    fill_buf = 1;
1524
1525
0
                *len += bytes;
1526
1527
0
            } else if (*len <= 0) {
1528
                /* error/EOF */
1529
0
                *len = bytes;
1530
0
                fill_buf = 0;
1531
0
            }
1532
0
        }
1533
1534
0
        if (*len < ID3v2_HEADER_SIZE)
1535
0
            break;
1536
1537
0
        if (ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) {
1538
0
            int64_t maxsize = seg->size >= 0 ? seg->size : 1024*1024;
1539
0
            int taglen = ff_id3v2_tag_len(buf);
1540
0
            int tag_got_bytes = FFMIN(taglen, *len);
1541
0
            int remaining = taglen - tag_got_bytes;
1542
1543
0
            if (taglen > maxsize) {
1544
0
                av_log(pls->parent, AV_LOG_ERROR, "Too large HLS ID3 tag (%d > %"PRId64" bytes)\n",
1545
0
                       taglen, maxsize);
1546
0
                break;
1547
0
            }
1548
1549
            /*
1550
             * Copy the id3 tag to our temporary id3 buffer.
1551
             * We could read a small id3 tag directly without memcpy, but
1552
             * we would still need to copy the large tags, and handling
1553
             * both of those cases together with the possibility for multiple
1554
             * tags would make the handling a bit complex.
1555
             */
1556
0
            pls->id3_buf = av_fast_realloc(pls->id3_buf, &pls->id3_buf_size, id3_buf_pos + taglen);
1557
0
            if (!pls->id3_buf)
1558
0
                break;
1559
0
            memcpy(pls->id3_buf + id3_buf_pos, buf, tag_got_bytes);
1560
0
            id3_buf_pos += tag_got_bytes;
1561
1562
            /* strip the intercepted bytes */
1563
0
            *len -= tag_got_bytes;
1564
0
            memmove(buf, buf + tag_got_bytes, *len);
1565
0
            av_log(pls->parent, AV_LOG_DEBUG, "Stripped %d HLS ID3 bytes\n", tag_got_bytes);
1566
1567
0
            if (remaining > 0) {
1568
                /* read the rest of the tag in */
1569
0
                if (read_from_url(pls, seg, pls->id3_buf + id3_buf_pos, remaining) != remaining)
1570
0
                    break;
1571
0
                id3_buf_pos += remaining;
1572
0
                av_log(pls->parent, AV_LOG_DEBUG, "Stripped additional %d HLS ID3 bytes\n", remaining);
1573
0
            }
1574
1575
0
        } else {
1576
            /* no more ID3 tags */
1577
0
            break;
1578
0
        }
1579
0
    }
1580
1581
    /* re-fill buffer for the caller unless EOF */
1582
0
    if (*len >= 0 && (fill_buf || *len == 0)) {
1583
0
        bytes = read_from_url(pls, seg, buf + *len, buf_size - *len);
1584
1585
        /* ignore error if we already had some data */
1586
0
        if (bytes >= 0)
1587
0
            *len += bytes;
1588
0
        else if (*len == 0)
1589
0
            *len = bytes;
1590
0
    }
1591
1592
0
    if (pls->id3_buf) {
1593
        /* Now parse all the ID3 tags */
1594
0
        FFIOContext id3ioctx;
1595
0
        ffio_init_read_context(&id3ioctx, pls->id3_buf, id3_buf_pos);
1596
0
        handle_id3(&id3ioctx.pub, pls);
1597
0
    }
1598
1599
0
    if (pls->is_id3_timestamped == -1)
1600
0
        pls->is_id3_timestamped = (pls->id3_mpegts_timestamp != AV_NOPTS_VALUE);
1601
0
}
1602
1603
static int read_key(HLSContext *c, struct playlist *pls, struct segment *seg)
1604
31
{
1605
31
    AVIOContext *pb = NULL;
1606
1607
31
    int ret = open_url(pls->parent, &pb, seg->key, &c->avio_opts, NULL, NULL);
1608
31
    if (ret < 0) {
1609
31
        av_log(pls->parent, AV_LOG_ERROR, "Unable to open key file %s, %s\n",
1610
31
               seg->key, av_err2str(ret));
1611
31
        return ret;
1612
31
    }
1613
1614
0
    ret = avio_read(pb, pls->key, sizeof(pls->key));
1615
0
    ff_format_io_close(pls->parent, &pb);
1616
0
    if (ret != sizeof(pls->key)) {
1617
0
        if (ret < 0) {
1618
0
            av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s, %s\n",
1619
0
                   seg->key, av_err2str(ret));
1620
0
        } else {
1621
0
            av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s, read bytes %d != %zu\n",
1622
0
                   seg->key, ret, sizeof(pls->key));
1623
0
            ret = AVERROR_INVALIDDATA;
1624
0
        }
1625
1626
0
        return ret;
1627
0
    }
1628
1629
0
    av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
1630
1631
0
    return 0;
1632
0
}
1633
1634
static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg,
1635
                      AVIOContext **in, int64_t *end)
1636
712
{
1637
712
    AVDictionary *opts = NULL;
1638
712
    int ret;
1639
712
    int is_http = 0;
1640
1641
712
    if (c->http_persistent)
1642
0
        av_dict_set(&opts, "multiple_requests", "1", 0);
1643
1644
712
    *end = -1;
1645
712
    if (seg->size >= 0) {
1646
        /* Restrict the request to the wanted byte range, extended so that one
1647
         * request serves the whole run of segments that continue it. */
1648
357
        *end = range_end(pls, seg);
1649
357
        av_dict_set_int(&opts, "offset", seg->url_offset, 0);
1650
357
        av_dict_set_int(&opts, "end_offset", *end, 0);
1651
357
    }
1652
1653
712
    av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n",
1654
712
           seg->url, seg->url_offset, pls->index);
1655
1656
712
    if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) {
1657
31
        if (strcmp(seg->key, pls->key_url)) {
1658
31
            ret = read_key(c, pls, seg);
1659
31
            if (ret < 0)
1660
31
                goto cleanup;
1661
31
        }
1662
31
    }
1663
1664
681
    if (seg->key_type == KEY_AES_128) {
1665
0
        char iv[33], key[33], url[MAX_URL_SIZE];
1666
0
        ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
1667
0
        ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
1668
0
        if (strstr(seg->url, "://"))
1669
0
            snprintf(url, sizeof(url), "crypto+%s", seg->url);
1670
0
        else
1671
0
            snprintf(url, sizeof(url), "crypto:%s", seg->url);
1672
1673
0
        av_dict_set(&opts, "key", key, 0);
1674
0
        av_dict_set(&opts, "iv", iv, 0);
1675
1676
0
        ret = open_url(pls->parent, in, url, &c->avio_opts, opts, &is_http);
1677
0
        if (ret < 0) {
1678
0
            goto cleanup;
1679
0
        }
1680
0
        ret = 0;
1681
681
    } else {
1682
681
        ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http);
1683
681
    }
1684
1685
    /* Seek to the requested position. If this was a HTTP request, the offset
1686
     * should already be where want it to, but this allows e.g. local testing
1687
     * without a HTTP server.
1688
     *
1689
     * This is not done for HTTP at all as avio_seek() does internal bookkeeping
1690
     * of file offset which is out-of-sync with the actual offset when "offset"
1691
     * AVOption is used with http protocol, causing the seek to not be a no-op
1692
     * as would be expected. Wrong offset received from the server will not be
1693
     * noticed without the call, though.
1694
     */
1695
681
    if (ret == 0 && !is_http && seg->url_offset) {
1696
0
        int64_t seekret = avio_seek(*in, seg->url_offset, SEEK_SET);
1697
0
        if (seekret < 0) {
1698
0
            av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url);
1699
0
            ret = seekret;
1700
0
            ff_format_io_close(pls->parent, in);
1701
0
        }
1702
0
    }
1703
1704
712
cleanup:
1705
712
    av_dict_free(&opts);
1706
712
    pls->cur_seg_offset = 0;
1707
712
    return ret;
1708
681
}
1709
1710
static int update_init_section(struct playlist *pls, struct segment *seg)
1711
712
{
1712
712
    static const int max_init_section_size = 1024*1024;
1713
712
    HLSContext *c = pls->parent->priv_data;
1714
712
    int64_t sec_size;
1715
712
    int64_t urlsize;
1716
712
    int ret;
1717
1718
712
    if (seg->init_section == pls->cur_init_section)
1719
698
        return 0;
1720
1721
14
    pls->cur_init_section = NULL;
1722
1723
14
    if (!seg->init_section)
1724
0
        return 0;
1725
1726
14
    ret = open_input(c, pls, seg->init_section, &pls->input, &pls->input_end);
1727
14
    if (ret < 0) {
1728
14
        av_log(pls->parent, AV_LOG_WARNING,
1729
14
               "Failed to open an initialization section in playlist %d\n",
1730
14
               pls->index);
1731
14
        return ret;
1732
14
    }
1733
1734
0
    if (seg->init_section->size >= 0)
1735
0
        sec_size = seg->init_section->size;
1736
0
    else if ((urlsize = avio_size(pls->input)) >= 0)
1737
0
        sec_size = urlsize;
1738
0
    else
1739
0
        sec_size = max_init_section_size;
1740
1741
0
    av_log(pls->parent, AV_LOG_DEBUG,
1742
0
           "Downloading an initialization section of size %"PRId64"\n",
1743
0
           sec_size);
1744
1745
0
    sec_size = FFMIN(sec_size, max_init_section_size);
1746
1747
0
    av_fast_malloc(&pls->init_sec_buf, &pls->init_sec_buf_size, sec_size);
1748
1749
0
    ret = read_from_url(pls, seg->init_section, pls->init_sec_buf,
1750
0
                        pls->init_sec_buf_size);
1751
0
    ff_format_io_close(pls->parent, &pls->input);
1752
1753
0
    if (ret < 0)
1754
0
        return ret;
1755
1756
0
    pls->cur_init_section = seg->init_section;
1757
0
    pls->init_sec_data_len = ret;
1758
0
    pls->init_sec_buf_read_offset = 0;
1759
1760
    /* spec says audio elementary streams do not have media initialization
1761
     * sections, so there should be no ID3 timestamps */
1762
0
    pls->is_id3_timestamped = 0;
1763
1764
0
    return 0;
1765
0
}
1766
1767
static int64_t default_reload_interval(struct playlist *pls)
1768
1.03k
{
1769
1.03k
    return pls->n_segments > 0 ?
1770
1.03k
                          pls->segments[pls->n_segments - 1]->duration :
1771
1.03k
                          pls->target_duration;
1772
1.03k
}
1773
1774
static int playlist_needed(struct playlist *pls)
1775
11.3k
{
1776
11.3k
    AVFormatContext *s = pls->parent;
1777
11.3k
    int i, j;
1778
11.3k
    int stream_needed = 0;
1779
11.3k
    int first_st;
1780
1781
    /* If there is no context or streams yet, the playlist is needed */
1782
11.3k
    if ((!pls->ctx || !pls->n_main_streams) && !pls->is_subtitle)
1783
10.9k
        return 1;
1784
1785
    /* check if any of the streams in the playlist are needed */
1786
445
    for (i = 0; i < pls->n_main_streams; i++) {
1787
33
        if (pls->main_streams[i]->discard < AVDISCARD_ALL) {
1788
0
            stream_needed = 1;
1789
0
            break;
1790
0
        }
1791
33
    }
1792
1793
    /* If all streams in the playlist were discarded, the playlist is not
1794
     * needed (regardless of whether whole programs are discarded or not). */
1795
412
    if (!stream_needed)
1796
412
        return 0;
1797
1798
    /* Otherwise, check if all the programs (variants) this playlist is in are
1799
     * discarded. Since all streams in the playlist are part of the same programs
1800
     * we can just check the programs of the first stream. */
1801
1802
0
    first_st = pls->main_streams[0]->index;
1803
1804
0
    for (i = 0; i < s->nb_programs; i++) {
1805
0
        AVProgram *program = s->programs[i];
1806
0
        if (program->discard < AVDISCARD_ALL) {
1807
0
            for (j = 0; j < program->nb_stream_indexes; j++) {
1808
0
                if (program->stream_index[j] == first_st) {
1809
                    /* playlist is in an undiscarded program */
1810
0
                    return 1;
1811
0
                }
1812
0
            }
1813
0
        }
1814
0
    }
1815
1816
    /* some streams were not discarded but all the programs were */
1817
0
    return 0;
1818
0
}
1819
1820
static int reload_playlist(struct playlist *v, HLSContext *c)
1821
1.03k
{
1822
1.03k
    int ret = 0;
1823
1.03k
    int reload_count = 0;
1824
1825
1.03k
    v->needed = playlist_needed(v);
1826
1827
1.03k
    if (!v->needed)
1828
0
        return AVERROR_EOF;
1829
1830
1.03k
    if (!v->input || (c->http_persistent && v->input_read_done)) {
1831
1.03k
        int64_t reload_interval;
1832
1833
        /* Check that the playlist is still needed before opening a new
1834
         * segment. */
1835
1.03k
        v->needed = playlist_needed(v);
1836
1837
1.03k
        if (!v->needed) {
1838
0
            av_log(v->parent, AV_LOG_INFO, "No longer receiving playlist %d ('%s')\n",
1839
0
                   v->index, v->url);
1840
0
            return AVERROR_EOF;
1841
0
        }
1842
1843
        /* If this is a live stream and the reload interval has elapsed since
1844
         * the last playlist reload, reload the playlists now. */
1845
1.03k
        reload_interval = default_reload_interval(v);
1846
1847
1.29k
reload:
1848
1.29k
        reload_count++;
1849
1.29k
        if (reload_count > c->max_reload)
1850
0
            return AVERROR_EOF;
1851
1.29k
        if (!v->finished &&
1852
1.29k
            av_gettime_relative() - v->last_load_time >= reload_interval) {
1853
270
            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) {
1854
270
                if (ret != AVERROR_EXIT)
1855
270
                    av_log(v->parent, AV_LOG_WARNING, "Failed to reload playlist %d\n",
1856
270
                           v->index);
1857
270
                return ret;
1858
270
            }
1859
            /* If we need to reload the playlist again below (if
1860
             * there's still no more segments), switch to a reload
1861
             * interval of half the target duration. */
1862
0
            reload_interval = v->target_duration / 2;
1863
0
        }
1864
1.02k
        if (v->cur_seq_no < v->start_seq_no) {
1865
0
            av_log(v->parent, AV_LOG_WARNING,
1866
0
                   "skipping %"PRId64" segments ahead, expired from playlists\n",
1867
0
                   v->start_seq_no - v->cur_seq_no);
1868
0
            v->cur_seq_no = v->start_seq_no;
1869
0
        }
1870
1.02k
        if (v->cur_seq_no > v->last_seq_no) {
1871
841
            v->last_seq_no = v->cur_seq_no;
1872
841
            v->m3u8_hold_counters = 0;
1873
841
        } else if (v->last_seq_no == v->cur_seq_no) {
1874
186
            v->m3u8_hold_counters++;
1875
186
            if (v->m3u8_hold_counters >= c->m3u8_hold_counters) {
1876
0
                return AVERROR_EOF;
1877
0
            }
1878
186
        } else {
1879
0
            av_log(v->parent, AV_LOG_WARNING, "The m3u8 list sequence may have been wrapped.\n");
1880
0
        }
1881
1.02k
        if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
1882
315
            if (v->finished || v->is_subtitle)
1883
0
                return AVERROR_EOF;
1884
1.07k
            while (av_gettime_relative() - v->last_load_time < reload_interval) {
1885
813
                if (ff_check_interrupt(c->interrupt_callback))
1886
57
                    return AVERROR_EXIT;
1887
756
                av_usleep(100*1000);
1888
756
            }
1889
            /* Enough time has elapsed since the last reload */
1890
258
            goto reload;
1891
315
        }
1892
1893
1.02k
    }
1894
712
    return ret;
1895
1.03k
}
1896
1897
static int read_data_continuous(void *opaque, uint8_t *buf, int buf_size)
1898
431
{
1899
431
    struct playlist *v = opaque;
1900
431
    HLSContext *c = v->parent->priv_data;
1901
431
    int ret;
1902
431
    int just_opened = 0;
1903
431
    int segment_retries = 0;
1904
431
    struct segment *seg;
1905
1906
431
    if (c->http_persistent && v->input_read_done) {
1907
0
        av_assert0(v->input);
1908
0
        ret = reload_playlist(v, c);
1909
0
        if (ret < 0)
1910
0
            return ret;
1911
0
    }
1912
1913
431
    v->input_read_done = 0;
1914
1915
1.03k
restart:
1916
1.03k
    ret = reload_playlist(v, c);
1917
1.03k
    if (ret < 0)
1918
327
        return ret;
1919
1920
712
    seg = current_segment(v);
1921
1922
712
    if (!v->input || v->input_read_done) {
1923
        /* load/update Media Initialization Section, if any */
1924
712
        ret = update_init_section(v, seg);
1925
712
        if (ret)
1926
14
            return ret;
1927
1928
698
        if (c->http_multiple == 1 && v->input_next_requested) {
1929
0
            FFSWAP(AVIOContext *, v->input, v->input_next);
1930
0
            FFSWAP(int64_t, v->input_end, v->input_next_end);
1931
0
            v->cur_seg_offset = 0;
1932
0
            v->input_next_requested = 0;
1933
0
            ret = 0;
1934
698
        } else {
1935
698
            ret = open_input(c, v, seg, &v->input, &v->input_end);
1936
698
        }
1937
698
        if (ret < 0) {
1938
698
            if (ff_check_interrupt(c->interrupt_callback))
1939
90
                return AVERROR_EXIT;
1940
608
            av_log(v->parent, AV_LOG_WARNING, "Failed to open segment %"PRId64" of playlist %d\n",
1941
608
                   v->cur_seq_no,
1942
608
                   v->index);
1943
608
            if (segment_retries >= c->seg_max_retry) {
1944
608
                av_log(v->parent, AV_LOG_WARNING, "Segment %"PRId64" of playlist %d failed too many times, skipping\n",
1945
608
                       v->cur_seq_no,
1946
608
                       v->index);
1947
608
                v->cur_seq_no++;
1948
608
                segment_retries = 0;
1949
608
            } else {
1950
0
                segment_retries++;
1951
0
            }
1952
608
            goto restart;
1953
698
        }
1954
0
        segment_retries = 0;
1955
0
        just_opened = 1;
1956
0
        v->input_read_done = 0;
1957
0
        if (v->first_read_seq_no < 0)
1958
0
            v->first_read_seq_no = v->cur_seq_no;
1959
0
    }
1960
1961
0
    if (c->http_multiple == -1) {
1962
0
        uint8_t *http_version_opt = NULL;
1963
0
        int r = av_opt_get(v->input, "http_version", AV_OPT_SEARCH_CHILDREN, &http_version_opt);
1964
0
        if (r >= 0) {
1965
0
            c->http_multiple = (!strncmp((const char *)http_version_opt, "1.1", 3) || !strncmp((const char *)http_version_opt, "2.0", 3));
1966
0
            av_freep(&http_version_opt);
1967
0
        }
1968
0
    }
1969
1970
0
    seg = next_segment(v);
1971
0
    if (c->http_multiple == 1 && !v->input_next_requested &&
1972
0
        seg && seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL) &&
1973
0
        !segment_continues(current_segment(v), seg, v->input_end)) {
1974
0
        ret = open_input(c, v, seg, &v->input_next, &v->input_next_end);
1975
0
        if (ret < 0) {
1976
0
            if (ff_check_interrupt(c->interrupt_callback))
1977
0
                return AVERROR_EXIT;
1978
0
            av_log(v->parent, AV_LOG_WARNING, "Failed to open segment %"PRId64" of playlist %d\n",
1979
0
                   v->cur_seq_no + 1,
1980
0
                   v->index);
1981
0
        } else {
1982
0
            v->input_next_requested = 1;
1983
0
        }
1984
0
    }
1985
1986
0
    if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
1987
        /* Push init section out first before first actual segment */
1988
0
        int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size);
1989
0
        memcpy(buf, v->init_sec_buf + v->init_sec_buf_read_offset, copy_size);
1990
0
        v->init_sec_buf_read_offset += copy_size;
1991
0
        return copy_size;
1992
0
    }
1993
1994
0
    seg = current_segment(v);
1995
0
    ret = read_from_url(v, seg, buf, buf_size);
1996
0
    if (ret > 0) {
1997
0
        if (just_opened && v->is_id3_timestamped != 0) {
1998
            /* Intercept ID3 tags here, elementary audio streams are required
1999
             * to convey timestamps using them in the beginning of each segment. */
2000
0
            intercept_id3(v, buf, buf_size, &ret);
2001
0
        }
2002
2003
0
        return ret;
2004
0
    }
2005
0
    if (ret == 0 && segment_continues(seg, next_segment(v), v->input_end)) {
2006
        /* The next segment follows within the requested range and is read
2007
         * on from the same input. */
2008
0
        v->cur_seq_no++;
2009
0
        c->cur_seq_no = v->cur_seq_no;
2010
0
        v->cur_seg_offset = 0;
2011
0
        just_opened = 1;
2012
0
        goto restart;
2013
0
    }
2014
    /* Keep the connection for the next request only if its reply was read
2015
     * to the end. */
2016
0
    if (c->http_persistent && is_native_http(v->input) &&
2017
0
        seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL) &&
2018
0
        (seg->size >= 0 ? ret == 0 && seg->url_offset + seg->size == v->input_end
2019
0
                        : ret == AVERROR_EOF)) {
2020
0
        v->input_read_done = 1;
2021
0
    } else {
2022
0
        ff_format_io_close(v->parent, &v->input);
2023
0
    }
2024
0
    v->cur_seq_no++;
2025
2026
0
    c->cur_seq_no = v->cur_seq_no;
2027
2028
0
    goto restart;
2029
0
}
2030
2031
static int read_data_subtitle_segment(void *opaque, uint8_t *buf, int buf_size)
2032
0
{
2033
0
    struct playlist *v = opaque;
2034
0
    HLSContext *c = v->parent->priv_data;
2035
0
    int ret;
2036
0
    struct segment *seg;
2037
2038
0
    if (!v->needed || v->cur_seq_no - v->start_seq_no >= v->n_segments) {
2039
0
        return AVERROR_EOF;
2040
0
    } else {
2041
0
        seg = current_segment(v);
2042
0
    }
2043
2044
0
    if (!v->input) {
2045
0
        ret = open_input(c, v, seg, &v->input, &v->input_end);
2046
0
        if (ret < 0) {
2047
0
            if (ff_check_interrupt(c->interrupt_callback))
2048
0
                return AVERROR_EXIT;
2049
0
            av_log(v->parent, AV_LOG_WARNING, "Failed to open segment of playlist %d\n",
2050
0
                   v->index);
2051
0
            return ret;
2052
0
        }
2053
0
        if (v->first_read_seq_no < 0)
2054
0
            v->first_read_seq_no = v->cur_seq_no;
2055
0
    }
2056
2057
0
    return read_from_url(v, seg, buf, buf_size);
2058
0
}
2059
2060
static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url,
2061
                          int flags, AVDictionary **opts)
2062
0
{
2063
0
    av_log(s, AV_LOG_ERROR,
2064
0
           "A HLS playlist item '%s' referred to an external file '%s'. "
2065
0
           "Opening this file was forbidden for security reasons\n",
2066
0
           s->url, url);
2067
0
    return AVERROR(EPERM);
2068
0
}
2069
2070
static int init_subtitle_context(struct playlist *pls)
2071
0
{
2072
0
    HLSContext *c = pls->parent->priv_data;
2073
0
    const AVInputFormat *in_fmt;
2074
0
    AVDictionary *opts = NULL;
2075
0
    uint8_t *buf;
2076
0
    int ret;
2077
2078
0
    if (!(pls->ctx = avformat_alloc_context()))
2079
0
        return AVERROR(ENOMEM);
2080
2081
0
    buf = av_malloc(INITIAL_BUFFER_SIZE);
2082
0
    if (!buf) {
2083
0
        avformat_free_context(pls->ctx);
2084
0
        pls->ctx = NULL;
2085
0
        return AVERROR(ENOMEM);
2086
0
    }
2087
2088
0
    av_freep(&pls->pb.pub.buffer);
2089
0
    ffio_init_context(&pls->pb, buf, INITIAL_BUFFER_SIZE, 0, pls,
2090
0
                      read_data_subtitle_segment, NULL, NULL);
2091
0
    pls->pb.pub.seekable = 0;
2092
0
    pls->ctx->pb       = &pls->pb.pub;
2093
0
    pls->ctx->io_open  = nested_io_open;
2094
2095
0
    ret = ff_copy_whiteblacklists(pls->ctx, pls->parent);
2096
0
    if (ret < 0) {
2097
0
        avformat_free_context(pls->ctx);
2098
0
        pls->ctx = NULL;
2099
0
        return ret;
2100
0
    }
2101
2102
0
    in_fmt = av_find_input_format("webvtt");
2103
0
    av_dict_copy(&opts, c->seg_format_opts, 0);
2104
0
    ret = avformat_open_input(&pls->ctx, current_segment(pls)->url, in_fmt, &opts);
2105
0
    av_dict_free(&opts);
2106
2107
0
    return ret;
2108
0
}
2109
2110
static int read_subtitle_packet(struct playlist *v, AVPacket *pkt)
2111
0
{
2112
0
    HLSContext *c = v->parent->priv_data;
2113
0
    int ret;
2114
2115
0
restart:
2116
0
    ret = reload_playlist(v, c);
2117
0
    if (ret < 0)
2118
0
        return ret;
2119
2120
0
    if (v->input && !v->ctx)
2121
0
        ff_format_io_close(v->parent, &v->input);
2122
2123
0
    if (!v->input && !v->ctx) {
2124
0
        ret = init_subtitle_context(v);
2125
0
        if (ret < 0)
2126
0
            return ret;
2127
0
    }
2128
2129
0
    ret = av_read_frame(v->ctx, v->pkt);
2130
0
    if (!ret) {
2131
0
        return ret;
2132
0
    }
2133
0
    ff_format_io_close(v->parent, &v->input);
2134
0
    v->cur_seq_no++;
2135
0
    c->cur_seq_no = v->cur_seq_no;
2136
2137
0
    avformat_close_input(&v->ctx);
2138
2139
0
    goto restart;
2140
0
}
2141
2142
static int add_renditions_to_variant(HLSContext *c, struct variant *var,
2143
                                     enum AVMediaType type, const char *group_id)
2144
14.3k
{
2145
14.3k
    struct rendition_group *group = find_rendition_group(c, type, group_id);
2146
14.3k
    int ret;
2147
2148
14.3k
    if (!group)
2149
6.38k
        return 0;
2150
2151
7.95k
    ret = av_dynarray_add_nofree(&group->variants, &group->n_variants, var);
2152
7.95k
    if (ret < 0)
2153
0
        return ret;
2154
2155
    /* add the playlists of the external renditions to the variant */
2156
18.2k
    for (int i = 0; i < group->n_playlists; i++) {
2157
10.2k
        struct playlist *pls = group->playlists[i];
2158
2159
10.2k
        if (pls->last_variant != var) {
2160
1.85k
            ret = av_dynarray_add_nofree(&var->playlists, &var->n_playlists, pls);
2161
1.85k
            if (ret < 0)
2162
0
                return ret;
2163
1.85k
            pls->last_variant = var;
2164
1.85k
        }
2165
10.2k
    }
2166
7.95k
    return 0;
2167
7.95k
}
2168
2169
/* The renditions without a playlist are part of the main Media Playlist of
2170
 * every variant that references their group. */
2171
static int add_renditions_to_playlists(HLSContext *c, enum AVMediaType type)
2172
2.30k
{
2173
3.76k
    for (int i = 0; i < c->n_rendition_groups; i++) {
2174
1.46k
        struct rendition_group *group = c->rendition_groups[i];
2175
2176
1.46k
        if (group->type != type || !group->n_renditions)
2177
1.00k
            continue;
2178
2179
7.83k
        for (int j = 0; j < group->n_variants; j++) {
2180
7.38k
            struct playlist *pls = group->variants[j]->playlists[0];
2181
2182
7.38k
            if (pls->last_group == group)
2183
6.93k
                continue;
2184
2185
29.8k
            for (int k = 0; k < group->n_renditions; k++) {
2186
29.4k
                int ret = av_dynarray_add_nofree(&pls->renditions, &pls->n_renditions,
2187
29.4k
                                                 group->renditions[k]);
2188
29.4k
                if (ret < 0)
2189
0
                    return ret;
2190
29.4k
            }
2191
452
            pls->last_group = group;
2192
452
        }
2193
453
    }
2194
2.30k
    return 0;
2195
2.30k
}
2196
2197
static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pls,
2198
                                         enum AVMediaType type)
2199
51
{
2200
51
    int rend_idx = 0;
2201
51
    int i;
2202
2203
85
    for (i = 0; i < pls->n_main_streams; i++) {
2204
51
        AVStream *st = pls->main_streams[i];
2205
2206
51
        if (st->codecpar->codec_type != type)
2207
34
            continue;
2208
2209
199
        for (; rend_idx < pls->n_renditions; rend_idx++) {
2210
182
            struct rendition *rend = pls->renditions[rend_idx];
2211
2212
182
            if (rend->type != type)
2213
21
                continue;
2214
2215
161
            if (rend->language[0])
2216
1
                av_dict_set(&st->metadata, "language", rend->language, 0);
2217
161
            if (rend->name[0])
2218
0
                av_dict_set(&st->metadata, "comment", rend->name, 0);
2219
2220
161
            st->disposition |= rend->disposition;
2221
161
        }
2222
17
        if (rend_idx >=pls->n_renditions)
2223
17
            break;
2224
17
    }
2225
51
}
2226
2227
/* if timestamp was in valid range: returns 1 and sets seq_no
2228
 * if not: returns 0 and sets seq_no to closest segment */
2229
static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls,
2230
                                      int64_t timestamp, int64_t *seq_no,
2231
                                      int64_t *seg_start_ts)
2232
0
{
2233
0
    int i;
2234
0
    int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
2235
0
                  0 : c->first_timestamp;
2236
2237
0
    if (timestamp < pos) {
2238
        /* Seeking before the start of the playlist, clamp to the first segment. */
2239
0
        *seq_no = pls->start_seq_no;
2240
0
        if (seg_start_ts)
2241
0
            *seg_start_ts = pos;
2242
0
        return 1;
2243
0
    }
2244
2245
0
    for (i = 0; i < pls->n_segments; i++) {
2246
0
        int64_t diff = pos + pls->segments[i]->duration - timestamp;
2247
0
        if (diff > 0) {
2248
0
            *seq_no = pls->start_seq_no + i;
2249
0
            if (seg_start_ts) {
2250
0
                *seg_start_ts = pos;
2251
0
            }
2252
0
            return 1;
2253
0
        }
2254
0
        pos += pls->segments[i]->duration;
2255
0
    }
2256
2257
0
    *seq_no = pls->start_seq_no + pls->n_segments - 1;
2258
2259
0
    if (!pls->finished && pls->n_segments > 0) {
2260
0
        if (seg_start_ts)
2261
0
            *seg_start_ts = pos - pls->segments[pls->n_segments - 1]->duration;
2262
0
        return 1;
2263
0
    }
2264
2265
0
    return 0;
2266
0
}
2267
2268
static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
2269
453
{
2270
453
    int64_t seq_no;
2271
2272
453
    if (!pls->finished && !c->first_packet &&
2273
0
        av_gettime_relative() - pls->last_load_time >= default_reload_interval(pls))
2274
        /* reload the playlist since it was suspended */
2275
0
        parse_playlist(c, pls->url, pls, NULL);
2276
2277
    /* If playback is already in progress (we are just selecting a new
2278
     * playlist) and this is a complete file, find the matching segment
2279
     * by counting durations. */
2280
453
    if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
2281
0
        find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no, NULL);
2282
0
        return seq_no;
2283
0
    }
2284
2285
453
    if (!pls->finished) {
2286
453
        if (!c->first_packet && /* we are doing a segment selection during playback */
2287
0
            c->cur_seq_no >= pls->start_seq_no &&
2288
0
            c->cur_seq_no < pls->start_seq_no + pls->n_segments)
2289
            /* While spec 3.4.3 says that we cannot assume anything about the
2290
             * content at the same sequence number on different playlists,
2291
             * in practice this seems to work and doing it otherwise would
2292
             * require us to download a segment to inspect its timestamps. */
2293
0
            return c->cur_seq_no;
2294
2295
        /* If this is a live stream, start live_start_index segments from the
2296
         * start or end */
2297
453
        if (c->live_start_index < 0)
2298
453
            seq_no = pls->start_seq_no + FFMAX(pls->n_segments +
2299
453
                                            c->live_start_index, 0);
2300
0
        else
2301
0
            seq_no = pls->start_seq_no + FFMIN(c->live_start_index,
2302
453
                                            pls->n_segments - 1);
2303
2304
        /* If #EXT-X-START in playlist, need to recalculate */
2305
453
        if (pls->time_offset_flag && c->prefer_x_start) {
2306
0
            int64_t start_timestamp;
2307
0
            int64_t playlist_duration = 0;
2308
0
            int64_t cur_timestamp = c->cur_timestamp == AV_NOPTS_VALUE ? 0 :
2309
0
                                    c->cur_timestamp;
2310
2311
0
            for (int i = 0; i < pls->n_segments; i++)
2312
0
                playlist_duration += pls->segments[i]->duration;
2313
2314
            /* If the absolute value of TIME-OFFSET exceeds
2315
             * the duration of the playlist, it indicates either the end of the
2316
             * playlist (if positive) or the beginning of the playlist (if
2317
             * negative). */
2318
0
            if (pls->start_time_offset >=0 &&
2319
0
                pls->start_time_offset > playlist_duration)
2320
0
                start_timestamp = cur_timestamp + playlist_duration;
2321
0
            else if (pls->start_time_offset >= 0 &&
2322
0
                        pls->start_time_offset <= playlist_duration)
2323
0
                start_timestamp = cur_timestamp + pls->start_time_offset;
2324
0
            else if (pls->start_time_offset < 0 &&
2325
0
                        pls->start_time_offset < -playlist_duration)
2326
0
                start_timestamp = cur_timestamp;
2327
0
            else if (pls->start_time_offset < 0 &&
2328
0
                        pls->start_time_offset > -playlist_duration)
2329
0
                start_timestamp = cur_timestamp + playlist_duration +
2330
0
                                    pls->start_time_offset;
2331
0
            else
2332
0
                start_timestamp = cur_timestamp;
2333
2334
0
            find_timestamp_in_playlist(c, pls, start_timestamp, &seq_no, NULL);
2335
0
        }
2336
453
        return seq_no;
2337
453
    }
2338
2339
    /* Otherwise just start on the first segment. */
2340
0
    return pls->start_seq_no;
2341
453
}
2342
2343
static void add_stream_to_programs(AVFormatContext *s, struct playlist *pls, AVStream *stream)
2344
17
{
2345
17
    HLSContext *c = s->priv_data;
2346
17
    int i, j;
2347
17
    int bandwidth = -1;
2348
2349
1.71k
    for (i = 0; i < c->n_variants; i++) {
2350
1.70k
        struct variant *v = c->variants[i];
2351
2352
3.56k
        for (j = 0; j < v->n_playlists; j++) {
2353
1.86k
            if (v->playlists[j] != pls)
2354
1.84k
                continue;
2355
2356
17
            av_program_add_stream_index(s, i, stream->index);
2357
2358
17
            if (bandwidth == -1)
2359
17
                bandwidth = v->bandwidth;
2360
0
            else if (bandwidth != v->bandwidth)
2361
0
                bandwidth = -2; /* stream in multiple variants with different bandwidths */
2362
17
        }
2363
1.70k
    }
2364
2365
17
    if (bandwidth >= 0)
2366
17
        av_dict_set_int(&stream->metadata, "variant_bitrate", bandwidth, 0);
2367
17
}
2368
2369
static int set_stream_info_from_input_stream(AVStream *st, struct playlist *pls, AVStream *ist)
2370
17
{
2371
17
    int err;
2372
2373
17
    err = avcodec_parameters_copy(st->codecpar, ist->codecpar);
2374
17
    if (err < 0)
2375
0
        return err;
2376
2377
17
    if (pls->is_id3_timestamped) /* custom timestamps via id3 */
2378
0
        avpriv_set_pts_info(st, 33, 1, MPEG_TIME_BASE);
2379
17
    else
2380
17
        avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
2381
2382
    // add the dispositions of the subdemuxer stream to the rendition ones
2383
17
    st->disposition |= ist->disposition;
2384
2385
17
    av_dict_copy(&st->metadata, ist->metadata, 0);
2386
2387
17
    ffstream(st)->need_context_update = 1;
2388
2389
17
    return 0;
2390
17
}
2391
2392
/* add new subdemuxer streams to our context, if any */
2393
static int update_streams_from_subdemuxer(AVFormatContext *s, struct playlist *pls)
2394
17
{
2395
17
    HLSContext *c = s->priv_data;
2396
17
    int err;
2397
2398
34
    while (pls->n_main_streams < pls->ctx->nb_streams) {
2399
17
        int ist_idx = pls->n_main_streams;
2400
17
        AVStream *st = avformat_new_stream(s, NULL);
2401
17
        AVStream *ist = pls->ctx->streams[ist_idx];
2402
2403
17
        if (!st)
2404
0
            return AVERROR(ENOMEM);
2405
2406
17
        st->id = pls->index;
2407
17
        dynarray_add(&pls->main_streams, &pls->n_main_streams, st);
2408
2409
17
        add_stream_to_programs(s, pls, st);
2410
2411
17
        err = set_stream_info_from_input_stream(st, pls, ist);
2412
17
        if (err < 0)
2413
0
            return err;
2414
2415
        /* Match the start_time of streams created before playback began. */
2416
17
        if (c->first_timestamp != AV_NOPTS_VALUE)
2417
0
            st->start_time = av_rescale_q(c->first_timestamp,
2418
0
                                          AV_TIME_BASE_Q, st->time_base);
2419
2420
17
        if (ist->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
2421
0
            if (pls->timed_id3_stream_index < 0)
2422
0
                pls->timed_id3_stream_index = ist_idx;
2423
0
            else
2424
0
                av_log(s, AV_LOG_WARNING,
2425
0
                       "Playlist has multiple timed ID3 streams; "
2426
0
                       "only stream %d will be used for metadata propagation\n",
2427
0
                       pls->timed_id3_stream_index);
2428
0
        }
2429
17
    }
2430
2431
17
    return 0;
2432
17
}
2433
2434
static void update_noheader_flag(AVFormatContext *s)
2435
717
{
2436
717
    HLSContext *c = s->priv_data;
2437
717
    int flag_needed = 0;
2438
717
    int i;
2439
2440
9.73k
    for (i = 0; i < c->n_playlists; i++) {
2441
9.01k
        struct playlist *pls = c->playlists[i];
2442
2443
9.01k
        if (pls->has_noheader_flag) {
2444
0
            flag_needed = 1;
2445
0
            break;
2446
0
        }
2447
9.01k
    }
2448
2449
717
    if (flag_needed)
2450
0
        s->ctx_flags |= AVFMTCTX_NOHEADER;
2451
717
    else
2452
717
        s->ctx_flags &= ~AVFMTCTX_NOHEADER;
2453
717
}
2454
2455
static int hls_close(AVFormatContext *s)
2456
4.56k
{
2457
4.56k
    HLSContext *c = s->priv_data;
2458
2459
4.56k
    free_playlist_list(c);
2460
4.56k
    free_variant_list(c);
2461
4.56k
    free_rendition_list(c);
2462
2463
4.56k
    if (c->crypto_ctx.aes_ctx)
2464
17
        av_free(c->crypto_ctx.aes_ctx);
2465
2466
4.56k
    av_dict_free(&c->avio_opts);
2467
4.56k
    ff_format_io_close(c->ctx, &c->playlist_pb);
2468
2469
4.56k
    return 0;
2470
4.56k
}
2471
2472
static int hls_read_header(AVFormatContext *s)
2473
4.56k
{
2474
4.56k
    HLSContext *c = s->priv_data;
2475
4.56k
    int ret = 0, i;
2476
4.56k
    int64_t highest_cur_seq_no = 0;
2477
2478
4.56k
    c->ctx                = s;
2479
4.56k
    c->interrupt_callback = &s->interrupt_callback;
2480
2481
4.56k
    c->first_packet = 1;
2482
4.56k
    c->first_timestamp = AV_NOPTS_VALUE;
2483
4.56k
    c->first_timestamp_pls = NULL;
2484
4.56k
    c->first_timestamp_locked = 0;
2485
4.56k
    c->cur_timestamp = AV_NOPTS_VALUE;
2486
2487
4.56k
    if ((ret = ffio_copy_url_options(s->pb, &c->avio_opts)) < 0)
2488
0
        return ret;
2489
2490
    /* http_persistent and http_multiple auto-detection both rely on the
2491
     * AVIOContext being backed by the builtin URLContext. Neither works
2492
     * when io_open is overridden with a custom callback. */
2493
4.56k
    if (!ffio_geturlcontext(s->pb)) {
2494
4.56k
        if (c->http_persistent) {
2495
4.56k
            av_log(s, AV_LOG_WARNING, "Disabling http_persistent due to custom io_open.\n");
2496
4.56k
            c->http_persistent = 0;
2497
4.56k
        }
2498
        /* Only auto-detection is disabled, enabling http_multiple can still work
2499
         * with custom io_open. */
2500
4.56k
        if (c->http_multiple == -1) {
2501
4.56k
            av_log(s, AV_LOG_WARNING, "Disabling http_multiple due to custom io_open.\n");
2502
4.56k
            c->http_multiple = 0;
2503
4.56k
        }
2504
4.56k
    }
2505
2506
    /* XXX: Some HLS servers don't like being sent the range header,
2507
       in this case, we need to set http_seekable = 0 to disable
2508
       the range header */
2509
4.56k
    av_dict_set_int(&c->avio_opts, "seekable", c->http_seekable, 0);
2510
2511
4.56k
    if ((ret = parse_playlist(c, s->url, NULL, s->pb)) < 0)
2512
786
        return ret;
2513
2514
3.77k
    if (c->n_variants == 0) {
2515
1.97k
        av_log(s, AV_LOG_WARNING, "Empty playlist\n");
2516
1.97k
        return AVERROR_EOF;
2517
1.97k
    }
2518
    /* If the playlist only contained playlists (Master Playlist),
2519
     * parse each individual playlist. */
2520
1.80k
    if (c->n_playlists > 1 || c->playlists[0]->n_segments == 0) {
2521
10.9k
        for (i = 0; i < c->n_playlists; i++) {
2522
10.1k
            struct playlist *pls = c->playlists[i];
2523
10.1k
            pls->m3u8_hold_counters = 0;
2524
10.1k
            if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0) {
2525
10.1k
                av_log(s, AV_LOG_WARNING, "parse_playlist error %s [%s]\n", av_err2str(ret), pls->url);
2526
10.1k
                pls->broken = 1;
2527
10.1k
                if (c->n_playlists > 1)
2528
9.54k
                    continue;
2529
647
                return ret;
2530
10.1k
            }
2531
10.1k
        }
2532
1.40k
    }
2533
2534
276k
    for (i = 0; i < c->n_variants; i++) {
2535
275k
        if (c->variants[i]->playlists[0]->n_segments == 0) {
2536
274k
            av_log(s, AV_LOG_WARNING, "Empty segment [%s]\n", c->variants[i]->playlists[0]->url);
2537
274k
            c->variants[i]->playlists[0]->broken = 1;
2538
274k
        }
2539
275k
    }
2540
2541
    /* Calculate the total duration of the stream if all segments are
2542
     * available (finished or EVENT playlists). */
2543
1.15k
    if (c->variants[0]->playlists[0]->finished ||
2544
1.15k
        c->variants[0]->playlists[0]->type == PLS_TYPE_EVENT) {
2545
0
        int64_t duration = 0;
2546
0
        for (i = 0; i < c->variants[0]->playlists[0]->n_segments; i++)
2547
0
            duration += c->variants[0]->playlists[0]->segments[i]->duration;
2548
0
        s->duration = duration;
2549
0
    }
2550
2551
    /* Associate renditions with variants */
2552
276k
    for (i = 0; i < c->n_variants; i++) {
2553
275k
        struct variant *var = c->variants[i];
2554
2555
275k
        if (var->audio_group[0] &&
2556
1.76k
            (ret = add_renditions_to_variant(c, var, AVMEDIA_TYPE_AUDIO, var->audio_group)) < 0)
2557
0
            return ret;
2558
275k
        if (var->video_group[0] &&
2559
8.55k
            (ret = add_renditions_to_variant(c, var, AVMEDIA_TYPE_VIDEO, var->video_group)) < 0)
2560
0
            return ret;
2561
275k
        if (var->subtitles_group[0] &&
2562
4.02k
            (ret = add_renditions_to_variant(c, var, AVMEDIA_TYPE_SUBTITLE, var->subtitles_group)) < 0)
2563
0
            return ret;
2564
275k
    }
2565
1.15k
    if ((ret = add_renditions_to_playlists(c, AVMEDIA_TYPE_AUDIO)) < 0 ||
2566
1.15k
        (ret = add_renditions_to_playlists(c, AVMEDIA_TYPE_VIDEO)) < 0)
2567
0
        return ret;
2568
2569
    /* Create a program for each variant */
2570
276k
    for (i = 0; i < c->n_variants; i++) {
2571
275k
        struct variant *v = c->variants[i];
2572
275k
        AVProgram *program;
2573
2574
275k
        program = av_new_program(s, i);
2575
275k
        if (!program)
2576
0
            return AVERROR(ENOMEM);
2577
275k
        av_dict_set_int(&program->metadata, "variant_bitrate", v->bandwidth, 0);
2578
275k
    }
2579
2580
    /* Select the starting segments */
2581
11.0k
    for (i = 0; i < c->n_playlists; i++) {
2582
9.93k
        struct playlist *pls = c->playlists[i];
2583
2584
9.93k
        if (pls->n_segments == 0)
2585
9.48k
            continue;
2586
2587
453
        pls->cur_seq_no = select_cur_seq_no(c, pls);
2588
453
        highest_cur_seq_no = FFMAX(highest_cur_seq_no, pls->cur_seq_no);
2589
453
    }
2590
2591
1.15k
    av_dict_set(&c->seg_format_opts, "prefer_hls_mpegts_pts", "1", 0);
2592
2593
    /* Open the demuxer for each playlist */
2594
10.6k
    for (i = 0; i < c->n_playlists; i++) {
2595
9.92k
        struct playlist *pls = c->playlists[i];
2596
9.92k
        const AVInputFormat *in_fmt = NULL;
2597
9.92k
        char *url;
2598
9.92k
        AVDictionary *options = NULL;
2599
9.92k
        struct segment *seg = NULL;
2600
9.92k
        uint8_t *buf;
2601
9.92k
        int buf_size;
2602
2603
9.92k
        if (!(pls->ctx = avformat_alloc_context()))
2604
0
            return AVERROR(ENOMEM);
2605
2606
9.92k
        if (pls->n_segments == 0)
2607
9.47k
            continue;
2608
2609
453
        pls->index  = i;
2610
453
        pls->needed = 1;
2611
453
        pls->parent = s;
2612
2613
        /*
2614
         * If this is a live stream and this playlist looks like it is one segment
2615
         * behind, try to sync it up so that every substream starts at the same
2616
         * time position (so e.g. avformat_find_stream_info() will see packets from
2617
         * all active streams within the first few seconds). This is not very generic,
2618
         * though, as the sequence numbers are technically independent.
2619
         */
2620
453
        if (!pls->finished && pls->cur_seq_no == highest_cur_seq_no - 1 &&
2621
0
            highest_cur_seq_no < pls->start_seq_no + pls->n_segments) {
2622
0
            pls->cur_seq_no = highest_cur_seq_no;
2623
0
        }
2624
2625
453
        if (pls->is_subtitle) {
2626
22
            buf_size = strlen("WEBVTT\n");
2627
22
            buf = av_memdup("WEBVTT\n", buf_size);
2628
431
        } else {
2629
431
            buf_size = INITIAL_BUFFER_SIZE;
2630
431
            buf = av_malloc(buf_size);
2631
431
        }
2632
453
        if (!buf) {
2633
0
            avformat_free_context(pls->ctx);
2634
0
            pls->ctx = NULL;
2635
0
            return AVERROR(ENOMEM);
2636
0
        }
2637
2638
453
        ffio_init_context(&pls->pb, buf, buf_size, 0, pls,
2639
453
                          pls->is_subtitle ? NULL : read_data_continuous, NULL, NULL);
2640
2641
        /*
2642
         * If encryption scheme is SAMPLE-AES, try to read  ID3 tags of
2643
         * external audio track that contains audio setup information
2644
         */
2645
453
        seg = current_segment(pls);
2646
453
        if (seg && seg->key_type == KEY_SAMPLE_AES && pls->n_renditions > 0 &&
2647
20
            pls->renditions[0]->type == AVMEDIA_TYPE_AUDIO) {
2648
19
            uint8_t buf[HLS_MAX_ID3_TAGS_DATA_LEN];
2649
19
            if ((ret = avio_read(&pls->pb.pub, buf, HLS_MAX_ID3_TAGS_DATA_LEN)) < 0) {
2650
                /* Fail if error was not end of file */
2651
1
                if (ret != AVERROR_EOF) {
2652
1
                    avformat_free_context(pls->ctx);
2653
1
                    pls->ctx = NULL;
2654
1
                    return ret;
2655
1
                }
2656
1
            }
2657
18
            ret = 0;
2658
            /* Reset reading */
2659
18
            ff_format_io_close(pls->parent, &pls->input);
2660
18
            pls->input = NULL;
2661
18
            pls->input_read_done = 0;
2662
18
            ff_format_io_close(pls->parent, &pls->input_next);
2663
18
            pls->input_next = NULL;
2664
18
            pls->input_next_requested = 0;
2665
18
            pls->cur_seg_offset = 0;
2666
18
            pls->cur_init_section = NULL;
2667
            /* Reset EOF flag */
2668
18
            pls->pb.pub.eof_reached = 0;
2669
            /* Clear any buffered data */
2670
18
            pls->pb.pub.buf_end = pls->pb.pub.buf_ptr = pls->pb.pub.buffer;
2671
            /* Reset the position */
2672
18
            pls->pb.pub.pos = 0;
2673
18
        }
2674
2675
        /*
2676
         * If encryption scheme is SAMPLE-AES and audio setup information is present in external audio track,
2677
         * use that information to find the media format, otherwise probe input data
2678
         */
2679
452
        seg = current_segment(pls);
2680
452
        if (seg && seg->key_type == KEY_SAMPLE_AES && pls->is_id3_timestamped &&
2681
8
            pls->audio_setup_info.codec_id != AV_CODEC_ID_NONE) {
2682
0
            av_assert1(pls->audio_setup_info.codec_id == AV_CODEC_ID_AAC ||
2683
0
                       pls->audio_setup_info.codec_id == AV_CODEC_ID_AC3 ||
2684
0
                       pls->audio_setup_info.codec_id == AV_CODEC_ID_EAC3);
2685
            // Keep this list in sync with ff_hls_senc_read_audio_setup_info()
2686
0
            in_fmt = av_find_input_format(pls->audio_setup_info.codec_id == AV_CODEC_ID_AAC ? "aac" :
2687
0
                                          pls->audio_setup_info.codec_id == AV_CODEC_ID_AC3 ? "ac3" : "eac3");
2688
452
        } else {
2689
452
            pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
2690
452
            pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
2691
452
            pls->ctx->interrupt_callback = s->interrupt_callback;
2692
452
            url = av_strdup(pls->segments[0]->url);
2693
452
            ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0);
2694
2695
7.38k
            for (int n = 0; n < pls->n_segments; n++)
2696
6.93k
                if (ret >= 0)
2697
129
                    ret = test_segment(s, in_fmt, pls, pls->segments[n]);
2698
2699
452
            if (ret < 0) {
2700
                /* Free the ctx - it isn't initialized properly at this point,
2701
                * so avformat_close_input shouldn't be called. If
2702
                * avformat_open_input fails below, it frees and zeros the
2703
                * context, so it doesn't need any special treatment like this. */
2704
435
                av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url);
2705
435
                avformat_free_context(pls->ctx);
2706
435
                pls->ctx = NULL;
2707
435
                av_free(url);
2708
435
                return ret;
2709
435
            }
2710
17
            av_free(url);
2711
17
        }
2712
2713
17
        seg = current_segment(pls);
2714
17
        if (seg && seg->key_type == KEY_SAMPLE_AES) {
2715
17
            if (strstr(in_fmt->name, "mov")) {
2716
0
                char key[33];
2717
0
                ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
2718
0
                av_dict_set(&options, "decryption_key", key, 0);
2719
17
            } else if (!c->crypto_ctx.aes_ctx) {
2720
17
                c->crypto_ctx.aes_ctx = av_aes_alloc();
2721
17
                if (!c->crypto_ctx.aes_ctx) {
2722
0
                    avformat_free_context(pls->ctx);
2723
0
                    pls->ctx = NULL;
2724
0
                    return AVERROR(ENOMEM);
2725
0
                }
2726
17
            }
2727
17
        }
2728
2729
17
        pls->ctx->pb       = &pls->pb.pub;
2730
17
        pls->ctx->io_open  = nested_io_open;
2731
17
        pls->ctx->flags   |= s->flags & ~AVFMT_FLAG_CUSTOM_IO;
2732
2733
17
        if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
2734
0
            return ret;
2735
2736
17
        av_dict_copy(&options, c->seg_format_opts, 0);
2737
2738
17
        ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, &options);
2739
17
        av_dict_free(&options);
2740
17
        if (ret < 0)
2741
0
            return ret;
2742
2743
17
        if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
2744
0
            if (av_match_name(pls->ctx->iformat->name, PACKED_AUDIO_FORMATS))
2745
0
                ff_id3v2_parse_apic(pls->ctx, pls->id3_deferred_extra);
2746
0
            avformat_queue_attached_pictures(pls->ctx);
2747
0
            ff_id3v2_parse_priv(pls->ctx, pls->id3_deferred_extra);
2748
0
            ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
2749
0
        }
2750
2751
17
        if (pls->is_id3_timestamped == -1)
2752
0
            av_log(s, AV_LOG_WARNING, "No expected HTTP requests have been made\n");
2753
2754
        /*
2755
         * For ID3 timestamped raw audio streams we need to detect the packet
2756
         * durations to calculate timestamps in fill_timing_for_id3_timestamped_stream(),
2757
         * but for other streams we can rely on our user calling avformat_find_stream_info()
2758
         * on us if they want to.
2759
         */
2760
17
        if (pls->is_id3_timestamped || (pls->n_renditions > 0 && pls->renditions[0]->type == AVMEDIA_TYPE_AUDIO)) {
2761
17
            seg = current_segment(pls);
2762
17
            if (seg && seg->key_type == KEY_SAMPLE_AES && pls->audio_setup_info.setup_data_length > 0 &&
2763
0
                pls->ctx->nb_streams == 1)
2764
0
                ret = ff_hls_senc_parse_audio_setup_info(pls->ctx->streams[0], &pls->audio_setup_info);
2765
17
            else
2766
17
                ret = avformat_find_stream_info(pls->ctx, NULL);
2767
2768
17
            if (ret < 0)
2769
0
                return ret;
2770
17
        }
2771
2772
17
        pls->has_noheader_flag = !!(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER);
2773
2774
        /* Create new AVStreams for each stream in this playlist */
2775
17
        ret = update_streams_from_subdemuxer(s, pls);
2776
17
        if (ret < 0)
2777
0
            return ret;
2778
2779
        /*
2780
         * Copy any metadata from playlist to main streams, but do not set
2781
         * event flags.
2782
         */
2783
17
        if (pls->n_main_streams)
2784
17
            av_dict_copy(&pls->main_streams[0]->metadata, pls->ctx->metadata, 0);
2785
2786
17
        if (pls->is_subtitle) {
2787
17
            avformat_free_context(pls->ctx);
2788
17
            pls->ctx = NULL;
2789
17
            pls->needed = 0;
2790
17
            pls->main_streams[0]->discard = AVDISCARD_ALL;
2791
17
        }
2792
2793
17
        add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_AUDIO);
2794
17
        add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_VIDEO);
2795
17
        add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_SUBTITLE);
2796
17
    }
2797
2798
717
    update_noheader_flag(s);
2799
2800
717
    return 0;
2801
1.15k
}
2802
2803
static int recheck_discard_flags(AVFormatContext *s, int first)
2804
733
{
2805
733
    HLSContext *c = s->priv_data;
2806
733
    int i, changed = 0;
2807
733
    int cur_needed;
2808
2809
    /* Check if any new streams are needed */
2810
10.0k
    for (i = 0; i < c->n_playlists; i++) {
2811
9.30k
        struct playlist *pls = c->playlists[i];
2812
2813
9.30k
        cur_needed = playlist_needed(c->playlists[i]);
2814
2815
9.30k
        if (pls->broken) {
2816
9.29k
            continue;
2817
9.29k
        }
2818
10
        if (cur_needed && !pls->needed) {
2819
0
            pls->needed = 1;
2820
0
            changed = 1;
2821
0
            pls->cur_seq_no = select_cur_seq_no(c, pls);
2822
0
            pls->first_read_seq_no = -1;
2823
0
            pls->pb.pub.eof_reached = 0;
2824
0
            if (c->cur_timestamp != AV_NOPTS_VALUE) {
2825
                /* catch up */
2826
0
                pls->seek_timestamp = av_sat_add64(c->cur_timestamp,
2827
0
                    pls->ts_offset != AV_NOPTS_VALUE ? pls->ts_offset : 0);
2828
0
                pls->seek_flags = AVSEEK_FLAG_ANY;
2829
0
                pls->seek_stream_index = -1;
2830
0
            }
2831
0
            av_log(s, AV_LOG_INFO, "Now receiving playlist %d, segment %"PRId64"\n", i, pls->cur_seq_no);
2832
10
        } else if (first && !cur_needed && pls->needed) {
2833
0
            ff_format_io_close(pls->parent, &pls->input);
2834
0
            pls->input_read_done = 0;
2835
0
            ff_format_io_close(pls->parent, &pls->input_next);
2836
0
            pls->input_next_requested = 0;
2837
0
            if (pls->is_subtitle)
2838
0
                avformat_close_input(&pls->ctx);
2839
0
            pls->needed = 0;
2840
0
            changed = 1;
2841
0
            av_log(s, AV_LOG_INFO, "No longer receiving playlist %d\n", i);
2842
0
        }
2843
10
    }
2844
733
    return changed;
2845
733
}
2846
2847
static void fill_timing_for_id3_timestamped_stream(struct playlist *pls)
2848
0
{
2849
0
    if (pls->id3_offset >= 0) {
2850
0
        pls->pkt->dts = av_sat_add64(pls->id3_mpegts_timestamp,
2851
0
                                     av_rescale_q(pls->id3_offset,
2852
0
                                                  pls->ctx->streams[pls->pkt->stream_index]->time_base,
2853
0
                                                  MPEG_TIME_BASE_Q));
2854
0
        if (pls->pkt->duration)
2855
0
            pls->id3_offset = av_sat_add64(pls->id3_offset, pls->pkt->duration);
2856
0
        else
2857
0
            pls->id3_offset = -1;
2858
0
    } else {
2859
        /* there have been packets with unknown duration
2860
         * since the last id3 tag, should not normally happen */
2861
0
        pls->pkt->dts = AV_NOPTS_VALUE;
2862
0
    }
2863
2864
0
    if (pls->pkt->duration)
2865
0
        pls->pkt->duration = av_rescale_q(pls->pkt->duration,
2866
0
                                         pls->ctx->streams[pls->pkt->stream_index]->time_base,
2867
0
                                         MPEG_TIME_BASE_Q);
2868
2869
0
    pls->pkt->pts = AV_NOPTS_VALUE;
2870
0
}
2871
2872
static AVRational get_timebase(struct playlist *pls)
2873
0
{
2874
0
    if (pls->is_id3_timestamped)
2875
0
        return MPEG_TIME_BASE_Q;
2876
2877
0
    return pls->ctx->streams[pls->pkt->stream_index]->time_base;
2878
0
}
2879
2880
static int compare_ts_with_wrapdetect(int64_t ts_a, struct playlist *pls_a,
2881
                                      int64_t ts_b, struct playlist *pls_b)
2882
0
{
2883
0
    int64_t scaled_ts_a = av_rescale_q(ts_a, get_timebase(pls_a), MPEG_TIME_BASE_Q);
2884
0
    int64_t scaled_ts_b = av_rescale_q(ts_b, get_timebase(pls_b), MPEG_TIME_BASE_Q);
2885
2886
0
    return av_compare_mod(scaled_ts_a, scaled_ts_b, 1LL << 33);
2887
0
}
2888
2889
/**
2890
 * Check whether any entry in @p update differs from the corresponding entry
2891
 * in @p current.
2892
 *
2893
 * HLS segments can repeat timed ID3 metadata in every segment so that
2894
 * listeners joining mid-stream immediately receive the current track
2895
 * information. Only signal a metadata change when values actually differ
2896
 * to avoid spurious updates on every segment boundary.
2897
 */
2898
static int metadata_has_changed(const AVDictionary *current,
2899
                                 const AVDictionary *update)
2900
0
{
2901
0
    if (av_dict_count(current) != av_dict_count(update))
2902
0
        return 1;
2903
0
    const AVDictionaryEntry *e = NULL;
2904
0
    while ((e = av_dict_iterate(update, e))) {
2905
0
        const AVDictionaryEntry *cur = av_dict_get(current, e->key, NULL, 0);
2906
0
        if (!cur || strcmp(cur->value, e->value))
2907
0
            return 1;
2908
0
    }
2909
0
    return 0;
2910
0
}
2911
2912
static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
2913
733
{
2914
733
    HLSContext *c = s->priv_data;
2915
733
    int ret, i, minplaylist = -1;
2916
2917
733
    recheck_discard_flags(s, c->first_packet);
2918
733
    c->first_packet = 0;
2919
2920
10.0k
    for (i = 0; i < c->n_playlists; i++) {
2921
9.30k
        struct playlist *pls = c->playlists[i];
2922
        /* Make sure we've got one buffered packet from each open playlist
2923
         * stream */
2924
9.30k
        if (pls->needed && !pls->pkt->data) {
2925
0
            while (1) {
2926
0
                int64_t ts_diff;
2927
0
                AVRational tb;
2928
0
                struct segment *seg = NULL;
2929
0
                if (pls->is_subtitle)
2930
0
                    ret = read_subtitle_packet(pls, pls->pkt);
2931
0
                else
2932
0
                    ret = av_read_frame(pls->ctx, pls->pkt);
2933
0
                if (ret < 0) {
2934
0
                    if (!avio_feof(&pls->pb.pub) && ret != AVERROR_EOF)
2935
0
                        return ret;
2936
0
                    break;
2937
0
                }
2938
2939
                /* stream_index check prevents matching picture attachments etc. */
2940
0
                if (pls->is_id3_timestamped && pls->pkt->stream_index == 0) {
2941
                    /* audio elementary streams are id3 timestamped */
2942
0
                    fill_timing_for_id3_timestamped_stream(pls);
2943
0
                }
2944
2945
0
                if (pls->pkt->dts != AV_NOPTS_VALUE &&
2946
0
                    (pls->ts_offset == AV_NOPTS_VALUE ||
2947
0
                     (!c->first_timestamp_locked &&
2948
0
                      c->first_timestamp_pls == pls &&
2949
0
                      pls->cur_seq_no <= pls->first_read_seq_no + 1))) {
2950
0
                    int adjusted = 0;
2951
                    /* Packet timestamp rebased onto the start of the segment list. */
2952
0
                    int64_t seg_idx = pls->first_read_seq_no - pls->start_seq_no;
2953
0
                    int64_t ts = av_rescale_q(pls->pkt->pts != AV_NOPTS_VALUE ?
2954
0
                                              pls->pkt->pts : pls->pkt->dts,
2955
0
                                              get_timebase(pls), AV_TIME_BASE_Q);
2956
2957
0
                    for (int64_t k = 0; k < seg_idx && k < pls->n_segments; k++)
2958
0
                        ts = av_sat_sub64(ts, pls->segments[k]->duration);
2959
2960
0
                    if (c->first_timestamp == AV_NOPTS_VALUE) {
2961
0
                        c->first_timestamp = ts;
2962
0
                        c->first_timestamp_pls = pls;
2963
0
                        adjusted = 1;
2964
0
                    } else if (c->first_timestamp_pls == pls) {
2965
                        /* first_timestamp came from the first packet in mux
2966
                         * order, but another stream in the same segment may
2967
                         * start earlier. Lower the estimate while packets of
2968
                         * that segment are still arriving. */
2969
0
                        int64_t delta = av_sat_sub64(c->first_timestamp, ts);
2970
2971
0
                        if (delta > 0 && delta <= pls->target_duration) {
2972
0
                            c->first_timestamp = ts;
2973
0
                            for (int k = 0; k < c->n_playlists; k++)
2974
0
                                if (c->playlists[k]->ts_offset != AV_NOPTS_VALUE)
2975
0
                                    c->playlists[k]->ts_offset = av_sat_add64(c->playlists[k]->ts_offset, delta);
2976
0
                            adjusted = 1;
2977
0
                        }
2978
0
                    }
2979
2980
0
                    if (pls->ts_offset == AV_NOPTS_VALUE)
2981
0
                        pls->ts_offset = av_sat_sub64(ts, c->first_timestamp);
2982
2983
0
                    if (adjusted) {
2984
0
                        for (unsigned k = 0; k < s->nb_streams; k++)
2985
0
                            s->streams[k]->start_time =
2986
0
                                av_rescale_q(c->first_timestamp, AV_TIME_BASE_Q,
2987
0
                                             s->streams[k]->time_base);
2988
0
                        av_log(s, AV_LOG_DEBUG,
2989
0
                               "First timestamp %"PRId64" from playlist %d\n",
2990
0
                               c->first_timestamp, pls->index);
2991
0
                    }
2992
0
                }
2993
2994
0
                seg = current_segment(pls);
2995
0
                if (seg && seg->key_type == KEY_SAMPLE_AES && !strstr(pls->ctx->iformat->name, "mov")) {
2996
0
                    enum AVCodecID codec_id = pls->ctx->streams[pls->pkt->stream_index]->codecpar->codec_id;
2997
0
                    memcpy(c->crypto_ctx.iv, seg->iv, sizeof(seg->iv));
2998
0
                    memcpy(c->crypto_ctx.key, pls->key, sizeof(pls->key));
2999
0
                    ff_hls_senc_decrypt_frame(codec_id, &c->crypto_ctx, pls->pkt);
3000
0
                }
3001
3002
0
                if (pls->seek_timestamp == AV_NOPTS_VALUE)
3003
0
                    break;
3004
3005
0
                if (pls->seek_stream_index < 0 ||
3006
0
                    pls->seek_stream_index == pls->pkt->stream_index) {
3007
3008
0
                    if (pls->pkt->dts == AV_NOPTS_VALUE) {
3009
0
                        pls->seek_timestamp = AV_NOPTS_VALUE;
3010
0
                        break;
3011
0
                    }
3012
3013
0
                    tb = get_timebase(pls);
3014
0
                    ts_diff = av_rescale_q_rnd(pls->pkt->dts, tb,
3015
0
                                               AV_TIME_BASE_Q, AV_ROUND_DOWN) -
3016
0
                            pls->seek_timestamp;
3017
0
                    if (ts_diff >= 0 && (pls->seek_flags  & AVSEEK_FLAG_ANY ||
3018
0
                                        pls->pkt->flags & AV_PKT_FLAG_KEY)) {
3019
0
                        pls->seek_timestamp = AV_NOPTS_VALUE;
3020
0
                        break;
3021
0
                    }
3022
0
                }
3023
0
                av_packet_unref(pls->pkt);
3024
0
            }
3025
0
        }
3026
        /* Check if this stream has the packet with the lowest dts */
3027
9.30k
        if (pls->pkt->data) {
3028
0
            struct playlist *minpls = minplaylist < 0 ?
3029
0
                                     NULL : c->playlists[minplaylist];
3030
0
            if (minplaylist < 0) {
3031
0
                minplaylist = i;
3032
0
            } else {
3033
0
                int64_t dts     =    pls->pkt->dts;
3034
0
                int64_t mindts  = minpls->pkt->dts;
3035
3036
0
                if (dts == AV_NOPTS_VALUE ||
3037
0
                    (mindts != AV_NOPTS_VALUE && compare_ts_with_wrapdetect(dts, pls, mindts, minpls) < 0))
3038
0
                    minplaylist = i;
3039
0
            }
3040
0
        }
3041
9.30k
    }
3042
3043
    /* If we got a packet, return it */
3044
733
    if (minplaylist >= 0) {
3045
0
        struct playlist *pls = c->playlists[minplaylist];
3046
0
        AVStream *ist;
3047
0
        AVStream *st;
3048
3049
0
        ret = update_streams_from_subdemuxer(s, pls);
3050
0
        if (ret < 0) {
3051
0
            av_packet_unref(pls->pkt);
3052
0
            return ret;
3053
0
        }
3054
3055
        // If sub-demuxer reports updated metadata, copy it to the first stream
3056
        // and set its AVSTREAM_EVENT_FLAG_METADATA_UPDATED flag.
3057
0
        if (pls->ctx->event_flags & AVFMT_EVENT_FLAG_METADATA_UPDATED) {
3058
0
            if (pls->n_main_streams) {
3059
0
                st = pls->main_streams[0];
3060
0
                av_dict_copy(&st->metadata, pls->ctx->metadata, 0);
3061
0
                st->event_flags |= AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
3062
0
            }
3063
0
            pls->ctx->event_flags &= ~AVFMT_EVENT_FLAG_METADATA_UPDATED;
3064
0
        }
3065
3066
        /* check if noheader flag has been cleared by the subdemuxer */
3067
0
        if (pls->has_noheader_flag && !(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER)) {
3068
0
            pls->has_noheader_flag = 0;
3069
0
            update_noheader_flag(s);
3070
0
        }
3071
3072
0
        if (pls->pkt->stream_index >= pls->n_main_streams) {
3073
0
            av_log(s, AV_LOG_ERROR, "stream index inconsistency: index %d, %d main streams, %d subdemuxer streams\n",
3074
0
                   pls->pkt->stream_index, pls->n_main_streams, pls->ctx->nb_streams);
3075
0
            av_packet_unref(pls->pkt);
3076
0
            return AVERROR_BUG;
3077
0
        }
3078
3079
0
        ist = pls->ctx->streams[pls->pkt->stream_index];
3080
0
        st = pls->main_streams[pls->pkt->stream_index];
3081
3082
        // Propagate timed-ID3 metadata changes to the main stream, suppressing
3083
        // duplicate packets that repeat unchanged metadata at segment boundaries.
3084
0
        if (ist->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3 &&
3085
0
            pls->pkt->stream_index == pls->timed_id3_stream_index &&
3086
0
            ist->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) {
3087
0
            ist->event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
3088
0
            if (metadata_has_changed(pls->timed_id3_metadata, ist->metadata)) {
3089
0
                int ret = av_dict_copy(&st->metadata, ist->metadata, 0);
3090
0
                if (ret < 0)
3091
0
                    return ret;
3092
0
                av_dict_free(&pls->timed_id3_metadata);
3093
0
                ret = av_dict_copy(&pls->timed_id3_metadata, ist->metadata, 0);
3094
0
                if (ret < 0)
3095
0
                    return ret;
3096
0
                st->event_flags |= AVSTREAM_EVENT_FLAG_METADATA_UPDATED;
3097
0
            }
3098
0
        }
3099
3100
0
        av_packet_move_ref(pkt, pls->pkt);
3101
0
        pkt->stream_index = st->index;
3102
3103
0
        if (pkt->dts != AV_NOPTS_VALUE)
3104
0
            c->cur_timestamp = av_rescale_q(pkt->dts,
3105
0
                                            ist->time_base,
3106
0
                                            AV_TIME_BASE_Q);
3107
3108
        /* There may be more situations where this would be useful, but this at least
3109
         * handles newly probed codecs properly (i.e. request_probe by mpegts). */
3110
0
        if (ist->codecpar->codec_id != st->codecpar->codec_id) {
3111
0
            ret = set_stream_info_from_input_stream(st, pls, ist);
3112
0
            if (ret < 0) {
3113
0
                return ret;
3114
0
            }
3115
0
        }
3116
3117
0
        return 0;
3118
0
    }
3119
733
    return AVERROR_EOF;
3120
733
}
3121
3122
static int hls_read_seek(AVFormatContext *s, int stream_index,
3123
                               int64_t timestamp, int flags)
3124
0
{
3125
0
    HLSContext *c = s->priv_data;
3126
0
    struct playlist *seek_pls = NULL;
3127
0
    int i, j;
3128
0
    int stream_subdemuxer_index;
3129
0
    int64_t first_timestamp, seek_timestamp, duration;
3130
0
    int64_t seq_no, seg_start_ts;
3131
0
    int snapped_to_segment = 0;
3132
3133
0
    if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags & AVFMTCTX_UNSEEKABLE))
3134
0
        return AVERROR(ENOSYS);
3135
3136
0
    seek_timestamp = av_rescale_q_rnd(timestamp,
3137
0
                                      s->streams[stream_index]->time_base,
3138
0
                                      AV_TIME_BASE_Q, AV_ROUND_DOWN);
3139
3140
    /* find the playlist with the specified stream */
3141
0
    for (i = 0; i < c->n_playlists; i++) {
3142
0
        struct playlist *pls = c->playlists[i];
3143
0
        for (j = 0; j < pls->n_main_streams; j++) {
3144
0
            if (pls->main_streams[j] == s->streams[stream_index]) {
3145
0
                seek_pls = pls;
3146
0
                stream_subdemuxer_index = j;
3147
0
                break;
3148
0
            }
3149
0
        }
3150
0
    }
3151
0
    if (!seek_pls)
3152
0
        return AVERROR(EIO);
3153
3154
    /* Live and EVENT playlists may have gained segments since the last load,
3155
     * and sliding-window playlists may also have expired some. Refresh before
3156
     * resolving a seek that may fall outside the loaded window, rate limited
3157
     * to the minimum reload interval (RFC 8216 6.3.4). */
3158
0
    if (!seek_pls->finished) {
3159
0
        int64_t elapsed = av_gettime_relative() - seek_pls->last_load_time;
3160
0
        int64_t start = c->first_timestamp == AV_NOPTS_VALUE ?
3161
0
                        0 : c->first_timestamp;
3162
0
        int64_t end = start;
3163
0
        int need_refresh;
3164
0
        for (i = 0; i < seek_pls->n_segments; i++)
3165
0
            end += seek_pls->segments[i]->duration;
3166
0
        need_refresh = seek_timestamp >= end;
3167
0
        if (seek_pls->type == PLS_TYPE_UNSPECIFIED)
3168
0
            need_refresh |= seek_timestamp < start + elapsed +
3169
0
                                             seek_pls->target_duration;
3170
0
        if (need_refresh && elapsed >= default_reload_interval(seek_pls))
3171
0
            parse_playlist(c, seek_pls->url, seek_pls, NULL);
3172
0
    }
3173
3174
0
    first_timestamp = c->first_timestamp == AV_NOPTS_VALUE ?
3175
0
                      0 : c->first_timestamp;
3176
3177
0
    duration = s->duration == AV_NOPTS_VALUE ?
3178
0
               0 : s->duration;
3179
3180
    /* Only finished playlists cannot grow past the known duration. */
3181
0
    if (seek_pls->finished &&
3182
0
        0 < duration && duration < seek_timestamp - first_timestamp)
3183
0
        return AVERROR(EIO);
3184
3185
    /* check if the timestamp is valid for the playlist with the
3186
     * specified stream index */
3187
0
    if (!find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no, &seg_start_ts))
3188
0
        return AVERROR(EIO);
3189
3190
0
    if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
3191
0
        flags & AVSEEK_FLAG_BACKWARD && !(flags & AVSEEK_FLAG_ANY)) {
3192
        /* Seeking to start of segment ensures we seek to a keyframe located
3193
         * before the given timestamp. */
3194
0
        seek_timestamp = seg_start_ts;
3195
0
        snapped_to_segment = 1;
3196
0
    }
3197
3198
0
    av_log(s, AV_LOG_DEBUG, "Seek to %"PRId64" mapped to segment %"PRId64
3199
0
           " of playlist %d (start %"PRId64")\n",
3200
0
           seek_timestamp, seq_no, seek_pls->index, seg_start_ts);
3201
3202
    /* Keep timeline start fixed from now on. */
3203
0
    c->first_timestamp_locked = 1;
3204
3205
    /* set segment now so we do not need to search again below */
3206
0
    seek_pls->cur_seq_no = seq_no;
3207
0
    seek_pls->seek_stream_index = stream_subdemuxer_index;
3208
3209
    /* Reset PTS wrap detection so backward seeks don't get misinterpreted
3210
     * as a forward PTS wrap. */
3211
0
    for (i = 0; i < (int)s->nb_streams; i++)
3212
0
        ffstream(s->streams[i])->pts_wrap_reference = AV_NOPTS_VALUE;
3213
3214
0
    for (i = 0; i < c->n_playlists; i++) {
3215
        /* Reset reading */
3216
0
        struct playlist *pls = c->playlists[i];
3217
0
        AVIOContext *const pb = &pls->pb.pub;
3218
0
        ff_format_io_close(pls->parent, &pls->input);
3219
0
        pls->input_read_done = 0;
3220
0
        pls->first_read_seq_no = -1;
3221
0
        ff_format_io_close(pls->parent, &pls->input_next);
3222
0
        pls->input_next_requested = 0;
3223
0
        av_packet_unref(pls->pkt);
3224
0
        pb->eof_reached = 0;
3225
        /* Clear any buffered data */
3226
0
        pb->buf_end = pb->buf_ptr = pb->buffer;
3227
        /* Reset the pos, to let the mpegts/mov demuxer know we've seeked. */
3228
0
        pb->pos = 0;
3229
        /* Flush the packet queue of the subdemuxer. */
3230
0
        if (pls->ctx) {
3231
0
            ff_read_frame_flush(pls->ctx);
3232
0
            for (j = 0; j < (int)pls->ctx->nb_streams; j++)
3233
0
                ffstream(pls->ctx->streams[j])->pts_wrap_reference = AV_NOPTS_VALUE;
3234
0
        }
3235
0
        if (pls->is_subtitle)
3236
0
            avformat_close_input(&pls->ctx);
3237
3238
        /* Reset the init segment so it's re-fetched and served appropriately */
3239
0
        pls->cur_init_section = NULL;
3240
3241
        /* The discard in hls_read_packet compares this playlist's packet DTS
3242
         * against seek_timestamp, but seek_timestamp is on c->first_timestamp's
3243
         * baseline (whichever stream produced the first packet). Streams can
3244
         * have different DTS baselines, so translate the threshold onto this
3245
         * playlist's own baseline using its captured offset. */
3246
0
        if (pls->ts_offset != AV_NOPTS_VALUE)
3247
0
            pls->seek_timestamp = av_sat_add64(seek_timestamp, pls->ts_offset);
3248
0
        else
3249
0
            pls->seek_timestamp = seek_timestamp;
3250
0
        pls->seek_flags = flags;
3251
3252
0
        if (pls == seek_pls && snapped_to_segment) {
3253
            /* The first keyframe of the target segment may have a slightly
3254
             * lower DTS than the EXTINF-derived seg_start_ts. Relax the cutoff
3255
             * to not discard the keyframe and land one segment late. */
3256
0
            int64_t idx = seq_no - pls->start_seq_no;
3257
0
            if (idx >= 0 && idx < pls->n_segments)
3258
0
                pls->seek_timestamp = av_sat_sub64(pls->seek_timestamp, pls->segments[idx]->duration);
3259
0
        }
3260
3261
0
        if (pls != seek_pls) {
3262
            /* set closest segment seq_no for playlists not handled above */
3263
0
            find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no, NULL);
3264
            /* seek the playlist to the given position without taking
3265
             * keyframes into account since this playlist does not have the
3266
             * specified stream where we should look for the keyframes */
3267
0
            pls->seek_stream_index = -1;
3268
0
            pls->seek_flags |= AVSEEK_FLAG_ANY;
3269
0
        }
3270
3271
0
        pls->last_seq_no = pls->cur_seq_no;
3272
0
    }
3273
3274
0
    c->cur_timestamp = seek_timestamp;
3275
3276
0
    return 0;
3277
0
}
3278
3279
static int hls_probe(const AVProbeData *p)
3280
963k
{
3281
    /* Require #EXTM3U at the start, and either one of the ones below
3282
     * somewhere for a proper match. */
3283
963k
    if (strncmp(p->buf, "#EXTM3U", 7))
3284
960k
        return 0;
3285
3286
2.52k
    if (strstr(p->buf, "#EXT-X-STREAM-INF:")     ||
3287
2.25k
        strstr(p->buf, "#EXT-X-TARGETDURATION:") ||
3288
2.09k
        strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:")) {
3289
3290
893
        int mime_ok = p->mime_type && !(
3291
0
            av_strcasecmp(p->mime_type, "application/vnd.apple.mpegurl") &&
3292
0
            av_strcasecmp(p->mime_type, "audio/mpegurl")
3293
0
            );
3294
3295
893
        int mime_x = p->mime_type && !(
3296
0
            av_strcasecmp(p->mime_type, "audio/x-mpegurl") &&
3297
0
            av_strcasecmp(p->mime_type, "application/x-mpegurl")
3298
0
            );
3299
3300
893
        if (!mime_ok &&
3301
893
            !mime_x &&
3302
893
            !av_match_ext    (p->filename, "m3u8,m3u") &&
3303
893
             ff_match_url_ext(p->filename, "m3u8,m3u") <= 0) {
3304
893
            av_log(NULL, AV_LOG_ERROR, "Not detecting m3u8/hls with non standard extension and non standard mime type\n");
3305
893
            return 0;
3306
893
        }
3307
0
        if (mime_x)
3308
0
            av_log(NULL, AV_LOG_WARNING, "mime type is not rfc8216 compliant\n");
3309
3310
0
        return AVPROBE_SCORE_MAX;
3311
893
    }
3312
1.63k
    return 0;
3313
2.52k
}
3314
3315
#define OFFSET(x) offsetof(HLSContext, x)
3316
#define FLAGS AV_OPT_FLAG_DECODING_PARAM
3317
static const AVOption hls_options[] = {
3318
    {"live_start_index", "segment index to start live streams at (negative values are from the end)",
3319
        OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS},
3320
    {"prefer_x_start", "prefer to use #EXT-X-START if it's in playlist instead of live_start_index",
3321
        OFFSET(prefer_x_start), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS},
3322
    {"allowed_extensions", "List of file extensions that hls is allowed to access",
3323
        OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
3324
        {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,vtt,wav,webvtt"
3325
            ",cmfv,cmfa" // Ticket11526 www.nicovideo.jp
3326
            ",ec3"       // part of Ticket11435 (Elisa Viihde (Finnish online recording service))
3327
            ",fmp4"      // https://github.com/yt-dlp/yt-dlp/issues/12700
3328
        },
3329
        INT_MIN, INT_MAX, FLAGS},
3330
    {"allowed_segment_extensions", "List of file extensions that hls is allowed to access",
3331
        OFFSET(allowed_segment_extensions), AV_OPT_TYPE_STRING,
3332
        {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,vtt,wav,webvtt"
3333
            ",cmfv,cmfa" // Ticket11526 www.nicovideo.jp
3334
            ",ec3"       // part of Ticket11435 (Elisa Viihde (Finnish online recording service))
3335
            ",fmp4"      // https://github.com/yt-dlp/yt-dlp/issues/12700
3336
            ",html"      // https://flash1.bogulus.cfd/
3337
        },
3338
        INT_MIN, INT_MAX, FLAGS},
3339
    {"extension_picky", "Be picky with all extensions matching",
3340
        OFFSET(extension_picky), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS},
3341
    {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded",
3342
        OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 100}, 0, INT_MAX, FLAGS},
3343
    {"m3u8_hold_counters", "The maximum number of times to load m3u8 when it refreshes without new segments",
3344
        OFFSET(m3u8_hold_counters), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS},
3345
    {"http_persistent", "Use persistent HTTP connections",
3346
        OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS },
3347
    {"http_multiple", "Use multiple HTTP connections for fetching segments",
3348
        OFFSET(http_multiple), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, FLAGS},
3349
    {"http_seekable", "Use HTTP partial requests, 0 = disable, 1 = enable, -1 = auto",
3350
        OFFSET(http_seekable), AV_OPT_TYPE_BOOL, { .i64 = -1}, -1, 1, FLAGS},
3351
    {"seg_format_options", "Set options for segment demuxer",
3352
        OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
3353
    {"seg_max_retry", "Maximum number of times to reload a segment on error.",
3354
     OFFSET(seg_max_retry), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
3355
    {NULL}
3356
};
3357
3358
static const AVClass hls_class = {
3359
    .class_name = "hls demuxer",
3360
    .item_name  = av_default_item_name,
3361
    .option     = hls_options,
3362
    .version    = LIBAVUTIL_VERSION_INT,
3363
};
3364
3365
const FFInputFormat ff_hls_demuxer = {
3366
    .p.name         = "hls",
3367
    .p.long_name    = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
3368
    .p.priv_class   = &hls_class,
3369
    .p.flags        = AVFMT_NOGENSEARCH | AVFMT_TS_DISCONT | AVFMT_NO_BYTE_SEEK | AVFMT_SHOW_IDS,
3370
    .priv_data_size = sizeof(HLSContext),
3371
    .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
3372
    .read_probe     = hls_probe,
3373
    .read_header    = hls_read_header,
3374
    .read_packet    = hls_read_packet,
3375
    .read_close     = hls_close,
3376
    .read_seek      = hls_read_seek,
3377
};