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