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