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