Go to the documentation of this file.
30 #include "config_components.h"
51 #define INITIAL_BUFFER_SIZE 32768
53 #define MAX_FIELD_LEN 64
54 #define MAX_CHARACTERISTICS_LEN 512
56 #define MPEG_TIME_BASE 90000
57 #define MPEG_TIME_BASE_Q (AVRational){1, MPEG_TIME_BASE}
285 for (
i = 0;
i <
c->n_playlists;
i++) {
316 for (
i = 0;
i <
c->n_variants;
i++) {
328 for (
i = 0;
i <
c->n_renditions;
i++)
344 for (
int i = 0;
i <
c->n_playlists;
i++) {
345 if (!strcmp(
c->playlists[
i]->url, abs_url))
346 return c->playlists[
i];
379 const char *url,
const char *
base)
405 int key_len,
char **dest,
int *dest_len)
408 if (!strncmp(
key,
"BANDWIDTH=", key_len)) {
409 *dest =
info->bandwidth;
410 *dest_len =
sizeof(
info->bandwidth);
411 }
else if (!strncmp(
key,
"AUDIO=", key_len)) {
413 *dest_len =
sizeof(
info->audio);
414 }
else if (!strncmp(
key,
"VIDEO=", key_len)) {
416 *dest_len =
sizeof(
info->video);
417 }
else if (!strncmp(
key,
"SUBTITLES=", key_len)) {
418 *dest =
info->subtitles;
419 *dest_len =
sizeof(
info->subtitles);
430 int key_len,
char **dest,
int *dest_len)
433 if (!strncmp(
key,
"METHOD=", key_len)) {
434 *dest =
info->method;
435 *dest_len =
sizeof(
info->method);
436 }
else if (!strncmp(
key,
"URI=", key_len)) {
438 *dest_len =
sizeof(
info->uri);
439 }
else if (!strncmp(
key,
"IV=", key_len)) {
441 *dest_len =
sizeof(
info->iv);
452 const char *url_base)
479 if (
info->byterange[0]) {
481 ptr = strchr(
info->byterange,
'@');
500 int key_len,
char **dest,
int *dest_len)
503 if (!strncmp(
key,
"URI=", key_len)) {
505 *dest_len =
sizeof(
info->uri);
506 }
else if (!strncmp(
key,
"BYTERANGE=", key_len)) {
507 *dest =
info->byterange;
508 *dest_len =
sizeof(
info->byterange);
525 const char *url_base)
529 char *characteristic;
533 if (!strcmp(
info->type,
"AUDIO"))
535 else if (!strcmp(
info->type,
"VIDEO"))
537 else if (!strcmp(
info->type,
"SUBTITLES"))
539 else if (!strcmp(
info->type,
"CLOSED-CAPTIONS"))
579 if (
info->assoc_language[0]) {
580 size_t langlen = strlen(rend->
language);
581 if (langlen <
sizeof(rend->
language) - 3) {
585 info->assoc_language,
586 sizeof(rend->
language) - langlen - 1);
587 if (langlen + assoc_len + 2 >
sizeof(rend->
language))
589 info->assoc_language);
593 if (!strcmp(
info->defaultr,
"YES"))
595 if (!strcmp(
info->forced,
"YES"))
598 chr_ptr =
info->characteristics;
599 while ((characteristic =
av_strtok(chr_ptr,
",", &saveptr))) {
600 if (!strcmp(characteristic,
"public.accessibility.describes-music-and-sound"))
602 else if (!strcmp(characteristic,
"public.accessibility.describes-video"))
612 int key_len,
char **dest,
int *dest_len)
616 if (!strncmp(
key,
"TYPE=", key_len)) {
618 *dest_len =
sizeof(
info->type);
619 }
else if (!strncmp(
key,
"URI=", key_len)) {
621 *dest_len =
sizeof(
info->uri);
622 }
else if (!strncmp(
key,
"GROUP-ID=", key_len)) {
623 *dest =
info->group_id;
624 *dest_len =
sizeof(
info->group_id);
625 }
else if (!strncmp(
key,
"LANGUAGE=", key_len)) {
626 *dest =
info->language;
627 *dest_len =
sizeof(
info->language);
628 }
else if (!strncmp(
key,
"ASSOC-LANGUAGE=", key_len)) {
629 *dest =
info->assoc_language;
630 *dest_len =
sizeof(
info->assoc_language);
631 }
else if (!strncmp(
key,
"NAME=", key_len)) {
633 *dest_len =
sizeof(
info->name);
634 }
else if (!strncmp(
key,
"DEFAULT=", key_len)) {
635 *dest =
info->defaultr;
636 *dest_len =
sizeof(
info->defaultr);
637 }
else if (!strncmp(
key,
"FORCED=", key_len)) {
638 *dest =
info->forced;
639 *dest_len =
sizeof(
info->forced);
640 }
else if (!strncmp(
key,
"CHARACTERISTICS=", key_len)) {
641 *dest =
info->characteristics;
642 *dest_len =
sizeof(
info->characteristics);
663 *pls =
c->playlists[
c->n_playlists - 1];
669 #if !CONFIG_HTTP_PROTOCOL
673 return uc && !strncmp(uc->
prot->
name,
"http", 4);
680 #if !CONFIG_HTTP_PROTOCOL
686 (*pb)->eof_reached = 0;
700 const char *proto_name =
NULL;
705 if (url[6] ==
'+' || url[6] ==
':')
708 if (url[4] ==
'+' || url[4] ==
':')
720 if (strcmp(
c->allowed_extensions,
"ALL") && !
av_match_ext(url,
c->allowed_extensions)) {
722 "Filename extension of \'%s\' is not a common multimedia extension, blocked for security reasons.\n"
723 "If you wish to override this adjust allowed_extensions, you can set it to \'ALL\' to allow all\n",
734 if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] ==
':')
736 else if (
av_strstart(url,
"crypto",
NULL) && !strncmp(proto_name, url + 7, strlen(proto_name)) && url[7 + strlen(proto_name)] ==
':')
738 else if (
av_strstart(url,
"data",
NULL) && !strncmp(proto_name, url + 5, strlen(proto_name)) && url[5 + strlen(proto_name)] ==
':')
740 else if (strcmp(proto_name,
"file") || !strncmp(url,
"file,", 5))
751 }
else if (
ret < 0) {
754 "keepalive request failed for '%s' with error: '%s' when opening url, retrying with new connection\n",
766 char *new_cookies =
NULL;
778 *is_http_out = is_http;
789 if (!
c->extension_picky)
792 if (strcmp(
c->allowed_segment_extensions,
"ALL"))
797 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);
807 matchF |=
av_match_ext( seg->
url,
"ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts,cmfv,cmfa")
808 + 2*(
ff_match_url_ext(seg->
url,
"ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts,cmfv,cmfa") > 0);
810 }
else if (!strcmp(in_fmt->
name,
"mpegts")) {
811 const char *str =
"ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts"
816 }
else if (!strcmp(in_fmt->
name,
"webvtt")) {
821 if (!(matchA & matchF)) {
833 int ret = 0, is_segment = 0, is_variant = 0;
844 uint8_t *new_url =
NULL;
850 int prev_n_segments = 0;
851 int64_t prev_start_seq_no = -1;
853 if (is_http && !in &&
c->http_persistent &&
c->playlist_pb) {
858 }
else if (
ret < 0) {
861 "keepalive request failed for '%s' with error: '%s' when parsing playlist\n",
871 if (
c->http_persistent)
889 if (strcmp(
line,
"#EXTM3U")) {
909 "Master Playlist tag found in a Media Playlist\n");
921 if (!strcmp(
info.method,
"AES-128"))
923 if (!strcmp(
info.method,
"SAMPLE-AES"))
934 "Master Playlist tag found in a Media Playlist\n");
945 t = strtoll(ptr,
NULL, 10);
956 seq_no = strtoull(ptr,
NULL, 10);
957 if (seq_no > INT64_MAX/2) {
959 "INT64_MAX/2, mask out the highest bit\n");
960 seq_no &= INT64_MAX/2;
967 if (!strcmp(ptr,
"EVENT"))
969 else if (!strcmp(ptr,
"VOD"))
978 if (!cur_init_section) {
982 cur_init_section->
key_type = key_type;
984 memcpy(cur_init_section->
iv, iv,
sizeof(iv));
987 memset(cur_init_section->
iv, 0,
sizeof(cur_init_section->
iv));
999 if (!cur_init_section->
key) {
1009 const char *time_offset_value =
NULL;
1014 if (
av_strstart(ptr,
"TIME-OFFSET=", &time_offset_value)) {
1021 "invalid, it will be ignored");
1025 "invalid, it will be ignored");
1033 if (d < 0 || d > INT64_MAX ||
isnan(d)) {
1040 seg_size = strtoll(ptr,
NULL, 10);
1041 ptr = strchr(ptr,
'@');
1043 seg_offset = strtoll(ptr+1,
NULL, 10);
1044 if (seg_size < 0 || seg_offset > INT64_MAX - seg_size) {
1051 }
else if (
line[0]) {
1070 memcpy(seg->
iv,
iv,
sizeof(
iv));
1073 memset(seg->
iv, 0,
sizeof(seg->
iv));
1120 " set to default value to 1ms.\n", seg->
url);
1128 seg->
size = seg_size;
1129 if (seg_size >= 0) {
1131 seg_offset += seg_size;
1142 if (prev_segments) {
1144 c->first_timestamp_pls == pls) {
1145 int64_t prev_timestamp =
c->first_timestamp;
1148 for (
i = 0;
i < prev_n_segments &&
i <
diff;
i++) {
1149 c->first_timestamp += prev_segments[
i]->
duration;
1152 " reflected in first_timestamp: %"PRId64
" -> %"PRId64
"\n",
1154 prev_timestamp,
c->first_timestamp);
1170 if (!
c->n_variants || !
c->variants[0]->n_playlists ||
1171 !
c->variants[0]->playlists[0]->n_segments)
1174 if (
c->n_variants &&
c->variants[0]->n_playlists &&
1176 !
c->variants[0]->playlists[0]->finished) {
1177 struct playlist *
p =
c->variants[0]->playlists[0];
1179 for (
int i = 0;
i <
p->n_segments;
i++)
1209 return in && cur && next &&
1211 cur->
size >= 0 && next->
size >= 0 &&
1215 !strcmp(next->
url, cur->
url);
1219 uint8_t *buf,
int buf_size)
1239 static const char id3_priv_owner_ts[] =
"com.apple.streaming.transportStreamTimestamp";
1240 static const char id3_priv_owner_audio_setup[] =
"com.apple.streaming.audioDescription";
1244 for (meta = *extra_meta; meta; meta = meta->
next) {
1245 if (!strcmp(meta->
tag,
"PRIV")) {
1251 if ((ts & ~((1ULL << 33) - 1)) == 0)
1258 }
else if (!strcmp(meta->
tag,
"APIC") && apic)
1272 if (!oldentry || strcmp(oldentry->
value,
entry->value) != 0)
1336 int buf_size,
int *
len)
1341 int id3_buf_pos = 0;
1359 }
else if (*
len <= 0) {
1372 int tag_got_bytes =
FFMIN(taglen, *
len);
1373 int remaining = taglen - tag_got_bytes;
1375 if (taglen > maxsize) {
1391 memcpy(pls->
id3_buf + id3_buf_pos, buf, tag_got_bytes);
1392 id3_buf_pos += tag_got_bytes;
1395 *
len -= tag_got_bytes;
1396 memmove(buf, buf + tag_got_bytes, *
len);
1399 if (remaining > 0) {
1403 id3_buf_pos += remaining;
1448 if (
ret !=
sizeof(pls->
key)) {
1478 if (seek_ret >= 0) {
1480 "HLS reusing connection for url '%s', offset %"PRId64
", playlist %d\n",
1491 if (
c->http_persistent)
1494 if (seg->
size >= 0) {
1501 while (n < pls->n_segments) {
1503 if (
ns->size < 0 ||
ns->url_offset != end_offset ||
1506 strcmp(
ns->url, seg->
url))
1508 end_offset =
ns->url_offset +
ns->size;
1531 if (strstr(seg->
url,
"://"))
1575 static const int max_init_section_size = 1024*1024;
1592 "Failed to open an initialization section in playlist %d\n",
1602 sec_size = max_init_section_size;
1605 "Downloading an initialization section of size %"PRId64
"\n",
1608 sec_size =
FFMIN(sec_size, max_init_section_size);
1641 int stream_needed = 0;
1667 for (
i = 0;
i <
s->nb_programs;
i++) {
1670 for (j = 0; j <
program->nb_stream_indexes; j++) {
1671 if (
program->stream_index[j] == first_st) {
1686 int reload_count = 0;
1712 if (reload_count >
c->max_reload)
1729 "skipping %"PRId64
" segments ahead, expired from playlists\n",
1765 int just_opened = 0;
1766 int segment_retries = 0;
1805 if (segment_retries >=
c->seg_max_retry) {
1810 segment_retries = 0;
1816 segment_retries = 0;
1822 if (
c->http_multiple == -1) {
1823 uint8_t *http_version_opt =
NULL;
1826 c->http_multiple = (!strncmp((
const char *)http_version_opt,
"1.1", 3) || !strncmp((
const char *)http_version_opt,
"2.0", 3));
1920 "A HLS playlist item '%s' referred to an external file '%s'. "
1921 "Opening this file was forbidden for security reasons\n",
1998 for (
i = 0;
i <
c->n_renditions;
i++) {
2055 0 :
c->first_timestamp;
2057 if (timestamp <
pos) {
2061 *seg_start_ts =
pos;
2070 *seg_start_ts =
pos;
2092 if (!pls->
finished && !
c->first_packet &&
2106 if (!
c->first_packet &&
2113 return c->cur_seq_no;
2117 if (
c->live_start_index < 0)
2119 c->live_start_index, 0);
2127 int64_t playlist_duration = 0;
2140 start_timestamp = cur_timestamp + playlist_duration;
2146 start_timestamp = cur_timestamp;
2149 start_timestamp = cur_timestamp + playlist_duration +
2152 start_timestamp = cur_timestamp;
2169 for (
i = 0;
i <
c->n_variants;
i++) {
2245 "Playlist has multiple timed ID3 streams; "
2246 "only stream %d will be used for metadata propagation\n",
2257 int flag_needed = 0;
2260 for (
i = 0;
i <
c->n_playlists;
i++) {
2283 if (
c->crypto_ctx.aes_ctx)
2296 int64_t highest_cur_seq_no = 0;
2299 c->interrupt_callback = &
s->interrupt_callback;
2301 c->first_packet = 1;
2303 c->first_timestamp_pls =
NULL;
2304 c->first_timestamp_locked = 0;
2314 if (
c->http_persistent) {
2316 c->http_persistent = 0;
2320 if (
c->http_multiple == -1) {
2322 c->http_multiple = 0;
2334 if (
c->n_variants == 0) {
2340 if (
c->n_playlists > 1 ||
c->playlists[0]->n_segments == 0) {
2341 for (
i = 0;
i <
c->n_playlists;
i++) {
2347 if (
c->n_playlists > 1)
2354 for (
i = 0;
i <
c->n_variants;
i++) {
2355 if (
c->variants[
i]->playlists[0]->n_segments == 0) {
2357 c->variants[
i]->playlists[0]->broken = 1;
2363 if (
c->variants[0]->playlists[0]->finished ||
2366 for (
i = 0;
i <
c->variants[0]->playlists[0]->n_segments;
i++)
2367 duration +=
c->variants[0]->playlists[0]->segments[
i]->duration;
2372 for (
i = 0;
i <
c->n_variants;
i++) {
2384 for (
i = 0;
i <
c->n_variants;
i++) {
2395 for (
i = 0;
i <
c->n_playlists;
i++) {
2405 av_dict_set(&
c->seg_format_opts,
"prefer_hls_mpegts_pts",
"1", 0);
2408 for (
i = 0;
i <
c->n_playlists;
i++) {
2433 highest_cur_seq_no < pls->start_seq_no + pls->
n_segments) {
2500 pls->
ctx->
probesize =
s->probesize > 0 ?
s->probesize : 1024 * 4;
2526 if (strstr(in_fmt->
name,
"mov")) {
2530 }
else if (!
c->crypto_ctx.aes_ctx) {
2532 if (!
c->crypto_ctx.aes_ctx) {
2620 for (
i = 0;
i <
c->n_playlists;
i++) {
2628 if (cur_needed && !pls->
needed) {
2726 int ret,
i, minplaylist = -1;
2729 c->first_packet = 0;
2731 for (
i = 0;
i <
c->n_playlists;
i++) {
2758 (!
c->first_timestamp_locked &&
2759 c->first_timestamp_pls == pls &&
2772 c->first_timestamp = ts;
2773 c->first_timestamp_pls = pls;
2775 }
else if (
c->first_timestamp_pls == pls) {
2782 if (
delta > 0 && delta <= pls->target_duration) {
2783 c->first_timestamp = ts;
2784 for (
int k = 0; k <
c->n_playlists; k++)
2786 c->playlists[k]->ts_offset +=
delta;
2795 for (
unsigned k = 0; k <
s->nb_streams; k++)
2796 s->streams[k]->start_time =
2798 s->streams[k]->time_base);
2800 "First timestamp %"PRId64
" from playlist %d\n",
2801 c->first_timestamp, pls->
index);
2808 memcpy(
c->crypto_ctx.iv, seg->
iv,
sizeof(seg->
iv));
2809 memcpy(
c->crypto_ctx.key, pls->
key,
sizeof(pls->
key));
2839 struct playlist *minpls = minplaylist < 0 ?
2840 NULL :
c->playlists[minplaylist];
2841 if (minplaylist < 0) {
2855 if (minplaylist >= 0) {
2856 struct playlist *pls =
c->playlists[minplaylist];
2884 av_log(
s,
AV_LOG_ERROR,
"stream index inconsistency: index %d, %d main streams, %d subdemuxer streams\n",
2939 int stream_subdemuxer_index;
2942 int snapped_to_segment = 0;
2948 0 :
c->first_timestamp;
2951 s->streams[stream_index]->time_base,
2955 for (
i = 0;
i <
c->n_playlists;
i++) {
2960 stream_subdemuxer_index = j;
2986 snapped_to_segment = 1;
2990 " of playlist %d (start %"PRId64
")\n",
2994 c->first_timestamp_locked = 1;
3002 for (
i = 0;
i < (int)
s->nb_streams;
i++)
3005 for (
i = 0;
i <
c->n_playlists;
i++) {
3016 pb->eof_reached = 0;
3018 pb->buf_end =
pb->buf_ptr =
pb->buffer;
3044 if (pls == seek_pls && snapped_to_segment) {
3053 if (pls != seek_pls) {
3075 if (strncmp(
p->buf,
"#EXTM3U", 7))
3078 if (strstr(
p->buf,
"#EXT-X-STREAM-INF:") ||
3079 strstr(
p->buf,
"#EXT-X-TARGETDURATION:") ||
3080 strstr(
p->buf,
"#EXT-X-MEDIA-SEQUENCE:")) {
3082 int mime_ok =
p->mime_type && !(
3087 int mime_x =
p->mime_type && !(
3096 av_log(
NULL,
AV_LOG_ERROR,
"Not detecting m3u8/hls with non standard extension and non standard mime type\n");
3107 #define OFFSET(x) offsetof(HLSContext, x)
3108 #define FLAGS AV_OPT_FLAG_DECODING_PARAM
3110 {
"live_start_index",
"segment index to start live streams at (negative values are from the end)",
3112 {
"prefer_x_start",
"prefer to use #EXT-X-START if it's in playlist instead of live_start_index",
3114 {
"allowed_extensions",
"List of file extensions that hls is allowed to access",
3116 {.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"
3121 INT_MIN, INT_MAX,
FLAGS},
3122 {
"allowed_segment_extensions",
"List of file extensions that hls is allowed to access",
3124 {.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"
3130 INT_MIN, INT_MAX,
FLAGS},
3131 {
"extension_picky",
"Be picky with all extensions matching",
3133 {
"max_reload",
"Maximum number of times a insufficient list is attempted to be reloaded",
3135 {
"m3u8_hold_counters",
"The maximum number of times to load m3u8 when it refreshes without new segments",
3137 {
"http_persistent",
"Use persistent HTTP connections",
3139 {
"http_multiple",
"Use multiple HTTP connections for fetching segments",
3141 {
"http_seekable",
"Use HTTP partial requests, 0 = disable, 1 = enable, -1 = auto",
3143 {
"seg_format_options",
"Set options for segment demuxer",
3145 {
"seg_max_retry",
"Maximum number of times to reload a segment on error.",
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
int ff_get_chomp_line(AVIOContext *s, char *buf, int maxlen)
Same as ff_get_line but strip the white-space characters in the text tail.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define MAX_CHARACTERISTICS_LEN
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C program
void ffio_init_context(FFIOContext *s, unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, const uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
int ffio_copy_url_options(AVIOContext *pb, AVDictionary **avio_opts)
Read url related dictionary options from the AVIOContext and write to the given dictionary.
static void free_segment_dynarray(struct segment **segments, int n_segments)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
enum AVMediaType codec_type
General type of the encoded data.
double strtod(const char *, char **)
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
#define AVERROR_EOF
End of file.
uint8_t * data
The data buffer.
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
char subtitles[MAX_FIELD_LEN]
int64_t id3_mpegts_timestamp
static struct segment * new_init_section(struct playlist *pls, struct init_section_info *info, const char *url_base)
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
static void handle_init_section_args(void *context, const char *key, int key_len, char **dest, int *dest_len)
char assoc_language[MAX_FIELD_LEN]
static av_cold void cleanup(FlashSV2Context *s)
AVStream ** streams
A list of all streams in the file.
char subtitles_group[MAX_FIELD_LEN]
static int compare_ts_with_wrapdetect(int64_t ts_a, struct playlist *pls_a, int64_t ts_b, struct playlist *pls_b)
static void handle_rendition_args(void *vinfo, const char *key, int key_len, char **dest, int *dest_len)
struct segment ** segments
static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **opts)
#define AV_LOG_VERBOSE
Detailed information.
static int read_subtitle_packet(struct playlist *v, AVPacket *pkt)
uint8_t setup_data_length
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
int64_t probesize
Maximum number of bytes read from input in order to determine stream properties.
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
void ff_read_frame_flush(AVFormatContext *s)
Flush the frame reader.
int64_t avio_size(AVIOContext *s)
Get the filesize.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
char key_url[MAX_URL_SIZE]
int64_t start_time_offset
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Callback for checking whether to abort blocking functions.
int avformat_queue_attached_pictures(AVFormatContext *s)
static int hls_close(AVFormatContext *s)
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
static int segment_reusable(AVIOContext *in, const struct segment *cur, const struct segment *next)
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
char audio_group[MAX_FIELD_LEN]
static int recheck_discard_flags(AVFormatContext *s, int first)
static const AVClass hls_class
static struct variant * new_variant(HLSContext *c, struct variant_info *info, const char *url, const char *base)
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
static int is_native_http(AVIOContext *pb)
static av_cold int read_close(AVFormatContext *ctx)
int64_t pos
position in the file of the current buffer
void ff_hls_senc_read_audio_setup_info(HLSAudioSetupInfo *info, const uint8_t *buf, size_t size)
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
AVProgram * av_new_program(AVFormatContext *ac, int id)
struct playlist * first_timestamp_pls
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
#define HLS_MAX_ID3_TAGS_DATA_LEN
int event_flags
Flags indicating events happening on the file, a combination of AVFMT_EVENT_FLAG_*.
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
char * allowed_segment_extensions
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, AVDictionary **opts, AVDictionary *opts2, int *is_http_out)
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
AVDictionary * metadata
Metadata that applies to the whole file.
int ctx_flags
Flags signalling stream properties.
static void free_rendition_list(HLSContext *c)
int avformat_open_input(AVFormatContext **ps, const char *url, const AVInputFormat *fmt, AVDictionary **options)
Open an input stream and read the header.
static const AVOption hls_options[]
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
#define flags(name, subs,...)
static void fill_timing_for_id3_timestamped_stream(struct playlist *pls)
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
static int playlist_needed(struct playlist *pls)
static int read_data_continuous(void *opaque, uint8_t *buf, int buf_size)
int flags
Flags modifying the (de)muxer behaviour.
const struct AVInputFormat * iformat
The input container format.
unsigned int init_sec_buf_read_offset
char video[MAX_FIELD_LEN]
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
int av_match_ext(const char *filename, const char *extensions)
Return a positive value if the given filename has one of the given extensions, 0 otherwise.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
char audio[MAX_FIELD_LEN]
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
struct segment ** init_sections
static void add_renditions_to_variant(HLSContext *c, struct variant *var, enum AVMediaType type, const char *group_id)
char * allowed_extensions
HLSCryptoContext crypto_ctx
int av_usleep(unsigned usec)
Sleep for a period of time.
unsigned int id3_buf_size
AVDictionary * seg_format_opts
static int hls_read_header(AVFormatContext *s)
int64_t max_analyze_duration
Maximum duration (in AV_TIME_BASE units) of the data read from input in avformat_find_stream_info().
static void handle_id3(AVIOContext *pb, struct playlist *pls)
static void free_variant_list(HLSContext *c)
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
char group_id[MAX_FIELD_LEN]
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option keep it simple and lowercase description are in without and describe what they for example set the foo of the bar offset is the offset of the field in your context
@ AVDISCARD_ALL
discard all
const FFInputFormat ff_hls_demuxer
AVIOInterruptCB * interrupt_callback
static AVDictionary * opts
AVCodecParameters * codecpar
Codec parameters associated with this stream.
#define LIBAVUTIL_VERSION_INT
static struct segment * current_segment(struct playlist *pls)
Describe the class of an AVClass context structure.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
struct playlist ** playlists
static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url)
static void fill_buf(uint8_t *data, int w, int h, int linesize, uint8_t v)
struct rendition ** renditions
AVIOContext * playlist_pb
int timed_id3_stream_index
Rational number (pair of numerator and denominator).
static void free_init_section_list(struct playlist *pls)
static int update_streams_from_subdemuxer(AVFormatContext *s, struct playlist *pls)
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
const char * av_default_item_name(void *ptr)
Return the context name.
int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
Create a stream for each APIC (attached picture) extracted from the ID3v2 header.
AVIOContext * pb
I/O context.
int ff_http_do_new_request2(URLContext *h, const char *uri, AVDictionary **opts)
Send a new HTTP request, reusing the old connection.
This structure contains the data a format has to probe a file.
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
static void handle_variant_args(void *context, const char *key, int key_len, char **dest, int *dest_len)
URLContext * ffio_geturlcontext(AVIOContext *s)
Return the URLContext associated with the AVIOContext.
ID3v2ExtraMeta * id3_deferred_extra
struct playlist ** playlists
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
#define INITIAL_BUFFER_SIZE
#define ID3v2_HEADER_SIZE
static int id3_has_changed_values(struct playlist *pls, AVDictionary *metadata, ID3v2ExtraMetaAPIC *apic)
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
AVCodecID
Identify the syntax and semantics of the bitstream.
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
@ AV_ROUND_DOWN
Round toward -infinity.
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
unsigned int init_sec_buf_size
static int read_data_subtitle_segment(void *opaque, uint8_t *buf, int buf_size)
struct variant ** variants
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information.
struct segment * cur_init_section
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
unsigned char * buf_end
End of the data, may be less than buffer+buffer_size if the read function returned less data than req...
static struct rendition * new_rendition(HLSContext *c, struct rendition_info *info, const char *url_base)
#define i(width, name, range_min, range_max)
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
static int metadata_has_changed(const AVDictionary *current, const AVDictionary *update)
Check whether any entry in update differs from the corresponding entry in current.
static int test_segment(AVFormatContext *s, const AVInputFormat *in_fmt, struct playlist *pls, struct segment *seg)
#define ID3v2_DEFAULT_MAGIC
Default magic bytes for ID3v2 header: "ID3".
#define AV_NOPTS_VALUE
Undefined timestamp value.
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
int event_flags
Flags indicating events happening on the stream, a combination of AVSTREAM_EVENT_FLAG_*.
char characteristics[MAX_CHARACTERISTICS_LEN]
@ AVMEDIA_TYPE_UNKNOWN
Usually treated as AVMEDIA_TYPE_DATA.
static AVRational get_timebase(struct playlist *pls)
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
static int update_init_section(struct playlist *pls, struct segment *seg)
int flags
A combination of AV_PKT_FLAG values.
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
static int read_header(FFV1Context *f, RangeCoder *c)
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
int av_probe_input_buffer(AVIOContext *pb, const AVInputFormat **fmt, const char *url, void *logctx, unsigned int offset, unsigned int max_probe_size)
Like av_probe_input_buffer2() but returns 0 on success.
struct playlist * playlist
size_t size
Size of data in bytes.
#define AV_LOG_INFO
Standard information.
static void free_segment_list(struct playlist *pls)
int ff_hls_senc_decrypt_frame(enum AVCodecID codec_id, HLSCryptoContext *crypto_ctx, AVPacket *pkt)
static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pls, enum AVMediaType type)
static struct segment * next_segment(struct playlist *pls)
static struct @602 current
static void update_noheader_flag(AVFormatContext *s)
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AV_TIME_BASE
Internal time base represented as integer.
const struct URLProtocol * prot
AVDictionary * timed_id3_metadata
void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata, const char *magic, ID3v2ExtraMeta **extra_meta)
Read an ID3v2 tag into specified dictionary and retrieve supported extra metadata.
static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
char video_group[MAX_FIELD_LEN]
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
static int init_subtitle_context(struct playlist *pls)
static int64_t default_reload_interval(struct playlist *pls)
int64_t first_read_seq_no
New fields can be added to the end with minor version bumps.
static int reload_playlist(struct playlist *v, HLSContext *c)
static int open_url_keepalive(AVFormatContext *s, AVIOContext **pb, const char *url, AVDictionary **options)
static void free_playlist_list(HLSContext *c)
int ff_hls_senc_parse_audio_setup_info(AVStream *st, HLSAudioSetupInfo *info)
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
char language[MAX_FIELD_LEN]
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
int ff_id3v2_tag_len(const uint8_t *buf)
Get the length of an ID3v2 tag.
int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod)
Compare the remainders of two integer operands divided by a common divisor.
int id
Format-specific stream ID.
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
#define FFSWAP(type, a, b)
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
HLSAudioSetupInfo audio_setup_info
#define AV_INPUT_BUFFER_PADDING_SIZE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, AVIOContext **in)
static int hls_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
static struct playlist * new_playlist(HLSContext *c, const char *url, const char *base)
static int set_stream_info_from_input_stream(AVStream *st, struct playlist *pls, AVStream *ist)
int index
stream index in AVFormatContext
static void handle_key_args(void *context, const char *key, int key_len, char **dest, int *dest_len)
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
AVDictionary * id3_initial
static int parse_playlist(HLSContext *c, const char *url, struct playlist *pls, AVIOContext *in)
@ AV_OPT_TYPE_INT
Underlying C type is int.
int av_match_name(const char *name, const char *names)
Match instances of a name in a comma-separated list of names.
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
int first_timestamp_locked
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
static av_always_inline void update(AVFilterContext *ctx, AVFrame *insamples, int is_silence, int current_sample, int64_t nb_samples_notify, AVRational time_base)
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
A callback for opening new IO streams.
int eof_reached
true if was unable to read due to error or eof
const AVInputFormat * av_find_input_format(const char *short_name)
Find AVInputFormat based on the short name of the input format.
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
static int read_key(HLSContext *c, struct playlist *pls, struct segment *seg)
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
#define AVIO_FLAG_READ
read-only
static void add_stream_to_programs(AVFormatContext *s, struct playlist *pls, AVStream *stream)
static int hls_probe(const AVProbeData *p)
static int read_probe(const AVProbeData *p)
unsigned int init_sec_data_len
static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
unsigned char * buffer
Start of the buffer.
static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls, int64_t timestamp, int64_t *seq_no, int64_t *seg_start_ts)
int ff_make_absolute_url(char *buf, int size, const char *base, const char *rel)
Convert a relative url into an absolute url, given a base url.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
This structure stores compressed data.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
Free memory allocated parsing special (non-text) metadata.
struct segment * init_section
const char * avio_find_protocol_name(const char *url)
Return the name of the protocol that will handle the passed URL.
int need_context_update
Whether the internal avctx needs to be updated from codecpar (after a late change to codecpar)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
int ff_id3v2_parse_priv(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
Add metadata for all PRIV tags in the ID3v2 header.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define ns(max_value, name, subs,...)
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
int pts_wrap_bits
Number of bits in timestamps.
static void parse_id3(AVFormatContext *s, AVIOContext *pb, AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta)
unsigned char * buf_ptr
Current position in the buffer.
static int read_from_url(struct playlist *pls, struct segment *seg, uint8_t *buf, int buf_size)
int ff_id3v2_parse_priv_dict(AVDictionary **metadata, ID3v2ExtraMeta *extra_meta)
Parse PRIV tags into a dictionary.
#define AVERROR_PROTOCOL_NOT_FOUND
Protocol not found.
void * priv_data
Format private data.
int64_t pts_wrap_reference
Internal data to check for wrapping of the time stamp.
static void intercept_id3(struct playlist *pls, uint8_t *buf, int buf_size, int *len)
char language[MAX_FIELD_LEN]
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding rnd)
Rescale a 64-bit integer by 2 rational numbers with specified rounding.
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
struct rendition ** renditions
char group_id[MAX_FIELD_LEN]
int ff_id3v2_match(const uint8_t *buf, const char *magic)
Detect ID3v2 Header.
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.