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