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