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