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