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