2 * Muxer/output file setup.
4 * This file is part of FFmpeg.
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.
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.
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
25 #include "ffmpeg_mux.h"
26 #include "ffmpeg_sched.h"
27 #include "fopen_utf8.h"
29 #include "libavformat/avformat.h"
30 #include "libavformat/avio.h"
32 #include "libavcodec/avcodec.h"
34 #include "libavfilter/avfilter.h"
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"
42 #include "libavutil/getenv_utf8.h"
43 #include "libavutil/iamf.h"
44 #include "libavutil/intreadwrite.h"
45 #include "libavutil/log.h"
46 #include "libavutil/mem.h"
47 #include "libavutil/opt.h"
48 #include "libavutil/parseutils.h"
49 #include "libavutil/pixdesc.h"
51 #define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
53 static int check_opt_bitexact(void *ctx
, const AVDictionary
*opts
,
54 const char *opt_name
, int flag
)
56 const AVDictionaryEntry
*e
= av_dict_get(opts
, opt_name
, NULL
, 0);
59 const AVOption
*o
= av_opt_find(ctx
, opt_name
, NULL
, 0, 0);
63 av_opt_eval_flags(ctx
, o
, e
->value
, &val
);
64 return !!(val
& flag
);
69 static int choose_encoder(const OptionsContext
*o
, AVFormatContext
*s
,
70 MuxStream
*ms
, const AVCodec
**enc
)
72 OutputStream
*ost
= &ms
->ost
;
73 enum AVMediaType type
= ost
->type
;
74 const char *codec_name
= NULL
;
78 opt_match_per_stream_str(ost
, &o
->codec_names
, s
, ost
->st
, &codec_name
);
80 if (type
!= AVMEDIA_TYPE_VIDEO
&&
81 type
!= AVMEDIA_TYPE_AUDIO
&&
82 type
!= AVMEDIA_TYPE_SUBTITLE
) {
83 if (codec_name
&& strcmp(codec_name
, "copy")) {
84 const char *type_str
= av_get_media_type_string(type
);
85 av_log(ost
, AV_LOG_FATAL
,
86 "Encoder '%s' specified, but only '-codec copy' supported "
87 "for %s streams\n", codec_name
, type_str
);
88 return AVERROR(ENOSYS
);
94 ms
->par_in
->codec_id
= av_guess_codec(s
->oformat
, NULL
, s
->url
, NULL
, ost
->type
);
95 *enc
= avcodec_find_encoder(ms
->par_in
->codec_id
);
97 av_log(ost
, AV_LOG_FATAL
, "Automatic encoder selection failed "
98 "Default encoder for format %s (codec %s) is "
99 "probably disabled. Please choose an encoder manually.\n",
100 s
->oformat
->name
, avcodec_get_name(ms
->par_in
->codec_id
));
101 return AVERROR_ENCODER_NOT_FOUND
;
103 } else if (strcmp(codec_name
, "copy")) {
104 int ret
= find_codec(ost
, codec_name
, ost
->type
, 1, enc
);
107 ms
->par_in
->codec_id
= (*enc
)->id
;
113 static char *get_line(AVIOContext
*s
, AVBPrint
*bprint
)
117 while ((c
= avio_r8(s
)) && c
!= '\n')
118 av_bprint_chars(bprint
, c
, 1);
120 if (!av_bprint_is_complete(bprint
))
126 static int get_preset_file_2(const char *preset_name
, const char *codec_name
, AVIOContext
**s
)
130 char *env_avconv_datadir
= getenv_utf8("AVCONV_DATADIR");
131 char *env_home
= getenv_utf8("HOME");
132 const char *base
[3] = { env_avconv_datadir
,
137 for (i
= 0; i
< FF_ARRAY_ELEMS(base
) && ret
< 0; i
++) {
141 snprintf(filename
, sizeof(filename
), "%s%s/%s-%s.avpreset", base
[i
],
142 i
!= 1 ? "" : "/.avconv", codec_name
, preset_name
);
143 ret
= avio_open2(s
, filename
, AVIO_FLAG_READ
, &int_cb
, NULL
);
146 snprintf(filename
, sizeof(filename
), "%s%s/%s.avpreset", base
[i
],
147 i
!= 1 ? "" : "/.avconv", preset_name
);
148 ret
= avio_open2(s
, filename
, AVIO_FLAG_READ
, &int_cb
, NULL
);
151 freeenv_utf8(env_home
);
152 freeenv_utf8(env_avconv_datadir
);
156 typedef struct EncStatsFile
{
161 static EncStatsFile
*enc_stats_files
;
162 static int nb_enc_stats_files
;
164 static int enc_stats_get_file(AVIOContext
**io
, const char *path
)
169 for (int i
= 0; i
< nb_enc_stats_files
; i
++)
170 if (!strcmp(path
, enc_stats_files
[i
].path
)) {
171 *io
= enc_stats_files
[i
].io
;
175 ret
= GROW_ARRAY(enc_stats_files
, nb_enc_stats_files
);
179 esf
= &enc_stats_files
[nb_enc_stats_files
- 1];
181 ret
= avio_open2(&esf
->io
, path
, AVIO_FLAG_WRITE
, &int_cb
, NULL
);
183 av_log(NULL
, AV_LOG_ERROR
, "Error opening stats file '%s': %s\n",
184 path
, av_err2str(ret
));
188 esf
->path
= av_strdup(path
);
190 return AVERROR(ENOMEM
);
197 void of_enc_stats_close(void)
199 for (int i
= 0; i
< nb_enc_stats_files
; i
++) {
200 av_freep(&enc_stats_files
[i
].path
);
201 avio_closep(&enc_stats_files
[i
].io
);
203 av_freep(&enc_stats_files
);
204 nb_enc_stats_files
= 0;
207 static int unescape(char **pdst
, size_t *dst_len
,
208 const char **pstr
, char delim
)
210 const char *str
= *pstr
;
220 dst
= av_malloc(len
+ 1);
222 return AVERROR(ENOMEM
);
224 for (idx
= 0; *str
; idx
++, str
++) {
225 if (str
[0] == '\\' && str
[1])
227 else if (*str
== delim
)
246 static int enc_stats_init(OutputStream
*ost
, EncStats
*es
, int pre
,
247 const char *path
, const char *fmt_spec
)
249 static const struct {
250 enum EncStatsType type
;
253 unsigned post_only
:1;
254 unsigned need_input_data
:1;
256 { ENC_STATS_FILE_IDX
, "fidx" },
257 { ENC_STATS_STREAM_IDX
, "sidx" },
258 { ENC_STATS_FRAME_NUM
, "n" },
259 { ENC_STATS_FRAME_NUM_IN
, "ni", 0, 0, 1 },
260 { ENC_STATS_TIMEBASE
, "tb" },
261 { ENC_STATS_TIMEBASE_IN
, "tbi", 0, 0, 1 },
262 { ENC_STATS_PTS
, "pts" },
263 { ENC_STATS_PTS_TIME
, "t" },
264 { ENC_STATS_PTS_IN
, "ptsi", 0, 0, 1 },
265 { ENC_STATS_PTS_TIME_IN
, "ti", 0, 0, 1 },
266 { ENC_STATS_DTS
, "dts", 0, 1 },
267 { ENC_STATS_DTS_TIME
, "dt", 0, 1 },
268 { ENC_STATS_SAMPLE_NUM
, "sn", 1 },
269 { ENC_STATS_NB_SAMPLES
, "samp", 1 },
270 { ENC_STATS_PKT_SIZE
, "size", 0, 1 },
271 { ENC_STATS_BITRATE
, "br", 0, 1 },
272 { ENC_STATS_AVG_BITRATE
, "abr", 0, 1 },
273 { ENC_STATS_KEYFRAME
, "key", 0, 1 },
275 const char *next
= fmt_spec
;
280 EncStatsComponent
*c
;
284 // get the sequence up until next opening brace
285 ret
= unescape(&val
, &val_len
, &next
, '{');
290 ret
= GROW_ARRAY(es
->components
, es
->nb_components
);
296 c
= &es
->components
[es
->nb_components
- 1];
297 c
->type
= ENC_STATS_LITERAL
;
299 c
->str_len
= val_len
;
306 // get the part inside braces
307 ret
= unescape(&val
, &val_len
, &next
, '}');
312 av_log(NULL
, AV_LOG_ERROR
,
313 "Empty formatting directive in: %s\n", fmt_spec
);
314 return AVERROR(EINVAL
);
318 av_log(NULL
, AV_LOG_ERROR
,
319 "Missing closing brace in: %s\n", fmt_spec
);
320 ret
= AVERROR(EINVAL
);
325 ret
= GROW_ARRAY(es
->components
, es
->nb_components
);
329 c
= &es
->components
[es
->nb_components
- 1];
331 for (size_t i
= 0; i
< FF_ARRAY_ELEMS(fmt_specs
); i
++) {
332 if (!strcmp(val
, fmt_specs
[i
].str
)) {
333 if ((pre
&& fmt_specs
[i
].post_only
) || (!pre
&& fmt_specs
[i
].pre_only
)) {
334 av_log(NULL
, AV_LOG_ERROR
,
335 "Format directive '%s' may only be used %s-encoding\n",
336 val
, pre
? "post" : "pre");
337 ret
= AVERROR(EINVAL
);
341 c
->type
= fmt_specs
[i
].type
;
343 if (fmt_specs
[i
].need_input_data
&& !ost
->ist
) {
344 av_log(ost
, AV_LOG_WARNING
,
345 "Format directive '%s' is unavailable, because "
346 "this output stream has no associated input stream\n",
355 av_log(NULL
, AV_LOG_ERROR
, "Invalid format directive: %s\n", val
);
356 ret
= AVERROR(EINVAL
);
366 ret
= pthread_mutex_init(&es
->lock
, NULL
);
369 es
->lock_initialized
= 1;
371 ret
= enc_stats_get_file(&es
->io
, path
);
378 static const char *output_stream_item_name(void *obj
)
380 const MuxStream
*ms
= obj
;
385 static const AVClass output_stream_class
= {
386 .class_name
= "OutputStream",
387 .version
= LIBAVUTIL_VERSION_INT
,
388 .item_name
= output_stream_item_name
,
389 .category
= AV_CLASS_CATEGORY_MUXER
,
392 static MuxStream
*mux_stream_alloc(Muxer
*mux
, enum AVMediaType type
)
394 const char *type_str
= av_get_media_type_string(type
);
397 ms
= allocate_array_elem(&mux
->of
.streams
, sizeof(*ms
), &mux
->of
.nb_streams
);
401 ms
->ost
.file
= &mux
->of
;
402 ms
->ost
.index
= mux
->of
.nb_streams
- 1;
405 ms
->ost
.class = &output_stream_class
;
408 ms
->sch_idx_enc
= -1;
410 snprintf(ms
->log_name
, sizeof(ms
->log_name
), "%cost#%d:%d",
411 type_str
? *type_str
: '?', mux
->of
.index
, ms
->ost
.index
);
416 static int ost_get_filters(const OptionsContext
*o
, AVFormatContext
*oc
,
417 OutputStream
*ost
, char **dst
)
419 const char *filters
= NULL
;
420 #if FFMPEG_OPT_FILTER_SCRIPT
421 const char *filters_script
= NULL
;
423 opt_match_per_stream_str(ost
, &o
->filter_scripts
, oc
, ost
->st
, &filters_script
);
425 opt_match_per_stream_str(ost
, &o
->filters
, oc
, ost
->st
, &filters
);
429 #if FFMPEG_OPT_FILTER_SCRIPT
433 av_log(ost
, AV_LOG_ERROR
,
434 "%s '%s' was specified for a stream fed from a complex "
435 "filtergraph. Simple and complex filtering cannot be used "
436 "together for the same stream.\n",
437 #if FFMPEG_OPT_FILTER_SCRIPT
438 filters
? "Filtergraph" : "Filtergraph script",
439 filters
? filters
: filters_script
441 "Filtergraph", filters
444 return AVERROR(EINVAL
);
449 #if FFMPEG_OPT_FILTER_SCRIPT
450 if (filters_script
&& filters
) {
451 av_log(ost
, AV_LOG_ERROR
, "Both -filter and -filter_script set\n");
452 return AVERROR(EINVAL
);
456 *dst
= read_file_to_string(filters_script
);
460 *dst
= av_strdup(filters
);
462 *dst
= av_strdup(ost
->type
== AVMEDIA_TYPE_VIDEO
? "null" : "anull");
463 return *dst
? 0 : AVERROR(ENOMEM
);
466 static int parse_matrix_coeffs(void *logctx
, uint16_t *dest
, const char *str
)
469 for (int i
= 0;; i
++) {
475 av_log(logctx
, AV_LOG_FATAL
,
476 "Syntax error in matrix \"%s\" at coeff %d\n", str
, i
);
477 return AVERROR(EINVAL
);
485 static int fmt_in_list(const int *formats
, int format
)
487 for (; *formats
!= -1; formats
++)
488 if (*formats
== format
)
493 static enum AVPixelFormat
494 choose_pixel_fmt(const AVCodecContext
*avctx
, enum AVPixelFormat target
)
496 const enum AVPixelFormat
*p
;
497 const AVPixFmtDescriptor
*desc
= av_pix_fmt_desc_get(target
);
498 //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel format without alpha is implemented
499 int has_alpha
= desc
? desc
->nb_components
% 2 == 0 : 0;
500 enum AVPixelFormat best
= AV_PIX_FMT_NONE
;
503 ret
= avcodec_get_supported_config(avctx
, NULL
, AV_CODEC_CONFIG_PIX_FORMAT
,
504 0, (const void **) &p
, NULL
);
506 return AV_PIX_FMT_NONE
;
508 for (; *p
!= AV_PIX_FMT_NONE
; p
++) {
509 best
= av_find_best_pix_fmt_of_2(best
, *p
, target
, has_alpha
, NULL
);
513 if (*p
== AV_PIX_FMT_NONE
) {
514 if (target
!= AV_PIX_FMT_NONE
)
515 av_log(NULL
, AV_LOG_WARNING
,
516 "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
517 av_get_pix_fmt_name(target
),
519 av_get_pix_fmt_name(best
));
525 static enum AVPixelFormat
pix_fmt_parse(OutputStream
*ost
, const char *name
)
527 const enum AVPixelFormat
*fmts
;
528 enum AVPixelFormat fmt
;
531 fmt
= av_get_pix_fmt(name
);
532 if (fmt
== AV_PIX_FMT_NONE
) {
533 av_log(ost
, AV_LOG_FATAL
, "Unknown pixel format requested: %s.\n", name
);
534 return AV_PIX_FMT_NONE
;
537 ret
= avcodec_get_supported_config(ost
->enc
->enc_ctx
, NULL
, AV_CODEC_CONFIG_PIX_FORMAT
,
538 0, (const void **) &fmts
, NULL
);
540 return AV_PIX_FMT_NONE
;
542 /* when the user specified-format is an alias for an endianness-specific
543 * one (e.g. rgb48 -> rgb48be/le), it gets translated into the native
544 * endianness by av_get_pix_fmt();
545 * the following code handles the case when the native endianness is not
546 * supported by the encoder, but the other one is */
547 if (fmts
&& !fmt_in_list(fmts
, fmt
)) {
548 const char *name_canonical
= av_get_pix_fmt_name(fmt
);
549 int len
= strlen(name_canonical
);
551 if (strcmp(name
, name_canonical
) &&
552 (!strcmp(name_canonical
+ len
- 2, "le") ||
553 !strcmp(name_canonical
+ len
- 2, "be"))) {
555 enum AVPixelFormat fmt_other
;
557 snprintf(name_other
, sizeof(name_other
), "%s%ce",
558 name
, name_canonical
[len
- 2] == 'l' ? 'b' : 'l');
559 fmt_other
= av_get_pix_fmt(name_other
);
560 if (fmt_other
!= AV_PIX_FMT_NONE
&& fmt_in_list(fmts
, fmt_other
)) {
561 av_log(ost
, AV_LOG_VERBOSE
, "Mapping pixel format %s->%s\n",
568 if (fmts
&& !fmt_in_list(fmts
, fmt
))
569 fmt
= choose_pixel_fmt(ost
->enc
->enc_ctx
, fmt
);
574 static int new_stream_video(Muxer
*mux
, const OptionsContext
*o
,
575 OutputStream
*ost
, int *keep_pix_fmt
,
576 enum VideoSyncMethod
*vsync_method
)
578 MuxStream
*ms
= ms_from_ost(ost
);
579 AVFormatContext
*oc
= mux
->fc
;
581 const char *frame_rate
= NULL
, *max_frame_rate
= NULL
, *frame_aspect_ratio
= NULL
;
586 opt_match_per_stream_str(ost
, &o
->frame_rates
, oc
, st
, &frame_rate
);
587 if (frame_rate
&& av_parse_video_rate(&ms
->frame_rate
, frame_rate
) < 0) {
588 av_log(ost
, AV_LOG_FATAL
, "Invalid framerate value: %s\n", frame_rate
);
589 return AVERROR(EINVAL
);
592 opt_match_per_stream_str(ost
, &o
->max_frame_rates
, oc
, st
, &max_frame_rate
);
593 if (max_frame_rate
&& av_parse_video_rate(&ms
->max_frame_rate
, max_frame_rate
) < 0) {
594 av_log(ost
, AV_LOG_FATAL
, "Invalid maximum framerate value: %s\n", max_frame_rate
);
595 return AVERROR(EINVAL
);
598 if (frame_rate
&& max_frame_rate
) {
599 av_log(ost
, AV_LOG_ERROR
, "Only one of -fpsmax and -r can be set for a stream.\n");
600 return AVERROR(EINVAL
);
603 opt_match_per_stream_str(ost
, &o
->frame_aspect_ratios
, oc
, st
, &frame_aspect_ratio
);
604 if (frame_aspect_ratio
) {
606 if (av_parse_ratio(&q
, frame_aspect_ratio
, 255, 0, NULL
) < 0 ||
607 q
.num
<= 0 || q
.den
<= 0) {
608 av_log(ost
, AV_LOG_FATAL
, "Invalid aspect ratio: %s\n", frame_aspect_ratio
);
609 return AVERROR(EINVAL
);
611 ost
->frame_aspect_ratio
= q
;
615 AVCodecContext
*video_enc
= ost
->enc
->enc_ctx
;
616 const char *p
= NULL
, *fps_mode
= NULL
;
617 const char *frame_size
= NULL
;
618 const char *frame_pix_fmt
= NULL
;
619 const char *intra_matrix
= NULL
, *inter_matrix
= NULL
;
620 const char *chroma_intra_matrix
= NULL
;
624 opt_match_per_stream_str(ost
, &o
->frame_sizes
, oc
, st
, &frame_size
);
626 ret
= av_parse_video_size(&video_enc
->width
, &video_enc
->height
, frame_size
);
628 av_log(ost
, AV_LOG_FATAL
, "Invalid frame size: %s.\n", frame_size
);
629 return AVERROR(EINVAL
);
633 opt_match_per_stream_str(ost
, &o
->frame_pix_fmts
, oc
, st
, &frame_pix_fmt
);
634 if (frame_pix_fmt
&& *frame_pix_fmt
== '+') {
636 if (!*++frame_pix_fmt
)
637 frame_pix_fmt
= NULL
;
640 video_enc
->pix_fmt
= pix_fmt_parse(ost
, frame_pix_fmt
);
641 if (video_enc
->pix_fmt
== AV_PIX_FMT_NONE
)
642 return AVERROR(EINVAL
);
645 opt_match_per_stream_str(ost
, &o
->intra_matrices
, oc
, st
, &intra_matrix
);
647 if (!(video_enc
->intra_matrix
= av_mallocz(sizeof(*video_enc
->intra_matrix
) * 64)))
648 return AVERROR(ENOMEM
);
650 ret
= parse_matrix_coeffs(ost
, video_enc
->intra_matrix
, intra_matrix
);
654 opt_match_per_stream_str(ost
, &o
->chroma_intra_matrices
, oc
, st
, &chroma_intra_matrix
);
655 if (chroma_intra_matrix
) {
656 if (!(video_enc
->chroma_intra_matrix
= av_mallocz(sizeof(*video_enc
->chroma_intra_matrix
) * 64)))
657 return AVERROR(ENOMEM
);
658 ret
= parse_matrix_coeffs(ost
, video_enc
->chroma_intra_matrix
, chroma_intra_matrix
);
662 opt_match_per_stream_str(ost
, &o
->inter_matrices
, oc
, st
, &inter_matrix
);
664 if (!(video_enc
->inter_matrix
= av_mallocz(sizeof(*video_enc
->inter_matrix
) * 64)))
665 return AVERROR(ENOMEM
);
666 ret
= parse_matrix_coeffs(ost
, video_enc
->inter_matrix
, inter_matrix
);
671 opt_match_per_stream_str(ost
, &o
->rc_overrides
, oc
, st
, &p
);
672 for (i
= 0; p
; i
++) {
674 int e
= sscanf(p
, "%d,%d,%d", &start
, &end
, &q
);
676 av_log(ost
, AV_LOG_FATAL
, "error parsing rc_override\n");
677 return AVERROR(EINVAL
);
679 video_enc
->rc_override
=
680 av_realloc_array(video_enc
->rc_override
,
681 i
+ 1, sizeof(RcOverride
));
682 if (!video_enc
->rc_override
) {
683 av_log(ost
, AV_LOG_FATAL
, "Could not (re)allocate memory for rc_override.\n");
684 return AVERROR(ENOMEM
);
686 video_enc
->rc_override
[i
].start_frame
= start
;
687 video_enc
->rc_override
[i
].end_frame
= end
;
689 video_enc
->rc_override
[i
].qscale
= q
;
690 video_enc
->rc_override
[i
].quality_factor
= 1.0;
693 video_enc
->rc_override
[i
].qscale
= 0;
694 video_enc
->rc_override
[i
].quality_factor
= -q
/100.0;
699 video_enc
->rc_override_count
= i
;
702 opt_match_per_stream_int(ost
, &o
->pass
, oc
, st
, &do_pass
);
705 video_enc
->flags
|= AV_CODEC_FLAG_PASS1
;
707 video_enc
->flags
|= AV_CODEC_FLAG_PASS2
;
710 opt_match_per_stream_str(ost
, &o
->passlogfiles
, oc
, st
, &ost
->logfile_prefix
);
711 if (ost
->logfile_prefix
&&
712 !(ost
->logfile_prefix
= av_strdup(ost
->logfile_prefix
)))
713 return AVERROR(ENOMEM
);
717 char logfilename
[1024];
720 /* compute this stream's global index */
721 for (int idx
= 0; idx
<= ost
->file
->index
; idx
++)
722 ost_idx
+= output_files
[idx
]->nb_streams
;
724 snprintf(logfilename
, sizeof(logfilename
), "%s-%d.log",
725 ost
->logfile_prefix
? ost
->logfile_prefix
:
726 DEFAULT_PASS_LOGFILENAME_PREFIX
,
728 if (!strcmp(video_enc
->codec
->name
, "libx264") || !strcmp(video_enc
->codec
->name
, "libvvenc")) {
729 if (av_opt_is_set_to_default_by_name(video_enc
, "stats",
730 AV_OPT_SEARCH_CHILDREN
) > 0)
731 av_opt_set(video_enc
, "stats", logfilename
,
732 AV_OPT_SEARCH_CHILDREN
);
734 if (video_enc
->flags
& AV_CODEC_FLAG_PASS2
) {
735 char *logbuffer
= read_file_to_string(logfilename
);
738 av_log(ost
, AV_LOG_FATAL
, "Error reading log file '%s' for pass-2 encoding\n",
742 video_enc
->stats_in
= logbuffer
;
744 if (video_enc
->flags
& AV_CODEC_FLAG_PASS1
) {
745 f
= fopen_utf8(logfilename
, "wb");
747 av_log(ost
, AV_LOG_FATAL
,
748 "Cannot write log file '%s' for pass-1 encoding: %s\n",
749 logfilename
, strerror(errno
));
750 return AVERROR(errno
);
757 opt_match_per_stream_int(ost
, &o
->force_fps
, oc
, st
, &ms
->force_fps
);
760 ost
->top_field_first
= -1;
761 opt_match_per_stream_int(ost
, &o
->top_field_first
, oc
, st
, &ost
->top_field_first
);
762 if (ost
->top_field_first
>= 0)
763 av_log(ost
, AV_LOG_WARNING
, "-top is deprecated, use the setfield filter instead\n");
767 *vsync_method
= video_sync_method
;
769 *vsync_method
= VSYNC_AUTO
;
771 opt_match_per_stream_str(ost
, &o
->fps_mode
, oc
, st
, &fps_mode
);
773 ret
= parse_and_set_vsync(fps_mode
, vsync_method
, ost
->file
->index
, ost
->index
, 0);
778 if ((ms
->frame_rate
.num
|| ms
->max_frame_rate
.num
) &&
779 !(*vsync_method
== VSYNC_AUTO
||
780 *vsync_method
== VSYNC_CFR
|| *vsync_method
== VSYNC_VSCFR
)) {
781 av_log(ost
, AV_LOG_FATAL
, "One of -r/-fpsmax was specified "
782 "together a non-CFR -vsync/-fps_mode. This is contradictory.\n");
783 return AVERROR(EINVAL
);
786 if (*vsync_method
== VSYNC_AUTO
) {
787 if (ms
->frame_rate
.num
|| ms
->max_frame_rate
.num
) {
788 *vsync_method
= VSYNC_CFR
;
789 } else if (!strcmp(oc
->oformat
->name
, "avi")) {
790 *vsync_method
= VSYNC_VFR
;
792 *vsync_method
= (oc
->oformat
->flags
& AVFMT_VARIABLE_FPS
) ?
793 ((oc
->oformat
->flags
& AVFMT_NOTIMESTAMPS
) ?
794 VSYNC_PASSTHROUGH
: VSYNC_VFR
) : VSYNC_CFR
;
797 if (ost
->ist
&& *vsync_method
== VSYNC_CFR
) {
798 const InputFile
*ifile
= ost
->ist
->file
;
800 if (ifile
->nb_streams
== 1 && ifile
->input_ts_offset
== 0)
801 *vsync_method
= VSYNC_VSCFR
;
804 if (*vsync_method
== VSYNC_CFR
&& copy_ts
) {
805 *vsync_method
= VSYNC_VSCFR
;
808 #if FFMPEG_OPT_VSYNC_DROP
809 if (*vsync_method
== VSYNC_DROP
)
817 static int new_stream_audio(Muxer
*mux
, const OptionsContext
*o
,
820 MuxStream
*ms
= ms_from_ost(ost
);
821 AVFormatContext
*oc
= mux
->fc
;
822 AVStream
*st
= ost
->st
;
825 AVCodecContext
*audio_enc
= ost
->enc
->enc_ctx
;
827 const char *layout
= NULL
;
828 const char *sample_fmt
= NULL
;
830 opt_match_per_stream_int(ost
, &o
->audio_channels
, oc
, st
, &channels
);
832 audio_enc
->ch_layout
.order
= AV_CHANNEL_ORDER_UNSPEC
;
833 audio_enc
->ch_layout
.nb_channels
= channels
;
836 opt_match_per_stream_str(ost
, &o
->audio_ch_layouts
, oc
, st
, &layout
);
837 if (layout
&& av_channel_layout_from_string(&audio_enc
->ch_layout
, layout
) < 0) {
838 av_log(ost
, AV_LOG_FATAL
, "Unknown channel layout: %s\n", layout
);
839 return AVERROR(EINVAL
);
842 opt_match_per_stream_str(ost
, &o
->sample_fmts
, oc
, st
, &sample_fmt
);
844 (audio_enc
->sample_fmt
= av_get_sample_fmt(sample_fmt
)) == AV_SAMPLE_FMT_NONE
) {
845 av_log(ost
, AV_LOG_FATAL
, "Invalid sample format '%s'\n", sample_fmt
);
846 return AVERROR(EINVAL
);
849 opt_match_per_stream_int(ost
, &o
->audio_sample_rate
, oc
, st
, &audio_enc
->sample_rate
);
850 opt_match_per_stream_str(ost
, &o
->apad
, oc
, st
, &ms
->apad
);
856 static int new_stream_subtitle(Muxer
*mux
, const OptionsContext
*o
,
864 AVCodecContext
*subtitle_enc
= ost
->enc
->enc_ctx
;
866 AVCodecDescriptor
const *input_descriptor
=
867 avcodec_descriptor_get(ost
->ist
->par
->codec_id
);
868 AVCodecDescriptor
const *output_descriptor
=
869 avcodec_descriptor_get(subtitle_enc
->codec_id
);
870 int input_props
= 0, output_props
= 0;
872 const char *frame_size
= NULL
;
874 opt_match_per_stream_str(ost
, &o
->frame_sizes
, mux
->fc
, st
, &frame_size
);
876 int ret
= av_parse_video_size(&subtitle_enc
->width
, &subtitle_enc
->height
, frame_size
);
878 av_log(ost
, AV_LOG_FATAL
, "Invalid frame size: %s.\n", frame_size
);
882 if (input_descriptor
)
883 input_props
= input_descriptor
->props
& (AV_CODEC_PROP_TEXT_SUB
| AV_CODEC_PROP_BITMAP_SUB
);
884 if (output_descriptor
)
885 output_props
= output_descriptor
->props
& (AV_CODEC_PROP_TEXT_SUB
| AV_CODEC_PROP_BITMAP_SUB
);
886 if (input_props
&& output_props
&& input_props
!= output_props
) {
887 av_log(ost
, AV_LOG_ERROR
,
888 "Subtitle encoding currently only possible from text to text "
889 "or bitmap to bitmap\n");
890 return AVERROR(EINVAL
);
898 ost_bind_filter(const Muxer
*mux
, MuxStream
*ms
, OutputFilter
*ofilter
,
899 const OptionsContext
*o
,
900 AVRational enc_tb
, enum VideoSyncMethod vsync_method
,
901 int keep_pix_fmt
, int autoscale
, int threads_manual
,
902 const ViewSpecifier
*vs
,
905 OutputStream
*ost
= &ms
->ost
;
906 AVCodecContext
*enc_ctx
= ost
->enc
->enc_ctx
;
908 char *filters
= NULL
;
911 OutputFilterOptions opts
= {
912 .enc
= enc_ctx
->codec
,
914 .format
= (ost
->type
== AVMEDIA_TYPE_VIDEO
) ?
915 enc_ctx
->pix_fmt
: enc_ctx
->sample_fmt
,
916 .width
= enc_ctx
->width
,
917 .height
= enc_ctx
->height
,
918 .color_space
= enc_ctx
->colorspace
,
919 .color_range
= enc_ctx
->color_range
,
920 .alpha_mode
= enc_ctx
->alpha_mode
,
921 .vsync_method
= vsync_method
,
922 .frame_rate
= ms
->frame_rate
,
923 .max_frame_rate
= ms
->max_frame_rate
,
924 .sample_rate
= enc_ctx
->sample_rate
,
925 .ch_layout
= enc_ctx
->ch_layout
,
926 .sws_opts
= o
->g
->sws_dict
,
927 .swr_opts
= o
->g
->swr_opts
,
929 .trim_start_us
= mux
->of
.start_time
,
930 .trim_duration_us
= mux
->of
.recording_time
,
931 .ts_offset
= mux
->of
.start_time
== AV_NOPTS_VALUE
?
932 0 : mux
->of
.start_time
,
936 .flags
= OFILTER_FLAG_DISABLE_CONVERT
* !!keep_pix_fmt
|
937 OFILTER_FLAG_AUTOSCALE
* !!autoscale
|
938 OFILTER_FLAG_AUDIO_24BIT
* !!(av_get_exact_bits_per_sample(enc_ctx
->codec_id
) == 24),
941 snprintf(name
, sizeof(name
), "#%d:%d", mux
->of
.index
, ost
->index
);
943 if (ost
->type
== AVMEDIA_TYPE_VIDEO
) {
945 ret
= avcodec_get_supported_config(enc_ctx
, NULL
,
946 AV_CODEC_CONFIG_PIX_FORMAT
, 0,
947 (const void **) &opts
.formats
, NULL
);
951 if (!ms
->force_fps
) {
952 ret
= avcodec_get_supported_config(enc_ctx
, NULL
,
953 AV_CODEC_CONFIG_FRAME_RATE
, 0,
954 (const void **) &opts
.frame_rates
, NULL
);
958 ret
= avcodec_get_supported_config(enc_ctx
, NULL
,
959 AV_CODEC_CONFIG_COLOR_SPACE
, 0,
960 (const void **) &opts
.color_spaces
, NULL
);
963 ret
= avcodec_get_supported_config(enc_ctx
, NULL
,
964 AV_CODEC_CONFIG_COLOR_RANGE
, 0,
965 (const void **) &opts
.color_ranges
, NULL
);
968 ret
= avcodec_get_supported_config(enc_ctx
, NULL
,
969 AV_CODEC_CONFIG_ALPHA_MODE
, 0,
970 (const void **) &opts
.alpha_modes
, NULL
);
974 ret
= avcodec_get_supported_config(enc_ctx
, NULL
,
975 AV_CODEC_CONFIG_SAMPLE_FORMAT
, 0,
976 (const void **) &opts
.formats
, NULL
);
979 ret
= avcodec_get_supported_config(enc_ctx
, NULL
,
980 AV_CODEC_CONFIG_SAMPLE_RATE
, 0,
981 (const void **) &opts
.sample_rates
, NULL
);
984 ret
= avcodec_get_supported_config(enc_ctx
, NULL
,
985 AV_CODEC_CONFIG_CHANNEL_LAYOUT
, 0,
986 (const void **) &opts
.ch_layouts
, NULL
);
991 if (threads_manual
) {
992 ret
= av_opt_get_int(enc_ctx
, "threads", 0, &opts
.nb_threads
);
997 ret
= ost_get_filters(o
, mux
->fc
, ost
, &filters
);
1002 av_assert0(!filters
);
1003 ost
->filter
= ofilter
;
1004 ret
= ofilter_bind_enc(ofilter
, ms
->sch_idx_enc
, &opts
);
1006 ret
= fg_create_simple(&ost
->fg_simple
, ost
->ist
, &filters
,
1007 mux
->sch
, ms
->sch_idx_enc
, &opts
);
1009 ost
->filter
= ost
->fg_simple
->outputs
[0];
1015 *src
= SCH_ENC(ms
->sch_idx_enc
);
1020 static int streamcopy_init(const OptionsContext
*o
, const Muxer
*mux
,
1021 OutputStream
*ost
, AVDictionary
**encoder_opts
)
1023 MuxStream
*ms
= ms_from_ost(ost
);
1025 const InputStream
*ist
= ost
->ist
;
1026 const InputFile
*ifile
= ist
->file
;
1028 AVCodecParameters
*par
= ms
->par_in
;
1029 uint32_t codec_tag
= par
->codec_tag
;
1031 AVCodecContext
*codec_ctx
= NULL
;
1033 AVRational fr
= ms
->frame_rate
;
1037 const char *filters
= NULL
;
1038 #if FFMPEG_OPT_FILTER_SCRIPT
1039 const char *filters_script
= NULL
;
1041 opt_match_per_stream_str(ost
, &o
->filter_scripts
, mux
->fc
, ost
->st
, &filters_script
);
1043 opt_match_per_stream_str(ost
, &o
->filters
, mux
->fc
, ost
->st
, &filters
);
1046 #if FFMPEG_OPT_FILTER_SCRIPT
1050 av_log(ost
, AV_LOG_ERROR
,
1051 "%s '%s' was specified, but codec copy was selected. "
1052 "Filtering and streamcopy cannot be used together.\n",
1053 #if FFMPEG_OPT_FILTER_SCRIPT
1054 filters
? "Filtergraph" : "Filtergraph script",
1055 filters
? filters
: filters_script
1057 "Filtergraph", filters
1060 return AVERROR(EINVAL
);
1063 codec_ctx
= avcodec_alloc_context3(NULL
);
1065 return AVERROR(ENOMEM
);
1067 ret
= avcodec_parameters_to_context(codec_ctx
, ist
->par
);
1069 ret
= av_opt_set_dict(codec_ctx
, encoder_opts
);
1071 av_log(ost
, AV_LOG_FATAL
,
1072 "Error setting up codec context options.\n");
1076 ret
= avcodec_parameters_from_context(par
, codec_ctx
);
1078 av_log(ost
, AV_LOG_FATAL
,
1079 "Error getting reference codec parameters.\n");
1084 const struct AVCodecTag
* const *ct
= mux
->fc
->oformat
->codec_tag
;
1085 unsigned int codec_tag_tmp
;
1086 if (!ct
|| av_codec_get_id (ct
, par
->codec_tag
) == par
->codec_id
||
1087 !av_codec_get_tag2(ct
, par
->codec_id
, &codec_tag_tmp
))
1088 codec_tag
= par
->codec_tag
;
1091 par
->codec_tag
= codec_tag
;
1094 fr
= ist
->framerate
;
1097 ost
->st
->avg_frame_rate
= fr
;
1099 ost
->st
->avg_frame_rate
= ist
->st
->avg_frame_rate
;
1101 // copy timebase while removing common factors
1102 if (ost
->st
->time_base
.num
<= 0 || ost
->st
->time_base
.den
<= 0) {
1104 ost
->st
->time_base
= av_inv_q(fr
);
1106 ost
->st
->time_base
= av_add_q(ist
->st
->time_base
, (AVRational
){0, 1});
1109 if (!ms
->copy_prior_start
) {
1110 ms
->ts_copy_start
= (mux
->of
.start_time
== AV_NOPTS_VALUE
) ?
1111 0 : mux
->of
.start_time
;
1112 if (copy_ts
&& ifile
->start_time
!= AV_NOPTS_VALUE
) {
1113 ms
->ts_copy_start
= FFMAX(ms
->ts_copy_start
,
1114 ifile
->start_time
+ ifile
->ts_offset
);
1118 for (int i
= 0; i
< ist
->st
->codecpar
->nb_coded_side_data
; i
++) {
1119 const AVPacketSideData
*sd_src
= &ist
->st
->codecpar
->coded_side_data
[i
];
1120 AVPacketSideData
*sd_dst
;
1122 sd_dst
= av_packet_side_data_new(&ost
->st
->codecpar
->coded_side_data
,
1123 &ost
->st
->codecpar
->nb_coded_side_data
,
1124 sd_src
->type
, sd_src
->size
, 0);
1126 ret
= AVERROR(ENOMEM
);
1129 memcpy(sd_dst
->data
, sd_src
->data
, sd_src
->size
);
1132 switch (par
->codec_type
) {
1133 case AVMEDIA_TYPE_AUDIO
:
1134 if ((par
->block_align
== 1 || par
->block_align
== 1152 || par
->block_align
== 576) &&
1135 par
->codec_id
== AV_CODEC_ID_MP3
)
1136 par
->block_align
= 0;
1137 if (par
->codec_id
== AV_CODEC_ID_AC3
)
1138 par
->block_align
= 0;
1140 case AVMEDIA_TYPE_VIDEO
: {
1142 if (ost
->frame_aspect_ratio
.num
) { // overridden by the -aspect cli option
1144 av_mul_q(ost
->frame_aspect_ratio
,
1145 (AVRational
){ par
->height
, par
->width
});
1146 av_log(ost
, AV_LOG_WARNING
, "Overriding aspect ratio "
1147 "with stream copy may produce invalid files\n");
1149 else if (ist
->st
->sample_aspect_ratio
.num
)
1150 sar
= ist
->st
->sample_aspect_ratio
;
1152 sar
= par
->sample_aspect_ratio
;
1153 ost
->st
->sample_aspect_ratio
= par
->sample_aspect_ratio
= sar
;
1154 ost
->st
->r_frame_rate
= ist
->st
->r_frame_rate
;
1160 avcodec_free_context(&codec_ctx
);
1164 static int set_encoder_id(OutputStream
*ost
, const AVCodec
*codec
)
1166 const char *cname
= codec
->name
;
1167 uint8_t *encoder_string
;
1168 int encoder_string_len
;
1170 encoder_string_len
= sizeof(LIBAVCODEC_IDENT
) + strlen(cname
) + 2;
1171 encoder_string
= av_mallocz(encoder_string_len
);
1172 if (!encoder_string
)
1173 return AVERROR(ENOMEM
);
1175 if (!ost
->file
->bitexact
&& !ost
->bitexact
)
1176 av_strlcpy(encoder_string
, LIBAVCODEC_IDENT
" ", encoder_string_len
);
1178 av_strlcpy(encoder_string
, "Lavc ", encoder_string_len
);
1179 av_strlcat(encoder_string
, cname
, encoder_string_len
);
1180 av_dict_set(&ost
->st
->metadata
, "encoder", encoder_string
,
1181 AV_DICT_DONT_STRDUP_VAL
| AV_DICT_DONT_OVERWRITE
);
1186 static int ost_add(Muxer
*mux
, const OptionsContext
*o
, enum AVMediaType type
,
1187 InputStream
*ist
, OutputFilter
*ofilter
, const ViewSpecifier
*vs
,
1188 OutputStream
**post
)
1190 AVFormatContext
*oc
= mux
->fc
;
1195 SchedulerNode src
= { .type
= SCH_NODE_TYPE_NONE
};
1196 AVDictionary
*encoder_opts
= NULL
;
1197 int ret
= 0, keep_pix_fmt
= 0, autoscale
= 1;
1198 int threads_manual
= 0;
1199 AVRational enc_tb
= { 0, 0 };
1200 enum VideoSyncMethod vsync_method
= VSYNC_AUTO
;
1201 const char *bsfs
= NULL
, *time_base
= NULL
, *codec_tag
= NULL
;
1205 st
= avformat_new_stream(oc
, NULL
);
1207 return AVERROR(ENOMEM
);
1209 ms
= mux_stream_alloc(mux
, type
);
1211 return AVERROR(ENOMEM
);
1213 // only streams with sources (i.e. not attachments)
1214 // are handled by the scheduler
1215 if (ist
|| ofilter
) {
1216 ret
= GROW_ARRAY(mux
->sch_stream_idx
, mux
->nb_sch_stream_idx
);
1220 ret
= sch_add_mux_stream(mux
->sch
, mux
->sch_idx
);
1224 av_assert0(ret
== mux
->nb_sch_stream_idx
- 1);
1225 mux
->sch_stream_idx
[ret
] = ms
->ost
.index
;
1232 AVDictionaryEntry
*e
;
1234 snprintf(idx
, sizeof(idx
), "%d", ost
->index
);
1236 e
= av_dict_get(o
->streamid
, idx
, NULL
, 0);
1238 st
->id
= strtol(e
->value
, &p
, 0);
1239 if (!e
->value
[0] || *p
) {
1240 av_log(ost
, AV_LOG_FATAL
, "Invalid stream id: %s\n", e
->value
);
1241 return AVERROR(EINVAL
);
1246 ms
->par_in
= avcodec_parameters_alloc();
1248 return AVERROR(ENOMEM
);
1250 ms
->last_mux_dts
= AV_NOPTS_VALUE
;
1254 ost
->kf
.ref_pts
= AV_NOPTS_VALUE
;
1255 ms
->par_in
->codec_type
= type
;
1256 st
->codecpar
->codec_type
= type
;
1258 ret
= choose_encoder(o
, oc
, ms
, &enc
);
1260 av_log(ost
, AV_LOG_FATAL
, "Error selecting an encoder\n");
1265 ret
= sch_add_enc(mux
->sch
, encoder_thread
, ost
,
1266 ost
->type
== AVMEDIA_TYPE_SUBTITLE
? NULL
: enc_open
);
1269 ms
->sch_idx_enc
= ret
;
1271 ret
= enc_alloc(&ost
->enc
, enc
, mux
->sch
, ms
->sch_idx_enc
, ost
);
1275 av_strlcat(ms
->log_name
, "/", sizeof(ms
->log_name
));
1276 av_strlcat(ms
->log_name
, enc
->name
, sizeof(ms
->log_name
));
1279 av_log(ost
, AV_LOG_ERROR
,
1280 "Streamcopy requested for output stream fed "
1281 "from a complex filtergraph. Filtering and streamcopy "
1282 "cannot be used together.\n");
1283 return AVERROR(EINVAL
);
1286 av_strlcat(ms
->log_name
, "/copy", sizeof(ms
->log_name
));
1289 av_log(ost
, AV_LOG_VERBOSE
, "Created %s stream from ",
1290 av_get_media_type_string(type
));
1292 av_log(ost
, AV_LOG_VERBOSE
, "input stream %d:%d",
1293 ist
->file
->index
, ist
->index
);
1295 av_log(ost
, AV_LOG_VERBOSE
, "complex filtergraph %d:[%s]\n",
1296 ofilter
->graph
->index
, ofilter
->name
);
1297 else if (type
== AVMEDIA_TYPE_ATTACHMENT
)
1298 av_log(ost
, AV_LOG_VERBOSE
, "attached file");
1300 av_log(ost
, AV_LOG_VERBOSE
, "\n");
1302 ms
->pkt
= av_packet_alloc();
1304 return AVERROR(ENOMEM
);
1307 AVIOContext
*s
= NULL
;
1308 char *buf
= NULL
, *arg
= NULL
;
1309 const char *enc_stats_pre
= NULL
, *enc_stats_post
= NULL
, *mux_stats
= NULL
;
1310 const char *enc_time_base
= NULL
, *preset
= NULL
;
1312 ret
= filter_codec_opts(o
->g
->codec_opts
, enc
->id
,
1313 oc
, st
, enc
, &encoder_opts
,
1314 &mux
->enc_opts_used
);
1318 opt_match_per_stream_str(ost
, &o
->presets
, oc
, st
, &preset
);
1319 opt_match_per_stream_int(ost
, &o
->autoscale
, oc
, st
, &autoscale
);
1320 if (preset
&& (!(ret
= get_preset_file_2(preset
, enc
->name
, &s
)))) {
1322 av_bprint_init(&bprint
, 0, AV_BPRINT_SIZE_UNLIMITED
);
1324 av_bprint_clear(&bprint
);
1325 buf
= get_line(s
, &bprint
);
1327 ret
= AVERROR(ENOMEM
);
1331 if (!buf
[0] || buf
[0] == '#')
1333 if (!(arg
= strchr(buf
, '='))) {
1334 av_log(ost
, AV_LOG_FATAL
, "Invalid line found in the preset file.\n");
1335 ret
= AVERROR(EINVAL
);
1339 av_dict_set(&encoder_opts
, buf
, arg
, AV_DICT_DONT_OVERWRITE
);
1340 } while (!s
->eof_reached
);
1341 av_bprint_finalize(&bprint
, NULL
);
1345 av_log(ost
, AV_LOG_FATAL
,
1346 "Preset %s specified, but could not be opened.\n", preset
);
1350 opt_match_per_stream_str(ost
, &o
->enc_stats_pre
, oc
, st
, &enc_stats_pre
);
1351 if (enc_stats_pre
&&
1352 (type
== AVMEDIA_TYPE_VIDEO
|| type
== AVMEDIA_TYPE_AUDIO
)) {
1353 const char *format
= "{fidx} {sidx} {n} {t}";
1355 opt_match_per_stream_str(ost
, &o
->enc_stats_pre_fmt
, oc
, st
, &format
);
1357 ret
= enc_stats_init(ost
, &ost
->enc_stats_pre
, 1, enc_stats_pre
, format
);
1362 opt_match_per_stream_str(ost
, &o
->enc_stats_post
, oc
, st
, &enc_stats_post
);
1363 if (enc_stats_post
&&
1364 (type
== AVMEDIA_TYPE_VIDEO
|| type
== AVMEDIA_TYPE_AUDIO
)) {
1365 const char *format
= "{fidx} {sidx} {n} {t}";
1367 opt_match_per_stream_str(ost
, &o
->enc_stats_post_fmt
, oc
, st
, &format
);
1369 ret
= enc_stats_init(ost
, &ost
->enc_stats_post
, 0, enc_stats_post
, format
);
1374 opt_match_per_stream_str(ost
, &o
->mux_stats
, oc
, st
, &mux_stats
);
1376 (type
== AVMEDIA_TYPE_VIDEO
|| type
== AVMEDIA_TYPE_AUDIO
)) {
1377 const char *format
= "{fidx} {sidx} {n} {t}";
1379 opt_match_per_stream_str(ost
, &o
->mux_stats_fmt
, oc
, st
, &format
);
1381 ret
= enc_stats_init(ost
, &ms
->stats
, 0, mux_stats
, format
);
1386 opt_match_per_stream_str(ost
, &o
->enc_time_bases
, oc
, st
, &enc_time_base
);
1387 if (enc_time_base
&& type
== AVMEDIA_TYPE_SUBTITLE
)
1388 av_log(ost
, AV_LOG_WARNING
,
1389 "-enc_time_base not supported for subtitles, ignoring\n");
1390 else if (enc_time_base
) {
1393 if (!strcmp(enc_time_base
, "demux")) {
1394 q
= (AVRational
){ ENC_TIME_BASE_DEMUX
, 0 };
1395 } else if (!strcmp(enc_time_base
, "filter")) {
1396 q
= (AVRational
){ ENC_TIME_BASE_FILTER
, 0 };
1398 ret
= av_parse_ratio(&q
, enc_time_base
, INT_MAX
, 0, NULL
);
1399 if (ret
< 0 || q
.den
<= 0
1400 #if !FFMPEG_OPT_ENC_TIME_BASE_NUM
1404 av_log(ost
, AV_LOG_FATAL
, "Invalid time base: %s\n", enc_time_base
);
1405 ret
= ret
< 0 ? ret
: AVERROR(EINVAL
);
1408 #if FFMPEG_OPT_ENC_TIME_BASE_NUM
1410 av_log(ost
, AV_LOG_WARNING
, "-enc_time_base -1 is deprecated,"
1411 " use -enc_time_base demux\n");
1418 threads_manual
= !!av_dict_get(encoder_opts
, "threads", NULL
, 0);
1420 ret
= av_opt_set_dict2(ost
->enc
->enc_ctx
, &encoder_opts
, AV_OPT_SEARCH_CHILDREN
);
1422 av_log(ost
, AV_LOG_ERROR
, "Error applying encoder options: %s\n",
1427 ret
= check_avoptions(encoder_opts
);
1431 // default to automatic thread count
1432 if (!threads_manual
)
1433 ost
->enc
->enc_ctx
->thread_count
= 0;
1435 ret
= filter_codec_opts(o
->g
->codec_opts
, AV_CODEC_ID_NONE
, oc
, st
,
1436 NULL
, &encoder_opts
,
1437 &mux
->enc_opts_used
);
1445 } else if (ost
->enc
) {
1446 ost
->bitexact
= !!(ost
->enc
->enc_ctx
->flags
& AV_CODEC_FLAG_BITEXACT
);
1450 ret
= set_encoder_id(ost
, enc
);
1455 opt_match_per_stream_str(ost
, &o
->time_bases
, oc
, st
, &time_base
);
1458 if (av_parse_ratio(&q
, time_base
, INT_MAX
, 0, NULL
) < 0 ||
1459 q
.num
<= 0 || q
.den
<= 0) {
1460 av_log(ost
, AV_LOG_FATAL
, "Invalid time base: %s\n", time_base
);
1461 ret
= AVERROR(EINVAL
);
1467 ms
->max_frames
= INT64_MAX
;
1468 opt_match_per_stream_int64(ost
, &o
->max_frames
, oc
, st
, &ms
->max_frames
);
1469 for (int i
= 0; i
< o
->max_frames
.nb_opt
; i
++) {
1470 char *p
= o
->max_frames
.opt
[i
].specifier
;
1471 if (!*p
&& type
!= AVMEDIA_TYPE_VIDEO
) {
1472 av_log(ost
, AV_LOG_WARNING
, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n");
1477 ms
->copy_prior_start
= -1;
1478 opt_match_per_stream_int(ost
, &o
->copy_prior_start
, oc
, st
, &ms
->copy_prior_start
);
1479 opt_match_per_stream_str(ost
, &o
->bitstream_filters
, oc
, st
, &bsfs
);
1480 if (bsfs
&& *bsfs
) {
1481 ret
= av_bsf_list_parse_str(bsfs
, &ms
->bsf_ctx
);
1483 av_log(ost
, AV_LOG_ERROR
, "Error parsing bitstream filter sequence '%s': %s\n", bsfs
, av_err2str(ret
));
1488 opt_match_per_stream_str(ost
, &o
->codec_tags
, oc
, st
, &codec_tag
);
1490 uint32_t tag
= strtol(codec_tag
, &next
, 0);
1492 uint8_t buf
[4] = { 0 };
1493 memcpy(buf
, codec_tag
, FFMIN(sizeof(buf
), strlen(codec_tag
)));
1496 ost
->st
->codecpar
->codec_tag
= tag
;
1497 ms
->par_in
->codec_tag
= tag
;
1499 ost
->enc
->enc_ctx
->codec_tag
= tag
;
1502 opt_match_per_stream_dbl(ost
, &o
->qscale
, oc
, st
, &qscale
);
1503 if (ost
->enc
&& qscale
>= 0) {
1504 ost
->enc
->enc_ctx
->flags
|= AV_CODEC_FLAG_QSCALE
;
1505 ost
->enc
->enc_ctx
->global_quality
= FF_QP2LAMBDA
* qscale
;
1508 if (ms
->sch_idx
>= 0) {
1509 int max_muxing_queue_size
= 128;
1510 int muxing_queue_data_threshold
= 50 * 1024 * 1024;
1512 opt_match_per_stream_int(ost
, &o
->max_muxing_queue_size
, oc
, st
,
1513 &max_muxing_queue_size
);
1514 opt_match_per_stream_int(ost
, &o
->muxing_queue_data_threshold
,
1515 oc
, st
, &muxing_queue_data_threshold
);
1517 sch_mux_stream_buffering(mux
->sch
, mux
->sch_idx
, ms
->sch_idx
,
1518 max_muxing_queue_size
, muxing_queue_data_threshold
);
1521 opt_match_per_stream_int(ost
, &o
->bits_per_raw_sample
, oc
, st
,
1522 &ost
->bits_per_raw_sample
);
1524 opt_match_per_stream_int(ost
, &o
->fix_sub_duration_heartbeat
,
1525 oc
, st
, &ost
->fix_sub_duration_heartbeat
);
1527 if (oc
->oformat
->flags
& AVFMT_GLOBALHEADER
&& ost
->enc
)
1528 ost
->enc
->enc_ctx
->flags
|= AV_CODEC_FLAG_GLOBAL_HEADER
;
1530 opt_match_per_stream_int(ost
, &o
->copy_initial_nonkeyframes
,
1531 oc
, st
, &ms
->copy_initial_nonkeyframes
);
1533 case AVMEDIA_TYPE_VIDEO
: ret
= new_stream_video (mux
, o
, ost
, &keep_pix_fmt
, &vsync_method
); break;
1534 case AVMEDIA_TYPE_AUDIO
: ret
= new_stream_audio (mux
, o
, ost
); break;
1535 case AVMEDIA_TYPE_SUBTITLE
: ret
= new_stream_subtitle (mux
, o
, ost
); break;
1541 (type
== AVMEDIA_TYPE_VIDEO
|| type
== AVMEDIA_TYPE_AUDIO
)) {
1542 ret
= ost_bind_filter(mux
, ms
, ofilter
, o
, enc_tb
, vsync_method
,
1543 keep_pix_fmt
, autoscale
, threads_manual
, vs
, &src
);
1546 } else if (ost
->ist
) {
1547 ret
= ist_use(ost
->ist
, !!ost
->enc
, NULL
, &src
);
1549 av_log(ost
, AV_LOG_ERROR
,
1550 "Error binding an input stream\n");
1553 ms
->sch_idx_src
= src
.idx
;
1555 // src refers to a decoder for transcoding, demux stream otherwise
1557 ret
= sch_connect(mux
->sch
,
1558 src
, SCH_ENC(ms
->sch_idx_enc
));
1561 src
= SCH_ENC(ms
->sch_idx_enc
);
1565 if (src
.type
!= SCH_NODE_TYPE_NONE
) {
1566 ret
= sch_connect(mux
->sch
,
1567 src
, SCH_MSTREAM(mux
->sch_idx
, ms
->sch_idx
));
1571 // only attachment streams don't have a source
1572 av_assert0(type
== AVMEDIA_TYPE_ATTACHMENT
&& ms
->sch_idx
< 0);
1575 if (ost
->ist
&& !ost
->enc
) {
1576 ret
= streamcopy_init(o
, mux
, ost
, &encoder_opts
);
1581 // copy estimated duration as a hint to the muxer
1582 if (ost
->ist
&& ost
->ist
->st
->duration
> 0) {
1583 ms
->stream_duration
= ist
->st
->duration
;
1584 ms
->stream_duration_tb
= ist
->st
->time_base
;
1593 av_dict_free(&encoder_opts
);
1598 static int map_auto_video(Muxer
*mux
, const OptionsContext
*o
)
1600 AVFormatContext
*oc
= mux
->fc
;
1601 InputStreamGroup
*best_istg
= NULL
;
1602 InputStream
*best_ist
= NULL
;
1603 int64_t best_score
= 0;
1606 /* video: highest resolution */
1607 if (av_guess_codec(oc
->oformat
, NULL
, oc
->url
, NULL
, AVMEDIA_TYPE_VIDEO
) == AV_CODEC_ID_NONE
)
1610 qcr
= avformat_query_codec(oc
->oformat
, oc
->oformat
->video_codec
, 0);
1611 for (int j
= 0; j
< nb_input_files
; j
++) {
1612 InputFile
*ifile
= input_files
[j
];
1613 InputStreamGroup
*file_best_istg
= NULL
;
1614 InputStream
*file_best_ist
= NULL
;
1615 int64_t file_best_score
= 0;
1616 for (int i
= 0; i
< ifile
->nb_stream_groups
; i
++) {
1617 InputStreamGroup
*istg
= ifile
->stream_groups
[i
];
1623 for (int j
= 0; j
< istg
->stg
->nb_streams
; j
++) {
1624 AVStream
*st
= istg
->stg
->streams
[j
];
1626 if (st
->event_flags
& AVSTREAM_EVENT_FLAG_NEW_PACKETS
) {
1632 switch (istg
->stg
->type
) {
1633 case AV_STREAM_GROUP_PARAMS_TILE_GRID
: {
1634 const AVStreamGroupTileGrid
*tg
= istg
->stg
->params
.tile_grid
;
1635 score
+= tg
->width
* (int64_t)tg
->height
1636 + 5000000*!!(istg
->stg
->disposition
& AV_DISPOSITION_DEFAULT
);
1643 if (score
> file_best_score
) {
1644 file_best_score
= score
;
1645 file_best_istg
= istg
;
1648 for (int i
= 0; i
< ifile
->nb_streams
; i
++) {
1649 InputStream
*ist
= ifile
->streams
[i
];
1652 if (ist
->user_set_discard
== AVDISCARD_ALL
||
1653 ist
->st
->codecpar
->codec_type
!= AVMEDIA_TYPE_VIDEO
)
1656 score
= ist
->st
->codecpar
->width
* (int64_t)ist
->st
->codecpar
->height
1657 + 100000000 * !!(ist
->st
->event_flags
& AVSTREAM_EVENT_FLAG_NEW_PACKETS
)
1658 + 5000000*!!(ist
->st
->disposition
& AV_DISPOSITION_DEFAULT
);
1659 if((qcr
!=MKTAG('A', 'P', 'I', 'C')) && (ist
->st
->disposition
& AV_DISPOSITION_ATTACHED_PIC
))
1662 if (score
> file_best_score
) {
1663 if((qcr
==MKTAG('A', 'P', 'I', 'C')) && !(ist
->st
->disposition
& AV_DISPOSITION_ATTACHED_PIC
))
1665 file_best_score
= score
;
1666 file_best_ist
= ist
;
1667 file_best_istg
= NULL
;
1670 if (file_best_istg
) {
1671 file_best_score
-= 5000000*!!(file_best_istg
->stg
->disposition
& AV_DISPOSITION_DEFAULT
);
1672 if (file_best_score
> best_score
) {
1673 best_score
= file_best_score
;
1674 best_istg
= file_best_istg
;
1678 if (file_best_ist
) {
1679 if((qcr
== MKTAG('A', 'P', 'I', 'C')) ||
1680 !(file_best_ist
->st
->disposition
& AV_DISPOSITION_ATTACHED_PIC
))
1681 file_best_score
-= 5000000*!!(file_best_ist
->st
->disposition
& AV_DISPOSITION_DEFAULT
);
1682 if (file_best_score
> best_score
) {
1683 best_score
= file_best_score
;
1684 best_ist
= file_best_ist
;
1690 FilterGraph
*fg
= best_istg
->fg
;
1691 OutputFilter
*ofilter
= fg
->outputs
[0];
1693 av_assert0(fg
->nb_outputs
== 1);
1694 av_log(mux
, AV_LOG_VERBOSE
, "Creating output stream from stream group derived complex filtergraph %d.\n", fg
->index
);
1696 return ost_add(mux
, o
, AVMEDIA_TYPE_VIDEO
, NULL
, ofilter
, NULL
, NULL
);
1699 return ost_add(mux
, o
, AVMEDIA_TYPE_VIDEO
, best_ist
, NULL
, NULL
, NULL
);
1704 static int map_auto_audio(Muxer
*mux
, const OptionsContext
*o
)
1706 AVFormatContext
*oc
= mux
->fc
;
1707 InputStream
*best_ist
= NULL
;
1710 /* audio: most channels */
1711 if (av_guess_codec(oc
->oformat
, NULL
, oc
->url
, NULL
, AVMEDIA_TYPE_AUDIO
) == AV_CODEC_ID_NONE
)
1714 for (int j
= 0; j
< nb_input_files
; j
++) {
1715 InputFile
*ifile
= input_files
[j
];
1716 InputStream
*file_best_ist
= NULL
;
1717 int file_best_score
= 0;
1718 for (int i
= 0; i
< ifile
->nb_streams
; i
++) {
1719 InputStream
*ist
= ifile
->streams
[i
];
1722 if (ist
->user_set_discard
== AVDISCARD_ALL
||
1723 ist
->st
->codecpar
->codec_type
!= AVMEDIA_TYPE_AUDIO
)
1726 score
= ist
->st
->codecpar
->ch_layout
.nb_channels
1727 + 100000000 * !!(ist
->st
->event_flags
& AVSTREAM_EVENT_FLAG_NEW_PACKETS
)
1728 + 5000000*!!(ist
->st
->disposition
& AV_DISPOSITION_DEFAULT
);
1729 if (score
> file_best_score
) {
1730 file_best_score
= score
;
1731 file_best_ist
= ist
;
1734 if (file_best_ist
) {
1735 file_best_score
-= 5000000*!!(file_best_ist
->st
->disposition
& AV_DISPOSITION_DEFAULT
);
1736 if (file_best_score
> best_score
) {
1737 best_score
= file_best_score
;
1738 best_ist
= file_best_ist
;
1743 return ost_add(mux
, o
, AVMEDIA_TYPE_AUDIO
, best_ist
, NULL
, NULL
, NULL
);
1748 static int map_auto_subtitle(Muxer
*mux
, const OptionsContext
*o
)
1750 AVFormatContext
*oc
= mux
->fc
;
1751 const char *subtitle_codec_name
= NULL
;
1753 /* subtitles: pick first */
1754 subtitle_codec_name
= opt_match_per_type_str(&o
->codec_names
, 's');
1755 if (!avcodec_find_encoder(oc
->oformat
->subtitle_codec
) && !subtitle_codec_name
)
1758 for (InputStream
*ist
= ist_iter(NULL
); ist
; ist
= ist_iter(ist
))
1759 if (ist
->st
->codecpar
->codec_type
== AVMEDIA_TYPE_SUBTITLE
) {
1760 AVCodecDescriptor
const *input_descriptor
=
1761 avcodec_descriptor_get(ist
->st
->codecpar
->codec_id
);
1762 AVCodecDescriptor
const *output_descriptor
= NULL
;
1763 AVCodec
const *output_codec
=
1764 avcodec_find_encoder(oc
->oformat
->subtitle_codec
);
1765 int input_props
= 0, output_props
= 0;
1766 if (ist
->user_set_discard
== AVDISCARD_ALL
)
1769 output_descriptor
= avcodec_descriptor_get(output_codec
->id
);
1770 if (input_descriptor
)
1771 input_props
= input_descriptor
->props
& (AV_CODEC_PROP_TEXT_SUB
| AV_CODEC_PROP_BITMAP_SUB
);
1772 if (output_descriptor
)
1773 output_props
= output_descriptor
->props
& (AV_CODEC_PROP_TEXT_SUB
| AV_CODEC_PROP_BITMAP_SUB
);
1774 if (subtitle_codec_name
||
1775 input_props
& output_props
||
1776 // Map dvb teletext which has neither property to any output subtitle encoder
1777 input_descriptor
&& output_descriptor
&&
1778 (!input_descriptor
->props
||
1779 !output_descriptor
->props
)) {
1780 return ost_add(mux
, o
, AVMEDIA_TYPE_SUBTITLE
, ist
, NULL
, NULL
, NULL
);
1787 static int map_auto_data(Muxer
*mux
, const OptionsContext
*o
)
1789 AVFormatContext
*oc
= mux
->fc
;
1790 /* Data only if codec id match */
1791 enum AVCodecID codec_id
= av_guess_codec(oc
->oformat
, NULL
, oc
->url
, NULL
, AVMEDIA_TYPE_DATA
);
1793 if (codec_id
== AV_CODEC_ID_NONE
)
1796 for (InputStream
*ist
= ist_iter(NULL
); ist
; ist
= ist_iter(ist
)) {
1797 if (ist
->user_set_discard
== AVDISCARD_ALL
)
1799 if (ist
->st
->codecpar
->codec_type
== AVMEDIA_TYPE_DATA
&&
1800 ist
->st
->codecpar
->codec_id
== codec_id
) {
1801 int ret
= ost_add(mux
, o
, AVMEDIA_TYPE_DATA
, ist
, NULL
, NULL
, NULL
);
1810 static int map_manual(Muxer
*mux
, const OptionsContext
*o
, const StreamMap
*map
)
1818 if (map
->linklabel
) {
1820 OutputFilter
*ofilter
= NULL
;
1823 for (j
= 0; j
< nb_filtergraphs
; j
++) {
1824 fg
= filtergraphs
[j
];
1825 for (k
= 0; k
< fg
->nb_outputs
; k
++) {
1826 const char *linklabel
= fg
->outputs
[k
]->linklabel
;
1827 if (linklabel
&& !strcmp(linklabel
, map
->linklabel
)) {
1828 ofilter
= fg
->outputs
[k
];
1835 av_log(mux
, AV_LOG_FATAL
, "Output with label '%s' does not exist "
1836 "in any defined filter graph, or was already used elsewhere.\n", map
->linklabel
);
1837 return AVERROR(EINVAL
);
1840 av_log(mux
, AV_LOG_VERBOSE
, "Creating output stream from an explicitly "
1841 "mapped complex filtergraph %d, output [%s]\n", fg
->index
, map
->linklabel
);
1843 ret
= ost_add(mux
, o
, ofilter
->type
, NULL
, ofilter
, NULL
, NULL
);
1847 const ViewSpecifier
*vs
= map
->vs
.type
== VIEW_SPECIFIER_TYPE_NONE
?
1850 ist
= input_files
[map
->file_index
]->streams
[map
->stream_index
];
1851 if (ist
->user_set_discard
== AVDISCARD_ALL
) {
1852 av_log(mux
, AV_LOG_FATAL
, "Stream #%d:%d is disabled and cannot be mapped.\n",
1853 map
->file_index
, map
->stream_index
);
1854 return AVERROR(EINVAL
);
1856 if(o
->subtitle_disable
&& ist
->st
->codecpar
->codec_type
== AVMEDIA_TYPE_SUBTITLE
)
1858 if(o
-> audio_disable
&& ist
->st
->codecpar
->codec_type
== AVMEDIA_TYPE_AUDIO
)
1860 if(o
-> video_disable
&& ist
->st
->codecpar
->codec_type
== AVMEDIA_TYPE_VIDEO
)
1862 if(o
-> data_disable
&& ist
->st
->codecpar
->codec_type
== AVMEDIA_TYPE_DATA
)
1865 if (ist
->st
->codecpar
->codec_type
== AVMEDIA_TYPE_UNKNOWN
&&
1866 !copy_unknown_streams
) {
1867 av_log(mux
, ignore_unknown_streams
? AV_LOG_WARNING
: AV_LOG_FATAL
,
1868 "Cannot map stream #%d:%d - unsupported type.\n",
1869 map
->file_index
, map
->stream_index
);
1870 if (!ignore_unknown_streams
) {
1871 av_log(mux
, AV_LOG_FATAL
,
1872 "If you want unsupported types ignored instead "
1873 "of failing, please use the -ignore_unknown option\n"
1874 "If you want them copied, please use -copy_unknown\n");
1875 return AVERROR(EINVAL
);
1880 if (vs
&& ist
->st
->codecpar
->codec_type
!= AVMEDIA_TYPE_VIDEO
) {
1881 av_log(mux
, AV_LOG_ERROR
,
1882 "View specifier given for mapping a %s input stream\n",
1883 av_get_media_type_string(ist
->st
->codecpar
->codec_type
));
1884 return AVERROR(EINVAL
);
1887 ret
= ost_add(mux
, o
, ist
->st
->codecpar
->codec_type
, ist
, NULL
, vs
, NULL
);
1895 static int of_add_attachments(Muxer
*mux
, const OptionsContext
*o
)
1901 for (int i
= 0; i
< o
->nb_attachments
; i
++) {
1903 uint8_t *attachment
;
1904 char *attachment_filename
;
1908 if ((err
= avio_open2(&pb
, o
->attachments
[i
], AVIO_FLAG_READ
, &int_cb
, NULL
)) < 0) {
1909 av_log(mux
, AV_LOG_FATAL
, "Could not open attachment file %s.\n",
1913 if ((len
= avio_size(pb
)) <= 0) {
1914 av_log(mux
, AV_LOG_FATAL
, "Could not get size of the attachment %s.\n",
1916 err
= len
? len
: AVERROR_INVALIDDATA
;
1919 if (len
> INT_MAX
- AV_INPUT_BUFFER_PADDING_SIZE
) {
1920 av_log(mux
, AV_LOG_FATAL
, "Attachment %s too large.\n",
1922 err
= AVERROR(ERANGE
);
1926 attachment
= av_malloc(len
+ AV_INPUT_BUFFER_PADDING_SIZE
);
1928 err
= AVERROR(ENOMEM
);
1932 err
= avio_read(pb
, attachment
, len
);
1934 av_log(mux
, AV_LOG_FATAL
, "Error reading attachment file %s: %s\n",
1935 o
->attachments
[i
], av_err2str(err
));
1936 else if (err
!= len
) {
1937 av_log(mux
, AV_LOG_FATAL
, "Could not read all %"PRId64
" bytes for "
1938 "attachment file %s\n", len
, o
->attachments
[i
]);
1947 memset(attachment
+ len
, 0, AV_INPUT_BUFFER_PADDING_SIZE
);
1949 av_log(mux
, AV_LOG_VERBOSE
, "Creating attachment stream from file %s\n",
1952 attachment_filename
= av_strdup(o
->attachments
[i
]);
1953 if (!attachment_filename
) {
1954 av_free(attachment
);
1955 return AVERROR(ENOMEM
);
1958 err
= ost_add(mux
, o
, AVMEDIA_TYPE_ATTACHMENT
, NULL
, NULL
, NULL
, &ost
);
1960 av_free(attachment_filename
);
1961 av_freep(&attachment
);
1965 ms
= ms_from_ost(ost
);
1967 ost
->attachment_filename
= attachment_filename
;
1968 ms
->par_in
->extradata
= attachment
;
1969 ms
->par_in
->extradata_size
= len
;
1971 p
= strrchr(o
->attachments
[i
], '/');
1972 av_dict_set(&ost
->st
->metadata
, "filename", (p
&& *p
) ? p
+ 1 : o
->attachments
[i
], AV_DICT_DONT_OVERWRITE
);
1978 static int create_streams(Muxer
*mux
, const OptionsContext
*o
)
1980 static int (* const map_func
[])(Muxer
*mux
, const OptionsContext
*o
) = {
1981 [AVMEDIA_TYPE_VIDEO
] = map_auto_video
,
1982 [AVMEDIA_TYPE_AUDIO
] = map_auto_audio
,
1983 [AVMEDIA_TYPE_SUBTITLE
] = map_auto_subtitle
,
1984 [AVMEDIA_TYPE_DATA
] = map_auto_data
,
1987 AVFormatContext
*oc
= mux
->fc
;
1990 o
->video_disable
* (1 << AVMEDIA_TYPE_VIDEO
) |
1991 o
->audio_disable
* (1 << AVMEDIA_TYPE_AUDIO
) |
1992 o
->subtitle_disable
* (1 << AVMEDIA_TYPE_SUBTITLE
) |
1993 o
->data_disable
* (1 << AVMEDIA_TYPE_DATA
);
1997 /* create streams for all unlabeled output pads */
1998 for (int i
= 0; i
< nb_filtergraphs
; i
++) {
1999 FilterGraph
*fg
= filtergraphs
[i
];
2000 for (int j
= 0; j
< fg
->nb_outputs
; j
++) {
2001 OutputFilter
*ofilter
= fg
->outputs
[j
];
2003 if (ofilter
->linklabel
|| ofilter
->bound
)
2006 auto_disable
|= 1 << ofilter
->type
;
2008 av_log(mux
, AV_LOG_VERBOSE
, "Creating output stream from unlabeled "
2009 "output of complex filtergraph %d.", fg
->index
);
2010 if (!o
->nb_stream_maps
)
2011 av_log(mux
, AV_LOG_VERBOSE
, " This overrides automatic %s mapping.",
2012 av_get_media_type_string(ofilter
->type
));
2013 av_log(mux
, AV_LOG_VERBOSE
, "\n");
2015 ret
= ost_add(mux
, o
, ofilter
->type
, NULL
, ofilter
, NULL
, NULL
);
2021 if (!o
->nb_stream_maps
) {
2022 av_log(mux
, AV_LOG_VERBOSE
, "No explicit maps, mapping streams automatically...\n");
2024 /* pick the "best" stream of each type */
2025 for (int i
= 0; i
< FF_ARRAY_ELEMS(map_func
); i
++) {
2026 if (!map_func
[i
] || auto_disable
& (1 << i
))
2028 ret
= map_func
[i
](mux
, o
);
2033 av_log(mux
, AV_LOG_VERBOSE
, "Adding streams from explicit maps...\n");
2035 for (int i
= 0; i
< o
->nb_stream_maps
; i
++) {
2036 ret
= map_manual(mux
, o
, &o
->stream_maps
[i
]);
2042 ret
= of_add_attachments(mux
, o
);
2046 // setup fix_sub_duration_heartbeat mappings
2047 for (unsigned i
= 0; i
< oc
->nb_streams
; i
++) {
2048 MuxStream
*src
= ms_from_ost(mux
->of
.streams
[i
]);
2050 if (!src
->ost
.fix_sub_duration_heartbeat
)
2053 for (unsigned j
= 0; j
< oc
->nb_streams
; j
++) {
2054 MuxStream
*dst
= ms_from_ost(mux
->of
.streams
[j
]);
2056 if (src
== dst
|| dst
->ost
.type
!= AVMEDIA_TYPE_SUBTITLE
||
2057 !dst
->ost
.enc
|| !dst
->ost
.ist
|| !dst
->ost
.ist
->fix_sub_duration
)
2060 ret
= sch_mux_sub_heartbeat_add(mux
->sch
, mux
->sch_idx
, src
->sch_idx
,
2070 for (unsigned i
= 0; i
< mux
->of
.nb_streams
; i
++)
2071 if (mux
->of
.streams
[i
]->type
== AVMEDIA_TYPE_VIDEO
) {
2076 for (unsigned i
= 0; have_video
&& i
< mux
->of
.nb_streams
; i
++) {
2077 MuxStream
*ms
= ms_from_ost(mux
->of
.streams
[i
]);
2078 OutputFilter
*ofilter
= ms
->ost
.filter
;
2080 if (ms
->ost
.type
!= AVMEDIA_TYPE_AUDIO
|| !ms
->apad
|| !ofilter
)
2083 ofilter
->apad
= av_strdup(ms
->apad
);
2085 return AVERROR(ENOMEM
);
2088 for (unsigned i
= 0; i
< mux
->of
.nb_streams
; i
++) {
2089 MuxStream
*ms
= ms_from_ost(mux
->of
.streams
[i
]);
2093 if (!oc
->nb_streams
&& !(oc
->oformat
->flags
& AVFMT_NOSTREAMS
)) {
2094 av_dump_format(oc
, nb_output_files
- 1, oc
->url
, 1);
2095 av_log(mux
, AV_LOG_ERROR
, "Output file does not contain any stream\n");
2096 return AVERROR(EINVAL
);
2102 static int setup_sync_queues(Muxer
*mux
, AVFormatContext
*oc
,
2103 int64_t buf_size_us
, int shortest
)
2105 OutputFile
*of
= &mux
->of
;
2106 int nb_av_enc
= 0, nb_audio_fs
= 0, nb_interleaved
= 0;
2107 int limit_frames
= 0, limit_frames_av_enc
= 0;
2109 #define IS_AV_ENC(ost, type) \
2110 (ost->enc && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO))
2111 #define IS_INTERLEAVED(type) (type != AVMEDIA_TYPE_ATTACHMENT)
2113 for (int i
= 0; i
< oc
->nb_streams
; i
++) {
2114 OutputStream
*ost
= of
->streams
[i
];
2115 MuxStream
*ms
= ms_from_ost(ost
);
2116 enum AVMediaType type
= ost
->type
;
2118 ms
->sq_idx_mux
= -1;
2120 nb_interleaved
+= IS_INTERLEAVED(type
);
2121 nb_av_enc
+= IS_AV_ENC(ost
, type
);
2122 nb_audio_fs
+= (ost
->enc
&& type
== AVMEDIA_TYPE_AUDIO
&&
2123 !(ost
->enc
->enc_ctx
->codec
->capabilities
& AV_CODEC_CAP_VARIABLE_FRAME_SIZE
));
2125 limit_frames
|= ms
->max_frames
< INT64_MAX
;
2126 limit_frames_av_enc
|= (ms
->max_frames
< INT64_MAX
) && IS_AV_ENC(ost
, type
);
2129 if (!((nb_interleaved
> 1 && shortest
) ||
2130 (nb_interleaved
> 0 && limit_frames
) ||
2134 /* we use a sync queue before encoding when:
2135 * - 'shortest' is in effect and we have two or more encoded audio/video
2137 * - at least one encoded audio/video stream is frame-limited, since
2138 * that has similar semantics to 'shortest'
2139 * - at least one audio encoder requires constant frame sizes
2141 * Note that encoding sync queues are handled in the scheduler, because
2142 * different encoders run in different threads and need external
2143 * synchronization, while muxer sync queues can be handled inside the muxer
2145 if ((shortest
&& nb_av_enc
> 1) || limit_frames_av_enc
|| nb_audio_fs
) {
2148 sq_idx
= sch_add_sq_enc(mux
->sch
, buf_size_us
, mux
);
2152 for (int i
= 0; i
< oc
->nb_streams
; i
++) {
2153 OutputStream
*ost
= of
->streams
[i
];
2154 MuxStream
*ms
= ms_from_ost(ost
);
2155 enum AVMediaType type
= ost
->type
;
2157 if (!IS_AV_ENC(ost
, type
))
2160 ret
= sch_sq_add_enc(mux
->sch
, sq_idx
, ms
->sch_idx_enc
,
2161 shortest
|| ms
->max_frames
< INT64_MAX
,
2168 /* if there are any additional interleaved streams, then ALL the streams
2169 * are also synchronized before sending them to the muxer */
2170 if (nb_interleaved
> nb_av_enc
) {
2171 mux
->sq_mux
= sq_alloc(SYNC_QUEUE_PACKETS
, buf_size_us
, mux
);
2173 return AVERROR(ENOMEM
);
2175 mux
->sq_pkt
= av_packet_alloc();
2177 return AVERROR(ENOMEM
);
2179 for (int i
= 0; i
< oc
->nb_streams
; i
++) {
2180 OutputStream
*ost
= of
->streams
[i
];
2181 MuxStream
*ms
= ms_from_ost(ost
);
2182 enum AVMediaType type
= ost
->type
;
2184 if (!IS_INTERLEAVED(type
))
2187 ms
->sq_idx_mux
= sq_add_stream(mux
->sq_mux
,
2188 shortest
|| ms
->max_frames
< INT64_MAX
);
2189 if (ms
->sq_idx_mux
< 0)
2190 return ms
->sq_idx_mux
;
2192 if (ms
->max_frames
!= INT64_MAX
)
2193 sq_limit_frames(mux
->sq_mux
, ms
->sq_idx_mux
, ms
->max_frames
);
2198 #undef IS_INTERLEAVED
2203 static int of_parse_iamf_audio_element_layers(Muxer
*mux
, AVStreamGroup
*stg
, char *ptr
)
2205 AVIAMFAudioElement
*audio_element
= stg
->params
.iamf_audio_element
;
2206 AVDictionary
*dict
= NULL
;
2210 audio_element
->demixing_info
=
2211 av_iamf_param_definition_alloc(AV_IAMF_PARAMETER_DEFINITION_DEMIXING
, 1, NULL
);
2212 audio_element
->recon_gain_info
=
2213 av_iamf_param_definition_alloc(AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN
, 1, NULL
);
2215 if (!audio_element
->demixing_info
||
2216 !audio_element
->recon_gain_info
)
2217 return AVERROR(ENOMEM
);
2219 /* process manually set layers and parameters */
2220 token
= av_strtok(NULL
, ",", &ptr
);
2222 const AVDictionaryEntry
*e
;
2223 int demixing
= 0, recon_gain
= 0;
2227 ptr
+= strspn(ptr
, " \n\t\r");
2228 if (av_strstart(token
, "layer=", &token
))
2230 else if (av_strstart(token
, "demixing=", &token
))
2232 else if (av_strstart(token
, "recon_gain=", &token
))
2235 av_dict_free(&dict
);
2236 ret
= av_dict_parse_string(&dict
, token
, "=", ":", 0);
2238 av_log(mux
, AV_LOG_ERROR
, "Error parsing audio element specification %s\n", token
);
2243 AVIAMFLayer
*audio_layer
= av_iamf_audio_element_add_layer(audio_element
);
2245 av_log(mux
, AV_LOG_ERROR
, "Error adding layer to stream group %d\n", stg
->index
);
2246 ret
= AVERROR(ENOMEM
);
2249 av_opt_set_dict(audio_layer
, &dict
);
2250 } else if (demixing
|| recon_gain
) {
2251 AVIAMFParamDefinition
*param
= demixing
? audio_element
->demixing_info
2252 : audio_element
->recon_gain_info
;
2253 void *subblock
= av_iamf_param_definition_get_subblock(param
, 0);
2255 av_opt_set_dict(param
, &dict
);
2256 av_opt_set_dict(subblock
, &dict
);
2259 // make sure that no entries are left in the dict
2261 if (e
= av_dict_iterate(dict
, e
)) {
2262 av_log(mux
, AV_LOG_FATAL
, "Unknown layer key %s.\n", e
->key
);
2263 ret
= AVERROR(EINVAL
);
2266 token
= av_strtok(NULL
, ",", &ptr
);
2270 av_dict_free(&dict
);
2271 if (!ret
&& !audio_element
->nb_layers
) {
2272 av_log(mux
, AV_LOG_ERROR
, "No layer in audio element specification\n");
2273 ret
= AVERROR(EINVAL
);
2279 static int of_parse_iamf_submixes(Muxer
*mux
, AVStreamGroup
*stg
, char *ptr
)
2281 AVFormatContext
*oc
= mux
->fc
;
2282 AVIAMFMixPresentation
*mix
= stg
->params
.iamf_mix_presentation
;
2283 AVDictionary
*dict
= NULL
;
2285 char *submix_str
= NULL
;
2288 /* process manually set submixes */
2289 token
= av_strtok(NULL
, ",", &ptr
);
2291 AVIAMFSubmix
*submix
= NULL
;
2292 const char *subtoken
;
2293 char *subptr
= NULL
;
2296 ptr
+= strspn(ptr
, " \n\t\r");
2297 if (!av_strstart(token
, "submix=", &token
)) {
2298 av_log(mux
, AV_LOG_ERROR
, "No submix in mix presentation specification \"%s\"\n", token
);
2302 submix_str
= av_strdup(token
);
2306 submix
= av_iamf_mix_presentation_add_submix(mix
);
2308 av_log(mux
, AV_LOG_ERROR
, "Error adding submix to stream group %d\n", stg
->index
);
2309 ret
= AVERROR(ENOMEM
);
2312 submix
->output_mix_config
=
2313 av_iamf_param_definition_alloc(AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN
, 0, NULL
);
2314 if (!submix
->output_mix_config
) {
2315 ret
= AVERROR(ENOMEM
);
2320 subtoken
= av_strtok(submix_str
, "|", &subptr
);
2322 const AVDictionaryEntry
*e
;
2323 int element
= 0, layout
= 0;
2326 subptr
+= strspn(subptr
, " \n\t\r");
2327 if (av_strstart(subtoken
, "element=", &subtoken
))
2329 else if (av_strstart(subtoken
, "layout=", &subtoken
))
2332 av_dict_free(&dict
);
2333 ret
= av_dict_parse_string(&dict
, subtoken
, "=", ":", 0);
2335 av_log(mux
, AV_LOG_ERROR
, "Error parsing submix specification \"%s\"\n", subtoken
);
2340 AVIAMFSubmixElement
*submix_element
;
2341 char *endptr
= NULL
;
2344 if (e
= av_dict_get(dict
, "stg", NULL
, 0))
2345 idx
= strtoll(e
->value
, &endptr
, 0);
2346 if (!endptr
|| *endptr
|| idx
< 0 || idx
>= oc
->nb_stream_groups
- 1 ||
2347 oc
->stream_groups
[idx
]->type
!= AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
) {
2348 av_log(mux
, AV_LOG_ERROR
, "Invalid or missing stream group index in "
2349 "submix element specification \"%s\"\n", subtoken
);
2350 ret
= AVERROR(EINVAL
);
2353 submix_element
= av_iamf_submix_add_element(submix
);
2354 if (!submix_element
) {
2355 av_log(mux
, AV_LOG_ERROR
, "Error adding element to submix\n");
2356 ret
= AVERROR(ENOMEM
);
2360 submix_element
->audio_element_id
= oc
->stream_groups
[idx
]->id
;
2362 submix_element
->element_mix_config
=
2363 av_iamf_param_definition_alloc(AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN
, 0, NULL
);
2364 if (!submix_element
->element_mix_config
)
2365 ret
= AVERROR(ENOMEM
);
2366 av_dict_set(&dict
, "stg", NULL
, 0);
2367 av_opt_set_dict2(submix_element
, &dict
, AV_OPT_SEARCH_CHILDREN
);
2368 } else if (layout
) {
2369 AVIAMFSubmixLayout
*submix_layout
= av_iamf_submix_add_layout(submix
);
2370 if (!submix_layout
) {
2371 av_log(mux
, AV_LOG_ERROR
, "Error adding layout to submix\n");
2372 ret
= AVERROR(ENOMEM
);
2375 av_opt_set_dict(submix_layout
, &dict
);
2377 av_opt_set_dict2(submix
, &dict
, AV_OPT_SEARCH_CHILDREN
);
2383 // make sure that no entries are left in the dict
2385 while (e
= av_dict_iterate(dict
, e
)) {
2386 av_log(mux
, AV_LOG_FATAL
, "Unknown submix key %s.\n", e
->key
);
2387 ret
= AVERROR(EINVAL
);
2390 subtoken
= av_strtok(NULL
, "|", &subptr
);
2392 av_freep(&submix_str
);
2394 if (!submix
->nb_elements
) {
2395 av_log(mux
, AV_LOG_ERROR
, "No audio elements in submix specification \"%s\"\n", token
);
2396 ret
= AVERROR(EINVAL
);
2398 token
= av_strtok(NULL
, ",", &ptr
);
2402 av_dict_free(&dict
);
2403 av_free(submix_str
);
2408 static int of_serialize_options(Muxer
*mux
, void *obj
, AVBPrint
*bp
)
2413 ret
= av_opt_serialize(obj
, 0, AV_OPT_SERIALIZE_SKIP_DEFAULTS
| AV_OPT_SERIALIZE_SEARCH_CHILDREN
,
2416 av_log(mux
, AV_LOG_ERROR
, "Failed to serialize group\n");
2420 av_bprintf(bp
, "%s", ptr
);
2427 #define SERIALIZE(parent, child) do { \
2428 ret = of_serialize_options(mux, parent->child, bp); \
2433 #define SERIALIZE_LOOP_SUBBLOCK(obj) do { \
2434 for (int k = 0; k < obj->nb_subblocks; k++) { \
2435 ret = of_serialize_options(mux, \
2436 av_iamf_param_definition_get_subblock(obj, k), bp); \
2442 #define SERIALIZE_LOOP(parent, child, suffix, separator) do { \
2443 for (int j = 0; j < parent->nb_## child ## suffix; j++) { \
2444 av_bprintf(bp, separator#child "="); \
2445 SERIALIZE(parent, child ## suffix[j]); \
2449 static int64_t get_stream_group_index_from_id(Muxer
*mux
, int64_t id
)
2451 AVFormatContext
*oc
= mux
->fc
;
2453 for (unsigned i
= 0; i
< oc
->nb_stream_groups
; i
++)
2454 if (oc
->stream_groups
[i
]->id
== id
)
2455 return oc
->stream_groups
[i
]->index
;
2457 return AVERROR(EINVAL
);
2460 static int of_map_group(Muxer
*mux
, AVDictionary
**dict
, AVBPrint
*bp
, const char *map
)
2463 int ret
, file_idx
, stream_idx
;
2466 file_idx
= strtol(map
, &ptr
, 0);
2467 if (file_idx
>= nb_input_files
|| file_idx
< 0 || map
== ptr
) {
2468 av_log(mux
, AV_LOG_ERROR
, "Invalid input file index: %d.\n", file_idx
);
2469 return AVERROR(EINVAL
);
2472 stream_idx
= strtol(*ptr
== '=' ? ptr
+ 1 : ptr
, &ptr
, 0);
2473 if (*ptr
|| stream_idx
>= input_files
[file_idx
]->ctx
->nb_stream_groups
|| stream_idx
< 0) {
2474 av_log(mux
, AV_LOG_ERROR
, "Invalid input stream group index: %d.\n", stream_idx
);
2475 return AVERROR(EINVAL
);
2478 stg
= input_files
[file_idx
]->ctx
->stream_groups
[stream_idx
];
2479 ret
= of_serialize_options(mux
, stg
, bp
);
2483 ret
= av_dict_parse_string(dict
, bp
->str
, "=", ":", 0);
2485 av_log(mux
, AV_LOG_ERROR
, "Error parsing mapped group specification %s\n", ptr
);
2486 av_dict_set_int(dict
, "type", stg
->type
, 0);
2488 av_bprint_clear(bp
);
2490 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
: {
2491 AVIAMFAudioElement
*audio_element
= stg
->params
.iamf_audio_element
;
2493 if (audio_element
->demixing_info
) {
2494 AVIAMFParamDefinition
*demixing_info
= audio_element
->demixing_info
;
2495 av_bprintf(bp
, ",demixing=");
2496 SERIALIZE(audio_element
, demixing_info
);
2497 if (ret
&& demixing_info
->nb_subblocks
)
2498 av_bprintf(bp
, ":");
2499 SERIALIZE_LOOP_SUBBLOCK(demixing_info
);
2501 if (audio_element
->recon_gain_info
) {
2502 AVIAMFParamDefinition
*recon_gain_info
= audio_element
->recon_gain_info
;
2503 av_bprintf(bp
, ",recon_gain=");
2504 SERIALIZE(audio_element
, recon_gain_info
);
2505 if (ret
&& recon_gain_info
->nb_subblocks
)
2506 av_bprintf(bp
, ":");
2507 SERIALIZE_LOOP_SUBBLOCK(recon_gain_info
);
2509 SERIALIZE_LOOP(audio_element
, layer
, s
, ",");
2512 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
: {
2513 AVIAMFMixPresentation
*mix
= stg
->params
.iamf_mix_presentation
;
2515 for (int i
= 0; i
< mix
->nb_submixes
; i
++) {
2516 AVIAMFSubmix
*submix
= mix
->submixes
[i
];
2517 AVIAMFParamDefinition
*output_mix_config
= submix
->output_mix_config
;
2519 av_bprintf(bp
, ",submix=");
2520 SERIALIZE(mix
, submixes
[i
]);
2521 if (ret
&& output_mix_config
->nb_subblocks
)
2522 av_bprintf(bp
, ":");
2523 SERIALIZE_LOOP_SUBBLOCK(output_mix_config
);
2524 for (int j
= 0; j
< submix
->nb_elements
; j
++) {
2525 AVIAMFSubmixElement
*element
= submix
->elements
[j
];
2526 AVIAMFParamDefinition
*element_mix_config
= element
->element_mix_config
;
2527 int64_t id
= get_stream_group_index_from_id(mux
, element
->audio_element_id
);
2530 av_log(mux
, AV_LOG_ERROR
, "Invalid or missing stream group index in"
2535 av_bprintf(bp
, "|element=");
2536 SERIALIZE(submix
, elements
[j
]);
2537 if (ret
&& element_mix_config
->nb_subblocks
)
2538 av_bprintf(bp
, ":");
2539 SERIALIZE_LOOP_SUBBLOCK(element_mix_config
);
2541 av_bprintf(bp
, ":");
2542 av_bprintf(bp
, "stg=%"PRId64
, id
);
2544 SERIALIZE_LOOP(submix
, layout
, s
, "|");
2549 av_log(mux
, AV_LOG_ERROR
, "Unsupported mapped group type %d.\n", stg
->type
);
2550 ret
= AVERROR(EINVAL
);
2556 static int of_parse_group_token(Muxer
*mux
, const char *token
, char *ptr
)
2558 AVFormatContext
*oc
= mux
->fc
;
2560 AVDictionary
*dict
= NULL
, *tmp
= NULL
;
2561 char *mapped_string
= NULL
;
2562 const AVDictionaryEntry
*e
;
2563 const AVOption opts
[] = {
2564 { "type", "Set group type", offsetof(AVStreamGroup
, type
), AV_OPT_TYPE_INT
,
2565 { .i64
= 0 }, 0, INT_MAX
, AV_OPT_FLAG_ENCODING_PARAM
, .unit
= "type" },
2566 { "iamf_audio_element", NULL
, 0, AV_OPT_TYPE_CONST
,
2567 { .i64
= AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
}, .unit
= "type" },
2568 { "iamf_mix_presentation", NULL
, 0, AV_OPT_TYPE_CONST
,
2569 { .i64
= AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
}, .unit
= "type" },
2572 const AVClass
class = {
2573 .class_name
= "StreamGroupType",
2574 .item_name
= av_default_item_name
,
2576 .version
= LIBAVUTIL_VERSION_INT
,
2578 const AVClass
*pclass
= &class;
2581 ret
= av_dict_parse_string(&dict
, token
, "=", ":", AV_DICT_MULTIKEY
);
2583 av_log(mux
, AV_LOG_ERROR
, "Error parsing group specification %s\n", token
);
2587 av_dict_copy(&tmp
, dict
, 0);
2588 e
= av_dict_get(dict
, "map", NULL
, 0);
2593 av_log(mux
, AV_LOG_ERROR
, "Unexpected extra parameters when mapping a"
2595 ret
= AVERROR(EINVAL
);
2599 av_bprint_init(&bp
, 0, AV_BPRINT_SIZE_AUTOMATIC
);
2600 ret
= of_map_group(mux
, &tmp
, &bp
, e
->value
);
2602 av_bprint_finalize(&bp
, NULL
);
2606 av_bprint_finalize(&bp
, &mapped_string
);
2607 ptr
= mapped_string
;
2610 // "type" is not a user settable AVOption in AVStreamGroup, so handle it here
2611 e
= av_dict_get(tmp
, "type", NULL
, 0);
2613 av_log(mux
, AV_LOG_ERROR
, "No type specified for Stream Group in \"%s\"\n", token
);
2614 ret
= AVERROR(EINVAL
);
2618 ret
= av_opt_eval_int(&pclass
, opts
, e
->value
, &type
);
2619 if (!ret
&& type
== AV_STREAM_GROUP_PARAMS_NONE
)
2620 ret
= AVERROR(EINVAL
);
2622 av_log(mux
, AV_LOG_ERROR
, "Invalid group type \"%s\"\n", e
->value
);
2626 stg
= avformat_stream_group_create(oc
, type
, &tmp
);
2628 ret
= AVERROR(ENOMEM
);
2633 while (e
= av_dict_get(dict
, "st", e
, 0)) {
2635 int64_t idx
= strtoll(e
->value
, &endptr
, 0);
2636 if (*endptr
|| idx
< 0 || idx
>= oc
->nb_streams
) {
2637 av_log(mux
, AV_LOG_ERROR
, "Invalid stream index %"PRId64
"\n", idx
);
2638 ret
= AVERROR(EINVAL
);
2641 ret
= avformat_stream_group_add_stream(stg
, oc
->streams
[idx
]);
2645 while (e
= av_dict_get(dict
, "stg", e
, 0)) {
2647 int64_t idx
= strtoll(e
->value
, &endptr
, 0);
2648 if (*endptr
|| idx
< 0 || idx
>= oc
->nb_stream_groups
- 1) {
2649 av_log(mux
, AV_LOG_ERROR
, "Invalid stream group index %"PRId64
"\n", idx
);
2650 ret
= AVERROR(EINVAL
);
2653 for (unsigned i
= 0; i
< oc
->stream_groups
[idx
]->nb_streams
; i
++) {
2654 ret
= avformat_stream_group_add_stream(stg
, oc
->stream_groups
[idx
]->streams
[i
]);
2661 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT
:
2662 ret
= of_parse_iamf_audio_element_layers(mux
, stg
, ptr
);
2664 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION
:
2665 ret
= of_parse_iamf_submixes(mux
, stg
, ptr
);
2668 av_log(mux
, AV_LOG_FATAL
, "Unknown group type %d.\n", type
);
2669 ret
= AVERROR(EINVAL
);
2676 // make sure that nothing but "st" and "stg" entries are left in the dict
2678 av_dict_set(&tmp
, "map", NULL
, 0);
2679 av_dict_set(&tmp
, "type", NULL
, 0);
2680 while (e
= av_dict_iterate(tmp
, e
)) {
2681 if (!strcmp(e
->key
, "st") || !strcmp(e
->key
, "stg"))
2684 av_log(mux
, AV_LOG_FATAL
, "Unknown group key %s.\n", e
->key
);
2685 ret
= AVERROR(EINVAL
);
2691 av_free(mapped_string
);
2692 av_dict_free(&dict
);
2698 static int of_add_groups(Muxer
*mux
, const OptionsContext
*o
)
2700 /* process manually set groups */
2701 for (int i
= 0; i
< o
->stream_groups
.nb_opt
; i
++) {
2703 char *str
, *ptr
= NULL
;
2706 str
= av_strdup(o
->stream_groups
.opt
[i
].u
.str
);
2710 token
= av_strtok(str
, ",", &ptr
);
2713 ptr
+= strspn(ptr
, " \n\t\r");
2714 ret
= of_parse_group_token(mux
, token
, ptr
);
2725 static int of_add_programs(Muxer
*mux
, const OptionsContext
*o
)
2727 AVFormatContext
*oc
= mux
->fc
;
2728 /* process manually set programs */
2729 for (int i
= 0; i
< o
->program
.nb_opt
; i
++) {
2730 AVDictionary
*dict
= NULL
;
2731 const AVDictionaryEntry
*e
;
2733 int ret
, progid
= i
+ 1;
2735 ret
= av_dict_parse_string(&dict
, o
->program
.opt
[i
].u
.str
, "=", ":",
2738 av_log(mux
, AV_LOG_ERROR
, "Error parsing program specification %s\n",
2739 o
->program
.opt
[i
].u
.str
);
2743 e
= av_dict_get(dict
, "program_num", NULL
, 0);
2745 progid
= strtol(e
->value
, NULL
, 0);
2746 av_dict_set(&dict
, e
->key
, NULL
, 0);
2749 program
= av_new_program(oc
, progid
);
2751 ret
= AVERROR(ENOMEM
);
2755 e
= av_dict_get(dict
, "title", NULL
, 0);
2757 av_dict_set(&program
->metadata
, e
->key
, e
->value
, 0);
2758 av_dict_set(&dict
, e
->key
, NULL
, 0);
2762 while (e
= av_dict_get(dict
, "st", e
, 0)) {
2763 int st_num
= strtol(e
->value
, NULL
, 0);
2764 av_program_add_stream_index(oc
, progid
, st_num
);
2767 // make sure that nothing but "st" entries are left in the dict
2769 while (e
= av_dict_iterate(dict
, e
)) {
2770 if (!strcmp(e
->key
, "st"))
2773 av_log(mux
, AV_LOG_FATAL
, "Unknown program key %s.\n", e
->key
);
2774 ret
= AVERROR(EINVAL
);
2779 av_dict_free(&dict
);
2788 * Parse a metadata specifier passed as 'arg' parameter.
2789 * @param arg metadata string to parse
2790 * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
2791 * @param index for type c/p, chapter/program index is written here
2792 * @param stream_spec for type s, the stream specifier is written here
2794 static int parse_meta_type(void *logctx
, const char *arg
,
2795 char *type
, int *index
, const char **stream_spec
)
2803 if (*(++arg
) && *arg
!= ':') {
2804 av_log(logctx
, AV_LOG_FATAL
, "Invalid metadata specifier %s.\n", arg
);
2805 return AVERROR(EINVAL
);
2807 *stream_spec
= *arg
== ':' ? arg
+ 1 : "";
2811 if (*(++arg
) == ':')
2812 *index
= strtol(++arg
, NULL
, 0);
2815 av_log(logctx
, AV_LOG_FATAL
, "Invalid metadata type %c.\n", *arg
);
2816 return AVERROR(EINVAL
);
2824 static int of_add_metadata(OutputFile
*of
, AVFormatContext
*oc
,
2825 const OptionsContext
*o
)
2827 for (int i
= 0; i
< o
->metadata
.nb_opt
; i
++) {
2830 const char *stream_spec
;
2831 int index
= 0, ret
= 0;
2833 val
= strchr(o
->metadata
.opt
[i
].u
.str
, '=');
2835 av_log(of
, AV_LOG_FATAL
, "No '=' character in metadata string %s.\n",
2836 o
->metadata
.opt
[i
].u
.str
);
2837 return AVERROR(EINVAL
);
2841 ret
= parse_meta_type(of
, o
->metadata
.opt
[i
].specifier
, &type
, &index
, &stream_spec
);
2846 for (int j
= 0; j
< oc
->nb_streams
; j
++) {
2847 if ((ret
= check_stream_specifier(oc
, oc
->streams
[j
], stream_spec
)) > 0) {
2848 av_dict_set(&oc
->streams
[j
]->metadata
, o
->metadata
.opt
[i
].u
.str
, *val
? val
: NULL
, 0);
2858 if (index
< 0 || index
>= oc
->nb_chapters
) {
2859 av_log(of
, AV_LOG_FATAL
, "Invalid chapter index %d in metadata specifier.\n", index
);
2860 return AVERROR(EINVAL
);
2862 m
= &oc
->chapters
[index
]->metadata
;
2865 if (index
< 0 || index
>= oc
->nb_programs
) {
2866 av_log(of
, AV_LOG_FATAL
, "Invalid program index %d in metadata specifier.\n", index
);
2867 return AVERROR(EINVAL
);
2869 m
= &oc
->programs
[index
]->metadata
;
2872 av_log(of
, AV_LOG_FATAL
, "Invalid metadata specifier %s.\n", o
->metadata
.opt
[i
].specifier
);
2873 return AVERROR(EINVAL
);
2875 av_dict_set(m
, o
->metadata
.opt
[i
].u
.str
, *val
? val
: NULL
, 0);
2882 static int copy_chapters(InputFile
*ifile
, OutputFile
*ofile
, AVFormatContext
*os
,
2885 AVFormatContext
*is
= ifile
->ctx
;
2888 tmp
= av_realloc_f(os
->chapters
, is
->nb_chapters
+ os
->nb_chapters
, sizeof(*os
->chapters
));
2890 return AVERROR(ENOMEM
);
2893 for (int i
= 0; i
< is
->nb_chapters
; i
++) {
2894 AVChapter
*in_ch
= is
->chapters
[i
], *out_ch
;
2895 int64_t start_time
= (ofile
->start_time
== AV_NOPTS_VALUE
) ? 0 : ofile
->start_time
;
2896 int64_t ts_off
= av_rescale_q(start_time
- ifile
->ts_offset
,
2897 AV_TIME_BASE_Q
, in_ch
->time_base
);
2898 int64_t rt
= (ofile
->recording_time
== INT64_MAX
) ? INT64_MAX
:
2899 av_rescale_q(ofile
->recording_time
, AV_TIME_BASE_Q
, in_ch
->time_base
);
2902 if (in_ch
->end
< ts_off
)
2904 if (rt
!= INT64_MAX
&& in_ch
->start
> rt
+ ts_off
)
2907 out_ch
= av_mallocz(sizeof(AVChapter
));
2909 return AVERROR(ENOMEM
);
2911 out_ch
->id
= in_ch
->id
;
2912 out_ch
->time_base
= in_ch
->time_base
;
2913 out_ch
->start
= FFMAX(0, in_ch
->start
- ts_off
);
2914 out_ch
->end
= FFMIN(rt
, in_ch
->end
- ts_off
);
2917 av_dict_copy(&out_ch
->metadata
, in_ch
->metadata
, 0);
2919 os
->chapters
[os
->nb_chapters
++] = out_ch
;
2924 static int copy_metadata(Muxer
*mux
, AVFormatContext
*ic
,
2925 const char *outspec
, const char *inspec
,
2926 int *metadata_global_manual
, int *metadata_streams_manual
,
2927 int *metadata_chapters_manual
)
2929 AVFormatContext
*oc
= mux
->fc
;
2930 AVDictionary
**meta_in
= NULL
;
2931 AVDictionary
**meta_out
= NULL
;
2933 char type_in
, type_out
;
2934 const char *istream_spec
= NULL
, *ostream_spec
= NULL
;
2935 int idx_in
= 0, idx_out
= 0;
2937 ret
= parse_meta_type(mux
, inspec
, &type_in
, &idx_in
, &istream_spec
);
2939 ret
= parse_meta_type(mux
, outspec
, &type_out
, &idx_out
, &ostream_spec
);
2943 if (type_in
== 'g' || type_out
== 'g' || (!*outspec
&& !ic
))
2944 *metadata_global_manual
= 1;
2945 if (type_in
== 's' || type_out
== 's' || (!*outspec
&& !ic
))
2946 *metadata_streams_manual
= 1;
2947 if (type_in
== 'c' || type_out
== 'c' || (!*outspec
&& !ic
))
2948 *metadata_chapters_manual
= 1;
2950 /* ic is NULL when just disabling automatic mappings */
2954 #define METADATA_CHECK_INDEX(index, nb_elems, desc)\
2955 if ((index) < 0 || (index) >= (nb_elems)) {\
2956 av_log(mux, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
2958 return AVERROR(EINVAL);\
2961 #define SET_DICT(type, meta, context, index)\
2964 meta = &context->metadata;\
2967 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
2968 meta = &context->chapters[index]->metadata;\
2971 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
2972 meta = &context->programs[index]->metadata;\
2975 break; /* handled separately below */ \
2976 default: av_assert0(0);\
2979 SET_DICT(type_in, meta_in, ic, idx_in);
2980 SET_DICT(type_out
, meta_out
, oc
, idx_out
);
2982 /* for input streams choose first matching stream */
2983 if (type_in
== 's') {
2984 for (i
= 0; i
< ic
->nb_streams
; i
++) {
2985 if ((ret
= check_stream_specifier(ic
, ic
->streams
[i
], istream_spec
)) > 0) {
2986 meta_in
= &ic
->streams
[i
]->metadata
;
2992 av_log(mux
, AV_LOG_FATAL
, "Stream specifier %s does not match any streams.\n", istream_spec
);
2993 return AVERROR(EINVAL
);
2997 if (type_out
== 's') {
2998 for (i
= 0; i
< oc
->nb_streams
; i
++) {
2999 if ((ret
= check_stream_specifier(oc
, oc
->streams
[i
], ostream_spec
)) > 0) {
3000 meta_out
= &oc
->streams
[i
]->metadata
;
3001 av_dict_copy(meta_out
, *meta_in
, AV_DICT_DONT_OVERWRITE
);
3006 av_dict_copy(meta_out
, *meta_in
, AV_DICT_DONT_OVERWRITE
);
3011 static int copy_meta(Muxer
*mux
, const OptionsContext
*o
)
3013 OutputFile
*of
= &mux
->of
;
3014 AVFormatContext
*oc
= mux
->fc
;
3015 int chapters_input_file
= o
->chapters_input_file
;
3016 int metadata_global_manual
= 0;
3017 int metadata_streams_manual
= 0;
3018 int metadata_chapters_manual
= 0;
3022 for (int i
= 0; i
< o
->metadata_map
.nb_opt
; i
++) {
3024 int in_file_index
= strtol(o
->metadata_map
.opt
[i
].u
.str
, &p
, 0);
3026 if (in_file_index
>= nb_input_files
) {
3027 av_log(mux
, AV_LOG_FATAL
, "Invalid input file index %d while "
3028 "processing metadata maps\n", in_file_index
);
3029 return AVERROR(EINVAL
);
3031 ret
= copy_metadata(mux
,
3032 in_file_index
>= 0 ? input_files
[in_file_index
]->ctx
: NULL
,
3033 o
->metadata_map
.opt
[i
].specifier
, *p
? p
+ 1 : p
,
3034 &metadata_global_manual
, &metadata_streams_manual
,
3035 &metadata_chapters_manual
);
3041 if (chapters_input_file
>= nb_input_files
) {
3042 if (chapters_input_file
== INT_MAX
) {
3043 /* copy chapters from the first input file that has them*/
3044 chapters_input_file
= -1;
3045 for (int i
= 0; i
< nb_input_files
; i
++)
3046 if (input_files
[i
]->ctx
->nb_chapters
) {
3047 chapters_input_file
= i
;
3051 av_log(mux
, AV_LOG_FATAL
, "Invalid input file index %d in chapter mapping.\n",
3052 chapters_input_file
);
3053 return AVERROR(EINVAL
);
3056 if (chapters_input_file
>= 0)
3057 copy_chapters(input_files
[chapters_input_file
], of
, oc
,
3058 !metadata_chapters_manual
);
3060 /* copy global metadata by default */
3061 if (!metadata_global_manual
&& nb_input_files
){
3062 av_dict_copy(&oc
->metadata
, input_files
[0]->ctx
->metadata
,
3063 AV_DICT_DONT_OVERWRITE
);
3064 if (of
->recording_time
!= INT64_MAX
)
3065 av_dict_set(&oc
->metadata
, "duration", NULL
, 0);
3066 av_dict_set(&oc
->metadata
, "creation_time", NULL
, 0);
3067 av_dict_set(&oc
->metadata
, "company_name", NULL
, 0);
3068 av_dict_set(&oc
->metadata
, "product_name", NULL
, 0);
3069 av_dict_set(&oc
->metadata
, "product_version", NULL
, 0);
3071 if (!metadata_streams_manual
)
3072 for (int i
= 0; i
< of
->nb_streams
; i
++) {
3073 OutputStream
*ost
= of
->streams
[i
];
3075 if (!ost
->ist
) /* this is true e.g. for attached files */
3077 av_dict_copy(&ost
->st
->metadata
, ost
->ist
->st
->metadata
, AV_DICT_DONT_OVERWRITE
);
3083 static int set_dispositions(Muxer
*mux
, const OptionsContext
*o
)
3085 OutputFile
*of
= &mux
->of
;
3086 AVFormatContext
*ctx
= mux
->fc
;
3088 // indexed by type+1, because AVMEDIA_TYPE_UNKNOWN=-1
3089 int nb_streams
[AVMEDIA_TYPE_NB
+ 1] = { 0 };
3090 int have_default
[AVMEDIA_TYPE_NB
+ 1] = { 0 };
3091 int have_manual
= 0;
3094 const char **dispositions
;
3096 dispositions
= av_calloc(ctx
->nb_streams
, sizeof(*dispositions
));
3098 return AVERROR(ENOMEM
);
3100 // first, copy the input dispositions
3101 for (int i
= 0; i
< ctx
->nb_streams
; i
++) {
3102 OutputStream
*ost
= of
->streams
[i
];
3104 nb_streams
[ost
->type
+ 1]++;
3106 opt_match_per_stream_str(ost
, &o
->disposition
, ctx
, ost
->st
, &dispositions
[i
]);
3108 have_manual
|= !!dispositions
[i
];
3111 ost
->st
->disposition
= ost
->ist
->st
->disposition
;
3113 if (ost
->st
->disposition
& AV_DISPOSITION_DEFAULT
)
3114 have_default
[ost
->type
+ 1] = 1;
3119 // process manually set dispositions - they override the above copy
3120 for (int i
= 0; i
< ctx
->nb_streams
; i
++) {
3121 OutputStream
*ost
= of
->streams
[i
];
3122 const char *disp
= dispositions
[i
];
3127 ret
= av_opt_set(ost
->st
, "disposition", disp
, 0);
3132 // For each media type with more than one stream, find a suitable stream to
3133 // mark as default, unless one is already marked default.
3134 // "Suitable" means the first of that type, skipping attached pictures.
3135 for (int i
= 0; i
< ctx
->nb_streams
; i
++) {
3136 OutputStream
*ost
= of
->streams
[i
];
3137 enum AVMediaType type
= ost
->type
;
3139 if (nb_streams
[type
+ 1] < 2 || have_default
[type
+ 1] ||
3140 ost
->st
->disposition
& AV_DISPOSITION_ATTACHED_PIC
)
3143 ost
->st
->disposition
|= AV_DISPOSITION_DEFAULT
;
3144 have_default
[type
+ 1] = 1;
3149 av_freep(&dispositions
);
3154 static const char *const forced_keyframes_const_names
[] = {
3163 static int compare_int64(const void *a
, const void *b
)
3165 return FFDIFFSIGN(*(const int64_t *)a
, *(const int64_t *)b
);
3168 static int parse_forced_key_frames(void *log
, KeyframeForceCtx
*kf
,
3169 const Muxer
*mux
, const char *spec
)
3172 int n
= 1, i
, ret
, size
, index
= 0;
3175 for (p
= spec
; *p
; p
++)
3179 pts
= av_malloc_array(size
, sizeof(*pts
));
3181 return AVERROR(ENOMEM
);
3184 for (i
= 0; i
< n
; i
++) {
3185 char *next
= strchr(p
, ',');
3190 if (strstr(p
, "chapters") == p
) {
3191 AVChapter
* const *ch
= mux
->fc
->chapters
;
3192 unsigned int nb_ch
= mux
->fc
->nb_chapters
;
3195 if (nb_ch
> INT_MAX
- size
) {
3196 ret
= AVERROR(ERANGE
);
3200 pts
= av_realloc_f(pts
, size
, sizeof(*pts
));
3202 return AVERROR(ENOMEM
);
3205 ret
= av_parse_time(&t
, p
+ 8, 1);
3207 av_log(log
, AV_LOG_ERROR
,
3208 "Invalid chapter time offset: %s\n", p
+ 8);
3214 for (j
= 0; j
< nb_ch
; j
++) {
3215 const AVChapter
*c
= ch
[j
];
3216 av_assert1(index
< size
);
3217 pts
[index
++] = av_rescale_q(c
->start
, c
->time_base
,
3218 AV_TIME_BASE_Q
) + t
;
3222 av_assert1(index
< size
);
3223 ret
= av_parse_time(&t
, p
, 1);
3225 av_log(log
, AV_LOG_ERROR
, "Invalid keyframe time: %s\n", p
);
3235 av_assert0(index
== size
);
3236 qsort(pts
, size
, sizeof(*pts
), compare_int64
);
3246 static int process_forced_keyframes(Muxer
*mux
, const OptionsContext
*o
)
3248 for (int i
= 0; i
< mux
->of
.nb_streams
; i
++) {
3249 OutputStream
*ost
= mux
->of
.streams
[i
];
3250 const char *forced_keyframes
= NULL
;
3252 opt_match_per_stream_str(ost
, &o
->forced_key_frames
,
3253 mux
->fc
, ost
->st
, &forced_keyframes
);
3255 if (!(ost
->type
== AVMEDIA_TYPE_VIDEO
&&
3256 ost
->enc
&& forced_keyframes
))
3259 if (!strncmp(forced_keyframes
, "expr:", 5)) {
3260 int ret
= av_expr_parse(&ost
->kf
.pexpr
, forced_keyframes
+ 5,
3261 forced_keyframes_const_names
, NULL
, NULL
, NULL
, NULL
, 0, NULL
);
3263 av_log(ost
, AV_LOG_ERROR
,
3264 "Invalid force_key_frames expression '%s'\n", forced_keyframes
+ 5);
3267 ost
->kf
.expr_const_values
[FKF_N
] = 0;
3268 ost
->kf
.expr_const_values
[FKF_N_FORCED
] = 0;
3269 ost
->kf
.expr_const_values
[FKF_PREV_FORCED_N
] = NAN
;
3270 ost
->kf
.expr_const_values
[FKF_PREV_FORCED_T
] = NAN
;
3272 // Don't parse the 'forced_keyframes' in case of 'keep-source-keyframes',
3273 // parse it only for static kf timings
3274 } else if (!strcmp(forced_keyframes
, "source")) {
3275 ost
->kf
.type
= KF_FORCE_SOURCE
;
3276 #if FFMPEG_OPT_FORCE_KF_SOURCE_NO_DROP
3277 } else if (!strcmp(forced_keyframes
, "source_no_drop")) {
3278 av_log(ost
, AV_LOG_WARNING
, "The 'source_no_drop' value for "
3279 "-force_key_frames is deprecated, use just 'source'\n");
3280 ost
->kf
.type
= KF_FORCE_SOURCE
;
3283 int ret
= parse_forced_key_frames(ost
, &ost
->kf
, mux
, forced_keyframes
);
3292 static const char *output_file_item_name(void *obj
)
3294 const Muxer
*mux
= obj
;
3296 return mux
->log_name
;
3299 static const AVClass output_file_class
= {
3300 .class_name
= "OutputFile",
3301 .version
= LIBAVUTIL_VERSION_INT
,
3302 .item_name
= output_file_item_name
,
3303 .category
= AV_CLASS_CATEGORY_MUXER
,
3306 static Muxer
*mux_alloc(void)
3308 Muxer
*mux
= allocate_array_elem(&output_files
, sizeof(*mux
), &nb_output_files
);
3313 mux
->of
.class = &output_file_class
;
3314 mux
->of
.index
= nb_output_files
- 1;
3316 snprintf(mux
->log_name
, sizeof(mux
->log_name
), "out#%d", mux
->of
.index
);
3321 int of_open(const OptionsContext
*o
, const char *filename
, Scheduler
*sch
)
3324 AVFormatContext
*oc
;
3328 int64_t recording_time
= o
->recording_time
;
3329 int64_t stop_time
= o
->stop_time
;
3333 return AVERROR(ENOMEM
);
3337 if (stop_time
!= INT64_MAX
&& recording_time
!= INT64_MAX
) {
3338 stop_time
= INT64_MAX
;
3339 av_log(mux
, AV_LOG_WARNING
, "-t and -to cannot be used together; using -t.\n");
3342 if (stop_time
!= INT64_MAX
&& recording_time
== INT64_MAX
) {
3343 int64_t start_time
= o
->start_time
== AV_NOPTS_VALUE
? 0 : o
->start_time
;
3344 if (stop_time
<= start_time
) {
3345 av_log(mux
, AV_LOG_ERROR
, "-to value smaller than -ss; aborting.\n");
3346 return AVERROR(EINVAL
);
3348 recording_time
= stop_time
- start_time
;
3352 of
->recording_time
= recording_time
;
3353 of
->start_time
= o
->start_time
;
3355 mux
->limit_filesize
= o
->limit_filesize
;
3356 av_dict_copy(&mux
->opts
, o
->g
->format_opts
, 0);
3358 if (!strcmp(filename
, "-"))
3361 err
= avformat_alloc_output_context2(&oc
, NULL
, o
->format
, filename
);
3363 av_log(mux
, AV_LOG_FATAL
, "Error initializing the muxer for %s: %s\n",
3364 filename
, av_err2str(err
));
3369 av_strlcat(mux
->log_name
, "/", sizeof(mux
->log_name
));
3370 av_strlcat(mux
->log_name
, oc
->oformat
->name
, sizeof(mux
->log_name
));
3373 if (recording_time
!= INT64_MAX
)
3374 oc
->duration
= recording_time
;
3376 oc
->interrupt_callback
= int_cb
;
3379 oc
->flags
|= AVFMT_FLAG_BITEXACT
;
3382 of
->bitexact
= check_opt_bitexact(oc
, mux
->opts
, "fflags",
3383 AVFMT_FLAG_BITEXACT
);
3386 err
= sch_add_mux(sch
, muxer_thread
, mux_check_init
, mux
,
3387 !strcmp(oc
->oformat
->name
, "rtp"), o
->thread_queue_size
);
3393 /* create all output streams for this file */
3394 err
= create_streams(mux
, o
);
3398 /* check if all codec options have been used */
3399 err
= check_avoptions_used(o
->g
->codec_opts
, mux
->enc_opts_used
, mux
, 0);
3400 av_dict_free(&mux
->enc_opts_used
);
3404 /* check filename in case of an image number is expected */
3405 if (oc
->oformat
->flags
& AVFMT_NEEDNUMBER
&& !av_filename_number_test(oc
->url
)) {
3406 av_log(mux
, AV_LOG_FATAL
,
3407 "Output filename '%s' does not contain a numeric pattern like "
3408 "'%%d', which is required by output format '%s'.\n",
3409 oc
->url
, oc
->oformat
->name
);
3410 return AVERROR(EINVAL
);
3413 if (!(oc
->oformat
->flags
& AVFMT_NOFILE
)) {
3414 /* test if it already exists to avoid losing precious files */
3415 err
= assert_file_overwrite(filename
);
3420 if ((err
= avio_open2(&oc
->pb
, filename
, AVIO_FLAG_WRITE
,
3421 &oc
->interrupt_callback
,
3423 av_log(mux
, AV_LOG_FATAL
, "Error opening output %s: %s\n",
3424 filename
, av_err2str(err
));
3427 } else if (strcmp(oc
->oformat
->name
, "image2")==0 && !av_filename_number_test(filename
)) {
3428 err
= assert_file_overwrite(filename
);
3433 if (o
->mux_preload
) {
3434 av_dict_set_int(&mux
->opts
, "preload", o
->mux_preload
*AV_TIME_BASE
, 0);
3436 oc
->max_delay
= (int)(o
->mux_max_delay
* AV_TIME_BASE
);
3438 /* copy metadata and chapters from input files */
3439 err
= copy_meta(mux
, o
);
3443 err
= of_add_groups(mux
, o
);
3447 err
= of_add_programs(mux
, o
);
3451 err
= of_add_metadata(of
, oc
, o
);
3455 err
= set_dispositions(mux
, o
);
3457 av_log(mux
, AV_LOG_FATAL
, "Error setting output stream dispositions\n");
3461 // parse forced keyframe specifications;
3462 // must be done after chapters are created
3463 err
= process_forced_keyframes(mux
, o
);
3465 av_log(mux
, AV_LOG_FATAL
, "Error processing forced keyframes\n");
3469 err
= setup_sync_queues(mux
, oc
, o
->shortest_buf_duration
* AV_TIME_BASE
,
3472 av_log(mux
, AV_LOG_FATAL
, "Error setting up output sync queues\n");
3478 /* initialize streamcopy streams. */
3479 for (int i
= 0; i
< of
->nb_streams
; i
++) {
3480 OutputStream
*ost
= of
->streams
[i
];
3483 err
= of_stream_init(of
, ost
, NULL
);