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