FFmpeg
hls.c
Go to the documentation of this file.
1 /*
2  * Apple HTTP Live Streaming demuxer
3  * Copyright (c) 2010 Martin Storsjo
4  * Copyright (c) 2013 Anssi Hannula
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file
25  * Apple HTTP Live Streaming demuxer
26  * https://www.rfc-editor.org/rfc/rfc8216.txt
27  */
28 
29 #include "libavformat/http.h"
30 #include "libavutil/avstring.h"
31 #include "libavutil/avassert.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/mathematics.h"
34 #include "libavutil/opt.h"
35 #include "libavutil/dict.h"
36 #include "libavutil/time.h"
37 #include "avformat.h"
38 #include "internal.h"
39 #include "avio_internal.h"
40 #include "id3v2.h"
41 
42 #define INITIAL_BUFFER_SIZE 32768
43 
44 #define MAX_FIELD_LEN 64
45 #define MAX_CHARACTERISTICS_LEN 512
46 
47 #define MPEG_TIME_BASE 90000
48 #define MPEG_TIME_BASE_Q (AVRational){1, MPEG_TIME_BASE}
49 
50 /*
51  * An apple http stream consists of a playlist with media segment files,
52  * played sequentially. There may be several playlists with the same
53  * video content, in different bandwidth variants, that are played in
54  * parallel (preferably only one bandwidth variant at a time). In this case,
55  * the user supplied the url to a main playlist that only lists the variant
56  * playlists.
57  *
58  * If the main playlist doesn't point at any variants, we still create
59  * one anonymous toplevel variant for this, to maintain the structure.
60  */
61 
62 enum KeyType {
66 };
67 
68 struct segment {
69  int64_t duration;
70  int64_t url_offset;
71  int64_t size;
72  char *url;
73  char *key;
75  uint8_t iv[16];
76  /* associated Media Initialization Section, treated as a segment */
78 };
79 
80 struct rendition;
81 
86 };
87 
88 /*
89  * Each playlist has its own demuxer. If it currently is active,
90  * it has an open AVIOContext too, and potentially an AVPacket
91  * containing the next packet from this stream.
92  */
93 struct playlist {
96  uint8_t* read_buffer;
102  int index;
106 
107  /* main demuxer streams associated with this playlist
108  * indexed by the subdemuxer stream indexes */
111 
112  int finished;
115  int64_t start_seq_no;
117  struct segment **segments;
118  int needed;
119  int broken;
120  int64_t cur_seq_no;
121  int64_t last_seq_no;
123  int64_t cur_seg_offset;
124  int64_t last_load_time;
125 
126  /* Currently active Media Initialization Section */
128  uint8_t *init_sec_buf;
129  unsigned int init_sec_buf_size;
130  unsigned int init_sec_data_len;
132 
134  uint8_t key[16];
135 
136  /* ID3 timestamp handling (elementary audio streams have ID3 timestamps
137  * (and possibly other ID3 tags) in the beginning of each segment) */
138  int is_id3_timestamped; /* -1: not yet known */
139  int64_t id3_mpegts_timestamp; /* in mpegts tb */
140  int64_t id3_offset; /* in stream original tb */
141  uint8_t* id3_buf; /* temp buffer for id3 parsing */
142  unsigned int id3_buf_size;
143  AVDictionary *id3_initial; /* data from first id3 tag */
144  int id3_found; /* ID3 tag found at some point */
145  int id3_changed; /* ID3 tag data has changed at some point */
146  ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */
147 
148  int64_t seek_timestamp;
150  int seek_stream_index; /* into subdemuxer stream array */
151 
152  /* Renditions associated with this playlist, if any.
153  * Alternative rendition playlists have a single rendition associated
154  * with them, and variant main Media Playlists may have
155  * multiple (playlist-less) renditions associated with them. */
158 
159  /* Media Initialization Sections (EXT-X-MAP) associated with this
160  * playlist, if any. */
163 };
164 
165 /*
166  * Renditions are e.g. alternative subtitle or audio streams.
167  * The rendition may either be an external playlist or it may be
168  * contained in the main Media Playlist of the variant (in which case
169  * playlist is NULL).
170  */
171 struct rendition {
178 };
179 
180 struct variant {
182 
183  /* every variant contains at least the main Media Playlist in index 0 */
185  struct playlist **playlists;
186 
190 };
191 
192 typedef struct HLSContext {
193  AVClass *class;
196  struct variant **variants;
198  struct playlist **playlists;
201 
202  int64_t cur_seq_no;
207  int64_t cur_timestamp;
217 } HLSContext;
218 
219 static void free_segment_dynarray(struct segment **segments, int n_segments)
220 {
221  int i;
222  for (i = 0; i < n_segments; i++) {
223  av_freep(&segments[i]->key);
224  av_freep(&segments[i]->url);
225  av_freep(&segments[i]);
226  }
227 }
228 
229 static void free_segment_list(struct playlist *pls)
230 {
232  av_freep(&pls->segments);
233  pls->n_segments = 0;
234 }
235 
236 static void free_init_section_list(struct playlist *pls)
237 {
238  int i;
239  for (i = 0; i < pls->n_init_sections; i++) {
240  av_freep(&pls->init_sections[i]->url);
241  av_freep(&pls->init_sections[i]);
242  }
243  av_freep(&pls->init_sections);
244  pls->n_init_sections = 0;
245 }
246 
248 {
249  int i;
250  for (i = 0; i < c->n_playlists; i++) {
251  struct playlist *pls = c->playlists[i];
252  free_segment_list(pls);
254  av_freep(&pls->main_streams);
255  av_freep(&pls->renditions);
256  av_freep(&pls->id3_buf);
257  av_dict_free(&pls->id3_initial);
259  av_freep(&pls->init_sec_buf);
260  av_packet_free(&pls->pkt);
261  av_freep(&pls->pb.pub.buffer);
262  ff_format_io_close(c->ctx, &pls->input);
263  pls->input_read_done = 0;
264  ff_format_io_close(c->ctx, &pls->input_next);
265  pls->input_next_requested = 0;
266  if (pls->ctx) {
267  pls->ctx->pb = NULL;
268  avformat_close_input(&pls->ctx);
269  }
270  av_free(pls);
271  }
272  av_freep(&c->playlists);
273  c->n_playlists = 0;
274 }
275 
277 {
278  int i;
279  for (i = 0; i < c->n_variants; i++) {
280  struct variant *var = c->variants[i];
281  av_freep(&var->playlists);
282  av_free(var);
283  }
284  av_freep(&c->variants);
285  c->n_variants = 0;
286 }
287 
289 {
290  int i;
291  for (i = 0; i < c->n_renditions; i++)
292  av_freep(&c->renditions[i]);
293  av_freep(&c->renditions);
294  c->n_renditions = 0;
295 }
296 
297 static struct playlist *new_playlist(HLSContext *c, const char *url,
298  const char *base)
299 {
300  struct playlist *pls = av_mallocz(sizeof(struct playlist));
301  if (!pls)
302  return NULL;
303  pls->pkt = av_packet_alloc();
304  if (!pls->pkt) {
305  av_free(pls);
306  return NULL;
307  }
308  ff_make_absolute_url(pls->url, sizeof(pls->url), base, url);
309  if (!pls->url[0]) {
310  av_packet_free(&pls->pkt);
311  av_free(pls);
312  return NULL;
313  }
315 
316  pls->is_id3_timestamped = -1;
318 
319  dynarray_add(&c->playlists, &c->n_playlists, pls);
320  return pls;
321 }
322 
323 struct variant_info {
324  char bandwidth[20];
325  /* variant group ids: */
329 };
330 
331 static struct variant *new_variant(HLSContext *c, struct variant_info *info,
332  const char *url, const char *base)
333 {
334  struct variant *var;
335  struct playlist *pls;
336 
337  pls = new_playlist(c, url, base);
338  if (!pls)
339  return NULL;
340 
341  var = av_mallocz(sizeof(struct variant));
342  if (!var)
343  return NULL;
344 
345  if (info) {
346  var->bandwidth = atoi(info->bandwidth);
347  strcpy(var->audio_group, info->audio);
348  strcpy(var->video_group, info->video);
349  strcpy(var->subtitles_group, info->subtitles);
350  }
351 
352  dynarray_add(&c->variants, &c->n_variants, var);
353  dynarray_add(&var->playlists, &var->n_playlists, pls);
354  return var;
355 }
356 
357 static void handle_variant_args(struct variant_info *info, const char *key,
358  int key_len, char **dest, int *dest_len)
359 {
360  if (!strncmp(key, "BANDWIDTH=", key_len)) {
361  *dest = info->bandwidth;
362  *dest_len = sizeof(info->bandwidth);
363  } else if (!strncmp(key, "AUDIO=", key_len)) {
364  *dest = info->audio;
365  *dest_len = sizeof(info->audio);
366  } else if (!strncmp(key, "VIDEO=", key_len)) {
367  *dest = info->video;
368  *dest_len = sizeof(info->video);
369  } else if (!strncmp(key, "SUBTITLES=", key_len)) {
370  *dest = info->subtitles;
371  *dest_len = sizeof(info->subtitles);
372  }
373 }
374 
375 struct key_info {
377  char method[11];
378  char iv[35];
379 };
380 
381 static void handle_key_args(struct key_info *info, const char *key,
382  int key_len, char **dest, int *dest_len)
383 {
384  if (!strncmp(key, "METHOD=", key_len)) {
385  *dest = info->method;
386  *dest_len = sizeof(info->method);
387  } else if (!strncmp(key, "URI=", key_len)) {
388  *dest = info->uri;
389  *dest_len = sizeof(info->uri);
390  } else if (!strncmp(key, "IV=", key_len)) {
391  *dest = info->iv;
392  *dest_len = sizeof(info->iv);
393  }
394 }
395 
398  char byterange[32];
399 };
400 
401 static struct segment *new_init_section(struct playlist *pls,
402  struct init_section_info *info,
403  const char *url_base)
404 {
405  struct segment *sec;
406  char tmp_str[MAX_URL_SIZE], *ptr = tmp_str;
407 
408  if (!info->uri[0])
409  return NULL;
410 
411  sec = av_mallocz(sizeof(*sec));
412  if (!sec)
413  return NULL;
414 
415  if (!av_strncasecmp(info->uri, "data:", 5)) {
416  ptr = info->uri;
417  } else {
418  ff_make_absolute_url(tmp_str, sizeof(tmp_str), url_base, info->uri);
419  if (!tmp_str[0]) {
420  av_free(sec);
421  return NULL;
422  }
423  }
424  sec->url = av_strdup(ptr);
425  if (!sec->url) {
426  av_free(sec);
427  return NULL;
428  }
429 
430  if (info->byterange[0]) {
431  sec->size = strtoll(info->byterange, NULL, 10);
432  ptr = strchr(info->byterange, '@');
433  if (ptr)
434  sec->url_offset = strtoll(ptr+1, NULL, 10);
435  } else {
436  /* the entire file is the init section */
437  sec->size = -1;
438  }
439 
440  dynarray_add(&pls->init_sections, &pls->n_init_sections, sec);
441 
442  return sec;
443 }
444 
445 static void handle_init_section_args(struct init_section_info *info, const char *key,
446  int key_len, char **dest, int *dest_len)
447 {
448  if (!strncmp(key, "URI=", key_len)) {
449  *dest = info->uri;
450  *dest_len = sizeof(info->uri);
451  } else if (!strncmp(key, "BYTERANGE=", key_len)) {
452  *dest = info->byterange;
453  *dest_len = sizeof(info->byterange);
454  }
455 }
456 
458  char type[16];
464  char defaultr[4];
465  char forced[4];
467 };
468 
470  const char *url_base)
471 {
472  struct rendition *rend;
474  char *characteristic;
475  char *chr_ptr;
476  char *saveptr;
477 
478  if (!strcmp(info->type, "AUDIO"))
480  else if (!strcmp(info->type, "VIDEO"))
482  else if (!strcmp(info->type, "SUBTITLES"))
484  else if (!strcmp(info->type, "CLOSED-CAPTIONS"))
485  /* CLOSED-CAPTIONS is ignored since we do not support CEA-608 CC in
486  * AVC SEI RBSP anyway */
487  return NULL;
488 
489  if (type == AVMEDIA_TYPE_UNKNOWN) {
490  av_log(c->ctx, AV_LOG_WARNING, "Can't support the type: %s\n", info->type);
491  return NULL;
492  }
493 
494  /* URI is mandatory for subtitles as per spec */
495  if (type == AVMEDIA_TYPE_SUBTITLE && !info->uri[0]) {
496  av_log(c->ctx, AV_LOG_ERROR, "The URI tag is REQUIRED for subtitle.\n");
497  return NULL;
498  }
499 
500  /* TODO: handle subtitles (each segment has to parsed separately) */
501  if (c->ctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL)
502  if (type == AVMEDIA_TYPE_SUBTITLE) {
503  av_log(c->ctx, AV_LOG_WARNING, "Can't support the subtitle(uri: %s)\n", info->uri);
504  return NULL;
505  }
506 
507  rend = av_mallocz(sizeof(struct rendition));
508  if (!rend)
509  return NULL;
510 
511  dynarray_add(&c->renditions, &c->n_renditions, rend);
512 
513  rend->type = type;
514  strcpy(rend->group_id, info->group_id);
515  strcpy(rend->language, info->language);
516  strcpy(rend->name, info->name);
517 
518  /* add the playlist if this is an external rendition */
519  if (info->uri[0]) {
520  rend->playlist = new_playlist(c, info->uri, url_base);
521  if (rend->playlist)
523  &rend->playlist->n_renditions, rend);
524  }
525 
526  if (info->assoc_language[0]) {
527  int langlen = strlen(rend->language);
528  if (langlen < sizeof(rend->language) - 3) {
529  rend->language[langlen] = ',';
530  strncpy(rend->language + langlen + 1, info->assoc_language,
531  sizeof(rend->language) - langlen - 2);
532  }
533  }
534 
535  if (!strcmp(info->defaultr, "YES"))
537  if (!strcmp(info->forced, "YES"))
539 
540  chr_ptr = info->characteristics;
541  while ((characteristic = av_strtok(chr_ptr, ",", &saveptr))) {
542  if (!strcmp(characteristic, "public.accessibility.describes-music-and-sound"))
544  else if (!strcmp(characteristic, "public.accessibility.describes-video"))
546 
547  chr_ptr = NULL;
548  }
549 
550  return rend;
551 }
552 
553 static void handle_rendition_args(struct rendition_info *info, const char *key,
554  int key_len, char **dest, int *dest_len)
555 {
556  if (!strncmp(key, "TYPE=", key_len)) {
557  *dest = info->type;
558  *dest_len = sizeof(info->type);
559  } else if (!strncmp(key, "URI=", key_len)) {
560  *dest = info->uri;
561  *dest_len = sizeof(info->uri);
562  } else if (!strncmp(key, "GROUP-ID=", key_len)) {
563  *dest = info->group_id;
564  *dest_len = sizeof(info->group_id);
565  } else if (!strncmp(key, "LANGUAGE=", key_len)) {
566  *dest = info->language;
567  *dest_len = sizeof(info->language);
568  } else if (!strncmp(key, "ASSOC-LANGUAGE=", key_len)) {
569  *dest = info->assoc_language;
570  *dest_len = sizeof(info->assoc_language);
571  } else if (!strncmp(key, "NAME=", key_len)) {
572  *dest = info->name;
573  *dest_len = sizeof(info->name);
574  } else if (!strncmp(key, "DEFAULT=", key_len)) {
575  *dest = info->defaultr;
576  *dest_len = sizeof(info->defaultr);
577  } else if (!strncmp(key, "FORCED=", key_len)) {
578  *dest = info->forced;
579  *dest_len = sizeof(info->forced);
580  } else if (!strncmp(key, "CHARACTERISTICS=", key_len)) {
581  *dest = info->characteristics;
582  *dest_len = sizeof(info->characteristics);
583  }
584  /*
585  * ignored:
586  * - AUTOSELECT: client may autoselect based on e.g. system language
587  * - INSTREAM-ID: EIA-608 closed caption number ("CC1".."CC4")
588  */
589 }
590 
591 /* used by parse_playlist to allocate a new variant+playlist when the
592  * playlist is detected to be a Media Playlist (not Master Playlist)
593  * and we have no parent Master Playlist (parsing of which would have
594  * allocated the variant and playlist already)
595  * *pls == NULL => Master Playlist or parentless Media Playlist
596  * *pls != NULL => parented Media Playlist, playlist+variant allocated */
597 static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url)
598 {
599  if (*pls)
600  return 0;
601  if (!new_variant(c, NULL, url, NULL))
602  return AVERROR(ENOMEM);
603  *pls = c->playlists[c->n_playlists - 1];
604  return 0;
605 }
606 
608  const char *url, AVDictionary **options)
609 {
610 #if !CONFIG_HTTP_PROTOCOL
612 #else
613  int ret;
614  URLContext *uc = ffio_geturlcontext(*pb);
615  av_assert0(uc);
616  (*pb)->eof_reached = 0;
617  ret = ff_http_do_new_request2(uc, url, options);
618  if (ret < 0) {
619  ff_format_io_close(s, pb);
620  }
621  return ret;
622 #endif
623 }
624 
625 static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url,
626  AVDictionary **opts, AVDictionary *opts2, int *is_http_out)
627 {
628  HLSContext *c = s->priv_data;
629  AVDictionary *tmp = NULL;
630  const char *proto_name = NULL;
631  int ret;
632  int is_http = 0;
633 
634  if (av_strstart(url, "crypto", NULL)) {
635  if (url[6] == '+' || url[6] == ':')
636  proto_name = avio_find_protocol_name(url + 7);
637  } else if (av_strstart(url, "data", NULL)) {
638  if (url[4] == '+' || url[4] == ':')
639  proto_name = avio_find_protocol_name(url + 5);
640  }
641 
642  if (!proto_name)
643  proto_name = avio_find_protocol_name(url);
644 
645  if (!proto_name)
646  return AVERROR_INVALIDDATA;
647 
648  // only http(s) & file are allowed
649  if (av_strstart(proto_name, "file", NULL)) {
650  if (strcmp(c->allowed_extensions, "ALL") && !av_match_ext(url, c->allowed_extensions)) {
652  "Filename extension of \'%s\' is not a common multimedia extension, blocked for security reasons.\n"
653  "If you wish to override this adjust allowed_extensions, you can set it to \'ALL\' to allow all\n",
654  url);
655  return AVERROR_INVALIDDATA;
656  }
657  } else if (av_strstart(proto_name, "http", NULL)) {
658  is_http = 1;
659  } else if (av_strstart(proto_name, "data", NULL)) {
660  ;
661  } else
662  return AVERROR_INVALIDDATA;
663 
664  if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] == ':')
665  ;
666  else if (av_strstart(url, "crypto", NULL) && !strncmp(proto_name, url + 7, strlen(proto_name)) && url[7 + strlen(proto_name)] == ':')
667  ;
668  else if (av_strstart(url, "data", NULL) && !strncmp(proto_name, url + 5, strlen(proto_name)) && url[5 + strlen(proto_name)] == ':')
669  ;
670  else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5))
671  return AVERROR_INVALIDDATA;
672 
673  av_dict_copy(&tmp, *opts, 0);
674  av_dict_copy(&tmp, opts2, 0);
675 
676  if (is_http && c->http_persistent && *pb) {
677  ret = open_url_keepalive(c->ctx, pb, url, &tmp);
678  if (ret == AVERROR_EXIT) {
679  av_dict_free(&tmp);
680  return ret;
681  } else if (ret < 0) {
682  if (ret != AVERROR_EOF)
684  "keepalive request failed for '%s' with error: '%s' when opening url, retrying with new connection\n",
685  url, av_err2str(ret));
686  av_dict_copy(&tmp, *opts, 0);
687  av_dict_copy(&tmp, opts2, 0);
688  ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp);
689  }
690  } else {
691  ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp);
692  }
693  if (ret >= 0) {
694  // update cookies on http response with setcookies.
695  char *new_cookies = NULL;
696 
697  if (!(s->flags & AVFMT_FLAG_CUSTOM_IO))
698  av_opt_get(*pb, "cookies", AV_OPT_SEARCH_CHILDREN, (uint8_t**)&new_cookies);
699 
700  if (new_cookies)
701  av_dict_set(opts, "cookies", new_cookies, AV_DICT_DONT_STRDUP_VAL);
702  }
703 
704  av_dict_free(&tmp);
705 
706  if (is_http_out)
707  *is_http_out = is_http;
708 
709  return ret;
710 }
711 
712 static int parse_playlist(HLSContext *c, const char *url,
713  struct playlist *pls, AVIOContext *in)
714 {
715  int ret = 0, is_segment = 0, is_variant = 0;
716  int64_t duration = 0;
717  enum KeyType key_type = KEY_NONE;
718  uint8_t iv[16] = "";
719  int has_iv = 0;
720  char key[MAX_URL_SIZE] = "";
721  char line[MAX_URL_SIZE];
722  const char *ptr;
723  int close_in = 0;
724  int64_t seg_offset = 0;
725  int64_t seg_size = -1;
726  uint8_t *new_url = NULL;
727  struct variant_info variant_info;
728  char tmp_str[MAX_URL_SIZE];
729  struct segment *cur_init_section = NULL;
730  int is_http = av_strstart(url, "http", NULL);
731  struct segment **prev_segments = NULL;
732  int prev_n_segments = 0;
733  int64_t prev_start_seq_no = -1;
734 
735  if (is_http && !in && c->http_persistent && c->playlist_pb) {
736  in = c->playlist_pb;
737  ret = open_url_keepalive(c->ctx, &c->playlist_pb, url, NULL);
738  if (ret == AVERROR_EXIT) {
739  return ret;
740  } else if (ret < 0) {
741  if (ret != AVERROR_EOF)
742  av_log(c->ctx, AV_LOG_WARNING,
743  "keepalive request failed for '%s' with error: '%s' when parsing playlist\n",
744  url, av_err2str(ret));
745  in = NULL;
746  }
747  }
748 
749  if (!in) {
751  av_dict_copy(&opts, c->avio_opts, 0);
752 
753  if (c->http_persistent)
754  av_dict_set(&opts, "multiple_requests", "1", 0);
755 
756  ret = c->ctx->io_open(c->ctx, &in, url, AVIO_FLAG_READ, &opts);
757  av_dict_free(&opts);
758  if (ret < 0)
759  return ret;
760 
761  if (is_http && c->http_persistent)
762  c->playlist_pb = in;
763  else
764  close_in = 1;
765  }
766 
767  if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
768  url = new_url;
769 
770  ff_get_chomp_line(in, line, sizeof(line));
771  if (strcmp(line, "#EXTM3U")) {
773  goto fail;
774  }
775 
776  if (pls) {
777  prev_start_seq_no = pls->start_seq_no;
778  prev_segments = pls->segments;
779  prev_n_segments = pls->n_segments;
780  pls->segments = NULL;
781  pls->n_segments = 0;
782 
783  pls->finished = 0;
784  pls->type = PLS_TYPE_UNSPECIFIED;
785  }
786  while (!avio_feof(in)) {
787  ff_get_chomp_line(in, line, sizeof(line));
788  if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
789  is_variant = 1;
790  memset(&variant_info, 0, sizeof(variant_info));
792  &variant_info);
793  } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
794  struct key_info info = {{0}};
796  &info);
797  key_type = KEY_NONE;
798  has_iv = 0;
799  if (!strcmp(info.method, "AES-128"))
800  key_type = KEY_AES_128;
801  if (!strcmp(info.method, "SAMPLE-AES"))
802  key_type = KEY_SAMPLE_AES;
803  if (!av_strncasecmp(info.iv, "0x", 2)) {
804  ff_hex_to_data(iv, info.iv + 2);
805  has_iv = 1;
806  }
807  av_strlcpy(key, info.uri, sizeof(key));
808  } else if (av_strstart(line, "#EXT-X-MEDIA:", &ptr)) {
809  struct rendition_info info = {{0}};
811  &info);
812  new_rendition(c, &info, url);
813  } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
814  ret = ensure_playlist(c, &pls, url);
815  if (ret < 0)
816  goto fail;
817  pls->target_duration = strtoll(ptr, NULL, 10) * AV_TIME_BASE;
818  } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
819  uint64_t seq_no;
820  ret = ensure_playlist(c, &pls, url);
821  if (ret < 0)
822  goto fail;
823  seq_no = strtoull(ptr, NULL, 10);
824  if (seq_no > INT64_MAX) {
825  av_log(c->ctx, AV_LOG_DEBUG, "MEDIA-SEQUENCE higher than "
826  "INT64_MAX, mask out the highest bit\n");
827  seq_no &= INT64_MAX;
828  }
829  pls->start_seq_no = seq_no;
830  } else if (av_strstart(line, "#EXT-X-PLAYLIST-TYPE:", &ptr)) {
831  ret = ensure_playlist(c, &pls, url);
832  if (ret < 0)
833  goto fail;
834  if (!strcmp(ptr, "EVENT"))
835  pls->type = PLS_TYPE_EVENT;
836  else if (!strcmp(ptr, "VOD"))
837  pls->type = PLS_TYPE_VOD;
838  } else if (av_strstart(line, "#EXT-X-MAP:", &ptr)) {
839  struct init_section_info info = {{0}};
840  ret = ensure_playlist(c, &pls, url);
841  if (ret < 0)
842  goto fail;
844  &info);
845  cur_init_section = new_init_section(pls, &info, url);
846  if (!cur_init_section) {
847  ret = AVERROR(ENOMEM);
848  goto fail;
849  }
850  cur_init_section->key_type = key_type;
851  if (has_iv) {
852  memcpy(cur_init_section->iv, iv, sizeof(iv));
853  } else {
854  int64_t seq = pls->start_seq_no + pls->n_segments;
855  memset(cur_init_section->iv, 0, sizeof(cur_init_section->iv));
856  AV_WB64(cur_init_section->iv + 8, seq);
857  }
858 
859  if (key_type != KEY_NONE) {
860  ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
861  if (!tmp_str[0]) {
862  av_free(cur_init_section);
864  goto fail;
865  }
866  cur_init_section->key = av_strdup(tmp_str);
867  if (!cur_init_section->key) {
868  av_free(cur_init_section);
869  ret = AVERROR(ENOMEM);
870  goto fail;
871  }
872  } else {
873  cur_init_section->key = NULL;
874  }
875 
876  } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
877  if (pls)
878  pls->finished = 1;
879  } else if (av_strstart(line, "#EXTINF:", &ptr)) {
880  is_segment = 1;
881  duration = atof(ptr) * AV_TIME_BASE;
882  } else if (av_strstart(line, "#EXT-X-BYTERANGE:", &ptr)) {
883  seg_size = strtoll(ptr, NULL, 10);
884  ptr = strchr(ptr, '@');
885  if (ptr)
886  seg_offset = strtoll(ptr+1, NULL, 10);
887  } else if (av_strstart(line, "#", NULL)) {
888  av_log(c->ctx, AV_LOG_INFO, "Skip ('%s')\n", line);
889  continue;
890  } else if (line[0]) {
891  if (is_variant) {
892  if (!new_variant(c, &variant_info, line, url)) {
893  ret = AVERROR(ENOMEM);
894  goto fail;
895  }
896  is_variant = 0;
897  }
898  if (is_segment) {
899  struct segment *seg;
900  ret = ensure_playlist(c, &pls, url);
901  if (ret < 0)
902  goto fail;
903  seg = av_malloc(sizeof(struct segment));
904  if (!seg) {
905  ret = AVERROR(ENOMEM);
906  goto fail;
907  }
908  if (has_iv) {
909  memcpy(seg->iv, iv, sizeof(iv));
910  } else {
911  int64_t seq = pls->start_seq_no + pls->n_segments;
912  memset(seg->iv, 0, sizeof(seg->iv));
913  AV_WB64(seg->iv + 8, seq);
914  }
915 
916  if (key_type != KEY_NONE) {
917  ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
918  if (!tmp_str[0]) {
920  av_free(seg);
921  goto fail;
922  }
923  seg->key = av_strdup(tmp_str);
924  if (!seg->key) {
925  av_free(seg);
926  ret = AVERROR(ENOMEM);
927  goto fail;
928  }
929  } else {
930  seg->key = NULL;
931  }
932 
933  ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, line);
934  if (!tmp_str[0]) {
936  if (seg->key)
937  av_free(seg->key);
938  av_free(seg);
939  goto fail;
940  }
941  seg->url = av_strdup(tmp_str);
942  if (!seg->url) {
943  av_free(seg->key);
944  av_free(seg);
945  ret = AVERROR(ENOMEM);
946  goto fail;
947  }
948 
949  if (duration < 0.001 * AV_TIME_BASE) {
950  av_log(c->ctx, AV_LOG_WARNING, "Cannot get correct #EXTINF value of segment %s,"
951  " set to default value to 1ms.\n", seg->url);
952  duration = 0.001 * AV_TIME_BASE;
953  }
954  seg->duration = duration;
955  seg->key_type = key_type;
956  dynarray_add(&pls->segments, &pls->n_segments, seg);
957  is_segment = 0;
958 
959  seg->size = seg_size;
960  if (seg_size >= 0) {
961  seg->url_offset = seg_offset;
962  seg_offset += seg_size;
963  seg_size = -1;
964  } else {
965  seg->url_offset = 0;
966  seg_offset = 0;
967  }
968 
969  seg->init_section = cur_init_section;
970  }
971  }
972  }
973  if (prev_segments) {
974  if (pls->start_seq_no > prev_start_seq_no && c->first_timestamp != AV_NOPTS_VALUE) {
975  int64_t prev_timestamp = c->first_timestamp;
976  int i;
977  int64_t diff = pls->start_seq_no - prev_start_seq_no;
978  for (i = 0; i < prev_n_segments && i < diff; i++) {
979  c->first_timestamp += prev_segments[i]->duration;
980  }
981  av_log(c->ctx, AV_LOG_DEBUG, "Media sequence change (%"PRId64" -> %"PRId64")"
982  " reflected in first_timestamp: %"PRId64" -> %"PRId64"\n",
983  prev_start_seq_no, pls->start_seq_no,
984  prev_timestamp, c->first_timestamp);
985  } else if (pls->start_seq_no < prev_start_seq_no) {
986  av_log(c->ctx, AV_LOG_WARNING, "Media sequence changed unexpectedly: %"PRId64" -> %"PRId64"\n",
987  prev_start_seq_no, pls->start_seq_no);
988  }
989  free_segment_dynarray(prev_segments, prev_n_segments);
990  av_freep(&prev_segments);
991  }
992  if (pls)
994 
995 fail:
996  av_free(new_url);
997  if (close_in)
998  ff_format_io_close(c->ctx, &in);
999  c->ctx->ctx_flags = c->ctx->ctx_flags & ~(unsigned)AVFMTCTX_UNSEEKABLE;
1000  if (!c->n_variants || !c->variants[0]->n_playlists ||
1001  !(c->variants[0]->playlists[0]->finished ||
1002  c->variants[0]->playlists[0]->type == PLS_TYPE_EVENT))
1003  c->ctx->ctx_flags |= AVFMTCTX_UNSEEKABLE;
1004  return ret;
1005 }
1006 
1007 static struct segment *current_segment(struct playlist *pls)
1008 {
1009  return pls->segments[pls->cur_seq_no - pls->start_seq_no];
1010 }
1011 
1012 static struct segment *next_segment(struct playlist *pls)
1013 {
1014  int64_t n = pls->cur_seq_no - pls->start_seq_no + 1;
1015  if (n >= pls->n_segments)
1016  return NULL;
1017  return pls->segments[n];
1018 }
1019 
1020 static int read_from_url(struct playlist *pls, struct segment *seg,
1021  uint8_t *buf, int buf_size)
1022 {
1023  int ret;
1024 
1025  /* limit read if the segment was only a part of a file */
1026  if (seg->size >= 0)
1027  buf_size = FFMIN(buf_size, seg->size - pls->cur_seg_offset);
1028 
1029  ret = avio_read(pls->input, buf, buf_size);
1030  if (ret > 0)
1031  pls->cur_seg_offset += ret;
1032 
1033  return ret;
1034 }
1035 
1036 /* Parse the raw ID3 data and pass contents to caller */
1038  AVDictionary **metadata, int64_t *dts,
1039  ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta)
1040 {
1041  static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp";
1042  ID3v2ExtraMeta *meta;
1043 
1044  ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta);
1045  for (meta = *extra_meta; meta; meta = meta->next) {
1046  if (!strcmp(meta->tag, "PRIV")) {
1047  ID3v2ExtraMetaPRIV *priv = &meta->data.priv;
1048  if (priv->datasize == 8 && !strcmp(priv->owner, id3_priv_owner_ts)) {
1049  /* 33-bit MPEG timestamp */
1050  int64_t ts = AV_RB64(priv->data);
1051  av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts);
1052  if ((ts & ~((1ULL << 33) - 1)) == 0)
1053  *dts = ts;
1054  else
1055  av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts);
1056  }
1057  } else if (!strcmp(meta->tag, "APIC") && apic)
1058  *apic = &meta->data.apic;
1059  }
1060 }
1061 
1062 /* Check if the ID3 metadata contents have changed */
1063 static int id3_has_changed_values(struct playlist *pls, AVDictionary *metadata,
1064  ID3v2ExtraMetaAPIC *apic)
1065 {
1066  AVDictionaryEntry *entry = NULL;
1067  AVDictionaryEntry *oldentry;
1068  /* check that no keys have changed values */
1069  while ((entry = av_dict_get(metadata, "", entry, AV_DICT_IGNORE_SUFFIX))) {
1070  oldentry = av_dict_get(pls->id3_initial, entry->key, NULL, AV_DICT_MATCH_CASE);
1071  if (!oldentry || strcmp(oldentry->value, entry->value) != 0)
1072  return 1;
1073  }
1074 
1075  /* check if apic appeared */
1076  if (apic && (pls->ctx->nb_streams != 2 || !pls->ctx->streams[1]->attached_pic.data))
1077  return 1;
1078 
1079  if (apic) {
1080  int size = pls->ctx->streams[1]->attached_pic.size;
1081  if (size != apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE)
1082  return 1;
1083 
1084  if (memcmp(apic->buf->data, pls->ctx->streams[1]->attached_pic.data, size) != 0)
1085  return 1;
1086  }
1087 
1088  return 0;
1089 }
1090 
1091 /* Parse ID3 data and handle the found data */
1092 static void handle_id3(AVIOContext *pb, struct playlist *pls)
1093 {
1094  AVDictionary *metadata = NULL;
1095  ID3v2ExtraMetaAPIC *apic = NULL;
1096  ID3v2ExtraMeta *extra_meta = NULL;
1097  int64_t timestamp = AV_NOPTS_VALUE;
1098 
1099  parse_id3(pls->ctx, pb, &metadata, &timestamp, &apic, &extra_meta);
1100 
1101  if (timestamp != AV_NOPTS_VALUE) {
1102  pls->id3_mpegts_timestamp = timestamp;
1103  pls->id3_offset = 0;
1104  }
1105 
1106  if (!pls->id3_found) {
1107  /* initial ID3 tags */
1109  pls->id3_found = 1;
1110 
1111  /* get picture attachment and set text metadata */
1112  if (pls->ctx->nb_streams)
1113  ff_id3v2_parse_apic(pls->ctx, extra_meta);
1114  else
1115  /* demuxer not yet opened, defer picture attachment */
1116  pls->id3_deferred_extra = extra_meta;
1117 
1118  ff_id3v2_parse_priv_dict(&metadata, extra_meta);
1119  av_dict_copy(&pls->ctx->metadata, metadata, 0);
1120  pls->id3_initial = metadata;
1121 
1122  } else {
1123  if (!pls->id3_changed && id3_has_changed_values(pls, metadata, apic)) {
1124  avpriv_report_missing_feature(pls->parent, "Changing ID3 metadata in HLS audio elementary stream");
1125  pls->id3_changed = 1;
1126  }
1127  av_dict_free(&metadata);
1128  }
1129 
1130  if (!pls->id3_deferred_extra)
1131  ff_id3v2_free_extra_meta(&extra_meta);
1132 }
1133 
1134 static void intercept_id3(struct playlist *pls, uint8_t *buf,
1135  int buf_size, int *len)
1136 {
1137  /* intercept id3 tags, we do not want to pass them to the raw
1138  * demuxer on all segment switches */
1139  int bytes;
1140  int id3_buf_pos = 0;
1141  int fill_buf = 0;
1142  struct segment *seg = current_segment(pls);
1143 
1144  /* gather all the id3 tags */
1145  while (1) {
1146  /* see if we can retrieve enough data for ID3 header */
1147  if (*len < ID3v2_HEADER_SIZE && buf_size >= ID3v2_HEADER_SIZE) {
1148  bytes = read_from_url(pls, seg, buf + *len, ID3v2_HEADER_SIZE - *len);
1149  if (bytes > 0) {
1150 
1151  if (bytes == ID3v2_HEADER_SIZE - *len)
1152  /* no EOF yet, so fill the caller buffer again after
1153  * we have stripped the ID3 tags */
1154  fill_buf = 1;
1155 
1156  *len += bytes;
1157 
1158  } else if (*len <= 0) {
1159  /* error/EOF */
1160  *len = bytes;
1161  fill_buf = 0;
1162  }
1163  }
1164 
1165  if (*len < ID3v2_HEADER_SIZE)
1166  break;
1167 
1168  if (ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) {
1169  int64_t maxsize = seg->size >= 0 ? seg->size : 1024*1024;
1170  int taglen = ff_id3v2_tag_len(buf);
1171  int tag_got_bytes = FFMIN(taglen, *len);
1172  int remaining = taglen - tag_got_bytes;
1173 
1174  if (taglen > maxsize) {
1175  av_log(pls->parent, AV_LOG_ERROR, "Too large HLS ID3 tag (%d > %"PRId64" bytes)\n",
1176  taglen, maxsize);
1177  break;
1178  }
1179 
1180  /*
1181  * Copy the id3 tag to our temporary id3 buffer.
1182  * We could read a small id3 tag directly without memcpy, but
1183  * we would still need to copy the large tags, and handling
1184  * both of those cases together with the possibility for multiple
1185  * tags would make the handling a bit complex.
1186  */
1187  pls->id3_buf = av_fast_realloc(pls->id3_buf, &pls->id3_buf_size, id3_buf_pos + taglen);
1188  if (!pls->id3_buf)
1189  break;
1190  memcpy(pls->id3_buf + id3_buf_pos, buf, tag_got_bytes);
1191  id3_buf_pos += tag_got_bytes;
1192 
1193  /* strip the intercepted bytes */
1194  *len -= tag_got_bytes;
1195  memmove(buf, buf + tag_got_bytes, *len);
1196  av_log(pls->parent, AV_LOG_DEBUG, "Stripped %d HLS ID3 bytes\n", tag_got_bytes);
1197 
1198  if (remaining > 0) {
1199  /* read the rest of the tag in */
1200  if (read_from_url(pls, seg, pls->id3_buf + id3_buf_pos, remaining) != remaining)
1201  break;
1202  id3_buf_pos += remaining;
1203  av_log(pls->parent, AV_LOG_DEBUG, "Stripped additional %d HLS ID3 bytes\n", remaining);
1204  }
1205 
1206  } else {
1207  /* no more ID3 tags */
1208  break;
1209  }
1210  }
1211 
1212  /* re-fill buffer for the caller unless EOF */
1213  if (*len >= 0 && (fill_buf || *len == 0)) {
1214  bytes = read_from_url(pls, seg, buf + *len, buf_size - *len);
1215 
1216  /* ignore error if we already had some data */
1217  if (bytes >= 0)
1218  *len += bytes;
1219  else if (*len == 0)
1220  *len = bytes;
1221  }
1222 
1223  if (pls->id3_buf) {
1224  /* Now parse all the ID3 tags */
1225  FFIOContext id3ioctx;
1226  ffio_init_context(&id3ioctx, pls->id3_buf, id3_buf_pos, 0, NULL, NULL, NULL, NULL);
1227  handle_id3(&id3ioctx.pub, pls);
1228  }
1229 
1230  if (pls->is_id3_timestamped == -1)
1232 }
1233 
1234 static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, AVIOContext **in)
1235 {
1236  AVDictionary *opts = NULL;
1237  int ret;
1238  int is_http = 0;
1239 
1240  if (c->http_persistent)
1241  av_dict_set(&opts, "multiple_requests", "1", 0);
1242 
1243  if (seg->size >= 0) {
1244  /* try to restrict the HTTP request to the part we want
1245  * (if this is in fact a HTTP request) */
1246  av_dict_set_int(&opts, "offset", seg->url_offset, 0);
1247  av_dict_set_int(&opts, "end_offset", seg->url_offset + seg->size, 0);
1248  }
1249 
1250  av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n",
1251  seg->url, seg->url_offset, pls->index);
1252 
1253  if (seg->key_type == KEY_NONE) {
1254  ret = open_url(pls->parent, in, seg->url, &c->avio_opts, opts, &is_http);
1255  } else if (seg->key_type == KEY_AES_128) {
1256  char iv[33], key[33], url[MAX_URL_SIZE];
1257  if (strcmp(seg->key, pls->key_url)) {
1258  AVIOContext *pb = NULL;
1259  if (open_url(pls->parent, &pb, seg->key, &c->avio_opts, opts, NULL) == 0) {
1260  ret = avio_read(pb, pls->key, sizeof(pls->key));
1261  if (ret != sizeof(pls->key)) {
1262  av_log(pls->parent, AV_LOG_ERROR, "Unable to read key file %s\n",
1263  seg->key);
1264  }
1265  ff_format_io_close(pls->parent, &pb);
1266  } else {
1267  av_log(pls->parent, AV_LOG_ERROR, "Unable to open key file %s\n",
1268  seg->key);
1269  }
1270  av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
1271  }
1272  ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
1273  ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
1274  iv[32] = key[32] = '\0';
1275  if (strstr(seg->url, "://"))
1276  snprintf(url, sizeof(url), "crypto+%s", seg->url);
1277  else
1278  snprintf(url, sizeof(url), "crypto:%s", seg->url);
1279 
1280  av_dict_set(&opts, "key", key, 0);
1281  av_dict_set(&opts, "iv", iv, 0);
1282 
1283  ret = open_url(pls->parent, in, url, &c->avio_opts, opts, &is_http);
1284  if (ret < 0) {
1285  goto cleanup;
1286  }
1287  ret = 0;
1288  } else if (seg->key_type == KEY_SAMPLE_AES) {
1289  av_log(pls->parent, AV_LOG_ERROR,
1290  "SAMPLE-AES encryption is not supported yet\n");
1292  }
1293  else
1294  ret = AVERROR(ENOSYS);
1295 
1296  /* Seek to the requested position. If this was a HTTP request, the offset
1297  * should already be where want it to, but this allows e.g. local testing
1298  * without a HTTP server.
1299  *
1300  * This is not done for HTTP at all as avio_seek() does internal bookkeeping
1301  * of file offset which is out-of-sync with the actual offset when "offset"
1302  * AVOption is used with http protocol, causing the seek to not be a no-op
1303  * as would be expected. Wrong offset received from the server will not be
1304  * noticed without the call, though.
1305  */
1306  if (ret == 0 && !is_http && seg->url_offset) {
1307  int64_t seekret = avio_seek(*in, seg->url_offset, SEEK_SET);
1308  if (seekret < 0) {
1309  av_log(pls->parent, AV_LOG_ERROR, "Unable to seek to offset %"PRId64" of HLS segment '%s'\n", seg->url_offset, seg->url);
1310  ret = seekret;
1311  ff_format_io_close(pls->parent, in);
1312  }
1313  }
1314 
1315 cleanup:
1316  av_dict_free(&opts);
1317  pls->cur_seg_offset = 0;
1318  return ret;
1319 }
1320 
1321 static int update_init_section(struct playlist *pls, struct segment *seg)
1322 {
1323  static const int max_init_section_size = 1024*1024;
1324  HLSContext *c = pls->parent->priv_data;
1325  int64_t sec_size;
1326  int64_t urlsize;
1327  int ret;
1328 
1329  if (seg->init_section == pls->cur_init_section)
1330  return 0;
1331 
1332  pls->cur_init_section = NULL;
1333 
1334  if (!seg->init_section)
1335  return 0;
1336 
1337  ret = open_input(c, pls, seg->init_section, &pls->input);
1338  if (ret < 0) {
1340  "Failed to open an initialization section in playlist %d\n",
1341  pls->index);
1342  return ret;
1343  }
1344 
1345  if (seg->init_section->size >= 0)
1346  sec_size = seg->init_section->size;
1347  else if ((urlsize = avio_size(pls->input)) >= 0)
1348  sec_size = urlsize;
1349  else
1350  sec_size = max_init_section_size;
1351 
1352  av_log(pls->parent, AV_LOG_DEBUG,
1353  "Downloading an initialization section of size %"PRId64"\n",
1354  sec_size);
1355 
1356  sec_size = FFMIN(sec_size, max_init_section_size);
1357 
1358  av_fast_malloc(&pls->init_sec_buf, &pls->init_sec_buf_size, sec_size);
1359 
1360  ret = read_from_url(pls, seg->init_section, pls->init_sec_buf,
1361  pls->init_sec_buf_size);
1362  ff_format_io_close(pls->parent, &pls->input);
1363 
1364  if (ret < 0)
1365  return ret;
1366 
1367  pls->cur_init_section = seg->init_section;
1368  pls->init_sec_data_len = ret;
1369  pls->init_sec_buf_read_offset = 0;
1370 
1371  /* spec says audio elementary streams do not have media initialization
1372  * sections, so there should be no ID3 timestamps */
1373  pls->is_id3_timestamped = 0;
1374 
1375  return 0;
1376 }
1377 
1378 static int64_t default_reload_interval(struct playlist *pls)
1379 {
1380  return pls->n_segments > 0 ?
1381  pls->segments[pls->n_segments - 1]->duration :
1382  pls->target_duration;
1383 }
1384 
1385 static int playlist_needed(struct playlist *pls)
1386 {
1387  AVFormatContext *s = pls->parent;
1388  int i, j;
1389  int stream_needed = 0;
1390  int first_st;
1391 
1392  /* If there is no context or streams yet, the playlist is needed */
1393  if (!pls->ctx || !pls->n_main_streams)
1394  return 1;
1395 
1396  /* check if any of the streams in the playlist are needed */
1397  for (i = 0; i < pls->n_main_streams; i++) {
1398  if (pls->main_streams[i]->discard < AVDISCARD_ALL) {
1399  stream_needed = 1;
1400  break;
1401  }
1402  }
1403 
1404  /* If all streams in the playlist were discarded, the playlist is not
1405  * needed (regardless of whether whole programs are discarded or not). */
1406  if (!stream_needed)
1407  return 0;
1408 
1409  /* Otherwise, check if all the programs (variants) this playlist is in are
1410  * discarded. Since all streams in the playlist are part of the same programs
1411  * we can just check the programs of the first stream. */
1412 
1413  first_st = pls->main_streams[0]->index;
1414 
1415  for (i = 0; i < s->nb_programs; i++) {
1416  AVProgram *program = s->programs[i];
1417  if (program->discard < AVDISCARD_ALL) {
1418  for (j = 0; j < program->nb_stream_indexes; j++) {
1419  if (program->stream_index[j] == first_st) {
1420  /* playlist is in an undiscarded program */
1421  return 1;
1422  }
1423  }
1424  }
1425  }
1426 
1427  /* some streams were not discarded but all the programs were */
1428  return 0;
1429 }
1430 
1431 static int read_data(void *opaque, uint8_t *buf, int buf_size)
1432 {
1433  struct playlist *v = opaque;
1434  HLSContext *c = v->parent->priv_data;
1435  int ret;
1436  int just_opened = 0;
1437  int reload_count = 0;
1438  struct segment *seg;
1439 
1440 restart:
1441  if (!v->needed)
1442  return AVERROR_EOF;
1443 
1444  if (!v->input || (c->http_persistent && v->input_read_done)) {
1445  int64_t reload_interval;
1446 
1447  /* Check that the playlist is still needed before opening a new
1448  * segment. */
1449  v->needed = playlist_needed(v);
1450 
1451  if (!v->needed) {
1452  av_log(v->parent, AV_LOG_INFO, "No longer receiving playlist %d ('%s')\n",
1453  v->index, v->url);
1454  return AVERROR_EOF;
1455  }
1456 
1457  /* If this is a live stream and the reload interval has elapsed since
1458  * the last playlist reload, reload the playlists now. */
1459  reload_interval = default_reload_interval(v);
1460 
1461 reload:
1462  reload_count++;
1463  if (reload_count > c->max_reload)
1464  return AVERROR_EOF;
1465  if (!v->finished &&
1466  av_gettime_relative() - v->last_load_time >= reload_interval) {
1467  if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) {
1468  if (ret != AVERROR_EXIT)
1469  av_log(v->parent, AV_LOG_WARNING, "Failed to reload playlist %d\n",
1470  v->index);
1471  return ret;
1472  }
1473  /* If we need to reload the playlist again below (if
1474  * there's still no more segments), switch to a reload
1475  * interval of half the target duration. */
1476  reload_interval = v->target_duration / 2;
1477  }
1478  if (v->cur_seq_no < v->start_seq_no) {
1480  "skipping %"PRId64" segments ahead, expired from playlists\n",
1481  v->start_seq_no - v->cur_seq_no);
1482  v->cur_seq_no = v->start_seq_no;
1483  }
1484  if (v->cur_seq_no > v->last_seq_no) {
1485  v->last_seq_no = v->cur_seq_no;
1486  v->m3u8_hold_counters = 0;
1487  } else if (v->last_seq_no == v->cur_seq_no) {
1488  v->m3u8_hold_counters++;
1489  if (v->m3u8_hold_counters >= c->m3u8_hold_counters) {
1490  return AVERROR_EOF;
1491  }
1492  } else {
1493  av_log(v->parent, AV_LOG_WARNING, "maybe the m3u8 list sequence have been wraped.\n");
1494  }
1495  if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
1496  if (v->finished)
1497  return AVERROR_EOF;
1498  while (av_gettime_relative() - v->last_load_time < reload_interval) {
1499  if (ff_check_interrupt(c->interrupt_callback))
1500  return AVERROR_EXIT;
1501  av_usleep(100*1000);
1502  }
1503  /* Enough time has elapsed since the last reload */
1504  goto reload;
1505  }
1506 
1507  v->input_read_done = 0;
1508  seg = current_segment(v);
1509 
1510  /* load/update Media Initialization Section, if any */
1511  ret = update_init_section(v, seg);
1512  if (ret)
1513  return ret;
1514 
1515  if (c->http_multiple == 1 && v->input_next_requested) {
1516  FFSWAP(AVIOContext *, v->input, v->input_next);
1517  v->cur_seg_offset = 0;
1518  v->input_next_requested = 0;
1519  ret = 0;
1520  } else {
1521  ret = open_input(c, v, seg, &v->input);
1522  }
1523  if (ret < 0) {
1524  if (ff_check_interrupt(c->interrupt_callback))
1525  return AVERROR_EXIT;
1526  av_log(v->parent, AV_LOG_WARNING, "Failed to open segment %"PRId64" of playlist %d\n",
1527  v->cur_seq_no,
1528  v->index);
1529  v->cur_seq_no += 1;
1530  goto reload;
1531  }
1532  just_opened = 1;
1533  }
1534 
1535  if (c->http_multiple == -1) {
1536  uint8_t *http_version_opt = NULL;
1537  int r = av_opt_get(v->input, "http_version", AV_OPT_SEARCH_CHILDREN, &http_version_opt);
1538  if (r >= 0) {
1539  c->http_multiple = (!strncmp((const char *)http_version_opt, "1.1", 3) || !strncmp((const char *)http_version_opt, "2.0", 3));
1540  av_freep(&http_version_opt);
1541  }
1542  }
1543 
1544  seg = next_segment(v);
1545  if (c->http_multiple == 1 && !v->input_next_requested &&
1546  seg && seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL)) {
1547  ret = open_input(c, v, seg, &v->input_next);
1548  if (ret < 0) {
1549  if (ff_check_interrupt(c->interrupt_callback))
1550  return AVERROR_EXIT;
1551  av_log(v->parent, AV_LOG_WARNING, "Failed to open segment %"PRId64" of playlist %d\n",
1552  v->cur_seq_no + 1,
1553  v->index);
1554  } else {
1555  v->input_next_requested = 1;
1556  }
1557  }
1558 
1560  /* Push init section out first before first actual segment */
1561  int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size);
1562  memcpy(buf, v->init_sec_buf, copy_size);
1563  v->init_sec_buf_read_offset += copy_size;
1564  return copy_size;
1565  }
1566 
1567  seg = current_segment(v);
1568  ret = read_from_url(v, seg, buf, buf_size);
1569  if (ret > 0) {
1570  if (just_opened && v->is_id3_timestamped != 0) {
1571  /* Intercept ID3 tags here, elementary audio streams are required
1572  * to convey timestamps using them in the beginning of each segment. */
1573  intercept_id3(v, buf, buf_size, &ret);
1574  }
1575 
1576  return ret;
1577  }
1578  if (c->http_persistent &&
1579  seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL)) {
1580  v->input_read_done = 1;
1581  } else {
1582  ff_format_io_close(v->parent, &v->input);
1583  }
1584  v->cur_seq_no++;
1585 
1586  c->cur_seq_no = v->cur_seq_no;
1587 
1588  goto restart;
1589 }
1590 
1591 static void add_renditions_to_variant(HLSContext *c, struct variant *var,
1592  enum AVMediaType type, const char *group_id)
1593 {
1594  int i;
1595 
1596  for (i = 0; i < c->n_renditions; i++) {
1597  struct rendition *rend = c->renditions[i];
1598 
1599  if (rend->type == type && !strcmp(rend->group_id, group_id)) {
1600 
1601  if (rend->playlist)
1602  /* rendition is an external playlist
1603  * => add the playlist to the variant */
1604  dynarray_add(&var->playlists, &var->n_playlists, rend->playlist);
1605  else
1606  /* rendition is part of the variant main Media Playlist
1607  * => add the rendition to the main Media Playlist */
1608  dynarray_add(&var->playlists[0]->renditions,
1609  &var->playlists[0]->n_renditions,
1610  rend);
1611  }
1612  }
1613 }
1614 
1616  enum AVMediaType type)
1617 {
1618  int rend_idx = 0;
1619  int i;
1620 
1621  for (i = 0; i < pls->n_main_streams; i++) {
1622  AVStream *st = pls->main_streams[i];
1623 
1624  if (st->codecpar->codec_type != type)
1625  continue;
1626 
1627  for (; rend_idx < pls->n_renditions; rend_idx++) {
1628  struct rendition *rend = pls->renditions[rend_idx];
1629 
1630  if (rend->type != type)
1631  continue;
1632 
1633  if (rend->language[0])
1634  av_dict_set(&st->metadata, "language", rend->language, 0);
1635  if (rend->name[0])
1636  av_dict_set(&st->metadata, "comment", rend->name, 0);
1637 
1638  st->disposition |= rend->disposition;
1639  }
1640  if (rend_idx >=pls->n_renditions)
1641  break;
1642  }
1643 }
1644 
1645 /* if timestamp was in valid range: returns 1 and sets seq_no
1646  * if not: returns 0 and sets seq_no to closest segment */
1648  int64_t timestamp, int64_t *seq_no)
1649 {
1650  int i;
1651  int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
1652  0 : c->first_timestamp;
1653 
1654  if (timestamp < pos) {
1655  *seq_no = pls->start_seq_no;
1656  return 0;
1657  }
1658 
1659  for (i = 0; i < pls->n_segments; i++) {
1660  int64_t diff = pos + pls->segments[i]->duration - timestamp;
1661  if (diff > 0) {
1662  *seq_no = pls->start_seq_no + i;
1663  return 1;
1664  }
1665  pos += pls->segments[i]->duration;
1666  }
1667 
1668  *seq_no = pls->start_seq_no + pls->n_segments - 1;
1669 
1670  return 0;
1671 }
1672 
1673 static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
1674 {
1675  int64_t seq_no;
1676 
1677  if (!pls->finished && !c->first_packet &&
1679  /* reload the playlist since it was suspended */
1680  parse_playlist(c, pls->url, pls, NULL);
1681 
1682  /* If playback is already in progress (we are just selecting a new
1683  * playlist) and this is a complete file, find the matching segment
1684  * by counting durations. */
1685  if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
1686  find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
1687  return seq_no;
1688  }
1689 
1690  if (!pls->finished) {
1691  if (!c->first_packet && /* we are doing a segment selection during playback */
1692  c->cur_seq_no >= pls->start_seq_no &&
1693  c->cur_seq_no < pls->start_seq_no + pls->n_segments)
1694  /* While spec 3.4.3 says that we cannot assume anything about the
1695  * content at the same sequence number on different playlists,
1696  * in practice this seems to work and doing it otherwise would
1697  * require us to download a segment to inspect its timestamps. */
1698  return c->cur_seq_no;
1699 
1700  /* If this is a live stream, start live_start_index segments from the
1701  * start or end */
1702  if (c->live_start_index < 0)
1703  return pls->start_seq_no + FFMAX(pls->n_segments + c->live_start_index, 0);
1704  else
1705  return pls->start_seq_no + FFMIN(c->live_start_index, pls->n_segments - 1);
1706  }
1707 
1708  /* Otherwise just start on the first segment. */
1709  return pls->start_seq_no;
1710 }
1711 
1713 {
1714  HLSContext *c = s->priv_data;
1715  static const char * const opts[] = {
1716  "headers", "http_proxy", "user_agent", "cookies", "referer", "rw_timeout", "icy", NULL };
1717  const char * const * opt = opts;
1718  uint8_t *buf;
1719  int ret = 0;
1720 
1721  while (*opt) {
1722  if (av_opt_get(s->pb, *opt, AV_OPT_SEARCH_CHILDREN | AV_OPT_ALLOW_NULL, &buf) >= 0) {
1723  ret = av_dict_set(&c->avio_opts, *opt, buf,
1725  if (ret < 0)
1726  return ret;
1727  }
1728  opt++;
1729  }
1730 
1731  return ret;
1732 }
1733 
1734 static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url,
1735  int flags, AVDictionary **opts)
1736 {
1738  "A HLS playlist item '%s' referred to an external file '%s'. "
1739  "Opening this file was forbidden for security reasons\n",
1740  s->url, url);
1741  return AVERROR(EPERM);
1742 }
1743 
1744 static void add_stream_to_programs(AVFormatContext *s, struct playlist *pls, AVStream *stream)
1745 {
1746  HLSContext *c = s->priv_data;
1747  int i, j;
1748  int bandwidth = -1;
1749 
1750  for (i = 0; i < c->n_variants; i++) {
1751  struct variant *v = c->variants[i];
1752 
1753  for (j = 0; j < v->n_playlists; j++) {
1754  if (v->playlists[j] != pls)
1755  continue;
1756 
1757  av_program_add_stream_index(s, i, stream->index);
1758 
1759  if (bandwidth < 0)
1760  bandwidth = v->bandwidth;
1761  else if (bandwidth != v->bandwidth)
1762  bandwidth = -1; /* stream in multiple variants with different bandwidths */
1763  }
1764  }
1765 
1766  if (bandwidth >= 0)
1767  av_dict_set_int(&stream->metadata, "variant_bitrate", bandwidth, 0);
1768 }
1769 
1771 {
1772  int err;
1773 
1774  err = avcodec_parameters_copy(st->codecpar, ist->codecpar);
1775  if (err < 0)
1776  return err;
1777 
1778  if (pls->is_id3_timestamped) /* custom timestamps via id3 */
1779  avpriv_set_pts_info(st, 33, 1, MPEG_TIME_BASE);
1780  else
1781  avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
1782 
1783  // copy disposition
1784  st->disposition = ist->disposition;
1785 
1786  // copy side data
1787  for (int i = 0; i < ist->nb_side_data; i++) {
1788  const AVPacketSideData *sd_src = &ist->side_data[i];
1789  uint8_t *dst_data;
1790 
1791  dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size);
1792  if (!dst_data)
1793  return AVERROR(ENOMEM);
1794  memcpy(dst_data, sd_src->data, sd_src->size);
1795  }
1796 
1797  ffstream(st)->need_context_update = 1;
1798 
1799  return 0;
1800 }
1801 
1802 /* add new subdemuxer streams to our context, if any */
1804 {
1805  int err;
1806 
1807  while (pls->n_main_streams < pls->ctx->nb_streams) {
1808  int ist_idx = pls->n_main_streams;
1810  AVStream *ist = pls->ctx->streams[ist_idx];
1811 
1812  if (!st)
1813  return AVERROR(ENOMEM);
1814 
1815  st->id = pls->index;
1816  dynarray_add(&pls->main_streams, &pls->n_main_streams, st);
1817 
1818  add_stream_to_programs(s, pls, st);
1819 
1820  err = set_stream_info_from_input_stream(st, pls, ist);
1821  if (err < 0)
1822  return err;
1823  }
1824 
1825  return 0;
1826 }
1827 
1829 {
1830  HLSContext *c = s->priv_data;
1831  int flag_needed = 0;
1832  int i;
1833 
1834  for (i = 0; i < c->n_playlists; i++) {
1835  struct playlist *pls = c->playlists[i];
1836 
1837  if (pls->has_noheader_flag) {
1838  flag_needed = 1;
1839  break;
1840  }
1841  }
1842 
1843  if (flag_needed)
1844  s->ctx_flags |= AVFMTCTX_NOHEADER;
1845  else
1846  s->ctx_flags &= ~AVFMTCTX_NOHEADER;
1847 }
1848 
1850 {
1851  HLSContext *c = s->priv_data;
1852 
1856 
1857  av_dict_free(&c->avio_opts);
1858  ff_format_io_close(c->ctx, &c->playlist_pb);
1859 
1860  return 0;
1861 }
1862 
1864 {
1865  HLSContext *c = s->priv_data;
1866  int ret = 0, i;
1867  int64_t highest_cur_seq_no = 0;
1868 
1869  c->ctx = s;
1870  c->interrupt_callback = &s->interrupt_callback;
1871 
1872  c->first_packet = 1;
1873  c->first_timestamp = AV_NOPTS_VALUE;
1874  c->cur_timestamp = AV_NOPTS_VALUE;
1875 
1876  if ((ret = save_avio_options(s)) < 0)
1877  return ret;
1878 
1879  /* XXX: Some HLS servers don't like being sent the range header,
1880  in this case, need to setting http_seekable = 0 to disable
1881  the range header */
1882  av_dict_set_int(&c->avio_opts, "seekable", c->http_seekable, 0);
1883 
1884  if ((ret = parse_playlist(c, s->url, NULL, s->pb)) < 0)
1885  return ret;
1886 
1887  if (c->n_variants == 0) {
1888  av_log(s, AV_LOG_WARNING, "Empty playlist\n");
1889  return AVERROR_EOF;
1890  }
1891  /* If the playlist only contained playlists (Master Playlist),
1892  * parse each individual playlist. */
1893  if (c->n_playlists > 1 || c->playlists[0]->n_segments == 0) {
1894  for (i = 0; i < c->n_playlists; i++) {
1895  struct playlist *pls = c->playlists[i];
1896  pls->m3u8_hold_counters = 0;
1897  if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0) {
1898  av_log(s, AV_LOG_WARNING, "parse_playlist error %s [%s]\n", av_err2str(ret), pls->url);
1899  pls->broken = 1;
1900  if (c->n_playlists > 1)
1901  continue;
1902  return ret;
1903  }
1904  }
1905  }
1906 
1907  for (i = 0; i < c->n_variants; i++) {
1908  if (c->variants[i]->playlists[0]->n_segments == 0) {
1909  av_log(s, AV_LOG_WARNING, "Empty segment [%s]\n", c->variants[i]->playlists[0]->url);
1910  c->variants[i]->playlists[0]->broken = 1;
1911  }
1912  }
1913 
1914  /* If this isn't a live stream, calculate the total duration of the
1915  * stream. */
1916  if (c->variants[0]->playlists[0]->finished) {
1917  int64_t duration = 0;
1918  for (i = 0; i < c->variants[0]->playlists[0]->n_segments; i++)
1919  duration += c->variants[0]->playlists[0]->segments[i]->duration;
1920  s->duration = duration;
1921  }
1922 
1923  /* Associate renditions with variants */
1924  for (i = 0; i < c->n_variants; i++) {
1925  struct variant *var = c->variants[i];
1926 
1927  if (var->audio_group[0])
1929  if (var->video_group[0])
1931  if (var->subtitles_group[0])
1933  }
1934 
1935  /* Create a program for each variant */
1936  for (i = 0; i < c->n_variants; i++) {
1937  struct variant *v = c->variants[i];
1938  AVProgram *program;
1939 
1940  program = av_new_program(s, i);
1941  if (!program)
1942  return AVERROR(ENOMEM);
1943  av_dict_set_int(&program->metadata, "variant_bitrate", v->bandwidth, 0);
1944  }
1945 
1946  /* Select the starting segments */
1947  for (i = 0; i < c->n_playlists; i++) {
1948  struct playlist *pls = c->playlists[i];
1949 
1950  if (pls->n_segments == 0)
1951  continue;
1952 
1953  pls->cur_seq_no = select_cur_seq_no(c, pls);
1954  highest_cur_seq_no = FFMAX(highest_cur_seq_no, pls->cur_seq_no);
1955  }
1956 
1957  /* Open the demuxer for each playlist */
1958  for (i = 0; i < c->n_playlists; i++) {
1959  struct playlist *pls = c->playlists[i];
1960  const AVInputFormat *in_fmt = NULL;
1961  char *url;
1962  AVDictionary *seg_format_opts = NULL;
1963 
1964  if (!(pls->ctx = avformat_alloc_context()))
1965  return AVERROR(ENOMEM);
1966 
1967  if (pls->n_segments == 0)
1968  continue;
1969 
1970  pls->index = i;
1971  pls->needed = 1;
1972  pls->parent = s;
1973 
1974  /*
1975  * If this is a live stream and this playlist looks like it is one segment
1976  * behind, try to sync it up so that every substream starts at the same
1977  * time position (so e.g. avformat_find_stream_info() will see packets from
1978  * all active streams within the first few seconds). This is not very generic,
1979  * though, as the sequence numbers are technically independent.
1980  */
1981  if (!pls->finished && pls->cur_seq_no == highest_cur_seq_no - 1 &&
1982  highest_cur_seq_no < pls->start_seq_no + pls->n_segments) {
1983  pls->cur_seq_no = highest_cur_seq_no;
1984  }
1985 
1987  if (!pls->read_buffer){
1988  avformat_free_context(pls->ctx);
1989  pls->ctx = NULL;
1990  return AVERROR(ENOMEM);
1991  }
1992  ffio_init_context(&pls->pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, pls,
1993  read_data, NULL, NULL);
1994  pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
1995  pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
1996  pls->ctx->interrupt_callback = s->interrupt_callback;
1997  url = av_strdup(pls->segments[0]->url);
1998  ret = av_probe_input_buffer(&pls->pb.pub, &in_fmt, url, NULL, 0, 0);
1999  if (ret < 0) {
2000  /* Free the ctx - it isn't initialized properly at this point,
2001  * so avformat_close_input shouldn't be called. If
2002  * avformat_open_input fails below, it frees and zeros the
2003  * context, so it doesn't need any special treatment like this. */
2004  av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", url);
2005  avformat_free_context(pls->ctx);
2006  pls->ctx = NULL;
2007  av_free(url);
2008  return ret;
2009  }
2010  av_free(url);
2011  pls->ctx->pb = &pls->pb.pub;
2012  pls->ctx->io_open = nested_io_open;
2013  pls->ctx->flags |= s->flags & ~AVFMT_FLAG_CUSTOM_IO;
2014 
2015  if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
2016  return ret;
2017 
2018  av_dict_copy(&seg_format_opts, c->seg_format_opts, 0);
2019 
2020  ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, &seg_format_opts);
2021  av_dict_free(&seg_format_opts);
2022  if (ret < 0)
2023  return ret;
2024 
2025  if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
2030  }
2031 
2032  if (pls->is_id3_timestamped == -1)
2033  av_log(s, AV_LOG_WARNING, "No expected HTTP requests have been made\n");
2034 
2035  /*
2036  * For ID3 timestamped raw audio streams we need to detect the packet
2037  * durations to calculate timestamps in fill_timing_for_id3_timestamped_stream(),
2038  * but for other streams we can rely on our user calling avformat_find_stream_info()
2039  * on us if they want to.
2040  */
2041  if (pls->is_id3_timestamped || (pls->n_renditions > 0 && pls->renditions[0]->type == AVMEDIA_TYPE_AUDIO)) {
2043  if (ret < 0)
2044  return ret;
2045  }
2046 
2047  pls->has_noheader_flag = !!(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER);
2048 
2049  /* Create new AVStreams for each stream in this playlist */
2051  if (ret < 0)
2052  return ret;
2053 
2054  /*
2055  * Copy any metadata from playlist to main streams, but do not set
2056  * event flags.
2057  */
2058  if (pls->n_main_streams)
2059  av_dict_copy(&pls->main_streams[0]->metadata, pls->ctx->metadata, 0);
2060 
2064  }
2065 
2067 
2068  return 0;
2069 }
2070 
2072 {
2073  HLSContext *c = s->priv_data;
2074  int i, changed = 0;
2075  int cur_needed;
2076 
2077  /* Check if any new streams are needed */
2078  for (i = 0; i < c->n_playlists; i++) {
2079  struct playlist *pls = c->playlists[i];
2080 
2081  cur_needed = playlist_needed(c->playlists[i]);
2082 
2083  if (pls->broken) {
2084  continue;
2085  }
2086  if (cur_needed && !pls->needed) {
2087  pls->needed = 1;
2088  changed = 1;
2089  pls->cur_seq_no = select_cur_seq_no(c, pls);
2090  pls->pb.pub.eof_reached = 0;
2091  if (c->cur_timestamp != AV_NOPTS_VALUE) {
2092  /* catch up */
2093  pls->seek_timestamp = c->cur_timestamp;
2094  pls->seek_flags = AVSEEK_FLAG_ANY;
2095  pls->seek_stream_index = -1;
2096  }
2097  av_log(s, AV_LOG_INFO, "Now receiving playlist %d, segment %"PRId64"\n", i, pls->cur_seq_no);
2098  } else if (first && !cur_needed && pls->needed) {
2099  ff_format_io_close(pls->parent, &pls->input);
2100  pls->input_read_done = 0;
2101  ff_format_io_close(pls->parent, &pls->input_next);
2102  pls->input_next_requested = 0;
2103  pls->needed = 0;
2104  changed = 1;
2105  av_log(s, AV_LOG_INFO, "No longer receiving playlist %d\n", i);
2106  }
2107  }
2108  return changed;
2109 }
2110 
2112 {
2113  if (pls->id3_offset >= 0) {
2114  pls->pkt->dts = pls->id3_mpegts_timestamp +
2115  av_rescale_q(pls->id3_offset,
2116  pls->ctx->streams[pls->pkt->stream_index]->time_base,
2118  if (pls->pkt->duration)
2119  pls->id3_offset += pls->pkt->duration;
2120  else
2121  pls->id3_offset = -1;
2122  } else {
2123  /* there have been packets with unknown duration
2124  * since the last id3 tag, should not normally happen */
2125  pls->pkt->dts = AV_NOPTS_VALUE;
2126  }
2127 
2128  if (pls->pkt->duration)
2129  pls->pkt->duration = av_rescale_q(pls->pkt->duration,
2130  pls->ctx->streams[pls->pkt->stream_index]->time_base,
2132 
2133  pls->pkt->pts = AV_NOPTS_VALUE;
2134 }
2135 
2136 static AVRational get_timebase(struct playlist *pls)
2137 {
2138  if (pls->is_id3_timestamped)
2139  return MPEG_TIME_BASE_Q;
2140 
2141  return pls->ctx->streams[pls->pkt->stream_index]->time_base;
2142 }
2143 
2144 static int compare_ts_with_wrapdetect(int64_t ts_a, struct playlist *pls_a,
2145  int64_t ts_b, struct playlist *pls_b)
2146 {
2147  int64_t scaled_ts_a = av_rescale_q(ts_a, get_timebase(pls_a), MPEG_TIME_BASE_Q);
2148  int64_t scaled_ts_b = av_rescale_q(ts_b, get_timebase(pls_b), MPEG_TIME_BASE_Q);
2149 
2150  return av_compare_mod(scaled_ts_a, scaled_ts_b, 1LL << 33);
2151 }
2152 
2154 {
2155  HLSContext *c = s->priv_data;
2156  int ret, i, minplaylist = -1;
2157 
2158  recheck_discard_flags(s, c->first_packet);
2159  c->first_packet = 0;
2160 
2161  for (i = 0; i < c->n_playlists; i++) {
2162  struct playlist *pls = c->playlists[i];
2163  /* Make sure we've got one buffered packet from each open playlist
2164  * stream */
2165  if (pls->needed && !pls->pkt->data) {
2166  while (1) {
2167  int64_t ts_diff;
2168  AVRational tb;
2169  ret = av_read_frame(pls->ctx, pls->pkt);
2170  if (ret < 0) {
2171  if (!avio_feof(&pls->pb.pub) && ret != AVERROR_EOF)
2172  return ret;
2173  break;
2174  } else {
2175  /* stream_index check prevents matching picture attachments etc. */
2176  if (pls->is_id3_timestamped && pls->pkt->stream_index == 0) {
2177  /* audio elementary streams are id3 timestamped */
2179  }
2180 
2181  if (c->first_timestamp == AV_NOPTS_VALUE &&
2182  pls->pkt->dts != AV_NOPTS_VALUE)
2183  c->first_timestamp = av_rescale_q(pls->pkt->dts,
2185  }
2186 
2187  if (pls->seek_timestamp == AV_NOPTS_VALUE)
2188  break;
2189 
2190  if (pls->seek_stream_index < 0 ||
2191  pls->seek_stream_index == pls->pkt->stream_index) {
2192 
2193  if (pls->pkt->dts == AV_NOPTS_VALUE) {
2195  break;
2196  }
2197 
2198  tb = get_timebase(pls);
2199  ts_diff = av_rescale_rnd(pls->pkt->dts, AV_TIME_BASE,
2200  tb.den, AV_ROUND_DOWN) -
2201  pls->seek_timestamp;
2202  if (ts_diff >= 0 && (pls->seek_flags & AVSEEK_FLAG_ANY ||
2203  pls->pkt->flags & AV_PKT_FLAG_KEY)) {
2205  break;
2206  }
2207  }
2208  av_packet_unref(pls->pkt);
2209  }
2210  }
2211  /* Check if this stream has the packet with the lowest dts */
2212  if (pls->pkt->data) {
2213  struct playlist *minpls = minplaylist < 0 ?
2214  NULL : c->playlists[minplaylist];
2215  if (minplaylist < 0) {
2216  minplaylist = i;
2217  } else {
2218  int64_t dts = pls->pkt->dts;
2219  int64_t mindts = minpls->pkt->dts;
2220 
2221  if (dts == AV_NOPTS_VALUE ||
2222  (mindts != AV_NOPTS_VALUE && compare_ts_with_wrapdetect(dts, pls, mindts, minpls) < 0))
2223  minplaylist = i;
2224  }
2225  }
2226  }
2227 
2228  /* If we got a packet, return it */
2229  if (minplaylist >= 0) {
2230  struct playlist *pls = c->playlists[minplaylist];
2231  AVStream *ist;
2232  AVStream *st;
2233 
2235  if (ret < 0) {
2236  av_packet_unref(pls->pkt);
2237  return ret;
2238  }
2239 
2240  // If sub-demuxer reports updated metadata, copy it to the first stream
2241  // and set its AVSTREAM_EVENT_FLAG_METADATA_UPDATED flag.
2243  if (pls->n_main_streams) {
2244  st = pls->main_streams[0];
2245  av_dict_copy(&st->metadata, pls->ctx->metadata, 0);
2247  }
2249  }
2250 
2251  /* check if noheader flag has been cleared by the subdemuxer */
2252  if (pls->has_noheader_flag && !(pls->ctx->ctx_flags & AVFMTCTX_NOHEADER)) {
2253  pls->has_noheader_flag = 0;
2255  }
2256 
2257  if (pls->pkt->stream_index >= pls->n_main_streams) {
2258  av_log(s, AV_LOG_ERROR, "stream index inconsistency: index %d, %d main streams, %d subdemuxer streams\n",
2259  pls->pkt->stream_index, pls->n_main_streams, pls->ctx->nb_streams);
2260  av_packet_unref(pls->pkt);
2261  return AVERROR_BUG;
2262  }
2263 
2264  ist = pls->ctx->streams[pls->pkt->stream_index];
2265  st = pls->main_streams[pls->pkt->stream_index];
2266 
2267  av_packet_move_ref(pkt, pls->pkt);
2268  pkt->stream_index = st->index;
2269 
2270  if (pkt->dts != AV_NOPTS_VALUE)
2271  c->cur_timestamp = av_rescale_q(pkt->dts,
2272  ist->time_base,
2273  AV_TIME_BASE_Q);
2274 
2275  /* There may be more situations where this would be useful, but this at least
2276  * handles newly probed codecs properly (i.e. request_probe by mpegts). */
2277  if (ist->codecpar->codec_id != st->codecpar->codec_id) {
2279  if (ret < 0) {
2280  return ret;
2281  }
2282  }
2283 
2284  return 0;
2285  }
2286  return AVERROR_EOF;
2287 }
2288 
2289 static int hls_read_seek(AVFormatContext *s, int stream_index,
2290  int64_t timestamp, int flags)
2291 {
2292  HLSContext *c = s->priv_data;
2293  struct playlist *seek_pls = NULL;
2294  int i, j;
2295  int stream_subdemuxer_index;
2296  int64_t first_timestamp, seek_timestamp, duration;
2297  int64_t seq_no;
2298 
2299  if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags & AVFMTCTX_UNSEEKABLE))
2300  return AVERROR(ENOSYS);
2301 
2302  first_timestamp = c->first_timestamp == AV_NOPTS_VALUE ?
2303  0 : c->first_timestamp;
2304 
2306  s->streams[stream_index]->time_base.den,
2309 
2310  duration = s->duration == AV_NOPTS_VALUE ?
2311  0 : s->duration;
2312 
2313  if (0 < duration && duration < seek_timestamp - first_timestamp)
2314  return AVERROR(EIO);
2315 
2316  /* find the playlist with the specified stream */
2317  for (i = 0; i < c->n_playlists; i++) {
2318  struct playlist *pls = c->playlists[i];
2319  for (j = 0; j < pls->n_main_streams; j++) {
2320  if (pls->main_streams[j] == s->streams[stream_index]) {
2321  seek_pls = pls;
2322  stream_subdemuxer_index = j;
2323  break;
2324  }
2325  }
2326  }
2327  /* check if the timestamp is valid for the playlist with the
2328  * specified stream index */
2329  if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no))
2330  return AVERROR(EIO);
2331 
2332  /* set segment now so we do not need to search again below */
2333  seek_pls->cur_seq_no = seq_no;
2334  seek_pls->seek_stream_index = stream_subdemuxer_index;
2335 
2336  for (i = 0; i < c->n_playlists; i++) {
2337  /* Reset reading */
2338  struct playlist *pls = c->playlists[i];
2339  AVIOContext *const pb = &pls->pb.pub;
2340  ff_format_io_close(pls->parent, &pls->input);
2341  pls->input_read_done = 0;
2342  ff_format_io_close(pls->parent, &pls->input_next);
2343  pls->input_next_requested = 0;
2344  av_packet_unref(pls->pkt);
2345  pb->eof_reached = 0;
2346  /* Clear any buffered data */
2347  pb->buf_end = pb->buf_ptr = pb->buffer;
2348  /* Reset the pos, to let the mpegts demuxer know we've seeked. */
2349  pb->pos = 0;
2350  /* Flush the packet queue of the subdemuxer. */
2351  ff_read_frame_flush(pls->ctx);
2352 
2354  pls->seek_flags = flags;
2355 
2356  if (pls != seek_pls) {
2357  /* set closest segment seq_no for playlists not handled above */
2359  /* seek the playlist to the given position without taking
2360  * keyframes into account since this playlist does not have the
2361  * specified stream where we should look for the keyframes */
2362  pls->seek_stream_index = -1;
2363  pls->seek_flags |= AVSEEK_FLAG_ANY;
2364  }
2365  }
2366 
2367  c->cur_timestamp = seek_timestamp;
2368 
2369  return 0;
2370 }
2371 
2372 static int hls_probe(const AVProbeData *p)
2373 {
2374  /* Require #EXTM3U at the start, and either one of the ones below
2375  * somewhere for a proper match. */
2376  if (strncmp(p->buf, "#EXTM3U", 7))
2377  return 0;
2378 
2379  if (strstr(p->buf, "#EXT-X-STREAM-INF:") ||
2380  strstr(p->buf, "#EXT-X-TARGETDURATION:") ||
2381  strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:"))
2382  return AVPROBE_SCORE_MAX;
2383  return 0;
2384 }
2385 
2386 #define OFFSET(x) offsetof(HLSContext, x)
2387 #define FLAGS AV_OPT_FLAG_DECODING_PARAM
2388 static const AVOption hls_options[] = {
2389  {"live_start_index", "segment index to start live streams at (negative values are from the end)",
2390  OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS},
2391  {"allowed_extensions", "List of file extensions that hls is allowed to access",
2392  OFFSET(allowed_extensions), AV_OPT_TYPE_STRING,
2393  {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"},
2394  INT_MIN, INT_MAX, FLAGS},
2395  {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded",
2396  OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS},
2397  {"m3u8_hold_counters", "The maximum number of times to load m3u8 when it refreshes without new segments",
2398  OFFSET(m3u8_hold_counters), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS},
2399  {"http_persistent", "Use persistent HTTP connections",
2400  OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS },
2401  {"http_multiple", "Use multiple HTTP connections for fetching segments",
2402  OFFSET(http_multiple), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, FLAGS},
2403  {"http_seekable", "Use HTTP partial requests, 0 = disable, 1 = enable, -1 = auto",
2404  OFFSET(http_seekable), AV_OPT_TYPE_BOOL, { .i64 = -1}, -1, 1, FLAGS},
2405  {"seg_format_options", "Set options for segment demuxer",
2406  OFFSET(seg_format_opts), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, FLAGS},
2407  {NULL}
2408 };
2409 
2410 static const AVClass hls_class = {
2411  .class_name = "hls demuxer",
2412  .item_name = av_default_item_name,
2413  .option = hls_options,
2414  .version = LIBAVUTIL_VERSION_INT,
2415 };
2416 
2418  .name = "hls",
2419  .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
2420  .priv_class = &hls_class,
2421  .priv_data_size = sizeof(HLSContext),
2423  .flags_internal = FF_FMT_INIT_CLEANUP,
2424  .read_probe = hls_probe,
2427  .read_close = hls_close,
2429 };
MPEG_TIME_BASE_Q
#define MPEG_TIME_BASE_Q
Definition: hls.c:48
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:798
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:417
playlist::start_seq_no
int64_t start_seq_no
Definition: hls.c:115
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
MAX_CHARACTERISTICS_LEN
#define MAX_CHARACTERISTICS_LEN
Definition: hls.c:45
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
FF_FMT_INIT_CLEANUP
#define FF_FMT_INIT_CLEANUP
For an AVInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition: internal.h:48
playlist::input
AVIOContext * input
Definition: hls.c:97
playlist::seek_stream_index
int seek_stream_index
Definition: hls.c:150
free_segment_dynarray
static void free_segment_dynarray(struct segment **segments, int n_segments)
Definition: hls.c:219
r
const char * r
Definition: vf_curves.c:116
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
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:724
playlist::target_duration
int64_t target_duration
Definition: hls.c:114
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
playlist::n_renditions
int n_renditions
Definition: hls.c:156
HLSContext::avio_opts
AVDictionary * avio_opts
Definition: hls.c:209
HLSContext::n_variants
int n_variants
Definition: hls.c:195
ID3v2ExtraMeta::next
struct ID3v2ExtraMeta * next
Definition: id3v2.h:86
FF_COMPLIANCE_EXPERIMENTAL
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition: avcodec.h:1281
HLSContext::http_seekable
int http_seekable
Definition: hls.c:215
playlist
Definition: hls.c:93
KEY_AES_128
@ KEY_AES_128
Definition: hls.c:64
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:100
AVStream::discard
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:894
segment::url_offset
int64_t url_offset
Definition: hls.c:70
variant_info::subtitles
char subtitles[MAX_FIELD_LEN]
Definition: hls.c:328
playlist::id3_mpegts_timestamp
int64_t id3_mpegts_timestamp
Definition: hls.c:139
new_init_section
static struct segment * new_init_section(struct playlist *pls, struct init_section_info *info, const char *url_base)
Definition: hls.c:401
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
PLS_TYPE_VOD
@ PLS_TYPE_VOD
Definition: hls.c:85
playlist::input_next
AVIOContext * input_next
Definition: hls.c:99
playlist::id3_offset
int64_t id3_offset
Definition: hls.c:140
AV_DISPOSITION_DEFAULT
#define AV_DISPOSITION_DEFAULT
Definition: avformat.h:792
id3v2.h
playlist::seek_timestamp
int64_t seek_timestamp
Definition: hls.c:148
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
rendition_info::assoc_language
char assoc_language[MAX_FIELD_LEN]
Definition: hls.c:462
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:128
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1165
AVPacketSideData
Definition: packet.h:314
parse_id3
static void parse_id3(AVFormatContext *s, AVIOContext *pb, AVDictionary **metadata, int64_t *dts, ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta)
Definition: hls.c:1037
AVPacket::data
uint8_t * data
Definition: packet.h:373
segment::size
int64_t size
Definition: hls.c:71
variant::subtitles_group
char subtitles_group[MAX_FIELD_LEN]
Definition: hls.c:189
AVOption
AVOption.
Definition: opt.h:247
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:2144
AVFMT_FLAG_CUSTOM_IO
#define AVFMT_FLAG_CUSTOM_IO
The caller has supplied a custom AVIOContext, don't avio_close() it.
Definition: avformat.h:1223
playlist::finished
int finished
Definition: hls.c:112
AVSEEK_FLAG_BYTE
#define AVSEEK_FLAG_BYTE
seeking based on position in bytes
Definition: avformat.h:2152
AV_DICT_IGNORE_SUFFIX
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition: dict.h:68
playlist::segments
struct segment ** segments
Definition: hls.c:117
rendition_info::type
char type[16]
Definition: hls.c:458
nested_io_open
static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **opts)
Definition: hls.c:1734
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
base
uint8_t base
Definition: vp3data.h:141
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:391
mathematics.h
AVDictionary
Definition: dict.c:30
segment::key
char * key
Definition: hls.c:73
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:1252
av_read_frame
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
Return the next frame of a stream.
Definition: demux.c:1414
rendition::type
enum AVMediaType type
Definition: hls.c:172
rendition_info::uri
char uri[MAX_URL_SIZE]
Definition: hls.c:459
OFFSET
#define OFFSET(x)
Definition: hls.c:2386
avio_size
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:338
FFIOContext
Definition: avio_internal.h:29
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:425
playlist::key_url
char key_url[MAX_URL_SIZE]
Definition: hls.c:133
av_packet_free
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:75
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:433
HLSContext::first_packet
int first_packet
Definition: hls.c:205
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AVIOInterruptCB
Callback for checking whether to abort blocking functions.
Definition: avio.h:58
avformat_queue_attached_pictures
int avformat_queue_attached_pictures(AVFormatContext *s)
Definition: utils.c:226
hls_close
static int hls_close(AVFormatContext *s)
Definition: hls.c:1849
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:458
avformat_close_input
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition: demux.c:355
AVPacketSideData::size
size_t size
Definition: packet.h:316
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1364
HLSContext::http_multiple
int http_multiple
Definition: hls.c:214
key_info::iv
char iv[35]
Definition: hls.c:378
variant::audio_group
char audio_group[MAX_FIELD_LEN]
Definition: hls.c:187
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:426
recheck_discard_flags
static int recheck_discard_flags(AVFormatContext *s, int first)
Definition: hls.c:2071
hls_class
static const AVClass hls_class
Definition: hls.c:2410
segment::duration
int64_t duration
Definition: hls.c:69
fail
#define fail()
Definition: checkasm.h:127
AVSEEK_FLAG_ANY
#define AVSEEK_FLAG_ANY
seek to any frame, even non-keyframes
Definition: avformat.h:2153
new_variant
static struct variant * new_variant(HLSContext *c, struct variant_info *info, const char *url, const char *base)
Definition: hls.c:331
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:149
playlist::input_read_done
int input_read_done
Definition: hls.c:98
HLSContext::n_renditions
int n_renditions
Definition: hls.c:199
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:141
variant
Definition: hls.c:180
AV_DISPOSITION_FORCED
#define AV_DISPOSITION_FORCED
Track should be used during playback by default.
Definition: avformat.h:804
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:439
AV_ROUND_UP
@ AV_ROUND_UP
Round toward +infinity.
Definition: mathematics.h:83
ist
fg inputs[0] ist
Definition: ffmpeg_filter.c:182
av_new_program
AVProgram * av_new_program(AVFormatContext *s, int id)
Definition: utils.c:804
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:658
ID3v2ExtraMeta::apic
ID3v2ExtraMetaAPIC apic
Definition: id3v2.h:88
ff_data_to_hex
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Definition: utils.c:1098
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:553
AVFormatContext::event_flags
int event_flags
Flags indicating events happening on the file, a combination of AVFMT_EVENT_FLAG_*.
Definition: avformat.h:1407
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:921
playlist::cur_seq_no
int64_t cur_seq_no
Definition: hls.c:120
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:72
playlist::type
enum PlaylistType type
Definition: hls.c:113
open_url
static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, AVDictionary **opts, AVDictionary *opts2, int *is_http_out)
Definition: hls.c:625
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:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
playlist::n_init_sections
int n_init_sections
Definition: hls.c:161
AVFormatContext::metadata
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1326
AVInputFormat
Definition: avformat.h:626
MPEG_TIME_BASE
#define MPEG_TIME_BASE
Definition: hls.c:47
ID3v2ExtraMeta
Definition: id3v2.h:84
AVFormatContext::ctx_flags
int ctx_flags
Flags signalling stream properties.
Definition: avformat.h:1146
duration
int64_t duration
Definition: movenc.c:64
free_rendition_list
static void free_rendition_list(HLSContext *c)
Definition: hls.c:288
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:207
hls_options
static const AVOption hls_options[]
Definition: hls.c:2388
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:40
variant_info
Definition: hls.c:323
fill_timing_for_id3_timestamped_stream
static void fill_timing_for_id3_timestamped_stream(struct playlist *pls)
Definition: hls.c:2111
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:502
playlist_needed
static int playlist_needed(struct playlist *pls)
Definition: hls.c:1385
intreadwrite.h
key_info::uri
char uri[MAX_URL_SIZE]
Definition: hls.c:376
s
#define s(width, name)
Definition: cbs_vp9.c:257
segment::key_type
enum KeyType key_type
Definition: hls.c:74
KEY_SAMPLE_AES
@ KEY_SAMPLE_AES
Definition: hls.c:65
playlist::n_main_streams
int n_main_streams
Definition: hls.c:110
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1215
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:631
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:448
AVDictionaryEntry::key
char * key
Definition: dict.h:80
playlist::init_sec_buf_read_offset
unsigned int init_sec_buf_read_offset
Definition: hls.c:131
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
HLSContext::cur_timestamp
int64_t cur_timestamp
Definition: hls.c:207
info
MIPS optimizations info
Definition: mips.txt:2
variant_info::video
char video[MAX_FIELD_LEN]
Definition: hls.c:327
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:186
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:38
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
AVPacketSideData::data
uint8_t * data
Definition: packet.h:315
KEY_NONE
@ KEY_NONE
Definition: hls.c:63
HLSContext::n_playlists
int n_playlists
Definition: hls.c:197
variant_info::audio
char audio[MAX_FIELD_LEN]
Definition: hls.c:326
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:141
playlist::init_sections
struct segment ** init_sections
Definition: hls.c:162
ID3v2ExtraMetaAPIC::buf
AVBufferRef * buf
Definition: id3v2.h:66
playlist::init_sec_buf
uint8_t * init_sec_buf
Definition: hls.c:128
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:1591
ID3v2ExtraMeta::data
union ID3v2ExtraMeta::@255 data
HLSContext::allowed_extensions
char * allowed_extensions
Definition: hls.c:211
playlist::id3_buf
uint8_t * id3_buf
Definition: hls.c:141
FLAGS
#define FLAGS
Definition: hls.c:2387
playlist::read_buffer
uint8_t * read_buffer
Definition: hls.c:96
key
const char * key
Definition: hwcontext_opencl.c:168
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:142
HLSContext::seg_format_opts
AVDictionary * seg_format_opts
Definition: hls.c:210
hls_read_header
static int hls_read_header(AVFormatContext *s)
Definition: hls.c:1863
init_section_info
Definition: hls.c:396
ff_hex_to_data
int ff_hex_to_data(uint8_t *data, const char *p)
Parse a string of hexadecimal strings.
Definition: utils.c:1118
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:1260
handle_id3
static void handle_id3(AVIOContext *pb, struct playlist *pls)
Definition: hls.c:1092
free_variant_list
static void free_variant_list(HLSContext *c)
Definition: hls.c:276
ID3v2ExtraMeta::tag
const char * tag
Definition: id3v2.h:85
rendition::group_id
char group_id[MAX_FIELD_LEN]
Definition: hls.c:174
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:54
AVFormatContext
Format I/O context.
Definition: avformat.h:1097
internal.h
HLSContext::interrupt_callback
AVIOInterruptCB * interrupt_callback
Definition: hls.c:208
opts
AVDictionary * opts
Definition: movenc.c:50
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:992
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:2151
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:527
current_segment
static struct segment * current_segment(struct playlist *pls)
Definition: hls.c:1007
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
variant::n_playlists
int n_playlists
Definition: hls.c:184
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:868
NULL
#define NULL
Definition: coverity.c:32
variant::playlists
struct playlist ** playlists
Definition: hls.c:185
ensure_playlist
static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url)
Definition: hls.c:597
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
read_probe
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
AVFMTCTX_NOHEADER
#define AVFMTCTX_NOHEADER
signal that no header is present (streams are added dynamically)
Definition: avformat.h:1048
ID3v2ExtraMetaPRIV::data
uint8_t * data
Definition: id3v2.h:74
fill_buf
static void fill_buf(uint8_t *data, int w, int h, int linesize, uint8_t v)
Definition: vf_fieldmatch.c:186
playlist::renditions
struct rendition ** renditions
Definition: hls.c:157
HLSContext::playlist_pb
AVIOContext * playlist_pb
Definition: hls.c:216
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:1050
AVPacketSideData::type
enum AVPacketSideDataType type
Definition: packet.h:317
free_init_section_list
static void free_init_section_list(struct playlist *pls)
Definition: hls.c:236
HLSContext::variants
struct variant ** variants
Definition: hls.c:196
update_streams_from_subdemuxer
static int update_streams_from_subdemuxer(AVFormatContext *s, struct playlist *pls)
Definition: hls.c:1803
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Definition: opt.h:231
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
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:1157
HLSContext::max_reload
int max_reload
Definition: hls.c:212
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1139
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:393
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:446
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:903
rendition_info::defaultr
char defaultr[4]
Definition: hls.c:464
HLSContext::cur_seq_no
int64_t cur_seq_no
Definition: hls.c:202
playlist::broken
int broken
Definition: hls.c:119
time.h
KeyType
KeyType
Definition: hls.c:62
playlist::id3_deferred_extra
ID3v2ExtraMeta * id3_deferred_extra
Definition: hls.c:146
HLSContext::playlists
struct playlist ** playlists
Definition: hls.c:198
playlist::n_segments
int n_segments
Definition: hls.c:116
av_packet_move_ref
void av_packet_move_ref(AVPacket *dst, AVPacket *src)
Move every field in src to dst and reset src.
Definition: avpacket.c:474
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:445
MAX_FIELD_LEN
#define MAX_FIELD_LEN
Definition: hls.c:44
INITIAL_BUFFER_SIZE
#define INITIAL_BUFFER_SIZE
Definition: hls.c:42
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:965
id3_has_changed_values
static int id3_has_changed_values(struct playlist *pls, AVDictionary *metadata, ID3v2ExtraMetaAPIC *apic)
Definition: hls.c:1063
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
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1153
av_strncasecmp
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
Definition: avstring.c:225
playlist::init_sec_buf_size
unsigned int init_sec_buf_size
Definition: hls.c:129
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:57
options
const OptionDef options[]
avformat_find_stream_info
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
Read packets of a media file to get stream information.
Definition: demux.c:2396
find_timestamp_in_playlist
static int find_timestamp_in_playlist(HLSContext *c, struct playlist *pls, int64_t timestamp, int64_t *seq_no)
Definition: hls.c:1647
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
rendition_info::forced
char forced[4]
Definition: hls.c:465
AVMediaType
AVMediaType
Definition: avutil.h:199
AVPacket::size
int size
Definition: packet.h:374
playlist::cur_init_section
struct segment * cur_init_section
Definition: hls.c:127
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:117
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:154
new_rendition
static struct rendition * new_rendition(HLSContext *c, struct rendition_info *info, const char *url_base)
Definition: hls.c:469
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:121
HLSContext::first_timestamp
int64_t first_timestamp
Definition: hls.c:206
FFIOContext::pub
AVIOContext pub
Definition: avio_internal.h:30
ff_copy_whiteblacklists
int ff_copy_whiteblacklists(AVFormatContext *dst, const AVFormatContext *src)
Copies the whilelists from one context to the other.
Definition: utils.c:114
playlist::cur_seg_offset
int64_t cur_seg_offset
Definition: hls.c:123
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:958
save_avio_options
static int save_avio_options(AVFormatContext *s)
Definition: hls.c:1712
rendition_info::characteristics
char characteristics[MAX_CHARACTERISTICS_LEN]
Definition: hls.c:466
AV_OPT_ALLOW_NULL
#define AV_OPT_ALLOW_NULL
In av_opt_get, return NULL if the option has a pointer type and is set to NULL, rather than returning...
Definition: opt.h:573
PLS_TYPE_EVENT
@ PLS_TYPE_EVENT
Definition: hls.c:84
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:2136
AV_OPT_SEARCH_CHILDREN
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
Definition: opt.h:559
AV_DISPOSITION_HEARING_IMPAIRED
#define AV_DISPOSITION_HEARING_IMPAIRED
stream for hearing impaired audiences
Definition: avformat.h:805
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:372
update_init_section
static int update_init_section(struct playlist *pls, struct segment *seg)
Definition: hls.c:1321
line
Definition: graph2dot.c:48
playlist::id3_found
int id3_found
Definition: hls.c:144
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:379
av_packet_alloc
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.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:203
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:34
playlist::seek_flags
int seek_flags
Definition: hls.c:149
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:313
read_data
static int read_data(void *opaque, uint8_t *buf, int buf_size)
Definition: hls.c:1431
ID3v2ExtraMetaAPIC
Definition: id3v2.h:65
rendition::playlist
struct playlist * playlist
Definition: hls.c:173
AVBufferRef::size
size_t size
Size of data in bytes.
Definition: buffer.h:94
playlist::ctx
AVFormatContext * ctx
Definition: hls.c:103
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
free_segment_list
static void free_segment_list(struct playlist *pls)
Definition: hls.c:229
init_section_info::uri
char uri[MAX_URL_SIZE]
Definition: hls.c:397
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:72
playlist::pb
FFIOContext pb
Definition: hls.c:95
add_metadata_from_renditions
static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pls, enum AVMediaType type)
Definition: hls.c:1615
key_info::method
char method[11]
Definition: hls.c:377
next_segment
static struct segment * next_segment(struct playlist *pls)
Definition: hls.c:1012
PLS_TYPE_UNSPECIFIED
@ PLS_TYPE_UNSPECIFIED
Definition: hls.c:83
i
int i
Definition: input.c:406
URLContext
Definition: url.h:38
playlist::key
uint8_t key[16]
Definition: hls.c:134
update_noheader_flag
static void update_noheader_flag(AVFormatContext *s)
Definition: hls.c:1828
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:366
avio_internal.h
playlist::needed
int needed
Definition: hls.c:118
rendition::name
char name[MAX_FIELD_LEN]
Definition: hls.c:176
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
rendition
Definition: hls.c:171
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, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Definition: aviobuf.c:80
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:1129
select_cur_seq_no
static int64_t select_cur_seq_no(HLSContext *c, struct playlist *pls)
Definition: hls.c:1673
HLSContext::m3u8_hold_counters
int m3u8_hold_counters
Definition: hls.c:203
variant::video_group
char video_group[MAX_FIELD_LEN]
Definition: hls.c:188
AV_ROUND_DOWN
@ AV_ROUND_DOWN
Round toward -infinity.
Definition: mathematics.h:82
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
HLSContext
Definition: hls.c:192
default_reload_interval
static int64_t default_reload_interval(struct playlist *pls)
Definition: hls.c:1378
tb
#define tb
Definition: regdef.h:68
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:261
AVProgram
New fields can be added to the end with minor version bumps.
Definition: avformat.h:1021
len
int len
Definition: vorbis_enc_data.h:426
HLSContext::ctx
AVFormatContext * ctx
Definition: hls.c:194
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:607
free_playlist_list
static void free_playlist_list(HLSContext *c)
Definition: hls.c:247
PlaylistType
PlaylistType
Definition: hls.c:82
rendition_info::language
char language[MAX_FIELD_LEN]
Definition: hls.c:461
playlist::parent
AVFormatContext * parent
Definition: hls.c:101
AVStream::disposition
int disposition
AV_DISPOSITION_* bit field.
Definition: avformat.h:892
AV_DISPOSITION_VISUAL_IMPAIRED
#define AV_DISPOSITION_VISUAL_IMPAIRED
stream for visual impaired audiences
Definition: avformat.h:806
HLSContext::http_persistent
int http_persistent
Definition: hls.c:213
ff_id3v2_tag_len
int ff_id3v2_tag_len(const uint8_t *buf)
Get the length of an ID3v2 tag.
Definition: id3v2.c:156
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:159
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:852
ret
ret
Definition: filter_design.txt:187
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
AVStream
Stream structure.
Definition: avformat.h:845
playlist::index
int index
Definition: hls.c:102
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
pos
unsigned int pos
Definition: spdifenc.c:412
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:122
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:67
open_input
static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg, AVIOContext **in)
Definition: hls.c:1234
hls_read_seek
static int hls_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: hls.c:2289
new_playlist
static struct playlist * new_playlist(HLSContext *c, const char *url, const char *base)
Definition: hls.c:297
HLSContext::live_start_index
int live_start_index
Definition: hls.c:204
set_stream_info_from_input_stream
static int set_stream_info_from_input_stream(AVStream *st, struct playlist *pls, AVStream *ist)
Definition: hls.c:1770
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:846
playlist::main_streams
AVStream ** main_streams
Definition: hls.c:109
MAX_URL_SIZE
#define MAX_URL_SIZE
Definition: internal.h:32
playlist::id3_initial
AVDictionary * id3_initial
Definition: hls.c:143
parse_playlist
static int parse_playlist(HLSContext *c, const char *url, struct playlist *pls, AVIOContext *in)
Definition: hls.c:712
rendition_info
Definition: hls.c:457
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
init_section_info::byterange
char byterange[32]
Definition: hls.c:398
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:679
AVFMT_NOGENSEARCH
#define AVFMT_NOGENSEARCH
Format does not allow to fall back on generic search.
Definition: avformat.h:474
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:625
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:596
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:1656
AVIOContext::eof_reached
int eof_reached
true if was unable to read due to error or eof
Definition: avio.h:239
playlist::last_seq_no
int64_t last_seq_no
Definition: hls.c:121
variant::bandwidth
int bandwidth
Definition: hls.c:181
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: utils.c:1146
AVPacket::stream_index
int stream_index
Definition: packet.h:375
segment
Definition: hls.c:68
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:147
ff_format_io_close
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:1798
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:603
add_stream_to_programs
static void add_stream_to_programs(AVFormatContext *s, struct playlist *pls, AVStream *stream)
Definition: hls.c:1744
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:277
hls_probe
static int hls_probe(const AVProbeData *p)
Definition: hls.c:2372
rendition_info::name
char name[MAX_FIELD_LEN]
Definition: hls.c:463
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
playlist::is_id3_timestamped
int is_id3_timestamped
Definition: hls.c:138
AVFMT_TS_DISCONT
#define AVFMT_TS_DISCONT
Format allows timestamp discontinuities.
Definition: avformat.h:469
playlist::init_sec_data_len
unsigned int init_sec_data_len
Definition: hls.c:130
hls_read_packet
static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: hls.c:2153
AVIOContext::buffer
unsigned char * buffer
Start of the buffer.
Definition: avio.h:226
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:357
diff
static av_always_inline int diff(const uint32_t a, const uint32_t b)
Definition: vf_palettegen.c:136
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:79
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:319
variant_info::bandwidth
char bandwidth[20]
Definition: hls.c:324
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
AVPacket
This structure stores compressed data.
Definition: packet.h:350
ff_read_frame_flush
void ff_read_frame_flush(AVFormatContext *s)
Flush the frame reader.
Definition: seek.c:714
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:241
segment::url
char * url
Definition: hls.c:72
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:70
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:558
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:217
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:1141
segment::init_section
struct segment * init_section
Definition: hls.c:77
av_stream_new_side_data
uint8_t * av_stream_new_side_data(AVStream *stream, enum AVPacketSideDataType type, size_t size)
Allocate new information from stream.
Definition: utils.c:1721
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:467
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:232
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
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:83
av_opt_get
int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val)
Definition: opt.c:779
playlist::last_load_time
int64_t last_load_time
Definition: hls.c:124
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:1253
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
rendition::disposition
int disposition
Definition: hls.c:177
playlist::url
char url[MAX_URL_SIZE]
Definition: hls.c:94
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:145
AVDictionaryEntry::value
char * value
Definition: dict.h:81
segment::iv
uint8_t iv[16]
Definition: hls.c:75
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:228
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:381
http.h
read_from_url
static int read_from_url(struct playlist *pls, struct segment *seg, uint8_t *buf, int buf_size)
Definition: hls.c:1020
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:1213
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:1125
intercept_id3
static void intercept_id3(struct playlist *pls, uint8_t *buf, int buf_size, int *len)
Definition: hls.c:1134
rendition::language
char language[MAX_FIELD_LEN]
Definition: hls.c:175
ID3v2ExtraMetaPRIV
Definition: id3v2.h:72
ffio_geturlcontext
URLContext * ffio_geturlcontext(AVIOContext *s)
Return the URLContext associated with the AVIOContext.
Definition: aviobuf.c:971
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:200
AVFMT_EVENT_FLAG_METADATA_UPDATED
#define AVFMT_EVENT_FLAG_METADATA_UPDATED
Definition: avformat.h:1414
rendition_info::group_id
char group_id[MAX_FIELD_LEN]
Definition: hls.c:460
ff_id3v2_match
int ff_id3v2_match(const uint8_t *buf, const char *magic)
Detect ID3v2 Header.
Definition: id3v2.c:143
key_info
Definition: hls.c:375
ff_hls_demuxer
const AVInputFormat ff_hls_demuxer
Definition: hls.c:2417
playlist::pkt
AVPacket * pkt
Definition: hls.c:104
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:1172
playlist::has_noheader_flag
int has_noheader_flag
Definition: hls.c:105
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:360
av_program_add_stream_index
void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx)
ID3v2ExtraMeta::priv
ID3v2ExtraMetaPRIV priv
Definition: id3v2.h:91