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