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