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