FFmpegKit Android API 6.0
Loading...
Searching...
No Matches
fftools_ffmpeg_mux_init.c
Go to the documentation of this file.
1/*
2 * Muxer/output file setup.
3 * Copyright (c) 2023 ARTHENICA LTD
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/*
23 * This file is the modified version of ffmpeg_mux_init.c file living in ffmpeg source code under the fftools folder. We
24 * manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
25 * by us to develop ffmpeg-kit library.
26 *
27 * ffmpeg-kit changes by ARTHENICA LTD
28 *
29 * 07.2023
30 * --------------------------------------------------------
31 * - FFmpeg 6.0 changes migrated
32 * - fftools header names updated
33 * - EncStatsFile declaration migrated to ffmpeg_mux.h
34 * - extern ms_from_ost added
35 * - "class" member field renamed as clazz
36 */
37
38#include <string.h>
39
40#include "fftools_cmdutils.h"
41#include "fftools_ffmpeg.h"
42#include "fftools_ffmpeg_mux.h"
43#include "fftools_fopen_utf8.h"
44
45#include "libavformat/avformat.h"
46#include "libavformat/avio.h"
47
48#include "libavcodec/avcodec.h"
49
50#include "libavfilter/avfilter.h"
51
52#include "libavutil/avassert.h"
53#include "libavutil/avstring.h"
54#include "libavutil/avutil.h"
55#include "libavutil/bprint.h"
56#include "libavutil/dict.h"
57#include "libavutil/getenv_utf8.h"
58#include "libavutil/intreadwrite.h"
59#include "libavutil/log.h"
60#include "libavutil/mem.h"
61#include "libavutil/opt.h"
62#include "libavutil/parseutils.h"
63#include "libavutil/pixdesc.h"
64
65#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
66
67static const char *const opt_name_apad[] = {"apad", NULL};
68static const char *const opt_name_autoscale[] = {"autoscale", NULL};
69static const char *const opt_name_bits_per_raw_sample[] = {"bits_per_raw_sample", NULL};
70static const char *const opt_name_bitstream_filters[] = {"bsf", "absf", "vbsf", NULL};
71static const char *const opt_name_copy_initial_nonkeyframes[] = {"copyinkf", NULL};
72static const char *const opt_name_copy_prior_start[] = {"copypriorss", NULL};
73static const char *const opt_name_disposition[] = {"disposition", NULL};
74static const char *const opt_name_enc_time_bases[] = {"enc_time_base", NULL};
75static const char *const opt_name_enc_stats_pre[] = {"enc_stats_pre", NULL};
76static const char *const opt_name_enc_stats_post[] = {"enc_stats_post", NULL};
77static const char *const opt_name_mux_stats[] = {"mux_stats", NULL};
78static const char *const opt_name_enc_stats_pre_fmt[] = {"enc_stats_pre_fmt", NULL};
79static const char *const opt_name_enc_stats_post_fmt[] = {"enc_stats_post_fmt", NULL};
80static const char *const opt_name_mux_stats_fmt[] = {"mux_stats_fmt", NULL};
81static const char *const opt_name_filters[] = {"filter", "af", "vf", NULL};
82static const char *const opt_name_filter_scripts[] = {"filter_script", NULL};
83static const char *const opt_name_fix_sub_duration_heartbeat[] = {"fix_sub_duration_heartbeat", NULL};
84static const char *const opt_name_fps_mode[] = {"fps_mode", NULL};
85static const char *const opt_name_force_fps[] = {"force_fps", NULL};
86static const char *const opt_name_forced_key_frames[] = {"forced_key_frames", NULL};
87static const char *const opt_name_frame_aspect_ratios[] = {"aspect", NULL};
88static const char *const opt_name_intra_matrices[] = {"intra_matrix", NULL};
89static const char *const opt_name_inter_matrices[] = {"inter_matrix", NULL};
90static const char *const opt_name_chroma_intra_matrices[] = {"chroma_intra_matrix", NULL};
91static const char *const opt_name_max_frame_rates[] = {"fpsmax", NULL};
92static const char *const opt_name_max_frames[] = {"frames", "aframes", "vframes", "dframes", NULL};
93static const char *const opt_name_max_muxing_queue_size[] = {"max_muxing_queue_size", NULL};
94static const char *const opt_name_muxing_queue_data_threshold[] = {"muxing_queue_data_threshold", NULL};
95static const char *const opt_name_pass[] = {"pass", NULL};
96static const char *const opt_name_passlogfiles[] = {"passlogfile", NULL};
97static const char *const opt_name_presets[] = {"pre", "apre", "vpre", "spre", NULL};
98static const char *const opt_name_qscale[] = {"q", "qscale", NULL};
99static const char *const opt_name_rc_overrides[] = {"rc_override", NULL};
100static const char *const opt_name_time_bases[] = {"time_base", NULL};
101static const char *const opt_name_audio_channels[] = {"ac", NULL};
102static const char *const opt_name_audio_ch_layouts[] = {"channel_layout", "ch_layout", NULL};
103static const char *const opt_name_audio_sample_rate[] = {"ar", NULL};
104static const char *const opt_name_frame_sizes[] = {"s", NULL};
105static const char *const opt_name_frame_pix_fmts[] = {"pix_fmt", NULL};
106static const char *const opt_name_sample_fmts[] = {"sample_fmt", NULL};
107
109
110static int check_opt_bitexact(void *ctx, const AVDictionary *opts,
111 const char *opt_name, int flag)
112{
113 const AVDictionaryEntry *e = av_dict_get(opts, opt_name, NULL, 0);
114
115 if (e) {
116 const AVOption *o = av_opt_find(ctx, opt_name, NULL, 0, 0);
117 int val = 0;
118 if (!o)
119 return 0;
120 av_opt_eval_flags(ctx, o, e->value, &val);
121 return !!(val & flag);
122 }
123 return 0;
124}
125
126static int choose_encoder(const OptionsContext *o, AVFormatContext *s,
127 OutputStream *ost, const AVCodec **enc)
128{
129 enum AVMediaType type = ost->st->codecpar->codec_type;
130 char *codec_name = NULL;
131
132 *enc = NULL;
133
134 if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) {
135 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
136 if (!codec_name) {
137 ost->st->codecpar->codec_id = av_guess_codec(s->oformat, NULL, s->url,
138 NULL, ost->st->codecpar->codec_type);
139 *enc = avcodec_find_encoder(ost->st->codecpar->codec_id);
140 if (!*enc) {
141 av_log(ost, AV_LOG_FATAL, "Automatic encoder selection failed "
142 "Default encoder for format %s (codec %s) is "
143 "probably disabled. Please choose an encoder manually.\n",
144 s->oformat->name, avcodec_get_name(ost->st->codecpar->codec_id));
145 return AVERROR_ENCODER_NOT_FOUND;
146 }
147 } else if (strcmp(codec_name, "copy")) {
148 *enc = find_codec_or_die(ost, codec_name, ost->st->codecpar->codec_type, 1);
149 ost->st->codecpar->codec_id = (*enc)->id;
150 }
151 }
152
153 return 0;
154}
155
156static char *get_line(AVIOContext *s, AVBPrint *bprint)
157{
158 char c;
159
160 while ((c = avio_r8(s)) && c != '\n')
161 av_bprint_chars(bprint, c, 1);
162
163 if (!av_bprint_is_complete(bprint))
164 report_and_exit(AVERROR(ENOMEM));
165 return bprint->str;
166}
167
168static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
169{
170 int i, ret = -1;
171 char filename[1000];
172 char *env_avconv_datadir = getenv_utf8("AVCONV_DATADIR");
173 char *env_home = getenv_utf8("HOME");
174 const char *base[3] = { env_avconv_datadir,
175 env_home,
176 AVCONV_DATADIR,
177 };
178
179 for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) {
180 if (!base[i])
181 continue;
182 if (codec_name) {
183 snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
184 i != 1 ? "" : "/.avconv", codec_name, preset_name);
185 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
186 }
187 if (ret < 0) {
188 snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
189 i != 1 ? "" : "/.avconv", preset_name);
190 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
191 }
192 }
193 freeenv_utf8(env_home);
194 freeenv_utf8(env_avconv_datadir);
195 return ret;
196}
197
200
201static int enc_stats_get_file(AVIOContext **io, const char *path)
202{
203 EncStatsFile *esf;
204 int ret;
205
206 for (int i = 0; i < nb_enc_stats_files; i++)
207 if (!strcmp(path, enc_stats_files[i].path)) {
208 *io = enc_stats_files[i].io;
209 return 0;
210 }
211
213
215
216 ret = avio_open2(&esf->io, path, AVIO_FLAG_WRITE, &int_cb, NULL);
217 if (ret < 0) {
218 av_log(NULL, AV_LOG_ERROR, "Error opening stats file '%s': %s\n",
219 path, av_err2str(ret));
220 return ret;
221 }
222
223 esf->path = av_strdup(path);
224 if (!esf->path)
225 return AVERROR(ENOMEM);
226
227 *io = esf->io;
228
229 return 0;
230}
231
233{
234 for (int i = 0; i < nb_enc_stats_files; i++) {
235 av_freep(&enc_stats_files[i].path);
236 avio_closep(&enc_stats_files[i].io);
237 }
238 av_freep(&enc_stats_files);
240}
241
242static int unescape(char **pdst, size_t *dst_len,
243 const char **pstr, char delim)
244{
245 const char *str = *pstr;
246 char *dst;
247 size_t len, idx;
248
249 *pdst = NULL;
250
251 len = strlen(str);
252 if (!len)
253 return 0;
254
255 dst = av_malloc(len + 1);
256 if (!dst)
257 return AVERROR(ENOMEM);
258
259 for (idx = 0; *str; idx++, str++) {
260 if (str[0] == '\\' && str[1])
261 str++;
262 else if (*str == delim)
263 break;
264
265 dst[idx] = *str;
266 }
267 if (!idx) {
268 av_freep(&dst);
269 return 0;
270 }
271
272 dst[idx] = 0;
273
274 *pdst = dst;
275 *dst_len = idx;
276 *pstr = str;
277
278 return 0;
279}
280
281static int enc_stats_init(OutputStream *ost, EncStats *es, int pre,
282 const char *path, const char *fmt_spec)
283{
284 static const struct {
285 enum EncStatsType type;
286 const char *str;
287 int pre_only:1;
288 int post_only:1;
289 int need_input_data:1;
290 } fmt_specs[] = {
291 { ENC_STATS_FILE_IDX, "fidx" },
292 { ENC_STATS_STREAM_IDX, "sidx" },
293 { ENC_STATS_FRAME_NUM, "n" },
294 { ENC_STATS_FRAME_NUM_IN, "ni", 0, 0, 1 },
295 { ENC_STATS_TIMEBASE, "tb" },
296 { ENC_STATS_TIMEBASE_IN, "tbi", 0, 0, 1 },
297 { ENC_STATS_PTS, "pts" },
298 { ENC_STATS_PTS_TIME, "t" },
299 { ENC_STATS_PTS_IN, "ptsi", 0, 0, 1 },
300 { ENC_STATS_PTS_TIME_IN, "ti", 0, 0, 1 },
301 { ENC_STATS_DTS, "dts", 0, 1 },
302 { ENC_STATS_DTS_TIME, "dt", 0, 1 },
303 { ENC_STATS_SAMPLE_NUM, "sn", 1 },
304 { ENC_STATS_NB_SAMPLES, "samp", 1 },
305 { ENC_STATS_PKT_SIZE, "size", 0, 1 },
306 { ENC_STATS_BITRATE, "br", 0, 1 },
307 { ENC_STATS_AVG_BITRATE, "abr", 0, 1 },
308 };
309 const char *next = fmt_spec;
310
311 int ret;
312
313 while (*next) {
315 char *val;
316 size_t val_len;
317
318 // get the sequence up until next opening brace
319 ret = unescape(&val, &val_len, &next, '{');
320 if (ret < 0)
321 return ret;
322
323 if (val) {
325
326 c = &es->components[es->nb_components - 1];
328 c->str = val;
329 c->str_len = val_len;
330 }
331
332 if (!*next)
333 break;
334 next++;
335
336 // get the part inside braces
337 ret = unescape(&val, &val_len, &next, '}');
338 if (ret < 0)
339 return ret;
340
341 if (!val) {
342 av_log(NULL, AV_LOG_ERROR,
343 "Empty formatting directive in: %s\n", fmt_spec);
344 return AVERROR(EINVAL);
345 }
346
347 if (!*next) {
348 av_log(NULL, AV_LOG_ERROR,
349 "Missing closing brace in: %s\n", fmt_spec);
350 ret = AVERROR(EINVAL);
351 goto fail;
352 }
353 next++;
354
356 c = &es->components[es->nb_components - 1];
357
358 for (size_t i = 0; i < FF_ARRAY_ELEMS(fmt_specs); i++) {
359 if (!strcmp(val, fmt_specs[i].str)) {
360 if ((pre && fmt_specs[i].post_only) || (!pre && fmt_specs[i].pre_only)) {
361 av_log(NULL, AV_LOG_ERROR,
362 "Format directive '%s' may only be used %s-encoding\n",
363 val, pre ? "post" : "pre");
364 ret = AVERROR(EINVAL);
365 goto fail;
366 }
367
368 c->type = fmt_specs[i].type;
369
370 if (fmt_specs[i].need_input_data) {
371 if (ost->ist)
372 ost->ist->want_frame_data = 1;
373 else {
374 av_log(ost, AV_LOG_WARNING,
375 "Format directive '%s' is unavailable, because "
376 "this output stream has no associated input stream\n",
377 val);
378 }
379 }
380
381 break;
382 }
383 }
384
385 if (!c->type) {
386 av_log(NULL, AV_LOG_ERROR, "Invalid format directive: %s\n", val);
387 ret = AVERROR(EINVAL);
388 goto fail;
389 }
390
391fail:
392 av_freep(&val);
393 if (ret < 0)
394 return ret;
395 }
396
397 ret = enc_stats_get_file(&es->io, path);
398 if (ret < 0)
399 return ret;
400
401 return 0;
402}
403
404static const char *output_stream_item_name(void *obj)
405{
406 const MuxStream *ms = obj;
407
408 return ms->log_name;
409}
410
411static const AVClass output_stream_class = {
412 .class_name = "OutputStream",
413 .version = LIBAVUTIL_VERSION_INT,
414 .item_name = output_stream_item_name,
415 .category = AV_CLASS_CATEGORY_MUXER,
416};
417
418static MuxStream *mux_stream_alloc(Muxer *mux, enum AVMediaType type)
419{
420 const char *type_str = av_get_media_type_string(type);
421 MuxStream *ms = allocate_array_elem(&mux->of.streams, sizeof(*ms),
422 &mux->of.nb_streams);
423
424 ms->ost.file_index = mux->of.index;
425 ms->ost.index = mux->of.nb_streams - 1;
426
428
429 snprintf(ms->log_name, sizeof(ms->log_name), "%cost#%d:%d",
430 type_str ? *type_str : '?', mux->of.index, ms->ost.index);
431
432 return ms;
433}
434
436 enum AVMediaType type, InputStream *ist)
437{
438 AVFormatContext *oc = mux->fc;
439 MuxStream *ms;
440 OutputStream *ost;
441 const AVCodec *enc;
442 AVStream *st = avformat_new_stream(oc, NULL);
443 int ret = 0;
444 const char *bsfs = NULL, *time_base = NULL;
445 char *next, *codec_tag = NULL;
446 double qscale = -1;
447 int i;
448
449 if (!st)
450 report_and_exit(AVERROR(ENOMEM));
451
452 if (oc->nb_streams - 1 < o->nb_streamid_map)
453 st->id = o->streamid_map[oc->nb_streams - 1];
454
455 ms = mux_stream_alloc(mux, type);
456 ost = &ms->ost;
457
458 ms->muxing_queue = av_fifo_alloc2(8, sizeof(AVPacket*), 0);
459 if (!ms->muxing_queue)
460 report_and_exit(AVERROR(ENOMEM));
461 ms->last_mux_dts = AV_NOPTS_VALUE;
462
463 ost->st = st;
464 ost->ist = ist;
465 ost->kf.ref_pts = AV_NOPTS_VALUE;
466 st->codecpar->codec_type = type;
467
468 ret = choose_encoder(o, oc, ost, &enc);
469 if (ret < 0) {
470 av_log(ost, AV_LOG_FATAL, "Error selecting an encoder\n");
471 exit_program(1);
472 }
473
474 if (enc) {
475 ost->enc_ctx = avcodec_alloc_context3(enc);
476 if (!ost->enc_ctx)
477 report_and_exit(AVERROR(ENOMEM));
478
479 av_strlcat(ms->log_name, "/", sizeof(ms->log_name));
480 av_strlcat(ms->log_name, enc->name, sizeof(ms->log_name));
481 } else {
482 av_strlcat(ms->log_name, "/copy", sizeof(ms->log_name));
483 }
484
485 ost->filtered_frame = av_frame_alloc();
486 if (!ost->filtered_frame)
487 report_and_exit(AVERROR(ENOMEM));
488
489 ost->pkt = av_packet_alloc();
490 if (!ost->pkt)
491 report_and_exit(AVERROR(ENOMEM));
492
493 if (ost->enc_ctx) {
494 AVCodecContext *enc = ost->enc_ctx;
495 AVIOContext *s = NULL;
496 char *buf = NULL, *arg = NULL, *preset = NULL;
497 const char *enc_stats_pre = NULL, *enc_stats_post = NULL, *mux_stats = NULL;
498
499 ost->encoder_opts = filter_codec_opts(o->g->codec_opts, enc->codec_id,
500 oc, st, enc->codec);
501
502 MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
503 ost->autoscale = 1;
504 MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st);
505 if (preset && (!(ret = get_preset_file_2(preset, enc->codec->name, &s)))) {
506 AVBPrint bprint;
507 av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
508 do {
509 av_bprint_clear(&bprint);
510 buf = get_line(s, &bprint);
511 if (!buf[0] || buf[0] == '#')
512 continue;
513 if (!(arg = strchr(buf, '='))) {
514 av_log(ost, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
515 exit_program(1);
516 }
517 *arg++ = 0;
518 av_dict_set(&ost->encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE);
519 } while (!s->eof_reached);
520 av_bprint_finalize(&bprint, NULL);
521 avio_closep(&s);
522 }
523 if (ret) {
524 av_log(ost, AV_LOG_FATAL,
525 "Preset %s specified, but could not be opened.\n", preset);
526 exit_program(1);
527 }
528
529 MATCH_PER_STREAM_OPT(enc_stats_pre, str, enc_stats_pre, oc, st);
530 if (enc_stats_pre &&
531 (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
532 const char *format = "{fidx} {sidx} {n} {t}";
533
534 MATCH_PER_STREAM_OPT(enc_stats_pre_fmt, str, format, oc, st);
535
536 ret = enc_stats_init(ost, &ost->enc_stats_pre, 1, enc_stats_pre, format);
537 if (ret < 0)
538 exit_program(1);
539 }
540
541 MATCH_PER_STREAM_OPT(enc_stats_post, str, enc_stats_post, oc, st);
542 if (enc_stats_post &&
543 (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
544 const char *format = "{fidx} {sidx} {n} {t}";
545
546 MATCH_PER_STREAM_OPT(enc_stats_post_fmt, str, format, oc, st);
547
548 ret = enc_stats_init(ost, &ost->enc_stats_post, 0, enc_stats_post, format);
549 if (ret < 0)
550 exit_program(1);
551 }
552
553 MATCH_PER_STREAM_OPT(mux_stats, str, mux_stats, oc, st);
554 if (mux_stats &&
555 (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
556 const char *format = "{fidx} {sidx} {n} {t}";
557
558 MATCH_PER_STREAM_OPT(mux_stats_fmt, str, format, oc, st);
559
560 ret = enc_stats_init(ost, &ms->stats, 0, mux_stats, format);
561 if (ret < 0)
562 exit_program(1);
563 }
564 } else {
565 ost->encoder_opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
566 }
567
568
569 if (o->bitexact) {
570 ost->bitexact = 1;
571 } else if (ost->enc_ctx) {
572 ost->bitexact = check_opt_bitexact(ost->enc_ctx, ost->encoder_opts, "flags",
573 AV_CODEC_FLAG_BITEXACT);
574 }
575
576 MATCH_PER_STREAM_OPT(time_bases, str, time_base, oc, st);
577 if (time_base) {
578 AVRational q;
579 if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
580 q.num <= 0 || q.den <= 0) {
581 av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
582 exit_program(1);
583 }
584 st->time_base = q;
585 }
586
587 MATCH_PER_STREAM_OPT(enc_time_bases, str, time_base, oc, st);
588 if (time_base) {
589 AVRational q;
590 if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
591 q.den <= 0) {
592 av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
593 exit_program(1);
594 }
595 ost->enc_timebase = q;
596 }
597
598 ms->max_frames = INT64_MAX;
599 MATCH_PER_STREAM_OPT(max_frames, i64, ms->max_frames, oc, st);
600 for (i = 0; i<o->nb_max_frames; i++) {
601 char *p = o->max_frames[i].specifier;
602 if (!*p && type != AVMEDIA_TYPE_VIDEO) {
603 av_log(ost, AV_LOG_WARNING, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n");
604 break;
605 }
606 }
607
608 ost->copy_prior_start = -1;
609 MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st);
610
611 MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st);
612 if (bsfs && *bsfs) {
613 ret = av_bsf_list_parse_str(bsfs, &ms->bsf_ctx);
614 if (ret < 0) {
615 av_log(ost, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret));
616 exit_program(1);
617 }
618 }
619
620 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
621 if (codec_tag) {
622 uint32_t tag = strtol(codec_tag, &next, 0);
623 if (*next)
624 tag = AV_RL32(codec_tag);
625 ost->st->codecpar->codec_tag = tag;
626 if (ost->enc_ctx)
627 ost->enc_ctx->codec_tag = tag;
628 }
629
630 MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
631 if (ost->enc_ctx && qscale >= 0) {
632 ost->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE;
633 ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale;
634 }
635
636 ms->max_muxing_queue_size = 128;
637 MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, ms->max_muxing_queue_size, oc, st);
638
639 ms->muxing_queue_data_threshold = 50*1024*1024;
640 MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, ms->muxing_queue_data_threshold, oc, st);
641
642 MATCH_PER_STREAM_OPT(bits_per_raw_sample, i, ost->bits_per_raw_sample,
643 oc, st);
644
646 oc, st);
647
648 if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->enc_ctx)
649 ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
650
651 av_dict_copy(&ost->sws_dict, o->g->sws_dict, 0);
652
653 av_dict_copy(&ost->swr_opts, o->g->swr_opts, 0);
654 if (ost->enc_ctx && av_get_exact_bits_per_sample(ost->enc_ctx->codec_id) == 24)
655 av_dict_set(&ost->swr_opts, "output_sample_bits", "24", 0);
656
657 if (ost->ist) {
658 ost->ist->discard = 0;
659 ost->ist->st->discard = ost->ist->user_set_discard;
660 }
661 ost->last_mux_dts = AV_NOPTS_VALUE;
662 ost->last_filter_pts = AV_NOPTS_VALUE;
663
664 MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i,
665 ost->copy_initial_nonkeyframes, oc, st);
666
667 return ost;
668}
669
670static char *get_ost_filters(const OptionsContext *o, AVFormatContext *oc,
671 OutputStream *ost)
672{
673 AVStream *st = ost->st;
674
675 if (ost->filters_script && ost->filters) {
676 av_log(ost, AV_LOG_ERROR, "Both -filter and -filter_script set\n");
677 exit_program(1);
678 }
679
680 if (ost->filters_script)
681 return file_read(ost->filters_script);
682 else if (ost->filters)
683 return av_strdup(ost->filters);
684
685 return av_strdup(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ?
686 "null" : "anull");
687}
688
689static void check_streamcopy_filters(const OptionsContext *o, AVFormatContext *oc,
690 OutputStream *ost, enum AVMediaType type)
691{
692 if (ost->filters_script || ost->filters) {
693 av_log(ost, AV_LOG_ERROR,
694 "%s '%s' was defined, but codec copy was selected.\n"
695 "Filtering and streamcopy cannot be used together.\n",
696 ost->filters ? "Filtergraph" : "Filtergraph script",
697 ost->filters ? ost->filters : ost->filters_script);
698 exit_program(1);
699 }
700}
701
702static void parse_matrix_coeffs(void *logctx, uint16_t *dest, const char *str)
703{
704 int i;
705 const char *p = str;
706 for (i = 0;; i++) {
707 dest[i] = atoi(p);
708 if (i == 63)
709 break;
710 p = strchr(p, ',');
711 if (!p) {
712 av_log(logctx, AV_LOG_FATAL,
713 "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
714 exit_program(1);
715 }
716 p++;
717 }
718}
719
721{
722 AVFormatContext *oc = mux->fc;
723 AVStream *st;
724 OutputStream *ost;
725 char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL;
726
727 ost = new_output_stream(mux, o, AVMEDIA_TYPE_VIDEO, ist);
728 st = ost->st;
729
730 MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
731 if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
732 av_log(ost, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
733 exit_program(1);
734 }
735
736 MATCH_PER_STREAM_OPT(max_frame_rates, str, max_frame_rate, oc, st);
737 if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, max_frame_rate) < 0) {
738 av_log(ost, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate);
739 exit_program(1);
740 }
741
742 if (frame_rate && max_frame_rate) {
743 av_log(ost, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n");
744 exit_program(1);
745 }
746
747 MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
748 if (frame_aspect_ratio) {
749 AVRational q;
750 if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
751 q.num <= 0 || q.den <= 0) {
752 av_log(ost, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
753 exit_program(1);
754 }
755 ost->frame_aspect_ratio = q;
756 }
757
758 MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
759 MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
760
761 if (ost->enc_ctx) {
762 AVCodecContext *video_enc = ost->enc_ctx;
763 const char *p = NULL, *fps_mode = NULL;
764 char *frame_size = NULL;
765 char *frame_pix_fmt = NULL;
766 char *intra_matrix = NULL, *inter_matrix = NULL;
767 char *chroma_intra_matrix = NULL;
768 int do_pass = 0;
769 int i;
770
771 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
772 if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
773 av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
774 exit_program(1);
775 }
776
777 MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
778 if (frame_pix_fmt && *frame_pix_fmt == '+') {
779 ost->keep_pix_fmt = 1;
780 if (!*++frame_pix_fmt)
781 frame_pix_fmt = NULL;
782 }
783 if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
784 av_log(ost, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
785 exit_program(1);
786 }
787 st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
788
789 MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
790 if (intra_matrix) {
791 if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64)))
792 report_and_exit(AVERROR(ENOMEM));
793 parse_matrix_coeffs(ost, video_enc->intra_matrix, intra_matrix);
794 }
795 MATCH_PER_STREAM_OPT(chroma_intra_matrices, str, chroma_intra_matrix, oc, st);
796 if (chroma_intra_matrix) {
797 uint16_t *p = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64);
798 if (!p)
799 report_and_exit(AVERROR(ENOMEM));
800 video_enc->chroma_intra_matrix = p;
801 parse_matrix_coeffs(ost, p, chroma_intra_matrix);
802 }
803 MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
804 if (inter_matrix) {
805 if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64)))
806 report_and_exit(AVERROR(ENOMEM));
807 parse_matrix_coeffs(ost, video_enc->inter_matrix, inter_matrix);
808 }
809
810 MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
811 for (i = 0; p; i++) {
812 int start, end, q;
813 int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
814 if (e != 3) {
815 av_log(ost, AV_LOG_FATAL, "error parsing rc_override\n");
816 exit_program(1);
817 }
818 video_enc->rc_override =
819 av_realloc_array(video_enc->rc_override,
820 i + 1, sizeof(RcOverride));
821 if (!video_enc->rc_override) {
822 av_log(ost, AV_LOG_FATAL, "Could not (re)allocate memory for rc_override.\n");
823 exit_program(1);
824 }
825 video_enc->rc_override[i].start_frame = start;
826 video_enc->rc_override[i].end_frame = end;
827 if (q > 0) {
828 video_enc->rc_override[i].qscale = q;
829 video_enc->rc_override[i].quality_factor = 1.0;
830 }
831 else {
832 video_enc->rc_override[i].qscale = 0;
833 video_enc->rc_override[i].quality_factor = -q/100.0;
834 }
835 p = strchr(p, '/');
836 if (p) p++;
837 }
838 video_enc->rc_override_count = i;
839
840#if FFMPEG_OPT_PSNR
841 if (do_psnr) {
842 av_log(ost, AV_LOG_WARNING, "The -psnr option is deprecated, use -flags +psnr\n");
843 video_enc->flags|= AV_CODEC_FLAG_PSNR;
844 }
845#endif
846
847 /* two pass mode */
848 MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
849 if (do_pass) {
850 if (do_pass & 1) {
851 video_enc->flags |= AV_CODEC_FLAG_PASS1;
852 av_dict_set(&ost->encoder_opts, "flags", "+pass1", AV_DICT_APPEND);
853 }
854 if (do_pass & 2) {
855 video_enc->flags |= AV_CODEC_FLAG_PASS2;
856 av_dict_set(&ost->encoder_opts, "flags", "+pass2", AV_DICT_APPEND);
857 }
858 }
859
860 MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
861 if (ost->logfile_prefix &&
862 !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
863 report_and_exit(AVERROR(ENOMEM));
864
865 if (do_pass) {
866 int ost_idx = -1;
867 char logfilename[1024];
868 FILE *f;
869
870 /* compute this stream's global index */
871 for (int i = 0; i <= ost->file_index; i++)
872 ost_idx += output_files[i]->nb_streams;
873
874 snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
875 ost->logfile_prefix ? ost->logfile_prefix :
877 ost_idx);
878 if (!strcmp(ost->enc_ctx->codec->name, "libx264")) {
879 av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
880 } else {
881 if (video_enc->flags & AV_CODEC_FLAG_PASS2) {
882 char *logbuffer = file_read(logfilename);
883
884 if (!logbuffer) {
885 av_log(ost, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
886 logfilename);
887 exit_program(1);
888 }
889 video_enc->stats_in = logbuffer;
890 }
891 if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
892 f = fopen_utf8(logfilename, "wb");
893 if (!f) {
894 av_log(ost, AV_LOG_FATAL,
895 "Cannot write log file '%s' for pass-1 encoding: %s\n",
896 logfilename, strerror(errno));
897 exit_program(1);
898 }
899 ost->logfile = f;
900 }
901 }
902 }
903
904 MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
905
906 ost->top_field_first = -1;
907 MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
908
910 MATCH_PER_STREAM_OPT(fps_mode, str, fps_mode, oc, st);
911 if (fps_mode)
912 parse_and_set_vsync(fps_mode, &ost->vsync_method, ost->file_index, ost->index, 0);
913
914 if ((ost->frame_rate.num || ost->max_frame_rate.num) &&
915 !(ost->vsync_method == VSYNC_AUTO ||
916 ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR)) {
917 av_log(ost, AV_LOG_FATAL, "One of -r/-fpsmax was specified "
918 "together a non-CFR -vsync/-fps_mode. This is contradictory.\n");
919 exit_program(1);
920 }
921
922 if (ost->vsync_method == VSYNC_AUTO) {
923 if (ost->frame_rate.num || ost->max_frame_rate.num) {
924 ost->vsync_method = VSYNC_CFR;
925 } else if (!strcmp(oc->oformat->name, "avi")) {
926 ost->vsync_method = VSYNC_VFR;
927 } else {
928 ost->vsync_method = (oc->oformat->flags & AVFMT_VARIABLE_FPS) ?
929 ((oc->oformat->flags & AVFMT_NOTIMESTAMPS) ?
931 VSYNC_CFR;
932 }
933
934 if (ost->ist && ost->vsync_method == VSYNC_CFR) {
935 const InputFile *ifile = input_files[ost->ist->file_index];
936
937 if (ifile->nb_streams == 1 && ifile->input_ts_offset == 0)
939 }
940
941 if (ost->vsync_method == VSYNC_CFR && copy_ts) {
943 }
944 }
945 ost->is_cfr = (ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR);
946
947 ost->avfilter = get_ost_filters(o, oc, ost);
948 if (!ost->avfilter)
949 exit_program(1);
950
951 ost->last_frame = av_frame_alloc();
952 if (!ost->last_frame)
953 report_and_exit(AVERROR(ENOMEM));
954 } else
955 check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_VIDEO);
956
957 return ost;
958}
959
961{
962 AVFormatContext *oc = mux->fc;
963 AVStream *st;
964 OutputStream *ost;
965
966 ost = new_output_stream(mux, o, AVMEDIA_TYPE_AUDIO, ist);
967 st = ost->st;
968
969
970 MATCH_PER_STREAM_OPT(filter_scripts, str, ost->filters_script, oc, st);
971 MATCH_PER_STREAM_OPT(filters, str, ost->filters, oc, st);
972
973 if (ost->enc_ctx) {
974 AVCodecContext *audio_enc = ost->enc_ctx;
975 int channels = 0;
976 char *layout = NULL;
977 char *sample_fmt = NULL;
978
979 MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st);
980 if (channels) {
981 audio_enc->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
982 audio_enc->ch_layout.nb_channels = channels;
983 }
984
985 MATCH_PER_STREAM_OPT(audio_ch_layouts, str, layout, oc, st);
986 if (layout) {
987 if (av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) {
988#if FF_API_OLD_CHANNEL_LAYOUT
989 uint64_t mask;
990 AV_NOWARN_DEPRECATED({
991 mask = av_get_channel_layout(layout);
992 })
993 if (!mask) {
994#endif
995 av_log(ost, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout);
996 exit_program(1);
997#if FF_API_OLD_CHANNEL_LAYOUT
998 }
999 av_log(ost, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
1000 layout);
1001 av_channel_layout_from_mask(&audio_enc->ch_layout, mask);
1002#endif
1003 }
1004 }
1005
1006 MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
1007 if (sample_fmt &&
1008 (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
1009 av_log(ost, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
1010 exit_program(1);
1011 }
1012
1013 MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
1014
1015 MATCH_PER_STREAM_OPT(apad, str, ost->apad, oc, st);
1016 ost->apad = av_strdup(ost->apad);
1017
1018 ost->avfilter = get_ost_filters(o, oc, ost);
1019 if (!ost->avfilter)
1020 exit_program(1);
1021
1022#if FFMPEG_OPT_MAP_CHANNEL
1023 /* check for channel mapping for this audio stream */
1024 for (int n = 0; n < o->nb_audio_channel_maps; n++) {
1025 AudioChannelMap *map = &o->audio_channel_maps[n];
1026 if ((map->ofile_idx == -1 || ost->file_index == map->ofile_idx) &&
1027 (map->ostream_idx == -1 || ost->st->index == map->ostream_idx)) {
1028 InputStream *ist;
1029
1030 if (map->channel_idx == -1) {
1031 ist = NULL;
1032 } else if (!ost->ist) {
1033 av_log(ost, AV_LOG_FATAL, "Cannot determine input stream for channel mapping %d.%d\n",
1034 ost->file_index, ost->st->index);
1035 continue;
1036 } else {
1037 ist = ost->ist;
1038 }
1039
1040 if (!ist || (ist->file_index == map->file_idx && ist->st->index == map->stream_idx)) {
1041 if (av_reallocp_array(&ost->audio_channels_map,
1042 ost->audio_channels_mapped + 1,
1043 sizeof(*ost->audio_channels_map)
1044 ) < 0 )
1045 report_and_exit(AVERROR(ENOMEM));
1046
1048 }
1049 }
1050 }
1051#endif
1052 } else
1053 check_streamcopy_filters(o, oc, ost, AVMEDIA_TYPE_AUDIO);
1054
1055 return ost;
1056}
1057
1059{
1060 OutputStream *ost;
1061
1062 ost = new_output_stream(mux, o, AVMEDIA_TYPE_DATA, ist);
1063 if (ost->enc_ctx) {
1064 av_log(ost, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
1065 exit_program(1);
1066 }
1067
1068 return ost;
1069}
1070
1072{
1073 OutputStream *ost;
1074
1075 ost = new_output_stream(mux, o, AVMEDIA_TYPE_UNKNOWN, ist);
1076 if (ost->enc_ctx) {
1077 av_log(ost, AV_LOG_FATAL, "Unknown stream encoding not supported yet (only streamcopy)\n");
1078 exit_program(1);
1079 }
1080
1081 return ost;
1082}
1083
1085{
1086 OutputStream *ost = new_output_stream(mux, o, AVMEDIA_TYPE_ATTACHMENT, ist);
1087 ost->finished = 1;
1088 return ost;
1089}
1090
1092{
1093 AVStream *st;
1094 OutputStream *ost;
1095
1096 ost = new_output_stream(mux, o, AVMEDIA_TYPE_SUBTITLE, ist);
1097 st = ost->st;
1098
1099 if (ost->enc_ctx) {
1100 AVCodecContext *subtitle_enc = ost->enc_ctx;
1101 char *frame_size = NULL;
1102
1103 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, mux->fc, st);
1104 if (frame_size && av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size) < 0) {
1105 av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
1106 exit_program(1);
1107 }
1108 }
1109
1110 return ost;
1111}
1112
1113static void init_output_filter(OutputFilter *ofilter, const OptionsContext *o,
1114 Muxer *mux)
1115{
1116 OutputStream *ost;
1117
1118 switch (ofilter->type) {
1119 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(mux, o, NULL); break;
1120 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(mux, o, NULL); break;
1121 default:
1122 av_log(mux, AV_LOG_FATAL, "Only video and audio filters are supported "
1123 "currently.\n");
1124 exit_program(1);
1125 }
1126
1127 ost->filter = ofilter;
1128
1129 ofilter->ost = ost;
1130 ofilter->format = -1;
1131
1132 if (!ost->enc_ctx) {
1133 av_log(ost, AV_LOG_ERROR, "Streamcopy requested for output stream fed "
1134 "from a complex filtergraph. Filtering and streamcopy "
1135 "cannot be used together.\n");
1136 exit_program(1);
1137 }
1138
1139 if (ost->avfilter && (ost->filters || ost->filters_script)) {
1140 const char *opt = ost->filters ? "-vf/-af/-filter" : "-filter_script";
1141 av_log(ost, AV_LOG_ERROR,
1142 "%s '%s' was specified through the %s option "
1143 "for output stream %d:%d, which is fed from a complex filtergraph.\n"
1144 "%s and -filter_complex cannot be used together for the same stream.\n",
1145 ost->filters ? "Filtergraph" : "Filtergraph script",
1146 ost->filters ? ost->filters : ost->filters_script,
1147 opt, ost->file_index, ost->index, opt);
1148 exit_program(1);
1149 }
1150
1151 avfilter_inout_free(&ofilter->out_tmp);
1152}
1153
1154static void map_auto_video(Muxer *mux, const OptionsContext *o)
1155{
1156 AVFormatContext *oc = mux->fc;
1157 InputStream *best_ist = NULL;
1158 int best_score = 0;
1159 int qcr;
1160
1161 /* video: highest resolution */
1162 if (av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_VIDEO) == AV_CODEC_ID_NONE)
1163 return;
1164
1165 qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
1166 for (int j = 0; j < nb_input_files; j++) {
1167 InputFile *ifile = input_files[j];
1168 InputStream *file_best_ist = NULL;
1169 int file_best_score = 0;
1170 for (int i = 0; i < ifile->nb_streams; i++) {
1171 InputStream *ist = ifile->streams[i];
1172 int score;
1173
1174 if (ist->user_set_discard == AVDISCARD_ALL ||
1175 ist->st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
1176 continue;
1177
1178 score = ist->st->codecpar->width * ist->st->codecpar->height
1179 + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
1180 + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
1181 if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1182 score = 1;
1183
1184 if (score > file_best_score) {
1185 if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1186 continue;
1187 file_best_score = score;
1188 file_best_ist = ist;
1189 }
1190 }
1191 if (file_best_ist) {
1192 if((qcr == MKTAG('A', 'P', 'I', 'C')) ||
1193 !(file_best_ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1194 file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT);
1195 if (file_best_score > best_score) {
1196 best_score = file_best_score;
1197 best_ist = file_best_ist;
1198 }
1199 }
1200 }
1201 if (best_ist)
1202 new_video_stream(mux, o, best_ist);
1203}
1204
1205static void map_auto_audio(Muxer *mux, const OptionsContext *o)
1206{
1207 AVFormatContext *oc = mux->fc;
1208 InputStream *best_ist = NULL;
1209 int best_score = 0;
1210
1211 /* audio: most channels */
1212 if (av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_AUDIO) == AV_CODEC_ID_NONE)
1213 return;
1214
1215 for (int j = 0; j < nb_input_files; j++) {
1216 InputFile *ifile = input_files[j];
1217 InputStream *file_best_ist = NULL;
1218 int file_best_score = 0;
1219 for (int i = 0; i < ifile->nb_streams; i++) {
1220 InputStream *ist = ifile->streams[i];
1221 int score;
1222
1223 if (ist->user_set_discard == AVDISCARD_ALL ||
1224 ist->st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
1225 continue;
1226
1227 score = ist->st->codecpar->ch_layout.nb_channels
1228 + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
1229 + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
1230 if (score > file_best_score) {
1231 file_best_score = score;
1232 file_best_ist = ist;
1233 }
1234 }
1235 if (file_best_ist) {
1236 file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT);
1237 if (file_best_score > best_score) {
1238 best_score = file_best_score;
1239 best_ist = file_best_ist;
1240 }
1241 }
1242 }
1243 if (best_ist)
1244 new_audio_stream(mux, o, best_ist);
1245}
1246
1247static void map_auto_subtitle(Muxer *mux, const OptionsContext *o)
1248{
1249 AVFormatContext *oc = mux->fc;
1250 char *subtitle_codec_name = NULL;
1251
1252 /* subtitles: pick first */
1253 MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");
1254 if (!avcodec_find_encoder(oc->oformat->subtitle_codec) && !subtitle_codec_name)
1255 return;
1256
1257 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist))
1258 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1259 AVCodecDescriptor const *input_descriptor =
1260 avcodec_descriptor_get(ist->st->codecpar->codec_id);
1261 AVCodecDescriptor const *output_descriptor = NULL;
1262 AVCodec const *output_codec =
1263 avcodec_find_encoder(oc->oformat->subtitle_codec);
1264 int input_props = 0, output_props = 0;
1265 if (ist->user_set_discard == AVDISCARD_ALL)
1266 continue;
1267 if (output_codec)
1268 output_descriptor = avcodec_descriptor_get(output_codec->id);
1269 if (input_descriptor)
1270 input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
1271 if (output_descriptor)
1272 output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
1273 if (subtitle_codec_name ||
1274 input_props & output_props ||
1275 // Map dvb teletext which has neither property to any output subtitle encoder
1276 (input_descriptor && output_descriptor &&
1277 (!input_descriptor->props ||
1278 !output_descriptor->props))) {
1279 new_subtitle_stream(mux, o, ist);
1280 break;
1281 }
1282 }
1283}
1284
1285static void map_auto_data(Muxer *mux, const OptionsContext *o)
1286{
1287 AVFormatContext *oc = mux->fc;
1288 /* Data only if codec id match */
1289 enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_DATA);
1290
1291 if (codec_id == AV_CODEC_ID_NONE)
1292 return;
1293
1294 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
1295 if (ist->user_set_discard == AVDISCARD_ALL)
1296 continue;
1297 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA &&
1298 ist->st->codecpar->codec_id == codec_id )
1299 new_data_stream(mux, o, ist);
1300 }
1301}
1302
1303static void map_manual(Muxer *mux, const OptionsContext *o, const StreamMap *map)
1304{
1305 InputStream *ist;
1306
1307 if (map->disabled)
1308 return;
1309
1310 if (map->linklabel) {
1311 FilterGraph *fg;
1312 OutputFilter *ofilter = NULL;
1313 int j, k;
1314
1315 for (j = 0; j < nb_filtergraphs; j++) {
1316 fg = filtergraphs[j];
1317 for (k = 0; k < fg->nb_outputs; k++) {
1318 AVFilterInOut *out = fg->outputs[k]->out_tmp;
1319 if (out && !strcmp(out->name, map->linklabel)) {
1320 ofilter = fg->outputs[k];
1321 goto loop_end;
1322 }
1323 }
1324 }
1325loop_end:
1326 if (!ofilter) {
1327 av_log(mux, AV_LOG_FATAL, "Output with label '%s' does not exist "
1328 "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);
1329 exit_program(1);
1330 }
1331 init_output_filter(ofilter, o, mux);
1332 } else {
1333 ist = input_files[map->file_index]->streams[map->stream_index];
1334 if (ist->user_set_discard == AVDISCARD_ALL) {
1335 av_log(mux, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n",
1336 map->file_index, map->stream_index);
1337 exit_program(1);
1338 }
1339 if(o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
1340 return;
1341 if(o-> audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
1342 return;
1343 if(o-> video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
1344 return;
1345 if(o-> data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
1346 return;
1347
1348 switch (ist->st->codecpar->codec_type) {
1349 case AVMEDIA_TYPE_VIDEO: new_video_stream (mux, o, ist); break;
1350 case AVMEDIA_TYPE_AUDIO: new_audio_stream (mux, o, ist); break;
1351 case AVMEDIA_TYPE_SUBTITLE: new_subtitle_stream (mux, o, ist); break;
1352 case AVMEDIA_TYPE_DATA: new_data_stream (mux, o, ist); break;
1353 case AVMEDIA_TYPE_ATTACHMENT: new_attachment_stream(mux, o, ist); break;
1354 case AVMEDIA_TYPE_UNKNOWN:
1356 new_unknown_stream (mux, o, ist);
1357 break;
1358 }
1359 default:
1360 av_log(mux, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL,
1361 "Cannot map stream #%d:%d - unsupported type.\n",
1362 map->file_index, map->stream_index);
1364 av_log(mux, AV_LOG_FATAL,
1365 "If you want unsupported types ignored instead "
1366 "of failing, please use the -ignore_unknown option\n"
1367 "If you want them copied, please use -copy_unknown\n");
1368 exit_program(1);
1369 }
1370 }
1371 }
1372}
1373
1374static void of_add_attachments(Muxer *mux, const OptionsContext *o)
1375{
1376 OutputStream *ost;
1377 int err;
1378
1379 for (int i = 0; i < o->nb_attachments; i++) {
1380 AVIOContext *pb;
1381 uint8_t *attachment;
1382 const char *p;
1383 int64_t len;
1384
1385 if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
1386 av_log(mux, AV_LOG_FATAL, "Could not open attachment file %s.\n",
1387 o->attachments[i]);
1388 exit_program(1);
1389 }
1390 if ((len = avio_size(pb)) <= 0) {
1391 av_log(mux, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
1392 o->attachments[i]);
1393 exit_program(1);
1394 }
1395 if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ||
1396 !(attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE))) {
1397 av_log(mux, AV_LOG_FATAL, "Attachment %s too large.\n",
1398 o->attachments[i]);
1399 exit_program(1);
1400 }
1401 avio_read(pb, attachment, len);
1402 memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1403
1404 ost = new_attachment_stream(mux, o, NULL);
1405 ost->attachment_filename = o->attachments[i];
1406 ost->st->codecpar->extradata = attachment;
1407 ost->st->codecpar->extradata_size = len;
1408
1409 p = strrchr(o->attachments[i], '/');
1410 av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
1411 avio_closep(&pb);
1412 }
1413}
1414
1415static void create_streams(Muxer *mux, const OptionsContext *o)
1416{
1417 AVFormatContext *oc = mux->fc;
1418 int auto_disable_v = o->video_disable;
1419 int auto_disable_a = o->audio_disable;
1420 int auto_disable_s = o->subtitle_disable;
1421 int auto_disable_d = o->data_disable;
1422
1423 /* create streams for all unlabeled output pads */
1424 for (int i = 0; i < nb_filtergraphs; i++) {
1425 FilterGraph *fg = filtergraphs[i];
1426 for (int j = 0; j < fg->nb_outputs; j++) {
1427 OutputFilter *ofilter = fg->outputs[j];
1428
1429 if (!ofilter->out_tmp || ofilter->out_tmp->name)
1430 continue;
1431
1432 switch (ofilter->type) {
1433 case AVMEDIA_TYPE_VIDEO: auto_disable_v = 1; break;
1434 case AVMEDIA_TYPE_AUDIO: auto_disable_a = 1; break;
1435 case AVMEDIA_TYPE_SUBTITLE: auto_disable_s = 1; break;
1436 }
1437 init_output_filter(ofilter, o, mux);
1438 }
1439 }
1440
1441 if (!o->nb_stream_maps) {
1442 /* pick the "best" stream of each type */
1443 if (!auto_disable_v)
1444 map_auto_video(mux, o);
1445 if (!auto_disable_a)
1446 map_auto_audio(mux, o);
1447 if (!auto_disable_s)
1448 map_auto_subtitle(mux, o);
1449 if (!auto_disable_d)
1450 map_auto_data(mux, o);
1451 } else {
1452 for (int i = 0; i < o->nb_stream_maps; i++)
1453 map_manual(mux, o, &o->stream_maps[i]);
1454 }
1455
1456 of_add_attachments(mux, o);
1457
1458 if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
1459 av_dump_format(oc, nb_output_files - 1, oc->url, 1);
1460 av_log(mux, AV_LOG_ERROR, "Output file does not contain any stream\n");
1461 exit_program(1);
1462 }
1463}
1464
1465static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_us)
1466{
1467 OutputFile *of = &mux->of;
1468 int nb_av_enc = 0, nb_interleaved = 0;
1469 int limit_frames = 0, limit_frames_av_enc = 0;
1470
1471#define IS_AV_ENC(ost, type) \
1472 (ost->enc_ctx && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO))
1473#define IS_INTERLEAVED(type) (type != AVMEDIA_TYPE_ATTACHMENT)
1474
1475 for (int i = 0; i < oc->nb_streams; i++) {
1476 OutputStream *ost = of->streams[i];
1477 MuxStream *ms = ms_from_ost(ost);
1478 enum AVMediaType type = ost->st->codecpar->codec_type;
1479
1480 ost->sq_idx_encode = -1;
1481 ost->sq_idx_mux = -1;
1482
1483 nb_interleaved += IS_INTERLEAVED(type);
1484 nb_av_enc += IS_AV_ENC(ost, type);
1485
1486 limit_frames |= ms->max_frames < INT64_MAX;
1487 limit_frames_av_enc |= (ms->max_frames < INT64_MAX) && IS_AV_ENC(ost, type);
1488 }
1489
1490 if (!((nb_interleaved > 1 && of->shortest) ||
1491 (nb_interleaved > 0 && limit_frames)))
1492 return 0;
1493
1494 /* if we have more than one encoded audio/video streams, or at least
1495 * one encoded audio/video stream is frame-limited, then we
1496 * synchronize them before encoding */
1497 if ((of->shortest && nb_av_enc > 1) || limit_frames_av_enc) {
1498 of->sq_encode = sq_alloc(SYNC_QUEUE_FRAMES, buf_size_us);
1499 if (!of->sq_encode)
1500 return AVERROR(ENOMEM);
1501
1502 for (int i = 0; i < oc->nb_streams; i++) {
1503 OutputStream *ost = of->streams[i];
1504 MuxStream *ms = ms_from_ost(ost);
1505 enum AVMediaType type = ost->st->codecpar->codec_type;
1506
1507 if (!IS_AV_ENC(ost, type))
1508 continue;
1509
1511 of->shortest || ms->max_frames < INT64_MAX);
1512 if (ost->sq_idx_encode < 0)
1513 return ost->sq_idx_encode;
1514
1515 ost->sq_frame = av_frame_alloc();
1516 if (!ost->sq_frame)
1517 return AVERROR(ENOMEM);
1518
1519 if (ms->max_frames != INT64_MAX)
1521 }
1522 }
1523
1524 /* if there are any additional interleaved streams, then ALL the streams
1525 * are also synchronized before sending them to the muxer */
1526 if (nb_interleaved > nb_av_enc) {
1527 mux->sq_mux = sq_alloc(SYNC_QUEUE_PACKETS, buf_size_us);
1528 if (!mux->sq_mux)
1529 return AVERROR(ENOMEM);
1530
1531 mux->sq_pkt = av_packet_alloc();
1532 if (!mux->sq_pkt)
1533 return AVERROR(ENOMEM);
1534
1535 for (int i = 0; i < oc->nb_streams; i++) {
1536 OutputStream *ost = of->streams[i];
1537 MuxStream *ms = ms_from_ost(ost);
1538 enum AVMediaType type = ost->st->codecpar->codec_type;
1539
1540 if (!IS_INTERLEAVED(type))
1541 continue;
1542
1543 ost->sq_idx_mux = sq_add_stream(mux->sq_mux,
1544 of->shortest || ms->max_frames < INT64_MAX);
1545 if (ost->sq_idx_mux < 0)
1546 return ost->sq_idx_mux;
1547
1548 if (ms->max_frames != INT64_MAX)
1550 }
1551 }
1552
1553#undef IS_AV_ENC
1554#undef IS_INTERLEAVED
1555
1556 return 0;
1557}
1558
1559static void of_add_programs(Muxer *mux, const OptionsContext *o)
1560{
1561 AVFormatContext *oc = mux->fc;
1562 /* process manually set programs */
1563 for (int i = 0; i < o->nb_program; i++) {
1564 const char *p = o->program[i].u.str;
1565 int progid = i+1;
1566 AVProgram *program;
1567
1568 while(*p) {
1569 const char *p2 = av_get_token(&p, ":");
1570 const char *to_dealloc = p2;
1571 char *key;
1572 if (!p2)
1573 break;
1574
1575 if(*p) p++;
1576
1577 key = av_get_token(&p2, "=");
1578 if (!key || !*p2) {
1579 av_freep(&to_dealloc);
1580 av_freep(&key);
1581 break;
1582 }
1583 p2++;
1584
1585 if (!strcmp(key, "program_num"))
1586 progid = strtol(p2, NULL, 0);
1587 av_freep(&to_dealloc);
1588 av_freep(&key);
1589 }
1590
1591 program = av_new_program(oc, progid);
1592 if (!program)
1593 report_and_exit(AVERROR(ENOMEM));
1594
1595 p = o->program[i].u.str;
1596 while(*p) {
1597 const char *p2 = av_get_token(&p, ":");
1598 const char *to_dealloc = p2;
1599 char *key;
1600 if (!p2)
1601 break;
1602 if(*p) p++;
1603
1604 key = av_get_token(&p2, "=");
1605 if (!key) {
1606 av_log(mux, AV_LOG_FATAL,
1607 "No '=' character in program string %s.\n",
1608 p2);
1609 exit_program(1);
1610 }
1611 if (!*p2)
1612 exit_program(1);
1613 p2++;
1614
1615 if (!strcmp(key, "title")) {
1616 av_dict_set(&program->metadata, "title", p2, 0);
1617 } else if (!strcmp(key, "program_num")) {
1618 } else if (!strcmp(key, "st")) {
1619 int st_num = strtol(p2, NULL, 0);
1620 av_program_add_stream_index(oc, progid, st_num);
1621 } else {
1622 av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", key);
1623 exit_program(1);
1624 }
1625 av_freep(&to_dealloc);
1626 av_freep(&key);
1627 }
1628 }
1629}
1630
1638static void parse_meta_type(void *logctx, const char *arg,
1639 char *type, int *index, const char **stream_spec)
1640{
1641 if (*arg) {
1642 *type = *arg;
1643 switch (*arg) {
1644 case 'g':
1645 break;
1646 case 's':
1647 if (*(++arg) && *arg != ':') {
1648 av_log(logctx, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
1649 exit_program(1);
1650 }
1651 *stream_spec = *arg == ':' ? arg + 1 : "";
1652 break;
1653 case 'c':
1654 case 'p':
1655 if (*(++arg) == ':')
1656 *index = strtol(++arg, NULL, 0);
1657 break;
1658 default:
1659 av_log(logctx, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
1660 exit_program(1);
1661 }
1662 } else
1663 *type = 'g';
1664}
1665
1666static void of_add_metadata(OutputFile *of, AVFormatContext *oc,
1667 const OptionsContext *o)
1668{
1669 for (int i = 0; i < o->nb_metadata; i++) {
1670 AVDictionary **m;
1671 char type, *val;
1672 const char *stream_spec;
1673 int index = 0, ret = 0;
1674
1675 val = strchr(o->metadata[i].u.str, '=');
1676 if (!val) {
1677 av_log(of, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
1678 o->metadata[i].u.str);
1679 exit_program(1);
1680 }
1681 *val++ = 0;
1682
1683 parse_meta_type(of, o->metadata[i].specifier, &type, &index, &stream_spec);
1684 if (type == 's') {
1685 for (int j = 0; j < oc->nb_streams; j++) {
1686 OutputStream *ost = of->streams[j];
1687 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
1688#if FFMPEG_ROTATION_METADATA
1689 if (!strcmp(o->metadata[i].u.str, "rotate")) {
1690 char *tail;
1691 double theta = av_strtod(val, &tail);
1692 if (!*tail) {
1693 ost->rotate_overridden = 1;
1694 ost->rotate_override_value = theta;
1695 }
1696
1697 av_log(ost, AV_LOG_WARNING,
1698 "Conversion of a 'rotate' metadata key to a "
1699 "proper display matrix rotation is deprecated. "
1700 "See -display_rotation for setting rotation "
1701 "instead.");
1702 } else {
1703#endif
1704 av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
1705#if FFMPEG_ROTATION_METADATA
1706 }
1707#endif
1708 } else if (ret < 0)
1709 exit_program(1);
1710 }
1711 } else {
1712 switch (type) {
1713 case 'g':
1714 m = &oc->metadata;
1715 break;
1716 case 'c':
1717 if (index < 0 || index >= oc->nb_chapters) {
1718 av_log(of, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
1719 exit_program(1);
1720 }
1721 m = &oc->chapters[index]->metadata;
1722 break;
1723 case 'p':
1724 if (index < 0 || index >= oc->nb_programs) {
1725 av_log(of, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index);
1726 exit_program(1);
1727 }
1728 m = &oc->programs[index]->metadata;
1729 break;
1730 default:
1731 av_log(of, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
1732 exit_program(1);
1733 }
1734 av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
1735 }
1736 }
1737}
1738
1740{
1741 const AVCodec *c = ost->enc_ctx->codec;
1742 int i, err;
1743
1744 if (ost->enc_ctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
1745 /* Pass the layout through for all orders but UNSPEC */
1746 err = av_channel_layout_copy(&f->ch_layout, &ost->enc_ctx->ch_layout);
1747 if (err < 0)
1748 report_and_exit(AVERROR(ENOMEM));
1749 return;
1750 }
1751
1752 /* Requested layout is of order UNSPEC */
1753 if (!c->ch_layouts) {
1754 /* Use the default native layout for the requested amount of channels when the
1755 encoder doesn't have a list of supported layouts */
1756 av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
1757 return;
1758 }
1759 /* Encoder has a list of supported layouts. Pick the first layout in it with the
1760 same amount of channels as the requested layout */
1761 for (i = 0; c->ch_layouts[i].nb_channels; i++) {
1762 if (c->ch_layouts[i].nb_channels == ost->enc_ctx->ch_layout.nb_channels)
1763 break;
1764 }
1765 if (c->ch_layouts[i].nb_channels) {
1766 /* Use it if one is found */
1767 err = av_channel_layout_copy(&f->ch_layout, &c->ch_layouts[i]);
1768 if (err < 0)
1769 report_and_exit(AVERROR(ENOMEM));
1770 return;
1771 }
1772 /* If no layout for the amount of channels requested was found, use the default
1773 native layout for it. */
1774 av_channel_layout_default(&f->ch_layout, ost->enc_ctx->ch_layout.nb_channels);
1775}
1776
1777static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *os,
1778 int copy_metadata)
1779{
1780 AVFormatContext *is = ifile->ctx;
1781 AVChapter **tmp;
1782 int i;
1783
1784 tmp = av_realloc_f(os->chapters, is->nb_chapters + os->nb_chapters, sizeof(*os->chapters));
1785 if (!tmp)
1786 return AVERROR(ENOMEM);
1787 os->chapters = tmp;
1788
1789 for (i = 0; i < is->nb_chapters; i++) {
1790 AVChapter *in_ch = is->chapters[i], *out_ch;
1791 int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
1792 int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
1793 AV_TIME_BASE_Q, in_ch->time_base);
1794 int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
1795 av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
1796
1797
1798 if (in_ch->end < ts_off)
1799 continue;
1800 if (rt != INT64_MAX && in_ch->start > rt + ts_off)
1801 break;
1802
1803 out_ch = av_mallocz(sizeof(AVChapter));
1804 if (!out_ch)
1805 return AVERROR(ENOMEM);
1806
1807 out_ch->id = in_ch->id;
1808 out_ch->time_base = in_ch->time_base;
1809 out_ch->start = FFMAX(0, in_ch->start - ts_off);
1810 out_ch->end = FFMIN(rt, in_ch->end - ts_off);
1811
1812 if (copy_metadata)
1813 av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
1814
1815 os->chapters[os->nb_chapters++] = out_ch;
1816 }
1817 return 0;
1818}
1819
1820static int copy_metadata(Muxer *mux, AVFormatContext *ic,
1821 const char *outspec, const char *inspec,
1822 int *metadata_global_manual, int *metadata_streams_manual,
1823 int *metadata_chapters_manual, const OptionsContext *o)
1824{
1825 AVFormatContext *oc = mux->fc;
1826 AVDictionary **meta_in = NULL;
1827 AVDictionary **meta_out = NULL;
1828 int i, ret = 0;
1829 char type_in, type_out;
1830 const char *istream_spec = NULL, *ostream_spec = NULL;
1831 int idx_in = 0, idx_out = 0;
1832
1833 parse_meta_type(mux, inspec, &type_in, &idx_in, &istream_spec);
1834 parse_meta_type(mux, outspec, &type_out, &idx_out, &ostream_spec);
1835
1836 if (type_in == 'g' || type_out == 'g')
1837 *metadata_global_manual = 1;
1838 if (type_in == 's' || type_out == 's')
1839 *metadata_streams_manual = 1;
1840 if (type_in == 'c' || type_out == 'c')
1841 *metadata_chapters_manual = 1;
1842
1843 /* ic is NULL when just disabling automatic mappings */
1844 if (!ic)
1845 return 0;
1846
1847#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
1848 if ((index) < 0 || (index) >= (nb_elems)) {\
1849 av_log(mux, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
1850 (desc), (index));\
1851 exit_program(1);\
1852 }
1853
1854#define SET_DICT(type, meta, context, index)\
1855 switch (type) {\
1856 case 'g':\
1857 meta = &context->metadata;\
1858 break;\
1859 case 'c':\
1860 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
1861 meta = &context->chapters[index]->metadata;\
1862 break;\
1863 case 'p':\
1864 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
1865 meta = &context->programs[index]->metadata;\
1866 break;\
1867 case 's':\
1868 break; /* handled separately below */ \
1869 default: av_assert0(0);\
1870 }\
1871
1872 SET_DICT(type_in, meta_in, ic, idx_in);
1873 SET_DICT(type_out, meta_out, oc, idx_out);
1874
1875 /* for input streams choose first matching stream */
1876 if (type_in == 's') {
1877 for (i = 0; i < ic->nb_streams; i++) {
1878 if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
1879 meta_in = &ic->streams[i]->metadata;
1880 break;
1881 } else if (ret < 0)
1882 exit_program(1);
1883 }
1884 if (!meta_in) {
1885 av_log(mux, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
1886 exit_program(1);
1887 }
1888 }
1889
1890 if (type_out == 's') {
1891 for (i = 0; i < oc->nb_streams; i++) {
1892 if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
1893 meta_out = &oc->streams[i]->metadata;
1894 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
1895 } else if (ret < 0)
1896 exit_program(1);
1897 }
1898 } else
1899 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
1900
1901 return 0;
1902}
1903
1904static void copy_meta(Muxer *mux, const OptionsContext *o)
1905{
1906 OutputFile *of = &mux->of;
1907 AVFormatContext *oc = mux->fc;
1908 int chapters_input_file = o->chapters_input_file;
1909 int metadata_global_manual = 0;
1910 int metadata_streams_manual = 0;
1911 int metadata_chapters_manual = 0;
1912
1913 /* copy metadata */
1914 for (int i = 0; i < o->nb_metadata_map; i++) {
1915 char *p;
1916 int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
1917
1918 if (in_file_index >= nb_input_files) {
1919 av_log(mux, AV_LOG_FATAL, "Invalid input file index %d while "
1920 "processing metadata maps\n", in_file_index);
1921 exit_program(1);
1922 }
1923 copy_metadata(mux,
1924 in_file_index >= 0 ? input_files[in_file_index]->ctx : NULL,
1925 o->metadata_map[i].specifier, *p ? p + 1 : p,
1926 &metadata_global_manual, &metadata_streams_manual,
1927 &metadata_chapters_manual, o);
1928 }
1929
1930 /* copy chapters */
1931 if (chapters_input_file >= nb_input_files) {
1932 if (chapters_input_file == INT_MAX) {
1933 /* copy chapters from the first input file that has them*/
1934 chapters_input_file = -1;
1935 for (int i = 0; i < nb_input_files; i++)
1936 if (input_files[i]->ctx->nb_chapters) {
1937 chapters_input_file = i;
1938 break;
1939 }
1940 } else {
1941 av_log(mux, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
1942 chapters_input_file);
1943 exit_program(1);
1944 }
1945 }
1946 if (chapters_input_file >= 0)
1947 copy_chapters(input_files[chapters_input_file], of, oc,
1948 !metadata_chapters_manual);
1949
1950 /* copy global metadata by default */
1951 if (!metadata_global_manual && nb_input_files){
1952 av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
1953 AV_DICT_DONT_OVERWRITE);
1954 if (of->recording_time != INT64_MAX)
1955 av_dict_set(&oc->metadata, "duration", NULL, 0);
1956 av_dict_set(&oc->metadata, "creation_time", NULL, 0);
1957 av_dict_set(&oc->metadata, "company_name", NULL, 0);
1958 av_dict_set(&oc->metadata, "product_name", NULL, 0);
1959 av_dict_set(&oc->metadata, "product_version", NULL, 0);
1960 }
1961 if (!metadata_streams_manual)
1962 for (int i = 0; i < of->nb_streams; i++) {
1963 OutputStream *ost = of->streams[i];
1964
1965 if (!ost->ist) /* this is true e.g. for attached files */
1966 continue;
1967 av_dict_copy(&ost->st->metadata, ost->ist->st->metadata, AV_DICT_DONT_OVERWRITE);
1968 if (ost->enc_ctx) {
1969 av_dict_set(&ost->st->metadata, "encoder", NULL, 0);
1970 }
1971 }
1972}
1973
1974static int set_dispositions(Muxer *mux, const OptionsContext *o)
1975{
1976 OutputFile *of = &mux->of;
1977 AVFormatContext *ctx = mux->fc;
1978
1979 int nb_streams[AVMEDIA_TYPE_NB] = { 0 };
1980 int have_default[AVMEDIA_TYPE_NB] = { 0 };
1981 int have_manual = 0;
1982 int ret = 0;
1983
1984 const char **dispositions;
1985
1986 dispositions = av_calloc(ctx->nb_streams, sizeof(*dispositions));
1987 if (!dispositions)
1988 return AVERROR(ENOMEM);
1989
1990 // first, copy the input dispositions
1991 for (int i = 0; i < ctx->nb_streams; i++) {
1992 OutputStream *ost = of->streams[i];
1993
1994 nb_streams[ost->st->codecpar->codec_type]++;
1995
1996 MATCH_PER_STREAM_OPT(disposition, str, dispositions[i], ctx, ost->st);
1997
1998 have_manual |= !!dispositions[i];
1999
2000 if (ost->ist) {
2001 ost->st->disposition = ost->ist->st->disposition;
2002
2003 if (ost->st->disposition & AV_DISPOSITION_DEFAULT)
2004 have_default[ost->st->codecpar->codec_type] = 1;
2005 }
2006 }
2007
2008 if (have_manual) {
2009 // process manually set dispositions - they override the above copy
2010 for (int i = 0; i < ctx->nb_streams; i++) {
2011 OutputStream *ost = of->streams[i];
2012 const char *disp = dispositions[i];
2013
2014 if (!disp)
2015 continue;
2016
2017 ret = av_opt_set(ost->st, "disposition", disp, 0);
2018 if (ret < 0)
2019 goto finish;
2020 }
2021 } else {
2022 // For each media type with more than one stream, find a suitable stream to
2023 // mark as default, unless one is already marked default.
2024 // "Suitable" means the first of that type, skipping attached pictures.
2025 for (int i = 0; i < ctx->nb_streams; i++) {
2026 OutputStream *ost = of->streams[i];
2027 enum AVMediaType type = ost->st->codecpar->codec_type;
2028
2029 if (nb_streams[type] < 2 || have_default[type] ||
2030 ost->st->disposition & AV_DISPOSITION_ATTACHED_PIC)
2031 continue;
2032
2033 ost->st->disposition |= AV_DISPOSITION_DEFAULT;
2034 have_default[type] = 1;
2035 }
2036 }
2037
2038finish:
2039 av_freep(&dispositions);
2040
2041 return ret;
2042}
2043
2044const char *const forced_keyframes_const_names[] = {
2045 "n",
2046 "n_forced",
2047 "prev_forced_n",
2048 "prev_forced_t",
2049 "t",
2050 NULL
2051};
2052
2053static int compare_int64(const void *a, const void *b)
2054{
2055 return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
2056}
2057
2059 const char *spec)
2060{
2061 const char *p;
2062 int n = 1, i, size, index = 0;
2063 int64_t t, *pts;
2064
2065 for (p = spec; *p; p++)
2066 if (*p == ',')
2067 n++;
2068 size = n;
2069 pts = av_malloc_array(size, sizeof(*pts));
2070 if (!pts)
2071 report_and_exit(AVERROR(ENOMEM));
2072
2073 p = spec;
2074 for (i = 0; i < n; i++) {
2075 char *next = strchr(p, ',');
2076
2077 if (next)
2078 *next++ = 0;
2079
2080 if (!memcmp(p, "chapters", 8)) {
2081 AVChapter * const *ch = mux->fc->chapters;
2082 unsigned int nb_ch = mux->fc->nb_chapters;
2083 int j;
2084
2085 if (nb_ch > INT_MAX - size ||
2086 !(pts = av_realloc_f(pts, size += nb_ch - 1,
2087 sizeof(*pts))))
2088 report_and_exit(AVERROR(ENOMEM));
2089 t = p[8] ? parse_time_or_die("force_key_frames", p + 8, 1) : 0;
2090
2091 for (j = 0; j < nb_ch; j++) {
2092 const AVChapter *c = ch[j];
2093 av_assert1(index < size);
2094 pts[index++] = av_rescale_q(c->start, c->time_base,
2095 AV_TIME_BASE_Q) + t;
2096 }
2097
2098 } else {
2099 av_assert1(index < size);
2100 pts[index++] = parse_time_or_die("force_key_frames", p, 1);
2101 }
2102
2103 p = next;
2104 }
2105
2106 av_assert0(index == size);
2107 qsort(pts, size, sizeof(*pts), compare_int64);
2108 kf->nb_pts = size;
2109 kf->pts = pts;
2110}
2111
2113{
2114 for (int i = 0; i < mux->of.nb_streams; i++) {
2115 OutputStream *ost = mux->of.streams[i];
2116 const char *forced_keyframes = NULL;
2117
2118 MATCH_PER_STREAM_OPT(forced_key_frames, str, forced_keyframes, mux->fc, ost->st);
2119
2120 if (!(ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
2121 ost->enc_ctx && forced_keyframes))
2122 continue;
2123
2124 if (!strncmp(forced_keyframes, "expr:", 5)) {
2125 int ret = av_expr_parse(&ost->kf.pexpr, forced_keyframes + 5,
2126 forced_keyframes_const_names, NULL, NULL, NULL, NULL, 0, NULL);
2127 if (ret < 0) {
2128 av_log(ost, AV_LOG_ERROR,
2129 "Invalid force_key_frames expression '%s'\n", forced_keyframes + 5);
2130 return ret;
2131 }
2132 ost->kf.expr_const_values[FKF_N] = 0;
2136
2137 // Don't parse the 'forced_keyframes' in case of 'keep-source-keyframes',
2138 // parse it only for static kf timings
2139 } else if (!strcmp(forced_keyframes, "source")) {
2140 ost->kf.type = KF_FORCE_SOURCE;
2141 } else if (!strcmp(forced_keyframes, "source_no_drop")) {
2143 } else {
2144 parse_forced_key_frames(&ost->kf, mux, forced_keyframes);
2145 }
2146 }
2147
2148 return 0;
2149}
2150
2151static void validate_enc_avopt(Muxer *mux, const AVDictionary *codec_avopt)
2152{
2153 const AVClass *class = avcodec_get_class();
2154 const AVClass *fclass = avformat_get_class();
2155 const OutputFile *of = &mux->of;
2156
2157 AVDictionary *unused_opts;
2158 const AVDictionaryEntry *e;
2159
2160 unused_opts = strip_specifiers(codec_avopt);
2161 for (int i = 0; i < of->nb_streams; i++) {
2162 e = NULL;
2163 while ((e = av_dict_iterate(of->streams[i]->encoder_opts, e)))
2164 av_dict_set(&unused_opts, e->key, NULL, 0);
2165 }
2166
2167 e = NULL;
2168 while ((e = av_dict_iterate(unused_opts, e))) {
2169 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
2170 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
2171 const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
2172 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
2173 if (!option || foption)
2174 continue;
2175
2176 if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
2177 av_log(mux, AV_LOG_ERROR, "Codec AVOption %s (%s) is not an "
2178 "encoding option.\n", e->key, option->help ? option->help : "");
2179 exit_program(1);
2180 }
2181
2182 // gop_timecode is injected by generic code but not always used
2183 if (!strcmp(e->key, "gop_timecode"))
2184 continue;
2185
2186 av_log(mux, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
2187 "for any stream. The most likely reason is either wrong type "
2188 "(e.g. a video option with no video streams) or that it is a "
2189 "private option of some encoder which was not actually used for "
2190 "any stream.\n", e->key, option->help ? option->help : "");
2191 }
2192 av_dict_free(&unused_opts);
2193}
2194
2195static const char *output_file_item_name(void *obj)
2196{
2197 const Muxer *mux = obj;
2198
2199 return mux->log_name;
2200}
2201
2202static const AVClass output_file_class = {
2203 .class_name = "OutputFile",
2204 .version = LIBAVUTIL_VERSION_INT,
2205 .item_name = output_file_item_name,
2206 .category = AV_CLASS_CATEGORY_MUXER,
2207};
2208
2209static Muxer *mux_alloc(void)
2210{
2211 Muxer *mux = allocate_array_elem(&output_files, sizeof(*mux), &nb_output_files);
2212
2213 mux->of.clazz = &output_file_class;
2214 mux->of.index = nb_output_files - 1;
2215
2216 snprintf(mux->log_name, sizeof(mux->log_name), "out#%d", mux->of.index);
2217
2218 return mux;
2219}
2220
2221int of_open(const OptionsContext *o, const char *filename)
2222{
2223 Muxer *mux;
2224 AVFormatContext *oc;
2225 int err;
2226 OutputFile *of;
2227
2228 int64_t recording_time = o->recording_time;
2229 int64_t stop_time = o->stop_time;
2230
2231 mux = mux_alloc();
2232 of = &mux->of;
2233
2234 if (stop_time != INT64_MAX && recording_time != INT64_MAX) {
2235 stop_time = INT64_MAX;
2236 av_log(mux, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
2237 }
2238
2239 if (stop_time != INT64_MAX && recording_time == INT64_MAX) {
2240 int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
2241 if (stop_time <= start_time) {
2242 av_log(mux, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
2243 exit_program(1);
2244 } else {
2245 recording_time = stop_time - start_time;
2246 }
2247 }
2248
2249 of->recording_time = recording_time;
2250 of->start_time = o->start_time;
2251 of->shortest = o->shortest;
2252
2255 av_dict_copy(&mux->opts, o->g->format_opts, 0);
2256
2257 if (!strcmp(filename, "-"))
2258 filename = "pipe:";
2259
2260 err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
2261 if (!oc) {
2262 print_error(filename, err);
2263 exit_program(1);
2264 }
2265 mux->fc = oc;
2266
2267 av_strlcat(mux->log_name, "/", sizeof(mux->log_name));
2268 av_strlcat(mux->log_name, oc->oformat->name, sizeof(mux->log_name));
2269
2270 if (strcmp(oc->oformat->name, "rtp"))
2271 want_sdp = 0;
2272
2273 of->format = oc->oformat;
2274 if (recording_time != INT64_MAX)
2275 oc->duration = recording_time;
2276
2277 oc->interrupt_callback = int_cb;
2278
2279 if (o->bitexact) {
2280 oc->flags |= AVFMT_FLAG_BITEXACT;
2281 of->bitexact = 1;
2282 } else {
2283 of->bitexact = check_opt_bitexact(oc, mux->opts, "fflags",
2284 AVFMT_FLAG_BITEXACT);
2285 }
2286
2287 /* create all output streams for this file */
2288 create_streams(mux, o);
2289
2290 /* check if all codec options have been used */
2292
2293 /* set the decoding_needed flags and create simple filtergraphs */
2294 for (int i = 0; i < of->nb_streams; i++) {
2295 OutputStream *ost = of->streams[i];
2296
2297 if (ost->enc_ctx && ost->ist) {
2298 InputStream *ist = ost->ist;
2300 ist->processing_needed = 1;
2301
2302 if (ost->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ||
2303 ost->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
2304 err = init_simple_filtergraph(ist, ost);
2305 if (err < 0) {
2306 av_log(ost, AV_LOG_ERROR,
2307 "Error initializing a simple filtergraph\n");
2308 exit_program(1);
2309 }
2310 }
2311 } else if (ost->ist) {
2312 ost->ist->processing_needed = 1;
2313 }
2314
2315 /* set the filter output constraints */
2316 if (ost->filter) {
2317 const AVCodec *c = ost->enc_ctx->codec;
2318 OutputFilter *f = ost->filter;
2319 switch (ost->enc_ctx->codec_type) {
2320 case AVMEDIA_TYPE_VIDEO:
2321 f->frame_rate = ost->frame_rate;
2322 f->width = ost->enc_ctx->width;
2323 f->height = ost->enc_ctx->height;
2324 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
2325 f->format = ost->enc_ctx->pix_fmt;
2326 } else {
2327 f->formats = c->pix_fmts;
2328 }
2329 break;
2330 case AVMEDIA_TYPE_AUDIO:
2331 if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
2332 f->format = ost->enc_ctx->sample_fmt;
2333 } else {
2334 f->formats = c->sample_fmts;
2335 }
2336 if (ost->enc_ctx->sample_rate) {
2337 f->sample_rate = ost->enc_ctx->sample_rate;
2338 } else {
2339 f->sample_rates = c->supported_samplerates;
2340 }
2341 if (ost->enc_ctx->ch_layout.nb_channels) {
2342 set_channel_layout(f, ost);
2343 } else if (c->ch_layouts) {
2344 f->ch_layouts = c->ch_layouts;
2345 }
2346 break;
2347 }
2348 }
2349 }
2350
2351 /* check filename in case of an image number is expected */
2352 if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
2353 if (!av_filename_number_test(oc->url)) {
2354 print_error(oc->url, AVERROR(EINVAL));
2355 exit_program(1);
2356 }
2357 }
2358
2359 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
2360 /* test if it already exists to avoid losing precious files */
2361 assert_file_overwrite(filename);
2362
2363 /* open the file */
2364 if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
2365 &oc->interrupt_callback,
2366 &mux->opts)) < 0) {
2367 print_error(filename, err);
2368 exit_program(1);
2369 }
2370 } else if (strcmp(oc->oformat->name, "image2")==0 && !av_filename_number_test(filename))
2371 assert_file_overwrite(filename);
2372
2373 if (o->mux_preload) {
2374 av_dict_set_int(&mux->opts, "preload", o->mux_preload*AV_TIME_BASE, 0);
2375 }
2376 oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
2377
2378 /* copy metadata and chapters from input files */
2379 copy_meta(mux, o);
2380
2381 of_add_programs(mux, o);
2382 of_add_metadata(of, oc, o);
2383
2384 err = set_dispositions(mux, o);
2385 if (err < 0) {
2386 av_log(mux, AV_LOG_FATAL, "Error setting output stream dispositions\n");
2387 exit_program(1);
2388 }
2389
2390 // parse forced keyframe specifications;
2391 // must be done after chapters are created
2392 err = process_forced_keyframes(mux, o);
2393 if (err < 0) {
2394 av_log(mux, AV_LOG_FATAL, "Error processing forced keyframes\n");
2395 exit_program(1);
2396 }
2397
2398 err = setup_sync_queues(mux, oc, o->shortest_buf_duration * AV_TIME_BASE);
2399 if (err < 0) {
2400 av_log(mux, AV_LOG_FATAL, "Error setting up output sync queues\n");
2401 exit_program(1);
2402 }
2403
2404 of->url = filename;
2405
2406 /* write the header for files with no streams */
2407 if (of->format->flags & AVFMT_NOSTREAMS && oc->nb_streams == 0) {
2408 int ret = mux_check_init(mux);
2409 if (ret < 0)
2410 return ret;
2411 }
2412
2413 return 0;
2414}
void exit_program(int ret)
void print_error(const char *filename, int err)
void report_and_exit(int ret)
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
void * allocate_array_elem(void *ptr, size_t elem_size, int *nb_elems)
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
AVDictionary * filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id, AVFormatContext *s, AVStream *st, const AVCodec *codec)
#define GROW_ARRAY(array, nb_elems)
__thread const AVIOInterruptCB int_cb
__thread OutputFile ** output_files
__thread int nb_input_files
__thread int nb_output_files
static int fix_sub_duration_heartbeat(InputStream *ist, int64_t signal_pts)
__thread int copy_unknown_streams
__thread InputFile ** input_files
__thread FilterGraph ** filtergraphs
__thread int nb_filtergraphs
__thread int do_psnr
InputStream * ist_iter(InputStream *prev)
__thread int want_sdp
__thread int ignore_unknown_streams
int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global)
__thread enum VideoSyncMethod video_sync_method
__thread int copy_ts
AVDictionary * strip_specifiers(const AVDictionary *dict)
int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
@ KF_FORCE_SOURCE
@ KF_FORCE_SOURCE_NO_DROP
void assert_file_overwrite(const char *filename)
@ FKF_PREV_FORCED_N
@ FKF_PREV_FORCED_T
@ FKF_N_FORCED
@ FKF_N
@ VSYNC_VFR
@ VSYNC_AUTO
@ VSYNC_PASSTHROUGH
@ VSYNC_CFR
@ VSYNC_VSCFR
const AVCodec * find_codec_or_die(void *logctx, const char *name, enum AVMediaType type, int encoder)
#define DECODING_FOR_OST
char * file_read(const char *filename)
EncStatsType
@ ENC_STATS_STREAM_IDX
@ ENC_STATS_PTS_TIME
@ ENC_STATS_SAMPLE_NUM
@ ENC_STATS_AVG_BITRATE
@ ENC_STATS_LITERAL
@ ENC_STATS_TIMEBASE
@ ENC_STATS_DTS_TIME
@ ENC_STATS_PKT_SIZE
@ ENC_STATS_FRAME_NUM_IN
@ ENC_STATS_PTS
@ ENC_STATS_FRAME_NUM
@ ENC_STATS_FILE_IDX
@ ENC_STATS_DTS
@ ENC_STATS_BITRATE
@ ENC_STATS_PTS_IN
@ ENC_STATS_TIMEBASE_IN
@ ENC_STATS_PTS_TIME_IN
@ ENC_STATS_NB_SAMPLES
int mux_check_init(Muxer *mux)
#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)
static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
#define SET_DICT(type, meta, context, index)
static void create_streams(Muxer *mux, const OptionsContext *o)
static const char *const opt_name_frame_aspect_ratios[]
static const char *const opt_name_max_frames[]
static const char *const opt_name_audio_channels[]
static void of_add_programs(Muxer *mux, const OptionsContext *o)
static const char *const opt_name_enc_stats_pre[]
#define IS_AV_ENC(ost, type)
const char *const forced_keyframes_const_names[]
static const char * output_file_item_name(void *obj)
static void copy_meta(Muxer *mux, const OptionsContext *o)
static const char *const opt_name_audio_ch_layouts[]
int of_open(const OptionsContext *o, const char *filename)
__thread EncStatsFile * enc_stats_files
static const char *const opt_name_inter_matrices[]
static const char *const opt_name_sample_fmts[]
static const char *const opt_name_enc_stats_post[]
static const char *const opt_name_force_fps[]
static OutputStream * new_data_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
static void init_output_filter(OutputFilter *ofilter, const OptionsContext *o, Muxer *mux)
static OutputStream * new_audio_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
__thread int nb_enc_stats_files
static const char *const opt_name_passlogfiles[]
static const char *const opt_name_max_muxing_queue_size[]
static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *os, int copy_metadata)
static void parse_forced_key_frames(KeyframeForceCtx *kf, const Muxer *mux, const char *spec)
static const char *const opt_name_muxing_queue_data_threshold[]
static const char *const opt_name_apad[]
static const char *const opt_name_copy_prior_start[]
static const AVClass output_stream_class
static const char *const opt_name_presets[]
#define DEFAULT_PASS_LOGFILENAME_PREFIX
static OutputStream * new_video_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
static const char *const opt_name_max_frame_rates[]
static const char * output_stream_item_name(void *obj)
static int unescape(char **pdst, size_t *dst_len, const char **pstr, char delim)
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 void of_add_attachments(Muxer *mux, const OptionsContext *o)
static OutputStream * new_unknown_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
static void map_manual(Muxer *mux, const OptionsContext *o, const StreamMap *map)
static int enc_stats_get_file(AVIOContext **io, const char *path)
#define IS_INTERLEAVED(type)
static const char *const opt_name_rc_overrides[]
static const char *const opt_name_forced_key_frames[]
static const char *const opt_name_time_bases[]
static const char *const opt_name_enc_stats_post_fmt[]
static const char *const opt_name_frame_sizes[]
static int process_forced_keyframes(Muxer *mux, const OptionsContext *o)
static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_us)
static const char *const opt_name_audio_sample_rate[]
static void validate_enc_avopt(Muxer *mux, const AVDictionary *codec_avopt)
void of_enc_stats_close(void)
static const char *const opt_name_filter_scripts[]
static void map_auto_video(Muxer *mux, const OptionsContext *o)
static const char *const opt_name_enc_time_bases[]
static MuxStream * mux_stream_alloc(Muxer *mux, enum AVMediaType type)
static void set_channel_layout(OutputFilter *f, OutputStream *ost)
static char * get_line(AVIOContext *s, AVBPrint *bprint)
static OutputStream * new_attachment_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
static Muxer * mux_alloc(void)
static int choose_encoder(const OptionsContext *o, AVFormatContext *s, OutputStream *ost, const AVCodec **enc)
static void map_auto_audio(Muxer *mux, const OptionsContext *o)
static const char *const opt_name_fix_sub_duration_heartbeat[]
static void parse_matrix_coeffs(void *logctx, uint16_t *dest, const char *str)
static int set_dispositions(Muxer *mux, const OptionsContext *o)
static void parse_meta_type(void *logctx, const char *arg, char *type, int *index, const char **stream_spec)
static const AVClass output_file_class
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 OptionsContext *o)
static int check_opt_bitexact(void *ctx, const AVDictionary *opts, const char *opt_name, int flag)
static const char *const opt_name_chroma_intra_matrices[]
static const char *const opt_name_filters[]
static const char *const opt_name_copy_initial_nonkeyframes[]
static const char *const opt_name_fps_mode[]
static const char *const opt_name_intra_matrices[]
static const char *const opt_name_bitstream_filters[]
static OutputStream * new_subtitle_stream(Muxer *mux, const OptionsContext *o, InputStream *ist)
static const char *const opt_name_qscale[]
static const char *const opt_name_mux_stats_fmt[]
static void check_streamcopy_filters(const OptionsContext *o, AVFormatContext *oc, OutputStream *ost, enum AVMediaType type)
static OutputStream * new_output_stream(Muxer *mux, const OptionsContext *o, enum AVMediaType type, InputStream *ist)
static void of_add_metadata(OutputFile *of, AVFormatContext *oc, const OptionsContext *o)
static const char *const opt_name_autoscale[]
static void map_auto_subtitle(Muxer *mux, const OptionsContext *o)
MuxStream * ms_from_ost(OutputStream *ost)
static const char *const opt_name_enc_stats_pre_fmt[]
static void map_auto_data(Muxer *mux, const OptionsContext *o)
static const char *const opt_name_mux_stats[]
static const char *const opt_name_bits_per_raw_sample[]
static const char *const opt_name_disposition[]
static char * get_ost_filters(const OptionsContext *o, AVFormatContext *oc, OutputStream *ost)
static const char *const opt_name_frame_pix_fmts[]
static const char *const opt_name_pass[]
__thread int nb_streams
static FILE * fopen_utf8(const char *path, const char *mode)
SyncQueue * sq_alloc(enum SyncQueueType type, int64_t buf_size_us)
void sq_limit_frames(SyncQueue *sq, unsigned int stream_idx, uint64_t frames)
int sq_add_stream(SyncQueue *sq, int limiting)
@ SYNC_QUEUE_FRAMES
@ SYNC_QUEUE_PACKETS
enum EncStatsType type
AVIOContext * io
AVIOContext * io
EncStatsComponent * components
OutputFilter ** outputs
int64_t ts_offset
AVFormatContext * ctx
int64_t input_ts_offset
InputStream ** streams
AVStream * st
double expr_const_values[FKF_NB]
OutputStream ost
AVBSFContext * bsf_ctx
AVFifo * muxing_queue
size_t muxing_queue_data_threshold
AVDictionary * opts
OutputFile of
int thread_queue_size
AVPacket * sq_pkt
char log_name[32]
SyncQueue * sq_mux
AVFormatContext * fc
int64_t limit_filesize
AVDictionary * codec_opts
AVDictionary * swr_opts
AVDictionary * sws_dict
AVDictionary * format_opts
SpecifierOpt * metadata_map
const char * format
SpecifierOpt * max_frames
StreamMap * stream_maps
SpecifierOpt * metadata
float shortest_buf_duration
const char ** attachments
SpecifierOpt * program
AudioChannelMap * audio_channel_maps
OptionGroup * g
const AVOutputFormat * format
SyncQueue * sq_encode
const char * url
OutputStream ** streams
int64_t start_time
start time in microseconds == AV_TIME_BASE units
const AVClass * clazz
int64_t recording_time
desired length of the resulting file in microseconds == AV_TIME_BASE units
AVFilterInOut * out_tmp
struct OutputStream * ost
const int * formats
const AVChannelLayout * ch_layouts
AVChannelLayout ch_layout
const int * sample_rates
AVRational frame_rate
enum AVMediaType type
AVDictionary * swr_opts
unsigned int fix_sub_duration_heartbeat
int copy_initial_nonkeyframes
int64_t last_mux_dts
OSTFinished finished
int * audio_channels_map
AVPacket * pkt
AVRational frame_aspect_ratio
double rotate_override_value
int64_t last_filter_pts
AVFrame * last_frame
EncStats enc_stats_pre
enum VideoSyncMethod vsync_method
InputStream * ist
KeyframeForceCtx kf
AVRational max_frame_rate
AVRational enc_timebase
AVFrame * filtered_frame
const char * attachment_filename
const AVClass * clazz
AVFrame * sq_frame
AVRational frame_rate
AVCodecContext * enc_ctx
AVDictionary * encoder_opts
AVStream * st
char * filters
filtergraph associated to the -filter option
EncStats enc_stats_post
char * filters_script
filtergraph script associated to the -filter_script option
AVDictionary * sws_dict
OutputFilter * filter
char * logfile_prefix
union SpecifierOpt::@0 u
char * linklabel