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