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