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