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