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  int64_t load_start = av_gettime_relative();
853 
854  if (is_http && !in && c->http_persistent && c->playlist_pb) {
855  in = c->playlist_pb;
856  ret = open_url_keepalive(c->ctx, &c->playlist_pb, url, NULL);
857  if (ret == AVERROR_EXIT) {
858  return ret;
859  } else if (ret < 0) {
860  if (ret != AVERROR_EOF)
861  av_log(c->ctx, AV_LOG_WARNING,
862  "keepalive request failed for '%s' with error: '%s' when parsing playlist\n",
863  url, av_err2str(ret));
864  in = NULL;
865  }
866  }
867 
868  if (!in) {
870  av_dict_copy(&opts, c->avio_opts, 0);
871 
872  if (c->http_persistent)
873  av_dict_set(&opts, "multiple_requests", "1", 0);
874 
875  ret = open_url(c->ctx, &in, url, &opts, NULL, NULL);
876  av_dict_free(&opts);
877  if (ret < 0)
878  return ret;
879 
880  if (is_http && c->http_persistent && is_native_http(in))
881  c->playlist_pb = in;
882  else
883  close_in = 1;
884  }
885 
886  if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
887  url = new_url;
888 
889  ff_get_chomp_line(in, line, sizeof(line));
890  if (strcmp(line, "#EXTM3U")) {
892  goto fail;
893  }
894 
895  if (pls) {
896  prev_start_seq_no = pls->start_seq_no;
897  prev_segments = pls->segments;
898  prev_n_segments = pls->n_segments;
899  pls->segments = NULL;
900  pls->n_segments = 0;
901 
902  pls->finished = 0;
903  pls->type = PLS_TYPE_UNSPECIFIED;
904  }
905  while (!avio_feof(in)) {
906  ff_get_chomp_line(in, line, sizeof(line));
907  if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
908  if (pls) {
909  av_log(c->ctx, AV_LOG_ERROR,
910  "Master Playlist tag found in a Media Playlist\n");
912  goto fail;
913  }
914  is_variant = 1;
915  memset(&variant_info, 0, sizeof(variant_info));
917  } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
918  struct key_info info = {{0}};
920  key_type = KEY_NONE;
921  has_iv = 0;
922  if (!strcmp(info.method, "AES-128"))
923  key_type = KEY_AES_128;
924  if (!strcmp(info.method, "SAMPLE-AES"))
925  key_type = KEY_SAMPLE_AES;
926  if (!av_strncasecmp(info.iv, "0x", 2)) {
927  ff_hex_to_data(iv, info.iv + 2);
928  has_iv = 1;
929  }
930  av_strlcpy(key, info.uri, sizeof(key));
931  } else if (av_strstart(line, "#EXT-X-MEDIA:", &ptr)) {
932  struct rendition_info info = {{0}};
933  if (pls) {
934  av_log(c->ctx, AV_LOG_ERROR,
935  "Master Playlist tag found in a Media Playlist\n");
937  goto fail;
938  }
940  new_rendition(c, &info, url);
941  } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
942  int64_t t;
943  ret = ensure_playlist(c, &pls, url);
944  if (ret < 0)
945  goto fail;
946  t = strtoll(ptr, NULL, 10);
947  if (t < 0 || t >= INT64_MAX / AV_TIME_BASE) {
949  goto fail;
950  }
951  pls->target_duration = t * AV_TIME_BASE;
952  } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
953  uint64_t seq_no;
954  ret = ensure_playlist(c, &pls, url);
955  if (ret < 0)
956  goto fail;
957  seq_no = strtoull(ptr, NULL, 10);
958  if (seq_no > INT64_MAX/2) {
959  av_log(c->ctx, AV_LOG_DEBUG, "MEDIA-SEQUENCE higher than "
960  "INT64_MAX/2, mask out the highest bit\n");
961  seq_no &= INT64_MAX/2;
962  }
963  pls->start_seq_no = seq_no;
964  } else if (av_strstart(line, "#EXT-X-PLAYLIST-TYPE:", &ptr)) {
965  ret = ensure_playlist(c, &pls, url);
966  if (ret < 0)
967  goto fail;
968  if (!strcmp(ptr, "EVENT"))
969  pls->type = PLS_TYPE_EVENT;
970  else if (!strcmp(ptr, "VOD"))
971  pls->type = PLS_TYPE_VOD;
972  } else if (av_strstart(line, "#EXT-X-MAP:", &ptr)) {
973  struct init_section_info info = {{0}};
974  ret = ensure_playlist(c, &pls, url);
975  if (ret < 0)
976  goto fail;
978  cur_init_section = new_init_section(pls, &info, url);
979  if (!cur_init_section) {
980  ret = AVERROR(ENOMEM);
981  goto fail;
982  }
983  cur_init_section->key_type = key_type;
984  if (has_iv) {
985  memcpy(cur_init_section->iv, iv, sizeof(iv));
986  } else {
987  int64_t seq = pls->start_seq_no + pls->n_segments;
988  memset(cur_init_section->iv, 0, sizeof(cur_init_section->iv));
989  AV_WB64(cur_init_section->iv + 8, seq);
990  }
991 
992  if (key_type != KEY_NONE) {
993  ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
994  if (!tmp_str[0]) {
995  av_free(cur_init_section);
997  goto fail;
998  }
999  cur_init_section->key = av_strdup(tmp_str);
1000  if (!cur_init_section->key) {
1001  av_free(cur_init_section);
1002  ret = AVERROR(ENOMEM);
1003  goto fail;
1004  }
1005  } else {
1006  cur_init_section->key = NULL;
1007  }
1008 
1009  } else if (av_strstart(line, "#EXT-X-START:", &ptr)) {
1010  const char *time_offset_value = NULL;
1011  ret = ensure_playlist(c, &pls, url);
1012  if (ret < 0) {
1013  goto fail;
1014  }
1015  if (av_strstart(ptr, "TIME-OFFSET=", &time_offset_value)) {
1016  double offset = strtod(time_offset_value, NULL) * AV_TIME_BASE;
1017  if (offset >= -0x1p63 && offset < 0x1p63) {
1018  pls->start_time_offset = offset;
1019  pls->time_offset_flag = 1;
1020  } else {
1021  av_log(c->ctx, AV_LOG_WARNING, "TIME-OFFSET value is"
1022  "invalid, it will be ignored");
1023  }
1024  } else {
1025  av_log(c->ctx, AV_LOG_WARNING, "#EXT-X-START value is"
1026  "invalid, it will be ignored");
1027  continue;
1028  }
1029  } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
1030  if (pls)
1031  pls->finished = 1;
1032  } else if (av_strstart(line, "#EXTINF:", &ptr)) {
1033  double d = atof(ptr) * AV_TIME_BASE;
1034  if (d < 0 || d > INT64_MAX || isnan(d)) {
1035  av_log(c->ctx, AV_LOG_WARNING, "EXTINF %f unsupported\n", d / AV_TIME_BASE);
1036  d = 0;
1037  }
1038  duration = d;
1039  is_segment = 1;
1040  } else if (av_strstart(line, "#EXT-X-BYTERANGE:", &ptr)) {
1041  seg_size = strtoll(ptr, NULL, 10);
1042  ptr = strchr(ptr, '@');
1043  if (ptr)
1044  seg_offset = strtoll(ptr+1, NULL, 10);
1045  if (seg_size < 0 || seg_offset > INT64_MAX - seg_size) {
1047  goto fail;
1048  }
1049  } else if (av_strstart(line, "#", NULL)) {
1050  av_log(c->ctx, AV_LOG_VERBOSE, "Skip ('%s')\n", line);
1051  continue;
1052  } else if (line[0]) {
1053  if (is_variant) {
1054  if (!new_variant(c, &variant_info, line, url)) {
1055  ret = AVERROR(ENOMEM);
1056  goto fail;
1057  }
1058  is_variant = 0;
1059  }
1060  if (is_segment) {
1061  struct segment *seg;
1062  ret = ensure_playlist(c, &pls, url);
1063  if (ret < 0)
1064  goto fail;
1065  seg = av_malloc(sizeof(struct segment));
1066  if (!seg) {
1067  ret = AVERROR(ENOMEM);
1068  goto fail;
1069  }
1070  if (has_iv) {
1071  memcpy(seg->iv, iv, sizeof(iv));
1072  } else {
1073  uint64_t seq = pls->start_seq_no + (uint64_t)pls->n_segments;
1074  memset(seg->iv, 0, sizeof(seg->iv));
1075  AV_WB64(seg->iv + 8, seq);
1076  }
1077 
1078  if (key_type != KEY_NONE) {
1079  ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
1080  if (!tmp_str[0]) {
1082  av_free(seg);
1083  goto fail;
1084  }
1085  seg->key = av_strdup(tmp_str);
1086  if (!seg->key) {
1087  av_free(seg);
1088  ret = AVERROR(ENOMEM);
1089  goto fail;
1090  }
1091  } else {
1092  seg->key = NULL;
1093  }
1094 
1095  ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, line);
1096  if (!tmp_str[0]) {
1098  if (seg->key)
1099  av_free(seg->key);
1100  av_free(seg);
1101  goto fail;
1102  }
1103  seg->url = av_strdup(tmp_str);
1104  if (!seg->url) {
1105  av_free(seg->key);
1106  av_free(seg);
1107  ret = AVERROR(ENOMEM);
1108  goto fail;
1109  }
1110 
1111  ret = test_segment(c->ctx, pls->ctx ? pls->ctx->iformat : NULL, pls, seg);
1112  if (ret < 0) {
1113  av_free(seg->url);
1114  av_free(seg->key);
1115  av_free(seg);
1116  goto fail;
1117  }
1118 
1119  if (duration < 0.001 * AV_TIME_BASE) {
1120  av_log(c->ctx, AV_LOG_WARNING, "Cannot get correct #EXTINF value of segment %s,"
1121  " set to default value to 1ms.\n", seg->url);
1122  duration = 0.001 * AV_TIME_BASE;
1123  }
1124  seg->duration = duration;
1125  seg->key_type = key_type;
1126  dynarray_add(&pls->segments, &pls->n_segments, seg);
1127  is_segment = 0;
1128 
1129  seg->size = seg_size;
1130  if (seg_size >= 0) {
1131  seg->url_offset = seg_offset;
1132  seg_offset += seg_size;
1133  seg_size = -1;
1134  } else {
1135  seg->url_offset = 0;
1136  seg_offset = 0;
1137  }
1138 
1139  seg->init_section = cur_init_section;
1140  }
1141  }
1142  }
1143  if (prev_segments) {
1144  if (pls->start_seq_no > prev_start_seq_no && c->first_timestamp != AV_NOPTS_VALUE &&
1145  c->first_timestamp_pls == pls) {
1146  int64_t prev_timestamp = c->first_timestamp;
1147  int i;
1148  int64_t diff = pls->start_seq_no - prev_start_seq_no;
1149  for (i = 0; i < prev_n_segments && i < diff; i++) {
1150  c->first_timestamp += prev_segments[i]->duration;
1151  }
1152  av_log(c->ctx, AV_LOG_DEBUG, "Media sequence change (%"PRId64" -> %"PRId64")"
1153  " reflected in first_timestamp: %"PRId64" -> %"PRId64"\n",
1154  prev_start_seq_no, pls->start_seq_no,
1155  prev_timestamp, c->first_timestamp);
1156  } else if (pls->start_seq_no < prev_start_seq_no) {
1157  av_log(c->ctx, AV_LOG_WARNING, "Media sequence changed unexpectedly: %"PRId64" -> %"PRId64"\n",
1158  prev_start_seq_no, pls->start_seq_no);
1159  }
1160  free_segment_dynarray(prev_segments, prev_n_segments);
1161  av_freep(&prev_segments);
1162  }
1163 
1164 fail:
1165  if (pls)
1166  pls->last_load_time = load_start;
1167  av_free(new_url);
1168  if (close_in)
1169  ff_format_io_close(c->ctx, &in);
1170  c->ctx->ctx_flags = c->ctx->ctx_flags & ~(unsigned)AVFMTCTX_UNSEEKABLE;
1171  if (!c->n_variants || !c->variants[0]->n_playlists ||
1172  !c->variants[0]->playlists[0]->n_segments)
1173  c->ctx->ctx_flags |= AVFMTCTX_UNSEEKABLE;
1174 
1175  if (c->n_variants && c->variants[0]->n_playlists &&
1176  c->variants[0]->playlists[0]->type == PLS_TYPE_EVENT &&
1177  !c->variants[0]->playlists[0]->finished) {
1178  struct playlist *p = c->variants[0]->playlists[0];
1179  int64_t duration = 0;
1180  for (int i = 0; i < p->n_segments; i++)
1181  duration += p->segments[i]->duration;
1182  c->ctx->duration = duration;
1183  }
1184 
1185  return ret;
1186 }
1187 
1188 static struct segment *current_segment(struct playlist *pls)
1189 {
1190  int64_t n = pls->cur_seq_no - pls->start_seq_no;
1191  if (n >= pls->n_segments)
1192  return NULL;
1193  return pls->segments[n];
1194 }
1195 
1196 static struct segment *next_segment(struct playlist *pls)
1197 {
1198  int64_t n = pls->cur_seq_no - pls->start_seq_no + 1;
1199  if (n >= pls->n_segments)
1200  return NULL;
1201  return pls->segments[n];
1202 }
1203 
1204 /* True if 'next' can be reached by seeking the open 'in' instead of reopening.
1205  * An unencrypted, contiguous byte range directly following 'cur' in the same
1206  * seekable resource (i.e. consecutive EXT-X-BYTERANGE segments). */
1207 static int segment_reusable(AVIOContext *in, const struct segment *cur,
1208  const struct segment *next)
1209 {
1210  return in && cur && next &&
1211  (in->seekable & AVIO_SEEKABLE_NORMAL) &&
1212  cur->size >= 0 && next->size >= 0 &&
1213  next->url_offset == cur->url_offset + cur->size &&
1214  cur->key_type == KEY_NONE && next->key_type == KEY_NONE &&
1215  next->init_section == cur->init_section &&
1216  !strcmp(next->url, cur->url);
1217 }
1218 
1219 static int read_from_url(struct playlist *pls, struct segment *seg,
1220  uint8_t *buf, int buf_size)
1221 {
1222  int ret;
1223 
1224  /* limit read if the segment was only a part of a file */
1225  if (seg->size >= 0)
1226  buf_size = FFMIN(buf_size, seg->size - pls->cur_seg_offset);
1227 
1228  ret = avio_read(pls->input, buf, buf_size);
1229  if (ret > 0)
1230  pls->cur_seg_offset += ret;
1231 
1232  return ret;
1233 }
1234 
1235 /* Parse the raw ID3 data and pass contents to caller */
1237  AVDictionary **metadata, int64_t *dts, HLSAudioSetupInfo *audio_setup_info,
1238  ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta)
1239 {
1240  static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp";
1241  static const char id3_priv_owner_audio_setup[] = "com.apple.streaming.audioDescription";
1242  ID3v2ExtraMeta *meta;
1243 
1245  for (meta = *extra_meta; meta; meta = meta->next) {
1246  if (!strcmp(meta->tag, "PRIV")) {
1247  ID3v2ExtraMetaPRIV *priv = &meta->data.priv;
1248  if (priv->datasize == 8 && !av_strncasecmp(priv->owner, id3_priv_owner_ts, 44)) {
1249  /* 33-bit MPEG timestamp */
1250  int64_t ts = AV_RB64(priv->data);
1251  av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts);
1252  if ((ts & ~((1ULL << 33) - 1)) == 0)
1253  *dts = ts;
1254  else
1255  av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts);
1256  } else if (priv->datasize >= 8 && !av_strncasecmp(priv->owner, id3_priv_owner_audio_setup, 36)) {
1257  ff_hls_senc_read_audio_setup_info(audio_setup_info, priv->data, priv->datasize);
1258  }
1259  } else if (!strcmp(meta->tag, "APIC") && apic)
1260  *apic = &meta->data.apic;
1261  }
1262 }
1263 
1264 /* Check if the ID3 metadata contents have changed */
1266  ID3v2ExtraMetaAPIC *apic)
1267 {
1268  const AVDictionaryEntry *entry = NULL;
1269  const AVDictionaryEntry *oldentry;
1270  /* check that no keys have changed values */
1271  while ((entry = av_dict_iterate(metadata, entry))) {
1272  oldentry = av_dict_get(pls->id3_initial, entry->key, NULL, AV_DICT_MATCH_CASE);
1273  if (!oldentry || strcmp(oldentry->value, entry->value) != 0)
1274  return 1;
1275  }
1276 
1277  /* check if apic appeared */
1278  if (apic && (pls->ctx->nb_streams != 2 || !pls->ctx->streams[1]->attached_pic.data))
1279  return 1;
1280 
1281  if (apic) {
1282  int size = pls->ctx->streams[1]->attached_pic.size;
1283  if (size != apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE)
1284  return 1;
1285 
1286  if (memcmp(apic->buf->data, pls->ctx->streams[1]->attached_pic.data, size) != 0)
1287  return 1;
1288  }
1289 
1290  return 0;
1291 }
1292 
1293 /* Parse ID3 data and handle the found data */
1294 static void handle_id3(AVIOContext *pb, struct playlist *pls)
1295 {
1297  ID3v2ExtraMetaAPIC *apic = NULL;
1298  ID3v2ExtraMeta *extra_meta = NULL;
1299  int64_t timestamp = AV_NOPTS_VALUE;
1300 
1301  parse_id3(pls->ctx, pb, &metadata, &timestamp, &pls->audio_setup_info, &apic, &extra_meta);
1302 
1303  if (timestamp != AV_NOPTS_VALUE) {
1304  pls->id3_mpegts_timestamp = timestamp;
1305  pls->id3_offset = 0;
1306  }
1307 
1308  if (!pls->id3_found) {
1309  /* initial ID3 tags */
1311  pls->id3_found = 1;
1312 
1313  /* get picture attachment and set text metadata */
1314  if (pls->ctx->nb_streams)
1315  ff_id3v2_parse_apic(pls->ctx, extra_meta);
1316  else
1317  /* demuxer not yet opened, defer picture attachment */
1318  pls->id3_deferred_extra = extra_meta;
1319 
1320  ff_id3v2_parse_priv_dict(&metadata, extra_meta);
1321  av_dict_copy(&pls->ctx->metadata, metadata, 0);
1322  pls->id3_initial = metadata;
1323 
1324  } else {
1325  if (!pls->id3_changed && id3_has_changed_values(pls, metadata, apic)) {
1326  avpriv_report_missing_feature(pls->parent, "Changing ID3 metadata in HLS audio elementary stream");
1327  pls->id3_changed = 1;
1328  }
1330  }
1331 
1332  if (!pls->id3_deferred_extra)
1333  ff_id3v2_free_extra_meta(&extra_meta);
1334 }
1335 
1336 static void intercept_id3(struct playlist *pls, uint8_t *buf,
1337  int buf_size, int *len)
1338 {
1339  /* intercept id3 tags, we do not want to pass them to the raw
1340  * demuxer on all segment switches */
1341  int bytes;
1342  int id3_buf_pos = 0;
1343  int fill_buf = 0;
1344  struct segment *seg = current_segment(pls);
1345 
1346  /* gather all the id3 tags */
1347  while (1) {
1348  /* see if we can retrieve enough data for ID3 header */
1349  if (*len < ID3v2_HEADER_SIZE && buf_size >= ID3v2_HEADER_SIZE) {
1350  bytes = read_from_url(pls, seg, buf + *len, ID3v2_HEADER_SIZE - *len);
1351  if (bytes > 0) {
1352 
1353  if (bytes == ID3v2_HEADER_SIZE - *len)
1354  /* no EOF yet, so fill the caller buffer again after
1355  * we have stripped the ID3 tags */
1356  fill_buf = 1;
1357 
1358  *len += bytes;
1359 
1360  } else if (*len <= 0) {
1361  /* error/EOF */
1362  *len = bytes;
1363  fill_buf = 0;
1364  }
1365  }
1366 
1367  if (*len < ID3v2_HEADER_SIZE)
1368  break;
1369 
1370  if (ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) {
1371  int64_t maxsize = seg->size >= 0 ? seg->size : 1024*1024;
1372  int taglen = ff_id3v2_tag_len(buf);
1373  int tag_got_bytes = FFMIN(taglen, *len);
1374  int remaining = taglen - tag_got_bytes;
1375 
1376  if (taglen > maxsize) {
1377  av_log(pls->parent, AV_LOG_ERROR, "Too large HLS ID3 tag (%d > %"PRId64" bytes)\n",
1378  taglen, maxsize);
1379  break;
1380  }
1381 
1382  /*
1383  * Copy the id3 tag to our temporary id3 buffer.
1384  * We could read a small id3 tag directly without memcpy, but
1385  * we would still need to copy the large tags, and handling
1386  * both of those cases together with the possibility for multiple
1387  * tags would make the handling a bit complex.
1388  */
1389  pls->id3_buf = av_fast_realloc(pls->id3_buf, &pls->id3_buf_size, id3_buf_pos + taglen);
1390  if (!pls->id3_buf)
1391  break;
1392  memcpy(pls->id3_buf + id3_buf_pos, buf, tag_got_bytes);
1393  id3_buf_pos += tag_got_bytes;
1394 
1395  /* strip the intercepted bytes */
1396  *len -= tag_got_bytes;
1397  memmove(buf, buf + tag_got_bytes, *len);
1398  av_log(pls->parent, AV_LOG_DEBUG, "Stripped %d HLS ID3 bytes\n", tag_got_bytes);
1399 
1400  if (remaining > 0) {
1401  /* read the rest of the tag in */
1402  if (read_from_url(pls, seg, pls->id3_buf + id3_buf_pos, remaining) != remaining)
1403  break;
1404  id3_buf_pos += remaining;
1405  av_log(pls->parent, AV_LOG_DEBUG, "Stripped additional %d HLS ID3 bytes\n", remaining);
1406  }
1407 
1408  } else {
1409  /* no more ID3 tags */
1410  break;
1411  }
1412  }
1413 
1414  /* re-fill buffer for the caller unless EOF */
1415  if (*len >= 0 && (fill_buf || *len == 0)) {
1416  bytes = read_from_url(pls, seg, buf + *len, buf_size - *len);
1417 
1418  /* ignore error if we already had some data */
1419  if (bytes >= 0)
1420  *len += bytes;
1421  else if (*len == 0)
1422  *len = bytes;
1423  }
1424 
1425  if (pls->id3_buf) {
1426  /* Now parse all the ID3 tags */
1427  FFIOContext id3ioctx;
1428  ffio_init_read_context(&id3ioctx, pls->id3_buf, id3_buf_pos);
1429  handle_id3(&id3ioctx.pub, pls);
1430  }
1431 
1432  if (pls->is_id3_timestamped == -1)
1434 }
1435 
1436 static int read_key(HLSContext *c, struct playlist *pls, struct segment *seg)
1437 {
1438  AVIOContext *pb = NULL;
1439 
1440  int ret = open_url(pls->parent, &pb, seg->key, &c->avio_opts, NULL, NULL);
1441  if (ret < 0) {
1442  av_log(pls->parent, AV_LOG_ERROR, "Unable to open key file %s, %s\n",
1443  seg->key, av_err2str(ret));
1444  return ret;
1445  }
1446 
1447  ret = avio_read(pb, pls->key, sizeof(pls->key));
1448  ff_format_io_close(pls->parent, &pb);
1449  if (ret != sizeof(pls->key)) {
1450  if (ret < 0) {
1451  av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s, %s\n",
1452  seg->key, av_err2str(ret));
1453  } else {
1454  av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s, read bytes %d != %zu\n",
1455  seg->key, ret, sizeof(pls->key));
1457  }
1458 
1459  return ret;
1460  }
1461 
1462  av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
1463 
1464  return 0;
1465 }
1466 
1467 static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, AVIOContext **in)
1468 {
1469  AVDictionary *opts = NULL;
1470  int ret;
1471  int is_http = 0;
1472 
1473  /* Reuse a kept-open connection to the same resource by seeking instead of
1474  * reopening. For contiguous ranges the seek is a no-op and issues no request. */
1475  if (*in && pls->input_reuse && seg->key_type == KEY_NONE &&
1476  ((*in)->seekable & AVIO_SEEKABLE_NORMAL)) {
1477  int64_t seek_ret = avio_seek(*in, seg->url_offset, SEEK_SET);
1478  pls->input_reuse = 0;
1479  if (seek_ret >= 0) {
1481  "HLS reusing connection for url '%s', offset %"PRId64", playlist %d\n",
1482  seg->url, seg->url_offset, pls->index);
1483  pls->input_read_done = 0;
1484  pls->cur_seg_offset = 0;
1485  return 0;
1486  }
1487  /* Seek failed: drop the connection and reopen. */
1488  ff_format_io_close(pls->parent, in);
1489  }
1490  pls->input_reuse = 0;
1491 
1492  if (c->http_persistent)
1493  av_dict_set(&opts, "multiple_requests", "1", 0);
1494 
1495  if (seg->size >= 0) {
1496  /* Restrict the request to the wanted byte range. The end is extended
1497  * across following contiguous segments of the same resource so one
1498  * connection serves the whole run. */
1499  int64_t end_offset = seg->url_offset + seg->size;
1500  if (seg == current_segment(pls)) {
1501  int64_t n = pls->cur_seq_no - pls->start_seq_no + 1;
1502  while (n < pls->n_segments) {
1503  struct segment *ns = pls->segments[n];
1504  if (ns->size < 0 || ns->url_offset != end_offset ||
1505  ns->key_type != KEY_NONE ||
1506  ns->init_section != seg->init_section ||
1507  strcmp(ns->url, seg->url))
1508  break;
1509  end_offset = ns->url_offset + ns->size;
1510  n++;
1511  }
1512  }
1513  av_dict_set_int(&opts, "offset", seg->url_offset, 0);
1514  av_dict_set_int(&opts, "end_offset", end_offset, 0);
1515  }
1516 
1517  av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n",
1518  seg->url, seg->url_offset, pls->index);
1519 
1520  if (seg->key_type == KEY_AES_128 || seg->key_type == KEY_SAMPLE_AES) {
1521  if (strcmp(seg->key, pls->key_url)) {
1522  ret = read_key(c, pls, seg);
1523  if (ret < 0)
1524  goto cleanup;
1525  }
1526  }
1527 
1528  if (seg->key_type == KEY_AES_128) {
1529  char iv[33], key[33], url[MAX_URL_SIZE];
1530  ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
1531  ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
1532  if (strstr(seg->url, "://"))
1533  snprintf(url, sizeof(url), "crypto+%s", seg->url);
1534  else
1535  snprintf(url, sizeof(url), "crypto:%s", seg->url);
1536 
1537  av_dict_set(&opts, "key", key, 0);
1538  av_dict_set(&opts, "iv", iv, 0);
1539 
1540  ret = open_url(pls->parent, in, url, &c->avio_opts, opts, &is_http);
1541  if (ret < 0) {
1542  goto cleanup;
1543  }
1544  ret = 0;
1545  } else {
1546  ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http);
1547  }
1548 
1549  /* Seek to the requested position. If this was a HTTP request, the offset
1550  * should already be where want it to, but this allows e.g. local testing
1551  * without a HTTP server.
1552  *
1553  * This is not done for HTTP at all as avio_seek() does internal bookkeeping
1554  * of file offset which is out-of-sync with the actual offset when "offset"
1555  * AVOption is used with http protocol, causing the seek to not be a no-op
1556  * as would be expected. Wrong offset received from the server will not be
1557  * noticed without the call, though.
1558  */
1559  if (ret == 0 && !is_http && seg->url_offset) {
1560  int64_t seekret = avio_seek(*in, seg->url_offset, SEEK_SET);
1561  if (seekret < 0) {
1562  av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url);
1563  ret = seekret;
1564  ff_format_io_close(pls->parent, in);
1565  }
1566  }
1567 
1568 cleanup:
1569  av_dict_free(&opts);
1570  pls->cur_seg_offset = 0;
1571  return ret;
1572 }
1573 
1574 static int update_init_section(struct playlist *pls, struct segment *seg)
1575 {
1576  static const int max_init_section_size = 1024*1024;
1577  HLSContext *c = pls->parent->priv_data;
1578  int64_t sec_size;
1579  int64_t urlsize;
1580  int ret;
1581 
1582  if (seg->init_section == pls->cur_init_section)
1583  return 0;
1584 
1585  pls->cur_init_section = NULL;
1586 
1587  if (!seg->init_section)
1588  return 0;
1589 
1590  ret = open_input(c, pls, seg->init_section, &pls->input);
1591  if (ret < 0) {
1593  "Failed to open an initialization section in playlist %d\n",
1594  pls->index);
1595  return ret;
1596  }
1597 
1598  if (seg->init_section->size >= 0)
1599  sec_size = seg->init_section->size;
1600  else if ((urlsize = avio_size(pls->input)) >= 0)
1601  sec_size = urlsize;
1602  else
1603  sec_size = max_init_section_size;
1604 
1605  av_log(pls->parent, AV_LOG_DEBUG,
1606  "Downloading an initialization section of size %"PRId64"\n",
1607  sec_size);
1608 
1609  sec_size = FFMIN(sec_size, max_init_section_size);
1610 
1611  av_fast_malloc(&pls->init_sec_buf, &pls->init_sec_buf_size, sec_size);
1612 
1613  ret = read_from_url(pls, seg->init_section, pls->init_sec_buf,
1614  pls->init_sec_buf_size);
1615  ff_format_io_close(pls->parent, &pls->input);
1616 
1617  if (ret < 0)
1618  return ret;
1619 
1620  pls->cur_init_section = seg->init_section;
1621  pls->init_sec_data_len = ret;
1622  pls->init_sec_buf_read_offset = 0;
1623 
1624  /* spec says audio elementary streams do not have media initialization
1625  * sections, so there should be no ID3 timestamps */
1626  pls->is_id3_timestamped = 0;
1627 
1628  return 0;
1629 }
1630 
1632 {
1633  return pls->n_segments > 0 ?
1634  pls->segments[pls->n_segments - 1]->duration :
1635  pls->target_duration;
1636 }
1637 
1638 static int playlist_needed(struct playlist *pls)
1639 {
1640  AVFormatContext *s = pls->parent;
1641  int i, j;
1642  int stream_needed = 0;
1643  int first_st;
1644 
1645  /* If there is no context or streams yet, the playlist is needed */
1646  if ((!pls->ctx || !pls->n_main_streams) && !pls->is_subtitle)
1647  return 1;
1648 
1649  /* check if any of the streams in the playlist are needed */
1650  for (i = 0; i < pls->n_main_streams; i++) {
1651  if (pls->main_streams[i]->discard < AVDISCARD_ALL) {
1652  stream_needed = 1;
1653  break;
1654  }
1655  }
1656 
1657  /* If all streams in the playlist were discarded, the playlist is not
1658  * needed (regardless of whether whole programs are discarded or not). */
1659  if (!stream_needed)
1660  return 0;
1661 
1662  /* Otherwise, check if all the programs (variants) this playlist is in are
1663  * discarded. Since all streams in the playlist are part of the same programs
1664  * we can just check the programs of the first stream. */
1665 
1666  first_st = pls->main_streams[0]->index;
1667 
1668  for (i = 0; i < s->nb_programs; i++) {
1669  AVProgram *program = s->programs[i];
1670  if (program->discard < AVDISCARD_ALL) {
1671  for (j = 0; j < program->nb_stream_indexes; j++) {
1672  if (program->stream_index[j] == first_st) {
1673  /* playlist is in an undiscarded program */
1674  return 1;
1675  }
1676  }
1677  }
1678  }
1679 
1680  /* some streams were not discarded but all the programs were */
1681  return 0;
1682 }
1683 
1684 static int reload_playlist(struct playlist *v, HLSContext *c)
1685 {
1686  int ret = 0;
1687  int reload_count = 0;
1688 
1689  v->needed = playlist_needed(v);
1690 
1691  if (!v->needed)
1692  return AVERROR_EOF;
1693 
1694  if (!v->input || (c->http_persistent && v->input_read_done)) {
1695  int64_t reload_interval;
1696 
1697  /* Check that the playlist is still needed before opening a new
1698  * segment. */
1699  v->needed = playlist_needed(v);
1700 
1701  if (!v->needed) {
1702  av_log(v->parent, AV_LOG_INFO, "No longer receiving playlist %d ('%s')\n",
1703  v->index, v->url);
1704  return AVERROR_EOF;
1705  }
1706 
1707  /* If this is a live stream and the reload interval has elapsed since
1708  * the last playlist reload, reload the playlists now. */
1709  reload_interval = default_reload_interval(v);
1710 
1711 reload:
1712  reload_count++;
1713  if (reload_count > c->max_reload)
1714  return AVERROR_EOF;
1715  if (!v->finished &&
1716  av_gettime_relative() - v->last_load_time >= reload_interval) {
1717  if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) {
1718  if (ret != AVERROR_EXIT)
1719  av_log(v->parent, AV_LOG_WARNING, "Failed to reload playlist %d\n",
1720  v->index);
1721  return ret;
1722  }
1723  /* If we need to reload the playlist again below (if
1724  * there's still no more segments), switch to a reload
1725  * interval of half the target duration. */
1726  reload_interval = v->target_duration / 2;
1727  }
1728  if (v->cur_seq_no < v->start_seq_no) {
1730  "skipping %"PRId64" segments ahead, expired from playlists\n",
1731  v->start_seq_no - v->cur_seq_no);
1732  v->cur_seq_no = v->start_seq_no;
1733  }
1734  if (v->cur_seq_no > v->last_seq_no) {
1735  v->last_seq_no = v->cur_seq_no;
1736  v->m3u8_hold_counters = 0;
1737  } else if (v->last_seq_no == v->cur_seq_no) {
1738  v->m3u8_hold_counters++;
1739  if (v->m3u8_hold_counters >= c->m3u8_hold_counters) {
1740  return AVERROR_EOF;
1741  }
1742  } else {
1743  av_log(v->parent, AV_LOG_WARNING, "The m3u8 list sequence may have been wrapped.\n");
1744  }
1745  if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
1746  if (v->finished || v->is_subtitle)
1747  return AVERROR_EOF;
1748  while (av_gettime_relative() - v->last_load_time < reload_interval) {
1749  if (ff_check_interrupt(c->interrupt_callback))
1750  return AVERROR_EXIT;
1751  av_usleep(100*1000);
1752  }
1753  /* Enough time has elapsed since the last reload */
1754  goto reload;
1755  }
1756 
1757  }
1758  return ret;
1759 }
1760 
1761 static int read_data_continuous(void *opaque, uint8_t *buf, int buf_size)
1762 {
1763  struct playlist *v = opaque;
1764  HLSContext *c = v->parent->priv_data;
1765  int ret;
1766  int just_opened = 0;
1767  int segment_retries = 0;
1768  struct segment *seg;
1769 
1770  if (c->http_persistent && v->input_read_done) {
1771  av_assert0(v->input);
1772  ret = reload_playlist(v, c);
1773  if (ret < 0)
1774  return ret;
1775  }
1776 
1777  v->input_read_done = 0;
1778 
1779 restart:
1780  ret = reload_playlist(v, c);
1781  if (ret < 0)
1782  return ret;
1783 
1784  seg = current_segment(v);
1785 
1786  if (!v->input || v->input_read_done) {
1787  /* load/update Media Initialization Section, if any */
1788  ret = update_init_section(v, seg);
1789  if (ret)
1790  return ret;
1791 
1792  if (c->http_multiple == 1 && v->input_next_requested) {
1793  FFSWAP(AVIOContext *, v->input, v->input_next);
1794  v->cur_seg_offset = 0;
1795  v->input_next_requested = 0;
1796  ret = 0;
1797  } else {
1798  ret = open_input(c, v, seg, &v->input);
1799  }
1800  if (ret < 0) {
1801  if (ff_check_interrupt(c->interrupt_callback))
1802  return AVERROR_EXIT;
1803  av_log(v->parent, AV_LOG_WARNING, "Failed to open segment %"PRId64" of playlist %d\n",
1804  v->cur_seq_no,
1805  v->index);
1806  if (segment_retries >= c->seg_max_retry) {
1807  av_log(v->parent, AV_LOG_WARNING, "Segment %"PRId64" of playlist %d failed too many times, skipping\n",
1808  v->cur_seq_no,
1809  v->index);
1810  v->cur_seq_no++;
1811  segment_retries = 0;
1812  } else {
1813  segment_retries++;
1814  }
1815  goto restart;
1816  }
1817  segment_retries = 0;
1818  just_opened = 1;
1819  if (v->first_read_seq_no < 0)
1820  v->first_read_seq_no = v->cur_seq_no;
1821  }
1822 
1823  if (c->http_multiple == -1) {
1824  uint8_t *http_version_opt = NULL;
1825  int r = av_opt_get(v->input, "http_version", AV_OPT_SEARCH_CHILDREN, &http_version_opt);
1826  if (r >= 0) {
1827  c->http_multiple = (!strncmp((const char *)http_version_opt, "1.1", 3) || !strncmp((const char *)http_version_opt, "2.0", 3));
1828  av_freep(&http_version_opt);
1829  }
1830  }
1831 
1832  seg = next_segment(v);
1833  if (c->http_multiple == 1 && !v->input_next_requested &&
1834  seg && seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL) &&
1835  !segment_reusable(v->input, current_segment(v), seg)) {
1836  ret = open_input(c, v, seg, &v->input_next);
1837  if (ret < 0) {
1838  if (ff_check_interrupt(c->interrupt_callback))
1839  return AVERROR_EXIT;
1840  av_log(v->parent, AV_LOG_WARNING, "Failed to open segment %"PRId64" of playlist %d\n",
1841  v->cur_seq_no + 1,
1842  v->index);
1843  } else {
1844  v->input_next_requested = 1;
1845  }
1846  }
1847 
1849  /* Push init section out first before first actual segment */
1850  int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size);
1851  memcpy(buf, v->init_sec_buf, copy_size);
1852  v->init_sec_buf_read_offset += copy_size;
1853  return copy_size;
1854  }
1855 
1856  seg = current_segment(v);
1857  ret = read_from_url(v, seg, buf, buf_size);
1858  if (ret > 0) {
1859  if (just_opened && v->is_id3_timestamped != 0) {
1860  /* Intercept ID3 tags here, elementary audio streams are required
1861  * to convey timestamps using them in the beginning of each segment. */
1862  intercept_id3(v, buf, buf_size, &ret);
1863  }
1864 
1865  return ret;
1866  }
1867  if (ret == 0 && segment_reusable(v->input, seg, next_segment(v))) {
1868  /* Clean boundary, and the next segment continues this resource. Keep
1869  * the connection open and read it as a whole. Note that splitting
1870  * segments in these cases is useful for dynamic variant/quality
1871  * switching, but this is not supported by our HLS demuxer, so we
1872  * join the ranges. */
1873  v->input_reuse = 1;
1874  v->input_read_done = 1;
1875  } else if (c->http_persistent && is_native_http(v->input) &&
1876  seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL)) {
1877  v->input_read_done = 1;
1878  } else {
1879  ff_format_io_close(v->parent, &v->input);
1880  }
1881  v->cur_seq_no++;
1882 
1883  c->cur_seq_no = v->cur_seq_no;
1884 
1885  goto restart;
1886 }
1887 
1888 static int read_data_subtitle_segment(void *opaque, uint8_t *buf, int buf_size)
1889 {
1890  struct playlist *v = opaque;
1891  HLSContext *c = v->parent->priv_data;
1892  int ret;
1893  struct segment *seg;
1894 
1895  if (!v->needed || v->cur_seq_no - v->start_seq_no >= v->n_segments) {
1896  return AVERROR_EOF;
1897  } else {
1898  seg = current_segment(v);
1899  }
1900 
1901  if (!v->input) {
1902  ret = open_input(c, v, seg, &v->input);
1903  if (ret < 0) {
1904  if (ff_check_interrupt(c->interrupt_callback))
1905  return AVERROR_EXIT;
1906  av_log(v->parent, AV_LOG_WARNING, "Failed to open segment of playlist %d\n",
1907  v->index);
1908  return ret;
1909  }
1910  if (v->first_read_seq_no < 0)
1911  v->first_read_seq_no = v->cur_seq_no;
1912  }
1913 
1914  return read_from_url(v, seg, buf, buf_size);
1915 }
1916 
1917 static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url,
1918  int flags, AVDictionary **opts)
1919 {
1921  "A HLS playlist item '%s' referred to an external file '%s'. "
1922  "Opening this file was forbidden for security reasons\n",
1923  s->url, url);
1924  return AVERROR(EPERM);
1925 }
1926 
1927 static int init_subtitle_context(struct playlist *pls)
1928 {
1929  HLSContext *c = pls->parent->priv_data;
1930  const AVInputFormat *in_fmt;
1931  AVDictionary *opts = NULL;
1932  int ret;
1933 
1934  if (!(pls->ctx = avformat_alloc_context()))
1935  return AVERROR(ENOMEM);
1936 
1938  if (!pls->read_buffer) {
1939  avformat_free_context(pls->ctx);
1940  pls->ctx = NULL;
1941  return AVERROR(ENOMEM);
1942  }
1943 
1944  ffio_init_context(&pls->pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, pls,
1946  pls->pb.pub.seekable = 0;
1947  pls->ctx->pb = &pls->pb.pub;
1948  pls->ctx->io_open = nested_io_open;
1949 
1950  ret = ff_copy_whiteblacklists(pls->ctx, pls->parent);
1951  if (ret < 0)
1952  return ret;
1953 
1954  in_fmt = av_find_input_format("webvtt");
1955  av_dict_copy(&opts, c->seg_format_opts, 0);
1956  ret = avformat_open_input(&pls->ctx, current_segment(pls)->url, in_fmt, &opts);
1957  av_dict_free(&opts);
1958 
1959  return ret;
1960 }
1961 
1963 {
1964  HLSContext *c = v->parent->priv_data;
1965  int ret;
1966 
1967 restart:
1968  ret = reload_playlist(v, c);
1969  if (ret < 0)
1970  return ret;
1971 
1972  if (v->input && !v->ctx)
1973  ff_format_io_close(v->parent, &v->input);
1974 
1975  if (!v->input && !v->ctx) {
1977  if (ret < 0)
1978  return ret;
1979  }
1980 
1981  ret = av_read_frame(v->ctx, v->pkt);
1982  if (!ret) {
1983  return ret;
1984  }
1985  ff_format_io_close(v->parent, &v->input);
1986  v->cur_seq_no++;
1987  c->cur_seq_no = v->cur_seq_no;
1988 
1990 
1991  goto restart;
1992 }
1993 
1994 static void add_renditions_to_variant(HLSContext *c, struct variant *var,
1995  enum AVMediaType type, const char *group_id)
1996 {
1997  int i;
1998 
1999  for (i = 0; i < c->n_renditions; i++) {
2000  struct rendition *rend = c->renditions[i];
2001 
2002  if (rend->type == type && !strcmp(rend->group_id, group_id)) {
2003 
2004  if (rend->playlist)
2005  /* rendition is an external playlist
2006  * => add the playlist to the variant */
2007  dynarray_add(&var->playlists, &var->n_playlists, rend->playlist);
2008  else
2009  /* rendition is part of the variant main Media Playlist
2010  * => add the rendition to the main Media Playlist */
2011  dynarray_add(&var->playlists[0]->renditions,
2012  &var->playlists[0]->n_renditions,
2013  rend);
2014  }
2015  }
2016 }
2017 
2019  enum AVMediaType type)
2020 {
2021  int rend_idx = 0;
2022  int i;
2023 
2024  for (i = 0; i < pls->n_main_streams; i++) {
2025  AVStream *st = pls->main_streams[i];
2026 
2027  if (st->codecpar->codec_type != type)
2028  continue;
2029 
2030  for (; rend_idx < pls->n_renditions; rend_idx++) {
2031  struct rendition *rend = pls->renditions[rend_idx];
2032 
2033  if (rend->type != type)
2034  continue;
2035 
2036  if (rend->language[0])
2037  av_dict_set(&st->metadata, "language", rend->language, 0);
2038  if (rend->name[0])
2039  av_dict_set(&st->metadata, "comment", rend->name, 0);
2040 
2041  st->disposition |= rend->disposition;
2042  }
2043  if (rend_idx >=pls->n_renditions)
2044  break;
2045  }
2046 }
2047 
2048 /* if timestamp was in valid range: returns 1 and sets seq_no
2049  * if not: returns 0 and sets seq_no to closest segment */
2051  int64_t timestamp, int64_t *seq_no,
2052  int64_t *seg_start_ts)
2053 {
2054  int i;
2055  int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
2056  0 : c->first_timestamp;
2057 
2058  if (timestamp < pos) {
2059  /* Seeking before the start of the playlist, clamp to the first segment. */
2060  *seq_no = pls->start_seq_no;
2061  if (seg_start_ts)
2062  *seg_start_ts = pos;
2063  return 1;
2064  }
2065 
2066  for (i = 0; i < pls->n_segments; i++) {
2067  int64_t diff = pos + pls->segments[i]->duration - timestamp;
2068  if (diff > 0) {
2069  *seq_no = pls->start_seq_no + i;
2070  if (seg_start_ts) {
2071  *seg_start_ts = pos;
2072  }
2073  return 1;
2074  }
2075  pos += pls->segments[i]->duration;
2076  }
2077 
2078  *seq_no = pls->start_seq_no + pls->n_segments - 1;
2079 
2080  if (!pls->finished && pls->n_segments > 0) {
2081  if (seg_start_ts)
2082  *seg_start_ts = pos - pls->segments[pls->n_segments - 1]->duration;
2083  return 1;
2084  }
2085 
2086  return 0;
2087 }
2088 
2090 {
2091  int64_t seq_no;
2092 
2093  if (!pls->finished && !c->first_packet &&
2095  /* reload the playlist since it was suspended */
2096  parse_playlist(c, pls->url, pls, NULL);
2097 
2098  /* If playback is already in progress (we are just selecting a new
2099  * playlist) and this is a complete file, find the matching segment
2100  * by counting durations. */
2101  if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
2102  find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no, NULL);
2103  return seq_no;
2104  }
2105 
2106  if (!pls->finished) {
2107  if (!c->first_packet && /* we are doing a segment selection during playback */
2108  c->cur_seq_no >= pls->start_seq_no &&
2109  c->cur_seq_no < pls->start_seq_no + pls->n_segments)
2110  /* While spec 3.4.3 says that we cannot assume anything about the
2111  * content at the same sequence number on different playlists,
2112  * in practice this seems to work and doing it otherwise would
2113  * require us to download a segment to inspect its timestamps. */
2114  return c->cur_seq_no;
2115 
2116  /* If this is a live stream, start live_start_index segments from the
2117  * start or end */
2118  if (c->live_start_index < 0)
2119  seq_no = pls->start_seq_no + FFMAX(pls->n_segments +
2120  c->live_start_index, 0);
2121  else
2122  seq_no = pls->start_seq_no + FFMIN(c->live_start_index,
2123  pls->n_segments - 1);
2124 
2125  /* If #EXT-X-START in playlist, need to recalculate */
2126  if (pls->time_offset_flag && c->prefer_x_start) {
2127  int64_t start_timestamp;
2128  int64_t playlist_duration = 0;
2129  int64_t cur_timestamp = c->cur_timestamp == AV_NOPTS_VALUE ? 0 :
2130  c->cur_timestamp;
2131 
2132  for (int i = 0; i < pls->n_segments; i++)
2133  playlist_duration += pls->segments[i]->duration;
2134 
2135  /* If the absolute value of TIME-OFFSET exceeds
2136  * the duration of the playlist, it indicates either the end of the
2137  * playlist (if positive) or the beginning of the playlist (if
2138  * negative). */
2139  if (pls->start_time_offset >=0 &&
2140  pls->start_time_offset > playlist_duration)
2141  start_timestamp = cur_timestamp + playlist_duration;
2142  else if (pls->start_time_offset >= 0 &&
2143  pls->start_time_offset <= playlist_duration)
2144  start_timestamp = cur_timestamp + pls->start_time_offset;
2145  else if (pls->start_time_offset < 0 &&
2146  pls->start_time_offset < -playlist_duration)
2147  start_timestamp = cur_timestamp;
2148  else if (pls->start_time_offset < 0 &&
2149  pls->start_time_offset > -playlist_duration)
2150  start_timestamp = cur_timestamp + playlist_duration +
2151  pls->start_time_offset;
2152  else
2153  start_timestamp = cur_timestamp;
2154 
2155  find_timestamp_in_playlist(c, pls, start_timestamp, &seq_no, NULL);
2156  }
2157  return seq_no;
2158  }
2159 
2160  /* Otherwise just start on the first segment. */
2161  return pls->start_seq_no;
2162 }
2163 
2164 static void add_stream_to_programs(AVFormatContext *s, struct playlist *pls, AVStream *stream)
2165 {
2166  HLSContext *c = s->priv_data;
2167  int i, j;
2168  int bandwidth = -1;
2169 
2170  for (i = 0; i < c->n_variants; i++) {
2171  struct variant *v = c->variants[i];
2172 
2173  for (j = 0; j < v->n_playlists; j++) {
2174  if (v->playlists[j] != pls)
2175  continue;
2176 
2177  av_program_add_stream_index(s, i, stream->index);
2178 
2179  if (bandwidth < 0)
2180  bandwidth = v->bandwidth;
2181  else if (bandwidth != v->bandwidth)
2182  bandwidth = -1; /* stream in multiple variants with different bandwidths */
2183  }
2184  }
2185 
2186  if (bandwidth >= 0)
2187  av_dict_set_int(&stream->metadata, "variant_bitrate", bandwidth, 0);
2188 }
2189 
2191 {
2192  int err;
2193 
2194  err = avcodec_parameters_copy(st->codecpar, ist->codecpar);
2195  if (err < 0)
2196  return err;
2197 
2198  if (pls->is_id3_timestamped) /* custom timestamps via id3 */
2199  avpriv_set_pts_info(st, 33, 1, MPEG_TIME_BASE);
2200  else
2202 
2203  // copy disposition
2204  st->disposition = ist->disposition;
2205 
2206  av_dict_copy(&st->metadata, ist->metadata, 0);
2207 
2208  ffstream(st)->need_context_update = 1;
2209 
2210  return 0;
2211 }
2212 
2213 /* add new subdemuxer streams to our context, if any */
2215 {
2216  HLSContext *c = s->priv_data;
2217  int err;
2218 
2219  while (pls->n_main_streams < pls->ctx->nb_streams) {
2220  int ist_idx = pls->n_main_streams;
2222  AVStream *ist = pls->ctx->streams[ist_idx];
2223 
2224  if (!st)
2225  return AVERROR(ENOMEM);
2226 
2227  st->id = pls->index;
2228  dynarray_add(&pls->main_streams, &pls->n_main_streams, st);
2229 
2230  add_stream_to_programs(s, pls, st);
2231 
2232  err = set_stream_info_from_input_stream(st, pls, ist);
2233  if (err < 0)
2234  return err;
2235 
2236  /* Match the start_time of streams created before playback began. */
2237  if (c->first_timestamp != AV_NOPTS_VALUE)
2238  st->start_time = av_rescale_q(c->first_timestamp,
2239  AV_TIME_BASE_Q, st->time_base);
2240 
2241  if (ist->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
2242  if (pls->timed_id3_stream_index < 0)
2243  pls->timed_id3_stream_index = ist_idx;
2244  else
2246  "Playlist has multiple timed ID3 streams; "
2247  "only stream %d will be used for metadata propagation\n",
2248  pls->timed_id3_stream_index);
2249  }
2250  }
2251 
2252  return 0;
2253 }
2254 
2256 {
2257  HLSContext *c = s->priv_data;
2258  int flag_needed = 0;
2259  int i;
2260 
2261  for (i = 0; i < c->n_playlists; i++) {
2262  struct playlist *pls = c->playlists[i];
2263 
2264  if (pls->has_noheader_flag) {
2265  flag_needed = 1;
2266  break;
2267  }
2268  }
2269 
2270  if (flag_needed)
2271  s->ctx_flags |= AVFMTCTX_NOHEADER;
2272  else
2273  s->ctx_flags &= ~AVFMTCTX_NOHEADER;
2274 }
2275 
2277 {
2278  HLSContext *c = s->priv_data;
2279 
2283 
2284  if (c->crypto_ctx.aes_ctx)
2285  av_free(c->crypto_ctx.aes_ctx);
2286 
2287  av_dict_free(&c->avio_opts);
2288  ff_format_io_close(c->ctx, &c->playlist_pb);
2289 
2290  return 0;
2291 }
2292 
2294 {
2295  HLSContext *c = s->priv_data;
2296  int ret = 0, i;
2297  int64_t highest_cur_seq_no = 0;
2298 
2299  c->ctx = s;
2300  c->interrupt_callback = &s->interrupt_callback;
2301 
2302  c->first_packet = 1;
2303  c->first_timestamp = AV_NOPTS_VALUE;
2304  c->first_timestamp_pls = NULL;
2305  c->first_timestamp_locked = 0;
2306  c->cur_timestamp = AV_NOPTS_VALUE;
2307 
2308  if ((ret = ffio_copy_url_options(s->pb, &c->avio_opts)) < 0)
2309  return ret;
2310 
2311  /* http_persistent and http_multiple auto-detection both rely on the
2312  * AVIOContext being backed by the builtin URLContext. Neither works
2313  * when io_open is overridden with a custom callback. */
2314  if (!ffio_geturlcontext(s->pb)) {
2315  if (c->http_persistent) {
2316  av_log(s, AV_LOG_WARNING, "Disabling http_persistent due to custom io_open.\n");
2317  c->http_persistent = 0;
2318  }
2319  /* Only auto-detection is disabled, enabling http_multiple can still work
2320  * with custom io_open. */
2321  if (c->http_multiple == -1) {
2322  av_log(s, AV_LOG_WARNING, "Disabling http_multiple due to custom io_open.\n");
2323  c->http_multiple = 0;
2324  }
2325  }
2326 
2327  /* XXX: Some HLS servers don't like being sent the range header,
2328  in this case, we need to set http_seekable = 0 to disable
2329  the range header */
2330  av_dict_set_int(&c->avio_opts, "seekable", c->http_seekable, 0);
2331 
2332  if ((ret = parse_playlist(c, s->url, NULL, s->pb)) < 0)
2333  return ret;
2334 
2335  if (c->n_variants == 0) {
2336  av_log(s, AV_LOG_WARNING, "Empty playlist\n");
2337  return AVERROR_EOF;
2338  }
2339  /* If the playlist only contained playlists (Master Playlist),
2340  * parse each individual playlist. */
2341  if (c->n_playlists > 1 || c->playlists[0]->n_segments == 0) {
2342  for (i = 0; i < c->n_playlists; i++) {
2343  struct playlist *pls = c->playlists[i];
2344  pls->m3u8_hold_counters = 0;
2345  if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0) {
2346  av_log(s, AV_LOG_WARNING, "parse_playlist error %s [%s]\n", av_err2str(ret), pls->url);
2347  pls->broken = 1;
2348  if (c->n_playlists > 1)
2349  continue;
2350  return ret;
2351  }
2352  }
2353  }
2354 
2355  for (i = 0; i < c->n_variants; i++) {
2356  if (c->variants[i]->playlists[0]->n_segments == 0) {
2357  av_log(s, AV_LOG_WARNING, "Empty segment [%s]\n", c->variants[i]->playlists[0]->url);
2358  c->variants[i]->playlists[0]->broken = 1;
2359  }
2360  }
2361 
2362  /* Calculate the total duration of the stream if all segments are
2363  * available (finished or EVENT playlists). */
2364  if (c->variants[0]->playlists[0]->finished ||
2365  c->variants[0]->playlists[0]->type == PLS_TYPE_EVENT) {
2366  int64_t duration = 0;
2367  for (i = 0; i < c->variants[0]->playlists[0]->n_segments; i++)
2368  duration += c->variants[0]->playlists[0]->segments[i]->duration;
2369  s->duration = duration;
2370  }
2371 
2372  /* Associate renditions with variants */
2373  for (i = 0; i < c->n_variants; i++) {
2374  struct variant *var = c->variants[i];
2375 
2376  if (var->audio_group[0])
2378  if (var->video_group[0])
2380  if (var->subtitles_group[0])
2382  }
2383 
2384  /* Create a program for each variant */
2385  for (i = 0; i < c->n_variants; i++) {
2386  struct variant *v = c->variants[i];
2387  AVProgram *program;
2388 
2389  program = av_new_program(s, i);
2390  if (!program)
2391  return AVERROR(ENOMEM);
2392  av_dict_set_int(&program->metadata, "variant_bitrate", v->bandwidth, 0);
2393  }
2394 
2395  /* Select the starting segments */
2396  for (i = 0; i < c->n_playlists; i++) {
2397  struct playlist *pls = c->playlists[i];
2398 
2399  if (pls->n_segments == 0)
2400  continue;
2401 
2402  pls->cur_seq_no = select_cur_seq_no(c, pls);
2403  highest_cur_seq_no = FFMAX(highest_cur_seq_no, pls->cur_seq_no);
2404  }
2405 
2406  av_dict_set(&c->seg_format_opts, "prefer_hls_mpegts_pts", "1", 0);
2407 
2408  /* Open the demuxer for each playlist */
2409  for (i = 0; i < c->n_playlists; i++) {
2410  struct playlist *pls = c->playlists[i];
2411  const AVInputFormat *in_fmt = NULL;
2412  char *url;
2414  struct segment *seg = NULL;
2415 
2416  if (!(pls->ctx = avformat_alloc_context()))
2417  return AVERROR(ENOMEM);
2418 
2419  if (pls->n_segments == 0)
2420  continue;
2421 
2422  pls->index = i;
2423  pls->needed = 1;
2424  pls->parent = s;
2425 
2426  /*
2427  * If this is a live stream and this playlist looks like it is one segment
2428  * behind, try to sync it up so that every substream starts at the same
2429  * time position (so e.g. avformat_find_stream_info() will see packets from
2430  * all active streams within the first few seconds). This is not very generic,
2431  * though, as the sequence numbers are technically independent.
2432  */
2433  if (!pls->finished && pls->cur_seq_no == highest_cur_seq_no - 1 &&
2434  highest_cur_seq_no < pls->start_seq_no + pls->n_segments) {
2435  pls->cur_seq_no = highest_cur_seq_no;
2436  }
2437 
2439  if (!pls->read_buffer){
2440  avformat_free_context(pls->ctx);
2441  pls->ctx = NULL;
2442  return AVERROR(ENOMEM);
2443  }
2444 
2445  if (pls->is_subtitle)
2446  ffio_init_context(&pls->pb, (unsigned char*)av_strdup("WEBVTT\n"), (int)strlen("WEBVTT\n"), 0, pls,
2447  NULL, NULL, NULL);
2448  else
2449  ffio_init_context(&pls->pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, pls,
2451 
2452  /*
2453  * If encryption scheme is SAMPLE-AES, try to read ID3 tags of
2454  * external audio track that contains audio setup information
2455  */
2456  seg = current_segment(pls);
2457  if (seg && seg->key_type == KEY_SAMPLE_AES && pls->n_renditions > 0 &&
2458  pls->renditions[0]->type == AVMEDIA_TYPE_AUDIO) {
2459  uint8_t buf[HLS_MAX_ID3_TAGS_DATA_LEN];
2460  if ((ret = avio_read(&pls->pb.pub, buf, HLS_MAX_ID3_TAGS_DATA_LEN)) < 0) {
2461  /* Fail if error was not end of file */
2462  if (ret != AVERROR_EOF) {
2463  avformat_free_context(pls->ctx);
2464  pls->ctx = NULL;
2465  return ret;
2466  }
2467  }
2468  ret = 0;
2469  /* Reset reading */
2470  ff_format_io_close(pls->parent, &pls->input);
2471  pls->input = NULL;
2472  pls->input_read_done = 0;
2473  pls->input_reuse = 0;
2474  ff_format_io_close(pls->parent, &pls->input_next);
2475  pls->input_next = NULL;
2476  pls->input_next_requested = 0;
2477  pls->cur_seg_offset = 0;
2478  pls->cur_init_section = NULL;
2479  /* Reset EOF flag */
2480  pls->pb.pub.eof_reached = 0;
2481  /* Clear any buffered data */
2482  pls->pb.pub.buf_end = pls->pb.pub.buf_ptr = pls->pb.pub.buffer;
2483  /* Reset the position */
2484  pls->pb.pub.pos = 0;
2485  }
2486 
2487  /*
2488  * If encryption scheme is SAMPLE-AES and audio setup information is present in external audio track,
2489  * use that information to find the media format, otherwise probe input data
2490  */
2491  seg = current_segment(pls);
2492  if (seg && seg->key_type == KEY_SAMPLE_AES && pls->is_id3_timestamped &&
2497  // Keep this list in sync with ff_hls_senc_read_audio_setup_info()
2499  pls->audio_setup_info.codec_id == AV_CODEC_ID_AC3 ? "ac3" : "eac3");
2500  } else {
2501  pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
2502  pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
2503  pls->ctx->interrupt_callback = s->interrupt_callback;
2504  url = av_strdup(pls->segments[0]->url);
2505  ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0);
2506 
2507  for (int n = 0; n < pls->n_segments; n++)
2508  if (ret >= 0)
2509  ret = test_segment(s, in_fmt, pls, pls->segments[n]);
2510 
2511  if (ret < 0) {
2512  /* Free the ctx - it isn't initialized properly at this point,
2513  * so avformat_close_input shouldn't be called. If
2514  * avformat_open_input fails below, it frees and zeros the
2515  * context, so it doesn't need any special treatment like this. */
2516  av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url);
2517  avformat_free_context(pls->ctx);
2518  pls->ctx = NULL;
2519  av_free(url);
2520  return ret;
2521  }
2522  av_free(url);
2523  }
2524 
2525  seg = current_segment(pls);
2526  if (seg && seg->key_type == KEY_SAMPLE_AES) {
2527  if (strstr(in_fmt->name, "mov")) {
2528  char key[33];
2529  ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
2530  av_dict_set(&options, "decryption_key", key, 0);
2531  } else if (!c->crypto_ctx.aes_ctx) {
2532  c->crypto_ctx.aes_ctx = av_aes_alloc();
2533  if (!c->crypto_ctx.aes_ctx) {
2534  avformat_free_context(pls->ctx);
2535  pls->ctx = NULL;
2536  return AVERROR(ENOMEM);
2537  }
2538  }
2539  }
2540 
2541  pls->ctx->pb = &pls->pb.pub;
2542  pls->ctx->io_open = nested_io_open;
2543  pls->ctx->flags |= s->flags & ~AVFMT_FLAG_CUSTOM_IO;
2544 
2545  if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
2546  return ret;
2547 
2548  av_dict_copy(&options, c->seg_format_opts, 0);
2549 
2550  ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, &options);
2552  if (ret < 0)
2553  return ret;
2554 
2555  if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
2560  }
2561 
2562  if (pls->is_id3_timestamped == -1)
2563  av_log(s, AV_LOG_WARNING, "No expected HTTP requests have been made\n");
2564 
2565  /*
2566  * For ID3 timestamped raw audio streams we need to detect the packet
2567  * durations to calculate timestamps in fill_timing_for_id3_timestamped_stream(),
2568  * but for other streams we can rely on our user calling avformat_find_stream_info()
2569  * on us if they want to.
2570  */
2571  if (pls->is_id3_timestamped || (pls->n_renditions > 0 && pls->renditions[0]->type == AVMEDIA_TYPE_AUDIO)) {
2572  seg = current_segment(pls);
2573  if (seg && seg->key_type == KEY_SAMPLE_AES && pls->audio_setup_info.setup_data_length > 0 &&
2574  pls->ctx->nb_streams == 1)
2576  else
2578 
2579  if (ret < 0)
2580  return ret;
2581  }
2582 
2583  pls->has_noheader_flag = !!(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER);
2584 
2585  /* Create new AVStreams for each stream in this playlist */
2587  if (ret < 0)
2588  return ret;
2589 
2590  /*
2591  * Copy any metadata from playlist to main streams, but do not set
2592  * event flags.
2593  */
2594  if (pls->n_main_streams)
2595  av_dict_copy(&pls->main_streams[0]->metadata, pls->ctx->metadata, 0);
2596 
2597  if (pls->is_subtitle) {
2598  avformat_free_context(pls->ctx);
2599  pls->ctx = NULL;
2600  pls->needed = 0;
2601  pls->main_streams[0]->discard = AVDISCARD_ALL;
2602  }
2603 
2607  }
2608 
2610 
2611  return 0;
2612 }
2613 
2615 {
2616  HLSContext *c = s->priv_data;
2617  int i, changed = 0;
2618  int cur_needed;
2619 
2620  /* Check if any new streams are needed */
2621  for (i = 0; i < c->n_playlists; i++) {
2622  struct playlist *pls = c->playlists[i];
2623 
2624  cur_needed = playlist_needed(c->playlists[i]);
2625 
2626  if (pls->broken) {
2627  continue;
2628  }
2629  if (cur_needed && !pls->needed) {
2630  pls->needed = 1;
2631  changed = 1;
2632  pls->cur_seq_no = select_cur_seq_no(c, pls);
2633  pls->first_read_seq_no = -1;
2634  pls->pb.pub.eof_reached = 0;
2635  if (c->cur_timestamp != AV_NOPTS_VALUE) {
2636  /* catch up */
2637  pls->seek_timestamp = c->cur_timestamp +
2638  (pls->ts_offset != AV_NOPTS_VALUE ? pls->ts_offset : 0);
2639  pls->seek_flags = AVSEEK_FLAG_ANY;
2640  pls->seek_stream_index = -1;
2641  }
2642  av_log(s, AV_LOG_INFO, "Now receiving playlist %d, segment %"PRId64"\n", i, pls->cur_seq_no);
2643  } else if (first && !cur_needed && pls->needed) {
2644  ff_format_io_close(pls->parent, &pls->input);
2645  pls->input_read_done = 0;
2646  pls->input_reuse = 0;
2647  ff_format_io_close(pls->parent, &pls->input_next);
2648  pls->input_next_requested = 0;
2649  if (pls->is_subtitle)
2650  avformat_close_input(&pls->ctx);
2651  pls->needed = 0;
2652  changed = 1;
2653  av_log(s, AV_LOG_INFO, "No longer receiving playlist %d\n", i);
2654  }
2655  }
2656  return changed;
2657 }
2658 
2660 {
2661  if (pls->id3_offset >= 0) {
2662  pls->pkt->dts = pls->id3_mpegts_timestamp +
2663  av_rescale_q(pls->id3_offset,
2664  pls->ctx->streams[pls->pkt->stream_index]->time_base,
2666  if (pls->pkt->duration)
2667  pls->id3_offset += pls->pkt->duration;
2668  else
2669  pls->id3_offset = -1;
2670  } else {
2671  /* there have been packets with unknown duration
2672  * since the last id3 tag, should not normally happen */
2673  pls->pkt->dts = AV_NOPTS_VALUE;
2674  }
2675 
2676  if (pls->pkt->duration)
2677  pls->pkt->duration = av_rescale_q(pls->pkt->duration,
2678  pls->ctx->streams[pls->pkt->stream_index]->time_base,
2680 
2681  pls->pkt->pts = AV_NOPTS_VALUE;
2682 }
2683 
2684 static AVRational get_timebase(struct playlist *pls)
2685 {
2686  if (pls->is_id3_timestamped)
2687  return MPEG_TIME_BASE_Q;
2688 
2689  return pls->ctx->streams[pls->pkt->stream_index]->time_base;
2690 }
2691 
2692 static int compare_ts_with_wrapdetect(int64_t ts_a, struct playlist *pls_a,
2693  int64_t ts_b, struct playlist *pls_b)
2694 {
2695  int64_t scaled_ts_a = av_rescale_q(ts_a, get_timebase(pls_a), MPEG_TIME_BASE_Q);
2696  int64_t scaled_ts_b = av_rescale_q(ts_b, get_timebase(pls_b), MPEG_TIME_BASE_Q);
2697 
2698  return av_compare_mod(scaled_ts_a, scaled_ts_b, 1LL << 33);
2699 }
2700 
2701 /**
2702  * Check whether any entry in @p update differs from the corresponding entry
2703  * in @p current.
2704  *
2705  * HLS segments can repeat timed ID3 metadata in every segment so that
2706  * listeners joining mid-stream immediately receive the current track
2707  * information. Only signal a metadata change when values actually differ
2708  * to avoid spurious updates on every segment boundary.
2709  */
2711  const AVDictionary *update)
2712 {
2714  return 1;
2715  const AVDictionaryEntry *e = NULL;
2716  while ((e = av_dict_iterate(update, e))) {
2717  const AVDictionaryEntry *cur = av_dict_get(current, e->key, NULL, 0);
2718  if (!cur || strcmp(cur->value, e->value))
2719  return 1;
2720  }
2721  return 0;
2722 }
2723 
2725 {
2726  HLSContext *c = s->priv_data;
2727  int ret, i, minplaylist = -1;
2728 
2729  recheck_discard_flags(s, c->first_packet);
2730  c->first_packet = 0;
2731 
2732  for (i = 0; i < c->n_playlists; i++) {
2733  struct playlist *pls = c->playlists[i];
2734  /* Make sure we've got one buffered packet from each open playlist
2735  * stream */
2736  if (pls->needed && !pls->pkt->data) {
2737  while (1) {
2738  int64_t ts_diff;
2739  AVRational tb;
2740  struct segment *seg = NULL;
2741  if (pls->is_subtitle)
2742  ret = read_subtitle_packet(pls, pls->pkt);
2743  else
2744  ret = av_read_frame(pls->ctx, pls->pkt);
2745  if (ret < 0) {
2746  if (!avio_feof(&pls->pb.pub) && ret != AVERROR_EOF)
2747  return ret;
2748  break;
2749  }
2750 
2751  /* stream_index check prevents matching picture attachments etc. */
2752  if (pls->is_id3_timestamped && pls->pkt->stream_index == 0) {
2753  /* audio elementary streams are id3 timestamped */
2755  }
2756 
2757  if (pls->pkt->dts != AV_NOPTS_VALUE &&
2758  (pls->ts_offset == AV_NOPTS_VALUE ||
2759  (!c->first_timestamp_locked &&
2760  c->first_timestamp_pls == pls &&
2761  pls->cur_seq_no <= pls->first_read_seq_no + 1))) {
2762  int adjusted = 0;
2763  /* Packet timestamp rebased onto the start of the segment list. */
2764  int64_t seg_idx = pls->first_read_seq_no - pls->start_seq_no;
2765  int64_t ts = av_rescale_q(pls->pkt->pts != AV_NOPTS_VALUE ?
2766  pls->pkt->pts : pls->pkt->dts,
2768 
2769  for (int64_t k = 0; k < seg_idx && k < pls->n_segments; k++)
2770  ts -= pls->segments[k]->duration;
2771 
2772  if (c->first_timestamp == AV_NOPTS_VALUE) {
2773  c->first_timestamp = ts;
2774  c->first_timestamp_pls = pls;
2775  adjusted = 1;
2776  } else if (c->first_timestamp_pls == pls) {
2777  /* first_timestamp came from the first packet in mux
2778  * order, but another stream in the same segment may
2779  * start earlier. Lower the estimate while packets of
2780  * that segment are still arriving. */
2781  int64_t delta = c->first_timestamp - ts;
2782 
2783  if (delta > 0 && delta <= pls->target_duration) {
2784  c->first_timestamp = ts;
2785  for (int k = 0; k < c->n_playlists; k++)
2786  if (c->playlists[k]->ts_offset != AV_NOPTS_VALUE)
2787  c->playlists[k]->ts_offset += delta;
2788  adjusted = 1;
2789  }
2790  }
2791 
2792  if (pls->ts_offset == AV_NOPTS_VALUE)
2793  pls->ts_offset = ts - c->first_timestamp;
2794 
2795  if (adjusted) {
2796  for (unsigned k = 0; k < s->nb_streams; k++)
2797  s->streams[k]->start_time =
2798  av_rescale_q(c->first_timestamp, AV_TIME_BASE_Q,
2799  s->streams[k]->time_base);
2801  "First timestamp %"PRId64" from playlist %d\n",
2802  c->first_timestamp, pls->index);
2803  }
2804  }
2805 
2806  seg = current_segment(pls);
2807  if (seg && seg->key_type == KEY_SAMPLE_AES && !strstr(pls->ctx->iformat->name, "mov")) {
2809  memcpy(c->crypto_ctx.iv, seg->iv, sizeof(seg->iv));
2810  memcpy(c->crypto_ctx.key, pls->key, sizeof(pls->key));
2811  ff_hls_senc_decrypt_frame(codec_id, &c->crypto_ctx, pls->pkt);
2812  }
2813 
2814  if (pls->seek_timestamp == AV_NOPTS_VALUE)
2815  break;
2816 
2817  if (pls->seek_stream_index < 0 ||
2818  pls->seek_stream_index == pls->pkt->stream_index) {
2819 
2820  if (pls->pkt->dts == AV_NOPTS_VALUE) {
2822  break;
2823  }
2824 
2825  tb = get_timebase(pls);
2826  ts_diff = av_rescale_q_rnd(pls->pkt->dts, tb,
2828  pls->seek_timestamp;
2829  if (ts_diff >= 0 && (pls->seek_flags & AVSEEK_FLAG_ANY ||
2830  pls->pkt->flags & AV_PKT_FLAG_KEY)) {
2832  break;
2833  }
2834  }
2835  av_packet_unref(pls->pkt);
2836  }
2837  }
2838  /* Check if this stream has the packet with the lowest dts */
2839  if (pls->pkt->data) {
2840  struct playlist *minpls = minplaylist < 0 ?
2841  NULL : c->playlists[minplaylist];
2842  if (minplaylist < 0) {
2843  minplaylist = i;
2844  } else {
2845  int64_t dts = pls->pkt->dts;
2846  int64_t mindts = minpls->pkt->dts;
2847 
2848  if (dts == AV_NOPTS_VALUE ||
2849  (mindts != AV_NOPTS_VALUE && compare_ts_with_wrapdetect(dts, pls, mindts, minpls) < 0))
2850  minplaylist = i;
2851  }
2852  }
2853  }
2854 
2855  /* If we got a packet, return it */
2856  if (minplaylist >= 0) {
2857  struct playlist *pls = c->playlists[minplaylist];
2858  AVStream *ist;
2859  AVStream *st;
2860 
2862  if (ret < 0) {
2863  av_packet_unref(pls->pkt);
2864  return ret;
2865  }
2866 
2867  // If sub-demuxer reports updated metadata, copy it to the first stream
2868  // and set its AVSTREAM_EVENT_FLAG_METADATA_UPDATED flag.
2870  if (pls->n_main_streams) {
2871  st = pls->main_streams[0];
2872  av_dict_copy(&st->metadata, pls->ctx->metadata, 0);
2874  }
2876  }
2877 
2878  /* check if noheader flag has been cleared by the subdemuxer */
2879  if (pls->has_noheader_flag && !(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER)) {
2880  pls->has_noheader_flag = 0;
2882  }
2883 
2884  if (pls->pkt->stream_index >= pls->n_main_streams) {
2885  av_log(s, AV_LOG_ERROR, "stream index inconsistency: index %d, %d main streams, %d subdemuxer streams\n",
2886  pls->pkt->stream_index, pls->n_main_streams, pls->ctx->nb_streams);
2887  av_packet_unref(pls->pkt);
2888  return AVERROR_BUG;
2889  }
2890 
2891  ist = pls->ctx->streams[pls->pkt->stream_index];
2892  st = pls->main_streams[pls->pkt->stream_index];
2893 
2894  // Propagate timed-ID3 metadata changes to the main stream, suppressing
2895  // duplicate packets that repeat unchanged metadata at segment boundaries.
2896  if (ist->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3 &&
2897  pls->pkt->stream_index == pls->timed_id3_stream_index &&
2901  int ret = av_dict_copy(&st->metadata, ist->metadata, 0);
2902  if (ret < 0)
2903  return ret;
2905  ret = av_dict_copy(&pls->timed_id3_metadata, ist->metadata, 0);
2906  if (ret < 0)
2907  return ret;
2909  }
2910  }
2911 
2912  av_packet_move_ref(pkt, pls->pkt);
2913  pkt->stream_index = st->index;
2914 
2915  if (pkt->dts != AV_NOPTS_VALUE)
2916  c->cur_timestamp = av_rescale_q(pkt->dts,
2917  ist->time_base,
2918  AV_TIME_BASE_Q);
2919 
2920  /* There may be more situations where this would be useful, but this at least
2921  * handles newly probed codecs properly (i.e. request_probe by mpegts). */
2922  if (ist->codecpar->codec_id != st->codecpar->codec_id) {
2923  ret = set_stream_info_from_input_stream(st, pls, ist);
2924  if (ret < 0) {
2925  return ret;
2926  }
2927  }
2928 
2929  return 0;
2930  }
2931  return AVERROR_EOF;
2932 }
2933 
2934 static int hls_read_seek(AVFormatContext *s, int stream_index,
2935  int64_t timestamp, int flags)
2936 {
2937  HLSContext *c = s->priv_data;
2938  struct playlist *seek_pls = NULL;
2939  int i, j;
2940  int stream_subdemuxer_index;
2941  int64_t first_timestamp, seek_timestamp, duration;
2942  int64_t seq_no, seg_start_ts;
2943  int snapped_to_segment = 0;
2944 
2945  if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags & AVFMTCTX_UNSEEKABLE))
2946  return AVERROR(ENOSYS);
2947 
2948  seek_timestamp = av_rescale_q_rnd(timestamp,
2949  s->streams[stream_index]->time_base,
2951 
2952  /* find the playlist with the specified stream */
2953  for (i = 0; i < c->n_playlists; i++) {
2954  struct playlist *pls = c->playlists[i];
2955  for (j = 0; j < pls->n_main_streams; j++) {
2956  if (pls->main_streams[j] == s->streams[stream_index]) {
2957  seek_pls = pls;
2958  stream_subdemuxer_index = j;
2959  break;
2960  }
2961  }
2962  }
2963  if (!seek_pls)
2964  return AVERROR(EIO);
2965 
2966  /* Live and EVENT playlists may have gained segments since the last load,
2967  * and sliding-window playlists may also have expired some. Refresh before
2968  * resolving a seek that may fall outside the loaded window, rate limited
2969  * to the minimum reload interval (RFC 8216 6.3.4). */
2970  if (!seek_pls->finished) {
2971  int64_t elapsed = av_gettime_relative() - seek_pls->last_load_time;
2972  int64_t start = c->first_timestamp == AV_NOPTS_VALUE ?
2973  0 : c->first_timestamp;
2974  int64_t end = start;
2975  int need_refresh;
2976  for (i = 0; i < seek_pls->n_segments; i++)
2977  end += seek_pls->segments[i]->duration;
2978  need_refresh = seek_timestamp >= end;
2979  if (seek_pls->type == PLS_TYPE_UNSPECIFIED)
2980  need_refresh |= seek_timestamp < start + elapsed +
2981  seek_pls->target_duration;
2982  if (need_refresh && elapsed >= default_reload_interval(seek_pls))
2983  parse_playlist(c, seek_pls->url, seek_pls, NULL);
2984  }
2985 
2986  first_timestamp = c->first_timestamp == AV_NOPTS_VALUE ?
2987  0 : c->first_timestamp;
2988 
2989  duration = s->duration == AV_NOPTS_VALUE ?
2990  0 : s->duration;
2991 
2992  /* Only finished playlists cannot grow past the known duration. */
2993  if (seek_pls->finished &&
2994  0 < duration && duration < seek_timestamp - first_timestamp)
2995  return AVERROR(EIO);
2996 
2997  /* check if the timestamp is valid for the playlist with the
2998  * specified stream index */
2999  if (!find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no, &seg_start_ts))
3000  return AVERROR(EIO);
3001 
3002  if (s->streams[stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
3004  /* Seeking to start of segment ensures we seek to a keyframe located
3005  * before the given timestamp. */
3006  seek_timestamp = seg_start_ts;
3007  snapped_to_segment = 1;
3008  }
3009 
3010  av_log(s, AV_LOG_DEBUG, "Seek to %"PRId64" mapped to segment %"PRId64
3011  " of playlist %d (start %"PRId64")\n",
3012  seek_timestamp, seq_no, seek_pls->index, seg_start_ts);
3013 
3014  /* Keep timeline start fixed from now on. */
3015  c->first_timestamp_locked = 1;
3016 
3017  /* set segment now so we do not need to search again below */
3018  seek_pls->cur_seq_no = seq_no;
3019  seek_pls->seek_stream_index = stream_subdemuxer_index;
3020 
3021  /* Reset PTS wrap detection so backward seeks don't get misinterpreted
3022  * as a forward PTS wrap. */
3023  for (i = 0; i < (int)s->nb_streams; i++)
3025 
3026  for (i = 0; i < c->n_playlists; i++) {
3027  /* Reset reading */
3028  struct playlist *pls = c->playlists[i];
3029  AVIOContext *const pb = &pls->pb.pub;
3030  ff_format_io_close(pls->parent, &pls->input);
3031  pls->input_read_done = 0;
3032  pls->first_read_seq_no = -1;
3033  pls->input_reuse = 0;
3034  ff_format_io_close(pls->parent, &pls->input_next);
3035  pls->input_next_requested = 0;
3036  av_packet_unref(pls->pkt);
3037  pb->eof_reached = 0;
3038  /* Clear any buffered data */
3039  pb->buf_end = pb->buf_ptr = pb->buffer;
3040  /* Reset the pos, to let the mpegts/mov demuxer know we've seeked. */
3041  pb->pos = 0;
3042  /* Flush the packet queue of the subdemuxer. */
3043  if (pls->ctx) {
3044  ff_read_frame_flush(pls->ctx);
3045  for (j = 0; j < (int)pls->ctx->nb_streams; j++)
3047  }
3048  if (pls->is_subtitle)
3049  avformat_close_input(&pls->ctx);
3050 
3051  /* Reset the init segment so it's re-fetched and served appropriately */
3052  pls->cur_init_section = NULL;
3053 
3054  /* The discard in hls_read_packet compares this playlist's packet DTS
3055  * against seek_timestamp, but seek_timestamp is on c->first_timestamp's
3056  * baseline (whichever stream produced the first packet). Streams can
3057  * have different DTS baselines, so translate the threshold onto this
3058  * playlist's own baseline using its captured offset. */
3059  if (pls->ts_offset != AV_NOPTS_VALUE)
3060  pls->seek_timestamp = seek_timestamp + pls->ts_offset;
3061  else
3063  pls->seek_flags = flags;
3064 
3065  if (pls == seek_pls && snapped_to_segment) {
3066  /* The first keyframe of the target segment may have a slightly
3067  * lower DTS than the EXTINF-derived seg_start_ts. Relax the cutoff
3068  * to not discard the keyframe and land one segment late. */
3069  int64_t idx = seq_no - pls->start_seq_no;
3070  if (idx >= 0 && idx < pls->n_segments)
3071  pls->seek_timestamp -= pls->segments[idx]->duration;
3072  }
3073 
3074  if (pls != seek_pls) {
3075  /* set closest segment seq_no for playlists not handled above */
3077  /* seek the playlist to the given position without taking
3078  * keyframes into account since this playlist does not have the
3079  * specified stream where we should look for the keyframes */
3080  pls->seek_stream_index = -1;
3081  pls->seek_flags |= AVSEEK_FLAG_ANY;
3082  }
3083 
3084  pls->last_seq_no = pls->cur_seq_no;
3085  }
3086 
3087  c->cur_timestamp = seek_timestamp;
3088 
3089  return 0;
3090 }
3091 
3092 static int hls_probe(const AVProbeData *p)
3093 {
3094  /* Require #EXTM3U at the start, and either one of the ones below
3095  * somewhere for a proper match. */
3096  if (strncmp(p->buf, "#EXTM3U", 7))
3097  return 0;
3098 
3099  if (strstr(p->buf, "#EXT-X-STREAM-INF:") ||
3100  strstr(p->buf, "#EXT-X-TARGETDURATION:") ||
3101  strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:")) {
3102 
3103  int mime_ok = p->mime_type && !(
3104  av_strcasecmp(p->mime_type, "application/vnd.apple.mpegurl") &&
3105  av_strcasecmp(p->mime_type, "audio/mpegurl")
3106  );
3107 
3108  int mime_x = p->mime_type && !(
3109  av_strcasecmp(p->mime_type, "audio/x-mpegurl") &&
3110  av_strcasecmp(p->mime_type, "application/x-mpegurl")
3111  );
3112 
3113  if (!mime_ok &&
3114  !mime_x &&
3115  !av_match_ext (p->filename, "m3u8,m3u") &&
3116  ff_match_url_ext(p->filename, "m3u8,m3u") <= 0) {
3117  av_log(NULL, AV_LOG_ERROR, "Not detecting m3u8/hls with non standard extension and non standard mime type\n");
3118  return 0;
3119  }
3120  if (mime_x)
3121  av_log(NULL, AV_LOG_WARNING, "mime type is not rfc8216 compliant\n");
3122 
3123  return AVPROBE_SCORE_MAX;
3124  }
3125  return 0;
3126 }
3127 
3128 #define OFFSET(x) offsetof(HLSContext, x)
3129 #define FLAGS AV_OPT_FLAG_DECODING_PARAM
3130 static const AVOption hls_options[] = {
3131  {"live_start_index", "segment index to start live streams at (negative values are from the end)",
3132  OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS},
3133  {"prefer_x_start", "prefer to use #EXT-X-START if it's in playlist instead of live_start_index",
3134  OFFSET(prefer_x_start), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS},
3135  {"allowed_extensions", "List of file extensions that hls is allowed to access",
3136  OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
3137  {.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"
3138  ",cmfv,cmfa" // Ticket11526 www.nicovideo.jp
3139  ",ec3" // part of Ticket11435 (Elisa Viihde (Finnish online recording service))
3140  ",fmp4" // https://github.com/yt-dlp/yt-dlp/issues/12700
3141  },
3142  INT_MIN, INT_MAX, FLAGS},
3143  {"allowed_segment_extensions", "List of file extensions that hls is allowed to access",
3144  OFFSET(allowed_segment_extensions), AV_OPT_TYPE_STRING,
3145  {.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"
3146  ",cmfv,cmfa" // Ticket11526 www.nicovideo.jp
3147  ",ec3" // part of Ticket11435 (Elisa Viihde (Finnish online recording service))
3148  ",fmp4" // https://github.com/yt-dlp/yt-dlp/issues/12700
3149  ",html" // https://flash1.bogulus.cfd/
3150  },
3151  INT_MIN, INT_MAX, FLAGS},
3152  {"extension_picky", "Be picky with all extensions matching",
3153  OFFSET(extension_picky), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS},
3154  {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded",
3155  OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 100}, 0, INT_MAX, FLAGS},
3156  {"m3u8_hold_counters", "The maximum number of times to load m3u8 when it refreshes without new segments",
3157  OFFSET(m3u8_hold_counters), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS},
3158  {"http_persistent", "Use persistent HTTP connections",
3159  OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS },
3160  {"http_multiple", "Use multiple HTTP connections for fetching segments",
3161  OFFSET(http_multiple), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, FLAGS},
3162  {"http_seekable", "Use HTTP partial requests, 0 = disable, 1 = enable, -1 = auto",
3163  OFFSET(http_seekable), AV_OPT_TYPE_BOOL, { .i64 = -1}, -1, 1, FLAGS},
3164  {"seg_format_options", "Set options for segment demuxer",
3165  OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
3166  {"seg_max_retry", "Maximum number of times to reload a segment on error.",
3167  OFFSET(seg_max_retry), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS},
3168  {NULL}
3169 };
3170 
3171 static const AVClass hls_class = {
3172  .class_name = "hls demuxer",
3173  .item_name = av_default_item_name,
3174  .option = hls_options,
3175  .version = LIBAVUTIL_VERSION_INT,
3176 };
3177 
3179  .p.name = "hls",
3180  .p.long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
3181  .p.priv_class = &hls_class,
3183  .priv_data_size = sizeof(HLSContext),
3184  .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
3185  .read_probe = hls_probe,
3188  .read_close = hls_close,
3190 };
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:55
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:2692
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:2617
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:1917
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:1962
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:1532
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:2985
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:3128
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:2276
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:1207
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1618
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:2614
hls_class
static const AVClass hls_class
Definition: hls.c:3171
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:2618
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:1720
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:1580
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:3130
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:2659
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:1638
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:1761
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:1994
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:3129
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:2293
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:1540
handle_id3
static void handle_id3(AVIOContext *pb, struct playlist *pls)
Definition: hls.c:1294
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:3178
fail
#define fail
Definition: test.h:479
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:2616
current_segment
static struct segment * current_segment(struct playlist *pls)
Definition: hls.c:1188
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
current
static struct @603 current
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:2214
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:241
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:1202
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:1265
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:1888
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:2606
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:2710
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:52
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:2684
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:1574
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:578
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:2018
key_info::method
char method[11]
Definition: hls.c:425
next_segment
static struct segment * next_segment(struct playlist *pls)
Definition: hls.c:1196
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
update_noheader_flag
static void update_noheader_flag(AVFormatContext *s)
Definition: hls.c:2255
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
ff_id3v2_read_dict
void ff_id3v2_read_dict(AVFormatContext *s, 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:1174
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
select_cur_seq_no
static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
Definition: hls.c:2089
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:1927
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:1631
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:1684
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:1467
hls_read_seek
static int hls_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: hls.c:2934
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:2190
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:1953
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:1436
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:2164
hls_probe
static int hls_probe(const AVProbeData *p)
Definition: hls.c:3092
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:2724
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:2050
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:1186
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:1287
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:1298
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:1236
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:1219
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:1258
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:1336
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:330
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1727
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