FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/fftools/ffmpeg_mux_init.c
Date: 2024-03-29 11:55:30
Exec Total Coverage
Lines: 1176 1812 64.9%
Functions: 39 46 84.8%
Branches: 972 2286 42.5%

Line Branch Exec Source
1 /*
2 * Muxer/output file setup.
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <string.h>
22
23 #include "cmdutils.h"
24 #include "ffmpeg.h"
25 #include "ffmpeg_mux.h"
26 #include "ffmpeg_sched.h"
27 #include "fopen_utf8.h"
28
29 #include "libavformat/avformat.h"
30 #include "libavformat/avio.h"
31
32 #include "libavcodec/avcodec.h"
33
34 #include "libavfilter/avfilter.h"
35
36 #include "libavutil/avassert.h"
37 #include "libavutil/avstring.h"
38 #include "libavutil/avutil.h"
39 #include "libavutil/bprint.h"
40 #include "libavutil/dict.h"
41 #include "libavutil/display.h"
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"
50
51 #define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
52
53 9686 static int check_opt_bitexact(void *ctx, const AVDictionary *opts,
54 const char *opt_name, int flag)
55 {
56 9686 const AVDictionaryEntry *e = av_dict_get(opts, opt_name, NULL, 0);
57
58
2/2
✓ Branch 0 taken 7845 times.
✓ Branch 1 taken 1841 times.
9686 if (e) {
59 7845 const AVOption *o = av_opt_find(ctx, opt_name, NULL, 0, 0);
60 7845 int val = 0;
61
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7845 times.
7845 if (!o)
62 return 0;
63 7845 av_opt_eval_flags(ctx, o, e->value, &val);
64 7845 return !!(val & flag);
65 }
66 1841 return 0;
67 }
68
69 7099 static int choose_encoder(const OptionsContext *o, AVFormatContext *s,
70 OutputStream *ost, const AVCodec **enc)
71 {
72 7099 enum AVMediaType type = ost->type;
73 7099 char *codec_name = NULL;
74
75 7099 *enc = NULL;
76
77
16/20
✓ Branch 1 taken 4283 times.
✓ Branch 2 taken 194 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 194 times.
✓ Branch 5 taken 4477 times.
✓ Branch 6 taken 7099 times.
✓ Branch 7 taken 62 times.
✓ Branch 8 taken 7037 times.
✓ Branch 9 taken 62 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 62 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 61 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 62 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 310 times.
✓ Branch 19 taken 62 times.
✓ Branch 20 taken 61 times.
✓ Branch 21 taken 1 times.
11886 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
78
79
4/4
✓ Branch 0 taken 1576 times.
✓ Branch 1 taken 5523 times.
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 1494 times.
7099 if (type != AVMEDIA_TYPE_VIDEO &&
80
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 71 times.
82 type != AVMEDIA_TYPE_AUDIO &&
81 type != AVMEDIA_TYPE_SUBTITLE) {
82
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
11 if (codec_name && strcmp(codec_name, "copy")) {
83 const char *type_str = av_get_media_type_string(type);
84 av_log(ost, AV_LOG_FATAL,
85 "Encoder '%s' specified, but only '-codec copy' supported "
86 "for %s streams\n", codec_name, type_str);
87 return AVERROR(ENOSYS);
88 }
89 11 return 0;
90 }
91
92
2/2
✓ Branch 0 taken 2871 times.
✓ Branch 1 taken 4217 times.
7088 if (!codec_name) {
93 2871 ost->par_in->codec_id = av_guess_codec(s->oformat, NULL, s->url, NULL, ost->type);
94 2871 *enc = avcodec_find_encoder(ost->par_in->codec_id);
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2871 times.
2871 if (!*enc) {
96 av_log(ost, AV_LOG_FATAL, "Automatic encoder selection failed "
97 "Default encoder for format %s (codec %s) is "
98 "probably disabled. Please choose an encoder manually.\n",
99 s->oformat->name, avcodec_get_name(ost->par_in->codec_id));
100 return AVERROR_ENCODER_NOT_FOUND;
101 }
102
2/2
✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 617 times.
4217 } else if (strcmp(codec_name, "copy")) {
103 3600 int ret = find_codec(ost, codec_name, ost->type, 1, enc);
104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3600 times.
3600 if (ret < 0)
105 return ret;
106 3600 ost->par_in->codec_id = (*enc)->id;
107 }
108
109 7088 return 0;
110 }
111
112 static char *get_line(AVIOContext *s, AVBPrint *bprint)
113 {
114 char c;
115
116 while ((c = avio_r8(s)) && c != '\n')
117 av_bprint_chars(bprint, c, 1);
118
119 if (!av_bprint_is_complete(bprint))
120 return NULL;
121
122 return bprint->str;
123 }
124
125 static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
126 {
127 int i, ret = -1;
128 char filename[1000];
129 char *env_avconv_datadir = getenv_utf8("AVCONV_DATADIR");
130 char *env_home = getenv_utf8("HOME");
131 const char *base[3] = { env_avconv_datadir,
132 env_home,
133 AVCONV_DATADIR,
134 };
135
136 for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) {
137 if (!base[i])
138 continue;
139 if (codec_name) {
140 snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
141 i != 1 ? "" : "/.avconv", codec_name, preset_name);
142 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
143 }
144 if (ret < 0) {
145 snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
146 i != 1 ? "" : "/.avconv", preset_name);
147 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
148 }
149 }
150 freeenv_utf8(env_home);
151 freeenv_utf8(env_avconv_datadir);
152 return ret;
153 }
154
155 typedef struct EncStatsFile {
156 char *path;
157 AVIOContext *io;
158 } EncStatsFile;
159
160 static EncStatsFile *enc_stats_files;
161 static int nb_enc_stats_files;
162
163 static int enc_stats_get_file(AVIOContext **io, const char *path)
164 {
165 EncStatsFile *esf;
166 int ret;
167
168 for (int i = 0; i < nb_enc_stats_files; i++)
169 if (!strcmp(path, enc_stats_files[i].path)) {
170 *io = enc_stats_files[i].io;
171 return 0;
172 }
173
174 ret = GROW_ARRAY(enc_stats_files, nb_enc_stats_files);
175 if (ret < 0)
176 return ret;
177
178 esf = &enc_stats_files[nb_enc_stats_files - 1];
179
180 ret = avio_open2(&esf->io, path, AVIO_FLAG_WRITE, &int_cb, NULL);
181 if (ret < 0) {
182 av_log(NULL, AV_LOG_ERROR, "Error opening stats file '%s': %s\n",
183 path, av_err2str(ret));
184 return ret;
185 }
186
187 esf->path = av_strdup(path);
188 if (!esf->path)
189 return AVERROR(ENOMEM);
190
191 *io = esf->io;
192
193 return 0;
194 }
195
196 6756 void of_enc_stats_close(void)
197 {
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6756 times.
6756 for (int i = 0; i < nb_enc_stats_files; i++) {
199 av_freep(&enc_stats_files[i].path);
200 avio_closep(&enc_stats_files[i].io);
201 }
202 6756 av_freep(&enc_stats_files);
203 6756 nb_enc_stats_files = 0;
204 6756 }
205
206 static int unescape(char **pdst, size_t *dst_len,
207 const char **pstr, char delim)
208 {
209 const char *str = *pstr;
210 char *dst;
211 size_t len, idx;
212
213 *pdst = NULL;
214
215 len = strlen(str);
216 if (!len)
217 return 0;
218
219 dst = av_malloc(len + 1);
220 if (!dst)
221 return AVERROR(ENOMEM);
222
223 for (idx = 0; *str; idx++, str++) {
224 if (str[0] == '\\' && str[1])
225 str++;
226 else if (*str == delim)
227 break;
228
229 dst[idx] = *str;
230 }
231 if (!idx) {
232 av_freep(&dst);
233 return 0;
234 }
235
236 dst[idx] = 0;
237
238 *pdst = dst;
239 *dst_len = idx;
240 *pstr = str;
241
242 return 0;
243 }
244
245 static int enc_stats_init(OutputStream *ost, EncStats *es, int pre,
246 const char *path, const char *fmt_spec)
247 {
248 static const struct {
249 enum EncStatsType type;
250 const char *str;
251 unsigned pre_only:1;
252 unsigned post_only:1;
253 unsigned need_input_data:1;
254 } fmt_specs[] = {
255 { ENC_STATS_FILE_IDX, "fidx" },
256 { ENC_STATS_STREAM_IDX, "sidx" },
257 { ENC_STATS_FRAME_NUM, "n" },
258 { ENC_STATS_FRAME_NUM_IN, "ni", 0, 0, 1 },
259 { ENC_STATS_TIMEBASE, "tb" },
260 { ENC_STATS_TIMEBASE_IN, "tbi", 0, 0, 1 },
261 { ENC_STATS_PTS, "pts" },
262 { ENC_STATS_PTS_TIME, "t" },
263 { ENC_STATS_PTS_IN, "ptsi", 0, 0, 1 },
264 { ENC_STATS_PTS_TIME_IN, "ti", 0, 0, 1 },
265 { ENC_STATS_DTS, "dts", 0, 1 },
266 { ENC_STATS_DTS_TIME, "dt", 0, 1 },
267 { ENC_STATS_SAMPLE_NUM, "sn", 1 },
268 { ENC_STATS_NB_SAMPLES, "samp", 1 },
269 { ENC_STATS_PKT_SIZE, "size", 0, 1 },
270 { ENC_STATS_BITRATE, "br", 0, 1 },
271 { ENC_STATS_AVG_BITRATE, "abr", 0, 1 },
272 { ENC_STATS_KEYFRAME, "key", 0, 1 },
273 };
274 const char *next = fmt_spec;
275
276 int ret;
277
278 while (*next) {
279 EncStatsComponent *c;
280 char *val;
281 size_t val_len;
282
283 // get the sequence up until next opening brace
284 ret = unescape(&val, &val_len, &next, '{');
285 if (ret < 0)
286 return ret;
287
288 if (val) {
289 ret = GROW_ARRAY(es->components, es->nb_components);
290 if (ret < 0) {
291 av_freep(&val);
292 return ret;
293 }
294
295 c = &es->components[es->nb_components - 1];
296 c->type = ENC_STATS_LITERAL;
297 c->str = val;
298 c->str_len = val_len;
299 }
300
301 if (!*next)
302 break;
303 next++;
304
305 // get the part inside braces
306 ret = unescape(&val, &val_len, &next, '}');
307 if (ret < 0)
308 return ret;
309
310 if (!val) {
311 av_log(NULL, AV_LOG_ERROR,
312 "Empty formatting directive in: %s\n", fmt_spec);
313 return AVERROR(EINVAL);
314 }
315
316 if (!*next) {
317 av_log(NULL, AV_LOG_ERROR,
318 "Missing closing brace in: %s\n", fmt_spec);
319 ret = AVERROR(EINVAL);
320 goto fail;
321 }
322 next++;
323
324 ret = GROW_ARRAY(es->components, es->nb_components);
325 if (ret < 0)
326 goto fail;
327
328 c = &es->components[es->nb_components - 1];
329
330 for (size_t i = 0; i < FF_ARRAY_ELEMS(fmt_specs); i++) {
331 if (!strcmp(val, fmt_specs[i].str)) {
332 if ((pre && fmt_specs[i].post_only) || (!pre && fmt_specs[i].pre_only)) {
333 av_log(NULL, AV_LOG_ERROR,
334 "Format directive '%s' may only be used %s-encoding\n",
335 val, pre ? "post" : "pre");
336 ret = AVERROR(EINVAL);
337 goto fail;
338 }
339
340 c->type = fmt_specs[i].type;
341
342 if (fmt_specs[i].need_input_data && !ost->ist) {
343 av_log(ost, AV_LOG_WARNING,
344 "Format directive '%s' is unavailable, because "
345 "this output stream has no associated input stream\n",
346 val);
347 }
348
349 break;
350 }
351 }
352
353 if (!c->type) {
354 av_log(NULL, AV_LOG_ERROR, "Invalid format directive: %s\n", val);
355 ret = AVERROR(EINVAL);
356 goto fail;
357 }
358
359 fail:
360 av_freep(&val);
361 if (ret < 0)
362 return ret;
363 }
364
365 ret = pthread_mutex_init(&es->lock, NULL);
366 if (ret)
367 return AVERROR(ret);
368 es->lock_initialized = 1;
369
370 ret = enc_stats_get_file(&es->io, path);
371 if (ret < 0)
372 return ret;
373
374 return 0;
375 }
376
377 31 static const char *output_stream_item_name(void *obj)
378 {
379 31 const MuxStream *ms = obj;
380
381 31 return ms->log_name;
382 }
383
384 static const AVClass output_stream_class = {
385 .class_name = "OutputStream",
386 .version = LIBAVUTIL_VERSION_INT,
387 .item_name = output_stream_item_name,
388 .category = AV_CLASS_CATEGORY_MUXER,
389 };
390
391 7099 static MuxStream *mux_stream_alloc(Muxer *mux, enum AVMediaType type)
392 {
393 7099 const char *type_str = av_get_media_type_string(type);
394 MuxStream *ms;
395
396 7099 ms = allocate_array_elem(&mux->of.streams, sizeof(*ms), &mux->of.nb_streams);
397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7099 times.
7099 if (!ms)
398 return NULL;
399
400 7099 ms->ost.file = &mux->of;
401 7099 ms->ost.index = mux->of.nb_streams - 1;
402 7099 ms->ost.type = type;
403
404 7099 ms->ost.class = &output_stream_class;
405
406 7099 ms->sch_idx = -1;
407 7099 ms->sch_idx_enc = -1;
408
409
1/2
✓ Branch 0 taken 7099 times.
✗ Branch 1 not taken.
7099 snprintf(ms->log_name, sizeof(ms->log_name), "%cost#%d:%d",
410 7099 type_str ? *type_str : '?', mux->of.index, ms->ost.index);
411
412 7099 return ms;
413 }
414
415 7017 static int ost_get_filters(const OptionsContext *o, AVFormatContext *oc,
416 OutputStream *ost, char **dst)
417 {
418 7017 const char *filters = NULL;
419 #if FFMPEG_OPT_FILTER_SCRIPT
420 7017 const char *filters_script = NULL;
421
422
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 7017 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7017 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7017 MATCH_PER_STREAM_OPT(filter_scripts, str, filters_script, oc, ost->st);
423 #endif
424
6/20
✓ Branch 1 taken 3404 times.
✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 91 times.
✓ Branch 5 taken 3495 times.
✓ Branch 6 taken 7017 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7017 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
10512 MATCH_PER_STREAM_OPT(filters, str, filters, oc, ost->st);
425
426
2/2
✓ Branch 0 taken 584 times.
✓ Branch 1 taken 6433 times.
7017 if (!ost->enc) {
427
1/2
✓ Branch 0 taken 584 times.
✗ Branch 1 not taken.
584 if (
428 #if FFMPEG_OPT_FILTER_SCRIPT
429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 584 times.
584 filters_script ||
430 #endif
431 filters) {
432 av_log(ost, AV_LOG_ERROR,
433 "%s '%s' was specified, but codec copy was selected. "
434 "Filtering and streamcopy cannot be used together.\n",
435 #if FFMPEG_OPT_FILTER_SCRIPT
436 filters ? "Filtergraph" : "Filtergraph script",
437 filters ? filters : filters_script
438 #else
439 "Filtergraph", filters
440 #endif
441 );
442 return AVERROR(ENOSYS);
443 }
444 584 return 0;
445 }
446
447
2/2
✓ Branch 0 taken 167 times.
✓ Branch 1 taken 6266 times.
6433 if (!ost->ist) {
448
1/2
✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
167 if (
449 #if FFMPEG_OPT_FILTER_SCRIPT
450
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 167 times.
167 filters_script ||
451 #endif
452 filters) {
453 av_log(ost, AV_LOG_ERROR,
454 "%s '%s' was specified for a stream fed from a complex "
455 "filtergraph. Simple and complex filtering cannot be used "
456 "together for the same stream.\n",
457 #if FFMPEG_OPT_FILTER_SCRIPT
458 filters ? "Filtergraph" : "Filtergraph script",
459 filters ? filters : filters_script
460 #else
461 "Filtergraph", filters
462 #endif
463 );
464 return AVERROR(EINVAL);
465 }
466 167 return 0;
467 }
468
469 #if FFMPEG_OPT_FILTER_SCRIPT
470
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6266 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6266 if (filters_script && filters) {
471 av_log(ost, AV_LOG_ERROR, "Both -filter and -filter_script set\n");
472 return AVERROR(EINVAL);
473 }
474
475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6266 times.
6266 if (filters_script)
476 *dst = file_read(filters_script);
477 else
478 #endif
479
2/2
✓ Branch 0 taken 3404 times.
✓ Branch 1 taken 2862 times.
6266 if (filters)
480 3404 *dst = av_strdup(filters);
481 else
482
2/2
✓ Branch 0 taken 2282 times.
✓ Branch 1 taken 580 times.
2862 *dst = av_strdup(ost->type == AVMEDIA_TYPE_VIDEO ? "null" : "anull");
483
1/2
✓ Branch 0 taken 6266 times.
✗ Branch 1 not taken.
6266 return *dst ? 0 : AVERROR(ENOMEM);
484 }
485
486 static int parse_matrix_coeffs(void *logctx, uint16_t *dest, const char *str)
487 {
488 const char *p = str;
489 for (int i = 0;; i++) {
490 dest[i] = atoi(p);
491 if (i == 63)
492 break;
493 p = strchr(p, ',');
494 if (!p) {
495 av_log(logctx, AV_LOG_FATAL,
496 "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
497 return AVERROR(EINVAL);
498 }
499 p++;
500 }
501
502 return 0;
503 }
504
505 622 static int fmt_in_list(const int *formats, int format)
506 {
507
1/2
✓ Branch 0 taken 3374 times.
✗ Branch 1 not taken.
3374 for (; *formats != -1; formats++)
508
2/2
✓ Branch 0 taken 622 times.
✓ Branch 1 taken 2752 times.
3374 if (*formats == format)
509 622 return 1;
510 return 0;
511 }
512
513 static enum AVPixelFormat
514 choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat target)
515 {
516 const enum AVPixelFormat *p = codec->pix_fmts;
517 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target);
518 //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel format without alpha is implemented
519 int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
520 enum AVPixelFormat best= AV_PIX_FMT_NONE;
521
522 for (; *p != AV_PIX_FMT_NONE; p++) {
523 best = av_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
524 if (*p == target)
525 break;
526 }
527 if (*p == AV_PIX_FMT_NONE) {
528 if (target != AV_PIX_FMT_NONE)
529 av_log(NULL, AV_LOG_WARNING,
530 "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
531 av_get_pix_fmt_name(target),
532 codec->name,
533 av_get_pix_fmt_name(best));
534 return best;
535 }
536 return target;
537 }
538
539 3733 static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, const char *name)
540 {
541 3733 const enum AVPixelFormat *fmts = ost->enc_ctx->codec->pix_fmts;
542 enum AVPixelFormat fmt;
543
544 3733 fmt = av_get_pix_fmt(name);
545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3733 times.
3733 if (fmt == AV_PIX_FMT_NONE) {
546 av_log(ost, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", name);
547 return AV_PIX_FMT_NONE;
548 }
549
550 /* when the user specified-format is an alias for an endianness-specific
551 * one (e.g. rgb48 -> rgb48be/le), it gets translated into the native
552 * endianness by av_get_pix_fmt();
553 * the following code handles the case when the native endianness is not
554 * supported by the encoder, but the other one is */
555
3/4
✓ Branch 0 taken 311 times.
✓ Branch 1 taken 3422 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 311 times.
3733 if (fmts && !fmt_in_list(fmts, fmt)) {
556 const char *name_canonical = av_get_pix_fmt_name(fmt);
557 int len = strlen(name_canonical);
558
559 if (strcmp(name, name_canonical) &&
560 (!strcmp(name_canonical + len - 2, "le") ||
561 !strcmp(name_canonical + len - 2, "be"))) {
562 char name_other[64];
563 enum AVPixelFormat fmt_other;
564
565 snprintf(name_other, sizeof(name_other), "%s%ce",
566 name, name_canonical[len - 2] == 'l' ? 'b' : 'l');
567 fmt_other = av_get_pix_fmt(name_other);
568 if (fmt_other != AV_PIX_FMT_NONE && fmt_in_list(fmts, fmt_other)) {
569 av_log(ost, AV_LOG_VERBOSE, "Mapping pixel format %s->%s\n",
570 name, name_other);
571 fmt = fmt_other;
572 }
573 }
574 }
575
576
3/4
✓ Branch 0 taken 311 times.
✓ Branch 1 taken 3422 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 311 times.
3733 if (fmts && !fmt_in_list(fmts, fmt))
577 fmt = choose_pixel_fmt(ost->enc_ctx->codec, fmt);
578
579 3733 return fmt;
580 }
581
582 5523 static int new_stream_video(Muxer *mux, const OptionsContext *o,
583 OutputStream *ost)
584 {
585 5523 AVFormatContext *oc = mux->fc;
586 AVStream *st;
587 5523 char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL;
588 5523 int ret = 0;
589
590 5523 st = ost->st;
591
592
4/20
✓ Branch 1 taken 22 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 22 times.
✓ Branch 6 taken 5523 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5523 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5545 MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
593
3/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 5501 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
5523 if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
594 av_log(ost, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
595 return AVERROR(EINVAL);
596 }
597
598
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5523 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5523 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5523 MATCH_PER_STREAM_OPT(max_frame_rates, str, max_frame_rate, oc, st);
599
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5523 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
5523 if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, max_frame_rate) < 0) {
600 av_log(ost, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate);
601 return AVERROR(EINVAL);
602 }
603
604
3/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 5501 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
5523 if (frame_rate && max_frame_rate) {
605 av_log(ost, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n");
606 return AVERROR(EINVAL);
607 }
608
609
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5523 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5523 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5523 MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5523 times.
5523 if (frame_aspect_ratio) {
611 AVRational q;
612 if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
613 q.num <= 0 || q.den <= 0) {
614 av_log(ost, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
615 return AVERROR(EINVAL);
616 }
617 ost->frame_aspect_ratio = q;
618 }
619
620
2/2
✓ Branch 0 taken 5192 times.
✓ Branch 1 taken 331 times.
5523 if (ost->enc_ctx) {
621 5192 AVCodecContext *video_enc = ost->enc_ctx;
622 5192 const char *p = NULL, *fps_mode = NULL;
623 5192 char *frame_size = NULL;
624 5192 char *frame_pix_fmt = NULL;
625 5192 char *intra_matrix = NULL, *inter_matrix = NULL;
626 5192 char *chroma_intra_matrix = NULL;
627 5192 int do_pass = 0;
628 int i;
629
630
4/20
✓ Branch 1 taken 231 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 231 times.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5423 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
631
2/2
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 4961 times.
5192 if (frame_size) {
632 231 ret = av_parse_video_size(&video_enc->width, &video_enc->height, frame_size);
633
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (ret < 0) {
634 av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
635 return AVERROR(EINVAL);
636 }
637 }
638
639
4/20
✓ Branch 1 taken 3733 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3733 times.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
8925 MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
640
3/4
✓ Branch 0 taken 3733 times.
✓ Branch 1 taken 1459 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3733 times.
5192 if (frame_pix_fmt && *frame_pix_fmt == '+') {
641 ost->keep_pix_fmt = 1;
642 if (!*++frame_pix_fmt)
643 frame_pix_fmt = NULL;
644 }
645
2/2
✓ Branch 0 taken 3733 times.
✓ Branch 1 taken 1459 times.
5192 if (frame_pix_fmt) {
646 3733 video_enc->pix_fmt = pix_fmt_parse(ost, frame_pix_fmt);
647
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3733 times.
3733 if (video_enc->pix_fmt == AV_PIX_FMT_NONE)
648 return AVERROR(EINVAL);
649 }
650
651
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5192 MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
652
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5192 times.
5192 if (intra_matrix) {
653 if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64)))
654 return AVERROR(ENOMEM);
655
656 ret = parse_matrix_coeffs(ost, video_enc->intra_matrix, intra_matrix);
657 if (ret < 0)
658 return ret;
659 }
660
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5192 MATCH_PER_STREAM_OPT(chroma_intra_matrices, str, chroma_intra_matrix, oc, st);
661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5192 times.
5192 if (chroma_intra_matrix) {
662 uint16_t *p = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64);
663 if (!p)
664 return AVERROR(ENOMEM);
665 video_enc->chroma_intra_matrix = p;
666 ret = parse_matrix_coeffs(ost, p, chroma_intra_matrix);
667 if (ret < 0)
668 return ret;
669 }
670
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5192 MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
671
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5192 times.
5192 if (inter_matrix) {
672 if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64)))
673 return AVERROR(ENOMEM);
674 ret = parse_matrix_coeffs(ost, video_enc->inter_matrix, inter_matrix);
675 if (ret < 0)
676 return ret;
677 }
678
679
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5192 MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
680
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5192 times.
5192 for (i = 0; p; i++) {
681 int start, end, q;
682 int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
683 if (e != 3) {
684 av_log(ost, AV_LOG_FATAL, "error parsing rc_override\n");
685 return AVERROR(EINVAL);
686 }
687 video_enc->rc_override =
688 av_realloc_array(video_enc->rc_override,
689 i + 1, sizeof(RcOverride));
690 if (!video_enc->rc_override) {
691 av_log(ost, AV_LOG_FATAL, "Could not (re)allocate memory for rc_override.\n");
692 return AVERROR(ENOMEM);
693 }
694 video_enc->rc_override[i].start_frame = start;
695 video_enc->rc_override[i].end_frame = end;
696 if (q > 0) {
697 video_enc->rc_override[i].qscale = q;
698 video_enc->rc_override[i].quality_factor = 1.0;
699 }
700 else {
701 video_enc->rc_override[i].qscale = 0;
702 video_enc->rc_override[i].quality_factor = -q/100.0;
703 }
704 p = strchr(p, '/');
705 if (p) p++;
706 }
707 5192 video_enc->rc_override_count = i;
708
709 /* two pass mode */
710
4/20
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5200 MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
711
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5184 times.
5192 if (do_pass) {
712
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (do_pass & 1) {
713 4 video_enc->flags |= AV_CODEC_FLAG_PASS1;
714 4 av_dict_set(&ost->encoder_opts, "flags", "+pass1", AV_DICT_APPEND);
715 }
716
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (do_pass & 2) {
717 4 video_enc->flags |= AV_CODEC_FLAG_PASS2;
718 4 av_dict_set(&ost->encoder_opts, "flags", "+pass2", AV_DICT_APPEND);
719 }
720 }
721
722
4/20
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5200 MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
723
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5184 times.
5192 if (ost->logfile_prefix &&
724
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
725 return AVERROR(ENOMEM);
726
727
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5184 times.
5192 if (do_pass) {
728 8 int ost_idx = -1;
729 char logfilename[1024];
730 FILE *f;
731
732 /* compute this stream's global index */
733
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 for (int i = 0; i <= ost->file->index; i++)
734 8 ost_idx += output_files[i]->nb_streams;
735
736 8 snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
737
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 ost->logfile_prefix ? ost->logfile_prefix :
738 DEFAULT_PASS_LOGFILENAME_PREFIX,
739 ost_idx);
740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (!strcmp(ost->enc_ctx->codec->name, "libx264")) {
741 av_dict_set(&ost->encoder_opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
742 } else {
743
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (video_enc->flags & AV_CODEC_FLAG_PASS2) {
744 4 char *logbuffer = file_read(logfilename);
745
746
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!logbuffer) {
747 av_log(ost, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
748 logfilename);
749 return AVERROR(EIO);
750 }
751 4 video_enc->stats_in = logbuffer;
752 }
753
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (video_enc->flags & AV_CODEC_FLAG_PASS1) {
754 4 f = fopen_utf8(logfilename, "wb");
755
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!f) {
756 av_log(ost, AV_LOG_FATAL,
757 "Cannot write log file '%s' for pass-1 encoding: %s\n",
758 logfilename, strerror(errno));
759 return AVERROR(errno);
760 }
761 4 ost->logfile = f;
762 }
763 }
764 }
765
766
4/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5193 MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
767
768 #if FFMPEG_OPT_TOP
769 5192 ost->top_field_first = -1;
770
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5192 MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
771
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5192 times.
5192 if (ost->top_field_first >= 0)
772 av_log(ost, AV_LOG_WARNING, "-top is deprecated, use the setfield filter instead\n");
773 #endif
774
775 #if FFMPEG_OPT_VSYNC
776 5192 ost->vsync_method = video_sync_method;
777 #else
778 ost->vsync_method = VSYNC_AUTO;
779 #endif
780
4/20
✓ Branch 1 taken 514 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 514 times.
✓ Branch 6 taken 5192 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
5706 MATCH_PER_STREAM_OPT(fps_mode, str, fps_mode, oc, st);
781
2/2
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 4678 times.
5192 if (fps_mode) {
782 514 ret = parse_and_set_vsync(fps_mode, &ost->vsync_method, ost->file->index, ost->index, 0);
783
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 514 times.
514 if (ret < 0)
784 return ret;
785 }
786
787
3/4
✓ Branch 0 taken 5171 times.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5171 times.
5192 if ((ost->frame_rate.num || ost->max_frame_rate.num) &&
788
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
21 !(ost->vsync_method == VSYNC_AUTO ||
789
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR)) {
790 av_log(ost, AV_LOG_FATAL, "One of -r/-fpsmax was specified "
791 "together a non-CFR -vsync/-fps_mode. This is contradictory.\n");
792 return AVERROR(EINVAL);
793 }
794
795
2/2
✓ Branch 0 taken 4678 times.
✓ Branch 1 taken 514 times.
5192 if (ost->vsync_method == VSYNC_AUTO) {
796
3/4
✓ Branch 0 taken 4658 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4658 times.
4678 if (ost->frame_rate.num || ost->max_frame_rate.num) {
797 20 ost->vsync_method = VSYNC_CFR;
798
2/2
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 4374 times.
4658 } else if (!strcmp(oc->oformat->name, "avi")) {
799 284 ost->vsync_method = VSYNC_VFR;
800 } else {
801 4374 ost->vsync_method = (oc->oformat->flags & AVFMT_VARIABLE_FPS) ?
802 3906 ((oc->oformat->flags & AVFMT_NOTIMESTAMPS) ?
803
4/4
✓ Branch 0 taken 3906 times.
✓ Branch 1 taken 468 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 3893 times.
4374 VSYNC_PASSTHROUGH : VSYNC_VFR) :
804 VSYNC_CFR;
805 }
806
807
4/4
✓ Branch 0 taken 4590 times.
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 488 times.
✓ Branch 3 taken 4102 times.
4678 if (ost->ist && ost->vsync_method == VSYNC_CFR) {
808 488 const InputFile *ifile = ost->ist->file;
809
810
3/4
✓ Branch 0 taken 442 times.
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 442 times.
✗ Branch 3 not taken.
488 if (ifile->nb_streams == 1 && ifile->input_ts_offset == 0)
811 442 ost->vsync_method = VSYNC_VSCFR;
812 }
813
814
3/4
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 4632 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
4678 if (ost->vsync_method == VSYNC_CFR && copy_ts) {
815 ost->vsync_method = VSYNC_VSCFR;
816 }
817 }
818
4/4
✓ Branch 0 taken 5140 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 4698 times.
5192 ost->is_cfr = (ost->vsync_method == VSYNC_CFR || ost->vsync_method == VSYNC_VSCFR);
819 }
820
821 5523 return 0;
822 }
823
824 1494 static int new_stream_audio(Muxer *mux, const OptionsContext *o,
825 OutputStream *ost)
826 {
827 1494 AVFormatContext *oc = mux->fc;
828 1494 AVStream *st = ost->st;
829
830
2/2
✓ Branch 0 taken 1241 times.
✓ Branch 1 taken 253 times.
1494 if (ost->enc_ctx) {
831 1241 AVCodecContext *audio_enc = ost->enc_ctx;
832 1241 int channels = 0;
833 1241 char *layout = NULL;
834 1241 char *sample_fmt = NULL;
835 1241 const char *apad = NULL;
836
837
4/20
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 1241 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1241 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1251 MATCH_PER_STREAM_OPT(audio_channels, i, channels, oc, st);
838
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1231 times.
1241 if (channels) {
839 10 audio_enc->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
840 10 audio_enc->ch_layout.nb_channels = channels;
841 }
842
843
4/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1241 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1241 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1242 MATCH_PER_STREAM_OPT(audio_ch_layouts, str, layout, oc, st);
844
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1240 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
1241 if (layout && av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) {
845 av_log(ost, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout);
846 return AVERROR(EINVAL);
847 }
848
849
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1241 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1241 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1241 MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
850
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1241 times.
1241 if (sample_fmt &&
851 (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
852 av_log(ost, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
853 return AVERROR(EINVAL);
854 }
855
856
4/20
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 1241 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1241 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1255 MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
857
858
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1241 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1241 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
1241 MATCH_PER_STREAM_OPT(apad, str, apad, oc, st);
859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1241 times.
1241 if (apad) {
860 ost->apad = av_strdup(apad);
861 if (!ost->apad)
862 return AVERROR(ENOMEM);
863 }
864 }
865
866 1494 return 0;
867 }
868
869 71 static int new_stream_subtitle(Muxer *mux, const OptionsContext *o,
870 OutputStream *ost)
871 {
872 AVStream *st;
873
874 71 st = ost->st;
875
876
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 33 times.
71 if (ost->enc_ctx) {
877 38 AVCodecContext *subtitle_enc = ost->enc_ctx;
878
879 AVCodecDescriptor const *input_descriptor =
880 38 avcodec_descriptor_get(ost->ist->par->codec_id);
881 AVCodecDescriptor const *output_descriptor =
882 38 avcodec_descriptor_get(subtitle_enc->codec_id);
883 38 int input_props = 0, output_props = 0;
884
885 38 char *frame_size = NULL;
886
887
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 38 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 38 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
38 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, mux->fc, st);
888
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (frame_size) {
889 int ret = av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size);
890 if (ret < 0) {
891 av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
892 return ret;
893 }
894 }
895
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 if (input_descriptor)
896 38 input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
897
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 if (output_descriptor)
898 38 output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
899
3/6
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 38 times.
38 if (input_props && output_props && input_props != output_props) {
900 av_log(ost, AV_LOG_ERROR,
901 "Subtitle encoding currently only possible from text to text "
902 "or bitmap to bitmap\n");
903 return AVERROR(EINVAL);
904 }
905 }
906
907 71 return 0;
908 }
909
910 627 static int streamcopy_init(const Muxer *mux, OutputStream *ost)
911 {
912 627 MuxStream *ms = ms_from_ost(ost);
913
914 627 const InputStream *ist = ost->ist;
915 627 const InputFile *ifile = ist->file;
916
917 627 AVCodecParameters *par = ost->par_in;
918 627 uint32_t codec_tag = par->codec_tag;
919
920 627 AVCodecContext *codec_ctx = NULL;
921 627 AVDictionary *codec_opts = NULL;
922
923 627 AVRational fr = ost->frame_rate;
924
925 627 int ret = 0;
926
927 627 codec_ctx = avcodec_alloc_context3(NULL);
928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if (!codec_ctx)
929 return AVERROR(ENOMEM);
930
931 627 ret = avcodec_parameters_to_context(codec_ctx, ist->par);
932
1/2
✓ Branch 0 taken 627 times.
✗ Branch 1 not taken.
627 if (ret >= 0)
933 627 ret = av_opt_set_dict(codec_ctx, &ost->encoder_opts);
934
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if (ret < 0) {
935 av_log(ost, AV_LOG_FATAL,
936 "Error setting up codec context options.\n");
937 goto fail;
938 }
939
940 627 ret = avcodec_parameters_from_context(par, codec_ctx);
941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if (ret < 0) {
942 av_log(ost, AV_LOG_FATAL,
943 "Error getting reference codec parameters.\n");
944 goto fail;
945 }
946
947
2/2
✓ Branch 0 taken 621 times.
✓ Branch 1 taken 6 times.
627 if (!codec_tag) {
948 621 const struct AVCodecTag * const *ct = mux->fc->oformat->codec_tag;
949 unsigned int codec_tag_tmp;
950
6/6
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 509 times.
✓ Branch 3 taken 80 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 11 times.
✓ Branch 6 taken 69 times.
701 if (!ct || av_codec_get_id (ct, par->codec_tag) == par->codec_id ||
951 80 !av_codec_get_tag2(ct, par->codec_id, &codec_tag_tmp))
952 552 codec_tag = par->codec_tag;
953 }
954
955 627 par->codec_tag = codec_tag;
956
957
2/2
✓ Branch 0 taken 626 times.
✓ Branch 1 taken 1 times.
627 if (!fr.num)
958 626 fr = ist->framerate;
959
960
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 625 times.
627 if (fr.num)
961 2 ost->st->avg_frame_rate = fr;
962 else
963 625 ost->st->avg_frame_rate = ist->st->avg_frame_rate;
964
965 627 ret = avformat_transfer_internal_stream_timing_info(mux->fc->oformat,
966 627 ost->st, ist->st, copy_tb);
967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if (ret < 0)
968 goto fail;
969
970 // copy timebase while removing common factors
971
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 626 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
627 if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) {
972
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 625 times.
626 if (fr.num)
973 1 ost->st->time_base = av_inv_q(fr);
974 else
975 625 ost->st->time_base = av_add_q(av_stream_get_codec_timebase(ost->st), (AVRational){0, 1});
976 }
977
978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if (!ms->copy_prior_start) {
979 ms->ts_copy_start = (mux->of.start_time == AV_NOPTS_VALUE) ?
980 0 : mux->of.start_time;
981 if (copy_ts && ifile->start_time != AV_NOPTS_VALUE) {
982 ms->ts_copy_start = FFMAX(ms->ts_copy_start,
983 ifile->start_time + ifile->ts_offset);
984 }
985 }
986
987
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 627 times.
696 for (int i = 0; i < ist->st->codecpar->nb_coded_side_data; i++) {
988 69 const AVPacketSideData *sd_src = &ist->st->codecpar->coded_side_data[i];
989 AVPacketSideData *sd_dst;
990
991 69 sd_dst = av_packet_side_data_new(&ost->st->codecpar->coded_side_data,
992 69 &ost->st->codecpar->nb_coded_side_data,
993 69 sd_src->type, sd_src->size, 0);
994
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if (!sd_dst) {
995 ret = AVERROR(ENOMEM);
996 goto fail;
997 }
998 69 memcpy(sd_dst->data, sd_src->data, sd_src->size);
999 }
1000
1001
3/3
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 331 times.
✓ Branch 2 taken 43 times.
627 switch (par->codec_type) {
1002 253 case AVMEDIA_TYPE_AUDIO:
1003
4/6
✓ Branch 0 taken 248 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 248 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 248 times.
253 if ((par->block_align == 1 || par->block_align == 1152 || par->block_align == 576) &&
1004
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 par->codec_id == AV_CODEC_ID_MP3)
1005 par->block_align = 0;
1006
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 240 times.
253 if (par->codec_id == AV_CODEC_ID_AC3)
1007 13 par->block_align = 0;
1008 253 break;
1009 331 case AVMEDIA_TYPE_VIDEO: {
1010 AVRational sar;
1011
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 331 times.
331 if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option
1012 sar =
1013 av_mul_q(ost->frame_aspect_ratio,
1014 (AVRational){ par->height, par->width });
1015 av_log(ost, AV_LOG_WARNING, "Overriding aspect ratio "
1016 "with stream copy may produce invalid files\n");
1017 }
1018
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 241 times.
331 else if (ist->st->sample_aspect_ratio.num)
1019 90 sar = ist->st->sample_aspect_ratio;
1020 else
1021 241 sar = par->sample_aspect_ratio;
1022 331 ost->st->sample_aspect_ratio = par->sample_aspect_ratio = sar;
1023 331 ost->st->avg_frame_rate = ist->st->avg_frame_rate;
1024 331 ost->st->r_frame_rate = ist->st->r_frame_rate;
1025 331 break;
1026 }
1027 }
1028
1029 627 fail:
1030 627 avcodec_free_context(&codec_ctx);
1031 627 av_dict_free(&codec_opts);
1032 627 return ret;
1033 }
1034
1035 7099 static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type,
1036 InputStream *ist, OutputFilter *ofilter,
1037 OutputStream **post)
1038 {
1039 7099 AVFormatContext *oc = mux->fc;
1040 MuxStream *ms;
1041 OutputStream *ost;
1042 const AVCodec *enc;
1043 AVStream *st;
1044 7099 int ret = 0;
1045 7099 const char *bsfs = NULL, *time_base = NULL;
1046 7099 char *filters = NULL, *next, *codec_tag = NULL;
1047 7099 double qscale = -1;
1048
1049 7099 st = avformat_new_stream(oc, NULL);
1050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7099 times.
7099 if (!st)
1051 return AVERROR(ENOMEM);
1052
1053 7099 ms = mux_stream_alloc(mux, type);
1054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7099 times.
7099 if (!ms)
1055 return AVERROR(ENOMEM);
1056
1057 // only streams with sources (i.e. not attachments)
1058 // are handled by the scheduler
1059
4/4
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 6931 times.
✓ Branch 2 taken 167 times.
✓ Branch 3 taken 1 times.
7099 if (ist || ofilter) {
1060 7098 ret = GROW_ARRAY(mux->sch_stream_idx, mux->nb_sch_stream_idx);
1061
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7098 times.
7098 if (ret < 0)
1062 return ret;
1063
1064 7098 ret = sch_add_mux_stream(mux->sch, mux->sch_idx);
1065
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7098 times.
7098 if (ret < 0)
1066 return ret;
1067
1068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7098 times.
7098 av_assert0(ret == mux->nb_sch_stream_idx - 1);
1069 7098 mux->sch_stream_idx[ret] = ms->ost.index;
1070 7098 ms->sch_idx = ret;
1071 }
1072
1073 7099 ost = &ms->ost;
1074
1075
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 7063 times.
7099 if (o->streamid) {
1076 AVDictionaryEntry *e;
1077 char idx[16], *p;
1078 36 snprintf(idx, sizeof(idx), "%d", ost->index);
1079
1080 36 e = av_dict_get(o->streamid, idx, NULL, 0);
1081
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 if (e) {
1082 36 st->id = strtol(e->value, &p, 0);
1083
2/4
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
36 if (!e->value[0] || *p) {
1084 av_log(ost, AV_LOG_FATAL, "Invalid stream id: %s\n", e->value);
1085 return AVERROR(EINVAL);
1086 }
1087 }
1088 }
1089
1090 7099 ost->par_in = avcodec_parameters_alloc();
1091
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7099 times.
7099 if (!ost->par_in)
1092 return AVERROR(ENOMEM);
1093
1094 7099 ms->last_mux_dts = AV_NOPTS_VALUE;
1095
1096 7099 ost->st = st;
1097 7099 ost->ist = ist;
1098 7099 ost->kf.ref_pts = AV_NOPTS_VALUE;
1099 7099 ost->par_in->codec_type = type;
1100 7099 st->codecpar->codec_type = type;
1101
1102 7099 ret = choose_encoder(o, oc, ost, &enc);
1103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7099 times.
7099 if (ret < 0) {
1104 av_log(ost, AV_LOG_FATAL, "Error selecting an encoder\n");
1105 return ret;
1106 }
1107
1108
2/2
✓ Branch 0 taken 6471 times.
✓ Branch 1 taken 628 times.
7099 if (enc) {
1109 6471 ost->enc_ctx = avcodec_alloc_context3(enc);
1110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6471 times.
6471 if (!ost->enc_ctx)
1111 return AVERROR(ENOMEM);
1112
1113 6471 ret = sch_add_enc(mux->sch, encoder_thread, ost,
1114
2/2
✓ Branch 0 taken 6433 times.
✓ Branch 1 taken 38 times.
6471 ost->type == AVMEDIA_TYPE_SUBTITLE ? NULL : enc_open);
1115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6471 times.
6471 if (ret < 0)
1116 return ret;
1117 6471 ms->sch_idx_enc = ret;
1118
1119 6471 ret = enc_alloc(&ost->enc, enc, mux->sch, ms->sch_idx_enc);
1120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6471 times.
6471 if (ret < 0)
1121 return ret;
1122
1123 6471 av_strlcat(ms->log_name, "/", sizeof(ms->log_name));
1124 6471 av_strlcat(ms->log_name, enc->name, sizeof(ms->log_name));
1125 } else {
1126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 628 times.
628 if (ofilter) {
1127 av_log(ost, AV_LOG_ERROR,
1128 "Streamcopy requested for output stream fed "
1129 "from a complex filtergraph. Filtering and streamcopy "
1130 "cannot be used together.\n");
1131 return AVERROR(EINVAL);
1132 }
1133
1134 628 av_strlcat(ms->log_name, "/copy", sizeof(ms->log_name));
1135 }
1136
1137 7099 av_log(ost, AV_LOG_VERBOSE, "Created %s stream from ",
1138 av_get_media_type_string(type));
1139
2/2
✓ Branch 0 taken 6931 times.
✓ Branch 1 taken 168 times.
7099 if (ist)
1140 6931 av_log(ost, AV_LOG_VERBOSE, "input stream %d:%d",
1141 6931 ist->file->index, ist->index);
1142
2/2
✓ Branch 0 taken 167 times.
✓ Branch 1 taken 1 times.
168 else if (ofilter)
1143 167 av_log(ost, AV_LOG_VERBOSE, "complex filtergraph %d:[%s]\n",
1144 167 ofilter->graph->index, ofilter->name);
1145
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 else if (type == AVMEDIA_TYPE_ATTACHMENT)
1146 1 av_log(ost, AV_LOG_VERBOSE, "attached file");
1147 else av_assert0(0);
1148 7099 av_log(ost, AV_LOG_VERBOSE, "\n");
1149
1150 7099 ms->pkt = av_packet_alloc();
1151
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7099 times.
7099 if (!ms->pkt)
1152 return AVERROR(ENOMEM);
1153
1154
2/2
✓ Branch 0 taken 6471 times.
✓ Branch 1 taken 628 times.
7099 if (ost->enc_ctx) {
1155 6471 AVCodecContext *enc = ost->enc_ctx;
1156 6471 AVIOContext *s = NULL;
1157 6471 char *buf = NULL, *arg = NULL, *preset = NULL;
1158 6471 const char *enc_stats_pre = NULL, *enc_stats_post = NULL, *mux_stats = NULL;
1159 6471 const char *enc_time_base = NULL;
1160
1161 6471 ret = filter_codec_opts(o->g->codec_opts, enc->codec_id,
1162 6471 oc, st, enc->codec, &ost->encoder_opts);
1163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6471 times.
6471 if (ret < 0)
1164 return ret;
1165
1166
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 6471 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6471 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
6471 MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
1167 6471 ost->autoscale = 1;
1168
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 6471 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6471 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
6471 MATCH_PER_STREAM_OPT(autoscale, i, ost->autoscale, oc, st);
1169
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6471 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6471 if (preset && (!(ret = get_preset_file_2(preset, enc->codec->name, &s)))) {
1170 AVBPrint bprint;
1171 av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
1172 do {
1173 av_bprint_clear(&bprint);
1174 buf = get_line(s, &bprint);
1175 if (!buf) {
1176 ret = AVERROR(ENOMEM);
1177 break;
1178 }
1179
1180 if (!buf[0] || buf[0] == '#')
1181 continue;
1182 if (!(arg = strchr(buf, '='))) {
1183 av_log(ost, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
1184 ret = AVERROR(EINVAL);
1185 break;
1186 }
1187 *arg++ = 0;
1188 av_dict_set(&ost->encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE);
1189 } while (!s->eof_reached);
1190 av_bprint_finalize(&bprint, NULL);
1191 avio_closep(&s);
1192 }
1193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6471 times.
6471 if (ret) {
1194 av_log(ost, AV_LOG_FATAL,
1195 "Preset %s specified, but could not be opened.\n", preset);
1196 return ret;
1197 }
1198
1199
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 6471 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6471 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
6471 MATCH_PER_STREAM_OPT(enc_stats_pre, str, enc_stats_pre, oc, st);
1200
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6471 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6471 if (enc_stats_pre &&
1201 (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
1202 const char *format = "{fidx} {sidx} {n} {t}";
1203
1204 MATCH_PER_STREAM_OPT(enc_stats_pre_fmt, str, format, oc, st);
1205
1206 ret = enc_stats_init(ost, &ost->enc_stats_pre, 1, enc_stats_pre, format);
1207 if (ret < 0)
1208 return ret;
1209 }
1210
1211
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 6471 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6471 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
6471 MATCH_PER_STREAM_OPT(enc_stats_post, str, enc_stats_post, oc, st);
1212
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6471 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6471 if (enc_stats_post &&
1213 (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
1214 const char *format = "{fidx} {sidx} {n} {t}";
1215
1216 MATCH_PER_STREAM_OPT(enc_stats_post_fmt, str, format, oc, st);
1217
1218 ret = enc_stats_init(ost, &ost->enc_stats_post, 0, enc_stats_post, format);
1219 if (ret < 0)
1220 return ret;
1221 }
1222
1223
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 6471 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6471 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
6471 MATCH_PER_STREAM_OPT(mux_stats, str, mux_stats, oc, st);
1224
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6471 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6471 if (mux_stats &&
1225 (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
1226 const char *format = "{fidx} {sidx} {n} {t}";
1227
1228 MATCH_PER_STREAM_OPT(mux_stats_fmt, str, format, oc, st);
1229
1230 ret = enc_stats_init(ost, &ms->stats, 0, mux_stats, format);
1231 if (ret < 0)
1232 return ret;
1233 }
1234
1235
4/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 6471 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6471 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
6472 MATCH_PER_STREAM_OPT(enc_time_bases, str, enc_time_base, oc, st);
1236
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6470 times.
6471 if (enc_time_base) {
1237 AVRational q;
1238
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!strcmp(enc_time_base, "demux")) {
1239 1 q = (AVRational){ ENC_TIME_BASE_DEMUX, 0 };
1240 } else if (!strcmp(enc_time_base, "filter")) {
1241 q = (AVRational){ ENC_TIME_BASE_FILTER, 0 };
1242 } else {
1243 ret = av_parse_ratio(&q, enc_time_base, INT_MAX, 0, NULL);
1244 if (ret < 0 || q.den <= 0
1245 #if !FFMPEG_OPT_ENC_TIME_BASE_NUM
1246 || q.num < 0
1247 #endif
1248 ) {
1249 av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", enc_time_base);
1250 return ret < 0 ? ret : AVERROR(EINVAL);
1251 }
1252 #if FFMPEG_OPT_ENC_TIME_BASE_NUM
1253 if (q.num < 0)
1254 av_log(ost, AV_LOG_WARNING, "-enc_time_base -1 is deprecated,"
1255 " use -enc_timebase demux\n");
1256 #endif
1257 }
1258
1259 1 ost->enc_timebase = q;
1260 }
1261 } else {
1262 628 ret = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st,
1263 NULL, &ost->encoder_opts);
1264
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 628 times.
628 if (ret < 0)
1265 return ret;
1266 }
1267
1268
1269
2/2
✓ Branch 0 taken 1857 times.
✓ Branch 1 taken 5242 times.
7099 if (o->bitexact) {
1270 1857 ost->bitexact = 1;
1271
2/2
✓ Branch 0 taken 4722 times.
✓ Branch 1 taken 520 times.
5242 } else if (ost->enc_ctx) {
1272 4722 ost->bitexact = check_opt_bitexact(ost->enc_ctx, ost->encoder_opts, "flags",
1273 AV_CODEC_FLAG_BITEXACT);
1274 }
1275
1276
4/20
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 7099 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7099 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7102 MATCH_PER_STREAM_OPT(time_bases, str, time_base, oc, st);
1277
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7096 times.
7099 if (time_base) {
1278 AVRational q;
1279
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 ||
1280
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
3 q.num <= 0 || q.den <= 0) {
1281 av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", time_base);
1282 return AVERROR(EINVAL);
1283 }
1284 3 st->time_base = q;
1285 }
1286
1287 7099 ms->max_frames = INT64_MAX;
1288
14/20
✓ Branch 1 taken 4811 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 4815 times.
✓ Branch 6 taken 7099 times.
✓ Branch 7 taken 2141 times.
✓ Branch 8 taken 4958 times.
✓ Branch 9 taken 2141 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2141 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2141 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 2141 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 6423 times.
✓ Branch 19 taken 2141 times.
✓ Branch 20 taken 2141 times.
✗ Branch 21 not taken.
18337 MATCH_PER_STREAM_OPT(max_frames, i64, ms->max_frames, oc, st);
1289
2/2
✓ Branch 0 taken 4815 times.
✓ Branch 1 taken 7093 times.
11908 for (int i = 0; i < o->max_frames.nb_opt; i++) {
1290 4815 char *p = o->max_frames.opt[i].specifier;
1291
4/4
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 4646 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 163 times.
4815 if (!*p && type != AVMEDIA_TYPE_VIDEO) {
1292 6 av_log(ost, AV_LOG_WARNING, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n");
1293 6 break;
1294 }
1295 }
1296
1297 7099 ms->copy_prior_start = -1;
1298
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 7099 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7099 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7099 MATCH_PER_STREAM_OPT(copy_prior_start, i, ms->copy_prior_start, oc ,st);
1299
1300
6/20
✓ Branch 1 taken 132 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 142 times.
✓ Branch 6 taken 7099 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7099 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7241 MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st);
1301
3/4
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 6967 times.
✓ Branch 2 taken 132 times.
✗ Branch 3 not taken.
7099 if (bsfs && *bsfs) {
1302 132 ret = av_bsf_list_parse_str(bsfs, &ms->bsf_ctx);
1303
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 132 times.
132 if (ret < 0) {
1304 av_log(ost, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret));
1305 return ret;
1306 }
1307 }
1308
1309
4/20
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 7099 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7099 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7106 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
1310
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7092 times.
7099 if (codec_tag) {
1311 7 uint32_t tag = strtol(codec_tag, &next, 0);
1312
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (*next) {
1313 7 uint8_t buf[4] = { 0 };
1314
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 memcpy(buf, codec_tag, FFMIN(sizeof(buf), strlen(codec_tag)));
1315 7 tag = AV_RL32(buf);
1316 }
1317 7 ost->st->codecpar->codec_tag = tag;
1318 7 ost->par_in->codec_tag = tag;
1319
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (ost->enc_ctx)
1320 1 ost->enc_ctx->codec_tag = tag;
1321 }
1322
1323
14/20
✓ Branch 1 taken 266 times.
✓ Branch 2 taken 55 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 55 times.
✓ Branch 5 taken 321 times.
✓ Branch 6 taken 7099 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 7098 times.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✓ Branch 19 taken 1 times.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
7421 MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
1324
4/4
✓ Branch 0 taken 6471 times.
✓ Branch 1 taken 628 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 6206 times.
7099 if (ost->enc_ctx && qscale >= 0) {
1325 265 ost->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE;
1326 265 ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale;
1327 }
1328
1329
2/2
✓ Branch 0 taken 7098 times.
✓ Branch 1 taken 1 times.
7099 if (ms->sch_idx >= 0) {
1330 7098 int max_muxing_queue_size = 128;
1331 7098 int muxing_queue_data_threshold = 50 * 1024 * 1024;
1332
1333
4/20
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 7098 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7098 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7100 MATCH_PER_STREAM_OPT(max_muxing_queue_size, i, max_muxing_queue_size, oc, st);
1334
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 7098 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7098 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7098 MATCH_PER_STREAM_OPT(muxing_queue_data_threshold, i, muxing_queue_data_threshold, oc, st);
1335
1336 7098 sch_mux_stream_buffering(mux->sch, mux->sch_idx, ms->sch_idx,
1337 max_muxing_queue_size, muxing_queue_data_threshold);
1338 }
1339
1340
4/20
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 7099 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7099 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7100 MATCH_PER_STREAM_OPT(bits_per_raw_sample, i, ost->bits_per_raw_sample,
1341 oc, st);
1342
1343
6/20
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 7099 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7099 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7101 MATCH_PER_STREAM_OPT(fix_sub_duration_heartbeat, i, ost->fix_sub_duration_heartbeat,
1344 oc, st);
1345
1346
4/4
✓ Branch 0 taken 2747 times.
✓ Branch 1 taken 4352 times.
✓ Branch 2 taken 2651 times.
✓ Branch 3 taken 96 times.
7099 if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->enc_ctx)
1347 2651 ost->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1348
1349 7099 av_dict_copy(&ost->sws_dict, o->g->sws_dict, 0);
1350
1351 7099 av_dict_copy(&ost->swr_opts, o->g->swr_opts, 0);
1352
4/4
✓ Branch 0 taken 6471 times.
✓ Branch 1 taken 628 times.
✓ Branch 3 taken 59 times.
✓ Branch 4 taken 6412 times.
7099 if (ost->enc_ctx && av_get_exact_bits_per_sample(ost->enc_ctx->codec_id) == 24)
1353 59 av_dict_set(&ost->swr_opts, "output_sample_bits", "24", 0);
1354
1355
2/20
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 7099 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7099 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7099 MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i,
1356 ms->copy_initial_nonkeyframes, oc, st);
1357
1358
4/4
✓ Branch 0 taken 5523 times.
✓ Branch 1 taken 1494 times.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 11 times.
7099 switch (type) {
1359 5523 case AVMEDIA_TYPE_VIDEO: ret = new_stream_video (mux, o, ost); break;
1360 1494 case AVMEDIA_TYPE_AUDIO: ret = new_stream_audio (mux, o, ost); break;
1361 71 case AVMEDIA_TYPE_SUBTITLE: ret = new_stream_subtitle (mux, o, ost); break;
1362 }
1363
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7099 times.
7099 if (ret < 0)
1364 return ret;
1365
1366
4/4
✓ Branch 0 taken 1576 times.
✓ Branch 1 taken 5523 times.
✓ Branch 2 taken 1494 times.
✓ Branch 3 taken 82 times.
7099 if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO) {
1367 7017 ret = ost_get_filters(o, oc, ost, &filters);
1368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7017 times.
7017 if (ret < 0)
1369 return ret;
1370 }
1371
1372
4/4
✓ Branch 0 taken 6471 times.
✓ Branch 1 taken 628 times.
✓ Branch 2 taken 1279 times.
✓ Branch 3 taken 5192 times.
7099 if (ost->enc &&
1373
2/2
✓ Branch 0 taken 1241 times.
✓ Branch 1 taken 38 times.
7712 (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) {
1374
2/2
✓ Branch 0 taken 167 times.
✓ Branch 1 taken 6266 times.
6433 if (ofilter) {
1375 167 ost->filter = ofilter;
1376 167 ret = ofilter_bind_ost(ofilter, ost, ms->sch_idx_enc);
1377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 167 times.
167 if (ret < 0)
1378 return ret;
1379 } else {
1380 6266 ret = init_simple_filtergraph(ost->ist, ost, filters,
1381 6266 mux->sch, ms->sch_idx_enc);
1382
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6266 times.
6266 if (ret < 0) {
1383 av_log(ost, AV_LOG_ERROR,
1384 "Error initializing a simple filtergraph\n");
1385 return ret;
1386 }
1387 }
1388
1389 6433 ret = sch_connect(mux->sch, SCH_ENC(ms->sch_idx_enc),
1390 6433 SCH_MSTREAM(mux->sch_idx, ms->sch_idx));
1391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6433 times.
6433 if (ret < 0)
1392 return ret;
1393
2/2
✓ Branch 0 taken 665 times.
✓ Branch 1 taken 1 times.
666 } else if (ost->ist) {
1394 665 int sched_idx = ist_output_add(ost->ist, ost);
1395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 665 times.
665 if (sched_idx < 0) {
1396 av_log(ost, AV_LOG_ERROR,
1397 "Error binding an input stream\n");
1398 return sched_idx;
1399 }
1400 665 ms->sch_idx_src = sched_idx;
1401
1402
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 627 times.
665 if (ost->enc) {
1403 38 ret = sch_connect(mux->sch, SCH_DEC(sched_idx),
1404 38 SCH_ENC(ms->sch_idx_enc));
1405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (ret < 0)
1406 return ret;
1407
1408 38 ret = sch_connect(mux->sch, SCH_ENC(ms->sch_idx_enc),
1409 38 SCH_MSTREAM(mux->sch_idx, ms->sch_idx));
1410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (ret < 0)
1411 return ret;
1412 } else {
1413 627 ret = sch_connect(mux->sch, SCH_DSTREAM(ost->ist->file->index, sched_idx),
1414 627 SCH_MSTREAM(ost->file->index, ms->sch_idx));
1415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if (ret < 0)
1416 return ret;
1417 }
1418 }
1419
1420
4/4
✓ Branch 0 taken 6931 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 627 times.
✓ Branch 3 taken 6304 times.
7099 if (ost->ist && !ost->enc) {
1421 627 ret = streamcopy_init(mux, ost);
1422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
627 if (ret < 0)
1423 return ret;
1424 }
1425
1426 // copy estimated duration as a hint to the muxer
1427
4/4
✓ Branch 0 taken 6931 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 5431 times.
✓ Branch 3 taken 1500 times.
7099 if (ost->ist && ost->ist->st->duration > 0) {
1428 5431 ms->stream_duration = ist->st->duration;
1429 5431 ms->stream_duration_tb = ist->st->time_base;
1430 }
1431
1432
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7098 times.
7099 if (post)
1433 1 *post = ost;
1434
1435 7099 return 0;
1436 }
1437
1438 6364 static int map_auto_video(Muxer *mux, const OptionsContext *o)
1439 {
1440 6364 AVFormatContext *oc = mux->fc;
1441 6364 InputStream *best_ist = NULL;
1442 6364 int best_score = 0;
1443 int qcr;
1444
1445 /* video: highest resolution */
1446
2/2
✓ Branch 1 taken 731 times.
✓ Branch 2 taken 5633 times.
6364 if (av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_VIDEO) == AV_CODEC_ID_NONE)
1447 731 return 0;
1448
1449 5633 qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
1450
2/2
✓ Branch 0 taken 5673 times.
✓ Branch 1 taken 5633 times.
11306 for (int j = 0; j < nb_input_files; j++) {
1451 5673 InputFile *ifile = input_files[j];
1452 5673 InputStream *file_best_ist = NULL;
1453 5673 int file_best_score = 0;
1454
2/2
✓ Branch 0 taken 5950 times.
✓ Branch 1 taken 5673 times.
11623 for (int i = 0; i < ifile->nb_streams; i++) {
1455 5950 InputStream *ist = ifile->streams[i];
1456 int score;
1457
1458
2/2
✓ Branch 0 taken 5949 times.
✓ Branch 1 taken 1 times.
5950 if (ist->user_set_discard == AVDISCARD_ALL ||
1459
2/2
✓ Branch 0 taken 630 times.
✓ Branch 1 taken 5319 times.
5949 ist->st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
1460 631 continue;
1461
1462 10638 score = ist->st->codecpar->width * ist->st->codecpar->height
1463
2/2
✓ Branch 0 taken 5317 times.
✓ Branch 1 taken 2 times.
5319 + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
1464
2/2
✓ Branch 0 taken 509 times.
✓ Branch 1 taken 4810 times.
5319 + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
1465
3/4
✓ Branch 0 taken 5319 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 5310 times.
5319 if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1466 9 score = 1;
1467
1468
2/2
✓ Branch 0 taken 5318 times.
✓ Branch 1 taken 1 times.
5319 if (score > file_best_score) {
1469
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5318 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5318 if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1470 continue;
1471 5318 file_best_score = score;
1472 5318 file_best_ist = ist;
1473 }
1474 }
1475
2/2
✓ Branch 0 taken 5318 times.
✓ Branch 1 taken 355 times.
5673 if (file_best_ist) {
1476
1/2
✓ Branch 0 taken 5318 times.
✗ Branch 1 not taken.
5318 if((qcr == MKTAG('A', 'P', 'I', 'C')) ||
1477
2/2
✓ Branch 0 taken 5310 times.
✓ Branch 1 taken 8 times.
5318 !(file_best_ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
1478
2/2
✓ Branch 0 taken 509 times.
✓ Branch 1 taken 4801 times.
5310 file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT);
1479
1/2
✓ Branch 0 taken 5318 times.
✗ Branch 1 not taken.
5318 if (file_best_score > best_score) {
1480 5318 best_score = file_best_score;
1481 5318 best_ist = file_best_ist;
1482 }
1483 }
1484 }
1485
2/2
✓ Branch 0 taken 5318 times.
✓ Branch 1 taken 315 times.
5633 if (best_ist)
1486 5318 return ost_add(mux, o, AVMEDIA_TYPE_VIDEO, best_ist, NULL, NULL);
1487
1488 315 return 0;
1489 }
1490
1491 6453 static int map_auto_audio(Muxer *mux, const OptionsContext *o)
1492 {
1493 6453 AVFormatContext *oc = mux->fc;
1494 6453 InputStream *best_ist = NULL;
1495 6453 int best_score = 0;
1496
1497 /* audio: most channels */
1498
2/2
✓ Branch 1 taken 842 times.
✓ Branch 2 taken 5611 times.
6453 if (av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_AUDIO) == AV_CODEC_ID_NONE)
1499 842 return 0;
1500
1501
2/2
✓ Branch 0 taken 5610 times.
✓ Branch 1 taken 5611 times.
11221 for (int j = 0; j < nb_input_files; j++) {
1502 5610 InputFile *ifile = input_files[j];
1503 5610 InputStream *file_best_ist = NULL;
1504 5610 int file_best_score = 0;
1505
2/2
✓ Branch 0 taken 5813 times.
✓ Branch 1 taken 5610 times.
11423 for (int i = 0; i < ifile->nb_streams; i++) {
1506 5813 InputStream *ist = ifile->streams[i];
1507 int score;
1508
1509
2/2
✓ Branch 0 taken 5812 times.
✓ Branch 1 taken 1 times.
5813 if (ist->user_set_discard == AVDISCARD_ALL ||
1510
2/2
✓ Branch 0 taken 4522 times.
✓ Branch 1 taken 1290 times.
5812 ist->st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
1511 4523 continue;
1512
1513 2580 score = ist->st->codecpar->ch_layout.nb_channels
1514
2/2
✓ Branch 0 taken 1289 times.
✓ Branch 1 taken 1 times.
1290 + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)
1515
2/2
✓ Branch 0 taken 171 times.
✓ Branch 1 taken 1119 times.
1290 + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT);
1516
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 10 times.
1290 if (score > file_best_score) {
1517 1280 file_best_score = score;
1518 1280 file_best_ist = ist;
1519 }
1520 }
1521
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 4330 times.
5610 if (file_best_ist) {
1522
2/2
✓ Branch 0 taken 171 times.
✓ Branch 1 taken 1109 times.
1280 file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT);
1523
1/2
✓ Branch 0 taken 1280 times.
✗ Branch 1 not taken.
1280 if (file_best_score > best_score) {
1524 1280 best_score = file_best_score;
1525 1280 best_ist = file_best_ist;
1526 }
1527 }
1528 }
1529
2/2
✓ Branch 0 taken 1280 times.
✓ Branch 1 taken 4331 times.
5611 if (best_ist)
1530 1280 return ost_add(mux, o, AVMEDIA_TYPE_AUDIO, best_ist, NULL, NULL);
1531
1532 4331 return 0;
1533 }
1534
1535 6610 static int map_auto_subtitle(Muxer *mux, const OptionsContext *o)
1536 {
1537 6610 AVFormatContext *oc = mux->fc;
1538 6610 const char *subtitle_codec_name = NULL;
1539
1540 /* subtitles: pick first */
1541 6610 subtitle_codec_name = opt_match_per_type_str(&o->codec_names, 's');
1542
4/4
✓ Branch 1 taken 6550 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 6543 times.
✓ Branch 4 taken 7 times.
6610 if (!avcodec_find_encoder(oc->oformat->subtitle_codec) && !subtitle_codec_name)
1543 6543 return 0;
1544
1545
2/2
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 19 times.
100 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist))
1546
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 33 times.
81 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1547 AVCodecDescriptor const *input_descriptor =
1548 48 avcodec_descriptor_get(ist->st->codecpar->codec_id);
1549 48 AVCodecDescriptor const *output_descriptor = NULL;
1550 AVCodec const *output_codec =
1551 48 avcodec_find_encoder(oc->oformat->subtitle_codec);
1552 48 int input_props = 0, output_props = 0;
1553
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (ist->user_set_discard == AVDISCARD_ALL)
1554 continue;
1555
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 7 times.
48 if (output_codec)
1556 41 output_descriptor = avcodec_descriptor_get(output_codec->id);
1557
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 if (input_descriptor)
1558 48 input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
1559
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 7 times.
48 if (output_descriptor)
1560 41 output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB);
1561
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
48 if (subtitle_codec_name ||
1562
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
32 input_props & output_props ||
1563 // Map dvb teletext which has neither property to any output subtitle encoder
1564 input_descriptor && output_descriptor &&
1565 (!input_descriptor->props ||
1566 !output_descriptor->props)) {
1567 48 return ost_add(mux, o, AVMEDIA_TYPE_SUBTITLE, ist, NULL, NULL);
1568 }
1569 }
1570
1571 19 return 0;
1572 }
1573
1574 6611 static int map_auto_data(Muxer *mux, const OptionsContext *o)
1575 {
1576 6611 AVFormatContext *oc = mux->fc;
1577 /* Data only if codec id match */
1578 6611 enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_DATA);
1579
1580
1/2
✓ Branch 0 taken 6611 times.
✗ Branch 1 not taken.
6611 if (codec_id == AV_CODEC_ID_NONE)
1581 6611 return 0;
1582
1583 for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) {
1584 if (ist->user_set_discard == AVDISCARD_ALL)
1585 continue;
1586 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA &&
1587 ist->st->codecpar->codec_id == codec_id) {
1588 int ret = ost_add(mux, o, AVMEDIA_TYPE_DATA, ist, NULL, NULL);
1589 if (ret < 0)
1590 return ret;
1591 }
1592 }
1593
1594 return 0;
1595 }
1596
1597 339 static int map_manual(Muxer *mux, const OptionsContext *o, const StreamMap *map)
1598 {
1599 InputStream *ist;
1600 int ret;
1601
1602
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 339 times.
339 if (map->disabled)
1603 return 0;
1604
1605
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 285 times.
339 if (map->linklabel) {
1606 FilterGraph *fg;
1607 54 OutputFilter *ofilter = NULL;
1608 int j, k;
1609
1610
1/2
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
54 for (j = 0; j < nb_filtergraphs; j++) {
1611 54 fg = filtergraphs[j];
1612
1/2
✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
176 for (k = 0; k < fg->nb_outputs; k++) {
1613 176 const char *linklabel = fg->outputs[k]->linklabel;
1614
3/4
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 122 times.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
176 if (linklabel && !strcmp(linklabel, map->linklabel)) {
1615 54 ofilter = fg->outputs[k];
1616 54 goto loop_end;
1617 }
1618 }
1619 }
1620 loop_end:
1621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (!ofilter) {
1622 av_log(mux, AV_LOG_FATAL, "Output with label '%s' does not exist "
1623 "in any defined filter graph, or was already used elsewhere.\n", map->linklabel);
1624 return AVERROR(EINVAL);
1625 }
1626
1627 54 av_log(mux, AV_LOG_VERBOSE, "Creating output stream from an explicitly "
1628 54 "mapped complex filtergraph %d, output [%s]\n", fg->index, map->linklabel);
1629
1630 54 ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL);
1631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 54 times.
54 if (ret < 0)
1632 return ret;
1633 } else {
1634 285 ist = input_files[map->file_index]->streams[map->stream_index];
1635
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 285 times.
285 if (ist->user_set_discard == AVDISCARD_ALL) {
1636 av_log(mux, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n",
1637 map->file_index, map->stream_index);
1638 return AVERROR(EINVAL);
1639 }
1640
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 285 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
285 if(o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
1641 return 0;
1642
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 285 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
285 if(o-> audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
1643 return 0;
1644
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 284 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
285 if(o-> video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
1645 return 0;
1646
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 285 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
285 if(o-> data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
1647 return 0;
1648
1649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 285 times.
285 if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_UNKNOWN &&
1650 !copy_unknown_streams) {
1651 av_log(mux, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL,
1652 "Cannot map stream #%d:%d - unsupported type.\n",
1653 map->file_index, map->stream_index);
1654 if (!ignore_unknown_streams) {
1655 av_log(mux, AV_LOG_FATAL,
1656 "If you want unsupported types ignored instead "
1657 "of failing, please use the -ignore_unknown option\n"
1658 "If you want them copied, please use -copy_unknown\n");
1659 return AVERROR(EINVAL);
1660 }
1661 return 0;
1662 }
1663
1664 285 ret = ost_add(mux, o, ist->st->codecpar->codec_type, ist, NULL, NULL);
1665
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 285 times.
285 if (ret < 0)
1666 return ret;
1667 }
1668
1669 339 return 0;
1670 }
1671
1672 6757 static int of_add_attachments(Muxer *mux, const OptionsContext *o)
1673 {
1674 OutputStream *ost;
1675 int err;
1676
1677
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6757 times.
6758 for (int i = 0; i < o->nb_attachments; i++) {
1678 AVIOContext *pb;
1679 uint8_t *attachment;
1680 char *attachment_filename;
1681 const char *p;
1682 int64_t len;
1683
1684
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
1685 av_log(mux, AV_LOG_FATAL, "Could not open attachment file %s.\n",
1686 o->attachments[i]);
1687 return err;
1688 }
1689
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if ((len = avio_size(pb)) <= 0) {
1690 av_log(mux, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
1691 o->attachments[i]);
1692 err = len ? len : AVERROR_INVALIDDATA;
1693 goto read_fail;
1694 }
1695
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
1696 av_log(mux, AV_LOG_FATAL, "Attachment %s too large.\n",
1697 o->attachments[i]);
1698 err = AVERROR(ERANGE);
1699 goto read_fail;
1700 }
1701
1702 1 attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE);
1703
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!attachment) {
1704 err = AVERROR(ENOMEM);
1705 goto read_fail;
1706 }
1707
1708 1 err = avio_read(pb, attachment, len);
1709
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (err < 0)
1710 av_log(mux, AV_LOG_FATAL, "Error reading attachment file %s: %s\n",
1711 o->attachments[i], av_err2str(err));
1712
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 else if (err != len) {
1713 av_log(mux, AV_LOG_FATAL, "Could not read all %"PRId64" bytes for "
1714 "attachment file %s\n", len, o->attachments[i]);
1715 err = AVERROR(EIO);
1716 }
1717
1718 1 read_fail:
1719 1 avio_closep(&pb);
1720
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (err < 0)
1721 return err;
1722
1723 1 memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
1724
1725 1 av_log(mux, AV_LOG_VERBOSE, "Creating attachment stream from file %s\n",
1726 1 o->attachments[i]);
1727
1728 1 attachment_filename = av_strdup(o->attachments[i]);
1729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!attachment_filename) {
1730 av_free(attachment);
1731 return AVERROR(ENOMEM);
1732 }
1733
1734 1 err = ost_add(mux, o, AVMEDIA_TYPE_ATTACHMENT, NULL, NULL, &ost);
1735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (err < 0) {
1736 av_free(attachment_filename);
1737 av_freep(&attachment);
1738 return err;
1739 }
1740
1741 1 ost->attachment_filename = attachment_filename;
1742 1 ost->par_in->extradata = attachment;
1743 1 ost->par_in->extradata_size = len;
1744
1745 1 p = strrchr(o->attachments[i], '/');
1746
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
1747 }
1748
1749 6757 return 0;
1750 }
1751
1752 6757 static int create_streams(Muxer *mux, const OptionsContext *o)
1753 {
1754 static int (* const map_func[])(Muxer *mux, const OptionsContext *o) = {
1755 [AVMEDIA_TYPE_VIDEO] = map_auto_video,
1756 [AVMEDIA_TYPE_AUDIO] = map_auto_audio,
1757 [AVMEDIA_TYPE_SUBTITLE] = map_auto_subtitle,
1758 [AVMEDIA_TYPE_DATA] = map_auto_data,
1759 };
1760
1761 6757 AVFormatContext *oc = mux->fc;
1762
1763 6757 int auto_disable =
1764 6757 o->video_disable * (1 << AVMEDIA_TYPE_VIDEO) |
1765 6757 o->audio_disable * (1 << AVMEDIA_TYPE_AUDIO) |
1766 6757 o->subtitle_disable * (1 << AVMEDIA_TYPE_SUBTITLE) |
1767 6757 o->data_disable * (1 << AVMEDIA_TYPE_DATA);
1768
1769 int ret;
1770
1771 /* create streams for all unlabeled output pads */
1772
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 6757 times.
6877 for (int i = 0; i < nb_filtergraphs; i++) {
1773 120 FilterGraph *fg = filtergraphs[i];
1774
2/2
✓ Branch 0 taken 170 times.
✓ Branch 1 taken 120 times.
290 for (int j = 0; j < fg->nb_outputs; j++) {
1775 170 OutputFilter *ofilter = fg->outputs[j];
1776
1777
4/4
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 55 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 113 times.
170 if (ofilter->linklabel || ofilter->ost)
1778 57 continue;
1779
1780 113 auto_disable |= 1 << ofilter->type;
1781
1782 113 av_log(mux, AV_LOG_VERBOSE, "Creating output stream from unlabeled "
1783 "output of complex filtergraph %d.", fg->index);
1784
1/2
✓ Branch 0 taken 113 times.
✗ Branch 1 not taken.
113 if (!o->nb_stream_maps)
1785 113 av_log(mux, AV_LOG_VERBOSE, " This overrides automatic %s mapping.",
1786 av_get_media_type_string(ofilter->type));
1787 113 av_log(mux, AV_LOG_VERBOSE, "\n");
1788
1789 113 ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL);
1790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113 times.
113 if (ret < 0)
1791 return ret;
1792 }
1793 }
1794
1795
2/2
✓ Branch 0 taken 6611 times.
✓ Branch 1 taken 146 times.
6757 if (!o->nb_stream_maps) {
1796 6611 av_log(mux, AV_LOG_VERBOSE, "No explicit maps, mapping streams automatically...\n");
1797
1798 /* pick the "best" stream of each type */
1799
2/2
✓ Branch 0 taken 26444 times.
✓ Branch 1 taken 6611 times.
33055 for (int i = 0; i < FF_ARRAY_ELEMS(map_func); i++) {
1800
3/4
✓ Branch 0 taken 26444 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 406 times.
✓ Branch 3 taken 26038 times.
26444 if (!map_func[i] || auto_disable & (1 << i))
1801 406 continue;
1802 26038 ret = map_func[i](mux, o);
1803
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26038 times.
26038 if (ret < 0)
1804 return ret;
1805 }
1806 } else {
1807 146 av_log(mux, AV_LOG_VERBOSE, "Adding streams from explicit maps...\n");
1808
1809
2/2
✓ Branch 0 taken 339 times.
✓ Branch 1 taken 146 times.
485 for (int i = 0; i < o->nb_stream_maps; i++) {
1810 339 ret = map_manual(mux, o, &o->stream_maps[i]);
1811
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 339 times.
339 if (ret < 0)
1812 return ret;
1813 }
1814 }
1815
1816 6757 ret = of_add_attachments(mux, o);
1817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (ret < 0)
1818 return ret;
1819
1820 // setup fix_sub_duration_heartbeat mappings
1821
2/2
✓ Branch 0 taken 7099 times.
✓ Branch 1 taken 6757 times.
13856 for (unsigned i = 0; i < oc->nb_streams; i++) {
1822 7099 MuxStream *src = ms_from_ost(mux->of.streams[i]);
1823
1824
2/2
✓ Branch 0 taken 7098 times.
✓ Branch 1 taken 1 times.
7099 if (!src->ost.fix_sub_duration_heartbeat)
1825 7098 continue;
1826
1827
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for (unsigned j = 0; j < oc->nb_streams; j++) {
1828 2 MuxStream *dst = ms_from_ost(mux->of.streams[j]);
1829
1830
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 if (src == dst || dst->ost.type != AVMEDIA_TYPE_SUBTITLE ||
1831
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 !dst->ost.enc || !dst->ost.ist || !dst->ost.ist->fix_sub_duration)
1832 1 continue;
1833
1834 1 ret = sch_mux_sub_heartbeat_add(mux->sch, mux->sch_idx, src->sch_idx,
1835 1 dst->sch_idx_src);
1836
1837 }
1838 }
1839
1840
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6757 if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
1841 av_dump_format(oc, nb_output_files - 1, oc->url, 1);
1842 av_log(mux, AV_LOG_ERROR, "Output file does not contain any stream\n");
1843 return AVERROR(EINVAL);
1844 }
1845
1846 6757 return 0;
1847 }
1848
1849 6757 static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, int64_t buf_size_us)
1850 {
1851 6757 OutputFile *of = &mux->of;
1852 6757 int nb_av_enc = 0, nb_audio_fs = 0, nb_interleaved = 0;
1853 6757 int limit_frames = 0, limit_frames_av_enc = 0;
1854
1855 #define IS_AV_ENC(ost, type) \
1856 (ost->enc_ctx && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO))
1857 #define IS_INTERLEAVED(type) (type != AVMEDIA_TYPE_ATTACHMENT)
1858
1859
2/2
✓ Branch 0 taken 7099 times.
✓ Branch 1 taken 6757 times.
13856 for (int i = 0; i < oc->nb_streams; i++) {
1860 7099 OutputStream *ost = of->streams[i];
1861 7099 MuxStream *ms = ms_from_ost(ost);
1862 7099 enum AVMediaType type = ost->type;
1863
1864 7099 ms->sq_idx_mux = -1;
1865
1866 7099 nb_interleaved += IS_INTERLEAVED(type);
1867
6/6
✓ Branch 0 taken 6471 times.
✓ Branch 1 taken 628 times.
✓ Branch 2 taken 1279 times.
✓ Branch 3 taken 5192 times.
✓ Branch 4 taken 1241 times.
✓ Branch 5 taken 38 times.
7099 nb_av_enc += IS_AV_ENC(ost, type);
1868
4/4
✓ Branch 0 taken 6471 times.
✓ Branch 1 taken 628 times.
✓ Branch 2 taken 1241 times.
✓ Branch 3 taken 5230 times.
8340 nb_audio_fs += (ost->enc_ctx && type == AVMEDIA_TYPE_AUDIO &&
1869
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 1085 times.
1241 !(ost->enc_ctx->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE));
1870
1871 7099 limit_frames |= ms->max_frames < INT64_MAX;
1872
7/8
✓ Branch 0 taken 2670 times.
✓ Branch 1 taken 4429 times.
✓ Branch 2 taken 2651 times.
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 2623 times.
✓ Branch 6 taken 28 times.
✗ Branch 7 not taken.
7099 limit_frames_av_enc |= (ms->max_frames < INT64_MAX) && IS_AV_ENC(ost, type);
1873 }
1874
1875
7/8
✓ Branch 0 taken 223 times.
✓ Branch 1 taken 6534 times.
✓ Branch 2 taken 219 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6753 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3972 times.
✓ Branch 7 taken 122 times.
10851 if (!((nb_interleaved > 1 && of->shortest) ||
1876
2/2
✓ Branch 0 taken 4094 times.
✓ Branch 1 taken 2659 times.
6753 (nb_interleaved > 0 && limit_frames) ||
1877 nb_audio_fs))
1878 3972 return 0;
1879
1880 /* we use a sync queue before encoding when:
1881 * - 'shortest' is in effect and we have two or more encoded audio/video
1882 * streams
1883 * - at least one encoded audio/video stream is frame-limited, since
1884 * that has similar semantics to 'shortest'
1885 * - at least one audio encoder requires constant frame sizes
1886 *
1887 * Note that encoding sync queues are handled in the scheduler, because
1888 * different encoders run in different threads and need external
1889 * synchronization, while muxer sync queues can be handled inside the muxer
1890 */
1891
8/8
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2781 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 133 times.
✓ Branch 5 taken 2651 times.
✓ Branch 6 taken 124 times.
✓ Branch 7 taken 9 times.
2785 if ((of->shortest && nb_av_enc > 1) || limit_frames_av_enc || nb_audio_fs) {
1892 int sq_idx, ret;
1893
1894 2776 sq_idx = sch_add_sq_enc(mux->sch, buf_size_us, mux);
1895
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2776 times.
2776 if (sq_idx < 0)
1896 return sq_idx;
1897
1898
2/2
✓ Branch 0 taken 2828 times.
✓ Branch 1 taken 2776 times.
5604 for (int i = 0; i < oc->nb_streams; i++) {
1899 2828 OutputStream *ost = of->streams[i];
1900 2828 MuxStream *ms = ms_from_ost(ost);
1901 2828 enum AVMediaType type = ost->type;
1902
1903
5/6
✓ Branch 0 taken 2821 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 183 times.
✓ Branch 3 taken 2638 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 183 times.
2828 if (!IS_AV_ENC(ost, type))
1904 7 continue;
1905
1906 2821 ret = sch_sq_add_enc(mux->sch, sq_idx, ms->sch_idx_enc,
1907
2/2
✓ Branch 0 taken 2651 times.
✓ Branch 1 taken 166 times.
2817 of->shortest || ms->max_frames < INT64_MAX,
1908
2/2
✓ Branch 0 taken 2817 times.
✓ Branch 1 taken 4 times.
2821 ms->max_frames);
1909
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2821 times.
2821 if (ret < 0)
1910 return ret;
1911 }
1912 }
1913
1914 /* if there are any additional interleaved streams, then ALL the streams
1915 * are also synchronized before sending them to the muxer */
1916
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 2772 times.
2785 if (nb_interleaved > nb_av_enc) {
1917 13 mux->sq_mux = sq_alloc(SYNC_QUEUE_PACKETS, buf_size_us, mux);
1918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!mux->sq_mux)
1919 return AVERROR(ENOMEM);
1920
1921 13 mux->sq_pkt = av_packet_alloc();
1922
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (!mux->sq_pkt)
1923 return AVERROR(ENOMEM);
1924
1925
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 13 times.
48 for (int i = 0; i < oc->nb_streams; i++) {
1926 35 OutputStream *ost = of->streams[i];
1927 35 MuxStream *ms = ms_from_ost(ost);
1928 35 enum AVMediaType type = ost->type;
1929
1930
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (!IS_INTERLEAVED(type))
1931 continue;
1932
1933 35 ms->sq_idx_mux = sq_add_stream(mux->sq_mux,
1934
4/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 10 times.
35 of->shortest || ms->max_frames < INT64_MAX);
1935
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (ms->sq_idx_mux < 0)
1936 return ms->sq_idx_mux;
1937
1938
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 16 times.
35 if (ms->max_frames != INT64_MAX)
1939 19 sq_limit_frames(mux->sq_mux, ms->sq_idx_mux, ms->max_frames);
1940 }
1941 }
1942
1943 #undef IS_AV_ENC
1944 #undef IS_INTERLEAVED
1945
1946 2785 return 0;
1947 }
1948
1949 8 static int of_parse_iamf_audio_element_layers(Muxer *mux, AVStreamGroup *stg, char *ptr)
1950 {
1951 8 AVIAMFAudioElement *audio_element = stg->params.iamf_audio_element;
1952 8 AVDictionary *dict = NULL;
1953 const char *token;
1954 8 int ret = 0;
1955
1956 8 audio_element->demixing_info =
1957 8 av_iamf_param_definition_alloc(AV_IAMF_PARAMETER_DEFINITION_DEMIXING, 1, NULL);
1958 8 audio_element->recon_gain_info =
1959 8 av_iamf_param_definition_alloc(AV_IAMF_PARAMETER_DEFINITION_RECON_GAIN, 1, NULL);
1960
1961
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (!audio_element->demixing_info ||
1962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 !audio_element->recon_gain_info)
1963 return AVERROR(ENOMEM);
1964
1965 /* process manually set layers and parameters */
1966 8 token = av_strtok(NULL, ",", &ptr);
1967
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 while (token) {
1968 const AVDictionaryEntry *e;
1969 32 int demixing = 0, recon_gain = 0;
1970 32 int layer = 0;
1971
1972
1/2
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
32 if (ptr)
1973 32 ptr += strspn(ptr, " \n\t\r");
1974
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 12 times.
32 if (av_strstart(token, "layer=", &token))
1975 20 layer = 1;
1976
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
12 else if (av_strstart(token, "demixing=", &token))
1977 6 demixing = 1;
1978
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 else if (av_strstart(token, "recon_gain=", &token))
1979 6 recon_gain = 1;
1980
1981 32 av_dict_free(&dict);
1982 32 ret = av_dict_parse_string(&dict, token, "=", ":", 0);
1983
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (ret < 0) {
1984 av_log(mux, AV_LOG_ERROR, "Error parsing audio element specification %s\n", token);
1985 goto fail;
1986 }
1987
1988
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 12 times.
32 if (layer) {
1989 20 AVIAMFLayer *audio_layer = av_iamf_audio_element_add_layer(audio_element);
1990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 if (!audio_layer) {
1991 av_log(mux, AV_LOG_ERROR, "Error adding layer to stream group %d\n", stg->index);
1992 ret = AVERROR(ENOMEM);
1993 goto fail;
1994 }
1995 20 av_opt_set_dict(audio_layer, &dict);
1996
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
12 } else if (demixing || recon_gain) {
1997 12 AVIAMFParamDefinition *param = demixing ? audio_element->demixing_info
1998
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 : audio_element->recon_gain_info;
1999 12 void *subblock = av_iamf_param_definition_get_subblock(param, 0);
2000
2001 12 av_opt_set_dict(param, &dict);
2002 12 av_opt_set_dict(subblock, &dict);
2003 }
2004
2005 // make sure that no entries are left in the dict
2006 32 e = NULL;
2007
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 if (e = av_dict_iterate(dict, e)) {
2008 av_log(mux, AV_LOG_FATAL, "Unknown layer key %s.\n", e->key);
2009 ret = AVERROR(EINVAL);
2010 goto fail;
2011 }
2012 32 token = av_strtok(NULL, ",", &ptr);
2013 }
2014
2015 8 fail:
2016 8 av_dict_free(&dict);
2017
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 if (!ret && !audio_element->nb_layers) {
2018 av_log(mux, AV_LOG_ERROR, "No layer in audio element specification\n");
2019 ret = AVERROR(EINVAL);
2020 }
2021
2022 8 return ret;
2023 }
2024
2025 8 static int of_parse_iamf_submixes(Muxer *mux, AVStreamGroup *stg, char *ptr)
2026 {
2027 8 AVFormatContext *oc = mux->fc;
2028 8 AVIAMFMixPresentation *mix = stg->params.iamf_mix_presentation;
2029 8 AVDictionary *dict = NULL;
2030 const char *token;
2031 8 char *submix_str = NULL;
2032 8 int ret = 0;
2033
2034 /* process manually set submixes */
2035 8 token = av_strtok(NULL, ",", &ptr);
2036
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8 times.
18 while (token) {
2037 10 AVIAMFSubmix *submix = NULL;
2038 const char *subtoken;
2039 10 char *subptr = NULL;
2040
2041
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 if (ptr)
2042 10 ptr += strspn(ptr, " \n\t\r");
2043
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if (!av_strstart(token, "submix=", &token)) {
2044 av_log(mux, AV_LOG_ERROR, "No submix in mix presentation specification \"%s\"\n", token);
2045 goto fail;
2046 }
2047
2048 10 submix_str = av_strdup(token);
2049
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!submix_str)
2050 goto fail;
2051
2052 10 submix = av_iamf_mix_presentation_add_submix(mix);
2053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!submix) {
2054 av_log(mux, AV_LOG_ERROR, "Error adding submix to stream group %d\n", stg->index);
2055 ret = AVERROR(ENOMEM);
2056 goto fail;
2057 }
2058 10 submix->output_mix_config =
2059 10 av_iamf_param_definition_alloc(AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN, 0, NULL);
2060
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!submix->output_mix_config) {
2061 ret = AVERROR(ENOMEM);
2062 goto fail;
2063 }
2064
2065 10 subptr = NULL;
2066 10 subtoken = av_strtok(submix_str, "|", &subptr);
2067
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 10 times.
52 while (subtoken) {
2068 const AVDictionaryEntry *e;
2069 42 int element = 0, layout = 0;
2070
2071
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 10 times.
42 if (subptr)
2072 32 subptr += strspn(subptr, " \n\t\r");
2073
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 32 times.
42 if (av_strstart(subtoken, "element=", &subtoken))
2074 10 element = 1;
2075
2/2
✓ Branch 1 taken 22 times.
✓ Branch 2 taken 10 times.
32 else if (av_strstart(subtoken, "layout=", &subtoken))
2076 22 layout = 1;
2077
2078 42 av_dict_free(&dict);
2079 42 ret = av_dict_parse_string(&dict, subtoken, "=", ":", 0);
2080
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (ret < 0) {
2081 av_log(mux, AV_LOG_ERROR, "Error parsing submix specification \"%s\"\n", subtoken);
2082 goto fail;
2083 }
2084
2085
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 32 times.
42 if (element) {
2086 AVIAMFSubmixElement *submix_element;
2087 10 char *endptr = NULL;
2088 10 int64_t idx = -1;
2089
2090
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 if (e = av_dict_get(dict, "stg", NULL, 0))
2091 10 idx = strtoll(e->value, &endptr, 0);
2092
4/8
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
10 if (!endptr || *endptr || idx < 0 || idx >= oc->nb_stream_groups - 1 ||
2093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 oc->stream_groups[idx]->type != AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT) {
2094 av_log(mux, AV_LOG_ERROR, "Invalid or missing stream group index in "
2095 "submix element specification \"%s\"\n", subtoken);
2096 ret = AVERROR(EINVAL);
2097 goto fail;
2098 }
2099 10 submix_element = av_iamf_submix_add_element(submix);
2100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!submix_element) {
2101 av_log(mux, AV_LOG_ERROR, "Error adding element to submix\n");
2102 ret = AVERROR(ENOMEM);
2103 goto fail;
2104 }
2105
2106 10 submix_element->audio_element_id = oc->stream_groups[idx]->id;
2107
2108 10 submix_element->element_mix_config =
2109 10 av_iamf_param_definition_alloc(AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN, 0, NULL);
2110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!submix_element->element_mix_config)
2111 ret = AVERROR(ENOMEM);
2112 10 av_dict_set(&dict, "stg", NULL, 0);
2113 10 av_opt_set_dict2(submix_element, &dict, AV_OPT_SEARCH_CHILDREN);
2114
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 10 times.
32 } else if (layout) {
2115 22 AVIAMFSubmixLayout *submix_layout = av_iamf_submix_add_layout(submix);
2116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (!submix_layout) {
2117 av_log(mux, AV_LOG_ERROR, "Error adding layout to submix\n");
2118 ret = AVERROR(ENOMEM);
2119 goto fail;
2120 }
2121 22 av_opt_set_dict(submix_layout, &dict);
2122 } else
2123 10 av_opt_set_dict2(submix, &dict, AV_OPT_SEARCH_CHILDREN);
2124
2125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42 times.
42 if (ret < 0) {
2126 goto fail;
2127 }
2128
2129 // make sure that no entries are left in the dict
2130 42 e = NULL;
2131
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 42 times.
42 while (e = av_dict_iterate(dict, e)) {
2132 av_log(mux, AV_LOG_FATAL, "Unknown submix key %s.\n", e->key);
2133 ret = AVERROR(EINVAL);
2134 goto fail;
2135 }
2136 42 subtoken = av_strtok(NULL, "|", &subptr);
2137 }
2138 10 av_freep(&submix_str);
2139
2140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if (!submix->nb_elements) {
2141 av_log(mux, AV_LOG_ERROR, "No audio elements in submix specification \"%s\"\n", token);
2142 ret = AVERROR(EINVAL);
2143 }
2144 10 token = av_strtok(NULL, ",", &ptr);
2145 }
2146
2147 8 fail:
2148 8 av_dict_free(&dict);
2149 8 av_free(submix_str);
2150
2151 8 return ret;
2152 }
2153
2154 16 static int of_parse_group_token(Muxer *mux, const char *token, char *ptr)
2155 {
2156 16 AVFormatContext *oc = mux->fc;
2157 AVStreamGroup *stg;
2158 16 AVDictionary *dict = NULL, *tmp = NULL;
2159 const AVDictionaryEntry *e;
2160 16 const AVOption opts[] = {
2161 { "type", "Set group type", offsetof(AVStreamGroup, type), AV_OPT_TYPE_INT,
2162 { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, .unit = "type" },
2163 { "iamf_audio_element", NULL, 0, AV_OPT_TYPE_CONST,
2164 { .i64 = AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT }, .unit = "type" },
2165 { "iamf_mix_presentation", NULL, 0, AV_OPT_TYPE_CONST,
2166 { .i64 = AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION }, .unit = "type" },
2167 { NULL },
2168 };
2169 16 const AVClass class = {
2170 .class_name = "StreamGroupType",
2171 .item_name = av_default_item_name,
2172 .option = opts,
2173 .version = LIBAVUTIL_VERSION_INT,
2174 };
2175 16 const AVClass *pclass = &class;
2176 int type, ret;
2177
2178 16 ret = av_dict_parse_string(&dict, token, "=", ":", AV_DICT_MULTIKEY);
2179
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0) {
2180 av_log(mux, AV_LOG_ERROR, "Error parsing group specification %s\n", token);
2181 return ret;
2182 }
2183
2184 // "type" is not a user settable AVOption in AVStreamGroup, so handle it here
2185 16 e = av_dict_get(dict, "type", NULL, 0);
2186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!e) {
2187 av_log(mux, AV_LOG_ERROR, "No type specified for Stream Group in \"%s\"\n", token);
2188 ret = AVERROR(EINVAL);
2189 goto end;
2190 }
2191
2192 16 ret = av_opt_eval_int(&pclass, opts, e->value, &type);
2193
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 if (!ret && type == AV_STREAM_GROUP_PARAMS_NONE)
2194 ret = AVERROR(EINVAL);
2195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0) {
2196 av_log(mux, AV_LOG_ERROR, "Invalid group type \"%s\"\n", e->value);
2197 goto end;
2198 }
2199
2200 16 av_dict_copy(&tmp, dict, 0);
2201 16 stg = avformat_stream_group_create(oc, type, &tmp);
2202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!stg) {
2203 ret = AVERROR(ENOMEM);
2204 goto end;
2205 }
2206
2207 16 e = NULL;
2208
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 16 times.
52 while (e = av_dict_get(dict, "st", e, 0)) {
2209 char *endptr;
2210 36 int64_t idx = strtoll(e->value, &endptr, 0);
2211
3/6
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 36 times.
36 if (*endptr || idx < 0 || idx >= oc->nb_streams) {
2212 av_log(mux, AV_LOG_ERROR, "Invalid stream index %"PRId64"\n", idx);
2213 ret = AVERROR(EINVAL);
2214 goto end;
2215 }
2216 36 ret = avformat_stream_group_add_stream(stg, oc->streams[idx]);
2217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (ret < 0)
2218 goto end;
2219 }
2220
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 16 times.
24 while (e = av_dict_get(dict, "stg", e, 0)) {
2221 char *endptr;
2222 8 int64_t idx = strtoll(e->value, &endptr, 0);
2223
3/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
8 if (*endptr || idx < 0 || idx >= oc->nb_stream_groups - 1) {
2224 av_log(mux, AV_LOG_ERROR, "Invalid stream group index %"PRId64"\n", idx);
2225 ret = AVERROR(EINVAL);
2226 goto end;
2227 }
2228
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 8 times.
44 for (unsigned i = 0; i < oc->stream_groups[idx]->nb_streams; i++) {
2229 36 ret = avformat_stream_group_add_stream(stg, oc->stream_groups[idx]->streams[i]);
2230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (ret < 0)
2231 goto end;
2232 }
2233 }
2234
2235
2/3
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 switch(type) {
2236 8 case AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT:
2237 8 ret = of_parse_iamf_audio_element_layers(mux, stg, ptr);
2238 8 break;
2239 8 case AV_STREAM_GROUP_PARAMS_IAMF_MIX_PRESENTATION:
2240 8 ret = of_parse_iamf_submixes(mux, stg, ptr);
2241 8 break;
2242 default:
2243 av_log(mux, AV_LOG_FATAL, "Unknown group type %d.\n", type);
2244 ret = AVERROR(EINVAL);
2245 break;
2246 }
2247
2248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0)
2249 goto end;
2250
2251 // make sure that nothing but "st" and "stg" entries are left in the dict
2252 16 e = NULL;
2253 16 av_dict_set(&tmp, "type", NULL, 0);
2254
2/2
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 16 times.
32 while (e = av_dict_iterate(tmp, e)) {
2255
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
16 if (!strcmp(e->key, "st") || !strcmp(e->key, "stg"))
2256 16 continue;
2257
2258 av_log(mux, AV_LOG_FATAL, "Unknown group key %s.\n", e->key);
2259 ret = AVERROR(EINVAL);
2260 goto end;
2261 }
2262
2263 16 ret = 0;
2264 16 end:
2265 16 av_dict_free(&dict);
2266 16 av_dict_free(&tmp);
2267
2268 16 return ret;
2269 }
2270
2271 6757 static int of_add_groups(Muxer *mux, const OptionsContext *o)
2272 {
2273 /* process manually set groups */
2274
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6757 times.
6773 for (int i = 0; i < o->stream_groups.nb_opt; i++) {
2275 const char *token;
2276 16 char *str, *ptr = NULL;
2277 16 int ret = 0;
2278
2279 16 str = av_strdup(o->stream_groups.opt[i].u.str);
2280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!str)
2281 return ret;
2282
2283 16 token = av_strtok(str, ",", &ptr);
2284
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (token) {
2285
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (ptr)
2286 16 ptr += strspn(ptr, " \n\t\r");
2287 16 ret = of_parse_group_token(mux, token, ptr);
2288 }
2289
2290 16 av_free(str);
2291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0)
2292 return ret;
2293 }
2294
2295 6757 return 0;
2296 }
2297
2298 6757 static int of_add_programs(Muxer *mux, const OptionsContext *o)
2299 {
2300 6757 AVFormatContext *oc = mux->fc;
2301 /* process manually set programs */
2302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 for (int i = 0; i < o->program.nb_opt; i++) {
2303 AVDictionary *dict = NULL;
2304 const AVDictionaryEntry *e;
2305 AVProgram *program;
2306 int ret, progid = i + 1;
2307
2308 ret = av_dict_parse_string(&dict, o->program.opt[i].u.str, "=", ":",
2309 AV_DICT_MULTIKEY);
2310 if (ret < 0) {
2311 av_log(mux, AV_LOG_ERROR, "Error parsing program specification %s\n",
2312 o->program.opt[i].u.str);
2313 return ret;
2314 }
2315
2316 e = av_dict_get(dict, "program_num", NULL, 0);
2317 if (e) {
2318 progid = strtol(e->value, NULL, 0);
2319 av_dict_set(&dict, e->key, NULL, 0);
2320 }
2321
2322 program = av_new_program(oc, progid);
2323 if (!program) {
2324 ret = AVERROR(ENOMEM);
2325 goto fail;
2326 }
2327
2328 e = av_dict_get(dict, "title", NULL, 0);
2329 if (e) {
2330 av_dict_set(&program->metadata, e->key, e->value, 0);
2331 av_dict_set(&dict, e->key, NULL, 0);
2332 }
2333
2334 e = NULL;
2335 while (e = av_dict_get(dict, "st", e, 0)) {
2336 int st_num = strtol(e->value, NULL, 0);
2337 av_program_add_stream_index(oc, progid, st_num);
2338 }
2339
2340 // make sure that nothing but "st" entries are left in the dict
2341 e = NULL;
2342 while (e = av_dict_iterate(dict, e)) {
2343 if (!strcmp(e->key, "st"))
2344 continue;
2345
2346 av_log(mux, AV_LOG_FATAL, "Unknown program key %s.\n", e->key);
2347 ret = AVERROR(EINVAL);
2348 goto fail;
2349 }
2350
2351 fail:
2352 av_dict_free(&dict);
2353 if (ret < 0)
2354 return ret;
2355 }
2356
2357 6757 return 0;
2358 }
2359
2360 /**
2361 * Parse a metadata specifier passed as 'arg' parameter.
2362 * @param arg metadata string to parse
2363 * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
2364 * @param index for type c/p, chapter/program index is written here
2365 * @param stream_spec for type s, the stream specifier is written here
2366 */
2367 230 static int parse_meta_type(void *logctx, const char *arg,
2368 char *type, int *index, const char **stream_spec)
2369 {
2370
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 159 times.
230 if (*arg) {
2371 71 *type = *arg;
2372
3/4
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 46 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
71 switch (*arg) {
2373 21 case 'g':
2374 21 break;
2375 46 case 's':
2376
2/4
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 46 times.
46 if (*(++arg) && *arg != ':') {
2377 av_log(logctx, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
2378 return AVERROR(EINVAL);
2379 }
2380
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 *stream_spec = *arg == ':' ? arg + 1 : "";
2381 46 break;
2382 4 case 'c':
2383 case 'p':
2384
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 if (*(++arg) == ':')
2385 3 *index = strtol(++arg, NULL, 0);
2386 4 break;
2387 default:
2388 av_log(logctx, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
2389 return AVERROR(EINVAL);
2390 }
2391 } else
2392 159 *type = 'g';
2393
2394 230 return 0;
2395 }
2396
2397 6757 static int of_add_metadata(OutputFile *of, AVFormatContext *oc,
2398 const OptionsContext *o)
2399 {
2400
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 6757 times.
6973 for (int i = 0; i < o->metadata.nb_opt; i++) {
2401 AVDictionary **m;
2402 char type, *val;
2403 const char *stream_spec;
2404 216 int index = 0, ret = 0;
2405
2406 216 val = strchr(o->metadata.opt[i].u.str, '=');
2407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if (!val) {
2408 av_log(of, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
2409 o->metadata.opt[i].u.str);
2410 return AVERROR(EINVAL);
2411 }
2412 216 *val++ = 0;
2413
2414 216 ret = parse_meta_type(of, o->metadata.opt[i].specifier, &type, &index, &stream_spec);
2415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if (ret < 0)
2416 return ret;
2417
2418
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 175 times.
216 if (type == 's') {
2419
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 41 times.
260 for (int j = 0; j < oc->nb_streams; j++) {
2420
2/2
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 178 times.
219 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
2421
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 av_dict_set(&oc->streams[j]->metadata, o->metadata.opt[i].u.str, *val ? val : NULL, 0);
2422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 178 times.
178 } else if (ret < 0)
2423 return ret;
2424 }
2425 } else {
2426
2/4
✓ Branch 0 taken 171 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
175 switch (type) {
2427 171 case 'g':
2428 171 m = &oc->metadata;
2429 171 break;
2430 4 case 'c':
2431
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (index < 0 || index >= oc->nb_chapters) {
2432 av_log(of, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
2433 return AVERROR(EINVAL);
2434 }
2435 4 m = &oc->chapters[index]->metadata;
2436 4 break;
2437 case 'p':
2438 if (index < 0 || index >= oc->nb_programs) {
2439 av_log(of, AV_LOG_FATAL, "Invalid program index %d in metadata specifier.\n", index);
2440 return AVERROR(EINVAL);
2441 }
2442 m = &oc->programs[index]->metadata;
2443 break;
2444 default:
2445 av_log(of, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata.opt[i].specifier);
2446 return AVERROR(EINVAL);
2447 }
2448
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 1 times.
175 av_dict_set(m, o->metadata.opt[i].u.str, *val ? val : NULL, 0);
2449 }
2450 }
2451
2452 6757 return 0;
2453 }
2454
2455 19 static int copy_chapters(InputFile *ifile, OutputFile *ofile, AVFormatContext *os,
2456 int copy_metadata)
2457 {
2458 19 AVFormatContext *is = ifile->ctx;
2459 AVChapter **tmp;
2460
2461 19 tmp = av_realloc_f(os->chapters, is->nb_chapters + os->nb_chapters, sizeof(*os->chapters));
2462
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19 times.
19 if (!tmp)
2463 return AVERROR(ENOMEM);
2464 19 os->chapters = tmp;
2465
2466
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 16 times.
53 for (int i = 0; i < is->nb_chapters; i++) {
2467 37 AVChapter *in_ch = is->chapters[i], *out_ch;
2468
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
2469 37 int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
2470 37 AV_TIME_BASE_Q, in_ch->time_base);
2471
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 32 times.
37 int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
2472 5 av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
2473
2474
2475
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if (in_ch->end < ts_off)
2476 continue;
2477
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 2 times.
37 if (rt != INT64_MAX && in_ch->start > rt + ts_off)
2478 3 break;
2479
2480 34 out_ch = av_mallocz(sizeof(AVChapter));
2481
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if (!out_ch)
2482 return AVERROR(ENOMEM);
2483
2484 34 out_ch->id = in_ch->id;
2485 34 out_ch->time_base = in_ch->time_base;
2486 34 out_ch->start = FFMAX(0, in_ch->start - ts_off);
2487 34 out_ch->end = FFMIN(rt, in_ch->end - ts_off);
2488
2489
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 if (copy_metadata)
2490 34 av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
2491
2492 34 os->chapters[os->nb_chapters++] = out_ch;
2493 }
2494 19 return 0;
2495 }
2496
2497 7 static int copy_metadata(Muxer *mux, AVFormatContext *ic,
2498 const char *outspec, const char *inspec,
2499 int *metadata_global_manual, int *metadata_streams_manual,
2500 int *metadata_chapters_manual)
2501 {
2502 7 AVFormatContext *oc = mux->fc;
2503 7 AVDictionary **meta_in = NULL;
2504 7 AVDictionary **meta_out = NULL;
2505 7 int i, ret = 0;
2506 char type_in, type_out;
2507 7 const char *istream_spec = NULL, *ostream_spec = NULL;
2508 7 int idx_in = 0, idx_out = 0;
2509
2510 7 ret = parse_meta_type(mux, inspec, &type_in, &idx_in, &istream_spec);
2511
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (ret >= 0)
2512 7 ret = parse_meta_type(mux, outspec, &type_out, &idx_out, &ostream_spec);
2513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (ret < 0)
2514 return ret;
2515
2516
4/8
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
7 if (type_in == 'g' || type_out == 'g' || (!*outspec && !ic))
2517 5 *metadata_global_manual = 1;
2518
7/8
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
7 if (type_in == 's' || type_out == 's' || (!*outspec && !ic))
2519 3 *metadata_streams_manual = 1;
2520
5/8
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
7 if (type_in == 'c' || type_out == 'c' || (!*outspec && !ic))
2521 *metadata_chapters_manual = 1;
2522
2523 /* ic is NULL when just disabling automatic mappings */
2524
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 if (!ic)
2525 2 return 0;
2526
2527 #define METADATA_CHECK_INDEX(index, nb_elems, desc)\
2528 if ((index) < 0 || (index) >= (nb_elems)) {\
2529 av_log(mux, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
2530 (desc), (index));\
2531 return AVERROR(EINVAL);\
2532 }
2533
2534 #define SET_DICT(type, meta, context, index)\
2535 switch (type) {\
2536 case 'g':\
2537 meta = &context->metadata;\
2538 break;\
2539 case 'c':\
2540 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
2541 meta = &context->chapters[index]->metadata;\
2542 break;\
2543 case 'p':\
2544 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
2545 meta = &context->programs[index]->metadata;\
2546 break;\
2547 case 's':\
2548 break; /* handled separately below */ \
2549 default: av_assert0(0);\
2550 }\
2551
2552
2/13
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5 SET_DICT(type_in, meta_in, ic, idx_in);
2553
2/13
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5 SET_DICT(type_out, meta_out, oc, idx_out);
2554
2555 /* for input streams choose first matching stream */
2556
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if (type_in == 's') {
2557
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 for (i = 0; i < ic->nb_streams; i++) {
2558
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
3 if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
2559 2 meta_in = &ic->streams[i]->metadata;
2560 2 break;
2561
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 } else if (ret < 0)
2562 return ret;
2563 }
2564
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!meta_in) {
2565 av_log(mux, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
2566 return AVERROR(EINVAL);
2567 }
2568 }
2569
2570
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if (type_out == 's') {
2571
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 for (i = 0; i < oc->nb_streams; i++) {
2572
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
8 if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
2573 3 meta_out = &oc->streams[i]->metadata;
2574 3 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
2575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 } else if (ret < 0)
2576 return ret;
2577 }
2578 } else
2579 2 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
2580
2581 5 return 0;
2582 }
2583
2584 6757 static int copy_meta(Muxer *mux, const OptionsContext *o)
2585 {
2586 6757 OutputFile *of = &mux->of;
2587 6757 AVFormatContext *oc = mux->fc;
2588 6757 int chapters_input_file = o->chapters_input_file;
2589 6757 int metadata_global_manual = 0;
2590 6757 int metadata_streams_manual = 0;
2591 6757 int metadata_chapters_manual = 0;
2592 int ret;
2593
2594 /* copy metadata */
2595
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6757 times.
6764 for (int i = 0; i < o->metadata_map.nb_opt; i++) {
2596 char *p;
2597 7 int in_file_index = strtol(o->metadata_map.opt[i].u.str, &p, 0);
2598
2599
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (in_file_index >= nb_input_files) {
2600 av_log(mux, AV_LOG_FATAL, "Invalid input file index %d while "
2601 "processing metadata maps\n", in_file_index);
2602 return AVERROR(EINVAL);
2603 }
2604 10 ret = copy_metadata(mux,
2605 5 in_file_index >= 0 ? input_files[in_file_index]->ctx : NULL,
2606
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 2 times.
10 o->metadata_map.opt[i].specifier, *p ? p + 1 : p,
2607 &metadata_global_manual, &metadata_streams_manual,
2608 &metadata_chapters_manual);
2609
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (ret < 0)
2610 return ret;
2611 }
2612
2613 /* copy chapters */
2614
1/2
✓ Branch 0 taken 6757 times.
✗ Branch 1 not taken.
6757 if (chapters_input_file >= nb_input_files) {
2615
1/2
✓ Branch 0 taken 6757 times.
✗ Branch 1 not taken.
6757 if (chapters_input_file == INT_MAX) {
2616 /* copy chapters from the first input file that has them*/
2617 6757 chapters_input_file = -1;
2618
2/2
✓ Branch 0 taken 6788 times.
✓ Branch 1 taken 6738 times.
13526 for (int i = 0; i < nb_input_files; i++)
2619
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 6769 times.
6788 if (input_files[i]->ctx->nb_chapters) {
2620 19 chapters_input_file = i;
2621 19 break;
2622 }
2623 } else {
2624 av_log(mux, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
2625 chapters_input_file);
2626 return AVERROR(EINVAL);
2627 }
2628 }
2629
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 6738 times.
6757 if (chapters_input_file >= 0)
2630 19 copy_chapters(input_files[chapters_input_file], of, oc,
2631 !metadata_chapters_manual);
2632
2633 /* copy global metadata by default */
2634
4/4
✓ Branch 0 taken 6753 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 6699 times.
✓ Branch 3 taken 54 times.
6757 if (!metadata_global_manual && nb_input_files){
2635 6699 av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
2636 AV_DICT_DONT_OVERWRITE);
2637
2/2
✓ Branch 0 taken 179 times.
✓ Branch 1 taken 6520 times.
6699 if (of->recording_time != INT64_MAX)
2638 179 av_dict_set(&oc->metadata, "duration", NULL, 0);
2639 6699 av_dict_set(&oc->metadata, "creation_time", NULL, 0);
2640 6699 av_dict_set(&oc->metadata, "company_name", NULL, 0);
2641 6699 av_dict_set(&oc->metadata, "product_name", NULL, 0);
2642 6699 av_dict_set(&oc->metadata, "product_version", NULL, 0);
2643 }
2644
2/2
✓ Branch 0 taken 6755 times.
✓ Branch 1 taken 2 times.
6757 if (!metadata_streams_manual)
2645
2/2
✓ Branch 0 taken 7094 times.
✓ Branch 1 taken 6755 times.
13849 for (int i = 0; i < of->nb_streams; i++) {
2646 7094 OutputStream *ost = of->streams[i];
2647
2648
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 6926 times.
7094 if (!ost->ist) /* this is true e.g. for attached files */
2649 168 continue;
2650 6926 av_dict_copy(&ost->st->metadata, ost->ist->st->metadata, AV_DICT_DONT_OVERWRITE);
2651
2/2
✓ Branch 0 taken 6300 times.
✓ Branch 1 taken 626 times.
6926 if (ost->enc_ctx) {
2652 6300 av_dict_set(&ost->st->metadata, "encoder", NULL, 0);
2653 }
2654 }
2655
2656 6757 return 0;
2657 }
2658
2659 6757 static int set_dispositions(Muxer *mux, const OptionsContext *o)
2660 {
2661 6757 OutputFile *of = &mux->of;
2662 6757 AVFormatContext *ctx = mux->fc;
2663
2664 // indexed by type+1, because AVMEDIA_TYPE_UNKNOWN=-1
2665 6757 int nb_streams[AVMEDIA_TYPE_NB + 1] = { 0 };
2666 6757 int have_default[AVMEDIA_TYPE_NB + 1] = { 0 };
2667 6757 int have_manual = 0;
2668 6757 int ret = 0;
2669
2670 const char **dispositions;
2671
2672 6757 dispositions = av_calloc(ctx->nb_streams, sizeof(*dispositions));
2673
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (!dispositions)
2674 return AVERROR(ENOMEM);
2675
2676 // first, copy the input dispositions
2677
2/2
✓ Branch 0 taken 7099 times.
✓ Branch 1 taken 6757 times.
13856 for (int i = 0; i < ctx->nb_streams; i++) {
2678 7099 OutputStream *ost = of->streams[i];
2679
2680 7099 nb_streams[ost->type + 1]++;
2681
2682
6/20
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 43 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 43 times.
✓ Branch 5 taken 59 times.
✓ Branch 6 taken 7099 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7099 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7158 MATCH_PER_STREAM_OPT(disposition, str, dispositions[i], ctx, ost->st);
2683
2684 7099 have_manual |= !!dispositions[i];
2685
2686
2/2
✓ Branch 0 taken 6931 times.
✓ Branch 1 taken 168 times.
7099 if (ost->ist) {
2687 6931 ost->st->disposition = ost->ist->st->disposition;
2688
2689
2/2
✓ Branch 0 taken 766 times.
✓ Branch 1 taken 6165 times.
6931 if (ost->st->disposition & AV_DISPOSITION_DEFAULT)
2690 766 have_default[ost->type + 1] = 1;
2691 }
2692 }
2693
2694
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6749 times.
6757 if (have_manual) {
2695 // process manually set dispositions - they override the above copy
2696
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 8 times.
31 for (int i = 0; i < ctx->nb_streams; i++) {
2697 23 OutputStream *ost = of->streams[i];
2698 23 const char *disp = dispositions[i];
2699
2700
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 16 times.
23 if (!disp)
2701 7 continue;
2702
2703 16 ret = av_opt_set(ost->st, "disposition", disp, 0);
2704
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ret < 0)
2705 goto finish;
2706 }
2707 } else {
2708 // For each media type with more than one stream, find a suitable stream to
2709 // mark as default, unless one is already marked default.
2710 // "Suitable" means the first of that type, skipping attached pictures.
2711
2/2
✓ Branch 0 taken 7076 times.
✓ Branch 1 taken 6749 times.
13825 for (int i = 0; i < ctx->nb_streams; i++) {
2712 7076 OutputStream *ost = of->streams[i];
2713 7076 enum AVMediaType type = ost->type;
2714
2715
4/4
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 6850 times.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 164 times.
7076 if (nb_streams[type + 1] < 2 || have_default[type + 1] ||
2716
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 30 times.
62 ost->st->disposition & AV_DISPOSITION_ATTACHED_PIC)
2717 7046 continue;
2718
2719 30 ost->st->disposition |= AV_DISPOSITION_DEFAULT;
2720 30 have_default[type + 1] = 1;
2721 }
2722 }
2723
2724 6749 finish:
2725 6757 av_freep(&dispositions);
2726
2727 6757 return ret;
2728 }
2729
2730 const char *const forced_keyframes_const_names[] = {
2731 "n",
2732 "n_forced",
2733 "prev_forced_n",
2734 "prev_forced_t",
2735 "t",
2736 NULL
2737 };
2738
2739 1 static int compare_int64(const void *a, const void *b)
2740 {
2741 1 return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
2742 }
2743
2744 1 static int parse_forced_key_frames(void *log, KeyframeForceCtx *kf,
2745 const Muxer *mux, const char *spec)
2746 {
2747 const char *p;
2748 1 int n = 1, i, ret, size, index = 0;
2749 int64_t t, *pts;
2750
2751
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
14 for (p = spec; *p; p++)
2752
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
13 if (*p == ',')
2753 1 n++;
2754 1 size = n;
2755 1 pts = av_malloc_array(size, sizeof(*pts));
2756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!pts)
2757 return AVERROR(ENOMEM);
2758
2759 1 p = spec;
2760
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 for (i = 0; i < n; i++) {
2761 2 char *next = strchr(p, ',');
2762
2763
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (next)
2764 1 *next++ = 0;
2765
2766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (strstr(p, "chapters") == p) {
2767 AVChapter * const *ch = mux->fc->chapters;
2768 unsigned int nb_ch = mux->fc->nb_chapters;
2769 int j;
2770
2771 if (nb_ch > INT_MAX - size ||
2772 !(pts = av_realloc_f(pts, size += nb_ch - 1,
2773 sizeof(*pts))))
2774 return AVERROR(ENOMEM);
2775
2776 if (p[8]) {
2777 ret = av_parse_time(&t, p + 8, 1);
2778 if (ret < 0) {
2779 av_log(log, AV_LOG_ERROR,
2780 "Invalid chapter time offset: %s\n", p + 8);
2781 goto fail;
2782 }
2783 } else
2784 t = 0;
2785
2786 for (j = 0; j < nb_ch; j++) {
2787 const AVChapter *c = ch[j];
2788 av_assert1(index < size);
2789 pts[index++] = av_rescale_q(c->start, c->time_base,
2790 AV_TIME_BASE_Q) + t;
2791 }
2792
2793 } else {
2794 av_assert1(index < size);
2795 2 ret = av_parse_time(&t, p, 1);
2796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0) {
2797 av_log(log, AV_LOG_ERROR, "Invalid keyframe time: %s\n", p);
2798 goto fail;
2799 }
2800
2801 2 pts[index++] = t;
2802 }
2803
2804 2 p = next;
2805 }
2806
2807
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 av_assert0(index == size);
2808 1 qsort(pts, size, sizeof(*pts), compare_int64);
2809 1 kf->nb_pts = size;
2810 1 kf->pts = pts;
2811
2812 1 return 0;
2813 fail:
2814 av_freep(&pts);
2815 return ret;
2816 }
2817
2818 6757 static int process_forced_keyframes(Muxer *mux, const OptionsContext *o)
2819 {
2820
2/2
✓ Branch 0 taken 7099 times.
✓ Branch 1 taken 6757 times.
13856 for (int i = 0; i < mux->of.nb_streams; i++) {
2821 7099 OutputStream *ost = mux->of.streams[i];
2822 7099 const char *forced_keyframes = NULL;
2823
2824
4/20
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 7099 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 7099 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
7103 MATCH_PER_STREAM_OPT(forced_key_frames, str, forced_keyframes, mux->fc, ost->st);
2825
2826
4/4
✓ Branch 0 taken 5523 times.
✓ Branch 1 taken 1576 times.
✓ Branch 2 taken 5188 times.
✓ Branch 3 taken 4 times.
12291 if (!(ost->type == AVMEDIA_TYPE_VIDEO &&
2827
2/2
✓ Branch 0 taken 5192 times.
✓ Branch 1 taken 331 times.
5523 ost->enc_ctx && forced_keyframes))
2828 7095 continue;
2829
2830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!strncmp(forced_keyframes, "expr:", 5)) {
2831 int ret = av_expr_parse(&ost->kf.pexpr, forced_keyframes + 5,
2832 forced_keyframes_const_names, NULL, NULL, NULL, NULL, 0, NULL);
2833 if (ret < 0) {
2834 av_log(ost, AV_LOG_ERROR,
2835 "Invalid force_key_frames expression '%s'\n", forced_keyframes + 5);
2836 return ret;
2837 }
2838 ost->kf.expr_const_values[FKF_N] = 0;
2839 ost->kf.expr_const_values[FKF_N_FORCED] = 0;
2840 ost->kf.expr_const_values[FKF_PREV_FORCED_N] = NAN;
2841 ost->kf.expr_const_values[FKF_PREV_FORCED_T] = NAN;
2842
2843 // Don't parse the 'forced_keyframes' in case of 'keep-source-keyframes',
2844 // parse it only for static kf timings
2845
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 } else if (!strcmp(forced_keyframes, "source")) {
2846 3 ost->kf.type = KF_FORCE_SOURCE;
2847 #if FFMPEG_OPT_FORCE_KF_SOURCE_NO_DROP
2848
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 } else if (!strcmp(forced_keyframes, "source_no_drop")) {
2849 av_log(ost, AV_LOG_WARNING, "The 'source_no_drop' value for "
2850 "-force_key_frames is deprecated, use just 'source'\n");
2851 ost->kf.type = KF_FORCE_SOURCE;
2852 #endif
2853 } else {
2854 1 int ret = parse_forced_key_frames(ost, &ost->kf, mux, forced_keyframes);
2855
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ret < 0)
2856 return ret;
2857 }
2858 }
2859
2860 6757 return 0;
2861 }
2862
2863 6757 static int validate_enc_avopt(Muxer *mux, const AVDictionary *codec_avopt)
2864 {
2865 6757 const AVClass *class = avcodec_get_class();
2866 6757 const AVClass *fclass = avformat_get_class();
2867 6757 const OutputFile *of = &mux->of;
2868
2869 AVDictionary *unused_opts;
2870 const AVDictionaryEntry *e;
2871
2872 6757 unused_opts = strip_specifiers(codec_avopt);
2873
2/2
✓ Branch 0 taken 7099 times.
✓ Branch 1 taken 6757 times.
13856 for (int i = 0; i < of->nb_streams; i++) {
2874 7099 e = NULL;
2875
2/2
✓ Branch 1 taken 15711 times.
✓ Branch 2 taken 7099 times.
22810 while ((e = av_dict_iterate(of->streams[i]->encoder_opts, e)))
2876 15711 av_dict_set(&unused_opts, e->key, NULL, 0);
2877 }
2878
2879 6757 e = NULL;
2880
2/2
✓ Branch 1 taken 1094 times.
✓ Branch 2 taken 6757 times.
7851 while ((e = av_dict_iterate(unused_opts, e))) {
2881 1094 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
2882 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
2883 1094 const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
2884 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
2885
4/4
✓ Branch 0 taken 1093 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1089 times.
1094 if (!option || foption)
2886 5 continue;
2887
2888
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1089 times.
1089 if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
2889 av_log(mux, AV_LOG_ERROR, "Codec AVOption %s (%s) is not an "
2890 "encoding option.\n", e->key, option->help ? option->help : "");
2891 return AVERROR(EINVAL);
2892 }
2893
2894 // gop_timecode is injected by generic code but not always used
2895
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1081 times.
1089 if (!strcmp(e->key, "gop_timecode"))
2896 8 continue;
2897
2898 1081 av_log(mux, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
2899 "for any stream. The most likely reason is either wrong type "
2900 "(e.g. a video option with no video streams) or that it is a "
2901 "private option of some encoder which was not actually used for "
2902
2/2
✓ Branch 0 taken 890 times.
✓ Branch 1 taken 191 times.
2162 "any stream.\n", e->key, option->help ? option->help : "");
2903 }
2904 6757 av_dict_free(&unused_opts);
2905
2906 6757 return 0;
2907 }
2908
2909 7862 static const char *output_file_item_name(void *obj)
2910 {
2911 7862 const Muxer *mux = obj;
2912
2913 7862 return mux->log_name;
2914 }
2915
2916 static const AVClass output_file_class = {
2917 .class_name = "OutputFile",
2918 .version = LIBAVUTIL_VERSION_INT,
2919 .item_name = output_file_item_name,
2920 .category = AV_CLASS_CATEGORY_MUXER,
2921 };
2922
2923 6757 static Muxer *mux_alloc(void)
2924 {
2925 6757 Muxer *mux = allocate_array_elem(&output_files, sizeof(*mux), &nb_output_files);
2926
2927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (!mux)
2928 return NULL;
2929
2930 6757 mux->of.class = &output_file_class;
2931 6757 mux->of.index = nb_output_files - 1;
2932
2933 6757 snprintf(mux->log_name, sizeof(mux->log_name), "out#%d", mux->of.index);
2934
2935 6757 return mux;
2936 }
2937
2938 6757 int of_open(const OptionsContext *o, const char *filename, Scheduler *sch)
2939 {
2940 Muxer *mux;
2941 AVFormatContext *oc;
2942 int err;
2943 OutputFile *of;
2944
2945 6757 int64_t recording_time = o->recording_time;
2946 6757 int64_t stop_time = o->stop_time;
2947
2948 6757 mux = mux_alloc();
2949
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (!mux)
2950 return AVERROR(ENOMEM);
2951
2952 6757 of = &mux->of;
2953
2954
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6757 if (stop_time != INT64_MAX && recording_time != INT64_MAX) {
2955 stop_time = INT64_MAX;
2956 av_log(mux, AV_LOG_WARNING, "-t and -to cannot be used together; using -t.\n");
2957 }
2958
2959
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6757 if (stop_time != INT64_MAX && recording_time == INT64_MAX) {
2960 int64_t start_time = o->start_time == AV_NOPTS_VALUE ? 0 : o->start_time;
2961 if (stop_time <= start_time) {
2962 av_log(mux, AV_LOG_ERROR, "-to value smaller than -ss; aborting.\n");
2963 return AVERROR(EINVAL);
2964 } else {
2965 recording_time = stop_time - start_time;
2966 }
2967 }
2968
2969 6757 of->recording_time = recording_time;
2970 6757 of->start_time = o->start_time;
2971 6757 of->shortest = o->shortest;
2972
2973 6757 mux->limit_filesize = o->limit_filesize;
2974 6757 av_dict_copy(&mux->opts, o->g->format_opts, 0);
2975
2976
2/2
✓ Branch 0 taken 2590 times.
✓ Branch 1 taken 4167 times.
6757 if (!strcmp(filename, "-"))
2977 2590 filename = "pipe:";
2978
2979 6757 err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
2980
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (!oc) {
2981 av_log(mux, AV_LOG_FATAL, "Error initializing the muxer for %s: %s\n",
2982 filename, av_err2str(err));
2983 return err;
2984 }
2985 6757 mux->fc = oc;
2986
2987 6757 av_strlcat(mux->log_name, "/", sizeof(mux->log_name));
2988 6757 av_strlcat(mux->log_name, oc->oformat->name, sizeof(mux->log_name));
2989
2990
2991 6757 of->format = oc->oformat;
2992
2/2
✓ Branch 0 taken 185 times.
✓ Branch 1 taken 6572 times.
6757 if (recording_time != INT64_MAX)
2993 185 oc->duration = recording_time;
2994
2995 6757 oc->interrupt_callback = int_cb;
2996
2997
2/2
✓ Branch 0 taken 1793 times.
✓ Branch 1 taken 4964 times.
6757 if (o->bitexact) {
2998 1793 oc->flags |= AVFMT_FLAG_BITEXACT;
2999 1793 of->bitexact = 1;
3000 } else {
3001 4964 of->bitexact = check_opt_bitexact(oc, mux->opts, "fflags",
3002 AVFMT_FLAG_BITEXACT);
3003 }
3004
3005 6757 err = sch_add_mux(sch, muxer_thread, mux_check_init, mux,
3006 6757 !strcmp(oc->oformat->name, "rtp"), o->thread_queue_size);
3007
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0)
3008 return err;
3009 6757 mux->sch = sch;
3010 6757 mux->sch_idx = err;
3011
3012 /* create all output streams for this file */
3013 6757 err = create_streams(mux, o);
3014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0)
3015 return err;
3016
3017 /* check if all codec options have been used */
3018 6757 err = validate_enc_avopt(mux, o->g->codec_opts);
3019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0)
3020 return err;
3021
3022 /* check filename in case of an image number is expected */
3023
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
6757 if (oc->oformat->flags & AVFMT_NEEDNUMBER && !av_filename_number_test(oc->url)) {
3024 av_log(mux, AV_LOG_FATAL,
3025 "Output filename '%s' does not contain a numeric pattern like "
3026 "'%%d', which is required by output format '%s'.\n",
3027 oc->url, oc->oformat->name);
3028 return AVERROR(EINVAL);
3029 }
3030
3031
2/2
✓ Branch 0 taken 6666 times.
✓ Branch 1 taken 91 times.
6757 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
3032 /* test if it already exists to avoid losing precious files */
3033 6666 err = assert_file_overwrite(filename);
3034
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6666 times.
6666 if (err < 0)
3035 return err;
3036
3037 /* open the file */
3038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6666 times.
6666 if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
3039 6666 &oc->interrupt_callback,
3040 &mux->opts)) < 0) {
3041 av_log(mux, AV_LOG_FATAL, "Error opening output %s: %s\n",
3042 filename, av_err2str(err));
3043 return err;
3044 }
3045
4/4
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 33 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 51 times.
91 } else if (strcmp(oc->oformat->name, "image2")==0 && !av_filename_number_test(filename)) {
3046 7 err = assert_file_overwrite(filename);
3047
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (err < 0)
3048 return err;
3049 }
3050
3051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (o->mux_preload) {
3052 av_dict_set_int(&mux->opts, "preload", o->mux_preload*AV_TIME_BASE, 0);
3053 }
3054 6757 oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
3055
3056 /* copy metadata and chapters from input files */
3057 6757 err = copy_meta(mux, o);
3058
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0)
3059 return err;
3060
3061 6757 err = of_add_groups(mux, o);
3062
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0)
3063 return err;
3064
3065 6757 err = of_add_programs(mux, o);
3066
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0)
3067 return err;
3068
3069 6757 err = of_add_metadata(of, oc, o);
3070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0)
3071 return err;
3072
3073 6757 err = set_dispositions(mux, o);
3074
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0) {
3075 av_log(mux, AV_LOG_FATAL, "Error setting output stream dispositions\n");
3076 return err;
3077 }
3078
3079 // parse forced keyframe specifications;
3080 // must be done after chapters are created
3081 6757 err = process_forced_keyframes(mux, o);
3082
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0) {
3083 av_log(mux, AV_LOG_FATAL, "Error processing forced keyframes\n");
3084 return err;
3085 }
3086
3087 6757 err = setup_sync_queues(mux, oc, o->shortest_buf_duration * AV_TIME_BASE);
3088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6757 times.
6757 if (err < 0) {
3089 av_log(mux, AV_LOG_FATAL, "Error setting up output sync queues\n");
3090 return err;
3091 }
3092
3093 6757 of->url = filename;
3094
3095 /* initialize streamcopy streams. */
3096
2/2
✓ Branch 0 taken 7099 times.
✓ Branch 1 taken 6757 times.
13856 for (int i = 0; i < of->nb_streams; i++) {
3097 7099 OutputStream *ost = of->streams[i];
3098
3099
2/2
✓ Branch 0 taken 628 times.
✓ Branch 1 taken 6471 times.
7099 if (!ost->enc) {
3100 628 err = of_stream_init(of, ost);
3101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 628 times.
628 if (err < 0)
3102 return err;
3103 }
3104 }
3105
3106 6757 return 0;
3107 }
3108