2 * Apple HTTP Live Streaming demuxer
3 * Copyright (c) 2010 Martin Storsjo
4 * Copyright (c) 2013 Anssi Hannula
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 * Apple HTTP Live Streaming demuxer
26 * http://tools.ietf.org/html/draft-pantos-http-live-streaming
29 #include "libavutil/avstring.h"
30 #include "libavutil/avassert.h"
31 #include "libavutil/intreadwrite.h"
32 #include "libavutil/mathematics.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/dict.h"
35 #include "libavutil/time.h"
38 #include "avio_internal.h"
42 #define INITIAL_BUFFER_SIZE 32768
44 #define MAX_FIELD_LEN 64
45 #define MAX_CHARACTERISTICS_LEN 512
47 #define MPEG_TIME_BASE 90000
48 #define MPEG_TIME_BASE_Q (AVRational){1, MPEG_TIME_BASE}
51 * An apple http stream consists of a playlist with media segment files,
52 * played sequentially. There may be several playlists with the same
53 * video content, in different bandwidth variants, that are played in
54 * parallel (preferably only one bandwidth variant at a time). In this case,
55 * the user supplied the url to a main playlist that only lists the variant
58 * If the main playlist doesn't point at any variants, we still create
59 * one anonymous toplevel variant for this, to maintain the structure.
73 enum KeyType key_type
;
86 * Each playlist has its own demuxer. If it currently is active,
87 * it has an open AVIOContext too, and potentially an AVPacket
88 * containing the next packet from this stream.
91 char url
[MAX_URL_SIZE
];
95 AVFormatContext
*parent
;
102 enum PlaylistType type
;
103 int64_t target_duration
;
106 struct segment
**segments
;
107 int needed
, cur_needed
;
109 int64_t cur_seg_offset
;
110 int64_t last_load_time
;
112 char key_url
[MAX_URL_SIZE
];
115 /* ID3 timestamp handling (elementary audio streams have ID3 timestamps
116 * (and possibly other ID3 tags) in the beginning of each segment) */
117 int is_id3_timestamped
; /* -1: not yet known */
118 int64_t id3_mpegts_timestamp
; /* in mpegts tb */
119 int64_t id3_offset
; /* in stream original tb */
120 uint8_t* id3_buf
; /* temp buffer for id3 parsing */
121 unsigned int id3_buf_size
;
122 AVDictionary
*id3_initial
; /* data from first id3 tag */
123 int id3_found
; /* ID3 tag found at some point */
124 int id3_changed
; /* ID3 tag data has changed at some point */
125 ID3v2ExtraMeta
*id3_deferred_extra
; /* stored here until subdemuxer is opened */
127 int64_t seek_timestamp
;
129 int seek_stream_index
; /* into subdemuxer stream array */
131 /* Renditions associated with this playlist, if any.
132 * Alternative rendition playlists have a single rendition associated
133 * with them, and variant main Media Playlists may have
134 * multiple (playlist-less) renditions associated with them. */
136 struct rendition
**renditions
;
140 * Renditions are e.g. alternative subtitle or audio streams.
141 * The rendition may either be an external playlist or it may be
142 * contained in the main Media Playlist of the variant (in which case
146 enum AVMediaType type
;
147 struct playlist
*playlist
;
148 char group_id
[MAX_FIELD_LEN
];
149 char language
[MAX_FIELD_LEN
];
150 char name
[MAX_FIELD_LEN
];
157 /* every variant contains at least the main Media Playlist in index 0 */
159 struct playlist
**playlists
;
161 char audio_group
[MAX_FIELD_LEN
];
162 char video_group
[MAX_FIELD_LEN
];
163 char subtitles_group
[MAX_FIELD_LEN
];
166 typedef struct HLSContext
{
168 struct variant
**variants
;
170 struct playlist
**playlists
;
172 struct rendition
**renditions
;
176 int64_t first_timestamp
;
177 int64_t cur_timestamp
;
178 AVIOInterruptCB
*interrupt_callback
;
179 char *user_agent
; ///< holds HTTP user agent set as an AVOption to the HTTP protocol context
180 char *cookies
; ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context
181 char *headers
; ///< holds HTTP headers set as an AVOption to the HTTP protocol context
184 static int read_chomp_line(AVIOContext
*s
, char *buf
, int maxlen
)
186 int len
= ff_get_line(s
, buf
, maxlen
);
187 while (len
> 0 && av_isspace(buf
[len
- 1]))
192 static void free_segment_list(struct playlist
*pls
)
195 for (i
= 0; i
< pls
->n_segments
; i
++) {
196 av_freep(&pls
->segments
[i
]->key
);
197 av_freep(&pls
->segments
[i
]->url
);
198 av_freep(&pls
->segments
[i
]);
200 av_freep(&pls
->segments
);
204 static void free_playlist_list(HLSContext
*c
)
207 for (i
= 0; i
< c
->n_playlists
; i
++) {
208 struct playlist
*pls
= c
->playlists
[i
];
209 free_segment_list(pls
);
210 av_freep(&pls
->renditions
);
211 av_freep(&pls
->id3_buf
);
212 av_dict_free(&pls
->id3_initial
);
213 ff_id3v2_free_extra_meta(&pls
->id3_deferred_extra
);
214 av_free_packet(&pls
->pkt
);
215 av_freep(&pls
->pb
.buffer
);
217 ffurl_close(pls
->input
);
220 avformat_close_input(&pls
->ctx
);
224 av_freep(&c
->playlists
);
225 av_freep(&c
->cookies
);
226 av_freep(&c
->user_agent
);
230 static void free_variant_list(HLSContext
*c
)
233 for (i
= 0; i
< c
->n_variants
; i
++) {
234 struct variant
*var
= c
->variants
[i
];
235 av_freep(&var
->playlists
);
238 av_freep(&c
->variants
);
242 static void free_rendition_list(HLSContext
*c
)
245 for (i
= 0; i
< c
->n_renditions
; i
++)
246 av_freep(&c
->renditions
[i
]);
247 av_freep(&c
->renditions
);
252 * Used to reset a statically allocated AVPacket to a clean slate,
253 * containing no data.
255 static void reset_packet(AVPacket
*pkt
)
261 static struct playlist
*new_playlist(HLSContext
*c
, const char *url
,
264 struct playlist
*pls
= av_mallocz(sizeof(struct playlist
));
267 reset_packet(&pls
->pkt
);
268 ff_make_absolute_url(pls
->url
, sizeof(pls
->url
), base
, url
);
269 pls
->seek_timestamp
= AV_NOPTS_VALUE
;
271 pls
->is_id3_timestamped
= -1;
272 pls
->id3_mpegts_timestamp
= AV_NOPTS_VALUE
;
274 dynarray_add(&c
->playlists
, &c
->n_playlists
, pls
);
278 struct variant_info
{
280 /* variant group ids: */
281 char audio
[MAX_FIELD_LEN
];
282 char video
[MAX_FIELD_LEN
];
283 char subtitles
[MAX_FIELD_LEN
];
286 static struct variant
*new_variant(HLSContext
*c
, struct variant_info
*info
,
287 const char *url
, const char *base
)
290 struct playlist
*pls
;
292 pls
= new_playlist(c
, url
, base
);
296 var
= av_mallocz(sizeof(struct variant
));
301 var
->bandwidth
= atoi(info
->bandwidth
);
302 strcpy(var
->audio_group
, info
->audio
);
303 strcpy(var
->video_group
, info
->video
);
304 strcpy(var
->subtitles_group
, info
->subtitles
);
307 dynarray_add(&c
->variants
, &c
->n_variants
, var
);
308 dynarray_add(&var
->playlists
, &var
->n_playlists
, pls
);
312 static void handle_variant_args(struct variant_info
*info
, const char *key
,
313 int key_len
, char **dest
, int *dest_len
)
315 if (!strncmp(key
, "BANDWIDTH=", key_len
)) {
316 *dest
= info
->bandwidth
;
317 *dest_len
= sizeof(info
->bandwidth
);
318 } else if (!strncmp(key
, "AUDIO=", key_len
)) {
320 *dest_len
= sizeof(info
->audio
);
321 } else if (!strncmp(key
, "VIDEO=", key_len
)) {
323 *dest_len
= sizeof(info
->video
);
324 } else if (!strncmp(key
, "SUBTITLES=", key_len
)) {
325 *dest
= info
->subtitles
;
326 *dest_len
= sizeof(info
->subtitles
);
331 char uri
[MAX_URL_SIZE
];
336 static void handle_key_args(struct key_info
*info
, const char *key
,
337 int key_len
, char **dest
, int *dest_len
)
339 if (!strncmp(key
, "METHOD=", key_len
)) {
340 *dest
= info
->method
;
341 *dest_len
= sizeof(info
->method
);
342 } else if (!strncmp(key
, "URI=", key_len
)) {
344 *dest_len
= sizeof(info
->uri
);
345 } else if (!strncmp(key
, "IV=", key_len
)) {
347 *dest_len
= sizeof(info
->iv
);
351 struct rendition_info
{
353 char uri
[MAX_URL_SIZE
];
354 char group_id
[MAX_FIELD_LEN
];
355 char language
[MAX_FIELD_LEN
];
356 char assoc_language
[MAX_FIELD_LEN
];
357 char name
[MAX_FIELD_LEN
];
360 char characteristics
[MAX_CHARACTERISTICS_LEN
];
363 static struct rendition
*new_rendition(HLSContext
*c
, struct rendition_info
*info
,
364 const char *url_base
)
366 struct rendition
*rend
;
367 enum AVMediaType type
= AVMEDIA_TYPE_UNKNOWN
;
368 char *characteristic
;
372 if (!strcmp(info
->type
, "AUDIO"))
373 type
= AVMEDIA_TYPE_AUDIO
;
374 else if (!strcmp(info
->type
, "VIDEO"))
375 type
= AVMEDIA_TYPE_VIDEO
;
376 else if (!strcmp(info
->type
, "SUBTITLES"))
377 type
= AVMEDIA_TYPE_SUBTITLE
;
378 else if (!strcmp(info
->type
, "CLOSED-CAPTIONS"))
379 /* CLOSED-CAPTIONS is ignored since we do not support CEA-608 CC in
380 * AVC SEI RBSP anyway */
383 if (type
== AVMEDIA_TYPE_UNKNOWN
)
386 /* URI is mandatory for subtitles as per spec */
387 if (type
== AVMEDIA_TYPE_SUBTITLE
&& !info
->uri
[0])
390 /* TODO: handle subtitles (each segment has to parsed separately) */
391 if (type
== AVMEDIA_TYPE_SUBTITLE
)
394 rend
= av_mallocz(sizeof(struct rendition
));
398 dynarray_add(&c
->renditions
, &c
->n_renditions
, rend
);
401 strcpy(rend
->group_id
, info
->group_id
);
402 strcpy(rend
->language
, info
->language
);
403 strcpy(rend
->name
, info
->name
);
405 /* add the playlist if this is an external rendition */
407 rend
->playlist
= new_playlist(c
, info
->uri
, url_base
);
409 dynarray_add(&rend
->playlist
->renditions
,
410 &rend
->playlist
->n_renditions
, rend
);
413 if (info
->assoc_language
[0]) {
414 int langlen
= strlen(rend
->language
);
415 if (langlen
< sizeof(rend
->language
) - 3) {
416 rend
->language
[langlen
] = ',';
417 strncpy(rend
->language
+ langlen
+ 1, info
->assoc_language
,
418 sizeof(rend
->language
) - langlen
- 2);
422 if (!strcmp(info
->defaultr
, "YES"))
423 rend
->disposition
|= AV_DISPOSITION_DEFAULT
;
424 if (!strcmp(info
->forced
, "YES"))
425 rend
->disposition
|= AV_DISPOSITION_FORCED
;
427 chr_ptr
= info
->characteristics
;
428 while ((characteristic
= av_strtok(chr_ptr
, ",", &saveptr
))) {
429 if (!strcmp(characteristic
, "public.accessibility.describes-music-and-sound"))
430 rend
->disposition
|= AV_DISPOSITION_HEARING_IMPAIRED
;
431 else if (!strcmp(characteristic
, "public.accessibility.describes-video"))
432 rend
->disposition
|= AV_DISPOSITION_VISUAL_IMPAIRED
;
440 static void handle_rendition_args(struct rendition_info
*info
, const char *key
,
441 int key_len
, char **dest
, int *dest_len
)
443 if (!strncmp(key
, "TYPE=", key_len
)) {
445 *dest_len
= sizeof(info
->type
);
446 } else if (!strncmp(key
, "URI=", key_len
)) {
448 *dest_len
= sizeof(info
->uri
);
449 } else if (!strncmp(key
, "GROUP-ID=", key_len
)) {
450 *dest
= info
->group_id
;
451 *dest_len
= sizeof(info
->group_id
);
452 } else if (!strncmp(key
, "LANGUAGE=", key_len
)) {
453 *dest
= info
->language
;
454 *dest_len
= sizeof(info
->language
);
455 } else if (!strncmp(key
, "ASSOC-LANGUAGE=", key_len
)) {
456 *dest
= info
->assoc_language
;
457 *dest_len
= sizeof(info
->assoc_language
);
458 } else if (!strncmp(key
, "NAME=", key_len
)) {
460 *dest_len
= sizeof(info
->name
);
461 } else if (!strncmp(key
, "DEFAULT=", key_len
)) {
462 *dest
= info
->defaultr
;
463 *dest_len
= sizeof(info
->defaultr
);
464 } else if (!strncmp(key
, "FORCED=", key_len
)) {
465 *dest
= info
->forced
;
466 *dest_len
= sizeof(info
->forced
);
467 } else if (!strncmp(key
, "CHARACTERISTICS=", key_len
)) {
468 *dest
= info
->characteristics
;
469 *dest_len
= sizeof(info
->characteristics
);
473 * - AUTOSELECT: client may autoselect based on e.g. system language
474 * - INSTREAM-ID: EIA-608 closed caption number ("CC1".."CC4")
478 /* used by parse_playlist to allocate a new variant+playlist when the
479 * playlist is detected to be a Media Playlist (not Master Playlist)
480 * and we have no parent Master Playlist (parsing of which would have
481 * allocated the variant and playlist already) */
482 static int ensure_playlist(HLSContext
*c
, struct playlist
**pls
, const char *url
)
486 if (!new_variant(c
, NULL
, url
, NULL
))
487 return AVERROR(ENOMEM
);
488 *pls
= c
->playlists
[c
->n_playlists
- 1];
492 /* pls = NULL => Master Playlist or parentless Media Playlist
493 * pls = !NULL => parented Media Playlist, playlist+variant allocated */
494 static int parse_playlist(HLSContext
*c
, const char *url
,
495 struct playlist
*pls
, AVIOContext
*in
)
497 int ret
= 0, is_segment
= 0, is_variant
= 0;
498 int64_t duration
= 0;
499 enum KeyType key_type
= KEY_NONE
;
502 char key
[MAX_URL_SIZE
] = "";
503 char line
[MAX_URL_SIZE
];
506 int64_t seg_offset
= 0;
507 int64_t seg_size
= -1;
508 uint8_t *new_url
= NULL
;
509 struct variant_info variant_info
;
510 char tmp_str
[MAX_URL_SIZE
];
513 AVDictionary
*opts
= NULL
;
515 /* Some HLS servers don't like being sent the range header */
516 av_dict_set(&opts
, "seekable", "0", 0);
518 // broker prior HTTP options that should be consistent across requests
519 av_dict_set(&opts
, "user-agent", c
->user_agent
, 0);
520 av_dict_set(&opts
, "cookies", c
->cookies
, 0);
521 av_dict_set(&opts
, "headers", c
->headers
, 0);
523 ret
= avio_open2(&in
, url
, AVIO_FLAG_READ
,
524 c
->interrupt_callback
, &opts
);
530 if (av_opt_get(in
, "location", AV_OPT_SEARCH_CHILDREN
, &new_url
) >= 0)
533 read_chomp_line(in
, line
, sizeof(line
));
534 if (strcmp(line
, "#EXTM3U")) {
535 ret
= AVERROR_INVALIDDATA
;
540 free_segment_list(pls
);
542 pls
->type
= PLS_TYPE_UNSPECIFIED
;
544 while (!avio_feof(in
)) {
545 read_chomp_line(in
, line
, sizeof(line
));
546 if (av_strstart(line
, "#EXT-X-STREAM-INF:", &ptr
)) {
548 memset(&variant_info
, 0, sizeof(variant_info
));
549 ff_parse_key_value(ptr
, (ff_parse_key_val_cb
) handle_variant_args
,
551 } else if (av_strstart(line
, "#EXT-X-KEY:", &ptr
)) {
552 struct key_info info
= {{0}};
553 ff_parse_key_value(ptr
, (ff_parse_key_val_cb
) handle_key_args
,
557 if (!strcmp(info
.method
, "AES-128"))
558 key_type
= KEY_AES_128
;
559 if (!strncmp(info
.iv
, "0x", 2) || !strncmp(info
.iv
, "0X", 2)) {
560 ff_hex_to_data(iv
, info
.iv
+ 2);
563 av_strlcpy(key
, info
.uri
, sizeof(key
));
564 } else if (av_strstart(line
, "#EXT-X-MEDIA:", &ptr
)) {
565 struct rendition_info info
= {{0}};
566 ff_parse_key_value(ptr
, (ff_parse_key_val_cb
) handle_rendition_args
,
568 new_rendition(c
, &info
, url
);
569 } else if (av_strstart(line
, "#EXT-X-TARGETDURATION:", &ptr
)) {
570 ret
= ensure_playlist(c
, &pls
, url
);
573 pls
->target_duration
= atoi(ptr
) * AV_TIME_BASE
;
574 } else if (av_strstart(line
, "#EXT-X-MEDIA-SEQUENCE:", &ptr
)) {
575 ret
= ensure_playlist(c
, &pls
, url
);
578 pls
->start_seq_no
= atoi(ptr
);
579 } else if (av_strstart(line
, "#EXT-X-PLAYLIST-TYPE:", &ptr
)) {
580 ret
= ensure_playlist(c
, &pls
, url
);
583 if (!strcmp(ptr
, "EVENT"))
584 pls
->type
= PLS_TYPE_EVENT
;
585 else if (!strcmp(ptr
, "VOD"))
586 pls
->type
= PLS_TYPE_VOD
;
587 } else if (av_strstart(line
, "#EXT-X-ENDLIST", &ptr
)) {
590 } else if (av_strstart(line
, "#EXTINF:", &ptr
)) {
592 duration
= atof(ptr
) * AV_TIME_BASE
;
593 } else if (av_strstart(line
, "#EXT-X-BYTERANGE:", &ptr
)) {
594 seg_size
= atoi(ptr
);
595 ptr
= strchr(ptr
, '@');
597 seg_offset
= atoi(ptr
+1);
598 } else if (av_strstart(line
, "#", NULL
)) {
600 } else if (line
[0]) {
602 if (!new_variant(c
, &variant_info
, line
, url
)) {
603 ret
= AVERROR(ENOMEM
);
611 if (!new_variant(c
, 0, url
, NULL
)) {
612 ret
= AVERROR(ENOMEM
);
615 pls
= c
->playlists
[c
->n_playlists
- 1];
617 seg
= av_malloc(sizeof(struct segment
));
619 ret
= AVERROR(ENOMEM
);
622 seg
->duration
= duration
;
623 seg
->key_type
= key_type
;
625 memcpy(seg
->iv
, iv
, sizeof(iv
));
627 int seq
= pls
->start_seq_no
+ pls
->n_segments
;
628 memset(seg
->iv
, 0, sizeof(seg
->iv
));
629 AV_WB32(seg
->iv
+ 12, seq
);
632 if (key_type
!= KEY_NONE
) {
633 ff_make_absolute_url(tmp_str
, sizeof(tmp_str
), url
, key
);
634 seg
->key
= av_strdup(tmp_str
);
637 ret
= AVERROR(ENOMEM
);
644 ff_make_absolute_url(tmp_str
, sizeof(tmp_str
), url
, line
);
645 seg
->url
= av_strdup(tmp_str
);
649 ret
= AVERROR(ENOMEM
);
653 dynarray_add(&pls
->segments
, &pls
->n_segments
, seg
);
656 seg
->size
= seg_size
;
658 seg
->url_offset
= seg_offset
;
659 seg_offset
+= seg_size
;
669 pls
->last_load_time
= av_gettime_relative();
678 enum ReadFromURLMode
{
683 /* read from URLContext, limiting read to current segment */
684 static int read_from_url(struct playlist
*pls
, uint8_t *buf
, int buf_size
,
685 enum ReadFromURLMode mode
)
688 struct segment
*seg
= pls
->segments
[pls
->cur_seq_no
- pls
->start_seq_no
];
690 /* limit read if the segment was only a part of a file */
692 buf_size
= FFMIN(buf_size
, seg
->size
- pls
->cur_seg_offset
);
694 if (mode
== READ_COMPLETE
)
695 ret
= ffurl_read_complete(pls
->input
, buf
, buf_size
);
697 ret
= ffurl_read(pls
->input
, buf
, buf_size
);
700 pls
->cur_seg_offset
+= ret
;
705 /* Parse the raw ID3 data and pass contents to caller */
706 static void parse_id3(AVFormatContext
*s
, AVIOContext
*pb
,
707 AVDictionary
**metadata
, int64_t *dts
,
708 ID3v2ExtraMetaAPIC
**apic
, ID3v2ExtraMeta
**extra_meta
)
710 static const char id3_priv_owner_ts
[] = "com.apple.streaming.transportStreamTimestamp";
711 ID3v2ExtraMeta
*meta
;
713 ff_id3v2_read_dict(pb
, metadata
, ID3v2_DEFAULT_MAGIC
, extra_meta
);
714 for (meta
= *extra_meta
; meta
; meta
= meta
->next
) {
715 if (!strcmp(meta
->tag
, "PRIV")) {
716 ID3v2ExtraMetaPRIV
*priv
= meta
->data
;
717 if (priv
->datasize
== 8 && !strcmp(priv
->owner
, id3_priv_owner_ts
)) {
718 /* 33-bit MPEG timestamp */
719 int64_t ts
= AV_RB64(priv
->data
);
720 av_log(s
, AV_LOG_DEBUG
, "HLS ID3 audio timestamp %"PRId64
"\n", ts
);
721 if ((ts
& ~((1ULL << 33) - 1)) == 0)
724 av_log(s
, AV_LOG_ERROR
, "Invalid HLS ID3 audio timestamp %"PRId64
"\n", ts
);
726 } else if (!strcmp(meta
->tag
, "APIC") && apic
)
731 /* Check if the ID3 metadata contents have changed */
732 static int id3_has_changed_values(struct playlist
*pls
, AVDictionary
*metadata
,
733 ID3v2ExtraMetaAPIC
*apic
)
735 AVDictionaryEntry
*entry
= NULL
;
736 AVDictionaryEntry
*oldentry
;
737 /* check that no keys have changed values */
738 while ((entry
= av_dict_get(metadata
, "", entry
, AV_DICT_IGNORE_SUFFIX
))) {
739 oldentry
= av_dict_get(pls
->id3_initial
, entry
->key
, NULL
, AV_DICT_MATCH_CASE
);
740 if (!oldentry
|| strcmp(oldentry
->value
, entry
->value
) != 0)
744 /* check if apic appeared */
745 if (apic
&& (pls
->ctx
->nb_streams
!= 2 || !pls
->ctx
->streams
[1]->attached_pic
.data
))
749 int size
= pls
->ctx
->streams
[1]->attached_pic
.size
;
750 if (size
!= apic
->buf
->size
- FF_INPUT_BUFFER_PADDING_SIZE
)
753 if (memcmp(apic
->buf
->data
, pls
->ctx
->streams
[1]->attached_pic
.data
, size
) != 0)
760 /* Parse ID3 data and handle the found data */
761 static void handle_id3(AVIOContext
*pb
, struct playlist
*pls
)
763 AVDictionary
*metadata
= NULL
;
764 ID3v2ExtraMetaAPIC
*apic
= NULL
;
765 ID3v2ExtraMeta
*extra_meta
= NULL
;
766 int64_t timestamp
= AV_NOPTS_VALUE
;
768 parse_id3(pls
->ctx
, pb
, &metadata
, ×tamp
, &apic
, &extra_meta
);
770 if (timestamp
!= AV_NOPTS_VALUE
) {
771 pls
->id3_mpegts_timestamp
= timestamp
;
775 if (!pls
->id3_found
) {
776 /* initial ID3 tags */
777 av_assert0(!pls
->id3_deferred_extra
);
780 /* get picture attachment and set text metadata */
781 if (pls
->ctx
->nb_streams
)
782 ff_id3v2_parse_apic(pls
->ctx
, &extra_meta
);
784 /* demuxer not yet opened, defer picture attachment */
785 pls
->id3_deferred_extra
= extra_meta
;
787 av_dict_copy(&pls
->ctx
->metadata
, metadata
, 0);
788 pls
->id3_initial
= metadata
;
791 if (!pls
->id3_changed
&& id3_has_changed_values(pls
, metadata
, apic
)) {
792 avpriv_report_missing_feature(pls
->ctx
, "Changing ID3 metadata in HLS audio elementary stream");
793 pls
->id3_changed
= 1;
795 av_dict_free(&metadata
);
798 if (!pls
->id3_deferred_extra
)
799 ff_id3v2_free_extra_meta(&extra_meta
);
802 /* Intercept and handle ID3 tags between URLContext and AVIOContext */
803 static void intercept_id3(struct playlist
*pls
, uint8_t *buf
,
804 int buf_size
, int *len
)
806 /* intercept id3 tags, we do not want to pass them to the raw
807 * demuxer on all segment switches */
812 /* gather all the id3 tags */
814 /* see if we can retrieve enough data for ID3 header */
815 if (*len
< ID3v2_HEADER_SIZE
&& buf_size
>= ID3v2_HEADER_SIZE
) {
816 bytes
= read_from_url(pls
, buf
+ *len
, ID3v2_HEADER_SIZE
- *len
, READ_COMPLETE
);
819 if (bytes
== ID3v2_HEADER_SIZE
- *len
)
820 /* no EOF yet, so fill the caller buffer again after
821 * we have stripped the ID3 tags */
826 } else if (*len
<= 0) {
833 if (*len
< ID3v2_HEADER_SIZE
)
836 if (ff_id3v2_match(buf
, ID3v2_DEFAULT_MAGIC
)) {
837 struct segment
*seg
= pls
->segments
[pls
->cur_seq_no
- pls
->start_seq_no
];
838 int64_t maxsize
= seg
->size
>= 0 ? seg
->size
: 1024*1024;
839 int taglen
= ff_id3v2_tag_len(buf
);
840 int tag_got_bytes
= FFMIN(taglen
, *len
);
841 int remaining
= taglen
- tag_got_bytes
;
843 if (taglen
> maxsize
) {
844 av_log(pls
->ctx
, AV_LOG_ERROR
, "Too large HLS ID3 tag (%d > %"PRId64
" bytes)\n",
850 * Copy the id3 tag to our temporary id3 buffer.
851 * We could read a small id3 tag directly without memcpy, but
852 * we would still need to copy the large tags, and handling
853 * both of those cases together with the possibility for multiple
854 * tags would make the handling a bit complex.
856 pls
->id3_buf
= av_fast_realloc(pls
->id3_buf
, &pls
->id3_buf_size
, id3_buf_pos
+ taglen
);
859 memcpy(pls
->id3_buf
+ id3_buf_pos
, buf
, tag_got_bytes
);
860 id3_buf_pos
+= tag_got_bytes
;
862 /* strip the intercepted bytes */
863 *len
-= tag_got_bytes
;
864 memmove(buf
, buf
+ tag_got_bytes
, *len
);
865 av_log(pls
->ctx
, AV_LOG_DEBUG
, "Stripped %d HLS ID3 bytes\n", tag_got_bytes
);
868 /* read the rest of the tag in */
869 if (read_from_url(pls
, pls
->id3_buf
+ id3_buf_pos
, remaining
, READ_COMPLETE
) != remaining
)
871 id3_buf_pos
+= remaining
;
872 av_log(pls
->ctx
, AV_LOG_DEBUG
, "Stripped additional %d HLS ID3 bytes\n", remaining
);
876 /* no more ID3 tags */
881 /* re-fill buffer for the caller unless EOF */
882 if (*len
>= 0 && (fill_buf
|| *len
== 0)) {
883 bytes
= read_from_url(pls
, buf
+ *len
, buf_size
- *len
, READ_NORMAL
);
885 /* ignore error if we already had some data */
893 /* Now parse all the ID3 tags */
894 AVIOContext id3ioctx
;
895 ffio_init_context(&id3ioctx
, pls
->id3_buf
, id3_buf_pos
, 0, NULL
, NULL
, NULL
, NULL
);
896 handle_id3(&id3ioctx
, pls
);
899 if (pls
->is_id3_timestamped
== -1)
900 pls
->is_id3_timestamped
= (pls
->id3_mpegts_timestamp
!= AV_NOPTS_VALUE
);
903 static int open_input(HLSContext
*c
, struct playlist
*pls
)
905 AVDictionary
*opts
= NULL
;
906 AVDictionary
*opts2
= NULL
;
908 struct segment
*seg
= pls
->segments
[pls
->cur_seq_no
- pls
->start_seq_no
];
910 // broker prior HTTP options that should be consistent across requests
911 av_dict_set(&opts
, "user-agent", c
->user_agent
, 0);
912 av_dict_set(&opts
, "cookies", c
->cookies
, 0);
913 av_dict_set(&opts
, "headers", c
->headers
, 0);
914 av_dict_set(&opts
, "seekable", "0", 0);
916 // Same opts for key request (ffurl_open mutilates the opts so it cannot be used twice)
917 av_dict_copy(&opts2
, opts
, 0);
919 if (seg
->size
>= 0) {
920 /* try to restrict the HTTP request to the part we want
921 * (if this is in fact a HTTP request) */
922 av_dict_set_int(&opts
, "offset", seg
->url_offset
, 0);
923 av_dict_set_int(&opts
, "end_offset", seg
->url_offset
+ seg
->size
, 0);
926 av_log(pls
->parent
, AV_LOG_VERBOSE
, "HLS request for url '%s', offset %"PRId64
", playlist %d\n",
927 seg
->url
, seg
->url_offset
, pls
->index
);
929 if (seg
->key_type
== KEY_NONE
) {
930 ret
= ffurl_open(&pls
->input
, seg
->url
, AVIO_FLAG_READ
,
931 &pls
->parent
->interrupt_callback
, &opts
);
933 } else if (seg
->key_type
== KEY_AES_128
) {
934 char iv
[33], key
[33], url
[MAX_URL_SIZE
];
935 if (strcmp(seg
->key
, pls
->key_url
)) {
937 if (ffurl_open(&uc
, seg
->key
, AVIO_FLAG_READ
,
938 &pls
->parent
->interrupt_callback
, &opts2
) == 0) {
939 if (ffurl_read_complete(uc
, pls
->key
, sizeof(pls
->key
))
940 != sizeof(pls
->key
)) {
941 av_log(NULL
, AV_LOG_ERROR
, "Unable to read key file %s\n",
946 av_log(NULL
, AV_LOG_ERROR
, "Unable to open key file %s\n",
949 av_strlcpy(pls
->key_url
, seg
->key
, sizeof(pls
->key_url
));
951 ff_data_to_hex(iv
, seg
->iv
, sizeof(seg
->iv
), 0);
952 ff_data_to_hex(key
, pls
->key
, sizeof(pls
->key
), 0);
953 iv
[32] = key
[32] = '\0';
954 if (strstr(seg
->url
, "://"))
955 snprintf(url
, sizeof(url
), "crypto+%s", seg
->url
);
957 snprintf(url
, sizeof(url
), "crypto:%s", seg
->url
);
958 if ((ret
= ffurl_alloc(&pls
->input
, url
, AVIO_FLAG_READ
,
959 &pls
->parent
->interrupt_callback
)) < 0)
961 av_opt_set(pls
->input
->priv_data
, "key", key
, 0);
962 av_opt_set(pls
->input
->priv_data
, "iv", iv
, 0);
964 if ((ret
= ffurl_connect(pls
->input
, &opts
)) < 0) {
965 ffurl_close(pls
->input
);
972 ret
= AVERROR(ENOSYS
);
974 /* Seek to the requested position. If this was a HTTP request, the offset
975 * should already be where want it to, but this allows e.g. local testing
976 * without a HTTP server. */
977 if (ret
== 0 && seg
->key_type
== KEY_NONE
) {
978 int seekret
= ffurl_seek(pls
->input
, seg
->url_offset
, SEEK_SET
);
980 av_log(pls
->parent
, AV_LOG_ERROR
, "Unable to seek to offset %"PRId64
" of HLS segment '%s'\n", seg
->url_offset
, seg
->url
);
982 ffurl_close(pls
->input
);
989 av_dict_free(&opts2
);
990 pls
->cur_seg_offset
= 0;
994 static int64_t default_reload_interval(struct playlist
*pls
)
996 return pls
->n_segments
> 0 ?
997 pls
->segments
[pls
->n_segments
- 1]->duration
:
998 pls
->target_duration
;
1001 static int read_data(void *opaque
, uint8_t *buf
, int buf_size
)
1003 struct playlist
*v
= opaque
;
1004 HLSContext
*c
= v
->parent
->priv_data
;
1006 int just_opened
= 0;
1013 int64_t reload_interval
;
1015 /* Check that the playlist is still needed before opening a new
1017 if (v
->ctx
&& v
->ctx
->nb_streams
&&
1018 v
->parent
->nb_streams
>= v
->stream_offset
+ v
->ctx
->nb_streams
) {
1020 for (i
= v
->stream_offset
; i
< v
->stream_offset
+ v
->ctx
->nb_streams
;
1022 if (v
->parent
->streams
[i
]->discard
< AVDISCARD_ALL
)
1027 av_log(v
->parent
, AV_LOG_INFO
, "No longer receiving playlist %d\n",
1032 /* If this is a live stream and the reload interval has elapsed since
1033 * the last playlist reload, reload the playlists now. */
1034 reload_interval
= default_reload_interval(v
);
1038 av_gettime_relative() - v
->last_load_time
>= reload_interval
) {
1039 if ((ret
= parse_playlist(c
, v
->url
, v
, NULL
)) < 0) {
1040 av_log(v
->parent
, AV_LOG_WARNING
, "Failed to reload playlist %d\n",
1044 /* If we need to reload the playlist again below (if
1045 * there's still no more segments), switch to a reload
1046 * interval of half the target duration. */
1047 reload_interval
= v
->target_duration
/ 2;
1049 if (v
->cur_seq_no
< v
->start_seq_no
) {
1050 av_log(NULL
, AV_LOG_WARNING
,
1051 "skipping %d segments ahead, expired from playlists\n",
1052 v
->start_seq_no
- v
->cur_seq_no
);
1053 v
->cur_seq_no
= v
->start_seq_no
;
1055 if (v
->cur_seq_no
>= v
->start_seq_no
+ v
->n_segments
) {
1058 while (av_gettime_relative() - v
->last_load_time
< reload_interval
) {
1059 if (ff_check_interrupt(c
->interrupt_callback
))
1060 return AVERROR_EXIT
;
1061 av_usleep(100*1000);
1063 /* Enough time has elapsed since the last reload */
1067 ret
= open_input(c
, v
);
1069 av_log(v
->parent
, AV_LOG_WARNING
, "Failed to open segment of playlist %d\n",
1076 ret
= read_from_url(v
, buf
, buf_size
, READ_NORMAL
);
1078 if (just_opened
&& v
->is_id3_timestamped
!= 0) {
1079 /* Intercept ID3 tags here, elementary audio streams are required
1080 * to convey timestamps using them in the beginning of each segment. */
1081 intercept_id3(v
, buf
, buf_size
, &ret
);
1086 ffurl_close(v
->input
);
1090 c
->cur_seq_no
= v
->cur_seq_no
;
1095 static int playlist_in_multiple_variants(HLSContext
*c
, struct playlist
*pls
)
1097 int variant_count
= 0;
1100 for (i
= 0; i
< c
->n_variants
&& variant_count
< 2; i
++) {
1101 struct variant
*v
= c
->variants
[i
];
1103 for (j
= 0; j
< v
->n_playlists
; j
++) {
1104 if (v
->playlists
[j
] == pls
) {
1111 return variant_count
>= 2;
1114 static void add_renditions_to_variant(HLSContext
*c
, struct variant
*var
,
1115 enum AVMediaType type
, const char *group_id
)
1119 for (i
= 0; i
< c
->n_renditions
; i
++) {
1120 struct rendition
*rend
= c
->renditions
[i
];
1122 if (rend
->type
== type
&& !strcmp(rend
->group_id
, group_id
)) {
1125 /* rendition is an external playlist
1126 * => add the playlist to the variant */
1127 dynarray_add(&var
->playlists
, &var
->n_playlists
, rend
->playlist
);
1129 /* rendition is part of the variant main Media Playlist
1130 * => add the rendition to the main Media Playlist */
1131 dynarray_add(&var
->playlists
[0]->renditions
,
1132 &var
->playlists
[0]->n_renditions
,
1138 static void add_metadata_from_renditions(AVFormatContext
*s
, struct playlist
*pls
,
1139 enum AVMediaType type
)
1144 for (i
= 0; i
< pls
->ctx
->nb_streams
; i
++) {
1145 AVStream
*st
= s
->streams
[pls
->stream_offset
+ i
];
1147 if (st
->codec
->codec_type
!= type
)
1150 for (; rend_idx
< pls
->n_renditions
; rend_idx
++) {
1151 struct rendition
*rend
= pls
->renditions
[rend_idx
];
1153 if (rend
->type
!= type
)
1156 if (rend
->language
[0])
1157 av_dict_set(&st
->metadata
, "language", rend
->language
, 0);
1159 av_dict_set(&st
->metadata
, "comment", rend
->name
, 0);
1161 st
->disposition
|= rend
->disposition
;
1163 if (rend_idx
>=pls
->n_renditions
)
1168 /* if timestamp was in valid range: returns 1 and sets seq_no
1169 * if not: returns 0 and sets seq_no to closest segment */
1170 static int find_timestamp_in_playlist(HLSContext
*c
, struct playlist
*pls
,
1171 int64_t timestamp
, int *seq_no
)
1174 int64_t pos
= c
->first_timestamp
== AV_NOPTS_VALUE
?
1175 0 : c
->first_timestamp
;
1177 if (timestamp
< pos
) {
1178 *seq_no
= pls
->start_seq_no
;
1182 for (i
= 0; i
< pls
->n_segments
; i
++) {
1183 int64_t diff
= pos
+ pls
->segments
[i
]->duration
- timestamp
;
1185 *seq_no
= pls
->start_seq_no
+ i
;
1188 pos
+= pls
->segments
[i
]->duration
;
1191 *seq_no
= pls
->start_seq_no
+ pls
->n_segments
- 1;
1196 static int select_cur_seq_no(HLSContext
*c
, struct playlist
*pls
)
1200 if (!pls
->finished
&& !c
->first_packet
&&
1201 av_gettime_relative() - pls
->last_load_time
>= default_reload_interval(pls
))
1202 /* reload the playlist since it was suspended */
1203 parse_playlist(c
, pls
->url
, pls
, NULL
);
1205 /* If playback is already in progress (we are just selecting a new
1206 * playlist) and this is a complete file, find the matching segment
1207 * by counting durations. */
1208 if (pls
->finished
&& c
->cur_timestamp
!= AV_NOPTS_VALUE
) {
1209 find_timestamp_in_playlist(c
, pls
, c
->cur_timestamp
, &seq_no
);
1213 if (!pls
->finished
) {
1214 if (!c
->first_packet
&& /* we are doing a segment selection during playback */
1215 c
->cur_seq_no
>= pls
->start_seq_no
&&
1216 c
->cur_seq_no
< pls
->start_seq_no
+ pls
->n_segments
)
1217 /* While spec 3.4.3 says that we cannot assume anything about the
1218 * content at the same sequence number on different playlists,
1219 * in practice this seems to work and doing it otherwise would
1220 * require us to download a segment to inspect its timestamps. */
1221 return c
->cur_seq_no
;
1223 /* If this is a live stream with more than 3 segments, start at the
1224 * third last segment. */
1225 if (pls
->n_segments
> 3)
1226 return pls
->start_seq_no
+ pls
->n_segments
- 3;
1229 /* Otherwise just start on the first segment. */
1230 return pls
->start_seq_no
;
1233 static int hls_read_header(AVFormatContext
*s
)
1235 URLContext
*u
= (s
->flags
& AVFMT_FLAG_CUSTOM_IO
) ? NULL
: s
->pb
->opaque
;
1236 HLSContext
*c
= s
->priv_data
;
1237 int ret
= 0, i
, j
, stream_offset
= 0;
1239 c
->interrupt_callback
= &s
->interrupt_callback
;
1241 c
->first_packet
= 1;
1242 c
->first_timestamp
= AV_NOPTS_VALUE
;
1243 c
->cur_timestamp
= AV_NOPTS_VALUE
;
1245 // if the URL context is good, read important options we must broker later
1246 if (u
&& u
->prot
->priv_data_class
) {
1247 // get the previous user agent & set back to null if string size is zero
1248 av_freep(&c
->user_agent
);
1249 av_opt_get(u
->priv_data
, "user-agent", 0, (uint8_t**)&(c
->user_agent
));
1250 if (c
->user_agent
&& !strlen(c
->user_agent
))
1251 av_freep(&c
->user_agent
);
1253 // get the previous cookies & set back to null if string size is zero
1254 av_freep(&c
->cookies
);
1255 av_opt_get(u
->priv_data
, "cookies", 0, (uint8_t**)&(c
->cookies
));
1256 if (c
->cookies
&& !strlen(c
->cookies
))
1257 av_freep(&c
->cookies
);
1259 // get the previous headers & set back to null if string size is zero
1260 av_freep(&c
->headers
);
1261 av_opt_get(u
->priv_data
, "headers", 0, (uint8_t**)&(c
->headers
));
1262 if (c
->headers
&& !strlen(c
->headers
))
1263 av_freep(&c
->headers
);
1266 if ((ret
= parse_playlist(c
, s
->filename
, NULL
, s
->pb
)) < 0)
1269 if (c
->n_variants
== 0) {
1270 av_log(NULL
, AV_LOG_WARNING
, "Empty playlist\n");
1274 /* If the playlist only contained playlists (Master Playlist),
1275 * parse each individual playlist. */
1276 if (c
->n_playlists
> 1 || c
->playlists
[0]->n_segments
== 0) {
1277 for (i
= 0; i
< c
->n_playlists
; i
++) {
1278 struct playlist
*pls
= c
->playlists
[i
];
1279 if ((ret
= parse_playlist(c
, pls
->url
, pls
, NULL
)) < 0)
1284 if (c
->variants
[0]->playlists
[0]->n_segments
== 0) {
1285 av_log(NULL
, AV_LOG_WARNING
, "Empty playlist\n");
1290 /* If this isn't a live stream, calculate the total duration of the
1292 if (c
->variants
[0]->playlists
[0]->finished
) {
1293 int64_t duration
= 0;
1294 for (i
= 0; i
< c
->variants
[0]->playlists
[0]->n_segments
; i
++)
1295 duration
+= c
->variants
[0]->playlists
[0]->segments
[i
]->duration
;
1296 s
->duration
= duration
;
1299 /* Associate renditions with variants */
1300 for (i
= 0; i
< c
->n_variants
; i
++) {
1301 struct variant
*var
= c
->variants
[i
];
1303 if (var
->audio_group
[0])
1304 add_renditions_to_variant(c
, var
, AVMEDIA_TYPE_AUDIO
, var
->audio_group
);
1305 if (var
->video_group
[0])
1306 add_renditions_to_variant(c
, var
, AVMEDIA_TYPE_VIDEO
, var
->video_group
);
1307 if (var
->subtitles_group
[0])
1308 add_renditions_to_variant(c
, var
, AVMEDIA_TYPE_SUBTITLE
, var
->subtitles_group
);
1311 /* Open the demuxer for each playlist */
1312 for (i
= 0; i
< c
->n_playlists
; i
++) {
1313 struct playlist
*pls
= c
->playlists
[i
];
1314 AVInputFormat
*in_fmt
= NULL
;
1316 if (pls
->n_segments
== 0)
1319 if (!(pls
->ctx
= avformat_alloc_context())) {
1320 ret
= AVERROR(ENOMEM
);
1327 pls
->cur_seq_no
= select_cur_seq_no(c
, pls
);
1329 pls
->read_buffer
= av_malloc(INITIAL_BUFFER_SIZE
);
1330 ffio_init_context(&pls
->pb
, pls
->read_buffer
, INITIAL_BUFFER_SIZE
, 0, pls
,
1331 read_data
, NULL
, NULL
);
1332 pls
->pb
.seekable
= 0;
1333 ret
= av_probe_input_buffer(&pls
->pb
, &in_fmt
, pls
->segments
[0]->url
,
1336 /* Free the ctx - it isn't initialized properly at this point,
1337 * so avformat_close_input shouldn't be called. If
1338 * avformat_open_input fails below, it frees and zeros the
1339 * context, so it doesn't need any special treatment like this. */
1340 av_log(s
, AV_LOG_ERROR
, "Error when loading first segment '%s'\n", pls
->segments
[0]->url
);
1341 avformat_free_context(pls
->ctx
);
1345 pls
->ctx
->pb
= &pls
->pb
;
1346 pls
->stream_offset
= stream_offset
;
1348 if ((ret
= ff_copy_whitelists(pls
->ctx
, s
)) < 0)
1351 ret
= avformat_open_input(&pls
->ctx
, pls
->segments
[0]->url
, in_fmt
, NULL
);
1355 if (pls
->id3_deferred_extra
&& pls
->ctx
->nb_streams
== 1) {
1356 ff_id3v2_parse_apic(pls
->ctx
, &pls
->id3_deferred_extra
);
1357 avformat_queue_attached_pictures(pls
->ctx
);
1358 ff_id3v2_free_extra_meta(&pls
->id3_deferred_extra
);
1359 pls
->id3_deferred_extra
= NULL
;
1362 pls
->ctx
->ctx_flags
&= ~AVFMTCTX_NOHEADER
;
1363 ret
= avformat_find_stream_info(pls
->ctx
, NULL
);
1367 if (pls
->is_id3_timestamped
== -1)
1368 av_log(s
, AV_LOG_WARNING
, "No expected HTTP requests have been made\n");
1370 /* Create new AVStreams for each stream in this playlist */
1371 for (j
= 0; j
< pls
->ctx
->nb_streams
; j
++) {
1372 AVStream
*st
= avformat_new_stream(s
, NULL
);
1373 AVStream
*ist
= pls
->ctx
->streams
[j
];
1375 ret
= AVERROR(ENOMEM
);
1380 avcodec_copy_context(st
->codec
, pls
->ctx
->streams
[j
]->codec
);
1382 if (pls
->is_id3_timestamped
) /* custom timestamps via id3 */
1383 avpriv_set_pts_info(st
, 33, 1, MPEG_TIME_BASE
);
1385 avpriv_set_pts_info(st
, ist
->pts_wrap_bits
, ist
->time_base
.num
, ist
->time_base
.den
);
1388 add_metadata_from_renditions(s
, pls
, AVMEDIA_TYPE_AUDIO
);
1389 add_metadata_from_renditions(s
, pls
, AVMEDIA_TYPE_VIDEO
);
1390 add_metadata_from_renditions(s
, pls
, AVMEDIA_TYPE_SUBTITLE
);
1392 stream_offset
+= pls
->ctx
->nb_streams
;
1395 /* Create a program for each variant */
1396 for (i
= 0; i
< c
->n_variants
; i
++) {
1397 struct variant
*v
= c
->variants
[i
];
1400 program
= av_new_program(s
, i
);
1403 av_dict_set_int(&program
->metadata
, "variant_bitrate", v
->bandwidth
, 0);
1405 for (j
= 0; j
< v
->n_playlists
; j
++) {
1406 struct playlist
*pls
= v
->playlists
[j
];
1407 int is_shared
= playlist_in_multiple_variants(c
, pls
);
1410 for (k
= 0; k
< pls
->ctx
->nb_streams
; k
++) {
1411 struct AVStream
*st
= s
->streams
[pls
->stream_offset
+ k
];
1413 ff_program_add_stream_index(s
, i
, pls
->stream_offset
+ k
);
1415 /* Set variant_bitrate for streams unique to this variant */
1416 if (!is_shared
&& v
->bandwidth
)
1417 av_dict_set_int(&st
->metadata
, "variant_bitrate", v
->bandwidth
, 0);
1424 free_playlist_list(c
);
1425 free_variant_list(c
);
1426 free_rendition_list(c
);
1430 static int recheck_discard_flags(AVFormatContext
*s
, int first
)
1432 HLSContext
*c
= s
->priv_data
;
1435 /* Check if any new streams are needed */
1436 for (i
= 0; i
< c
->n_playlists
; i
++)
1437 c
->playlists
[i
]->cur_needed
= 0;
1439 for (i
= 0; i
< s
->nb_streams
; i
++) {
1440 AVStream
*st
= s
->streams
[i
];
1441 struct playlist
*pls
= c
->playlists
[s
->streams
[i
]->id
];
1442 if (st
->discard
< AVDISCARD_ALL
)
1443 pls
->cur_needed
= 1;
1445 for (i
= 0; i
< c
->n_playlists
; i
++) {
1446 struct playlist
*pls
= c
->playlists
[i
];
1447 if (pls
->cur_needed
&& !pls
->needed
) {
1450 pls
->cur_seq_no
= select_cur_seq_no(c
, pls
);
1451 pls
->pb
.eof_reached
= 0;
1452 if (c
->cur_timestamp
!= AV_NOPTS_VALUE
) {
1454 pls
->seek_timestamp
= c
->cur_timestamp
;
1455 pls
->seek_flags
= AVSEEK_FLAG_ANY
;
1456 pls
->seek_stream_index
= -1;
1458 av_log(s
, AV_LOG_INFO
, "Now receiving playlist %d, segment %d\n", i
, pls
->cur_seq_no
);
1459 } else if (first
&& !pls
->cur_needed
&& pls
->needed
) {
1461 ffurl_close(pls
->input
);
1465 av_log(s
, AV_LOG_INFO
, "No longer receiving playlist %d\n", i
);
1471 static void fill_timing_for_id3_timestamped_stream(struct playlist
*pls
)
1473 if (pls
->id3_offset
>= 0) {
1474 pls
->pkt
.dts
= pls
->id3_mpegts_timestamp
+
1475 av_rescale_q(pls
->id3_offset
,
1476 pls
->ctx
->streams
[pls
->pkt
.stream_index
]->time_base
,
1478 if (pls
->pkt
.duration
)
1479 pls
->id3_offset
+= pls
->pkt
.duration
;
1481 pls
->id3_offset
= -1;
1483 /* there have been packets with unknown duration
1484 * since the last id3 tag, should not normally happen */
1485 pls
->pkt
.dts
= AV_NOPTS_VALUE
;
1488 if (pls
->pkt
.duration
)
1489 pls
->pkt
.duration
= av_rescale_q(pls
->pkt
.duration
,
1490 pls
->ctx
->streams
[pls
->pkt
.stream_index
]->time_base
,
1493 pls
->pkt
.pts
= AV_NOPTS_VALUE
;
1496 static AVRational
get_timebase(struct playlist
*pls
)
1498 if (pls
->is_id3_timestamped
)
1499 return MPEG_TIME_BASE_Q
;
1501 return pls
->ctx
->streams
[pls
->pkt
.stream_index
]->time_base
;
1504 static int compare_ts_with_wrapdetect(int64_t ts_a
, struct playlist
*pls_a
,
1505 int64_t ts_b
, struct playlist
*pls_b
)
1507 int64_t scaled_ts_a
= av_rescale_q(ts_a
, get_timebase(pls_a
), MPEG_TIME_BASE_Q
);
1508 int64_t scaled_ts_b
= av_rescale_q(ts_b
, get_timebase(pls_b
), MPEG_TIME_BASE_Q
);
1510 return av_compare_mod(scaled_ts_a
, scaled_ts_b
, 1LL << 33);
1513 static int hls_read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
1515 HLSContext
*c
= s
->priv_data
;
1516 int ret
, i
, minplaylist
= -1;
1518 recheck_discard_flags(s
, c
->first_packet
);
1520 for (i
= 0; i
< c
->n_playlists
; i
++) {
1521 struct playlist
*pls
= c
->playlists
[i
];
1522 /* Make sure we've got one buffered packet from each open playlist
1524 if (pls
->needed
&& !pls
->pkt
.data
) {
1528 ret
= av_read_frame(pls
->ctx
, &pls
->pkt
);
1530 if (!avio_feof(&pls
->pb
) && ret
!= AVERROR_EOF
)
1532 reset_packet(&pls
->pkt
);
1535 /* stream_index check prevents matching picture attachments etc. */
1536 if (pls
->is_id3_timestamped
&& pls
->pkt
.stream_index
== 0) {
1537 /* audio elementary streams are id3 timestamped */
1538 fill_timing_for_id3_timestamped_stream(pls
);
1541 if (c
->first_timestamp
== AV_NOPTS_VALUE
&&
1542 pls
->pkt
.dts
!= AV_NOPTS_VALUE
)
1543 c
->first_timestamp
= av_rescale_q(pls
->pkt
.dts
,
1544 get_timebase(pls
), AV_TIME_BASE_Q
);
1547 if (pls
->seek_timestamp
== AV_NOPTS_VALUE
)
1550 if (pls
->seek_stream_index
< 0 ||
1551 pls
->seek_stream_index
== pls
->pkt
.stream_index
) {
1553 if (pls
->pkt
.dts
== AV_NOPTS_VALUE
) {
1554 pls
->seek_timestamp
= AV_NOPTS_VALUE
;
1558 tb
= get_timebase(pls
);
1559 ts_diff
= av_rescale_rnd(pls
->pkt
.dts
, AV_TIME_BASE
,
1560 tb
.den
, AV_ROUND_DOWN
) -
1561 pls
->seek_timestamp
;
1562 if (ts_diff
>= 0 && (pls
->seek_flags
& AVSEEK_FLAG_ANY
||
1563 pls
->pkt
.flags
& AV_PKT_FLAG_KEY
)) {
1564 pls
->seek_timestamp
= AV_NOPTS_VALUE
;
1568 av_free_packet(&pls
->pkt
);
1569 reset_packet(&pls
->pkt
);
1572 /* Check if this stream has the packet with the lowest dts */
1573 if (pls
->pkt
.data
) {
1574 struct playlist
*minpls
= minplaylist
< 0 ?
1575 NULL
: c
->playlists
[minplaylist
];
1576 if (minplaylist
< 0) {
1579 int64_t dts
= pls
->pkt
.dts
;
1580 int64_t mindts
= minpls
->pkt
.dts
;
1582 if (dts
== AV_NOPTS_VALUE
||
1583 (mindts
!= AV_NOPTS_VALUE
&& compare_ts_with_wrapdetect(dts
, pls
, mindts
, minpls
) < 0))
1589 /* If we got a packet, return it */
1590 if (minplaylist
>= 0) {
1591 struct playlist
*pls
= c
->playlists
[minplaylist
];
1593 pkt
->stream_index
+= pls
->stream_offset
;
1594 reset_packet(&c
->playlists
[minplaylist
]->pkt
);
1596 if (pkt
->dts
!= AV_NOPTS_VALUE
)
1597 c
->cur_timestamp
= av_rescale_q(pkt
->dts
,
1598 pls
->ctx
->streams
[pls
->pkt
.stream_index
]->time_base
,
1606 static int hls_close(AVFormatContext
*s
)
1608 HLSContext
*c
= s
->priv_data
;
1610 free_playlist_list(c
);
1611 free_variant_list(c
);
1612 free_rendition_list(c
);
1616 static int hls_read_seek(AVFormatContext
*s
, int stream_index
,
1617 int64_t timestamp
, int flags
)
1619 HLSContext
*c
= s
->priv_data
;
1620 struct playlist
*seek_pls
= NULL
;
1622 int64_t first_timestamp
, seek_timestamp
, duration
;
1624 if ((flags
& AVSEEK_FLAG_BYTE
) ||
1625 !(c
->variants
[0]->playlists
[0]->finished
|| c
->variants
[0]->playlists
[0]->type
== PLS_TYPE_EVENT
))
1626 return AVERROR(ENOSYS
);
1628 first_timestamp
= c
->first_timestamp
== AV_NOPTS_VALUE
?
1629 0 : c
->first_timestamp
;
1631 seek_timestamp
= av_rescale_rnd(timestamp
, AV_TIME_BASE
,
1632 s
->streams
[stream_index
]->time_base
.den
,
1633 flags
& AVSEEK_FLAG_BACKWARD
?
1634 AV_ROUND_DOWN
: AV_ROUND_UP
);
1636 duration
= s
->duration
== AV_NOPTS_VALUE
?
1639 if (0 < duration
&& duration
< seek_timestamp
- first_timestamp
)
1640 return AVERROR(EIO
);
1642 /* find the playlist with the specified stream */
1643 for (i
= 0; i
< c
->n_playlists
; i
++) {
1644 struct playlist
*pls
= c
->playlists
[i
];
1645 if (stream_index
>= pls
->stream_offset
&&
1646 stream_index
- pls
->stream_offset
< pls
->ctx
->nb_streams
) {
1651 /* check if the timestamp is valid for the playlist with the
1652 * specified stream index */
1653 if (!seek_pls
|| !find_timestamp_in_playlist(c
, seek_pls
, seek_timestamp
, &seq_no
))
1654 return AVERROR(EIO
);
1656 /* set segment now so we do not need to search again below */
1657 seek_pls
->cur_seq_no
= seq_no
;
1658 seek_pls
->seek_stream_index
= stream_index
- seek_pls
->stream_offset
;
1660 for (i
= 0; i
< c
->n_playlists
; i
++) {
1662 struct playlist
*pls
= c
->playlists
[i
];
1664 ffurl_close(pls
->input
);
1667 av_free_packet(&pls
->pkt
);
1668 reset_packet(&pls
->pkt
);
1669 pls
->pb
.eof_reached
= 0;
1670 /* Clear any buffered data */
1671 pls
->pb
.buf_end
= pls
->pb
.buf_ptr
= pls
->pb
.buffer
;
1672 /* Reset the pos, to let the mpegts demuxer know we've seeked. */
1674 /* Flush the packet queue of the subdemuxer. */
1675 ff_read_frame_flush(pls
->ctx
);
1677 pls
->seek_timestamp
= seek_timestamp
;
1678 pls
->seek_flags
= flags
;
1680 if (pls
!= seek_pls
) {
1681 /* set closest segment seq_no for playlists not handled above */
1682 find_timestamp_in_playlist(c
, pls
, seek_timestamp
, &pls
->cur_seq_no
);
1683 /* seek the playlist to the given position without taking
1684 * keyframes into account since this playlist does not have the
1685 * specified stream where we should look for the keyframes */
1686 pls
->seek_stream_index
= -1;
1687 pls
->seek_flags
|= AVSEEK_FLAG_ANY
;
1691 c
->cur_timestamp
= seek_timestamp
;
1696 static int hls_probe(AVProbeData
*p
)
1698 /* Require #EXTM3U at the start, and either one of the ones below
1699 * somewhere for a proper match. */
1700 if (strncmp(p
->buf
, "#EXTM3U", 7))
1702 if (strstr(p
->buf
, "#EXT-X-STREAM-INF:") ||
1703 strstr(p
->buf
, "#EXT-X-TARGETDURATION:") ||
1704 strstr(p
->buf
, "#EXT-X-MEDIA-SEQUENCE:"))
1705 return AVPROBE_SCORE_MAX
;
1709 AVInputFormat ff_hls_demuxer
= {
1710 .name
= "hls,applehttp",
1711 .long_name
= NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
1712 .priv_data_size
= sizeof(HLSContext
),
1713 .read_probe
= hls_probe
,
1714 .read_header
= hls_read_header
,
1715 .read_packet
= hls_read_packet
,
1716 .read_close
= hls_close
,
1717 .read_seek
= hls_read_seek
,