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