blob: 7bc41c96b2f04af11f9163b0a777bb3744ed45a4 [file] [log] [blame]
Anton Khirnovf5e66822012-08-01 16:23:121/*
2 * avconv option parsing
3 *
4 * This file is part of Libav.
5 *
6 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <stdint.h>
22
23#include "avconv.h"
24#include "cmdutils.h"
25
26#include "libavformat/avformat.h"
27
28#include "libavcodec/avcodec.h"
29
30#include "libavfilter/avfilter.h"
Anton Khirnovf5e66822012-08-01 16:23:1231
Anton Khirnovf5e66822012-08-01 16:23:1232#include "libavutil/avassert.h"
33#include "libavutil/avstring.h"
34#include "libavutil/avutil.h"
Justin Rugglesa903f8f2012-11-10 15:00:0035#include "libavutil/channel_layout.h"
Anton Khirnovf5e66822012-08-01 16:23:1236#include "libavutil/intreadwrite.h"
37#include "libavutil/fifo.h"
38#include "libavutil/mathematics.h"
39#include "libavutil/opt.h"
40#include "libavutil/parseutils.h"
41#include "libavutil/pixdesc.h"
42#include "libavutil/pixfmt.h"
43
44#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
45{\
46 int i, ret;\
47 for (i = 0; i < o->nb_ ## name; i++) {\
48 char *spec = o->name[i].specifier;\
49 if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
50 outvar = o->name[i].u.type;\
51 else if (ret < 0)\
Martin Storsjöb85dbe62013-07-31 10:44:1752 exit_program(1);\
Anton Khirnovf5e66822012-08-01 16:23:1253 }\
54}
55
Anton Khirnov07fd0a22013-11-02 21:06:3656const HWAccel hwaccels[] = {
Anton Khirnov7671dd72013-11-03 18:21:0057#if HAVE_VDPAU_X11
58 { "vdpau", vdpau_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU },
59#endif
Anton Khirnov07fd0a22013-11-02 21:06:3660 { 0 },
61};
62
Anton Khirnovf5e66822012-08-01 16:23:1263char *vstats_filename;
64
65float audio_drift_threshold = 0.1;
66float dts_delta_threshold = 10;
67
68int audio_volume = 256;
69int audio_sync_method = 0;
70int video_sync_method = VSYNC_AUTO;
Anton Khirnovf5e66822012-08-01 16:23:1271int do_benchmark = 0;
72int do_hex_dump = 0;
73int do_pkt_dump = 0;
74int copy_ts = 0;
75int copy_tb = 1;
Anton Khirnovf5e66822012-08-01 16:23:1276int exit_on_error = 0;
77int print_stats = 1;
78int qp_hist = 0;
Anton Khirnovf5e66822012-08-01 16:23:1279
80static int file_overwrite = 0;
Vittorio Giovara7748dd42013-07-31 12:48:4981static int file_skip = 0;
Anton Khirnovf5e66822012-08-01 16:23:1282static int video_discard = 0;
83static int intra_dc_precision = 8;
Anton Khirnovf5e66822012-08-01 16:23:1284static int using_stdin = 0;
85static int input_sync;
86
Anton Khirnov77bd1bc2012-06-08 19:35:1687static void uninit_options(OptionsContext *o)
Anton Khirnovf5e66822012-08-01 16:23:1288{
89 const OptionDef *po = options;
90 int i;
91
92 /* all OPT_SPEC and OPT_STRING can be freed in generic way */
93 while (po->name) {
94 void *dst = (uint8_t*)o + po->u.off;
95
96 if (po->flags & OPT_SPEC) {
97 SpecifierOpt **so = dst;
98 int i, *count = (int*)(so + 1);
99 for (i = 0; i < *count; i++) {
100 av_freep(&(*so)[i].specifier);
101 if (po->flags & OPT_STRING)
102 av_freep(&(*so)[i].u.str);
103 }
104 av_freep(so);
105 *count = 0;
106 } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
107 av_freep(dst);
108 po++;
109 }
110
111 for (i = 0; i < o->nb_stream_maps; i++)
112 av_freep(&o->stream_maps[i].linklabel);
113 av_freep(&o->stream_maps);
114 av_freep(&o->meta_data_maps);
115 av_freep(&o->streamid_map);
Anton Khirnov77bd1bc2012-06-08 19:35:16116}
Anton Khirnovf5e66822012-08-01 16:23:12117
Anton Khirnov77bd1bc2012-06-08 19:35:16118static void init_options(OptionsContext *o)
119{
Anton Khirnovf5e66822012-08-01 16:23:12120 memset(o, 0, sizeof(*o));
121
122 o->mux_max_delay = 0.7;
Anton Khirnov56ee3f92013-06-15 07:35:10123 o->start_time = AV_NOPTS_VALUE;
Anton Khirnovf5e66822012-08-01 16:23:12124 o->recording_time = INT64_MAX;
125 o->limit_filesize = UINT64_MAX;
126 o->chapters_input_file = INT_MAX;
Anton Khirnov811bd072013-06-15 07:59:40127 o->accurate_seek = 1;
Anton Khirnovf5e66822012-08-01 16:23:12128}
129
Anton Khirnove7553f42013-02-21 09:58:46130/* return a copy of the input with the stream specifiers removed from the keys */
131static AVDictionary *strip_specifiers(AVDictionary *dict)
132{
133 AVDictionaryEntry *e = NULL;
134 AVDictionary *ret = NULL;
135
136 while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
137 char *p = strchr(e->key, ':');
138
139 if (p)
140 *p = 0;
141 av_dict_set(&ret, e->key, e->value, 0);
142 if (p)
143 *p = ':';
144 }
145 return ret;
146}
147
Anton Khirnovf5e66822012-08-01 16:23:12148static double parse_frame_aspect_ratio(const char *arg)
149{
150 int x = 0, y = 0;
151 double ar = 0;
152 const char *p;
153 char *end;
154
155 p = strchr(arg, ':');
156 if (p) {
157 x = strtol(arg, &end, 10);
158 if (end == p)
159 y = strtol(end + 1, &end, 10);
160 if (x > 0 && y > 0)
161 ar = (double)x / (double)y;
162 } else
163 ar = strtod(arg, NULL);
164
165 if (!ar) {
166 av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17167 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12168 }
169 return ar;
170}
171
Anton Khirnovd3810c42012-08-11 14:30:26172static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12173{
Anton Khirnovd3810c42012-08-11 14:30:26174 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12175 return parse_option(o, "codec:a", arg, options);
176}
177
Anton Khirnovd3810c42012-08-11 14:30:26178static int opt_video_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12179{
Anton Khirnovd3810c42012-08-11 14:30:26180 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12181 return parse_option(o, "codec:v", arg, options);
182}
183
Anton Khirnovd3810c42012-08-11 14:30:26184static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12185{
Anton Khirnovd3810c42012-08-11 14:30:26186 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12187 return parse_option(o, "codec:s", arg, options);
188}
189
Anton Khirnovd3810c42012-08-11 14:30:26190static int opt_data_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12191{
Anton Khirnovd3810c42012-08-11 14:30:26192 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12193 return parse_option(o, "codec:d", arg, options);
194}
195
Anton Khirnovd3810c42012-08-11 14:30:26196static int opt_map(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12197{
Anton Khirnovd3810c42012-08-11 14:30:26198 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12199 StreamMap *m = NULL;
200 int i, negative = 0, file_idx;
201 int sync_file_idx = -1, sync_stream_idx;
202 char *p, *sync;
203 char *map;
204
205 if (*arg == '-') {
206 negative = 1;
207 arg++;
208 }
209 map = av_strdup(arg);
210
211 /* parse sync stream first, just pick first matching stream */
212 if (sync = strchr(map, ',')) {
213 *sync = 0;
214 sync_file_idx = strtol(sync + 1, &sync, 0);
215 if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
216 av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
Martin Storsjöb85dbe62013-07-31 10:44:17217 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12218 }
219 if (*sync)
220 sync++;
221 for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
222 if (check_stream_specifier(input_files[sync_file_idx]->ctx,
223 input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
224 sync_stream_idx = i;
225 break;
226 }
227 if (i == input_files[sync_file_idx]->nb_streams) {
228 av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
229 "match any streams.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17230 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12231 }
232 }
233
234
235 if (map[0] == '[') {
236 /* this mapping refers to lavfi output */
237 const char *c = map + 1;
Anton Khirnov10bca662012-06-07 19:52:07238 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
Anton Khirnovf5e66822012-08-01 16:23:12239 m = &o->stream_maps[o->nb_stream_maps - 1];
240 m->linklabel = av_get_token(&c, "]");
241 if (!m->linklabel) {
242 av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
Martin Storsjöb85dbe62013-07-31 10:44:17243 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12244 }
245 } else {
246 file_idx = strtol(map, &p, 0);
247 if (file_idx >= nb_input_files || file_idx < 0) {
248 av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
Martin Storsjöb85dbe62013-07-31 10:44:17249 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12250 }
251 if (negative)
252 /* disable some already defined maps */
253 for (i = 0; i < o->nb_stream_maps; i++) {
254 m = &o->stream_maps[i];
255 if (file_idx == m->file_index &&
256 check_stream_specifier(input_files[m->file_index]->ctx,
257 input_files[m->file_index]->ctx->streams[m->stream_index],
258 *p == ':' ? p + 1 : p) > 0)
259 m->disabled = 1;
260 }
261 else
262 for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
263 if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
264 *p == ':' ? p + 1 : p) <= 0)
265 continue;
Anton Khirnov10bca662012-06-07 19:52:07266 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
Anton Khirnovf5e66822012-08-01 16:23:12267 m = &o->stream_maps[o->nb_stream_maps - 1];
268
269 m->file_index = file_idx;
270 m->stream_index = i;
271
272 if (sync_file_idx >= 0) {
273 m->sync_file_index = sync_file_idx;
274 m->sync_stream_index = sync_stream_idx;
275 } else {
276 m->sync_file_index = file_idx;
277 m->sync_stream_index = i;
278 }
279 }
280 }
281
282 if (!m) {
283 av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17284 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12285 }
286
287 av_freep(&map);
288 return 0;
289}
290
Anton Khirnovd3810c42012-08-11 14:30:26291static int opt_attach(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12292{
Anton Khirnovd3810c42012-08-11 14:30:26293 OptionsContext *o = optctx;
Anton Khirnov10bca662012-06-07 19:52:07294 GROW_ARRAY(o->attachments, o->nb_attachments);
Anton Khirnovf5e66822012-08-01 16:23:12295 o->attachments[o->nb_attachments - 1] = arg;
296 return 0;
297}
298
299/**
Diego Biurrunc1ef30a2012-08-24 11:31:50300 * Parse a metadata specifier passed as 'arg' parameter.
Diego Biurrun02e42752012-10-24 17:20:13301 * @param arg metadata string to parse
Anton Khirnovf5e66822012-08-01 16:23:12302 * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
303 * @param index for type c/p, chapter/program index is written here
304 * @param stream_spec for type s, the stream specifier is written here
305 */
306static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
307{
308 if (*arg) {
309 *type = *arg;
310 switch (*arg) {
311 case 'g':
312 break;
313 case 's':
314 if (*(++arg) && *arg != ':') {
315 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17316 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12317 }
318 *stream_spec = *arg == ':' ? arg + 1 : "";
319 break;
320 case 'c':
321 case 'p':
322 if (*(++arg) == ':')
323 *index = strtol(++arg, NULL, 0);
324 break;
325 default:
326 av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
Martin Storsjöb85dbe62013-07-31 10:44:17327 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12328 }
329 } else
330 *type = 'g';
331}
332
333static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
334{
335 AVDictionary **meta_in = NULL;
336 AVDictionary **meta_out;
337 int i, ret = 0;
338 char type_in, type_out;
339 const char *istream_spec = NULL, *ostream_spec = NULL;
340 int idx_in = 0, idx_out = 0;
341
342 parse_meta_type(inspec, &type_in, &idx_in, &istream_spec);
343 parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
344
345 if (type_in == 'g' || type_out == 'g')
346 o->metadata_global_manual = 1;
347 if (type_in == 's' || type_out == 's')
348 o->metadata_streams_manual = 1;
349 if (type_in == 'c' || type_out == 'c')
350 o->metadata_chapters_manual = 1;
351
Anton Khirnova119c642012-10-16 07:53:39352 /* ic is NULL when just disabling automatic mappings */
353 if (!ic)
354 return 0;
355
Anton Khirnovf5e66822012-08-01 16:23:12356#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
357 if ((index) < 0 || (index) >= (nb_elems)) {\
358 av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
359 (desc), (index));\
Martin Storsjöb85dbe62013-07-31 10:44:17360 exit_program(1);\
Anton Khirnovf5e66822012-08-01 16:23:12361 }
362
363#define SET_DICT(type, meta, context, index)\
364 switch (type) {\
365 case 'g':\
366 meta = &context->metadata;\
367 break;\
368 case 'c':\
369 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
370 meta = &context->chapters[index]->metadata;\
371 break;\
372 case 'p':\
373 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
374 meta = &context->programs[index]->metadata;\
375 break;\
Anton Khirnov4632abc2012-11-24 06:55:42376 case 's':\
377 break; /* handled separately below */ \
Anton Khirnovf5e66822012-08-01 16:23:12378 default: av_assert0(0);\
379 }\
380
381 SET_DICT(type_in, meta_in, ic, idx_in);
382 SET_DICT(type_out, meta_out, oc, idx_out);
383
384 /* for input streams choose first matching stream */
385 if (type_in == 's') {
386 for (i = 0; i < ic->nb_streams; i++) {
387 if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
388 meta_in = &ic->streams[i]->metadata;
389 break;
390 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:17391 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12392 }
393 if (!meta_in) {
394 av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
Martin Storsjöb85dbe62013-07-31 10:44:17395 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12396 }
397 }
398
399 if (type_out == 's') {
400 for (i = 0; i < oc->nb_streams; i++) {
401 if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
402 meta_out = &oc->streams[i]->metadata;
403 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
404 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:17405 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12406 }
407 } else
408 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
409
410 return 0;
411}
412
413static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
414{
Anton Khirnovdb4766a2012-08-11 13:40:12415 const AVCodecDescriptor *desc;
Anton Khirnovf5e66822012-08-01 16:23:12416 const char *codec_string = encoder ? "encoder" : "decoder";
417 AVCodec *codec;
418
419 codec = encoder ?
420 avcodec_find_encoder_by_name(name) :
421 avcodec_find_decoder_by_name(name);
Anton Khirnovdb4766a2012-08-11 13:40:12422
423 if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
424 codec = encoder ? avcodec_find_encoder(desc->id) :
425 avcodec_find_decoder(desc->id);
426 if (codec)
427 av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
428 codec_string, codec->name, desc->name);
429 }
430
Anton Khirnovf5e66822012-08-01 16:23:12431 if (!codec) {
432 av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
Martin Storsjöb85dbe62013-07-31 10:44:17433 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12434 }
435 if (codec->type != type) {
436 av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
Martin Storsjöb85dbe62013-07-31 10:44:17437 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12438 }
439 return codec;
440}
441
442static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
443{
444 char *codec_name = NULL;
445
446 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
447 if (codec_name) {
448 AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
449 st->codec->codec_id = codec->id;
450 return codec;
451 } else
452 return avcodec_find_decoder(st->codec->codec_id);
453}
454
Diego Biurrunc1ef30a2012-08-24 11:31:50455/* Add all the streams from the given input file to the global
456 * list of input streams. */
Anton Khirnovf5e66822012-08-01 16:23:12457static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
458{
459 int i;
460
461 for (i = 0; i < ic->nb_streams; i++) {
462 AVStream *st = ic->streams[i];
463 AVCodecContext *dec = st->codec;
464 InputStream *ist = av_mallocz(sizeof(*ist));
Anton Khirnov07fd0a22013-11-02 21:06:36465 char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
Anton Khirnov746dca42014-02-23 07:05:52466 char *codec_tag = NULL;
467 char *next;
Anton Khirnovf5e66822012-08-01 16:23:12468
469 if (!ist)
Martin Storsjöb85dbe62013-07-31 10:44:17470 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12471
Anton Khirnov10bca662012-06-07 19:52:07472 GROW_ARRAY(input_streams, nb_input_streams);
Anton Khirnovf5e66822012-08-01 16:23:12473 input_streams[nb_input_streams - 1] = ist;
474
475 ist->st = st;
476 ist->file_index = nb_input_files;
477 ist->discard = 1;
478 st->discard = AVDISCARD_ALL;
Anton Khirnovf5e66822012-08-01 16:23:12479
480 ist->ts_scale = 1.0;
481 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
482
Anton Khirnov746dca42014-02-23 07:05:52483 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
484 if (codec_tag) {
485 uint32_t tag = strtol(codec_tag, &next, 0);
486 if (*next)
487 tag = AV_RL32(codec_tag);
488 st->codec->codec_tag = tag;
489 }
490
Anton Khirnovf5e66822012-08-01 16:23:12491 ist->dec = choose_decoder(o, ic, st);
Anton Khirnove82cb792012-12-15 10:45:59492 ist->opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, ist->dec);
Anton Khirnovf5e66822012-08-01 16:23:12493
494 switch (dec->codec_type) {
495 case AVMEDIA_TYPE_VIDEO:
496 ist->resample_height = dec->height;
497 ist->resample_width = dec->width;
498 ist->resample_pix_fmt = dec->pix_fmt;
499
500 MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
501 if (framerate && av_parse_video_rate(&ist->framerate,
502 framerate) < 0) {
503 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
504 framerate);
Martin Storsjöb85dbe62013-07-31 10:44:17505 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12506 }
507
Anton Khirnov07fd0a22013-11-02 21:06:36508 MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
509 if (hwaccel) {
510 if (!strcmp(hwaccel, "none"))
511 ist->hwaccel_id = HWACCEL_NONE;
512 else if (!strcmp(hwaccel, "auto"))
513 ist->hwaccel_id = HWACCEL_AUTO;
514 else {
515 int i;
516 for (i = 0; hwaccels[i].name; i++) {
517 if (!strcmp(hwaccels[i].name, hwaccel)) {
518 ist->hwaccel_id = hwaccels[i].id;
519 break;
520 }
521 }
522
523 if (!ist->hwaccel_id) {
524 av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
525 hwaccel);
526 av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
527 for (i = 0; hwaccels[i].name; i++)
528 av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
529 av_log(NULL, AV_LOG_FATAL, "\n");
530 exit_program(1);
531 }
532 }
533 }
534
535 MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
536 if (hwaccel_device) {
537 ist->hwaccel_device = av_strdup(hwaccel_device);
538 if (!ist->hwaccel_device)
539 exit_program(1);
540 }
Anton Khirnovc255f0b2013-11-23 13:07:48541 ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
Anton Khirnov07fd0a22013-11-02 21:06:36542
Anton Khirnovf5e66822012-08-01 16:23:12543 break;
544 case AVMEDIA_TYPE_AUDIO:
545 guess_input_channel_layout(ist);
546
547 ist->resample_sample_fmt = dec->sample_fmt;
548 ist->resample_sample_rate = dec->sample_rate;
549 ist->resample_channels = dec->channels;
550 ist->resample_channel_layout = dec->channel_layout;
551
552 break;
553 case AVMEDIA_TYPE_DATA:
554 case AVMEDIA_TYPE_SUBTITLE:
555 case AVMEDIA_TYPE_ATTACHMENT:
556 case AVMEDIA_TYPE_UNKNOWN:
557 break;
558 default:
559 abort();
560 }
561 }
562}
563
564static void assert_file_overwrite(const char *filename)
565{
Vittorio Giovara7748dd42013-07-31 12:48:49566 if (file_overwrite && file_skip) {
567 fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
568 exit_program(1);
569 }
570
Anton Khirnovf5e66822012-08-01 16:23:12571 if (!file_overwrite &&
572 (strchr(filename, ':') == NULL || filename[1] == ':' ||
573 av_strstart(filename, "file:", NULL))) {
574 if (avio_check(filename, 0) == 0) {
Vittorio Giovara7748dd42013-07-31 12:48:49575 if (!using_stdin && !file_skip) {
Anton Khirnovf5e66822012-08-01 16:23:12576 fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
577 fflush(stderr);
578 if (!read_yesno()) {
579 fprintf(stderr, "Not overwriting - exiting\n");
Martin Storsjöb85dbe62013-07-31 10:44:17580 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12581 }
582 }
583 else {
584 fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
Martin Storsjöb85dbe62013-07-31 10:44:17585 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12586 }
587 }
588 }
589}
590
591static void dump_attachment(AVStream *st, const char *filename)
592{
593 int ret;
594 AVIOContext *out = NULL;
595 AVDictionaryEntry *e;
596
597 if (!st->codec->extradata_size) {
598 av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
599 nb_input_files - 1, st->index);
600 return;
601 }
602 if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
603 filename = e->value;
604 if (!*filename) {
605 av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
606 "in stream #%d:%d.\n", nb_input_files - 1, st->index);
Martin Storsjöb85dbe62013-07-31 10:44:17607 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12608 }
609
610 assert_file_overwrite(filename);
611
612 if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
613 av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
614 filename);
Martin Storsjöb85dbe62013-07-31 10:44:17615 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12616 }
617
618 avio_write(out, st->codec->extradata, st->codec->extradata_size);
619 avio_flush(out);
620 avio_close(out);
621}
622
Anton Khirnov77bd1bc2012-06-08 19:35:16623static int open_input_file(OptionsContext *o, const char *filename)
Anton Khirnovf5e66822012-08-01 16:23:12624{
Anton Khirnov41d20082013-02-21 08:53:28625 InputFile *f;
Anton Khirnovf5e66822012-08-01 16:23:12626 AVFormatContext *ic;
627 AVInputFormat *file_iformat = NULL;
628 int err, i, ret;
629 int64_t timestamp;
630 uint8_t buf[128];
631 AVDictionary **opts;
Anton Khirnove7553f42013-02-21 09:58:46632 AVDictionary *unused_opts = NULL;
633 AVDictionaryEntry *e = NULL;
Anton Khirnovf5e66822012-08-01 16:23:12634 int orig_nb_streams; // number of streams before avformat_find_stream_info
635
636 if (o->format) {
637 if (!(file_iformat = av_find_input_format(o->format))) {
638 av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
Martin Storsjöb85dbe62013-07-31 10:44:17639 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12640 }
641 }
642
643 if (!strcmp(filename, "-"))
644 filename = "pipe:";
645
646 using_stdin |= !strncmp(filename, "pipe:", 5) ||
647 !strcmp(filename, "/dev/stdin");
648
649 /* get default parameters from command line */
650 ic = avformat_alloc_context();
651 if (!ic) {
652 print_error(filename, AVERROR(ENOMEM));
Martin Storsjöb85dbe62013-07-31 10:44:17653 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12654 }
655 if (o->nb_audio_sample_rate) {
656 snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
Anton Khirnov77bd1bc2012-06-08 19:35:16657 av_dict_set(&o->g->format_opts, "sample_rate", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:12658 }
659 if (o->nb_audio_channels) {
660 /* because we set audio_channels based on both the "ac" and
661 * "channel_layout" options, we need to check that the specified
662 * demuxer actually has the "channels" option before setting it */
663 if (file_iformat && file_iformat->priv_class &&
664 av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
665 AV_OPT_SEARCH_FAKE_OBJ)) {
666 snprintf(buf, sizeof(buf), "%d",
667 o->audio_channels[o->nb_audio_channels - 1].u.i);
Anton Khirnov77bd1bc2012-06-08 19:35:16668 av_dict_set(&o->g->format_opts, "channels", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:12669 }
670 }
671 if (o->nb_frame_rates) {
672 /* set the format-level framerate option;
673 * this is important for video grabbers, e.g. x11 */
674 if (file_iformat && file_iformat->priv_class &&
675 av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
676 AV_OPT_SEARCH_FAKE_OBJ)) {
Anton Khirnov77bd1bc2012-06-08 19:35:16677 av_dict_set(&o->g->format_opts, "framerate",
Anton Khirnovf5e66822012-08-01 16:23:12678 o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
679 }
680 }
681 if (o->nb_frame_sizes) {
Anton Khirnov77bd1bc2012-06-08 19:35:16682 av_dict_set(&o->g->format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
Anton Khirnovf5e66822012-08-01 16:23:12683 }
684 if (o->nb_frame_pix_fmts)
Anton Khirnov77bd1bc2012-06-08 19:35:16685 av_dict_set(&o->g->format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
Anton Khirnovf5e66822012-08-01 16:23:12686
687 ic->flags |= AVFMT_FLAG_NONBLOCK;
688 ic->interrupt_callback = int_cb;
689
690 /* open the input file with generic libav function */
Anton Khirnov77bd1bc2012-06-08 19:35:16691 err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
Anton Khirnovf5e66822012-08-01 16:23:12692 if (err < 0) {
693 print_error(filename, err);
Martin Storsjöb85dbe62013-07-31 10:44:17694 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12695 }
Anton Khirnov77bd1bc2012-06-08 19:35:16696 assert_avoptions(o->g->format_opts);
Anton Khirnovf5e66822012-08-01 16:23:12697
698 /* apply forced codec ids */
699 for (i = 0; i < ic->nb_streams; i++)
700 choose_decoder(o, ic, ic->streams[i]);
701
702 /* Set AVCodecContext options for avformat_find_stream_info */
Anton Khirnov77bd1bc2012-06-08 19:35:16703 opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
Anton Khirnovf5e66822012-08-01 16:23:12704 orig_nb_streams = ic->nb_streams;
705
706 /* If not enough info to get the stream parameters, we decode the
707 first frames to get it. (used in mpeg case for example) */
708 ret = avformat_find_stream_info(ic, opts);
709 if (ret < 0) {
710 av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
711 avformat_close_input(&ic);
Martin Storsjöb85dbe62013-07-31 10:44:17712 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12713 }
714
Anton Khirnov56ee3f92013-06-15 07:35:10715 timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
Anton Khirnovf5e66822012-08-01 16:23:12716 /* add the stream start time */
717 if (ic->start_time != AV_NOPTS_VALUE)
718 timestamp += ic->start_time;
719
720 /* if seeking requested, we execute it */
Anton Khirnov56ee3f92013-06-15 07:35:10721 if (o->start_time != AV_NOPTS_VALUE) {
Anton Khirnovf5e66822012-08-01 16:23:12722 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
723 if (ret < 0) {
724 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
725 filename, (double)timestamp / AV_TIME_BASE);
726 }
727 }
728
729 /* update the current parameters so that they match the one of the input stream */
730 add_input_streams(o, ic);
731
732 /* dump the file content */
733 av_dump_format(ic, nb_input_files, filename, 0);
734
Anton Khirnov10bca662012-06-07 19:52:07735 GROW_ARRAY(input_files, nb_input_files);
Anton Khirnov41d20082013-02-21 08:53:28736 f = av_mallocz(sizeof(*f));
737 if (!f)
Martin Storsjöb85dbe62013-07-31 10:44:17738 exit_program(1);
Anton Khirnov41d20082013-02-21 08:53:28739 input_files[nb_input_files - 1] = f;
Anton Khirnovf5e66822012-08-01 16:23:12740
Anton Khirnov41d20082013-02-21 08:53:28741 f->ctx = ic;
742 f->ist_index = nb_input_streams - ic->nb_streams;
Anton Khirnov811bd072013-06-15 07:59:40743 f->start_time = o->start_time;
Anton Khirnov488a0fa2013-06-18 09:12:09744 f->recording_time = o->recording_time;
Anton Khirnov41d20082013-02-21 08:53:28745 f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
746 f->nb_streams = ic->nb_streams;
747 f->rate_emu = o->rate_emu;
Anton Khirnov811bd072013-06-15 07:59:40748 f->accurate_seek = o->accurate_seek;
Anton Khirnovf5e66822012-08-01 16:23:12749
Anton Khirnove7553f42013-02-21 09:58:46750 /* check if all codec options have been used */
751 unused_opts = strip_specifiers(o->g->codec_opts);
752 for (i = f->ist_index; i < nb_input_streams; i++) {
753 e = NULL;
754 while ((e = av_dict_get(input_streams[i]->opts, "", e,
755 AV_DICT_IGNORE_SUFFIX)))
756 av_dict_set(&unused_opts, e->key, NULL, 0);
757 }
758
759 e = NULL;
760 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
761 const AVClass *class = avcodec_get_class();
762 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
763 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
764 if (!option)
765 continue;
766 if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
767 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
768 "input file #%d (%s) is not a decoding option.\n", e->key,
769 option->help ? option->help : "", nb_input_files - 1,
770 filename);
Martin Storsjöb85dbe62013-07-31 10:44:17771 exit_program(1);
Anton Khirnove7553f42013-02-21 09:58:46772 }
773
774 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
775 "input file #%d (%s) has not been used for any stream. The most "
776 "likely reason is either wrong type (e.g. a video option with "
777 "no video streams) or that it is a private option of some decoder "
778 "which was not actually used for any stream.\n", e->key,
779 option->help ? option->help : "", nb_input_files - 1, filename);
780 }
781 av_dict_free(&unused_opts);
782
Anton Khirnovf5e66822012-08-01 16:23:12783 for (i = 0; i < o->nb_dump_attachment; i++) {
784 int j;
785
786 for (j = 0; j < ic->nb_streams; j++) {
787 AVStream *st = ic->streams[j];
788
789 if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
790 dump_attachment(st, o->dump_attachment[i].u.str);
791 }
792 }
793
794 for (i = 0; i < orig_nb_streams; i++)
795 av_dict_free(&opts[i]);
796 av_freep(&opts);
797
Anton Khirnovf5e66822012-08-01 16:23:12798 return 0;
799}
800
801static uint8_t *get_line(AVIOContext *s)
802{
803 AVIOContext *line;
804 uint8_t *buf;
805 char c;
806
807 if (avio_open_dyn_buf(&line) < 0) {
808 av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17809 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12810 }
811
812 while ((c = avio_r8(s)) && c != '\n')
813 avio_w8(line, c);
814 avio_w8(line, 0);
815 avio_close_dyn_buf(line, &buf);
816
817 return buf;
818}
819
820static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
821{
822 int i, ret = 1;
823 char filename[1000];
824 const char *base[3] = { getenv("AVCONV_DATADIR"),
825 getenv("HOME"),
826 AVCONV_DATADIR,
827 };
828
829 for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
830 if (!base[i])
831 continue;
832 if (codec_name) {
833 snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
834 i != 1 ? "" : "/.avconv", codec_name, preset_name);
835 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
836 }
837 if (ret) {
838 snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
839 i != 1 ? "" : "/.avconv", preset_name);
840 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
841 }
842 }
843 return ret;
844}
845
846static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
847{
848 char *codec_name = NULL;
849
850 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
851 if (!codec_name) {
852 ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
853 NULL, ost->st->codec->codec_type);
854 ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
855 } else if (!strcmp(codec_name, "copy"))
856 ost->stream_copy = 1;
857 else {
858 ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
859 ost->st->codec->codec_id = ost->enc->id;
860 }
861}
862
863static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
864{
865 OutputStream *ost;
866 AVStream *st = avformat_new_stream(oc, NULL);
867 int idx = oc->nb_streams - 1, ret = 0;
868 char *bsf = NULL, *next, *codec_tag = NULL;
869 AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
870 double qscale = -1;
Anton Khirnovf5e66822012-08-01 16:23:12871
872 if (!st) {
873 av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17874 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12875 }
876
877 if (oc->nb_streams - 1 < o->nb_streamid_map)
878 st->id = o->streamid_map[oc->nb_streams - 1];
879
Anton Khirnov10bca662012-06-07 19:52:07880 GROW_ARRAY(output_streams, nb_output_streams);
Anton Khirnovf5e66822012-08-01 16:23:12881 if (!(ost = av_mallocz(sizeof(*ost))))
Martin Storsjöb85dbe62013-07-31 10:44:17882 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12883 output_streams[nb_output_streams - 1] = ost;
884
Anton Khirnov3d624422013-04-10 12:46:20885 ost->file_index = nb_output_files - 1;
Anton Khirnovf5e66822012-08-01 16:23:12886 ost->index = idx;
887 ost->st = st;
888 st->codec->codec_type = type;
889 choose_encoder(o, oc, ost);
890 if (ost->enc) {
Anton Khirnov4e61a382012-10-22 20:40:22891 AVIOContext *s = NULL;
892 char *buf = NULL, *arg = NULL, *preset = NULL;
893
Anton Khirnov77bd1bc2012-06-08 19:35:16894 ost->opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
Anton Khirnov4e61a382012-10-22 20:40:22895
896 MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
897 if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
898 do {
899 buf = get_line(s);
900 if (!buf[0] || buf[0] == '#') {
901 av_free(buf);
902 continue;
903 }
904 if (!(arg = strchr(buf, '='))) {
905 av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17906 exit_program(1);
Anton Khirnov4e61a382012-10-22 20:40:22907 }
908 *arg++ = 0;
909 av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
910 av_free(buf);
911 } while (!s->eof_reached);
912 avio_close(s);
913 }
914 if (ret) {
915 av_log(NULL, AV_LOG_FATAL,
916 "Preset %s specified for stream %d:%d, but could not be opened.\n",
917 preset, ost->file_index, ost->index);
Martin Storsjöb85dbe62013-07-31 10:44:17918 exit_program(1);
Anton Khirnov4e61a382012-10-22 20:40:22919 }
Martin Storsjödf0229a2013-02-27 21:22:39920 } else {
921 ost->opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
Anton Khirnovf5e66822012-08-01 16:23:12922 }
923
924 avcodec_get_context_defaults3(st->codec, ost->enc);
925 st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
926
Anton Khirnovf5e66822012-08-01 16:23:12927 ost->max_frames = INT64_MAX;
928 MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
929
930 MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
931 while (bsf) {
932 if (next = strchr(bsf, ','))
933 *next++ = 0;
934 if (!(bsfc = av_bitstream_filter_init(bsf))) {
935 av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
Martin Storsjöb85dbe62013-07-31 10:44:17936 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12937 }
938 if (bsfc_prev)
939 bsfc_prev->next = bsfc;
940 else
941 ost->bitstream_filters = bsfc;
942
943 bsfc_prev = bsfc;
944 bsf = next;
945 }
946
947 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
948 if (codec_tag) {
949 uint32_t tag = strtol(codec_tag, &next, 0);
950 if (*next)
951 tag = AV_RL32(codec_tag);
952 st->codec->codec_tag = tag;
953 }
954
955 MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
Anton Khirnovfb722a92012-10-09 15:40:20956 if (qscale >= 0) {
Anton Khirnovf5e66822012-08-01 16:23:12957 st->codec->flags |= CODEC_FLAG_QSCALE;
958 st->codec->global_quality = FF_QP2LAMBDA * qscale;
959 }
960
961 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
962 st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
963
Anton Khirnov77bd1bc2012-06-08 19:35:16964 av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
Anton Khirnovf5e66822012-08-01 16:23:12965
Justin Ruggles5c7db092012-12-19 02:47:28966 av_dict_copy(&ost->resample_opts, o->g->resample_opts, 0);
967
Anton Khirnov716d4132012-10-06 10:10:34968 ost->pix_fmts[0] = ost->pix_fmts[1] = AV_PIX_FMT_NONE;
Anton Khirnov76d23f42013-04-24 06:34:44969 ost->last_mux_dts = AV_NOPTS_VALUE;
Anton Khirnovf5e66822012-08-01 16:23:12970
971 return ost;
972}
973
974static void parse_matrix_coeffs(uint16_t *dest, const char *str)
975{
976 int i;
977 const char *p = str;
978 for (i = 0;; i++) {
979 dest[i] = atoi(p);
980 if (i == 63)
981 break;
982 p = strchr(p, ',');
983 if (!p) {
984 av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
Martin Storsjöb85dbe62013-07-31 10:44:17985 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12986 }
987 p++;
988 }
989}
990
Anton Khirnova4208b92013-03-13 13:24:45991/* read file contents into a string */
992static uint8_t *read_file(const char *filename)
993{
994 AVIOContext *pb = NULL;
995 AVIOContext *dyn_buf = NULL;
996 int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
997 uint8_t buf[1024], *str;
998
999 if (ret < 0) {
1000 av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
1001 return NULL;
1002 }
1003
1004 ret = avio_open_dyn_buf(&dyn_buf);
1005 if (ret < 0) {
1006 avio_closep(&pb);
1007 return NULL;
1008 }
1009 while ((ret = avio_read(pb, buf, sizeof(buf))) > 0)
1010 avio_write(dyn_buf, buf, ret);
1011 avio_w8(dyn_buf, 0);
1012 avio_closep(&pb);
1013
1014 ret = avio_close_dyn_buf(dyn_buf, &str);
1015 if (ret < 0)
1016 return NULL;
1017 return str;
1018}
1019
1020static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
1021 OutputStream *ost)
1022{
1023 AVStream *st = ost->st;
1024 char *filter = NULL, *filter_script = NULL;
1025
1026 MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
1027 MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
1028
1029 if (filter_script && filter) {
1030 av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
1031 "output stream #%d:%d.\n", nb_output_files, st->index);
Martin Storsjöb85dbe62013-07-31 10:44:171032 exit_program(1);
Anton Khirnova4208b92013-03-13 13:24:451033 }
1034
1035 if (filter_script)
1036 return read_file(filter_script);
1037 else if (filter)
1038 return av_strdup(filter);
1039
1040 return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
1041 "null" : "anull");
1042}
1043
Anton Khirnovf5e66822012-08-01 16:23:121044static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
1045{
1046 AVStream *st;
1047 OutputStream *ost;
1048 AVCodecContext *video_enc;
Anton Khirnov538bf762013-05-26 13:31:091049 char *frame_aspect_ratio = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121050
1051 ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
1052 st = ost->st;
1053 video_enc = st->codec;
1054
Anton Khirnov538bf762013-05-26 13:31:091055 MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
1056 if (frame_aspect_ratio)
1057 ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio);
1058
Anton Khirnovf5e66822012-08-01 16:23:121059 if (!ost->stream_copy) {
1060 const char *p = NULL;
1061 char *frame_rate = NULL, *frame_size = NULL;
Anton Khirnov538bf762013-05-26 13:31:091062 char *frame_pix_fmt = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121063 char *intra_matrix = NULL, *inter_matrix = NULL;
Anton Khirnov038c0b12012-08-19 06:29:441064 int do_pass = 0;
Anton Khirnovf5e66822012-08-01 16:23:121065 int i;
1066
1067 MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
1068 if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
1069 av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
Martin Storsjöb85dbe62013-07-31 10:44:171070 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121071 }
1072
1073 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
1074 if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
1075 av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
Martin Storsjöb85dbe62013-07-31 10:44:171076 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121077 }
1078
Anton Khirnovf5e66822012-08-01 16:23:121079 MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
Anton Khirnov716d4132012-10-06 10:10:341080 if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
Anton Khirnovf5e66822012-08-01 16:23:121081 av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
Martin Storsjöb85dbe62013-07-31 10:44:171082 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121083 }
1084 st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
1085
1086 MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
1087 if (intra_matrix) {
1088 if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
1089 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171090 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121091 }
1092 parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
1093 }
1094 MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
1095 if (inter_matrix) {
1096 if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
1097 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171098 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121099 }
1100 parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
1101 }
1102
1103 MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
1104 for (i = 0; p; i++) {
1105 int start, end, q;
1106 int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
1107 if (e != 3) {
1108 av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
Martin Storsjöb85dbe62013-07-31 10:44:171109 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121110 }
1111 video_enc->rc_override =
1112 av_realloc(video_enc->rc_override,
1113 sizeof(RcOverride) * (i + 1));
1114 video_enc->rc_override[i].start_frame = start;
1115 video_enc->rc_override[i].end_frame = end;
1116 if (q > 0) {
1117 video_enc->rc_override[i].qscale = q;
1118 video_enc->rc_override[i].quality_factor = 1.0;
1119 }
1120 else {
1121 video_enc->rc_override[i].qscale = 0;
1122 video_enc->rc_override[i].quality_factor = -q/100.0;
1123 }
1124 p = strchr(p, '/');
1125 if (p) p++;
1126 }
1127 video_enc->rc_override_count = i;
Anton Khirnovf5e66822012-08-01 16:23:121128 video_enc->intra_dc_precision = intra_dc_precision - 8;
1129
1130 /* two pass mode */
Anton Khirnov038c0b12012-08-19 06:29:441131 MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
Anton Khirnovf5e66822012-08-01 16:23:121132 if (do_pass) {
1133 if (do_pass == 1) {
1134 video_enc->flags |= CODEC_FLAG_PASS1;
1135 } else {
1136 video_enc->flags |= CODEC_FLAG_PASS2;
1137 }
1138 }
1139
Anton Khirnovbbcedad2012-08-19 07:15:481140 MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
1141 if (ost->logfile_prefix &&
1142 !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
Martin Storsjöb85dbe62013-07-31 10:44:171143 exit_program(1);
Anton Khirnovbbcedad2012-08-19 07:15:481144
Anton Khirnovf5e66822012-08-01 16:23:121145 MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
1146 if (ost->forced_keyframes)
1147 ost->forced_keyframes = av_strdup(ost->forced_keyframes);
1148
1149 MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
1150
1151 ost->top_field_first = -1;
1152 MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
1153
Anton Khirnova4208b92013-03-13 13:24:451154
1155 ost->avfilter = get_ost_filters(o, oc, ost);
1156 if (!ost->avfilter)
Martin Storsjöb85dbe62013-07-31 10:44:171157 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121158 } else {
1159 MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
1160 }
1161
1162 return ost;
1163}
1164
1165static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
1166{
1167 AVStream *st;
1168 OutputStream *ost;
1169 AVCodecContext *audio_enc;
1170
1171 ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO);
1172 st = ost->st;
1173
1174 audio_enc = st->codec;
1175 audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
1176
1177 if (!ost->stream_copy) {
1178 char *sample_fmt = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121179
1180 MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
1181
1182 MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
1183 if (sample_fmt &&
1184 (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
1185 av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
Martin Storsjöb85dbe62013-07-31 10:44:171186 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121187 }
1188
1189 MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
1190
Anton Khirnova4208b92013-03-13 13:24:451191 ost->avfilter = get_ost_filters(o, oc, ost);
1192 if (!ost->avfilter)
Martin Storsjöb85dbe62013-07-31 10:44:171193 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121194 }
1195
1196 return ost;
1197}
1198
1199static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
1200{
1201 OutputStream *ost;
1202
1203 ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
1204 if (!ost->stream_copy) {
1205 av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
Martin Storsjöb85dbe62013-07-31 10:44:171206 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121207 }
1208
1209 return ost;
1210}
1211
1212static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc)
1213{
1214 OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
1215 ost->stream_copy = 1;
Anton Khirnov3e175a22013-03-14 08:44:071216 ost->finished = 1;
Anton Khirnovf5e66822012-08-01 16:23:121217 return ost;
1218}
1219
1220static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
1221{
1222 AVStream *st;
1223 OutputStream *ost;
1224 AVCodecContext *subtitle_enc;
1225
1226 ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE);
1227 st = ost->st;
1228 subtitle_enc = st->codec;
1229
1230 subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
1231
1232 return ost;
1233}
1234
1235/* arg format is "output-stream-index:streamid-value". */
Anton Khirnovd3810c42012-08-11 14:30:261236static int opt_streamid(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121237{
Anton Khirnovd3810c42012-08-11 14:30:261238 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121239 int idx;
1240 char *p;
1241 char idx_str[16];
1242
1243 av_strlcpy(idx_str, arg, sizeof(idx_str));
1244 p = strchr(idx_str, ':');
1245 if (!p) {
1246 av_log(NULL, AV_LOG_FATAL,
1247 "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
1248 arg, opt);
Martin Storsjöb85dbe62013-07-31 10:44:171249 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121250 }
1251 *p++ = '\0';
1252 idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
1253 o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
1254 o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
1255 return 0;
1256}
1257
1258static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
1259{
1260 AVFormatContext *is = ifile->ctx;
1261 AVFormatContext *os = ofile->ctx;
Janne Grunau18ff4d22012-10-09 13:20:151262 AVChapter **tmp;
Anton Khirnovf5e66822012-08-01 16:23:121263 int i;
1264
Janne Grunau18ff4d22012-10-09 13:20:151265 tmp = av_realloc(os->chapters, sizeof(*os->chapters) * (is->nb_chapters + os->nb_chapters));
1266 if (!tmp)
1267 return AVERROR(ENOMEM);
1268 os->chapters = tmp;
1269
Anton Khirnovf5e66822012-08-01 16:23:121270 for (i = 0; i < is->nb_chapters; i++) {
1271 AVChapter *in_ch = is->chapters[i], *out_ch;
Anton Khirnov56ee3f92013-06-15 07:35:101272 int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
1273 int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
Anton Khirnovf5e66822012-08-01 16:23:121274 AV_TIME_BASE_Q, in_ch->time_base);
1275 int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
1276 av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
1277
1278
1279 if (in_ch->end < ts_off)
1280 continue;
1281 if (rt != INT64_MAX && in_ch->start > rt + ts_off)
1282 break;
1283
1284 out_ch = av_mallocz(sizeof(AVChapter));
1285 if (!out_ch)
1286 return AVERROR(ENOMEM);
1287
1288 out_ch->id = in_ch->id;
1289 out_ch->time_base = in_ch->time_base;
1290 out_ch->start = FFMAX(0, in_ch->start - ts_off);
1291 out_ch->end = FFMIN(rt, in_ch->end - ts_off);
1292
1293 if (copy_metadata)
1294 av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
1295
Janne Grunau18ff4d22012-10-09 13:20:151296 os->chapters[os->nb_chapters++] = out_ch;
Anton Khirnovf5e66822012-08-01 16:23:121297 }
1298 return 0;
1299}
1300
1301static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
1302 AVFormatContext *oc)
1303{
1304 OutputStream *ost;
1305
1306 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1307 ofilter->out_tmp->pad_idx)) {
1308 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1309 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1310 default:
1311 av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
1312 "currently.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171313 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121314 }
1315
1316 ost->source_index = -1;
1317 ost->filter = ofilter;
1318
1319 ofilter->ost = ost;
1320
1321 if (ost->stream_copy) {
1322 av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
1323 "which is fed from a complex filtergraph. Filtering and streamcopy "
1324 "cannot be used together.\n", ost->file_index, ost->index);
Martin Storsjöb85dbe62013-07-31 10:44:171325 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121326 }
1327
1328 if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
1329 av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171330 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121331 }
1332 avfilter_inout_free(&ofilter->out_tmp);
1333}
1334
1335static int configure_complex_filters(void)
1336{
1337 int i, ret = 0;
1338
1339 for (i = 0; i < nb_filtergraphs; i++)
1340 if (!filtergraphs[i]->graph &&
1341 (ret = configure_filtergraph(filtergraphs[i])) < 0)
1342 return ret;
1343 return 0;
1344}
1345
Anton Khirnov77bd1bc2012-06-08 19:35:161346static int open_output_file(OptionsContext *o, const char *filename)
Anton Khirnovf5e66822012-08-01 16:23:121347{
Anton Khirnovf5e66822012-08-01 16:23:121348 AVFormatContext *oc;
1349 int i, j, err;
1350 AVOutputFormat *file_oformat;
Anton Khirnov1da54e92013-02-21 08:53:281351 OutputFile *of;
Anton Khirnovf5e66822012-08-01 16:23:121352 OutputStream *ost;
1353 InputStream *ist;
Anton Khirnove7553f42013-02-21 09:58:461354 AVDictionary *unused_opts = NULL;
1355 AVDictionaryEntry *e = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121356
1357 if (configure_complex_filters() < 0) {
1358 av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171359 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121360 }
1361
Anton Khirnov3d624422013-04-10 12:46:201362 GROW_ARRAY(output_files, nb_output_files);
1363 of = av_mallocz(sizeof(*of));
1364 if (!of)
Martin Storsjöb85dbe62013-07-31 10:44:171365 exit_program(1);
Anton Khirnov3d624422013-04-10 12:46:201366 output_files[nb_output_files - 1] = of;
1367
1368 of->ost_index = nb_output_streams;
1369 of->recording_time = o->recording_time;
1370 of->start_time = o->start_time;
1371 of->limit_filesize = o->limit_filesize;
1372 of->shortest = o->shortest;
1373 av_dict_copy(&of->opts, o->g->format_opts, 0);
1374
Anton Khirnovf5e66822012-08-01 16:23:121375 if (!strcmp(filename, "-"))
1376 filename = "pipe:";
1377
1378 oc = avformat_alloc_context();
1379 if (!oc) {
1380 print_error(filename, AVERROR(ENOMEM));
Martin Storsjöb85dbe62013-07-31 10:44:171381 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121382 }
Anton Khirnov3d624422013-04-10 12:46:201383 of->ctx = oc;
1384 if (o->recording_time != INT64_MAX)
1385 oc->duration = o->recording_time;
Anton Khirnovf5e66822012-08-01 16:23:121386
1387 if (o->format) {
1388 file_oformat = av_guess_format(o->format, NULL, NULL);
1389 if (!file_oformat) {
1390 av_log(NULL, AV_LOG_FATAL, "Requested output format '%s' is not a suitable output format\n", o->format);
Martin Storsjöb85dbe62013-07-31 10:44:171391 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121392 }
1393 } else {
1394 file_oformat = av_guess_format(NULL, filename, NULL);
1395 if (!file_oformat) {
1396 av_log(NULL, AV_LOG_FATAL, "Unable to find a suitable output format for '%s'\n",
1397 filename);
Martin Storsjöb85dbe62013-07-31 10:44:171398 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121399 }
1400 }
1401
1402 oc->oformat = file_oformat;
1403 oc->interrupt_callback = int_cb;
1404 av_strlcpy(oc->filename, filename, sizeof(oc->filename));
1405
1406 /* create streams for all unlabeled output pads */
1407 for (i = 0; i < nb_filtergraphs; i++) {
1408 FilterGraph *fg = filtergraphs[i];
1409 for (j = 0; j < fg->nb_outputs; j++) {
1410 OutputFilter *ofilter = fg->outputs[j];
1411
1412 if (!ofilter->out_tmp || ofilter->out_tmp->name)
1413 continue;
1414
1415 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1416 ofilter->out_tmp->pad_idx)) {
1417 case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break;
1418 case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break;
1419 case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
1420 }
1421 init_output_filter(ofilter, o, oc);
1422 }
1423 }
1424
1425 if (!o->nb_stream_maps) {
1426 /* pick the "best" stream of each type */
1427#define NEW_STREAM(type, index)\
1428 if (index >= 0) {\
1429 ost = new_ ## type ## _stream(o, oc);\
1430 ost->source_index = index;\
1431 ost->sync_ist = input_streams[index];\
1432 input_streams[index]->discard = 0;\
1433 input_streams[index]->st->discard = AVDISCARD_NONE;\
1434 }
1435
1436 /* video: highest resolution */
1437 if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
1438 int area = 0, idx = -1;
1439 for (i = 0; i < nb_input_streams; i++) {
1440 ist = input_streams[i];
1441 if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
1442 ist->st->codec->width * ist->st->codec->height > area) {
1443 area = ist->st->codec->width * ist->st->codec->height;
1444 idx = i;
1445 }
1446 }
1447 NEW_STREAM(video, idx);
1448 }
1449
1450 /* audio: most channels */
1451 if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
1452 int channels = 0, idx = -1;
1453 for (i = 0; i < nb_input_streams; i++) {
1454 ist = input_streams[i];
1455 if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
1456 ist->st->codec->channels > channels) {
1457 channels = ist->st->codec->channels;
1458 idx = i;
1459 }
1460 }
1461 NEW_STREAM(audio, idx);
1462 }
1463
1464 /* subtitles: pick first */
1465 if (!o->subtitle_disable && oc->oformat->subtitle_codec != AV_CODEC_ID_NONE) {
1466 for (i = 0; i < nb_input_streams; i++)
1467 if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1468 NEW_STREAM(subtitle, i);
1469 break;
1470 }
1471 }
1472 /* do something with data? */
1473 } else {
1474 for (i = 0; i < o->nb_stream_maps; i++) {
1475 StreamMap *map = &o->stream_maps[i];
1476
1477 if (map->disabled)
1478 continue;
1479
1480 if (map->linklabel) {
1481 FilterGraph *fg;
1482 OutputFilter *ofilter = NULL;
1483 int j, k;
1484
1485 for (j = 0; j < nb_filtergraphs; j++) {
1486 fg = filtergraphs[j];
1487 for (k = 0; k < fg->nb_outputs; k++) {
1488 AVFilterInOut *out = fg->outputs[k]->out_tmp;
1489 if (out && !strcmp(out->name, map->linklabel)) {
1490 ofilter = fg->outputs[k];
1491 goto loop_end;
1492 }
1493 }
1494 }
1495loop_end:
1496 if (!ofilter) {
1497 av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
1498 "in any defined filter graph.\n", map->linklabel);
Martin Storsjöb85dbe62013-07-31 10:44:171499 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121500 }
1501 init_output_filter(ofilter, o, oc);
1502 } else {
1503 ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
1504 switch (ist->st->codec->codec_type) {
1505 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1506 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1507 case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
1508 case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break;
1509 case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
1510 default:
1511 av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
1512 map->file_index, map->stream_index);
Martin Storsjöb85dbe62013-07-31 10:44:171513 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121514 }
1515
1516 ost->source_index = input_files[map->file_index]->ist_index + map->stream_index;
1517 ost->sync_ist = input_streams[input_files[map->sync_file_index]->ist_index +
1518 map->sync_stream_index];
1519 ist->discard = 0;
1520 ist->st->discard = AVDISCARD_NONE;
1521 }
1522 }
1523 }
1524
1525 /* handle attached files */
1526 for (i = 0; i < o->nb_attachments; i++) {
1527 AVIOContext *pb;
1528 uint8_t *attachment;
1529 const char *p;
1530 int64_t len;
1531
1532 if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
1533 av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
1534 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171535 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121536 }
1537 if ((len = avio_size(pb)) <= 0) {
1538 av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
1539 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171540 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121541 }
1542 if (!(attachment = av_malloc(len))) {
1543 av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
1544 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171545 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121546 }
1547 avio_read(pb, attachment, len);
1548
1549 ost = new_attachment_stream(o, oc);
1550 ost->stream_copy = 0;
1551 ost->source_index = -1;
1552 ost->attachment_filename = o->attachments[i];
1553 ost->st->codec->extradata = attachment;
1554 ost->st->codec->extradata_size = len;
1555
1556 p = strrchr(o->attachments[i], '/');
1557 av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
1558 avio_close(pb);
1559 }
1560
Anton Khirnove7553f42013-02-21 09:58:461561 /* check if all codec options have been used */
1562 unused_opts = strip_specifiers(o->g->codec_opts);
1563 for (i = of->ost_index; i < nb_output_streams; i++) {
1564 e = NULL;
1565 while ((e = av_dict_get(output_streams[i]->opts, "", e,
1566 AV_DICT_IGNORE_SUFFIX)))
1567 av_dict_set(&unused_opts, e->key, NULL, 0);
1568 }
1569
1570 e = NULL;
1571 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
1572 const AVClass *class = avcodec_get_class();
1573 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
1574 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1575 if (!option)
1576 continue;
1577 if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
1578 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
1579 "output file #%d (%s) is not an encoding option.\n", e->key,
1580 option->help ? option->help : "", nb_output_files - 1,
1581 filename);
Martin Storsjöb85dbe62013-07-31 10:44:171582 exit_program(1);
Anton Khirnove7553f42013-02-21 09:58:461583 }
1584
1585 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
1586 "output file #%d (%s) has not been used for any stream. The most "
1587 "likely reason is either wrong type (e.g. a video option with "
1588 "no video streams) or that it is a private option of some encoder "
1589 "which was not actually used for any stream.\n", e->key,
1590 option->help ? option->help : "", nb_output_files - 1, filename);
1591 }
1592 av_dict_free(&unused_opts);
1593
Anton Khirnovf5e66822012-08-01 16:23:121594 /* check filename in case of an image number is expected */
1595 if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
1596 if (!av_filename_number_test(oc->filename)) {
1597 print_error(oc->filename, AVERROR(EINVAL));
Martin Storsjöb85dbe62013-07-31 10:44:171598 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121599 }
1600 }
1601
1602 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
1603 /* test if it already exists to avoid losing precious files */
1604 assert_file_overwrite(filename);
1605
1606 /* open the file */
1607 if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
1608 &oc->interrupt_callback,
Anton Khirnov1da54e92013-02-21 08:53:281609 &of->opts)) < 0) {
Anton Khirnovf5e66822012-08-01 16:23:121610 print_error(filename, err);
Martin Storsjöb85dbe62013-07-31 10:44:171611 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121612 }
1613 }
1614
1615 if (o->mux_preload) {
1616 uint8_t buf[64];
1617 snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
Anton Khirnov1da54e92013-02-21 08:53:281618 av_dict_set(&of->opts, "preload", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:121619 }
1620 oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
1621 oc->flags |= AVFMT_FLAG_NONBLOCK;
1622
1623 /* copy metadata */
1624 for (i = 0; i < o->nb_metadata_map; i++) {
1625 char *p;
1626 int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
1627
Anton Khirnovf5e66822012-08-01 16:23:121628 if (in_file_index >= nb_input_files) {
1629 av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
Martin Storsjöb85dbe62013-07-31 10:44:171630 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121631 }
Anton Khirnova119c642012-10-16 07:53:391632 copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
1633 in_file_index >= 0 ?
1634 input_files[in_file_index]->ctx : NULL, o);
Anton Khirnovf5e66822012-08-01 16:23:121635 }
1636
1637 /* copy chapters */
1638 if (o->chapters_input_file >= nb_input_files) {
1639 if (o->chapters_input_file == INT_MAX) {
1640 /* copy chapters from the first input file that has them*/
1641 o->chapters_input_file = -1;
1642 for (i = 0; i < nb_input_files; i++)
1643 if (input_files[i]->ctx->nb_chapters) {
1644 o->chapters_input_file = i;
1645 break;
1646 }
1647 } else {
1648 av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
1649 o->chapters_input_file);
Martin Storsjöb85dbe62013-07-31 10:44:171650 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121651 }
1652 }
1653 if (o->chapters_input_file >= 0)
Anton Khirnov1da54e92013-02-21 08:53:281654 copy_chapters(input_files[o->chapters_input_file], of,
Anton Khirnovf5e66822012-08-01 16:23:121655 !o->metadata_chapters_manual);
1656
1657 /* copy global metadata by default */
1658 if (!o->metadata_global_manual && nb_input_files)
1659 av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
1660 AV_DICT_DONT_OVERWRITE);
1661 if (!o->metadata_streams_manual)
Anton Khirnov1da54e92013-02-21 08:53:281662 for (i = of->ost_index; i < nb_output_streams; i++) {
Anton Khirnovf5e66822012-08-01 16:23:121663 InputStream *ist;
1664 if (output_streams[i]->source_index < 0) /* this is true e.g. for attached files */
1665 continue;
1666 ist = input_streams[output_streams[i]->source_index];
1667 av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
1668 }
1669
1670 /* process manually set metadata */
1671 for (i = 0; i < o->nb_metadata; i++) {
1672 AVDictionary **m;
1673 char type, *val;
1674 const char *stream_spec;
1675 int index = 0, j, ret;
1676
1677 val = strchr(o->metadata[i].u.str, '=');
1678 if (!val) {
1679 av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
1680 o->metadata[i].u.str);
Martin Storsjöb85dbe62013-07-31 10:44:171681 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121682 }
1683 *val++ = 0;
1684
1685 parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
1686 if (type == 's') {
1687 for (j = 0; j < oc->nb_streams; j++) {
1688 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
1689 av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
1690 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:171691 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121692 }
1693 }
1694 else {
1695 switch (type) {
1696 case 'g':
1697 m = &oc->metadata;
1698 break;
1699 case 'c':
1700 if (index < 0 || index >= oc->nb_chapters) {
1701 av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
Martin Storsjöb85dbe62013-07-31 10:44:171702 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121703 }
1704 m = &oc->chapters[index]->metadata;
1705 break;
1706 default:
1707 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
Martin Storsjöb85dbe62013-07-31 10:44:171708 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121709 }
1710 av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
1711 }
1712 }
1713
Anton Khirnov77bd1bc2012-06-08 19:35:161714 return 0;
Anton Khirnovf5e66822012-08-01 16:23:121715}
1716
Anton Khirnovd3810c42012-08-11 14:30:261717static int opt_target(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121718{
Anton Khirnovd3810c42012-08-11 14:30:261719 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121720 enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
1721 static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
1722
1723 if (!strncmp(arg, "pal-", 4)) {
1724 norm = PAL;
1725 arg += 4;
1726 } else if (!strncmp(arg, "ntsc-", 5)) {
1727 norm = NTSC;
1728 arg += 5;
1729 } else if (!strncmp(arg, "film-", 5)) {
1730 norm = FILM;
1731 arg += 5;
1732 } else {
1733 /* Try to determine PAL/NTSC by peeking in the input files */
1734 if (nb_input_files) {
1735 int i, j, fr;
1736 for (j = 0; j < nb_input_files; j++) {
1737 for (i = 0; i < input_files[j]->nb_streams; i++) {
1738 AVCodecContext *c = input_files[j]->ctx->streams[i]->codec;
1739 if (c->codec_type != AVMEDIA_TYPE_VIDEO)
1740 continue;
1741 fr = c->time_base.den * 1000 / c->time_base.num;
1742 if (fr == 25000) {
1743 norm = PAL;
1744 break;
1745 } else if ((fr == 29970) || (fr == 23976)) {
1746 norm = NTSC;
1747 break;
1748 }
1749 }
1750 if (norm != UNKNOWN)
1751 break;
1752 }
1753 }
1754 if (norm != UNKNOWN)
1755 av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
1756 }
1757
1758 if (norm == UNKNOWN) {
1759 av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
1760 av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
1761 av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
Martin Storsjöb85dbe62013-07-31 10:44:171762 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121763 }
1764
1765 if (!strcmp(arg, "vcd")) {
1766 opt_video_codec(o, "c:v", "mpeg1video");
1767 opt_audio_codec(o, "c:a", "mp2");
1768 parse_option(o, "f", "vcd", options);
1769
1770 parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
1771 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221772 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121773
Anton Khirnov11d957f2012-08-29 12:37:221774 opt_default(NULL, "b", "1150000");
1775 opt_default(NULL, "maxrate", "1150000");
1776 opt_default(NULL, "minrate", "1150000");
1777 opt_default(NULL, "bufsize", "327680"); // 40*1024*8;
Anton Khirnovf5e66822012-08-01 16:23:121778
Anton Khirnov11d957f2012-08-29 12:37:221779 opt_default(NULL, "b:a", "224000");
Anton Khirnovf5e66822012-08-01 16:23:121780 parse_option(o, "ar", "44100", options);
1781 parse_option(o, "ac", "2", options);
1782
Anton Khirnov11d957f2012-08-29 12:37:221783 opt_default(NULL, "packetsize", "2324");
1784 opt_default(NULL, "muxrate", "1411200"); // 2352 * 75 * 8;
Anton Khirnovf5e66822012-08-01 16:23:121785
1786 /* We have to offset the PTS, so that it is consistent with the SCR.
1787 SCR starts at 36000, but the first two packs contain only padding
1788 and the first pack from the other stream, respectively, may also have
1789 been written before.
1790 So the real data starts at SCR 36000+3*1200. */
1791 o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
1792 } else if (!strcmp(arg, "svcd")) {
1793
1794 opt_video_codec(o, "c:v", "mpeg2video");
1795 opt_audio_codec(o, "c:a", "mp2");
1796 parse_option(o, "f", "svcd", options);
1797
1798 parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
1799 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221800 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121801
Anton Khirnov11d957f2012-08-29 12:37:221802 opt_default(NULL, "b", "2040000");
1803 opt_default(NULL, "maxrate", "2516000");
1804 opt_default(NULL, "minrate", "0"); // 1145000;
1805 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
1806 opt_default(NULL, "flags", "+scan_offset");
Anton Khirnovf5e66822012-08-01 16:23:121807
1808
Anton Khirnov11d957f2012-08-29 12:37:221809 opt_default(NULL, "b:a", "224000");
Anton Khirnovf5e66822012-08-01 16:23:121810 parse_option(o, "ar", "44100", options);
1811
Anton Khirnov11d957f2012-08-29 12:37:221812 opt_default(NULL, "packetsize", "2324");
Anton Khirnovf5e66822012-08-01 16:23:121813
1814 } else if (!strcmp(arg, "dvd")) {
1815
1816 opt_video_codec(o, "c:v", "mpeg2video");
1817 opt_audio_codec(o, "c:a", "ac3");
1818 parse_option(o, "f", "dvd", options);
1819
1820 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
1821 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221822 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121823
Anton Khirnov11d957f2012-08-29 12:37:221824 opt_default(NULL, "b", "6000000");
1825 opt_default(NULL, "maxrate", "9000000");
1826 opt_default(NULL, "minrate", "0"); // 1500000;
1827 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
Anton Khirnovf5e66822012-08-01 16:23:121828
Anton Khirnov11d957f2012-08-29 12:37:221829 opt_default(NULL, "packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
1830 opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
Anton Khirnovf5e66822012-08-01 16:23:121831
Anton Khirnov11d957f2012-08-29 12:37:221832 opt_default(NULL, "b:a", "448000");
Anton Khirnovf5e66822012-08-01 16:23:121833 parse_option(o, "ar", "48000", options);
1834
1835 } else if (!strncmp(arg, "dv", 2)) {
1836
1837 parse_option(o, "f", "dv", options);
1838
1839 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
1840 parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
1841 norm == PAL ? "yuv420p" : "yuv411p", options);
1842 parse_option(o, "r", frame_rates[norm], options);
1843
1844 parse_option(o, "ar", "48000", options);
1845 parse_option(o, "ac", "2", options);
1846
1847 } else {
1848 av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
1849 return AVERROR(EINVAL);
1850 }
1851 return 0;
1852}
1853
Anton Khirnov11d957f2012-08-29 12:37:221854static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121855{
1856 av_free (vstats_filename);
1857 vstats_filename = av_strdup (arg);
1858 return 0;
1859}
1860
Anton Khirnov11d957f2012-08-29 12:37:221861static int opt_vstats(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121862{
1863 char filename[40];
1864 time_t today2 = time(NULL);
1865 struct tm *today = localtime(&today2);
1866
1867 snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
1868 today->tm_sec);
Anton Khirnov11d957f2012-08-29 12:37:221869 return opt_vstats_file(NULL, opt, filename);
Anton Khirnovf5e66822012-08-01 16:23:121870}
1871
Anton Khirnovd3810c42012-08-11 14:30:261872static int opt_video_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121873{
Anton Khirnovd3810c42012-08-11 14:30:261874 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121875 return parse_option(o, "frames:v", arg, options);
1876}
1877
Anton Khirnovd3810c42012-08-11 14:30:261878static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121879{
Anton Khirnovd3810c42012-08-11 14:30:261880 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121881 return parse_option(o, "frames:a", arg, options);
1882}
1883
Anton Khirnovd3810c42012-08-11 14:30:261884static int opt_data_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121885{
Anton Khirnovd3810c42012-08-11 14:30:261886 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121887 return parse_option(o, "frames:d", arg, options);
1888}
1889
Anton Khirnovd3810c42012-08-11 14:30:261890static int opt_video_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121891{
Anton Khirnovd3810c42012-08-11 14:30:261892 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121893 return parse_option(o, "tag:v", arg, options);
1894}
1895
Anton Khirnovd3810c42012-08-11 14:30:261896static int opt_audio_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121897{
Anton Khirnovd3810c42012-08-11 14:30:261898 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121899 return parse_option(o, "tag:a", arg, options);
1900}
1901
Anton Khirnovd3810c42012-08-11 14:30:261902static int opt_subtitle_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121903{
Anton Khirnovd3810c42012-08-11 14:30:261904 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121905 return parse_option(o, "tag:s", arg, options);
1906}
1907
Anton Khirnovd3810c42012-08-11 14:30:261908static int opt_video_filters(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121909{
Anton Khirnovd3810c42012-08-11 14:30:261910 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121911 return parse_option(o, "filter:v", arg, options);
1912}
1913
Anton Khirnovd3810c42012-08-11 14:30:261914static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121915{
Anton Khirnovd3810c42012-08-11 14:30:261916 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121917 return parse_option(o, "filter:a", arg, options);
1918}
1919
Anton Khirnov11d957f2012-08-29 12:37:221920static int opt_vsync(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121921{
1922 if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR;
1923 else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR;
1924 else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
1925
1926 if (video_sync_method == VSYNC_AUTO)
1927 video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
1928 return 0;
1929}
1930
Anton Khirnovd3810c42012-08-11 14:30:261931static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121932{
Anton Khirnovd3810c42012-08-11 14:30:261933 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121934 char layout_str[32];
1935 char *stream_str;
1936 char *ac_str;
1937 int ret, channels, ac_str_size;
1938 uint64_t layout;
1939
1940 layout = av_get_channel_layout(arg);
1941 if (!layout) {
1942 av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
1943 return AVERROR(EINVAL);
1944 }
1945 snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
Anton Khirnov11d957f2012-08-29 12:37:221946 ret = opt_default(NULL, opt, layout_str);
Anton Khirnovf5e66822012-08-01 16:23:121947 if (ret < 0)
1948 return ret;
1949
1950 /* set 'ac' option based on channel layout */
1951 channels = av_get_channel_layout_nb_channels(layout);
1952 snprintf(layout_str, sizeof(layout_str), "%d", channels);
1953 stream_str = strchr(opt, ':');
1954 ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
1955 ac_str = av_mallocz(ac_str_size);
1956 if (!ac_str)
1957 return AVERROR(ENOMEM);
1958 av_strlcpy(ac_str, "ac", 3);
1959 if (stream_str)
1960 av_strlcat(ac_str, stream_str, ac_str_size);
1961 ret = parse_option(o, ac_str, layout_str, options);
1962 av_free(ac_str);
1963
1964 return ret;
1965}
1966
Anton Khirnovd3810c42012-08-11 14:30:261967static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121968{
Anton Khirnovd3810c42012-08-11 14:30:261969 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121970 return parse_option(o, "q:a", arg, options);
1971}
1972
Anton Khirnov11d957f2012-08-29 12:37:221973static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121974{
Anton Khirnov10bca662012-06-07 19:52:071975 GROW_ARRAY(filtergraphs, nb_filtergraphs);
Anton Khirnovf5e66822012-08-01 16:23:121976 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
1977 return AVERROR(ENOMEM);
Anton Khirnova4208b92013-03-13 13:24:451978 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
1979 filtergraphs[nb_filtergraphs - 1]->graph_desc = av_strdup(arg);
1980 if (!filtergraphs[nb_filtergraphs - 1]->graph_desc)
1981 return AVERROR(ENOMEM);
1982 return 0;
1983}
1984
1985static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
1986{
1987 uint8_t *graph_desc = read_file(arg);
1988 if (!graph_desc)
1989 return AVERROR(EINVAL);
1990
1991 GROW_ARRAY(filtergraphs, nb_filtergraphs);
1992 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
1993 return AVERROR(ENOMEM);
1994 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
1995 filtergraphs[nb_filtergraphs - 1]->graph_desc = graph_desc;
Anton Khirnovf5e66822012-08-01 16:23:121996 return 0;
1997}
1998
Anton Khirnova3ad68d2012-08-13 18:06:251999void show_help_default(const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:122000{
Anton Khirnovf9fada22012-08-15 08:31:462001 /* per-file options have at least one of those set */
Anton Khirnov11d957f2012-08-29 12:37:222002 const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
Anton Khirnov6e3857f2012-08-14 06:56:322003 int show_advanced = 0, show_avoptions = 0;
2004
Janne Grunau8d09d392012-10-10 18:35:262005 if (opt && *opt) {
Anton Khirnov6e3857f2012-08-14 06:56:322006 if (!strcmp(opt, "long"))
2007 show_advanced = 1;
2008 else if (!strcmp(opt, "full"))
2009 show_advanced = show_avoptions = 1;
2010 else
2011 av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
2012 }
Anton Khirnova3ad68d2012-08-13 18:06:252013
Anton Khirnovf5e66822012-08-01 16:23:122014 show_usage();
Anton Khirnov6e3857f2012-08-14 06:56:322015
2016 printf("Getting help:\n"
2017 " -h -- print basic options\n"
2018 " -h long -- print more options\n"
2019 " -h full -- print all options (including all format and codec specific options, very long)\n"
2020 " See man %s for detailed description of the options.\n"
2021 "\n", program_name);
2022
Anton Khirnovf8b1e662012-08-14 06:21:422023 show_help_options(options, "Print help / information / capabilities:",
Anton Khirnovf9fada22012-08-15 08:31:462024 OPT_EXIT, 0, 0);
2025
2026 show_help_options(options, "Global options (affect whole program "
2027 "instead of just one file:",
2028 0, per_file | OPT_EXIT | OPT_EXPERT, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322029 if (show_advanced)
Anton Khirnovf9fada22012-08-15 08:31:462030 show_help_options(options, "Advanced global options:", OPT_EXPERT,
2031 per_file | OPT_EXIT, 0);
2032
2033 show_help_options(options, "Per-file main options:", 0,
2034 OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
2035 OPT_EXIT, per_file);
2036 if (show_advanced)
2037 show_help_options(options, "Advanced per-file options:",
2038 OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
Anton Khirnov6e3857f2012-08-14 06:56:322039
Anton Khirnovdc4c24a2012-08-11 17:33:272040 show_help_options(options, "Video options:",
Anton Khirnovf9fada22012-08-15 08:31:462041 OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322042 if (show_advanced)
2043 show_help_options(options, "Advanced Video options:",
Anton Khirnovf9fada22012-08-15 08:31:462044 OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322045
Anton Khirnovdc4c24a2012-08-11 17:33:272046 show_help_options(options, "Audio options:",
Anton Khirnovf9fada22012-08-15 08:31:462047 OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322048 if (show_advanced)
2049 show_help_options(options, "Advanced Audio options:",
Anton Khirnovf9fada22012-08-15 08:31:462050 OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
Anton Khirnovdc4c24a2012-08-11 17:33:272051 show_help_options(options, "Subtitle options:",
Anton Khirnovf9fada22012-08-15 08:31:462052 OPT_SUBTITLE, 0, 0);
Anton Khirnovf5e66822012-08-01 16:23:122053 printf("\n");
Anton Khirnov6e3857f2012-08-14 06:56:322054
2055 if (show_avoptions) {
2056 int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
2057 show_help_children(avcodec_get_class(), flags);
2058 show_help_children(avformat_get_class(), flags);
2059 show_help_children(sws_get_class(), flags);
Anton Khirnovdc574652013-03-13 08:10:342060 show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM);
Anton Khirnov6e3857f2012-08-14 06:56:322061 }
Anton Khirnovf5e66822012-08-01 16:23:122062}
2063
2064void show_usage(void)
2065{
2066 printf("Hyper fast Audio and Video encoder\n");
2067 printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
2068 printf("\n");
2069}
2070
Anton Khirnov77bd1bc2012-06-08 19:35:162071enum OptGroup {
2072 GROUP_OUTFILE,
2073 GROUP_INFILE,
2074};
2075
2076static const OptionGroupDef groups[] = {
Anton Khirnov9d3009c2013-02-20 07:02:162077 [GROUP_OUTFILE] = { "output file", NULL, OPT_OUTPUT },
2078 [GROUP_INFILE] = { "input file", "i", OPT_INPUT },
Anton Khirnov77bd1bc2012-06-08 19:35:162079};
2080
2081static int open_files(OptionGroupList *l, const char *inout,
2082 int (*open_file)(OptionsContext*, const char*))
2083{
2084 int i, ret;
2085
2086 for (i = 0; i < l->nb_groups; i++) {
2087 OptionGroup *g = &l->groups[i];
2088 OptionsContext o;
2089
2090 init_options(&o);
2091 o.g = g;
2092
2093 ret = parse_optgroup(&o, g);
2094 if (ret < 0) {
2095 av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
2096 "%s.\n", inout, g->arg);
2097 return ret;
2098 }
2099
2100 av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
2101 ret = open_file(&o, g->arg);
2102 uninit_options(&o);
2103 if (ret < 0) {
2104 av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
2105 inout, g->arg);
2106 return ret;
2107 }
Anton Khirnovdb2d65c2013-02-21 09:57:572108 av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
Anton Khirnov77bd1bc2012-06-08 19:35:162109 }
2110
2111 return 0;
2112}
2113
2114int avconv_parse_options(int argc, char **argv)
2115{
2116 OptionParseContext octx;
2117 uint8_t error[128];
2118 int ret;
2119
2120 memset(&octx, 0, sizeof(octx));
2121
2122 /* split the commandline into an internal representation */
Anton Khirnovc661cb62012-12-19 20:53:222123 ret = split_commandline(&octx, argc, argv, options, groups,
2124 FF_ARRAY_ELEMS(groups));
Anton Khirnov77bd1bc2012-06-08 19:35:162125 if (ret < 0) {
2126 av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
2127 goto fail;
2128 }
2129
2130 /* apply global options */
2131 ret = parse_optgroup(NULL, &octx.global_opts);
2132 if (ret < 0) {
2133 av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
2134 goto fail;
2135 }
2136
2137 /* open input files */
2138 ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
2139 if (ret < 0) {
2140 av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
2141 goto fail;
2142 }
2143
2144 /* open output files */
2145 ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
2146 if (ret < 0) {
2147 av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
2148 goto fail;
2149 }
2150
2151fail:
2152 uninit_parse_context(&octx);
2153 if (ret < 0) {
2154 av_strerror(ret, error, sizeof(error));
2155 av_log(NULL, AV_LOG_FATAL, "%s\n", error);
2156 }
2157 return ret;
2158}
Anton Khirnovf5e66822012-08-01 16:23:122159
2160#define OFFSET(x) offsetof(OptionsContext, x)
2161const OptionDef options[] = {
2162 /* main options */
2163#include "cmdutils_common_opts.h"
Anton Khirnov9d3009c2013-02-20 07:02:162164 { "f", HAS_ARG | OPT_STRING | OPT_OFFSET |
2165 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(format) },
Anton Khirnov8fc83fb2012-08-11 15:00:302166 "force format", "fmt" },
Anton Khirnov8fc83fb2012-08-11 15:00:302167 { "y", OPT_BOOL, { &file_overwrite },
2168 "overwrite output files" },
Vittorio Giovara7748dd42013-07-31 12:48:492169 { "n", OPT_BOOL, { &file_skip },
2170 "never overwrite output files" },
Anton Khirnov9d3009c2013-02-20 07:02:162171 { "c", HAS_ARG | OPT_STRING | OPT_SPEC |
2172 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
Anton Khirnov8fc83fb2012-08-11 15:00:302173 "codec name", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162174 { "codec", HAS_ARG | OPT_STRING | OPT_SPEC |
2175 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
Anton Khirnov8fc83fb2012-08-11 15:00:302176 "codec name", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162177 { "pre", HAS_ARG | OPT_STRING | OPT_SPEC |
2178 OPT_OUTPUT, { .off = OFFSET(presets) },
Anton Khirnov8fc83fb2012-08-11 15:00:302179 "preset name", "preset" },
Anton Khirnov9d3009c2013-02-20 07:02:162180 { "map", HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2181 OPT_OUTPUT, { .func_arg = opt_map },
Anton Khirnov8fc83fb2012-08-11 15:00:302182 "set input stream mapping",
2183 "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
Anton Khirnov9d3009c2013-02-20 07:02:162184 { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC |
2185 OPT_OUTPUT, { .off = OFFSET(metadata_map) },
Anton Khirnov8fc83fb2012-08-11 15:00:302186 "set metadata information of outfile from infile",
2187 "outfile[,metadata]:infile[,metadata]" },
Anton Khirnov9d3009c2013-02-20 07:02:162188 { "map_chapters", HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
2189 OPT_OUTPUT, { .off = OFFSET(chapters_input_file) },
Anton Khirnov8fc83fb2012-08-11 15:00:302190 "set chapters mapping", "input_file_index" },
Anton Khirnov488a0fa2013-06-18 09:12:092191 { "t", HAS_ARG | OPT_TIME | OPT_OFFSET |
2192 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(recording_time) },
Anton Khirnov8fc83fb2012-08-11 15:00:302193 "record or transcode \"duration\" seconds of audio/video",
2194 "duration" },
Anton Khirnov9d3009c2013-02-20 07:02:162195 { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
Anton Khirnov8fc83fb2012-08-11 15:00:302196 "set the limit file size in bytes", "limit_size" },
Anton Khirnov9d3009c2013-02-20 07:02:162197 { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET |
2198 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time) },
Anton Khirnov8fc83fb2012-08-11 15:00:302199 "set the start time offset", "time_off" },
Anton Khirnov811bd072013-06-15 07:59:402200 { "accurate_seek", OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
2201 OPT_INPUT, { .off = OFFSET(accurate_seek) },
2202 "enable/disable accurate seeking with -ss" },
Anton Khirnov9d3009c2013-02-20 07:02:162203 { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET |
2204 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(input_ts_offset) },
Anton Khirnov8fc83fb2012-08-11 15:00:302205 "set the input ts offset", "time_off" },
Anton Khirnov9d3009c2013-02-20 07:02:162206 { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC |
2207 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(ts_scale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302208 "set the input ts scale", "scale" },
Anton Khirnov9d3009c2013-02-20 07:02:162209 { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
Anton Khirnov8fc83fb2012-08-11 15:00:302210 "add metadata", "string=string" },
Anton Khirnov9d3009c2013-02-20 07:02:162211 { "dframes", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2212 OPT_OUTPUT, { .func_arg = opt_data_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302213 "set the number of data frames to record", "number" },
2214 { "benchmark", OPT_BOOL | OPT_EXPERT, { &do_benchmark },
2215 "add timings for benchmarking" },
Anton Khirnov602b1892012-08-15 08:33:362216 { "timelimit", HAS_ARG | OPT_EXPERT, { .func_arg = opt_timelimit },
Anton Khirnov8fc83fb2012-08-11 15:00:302217 "set max runtime in seconds", "limit" },
2218 { "dump", OPT_BOOL | OPT_EXPERT, { &do_pkt_dump },
2219 "dump each input packet" },
2220 { "hex", OPT_BOOL | OPT_EXPERT, { &do_hex_dump },
2221 "when dumping packets, also dump the payload" },
Anton Khirnov9d3009c2013-02-20 07:02:162222 { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2223 OPT_INPUT, { .off = OFFSET(rate_emu) },
Anton Khirnov8fc83fb2012-08-11 15:00:302224 "read input at native frame rate", "" },
Anton Khirnov9d3009c2013-02-20 07:02:162225 { "target", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_target },
Anton Khirnov8fc83fb2012-08-11 15:00:302226 "specify target file type (\"vcd\", \"svcd\", \"dvd\","
2227 " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
2228 { "vsync", HAS_ARG | OPT_EXPERT, { opt_vsync },
2229 "video sync method", "" },
2230 { "async", HAS_ARG | OPT_INT | OPT_EXPERT, { &audio_sync_method },
2231 "audio sync method", "" },
2232 { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &audio_drift_threshold },
2233 "audio drift threshold", "threshold" },
2234 { "copyts", OPT_BOOL | OPT_EXPERT, { &copy_ts },
2235 "copy timestamps" },
2236 { "copytb", OPT_BOOL | OPT_EXPERT, { &copy_tb },
2237 "copy input stream time base when stream copying" },
Anton Khirnov9d3009c2013-02-20 07:02:162238 { "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2239 OPT_OUTPUT, { .off = OFFSET(shortest) },
Anton Khirnov8fc83fb2012-08-11 15:00:302240 "finish encoding within shortest input" },
2241 { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &dts_delta_threshold },
2242 "timestamp discontinuity delta threshold", "threshold" },
Anton Khirnov602b1892012-08-15 08:33:362243 { "xerror", OPT_BOOL | OPT_EXPERT, { &exit_on_error },
Anton Khirnov8fc83fb2012-08-11 15:00:302244 "exit on error", "error" },
Anton Khirnov9d3009c2013-02-20 07:02:162245 { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2246 OPT_OUTPUT, { .off = OFFSET(copy_initial_nonkeyframes) },
Anton Khirnov8fc83fb2012-08-11 15:00:302247 "copy initial non-keyframes" },
Anton Khirnov9d3009c2013-02-20 07:02:162248 { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
Anton Khirnov8fc83fb2012-08-11 15:00:302249 "set the number of frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162250 { "tag", OPT_STRING | HAS_ARG | OPT_SPEC |
Anton Khirnov746dca42014-02-23 07:05:522251 OPT_EXPERT | OPT_OUTPUT | OPT_INPUT, { .off = OFFSET(codec_tags) },
Anton Khirnov8fc83fb2012-08-11 15:00:302252 "force codec tag/fourcc", "fourcc/tag" },
Anton Khirnov9d3009c2013-02-20 07:02:162253 { "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2254 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302255 "use fixed quality scale (VBR)", "q" },
Anton Khirnov9d3009c2013-02-20 07:02:162256 { "qscale", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2257 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302258 "use fixed quality scale (VBR)", "q" },
Anton Khirnov9d3009c2013-02-20 07:02:162259 { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
Anton Khirnov8fc83fb2012-08-11 15:00:302260 "set stream filterchain", "filter_list" },
Anton Khirnova4208b92013-03-13 13:24:452261 { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) },
2262 "read stream filtergraph description from a file", "filename" },
Anton Khirnov8fc83fb2012-08-11 15:00:302263 { "filter_complex", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex },
2264 "create a complex filtergraph", "graph_description" },
Anton Khirnova4208b92013-03-13 13:24:452265 { "filter_complex_script", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex_script },
2266 "read complex filtergraph description from a file", "filename" },
Anton Khirnov8fc83fb2012-08-11 15:00:302267 { "stats", OPT_BOOL, { &print_stats },
2268 "print progress report during encoding", },
Anton Khirnov9d3009c2013-02-20 07:02:162269 { "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2270 OPT_OUTPUT, { .func_arg = opt_attach },
Anton Khirnov8fc83fb2012-08-11 15:00:302271 "add an attachment to the output file", "filename" },
Anton Khirnov9d3009c2013-02-20 07:02:162272 { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |
2273 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(dump_attachment) },
Anton Khirnov8fc83fb2012-08-11 15:00:302274 "extract an attachment into a file", "filename" },
Anton Khirnovf5e66822012-08-01 16:23:122275
2276 /* video options */
Anton Khirnov9d3009c2013-02-20 07:02:162277 { "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302278 "set the number of video frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162279 { "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2280 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_rates) },
Anton Khirnov8fc83fb2012-08-11 15:00:302281 "set frame rate (Hz value, fraction or abbreviation)", "rate" },
Anton Khirnov9d3009c2013-02-20 07:02:162282 { "s", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2283 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_sizes) },
Anton Khirnov8fc83fb2012-08-11 15:00:302284 "set frame size (WxH or abbreviation)", "size" },
Anton Khirnov9d3009c2013-02-20 07:02:162285 { "aspect", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2286 OPT_OUTPUT, { .off = OFFSET(frame_aspect_ratios) },
Anton Khirnov8fc83fb2012-08-11 15:00:302287 "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
Anton Khirnov9d3009c2013-02-20 07:02:162288 { "pix_fmt", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2289 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_pix_fmts) },
Anton Khirnov8fc83fb2012-08-11 15:00:302290 "set pixel format", "format" },
Anton Khirnov9d3009c2013-02-20 07:02:162291 { "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(video_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302292 "disable video" },
2293 { "vdt", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &video_discard },
2294 "discard threshold", "n" },
Anton Khirnov9d3009c2013-02-20 07:02:162295 { "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2296 OPT_OUTPUT, { .off = OFFSET(rc_overrides) },
Anton Khirnov8fc83fb2012-08-11 15:00:302297 "rate control override for specific intervals", "override" },
Anton Khirnov9d3009c2013-02-20 07:02:162298 { "vcodec", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_INPUT |
2299 OPT_OUTPUT, { .func_arg = opt_video_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302300 "force video codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162301 { "pass", OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT | OPT_OUTPUT, { .off = OFFSET(pass) },
Anton Khirnov8fc83fb2012-08-11 15:00:302302 "select the pass number (1 or 2)", "n" },
Anton Khirnov9d3009c2013-02-20 07:02:162303 { "passlogfile", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
2304 OPT_OUTPUT, { .off = OFFSET(passlogfiles) },
Anton Khirnov8fc83fb2012-08-11 15:00:302305 "select two pass log file name prefix", "prefix" },
Anton Khirnov8fc83fb2012-08-11 15:00:302306 { "vstats", OPT_VIDEO | OPT_EXPERT , { &opt_vstats },
2307 "dump video coding statistics to file" },
2308 { "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { opt_vstats_file },
2309 "dump video coding statistics to file", "file" },
Anton Khirnov9d3009c2013-02-20 07:02:162310 { "vf", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_filters },
Anton Khirnov8fc83fb2012-08-11 15:00:302311 "video filters", "filter list" },
Anton Khirnov9d3009c2013-02-20 07:02:162312 { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2313 OPT_OUTPUT, { .off = OFFSET(intra_matrices) },
Anton Khirnov8fc83fb2012-08-11 15:00:302314 "specify intra matrix coeffs", "matrix" },
Anton Khirnov9d3009c2013-02-20 07:02:162315 { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2316 OPT_OUTPUT, { .off = OFFSET(inter_matrices) },
Anton Khirnov8fc83fb2012-08-11 15:00:302317 "specify inter matrix coeffs", "matrix" },
Anton Khirnov9d3009c2013-02-20 07:02:162318 { "top", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_INT| OPT_SPEC |
2319 OPT_OUTPUT, { .off = OFFSET(top_field_first) },
Anton Khirnov8fc83fb2012-08-11 15:00:302320 "top=1/bottom=0/auto=-1 field first", "" },
2321 { "dc", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &intra_dc_precision },
2322 "intra_dc_precision", "precision" },
Anton Khirnov9d3009c2013-02-20 07:02:162323 { "vtag", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2324 OPT_OUTPUT, { .func_arg = opt_video_tag },
Anton Khirnov8fc83fb2012-08-11 15:00:302325 "force video tag/fourcc", "fourcc/tag" },
2326 { "qphist", OPT_VIDEO | OPT_BOOL | OPT_EXPERT , { &qp_hist },
2327 "show QP histogram" },
Anton Khirnov9d3009c2013-02-20 07:02:162328 { "force_fps", OPT_VIDEO | OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2329 OPT_OUTPUT, { .off = OFFSET(force_fps) },
Anton Khirnov8fc83fb2012-08-11 15:00:302330 "force the selected framerate, disable the best supported framerate selection" },
Anton Khirnov9d3009c2013-02-20 07:02:162331 { "streamid", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2332 OPT_OUTPUT, { .func_arg = opt_streamid },
Anton Khirnov8fc83fb2012-08-11 15:00:302333 "set the value of an outfile streamid", "streamIndex:value" },
Anton Khirnov9d3009c2013-02-20 07:02:162334 { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2335 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(forced_key_frames) },
2336 "force key frames at specified timestamps", "timestamps" },
Anton Khirnov07fd0a22013-11-02 21:06:362337 { "hwaccel", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2338 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccels) },
2339 "use HW accelerated decoding", "hwaccel name" },
2340 { "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2341 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) },
2342 "select a device for HW acceleration" "devicename" },
Anton Khirnovf5e66822012-08-01 16:23:122343
2344 /* audio options */
Anton Khirnov9d3009c2013-02-20 07:02:162345 { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302346 "set the number of audio frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162347 { "aq", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_qscale },
Anton Khirnov8fc83fb2012-08-11 15:00:302348 "set audio quality (codec-specific)", "quality", },
Anton Khirnov9d3009c2013-02-20 07:02:162349 { "ar", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2350 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_sample_rate) },
Anton Khirnov8fc83fb2012-08-11 15:00:302351 "set audio sampling rate (in Hz)", "rate" },
Anton Khirnov9d3009c2013-02-20 07:02:162352 { "ac", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2353 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_channels) },
Anton Khirnov8fc83fb2012-08-11 15:00:302354 "set number of audio channels", "channels" },
Anton Khirnov9d3009c2013-02-20 07:02:162355 { "an", OPT_AUDIO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(audio_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302356 "disable audio" },
Anton Khirnov9d3009c2013-02-20 07:02:162357 { "acodec", OPT_AUDIO | HAS_ARG | OPT_PERFILE |
2358 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_audio_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302359 "force audio codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162360 { "atag", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2361 OPT_OUTPUT, { .func_arg = opt_audio_tag },
Anton Khirnov8fc83fb2012-08-11 15:00:302362 "force audio tag/fourcc", "fourcc/tag" },
2363 { "vol", OPT_AUDIO | HAS_ARG | OPT_INT, { &audio_volume },
2364 "change audio volume (256=normal)" , "volume" },
Anton Khirnov9d3009c2013-02-20 07:02:162365 { "sample_fmt", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_SPEC |
2366 OPT_STRING | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(sample_fmts) },
Anton Khirnov8fc83fb2012-08-11 15:00:302367 "set sample format", "format" },
Anton Khirnov9d3009c2013-02-20 07:02:162368 { "channel_layout", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2369 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_channel_layout },
Anton Khirnov8fc83fb2012-08-11 15:00:302370 "set channel layout", "layout" },
Anton Khirnov9d3009c2013-02-20 07:02:162371 { "af", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_filters },
Anton Khirnov8fc83fb2012-08-11 15:00:302372 "audio filters", "filter list" },
Anton Khirnovf5e66822012-08-01 16:23:122373
2374 /* subtitle options */
Anton Khirnov9d3009c2013-02-20 07:02:162375 { "sn", OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(subtitle_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302376 "disable subtitle" },
Anton Khirnov9d3009c2013-02-20 07:02:162377 { "scodec", OPT_SUBTITLE | HAS_ARG | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_subtitle_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302378 "force subtitle codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162379 { "stag", OPT_SUBTITLE | HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_subtitle_tag }
Anton Khirnov8fc83fb2012-08-11 15:00:302380 , "force subtitle tag/fourcc", "fourcc/tag" },
Anton Khirnovf5e66822012-08-01 16:23:122381
2382 /* grab options */
Anton Khirnov79600a82012-08-11 17:19:532383 { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
Anton Khirnovf5e66822012-08-01 16:23:122384
2385 /* muxer options */
Anton Khirnov9d3009c2013-02-20 07:02:162386 { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_max_delay) },
Anton Khirnov8fc83fb2012-08-11 15:00:302387 "set the maximum demux-decode delay", "seconds" },
Anton Khirnov9d3009c2013-02-20 07:02:162388 { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
Anton Khirnov8fc83fb2012-08-11 15:00:302389 "set the initial demux-decode delay", "seconds" },
Anton Khirnovf5e66822012-08-01 16:23:122390
Anton Khirnov9d3009c2013-02-20 07:02:162391 { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
Anton Khirnov8fc83fb2012-08-11 15:00:302392 "A comma-separated list of bitstream filters", "bitstream_filters" },
Anton Khirnovf5e66822012-08-01 16:23:122393
2394 /* data codec support */
Anton Khirnov9d3009c2013-02-20 07:02:162395 { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302396 "force data codec ('copy' to copy stream)", "codec" },
Anton Khirnovf5e66822012-08-01 16:23:122397
Anton Khirnovf5e66822012-08-01 16:23:122398 { NULL, },
2399};