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