FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 <float.h>
25 #include <stdint.h>
26 #if HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 
30 #if CONFIG_GCRYPT
31 #include <gcrypt.h>
32 #elif CONFIG_OPENSSL
33 #include <openssl/rand.h>
34 #endif
35 
36 #include "libavutil/avassert.h"
37 #include "libavutil/mathematics.h"
38 #include "libavutil/parseutils.h"
39 #include "libavutil/avstring.h"
40 #include "libavutil/intreadwrite.h"
41 #include "libavutil/random_seed.h"
42 #include "libavutil/opt.h"
43 #include "libavutil/log.h"
45 
46 #include "avformat.h"
47 #include "avio_internal.h"
48 #if CONFIG_HTTP_PROTOCOL
49 #include "http.h"
50 #endif
51 #include "hlsplaylist.h"
52 #include "internal.h"
53 #include "os_support.h"
54 
55 typedef enum {
60 
61 #define KEYSIZE 16
62 #define LINE_BUFFER_SIZE 1024
63 #define HLS_MICROSECOND_UNIT 1000000
64 #define POSTFIX_PATTERN "_%d"
65 
66 typedef struct HLSSegment {
67  char filename[1024];
68  char sub_filename[1024];
69  double duration; /* in seconds */
70  int discont;
71  int64_t pos;
72  int64_t size;
73 
75  char iv_string[KEYSIZE*2 + 1];
76 
77  struct HLSSegment *next;
78 } HLSSegment;
79 
80 typedef enum HLSFlags {
81  // Generate a single media file and use byte ranges in the playlist.
82  HLS_SINGLE_FILE = (1 << 0),
83  HLS_DELETE_SEGMENTS = (1 << 1),
84  HLS_ROUND_DURATIONS = (1 << 2),
85  HLS_DISCONT_START = (1 << 3),
86  HLS_OMIT_ENDLIST = (1 << 4),
87  HLS_SPLIT_BY_TIME = (1 << 5),
88  HLS_APPEND_LIST = (1 << 6),
90  HLS_SECOND_LEVEL_SEGMENT_INDEX = (1 << 8), // include segment index in segment filenames when use_localtime e.g.: %%03d
91  HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime e.g.: %%09t
92  HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s
93  HLS_TEMP_FILE = (1 << 11),
94  HLS_PERIODIC_REKEY = (1 << 12),
96 } HLSFlags;
97 
98 typedef enum {
101 } SegmentType;
102 
103 typedef struct VariantStream {
104  unsigned number;
105  int64_t sequence;
111 
114 
118  double dpp; // duration per packet
119  int64_t start_pts;
120  int64_t end_pts;
121  double duration; // last segment duration computed so far, in seconds
122  int64_t start_pos; // last segment starting position
123  int64_t size; // last segment size
127 
131 
132  char *basename;
135  char *m3u8_name;
136 
138  char current_segment_final_filename_fmt[1024]; // when renaming segments
139 
143 
145  unsigned int nb_streams;
146  int m3u8_created; /* status of media play-list creation */
147  char *agroup; /* audio group name */
148  char *baseurl;
149 } VariantStream;
150 
151 typedef struct HLSContext {
152  const AVClass *class; // Class for private options.
153  int64_t start_sequence;
154  uint32_t start_sequence_source_type; // enum StartSequenceSourceType
155 
156  float time; // Set by a private option.
157  float init_time; // Set by a private option.
158  int max_nb_segments; // Set by a private option.
159 #if FF_API_HLS_WRAP
160  int wrap; // Set by a private option.
161 #endif
162  uint32_t flags; // enum HLSFlags
163  uint32_t pl_type; // enum PlaylistType
167 
168  int use_localtime; ///< flag to expand filename with localtime
169  int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename
171  int64_t recording_time;
172  int64_t max_seg_size; // every segment file max size
173 
174  char *baseurl;
179 
180  int encrypt;
181  char *key;
182  char *key_url;
183  char *iv;
186 
190  char key_string[KEYSIZE*2 + 1];
191  char iv_string[KEYSIZE*2 + 1];
193 
194  char *method;
195  char *user_agent;
196 
198  unsigned int nb_varstreams;
199 
200  int master_m3u8_created; /* status of master play-list creation */
201  char *master_m3u8_url; /* URL of the master m3u8 file */
202  int version; /* HLS version */
203  char *var_stream_map; /* user specified variant stream map string */
205  unsigned int master_publish_rate;
206  int http_persistent;
209 } HLSContext;
210 
211 static int mkdir_p(const char *path) {
212  int ret = 0;
213  char *temp = av_strdup(path);
214  char *pos = temp;
215  char tmp_ch = '\0';
216 
217  if (!path || !temp) {
218  return -1;
219  }
220 
221  if (!strncmp(temp, "/", 1) || !strncmp(temp, "\\", 1)) {
222  pos++;
223  } else if (!strncmp(temp, "./", 2) || !strncmp(temp, ".\\", 2)) {
224  pos += 2;
225  }
226 
227  for ( ; *pos != '\0'; ++pos) {
228  if (*pos == '/' || *pos == '\\') {
229  tmp_ch = *pos;
230  *pos = '\0';
231  ret = mkdir(temp, 0755);
232  *pos = tmp_ch;
233  }
234  }
235 
236  if ((*(pos - 1) != '/') || (*(pos - 1) != '\\')) {
237  ret = mkdir(temp, 0755);
238  }
239 
240  av_free(temp);
241  return ret;
242 }
243 
244 static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
245  AVDictionary **options) {
246  HLSContext *hls = s->priv_data;
247  int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
248  int err = AVERROR_MUXER_NOT_FOUND;
249  if (!*pb || !http_base_proto || !hls->http_persistent) {
250  err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
251 #if CONFIG_HTTP_PROTOCOL
252  } else {
253  URLContext *http_url_context = ffio_geturlcontext(*pb);
254  av_assert0(http_url_context);
255  err = ff_http_do_new_request(http_url_context, filename);
256 #endif
257  }
258  return err;
259 }
260 
261 static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename) {
262  HLSContext *hls = s->priv_data;
263  int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
264  if (!http_base_proto || !hls->http_persistent || hls->key_info_file || hls->encrypt) {
265  ff_format_io_close(s, pb);
266 #if CONFIG_HTTP_PROTOCOL
267  } else {
268  URLContext *http_url_context = ffio_geturlcontext(*pb);
269  av_assert0(http_url_context);
270  avio_flush(*pb);
271  ffurl_shutdown(http_url_context, AVIO_FLAG_WRITE);
272 #endif
273  }
274 }
275 
277 {
278  int http_base_proto = ff_is_http_proto(s->filename);
279 
280  if (c->method) {
281  av_dict_set(options, "method", c->method, 0);
282  } else if (http_base_proto) {
283  av_log(c, AV_LOG_WARNING, "No HTTP method set, hls muxer defaulting to method PUT.\n");
284  av_dict_set(options, "method", "PUT", 0);
285  }
286  if (c->user_agent)
287  av_dict_set(options, "user_agent", c->user_agent, 0);
288  if (c->http_persistent)
289  av_dict_set_int(options, "multiple_requests", 1, 0);
290 
291 }
292 
293 static int replace_int_data_in_filename(char *buf, int buf_size, const char *filename, char placeholder, int64_t number)
294 {
295  const char *p;
296  char *q, buf1[20], c;
297  int nd, len, addchar_count;
298  int found_count = 0;
299 
300  q = buf;
301  p = filename;
302  for (;;) {
303  c = *p;
304  if (c == '\0')
305  break;
306  if (c == '%' && *(p+1) == '%') // %%
307  addchar_count = 2;
308  else if (c == '%' && (av_isdigit(*(p+1)) || *(p+1) == placeholder)) {
309  nd = 0;
310  addchar_count = 1;
311  while (av_isdigit(*(p + addchar_count))) {
312  nd = nd * 10 + *(p + addchar_count) - '0';
313  addchar_count++;
314  }
315 
316  if (*(p + addchar_count) == placeholder) {
317  len = snprintf(buf1, sizeof(buf1), "%0*"PRId64, (number < 0) ? nd : nd++, number);
318  if (len < 1) // returned error or empty buf1
319  goto fail;
320  if ((q - buf + len) > buf_size - 1)
321  goto fail;
322  memcpy(q, buf1, len);
323  q += len;
324  p += (addchar_count + 1);
325  addchar_count = 0;
326  found_count++;
327  }
328 
329  } else
330  addchar_count = 1;
331 
332  while (addchar_count--)
333  if ((q - buf) < buf_size - 1)
334  *q++ = *p++;
335  else
336  goto fail;
337  }
338  *q = '\0';
339  return found_count;
340 fail:
341  *q = '\0';
342  return -1;
343 }
344 
345 static void write_styp(AVIOContext *pb)
346 {
347  avio_wb32(pb, 24);
348  ffio_wfourcc(pb, "styp");
349  ffio_wfourcc(pb, "msdh");
350  avio_wb32(pb, 0); /* minor */
351  ffio_wfourcc(pb, "msdh");
352  ffio_wfourcc(pb, "msix");
353 }
354 
355 static int flush_dynbuf(VariantStream *vs, int *range_length)
356 {
357  AVFormatContext *ctx = vs->avf;
358  uint8_t *buffer;
359 
360  if (!ctx->pb) {
361  return AVERROR(EINVAL);
362  }
363 
364  // flush
365  av_write_frame(ctx, NULL);
366  avio_flush(ctx->pb);
367 
368  // write out to file
369  *range_length = avio_close_dyn_buf(ctx->pb, &buffer);
370  ctx->pb = NULL;
371  avio_write(vs->out, buffer, *range_length);
372  av_free(buffer);
373 
374  // re-open buffer
375  return avio_open_dyn_buf(&ctx->pb);
376 }
377 
379  VariantStream *vs) {
380 
381  HLSSegment *segment, *previous_segment = NULL;
382  float playlist_duration = 0.0f;
383  int ret = 0, path_size, sub_path_size;
384  char *dirname = NULL, *p, *sub_path;
385  char *path = NULL;
387  AVIOContext *out = NULL;
388  const char *proto = NULL;
389 
390  segment = vs->segments;
391  while (segment) {
392  playlist_duration += segment->duration;
393  segment = segment->next;
394  }
395 
396  segment = vs->old_segments;
397  while (segment) {
398  playlist_duration -= segment->duration;
399  previous_segment = segment;
400  segment = previous_segment->next;
401  if (playlist_duration <= -previous_segment->duration) {
402  previous_segment->next = NULL;
403  break;
404  }
405  }
406 
407  if (segment && !hls->use_localtime_mkdir) {
408  if (hls->segment_filename) {
409  dirname = av_strdup(hls->segment_filename);
410  } else {
411  dirname = av_strdup(vs->avf->filename);
412  }
413  if (!dirname) {
414  ret = AVERROR(ENOMEM);
415  goto fail;
416  }
417  p = (char *)av_basename(dirname);
418  *p = '\0';
419  }
420 
421  while (segment) {
422  av_log(hls, AV_LOG_DEBUG, "deleting old segment %s\n",
423  segment->filename);
424  path_size = (hls->use_localtime_mkdir ? 0 : strlen(dirname)) + strlen(segment->filename) + 1;
425  path = av_malloc(path_size);
426  if (!path) {
427  ret = AVERROR(ENOMEM);
428  goto fail;
429  }
430 
431  if (hls->use_localtime_mkdir)
432  av_strlcpy(path, segment->filename, path_size);
433  else { // segment->filename contains basename only
434  av_strlcpy(path, dirname, path_size);
435  av_strlcat(path, segment->filename, path_size);
436  }
437 
438  proto = avio_find_protocol_name(s->filename);
439  if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
440  av_dict_set(&options, "method", "DELETE", 0);
441  if ((ret = vs->avf->io_open(vs->avf, &out, path, AVIO_FLAG_WRITE, &options)) < 0)
442  goto fail;
443  ff_format_io_close(vs->avf, &out);
444  } else if (unlink(path) < 0) {
445  av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
446  path, strerror(errno));
447  }
448 
449  if ((segment->sub_filename[0] != '\0')) {
450  sub_path_size = strlen(segment->sub_filename) + 1 + (dirname ? strlen(dirname) : 0);
451  sub_path = av_malloc(sub_path_size);
452  if (!sub_path) {
453  ret = AVERROR(ENOMEM);
454  goto fail;
455  }
456 
457  av_strlcpy(sub_path, dirname, sub_path_size);
458  av_strlcat(sub_path, segment->sub_filename, sub_path_size);
459 
460  if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
461  av_dict_set(&options, "method", "DELETE", 0);
462  if ((ret = vs->avf->io_open(vs->avf, &out, sub_path, AVIO_FLAG_WRITE, &options)) < 0) {
463  av_free(sub_path);
464  goto fail;
465  }
466  ff_format_io_close(vs->avf, &out);
467  } else if (unlink(sub_path) < 0) {
468  av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
469  sub_path, strerror(errno));
470  }
471  av_free(sub_path);
472  }
473  av_freep(&path);
474  previous_segment = segment;
475  segment = previous_segment->next;
476  av_free(previous_segment);
477  }
478 
479 fail:
480  av_free(path);
481  av_free(dirname);
482 
483  return ret;
484 }
485 
486 static int randomize(uint8_t *buf, int len)
487 {
488 #if CONFIG_GCRYPT
489  gcry_randomize(buf, len, GCRY_VERY_STRONG_RANDOM);
490  return 0;
491 #elif CONFIG_OPENSSL
492  if (RAND_bytes(buf, len))
493  return 0;
494 #else
495  return AVERROR(ENOSYS);
496 #endif
497  return AVERROR(EINVAL);
498 }
499 
501 {
502  HLSContext *hls = s->priv_data;
503  int ret;
504  int len;
505  AVIOContext *pb;
507 
508  len = strlen(s->filename) + 4 + 1;
509  hls->key_basename = av_mallocz(len);
510  if (!hls->key_basename)
511  return AVERROR(ENOMEM);
512 
513  av_strlcpy(hls->key_basename, s->filename, len);
514  av_strlcat(hls->key_basename, ".key", len);
515 
516  if (hls->key_url) {
517  av_strlcpy(hls->key_file, hls->key_url, sizeof(hls->key_file));
518  av_strlcpy(hls->key_uri, hls->key_url, sizeof(hls->key_uri));
519  } else {
520  av_strlcpy(hls->key_file, hls->key_basename, sizeof(hls->key_file));
521  av_strlcpy(hls->key_uri, hls->key_basename, sizeof(hls->key_uri));
522  }
523 
524  if (!*hls->iv_string) {
525  uint8_t iv[16] = { 0 };
526  char buf[33];
527 
528  if (!hls->iv) {
529  AV_WB64(iv + 8, vs->sequence);
530  } else {
531  memcpy(iv, hls->iv, sizeof(iv));
532  }
533  ff_data_to_hex(buf, iv, sizeof(iv), 0);
534  buf[32] = '\0';
535  memcpy(hls->iv_string, buf, sizeof(hls->iv_string));
536  }
537 
538  if (!*hls->key_uri) {
539  av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
540  return AVERROR(EINVAL);
541  }
542 
543  if (!*hls->key_file) {
544  av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
545  return AVERROR(EINVAL);
546  }
547 
548  if (!*hls->key_string) {
549  if (!hls->key) {
550  if ((ret = randomize(key, sizeof(key))) < 0) {
551  av_log(s, AV_LOG_ERROR, "Cannot generate a strong random key\n");
552  return ret;
553  }
554  } else {
555  memcpy(key, hls->key, sizeof(key));
556  }
557 
558  ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
559  if ((ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_WRITE, NULL)) < 0)
560  return ret;
561  avio_seek(pb, 0, SEEK_CUR);
562  avio_write(pb, key, KEYSIZE);
563  avio_close(pb);
564  }
565  return 0;
566 }
567 
568 
570 {
571  HLSContext *hls = s->priv_data;
572  int ret;
573  AVIOContext *pb;
575 
576  if ((ret = s->io_open(s, &pb, hls->key_info_file, AVIO_FLAG_READ, NULL)) < 0) {
577  av_log(hls, AV_LOG_ERROR,
578  "error opening key info file %s\n", hls->key_info_file);
579  return ret;
580  }
581 
582  ff_get_line(pb, hls->key_uri, sizeof(hls->key_uri));
583  hls->key_uri[strcspn(hls->key_uri, "\r\n")] = '\0';
584 
585  ff_get_line(pb, hls->key_file, sizeof(hls->key_file));
586  hls->key_file[strcspn(hls->key_file, "\r\n")] = '\0';
587 
588  ff_get_line(pb, hls->iv_string, sizeof(hls->iv_string));
589  hls->iv_string[strcspn(hls->iv_string, "\r\n")] = '\0';
590 
591  ff_format_io_close(s, &pb);
592 
593  if (!*hls->key_uri) {
594  av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
595  return AVERROR(EINVAL);
596  }
597 
598  if (!*hls->key_file) {
599  av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
600  return AVERROR(EINVAL);
601  }
602 
603  if ((ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_READ, NULL)) < 0) {
604  av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", hls->key_file);
605  return ret;
606  }
607 
608  ret = avio_read(pb, key, sizeof(key));
609  ff_format_io_close(s, &pb);
610  if (ret != sizeof(key)) {
611  av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", hls->key_file);
612  if (ret >= 0 || ret == AVERROR_EOF)
613  ret = AVERROR(EINVAL);
614  return ret;
615  }
616  ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
617 
618  return 0;
619 }
620 
621 static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
622 {
623  int len = ff_get_line(s, buf, maxlen);
624  while (len > 0 && av_isspace(buf[len - 1]))
625  buf[--len] = '\0';
626  return len;
627 }
628 
630 {
632  HLSContext *hls = s->priv_data;
633  AVFormatContext *oc;
634  AVFormatContext *vtt_oc = NULL;
635  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
636  int i, ret;
637 
639  if (ret < 0)
640  return ret;
641  oc = vs->avf;
642 
643  oc->filename[0] = '\0';
644  oc->oformat = vs->oformat;
646  oc->max_delay = s->max_delay;
647  oc->opaque = s->opaque;
648  oc->io_open = s->io_open;
649  oc->io_close = s->io_close;
650  av_dict_copy(&oc->metadata, s->metadata, 0);
651 
652  if(vs->vtt_oformat) {
654  if (ret < 0)
655  return ret;
656  vtt_oc = vs->vtt_avf;
657  vtt_oc->oformat = vs->vtt_oformat;
658  av_dict_copy(&vtt_oc->metadata, s->metadata, 0);
659  }
660 
661  for (i = 0; i < vs->nb_streams; i++) {
662  AVStream *st;
663  AVFormatContext *loc;
665  loc = vtt_oc;
666  else
667  loc = oc;
668 
669  if (!(st = avformat_new_stream(loc, NULL)))
670  return AVERROR(ENOMEM);
672  if (!oc->oformat->codec_tag ||
675  st->codecpar->codec_tag = vs->streams[i]->codecpar->codec_tag;
676  } else {
677  st->codecpar->codec_tag = 0;
678  }
679 
681  st->time_base = vs->streams[i]->time_base;
682  av_dict_copy(&st->metadata, vs->streams[i]->metadata, 0);
683  }
684 
685  vs->packets_written = 1;
686  vs->start_pos = 0;
687  vs->new_start = 1;
688  vs->fmp4_init_mode = 0;
689 
690  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
691  if (hls->max_seg_size > 0) {
692  av_log(s, AV_LOG_WARNING, "Multi-file byterange mode is currently unsupported in the HLS muxer.\n");
693  return AVERROR_PATCHWELCOME;
694  }
695 
696  vs->packets_written = 0;
697  vs->init_range_length = 0;
698  vs->fmp4_init_mode = !byterange_mode;
699  set_http_options(s, &options, hls);
700  if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
701  return ret;
702 
703  ret = hlsenc_io_open(s, &vs->out, vs->base_output_dirname, &options);
704  av_dict_free(&options);
705  if (ret < 0) {
706  av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", vs->fmp4_init_filename);
707  return ret;
708  }
709 
710  if (hls->format_options_str) {
711  ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
712  if (ret < 0) {
713  av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n",
714  hls->format_options_str);
715  return ret;
716  }
717  }
718 
719  av_dict_copy(&options, hls->format_options, 0);
720  av_dict_set(&options, "fflags", "-autobsf", 0);
721  av_dict_set(&options, "movflags", "frag_custom+dash+delay_moov", 0);
722  ret = avformat_init_output(oc, &options);
723  if (ret < 0)
724  return ret;
725  if (av_dict_count(options)) {
726  av_log(s, AV_LOG_ERROR, "Some of the provided format options in '%s' are not recognized\n", hls->format_options_str);
727  av_dict_free(&options);
728  return AVERROR(EINVAL);
729  }
730  avio_flush(oc->pb);
731  av_dict_free(&options);
732  }
733  return 0;
734 }
735 
736 static HLSSegment *find_segment_by_filename(HLSSegment *segment, const char *filename)
737 {
738  while (segment) {
739  if (!av_strcasecmp(segment->filename,filename))
740  return segment;
741  segment = segment->next;
742  }
743  return (HLSSegment *) NULL;
744 }
745 
747  VariantStream *vs, HLSSegment *en,
748  double duration, int64_t pos, int64_t size)
749 {
754  char * filename = av_strdup(vs->avf->filename); // %%s will be %s after strftime
755  if (!filename) {
756  av_free(en);
757  return AVERROR(ENOMEM);
758  }
759  if (replace_int_data_in_filename(vs->avf->filename, sizeof(vs->avf->filename),
760  filename, 's', pos + size) < 1) {
761  av_log(hls, AV_LOG_ERROR,
762  "Invalid second level segment filename template '%s', "
763  "you can try to remove second_level_segment_size flag\n",
764  filename);
765  av_free(filename);
766  av_free(en);
767  return AVERROR(EINVAL);
768  }
769  av_free(filename);
770  }
772  char * filename = av_strdup(vs->avf->filename); // %%t will be %t after strftime
773  if (!filename) {
774  av_free(en);
775  return AVERROR(ENOMEM);
776  }
777  if (replace_int_data_in_filename(vs->avf->filename, sizeof(vs->avf->filename),
778  filename, 't', (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) {
779  av_log(hls, AV_LOG_ERROR,
780  "Invalid second level segment filename template '%s', "
781  "you can try to remove second_level_segment_time flag\n",
782  filename);
783  av_free(filename);
784  av_free(en);
785  return AVERROR(EINVAL);
786  }
787  av_free(filename);
788  }
789  }
790  return 0;
791 }
792 
794 {
795  int ret = 0;
796 
798  av_log(hls, AV_LOG_ERROR,
799  "second_level_segment_duration hls_flag requires use_localtime to be true\n");
800  ret = AVERROR(EINVAL);
801  }
803  av_log(hls, AV_LOG_ERROR,
804  "second_level_segment_size hls_flag requires use_localtime to be true\n");
805  ret = AVERROR(EINVAL);
806  }
808  av_log(hls, AV_LOG_ERROR,
809  "second_level_segment_index hls_flag requires use_localtime to be true\n");
810  ret = AVERROR(EINVAL);
811  }
812 
813  return ret;
814 }
815 
817 {
818  const char *proto = avio_find_protocol_name(vs->basename);
819  int segment_renaming_ok = proto && !strcmp(proto, "file");
820  int ret = 0;
821 
822  if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) {
823  av_log(hls, AV_LOG_ERROR,
824  "second_level_segment_duration hls_flag works only with file protocol segment names\n");
825  ret = AVERROR(EINVAL);
826  }
827  if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) {
828  av_log(hls, AV_LOG_ERROR,
829  "second_level_segment_size hls_flag works only with file protocol segment names\n");
830  ret = AVERROR(EINVAL);
831  }
832 
833  return ret;
834 }
835 
836 static void sls_flag_file_rename(HLSContext *hls, VariantStream *vs, char *old_filename) {
839  ff_rename(old_filename, vs->avf->filename, hls);
840  }
841 }
842 
844 {
846  char * filename = av_strdup(oc->filename); // %%d will be %d after strftime
847  if (!filename)
848  return AVERROR(ENOMEM);
849  if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
850 #if FF_API_HLS_WRAP
851  filename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
852 #else
853  filename, 'd', vs->sequence) < 1) {
854 #endif
855  av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
856  "you can try to remove second_level_segment_index flag\n",
857  filename);
858  av_free(filename);
859  return AVERROR(EINVAL);
860  }
861  av_free(filename);
862  }
867  char * filename = av_strdup(oc->filename); // %%s will be %s after strftime
868  if (!filename)
869  return AVERROR(ENOMEM);
870  if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 's', 0) < 1) {
871  av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
872  "you can try to remove second_level_segment_size flag\n",
873  filename);
874  av_free(filename);
875  return AVERROR(EINVAL);
876  }
877  av_free(filename);
878  }
880  char * filename = av_strdup(oc->filename); // %%t will be %t after strftime
881  if (!filename)
882  return AVERROR(ENOMEM);
883  if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 't', 0) < 1) {
884  av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
885  "you can try to remove second_level_segment_time flag\n",
886  filename);
887  av_free(filename);
888  return AVERROR(EINVAL);
889  }
890  av_free(filename);
891  }
892  }
893  return 0;
894 }
895 
896 /* Create a new segment and append it to the segment list */
898  VariantStream *vs, double duration, int64_t pos,
899  int64_t size)
900 {
901  HLSSegment *en = av_malloc(sizeof(*en));
902  const char *filename;
903  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
904  int ret;
905 
906  if (!en)
907  return AVERROR(ENOMEM);
908 
909  ret = sls_flags_filename_process(s, hls, vs, en, duration, pos, size);
910  if (ret < 0) {
911  return ret;
912  }
913 
914  filename = av_basename(vs->avf->filename);
915 
916  if (hls->use_localtime_mkdir) {
917  filename = vs->avf->filename;
918  }
919  if ((find_segment_by_filename(vs->segments, filename) || find_segment_by_filename(vs->old_segments, filename))
920  && !byterange_mode) {
921  av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", filename);
922  }
923  av_strlcpy(en->filename, filename, sizeof(en->filename));
924 
925  if(vs->has_subtitle)
927  else
928  en->sub_filename[0] = '\0';
929 
930  en->duration = duration;
931  en->pos = pos;
932  en->size = size;
933  en->next = NULL;
934  en->discont = 0;
935 
936  if (vs->discontinuity) {
937  en->discont = 1;
938  vs->discontinuity = 0;
939  }
940 
941  if (hls->key_info_file || hls->encrypt) {
942  av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri));
943  av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string));
944  }
945 
946  if (!vs->segments)
947  vs->segments = en;
948  else
949  vs->last_segment->next = en;
950 
951  vs->last_segment = en;
952 
953  // EVENT or VOD playlists imply sliding window cannot be used
954  if (hls->pl_type != PLAYLIST_TYPE_NONE)
955  hls->max_nb_segments = 0;
956 
957  if (hls->max_nb_segments && vs->nb_entries >= hls->max_nb_segments) {
958  en = vs->segments;
959  vs->initial_prog_date_time += en->duration;
960  vs->segments = en->next;
961  if (en && hls->flags & HLS_DELETE_SEGMENTS &&
962 #if FF_API_HLS_WRAP
963  !(hls->flags & HLS_SINGLE_FILE || hls->wrap)) {
964 #else
965  !(hls->flags & HLS_SINGLE_FILE)) {
966 #endif
967  en->next = vs->old_segments;
968  vs->old_segments = en;
969  if ((ret = hls_delete_old_segments(s, hls, vs)) < 0)
970  return ret;
971  } else
972  av_free(en);
973  } else
974  vs->nb_entries++;
975 
976  if (hls->max_seg_size > 0) {
977  return 0;
978  }
979  vs->sequence++;
980 
981  return 0;
982 }
983 
984 static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
985 {
986  HLSContext *hls = s->priv_data;
987  AVIOContext *in;
988  int ret = 0, is_segment = 0;
989  int64_t new_start_pos;
990  char line[1024];
991  const char *ptr;
992  const char *end;
993 
994  if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ,
997  return ret;
998 
999  read_chomp_line(in, line, sizeof(line));
1000  if (strcmp(line, "#EXTM3U")) {
1001  ret = AVERROR_INVALIDDATA;
1002  goto fail;
1003  }
1004 
1005  vs->discontinuity = 0;
1006  while (!avio_feof(in)) {
1007  read_chomp_line(in, line, sizeof(line));
1008  if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
1009  int64_t tmp_sequence = strtoll(ptr, NULL, 10);
1010  if (tmp_sequence < vs->sequence)
1011  av_log(hls, AV_LOG_VERBOSE,
1012  "Found playlist sequence number was smaller """
1013  "than specified start sequence number: %"PRId64" < %"PRId64", "
1014  "omitting\n", tmp_sequence, hls->start_sequence);
1015  else {
1016  av_log(hls, AV_LOG_DEBUG, "Found playlist sequence number: %"PRId64"\n", tmp_sequence);
1017  vs->sequence = tmp_sequence;
1018  }
1019  } else if (av_strstart(line, "#EXT-X-DISCONTINUITY", &ptr)) {
1020  is_segment = 1;
1021  vs->discontinuity = 1;
1022  } else if (av_strstart(line, "#EXTINF:", &ptr)) {
1023  is_segment = 1;
1024  vs->duration = atof(ptr);
1025  } else if (av_stristart(line, "#EXT-X-KEY:", &ptr)) {
1026  ptr = av_stristr(line, "URI=\"");
1027  if (ptr) {
1028  ptr += strlen("URI=\"");
1029  end = av_stristr(ptr, ",");
1030  if (end) {
1031  av_strlcpy(hls->key_uri, ptr, end - ptr);
1032  } else {
1033  av_strlcpy(hls->key_uri, ptr, sizeof(hls->key_uri));
1034  }
1035  }
1036 
1037  ptr = av_stristr(line, "IV=0x");
1038  if (ptr) {
1039  ptr += strlen("IV=0x");
1040  end = av_stristr(ptr, ",");
1041  if (end) {
1042  av_strlcpy(hls->iv_string, ptr, end - ptr);
1043  } else {
1044  av_strlcpy(hls->iv_string, ptr, sizeof(hls->iv_string));
1045  }
1046  }
1047 
1048  } else if (av_strstart(line, "#", NULL)) {
1049  continue;
1050  } else if (line[0]) {
1051  if (is_segment) {
1052  is_segment = 0;
1053  new_start_pos = avio_tell(vs->avf->pb);
1054  vs->size = new_start_pos - vs->start_pos;
1055  av_strlcpy(vs->avf->filename, line, sizeof(line));
1056  ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size);
1057  if (ret < 0)
1058  goto fail;
1059  vs->start_pos = new_start_pos;
1060  }
1061  }
1062  }
1063 
1064 fail:
1065  avio_close(in);
1066  return ret;
1067 }
1068 
1070 {
1071  HLSSegment *en;
1072 
1073  while(p) {
1074  en = p;
1075  p = p->next;
1076  av_free(en);
1077  }
1078 }
1079 
1081 {
1082  size_t len = strlen(oc->filename);
1083  char final_filename[sizeof(oc->filename)];
1084 
1085  av_strlcpy(final_filename, oc->filename, len);
1086  final_filename[len-4] = '\0';
1087  ff_rename(oc->filename, final_filename, s);
1088  oc->filename[len-4] = '\0';
1089 }
1090 
1091 static int get_relative_url(const char *master_url, const char *media_url,
1092  char *rel_url, int rel_url_buf_size)
1093 {
1094  char *p = NULL;
1095  int base_len = -1;
1096  p = strrchr(master_url, '/') ? strrchr(master_url, '/') :\
1097  strrchr(master_url, '\\');
1098  if (p) {
1099  base_len = FFABS(p - master_url);
1100  if (av_strncasecmp(master_url, media_url, base_len)) {
1101  av_log(NULL, AV_LOG_WARNING, "Unable to find relative url\n");
1102  return AVERROR(EINVAL);
1103  }
1104  }
1105  av_strlcpy(rel_url, &(media_url[base_len + 1]), rel_url_buf_size);
1106  return 0;
1107 }
1108 
1110  VariantStream * const input_vs)
1111 {
1112  HLSContext *hls = s->priv_data;
1113  VariantStream *vs, *temp_vs;
1114  AVStream *vid_st, *aud_st;
1116  unsigned int i, j;
1117  int m3u8_name_size, ret, bandwidth;
1118  char *m3u8_rel_name;
1119 
1120  input_vs->m3u8_created = 1;
1121  if (!hls->master_m3u8_created) {
1122  /* For the first time, wait until all the media playlists are created */
1123  for (i = 0; i < hls->nb_varstreams; i++)
1124  if (!hls->var_streams[i].m3u8_created)
1125  return 0;
1126  } else {
1127  /* Keep publishing the master playlist at the configured rate */
1128  if (&hls->var_streams[0] != input_vs || !hls->master_publish_rate ||
1129  input_vs->number % hls->master_publish_rate)
1130  return 0;
1131  }
1132 
1133  set_http_options(s, &options, hls);
1134 
1135  ret = hlsenc_io_open(s, &hls->m3u8_out, hls->master_m3u8_url, &options);
1136  av_dict_free(&options);
1137  if (ret < 0) {
1138  av_log(NULL, AV_LOG_ERROR, "Failed to open master play list file '%s'\n",
1139  hls->master_m3u8_url);
1140  goto fail;
1141  }
1142 
1144 
1145  /* For audio only variant streams add #EXT-X-MEDIA tag with attributes*/
1146  for (i = 0; i < hls->nb_varstreams; i++) {
1147  vs = &(hls->var_streams[i]);
1148 
1149  if (vs->has_video || vs->has_subtitle || !vs->agroup)
1150  continue;
1151 
1152  m3u8_name_size = strlen(vs->m3u8_name) + 1;
1153  m3u8_rel_name = av_malloc(m3u8_name_size);
1154  if (!m3u8_rel_name) {
1155  ret = AVERROR(ENOMEM);
1156  goto fail;
1157  }
1158  av_strlcpy(m3u8_rel_name, vs->m3u8_name, m3u8_name_size);
1159  ret = get_relative_url(hls->master_m3u8_url, vs->m3u8_name,
1160  m3u8_rel_name, m3u8_name_size);
1161  if (ret < 0) {
1162  av_log(s, AV_LOG_ERROR, "Unable to find relative URL\n");
1163  goto fail;
1164  }
1165 
1166  ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, 0, 1);
1167 
1168  av_freep(&m3u8_rel_name);
1169  }
1170 
1171  /* For variant streams with video add #EXT-X-STREAM-INF tag with attributes*/
1172  for (i = 0; i < hls->nb_varstreams; i++) {
1173  vs = &(hls->var_streams[i]);
1174 
1175  m3u8_name_size = strlen(vs->m3u8_name) + 1;
1176  m3u8_rel_name = av_malloc(m3u8_name_size);
1177  if (!m3u8_rel_name) {
1178  ret = AVERROR(ENOMEM);
1179  goto fail;
1180  }
1181  av_strlcpy(m3u8_rel_name, vs->m3u8_name, m3u8_name_size);
1182  ret = get_relative_url(hls->master_m3u8_url, vs->m3u8_name,
1183  m3u8_rel_name, m3u8_name_size);
1184  if (ret < 0) {
1185  av_log(NULL, AV_LOG_ERROR, "Unable to find relative URL\n");
1186  goto fail;
1187  }
1188 
1189  vid_st = NULL;
1190  aud_st = NULL;
1191  for (j = 0; j < vs->nb_streams; j++) {
1193  vid_st = vs->streams[j];
1194  else if (vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
1195  aud_st = vs->streams[j];
1196  }
1197 
1198  if (!vid_st && !aud_st) {
1199  av_log(NULL, AV_LOG_WARNING, "Media stream not found\n");
1200  continue;
1201  }
1202 
1203  /**
1204  * Traverse through the list of audio only rendition streams and find
1205  * the rendition which has highest bitrate in the same audio group
1206  */
1207  if (vs->agroup) {
1208  for (j = 0; j < hls->nb_varstreams; j++) {
1209  temp_vs = &(hls->var_streams[j]);
1210  if (!temp_vs->has_video && !temp_vs->has_subtitle &&
1211  temp_vs->agroup &&
1212  !av_strcasecmp(temp_vs->agroup, vs->agroup)) {
1213  if (!aud_st)
1214  aud_st = temp_vs->streams[0];
1215  if (temp_vs->streams[0]->codecpar->bit_rate >
1216  aud_st->codecpar->bit_rate)
1217  aud_st = temp_vs->streams[0];
1218  }
1219  }
1220  }
1221 
1222  bandwidth = 0;
1223  if (vid_st)
1224  bandwidth += vid_st->codecpar->bit_rate;
1225  if (aud_st)
1226  bandwidth += aud_st->codecpar->bit_rate;
1227  bandwidth += bandwidth / 10;
1228 
1229  ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, m3u8_rel_name,
1230  aud_st ? vs->agroup : NULL);
1231 
1232  av_freep(&m3u8_rel_name);
1233  }
1234 fail:
1235  if(ret >=0)
1236  hls->master_m3u8_created = 1;
1237  av_freep(&m3u8_rel_name);
1238  hlsenc_io_close(s, &hls->m3u8_out, hls->master_m3u8_url);
1239  return ret;
1240 }
1241 
1242 static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
1243 {
1244  HLSContext *hls = s->priv_data;
1245  HLSSegment *en;
1246  int target_duration = 0;
1247  int ret = 0;
1248  char temp_filename[1024];
1249  int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - vs->nb_entries);
1250  const char *proto = avio_find_protocol_name(s->filename);
1251  int use_rename = proto && !strcmp(proto, "file");
1252  static unsigned warned_non_file;
1253  char *key_uri = NULL;
1254  char *iv_string = NULL;
1256  double prog_date_time = vs->initial_prog_date_time;
1257  double *prog_date_time_p = (hls->flags & HLS_PROGRAM_DATE_TIME) ? &prog_date_time : NULL;
1258  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
1259 
1260  hls->version = 3;
1261  if (byterange_mode) {
1262  hls->version = 4;
1263  sequence = 0;
1264  }
1265 
1266  if (hls->flags & HLS_INDEPENDENT_SEGMENTS) {
1267  hls->version = 6;
1268  }
1269 
1270  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1271  hls->version = 7;
1272  }
1273 
1274  if (!use_rename && !warned_non_file++)
1275  av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n");
1276 
1277  set_http_options(s, &options, hls);
1278  snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", vs->m3u8_name);
1279  if ((ret = hlsenc_io_open(s, &hls->m3u8_out, temp_filename, &options)) < 0)
1280  goto fail;
1281 
1282  for (en = vs->segments; en; en = en->next) {
1283  if (target_duration <= en->duration)
1284  target_duration = lrint(en->duration);
1285  }
1286 
1287  vs->discontinuity_set = 0;
1289  target_duration, sequence, hls->pl_type);
1290 
1291  if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && vs->discontinuity_set==0 ){
1292  avio_printf(hls->m3u8_out, "#EXT-X-DISCONTINUITY\n");
1293  vs->discontinuity_set = 1;
1294  }
1295  if (vs->has_video && (hls->flags & HLS_INDEPENDENT_SEGMENTS)) {
1296  avio_printf(hls->m3u8_out, "#EXT-X-INDEPENDENT-SEGMENTS\n");
1297  }
1298  for (en = vs->segments; en; en = en->next) {
1299  if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) ||
1300  av_strcasecmp(en->iv_string, iv_string))) {
1301  avio_printf(hls->m3u8_out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", en->key_uri);
1302  if (*en->iv_string)
1303  avio_printf(hls->m3u8_out, ",IV=0x%s", en->iv_string);
1304  avio_printf(hls->m3u8_out, "\n");
1305  key_uri = en->key_uri;
1306  iv_string = en->iv_string;
1307  }
1308 
1309  if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == vs->segments)) {
1311  hls->flags & HLS_SINGLE_FILE, en->size, en->pos);
1312  }
1313 
1314  ret = ff_hls_write_file_entry(hls->m3u8_out, en->discont, byterange_mode,
1315  en->duration, hls->flags & HLS_ROUND_DURATIONS,
1316  en->size, en->pos, vs->baseurl,
1317  en->filename, prog_date_time_p);
1318  if (ret < 0) {
1319  av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
1320  }
1321  }
1322 
1323  if (last && (hls->flags & HLS_OMIT_ENDLIST)==0)
1325 
1326  if( vs->vtt_m3u8_name ) {
1327  if ((ret = hlsenc_io_open(s, &hls->sub_m3u8_out, vs->vtt_m3u8_name, &options)) < 0)
1328  goto fail;
1330  target_duration, sequence, PLAYLIST_TYPE_NONE);
1331  for (en = vs->segments; en; en = en->next) {
1332  ret = ff_hls_write_file_entry(hls->sub_m3u8_out, 0, byterange_mode,
1333  en->duration, 0, en->size, en->pos,
1334  vs->baseurl, en->sub_filename, NULL);
1335  if (ret < 0) {
1336  av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
1337  }
1338  }
1339 
1340  if (last)
1342 
1343  }
1344 
1345 fail:
1346  av_dict_free(&options);
1347  hlsenc_io_close(s, &hls->m3u8_out, temp_filename);
1349  if (ret >= 0 && use_rename)
1350  ff_rename(temp_filename, vs->m3u8_name, s);
1351 
1352  if (ret >= 0 && hls->master_pl_name)
1353  if (create_master_playlist(s, vs) < 0)
1354  av_log(s, AV_LOG_WARNING, "Master playlist creation failed\n");
1355 
1356  return ret;
1357 }
1358 
1360 {
1361  HLSContext *c = s->priv_data;
1362  AVFormatContext *oc = vs->avf;
1363  AVFormatContext *vtt_oc = vs->vtt_avf;
1365  char *filename, iv_string[KEYSIZE*2 + 1];
1366  int err = 0;
1367 
1368  if (c->flags & HLS_SINGLE_FILE) {
1369  av_strlcpy(oc->filename, vs->basename,
1370  sizeof(oc->filename));
1371  if (vs->vtt_basename)
1372  av_strlcpy(vtt_oc->filename, vs->vtt_basename,
1373  sizeof(vtt_oc->filename));
1374  } else if (c->max_seg_size > 0) {
1375  if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
1376 #if FF_API_HLS_WRAP
1377  vs->basename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
1378 #else
1379  vs->basename, 'd', vs->sequence) < 1) {
1380 #endif
1381  av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s', you can try to use -use_localtime 1 with it\n", vs->basename);
1382  return AVERROR(EINVAL);
1383  }
1384  } else {
1385  if (c->use_localtime) {
1386  time_t now0;
1387  struct tm *tm, tmpbuf;
1388  time(&now0);
1389  tm = localtime_r(&now0, &tmpbuf);
1390  if (!strftime(oc->filename, sizeof(oc->filename), vs->basename, tm)) {
1391  av_log(oc, AV_LOG_ERROR, "Could not get segment filename with use_localtime\n");
1392  return AVERROR(EINVAL);
1393  }
1394 
1395  err = sls_flag_use_localtime_filename(oc, c, vs);
1396  if (err < 0) {
1397  return AVERROR(ENOMEM);
1398  }
1399 
1400  if (c->use_localtime_mkdir) {
1401  const char *dir;
1402  char *fn_copy = av_strdup(oc->filename);
1403  if (!fn_copy) {
1404  return AVERROR(ENOMEM);
1405  }
1406  dir = av_dirname(fn_copy);
1407  if (mkdir_p(dir) == -1 && errno != EEXIST) {
1408  av_log(oc, AV_LOG_ERROR, "Could not create directory %s with use_localtime_mkdir\n", dir);
1409  av_free(fn_copy);
1410  return AVERROR(errno);
1411  }
1412  av_free(fn_copy);
1413  }
1414  } else if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),
1415 #if FF_API_HLS_WRAP
1416  vs->basename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
1417 #else
1418  vs->basename, 'd', vs->sequence) < 1) {
1419 #endif
1420  av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s' you can try to use -use_localtime 1 with it\n", vs->basename);
1421  return AVERROR(EINVAL);
1422  }
1423  if( vs->vtt_basename) {
1424  if (replace_int_data_in_filename(vtt_oc->filename, sizeof(vtt_oc->filename),
1425 #if FF_API_HLS_WRAP
1426  vs->vtt_basename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
1427 #else
1428  vs->vtt_basename, 'd', vs->sequence) < 1) {
1429 #endif
1430  av_log(vtt_oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", vs->vtt_basename);
1431  return AVERROR(EINVAL);
1432  }
1433  }
1434  }
1435  vs->number++;
1436 
1437  set_http_options(s, &options, c);
1438 
1439  if (c->flags & HLS_TEMP_FILE) {
1440  av_strlcat(oc->filename, ".tmp", sizeof(oc->filename));
1441  }
1442 
1443  if (c->key_info_file || c->encrypt) {
1444  if (c->key_info_file && c->encrypt) {
1445  av_log(s, AV_LOG_WARNING, "Cannot use both -hls_key_info_file and -hls_enc,"
1446  " will use -hls_key_info_file priority\n");
1447  }
1448 
1449  if (!c->encrypt_started || (c->flags & HLS_PERIODIC_REKEY)) {
1450  if (c->key_info_file) {
1451  if ((err = hls_encryption_start(s)) < 0)
1452  goto fail;
1453  } else {
1454  if ((err = do_encrypt(s, vs)) < 0)
1455  goto fail;
1456  }
1457  c->encrypt_started = 1;
1458  }
1459  if ((err = av_dict_set(&options, "encryption_key", c->key_string, 0))
1460  < 0)
1461  goto fail;
1462  err = av_strlcpy(iv_string, c->iv_string, sizeof(iv_string));
1463  if (!err)
1464  snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, vs->sequence);
1465  if ((err = av_dict_set(&options, "encryption_iv", iv_string, 0)) < 0)
1466  goto fail;
1467 
1468  filename = av_asprintf("crypto:%s", oc->filename);
1469  if (!filename) {
1470  err = AVERROR(ENOMEM);
1471  goto fail;
1472  }
1473  err = hlsenc_io_open(s, &oc->pb, filename, &options);
1474  av_free(filename);
1475  av_dict_free(&options);
1476  if (err < 0)
1477  return err;
1478  } else if (c->segment_type != SEGMENT_TYPE_FMP4) {
1479  if ((err = hlsenc_io_open(s, &oc->pb, oc->filename, &options)) < 0)
1480  goto fail;
1481  }
1482  if (vs->vtt_basename) {
1483  set_http_options(s, &options, c);
1484  if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->filename, &options)) < 0)
1485  goto fail;
1486  }
1487  av_dict_free(&options);
1488 
1489  if (c->segment_type != SEGMENT_TYPE_FMP4) {
1490  /* We only require one PAT/PMT per segment. */
1491  if (oc->oformat->priv_class && oc->priv_data) {
1492  char period[21];
1493 
1494  snprintf(period, sizeof(period), "%d", (INT_MAX / 2) - 1);
1495 
1496  av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0);
1497  av_opt_set(oc->priv_data, "sdt_period", period, 0);
1498  av_opt_set(oc->priv_data, "pat_period", period, 0);
1499  }
1500  }
1501 
1502  if (vs->vtt_basename) {
1503  err = avformat_write_header(vtt_oc,NULL);
1504  if (err < 0)
1505  return err;
1506  }
1507 
1508  return 0;
1509 fail:
1510  av_dict_free(&options);
1511 
1512  return err;
1513 }
1514 
1516 {
1517  char b[21];
1518  time_t t = time(NULL);
1519  struct tm *p, tmbuf;
1520  HLSContext *hls = s->priv_data;
1521 
1522  p = localtime_r(&t, &tmbuf);
1523  // no %s support when strftime returned error or left format string unchanged
1524  // also no %s support on MSVC, which invokes the invalid parameter handler on unsupported format strings, instead of returning an error
1525  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1526  return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.m4s" : "-%s.m4s";
1527  }
1528  return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.ts" : "-%s.ts";
1529 }
1530 
1531 static int append_postfix(char *name, int name_buf_len, int i)
1532 {
1533  char *p;
1534  char extension[10] = {'\0'};
1535 
1536  p = strrchr(name, '.');
1537  if (p) {
1538  av_strlcpy(extension, p, sizeof(extension));
1539  *p = '\0';
1540  }
1541 
1542  snprintf(name + strlen(name), name_buf_len - strlen(name), POSTFIX_PATTERN, i);
1543 
1544  if (strlen(extension))
1545  av_strlcat(name, extension, name_buf_len);
1546 
1547  return 0;
1548 }
1549 
1550 static int validate_name(int nb_vs, const char *fn)
1551 {
1552  const char *filename, *subdir_name;
1553  char *fn_dup = NULL;
1554  int ret = 0;
1555 
1556  if (!fn) {
1557  ret = AVERROR(EINVAL);
1558  goto fail;
1559  }
1560 
1561  fn_dup = av_strdup(fn);
1562  if (!fn_dup) {
1563  ret = AVERROR(ENOMEM);
1564  goto fail;
1565  }
1566 
1567  filename = av_basename(fn);
1568  subdir_name = av_dirname(fn_dup);
1569 
1570  if (nb_vs > 1 && !av_stristr(filename, "%v") && !av_stristr(subdir_name, "%v")) {
1571  av_log(NULL, AV_LOG_ERROR, "More than 1 variant streams are present, %%v is expected in the filename %s\n",
1572  fn);
1573  ret = AVERROR(EINVAL);
1574  goto fail;
1575  }
1576 
1577  if (av_stristr(filename, "%v") && av_stristr(subdir_name, "%v")) {
1578  av_log(NULL, AV_LOG_ERROR, "%%v is expected either in filename or in the sub-directory name of file %s\n",
1579  fn);
1580  ret = AVERROR(EINVAL);
1581  goto fail;
1582  }
1583 
1584 fail:
1585  av_freep(&fn_dup);
1586  return ret;
1587 }
1588 
1589 static int format_name(char *buf, int buf_len, int index)
1590 {
1591  const char *proto, *dir;
1592  char *orig_buf_dup = NULL, *mod_buf_dup = NULL;
1593  int ret = 0;
1594 
1595  if (!av_stristr(buf, "%v"))
1596  return ret;
1597 
1598  orig_buf_dup = av_strdup(buf);
1599  if (!orig_buf_dup) {
1600  ret = AVERROR(ENOMEM);
1601  goto fail;
1602  }
1603 
1604  if (replace_int_data_in_filename(buf, buf_len, orig_buf_dup, 'v', index) < 1) {
1605  ret = AVERROR(EINVAL);
1606  goto fail;
1607  }
1608 
1609  proto = avio_find_protocol_name(orig_buf_dup);
1610  dir = av_dirname(orig_buf_dup);
1611 
1612  /* if %v is present in the file's directory, create sub-directory */
1613  if (av_stristr(dir, "%v") && proto && !strcmp(proto, "file")) {
1614  mod_buf_dup = av_strdup(buf);
1615  if (!mod_buf_dup) {
1616  ret = AVERROR(ENOMEM);
1617  goto fail;
1618  }
1619 
1620  dir = av_dirname(mod_buf_dup);
1621  if (mkdir_p(dir) == -1 && errno != EEXIST) {
1622  ret = AVERROR(errno);
1623  goto fail;
1624  }
1625  }
1626 
1627 fail:
1628  av_freep(&orig_buf_dup);
1629  av_freep(&mod_buf_dup);
1630  return ret;
1631 }
1632 
1634  enum AVMediaType codec_type,
1635  int stream_id)
1636 {
1637  unsigned int stream_index, cnt;
1638  if (stream_id < 0 || stream_id > s->nb_streams - 1)
1639  return -1;
1640  cnt = 0;
1641  for (stream_index = 0; stream_index < s->nb_streams; stream_index++) {
1642  if (s->streams[stream_index]->codecpar->codec_type != codec_type)
1643  continue;
1644  if (cnt == stream_id)
1645  return stream_index;
1646  cnt++;
1647  }
1648  return -1;
1649 }
1650 
1652 {
1653  HLSContext *hls = s->priv_data;
1654  VariantStream *vs;
1655  int stream_index;
1656  enum AVMediaType codec_type;
1657  int nb_varstreams, nb_streams;
1658  char *p, *q, *saveptr1, *saveptr2, *varstr, *keyval;
1659  const char *val;
1660 
1661  /**
1662  * Expected format for var_stream_map string is as below:
1663  * "a:0,v:0 a:1,v:1"
1664  * "a:0,agroup:a0 a:1,agroup:a1 v:0,agroup:a0 v:1,agroup:a1"
1665  * This string specifies how to group the audio, video and subtitle streams
1666  * into different variant streams. The variant stream groups are separated
1667  * by space.
1668  *
1669  * a:, v:, s: are keys to specify audio, video and subtitle streams
1670  * respectively. Allowed values are 0 to 9 digits (limited just based on
1671  * practical usage)
1672  *
1673  * agroup: is key to specify audio group. A string can be given as value.
1674  */
1675  p = av_strdup(hls->var_stream_map);
1676  q = p;
1677  while(av_strtok(q, " \t", &saveptr1)) {
1678  q = NULL;
1679  hls->nb_varstreams++;
1680  }
1681  av_freep(&p);
1682 
1683  hls->var_streams = av_mallocz(sizeof(*hls->var_streams) * hls->nb_varstreams);
1684  if (!hls->var_streams)
1685  return AVERROR(ENOMEM);
1686 
1687  p = hls->var_stream_map;
1688  nb_varstreams = 0;
1689  while (varstr = av_strtok(p, " \t", &saveptr1)) {
1690  p = NULL;
1691 
1692  if (nb_varstreams < hls->nb_varstreams)
1693  vs = &(hls->var_streams[nb_varstreams++]);
1694  else
1695  return AVERROR(EINVAL);
1696 
1697  q = varstr;
1698  while (q < varstr + strlen(varstr)) {
1699  if (!av_strncasecmp(q, "a:", 2) || !av_strncasecmp(q, "v:", 2) ||
1700  !av_strncasecmp(q, "s:", 2))
1701  vs->nb_streams++;
1702  q++;
1703  }
1704  vs->streams = av_mallocz(sizeof(AVStream *) * vs->nb_streams);
1705  if (!vs->streams)
1706  return AVERROR(ENOMEM);
1707 
1708  nb_streams = 0;
1709  while (keyval = av_strtok(varstr, ",", &saveptr2)) {
1710  varstr = NULL;
1711 
1712  if (av_strstart(keyval, "agroup:", &val)) {
1713  vs->agroup = av_strdup(val);
1714  if (!vs->agroup)
1715  return AVERROR(ENOMEM);
1716  continue;
1717  } else if (av_strstart(keyval, "v:", &val)) {
1718  codec_type = AVMEDIA_TYPE_VIDEO;
1719  } else if (av_strstart(keyval, "a:", &val)) {
1720  codec_type = AVMEDIA_TYPE_AUDIO;
1721  } else if (av_strstart(keyval, "s:", &val)) {
1722  codec_type = AVMEDIA_TYPE_SUBTITLE;
1723  } else {
1724  av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
1725  return AVERROR(EINVAL);
1726  }
1727 
1728  stream_index = -1;
1729  if (av_isdigit(*val))
1730  stream_index = get_nth_codec_stream_index (s, codec_type,
1731  atoi(val));
1732 
1733  if (stream_index >= 0 && nb_streams < vs->nb_streams) {
1734  vs->streams[nb_streams++] = s->streams[stream_index];
1735  } else {
1736  av_log(s, AV_LOG_ERROR, "Unable to map stream at %s\n", keyval);
1737  return AVERROR(EINVAL);
1738  }
1739  }
1740  }
1741  av_log(s, AV_LOG_DEBUG, "Number of variant streams %d\n",
1742  hls->nb_varstreams);
1743 
1744  return 0;
1745 }
1746 
1748  HLSContext *hls = s->priv_data;
1749  unsigned int i;
1750 
1751  if (hls->var_stream_map) {
1753  } else {
1754  //By default, a single variant stream with all the codec streams is created
1755  hls->nb_varstreams = 1;
1756  hls->var_streams = av_mallocz(sizeof(*hls->var_streams) *
1757  hls->nb_varstreams);
1758  if (!hls->var_streams)
1759  return AVERROR(ENOMEM);
1760 
1761  hls->var_streams[0].nb_streams = s->nb_streams;
1762  hls->var_streams[0].streams = av_mallocz(sizeof(AVStream *) *
1763  hls->var_streams[0].nb_streams);
1764  if (!hls->var_streams[0].streams)
1765  return AVERROR(ENOMEM);
1766 
1767  for (i = 0; i < s->nb_streams; i++)
1768  hls->var_streams[0].streams[i] = s->streams[i];
1769  }
1770  return 0;
1771 }
1772 
1774  HLSContext *hls = s->priv_data;
1775  const char *dir;
1776  char *fn1= NULL, *fn2 = NULL;
1777  int ret = 0;
1778 
1779  fn1 = av_strdup(s->filename);
1780  if (!fn1) {
1781  ret = AVERROR(ENOMEM);
1782  goto fail;
1783  }
1784 
1785  dir = av_dirname(fn1);
1786 
1787  /**
1788  * if output file's directory has %v, variants are created in sub-directories
1789  * then master is created at the sub-directories level
1790  */
1791  if (dir && av_stristr(av_basename(dir), "%v")) {
1792  fn2 = av_strdup(dir);
1793  if (!fn2) {
1794  ret = AVERROR(ENOMEM);
1795  goto fail;
1796  }
1797  dir = av_dirname(fn2);
1798  }
1799 
1800  if (dir && strcmp(dir, "."))
1802  else
1804 
1805  if (!hls->master_m3u8_url) {
1806  ret = AVERROR(ENOMEM);
1807  goto fail;
1808  }
1809 
1810 fail:
1811  av_freep(&fn1);
1812  av_freep(&fn2);
1813 
1814  return ret;
1815 }
1816 
1818 {
1819  HLSContext *hls = s->priv_data;
1820  int ret, i, j;
1821  AVDictionary *options = NULL;
1822  VariantStream *vs = NULL;
1823 
1824  for (i = 0; i < hls->nb_varstreams; i++) {
1825  vs = &hls->var_streams[i];
1826 
1827  av_dict_copy(&options, hls->format_options, 0);
1828  ret = avformat_write_header(vs->avf, &options);
1829  if (av_dict_count(options)) {
1830  av_log(s, AV_LOG_ERROR, "Some of provided format options in '%s' are not recognized\n", hls->format_options_str);
1831  ret = AVERROR(EINVAL);
1832  av_dict_free(&options);
1833  goto fail;
1834  }
1835  av_dict_free(&options);
1836  //av_assert0(s->nb_streams == hls->avf->nb_streams);
1837  for (j = 0; j < vs->nb_streams; j++) {
1838  AVStream *inner_st;
1839  AVStream *outer_st = vs->streams[j];
1840 
1841  if (hls->max_seg_size > 0) {
1842  if ((outer_st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
1843  (outer_st->codecpar->bit_rate > hls->max_seg_size)) {
1844  av_log(s, AV_LOG_WARNING, "Your video bitrate is bigger than hls_segment_size, "
1845  "(%"PRId64 " > %"PRId64 "), the result maybe not be what you want.",
1846  outer_st->codecpar->bit_rate, hls->max_seg_size);
1847  }
1848  }
1849 
1850  if (outer_st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
1851  inner_st = vs->avf->streams[j];
1852  else if (vs->vtt_avf)
1853  inner_st = vs->vtt_avf->streams[0];
1854  else {
1855  /* We have a subtitle stream, when the user does not want one */
1856  inner_st = NULL;
1857  continue;
1858  }
1859  avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
1860  }
1861  }
1862 fail:
1863 
1864  return ret;
1865 }
1866 
1868 {
1869  HLSContext *hls = s->priv_data;
1870  AVFormatContext *oc = NULL;
1871  AVStream *st = s->streams[pkt->stream_index];
1872  int64_t end_pts = 0;
1873  int is_ref_pkt = 1;
1874  int ret = 0, can_split = 1, i, j;
1875  int stream_index = 0;
1876  int range_length = 0;
1877  uint8_t *buffer = NULL;
1878  VariantStream *vs = NULL;
1879 
1880  for (i = 0; i < hls->nb_varstreams; i++) {
1881  vs = &hls->var_streams[i];
1882  for (j = 0; j < vs->nb_streams; j++) {
1883  if (vs->streams[j] == st) {
1884  if( st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE ) {
1885  oc = vs->vtt_avf;
1886  stream_index = 0;
1887  } else {
1888  oc = vs->avf;
1889  stream_index = j;
1890  }
1891  break;
1892  }
1893  }
1894 
1895  if (oc)
1896  break;
1897  }
1898 
1899  if (!oc) {
1900  av_log(s, AV_LOG_ERROR, "Unable to find mapping variant stream\n");
1901  return AVERROR(ENOMEM);
1902  }
1903 
1904  end_pts = hls->recording_time * vs->number;
1905 
1906  if (vs->sequence - vs->nb_entries > hls->start_sequence && hls->init_time > 0) {
1907  /* reset end_pts, hls->recording_time at end of the init hls list */
1908  int init_list_dur = hls->init_time * vs->nb_entries * AV_TIME_BASE;
1909  int after_init_list_dur = (vs->sequence - vs->nb_entries ) * hls->time * AV_TIME_BASE;
1910  hls->recording_time = hls->time * AV_TIME_BASE;
1911  end_pts = init_list_dur + after_init_list_dur ;
1912  }
1913 
1914  if (vs->start_pts == AV_NOPTS_VALUE) {
1915  vs->start_pts = pkt->pts;
1916  }
1917 
1918  if (vs->has_video) {
1919  can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
1920  ((pkt->flags & AV_PKT_FLAG_KEY) || (hls->flags & HLS_SPLIT_BY_TIME));
1921  is_ref_pkt = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO;
1922  }
1923  if (pkt->pts == AV_NOPTS_VALUE)
1924  is_ref_pkt = can_split = 0;
1925 
1926  if (is_ref_pkt) {
1927  if (vs->end_pts == AV_NOPTS_VALUE)
1928  vs->end_pts = pkt->pts;
1929  if (vs->new_start) {
1930  vs->new_start = 0;
1931  vs->duration = (double)(pkt->pts - vs->end_pts)
1932  * st->time_base.num / st->time_base.den;
1933  vs->dpp = (double)(pkt->duration) * st->time_base.num / st->time_base.den;
1934  } else {
1935  if (pkt->duration) {
1936  vs->duration += (double)(pkt->duration) * st->time_base.num / st->time_base.den;
1937  } else {
1938  av_log(s, AV_LOG_WARNING, "pkt->duration = 0, maybe the hls segment duration will not precise\n");
1939  vs->duration = (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den;
1940  }
1941  }
1942 
1943  }
1944 
1945  if (vs->packets_written && can_split && av_compare_ts(pkt->pts - vs->start_pts, st->time_base,
1946  end_pts, AV_TIME_BASE_Q) >= 0) {
1947  int64_t new_start_pos;
1948  char *old_filename = av_strdup(vs->avf->filename);
1949  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
1950 
1951  if (!old_filename) {
1952  return AVERROR(ENOMEM);
1953  }
1954 
1955  av_write_frame(vs->avf, NULL); /* Flush any buffered data */
1956 
1957  new_start_pos = avio_tell(vs->avf->pb);
1958  vs->size = new_start_pos - vs->start_pos;
1959 
1960  if (!byterange_mode) {
1961  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1962  if (!vs->init_range_length) {
1963  avio_flush(oc->pb);
1964  range_length = avio_close_dyn_buf(oc->pb, &buffer);
1965  avio_write(vs->out, buffer, range_length);
1966  vs->init_range_length = range_length;
1967  avio_open_dyn_buf(&oc->pb);
1968  vs->packets_written = 0;
1969  ff_format_io_close(s, &vs->out);
1970  hlsenc_io_close(s, &vs->out, vs->base_output_dirname);
1971  }
1972  } else {
1973  hlsenc_io_close(s, &oc->pb, oc->filename);
1974  }
1975  if (vs->vtt_avf) {
1976  hlsenc_io_close(s, &vs->vtt_avf->pb, vs->vtt_avf->filename);
1977  }
1978  }
1979  if ((hls->flags & HLS_TEMP_FILE) && oc->filename[0]) {
1980  if (!(hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size <= 0))
1981  if ((vs->avf->oformat->priv_class && vs->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4)
1982  av_opt_set(vs->avf->priv_data, "mpegts_flags", "resend_headers", 0);
1983  hls_rename_temp_file(s, oc);
1984  }
1985 
1986  if (vs->fmp4_init_mode) {
1987  vs->number--;
1988  }
1989 
1990  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1991  ret = hlsenc_io_open(s, &vs->out, vs->avf->filename, NULL);
1992  if (ret < 0) {
1993  av_log(NULL, AV_LOG_ERROR, "Failed to open file '%s'\n",
1994  vs->avf->filename);
1995  av_free(old_filename);
1996  return ret;
1997  }
1998  write_styp(vs->out);
1999  ret = flush_dynbuf(vs, &range_length);
2000  if (ret < 0) {
2001  av_free(old_filename);
2002  return ret;
2003  }
2004  ff_format_io_close(s, &vs->out);
2005  }
2006  ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size);
2007  vs->start_pos = new_start_pos;
2008  if (ret < 0) {
2009  av_free(old_filename);
2010  return ret;
2011  }
2012 
2013  vs->end_pts = pkt->pts;
2014  vs->duration = 0;
2015 
2016  vs->fmp4_init_mode = 0;
2017  if (hls->flags & HLS_SINGLE_FILE) {
2018  vs->number++;
2019  } else if (hls->max_seg_size > 0) {
2020  if (vs->start_pos >= hls->max_seg_size) {
2021  vs->sequence++;
2022  sls_flag_file_rename(hls, vs, old_filename);
2023  ret = hls_start(s, vs);
2024  vs->start_pos = 0;
2025  /* When split segment by byte, the duration is short than hls_time,
2026  * so it is not enough one segment duration as hls_time, */
2027  vs->number--;
2028  }
2029  vs->number++;
2030  } else {
2031  sls_flag_file_rename(hls, vs, old_filename);
2032  ret = hls_start(s, vs);
2033  }
2034  av_free(old_filename);
2035 
2036  if (ret < 0) {
2037  return ret;
2038  }
2039 
2040  if (!vs->fmp4_init_mode || byterange_mode)
2041  if ((ret = hls_window(s, 0, vs)) < 0) {
2042  return ret;
2043  }
2044  }
2045 
2046  vs->packets_written++;
2047  ret = ff_write_chained(oc, stream_index, pkt, s, 0);
2048 
2049  return ret;
2050 }
2051 
2052 static int hls_write_trailer(struct AVFormatContext *s)
2053 {
2054  HLSContext *hls = s->priv_data;
2055  AVFormatContext *oc = NULL;
2056  AVFormatContext *vtt_oc = NULL;
2057  char *old_filename = NULL;
2058  int i;
2059  int ret = 0;
2060  VariantStream *vs = NULL;
2061 
2062  for (i = 0; i < hls->nb_varstreams; i++) {
2063  vs = &hls->var_streams[i];
2064 
2065  oc = vs->avf;
2066  vtt_oc = vs->vtt_avf;
2067  old_filename = av_strdup(vs->avf->filename);
2068 
2069  if (!old_filename) {
2070  return AVERROR(ENOMEM);
2071  }
2072  if ( hls->segment_type == SEGMENT_TYPE_FMP4) {
2073  int range_length = 0;
2074  ret = hlsenc_io_open(s, &vs->out, vs->avf->filename, NULL);
2075  if (ret < 0) {
2076  av_log(NULL, AV_LOG_ERROR, "Failed to open file '%s'\n", vs->avf->filename);
2077  goto failed;
2078  }
2079  write_styp(vs->out);
2080  ret = flush_dynbuf(vs, &range_length);
2081  if (ret < 0) {
2082  goto failed;
2083  }
2084  ff_format_io_close(s, &vs->out);
2085  }
2086 
2087 failed:
2088  av_write_trailer(oc);
2089  if (oc->pb) {
2090  vs->size = avio_tell(vs->avf->pb) - vs->start_pos;
2091  if (hls->segment_type != SEGMENT_TYPE_FMP4)
2092  ff_format_io_close(s, &oc->pb);
2093 
2094  if ((hls->flags & HLS_TEMP_FILE) && oc->filename[0]) {
2095  hls_rename_temp_file(s, oc);
2096  }
2097 
2098  /* after av_write_trailer, then duration + 1 duration per packet */
2099  hls_append_segment(s, hls, vs, vs->duration + vs->dpp, vs->start_pos, vs->size);
2100  }
2101 
2102  sls_flag_file_rename(hls, vs, old_filename);
2103 
2104  if (vtt_oc) {
2105  if (vtt_oc->pb)
2106  av_write_trailer(vtt_oc);
2107  vs->size = avio_tell(vs->vtt_avf->pb) - vs->start_pos;
2108  ff_format_io_close(s, &vtt_oc->pb);
2109  }
2110  av_freep(&vs->basename);
2113 
2114  vs->avf = NULL;
2115  hls_window(s, 1, vs);
2116 
2118  if (vtt_oc) {
2119  av_freep(&vs->vtt_basename);
2120  av_freep(&vs->vtt_m3u8_name);
2121  avformat_free_context(vtt_oc);
2122  }
2123 
2126  av_free(old_filename);
2127  av_freep(&vs->m3u8_name);
2128  av_freep(&vs->streams);
2129  av_freep(&vs->agroup);
2130  av_freep(&vs->baseurl);
2131  }
2132 
2133  ff_format_io_close(s, &hls->m3u8_out);
2134  ff_format_io_close(s, &hls->sub_m3u8_out);
2135  av_freep(&hls->key_basename);
2136  av_freep(&hls->var_streams);
2137  av_freep(&hls->master_m3u8_url);
2138  return 0;
2139 }
2140 
2141 
2143 {
2144  int ret = 0;
2145  int i = 0;
2146  int j = 0;
2147  HLSContext *hls = s->priv_data;
2148  const char *pattern = "%d.ts";
2149  VariantStream *vs = NULL;
2150  int basename_size = 0;
2151  const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s);
2152  const char *vtt_pattern = "%d.vtt";
2153  char *p = NULL;
2154  int vtt_basename_size = 0;
2155  int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
2156 
2157  ret = update_variant_stream_info(s);
2158  if (ret < 0) {
2159  av_log(s, AV_LOG_ERROR, "Variant stream info update failed with status %x\n",
2160  ret);
2161  goto fail;
2162  }
2163  //TODO: Updates needed to encryption functionality with periodic re-key when more than one variant streams are present
2164  if (hls->nb_varstreams > 1 && hls->flags & HLS_PERIODIC_REKEY) {
2165  ret = AVERROR(EINVAL);
2166  av_log(s, AV_LOG_ERROR, "Periodic re-key not supported when more than one variant streams are present\n");
2167  goto fail;
2168  }
2169 
2170  ret = validate_name(hls->nb_varstreams, s->filename);
2171  if (ret < 0)
2172  goto fail;
2173 
2174  if (hls->segment_filename) {
2175  ret = validate_name(hls->nb_varstreams, hls->segment_filename);
2176  if (ret < 0)
2177  goto fail;
2178  }
2179 
2180  if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
2182  if (ret < 0)
2183  goto fail;
2184  }
2185 
2186  if (hls->subtitle_filename) {
2187  ret = validate_name(hls->nb_varstreams, hls->subtitle_filename);
2188  if (ret < 0)
2189  goto fail;
2190  }
2191 
2192  if (hls->master_pl_name) {
2193  ret = update_master_pl_info(s);
2194  if (ret < 0) {
2195  av_log(s, AV_LOG_ERROR, "Master stream info update failed with status %x\n",
2196  ret);
2197  goto fail;
2198  }
2199  }
2200 
2201  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2202  pattern = "%d.m4s";
2203  }
2206  time_t t = time(NULL); // we will need it in either case
2208  hls->start_sequence = (int64_t)t;
2210  char b[15];
2211  struct tm *p, tmbuf;
2212  if (!(p = localtime_r(&t, &tmbuf)))
2213  return AVERROR(ENOMEM);
2214  if (!strftime(b, sizeof(b), "%Y%m%d%H%M%S", p))
2215  return AVERROR(ENOMEM);
2216  hls->start_sequence = strtoll(b, NULL, 10);
2217  }
2218  av_log(hls, AV_LOG_DEBUG, "start_number evaluated to %"PRId64"\n", hls->start_sequence);
2219  }
2220 
2221  hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
2222  for (i = 0; i < hls->nb_varstreams; i++) {
2223  vs = &hls->var_streams[i];
2224 
2225  vs->m3u8_name = av_strdup(s->filename);
2226  if (!vs->m3u8_name ) {
2227  ret = AVERROR(ENOMEM);
2228  goto fail;
2229  }
2230  ret = format_name(vs->m3u8_name, strlen(s->filename) + 1, i);
2231  if (ret < 0)
2232  goto fail;
2233 
2234  vs->sequence = hls->start_sequence;
2235  vs->start_pts = AV_NOPTS_VALUE;
2236  vs->end_pts = AV_NOPTS_VALUE;
2237  vs->current_segment_final_filename_fmt[0] = '\0';
2238 
2239  if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
2240  // Independent segments cannot be guaranteed when splitting by time
2243  "'split_by_time' and 'independent_segments' cannot be enabled together. "
2244  "Disabling 'independent_segments' flag\n");
2245  }
2246 
2247  if (hls->flags & HLS_PROGRAM_DATE_TIME) {
2248  time_t now0;
2249  time(&now0);
2250  vs->initial_prog_date_time = now0;
2251  }
2252  if (hls->format_options_str) {
2253  ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
2254  if (ret < 0) {
2255  av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n", hls->format_options_str);
2256  goto fail;
2257  }
2258  }
2259 
2260  for (j = 0; j < vs->nb_streams; j++) {
2263  }
2264 
2265  if (vs->has_video > 1)
2266  av_log(s, AV_LOG_WARNING, "More than a single video stream present, expect issues decoding it.\n");
2267  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2268  vs->oformat = av_guess_format("mp4", NULL, NULL);
2269  } else {
2270  vs->oformat = av_guess_format("mpegts", NULL, NULL);
2271  }
2272 
2273  if (!vs->oformat) {
2275  goto fail;
2276  }
2277 
2278  if (vs->has_subtitle) {
2279  vs->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
2280  if (!vs->oformat) {
2282  goto fail;
2283  }
2284  }
2285  if (hls->segment_filename) {
2286  basename_size = strlen(hls->segment_filename) + 1;
2287  vs->basename = av_malloc(basename_size);
2288  if (!vs->basename) {
2289  ret = AVERROR(ENOMEM);
2290  goto fail;
2291  }
2292 
2293  av_strlcpy(vs->basename, hls->segment_filename, basename_size);
2294  ret = format_name(vs->basename, basename_size, i);
2295  if (ret < 0)
2296  goto fail;
2297  } else {
2298  if (hls->flags & HLS_SINGLE_FILE) {
2299  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2300  pattern = ".m4s";
2301  } else {
2302  pattern = ".ts";
2303  }
2304  }
2305 
2306  if (hls->use_localtime) {
2307  basename_size = strlen(vs->m3u8_name) + strlen(pattern_localtime_fmt) + 1;
2308  } else {
2309  basename_size = strlen(vs->m3u8_name) + strlen(pattern) + 1;
2310  }
2311 
2312  vs->basename = av_malloc(basename_size);
2313  if (!vs->basename) {
2314  ret = AVERROR(ENOMEM);
2315  goto fail;
2316  }
2317 
2318  av_strlcpy(vs->basename, vs->m3u8_name, basename_size);
2319 
2320  p = strrchr(vs->basename, '.');
2321  if (p)
2322  *p = '\0';
2323  if (hls->use_localtime) {
2324  av_strlcat(vs->basename, pattern_localtime_fmt, basename_size);
2325  } else {
2326  av_strlcat(vs->basename, pattern, basename_size);
2327  }
2328  }
2329 
2330  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2331  if (hls->nb_varstreams > 1)
2332  fmp4_init_filename_len += strlen(POSTFIX_PATTERN);
2333  vs->fmp4_init_filename = av_malloc(fmp4_init_filename_len);
2334  if (!vs->fmp4_init_filename ) {
2335  ret = AVERROR(ENOMEM);
2336  goto fail;
2337  }
2339  fmp4_init_filename_len);
2340 
2341  if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
2342  ret = format_name(vs->fmp4_init_filename, fmp4_init_filename_len, i);
2343  if (ret < 0)
2344  goto fail;
2345 
2346  fmp4_init_filename_len = strlen(vs->fmp4_init_filename) + 1;
2347  vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
2348  if (!vs->base_output_dirname) {
2349  ret = AVERROR(ENOMEM);
2350  goto fail;
2351  }
2353  fmp4_init_filename_len);
2354  } else {
2355  if (hls->nb_varstreams > 1) {
2356  ret = append_postfix(vs->fmp4_init_filename, fmp4_init_filename_len, i);
2357  if (ret < 0)
2358  goto fail;
2359  }
2360 
2361  fmp4_init_filename_len = strlen(vs->m3u8_name) +
2362  strlen(vs->fmp4_init_filename) + 1;
2363 
2364  vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
2365  if (!vs->base_output_dirname) {
2366  ret = AVERROR(ENOMEM);
2367  goto fail;
2368  }
2369 
2371  fmp4_init_filename_len);
2372  p = strrchr(vs->base_output_dirname, '/');
2373  if (p) {
2374  *(p + 1) = '\0';
2376  fmp4_init_filename_len);
2377  } else {
2379  fmp4_init_filename_len);
2380  }
2381  }
2382  }
2383 
2384  if (!hls->use_localtime) {
2386  if (ret < 0) {
2387  goto fail;
2388  }
2389  } else {
2390  ret = sls_flag_check_duration_size(hls, vs);
2391  if (ret < 0) {
2392  goto fail;
2393  }
2394  }
2395  if (vs->has_subtitle) {
2396 
2397  if (hls->flags & HLS_SINGLE_FILE)
2398  vtt_pattern = ".vtt";
2399  vtt_basename_size = strlen(vs->m3u8_name) + strlen(vtt_pattern) + 1;
2400 
2401  vs->vtt_basename = av_malloc(vtt_basename_size);
2402  if (!vs->vtt_basename) {
2403  ret = AVERROR(ENOMEM);
2404  goto fail;
2405  }
2406  vs->vtt_m3u8_name = av_malloc(vtt_basename_size);
2407  if (!vs->vtt_m3u8_name ) {
2408  ret = AVERROR(ENOMEM);
2409  goto fail;
2410  }
2411  av_strlcpy(vs->vtt_basename, vs->m3u8_name, vtt_basename_size);
2412  p = strrchr(vs->vtt_basename, '.');
2413  if (p)
2414  *p = '\0';
2415 
2416  if ( hls->subtitle_filename ) {
2417  strcpy(vs->vtt_m3u8_name, hls->subtitle_filename);
2418  ret = format_name(vs->vtt_m3u8_name, vtt_basename_size, i);
2419  if (ret < 0)
2420  goto fail;
2421  } else {
2422  strcpy(vs->vtt_m3u8_name, vs->vtt_basename);
2423  av_strlcat(vs->vtt_m3u8_name, "_vtt.m3u8", vtt_basename_size);
2424  }
2425  av_strlcat(vs->vtt_basename, vtt_pattern, vtt_basename_size);
2426  }
2427 
2428  if (hls->baseurl) {
2429  vs->baseurl = av_strdup(hls->baseurl);
2430  if (!vs->baseurl) {
2431  ret = AVERROR(ENOMEM);
2432  goto fail;
2433  }
2434  }
2435 
2436  if ((hls->flags & HLS_SINGLE_FILE) && (hls->segment_type == SEGMENT_TYPE_FMP4)) {
2438  if (!vs->fmp4_init_filename) {
2439  ret = AVERROR(ENOMEM);
2440  goto fail;
2441  }
2442  }
2443  if ((ret = hls_mux_init(s, vs)) < 0)
2444  goto fail;
2445 
2446  if (hls->flags & HLS_APPEND_LIST) {
2447  parse_playlist(s, vs->m3u8_name, vs);
2448  vs->discontinuity = 1;
2449  if (hls->init_time > 0) {
2450  av_log(s, AV_LOG_WARNING, "append_list mode does not support hls_init_time,"
2451  " hls_init_time value will have no effect\n");
2452  hls->init_time = 0;
2453  hls->recording_time = hls->time * AV_TIME_BASE;
2454  }
2455  }
2456 
2457  if ((ret = hls_start(s, vs)) < 0)
2458  goto fail;
2459  }
2460 
2461 fail:
2462  if (ret < 0) {
2463  av_freep(&hls->key_basename);
2464  for (i = 0; i < hls->nb_varstreams && hls->var_streams; i++) {
2465  vs = &hls->var_streams[i];
2466  av_freep(&vs->basename);
2467  av_freep(&vs->vtt_basename);
2469  av_freep(&vs->m3u8_name);
2470  av_freep(&vs->vtt_m3u8_name);
2471  av_freep(&vs->streams);
2472  av_freep(&vs->agroup);
2473  av_freep(&vs->baseurl);
2474  if (vs->avf)
2476  if (vs->vtt_avf)
2478  }
2479  av_freep(&hls->var_streams);
2480  av_freep(&hls->master_m3u8_url);
2481  }
2482 
2483  return ret;
2484 }
2485 
2486 #define OFFSET(x) offsetof(HLSContext, x)
2487 #define E AV_OPT_FLAG_ENCODING_PARAM
2488 static const AVOption options[] = {
2489  {"start_number", "set first number in the sequence", OFFSET(start_sequence),AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E},
2490  {"hls_time", "set segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E},
2491  {"hls_init_time", "set segment length in seconds at init list", OFFSET(init_time), AV_OPT_TYPE_FLOAT, {.dbl = 0}, 0, FLT_MAX, E},
2492  {"hls_list_size", "set maximum number of playlist entries", OFFSET(max_nb_segments), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E},
2493  {"hls_ts_options","set hls mpegts list of options for the container format used for hls", OFFSET(format_options_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2494  {"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},
2495 #if FF_API_HLS_WRAP
2496  {"hls_wrap", "set number after which the index wraps (will be deprecated)", OFFSET(wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E},
2497 #endif
2498  {"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},
2499  {"hls_base_url", "url to prepend to each playlist entry", OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2500  {"hls_segment_filename", "filename template for segment files", OFFSET(segment_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2501  {"hls_segment_size", "maximum size per segment file, (in bytes)", OFFSET(max_seg_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E},
2502  {"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},
2503  {"hls_enc", "enable AES128 encryption support", OFFSET(encrypt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E},
2504  {"hls_enc_key", "hex-coded 16 byte key to encrypt the segments", OFFSET(key), AV_OPT_TYPE_STRING, .flags = E},
2505  {"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},
2506  {"hls_enc_iv", "hex-coded 16 byte initialization vector", OFFSET(iv), AV_OPT_TYPE_STRING, .flags = E},
2507  {"hls_subtitle_path", "set path of hls subtitles", OFFSET(subtitle_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2508  {"hls_segment_type", "set hls segment files type", OFFSET(segment_type), AV_OPT_TYPE_INT, {.i64 = SEGMENT_TYPE_MPEGTS }, 0, SEGMENT_TYPE_FMP4, E, "segment_type"},
2509  {"mpegts", "make segment file to mpegts files in m3u8", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_MPEGTS }, 0, UINT_MAX, E, "segment_type"},
2510  {"fmp4", "make segment file to fragment mp4 files in m3u8", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_FMP4 }, 0, UINT_MAX, E, "segment_type"},
2511  {"hls_fmp4_init_filename", "set fragment mp4 file init filename", OFFSET(fmp4_init_filename), AV_OPT_TYPE_STRING, {.str = "init.mp4"}, 0, 0, E},
2512  {"hls_flags", "set flags affecting HLS playlist and media file generation", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, 0, UINT_MAX, E, "flags"},
2513  {"single_file", "generate a single media file indexed with byte ranges", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_SINGLE_FILE }, 0, UINT_MAX, E, "flags"},
2514  {"temp_file", "write segment to temporary file and rename when complete", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_TEMP_FILE }, 0, UINT_MAX, E, "flags"},
2515  {"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, "flags"},
2516  {"round_durations", "round durations in m3u8 to whole numbers", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_ROUND_DURATIONS }, 0, UINT_MAX, E, "flags"},
2517  {"discont_start", "start the playlist with a discontinuity tag", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DISCONT_START }, 0, UINT_MAX, E, "flags"},
2518  {"omit_endlist", "Do not append an endlist when ending stream", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_OMIT_ENDLIST }, 0, UINT_MAX, E, "flags"},
2519  {"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, "flags"},
2520  {"append_list", "append the new segments into old hls segment list", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_APPEND_LIST }, 0, UINT_MAX, E, "flags"},
2521  {"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX, E, "flags"},
2522  {"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, "flags"},
2523  {"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, "flags"},
2524  {"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, "flags"},
2525  {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"},
2526  {"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, "flags"},
2527  {"use_localtime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
2528  {"use_localtime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
2529  {"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, "pl_type" },
2530  {"event", "EVENT playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_EVENT }, INT_MIN, INT_MAX, E, "pl_type" },
2531  {"vod", "VOD playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_VOD }, INT_MIN, INT_MAX, E, "pl_type" },
2532  {"method", "set the HTTP method(default: PUT)", OFFSET(method), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2533  {"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_AS_FORMATTED_DATETIME, E, "start_sequence_source_type" },
2534  {"generic", "start_number value (default)", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_START_NUMBER }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
2535  {"epoch", "seconds since epoch", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_SECONDS_SINCE_EPOCH }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
2536  {"datetime", "current datetime as YYYYMMDDhhmmss", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_START_SEQUENCE_AS_FORMATTED_DATETIME }, INT_MIN, INT_MAX, E, "start_sequence_source_type" },
2537  {"http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2538  {"var_stream_map", "Variant stream map string", OFFSET(var_stream_map), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2539  {"master_pl_name", "Create HLS master playlist with this name", OFFSET(master_pl_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2540  {"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},
2541  {"http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
2542  { NULL },
2543 };
2544 
2545 static const AVClass hls_class = {
2546  .class_name = "hls muxer",
2547  .item_name = av_default_item_name,
2548  .option = options,
2549  .version = LIBAVUTIL_VERSION_INT,
2550 };
2551 
2552 
2554  .name = "hls",
2555  .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
2556  .extensions = "m3u8",
2557  .priv_data_size = sizeof(HLSContext),
2558  .audio_codec = AV_CODEC_ID_AAC,
2559  .video_codec = AV_CODEC_ID_H264,
2560  .subtitle_codec = AV_CODEC_ID_WEBVTT,
2562  .init = hls_init,
2566  .priv_class = &hls_class,
2567 };
float time
Definition: hlsenc.c:156
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:678
#define NULL
Definition: coverity.c:32
const char const char void * val
Definition: avisynth_c.h:771
char key_uri[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:189
const char * s
Definition: avisynth_c.h:768
Bytestream IO Context.
Definition: avio.h:161
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static av_const int av_isdigit(int c)
Locale-independent conversion of ASCII isdigit.
Definition: avstring.h:206
char * master_m3u8_url
Definition: hlsenc.c:201
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1586
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1364
AVOption.
Definition: opt.h:246
static int hls_write_trailer(struct AVFormatContext *s)
Definition: hlsenc.c:2052
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:859
char current_segment_final_filename_fmt[1024]
Definition: hlsenc.c:138
static int update_variant_stream_info(AVFormatContext *s)
Definition: hlsenc.c:1747
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
else temp
Definition: vf_mcdeint.c:256
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4773
double duration
Definition: hlsenc.c:69
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:56
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static int replace_int_data_in_filename(char *buf, int buf_size, const char *filename, char placeholder, int64_t number)
Definition: hlsenc.c:293
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:1292
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3838
char * vtt_format_options_str
Definition: hlsenc.c:176
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:934
char * key_basename
Definition: hlsenc.c:184
int64_t size
Definition: hlsenc.c:72
int num
Numerator.
Definition: rational.h:59
int use_localtime_mkdir
flag to mkdir dirname in timebased filename
Definition: hlsenc.c:169
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition: dict.c:35
const char * b
Definition: vf_curves.c:113
static int mkdir_p(const char *path)
Definition: hlsenc.c:211
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:244
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
#define AVIO_FLAG_READ
read-only
Definition: avio.h:654
static av_const int av_isspace(int c)
Locale-independent conversion of ASCII isspace.
Definition: avstring.h:222
static int hls_start(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:1359
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:655
enum AVMediaType codec_type
Definition: rtp.c:37
int discontinuity_set
Definition: hlsenc.c:125
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
Definition: avstring.c:223
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:217
HLSSegment * old_segments
Definition: hlsenc.c:130
#define POSTFIX_PATTERN
Definition: hlsenc.c:64
const char * key
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, char *baseurl, char *filename, double *prog_date_time)
Definition: hlsplaylist.c:97
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
static AVPacket pkt
int ff_is_http_proto(char *filename)
Utility function to check if the file uses http or https protocol.
Definition: utils.c:5485
#define fn(a)
#define AVFMT_ALLOW_FLUSH
Format allows flushing.
Definition: avformat.h:478
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1335
static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
Definition: hlsenc.c:1242
static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename)
Definition: hlsenc.c:261
unsigned int nb_streams
Definition: hlsenc.c:145
int ffurl_shutdown(URLContext *h, int flags)
Signal the URLContext that we are done reading or writing the stream.
Definition: avio.c:657
static int update_master_pl_info(AVFormatContext *s)
Definition: hlsenc.c:1773
int m3u8_created
Definition: hlsenc.c:146
VariantStream * var_streams
Definition: hlsenc.c:197
static int do_encrypt(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:500
Format I/O context.
Definition: avformat.h:1330
int max_nb_segments
Definition: hlsenc.c:158
AVIOContext * m3u8_out
Definition: hlsenc.c:207
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
#define AV_WB64(p, v)
Definition: intreadwrite.h:433
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
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:45
char * iv
Definition: hlsenc.c:183
int packets_written
Definition: hlsenc.c:109
AVOutputFormat * vtt_oformat
Definition: hlsenc.c:107
const char * av_basename(const char *path)
Thread safe basename.
Definition: avstring.c:257
char * vtt_m3u8_name
Definition: hlsenc.c:134
uint8_t
static int nb_streams
Definition: ffprobe.c:276
#define av_malloc(s)
float init_time
Definition: hlsenc.c:157
AVOptions.
enum AVCodecID av_codec_get_id(const struct AVCodecTag *const *tags, unsigned int tag)
Get the AVCodecID for the given codec tag tag.
miscellaneous OS support macros and functions.
char * fmp4_init_filename
Definition: hlsenc.c:140
char * vtt_basename
Definition: hlsenc.c:133
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1432
static void hls_free_segments(HLSSegment *p)
Definition: hlsenc.c:1069
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5478
int master_m3u8_created
Definition: hlsenc.c:200
int init_range_length
Definition: hlsenc.c:110
static int append_postfix(char *name, int name_buf_len, int i)
Definition: hlsenc.c:1531
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4403
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1398
int64_t duration
Definition: movenc.c:63
int discont
Definition: hlsenc.c:70
double dpp
Definition: hlsenc.c:118
char * protocol_whitelist
',' separated list of allowed protocols.
Definition: avformat.h:1868
static int get_nth_codec_stream_index(AVFormatContext *s, enum AVMediaType codec_type, int stream_id)
Definition: hlsenc.c:1633
static int flags
Definition: log.c:55
#define AVERROR_EOF
End of file.
Definition: error.h:55
char * format_options_str
Definition: hlsenc.c:175
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
#define LINE_BUFFER_SIZE
Definition: hlsenc.c:62
int64_t start_pos
Definition: hlsenc.c:122
int has_subtitle
Definition: hlsenc.c:116
void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup, char *filename, int name_id, int is_default)
Definition: hlsplaylist.c:38
ptrdiff_t size
Definition: opengl_enc.c:101
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
char * key
Definition: hlsenc.c:181
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:216
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:58
int64_t start_pts
Definition: hlsenc.c:119
#define av_log(a,...)
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:646
struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1349
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3867
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1446
char * basename
Definition: hlsenc.c:132
int64_t sequence
Definition: hlsenc.c:105
int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition: mux.c:148
static const AVOption options[]
Definition: hlsenc.c:2488
int64_t end_pts
Definition: hlsenc.c:120
static int hls_write_header(AVFormatContext *s)
Definition: hlsenc.c:1817
int64_t size
Definition: hlsenc.c:123
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: utils.c:2112
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1548
char * master_pl_name
Definition: hlsenc.c:204
#define OFFSET(x)
Definition: hlsenc.c:2486
int nb_entries
Definition: hlsenc.c:124
#define AVERROR(e)
Definition: error.h:43
struct HLSSegment * next
Definition: hlsenc.c:77
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: aviobuf.c:1134
unsigned number
Definition: hlsenc.c:104
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
char sub_filename[1024]
Definition: hlsenc.c:68
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:203
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3834
AVDictionary * vtt_format_options
Definition: hlsenc.c:192
double duration
Definition: hlsenc.c:121
static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls, VariantStream *vs)
Definition: hlsenc.c:378
Definition: graph2dot.c:48
#define wrap(func)
Definition: neontest.h:65
simple assert() macros that are a bit more flexible than ISO C assert().
AVOutputFormat * oformat
Definition: hlsenc.c:106
static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, VariantStream *vs, double duration, int64_t pos, int64_t size)
Definition: hlsenc.c:897
static av_always_inline av_const double round(double x)
Definition: libm.h:444
#define FF_API_HLS_WRAP
Definition: version.h:71
char key_uri[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:74
int64_t recording_time
Definition: hlsenc.c:171
#define FFMAX(a, b)
Definition: common.h:94
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:83
#define fail()
Definition: checkasm.h:113
static void write_styp(AVIOContext *pb)
Definition: hlsenc.c:345
int64_t pos
Definition: hlsenc.c:71
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1420
AVStream ** streams
Definition: hlsenc.c:144
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
void * opaque
User data.
Definition: avformat.h:1814
char * baseurl
Definition: hlsenc.c:174
static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSContext *c)
Definition: hlsenc.c:276
int discontinuity
Definition: hlsenc.c:126
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
Definition: hls.c:68
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1386
StartSequenceSourceType
Definition: hlsenc.c:55
AVIOContext * out
Definition: hlsenc.c:108
static int sls_flag_check_duration_size_index(HLSContext *hls)
Definition: hlsenc.c:793
void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache, int target_duration, int64_t sequence, uint32_t playlist_type)
Definition: hlsplaylist.c:68
char key_string[KEYSIZE *2+1]
Definition: hlsenc.c:190
AVFormatContext * vtt_avf
Definition: hlsenc.c:113
#define HLS_MICROSECOND_UNIT
Definition: hlsenc.c:63
static int randomize(uint8_t *buf, int len)
Definition: hlsenc.c:486
int void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:236
int64_t max_seg_size
Definition: hlsenc.c:172
HLSSegment * last_segment
Definition: hlsenc.c:129
char filename[1024]
input or output filename
Definition: avformat.h:1406
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
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:489
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:213
#define fn2(a, b, c)
AVIOContext * sub_m3u8_out
Definition: hlsenc.c:208
static struct tm * localtime_r(const time_t *clock, struct tm *result)
Definition: time_internal.h:37
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:94
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:468
static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: hlsenc.c:1867
const char * name
Definition: avformat.h:507
AVFormatContext * ctx
Definition: movenc.c:48
static int create_master_playlist(AVFormatContext *s, VariantStream *const input_vs)
Definition: hlsenc.c:1109
static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:629
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
#define E
Definition: hlsenc.c:2487
int encrypt_started
Definition: hlsenc.c:185
AVDictionary * metadata
Definition: avformat.h:936
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:110
AVDictionary * format_options
Definition: hlsenc.c:178
int ff_get_line(AVIOContext *s, char *buf, int maxlen)
Read a whole line of text from AVIOContext.
Definition: aviobuf.c:807
static void sls_flag_file_rename(HLSContext *hls, VariantStream *vs, char *old_filename)
Definition: hlsenc.c:836
const AVClass * priv_class
AVClass for the private context.
Definition: avformat.h:535
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:469
static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
Definition: hlsenc.c:621
char * base_output_dirname
Definition: hlsenc.c:141
int use_localtime
flag to expand filename with localtime
Definition: hlsenc.c:168
Stream structure.
Definition: avformat.h:872
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
Definition: dict.c:180
void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, int bandwidth, char *filename, char *agroup)
Definition: hlsplaylist.c:48
char * key_url
Definition: hlsenc.c:182
void ff_hls_write_playlist_version(AVIOContext *out, int version)
Definition: hlsplaylist.c:31
char iv_string[KEYSIZE *2+1]
Definition: hlsenc.c:75
int64_t start_sequence
Definition: hlsenc.c:153
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
char * user_agent
holds HTTP user agent set as an AVOption to the HTTP protocol context
Definition: hls.c:205
AVIOContext * pb
I/O context.
Definition: avformat.h:1372
static int hls_encryption_start(AVFormatContext *s)
Definition: hlsenc.c:569
const struct AVCodecTag *const * codec_tag
List of supported codec_id-codec_tag pairs, ordered by "better choice first".
Definition: avformat.h:532
char * key_info_file
Definition: hlsenc.c:187
char * agroup
Definition: hlsenc.c:147
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
char * method
Definition: hlsenc.c:194
char * fmp4_init_filename
Definition: hlsenc.c:165
void * buf
Definition: avisynth_c.h:690
Definition: url.h:38
int allowcache
Definition: hlsenc.c:170
int segment_type
Definition: hlsenc.c:166
HLSFlags
Definition: hlsenc.c:80
static int ff_rename(const char *oldpath, const char *newpath, void *logctx)
Wrap errno on rename() error.
Definition: internal.h:539
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:70
static int validate_name(int nb_vs, const char *fn)
Definition: hlsenc.c:1550
Describe the class of an AVClass context structure.
Definition: log.h:67
int index
Definition: gxfenc.c:89
static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, AVDictionary **options)
Definition: hlsenc.c:244
static void hls_rename_temp_file(AVFormatContext *s, AVFormatContext *oc)
Definition: hlsenc.c:1080
int encrypt
Definition: hlsenc.c:180
AVFormatContext * avf
Definition: hlsenc.c:112
char iv_string[KEYSIZE *2+1]
Definition: hlsenc.c:191
AVMediaType
Definition: avutil.h:199
static int flush_dynbuf(VariantStream *vs, int *range_length)
Definition: hlsenc.c:355
#define snprintf
Definition: snprintf.h:34
char * m3u8_name
Definition: hlsenc.c:135
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4338
static int hls_init(AVFormatContext *s)
Definition: hlsenc.c:2142
int ffio_open_whitelist(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist)
Definition: aviobuf.c:1103
misc parsing utilities
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:93
char * baseurl
Definition: hlsenc.c:148
const char * avio_find_protocol_name(const char *url)
Return the name of the protocol that will handle the passed URL.
Definition: avio.c:473
URLContext * ffio_geturlcontext(AVIOContext *s)
Return the URLContext associated with the AVIOContext.
Definition: aviobuf.c:983
char key_file[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:188
int has_video
Definition: hlsenc.c:115
static HLSSegment * find_segment_by_filename(HLSSegment *segment, const char *filename)
Definition: hlsenc.c:736
static const char * get_default_pattern_localtime_fmt(AVFormatContext *s)
Definition: hlsenc.c:1515
int ff_http_do_new_request(URLContext *h, const char *uri)
Send a new HTTP request, reusing the old connection.
Definition: http.c:305
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok()...
Definition: avstring.c:184
SegmentType
Definition: hlsenc.c:98
uint32_t pl_type
Definition: hlsenc.c:163
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:34
Main libavformat public API header.
static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
Definition: hlsenc.c:984
char * av_append_path_component(const char *path, const char *component)
Append path component to the existing path.
Definition: avstring.c:295
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:465
unsigned int nb_varstreams
Definition: hlsenc.c:198
static double c[64]
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set that converts the value to a string and stores it...
Definition: dict.c:147
const char * av_dirname(char *path)
Thread safe dirname.
Definition: avstring.c:274
void ff_hls_write_init_file(AVIOContext *out, char *filename, int byterange_mode, int64_t size, int64_t pos)
Definition: hlsplaylist.c:88
uint32_t flags
Definition: hlsenc.c:162
int pts_wrap_bits
number of bits in pts (used for wrapping control)
Definition: avformat.h:1062
int den
Denominator.
Definition: rational.h:60
#define KEYSIZE
Definition: hlsenc.c:61
int http_persistent
Definition: hls.c:213
static int sls_flag_check_duration_size(HLSContext *hls, VariantStream *vs)
Definition: hlsenc.c:816
char * segment_filename
Definition: hlsenc.c:164
#define av_free(p)
int len
uint32_t start_sequence_source_type
Definition: hlsenc.c:154
char filename[1024]
Definition: hlsenc.c:67
int fmp4_init_mode
Definition: hlsenc.c:142
void * priv_data
Format private data.
Definition: avformat.h:1358
char * subtitle_filename
Definition: hlsenc.c:177
static const uint8_t start_sequence[]
Definition: rtpdec_h264.c:65
static int get_relative_url(const char *master_url, const char *media_url, char *rel_url, int rel_url_buf_size)
Definition: hlsenc.c:1091
int version
Definition: hlsenc.c:202
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:337
#define lrint
Definition: tablegen.h:53
char * var_stream_map
Definition: hlsenc.c:203
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:746
AVOutputFormat ff_hls_muxer
Definition: hlsenc.c:2553
void ff_hls_write_end_list(AVIOContext *out)
Definition: hlsplaylist.c:150
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1228
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:375
char * protocol_blacklist
',' separated list of disallowed protocols.
Definition: avformat.h:1903
unsigned int master_publish_rate
Definition: hlsenc.c:205
FILE * out
Definition: movenc.c:54
#define av_freep(p)
HLSSegment * segments
Definition: hlsenc.c:128
static int format_name(char *buf, int buf_len, int index)
Definition: hlsenc.c:1589
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1017
int avio_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
Definition: aviobuf.c:356
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3842
int stream_index
Definition: avcodec.h:1416
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:901
int new_start
Definition: hlsenc.c:117
static const AVClass hls_class
Definition: hlsenc.c:2545
unsigned int av_codec_get_tag(const struct AVCodecTag *const *tags, enum AVCodecID id)
Get the codec tag for the given codec id id.
double initial_prog_date_time
Definition: hlsenc.c:137
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
Definition: avformat.h:1890
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Definition: utils.c:4724
This structure stores compressed data.
Definition: avcodec.h:1391
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:449
static int parse_variant_stream_mapstring(AVFormatContext *s)
Definition: hlsenc.c:1651
void(* io_close)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1896
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1407
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
GLuint buffer
Definition: opengl_enc.c:102
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
const char * name
Definition: opengl_enc.c:103
static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c, VariantStream *vs)
Definition: hlsenc.c:843