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