blob: f400e75cd706ea255dab2da165a51604d730cdcb [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 Khirnova61c2112014-04-28 21:00:3860#if HAVE_DXVA2_LIB
Hendrik Leppkes35177ba2014-04-22 13:22:5361 { "dxva2", dxva2_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD },
62#endif
Anton Khirnov07fd0a22013-11-02 21:06:3663 { 0 },
64};
65
Anton Khirnovf5e66822012-08-01 16:23:1266char *vstats_filename;
67
68float audio_drift_threshold = 0.1;
69float dts_delta_threshold = 10;
70
71int audio_volume = 256;
72int audio_sync_method = 0;
73int video_sync_method = VSYNC_AUTO;
Anton Khirnovf5e66822012-08-01 16:23:1274int do_benchmark = 0;
75int do_hex_dump = 0;
76int do_pkt_dump = 0;
77int copy_ts = 0;
78int copy_tb = 1;
Anton Khirnovf5e66822012-08-01 16:23:1279int exit_on_error = 0;
80int print_stats = 1;
81int qp_hist = 0;
Anton Khirnovf5e66822012-08-01 16:23:1282
83static int file_overwrite = 0;
Vittorio Giovara7748dd42013-07-31 12:48:4984static int file_skip = 0;
Anton Khirnovf5e66822012-08-01 16:23:1285static int video_discard = 0;
86static int intra_dc_precision = 8;
Anton Khirnovf5e66822012-08-01 16:23:1287static int using_stdin = 0;
88static int input_sync;
89
Anton Khirnov77bd1bc2012-06-08 19:35:1690static void uninit_options(OptionsContext *o)
Anton Khirnovf5e66822012-08-01 16:23:1291{
92 const OptionDef *po = options;
93 int i;
94
95 /* all OPT_SPEC and OPT_STRING can be freed in generic way */
96 while (po->name) {
97 void *dst = (uint8_t*)o + po->u.off;
98
99 if (po->flags & OPT_SPEC) {
100 SpecifierOpt **so = dst;
101 int i, *count = (int*)(so + 1);
102 for (i = 0; i < *count; i++) {
103 av_freep(&(*so)[i].specifier);
104 if (po->flags & OPT_STRING)
105 av_freep(&(*so)[i].u.str);
106 }
107 av_freep(so);
108 *count = 0;
109 } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
110 av_freep(dst);
111 po++;
112 }
113
114 for (i = 0; i < o->nb_stream_maps; i++)
115 av_freep(&o->stream_maps[i].linklabel);
116 av_freep(&o->stream_maps);
117 av_freep(&o->meta_data_maps);
118 av_freep(&o->streamid_map);
Anton Khirnov77bd1bc2012-06-08 19:35:16119}
Anton Khirnovf5e66822012-08-01 16:23:12120
Anton Khirnov77bd1bc2012-06-08 19:35:16121static void init_options(OptionsContext *o)
122{
Anton Khirnovf5e66822012-08-01 16:23:12123 memset(o, 0, sizeof(*o));
124
125 o->mux_max_delay = 0.7;
Anton Khirnov56ee3f92013-06-15 07:35:10126 o->start_time = AV_NOPTS_VALUE;
Anton Khirnovf5e66822012-08-01 16:23:12127 o->recording_time = INT64_MAX;
128 o->limit_filesize = UINT64_MAX;
129 o->chapters_input_file = INT_MAX;
Anton Khirnov811bd072013-06-15 07:59:40130 o->accurate_seek = 1;
Anton Khirnovf5e66822012-08-01 16:23:12131}
132
Anton Khirnove7553f42013-02-21 09:58:46133/* return a copy of the input with the stream specifiers removed from the keys */
134static AVDictionary *strip_specifiers(AVDictionary *dict)
135{
136 AVDictionaryEntry *e = NULL;
137 AVDictionary *ret = NULL;
138
139 while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
140 char *p = strchr(e->key, ':');
141
142 if (p)
143 *p = 0;
144 av_dict_set(&ret, e->key, e->value, 0);
145 if (p)
146 *p = ':';
147 }
148 return ret;
149}
150
Anton Khirnovf5e66822012-08-01 16:23:12151static double parse_frame_aspect_ratio(const char *arg)
152{
153 int x = 0, y = 0;
154 double ar = 0;
155 const char *p;
156 char *end;
157
158 p = strchr(arg, ':');
159 if (p) {
160 x = strtol(arg, &end, 10);
161 if (end == p)
162 y = strtol(end + 1, &end, 10);
163 if (x > 0 && y > 0)
164 ar = (double)x / (double)y;
165 } else
166 ar = strtod(arg, NULL);
167
168 if (!ar) {
169 av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17170 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12171 }
172 return ar;
173}
174
Anton Khirnovd3810c42012-08-11 14:30:26175static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12176{
Anton Khirnovd3810c42012-08-11 14:30:26177 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12178 return parse_option(o, "codec:a", arg, options);
179}
180
Anton Khirnovd3810c42012-08-11 14:30:26181static int opt_video_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12182{
Anton Khirnovd3810c42012-08-11 14:30:26183 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12184 return parse_option(o, "codec:v", arg, options);
185}
186
Anton Khirnovd3810c42012-08-11 14:30:26187static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12188{
Anton Khirnovd3810c42012-08-11 14:30:26189 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12190 return parse_option(o, "codec:s", arg, options);
191}
192
Anton Khirnovd3810c42012-08-11 14:30:26193static int opt_data_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12194{
Anton Khirnovd3810c42012-08-11 14:30:26195 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12196 return parse_option(o, "codec:d", arg, options);
197}
198
Anton Khirnovd3810c42012-08-11 14:30:26199static int opt_map(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12200{
Anton Khirnovd3810c42012-08-11 14:30:26201 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12202 StreamMap *m = NULL;
203 int i, negative = 0, file_idx;
204 int sync_file_idx = -1, sync_stream_idx;
205 char *p, *sync;
206 char *map;
207
208 if (*arg == '-') {
209 negative = 1;
210 arg++;
211 }
212 map = av_strdup(arg);
213
214 /* parse sync stream first, just pick first matching stream */
215 if (sync = strchr(map, ',')) {
216 *sync = 0;
217 sync_file_idx = strtol(sync + 1, &sync, 0);
218 if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
219 av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
Martin Storsjöb85dbe62013-07-31 10:44:17220 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12221 }
222 if (*sync)
223 sync++;
224 for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
225 if (check_stream_specifier(input_files[sync_file_idx]->ctx,
226 input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
227 sync_stream_idx = i;
228 break;
229 }
230 if (i == input_files[sync_file_idx]->nb_streams) {
231 av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
232 "match any streams.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17233 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12234 }
235 }
236
237
238 if (map[0] == '[') {
239 /* this mapping refers to lavfi output */
240 const char *c = map + 1;
Anton Khirnov10bca662012-06-07 19:52:07241 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
Anton Khirnovf5e66822012-08-01 16:23:12242 m = &o->stream_maps[o->nb_stream_maps - 1];
243 m->linklabel = av_get_token(&c, "]");
244 if (!m->linklabel) {
245 av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
Martin Storsjöb85dbe62013-07-31 10:44:17246 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12247 }
248 } else {
249 file_idx = strtol(map, &p, 0);
250 if (file_idx >= nb_input_files || file_idx < 0) {
251 av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
Martin Storsjöb85dbe62013-07-31 10:44:17252 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12253 }
254 if (negative)
255 /* disable some already defined maps */
256 for (i = 0; i < o->nb_stream_maps; i++) {
257 m = &o->stream_maps[i];
258 if (file_idx == m->file_index &&
259 check_stream_specifier(input_files[m->file_index]->ctx,
260 input_files[m->file_index]->ctx->streams[m->stream_index],
261 *p == ':' ? p + 1 : p) > 0)
262 m->disabled = 1;
263 }
264 else
265 for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
266 if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
267 *p == ':' ? p + 1 : p) <= 0)
268 continue;
Anton Khirnov10bca662012-06-07 19:52:07269 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
Anton Khirnovf5e66822012-08-01 16:23:12270 m = &o->stream_maps[o->nb_stream_maps - 1];
271
272 m->file_index = file_idx;
273 m->stream_index = i;
274
275 if (sync_file_idx >= 0) {
276 m->sync_file_index = sync_file_idx;
277 m->sync_stream_index = sync_stream_idx;
278 } else {
279 m->sync_file_index = file_idx;
280 m->sync_stream_index = i;
281 }
282 }
283 }
284
285 if (!m) {
286 av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17287 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12288 }
289
290 av_freep(&map);
291 return 0;
292}
293
Anton Khirnovd3810c42012-08-11 14:30:26294static int opt_attach(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12295{
Anton Khirnovd3810c42012-08-11 14:30:26296 OptionsContext *o = optctx;
Anton Khirnov10bca662012-06-07 19:52:07297 GROW_ARRAY(o->attachments, o->nb_attachments);
Anton Khirnovf5e66822012-08-01 16:23:12298 o->attachments[o->nb_attachments - 1] = arg;
299 return 0;
300}
301
302/**
Diego Biurrunc1ef30a2012-08-24 11:31:50303 * Parse a metadata specifier passed as 'arg' parameter.
Diego Biurrun02e42752012-10-24 17:20:13304 * @param arg metadata string to parse
Anton Khirnovf5e66822012-08-01 16:23:12305 * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
306 * @param index for type c/p, chapter/program index is written here
307 * @param stream_spec for type s, the stream specifier is written here
308 */
309static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
310{
311 if (*arg) {
312 *type = *arg;
313 switch (*arg) {
314 case 'g':
315 break;
316 case 's':
317 if (*(++arg) && *arg != ':') {
318 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17319 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12320 }
321 *stream_spec = *arg == ':' ? arg + 1 : "";
322 break;
323 case 'c':
324 case 'p':
325 if (*(++arg) == ':')
326 *index = strtol(++arg, NULL, 0);
327 break;
328 default:
329 av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
Martin Storsjöb85dbe62013-07-31 10:44:17330 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12331 }
332 } else
333 *type = 'g';
334}
335
336static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
337{
338 AVDictionary **meta_in = NULL;
339 AVDictionary **meta_out;
340 int i, ret = 0;
341 char type_in, type_out;
342 const char *istream_spec = NULL, *ostream_spec = NULL;
343 int idx_in = 0, idx_out = 0;
344
345 parse_meta_type(inspec, &type_in, &idx_in, &istream_spec);
346 parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
347
348 if (type_in == 'g' || type_out == 'g')
349 o->metadata_global_manual = 1;
350 if (type_in == 's' || type_out == 's')
351 o->metadata_streams_manual = 1;
352 if (type_in == 'c' || type_out == 'c')
353 o->metadata_chapters_manual = 1;
354
Anton Khirnova119c642012-10-16 07:53:39355 /* ic is NULL when just disabling automatic mappings */
356 if (!ic)
357 return 0;
358
Anton Khirnovf5e66822012-08-01 16:23:12359#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
360 if ((index) < 0 || (index) >= (nb_elems)) {\
361 av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
362 (desc), (index));\
Martin Storsjöb85dbe62013-07-31 10:44:17363 exit_program(1);\
Anton Khirnovf5e66822012-08-01 16:23:12364 }
365
366#define SET_DICT(type, meta, context, index)\
367 switch (type) {\
368 case 'g':\
369 meta = &context->metadata;\
370 break;\
371 case 'c':\
372 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
373 meta = &context->chapters[index]->metadata;\
374 break;\
375 case 'p':\
376 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
377 meta = &context->programs[index]->metadata;\
378 break;\
Anton Khirnov4632abc2012-11-24 06:55:42379 case 's':\
380 break; /* handled separately below */ \
Anton Khirnovf5e66822012-08-01 16:23:12381 default: av_assert0(0);\
382 }\
383
384 SET_DICT(type_in, meta_in, ic, idx_in);
385 SET_DICT(type_out, meta_out, oc, idx_out);
386
387 /* for input streams choose first matching stream */
388 if (type_in == 's') {
389 for (i = 0; i < ic->nb_streams; i++) {
390 if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
391 meta_in = &ic->streams[i]->metadata;
392 break;
393 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:17394 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12395 }
396 if (!meta_in) {
397 av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
Martin Storsjöb85dbe62013-07-31 10:44:17398 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12399 }
400 }
401
402 if (type_out == 's') {
403 for (i = 0; i < oc->nb_streams; i++) {
404 if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
405 meta_out = &oc->streams[i]->metadata;
406 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
407 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:17408 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12409 }
410 } else
411 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
412
413 return 0;
414}
415
416static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
417{
Anton Khirnovdb4766a2012-08-11 13:40:12418 const AVCodecDescriptor *desc;
Anton Khirnovf5e66822012-08-01 16:23:12419 const char *codec_string = encoder ? "encoder" : "decoder";
420 AVCodec *codec;
421
422 codec = encoder ?
423 avcodec_find_encoder_by_name(name) :
424 avcodec_find_decoder_by_name(name);
Anton Khirnovdb4766a2012-08-11 13:40:12425
426 if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
427 codec = encoder ? avcodec_find_encoder(desc->id) :
428 avcodec_find_decoder(desc->id);
429 if (codec)
430 av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
431 codec_string, codec->name, desc->name);
432 }
433
Anton Khirnovf5e66822012-08-01 16:23:12434 if (!codec) {
435 av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
Martin Storsjöb85dbe62013-07-31 10:44:17436 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12437 }
438 if (codec->type != type) {
439 av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
Martin Storsjöb85dbe62013-07-31 10:44:17440 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12441 }
442 return codec;
443}
444
445static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
446{
447 char *codec_name = NULL;
448
449 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
450 if (codec_name) {
451 AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
452 st->codec->codec_id = codec->id;
453 return codec;
454 } else
455 return avcodec_find_decoder(st->codec->codec_id);
456}
457
Diego Biurrunc1ef30a2012-08-24 11:31:50458/* Add all the streams from the given input file to the global
459 * list of input streams. */
Anton Khirnovf5e66822012-08-01 16:23:12460static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
461{
462 int i;
463
464 for (i = 0; i < ic->nb_streams; i++) {
465 AVStream *st = ic->streams[i];
466 AVCodecContext *dec = st->codec;
467 InputStream *ist = av_mallocz(sizeof(*ist));
Anton Khirnov07fd0a22013-11-02 21:06:36468 char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
Anton Khirnov746dca42014-02-23 07:05:52469 char *codec_tag = NULL;
470 char *next;
Anton Khirnovf5e66822012-08-01 16:23:12471
472 if (!ist)
Martin Storsjöb85dbe62013-07-31 10:44:17473 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12474
Anton Khirnov10bca662012-06-07 19:52:07475 GROW_ARRAY(input_streams, nb_input_streams);
Anton Khirnovf5e66822012-08-01 16:23:12476 input_streams[nb_input_streams - 1] = ist;
477
478 ist->st = st;
479 ist->file_index = nb_input_files;
480 ist->discard = 1;
481 st->discard = AVDISCARD_ALL;
Anton Khirnovf5e66822012-08-01 16:23:12482
483 ist->ts_scale = 1.0;
484 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
485
Anton Khirnov746dca42014-02-23 07:05:52486 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
487 if (codec_tag) {
488 uint32_t tag = strtol(codec_tag, &next, 0);
489 if (*next)
490 tag = AV_RL32(codec_tag);
491 st->codec->codec_tag = tag;
492 }
493
Anton Khirnovf5e66822012-08-01 16:23:12494 ist->dec = choose_decoder(o, ic, st);
Anton Khirnovf3a6ad22014-04-04 17:38:04495 ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, ist->dec);
Anton Khirnovf5e66822012-08-01 16:23:12496
497 switch (dec->codec_type) {
498 case AVMEDIA_TYPE_VIDEO:
499 ist->resample_height = dec->height;
500 ist->resample_width = dec->width;
501 ist->resample_pix_fmt = dec->pix_fmt;
502
503 MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
504 if (framerate && av_parse_video_rate(&ist->framerate,
505 framerate) < 0) {
506 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
507 framerate);
Martin Storsjöb85dbe62013-07-31 10:44:17508 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12509 }
510
Anton Khirnov07fd0a22013-11-02 21:06:36511 MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
512 if (hwaccel) {
513 if (!strcmp(hwaccel, "none"))
514 ist->hwaccel_id = HWACCEL_NONE;
515 else if (!strcmp(hwaccel, "auto"))
516 ist->hwaccel_id = HWACCEL_AUTO;
517 else {
518 int i;
519 for (i = 0; hwaccels[i].name; i++) {
520 if (!strcmp(hwaccels[i].name, hwaccel)) {
521 ist->hwaccel_id = hwaccels[i].id;
522 break;
523 }
524 }
525
526 if (!ist->hwaccel_id) {
527 av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
528 hwaccel);
529 av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
530 for (i = 0; hwaccels[i].name; i++)
531 av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
532 av_log(NULL, AV_LOG_FATAL, "\n");
533 exit_program(1);
534 }
535 }
536 }
537
538 MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
539 if (hwaccel_device) {
540 ist->hwaccel_device = av_strdup(hwaccel_device);
541 if (!ist->hwaccel_device)
542 exit_program(1);
543 }
Anton Khirnovc255f0b2013-11-23 13:07:48544 ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
Anton Khirnov07fd0a22013-11-02 21:06:36545
Anton Khirnovf5e66822012-08-01 16:23:12546 break;
547 case AVMEDIA_TYPE_AUDIO:
548 guess_input_channel_layout(ist);
549
550 ist->resample_sample_fmt = dec->sample_fmt;
551 ist->resample_sample_rate = dec->sample_rate;
552 ist->resample_channels = dec->channels;
553 ist->resample_channel_layout = dec->channel_layout;
554
555 break;
556 case AVMEDIA_TYPE_DATA:
557 case AVMEDIA_TYPE_SUBTITLE:
558 case AVMEDIA_TYPE_ATTACHMENT:
559 case AVMEDIA_TYPE_UNKNOWN:
560 break;
561 default:
562 abort();
563 }
564 }
565}
566
567static void assert_file_overwrite(const char *filename)
568{
Vittorio Giovara7748dd42013-07-31 12:48:49569 if (file_overwrite && file_skip) {
570 fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
571 exit_program(1);
572 }
573
Anton Khirnovf5e66822012-08-01 16:23:12574 if (!file_overwrite &&
575 (strchr(filename, ':') == NULL || filename[1] == ':' ||
576 av_strstart(filename, "file:", NULL))) {
577 if (avio_check(filename, 0) == 0) {
Vittorio Giovara7748dd42013-07-31 12:48:49578 if (!using_stdin && !file_skip) {
Anton Khirnovf5e66822012-08-01 16:23:12579 fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
580 fflush(stderr);
581 if (!read_yesno()) {
582 fprintf(stderr, "Not overwriting - exiting\n");
Martin Storsjöb85dbe62013-07-31 10:44:17583 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12584 }
585 }
586 else {
587 fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
Martin Storsjöb85dbe62013-07-31 10:44:17588 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12589 }
590 }
591 }
592}
593
594static void dump_attachment(AVStream *st, const char *filename)
595{
596 int ret;
597 AVIOContext *out = NULL;
598 AVDictionaryEntry *e;
599
600 if (!st->codec->extradata_size) {
601 av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
602 nb_input_files - 1, st->index);
603 return;
604 }
605 if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
606 filename = e->value;
607 if (!*filename) {
608 av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
609 "in stream #%d:%d.\n", nb_input_files - 1, st->index);
Martin Storsjöb85dbe62013-07-31 10:44:17610 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12611 }
612
613 assert_file_overwrite(filename);
614
615 if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
616 av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
617 filename);
Martin Storsjöb85dbe62013-07-31 10:44:17618 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12619 }
620
621 avio_write(out, st->codec->extradata, st->codec->extradata_size);
622 avio_flush(out);
623 avio_close(out);
624}
625
Anton Khirnov77bd1bc2012-06-08 19:35:16626static int open_input_file(OptionsContext *o, const char *filename)
Anton Khirnovf5e66822012-08-01 16:23:12627{
Anton Khirnov41d20082013-02-21 08:53:28628 InputFile *f;
Anton Khirnovf5e66822012-08-01 16:23:12629 AVFormatContext *ic;
630 AVInputFormat *file_iformat = NULL;
631 int err, i, ret;
632 int64_t timestamp;
633 uint8_t buf[128];
634 AVDictionary **opts;
Anton Khirnove7553f42013-02-21 09:58:46635 AVDictionary *unused_opts = NULL;
636 AVDictionaryEntry *e = NULL;
Anton Khirnovf5e66822012-08-01 16:23:12637 int orig_nb_streams; // number of streams before avformat_find_stream_info
638
639 if (o->format) {
640 if (!(file_iformat = av_find_input_format(o->format))) {
641 av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
Martin Storsjöb85dbe62013-07-31 10:44:17642 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12643 }
644 }
645
646 if (!strcmp(filename, "-"))
647 filename = "pipe:";
648
649 using_stdin |= !strncmp(filename, "pipe:", 5) ||
650 !strcmp(filename, "/dev/stdin");
651
652 /* get default parameters from command line */
653 ic = avformat_alloc_context();
654 if (!ic) {
655 print_error(filename, AVERROR(ENOMEM));
Martin Storsjöb85dbe62013-07-31 10:44:17656 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12657 }
658 if (o->nb_audio_sample_rate) {
659 snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
Anton Khirnov77bd1bc2012-06-08 19:35:16660 av_dict_set(&o->g->format_opts, "sample_rate", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:12661 }
662 if (o->nb_audio_channels) {
663 /* because we set audio_channels based on both the "ac" and
664 * "channel_layout" options, we need to check that the specified
665 * demuxer actually has the "channels" option before setting it */
666 if (file_iformat && file_iformat->priv_class &&
667 av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
668 AV_OPT_SEARCH_FAKE_OBJ)) {
669 snprintf(buf, sizeof(buf), "%d",
670 o->audio_channels[o->nb_audio_channels - 1].u.i);
Anton Khirnov77bd1bc2012-06-08 19:35:16671 av_dict_set(&o->g->format_opts, "channels", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:12672 }
673 }
674 if (o->nb_frame_rates) {
675 /* set the format-level framerate option;
676 * this is important for video grabbers, e.g. x11 */
677 if (file_iformat && file_iformat->priv_class &&
678 av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
679 AV_OPT_SEARCH_FAKE_OBJ)) {
Anton Khirnov77bd1bc2012-06-08 19:35:16680 av_dict_set(&o->g->format_opts, "framerate",
Anton Khirnovf5e66822012-08-01 16:23:12681 o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
682 }
683 }
684 if (o->nb_frame_sizes) {
Anton Khirnov77bd1bc2012-06-08 19:35:16685 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:12686 }
687 if (o->nb_frame_pix_fmts)
Anton Khirnov77bd1bc2012-06-08 19:35:16688 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:12689
690 ic->flags |= AVFMT_FLAG_NONBLOCK;
691 ic->interrupt_callback = int_cb;
692
693 /* open the input file with generic libav function */
Anton Khirnov77bd1bc2012-06-08 19:35:16694 err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
Anton Khirnovf5e66822012-08-01 16:23:12695 if (err < 0) {
696 print_error(filename, err);
Martin Storsjöb85dbe62013-07-31 10:44:17697 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12698 }
Anton Khirnov77bd1bc2012-06-08 19:35:16699 assert_avoptions(o->g->format_opts);
Anton Khirnovf5e66822012-08-01 16:23:12700
701 /* apply forced codec ids */
702 for (i = 0; i < ic->nb_streams; i++)
703 choose_decoder(o, ic, ic->streams[i]);
704
705 /* Set AVCodecContext options for avformat_find_stream_info */
Anton Khirnov77bd1bc2012-06-08 19:35:16706 opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
Anton Khirnovf5e66822012-08-01 16:23:12707 orig_nb_streams = ic->nb_streams;
708
709 /* If not enough info to get the stream parameters, we decode the
710 first frames to get it. (used in mpeg case for example) */
711 ret = avformat_find_stream_info(ic, opts);
712 if (ret < 0) {
713 av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
714 avformat_close_input(&ic);
Martin Storsjöb85dbe62013-07-31 10:44:17715 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12716 }
717
Anton Khirnov56ee3f92013-06-15 07:35:10718 timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
Anton Khirnovf5e66822012-08-01 16:23:12719 /* add the stream start time */
720 if (ic->start_time != AV_NOPTS_VALUE)
721 timestamp += ic->start_time;
722
723 /* if seeking requested, we execute it */
Anton Khirnov56ee3f92013-06-15 07:35:10724 if (o->start_time != AV_NOPTS_VALUE) {
Anton Khirnovf5e66822012-08-01 16:23:12725 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
726 if (ret < 0) {
727 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
728 filename, (double)timestamp / AV_TIME_BASE);
729 }
730 }
731
732 /* update the current parameters so that they match the one of the input stream */
733 add_input_streams(o, ic);
734
735 /* dump the file content */
736 av_dump_format(ic, nb_input_files, filename, 0);
737
Anton Khirnov10bca662012-06-07 19:52:07738 GROW_ARRAY(input_files, nb_input_files);
Anton Khirnov41d20082013-02-21 08:53:28739 f = av_mallocz(sizeof(*f));
740 if (!f)
Martin Storsjöb85dbe62013-07-31 10:44:17741 exit_program(1);
Anton Khirnov41d20082013-02-21 08:53:28742 input_files[nb_input_files - 1] = f;
Anton Khirnovf5e66822012-08-01 16:23:12743
Anton Khirnov41d20082013-02-21 08:53:28744 f->ctx = ic;
745 f->ist_index = nb_input_streams - ic->nb_streams;
Anton Khirnov811bd072013-06-15 07:59:40746 f->start_time = o->start_time;
Anton Khirnov488a0fa2013-06-18 09:12:09747 f->recording_time = o->recording_time;
Anton Khirnov41d20082013-02-21 08:53:28748 f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
749 f->nb_streams = ic->nb_streams;
750 f->rate_emu = o->rate_emu;
Anton Khirnov811bd072013-06-15 07:59:40751 f->accurate_seek = o->accurate_seek;
Anton Khirnovf5e66822012-08-01 16:23:12752
Anton Khirnove7553f42013-02-21 09:58:46753 /* check if all codec options have been used */
754 unused_opts = strip_specifiers(o->g->codec_opts);
755 for (i = f->ist_index; i < nb_input_streams; i++) {
756 e = NULL;
Anton Khirnovf3a6ad22014-04-04 17:38:04757 while ((e = av_dict_get(input_streams[i]->decoder_opts, "", e,
Anton Khirnove7553f42013-02-21 09:58:46758 AV_DICT_IGNORE_SUFFIX)))
759 av_dict_set(&unused_opts, e->key, NULL, 0);
760 }
761
762 e = NULL;
763 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
764 const AVClass *class = avcodec_get_class();
765 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
766 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
767 if (!option)
768 continue;
769 if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
770 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
771 "input file #%d (%s) is not a decoding option.\n", e->key,
772 option->help ? option->help : "", nb_input_files - 1,
773 filename);
Martin Storsjöb85dbe62013-07-31 10:44:17774 exit_program(1);
Anton Khirnove7553f42013-02-21 09:58:46775 }
776
777 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
778 "input file #%d (%s) has not been used for any stream. The most "
779 "likely reason is either wrong type (e.g. a video option with "
780 "no video streams) or that it is a private option of some decoder "
781 "which was not actually used for any stream.\n", e->key,
782 option->help ? option->help : "", nb_input_files - 1, filename);
783 }
784 av_dict_free(&unused_opts);
785
Anton Khirnovf5e66822012-08-01 16:23:12786 for (i = 0; i < o->nb_dump_attachment; i++) {
787 int j;
788
789 for (j = 0; j < ic->nb_streams; j++) {
790 AVStream *st = ic->streams[j];
791
792 if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
793 dump_attachment(st, o->dump_attachment[i].u.str);
794 }
795 }
796
797 for (i = 0; i < orig_nb_streams; i++)
798 av_dict_free(&opts[i]);
799 av_freep(&opts);
800
Anton Khirnovf5e66822012-08-01 16:23:12801 return 0;
802}
803
804static uint8_t *get_line(AVIOContext *s)
805{
806 AVIOContext *line;
807 uint8_t *buf;
808 char c;
809
810 if (avio_open_dyn_buf(&line) < 0) {
811 av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17812 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12813 }
814
815 while ((c = avio_r8(s)) && c != '\n')
816 avio_w8(line, c);
817 avio_w8(line, 0);
818 avio_close_dyn_buf(line, &buf);
819
820 return buf;
821}
822
823static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
824{
Timothy Gu9e4e35b2014-03-29 20:59:45825 int i, ret = -1;
Anton Khirnovf5e66822012-08-01 16:23:12826 char filename[1000];
827 const char *base[3] = { getenv("AVCONV_DATADIR"),
828 getenv("HOME"),
829 AVCONV_DATADIR,
830 };
831
Timothy Gu9e4e35b2014-03-29 20:59:45832 for (i = 0; i < FF_ARRAY_ELEMS(base) && ret < 0; i++) {
Anton Khirnovf5e66822012-08-01 16:23:12833 if (!base[i])
834 continue;
835 if (codec_name) {
836 snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
837 i != 1 ? "" : "/.avconv", codec_name, preset_name);
838 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
839 }
Timothy Gu9e4e35b2014-03-29 20:59:45840 if (ret < 0) {
Anton Khirnovf5e66822012-08-01 16:23:12841 snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
842 i != 1 ? "" : "/.avconv", preset_name);
843 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
844 }
845 }
846 return ret;
847}
848
849static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
850{
851 char *codec_name = NULL;
852
853 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
854 if (!codec_name) {
855 ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
856 NULL, ost->st->codec->codec_type);
857 ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
858 } else if (!strcmp(codec_name, "copy"))
859 ost->stream_copy = 1;
860 else {
861 ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
862 ost->st->codec->codec_id = ost->enc->id;
863 }
864}
865
866static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
867{
868 OutputStream *ost;
869 AVStream *st = avformat_new_stream(oc, NULL);
870 int idx = oc->nb_streams - 1, ret = 0;
871 char *bsf = NULL, *next, *codec_tag = NULL;
872 AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
873 double qscale = -1;
Anton Khirnovf5e66822012-08-01 16:23:12874
875 if (!st) {
876 av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17877 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12878 }
879
880 if (oc->nb_streams - 1 < o->nb_streamid_map)
881 st->id = o->streamid_map[oc->nb_streams - 1];
882
Anton Khirnov10bca662012-06-07 19:52:07883 GROW_ARRAY(output_streams, nb_output_streams);
Anton Khirnovf5e66822012-08-01 16:23:12884 if (!(ost = av_mallocz(sizeof(*ost))))
Martin Storsjöb85dbe62013-07-31 10:44:17885 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12886 output_streams[nb_output_streams - 1] = ost;
887
Anton Khirnov3d624422013-04-10 12:46:20888 ost->file_index = nb_output_files - 1;
Anton Khirnovf5e66822012-08-01 16:23:12889 ost->index = idx;
890 ost->st = st;
891 st->codec->codec_type = type;
892 choose_encoder(o, oc, ost);
893 if (ost->enc) {
Anton Khirnov4e61a382012-10-22 20:40:22894 AVIOContext *s = NULL;
895 char *buf = NULL, *arg = NULL, *preset = NULL;
896
Anton Khirnov95808182014-04-04 17:38:04897 ost->encoder_opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
Anton Khirnov4e61a382012-10-22 20:40:22898
899 MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
900 if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
901 do {
902 buf = get_line(s);
903 if (!buf[0] || buf[0] == '#') {
904 av_free(buf);
905 continue;
906 }
907 if (!(arg = strchr(buf, '='))) {
908 av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17909 exit_program(1);
Anton Khirnov4e61a382012-10-22 20:40:22910 }
911 *arg++ = 0;
Anton Khirnov95808182014-04-04 17:38:04912 av_dict_set(&ost->encoder_opts, buf, arg, AV_DICT_DONT_OVERWRITE);
Anton Khirnov4e61a382012-10-22 20:40:22913 av_free(buf);
914 } while (!s->eof_reached);
915 avio_close(s);
916 }
917 if (ret) {
918 av_log(NULL, AV_LOG_FATAL,
919 "Preset %s specified for stream %d:%d, but could not be opened.\n",
920 preset, ost->file_index, ost->index);
Martin Storsjöb85dbe62013-07-31 10:44:17921 exit_program(1);
Anton Khirnov4e61a382012-10-22 20:40:22922 }
Martin Storsjödf0229a2013-02-27 21:22:39923 } else {
Anton Khirnov95808182014-04-04 17:38:04924 ost->encoder_opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
Anton Khirnovf5e66822012-08-01 16:23:12925 }
926
927 avcodec_get_context_defaults3(st->codec, ost->enc);
928 st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
929
Anton Khirnovf5e66822012-08-01 16:23:12930 ost->max_frames = INT64_MAX;
931 MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
932
933 MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
934 while (bsf) {
935 if (next = strchr(bsf, ','))
936 *next++ = 0;
937 if (!(bsfc = av_bitstream_filter_init(bsf))) {
938 av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
Martin Storsjöb85dbe62013-07-31 10:44:17939 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12940 }
941 if (bsfc_prev)
942 bsfc_prev->next = bsfc;
943 else
944 ost->bitstream_filters = bsfc;
945
946 bsfc_prev = bsfc;
947 bsf = next;
948 }
949
950 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
951 if (codec_tag) {
952 uint32_t tag = strtol(codec_tag, &next, 0);
953 if (*next)
954 tag = AV_RL32(codec_tag);
955 st->codec->codec_tag = tag;
956 }
957
958 MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
Anton Khirnovfb722a92012-10-09 15:40:20959 if (qscale >= 0) {
Anton Khirnovf5e66822012-08-01 16:23:12960 st->codec->flags |= CODEC_FLAG_QSCALE;
961 st->codec->global_quality = FF_QP2LAMBDA * qscale;
962 }
963
964 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
965 st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
966
Anton Khirnov77bd1bc2012-06-08 19:35:16967 av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
Anton Khirnovf5e66822012-08-01 16:23:12968
Justin Ruggles5c7db092012-12-19 02:47:28969 av_dict_copy(&ost->resample_opts, o->g->resample_opts, 0);
970
Anton Khirnov716d4132012-10-06 10:10:34971 ost->pix_fmts[0] = ost->pix_fmts[1] = AV_PIX_FMT_NONE;
Anton Khirnov76d23f42013-04-24 06:34:44972 ost->last_mux_dts = AV_NOPTS_VALUE;
Anton Khirnovf5e66822012-08-01 16:23:12973
974 return ost;
975}
976
977static void parse_matrix_coeffs(uint16_t *dest, const char *str)
978{
979 int i;
980 const char *p = str;
981 for (i = 0;; i++) {
982 dest[i] = atoi(p);
983 if (i == 63)
984 break;
985 p = strchr(p, ',');
986 if (!p) {
987 av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
Martin Storsjöb85dbe62013-07-31 10:44:17988 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12989 }
990 p++;
991 }
992}
993
Anton Khirnova4208b92013-03-13 13:24:45994/* read file contents into a string */
995static uint8_t *read_file(const char *filename)
996{
997 AVIOContext *pb = NULL;
998 AVIOContext *dyn_buf = NULL;
999 int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
1000 uint8_t buf[1024], *str;
1001
1002 if (ret < 0) {
1003 av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
1004 return NULL;
1005 }
1006
1007 ret = avio_open_dyn_buf(&dyn_buf);
1008 if (ret < 0) {
1009 avio_closep(&pb);
1010 return NULL;
1011 }
1012 while ((ret = avio_read(pb, buf, sizeof(buf))) > 0)
1013 avio_write(dyn_buf, buf, ret);
1014 avio_w8(dyn_buf, 0);
1015 avio_closep(&pb);
1016
1017 ret = avio_close_dyn_buf(dyn_buf, &str);
1018 if (ret < 0)
1019 return NULL;
1020 return str;
1021}
1022
1023static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
1024 OutputStream *ost)
1025{
1026 AVStream *st = ost->st;
1027 char *filter = NULL, *filter_script = NULL;
1028
1029 MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
1030 MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
1031
1032 if (filter_script && filter) {
1033 av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
1034 "output stream #%d:%d.\n", nb_output_files, st->index);
Martin Storsjöb85dbe62013-07-31 10:44:171035 exit_program(1);
Anton Khirnova4208b92013-03-13 13:24:451036 }
1037
1038 if (filter_script)
1039 return read_file(filter_script);
1040 else if (filter)
1041 return av_strdup(filter);
1042
1043 return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
1044 "null" : "anull");
1045}
1046
Anton Khirnovf5e66822012-08-01 16:23:121047static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
1048{
1049 AVStream *st;
1050 OutputStream *ost;
1051 AVCodecContext *video_enc;
Anton Khirnov538bf762013-05-26 13:31:091052 char *frame_aspect_ratio = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121053
1054 ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
1055 st = ost->st;
1056 video_enc = st->codec;
1057
Anton Khirnov538bf762013-05-26 13:31:091058 MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
1059 if (frame_aspect_ratio)
1060 ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio);
1061
Anton Khirnovf5e66822012-08-01 16:23:121062 if (!ost->stream_copy) {
1063 const char *p = NULL;
1064 char *frame_rate = NULL, *frame_size = NULL;
Anton Khirnov538bf762013-05-26 13:31:091065 char *frame_pix_fmt = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121066 char *intra_matrix = NULL, *inter_matrix = NULL;
Anton Khirnov038c0b12012-08-19 06:29:441067 int do_pass = 0;
Anton Khirnovf5e66822012-08-01 16:23:121068 int i;
1069
1070 MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
1071 if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
1072 av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
Martin Storsjöb85dbe62013-07-31 10:44:171073 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121074 }
1075
1076 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
1077 if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
1078 av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
Martin Storsjöb85dbe62013-07-31 10:44:171079 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121080 }
1081
Anton Khirnovf5e66822012-08-01 16:23:121082 MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
Anton Khirnov716d4132012-10-06 10:10:341083 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:121084 av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
Martin Storsjöb85dbe62013-07-31 10:44:171085 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121086 }
1087 st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
1088
1089 MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
1090 if (intra_matrix) {
1091 if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
1092 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171093 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121094 }
1095 parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
1096 }
1097 MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
1098 if (inter_matrix) {
1099 if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
1100 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171101 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121102 }
1103 parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
1104 }
1105
1106 MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
1107 for (i = 0; p; i++) {
1108 int start, end, q;
1109 int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
1110 if (e != 3) {
1111 av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
Martin Storsjöb85dbe62013-07-31 10:44:171112 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121113 }
1114 video_enc->rc_override =
1115 av_realloc(video_enc->rc_override,
1116 sizeof(RcOverride) * (i + 1));
1117 video_enc->rc_override[i].start_frame = start;
1118 video_enc->rc_override[i].end_frame = end;
1119 if (q > 0) {
1120 video_enc->rc_override[i].qscale = q;
1121 video_enc->rc_override[i].quality_factor = 1.0;
1122 }
1123 else {
1124 video_enc->rc_override[i].qscale = 0;
1125 video_enc->rc_override[i].quality_factor = -q/100.0;
1126 }
1127 p = strchr(p, '/');
1128 if (p) p++;
1129 }
1130 video_enc->rc_override_count = i;
Anton Khirnovf5e66822012-08-01 16:23:121131 video_enc->intra_dc_precision = intra_dc_precision - 8;
1132
1133 /* two pass mode */
Anton Khirnov038c0b12012-08-19 06:29:441134 MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
Anton Khirnovf5e66822012-08-01 16:23:121135 if (do_pass) {
1136 if (do_pass == 1) {
1137 video_enc->flags |= CODEC_FLAG_PASS1;
1138 } else {
1139 video_enc->flags |= CODEC_FLAG_PASS2;
1140 }
1141 }
1142
Anton Khirnovbbcedad2012-08-19 07:15:481143 MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
1144 if (ost->logfile_prefix &&
1145 !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
Martin Storsjöb85dbe62013-07-31 10:44:171146 exit_program(1);
Anton Khirnovbbcedad2012-08-19 07:15:481147
Anton Khirnovf5e66822012-08-01 16:23:121148 MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
1149 if (ost->forced_keyframes)
1150 ost->forced_keyframes = av_strdup(ost->forced_keyframes);
1151
1152 MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
1153
1154 ost->top_field_first = -1;
1155 MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
1156
Anton Khirnova4208b92013-03-13 13:24:451157
1158 ost->avfilter = get_ost_filters(o, oc, ost);
1159 if (!ost->avfilter)
Martin Storsjöb85dbe62013-07-31 10:44:171160 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121161 } else {
1162 MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
1163 }
1164
1165 return ost;
1166}
1167
1168static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
1169{
1170 AVStream *st;
1171 OutputStream *ost;
1172 AVCodecContext *audio_enc;
1173
1174 ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO);
1175 st = ost->st;
1176
1177 audio_enc = st->codec;
1178 audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
1179
1180 if (!ost->stream_copy) {
1181 char *sample_fmt = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121182
1183 MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
1184
1185 MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
1186 if (sample_fmt &&
1187 (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
1188 av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
Martin Storsjöb85dbe62013-07-31 10:44:171189 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121190 }
1191
1192 MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
1193
Anton Khirnova4208b92013-03-13 13:24:451194 ost->avfilter = get_ost_filters(o, oc, ost);
1195 if (!ost->avfilter)
Martin Storsjöb85dbe62013-07-31 10:44:171196 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121197 }
1198
1199 return ost;
1200}
1201
1202static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
1203{
1204 OutputStream *ost;
1205
1206 ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
1207 if (!ost->stream_copy) {
1208 av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
Martin Storsjöb85dbe62013-07-31 10:44:171209 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121210 }
1211
1212 return ost;
1213}
1214
1215static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc)
1216{
1217 OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
1218 ost->stream_copy = 1;
Anton Khirnov3e175a22013-03-14 08:44:071219 ost->finished = 1;
Anton Khirnovf5e66822012-08-01 16:23:121220 return ost;
1221}
1222
1223static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
1224{
1225 AVStream *st;
1226 OutputStream *ost;
1227 AVCodecContext *subtitle_enc;
1228
1229 ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE);
1230 st = ost->st;
1231 subtitle_enc = st->codec;
1232
1233 subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
1234
1235 return ost;
1236}
1237
1238/* arg format is "output-stream-index:streamid-value". */
Anton Khirnovd3810c42012-08-11 14:30:261239static int opt_streamid(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121240{
Anton Khirnovd3810c42012-08-11 14:30:261241 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121242 int idx;
1243 char *p;
1244 char idx_str[16];
1245
1246 av_strlcpy(idx_str, arg, sizeof(idx_str));
1247 p = strchr(idx_str, ':');
1248 if (!p) {
1249 av_log(NULL, AV_LOG_FATAL,
1250 "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
1251 arg, opt);
Martin Storsjöb85dbe62013-07-31 10:44:171252 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121253 }
1254 *p++ = '\0';
1255 idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
1256 o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
1257 o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
1258 return 0;
1259}
1260
1261static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
1262{
1263 AVFormatContext *is = ifile->ctx;
1264 AVFormatContext *os = ofile->ctx;
Janne Grunau18ff4d22012-10-09 13:20:151265 AVChapter **tmp;
Anton Khirnovf5e66822012-08-01 16:23:121266 int i;
1267
Janne Grunau18ff4d22012-10-09 13:20:151268 tmp = av_realloc(os->chapters, sizeof(*os->chapters) * (is->nb_chapters + os->nb_chapters));
1269 if (!tmp)
1270 return AVERROR(ENOMEM);
1271 os->chapters = tmp;
1272
Anton Khirnovf5e66822012-08-01 16:23:121273 for (i = 0; i < is->nb_chapters; i++) {
1274 AVChapter *in_ch = is->chapters[i], *out_ch;
Anton Khirnov56ee3f92013-06-15 07:35:101275 int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
1276 int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
Anton Khirnovf5e66822012-08-01 16:23:121277 AV_TIME_BASE_Q, in_ch->time_base);
1278 int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
1279 av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
1280
1281
1282 if (in_ch->end < ts_off)
1283 continue;
1284 if (rt != INT64_MAX && in_ch->start > rt + ts_off)
1285 break;
1286
1287 out_ch = av_mallocz(sizeof(AVChapter));
1288 if (!out_ch)
1289 return AVERROR(ENOMEM);
1290
1291 out_ch->id = in_ch->id;
1292 out_ch->time_base = in_ch->time_base;
1293 out_ch->start = FFMAX(0, in_ch->start - ts_off);
1294 out_ch->end = FFMIN(rt, in_ch->end - ts_off);
1295
1296 if (copy_metadata)
1297 av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
1298
Janne Grunau18ff4d22012-10-09 13:20:151299 os->chapters[os->nb_chapters++] = out_ch;
Anton Khirnovf5e66822012-08-01 16:23:121300 }
1301 return 0;
1302}
1303
1304static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
1305 AVFormatContext *oc)
1306{
1307 OutputStream *ost;
1308
1309 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1310 ofilter->out_tmp->pad_idx)) {
1311 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1312 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1313 default:
1314 av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
1315 "currently.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171316 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121317 }
1318
1319 ost->source_index = -1;
1320 ost->filter = ofilter;
1321
1322 ofilter->ost = ost;
1323
1324 if (ost->stream_copy) {
1325 av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
1326 "which is fed from a complex filtergraph. Filtering and streamcopy "
1327 "cannot be used together.\n", ost->file_index, ost->index);
Martin Storsjöb85dbe62013-07-31 10:44:171328 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121329 }
1330
1331 if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
1332 av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171333 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121334 }
1335 avfilter_inout_free(&ofilter->out_tmp);
1336}
1337
1338static int configure_complex_filters(void)
1339{
1340 int i, ret = 0;
1341
1342 for (i = 0; i < nb_filtergraphs; i++)
1343 if (!filtergraphs[i]->graph &&
1344 (ret = configure_filtergraph(filtergraphs[i])) < 0)
1345 return ret;
1346 return 0;
1347}
1348
Anton Khirnov77bd1bc2012-06-08 19:35:161349static int open_output_file(OptionsContext *o, const char *filename)
Anton Khirnovf5e66822012-08-01 16:23:121350{
Anton Khirnovf5e66822012-08-01 16:23:121351 AVFormatContext *oc;
1352 int i, j, err;
1353 AVOutputFormat *file_oformat;
Anton Khirnov1da54e92013-02-21 08:53:281354 OutputFile *of;
Anton Khirnovf5e66822012-08-01 16:23:121355 OutputStream *ost;
1356 InputStream *ist;
Anton Khirnove7553f42013-02-21 09:58:461357 AVDictionary *unused_opts = NULL;
1358 AVDictionaryEntry *e = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121359
1360 if (configure_complex_filters() < 0) {
1361 av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171362 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121363 }
1364
Anton Khirnov3d624422013-04-10 12:46:201365 GROW_ARRAY(output_files, nb_output_files);
1366 of = av_mallocz(sizeof(*of));
1367 if (!of)
Martin Storsjöb85dbe62013-07-31 10:44:171368 exit_program(1);
Anton Khirnov3d624422013-04-10 12:46:201369 output_files[nb_output_files - 1] = of;
1370
1371 of->ost_index = nb_output_streams;
1372 of->recording_time = o->recording_time;
1373 of->start_time = o->start_time;
1374 of->limit_filesize = o->limit_filesize;
1375 of->shortest = o->shortest;
1376 av_dict_copy(&of->opts, o->g->format_opts, 0);
1377
Anton Khirnovf5e66822012-08-01 16:23:121378 if (!strcmp(filename, "-"))
1379 filename = "pipe:";
1380
1381 oc = avformat_alloc_context();
1382 if (!oc) {
1383 print_error(filename, AVERROR(ENOMEM));
Martin Storsjöb85dbe62013-07-31 10:44:171384 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121385 }
Anton Khirnov3d624422013-04-10 12:46:201386 of->ctx = oc;
1387 if (o->recording_time != INT64_MAX)
1388 oc->duration = o->recording_time;
Anton Khirnovf5e66822012-08-01 16:23:121389
1390 if (o->format) {
1391 file_oformat = av_guess_format(o->format, NULL, NULL);
1392 if (!file_oformat) {
1393 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:171394 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121395 }
1396 } else {
1397 file_oformat = av_guess_format(NULL, filename, NULL);
1398 if (!file_oformat) {
1399 av_log(NULL, AV_LOG_FATAL, "Unable to find a suitable output format for '%s'\n",
1400 filename);
Martin Storsjöb85dbe62013-07-31 10:44:171401 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121402 }
1403 }
1404
1405 oc->oformat = file_oformat;
1406 oc->interrupt_callback = int_cb;
1407 av_strlcpy(oc->filename, filename, sizeof(oc->filename));
1408
1409 /* create streams for all unlabeled output pads */
1410 for (i = 0; i < nb_filtergraphs; i++) {
1411 FilterGraph *fg = filtergraphs[i];
1412 for (j = 0; j < fg->nb_outputs; j++) {
1413 OutputFilter *ofilter = fg->outputs[j];
1414
1415 if (!ofilter->out_tmp || ofilter->out_tmp->name)
1416 continue;
1417
1418 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1419 ofilter->out_tmp->pad_idx)) {
1420 case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break;
1421 case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break;
1422 case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
1423 }
1424 init_output_filter(ofilter, o, oc);
1425 }
1426 }
1427
1428 if (!o->nb_stream_maps) {
1429 /* pick the "best" stream of each type */
1430#define NEW_STREAM(type, index)\
1431 if (index >= 0) {\
1432 ost = new_ ## type ## _stream(o, oc);\
1433 ost->source_index = index;\
1434 ost->sync_ist = input_streams[index];\
1435 input_streams[index]->discard = 0;\
1436 input_streams[index]->st->discard = AVDISCARD_NONE;\
1437 }
1438
1439 /* video: highest resolution */
1440 if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
1441 int area = 0, idx = -1;
1442 for (i = 0; i < nb_input_streams; i++) {
1443 ist = input_streams[i];
1444 if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
1445 ist->st->codec->width * ist->st->codec->height > area) {
1446 area = ist->st->codec->width * ist->st->codec->height;
1447 idx = i;
1448 }
1449 }
1450 NEW_STREAM(video, idx);
1451 }
1452
1453 /* audio: most channels */
1454 if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
1455 int channels = 0, idx = -1;
1456 for (i = 0; i < nb_input_streams; i++) {
1457 ist = input_streams[i];
1458 if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
1459 ist->st->codec->channels > channels) {
1460 channels = ist->st->codec->channels;
1461 idx = i;
1462 }
1463 }
1464 NEW_STREAM(audio, idx);
1465 }
1466
1467 /* subtitles: pick first */
1468 if (!o->subtitle_disable && oc->oformat->subtitle_codec != AV_CODEC_ID_NONE) {
1469 for (i = 0; i < nb_input_streams; i++)
1470 if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1471 NEW_STREAM(subtitle, i);
1472 break;
1473 }
1474 }
1475 /* do something with data? */
1476 } else {
1477 for (i = 0; i < o->nb_stream_maps; i++) {
1478 StreamMap *map = &o->stream_maps[i];
1479
1480 if (map->disabled)
1481 continue;
1482
1483 if (map->linklabel) {
1484 FilterGraph *fg;
1485 OutputFilter *ofilter = NULL;
1486 int j, k;
1487
1488 for (j = 0; j < nb_filtergraphs; j++) {
1489 fg = filtergraphs[j];
1490 for (k = 0; k < fg->nb_outputs; k++) {
1491 AVFilterInOut *out = fg->outputs[k]->out_tmp;
1492 if (out && !strcmp(out->name, map->linklabel)) {
1493 ofilter = fg->outputs[k];
1494 goto loop_end;
1495 }
1496 }
1497 }
1498loop_end:
1499 if (!ofilter) {
1500 av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
1501 "in any defined filter graph.\n", map->linklabel);
Martin Storsjöb85dbe62013-07-31 10:44:171502 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121503 }
1504 init_output_filter(ofilter, o, oc);
1505 } else {
1506 ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
1507 switch (ist->st->codec->codec_type) {
1508 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1509 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1510 case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
1511 case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break;
1512 case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
1513 default:
1514 av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
1515 map->file_index, map->stream_index);
Martin Storsjöb85dbe62013-07-31 10:44:171516 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121517 }
1518
1519 ost->source_index = input_files[map->file_index]->ist_index + map->stream_index;
1520 ost->sync_ist = input_streams[input_files[map->sync_file_index]->ist_index +
1521 map->sync_stream_index];
1522 ist->discard = 0;
1523 ist->st->discard = AVDISCARD_NONE;
1524 }
1525 }
1526 }
1527
1528 /* handle attached files */
1529 for (i = 0; i < o->nb_attachments; i++) {
1530 AVIOContext *pb;
1531 uint8_t *attachment;
1532 const char *p;
1533 int64_t len;
1534
1535 if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
1536 av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
1537 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171538 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121539 }
1540 if ((len = avio_size(pb)) <= 0) {
1541 av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
1542 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171543 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121544 }
1545 if (!(attachment = av_malloc(len))) {
1546 av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
1547 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171548 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121549 }
1550 avio_read(pb, attachment, len);
1551
1552 ost = new_attachment_stream(o, oc);
1553 ost->stream_copy = 0;
1554 ost->source_index = -1;
1555 ost->attachment_filename = o->attachments[i];
1556 ost->st->codec->extradata = attachment;
1557 ost->st->codec->extradata_size = len;
1558
1559 p = strrchr(o->attachments[i], '/');
1560 av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
1561 avio_close(pb);
1562 }
1563
Anton Khirnove7553f42013-02-21 09:58:461564 /* check if all codec options have been used */
1565 unused_opts = strip_specifiers(o->g->codec_opts);
1566 for (i = of->ost_index; i < nb_output_streams; i++) {
1567 e = NULL;
Anton Khirnov95808182014-04-04 17:38:041568 while ((e = av_dict_get(output_streams[i]->encoder_opts, "", e,
Anton Khirnove7553f42013-02-21 09:58:461569 AV_DICT_IGNORE_SUFFIX)))
1570 av_dict_set(&unused_opts, e->key, NULL, 0);
1571 }
1572
1573 e = NULL;
1574 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
1575 const AVClass *class = avcodec_get_class();
1576 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
1577 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1578 if (!option)
1579 continue;
1580 if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
1581 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
1582 "output file #%d (%s) is not an encoding option.\n", e->key,
1583 option->help ? option->help : "", nb_output_files - 1,
1584 filename);
Martin Storsjöb85dbe62013-07-31 10:44:171585 exit_program(1);
Anton Khirnove7553f42013-02-21 09:58:461586 }
1587
1588 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
1589 "output file #%d (%s) has not been used for any stream. The most "
1590 "likely reason is either wrong type (e.g. a video option with "
1591 "no video streams) or that it is a private option of some encoder "
1592 "which was not actually used for any stream.\n", e->key,
1593 option->help ? option->help : "", nb_output_files - 1, filename);
1594 }
1595 av_dict_free(&unused_opts);
1596
Anton Khirnovf5e66822012-08-01 16:23:121597 /* check filename in case of an image number is expected */
1598 if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
1599 if (!av_filename_number_test(oc->filename)) {
1600 print_error(oc->filename, AVERROR(EINVAL));
Martin Storsjöb85dbe62013-07-31 10:44:171601 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121602 }
1603 }
1604
1605 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
1606 /* test if it already exists to avoid losing precious files */
1607 assert_file_overwrite(filename);
1608
1609 /* open the file */
1610 if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
1611 &oc->interrupt_callback,
Anton Khirnov1da54e92013-02-21 08:53:281612 &of->opts)) < 0) {
Anton Khirnovf5e66822012-08-01 16:23:121613 print_error(filename, err);
Martin Storsjöb85dbe62013-07-31 10:44:171614 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121615 }
1616 }
1617
1618 if (o->mux_preload) {
1619 uint8_t buf[64];
1620 snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
Anton Khirnov1da54e92013-02-21 08:53:281621 av_dict_set(&of->opts, "preload", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:121622 }
1623 oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
1624 oc->flags |= AVFMT_FLAG_NONBLOCK;
1625
1626 /* copy metadata */
1627 for (i = 0; i < o->nb_metadata_map; i++) {
1628 char *p;
1629 int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
1630
Anton Khirnovf5e66822012-08-01 16:23:121631 if (in_file_index >= nb_input_files) {
1632 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:171633 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121634 }
Anton Khirnova119c642012-10-16 07:53:391635 copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
1636 in_file_index >= 0 ?
1637 input_files[in_file_index]->ctx : NULL, o);
Anton Khirnovf5e66822012-08-01 16:23:121638 }
1639
1640 /* copy chapters */
1641 if (o->chapters_input_file >= nb_input_files) {
1642 if (o->chapters_input_file == INT_MAX) {
1643 /* copy chapters from the first input file that has them*/
1644 o->chapters_input_file = -1;
1645 for (i = 0; i < nb_input_files; i++)
1646 if (input_files[i]->ctx->nb_chapters) {
1647 o->chapters_input_file = i;
1648 break;
1649 }
1650 } else {
1651 av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
1652 o->chapters_input_file);
Martin Storsjöb85dbe62013-07-31 10:44:171653 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121654 }
1655 }
1656 if (o->chapters_input_file >= 0)
Anton Khirnov1da54e92013-02-21 08:53:281657 copy_chapters(input_files[o->chapters_input_file], of,
Anton Khirnovf5e66822012-08-01 16:23:121658 !o->metadata_chapters_manual);
1659
1660 /* copy global metadata by default */
1661 if (!o->metadata_global_manual && nb_input_files)
1662 av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
1663 AV_DICT_DONT_OVERWRITE);
1664 if (!o->metadata_streams_manual)
Anton Khirnov1da54e92013-02-21 08:53:281665 for (i = of->ost_index; i < nb_output_streams; i++) {
Anton Khirnovf5e66822012-08-01 16:23:121666 InputStream *ist;
1667 if (output_streams[i]->source_index < 0) /* this is true e.g. for attached files */
1668 continue;
1669 ist = input_streams[output_streams[i]->source_index];
1670 av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
1671 }
1672
1673 /* process manually set metadata */
1674 for (i = 0; i < o->nb_metadata; i++) {
1675 AVDictionary **m;
1676 char type, *val;
1677 const char *stream_spec;
1678 int index = 0, j, ret;
1679
1680 val = strchr(o->metadata[i].u.str, '=');
1681 if (!val) {
1682 av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
1683 o->metadata[i].u.str);
Martin Storsjöb85dbe62013-07-31 10:44:171684 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121685 }
1686 *val++ = 0;
1687
1688 parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
1689 if (type == 's') {
1690 for (j = 0; j < oc->nb_streams; j++) {
1691 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
1692 av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
1693 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:171694 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121695 }
1696 }
1697 else {
1698 switch (type) {
1699 case 'g':
1700 m = &oc->metadata;
1701 break;
1702 case 'c':
1703 if (index < 0 || index >= oc->nb_chapters) {
1704 av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
Martin Storsjöb85dbe62013-07-31 10:44:171705 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121706 }
1707 m = &oc->chapters[index]->metadata;
1708 break;
1709 default:
1710 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
Martin Storsjöb85dbe62013-07-31 10:44:171711 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121712 }
1713 av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
1714 }
1715 }
1716
Anton Khirnov77bd1bc2012-06-08 19:35:161717 return 0;
Anton Khirnovf5e66822012-08-01 16:23:121718}
1719
Anton Khirnovd3810c42012-08-11 14:30:261720static int opt_target(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121721{
Anton Khirnovd3810c42012-08-11 14:30:261722 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121723 enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
1724 static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
1725
1726 if (!strncmp(arg, "pal-", 4)) {
1727 norm = PAL;
1728 arg += 4;
1729 } else if (!strncmp(arg, "ntsc-", 5)) {
1730 norm = NTSC;
1731 arg += 5;
1732 } else if (!strncmp(arg, "film-", 5)) {
1733 norm = FILM;
1734 arg += 5;
1735 } else {
1736 /* Try to determine PAL/NTSC by peeking in the input files */
1737 if (nb_input_files) {
1738 int i, j, fr;
1739 for (j = 0; j < nb_input_files; j++) {
1740 for (i = 0; i < input_files[j]->nb_streams; i++) {
1741 AVCodecContext *c = input_files[j]->ctx->streams[i]->codec;
1742 if (c->codec_type != AVMEDIA_TYPE_VIDEO)
1743 continue;
1744 fr = c->time_base.den * 1000 / c->time_base.num;
1745 if (fr == 25000) {
1746 norm = PAL;
1747 break;
1748 } else if ((fr == 29970) || (fr == 23976)) {
1749 norm = NTSC;
1750 break;
1751 }
1752 }
1753 if (norm != UNKNOWN)
1754 break;
1755 }
1756 }
1757 if (norm != UNKNOWN)
1758 av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
1759 }
1760
1761 if (norm == UNKNOWN) {
1762 av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
1763 av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
1764 av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
Martin Storsjöb85dbe62013-07-31 10:44:171765 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121766 }
1767
1768 if (!strcmp(arg, "vcd")) {
1769 opt_video_codec(o, "c:v", "mpeg1video");
1770 opt_audio_codec(o, "c:a", "mp2");
1771 parse_option(o, "f", "vcd", options);
1772
1773 parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
1774 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221775 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121776
Anton Khirnov11d957f2012-08-29 12:37:221777 opt_default(NULL, "b", "1150000");
1778 opt_default(NULL, "maxrate", "1150000");
1779 opt_default(NULL, "minrate", "1150000");
1780 opt_default(NULL, "bufsize", "327680"); // 40*1024*8;
Anton Khirnovf5e66822012-08-01 16:23:121781
Anton Khirnov11d957f2012-08-29 12:37:221782 opt_default(NULL, "b:a", "224000");
Anton Khirnovf5e66822012-08-01 16:23:121783 parse_option(o, "ar", "44100", options);
1784 parse_option(o, "ac", "2", options);
1785
Anton Khirnov11d957f2012-08-29 12:37:221786 opt_default(NULL, "packetsize", "2324");
1787 opt_default(NULL, "muxrate", "1411200"); // 2352 * 75 * 8;
Anton Khirnovf5e66822012-08-01 16:23:121788
1789 /* We have to offset the PTS, so that it is consistent with the SCR.
1790 SCR starts at 36000, but the first two packs contain only padding
1791 and the first pack from the other stream, respectively, may also have
1792 been written before.
1793 So the real data starts at SCR 36000+3*1200. */
1794 o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
1795 } else if (!strcmp(arg, "svcd")) {
1796
1797 opt_video_codec(o, "c:v", "mpeg2video");
1798 opt_audio_codec(o, "c:a", "mp2");
1799 parse_option(o, "f", "svcd", options);
1800
1801 parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
1802 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221803 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121804
Anton Khirnov11d957f2012-08-29 12:37:221805 opt_default(NULL, "b", "2040000");
1806 opt_default(NULL, "maxrate", "2516000");
1807 opt_default(NULL, "minrate", "0"); // 1145000;
1808 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
1809 opt_default(NULL, "flags", "+scan_offset");
Anton Khirnovf5e66822012-08-01 16:23:121810
1811
Anton Khirnov11d957f2012-08-29 12:37:221812 opt_default(NULL, "b:a", "224000");
Anton Khirnovf5e66822012-08-01 16:23:121813 parse_option(o, "ar", "44100", options);
1814
Anton Khirnov11d957f2012-08-29 12:37:221815 opt_default(NULL, "packetsize", "2324");
Anton Khirnovf5e66822012-08-01 16:23:121816
1817 } else if (!strcmp(arg, "dvd")) {
1818
1819 opt_video_codec(o, "c:v", "mpeg2video");
1820 opt_audio_codec(o, "c:a", "ac3");
1821 parse_option(o, "f", "dvd", options);
1822
1823 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
1824 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221825 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121826
Anton Khirnov11d957f2012-08-29 12:37:221827 opt_default(NULL, "b", "6000000");
1828 opt_default(NULL, "maxrate", "9000000");
1829 opt_default(NULL, "minrate", "0"); // 1500000;
1830 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
Anton Khirnovf5e66822012-08-01 16:23:121831
Anton Khirnov11d957f2012-08-29 12:37:221832 opt_default(NULL, "packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
1833 opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
Anton Khirnovf5e66822012-08-01 16:23:121834
Anton Khirnov11d957f2012-08-29 12:37:221835 opt_default(NULL, "b:a", "448000");
Anton Khirnovf5e66822012-08-01 16:23:121836 parse_option(o, "ar", "48000", options);
1837
1838 } else if (!strncmp(arg, "dv", 2)) {
1839
1840 parse_option(o, "f", "dv", options);
1841
1842 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
1843 parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
1844 norm == PAL ? "yuv420p" : "yuv411p", options);
1845 parse_option(o, "r", frame_rates[norm], options);
1846
1847 parse_option(o, "ar", "48000", options);
1848 parse_option(o, "ac", "2", options);
1849
1850 } else {
1851 av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
1852 return AVERROR(EINVAL);
1853 }
1854 return 0;
1855}
1856
Anton Khirnov11d957f2012-08-29 12:37:221857static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121858{
1859 av_free (vstats_filename);
1860 vstats_filename = av_strdup (arg);
1861 return 0;
1862}
1863
Anton Khirnov11d957f2012-08-29 12:37:221864static int opt_vstats(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121865{
1866 char filename[40];
1867 time_t today2 = time(NULL);
1868 struct tm *today = localtime(&today2);
1869
1870 snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
1871 today->tm_sec);
Anton Khirnov11d957f2012-08-29 12:37:221872 return opt_vstats_file(NULL, opt, filename);
Anton Khirnovf5e66822012-08-01 16:23:121873}
1874
Anton Khirnovd3810c42012-08-11 14:30:261875static int opt_video_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121876{
Anton Khirnovd3810c42012-08-11 14:30:261877 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121878 return parse_option(o, "frames:v", arg, options);
1879}
1880
Anton Khirnovd3810c42012-08-11 14:30:261881static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121882{
Anton Khirnovd3810c42012-08-11 14:30:261883 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121884 return parse_option(o, "frames:a", arg, options);
1885}
1886
Anton Khirnovd3810c42012-08-11 14:30:261887static int opt_data_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121888{
Anton Khirnovd3810c42012-08-11 14:30:261889 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121890 return parse_option(o, "frames:d", arg, options);
1891}
1892
Anton Khirnovd3810c42012-08-11 14:30:261893static int opt_video_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121894{
Anton Khirnovd3810c42012-08-11 14:30:261895 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121896 return parse_option(o, "tag:v", arg, options);
1897}
1898
Anton Khirnovd3810c42012-08-11 14:30:261899static int opt_audio_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121900{
Anton Khirnovd3810c42012-08-11 14:30:261901 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121902 return parse_option(o, "tag:a", arg, options);
1903}
1904
Anton Khirnovd3810c42012-08-11 14:30:261905static int opt_subtitle_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121906{
Anton Khirnovd3810c42012-08-11 14:30:261907 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121908 return parse_option(o, "tag:s", arg, options);
1909}
1910
Anton Khirnovd3810c42012-08-11 14:30:261911static int opt_video_filters(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121912{
Anton Khirnovd3810c42012-08-11 14:30:261913 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121914 return parse_option(o, "filter:v", arg, options);
1915}
1916
Anton Khirnovd3810c42012-08-11 14:30:261917static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121918{
Anton Khirnovd3810c42012-08-11 14:30:261919 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121920 return parse_option(o, "filter:a", arg, options);
1921}
1922
Anton Khirnov11d957f2012-08-29 12:37:221923static int opt_vsync(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121924{
1925 if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR;
1926 else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR;
1927 else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
1928
1929 if (video_sync_method == VSYNC_AUTO)
1930 video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
1931 return 0;
1932}
1933
Anton Khirnovd3810c42012-08-11 14:30:261934static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121935{
Anton Khirnovd3810c42012-08-11 14:30:261936 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121937 char layout_str[32];
1938 char *stream_str;
1939 char *ac_str;
1940 int ret, channels, ac_str_size;
1941 uint64_t layout;
1942
1943 layout = av_get_channel_layout(arg);
1944 if (!layout) {
1945 av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
1946 return AVERROR(EINVAL);
1947 }
1948 snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
Anton Khirnov11d957f2012-08-29 12:37:221949 ret = opt_default(NULL, opt, layout_str);
Anton Khirnovf5e66822012-08-01 16:23:121950 if (ret < 0)
1951 return ret;
1952
1953 /* set 'ac' option based on channel layout */
1954 channels = av_get_channel_layout_nb_channels(layout);
1955 snprintf(layout_str, sizeof(layout_str), "%d", channels);
1956 stream_str = strchr(opt, ':');
1957 ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
1958 ac_str = av_mallocz(ac_str_size);
1959 if (!ac_str)
1960 return AVERROR(ENOMEM);
1961 av_strlcpy(ac_str, "ac", 3);
1962 if (stream_str)
1963 av_strlcat(ac_str, stream_str, ac_str_size);
1964 ret = parse_option(o, ac_str, layout_str, options);
1965 av_free(ac_str);
1966
1967 return ret;
1968}
1969
Anton Khirnovd3810c42012-08-11 14:30:261970static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121971{
Anton Khirnovd3810c42012-08-11 14:30:261972 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121973 return parse_option(o, "q:a", arg, options);
1974}
1975
Anton Khirnov11d957f2012-08-29 12:37:221976static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121977{
Anton Khirnov10bca662012-06-07 19:52:071978 GROW_ARRAY(filtergraphs, nb_filtergraphs);
Anton Khirnovf5e66822012-08-01 16:23:121979 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
1980 return AVERROR(ENOMEM);
Anton Khirnova4208b92013-03-13 13:24:451981 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
1982 filtergraphs[nb_filtergraphs - 1]->graph_desc = av_strdup(arg);
1983 if (!filtergraphs[nb_filtergraphs - 1]->graph_desc)
1984 return AVERROR(ENOMEM);
1985 return 0;
1986}
1987
1988static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
1989{
1990 uint8_t *graph_desc = read_file(arg);
1991 if (!graph_desc)
1992 return AVERROR(EINVAL);
1993
1994 GROW_ARRAY(filtergraphs, nb_filtergraphs);
1995 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
1996 return AVERROR(ENOMEM);
1997 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
1998 filtergraphs[nb_filtergraphs - 1]->graph_desc = graph_desc;
Anton Khirnovf5e66822012-08-01 16:23:121999 return 0;
2000}
2001
Anton Khirnova3ad68d2012-08-13 18:06:252002void show_help_default(const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:122003{
Anton Khirnovf9fada22012-08-15 08:31:462004 /* per-file options have at least one of those set */
Anton Khirnov11d957f2012-08-29 12:37:222005 const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
Anton Khirnov6e3857f2012-08-14 06:56:322006 int show_advanced = 0, show_avoptions = 0;
2007
Janne Grunau8d09d392012-10-10 18:35:262008 if (opt && *opt) {
Anton Khirnov6e3857f2012-08-14 06:56:322009 if (!strcmp(opt, "long"))
2010 show_advanced = 1;
2011 else if (!strcmp(opt, "full"))
2012 show_advanced = show_avoptions = 1;
2013 else
2014 av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
2015 }
Anton Khirnova3ad68d2012-08-13 18:06:252016
Anton Khirnovf5e66822012-08-01 16:23:122017 show_usage();
Anton Khirnov6e3857f2012-08-14 06:56:322018
2019 printf("Getting help:\n"
2020 " -h -- print basic options\n"
2021 " -h long -- print more options\n"
2022 " -h full -- print all options (including all format and codec specific options, very long)\n"
2023 " See man %s for detailed description of the options.\n"
2024 "\n", program_name);
2025
Anton Khirnovf8b1e662012-08-14 06:21:422026 show_help_options(options, "Print help / information / capabilities:",
Anton Khirnovf9fada22012-08-15 08:31:462027 OPT_EXIT, 0, 0);
2028
2029 show_help_options(options, "Global options (affect whole program "
2030 "instead of just one file:",
2031 0, per_file | OPT_EXIT | OPT_EXPERT, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322032 if (show_advanced)
Anton Khirnovf9fada22012-08-15 08:31:462033 show_help_options(options, "Advanced global options:", OPT_EXPERT,
2034 per_file | OPT_EXIT, 0);
2035
2036 show_help_options(options, "Per-file main options:", 0,
2037 OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
2038 OPT_EXIT, per_file);
2039 if (show_advanced)
2040 show_help_options(options, "Advanced per-file options:",
2041 OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
Anton Khirnov6e3857f2012-08-14 06:56:322042
Anton Khirnovdc4c24a2012-08-11 17:33:272043 show_help_options(options, "Video options:",
Anton Khirnovf9fada22012-08-15 08:31:462044 OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322045 if (show_advanced)
2046 show_help_options(options, "Advanced Video options:",
Anton Khirnovf9fada22012-08-15 08:31:462047 OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322048
Anton Khirnovdc4c24a2012-08-11 17:33:272049 show_help_options(options, "Audio options:",
Anton Khirnovf9fada22012-08-15 08:31:462050 OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322051 if (show_advanced)
2052 show_help_options(options, "Advanced Audio options:",
Anton Khirnovf9fada22012-08-15 08:31:462053 OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
Anton Khirnovdc4c24a2012-08-11 17:33:272054 show_help_options(options, "Subtitle options:",
Anton Khirnovf9fada22012-08-15 08:31:462055 OPT_SUBTITLE, 0, 0);
Anton Khirnovf5e66822012-08-01 16:23:122056 printf("\n");
Anton Khirnov6e3857f2012-08-14 06:56:322057
2058 if (show_avoptions) {
2059 int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
2060 show_help_children(avcodec_get_class(), flags);
2061 show_help_children(avformat_get_class(), flags);
2062 show_help_children(sws_get_class(), flags);
Anton Khirnovdc574652013-03-13 08:10:342063 show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM);
Anton Khirnov6e3857f2012-08-14 06:56:322064 }
Anton Khirnovf5e66822012-08-01 16:23:122065}
2066
2067void show_usage(void)
2068{
2069 printf("Hyper fast Audio and Video encoder\n");
2070 printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
2071 printf("\n");
2072}
2073
Anton Khirnov77bd1bc2012-06-08 19:35:162074enum OptGroup {
2075 GROUP_OUTFILE,
2076 GROUP_INFILE,
2077};
2078
2079static const OptionGroupDef groups[] = {
Anton Khirnov9d3009c2013-02-20 07:02:162080 [GROUP_OUTFILE] = { "output file", NULL, OPT_OUTPUT },
2081 [GROUP_INFILE] = { "input file", "i", OPT_INPUT },
Anton Khirnov77bd1bc2012-06-08 19:35:162082};
2083
2084static int open_files(OptionGroupList *l, const char *inout,
2085 int (*open_file)(OptionsContext*, const char*))
2086{
2087 int i, ret;
2088
2089 for (i = 0; i < l->nb_groups; i++) {
2090 OptionGroup *g = &l->groups[i];
2091 OptionsContext o;
2092
2093 init_options(&o);
2094 o.g = g;
2095
2096 ret = parse_optgroup(&o, g);
2097 if (ret < 0) {
2098 av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
2099 "%s.\n", inout, g->arg);
2100 return ret;
2101 }
2102
2103 av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
2104 ret = open_file(&o, g->arg);
2105 uninit_options(&o);
2106 if (ret < 0) {
2107 av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
2108 inout, g->arg);
2109 return ret;
2110 }
Anton Khirnovdb2d65c2013-02-21 09:57:572111 av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
Anton Khirnov77bd1bc2012-06-08 19:35:162112 }
2113
2114 return 0;
2115}
2116
2117int avconv_parse_options(int argc, char **argv)
2118{
2119 OptionParseContext octx;
2120 uint8_t error[128];
2121 int ret;
2122
2123 memset(&octx, 0, sizeof(octx));
2124
2125 /* split the commandline into an internal representation */
Anton Khirnovc661cb62012-12-19 20:53:222126 ret = split_commandline(&octx, argc, argv, options, groups,
2127 FF_ARRAY_ELEMS(groups));
Anton Khirnov77bd1bc2012-06-08 19:35:162128 if (ret < 0) {
2129 av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
2130 goto fail;
2131 }
2132
2133 /* apply global options */
2134 ret = parse_optgroup(NULL, &octx.global_opts);
2135 if (ret < 0) {
2136 av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
2137 goto fail;
2138 }
2139
2140 /* open input files */
2141 ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
2142 if (ret < 0) {
2143 av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
2144 goto fail;
2145 }
2146
2147 /* open output files */
2148 ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
2149 if (ret < 0) {
2150 av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
2151 goto fail;
2152 }
2153
2154fail:
2155 uninit_parse_context(&octx);
2156 if (ret < 0) {
2157 av_strerror(ret, error, sizeof(error));
2158 av_log(NULL, AV_LOG_FATAL, "%s\n", error);
2159 }
2160 return ret;
2161}
Anton Khirnovf5e66822012-08-01 16:23:122162
2163#define OFFSET(x) offsetof(OptionsContext, x)
2164const OptionDef options[] = {
2165 /* main options */
2166#include "cmdutils_common_opts.h"
Anton Khirnov9d3009c2013-02-20 07:02:162167 { "f", HAS_ARG | OPT_STRING | OPT_OFFSET |
2168 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(format) },
Anton Khirnov8fc83fb2012-08-11 15:00:302169 "force format", "fmt" },
Anton Khirnov8fc83fb2012-08-11 15:00:302170 { "y", OPT_BOOL, { &file_overwrite },
2171 "overwrite output files" },
Vittorio Giovara7748dd42013-07-31 12:48:492172 { "n", OPT_BOOL, { &file_skip },
2173 "never overwrite output files" },
Anton Khirnov9d3009c2013-02-20 07:02:162174 { "c", 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 { "codec", HAS_ARG | OPT_STRING | OPT_SPEC |
2178 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
Anton Khirnov8fc83fb2012-08-11 15:00:302179 "codec name", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162180 { "pre", HAS_ARG | OPT_STRING | OPT_SPEC |
2181 OPT_OUTPUT, { .off = OFFSET(presets) },
Anton Khirnov8fc83fb2012-08-11 15:00:302182 "preset name", "preset" },
Anton Khirnov9d3009c2013-02-20 07:02:162183 { "map", HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2184 OPT_OUTPUT, { .func_arg = opt_map },
Anton Khirnov8fc83fb2012-08-11 15:00:302185 "set input stream mapping",
2186 "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
Anton Khirnov9d3009c2013-02-20 07:02:162187 { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC |
2188 OPT_OUTPUT, { .off = OFFSET(metadata_map) },
Anton Khirnov8fc83fb2012-08-11 15:00:302189 "set metadata information of outfile from infile",
2190 "outfile[,metadata]:infile[,metadata]" },
Anton Khirnov9d3009c2013-02-20 07:02:162191 { "map_chapters", HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
2192 OPT_OUTPUT, { .off = OFFSET(chapters_input_file) },
Anton Khirnov8fc83fb2012-08-11 15:00:302193 "set chapters mapping", "input_file_index" },
Anton Khirnov488a0fa2013-06-18 09:12:092194 { "t", HAS_ARG | OPT_TIME | OPT_OFFSET |
2195 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(recording_time) },
Anton Khirnov8fc83fb2012-08-11 15:00:302196 "record or transcode \"duration\" seconds of audio/video",
2197 "duration" },
Anton Khirnov9d3009c2013-02-20 07:02:162198 { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
Anton Khirnov8fc83fb2012-08-11 15:00:302199 "set the limit file size in bytes", "limit_size" },
Anton Khirnov9d3009c2013-02-20 07:02:162200 { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET |
2201 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time) },
Anton Khirnov8fc83fb2012-08-11 15:00:302202 "set the start time offset", "time_off" },
Anton Khirnov811bd072013-06-15 07:59:402203 { "accurate_seek", OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
2204 OPT_INPUT, { .off = OFFSET(accurate_seek) },
2205 "enable/disable accurate seeking with -ss" },
Anton Khirnov9d3009c2013-02-20 07:02:162206 { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET |
2207 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(input_ts_offset) },
Anton Khirnov8fc83fb2012-08-11 15:00:302208 "set the input ts offset", "time_off" },
Anton Khirnov9d3009c2013-02-20 07:02:162209 { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC |
2210 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(ts_scale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302211 "set the input ts scale", "scale" },
Anton Khirnov9d3009c2013-02-20 07:02:162212 { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
Anton Khirnov8fc83fb2012-08-11 15:00:302213 "add metadata", "string=string" },
Anton Khirnov9d3009c2013-02-20 07:02:162214 { "dframes", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2215 OPT_OUTPUT, { .func_arg = opt_data_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302216 "set the number of data frames to record", "number" },
2217 { "benchmark", OPT_BOOL | OPT_EXPERT, { &do_benchmark },
2218 "add timings for benchmarking" },
Anton Khirnov602b1892012-08-15 08:33:362219 { "timelimit", HAS_ARG | OPT_EXPERT, { .func_arg = opt_timelimit },
Anton Khirnov8fc83fb2012-08-11 15:00:302220 "set max runtime in seconds", "limit" },
2221 { "dump", OPT_BOOL | OPT_EXPERT, { &do_pkt_dump },
2222 "dump each input packet" },
2223 { "hex", OPT_BOOL | OPT_EXPERT, { &do_hex_dump },
2224 "when dumping packets, also dump the payload" },
Anton Khirnov9d3009c2013-02-20 07:02:162225 { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2226 OPT_INPUT, { .off = OFFSET(rate_emu) },
Anton Khirnov8fc83fb2012-08-11 15:00:302227 "read input at native frame rate", "" },
Anton Khirnov9d3009c2013-02-20 07:02:162228 { "target", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_target },
Anton Khirnov8fc83fb2012-08-11 15:00:302229 "specify target file type (\"vcd\", \"svcd\", \"dvd\","
2230 " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
2231 { "vsync", HAS_ARG | OPT_EXPERT, { opt_vsync },
2232 "video sync method", "" },
2233 { "async", HAS_ARG | OPT_INT | OPT_EXPERT, { &audio_sync_method },
2234 "audio sync method", "" },
2235 { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &audio_drift_threshold },
2236 "audio drift threshold", "threshold" },
2237 { "copyts", OPT_BOOL | OPT_EXPERT, { &copy_ts },
2238 "copy timestamps" },
2239 { "copytb", OPT_BOOL | OPT_EXPERT, { &copy_tb },
2240 "copy input stream time base when stream copying" },
Anton Khirnov9d3009c2013-02-20 07:02:162241 { "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2242 OPT_OUTPUT, { .off = OFFSET(shortest) },
Anton Khirnov8fc83fb2012-08-11 15:00:302243 "finish encoding within shortest input" },
2244 { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &dts_delta_threshold },
2245 "timestamp discontinuity delta threshold", "threshold" },
Anton Khirnov602b1892012-08-15 08:33:362246 { "xerror", OPT_BOOL | OPT_EXPERT, { &exit_on_error },
Anton Khirnov8fc83fb2012-08-11 15:00:302247 "exit on error", "error" },
Anton Khirnov9d3009c2013-02-20 07:02:162248 { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2249 OPT_OUTPUT, { .off = OFFSET(copy_initial_nonkeyframes) },
Anton Khirnov8fc83fb2012-08-11 15:00:302250 "copy initial non-keyframes" },
Anton Khirnov9d3009c2013-02-20 07:02:162251 { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
Anton Khirnov8fc83fb2012-08-11 15:00:302252 "set the number of frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162253 { "tag", OPT_STRING | HAS_ARG | OPT_SPEC |
Anton Khirnov746dca42014-02-23 07:05:522254 OPT_EXPERT | OPT_OUTPUT | OPT_INPUT, { .off = OFFSET(codec_tags) },
Anton Khirnov8fc83fb2012-08-11 15:00:302255 "force codec tag/fourcc", "fourcc/tag" },
Anton Khirnov9d3009c2013-02-20 07:02:162256 { "q", 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 { "qscale", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2260 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302261 "use fixed quality scale (VBR)", "q" },
Anton Khirnov9d3009c2013-02-20 07:02:162262 { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
Anton Khirnov8fc83fb2012-08-11 15:00:302263 "set stream filterchain", "filter_list" },
Anton Khirnova4208b92013-03-13 13:24:452264 { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) },
2265 "read stream filtergraph description from a file", "filename" },
Anton Khirnov8fc83fb2012-08-11 15:00:302266 { "filter_complex", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex },
2267 "create a complex filtergraph", "graph_description" },
Anton Khirnova4208b92013-03-13 13:24:452268 { "filter_complex_script", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex_script },
2269 "read complex filtergraph description from a file", "filename" },
Anton Khirnov8fc83fb2012-08-11 15:00:302270 { "stats", OPT_BOOL, { &print_stats },
2271 "print progress report during encoding", },
Anton Khirnov9d3009c2013-02-20 07:02:162272 { "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2273 OPT_OUTPUT, { .func_arg = opt_attach },
Anton Khirnov8fc83fb2012-08-11 15:00:302274 "add an attachment to the output file", "filename" },
Anton Khirnov9d3009c2013-02-20 07:02:162275 { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |
2276 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(dump_attachment) },
Anton Khirnov8fc83fb2012-08-11 15:00:302277 "extract an attachment into a file", "filename" },
Anton Khirnovf5e66822012-08-01 16:23:122278
2279 /* video options */
Anton Khirnov9d3009c2013-02-20 07:02:162280 { "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302281 "set the number of video frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162282 { "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2283 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_rates) },
Anton Khirnov8fc83fb2012-08-11 15:00:302284 "set frame rate (Hz value, fraction or abbreviation)", "rate" },
Anton Khirnov9d3009c2013-02-20 07:02:162285 { "s", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2286 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_sizes) },
Anton Khirnov8fc83fb2012-08-11 15:00:302287 "set frame size (WxH or abbreviation)", "size" },
Anton Khirnov9d3009c2013-02-20 07:02:162288 { "aspect", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2289 OPT_OUTPUT, { .off = OFFSET(frame_aspect_ratios) },
Anton Khirnov8fc83fb2012-08-11 15:00:302290 "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
Anton Khirnov9d3009c2013-02-20 07:02:162291 { "pix_fmt", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2292 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_pix_fmts) },
Anton Khirnov8fc83fb2012-08-11 15:00:302293 "set pixel format", "format" },
Anton Khirnov9d3009c2013-02-20 07:02:162294 { "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(video_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302295 "disable video" },
2296 { "vdt", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &video_discard },
2297 "discard threshold", "n" },
Anton Khirnov9d3009c2013-02-20 07:02:162298 { "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2299 OPT_OUTPUT, { .off = OFFSET(rc_overrides) },
Anton Khirnov8fc83fb2012-08-11 15:00:302300 "rate control override for specific intervals", "override" },
Anton Khirnov9d3009c2013-02-20 07:02:162301 { "vcodec", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_INPUT |
2302 OPT_OUTPUT, { .func_arg = opt_video_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302303 "force video codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162304 { "pass", OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT | OPT_OUTPUT, { .off = OFFSET(pass) },
Anton Khirnov8fc83fb2012-08-11 15:00:302305 "select the pass number (1 or 2)", "n" },
Anton Khirnov9d3009c2013-02-20 07:02:162306 { "passlogfile", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
2307 OPT_OUTPUT, { .off = OFFSET(passlogfiles) },
Anton Khirnov8fc83fb2012-08-11 15:00:302308 "select two pass log file name prefix", "prefix" },
Anton Khirnov8fc83fb2012-08-11 15:00:302309 { "vstats", OPT_VIDEO | OPT_EXPERT , { &opt_vstats },
2310 "dump video coding statistics to file" },
2311 { "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { opt_vstats_file },
2312 "dump video coding statistics to file", "file" },
Anton Khirnov9d3009c2013-02-20 07:02:162313 { "vf", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_filters },
Anton Khirnov8fc83fb2012-08-11 15:00:302314 "video filters", "filter list" },
Anton Khirnov9d3009c2013-02-20 07:02:162315 { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2316 OPT_OUTPUT, { .off = OFFSET(intra_matrices) },
Anton Khirnov8fc83fb2012-08-11 15:00:302317 "specify intra matrix coeffs", "matrix" },
Anton Khirnov9d3009c2013-02-20 07:02:162318 { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2319 OPT_OUTPUT, { .off = OFFSET(inter_matrices) },
Anton Khirnov8fc83fb2012-08-11 15:00:302320 "specify inter matrix coeffs", "matrix" },
Anton Khirnov9d3009c2013-02-20 07:02:162321 { "top", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_INT| OPT_SPEC |
2322 OPT_OUTPUT, { .off = OFFSET(top_field_first) },
Anton Khirnov8fc83fb2012-08-11 15:00:302323 "top=1/bottom=0/auto=-1 field first", "" },
2324 { "dc", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &intra_dc_precision },
2325 "intra_dc_precision", "precision" },
Anton Khirnov9d3009c2013-02-20 07:02:162326 { "vtag", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2327 OPT_OUTPUT, { .func_arg = opt_video_tag },
Anton Khirnov8fc83fb2012-08-11 15:00:302328 "force video tag/fourcc", "fourcc/tag" },
2329 { "qphist", OPT_VIDEO | OPT_BOOL | OPT_EXPERT , { &qp_hist },
2330 "show QP histogram" },
Anton Khirnov9d3009c2013-02-20 07:02:162331 { "force_fps", OPT_VIDEO | OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2332 OPT_OUTPUT, { .off = OFFSET(force_fps) },
Anton Khirnov8fc83fb2012-08-11 15:00:302333 "force the selected framerate, disable the best supported framerate selection" },
Anton Khirnov9d3009c2013-02-20 07:02:162334 { "streamid", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2335 OPT_OUTPUT, { .func_arg = opt_streamid },
Anton Khirnov8fc83fb2012-08-11 15:00:302336 "set the value of an outfile streamid", "streamIndex:value" },
Anton Khirnov9d3009c2013-02-20 07:02:162337 { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2338 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(forced_key_frames) },
2339 "force key frames at specified timestamps", "timestamps" },
Anton Khirnov07fd0a22013-11-02 21:06:362340 { "hwaccel", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2341 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccels) },
2342 "use HW accelerated decoding", "hwaccel name" },
2343 { "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2344 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) },
2345 "select a device for HW acceleration" "devicename" },
Anton Khirnovf5e66822012-08-01 16:23:122346
2347 /* audio options */
Anton Khirnov9d3009c2013-02-20 07:02:162348 { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302349 "set the number of audio frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162350 { "aq", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_qscale },
Anton Khirnov8fc83fb2012-08-11 15:00:302351 "set audio quality (codec-specific)", "quality", },
Anton Khirnov9d3009c2013-02-20 07:02:162352 { "ar", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2353 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_sample_rate) },
Anton Khirnov8fc83fb2012-08-11 15:00:302354 "set audio sampling rate (in Hz)", "rate" },
Anton Khirnov9d3009c2013-02-20 07:02:162355 { "ac", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2356 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_channels) },
Anton Khirnov8fc83fb2012-08-11 15:00:302357 "set number of audio channels", "channels" },
Anton Khirnov9d3009c2013-02-20 07:02:162358 { "an", OPT_AUDIO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(audio_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302359 "disable audio" },
Anton Khirnov9d3009c2013-02-20 07:02:162360 { "acodec", OPT_AUDIO | HAS_ARG | OPT_PERFILE |
2361 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_audio_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302362 "force audio codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162363 { "atag", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2364 OPT_OUTPUT, { .func_arg = opt_audio_tag },
Anton Khirnov8fc83fb2012-08-11 15:00:302365 "force audio tag/fourcc", "fourcc/tag" },
2366 { "vol", OPT_AUDIO | HAS_ARG | OPT_INT, { &audio_volume },
2367 "change audio volume (256=normal)" , "volume" },
Anton Khirnov9d3009c2013-02-20 07:02:162368 { "sample_fmt", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_SPEC |
2369 OPT_STRING | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(sample_fmts) },
Anton Khirnov8fc83fb2012-08-11 15:00:302370 "set sample format", "format" },
Anton Khirnov9d3009c2013-02-20 07:02:162371 { "channel_layout", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2372 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_channel_layout },
Anton Khirnov8fc83fb2012-08-11 15:00:302373 "set channel layout", "layout" },
Anton Khirnov9d3009c2013-02-20 07:02:162374 { "af", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_filters },
Anton Khirnov8fc83fb2012-08-11 15:00:302375 "audio filters", "filter list" },
Anton Khirnovf5e66822012-08-01 16:23:122376
2377 /* subtitle options */
Anton Khirnov9d3009c2013-02-20 07:02:162378 { "sn", OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(subtitle_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302379 "disable subtitle" },
Anton Khirnov9d3009c2013-02-20 07:02:162380 { "scodec", OPT_SUBTITLE | HAS_ARG | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_subtitle_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302381 "force subtitle codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162382 { "stag", OPT_SUBTITLE | HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_subtitle_tag }
Anton Khirnov8fc83fb2012-08-11 15:00:302383 , "force subtitle tag/fourcc", "fourcc/tag" },
Anton Khirnovf5e66822012-08-01 16:23:122384
2385 /* grab options */
Anton Khirnov79600a82012-08-11 17:19:532386 { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
Anton Khirnovf5e66822012-08-01 16:23:122387
2388 /* muxer options */
Anton Khirnov9d3009c2013-02-20 07:02:162389 { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_max_delay) },
Anton Khirnov8fc83fb2012-08-11 15:00:302390 "set the maximum demux-decode delay", "seconds" },
Anton Khirnov9d3009c2013-02-20 07:02:162391 { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
Anton Khirnov8fc83fb2012-08-11 15:00:302392 "set the initial demux-decode delay", "seconds" },
Anton Khirnovf5e66822012-08-01 16:23:122393
Anton Khirnov9d3009c2013-02-20 07:02:162394 { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
Anton Khirnov8fc83fb2012-08-11 15:00:302395 "A comma-separated list of bitstream filters", "bitstream_filters" },
Anton Khirnovf5e66822012-08-01 16:23:122396
2397 /* data codec support */
Anton Khirnov9d3009c2013-02-20 07:02:162398 { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302399 "force data codec ('copy' to copy stream)", "codec" },
Anton Khirnovf5e66822012-08-01 16:23:122400
Anton Khirnovf5e66822012-08-01 16:23:122401 { NULL, },
2402};