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