FFmpeg
Loading...
Searching...
No Matches
ffmpeg_mux_init.c
Go to the documentation of this file.
1/*
2 * Muxer/output file setup.
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <string.h>
22
23#include "cmdutils.h"
24#include "ffmpeg.h"
25#include "ffmpeg_mux.h"
26#include "ffmpeg_sched.h"
27#include "fopen_utf8.h"
28
30#include "libavformat/avio.h"
31
32#include "libavcodec/avcodec.h"
33
35
36#include "libavutil/avassert.h"
37#include "libavutil/avstring.h"
38#include "libavutil/avutil.h"
39#include "libavutil/bprint.h"
40#include "libavutil/dict.h"
41#include "libavutil/display.h"
43#include "libavutil/iamf.h"
45#include "libavutil/log.h"
46#include "libavutil/mem.h"
47#include "libavutil/opt.h"
49#include "libavutil/pixdesc.h"
50#include "libavutil/stereo3d.h"
51
52#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
53
54static int check_opt_bitexact(void *ctx, const AVDictionary *opts,
55 const char *opt_name, int flag)
56{
57 const AVDictionaryEntry *e = av_dict_get(opts, opt_name, NULL, 0);
58
59 if (e) {
60 const AVOption *o = av_opt_find(ctx, opt_name, NULL, 0, 0);
61 int val = 0;
62 if (!o)
63 return 0;
65 return !!(val & flag);
66 }
67 return 0;
68}
69
71 MuxStream *ms, const AVCodec **enc)
72{
73 OutputStream *ost = &ms->ost;
74 enum AVMediaType type = ost->type;
75 const char *codec_name = NULL;
76
77 *enc = NULL;
78
79 opt_match_per_stream_str(ost, &o->codec_names, s, ost->st, &codec_name);
80
81 if (type != AVMEDIA_TYPE_VIDEO &&
84 if (codec_name && strcmp(codec_name, "copy")) {
85 const char *type_str = av_get_media_type_string(type);
87 "Encoder '%s' specified, but only '-codec copy' supported "
88 "for %s streams\n", codec_name, type_str);
89 return AVERROR(ENOSYS);
90 }
91 return 0;
92 }
93
94 if (!codec_name) {
95 ms->par_in->codec_id = av_guess_codec(s->oformat, NULL, s->url, NULL, ost->type);
97 if (!*enc) {
98 av_log(ost, AV_LOG_FATAL, "Automatic encoder selection failed "
99 "Default encoder for format %s (codec %s) is "
100 "probably disabled. Please choose an encoder manually.\n",
101 s->oformat->name, avcodec_get_name(ms->par_in->codec_id));
103 }
104 } else if (strcmp(codec_name, "copy")) {
105 int ret = find_codec(ost, codec_name, ost->type, 1, enc);
106 if (ret < 0)
107 return ret;
108 ms->par_in->codec_id = (*enc)->id;
109 }
110
111 return 0;
112}
113
114static char *get_line(AVIOContext *s, AVBPrint *bprint)
115{
116 char c;
117
118 while ((c = avio_r8(s)) && c != '\n')
119 av_bprint_chars(bprint, c, 1);
120
121 if (!av_bprint_is_complete(bprint))
122 return NULL;
123
124 return bprint->str;
125}
126
127static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
128{
129 int i, ret = -1;
130 char filename[1000];
131 char *env_avconv_datadir = getenv_utf8("AVCONV_DATADIR");
132 char *env_home = getenv_utf8("HOME");
133 const char *base[3] = { env_avconv_datadir,
134 env_home,
135 AVCONV_DATADIR,
136 };
137
138 for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) {
139 if (!base[i])
140 continue;
141 if (codec_name) {
142 snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
143 i != 1 ? "" : "/.avconv", codec_name, preset_name);
144 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
145 }
146 if (ret < 0) {
147 snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
148 i != 1 ? "" : "/.avconv", preset_name);
149 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
150 }
151 }
152 freeenv_utf8(env_home);
153 freeenv_utf8(env_avconv_datadir);
154 return ret;
155}
156
157typedef struct EncStatsFile {
158 char *path;
161
164
165static int enc_stats_get_file(AVIOContext **io, const char *path)
166{
167 EncStatsFile *esf;
168 int ret;
169
170 for (int i = 0; i < nb_enc_stats_files; i++)
171 if (!strcmp(path, enc_stats_files[i].path)) {
172 *io = enc_stats_files[i].io;
173 return 0;
174 }
175
177 if (ret < 0)
178 return ret;
179
181
182 ret = avio_open2(&esf->io, path, AVIO_FLAG_WRITE, &int_cb, NULL);
183 if (ret < 0) {
184 av_log(NULL, AV_LOG_ERROR, "Error opening stats file '%s': %s\n",
185 path, av_err2str(ret));
186 return ret;
187 }
188
189 esf->path = av_strdup(path);
190 if (!esf->path)
191 return AVERROR(ENOMEM);
192
193 *io = esf->io;
194
195 return 0;
196}
197
199{
200 for (int i = 0; i < nb_enc_stats_files; i++) {
201 av_freep(&enc_stats_files[i].path);
203 }
206}
207
208static int unescape(char **pdst, size_t *dst_len,
209 const char **pstr, char delim)
210{
211 const char *str = *pstr;
212 char *dst;
213 size_t len, idx;
214
215 *pdst = NULL;
216
217 len = strlen(str);
218 if (!len)
219 return 0;
220
221 dst = av_malloc(len + 1);
222 if (!dst)
223 return AVERROR(ENOMEM);
224
225 for (idx = 0; *str; idx++, str++) {
226 if (str[0] == '\\' && str[1])
227 str++;
228 else if (*str == delim)
229 break;
230
231 dst[idx] = *str;
232 }
233 if (!idx) {
234 av_freep(&dst);
235 return 0;
236 }
237
238 dst[idx] = 0;
239
240 *pdst = dst;
241 *dst_len = idx;
242 *pstr = str;
243
244 return 0;
245}
246
247static int enc_stats_init(OutputStream *ost, EncStats *es, int pre,
248 const char *path, const char *fmt_spec)
249{
250 static const struct {
251 enum EncStatsType type;
252 const char *str;
253 unsigned pre_only:1;
254 unsigned post_only:1;
255 unsigned need_input_data:1;
256 } fmt_specs[] = {
257 { ENC_STATS_FILE_IDX, "fidx" },
258 { ENC_STATS_STREAM_IDX, "sidx" },
259 { ENC_STATS_FRAME_NUM, "n" },
260 { ENC_STATS_FRAME_NUM_IN, "ni", 0, 0, 1 },
261 { ENC_STATS_TIMEBASE, "tb" },
262 { ENC_STATS_TIMEBASE_IN, "tbi", 0, 0, 1 },
263 { ENC_STATS_PTS, "pts" },
264 { ENC_STATS_PTS_TIME, "t" },
265 { ENC_STATS_PTS_IN, "ptsi", 0, 0, 1 },
266 { ENC_STATS_PTS_TIME_IN, "ti", 0, 0, 1 },
267 { ENC_STATS_DTS, "dts", 0, 1 },
268 { ENC_STATS_DTS_TIME, "dt", 0, 1 },
269 { ENC_STATS_SAMPLE_NUM, "sn", 1 },
270 { ENC_STATS_NB_SAMPLES, "samp", 1 },
271 { ENC_STATS_PKT_SIZE, "size", 0, 1 },
272 { ENC_STATS_BITRATE, "br", 0, 1 },
273 { ENC_STATS_AVG_BITRATE, "abr", 0, 1 },
274 { ENC_STATS_KEYFRAME, "key", 0, 1 },
275 };
276 const char *next = fmt_spec;
277
278 int ret;
279
280 while (*next) {
282 char *val;
283 size_t val_len;
284
285 // get the sequence up until next opening brace
286 ret = unescape(&val, &val_len, &next, '{');
287 if (ret < 0)
288 return ret;
289
290 if (val) {
291 ret = GROW_ARRAY(es->components, es->nb_components);
292 if (ret < 0) {
293 av_freep(&val);
294 return ret;
295 }
296
297 c = &es->components[es->nb_components - 1];
298 c->type = ENC_STATS_LITERAL;
299 c->str = val;
300 c->str_len = val_len;
301 }
302
303 if (!*next)
304 break;
305 next++;
306
307 // get the part inside braces
308 ret = unescape(&val, &val_len, &next, '}');
309 if (ret < 0)
310 return ret;
311
312 if (!val) {
314 "Empty formatting directive in: %s\n", fmt_spec);
315 return AVERROR(EINVAL);
316 }
317
318 if (!*next) {
320 "Missing closing brace in: %s\n", fmt_spec);
321 ret = AVERROR(EINVAL);
322 goto fail;
323 }
324 next++;
325
326 ret = GROW_ARRAY(es->components, es->nb_components);
327 if (ret < 0)
328 goto fail;
329
330 c = &es->components[es->nb_components - 1];
331
332 for (size_t i = 0; i < FF_ARRAY_ELEMS(fmt_specs); i++) {
333 if (!strcmp(val, fmt_specs[i].str)) {
334 if ((pre && fmt_specs[i].post_only) || (!pre && fmt_specs[i].pre_only)) {
336 "Format directive '%s' may only be used %s-encoding\n",
337 val, pre ? "post" : "pre");
338 ret = AVERROR(EINVAL);
339 goto fail;
340 }
341
342 c->type = fmt_specs[i].type;
343
344 if (fmt_specs[i].need_input_data && !ost->ist) {
346 "Format directive '%s' is unavailable, because "
347 "this output stream has no associated input stream\n",
348 val);
349 }
350
351 break;
352 }
353 }
354
355 if (!c->type) {
356 av_log(NULL, AV_LOG_ERROR, "Invalid format directive: %s\n", val);
357 ret = AVERROR(EINVAL);
358 goto fail;
359 }
360
361fail:
362 av_freep(&val);
363 if (ret < 0)
364 return ret;
365 }
366
367 ret = pthread_mutex_init(&es->lock, NULL);
368 if (ret)
369 return AVERROR(ret);
370 es->lock_initialized = 1;
371
372 ret = enc_stats_get_file(&es->io, path);
373 if (ret < 0)
374 return ret;
375
376 return 0;
377}
378
379static const char *output_stream_item_name(void *obj)
380{
381 const MuxStream *ms = obj;
382
383 return ms->log_name;
384}
385
387 .class_name = "OutputStream",
388 .version = LIBAVUTIL_VERSION_INT,
389 .item_name = output_stream_item_name,
390 .category = AV_CLASS_CATEGORY_MUXER,
391};
392
394{
395 const char *type_str = av_get_media_type_string(type);
396 MuxStream *ms;
397
398 ms = allocate_array_elem(&mux->of.streams, sizeof(*ms), &mux->of.nb_streams);
399 if (!ms)
400 return NULL;
401
402 ms->ost.file = &mux->of;
403 ms->ost.index = mux->of.nb_streams - 1;
404 ms->ost.type = type;
405
407
408 ms->sch_idx = -1;
409 ms->sch_idx_enc = -1;
410
411 snprintf(ms->log_name, sizeof(ms->log_name), "%cost#%d:%d",
412 type_str ? *type_str : '?', mux->of.index, ms->ost.index);
413
414 return ms;
415}
416
418 OutputStream *ost, char **dst)
419{
420 const char *filters = NULL;
422
423 if (!ost->ist) {
424 if (filters) {
426 "Filtergraph '%s' was specified for a stream fed from a complex "
427 "filtergraph. Simple and complex filtering cannot be used "
428 "together for the same stream.\n", filters);
429 return AVERROR(EINVAL);
430 }
431 return 0;
432 }
433
434 if (filters)
436 else
437 *dst = av_strdup(ost->type == AVMEDIA_TYPE_VIDEO ? "null" : "anull");
438 return *dst ? 0 : AVERROR(ENOMEM);
439}
440
441static int parse_matrix_coeffs(void *logctx, uint16_t *dest, const char *str)
442{
443 const char *p = str;
444 for (int i = 0;; i++) {
445 dest[i] = atoi(p);
446 if (i == 63)
447 break;
448 p = strchr(p, ',');
449 if (!p) {
450 av_log(logctx, AV_LOG_FATAL,
451 "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
452 return AVERROR(EINVAL);
453 }
454 p++;
455 }
456
457 return 0;
458}
459
461{
462 for (; *formats != AV_PIX_FMT_NONE; formats++)
463 if (*formats == format)
464 return 1;
465 return 0;
466}
467
468static enum AVPixelFormat
470{
471 const enum AVPixelFormat *p;
473 //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel format without alpha is implemented
474 int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
476 int ret;
477
479 0, (const void **) &p, NULL);
480 if (ret < 0)
481 return AV_PIX_FMT_NONE;
482
483 for (; *p != AV_PIX_FMT_NONE; p++) {
484 best = av_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
485 if (*p == target)
486 break;
487 }
488 if (*p == AV_PIX_FMT_NONE) {
489 if (target != AV_PIX_FMT_NONE)
491 "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
492 av_get_pix_fmt_name(target),
493 avctx->codec->name,
494 av_get_pix_fmt_name(best));
495 return best;
496 }
497 return target;
498}
499
501{
502 const enum AVPixelFormat *fmts;
503 enum AVPixelFormat fmt;
504 int ret;
505
506 fmt = av_get_pix_fmt(name);
507 if (fmt == AV_PIX_FMT_NONE) {
508 av_log(ost, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", name);
509 return AV_PIX_FMT_NONE;
510 }
511
513 0, (const void **) &fmts, NULL);
514 if (ret < 0)
515 return AV_PIX_FMT_NONE;
516
517 /* when the user specified-format is an alias for an endianness-specific
518 * one (e.g. rgb48 -> rgb48be/le), it gets translated into the native
519 * endianness by av_get_pix_fmt();
520 * the following code handles the case when the native endianness is not
521 * supported by the encoder, but the other one is */
522 if (fmts && !pixfmt_in_list(fmts, fmt)) {
523 const char *name_canonical = av_get_pix_fmt_name(fmt);
524 int len = strlen(name_canonical);
525
526 if (strcmp(name, name_canonical) &&
527 (!strcmp(name_canonical + len - 2, "le") ||
528 !strcmp(name_canonical + len - 2, "be"))) {
529 char name_other[64];
530 enum AVPixelFormat fmt_other;
531
532 snprintf(name_other, sizeof(name_other), "%s%ce",
533 name, name_canonical[len - 2] == 'l' ? 'b' : 'l');
534 fmt_other = av_get_pix_fmt(name_other);
535 if (fmt_other != AV_PIX_FMT_NONE && pixfmt_in_list(fmts, fmt_other)) {
536 av_log(ost, AV_LOG_VERBOSE, "Mapping pixel format %s->%s\n",
537 name, name_other);
538 fmt = fmt_other;
539 }
540 }
541 }
542
543 if (fmts && !pixfmt_in_list(fmts, fmt))
544 fmt = choose_pixel_fmt(ost->enc->enc_ctx, fmt);
545
546 return fmt;
547}
548
549static int parse_stereo3d_type(void *logctx, const char *arg, int *type)
550{
551 static const struct {
552 const char *name;
553 int type;
554 } aliases[] = {
555 { "2d", AV_STEREO3D_2D },
556 { "mono", AV_STEREO3D_2D },
557 { "sbs", AV_STEREO3D_SIDEBYSIDE },
558 { "sbsl", AV_STEREO3D_SIDEBYSIDE },
559 { "tb", AV_STEREO3D_TOPBOTTOM },
560 { "tbl", AV_STEREO3D_TOPBOTTOM },
561 };
562 static const enum AVStereo3DType v1_types[] = {
566 };
567
568 for (int i = 0; i < FF_ARRAY_ELEMS(aliases); i++) {
569 if (!av_strcasecmp(arg, aliases[i].name)) {
570 *type = aliases[i].type;
571 return 0;
572 }
573 }
574
575 for (int i = 0; i < FF_ARRAY_ELEMS(v1_types); i++) {
576 const char *name = av_stereo3d_type_name(v1_types[i]);
577 if (!av_strcasecmp(arg, name)) {
578 *type = v1_types[i];
579 return 0;
580 }
581 }
582
583 av_log(logctx, AV_LOG_ERROR,
584 "Invalid stereoscopic 3D layout '%s'. "
585 "Valid values are: 2d, mono, sbs, sbsl, side by side, "
586 "tb, tbl, top and bottom.\n", arg);
587 return AVERROR(EINVAL);
588}
589
591{
592 AVFormatContext *oc = mux->fc;
593
594 for (int i = 0; i < o->stereo3ds.nb_opt; i++) {
595 const SpecifierOpt *so = &o->stereo3ds.opt[i];
596 int matched_video = 0, matched_other = 0;
597
598 /* Empty specifier applies to video only; ignore other stream types. */
599 if (!so->specifier[0])
600 continue;
601
602 for (unsigned j = 0; j < oc->nb_streams; j++) {
603 AVStream *st = oc->streams[j];
604 if (!stream_specifier_match(&so->stream_spec, oc, st, mux))
605 continue;
607 matched_video++;
608 else
609 matched_other++;
610 }
611
612 if (matched_other) {
613 av_log(mux, AV_LOG_ERROR,
614 "-stereo3d is only valid for video streams (specifier '%s').\n",
615 so->specifier);
616 return AVERROR(EINVAL);
617 }
618 if (!matched_video) {
619 av_log(mux, AV_LOG_ERROR,
620 "Stream specifier '%s' for -stereo3d matches no video streams.\n",
621 so->specifier);
622 return AVERROR(EINVAL);
623 }
624 }
625
626 return 0;
627}
628
629static int new_stream_video(Muxer *mux, const OptionsContext *o,
630 OutputStream *ost, int *keep_pix_fmt,
631 enum VideoSyncMethod *vsync_method)
632{
634 AVFormatContext *oc = mux->fc;
635 AVStream *st;
636 const char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL;
637 const char *stereo3d = NULL;
638 int ret = 0;
639
640 st = ost->st;
641
642 opt_match_per_stream_str(ost, &o->frame_rates, oc, st, &frame_rate);
643 if (frame_rate && av_parse_video_rate(&ms->frame_rate, frame_rate) < 0) {
644 av_log(ost, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
645 return AVERROR(EINVAL);
646 }
647
648 opt_match_per_stream_str(ost, &o->max_frame_rates, oc, st, &max_frame_rate);
649 if (max_frame_rate && av_parse_video_rate(&ms->max_frame_rate, max_frame_rate) < 0) {
650 av_log(ost, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate);
651 return AVERROR(EINVAL);
652 }
653
654 if (frame_rate && max_frame_rate) {
655 av_log(ost, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n");
656 return AVERROR(EINVAL);
657 }
658
659 opt_match_per_stream_str(ost, &o->frame_aspect_ratios, oc, st, &frame_aspect_ratio);
660 if (frame_aspect_ratio) {
661 AVRational q;
662 if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
663 q.num <= 0 || q.den <= 0) {
664 av_log(ost, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
665 return AVERROR(EINVAL);
666 }
667 ost->frame_aspect_ratio = q;
668 }
669
670 opt_match_per_stream_str(ost, &o->stereo3ds, oc, st, &stereo3d);
671 if (stereo3d) {
672 ret = parse_stereo3d_type(ost, stereo3d, &ms->stereo3d_type);
673 if (ret < 0)
674 return ret;
675 ms->stereo3d_set = 1;
676 }
677
678 if (ost->enc) {
679 AVCodecContext *video_enc = ost->enc->enc_ctx;
680 const char *p = NULL, *fps_mode = NULL;
681 const char *frame_size = NULL;
682 const char *frame_pix_fmt = NULL;
683 const char *intra_matrix = NULL, *inter_matrix = NULL;
684 const char *chroma_intra_matrix = NULL;
685 int do_pass = 0;
686 int i;
687
689 if (frame_size) {
690 ret = av_parse_video_size(&video_enc->width, &video_enc->height, frame_size);
691 if (ret < 0) {
692 av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
693 return AVERROR(EINVAL);
694 }
695 }
696
697 opt_match_per_stream_str(ost, &o->frame_pix_fmts, oc, st, &frame_pix_fmt);
698 if (frame_pix_fmt && *frame_pix_fmt == '+') {
699 *keep_pix_fmt = 1;
700 if (!*++frame_pix_fmt)
701 frame_pix_fmt = NULL;
702 }
703 if (frame_pix_fmt) {
704 video_enc->pix_fmt = pix_fmt_parse(ost, frame_pix_fmt);
705 if (video_enc->pix_fmt == AV_PIX_FMT_NONE)
706 return AVERROR(EINVAL);
707 }
708
709 opt_match_per_stream_str(ost, &o->intra_matrices, oc, st, &intra_matrix);
710 if (intra_matrix) {
711 if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64)))
712 return AVERROR(ENOMEM);
713
714 ret = parse_matrix_coeffs(ost, video_enc->intra_matrix, intra_matrix);
715 if (ret < 0)
716 return ret;
717 }
718 opt_match_per_stream_str(ost, &o->chroma_intra_matrices, oc, st, &chroma_intra_matrix);
719 if (chroma_intra_matrix) {
720 if (!(video_enc->chroma_intra_matrix = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64)))
721 return AVERROR(ENOMEM);
722 ret = parse_matrix_coeffs(ost, video_enc->chroma_intra_matrix, chroma_intra_matrix);
723 if (ret < 0)
724 return ret;
725 }
726 opt_match_per_stream_str(ost, &o->inter_matrices, oc, st, &inter_matrix);
727 if (inter_matrix) {
728 if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64)))
729 return AVERROR(ENOMEM);
730 ret = parse_matrix_coeffs(ost, video_enc->inter_matrix, inter_matrix);
731 if (ret < 0)
732 return ret;
733 }
734
735 opt_match_per_stream_str(ost, &o->rc_overrides, oc, st, &p);
736 for (i = 0; p; i++) {
737 int start, end, q;
738 int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
739 if (e != 3) {
740 av_log(ost, AV_LOG_FATAL, "error parsing rc_override\n");
741 return AVERROR(EINVAL);
742 }
743 video_enc->rc_override =
744 av_realloc_array(video_enc->rc_override,
745 i + 1, sizeof(RcOverride));
746 if (!video_enc->rc_override) {
747 av_log(ost, AV_LOG_FATAL, "Could not (re)allocate memory for rc_override.\n");
748 return AVERROR(ENOMEM);
749 }
750 video_enc->rc_override[i].start_frame = start;
751 video_enc->rc_override[i].end_frame = end;
752 if (q > 0) {
753 video_enc->rc_override[i].qscale = q;
754 video_enc->rc_override[i].quality_factor = 1.0;
755 }
756 else {
757 video_enc->rc_override[i].qscale = 0;
758 video_enc->rc_override[i].quality_factor = -q/100.0;
759 }
760 p = strchr(p, '/');
761 if (p) p++;
762 }
763 video_enc->rc_override_count = i;
764
765 /* two pass mode */
766 opt_match_per_stream_int(ost, &o->pass, oc, st, &do_pass);
767 if (do_pass) {
768 if (do_pass & 1)
769 video_enc->flags |= AV_CODEC_FLAG_PASS1;
770 if (do_pass & 2)
771 video_enc->flags |= AV_CODEC_FLAG_PASS2;
772 }
773
774 opt_match_per_stream_str(ost, &o->passlogfiles, oc, st, &ost->logfile_prefix);
775 if (ost->logfile_prefix &&
776 !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
777 return AVERROR(ENOMEM);
778
779 if (do_pass) {
780 int ost_idx = -1;
781 char logfilename[1024];
782 FILE *f;
783
784 /* compute this stream's global index */
785 for (int idx = 0; idx <= ost->file->index; idx++)
786 ost_idx += output_files[idx]->nb_streams;
787
788 snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
789 ost->logfile_prefix ? ost->logfile_prefix :
791 ost_idx);
792 if (!strcmp(video_enc->codec->name, "libx264") || !strcmp(video_enc->codec->name, "libvvenc")) {
793 if (av_opt_is_set_to_default_by_name(video_enc, "stats",
795 av_opt_set(video_enc, "stats", logfilename,
797 } else if (!strcmp(video_enc->codec->name, "libx265")) {
798 if (av_opt_is_set_to_default_by_name(video_enc, "x265-stats",
800 av_opt_set(video_enc, "x265-stats", logfilename,
802 } else {
803 if (video_enc->flags & AV_CODEC_FLAG_PASS2) {
804 char *logbuffer = read_file_to_string(logfilename);
805
806 if (!logbuffer) {
807 av_log(ost, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
808 logfilename);
809 return AVERROR(EIO);
810 }
811 video_enc->stats_in = logbuffer;
812 }
813 if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
814 f = fopen_utf8(logfilename, "wb");
815 if (!f) {
817 "Cannot write log file '%s' for pass-1 encoding: %s\n",
818 logfilename, strerror(errno));
819 return AVERROR(errno);
820 }
821 ost->logfile = f;
822 }
823 }
824 }
825
827
828 *vsync_method = VSYNC_AUTO;
829 opt_match_per_stream_str(ost, &o->fps_mode, oc, st, &fps_mode);
830 if (fps_mode) {
831 ret = parse_and_set_vsync(fps_mode, vsync_method, ost->file->index, ost->index);
832 if (ret < 0)
833 return ret;
834 }
835
836 if ((ms->frame_rate.num || ms->max_frame_rate.num) &&
837 !(*vsync_method == VSYNC_AUTO ||
838 *vsync_method == VSYNC_CFR || *vsync_method == VSYNC_VSCFR)) {
839 av_log(ost, AV_LOG_FATAL, "One of -r/-fpsmax was specified "
840 "together a non-CFR -vsync/-fps_mode. This is contradictory.\n");
841 return AVERROR(EINVAL);
842 }
843
844 if (*vsync_method == VSYNC_AUTO) {
845 if (ms->frame_rate.num || ms->max_frame_rate.num) {
846 *vsync_method = VSYNC_CFR;
847 } else if (!strcmp(oc->oformat->name, "avi")) {
848 *vsync_method = VSYNC_VFR;
849 } else {
850 *vsync_method = (oc->oformat->flags & AVFMT_VARIABLE_FPS) ?
853 }
854
855 if (ost->ist && *vsync_method == VSYNC_CFR) {
856 const InputFile *ifile = ost->ist->file;
857
858 if (ifile->nb_streams == 1 && ifile->input_ts_offset == 0)
859 *vsync_method = VSYNC_VSCFR;
860 }
861
862 if (*vsync_method == VSYNC_CFR && copy_ts) {
863 *vsync_method = VSYNC_VSCFR;
864 }
865 }
866 }
867
868 return 0;
869}
870
871static int new_stream_audio(Muxer *mux, const OptionsContext *o,
873{
875 AVFormatContext *oc = mux->fc;
876 AVStream *st = ost->st;
877
878 if (ost->enc) {
879 AVCodecContext *audio_enc = ost->enc->enc_ctx;
880 int channels = 0;
881 const char *layout = NULL;
882 const char *sample_fmt = NULL;
883
885 if (channels) {
887 audio_enc->ch_layout.nb_channels = channels;
888 }
889
891 if (layout && av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) {
892 av_log(ost, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout);
893 return AVERROR(EINVAL);
894 }
895
896 opt_match_per_stream_str(ost, &o->sample_fmts, oc, st, &sample_fmt);
897 if (sample_fmt &&
898 (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
899 av_log(ost, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
900 return AVERROR(EINVAL);
901 }
902
904 opt_match_per_stream_str(ost, &o->apad, oc, st, &ms->apad);
905 }
906
907 return 0;
908}
909
910static int new_stream_subtitle(Muxer *mux, const OptionsContext *o,
912{
913 AVStream *st;
914
915 st = ost->st;
916
917 if (ost->enc) {
918 AVCodecContext *subtitle_enc = ost->enc->enc_ctx;
919
920 AVCodecDescriptor const *input_descriptor =
921 avcodec_descriptor_get(ost->ist->par->codec_id);
922 AVCodecDescriptor const *output_descriptor =
923 avcodec_descriptor_get(subtitle_enc->codec_id);
924 int input_props = 0, output_props = 0;
925
926 const char *frame_size = NULL;
927
929 if (frame_size) {
930 int ret = av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size);
931 if (ret < 0) {
932 av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
933 return ret;
934 }
935 }
936 if (input_descriptor)
937 input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
938 if (output_descriptor)
939 output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
940 if (input_props && output_props && input_props != output_props) {
942 "Subtitle encoding currently only possible from text to text "
943 "or bitmap to bitmap\n");
944 return AVERROR(EINVAL);
945 }
946 }
947
948 return 0;
949}
950
951static int
952ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter,
953 const OptionsContext *o,
954 AVRational enc_tb, enum VideoSyncMethod vsync_method,
955 int keep_pix_fmt, int autoscale, int threads_manual,
956 const ViewSpecifier *vs,
958{
959 OutputStream *ost = &ms->ost;
960 AVCodecContext *enc_ctx = ost->enc->enc_ctx;
961 char name[16];
962 char *filters = NULL;
963 int ret;
964
966 .enc = enc_ctx->codec,
967 .name = name,
968 .format = (ost->type == AVMEDIA_TYPE_VIDEO) ?
969 enc_ctx->pix_fmt : enc_ctx->sample_fmt,
970 .width = enc_ctx->width,
971 .height = enc_ctx->height,
972 .color_space = enc_ctx->colorspace,
973 .color_range = enc_ctx->color_range,
974 .alpha_mode = enc_ctx->alpha_mode,
975 .chroma_location = enc_ctx->chroma_sample_location,
976 .vsync_method = vsync_method,
977 .frame_rate = ms->frame_rate,
978 .max_frame_rate = ms->max_frame_rate,
979 .sample_rate = enc_ctx->sample_rate,
980 .ch_layout = enc_ctx->ch_layout,
981 .sws_opts = o->g->sws_dict,
982 .swr_opts = o->g->swr_opts,
983 .output_tb = enc_tb,
984 .trim_start_us = mux->of.start_time,
985 .trim_duration_us = mux->of.recording_time,
986 .ts_offset = mux->of.start_time == AV_NOPTS_VALUE ?
987 0 : mux->of.start_time,
988 .vs = vs,
989 .nb_threads = -1,
990 .reinit_opts = ost->enc->reinit_opts,
991
992 .flags = OFILTER_FLAG_DISABLE_CONVERT * !!keep_pix_fmt |
993 OFILTER_FLAG_AUTOSCALE * !!autoscale |
995 };
996
997 snprintf(name, sizeof(name), "#%d:%d", mux->of.index, ost->index);
998
999 if (ost->type == AVMEDIA_TYPE_VIDEO) {
1000 if (!keep_pix_fmt) {
1001 ret = avcodec_get_supported_config(enc_ctx, NULL,
1003 (const void **) &opts.pix_fmts, NULL);
1004 if (ret < 0)
1005 return ret;
1006 }
1007 if (!ms->force_fps) {
1008 ret = avcodec_get_supported_config(enc_ctx, NULL,
1010 (const void **) &opts.frame_rates, NULL);
1011 if (ret < 0)
1012 return ret;
1013 }
1014 ret = avcodec_get_supported_config(enc_ctx, NULL,
1016 (const void **) &opts.color_spaces, NULL);
1017 if (ret < 0)
1018 return ret;
1019 ret = avcodec_get_supported_config(enc_ctx, NULL,
1021 (const void **) &opts.color_ranges, NULL);
1022 if (ret < 0)
1023 return ret;
1024 ret = avcodec_get_supported_config(enc_ctx, NULL,
1026 (const void **) &opts.alpha_modes, NULL);
1027 if (ret < 0)
1028 return ret;
1029 ret = avcodec_get_supported_config(enc_ctx, NULL,
1031 (const void **) &opts.chroma_locations, NULL);
1032 if (ret < 0)
1033 return ret;
1034 } else {
1035 ret = avcodec_get_supported_config(enc_ctx, NULL,
1037 (const void **) &opts.sample_fmts, NULL);
1038 if (ret < 0)
1039 return ret;
1040 ret = avcodec_get_supported_config(enc_ctx, NULL,
1042 (const void **) &opts.sample_rates, NULL);
1043 if (ret < 0)
1044 return ret;
1045 ret = avcodec_get_supported_config(enc_ctx, NULL,
1047 (const void **) &opts.ch_layouts, NULL);
1048 if (ret < 0)
1049 return ret;
1050 }
1051
1052 if (threads_manual) {
1053 ret = av_opt_get_int(enc_ctx, "threads", 0, &opts.nb_threads);
1054 if (ret < 0)
1055 return ret;
1056 }
1057
1058 ret = ost_get_filters(o, mux->fc, ost, &filters);
1059 if (ret < 0)
1060 return ret;
1061
1062 if (ofilter) {
1064 ost->filter = ofilter;
1065 ret = ofilter_bind_enc(ofilter, ms->sch_idx_enc, &opts);
1066 } else {
1067 ret = fg_create_simple(&ost->fg_simple, ost->ist, &filters,
1068 mux->sch, ms->sch_idx_enc, &opts);
1069 if (ret >= 0)
1070 ost->filter = ost->fg_simple->outputs[0];
1071
1072 }
1073 if (ret < 0)
1074 return ret;
1075
1076 *src = SCH_ENC(ms->sch_idx_enc);
1077
1078 return 0;
1079}
1080
1081static int streamcopy_init(const OptionsContext *o, const Muxer *mux,
1082 OutputStream *ost, AVDictionary **encoder_opts)
1083{
1084 MuxStream *ms = ms_from_ost(ost);
1085
1086 const InputStream *ist = ost->ist;
1087 const InputFile *ifile = ist->file;
1088
1089 AVCodecParameters *par = ms->par_in;
1090 uint32_t codec_tag = par->codec_tag;
1091
1092 AVCodecContext *codec_ctx = NULL;
1093
1094 AVRational fr = ms->frame_rate;
1095
1096 int ret = 0;
1097
1098 const char *filters = NULL;
1099 opt_match_per_stream_str(ost, &o->filters, mux->fc, ost->st, &filters);
1100
1101 if (filters) {
1103 "Filtergraph '%s' was specified, but codec copy was selected. "
1104 "Filtering and streamcopy cannot be used together.\n", filters);
1105 return AVERROR(EINVAL);
1106 }
1107
1108 codec_ctx = avcodec_alloc_context3(NULL);
1109 if (!codec_ctx)
1110 return AVERROR(ENOMEM);
1111
1112 ret = avcodec_parameters_to_context(codec_ctx, ist->par);
1113 if (ret >= 0)
1114 ret = av_opt_set_dict(codec_ctx, encoder_opts);
1115 if (ret < 0) {
1117 "Error setting up codec context options.\n");
1118 goto fail;
1119 }
1120
1121 ret = avcodec_parameters_from_context(par, codec_ctx);
1122 if (ret < 0) {
1124 "Error getting reference codec parameters.\n");
1125 goto fail;
1126 }
1127
1128 if (!codec_tag) {
1129 const struct AVCodecTag * const *ct = mux->fc->oformat->codec_tag;
1130 unsigned int codec_tag_tmp;
1131 if (!ct || av_codec_get_id (ct, par->codec_tag) == par->codec_id ||
1132 !av_codec_get_tag2(ct, par->codec_id, &codec_tag_tmp))
1133 codec_tag = par->codec_tag;
1134 }
1135
1136 par->codec_tag = codec_tag;
1137
1138 if (!fr.num)
1139 fr = ist->framerate;
1140
1141 if (fr.num)
1142 ost->st->avg_frame_rate = fr;
1143 else
1144 ost->st->avg_frame_rate = ist->st->avg_frame_rate;
1145
1146 // copy timebase while removing common factors
1147 if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) {
1148 if (fr.num)
1149 ost->st->time_base = av_inv_q(fr);
1150 else
1151 ost->st->time_base = av_add_q(ist->st->time_base, (AVRational){0, 1});
1152 }
1153
1154 if (!ms->copy_prior_start) {
1155 ms->ts_copy_start = (mux->of.start_time == AV_NOPTS_VALUE) ?
1156 0 : mux->of.start_time;
1157 if (copy_ts && ifile->start_time != AV_NOPTS_VALUE) {
1159 ifile->start_time + ifile->ts_offset);
1160 }
1161 }
1162
1163 for (int i = 0; i < ist->st->codecpar->nb_coded_side_data; i++) {
1164 const AVPacketSideData *sd_src = &ist->st->codecpar->coded_side_data[i];
1165 AVPacketSideData *sd_dst;
1166
1167 sd_dst = av_packet_side_data_new(&ost->st->codecpar->coded_side_data,
1168 &ost->st->codecpar->nb_coded_side_data,
1169 sd_src->type, sd_src->size, 0);
1170 if (!sd_dst) {
1171 ret = AVERROR(ENOMEM);
1172 goto fail;
1173 }
1174 memcpy(sd_dst->data, sd_src->data, sd_src->size);
1175 }
1176
1177 switch (par->codec_type) {
1178 case AVMEDIA_TYPE_AUDIO:
1179 if ((par->block_align == 1 || par->block_align == 1152 || par->block_align == 576) &&
1180 par->codec_id == AV_CODEC_ID_MP3)
1181 par->block_align = 0;
1182 if (par->codec_id == AV_CODEC_ID_AC3)
1183 par->block_align = 0;
1184 break;
1185 case AVMEDIA_TYPE_VIDEO: {
1186 AVRational sar;
1187 if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option
1188 sar =
1189 av_mul_q(ost->frame_aspect_ratio,
1190 (AVRational){ par->height, par->width });
1191 av_log(ost, AV_LOG_WARNING, "Overriding aspect ratio "
1192 "with stream copy may produce invalid files\n");
1193 }
1194 else if (ist->st->sample_aspect_ratio.num)
1195 sar = ist->st->sample_aspect_ratio;
1196 else
1197 sar = par->sample_aspect_ratio;
1198 ost->st->sample_aspect_ratio = par->sample_aspect_ratio = sar;
1199 ost->st->r_frame_rate = ist->st->r_frame_rate;
1200 break;
1201 }
1202 }
1203
1204fail:
1205 avcodec_free_context(&codec_ctx);
1206 return ret;
1207}
1208
1209static int set_encoder_id(OutputStream *ost, const AVCodec *codec)
1210{
1211 const char *cname = codec->name;
1212 uint8_t *encoder_string;
1213 int encoder_string_len;
1214
1215 encoder_string_len = sizeof(LIBAVCODEC_IDENT) + strlen(cname) + 2;
1216 encoder_string = av_mallocz(encoder_string_len);
1217 if (!encoder_string)
1218 return AVERROR(ENOMEM);
1219
1220 if (!ost->file->bitexact && !ost->bitexact)
1221 av_strlcpy(encoder_string, LIBAVCODEC_IDENT " ", encoder_string_len);
1222 else
1223 av_strlcpy(encoder_string, "Lavc ", encoder_string_len);
1224 av_strlcat(encoder_string, cname, encoder_string_len);
1225 av_dict_set(&ost->st->metadata, "encoder", encoder_string,
1227
1228 return 0;
1229}
1230
1231static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type,
1232 InputStream *ist, OutputFilter *ofilter, const ViewSpecifier *vs,
1233 OutputStream **post)
1234{
1235 AVFormatContext *oc = mux->fc;
1236 MuxStream *ms;
1238 const AVCodec *enc;
1239 AVStream *st;
1240 SchedulerNode src = { .type = SCH_NODE_TYPE_NONE };
1241 AVDictionary *encoder_opts = NULL;
1242 int ret = 0, keep_pix_fmt = 0, autoscale = 1;
1243 int threads_manual = 0;
1244 AVRational enc_tb = { 0, 0 };
1245 enum VideoSyncMethod vsync_method = VSYNC_AUTO;
1246 const char *bsfs = NULL, *time_base = NULL, *codec_tag = NULL, *manual_disp = NULL;
1247 char *next;
1248 double qscale = -1;
1249
1250 st = avformat_new_stream(oc, NULL);
1251 if (!st)
1252 return AVERROR(ENOMEM);
1253
1254 ms = mux_stream_alloc(mux, type);
1255 if (!ms)
1256 return AVERROR(ENOMEM);
1257
1258 // only streams with sources (i.e. not attachments)
1259 // are handled by the scheduler
1260 if (ist || ofilter) {
1262 if (ret < 0)
1263 return ret;
1264
1265 ret = sch_add_mux_stream(mux->sch, mux->sch_idx);
1266 if (ret < 0)
1267 return ret;
1268
1269 av_assert0(ret == mux->nb_sch_stream_idx - 1);
1270 mux->sch_stream_idx[ret] = ms->ost.index;
1271 ms->sch_idx = ret;
1272 }
1273
1274 ost = &ms->ost;
1275
1276 if (o->streamid) {
1278 char idx[16], *p;
1279 snprintf(idx, sizeof(idx), "%d", ost->index);
1280
1281 e = av_dict_get(o->streamid, idx, NULL, 0);
1282 if (e) {
1283 st->id = strtol(e->value, &p, 0);
1284 if (!e->value[0] || *p) {
1285 av_log(ost, AV_LOG_FATAL, "Invalid stream id: %s\n", e->value);
1286 return AVERROR(EINVAL);
1287 }
1288 }
1289 }
1290
1292 if (!ms->par_in)
1293 return AVERROR(ENOMEM);
1294
1296
1297 ost->st = st;
1298 ost->ist = ist;
1299 ost->kf.ref_pts = AV_NOPTS_VALUE;
1300 ms->par_in->codec_type = type;
1301 st->codecpar->codec_type = type;
1302
1303 if (ost->type == AVMEDIA_TYPE_VIDEO) {
1304 if (ost->ist)
1305 ost->st->disposition = ost->ist->st->disposition;
1306
1307 opt_match_per_stream_str(ost, &o->disposition, oc, st, &manual_disp);
1308 if (manual_disp) {
1309 ret = av_opt_set(ost->st, "disposition", manual_disp, 0);
1310 if (ret < 0)
1311 return ret;
1312 }
1313
1314 ost->st->disposition &= AV_DISPOSITION_ATTACHED_PIC;
1315 }
1316
1317 ret = choose_encoder(o, oc, ms, &enc);
1318 if (ret < 0) {
1319 av_log(ost, AV_LOG_FATAL, "Error selecting an encoder\n");
1320 return ret;
1321 }
1322
1323 if (enc) {
1324 ret = sch_add_enc(mux->sch, encoder_thread, ost,
1325 ost->type == AVMEDIA_TYPE_SUBTITLE ? NULL : enc_open);
1326 if (ret < 0)
1327 return ret;
1328 ms->sch_idx_enc = ret;
1329
1330 ret = enc_alloc(&ost->enc, enc, mux->sch, ms->sch_idx_enc, ost);
1331 if (ret < 0)
1332 return ret;
1333
1334 av_strlcat(ms->log_name, "/", sizeof(ms->log_name));
1335 av_strlcat(ms->log_name, enc->name, sizeof(ms->log_name));
1336 } else {
1337 if (ofilter) {
1339 "Streamcopy requested for output stream fed "
1340 "from a complex filtergraph. Filtering and streamcopy "
1341 "cannot be used together.\n");
1342 return AVERROR(EINVAL);
1343 }
1344
1345 av_strlcat(ms->log_name, "/copy", sizeof(ms->log_name));
1346 }
1347
1348 av_log(ost, AV_LOG_VERBOSE, "Created %s stream from ",
1350 if (ist)
1351 av_log(ost, AV_LOG_VERBOSE, "input stream %d:%d",
1352 ist->file->index, ist->index);
1353 else if (ofilter)
1354 av_log(ost, AV_LOG_VERBOSE, "complex filtergraph %d:[%s]",
1355 ofilter->graph->index, ofilter->name);
1356 else if (type == AVMEDIA_TYPE_ATTACHMENT)
1357 av_log(ost, AV_LOG_VERBOSE, "attached file");
1358 else av_assert0(0);
1359 av_log(ost, AV_LOG_VERBOSE, "\n");
1360
1361 ms->pkt = av_packet_alloc();
1362 if (!ms->pkt)
1363 return AVERROR(ENOMEM);
1364
1365 if (ost->enc) {
1366 AVIOContext *s = NULL;
1367 char *buf = NULL, *arg = NULL;
1368 const char *enc_stats_pre = NULL, *enc_stats_post = NULL, *mux_stats = NULL;
1369 const char *enc_time_base = NULL, *enc_reinit_opts = NULL, *preset = NULL;
1370
1371 ret = filter_codec_opts(o->g->codec_opts, enc->id,
1372 oc, st, enc, &encoder_opts,
1373 &mux->enc_opts_used);
1374 if (ret < 0)
1375 goto fail;
1376
1378 opt_match_per_stream_int(ost, &o->autoscale, oc, st, &autoscale);
1379 if (preset && (!(ret = get_preset_file_2(preset, enc->name, &s)))) {
1380 AVBPrint bprint;
1382 do {
1383 av_bprint_clear(&bprint);
1384 buf = get_line(s, &bprint);
1385 if (!buf) {
1386 ret = AVERROR(ENOMEM);
1387 break;
1388 }
1389
1390 if (!buf[0] || buf[0] == '#')
1391 continue;
1392 if (!(arg = strchr(buf, '='))) {
1393 av_log(ost, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
1394 ret = AVERROR(EINVAL);
1395 break;
1396 }
1397 *arg++ = 0;
1398 av_dict_set(&encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE);
1399 } while (!s->eof_reached);
1400 av_bprint_finalize(&bprint, NULL);
1401 avio_closep(&s);
1402 }
1403 if (ret) {
1405 "Preset %s specified, but could not be opened.\n", preset);
1406 goto fail;
1407 }
1408
1409 opt_match_per_stream_str(ost, &o->enc_reinit_opts, oc, st, &enc_reinit_opts);
1410 if (enc_reinit_opts &&
1412 ost->enc->reinit_opts = av_strdup(enc_reinit_opts);
1413 if (!ost->enc->reinit_opts) {
1414 ret = AVERROR(ENOMEM);
1415 goto fail;
1416 }
1417 }
1418
1419 opt_match_per_stream_str(ost, &o->enc_stats_pre, oc, st, &enc_stats_pre);
1420 if (enc_stats_pre &&
1422 const char *format = "{fidx} {sidx} {n} {t}";
1423
1425
1426 ret = enc_stats_init(ost, &ost->enc_stats_pre, 1, enc_stats_pre, format);
1427 if (ret < 0)
1428 goto fail;
1429 }
1430
1431 opt_match_per_stream_str(ost, &o->enc_stats_post, oc, st, &enc_stats_post);
1432 if (enc_stats_post &&
1434 const char *format = "{fidx} {sidx} {n} {t}";
1435
1437
1438 ret = enc_stats_init(ost, &ost->enc_stats_post, 0, enc_stats_post, format);
1439 if (ret < 0)
1440 goto fail;
1441 }
1442
1443 opt_match_per_stream_str(ost, &o->mux_stats, oc, st, &mux_stats);
1444 if (mux_stats &&
1446 const char *format = "{fidx} {sidx} {n} {t}";
1447
1449
1450 ret = enc_stats_init(ost, &ms->stats, 0, mux_stats, format);
1451 if (ret < 0)
1452 goto fail;
1453 }
1454
1455 opt_match_per_stream_str(ost, &o->enc_time_bases, oc, st, &enc_time_base);
1456 if (enc_time_base && type == AVMEDIA_TYPE_SUBTITLE)
1458 "-enc_time_base not supported for subtitles, ignoring\n");
1459 else if (enc_time_base) {
1460 AVRational q;
1461
1462 if (!strcmp(enc_time_base, "demux")) {
1463 q = (AVRational){ ENC_TIME_BASE_DEMUX, 0 };
1464 } else if (!strcmp(enc_time_base, "filter")) {
1465 q = (AVRational){ ENC_TIME_BASE_FILTER, 0 };
1466 } else {
1467 ret = av_parse_ratio(&q, enc_time_base, INT_MAX, 0, NULL);
1468 if (ret < 0 || q.den <= 0 || q.num < 0) {
1469 av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", enc_time_base);
1470 ret = ret < 0 ? ret : AVERROR(EINVAL);
1471 goto fail;
1472 }
1473 }
1474
1475 enc_tb = q;
1476 }
1477
1478 threads_manual = !!av_dict_get(encoder_opts, "threads", NULL, 0);
1479
1480 ret = av_dict_copy(&ost->enc->encoder_opts, encoder_opts, 0);
1481 if (ret < 0)
1482 goto fail;
1483 ret = av_opt_set_dict2(ost->enc->enc_ctx, &encoder_opts, AV_OPT_SEARCH_CHILDREN);
1484 if (ret < 0) {
1485 av_log(ost, AV_LOG_ERROR, "Error applying encoder options: %s\n",
1486 av_err2str(ret));
1487 goto fail;
1488 }
1489
1490 ret = check_avoptions(encoder_opts);
1491 if (ret < 0)
1492 goto fail;
1493
1494 // default to automatic thread count
1495 if (!threads_manual)
1496 ost->enc->enc_ctx->thread_count = 0;
1497 } else {
1499 NULL, &encoder_opts,
1500 &mux->enc_opts_used);
1501 if (ret < 0)
1502 goto fail;
1503 }
1504
1505
1506 if (o->bitexact) {
1507 ost->bitexact = 1;
1508 } else if (ost->enc) {
1509 ost->bitexact = !!(ost->enc->enc_ctx->flags & AV_CODEC_FLAG_BITEXACT);
1510 }
1511
1512 if (enc) {
1513 ret = set_encoder_id(ost, enc);
1514 if (ret < 0)
1515 return ret;
1516 }
1517
1518 opt_match_per_stream_str(ost, &o->time_bases, oc, st, &time_base);
1519 if (time_base) {
1520 AVRational q;
1521 if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
1522 q.num <= 0 || q.den <= 0) {
1523 av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
1524 ret = AVERROR(EINVAL);
1525 goto fail;
1526 }
1527 st->time_base = q;
1528 }
1529
1530 ms->max_frames = INT64_MAX;
1532 for (int i = 0; i < o->max_frames.nb_opt; i++) {
1533 char *p = o->max_frames.opt[i].specifier;
1534 if (!*p && type != AVMEDIA_TYPE_VIDEO) {
1535 av_log(ost, AV_LOG_WARNING, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n");
1536 break;
1537 }
1538 }
1539
1540 ms->copy_prior_start = -1;
1542 opt_match_per_stream_str(ost, &o->bitstream_filters, oc, st, &bsfs);
1543 if (bsfs && *bsfs) {
1544 ret = av_bsf_list_parse_str(bsfs, &ms->bsf_ctx);
1545 if (ret < 0) {
1546 av_log(ost, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret));
1547 goto fail;
1548 }
1549 }
1550
1551 opt_match_per_stream_str(ost, &o->codec_tags, oc, st, &codec_tag);
1552 if (codec_tag) {
1553 uint32_t tag = strtol(codec_tag, &next, 0);
1554 if (*next) {
1555 uint8_t buf[4] = { 0 };
1556 memcpy(buf, codec_tag, FFMIN(sizeof(buf), strlen(codec_tag)));
1557 tag = AV_RL32(buf);
1558 }
1559 ost->st->codecpar->codec_tag = tag;
1560 ms->par_in->codec_tag = tag;
1561 if (ost->enc)
1562 ost->enc->codec_tag = tag;
1563 }
1564
1565 opt_match_per_stream_dbl(ost, &o->qscale, oc, st, &qscale);
1566 if (ost->enc) {
1567 if (qscale >= 0) {
1568 ost->enc->flags |= AV_CODEC_FLAG_QSCALE;
1569 ost->enc->global_quality = FF_QP2LAMBDA * qscale;
1570 } else
1571 ost->enc->global_quality = ost->enc->enc_ctx->global_quality;
1572 }
1573
1574 if (ms->sch_idx >= 0) {
1575 int max_muxing_queue_size = 128;
1576 int muxing_queue_data_threshold = 50 * 1024 * 1024;
1577
1579 &max_muxing_queue_size);
1581 oc, st, &muxing_queue_data_threshold);
1582
1584 max_muxing_queue_size, muxing_queue_data_threshold);
1585 }
1586
1588 &ost->bits_per_raw_sample);
1589
1591 oc, st, &ost->fix_sub_duration_heartbeat);
1592
1593 if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->enc)
1594 ost->enc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1595 if (oc->oformat->flags & AVFMT_FIXED_FRAMESIZE && ost->enc)
1596 ost->enc->flags2 |= AV_CODEC_FLAG2_FIXED_FRAME_SIZE;
1597
1599 oc, st, &ms->copy_initial_nonkeyframes);
1600 switch (type) {
1601 case AVMEDIA_TYPE_VIDEO: ret = new_stream_video (mux, o, ost, &keep_pix_fmt, &vsync_method); break;
1602 case AVMEDIA_TYPE_AUDIO: ret = new_stream_audio (mux, o, ost); break;
1603 case AVMEDIA_TYPE_SUBTITLE: ret = new_stream_subtitle (mux, o, ost); break;
1604 }
1605 if (ret < 0)
1606 goto fail;
1607
1608 if (ost->enc &&
1610 ret = ost_bind_filter(mux, ms, ofilter, o, enc_tb, vsync_method,
1611 keep_pix_fmt, autoscale, threads_manual, vs, &src);
1612 if (ret < 0)
1613 goto fail;
1614 } else if (ost->ist) {
1615 ret = ist_use(ost->ist, !!ost->enc, NULL, &src);
1616 if (ret < 0) {
1618 "Error binding an input stream\n");
1619 goto fail;
1620 }
1621 ms->sch_idx_src = src.idx;
1622
1623 // src refers to a decoder for transcoding, demux stream otherwise
1624 if (ost->enc) {
1625 ret = sch_connect(mux->sch,
1626 src, SCH_ENC(ms->sch_idx_enc));
1627 if (ret < 0)
1628 goto fail;
1629 src = SCH_ENC(ms->sch_idx_enc);
1630 }
1631 }
1632
1633 if (src.type != SCH_NODE_TYPE_NONE) {
1634 ret = sch_connect(mux->sch,
1635 src, SCH_MSTREAM(mux->sch_idx, ms->sch_idx));
1636 if (ret < 0)
1637 goto fail;
1638 } else {
1639 // only attachment streams don't have a source
1641 }
1642
1643 if (ost->ist && !ost->enc) {
1644 ret = streamcopy_init(o, mux, ost, &encoder_opts);
1645 if (ret < 0)
1646 goto fail;
1647 }
1648
1649 // copy estimated duration as a hint to the muxer
1650 if (ost->ist && ost->ist->st->duration > 0) {
1651 ms->stream_duration = ist->st->duration;
1652 ms->stream_duration_tb = ist->st->time_base;
1653 }
1654
1655 if (post)
1656 *post = ost;
1657
1658 ret = 0;
1659
1660fail:
1661 av_dict_free(&encoder_opts);
1662
1663 return ret;
1664}
1665
1666static int map_auto_video(Muxer *mux, const OptionsContext *o)
1667{
1668 AVFormatContext *oc = mux->fc;
1669 InputStreamGroup *best_istg = NULL;
1670 InputStream *best_ist = NULL;
1671 int64_t best_score = 0;
1672 int qcr;
1673
1674 /* video: highest resolution */
1676 return 0;
1677
1678 qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
1679 for (int j = 0; j < nb_input_files; j++) {
1680 InputFile *ifile = input_files[j];
1681 InputStreamGroup *file_best_istg = NULL;
1682 InputStream *file_best_ist = NULL;
1683 int64_t file_best_score = 0;
1684 for (int i = 0; i < ifile->nb_stream_groups; i++) {
1685 InputStreamGroup *istg = ifile->stream_groups[i];
1686 int64_t score = 0;
1687
1688 if (!istg->fg)
1689 continue;
1690
1691 for (int j = 0; j < istg->stg->nb_streams; j++) {
1692 AVStream *st = istg->stg->streams[j];
1693
1695 score = 100000000;
1696 break;
1697 }
1698 }
1699
1700 switch (istg->stg->type) {
1702 const AVStreamGroupTileGrid *tg = istg->stg->params.tile_grid;
1703 score += tg->width * (int64_t)tg->height
1704 + 5000000*!!(istg->stg->disposition & AV_DISPOSITION_DEFAULT);
1705 break;
1706 }
1707 default:
1708 continue;
1709 }
1710
1711 if (score > file_best_score) {
1712 file_best_score = score;
1713 file_best_istg = istg;
1714 }
1715 }
1716 for (int i = 0; i < ifile->nb_streams; i++) {
1717 InputStream *ist = ifile->streams[i];
1719 int64_t score;
1720
1721 if (ist->user_set_discard == AVDISCARD_ALL ||
1723 (desc && (desc->props & AV_CODEC_PROP_ENHANCEMENT)))
1724 continue;
1725
1726 score = ist->st->codecpar->width * (int64_t)ist->st->codecpar->height
1727 + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
1728 + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
1729 if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1730 score = 1;
1731
1732 if (score > file_best_score) {
1733 if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1734 continue;
1735 file_best_score = score;
1736 file_best_ist = ist;
1737 file_best_istg = NULL;
1738 }
1739 }
1740 if (file_best_istg) {
1741 file_best_score -= 5000000*!!(file_best_istg->stg->disposition & AV_DISPOSITION_DEFAULT);
1742 if (file_best_score > best_score) {
1743 best_score = file_best_score;
1744 best_istg = file_best_istg;
1745 best_ist = NULL;
1746 }
1747 }
1748 if (file_best_ist) {
1749 if((qcr == MKTAG('A', 'P', 'I', 'C')) ||
1750 !(file_best_ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1751 file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT);
1752 if (file_best_score > best_score) {
1753 best_score = file_best_score;
1754 best_ist = file_best_ist;
1755 best_istg = NULL;
1756 }
1757 }
1758 }
1759 if (best_istg) {
1760 FilterGraph *fg = best_istg->fg;
1761 OutputFilter *ofilter = fg->outputs[0];
1762
1763 av_assert0(fg->nb_outputs == 1);
1764 av_log(mux, AV_LOG_VERBOSE, "Creating output stream from stream group derived complex filtergraph %d.\n", fg->index);
1765
1766 return ost_add(mux, o, AVMEDIA_TYPE_VIDEO, NULL, ofilter, NULL, NULL);
1767 }
1768 if (best_ist)
1769 return ost_add(mux, o, AVMEDIA_TYPE_VIDEO, best_ist, NULL, NULL, NULL);
1770
1771 return 0;
1772}
1773
1774static int map_auto_audio(Muxer *mux, const OptionsContext *o)
1775{
1776 AVFormatContext *oc = mux->fc;
1777 InputStream *best_ist = NULL;
1778 int best_score = 0;
1779
1780 /* audio: most channels */
1782 return 0;
1783
1784 for (int j = 0; j < nb_input_files; j++) {
1785 InputFile *ifile = input_files[j];
1786 InputStream *file_best_ist = NULL;
1787 int file_best_score = 0;
1788 for (int i = 0; i < ifile->nb_streams; i++) {
1789 InputStream *ist = ifile->streams[i];
1790 int score;
1791
1792 if (ist->user_set_discard == AVDISCARD_ALL ||
1794 continue;
1795
1796 score = ist->st->codecpar->ch_layout.nb_channels
1797 + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
1798 + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
1799 if (score > file_best_score) {
1800 file_best_score = score;
1801 file_best_ist = ist;
1802 }
1803 }
1804 if (file_best_ist) {
1805 file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT);
1806 if (file_best_score > best_score) {
1807 best_score = file_best_score;
1808 best_ist = file_best_ist;
1809 }
1810 }
1811 }
1812 if (best_ist)
1813 return ost_add(mux, o, AVMEDIA_TYPE_AUDIO, best_ist, NULL, NULL, NULL);
1814
1815 return 0;
1816}
1817
1818static int map_auto_subtitle(Muxer *mux, const OptionsContext *o)
1819{
1820 AVFormatContext *oc = mux->fc;
1821 const char *subtitle_codec_name = NULL;
1822
1823 /* subtitles: pick first */
1826 return 0;
1827
1828 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist))
1829 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1830 AVCodecDescriptor const *input_descriptor =
1831 avcodec_descriptor_get(ist->st->codecpar->codec_id);
1832 AVCodecDescriptor const *output_descriptor = NULL;
1833 AVCodec const *output_codec =
1835 int input_props = 0, output_props = 0;
1836 if (ist->user_set_discard == AVDISCARD_ALL)
1837 continue;
1838 if (output_codec)
1839 output_descriptor = avcodec_descriptor_get(output_codec->id);
1840 if (input_descriptor)
1841 input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
1842 if (output_descriptor)
1843 output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
1844 if (subtitle_codec_name ||
1845 input_props & output_props ||
1846 // Map dvb teletext which has neither property to any output subtitle encoder
1847 input_descriptor && output_descriptor &&
1848 (!input_descriptor->props ||
1849 !output_descriptor->props)) {
1850 return ost_add(mux, o, AVMEDIA_TYPE_SUBTITLE, ist, NULL, NULL, NULL);
1851 }
1852 }
1853
1854 return 0;
1855}
1856
1857static int map_auto_data(Muxer *mux, const OptionsContext *o)
1858{
1859 AVFormatContext *oc = mux->fc;
1860 /* Data only if codec id match */
1862
1864 return 0;
1865
1866 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
1867 if (ist->user_set_discard == AVDISCARD_ALL)
1868 continue;
1869 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA &&
1870 ist->st->codecpar->codec_id == codec_id) {
1871 int ret = ost_add(mux, o, AVMEDIA_TYPE_DATA, ist, NULL, NULL, NULL);
1872 if (ret < 0)
1873 return ret;
1874 }
1875 }
1876
1877 return 0;
1878}
1879
1880static int map_manual(Muxer *mux, const OptionsContext *o, const StreamMap *map)
1881{
1882 InputStream *ist;
1883 int ret;
1884
1885 if (map->disabled)
1886 return 0;
1887
1888 if (map->linklabel) {
1889 FilterGraph *fg;
1890 OutputFilter *ofilter = NULL;
1891 int j, k;
1892
1893 for (j = 0; j < nb_filtergraphs; j++) {
1894 fg = filtergraphs[j];
1895 for (k = 0; k < fg->nb_outputs; k++) {
1896 const char *linklabel = fg->outputs[k]->linklabel;
1897 if (linklabel && !strcmp(linklabel, map->linklabel)) {
1898 ofilter = fg->outputs[k];
1899 goto loop_end;
1900 }
1901 }
1902 }
1903loop_end:
1904 if (!ofilter) {
1905 av_log(mux, AV_LOG_FATAL, "Output with label '%s' does not exist "
1906 "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);
1907 return AVERROR(EINVAL);
1908 }
1909
1910 av_log(mux, AV_LOG_VERBOSE, "Creating output stream from an explicitly "
1911 "mapped complex filtergraph %d, output [%s]\n", fg->index, map->linklabel);
1912
1913 ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL, NULL);
1914 if (ret < 0)
1915 return ret;
1916 } else {
1917 const ViewSpecifier *vs = map->vs.type == VIEW_SPECIFIER_TYPE_NONE ?
1918 NULL : &map->vs;
1919
1920 ist = input_files[map->file_index]->streams[map->stream_index];
1921 if (ist->user_set_discard == AVDISCARD_ALL) {
1922 av_log(mux, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n",
1923 map->file_index, map->stream_index);
1924 return AVERROR(EINVAL);
1925 }
1927 return 0;
1929 return 0;
1931 return 0;
1932 if(o-> data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
1933 return 0;
1934
1938 "Cannot map stream #%d:%d - unsupported type.\n",
1939 map->file_index, map->stream_index);
1941 av_log(mux, AV_LOG_FATAL,
1942 "If you want unsupported types ignored instead "
1943 "of failing, please use the -ignore_unknown option\n"
1944 "If you want them copied, please use -copy_unknown\n");
1945 return AVERROR(EINVAL);
1946 }
1947 return 0;
1948 }
1949
1950 if (vs && ist->st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
1951 av_log(mux, AV_LOG_ERROR,
1952 "View specifier given for mapping a %s input stream\n",
1954 return AVERROR(EINVAL);
1955 }
1956
1957 ret = ost_add(mux, o, ist->st->codecpar->codec_type, ist, NULL, vs, NULL);
1958 if (ret < 0)
1959 return ret;
1960 }
1961
1962 return 0;
1963}
1964
1965static int of_add_attachments(Muxer *mux, const OptionsContext *o)
1966{
1967 MuxStream *ms;
1969 int err;
1970
1971 for (int i = 0; i < o->nb_attachments; i++) {
1972 AVIOContext *pb;
1973 uint8_t *attachment;
1974 char *attachment_filename;
1975 const char *p;
1976 int64_t len;
1977
1978 if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
1979 av_log(mux, AV_LOG_FATAL, "Could not open attachment file %s.\n",
1980 o->attachments[i]);
1981 return err;
1982 }
1983 if ((len = avio_size(pb)) <= 0) {
1984 av_log(mux, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
1985 o->attachments[i]);
1986 err = len ? len : AVERROR_INVALIDDATA;
1987 goto read_fail;
1988 }
1989 if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
1990 av_log(mux, AV_LOG_FATAL, "Attachment %s too large.\n",
1991 o->attachments[i]);
1992 err = AVERROR(ERANGE);
1993 goto read_fail;
1994 }
1995
1997 if (!attachment) {
1998 err = AVERROR(ENOMEM);
1999 goto read_fail;
2000 }
2001
2002 err = avio_read(pb, attachment, len);
2003 if (err < 0)
2004 av_log(mux, AV_LOG_FATAL, "Error reading attachment file %s: %s\n",
2005 o->attachments[i], av_err2str(err));
2006 else if (err != len) {
2007 av_log(mux, AV_LOG_FATAL, "Could not read all %"PRId64" bytes for "
2008 "attachment file %s\n", len, o->attachments[i]);
2009 err = AVERROR(EIO);
2010 }
2011
2012read_fail:
2013 avio_closep(&pb);
2014 if (err < 0)
2015 return err;
2016
2017 memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
2018
2019 av_log(mux, AV_LOG_VERBOSE, "Creating attachment stream from file %s\n",
2020 o->attachments[i]);
2021
2022 attachment_filename = av_strdup(o->attachments[i]);
2023 if (!attachment_filename) {
2024 av_free(attachment);
2025 return AVERROR(ENOMEM);
2026 }
2027
2028 err = ost_add(mux, o, AVMEDIA_TYPE_ATTACHMENT, NULL, NULL, NULL, &ost);
2029 if (err < 0) {
2030 av_free(attachment_filename);
2031 av_freep(&attachment);
2032 return err;
2033 }
2034
2035 ms = ms_from_ost(ost);
2036
2037 ost->attachment_filename = attachment_filename;
2038 ms->par_in->extradata = attachment;
2039 ms->par_in->extradata_size = len;
2040
2041 p = strrchr(o->attachments[i], '/');
2042 av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
2043 }
2044
2045 return 0;
2046}
2047
2048static int create_streams(Muxer *mux, const OptionsContext *o)
2049{
2050 static int (* const map_func[])(Muxer *mux, const OptionsContext *o) = {
2055 };
2056
2057 AVFormatContext *oc = mux->fc;
2058
2059 int auto_disable =
2060 o->video_disable * (1 << AVMEDIA_TYPE_VIDEO) |
2061 o->audio_disable * (1 << AVMEDIA_TYPE_AUDIO) |
2063 o->data_disable * (1 << AVMEDIA_TYPE_DATA);
2064
2065 int ret;
2066
2067 /* create streams for all unlabeled output pads */
2068 for (int i = 0; i < nb_filtergraphs; i++) {
2069 FilterGraph *fg = filtergraphs[i];
2070 for (int j = 0; j < fg->nb_outputs; j++) {
2071 OutputFilter *ofilter = fg->outputs[j];
2072
2073 if (ofilter->linklabel || ofilter->bound)
2074 continue;
2075
2076 auto_disable |= 1 << ofilter->type;
2077
2078 av_log(mux, AV_LOG_VERBOSE, "Creating output stream from unlabeled "
2079 "output of complex filtergraph %d.", fg->index);
2080 if (!o->nb_stream_maps)
2081 av_log(mux, AV_LOG_VERBOSE, " This overrides automatic %s mapping.",
2082 av_get_media_type_string(ofilter->type));
2083 av_log(mux, AV_LOG_VERBOSE, "\n");
2084
2085 ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL, NULL);
2086 if (ret < 0)
2087 return ret;
2088 }
2089 }
2090
2091 if (!o->nb_stream_maps) {
2092 av_log(mux, AV_LOG_VERBOSE, "No explicit maps, mapping streams automatically...\n");
2093
2094 /* pick the "best" stream of each type */
2095 for (int i = 0; i < FF_ARRAY_ELEMS(map_func); i++) {
2096 if (!map_func[i] || auto_disable & (1 << i))
2097 continue;
2098 ret = map_func[i](mux, o);
2099 if (ret < 0)
2100 return ret;
2101 }
2102 } else {
2103 av_log(mux, AV_LOG_VERBOSE, "Adding streams from explicit maps...\n");
2104
2105 for (int i = 0; i < o->nb_stream_maps; i++) {
2106 ret = map_manual(mux, o, &o->stream_maps[i]);
2107 if (ret < 0)
2108 return ret;
2109 }
2110 }
2111
2112 ret = of_add_attachments(mux, o);
2113 if (ret < 0)
2114 return ret;
2115
2116 // setup fix_sub_duration_heartbeat mappings
2117 for (unsigned i = 0; i < oc->nb_streams; i++) {
2118 MuxStream *src = ms_from_ost(mux->of.streams[i]);
2119
2120 if (!src->ost.fix_sub_duration_heartbeat)
2121 continue;
2122
2123 for (unsigned j = 0; j < oc->nb_streams; j++) {
2124 MuxStream *dst = ms_from_ost(mux->of.streams[j]);
2125
2126 if (src == dst || dst->ost.type != AVMEDIA_TYPE_SUBTITLE ||
2127 !dst->ost.enc || !dst->ost.ist || !dst->ost.ist->fix_sub_duration)
2128 continue;
2129
2130 ret = sch_mux_sub_heartbeat_add(mux->sch, mux->sch_idx, src->sch_idx,
2131 dst->sch_idx_src);
2132
2133 }
2134 }
2135
2136 // handle -apad
2137 if (o->shortest) {
2138 int have_video = 0;
2139
2140 for (unsigned i = 0; i < mux->of.nb_streams; i++)
2141 if (mux->of.streams[i]->type == AVMEDIA_TYPE_VIDEO) {
2142 have_video = 1;
2143 break;
2144 }
2145
2146 for (unsigned i = 0; have_video && i < mux->of.nb_streams; i++) {
2147 MuxStream *ms = ms_from_ost(mux->of.streams[i]);
2148 OutputFilter *ofilter = ms->ost.filter;
2149
2150 if (ms->ost.type != AVMEDIA_TYPE_AUDIO || !ms->apad || !ofilter)
2151 continue;
2152
2153 ofilter->apad = av_strdup(ms->apad);
2154 if (!ofilter->apad)
2155 return AVERROR(ENOMEM);
2156 }
2157 }
2158 for (unsigned i = 0; i < mux->of.nb_streams; i++) {
2159 MuxStream *ms = ms_from_ost(mux->of.streams[i]);
2160 ms->apad = NULL;
2161 }
2162
2163 if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
2164 av_dump_format(oc, nb_output_files - 1, oc->url, 1);
2165 av_log(mux, AV_LOG_ERROR, "Output file does not contain any stream\n");
2166 return AVERROR(EINVAL);
2167 }
2168
2169 return check_stereo3d_leftovers(mux, o);
2170}
2171
2173 int64_t buf_size_us, int shortest)
2174{
2175 OutputFile *of = &mux->of;
2176 int nb_av_enc = 0, nb_audio_fs = 0, nb_interleaved = 0;
2177 int limit_frames = 0, limit_frames_av_enc = 0;
2178
2179#define IS_AV_ENC(ost, type) \
2180 (ost->enc && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO))
2181#define IS_INTERLEAVED(type) (type != AVMEDIA_TYPE_ATTACHMENT)
2182
2183 for (int i = 0; i < oc->nb_streams; i++) {
2184 OutputStream *ost = of->streams[i];
2185 MuxStream *ms = ms_from_ost(ost);
2186 enum AVMediaType type = ost->type;
2187
2188 ms->sq_idx_mux = -1;
2189
2190 nb_interleaved += IS_INTERLEAVED(type);
2191 nb_av_enc += IS_AV_ENC(ost, type);
2192 nb_audio_fs += (ost->enc && type == AVMEDIA_TYPE_AUDIO &&
2193 (!(ost->enc->enc_ctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) ||
2194 (ost->enc->flags2 & AV_CODEC_FLAG2_FIXED_FRAME_SIZE)));
2195
2196 limit_frames |= ms->max_frames < INT64_MAX;
2197 limit_frames_av_enc |= (ms->max_frames < INT64_MAX) && IS_AV_ENC(ost, type);
2198 }
2199
2200 if (!((nb_interleaved > 1 && shortest) ||
2201 (nb_interleaved > 0 && limit_frames) ||
2202 nb_audio_fs))
2203 return 0;
2204
2205 /* we use a sync queue before encoding when:
2206 * - 'shortest' is in effect and we have two or more encoded audio/video
2207 * streams
2208 * - at least one encoded audio/video stream is frame-limited, since
2209 * that has similar semantics to 'shortest'
2210 * - at least one audio encoder requires constant frame sizes
2211 *
2212 * Note that encoding sync queues are handled in the scheduler, because
2213 * different encoders run in different threads and need external
2214 * synchronization, while muxer sync queues can be handled inside the muxer
2215 */
2216 if ((shortest && nb_av_enc > 1) || limit_frames_av_enc || nb_audio_fs) {
2217 int sq_idx, ret;
2218
2219 sq_idx = sch_add_sq_enc(mux->sch, buf_size_us, mux);
2220 if (sq_idx < 0)
2221 return sq_idx;
2222
2223 for (int i = 0; i < oc->nb_streams; i++) {
2224 OutputStream *ost = of->streams[i];
2225 MuxStream *ms = ms_from_ost(ost);
2226 enum AVMediaType type = ost->type;
2227
2228 if (!IS_AV_ENC(ost, type))
2229 continue;
2230
2231 ret = sch_sq_add_enc(mux->sch, sq_idx, ms->sch_idx_enc,
2232 shortest || ms->max_frames < INT64_MAX,
2233 ms->max_frames);
2234 if (ret < 0)
2235 return ret;
2236 }
2237 }
2238
2239 /* if there are any additional interleaved streams, then ALL the streams
2240 * are also synchronized before sending them to the muxer */
2241 if (nb_interleaved > nb_av_enc) {
2242 mux->sq_mux = sq_alloc(SYNC_QUEUE_PACKETS, buf_size_us, mux);
2243 if (!mux->sq_mux)
2244 return AVERROR(ENOMEM);
2245
2246 mux->sq_pkt = av_packet_alloc();
2247 if (!mux->sq_pkt)
2248 return AVERROR(ENOMEM);
2249
2250 for (int i = 0; i < oc->nb_streams; i++) {
2251 OutputStream *ost = of->streams[i];
2252 MuxStream *ms = ms_from_ost(ost);
2253 enum AVMediaType type = ost->type;
2254
2255 if (!IS_INTERLEAVED(type))
2256 continue;
2257
2258 ms->sq_idx_mux = sq_add_stream(mux->sq_mux,
2259 shortest || ms->max_frames < INT64_MAX);
2260 if (ms->sq_idx_mux < 0)
2261 return ms->sq_idx_mux;
2262
2263 if (ms->max_frames != INT64_MAX)
2265 }
2266 }
2267
2268#undef IS_AV_ENC
2269#undef IS_INTERLEAVED
2270
2271 return 0;
2272}
2273
2275{
2276 AVIAMFAudioElement *audio_element = stg->params.iamf_audio_element;
2277 AVDictionary *dict = NULL;
2278 const char *token;
2279 int ret = 0;
2280
2281 audio_element->demixing_info =
2283 audio_element->recon_gain_info =
2285
2286 if (!audio_element->demixing_info ||
2287 !audio_element->recon_gain_info)
2288 return AVERROR(ENOMEM);
2289
2290 /* process manually set layers and parameters */
2291 token = av_strtok(NULL, ",", &ptr);
2292 while (token) {
2293 const AVDictionaryEntry *e;
2294 int demixing = 0, recon_gain = 0;
2295 int layer = 0;
2296
2297 if (ptr)
2298 ptr += strspn(ptr, " \n\t\r");
2299 if (av_strstart(token, "layer=", &token))
2300 layer = 1;
2301 else if (av_strstart(token, "demixing=", &token))
2302 demixing = 1;
2303 else if (av_strstart(token, "recon_gain=", &token))
2304 recon_gain = 1;
2305
2306 av_dict_free(&dict);
2307 ret = av_dict_parse_string(&dict, token, "=", ":", 0);
2308 if (ret < 0) {
2309 av_log(mux, AV_LOG_ERROR, "Error parsing audio element specification %s\n", token);
2310 goto fail;
2311 }
2312
2313 if (layer) {
2314 AVIAMFLayer *audio_layer = av_iamf_audio_element_add_layer(audio_element);
2315 if (!audio_layer) {
2316 av_log(mux, AV_LOG_ERROR, "Error adding layer to stream group %d\n", stg->index);
2317 ret = AVERROR(ENOMEM);
2318 goto fail;
2319 }
2320 av_opt_set_dict(audio_layer, &dict);
2321 } else if (demixing || recon_gain) {
2322 AVIAMFParamDefinition *param = demixing ? audio_element->demixing_info
2323 : audio_element->recon_gain_info;
2324 void *subblock = av_iamf_param_definition_get_subblock(param, 0);
2325
2326 av_opt_set_dict(param, &dict);
2327 av_opt_set_dict(subblock, &dict);
2328 }
2329
2330 // make sure that no entries are left in the dict
2331 e = NULL;
2332 if (e = av_dict_iterate(dict, e)) {
2333 av_log(mux, AV_LOG_FATAL, "Unknown layer key %s.\n", e->key);
2334 ret = AVERROR(EINVAL);
2335 goto fail;
2336 }
2337 token = av_strtok(NULL, ",", &ptr);
2338 }
2339
2340fail:
2341 av_dict_free(&dict);
2342 if (!ret && !audio_element->nb_layers) {
2343 av_log(mux, AV_LOG_ERROR, "No layer in audio element specification\n");
2344 ret = AVERROR(EINVAL);
2345 }
2346
2347 return ret;
2348}
2349
2350static int of_parse_iamf_submixes(Muxer *mux, AVStreamGroup *stg, char *ptr)
2351{
2352 AVFormatContext *oc = mux->fc;
2354 AVDictionary *dict = NULL;
2355 const char *token;
2356 char *submix_str = NULL;
2357 int ret = 0;
2358
2359 /* process manually set submixes */
2360 token = av_strtok(NULL, ",", &ptr);
2361 while (token) {
2362 AVIAMFSubmix *submix = NULL;
2363 const char *subtoken;
2364 char *subptr = NULL;
2365
2366 if (ptr)
2367 ptr += strspn(ptr, " \n\t\r");
2368 if (!av_strstart(token, "submix=", &token)) {
2369 av_log(mux, AV_LOG_ERROR, "No submix in mix presentation specification \"%s\"\n", token);
2370 goto fail;
2371 }
2372
2373 submix_str = av_strdup(token);
2374 if (!submix_str)
2375 goto fail;
2376
2378 if (!submix) {
2379 av_log(mux, AV_LOG_ERROR, "Error adding submix to stream group %d\n", stg->index);
2380 ret = AVERROR(ENOMEM);
2381 goto fail;
2382 }
2383 submix->output_mix_config =
2385 if (!submix->output_mix_config) {
2386 ret = AVERROR(ENOMEM);
2387 goto fail;
2388 }
2389
2390 subptr = NULL;
2391 subtoken = av_strtok(submix_str, "|", &subptr);
2392 while (subtoken) {
2393 const AVDictionaryEntry *e;
2394 int element = 0, layout = 0;
2395
2396 if (subptr)
2397 subptr += strspn(subptr, " \n\t\r");
2398 if (av_strstart(subtoken, "element=", &subtoken))
2399 element = 1;
2400 else if (av_strstart(subtoken, "layout=", &subtoken))
2401 layout = 1;
2402
2403 av_dict_free(&dict);
2404 ret = av_dict_parse_string(&dict, subtoken, "=", ":", 0);
2405 if (ret < 0) {
2406 av_log(mux, AV_LOG_ERROR, "Error parsing submix specification \"%s\"\n", subtoken);
2407 goto fail;
2408 }
2409
2410 if (element) {
2411 AVIAMFSubmixElement *submix_element;
2412 char *endptr = NULL;
2413 int64_t idx = -1;
2414
2415 if (e = av_dict_get(dict, "stg", NULL, 0))
2416 idx = strtoll(e->value, &endptr, 0);
2417 if (!endptr || *endptr || idx < 0 || idx >= oc->nb_stream_groups - 1 ||
2419 av_log(mux, AV_LOG_ERROR, "Invalid or missing stream group index in "
2420 "submix element specification \"%s\"\n", subtoken);
2421 ret = AVERROR(EINVAL);
2422 goto fail;
2423 }
2424 submix_element = av_iamf_submix_add_element(submix);
2425 if (!submix_element) {
2426 av_log(mux, AV_LOG_ERROR, "Error adding element to submix\n");
2427 ret = AVERROR(ENOMEM);
2428 goto fail;
2429 }
2430
2431 submix_element->audio_element_id = oc->stream_groups[idx]->id;
2432
2433 submix_element->element_mix_config =
2435 if (!submix_element->element_mix_config)
2436 ret = AVERROR(ENOMEM);
2437 av_dict_set(&dict, "stg", NULL, 0);
2438 av_opt_set_dict2(submix_element, &dict, AV_OPT_SEARCH_CHILDREN);
2439 } else if (layout) {
2440 AVIAMFSubmixLayout *submix_layout = av_iamf_submix_add_layout(submix);
2441 if (!submix_layout) {
2442 av_log(mux, AV_LOG_ERROR, "Error adding layout to submix\n");
2443 ret = AVERROR(ENOMEM);
2444 goto fail;
2445 }
2446 av_opt_set_dict(submix_layout, &dict);
2447 } else
2449
2450 if (ret < 0) {
2451 goto fail;
2452 }
2453
2454 // make sure that no entries are left in the dict
2455 e = NULL;
2456 while (e = av_dict_iterate(dict, e)) {
2457 av_log(mux, AV_LOG_FATAL, "Unknown submix key %s.\n", e->key);
2458 ret = AVERROR(EINVAL);
2459 goto fail;
2460 }
2461 subtoken = av_strtok(NULL, "|", &subptr);
2462 }
2463 av_freep(&submix_str);
2464
2465 if (!submix->nb_elements) {
2466 av_log(mux, AV_LOG_ERROR, "No audio elements in submix specification \"%s\"\n", token);
2467 ret = AVERROR(EINVAL);
2468 }
2469 token = av_strtok(NULL, ",", &ptr);
2470 }
2471
2472fail:
2473 av_dict_free(&dict);
2474 av_free(submix_str);
2475
2476 return ret;
2477}
2478
2479static int of_serialize_options(Muxer *mux, void *obj, AVBPrint *bp)
2480{
2481 char *ptr;
2482 int ret;
2483
2485 &ptr, '=', ':');
2486 if (ret < 0) {
2487 av_log(mux, AV_LOG_ERROR, "Failed to serialize group\n");
2488 return ret;
2489 }
2490
2491 av_bprintf(bp, "%s", ptr);
2492 ret = strlen(ptr);
2493 av_free(ptr);
2494
2495 return ret;
2496}
2497
2498#define SERIALIZE(parent, child) do { \
2499 ret = of_serialize_options(mux, parent->child, bp); \
2500 if (ret < 0) \
2501 return ret; \
2502} while (0)
2503
2504#define SERIALIZE_LOOP_SUBBLOCK(obj) do { \
2505 for (int k = 0; k < obj->nb_subblocks; k++) { \
2506 ret = of_serialize_options(mux, \
2507 av_iamf_param_definition_get_subblock(obj, k), bp); \
2508 if (ret < 0) \
2509 return ret; \
2510 } \
2511} while (0)
2512
2513#define SERIALIZE_LOOP(parent, child, suffix, separator) do { \
2514 for (int j = 0; j < parent->nb_## child ## suffix; j++) { \
2515 av_bprintf(bp, separator#child "="); \
2516 SERIALIZE(parent, child ## suffix[j]); \
2517 } \
2518} while (0)
2519
2521{
2522 AVFormatContext *oc = mux->fc;
2523
2524 for (unsigned i = 0; i < oc->nb_stream_groups; i++)
2525 if (oc->stream_groups[i]->id == id)
2526 return oc->stream_groups[i]->index;
2527
2528 return AVERROR(EINVAL);
2529}
2530
2531static int of_map_group(Muxer *mux, AVDictionary **dict, AVBPrint *bp, const char *map)
2532{
2533 AVStreamGroup *stg;
2534 int ret, file_idx, stream_idx;
2535 char *ptr;
2536
2537 file_idx = strtol(map, &ptr, 0);
2538 if (file_idx >= nb_input_files || file_idx < 0 || map == ptr) {
2539 av_log(mux, AV_LOG_ERROR, "Invalid input file index: %d.\n", file_idx);
2540 return AVERROR(EINVAL);
2541 }
2542
2543 stream_idx = strtol(*ptr == '=' ? ptr + 1 : ptr, &ptr, 0);
2544 if (*ptr || stream_idx >= input_files[file_idx]->ctx->nb_stream_groups || stream_idx < 0) {
2545 av_log(mux, AV_LOG_ERROR, "Invalid input stream group index: %d.\n", stream_idx);
2546 return AVERROR(EINVAL);
2547 }
2548
2549 stg = input_files[file_idx]->ctx->stream_groups[stream_idx];
2550 ret = of_serialize_options(mux, stg, bp);
2551 if (ret < 0)
2552 return ret;
2553
2554 ret = av_dict_parse_string(dict, bp->str, "=", ":", 0);
2555 if (ret < 0)
2556 av_log(mux, AV_LOG_ERROR, "Error parsing mapped group specification %s\n", ptr);
2557 av_dict_set_int(dict, "type", stg->type, 0);
2558
2559 av_bprint_clear(bp);
2560 switch(stg->type) {
2562 AVIAMFAudioElement *audio_element = stg->params.iamf_audio_element;
2563
2564 if (audio_element->demixing_info) {
2565 AVIAMFParamDefinition *demixing_info = audio_element->demixing_info;
2566 av_bprintf(bp, ",demixing=");
2567 SERIALIZE(audio_element, demixing_info);
2568 if (ret && demixing_info->nb_subblocks)
2569 av_bprintf(bp, ":");
2570 SERIALIZE_LOOP_SUBBLOCK(demixing_info);
2571 }
2572 if (audio_element->recon_gain_info) {
2573 AVIAMFParamDefinition *recon_gain_info = audio_element->recon_gain_info;
2574 av_bprintf(bp, ",recon_gain=");
2575 SERIALIZE(audio_element, recon_gain_info);
2576 if (ret && recon_gain_info->nb_subblocks)
2577 av_bprintf(bp, ":");
2578 SERIALIZE_LOOP_SUBBLOCK(recon_gain_info);
2579 }
2580 SERIALIZE_LOOP(audio_element, layer, s, ",");
2581 break;
2582 }
2585
2586 for (int i = 0; i < mix->nb_submixes; i++) {
2587 AVIAMFSubmix *submix = mix->submixes[i];
2588 AVIAMFParamDefinition *output_mix_config = submix->output_mix_config;
2589
2590 av_bprintf(bp, ",submix=");
2591 SERIALIZE(mix, submixes[i]);
2592 if (ret && output_mix_config->nb_subblocks)
2593 av_bprintf(bp, ":");
2594 SERIALIZE_LOOP_SUBBLOCK(output_mix_config);
2595 for (int j = 0; j < submix->nb_elements; j++) {
2596 AVIAMFSubmixElement *element = submix->elements[j];
2597 AVIAMFParamDefinition *element_mix_config = element->element_mix_config;
2599
2600 if (id < 0) {
2601 av_log(mux, AV_LOG_ERROR, "Invalid or missing stream group index in"
2602 "submix element");
2603 return id;
2604 }
2605
2606 av_bprintf(bp, "|element=");
2607 SERIALIZE(submix, elements[j]);
2608 if (ret && element_mix_config->nb_subblocks)
2609 av_bprintf(bp, ":");
2610 SERIALIZE_LOOP_SUBBLOCK(element_mix_config);
2611 if (ret)
2612 av_bprintf(bp, ":");
2613 av_bprintf(bp, "stg=%"PRId64, id);
2614 }
2615 SERIALIZE_LOOP(submix, layout, s, "|");
2616 }
2617 break;
2618 }
2623 break;
2624 default:
2625 av_log(mux, AV_LOG_ERROR, "Unsupported mapped group type %d.\n", stg->type);
2626 ret = AVERROR(EINVAL);
2627 break;
2628 }
2629 return 0;
2630}
2631
2632static int of_parse_group_token(Muxer *mux, const char *token, char *ptr)
2633{
2634 AVFormatContext *oc = mux->fc;
2635 AVStreamGroup *stg;
2636 AVDictionary *dict = NULL, *tmp = NULL;
2637 char *mapped_string = NULL;
2638 const AVDictionaryEntry *e;
2639 const AVOption opts[] = {
2640 { "type", "Set group type", offsetof(AVStreamGroup, type), AV_OPT_TYPE_INT,
2641 { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "type" },
2642 { "iamf_audio_element", NULL, 0, AV_OPT_TYPE_CONST,
2643 { .i64 = AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT }, .unit = "type" },
2644 { "iamf_mix_presentation", NULL, 0, AV_OPT_TYPE_CONST,
2645 { .i64 = AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION }, .unit = "type" },
2646 { "lcevc", NULL, 0, AV_OPT_TYPE_CONST,
2647 { .i64 = AV_STREAM_GROUP_PARAMS_LCEVC }, .unit = "type" },
2648 { "tref", NULL, 0, AV_OPT_TYPE_CONST,
2649 { .i64 = AV_STREAM_GROUP_PARAMS_TREF }, .unit = "type" },
2650 { "gain_map", NULL, 0, AV_OPT_TYPE_CONST,
2651 { .i64 = AV_STREAM_GROUP_PARAMS_GAIN_MAP }, .unit = "type" },
2652 { NULL },
2653 };
2654 const AVClass class = {
2655 .class_name = "StreamGroupType",
2656 .item_name = av_default_item_name,
2657 .option = opts,
2658 .version = LIBAVUTIL_VERSION_INT,
2659 };
2660 const AVClass *pclass = &class;
2661 int type, ret;
2662
2663 ret = av_dict_parse_string(&dict, token, "=", ":", AV_DICT_MULTIKEY);
2664 if (ret < 0) {
2665 av_log(mux, AV_LOG_ERROR, "Error parsing group specification %s\n", token);
2666 return ret;
2667 }
2668
2669 av_dict_copy(&tmp, dict, 0);
2670 e = av_dict_get(dict, "map", NULL, 0);
2671 if (e) {
2672 AVBPrint bp;
2673
2674 if (ptr) {
2675 av_log(mux, AV_LOG_ERROR, "Unexpected extra parameters when mapping a"
2676 " stream group\n");
2677 ret = AVERROR(EINVAL);
2678 goto end;
2679 }
2680
2682 ret = of_map_group(mux, &tmp, &bp, e->value);
2683 if (ret < 0) {
2685 goto end;
2686 }
2687
2688 av_bprint_finalize(&bp, &mapped_string);
2689 ptr = mapped_string;
2690 }
2691
2692 // "type" is not a user settable AVOption in AVStreamGroup, so handle it here
2693 e = av_dict_get(tmp, "type", NULL, 0);
2694 if (!e) {
2695 av_log(mux, AV_LOG_ERROR, "No type specified for Stream Group in \"%s\"\n", token);
2696 ret = AVERROR(EINVAL);
2697 goto end;
2698 }
2699
2700 ret = av_opt_eval_int(&pclass, opts, e->value, &type);
2701 if (!ret && type == AV_STREAM_GROUP_PARAMS_NONE)
2702 ret = AVERROR(EINVAL);
2703 if (ret < 0) {
2704 av_log(mux, AV_LOG_ERROR, "Invalid group type \"%s\"\n", e->value);
2705 goto end;
2706 }
2707
2709 if (!stg) {
2710 ret = AVERROR(ENOMEM);
2711 goto end;
2712 }
2713
2714 e = NULL;
2715 while (e = av_dict_get(dict, "st", e, 0)) {
2716 char *endptr;
2717 int64_t idx = strtoll(e->value, &endptr, 0);
2718 if (*endptr || idx < 0 || idx >= oc->nb_streams) {
2719 av_log(mux, AV_LOG_ERROR, "Invalid stream index %"PRId64"\n", idx);
2720 ret = AVERROR(EINVAL);
2721 goto end;
2722 }
2723 ret = avformat_stream_group_add_stream(stg, oc->streams[idx]);
2724 if (ret < 0)
2725 goto end;
2726 OutputStream *ost = mux->of.streams[idx];
2729 ost->enc->flags2 |= AV_CODEC_FLAG2_FIXED_FRAME_SIZE;
2730 }
2731 while (e = av_dict_get(dict, "stg", e, 0)) {
2732 char *endptr;
2733 int64_t idx = strtoll(e->value, &endptr, 0);
2734 if (*endptr || idx < 0 || idx >= oc->nb_stream_groups - 1) {
2735 av_log(mux, AV_LOG_ERROR, "Invalid stream group index %"PRId64"\n", idx);
2736 ret = AVERROR(EINVAL);
2737 goto end;
2738 }
2739 for (unsigned i = 0; i < oc->stream_groups[idx]->nb_streams; i++) {
2741 if (ret < 0)
2742 goto end;
2743 }
2744 }
2745
2746 switch(type) {
2748 ret = of_parse_iamf_audio_element_layers(mux, stg, ptr);
2749 break;
2751 ret = of_parse_iamf_submixes(mux, stg, ptr);
2752 break;
2753 default:
2754 break;
2755 }
2756
2757 if (ret < 0)
2758 goto end;
2759
2760 // make sure that nothing but "st" and "stg" entries are left in the dict
2761 e = NULL;
2762 av_dict_set(&tmp, "map", NULL, 0);
2763 av_dict_set(&tmp, "type", NULL, 0);
2764 while (e = av_dict_iterate(tmp, e)) {
2765 if (!strcmp(e->key, "st") || !strcmp(e->key, "stg"))
2766 continue;
2767
2768 av_log(mux, AV_LOG_FATAL, "Unknown group key %s.\n", e->key);
2769 ret = AVERROR(EINVAL);
2770 goto end;
2771 }
2772
2773 ret = 0;
2774end:
2775 av_free(mapped_string);
2776 av_dict_free(&dict);
2777 av_dict_free(&tmp);
2778
2779 return ret;
2780}
2781
2782static int of_add_groups(Muxer *mux, const OptionsContext *o)
2783{
2784 /* process manually set groups */
2785 for (int i = 0; i < o->stream_groups.nb_opt; i++) {
2786 const char *token;
2787 char *str, *ptr = NULL;
2788 int ret = 0;
2789
2790 str = av_strdup(o->stream_groups.opt[i].u.str);
2791 if (!str)
2792 return ret;
2793
2794 token = av_strtok(str, ",", &ptr);
2795 if (token) {
2796 if (ptr)
2797 ptr += strspn(ptr, " \n\t\r");
2798 ret = of_parse_group_token(mux, token, ptr);
2799 }
2800
2801 av_free(str);
2802 if (ret < 0)
2803 return ret;
2804 }
2805
2806 return 0;
2807}
2808
2809static int of_add_programs(Muxer *mux, const OptionsContext *o)
2810{
2811 AVFormatContext *oc = mux->fc;
2812 /* process manually set programs */
2813 for (int i = 0; i < o->program.nb_opt; i++) {
2814 AVDictionary *dict = NULL;
2815 const AVDictionaryEntry *e;
2816 AVProgram *program;
2817 int ret, progid = i + 1;
2818
2819 ret = av_dict_parse_string(&dict, o->program.opt[i].u.str, "=", ":",
2821 if (ret < 0) {
2822 av_log(mux, AV_LOG_ERROR, "Error parsing program specification %s\n",
2823 o->program.opt[i].u.str);
2824 return ret;
2825 }
2826
2827 e = av_dict_get(dict, "program_num", NULL, 0);
2828 if (e) {
2829 progid = strtol(e->value, NULL, 0);
2830 av_dict_set(&dict, e->key, NULL, 0);
2831 }
2832
2833 program = av_new_program(oc, progid);
2834 if (!program) {
2835 ret = AVERROR(ENOMEM);
2836 goto fail;
2837 }
2838
2839 e = av_dict_get(dict, "title", NULL, 0);
2840 if (e) {
2841 av_dict_set(&program->metadata, e->key, e->value, 0);
2842 av_dict_set(&dict, e->key, NULL, 0);
2843 }
2844
2845 e = NULL;
2846 while (e = av_dict_get(dict, "st", e, 0)) {
2847 int st_num = strtol(e->value, NULL, 0);
2848 av_program_add_stream_index(oc, progid, st_num);
2849 }
2850
2851 // make sure that nothing but "st" entries are left in the dict
2852 e = NULL;
2853 while (e = av_dict_iterate(dict, e)) {
2854 if (!strcmp(e->key, "st"))
2855 continue;
2856
2857 av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", e->key);
2858 ret = AVERROR(EINVAL);
2859 goto fail;
2860 }
2861
2862fail:
2863 av_dict_free(&dict);
2864 if (ret < 0)
2865 return ret;
2866 }
2867
2868 return 0;
2869}
2870
2871/**
2872 * Parse a metadata specifier passed as 'arg' parameter.
2873 * @param arg metadata string to parse
2874 * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
2875 * @param index for type c/p, chapter/program index is written here
2876 * @param stream_spec for type s, the stream specifier is written here
2877 */
2878static int parse_meta_type(void *logctx, const char *arg,
2879 char *type, int *index, const char **stream_spec)
2880{
2881 if (*arg) {
2882 *type = *arg;
2883 switch (*arg) {
2884 case 'g':
2885 break;
2886 case 's':
2887 if (*(++arg) && *arg != ':') {
2888 av_log(logctx, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
2889 return AVERROR(EINVAL);
2890 }
2891 *stream_spec = *arg == ':' ? arg + 1 : "";
2892 break;
2893 case 'c':
2894 case 'p':
2895 if (*(++arg) == ':')
2896 *index = strtol(++arg, NULL, 0);
2897 break;
2898 default:
2899 av_log(logctx, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
2900 return AVERROR(EINVAL);
2901 }
2902 } else
2903 *type = 'g';
2904
2905 return 0;
2906}
2907
2909 const OptionsContext *o)
2910{
2911 for (int i = 0; i < o->metadata.nb_opt; i++) {
2912 AVDictionary **m;
2913 char type, *val;
2914 const char *stream_spec;
2915 int index = 0, ret = 0;
2916
2917 val = strchr(o->metadata.opt[i].u.str, '=');
2918 if (!val) {
2919 av_log(of, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
2920 o->metadata.opt[i].u.str);
2921 return AVERROR(EINVAL);
2922 }
2923 *val++ = 0;
2924
2925 ret = parse_meta_type(of, o->metadata.opt[i].specifier, &type, &index, &stream_spec);
2926 if (ret < 0)
2927 return ret;
2928
2929 if (type == 's') {
2930 for (int j = 0; j < oc->nb_streams; j++) {
2931 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
2932 av_dict_set(&oc->streams[j]->metadata, o->metadata.opt[i].u.str, *val ? val : NULL, 0);
2933 } else if (ret < 0)
2934 return ret;
2935 }
2936 } else {
2937 switch (type) {
2938 case 'g':
2939 m = &oc->metadata;
2940 break;
2941 case 'c':
2943 av_log(of, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
2944 return AVERROR(EINVAL);
2945 }
2946 m = &oc->chapters[index]->metadata;
2947 break;
2948 case 'p':
2950 av_log(of, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index);
2951 return AVERROR(EINVAL);
2952 }
2953 m = &oc->programs[index]->metadata;
2954 break;
2955 default:
2956 av_log(of, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata.opt[i].specifier);
2957 return AVERROR(EINVAL);
2958 }
2959 av_dict_set(m, o->metadata.opt[i].u.str, *val ? val : NULL, 0);
2960 }
2961 }
2962
2963 return 0;
2964}
2965
2966static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *os,
2967 int copy_metadata)
2968{
2969 AVFormatContext *is = ifile->ctx;
2970 AVChapter **tmp;
2971
2972 tmp = av_realloc_f(os->chapters, is->nb_chapters + os->nb_chapters, sizeof(*os->chapters));
2973 if (!tmp)
2974 return AVERROR(ENOMEM);
2975 os->chapters = tmp;
2976
2977 for (int i = 0; i < is->nb_chapters; i++) {
2978 AVChapter *in_ch = is->chapters[i], *out_ch;
2979 int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
2980 int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
2981 AV_TIME_BASE_Q, in_ch->time_base);
2982 int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
2984
2985
2986 if (in_ch->end < ts_off)
2987 continue;
2988 if (rt != INT64_MAX && in_ch->start > rt + ts_off)
2989 break;
2990
2991 out_ch = av_mallocz(sizeof(AVChapter));
2992 if (!out_ch)
2993 return AVERROR(ENOMEM);
2994
2995 out_ch->id = in_ch->id;
2996 out_ch->time_base = in_ch->time_base;
2997 out_ch->start = FFMAX(0, in_ch->start - ts_off);
2998 out_ch->end = FFMIN(rt, in_ch->end - ts_off);
2999
3000 if (copy_metadata)
3001 av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
3002
3003 os->chapters[os->nb_chapters++] = out_ch;
3004 }
3005 return 0;
3006}
3007
3009 const char *outspec, const char *inspec,
3010 int *metadata_global_manual, int *metadata_streams_manual,
3011 int *metadata_chapters_manual)
3012{
3013 AVFormatContext *oc = mux->fc;
3014 AVDictionary **meta_in = NULL;
3015 AVDictionary **meta_out = NULL;
3016 int i, ret = 0;
3017 char type_in, type_out;
3018 const char *istream_spec = NULL, *ostream_spec = NULL;
3019 int idx_in = 0, idx_out = 0;
3020
3021 ret = parse_meta_type(mux, inspec, &type_in, &idx_in, &istream_spec);
3022 if (ret >= 0)
3023 ret = parse_meta_type(mux, outspec, &type_out, &idx_out, &ostream_spec);
3024 if (ret < 0)
3025 return ret;
3026
3027 if (type_in == 'g' || type_out == 'g' || (!*outspec && !ic))
3028 *metadata_global_manual = 1;
3029 if (type_in == 's' || type_out == 's' || (!*outspec && !ic))
3030 *metadata_streams_manual = 1;
3031 if (type_in == 'c' || type_out == 'c' || (!*outspec && !ic))
3032 *metadata_chapters_manual = 1;
3033
3034 /* ic is NULL when just disabling automatic mappings */
3035 if (!ic)
3036 return 0;
3037
3038#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
3039 if ((index) < 0 || (index) >= (nb_elems)) {\
3040 av_log(mux, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
3041 (desc), (index));\
3042 return AVERROR(EINVAL);\
3043 }
3044
3045#define SET_DICT(type, meta, context, index)\
3046 switch (type) {\
3047 case 'g':\
3048 meta = &context->metadata;\
3049 break;\
3050 case 'c':\
3051 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
3052 meta = &context->chapters[index]->metadata;\
3053 break;\
3054 case 'p':\
3055 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
3056 meta = &context->programs[index]->metadata;\
3057 break;\
3058 case 's':\
3059 break; /* handled separately below */ \
3060 default: av_assert0(0);\
3061 }\
3062
3063 SET_DICT(type_in, meta_in, ic, idx_in);
3064 SET_DICT(type_out, meta_out, oc, idx_out);
3065
3066 /* for input streams choose first matching stream */
3067 if (type_in == 's') {
3068 for (i = 0; i < ic->nb_streams; i++) {
3069 if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
3070 meta_in = &ic->streams[i]->metadata;
3071 break;
3072 } else if (ret < 0)
3073 return ret;
3074 }
3075 if (!meta_in) {
3076 av_log(mux, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
3077 return AVERROR(EINVAL);
3078 }
3079 }
3080
3081 if (type_out == 's') {
3082 for (i = 0; i < oc->nb_streams; i++) {
3083 if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
3084 meta_out = &oc->streams[i]->metadata;
3085 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
3086 } else if (ret < 0)
3087 return ret;
3088 }
3089 } else
3090 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
3091
3092 return 0;
3093}
3094
3095#define REENC_MASK(type) (1u << (type))
3096#define REENC_AUDIO_ONLY REENC_MASK(AVMEDIA_TYPE_AUDIO)
3097#define REENC_VIDEO_ONLY REENC_MASK(AVMEDIA_TYPE_VIDEO)
3098#define REENC_ANY (REENC_AUDIO_ONLY | REENC_VIDEO_ONLY)
3099
3100static const struct {
3101 const char *key;
3103 unsigned reenc_mask; /* 0 = always delete; non-zero = bit-mask of
3104 * REENC_* values whose re-encoding triggers
3105 * deletion of this key */
3106} reenc_delete_keys[] = {
3107 // Note: "encoder" is intentionally absent — set_encoder_id() stamps it
3108 // after copy_meta() runs, so it always reflects the current encoder.
3109
3110 // iTunes gapless playback: encoder-specific sample counts and padding;
3111 // gapless_playback is the M4A/MOV equivalent of iTunPGAP
3112 { "iTunPGAP", 0, REENC_AUDIO_ONLY },
3113 { "comment-iTunPGAP-eng", 0, REENC_AUDIO_ONLY },
3114 { "iTunSMPB", 0, REENC_AUDIO_ONLY },
3115 { "comment-iTunSMPB-eng", 0, REENC_AUDIO_ONLY },
3116 { "gapless_playback", 0, REENC_AUDIO_ONLY },
3117 // iTunes Sound Check: peak amplitude computed from the original waveform
3118 { "iTunNORM", 0, REENC_AUDIO_ONLY },
3119 { "comment-iTunNORM-eng", 0, REENC_AUDIO_ONLY },
3120 // encoding provenance: describe the original encoder, not the new one
3121 { "encoded_by", 0, REENC_ANY },
3122 { "encoding_tool", 0, REENC_ANY },
3123 // MOV/MP4 stream: vendor 4CC identifies the original encoder
3124 { "vendor_id", 0, REENC_ANY },
3125 // Matroska stream stats written by mkvmerge; all are invalidated by re-encoding
3126 { "BPS", AV_DICT_IGNORE_SUFFIX, REENC_ANY },
3127 { "DURATION", AV_DICT_IGNORE_SUFFIX, REENC_ANY },
3128 { "NUMBER_OF_BYTES", AV_DICT_IGNORE_SUFFIX, REENC_ANY },
3129 { "NUMBER_OF_FRAMES", AV_DICT_IGNORE_SUFFIX, REENC_ANY },
3130 { "_STATISTICS_TAGS", AV_DICT_IGNORE_SUFFIX, REENC_ANY },
3131 { "_STATISTICS_WRITING_APP", AV_DICT_IGNORE_SUFFIX, REENC_ANY },
3132 { "_STATISTICS_WRITING_DATE_UTC", AV_DICT_IGNORE_SUFFIX, REENC_ANY },
3133
3134 // MOV/MP4: source container brand written by the demuxer; muxer ignores
3135 // these keys and writes its own ftyp, so they always describe the source file
3136 { "major_brand", 0, 0 },
3137 { "minor_version", 0, 0 },
3138 { "compatible_brands", 0, 0 },
3139 { NULL }
3141
3142static int meta_spec_matches(void *log_ctx, AVFormatContext *oc, AVStream *st,
3143 const char *spec)
3144{
3145 char type;
3146 int index = 0;
3147 const char *stream_spec = NULL;
3148
3149 if (parse_meta_type(log_ctx, spec, &type, &index, &stream_spec) < 0)
3150 return 0;
3151
3152 if (*spec) {
3153 if (type == 'g' && st)
3154 return 0;
3155 if (type == 's') {
3156 int ret;
3157 if (!st)
3158 return 0;
3159 ret = check_stream_specifier(oc, st, stream_spec);
3160 return ret < 0 ? ret : ret > 0;
3161 }
3162 if (type == 'c' || type == 'p')
3163 return 0;
3164 }
3165 return 1;
3166}
3167
3168static int reenc_delete_metadata_key(const OptionsContext *o, void *log_ctx,
3169 AVFormatContext *oc, AVStream *st,
3170 const char *family, const char *key, int flags)
3171{
3172 for (int i = 0; i < o->keep_metadata.nb_opt; i++) {
3173 int ret = meta_spec_matches(log_ctx, oc, st, o->keep_metadata.opt[i].specifier);
3174 if (ret < 0)
3175 return ret;
3176 if (!ret)
3177 continue;
3178 const char *keep = o->keep_metadata.opt[i].u.str;
3180 /* accept the unsuffixed family name (e.g. NUMBER_OF_BYTES keeps
3181 * NUMBER_OF_BYTES-eng) or the exact matched key; an arbitrary
3182 * prefix like NUMBER does not match NUMBER_OF_BYTES-eng */
3183 if (!strcmp(keep, family) || !strcmp(keep, key))
3184 return 0;
3185 } else {
3186 if (!strcmp(key, keep))
3187 return 0;
3188 }
3189 }
3190 for (int i = 0; i < o->metadata.nb_opt; i++) {
3191 int ret;
3192 /* plain -metadata (empty specifier) applies to global metadata only,
3193 * matching of_add_metadata(); don't let it suppress stream-level pruning */
3194 if (!*o->metadata.opt[i].specifier && st)
3195 continue;
3196 ret = meta_spec_matches(log_ctx, oc, st, o->metadata.opt[i].specifier);
3197 if (ret < 0)
3198 return ret;
3199 if (!ret)
3200 continue;
3201 size_t klen = strcspn(o->metadata.opt[i].u.str, "=");
3202 if (!strncmp(key, o->metadata.opt[i].u.str, klen) && key[klen] == '\0')
3203 return 0;
3204 }
3205 return 1;
3206}
3207
3208static int reenc_delete_stale_metadata(const OptionsContext *o, void *log_ctx,
3209 AVFormatContext *oc, AVStream *st,
3210 AVDictionary **dict, const char *kind,
3211 unsigned reenc_mask)
3212{
3213 for (int i = 0; reenc_delete_keys[i].key; i++) {
3214 const char *key = reenc_delete_keys[i].key;
3215 int flags = reenc_delete_keys[i].flags;
3216 const AVDictionaryEntry *e;
3217 int ret;
3218
3220 continue;
3221
3222 e = NULL;
3223 while ((e = av_dict_get(*dict, key, e, flags | AV_DICT_MATCH_CASE))) {
3224 ret = reenc_delete_metadata_key(o, log_ctx, oc, st, key, e->key, flags);
3225 if (ret < 0)
3226 return ret;
3227 if (!ret)
3228 continue;
3230 av_log(log_ctx, AV_LOG_WARNING,
3231 "Discarding %s metadata '%s' because %s stream is being "
3232 "re-encoded. Use '-keep_metadata %s' to keep it.\n",
3233 kind, e->key,
3234 !strcmp(kind, "stream") ? "the" : "a", e->key);
3235 av_dict_set(dict, e->key, NULL, 0);
3236 e = NULL;
3237 }
3238 }
3239 return 0;
3240}
3241
3242static int copy_meta(Muxer *mux, const OptionsContext *o)
3243{
3244 OutputFile *of = &mux->of;
3245 AVFormatContext *oc = mux->fc;
3246 int chapters_input_file = o->chapters_input_file;
3247 int metadata_global_manual = 0;
3248 int metadata_streams_manual = 0;
3249 int metadata_chapters_manual = 0;
3250 int ret;
3251
3252 /* copy metadata */
3253 for (int i = 0; i < o->metadata_map.nb_opt; i++) {
3254 char *p;
3255 int in_file_index = strtol(o->metadata_map.opt[i].u.str, &p, 0);
3256
3257 if (in_file_index >= nb_input_files) {
3258 av_log(mux, AV_LOG_FATAL, "Invalid input file index %d while "
3259 "processing metadata maps\n", in_file_index);
3260 return AVERROR(EINVAL);
3261 }
3262 ret = copy_metadata(mux,
3263 in_file_index >= 0 ? input_files[in_file_index]->ctx : NULL,
3264 o->metadata_map.opt[i].specifier, *p ? p + 1 : p,
3265 &metadata_global_manual, &metadata_streams_manual,
3266 &metadata_chapters_manual);
3267 if (ret < 0)
3268 return ret;
3269 }
3270
3271 /* copy chapters */
3272 if (chapters_input_file >= nb_input_files) {
3273 if (chapters_input_file == INT_MAX) {
3274 /* copy chapters from the first input file that has them*/
3275 chapters_input_file = -1;
3276 for (int i = 0; i < nb_input_files; i++)
3277 if (input_files[i]->ctx->nb_chapters) {
3278 chapters_input_file = i;
3279 break;
3280 }
3281 } else {
3282 av_log(mux, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
3283 chapters_input_file);
3284 return AVERROR(EINVAL);
3285 }
3286 }
3287 if (chapters_input_file >= 0)
3288 copy_chapters(input_files[chapters_input_file], of, oc,
3289 !metadata_chapters_manual);
3290
3291 /* copy global metadata by default */
3292 if (!metadata_global_manual && nb_input_files){
3293 av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
3295 if (of->recording_time != INT64_MAX)
3296 av_dict_set(&oc->metadata, "duration", NULL, 0);
3297 av_dict_set(&oc->metadata, "creation_time", NULL, 0);
3298 av_dict_set(&oc->metadata, "company_name", NULL, 0);
3299 av_dict_set(&oc->metadata, "product_name", NULL, 0);
3300 av_dict_set(&oc->metadata, "product_version", NULL, 0);
3301
3302 }
3303 for (int i = 0; i < o->keep_metadata.nb_opt; i++) {
3304 char type;
3305 int index = 0;
3306 const char *stream_spec = NULL;
3307 const char *spec = o->keep_metadata.opt[i].specifier;
3308 ret = parse_meta_type(mux, spec, &type, &index, &stream_spec);
3309 if (ret < 0)
3310 return ret;
3311 if (type == 'c' || type == 'p') {
3313 "-keep_metadata:%s: chapter and program metadata filtering "
3314 "is not supported and will be ignored.\n", spec);
3315 } else if (type == 's') {
3316 for (int j = 0; j < oc->nb_streams; j++) {
3317 ret = check_stream_specifier(oc, oc->streams[j], stream_spec);
3318 if (ret < 0)
3319 return ret;
3320 }
3321 }
3322 }
3323
3324 /* reenc_mask keys only apply when an audio/video stream is re-encoded;
3325 * subtitle/attachment re-encodes do not affect format-level tags.
3326 * Runs unconditionally so -map_metadata does not bypass the pruning. */
3327 {
3328 unsigned reenc_mask = 0;
3329 for (int i = 0; i < of->nb_streams; i++) {
3330 OutputStream *ost = of->streams[i];
3331 if (ost->enc)
3332 reenc_mask |= REENC_MASK(ost->st->codecpar->codec_type);
3333 }
3334 ret = reenc_delete_stale_metadata(o, mux, oc, NULL, &oc->metadata, "format", reenc_mask);
3335 if (ret < 0)
3336 return ret;
3337 }
3338 if (!metadata_streams_manual)
3339 for (int i = 0; i < of->nb_streams; i++) {
3340 OutputStream *ost = of->streams[i];
3341
3342 if (!ost->ist) /* this is true e.g. for attached files */
3343 continue;
3344 av_dict_copy(&ost->st->metadata, ost->ist->st->metadata, AV_DICT_DONT_OVERWRITE);
3345 }
3346 /* runs unconditionally so -map_metadata does not bypass the pruning;
3347 * applies to all output streams, including filter outputs without ost->ist */
3348 for (int i = 0; i < of->nb_streams; i++) {
3349 OutputStream *ost = of->streams[i];
3350
3351 ret = reenc_delete_stale_metadata(o, ost, oc, ost->st, &ost->st->metadata, "stream",
3352 ost->enc ? REENC_MASK(ost->st->codecpar->codec_type) : 0);
3353 if (ret < 0)
3354 return ret;
3355 }
3356
3357 return 0;
3358}
3359
3360static int set_dispositions(Muxer *mux, const OptionsContext *o)
3361{
3362 OutputFile *of = &mux->of;
3363 AVFormatContext *ctx = mux->fc;
3364
3365 // indexed by type+1, because AVMEDIA_TYPE_UNKNOWN=-1
3366 int nb_streams[AVMEDIA_TYPE_NB + 1] = { 0 };
3367 int have_default[AVMEDIA_TYPE_NB + 1] = { 0 };
3368 int have_manual = 0;
3369 int ret = 0;
3370
3371 const char **dispositions;
3372
3373 dispositions = av_calloc(ctx->nb_streams, sizeof(*dispositions));
3374 if (!dispositions)
3375 return AVERROR(ENOMEM);
3376
3377 // reset any apic flag set for option stream-spec matching in ost_add
3378 for (int i = 0; i < ctx->nb_streams; i++) {
3379 of->streams[i]->st->disposition = 0;
3380 }
3381
3382 // first, copy the input dispositions
3383 for (int i = 0; i < ctx->nb_streams; i++) {
3384 OutputStream *ost = of->streams[i];
3385
3386 nb_streams[ost->type + 1]++;
3387
3388 opt_match_per_stream_str(ost, &o->disposition, ctx, ost->st, &dispositions[i]);
3389
3390 have_manual |= !!dispositions[i];
3391
3392 if (ost->ist) {
3393 ost->st->disposition = ost->ist->st->disposition;
3394
3395 if (ost->st->disposition & AV_DISPOSITION_DEFAULT)
3396 have_default[ost->type + 1] = 1;
3397 }
3398 }
3399
3400 if (have_manual) {
3401 // process manually set dispositions - they override the above copy
3402 for (int i = 0; i < ctx->nb_streams; i++) {
3403 OutputStream *ost = of->streams[i];
3404 const char *disp = dispositions[i];
3405
3406 if (!disp)
3407 continue;
3408
3409 ret = av_opt_set(ost->st, "disposition", disp, 0);
3410 if (ret < 0)
3411 goto finish;
3412 }
3413 } else {
3414 // For each media type with more than one stream, find a suitable stream to
3415 // mark as default, unless one is already marked default.
3416 // "Suitable" means the first of that type, skipping attached pictures.
3417 for (int i = 0; i < ctx->nb_streams; i++) {
3418 OutputStream *ost = of->streams[i];
3419 enum AVMediaType type = ost->type;
3420
3421 if (nb_streams[type + 1] < 2 || have_default[type + 1] ||
3422 ost->st->disposition & AV_DISPOSITION_ATTACHED_PIC)
3423 continue;
3424
3425 ost->st->disposition |= AV_DISPOSITION_DEFAULT;
3426 have_default[type + 1] = 1;
3427 }
3428 }
3429
3430finish:
3431 av_freep(&dispositions);
3432
3433 return ret;
3434}
3435
3436static const char *const forced_keyframes_const_names[] = {
3437 "n",
3438 "n_forced",
3439 "prev_forced_n",
3440 "prev_forced_t",
3441 "t",
3442 NULL
3443};
3444
3445static int compare_int64(const void *a, const void *b)
3446{
3447 return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
3448}
3449
3451 const Muxer *mux, const char *spec)
3452{
3453 int n = 1, i, ret, size, index = 0;
3454 int64_t t, *pts;
3455
3456 for (const char *p = spec; *p; p++)
3457 if (*p == ',')
3458 n++;
3459 size = n;
3460
3461 char *spec_dup = av_strdup(spec);
3462 pts = av_malloc_array(size, sizeof(*pts));
3463 if (!spec_dup || !pts) {
3464 ret = AVERROR(ENOMEM);
3465 goto fail;
3466 }
3467
3468 char *p = spec_dup;
3469 for (i = 0; i < n; i++) {
3470 char *next = strchr(p, ',');
3471
3472 if (next)
3473 *next++ = 0;
3474
3475 if (strstr(p, "chapters") == p) {
3476 AVChapter * const *ch = mux->fc->chapters;
3477 unsigned int nb_ch = mux->fc->nb_chapters;
3478 int j;
3479
3480 if (nb_ch > INT_MAX - size) {
3481 ret = AVERROR(ERANGE);
3482 goto fail;
3483 }
3484 size += nb_ch - 1;
3485 pts = av_realloc_f(pts, size, sizeof(*pts));
3486 if (!pts) {
3487 ret = AVERROR(ENOMEM);
3488 goto fail;
3489 }
3490
3491 if (p[8]) {
3492 ret = av_parse_time(&t, p + 8, 1);
3493 if (ret < 0) {
3494 av_log(log, AV_LOG_ERROR,
3495 "Invalid chapter time offset: %s\n", p + 8);
3496 goto fail;
3497 }
3498 } else
3499 t = 0;
3500
3501 for (j = 0; j < nb_ch; j++) {
3502 const AVChapter *c = ch[j];
3504 pts[index++] = av_rescale_q(c->start, c->time_base,
3505 AV_TIME_BASE_Q) + t;
3506 }
3507
3508 } else {
3510 ret = av_parse_time(&t, p, 1);
3511 if (ret < 0) {
3512 av_log(log, AV_LOG_ERROR, "Invalid keyframe time: %s\n", p);
3513 goto fail;
3514 }
3515
3516 pts[index++] = t;
3517 }
3518
3519 p = next;
3520 }
3521
3522 av_assert0(index == size);
3523 qsort(pts, size, sizeof(*pts), compare_int64);
3524 kf->nb_pts = size;
3525 kf->pts = pts;
3526
3527 av_freep(&spec_dup);
3528
3529 return 0;
3530fail:
3531 av_freep(&spec_dup);
3532 av_freep(&pts);
3533 return ret;
3534}
3535
3537{
3538 for (int i = 0; i < mux->of.nb_streams; i++) {
3539 OutputStream *ost = mux->of.streams[i];
3540 const char *forced_keyframes = NULL;
3541
3543 mux->fc, ost->st, &forced_keyframes);
3544
3545 if (!(ost->type == AVMEDIA_TYPE_VIDEO &&
3546 ost->enc && forced_keyframes))
3547 continue;
3548
3549 if (!strncmp(forced_keyframes, "expr:", 5)) {
3550 int ret = av_expr_parse(&ost->kf.pexpr, forced_keyframes + 5,
3552 if (ret < 0) {
3554 "Invalid force_key_frames expression '%s'\n", forced_keyframes + 5);
3555 return ret;
3556 }
3557 ost->kf.expr_const_values[FKF_N] = 0;
3558 ost->kf.expr_const_values[FKF_N_FORCED] = 0;
3559 ost->kf.expr_const_values[FKF_PREV_FORCED_N] = NAN;
3560 ost->kf.expr_const_values[FKF_PREV_FORCED_T] = NAN;
3561
3562 // Don't parse the 'forced_keyframes' in case of 'keep-source-keyframes',
3563 // parse it only for static kf timings
3564 } else if (!strcmp(forced_keyframes, "source")) {
3565 ost->kf.type = KF_FORCE_SOURCE;
3566 } else if (!strcmp(forced_keyframes, "scd_metadata")) {
3567 ost->kf.type = KF_FORCE_SCD_METADATA;
3568 } else {
3569 int ret = parse_forced_key_frames(ost, &ost->kf, mux, forced_keyframes);
3570 if (ret < 0)
3571 return ret;
3572 }
3573 }
3574
3575 return 0;
3576}
3577
3578static const char *output_file_item_name(void *obj)
3579{
3580 const Muxer *mux = obj;
3581
3582 return mux->log_name;
3583}
3584
3586 .class_name = "OutputFile",
3587 .version = LIBAVUTIL_VERSION_INT,
3588 .item_name = output_file_item_name,
3589 .category = AV_CLASS_CATEGORY_MUXER,
3590};
3591
3592static Muxer *mux_alloc(void)
3593{
3594 Muxer *mux = allocate_array_elem(&output_files, sizeof(*mux), &nb_output_files);
3595
3596 if (!mux)
3597 return NULL;
3598
3599 mux->of.class = &output_file_class;
3600 mux->of.index = nb_output_files - 1;
3601
3602 snprintf(mux->log_name, sizeof(mux->log_name), "out#%d", mux->of.index);
3603
3604 return mux;
3605}
3606
3607int of_open(const OptionsContext *o, const char *filename, Scheduler *sch)
3608{
3609 Muxer *mux;
3610 AVFormatContext *oc;
3611 int err;
3612 OutputFile *of;
3613
3614 int64_t recording_time = o->recording_time;
3615 int64_t stop_time = o->stop_time;
3616
3617 mux = mux_alloc();
3618 if (!mux)
3619 return AVERROR(ENOMEM);
3620
3621 of = &mux->of;
3622
3623 if (stop_time != INT64_MAX && recording_time != INT64_MAX) {
3624 stop_time = INT64_MAX;
3625 av_log(mux, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
3626 }
3627
3628 if (stop_time != INT64_MAX && recording_time == INT64_MAX) {
3630 if (stop_time <= start_time) {
3631 av_log(mux, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
3632 return AVERROR(EINVAL);
3633 } else {
3634 recording_time = stop_time - start_time;
3635 }
3636 }
3637
3638 if (recording_time < 0) {
3639 av_log(mux, AV_LOG_ERROR, "-t value must be non-negative; aborting.\n");
3640 return AVERROR(EINVAL);
3641 }
3642
3643 of->recording_time = recording_time;
3644 of->start_time = o->start_time;
3645
3647 av_dict_copy(&mux->opts, o->g->format_opts, 0);
3648
3649 if (!strcmp(filename, "-"))
3650 filename = "pipe:";
3651
3652 err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
3653 if (!oc) {
3654 av_log(mux, AV_LOG_FATAL, "Error initializing the muxer for %s: %s\n",
3655 filename, av_err2str(err));
3656 return err;
3657 }
3658 mux->fc = oc;
3659
3660 av_strlcat(mux->log_name, "/", sizeof(mux->log_name));
3661 av_strlcat(mux->log_name, oc->oformat->name, sizeof(mux->log_name));
3662
3663
3664 if (recording_time != INT64_MAX)
3665 oc->duration = recording_time;
3666
3668
3669 if (o->bitexact) {
3671 of->bitexact = 1;
3672 } else {
3673 of->bitexact = check_opt_bitexact(oc, mux->opts, "fflags",
3675 }
3676
3677 err = sch_add_mux(sch, muxer_thread, mux_check_init, mux,
3678 !strcmp(oc->oformat->name, "rtp"), o->thread_queue_size);
3679 if (err < 0)
3680 return err;
3681 mux->sch = sch;
3682 mux->sch_idx = err;
3683
3684 /* create all output streams for this file */
3685 err = create_streams(mux, o);
3686 if (err < 0)
3687 return err;
3688
3689 /* check if all codec options have been used */
3690 err = check_avoptions_used(o->g->codec_opts, mux->enc_opts_used, mux, 0);
3692 if (err < 0)
3693 return err;
3694
3695 /* check filename in case of an image number is expected */
3697 av_log(mux, AV_LOG_FATAL,
3698 "Output filename '%s' does not contain a numeric pattern like "
3699 "'%%d', which is required by output format '%s'.\n",
3700 oc->url, oc->oformat->name);
3701 return AVERROR(EINVAL);
3702 }
3703
3704 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
3705 /* test if it already exists to avoid losing precious files */
3706 err = assert_file_overwrite(filename);
3707 if (err < 0)
3708 return err;
3709
3710 /* open the file */
3711 if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
3712 &oc->interrupt_callback,
3713 &mux->opts)) < 0) {
3714 av_log(mux, AV_LOG_FATAL, "Error opening output %s: %s\n",
3715 filename, av_err2str(err));
3716 return err;
3717 }
3718 } else if (strcmp(oc->oformat->name, "image2")==0 && !av_filename_number_test(filename)) {
3719 err = assert_file_overwrite(filename);
3720 if (err < 0)
3721 return err;
3722 }
3723
3724 if (o->mux_preload) {
3725 av_dict_set_int(&mux->opts, "preload", o->mux_preload*AV_TIME_BASE, 0);
3726 }
3727 oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
3728
3729 /* copy metadata and chapters from input files */
3730 err = copy_meta(mux, o);
3731 if (err < 0)
3732 return err;
3733
3734 err = of_add_groups(mux, o);
3735 if (err < 0)
3736 return err;
3737
3738 err = of_add_programs(mux, o);
3739 if (err < 0)
3740 return err;
3741
3742 err = of_add_metadata(of, oc, o);
3743 if (err < 0)
3744 return err;
3745
3746 err = set_dispositions(mux, o);
3747 if (err < 0) {
3748 av_log(mux, AV_LOG_FATAL, "Error setting output stream dispositions\n");
3749 return err;
3750 }
3751
3752 // parse forced keyframe specifications;
3753 // must be done after chapters are created
3754 err = process_forced_keyframes(mux, o);
3755 if (err < 0) {
3756 av_log(mux, AV_LOG_FATAL, "Error processing forced keyframes\n");
3757 return err;
3758 }
3759
3761 o->shortest);
3762 if (err < 0) {
3763 av_log(mux, AV_LOG_FATAL, "Error setting up output sync queues\n");
3764 return err;
3765 }
3766
3767 of->url = filename;
3768
3769 /* initialize streamcopy streams. */
3770 for (int i = 0; i < of->nb_streams; i++) {
3771 OutputStream *ost = of->streams[i];
3772
3773 if (!ost->enc) {
3774 err = of_stream_init(of, ost, NULL);
3775 if (err < 0)
3776 return err;
3777 }
3778 }
3779
3780 return 0;
3781}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:97
static double val(void *priv, double ch)
Definition aeval.c:77
static const char *const format[]
Definition af_aiir.c:445
#define filters(fmt, type, inverse, clp, inverset, clip, one, clip_fn, packed)
static AVFormatContext * ctx
static void finish(void)
static AVDictionary * opts
channels
Definition aptx.h:31
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
Main libavfilter public API header.
void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned idx)
Definition avformat.c:345
Main libavformat public API header.
#define AVFMT_NOSTREAMS
Format does not require any streams.
Definition avformat.h:505
#define AVFMT_FIXED_FRAMESIZE
Format wants fixed size audio frames..
Definition avformat.h:520
#define AVFMT_FLAG_BITEXACT
When muxing, try to avoid writing any random/volatile data to the output.
Definition avformat.h:1505
@ AV_STREAM_GROUP_PARAMS_DOLBY_VISION
Definition avformat.h:1156
@ AV_STREAM_GROUP_PARAMS_TREF
Definition avformat.h:1155
@ AV_STREAM_GROUP_PARAMS_NONE
Definition avformat.h:1150
@ AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
Definition avformat.h:1152
@ AV_STREAM_GROUP_PARAMS_TILE_GRID
Definition avformat.h:1153
@ AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
Definition avformat.h:1151
@ AV_STREAM_GROUP_PARAMS_LCEVC
Definition avformat.h:1154
@ AV_STREAM_GROUP_PARAMS_GAIN_MAP
Definition avformat.h:1157
#define AVFMT_VARIABLE_FPS
Format allows variable fps.
Definition avformat.h:503
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition avformat.h:490
#define AVSTREAM_EVENT_FLAG_NEW_PACKETS
Definition avformat.h:892
#define AVFMT_GLOBALHEADER
Format wants global header.
Definition avformat.h:499
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition avformat.h:694
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition avformat.h:500
#define AV_DISPOSITION_DEFAULT
The stream should be chosen by default among other streams of the same type, unless the user has expl...
Definition avformat.h:641
int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition mux.c:95
#define AVFMT_NEEDNUMBER
Needs 'd' in filename.
Definition avformat.h:491
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition avio.c:724
int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition avio.c:566
Buffered I/O operations.
#define AVIO_FLAG_READ
read-only
Definition avio.h:617
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition aviobuf.c:326
#define AVIO_FLAG_WRITE
write-only
Definition avio.h:618
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:615
int avio_r8(AVIOContext *s)
Definition aviobuf.c:606
Convenience header that includes libavutil's core.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:121
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:68
AVBPrint public header.
#define AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_AUTOMATIC
#define is(width, name, range_min, range_max, subs,...)
Definition cbs_h264.c:78
#define flag(name)
Definition cbs_h264.c:60
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define s(width, name)
Definition cbs_vp9.c:198
int check_avoptions(AVDictionary *m)
Definition cmdutils.c:1603
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
Check if the given stream matches a stream specifier.
Definition cmdutils.c:1336
void * allocate_array_elem(void *ptr, size_t elem_size, int *nb_elems)
Atomically add a new element to an array of pointers, i.e.
Definition cmdutils.c:1538
int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id, AVFormatContext *s, AVStream *st, const AVCodec *codec, AVDictionary **dst, AVDictionary **opts_used)
Filter out options for given codec.
Definition cmdutils.c:1421
char * read_file_to_string(const char *filename)
Definition cmdutils.c:1569
unsigned stream_specifier_match(const StreamSpecifier *ss, const AVFormatContext *s, const AVStream *st, void *logctx)
Definition cmdutils.c:1224
#define GROW_ARRAY(array, nb_elems)
Definition cmdutils.h:536
int avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec)
Definition codec_par.c:138
AVCodecParameters * avcodec_parameters_alloc(void)
Definition codec_par.c:57
int avcodec_parameters_to_context(AVCodecContext *codec, const AVCodecParameters *par)
Definition codec_par.c:206
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
Public dictionary API.
Display matrix.
enum AVCodecID id
Definition dts2pts.c:607
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition eval.c:735
int nb_filtergraphs
Definition ffmpeg.c:115
InputFile ** input_files
Definition ffmpeg.c:108
const AVIOInterruptCB int_cb
Definition ffmpeg.c:322
int nb_input_files
Definition ffmpeg.c:109
FilterGraph ** filtergraphs
Definition ffmpeg.c:114
int nb_output_files
Definition ffmpeg.c:112
int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used, void *logctx, int decode)
Definition ffmpeg.c:515
OutputFile ** output_files
Definition ffmpeg.c:111
InputStream * ist_iter(InputStream *prev)
Definition ffmpeg.c:397
int muxer_thread(void *arg)
Definition ffmpeg_mux.c:403
int of_stream_init(OutputFile *of, OutputStream *ost, const AVCodecContext *enc_ctx)
Definition ffmpeg_mux.c:607
int enc_alloc(Encoder **penc, const AVCodec *codec, Scheduler *sch, unsigned sch_idx, void *log_parent)
Definition ffmpeg_enc.c:125
@ VIEW_SPECIFIER_TYPE_NONE
Definition ffmpeg.h:105
int parse_and_set_vsync(const char *arg, enum VideoSyncMethod *vsync_var, int file_idx, int st_idx)
Definition ffmpeg_opt.c:359
int ignore_unknown_streams
Definition ffmpeg_opt.c:86
int ist_use(InputStream *ist, int decoding_needed, const ViewSpecifier *vs, SchedulerNode *src)
int copy_unknown_streams
Definition ffmpeg_opt.c:87
int find_codec(void *logctx, const char *name, enum AVMediaType type, int encoder, const AVCodec **codec)
Definition ffmpeg_opt.c:783
int encoder_thread(void *arg)
Definition ffmpeg_enc.c:998
int enc_open(void *opaque, const AVFrame *frame)
Definition ffmpeg_enc.c:413
void opt_match_per_stream_int(void *logctx, const SpecifierOptList *sol, AVFormatContext *fc, AVStream *st, int *out)
int assert_file_overwrite(const char *filename)
Definition ffmpeg_opt.c:816
void opt_match_per_stream_dbl(void *logctx, const SpecifierOptList *sol, AVFormatContext *fc, AVStream *st, double *out)
@ FKF_PREV_FORCED_N
Definition ffmpeg.h:541
@ FKF_PREV_FORCED_T
Definition ffmpeg.h:542
@ FKF_N_FORCED
Definition ffmpeg.h:540
@ FKF_N
Definition ffmpeg.h:539
const char * opt_match_per_type_str(const SpecifierOptList *sol, char mediatype)
Definition ffmpeg_opt.c:165
@ OFILTER_FLAG_AUDIO_24BIT
Definition ffmpeg.h:289
@ OFILTER_FLAG_AUTOSCALE
Definition ffmpeg.h:290
@ OFILTER_FLAG_DISABLE_CONVERT
Definition ffmpeg.h:287
VideoSyncMethod
Definition ffmpeg.h:56
@ VSYNC_VFR
Definition ffmpeg.h:60
@ VSYNC_AUTO
Definition ffmpeg.h:57
@ VSYNC_PASSTHROUGH
Definition ffmpeg.h:58
@ VSYNC_CFR
Definition ffmpeg.h:59
@ VSYNC_VSCFR
Definition ffmpeg.h:61
void opt_match_per_stream_int64(void *logctx, const SpecifierOptList *sol, AVFormatContext *fc, AVStream *st, int64_t *out)
int fg_create_simple(FilterGraph **pfg, InputStream *ist, char **graph_desc, Scheduler *sch, unsigned sched_idx_enc, const OutputFilterOptions *opts)
@ KF_FORCE_SCD_METADATA
Definition ffmpeg.h:592
@ KF_FORCE_SOURCE
Definition ffmpeg.h:590
@ ENC_TIME_BASE_DEMUX
Definition ffmpeg.h:65
@ ENC_TIME_BASE_FILTER
Definition ffmpeg.h:66
int ofilter_bind_enc(OutputFilter *ofilter, unsigned sched_idx_enc, const OutputFilterOptions *opts)
int copy_ts
Definition ffmpeg_opt.c:64
EncStatsType
Definition ffmpeg.h:550
@ ENC_STATS_STREAM_IDX
Definition ffmpeg.h:553
@ ENC_STATS_PTS_TIME
Definition ffmpeg.h:559
@ ENC_STATS_SAMPLE_NUM
Definition ffmpeg.h:564
@ ENC_STATS_AVG_BITRATE
Definition ffmpeg.h:568
@ ENC_STATS_LITERAL
Definition ffmpeg.h:551
@ ENC_STATS_TIMEBASE
Definition ffmpeg.h:556
@ ENC_STATS_KEYFRAME
Definition ffmpeg.h:569
@ ENC_STATS_DTS_TIME
Definition ffmpeg.h:563
@ ENC_STATS_PKT_SIZE
Definition ffmpeg.h:566
@ ENC_STATS_FRAME_NUM_IN
Definition ffmpeg.h:555
@ ENC_STATS_PTS
Definition ffmpeg.h:558
@ ENC_STATS_FRAME_NUM
Definition ffmpeg.h:554
@ ENC_STATS_FILE_IDX
Definition ffmpeg.h:552
@ ENC_STATS_DTS
Definition ffmpeg.h:562
@ ENC_STATS_BITRATE
Definition ffmpeg.h:567
@ ENC_STATS_PTS_IN
Definition ffmpeg.h:560
@ ENC_STATS_TIMEBASE_IN
Definition ffmpeg.h:557
@ ENC_STATS_PTS_TIME_IN
Definition ffmpeg.h:561
@ ENC_STATS_NB_SAMPLES
Definition ffmpeg.h:565
void opt_match_per_stream_str(void *logctx, const SpecifierOptList *sol, AVFormatContext *fc, AVStream *st, const char **out)
int mux_check_init(void *arg)
Definition ffmpeg_mux.c:551
static MuxStream * ms_from_ost(OutputStream *ost)
Definition ffmpeg_mux.h:126
static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
#define SET_DICT(type, meta, context, index)
#define REENC_AUDIO_ONLY
#define SERIALIZE_LOOP_SUBBLOCK(obj)
static int parse_stereo3d_type(void *logctx, const char *arg, int *type)
static int of_parse_iamf_audio_element_layers(Muxer *mux, AVStreamGroup *stg, char *ptr)
#define SERIALIZE_LOOP(parent, child, suffix, separator)
static int of_parse_group_token(Muxer *mux, const char *token, char *ptr)
static int create_streams(Muxer *mux, const OptionsContext *o)
static int streamcopy_init(const OptionsContext *o, const Muxer *mux, OutputStream *ost, AVDictionary **encoder_opts)
#define IS_AV_ENC(ost, type)
static int meta_spec_matches(void *log_ctx, AVFormatContext *oc, AVStream *st, const char *spec)
static const char *const forced_keyframes_const_names[]
static int of_add_programs(Muxer *mux, const OptionsContext *o)
static const char * output_file_item_name(void *obj)
static int reenc_delete_metadata_key(const OptionsContext *o, void *log_ctx, AVFormatContext *oc, AVStream *st, const char *family, const char *key, int flags)
static int map_manual(Muxer *mux, const OptionsContext *o, const StreamMap *map)
#define SERIALIZE(parent, child)
static int of_add_attachments(Muxer *mux, const OptionsContext *o)
static int of_add_metadata(OutputFile *of, AVFormatContext *oc, const OptionsContext *o)
static const struct @155315260326237246327062132355032355213237357165 reenc_delete_keys[]
static int of_map_group(Muxer *mux, AVDictionary **dict, AVBPrint *bp, const char *map)
static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *os, int copy_metadata)
static int map_auto_data(Muxer *mux, const OptionsContext *o)
static const AVClass output_stream_class
static int ost_get_filters(const OptionsContext *o, AVFormatContext *oc, OutputStream *ost, char **dst)
#define DEFAULT_PASS_LOGFILENAME_PREFIX
static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, const char *name)
static int parse_forced_key_frames(void *log, KeyframeForceCtx *kf, const Muxer *mux, const char *spec)
static const char * output_stream_item_name(void *obj)
static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_us, int shortest)
#define REENC_ANY
static int copy_meta(Muxer *mux, const OptionsContext *o)
static int unescape(char **pdst, size_t *dst_len, const char **pstr, char delim)
static int reenc_delete_stale_metadata(const OptionsContext *o, void *log_ctx, AVFormatContext *oc, AVStream *st, AVDictionary **dict, const char *kind, unsigned reenc_mask)
static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, InputStream *ist, OutputFilter *ofilter, const ViewSpecifier *vs, OutputStream **post)
static int compare_int64(const void *a, const void *b)
static int enc_stats_init(OutputStream *ost, EncStats *es, int pre, const char *path, const char *fmt_spec)
static int map_auto_video(Muxer *mux, const OptionsContext *o)
static int64_t get_stream_group_index_from_id(Muxer *mux, int64_t id)
int of_open(const OptionsContext *o, const char *filename, Scheduler *sch)
static int enc_stats_get_file(AVIOContext **io, const char *path)
#define IS_INTERLEAVED(type)
static int new_stream_subtitle(Muxer *mux, const OptionsContext *o, OutputStream *ost)
static int process_forced_keyframes(Muxer *mux, const OptionsContext *o)
void of_enc_stats_close(void)
#define REENC_MASK(type)
static int set_encoder_id(OutputStream *ost, const AVCodec *codec)
static MuxStream * mux_stream_alloc(Muxer *mux, enum AVMediaType type)
static char * get_line(AVIOContext *s, AVBPrint *bprint)
static Muxer * mux_alloc(void)
static int parse_meta_type(void *logctx, const char *arg, char *type, int *index, const char **stream_spec)
Parse a metadata specifier passed as 'arg' parameter.
static int set_dispositions(Muxer *mux, const OptionsContext *o)
static int check_stereo3d_leftovers(Muxer *mux, const OptionsContext *o)
static int new_stream_audio(Muxer *mux, const OptionsContext *o, OutputStream *ost)
static int choose_encoder(const OptionsContext *o, AVFormatContext *s, MuxStream *ms, const AVCodec **enc)
static const AVClass output_file_class
static int nb_enc_stats_files
static int parse_matrix_coeffs(void *logctx, uint16_t *dest, const char *str)
static int of_parse_iamf_submixes(Muxer *mux, AVStreamGroup *stg, char *ptr)
static int check_opt_bitexact(void *ctx, const AVDictionary *opts, const char *opt_name, int flag)
static int map_auto_audio(Muxer *mux, const OptionsContext *o)
unsigned reenc_mask
static int copy_metadata(Muxer *mux, AVFormatContext *ic, const char *outspec, const char *inspec, int *metadata_global_manual, int *metadata_streams_manual, int *metadata_chapters_manual)
const char * key
static int map_auto_subtitle(Muxer *mux, const OptionsContext *o)
static EncStatsFile * enc_stats_files
static int pixfmt_in_list(const enum AVPixelFormat *formats, enum AVPixelFormat format)
static int of_add_groups(Muxer *mux, const OptionsContext *o)
static int of_serialize_options(Muxer *mux, void *obj, AVBPrint *bp)
static int new_stream_video(Muxer *mux, const OptionsContext *o, OutputStream *ost, int *keep_pix_fmt, enum VideoSyncMethod *vsync_method)
static int ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter, const OptionsContext *o, AVRational enc_tb, enum VideoSyncMethod vsync_method, int keep_pix_fmt, int autoscale, int threads_manual, const ViewSpecifier *vs, SchedulerNode *src)
static enum AVPixelFormat choose_pixel_fmt(const AVCodecContext *avctx, enum AVPixelFormat target)
int sch_mux_sub_heartbeat_add(Scheduler *sch, unsigned mux_idx, unsigned stream_idx, unsigned dec_idx)
int sch_add_sq_enc(Scheduler *sch, uint64_t buf_size_us, void *logctx)
Add an pre-encoding sync queue to the scheduler.
int sch_sq_add_enc(Scheduler *sch, unsigned sq_idx, unsigned enc_idx, int limiting, uint64_t max_frames)
void sch_mux_stream_buffering(Scheduler *sch, unsigned mux_idx, unsigned stream_idx, size_t data_threshold, int max_packets)
Configure limits on packet buffering performed before the muxer task is started.
int sch_add_enc(Scheduler *sch, SchThreadFunc func, void *ctx, int(*open_cb)(void *opaque, const AVFrame *frame))
Add an encoder to the scheduler.
int sch_connect(Scheduler *sch, SchedulerNode src, SchedulerNode dst)
int sch_add_mux(Scheduler *sch, SchThreadFunc func, int(*init)(void *), void *arg, int sdp_auto, unsigned thread_queue_size)
Add a muxer to the scheduler.
int sch_add_mux_stream(Scheduler *sch, unsigned mux_idx)
Add a muxed stream for a previously added muxer.
#define SCH_MSTREAM(file, stream)
#define SCH_ENC(encoder)
@ SCH_NODE_TYPE_NONE
static int video_disable
Definition ffplay.c:387
static const char * subtitle_codec_name
Definition ffplay.c:416
static int audio_disable
Definition ffplay.c:386
static int64_t start_time
Definition ffplay.c:398
static unsigned int nb_streams
Definition ffprobe.c:353
static FILE * fopen_utf8(const char *path, const char *mode)
Definition fopen_utf8.h:66
static const uint8_t frame_size[4]
Definition g723_1.h:222
static char * getenv_utf8(const char *varname)
Definition getenv_utf8.h:67
static void freeenv_utf8(char *var)
Definition getenv_utf8.h:72
#define fail
Definition test.h:479
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition opt.h:351
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
int av_bsf_list_parse_str(const char *str, AVBSFContext **bsf_lst)
Parse string describing list of bitstream filters and create single AVBSFContext describing the whole...
Definition bsf.c:524
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
#define AV_CODEC_FLAG_BITEXACT
Use only bitexact stuff (except (I)DCT).
Definition avcodec.h:322
#define AV_CODEC_FLAG_PASS2
Use internal 2pass ratecontrol in second pass mode.
Definition avcodec.h:294
#define AV_CODEC_CAP_VARIABLE_FRAME_SIZE
Audio encoder supports receiving a different number of samples in each call.
Definition codec.h:116
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition options.c:149
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition avcodec.h:213
#define AV_CODEC_FLAG_PASS1
Use internal 2pass ratecontrol in first pass mode.
Definition avcodec.h:290
#define AV_CODEC_FLAG2_FIXED_FRAME_SIZE
Force audio encoders to use a fixed frame size.
Definition avcodec.h:359
const AVCodec * avcodec_find_encoder(enum AVCodecID id)
Find a registered encoder with a matching codec ID.
Definition allcodecs.c:990
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition avcodec.h:318
const char * avcodec_get_name(enum AVCodecID id)
Get the name of a codec.
Definition utils.c:421
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
#define AV_CODEC_PROP_BITMAP_SUB
Subtitle codec is bitmap based Decoded AVSubtitle data can be read from the AVSubtitleRect->pict fiel...
Definition codec_desc.h:111
#define AV_CODEC_PROP_ENHANCEMENT
Video codec contains enhancement information meant to be applied to other existing frames,...
Definition codec_desc.h:105
int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
Return codec bits per sample.
Definition utils.c:461
#define AV_CODEC_PROP_TEXT_SUB
Subtitle codec is text based.
Definition codec_desc.h:116
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
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_AC3
Definition codec_id.h:459
@ AV_CODEC_ID_MP3
preferred ID for decoding MPEG audio layer 1, 2 or 3
Definition codec_id.h:457
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
int avcodec_get_supported_config(const AVCodecContext *avctx, const AVCodec *codec, enum AVCodecConfig config, unsigned flags, const void **out, int *out_num)
Retrieve a list of all supported values for a given configuration type.
Definition avcodec.c:822
@ AVDISCARD_ALL
discard all
Definition defs.h:246
@ AV_CODEC_CONFIG_PIX_FORMAT
AVPixelFormat, terminated by AV_PIX_FMT_NONE.
Definition avcodec.h:2588
@ AV_CODEC_CONFIG_SAMPLE_FORMAT
AVSampleFormat, terminated by AV_SAMPLE_FMT_NONE.
Definition avcodec.h:2591
@ AV_CODEC_CONFIG_ALPHA_MODE
AVAlphaMode, terminated by AVALPHA_MODE_UNSPECIFIED.
Definition avcodec.h:2595
@ AV_CODEC_CONFIG_FRAME_RATE
AVRational, terminated by {0, 0}.
Definition avcodec.h:2589
@ AV_CODEC_CONFIG_COLOR_SPACE
AVColorSpace, terminated by AVCOL_SPC_UNSPECIFIED.
Definition avcodec.h:2594
@ AV_CODEC_CONFIG_CHROMA_LOCATION
AVChromaLocation, terminated by AVCHROMA_LOC_UNSPECIFIED.
Definition avcodec.h:2596
@ AV_CODEC_CONFIG_COLOR_RANGE
AVColorRange, terminated by AVCOL_RANGE_UNSPECIFIED.
Definition avcodec.h:2593
@ AV_CODEC_CONFIG_SAMPLE_RATE
int, terminated by 0
Definition avcodec.h:2590
@ AV_CODEC_CONFIG_CHANNEL_LAYOUT
AVChannelLayout, terminated by {0}.
Definition avcodec.h:2592
AVPacketSideData * av_packet_side_data_new(AVPacketSideData **psd, int *pnb_sd, enum AVPacketSideDataType type, size_t size, int flags)
Allocate a new packet side data.
Definition packet.c:620
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition packet.c:63
AVProgram * av_new_program(AVFormatContext *ac, int id)
Definition avformat.c:284
AVStreamGroup * avformat_stream_group_create(AVFormatContext *s, enum AVStreamGroupParamsType type, AVDictionary **options)
Add a new empty stream group to a media file.
Definition options.c:472
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
int avformat_stream_group_add_stream(AVStreamGroup *stg, AVStream *st)
Add an already allocated stream to a stream group.
Definition options.c:561
enum AVCodecID av_guess_codec(const AVOutputFormat *fmt, const char *short_name, const char *filename, const char *mime_type, enum AVMediaType type)
Guess the codec ID based upon muxer and filename.
Definition format.c:117
enum AVCodecID av_codec_get_id(const struct AVCodecTag *const *tags, unsigned int tag)
Get the AVCodecID for the given codec tag tag.
int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id, int std_compliance)
Test if the given container can store a codec.
Definition mux_utils.c:32
int av_codec_get_tag2(const struct AVCodecTag *const *tags, enum AVCodecID id, unsigned int *tag)
Get the codec tag for the given codec id.
int av_filename_number_test(const char *filename)
Check whether filename actually is a numbered sequence generator.
Definition utils.c:121
void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output)
Print detailed information about the input or output format, such as duration, bitrate,...
Definition dump.c:854
int av_channel_layout_from_string(AVChannelLayout *channel_layout, const char *str)
Initialize a channel layout from a given string description.
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition bprint.h:218
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:234
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition bprint.c:129
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition bprint.c:226
#define AV_DICT_MULTIKEY
Allow to store several equal keys in the dictionary.
Definition dict.h:84
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
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
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
Definition dict.h:75
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition dict.c:247
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition dict.h:79
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
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition dict.h:81
int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)
Parse the key/value pairs list and add the parsed entries to a dictionary.
Definition dict.c:210
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition dict.h:74
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
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition avutil.h:226
#define AVERROR_ENCODER_NOT_FOUND
Encoder not found.
Definition error.h:56
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
AVIAMFLayer * av_iamf_audio_element_add_layer(AVIAMFAudioElement *audio_element)
Allocate a layer and add it to a given AVIAMFAudioElement.
AVIAMFSubmixLayout * av_iamf_submix_add_layout(AVIAMFSubmix *submix)
Allocate a submix layout and add it to a given AVIAMFSubmix.
AVIAMFSubmix * av_iamf_mix_presentation_add_submix(AVIAMFMixPresentation *mix_presentation)
Allocate a submix and add it to a given AVIAMFMixPresentation.
AVIAMFSubmixElement * av_iamf_submix_add_element(AVIAMFSubmix *submix)
Allocate a submix element and add it to a given AVIAMFSubmix.
static av_always_inline void * av_iamf_param_definition_get_subblock(const AVIAMFParamDefinition *par, unsigned int idx)
Get the subblock at the specified idx.
Definition iamf.h:260
AVIAMFParamDefinition * av_iamf_param_definition_alloc(enum AVIAMFParamDefinitionType type, unsigned int nb_subblocks, size_t *out_size)
Allocates memory for AVIAMFParamDefinition, plus an array of nb_subblocks amount of subblocks of the ...
Definition iamf.c:159
@ AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN
Subblocks are of struct type AVIAMFReconGain.
Definition iamf.h:181
@ AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN
Subblocks are of struct type AVIAMFMixGain.
Definition iamf.h:173
@ AV_IAMF_PARAMETER_DEFINITION_DEMIXING
Subblocks are of struct type AVIAMFDemixingInfo.
Definition iamf.h:177
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition log.h:204
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
AVRational av_add_q(AVRational b, AVRational c)
Add two rationals.
Definition rational.c:93
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
Definition rational.c:80
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition rational.h:159
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition mem.c:318
const char * av_get_media_type_string(enum AVMediaType media_type)
Return a string describing the media_type enum, NULL if media_type is unknown.
Definition utils.c:28
AVMediaType
Definition avutil.h:198
@ AVMEDIA_TYPE_ATTACHMENT
Opaque data information usually sparse.
Definition avutil.h:204
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_NB
Definition avutil.h:205
@ AVMEDIA_TYPE_SUBTITLE
Definition avutil.h:203
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition avutil.h:202
@ AVMEDIA_TYPE_UNKNOWN
Usually treated as AVMEDIA_TYPE_DATA.
Definition avutil.h:199
enum AVSampleFormat av_get_sample_fmt(const char *name)
Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE on error.
Definition samplefmt.c:59
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
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
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition avstring.c:179
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition avstring.c:208
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
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
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
AVStereo3DType
List of possible 3D Types.
Definition stereo3d.h:48
const char * av_stereo3d_type_name(unsigned int type)
Provide a human-readable name of a given stereo3d type.
Definition stereo3d.c:93
@ AV_STEREO3D_2D
Video is not stereoscopic (and metadata has to be there).
Definition stereo3d.h:52
@ AV_STEREO3D_TOPBOTTOM
Views are on top of each other.
Definition stereo3d.h:76
@ AV_STEREO3D_SIDEBYSIDE
Views are next to each other.
Definition stereo3d.h:64
int av_opt_eval_int(void *obj, const AVOption *o, const char *val, int *int_out)
int av_opt_eval_flags(void *obj, const AVOption *o, const char *val, int *flags_out)
int av_opt_get_int(void *obj, const char *name, int search_flags, int64_t *out_val)
Definition opt.c:1349
#define AV_OPT_SEARCH_CHILDREN
Search in possible children of the given object first.
Definition opt.h:604
const AVOption * av_opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags)
Look for an option in an object.
Definition opt.c:2071
int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer, const char key_val_sep, const char pairs_sep)
Serialize object's options.
Definition opt.c:2842
#define AV_OPT_SERIALIZE_SKIP_DEFAULTS
Serialize options that are not set to default values only.
Definition opt.h:1092
int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_flags)
Check if given option is set to its default value.
Definition opt.c:2787
#define AV_OPT_SERIALIZE_SEARCH_CHILDREN
Serialize options in possible children of the given object.
Definition opt.h:1094
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:891
int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags)
Set all the options from a given dictionary on an object.
Definition opt.c:2042
int av_opt_set_dict(void *obj, AVDictionary **options)
Set all the options from a given dictionary on an object.
Definition opt.c:2066
int index
Definition gxfenc.c:90
int a
const VDPAUPixFmtMap * map
#define b
Definition input.c:43
#define AV_RL32(p)
uint32_t type
Definition jpegmpfenc.c:80
static int mix(int c0, int c1)
Definition 4xm.c:717
const char * arg
Definition jacosubdec.c:65
#define LIBAVCODEC_IDENT
Definition version.h:43
Immersive Audio Model and Formats API header.
Stereoscopic video.
const char * desc
Definition libsvtav1.c:83
@ AV_CLASS_CATEGORY_MUXER
Definition log.h:32
#define FFMIN(a, b)
Definition macros.h:49
#define MKTAG(a, b, c, d)
Definition macros.h:55
#define FFMAX(a, b)
Definition macros.h:47
#define FFDIFFSIGN(x, y)
Comparator.
Definition macros.h:45
#define NAN
static const alias aliases[20]
Definition mccdec.c:90
uint64_t layout
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
Memory handling functions.
uint32_t tag
Definition movenc.c:2128
static const char * obj
Definition mscl.c:57
#define av_strdup(s)
Definition ops_static.c:55
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition os2threads.h:104
int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
Parse str and put in width_ptr and height_ptr the detected values.
Definition parseutils.c:150
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
Definition parseutils.c:181
int av_parse_ratio(AVRational *q, const char *str, int max, int log_offset, void *log_ctx)
Parse str and store the parsed ratio in q.
Definition parseutils.c:45
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
misc parsing utilities
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3404
enum AVPixelFormat av_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2, enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
Compute what kind of losses will occur when converting from one specific pixel format to another.
Definition pixdesc.c:3763
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
Definition pixdesc.c:3416
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3484
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
const char * name
Definition qsvenc.c:142
formats
Definition signature.h:47
static const ElemCat * elements[ELEMENT_COUNT]
Definition signature.h:565
#define FF_ARRAY_ELEMS(a)
enum AVChannelOrder order
Channel order used in this layout.
int nb_channels
Number of channels in this layout.
int64_t id
unique ID to identify the chapter
Definition avformat.h:1297
int64_t start
Definition avformat.h:1299
AVDictionary * metadata
Definition avformat.h:1300
int64_t end
chapter start/end time in time_base units
Definition avformat.h:1299
AVRational time_base
time base in which the start/end timestamps are specified
Definition avformat.h:1298
Describe the class of an AVClass context structure.
Definition log.h:76
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
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
uint16_t * chroma_intra_matrix
custom intra quantization matrix
Definition avcodec.h:976
int width
picture width / height.
Definition avcodec.h:604
AVChannelLayout ch_layout
Audio channel layout.
Definition avcodec.h:1055
enum AVSampleFormat sample_fmt
audio sample format
Definition avcodec.h:1047
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition avcodec.h:681
char * stats_in
pass2 encoding statistics input buffer Concatenated stuff from stats_out of pass1 should be placed he...
Definition avcodec.h:1338
int rc_override_count
ratecontrol override, see RcOverride
Definition avcodec.h:1280
uint16_t * inter_matrix
custom inter quantization matrix Must be allocated with the av_malloc() family of functions,...
Definition avcodec.h:969
const struct AVCodec * codec
Definition avcodec.h:452
enum AVColorSpace colorspace
YUV colorspace type.
Definition avcodec.h:671
int sample_rate
samples per second
Definition avcodec.h:1040
uint16_t * intra_matrix
custom intra quantization matrix Must be allocated with the av_malloc() family of functions,...
Definition avcodec.h:960
int flags
AV_CODEC_FLAG_*.
Definition avcodec.h:500
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition avcodec.h:688
enum AVAlphaMode alpha_mode
Indicates how the alpha channel of the video is represented.
Definition avcodec.h:1942
RcOverride * rc_override
Definition avcodec.h:1281
enum AVCodecID codec_id
Definition avcodec.h:453
This struct describes the properties of a single codec described by an AVCodecID.
Definition codec_desc.h:38
int props
Codec properties, a combination of AV_CODEC_PROP_* flags.
Definition codec_desc.h:54
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int nb_coded_side_data
Amount of entries in coded_side_data.
Definition codec_par.h:88
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
int width
The width of the video frame in pixels.
Definition codec_par.h:143
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition codec_par.h:221
AVRational sample_aspect_ratio
The aspect ratio (width/height) which a single pixel should have when displayed.
Definition codec_par.h:161
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition codec_par.h:61
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
AVPacketSideData * coded_side_data
Additional data associated with the entire stream.
Definition codec_par.h:83
AVCodec.
Definition codec.h:175
enum AVCodecID id
Definition codec.h:189
const char * name
Name of the codec implementation.
Definition codec.h:182
char * key
Definition dict.h:91
char * value
Definition dict.h:92
Format I/O context.
Definition avformat.h:1337
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition avformat.h:1393
AVStreamGroup ** stream_groups
A list of all stream groups in the file.
Definition avformat.h:1424
AVIOContext * pb
I/O context.
Definition avformat.h:1379
AVDictionary * metadata
Metadata that applies to the whole file.
Definition avformat.h:1584
int flags
Flags modifying the (de)muxer behaviour.
Definition avformat.h:1488
const struct AVOutputFormat * oformat
The output container format.
Definition avformat.h:1356
AVProgram ** programs
Definition avformat.h:1550
unsigned int nb_programs
Definition avformat.h:1549
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition avformat.h:1622
char * url
input or output URL.
Definition avformat.h:1453
unsigned int nb_chapters
Number of chapters in AVChapter array.
Definition avformat.h:1437
AVChapter ** chapters
Definition avformat.h:1438
unsigned int nb_stream_groups
Number of elements in AVFormatContext.stream_groups.
Definition avformat.h:1412
AVStream ** streams
A list of all streams in the file.
Definition avformat.h:1405
int64_t duration
Duration of the stream, in AV_TIME_BASE fractional seconds.
Definition avformat.h:1472
Information on how to combine one or more audio streams, as defined in section 3.6 of IAMF.
Definition iamf.h:359
AVIAMFParamDefinition * recon_gain_info
Recon gain information used to reconstruct a scalable channel audio representation.
Definition iamf.h:386
AVIAMFParamDefinition * demixing_info
Demixing information used to reconstruct a scalable channel audio representation.
Definition iamf.h:379
unsigned int nb_layers
Number of layers, or channel groups, in the Audio Element.
Definition iamf.h:371
A layer defining a Channel Layout in the Audio Element.
Definition iamf.h:294
Information on how to render and mix one or more AVIAMFAudioElement to generate the final audio outpu...
Definition iamf.h:616
Parameters as defined in section 3.6.1 of IAMF.
Definition iamf.h:193
unsigned int nb_subblocks
Number of subblocks in the array.
Definition iamf.h:208
Submix element as defined in section 3.7 of IAMF.
Definition iamf.h:449
AVIAMFParamDefinition * element_mix_config
Information required required for applying any processing to the referenced and rendered Audio Elemen...
Definition iamf.h:464
unsigned int audio_element_id
The id of the Audio Element this submix element references.
Definition iamf.h:455
Submix layout as defined in section 3.7.6 of IAMF.
Definition iamf.h:517
Submix layout as defined in section 3.7 of IAMF.
Definition iamf.h:559
unsigned int nb_elements
Number of elements in the submix.
Definition iamf.h:575
AVIAMFSubmixElement ** elements
Array of submix elements.
Definition iamf.h:568
AVIAMFParamDefinition * output_mix_config
Information required for post-processing the mixed audio signal to generate the audio signal for play...
Definition iamf.h:598
Bytestream IO Context.
Definition avio.h:160
AVOption.
Definition opt.h:428
enum AVCodecID video_codec
default video codec
Definition avformat.h:540
int flags
can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_EXPERIMENTAL, AVFMT_GLOBALHEADER,...
Definition avformat.h:548
const char * name
Definition avformat.h:529
const struct AVCodecTag *const * codec_tag
List of supported codec_id-codec_tag pairs, ordered by "betterchoice first".
Definition avformat.h:554
enum AVCodecID subtitle_codec
default subtitle codec
Definition avformat.h:541
This structure stores auxiliary information for decoding, presenting, or otherwise processing the cod...
Definition packet.h:424
uint8_t * data
Definition packet.h:425
enum AVPacketSideDataType type
Definition packet.h:427
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
New fields can be added to the end with minor version bumps.
Definition avformat.h:1261
AVDictionary * metadata
Definition avformat.h:1267
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
AVStreamGroupTileGrid holds information on how to combine several independent images on a single canv...
Definition avformat.h:975
int width
Width of the final image for presentation.
Definition avformat.h:1060
int height
Height of the final image for presentation.
Definition avformat.h:1070
union AVStreamGroup::@166361102046003066253145020066347265153020354020 params
Group type-specific parameters.
enum AVStreamGroupParamsType type
Group type.
Definition avformat.h:1190
struct AVIAMFMixPresentation * iamf_mix_presentation
Definition avformat.h:1197
struct AVStreamGroupTileGrid * tile_grid
Definition avformat.h:1198
unsigned int nb_streams
Number of elements in AVStreamGroup.streams.
Definition avformat.h:1225
unsigned int index
Group index in AVFormatContext.
Definition avformat.h:1174
struct AVIAMFAudioElement * iamf_audio_element
Definition avformat.h:1196
int disposition
Stream group disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:1248
int64_t id
Group type-specific group ID.
Definition avformat.h:1182
AVStream ** streams
A list of streams in the group.
Definition avformat.h:1238
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown)
Definition avformat.h:846
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition avformat.h:827
AVDictionary * metadata
Definition avformat.h:848
int id
Format-specific stream ID.
Definition avformat.h:780
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:857
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:807
int event_flags
Flags indicating events happening on the stream, a combination of AVSTREAM_EVENT_FLAG_*.
Definition avformat.h:879
AVRational r_frame_rate
Real base framerate of the stream.
Definition avformat.h:902
int disposition
Stream disposition - a combination of AV_DISPOSITION_* flags.
Definition avformat.h:837
AVIOContext * io
int nb_components
Definition ffmpeg.h:581
AVIOContext * io
Definition ffmpeg.h:583
EncStatsComponent * components
Definition ffmpeg.h:580
pthread_mutex_t lock
Definition ffmpeg.h:585
int lock_initialized
Definition ffmpeg.h:586
int index
Definition ffmpeg.h:404
int nb_outputs
Definition ffmpeg.h:409
OutputFilter ** outputs
Definition ffmpeg.h:408
int64_t ts_offset
Definition ffmpeg.h:523
AVFormatContext * ctx
Definition ffmpeg.h:516
int64_t input_ts_offset
Definition ffmpeg.h:517
int index
Definition ffmpeg.h:514
int nb_stream_groups
Definition ffmpeg.h:535
InputStream ** streams
Definition ffmpeg.h:530
InputStreamGroup ** stream_groups
Definition ffmpeg.h:534
int64_t start_time
Definition ffmpeg.h:525
int nb_streams
Definition ffmpeg.h:531
FilterGraph * fg
Definition ffmpeg.h:507
AVStreamGroup * stg
Definition ffmpeg.h:508
int index
Definition ffmpeg.h:474
struct InputFile * file
Definition ffmpeg.h:472
int user_set_discard
Definition ffmpeg.h:477
AVCodecParameters * par
Codec parameters - to be used by the decoding/streamcopy code.
Definition ffmpeg.h:484
AVStream * st
Definition ffmpeg.h:476
AVRational framerate
Definition ffmpeg.h:489
int64_t * pts
Definition ffmpeg.h:601
OutputStream ost
Definition ffmpeg_mux.h:37
const char * apad
Definition ffmpeg_mux.h:89
char log_name[32]
Definition ffmpeg_mux.h:46
int copy_prior_start
Definition ffmpeg_mux.h:82
AVPacket * pkt
Definition ffmpeg_mux.h:51
int stereo3d_type
Definition ffmpeg_mux.h:92
int sq_idx_mux
Definition ffmpeg_mux.h:59
int stereo3d_set
Definition ffmpeg_mux.h:91
AVBSFContext * bsf_ctx
Definition ffmpeg_mux.h:48
int64_t max_frames
Definition ffmpeg_mux.h:61
AVCodecParameters * par_in
Codec parameters for packets submitted to the muxer (i.e.
Definition ffmpeg_mux.h:43
int sch_idx_enc
Definition ffmpeg_mux.h:56
int copy_initial_nonkeyframes
Definition ffmpeg_mux.h:81
int sch_idx_src
Definition ffmpeg_mux.h:57
int64_t ts_copy_start
Definition ffmpeg_mux.h:66
int64_t stream_duration
Definition ffmpeg_mux.h:72
AVRational stream_duration_tb
Definition ffmpeg_mux.h:73
int force_fps
Definition ffmpeg_mux.h:87
int64_t last_mux_dts
Definition ffmpeg_mux.h:70
EncStats stats
Definition ffmpeg_mux.h:53
int sch_idx
Definition ffmpeg_mux.h:55
AVRational max_frame_rate
Definition ffmpeg_mux.h:86
AVRational frame_rate
Definition ffmpeg_mux.h:85
AVDictionary * opts
Definition ffmpeg_mux.h:110
AVDictionary * enc_opts_used
Definition ffmpeg_mux.h:113
OutputFile of
Definition ffmpeg_mux.h:96
AVPacket * sq_pkt
Definition ffmpeg_mux.h:121
int nb_sch_stream_idx
Definition ffmpeg_mux.h:108
Scheduler * sch
Definition ffmpeg_mux.h:103
char log_name[32]
Definition ffmpeg_mux.h:99
SyncQueue * sq_mux
Definition ffmpeg_mux.h:120
AVFormatContext * fc
Definition ffmpeg_mux.h:101
unsigned sch_idx
Definition ffmpeg_mux.h:104
int * sch_stream_idx
Definition ffmpeg_mux.h:107
int64_t limit_filesize
Definition ffmpeg_mux.h:116
AVDictionary * codec_opts
Definition cmdutils.h:347
AVDictionary * swr_opts
Definition cmdutils.h:350
AVDictionary * sws_dict
Definition cmdutils.h:349
AVDictionary * format_opts
Definition cmdutils.h:348
float mux_preload
Definition ffmpeg.h:181
SpecifierOptList rc_overrides
Definition ffmpeg.h:212
SpecifierOptList enc_stats_pre
Definition ffmpeg.h:241
SpecifierOptList metadata_map
Definition ffmpeg.h:216
int nb_stream_maps
Definition ffmpeg.h:172
SpecifierOptList frame_pix_fmts
Definition ffmpeg.h:148
SpecifierOptList intra_matrices
Definition ffmpeg.h:213
SpecifierOptList enc_stats_post_fmt
Definition ffmpeg.h:245
SpecifierOptList codec_tags
Definition ffmpeg.h:199
SpecifierOptList stream_groups
Definition ffmpeg.h:235
SpecifierOptList qscale
Definition ffmpeg.h:201
int64_t start_time
Definition ffmpeg.h:136
SpecifierOptList enc_stats_post
Definition ffmpeg.h:242
SpecifierOptList codec_names
Definition ffmpeg.h:141
const char * format
Definition ffmpeg.h:139
int nb_attachments
Definition ffmpeg.h:174
SpecifierOptList mux_stats
Definition ffmpeg.h:243
SpecifierOptList disposition
Definition ffmpeg.h:233
SpecifierOptList audio_channels
Definition ffmpeg.h:143
StreamMap * stream_maps
Definition ffmpeg.h:171
SpecifierOptList inter_matrices
Definition ffmpeg.h:214
SpecifierOptList stereo3ds
Definition ffmpeg.h:206
SpecifierOptList mux_stats_fmt
Definition ffmpeg.h:246
SpecifierOptList pass
Definition ffmpeg.h:226
SpecifierOptList muxing_queue_data_threshold
Definition ffmpeg.h:229
SpecifierOptList presets
Definition ffmpeg.h:217
SpecifierOptList copy_prior_start
Definition ffmpeg.h:219
int64_t recording_time
Definition ffmpeg.h:178
SpecifierOptList time_bases
Definition ffmpeg.h:236
SpecifierOptList frame_rates
Definition ffmpeg.h:145
SpecifierOptList forced_key_frames
Definition ffmpeg.h:202
float shortest_buf_duration
Definition ffmpeg.h:183
SpecifierOptList keep_metadata
Definition ffmpeg.h:196
SpecifierOptList enc_stats_pre_fmt
Definition ffmpeg.h:244
SpecifierOptList force_fps
Definition ffmpeg.h:204
int thread_queue_size
Definition ffmpeg.h:158
int data_disable
Definition ffmpeg.h:190
int chapters_input_file
Definition ffmpeg.h:176
SpecifierOptList max_frame_rates
Definition ffmpeg.h:146
int video_disable
Definition ffmpeg.h:187
int audio_disable
Definition ffmpeg.h:188
SpecifierOptList program
Definition ffmpeg.h:234
SpecifierOptList fps_mode
Definition ffmpeg.h:203
SpecifierOptList copy_initial_nonkeyframes
Definition ffmpeg.h:218
SpecifierOptList filters
Definition ffmpeg.h:220
SpecifierOptList enc_reinit_opts
Definition ffmpeg.h:240
AVDictionary * streamid
Definition ffmpeg.h:193
SpecifierOptList max_muxing_queue_size
Definition ffmpeg.h:228
SpecifierOptList bits_per_raw_sample
Definition ffmpeg.h:239
int64_t stop_time
Definition ffmpeg.h:179
const char ** attachments
Definition ffmpeg.h:173
SpecifierOptList passlogfiles
Definition ffmpeg.h:227
SpecifierOptList enc_time_bases
Definition ffmpeg.h:237
int64_t limit_filesize
Definition ffmpeg.h:180
SpecifierOptList audio_sample_rate
Definition ffmpeg.h:144
SpecifierOptList sample_fmts
Definition ffmpeg.h:200
SpecifierOptList frame_aspect_ratios
Definition ffmpeg.h:205
float mux_max_delay
Definition ffmpeg.h:182
SpecifierOptList autoscale
Definition ffmpeg.h:238
SpecifierOptList max_frames
Definition ffmpeg.h:197
SpecifierOptList metadata
Definition ffmpeg.h:195
SpecifierOptList bitstream_filters
Definition ffmpeg.h:198
SpecifierOptList chroma_intra_matrices
Definition ffmpeg.h:215
SpecifierOptList fix_sub_duration_heartbeat
Definition ffmpeg.h:224
SpecifierOptList apad
Definition ffmpeg.h:231
int subtitle_disable
Definition ffmpeg.h:189
SpecifierOptList frame_sizes
Definition ffmpeg.h:147
SpecifierOptList audio_ch_layouts
Definition ffmpeg.h:142
OptionGroup * g
Definition ffmpeg.h:133
int index
Definition ffmpeg.h:693
const char * url
Definition ffmpeg.h:695
int bitexact
Definition ffmpeg.h:703
OutputStream ** streams
Definition ffmpeg.h:697
int nb_streams
Definition ffmpeg.h:698
int64_t start_time
start time in microseconds == AV_TIME_BASE units
Definition ffmpeg.h:701
int64_t recording_time
desired length of the resulting file in microseconds == AV_TIME_BASE units
Definition ffmpeg.h:700
const AVClass * class
Definition ffmpeg.h:691
uint8_t * name
Definition ffmpeg.h:382
uint8_t * linklabel
Definition ffmpeg.h:392
struct FilterGraph * graph
Definition ffmpeg.h:381
char * apad
Definition ffmpeg.h:394
enum AVMediaType type
Definition ffmpeg.h:396
enum AVMediaType type
Definition ffmpeg.h:641
struct OutputFile * file
Definition ffmpeg.h:644
OutputFilter * filter
Definition ffmpeg.h:669
const AVClass * class
Definition ffmpeg.h:639
AVStream * st
Definition mux.c:54
int qscale
Definition avcodec.h:196
int start_frame
Definition avcodec.h:194
int end_frame
Definition avcodec.h:195
float quality_factor
Definition avcodec.h:197
SpecifierOpt * opt
Definition cmdutils.h:184
StreamSpecifier stream_spec
Definition cmdutils.h:171
union SpecifierOpt::@356325016025214271156003270003007057215065005026 u
uint8_t * str
Definition cmdutils.h:174
char * specifier
Definition cmdutils.h:169
void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx, uint64_t frames)
Limit the number of output frames for stream with index stream_idx to max_frames.
Definition sync_queue.c:628
int sq_add_stream(SyncQueue *sq, int limiting)
Add a new stream to the sync queue.
Definition sync_queue.c:598
SyncQueue * sq_alloc(enum SyncQueueType type, int64_t buf_size_us, void *logctx)
Allocate a sync queue of the given type.
Definition sync_queue.c:654
@ SYNC_QUEUE_PACKETS
Definition sync_queue.h:29
#define av_free(p)
#define av_malloc_array(a, b)
#define av_mallocz(s)
#define av_realloc_f(p, o, n)
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
static int64_t pts
int size
enum AVCodecID codec_id
static AVStream * ost
preset
Definition vf_curves.c:47
int len
uint8_t base
Definition vp3data.h:128
static double c[64]