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 | 6091 | static int check_opt_bitexact(void *ctx, const AVDictionary *opts, | |
54 | const char *opt_name, int flag) | ||
55 | { | ||
56 | 6091 | const AVDictionaryEntry *e = av_dict_get(opts, opt_name, NULL, 0); | |
57 | |||
58 |
2/2✓ Branch 0 taken 5118 times.
✓ Branch 1 taken 973 times.
|
6091 | if (e) { |
59 | 5118 | const AVOption *o = av_opt_find(ctx, opt_name, NULL, 0, 0); | |
60 | 5118 | int val = 0; | |
61 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5118 times.
|
5118 | if (!o) |
62 | ✗ | return 0; | |
63 | 5118 | av_opt_eval_flags(ctx, o, e->value, &val); | |
64 | 5118 | return !!(val & flag); | |
65 | } | ||
66 | 973 | return 0; | |
67 | } | ||
68 | |||
69 | 8357 | static int choose_encoder(const OptionsContext *o, AVFormatContext *s, | |
70 | MuxStream *ms, const AVCodec **enc) | ||
71 | { | ||
72 | 8357 | OutputStream *ost = &ms->ost; | |
73 | 8357 | enum AVMediaType type = ost->type; | |
74 | 8357 | const char *codec_name = NULL; | |
75 | |||
76 | 8357 | *enc = NULL; | |
77 | |||
78 | 8357 | opt_match_per_stream_str(ost, &o->codec_names, s, ost->st, &codec_name); | |
79 | |||
80 |
4/4✓ Branch 0 taken 1676 times.
✓ Branch 1 taken 6681 times.
✓ Branch 2 taken 82 times.
✓ Branch 3 taken 1594 times.
|
8357 | if (type != AVMEDIA_TYPE_VIDEO && |
81 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 71 times.
|
82 | type != AVMEDIA_TYPE_AUDIO && |
82 | type != AVMEDIA_TYPE_SUBTITLE) { | ||
83 |
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")) { |
84 | ✗ | const char *type_str = av_get_media_type_string(type); | |
85 | ✗ | av_log(ost, AV_LOG_FATAL, | |
86 | "Encoder '%s' specified, but only '-codec copy' supported " | ||
87 | "for %s streams\n", codec_name, type_str); | ||
88 | ✗ | return AVERROR(ENOSYS); | |
89 | } | ||
90 | 11 | return 0; | |
91 | } | ||
92 | |||
93 |
2/2✓ Branch 0 taken 3776 times.
✓ Branch 1 taken 4570 times.
|
8346 | if (!codec_name) { |
94 | 3776 | ms->par_in->codec_id = av_guess_codec(s->oformat, NULL, s->url, NULL, ost->type); | |
95 | 3776 | *enc = avcodec_find_encoder(ms->par_in->codec_id); | |
96 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3776 times.
|
3776 | if (!*enc) { |
97 | ✗ | av_log(ost, AV_LOG_FATAL, "Automatic encoder selection failed " | |
98 | "Default encoder for format %s (codec %s) is " | ||
99 | "probably disabled. Please choose an encoder manually.\n", | ||
100 | ✗ | s->oformat->name, avcodec_get_name(ms->par_in->codec_id)); | |
101 | ✗ | return AVERROR_ENCODER_NOT_FOUND; | |
102 | } | ||
103 |
2/2✓ Branch 0 taken 3920 times.
✓ Branch 1 taken 650 times.
|
4570 | } else if (strcmp(codec_name, "copy")) { |
104 | 3920 | int ret = find_codec(ost, codec_name, ost->type, 1, enc); | |
105 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3920 times.
|
3920 | if (ret < 0) |
106 | ✗ | return ret; | |
107 | 3920 | ms->par_in->codec_id = (*enc)->id; | |
108 | } | ||
109 | |||
110 | 8346 | return 0; | |
111 | } | ||
112 | |||
113 | ✗ | static char *get_line(AVIOContext *s, AVBPrint *bprint) | |
114 | { | ||
115 | char c; | ||
116 | |||
117 | ✗ | while ((c = avio_r8(s)) && c != '\n') | |
118 | ✗ | av_bprint_chars(bprint, c, 1); | |
119 | |||
120 | ✗ | if (!av_bprint_is_complete(bprint)) | |
121 | ✗ | return NULL; | |
122 | |||
123 | ✗ | return bprint->str; | |
124 | } | ||
125 | |||
126 | ✗ | static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s) | |
127 | { | ||
128 | ✗ | int i, ret = -1; | |
129 | char filename[1000]; | ||
130 | ✗ | char *env_avconv_datadir = getenv_utf8("AVCONV_DATADIR"); | |
131 | ✗ | char *env_home = getenv_utf8("HOME"); | |
132 | ✗ | const char *base[3] = { env_avconv_datadir, | |
133 | env_home, | ||
134 | AVCONV_DATADIR, | ||
135 | }; | ||
136 | |||
137 | ✗ | for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) { | |
138 | ✗ | if (!base[i]) | |
139 | ✗ | continue; | |
140 | ✗ | if (codec_name) { | |
141 | ✗ | snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], | |
142 | i != 1 ? "" : "/.avconv", codec_name, preset_name); | ||
143 | ✗ | ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); | |
144 | } | ||
145 | ✗ | if (ret < 0) { | |
146 | ✗ | snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], | |
147 | i != 1 ? "" : "/.avconv", preset_name); | ||
148 | ✗ | ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL); | |
149 | } | ||
150 | } | ||
151 | ✗ | freeenv_utf8(env_home); | |
152 | ✗ | freeenv_utf8(env_avconv_datadir); | |
153 | ✗ | return ret; | |
154 | } | ||
155 | |||
156 | typedef struct EncStatsFile { | ||
157 | char *path; | ||
158 | AVIOContext *io; | ||
159 | } EncStatsFile; | ||
160 | |||
161 | static EncStatsFile *enc_stats_files; | ||
162 | static int nb_enc_stats_files; | ||
163 | |||
164 | ✗ | static int enc_stats_get_file(AVIOContext **io, const char *path) | |
165 | { | ||
166 | EncStatsFile *esf; | ||
167 | int ret; | ||
168 | |||
169 | ✗ | for (int i = 0; i < nb_enc_stats_files; i++) | |
170 | ✗ | if (!strcmp(path, enc_stats_files[i].path)) { | |
171 | ✗ | *io = enc_stats_files[i].io; | |
172 | ✗ | return 0; | |
173 | } | ||
174 | |||
175 | ✗ | ret = GROW_ARRAY(enc_stats_files, nb_enc_stats_files); | |
176 | ✗ | if (ret < 0) | |
177 | ✗ | return ret; | |
178 | |||
179 | ✗ | esf = &enc_stats_files[nb_enc_stats_files - 1]; | |
180 | |||
181 | ✗ | ret = avio_open2(&esf->io, path, AVIO_FLAG_WRITE, &int_cb, NULL); | |
182 | ✗ | if (ret < 0) { | |
183 | ✗ | av_log(NULL, AV_LOG_ERROR, "Error opening stats file '%s': %s\n", | |
184 | ✗ | path, av_err2str(ret)); | |
185 | ✗ | return ret; | |
186 | } | ||
187 | |||
188 | ✗ | esf->path = av_strdup(path); | |
189 | ✗ | if (!esf->path) | |
190 | ✗ | return AVERROR(ENOMEM); | |
191 | |||
192 | ✗ | *io = esf->io; | |
193 | |||
194 | ✗ | return 0; | |
195 | } | ||
196 | |||
197 | 7915 | void of_enc_stats_close(void) | |
198 | { | ||
199 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7915 times.
|
7915 | for (int i = 0; i < nb_enc_stats_files; i++) { |
200 | ✗ | av_freep(&enc_stats_files[i].path); | |
201 | ✗ | avio_closep(&enc_stats_files[i].io); | |
202 | } | ||
203 | 7915 | av_freep(&enc_stats_files); | |
204 | 7915 | nb_enc_stats_files = 0; | |
205 | 7915 | } | |
206 | |||
207 | ✗ | static int unescape(char **pdst, size_t *dst_len, | |
208 | const char **pstr, char delim) | ||
209 | { | ||
210 | ✗ | const char *str = *pstr; | |
211 | char *dst; | ||
212 | size_t len, idx; | ||
213 | |||
214 | ✗ | *pdst = NULL; | |
215 | |||
216 | ✗ | len = strlen(str); | |
217 | ✗ | if (!len) | |
218 | ✗ | return 0; | |
219 | |||
220 | ✗ | dst = av_malloc(len + 1); | |
221 | ✗ | if (!dst) | |
222 | ✗ | return AVERROR(ENOMEM); | |
223 | |||
224 | ✗ | for (idx = 0; *str; idx++, str++) { | |
225 | ✗ | if (str[0] == '\\' && str[1]) | |
226 | ✗ | str++; | |
227 | ✗ | else if (*str == delim) | |
228 | ✗ | break; | |
229 | |||
230 | ✗ | dst[idx] = *str; | |
231 | } | ||
232 | ✗ | if (!idx) { | |
233 | ✗ | av_freep(&dst); | |
234 | ✗ | return 0; | |
235 | } | ||
236 | |||
237 | ✗ | dst[idx] = 0; | |
238 | |||
239 | ✗ | *pdst = dst; | |
240 | ✗ | *dst_len = idx; | |
241 | ✗ | *pstr = str; | |
242 | |||
243 | ✗ | return 0; | |
244 | } | ||
245 | |||
246 | ✗ | static int enc_stats_init(OutputStream *ost, EncStats *es, int pre, | |
247 | const char *path, const char *fmt_spec) | ||
248 | { | ||
249 | static const struct { | ||
250 | enum EncStatsType type; | ||
251 | const char *str; | ||
252 | unsigned pre_only:1; | ||
253 | unsigned post_only:1; | ||
254 | unsigned need_input_data:1; | ||
255 | } fmt_specs[] = { | ||
256 | { ENC_STATS_FILE_IDX, "fidx" }, | ||
257 | { ENC_STATS_STREAM_IDX, "sidx" }, | ||
258 | { ENC_STATS_FRAME_NUM, "n" }, | ||
259 | { ENC_STATS_FRAME_NUM_IN, "ni", 0, 0, 1 }, | ||
260 | { ENC_STATS_TIMEBASE, "tb" }, | ||
261 | { ENC_STATS_TIMEBASE_IN, "tbi", 0, 0, 1 }, | ||
262 | { ENC_STATS_PTS, "pts" }, | ||
263 | { ENC_STATS_PTS_TIME, "t" }, | ||
264 | { ENC_STATS_PTS_IN, "ptsi", 0, 0, 1 }, | ||
265 | { ENC_STATS_PTS_TIME_IN, "ti", 0, 0, 1 }, | ||
266 | { ENC_STATS_DTS, "dts", 0, 1 }, | ||
267 | { ENC_STATS_DTS_TIME, "dt", 0, 1 }, | ||
268 | { ENC_STATS_SAMPLE_NUM, "sn", 1 }, | ||
269 | { ENC_STATS_NB_SAMPLES, "samp", 1 }, | ||
270 | { ENC_STATS_PKT_SIZE, "size", 0, 1 }, | ||
271 | { ENC_STATS_BITRATE, "br", 0, 1 }, | ||
272 | { ENC_STATS_AVG_BITRATE, "abr", 0, 1 }, | ||
273 | { ENC_STATS_KEYFRAME, "key", 0, 1 }, | ||
274 | }; | ||
275 | ✗ | const char *next = fmt_spec; | |
276 | |||
277 | int ret; | ||
278 | |||
279 | ✗ | while (*next) { | |
280 | EncStatsComponent *c; | ||
281 | char *val; | ||
282 | size_t val_len; | ||
283 | |||
284 | // get the sequence up until next opening brace | ||
285 | ✗ | ret = unescape(&val, &val_len, &next, '{'); | |
286 | ✗ | if (ret < 0) | |
287 | ✗ | return ret; | |
288 | |||
289 | ✗ | if (val) { | |
290 | ✗ | ret = GROW_ARRAY(es->components, es->nb_components); | |
291 | ✗ | if (ret < 0) { | |
292 | ✗ | av_freep(&val); | |
293 | ✗ | return ret; | |
294 | } | ||
295 | |||
296 | ✗ | c = &es->components[es->nb_components - 1]; | |
297 | ✗ | c->type = ENC_STATS_LITERAL; | |
298 | ✗ | c->str = val; | |
299 | ✗ | c->str_len = val_len; | |
300 | } | ||
301 | |||
302 | ✗ | if (!*next) | |
303 | ✗ | break; | |
304 | ✗ | next++; | |
305 | |||
306 | // get the part inside braces | ||
307 | ✗ | ret = unescape(&val, &val_len, &next, '}'); | |
308 | ✗ | if (ret < 0) | |
309 | ✗ | return ret; | |
310 | |||
311 | ✗ | if (!val) { | |
312 | ✗ | av_log(NULL, AV_LOG_ERROR, | |
313 | "Empty formatting directive in: %s\n", fmt_spec); | ||
314 | ✗ | return AVERROR(EINVAL); | |
315 | } | ||
316 | |||
317 | ✗ | if (!*next) { | |
318 | ✗ | av_log(NULL, AV_LOG_ERROR, | |
319 | "Missing closing brace in: %s\n", fmt_spec); | ||
320 | ✗ | ret = AVERROR(EINVAL); | |
321 | ✗ | goto fail; | |
322 | } | ||
323 | ✗ | next++; | |
324 | |||
325 | ✗ | ret = GROW_ARRAY(es->components, es->nb_components); | |
326 | ✗ | if (ret < 0) | |
327 | ✗ | goto fail; | |
328 | |||
329 | ✗ | c = &es->components[es->nb_components - 1]; | |
330 | |||
331 | ✗ | for (size_t i = 0; i < FF_ARRAY_ELEMS(fmt_specs); i++) { | |
332 | ✗ | if (!strcmp(val, fmt_specs[i].str)) { | |
333 | ✗ | if ((pre && fmt_specs[i].post_only) || (!pre && fmt_specs[i].pre_only)) { | |
334 | ✗ | av_log(NULL, AV_LOG_ERROR, | |
335 | "Format directive '%s' may only be used %s-encoding\n", | ||
336 | val, pre ? "post" : "pre"); | ||
337 | ✗ | ret = AVERROR(EINVAL); | |
338 | ✗ | goto fail; | |
339 | } | ||
340 | |||
341 | ✗ | c->type = fmt_specs[i].type; | |
342 | |||
343 | ✗ | if (fmt_specs[i].need_input_data && !ost->ist) { | |
344 | ✗ | av_log(ost, AV_LOG_WARNING, | |
345 | "Format directive '%s' is unavailable, because " | ||
346 | "this output stream has no associated input stream\n", | ||
347 | val); | ||
348 | } | ||
349 | |||
350 | ✗ | break; | |
351 | } | ||
352 | } | ||
353 | |||
354 | ✗ | if (!c->type) { | |
355 | ✗ | av_log(NULL, AV_LOG_ERROR, "Invalid format directive: %s\n", val); | |
356 | ✗ | ret = AVERROR(EINVAL); | |
357 | ✗ | goto fail; | |
358 | } | ||
359 | |||
360 | ✗ | fail: | |
361 | ✗ | av_freep(&val); | |
362 | ✗ | if (ret < 0) | |
363 | ✗ | return ret; | |
364 | } | ||
365 | |||
366 | ✗ | ret = pthread_mutex_init(&es->lock, NULL); | |
367 | ✗ | if (ret) | |
368 | ✗ | return AVERROR(ret); | |
369 | ✗ | es->lock_initialized = 1; | |
370 | |||
371 | ✗ | ret = enc_stats_get_file(&es->io, path); | |
372 | ✗ | if (ret < 0) | |
373 | ✗ | return ret; | |
374 | |||
375 | ✗ | return 0; | |
376 | } | ||
377 | |||
378 | 2322 | static const char *output_stream_item_name(void *obj) | |
379 | { | ||
380 | 2322 | const MuxStream *ms = obj; | |
381 | |||
382 | 2322 | return ms->log_name; | |
383 | } | ||
384 | |||
385 | static const AVClass output_stream_class = { | ||
386 | .class_name = "OutputStream", | ||
387 | .version = LIBAVUTIL_VERSION_INT, | ||
388 | .item_name = output_stream_item_name, | ||
389 | .category = AV_CLASS_CATEGORY_MUXER, | ||
390 | }; | ||
391 | |||
392 | 8357 | static MuxStream *mux_stream_alloc(Muxer *mux, enum AVMediaType type) | |
393 | { | ||
394 | 8357 | const char *type_str = av_get_media_type_string(type); | |
395 | MuxStream *ms; | ||
396 | |||
397 | 8357 | ms = allocate_array_elem(&mux->of.streams, sizeof(*ms), &mux->of.nb_streams); | |
398 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8357 times.
|
8357 | if (!ms) |
399 | ✗ | return NULL; | |
400 | |||
401 | 8357 | ms->ost.file = &mux->of; | |
402 | 8357 | ms->ost.index = mux->of.nb_streams - 1; | |
403 | 8357 | ms->ost.type = type; | |
404 | |||
405 | 8357 | ms->ost.class = &output_stream_class; | |
406 | |||
407 | 8357 | ms->sch_idx = -1; | |
408 | 8357 | ms->sch_idx_enc = -1; | |
409 | |||
410 |
1/2✓ Branch 0 taken 8357 times.
✗ Branch 1 not taken.
|
8357 | snprintf(ms->log_name, sizeof(ms->log_name), "%cost#%d:%d", |
411 | 8357 | type_str ? *type_str : '?', mux->of.index, ms->ost.index); | |
412 | |||
413 | 8357 | return ms; | |
414 | } | ||
415 | |||
416 | 7658 | static int ost_get_filters(const OptionsContext *o, AVFormatContext *oc, | |
417 | OutputStream *ost, char **dst) | ||
418 | { | ||
419 | 7658 | const char *filters = NULL; | |
420 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
421 | 7658 | const char *filters_script = NULL; | |
422 | |||
423 | 7658 | opt_match_per_stream_str(ost, &o->filter_scripts, oc, ost->st, &filters_script); | |
424 | #endif | ||
425 | 7658 | opt_match_per_stream_str(ost, &o->filters, oc, ost->st, &filters); | |
426 | |||
427 |
2/2✓ Branch 0 taken 1023 times.
✓ Branch 1 taken 6635 times.
|
7658 | if (!ost->ist) { |
428 | 1023 | if ( | |
429 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
430 |
2/4✓ Branch 0 taken 1023 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1023 times.
|
1023 | filters_script || |
431 | #endif | ||
432 | filters) { | ||
433 | ✗ | av_log(ost, AV_LOG_ERROR, | |
434 | "%s '%s' was specified for a stream fed from a complex " | ||
435 | "filtergraph. Simple and complex filtering cannot be used " | ||
436 | "together for the same stream.\n", | ||
437 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
438 | ✗ | filters ? "Filtergraph" : "Filtergraph script", | |
439 | ✗ | filters ? filters : filters_script | |
440 | #else | ||
441 | "Filtergraph", filters | ||
442 | #endif | ||
443 | ); | ||
444 | ✗ | return AVERROR(EINVAL); | |
445 | } | ||
446 | 1023 | return 0; | |
447 | } | ||
448 | |||
449 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
450 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 6635 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
6635 | if (filters_script && filters) { |
451 | ✗ | av_log(ost, AV_LOG_ERROR, "Both -filter and -filter_script set\n"); | |
452 | ✗ | return AVERROR(EINVAL); | |
453 | } | ||
454 | |||
455 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6635 times.
|
6635 | if (filters_script) |
456 | ✗ | *dst = file_read(filters_script); | |
457 | else | ||
458 | #endif | ||
459 |
2/2✓ Branch 0 taken 3787 times.
✓ Branch 1 taken 2848 times.
|
6635 | if (filters) |
460 | 3787 | *dst = av_strdup(filters); | |
461 | else | ||
462 |
2/2✓ Branch 0 taken 2264 times.
✓ Branch 1 taken 584 times.
|
2848 | *dst = av_strdup(ost->type == AVMEDIA_TYPE_VIDEO ? "null" : "anull"); |
463 |
1/2✓ Branch 0 taken 6635 times.
✗ Branch 1 not taken.
|
6635 | return *dst ? 0 : AVERROR(ENOMEM); |
464 | } | ||
465 | |||
466 | ✗ | static int parse_matrix_coeffs(void *logctx, uint16_t *dest, const char *str) | |
467 | { | ||
468 | ✗ | const char *p = str; | |
469 | ✗ | for (int i = 0;; i++) { | |
470 | ✗ | dest[i] = atoi(p); | |
471 | ✗ | if (i == 63) | |
472 | ✗ | break; | |
473 | ✗ | p = strchr(p, ','); | |
474 | ✗ | if (!p) { | |
475 | ✗ | av_log(logctx, AV_LOG_FATAL, | |
476 | "Syntax error in matrix \"%s\" at coeff %d\n", str, i); | ||
477 | ✗ | return AVERROR(EINVAL); | |
478 | } | ||
479 | ✗ | p++; | |
480 | } | ||
481 | |||
482 | ✗ | return 0; | |
483 | } | ||
484 | |||
485 | 640 | static int fmt_in_list(const int *formats, int format) | |
486 | { | ||
487 |
1/2✓ Branch 0 taken 3680 times.
✗ Branch 1 not taken.
|
3680 | for (; *formats != -1; formats++) |
488 |
2/2✓ Branch 0 taken 640 times.
✓ Branch 1 taken 3040 times.
|
3680 | if (*formats == format) |
489 | 640 | return 1; | |
490 | ✗ | return 0; | |
491 | } | ||
492 | |||
493 | static enum AVPixelFormat | ||
494 | ✗ | choose_pixel_fmt(const AVCodecContext *avctx, enum AVPixelFormat target) | |
495 | { | ||
496 | const enum AVPixelFormat *p; | ||
497 | ✗ | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target); | |
498 | //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel format without alpha is implemented | ||
499 | ✗ | int has_alpha = desc ? desc->nb_components % 2 == 0 : 0; | |
500 | ✗ | enum AVPixelFormat best= AV_PIX_FMT_NONE; | |
501 | int ret; | ||
502 | |||
503 | ✗ | ret = avcodec_get_supported_config(avctx, NULL, AV_CODEC_CONFIG_PIX_FORMAT, | |
504 | 0, (const void **) &p, NULL); | ||
505 | ✗ | if (ret < 0) | |
506 | ✗ | return AV_PIX_FMT_NONE; | |
507 | |||
508 | ✗ | for (; *p != AV_PIX_FMT_NONE; p++) { | |
509 | ✗ | best = av_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL); | |
510 | ✗ | if (*p == target) | |
511 | ✗ | break; | |
512 | } | ||
513 | ✗ | if (*p == AV_PIX_FMT_NONE) { | |
514 | ✗ | if (target != AV_PIX_FMT_NONE) | |
515 | ✗ | av_log(NULL, AV_LOG_WARNING, | |
516 | "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n", | ||
517 | av_get_pix_fmt_name(target), | ||
518 | ✗ | avctx->codec->name, | |
519 | av_get_pix_fmt_name(best)); | ||
520 | ✗ | return best; | |
521 | } | ||
522 | ✗ | return target; | |
523 | } | ||
524 | |||
525 | 4866 | static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, const char *name) | |
526 | { | ||
527 | const enum AVPixelFormat *fmts; | ||
528 | enum AVPixelFormat fmt; | ||
529 | int ret; | ||
530 | |||
531 | 4866 | fmt = av_get_pix_fmt(name); | |
532 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4866 times.
|
4866 | if (fmt == AV_PIX_FMT_NONE) { |
533 | ✗ | av_log(ost, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", name); | |
534 | ✗ | return AV_PIX_FMT_NONE; | |
535 | } | ||
536 | |||
537 | 4866 | ret = avcodec_get_supported_config(ost->enc->enc_ctx, NULL, AV_CODEC_CONFIG_PIX_FORMAT, | |
538 | 0, (const void **) &fmts, NULL); | ||
539 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4866 times.
|
4866 | if (ret < 0) |
540 | ✗ | return AV_PIX_FMT_NONE; | |
541 | |||
542 | /* when the user specified-format is an alias for an endianness-specific | ||
543 | * one (e.g. rgb48 -> rgb48be/le), it gets translated into the native | ||
544 | * endianness by av_get_pix_fmt(); | ||
545 | * the following code handles the case when the native endianness is not | ||
546 | * supported by the encoder, but the other one is */ | ||
547 |
3/4✓ Branch 0 taken 320 times.
✓ Branch 1 taken 4546 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 320 times.
|
4866 | if (fmts && !fmt_in_list(fmts, fmt)) { |
548 | ✗ | const char *name_canonical = av_get_pix_fmt_name(fmt); | |
549 | ✗ | int len = strlen(name_canonical); | |
550 | |||
551 | ✗ | if (strcmp(name, name_canonical) && | |
552 | ✗ | (!strcmp(name_canonical + len - 2, "le") || | |
553 | ✗ | !strcmp(name_canonical + len - 2, "be"))) { | |
554 | char name_other[64]; | ||
555 | enum AVPixelFormat fmt_other; | ||
556 | |||
557 | ✗ | snprintf(name_other, sizeof(name_other), "%s%ce", | |
558 | ✗ | name, name_canonical[len - 2] == 'l' ? 'b' : 'l'); | |
559 | ✗ | fmt_other = av_get_pix_fmt(name_other); | |
560 | ✗ | if (fmt_other != AV_PIX_FMT_NONE && fmt_in_list(fmts, fmt_other)) { | |
561 | ✗ | av_log(ost, AV_LOG_VERBOSE, "Mapping pixel format %s->%s\n", | |
562 | name, name_other); | ||
563 | ✗ | fmt = fmt_other; | |
564 | } | ||
565 | } | ||
566 | } | ||
567 | |||
568 |
3/4✓ Branch 0 taken 320 times.
✓ Branch 1 taken 4546 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 320 times.
|
4866 | if (fmts && !fmt_in_list(fmts, fmt)) |
569 | ✗ | fmt = choose_pixel_fmt(ost->enc->enc_ctx, fmt); | |
570 | |||
571 | 4866 | return fmt; | |
572 | } | ||
573 | |||
574 | 6681 | static int new_stream_video(Muxer *mux, const OptionsContext *o, | |
575 | OutputStream *ost, int *keep_pix_fmt, | ||
576 | enum VideoSyncMethod *vsync_method) | ||
577 | { | ||
578 | 6681 | MuxStream *ms = ms_from_ost(ost); | |
579 | 6681 | AVFormatContext *oc = mux->fc; | |
580 | AVStream *st; | ||
581 | 6681 | const char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL; | |
582 | 6681 | int ret = 0; | |
583 | |||
584 | 6681 | st = ost->st; | |
585 | |||
586 | 6681 | opt_match_per_stream_str(ost, &o->frame_rates, oc, st, &frame_rate); | |
587 |
3/4✓ Branch 0 taken 22 times.
✓ Branch 1 taken 6659 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
|
6681 | if (frame_rate && av_parse_video_rate(&ms->frame_rate, frame_rate) < 0) { |
588 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate); | |
589 | ✗ | return AVERROR(EINVAL); | |
590 | } | ||
591 | |||
592 | 6681 | opt_match_per_stream_str(ost, &o->max_frame_rates, oc, st, &max_frame_rate); | |
593 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 6681 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
6681 | if (max_frame_rate && av_parse_video_rate(&ms->max_frame_rate, max_frame_rate) < 0) { |
594 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", max_frame_rate); | |
595 | ✗ | return AVERROR(EINVAL); | |
596 | } | ||
597 | |||
598 |
3/4✓ Branch 0 taken 22 times.
✓ Branch 1 taken 6659 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22 times.
|
6681 | if (frame_rate && max_frame_rate) { |
599 | ✗ | av_log(ost, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n"); | |
600 | ✗ | return AVERROR(EINVAL); | |
601 | } | ||
602 | |||
603 | 6681 | opt_match_per_stream_str(ost, &o->frame_aspect_ratios, oc, st, &frame_aspect_ratio); | |
604 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6681 times.
|
6681 | if (frame_aspect_ratio) { |
605 | AVRational q; | ||
606 | ✗ | if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 || | |
607 | ✗ | q.num <= 0 || q.den <= 0) { | |
608 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio); | |
609 | ✗ | return AVERROR(EINVAL); | |
610 | } | ||
611 | ✗ | ost->frame_aspect_ratio = q; | |
612 | } | ||
613 | |||
614 |
2/2✓ Branch 0 taken 6338 times.
✓ Branch 1 taken 343 times.
|
6681 | if (ost->enc) { |
615 | 6338 | AVCodecContext *video_enc = ost->enc->enc_ctx; | |
616 | 6338 | const char *p = NULL, *fps_mode = NULL; | |
617 | 6338 | const char *frame_size = NULL; | |
618 | 6338 | const char *frame_pix_fmt = NULL; | |
619 | 6338 | const char *intra_matrix = NULL, *inter_matrix = NULL; | |
620 | 6338 | const char *chroma_intra_matrix = NULL; | |
621 | 6338 | int do_pass = 0; | |
622 | int i; | ||
623 | |||
624 | 6338 | opt_match_per_stream_str(ost, &o->frame_sizes, oc, st, &frame_size); | |
625 |
2/2✓ Branch 0 taken 1013 times.
✓ Branch 1 taken 5325 times.
|
6338 | if (frame_size) { |
626 | 1013 | ret = av_parse_video_size(&video_enc->width, &video_enc->height, frame_size); | |
627 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1013 times.
|
1013 | if (ret < 0) { |
628 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size); | |
629 | ✗ | return AVERROR(EINVAL); | |
630 | } | ||
631 | } | ||
632 | |||
633 | 6338 | opt_match_per_stream_str(ost, &o->frame_pix_fmts, oc, st, &frame_pix_fmt); | |
634 |
3/4✓ Branch 0 taken 4866 times.
✓ Branch 1 taken 1472 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4866 times.
|
6338 | if (frame_pix_fmt && *frame_pix_fmt == '+') { |
635 | ✗ | *keep_pix_fmt = 1; | |
636 | ✗ | if (!*++frame_pix_fmt) | |
637 | ✗ | frame_pix_fmt = NULL; | |
638 | } | ||
639 |
2/2✓ Branch 0 taken 4866 times.
✓ Branch 1 taken 1472 times.
|
6338 | if (frame_pix_fmt) { |
640 | 4866 | video_enc->pix_fmt = pix_fmt_parse(ost, frame_pix_fmt); | |
641 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4866 times.
|
4866 | if (video_enc->pix_fmt == AV_PIX_FMT_NONE) |
642 | ✗ | return AVERROR(EINVAL); | |
643 | } | ||
644 | |||
645 | 6338 | opt_match_per_stream_str(ost, &o->intra_matrices, oc, st, &intra_matrix); | |
646 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6338 times.
|
6338 | if (intra_matrix) { |
647 | ✗ | if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) | |
648 | ✗ | return AVERROR(ENOMEM); | |
649 | |||
650 | ✗ | ret = parse_matrix_coeffs(ost, video_enc->intra_matrix, intra_matrix); | |
651 | ✗ | if (ret < 0) | |
652 | ✗ | return ret; | |
653 | } | ||
654 | 6338 | opt_match_per_stream_str(ost, &o->chroma_intra_matrices, oc, st, &chroma_intra_matrix); | |
655 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6338 times.
|
6338 | if (chroma_intra_matrix) { |
656 | ✗ | if (!(video_enc->chroma_intra_matrix = av_mallocz(sizeof(*video_enc->chroma_intra_matrix) * 64))) | |
657 | ✗ | return AVERROR(ENOMEM); | |
658 | ✗ | ret = parse_matrix_coeffs(ost, video_enc->chroma_intra_matrix, chroma_intra_matrix); | |
659 | ✗ | if (ret < 0) | |
660 | ✗ | return ret; | |
661 | } | ||
662 | 6338 | opt_match_per_stream_str(ost, &o->inter_matrices, oc, st, &inter_matrix); | |
663 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6338 times.
|
6338 | if (inter_matrix) { |
664 | ✗ | if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) | |
665 | ✗ | return AVERROR(ENOMEM); | |
666 | ✗ | ret = parse_matrix_coeffs(ost, video_enc->inter_matrix, inter_matrix); | |
667 | ✗ | if (ret < 0) | |
668 | ✗ | return ret; | |
669 | } | ||
670 | |||
671 | 6338 | opt_match_per_stream_str(ost, &o->rc_overrides, oc, st, &p); | |
672 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6338 times.
|
6338 | for (i = 0; p; i++) { |
673 | int start, end, q; | ||
674 | ✗ | int e = sscanf(p, "%d,%d,%d", &start, &end, &q); | |
675 | ✗ | if (e != 3) { | |
676 | ✗ | av_log(ost, AV_LOG_FATAL, "error parsing rc_override\n"); | |
677 | ✗ | return AVERROR(EINVAL); | |
678 | } | ||
679 | ✗ | video_enc->rc_override = | |
680 | ✗ | av_realloc_array(video_enc->rc_override, | |
681 | ✗ | i + 1, sizeof(RcOverride)); | |
682 | ✗ | if (!video_enc->rc_override) { | |
683 | ✗ | av_log(ost, AV_LOG_FATAL, "Could not (re)allocate memory for rc_override.\n"); | |
684 | ✗ | return AVERROR(ENOMEM); | |
685 | } | ||
686 | ✗ | video_enc->rc_override[i].start_frame = start; | |
687 | ✗ | video_enc->rc_override[i].end_frame = end; | |
688 | ✗ | if (q > 0) { | |
689 | ✗ | video_enc->rc_override[i].qscale = q; | |
690 | ✗ | video_enc->rc_override[i].quality_factor = 1.0; | |
691 | } | ||
692 | else { | ||
693 | ✗ | video_enc->rc_override[i].qscale = 0; | |
694 | ✗ | video_enc->rc_override[i].quality_factor = -q/100.0; | |
695 | } | ||
696 | ✗ | p = strchr(p, '/'); | |
697 | ✗ | if (p) p++; | |
698 | } | ||
699 | 6338 | video_enc->rc_override_count = i; | |
700 | |||
701 | /* two pass mode */ | ||
702 | 6338 | opt_match_per_stream_int(ost, &o->pass, oc, st, &do_pass); | |
703 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6322 times.
|
6338 | if (do_pass) { |
704 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (do_pass & 1) |
705 | 8 | video_enc->flags |= AV_CODEC_FLAG_PASS1; | |
706 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (do_pass & 2) |
707 | 8 | video_enc->flags |= AV_CODEC_FLAG_PASS2; | |
708 | } | ||
709 | |||
710 | 6338 | opt_match_per_stream_str(ost, &o->passlogfiles, oc, st, &ost->logfile_prefix); | |
711 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6322 times.
|
6338 | if (ost->logfile_prefix && |
712 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
|
16 | !(ost->logfile_prefix = av_strdup(ost->logfile_prefix))) |
713 | ✗ | return AVERROR(ENOMEM); | |
714 | |||
715 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 6322 times.
|
6338 | if (do_pass) { |
716 | 16 | int ost_idx = -1; | |
717 | char logfilename[1024]; | ||
718 | FILE *f; | ||
719 | |||
720 | /* compute this stream's global index */ | ||
721 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
|
32 | for (int idx = 0; idx <= ost->file->index; idx++) |
722 | 16 | ost_idx += output_files[idx]->nb_streams; | |
723 | |||
724 | 16 | snprintf(logfilename, sizeof(logfilename), "%s-%d.log", | |
725 |
1/2✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
|
16 | ost->logfile_prefix ? ost->logfile_prefix : |
726 | DEFAULT_PASS_LOGFILENAME_PREFIX, | ||
727 | ost_idx); | ||
728 |
2/4✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
|
16 | if (!strcmp(video_enc->codec->name, "libx264") || !strcmp(video_enc->codec->name, "libvvenc")) { |
729 | ✗ | if (av_opt_is_set_to_default_by_name(video_enc, "stats", | |
730 | AV_OPT_SEARCH_CHILDREN) > 0) | ||
731 | ✗ | av_opt_set(video_enc, "stats", logfilename, | |
732 | AV_OPT_SEARCH_CHILDREN); | ||
733 | } else { | ||
734 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (video_enc->flags & AV_CODEC_FLAG_PASS2) { |
735 | 8 | char *logbuffer = file_read(logfilename); | |
736 | |||
737 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (!logbuffer) { |
738 | ✗ | av_log(ost, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n", | |
739 | logfilename); | ||
740 | ✗ | return AVERROR(EIO); | |
741 | } | ||
742 | 8 | video_enc->stats_in = logbuffer; | |
743 | } | ||
744 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
|
16 | if (video_enc->flags & AV_CODEC_FLAG_PASS1) { |
745 | 8 | f = fopen_utf8(logfilename, "wb"); | |
746 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | if (!f) { |
747 | ✗ | av_log(ost, AV_LOG_FATAL, | |
748 | "Cannot write log file '%s' for pass-1 encoding: %s\n", | ||
749 | ✗ | logfilename, strerror(errno)); | |
750 | ✗ | return AVERROR(errno); | |
751 | } | ||
752 | 8 | ost->logfile = f; | |
753 | } | ||
754 | } | ||
755 | } | ||
756 | |||
757 | 6338 | opt_match_per_stream_int(ost, &o->force_fps, oc, st, &ms->force_fps); | |
758 | |||
759 | #if FFMPEG_OPT_TOP | ||
760 | 6338 | ost->top_field_first = -1; | |
761 | 6338 | opt_match_per_stream_int(ost, &o->top_field_first, oc, st, &ost->top_field_first); | |
762 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6338 times.
|
6338 | if (ost->top_field_first >= 0) |
763 | ✗ | av_log(ost, AV_LOG_WARNING, "-top is deprecated, use the setfield filter instead\n"); | |
764 | #endif | ||
765 | |||
766 | #if FFMPEG_OPT_VSYNC | ||
767 | 6338 | *vsync_method = video_sync_method; | |
768 | #else | ||
769 | *vsync_method = VSYNC_AUTO; | ||
770 | #endif | ||
771 | 6338 | opt_match_per_stream_str(ost, &o->fps_mode, oc, st, &fps_mode); | |
772 |
2/2✓ Branch 0 taken 528 times.
✓ Branch 1 taken 5810 times.
|
6338 | if (fps_mode) { |
773 | 528 | ret = parse_and_set_vsync(fps_mode, vsync_method, ost->file->index, ost->index, 0); | |
774 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 528 times.
|
528 | if (ret < 0) |
775 | ✗ | return ret; | |
776 | } | ||
777 | |||
778 |
3/4✓ Branch 0 taken 6317 times.
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6317 times.
|
6338 | if ((ms->frame_rate.num || ms->max_frame_rate.num) && |
779 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
|
21 | !(*vsync_method == VSYNC_AUTO || |
780 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1 | *vsync_method == VSYNC_CFR || *vsync_method == VSYNC_VSCFR)) { |
781 | ✗ | av_log(ost, AV_LOG_FATAL, "One of -r/-fpsmax was specified " | |
782 | "together a non-CFR -vsync/-fps_mode. This is contradictory.\n"); | ||
783 | ✗ | return AVERROR(EINVAL); | |
784 | } | ||
785 | |||
786 |
2/2✓ Branch 0 taken 5810 times.
✓ Branch 1 taken 528 times.
|
6338 | if (*vsync_method == VSYNC_AUTO) { |
787 |
3/4✓ Branch 0 taken 5790 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5790 times.
|
5810 | if (ms->frame_rate.num || ms->max_frame_rate.num) { |
788 | 20 | *vsync_method = VSYNC_CFR; | |
789 |
2/2✓ Branch 0 taken 296 times.
✓ Branch 1 taken 5494 times.
|
5790 | } else if (!strcmp(oc->oformat->name, "avi")) { |
790 | 296 | *vsync_method = VSYNC_VFR; | |
791 | } else { | ||
792 | 5494 | *vsync_method = (oc->oformat->flags & AVFMT_VARIABLE_FPS) ? | |
793 | 4363 | ((oc->oformat->flags & AVFMT_NOTIMESTAMPS) ? | |
794 |
4/4✓ Branch 0 taken 4363 times.
✓ Branch 1 taken 1131 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 4348 times.
|
5494 | VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR; |
795 | } | ||
796 | |||
797 |
4/4✓ Branch 0 taken 4939 times.
✓ Branch 1 taken 871 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 4556 times.
|
5810 | if (ost->ist && *vsync_method == VSYNC_CFR) { |
798 | 383 | const InputFile *ifile = ost->ist->file; | |
799 | |||
800 |
3/4✓ Branch 0 taken 338 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 338 times.
✗ Branch 3 not taken.
|
383 | if (ifile->nb_streams == 1 && ifile->input_ts_offset == 0) |
801 | 338 | *vsync_method = VSYNC_VSCFR; | |
802 | } | ||
803 | |||
804 |
3/4✓ Branch 0 taken 813 times.
✓ Branch 1 taken 4997 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 813 times.
|
5810 | if (*vsync_method == VSYNC_CFR && copy_ts) { |
805 | ✗ | *vsync_method = VSYNC_VSCFR; | |
806 | } | ||
807 | } | ||
808 | #if FFMPEG_OPT_VSYNC_DROP | ||
809 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6338 times.
|
6338 | if (*vsync_method == VSYNC_DROP) |
810 | ✗ | ms->ts_drop = 1; | |
811 | #endif | ||
812 | } | ||
813 | |||
814 | 6681 | return 0; | |
815 | } | ||
816 | |||
817 | 1594 | static int new_stream_audio(Muxer *mux, const OptionsContext *o, | |
818 | OutputStream *ost) | ||
819 | { | ||
820 | 1594 | MuxStream *ms = ms_from_ost(ost); | |
821 | 1594 | AVFormatContext *oc = mux->fc; | |
822 | 1594 | AVStream *st = ost->st; | |
823 | |||
824 |
2/2✓ Branch 0 taken 1320 times.
✓ Branch 1 taken 274 times.
|
1594 | if (ost->enc) { |
825 | 1320 | AVCodecContext *audio_enc = ost->enc->enc_ctx; | |
826 | 1320 | int channels = 0; | |
827 | 1320 | const char *layout = NULL; | |
828 | 1320 | const char *sample_fmt = NULL; | |
829 | |||
830 | 1320 | opt_match_per_stream_int(ost, &o->audio_channels, oc, st, &channels); | |
831 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1310 times.
|
1320 | if (channels) { |
832 | 10 | audio_enc->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; | |
833 | 10 | audio_enc->ch_layout.nb_channels = channels; | |
834 | } | ||
835 | |||
836 | 1320 | opt_match_per_stream_str(ost, &o->audio_ch_layouts, oc, st, &layout); | |
837 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1319 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
|
1320 | if (layout && av_channel_layout_from_string(&audio_enc->ch_layout, layout) < 0) { |
838 | ✗ | av_log(ost, AV_LOG_FATAL, "Unknown channel layout: %s\n", layout); | |
839 | ✗ | return AVERROR(EINVAL); | |
840 | } | ||
841 | |||
842 | 1320 | opt_match_per_stream_str(ost, &o->sample_fmts, oc, st, &sample_fmt); | |
843 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1320 times.
|
1320 | if (sample_fmt && |
844 | ✗ | (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) { | |
845 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt); | |
846 | ✗ | return AVERROR(EINVAL); | |
847 | } | ||
848 | |||
849 | 1320 | opt_match_per_stream_int(ost, &o->audio_sample_rate, oc, st, &audio_enc->sample_rate); | |
850 | 1320 | opt_match_per_stream_str(ost, &o->apad, oc, st, &ms->apad); | |
851 | } | ||
852 | |||
853 | 1594 | return 0; | |
854 | } | ||
855 | |||
856 | 71 | static int new_stream_subtitle(Muxer *mux, const OptionsContext *o, | |
857 | OutputStream *ost) | ||
858 | { | ||
859 | AVStream *st; | ||
860 | |||
861 | 71 | st = ost->st; | |
862 | |||
863 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 33 times.
|
71 | if (ost->enc) { |
864 | 38 | AVCodecContext *subtitle_enc = ost->enc->enc_ctx; | |
865 | |||
866 | AVCodecDescriptor const *input_descriptor = | ||
867 | 38 | avcodec_descriptor_get(ost->ist->par->codec_id); | |
868 | AVCodecDescriptor const *output_descriptor = | ||
869 | 38 | avcodec_descriptor_get(subtitle_enc->codec_id); | |
870 | 38 | int input_props = 0, output_props = 0; | |
871 | |||
872 | 38 | const char *frame_size = NULL; | |
873 | |||
874 | 38 | opt_match_per_stream_str(ost, &o->frame_sizes, mux->fc, st, &frame_size); | |
875 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
|
38 | if (frame_size) { |
876 | ✗ | int ret = av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size); | |
877 | ✗ | if (ret < 0) { | |
878 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size); | |
879 | ✗ | return ret; | |
880 | } | ||
881 | } | ||
882 |
1/2✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
|
38 | if (input_descriptor) |
883 | 38 | input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB); | |
884 |
1/2✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
|
38 | if (output_descriptor) |
885 | 38 | output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB); | |
886 |
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) { |
887 | ✗ | av_log(ost, AV_LOG_ERROR, | |
888 | "Subtitle encoding currently only possible from text to text " | ||
889 | "or bitmap to bitmap\n"); | ||
890 | ✗ | return AVERROR(EINVAL); | |
891 | } | ||
892 | } | ||
893 | |||
894 | 71 | return 0; | |
895 | } | ||
896 | |||
897 | static int | ||
898 | 7658 | ost_bind_filter(const Muxer *mux, MuxStream *ms, OutputFilter *ofilter, | |
899 | const OptionsContext *o, | ||
900 | AVRational enc_tb, enum VideoSyncMethod vsync_method, | ||
901 | int keep_pix_fmt, int autoscale, int threads_manual, | ||
902 | const ViewSpecifier *vs, | ||
903 | SchedulerNode *src) | ||
904 | { | ||
905 | 7658 | OutputStream *ost = &ms->ost; | |
906 | 7658 | AVCodecContext *enc_ctx = ost->enc->enc_ctx; | |
907 | char name[16]; | ||
908 | 7658 | char *filters = NULL; | |
909 | int ret; | ||
910 | |||
911 | 30632 | OutputFilterOptions opts = { | |
912 | 7658 | .enc = enc_ctx->codec, | |
913 | .name = name, | ||
914 | 7658 | .format = (ost->type == AVMEDIA_TYPE_VIDEO) ? | |
915 | 7658 | enc_ctx->pix_fmt : enc_ctx->sample_fmt, | |
916 | 7658 | .width = enc_ctx->width, | |
917 | 7658 | .height = enc_ctx->height, | |
918 | 7658 | .color_space = enc_ctx->colorspace, | |
919 | 7658 | .color_range = enc_ctx->color_range, | |
920 | .vsync_method = vsync_method, | ||
921 | .frame_rate = ms->frame_rate, | ||
922 | .max_frame_rate = ms->max_frame_rate, | ||
923 | 7658 | .sample_rate = enc_ctx->sample_rate, | |
924 | .ch_layout = enc_ctx->ch_layout, | ||
925 | 7658 | .sws_opts = o->g->sws_dict, | |
926 | 7658 | .swr_opts = o->g->swr_opts, | |
927 | .output_tb = enc_tb, | ||
928 | 7658 | .trim_start_us = mux->of.start_time, | |
929 | 7658 | .trim_duration_us = mux->of.recording_time, | |
930 | 7658 | .ts_offset = mux->of.start_time == AV_NOPTS_VALUE ? | |
931 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7657 times.
|
7658 | 0 : mux->of.start_time, |
932 | .vs = vs, | ||
933 | |||
934 | 15316 | .flags = OFILTER_FLAG_DISABLE_CONVERT * !!keep_pix_fmt | | |
935 |
3/4✓ Branch 0 taken 7658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6338 times.
✓ Branch 3 taken 1320 times.
|
15316 | OFILTER_FLAG_AUTOSCALE * !!autoscale | |
936 |
2/2✓ Branch 1 taken 59 times.
✓ Branch 2 taken 7599 times.
|
7658 | OFILTER_FLAG_AUDIO_24BIT * !!(av_get_exact_bits_per_sample(enc_ctx->codec_id) == 24), |
937 | }; | ||
938 | |||
939 | 7658 | snprintf(name, sizeof(name), "#%d:%d", mux->of.index, ost->index); | |
940 | |||
941 |
2/2✓ Branch 0 taken 6338 times.
✓ Branch 1 taken 1320 times.
|
7658 | if (ost->type == AVMEDIA_TYPE_VIDEO) { |
942 |
1/2✓ Branch 0 taken 6338 times.
✗ Branch 1 not taken.
|
6338 | if (!keep_pix_fmt) { |
943 | 6338 | ret = avcodec_get_supported_config(enc_ctx, NULL, | |
944 | AV_CODEC_CONFIG_PIX_FORMAT, 0, | ||
945 | (const void **) &opts.formats, NULL); | ||
946 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6338 times.
|
6338 | if (ret < 0) |
947 | ✗ | return ret; | |
948 | } | ||
949 |
2/2✓ Branch 0 taken 6337 times.
✓ Branch 1 taken 1 times.
|
6338 | if (!ms->force_fps) { |
950 | 6337 | ret = avcodec_get_supported_config(enc_ctx, NULL, | |
951 | AV_CODEC_CONFIG_FRAME_RATE, 0, | ||
952 | (const void **) &opts.frame_rates, NULL); | ||
953 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6337 times.
|
6337 | if (ret < 0) |
954 | ✗ | return ret; | |
955 | } | ||
956 | 6338 | ret = avcodec_get_supported_config(enc_ctx, NULL, | |
957 | AV_CODEC_CONFIG_COLOR_SPACE, 0, | ||
958 | (const void **) &opts.color_spaces, NULL); | ||
959 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6338 times.
|
6338 | if (ret < 0) |
960 | ✗ | return ret; | |
961 | 6338 | ret = avcodec_get_supported_config(enc_ctx, NULL, | |
962 | AV_CODEC_CONFIG_COLOR_RANGE, 0, | ||
963 | (const void **) &opts.color_ranges, NULL); | ||
964 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6338 times.
|
6338 | if (ret < 0) |
965 | ✗ | return ret; | |
966 | } else { | ||
967 | 1320 | ret = avcodec_get_supported_config(enc_ctx, NULL, | |
968 | AV_CODEC_CONFIG_SAMPLE_FORMAT, 0, | ||
969 | (const void **) &opts.formats, NULL); | ||
970 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1320 times.
|
1320 | if (ret < 0) |
971 | ✗ | return ret; | |
972 | 1320 | ret = avcodec_get_supported_config(enc_ctx, NULL, | |
973 | AV_CODEC_CONFIG_SAMPLE_RATE, 0, | ||
974 | (const void **) &opts.sample_rates, NULL); | ||
975 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1320 times.
|
1320 | if (ret < 0) |
976 | ✗ | return ret; | |
977 | 1320 | ret = avcodec_get_supported_config(enc_ctx, NULL, | |
978 | AV_CODEC_CONFIG_CHANNEL_LAYOUT, 0, | ||
979 | (const void **) &opts.ch_layouts, NULL); | ||
980 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1320 times.
|
1320 | if (ret < 0) |
981 | ✗ | return ret; | |
982 | } | ||
983 | |||
984 |
2/2✓ Branch 0 taken 4948 times.
✓ Branch 1 taken 2710 times.
|
7658 | if (threads_manual) { |
985 | 4948 | ret = av_opt_get(enc_ctx, "threads", 0, (uint8_t**)&opts.nb_threads); | |
986 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4948 times.
|
4948 | if (ret < 0) |
987 | ✗ | return ret; | |
988 | } | ||
989 | |||
990 | 7658 | ret = ost_get_filters(o, mux->fc, ost, &filters); | |
991 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7658 times.
|
7658 | if (ret < 0) |
992 | ✗ | return ret; | |
993 | |||
994 |
2/2✓ Branch 0 taken 1023 times.
✓ Branch 1 taken 6635 times.
|
7658 | if (ofilter) { |
995 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1023 times.
|
1023 | av_assert0(!filters); |
996 | 1023 | ost->filter = ofilter; | |
997 | 1023 | ret = ofilter_bind_enc(ofilter, ms->sch_idx_enc, &opts); | |
998 | } else { | ||
999 | 6635 | ret = fg_create_simple(&ost->fg_simple, ost->ist, filters, | |
1000 | 6635 | mux->sch, ms->sch_idx_enc, &opts); | |
1001 |
1/2✓ Branch 0 taken 6635 times.
✗ Branch 1 not taken.
|
6635 | if (ret >= 0) |
1002 | 6635 | ost->filter = ost->fg_simple->outputs[0]; | |
1003 | |||
1004 | } | ||
1005 | 7658 | av_freep(&opts.nb_threads); | |
1006 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7658 times.
|
7658 | if (ret < 0) |
1007 | ✗ | return ret; | |
1008 | |||
1009 | 7658 | *src = SCH_ENC(ms->sch_idx_enc); | |
1010 | |||
1011 | 7658 | return 0; | |
1012 | } | ||
1013 | |||
1014 | 660 | static int streamcopy_init(const OptionsContext *o, const Muxer *mux, | |
1015 | OutputStream *ost, AVDictionary **encoder_opts) | ||
1016 | { | ||
1017 | 660 | MuxStream *ms = ms_from_ost(ost); | |
1018 | |||
1019 | 660 | const InputStream *ist = ost->ist; | |
1020 | 660 | const InputFile *ifile = ist->file; | |
1021 | |||
1022 | 660 | AVCodecParameters *par = ms->par_in; | |
1023 | 660 | uint32_t codec_tag = par->codec_tag; | |
1024 | |||
1025 | 660 | AVCodecContext *codec_ctx = NULL; | |
1026 | |||
1027 | 660 | AVRational fr = ms->frame_rate; | |
1028 | |||
1029 | 660 | int ret = 0; | |
1030 | |||
1031 | 660 | const char *filters = NULL; | |
1032 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
1033 | 660 | const char *filters_script = NULL; | |
1034 | |||
1035 | 660 | opt_match_per_stream_str(ost, &o->filter_scripts, mux->fc, ost->st, &filters_script); | |
1036 | #endif | ||
1037 | 660 | opt_match_per_stream_str(ost, &o->filters, mux->fc, ost->st, &filters); | |
1038 | |||
1039 | 660 | if ( | |
1040 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
1041 |
2/4✓ Branch 0 taken 660 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 660 times.
|
660 | filters_script || |
1042 | #endif | ||
1043 | filters) { | ||
1044 | ✗ | av_log(ost, AV_LOG_ERROR, | |
1045 | "%s '%s' was specified, but codec copy was selected. " | ||
1046 | "Filtering and streamcopy cannot be used together.\n", | ||
1047 | #if FFMPEG_OPT_FILTER_SCRIPT | ||
1048 | ✗ | filters ? "Filtergraph" : "Filtergraph script", | |
1049 | ✗ | filters ? filters : filters_script | |
1050 | #else | ||
1051 | "Filtergraph", filters | ||
1052 | #endif | ||
1053 | ); | ||
1054 | ✗ | return AVERROR(EINVAL); | |
1055 | } | ||
1056 | |||
1057 | 660 | codec_ctx = avcodec_alloc_context3(NULL); | |
1058 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
|
660 | if (!codec_ctx) |
1059 | ✗ | return AVERROR(ENOMEM); | |
1060 | |||
1061 | 660 | ret = avcodec_parameters_to_context(codec_ctx, ist->par); | |
1062 |
1/2✓ Branch 0 taken 660 times.
✗ Branch 1 not taken.
|
660 | if (ret >= 0) |
1063 | 660 | ret = av_opt_set_dict(codec_ctx, encoder_opts); | |
1064 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
|
660 | if (ret < 0) { |
1065 | ✗ | av_log(ost, AV_LOG_FATAL, | |
1066 | "Error setting up codec context options.\n"); | ||
1067 | ✗ | goto fail; | |
1068 | } | ||
1069 | |||
1070 | 660 | ret = avcodec_parameters_from_context(par, codec_ctx); | |
1071 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
|
660 | if (ret < 0) { |
1072 | ✗ | av_log(ost, AV_LOG_FATAL, | |
1073 | "Error getting reference codec parameters.\n"); | ||
1074 | ✗ | goto fail; | |
1075 | } | ||
1076 | |||
1077 |
2/2✓ Branch 0 taken 654 times.
✓ Branch 1 taken 6 times.
|
660 | if (!codec_tag) { |
1078 | 654 | const struct AVCodecTag * const *ct = mux->fc->oformat->codec_tag; | |
1079 | unsigned int codec_tag_tmp; | ||
1080 |
6/6✓ Branch 0 taken 120 times.
✓ Branch 1 taken 534 times.
✓ Branch 3 taken 87 times.
✓ Branch 4 taken 33 times.
✓ Branch 5 taken 11 times.
✓ Branch 6 taken 76 times.
|
741 | if (!ct || av_codec_get_id (ct, par->codec_tag) == par->codec_id || |
1081 | 87 | !av_codec_get_tag2(ct, par->codec_id, &codec_tag_tmp)) | |
1082 | 578 | codec_tag = par->codec_tag; | |
1083 | } | ||
1084 | |||
1085 | 660 | par->codec_tag = codec_tag; | |
1086 | |||
1087 |
2/2✓ Branch 0 taken 659 times.
✓ Branch 1 taken 1 times.
|
660 | if (!fr.num) |
1088 | 659 | fr = ist->framerate; | |
1089 | |||
1090 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 658 times.
|
660 | if (fr.num) |
1091 | 2 | ost->st->avg_frame_rate = fr; | |
1092 | else | ||
1093 | 658 | ost->st->avg_frame_rate = ist->st->avg_frame_rate; | |
1094 | |||
1095 | // copy timebase while removing common factors | ||
1096 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
660 | if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0) { |
1097 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 658 times.
|
660 | if (fr.num) |
1098 | 2 | ost->st->time_base = av_inv_q(fr); | |
1099 | else | ||
1100 | 658 | ost->st->time_base = av_add_q(ist->st->time_base, (AVRational){0, 1}); | |
1101 | } | ||
1102 | |||
1103 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
|
660 | if (!ms->copy_prior_start) { |
1104 | ✗ | ms->ts_copy_start = (mux->of.start_time == AV_NOPTS_VALUE) ? | |
1105 | ✗ | 0 : mux->of.start_time; | |
1106 | ✗ | if (copy_ts && ifile->start_time != AV_NOPTS_VALUE) { | |
1107 | ✗ | ms->ts_copy_start = FFMAX(ms->ts_copy_start, | |
1108 | ifile->start_time + ifile->ts_offset); | ||
1109 | } | ||
1110 | } | ||
1111 | |||
1112 |
2/2✓ Branch 0 taken 78 times.
✓ Branch 1 taken 660 times.
|
738 | for (int i = 0; i < ist->st->codecpar->nb_coded_side_data; i++) { |
1113 | 78 | const AVPacketSideData *sd_src = &ist->st->codecpar->coded_side_data[i]; | |
1114 | AVPacketSideData *sd_dst; | ||
1115 | |||
1116 | 78 | sd_dst = av_packet_side_data_new(&ost->st->codecpar->coded_side_data, | |
1117 | 78 | &ost->st->codecpar->nb_coded_side_data, | |
1118 | 78 | sd_src->type, sd_src->size, 0); | |
1119 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 78 times.
|
78 | if (!sd_dst) { |
1120 | ✗ | ret = AVERROR(ENOMEM); | |
1121 | ✗ | goto fail; | |
1122 | } | ||
1123 | 78 | memcpy(sd_dst->data, sd_src->data, sd_src->size); | |
1124 | } | ||
1125 | |||
1126 |
3/3✓ Branch 0 taken 274 times.
✓ Branch 1 taken 343 times.
✓ Branch 2 taken 43 times.
|
660 | switch (par->codec_type) { |
1127 | 274 | case AVMEDIA_TYPE_AUDIO: | |
1128 |
4/6✓ Branch 0 taken 269 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 269 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 269 times.
|
274 | if ((par->block_align == 1 || par->block_align == 1152 || par->block_align == 576) && |
1129 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
|
5 | par->codec_id == AV_CODEC_ID_MP3) |
1130 | ✗ | par->block_align = 0; | |
1131 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 260 times.
|
274 | if (par->codec_id == AV_CODEC_ID_AC3) |
1132 | 14 | par->block_align = 0; | |
1133 | 274 | break; | |
1134 | 343 | case AVMEDIA_TYPE_VIDEO: { | |
1135 | AVRational sar; | ||
1136 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 343 times.
|
343 | if (ost->frame_aspect_ratio.num) { // overridden by the -aspect cli option |
1137 | sar = | ||
1138 | ✗ | av_mul_q(ost->frame_aspect_ratio, | |
1139 | ✗ | (AVRational){ par->height, par->width }); | |
1140 | ✗ | av_log(ost, AV_LOG_WARNING, "Overriding aspect ratio " | |
1141 | "with stream copy may produce invalid files\n"); | ||
1142 | } | ||
1143 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 253 times.
|
343 | else if (ist->st->sample_aspect_ratio.num) |
1144 | 90 | sar = ist->st->sample_aspect_ratio; | |
1145 | else | ||
1146 | 253 | sar = par->sample_aspect_ratio; | |
1147 | 343 | ost->st->sample_aspect_ratio = par->sample_aspect_ratio = sar; | |
1148 | 343 | ost->st->r_frame_rate = ist->st->r_frame_rate; | |
1149 | 343 | break; | |
1150 | } | ||
1151 | } | ||
1152 | |||
1153 | 660 | fail: | |
1154 | 660 | avcodec_free_context(&codec_ctx); | |
1155 | 660 | return ret; | |
1156 | } | ||
1157 | |||
1158 | 7696 | static int set_encoder_id(OutputStream *ost, const AVCodec *codec) | |
1159 | { | ||
1160 | 7696 | const char *cname = codec->name; | |
1161 | uint8_t *encoder_string; | ||
1162 | int encoder_string_len; | ||
1163 | |||
1164 | 7696 | encoder_string_len = sizeof(LIBAVCODEC_IDENT) + strlen(cname) + 2; | |
1165 | 7696 | encoder_string = av_mallocz(encoder_string_len); | |
1166 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
|
7696 | if (!encoder_string) |
1167 | ✗ | return AVERROR(ENOMEM); | |
1168 | |||
1169 |
4/4✓ Branch 0 taken 845 times.
✓ Branch 1 taken 6851 times.
✓ Branch 2 taken 838 times.
✓ Branch 3 taken 7 times.
|
7696 | if (!ost->file->bitexact && !ost->bitexact) |
1170 | 838 | av_strlcpy(encoder_string, LIBAVCODEC_IDENT " ", encoder_string_len); | |
1171 | else | ||
1172 | 6858 | av_strlcpy(encoder_string, "Lavc ", encoder_string_len); | |
1173 | 7696 | av_strlcat(encoder_string, cname, encoder_string_len); | |
1174 | 7696 | av_dict_set(&ost->st->metadata, "encoder", encoder_string, | |
1175 | AV_DICT_DONT_STRDUP_VAL | AV_DICT_DONT_OVERWRITE); | ||
1176 | |||
1177 | 7696 | return 0; | |
1178 | } | ||
1179 | |||
1180 | 8357 | static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, | |
1181 | InputStream *ist, OutputFilter *ofilter, const ViewSpecifier *vs, | ||
1182 | OutputStream **post) | ||
1183 | { | ||
1184 | 8357 | AVFormatContext *oc = mux->fc; | |
1185 | MuxStream *ms; | ||
1186 | OutputStream *ost; | ||
1187 | const AVCodec *enc; | ||
1188 | AVStream *st; | ||
1189 | 8357 | SchedulerNode src = { .type = SCH_NODE_TYPE_NONE }; | |
1190 | 8357 | AVDictionary *encoder_opts = NULL; | |
1191 | 8357 | int ret = 0, keep_pix_fmt = 0, autoscale = 1; | |
1192 | 8357 | int threads_manual = 0; | |
1193 | 8357 | AVRational enc_tb = { 0, 0 }; | |
1194 | 8357 | enum VideoSyncMethod vsync_method = VSYNC_AUTO; | |
1195 | 8357 | const char *bsfs = NULL, *time_base = NULL, *codec_tag = NULL; | |
1196 | char *next; | ||
1197 | 8357 | double qscale = -1; | |
1198 | |||
1199 | 8357 | st = avformat_new_stream(oc, NULL); | |
1200 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8357 times.
|
8357 | if (!st) |
1201 | ✗ | return AVERROR(ENOMEM); | |
1202 | |||
1203 | 8357 | ms = mux_stream_alloc(mux, type); | |
1204 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8357 times.
|
8357 | if (!ms) |
1205 | ✗ | return AVERROR(ENOMEM); | |
1206 | |||
1207 | // only streams with sources (i.e. not attachments) | ||
1208 | // are handled by the scheduler | ||
1209 |
4/4✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 7333 times.
✓ Branch 2 taken 1023 times.
✓ Branch 3 taken 1 times.
|
8357 | if (ist || ofilter) { |
1210 | 8356 | ret = GROW_ARRAY(mux->sch_stream_idx, mux->nb_sch_stream_idx); | |
1211 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8356 times.
|
8356 | if (ret < 0) |
1212 | ✗ | return ret; | |
1213 | |||
1214 | 8356 | ret = sch_add_mux_stream(mux->sch, mux->sch_idx); | |
1215 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8356 times.
|
8356 | if (ret < 0) |
1216 | ✗ | return ret; | |
1217 | |||
1218 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8356 times.
|
8356 | av_assert0(ret == mux->nb_sch_stream_idx - 1); |
1219 | 8356 | mux->sch_stream_idx[ret] = ms->ost.index; | |
1220 | 8356 | ms->sch_idx = ret; | |
1221 | } | ||
1222 | |||
1223 | 8357 | ost = &ms->ost; | |
1224 | |||
1225 |
2/2✓ Branch 0 taken 49 times.
✓ Branch 1 taken 8308 times.
|
8357 | if (o->streamid) { |
1226 | AVDictionaryEntry *e; | ||
1227 | char idx[16], *p; | ||
1228 | 49 | snprintf(idx, sizeof(idx), "%d", ost->index); | |
1229 | |||
1230 | 49 | e = av_dict_get(o->streamid, idx, NULL, 0); | |
1231 |
1/2✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
|
49 | if (e) { |
1232 | 49 | st->id = strtol(e->value, &p, 0); | |
1233 |
2/4✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
|
49 | if (!e->value[0] || *p) { |
1234 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid stream id: %s\n", e->value); | |
1235 | ✗ | return AVERROR(EINVAL); | |
1236 | } | ||
1237 | } | ||
1238 | } | ||
1239 | |||
1240 | 8357 | ms->par_in = avcodec_parameters_alloc(); | |
1241 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8357 times.
|
8357 | if (!ms->par_in) |
1242 | ✗ | return AVERROR(ENOMEM); | |
1243 | |||
1244 | 8357 | ms->last_mux_dts = AV_NOPTS_VALUE; | |
1245 | |||
1246 | 8357 | ost->st = st; | |
1247 | 8357 | ost->ist = ist; | |
1248 | 8357 | ost->kf.ref_pts = AV_NOPTS_VALUE; | |
1249 | 8357 | ms->par_in->codec_type = type; | |
1250 | 8357 | st->codecpar->codec_type = type; | |
1251 | |||
1252 | 8357 | ret = choose_encoder(o, oc, ms, &enc); | |
1253 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8357 times.
|
8357 | if (ret < 0) { |
1254 | ✗ | av_log(ost, AV_LOG_FATAL, "Error selecting an encoder\n"); | |
1255 | ✗ | return ret; | |
1256 | } | ||
1257 | |||
1258 |
2/2✓ Branch 0 taken 7696 times.
✓ Branch 1 taken 661 times.
|
8357 | if (enc) { |
1259 | 7696 | ret = sch_add_enc(mux->sch, encoder_thread, ost, | |
1260 |
2/2✓ Branch 0 taken 7658 times.
✓ Branch 1 taken 38 times.
|
7696 | ost->type == AVMEDIA_TYPE_SUBTITLE ? NULL : enc_open); |
1261 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
|
7696 | if (ret < 0) |
1262 | ✗ | return ret; | |
1263 | 7696 | ms->sch_idx_enc = ret; | |
1264 | |||
1265 | 7696 | ret = enc_alloc(&ost->enc, enc, mux->sch, ms->sch_idx_enc, ost); | |
1266 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
|
7696 | if (ret < 0) |
1267 | ✗ | return ret; | |
1268 | |||
1269 | 7696 | av_strlcat(ms->log_name, "/", sizeof(ms->log_name)); | |
1270 | 7696 | av_strlcat(ms->log_name, enc->name, sizeof(ms->log_name)); | |
1271 | } else { | ||
1272 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 661 times.
|
661 | if (ofilter) { |
1273 | ✗ | av_log(ost, AV_LOG_ERROR, | |
1274 | "Streamcopy requested for output stream fed " | ||
1275 | "from a complex filtergraph. Filtering and streamcopy " | ||
1276 | "cannot be used together.\n"); | ||
1277 | ✗ | return AVERROR(EINVAL); | |
1278 | } | ||
1279 | |||
1280 | 661 | av_strlcat(ms->log_name, "/copy", sizeof(ms->log_name)); | |
1281 | } | ||
1282 | |||
1283 | 8357 | av_log(ost, AV_LOG_VERBOSE, "Created %s stream from ", | |
1284 | av_get_media_type_string(type)); | ||
1285 |
2/2✓ Branch 0 taken 7333 times.
✓ Branch 1 taken 1024 times.
|
8357 | if (ist) |
1286 | 7333 | av_log(ost, AV_LOG_VERBOSE, "input stream %d:%d", | |
1287 | 7333 | ist->file->index, ist->index); | |
1288 |
2/2✓ Branch 0 taken 1023 times.
✓ Branch 1 taken 1 times.
|
1024 | else if (ofilter) |
1289 | 1023 | av_log(ost, AV_LOG_VERBOSE, "complex filtergraph %d:[%s]\n", | |
1290 | 1023 | ofilter->graph->index, ofilter->name); | |
1291 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | else if (type == AVMEDIA_TYPE_ATTACHMENT) |
1292 | 1 | av_log(ost, AV_LOG_VERBOSE, "attached file"); | |
1293 | ✗ | else av_assert0(0); | |
1294 | 8357 | av_log(ost, AV_LOG_VERBOSE, "\n"); | |
1295 | |||
1296 | 8357 | ms->pkt = av_packet_alloc(); | |
1297 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8357 times.
|
8357 | if (!ms->pkt) |
1298 | ✗ | return AVERROR(ENOMEM); | |
1299 | |||
1300 |
2/2✓ Branch 0 taken 7696 times.
✓ Branch 1 taken 661 times.
|
8357 | if (ost->enc) { |
1301 | 7696 | AVIOContext *s = NULL; | |
1302 | 7696 | char *buf = NULL, *arg = NULL; | |
1303 | 7696 | const char *enc_stats_pre = NULL, *enc_stats_post = NULL, *mux_stats = NULL; | |
1304 | 7696 | const char *enc_time_base = NULL, *preset = NULL; | |
1305 | |||
1306 | 7696 | ret = filter_codec_opts(o->g->codec_opts, enc->id, | |
1307 | oc, st, enc, &encoder_opts, | ||
1308 | &mux->enc_opts_used); | ||
1309 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
|
7696 | if (ret < 0) |
1310 | ✗ | goto fail; | |
1311 | |||
1312 | 7696 | opt_match_per_stream_str(ost, &o->presets, oc, st, &preset); | |
1313 | 7696 | opt_match_per_stream_int(ost, &o->autoscale, oc, st, &autoscale); | |
1314 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
7696 | if (preset && (!(ret = get_preset_file_2(preset, enc->name, &s)))) { |
1315 | AVBPrint bprint; | ||
1316 | ✗ | av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED); | |
1317 | do { | ||
1318 | ✗ | av_bprint_clear(&bprint); | |
1319 | ✗ | buf = get_line(s, &bprint); | |
1320 | ✗ | if (!buf) { | |
1321 | ✗ | ret = AVERROR(ENOMEM); | |
1322 | ✗ | break; | |
1323 | } | ||
1324 | |||
1325 | ✗ | if (!buf[0] || buf[0] == '#') | |
1326 | ✗ | continue; | |
1327 | ✗ | if (!(arg = strchr(buf, '='))) { | |
1328 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid line found in the preset file.\n"); | |
1329 | ✗ | ret = AVERROR(EINVAL); | |
1330 | ✗ | break; | |
1331 | } | ||
1332 | ✗ | *arg++ = 0; | |
1333 | ✗ | av_dict_set(&encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE); | |
1334 | ✗ | } while (!s->eof_reached); | |
1335 | ✗ | av_bprint_finalize(&bprint, NULL); | |
1336 | ✗ | avio_closep(&s); | |
1337 | } | ||
1338 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
|
7696 | if (ret) { |
1339 | ✗ | av_log(ost, AV_LOG_FATAL, | |
1340 | "Preset %s specified, but could not be opened.\n", preset); | ||
1341 | ✗ | goto fail; | |
1342 | } | ||
1343 | |||
1344 | 7696 | opt_match_per_stream_str(ost, &o->enc_stats_pre, oc, st, &enc_stats_pre); | |
1345 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7696 | if (enc_stats_pre && |
1346 | ✗ | (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) { | |
1347 | ✗ | const char *format = "{fidx} {sidx} {n} {t}"; | |
1348 | |||
1349 | ✗ | opt_match_per_stream_str(ost, &o->enc_stats_pre_fmt, oc, st, &format); | |
1350 | |||
1351 | ✗ | ret = enc_stats_init(ost, &ost->enc_stats_pre, 1, enc_stats_pre, format); | |
1352 | ✗ | if (ret < 0) | |
1353 | ✗ | goto fail; | |
1354 | } | ||
1355 | |||
1356 | 7696 | opt_match_per_stream_str(ost, &o->enc_stats_post, oc, st, &enc_stats_post); | |
1357 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7696 | if (enc_stats_post && |
1358 | ✗ | (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) { | |
1359 | ✗ | const char *format = "{fidx} {sidx} {n} {t}"; | |
1360 | |||
1361 | ✗ | opt_match_per_stream_str(ost, &o->enc_stats_post_fmt, oc, st, &format); | |
1362 | |||
1363 | ✗ | ret = enc_stats_init(ost, &ost->enc_stats_post, 0, enc_stats_post, format); | |
1364 | ✗ | if (ret < 0) | |
1365 | ✗ | goto fail; | |
1366 | } | ||
1367 | |||
1368 | 7696 | opt_match_per_stream_str(ost, &o->mux_stats, oc, st, &mux_stats); | |
1369 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7696 | if (mux_stats && |
1370 | ✗ | (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) { | |
1371 | ✗ | const char *format = "{fidx} {sidx} {n} {t}"; | |
1372 | |||
1373 | ✗ | opt_match_per_stream_str(ost, &o->mux_stats_fmt, oc, st, &format); | |
1374 | |||
1375 | ✗ | ret = enc_stats_init(ost, &ms->stats, 0, mux_stats, format); | |
1376 | ✗ | if (ret < 0) | |
1377 | ✗ | goto fail; | |
1378 | } | ||
1379 | |||
1380 | 7696 | opt_match_per_stream_str(ost, &o->enc_time_bases, oc, st, &enc_time_base); | |
1381 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7695 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
7696 | if (enc_time_base && type == AVMEDIA_TYPE_SUBTITLE) |
1382 | ✗ | av_log(ost, AV_LOG_WARNING, | |
1383 | "-enc_time_base not supported for subtitles, ignoring\n"); | ||
1384 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7695 times.
|
7696 | else if (enc_time_base) { |
1385 | AVRational q; | ||
1386 | |||
1387 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (!strcmp(enc_time_base, "demux")) { |
1388 | 1 | q = (AVRational){ ENC_TIME_BASE_DEMUX, 0 }; | |
1389 | ✗ | } else if (!strcmp(enc_time_base, "filter")) { | |
1390 | ✗ | q = (AVRational){ ENC_TIME_BASE_FILTER, 0 }; | |
1391 | } else { | ||
1392 | ✗ | ret = av_parse_ratio(&q, enc_time_base, INT_MAX, 0, NULL); | |
1393 | ✗ | if (ret < 0 || q.den <= 0 | |
1394 | #if !FFMPEG_OPT_ENC_TIME_BASE_NUM | ||
1395 | || q.num < 0 | ||
1396 | #endif | ||
1397 | ) { | ||
1398 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", enc_time_base); | |
1399 | ✗ | ret = ret < 0 ? ret : AVERROR(EINVAL); | |
1400 | ✗ | goto fail; | |
1401 | } | ||
1402 | #if FFMPEG_OPT_ENC_TIME_BASE_NUM | ||
1403 | ✗ | if (q.num < 0) | |
1404 | ✗ | av_log(ost, AV_LOG_WARNING, "-enc_time_base -1 is deprecated," | |
1405 | " use -enc_time_base demux\n"); | ||
1406 | #endif | ||
1407 | } | ||
1408 | |||
1409 | 1 | enc_tb = q; | |
1410 | } | ||
1411 | |||
1412 | 7696 | threads_manual = !!av_dict_get(encoder_opts, "threads", NULL, 0); | |
1413 | |||
1414 | 7696 | ret = av_opt_set_dict2(ost->enc->enc_ctx, &encoder_opts, AV_OPT_SEARCH_CHILDREN); | |
1415 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
|
7696 | if (ret < 0) { |
1416 | ✗ | av_log(ost, AV_LOG_ERROR, "Error applying encoder options: %s\n", | |
1417 | ✗ | av_err2str(ret)); | |
1418 | ✗ | goto fail; | |
1419 | } | ||
1420 | |||
1421 | 7696 | ret = check_avoptions(encoder_opts); | |
1422 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
|
7696 | if (ret < 0) |
1423 | ✗ | goto fail; | |
1424 | |||
1425 | // default to automatic thread count | ||
1426 |
2/2✓ Branch 0 taken 2748 times.
✓ Branch 1 taken 4948 times.
|
7696 | if (!threads_manual) |
1427 | 2748 | ost->enc->enc_ctx->thread_count = 0; | |
1428 | } else { | ||
1429 | 661 | ret = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, | |
1430 | NULL, &encoder_opts, | ||
1431 | &mux->enc_opts_used); | ||
1432 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 661 times.
|
661 | if (ret < 0) |
1433 | ✗ | goto fail; | |
1434 | } | ||
1435 | |||
1436 | |||
1437 |
2/2✓ Branch 0 taken 1960 times.
✓ Branch 1 taken 6397 times.
|
8357 | if (o->bitexact) { |
1438 | 1960 | ost->bitexact = 1; | |
1439 |
2/2✓ Branch 0 taken 5845 times.
✓ Branch 1 taken 552 times.
|
6397 | } else if (ost->enc) { |
1440 | 5845 | ost->bitexact = !!(ost->enc->enc_ctx->flags & AV_CODEC_FLAG_BITEXACT); | |
1441 | } | ||
1442 | |||
1443 |
2/2✓ Branch 0 taken 7696 times.
✓ Branch 1 taken 661 times.
|
8357 | if (enc) { |
1444 | 7696 | ret = set_encoder_id(ost, enc); | |
1445 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7696 times.
|
7696 | if (ret < 0) |
1446 | ✗ | return ret; | |
1447 | } | ||
1448 | |||
1449 | 8357 | opt_match_per_stream_str(ost, &o->time_bases, oc, st, &time_base); | |
1450 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8355 times.
|
8357 | if (time_base) { |
1451 | AVRational q; | ||
1452 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | if (av_parse_ratio(&q, time_base, INT_MAX, 0, NULL) < 0 || |
1453 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
|
2 | q.num <= 0 || q.den <= 0) { |
1454 | ✗ | av_log(ost, AV_LOG_FATAL, "Invalid time base: %s\n", time_base); | |
1455 | ✗ | ret = AVERROR(EINVAL); | |
1456 | ✗ | goto fail; | |
1457 | } | ||
1458 | 2 | st->time_base = q; | |
1459 | } | ||
1460 | |||
1461 | 8357 | ms->max_frames = INT64_MAX; | |
1462 | 8357 | opt_match_per_stream_int64(ost, &o->max_frames, oc, st, &ms->max_frames); | |
1463 |
2/2✓ Branch 0 taken 5206 times.
✓ Branch 1 taken 8351 times.
|
13557 | for (int i = 0; i < o->max_frames.nb_opt; i++) { |
1464 | 5206 | char *p = o->max_frames.opt[i].specifier; | |
1465 |
4/4✓ Branch 0 taken 169 times.
✓ Branch 1 taken 5037 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 163 times.
|
5206 | if (!*p && type != AVMEDIA_TYPE_VIDEO) { |
1466 | 6 | av_log(ost, AV_LOG_WARNING, "Applying unspecific -frames to non video streams, maybe you meant -vframes ?\n"); | |
1467 | 6 | break; | |
1468 | } | ||
1469 | } | ||
1470 | |||
1471 | 8357 | ms->copy_prior_start = -1; | |
1472 | 8357 | opt_match_per_stream_int(ost, &o->copy_prior_start, oc, st, &ms->copy_prior_start); | |
1473 | 8357 | opt_match_per_stream_str(ost, &o->bitstream_filters, oc, st, &bsfs); | |
1474 |
3/4✓ Branch 0 taken 133 times.
✓ Branch 1 taken 8224 times.
✓ Branch 2 taken 133 times.
✗ Branch 3 not taken.
|
8357 | if (bsfs && *bsfs) { |
1475 | 133 | ret = av_bsf_list_parse_str(bsfs, &ms->bsf_ctx); | |
1476 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 133 times.
|
133 | if (ret < 0) { |
1477 | ✗ | av_log(ost, AV_LOG_ERROR, "Error parsing bitstream filter sequence '%s': %s\n", bsfs, av_err2str(ret)); | |
1478 | ✗ | goto fail; | |
1479 | } | ||
1480 | } | ||
1481 | |||
1482 | 8357 | opt_match_per_stream_str(ost, &o->codec_tags, oc, st, &codec_tag); | |
1483 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 8350 times.
|
8357 | if (codec_tag) { |
1484 | 7 | uint32_t tag = strtol(codec_tag, &next, 0); | |
1485 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (*next) { |
1486 | 7 | uint8_t buf[4] = { 0 }; | |
1487 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | memcpy(buf, codec_tag, FFMIN(sizeof(buf), strlen(codec_tag))); |
1488 | 7 | tag = AV_RL32(buf); | |
1489 | } | ||
1490 | 7 | ost->st->codecpar->codec_tag = tag; | |
1491 | 7 | ms->par_in->codec_tag = tag; | |
1492 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if (ost->enc) |
1493 | 1 | ost->enc->enc_ctx->codec_tag = tag; | |
1494 | } | ||
1495 | |||
1496 | 8357 | opt_match_per_stream_dbl(ost, &o->qscale, oc, st, &qscale); | |
1497 |
4/4✓ Branch 0 taken 7696 times.
✓ Branch 1 taken 661 times.
✓ Branch 2 taken 266 times.
✓ Branch 3 taken 7430 times.
|
8357 | if (ost->enc && qscale >= 0) { |
1498 | 266 | ost->enc->enc_ctx->flags |= AV_CODEC_FLAG_QSCALE; | |
1499 | 266 | ost->enc->enc_ctx->global_quality = FF_QP2LAMBDA * qscale; | |
1500 | } | ||
1501 | |||
1502 |
2/2✓ Branch 0 taken 8356 times.
✓ Branch 1 taken 1 times.
|
8357 | if (ms->sch_idx >= 0) { |
1503 | 8356 | int max_muxing_queue_size = 128; | |
1504 | 8356 | int muxing_queue_data_threshold = 50 * 1024 * 1024; | |
1505 | |||
1506 | 8356 | opt_match_per_stream_int(ost, &o->max_muxing_queue_size, oc, st, | |
1507 | &max_muxing_queue_size); | ||
1508 | 8356 | opt_match_per_stream_int(ost, &o->muxing_queue_data_threshold, | |
1509 | oc, st, &muxing_queue_data_threshold); | ||
1510 | |||
1511 | 8356 | sch_mux_stream_buffering(mux->sch, mux->sch_idx, ms->sch_idx, | |
1512 | max_muxing_queue_size, muxing_queue_data_threshold); | ||
1513 | } | ||
1514 | |||
1515 | 8357 | opt_match_per_stream_int(ost, &o->bits_per_raw_sample, oc, st, | |
1516 | &ost->bits_per_raw_sample); | ||
1517 | |||
1518 | 8357 | opt_match_per_stream_int(ost, &o->fix_sub_duration_heartbeat, | |
1519 | 8357 | oc, st, &ost->fix_sub_duration_heartbeat); | |
1520 | |||
1521 |
4/4✓ Branch 0 taken 3062 times.
✓ Branch 1 taken 5295 times.
✓ Branch 2 taken 2958 times.
✓ Branch 3 taken 104 times.
|
8357 | if (oc->oformat->flags & AVFMT_GLOBALHEADER && ost->enc) |
1522 | 2958 | ost->enc->enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; | |
1523 | |||
1524 | 8357 | opt_match_per_stream_int(ost, &o->copy_initial_nonkeyframes, | |
1525 | oc, st, &ms->copy_initial_nonkeyframes); | ||
1526 |
4/4✓ Branch 0 taken 6681 times.
✓ Branch 1 taken 1594 times.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 11 times.
|
8357 | switch (type) { |
1527 | 6681 | case AVMEDIA_TYPE_VIDEO: ret = new_stream_video (mux, o, ost, &keep_pix_fmt, &vsync_method); break; | |
1528 | 1594 | case AVMEDIA_TYPE_AUDIO: ret = new_stream_audio (mux, o, ost); break; | |
1529 | 71 | case AVMEDIA_TYPE_SUBTITLE: ret = new_stream_subtitle (mux, o, ost); break; | |
1530 | } | ||
1531 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8357 times.
|
8357 | if (ret < 0) |
1532 | ✗ | goto fail; | |
1533 | |||
1534 |
4/4✓ Branch 0 taken 7696 times.
✓ Branch 1 taken 661 times.
✓ Branch 2 taken 1358 times.
✓ Branch 3 taken 6338 times.
|
8357 | if (ost->enc && |
1535 |
2/2✓ Branch 0 taken 1320 times.
✓ Branch 1 taken 38 times.
|
1358 | (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) { |
1536 | 7658 | ret = ost_bind_filter(mux, ms, ofilter, o, enc_tb, vsync_method, | |
1537 | keep_pix_fmt, autoscale, threads_manual, vs, &src); | ||
1538 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7658 times.
|
7658 | if (ret < 0) |
1539 | ✗ | goto fail; | |
1540 |
2/2✓ Branch 0 taken 698 times.
✓ Branch 1 taken 1 times.
|
699 | } else if (ost->ist) { |
1541 | 698 | ret = ist_use(ost->ist, !!ost->enc, NULL, &src); | |
1542 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 698 times.
|
698 | if (ret < 0) { |
1543 | ✗ | av_log(ost, AV_LOG_ERROR, | |
1544 | "Error binding an input stream\n"); | ||
1545 | ✗ | goto fail; | |
1546 | } | ||
1547 | 698 | ms->sch_idx_src = src.idx; | |
1548 | |||
1549 | // src refers to a decoder for transcoding, demux stream otherwise | ||
1550 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 660 times.
|
698 | if (ost->enc) { |
1551 | 38 | ret = sch_connect(mux->sch, | |
1552 | 38 | src, SCH_ENC(ms->sch_idx_enc)); | |
1553 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
|
38 | if (ret < 0) |
1554 | ✗ | goto fail; | |
1555 | 38 | src = SCH_ENC(ms->sch_idx_enc); | |
1556 | } | ||
1557 | } | ||
1558 | |||
1559 |
2/2✓ Branch 0 taken 8356 times.
✓ Branch 1 taken 1 times.
|
8357 | if (src.type != SCH_NODE_TYPE_NONE) { |
1560 | 8356 | ret = sch_connect(mux->sch, | |
1561 | 8356 | src, SCH_MSTREAM(mux->sch_idx, ms->sch_idx)); | |
1562 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8356 times.
|
8356 | if (ret < 0) |
1563 | ✗ | goto fail; | |
1564 | } else { | ||
1565 | // only attachment streams don't have a source | ||
1566 |
2/4✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
1 | av_assert0(type == AVMEDIA_TYPE_ATTACHMENT && ms->sch_idx < 0); |
1567 | } | ||
1568 | |||
1569 |
4/4✓ Branch 0 taken 7333 times.
✓ Branch 1 taken 1024 times.
✓ Branch 2 taken 660 times.
✓ Branch 3 taken 6673 times.
|
8357 | if (ost->ist && !ost->enc) { |
1570 | 660 | ret = streamcopy_init(o, mux, ost, &encoder_opts); | |
1571 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 660 times.
|
660 | if (ret < 0) |
1572 | ✗ | goto fail; | |
1573 | } | ||
1574 | |||
1575 | // copy estimated duration as a hint to the muxer | ||
1576 |
4/4✓ Branch 0 taken 7333 times.
✓ Branch 1 taken 1024 times.
✓ Branch 2 taken 5798 times.
✓ Branch 3 taken 1535 times.
|
8357 | if (ost->ist && ost->ist->st->duration > 0) { |
1577 | 5798 | ms->stream_duration = ist->st->duration; | |
1578 | 5798 | ms->stream_duration_tb = ist->st->time_base; | |
1579 | } | ||
1580 | |||
1581 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8356 times.
|
8357 | if (post) |
1582 | 1 | *post = ost; | |
1583 | |||
1584 | 8357 | ret = 0; | |
1585 | |||
1586 | 8357 | fail: | |
1587 | 8357 | av_dict_free(&encoder_opts); | |
1588 | |||
1589 | 8357 | return ret; | |
1590 | } | ||
1591 | |||
1592 | 6722 | static int map_auto_video(Muxer *mux, const OptionsContext *o) | |
1593 | { | ||
1594 | 6722 | AVFormatContext *oc = mux->fc; | |
1595 | 6722 | InputStream *best_ist = NULL; | |
1596 | 6722 | int best_score = 0; | |
1597 | int qcr; | ||
1598 | |||
1599 | /* video: highest resolution */ | ||
1600 |
2/2✓ Branch 1 taken 732 times.
✓ Branch 2 taken 5990 times.
|
6722 | if (av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_VIDEO) == AV_CODEC_ID_NONE) |
1601 | 732 | return 0; | |
1602 | |||
1603 | 5990 | qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0); | |
1604 |
2/2✓ Branch 0 taken 6030 times.
✓ Branch 1 taken 5990 times.
|
12020 | for (int j = 0; j < nb_input_files; j++) { |
1605 | 6030 | InputFile *ifile = input_files[j]; | |
1606 | 6030 | InputStream *file_best_ist = NULL; | |
1607 | 6030 | int file_best_score = 0; | |
1608 |
2/2✓ Branch 0 taken 6309 times.
✓ Branch 1 taken 6030 times.
|
12339 | for (int i = 0; i < ifile->nb_streams; i++) { |
1609 | 6309 | InputStream *ist = ifile->streams[i]; | |
1610 | int score; | ||
1611 | |||
1612 |
2/2✓ Branch 0 taken 6308 times.
✓ Branch 1 taken 1 times.
|
6309 | if (ist->user_set_discard == AVDISCARD_ALL || |
1613 |
2/2✓ Branch 0 taken 633 times.
✓ Branch 1 taken 5675 times.
|
6308 | ist->st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) |
1614 | 634 | continue; | |
1615 | |||
1616 | 11350 | score = ist->st->codecpar->width * ist->st->codecpar->height | |
1617 |
2/2✓ Branch 0 taken 5673 times.
✓ Branch 1 taken 2 times.
|
5675 | + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS) |
1618 |
2/2✓ Branch 0 taken 519 times.
✓ Branch 1 taken 5156 times.
|
5675 | + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT); |
1619 |
3/4✓ Branch 0 taken 5675 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 5666 times.
|
5675 | if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) |
1620 | 9 | score = 1; | |
1621 | |||
1622 |
2/2✓ Branch 0 taken 5674 times.
✓ Branch 1 taken 1 times.
|
5675 | if (score > file_best_score) { |
1623 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 5674 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
5674 | if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) |
1624 | ✗ | continue; | |
1625 | 5674 | file_best_score = score; | |
1626 | 5674 | file_best_ist = ist; | |
1627 | } | ||
1628 | } | ||
1629 |
2/2✓ Branch 0 taken 5674 times.
✓ Branch 1 taken 356 times.
|
6030 | if (file_best_ist) { |
1630 |
1/2✓ Branch 0 taken 5674 times.
✗ Branch 1 not taken.
|
5674 | if((qcr == MKTAG('A', 'P', 'I', 'C')) || |
1631 |
2/2✓ Branch 0 taken 5666 times.
✓ Branch 1 taken 8 times.
|
5674 | !(file_best_ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC)) |
1632 |
2/2✓ Branch 0 taken 519 times.
✓ Branch 1 taken 5147 times.
|
5666 | file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT); |
1633 |
1/2✓ Branch 0 taken 5674 times.
✗ Branch 1 not taken.
|
5674 | if (file_best_score > best_score) { |
1634 | 5674 | best_score = file_best_score; | |
1635 | 5674 | best_ist = file_best_ist; | |
1636 | } | ||
1637 | } | ||
1638 | } | ||
1639 |
2/2✓ Branch 0 taken 5674 times.
✓ Branch 1 taken 316 times.
|
5990 | if (best_ist) |
1640 | 5674 | return ost_add(mux, o, AVMEDIA_TYPE_VIDEO, best_ist, NULL, NULL, NULL); | |
1641 | |||
1642 | 316 | return 0; | |
1643 | } | ||
1644 | |||
1645 | 7594 | static int map_auto_audio(Muxer *mux, const OptionsContext *o) | |
1646 | { | ||
1647 | 7594 | AVFormatContext *oc = mux->fc; | |
1648 | 7594 | InputStream *best_ist = NULL; | |
1649 | 7594 | int best_score = 0; | |
1650 | |||
1651 | /* audio: most channels */ | ||
1652 |
2/2✓ Branch 1 taken 1637 times.
✓ Branch 2 taken 5957 times.
|
7594 | if (av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_AUDIO) == AV_CODEC_ID_NONE) |
1653 | 1637 | return 0; | |
1654 | |||
1655 |
2/2✓ Branch 0 taken 5942 times.
✓ Branch 1 taken 5957 times.
|
11899 | for (int j = 0; j < nb_input_files; j++) { |
1656 | 5942 | InputFile *ifile = input_files[j]; | |
1657 | 5942 | InputStream *file_best_ist = NULL; | |
1658 | 5942 | int file_best_score = 0; | |
1659 |
2/2✓ Branch 0 taken 6147 times.
✓ Branch 1 taken 5942 times.
|
12089 | for (int i = 0; i < ifile->nb_streams; i++) { |
1660 | 6147 | InputStream *ist = ifile->streams[i]; | |
1661 | int score; | ||
1662 | |||
1663 |
2/2✓ Branch 0 taken 6146 times.
✓ Branch 1 taken 1 times.
|
6147 | if (ist->user_set_discard == AVDISCARD_ALL || |
1664 |
2/2✓ Branch 0 taken 4850 times.
✓ Branch 1 taken 1296 times.
|
6146 | ist->st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) |
1665 | 4851 | continue; | |
1666 | |||
1667 | 2592 | score = ist->st->codecpar->ch_layout.nb_channels | |
1668 |
2/2✓ Branch 0 taken 1295 times.
✓ Branch 1 taken 1 times.
|
1296 | + 100000000 * !!(ist->st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS) |
1669 |
2/2✓ Branch 0 taken 174 times.
✓ Branch 1 taken 1122 times.
|
1296 | + 5000000*!!(ist->st->disposition & AV_DISPOSITION_DEFAULT); |
1670 |
2/2✓ Branch 0 taken 1286 times.
✓ Branch 1 taken 10 times.
|
1296 | if (score > file_best_score) { |
1671 | 1286 | file_best_score = score; | |
1672 | 1286 | file_best_ist = ist; | |
1673 | } | ||
1674 | } | ||
1675 |
2/2✓ Branch 0 taken 1286 times.
✓ Branch 1 taken 4656 times.
|
5942 | if (file_best_ist) { |
1676 |
2/2✓ Branch 0 taken 174 times.
✓ Branch 1 taken 1112 times.
|
1286 | file_best_score -= 5000000*!!(file_best_ist->st->disposition & AV_DISPOSITION_DEFAULT); |
1677 |
1/2✓ Branch 0 taken 1286 times.
✗ Branch 1 not taken.
|
1286 | if (file_best_score > best_score) { |
1678 | 1286 | best_score = file_best_score; | |
1679 | 1286 | best_ist = file_best_ist; | |
1680 | } | ||
1681 | } | ||
1682 | } | ||
1683 |
2/2✓ Branch 0 taken 1286 times.
✓ Branch 1 taken 4671 times.
|
5957 | if (best_ist) |
1684 | 1286 | return ost_add(mux, o, AVMEDIA_TYPE_AUDIO, best_ist, NULL, NULL, NULL); | |
1685 | |||
1686 | 4671 | return 0; | |
1687 | } | ||
1688 | |||
1689 | 7754 | static int map_auto_subtitle(Muxer *mux, const OptionsContext *o) | |
1690 | { | ||
1691 | 7754 | AVFormatContext *oc = mux->fc; | |
1692 | 7754 | const char *subtitle_codec_name = NULL; | |
1693 | |||
1694 | /* subtitles: pick first */ | ||
1695 | 7754 | subtitle_codec_name = opt_match_per_type_str(&o->codec_names, 's'); | |
1696 |
4/4✓ Branch 1 taken 7694 times.
✓ Branch 2 taken 60 times.
✓ Branch 3 taken 7687 times.
✓ Branch 4 taken 7 times.
|
7754 | if (!avcodec_find_encoder(oc->oformat->subtitle_codec) && !subtitle_codec_name) |
1697 | 7687 | return 0; | |
1698 | |||
1699 |
2/2✓ Branch 2 taken 81 times.
✓ Branch 3 taken 19 times.
|
100 | for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) |
1700 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 33 times.
|
81 | if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) { |
1701 | AVCodecDescriptor const *input_descriptor = | ||
1702 | 48 | avcodec_descriptor_get(ist->st->codecpar->codec_id); | |
1703 | 48 | AVCodecDescriptor const *output_descriptor = NULL; | |
1704 | AVCodec const *output_codec = | ||
1705 | 48 | avcodec_find_encoder(oc->oformat->subtitle_codec); | |
1706 | 48 | int input_props = 0, output_props = 0; | |
1707 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | if (ist->user_set_discard == AVDISCARD_ALL) |
1708 | ✗ | continue; | |
1709 |
2/2✓ Branch 0 taken 41 times.
✓ Branch 1 taken 7 times.
|
48 | if (output_codec) |
1710 | 41 | output_descriptor = avcodec_descriptor_get(output_codec->id); | |
1711 |
1/2✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
|
48 | if (input_descriptor) |
1712 | 48 | input_props = input_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB); | |
1713 |
2/2✓ Branch 0 taken 41 times.
✓ Branch 1 taken 7 times.
|
48 | if (output_descriptor) |
1714 | 41 | output_props = output_descriptor->props & (AV_CODEC_PROP_TEXT_SUB | AV_CODEC_PROP_BITMAP_SUB); | |
1715 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 16 times.
|
48 | if (subtitle_codec_name || |
1716 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
32 | input_props & output_props || |
1717 | // Map dvb teletext which has neither property to any output subtitle encoder | ||
1718 | ✗ | input_descriptor && output_descriptor && | |
1719 | ✗ | (!input_descriptor->props || | |
1720 | ✗ | !output_descriptor->props)) { | |
1721 | 48 | return ost_add(mux, o, AVMEDIA_TYPE_SUBTITLE, ist, NULL, NULL, NULL); | |
1722 | } | ||
1723 | } | ||
1724 | |||
1725 | 19 | return 0; | |
1726 | } | ||
1727 | |||
1728 | 7755 | static int map_auto_data(Muxer *mux, const OptionsContext *o) | |
1729 | { | ||
1730 | 7755 | AVFormatContext *oc = mux->fc; | |
1731 | /* Data only if codec id match */ | ||
1732 | 7755 | enum AVCodecID codec_id = av_guess_codec(oc->oformat, NULL, oc->url, NULL, AVMEDIA_TYPE_DATA); | |
1733 | |||
1734 |
1/2✓ Branch 0 taken 7755 times.
✗ Branch 1 not taken.
|
7755 | if (codec_id == AV_CODEC_ID_NONE) |
1735 | 7755 | return 0; | |
1736 | |||
1737 | ✗ | for (InputStream *ist = ist_iter(NULL); ist; ist = ist_iter(ist)) { | |
1738 | ✗ | if (ist->user_set_discard == AVDISCARD_ALL) | |
1739 | ✗ | continue; | |
1740 | ✗ | if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA && | |
1741 | ✗ | ist->st->codecpar->codec_id == codec_id) { | |
1742 | ✗ | int ret = ost_add(mux, o, AVMEDIA_TYPE_DATA, ist, NULL, NULL, NULL); | |
1743 | ✗ | if (ret < 0) | |
1744 | ✗ | return ret; | |
1745 | } | ||
1746 | } | ||
1747 | |||
1748 | ✗ | return 0; | |
1749 | } | ||
1750 | |||
1751 | 386 | static int map_manual(Muxer *mux, const OptionsContext *o, const StreamMap *map) | |
1752 | { | ||
1753 | InputStream *ist; | ||
1754 | int ret; | ||
1755 | |||
1756 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 386 times.
|
386 | if (map->disabled) |
1757 | ✗ | return 0; | |
1758 | |||
1759 |
2/2✓ Branch 0 taken 61 times.
✓ Branch 1 taken 325 times.
|
386 | if (map->linklabel) { |
1760 | FilterGraph *fg; | ||
1761 | 61 | OutputFilter *ofilter = NULL; | |
1762 | int j, k; | ||
1763 | |||
1764 |
1/2✓ Branch 0 taken 61 times.
✗ Branch 1 not taken.
|
61 | for (j = 0; j < nb_filtergraphs; j++) { |
1765 | 61 | fg = filtergraphs[j]; | |
1766 |
1/2✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
|
204 | for (k = 0; k < fg->nb_outputs; k++) { |
1767 | 204 | const char *linklabel = fg->outputs[k]->linklabel; | |
1768 |
3/4✓ Branch 0 taken 61 times.
✓ Branch 1 taken 143 times.
✓ Branch 2 taken 61 times.
✗ Branch 3 not taken.
|
204 | if (linklabel && !strcmp(linklabel, map->linklabel)) { |
1769 | 61 | ofilter = fg->outputs[k]; | |
1770 | 61 | goto loop_end; | |
1771 | } | ||
1772 | } | ||
1773 | } | ||
1774 | ✗ | loop_end: | |
1775 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
|
61 | if (!ofilter) { |
1776 | ✗ | av_log(mux, AV_LOG_FATAL, "Output with label '%s' does not exist " | |
1777 | ✗ | "in any defined filter graph, or was already used elsewhere.\n", map->linklabel); | |
1778 | ✗ | return AVERROR(EINVAL); | |
1779 | } | ||
1780 | |||
1781 | 61 | av_log(mux, AV_LOG_VERBOSE, "Creating output stream from an explicitly " | |
1782 | 61 | "mapped complex filtergraph %d, output [%s]\n", fg->index, map->linklabel); | |
1783 | |||
1784 | 61 | ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL, NULL); | |
1785 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 61 times.
|
61 | if (ret < 0) |
1786 | ✗ | return ret; | |
1787 | } else { | ||
1788 | 650 | const ViewSpecifier *vs = map->vs.type == VIEW_SPECIFIER_TYPE_NONE ? | |
1789 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 312 times.
|
325 | NULL : &map->vs; |
1790 | |||
1791 | 325 | ist = input_files[map->file_index]->streams[map->stream_index]; | |
1792 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
|
325 | if (ist->user_set_discard == AVDISCARD_ALL) { |
1793 | ✗ | av_log(mux, AV_LOG_FATAL, "Stream #%d:%d is disabled and cannot be mapped.\n", | |
1794 | ✗ | map->file_index, map->stream_index); | |
1795 | ✗ | return AVERROR(EINVAL); | |
1796 | } | ||
1797 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
325 | if(o->subtitle_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) |
1798 | ✗ | return 0; | |
1799 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
325 | if(o-> audio_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) |
1800 | ✗ | return 0; | |
1801 |
3/4✓ Branch 0 taken 1 times.
✓ Branch 1 taken 324 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
|
325 | if(o-> video_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) |
1802 | ✗ | return 0; | |
1803 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
325 | if(o-> data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA) |
1804 | ✗ | return 0; | |
1805 | |||
1806 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
|
325 | if (ist->st->codecpar->codec_type == AVMEDIA_TYPE_UNKNOWN && |
1807 | ✗ | !copy_unknown_streams) { | |
1808 | ✗ | av_log(mux, ignore_unknown_streams ? AV_LOG_WARNING : AV_LOG_FATAL, | |
1809 | "Cannot map stream #%d:%d - unsupported type.\n", | ||
1810 | ✗ | map->file_index, map->stream_index); | |
1811 | ✗ | if (!ignore_unknown_streams) { | |
1812 | ✗ | av_log(mux, AV_LOG_FATAL, | |
1813 | "If you want unsupported types ignored instead " | ||
1814 | "of failing, please use the -ignore_unknown option\n" | ||
1815 | "If you want them copied, please use -copy_unknown\n"); | ||
1816 | ✗ | return AVERROR(EINVAL); | |
1817 | } | ||
1818 | ✗ | return 0; | |
1819 | } | ||
1820 | |||
1821 |
3/4✓ Branch 0 taken 13 times.
✓ Branch 1 taken 312 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
|
325 | if (vs && ist->st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) { |
1822 | ✗ | av_log(mux, AV_LOG_ERROR, | |
1823 | "View specifier given for mapping a %s input stream\n", | ||
1824 | ✗ | av_get_media_type_string(ist->st->codecpar->codec_type)); | |
1825 | ✗ | return AVERROR(EINVAL); | |
1826 | } | ||
1827 | |||
1828 | 325 | ret = ost_add(mux, o, ist->st->codecpar->codec_type, ist, NULL, vs, NULL); | |
1829 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
|
325 | if (ret < 0) |
1830 | ✗ | return ret; | |
1831 | } | ||
1832 | |||
1833 | 386 | return 0; | |
1834 | } | ||
1835 | |||
1836 | 7916 | static int of_add_attachments(Muxer *mux, const OptionsContext *o) | |
1837 | { | ||
1838 | MuxStream *ms; | ||
1839 | OutputStream *ost; | ||
1840 | int err; | ||
1841 | |||
1842 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7916 times.
|
7917 | for (int i = 0; i < o->nb_attachments; i++) { |
1843 | AVIOContext *pb; | ||
1844 | uint8_t *attachment; | ||
1845 | char *attachment_filename; | ||
1846 | const char *p; | ||
1847 | int64_t len; | ||
1848 | |||
1849 |
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) { |
1850 | ✗ | av_log(mux, AV_LOG_FATAL, "Could not open attachment file %s.\n", | |
1851 | ✗ | o->attachments[i]); | |
1852 | ✗ | return err; | |
1853 | } | ||
1854 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if ((len = avio_size(pb)) <= 0) { |
1855 | ✗ | av_log(mux, AV_LOG_FATAL, "Could not get size of the attachment %s.\n", | |
1856 | ✗ | o->attachments[i]); | |
1857 | ✗ | err = len ? len : AVERROR_INVALIDDATA; | |
1858 | ✗ | goto read_fail; | |
1859 | } | ||
1860 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { |
1861 | ✗ | av_log(mux, AV_LOG_FATAL, "Attachment %s too large.\n", | |
1862 | ✗ | o->attachments[i]); | |
1863 | ✗ | err = AVERROR(ERANGE); | |
1864 | ✗ | goto read_fail; | |
1865 | } | ||
1866 | |||
1867 | 1 | attachment = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE); | |
1868 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!attachment) { |
1869 | ✗ | err = AVERROR(ENOMEM); | |
1870 | ✗ | goto read_fail; | |
1871 | } | ||
1872 | |||
1873 | 1 | err = avio_read(pb, attachment, len); | |
1874 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (err < 0) |
1875 | ✗ | av_log(mux, AV_LOG_FATAL, "Error reading attachment file %s: %s\n", | |
1876 | ✗ | o->attachments[i], av_err2str(err)); | |
1877 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | else if (err != len) { |
1878 | ✗ | av_log(mux, AV_LOG_FATAL, "Could not read all %"PRId64" bytes for " | |
1879 | ✗ | "attachment file %s\n", len, o->attachments[i]); | |
1880 | ✗ | err = AVERROR(EIO); | |
1881 | } | ||
1882 | |||
1883 | 1 | read_fail: | |
1884 | 1 | avio_closep(&pb); | |
1885 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (err < 0) |
1886 | ✗ | return err; | |
1887 | |||
1888 | 1 | memset(attachment + len, 0, AV_INPUT_BUFFER_PADDING_SIZE); | |
1889 | |||
1890 | 1 | av_log(mux, AV_LOG_VERBOSE, "Creating attachment stream from file %s\n", | |
1891 | 1 | o->attachments[i]); | |
1892 | |||
1893 | 1 | attachment_filename = av_strdup(o->attachments[i]); | |
1894 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (!attachment_filename) { |
1895 | ✗ | av_free(attachment); | |
1896 | ✗ | return AVERROR(ENOMEM); | |
1897 | } | ||
1898 | |||
1899 | 1 | err = ost_add(mux, o, AVMEDIA_TYPE_ATTACHMENT, NULL, NULL, NULL, &ost); | |
1900 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (err < 0) { |
1901 | ✗ | av_free(attachment_filename); | |
1902 | ✗ | av_freep(&attachment); | |
1903 | ✗ | return err; | |
1904 | } | ||
1905 | |||
1906 | 1 | ms = ms_from_ost(ost); | |
1907 | |||
1908 | 1 | ost->attachment_filename = attachment_filename; | |
1909 | 1 | ms->par_in->extradata = attachment; | |
1910 | 1 | ms->par_in->extradata_size = len; | |
1911 | |||
1912 | 1 | p = strrchr(o->attachments[i], '/'); | |
1913 |
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); |
1914 | } | ||
1915 | |||
1916 | 7916 | return 0; | |
1917 | } | ||
1918 | |||
1919 | 7916 | static int create_streams(Muxer *mux, const OptionsContext *o) | |
1920 | { | ||
1921 | static int (* const map_func[])(Muxer *mux, const OptionsContext *o) = { | ||
1922 | [AVMEDIA_TYPE_VIDEO] = map_auto_video, | ||
1923 | [AVMEDIA_TYPE_AUDIO] = map_auto_audio, | ||
1924 | [AVMEDIA_TYPE_SUBTITLE] = map_auto_subtitle, | ||
1925 | [AVMEDIA_TYPE_DATA] = map_auto_data, | ||
1926 | }; | ||
1927 | |||
1928 | 7916 | AVFormatContext *oc = mux->fc; | |
1929 | |||
1930 | 7916 | int auto_disable = | |
1931 | 7916 | o->video_disable * (1 << AVMEDIA_TYPE_VIDEO) | | |
1932 | 7916 | o->audio_disable * (1 << AVMEDIA_TYPE_AUDIO) | | |
1933 | 7916 | o->subtitle_disable * (1 << AVMEDIA_TYPE_SUBTITLE) | | |
1934 | 7916 | o->data_disable * (1 << AVMEDIA_TYPE_DATA); | |
1935 | |||
1936 | int ret; | ||
1937 | |||
1938 | /* create streams for all unlabeled output pads */ | ||
1939 |
2/2✓ Branch 0 taken 903 times.
✓ Branch 1 taken 7916 times.
|
8819 | for (int i = 0; i < nb_filtergraphs; i++) { |
1940 | 903 | FilterGraph *fg = filtergraphs[i]; | |
1941 |
2/2✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 903 times.
|
1927 | for (int j = 0; j < fg->nb_outputs; j++) { |
1942 | 1024 | OutputFilter *ofilter = fg->outputs[j]; | |
1943 | |||
1944 |
3/4✓ Branch 0 taken 962 times.
✓ Branch 1 taken 62 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 962 times.
|
1024 | if (ofilter->linklabel || ofilter->bound) |
1945 | 62 | continue; | |
1946 | |||
1947 | 962 | auto_disable |= 1 << ofilter->type; | |
1948 | |||
1949 | 962 | av_log(mux, AV_LOG_VERBOSE, "Creating output stream from unlabeled " | |
1950 | "output of complex filtergraph %d.", fg->index); | ||
1951 |
1/2✓ Branch 0 taken 962 times.
✗ Branch 1 not taken.
|
962 | if (!o->nb_stream_maps) |
1952 | 962 | av_log(mux, AV_LOG_VERBOSE, " This overrides automatic %s mapping.", | |
1953 | av_get_media_type_string(ofilter->type)); | ||
1954 | 962 | av_log(mux, AV_LOG_VERBOSE, "\n"); | |
1955 | |||
1956 | 962 | ret = ost_add(mux, o, ofilter->type, NULL, ofilter, NULL, NULL); | |
1957 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 962 times.
|
962 | if (ret < 0) |
1958 | ✗ | return ret; | |
1959 | } | ||
1960 | } | ||
1961 | |||
1962 |
2/2✓ Branch 0 taken 7755 times.
✓ Branch 1 taken 161 times.
|
7916 | if (!o->nb_stream_maps) { |
1963 | 7755 | av_log(mux, AV_LOG_VERBOSE, "No explicit maps, mapping streams automatically...\n"); | |
1964 | |||
1965 | /* pick the "best" stream of each type */ | ||
1966 |
2/2✓ Branch 0 taken 31020 times.
✓ Branch 1 taken 7755 times.
|
38775 | for (int i = 0; i < FF_ARRAY_ELEMS(map_func); i++) { |
1967 |
3/4✓ Branch 0 taken 31020 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1195 times.
✓ Branch 3 taken 29825 times.
|
31020 | if (!map_func[i] || auto_disable & (1 << i)) |
1968 | 1195 | continue; | |
1969 | 29825 | ret = map_func[i](mux, o); | |
1970 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 29825 times.
|
29825 | if (ret < 0) |
1971 | ✗ | return ret; | |
1972 | } | ||
1973 | } else { | ||
1974 | 161 | av_log(mux, AV_LOG_VERBOSE, "Adding streams from explicit maps...\n"); | |
1975 | |||
1976 |
2/2✓ Branch 0 taken 386 times.
✓ Branch 1 taken 161 times.
|
547 | for (int i = 0; i < o->nb_stream_maps; i++) { |
1977 | 386 | ret = map_manual(mux, o, &o->stream_maps[i]); | |
1978 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 386 times.
|
386 | if (ret < 0) |
1979 | ✗ | return ret; | |
1980 | } | ||
1981 | } | ||
1982 | |||
1983 | 7916 | ret = of_add_attachments(mux, o); | |
1984 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7916 times.
|
7916 | if (ret < 0) |
1985 | ✗ | return ret; | |
1986 | |||
1987 | // setup fix_sub_duration_heartbeat mappings | ||
1988 |
2/2✓ Branch 0 taken 8357 times.
✓ Branch 1 taken 7916 times.
|
16273 | for (unsigned i = 0; i < oc->nb_streams; i++) { |
1989 | 8357 | MuxStream *src = ms_from_ost(mux->of.streams[i]); | |
1990 | |||
1991 |
2/2✓ Branch 0 taken 8356 times.
✓ Branch 1 taken 1 times.
|
8357 | if (!src->ost.fix_sub_duration_heartbeat) |
1992 | 8356 | continue; | |
1993 | |||
1994 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | for (unsigned j = 0; j < oc->nb_streams; j++) { |
1995 | 2 | MuxStream *dst = ms_from_ost(mux->of.streams[j]); | |
1996 | |||
1997 |
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 || |
1998 |
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) |
1999 | 1 | continue; | |
2000 | |||
2001 | 1 | ret = sch_mux_sub_heartbeat_add(mux->sch, mux->sch_idx, src->sch_idx, | |
2002 | 1 | dst->sch_idx_src); | |
2003 | |||
2004 | } | ||
2005 | } | ||
2006 | |||
2007 | // handle -apad | ||
2008 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7912 times.
|
7916 | if (o->shortest) { |
2009 | 4 | int have_video = 0; | |
2010 | |||
2011 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | for (unsigned i = 0; i < mux->of.nb_streams; i++) |
2012 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
4 | if (mux->of.streams[i]->type == AVMEDIA_TYPE_VIDEO) { |
2013 | 4 | have_video = 1; | |
2014 | 4 | break; | |
2015 | } | ||
2016 | |||
2017 |
3/4✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 4 times.
|
12 | for (unsigned i = 0; have_video && i < mux->of.nb_streams; i++) { |
2018 | 8 | MuxStream *ms = ms_from_ost(mux->of.streams[i]); | |
2019 | 8 | OutputFilter *ofilter = ms->ost.filter; | |
2020 | |||
2021 |
3/6✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
8 | if (ms->ost.type != AVMEDIA_TYPE_AUDIO || !ms->apad || !ofilter) |
2022 | 8 | continue; | |
2023 | |||
2024 | ✗ | ofilter->apad = av_strdup(ms->apad); | |
2025 | ✗ | if (!ofilter->apad) | |
2026 | ✗ | return AVERROR(ENOMEM); | |
2027 | } | ||
2028 | } | ||
2029 |
2/2✓ Branch 0 taken 8357 times.
✓ Branch 1 taken 7916 times.
|
16273 | for (unsigned i = 0; i < mux->of.nb_streams; i++) { |
2030 | 8357 | MuxStream *ms = ms_from_ost(mux->of.streams[i]); | |
2031 | 8357 | ms->apad = NULL; | |
2032 | } | ||
2033 | |||
2034 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 7916 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
7916 | if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) { |
2035 | ✗ | av_dump_format(oc, nb_output_files - 1, oc->url, 1); | |
2036 | ✗ | av_log(mux, AV_LOG_ERROR, "Output file does not contain any stream\n"); | |
2037 | ✗ | return AVERROR(EINVAL); | |
2038 | } | ||
2039 | |||
2040 | 7916 | return 0; | |
2041 | } | ||
2042 | |||
2043 | 7916 | static int setup_sync_queues(Muxer *mux, AVFormatContext *oc, | |
2044 | int64_t buf_size_us, int shortest) | ||
2045 | { | ||
2046 | 7916 | OutputFile *of = &mux->of; | |
2047 | 7916 | int nb_av_enc = 0, nb_audio_fs = 0, nb_interleaved = 0; | |
2048 | 7916 | int limit_frames = 0, limit_frames_av_enc = 0; | |
2049 | |||
2050 | #define IS_AV_ENC(ost, type) \ | ||
2051 | (ost->enc && (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)) | ||
2052 | #define IS_INTERLEAVED(type) (type != AVMEDIA_TYPE_ATTACHMENT) | ||
2053 | |||
2054 |
2/2✓ Branch 0 taken 8357 times.
✓ Branch 1 taken 7916 times.
|
16273 | for (int i = 0; i < oc->nb_streams; i++) { |
2055 | 8357 | OutputStream *ost = of->streams[i]; | |
2056 | 8357 | MuxStream *ms = ms_from_ost(ost); | |
2057 | 8357 | enum AVMediaType type = ost->type; | |
2058 | |||
2059 | 8357 | ms |