FFmpeg
hlsenc.c
Go to the documentation of this file.
1 /*
2  * Apple HTTP Live Streaming segmenter
3  * Copyright (c) 2012, Luca Barbato
4  * Copyright (c) 2017 Akamai Technologies, Inc.
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "config.h"
24 #include <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 typedef enum {
65 
66 #define KEYSIZE 16
67 #define LINE_BUFFER_SIZE 1024
68 #define HLS_MICROSECOND_UNIT 1000000
69 #define POSTFIX_PATTERN "_%d"
70 
71 typedef struct HLSSegment {
72  char filename[1024];
73  char sub_filename[1024];
74  double duration; /* in seconds */
75  int discont;
76  int64_t pos;
77  int64_t size;
78  int64_t keyframe_pos;
79  int64_t keyframe_size;
80  unsigned var_stream_idx;
81 
83  char iv_string[KEYSIZE*2 + 1];
84 
85  struct HLSSegment *next;
86 } HLSSegment;
87 
88 typedef enum HLSFlags {
89  // Generate a single media file and use byte ranges in the playlist.
90  HLS_SINGLE_FILE = (1 << 0),
91  HLS_DELETE_SEGMENTS = (1 << 1),
92  HLS_ROUND_DURATIONS = (1 << 2),
93  HLS_DISCONT_START = (1 << 3),
94  HLS_OMIT_ENDLIST = (1 << 4),
95  HLS_SPLIT_BY_TIME = (1 << 5),
96  HLS_APPEND_LIST = (1 << 6),
98  HLS_SECOND_LEVEL_SEGMENT_INDEX = (1 << 8), // include segment index in segment filenames when use_localtime e.g.: %%03d
99  HLS_SECOND_LEVEL_SEGMENT_DURATION = (1 << 9), // include segment duration (microsec) in segment filenames when use_localtime e.g.: %%09t
100  HLS_SECOND_LEVEL_SEGMENT_SIZE = (1 << 10), // include segment size (bytes) in segment filenames when use_localtime e.g.: %%014s
101  HLS_TEMP_FILE = (1 << 11),
102  HLS_PERIODIC_REKEY = (1 << 12),
104  HLS_I_FRAMES_ONLY = (1 << 14),
105 } HLSFlags;
106 
107 typedef enum {
110 } SegmentType;
111 
112 typedef struct VariantStream {
113  unsigned var_stream_idx;
114  unsigned number;
115  int64_t sequence;
121 
124 
128  double dpp; // duration per packet
129  int64_t start_pts;
130  int64_t end_pts;
131  int64_t video_lastpos;
134  double duration; // last segment duration computed so far, in seconds
135  int64_t start_pos; // last segment starting position
136  int64_t size; // last segment size
141 
145 
146  char *basename;
149  char *m3u8_name;
150 
152  char current_segment_final_filename_fmt[1024]; // when renaming segments
153 
156 
158  char codec_attr[128];
160  unsigned int nb_streams;
161  int m3u8_created; /* status of media play-list creation */
162  int is_default; /* default status of audio group */
163  char *language; /* audio lauguage name */
164  char *agroup; /* audio group name */
165  char *ccgroup; /* closed caption group name */
166  char *baseurl;
167 } VariantStream;
168 
169 typedef struct ClosedCaptionsStream {
170  char *ccgroup; /* closed caption group name */
171  char *instreamid; /* closed captions INSTREAM-ID */
172  char *language; /* closed captions langauge */
174 
175 typedef struct HLSContext {
176  const AVClass *class; // Class for private options.
177  int64_t start_sequence;
178  uint32_t start_sequence_source_type; // enum StartSequenceSourceType
179 
180  float time; // Set by a private option.
181  float init_time; // Set by a private option.
182  int max_nb_segments; // Set by a private option.
183  int hls_delete_threshold; // Set by a private option.
184 #if FF_API_HLS_WRAP
185  int wrap; // Set by a private option.
186 #endif
187  uint32_t flags; // enum HLSFlags
188  uint32_t pl_type; // enum PlaylistType
192 
193  int use_localtime; ///< flag to expand filename with localtime
194  int use_localtime_mkdir;///< flag to mkdir dirname in timebased filename
196  int64_t recording_time;
197  int64_t max_seg_size; // every segment file max size
198 
199  char *baseurl;
204 
205  int encrypt;
206  char *key;
207  char *key_url;
208  char *iv;
211 
213  char key_file[LINE_BUFFER_SIZE + 1];
215  char key_string[KEYSIZE*2 + 1];
216  char iv_string[KEYSIZE*2 + 1];
218 
219  char *method;
220  char *user_agent;
221 
223  unsigned int nb_varstreams;
225  unsigned int nb_ccstreams;
226 
227  int master_m3u8_created; /* status of master play-list creation */
228  char *master_m3u8_url; /* URL of the master m3u8 file */
229  int version; /* HLS version */
230  char *var_stream_map; /* user specified variant stream map string */
231  char *cc_stream_map; /* user specified closed caption streams map string */
233  unsigned int master_publish_rate;
234  int http_persistent;
237  int64_t timeout;
239  int has_default_key; /* has DEFAULT field of var_stream_map */
240  int has_video_m3u8; /* has video stream m3u8 list */
241 } HLSContext;
242 
244  AVDictionary **options) {
245  HLSContext *hls = s->priv_data;
246  int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
247  int err = AVERROR_MUXER_NOT_FOUND;
248  if (!*pb || !http_base_proto || !hls->http_persistent) {
249  err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
250 #if CONFIG_HTTP_PROTOCOL
251  } else {
252  URLContext *http_url_context = ffio_geturlcontext(*pb);
253  av_assert0(http_url_context);
254  err = ff_http_do_new_request(http_url_context, filename);
255  if (err < 0)
256  ff_format_io_close(s, pb);
257 
258 #endif
259  }
260  return err;
261 }
262 
264  HLSContext *hls = s->priv_data;
265  int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
266  if (!*pb)
267  return;
268  if (!http_base_proto || !hls->http_persistent || hls->key_info_file || hls->encrypt) {
269  ff_format_io_close(s, pb);
270 #if CONFIG_HTTP_PROTOCOL
271  } else {
272  URLContext *http_url_context = ffio_geturlcontext(*pb);
273  av_assert0(http_url_context);
274  avio_flush(*pb);
275  ffurl_shutdown(http_url_context, AVIO_FLAG_WRITE);
276 #endif
277  }
278 }
279 
281 {
282  int http_base_proto = ff_is_http_proto(s->url);
283 
284  if (c->method) {
285  av_dict_set(options, "method", c->method, 0);
286  } else if (http_base_proto) {
287  av_log(c, AV_LOG_WARNING, "No HTTP method set, hls muxer defaulting to method PUT.\n");
288  av_dict_set(options, "method", "PUT", 0);
289  }
290  if (c->user_agent)
291  av_dict_set(options, "user_agent", c->user_agent, 0);
292  if (c->http_persistent)
293  av_dict_set_int(options, "multiple_requests", 1, 0);
294  if (c->timeout >= 0)
295  av_dict_set_int(options, "timeout", c->timeout, 0);
296 }
297 
298 static void write_codec_attr(AVStream *st, VariantStream *vs) {
299  int codec_strlen = strlen(vs->codec_attr);
300  char attr[32];
301 
303  return;
305  return;
306 
307  if (st->codecpar->codec_id == AV_CODEC_ID_H264) {
308  uint8_t *data = st->codecpar->extradata;
309  if (data && (data[0] | data[1] | data[2]) == 0 && data[3] == 1 && (data[4] & 0x1F) == 7) {
310  snprintf(attr, sizeof(attr),
311  "avc1.%02x%02x%02x", data[5], data[6], data[7]);
312  } else {
313  goto fail;
314  }
315  } else if (st->codecpar->codec_id == AV_CODEC_ID_MP2) {
316  snprintf(attr, sizeof(attr), "mp4a.40.33");
317  } else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) {
318  snprintf(attr, sizeof(attr), "mp4a.40.34");
319  } else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
320  /* TODO : For HE-AAC, HE-AACv2, the last digit needs to be set to 5 and 29 respectively */
321  snprintf(attr, sizeof(attr), "mp4a.40.2");
322  } else if (st->codecpar->codec_id == AV_CODEC_ID_AC3) {
323  snprintf(attr, sizeof(attr), "ac-3");
324  } else if (st->codecpar->codec_id == AV_CODEC_ID_EAC3) {
325  snprintf(attr, sizeof(attr), "ec-3");
326  } else {
327  goto fail;
328  }
329  // Don't write the same attribute multiple times
330  if (!av_stristr(vs->codec_attr, attr)) {
331  snprintf(vs->codec_attr + codec_strlen,
332  sizeof(vs->codec_attr) - codec_strlen,
333  "%s%s", codec_strlen ? "," : "", attr);
334  }
335  return;
336 
337 fail:
338  vs->codec_attr[0] = '\0';
340  return;
341 }
342 
343 static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number)
344 {
345  const char *p;
346  char *new_filename;
347  char c;
348  int nd, addchar_count;
349  int found_count = 0;
350  AVBPrint buf;
351 
353 
354  p = filename;
355  for (;;) {
356  c = *p;
357  if (c == '\0')
358  break;
359  if (c == '%' && *(p+1) == '%') // %%
360  addchar_count = 2;
361  else if (c == '%' && (av_isdigit(*(p+1)) || *(p+1) == placeholder)) {
362  nd = 0;
363  addchar_count = 1;
364  while (av_isdigit(*(p + addchar_count))) {
365  nd = nd * 10 + *(p + addchar_count) - '0';
366  addchar_count++;
367  }
368 
369  if (*(p + addchar_count) == placeholder) {
370  av_bprintf(&buf, "%0*"PRId64, (number < 0) ? nd : nd++, number);
371  p += (addchar_count + 1);
372  addchar_count = 0;
373  found_count++;
374  }
375 
376  } else
377  addchar_count = 1;
378 
379  av_bprint_append_data(&buf, p, addchar_count);
380  p += addchar_count;
381  }
382  if (!av_bprint_is_complete(&buf)) {
383  av_bprint_finalize(&buf, NULL);
384  return -1;
385  }
386  if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename)
387  return -1;
388  *s = new_filename;
389  return found_count;
390 }
391 
392 static void write_styp(AVIOContext *pb)
393 {
394  avio_wb32(pb, 24);
395  ffio_wfourcc(pb, "styp");
396  ffio_wfourcc(pb, "msdh");
397  avio_wb32(pb, 0); /* minor */
398  ffio_wfourcc(pb, "msdh");
399  ffio_wfourcc(pb, "msix");
400 }
401 
402 static int flush_dynbuf(VariantStream *vs, int *range_length)
403 {
404  AVFormatContext *ctx = vs->avf;
405  uint8_t *buffer;
406 
407  if (!ctx->pb) {
408  return AVERROR(EINVAL);
409  }
410 
411  // flush
412  av_write_frame(ctx, NULL);
413  avio_flush(ctx->pb);
414 
415  // write out to file
416  *range_length = avio_close_dyn_buf(ctx->pb, &buffer);
417  ctx->pb = NULL;
418  avio_write(vs->out, buffer, *range_length);
419  av_free(buffer);
420 
421  // re-open buffer
422  return avio_open_dyn_buf(&ctx->pb);
423 }
424 
426  VariantStream *vs) {
427 
428  HLSSegment *segment, *previous_segment = NULL;
429  float playlist_duration = 0.0f;
430  int ret = 0, path_size, sub_path_size;
431  int segment_cnt = 0;
432  char *dirname = NULL, *p, *sub_path;
433  char *path = NULL;
434  char *vtt_dirname = NULL;
436  AVIOContext *out = NULL;
437  const char *proto = NULL;
438 
439  segment = vs->segments;
440  while (segment) {
441  playlist_duration += segment->duration;
442  segment = segment->next;
443  }
444 
445  segment = vs->old_segments;
446  segment_cnt = 0;
447  while (segment) {
448  playlist_duration -= segment->duration;
449  previous_segment = segment;
450  segment = previous_segment->next;
451  segment_cnt++;
452  if (playlist_duration <= -previous_segment->duration) {
453  previous_segment->next = NULL;
454  break;
455  }
456  if (segment_cnt >= hls->hls_delete_threshold) {
457  previous_segment->next = NULL;
458  break;
459  }
460  }
461 
462  if (segment && !hls->use_localtime_mkdir) {
463  if (hls->segment_filename) {
464  dirname = av_strdup(hls->segment_filename);
465  } else {
466  dirname = av_strdup(vs->avf->url);
467  }
468  if (!dirname) {
469  ret = AVERROR(ENOMEM);
470  goto fail;
471  }
472  p = (char *)av_basename(dirname);
473  *p = '\0';
474 
475  }
476 
477  while (segment) {
478  char * r_dirname = dirname;
479 
480  /* if %v is present in the file's directory */
481  if (dirname && av_stristr(dirname, "%v")) {
482 
483  if (replace_int_data_in_filename(&r_dirname, dirname, 'v', segment->var_stream_idx) < 1) {
484  ret = AVERROR(EINVAL);
485  goto fail;
486  }
487  av_free(dirname);
488  dirname = r_dirname;
489  }
490 
491  av_log(hls, AV_LOG_DEBUG, "deleting old segment %s\n",
492  segment->filename);
493  path_size = (hls->use_localtime_mkdir ? 0 : strlen(dirname)) + strlen(segment->filename) + 1;
494  path = av_malloc(path_size);
495  if (!path) {
496  ret = AVERROR(ENOMEM);
497  goto fail;
498  }
499 
500  if (hls->use_localtime_mkdir)
501  av_strlcpy(path, segment->filename, path_size);
502  else { // segment->filename contains basename only
503  av_strlcpy(path, dirname, path_size);
504  av_strlcat(path, segment->filename, path_size);
505  }
506 
507  proto = avio_find_protocol_name(s->url);
508  if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
509  av_dict_set(&options, "method", "DELETE", 0);
510  if ((ret = vs->avf->io_open(vs->avf, &out, path, AVIO_FLAG_WRITE, &options)) < 0) {
511  if (hls->ignore_io_errors)
512  ret = 0;
513  goto fail;
514  }
515  ff_format_io_close(vs->avf, &out);
516  } else if (unlink(path) < 0) {
517  av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
518  path, strerror(errno));
519  }
520 
521  if ((segment->sub_filename[0] != '\0')) {
522  vtt_dirname = av_strdup(vs->vtt_avf->url);
523  if (!vtt_dirname) {
524  ret = AVERROR(ENOMEM);
525  goto fail;
526  }
527  p = (char *)av_basename(vtt_dirname);
528  *p = '\0';
529  sub_path_size = strlen(segment->sub_filename) + 1 + strlen(vtt_dirname);
530  sub_path = av_malloc(sub_path_size);
531  if (!sub_path) {
532  ret = AVERROR(ENOMEM);
533  goto fail;
534  }
535 
536  av_strlcpy(sub_path, vtt_dirname, sub_path_size);
537  av_strlcat(sub_path, segment->sub_filename, sub_path_size);
538 
539  if (hls->method || (proto && !av_strcasecmp(proto, "http"))) {
540  av_dict_set(&options, "method", "DELETE", 0);
541  if ((ret = vs->vtt_avf->io_open(vs->vtt_avf, &out, sub_path, AVIO_FLAG_WRITE, &options)) < 0) {
542  if (hls->ignore_io_errors)
543  ret = 0;
544  av_free(sub_path);
545  goto fail;
546  }
547  ff_format_io_close(vs->vtt_avf, &out);
548  } else if (unlink(sub_path) < 0) {
549  av_log(hls, AV_LOG_ERROR, "failed to delete old segment %s: %s\n",
550  sub_path, strerror(errno));
551  }
552  av_free(sub_path);
553  }
554  av_freep(&path);
555  previous_segment = segment;
556  segment = previous_segment->next;
557  av_free(previous_segment);
558  }
559 
560 fail:
561  av_free(path);
562  av_free(dirname);
563  av_free(vtt_dirname);
564 
565  return ret;
566 }
567 
568 static int randomize(uint8_t *buf, int len)
569 {
570 #if CONFIG_GCRYPT
571  gcry_randomize(buf, len, GCRY_VERY_STRONG_RANDOM);
572  return 0;
573 #elif CONFIG_OPENSSL
574  if (RAND_bytes(buf, len))
575  return 0;
576 #else
577  return AVERROR(ENOSYS);
578 #endif
579  return AVERROR(EINVAL);
580 }
581 
583 {
584  HLSContext *hls = s->priv_data;
585  int ret;
586  int len;
587  AVIOContext *pb;
589 
590  len = strlen(s->url) + 4 + 1;
591  hls->key_basename = av_mallocz(len);
592  if (!hls->key_basename)
593  return AVERROR(ENOMEM);
594 
595  av_strlcpy(hls->key_basename, s->url, len);
596  av_strlcat(hls->key_basename, ".key", len);
597 
598  if (hls->key_url) {
599  av_strlcpy(hls->key_file, hls->key_url, sizeof(hls->key_file));
600  av_strlcpy(hls->key_uri, hls->key_url, sizeof(hls->key_uri));
601  } else {
602  av_strlcpy(hls->key_file, hls->key_basename, sizeof(hls->key_file));
603  av_strlcpy(hls->key_uri, hls->key_basename, sizeof(hls->key_uri));
604  }
605 
606  if (!*hls->iv_string) {
607  uint8_t iv[16] = { 0 };
608  char buf[33];
609 
610  if (!hls->iv) {
611  AV_WB64(iv + 8, vs->sequence);
612  } else {
613  memcpy(iv, hls->iv, sizeof(iv));
614  }
615  ff_data_to_hex(buf, iv, sizeof(iv), 0);
616  buf[32] = '\0';
617  memcpy(hls->iv_string, buf, sizeof(hls->iv_string));
618  }
619 
620  if (!*hls->key_uri) {
621  av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
622  return AVERROR(EINVAL);
623  }
624 
625  if (!*hls->key_file) {
626  av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
627  return AVERROR(EINVAL);
628  }
629 
630  if (!*hls->key_string) {
631  if (!hls->key) {
632  if ((ret = randomize(key, sizeof(key))) < 0) {
633  av_log(s, AV_LOG_ERROR, "Cannot generate a strong random key\n");
634  return ret;
635  }
636  } else {
637  memcpy(key, hls->key, sizeof(key));
638  }
639 
640  ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
641  if ((ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_WRITE, NULL)) < 0)
642  return ret;
643  avio_seek(pb, 0, SEEK_CUR);
644  avio_write(pb, key, KEYSIZE);
645  avio_close(pb);
646  }
647  return 0;
648 }
649 
650 
652 {
653  HLSContext *hls = s->priv_data;
654  int ret;
655  AVIOContext *pb;
657 
658  if ((ret = s->io_open(s, &pb, hls->key_info_file, AVIO_FLAG_READ, NULL)) < 0) {
659  av_log(hls, AV_LOG_ERROR,
660  "error opening key info file %s\n", hls->key_info_file);
661  return ret;
662  }
663 
664  ff_get_line(pb, hls->key_uri, sizeof(hls->key_uri));
665  hls->key_uri[strcspn(hls->key_uri, "\r\n")] = '\0';
666 
667  ff_get_line(pb, hls->key_file, sizeof(hls->key_file));
668  hls->key_file[strcspn(hls->key_file, "\r\n")] = '\0';
669 
670  ff_get_line(pb, hls->iv_string, sizeof(hls->iv_string));
671  hls->iv_string[strcspn(hls->iv_string, "\r\n")] = '\0';
672 
673  ff_format_io_close(s, &pb);
674 
675  if (!*hls->key_uri) {
676  av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n");
677  return AVERROR(EINVAL);
678  }
679 
680  if (!*hls->key_file) {
681  av_log(hls, AV_LOG_ERROR, "no key file specified in key info file\n");
682  return AVERROR(EINVAL);
683  }
684 
685  if ((ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_READ, NULL)) < 0) {
686  av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", hls->key_file);
687  return ret;
688  }
689 
690  ret = avio_read(pb, key, sizeof(key));
691  ff_format_io_close(s, &pb);
692  if (ret != sizeof(key)) {
693  av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", hls->key_file);
694  if (ret >= 0 || ret == AVERROR_EOF)
695  ret = AVERROR(EINVAL);
696  return ret;
697  }
698  ff_data_to_hex(hls->key_string, key, sizeof(key), 0);
699 
700  return 0;
701 }
702 
704 {
706  HLSContext *hls = s->priv_data;
707  AVFormatContext *oc;
708  AVFormatContext *vtt_oc = NULL;
709  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
710  int i, ret;
711 
713  if (ret < 0)
714  return ret;
715  oc = vs->avf;
716 
717  oc->url = av_strdup("");
718  if (!oc->url)
719  return AVERROR(ENOMEM);
720 
721  oc->oformat = vs->oformat;
723  oc->max_delay = s->max_delay;
724  oc->opaque = s->opaque;
725  oc->io_open = s->io_open;
726  oc->io_close = s->io_close;
727  av_dict_copy(&oc->metadata, s->metadata, 0);
728 
729  if(vs->vtt_oformat) {
731  if (ret < 0)
732  return ret;
733  vtt_oc = vs->vtt_avf;
734  vtt_oc->oformat = vs->vtt_oformat;
735  av_dict_copy(&vtt_oc->metadata, s->metadata, 0);
736  }
737 
738  for (i = 0; i < vs->nb_streams; i++) {
739  AVStream *st;
740  AVFormatContext *loc;
742  loc = vtt_oc;
743  else
744  loc = oc;
745 
746  if (!(st = avformat_new_stream(loc, NULL)))
747  return AVERROR(ENOMEM);
749  if (!oc->oformat->codec_tag ||
753  } else {
754  st->codecpar->codec_tag = 0;
755  }
756 
758  st->time_base = vs->streams[i]->time_base;
759  av_dict_copy(&st->metadata, vs->streams[i]->metadata, 0);
760  }
761 
762  vs->packets_written = 1;
763  vs->start_pos = 0;
764  vs->new_start = 1;
765 
766  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
767  if (hls->max_seg_size > 0) {
768  av_log(s, AV_LOG_WARNING, "Multi-file byterange mode is currently unsupported in the HLS muxer.\n");
769  return AVERROR_PATCHWELCOME;
770  }
771 
772  vs->packets_written = 0;
773  vs->init_range_length = 0;
774  set_http_options(s, &options, hls);
775  if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
776  return ret;
777 
778  if (byterange_mode) {
779  ret = hlsenc_io_open(s, &vs->out, vs->basename, &options);
780  } else {
781  ret = hlsenc_io_open(s, &vs->out, vs->base_output_dirname, &options);
782  }
783  av_dict_free(&options);
784  if (ret < 0) {
785  av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", vs->fmp4_init_filename);
786  return ret;
787  }
788 
789  if (hls->format_options_str) {
790  ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
791  if (ret < 0) {
792  av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n",
793  hls->format_options_str);
794  return ret;
795  }
796  }
797 
798  av_dict_copy(&options, hls->format_options, 0);
799  av_dict_set(&options, "fflags", "-autobsf", 0);
800  av_dict_set(&options, "movflags", "+frag_custom+dash+delay_moov", AV_DICT_APPEND);
801  ret = avformat_init_output(oc, &options);
802  if (ret < 0)
803  return ret;
804  if (av_dict_count(options)) {
805  av_log(s, AV_LOG_ERROR, "Some of the provided format options in '%s' are not recognized\n", hls->format_options_str);
806  av_dict_free(&options);
807  return AVERROR(EINVAL);
808  }
809  avio_flush(oc->pb);
810  av_dict_free(&options);
811  }
812  return 0;
813 }
814 
816 {
817  while (segment) {
818  if (!av_strcasecmp(segment->filename,filename))
819  return segment;
820  segment = segment->next;
821  }
822  return (HLSSegment *) NULL;
823 }
824 
826  VariantStream *vs, HLSSegment *en,
827  double duration, int64_t pos, int64_t size)
828 {
831  char * new_url = av_strdup(vs->current_segment_final_filename_fmt);
832  if (!new_url) {
833  av_free(en);
834  return AVERROR(ENOMEM);
835  }
836  ff_format_set_url(vs->avf, new_url);
838  char *filename = NULL;
839  if (replace_int_data_in_filename(&filename, vs->avf->url, 's', pos + size) < 1) {
840  av_log(hls, AV_LOG_ERROR,
841  "Invalid second level segment filename template '%s', "
842  "you can try to remove second_level_segment_size flag\n",
843  vs->avf->url);
844  av_free(filename);
845  av_free(en);
846  return AVERROR(EINVAL);
847  }
848  ff_format_set_url(vs->avf, filename);
849  }
851  char *filename = NULL;
852  if (replace_int_data_in_filename(&filename, vs->avf->url,
853  't', (int64_t)round(duration * HLS_MICROSECOND_UNIT)) < 1) {
854  av_log(hls, AV_LOG_ERROR,
855  "Invalid second level segment filename template '%s', "
856  "you can try to remove second_level_segment_time flag\n",
857  vs->avf->url);
858  av_free(filename);
859  av_free(en);
860  return AVERROR(EINVAL);
861  }
862  ff_format_set_url(vs->avf, filename);
863  }
864  }
865  return 0;
866 }
867 
869 {
870  int ret = 0;
871 
873  av_log(hls, AV_LOG_ERROR,
874  "second_level_segment_duration hls_flag requires strftime to be true\n");
875  ret = AVERROR(EINVAL);
876  }
878  av_log(hls, AV_LOG_ERROR,
879  "second_level_segment_size hls_flag requires strfime to be true\n");
880  ret = AVERROR(EINVAL);
881  }
883  av_log(hls, AV_LOG_ERROR,
884  "second_level_segment_index hls_flag requires strftime to be true\n");
885  ret = AVERROR(EINVAL);
886  }
887 
888  return ret;
889 }
890 
892 {
893  const char *proto = avio_find_protocol_name(vs->basename);
894  int segment_renaming_ok = proto && !strcmp(proto, "file");
895  int ret = 0;
896 
897  if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) && !segment_renaming_ok) {
898  av_log(hls, AV_LOG_ERROR,
899  "second_level_segment_duration hls_flag works only with file protocol segment names\n");
900  ret = AVERROR(EINVAL);
901  }
902  if ((hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) && !segment_renaming_ok) {
903  av_log(hls, AV_LOG_ERROR,
904  "second_level_segment_size hls_flag works only with file protocol segment names\n");
905  ret = AVERROR(EINVAL);
906  }
907 
908  return ret;
909 }
910 
911 static void sls_flag_file_rename(HLSContext *hls, VariantStream *vs, char *old_filename) {
914  ff_rename(old_filename, vs->avf->url, hls);
915  }
916 }
917 
919 {
921  char *filename = NULL;
922  if (replace_int_data_in_filename(&filename,
923 #if FF_API_HLS_WRAP
924  oc->url, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
925 #else
926  oc->url, 'd', vs->sequence) < 1) {
927 #endif
928  av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
929  "you can try to remove second_level_segment_index flag\n",
930  oc->url);
931  av_free(filename);
932  return AVERROR(EINVAL);
933  }
934  ff_format_set_url(oc, filename);
935  }
940  char *filename = NULL;
941  if (replace_int_data_in_filename(&filename, oc->url, 's', 0) < 1) {
942  av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
943  "you can try to remove second_level_segment_size flag\n",
944  oc->url);
945  av_free(filename);
946  return AVERROR(EINVAL);
947  }
948  ff_format_set_url(oc, filename);
949  }
951  char *filename = NULL;
952  if (replace_int_data_in_filename(&filename, oc->url, 't', 0) < 1) {
953  av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "
954  "you can try to remove second_level_segment_time flag\n",
955  oc->url);
956  av_free(filename);
957  return AVERROR(EINVAL);
958  }
959  ff_format_set_url(oc, filename);
960  }
961  }
962  return 0;
963 }
964 
965 /* Create a new segment and append it to the segment list */
967  VariantStream *vs, double duration, int64_t pos,
968  int64_t size)
969 {
970  HLSSegment *en = av_malloc(sizeof(*en));
971  const char *filename;
972  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
973  int ret;
974 
975  if (!en)
976  return AVERROR(ENOMEM);
977 
978  en->var_stream_idx = vs->var_stream_idx;
979  ret = sls_flags_filename_process(s, hls, vs, en, duration, pos, size);
980  if (ret < 0) {
981  return ret;
982  }
983 
984  filename = av_basename(vs->avf->url);
985 
986  if (hls->use_localtime_mkdir) {
987  filename = vs->avf->url;
988  }
989  if ((find_segment_by_filename(vs->segments, filename) || find_segment_by_filename(vs->old_segments, filename))
990  && !byterange_mode) {
991  av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", filename);
992  }
993  av_strlcpy(en->filename, filename, sizeof(en->filename));
994 
995  if(vs->has_subtitle)
996  av_strlcpy(en->sub_filename, av_basename(vs->vtt_avf->url), sizeof(en->sub_filename));
997  else
998  en->sub_filename[0] = '\0';
999 
1000  en->duration = duration;
1001  en->pos = pos;
1002  en->size = size;
1003  en->keyframe_pos = vs->video_keyframe_pos;
1005  en->next = NULL;
1006  en->discont = 0;
1007 
1008  if (vs->discontinuity) {
1009  en->discont = 1;
1010  vs->discontinuity = 0;
1011  }
1012 
1013  if (hls->key_info_file || hls->encrypt) {
1014  av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri));
1015  av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string));
1016  }
1017 
1018  if (!vs->segments)
1019  vs->segments = en;
1020  else
1021  vs->last_segment->next = en;
1022 
1023  vs->last_segment = en;
1024 
1025  // EVENT or VOD playlists imply sliding window cannot be used
1026  if (hls->pl_type != PLAYLIST_TYPE_NONE)
1027  hls->max_nb_segments = 0;
1028 
1029  if (hls->max_nb_segments && vs->nb_entries >= hls->max_nb_segments) {
1030  en = vs->segments;
1031  vs->initial_prog_date_time += en->duration;
1032  vs->segments = en->next;
1033  if (en && hls->flags & HLS_DELETE_SEGMENTS &&
1034 #if FF_API_HLS_WRAP
1035  !(hls->flags & HLS_SINGLE_FILE || hls->wrap)) {
1036 #else
1037  !(hls->flags & HLS_SINGLE_FILE)) {
1038 #endif
1039  en->next = vs->old_segments;
1040  vs->old_segments = en;
1041  if ((ret = hls_delete_old_segments(s, hls, vs)) < 0)
1042  return ret;
1043  } else
1044  av_free(en);
1045  } else
1046  vs->nb_entries++;
1047 
1048  if (hls->max_seg_size > 0) {
1049  return 0;
1050  }
1051  vs->sequence++;
1052 
1053  return 0;
1054 }
1055 
1056 static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
1057 {
1058  HLSContext *hls = s->priv_data;
1059  AVIOContext *in;
1060  int ret = 0, is_segment = 0;
1061  int64_t new_start_pos;
1062  char line[1024];
1063  const char *ptr;
1064  const char *end;
1065 
1066  if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ,
1067  &s->interrupt_callback, NULL,
1069  return ret;
1070 
1071  ff_get_chomp_line(in, line, sizeof(line));
1072  if (strcmp(line, "#EXTM3U")) {
1073  ret = AVERROR_INVALIDDATA;
1074  goto fail;
1075  }
1076 
1077  vs->discontinuity = 0;
1078  while (!avio_feof(in)) {
1079  ff_get_chomp_line(in, line, sizeof(line));
1080  if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
1081  int64_t tmp_sequence = strtoll(ptr, NULL, 10);
1082  if (tmp_sequence < vs->sequence)
1083  av_log(hls, AV_LOG_VERBOSE,
1084  "Found playlist sequence number was smaller """
1085  "than specified start sequence number: %"PRId64" < %"PRId64", "
1086  "omitting\n", tmp_sequence, hls->start_sequence);
1087  else {
1088  av_log(hls, AV_LOG_DEBUG, "Found playlist sequence number: %"PRId64"\n", tmp_sequence);
1089  vs->sequence = tmp_sequence;
1090  }
1091  } else if (av_strstart(line, "#EXT-X-DISCONTINUITY", &ptr)) {
1092  is_segment = 1;
1093  vs->discontinuity = 1;
1094  } else if (av_strstart(line, "#EXTINF:", &ptr)) {
1095  is_segment = 1;
1096  vs->duration = atof(ptr);
1097  } else if (av_stristart(line, "#EXT-X-KEY:", &ptr)) {
1098  ptr = av_stristr(line, "URI=\"");
1099  if (ptr) {
1100  ptr += strlen("URI=\"");
1101  end = av_stristr(ptr, ",");
1102  if (end) {
1103  av_strlcpy(hls->key_uri, ptr, end - ptr);
1104  } else {
1105  av_strlcpy(hls->key_uri, ptr, sizeof(hls->key_uri));
1106  }
1107  }
1108 
1109  ptr = av_stristr(line, "IV=0x");
1110  if (ptr) {
1111  ptr += strlen("IV=0x");
1112  end = av_stristr(ptr, ",");
1113  if (end) {
1114  av_strlcpy(hls->iv_string, ptr, end - ptr);
1115  } else {
1116  av_strlcpy(hls->iv_string, ptr, sizeof(hls->iv_string));
1117  }
1118  }
1119 
1120  } else if (av_strstart(line, "#", NULL)) {
1121  continue;
1122  } else if (line[0]) {
1123  if (is_segment) {
1124  char *new_file = av_strdup(line);
1125  if (!new_file) {
1126  ret = AVERROR(ENOMEM);
1127  goto fail;
1128  }
1129  ff_format_set_url(vs->avf, new_file);
1130  is_segment = 0;
1131  new_start_pos = avio_tell(vs->avf->pb);
1132  vs->size = new_start_pos - vs->start_pos;
1133  ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size);
1134  if (ret < 0)
1135  goto fail;
1136  vs->start_pos = new_start_pos;
1137  }
1138  }
1139  }
1140 
1141 fail:
1142  avio_close(in);
1143  return ret;
1144 }
1145 
1147 {
1148  HLSSegment *en;
1149 
1150  while(p) {
1151  en = p;
1152  p = p->next;
1153  av_free(en);
1154  }
1155 }
1156 
1158 {
1159  size_t len = strlen(oc->url);
1160  char *final_filename = av_strdup(oc->url);
1161  int ret;
1162 
1163  if (!final_filename)
1164  return AVERROR(ENOMEM);
1165  final_filename[len-4] = '\0';
1166  ret = ff_rename(oc->url, final_filename, s);
1167  oc->url[len-4] = '\0';
1168  av_freep(&final_filename);
1169  return ret;
1170 }
1171 
1172 static int get_relative_url(const char *master_url, const char *media_url,
1173  char *rel_url, int rel_url_buf_size)
1174 {
1175  char *p = NULL;
1176  int base_len = -1;
1177  p = strrchr(master_url, '/') ? strrchr(master_url, '/') :\
1178  strrchr(master_url, '\\');
1179  if (p) {
1180  base_len = FFABS(p - master_url);
1181  if (av_strncasecmp(master_url, media_url, base_len)) {
1182  av_log(NULL, AV_LOG_WARNING, "Unable to find relative url\n");
1183  return AVERROR(EINVAL);
1184  }
1185  }
1186  av_strlcpy(rel_url, &(media_url[base_len + 1]), rel_url_buf_size);
1187  return 0;
1188 }
1189 
1190 static int64_t get_stream_bit_rate(AVStream *stream) {
1192  stream,
1194  NULL
1195  );
1196 
1197  if (stream->codecpar->bit_rate)
1198  return stream->codecpar->bit_rate;
1199  else if (props)
1200  return props->max_bitrate;
1201 
1202  return 0;
1203 }
1204 
1206  VariantStream * const input_vs)
1207 {
1208  HLSContext *hls = s->priv_data;
1209  VariantStream *vs, *temp_vs;
1210  AVStream *vid_st, *aud_st;
1212  unsigned int i, j;
1213  int m3u8_name_size, ret, bandwidth;
1214  char *m3u8_rel_name, *ccgroup;
1215  ClosedCaptionsStream *ccs;
1216 
1217  input_vs->m3u8_created = 1;
1218  if (!hls->master_m3u8_created) {
1219  /* For the first time, wait until all the media playlists are created */
1220  for (i = 0; i < hls->nb_varstreams; i++)
1221  if (!hls->var_streams[i].m3u8_created)
1222  return 0;
1223  } else {
1224  /* Keep publishing the master playlist at the configured rate */
1225  if (&hls->var_streams[0] != input_vs || !hls->master_publish_rate ||
1226  input_vs->number % hls->master_publish_rate)
1227  return 0;
1228  }
1229 
1230  set_http_options(s, &options, hls);
1231 
1232  ret = hlsenc_io_open(s, &hls->m3u8_out, hls->master_m3u8_url, &options);
1233  av_dict_free(&options);
1234  if (ret < 0) {
1235  av_log(NULL, AV_LOG_ERROR, "Failed to open master play list file '%s'\n",
1236  hls->master_m3u8_url);
1237  goto fail;
1238  }
1239 
1241 
1242  for (i = 0; i < hls->nb_ccstreams; i++) {
1243  ccs = &(hls->cc_streams[i]);
1244  avio_printf(hls->m3u8_out, "#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS");
1245  avio_printf(hls->m3u8_out, ",GROUP-ID=\"%s\"", ccs->ccgroup);
1246  avio_printf(hls->m3u8_out, ",NAME=\"%s\"", ccs->instreamid);
1247  if (ccs->language)
1248  avio_printf(hls->m3u8_out, ",LANGUAGE=\"%s\"", ccs->language);
1249  avio_printf(hls->m3u8_out, ",INSTREAM-ID=\"%s\"\n", ccs->instreamid);
1250  }
1251 
1252  /* For audio only variant streams add #EXT-X-MEDIA tag with attributes*/
1253  for (i = 0; i < hls->nb_varstreams; i++) {
1254  vs = &(hls->var_streams[i]);
1255 
1256  if (vs->has_video || vs->has_subtitle || !vs->agroup)
1257  continue;
1258 
1259  m3u8_name_size = strlen(vs->m3u8_name) + 1;
1260  m3u8_rel_name = av_malloc(m3u8_name_size);
1261  if (!m3u8_rel_name) {
1262  ret = AVERROR(ENOMEM);
1263  goto fail;
1264  }
1265  av_strlcpy(m3u8_rel_name, vs->m3u8_name, m3u8_name_size);
1266  ret = get_relative_url(hls->master_m3u8_url, vs->m3u8_name,
1267  m3u8_rel_name, m3u8_name_size);
1268  if (ret < 0) {
1269  av_log(s, AV_LOG_ERROR, "Unable to find relative URL\n");
1270  goto fail;
1271  }
1272 
1273  ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, vs->language, i, hls->has_default_key ? vs->is_default : 1);
1274 
1275  av_freep(&m3u8_rel_name);
1276  }
1277 
1278  /* For variant streams with video add #EXT-X-STREAM-INF tag with attributes*/
1279  for (i = 0; i < hls->nb_varstreams; i++) {
1280  vs = &(hls->var_streams[i]);
1281 
1282  m3u8_name_size = strlen(vs->m3u8_name) + 1;
1283  m3u8_rel_name = av_malloc(m3u8_name_size);
1284  if (!m3u8_rel_name) {
1285  ret = AVERROR(ENOMEM);
1286  goto fail;
1287  }
1288  av_strlcpy(m3u8_rel_name, vs->m3u8_name, m3u8_name_size);
1289  ret = get_relative_url(hls->master_m3u8_url, vs->m3u8_name,
1290  m3u8_rel_name, m3u8_name_size);
1291  if (ret < 0) {
1292  av_log(NULL, AV_LOG_ERROR, "Unable to find relative URL\n");
1293  goto fail;
1294  }
1295 
1296  vid_st = NULL;
1297  aud_st = NULL;
1298  for (j = 0; j < vs->nb_streams; j++) {
1300  vid_st = vs->streams[j];
1301  else if (vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
1302  aud_st = vs->streams[j];
1303  }
1304 
1305  if (!vid_st && !aud_st) {
1306  av_log(NULL, AV_LOG_WARNING, "Media stream not found\n");
1307  continue;
1308  }
1309 
1310  /**
1311  * Traverse through the list of audio only rendition streams and find
1312  * the rendition which has highest bitrate in the same audio group
1313  */
1314  if (vs->agroup) {
1315  for (j = 0; j < hls->nb_varstreams; j++) {
1316  temp_vs = &(hls->var_streams[j]);
1317  if (!temp_vs->has_video && !temp_vs->has_subtitle &&
1318  temp_vs->agroup &&
1319  !av_strcasecmp(temp_vs->agroup, vs->agroup)) {
1320  if (!aud_st)
1321  aud_st = temp_vs->streams[0];
1322  if (temp_vs->streams[0]->codecpar->bit_rate >
1323  aud_st->codecpar->bit_rate)
1324  aud_st = temp_vs->streams[0];
1325  }
1326  }
1327  }
1328 
1329  bandwidth = 0;
1330  if (vid_st)
1331  bandwidth += get_stream_bit_rate(vid_st);
1332  if (aud_st)
1333  bandwidth += get_stream_bit_rate(aud_st);
1334  bandwidth += bandwidth / 10;
1335 
1336  ccgroup = NULL;
1337  if (vid_st && vs->ccgroup) {
1338  /* check if this group name is available in the cc map string */
1339  for (j = 0; j < hls->nb_ccstreams; j++) {
1340  ccs = &(hls->cc_streams[j]);
1341  if (!av_strcasecmp(ccs->ccgroup, vs->ccgroup)) {
1342  ccgroup = vs->ccgroup;
1343  break;
1344  }
1345  }
1346  if (j == hls->nb_ccstreams)
1347  av_log(NULL, AV_LOG_WARNING, "mapping ccgroup %s not found\n",
1348  vs->ccgroup);
1349  }
1350 
1351  if (!hls->has_default_key || !hls->has_video_m3u8) {
1352  ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, m3u8_rel_name,
1353  aud_st ? vs->agroup : NULL, vs->codec_attr, ccgroup);
1354  } else {
1355  if (vid_st) {
1356  ff_hls_write_stream_info(vid_st, hls->m3u8_out, bandwidth, m3u8_rel_name,
1357  aud_st ? vs->agroup : NULL, vs->codec_attr, ccgroup);
1358  }
1359  }
1360 
1361  av_freep(&m3u8_rel_name);
1362  }
1363 fail:
1364  if(ret >=0)
1365  hls->master_m3u8_created = 1;
1366  av_freep(&m3u8_rel_name);
1367  hlsenc_io_close(s, &hls->m3u8_out, hls->master_m3u8_url);
1368  return ret;
1369 }
1370 
1371 static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
1372 {
1373  HLSContext *hls = s->priv_data;
1374  HLSSegment *en;
1375  int target_duration = 0;
1376  int ret = 0;
1377  char temp_filename[1024];
1378  int64_t sequence = FFMAX(hls->start_sequence, vs->sequence - vs->nb_entries);
1379  const char *proto = avio_find_protocol_name(vs->m3u8_name);
1380  int is_file_proto = proto && !strcmp(proto, "file");
1381  int use_temp_file = is_file_proto && ((hls->flags & HLS_TEMP_FILE) || !(hls->pl_type == PLAYLIST_TYPE_VOD));
1382  static unsigned warned_non_file;
1383  char *key_uri = NULL;
1384  char *iv_string = NULL;
1386  double prog_date_time = vs->initial_prog_date_time;
1387  double *prog_date_time_p = (hls->flags & HLS_PROGRAM_DATE_TIME) ? &prog_date_time : NULL;
1388  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
1389 
1390  hls->version = 3;
1391  if (byterange_mode) {
1392  hls->version = 4;
1393  sequence = 0;
1394  }
1395 
1396  if (hls->flags & HLS_INDEPENDENT_SEGMENTS) {
1397  hls->version = 6;
1398  }
1399 
1400  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1401  hls->version = 7;
1402  }
1403 
1404  if (!is_file_proto && (hls->flags & HLS_TEMP_FILE) && !warned_non_file++)
1405  av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n");
1406 
1407  set_http_options(s, &options, hls);
1408  snprintf(temp_filename, sizeof(temp_filename), use_temp_file ? "%s.tmp" : "%s", vs->m3u8_name);
1409  if ((ret = hlsenc_io_open(s, &hls->m3u8_out, temp_filename, &options)) < 0) {
1410  if (hls->ignore_io_errors)
1411  ret = 0;
1412  goto fail;
1413  }
1414 
1415  for (en = vs->segments; en; en = en->next) {
1416  if (target_duration <= en->duration)
1417  target_duration = lrint(en->duration);
1418  }
1419 
1420  vs->discontinuity_set = 0;
1422  target_duration, sequence, hls->pl_type, hls->flags & HLS_I_FRAMES_ONLY);
1423 
1424  if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && vs->discontinuity_set==0 ){
1425  avio_printf(hls->m3u8_out, "#EXT-X-DISCONTINUITY\n");
1426  vs->discontinuity_set = 1;
1427  }
1428  if (vs->has_video && (hls->flags & HLS_INDEPENDENT_SEGMENTS)) {
1429  avio_printf(hls->m3u8_out, "#EXT-X-INDEPENDENT-SEGMENTS\n");
1430  }
1431  for (en = vs->segments; en; en = en->next) {
1432  if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) ||
1433  av_strcasecmp(en->iv_string, iv_string))) {
1434  avio_printf(hls->m3u8_out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", en->key_uri);
1435  if (*en->iv_string)
1436  avio_printf(hls->m3u8_out, ",IV=0x%s", en->iv_string);
1437  avio_printf(hls->m3u8_out, "\n");
1438  key_uri = en->key_uri;
1439  iv_string = en->iv_string;
1440  }
1441 
1442  if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == vs->segments)) {
1444  hls->flags & HLS_SINGLE_FILE, vs->init_range_length, 0);
1445  }
1446 
1447  ret = ff_hls_write_file_entry(hls->m3u8_out, en->discont, byterange_mode,
1448  en->duration, hls->flags & HLS_ROUND_DURATIONS,
1449  en->size, en->pos, vs->baseurl,
1450  en->filename, prog_date_time_p, en->keyframe_size, en->keyframe_pos, hls->flags & HLS_I_FRAMES_ONLY);
1451  if (ret < 0) {
1452  av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
1453  }
1454  }
1455 
1456  if (last && (hls->flags & HLS_OMIT_ENDLIST)==0)
1458 
1459  if( vs->vtt_m3u8_name ) {
1460  if ((ret = hlsenc_io_open(s, &hls->sub_m3u8_out, vs->vtt_m3u8_name, &options)) < 0) {
1461  if (hls->ignore_io_errors)
1462  ret = 0;
1463  goto fail;
1464  }
1466  target_duration, sequence, PLAYLIST_TYPE_NONE, 0);
1467  for (en = vs->segments; en; en = en->next) {
1468  ret = ff_hls_write_file_entry(hls->sub_m3u8_out, 0, byterange_mode,
1469  en->duration, 0, en->size, en->pos,
1470  vs->baseurl, en->sub_filename, NULL, 0, 0, 0);
1471  if (ret < 0) {
1472  av_log(s, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
1473  }
1474  }
1475 
1476  if (last)
1478 
1479  }
1480 
1481 fail:
1482  av_dict_free(&options);
1483  hlsenc_io_close(s, &hls->m3u8_out, temp_filename);
1485  if (use_temp_file)
1486  ff_rename(temp_filename, vs->m3u8_name, s);
1487  if (ret >= 0 && hls->master_pl_name)
1488  if (create_master_playlist(s, vs) < 0)
1489  av_log(s, AV_LOG_WARNING, "Master playlist creation failed\n");
1490 
1491  return ret;
1492 }
1493 
1495 {
1496  HLSContext *c = s->priv_data;
1497  AVFormatContext *oc = vs->avf;
1498  AVFormatContext *vtt_oc = vs->vtt_avf;
1500  const char *proto = NULL;
1501  int use_temp_file = 0;
1502  char *filename, iv_string[KEYSIZE*2 + 1];
1503  int err = 0;
1504 
1505  if (c->flags & HLS_SINGLE_FILE) {
1506  char *new_name = av_strdup(vs->basename);
1507  if (!new_name)
1508  return AVERROR(ENOMEM);
1509  ff_format_set_url(oc, new_name);
1510  if (vs->vtt_basename) {
1511  new_name = av_strdup(vs->vtt_basename);
1512  if (!new_name)
1513  return AVERROR(ENOMEM);
1514  ff_format_set_url(vtt_oc, new_name);
1515  }
1516  } else if (c->max_seg_size > 0) {
1517  char *filename = NULL;
1518  if (replace_int_data_in_filename(&filename,
1519 #if FF_API_HLS_WRAP
1520  vs->basename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
1521 #else
1522  vs->basename, 'd', vs->sequence) < 1) {
1523 #endif
1524  av_free(filename);
1525  av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s', you can try to use -strftime 1 with it\n", vs->basename);
1526  return AVERROR(EINVAL);
1527  }
1528  ff_format_set_url(oc, filename);
1529  } else {
1530  if (c->use_localtime) {
1531  time_t now0;
1532  struct tm *tm, tmpbuf;
1533  int bufsize = strlen(vs->basename) + 1024;
1534  char *buf = av_mallocz(bufsize);
1535  if (!buf)
1536  return AVERROR(ENOMEM);
1537  time(&now0);
1538  tm = localtime_r(&now0, &tmpbuf);
1539  ff_format_set_url(oc, buf);
1540  if (!strftime(oc->url, bufsize, vs->basename, tm)) {
1541  av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
1542  return AVERROR(EINVAL);
1543  }
1544 
1545  err = sls_flag_use_localtime_filename(oc, c, vs);
1546  if (err < 0) {
1547  return AVERROR(ENOMEM);
1548  }
1549 
1550  if (c->use_localtime_mkdir) {
1551  const char *dir;
1552  char *fn_copy = av_strdup(oc->url);
1553  if (!fn_copy) {
1554  return AVERROR(ENOMEM);
1555  }
1556  dir = av_dirname(fn_copy);
1557  if (ff_mkdir_p(dir) == -1 && errno != EEXIST) {
1558  av_log(oc, AV_LOG_ERROR, "Could not create directory %s with use_localtime_mkdir\n", dir);
1559  av_free(fn_copy);
1560  return AVERROR(errno);
1561  }
1562  av_free(fn_copy);
1563  }
1564  } else {
1565  char *filename = NULL;
1566  if (replace_int_data_in_filename(&filename,
1567 #if FF_API_HLS_WRAP
1568  vs->basename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
1569 #else
1570  vs->basename, 'd', vs->sequence) < 1) {
1571 #endif
1572  av_free(filename);
1573  av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s' you can try to use -strftime 1 with it\n", vs->basename);
1574  return AVERROR(EINVAL);
1575  }
1576  ff_format_set_url(oc, filename);
1577  }
1578  if( vs->vtt_basename) {
1579  char *filename = NULL;
1580  if (replace_int_data_in_filename(&filename,
1581 #if FF_API_HLS_WRAP
1582  vs->vtt_basename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {
1583 #else
1584  vs->vtt_basename, 'd', vs->sequence) < 1) {
1585 #endif
1586  av_free(filename);
1587  av_log(vtt_oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", vs->vtt_basename);
1588  return AVERROR(EINVAL);
1589  }
1590  ff_format_set_url(vtt_oc, filename);
1591  }
1592  }
1593  vs->number++;
1594 
1595  set_http_options(s, &options, c);
1596 
1597  proto = avio_find_protocol_name(oc->url);
1598  use_temp_file = proto && !strcmp(proto, "file") && (c->flags & HLS_TEMP_FILE);
1599 
1600  if (use_temp_file) {
1601  char *new_name = av_asprintf("%s.tmp", oc->url);
1602  if (!new_name)
1603  return AVERROR(ENOMEM);
1604  ff_format_set_url(oc, new_name);
1605  }
1606 
1607  if (c->key_info_file || c->encrypt) {
1608  if (c->segment_type == SEGMENT_TYPE_FMP4) {
1609  av_log(s, AV_LOG_ERROR, "Encrypted fmp4 not yet supported\n");
1610  return AVERROR_PATCHWELCOME;
1611  }
1612 
1613  if (c->key_info_file && c->encrypt) {
1614  av_log(s, AV_LOG_WARNING, "Cannot use both -hls_key_info_file and -hls_enc,"
1615  " ignoring -hls_enc\n");
1616  }
1617 
1618  if (!c->encrypt_started || (c->flags & HLS_PERIODIC_REKEY)) {
1619  if (c->key_info_file) {
1620  if ((err = hls_encryption_start(s)) < 0)
1621  goto fail;
1622  } else {
1623  if ((err = do_encrypt(s, vs)) < 0)
1624  goto fail;
1625  }
1626  c->encrypt_started = 1;
1627  }
1628  if ((err = av_dict_set(&options, "encryption_key", c->key_string, 0))
1629  < 0)
1630  goto fail;
1631  err = av_strlcpy(iv_string, c->iv_string, sizeof(iv_string));
1632  if (!err)
1633  snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, vs->sequence);
1634  if ((err = av_dict_set(&options, "encryption_iv", iv_string, 0)) < 0)
1635  goto fail;
1636 
1637  filename = av_asprintf("crypto:%s", oc->url);
1638  if (!filename) {
1639  err = AVERROR(ENOMEM);
1640  goto fail;
1641  }
1642  err = hlsenc_io_open(s, &oc->pb, filename, &options);
1643  av_free(filename);
1644  av_dict_free(&options);
1645  if (err < 0)
1646  return err;
1647  } else if (c->segment_type != SEGMENT_TYPE_FMP4) {
1648  if ((err = hlsenc_io_open(s, &oc->pb, oc->url, &options)) < 0) {
1649  if (c->ignore_io_errors)
1650  err = 0;
1651  goto fail;
1652  }
1653  }
1654  if (vs->vtt_basename) {
1655  set_http_options(s, &options, c);
1656  if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->url, &options)) < 0) {
1657  if (c->ignore_io_errors)
1658  err = 0;
1659  goto fail;
1660  }
1661  }
1662  av_dict_free(&options);
1663 
1664  if (c->segment_type != SEGMENT_TYPE_FMP4) {
1665  /* We only require one PAT/PMT per segment. */
1666  if (oc->oformat->priv_class && oc->priv_data) {
1667  char period[21];
1668 
1669  snprintf(period, sizeof(period), "%d", (INT_MAX / 2) - 1);
1670 
1671  av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0);
1672  av_opt_set(oc->priv_data, "sdt_period", period, 0);
1673  av_opt_set(oc->priv_data, "pat_period", period, 0);
1674  }
1675  }
1676 
1677  if (vs->vtt_basename) {
1678  err = avformat_write_header(vtt_oc,NULL);
1679  if (err < 0)
1680  return err;
1681  }
1682 
1683  return 0;
1684 fail:
1685  av_dict_free(&options);
1686 
1687  return err;
1688 }
1689 
1691 {
1692  char b[21];
1693  time_t t = time(NULL);
1694  struct tm *p, tmbuf;
1695  HLSContext *hls = s->priv_data;
1696 
1697  p = localtime_r(&t, &tmbuf);
1698  // no %s support when strftime returned error or left format string unchanged
1699  // also no %s support on MSVC, which invokes the invalid parameter handler on unsupported format strings, instead of returning an error
1700  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
1701  return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.m4s" : "-%s.m4s";
1702  }
1703  return (HAVE_LIBC_MSVCRT || !strftime(b, sizeof(b), "%s", p) || !strcmp(b, "%s")) ? "-%Y%m%d%H%M%S.ts" : "-%s.ts";
1704 }
1705 
1706 static int append_postfix(char *name, int name_buf_len, int i)
1707 {
1708  char *p;
1709  char extension[10] = {'\0'};
1710 
1711  p = strrchr(name, '.');
1712  if (p) {
1713  av_strlcpy(extension, p, sizeof(extension));
1714  *p = '\0';
1715  }
1716 
1717  snprintf(name + strlen(name), name_buf_len - strlen(name), POSTFIX_PATTERN, i);
1718 
1719  if (strlen(extension))
1720  av_strlcat(name, extension, name_buf_len);
1721 
1722  return 0;
1723 }
1724 
1725 static int validate_name(int nb_vs, const char *fn)
1726 {
1727  const char *filename, *subdir_name;
1728  char *fn_dup = NULL;
1729  int ret = 0;
1730 
1731  if (!fn) {
1732  ret = AVERROR(EINVAL);
1733  goto fail;
1734  }
1735 
1736  fn_dup = av_strdup(fn);
1737  if (!fn_dup) {
1738  ret = AVERROR(ENOMEM);
1739  goto fail;
1740  }
1741 
1742  filename = av_basename(fn);
1743  subdir_name = av_dirname(fn_dup);
1744 
1745  if (nb_vs > 1 && !av_stristr(filename, "%v") && !av_stristr(subdir_name, "%v")) {
1746  av_log(NULL, AV_LOG_ERROR, "More than 1 variant streams are present, %%v is expected in the filename %s\n",
1747  fn);
1748  ret = AVERROR(EINVAL);
1749  goto fail;
1750  }
1751 
1752  if (av_stristr(filename, "%v") && av_stristr(subdir_name, "%v")) {
1753  av_log(NULL, AV_LOG_ERROR, "%%v is expected either in filename or in the sub-directory name of file %s\n",
1754  fn);
1755  ret = AVERROR(EINVAL);
1756  goto fail;
1757  }
1758 
1759 fail:
1760  av_freep(&fn_dup);
1761  return ret;
1762 }
1763 
1764 static int format_name(char *buf, int buf_len, int index)
1765 {
1766  const char *proto, *dir;
1767  char *orig_buf_dup = NULL, *mod_buf = NULL, *mod_buf_dup = NULL;
1768  int ret = 0;
1769 
1770  if (!av_stristr(buf, "%v"))
1771  return ret;
1772 
1773  orig_buf_dup = av_strdup(buf);
1774  if (!orig_buf_dup) {
1775  ret = AVERROR(ENOMEM);
1776  goto fail;
1777  }
1778 
1779  if (replace_int_data_in_filename(&mod_buf, orig_buf_dup, 'v', index) < 1) {
1780  ret = AVERROR(EINVAL);
1781  goto fail;
1782  }
1783  av_strlcpy(buf, mod_buf, buf_len);
1784 
1785  proto = avio_find_protocol_name(orig_buf_dup);
1786  dir = av_dirname(orig_buf_dup);
1787 
1788  /* if %v is present in the file's directory, create sub-directory */
1789  if (av_stristr(dir, "%v") && proto && !strcmp(proto, "file")) {
1790  mod_buf_dup = av_strdup(buf);
1791  if (!mod_buf_dup) {
1792  ret = AVERROR(ENOMEM);
1793  goto fail;
1794  }
1795 
1796  dir = av_dirname(mod_buf_dup);
1797  if (ff_mkdir_p(dir) == -1 && errno != EEXIST) {
1798  ret = AVERROR(errno);
1799  goto fail;
1800  }
1801  }
1802 
1803 fail:
1804  av_freep(&orig_buf_dup);
1805  av_freep(&mod_buf_dup);
1806  av_freep(&mod_buf);
1807  return ret;
1808 }
1809 
1811  enum AVMediaType codec_type,
1812  int stream_id)
1813 {
1814  unsigned int stream_index, cnt;
1815  if (stream_id < 0 || stream_id > s->nb_streams - 1)
1816  return -1;
1817  cnt = 0;
1818  for (stream_index = 0; stream_index < s->nb_streams; stream_index++) {
1819  if (s->streams[stream_index]->codecpar->codec_type != codec_type)
1820  continue;
1821  if (cnt == stream_id)
1822  return stream_index;
1823  cnt++;
1824  }
1825  return -1;
1826 }
1827 
1829 {
1830  HLSContext *hls = s->priv_data;
1831  VariantStream *vs;
1832  int stream_index;
1833  enum AVMediaType codec_type;
1834  int nb_varstreams, nb_streams;
1835  char *p, *q, *saveptr1, *saveptr2, *varstr, *keyval;
1836  const char *val;
1837 
1838  /**
1839  * Expected format for var_stream_map string is as below:
1840  * "a:0,v:0 a:1,v:1"
1841  * "a:0,agroup:a0,default:1,language:ENG a:1,agroup:a1,default:0 v:0,agroup:a0 v:1,agroup:a1"
1842  * This string specifies how to group the audio, video and subtitle streams
1843  * into different variant streams. The variant stream groups are separated
1844  * by space.
1845  *
1846  * a:, v:, s: are keys to specify audio, video and subtitle streams
1847  * respectively. Allowed values are 0 to 9 digits (limited just based on
1848  * practical usage)
1849  *
1850  * agroup: is key to specify audio group. A string can be given as value.
1851  */
1852  p = av_strdup(hls->var_stream_map);
1853  q = p;
1854  while(av_strtok(q, " \t", &saveptr1)) {
1855  q = NULL;
1856  hls->nb_varstreams++;
1857  }
1858  av_freep(&p);
1859 
1860  hls->var_streams = av_mallocz(sizeof(*hls->var_streams) * hls->nb_varstreams);
1861  if (!hls->var_streams)
1862  return AVERROR(ENOMEM);
1863 
1864  p = hls->var_stream_map;
1865  nb_varstreams = 0;
1866  while (varstr = av_strtok(p, " \t", &saveptr1)) {
1867  p = NULL;
1868 
1869  if (nb_varstreams < hls->nb_varstreams) {
1870  vs = &(hls->var_streams[nb_varstreams]);
1871  vs->var_stream_idx = nb_varstreams;
1872  vs->is_default = 0;
1873  nb_varstreams++;
1874  } else
1875  return AVERROR(EINVAL);
1876 
1877  q = varstr;
1878  while (q < varstr + strlen(varstr)) {
1879  if (!av_strncasecmp(q, "a:", 2) || !av_strncasecmp(q, "v:", 2) ||
1880  !av_strncasecmp(q, "s:", 2))
1881  vs->nb_streams++;
1882  q++;
1883  }
1884  vs->streams = av_mallocz(sizeof(AVStream *) * vs->nb_streams);
1885  if (!vs->streams)
1886  return AVERROR(ENOMEM);
1887 
1888  nb_streams = 0;
1889  while (keyval = av_strtok(varstr, ",", &saveptr2)) {
1890  varstr = NULL;
1891  if (av_strstart(keyval, "language:", &val)) {
1892  vs->language = av_strdup(val);
1893  if (!vs->language)
1894  return AVERROR(ENOMEM);
1895  continue;
1896  } else if (av_strstart(keyval, "default:", &val)) {
1897  vs->is_default = (!av_strncasecmp(val, "YES", strlen("YES")) ||
1898  (!av_strncasecmp(val, "1", strlen("1"))));
1899  hls->has_default_key = 1;
1900  continue;
1901  } else if (av_strstart(keyval, "agroup:", &val)) {
1902  vs->agroup = av_strdup(val);
1903  if (!vs->agroup)
1904  return AVERROR(ENOMEM);
1905  continue;
1906  } else if (av_strstart(keyval, "ccgroup:", &val)) {
1907  vs->ccgroup = av_strdup(val);
1908  if (!vs->ccgroup)
1909  return AVERROR(ENOMEM);
1910  continue;
1911  } else if (av_strstart(keyval, "v:", &val)) {
1912  codec_type = AVMEDIA_TYPE_VIDEO;
1913  hls->has_video_m3u8 = 1;
1914  } else if (av_strstart(keyval, "a:", &val)) {
1915  codec_type = AVMEDIA_TYPE_AUDIO;
1916  } else if (av_strstart(keyval, "s:", &val)) {
1917  codec_type = AVMEDIA_TYPE_SUBTITLE;
1918  } else {
1919  av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
1920  return AVERROR(EINVAL);
1921  }
1922 
1923  stream_index = -1;
1924  if (av_isdigit(*val))
1925  stream_index = get_nth_codec_stream_index (s, codec_type,
1926  atoi(val));
1927 
1928  if (stream_index >= 0 && nb_streams < vs->nb_streams) {
1929  vs->streams[nb_streams++] = s->streams[stream_index];
1930  } else {
1931  av_log(s, AV_LOG_ERROR, "Unable to map stream at %s\n", keyval);
1932  return AVERROR(EINVAL);
1933  }
1934  }
1935  }
1936  av_log(s, AV_LOG_DEBUG, "Number of variant streams %d\n",
1937  hls->nb_varstreams);
1938 
1939  return 0;
1940 }
1941 
1943 {
1944  HLSContext *hls = s->priv_data;
1945  int nb_ccstreams;
1946  char *p, *q, *ccstr, *keyval;
1947  char *saveptr1 = NULL, *saveptr2 = NULL;
1948  const char *val;
1949  ClosedCaptionsStream *ccs;
1950 
1951  p = av_strdup(hls->cc_stream_map);
1952  q = p;
1953  while(av_strtok(q, " \t", &saveptr1)) {
1954  q = NULL;
1955  hls->nb_ccstreams++;
1956  }
1957  av_freep(&p);
1958 
1959  hls->cc_streams = av_mallocz(sizeof(*hls->cc_streams) * hls->nb_ccstreams);
1960  if (!hls->cc_streams)
1961  return AVERROR(ENOMEM);
1962 
1963  p = hls->cc_stream_map;
1964  nb_ccstreams = 0;
1965  while (ccstr = av_strtok(p, " \t", &saveptr1)) {
1966  p = NULL;
1967 
1968  if (nb_ccstreams < hls->nb_ccstreams)
1969  ccs = &(hls->cc_streams[nb_ccstreams++]);
1970  else
1971  return AVERROR(EINVAL);
1972 
1973  while (keyval = av_strtok(ccstr, ",", &saveptr2)) {
1974  ccstr = NULL;
1975 
1976  if (av_strstart(keyval, "ccgroup:", &val)) {
1977  ccs->ccgroup = av_strdup(val);
1978  if (!ccs->ccgroup)
1979  return AVERROR(ENOMEM);
1980  } else if (av_strstart(keyval, "instreamid:", &val)) {
1981  ccs->instreamid = av_strdup(val);
1982  if (!ccs->instreamid)
1983  return AVERROR(ENOMEM);
1984  } else if (av_strstart(keyval, "language:", &val)) {
1985  ccs->language = av_strdup(val);
1986  if (!ccs->language)
1987  return AVERROR(ENOMEM);
1988  } else {
1989  av_log(s, AV_LOG_ERROR, "Invalid keyval %s\n", keyval);
1990  return AVERROR(EINVAL);
1991  }
1992  }
1993 
1994  if (!ccs->ccgroup || !ccs->instreamid) {
1995  av_log(s, AV_LOG_ERROR, "Insufficient parameters in cc stream map string\n");
1996  return AVERROR(EINVAL);
1997  }
1998 
1999  if (av_strstart(ccs->instreamid, "CC", &val)) {
2000  if(atoi(val) < 1 || atoi(val) > 4) {
2001  av_log(s, AV_LOG_ERROR, "Invalid instream ID CC index %d in %s, range 1-4\n",
2002  atoi(val), ccs->instreamid);
2003  return AVERROR(EINVAL);
2004  }
2005  } else if (av_strstart(ccs->instreamid, "SERVICE", &val)) {
2006  if(atoi(val) < 1 || atoi(val) > 63) {
2007  av_log(s, AV_LOG_ERROR, "Invalid instream ID SERVICE index %d in %s, range 1-63 \n",
2008  atoi(val), ccs->instreamid);
2009  return AVERROR(EINVAL);
2010  }
2011  } else {
2012  av_log(s, AV_LOG_ERROR, "Invalid instream ID %s, supported are CCn or SERIVICEn\n",
2013  ccs->instreamid);
2014  return AVERROR(EINVAL);
2015  }
2016  }
2017 
2018  return 0;
2019 }
2020 
2022  HLSContext *hls = s->priv_data;
2023  unsigned int i;
2024  int ret = 0;
2025 
2026  if (hls->cc_stream_map) {
2027  ret = parse_cc_stream_mapstring(s);
2028  if (ret < 0)
2029  return ret;
2030  }
2031 
2032  if (hls->var_stream_map) {
2034  } else {
2035  //By default, a single variant stream with all the codec streams is created
2036  hls->nb_varstreams = 1;
2037  hls->var_streams = av_mallocz(sizeof(*hls->var_streams) *
2038  hls->nb_varstreams);
2039  if (!hls->var_streams)
2040  return AVERROR(ENOMEM);
2041 
2042  hls->var_streams[0].var_stream_idx = 0;
2043  hls->var_streams[0].nb_streams = s->nb_streams;
2044  hls->var_streams[0].streams = av_mallocz(sizeof(AVStream *) *
2045  hls->var_streams[0].nb_streams);
2046  if (!hls->var_streams[0].streams)
2047  return AVERROR(ENOMEM);
2048 
2049  //by default, the first available ccgroup is mapped to the variant stream
2050  if (hls->nb_ccstreams) {
2051  hls->var_streams[0].ccgroup = av_strdup(hls->cc_streams[0].ccgroup);
2052  if (!hls->var_streams[0].ccgroup)
2053  return AVERROR(ENOMEM);
2054  }
2055 
2056  for (i = 0; i < s->nb_streams; i++)
2057  hls->var_streams[0].streams[i] = s->streams[i];
2058  }
2059  return 0;
2060 }
2061 
2063  HLSContext *hls = s->priv_data;
2064  const char *dir;
2065  char *fn1= NULL, *fn2 = NULL;
2066  int ret = 0;
2067 
2068  fn1 = av_strdup(s->url);
2069  if (!fn1) {
2070  ret = AVERROR(ENOMEM);
2071  goto fail;
2072  }
2073 
2074  dir = av_dirname(fn1);
2075 
2076  /**
2077  * if output file's directory has %v, variants are created in sub-directories
2078  * then master is created at the sub-directories level
2079  */
2080  if (dir && av_stristr(av_basename(dir), "%v")) {
2081  fn2 = av_strdup(dir);
2082  if (!fn2) {
2083  ret = AVERROR(ENOMEM);
2084  goto fail;
2085  }
2086  dir = av_dirname(fn2);
2087  }
2088 
2089  if (dir && strcmp(dir, "."))
2091  else
2093 
2094  if (!hls->master_m3u8_url) {
2095  ret = AVERROR(ENOMEM);
2096  goto fail;
2097  }
2098 
2099 fail:
2100  av_freep(&fn1);
2101  av_freep(&fn2);
2102 
2103  return ret;
2104 }
2105 
2107 {
2108  HLSContext *hls = s->priv_data;
2109  int ret, i, j;
2110  VariantStream *vs = NULL;
2111 
2112  for (i = 0; i < hls->nb_varstreams; i++) {
2113  vs = &hls->var_streams[i];
2114 
2115  ret = avformat_write_header(vs->avf, NULL);
2116  if (ret < 0)
2117  return ret;
2118  //av_assert0(s->nb_streams == hls->avf->nb_streams);
2119  for (j = 0; j < vs->nb_streams; j++) {
2120  AVStream *inner_st;
2121  AVStream *outer_st = vs->streams[j];
2122 
2123  if (hls->max_seg_size > 0) {
2124  if ((outer_st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) &&
2125  (outer_st->codecpar->bit_rate > hls->max_seg_size)) {
2126  av_log(s, AV_LOG_WARNING, "Your video bitrate is bigger than hls_segment_size, "
2127  "(%"PRId64 " > %"PRId64 "), the result maybe not be what you want.",
2128  outer_st->codecpar->bit_rate, hls->max_seg_size);
2129  }
2130  }
2131 
2132  if (outer_st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
2133  inner_st = vs->avf->streams[j];
2134  else if (vs->vtt_avf)
2135  inner_st = vs->vtt_avf->streams[0];
2136  else {
2137  /* We have a subtitle stream, when the user does not want one */
2138  inner_st = NULL;
2139  continue;
2140  }
2141  avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den);
2142  write_codec_attr(outer_st, vs);
2143 
2144  }
2145  /* Update the Codec Attr string for the mapped audio groups */
2146  if (vs->has_video && vs->agroup) {
2147  for (j = 0; j < hls->nb_varstreams; j++) {
2148  VariantStream *vs_agroup = &(hls->var_streams[j]);
2149  if (!vs_agroup->has_video && !vs_agroup->has_subtitle &&
2150  vs_agroup->agroup &&
2151  !av_strcasecmp(vs_agroup->agroup, vs->agroup)) {
2152  write_codec_attr(vs_agroup->streams[0], vs);
2153  }
2154  }
2155  }
2156  }
2157 
2158  return ret;
2159 }
2160 
2162 {
2163  HLSContext *hls = s->priv_data;
2164  AVFormatContext *oc = NULL;
2165  AVStream *st = s->streams[pkt->stream_index];
2166  int64_t end_pts = 0;
2167  int is_ref_pkt = 1;
2168  int ret = 0, can_split = 1, i, j;
2169  int stream_index = 0;
2170  int range_length = 0;
2171  const char *proto = NULL;
2172  int use_temp_file = 0;
2173  uint8_t *buffer = NULL;
2174  VariantStream *vs = NULL;
2175  AVDictionary *options = NULL;
2176  char *old_filename = NULL;
2177 
2178  for (i = 0; i < hls->nb_varstreams; i++) {
2179  vs = &hls->var_streams[i];
2180  for (j = 0; j < vs->nb_streams; j++) {
2181  if (vs->streams[j] == st) {
2182  if( st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE ) {
2183  oc = vs->vtt_avf;
2184  stream_index = 0;
2185  } else {
2186  oc = vs->avf;
2187  stream_index = j;
2188  }
2189  break;
2190  }
2191  }
2192 
2193  if (oc)
2194  break;
2195  }
2196 
2197  if (!oc) {
2198  av_log(s, AV_LOG_ERROR, "Unable to find mapping variant stream\n");
2199  return AVERROR(ENOMEM);
2200  }
2201 
2202  end_pts = hls->recording_time * vs->number;
2203 
2204  if (vs->sequence - vs->nb_entries > hls->start_sequence && hls->init_time > 0) {
2205  /* reset end_pts, hls->recording_time at end of the init hls list */
2206  int init_list_dur = hls->init_time * vs->nb_entries * AV_TIME_BASE;
2207  int after_init_list_dur = (vs->sequence - hls->start_sequence - vs->nb_entries ) * (hls->time * AV_TIME_BASE);
2208  hls->recording_time = hls->time * AV_TIME_BASE;
2209  end_pts = init_list_dur + after_init_list_dur ;
2210  }
2211 
2212  if (vs->start_pts == AV_NOPTS_VALUE) {
2213  vs->start_pts = pkt->pts;
2214  }
2215 
2216  if (vs->has_video) {
2217  can_split = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
2218  ((pkt->flags & AV_PKT_FLAG_KEY) || (hls->flags & HLS_SPLIT_BY_TIME));
2219  is_ref_pkt = (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->stream_index == vs->reference_stream_index);
2220  }
2221  if (pkt->pts == AV_NOPTS_VALUE)
2222  is_ref_pkt = can_split = 0;
2223 
2224  if (is_ref_pkt) {
2225  if (vs->end_pts == AV_NOPTS_VALUE)
2226  vs->end_pts = pkt->pts;
2227  if (vs->new_start) {
2228  vs->new_start = 0;
2229  vs->duration = (double)(pkt->pts - vs->end_pts)
2230  * st->time_base.num / st->time_base.den;
2231  vs->dpp = (double)(pkt->duration) * st->time_base.num / st->time_base.den;
2232  } else {
2233  if (pkt->duration) {
2234  vs->duration += (double)(pkt->duration) * st->time_base.num / st->time_base.den;
2235  } else {
2236  av_log(s, AV_LOG_WARNING, "pkt->duration = 0, maybe the hls segment duration will not precise\n");
2237  vs->duration = (double)(pkt->pts - vs->end_pts) * st->time_base.num / st->time_base.den;
2238  }
2239  }
2240 
2241  }
2242 
2243  if (vs->packets_written && can_split && av_compare_ts(pkt->pts - vs->start_pts, st->time_base,
2244  end_pts, AV_TIME_BASE_Q) >= 0) {
2245  int64_t new_start_pos;
2246  int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
2247 
2248  av_write_frame(vs->avf, NULL); /* Flush any buffered data */
2249 
2250  new_start_pos = avio_tell(vs->avf->pb);
2251 
2252  if (hls->segment_type != SEGMENT_TYPE_FMP4) {
2253  avio_flush(oc->pb);
2254  vs->size = new_start_pos - vs->start_pos;
2255  } else {
2256  vs->size = new_start_pos;
2257  }
2258 
2259  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2260  if (!vs->init_range_length) {
2261  avio_flush(oc->pb);
2262  range_length = avio_close_dyn_buf(oc->pb, &buffer);
2263  avio_write(vs->out, buffer, range_length);
2264  av_free(buffer);
2265  vs->init_range_length = range_length;
2266  avio_open_dyn_buf(&oc->pb);
2267  vs->packets_written = 0;
2268  vs->start_pos = range_length;
2269  if (!byterange_mode) {
2270  ff_format_io_close(s, &vs->out);
2271  hlsenc_io_close(s, &vs->out, vs->base_output_dirname);
2272  }
2273  }
2274  } else {
2275  if (!byterange_mode) {
2276  hlsenc_io_close(s, &oc->pb, oc->url);
2277  }
2278  }
2279  if (!byterange_mode) {
2280  if (vs->vtt_avf) {
2281  hlsenc_io_close(s, &vs->vtt_avf->pb, vs->vtt_avf->url);
2282  }
2283  }
2284 
2285  if (oc->url[0]) {
2286  proto = avio_find_protocol_name(oc->url);
2287  use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & HLS_TEMP_FILE);
2288  }
2289 
2290  // look to rename the asset name
2291  if (use_temp_file) {
2292  if (!(hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size <= 0))
2293  if ((vs->avf->oformat->priv_class && vs->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4)
2294  av_opt_set(vs->avf->priv_data, "mpegts_flags", "resend_headers", 0);
2295  }
2296 
2297  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2298  if (hls->flags & HLS_SINGLE_FILE) {
2299  ret = flush_dynbuf(vs, &range_length);
2300  if (ret < 0) {
2301  return ret;
2302  }
2303  vs->size = range_length;
2304  } else {
2305  set_http_options(s, &options, hls);
2306  ret = hlsenc_io_open(s, &vs->out, vs->avf->url, &options);
2307  if (ret < 0) {
2309  "Failed to open file '%s'\n", vs->avf->url);
2310  return hls->ignore_io_errors ? 0 : ret;
2311  }
2312  write_styp(vs->out);
2313  ret = flush_dynbuf(vs, &range_length);
2314  if (ret < 0) {
2315  return ret;
2316  }
2317  ff_format_io_close(s, &vs->out);
2318  }
2319  }
2320 
2321  if (use_temp_file && !(hls->flags & HLS_SINGLE_FILE)) {
2322  hls_rename_temp_file(s, oc);
2323  }
2324 
2325  old_filename = av_strdup(vs->avf->url);
2326  if (!old_filename) {
2327  return AVERROR(ENOMEM);
2328  }
2329 
2330  if (vs->start_pos || hls->segment_type != SEGMENT_TYPE_FMP4) {
2331  ret = hls_append_segment(s, hls, vs, vs->duration, vs->start_pos, vs->size);
2332  vs->end_pts = pkt->pts;
2333  vs->duration = 0;
2334  if (ret < 0) {
2335  av_free(old_filename);
2336  return ret;
2337  }
2338  }
2339 
2340  if (hls->segment_type != SEGMENT_TYPE_FMP4) {
2341  vs->start_pos = new_start_pos;
2342  } else {
2343  vs->start_pos += vs->size;
2344  }
2345 
2346  if (hls->flags & HLS_SINGLE_FILE) {
2347  vs->number++;
2348  } else if (hls->max_seg_size > 0) {
2349  if (vs->start_pos >= hls->max_seg_size) {
2350  vs->sequence++;
2351  sls_flag_file_rename(hls, vs, old_filename);
2352  ret = hls_start(s, vs);
2353  vs->start_pos = 0;
2354  /* When split segment by byte, the duration is short than hls_time,
2355  * so it is not enough one segment duration as hls_time, */
2356  vs->number--;
2357  }
2358  vs->number++;
2359  } else {
2360  sls_flag_file_rename(hls, vs, old_filename);
2361  ret = hls_start(s, vs);
2362  }
2363  av_free(old_filename);
2364 
2365  if (ret < 0) {
2366  return ret;
2367  }
2368 
2369  // if we're building a VOD playlist, skip writing the manifest multiple times, and just wait until the end
2370  if (hls->pl_type != PLAYLIST_TYPE_VOD) {
2371  if ((ret = hls_window(s, 0, vs)) < 0) {
2372  return ret;
2373  }
2374  }
2375  }
2376 
2377  vs->packets_written++;
2378  if (oc->pb) {
2379  ret = ff_write_chained(oc, stream_index, pkt, s, 0);
2380  if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->flags & AV_PKT_FLAG_KEY)) {
2381  vs->video_keyframe_size = avio_tell(oc->pb) - vs->video_lastpos;
2382  vs->video_keyframe_pos = vs->start_pos;
2383  } else {
2384  vs->video_lastpos = avio_tell(oc->pb);
2385  }
2386 
2387  if (hls->ignore_io_errors)
2388  ret = 0;
2389  }
2390 
2391  return ret;
2392 }
2393 
2394 static void hls_free_variant_streams(struct HLSContext *hls)
2395 {
2396  int i = 0;
2397  AVFormatContext *vtt_oc = NULL;
2398  VariantStream *vs = NULL;
2399 
2400  for (i = 0; i < hls->nb_varstreams; i++) {
2401  vs = &hls->var_streams[i];
2402  vtt_oc = vs->vtt_avf;
2403 
2404  av_freep(&vs->basename);
2407  if (vtt_oc) {
2408  av_freep(&vs->vtt_basename);
2409  av_freep(&vs->vtt_m3u8_name);
2410  }
2411 
2414  av_freep(&vs->m3u8_name);
2415  av_freep(&vs->streams);
2416  av_freep(&vs->agroup);
2417  av_freep(&vs->language);
2418  av_freep(&vs->ccgroup);
2419  av_freep(&vs->baseurl);
2420  }
2421 }
2422 
2423 static int hls_write_trailer(struct AVFormatContext *s)
2424 {
2425  HLSContext *hls = s->priv_data;
2426  AVFormatContext *oc = NULL;
2427  AVFormatContext *vtt_oc = NULL;
2428  char *old_filename = NULL;
2429  const char *proto = NULL;
2430  int use_temp_file = 0;
2431  int i;
2432  int ret = 0;
2433  VariantStream *vs = NULL;
2434 
2435  for (i = 0; i < hls->nb_varstreams; i++) {
2436  vs = &hls->var_streams[i];
2437 
2438  oc = vs->avf;
2439  vtt_oc = vs->vtt_avf;
2440  old_filename = av_strdup(vs->avf->url);
2441  use_temp_file = 0;
2442 
2443  if (!old_filename) {
2444  return AVERROR(ENOMEM);
2445  }
2446  if ( hls->segment_type == SEGMENT_TYPE_FMP4) {
2447  int range_length = 0;
2448  if (!vs->init_range_length) {
2449  uint8_t *buffer = NULL;
2450  int range_length, byterange_mode;
2451  av_write_frame(vs->avf, NULL); /* Flush any buffered data */
2452  avio_flush(oc->pb);
2453 
2454  range_length = avio_close_dyn_buf(oc->pb, &buffer);
2455  avio_write(vs->out, buffer, range_length);
2456  av_free(buffer);
2457  vs->init_range_length = range_length;
2458  avio_open_dyn_buf(&oc->pb);
2459  vs->packets_written = 0;
2460  vs->start_pos = range_length;
2461  byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
2462  if (!byterange_mode) {
2463  ff_format_io_close(s, &vs->out);
2464  hlsenc_io_close(s, &vs->out, vs->base_output_dirname);
2465  }
2466  }
2467  if (!(hls->flags & HLS_SINGLE_FILE)) {
2468  ret = hlsenc_io_open(s, &vs->out, vs->avf->url, NULL);
2469  if (ret < 0) {
2470  av_log(s, AV_LOG_ERROR, "Failed to open file '%s'\n", vs->avf->url);
2471  goto failed;
2472  }
2473  write_styp(vs->out);
2474  }
2475  ret = flush_dynbuf(vs, &range_length);
2476  if (ret < 0) {
2477  goto failed;
2478  }
2479  vs->size = range_length;
2480  ff_format_io_close(s, &vs->out);
2481  }
2482 
2483 failed:
2484  av_write_trailer(oc);
2485 
2486  if (oc->url[0]) {
2487  proto = avio_find_protocol_name(oc->url);
2488  use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & HLS_TEMP_FILE);
2489  }
2490 
2491  if (oc->pb) {
2492  if (hls->segment_type != SEGMENT_TYPE_FMP4) {
2493  vs->size = avio_tell(vs->avf->pb) - vs->start_pos;
2494  ff_format_io_close(s, &oc->pb);
2495  }
2496 
2497  // rename that segment from .tmp to the real one
2498  if (use_temp_file && !(hls->flags & HLS_SINGLE_FILE)) {
2499  hls_rename_temp_file(s, oc);
2500  av_free(old_filename);
2501  old_filename = av_strdup(vs->avf->url);
2502 
2503  if (!old_filename) {
2504  return AVERROR(ENOMEM);
2505  }
2506  }
2507 
2508  /* after av_write_trailer, then duration + 1 duration per packet */
2509  hls_append_segment(s, hls, vs, vs->duration + vs->dpp, vs->start_pos, vs->size);
2510  }
2511 
2512  sls_flag_file_rename(hls, vs, old_filename);
2513 
2514  if (vtt_oc) {
2515  if (vtt_oc->pb)
2516  av_write_trailer(vtt_oc);
2517  vs->size = avio_tell(vs->vtt_avf->pb) - vs->start_pos;
2518  ff_format_io_close(s, &vtt_oc->pb);
2519  avformat_free_context(vtt_oc);
2520  }
2522 
2523  vs->avf = NULL;
2524  hls_window(s, 1, vs);
2525  av_free(old_filename);
2526  }
2527 
2529 
2530  for (i = 0; i < hls->nb_ccstreams; i++) {
2531  ClosedCaptionsStream *ccs = &hls->cc_streams[i];
2532  av_freep(&ccs->ccgroup);
2533  av_freep(&ccs->instreamid);
2534  av_freep(&ccs->language);
2535  }
2536 
2537  ff_format_io_close(s, &hls->m3u8_out);
2538  ff_format_io_close(s, &hls->sub_m3u8_out);
2539  av_freep(&hls->key_basename);
2540  av_freep(&hls->var_streams);
2541  av_freep(&hls->cc_streams);
2542  av_freep(&hls->master_m3u8_url);
2543  return 0;
2544 }
2545 
2546 
2548 {
2549  int ret = 0;
2550  int i = 0;
2551  int j = 0;
2552  HLSContext *hls = s->priv_data;
2553  const char *pattern = "%d.ts";
2554  VariantStream *vs = NULL;
2555  int basename_size = 0;
2556  const char *pattern_localtime_fmt = get_default_pattern_localtime_fmt(s);
2557  const char *vtt_pattern = "%d.vtt";
2558  char *p = NULL;
2559  int vtt_basename_size = 0;
2560  int fmp4_init_filename_len = strlen(hls->fmp4_init_filename) + 1;
2561 
2562  hls->has_default_key = 0;
2563  hls->has_video_m3u8 = 0;
2564  ret = update_variant_stream_info(s);
2565  if (ret < 0) {
2566  av_log(s, AV_LOG_ERROR, "Variant stream info update failed with status %x\n",
2567  ret);
2568  goto fail;
2569  }
2570  //TODO: Updates needed to encryption functionality with periodic re-key when more than one variant streams are present
2571  if (hls->nb_varstreams > 1 && hls->flags & HLS_PERIODIC_REKEY) {
2572  ret = AVERROR(EINVAL);
2573  av_log(s, AV_LOG_ERROR, "Periodic re-key not supported when more than one variant streams are present\n");
2574  goto fail;
2575  }
2576 
2577  ret = validate_name(hls->nb_varstreams, s->url);
2578  if (ret < 0)
2579  goto fail;
2580 
2581  if (hls->segment_filename) {
2582  ret = validate_name(hls->nb_varstreams, hls->segment_filename);
2583  if (ret < 0)
2584  goto fail;
2585  }
2586 
2587  if (av_strcasecmp(hls->fmp4_init_filename, "init.mp4")) {
2589  if (ret < 0)
2590  goto fail;
2591  }
2592 
2593  if (hls->subtitle_filename) {
2594  ret = validate_name(hls->nb_varstreams, hls->subtitle_filename);
2595  if (ret < 0)
2596  goto fail;
2597  }
2598 
2599  if (hls->master_pl_name) {
2600  ret = update_master_pl_info(s);
2601  if (ret < 0) {
2602  av_log(s, AV_LOG_ERROR, "Master stream info update failed with status %x\n",
2603  ret);
2604  goto fail;
2605  }
2606  }
2607 
2608  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2609  pattern = "%d.m4s";
2610  }
2613  time_t t = time(NULL); // we will need it in either case
2615  hls->start_sequence = (int64_t)t;
2617  char b[15];
2618  struct tm *p, tmbuf;
2619  if (!(p = localtime_r(&t, &tmbuf)))
2620  return AVERROR(ENOMEM);
2621  if (!strftime(b, sizeof(b), "%Y%m%d%H%M%S", p))
2622  return AVERROR(ENOMEM);
2623  hls->start_sequence = strtoll(b, NULL, 10);
2624  }
2625  av_log(hls, AV_LOG_DEBUG, "start_number evaluated to %"PRId64"\n", hls->start_sequence);
2626  }
2627 
2628  hls->recording_time = (hls->init_time ? hls->init_time : hls->time) * AV_TIME_BASE;
2629  for (i = 0; i < hls->nb_varstreams; i++) {
2630  vs = &hls->var_streams[i];
2631 
2632  vs->m3u8_name = av_strdup(s->url);
2633  if (!vs->m3u8_name ) {
2634  ret = AVERROR(ENOMEM);
2635  goto fail;
2636  }
2637  ret = format_name(vs->m3u8_name, strlen(s->url) + 1, i);
2638  if (ret < 0)
2639  goto fail;
2640 
2641  vs->sequence = hls->start_sequence;
2642  vs->start_pts = AV_NOPTS_VALUE;
2643  vs->end_pts = AV_NOPTS_VALUE;
2644  vs->current_segment_final_filename_fmt[0] = '\0';
2645 
2646  if (hls->flags & HLS_SPLIT_BY_TIME && hls->flags & HLS_INDEPENDENT_SEGMENTS) {
2647  // Independent segments cannot be guaranteed when splitting by time
2650  "'split_by_time' and 'independent_segments' cannot be enabled together. "
2651  "Disabling 'independent_segments' flag\n");
2652  }
2653 
2654  if (hls->flags & HLS_PROGRAM_DATE_TIME) {
2655  time_t now0;
2656  time(&now0);
2657  vs->initial_prog_date_time = now0;
2658  }
2659  if (hls->format_options_str) {
2660  ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
2661  if (ret < 0) {
2662  av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n", hls->format_options_str);
2663  goto fail;
2664  }
2665  }
2666 
2667  for (j = 0; j < vs->nb_streams; j++) {
2669  /* Get one video stream to reference for split segments
2670  * so use the first video stream index. */
2671  if ((vs->has_video == 1) && (vs->streams[j]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)) {
2672  vs->reference_stream_index = vs->streams[j]->index;
2673  }
2675  }
2676 
2677  if (vs->has_video > 1)
2678  av_log(s, AV_LOG_WARNING, "More than a single video stream present, expect issues decoding it.\n");
2679  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2680  vs->oformat = av_guess_format("mp4", NULL, NULL);
2681  } else {
2682  vs->oformat = av_guess_format("mpegts", NULL, NULL);
2683  }
2684 
2685  if (!vs->oformat) {
2687  goto fail;
2688  }
2689 
2690  if (vs->has_subtitle) {
2691  vs->vtt_oformat = av_guess_format("webvtt", NULL, NULL);
2692  if (!vs->oformat) {
2694  goto fail;
2695  }
2696  }
2697  if (hls->segment_filename) {
2698  basename_size = strlen(hls->segment_filename) + 1;
2699  vs->basename = av_malloc(basename_size);
2700  if (!vs->basename) {
2701  ret = AVERROR(ENOMEM);
2702  goto fail;
2703  }
2704 
2705  av_strlcpy(vs->basename, hls->segment_filename, basename_size);
2706  ret = format_name(vs->basename, basename_size, i);
2707  if (ret < 0)
2708  goto fail;
2709  } else {
2710  if (hls->flags & HLS_SINGLE_FILE) {
2711  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2712  pattern = ".m4s";
2713  } else {
2714  pattern = ".ts";
2715  }
2716  }
2717 
2718  if (hls->use_localtime) {
2719  basename_size = strlen(vs->m3u8_name) + strlen(pattern_localtime_fmt) + 1;
2720  } else {
2721  basename_size = strlen(vs->m3u8_name) + strlen(pattern) + 1;
2722  }
2723 
2724  vs->basename = av_malloc(basename_size);
2725  if (!vs->basename) {
2726  ret = AVERROR(ENOMEM);
2727  goto fail;
2728  }
2729 
2730  av_strlcpy(vs->basename, vs->m3u8_name, basename_size);
2731 
2732  p = strrchr(vs->basename, '.');
2733  if (p)
2734  *p = '\0';
2735  if (hls->use_localtime) {
2736  av_strlcat(vs->basename, pattern_localtime_fmt, basename_size);
2737  } else {
2738  av_strlcat(vs->basename, pattern, basename_size);
2739  }
2740  }
2741 
2742  if (hls->segment_type == SEGMENT_TYPE_FMP4) {
2743  if (hls->nb_varstreams > 1)
2744  fmp4_init_filename_len += strlen(POSTFIX_PATTERN);
2745  if (hls->flags & HLS_SINGLE_FILE) {
2747  if (!vs->fmp4_init_filename) {
2748  ret = AVERROR(ENOMEM);
2749  goto fail;
2750  }
2751  } else {
2752  vs->fmp4_init_filename = av_malloc(fmp4_init_filename_len);
2753  if (!vs->fmp4_init_filename ) {
2754  ret = AVERROR(ENOMEM);
2755  goto fail;
2756  }
2758  fmp4_init_filename_len);
2759  if (hls->nb_varstreams > 1) {
2760  if (av_stristr(vs->fmp4_init_filename, "%v")) {
2761  format_name(vs->fmp4_init_filename, fmp4_init_filename_len, i);
2762  } else {
2763  ret = append_postfix(vs->fmp4_init_filename, fmp4_init_filename_len, i);
2764  }
2765  if (ret < 0)
2766  goto fail;
2767  }
2768 
2769  fmp4_init_filename_len = strlen(vs->m3u8_name) +
2770  strlen(vs->fmp4_init_filename) + 1;
2771 
2772  vs->base_output_dirname = av_malloc(fmp4_init_filename_len);
2773  if (!vs->base_output_dirname) {
2774  ret = AVERROR(ENOMEM);
2775  goto fail;
2776  }
2777 
2779  fmp4_init_filename_len);
2780  p = strrchr(vs->base_output_dirname, '/');
2781  if (p) {
2782  *(p + 1) = '\0';
2784  fmp4_init_filename_len);
2785  } else {
2787  fmp4_init_filename_len);
2788  }
2789  }
2790  }
2791 
2792  if (!hls->use_localtime) {
2794  if (ret < 0) {
2795  goto fail;
2796  }
2797  } else {
2798  ret = sls_flag_check_duration_size(hls, vs);
2799  if (ret < 0) {
2800  goto fail;
2801  }
2802  }
2803  if (vs->has_subtitle) {
2804 
2805  if (hls->flags & HLS_SINGLE_FILE)
2806  vtt_pattern = ".vtt";
2807  vtt_basename_size = strlen(vs->m3u8_name) + strlen(vtt_pattern) + 1;
2808 
2809  vs->vtt_basename = av_malloc(vtt_basename_size);
2810  if (!vs->vtt_basename) {
2811  ret = AVERROR(ENOMEM);
2812  goto fail;
2813  }
2814  vs->vtt_m3u8_name = av_malloc(vtt_basename_size);
2815  if (!vs->vtt_m3u8_name ) {
2816  ret = AVERROR(ENOMEM);
2817  goto fail;
2818  }
2819  av_strlcpy(vs->vtt_basename, vs->m3u8_name, vtt_basename_size);
2820  p = strrchr(vs->vtt_basename, '.');
2821  if (p)
2822  *p = '\0';
2823 
2824  if ( hls->subtitle_filename ) {
2825  strcpy(vs->vtt_m3u8_name, hls->subtitle_filename);
2826  ret = format_name(vs->vtt_m3u8_name, vtt_basename_size, i);
2827  if (ret < 0)
2828  goto fail;
2829  } else {
2830  strcpy(vs->vtt_m3u8_name, vs->vtt_basename);
2831  av_strlcat(vs->vtt_m3u8_name, "_vtt.m3u8", vtt_basename_size);
2832  }
2833  av_strlcat(vs->vtt_basename, vtt_pattern, vtt_basename_size);
2834  }
2835 
2836  if (hls->baseurl) {
2837  vs->baseurl = av_strdup(hls->baseurl);
2838  if (!vs->baseurl) {
2839  ret = AVERROR(ENOMEM);
2840  goto fail;
2841  }
2842  }
2843 
2844  if ((ret = hls_mux_init(s, vs)) < 0)
2845  goto fail;
2846 
2847  if (hls->flags & HLS_APPEND_LIST) {
2848  parse_playlist(s, vs->m3u8_name, vs);
2849  vs->discontinuity = 1;
2850  if (hls->init_time > 0) {
2851  av_log(s, AV_LOG_WARNING, "append_list mode does not support hls_init_time,"
2852  " hls_init_time value will have no effect\n");
2853  hls->init_time = 0;
2854  hls->recording_time = hls->time * AV_TIME_BASE;
2855  }
2856  }
2857 
2858  if ((ret = hls_start(s, vs)) < 0)
2859  goto fail;
2860  }
2861 
2862 fail:
2863  if (ret < 0) {
2864  av_freep(&hls->key_basename);
2865  for (i = 0; i < hls->nb_varstreams && hls->var_streams; i++) {
2866  vs = &hls->var_streams[i];
2867  av_freep(&vs->basename);
2868  av_freep(&vs->vtt_basename);
2870  av_freep(&vs->m3u8_name);
2871  av_freep(&vs->vtt_m3u8_name);
2872  av_freep(&vs->streams);
2873  av_freep(&vs->language);
2874  av_freep(&vs->agroup);
2875  av_freep(&vs->ccgroup);
2876  av_freep(&vs->baseurl);
2877  if (vs->avf)
2879  if (vs->vtt_avf)
2881  }
2882  for (i = 0; i < hls->nb_ccstreams; i++) {
2883  ClosedCaptionsStream *ccs = &hls->cc_streams[i];
2884  av_freep(&ccs->ccgroup);
2885  av_freep(&ccs->instreamid);
2886  av_freep(&ccs->language);
2887  }
2888  av_freep(&hls->var_streams);
2889  av_freep(&hls->cc_streams);
2890  av_freep(&hls->master_m3u8_url);
2891  }
2892 
2893  return ret;
2894 }
2895 
2896 #define OFFSET(x) offsetof(HLSContext, x)
2897 #define E AV_OPT_FLAG_ENCODING_PARAM
2898 static const AVOption options[] = {
2899  {"start_number", "set first number in the sequence", OFFSET(start_sequence),AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E},
2900  {"hls_time", "set segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E},
2901  {"hls_init_time", "set segment length in seconds at init list", OFFSET(init_time), AV_OPT_TYPE_FLOAT, {.dbl = 0}, 0, FLT_MAX, E},
2902  {"hls_list_size", "set maximum number of playlist entries", OFFSET(max_nb_segments), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E},
2903  {"hls_delete_threshold", "set number of unreferenced segments to keep before deleting", OFFSET(hls_delete_threshold), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, E},
2904  {"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},
2905  {"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},
2906 #if FF_API_HLS_WRAP
2907  {"hls_wrap", "set number after which the index wraps (will be deprecated)", OFFSET(wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E},
2908 #endif
2909  {"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},
2910  {"hls_base_url", "url to prepend to each playlist entry", OFFSET(baseurl), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2911  {"hls_segment_filename", "filename template for segment files", OFFSET(segment_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2912  {"hls_segment_size", "maximum size per segment file, (in bytes)", OFFSET(max_seg_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E},
2913  {"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},
2914  {"hls_enc", "enable AES128 encryption support", OFFSET(encrypt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E},
2915  {"hls_enc_key", "hex-coded 16 byte key to encrypt the segments", OFFSET(key), AV_OPT_TYPE_STRING, .flags = E},
2916  {"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},
2917  {"hls_enc_iv", "hex-coded 16 byte initialization vector", OFFSET(iv), AV_OPT_TYPE_STRING, .flags = E},
2918  {"hls_subtitle_path", "set path of hls subtitles", OFFSET(subtitle_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2919  {"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"},
2920  {"mpegts", "make segment file to mpegts files in m3u8", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_MPEGTS }, 0, UINT_MAX, E, "segment_type"},
2921  {"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"},
2922  {"hls_fmp4_init_filename", "set fragment mp4 file init filename", OFFSET(fmp4_init_filename), AV_OPT_TYPE_STRING, {.str = "init.mp4"}, 0, 0, E},
2923  {"hls_flags", "set flags affecting HLS playlist and media file generation", OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0 }, 0, UINT_MAX, E, "flags"},
2924  {"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"},
2925  {"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"},
2926  {"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"},
2927  {"round_durations", "round durations in m3u8 to whole numbers", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_ROUND_DURATIONS }, 0, UINT_MAX, E, "flags"},
2928  {"discont_start", "start the playlist with a discontinuity tag", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_DISCONT_START }, 0, UINT_MAX, E, "flags"},
2929  {"omit_endlist", "Do not append an endlist when ending stream", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_OMIT_ENDLIST }, 0, UINT_MAX, E, "flags"},
2930  {"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"},
2931  {"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"},
2932  {"program_date_time", "add EXT-X-PROGRAM-DATE-TIME", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PROGRAM_DATE_TIME }, 0, UINT_MAX, E, "flags"},
2933  {"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"},
2934  {"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"},
2935  {"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"},
2936  {"periodic_rekey", "reload keyinfo file periodically for re-keying", 0, AV_OPT_TYPE_CONST, {.i64 = HLS_PERIODIC_REKEY }, 0, UINT_MAX, E, "flags"},
2937  {"independent_segments", "add EXT-X-INDEPENDENT-SEGMENTS, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_INDEPENDENT_SEGMENTS }, 0, UINT_MAX, E, "flags"},
2938  {"iframes_only", "add EXT-X-I-FRAMES-ONLY, whenever applicable", 0, AV_OPT_TYPE_CONST, { .i64 = HLS_I_FRAMES_ONLY }, 0, UINT_MAX, E, "flags"},
2939 #if FF_API_HLS_USE_LOCALTIME
2940  {"use_localtime", "set filename expansion with strftime at segment creation(will be deprecated )", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
2941 #endif
2942  {"strftime", "set filename expansion with strftime at segment creation", OFFSET(use_localtime), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
2943 #if FF_API_HLS_USE_LOCALTIME
2944  {"use_localtime_mkdir", "create last directory component in strftime-generated filename(will be deprecated)", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
2945 #endif
2946  {"strftime_mkdir", "create last directory component in strftime-generated filename", OFFSET(use_localtime_mkdir), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
2947  {"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" },
2948  {"event", "EVENT playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_EVENT }, INT_MIN, INT_MAX, E, "pl_type" },
2949  {"vod", "VOD playlist", 0, AV_OPT_TYPE_CONST, {.i64 = PLAYLIST_TYPE_VOD }, INT_MIN, INT_MAX, E, "pl_type" },
2950  {"method", "set the HTTP method(default: PUT)", OFFSET(method), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2951  {"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" },
2952  {"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" },
2953  {"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" },
2954  {"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" },
2955  {"http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2956  {"var_stream_map", "Variant stream map string", OFFSET(var_stream_map), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2957  {"cc_stream_map", "Closed captions stream map string", OFFSET(cc_stream_map), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2958  {"master_pl_name", "Create HLS master playlist with this name", OFFSET(master_pl_name), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2959  {"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},
2960  {"http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
2961  {"timeout", "set timeout for socket I/O operations", OFFSET(timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E },
2962  {"ignore_io_errors", "Ignore IO errors for stable long-duration runs with network output", OFFSET(ignore_io_errors), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2963  { NULL },
2964 };
2965 
2966 static const AVClass hls_class = {
2967  .class_name = "hls muxer",
2968  .item_name = av_default_item_name,
2969  .option = options,
2970  .version = LIBAVUTIL_VERSION_INT,
2971 };
2972 
2973 
2975  .name = "hls",
2976  .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
2977  .extensions = "m3u8",
2978  .priv_data_size = sizeof(HLSContext),
2979  .audio_codec = AV_CODEC_ID_AAC,
2980  .video_codec = AV_CODEC_ID_H264,
2981  .subtitle_codec = AV_CODEC_ID_WEBVTT,
2983  .init = hls_init,
2987  .priv_class = &hls_class,
2988 };
int64_t timeout
Definition: hlsenc.c:237
float time
Definition: hlsenc.c:180
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:689
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
A callback for opening new IO streams.
Definition: avformat.h:1940
#define NULL
Definition: coverity.c:32
const char const char void * val
Definition: avisynth_c.h:863
char key_uri[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:214
Bytestream IO Context.
Definition: avio.h:161
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
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:228
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1636
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1420
AVOption.
Definition: opt.h:246
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static int hls_write_trailer(struct AVFormatContext *s)
Definition: hlsenc.c:2423
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:878
char current_segment_final_filename_fmt[1024]
Definition: hlsenc.c:152
static int update_variant_stream_info(AVFormatContext *s)
Definition: hlsenc.c:2021
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
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:4882
double duration
Definition: hlsenc.c:74
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
int max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition: avcodec.h:1134
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:1311
int ff_mkdir_p(const char *path)
Automatically create sub-directories.
Definition: utils.c:4799
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3953
char * vtt_format_options_str
Definition: hlsenc.c:201
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:943
char * key_basename
Definition: hlsenc.c:209
int64_t size
Definition: hlsenc.c:77
int num
Numerator.
Definition: rational.h:59
int use_localtime_mkdir
flag to mkdir dirname in timebased filename
Definition: hlsenc.c:194
int index
stream index in AVFormatContext
Definition: avformat.h:882
int av_dict_count(const AVDictionary *m)
Get number of entries in dictionary.
Definition: dict.c:35
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
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 int hls_start(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:1494
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:655
enum AVMediaType codec_type
Definition: rtp.c:37
int discontinuity_set
Definition: hlsenc.c:138
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
Definition: avstring.c:223
static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number)
Definition: hlsenc.c:343
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:144
CodecAttributeStatus attr_status
Definition: hlsenc.c:159
#define POSTFIX_PATTERN
Definition: hlsenc.c:69
const char * key
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
char * user_agent
Definition: hlsenc.c:220
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:5644
#define fn(a)
char * ccgroup
Definition: hlsenc.c:165
#define AVFMT_ALLOW_FLUSH
Format allows flushing.
Definition: avformat.h:476
int64_t keyframe_pos
Definition: hlsenc.c:78
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1391
static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
Definition: hlsenc.c:1371
static void hlsenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename)
Definition: hlsenc.c:263
unsigned int nb_streams
Definition: hlsenc.c:160
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
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:2062
int m3u8_created
Definition: hlsenc.c:161
static void hls_free_variant_streams(struct HLSContext *hls)
Definition: hlsenc.c:2394
VariantStream * var_streams
Definition: hlsenc.c:222
static int do_encrypt(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:582
Format I/O context.
Definition: avformat.h:1358
int max_nb_segments
Definition: hlsenc.c:182
AVIOContext * m3u8_out
Definition: hlsenc.c:235
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:208
int packets_written
Definition: hlsenc.c:119
const char * av_basename(const char *path)
Thread safe basename.
Definition: avstring.c:258
char * vtt_m3u8_name
Definition: hlsenc.c:148
uint8_t
static int nb_streams
Definition: ffprobe.c:280
#define av_malloc(s)
float init_time
Definition: hlsenc.c:181
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:154
char * vtt_basename
Definition: hlsenc.c:147
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:1495
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
static void hls_free_segments(HLSSegment *p)
Definition: hlsenc.c:1146
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5637
int master_m3u8_created
Definition: hlsenc.c:227
int init_range_length
Definition: hlsenc.c:120
static int append_postfix(char *name, int name_buf_len, int i)
Definition: hlsenc.c:1706
unsigned var_stream_idx
Definition: hlsenc.c:113
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4455
uint8_t * av_stream_get_side_data(const AVStream *stream, enum AVPacketSideDataType type, int *size)
Get side information from stream.
Definition: utils.c:5443
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1426
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition: bprint.c:158
int discont
Definition: hlsenc.c:75
double dpp
Definition: hlsenc.c:128
char * protocol_whitelist
&#39;,&#39; separated list of allowed protocols.
Definition: avformat.h:1918
static int get_nth_codec_stream_index(AVFormatContext *s, enum AVMediaType codec_type, int stream_id)
Definition: hlsenc.c:1810
#define AVERROR_EOF
End of file.
Definition: error.h:55
char * format_options_str
Definition: hlsenc.c:200
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
#define LINE_BUFFER_SIZE
Definition: hlsenc.c:67
int64_t start_pos
Definition: hlsenc.c:135
int has_subtitle
Definition: hlsenc.c:126
ptrdiff_t size
Definition: opengl_enc.c:100
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
char * key
Definition: hlsenc.c:206
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:218
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:129
#define av_log(a,...)
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:648
void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup, char *filename, char *language, int name_id, int is_default)
Definition: hlsplaylist.c:38
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3982
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
char * basename
Definition: hlsenc.c:146
int64_t sequence
Definition: hlsenc.c:115
int is_default
Definition: hlsenc.c:162
static const AVOption options[]
Definition: hlsenc.c:2898
#define ff_const59
The ff_const59 define is not part of the public API and will be removed without further warning...
Definition: avformat.h:549
char codec_attr[128]
Definition: hlsenc.c:158
int64_t end_pts
Definition: hlsenc.c:130
static int hls_write_header(AVFormatContext *s)
Definition: hlsenc.c:2106
int64_t size
Definition: hlsenc.c:136
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:260
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: utils.c:2013
#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:1598
char * master_pl_name
Definition: hlsenc.c:232
#define AV_BPRINT_SIZE_UNLIMITED
#define OFFSET(x)
Definition: hlsenc.c:2896
int nb_entries
Definition: hlsenc.c:137
struct HLSSegment * next
Definition: hlsenc.c:85
#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:1190
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
unsigned number
Definition: hlsenc.c:114
char * url
input or output URL.
Definition: avformat.h:1454
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
char sub_filename[1024]
Definition: hlsenc.c:73
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:203
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition: avcodec.h:565
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3949
AVDictionary * vtt_format_options
Definition: hlsenc.c:217
double duration
Definition: hlsenc.c:134
static int hls_delete_old_segments(AVFormatContext *s, HLSContext *hls, VariantStream *vs)
Definition: hlsenc.c:425
Definition: graph2dot.c:48
#define wrap(func)
Definition: neontest.h:65
simple assert() macros that are a bit more flexible than ISO C assert().
static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, VariantStream *vs, double duration, int64_t pos, int64_t size)
Definition: hlsenc.c:966
int avformat_alloc_output_context2(AVFormatContext **ctx, ff_const59 AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition: mux.c:148
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:82
static int hls_rename_temp_file(AVFormatContext *s, AVFormatContext *oc)
Definition: hlsenc.c:1157
int64_t recording_time
Definition: hlsenc.c:196
#define FFMAX(a, b)
Definition: common.h:94
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option keep it simple and lowercase description are in without period
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:120
static void write_styp(AVIOContext *pb)
Definition: hlsenc.c:392
int64_t pos
Definition: hlsenc.c:76
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
AVStream ** streams
Definition: hlsenc.c:157
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:1864
char * baseurl
Definition: hlsenc.c:199
static void set_http_options(AVFormatContext *s, AVDictionary **options, HLSContext *c)
Definition: hlsenc.c:280
int discontinuity
Definition: hlsenc.c:139
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:1414
StartSequenceSourceType
Definition: hlsenc.c:55
AVIOContext * out
Definition: hlsenc.c:118
static int sls_flag_check_duration_size_index(HLSContext *hls)
Definition: hlsenc.c:868
char key_string[KEYSIZE *2+1]
Definition: hlsenc.c:215
AVFormatContext * vtt_avf
Definition: hlsenc.c:123
#define HLS_MICROSECOND_UNIT
Definition: hlsenc.c:68
static int randomize(uint8_t *buf, int len)
Definition: hlsenc.c:568
#define b
Definition: input.c:41
int void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:238
int64_t max_seg_size
Definition: hlsenc.c:197
HLSSegment * last_segment
Definition: hlsenc.c:143
#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:508
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:236
int64_t keyframe_size
Definition: hlsenc.c:79
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:94
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:466
static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: hlsenc.c:2161
void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache, int target_duration, int64_t sequence, uint32_t playlist_type, int iframe_mode)
Definition: hlsplaylist.c:77
const char * name
Definition: avformat.h:505
AVFormatContext * ctx
Definition: movenc.c:48
int has_default_key
Definition: hlsenc.c:239
static int create_master_playlist(AVFormatContext *s, VariantStream *const input_vs)
Definition: hlsenc.c:1205
static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
Definition: hlsenc.c:703
unsigned var_stream_idx
Definition: hlsenc.c:80
#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:2897
#define s(width, name)
Definition: cbs_vp9.c:257
int encrypt_started
Definition: hlsenc.c:210
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition: dict.h:80
void ff_format_set_url(AVFormatContext *s, char *url)
Set AVFormatContext url field to the provided pointer.
Definition: utils.c:5797
ClosedCaptionsStream * cc_streams
Definition: hlsenc.c:224
AVDictionary * metadata
Definition: avformat.h:945
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:185
AVDictionary * format_options
Definition: hlsenc.c:203
int ff_get_line(AVIOContext *s, char *buf, int maxlen)
Read a whole line of text from AVIOContext.
Definition: aviobuf.c:809
static void sls_flag_file_rename(HLSContext *hls, VariantStream *vs, char *old_filename)
Definition: hlsenc.c:911
const AVClass * priv_class
AVClass for the private context.
Definition: avformat.h:533
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:488
int has_video_m3u8
Definition: hlsenc.c:240
int reference_stream_index
Definition: hlsenc.c:140
char * base_output_dirname
Definition: hlsenc.c:155
CodecAttributeStatus
Definition: hlsenc.c:61
ff_const59 struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1377
int use_localtime
flag to expand filename with localtime
Definition: hlsenc.c:193
Stream structure.
Definition: avformat.h:881
#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
int ignore_io_errors
Definition: hlsenc.c:238
char * key_url
Definition: hlsenc.c:207
void ff_hls_write_playlist_version(AVIOContext *out, int version)
Definition: hlsplaylist.c:31
This structure describes the bitrate properties of an encoded bitstream.
Definition: avcodec.h:1128
char iv_string[KEYSIZE *2+1]
Definition: hlsenc.c:83
int64_t start_sequence
Definition: hlsenc.c:177
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
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, int64_t video_keyframe_size, int64_t video_keyframe_pos, int iframe_mode)
Definition: hlsplaylist.c:109
AVIOContext * pb
I/O context.
Definition: avformat.h:1400
static int hls_encryption_start(AVFormatContext *s)
Definition: hlsenc.c:651
const struct AVCodecTag *const * codec_tag
List of supported codec_id-codec_tag pairs, ordered by "better choice first".
Definition: avformat.h:530
char * key_info_file
Definition: hlsenc.c:212
unsigned int nb_ccstreams
Definition: hlsenc.c:225
char * agroup
Definition: hlsenc.c:164
char * method
Definition: hlsenc.c:219
char * fmp4_init_filename
Definition: hlsenc.c:190
void(* io_close)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1946
void * buf
Definition: avisynth_c.h:766
Definition: url.h:38
int allowcache
Definition: hlsenc.c:195
int segment_type
Definition: hlsenc.c:191
HLSFlags
Definition: hlsenc.c:88
static int ff_rename(const char *oldpath, const char *newpath, void *logctx)
Wrap errno on rename() error.
Definition: internal.h:591
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 int64_t get_stream_bit_rate(AVStream *stream)
Definition: hlsenc.c:1190
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
static int validate_name(int nb_vs, const char *fn)
Definition: hlsenc.c:1725
Describe the class of an AVClass context structure.
Definition: log.h:67
int index
Definition: gxfenc.c:89
ff_const59 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:51
static int hlsenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, AVDictionary **options)
Definition: hlsenc.c:243
int encrypt
Definition: hlsenc.c:205
AVFormatContext * avf
Definition: hlsenc.c:122
char iv_string[KEYSIZE *2+1]
Definition: hlsenc.c:216
AVMediaType
Definition: avutil.h:199
static int flush_dynbuf(VariantStream *vs, int *range_length)
Definition: hlsenc.c:402
#define snprintf
Definition: snprintf.h:34
char * m3u8_name
Definition: hlsenc.c:149
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4389
static int hls_init(AVFormatContext *s)
Definition: hlsenc.c:2547
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:1159
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:166
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:1039
#define flags(name, subs,...)
Definition: cbs_av1.c:561
char key_file[LINE_BUFFER_SIZE+1]
Definition: hlsenc.c:213
int has_video
Definition: hlsenc.c:125
static HLSSegment * find_segment_by_filename(HLSSegment *segment, const char *filename)
Definition: hlsenc.c:815
static const char * get_default_pattern_localtime_fmt(AVFormatContext *s)
Definition: hlsenc.c:1690
void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, int bandwidth, char *filename, char *agroup, char *codecs, char *ccgroup)
Definition: hlsplaylist.c:51
int ff_http_do_new_request(URLContext *h, const char *uri)
Send a new HTTP request, reusing the old connection.
Definition: http.c:308
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
static void write_codec_attr(AVStream *st, VariantStream *vs)
Definition: hlsenc.c:298
SegmentType
Definition: hlsenc.c:107
uint32_t pl_type
Definition: hlsenc.c:188
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
char * cc_stream_map
Definition: hlsenc.c:231
Main libavformat public API header.
static int parse_playlist(AVFormatContext *s, const char *url, VariantStream *vs)
Definition: hlsenc.c:1056
char * av_append_path_component(const char *path, const char *component)
Append path component to the existing path.
Definition: avstring.c:296
char * language
Definition: hlsenc.c:163
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
unsigned int nb_varstreams
Definition: hlsenc.c:223
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:275
void ff_hls_write_init_file(AVIOContext *out, char *filename, int byterange_mode, int64_t size, int64_t pos)
Definition: hlsplaylist.c:100
int64_t video_lastpos
Definition: hlsenc.c:131
uint32_t flags
Definition: hlsenc.c:187
int pts_wrap_bits
number of bits in pts (used for wrapping control)
Definition: avformat.h:1073
#define localtime_r
Definition: time_internal.h:46
int den
Denominator.
Definition: rational.h:60
int64_t video_keyframe_pos
Definition: hlsenc.c:132
#define KEYSIZE
Definition: hlsenc.c:66
int http_persistent
Definition: hls.c:208
static int sls_flag_check_duration_size(HLSContext *hls, VariantStream *vs)
Definition: hlsenc.c:891
char * segment_filename
Definition: hlsenc.c:189
#define av_free(p)
int len
uint32_t start_sequence_source_type
Definition: hlsenc.c:178
char filename[1024]
Definition: hlsenc.c:72
void * priv_data
Format private data.
Definition: avformat.h:1386
This side data corresponds to the AVCPBProperties struct.
Definition: avcodec.h:1289
char * subtitle_filename
Definition: hlsenc.c:202
#define AVFMT_NODIMENSIONS
Format does not need width/height.
Definition: avformat.h:471
ff_const59 AVOutputFormat * vtt_oformat
Definition: hlsenc.c:117
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:1172
int version
Definition: hlsenc.c:229
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:337
#define lrint
Definition: tablegen.h:53
char * var_stream_map
Definition: hlsenc.c:230
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: avcodec.h:3967
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:825
AVOutputFormat ff_hls_muxer
Definition: hlsenc.c:2974
void ff_hls_write_end_list(AVIOContext *out)
Definition: hlsplaylist.c:164
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1247
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:377
char * protocol_blacklist
&#39;,&#39; separated list of disallowed protocols.
Definition: avformat.h:1953
ff_const59 AVOutputFormat * oformat
Definition: hlsenc.c:116
unsigned int master_publish_rate
Definition: hlsenc.c:233
FILE * out
Definition: movenc.c:54
#define av_freep(p)
HLSSegment * segments
Definition: hlsenc.c:142
int64_t video_keyframe_size
Definition: hlsenc.c:133
static int format_name(char *buf, int buf_len, int index)
Definition: hlsenc.c:1764
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:60
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1028
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:358
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3957
int stream_index
Definition: avcodec.h:1479
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:910
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
int new_start
Definition: hlsenc.c:127
static const AVClass hls_class
Definition: hlsenc.c:2966
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:151
int ff_get_chomp_line(AVIOContext *s, char *buf, int maxlen)
Same as ff_get_line but strip the white-space characters in the text tail.
Definition: aviobuf.c:826
char * ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase)
Definition: utils.c:4833
This structure stores compressed data.
Definition: avcodec.h:1454
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:1828
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1470
int hls_delete_threshold
Definition: hlsenc.c:183
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
GLuint buffer
Definition: opengl_enc.c:101
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
const char * name
Definition: opengl_enc.c:102
static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c, VariantStream *vs)
Definition: hlsenc.c:918
static int parse_cc_stream_mapstring(AVFormatContext *s)
Definition: hlsenc.c:1942