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