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