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