FFmpeg
dashenc.c
Go to the documentation of this file.
1 /*
2  * MPEG-DASH ISO BMFF segmenter
3  * Copyright (c) 2014 Martin Storsjo
4  * Copyright (c) 2018 Akamai Technologies, Inc.
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "config.h"
24 #include "config_components.h"
25 #include <time.h>
26 #if HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 
30 #include "libavutil/avassert.h"
31 #include "libavutil/avutil.h"
32 #include "libavutil/avstring.h"
33 #include "libavutil/bprint.h"
34 #include "libavutil/intreadwrite.h"
35 #include "libavutil/mathematics.h"
36 #include "libavutil/mem.h"
37 #include "libavutil/opt.h"
38 #include "libavutil/parseutils.h"
39 #include "libavutil/rational.h"
40 #include "libavutil/time.h"
42 
43 #include "libavcodec/avcodec.h"
44 
45 #include "av1.h"
46 #include "avc.h"
47 #include "avformat.h"
48 #include "avio_internal.h"
49 #include "hlsplaylist.h"
50 #if CONFIG_HTTP_PROTOCOL
51 #include "http.h"
52 #endif
53 #include "internal.h"
54 #include "isom.h"
55 #include "mux.h"
56 #include "os_support.h"
57 #include "url.h"
58 #include "vpcc.h"
59 #include "dash.h"
60 
61 typedef enum {
66 } SegmentType;
67 
68 enum {
74 };
75 
76 #define MPD_PROFILE_DASH 1
77 #define MPD_PROFILE_DVB 2
78 
79 typedef struct Segment {
80  char file[1024];
81  int64_t start_pos;
83  int64_t time;
85  int64_t duration;
86  int n;
87 } Segment;
88 
89 typedef struct AdaptationSet {
90  int id;
91  char *descriptor;
92  int64_t seg_duration;
93  int64_t frag_duration;
94  int frag_type;
104 } AdaptationSet;
105 
106 typedef struct OutputStream {
113  char initfile[1024];
114  int64_t init_start_pos, pos;
117  int64_t seg_duration;
118  int64_t frag_duration;
119  int64_t last_duration;
122  int64_t last_dts, last_pts;
124  int bit_rate;
126  SegmentType segment_type; /* segment type selected for this particular stream */
127  const char *format_name;
128  const char *extension_name;
129  const char *single_file_name; /* file names selected for this particular stream */
130  const char *init_seg_name;
131  const char *media_seg_name;
132 
133  char codec_str[100];
135  char filename[1024];
136  char full_path[1024];
137  char temp_path[1024];
145  int64_t gop_size;
148 } OutputStream;
149 
150 typedef struct DASHContext {
151  const AVClass *class; /* Class for private options. */
154  int nb_as;
157  int64_t seg_duration;
158  int64_t frag_duration;
165  int64_t last_duration;
166  int64_t total_duration;
168  time_t start_time_s;
170  char dirname[1024];
171  const char *single_file_name; /* file names as specified in options */
172  const char *init_seg_name;
173  const char *media_seg_name;
174  const char *utc_timing_url;
175  const char *method;
176  const char *user_agent;
179  const char *hls_master_name;
186  int64_t timeout;
190  SegmentType segment_type_option; /* segment type as specified in options */
192  int lhls;
193  int ldash;
199  int64_t max_gop_size;
201  int profile;
202  int64_t target_latency;
206  int64_t update_period;
207 } DASHContext;
208 
209 static const struct codec_string {
210  enum AVCodecID id;
211  const char str[8];
212 } codecs[] = {
213  { AV_CODEC_ID_VP8, "vp8" },
214  { AV_CODEC_ID_VP9, "vp9" },
215  { AV_CODEC_ID_VORBIS, "vorbis" },
216  { AV_CODEC_ID_OPUS, "opus" },
217  { AV_CODEC_ID_FLAC, "flac" },
218  { AV_CODEC_ID_NONE }
219 };
220 
221 static int dashenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename,
222  AVDictionary **options) {
223  DASHContext *c = s->priv_data;
224  int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
225  int err = AVERROR_MUXER_NOT_FOUND;
226  if (!*pb || !http_base_proto || !c->http_persistent) {
227  err = s->io_open(s, pb, filename, AVIO_FLAG_WRITE, options);
228 #if CONFIG_HTTP_PROTOCOL
229  } else {
230  URLContext *http_url_context = ffio_geturlcontext(*pb);
231  av_assert0(http_url_context);
232  err = ff_http_do_new_request(http_url_context, filename);
233  if (err < 0)
234  ff_format_io_close(s, pb);
235 #endif
236  }
237  return err;
238 }
239 
240 static void dashenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename) {
241  DASHContext *c = s->priv_data;
242  int http_base_proto = filename ? ff_is_http_proto(filename) : 0;
243 
244  if (!*pb)
245  return;
246 
247  if (!http_base_proto || !c->http_persistent) {
248  ff_format_io_close(s, pb);
249 #if CONFIG_HTTP_PROTOCOL
250  } else {
251  URLContext *http_url_context = ffio_geturlcontext(*pb);
252  av_assert0(http_url_context);
253  avio_flush(*pb);
254  ffurl_shutdown(http_url_context, AVIO_FLAG_WRITE);
255 #endif
256  }
257 }
258 
259 static const char *get_format_str(SegmentType segment_type)
260 {
261  switch (segment_type) {
262  case SEGMENT_TYPE_MP4: return "mp4";
263  case SEGMENT_TYPE_WEBM: return "webm";
264  }
265  return NULL;
266 }
267 
268 static const char *get_extension_str(SegmentType type, int single_file)
269 {
270  switch (type) {
271 
272  case SEGMENT_TYPE_MP4: return single_file ? "mp4" : "m4s";
273  case SEGMENT_TYPE_WEBM: return "webm";
274  default: return NULL;
275  }
276 }
277 
278 static int handle_io_open_error(AVFormatContext *s, int err, char *url) {
279  DASHContext *c = s->priv_data;
280  char errbuf[AV_ERROR_MAX_STRING_SIZE];
281  av_strerror(err, errbuf, sizeof(errbuf));
282  av_log(s, c->ignore_io_errors ? AV_LOG_WARNING : AV_LOG_ERROR,
283  "Unable to open %s for writing: %s\n", url, errbuf);
284  return c->ignore_io_errors ? 0 : err;
285 }
286 
288 {
289  if (segment_type == SEGMENT_TYPE_AUTO) {
292  segment_type = SEGMENT_TYPE_WEBM;
293  } else {
294  segment_type = SEGMENT_TYPE_MP4;
295  }
296  }
297 
298  return segment_type;
299 }
300 
302 {
303  DASHContext *c = s->priv_data;
304  int has_mp4_streams = 0;
305  for (int i = 0; i < s->nb_streams; ++i) {
306  OutputStream *os = &c->streams[i];
307  SegmentType segment_type = select_segment_type(
308  c->segment_type_option, s->streams[i]->codecpar->codec_id);
309  os->segment_type = segment_type;
310  os->format_name = get_format_str(segment_type);
311  if (!os->format_name) {
312  av_log(s, AV_LOG_ERROR, "Could not select DASH segment type for stream %d\n", i);
314  }
315  os->extension_name = get_extension_str(segment_type, c->single_file);
316  if (!os->extension_name) {
317  av_log(s, AV_LOG_ERROR, "Could not get extension type for stream %d\n", i);
319  }
320 
321  has_mp4_streams |= segment_type == SEGMENT_TYPE_MP4;
322  }
323 
324  if (c->hls_playlist && !has_mp4_streams) {
325  av_log(s, AV_LOG_WARNING, "No mp4 streams, disabling HLS manifest generation\n");
326  c->hls_playlist = 0;
327  }
328 
329  return 0;
330 }
331 
333  AVRational *frame_rate, char *str, int size) {
334  VPCC vpcc;
335  int ret = ff_isom_get_vpcc_features(s, par, NULL, 0, frame_rate, &vpcc);
336  if (ret == 0) {
337  av_strlcatf(str, size, "vp09.%02d.%02d.%02d",
338  vpcc.profile, vpcc.level, vpcc.bitdepth);
339  } else {
340  // Default to just vp9 in case of error while finding out profile or level
341  av_log(s, AV_LOG_WARNING, "Could not find VP9 profile and/or level\n");
342  av_strlcpy(str, "vp9", size);
343  }
344  return;
345 }
346 
348  AVRational *frame_rate, char *str, int size)
349 {
350  const AVCodecTag *tags[2] = { NULL, NULL };
351  uint32_t tag;
352  int i;
353 
354  // common Webm codecs are not part of RFC 6381
355  for (i = 0; codecs[i].id != AV_CODEC_ID_NONE; i++)
356  if (codecs[i].id == par->codec_id) {
357  if (codecs[i].id == AV_CODEC_ID_VP9) {
358  set_vp9_codec_str(s, par, frame_rate, str, size);
359  } else {
360  av_strlcpy(str, codecs[i].str, size);
361  }
362  return;
363  }
364 
365  // for codecs part of RFC 6381
366  if (par->codec_type == AVMEDIA_TYPE_VIDEO)
367  tags[0] = ff_codec_movvideo_tags;
368  else if (par->codec_type == AVMEDIA_TYPE_AUDIO)
369  tags[0] = ff_codec_movaudio_tags;
370  else
371  return;
372 
373  tag = par->codec_tag;
374  if (!tag)
375  tag = av_codec_get_tag(tags, par->codec_id);
376  if (!tag)
377  return;
378  if (size < 5)
379  return;
380 
381  AV_WL32(str, tag);
382  str[4] = '\0';
383  if (!strcmp(str, "mp4a") || !strcmp(str, "mp4v")) {
384  uint32_t oti;
385  tags[0] = ff_mp4_obj_type;
386  oti = av_codec_get_tag(tags, par->codec_id);
387  if (oti)
388  av_strlcatf(str, size, ".%02"PRIx32, oti);
389  else
390  return;
391 
392  if (tag == MKTAG('m', 'p', '4', 'a')) {
393  if (par->extradata_size >= 2) {
394  int aot = par->extradata[0] >> 3;
395  if (aot == 31)
396  aot = ((AV_RB16(par->extradata) >> 5) & 0x3f) + 32;
397  av_strlcatf(str, size, ".%d", aot);
398  }
399  } else if (tag == MKTAG('m', 'p', '4', 'v')) {
400  // Unimplemented, should output ProfileLevelIndication as a decimal number
401  av_log(s, AV_LOG_WARNING, "Incomplete RFC 6381 codec string for mp4v\n");
402  }
403  } else if (!strcmp(str, "avc1")) {
404  uint8_t *tmpbuf = NULL;
405  uint8_t *extradata = par->extradata;
406  int extradata_size = par->extradata_size;
407  if (!extradata_size)
408  return;
409  if (extradata[0] != 1) {
410  AVIOContext *pb;
411  if (avio_open_dyn_buf(&pb) < 0)
412  return;
413  if (ff_isom_write_avcc(pb, extradata, extradata_size) < 0) {
414  ffio_free_dyn_buf(&pb);
415  return;
416  }
417  extradata_size = avio_close_dyn_buf(pb, &extradata);
418  tmpbuf = extradata;
419  }
420 
421  if (extradata_size >= 4)
422  av_strlcatf(str, size, ".%02x%02x%02x",
423  extradata[1], extradata[2], extradata[3]);
424  av_free(tmpbuf);
425  } else if (!strcmp(str, "av01")) {
427  if (!par->extradata_size)
428  return;
429  if (ff_av1_parse_seq_header(&seq, par->extradata, par->extradata_size) < 0)
430  return;
431 
432  av_strlcatf(str, size, ".%01u.%02u%s.%02u",
433  seq.profile, seq.level, seq.tier ? "H" : "M", seq.bitdepth);
435  av_strlcatf(str, size, ".%01u.%01u%01u%01u.%02u.%02u.%02u.%01u",
436  seq.monochrome,
439  seq.color_range);
440  }
441 }
442 
443 static int flush_dynbuf(DASHContext *c, OutputStream *os, int *range_length)
444 {
445  uint8_t *buffer;
446 
447  if (!os->ctx->pb) {
448  return AVERROR(EINVAL);
449  }
450 
451  // flush
452  av_write_frame(os->ctx, NULL);
453  avio_flush(os->ctx->pb);
454 
455  if (!c->single_file) {
456  // write out to file
457  *range_length = avio_close_dyn_buf(os->ctx->pb, &buffer);
458  os->ctx->pb = NULL;
459  if (os->out)
460  avio_write(os->out, buffer + os->written_len, *range_length - os->written_len);
461  os->written_len = 0;
462  av_free(buffer);
463 
464  // re-open buffer
465  return avio_open_dyn_buf(&os->ctx->pb);
466  } else {
467  *range_length = avio_tell(os->ctx->pb) - os->pos;
468  return 0;
469  }
470 }
471 
473 {
474  if (c->method)
475  av_dict_set(options, "method", c->method, 0);
476  av_dict_copy(options, c->http_opts, 0);
477  if (c->user_agent)
478  av_dict_set(options, "user_agent", c->user_agent, 0);
479  if (c->http_persistent)
480  av_dict_set_int(options, "multiple_requests", 1, 0);
481  if (c->timeout >= 0)
482  av_dict_set_int(options, "timeout", c->timeout, 0);
483 }
484 
485 static void get_hls_playlist_name(char *playlist_name, int string_size,
486  const char *base_url, int id) {
487  if (base_url)
488  snprintf(playlist_name, string_size, "%smedia_%d.m3u8", base_url, id);
489  else
490  snprintf(playlist_name, string_size, "media_%d.m3u8", id);
491 }
492 
494  int *start_index, int *start_number) {
495  *start_index = 0;
496  *start_number = 1;
497  if (c->window_size) {
498  *start_index = FFMAX(os->nb_segments - c->window_size, 0);
499  *start_number = FFMAX(os->segment_index - c->window_size, 1);
500  }
501 }
502 
504  int representation_id, int final,
505  char *prefetch_url) {
506  DASHContext *c = s->priv_data;
507  int timescale = os->ctx->streams[0]->time_base.den;
508  char temp_filename_hls[1024];
509  char filename_hls[1024];
510  AVDictionary *http_opts = NULL;
511  int target_duration = 0;
512  int ret = 0;
513  const char *proto = avio_find_protocol_name(c->dirname);
514  int use_rename = proto && !strcmp(proto, "file");
515  int i, start_index, start_number;
516  double prog_date_time = 0;
517 
518  get_start_index_number(os, c, &start_index, &start_number);
519 
520  if (!c->hls_playlist || start_index >= os->nb_segments ||
522  return;
523 
524  get_hls_playlist_name(filename_hls, sizeof(filename_hls),
525  c->dirname, representation_id);
526 
527  snprintf(temp_filename_hls, sizeof(temp_filename_hls), use_rename ? "%s.tmp" : "%s", filename_hls);
528 
529  set_http_options(&http_opts, c);
530  ret = dashenc_io_open(s, &c->m3u8_out, temp_filename_hls, &http_opts);
531  av_dict_free(&http_opts);
532  if (ret < 0) {
533  handle_io_open_error(s, ret, temp_filename_hls);
534  return;
535  }
536  for (i = start_index; i < os->nb_segments; i++) {
537  Segment *seg = os->segments[i];
538  double duration = (double) seg->duration / timescale;
539  if (target_duration <= duration)
540  target_duration = lrint(duration);
541  }
542 
543  ff_hls_write_playlist_header(c->m3u8_out, 6, -1, target_duration,
544  start_number, PLAYLIST_TYPE_NONE, 0);
545 
546  ff_hls_write_init_file(c->m3u8_out, os->initfile, c->single_file,
548 
549  for (i = start_index; i < os->nb_segments; i++) {
550  Segment *seg = os->segments[i];
551 
552  if (fabs(prog_date_time) < 1e-7) {
553  if (os->nb_segments == 1)
554  prog_date_time = c->start_time_s;
555  else
556  prog_date_time = seg->prog_date_time;
557  }
558  seg->prog_date_time = prog_date_time;
559 
560  ret = ff_hls_write_file_entry(c->m3u8_out, 0, c->single_file,
561  (double) seg->duration / timescale, 0,
562  seg->range_length, seg->start_pos, NULL,
563  c->single_file ? os->initfile : seg->file,
564  &prog_date_time, 0, 0, 0);
565  if (ret < 0) {
566  av_log(os->ctx, AV_LOG_WARNING, "ff_hls_write_file_entry get error\n");
567  }
568  }
569 
570  if (prefetch_url)
571  avio_printf(c->m3u8_out, "#EXT-X-PREFETCH:%s\n", prefetch_url);
572 
573  if (final)
574  ff_hls_write_end_list(c->m3u8_out);
575 
576  dashenc_io_close(s, &c->m3u8_out, temp_filename_hls);
577 
578  if (use_rename)
579  ff_rename(temp_filename_hls, filename_hls, os->ctx);
580 }
581 
583 {
584  DASHContext *c = s->priv_data;
585  int ret, range_length;
586 
587  ret = flush_dynbuf(c, os, &range_length);
588  if (ret < 0)
589  return ret;
590 
591  os->pos = os->init_range_length = range_length;
592  if (!c->single_file) {
593  char filename[1024];
594  snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->initfile);
595  dashenc_io_close(s, &os->out, filename);
596  }
597  return 0;
598 }
599 
601 {
602  DASHContext *c = s->priv_data;
603  int i, j;
604 
605  if (c->as) {
606  for (i = 0; i < c->nb_as; i++) {
607  av_dict_free(&c->as[i].metadata);
608  av_freep(&c->as[i].descriptor);
609  }
610  av_freep(&c->as);
611  c->nb_as = 0;
612  }
613 
614  if (!c->streams)
615  return;
616  for (i = 0; i < s->nb_streams; i++) {
617  OutputStream *os = &c->streams[i];
618  if (os->ctx && os->ctx->pb) {
619  if (!c->single_file)
620  ffio_free_dyn_buf(&os->ctx->pb);
621  else
622  avio_close(os->ctx->pb);
623  }
624  ff_format_io_close(s, &os->out);
627  av_parser_close(os->parser);
628  for (j = 0; j < os->nb_segments; j++)
629  av_free(os->segments[j]);
630  av_free(os->segments);
632  av_freep(&os->init_seg_name);
633  av_freep(&os->media_seg_name);
634  }
635  av_freep(&c->streams);
636 
637  ff_format_io_close(s, &c->mpd_out);
638  ff_format_io_close(s, &c->m3u8_out);
639  ff_format_io_close(s, &c->http_delete);
640 }
641 
643  int representation_id, int final)
644 {
645  DASHContext *c = s->priv_data;
646  int i, start_index, start_number;
647  get_start_index_number(os, c, &start_index, &start_number);
648 
649  if (c->use_template) {
650  int timescale = c->use_timeline ? os->ctx->streams[0]->time_base.den : AV_TIME_BASE;
651  avio_printf(out, "\t\t\t\t<SegmentTemplate timescale=\"%d\" ", timescale);
652  if (!c->use_timeline) {
653  avio_printf(out, "duration=\"%"PRId64"\" ", os->seg_duration);
654  if (c->streaming && os->availability_time_offset)
655  avio_printf(out, "availabilityTimeOffset=\"%.3f\" ",
657  }
658  if (c->streaming && os->availability_time_offset && !final)
659  avio_printf(out, "availabilityTimeComplete=\"false\" ");
660 
661  avio_printf(out, "initialization=\"%s\" media=\"%s\" startNumber=\"%d\"", os->init_seg_name, os->media_seg_name, c->use_timeline ? start_number : 1);
662  if (c->presentation_time_offset)
663  avio_printf(out, " presentationTimeOffset=\"%"PRId64"\"", c->presentation_time_offset);
664  avio_printf(out, ">\n");
665  if (c->use_timeline) {
666  int64_t cur_time = 0;
667  avio_printf(out, "\t\t\t\t\t<SegmentTimeline>\n");
668  for (i = start_index; i < os->nb_segments; ) {
669  Segment *seg = os->segments[i];
670  int repeat = 0;
671  avio_printf(out, "\t\t\t\t\t\t<S ");
672  if (i == start_index || seg->time != cur_time) {
673  cur_time = seg->time;
674  avio_printf(out, "t=\"%"PRId64"\" ", seg->time);
675  }
676  avio_printf(out, "d=\"%"PRId64"\" ", seg->duration);
677  while (i + repeat + 1 < os->nb_segments &&
678  os->segments[i + repeat + 1]->duration == seg->duration &&
679  os->segments[i + repeat + 1]->time == os->segments[i + repeat]->time + os->segments[i + repeat]->duration)
680  repeat++;
681  if (repeat > 0)
682  avio_printf(out, "r=\"%d\" ", repeat);
683  avio_printf(out, "/>\n");
684  i += 1 + repeat;
685  cur_time += (1 + repeat) * seg->duration;
686  }
687  avio_printf(out, "\t\t\t\t\t</SegmentTimeline>\n");
688  }
689  avio_printf(out, "\t\t\t\t</SegmentTemplate>\n");
690  } else if (c->single_file) {
691  avio_printf(out, "\t\t\t\t<BaseURL>%s</BaseURL>\n", os->initfile);
692  avio_printf(out, "\t\t\t\t<SegmentList timescale=\"%d\" duration=\"%"PRId64"\" startNumber=\"%d\">\n", AV_TIME_BASE, FFMIN(os->seg_duration, os->last_duration), start_number);
693  avio_printf(out, "\t\t\t\t\t<Initialization range=\"%"PRId64"-%"PRId64"\" />\n", os->init_start_pos, os->init_start_pos + os->init_range_length - 1);
694  for (i = start_index; i < os->nb_segments; i++) {
695  Segment *seg = os->segments[i];
696  avio_printf(out, "\t\t\t\t\t<SegmentURL mediaRange=\"%"PRId64"-%"PRId64"\" ", seg->start_pos, seg->start_pos + seg->range_length - 1);
697  if (seg->index_length)
698  avio_printf(out, "indexRange=\"%"PRId64"-%"PRId64"\" ", seg->start_pos, seg->start_pos + seg->index_length - 1);
699  avio_printf(out, "/>\n");
700  }
701  avio_printf(out, "\t\t\t\t</SegmentList>\n");
702  } else {
703  avio_printf(out, "\t\t\t\t<SegmentList timescale=\"%d\" duration=\"%"PRId64"\" startNumber=\"%d\">\n", AV_TIME_BASE, FFMIN(os->seg_duration, os->last_duration), start_number);
704  avio_printf(out, "\t\t\t\t\t<Initialization sourceURL=\"%s\" />\n", os->initfile);
705  for (i = start_index; i < os->nb_segments; i++) {
706  Segment *seg = os->segments[i];
707  avio_printf(out, "\t\t\t\t\t<SegmentURL media=\"%s\" />\n", seg->file);
708  }
709  avio_printf(out, "\t\t\t\t</SegmentList>\n");
710  }
711  if (!c->lhls || final) {
712  write_hls_media_playlist(os, s, representation_id, final, NULL);
713  }
714 
715 }
716 
717 static char *xmlescape(const char *str) {
718  int outlen = strlen(str)*3/2 + 6;
719  char *out = av_realloc(NULL, outlen + 1);
720  int pos = 0;
721  if (!out)
722  return NULL;
723  for (; *str; str++) {
724  if (pos + 6 > outlen) {
725  char *tmp;
726  outlen = 2 * outlen + 6;
727  tmp = av_realloc(out, outlen + 1);
728  if (!tmp) {
729  av_free(out);
730  return NULL;
731  }
732  out = tmp;
733  }
734  if (*str == '&') {
735  memcpy(&out[pos], "&amp;", 5);
736  pos += 5;
737  } else if (*str == '<') {
738  memcpy(&out[pos], "&lt;", 4);
739  pos += 4;
740  } else if (*str == '>') {
741  memcpy(&out[pos], "&gt;", 4);
742  pos += 4;
743  } else if (*str == '\'') {
744  memcpy(&out[pos], "&apos;", 6);
745  pos += 6;
746  } else if (*str == '\"') {
747  memcpy(&out[pos], "&quot;", 6);
748  pos += 6;
749  } else {
750  out[pos++] = *str;
751  }
752  }
753  out[pos] = '\0';
754  return out;
755 }
756 
757 static void write_time(AVIOContext *out, int64_t time)
758 {
759  int seconds = time / AV_TIME_BASE;
760  int fractions = time % AV_TIME_BASE;
761  int minutes = seconds / 60;
762  int hours = minutes / 60;
763  seconds %= 60;
764  minutes %= 60;
765  avio_printf(out, "PT");
766  if (hours)
767  avio_printf(out, "%dH", hours);
768  if (hours || minutes)
769  avio_printf(out, "%dM", minutes);
770  avio_printf(out, "%d.%dS", seconds, fractions / (AV_TIME_BASE / 10));
771 }
772 
773 static void format_date(char *buf, int size, int64_t time_us)
774 {
775  struct tm *ptm, tmbuf;
776  int64_t time_ms = time_us / 1000;
777  const time_t time_s = time_ms / 1000;
778  int millisec = time_ms - (time_s * 1000);
779  ptm = gmtime_r(&time_s, &tmbuf);
780  if (ptm) {
781  int len;
782  if (!strftime(buf, size, "%Y-%m-%dT%H:%M:%S", ptm)) {
783  buf[0] = '\0';
784  return;
785  }
786  len = strlen(buf);
787  snprintf(buf + len, size - len, ".%03dZ", millisec);
788  }
789 }
790 
792  int final)
793 {
794  DASHContext *c = s->priv_data;
795  AdaptationSet *as = &c->as[as_index];
796  AVDictionaryEntry *lang, *role;
797  int i;
798 
799  avio_printf(out, "\t\t<AdaptationSet id=\"%d\" contentType=\"%s\" startWithSAP=\"1\" segmentAlignment=\"true\" bitstreamSwitching=\"true\"",
800  as->id, as->media_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
802  avio_printf(out, " maxFrameRate=\"%d/%d\"", as->max_frame_rate.num, as->max_frame_rate.den);
804  avio_printf(out, " frameRate=\"%d/%d\"", as->max_frame_rate.num, as->max_frame_rate.den);
805  if (as->media_type == AVMEDIA_TYPE_VIDEO) {
806  avio_printf(out, " maxWidth=\"%d\" maxHeight=\"%d\"", as->max_width, as->max_height);
807  avio_printf(out, " par=\"%d:%d\"", as->par.num, as->par.den);
808  }
809  lang = av_dict_get(as->metadata, "language", NULL, 0);
810  if (lang)
811  avio_printf(out, " lang=\"%s\"", lang->value);
812  avio_printf(out, ">\n");
813 
814  if (!final && c->ldash && as->max_frag_duration && !(c->profile & MPD_PROFILE_DVB))
815  avio_printf(out, "\t\t\t<Resync dT=\"%"PRId64"\" type=\"0\"/>\n", as->max_frag_duration);
816  if (as->trick_idx >= 0)
817  avio_printf(out, "\t\t\t<EssentialProperty id=\"%d\" schemeIdUri=\"http://dashif.org/guidelines/trickmode\" value=\"%d\"/>\n", as->id, as->trick_idx);
818  role = av_dict_get(as->metadata, "role", NULL, 0);
819  if (role)
820  avio_printf(out, "\t\t\t<Role schemeIdUri=\"urn:mpeg:dash:role:2011\" value=\"%s\"/>\n", role->value);
821  if (as->descriptor)
822  avio_printf(out, "\t\t\t%s\n", as->descriptor);
823  for (i = 0; i < s->nb_streams; i++) {
824  AVStream *st = s->streams[i];
825  OutputStream *os = &c->streams[i];
826  char bandwidth_str[64] = {'\0'};
827 
828  if (os->as_idx - 1 != as_index)
829  continue;
830 
831  if (os->bit_rate > 0)
832  snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->bit_rate);
833  else if (final) {
834  int average_bit_rate = os->pos * 8 * AV_TIME_BASE / c->total_duration;
835  snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", average_bit_rate);
836  } else if (os->first_segment_bit_rate > 0)
837  snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->first_segment_bit_rate);
838 
839  if (as->media_type == AVMEDIA_TYPE_VIDEO) {
840  avio_printf(out, "\t\t\t<Representation id=\"%d\" mimeType=\"video/%s\" codecs=\"%s\"%s width=\"%d\" height=\"%d\"",
841  i, os->format_name, os->codec_str, bandwidth_str, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height);
843  avio_printf(out, " scanType=\"unknown\"");
844  else if (st->codecpar->field_order != AV_FIELD_PROGRESSIVE)
845  avio_printf(out, " scanType=\"interlaced\"");
846  avio_printf(out, " sar=\"%d:%d\"", os->sar.num, os->sar.den);
847  if (st->avg_frame_rate.num && av_cmp_q(as->min_frame_rate, as->max_frame_rate) < 0)
848  avio_printf(out, " frameRate=\"%d/%d\"", st->avg_frame_rate.num, st->avg_frame_rate.den);
849  if (as->trick_idx >= 0) {
850  AdaptationSet *tas = &c->as[as->trick_idx];
851  if (!as->ambiguous_frame_rate && !tas->ambiguous_frame_rate)
852  avio_printf(out, " maxPlayoutRate=\"%d\"", FFMAX((int)av_q2d(av_div_q(tas->min_frame_rate, as->min_frame_rate)), 1));
853  }
854  if (!os->coding_dependency)
855  avio_printf(out, " codingDependency=\"false\"");
856  avio_printf(out, ">\n");
857  } else {
858  avio_printf(out, "\t\t\t<Representation id=\"%d\" mimeType=\"audio/%s\" codecs=\"%s\"%s audioSamplingRate=\"%d\">\n",
859  i, os->format_name, os->codec_str, bandwidth_str, s->streams[i]->codecpar->sample_rate);
860  avio_printf(out, "\t\t\t\t<AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"%d\" />\n",
861  s->streams[i]->codecpar->ch_layout.nb_channels);
862  }
863  if (!final && c->write_prft && os->producer_reference_time_str[0]) {
864  avio_printf(out, "\t\t\t\t<ProducerReferenceTime id=\"%d\" inband=\"true\" type=\"%s\" wallClockTime=\"%s\" presentationTime=\"%"PRId64"\">\n",
865  i, os->producer_reference_time.flags ? "captured" : "encoder", os->producer_reference_time_str, c->presentation_time_offset);
866  avio_printf(out, "\t\t\t\t\t<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:http-xsdate:2014\" value=\"%s\"/>\n", c->utc_timing_url);
867  avio_printf(out, "\t\t\t\t</ProducerReferenceTime>\n");
868  }
869  if (!final && c->ldash && os->gop_size && os->frag_type != FRAG_TYPE_NONE && !(c->profile & MPD_PROFILE_DVB) &&
871  avio_printf(out, "\t\t\t\t<Resync dT=\"%"PRId64"\" type=\"1\"/>\n", os->gop_size);
872  output_segment_list(os, out, s, i, final);
873  avio_printf(out, "\t\t\t</Representation>\n");
874  }
875  avio_printf(out, "\t\t</AdaptationSet>\n");
876 
877  return 0;
878 }
879 
881 {
882  DASHContext *c = s->priv_data;
883  void *mem;
884 
885  if (c->profile & MPD_PROFILE_DVB && (c->nb_as + 1) > 16) {
886  av_log(s, AV_LOG_ERROR, "DVB-DASH profile allows a max of 16 Adaptation Sets\n");
887  return AVERROR(EINVAL);
888  }
889  mem = av_realloc(c->as, sizeof(*c->as) * (c->nb_as + 1));
890  if (!mem)
891  return AVERROR(ENOMEM);
892  c->as = mem;
893  ++c->nb_as;
894 
895  *as = &c->as[c->nb_as - 1];
896  memset(*as, 0, sizeof(**as));
897  (*as)->media_type = type;
898  (*as)->frag_type = -1;
899  (*as)->trick_idx = -1;
900 
901  return 0;
902 }
903 
904 static int adaptation_set_add_stream(AVFormatContext *s, int as_idx, int i)
905 {
906  DASHContext *c = s->priv_data;
907  AdaptationSet *as = &c->as[as_idx - 1];
908  OutputStream *os = &c->streams[i];
909 
910  if (as->media_type != s->streams[i]->codecpar->codec_type) {
911  av_log(s, AV_LOG_ERROR, "Codec type of stream %d doesn't match AdaptationSet's media type\n", i);
912  return AVERROR(EINVAL);
913  } else if (os->as_idx) {
914  av_log(s, AV_LOG_ERROR, "Stream %d is already assigned to an AdaptationSet\n", i);
915  return AVERROR(EINVAL);
916  }
917  if (c->profile & MPD_PROFILE_DVB && (as->nb_streams + 1) > 16) {
918  av_log(s, AV_LOG_ERROR, "DVB-DASH profile allows a max of 16 Representations per Adaptation Set\n");
919  return AVERROR(EINVAL);
920  }
921  os->as_idx = as_idx;
922  ++as->nb_streams;
923 
924  return 0;
925 }
926 
928 {
929  DASHContext *c = s->priv_data;
930  const char *p = c->adaptation_sets;
931  enum { new_set, parse_default, parsing_streams, parse_seg_duration, parse_frag_duration } state;
932  AdaptationSet *as;
933  int i, n, ret;
934 
935  // default: one AdaptationSet for each stream
936  if (!p) {
937  for (i = 0; i < s->nb_streams; i++) {
938  if ((ret = add_adaptation_set(s, &as, s->streams[i]->codecpar->codec_type)) < 0)
939  return ret;
940  as->id = i;
941 
942  c->streams[i].as_idx = c->nb_as;
943  ++as->nb_streams;
944  }
945  goto end;
946  }
947 
948  // syntax id=0,streams=0,1,2 id=1,streams=3,4 and so on
949  // option id=0,descriptor=descriptor_str,streams=0,1,2 and so on
950  // option id=0,seg_duration=2.5,frag_duration=0.5,streams=0,1,2
951  // id=1,trick_id=0,seg_duration=10,frag_type=none,streams=3 and so on
952  // descriptor is useful to the scheme defined by ISO/IEC 23009-1:2014/Amd.2:2015
953  // descriptor_str should be a self-closing xml tag.
954  // seg_duration and frag_duration have the same syntax as the global options of
955  // the same name, and the former have precedence over them if set.
956  state = new_set;
957  while (*p) {
958  if (*p == ' ') {
959  p++;
960  continue;
961  } else if (state == new_set && av_strstart(p, "id=", &p)) {
962  char id_str[10], *end_str;
963 
964  n = strcspn(p, ",");
965  snprintf(id_str, sizeof(id_str), "%.*s", n, p);
966 
967  i = strtol(id_str, &end_str, 10);
968  if (id_str == end_str || i < 0 || i > c->nb_as) {
969  av_log(s, AV_LOG_ERROR, "\"%s\" is not a valid value for an AdaptationSet id\n", id_str);
970  return AVERROR(EINVAL);
971  }
972 
973  if ((ret = add_adaptation_set(s, &as, AVMEDIA_TYPE_UNKNOWN)) < 0)
974  return ret;
975  as->id = i;
976 
977  p += n;
978  if (*p)
979  p++;
980  state = parse_default;
981  } else if (state != new_set && av_strstart(p, "seg_duration=", &p)) {
982  state = parse_seg_duration;
983  } else if (state != new_set && av_strstart(p, "frag_duration=", &p)) {
984  state = parse_frag_duration;
985  } else if (state == parse_seg_duration || state == parse_frag_duration) {
986  char str[32];
987  int64_t usecs = 0;
988 
989  n = strcspn(p, ",");
990  snprintf(str, sizeof(str), "%.*s", n, p);
991  p += n;
992  if (*p)
993  p++;
994 
995  ret = av_parse_time(&usecs, str, 1);
996  if (ret < 0) {
997  av_log(s, AV_LOG_ERROR, "Unable to parse option value \"%s\" as duration\n", str);
998  return ret;
999  }
1000 
1001  if (state == parse_seg_duration)
1002  as->seg_duration = usecs;
1003  else
1004  as->frag_duration = usecs;
1005  state = parse_default;
1006  } else if (state != new_set && av_strstart(p, "frag_type=", &p)) {
1007  char type_str[16];
1008 
1009  n = strcspn(p, ",");
1010  snprintf(type_str, sizeof(type_str), "%.*s", n, p);
1011  p += n;
1012  if (*p)
1013  p++;
1014 
1015  if (!strcmp(type_str, "duration"))
1017  else if (!strcmp(type_str, "pframes"))
1019  else if (!strcmp(type_str, "every_frame"))
1021  else if (!strcmp(type_str, "none"))
1022  as->frag_type = FRAG_TYPE_NONE;
1023  else {
1024  av_log(s, AV_LOG_ERROR, "Unable to parse option value \"%s\" as fragment type\n", type_str);
1025  return ret;
1026  }
1027  state = parse_default;
1028  } else if (state != new_set && av_strstart(p, "descriptor=", &p)) {
1029  n = strcspn(p, ">") + 1; //followed by one comma, so plus 1
1030  if (n < strlen(p)) {
1031  as->descriptor = av_strndup(p, n);
1032  } else {
1033  av_log(s, AV_LOG_ERROR, "Parse error, descriptor string should be a self-closing xml tag\n");
1034  return AVERROR(EINVAL);
1035  }
1036  p += n;
1037  if (*p)
1038  p++;
1039  state = parse_default;
1040  } else if ((state != new_set) && av_strstart(p, "trick_id=", &p)) {
1041  char trick_id_str[10], *end_str;
1042 
1043  n = strcspn(p, ",");
1044  snprintf(trick_id_str, sizeof(trick_id_str), "%.*s", n, p);
1045  p += n;
1046 
1047  as->trick_idx = strtol(trick_id_str, &end_str, 10);
1048  if (trick_id_str == end_str || as->trick_idx < 0)
1049  return AVERROR(EINVAL);
1050 
1051  if (*p)
1052  p++;
1053  state = parse_default;
1054  } else if ((state != new_set) && av_strstart(p, "streams=", &p)) { //descriptor and durations are optional
1055  state = parsing_streams;
1056  } else if (state == parsing_streams) {
1057  AdaptationSet *as = &c->as[c->nb_as - 1];
1058  char idx_str[8], *end_str;
1059 
1060  n = strcspn(p, " ,");
1061  snprintf(idx_str, sizeof(idx_str), "%.*s", n, p);
1062  p += n;
1063 
1064  // if value is "a" or "v", map all streams of that type
1065  if (as->media_type == AVMEDIA_TYPE_UNKNOWN && (idx_str[0] == 'v' || idx_str[0] == 'a')) {
1066  enum AVMediaType type = (idx_str[0] == 'v') ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
1067  av_log(s, AV_LOG_DEBUG, "Map all streams of type %s\n", idx_str);
1068 
1069  for (i = 0; i < s->nb_streams; i++) {
1070  if (s->streams[i]->codecpar->codec_type != type)
1071  continue;
1072 
1073  as->media_type = s->streams[i]->codecpar->codec_type;
1074 
1075  if ((ret = adaptation_set_add_stream(s, c->nb_as, i)) < 0)
1076  return ret;
1077  }
1078  } else { // select single stream
1079  i = strtol(idx_str, &end_str, 10);
1080  if (idx_str == end_str || i < 0 || i >= s->nb_streams) {
1081  av_log(s, AV_LOG_ERROR, "Selected stream \"%s\" not found!\n", idx_str);
1082  return AVERROR(EINVAL);
1083  }
1084  av_log(s, AV_LOG_DEBUG, "Map stream %d\n", i);
1085 
1086  if (as->media_type == AVMEDIA_TYPE_UNKNOWN) {
1087  as->media_type = s->streams[i]->codecpar->codec_type;
1088  }
1089 
1090  if ((ret = adaptation_set_add_stream(s, c->nb_as, i)) < 0)
1091  return ret;
1092  }
1093 
1094  if (*p == ' ')
1095  state = new_set;
1096  if (*p)
1097  p++;
1098  } else {
1099  return AVERROR(EINVAL);
1100  }
1101  }
1102 
1103 end:
1104  // check for unassigned streams
1105  for (i = 0; i < s->nb_streams; i++) {
1106  OutputStream *os = &c->streams[i];
1107  if (!os->as_idx) {
1108  av_log(s, AV_LOG_ERROR, "Stream %d is not mapped to an AdaptationSet\n", i);
1109  return AVERROR(EINVAL);
1110  }
1111  }
1112 
1113  // check references for trick mode AdaptationSet
1114  for (i = 0; i < c->nb_as; i++) {
1115  as = &c->as[i];
1116  if (as->trick_idx < 0)
1117  continue;
1118  for (n = 0; n < c->nb_as; n++) {
1119  if (c->as[n].id == as->trick_idx)
1120  break;
1121  }
1122  if (n >= c->nb_as) {
1123  av_log(s, AV_LOG_ERROR, "reference AdaptationSet id \"%d\" not found for trick mode AdaptationSet id \"%d\"\n", as->trick_idx, as->id);
1124  return AVERROR(EINVAL);
1125  }
1126  }
1127 
1128  return 0;
1129 }
1130 
1131 static int write_manifest(AVFormatContext *s, int final)
1132 {
1133  DASHContext *c = s->priv_data;
1134  AVIOContext *out;
1135  char temp_filename[1024];
1136  int ret, i;
1137  const char *proto = avio_find_protocol_name(s->url);
1138  int use_rename = proto && !strcmp(proto, "file");
1139  static unsigned int warned_non_file = 0;
1140  AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
1141  AVDictionary *opts = NULL;
1142 
1143  if (!use_rename && !warned_non_file++)
1144  av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n");
1145 
1146  snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->url);
1147  set_http_options(&opts, c);
1148  ret = dashenc_io_open(s, &c->mpd_out, temp_filename, &opts);
1149  av_dict_free(&opts);
1150  if (ret < 0) {
1151  return handle_io_open_error(s, ret, temp_filename);
1152  }
1153  out = c->mpd_out;
1154  avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1155  avio_printf(out, "<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
1156  "\txmlns=\"urn:mpeg:dash:schema:mpd:2011\"\n"
1157  "\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
1158  "\txsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd\"\n"
1159  "\tprofiles=\"");
1160  if (c->profile & MPD_PROFILE_DASH)
1161  avio_printf(out, "%s%s", "urn:mpeg:dash:profile:isoff-live:2011", c->profile & MPD_PROFILE_DVB ? "," : "\"\n");
1162  if (c->profile & MPD_PROFILE_DVB)
1163  avio_printf(out, "%s", "urn:dvb:dash:profile:dvb-dash:2014\"\n");
1164  avio_printf(out, "\ttype=\"%s\"\n",
1165  final ? "static" : "dynamic");
1166  if (final) {
1167  avio_printf(out, "\tmediaPresentationDuration=\"");
1168  write_time(out, c->total_duration);
1169  avio_printf(out, "\"\n");
1170  } else {
1171  int64_t update_period = c->last_duration / AV_TIME_BASE;
1172  char now_str[100];
1173  if (c->use_template && !c->use_timeline)
1174  update_period = 500;
1175  if (c->update_period)
1176  update_period = c->update_period;
1177  avio_printf(out, "\tminimumUpdatePeriod=\"PT%"PRId64"S\"\n", update_period);
1178  if (!c->ldash)
1179  avio_printf(out, "\tsuggestedPresentationDelay=\"PT%"PRId64"S\"\n", c->last_duration / AV_TIME_BASE);
1180  if (c->availability_start_time[0])
1181  avio_printf(out, "\tavailabilityStartTime=\"%s\"\n", c->availability_start_time);
1182  format_date(now_str, sizeof(now_str), av_gettime());
1183  if (now_str[0])
1184  avio_printf(out, "\tpublishTime=\"%s\"\n", now_str);
1185  if (c->window_size && c->use_template) {
1186  avio_printf(out, "\ttimeShiftBufferDepth=\"");
1187  write_time(out, c->last_duration * c->window_size);
1188  avio_printf(out, "\"\n");
1189  }
1190  }
1191  avio_printf(out, "\tmaxSegmentDuration=\"");
1192  write_time(out, c->max_segment_duration);
1193  avio_printf(out, "\"\n");
1194  avio_printf(out, "\tminBufferTime=\"");
1195  write_time(out, c->ldash && c->max_gop_size ? c->max_gop_size : c->last_duration * 2);
1196  avio_printf(out, "\">\n");
1197  avio_printf(out, "\t<ProgramInformation>\n");
1198  if (title) {
1199  char *escaped = xmlescape(title->value);
1200  avio_printf(out, "\t\t<Title>%s</Title>\n", escaped);
1201  av_free(escaped);
1202  }
1203  avio_printf(out, "\t</ProgramInformation>\n");
1204 
1205  avio_printf(out, "\t<ServiceDescription id=\"0\">\n");
1206  if (!final && c->target_latency && c->target_latency_refid >= 0) {
1207  avio_printf(out, "\t\t<Latency target=\"%"PRId64"\"", c->target_latency / 1000);
1208  if (s->nb_streams > 1)
1209  avio_printf(out, " referenceId=\"%d\"", c->target_latency_refid);
1210  avio_printf(out, "/>\n");
1211  }
1212  if (av_cmp_q(c->min_playback_rate, (AVRational) {1, 1}) ||
1213  av_cmp_q(c->max_playback_rate, (AVRational) {1, 1}))
1214  avio_printf(out, "\t\t<PlaybackRate min=\"%.2f\" max=\"%.2f\"/>\n",
1215  av_q2d(c->min_playback_rate), av_q2d(c->max_playback_rate));
1216  avio_printf(out, "\t</ServiceDescription>\n");
1217 
1218  if (c->window_size && s->nb_streams > 0 && c->streams[0].nb_segments > 0 && !c->use_template) {
1219  OutputStream *os = &c->streams[0];
1220  int start_index = FFMAX(os->nb_segments - c->window_size, 0);
1221  int64_t start_time = av_rescale_q(os->segments[start_index]->time, s->streams[0]->time_base, AV_TIME_BASE_Q);
1222  avio_printf(out, "\t<Period id=\"0\" start=\"");
1224  avio_printf(out, "\">\n");
1225  } else {
1226  avio_printf(out, "\t<Period id=\"0\" start=\"PT0.0S\">\n");
1227  }
1228 
1229  for (i = 0; i < c->nb_as; i++) {
1230  if ((ret = write_adaptation_set(s, out, i, final)) < 0)
1231  return ret;
1232  }
1233  avio_printf(out, "\t</Period>\n");
1234 
1235  if (c->utc_timing_url)
1236  avio_printf(out, "\t<UTCTiming schemeIdUri=\"urn:mpeg:dash:utc:http-xsdate:2014\" value=\"%s\"/>\n", c->utc_timing_url);
1237 
1238  avio_printf(out, "</MPD>\n");
1239  avio_flush(out);
1240  dashenc_io_close(s, &c->mpd_out, temp_filename);
1241 
1242  if (use_rename) {
1243  if ((ret = ff_rename(temp_filename, s->url, s)) < 0)
1244  return ret;
1245  }
1246 
1247  if (c->hls_playlist) {
1248  char filename_hls[1024];
1249 
1250  // Publish master playlist only the configured rate
1251  if (c->master_playlist_created && (!c->master_publish_rate ||
1252  c->streams[0].segment_index % c->master_publish_rate))
1253  return 0;
1254 
1255  if (*c->dirname)
1256  snprintf(filename_hls, sizeof(filename_hls), "%s%s", c->dirname, c->hls_master_name);
1257  else
1258  snprintf(filename_hls, sizeof(filename_hls), "%s", c->hls_master_name);
1259 
1260  snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", filename_hls);
1261 
1262  set_http_options(&opts, c);
1263  ret = dashenc_io_open(s, &c->m3u8_out, temp_filename, &opts);
1264  av_dict_free(&opts);
1265  if (ret < 0) {
1266  return handle_io_open_error(s, ret, temp_filename);
1267  }
1268 
1269  ff_hls_write_playlist_version(c->m3u8_out, 7);
1270 
1271  if (c->has_video) {
1272  // treat audio streams as alternative renditions for video streams
1273  const char *audio_group = "A1";
1274  char audio_codec_str[128] = "\0";
1275  int is_default = 1;
1276  int max_audio_bitrate = 0;
1277 
1278  for (i = 0; i < s->nb_streams; i++) {
1279  char playlist_file[64];
1280  AVStream *st = s->streams[i];
1281  OutputStream *os = &c->streams[i];
1283  continue;
1284  if (os->segment_type != SEGMENT_TYPE_MP4)
1285  continue;
1286  get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i);
1287  ff_hls_write_audio_rendition(c->m3u8_out, audio_group,
1288  playlist_file, NULL, i, is_default,
1289  s->streams[i]->codecpar->ch_layout.nb_channels);
1290  max_audio_bitrate = FFMAX(st->codecpar->bit_rate +
1291  os->muxer_overhead, max_audio_bitrate);
1292  if (!av_strnstr(audio_codec_str, os->codec_str, sizeof(audio_codec_str))) {
1293  if (strlen(audio_codec_str))
1294  av_strlcat(audio_codec_str, ",", sizeof(audio_codec_str));
1295  av_strlcat(audio_codec_str, os->codec_str, sizeof(audio_codec_str));
1296  }
1297  is_default = 0;
1298  }
1299 
1300  for (i = 0; i < s->nb_streams; i++) {
1301  char playlist_file[64];
1302  char codec_str[128];
1303  AVStream *st = s->streams[i];
1304  OutputStream *os = &c->streams[i];
1305  const char *agroup = NULL;
1306  int stream_bitrate = os->muxer_overhead;
1307  if (os->bit_rate > 0)
1308  stream_bitrate += os->bit_rate;
1309  else if (final)
1310  stream_bitrate += os->pos * 8 * AV_TIME_BASE / c->total_duration;
1311  else if (os->first_segment_bit_rate > 0)
1312  stream_bitrate += os->first_segment_bit_rate;
1314  continue;
1315  if (os->segment_type != SEGMENT_TYPE_MP4)
1316  continue;
1317  av_strlcpy(codec_str, os->codec_str, sizeof(codec_str));
1318  if (max_audio_bitrate) {
1319  agroup = audio_group;
1320  stream_bitrate += max_audio_bitrate;
1321  av_strlcat(codec_str, ",", sizeof(codec_str));
1322  av_strlcat(codec_str, audio_codec_str, sizeof(codec_str));
1323  }
1324  get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i);
1325  ff_hls_write_stream_info(st, c->m3u8_out, stream_bitrate,
1326  playlist_file, agroup,
1327  codec_str, NULL, NULL);
1328  }
1329 
1330  } else {
1331  // treat audio streams as separate renditions
1332 
1333  for (i = 0; i < s->nb_streams; i++) {
1334  char playlist_file[64];
1335  char codec_str[128];
1336  AVStream *st = s->streams[i];
1337  OutputStream *os = &c->streams[i];
1338  int stream_bitrate = os->muxer_overhead;
1339  if (os->bit_rate > 0)
1340  stream_bitrate += os->bit_rate;
1341  else if (final)
1342  stream_bitrate += os->pos * 8 * AV_TIME_BASE / c->total_duration;
1343  else if (os->first_segment_bit_rate > 0)
1344  stream_bitrate += os->first_segment_bit_rate;
1346  continue;
1347  if (os->segment_type != SEGMENT_TYPE_MP4)
1348  continue;
1349  av_strlcpy(codec_str, os->codec_str, sizeof(codec_str));
1350  get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i);
1351  ff_hls_write_stream_info(st, c->m3u8_out, stream_bitrate,
1352  playlist_file, NULL,
1353  codec_str, NULL, NULL);
1354  }
1355  }
1356 
1357  dashenc_io_close(s, &c->m3u8_out, temp_filename);
1358  if (use_rename)
1359  if ((ret = ff_rename(temp_filename, filename_hls, s)) < 0)
1360  return ret;
1361  c->master_playlist_created = 1;
1362  }
1363 
1364  return 0;
1365 }
1366 
1367 static int dict_copy_entry(AVDictionary **dst, const AVDictionary *src, const char *key)
1368 {
1370  if (entry)
1372  return 0;
1373 }
1374 
1376 {
1377  DASHContext *c = s->priv_data;
1378  int ret = 0, i;
1379  char *ptr;
1380  char basename[1024];
1381 
1382  c->nr_of_streams_to_flush = 0;
1383  if (c->single_file_name)
1384  c->single_file = 1;
1385  if (c->single_file)
1386  c->use_template = 0;
1387 
1388  if (!c->profile) {
1389  av_log(s, AV_LOG_ERROR, "At least one profile must be enabled.\n");
1390  return AVERROR(EINVAL);
1391  }
1392  if (c->lhls && s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1394  "LHLS is experimental, Please set -strict experimental in order to enable it.\n");
1395  return AVERROR_EXPERIMENTAL;
1396  }
1397 
1398  if (c->lhls && !c->streaming) {
1399  av_log(s, AV_LOG_WARNING, "Enabling streaming as LHLS is enabled\n");
1400  c->streaming = 1;
1401  }
1402 
1403  if (c->lhls && !c->hls_playlist) {
1404  av_log(s, AV_LOG_INFO, "Enabling hls_playlist as LHLS is enabled\n");
1405  c->hls_playlist = 1;
1406  }
1407 
1408  if (c->ldash && !c->streaming) {
1409  av_log(s, AV_LOG_WARNING, "Enabling streaming as LDash is enabled\n");
1410  c->streaming = 1;
1411  }
1412 
1413  if (c->target_latency && !c->streaming) {
1414  av_log(s, AV_LOG_WARNING, "Target latency option will be ignored as streaming is not enabled\n");
1415  c->target_latency = 0;
1416  }
1417 
1418  if (c->global_sidx && !c->single_file) {
1419  av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as single_file is not enabled\n");
1420  c->global_sidx = 0;
1421  }
1422 
1423  if (c->global_sidx && c->streaming) {
1424  av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as streaming is enabled\n");
1425  c->global_sidx = 0;
1426  }
1427  if (c->frag_type == FRAG_TYPE_NONE && c->streaming) {
1428  av_log(s, AV_LOG_VERBOSE, "Changing frag_type from none to every_frame as streaming is enabled\n");
1429  c->frag_type = FRAG_TYPE_EVERY_FRAME;
1430  }
1431 
1432  if (c->write_prft < 0) {
1433  c->write_prft = c->ldash;
1434  if (c->ldash)
1435  av_log(s, AV_LOG_VERBOSE, "Enabling Producer Reference Time element for Low Latency mode\n");
1436  }
1437 
1438  if (c->write_prft && !c->utc_timing_url) {
1439  av_log(s, AV_LOG_WARNING, "Producer Reference Time element option will be ignored as utc_timing_url is not set\n");
1440  c->write_prft = 0;
1441  }
1442 
1443  if (c->write_prft && !c->streaming) {
1444  av_log(s, AV_LOG_WARNING, "Producer Reference Time element option will be ignored as streaming is not enabled\n");
1445  c->write_prft = 0;
1446  }
1447 
1448  if (c->ldash && !c->write_prft) {
1449  av_log(s, AV_LOG_WARNING, "Low Latency mode enabled without Producer Reference Time element option! Resulting manifest may not be complaint\n");
1450  }
1451 
1452  if (c->target_latency && !c->write_prft) {
1453  av_log(s, AV_LOG_WARNING, "Target latency option will be ignored as Producer Reference Time element will not be written\n");
1454  c->target_latency = 0;
1455  }
1456 
1457  if (av_cmp_q(c->max_playback_rate, c->min_playback_rate) < 0) {
1458  av_log(s, AV_LOG_WARNING, "Minimum playback rate value is higher than the Maximum. Both will be ignored\n");
1459  c->min_playback_rate = c->max_playback_rate = (AVRational) {1, 1};
1460  }
1461 
1462  av_strlcpy(c->dirname, s->url, sizeof(c->dirname));
1463  ptr = strrchr(c->dirname, '/');
1464  if (ptr) {
1465  av_strlcpy(basename, &ptr[1], sizeof(basename));
1466  ptr[1] = '\0';
1467  } else {
1468  c->dirname[0] = '\0';
1469  av_strlcpy(basename, s->url, sizeof(basename));
1470  }
1471 
1472  ptr = strrchr(basename, '.');
1473  if (ptr)
1474  *ptr = '\0';
1475 
1476  c->streams = av_mallocz(sizeof(*c->streams) * s->nb_streams);
1477  if (!c->streams)
1478  return AVERROR(ENOMEM);
1479 
1480  if ((ret = parse_adaptation_sets(s)) < 0)
1481  return ret;
1482 
1483  if ((ret = init_segment_types(s)) < 0)
1484  return ret;
1485 
1486  for (i = 0; i < s->nb_streams; i++) {
1487  OutputStream *os = &c->streams[i];
1488  AdaptationSet *as = &c->as[os->as_idx - 1];
1490  AVStream *st;
1491  AVDictionary *opts = NULL;
1492  char filename[1024];
1493 
1494  os->bit_rate = s->streams[i]->codecpar->bit_rate;
1495  if (!os->bit_rate) {
1496  int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ?
1498  av_log(s, level, "No bit rate set for stream %d\n", i);
1499  if (s->strict_std_compliance >= FF_COMPLIANCE_STRICT)
1500  return AVERROR(EINVAL);
1501  }
1502 
1503  // copy AdaptationSet language and role from stream metadata
1504  dict_copy_entry(&as->metadata, s->streams[i]->metadata, "language");
1505  dict_copy_entry(&as->metadata, s->streams[i]->metadata, "role");
1506 
1507  if (c->init_seg_name) {
1508  os->init_seg_name = av_strireplace(c->init_seg_name, "$ext$", os->extension_name);
1509  if (!os->init_seg_name)
1510  return AVERROR(ENOMEM);
1511  }
1512  if (c->media_seg_name) {
1513  os->media_seg_name = av_strireplace(c->media_seg_name, "$ext$", os->extension_name);
1514  if (!os->media_seg_name)
1515  return AVERROR(ENOMEM);
1516  }
1517  if (c->single_file_name) {
1518  os->single_file_name = av_strireplace(c->single_file_name, "$ext$", os->extension_name);
1519  if (!os->single_file_name)
1520  return AVERROR(ENOMEM);
1521  }
1522 
1523  if (os->segment_type == SEGMENT_TYPE_WEBM) {
1524  if ((!c->single_file && !av_match_ext(os->init_seg_name, os->format_name)) ||
1525  (!c->single_file && !av_match_ext(os->media_seg_name, os->format_name)) ||
1526  ( c->single_file && !av_match_ext(os->single_file_name, os->format_name))) {
1528  "One or many segment file names doesn't end with .webm. "
1529  "Override -init_seg_name and/or -media_seg_name and/or "
1530  "-single_file_name to end with the extension .webm\n");
1531  }
1532  if (c->streaming) {
1533  // Streaming not supported as matroskaenc buffers internally before writing the output
1534  av_log(s, AV_LOG_WARNING, "One or more streams in WebM output format. Streaming option will be ignored\n");
1535  c->streaming = 0;
1536  }
1537  }
1538 
1539  os->ctx = ctx = avformat_alloc_context();
1540  if (!ctx)
1541  return AVERROR(ENOMEM);
1542 
1544  if (!ctx->oformat)
1545  return AVERROR_MUXER_NOT_FOUND;
1546  ctx->interrupt_callback = s->interrupt_callback;
1547  ctx->opaque = s->opaque;
1548  ctx->io_close2 = s->io_close2;
1549  ctx->io_open = s->io_open;
1550  ctx->strict_std_compliance = s->strict_std_compliance;
1551 
1552  if (!(st = avformat_new_stream(ctx, NULL)))
1553  return AVERROR(ENOMEM);
1554  avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
1555  st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
1556  st->time_base = s->streams[i]->time_base;
1557  st->avg_frame_rate = s->streams[i]->avg_frame_rate;
1558  ctx->avoid_negative_ts = s->avoid_negative_ts;
1559  ctx->flags = s->flags;
1560 
1561  os->parser = av_parser_init(st->codecpar->codec_id);
1562  if (os->parser) {
1564  if (!os->parser_avctx)
1565  return AVERROR(ENOMEM);
1567  if (ret < 0)
1568  return ret;
1569  // We only want to parse frame headers
1571  }
1572 
1573  if (c->single_file) {
1574  if (os->single_file_name)
1575  ff_dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), os->single_file_name, i, 0, os->bit_rate, 0);
1576  else
1577  snprintf(os->initfile, sizeof(os->initfile), "%s-stream%d.%s", basename, i, os->format_name);
1578  } else {
1579  ff_dash_fill_tmpl_params(os->initfile, sizeof(os->initfile), os->init_seg_name, i, 0, os->bit_rate, 0);
1580  }
1581  snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->initfile);
1582  set_http_options(&opts, c);
1583  if (!c->single_file) {
1584  if ((ret = avio_open_dyn_buf(&ctx->pb)) < 0)
1585  return ret;
1586  ret = s->io_open(s, &os->out, filename, AVIO_FLAG_WRITE, &opts);
1587  } else {
1588  ctx->url = av_strdup(filename);
1589  ret = avio_open2(&ctx->pb, filename, AVIO_FLAG_WRITE, NULL, &opts);
1590  }
1591  av_dict_free(&opts);
1592  if (ret < 0)
1593  return ret;
1594  os->init_start_pos = 0;
1595 
1596  av_dict_copy(&opts, c->format_options, 0);
1597  if (!as->seg_duration)
1598  as->seg_duration = c->seg_duration;
1599  if (!as->frag_duration)
1600  as->frag_duration = c->frag_duration;
1601  if (as->frag_type < 0)
1602  as->frag_type = c->frag_type;
1603  os->seg_duration = as->seg_duration;
1604  os->frag_duration = as->frag_duration;
1605  os->frag_type = as->frag_type;
1606 
1607  c->max_segment_duration = FFMAX(c->max_segment_duration, as->seg_duration);
1608 
1609  if (c->profile & MPD_PROFILE_DVB && (os->seg_duration > 15000000 || os->seg_duration < 960000)) {
1610  av_log(s, AV_LOG_ERROR, "Segment duration %"PRId64" is outside the allowed range for DVB-DASH profile\n", os->seg_duration);
1611  return AVERROR(EINVAL);
1612  }
1613 
1614  if (os->frag_type == FRAG_TYPE_DURATION && !os->frag_duration) {
1615  av_log(s, AV_LOG_WARNING, "frag_type set to duration for stream %d but no frag_duration set\n", i);
1616  os->frag_type = c->streaming ? FRAG_TYPE_EVERY_FRAME : FRAG_TYPE_NONE;
1617  }
1618  if (os->frag_type == FRAG_TYPE_DURATION && os->frag_duration > os->seg_duration) {
1619  av_log(s, AV_LOG_ERROR, "Fragment duration %"PRId64" is longer than Segment duration %"PRId64"\n", os->frag_duration, os->seg_duration);
1620  return AVERROR(EINVAL);
1621  }
1622  if (os->frag_type == FRAG_TYPE_PFRAMES && (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO || !os->parser)) {
1623  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && !os->parser)
1624  av_log(s, AV_LOG_WARNING, "frag_type set to P-Frame reordering, but no parser found for stream %d\n", i);
1625  os->frag_type = c->streaming ? FRAG_TYPE_EVERY_FRAME : FRAG_TYPE_NONE;
1626  }
1627  if (os->frag_type != FRAG_TYPE_PFRAMES && as->trick_idx < 0)
1628  // Set this now if a parser isn't used
1629  os->coding_dependency = 1;
1630 
1631  if (os->segment_type == SEGMENT_TYPE_MP4) {
1632  if (c->streaming)
1633  // skip_sidx : Reduce bitrate overhead
1634  // skip_trailer : Avoids growing memory usage with time
1635  av_dict_set(&opts, "movflags", "+dash+delay_moov+skip_sidx+skip_trailer", AV_DICT_APPEND);
1636  else {
1637  if (c->global_sidx)
1638  av_dict_set(&opts, "movflags", "+dash+delay_moov+global_sidx+skip_trailer", AV_DICT_APPEND);
1639  else
1640  av_dict_set(&opts, "movflags", "+dash+delay_moov+skip_trailer", AV_DICT_APPEND);
1641  }
1642  if (os->frag_type == FRAG_TYPE_EVERY_FRAME)
1643  av_dict_set(&opts, "movflags", "+frag_every_frame", AV_DICT_APPEND);
1644  else
1645  av_dict_set(&opts, "movflags", "+frag_custom", AV_DICT_APPEND);
1646  if (os->frag_type == FRAG_TYPE_DURATION)
1647  av_dict_set_int(&opts, "frag_duration", os->frag_duration, 0);
1648  if (c->write_prft)
1649  av_dict_set(&opts, "write_prft", "wallclock", 0);
1650  } else {
1651  av_dict_set_int(&opts, "cluster_time_limit", c->seg_duration / 1000, 0);
1652  av_dict_set_int(&opts, "cluster_size_limit", 5 * 1024 * 1024, 0); // set a large cluster size limit
1653  av_dict_set_int(&opts, "dash", 1, 0);
1654  av_dict_set_int(&opts, "dash_track_number", i + 1, 0);
1655  av_dict_set_int(&opts, "live", 1, 0);
1656  }
1658  av_dict_free(&opts);
1659  if (ret < 0)
1660  return ret;
1661  os->ctx_inited = 1;
1662  avio_flush(ctx->pb);
1663 
1664  av_log(s, AV_LOG_VERBOSE, "Representation %d init segment will be written to: %s\n", i, filename);
1665 
1666  s->streams[i]->time_base = st->time_base;
1667  // If the muxer wants to shift timestamps, request to have them shifted
1668  // already before being handed to this muxer, so we don't have mismatches
1669  // between the MPD and the actual segments.
1670  s->avoid_negative_ts = ctx->avoid_negative_ts;
1671  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
1672  AVRational avg_frame_rate = s->streams[i]->avg_frame_rate;
1673  AVRational par;
1674  if (avg_frame_rate.num > 0) {
1675  if (av_cmp_q(avg_frame_rate, as->min_frame_rate) < 0)
1676  as->min_frame_rate = avg_frame_rate;
1677  if (av_cmp_q(as->max_frame_rate, avg_frame_rate) < 0)
1678  as->max_frame_rate = avg_frame_rate;
1679  } else {
1680  as->ambiguous_frame_rate = 1;
1681  }
1682 
1683  if (st->codecpar->width > as->max_width)
1684  as->max_width = st->codecpar->width;
1685  if (st->codecpar->height > as->max_height)
1686  as->max_height = st->codecpar->height;
1687 
1688  if (st->sample_aspect_ratio.num)
1689  os->sar = st->sample_aspect_ratio;
1690  else
1691  os->sar = (AVRational){1,1};
1692  av_reduce(&par.num, &par.den,
1693  st->codecpar->width * (int64_t)os->sar.num,
1694  st->codecpar->height * (int64_t)os->sar.den,
1695  1024 * 1024);
1696 
1697  if (as->par.num && av_cmp_q(par, as->par)) {
1698  av_log(s, AV_LOG_ERROR, "Conflicting stream aspect ratios values in Adaptation Set %d. Please ensure all adaptation sets have the same aspect ratio\n", os->as_idx);
1699  return AVERROR(EINVAL);
1700  }
1701  as->par = par;
1702 
1703  c->has_video = 1;
1704  }
1705 
1707  sizeof(os->codec_str));
1708  os->first_pts = AV_NOPTS_VALUE;
1709  os->max_pts = AV_NOPTS_VALUE;
1710  os->last_dts = AV_NOPTS_VALUE;
1711  os->segment_index = 1;
1712 
1713  if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
1714  c->nr_of_streams_to_flush++;
1715  }
1716 
1717  if (!c->has_video && c->seg_duration <= 0) {
1718  av_log(s, AV_LOG_WARNING, "no video stream and no seg duration set\n");
1719  return AVERROR(EINVAL);
1720  }
1721  if (!c->has_video && c->frag_type == FRAG_TYPE_PFRAMES)
1722  av_log(s, AV_LOG_WARNING, "no video stream and P-frame fragmentation set\n");
1723 
1724  c->nr_of_streams_flushed = 0;
1725  c->target_latency_refid = -1;
1726 
1727  return 0;
1728 }
1729 
1731 {
1732  DASHContext *c = s->priv_data;
1733  int i, ret;
1734  for (i = 0; i < s->nb_streams; i++) {
1735  OutputStream *os = &c->streams[i];
1736  if ((ret = avformat_write_header(os->ctx, NULL)) < 0)
1737  return ret;
1738 
1739  // Flush init segment
1740  // Only for WebM segment, since for mp4 delay_moov is set and
1741  // the init segment is thus flushed after the first packets.
1742  if (os->segment_type == SEGMENT_TYPE_WEBM &&
1743  (ret = flush_init_segment(s, os)) < 0)
1744  return ret;
1745  }
1746  return 0;
1747 }
1748 
1749 static int add_segment(OutputStream *os, const char *file,
1750  int64_t time, int64_t duration,
1751  int64_t start_pos, int64_t range_length,
1752  int64_t index_length, int next_exp_index)
1753 {
1754  int err;
1755  Segment *seg;
1756  if (os->nb_segments >= os->segments_size) {
1757  os->segments_size = (os->segments_size + 1) * 2;
1758  if ((err = av_reallocp_array(&os->segments, sizeof(*os->segments),
1759  os->segments_size)) < 0) {
1760  os->segments_size = 0;
1761  os->nb_segments = 0;
1762  return err;
1763  }
1764  }
1765  seg = av_mallocz(sizeof(*seg));
1766  if (!seg)
1767  return AVERROR(ENOMEM);
1768  av_strlcpy(seg->file, file, sizeof(seg->file));
1769  seg->time = time;
1770  seg->duration = duration;
1771  if (seg->time < 0) { // If pts<0, it is expected to be cut away with an edit list
1772  seg->duration += seg->time;
1773  seg->time = 0;
1774  }
1775  seg->start_pos = start_pos;
1776  seg->range_length = range_length;
1777  seg->index_length = index_length;
1778  os->segments[os->nb_segments++] = seg;
1779  os->segment_index++;
1780  //correcting the segment index if it has fallen behind the expected value
1781  if (os->segment_index < next_exp_index) {
1782  av_log(NULL, AV_LOG_WARNING, "Correcting the segment index after file %s: current=%d corrected=%d\n",
1783  file, os->segment_index, next_exp_index);
1784  os->segment_index = next_exp_index;
1785  }
1786  return 0;
1787 }
1788 
1789 static void write_styp(AVIOContext *pb)
1790 {
1791  avio_wb32(pb, 24);
1792  ffio_wfourcc(pb, "styp");
1793  ffio_wfourcc(pb, "msdh");
1794  avio_wb32(pb, 0); /* minor */
1795  ffio_wfourcc(pb, "msdh");
1796  ffio_wfourcc(pb, "msix");
1797 }
1798 
1799 static void find_index_range(AVFormatContext *s, const char *full_path,
1800  int64_t pos, int *index_length)
1801 {
1802  uint8_t buf[8];
1803  AVIOContext *pb;
1804  int ret;
1805 
1806  ret = s->io_open(s, &pb, full_path, AVIO_FLAG_READ, NULL);
1807  if (ret < 0)
1808  return;
1809  if (avio_seek(pb, pos, SEEK_SET) != pos) {
1810  ff_format_io_close(s, &pb);
1811  return;
1812  }
1813  ret = avio_read(pb, buf, 8);
1814  ff_format_io_close(s, &pb);
1815  if (ret < 8)
1816  return;
1817  if (AV_RL32(&buf[4]) != MKTAG('s', 'i', 'd', 'x'))
1818  return;
1819  *index_length = AV_RB32(&buf[0]);
1820 }
1821 
1823  AVPacket *pkt, AVRational *frame_rate)
1824 {
1825  AVCodecParameters *par = os->ctx->streams[0]->codecpar;
1826  uint8_t *extradata;
1827  size_t extradata_size;
1828  int ret;
1829 
1830  if (par->extradata_size)
1831  return 0;
1832 
1833  extradata = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &extradata_size);
1834  if (!extradata_size)
1835  return 0;
1836 
1837  ret = ff_alloc_extradata(par, extradata_size);
1838  if (ret < 0)
1839  return ret;
1840 
1841  memcpy(par->extradata, extradata, extradata_size);
1842 
1843  set_codec_str(s, par, frame_rate, os->codec_str, sizeof(os->codec_str));
1844 
1845  return 0;
1846 }
1847 
1848 static void dashenc_delete_file(AVFormatContext *s, char *filename) {
1849  DASHContext *c = s->priv_data;
1850  int http_base_proto = ff_is_http_proto(filename);
1851 
1852  if (http_base_proto) {
1853  AVDictionary *http_opts = NULL;
1854 
1855  set_http_options(&http_opts, c);
1856  av_dict_set(&http_opts, "method", "DELETE", 0);
1857 
1858  if (dashenc_io_open(s, &c->http_delete, filename, &http_opts) < 0) {
1859  av_log(s, AV_LOG_ERROR, "failed to delete %s\n", filename);
1860  }
1861  av_dict_free(&http_opts);
1862 
1863  //Nothing to write
1864  dashenc_io_close(s, &c->http_delete, filename);
1865  } else {
1866  int res = ffurl_delete(filename);
1867  if (res < 0) {
1868  char errbuf[AV_ERROR_MAX_STRING_SIZE];
1869  av_strerror(res, errbuf, sizeof(errbuf));
1870  av_log(s, (res == AVERROR(ENOENT) ? AV_LOG_WARNING : AV_LOG_ERROR), "failed to delete %s: %s\n", filename, errbuf);
1871  }
1872  }
1873 }
1874 
1875 static int dashenc_delete_segment_file(AVFormatContext *s, const char* file)
1876 {
1877  DASHContext *c = s->priv_data;
1878  AVBPrint buf;
1879 
1881 
1882  av_bprintf(&buf, "%s%s", c->dirname, file);
1883  if (!av_bprint_is_complete(&buf)) {
1884  av_bprint_finalize(&buf, NULL);
1885  av_log(s, AV_LOG_WARNING, "Out of memory for filename\n");
1886  return AVERROR(ENOMEM);
1887  }
1888 
1889  dashenc_delete_file(s, buf.str);
1890 
1891  av_bprint_finalize(&buf, NULL);
1892  return 0;
1893 }
1894 
1895 static inline void dashenc_delete_media_segments(AVFormatContext *s, OutputStream *os, int remove_count)
1896 {
1897  for (int i = 0; i < remove_count; ++i) {
1899 
1900  // Delete the segment regardless of whether the file was successfully deleted
1901  av_free(os->segments[i]);
1902  }
1903 
1904  os->nb_segments -= remove_count;
1905  memmove(os->segments, os->segments + remove_count, os->nb_segments * sizeof(*os->segments));
1906 }
1907 
1908 static int dash_flush(AVFormatContext *s, int final, int stream)
1909 {
1910  DASHContext *c = s->priv_data;
1911  int i, ret = 0;
1912 
1913  const char *proto = avio_find_protocol_name(s->url);
1914  int use_rename = proto && !strcmp(proto, "file");
1915 
1916  int cur_flush_segment_index = 0, next_exp_index = -1;
1917  if (stream >= 0) {
1918  cur_flush_segment_index = c->streams[stream].segment_index;
1919 
1920  //finding the next segment's expected index, based on the current pts value
1921  if (c->use_template && !c->use_timeline && c->index_correction &&
1922  c->streams[stream].last_pts != AV_NOPTS_VALUE &&
1923  c->streams[stream].first_pts != AV_NOPTS_VALUE) {
1924  int64_t pts_diff = av_rescale_q(c->streams[stream].last_pts -
1925  c->streams[stream].first_pts,
1926  s->streams[stream]->time_base,
1927  AV_TIME_BASE_Q);
1928  next_exp_index = (pts_diff / c->streams[stream].seg_duration) + 1;
1929  }
1930  }
1931 
1932  for (i = 0; i < s->nb_streams; i++) {
1933  OutputStream *os = &c->streams[i];
1934  AVStream *st = s->streams[i];
1935  int range_length, index_length = 0;
1936  int64_t duration;
1937 
1938  if (!os->packets_written)
1939  continue;
1940 
1941  // Flush the single stream that got a keyframe right now.
1942  // Flush all audio streams as well, in sync with video keyframes,
1943  // but not the other video streams.
1944  if (stream >= 0 && i != stream) {
1945  if (s->streams[stream]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
1946  s->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
1947  continue;
1948  if (s->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
1949  continue;
1950  // Make sure we don't flush audio streams multiple times, when
1951  // all video streams are flushed one at a time.
1952  if (c->has_video && os->segment_index > cur_flush_segment_index)
1953  continue;
1954  }
1955 
1956  if (c->single_file)
1957  snprintf(os->full_path, sizeof(os->full_path), "%s%s", c->dirname, os->initfile);
1958 
1959  ret = flush_dynbuf(c, os, &range_length);
1960  if (ret < 0)
1961  break;
1962  os->packets_written = 0;
1963 
1964  if (c->single_file) {
1965  find_index_range(s, os->full_path, os->pos, &index_length);
1966  } else {
1967  dashenc_io_close(s, &os->out, os->temp_path);
1968 
1969  if (use_rename) {
1970  ret = ff_rename(os->temp_path, os->full_path, os->ctx);
1971  if (ret < 0)
1972  break;
1973  }
1974  }
1975 
1978 
1979  if (!os->muxer_overhead && os->max_pts > os->start_pts)
1980  os->muxer_overhead = ((int64_t) (range_length - os->total_pkt_size) *
1981  8 * AV_TIME_BASE) / duration;
1982  os->total_pkt_size = 0;
1983  os->total_pkt_duration = 0;
1984 
1985  if (!os->bit_rate && !os->first_segment_bit_rate) {
1986  os->first_segment_bit_rate = (int64_t) range_length * 8 * AV_TIME_BASE / duration;
1987  }
1988  add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_pts, os->pos, range_length, index_length, next_exp_index);
1989  av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, os->full_path);
1990 
1991  os->pos += range_length;
1992  }
1993 
1994  if (c->window_size) {
1995  for (i = 0; i < s->nb_streams; i++) {
1996  OutputStream *os = &c->streams[i];
1997  int remove_count = os->nb_segments - c->window_size - c->extra_window_size;
1998  if (remove_count > 0)
1999  dashenc_delete_media_segments(s, os, remove_count);
2000  }
2001  }
2002 
2003  if (final) {
2004  for (i = 0; i < s->nb_streams; i++) {
2005  OutputStream *os = &c->streams[i];
2006  if (os->ctx && os->ctx_inited) {
2007  int64_t file_size = avio_tell(os->ctx->pb);
2008  av_write_trailer(os->ctx);
2009  if (c->global_sidx) {
2010  int j, start_index, start_number;
2011  int64_t sidx_size = avio_tell(os->ctx->pb) - file_size;
2012  get_start_index_number(os, c, &start_index, &start_number);
2013  if (start_index >= os->nb_segments ||
2015  continue;
2016  os->init_range_length += sidx_size;
2017  for (j = start_index; j < os->nb_segments; j++) {
2018  Segment *seg = os->segments[j];
2019  seg->start_pos += sidx_size;
2020  }
2021  }
2022 
2023  }
2024  }
2025  }
2026  if (ret >= 0) {
2027  if (c->has_video && !final) {
2028  c->nr_of_streams_flushed++;
2029  if (c->nr_of_streams_flushed != c->nr_of_streams_to_flush)
2030  return ret;
2031 
2032  c->nr_of_streams_flushed = 0;
2033  }
2034  // In streaming mode the manifest is written at the beginning
2035  // of the segment instead
2036  if (!c->streaming || final)
2037  ret = write_manifest(s, final);
2038  }
2039  return ret;
2040 }
2041 
2043 {
2044  OutputStream *os = &c->streams[pkt->stream_index];
2046  size_t side_data_size;
2047 
2049  if (!prft || side_data_size != sizeof(AVProducerReferenceTime) || (prft->flags && prft->flags != 24)) {
2050  // No encoder generated or user provided capture time AVProducerReferenceTime side data. Instead
2051  // of letting the mov muxer generate one, do it here so we can also use it for the manifest.
2053  sizeof(AVProducerReferenceTime));
2054  if (!prft)
2055  return AVERROR(ENOMEM);
2056  prft->wallclock = av_gettime();
2057  prft->flags = 24;
2058  }
2059  if (os->first_pts == AV_NOPTS_VALUE) {
2060  os->producer_reference_time = *prft;
2061  if (c->target_latency_refid < 0)
2062  c->target_latency_refid = pkt->stream_index;
2063  }
2064 
2065  return 0;
2066 }
2067 
2069 {
2070  DASHContext *c = s->priv_data;
2071  AVStream *st = s->streams[pkt->stream_index];
2072  OutputStream *os = &c->streams[pkt->stream_index];
2073  AdaptationSet *as = &c->as[os->as_idx - 1];
2074  int64_t seg_end_duration, elapsed_duration;
2075  int ret;
2076 
2078  if (ret < 0)
2079  return ret;
2080 
2081  // Fill in a heuristic guess of the packet duration, if none is available.
2082  // The mp4 muxer will do something similar (for the last packet in a fragment)
2083  // if nothing is set (setting it for the other packets doesn't hurt).
2084  // By setting a nonzero duration here, we can be sure that the mp4 muxer won't
2085  // invoke its heuristic (this doesn't have to be identical to that algorithm),
2086  // so that we know the exact timestamps of fragments.
2087  if (!pkt->duration && os->last_dts != AV_NOPTS_VALUE)
2088  pkt->duration = pkt->dts - os->last_dts;
2089  os->last_dts = pkt->dts;
2090 
2091  // If forcing the stream to start at 0, the mp4 muxer will set the start
2092  // timestamps to 0. Do the same here, to avoid mismatches in duration/timestamps.
2093  if (os->first_pts == AV_NOPTS_VALUE &&
2094  s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
2095  pkt->pts -= pkt->dts;
2096  pkt->dts = 0;
2097  }
2098 
2099  if (c->write_prft) {
2100  ret = dash_parse_prft(c, pkt);
2101  if (ret < 0)
2102  return ret;
2103  }
2104 
2105  if (os->first_pts == AV_NOPTS_VALUE) {
2106  os->first_pts = pkt->pts;
2107  }
2108  os->last_pts = pkt->pts;
2109 
2110  if (!c->availability_start_time[0]) {
2111  int64_t start_time_us = av_gettime();
2112  c->start_time_s = start_time_us / 1000000;
2113  format_date(c->availability_start_time,
2114  sizeof(c->availability_start_time), start_time_us);
2115  }
2116 
2117  if (!os->packets_written)
2118  os->availability_time_offset = 0;
2119 
2120  if (!os->availability_time_offset &&
2121  ((os->frag_type == FRAG_TYPE_DURATION && os->seg_duration != os->frag_duration) ||
2122  (os->frag_type == FRAG_TYPE_EVERY_FRAME && pkt->duration))) {
2123  AdaptationSet *as = &c->as[os->as_idx - 1];
2124  int64_t frame_duration = 0;
2125 
2126  switch (os->frag_type) {
2127  case FRAG_TYPE_DURATION:
2128  frame_duration = os->frag_duration;
2129  break;
2130  case FRAG_TYPE_EVERY_FRAME:
2131  frame_duration = av_rescale_q(pkt->duration, st->time_base, AV_TIME_BASE_Q);
2132  break;
2133  }
2134 
2136  frame_duration) / AV_TIME_BASE;
2137  as->max_frag_duration = FFMAX(frame_duration, as->max_frag_duration);
2138  }
2139 
2140  if (c->use_template && !c->use_timeline) {
2141  elapsed_duration = pkt->pts - os->first_pts;
2142  seg_end_duration = (int64_t) os->segment_index * os->seg_duration;
2143  } else {
2144  elapsed_duration = pkt->pts - os->start_pts;
2145  seg_end_duration = os->seg_duration;
2146  }
2147 
2148  if (os->parser &&
2149  (os->frag_type == FRAG_TYPE_PFRAMES ||
2150  as->trick_idx >= 0)) {
2151  // Parse the packets only in scenarios where it's needed
2152  uint8_t *data;
2153  int size;
2155  &data, &size, pkt->data, pkt->size,
2156  pkt->pts, pkt->dts, pkt->pos);
2157 
2159  }
2160 
2161  if (pkt->flags & AV_PKT_FLAG_KEY && os->packets_written &&
2162  av_compare_ts(elapsed_duration, st->time_base,
2163  seg_end_duration, AV_TIME_BASE_Q) >= 0) {
2164  if (!c->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
2165  c->last_duration = av_rescale_q(pkt->pts - os->start_pts,
2166  st->time_base,
2167  AV_TIME_BASE_Q);
2168  c->total_duration = av_rescale_q(pkt->pts - os->first_pts,
2169  st->time_base,
2170  AV_TIME_BASE_Q);
2171 
2172  if ((!c->use_timeline || !c->use_template) && os->last_duration) {
2173  if (c->last_duration < os->last_duration*9/10 ||
2174  c->last_duration > os->last_duration*11/10) {
2176  "Segment durations differ too much, enable use_timeline "
2177  "and use_template, or keep a stricter keyframe interval\n");
2178  }
2179  }
2180  }
2181 
2182  if (c->write_prft && os->producer_reference_time.wallclock && !os->producer_reference_time_str[0])
2184  sizeof(os->producer_reference_time_str),
2186 
2187  if ((ret = dash_flush(s, 0, pkt->stream_index)) < 0)
2188  return ret;
2189  }
2190 
2191  if (!os->packets_written) {
2192  // If we wrote a previous segment, adjust the start time of the segment
2193  // to the end of the previous one (which is the same as the mp4 muxer
2194  // does). This avoids gaps in the timeline.
2195  if (os->max_pts != AV_NOPTS_VALUE)
2196  os->start_pts = os->max_pts;
2197  else
2198  os->start_pts = pkt->pts;
2199  }
2200  if (os->max_pts == AV_NOPTS_VALUE)
2201  os->max_pts = pkt->pts + pkt->duration;
2202  else
2203  os->max_pts = FFMAX(os->max_pts, pkt->pts + pkt->duration);
2204 
2205  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
2206  os->frag_type == FRAG_TYPE_PFRAMES &&
2207  os->packets_written) {
2208  av_assert0(os->parser);
2209  if ((os->parser->pict_type == AV_PICTURE_TYPE_P &&
2210  st->codecpar->video_delay &&
2211  !(os->last_flags & AV_PKT_FLAG_KEY)) ||
2212  pkt->flags & AV_PKT_FLAG_KEY) {
2213  ret = av_write_frame(os->ctx, NULL);
2214  if (ret < 0)
2215  return ret;
2216 
2217  if (!os->availability_time_offset) {
2218  int64_t frag_duration = av_rescale_q(os->total_pkt_duration, st->time_base,
2219  AV_TIME_BASE_Q);
2221  frag_duration) / AV_TIME_BASE;
2222  as->max_frag_duration = FFMAX(frag_duration, as->max_frag_duration);
2223  }
2224  }
2225  }
2226 
2227  if (pkt->flags & AV_PKT_FLAG_KEY && (os->packets_written || os->nb_segments) && !os->gop_size && as->trick_idx < 0) {
2229  c->max_gop_size = FFMAX(c->max_gop_size, os->gop_size);
2230  }
2231 
2232  if ((ret = ff_write_chained(os->ctx, 0, pkt, s, 0)) < 0)
2233  return ret;
2234 
2235  os->packets_written++;
2236  os->total_pkt_size += pkt->size;
2238  os->last_flags = pkt->flags;
2239 
2240  if (!os->init_range_length)
2241  flush_init_segment(s, os);
2242 
2243  //open the output context when the first frame of a segment is ready
2244  if (!c->single_file && os->packets_written == 1) {
2245  AVDictionary *opts = NULL;
2246  const char *proto = avio_find_protocol_name(s->url);
2247  int use_rename = proto && !strcmp(proto, "file");
2248  if (os->segment_type == SEGMENT_TYPE_MP4)
2249  write_styp(os->ctx->pb);
2250  os->filename[0] = os->full_path[0] = os->temp_path[0] = '\0';
2251  ff_dash_fill_tmpl_params(os->filename, sizeof(os->filename),
2253  os->segment_index, os->bit_rate, os->start_pts);
2254  snprintf(os->full_path, sizeof(os->full_path), "%s%s", c->dirname,
2255  os->filename);
2256  snprintf(os->temp_path, sizeof(os->temp_path),
2257  use_rename ? "%s.tmp" : "%s", os->full_path);
2258  set_http_options(&opts, c);
2259  ret = dashenc_io_open(s, &os->out, os->temp_path, &opts);
2260  av_dict_free(&opts);
2261  if (ret < 0) {
2262  return handle_io_open_error(s, ret, os->temp_path);
2263  }
2264 
2265  // in streaming mode, the segments are available for playing
2266  // before fully written but the manifest is needed so that
2267  // clients and discover the segment filenames.
2268  if (c->streaming) {
2269  write_manifest(s, 0);
2270  }
2271 
2272  if (c->lhls) {
2273  char *prefetch_url = use_rename ? NULL : os->filename;
2274  write_hls_media_playlist(os, s, pkt->stream_index, 0, prefetch_url);
2275  }
2276  }
2277 
2278  //write out the data immediately in streaming mode
2279  if (c->streaming && os->segment_type == SEGMENT_TYPE_MP4) {
2280  int len = 0;
2281  uint8_t *buf = NULL;
2282  avio_flush(os->ctx->pb);
2283  len = avio_get_dyn_buf (os->ctx->pb, &buf);
2284  if (os->out) {
2285  avio_write(os->out, buf + os->written_len, len - os->written_len);
2286  avio_flush(os->out);
2287  }
2288  os->written_len = len;
2289  }
2290 
2291  return ret;
2292 }
2293 
2295 {
2296  DASHContext *c = s->priv_data;
2297  int i;
2298 
2299  if (s->nb_streams > 0) {
2300  OutputStream *os = &c->streams[0];
2301  // If no segments have been written so far, try to do a crude
2302  // guess of the segment duration
2303  if (!c->last_duration)
2304  c->last_duration = av_rescale_q(os->max_pts - os->start_pts,
2305  s->streams[0]->time_base,
2306  AV_TIME_BASE_Q);
2307  c->total_duration = av_rescale_q(os->max_pts - os->first_pts,
2308  s->streams[0]->time_base,
2309  AV_TIME_BASE_Q);
2310  }
2311  dash_flush(s, 1, -1);
2312 
2313  if (c->remove_at_exit) {
2314  for (i = 0; i < s->nb_streams; ++i) {
2315  OutputStream *os = &c->streams[i];
2318  if (c->hls_playlist && os->segment_type == SEGMENT_TYPE_MP4) {
2319  char filename[1024];
2320  get_hls_playlist_name(filename, sizeof(filename), c->dirname, i);
2321  dashenc_delete_file(s, filename);
2322  }
2323  }
2324  dashenc_delete_file(s, s->url);
2325 
2326  if (c->hls_playlist && c->master_playlist_created) {
2327  char filename[1024];
2328  snprintf(filename, sizeof(filename), "%s%s", c->dirname, c->hls_master_name);
2329  dashenc_delete_file(s, filename);
2330  }
2331  }
2332 
2333  return 0;
2334 }
2335 
2337  const AVPacket *avpkt)
2338 {
2339  DASHContext *c = s->priv_data;
2340  OutputStream *os = &c->streams[st->index];
2341  AVFormatContext *oc = os->ctx;
2342  if (ffofmt(oc->oformat)->check_bitstream) {
2343  AVStream *const ost = oc->streams[0];
2344  int ret;
2345  ret = ffofmt(oc->oformat)->check_bitstream(oc, ost, avpkt);
2346  if (ret == 1) {
2347  FFStream *const sti = ffstream(st);
2348  FFStream *const osti = ffstream(ost);
2349  sti->bsfc = osti->bsfc;
2350  osti->bsfc = NULL;
2351  }
2352  return ret;
2353  }
2354  return 1;
2355 }
2356 
2357 #define OFFSET(x) offsetof(DASHContext, x)
2358 #define E AV_OPT_FLAG_ENCODING_PARAM
2359 static const AVOption options[] = {
2360  { "adaptation_sets", "Adaptation sets. Syntax: id=0,streams=0,1,2 id=1,streams=3,4 and so on", OFFSET(adaptation_sets), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
2361  { "dash_segment_type", "set dash segment files type", OFFSET(segment_type_option), AV_OPT_TYPE_INT, {.i64 = SEGMENT_TYPE_AUTO }, 0, SEGMENT_TYPE_NB - 1, E, .unit = "segment_type"},
2362  { "auto", "select segment file format based on codec", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_AUTO }, 0, UINT_MAX, E, .unit = "segment_type"},
2363  { "mp4", "make segment file in ISOBMFF format", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_MP4 }, 0, UINT_MAX, E, .unit = "segment_type"},
2364  { "webm", "make segment file in WebM format", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_WEBM }, 0, UINT_MAX, E, .unit = "segment_type"},
2365  { "extra_window_size", "number of segments kept outside of the manifest before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { .i64 = 5 }, 0, INT_MAX, E },
2366  { "format_options","set list of options for the container format (mp4/webm) used for dash", OFFSET(format_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E},
2367  { "frag_duration", "fragment duration (in seconds, fractional value can be set)", OFFSET(frag_duration), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT_MAX, E },
2368  { "frag_type", "set type of interval for fragments", OFFSET(frag_type), AV_OPT_TYPE_INT, {.i64 = FRAG_TYPE_NONE }, 0, FRAG_TYPE_NB - 1, E, .unit = "frag_type"},
2369  { "none", "one fragment per segment", 0, AV_OPT_TYPE_CONST, {.i64 = FRAG_TYPE_NONE }, 0, UINT_MAX, E, .unit = "frag_type"},
2370  { "every_frame", "fragment at every frame", 0, AV_OPT_TYPE_CONST, {.i64 = FRAG_TYPE_EVERY_FRAME }, 0, UINT_MAX, E, .unit = "frag_type"},
2371  { "duration", "fragment at specific time intervals", 0, AV_OPT_TYPE_CONST, {.i64 = FRAG_TYPE_DURATION }, 0, UINT_MAX, E, .unit = "frag_type"},
2372  { "pframes", "fragment at keyframes and following P-Frame reordering (Video only, experimental)", 0, AV_OPT_TYPE_CONST, {.i64 = FRAG_TYPE_PFRAMES }, 0, UINT_MAX, E, .unit = "frag_type"},
2373  { "global_sidx", "Write global SIDX atom. Applicable only for single file, mp4 output, non-streaming mode", OFFSET(global_sidx), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2374  { "hls_master_name", "HLS master playlist name", OFFSET(hls_master_name), AV_OPT_TYPE_STRING, {.str = "master.m3u8"}, 0, 0, E },
2375  { "hls_playlist", "Generate HLS playlist files(master.m3u8, media_%d.m3u8)", OFFSET(hls_playlist), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2376  { "http_opts", "HTTP protocol options", OFFSET(http_opts), AV_OPT_TYPE_DICT, { .str = NULL }, 0, 0, E },
2377  { "http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
2378  { "http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
2379  { "ignore_io_errors", "Ignore IO errors during open and write. Useful for long-duration runs with network output", OFFSET(ignore_io_errors), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2380  { "index_correction", "Enable/Disable segment index correction logic", OFFSET(index_correction), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2381  { "init_seg_name", "DASH-templated name to used for the initialization segment", OFFSET(init_seg_name), AV_OPT_TYPE_STRING, {.str = "init-stream$RepresentationID$.$ext$"}, 0, 0, E },
2382  { "ldash", "Enable Low-latency dash. Constrains the value of a few elements", OFFSET(ldash), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2383  { "lhls", "Enable Low-latency HLS(Experimental). Adds #EXT-X-PREFETCH tag with current segment's URI", OFFSET(lhls), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2384  { "master_m3u8_publish_rate", "Publish master playlist every after this many segment intervals", OFFSET(master_publish_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT_MAX, E},
2385  { "max_playback_rate", "Set desired maximum playback rate", OFFSET(max_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E },
2386  { "media_seg_name", "DASH-templated name to used for the media segments", OFFSET(media_seg_name), AV_OPT_TYPE_STRING, {.str = "chunk-stream$RepresentationID$-$Number%05d$.$ext$"}, 0, 0, E },
2387  { "method", "set the HTTP method", OFFSET(method), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
2388  { "min_playback_rate", "Set desired minimum playback rate", OFFSET(min_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E },
2389  { "mpd_profile", "Set profiles. Elements and values used in the manifest may be constrained by them", OFFSET(profile), AV_OPT_TYPE_FLAGS, {.i64 = MPD_PROFILE_DASH }, 0, UINT_MAX, E, .unit = "mpd_profile"},
2390  { "dash", "MPEG-DASH ISO Base media file format live profile", 0, AV_OPT_TYPE_CONST, {.i64 = MPD_PROFILE_DASH }, 0, UINT_MAX, E, .unit = "mpd_profile"},
2391  { "dvb_dash", "DVB-DASH profile", 0, AV_OPT_TYPE_CONST, {.i64 = MPD_PROFILE_DVB }, 0, UINT_MAX, E, .unit = "mpd_profile"},
2392  { "remove_at_exit", "remove all segments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2393  { "seg_duration", "segment duration (in seconds, fractional value can be set)", OFFSET(seg_duration), AV_OPT_TYPE_DURATION, { .i64 = 5000000 }, 0, INT_MAX, E },
2394  { "single_file", "Store all segments in one file, accessed using byte ranges", OFFSET(single_file), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2395  { "single_file_name", "DASH-templated name to be used for baseURL. Implies storing all segments in one file, accessed using byte ranges", OFFSET(single_file_name), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
2396  { "streaming", "Enable/Disable streaming mode of output. Each frame will be moof fragment", OFFSET(streaming), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
2397  { "target_latency", "Set desired target latency for Low-latency dash", OFFSET(target_latency), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT_MAX, E },
2398  { "timeout", "set timeout for socket I/O operations", OFFSET(timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E },
2399  { "update_period", "Set the mpd update interval", OFFSET(update_period), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E},
2400  { "use_template", "Use SegmentTemplate instead of SegmentList", OFFSET(use_template), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, E },
2401  { "use_timeline", "Use SegmentTimeline in SegmentTemplate", OFFSET(use_timeline), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, E },
2402  { "utc_timing_url", "URL of the page that will return the UTC timestamp in ISO format", OFFSET(utc_timing_url), AV_OPT_TYPE_STRING, { 0 }, 0, 0, E },
2403  { "window_size", "number of segments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E },
2404  { "write_prft", "Write producer reference time element", OFFSET(write_prft), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, E},
2405  { NULL },
2406 };
2407 
2408 static const AVClass dash_class = {
2409  .class_name = "dash muxer",
2410  .item_name = av_default_item_name,
2411  .option = options,
2412  .version = LIBAVUTIL_VERSION_INT,
2413 };
2414 
2416  .p.name = "dash",
2417  .p.long_name = NULL_IF_CONFIG_SMALL("DASH Muxer"),
2418  .p.extensions = "mpd",
2419  .p.audio_codec = AV_CODEC_ID_AAC,
2420  .p.video_codec = AV_CODEC_ID_H264,
2422  .p.priv_class = &dash_class,
2423  .priv_data_size = sizeof(DASHContext),
2424  .init = dash_init,
2428  .deinit = dash_free,
2430 };
OutputStream::as_idx
int as_idx
Definition: dashenc.c:108
Segment::n
int n
Definition: dashenc.c:86
AdaptationSet::max_height
int max_height
Definition: dashenc.c:100
OutputStream::gop_size
int64_t gop_size
Definition: dashenc.c:145
DASHContext::target_latency_refid
int target_latency_refid
Definition: dashenc.c:203
options
static const AVOption options[]
Definition: dashenc.c:2359
DASHContext::remove_at_exit
int remove_at_exit
Definition: dashenc.c:159
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
FRAG_TYPE_NONE
@ FRAG_TYPE_NONE
Definition: dashenc.c:69
DASHContext::master_playlist_created
int master_playlist_created
Definition: dashenc.c:181
AVCodecParameters::extradata
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: codec_par.h:69
DASHContext::profile
int profile
Definition: dashenc.c:201
AdaptationSet::max_frame_rate
AVRational max_frame_rate
Definition: dashenc.c:97
AVERROR_EXPERIMENTAL
#define AVERROR_EXPERIMENTAL
Requested feature is flagged experimental. Set strict_std_compliance if you really want to use it.
Definition: error.h:74
entry
#define entry
Definition: aom_film_grain_template.c:66
DASHContext::as
AdaptationSet * as
Definition: dashenc.c:153
DASHContext::last_duration
int64_t last_duration
Definition: dashenc.c:165
level
uint8_t level
Definition: svq3.c:205
AVOutputFormat::name
const char * name
Definition: avformat.h:510
av_bprint_is_complete
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:218
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:424
av_compare_ts
int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b)
Compare two timestamps each in its own time base.
Definition: mathematics.c:147
FRAG_TYPE_PFRAMES
@ FRAG_TYPE_PFRAMES
Definition: dashenc.c:72
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:124
FFStream::bsfc
struct AVBSFContext * bsfc
bitstream filter to run on stream
Definition: internal.h:211
OutputStream::format_name
const char * format_name
Definition: dashenc.c:127
out
FILE * out
Definition: movenc.c:55
AVCodecParserContext::pict_type
int pict_type
Definition: avcodec.h:2715
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ff_mp4_obj_type
const AVCodecTag ff_mp4_obj_type[]
Definition: isom.c:34
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
ff_hls_write_end_list
void ff_hls_write_end_list(AVIOContext *out)
Definition: hlsplaylist.c:193
DASHContext::index_correction
int index_correction
Definition: dashenc.c:187
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AV_PKT_DATA_NEW_EXTRADATA
@ AV_PKT_DATA_NEW_EXTRADATA
The AV_PKT_DATA_NEW_EXTRADATA is used to notify the codec or the format that the extradata buffer was...
Definition: packet.h:56
dash_check_bitstream
static int dash_check_bitstream(AVFormatContext *s, AVStream *st, const AVPacket *avpkt)
Definition: dashenc.c:2336
AdaptationSet::metadata
AVDictionary * metadata
Definition: dashenc.c:96
AV_FIELD_PROGRESSIVE
@ AV_FIELD_PROGRESSIVE
Definition: defs.h:200
av_div_q
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition: rational.c:88
dict_copy_entry
static int dict_copy_entry(AVDictionary **dst, const AVDictionary *src, const char *key)
Definition: dashenc.c:1367
DASHContext::presentation_time_offset
int64_t presentation_time_offset
Definition: dashenc.c:169
rational.h
OutputStream::start_pts
int64_t start_pts
Definition: dashenc.c:121
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
OutputStream::packets_written
int packets_written
Definition: dashenc.c:112
DASHContext::timeout
int64_t timeout
Definition: dashenc.c:186
DASHContext::http_persistent
int http_persistent
Definition: dashenc.c:180
DASHContext::hls_master_name
const char * hls_master_name
Definition: dashenc.c:179
set_http_options
static void set_http_options(AVDictionary **options, DASHContext *c)
Definition: dashenc.c:472
parse_adaptation_sets
static int parse_adaptation_sets(AVFormatContext *s)
Definition: dashenc.c:927
update_stream_extradata
static int update_stream_extradata(AVFormatContext *s, OutputStream *os, AVPacket *pkt, AVRational *frame_rate)
Definition: dashenc.c:1822
AdaptationSet::id
int id
Definition: dashenc.c:90
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1323
deinit
static void deinit(AVFormatContext *s)
Definition: chromaprint.c:50
AVFormatContext::strict_std_compliance
int strict_std_compliance
Allow non-standard and experimental extension.
Definition: avformat.h:1612
set_codec_str
static void set_codec_str(AVFormatContext *s, AVCodecParameters *par, AVRational *frame_rate, char *str, int size)
Definition: dashenc.c:347
AVProducerReferenceTime::wallclock
int64_t wallclock
A UTC timestamp, in microseconds, since Unix epoch (e.g, av_gettime()).
Definition: defs.h:322
AVPacket::data
uint8_t * data
Definition: packet.h:524
OutputStream::last_dts
int64_t last_dts
Definition: dashenc.c:122
dash_init
static int dash_init(AVFormatContext *s)
Definition: dashenc.c:1375
AVOption
AVOption.
Definition: opt.h:346
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:832
data
const char data[16]
Definition: mxf.c:148
AV_OPT_TYPE_DURATION
@ AV_OPT_TYPE_DURATION
Definition: opt.h:249
FF_COMPLIANCE_STRICT
#define FF_COMPLIANCE_STRICT
Strictly conform to all the things in the spec no matter what consequences.
Definition: defs.h:59
AV_DICT_APPEND
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition: dict.h:82
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:542
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
PLAYLIST_TYPE_NONE
@ PLAYLIST_TYPE_NONE
Definition: hlsplaylist.h:32
mathematics.h
dashenc_io_close
static void dashenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filename)
Definition: dashenc.c:240
FF_COMPLIANCE_EXPERIMENTAL
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition: defs.h:62
AVDictionary
Definition: dict.c:34
AV_CODEC_ID_FLAC
@ AV_CODEC_ID_FLAC
Definition: codec_id.h:452
AdaptationSet::min_frame_rate
AVRational min_frame_rate
Definition: dashenc.c:97
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
avformat_init_output
av_warn_unused_result int avformat_init_output(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and initialize the codec, but do not write the header.
Definition: mux.c:466
DASHContext::global_sidx
int global_sidx
Definition: dashenc.c:189
OutputStream::last_flags
int last_flags
Definition: dashenc.c:123
SEGMENT_TYPE_MP4
@ SEGMENT_TYPE_MP4
Definition: dashenc.c:63
AV_OPT_TYPE_RATIONAL
@ AV_OPT_TYPE_RATIONAL
Definition: opt.h:240
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
ost
static AVStream * ost
Definition: vaapi_transcode.c:42
avio_get_dyn_buf
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1374
os_support.h
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:579
AV1SequenceParameters::chroma_subsampling_y
uint8_t chroma_subsampling_y
Definition: av1.h:35
FRAG_TYPE_DURATION
@ FRAG_TYPE_DURATION
Definition: dashenc.c:71
FFOutputFormat::p
AVOutputFormat p
The public AVOutputFormat.
Definition: mux.h:65
hlsplaylist.h
add_adaptation_set
static int add_adaptation_set(AVFormatContext *s, AdaptationSet **as, enum AVMediaType type)
Definition: dashenc.c:880
OutputStream::parser
AVCodecParserContext * parser
Definition: dashenc.c:110
DASHContext
Definition: dashdec.c:123
AdaptationSet::descriptor
char * descriptor
Definition: dashenc.c:91
OutputStream::coding_dependency
int coding_dependency
Definition: dashenc.c:147
AVFormatContext::interrupt_callback
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1528
AdaptationSet::nb_streams
int nb_streams
Definition: dashenc.c:101
SEGMENT_TYPE_AUTO
@ SEGMENT_TYPE_AUTO
Definition: dashenc.c:62
DASHContext::single_file_name
const char * single_file_name
Definition: dashenc.c:171
ff_hls_write_playlist_header
void ff_hls_write_playlist_header(AVIOContext *out, int version, int allowcache, int target_duration, int64_t sequence, uint32_t playlist_type, int iframe_mode)
Definition: hlsplaylist.c:102
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:417
AdaptationSet::seg_duration
int64_t seg_duration
Definition: dashenc.c:92
av_strerror
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
Definition: error.c:108
OutputStream::full_path
char full_path[1024]
Definition: dashenc.c:136
dashenc_delete_media_segments
static void dashenc_delete_media_segments(AVFormatContext *s, OutputStream *os, int remove_count)
Definition: dashenc.c:1895
DASHContext::method
const char * method
Definition: dashenc.c:175
gmtime_r
#define gmtime_r
Definition: time_internal.h:34
dashenc_delete_segment_file
static int dashenc_delete_segment_file(AVFormatContext *s, const char *file)
Definition: dashenc.c:1875
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
AVFMT_AVOID_NEG_TS_MAKE_ZERO
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO
Shift timestamps so that they start at 0.
Definition: avformat.h:1646
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
av_parser_init
AVCodecParserContext * av_parser_init(int codec_id)
Definition: parser.c:32
add_segment
static int add_segment(OutputStream *os, const char *file, int64_t time, int64_t duration, int64_t start_pos, int64_t range_length, int64_t index_length, int next_exp_index)
Definition: dashenc.c:1749
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
ff_rename
int ff_rename(const char *url_src, const char *url_dst, void *logctx)
Wrap ffurl_move() and log if error happens.
Definition: avio.c:861
AVRational::num
int num
Numerator.
Definition: rational.h:59
DASHContext::user_agent
const char * user_agent
Definition: dashenc.c:176
vpcc.h
AV1SequenceParameters::color_description_present_flag
uint8_t color_description_present_flag
Definition: av1.h:37
FRAG_TYPE_NB
@ FRAG_TYPE_NB
Definition: dashenc.c:73
get_hls_playlist_name
static void get_hls_playlist_name(char *playlist_name, int string_size, const char *base_url, int id)
Definition: dashenc.c:485
write_time
static void write_time(AVIOContext *out, int64_t time)
Definition: dashenc.c:757
avio_close_dyn_buf
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1407
avassert.h
lrint
#define lrint
Definition: tablegen.h:53
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AdaptationSet::par
AVRational par
Definition: dashenc.c:102
DASHContext::http_delete
AVIOContext * http_delete
Definition: dashenc.c:184
E
#define E
Definition: dashenc.c:2358
AVCodecTag
Definition: internal.h:42
DASHContext::init_seg_name
const char * init_seg_name
Definition: dashenc.c:172
get_start_index_number
static void get_start_index_number(OutputStream *os, DASHContext *c, int *start_index, int *start_number)
Definition: dashenc.c:493
duration
int64_t duration
Definition: movenc.c:65
AV_FIELD_UNKNOWN
@ AV_FIELD_UNKNOWN
Definition: defs.h:199
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:62
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1362
avcodec_alloc_context3
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:149
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
DASHContext::ignore_io_errors
int ignore_io_errors
Definition: dashenc.c:191
ff_isom_get_vpcc_features
int ff_isom_get_vpcc_features(AVFormatContext *s, AVCodecParameters *par, const uint8_t *data, int len, AVRational *frame_rate, VPCC *vpcc)
Definition: vpcc.c:153
SegmentType
SegmentType
Definition: dashenc.c:61
AVFormatContext::flags
int flags
Flags modifying the (de)muxer behaviour.
Definition: avformat.h:1406
DASHContext::media_seg_name
const char * media_seg_name
Definition: dashenc.c:173
DASHContext::window_size
int window_size
Definition: dashenc.c:155
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:220
AVCodecParameters::width
int width
Video only.
Definition: codec_par.h:134
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
av_match_ext
int av_match_ext(const char *filename, const char *extensions)
Return a positive value if the given filename has one of the given extensions, 0 otherwise.
Definition: format.c:41
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:236
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:618
AV1SequenceParameters::color_range
uint8_t color_range
Definition: av1.h:41
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:49
ffofmt
static const FFOutputFormat * ffofmt(const AVOutputFormat *fmt)
Definition: mux.h:167
OutputStream::max_pts
int64_t max_pts
Definition: dashenc.c:121
DASHContext::use_timeline
int use_timeline
Definition: dashenc.c:161
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
DASHContext::hls_playlist
int hls_playlist
Definition: dashenc.c:178
DASHContext::mpd_out
AVIOContext * mpd_out
Definition: dashenc.c:182
codec_id
enum AVCodecID codec_id
Definition: vaapi_decode.c:387
AVFormatContext::opaque
void * opaque
User data.
Definition: avformat.h:1817
key
const char * key
Definition: hwcontext_opencl.c:189
dashenc_delete_file
static void dashenc_delete_file(AVFormatContext *s, char *filename)
Definition: dashenc.c:1848
DASHContext::dirname
char dirname[1024]
Definition: dashenc.c:170
OutputStream::media_seg_name
const char * media_seg_name
Definition: dashenc.c:131
write_manifest
static int write_manifest(AVFormatContext *s, int final)
Definition: dashenc.c:1131
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
avformat_write_header
av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and write the stream header to an output media file.
Definition: mux.c:487
time_internal.h
ff_http_do_new_request
int ff_http_do_new_request(URLContext *h, const char *uri)
Send a new HTTP request, reusing the old connection.
Definition: http.c:454
if
if(ret)
Definition: filter_design.txt:179
avio_flush
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:223
DASHContext::max_gop_size
int64_t max_gop_size
Definition: dashenc.c:199
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
DASHContext::streaming
int streaming
Definition: dashenc.c:185
internal.h
opts
AVDictionary * opts
Definition: movenc.c:51
AV1SequenceParameters::chroma_sample_position
uint8_t chroma_sample_position
Definition: av1.h:36
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
avcodec_parameters_to_context
int avcodec_parameters_to_context(AVCodecContext *codec, const struct AVCodecParameters *par)
Fill the codec context based on the values from the supplied codec parameters.
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
OutputStream::first_segment_bit_rate
int first_segment_bit_rate
Definition: dashenc.c:125
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:782
NULL
#define NULL
Definition: coverity.c:32
SEGMENT_TYPE_WEBM
@ SEGMENT_TYPE_WEBM
Definition: dashenc.c:64
OutputStream::frag_type
int frag_type
Definition: dashenc.c:144
OutputStream::ctx_inited
int ctx_inited
Definition: dashenc.c:108
DASHContext::write_prft
int write_prft
Definition: dashenc.c:198
dash_write_packet
static int dash_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: dashenc.c:2068
isom.h
VPCC::bitdepth
int bitdepth
Definition: vpcc.h:38
DASHContext::use_template
int use_template
Definition: dashenc.c:160
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:101
avcodec_free_context
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer.
Definition: options.c:164
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
av_strireplace
char * av_strireplace(const char *str, const char *from, const char *to)
Locale-independent strings replace.
Definition: avstring.c:229
OutputStream::init_start_pos
int64_t init_start_pos
Definition: dashenc.c:114
OutputStream::pos
int64_t pos
Definition: dashenc.c:114
AV_OPT_TYPE_DICT
@ AV_OPT_TYPE_DICT
Definition: opt.h:242
Segment::range_length
int range_length
Definition: dashenc.c:82
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
ffurl_shutdown
int ffurl_shutdown(URLContext *h, int flags)
Signal the URLContext that we are done reading or writing the stream.
Definition: avio.c:847
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1297
AV1SequenceParameters::transfer_characteristics
uint8_t transfer_characteristics
Definition: av1.h:39
avc.h
parseutils.h
DASHContext::single_file
int single_file
Definition: dashenc.c:162
flush_init_segment
static int flush_init_segment(AVFormatContext *s, OutputStream *os)
Definition: dashenc.c:582
AV1SequenceParameters::tier
uint8_t tier
Definition: av1.h:31
select_segment_type
static SegmentType select_segment_type(SegmentType segment_type, enum AVCodecID codec_id)
Definition: dashenc.c:287
FFOutputFormat
Definition: mux.h:61
codecs
static const struct codec_string codecs[]
double
double
Definition: af_crystalizer.c:131
av_parse_time
int av_parse_time(int64_t *timeval, const char *timestr, int duration)
Parse timestr and return in *time a corresponding number of microseconds.
Definition: parseutils.c:589
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:81
AVCodecParserContext::flags
int flags
Definition: avcodec.h:2740
time.h
DASHContext::start_time_s
time_t start_time_s
Definition: dashenc.c:168
ff_codec_movvideo_tags
const AVCodecTag ff_codec_movvideo_tags[]
Definition: isom_tags.c:29
ffio_geturlcontext
URLContext * ffio_geturlcontext(AVIOContext *s)
Return the URLContext associated with the AVIOContext.
Definition: avio.c:107
av_write_frame
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file.
Definition: mux.c:1233
AVProducerReferenceTime
This structure supplies correlation between a packet timestamp and a wall clock production time.
Definition: defs.h:318
AdaptationSet::frag_duration
int64_t frag_duration
Definition: dashenc.c:93
AVProducerReferenceTime::flags
int flags
Definition: defs.h:323
ff_codec_movaudio_tags
const AVCodecTag ff_codec_movaudio_tags[]
Definition: isom_tags.c:296
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition: opt.h:269
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
DASHContext::lhls
int lhls
Definition: dashenc.c:192
AVCodecParameters::extradata_size
int extradata_size
Size of the extradata content in bytes.
Definition: codec_par.h:73
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:442
MPD_PROFILE_DASH
#define MPD_PROFILE_DASH
Definition: dashenc.c:76
DASHContext::master_publish_rate
int master_publish_rate
Definition: dashenc.c:194
AV1SequenceParameters::monochrome
uint8_t monochrome
Definition: av1.h:33
ff_hls_write_playlist_version
void ff_hls_write_playlist_version(AVIOContext *out, int version)
Definition: hlsplaylist.c:32
OutputStream::extension_name
const char * extension_name
Definition: dashenc.c:128
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:366
AV1SequenceParameters::matrix_coefficients
uint8_t matrix_coefficients
Definition: av1.h:40
AVMediaType
AVMediaType
Definition: avutil.h:199
AVPacket::size
int size
Definition: packet.h:525
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
OutputStream::total_pkt_size
int total_pkt_size
Definition: dashenc.c:141
avformat_alloc_context
AVFormatContext * avformat_alloc_context(void)
Allocate an AVFormatContext.
Definition: options.c:161
OutputStream::availability_time_offset
double availability_time_offset
Definition: dashenc.c:138
av_codec_get_tag
unsigned int av_codec_get_tag(const struct AVCodecTag *const *tags, enum AVCodecID id)
Get the codec tag for the given codec id id.
ff_isom_write_avcc
int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
Definition: avc.c:142
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
FFStream
Definition: internal.h:193
OutputStream::producer_reference_time
AVProducerReferenceTime producer_reference_time
Definition: dashenc.c:139
start_time
static int64_t start_time
Definition: ffplay.c:326
FFOutputFormat::check_bitstream
int(* check_bitstream)(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
Set up any necessary bitstream filtering and extract any extra data needed for the global header.
Definition: mux.h:163
DASHContext::streams
OutputStream * streams
Definition: dashenc.c:163
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1371
DASHContext::nr_of_streams_to_flush
int nr_of_streams_to_flush
Definition: dashenc.c:195
size
int size
Definition: twinvq_data.h:10344
DASHContext::utc_timing_url
const char * utc_timing_url
Definition: dashenc.c:174
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
DASHContext::frag_duration
int64_t frag_duration
Definition: dashenc.c:158
state
static struct @395 state
DASHContext::min_playback_rate
AVRational min_playback_rate
Definition: dashenc.c:204
AV_CODEC_ID_OPUS
@ AV_CODEC_ID_OPUS
Definition: codec_id.h:500
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
ff_is_http_proto
int ff_is_http_proto(const char *filename)
Utility function to check if the file uses http or https protocol.
Definition: utils.c:580
DASHContext::has_video
int has_video
Definition: dashenc.c:164
ff_format_io_close
int ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: avformat.c:944
ff_hls_write_init_file
void ff_hls_write_init_file(AVIOContext *out, const char *filename, int byterange_mode, int64_t size, int64_t pos)
Definition: hlsplaylist.c:126
AVMEDIA_TYPE_UNKNOWN
@ AVMEDIA_TYPE_UNKNOWN
Usually treated as AVMEDIA_TYPE_DATA.
Definition: avutil.h:200
AVStream::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition: avformat.h:821
SegmentType
SegmentType
Definition: pgssubdec.c:42
Segment::prog_date_time
double prog_date_time
Definition: dashenc.c:84
set_vp9_codec_str
static void set_vp9_codec_str(AVFormatContext *s, AVCodecParameters *par, AVRational *frame_rate, char *str, int size)
Definition: dashenc.c:332
DASHContext::availability_start_time
uint64_t availability_start_time
Definition: dashdec.c:137
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:523
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:201
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:365
av_reallocp_array
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition: mem.c:225
AV_PKT_DATA_PRFT
@ AV_PKT_DATA_PRFT
Producer Reference Time data corresponding to the AVProducerReferenceTime struct, usually exported by...
Definition: packet.h:269
OutputStream::segments
Segment ** segments
Definition: dashenc.c:120
DASHContext::nb_as
int nb_as
Definition: dashenc.c:154
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:530
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:223
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
OFFSET
#define OFFSET(x)
Definition: dashenc.c:2357
OutputStream::parser_avctx
AVCodecContext * parser_avctx
Definition: dashenc.c:111
OutputStream::temp_path
char temp_path[1024]
Definition: dashenc.c:137
AV1SequenceParameters::profile
uint8_t profile
Definition: av1.h:29
Segment::duration
int64_t duration
Definition: dashenc.c:85
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
OutputStream::written_len
int written_len
Definition: dashenc.c:134
flush_dynbuf
static int flush_dynbuf(DASHContext *c, OutputStream *os, int *range_length)
Definition: dashenc.c:443
OutputStream::codec_str
char codec_str[100]
Definition: dashenc.c:133
AdaptationSet::frag_type
int frag_type
Definition: dashenc.c:94
OutputStream::first_pts
int64_t first_pts
Definition: dashenc.c:121
DASHContext::max_playback_rate
AVRational max_playback_rate
Definition: dashenc.c:205
AdaptationSet::max_frag_duration
int64_t max_frag_duration
Definition: dashenc.c:99
OutputStream::segment_index
int segment_index
Definition: dashenc.c:116
AV1SequenceParameters::color_primaries
uint8_t color_primaries
Definition: av1.h:38
get_format_str
static const char * get_format_str(SegmentType segment_type)
Definition: dashenc.c:259
av_write_trailer
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1295
bprint.h
ff_hls_write_audio_rendition
void ff_hls_write_audio_rendition(AVIOContext *out, const char *agroup, const char *filename, const char *language, int name_id, int is_default, int nb_channels)
Definition: hlsplaylist.c:40
URLContext
Definition: url.h:35
AVFMT_GLOBALHEADER
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition: avformat.h:478
PARSER_FLAG_COMPLETE_FRAMES
#define PARSER_FLAG_COMPLETE_FRAMES
Definition: avcodec.h:2741
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:517
avio_internal.h
av_packet_get_side_data
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, size_t *size)
Get side information from packet.
Definition: packet.c:252
AVERROR_MUXER_NOT_FOUND
#define AVERROR_MUXER_NOT_FOUND
Muxer not found.
Definition: error.h:62
AVCodecParameters::height
int height
Definition: codec_par.h:135
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
OutputStream::last_pts
int64_t last_pts
Definition: dashenc.c:122
find_index_range
static void find_index_range(AVFormatContext *s, const char *full_path, int64_t pos, int *index_length)
Definition: dashenc.c:1799
check_bitstream
static int check_bitstream(AVFormatContext *s, FFStream *sti, AVPacket *pkt)
Definition: mux.c:1114
FRAG_TYPE_EVERY_FRAME
@ FRAG_TYPE_EVERY_FRAME
Definition: dashenc.c:70
AdaptationSet
Definition: dashenc.c:89
DASHContext::adaptation_sets
char * adaptation_sets
Definition: dashenc.c:152
AVFormatContext::avoid_negative_ts
int avoid_negative_ts
Avoid negative timestamps during muxing.
Definition: avformat.h:1642
AV1SequenceParameters::level
uint8_t level
Definition: av1.h:30
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
url.h
OutputStream::ctx
AVFormatContext * ctx
Definition: dashenc.c:107
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
MPD_PROFILE_DVB
#define MPD_PROFILE_DVB
Definition: dashenc.c:77
AdaptationSet::ambiguous_frame_rate
int ambiguous_frame_rate
Definition: dashenc.c:98
len
int len
Definition: vorbis_enc_data.h:426
DASHContext::seg_duration
int64_t seg_duration
Definition: dashenc.c:157
profile
int profile
Definition: mxfenc.c:2227
codec_string::id
enum AVCodecID id
Definition: dashenc.c:210
AVCodecParameters::field_order
enum AVFieldOrder field_order
Video only.
Definition: codec_par.h:161
write_packet
static int write_packet(Muxer *mux, OutputStream *ost, AVPacket *pkt)
Definition: ffmpeg_mux.c:209
avcodec.h
AVFMT_TS_NEGATIVE
#define AVFMT_TS_NEGATIVE
Format allows muxing negative timestamps.
Definition: avformat.h:494
AVCodecParserContext
Definition: avcodec.h:2707
ff_dash_muxer
const FFOutputFormat ff_dash_muxer
Definition: dashenc.c:2415
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
Segment
Definition: dashenc.c:79
AdaptationSet::max_width
int max_width
Definition: dashenc.c:100
OutputStream::producer_reference_time_str
char producer_reference_time_str[100]
Definition: dashenc.c:140
AdaptationSet::trick_idx
int trick_idx
Definition: dashenc.c:103
ff_av1_parse_seq_header
int ff_av1_parse_seq_header(AV1SequenceParameters *seq, const uint8_t *buf, int size)
Parses a Sequence Header from the the provided buffer.
Definition: av1.c:336
tag
uint32_t tag
Definition: movenc.c:1787
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1435
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
OutputStream::init_seg_name
const char * init_seg_name
Definition: dashenc.c:130
ff_hls_write_file_entry
int ff_hls_write_file_entry(AVIOContext *out, int insert_discont, int byterange_mode, double duration, int round_duration, int64_t size, int64_t pos, const char *baseurl, const char *filename, double *prog_date_time, int64_t video_keyframe_size, int64_t video_keyframe_pos, int iframe_mode)
Definition: hlsplaylist.c:136
write_adaptation_set
static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_index, int final)
Definition: dashenc.c:791
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:231
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
AVFormatContext::oformat
const struct AVOutputFormat * oformat
The output container format.
Definition: avformat.h:1274
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
av_strnstr
char * av_strnstr(const char *haystack, const char *needle, size_t hay_length)
Locate the first occurrence of the string needle in the string haystack where not more than hay_lengt...
Definition: avstring.c:71
pos
unsigned int pos
Definition: spdifenc.c:414
avformat.h
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
AV_ERROR_MAX_STRING_SIZE
#define AV_ERROR_MAX_STRING_SIZE
Definition: error.h:85
OutputStream::seg_duration
int64_t seg_duration
Definition: dashenc.c:117
VPCC::level
int level
Definition: vpcc.h:37
adaptation_set_add_stream
static int adaptation_set_add_stream(AVFormatContext *s, int as_idx, int i)
Definition: dashenc.c:904
SEGMENT_TYPE_NB
@ SEGMENT_TYPE_NB
Definition: dashenc.c:65
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
avio_printf
int avio_printf(AVIOContext *s, const char *fmt,...) av_printf_format(2
Writes a formatted string to the context.
OutputStream::single_file_name
const char * single_file_name
Definition: dashenc.c:129
dash_write_header
static int dash_write_header(AVFormatContext *s)
Definition: dashenc.c:1730
write_styp
static void write_styp(AVIOContext *pb)
Definition: dashenc.c:1789
AVCodecContext
main external API structure.
Definition: avcodec.h:445
DASHContext::max_segment_duration
int64_t max_segment_duration
Definition: dashenc.c:200
DASHContext::frag_type
int frag_type
Definition: dashenc.c:197
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:749
OutputStream::init_range_length
int init_range_length
Definition: dashenc.c:115
DASHContext::nr_of_streams_flushed
int nr_of_streams_flushed
Definition: dashenc.c:196
dashenc_io_open
static int dashenc_io_open(AVFormatContext *s, AVIOContext **pb, char *filename, AVDictionary **options)
Definition: dashenc.c:221
VPCC
Definition: vpcc.h:35
get_extension_str
static const char * get_extension_str(SegmentType type, int single_file)
Definition: dashenc.c:268
OutputStream::last_duration
int64_t last_duration
Definition: dashenc.c:119
Segment::file
char file[1024]
Definition: dashenc.c:80
OutputStream::initfile
char initfile[1024]
Definition: dashenc.c:113
Segment::index_length
int index_length
Definition: dashenc.c:82
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
OutputStream::muxer_overhead
int muxer_overhead
Definition: dashenc.c:143
AVRational::den
int den
Denominator.
Definition: rational.h:60
ff_hls_write_stream_info
void ff_hls_write_stream_info(AVStream *st, AVIOContext *out, int bandwidth, const char *filename, const char *agroup, const char *codecs, const char *ccgroup, const char *sgroup)
Definition: hlsplaylist.c:73
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:141
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:612
OutputStream::total_pkt_duration
int64_t total_pkt_duration
Definition: dashenc.c:142
format_date
static void format_date(char *buf, int size, int64_t time_us)
Definition: dashenc.c:773
OutputStream::nb_segments
int nb_segments
Definition: dashenc.c:116
AVFormatContext::io_open
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
A callback for opening new IO streams.
Definition: avformat.h:1858
DASHContext::total_duration
int64_t total_duration
Definition: dashenc.c:166
AV1SequenceParameters::chroma_subsampling_x
uint8_t chroma_subsampling_x
Definition: av1.h:34
dash_write_trailer
static int dash_write_trailer(AVFormatContext *s)
Definition: dashenc.c:2294
AVPacket::stream_index
int stream_index
Definition: packet.h:526
OutputStream::sar
AVRational sar
Definition: dashenc.c:146
OutputStream::filename
char filename[1024]
Definition: dashenc.c:135
write_hls_media_playlist
static void write_hls_media_playlist(OutputStream *os, AVFormatContext *s, int representation_id, int final, char *prefetch_url)
Definition: dashenc.c:503
OutputStream::out
AVIOContext * out
Definition: dashenc.c:109
OutputStream::bit_rate
int bit_rate
Definition: dashenc.c:124
av_gettime
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:167
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
output_segment_list
static void output_segment_list(OutputStream *os, AVIOContext *out, AVFormatContext *s, int representation_id, int final)
Definition: dashenc.c:642
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:280
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
av_parser_parse2
int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int64_t pts, int64_t dts, int64_t pos)
Parse a packet.
Definition: parser.c:115
avutil.h
av_guess_format
const AVOutputFormat * av_guess_format(const char *short_name, const char *filename, const char *mime_type)
Return the output format in the list of registered output formats which best matches the provided par...
Definition: format.c:79
mem.h
DASHContext::m3u8_out
AVIOContext * m3u8_out
Definition: dashenc.c:183
avio_open2
int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: avio.c:491
AVCodecParameters::video_delay
int video_delay
Video only.
Definition: codec_par.h:175
codec_string::str
const char str[8]
Definition: dashenc.c:211
handle_io_open_error
static int handle_io_open_error(AVFormatContext *s, int err, char *url)
Definition: dashenc.c:278
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
dash_flush
static int dash_flush(AVFormatContext *s, int final, int stream)
Definition: dashenc.c:1908
AVDictionaryEntry
Definition: dict.h:89
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:501
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
ff_dash_fill_tmpl_params
void ff_dash_fill_tmpl_params(char *dst, size_t buffer_size, const char *template, int rep_id, int number, int bit_rate, int64_t time)
Definition: dash.c:95
DASHContext::http_opts
AVDictionary * http_opts
Definition: dashenc.c:177
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:88
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:237
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:544
DASHContext::target_latency
int64_t target_latency
Definition: dashenc.c:202
AVFormatContext::io_close2
int(* io_close2)(struct AVFormatContext *s, AVIOContext *pb)
A callback for closing the streams opened with AVFormatContext.io_open().
Definition: avformat.h:1872
avio_find_protocol_name
const char * avio_find_protocol_name(const char *url)
Return the name of the protocol that will handle the passed URL.
Definition: avio.c:657
codec_string
Definition: dashenc.c:209
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Definition: opt.h:234
OutputStream
Definition: mux.c:53
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
avio_close
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: avio.c:616
dash_parse_prft
static int dash_parse_prft(DASHContext *c, AVPacket *pkt)
Definition: dashenc.c:2042
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
AVCodecParameters::bit_rate
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: codec_par.h:97
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV1SequenceParameters::bitdepth
uint8_t bitdepth
Definition: av1.h:32
DASHContext::format_options
AVDictionary * format_options
Definition: dashenc.c:188
dash_class
static const AVClass dash_class
Definition: dashenc.c:2408
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
av1.h
AV_CODEC_ID_VORBIS
@ AV_CODEC_ID_VORBIS
Definition: codec_id.h:445
dash.h
AV1SequenceParameters
Definition: av1.h:28
AVDictionaryEntry::value
char * value
Definition: dict.h:91
VPCC::profile
int profile
Definition: vpcc.h:36
avstring.h
DASHContext::segment_type_option
SegmentType segment_type_option
Definition: dashenc.c:190
Segment::time
int64_t time
Definition: dashenc.c:83
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:239
ffurl_delete
int ffurl_delete(const char *url)
Delete a resource.
Definition: avio.c:705
write_header
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:345
av_strndup
char * av_strndup(const char *s, size_t len)
Duplicate a substring of a string.
Definition: mem.c:284
Segment::start_pos
int64_t start_pos
Definition: dashenc.c:81
http.h
dash_free
static void dash_free(AVFormatContext *s)
Definition: dashenc.c:600
DASHContext::update_period
int64_t update_period
Definition: dashenc.c:206
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
snprintf
#define snprintf
Definition: snprintf.h:34
OutputStream::segments_size
int segments_size
Definition: dashenc.c:116
AdaptationSet::media_type
enum AVMediaType media_type
Definition: dashenc.c:95
init_segment_types
static int init_segment_types(AVFormatContext *s)
Definition: dashenc.c:301
OutputStream::frag_duration
int64_t frag_duration
Definition: dashenc.c:118
avcodec_parameters_copy
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:106
DASHContext::extra_window_size
int extra_window_size
Definition: dashenc.c:156
av_parser_close
void av_parser_close(AVCodecParserContext *s)
Definition: parser.c:193
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
av_realloc
void * av_realloc(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory.
Definition: mem.c:155
xmlescape
static char * xmlescape(const char *str)
Definition: dashenc.c:717
ff_alloc_extradata
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition: utils.c:240
DASHContext::ldash
int ldash
Definition: dashenc.c:193
OutputStream::segment_type
SegmentType segment_type
Definition: dashenc.c:126
mux.h
ff_write_chained
int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, AVFormatContext *src, int interleave)
Write a packet to another muxer than the one the user originally intended.
Definition: mux.c:1394