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