FFmpeg
hlsenc.c
Go to the documentation of this file.
1 /*
2  * Apple HTTP Live Streaming segmenter
3  * Copyright (c) 2012, Luca Barbato
4  * Copyright (c) 2017 Akamai Technologies, Inc.
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "config.h"
24 #include "config_components.h"
25 #include <stdint.h>
26 #include <time.h>
27 #if HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
30 
31 #include "libavutil/avassert.h"
32 #include "libavutil/mathematics.h"
33 #include "libavutil/avstring.h"
34 #include "libavutil/bprint.h"
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/mem.h"
37 #include "libavutil/opt.h"
38 #include "libavutil/log.h"
39 #include "libavutil/random_seed.h"
40 #include "libavutil/time.h"
42 
43 #include "libavcodec/defs.h"
44 
45 #include "avformat.h"
46 #include "avio_internal.h"
47 #include "avc.h"
48 #if CONFIG_HTTP_PROTOCOL
49 #include "http.h"
50 #endif
51 #include "hlsplaylist.h"
52 #include "internal.h"
53 #include "nal.h"
54 #include "mux.h"
55 #include "os_support.h"
56 #include "url.h"
57 
58 typedef enum {
65 
66 typedef enum {
70 
71 #define KEYSIZE 16
72 #define LINE_BUFFER_SIZE MAX_URL_SIZE
73 #define HLS_MICROSECOND_UNIT 1000000
74 #define BUFSIZE (16 * 1024)
75 #define POSTFIX_PATTERN "_%d"
76 
77 typedef struct HLSSegment {
80  double duration; /* in seconds */
81  int discont;
86  unsigned var_stream_idx;
87 
89  char iv_string[KEYSIZE*2 + 1];
90 
91  struct HLSSegment *next;
93 } HLSSegment;
94 
95 typedef enum HLSFlags {
96  // Generate a single media file and use byte ranges in the playlist.
97  HLS_SINGLE_FILE = (1 << 0),
98  HLS_DELETE_SEGMENTS = (1 << 1),
99  HLS_ROUND_DURATIONS = (1 << 2),
100  HLS_DISCONT_START = (1 << 3),
101  HLS_OMIT_ENDLIST = (1 << 4),
102  HLS_SPLIT_BY_TIME = (1 << 5),
103  HLS_APPEND_LIST = (1 << 6),
105  HLS_SECOND_LEVEL_SEGMENT_INDEX = (1 << 8), // include segment index in segment filenames when use_localtime e.g.: %%03d
106  HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime e.g.: %%09t
107  HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s
108  HLS_TEMP_FILE = (1 << 11),
109  HLS_PERIODIC_REKEY = (1 << 12),
111  HLS_I_FRAMES_ONLY = (1 << 14),
112 } HLSFlags;
113 
114 typedef enum {
117 } SegmentType;
118 
119 typedef struct VariantStream {
120  unsigned var_stream_idx;
121  unsigned number;
129  uint8_t *temp_buffer;
130  uint8_t *init_buffer;
131 
134 
139  double dpp; // duration per packet
145  double duration; // last segment duration computed so far, in seconds
146  int64_t start_pos; // last segment starting position
147  int64_t size; // last segment size
152 
157 
161 
163  char *basename;
166  char *m3u8_name;
167 
169  char current_segment_final_filename_fmt[MAX_URL_SIZE]; // when renaming segments
170 
173 
175 
178  char key_string[KEYSIZE*2 + 1];
179  char iv_string[KEYSIZE*2 + 1];
180 
182  char codec_attr[128];
184  unsigned int nb_streams;
185  int m3u8_created; /* status of media play-list creation */
186  int is_default; /* default status of audio group */
187  const char *language; /* audio language name */
188  const char *agroup; /* audio group name */
189  const char *sgroup; /* subtitle group name */
190  const char *ccgroup; /* closed caption group name */
191  const char *varname; /* variant name */
192 } VariantStream;
193 
194 typedef struct ClosedCaptionsStream {
195  const char *ccgroup; /* closed caption group name */
196  const char *instreamid; /* closed captions INSTREAM-ID */
197  const char *language; /* closed captions language */
199 
200 typedef struct HLSContext {
201  const AVClass *class; // Class for private options.
203  uint32_t start_sequence_source_type; // enum StartSequenceSourceType
204 
205  int64_t time; // Set by a private option.
206  int64_t init_time; // Set by a private option.
207  int max_nb_segments; // Set by a private option.
208  int hls_delete_threshold; // Set by a private option.
209  uint32_t flags; // enum HLSFlags
210  uint32_t pl_type; // enum PlaylistType
214  int resend_init_file; ///< resend init file into disk after refresh m3u8
215 
216  int use_localtime; ///< flag to expand filename with localtime
217  int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename
220  int64_t max_seg_size; // every segment file max size
221 
222  char *baseurl;
226 
227  int encrypt;
228  char *key;
229  char *key_url;
230  char *iv;
233 
237  char key_string[KEYSIZE*2 + 1];
238  char iv_string[KEYSIZE*2 + 1];
240 
241  char *method;
242  char *user_agent;
243 
245  unsigned int nb_varstreams;
247  unsigned int nb_ccstreams;
248 
249  int master_m3u8_created; /* status of master play-list creation */
250  char *master_m3u8_url; /* URL of the master m3u8 file */
251  int version; /* HLS version */
252  char *var_stream_map; /* user specified variant stream map string */
253  char *cc_stream_map; /* user specified closed caption streams map string */
255  unsigned int master_publish_rate;
256  int http_persistent;
262  char *headers;
263  int has_default_key; /* has DEFAULT field of var_stream_map */
264  int has_video_m3u8; /* has video stream m3u8 list */
265 } HLSContext;
266 
267 static int strftime_expand(const char *fmt, char **dest)
268 {
269  int r = 1;
270  time_t now0;
271  struct tm *tm, tmpbuf;
272  char *buf;
273 
274  buf = av_mallocz(MAX_URL_SIZE);
275  if (!buf)
276  return AVERROR(ENOMEM);
277 
278  time(&now0);
279  tm = localtime_r(&now0, &tmpbuf);
280  r = strftime(buf, MAX_URL_SIZE, fmt, tm);
281  if (!r) {
282  av_free(buf);
283  return AVERROR(EINVAL);
284  }
285  *dest = buf;
286 
287  return r;
288 }
289 
290 static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, const char *filename,
292 {
293  HLSContext *hls = s->priv_data;
294  int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
295  int err = AVERROR_MUXER_NOT_FOUND;
296  if (!*pb || !http_base_proto || !hls->http_persistent) {
297  err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
298 #if CONFIG_HTTP_PROTOCOL
299  } else {
300  URLContext *http_url_context = ffio_geturlcontext(*pb);
301  av_assert0(http_url_context);
302  err = ff_http_do_new_request(http_url_context, filename);
303  if (err < 0)
304  ff_format_io_close(s, pb);
305 
306 #endif
307  }
308  return err;
309 }
310 
311 static int hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename)
312 {
313  HLSContext *hls = s->priv_data;
314  int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
315  int ret = 0;
316  if (!*pb)
317  return ret;
318  if (!http_base_proto || !hls->http_persistent || hls->key_info_file || hls->encrypt) {
319  ff_format_io_close(s, pb);
320 #if CONFIG_HTTP_PROTOCOL
321  } else {
322  URLContext *http_url_context = ffio_geturlcontext(*pb);
323  av_assert0(http_url_context);
324  avio_flush(*pb);
325  ret = ffurl_shutdown(http_url_context, AVIO_FLAG_WRITE);
326 #endif
327  }
328  return ret;
329 }
330 
332 {
333  int http_base_proto = ff_is_http_proto(s->url);
334 
335  if (c->method) {
336  av_dict_set(options, "method", c->method, 0);
337  } else if (http_base_proto) {
338  av_dict_set(options, "method", "PUT", 0);
339  }
340  if (c->user_agent)
341  av_dict_set(options, "user_agent", c->user_agent, 0);
342  if (c->http_persistent)
343  av_dict_set_int(options, "multiple_requests", 1, 0);
344  if (c->timeout >= 0)
345  av_dict_set_int(options, "timeout", c->timeout, 0);
346  if (c->headers)
347  av_dict_set(options, "headers", c->headers, 0);
348 }
349 
351 {
352  int codec_strlen = strlen(vs->codec_attr);
353  char attr[32];
354 
356  return;
358  return;
359 
360  if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
361  uint8_t *data = st->codecpar->extradata;
362  if (data) {
363  const uint8_t *p;
364 
365  if (AV_RB32(data) == 0x01 && (data[4] & 0x1F) == 7)
366  p = &data[5];
367  else if (AV_RB24(data) == 0x01 && (data[3] & 0x1F) == 7)
368  p = &data[4];
369  else if (data[0] == 0x01) /* avcC */
370  p = &data[1];
371  else
372  goto fail;
373  snprintf(attr, sizeof(attr),
374  "avc1.%02x%02x%02x", p[0], p[1], p[2]);
375  } else {
376  goto fail;
377  }
378  } else if (st->codecpar->codec_id == AV_CODEC_ID_HEVC) {
379  uint8_t *data = st->codecpar->extradata;
381  int level = AV_LEVEL_UNKNOWN;
382 
383  if (st->codecpar->profile != AV_PROFILE_UNKNOWN)
384  profile = st->codecpar->profile;
385  if (st->codecpar->level != AV_LEVEL_UNKNOWN)
386  level = st->codecpar->level;
387 
388  /* check the boundary of data which from current position is small than extradata_size */
389  while (data && (data - st->codecpar->extradata + 19) < st->codecpar->extradata_size) {
390  /* get HEVC SPS NAL and seek to profile_tier_level */
391  if (!(data[0] | data[1] | data[2]) && data[3] == 1 && ((data[4] & 0x7E) == 0x42)) {
392  uint8_t *rbsp_buf;
393  int remain_size = 0;
394  int rbsp_size = 0;
395  /* skip start code + nalu header */
396  data += 6;
397  /* process by reference General NAL unit syntax */
398  remain_size = st->codecpar->extradata_size - (data - st->codecpar->extradata);
399  rbsp_buf = ff_nal_unit_extract_rbsp(data, remain_size, &rbsp_size, 0);
400  if (!rbsp_buf)
401  return;
402  if (rbsp_size < 13) {
403  av_freep(&rbsp_buf);
404  break;
405  }
406  /* skip sps_video_parameter_set_id u(4),
407  * sps_max_sub_layers_minus1 u(3),
408  * and sps_temporal_id_nesting_flag u(1) */
409  profile = rbsp_buf[1] & 0x1f;
410  /* skip 8 + 8 + 32 + 4 + 43 + 1 bit */
411  level = rbsp_buf[12];
412  av_freep(&rbsp_buf);
413  break;
414  }
415  data++;
416  }
417  if (st->codecpar->codec_tag == MKTAG('h','v','c','1') &&
419  level != AV_LEVEL_UNKNOWN) {
420  snprintf(attr, sizeof(attr), "%s.%d.4.L%d.B01", av_fourcc2str(st->codecpar->codec_tag), profile, level);
421  } else
422  goto fail;
423  } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
424  snprintf(attr, sizeof(attr), "mp4a.40.33");
425  } else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) {
426  snprintf(attr, sizeof(attr), "mp4a.40.34");
427  } else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
428  if (st->codecpar->profile != AV_PROFILE_UNKNOWN)
429  snprintf(attr, sizeof(attr), "mp4a.40.%d", st->codecpar->profile+1);
430  else
431  // This is for backward compatibility with the previous implementation.
432  snprintf(attr, sizeof(attr), "mp4a.40.2");
433  } else if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
434  snprintf(attr, sizeof(attr), "ac-3");
435  } else if (st->codecpar->codec_id == AV_CODEC_ID_EAC3) {
436  snprintf(attr, sizeof(attr), "ec-3");
437  } else {
438  goto fail;
439  }
440  // Don't write the same attribute multiple times
441  if (!av_stristr(vs->codec_attr, attr)) {
442  snprintf(vs->codec_attr + codec_strlen,
443  sizeof(vs->codec_attr) - codec_strlen,
444  "%s%s", codec_strlen ? "," : "", attr);
445  }
446  return;
447 
448 fail:
449  vs->codec_attr[0] = '\0';
451  return;
452 }
453 
454 static int replace_str_data_in_filename(char **s, const char *filename, char placeholder, const char *datastring)
455 {
456  const char *p;
457  char c;
458  int addchar_count;
459  int found_count = 0;
460  AVBPrint buf;
461  int ret;
462 
464 
465  p = filename;
466  for (;;) {
467  c = *p;
468  if (c == '\0')
469  break;
470  if (c == '%' && *(p+1) == '%') // %%
471  addchar_count = 2;
472  else if (c == '%' && *(p+1) == placeholder) {
473  av_bprintf(&buf, "%s", datastring);
474  p += 2;
475  addchar_count = 0;
476  found_count ++;
477  } else
478  addchar_count = 1;
479 
480  if (addchar_count > 0) {
481  av_bprint_append_data(&buf, p, addchar_count);
482  p += addchar_count;
483  }
484  }
485  if (!av_bprint_is_complete(&buf)) {
486  av_bprint_finalize(&buf, NULL);
487  return AVERROR(ENOMEM);
488  }
489  if ((ret = av_bprint_finalize(&buf, s)) < 0)
490  return ret;
491  return found_count;
492 }
493 
494 static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number)
495 {
496  const char *p;
497  char c;
498  int nd, addchar_count;
499  int found_count = 0;
500  AVBPrint buf;
501  int ret;
502 
504 
505  p = filename;
506  for (;;) {
507  c = *p;
508  if (c == '\0')
509  break;
510  if (c == '%' && *(p+1) == '%') // %%
511  addchar_count = 2;
512  else if (c == '%' && (av_isdigit(*(p+1)) || *(p+1) == placeholder)) {
513  nd = 0;
514  addchar_count = 1;
515  while (av_isdigit(*(p + addchar_count))) {
516  nd = nd * 10 + *(p + addchar_count) - '0';
517  addchar_count++;
518  }
519 
520  if (*(p + addchar_count) == placeholder) {
521  av_bprintf(&buf, "%0*"PRId64, (number < 0) ? nd : nd++, number);
522  p += (addchar_count + 1);
523  addchar_count = 0;
524  found_count++;
525  }
526 
527  } else
528  addchar_count = 1;
529 
530  av_bprint_append_data(&buf, p, addchar_count);
531  p += addchar_count;
532  }
533  if (!av_bprint_is_complete(&buf)) {
534  av_bprint_finalize(&buf, NULL);
535  return AVERROR(ENOMEM);
536  }
537  if ((ret = av_bprint_finalize(&buf, s)) < 0)
538  return ret;
539  return found_count;
540 }
541 
542 static void write_styp(AVIOContext *pb)
543 {
544  avio_wb32(pb, 24);
545  ffio_wfourcc(pb, "styp");
546  ffio_wfourcc(pb, "msdh");
547  avio_wb32(pb, 0); /* minor */
548  ffio_wfourcc(pb, "msdh");
549  ffio_wfourcc(pb, "msix");
550 }
551 
552 static int flush_dynbuf(VariantStream *vs, int *range_length)
553 {
554  AVFormatContext *ctx = vs->avf;
555 
556  if (!ctx->pb) {
557  return AVERROR(EINVAL);
558  }
559 
560  // flush
562 
563  // write out to file
564  *range_length = avio_close_dyn_buf(ctx->pb, &vs->temp_buffer);
565  ctx->pb = NULL;
566  avio_write(vs->out, vs->temp_buffer, *range_length);
567  avio_flush(vs->out);
568 
569  // re-open buffer
570  return avio_open_dyn_buf(&ctx->pb);
571 }
572 
573 static void reflush_dynbuf(VariantStream *vs, int *range_length)
574 {
575  // re-open buffer
576  avio_write(vs->out, vs->temp_buffer, *range_length);
577 }
578 
580  char *path, const char *proto)
581 {
582  if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
583  AVDictionary *opt = NULL;
584  int ret;
585 
586  set_http_options(avf, &opt, hls);
587  av_dict_set(&opt, "method", "DELETE", 0);
588 
589  ret = hlsenc_io_open(avf, &hls->http_delete, path, &opt);
590  av_dict_free(&opt);
591  if (ret < 0)
592  return hls->ignore_io_errors ? 1 : ret;
593 
594  //Nothing to write
595  hlsenc_io_close(avf, &hls->http_delete, path);
596  } else if (unlink(path) < 0) {
597  av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
598  path, strerror(errno));
599  }
600  return 0;
601 }
602 
604  VariantStream *vs)
605 {
606 
607  HLSSegment *segment, *previous_segment = NULL;
608  float playlist_duration = 0.0f;
609  int ret = 0;
610  int segment_cnt = 0;
611  AVBPrint path;
612  const char *dirname = NULL;
613  char *dirname_r = NULL;
614  char *dirname_repl = NULL;
615  const char *vtt_dirname = NULL;
616  char *vtt_dirname_r = NULL;
617  const char *proto = NULL;
618 
620 
621  segment = vs->segments;
622  while (segment) {
623  playlist_duration += segment->duration;
624  segment = segment->next;
625  }
626 
627  segment = vs->old_segments;
628  segment_cnt = 0;
629  while (segment) {
630  playlist_duration -= segment->duration;
631  previous_segment = segment;
632  segment = previous_segment->next;
633  segment_cnt++;
634  if (playlist_duration <= -previous_segment->duration) {
635  previous_segment->next = NULL;
636  break;
637  }
638  if (segment_cnt >= hls->hls_delete_threshold) {
639  previous_segment->next = NULL;
640  break;
641  }
642  }
643 
644  if (segment && !hls->use_localtime_mkdir) {
645  dirname_r = hls->segment_filename ? av_strdup(hls->segment_filename): av_strdup(vs->avf->url);
646  dirname = av_dirname(dirname_r);
647  }
648 
649  /* if %v is present in the file's directory
650  * all segment belongs to the same variant, so do it only once before the loop*/
651  if (dirname && av_stristr(dirname, "%v")) {
652  if (!vs->varname) {
653  if (replace_int_data_in_filename(&dirname_repl, dirname, 'v', segment->var_stream_idx) < 1) {
654  ret = AVERROR(EINVAL);
655  goto fail;
656  }
657  } else {
658  if (replace_str_data_in_filename(&dirname_repl, dirname, 'v', vs->varname) < 1) {
659  ret = AVERROR(EINVAL);
660  goto fail;
661  }
662  }
663 
664  dirname = dirname_repl;
665  }
666 
667  while (segment) {
668  av_log(hls, AV_LOG_DEBUG, "deleting old segment %s\n",
669  segment->filename);
670  if (!hls->use_localtime_mkdir) // segment->filename contains basename only
671  av_bprintf(&path, "%s/", dirname);
672  av_bprintf(&path, "%s", segment->filename);
673 
674  if (!av_bprint_is_complete(&path)) {
675  ret = AVERROR(ENOMEM);
676  goto fail;
677  }
678 
679  proto = avio_find_protocol_name(s->url);
680  if (ret = hls_delete_file(hls, s, path.str, proto))
681  goto fail;
682 
683  if ((segment->sub_filename[0] != '\0')) {
684  vtt_dirname_r = av_strdup(vs->vtt_avf->url);
685  vtt_dirname = av_dirname(vtt_dirname_r);
686 
687  av_bprint_clear(&path);
688  av_bprintf(&path, "%s/%s", vtt_dirname, segment->sub_filename);
689  av_freep(&vtt_dirname_r);
690 
691  if (!av_bprint_is_complete(&path)) {
692  ret = AVERROR(ENOMEM);
693  goto fail;
694  }
695 
696  if (ret = hls_delete_file(hls, s, path.str, proto))
697  goto fail;
698  }
699  av_bprint_clear(&path);
700  previous_segment = segment;
701  segment = previous_segment->next;
702  av_freep(&previous_segment);
703  }
704 
705 fail:
706  av_bprint_finalize(&path, NULL);
707  av_freep(&dirname_r);
708  av_freep(&dirname_repl);
709 
710  return ret;
711 }
712 
714 {
715  HLSContext *hls = s->priv_data;
716  int ret;
717  int len;
718  AVIOContext *pb;
719  uint8_t key[KEYSIZE];
720  char * key_basename_source = (hls->master_m3u8_url) ? hls->master_m3u8_url : s->url;
721 
722  len = strlen(key_basename_source) + 4 + 1;
723  hls->key_basename = av_mallocz(len);
724  if (!hls->key_basename)
725  return AVERROR(ENOMEM);
726 
727  av_strlcpy(hls->key_basename, key_basename_source, len);
728  av_strlcat(hls->key_basename, ".key", len);
729 
730  if (hls->key_url) {
731  av_strlcpy(hls->key_file, hls->key_url, sizeof(hls->key_file));
732  av_strlcpy(hls->key_uri, hls->key_url, sizeof(hls->key_uri));
733  } else {
734  av_strlcpy(hls->key_file, hls->key_basename, sizeof(hls->key_file));
735  av_strlcpy(hls->key_uri, hls->key_basename, sizeof(hls->key_uri));
736  }
737 
738  if (!*hls->iv_string) {
739  uint8_t iv[16] = { 0 };
740  char buf[33];
741 
742  if (!hls->iv) {
743  AV_WB64(iv + 8, vs->sequence);
744  } else {
745  memcpy(iv, hls->iv, sizeof(iv));
746  }
747  ff_data_to_hex(buf, iv, sizeof(iv), 0);
748  memcpy(hls->iv_string, buf, sizeof(hls->iv_string));
749  }
750 
751  if (!*hls->key_uri) {
752  av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
753  return AVERROR(EINVAL);
754  }
755 
756  if (!*hls->key_file) {
757  av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
758  return AVERROR(EINVAL);
759  }
760 
761  if (!*hls->key_string) {
763  if (!hls->key) {
764  if ((ret = av_random_bytes(key, sizeof(key))) < 0) {
765  av_log(s, AV_LOG_ERROR, "Cannot generate a strong random key\n");
766  return ret;
767  }
768  } else {
769  memcpy(key, hls->key, sizeof(key));
770  }
771 
772  ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
773  set_http_options(s, &options, hls);
774  ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_WRITE, &options);
776  if (ret < 0)
777  return ret;
778  avio_seek(pb, 0, SEEK_CUR);
779  avio_write(pb, key, KEYSIZE);
780  avio_close(pb);
781  }
782  return 0;
783 }
784 
785 
787 {
788  HLSContext *hls = s->priv_data;
789  int ret;
790  AVIOContext *pb;
791  uint8_t key[KEYSIZE];
793 
794  set_http_options(s, &options, hls);
795  ret = s->io_open(s, &pb, hls->key_info_file, AVIO_FLAG_READ, &options);
797  if (ret < 0) {
798  av_log(hls, AV_LOG_ERROR,
799  "error opening key info file %s\n", hls->key_info_file);
800  return ret;
801  }
802 
803  ff_get_line(pb, vs->key_uri, sizeof(vs->key_uri));
804  vs->key_uri[strcspn(vs->key_uri, "\r\n")] = '\0';
805 
806  ff_get_line(pb, vs->key_file, sizeof(vs->key_file));
807  vs->key_file[strcspn(vs->key_file, "\r\n")] = '\0';
808 
809  ff_get_line(pb, vs->iv_string, sizeof(vs->iv_string));
810  vs->iv_string[strcspn(vs->iv_string, "\r\n")] = '\0';
811 
812  ff_format_io_close(s, &pb);
813 
814  if (!*vs->key_uri) {
815  av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
816  return AVERROR(EINVAL);
817  }
818 
819  if (!*vs->key_file) {
820  av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
821  return AVERROR(EINVAL);
822  }
823 
824  set_http_options(s, &options, hls);
825  ret = s->io_open(s, &pb, vs->key_file, AVIO_FLAG_READ, &options);
827  if (ret < 0) {
828  av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", vs->key_file);
829  return ret;
830  }
831 
832  ret = avio_read(pb, key, sizeof(key));
833  ff_format_io_close(s, &pb);
834  if (ret != sizeof(key)) {
835  av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", vs->key_file);
836  if (ret >= 0 || ret == AVERROR_EOF)
837  ret = AVERROR(EINVAL);
838  return ret;
839  }
840  ff_data_to_hex(vs->key_string, key, sizeof(key), 0);
841 
842  return 0;
843 }
844 
846 {
848  HLSContext *hls = s->priv_data;
849  AVFormatContext *oc;
850  AVFormatContext *vtt_oc = NULL;
851  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
852  int remaining_options;
853  int i, ret;
854 
856  if (ret < 0)
857  return ret;
858  oc = vs->avf;
859 
860  oc->url = av_strdup("");
861  if (!oc->url)
862  return AVERROR(ENOMEM);
863 
864  oc->interrupt_callback = s->interrupt_callback;
865  oc->max_delay = s->max_delay;
866  oc->opaque = s->opaque;
867  oc->io_open = s->io_open;
868  oc->io_close2 = s->io_close2;
869  oc->strict_std_compliance = s->strict_std_compliance;
870  av_dict_copy(&oc->metadata, s->metadata, 0);
871 
872  if (vs->vtt_oformat) {
874  if (ret < 0)
875  return ret;
876  vtt_oc = vs->vtt_avf;
877  av_dict_copy(&vtt_oc->metadata, s->metadata, 0);
878  }
879 
880  for (i = 0; i < vs->nb_streams; i++) {
881  AVStream *st;
882  AVFormatContext *loc;
884  loc = vtt_oc;
885  else
886  loc = oc;
887 
888  if (!(st = avformat_new_stream(loc, NULL)))
889  return AVERROR(ENOMEM);
891  if (ret < 0)
892  return ret;
893  if (!oc->oformat->codec_tag ||
897  } else {
898  st->codecpar->codec_tag = 0;
899  }
900 
902  st->time_base = vs->streams[i]->time_base;
903  av_dict_copy(&st->metadata, vs->streams[i]->metadata, 0);
904  st->id = vs->streams[i]->id;
905  }
906 
907  vs->start_pos = 0;
908  vs->new_start = 1;
909 
910  if (hls->segment_type == SEGMENT_TYPE_FMP4 && hls->max_seg_size > 0) {
911  if (hls->http_persistent > 0) {
912  //TODO: Support fragment fmp4 for http persistent in HLS muxer.
913  av_log(s, AV_LOG_WARNING, "http persistent mode is currently unsupported for fragment mp4 in the HLS muxer.\n");
914  }
915  if (hls->max_seg_size > 0) {
916  av_log(s, AV_LOG_WARNING, "Multi-file byterange mode is currently unsupported in the HLS muxer.\n");
917  return AVERROR_PATCHWELCOME;
918  }
919  }
920 
921  if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
922  return ret;
923 
924  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
925  set_http_options(s, &options, hls);
926  if (byterange_mode) {
927  ret = hlsenc_io_open(s, &vs->out, vs->basename, &options);
928  } else {
930  }
932  }
933  if (ret < 0) {
934  av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", vs->fmp4_init_filename);
935  return ret;
936  }
937 
939  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
940  av_dict_set(&options, "fflags", "-autobsf", 0);
941  av_dict_set(&options, "movflags", "+frag_custom+dash+delay_moov", AV_DICT_APPEND);
942  } else {
943  /* We only require one PAT/PMT per segment. */
944  char period[21];
945  snprintf(period, sizeof(period), "%d", (INT_MAX / 2) - 1);
948  }
950  remaining_options = av_dict_count(options);
952  if (ret < 0)
953  return ret;
954  if (remaining_options) {
955  av_log(s, AV_LOG_ERROR, "Some of the provided format options are not recognized\n");
956  return AVERROR(EINVAL);
957  }
958  avio_flush(oc->pb);
959  return 0;
960 }
961 
962 static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *filename)
963 {
964  while (segment) {
965  if (!av_strcasecmp(segment->filename,filename))
966  return segment;
967  segment = segment->next;
968  }
969  return (HLSSegment *) NULL;
970 }
971 
973  VariantStream *vs, HLSSegment *en,
974  double duration, int64_t pos, int64_t size)
975 {
978  char * new_url = av_strdup(vs->current_segment_final_filename_fmt);
979  if (!new_url) {
980  return AVERROR(ENOMEM);
981  }
982  ff_format_set_url(vs->avf, new_url);
984  char *filename = NULL;
985  if (replace_int_data_in_filename(&filename, vs->avf->url, 's', pos + size) < 1) {
986  av_log(hls, AV_LOG_ERROR,
987  "Invalid second level segment filename template '%s', "
988  "you can try to remove second_level_segment_size flag\n",
989  vs->avf->url);
990  av_freep(&filename);
991  return AVERROR(EINVAL);
992  }
993  ff_format_set_url(vs->avf, filename);
994  }
996  char *filename = NULL;
997  if (replace_int_data_in_filename(&filename, vs->avf->url,
998  't', (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) {
999  av_log(hls, AV_LOG_ERROR,
1000  "Invalid second level segment filename template '%s', "
1001  "you can try to remove second_level_segment_duration flag\n",
1002  vs->avf->url);
1003  av_freep(&filename);
1004  return AVERROR(EINVAL);
1005  }
1006  ff_format_set_url(vs->avf, filename);
1007  }
1008  }
1009  return 0;
1010 }
1011 
1013 {
1014  int ret = 0;
1015 
1017  av_log(hls, AV_LOG_ERROR,
1018  "second_level_segment_duration hls_flag requires strftime to be true\n");
1019  ret = AVERROR(EINVAL);
1020  }
1021  if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
1022  av_log(hls, AV_LOG_ERROR,
1023  "second_level_segment_size hls_flag requires strfime to be true\n");
1024  ret = AVERROR(EINVAL);
1025  }
1027  av_log(hls, AV_LOG_ERROR,
1028  "second_level_segment_index hls_flag requires strftime to be true\n");
1029  ret = AVERROR(EINVAL);
1030  }
1031 
1032  return ret;
1033 }
1034 
1036 {
1037  const char *proto = avio_find_protocol_name(vs->basename);
1038  int segment_renaming_ok = proto && !strcmp(proto, "file");
1039  int ret = 0;
1040 
1041  if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) {
1042  av_log(hls, AV_LOG_ERROR,
1043  "second_level_segment_duration hls_flag works only with file protocol segment names\n");
1044  ret = AVERROR(EINVAL);
1045  }
1046  if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) {
1047  av_log(hls, AV_LOG_ERROR,
1048  "second_level_segment_size hls_flag works only with file protocol segment names\n");
1049  ret = AVERROR(EINVAL);
1050  }
1051 
1052  return ret;
1053 }
1054 
1055 static void sls_flag_file_rename(HLSContext *hls, VariantStream *vs, char *old_filename) {
1057  strlen(vs->current_segment_final_filename_fmt)) {
1058  ff_rename(old_filename, vs->avf->url, hls);
1059  }
1060 }
1061 
1063 {
1064  if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {
1065  char *filename = NULL;
1066  if (replace_int_data_in_filename(&filename,
1067  oc->url, 'd', vs->sequence) < 1) {
1068  av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
1069  "you can try to remove second_level_segment_index flag\n",
1070  oc->url);
1071  av_freep(&filename);
1072  return AVERROR(EINVAL);
1073  }
1074  ff_format_set_url(oc, filename);
1075  }
1079  if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {
1080  char *filename = NULL;
1081  if (replace_int_data_in_filename(&filename, oc->url, 's', 0) < 1) {
1082  av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
1083  "you can try to remove second_level_segment_size flag\n",
1084  oc->url);
1085  av_freep(&filename);
1086  return AVERROR(EINVAL);
1087  }
1088  ff_format_set_url(oc, filename);
1089  }
1090  if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {
1091  char *filename = NULL;
1092  if (replace_int_data_in_filename(&filename, oc->url, 't', 0) < 1) {
1093  av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
1094  "you can try to remove second_level_segment_duration flag\n",
1095  oc->url);
1096  av_freep(&filename);
1097  return AVERROR(EINVAL);
1098  }
1099  ff_format_set_url(oc, filename);
1100  }
1101  }
1102  return 0;
1103 }
1104 
1105 /* Create a new segment and append it to the segment list */
1107  VariantStream *vs, double duration, int64_t pos,
1108  int64_t size)
1109 {
1110  HLSSegment *en = av_malloc(sizeof(*en));
1111  const char *filename;
1112  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
1113  int ret;
1114 
1115  if (!en)
1116  return AVERROR(ENOMEM);
1117 
1118  vs->total_size += size;
1119  vs->total_duration += duration;
1120  if (duration > 0.5) {
1121  // Don't include the final, possibly very short segment in the
1122  // calculation of the max bitrate.
1123  int cur_bitrate = (int)(8 * size / duration);
1124  if (cur_bitrate > vs->max_bitrate)
1125  vs->max_bitrate = cur_bitrate;
1126  }
1127  if (vs->total_duration > 0)
1128  vs->avg_bitrate = (int)(8 * vs->total_size / vs->total_duration);
1129 
1130  en->var_stream_idx = vs->var_stream_idx;
1131  ret = sls_flags_filename_process(s, hls, vs, en, duration, pos, size);
1132  if (ret < 0) {
1133  av_freep(&en);
1134  return ret;
1135  }
1136 
1137  filename = av_basename(vs->avf->url);
1138 
1139  if (hls->use_localtime_mkdir) {
1140  filename = vs->avf->url;
1141  }
1142  if ((find_segment_by_filename(vs->segments, filename) || find_segment_by_filename(vs->old_segments, filename))
1143  && !byterange_mode) {
1144  av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", filename);
1145  }
1146  av_strlcpy(en->filename, filename, sizeof(en->filename));
1147 
1148  if (vs->has_subtitle)
1149  av_strlcpy(en->sub_filename, av_basename(vs->vtt_avf->url), sizeof(en->sub_filename));
1150  else
1151  en->sub_filename[0] = '\0';
1152 
1153  en->duration = duration;
1154  en->pos = pos;
1155  en->size = size;
1156  en->keyframe_pos = vs->video_keyframe_pos;
1158  en->next = NULL;
1159  en->discont = 0;
1160  en->discont_program_date_time = 0;
1161 
1162  if (vs->discontinuity) {
1163  en->discont = 1;
1164  vs->discontinuity = 0;
1165  }
1166 
1167  if (hls->key_info_file || hls->encrypt) {
1168  av_strlcpy(en->key_uri, vs->key_uri, sizeof(en->key_uri));
1169  av_strlcpy(en->iv_string, vs->iv_string, sizeof(en->iv_string));
1170  }
1171 
1172  if (!vs->segments)
1173  vs->segments = en;
1174  else
1175  vs->last_segment->next = en;
1176 
1177  vs->last_segment = en;
1178 
1179  // EVENT or VOD playlists imply sliding window cannot be used
1180  if (hls->pl_type != PLAYLIST_TYPE_NONE)
1181  hls->max_nb_segments = 0;
1182 
1183  if (hls->max_nb_segments && vs->nb_entries >= hls->max_nb_segments) {
1184  en = vs->segments;
1186  vs->initial_prog_date_time += en->duration;
1187  vs->segments = en->next;
1188  if (en && hls->flags & HLS_DELETE_SEGMENTS &&
1189  !(hls->flags & HLS_SINGLE_FILE)) {
1190  en->next = vs->old_segments;
1191  vs->old_segments = en;
1192  if ((ret = hls_delete_old_segments(s, hls, vs)) < 0)
1193  return ret;
1194  } else
1195  av_freep(&en);
1196  } else
1197  vs->nb_entries++;
1198 
1199  if (hls->max_seg_size > 0) {
1200  return 0;
1201  }
1202  vs->sequence++;
1203 
1204  return 0;
1205 }
1206 
1207 static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
1208 {
1209  HLSContext *hls = s->priv_data;
1210  AVIOContext *in;
1211  int ret = 0, is_segment = 0;
1212  int64_t new_start_pos;
1213  char line[MAX_URL_SIZE];
1214  const char *ptr;
1215  const char *end;
1216  double discont_program_date_time = 0;
1217 
1218  if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ,
1219  &s->interrupt_callback, NULL,
1220  s->protocol_whitelist, s->protocol_blacklist)) < 0)
1221  return ret;
1222 
1223  ff_get_chomp_line(in, line, sizeof(line));
1224  if (strcmp(line, "#EXTM3U")) {
1226  goto fail;
1227  }
1228 
1229  vs->discontinuity = 0;
1230  while (!avio_feof(in)) {
1231  ff_get_chomp_line(in, line, sizeof(line));
1232  if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
1233  int64_t tmp_sequence = strtoll(ptr, NULL, 10);
1234  if (tmp_sequence < vs->sequence)
1235  av_log(hls, AV_LOG_VERBOSE,
1236  "Found playlist sequence number was smaller """
1237  "than specified start sequence number: %"PRId64" < %"PRId64", "
1238  "omitting\n", tmp_sequence, hls->start_sequence);
1239  else {
1240  av_log(hls, AV_LOG_DEBUG, "Found playlist sequence number: %"PRId64"\n", tmp_sequence);
1241  vs->sequence = tmp_sequence;
1242  }
1243  } else if (av_strstart(line, "#EXT-X-DISCONTINUITY", &ptr)) {
1244  is_segment = 1;
1245  vs->discontinuity = 1;
1246  } else if (av_strstart(line, "#EXTINF:", &ptr)) {
1247  is_segment = 1;
1248  vs->duration = atof(ptr);
1249  } else if (av_stristart(line, "#EXT-X-KEY:", &ptr)) {
1250  ptr = av_stristr(line, "URI=\"");
1251  if (ptr) {
1252  ptr += strlen("URI=\"");
1253  end = av_stristr(ptr, ",");
1254  if (end) {
1255  av_strlcpy(vs->key_uri, ptr, end - ptr);
1256  } else {
1257  av_strlcpy(vs->key_uri, ptr, sizeof(vs->key_uri));
1258  }
1259  }
1260 
1261  ptr = av_stristr(line, "IV=0x");
1262  if (ptr) {
1263  ptr += strlen("IV=0x");
1264  end = av_stristr(ptr, ",");
1265  if (end) {
1266  av_strlcpy(vs->iv_string, ptr, end - ptr);
1267  } else {
1268  av_strlcpy(vs->iv_string, ptr, sizeof(vs->iv_string));
1269  }
1270  }
1271  } else if (av_strstart(line, "#EXT-X-PROGRAM-DATE-TIME:", &ptr)) {
1272  struct tm program_date_time;
1273  int y,M,d,h,m,s;
1274  double ms;
1275  if (sscanf(ptr, "%d-%d-%dT%d:%d:%d.%lf", &y, &M, &d, &h, &m, &s, &ms) != 7) {
1277  goto fail;
1278  }
1279 
1280  program_date_time.tm_year = y - 1900;
1281  program_date_time.tm_mon = M - 1;
1282  program_date_time.tm_mday = d;
1283  program_date_time.tm_hour = h;
1284  program_date_time.tm_min = m;
1285  program_date_time.tm_sec = s;
1286  program_date_time.tm_isdst = -1;
1287 
1288  discont_program_date_time = mktime(&program_date_time);
1289  discont_program_date_time += (double)(ms / 1000);
1290  } else if (av_strstart(line, "#", NULL)) {
1291  continue;
1292  } else if (line[0]) {
1293  if (is_segment) {
1294  char *new_file = av_strdup(line);
1295  if (!new_file) {
1296  ret = AVERROR(ENOMEM);
1297  goto fail;
1298  }
1299  ff_format_set_url(vs->avf, new_file);
1300  is_segment = 0;
1301  new_start_pos = avio_tell(vs->avf->pb);
1302  vs->size = new_start_pos - vs->start_pos;
1303  ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size);
1304  if (discont_program_date_time) {
1305  vs->last_segment->discont_program_date_time = discont_program_date_time;
1306  discont_program_date_time += vs->duration;
1307  }
1308  if (ret < 0)
1309  goto fail;
1310  vs->start_pos = new_start_pos;
1311  }
1312  }
1313  }
1314 
1315 fail:
1316  avio_close(in);
1317  return ret;
1318 }
1319 
1321 {
1322  HLSSegment *en;
1323 
1324  while (p) {
1325  en = p;
1326  p = p->next;
1327  av_freep(&en);
1328  }
1329 }
1330 
1332 {
1333  size_t len = strlen(oc->url);
1334  char *final_filename = av_strdup(oc->url);
1335  int ret;
1336 
1337  if (!final_filename)
1338  return AVERROR(ENOMEM);
1339  final_filename[len-4] = '\0';
1340  ret = ff_rename(oc->url, final_filename, s);
1341  oc->url[len-4] = '\0';
1342  av_freep(&final_filename);
1343  return ret;
1344 }
1345 
1346 static const char* get_relative_url(const char *master_url, const char *media_url)
1347 {
1348  const char *p = strrchr(master_url, '/');
1349  size_t base_len = 0;
1350 
1351  if (!p) p = strrchr(master_url, '\\');
1352 
1353  if (p) {
1354  base_len = p - master_url;
1355  if (av_strncasecmp(master_url, media_url, base_len)) {
1356  av_log(NULL, AV_LOG_WARNING, "Unable to find relative url\n");
1357  return NULL;
1358  }
1359  } else {
1360  return media_url;
1361  }
1362 
1363  return media_url + base_len + 1;
1364 }
1365 
1367 {
1371  );
1372 
1373  if (stream->codecpar->bit_rate)
1374  return stream->codecpar->bit_rate;
1375  else if (sd) {
1376  AVCPBProperties *props = (AVCPBProperties*)sd->data;
1377  return props->max_bitrate;
1378  }
1379 
1380  return 0;
1381 }
1382 
1384  VariantStream * const input_vs,
1385  int final)
1386 {
1387  HLSContext *hls = s->priv_data;
1388  VariantStream *vs, *temp_vs;
1389  AVStream *vid_st, *aud_st;
1391  unsigned int i, j;
1392  int ret, bandwidth, avg_bandwidth;
1393  const char *m3u8_rel_name = NULL;
1394  const char *vtt_m3u8_rel_name = NULL;
1395  const char *ccgroup;
1396  const char *sgroup = NULL;
1397  ClosedCaptionsStream *ccs;
1398  const char *proto = avio_find_protocol_name(hls->master_m3u8_url);
1399  int is_file_proto = proto && !strcmp(proto, "file");
1400  int use_temp_file = is_file_proto && ((hls->flags & HLS_TEMP_FILE) || hls->master_publish_rate);
1401  char temp_filename[MAX_URL_SIZE];
1402  int nb_channels;
1403 
1404  input_vs->m3u8_created = 1;
1405  if (!hls->master_m3u8_created) {
1406  /* For the first time, wait until all the media playlists are created */
1407  for (i = 0; i < hls->nb_varstreams; i++)
1408  if (!hls->var_streams[i].m3u8_created)
1409  return 0;
1410  } else {
1411  /* Keep publishing the master playlist at the configured rate */
1412  if ((&hls->var_streams[0] != input_vs || !hls->master_publish_rate ||
1413  input_vs->number % hls->master_publish_rate) && !final)
1414  return 0;
1415  }
1416 
1417  set_http_options(s, &options, hls);
1418  snprintf(temp_filename, sizeof(temp_filename), use_temp_file ? "%s.tmp" : "%s", hls->master_m3u8_url);
1419  ret = hlsenc_io_open(s, &hls->m3u8_out, temp_filename, &options);
1421  if (ret < 0) {
1422  av_log(s, AV_LOG_ERROR, "Failed to open master play list file '%s'\n",
1423  temp_filename);
1424  goto fail;
1425  }
1426 
1428 
1429  for (i = 0; i < hls->nb_ccstreams; i++) {
1430  ccs = &(hls->cc_streams[i]);
1431  avio_printf(hls->m3u8_out, "#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS");
1432  avio_printf(hls->m3u8_out, ",GROUP-ID=\"%s\"", ccs->ccgroup);
1433  avio_printf(hls->m3u8_out, ",NAME=\"%s\"", ccs->instreamid);
1434  if (ccs->language)
1435  avio_printf(hls->m3u8_out, ",LANGUAGE=\"%s\"", ccs->language);
1436  avio_printf(hls->m3u8_out, ",INSTREAM-ID=\"%s\"\n", ccs->instreamid);
1437  }
1438 
1439  /* For audio only variant streams add #EXT-X-MEDIA tag with attributes*/
1440  for (i = 0; i < hls->nb_varstreams; i++) {
1441  vs = &(hls->var_streams[i]);
1442 
1443  if (vs->has_video || vs->has_subtitle || !vs->agroup)
1444  continue;
1445 
1446  m3u8_rel_name = get_relative_url(hls->master_m3u8_url, vs->m3u8_name);
1447  if (!m3u8_rel_name) {
1448  av_log(s, AV_LOG_ERROR, "Unable to find relative URL\n");
1449  goto fail;
1450  }
1451  nb_channels = 0;
1452  for (j = 0; j < vs->nb_streams; j++)
1454  if (vs->streams[j]->codecpar->ch_layout.nb_channels > nb_channels)
1455  nb_channels = vs->streams[j]->codecpar->ch_layout.nb_channels;
1456 
1457  ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, vs->language, i, hls->has_default_key ? vs->is_default : 1, nb_channels);
1458  }
1459 
1460  /* For variant streams with video add #EXT-X-STREAM-INF tag with attributes*/
1461  for (i = 0; i < hls->nb_varstreams; i++) {
1462  vs = &(hls->var_streams[i]);
1463 
1464  m3u8_rel_name = get_relative_url(hls->master_m3u8_url, vs->m3u8_name);
1465  if (!m3u8_rel_name) {
1466  av_log(s, AV_LOG_ERROR, "Unable to find relative URL\n");
1467  goto fail;
1468  }
1469 
1470  vid_st = NULL;
1471  aud_st = NULL;
1472  for (j = 0; j < vs->nb_streams; j++) {
1474  vid_st = vs->streams[j];
1475  else if (vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
1476  aud_st = vs->streams[j];
1477  }
1478 
1479  if (!vid_st && !aud_st) {
1480  av_log(s, AV_LOG_WARNING, "Media stream not found\n");
1481  continue;
1482  }
1483 
1484  /**
1485  * Traverse through the list of audio only rendition streams and find
1486  * the rendition which has highest bitrate in the same audio group
1487  */
1488  if (vs->agroup) {
1489  for (j = 0; j < hls->nb_varstreams; j++) {
1490  temp_vs = &(hls->var_streams[j]);
1491  if (!temp_vs->has_video && !temp_vs->has_subtitle &&
1492  temp_vs->agroup &&
1493  !av_strcasecmp(temp_vs->agroup, vs->agroup)) {
1494  if (!aud_st)
1495  aud_st = temp_vs->streams[0];
1496  if (temp_vs->streams[0]->codecpar->bit_rate >
1497  aud_st->codecpar->bit_rate)
1498  aud_st = temp_vs->streams[0];
1499  }
1500  }
1501  }
1502 
1503  if (final) {
1504  bandwidth = vs->max_bitrate;
1505  avg_bandwidth = vs->avg_bitrate;
1506  } else {
1507  bandwidth = 0;
1508  if (vid_st)
1509  bandwidth += get_stream_bit_rate(vid_st);
1510  if (aud_st)
1511  bandwidth += get_stream_bit_rate(aud_st);
1512  bandwidth += bandwidth / 10;
1513  }
1514 
1515  ccgroup = NULL;
1516  if (vid_st && vs->ccgroup) {
1517  /* check if this group name is available in the cc map string */
1518  for (j = 0; j < hls->nb_ccstreams; j++) {
1519  ccs = &(hls->cc_streams[j]);
1520  if (!av_strcasecmp(ccs->ccgroup, vs->ccgroup)) {
1521  ccgroup = vs->ccgroup;
1522  break;
1523  }
1524  }
1525  if (j == hls->nb_ccstreams)
1526  av_log(s, AV_LOG_WARNING, "mapping ccgroup %s not found\n",
1527  vs->ccgroup);
1528  }
1529 
1530  if (vid_st && vs->sgroup) {
1531  sgroup = vs->sgroup;
1532  vtt_m3u8_rel_name = get_relative_url(hls->master_m3u8_url, vs->vtt_m3u8_name);
1533  if (!vtt_m3u8_rel_name) {
1534  av_log(s, AV_LOG_WARNING, "Unable to find relative subtitle URL\n");
1535  break;
1536  }
1537 
1538  ff_hls_write_subtitle_rendition(hls->m3u8_out, sgroup, vtt_m3u8_rel_name, vs->language, i, hls->has_default_key ? vs->is_default : 1);
1539  }
1540 
1541  if (!hls->has_default_key || !hls->has_video_m3u8) {
1542  ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, avg_bandwidth, m3u8_rel_name,
1543  aud_st ? vs->agroup : NULL, vs->codec_attr, ccgroup, sgroup);
1544  } else {
1545  if (vid_st) {
1546  ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, avg_bandwidth, m3u8_rel_name,
1547  aud_st ? vs->agroup : NULL, vs->codec_attr, ccgroup, sgroup);
1548  }
1549  }
1550  }
1551 fail:
1552  if (ret >=0)
1553  hls->master_m3u8_created = 1;
1554  hlsenc_io_close(s, &hls->m3u8_out, temp_filename);
1555  if (use_temp_file)
1556  ff_rename(temp_filename, hls->master_m3u8_url, s);
1557 
1558  return ret;
1559 }
1560 
1561 static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
1562 {
1563  HLSContext *hls = s->priv_data;
1564  HLSSegment *en;
1565  int target_duration = 0;
1566  int ret = 0;
1567  char temp_filename[MAX_URL_SIZE];
1568  char temp_vtt_filename[MAX_URL_SIZE];
1569  int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - vs->nb_entries);
1570  const char *proto = avio_find_protocol_name(vs->m3u8_name);
1571  int is_file_proto = proto && !strcmp(proto, "file");
1572  int use_temp_file = is_file_proto && ((hls->flags & HLS_TEMP_FILE) || !(hls->pl_type == PLAYLIST_TYPE_VOD));
1573  static unsigned warned_non_file;
1574  char *key_uri = NULL;
1575  char *iv_string = NULL;
1577  double prog_date_time = vs->initial_prog_date_time;
1578  double *prog_date_time_p = (hls->flags & HLS_PROGRAM_DATE_TIME) ? &prog_date_time : NULL;
1579  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
1580 
1581  hls->version = 2;
1582  if (!(hls->flags & HLS_ROUND_DURATIONS)) {
1583  hls->version = 3;
1584  }
1585 
1586  if (byterange_mode) {
1587  hls->version = 4;
1588  sequence = 0;
1589  }
1590 
1591  if (hls->flags & HLS_I_FRAMES_ONLY) {
1592  hls->version = 4;
1593  }
1594 
1595  if (hls->flags & HLS_INDEPENDENT_SEGMENTS) {
1596  hls->version = 6;
1597  }
1598 
1599  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1600  hls->version = 7;
1601  }
1602 
1603  if (!is_file_proto && (hls->flags & HLS_TEMP_FILE) && !warned_non_file++)
1604  av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n");
1605 
1606  set_http_options(s, &options, hls);
1607  snprintf(temp_filename, sizeof(temp_filename), use_temp_file ? "%s.tmp" : "%s", vs->m3u8_name);
1608  ret = hlsenc_io_open(s, byterange_mode ? &hls->m3u8_out : &vs->out, temp_filename, &options);
1610  if (ret < 0) {
1611  goto fail;
1612  }
1613 
1614  for (en = vs->segments; en; en = en->next) {
1615  if (target_duration <= en->duration)
1616  target_duration = lrint(en->duration);
1617  }
1618 
1619  vs->discontinuity_set = 0;
1620  ff_hls_write_playlist_header(byterange_mode ? hls->m3u8_out : vs->out, hls->version, hls->allowcache,
1621  target_duration, sequence, hls->pl_type, hls->flags & HLS_I_FRAMES_ONLY);
1622 
1623  if ((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && vs->discontinuity_set==0) {
1624  avio_printf(byterange_mode ? hls->m3u8_out : vs->out, "#EXT-X-DISCONTINUITY\n");
1625  vs->discontinuity_set = 1;
1626  }
1627  if (vs->has_video && (hls->flags & HLS_INDEPENDENT_SEGMENTS)) {
1628  avio_printf(byterange_mode ? hls->m3u8_out : vs->out, "#EXT-X-INDEPENDENT-SEGMENTS\n");
1629  }
1630  for (en = vs->segments; en; en = en->next) {
1631  if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) ||
1632  av_strcasecmp(en->iv_string, iv_string))) {
1633  avio_printf(byterange_mode ? hls->m3u8_out : vs->out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", en->key_uri);
1634  if (*en->iv_string)
1635  avio_printf(byterange_mode ? hls->m3u8_out : vs->out, ",IV=0x%s", en->iv_string);
1636  avio_printf(byterange_mode ? hls->m3u8_out : vs->out, "\n");
1637  key_uri = en->key_uri;
1638  iv_string = en->iv_string;
1639  }
1640 
1641  if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == vs->segments)) {
1642  ff_hls_write_init_file(byterange_mode ? hls->m3u8_out : vs->out, (hls->flags & HLS_SINGLE_FILE) ? en->filename : vs->fmp4_init_filename,
1643  hls->flags & HLS_SINGLE_FILE, vs->init_range_length, 0);
1644  }
1645 
1646  ret = ff_hls_write_file_entry(byterange_mode ? hls->m3u8_out : vs->out, en->discont, byterange_mode,
1647  en->duration, hls->flags & HLS_ROUND_DURATIONS,
1648  en->size, en->pos, hls->baseurl,
1649  en->filename,
1650  en->discont_program_date_time ? &en->discont_program_date_time : prog_date_time_p,
1652  if (en->discont_program_date_time)
1654  if (ret < 0) {
1655  av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
1656  }
1657  }
1658 
1659  if (last && (hls->flags & HLS_OMIT_ENDLIST)==0)
1660  ff_hls_write_end_list(byterange_mode ? hls->m3u8_out : vs->out);
1661 
1662  if (vs->vtt_m3u8_name) {
1663  set_http_options(vs->vtt_avf, &options, hls);
1664  snprintf(temp_vtt_filename, sizeof(temp_vtt_filename), use_temp_file ? "%s.tmp" : "%s", vs->vtt_m3u8_name);
1665  ret = hlsenc_io_open(s, &hls->sub_m3u8_out, temp_vtt_filename, &options);
1667  if (ret < 0) {
1668  goto fail;
1669  }
1671  target_duration, sequence, PLAYLIST_TYPE_NONE, 0);
1672  for (en = vs->segments; en; en = en->next) {
1673  ret = ff_hls_write_file_entry(hls->sub_m3u8_out, 0, byterange_mode,
1674  en->duration, 0, en->size, en->pos,
1675  hls->baseurl, en->sub_filename, NULL, 0, 0, 0);
1676  if (ret < 0) {
1677  av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
1678  }
1679  }
1680 
1681  if (last)
1683 
1684  }
1685 
1686 fail:
1688  ret = hlsenc_io_close(s, byterange_mode ? &hls->m3u8_out : &vs->out, temp_filename);
1689  if (ret < 0) {
1690  return ret;
1691  }
1693  if (use_temp_file) {
1694  ff_rename(temp_filename, vs->m3u8_name, s);
1695  if (vs->vtt_m3u8_name)
1696  ff_rename(temp_vtt_filename, vs->vtt_m3u8_name, s);
1697  }
1698  if (ret >= 0 && hls->master_pl_name)
1699  if (create_master_playlist(s, vs, last) < 0)
1700  av_log(s, AV_LOG_WARNING, "Master playlist creation failed\n");
1701 
1702  return ret;
1703 }
1704 
1706 {
1707  HLSContext *c = s->priv_data;
1708  AVFormatContext *oc = vs->avf;
1709  AVFormatContext *vtt_oc = vs->vtt_avf;
1711  const char *proto = NULL;
1712  int use_temp_file = 0;
1713  char iv_string[KEYSIZE*2 + 1];
1714  int err = 0;
1715 
1716  if (c->flags & HLS_SINGLE_FILE) {
1717  char *new_name = av_strdup(vs->basename);
1718  if (!new_name)
1719  return AVERROR(ENOMEM);
1720  ff_format_set_url(oc, new_name);
1721  if (vs->vtt_basename) {
1722  new_name = av_strdup(vs->vtt_basename);
1723  if (!new_name)
1724  return AVERROR(ENOMEM);
1725  ff_format_set_url(vtt_oc, new_name);
1726  }
1727  } else if (c->max_seg_size > 0) {
1728  char *filename = NULL;
1729  if (replace_int_data_in_filename(&filename,
1730  vs->basename, 'd', vs->sequence) < 1) {
1731  av_freep(&filename);
1732  av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s', you can try to use -strftime 1 with it\n", vs->basename);
1733  return AVERROR(EINVAL);
1734  }
1735  ff_format_set_url(oc, filename);
1736  } else {
1737  if (c->use_localtime) {
1738  int r;
1739  char *expanded = NULL;
1740 
1741  r = strftime_expand(vs->basename, &expanded);
1742  if (r < 0) {
1743  av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
1744  return r;
1745  }
1746  ff_format_set_url(oc, expanded);
1747 
1748  err = sls_flag_use_localtime_filename(oc, c, vs);
1749  if (err < 0) {
1750  return AVERROR(ENOMEM);
1751  }
1752 
1753  if (c->use_localtime_mkdir) {
1754  const char *dir;
1755  char *fn_copy = av_strdup(oc->url);
1756  if (!fn_copy)
1757  return AVERROR(ENOMEM);
1758  dir = av_dirname(fn_copy);
1759  if (ff_mkdir_p(dir) == -1 && errno != EEXIST) {
1760  av_log(oc, AV_LOG_ERROR, "Could not create directory %s with use_localtime_mkdir\n", dir);
1761  av_freep(&fn_copy);
1762  return AVERROR(errno);
1763  }
1764  av_freep(&fn_copy);
1765  }
1766  } else {
1767  char *filename = NULL;
1768  if (replace_int_data_in_filename(&filename,
1769  vs->basename, 'd', vs->sequence) < 1) {
1770  av_freep(&filename);
1771  av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s' you can try to use -strftime 1 with it\n", vs->basename);
1772  return AVERROR(EINVAL);
1773  }
1774  ff_format_set_url(oc, filename);
1775  }
1776  if (vs->vtt_basename) {
1777  char *filename = NULL;
1778  if (replace_int_data_in_filename(&filename,
1779  vs->vtt_basename, 'd', vs->sequence) < 1) {
1780  av_freep(&filename);
1781  av_log(vtt_oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", vs->vtt_basename);
1782  return AVERROR(EINVAL);
1783  }
1784  ff_format_set_url(vtt_oc, filename);
1785  }
1786  }
1787 
1788  proto = avio_find_protocol_name(oc->url);
1789  use_temp_file = proto && !strcmp(proto, "file") && (c->flags & HLS_TEMP_FILE);
1790 
1791  if (use_temp_file) {
1792  char *new_name = av_asprintf("%s.tmp", oc->url);
1793  if (!new_name)
1794  return AVERROR(ENOMEM);
1795  ff_format_set_url(oc, new_name);
1796  }
1797 
1798  if (c->key_info_file || c->encrypt) {
1799  if (c->segment_type == SEGMENT_TYPE_FMP4) {
1800  av_log(s, AV_LOG_ERROR, "Encrypted fmp4 not yet supported\n");
1801  return AVERROR_PATCHWELCOME;
1802  }
1803 
1804  if (c->key_info_file && c->encrypt) {
1805  av_log(s, AV_LOG_WARNING, "Cannot use both -hls_key_info_file and -hls_enc,"
1806  " ignoring -hls_enc\n");
1807  }
1808 
1809  if (!vs->encrypt_started || (c->flags & HLS_PERIODIC_REKEY)) {
1810  if (c->key_info_file) {
1811  if ((err = hls_encryption_start(s, vs)) < 0)
1812  goto fail;
1813  } else {
1814  if (!c->encrypt_started) {
1815  if ((err = do_encrypt(s, vs)) < 0)
1816  goto fail;
1817  c->encrypt_started = 1;
1818  }
1819  av_strlcpy(vs->key_uri, c->key_uri, sizeof(vs->key_uri));
1820  av_strlcpy(vs->key_string, c->key_string, sizeof(vs->key_string));
1821  av_strlcpy(vs->iv_string, c->iv_string, sizeof(vs->iv_string));
1822  }
1823  vs->encrypt_started = 1;
1824  }
1825  err = av_strlcpy(iv_string, vs->iv_string, sizeof(iv_string));
1826  if (!err) {
1827  snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, vs->sequence);
1828  memset(vs->iv_string, 0, sizeof(vs->iv_string));
1829  memcpy(vs->iv_string, iv_string, sizeof(iv_string));
1830  }
1831  }
1832  if (c->segment_type != SEGMENT_TYPE_FMP4) {
1833  if (oc->oformat->priv_class && oc->priv_data) {
1834  av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0);
1835  }
1836  if (c->flags & HLS_SINGLE_FILE) {
1837  if (c->key_info_file || c->encrypt) {
1838  av_dict_set(&options, "encryption_key", vs->key_string, 0);
1839  av_dict_set(&options, "encryption_iv", vs->iv_string, 0);
1840 
1841  /* Write temp file with cryption content */
1842  av_freep(&vs->basename_tmp);
1843  vs->basename_tmp = av_asprintf("crypto:%s.tmp", oc->url);
1844 
1845  /* append temp file content into single file */
1846  av_freep(&vs->basename);
1847  vs->basename = av_asprintf("%s", oc->url);
1848  } else {
1849  vs->basename_tmp = vs->basename;
1850  }
1852  if (!vs->out_single_file)
1853  if ((err = hlsenc_io_open(s, &vs->out_single_file, vs->basename, &options)) < 0) {
1854  if (c->ignore_io_errors)
1855  err = 0;
1856  goto fail;
1857  }
1858 
1859  if ((err = hlsenc_io_open(s, &vs->out, vs->basename_tmp, &options)) < 0) {
1860  if (c->ignore_io_errors)
1861  err = 0;
1862  goto fail;
1863  }
1864 
1865  }
1866  }
1867  if (vs->vtt_basename) {
1869  if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->url, &options)) < 0) {
1870  if (c->ignore_io_errors)
1871  err = 0;
1872  goto fail;
1873  }
1874  }
1876 
1877  if (vs->vtt_basename) {
1878  err = avformat_write_header(vtt_oc,NULL);
1879  if (err < 0)
1880  return err;
1881  }
1882 
1883  return 0;
1884 fail:
1886 
1887  return err;
1888 }
1889 
1891 {
1892  HLSContext *hls = s->priv_data;
1893 #if HAVE_LIBC_MSVCRT
1894  // no %s support on MSVC, which invokes the invalid parameter handler
1895  // on unsupported format strings, instead of returning an error
1896  int strftime_s_supported = 0;
1897 #else
1898  char b[21];
1899  time_t t = time(NULL);
1900  struct tm tmbuf, *p = localtime_r(&t, &tmbuf);
1901  // no %s support when strftime returned error or left format string unchanged
1902  int strftime_s_supported = strftime(b, sizeof(b), "%s", p) && strcmp(b, "%s");
1903 #endif
1904 
1905  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1906  return strftime_s_supported ? "-%s.m4s" : "-%Y%m%d%H%M%S.m4s";
1907  }
1908  return strftime_s_supported ? "-%s.ts" : "-%Y%m%d%H%M%S.ts";
1909 }
1910 
1911 static int append_postfix(char *name, int name_buf_len, int i)
1912 {
1913  char *p;
1914  char extension[10] = {'\0'};
1915 
1916  p = strrchr(name, '.');
1917  if (p) {
1918  av_strlcpy(extension, p, sizeof(extension));
1919  *p = '\0';
1920  }
1921 
1922  snprintf(name + strlen(name), name_buf_len - strlen(name), POSTFIX_PATTERN, i);
1923 
1924  if (strlen(extension))
1925  av_strlcat(name, extension, name_buf_len);
1926 
1927  return 0;
1928 }
1929 
1930 static int validate_name(int nb_vs, const char *fn)
1931 {
1932  const char *filename, *subdir_name;
1933  char *fn_dup = NULL;
1934  int ret = 0;
1935 
1936  if (!fn)
1937  return AVERROR(EINVAL);
1938 
1939  fn_dup = av_strdup(fn);
1940  if (!fn_dup)
1941  return AVERROR(ENOMEM);
1942  filename = av_basename(fn);
1943  subdir_name = av_dirname(fn_dup);
1944 
1945  if (nb_vs > 1 && !av_stristr(filename, "%v") && !av_stristr(subdir_name, "%v")) {
1946  av_log(NULL, AV_LOG_ERROR, "More than 1 variant streams are present, %%v is expected "
1947  "either in the filename or in the sub-directory name of file %s\n", fn);
1948  ret = AVERROR(EINVAL);
1949  goto fail;
1950  }
1951 
1952  if (av_stristr(filename, "%v") && av_stristr(subdir_name, "%v")) {
1953  av_log(NULL, AV_LOG_ERROR, "%%v is expected either in the filename or "
1954  "in the sub-directory name of file %s, but only in one of them\n", fn);
1955  ret = AVERROR(EINVAL);
1956  goto fail;
1957  }
1958 
1959 fail:
1960  av_freep(&fn_dup);
1961  return ret;
1962 }
1963 
1964 static int format_name(const char *buf, char **s, int index, const char *varname)
1965 {
1966  const char *proto, *dir;
1967  char *orig_buf_dup = NULL, *mod_buf_dup = NULL;
1968  int ret = 0;
1969 
1970  orig_buf_dup = av_strdup(buf);
1971  if (!orig_buf_dup)
1972  return AVERROR(ENOMEM);
1973 
1974  if (!av_stristr(buf, "%v")) {
1975  *s = orig_buf_dup;
1976  return 0;
1977  }
1978 
1979  if (!varname) {
1980  if (replace_int_data_in_filename(s, orig_buf_dup, 'v', index) < 1) {
1981  ret = AVERROR(EINVAL);
1982  goto fail;
1983  }
1984  } else {
1985  if (replace_str_data_in_filename(s, orig_buf_dup, 'v', varname) < 1) {
1986  ret = AVERROR(EINVAL);
1987  goto fail;
1988  }
1989  }
1990 
1991  proto = avio_find_protocol_name(orig_buf_dup);
1992  dir = av_dirname(orig_buf_dup);
1993 
1994  /* if %v is present in the file's directory, create sub-directory */
1995  if (av_stristr(dir, "%v") && proto && !strcmp(proto, "file")) {
1996  mod_buf_dup = av_strdup(*s);
1997  dir = av_dirname(mod_buf_dup);
1998  if (ff_mkdir_p(dir) == -1 && errno != EEXIST) {
1999  ret = AVERROR(errno);
2000  goto fail;
2001  }
2002  }
2003 
2004 fail:
2005  av_freep(&orig_buf_dup);
2006  av_freep(&mod_buf_dup);
2007  return ret;
2008 }
2009 
2011  enum AVMediaType codec_type,
2012  int64_t stream_id)
2013 {
2014  unsigned int stream_index, cnt;
2015  if (stream_id < 0 || stream_id > s->nb_streams - 1)
2016  return -1;
2017  cnt = 0;
2018  for (stream_index = 0; stream_index < s->nb_streams; stream_index++) {
2019  if (s->streams[stream_index]->codecpar->codec_type != codec_type)
2020  continue;
2021  if (cnt == stream_id)
2022  return stream_index;
2023  cnt++;
2024  }
2025  return -1;
2026 }
2027 
2029 {
2030  HLSContext *hls = s->priv_data;
2031  VariantStream *vs;
2032  int stream_index, i, j;
2033  enum AVMediaType codec_type;
2034  int nb_varstreams = 0, nb_streams;
2035  char *p, *q, *saveptr1, *saveptr2, *varstr, *keyval;
2036  const char *val;
2037 
2038  /**
2039  * Expected format for var_stream_map string is as below:
2040  * "a:0,v:0 a:1,v:1"
2041  * "a:0,agroup:a0,default:1,language:ENG a:1,agroup:a1,default:0 v:0,agroup:a0 v:1,agroup:a1"
2042  * This string specifies how to group the audio, video and subtitle streams
2043  * into different variant streams. The variant stream groups are separated
2044  * by space.
2045  *
2046  * a:, v:, s: are keys to specify audio, video and subtitle streams
2047  * respectively. Allowed values are 0 to 9 digits (limited just based on
2048  * practical usage)
2049  *
2050  * agroup: is key to specify audio group. A string can be given as value.
2051  * sgroup: is key to specify subtitle group. A string can be given as value.
2052  */
2053  p = av_strdup(hls->var_stream_map);
2054  if (!p)
2055  return AVERROR(ENOMEM);
2056 
2057  q = p;
2058  while (av_strtok(q, " \t", &saveptr1)) {
2059  q = NULL;
2060  nb_varstreams++;
2061  }
2062  av_freep(&p);
2063 
2064  hls->var_streams = av_mallocz(sizeof(*hls->var_streams) * nb_varstreams);
2065  if (!hls->var_streams)
2066  return AVERROR(ENOMEM);
2067  hls->nb_varstreams = nb_varstreams;
2068 
2069  p = hls->var_stream_map;
2070  nb_varstreams = 0;
2071  while (varstr = av_strtok(p, " \t", &saveptr1)) {
2072  p = NULL;
2073 
2074  if (nb_varstreams < hls->nb_varstreams) {
2075  vs = &(hls->var_streams[nb_varstreams]);
2076  vs->var_stream_idx = nb_varstreams;
2077  vs->is_default = 0;
2078  nb_varstreams++;
2079  } else
2080  return AVERROR(EINVAL);
2081 
2082  q = varstr;
2083  while (1) {
2084  if (!av_strncasecmp(q, "a:", 2) || !av_strncasecmp(q, "v:", 2) ||
2085  !av_strncasecmp(q, "s:", 2))
2086  vs->nb_streams++;
2087  q = strchr(q, ',');
2088  if (!q)
2089  break;
2090  q++;
2091  }
2092  vs->streams = av_mallocz(sizeof(AVStream *) * vs->nb_streams);
2093  if (!vs->streams)
2094  return AVERROR(ENOMEM);
2095 
2096  nb_streams = 0;
2097  while (keyval = av_strtok(varstr, ",", &saveptr2)) {
2098  int64_t num;
2099  char *end;
2100  varstr = NULL;
2101  if (av_strstart(keyval, "language:", &val)) {
2102  vs->language = val;
2103  continue;
2104  } else if (av_strstart(keyval, "default:", &val)) {
2105  vs->is_default = (!av_strncasecmp(val, "YES", strlen("YES")) ||
2106  (!av_strncasecmp(val, "1", strlen("1"))));
2107  hls->has_default_key = 1;
2108  continue;
2109  } else if (av_strstart(keyval, "name:", &val)) {
2110  vs->varname = val;
2111  continue;
2112  } else if (av_strstart(keyval, "agroup:", &val)) {
2113  vs->agroup = val;
2114  continue;
2115  } else if (av_strstart(keyval, "sgroup:", &val)) {
2116  vs->sgroup = val;
2117  continue;
2118  } else if (av_strstart(keyval, "ccgroup:", &val)) {
2119  vs->ccgroup = val;
2120  continue;
2121  } else if (av_strstart(keyval, "v:", &val)) {
2123  hls->has_video_m3u8 = 1;
2124  } else if (av_strstart(keyval, "a:", &val)) {
2126  } else if (av_strstart(keyval, "s:", &val)) {
2128  } else {
2129  av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
2130  return AVERROR(EINVAL);
2131  }
2132 
2133  num = strtoll(val, &end, 10);
2134  if (!av_isdigit(*val) || *end != '\0') {
2135  av_log(s, AV_LOG_ERROR, "Invalid stream number: '%s'\n", val);
2136  return AVERROR(EINVAL);
2137  }
2138  stream_index = get_nth_codec_stream_index(s, codec_type, num);
2139 
2140  if (stream_index >= 0 && nb_streams < vs->nb_streams) {
2141  for (i = 0; nb_streams > 0 && i < nb_streams; i++) {
2142  if (vs->streams[i] == s->streams[stream_index]) {
2143  av_log(s, AV_LOG_ERROR, "Same elementary stream found more than once inside "
2144  "variant definition #%d\n", nb_varstreams - 1);
2145  return AVERROR(EINVAL);
2146  }
2147  }
2148  for (j = 0; nb_varstreams > 1 && j < nb_varstreams - 1; j++) {
2149  for (i = 0; i < hls->var_streams[j].nb_streams; i++) {
2150  if (hls->var_streams[j].streams[i] == s->streams[stream_index]) {
2151  av_log(s, AV_LOG_ERROR, "Same elementary stream found more than once "
2152  "in two different variant definitions #%d and #%d\n",
2153  j, nb_varstreams - 1);
2154  return AVERROR(EINVAL);
2155  }
2156  }
2157  }
2158  vs->streams[nb_streams++] = s->streams[stream_index];
2159  } else {
2160  av_log(s, AV_LOG_ERROR, "Unable to map stream at %s\n", keyval);
2161  return AVERROR(EINVAL);
2162  }
2163  }
2164  }
2165  av_log(s, AV_LOG_DEBUG, "Number of variant streams %d\n",
2166  hls->nb_varstreams);
2167 
2168  return 0;
2169 }
2170 
2172 {
2173  HLSContext *hls = s->priv_data;
2174  int nb_ccstreams = 0;
2175  char *p, *q, *ccstr, *keyval;
2176  char *saveptr1 = NULL, *saveptr2 = NULL;
2177  const char *val;
2178  ClosedCaptionsStream *ccs;
2179 
2180  p = av_strdup(hls->cc_stream_map);
2181  if(!p)
2182  return AVERROR(ENOMEM);
2183 
2184  q = p;
2185  while (av_strtok(q, " \t", &saveptr1)) {
2186  q = NULL;
2187  nb_ccstreams++;
2188  }
2189  av_freep(&p);
2190 
2191  hls->cc_streams = av_mallocz(sizeof(*hls->cc_streams) * nb_ccstreams);
2192  if (!hls->cc_streams)
2193  return AVERROR(ENOMEM);
2194  hls->nb_ccstreams = nb_ccstreams;
2195 
2196  p = hls->cc_stream_map;
2197  nb_ccstreams = 0;
2198  while (ccstr = av_strtok(p, " \t", &saveptr1)) {
2199  p = NULL;
2200 
2201  if (nb_ccstreams < hls->nb_ccstreams)
2202  ccs = &(hls->cc_streams[nb_ccstreams++]);
2203  else
2204  return AVERROR(EINVAL);
2205 
2206  while (keyval = av_strtok(ccstr, ",", &saveptr2)) {
2207  ccstr = NULL;
2208 
2209  if (av_strstart(keyval, "ccgroup:", &val)) {
2210  ccs->ccgroup = val;
2211  } else if (av_strstart(keyval, "instreamid:", &val)) {
2212  ccs->instreamid = val;
2213  } else if (av_strstart(keyval, "language:", &val)) {
2214  ccs->language = val;
2215  } else {
2216  av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
2217  return AVERROR(EINVAL);
2218  }
2219  }
2220 
2221  if (!ccs->ccgroup || !ccs->instreamid) {
2222  av_log(s, AV_LOG_ERROR, "Insufficient parameters in cc stream map string\n");
2223  return AVERROR(EINVAL);
2224  }
2225 
2226  if (av_strstart(ccs->instreamid, "CC", &val)) {
2227  if (atoi(val) < 1 || atoi(val) > 4) {
2228  av_log(s, AV_LOG_ERROR, "Invalid instream ID CC index %d in %s, range 1-4\n",
2229  atoi(val), ccs->instreamid);
2230  return AVERROR(EINVAL);
2231  }
2232  } else if (av_strstart(ccs->instreamid, "SERVICE", &val)) {
2233  if (atoi(val) < 1 || atoi(val) > 63) {
2234  av_log(s, AV_LOG_ERROR, "Invalid instream ID SERVICE index %d in %s, range 1-63 \n",
2235  atoi(val), ccs->instreamid);
2236  return AVERROR(EINVAL);
2237  }
2238  } else {
2239  av_log(s, AV_LOG_ERROR, "Invalid instream ID %s, supported are CCn or SERVICEn\n",
2240  ccs->instreamid);
2241  return AVERROR(EINVAL);
2242  }
2243  }
2244 
2245  return 0;
2246 }
2247 
2249 {
2250  HLSContext *hls = s->priv_data;
2251  unsigned int i;
2252  int ret = 0;
2253 
2254  if (hls->cc_stream_map) {
2256  if (ret < 0)
2257  return ret;
2258  }
2259 
2260  if (hls->var_stream_map) {
2262  } else {
2263  //By default, a single variant stream with all the codec streams is created
2264  hls->var_streams = av_mallocz(sizeof(*hls->var_streams));
2265  if (!hls->var_streams)
2266  return AVERROR(ENOMEM);
2267  hls->nb_varstreams = 1;
2268 
2269  hls->var_streams[0].var_stream_idx = 0;
2270  hls->var_streams[0].nb_streams = s->nb_streams;
2271  hls->var_streams[0].streams = av_mallocz(sizeof(AVStream *) *
2272  hls->var_streams[0].nb_streams);
2273  if (!hls->var_streams[0].streams)
2274  return AVERROR(ENOMEM);
2275 
2276  //by default, the first available ccgroup is mapped to the variant stream
2277  if (hls->nb_ccstreams)
2278  hls->var_streams[0].ccgroup = hls->cc_streams[0].ccgroup;
2279 
2280  for (i = 0; i < s->nb_streams; i++)
2281  hls->var_streams[0].streams[i] = s->streams[i];
2282  }
2283  return 0;
2284 }
2285 
2287 {
2288  HLSContext *hls = s->priv_data;
2289  const char *dir;
2290  char *fn1= NULL, *fn2 = NULL;
2291  int ret = 0;
2292 
2293  fn1 = av_strdup(s->url);
2294  if (!fn1)
2295  return AVERROR(ENOMEM);
2296  dir = av_dirname(fn1);
2297 
2298  /**
2299  * if output file's directory has %v, variants are created in sub-directories
2300  * then master is created at the sub-directories level
2301  */
2302  if (dir && av_stristr(av_basename(dir), "%v")) {
2303  fn2 = av_strdup(dir);
2304  if (!fn2) {
2305  ret = AVERROR(ENOMEM);
2306  goto fail;
2307  }
2308  dir = av_dirname(fn2);
2309  }
2310 
2311  if (dir && strcmp(dir, "."))
2313  else
2315 
2316  if (!hls->master_m3u8_url) {
2317  ret = AVERROR(ENOMEM);
2318  goto fail;
2319  }
2320 
2321 fail:
2322  av_freep(&fn1);
2323  av_freep(&fn2);
2324 
2325  return ret;
2326 }
2327 
2329 {
2330  HLSContext *hls = s->priv_data;
2331  int ret, i, j;
2332  VariantStream *vs = NULL;
2333 
2334  for (i = 0; i < hls->nb_varstreams; i++) {
2335  int subtitle_streams = 0;
2336  vs = &hls->var_streams[i];
2337 
2339  if (ret < 0)
2340  return ret;
2341  //av_assert0(s->nb_streams == hls->avf->nb_streams);
2342  for (j = 0; j < vs->nb_streams; j++) {
2343  AVStream *inner_st;
2344  AVStream *outer_st = vs->streams[j];
2345 
2346  if (hls->max_seg_size > 0) {
2347  if ((outer_st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
2348  (outer_st->codecpar->bit_rate > hls->max_seg_size)) {
2349  av_log(s, AV_LOG_WARNING, "Your video bitrate is bigger than hls_segment_size, "
2350  "(%"PRId64 " > %"PRId64 "), the result maybe not be what you want.",
2351  outer_st->codecpar->bit_rate, hls->max_seg_size);
2352  }
2353  }
2354 
2355  if (outer_st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
2356  inner_st = vs->avf->streams[j - subtitle_streams];
2357  else if (vs->vtt_avf) {
2358  inner_st = vs->vtt_avf->streams[0];
2359  subtitle_streams++;
2360  } else {
2361  /* We have a subtitle stream, when the user does not want one */
2362  inner_st = NULL;
2363  continue;
2364  }
2365  avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
2366  if (outer_st->codecpar->codec_id == AV_CODEC_ID_HEVC &&
2367  outer_st->codecpar->codec_tag != MKTAG('h','v','c','1')) {
2368  av_log(s, AV_LOG_WARNING, "Stream HEVC is not hvc1, you should use tag:v hvc1 to set it.\n");
2369  }
2370  write_codec_attr(outer_st, vs);
2371 
2372  }
2373  /* Update the Codec Attr string for the mapped audio groups */
2374  if (vs->has_video && vs->agroup) {
2375  for (j = 0; j < hls->nb_varstreams; j++) {
2376  VariantStream *vs_agroup = &(hls->var_streams[j]);
2377  if (!vs_agroup->has_video && !vs_agroup->has_subtitle &&
2378  vs_agroup->agroup &&
2379  !av_strcasecmp(vs_agroup->agroup, vs->agroup)) {
2380  write_codec_attr(vs_agroup->streams[0], vs);
2381  }
2382  }
2383  }
2384  }
2385 
2386  return 0;
2387 }
2388 
2390 {
2391  HLSContext *hls = s->priv_data;
2393  int ret = 0;
2394 
2395  set_http_options(s, &options, hls);
2398  if (ret < 0)
2399  return ret;
2401  hlsenc_io_close(s, &vs->out, hls->fmp4_init_filename);
2402 
2403  return ret;
2404 }
2405 
2407 {
2408  int64_t ret = 0;
2409  int64_t read_byte = 0;
2410  int64_t total_size = 0;
2411  char *filename = NULL;
2412  char buf[BUFSIZE];
2413  AVFormatContext *oc = vs->avf;
2414 
2415  hlsenc_io_close(s, &vs->out, vs->basename_tmp);
2416  filename = av_asprintf("%s.tmp", oc->url);
2417  ret = s->io_open(s, &vs->out, filename, AVIO_FLAG_READ, NULL);
2418  if (ret < 0) {
2419  av_free(filename);
2420  return ret;
2421  }
2422 
2423  do {
2424  read_byte = avio_read(vs->out, buf, BUFSIZE);
2425  if (read_byte > 0) {
2426  avio_write(vs->out_single_file, buf, read_byte);
2427  total_size += read_byte;
2428  ret = total_size;
2429  }
2430  } while (read_byte > 0);
2431 
2432  hlsenc_io_close(s, &vs->out, filename);
2433  av_free(filename);
2434 
2435  return ret;
2436 }
2438 {
2439  HLSContext *hls = s->priv_data;
2440  AVFormatContext *oc = NULL;
2441  AVStream *st = s->streams[pkt->stream_index];
2442  int64_t end_pts = 0;
2443  int is_ref_pkt = 1;
2444  int ret = 0, can_split = 1, i, j;
2445  int stream_index = 0;
2446  int range_length = 0;
2447  const char *proto = NULL;
2448  int use_temp_file = 0;
2449  VariantStream *vs = NULL;
2450  char *old_filename = NULL;
2451 
2452  for (i = 0; i < hls->nb_varstreams; i++) {
2453  int subtitle_streams = 0;
2454  vs = &hls->var_streams[i];
2455  for (j = 0; j < vs->nb_streams; j++) {
2457  subtitle_streams++;
2458  }
2459  if (vs->streams[j] == st) {
2461  oc = vs->vtt_avf;
2462  stream_index = 0;
2463  } else {
2464  oc = vs->avf;
2465  stream_index = j - subtitle_streams;
2466  }
2467  break;
2468  }
2469  }
2470 
2471  if (oc)
2472  break;
2473  }
2474 
2475  if (!oc) {
2476  av_log(s, AV_LOG_ERROR, "Unable to find mapping variant stream\n");
2477  return AVERROR(ENOMEM);
2478  }
2479 
2480  end_pts = hls->recording_time * vs->number;
2481 
2482  if (vs->sequence - vs->nb_entries > hls->start_sequence && hls->init_time > 0) {
2483  /* reset end_pts, hls->recording_time at end of the init hls list */
2484  int64_t init_list_dur = hls->init_time * vs->nb_entries;
2485  int64_t after_init_list_dur = (vs->sequence - hls->start_sequence - vs->nb_entries) * hls->time;
2486  hls->recording_time = hls->time;
2487  end_pts = init_list_dur + after_init_list_dur ;
2488  }
2489 
2490  if (vs->start_pts == AV_NOPTS_VALUE) {
2491  vs->start_pts = pkt->pts;
2493  vs->start_pts_from_audio = 1;
2494  }
2496  vs->start_pts = pkt->pts;
2497  vs->start_pts_from_audio = 0;
2498  }
2499 
2500  if (vs->has_video) {
2502  ((pkt->flags & AV_PKT_FLAG_KEY) || (hls->flags & HLS_SPLIT_BY_TIME));
2503  is_ref_pkt = (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->stream_index == vs->reference_stream_index);
2504  }
2505  if (pkt->pts == AV_NOPTS_VALUE)
2506  is_ref_pkt = can_split = 0;
2507 
2508  if (is_ref_pkt) {
2509  if (vs->end_pts == AV_NOPTS_VALUE)
2510  vs->end_pts = pkt->pts;
2511  if (vs->new_start) {
2512  vs->new_start = 0;
2513  vs->duration = (double)(pkt->pts - vs->end_pts)
2514  * st->time_base.num / st->time_base.den;
2515  vs->dpp = (double)(pkt->duration) * st->time_base.num / st->time_base.den;
2516  } else {
2517  if (pkt->duration) {
2518  vs->duration += (double)(pkt->duration) * st->time_base.num / st->time_base.den;
2519  } else {
2520  av_log(s, AV_LOG_WARNING, "Stream %d packet with pts %" PRId64 " has duration 0. The segment duration may not be precise.\n",
2521  pkt->stream_index, pkt->pts);
2522  vs->duration = (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den;
2523  }
2524  }
2525  }
2526 
2527  can_split = can_split && (pkt->pts - vs->end_pts > 0);
2528  if (vs->packets_written && can_split && av_compare_ts(pkt->pts - vs->start_pts, st->time_base,
2529  end_pts, AV_TIME_BASE_Q) >= 0) {
2530  int64_t new_start_pos;
2531  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
2532  double cur_duration;
2533 
2534  av_write_frame(oc, NULL); /* Flush any buffered data */
2535  new_start_pos = avio_tell(oc->pb);
2536  vs->size = new_start_pos - vs->start_pos;
2537  avio_flush(oc->pb);
2538  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2539  if (!vs->init_range_length) {
2540  range_length = avio_close_dyn_buf(oc->pb, &vs->init_buffer);
2541  if (range_length <= 0)
2542  return AVERROR(EINVAL);
2543  avio_write(vs->out, vs->init_buffer, range_length);
2544  if (!hls->resend_init_file)
2545  av_freep(&vs->init_buffer);
2546  vs->init_range_length = range_length;
2547  avio_open_dyn_buf(&oc->pb);
2548  vs->packets_written = 0;
2549  vs->start_pos = range_length;
2550  if (!byterange_mode) {
2552  }
2553  }
2554  }
2555  if (!byterange_mode) {
2556  if (vs->vtt_avf) {
2557  hlsenc_io_close(s, &vs->vtt_avf->pb, vs->vtt_avf->url);
2558  }
2559  }
2560 
2561  if (hls->flags & HLS_SINGLE_FILE) {
2562  ret = flush_dynbuf(vs, &range_length);
2563  av_freep(&vs->temp_buffer);
2564  if (ret < 0) {
2565  return ret;
2566  }
2567  vs->size = range_length;
2568  if (hls->key_info_file || hls->encrypt)
2569  vs->size = append_single_file(s, vs);
2570  } else {
2571  if (oc->url[0]) {
2572  proto = avio_find_protocol_name(oc->url);
2573  use_temp_file = proto && !strcmp(proto, "file")
2574  && (hls->flags & HLS_TEMP_FILE);
2575  }
2576 
2577  if ((hls->max_seg_size > 0 && (vs->size + vs->start_pos >= hls->max_seg_size)) || !byterange_mode) {
2579  char *filename = NULL;
2580  if (hls->key_info_file || hls->encrypt) {
2581  av_dict_set(&options, "encryption_key", vs->key_string, 0);
2582  av_dict_set(&options, "encryption_iv", vs->iv_string, 0);
2583  filename = av_asprintf("crypto:%s", oc->url);
2584  } else {
2585  filename = av_asprintf("%s", oc->url);
2586  }
2587  if (!filename) {
2589  return AVERROR(ENOMEM);
2590  }
2591 
2592  // look to rename the asset name
2593  if (use_temp_file)
2594  av_dict_set(&options, "mpegts_flags", "resend_headers", 0);
2595 
2596  set_http_options(s, &options, hls);
2597 
2598  ret = hlsenc_io_open(s, &vs->out, filename, &options);
2599  if (ret < 0) {
2601  "Failed to open file '%s'\n", filename);
2602  av_freep(&filename);
2604  return hls->ignore_io_errors ? 0 : ret;
2605  }
2606  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2607  write_styp(vs->out);
2608  }
2609  ret = flush_dynbuf(vs, &range_length);
2610  if (ret < 0) {
2611  av_freep(&filename);
2613  return ret;
2614  }
2615  vs->size = range_length;
2616  ret = hlsenc_io_close(s, &vs->out, filename);
2617  if (ret < 0) {
2618  av_log(s, AV_LOG_WARNING, "upload segment failed,"
2619  " will retry with a new http session.\n");
2620  ff_format_io_close(s, &vs->out);
2621  ret = hlsenc_io_open(s, &vs->out, filename, &options);
2622  if (ret >= 0) {
2623  reflush_dynbuf(vs, &range_length);
2624  ret = hlsenc_io_close(s, &vs->out, filename);
2625  }
2626  }
2628  av_freep(&vs->temp_buffer);
2629  av_freep(&filename);
2630  }
2631 
2632  if (use_temp_file)
2633  hls_rename_temp_file(s, oc);
2634  }
2635 
2636  if (ret < 0)
2637  return ret;
2638 
2639  old_filename = av_strdup(oc->url);
2640  if (!old_filename) {
2641  return AVERROR(ENOMEM);
2642  }
2643 
2644  cur_duration = (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den;
2645  ret = hls_append_segment(s, hls, vs, cur_duration, vs->start_pos, vs->size);
2646  vs->end_pts = pkt->pts;
2647  vs->duration = 0;
2648  if (ret < 0) {
2649  av_freep(&old_filename);
2650  return ret;
2651  }
2652 
2653  // if we're building a VOD playlist, skip writing the manifest multiple times, and just wait until the end
2654  if (hls->pl_type != PLAYLIST_TYPE_VOD) {
2655  if ((ret = hls_window(s, 0, vs)) < 0) {
2656  av_log(s, AV_LOG_WARNING, "upload playlist failed, will retry with a new http session.\n");
2657  ff_format_io_close(s, &vs->out);
2658  if ((ret = hls_window(s, 0, vs)) < 0) {
2659  av_freep(&old_filename);
2660  return ret;
2661  }
2662  }
2663  }
2664 
2665  if (hls->resend_init_file && hls->segment_type == SEGMENT_TYPE_FMP4) {
2666  ret = hls_init_file_resend(s, vs);
2667  if (ret < 0) {
2668  av_freep(&old_filename);
2669  return ret;
2670  }
2671  }
2672 
2673  if (hls->flags & HLS_SINGLE_FILE) {
2674  vs->start_pos += vs->size;
2675  if (hls->key_info_file || hls->encrypt)
2676  ret = hls_start(s, vs);
2677  if (hls->segment_type == SEGMENT_TYPE_MPEGTS && oc->oformat->priv_class && oc->priv_data) {
2678  av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0);
2679  }
2680  } else if (hls->max_seg_size > 0) {
2681  if (vs->size + vs->start_pos >= hls->max_seg_size) {
2682  vs->sequence++;
2683  sls_flag_file_rename(hls, vs, old_filename);
2684  ret = hls_start(s, vs);
2685  vs->start_pos = 0;
2686  /* When split segment by byte, the duration is short than hls_time,
2687  * so it is not enough one segment duration as hls_time, */
2688  } else {
2689  vs->start_pos = new_start_pos;
2690  }
2691  } else {
2692  vs->start_pos = 0;
2693  sls_flag_file_rename(hls, vs, old_filename);
2694  ret = hls_start(s, vs);
2695  }
2696  vs->number++;
2697  av_freep(&old_filename);
2698 
2699  if (ret < 0) {
2700  return ret;
2701  }
2702  }
2703 
2704  vs->packets_written++;
2705  if (oc->pb) {
2706  ret = ff_write_chained(oc, stream_index, pkt, s, 0);
2707  vs->video_keyframe_size += pkt->size;
2709  vs->video_keyframe_size = avio_tell(oc->pb);
2710  } else {
2711  vs->video_keyframe_pos = avio_tell(vs->out);
2712  }
2713  if (hls->ignore_io_errors)
2714  ret = 0;
2715  }
2716 
2717  return ret;
2718 }
2719 
2721 {
2722  HLSContext *hls = s->priv_data;
2723  int i = 0;
2724  VariantStream *vs = NULL;
2725 
2726  for (i = 0; i < hls->nb_varstreams; i++) {
2727  vs = &hls->var_streams[i];
2728 
2729  av_freep(&vs->basename);
2732  av_freep(&vs->vtt_basename);
2733  av_freep(&vs->vtt_m3u8_name);
2734 
2737  if (hls->resend_init_file)
2738  av_freep(&vs->init_buffer);
2741  av_freep(&vs->m3u8_name);
2742  av_freep(&vs->streams);
2743  }
2744 
2745  ff_format_io_close(s, &hls->m3u8_out);
2748  av_freep(&hls->key_basename);
2749  av_freep(&hls->var_streams);
2750  av_freep(&hls->cc_streams);
2751  av_freep(&hls->master_m3u8_url);
2752 }
2753 
2755 {
2756  HLSContext *hls = s->priv_data;
2757  AVFormatContext *oc = NULL;
2758  AVFormatContext *vtt_oc = NULL;
2759  char *old_filename = NULL;
2760  const char *proto = NULL;
2761  int use_temp_file = 0;
2762  int i;
2763  int ret = 0;
2764  VariantStream *vs = NULL;
2766  int range_length, byterange_mode;
2767 
2768  for (i = 0; i < hls->nb_varstreams; i++) {
2769  char *filename = NULL;
2770  vs = &hls->var_streams[i];
2771  oc = vs->avf;
2772  vtt_oc = vs->vtt_avf;
2773  old_filename = av_strdup(oc->url);
2774  use_temp_file = 0;
2775 
2776  if (!old_filename) {
2777  return AVERROR(ENOMEM);
2778  }
2779  if (hls->key_info_file || hls->encrypt) {
2780  av_dict_set(&options, "encryption_key", vs->key_string, 0);
2781  av_dict_set(&options, "encryption_iv", vs->iv_string, 0);
2782  filename = av_asprintf("crypto:%s", oc->url);
2783  } else {
2784  filename = av_asprintf("%s", oc->url);
2785  }
2786  if (!filename) {
2788  av_freep(&old_filename);
2789  return AVERROR(ENOMEM);
2790  }
2791 
2792  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2793  int range_length = 0;
2794  if (!vs->init_range_length) {
2795  uint8_t *buffer = NULL;
2796  av_write_frame(oc, NULL); /* Flush any buffered data */
2797 
2798  range_length = avio_close_dyn_buf(oc->pb, &buffer);
2799  avio_write(vs->out, buffer, range_length);
2800  av_freep(&buffer);
2801  vs->init_range_length = range_length;
2802  avio_open_dyn_buf(&oc->pb);
2803  vs->packets_written = 0;
2804  vs->start_pos = range_length;
2805  byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
2806  if (!byterange_mode) {
2807  ff_format_io_close(s, &vs->out);
2809  }
2810  }
2811  }
2812  if (!(hls->flags & HLS_SINGLE_FILE)) {
2813  set_http_options(s, &options, hls);
2814  ret = hlsenc_io_open(s, &vs->out, filename, &options);
2815  if (ret < 0) {
2816  av_log(s, AV_LOG_ERROR, "Failed to open file '%s'\n", oc->url);
2817  goto failed;
2818  }
2819  if (hls->segment_type == SEGMENT_TYPE_FMP4)
2820  write_styp(vs->out);
2821  }
2822  ret = flush_dynbuf(vs, &range_length);
2823  if (ret < 0)
2824  goto failed;
2825 
2826  vs->size = range_length;
2827  ret = hlsenc_io_close(s, &vs->out, filename);
2828  if (ret < 0) {
2829  av_log(s, AV_LOG_WARNING, "upload segment failed, will retry with a new http session.\n");
2830  ff_format_io_close(s, &vs->out);
2831  ret = hlsenc_io_open(s, &vs->out, filename, &options);
2832  if (ret < 0) {
2833  av_log(s, AV_LOG_ERROR, "Failed to open file '%s'\n", oc->url);
2834  goto failed;
2835  }
2836  reflush_dynbuf(vs, &range_length);
2837  ret = hlsenc_io_close(s, &vs->out, filename);
2838  if (ret < 0)
2839  av_log(s, AV_LOG_WARNING, "Failed to upload file '%s' at the end.\n", oc->url);
2840  }
2841  if (hls->flags & HLS_SINGLE_FILE) {
2842  if (hls->key_info_file || hls->encrypt) {
2843  vs->size = append_single_file(s, vs);
2844  }
2846  }
2847 failed:
2848  av_freep(&vs->temp_buffer);
2850  av_freep(&filename);
2851  av_write_trailer(oc);
2852  if (oc->url[0]) {
2853  proto = avio_find_protocol_name(oc->url);
2854  use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & HLS_TEMP_FILE);
2855  }
2856 
2857  // rename that segment from .tmp to the real one
2858  if (use_temp_file && !(hls->flags & HLS_SINGLE_FILE)) {
2859  hls_rename_temp_file(s, oc);
2860  av_freep(&old_filename);
2861  old_filename = av_strdup(oc->url);
2862 
2863  if (!old_filename) {
2864  return AVERROR(ENOMEM);
2865  }
2866  }
2867 
2868  /* after av_write_trailer, then duration + 1 duration per packet */
2869  hls_append_segment(s, hls, vs, vs->duration + vs->dpp, vs->start_pos, vs->size);
2870 
2871  sls_flag_file_rename(hls, vs, old_filename);
2872 
2873  if (vtt_oc) {
2874  if (vtt_oc->pb)
2875  av_write_trailer(vtt_oc);
2876  vs->size = avio_tell(vs->vtt_avf->pb) - vs->start_pos;
2877  ff_format_io_close(s, &vtt_oc->pb);
2878  }
2879  ret = hls_window(s, 1, vs);
2880  if (ret < 0) {
2881  av_log(s, AV_LOG_WARNING, "upload playlist failed, will retry with a new http session.\n");
2882  ff_format_io_close(s, &vs->out);
2883  hls_window(s, 1, vs);
2884  }
2885  ffio_free_dyn_buf(&oc->pb);
2886 
2887  av_free(old_filename);
2888  }
2889 
2890  return 0;
2891 }
2892 
2893 
2895 {
2896  int ret = 0;
2897  int i = 0;
2898  int j = 0;
2899  HLSContext *hls = s->priv_data;
2900  const char *pattern;
2901  VariantStream *vs = NULL;
2902  const char *vtt_pattern = hls->flags & HLS_SINGLE_FILE ? ".vtt" : "%d.vtt";
2903  char *p = NULL;
2904  int http_base_proto = ff_is_http_proto(s->url);
2905  int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
2906  double initial_program_date_time = av_gettime() / 1000000.0;
2907 
2908  if (hls->use_localtime) {
2910  } else {
2911  pattern = hls->segment_type == SEGMENT_TYPE_FMP4 ? "%d.m4s" : "%d.ts";
2912  if (hls->flags & HLS_SINGLE_FILE)
2913  pattern += 2;
2914  }
2915 
2916  hls->has_default_key = 0;
2917  hls->has_video_m3u8 = 0;
2919  if (ret < 0) {
2920  av_log(s, AV_LOG_ERROR, "Variant stream info update failed with status %x\n",
2921  ret);
2922  return ret;
2923  }
2924 
2925  if (!hls->method && http_base_proto) {
2926  av_log(hls, AV_LOG_WARNING, "No HTTP method set, hls muxer defaulting to method PUT.\n");
2927  }
2928 
2929  ret = validate_name(hls->nb_varstreams, s->url);
2930  if (ret < 0)
2931  return ret;
2932 
2933  if (hls->segment_filename) {
2935  if (ret < 0)
2936  return ret;
2937  }
2938 
2939  if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
2941  if (ret < 0)
2942  return ret;
2943  }
2944 
2945  if (hls->subtitle_filename) {
2947  if (ret < 0)
2948  return ret;
2949  }
2950 
2951  if (hls->master_pl_name) {
2953  if (ret < 0) {
2954  av_log(s, AV_LOG_ERROR, "Master stream info update failed with status %x\n",
2955  ret);
2956  return ret;
2957  }
2958  }
2959 
2963  time_t t = time(NULL);
2965  hls->start_sequence = av_gettime();
2967  hls->start_sequence = (int64_t)t;
2969  char b[15];
2970  struct tm *p, tmbuf;
2971  if (!(p = localtime_r(&t, &tmbuf)))
2972  return AVERROR(errno);
2973  if (!strftime(b, sizeof(b), "%Y%m%d%H%M%S", p))
2974  return AVERROR(ENOMEM);
2975  hls->start_sequence = strtoll(b, NULL, 10);
2976  }
2977  av_log(hls, AV_LOG_DEBUG, "start_number evaluated to %"PRId64"\n", hls->start_sequence);
2978  }
2979 
2980  hls->recording_time = hls->init_time && hls->max_nb_segments > 0 ? hls->init_time : hls->time;
2981 
2982  if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
2983  // Independent segments cannot be guaranteed when splitting by time
2986  "'split_by_time' and 'independent_segments' cannot be "
2987  "enabled together. Disabling 'independent_segments' flag\n");
2988  }
2989 
2990  for (i = 0; i < hls->nb_varstreams; i++) {
2991  vs = &hls->var_streams[i];
2992 
2993  ret = format_name(s->url, &vs->m3u8_name, i, vs->varname);
2994  if (ret < 0)
2995  return ret;
2996 
2997  vs->sequence = hls->start_sequence;
2998  vs->start_pts = AV_NOPTS_VALUE;
2999  vs->end_pts = AV_NOPTS_VALUE;
3000  vs->current_segment_final_filename_fmt[0] = '\0';
3001  vs->initial_prog_date_time = initial_program_date_time;
3002 
3003  for (j = 0; j < vs->nb_streams; j++) {
3005  /* Get one video stream to reference for split segments
3006  * so use the first video stream index. */
3007  if ((vs->has_video == 1) && (vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)) {
3008  vs->reference_stream_index = vs->streams[j]->index;
3009  }
3011  }
3012 
3013  if (vs->has_video > 1)
3014  av_log(s, AV_LOG_WARNING, "More than a single video stream present, expect issues decoding it.\n");
3015  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
3016  vs->oformat = av_guess_format("mp4", NULL, NULL);
3017  } else {
3018  vs->oformat = av_guess_format("mpegts", NULL, NULL);
3019  }
3020  if (!vs->oformat)
3021  return AVERROR_MUXER_NOT_FOUND;
3022 
3023  if (hls->segment_filename) {
3024  ret = format_name(hls->segment_filename, &vs->basename, i, vs->varname);
3025  if (ret < 0)
3026  return ret;
3027  } else {
3028  p = strrchr(vs->m3u8_name, '.');
3029  if (p)
3030  *p = '\0';
3031 
3032  vs->basename = av_asprintf("%s%s", vs->m3u8_name, pattern);
3033  if (!vs->basename)
3034  return AVERROR(ENOMEM);
3035 
3036  if (p)
3037  *p = '.';
3038  }
3039 
3040  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
3041  if (hls->nb_varstreams > 1)
3042  fmp4_init_filename_len += strlen(POSTFIX_PATTERN);
3043  if (hls->flags & HLS_SINGLE_FILE) {
3045  if (!vs->fmp4_init_filename)
3046  return AVERROR(ENOMEM);
3047  } else {
3048  vs->fmp4_init_filename = av_malloc(fmp4_init_filename_len);
3049  if (!vs->fmp4_init_filename)
3050  return AVERROR(ENOMEM);
3052  fmp4_init_filename_len);
3053  if (hls->nb_varstreams > 1) {
3054  if (av_stristr(vs->fmp4_init_filename, "%v")) {
3057  &vs->fmp4_init_filename, i, vs->varname);
3058  } else {
3059  ret = append_postfix(vs->fmp4_init_filename, fmp4_init_filename_len, i);
3060  }
3061  if (ret < 0)
3062  return ret;
3063  }
3064 
3065  if (hls->use_localtime) {
3066  int r;
3067  char *expanded = NULL;
3068 
3069  r = strftime_expand(vs->fmp4_init_filename, &expanded);
3070  if (r < 0) {
3071  av_log(s, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
3072  return r;
3073  }
3075  vs->fmp4_init_filename = expanded;
3076  }
3077 
3078  p = strrchr(vs->m3u8_name, '/');
3079  if (p) {
3080  char tmp = *(++p);
3081  *p = '\0';
3082  vs->base_output_dirname = av_asprintf("%s%s", vs->m3u8_name,
3083  vs->fmp4_init_filename);
3084  *p = tmp;
3085  } else {
3087  }
3088  if (!vs->base_output_dirname)
3089  return AVERROR(ENOMEM);
3090  }
3091  }
3092 
3094  if (ret < 0)
3095  return ret;
3096 
3097  if (vs->has_subtitle) {
3098  vs->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
3099  if (!vs->vtt_oformat)
3100  return AVERROR_MUXER_NOT_FOUND;
3101 
3102  p = strrchr(vs->m3u8_name, '.');
3103  if (p)
3104  *p = '\0';
3105 
3106  vs->vtt_basename = av_asprintf("%s%s", vs->m3u8_name, vtt_pattern);
3107  if (!vs->vtt_basename)
3108  return AVERROR(ENOMEM);
3109 
3110  if (hls->subtitle_filename) {
3112  if (ret < 0)
3113  return ret;
3114  } else {
3115  vs->vtt_m3u8_name = av_asprintf("%s_vtt.m3u8", vs->m3u8_name);
3116  if (!vs->vtt_m3u8_name)
3117  return AVERROR(ENOMEM);
3118  }
3119  if (p)
3120  *p = '.';
3121  }
3122 
3123  if ((ret = hls_mux_init(s, vs)) < 0)
3124  return ret;
3125 
3126  if (hls->flags & HLS_APPEND_LIST) {
3127  parse_playlist(s, vs->m3u8_name, vs);
3128  vs->discontinuity = 1;
3129  if (hls->init_time > 0) {
3130  av_log(s, AV_LOG_WARNING, "append_list mode does not support hls_init_time,"
3131  " hls_init_time value will have no effect\n");
3132  hls->init_time = 0;
3133  hls->recording_time = hls->time;
3134  }
3135  }
3136 
3137  if ((ret = hls_start(s, vs)) < 0)
3138  return ret;
3139  vs->number++;
3140  }
3141 
3142  return ret;
3143 }
3144 
3145 #define OFFSET(x) offsetof(HLSContext, x)
3146 #define E AV_OPT_FLAG_ENCODING_PARAM
3147 static const AVOption options[] = {
3148  {"start_number", "set first number in the sequence", OFFSET(start_sequence),AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E},
3149  {"hls_time", "set segment length", OFFSET(time), AV_OPT_TYPE_DURATION, {.i64 = 2000000}, 0, INT64_MAX, E},
3150  {"hls_init_time", "set segment length at init list", OFFSET(init_time), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, E},
3151  {"hls_list_size", "set maximum number of playlist entries", OFFSET(max_nb_segments), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E},
3152  {"hls_delete_threshold", "set number of unreferenced segments to keep before deleting", OFFSET(hls_delete_threshold), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, E},
3153  {"hls_vtt_options","set hls vtt list of options for the container format used for hls", OFFSET(vtt_format_options_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3154  {"hls_allow_cache", "explicitly set whether the client MAY (1) or MUST NOT (0) cache media segments", OFFSET(allowcache), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, E},
3155  {"hls_base_url", "url to prepend to each playlist entry", OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3156  {"hls_segment_filename", "filename template for segment files", OFFSET(segment_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3157  {"hls_segment_options","set segments files format options of hls", OFFSET(format_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E},
3158  {"hls_segment_size", "maximum size per segment file, (in bytes)", OFFSET(max_seg_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E},
3159  {"hls_key_info_file", "file with key URI and key file path", OFFSET(key_info_file), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3160  {"hls_enc", "enable AES128 encryption support", OFFSET(encrypt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E},
3161  {"hls_enc_key", "hex-coded 16 byte key to encrypt the segments", OFFSET(key), AV_OPT_TYPE_STRING, .flags = E},
3162  {"hls_enc_key_url", "url to access the key to decrypt the segments", OFFSET(key_url), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3163  {"hls_enc_iv", "hex-coded 16 byte initialization vector", OFFSET(iv), AV_OPT_TYPE_STRING, .flags = E},
3164  {"hls_subtitle_path", "set path of hls subtitles", OFFSET(subtitle_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3165  {"hls_segment_type", "set hls segment files type", OFFSET(segment_type), AV_OPT_TYPE_INT, {.i64 = SEGMENT_TYPE_MPEGTS }, 0, SEGMENT_TYPE_FMP4, E, .unit = "segment_type"},
3166  {"mpegts", "make segment file to mpegts files in m3u8", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_MPEGTS }, 0, UINT_MAX, E, .unit = "segment_type"},
3167  {"fmp4", "make segment file to fragment mp4 files in m3u8", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_FMP4 }, 0, UINT_MAX, E, .unit = "segment_type"},
3168  {"hls_fmp4_init_filename", "set fragment mp4 file init filename", OFFSET(fmp4_init_filename), AV_OPT_TYPE_STRING, {.str = "init.mp4"}, 0, 0, E},
3169  {"hls_fmp4_init_resend", "resend fragment mp4 init file after refresh m3u8 every time", OFFSET(resend_init_file), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
3170  {"hls_flags", "set flags affecting HLS playlist and media file generation", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, 0, UINT_MAX, E, .unit = "flags"},
3171  {"single_file", "generate a single media file indexed with byte ranges", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SINGLE_FILE }, 0, UINT_MAX, E, .unit = "flags"},
3172  {"temp_file", "write segment and playlist to temporary file and rename when complete", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_TEMP_FILE }, 0, UINT_MAX, E, .unit = "flags"},
3173  {"delete_segments", "delete segment files that are no longer part of the playlist", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DELETE_SEGMENTS }, 0, UINT_MAX, E, .unit = "flags"},
3174  {"round_durations", "round durations in m3u8 to whole numbers", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_ROUND_DURATIONS }, 0, UINT_MAX, E, .unit = "flags"},
3175  {"discont_start", "start the playlist with a discontinuity tag", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DISCONT_START }, 0, UINT_MAX, E, .unit = "flags"},
3176  {"omit_endlist", "Do not append an endlist when ending stream", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_OMIT_ENDLIST }, 0, UINT_MAX, E, .unit = "flags"},
3177  {"split_by_time", "split the hls segment by time which user set by hls_time", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SPLIT_BY_TIME }, 0, UINT_MAX, E, .unit = "flags"},
3178  {"append_list", "append the new segments into old hls segment list", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_APPEND_LIST }, 0, UINT_MAX, E, .unit = "flags"},
3179  {"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX, E, .unit = "flags"},
3180  {"second_level_segment_index", "include segment index in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_INDEX }, 0, UINT_MAX, E, .unit = "flags"},
3181  {"second_level_segment_duration", "include segment duration in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_DURATION }, 0, UINT_MAX, E, .unit = "flags"},
3182  {"second_level_segment_size", "include segment size in segment filenames when use_localtime", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SECOND_LEVEL_SEGMENT_SIZE }, 0, UINT_MAX, E, .unit = "flags"},
3183  {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, .unit = "flags"},
3184  {"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, .unit = "flags"},
3185  {"iframes_only", "add EXT-X-I-FRAMES-ONLY, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_I_FRAMES_ONLY }, 0, UINT_MAX, E, .unit = "flags"},
3186  {"strftime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
3187  {"strftime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
3188  {"hls_playlist_type", "set the HLS playlist type", OFFSET(pl_type), AV_OPT_TYPE_INT, {.i64 = PLAYLIST_TYPE_NONE }, 0, PLAYLIST_TYPE_NB-1, E, .unit = "pl_type" },
3189  {"event", "EVENT playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_EVENT }, INT_MIN, INT_MAX, E, .unit = "pl_type" },
3190  {"vod", "VOD playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_VOD }, INT_MIN, INT_MAX, E, .unit = "pl_type" },
3191  {"method", "set the HTTP method(default: PUT)", OFFSET(method), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3192  {"hls_start_number_source", "set source of first number in sequence", OFFSET(start_sequence_source_type), AV_OPT_TYPE_INT, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, 0, HLS_START_SEQUENCE_LAST-1, E, .unit = "start_sequence_source_type" },
3193  {"generic", "start_number value (default)", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, INT_MIN, INT_MAX, E, .unit = "start_sequence_source_type" },
3194  {"epoch", "seconds since epoch", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH }, INT_MIN, INT_MAX, E, .unit = "start_sequence_source_type" },
3195  {"epoch_us", "microseconds since epoch", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_MICROSECONDS_SINCE_EPOCH }, INT_MIN, INT_MAX, E, .unit = "start_sequence_source_type" },
3196  {"datetime", "current datetime as YYYYMMDDhhmmss", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_FORMATTED_DATETIME }, INT_MIN, INT_MAX, E, .unit = "start_sequence_source_type" },
3197  {"http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3198  {"var_stream_map", "Variant stream map string", OFFSET(var_stream_map), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3199  {"cc_stream_map", "Closed captions stream map string", OFFSET(cc_stream_map), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3200  {"master_pl_name", "Create HLS master playlist with this name", OFFSET(master_pl_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
3201  {"master_pl_publish_rate", "Publish master play list every after this many segment intervals", OFFSET(master_publish_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT_MAX, E},
3202  {"http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
3203  {"timeout", "set timeout for socket I/O operations", OFFSET(timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E },
3204  {"ignore_io_errors", "Ignore IO errors for stable long-duration runs with network output", OFFSET(ignore_io_errors), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
3205  {"headers", "set custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
3206  { NULL },
3207 };
3208 
3209 static const AVClass hls_class = {
3210  .class_name = "hls muxer",
3211  .item_name = av_default_item_name,
3212  .option = options,
3213  .version = LIBAVUTIL_VERSION_INT,
3214 };
3215 
3216 
3218  .p.name = "hls",
3219  .p.long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
3220  .p.extensions = "m3u8",
3221  .p.audio_codec = AV_CODEC_ID_AAC,
3222  .p.video_codec = AV_CODEC_ID_H264,
3223  .p.subtitle_codec = AV_CODEC_ID_WEBVTT,
3224 #if FF_API_ALLOW_FLUSH
3225  .p.flags = AVFMT_NOFILE | AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_NODIMENSIONS,
3226 #else
3228 #endif
3229  .p.priv_class = &hls_class,
3230  .flags_internal = FF_OFMT_FLAG_ALLOW_FLUSH,
3231  .priv_data_size = sizeof(HLSContext),
3232  .init = hls_init,
3236  .deinit = hls_deinit,
3237 };
M
#define M(a, b)
Definition: vp3dsp.c:48
ff_get_chomp_line
int ff_get_chomp_line(AVIOContext *s, char *buf, int maxlen)
Same as ff_get_line but strip the white-space characters in the text tail.
Definition: aviobuf.c:786
VariantStream::vtt_avf
AVFormatContext * vtt_avf
Definition: hlsenc.c:133
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
hls_write_header
static int hls_write_header(AVFormatContext *s)
Definition: hlsenc.c:2328
av_codec_get_id
enum AVCodecID av_codec_get_id(const struct AVCodecTag *const *tags, unsigned int tag)
Get the AVCodecID for the given codec tag tag.
ffio_open_whitelist
int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist)
Definition: avio.c:471
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
get_relative_url
static const char * get_relative_url(const char *master_url, const char *media_url)
Definition: hlsenc.c:1346
name
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 default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
find_segment_by_filename
static HLSSegment * find_segment_by_filename(HLSSegment *segment, const char *filename)
Definition: hlsenc.c:962
append_postfix
static int append_postfix(char *name, int name_buf_len, int i)
Definition: hlsenc.c:1911
level
uint8_t level
Definition: svq3.c:205
AV_CODEC_ID_AC3
@ AV_CODEC_ID_AC3
Definition: codec_id.h:443
HLSContext::timeout
int64_t timeout
Definition: hlsenc.c:260
sls_flag_use_localtime_filename
static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c, VariantStream *vs)
Definition: hlsenc.c:1062
HLS_TEMP_FILE
@ HLS_TEMP_FILE
Definition: hlsenc.c:108
AVOutputFormat::name
const char * name
Definition: avformat.h:510
av_bprint_is_complete
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:218
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
strftime_expand
static int strftime_expand(const char *fmt, char **dest)
Definition: hlsenc.c:267
VariantStream::has_subtitle
int has_subtitle
Definition: hlsenc.c:136
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
HLSContext::resend_init_file
int resend_init_file
resend init file into disk after refresh m3u8
Definition: hlsenc.c:214
HLSContext::hls_delete_threshold
int hls_delete_threshold
Definition: hlsenc.c:208
av_compare_ts
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
Compare two timestamps each in its own time base.
Definition: mathematics.c:147
AVFMT_NODIMENSIONS
#define AVFMT_NODIMENSIONS
Format does not need width/height.
Definition: avformat.h:483
VariantStream::codec_attr
char codec_attr[128]
Definition: hlsenc.c:182
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:124
HLSContext::key_file
char key_file[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:235
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ff_hls_write_end_list
void ff_hls_write_end_list(AVIOContext *out)
Definition: hlsplaylist.c:196
hls_init_file_resend
static int hls_init_file_resend(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:2389
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
HLSSegment::filename
char filename[MAX_URL_SIZE]
Definition: hlsenc.c:78
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
av_dict_count
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition: dict.c:39
fn1
#define fn1(name, depth)
Definition: blend_modes.c:85
PLAYLIST_TYPE_VOD
@ PLAYLIST_TYPE_VOD
Definition: hlsplaylist.h:34
VariantStream::key_uri
char key_uri[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:177
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
int64_t
long long int64_t
Definition: coverity.c:34
VariantStream::init_range_length
int init_range_length
Definition: hlsenc.c:128
av_asprintf
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:115
av_strcasecmp
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:207
write_styp
static void write_styp(AVIOContext *pb)
Definition: hlsenc.c:542
VariantStream::var_stream_idx
unsigned var_stream_idx
Definition: hlsenc.c:120
HLSContext::cc_stream_map
char * cc_stream_map
Definition: hlsenc.c:253
PLAYLIST_TYPE_EVENT
@ PLAYLIST_TYPE_EVENT
Definition: hlsplaylist.h:33
HLS_APPEND_LIST
@ HLS_APPEND_LIST
Definition: hlsenc.c:103
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1355
deinit
static void deinit(AVFormatContext *s)
Definition: chromaprint.c:52
create_master_playlist
static int create_master_playlist(AVFormatContext *s, VariantStream *const input_vs, int final)
Definition: hlsenc.c:1383
AVPacketSideData
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition: packet.h:390
HLS_SECOND_LEVEL_SEGMENT_INDEX
@ HLS_SECOND_LEVEL_SEGMENT_INDEX
Definition: hlsenc.c:105
HLS_DELETE_SEGMENTS
@ HLS_DELETE_SEGMENTS
Definition: hlsenc.c:98
AVFormatContext::strict_std_compliance
int strict_std_compliance
Allow non-standard and experimental extension.
Definition: avformat.h:1644
HLSContext::ignore_io_errors
int ignore_io_errors
Definition: hlsenc.c:261
KEYSIZE
#define KEYSIZE
Definition: hlsenc.c:71
HLS_MICROSECOND_UNIT
#define HLS_MICROSECOND_UNIT
Definition: hlsenc.c:73
ClosedCaptionsStream
Definition: hlsenc.c:194
AVOption
AVOption.
Definition: opt.h:429
HLS_START_SEQUENCE_AS_MICROSECONDS_SINCE_EPOCH
@ HLS_START_SEQUENCE_AS_MICROSECONDS_SINCE_EPOCH
Definition: hlsenc.c:62
b
#define b
Definition: input.c:41
data
const char data[16]
Definition: mxf.c:148
HLS_INDEPENDENT_SEGMENTS
@ HLS_INDEPENDENT_SEGMENTS
Definition: hlsenc.c:110
HLS_OMIT_ENDLIST
@ HLS_OMIT_ENDLIST
Definition: hlsenc.c:101
HLSContext::iv
char * iv
Definition: hlsenc.c:230
VariantStream::iv_string
char iv_string[KEYSIZE *2+1]
Definition: hlsenc.c:179
AV_OPT_TYPE_DURATION
@ AV_OPT_TYPE_DURATION
Underlying C type is int64_t.
Definition: opt.h:319
AV_DICT_APPEND
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition: dict.h:82
VariantStream::total_duration
double total_duration
Definition: hlsenc.c:154
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
VariantStream::start_pts
int64_t start_pts
Definition: hlsenc.c:140
HLSContext::nb_ccstreams
unsigned int nb_ccstreams
Definition: hlsenc.c:247
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:557
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
PLAYLIST_TYPE_NONE
@ PLAYLIST_TYPE_NONE
Definition: hlsplaylist.h:32
mathematics.h
AVDictionary
Definition: dict.c:34
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
BUFSIZE
#define BUFSIZE
Definition: hlsenc.c:74
avformat_init_output
av_warn_unused_result int avformat_init_output(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and initialize the codec, but do not write the header.
Definition: mux.c:466
hls_write_trailer
static int hls_write_trailer(struct AVFormatContext *s)
Definition: hlsenc.c:2754
get_nth_codec_stream_index
static int get_nth_codec_stream_index(AVFormatContext *s, enum AVMediaType codec_type, int64_t stream_id)
Definition: hlsenc.c:2010
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:321
LINE_BUFFER_SIZE
#define LINE_BUFFER_SIZE
Definition: hlsenc.c:72
codec_type
enum AVMediaType codec_type
Definition: rtp.c:37
E
#define E
Definition: hlsenc.c:3146
os_support.h
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:594
update_variant_stream_info
static int update_variant_stream_info(AVFormatContext *s)
Definition: hlsenc.c:2248
av_basename
const char * av_basename(const char *path)
Thread safe basename.
Definition: avstring.c:252
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:429
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
hlsplaylist.h
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
HLSContext::allowcache
int allowcache
Definition: hlsenc.c:218
HLSContext::user_agent
char * user_agent
Definition: hlsenc.c:242
sls_flag_check_duration_size
static int sls_flag_check_duration_size(HLSContext *hls, VariantStream *vs)
Definition: hlsenc.c:1035
av_append_path_component
char * av_append_path_component(const char *path, const char *component)
Append path component to the existing path.
Definition: avstring.c:296
VariantStream::key_file
char key_file[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:176
HLSSegment::duration
double duration
Definition: hlsenc.c:80
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1560
do_encrypt
static int do_encrypt(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:713
HLSContext::use_localtime
int use_localtime
flag to expand filename with localtime
Definition: hlsenc.c:216
SEGMENT_TYPE_FMP4
@ SEGMENT_TYPE_FMP4
Definition: hlsenc.c:116
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:860
ff_hls_write_playlist_header
void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache, int target_duration, int64_t sequence, uint32_t playlist_type, int iframe_mode)
Definition: hlsplaylist.c:105
segment::duration
int64_t duration
Definition: hls.c:78
fail
#define fail()
Definition: checkasm.h:188
ff_hls_muxer
const FFOutputFormat ff_hls_muxer
Definition: hlsenc.c:3217
sls_flags_filename_process
static int sls_flags_filename_process(struct AVFormatContext *s, HLSContext *hls, VariantStream *vs, HLSSegment *en, double duration, int64_t pos, int64_t size)
Definition: hlsenc.c:972
hls_start
static int hls_start(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:1705
hls_delete_file
static int hls_delete_file(HLSContext *hls, AVFormatContext *avf, char *path, const char *proto)
Definition: hlsenc.c:579
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
val
static double val(void *priv, double ch)
Definition: aeval.c:77
VariantStream::oformat
const AVOutputFormat * oformat
Definition: hlsenc.c:123
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:748
VariantStream::start_pts_from_audio
int start_pts_from_audio
Definition: hlsenc.c:138
AV_CODEC_ID_MP3
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: codec_id.h:441
ff_rename
int ff_rename(const char *url_src, const char *url_dst, void *logctx)
Wrap ffurl_move() and log if error happens.
Definition: avio.c:861
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
HLS_PERIODIC_REKEY
@ HLS_PERIODIC_REKEY
Definition: hlsenc.c:109
av_dirname
const char * av_dirname(char *path)
Thread safe dirname.
Definition: avstring.c:275
sls_flag_file_rename
static void sls_flag_file_rename(HLSContext *hls, VariantStream *vs, char *old_filename)
Definition: hlsenc.c:1055
HLS_ROUND_DURATIONS
@ HLS_ROUND_DURATIONS
Definition: hlsenc.c:99
HLSContext::use_localtime_mkdir
int use_localtime_mkdir
flag to mkdir dirname in timebased filename
Definition: hlsenc.c:217
avio_close_dyn_buf
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1407
avassert.h
lrint
#define lrint
Definition: tablegen.h:53
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:180
AVFormatContext::metadata
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1522
get_stream_bit_rate
static int64_t get_stream_bit_rate(AVStream *stream)
Definition: hlsenc.c:1366
HLSSegment::keyframe_pos
int64_t keyframe_pos
Definition: hlsenc.c:84
HLSSegment::discont
int discont
Definition: hlsenc.c:81
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
VariantStream::avg_bitrate
int64_t avg_bitrate
Definition: hlsenc.c:155
ff_hls_write_subtitle_rendition
void ff_hls_write_subtitle_rendition(AVIOContext *out, const char *sgroup, const char *filename, const char *language, int name_id, int is_default)
Definition: hlsplaylist.c:58
HLSContext::key_basename
char * key_basename
Definition: hlsenc.c:231
HLSContext::m3u8_out
AVIOContext * m3u8_out
Definition: hlsenc.c:257
duration
int64_t duration
Definition: movenc.c:65
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1362
HLSContext::encrypt_started
int encrypt_started
Definition: hlsenc.c:232
HLSSegment::next
struct HLSSegment * next
Definition: hlsenc.c:91
validate_name
static int validate_name(int nb_vs, const char *fn)
Definition: hlsenc.c:1930
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
HLSContext::method
char * method
Definition: hlsenc.c:241
set_http_options
static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSContext *c)
Definition: hlsenc.c:331
CODEC_ATTRIBUTE_WRITTEN
@ CODEC_ATTRIBUTE_WRITTEN
Definition: hlsenc.c:67
VariantStream::vtt_oformat
const AVOutputFormat * vtt_oformat
Definition: hlsenc.c:124
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
HLSContext::has_default_key
int has_default_key
Definition: hlsenc.c:263
AV_CODEC_ID_MP2
@ AV_CODEC_ID_MP2
Definition: codec_id.h:440
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
flush_dynbuf
static int flush_dynbuf(VariantStream *vs, int *range_length)
Definition: hlsenc.c:552
hls_deinit
static void hls_deinit(AVFormatContext *s)
Definition: hlsenc.c:2720
HLS_SECOND_LEVEL_SEGMENT_SIZE
@ HLS_SECOND_LEVEL_SEGMENT_SIZE
Definition: hlsenc.c:107
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Underlying C type is int64_t.
Definition: opt.h:263
VariantStream::has_video
int has_video
Definition: hlsenc.c:135
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:618
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
AVPacketSideData::data
uint8_t * data
Definition: packet.h:391
VariantStream::language
const char * language
Definition: hlsenc.c:187
ctx
AVFormatContext * ctx
Definition: movenc.c:49
nb_streams
static int nb_streams
Definition: ffprobe.c:384
HLSContext::time
int64_t time
Definition: hlsenc.c:205
HLSContext::key_url
char * key_url
Definition: hlsenc.c:229
AVOutputFormat::codec_tag
const struct AVCodecTag *const * codec_tag
List of supported codec_id-codec_tag pairs, ordered by "better choice first".
Definition: avformat.h:535
av_stristart
int av_stristart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str independent of case.
Definition: avstring.c:47
AVFormatContext::opaque
void * opaque
User data.
Definition: avformat.h:1849
VariantStream::key_string
char key_string[KEYSIZE *2+1]
Definition: hlsenc.c:178
key
const char * key
Definition: hwcontext_opencl.c:189
AVCodecParameters::nb_coded_side_data
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition: codec_par.h:86
AVCPBProperties
This structure describes the bitrate properties of an encoded bitstream.
Definition: defs.h:271
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
avformat_write_header
av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and write the stream header to an output media file.
Definition: mux.c:487
VariantStream::attr_status
CodecAttributeStatus attr_status
Definition: hlsenc.c:183
VariantStream::video_lastpos
int64_t video_lastpos
Definition: hlsenc.c:142
VariantStream::reference_stream_index
int reference_stream_index
Definition: hlsenc.c:151
VariantStream::base_output_dirname
char * base_output_dirname
Definition: hlsenc.c:172
VariantStream::segments
HLSSegment * segments
Definition: hlsenc.c:158
write_codec_attr
static void write_codec_attr(AVStream *st, VariantStream *vs)
Definition: hlsenc.c:350
time_internal.h
ff_http_do_new_request
int ff_http_do_new_request(URLContext *h, const char *uri)
Send a new HTTP request, reusing the old connection.
Definition: http.c:476
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:223
AV_CODEC_ID_WEBVTT
@ AV_CODEC_ID_WEBVTT
Definition: codec_id.h:568
AVFormatContext
Format I/O context.
Definition: avformat.h:1287
VariantStream::video_keyframe_pos
int64_t video_keyframe_pos
Definition: hlsenc.c:143
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:771
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
replace_str_data_in_filename
static int replace_str_data_in_filename(char **s, const char *filename, char placeholder, const char *datastring)
Definition: hlsenc.c:454
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
reflush_dynbuf
static void reflush_dynbuf(VariantStream *vs, int *range_length)
Definition: hlsenc.c:573
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
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
StartSequenceSourceType
StartSequenceSourceType
Definition: hlsenc.c:58
VariantStream::m3u8_name
char * m3u8_name
Definition: hlsenc.c:166
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:101
VariantStream::new_start
int new_start
Definition: hlsenc.c:137
HLS_PROGRAM_DATE_TIME
@ HLS_PROGRAM_DATE_TIME
Definition: hlsenc.c:104
AV_LEVEL_UNKNOWN
#define AV_LEVEL_UNKNOWN
Definition: defs.h:198
HLSSegment::sub_filename
char sub_filename[MAX_URL_SIZE]
Definition: hlsenc.c:79
ff_nal_unit_extract_rbsp
uint8_t * ff_nal_unit_extract_rbsp(const uint8_t *src, uint32_t src_len, uint32_t *dst_len, int header_len)
Definition: nal.c:160
HLSSegment::iv_string
char iv_string[KEYSIZE *2+1]
Definition: hlsenc.c:89
period
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 default minimum maximum flags name is the option keep it simple and lowercase description are in without period
Definition: writing_filters.txt:89
HLSSegment::key_uri
char key_uri[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:88
HLSContext::vtt_format_options_str
char * vtt_format_options_str
Definition: hlsenc.c:223
HLSContext::http_delete
AVIOContext * http_delete
Definition: hlsenc.c:259
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
ffurl_shutdown
int ffurl_shutdown(URLContext *h, int flags)
Signal the URLContext that we are done reading or writing the stream.
Definition: avio.c:847
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1329
avc.h
HLS_START_SEQUENCE_LAST
@ HLS_START_SEQUENCE_LAST
Definition: hlsenc.c:63
hlsenc_io_open
static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, const char *filename, AVDictionary **options)
Definition: hlsenc.c:290
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:828
FFOutputFormat
Definition: mux.h:61
double
double
Definition: af_crystalizer.c:132
HLSSegment
Definition: hlsenc.c:77
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
time.h
VariantStream::discontinuity_set
int discontinuity_set
Definition: hlsenc.c:149
ffio_geturlcontext
URLContext * ffio_geturlcontext(AVIOContext *s)
Return the URLContext associated with the AVIOContext.
Definition: avio.c:107
AVOutputFormat::priv_class
const AVClass * priv_class
AVClass for the private context.
Definition: avformat.h:538
av_write_frame
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:1233
HLSContext::vtt_format_options
AVDictionary * vtt_format_options
Definition: hlsenc.c:239
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
PLAYLIST_TYPE_NB
@ PLAYLIST_TYPE_NB
Definition: hlsplaylist.h:35
SegmentType
SegmentType
Definition: hlsenc.c:114
AVCodecParameters::level
int level
Definition: codec_par.h:129
index
int index
Definition: gxfenc.c:90
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
HLS_START_SEQUENCE_AS_START_NUMBER
@ HLS_START_SEQUENCE_AS_START_NUMBER
Definition: hlsenc.c:59
HLSContext::key
char * key
Definition: hlsenc.c:228
VariantStream::old_segments
HLSSegment * old_segments
Definition: hlsenc.c:160
av_packet_side_data_get
const AVPacketSideData * av_packet_side_data_get(const AVPacketSideData *sd, int nb_sd, enum AVPacketSideDataType type)
Get side information from a side data array.
Definition: packet.c:656
AV_CODEC_ID_EAC3
@ AV_CODEC_ID_EAC3
Definition: codec_id.h:480
VariantStream::is_default
int is_default
Definition: hlsenc.c:186
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
HLS_I_FRAMES_ONLY
@ HLS_I_FRAMES_ONLY
Definition: hlsenc.c:111
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:442
av_strncasecmp
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
Definition: avstring.c:217
VariantStream::initial_prog_date_time
double initial_prog_date_time
Definition: hlsenc.c:168
HLSContext::segment_filename
char * segment_filename
Definition: hlsenc.c:211
hls_append_segment
static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, VariantStream *vs, double duration, int64_t pos, int64_t size)
Definition: hlsenc.c:1106
ff_hls_write_stream_info
void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, int bandwidth, int avg_bandwidth, const char *filename, const char *agroup, const char *codecs, const char *ccgroup, const char *sgroup)
Definition: hlsplaylist.c:73
HLSFlags
HLSFlags
Definition: hlsenc.c:95
HLSContext::cc_streams
ClosedCaptionsStream * cc_streams
Definition: hlsenc.c:246
ff_hls_write_playlist_version
void ff_hls_write_playlist_version(AVIOContext *out, int version)
Definition: hlsplaylist.c:32
HLSContext::has_video_m3u8
int has_video_m3u8
Definition: hlsenc.c:264
VariantStream::init_buffer
uint8_t * init_buffer
Definition: hlsenc.c:130
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
VariantStream::ccgroup
const char * ccgroup
Definition: hlsenc.c:190
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
HLSSegment::keyframe_size
int64_t keyframe_size
Definition: hlsenc.c:85
hls_rename_temp_file
static int hls_rename_temp_file(AVFormatContext *s, AVFormatContext *oc)
Definition: hlsenc.c:1331
AVMediaType
AVMediaType
Definition: avutil.h:199
AVPacket::size
int size
Definition: packet.h:540
HLSContext::master_pl_name
char * master_pl_name
Definition: hlsenc.c:254
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
av_codec_get_tag
unsigned int av_codec_get_tag(const struct AVCodecTag *const *tags, enum AVCodecID id)
Get the codec tag for the given codec id id.
FF_OFMT_FLAG_ALLOW_FLUSH
#define FF_OFMT_FLAG_ALLOW_FLUSH
This flag indicates that the muxer stores data internally and supports flushing it.
Definition: mux.h:38
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
HLS_SPLIT_BY_TIME
@ HLS_SPLIT_BY_TIME
Definition: hlsenc.c:102
VariantStream::basename_tmp
char * basename_tmp
Definition: hlsenc.c:162
localtime_r
#define localtime_r
Definition: time_internal.h:46
HLSContext::start_sequence_source_type
uint32_t start_sequence_source_type
Definition: hlsenc.c:203
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1403
size
int size
Definition: twinvq_data.h:10344
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
HLSSegment::pos
int64_t pos
Definition: hlsenc.c:82
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
HLSContext::pl_type
uint32_t pl_type
Definition: hlsenc.c:210
AVCodecParameters::profile
int profile
Codec-specific bitstream restrictions that the stream conforms to.
Definition: codec_par.h:128
CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN
@ CODEC_ATTRIBUTE_WILL_NOT_BE_WRITTEN
Definition: hlsenc.c:68
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
ff_is_http_proto
int ff_is_http_proto(const char *filename)
Utility function to check if the file uses http or https protocol.
Definition: utils.c:572
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:951
ff_hls_write_init_file
void ff_hls_write_init_file(AVIOContext *out, const char *filename, int byterange_mode, int64_t size, int64_t pos)
Definition: hlsplaylist.c:129
HLSSegment::discont_program_date_time
double discont_program_date_time
Definition: hlsenc.c:92
fn
#define fn(a)
Definition: aap_template.c:37
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:826
parse_variant_stream_mapstring
static int parse_variant_stream_mapstring(AVFormatContext *s)
Definition: hlsenc.c:2028
hls_init
static int hls_init(AVFormatContext *s)
Definition: hlsenc.c:2894
VariantStream::agroup
const char * agroup
Definition: hlsenc.c:188
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:201
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:365
av_isdigit
static av_const int av_isdigit(int c)
Locale-independent conversion of ASCII isdigit.
Definition: avstring.h:202
VariantStream::sequence
int64_t sequence
Definition: hlsenc.c:122
line
Definition: graph2dot.c:48
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:545
HLSContext::start_sequence
int64_t start_sequence
Definition: hlsenc.c:202
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:223
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
VariantStream::temp_buffer
uint8_t * temp_buffer
Definition: hlsenc.c:129
HLSContext::format_options
AVDictionary * format_options
Definition: hlsenc.c:225
OFFSET
#define OFFSET(x)
Definition: hlsenc.c:3145
HLS_DISCONT_START
@ HLS_DISCONT_START
Definition: hlsenc.c:100
VariantStream::video_keyframe_size
int64_t video_keyframe_size
Definition: hlsenc.c:144
VariantStream::basename
char * basename
Definition: hlsenc.c:163
HLS_START_SEQUENCE_AS_FORMATTED_DATETIME
@ HLS_START_SEQUENCE_AS_FORMATTED_DATETIME
Definition: hlsenc.c:61
parse_playlist
static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
Definition: hlsenc.c:1207
hls_write_packet
static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: hlsenc.c:2437
VariantStream::last_segment
HLSSegment * last_segment
Definition: hlsenc.c:159
av_write_trailer
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1295
AV_PKT_DATA_CPB_PROPERTIES
@ AV_PKT_DATA_CPB_PROPERTIES
This side data corresponds to the AVCPBProperties struct.
Definition: packet.h:142
VariantStream::m3u8_created
int m3u8_created
Definition: hlsenc.c:185
bprint.h
ff_hls_write_audio_rendition
void ff_hls_write_audio_rendition(AVIOContext *out, const char *agroup, const char *filename, const char *language, int name_id, int is_default, int nb_channels)
Definition: hlsplaylist.c:40
URLContext
Definition: url.h:35
HLSContext::iv_string
char iv_string[KEYSIZE *2+1]
Definition: hlsenc.c:238
log.h
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:478
AVOutputFormat
Definition: avformat.h:509
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
round
static av_always_inline av_const double round(double x)
Definition: libm.h:444
fn2
#define fn2(a, b)
Definition: aap_template.c:36
AVERROR_MUXER_NOT_FOUND
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:62
HLSContext::key_string
char key_string[KEYSIZE *2+1]
Definition: hlsenc.c:237
VariantStream::sgroup
const char * sgroup
Definition: hlsenc.c:189
HLSContext::max_nb_segments
int max_nb_segments
Definition: hlsenc.c:207
VariantStream::start_pos
int64_t start_pos
Definition: hlsenc.c:146
AVCPBProperties::max_bitrate
int64_t max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition: defs.h:276
VariantStream::nb_streams
unsigned int nb_streams
Definition: hlsenc.c:184
HLSContext::sub_m3u8_out
AVIOContext * sub_m3u8_out
Definition: hlsenc.c:258
hls_encryption_start
static int hls_encryption_start(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:786
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:226
HLSContext
Definition: hls.c:205
options
static const AVOption options[]
Definition: hlsenc.c:3147
url.h
hlsenc_io_close
static int hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename)
Definition: hlsenc.c:311
av_random_bytes
int av_random_bytes(uint8_t *buf, size_t len)
Generate cryptographically secure random data, i.e.
Definition: random_seed.c:130
AVFormatContext::max_delay
int max_delay
Definition: avformat.h:1432
VariantStream::number
unsigned number
Definition: hlsenc.c:121
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
ff_get_line
int ff_get_line(AVIOContext *s, char *buf, int maxlen)
Read a whole line of text from AVIOContext.
Definition: aviobuf.c:769
HLSSegment::var_stream_idx
unsigned var_stream_idx
Definition: hlsenc.c:86
len
int len
Definition: vorbis_enc_data.h:426
start_sequence
static const uint8_t start_sequence[]
Definition: rtpdec_h264.c:66
profile
int profile
Definition: mxfenc.c:2228
VariantStream::duration
double duration
Definition: hlsenc.c:145
VariantStream::streams
AVStream ** streams
Definition: hlsenc.c:181
AVCodecParameters::coded_side_data
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition: codec_par.h:81
nal.h
write_packet
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:209
HLSContext::fmp4_init_filename
char * fmp4_init_filename
Definition: hlsenc.c:212
HLSContext::encrypt
int encrypt
Definition: hlsenc.c:227
VariantStream::max_bitrate
int64_t max_bitrate
Definition: hlsenc.c:156
HLSContext::http_persistent
int http_persistent
Definition: hls.c:229
HLS_SINGLE_FILE
@ HLS_SINGLE_FILE
Definition: hlsenc.c:97
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1435
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
VariantStream::out_single_file
AVIOContext * out_single_file
Definition: hlsenc.c:126
ff_hls_write_file_entry
int ff_hls_write_file_entry(AVIOContext *out, int insert_discont, int byterange_mode, double duration, int round_duration, int64_t size, int64_t pos, const char *baseurl, const char *filename, double *prog_date_time, int64_t video_keyframe_size, int64_t video_keyframe_pos, int iframe_mode)
Definition: hlsplaylist.c:139
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
VariantStream::fmp4_init_filename
char * fmp4_init_filename
Definition: hlsenc.c:171
HLSContext::subtitle_filename
char * subtitle_filename
Definition: hlsenc.c:224
AVFormatContext::oformat
const struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1306
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
replace_int_data_in_filename
static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number)
Definition: hlsenc.c:494
hls_delete_old_segments
static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls, VariantStream *vs)
Definition: hlsenc.c:603
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
VariantStream::end_pts
int64_t end_pts
Definition: hlsenc.c:141
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
VariantStream::encrypt_started
int encrypt_started
Definition: hlsenc.c:174
VariantStream::discontinuity
int discontinuity
Definition: hlsenc.c:150
VariantStream::nb_entries
int nb_entries
Definition: hlsenc.c:148
SEGMENT_TYPE_MPEGTS
@ SEGMENT_TYPE_MPEGTS
Definition: hlsenc.c:115
avio_printf
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
VariantStream::current_segment_final_filename_fmt
char current_segment_final_filename_fmt[MAX_URL_SIZE]
Definition: hlsenc.c:169
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:754
can_split
static void can_split(const VVCLocalContext *lc, int x0, int y0, int cb_width, int cb_height, int mtt_depth, int depth_offset, int part_idx, VVCSplitMode last_split_mode, VVCTreeType tree_type, VVCModeType mode_type, VVCAllowedSplit *split)
Definition: ctu.c:525
random_seed.h
format_name
static int format_name(const char *buf, char **s, int index, const char *varname)
Definition: hlsenc.c:1964
MAX_URL_SIZE
#define MAX_URL_SIZE
Definition: internal.h:30
get_default_pattern_localtime_fmt
static const char * get_default_pattern_localtime_fmt(AVFormatContext *s)
Definition: hlsenc.c:1890
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
AVRational::den
int den
Denominator.
Definition: rational.h:60
VariantStream::packets_written
int packets_written
Definition: hlsenc.c:127
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
headers
FFmpeg currently uses a custom build this text attempts to document some of its obscure features and options Makefile the full command issued by make and its output will be shown on the screen DBG Preprocess x86 external assembler files to a dbg asm file in the object which then gets compiled Helps in developing those assembler files DESTDIR Destination directory for the install useful to prepare packages or install FFmpeg in cross environments GEN Set to ‘1’ to generate the missing or mismatched references Makefile builds all the libraries and the executables fate Run the fate test note that you must have installed it fate list List all fate regression test targets install Install headers
Definition: build_system.txt:34
defs.h
av_bprint_clear
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:232
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:145
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:612
update_master_pl_info
static int update_master_pl_info(AVFormatContext *s)
Definition: hlsenc.c:2286
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:1890
sls_flag_check_duration_size_index
static int sls_flag_check_duration_size_index(HLSContext *hls)
Definition: hlsenc.c:1012
ClosedCaptionsStream::language
const char * language
Definition: hlsenc.c:197
VariantStream::vtt_m3u8_name
char * vtt_m3u8_name
Definition: hlsenc.c:165
HLSContext::baseurl
char * baseurl
Definition: hlsenc.c:222
AVPacket::stream_index
int stream_index
Definition: packet.h:541
CodecAttributeStatus
CodecAttributeStatus
Definition: hlsenc.c:66
segment
Definition: hls.c:77
HLSContext::key_info_file
char * key_info_file
Definition: hlsenc.c:234
av_gettime
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:167
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
av_guess_format
const AVOutputFormat * av_guess_format(const char *short_name, const char *filename, const char *mime_type)
Return the output format in the list of registered output formats which best matches the provided par...
Definition: format.c:79
mem.h
VariantStream::out
AVIOContext * out
Definition: hlsenc.c:125
HLSContext::nb_varstreams
unsigned int nb_varstreams
Definition: hlsenc.c:245
HLSContext::master_m3u8_created
int master_m3u8_created
Definition: hlsenc.c:249
VariantStream::size
int64_t size
Definition: hlsenc.c:147
HLSContext::version
int version
Definition: hlsenc.c:251
ff_mkdir_p
int ff_mkdir_p(const char *path)
Automatically create sub-directories.
Definition: utils.c:414
HLSContext::var_streams
VariantStream * var_streams
Definition: hlsenc.c:244
VariantStream::dpp
double dpp
Definition: hlsenc.c:139
VariantStream::avf
AVFormatContext * avf
Definition: hlsenc.c:132
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
POSTFIX_PATTERN
#define POSTFIX_PATTERN
Definition: hlsenc.c:75
AVPacket
This structure stores compressed data.
Definition: packet.h:516
hls_free_segments
static void hls_free_segments(HLSSegment *p)
Definition: hlsenc.c:1320
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
HLSContext::flags
uint32_t flags
Definition: hlsenc.c:209
hls_mux_init
static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:845
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_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
VariantStream::varname
const char * varname
Definition: hlsenc.c:191
AVFormatContext::io_close2
int(* io_close2)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1904
append_single_file
static int64_t append_single_file(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:2406
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
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition: opt.h:255
HLSContext::init_time
int64_t init_time
Definition: hlsenc.c:206
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
avio_close
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: avio.c:616
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
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
hls_window
static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
Definition: hlsenc.c:1561
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
h
h
Definition: vp9dsp_template.c:2070
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
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:348
HLSContext::key_uri
char key_uri[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:236
AV_RB24
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:97
avformat_alloc_output_context2
int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition: mux.c:94
AVStream::pts_wrap_bits
int pts_wrap_bits
Number of bits in timestamps.
Definition: avformat.h:923
http.h
HLS_SECOND_LEVEL_SEGMENT_DURATION
@ HLS_SECOND_LEVEL_SEGMENT_DURATION
Definition: hlsenc.c:106
av_bprint_append_data
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition: bprint.c:163
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
snprintf
#define snprintf
Definition: snprintf.h:34
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1315
ff_format_set_url
void ff_format_set_url(AVFormatContext *s, char *url)
Set AVFormatContext url field to the provided pointer.
Definition: avformat.c:944
parse_cc_stream_mapstring
static int parse_cc_stream_mapstring(AVFormatContext *s)
Definition: hlsenc.c:2171
HLSContext::segment_type
int segment_type
Definition: hlsenc.c:213
HLSContext::master_m3u8_url
char * master_m3u8_url
Definition: hlsenc.c:250
HLSContext::recording_time
int64_t recording_time
Definition: hlsenc.c:219
HLSContext::max_seg_size
int64_t max_seg_size
Definition: hlsenc.c:220
HLSContext::master_publish_rate
unsigned int master_publish_rate
Definition: hlsenc.c:255
ClosedCaptionsStream::instreamid
const char * instreamid
Definition: hlsenc.c:196
HLSSegment::size
int64_t size
Definition: hlsenc.c:83
HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH
@ HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH
Definition: hlsenc.c:60
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
VariantStream::vtt_basename
char * vtt_basename
Definition: hlsenc.c:164
ClosedCaptionsStream::ccgroup
const char * ccgroup
Definition: hlsenc.c:195
HLSContext::headers
char * headers
Definition: hlsenc.c:262
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:345
hls_class
static const AVClass hls_class
Definition: hlsenc.c:3209
VariantStream
Definition: hlsenc.c:119
VariantStream::total_size
int64_t total_size
Definition: hlsenc.c:153
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:346
HLSContext::var_stream_map
char * var_stream_map
Definition: hlsenc.c:252
mux.h
ff_write_chained
int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, AVFormatContext *src, int interleave)
Write a packet to another muxer than the one the user originally intended.
Definition: mux.c:1394