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