blob: cbd8370eba6f442386863df35077a888c848b2e2 [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[] = {
57 { 0 },
58};
59
Anton Khirnovf5e66822012-08-01 16:23:1260char *vstats_filename;
61
62float audio_drift_threshold = 0.1;
63float dts_delta_threshold = 10;
64
65int audio_volume = 256;
66int audio_sync_method = 0;
67int video_sync_method = VSYNC_AUTO;
Anton Khirnovf5e66822012-08-01 16:23:1268int do_benchmark = 0;
69int do_hex_dump = 0;
70int do_pkt_dump = 0;
71int copy_ts = 0;
72int copy_tb = 1;
Anton Khirnovf5e66822012-08-01 16:23:1273int exit_on_error = 0;
74int print_stats = 1;
75int qp_hist = 0;
Anton Khirnovf5e66822012-08-01 16:23:1276
77static int file_overwrite = 0;
Vittorio Giovara7748dd42013-07-31 12:48:4978static int file_skip = 0;
Anton Khirnovf5e66822012-08-01 16:23:1279static int video_discard = 0;
80static int intra_dc_precision = 8;
Anton Khirnovf5e66822012-08-01 16:23:1281static int using_stdin = 0;
82static int input_sync;
83
Anton Khirnov77bd1bc2012-06-08 19:35:1684static void uninit_options(OptionsContext *o)
Anton Khirnovf5e66822012-08-01 16:23:1285{
86 const OptionDef *po = options;
87 int i;
88
89 /* all OPT_SPEC and OPT_STRING can be freed in generic way */
90 while (po->name) {
91 void *dst = (uint8_t*)o + po->u.off;
92
93 if (po->flags & OPT_SPEC) {
94 SpecifierOpt **so = dst;
95 int i, *count = (int*)(so + 1);
96 for (i = 0; i < *count; i++) {
97 av_freep(&(*so)[i].specifier);
98 if (po->flags & OPT_STRING)
99 av_freep(&(*so)[i].u.str);
100 }
101 av_freep(so);
102 *count = 0;
103 } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
104 av_freep(dst);
105 po++;
106 }
107
108 for (i = 0; i < o->nb_stream_maps; i++)
109 av_freep(&o->stream_maps[i].linklabel);
110 av_freep(&o->stream_maps);
111 av_freep(&o->meta_data_maps);
112 av_freep(&o->streamid_map);
Anton Khirnov77bd1bc2012-06-08 19:35:16113}
Anton Khirnovf5e66822012-08-01 16:23:12114
Anton Khirnov77bd1bc2012-06-08 19:35:16115static void init_options(OptionsContext *o)
116{
Anton Khirnovf5e66822012-08-01 16:23:12117 memset(o, 0, sizeof(*o));
118
119 o->mux_max_delay = 0.7;
Anton Khirnov56ee3f92013-06-15 07:35:10120 o->start_time = AV_NOPTS_VALUE;
Anton Khirnovf5e66822012-08-01 16:23:12121 o->recording_time = INT64_MAX;
122 o->limit_filesize = UINT64_MAX;
123 o->chapters_input_file = INT_MAX;
Anton Khirnov811bd072013-06-15 07:59:40124 o->accurate_seek = 1;
Anton Khirnovf5e66822012-08-01 16:23:12125}
126
Anton Khirnove7553f42013-02-21 09:58:46127/* return a copy of the input with the stream specifiers removed from the keys */
128static AVDictionary *strip_specifiers(AVDictionary *dict)
129{
130 AVDictionaryEntry *e = NULL;
131 AVDictionary *ret = NULL;
132
133 while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
134 char *p = strchr(e->key, ':');
135
136 if (p)
137 *p = 0;
138 av_dict_set(&ret, e->key, e->value, 0);
139 if (p)
140 *p = ':';
141 }
142 return ret;
143}
144
Anton Khirnovf5e66822012-08-01 16:23:12145static double parse_frame_aspect_ratio(const char *arg)
146{
147 int x = 0, y = 0;
148 double ar = 0;
149 const char *p;
150 char *end;
151
152 p = strchr(arg, ':');
153 if (p) {
154 x = strtol(arg, &end, 10);
155 if (end == p)
156 y = strtol(end + 1, &end, 10);
157 if (x > 0 && y > 0)
158 ar = (double)x / (double)y;
159 } else
160 ar = strtod(arg, NULL);
161
162 if (!ar) {
163 av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17164 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12165 }
166 return ar;
167}
168
Anton Khirnovd3810c42012-08-11 14:30:26169static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12170{
Anton Khirnovd3810c42012-08-11 14:30:26171 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12172 return parse_option(o, "codec:a", arg, options);
173}
174
Anton Khirnovd3810c42012-08-11 14:30:26175static int opt_video_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:v", arg, options);
179}
180
Anton Khirnovd3810c42012-08-11 14:30:26181static int opt_subtitle_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:s", arg, options);
185}
186
Anton Khirnovd3810c42012-08-11 14:30:26187static int opt_data_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:d", arg, options);
191}
192
Anton Khirnovd3810c42012-08-11 14:30:26193static int opt_map(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 StreamMap *m = NULL;
197 int i, negative = 0, file_idx;
198 int sync_file_idx = -1, sync_stream_idx;
199 char *p, *sync;
200 char *map;
201
202 if (*arg == '-') {
203 negative = 1;
204 arg++;
205 }
206 map = av_strdup(arg);
207
208 /* parse sync stream first, just pick first matching stream */
209 if (sync = strchr(map, ',')) {
210 *sync = 0;
211 sync_file_idx = strtol(sync + 1, &sync, 0);
212 if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
213 av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
Martin Storsjöb85dbe62013-07-31 10:44:17214 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12215 }
216 if (*sync)
217 sync++;
218 for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
219 if (check_stream_specifier(input_files[sync_file_idx]->ctx,
220 input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
221 sync_stream_idx = i;
222 break;
223 }
224 if (i == input_files[sync_file_idx]->nb_streams) {
225 av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
226 "match any streams.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17227 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12228 }
229 }
230
231
232 if (map[0] == '[') {
233 /* this mapping refers to lavfi output */
234 const char *c = map + 1;
Anton Khirnov10bca662012-06-07 19:52:07235 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
Anton Khirnovf5e66822012-08-01 16:23:12236 m = &o->stream_maps[o->nb_stream_maps - 1];
237 m->linklabel = av_get_token(&c, "]");
238 if (!m->linklabel) {
239 av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
Martin Storsjöb85dbe62013-07-31 10:44:17240 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12241 }
242 } else {
243 file_idx = strtol(map, &p, 0);
244 if (file_idx >= nb_input_files || file_idx < 0) {
245 av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
Martin Storsjöb85dbe62013-07-31 10:44:17246 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12247 }
248 if (negative)
249 /* disable some already defined maps */
250 for (i = 0; i < o->nb_stream_maps; i++) {
251 m = &o->stream_maps[i];
252 if (file_idx == m->file_index &&
253 check_stream_specifier(input_files[m->file_index]->ctx,
254 input_files[m->file_index]->ctx->streams[m->stream_index],
255 *p == ':' ? p + 1 : p) > 0)
256 m->disabled = 1;
257 }
258 else
259 for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
260 if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
261 *p == ':' ? p + 1 : p) <= 0)
262 continue;
Anton Khirnov10bca662012-06-07 19:52:07263 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
Anton Khirnovf5e66822012-08-01 16:23:12264 m = &o->stream_maps[o->nb_stream_maps - 1];
265
266 m->file_index = file_idx;
267 m->stream_index = i;
268
269 if (sync_file_idx >= 0) {
270 m->sync_file_index = sync_file_idx;
271 m->sync_stream_index = sync_stream_idx;
272 } else {
273 m->sync_file_index = file_idx;
274 m->sync_stream_index = i;
275 }
276 }
277 }
278
279 if (!m) {
280 av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17281 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12282 }
283
284 av_freep(&map);
285 return 0;
286}
287
Anton Khirnovd3810c42012-08-11 14:30:26288static int opt_attach(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12289{
Anton Khirnovd3810c42012-08-11 14:30:26290 OptionsContext *o = optctx;
Anton Khirnov10bca662012-06-07 19:52:07291 GROW_ARRAY(o->attachments, o->nb_attachments);
Anton Khirnovf5e66822012-08-01 16:23:12292 o->attachments[o->nb_attachments - 1] = arg;
293 return 0;
294}
295
296/**
Diego Biurrunc1ef30a2012-08-24 11:31:50297 * Parse a metadata specifier passed as 'arg' parameter.
Diego Biurrun02e42752012-10-24 17:20:13298 * @param arg metadata string to parse
Anton Khirnovf5e66822012-08-01 16:23:12299 * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
300 * @param index for type c/p, chapter/program index is written here
301 * @param stream_spec for type s, the stream specifier is written here
302 */
303static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
304{
305 if (*arg) {
306 *type = *arg;
307 switch (*arg) {
308 case 'g':
309 break;
310 case 's':
311 if (*(++arg) && *arg != ':') {
312 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17313 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12314 }
315 *stream_spec = *arg == ':' ? arg + 1 : "";
316 break;
317 case 'c':
318 case 'p':
319 if (*(++arg) == ':')
320 *index = strtol(++arg, NULL, 0);
321 break;
322 default:
323 av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
Martin Storsjöb85dbe62013-07-31 10:44:17324 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12325 }
326 } else
327 *type = 'g';
328}
329
330static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
331{
332 AVDictionary **meta_in = NULL;
333 AVDictionary **meta_out;
334 int i, ret = 0;
335 char type_in, type_out;
336 const char *istream_spec = NULL, *ostream_spec = NULL;
337 int idx_in = 0, idx_out = 0;
338
339 parse_meta_type(inspec, &type_in, &idx_in, &istream_spec);
340 parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
341
342 if (type_in == 'g' || type_out == 'g')
343 o->metadata_global_manual = 1;
344 if (type_in == 's' || type_out == 's')
345 o->metadata_streams_manual = 1;
346 if (type_in == 'c' || type_out == 'c')
347 o->metadata_chapters_manual = 1;
348
Anton Khirnova119c642012-10-16 07:53:39349 /* ic is NULL when just disabling automatic mappings */
350 if (!ic)
351 return 0;
352
Anton Khirnovf5e66822012-08-01 16:23:12353#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
354 if ((index) < 0 || (index) >= (nb_elems)) {\
355 av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
356 (desc), (index));\
Martin Storsjöb85dbe62013-07-31 10:44:17357 exit_program(1);\
Anton Khirnovf5e66822012-08-01 16:23:12358 }
359
360#define SET_DICT(type, meta, context, index)\
361 switch (type) {\
362 case 'g':\
363 meta = &context->metadata;\
364 break;\
365 case 'c':\
366 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
367 meta = &context->chapters[index]->metadata;\
368 break;\
369 case 'p':\
370 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
371 meta = &context->programs[index]->metadata;\
372 break;\
Anton Khirnov4632abc2012-11-24 06:55:42373 case 's':\
374 break; /* handled separately below */ \
Anton Khirnovf5e66822012-08-01 16:23:12375 default: av_assert0(0);\
376 }\
377
378 SET_DICT(type_in, meta_in, ic, idx_in);
379 SET_DICT(type_out, meta_out, oc, idx_out);
380
381 /* for input streams choose first matching stream */
382 if (type_in == 's') {
383 for (i = 0; i < ic->nb_streams; i++) {
384 if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
385 meta_in = &ic->streams[i]->metadata;
386 break;
387 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:17388 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12389 }
390 if (!meta_in) {
391 av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
Martin Storsjöb85dbe62013-07-31 10:44:17392 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12393 }
394 }
395
396 if (type_out == 's') {
397 for (i = 0; i < oc->nb_streams; i++) {
398 if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
399 meta_out = &oc->streams[i]->metadata;
400 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
401 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:17402 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12403 }
404 } else
405 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
406
407 return 0;
408}
409
410static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
411{
Anton Khirnovdb4766a2012-08-11 13:40:12412 const AVCodecDescriptor *desc;
Anton Khirnovf5e66822012-08-01 16:23:12413 const char *codec_string = encoder ? "encoder" : "decoder";
414 AVCodec *codec;
415
416 codec = encoder ?
417 avcodec_find_encoder_by_name(name) :
418 avcodec_find_decoder_by_name(name);
Anton Khirnovdb4766a2012-08-11 13:40:12419
420 if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
421 codec = encoder ? avcodec_find_encoder(desc->id) :
422 avcodec_find_decoder(desc->id);
423 if (codec)
424 av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
425 codec_string, codec->name, desc->name);
426 }
427
Anton Khirnovf5e66822012-08-01 16:23:12428 if (!codec) {
429 av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
Martin Storsjöb85dbe62013-07-31 10:44:17430 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12431 }
432 if (codec->type != type) {
433 av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
Martin Storsjöb85dbe62013-07-31 10:44:17434 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12435 }
436 return codec;
437}
438
439static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
440{
441 char *codec_name = NULL;
442
443 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
444 if (codec_name) {
445 AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
446 st->codec->codec_id = codec->id;
447 return codec;
448 } else
449 return avcodec_find_decoder(st->codec->codec_id);
450}
451
Diego Biurrunc1ef30a2012-08-24 11:31:50452/* Add all the streams from the given input file to the global
453 * list of input streams. */
Anton Khirnovf5e66822012-08-01 16:23:12454static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
455{
456 int i;
457
458 for (i = 0; i < ic->nb_streams; i++) {
459 AVStream *st = ic->streams[i];
460 AVCodecContext *dec = st->codec;
461 InputStream *ist = av_mallocz(sizeof(*ist));
Anton Khirnov07fd0a22013-11-02 21:06:36462 char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
Anton Khirnovf5e66822012-08-01 16:23:12463
464 if (!ist)
Martin Storsjöb85dbe62013-07-31 10:44:17465 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12466
Anton Khirnov10bca662012-06-07 19:52:07467 GROW_ARRAY(input_streams, nb_input_streams);
Anton Khirnovf5e66822012-08-01 16:23:12468 input_streams[nb_input_streams - 1] = ist;
469
470 ist->st = st;
471 ist->file_index = nb_input_files;
472 ist->discard = 1;
473 st->discard = AVDISCARD_ALL;
Anton Khirnovf5e66822012-08-01 16:23:12474
475 ist->ts_scale = 1.0;
476 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
477
478 ist->dec = choose_decoder(o, ic, st);
Anton Khirnove82cb792012-12-15 10:45:59479 ist->opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, ist->dec);
Anton Khirnovf5e66822012-08-01 16:23:12480
481 switch (dec->codec_type) {
482 case AVMEDIA_TYPE_VIDEO:
483 ist->resample_height = dec->height;
484 ist->resample_width = dec->width;
485 ist->resample_pix_fmt = dec->pix_fmt;
486
487 MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
488 if (framerate && av_parse_video_rate(&ist->framerate,
489 framerate) < 0) {
490 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
491 framerate);
Martin Storsjöb85dbe62013-07-31 10:44:17492 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12493 }
494
Anton Khirnov07fd0a22013-11-02 21:06:36495 MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
496 if (hwaccel) {
497 if (!strcmp(hwaccel, "none"))
498 ist->hwaccel_id = HWACCEL_NONE;
499 else if (!strcmp(hwaccel, "auto"))
500 ist->hwaccel_id = HWACCEL_AUTO;
501 else {
502 int i;
503 for (i = 0; hwaccels[i].name; i++) {
504 if (!strcmp(hwaccels[i].name, hwaccel)) {
505 ist->hwaccel_id = hwaccels[i].id;
506 break;
507 }
508 }
509
510 if (!ist->hwaccel_id) {
511 av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
512 hwaccel);
513 av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
514 for (i = 0; hwaccels[i].name; i++)
515 av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
516 av_log(NULL, AV_LOG_FATAL, "\n");
517 exit_program(1);
518 }
519 }
520 }
521
522 MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
523 if (hwaccel_device) {
524 ist->hwaccel_device = av_strdup(hwaccel_device);
525 if (!ist->hwaccel_device)
526 exit_program(1);
527 }
528
Anton Khirnovf5e66822012-08-01 16:23:12529 break;
530 case AVMEDIA_TYPE_AUDIO:
531 guess_input_channel_layout(ist);
532
533 ist->resample_sample_fmt = dec->sample_fmt;
534 ist->resample_sample_rate = dec->sample_rate;
535 ist->resample_channels = dec->channels;
536 ist->resample_channel_layout = dec->channel_layout;
537
538 break;
539 case AVMEDIA_TYPE_DATA:
540 case AVMEDIA_TYPE_SUBTITLE:
541 case AVMEDIA_TYPE_ATTACHMENT:
542 case AVMEDIA_TYPE_UNKNOWN:
543 break;
544 default:
545 abort();
546 }
547 }
548}
549
550static void assert_file_overwrite(const char *filename)
551{
Vittorio Giovara7748dd42013-07-31 12:48:49552 if (file_overwrite && file_skip) {
553 fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
554 exit_program(1);
555 }
556
Anton Khirnovf5e66822012-08-01 16:23:12557 if (!file_overwrite &&
558 (strchr(filename, ':') == NULL || filename[1] == ':' ||
559 av_strstart(filename, "file:", NULL))) {
560 if (avio_check(filename, 0) == 0) {
Vittorio Giovara7748dd42013-07-31 12:48:49561 if (!using_stdin && !file_skip) {
Anton Khirnovf5e66822012-08-01 16:23:12562 fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
563 fflush(stderr);
564 if (!read_yesno()) {
565 fprintf(stderr, "Not overwriting - exiting\n");
Martin Storsjöb85dbe62013-07-31 10:44:17566 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12567 }
568 }
569 else {
570 fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
Martin Storsjöb85dbe62013-07-31 10:44:17571 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12572 }
573 }
574 }
575}
576
577static void dump_attachment(AVStream *st, const char *filename)
578{
579 int ret;
580 AVIOContext *out = NULL;
581 AVDictionaryEntry *e;
582
583 if (!st->codec->extradata_size) {
584 av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
585 nb_input_files - 1, st->index);
586 return;
587 }
588 if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
589 filename = e->value;
590 if (!*filename) {
591 av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
592 "in stream #%d:%d.\n", nb_input_files - 1, st->index);
Martin Storsjöb85dbe62013-07-31 10:44:17593 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12594 }
595
596 assert_file_overwrite(filename);
597
598 if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
599 av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
600 filename);
Martin Storsjöb85dbe62013-07-31 10:44:17601 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12602 }
603
604 avio_write(out, st->codec->extradata, st->codec->extradata_size);
605 avio_flush(out);
606 avio_close(out);
607}
608
Anton Khirnov77bd1bc2012-06-08 19:35:16609static int open_input_file(OptionsContext *o, const char *filename)
Anton Khirnovf5e66822012-08-01 16:23:12610{
Anton Khirnov41d20082013-02-21 08:53:28611 InputFile *f;
Anton Khirnovf5e66822012-08-01 16:23:12612 AVFormatContext *ic;
613 AVInputFormat *file_iformat = NULL;
614 int err, i, ret;
615 int64_t timestamp;
616 uint8_t buf[128];
617 AVDictionary **opts;
Anton Khirnove7553f42013-02-21 09:58:46618 AVDictionary *unused_opts = NULL;
619 AVDictionaryEntry *e = NULL;
Anton Khirnovf5e66822012-08-01 16:23:12620 int orig_nb_streams; // number of streams before avformat_find_stream_info
621
622 if (o->format) {
623 if (!(file_iformat = av_find_input_format(o->format))) {
624 av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
Martin Storsjöb85dbe62013-07-31 10:44:17625 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12626 }
627 }
628
629 if (!strcmp(filename, "-"))
630 filename = "pipe:";
631
632 using_stdin |= !strncmp(filename, "pipe:", 5) ||
633 !strcmp(filename, "/dev/stdin");
634
635 /* get default parameters from command line */
636 ic = avformat_alloc_context();
637 if (!ic) {
638 print_error(filename, AVERROR(ENOMEM));
Martin Storsjöb85dbe62013-07-31 10:44:17639 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12640 }
641 if (o->nb_audio_sample_rate) {
642 snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
Anton Khirnov77bd1bc2012-06-08 19:35:16643 av_dict_set(&o->g->format_opts, "sample_rate", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:12644 }
645 if (o->nb_audio_channels) {
646 /* because we set audio_channels based on both the "ac" and
647 * "channel_layout" options, we need to check that the specified
648 * demuxer actually has the "channels" option before setting it */
649 if (file_iformat && file_iformat->priv_class &&
650 av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
651 AV_OPT_SEARCH_FAKE_OBJ)) {
652 snprintf(buf, sizeof(buf), "%d",
653 o->audio_channels[o->nb_audio_channels - 1].u.i);
Anton Khirnov77bd1bc2012-06-08 19:35:16654 av_dict_set(&o->g->format_opts, "channels", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:12655 }
656 }
657 if (o->nb_frame_rates) {
658 /* set the format-level framerate option;
659 * this is important for video grabbers, e.g. x11 */
660 if (file_iformat && file_iformat->priv_class &&
661 av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
662 AV_OPT_SEARCH_FAKE_OBJ)) {
Anton Khirnov77bd1bc2012-06-08 19:35:16663 av_dict_set(&o->g->format_opts, "framerate",
Anton Khirnovf5e66822012-08-01 16:23:12664 o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
665 }
666 }
667 if (o->nb_frame_sizes) {
Anton Khirnov77bd1bc2012-06-08 19:35:16668 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:12669 }
670 if (o->nb_frame_pix_fmts)
Anton Khirnov77bd1bc2012-06-08 19:35:16671 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:12672
673 ic->flags |= AVFMT_FLAG_NONBLOCK;
674 ic->interrupt_callback = int_cb;
675
676 /* open the input file with generic libav function */
Anton Khirnov77bd1bc2012-06-08 19:35:16677 err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
Anton Khirnovf5e66822012-08-01 16:23:12678 if (err < 0) {
679 print_error(filename, err);
Martin Storsjöb85dbe62013-07-31 10:44:17680 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12681 }
Anton Khirnov77bd1bc2012-06-08 19:35:16682 assert_avoptions(o->g->format_opts);
Anton Khirnovf5e66822012-08-01 16:23:12683
684 /* apply forced codec ids */
685 for (i = 0; i < ic->nb_streams; i++)
686 choose_decoder(o, ic, ic->streams[i]);
687
688 /* Set AVCodecContext options for avformat_find_stream_info */
Anton Khirnov77bd1bc2012-06-08 19:35:16689 opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
Anton Khirnovf5e66822012-08-01 16:23:12690 orig_nb_streams = ic->nb_streams;
691
692 /* If not enough info to get the stream parameters, we decode the
693 first frames to get it. (used in mpeg case for example) */
694 ret = avformat_find_stream_info(ic, opts);
695 if (ret < 0) {
696 av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
697 avformat_close_input(&ic);
Martin Storsjöb85dbe62013-07-31 10:44:17698 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12699 }
700
Anton Khirnov56ee3f92013-06-15 07:35:10701 timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
Anton Khirnovf5e66822012-08-01 16:23:12702 /* add the stream start time */
703 if (ic->start_time != AV_NOPTS_VALUE)
704 timestamp += ic->start_time;
705
706 /* if seeking requested, we execute it */
Anton Khirnov56ee3f92013-06-15 07:35:10707 if (o->start_time != AV_NOPTS_VALUE) {
Anton Khirnovf5e66822012-08-01 16:23:12708 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
709 if (ret < 0) {
710 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
711 filename, (double)timestamp / AV_TIME_BASE);
712 }
713 }
714
715 /* update the current parameters so that they match the one of the input stream */
716 add_input_streams(o, ic);
717
718 /* dump the file content */
719 av_dump_format(ic, nb_input_files, filename, 0);
720
Anton Khirnov10bca662012-06-07 19:52:07721 GROW_ARRAY(input_files, nb_input_files);
Anton Khirnov41d20082013-02-21 08:53:28722 f = av_mallocz(sizeof(*f));
723 if (!f)
Martin Storsjöb85dbe62013-07-31 10:44:17724 exit_program(1);
Anton Khirnov41d20082013-02-21 08:53:28725 input_files[nb_input_files - 1] = f;
Anton Khirnovf5e66822012-08-01 16:23:12726
Anton Khirnov41d20082013-02-21 08:53:28727 f->ctx = ic;
728 f->ist_index = nb_input_streams - ic->nb_streams;
Anton Khirnov811bd072013-06-15 07:59:40729 f->start_time = o->start_time;
Anton Khirnov488a0fa2013-06-18 09:12:09730 f->recording_time = o->recording_time;
Anton Khirnov41d20082013-02-21 08:53:28731 f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
732 f->nb_streams = ic->nb_streams;
733 f->rate_emu = o->rate_emu;
Anton Khirnov811bd072013-06-15 07:59:40734 f->accurate_seek = o->accurate_seek;
Anton Khirnovf5e66822012-08-01 16:23:12735
Anton Khirnove7553f42013-02-21 09:58:46736 /* check if all codec options have been used */
737 unused_opts = strip_specifiers(o->g->codec_opts);
738 for (i = f->ist_index; i < nb_input_streams; i++) {
739 e = NULL;
740 while ((e = av_dict_get(input_streams[i]->opts, "", e,
741 AV_DICT_IGNORE_SUFFIX)))
742 av_dict_set(&unused_opts, e->key, NULL, 0);
743 }
744
745 e = NULL;
746 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
747 const AVClass *class = avcodec_get_class();
748 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
749 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
750 if (!option)
751 continue;
752 if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
753 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
754 "input file #%d (%s) is not a decoding option.\n", e->key,
755 option->help ? option->help : "", nb_input_files - 1,
756 filename);
Martin Storsjöb85dbe62013-07-31 10:44:17757 exit_program(1);
Anton Khirnove7553f42013-02-21 09:58:46758 }
759
760 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
761 "input file #%d (%s) has not been used for any stream. The most "
762 "likely reason is either wrong type (e.g. a video option with "
763 "no video streams) or that it is a private option of some decoder "
764 "which was not actually used for any stream.\n", e->key,
765 option->help ? option->help : "", nb_input_files - 1, filename);
766 }
767 av_dict_free(&unused_opts);
768
Anton Khirnovf5e66822012-08-01 16:23:12769 for (i = 0; i < o->nb_dump_attachment; i++) {
770 int j;
771
772 for (j = 0; j < ic->nb_streams; j++) {
773 AVStream *st = ic->streams[j];
774
775 if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
776 dump_attachment(st, o->dump_attachment[i].u.str);
777 }
778 }
779
780 for (i = 0; i < orig_nb_streams; i++)
781 av_dict_free(&opts[i]);
782 av_freep(&opts);
783
Anton Khirnovf5e66822012-08-01 16:23:12784 return 0;
785}
786
787static uint8_t *get_line(AVIOContext *s)
788{
789 AVIOContext *line;
790 uint8_t *buf;
791 char c;
792
793 if (avio_open_dyn_buf(&line) < 0) {
794 av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17795 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12796 }
797
798 while ((c = avio_r8(s)) && c != '\n')
799 avio_w8(line, c);
800 avio_w8(line, 0);
801 avio_close_dyn_buf(line, &buf);
802
803 return buf;
804}
805
806static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
807{
808 int i, ret = 1;
809 char filename[1000];
810 const char *base[3] = { getenv("AVCONV_DATADIR"),
811 getenv("HOME"),
812 AVCONV_DATADIR,
813 };
814
815 for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
816 if (!base[i])
817 continue;
818 if (codec_name) {
819 snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
820 i != 1 ? "" : "/.avconv", codec_name, preset_name);
821 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
822 }
823 if (ret) {
824 snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
825 i != 1 ? "" : "/.avconv", preset_name);
826 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
827 }
828 }
829 return ret;
830}
831
832static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
833{
834 char *codec_name = NULL;
835
836 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
837 if (!codec_name) {
838 ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
839 NULL, ost->st->codec->codec_type);
840 ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
841 } else if (!strcmp(codec_name, "copy"))
842 ost->stream_copy = 1;
843 else {
844 ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
845 ost->st->codec->codec_id = ost->enc->id;
846 }
847}
848
849static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
850{
851 OutputStream *ost;
852 AVStream *st = avformat_new_stream(oc, NULL);
853 int idx = oc->nb_streams - 1, ret = 0;
854 char *bsf = NULL, *next, *codec_tag = NULL;
855 AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
856 double qscale = -1;
Anton Khirnovf5e66822012-08-01 16:23:12857
858 if (!st) {
859 av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17860 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12861 }
862
863 if (oc->nb_streams - 1 < o->nb_streamid_map)
864 st->id = o->streamid_map[oc->nb_streams - 1];
865
Anton Khirnov10bca662012-06-07 19:52:07866 GROW_ARRAY(output_streams, nb_output_streams);
Anton Khirnovf5e66822012-08-01 16:23:12867 if (!(ost = av_mallocz(sizeof(*ost))))
Martin Storsjöb85dbe62013-07-31 10:44:17868 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12869 output_streams[nb_output_streams - 1] = ost;
870
Anton Khirnov3d624422013-04-10 12:46:20871 ost->file_index = nb_output_files - 1;
Anton Khirnovf5e66822012-08-01 16:23:12872 ost->index = idx;
873 ost->st = st;
874 st->codec->codec_type = type;
875 choose_encoder(o, oc, ost);
876 if (ost->enc) {
Anton Khirnov4e61a382012-10-22 20:40:22877 AVIOContext *s = NULL;
878 char *buf = NULL, *arg = NULL, *preset = NULL;
879
Anton Khirnov77bd1bc2012-06-08 19:35:16880 ost->opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
Anton Khirnov4e61a382012-10-22 20:40:22881
882 MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
883 if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
884 do {
885 buf = get_line(s);
886 if (!buf[0] || buf[0] == '#') {
887 av_free(buf);
888 continue;
889 }
890 if (!(arg = strchr(buf, '='))) {
891 av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17892 exit_program(1);
Anton Khirnov4e61a382012-10-22 20:40:22893 }
894 *arg++ = 0;
895 av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
896 av_free(buf);
897 } while (!s->eof_reached);
898 avio_close(s);
899 }
900 if (ret) {
901 av_log(NULL, AV_LOG_FATAL,
902 "Preset %s specified for stream %d:%d, but could not be opened.\n",
903 preset, ost->file_index, ost->index);
Martin Storsjöb85dbe62013-07-31 10:44:17904 exit_program(1);
Anton Khirnov4e61a382012-10-22 20:40:22905 }
Martin Storsjödf0229a2013-02-27 21:22:39906 } else {
907 ost->opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
Anton Khirnovf5e66822012-08-01 16:23:12908 }
909
910 avcodec_get_context_defaults3(st->codec, ost->enc);
911 st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
912
Anton Khirnovf5e66822012-08-01 16:23:12913 ost->max_frames = INT64_MAX;
914 MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
915
916 MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
917 while (bsf) {
918 if (next = strchr(bsf, ','))
919 *next++ = 0;
920 if (!(bsfc = av_bitstream_filter_init(bsf))) {
921 av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
Martin Storsjöb85dbe62013-07-31 10:44:17922 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12923 }
924 if (bsfc_prev)
925 bsfc_prev->next = bsfc;
926 else
927 ost->bitstream_filters = bsfc;
928
929 bsfc_prev = bsfc;
930 bsf = next;
931 }
932
933 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
934 if (codec_tag) {
935 uint32_t tag = strtol(codec_tag, &next, 0);
936 if (*next)
937 tag = AV_RL32(codec_tag);
938 st->codec->codec_tag = tag;
939 }
940
941 MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
Anton Khirnovfb722a92012-10-09 15:40:20942 if (qscale >= 0) {
Anton Khirnovf5e66822012-08-01 16:23:12943 st->codec->flags |= CODEC_FLAG_QSCALE;
944 st->codec->global_quality = FF_QP2LAMBDA * qscale;
945 }
946
947 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
948 st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
949
Anton Khirnov77bd1bc2012-06-08 19:35:16950 av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
Anton Khirnovf5e66822012-08-01 16:23:12951
Justin Ruggles5c7db092012-12-19 02:47:28952 av_dict_copy(&ost->resample_opts, o->g->resample_opts, 0);
953
Anton Khirnov716d4132012-10-06 10:10:34954 ost->pix_fmts[0] = ost->pix_fmts[1] = AV_PIX_FMT_NONE;
Anton Khirnov76d23f42013-04-24 06:34:44955 ost->last_mux_dts = AV_NOPTS_VALUE;
Anton Khirnovf5e66822012-08-01 16:23:12956
957 return ost;
958}
959
960static void parse_matrix_coeffs(uint16_t *dest, const char *str)
961{
962 int i;
963 const char *p = str;
964 for (i = 0;; i++) {
965 dest[i] = atoi(p);
966 if (i == 63)
967 break;
968 p = strchr(p, ',');
969 if (!p) {
970 av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
Martin Storsjöb85dbe62013-07-31 10:44:17971 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12972 }
973 p++;
974 }
975}
976
Anton Khirnova4208b92013-03-13 13:24:45977/* read file contents into a string */
978static uint8_t *read_file(const char *filename)
979{
980 AVIOContext *pb = NULL;
981 AVIOContext *dyn_buf = NULL;
982 int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
983 uint8_t buf[1024], *str;
984
985 if (ret < 0) {
986 av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
987 return NULL;
988 }
989
990 ret = avio_open_dyn_buf(&dyn_buf);
991 if (ret < 0) {
992 avio_closep(&pb);
993 return NULL;
994 }
995 while ((ret = avio_read(pb, buf, sizeof(buf))) > 0)
996 avio_write(dyn_buf, buf, ret);
997 avio_w8(dyn_buf, 0);
998 avio_closep(&pb);
999
1000 ret = avio_close_dyn_buf(dyn_buf, &str);
1001 if (ret < 0)
1002 return NULL;
1003 return str;
1004}
1005
1006static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
1007 OutputStream *ost)
1008{
1009 AVStream *st = ost->st;
1010 char *filter = NULL, *filter_script = NULL;
1011
1012 MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
1013 MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
1014
1015 if (filter_script && filter) {
1016 av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
1017 "output stream #%d:%d.\n", nb_output_files, st->index);
Martin Storsjöb85dbe62013-07-31 10:44:171018 exit_program(1);
Anton Khirnova4208b92013-03-13 13:24:451019 }
1020
1021 if (filter_script)
1022 return read_file(filter_script);
1023 else if (filter)
1024 return av_strdup(filter);
1025
1026 return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
1027 "null" : "anull");
1028}
1029
Anton Khirnovf5e66822012-08-01 16:23:121030static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
1031{
1032 AVStream *st;
1033 OutputStream *ost;
1034 AVCodecContext *video_enc;
Anton Khirnov538bf762013-05-26 13:31:091035 char *frame_aspect_ratio = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121036
1037 ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
1038 st = ost->st;
1039 video_enc = st->codec;
1040
Anton Khirnov538bf762013-05-26 13:31:091041 MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
1042 if (frame_aspect_ratio)
1043 ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio);
1044
Anton Khirnovf5e66822012-08-01 16:23:121045 if (!ost->stream_copy) {
1046 const char *p = NULL;
1047 char *frame_rate = NULL, *frame_size = NULL;
Anton Khirnov538bf762013-05-26 13:31:091048 char *frame_pix_fmt = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121049 char *intra_matrix = NULL, *inter_matrix = NULL;
Anton Khirnov038c0b12012-08-19 06:29:441050 int do_pass = 0;
Anton Khirnovf5e66822012-08-01 16:23:121051 int i;
1052
1053 MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
1054 if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
1055 av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
Martin Storsjöb85dbe62013-07-31 10:44:171056 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121057 }
1058
1059 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
1060 if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
1061 av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
Martin Storsjöb85dbe62013-07-31 10:44:171062 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121063 }
1064
Anton Khirnovf5e66822012-08-01 16:23:121065 MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
Anton Khirnov716d4132012-10-06 10:10:341066 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:121067 av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
Martin Storsjöb85dbe62013-07-31 10:44:171068 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121069 }
1070 st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
1071
1072 MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
1073 if (intra_matrix) {
1074 if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
1075 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171076 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121077 }
1078 parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
1079 }
1080 MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
1081 if (inter_matrix) {
1082 if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
1083 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171084 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121085 }
1086 parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
1087 }
1088
1089 MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
1090 for (i = 0; p; i++) {
1091 int start, end, q;
1092 int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
1093 if (e != 3) {
1094 av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
Martin Storsjöb85dbe62013-07-31 10:44:171095 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121096 }
1097 video_enc->rc_override =
1098 av_realloc(video_enc->rc_override,
1099 sizeof(RcOverride) * (i + 1));
1100 video_enc->rc_override[i].start_frame = start;
1101 video_enc->rc_override[i].end_frame = end;
1102 if (q > 0) {
1103 video_enc->rc_override[i].qscale = q;
1104 video_enc->rc_override[i].quality_factor = 1.0;
1105 }
1106 else {
1107 video_enc->rc_override[i].qscale = 0;
1108 video_enc->rc_override[i].quality_factor = -q/100.0;
1109 }
1110 p = strchr(p, '/');
1111 if (p) p++;
1112 }
1113 video_enc->rc_override_count = i;
Anton Khirnovf5e66822012-08-01 16:23:121114 video_enc->intra_dc_precision = intra_dc_precision - 8;
1115
1116 /* two pass mode */
Anton Khirnov038c0b12012-08-19 06:29:441117 MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
Anton Khirnovf5e66822012-08-01 16:23:121118 if (do_pass) {
1119 if (do_pass == 1) {
1120 video_enc->flags |= CODEC_FLAG_PASS1;
1121 } else {
1122 video_enc->flags |= CODEC_FLAG_PASS2;
1123 }
1124 }
1125
Anton Khirnovbbcedad2012-08-19 07:15:481126 MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
1127 if (ost->logfile_prefix &&
1128 !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
Martin Storsjöb85dbe62013-07-31 10:44:171129 exit_program(1);
Anton Khirnovbbcedad2012-08-19 07:15:481130
Anton Khirnovf5e66822012-08-01 16:23:121131 MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
1132 if (ost->forced_keyframes)
1133 ost->forced_keyframes = av_strdup(ost->forced_keyframes);
1134
1135 MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
1136
1137 ost->top_field_first = -1;
1138 MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
1139
Anton Khirnova4208b92013-03-13 13:24:451140
1141 ost->avfilter = get_ost_filters(o, oc, ost);
1142 if (!ost->avfilter)
Martin Storsjöb85dbe62013-07-31 10:44:171143 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121144 } else {
1145 MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
1146 }
1147
1148 return ost;
1149}
1150
1151static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
1152{
1153 AVStream *st;
1154 OutputStream *ost;
1155 AVCodecContext *audio_enc;
1156
1157 ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO);
1158 st = ost->st;
1159
1160 audio_enc = st->codec;
1161 audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
1162
1163 if (!ost->stream_copy) {
1164 char *sample_fmt = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121165
1166 MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
1167
1168 MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
1169 if (sample_fmt &&
1170 (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
1171 av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
Martin Storsjöb85dbe62013-07-31 10:44:171172 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121173 }
1174
1175 MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
1176
Anton Khirnova4208b92013-03-13 13:24:451177 ost->avfilter = get_ost_filters(o, oc, ost);
1178 if (!ost->avfilter)
Martin Storsjöb85dbe62013-07-31 10:44:171179 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121180 }
1181
1182 return ost;
1183}
1184
1185static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
1186{
1187 OutputStream *ost;
1188
1189 ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
1190 if (!ost->stream_copy) {
1191 av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
Martin Storsjöb85dbe62013-07-31 10:44:171192 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121193 }
1194
1195 return ost;
1196}
1197
1198static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc)
1199{
1200 OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
1201 ost->stream_copy = 1;
Anton Khirnov3e175a22013-03-14 08:44:071202 ost->finished = 1;
Anton Khirnovf5e66822012-08-01 16:23:121203 return ost;
1204}
1205
1206static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
1207{
1208 AVStream *st;
1209 OutputStream *ost;
1210 AVCodecContext *subtitle_enc;
1211
1212 ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE);
1213 st = ost->st;
1214 subtitle_enc = st->codec;
1215
1216 subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
1217
1218 return ost;
1219}
1220
1221/* arg format is "output-stream-index:streamid-value". */
Anton Khirnovd3810c42012-08-11 14:30:261222static int opt_streamid(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121223{
Anton Khirnovd3810c42012-08-11 14:30:261224 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121225 int idx;
1226 char *p;
1227 char idx_str[16];
1228
1229 av_strlcpy(idx_str, arg, sizeof(idx_str));
1230 p = strchr(idx_str, ':');
1231 if (!p) {
1232 av_log(NULL, AV_LOG_FATAL,
1233 "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
1234 arg, opt);
Martin Storsjöb85dbe62013-07-31 10:44:171235 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121236 }
1237 *p++ = '\0';
1238 idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
1239 o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
1240 o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
1241 return 0;
1242}
1243
1244static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
1245{
1246 AVFormatContext *is = ifile->ctx;
1247 AVFormatContext *os = ofile->ctx;
Janne Grunau18ff4d22012-10-09 13:20:151248 AVChapter **tmp;
Anton Khirnovf5e66822012-08-01 16:23:121249 int i;
1250
Janne Grunau18ff4d22012-10-09 13:20:151251 tmp = av_realloc(os->chapters, sizeof(*os->chapters) * (is->nb_chapters + os->nb_chapters));
1252 if (!tmp)
1253 return AVERROR(ENOMEM);
1254 os->chapters = tmp;
1255
Anton Khirnovf5e66822012-08-01 16:23:121256 for (i = 0; i < is->nb_chapters; i++) {
1257 AVChapter *in_ch = is->chapters[i], *out_ch;
Anton Khirnov56ee3f92013-06-15 07:35:101258 int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
1259 int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
Anton Khirnovf5e66822012-08-01 16:23:121260 AV_TIME_BASE_Q, in_ch->time_base);
1261 int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
1262 av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
1263
1264
1265 if (in_ch->end < ts_off)
1266 continue;
1267 if (rt != INT64_MAX && in_ch->start > rt + ts_off)
1268 break;
1269
1270 out_ch = av_mallocz(sizeof(AVChapter));
1271 if (!out_ch)
1272 return AVERROR(ENOMEM);
1273
1274 out_ch->id = in_ch->id;
1275 out_ch->time_base = in_ch->time_base;
1276 out_ch->start = FFMAX(0, in_ch->start - ts_off);
1277 out_ch->end = FFMIN(rt, in_ch->end - ts_off);
1278
1279 if (copy_metadata)
1280 av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
1281
Janne Grunau18ff4d22012-10-09 13:20:151282 os->chapters[os->nb_chapters++] = out_ch;
Anton Khirnovf5e66822012-08-01 16:23:121283 }
1284 return 0;
1285}
1286
1287static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
1288 AVFormatContext *oc)
1289{
1290 OutputStream *ost;
1291
1292 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1293 ofilter->out_tmp->pad_idx)) {
1294 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1295 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1296 default:
1297 av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
1298 "currently.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171299 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121300 }
1301
1302 ost->source_index = -1;
1303 ost->filter = ofilter;
1304
1305 ofilter->ost = ost;
1306
1307 if (ost->stream_copy) {
1308 av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
1309 "which is fed from a complex filtergraph. Filtering and streamcopy "
1310 "cannot be used together.\n", ost->file_index, ost->index);
Martin Storsjöb85dbe62013-07-31 10:44:171311 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121312 }
1313
1314 if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
1315 av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171316 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121317 }
1318 avfilter_inout_free(&ofilter->out_tmp);
1319}
1320
1321static int configure_complex_filters(void)
1322{
1323 int i, ret = 0;
1324
1325 for (i = 0; i < nb_filtergraphs; i++)
1326 if (!filtergraphs[i]->graph &&
1327 (ret = configure_filtergraph(filtergraphs[i])) < 0)
1328 return ret;
1329 return 0;
1330}
1331
Anton Khirnov77bd1bc2012-06-08 19:35:161332static int open_output_file(OptionsContext *o, const char *filename)
Anton Khirnovf5e66822012-08-01 16:23:121333{
Anton Khirnovf5e66822012-08-01 16:23:121334 AVFormatContext *oc;
1335 int i, j, err;
1336 AVOutputFormat *file_oformat;
Anton Khirnov1da54e92013-02-21 08:53:281337 OutputFile *of;
Anton Khirnovf5e66822012-08-01 16:23:121338 OutputStream *ost;
1339 InputStream *ist;
Anton Khirnove7553f42013-02-21 09:58:461340 AVDictionary *unused_opts = NULL;
1341 AVDictionaryEntry *e = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121342
1343 if (configure_complex_filters() < 0) {
1344 av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171345 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121346 }
1347
Anton Khirnov3d624422013-04-10 12:46:201348 GROW_ARRAY(output_files, nb_output_files);
1349 of = av_mallocz(sizeof(*of));
1350 if (!of)
Martin Storsjöb85dbe62013-07-31 10:44:171351 exit_program(1);
Anton Khirnov3d624422013-04-10 12:46:201352 output_files[nb_output_files - 1] = of;
1353
1354 of->ost_index = nb_output_streams;
1355 of->recording_time = o->recording_time;
1356 of->start_time = o->start_time;
1357 of->limit_filesize = o->limit_filesize;
1358 of->shortest = o->shortest;
1359 av_dict_copy(&of->opts, o->g->format_opts, 0);
1360
Anton Khirnovf5e66822012-08-01 16:23:121361 if (!strcmp(filename, "-"))
1362 filename = "pipe:";
1363
1364 oc = avformat_alloc_context();
1365 if (!oc) {
1366 print_error(filename, AVERROR(ENOMEM));
Martin Storsjöb85dbe62013-07-31 10:44:171367 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121368 }
Anton Khirnov3d624422013-04-10 12:46:201369 of->ctx = oc;
1370 if (o->recording_time != INT64_MAX)
1371 oc->duration = o->recording_time;
Anton Khirnovf5e66822012-08-01 16:23:121372
1373 if (o->format) {
1374 file_oformat = av_guess_format(o->format, NULL, NULL);
1375 if (!file_oformat) {
1376 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:171377 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121378 }
1379 } else {
1380 file_oformat = av_guess_format(NULL, filename, NULL);
1381 if (!file_oformat) {
1382 av_log(NULL, AV_LOG_FATAL, "Unable to find a suitable output format for '%s'\n",
1383 filename);
Martin Storsjöb85dbe62013-07-31 10:44:171384 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121385 }
1386 }
1387
1388 oc->oformat = file_oformat;
1389 oc->interrupt_callback = int_cb;
1390 av_strlcpy(oc->filename, filename, sizeof(oc->filename));
1391
1392 /* create streams for all unlabeled output pads */
1393 for (i = 0; i < nb_filtergraphs; i++) {
1394 FilterGraph *fg = filtergraphs[i];
1395 for (j = 0; j < fg->nb_outputs; j++) {
1396 OutputFilter *ofilter = fg->outputs[j];
1397
1398 if (!ofilter->out_tmp || ofilter->out_tmp->name)
1399 continue;
1400
1401 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1402 ofilter->out_tmp->pad_idx)) {
1403 case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break;
1404 case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break;
1405 case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
1406 }
1407 init_output_filter(ofilter, o, oc);
1408 }
1409 }
1410
1411 if (!o->nb_stream_maps) {
1412 /* pick the "best" stream of each type */
1413#define NEW_STREAM(type, index)\
1414 if (index >= 0) {\
1415 ost = new_ ## type ## _stream(o, oc);\
1416 ost->source_index = index;\
1417 ost->sync_ist = input_streams[index];\
1418 input_streams[index]->discard = 0;\
1419 input_streams[index]->st->discard = AVDISCARD_NONE;\
1420 }
1421
1422 /* video: highest resolution */
1423 if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
1424 int area = 0, idx = -1;
1425 for (i = 0; i < nb_input_streams; i++) {
1426 ist = input_streams[i];
1427 if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
1428 ist->st->codec->width * ist->st->codec->height > area) {
1429 area = ist->st->codec->width * ist->st->codec->height;
1430 idx = i;
1431 }
1432 }
1433 NEW_STREAM(video, idx);
1434 }
1435
1436 /* audio: most channels */
1437 if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
1438 int channels = 0, idx = -1;
1439 for (i = 0; i < nb_input_streams; i++) {
1440 ist = input_streams[i];
1441 if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
1442 ist->st->codec->channels > channels) {
1443 channels = ist->st->codec->channels;
1444 idx = i;
1445 }
1446 }
1447 NEW_STREAM(audio, idx);
1448 }
1449
1450 /* subtitles: pick first */
1451 if (!o->subtitle_disable && oc->oformat->subtitle_codec != AV_CODEC_ID_NONE) {
1452 for (i = 0; i < nb_input_streams; i++)
1453 if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1454 NEW_STREAM(subtitle, i);
1455 break;
1456 }
1457 }
1458 /* do something with data? */
1459 } else {
1460 for (i = 0; i < o->nb_stream_maps; i++) {
1461 StreamMap *map = &o->stream_maps[i];
1462
1463 if (map->disabled)
1464 continue;
1465
1466 if (map->linklabel) {
1467 FilterGraph *fg;
1468 OutputFilter *ofilter = NULL;
1469 int j, k;
1470
1471 for (j = 0; j < nb_filtergraphs; j++) {
1472 fg = filtergraphs[j];
1473 for (k = 0; k < fg->nb_outputs; k++) {
1474 AVFilterInOut *out = fg->outputs[k]->out_tmp;
1475 if (out && !strcmp(out->name, map->linklabel)) {
1476 ofilter = fg->outputs[k];
1477 goto loop_end;
1478 }
1479 }
1480 }
1481loop_end:
1482 if (!ofilter) {
1483 av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
1484 "in any defined filter graph.\n", map->linklabel);
Martin Storsjöb85dbe62013-07-31 10:44:171485 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121486 }
1487 init_output_filter(ofilter, o, oc);
1488 } else {
1489 ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
1490 switch (ist->st->codec->codec_type) {
1491 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1492 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1493 case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
1494 case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break;
1495 case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
1496 default:
1497 av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
1498 map->file_index, map->stream_index);
Martin Storsjöb85dbe62013-07-31 10:44:171499 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121500 }
1501
1502 ost->source_index = input_files[map->file_index]->ist_index + map->stream_index;
1503 ost->sync_ist = input_streams[input_files[map->sync_file_index]->ist_index +
1504 map->sync_stream_index];
1505 ist->discard = 0;
1506 ist->st->discard = AVDISCARD_NONE;
1507 }
1508 }
1509 }
1510
1511 /* handle attached files */
1512 for (i = 0; i < o->nb_attachments; i++) {
1513 AVIOContext *pb;
1514 uint8_t *attachment;
1515 const char *p;
1516 int64_t len;
1517
1518 if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
1519 av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
1520 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171521 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121522 }
1523 if ((len = avio_size(pb)) <= 0) {
1524 av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
1525 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171526 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121527 }
1528 if (!(attachment = av_malloc(len))) {
1529 av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
1530 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171531 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121532 }
1533 avio_read(pb, attachment, len);
1534
1535 ost = new_attachment_stream(o, oc);
1536 ost->stream_copy = 0;
1537 ost->source_index = -1;
1538 ost->attachment_filename = o->attachments[i];
1539 ost->st->codec->extradata = attachment;
1540 ost->st->codec->extradata_size = len;
1541
1542 p = strrchr(o->attachments[i], '/');
1543 av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
1544 avio_close(pb);
1545 }
1546
Anton Khirnove7553f42013-02-21 09:58:461547 /* check if all codec options have been used */
1548 unused_opts = strip_specifiers(o->g->codec_opts);
1549 for (i = of->ost_index; i < nb_output_streams; i++) {
1550 e = NULL;
1551 while ((e = av_dict_get(output_streams[i]->opts, "", e,
1552 AV_DICT_IGNORE_SUFFIX)))
1553 av_dict_set(&unused_opts, e->key, NULL, 0);
1554 }
1555
1556 e = NULL;
1557 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
1558 const AVClass *class = avcodec_get_class();
1559 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
1560 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1561 if (!option)
1562 continue;
1563 if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
1564 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
1565 "output file #%d (%s) is not an encoding option.\n", e->key,
1566 option->help ? option->help : "", nb_output_files - 1,
1567 filename);
Martin Storsjöb85dbe62013-07-31 10:44:171568 exit_program(1);
Anton Khirnove7553f42013-02-21 09:58:461569 }
1570
1571 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
1572 "output file #%d (%s) has not been used for any stream. The most "
1573 "likely reason is either wrong type (e.g. a video option with "
1574 "no video streams) or that it is a private option of some encoder "
1575 "which was not actually used for any stream.\n", e->key,
1576 option->help ? option->help : "", nb_output_files - 1, filename);
1577 }
1578 av_dict_free(&unused_opts);
1579
Anton Khirnovf5e66822012-08-01 16:23:121580 /* check filename in case of an image number is expected */
1581 if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
1582 if (!av_filename_number_test(oc->filename)) {
1583 print_error(oc->filename, AVERROR(EINVAL));
Martin Storsjöb85dbe62013-07-31 10:44:171584 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121585 }
1586 }
1587
1588 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
1589 /* test if it already exists to avoid losing precious files */
1590 assert_file_overwrite(filename);
1591
1592 /* open the file */
1593 if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
1594 &oc->interrupt_callback,
Anton Khirnov1da54e92013-02-21 08:53:281595 &of->opts)) < 0) {
Anton Khirnovf5e66822012-08-01 16:23:121596 print_error(filename, err);
Martin Storsjöb85dbe62013-07-31 10:44:171597 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121598 }
1599 }
1600
1601 if (o->mux_preload) {
1602 uint8_t buf[64];
1603 snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
Anton Khirnov1da54e92013-02-21 08:53:281604 av_dict_set(&of->opts, "preload", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:121605 }
1606 oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
1607 oc->flags |= AVFMT_FLAG_NONBLOCK;
1608
1609 /* copy metadata */
1610 for (i = 0; i < o->nb_metadata_map; i++) {
1611 char *p;
1612 int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
1613
Anton Khirnovf5e66822012-08-01 16:23:121614 if (in_file_index >= nb_input_files) {
1615 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:171616 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121617 }
Anton Khirnova119c642012-10-16 07:53:391618 copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
1619 in_file_index >= 0 ?
1620 input_files[in_file_index]->ctx : NULL, o);
Anton Khirnovf5e66822012-08-01 16:23:121621 }
1622
1623 /* copy chapters */
1624 if (o->chapters_input_file >= nb_input_files) {
1625 if (o->chapters_input_file == INT_MAX) {
1626 /* copy chapters from the first input file that has them*/
1627 o->chapters_input_file = -1;
1628 for (i = 0; i < nb_input_files; i++)
1629 if (input_files[i]->ctx->nb_chapters) {
1630 o->chapters_input_file = i;
1631 break;
1632 }
1633 } else {
1634 av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
1635 o->chapters_input_file);
Martin Storsjöb85dbe62013-07-31 10:44:171636 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121637 }
1638 }
1639 if (o->chapters_input_file >= 0)
Anton Khirnov1da54e92013-02-21 08:53:281640 copy_chapters(input_files[o->chapters_input_file], of,
Anton Khirnovf5e66822012-08-01 16:23:121641 !o->metadata_chapters_manual);
1642
1643 /* copy global metadata by default */
1644 if (!o->metadata_global_manual && nb_input_files)
1645 av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
1646 AV_DICT_DONT_OVERWRITE);
1647 if (!o->metadata_streams_manual)
Anton Khirnov1da54e92013-02-21 08:53:281648 for (i = of->ost_index; i < nb_output_streams; i++) {
Anton Khirnovf5e66822012-08-01 16:23:121649 InputStream *ist;
1650 if (output_streams[i]->source_index < 0) /* this is true e.g. for attached files */
1651 continue;
1652 ist = input_streams[output_streams[i]->source_index];
1653 av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
1654 }
1655
1656 /* process manually set metadata */
1657 for (i = 0; i < o->nb_metadata; i++) {
1658 AVDictionary **m;
1659 char type, *val;
1660 const char *stream_spec;
1661 int index = 0, j, ret;
1662
1663 val = strchr(o->metadata[i].u.str, '=');
1664 if (!val) {
1665 av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
1666 o->metadata[i].u.str);
Martin Storsjöb85dbe62013-07-31 10:44:171667 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121668 }
1669 *val++ = 0;
1670
1671 parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
1672 if (type == 's') {
1673 for (j = 0; j < oc->nb_streams; j++) {
1674 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
1675 av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
1676 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:171677 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121678 }
1679 }
1680 else {
1681 switch (type) {
1682 case 'g':
1683 m = &oc->metadata;
1684 break;
1685 case 'c':
1686 if (index < 0 || index >= oc->nb_chapters) {
1687 av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
Martin Storsjöb85dbe62013-07-31 10:44:171688 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121689 }
1690 m = &oc->chapters[index]->metadata;
1691 break;
1692 default:
1693 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
Martin Storsjöb85dbe62013-07-31 10:44:171694 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121695 }
1696 av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
1697 }
1698 }
1699
Anton Khirnov77bd1bc2012-06-08 19:35:161700 return 0;
Anton Khirnovf5e66822012-08-01 16:23:121701}
1702
Anton Khirnovd3810c42012-08-11 14:30:261703static int opt_target(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121704{
Anton Khirnovd3810c42012-08-11 14:30:261705 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121706 enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
1707 static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
1708
1709 if (!strncmp(arg, "pal-", 4)) {
1710 norm = PAL;
1711 arg += 4;
1712 } else if (!strncmp(arg, "ntsc-", 5)) {
1713 norm = NTSC;
1714 arg += 5;
1715 } else if (!strncmp(arg, "film-", 5)) {
1716 norm = FILM;
1717 arg += 5;
1718 } else {
1719 /* Try to determine PAL/NTSC by peeking in the input files */
1720 if (nb_input_files) {
1721 int i, j, fr;
1722 for (j = 0; j < nb_input_files; j++) {
1723 for (i = 0; i < input_files[j]->nb_streams; i++) {
1724 AVCodecContext *c = input_files[j]->ctx->streams[i]->codec;
1725 if (c->codec_type != AVMEDIA_TYPE_VIDEO)
1726 continue;
1727 fr = c->time_base.den * 1000 / c->time_base.num;
1728 if (fr == 25000) {
1729 norm = PAL;
1730 break;
1731 } else if ((fr == 29970) || (fr == 23976)) {
1732 norm = NTSC;
1733 break;
1734 }
1735 }
1736 if (norm != UNKNOWN)
1737 break;
1738 }
1739 }
1740 if (norm != UNKNOWN)
1741 av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
1742 }
1743
1744 if (norm == UNKNOWN) {
1745 av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
1746 av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
1747 av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
Martin Storsjöb85dbe62013-07-31 10:44:171748 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121749 }
1750
1751 if (!strcmp(arg, "vcd")) {
1752 opt_video_codec(o, "c:v", "mpeg1video");
1753 opt_audio_codec(o, "c:a", "mp2");
1754 parse_option(o, "f", "vcd", options);
1755
1756 parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
1757 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221758 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121759
Anton Khirnov11d957f2012-08-29 12:37:221760 opt_default(NULL, "b", "1150000");
1761 opt_default(NULL, "maxrate", "1150000");
1762 opt_default(NULL, "minrate", "1150000");
1763 opt_default(NULL, "bufsize", "327680"); // 40*1024*8;
Anton Khirnovf5e66822012-08-01 16:23:121764
Anton Khirnov11d957f2012-08-29 12:37:221765 opt_default(NULL, "b:a", "224000");
Anton Khirnovf5e66822012-08-01 16:23:121766 parse_option(o, "ar", "44100", options);
1767 parse_option(o, "ac", "2", options);
1768
Anton Khirnov11d957f2012-08-29 12:37:221769 opt_default(NULL, "packetsize", "2324");
1770 opt_default(NULL, "muxrate", "1411200"); // 2352 * 75 * 8;
Anton Khirnovf5e66822012-08-01 16:23:121771
1772 /* We have to offset the PTS, so that it is consistent with the SCR.
1773 SCR starts at 36000, but the first two packs contain only padding
1774 and the first pack from the other stream, respectively, may also have
1775 been written before.
1776 So the real data starts at SCR 36000+3*1200. */
1777 o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
1778 } else if (!strcmp(arg, "svcd")) {
1779
1780 opt_video_codec(o, "c:v", "mpeg2video");
1781 opt_audio_codec(o, "c:a", "mp2");
1782 parse_option(o, "f", "svcd", options);
1783
1784 parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
1785 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221786 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121787
Anton Khirnov11d957f2012-08-29 12:37:221788 opt_default(NULL, "b", "2040000");
1789 opt_default(NULL, "maxrate", "2516000");
1790 opt_default(NULL, "minrate", "0"); // 1145000;
1791 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
1792 opt_default(NULL, "flags", "+scan_offset");
Anton Khirnovf5e66822012-08-01 16:23:121793
1794
Anton Khirnov11d957f2012-08-29 12:37:221795 opt_default(NULL, "b:a", "224000");
Anton Khirnovf5e66822012-08-01 16:23:121796 parse_option(o, "ar", "44100", options);
1797
Anton Khirnov11d957f2012-08-29 12:37:221798 opt_default(NULL, "packetsize", "2324");
Anton Khirnovf5e66822012-08-01 16:23:121799
1800 } else if (!strcmp(arg, "dvd")) {
1801
1802 opt_video_codec(o, "c:v", "mpeg2video");
1803 opt_audio_codec(o, "c:a", "ac3");
1804 parse_option(o, "f", "dvd", options);
1805
1806 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
1807 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221808 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121809
Anton Khirnov11d957f2012-08-29 12:37:221810 opt_default(NULL, "b", "6000000");
1811 opt_default(NULL, "maxrate", "9000000");
1812 opt_default(NULL, "minrate", "0"); // 1500000;
1813 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
Anton Khirnovf5e66822012-08-01 16:23:121814
Anton Khirnov11d957f2012-08-29 12:37:221815 opt_default(NULL, "packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
1816 opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
Anton Khirnovf5e66822012-08-01 16:23:121817
Anton Khirnov11d957f2012-08-29 12:37:221818 opt_default(NULL, "b:a", "448000");
Anton Khirnovf5e66822012-08-01 16:23:121819 parse_option(o, "ar", "48000", options);
1820
1821 } else if (!strncmp(arg, "dv", 2)) {
1822
1823 parse_option(o, "f", "dv", options);
1824
1825 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
1826 parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
1827 norm == PAL ? "yuv420p" : "yuv411p", options);
1828 parse_option(o, "r", frame_rates[norm], options);
1829
1830 parse_option(o, "ar", "48000", options);
1831 parse_option(o, "ac", "2", options);
1832
1833 } else {
1834 av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
1835 return AVERROR(EINVAL);
1836 }
1837 return 0;
1838}
1839
Anton Khirnov11d957f2012-08-29 12:37:221840static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121841{
1842 av_free (vstats_filename);
1843 vstats_filename = av_strdup (arg);
1844 return 0;
1845}
1846
Anton Khirnov11d957f2012-08-29 12:37:221847static int opt_vstats(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121848{
1849 char filename[40];
1850 time_t today2 = time(NULL);
1851 struct tm *today = localtime(&today2);
1852
1853 snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
1854 today->tm_sec);
Anton Khirnov11d957f2012-08-29 12:37:221855 return opt_vstats_file(NULL, opt, filename);
Anton Khirnovf5e66822012-08-01 16:23:121856}
1857
Anton Khirnovd3810c42012-08-11 14:30:261858static int opt_video_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121859{
Anton Khirnovd3810c42012-08-11 14:30:261860 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121861 return parse_option(o, "frames:v", arg, options);
1862}
1863
Anton Khirnovd3810c42012-08-11 14:30:261864static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121865{
Anton Khirnovd3810c42012-08-11 14:30:261866 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121867 return parse_option(o, "frames:a", arg, options);
1868}
1869
Anton Khirnovd3810c42012-08-11 14:30:261870static int opt_data_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121871{
Anton Khirnovd3810c42012-08-11 14:30:261872 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121873 return parse_option(o, "frames:d", arg, options);
1874}
1875
Anton Khirnovd3810c42012-08-11 14:30:261876static int opt_video_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121877{
Anton Khirnovd3810c42012-08-11 14:30:261878 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121879 return parse_option(o, "tag:v", arg, options);
1880}
1881
Anton Khirnovd3810c42012-08-11 14:30:261882static int opt_audio_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121883{
Anton Khirnovd3810c42012-08-11 14:30:261884 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121885 return parse_option(o, "tag:a", arg, options);
1886}
1887
Anton Khirnovd3810c42012-08-11 14:30:261888static int opt_subtitle_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121889{
Anton Khirnovd3810c42012-08-11 14:30:261890 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121891 return parse_option(o, "tag:s", arg, options);
1892}
1893
Anton Khirnovd3810c42012-08-11 14:30:261894static int opt_video_filters(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121895{
Anton Khirnovd3810c42012-08-11 14:30:261896 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121897 return parse_option(o, "filter:v", arg, options);
1898}
1899
Anton Khirnovd3810c42012-08-11 14:30:261900static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121901{
Anton Khirnovd3810c42012-08-11 14:30:261902 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121903 return parse_option(o, "filter:a", arg, options);
1904}
1905
Anton Khirnov11d957f2012-08-29 12:37:221906static int opt_vsync(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121907{
1908 if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR;
1909 else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR;
1910 else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
1911
1912 if (video_sync_method == VSYNC_AUTO)
1913 video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
1914 return 0;
1915}
1916
Anton Khirnovd3810c42012-08-11 14:30:261917static int opt_channel_layout(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 char layout_str[32];
1921 char *stream_str;
1922 char *ac_str;
1923 int ret, channels, ac_str_size;
1924 uint64_t layout;
1925
1926 layout = av_get_channel_layout(arg);
1927 if (!layout) {
1928 av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
1929 return AVERROR(EINVAL);
1930 }
1931 snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
Anton Khirnov11d957f2012-08-29 12:37:221932 ret = opt_default(NULL, opt, layout_str);
Anton Khirnovf5e66822012-08-01 16:23:121933 if (ret < 0)
1934 return ret;
1935
1936 /* set 'ac' option based on channel layout */
1937 channels = av_get_channel_layout_nb_channels(layout);
1938 snprintf(layout_str, sizeof(layout_str), "%d", channels);
1939 stream_str = strchr(opt, ':');
1940 ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
1941 ac_str = av_mallocz(ac_str_size);
1942 if (!ac_str)
1943 return AVERROR(ENOMEM);
1944 av_strlcpy(ac_str, "ac", 3);
1945 if (stream_str)
1946 av_strlcat(ac_str, stream_str, ac_str_size);
1947 ret = parse_option(o, ac_str, layout_str, options);
1948 av_free(ac_str);
1949
1950 return ret;
1951}
1952
Anton Khirnovd3810c42012-08-11 14:30:261953static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121954{
Anton Khirnovd3810c42012-08-11 14:30:261955 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121956 return parse_option(o, "q:a", arg, options);
1957}
1958
Anton Khirnov11d957f2012-08-29 12:37:221959static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121960{
Anton Khirnov10bca662012-06-07 19:52:071961 GROW_ARRAY(filtergraphs, nb_filtergraphs);
Anton Khirnovf5e66822012-08-01 16:23:121962 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
1963 return AVERROR(ENOMEM);
Anton Khirnova4208b92013-03-13 13:24:451964 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
1965 filtergraphs[nb_filtergraphs - 1]->graph_desc = av_strdup(arg);
1966 if (!filtergraphs[nb_filtergraphs - 1]->graph_desc)
1967 return AVERROR(ENOMEM);
1968 return 0;
1969}
1970
1971static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
1972{
1973 uint8_t *graph_desc = read_file(arg);
1974 if (!graph_desc)
1975 return AVERROR(EINVAL);
1976
1977 GROW_ARRAY(filtergraphs, nb_filtergraphs);
1978 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
1979 return AVERROR(ENOMEM);
1980 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
1981 filtergraphs[nb_filtergraphs - 1]->graph_desc = graph_desc;
Anton Khirnovf5e66822012-08-01 16:23:121982 return 0;
1983}
1984
Anton Khirnova3ad68d2012-08-13 18:06:251985void show_help_default(const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121986{
Anton Khirnovf9fada22012-08-15 08:31:461987 /* per-file options have at least one of those set */
Anton Khirnov11d957f2012-08-29 12:37:221988 const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
Anton Khirnov6e3857f2012-08-14 06:56:321989 int show_advanced = 0, show_avoptions = 0;
1990
Janne Grunau8d09d392012-10-10 18:35:261991 if (opt && *opt) {
Anton Khirnov6e3857f2012-08-14 06:56:321992 if (!strcmp(opt, "long"))
1993 show_advanced = 1;
1994 else if (!strcmp(opt, "full"))
1995 show_advanced = show_avoptions = 1;
1996 else
1997 av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
1998 }
Anton Khirnova3ad68d2012-08-13 18:06:251999
Anton Khirnovf5e66822012-08-01 16:23:122000 show_usage();
Anton Khirnov6e3857f2012-08-14 06:56:322001
2002 printf("Getting help:\n"
2003 " -h -- print basic options\n"
2004 " -h long -- print more options\n"
2005 " -h full -- print all options (including all format and codec specific options, very long)\n"
2006 " See man %s for detailed description of the options.\n"
2007 "\n", program_name);
2008
Anton Khirnovf8b1e662012-08-14 06:21:422009 show_help_options(options, "Print help / information / capabilities:",
Anton Khirnovf9fada22012-08-15 08:31:462010 OPT_EXIT, 0, 0);
2011
2012 show_help_options(options, "Global options (affect whole program "
2013 "instead of just one file:",
2014 0, per_file | OPT_EXIT | OPT_EXPERT, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322015 if (show_advanced)
Anton Khirnovf9fada22012-08-15 08:31:462016 show_help_options(options, "Advanced global options:", OPT_EXPERT,
2017 per_file | OPT_EXIT, 0);
2018
2019 show_help_options(options, "Per-file main options:", 0,
2020 OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
2021 OPT_EXIT, per_file);
2022 if (show_advanced)
2023 show_help_options(options, "Advanced per-file options:",
2024 OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
Anton Khirnov6e3857f2012-08-14 06:56:322025
Anton Khirnovdc4c24a2012-08-11 17:33:272026 show_help_options(options, "Video options:",
Anton Khirnovf9fada22012-08-15 08:31:462027 OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322028 if (show_advanced)
2029 show_help_options(options, "Advanced Video options:",
Anton Khirnovf9fada22012-08-15 08:31:462030 OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322031
Anton Khirnovdc4c24a2012-08-11 17:33:272032 show_help_options(options, "Audio options:",
Anton Khirnovf9fada22012-08-15 08:31:462033 OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322034 if (show_advanced)
2035 show_help_options(options, "Advanced Audio options:",
Anton Khirnovf9fada22012-08-15 08:31:462036 OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
Anton Khirnovdc4c24a2012-08-11 17:33:272037 show_help_options(options, "Subtitle options:",
Anton Khirnovf9fada22012-08-15 08:31:462038 OPT_SUBTITLE, 0, 0);
Anton Khirnovf5e66822012-08-01 16:23:122039 printf("\n");
Anton Khirnov6e3857f2012-08-14 06:56:322040
2041 if (show_avoptions) {
2042 int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
2043 show_help_children(avcodec_get_class(), flags);
2044 show_help_children(avformat_get_class(), flags);
2045 show_help_children(sws_get_class(), flags);
Anton Khirnovdc574652013-03-13 08:10:342046 show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM);
Anton Khirnov6e3857f2012-08-14 06:56:322047 }
Anton Khirnovf5e66822012-08-01 16:23:122048}
2049
2050void show_usage(void)
2051{
2052 printf("Hyper fast Audio and Video encoder\n");
2053 printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
2054 printf("\n");
2055}
2056
Anton Khirnov77bd1bc2012-06-08 19:35:162057enum OptGroup {
2058 GROUP_OUTFILE,
2059 GROUP_INFILE,
2060};
2061
2062static const OptionGroupDef groups[] = {
Anton Khirnov9d3009c2013-02-20 07:02:162063 [GROUP_OUTFILE] = { "output file", NULL, OPT_OUTPUT },
2064 [GROUP_INFILE] = { "input file", "i", OPT_INPUT },
Anton Khirnov77bd1bc2012-06-08 19:35:162065};
2066
2067static int open_files(OptionGroupList *l, const char *inout,
2068 int (*open_file)(OptionsContext*, const char*))
2069{
2070 int i, ret;
2071
2072 for (i = 0; i < l->nb_groups; i++) {
2073 OptionGroup *g = &l->groups[i];
2074 OptionsContext o;
2075
2076 init_options(&o);
2077 o.g = g;
2078
2079 ret = parse_optgroup(&o, g);
2080 if (ret < 0) {
2081 av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
2082 "%s.\n", inout, g->arg);
2083 return ret;
2084 }
2085
2086 av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
2087 ret = open_file(&o, g->arg);
2088 uninit_options(&o);
2089 if (ret < 0) {
2090 av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
2091 inout, g->arg);
2092 return ret;
2093 }
Anton Khirnovdb2d65c2013-02-21 09:57:572094 av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
Anton Khirnov77bd1bc2012-06-08 19:35:162095 }
2096
2097 return 0;
2098}
2099
2100int avconv_parse_options(int argc, char **argv)
2101{
2102 OptionParseContext octx;
2103 uint8_t error[128];
2104 int ret;
2105
2106 memset(&octx, 0, sizeof(octx));
2107
2108 /* split the commandline into an internal representation */
Anton Khirnovc661cb62012-12-19 20:53:222109 ret = split_commandline(&octx, argc, argv, options, groups,
2110 FF_ARRAY_ELEMS(groups));
Anton Khirnov77bd1bc2012-06-08 19:35:162111 if (ret < 0) {
2112 av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
2113 goto fail;
2114 }
2115
2116 /* apply global options */
2117 ret = parse_optgroup(NULL, &octx.global_opts);
2118 if (ret < 0) {
2119 av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
2120 goto fail;
2121 }
2122
2123 /* open input files */
2124 ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
2125 if (ret < 0) {
2126 av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
2127 goto fail;
2128 }
2129
2130 /* open output files */
2131 ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
2132 if (ret < 0) {
2133 av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
2134 goto fail;
2135 }
2136
2137fail:
2138 uninit_parse_context(&octx);
2139 if (ret < 0) {
2140 av_strerror(ret, error, sizeof(error));
2141 av_log(NULL, AV_LOG_FATAL, "%s\n", error);
2142 }
2143 return ret;
2144}
Anton Khirnovf5e66822012-08-01 16:23:122145
2146#define OFFSET(x) offsetof(OptionsContext, x)
2147const OptionDef options[] = {
2148 /* main options */
2149#include "cmdutils_common_opts.h"
Anton Khirnov9d3009c2013-02-20 07:02:162150 { "f", HAS_ARG | OPT_STRING | OPT_OFFSET |
2151 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(format) },
Anton Khirnov8fc83fb2012-08-11 15:00:302152 "force format", "fmt" },
Anton Khirnov8fc83fb2012-08-11 15:00:302153 { "y", OPT_BOOL, { &file_overwrite },
2154 "overwrite output files" },
Vittorio Giovara7748dd42013-07-31 12:48:492155 { "n", OPT_BOOL, { &file_skip },
2156 "never overwrite output files" },
Anton Khirnov9d3009c2013-02-20 07:02:162157 { "c", HAS_ARG | OPT_STRING | OPT_SPEC |
2158 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
Anton Khirnov8fc83fb2012-08-11 15:00:302159 "codec name", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162160 { "codec", HAS_ARG | OPT_STRING | OPT_SPEC |
2161 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
Anton Khirnov8fc83fb2012-08-11 15:00:302162 "codec name", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162163 { "pre", HAS_ARG | OPT_STRING | OPT_SPEC |
2164 OPT_OUTPUT, { .off = OFFSET(presets) },
Anton Khirnov8fc83fb2012-08-11 15:00:302165 "preset name", "preset" },
Anton Khirnov9d3009c2013-02-20 07:02:162166 { "map", HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2167 OPT_OUTPUT, { .func_arg = opt_map },
Anton Khirnov8fc83fb2012-08-11 15:00:302168 "set input stream mapping",
2169 "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
Anton Khirnov9d3009c2013-02-20 07:02:162170 { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC |
2171 OPT_OUTPUT, { .off = OFFSET(metadata_map) },
Anton Khirnov8fc83fb2012-08-11 15:00:302172 "set metadata information of outfile from infile",
2173 "outfile[,metadata]:infile[,metadata]" },
Anton Khirnov9d3009c2013-02-20 07:02:162174 { "map_chapters", HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
2175 OPT_OUTPUT, { .off = OFFSET(chapters_input_file) },
Anton Khirnov8fc83fb2012-08-11 15:00:302176 "set chapters mapping", "input_file_index" },
Anton Khirnov488a0fa2013-06-18 09:12:092177 { "t", HAS_ARG | OPT_TIME | OPT_OFFSET |
2178 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(recording_time) },
Anton Khirnov8fc83fb2012-08-11 15:00:302179 "record or transcode \"duration\" seconds of audio/video",
2180 "duration" },
Anton Khirnov9d3009c2013-02-20 07:02:162181 { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
Anton Khirnov8fc83fb2012-08-11 15:00:302182 "set the limit file size in bytes", "limit_size" },
Anton Khirnov9d3009c2013-02-20 07:02:162183 { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET |
2184 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time) },
Anton Khirnov8fc83fb2012-08-11 15:00:302185 "set the start time offset", "time_off" },
Anton Khirnov811bd072013-06-15 07:59:402186 { "accurate_seek", OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
2187 OPT_INPUT, { .off = OFFSET(accurate_seek) },
2188 "enable/disable accurate seeking with -ss" },
Anton Khirnov9d3009c2013-02-20 07:02:162189 { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET |
2190 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(input_ts_offset) },
Anton Khirnov8fc83fb2012-08-11 15:00:302191 "set the input ts offset", "time_off" },
Anton Khirnov9d3009c2013-02-20 07:02:162192 { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC |
2193 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(ts_scale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302194 "set the input ts scale", "scale" },
Anton Khirnov9d3009c2013-02-20 07:02:162195 { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
Anton Khirnov8fc83fb2012-08-11 15:00:302196 "add metadata", "string=string" },
Anton Khirnov9d3009c2013-02-20 07:02:162197 { "dframes", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2198 OPT_OUTPUT, { .func_arg = opt_data_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302199 "set the number of data frames to record", "number" },
2200 { "benchmark", OPT_BOOL | OPT_EXPERT, { &do_benchmark },
2201 "add timings for benchmarking" },
Anton Khirnov602b1892012-08-15 08:33:362202 { "timelimit", HAS_ARG | OPT_EXPERT, { .func_arg = opt_timelimit },
Anton Khirnov8fc83fb2012-08-11 15:00:302203 "set max runtime in seconds", "limit" },
2204 { "dump", OPT_BOOL | OPT_EXPERT, { &do_pkt_dump },
2205 "dump each input packet" },
2206 { "hex", OPT_BOOL | OPT_EXPERT, { &do_hex_dump },
2207 "when dumping packets, also dump the payload" },
Anton Khirnov9d3009c2013-02-20 07:02:162208 { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2209 OPT_INPUT, { .off = OFFSET(rate_emu) },
Anton Khirnov8fc83fb2012-08-11 15:00:302210 "read input at native frame rate", "" },
Anton Khirnov9d3009c2013-02-20 07:02:162211 { "target", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_target },
Anton Khirnov8fc83fb2012-08-11 15:00:302212 "specify target file type (\"vcd\", \"svcd\", \"dvd\","
2213 " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
2214 { "vsync", HAS_ARG | OPT_EXPERT, { opt_vsync },
2215 "video sync method", "" },
2216 { "async", HAS_ARG | OPT_INT | OPT_EXPERT, { &audio_sync_method },
2217 "audio sync method", "" },
2218 { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &audio_drift_threshold },
2219 "audio drift threshold", "threshold" },
2220 { "copyts", OPT_BOOL | OPT_EXPERT, { &copy_ts },
2221 "copy timestamps" },
2222 { "copytb", OPT_BOOL | OPT_EXPERT, { &copy_tb },
2223 "copy input stream time base when stream copying" },
Anton Khirnov9d3009c2013-02-20 07:02:162224 { "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2225 OPT_OUTPUT, { .off = OFFSET(shortest) },
Anton Khirnov8fc83fb2012-08-11 15:00:302226 "finish encoding within shortest input" },
2227 { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &dts_delta_threshold },
2228 "timestamp discontinuity delta threshold", "threshold" },
Anton Khirnov602b1892012-08-15 08:33:362229 { "xerror", OPT_BOOL | OPT_EXPERT, { &exit_on_error },
Anton Khirnov8fc83fb2012-08-11 15:00:302230 "exit on error", "error" },
Anton Khirnov9d3009c2013-02-20 07:02:162231 { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2232 OPT_OUTPUT, { .off = OFFSET(copy_initial_nonkeyframes) },
Anton Khirnov8fc83fb2012-08-11 15:00:302233 "copy initial non-keyframes" },
Anton Khirnov9d3009c2013-02-20 07:02:162234 { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
Anton Khirnov8fc83fb2012-08-11 15:00:302235 "set the number of frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162236 { "tag", OPT_STRING | HAS_ARG | OPT_SPEC |
2237 OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(codec_tags) },
Anton Khirnov8fc83fb2012-08-11 15:00:302238 "force codec tag/fourcc", "fourcc/tag" },
Anton Khirnov9d3009c2013-02-20 07:02:162239 { "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2240 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302241 "use fixed quality scale (VBR)", "q" },
Anton Khirnov9d3009c2013-02-20 07:02:162242 { "qscale", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2243 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302244 "use fixed quality scale (VBR)", "q" },
Anton Khirnov9d3009c2013-02-20 07:02:162245 { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
Anton Khirnov8fc83fb2012-08-11 15:00:302246 "set stream filterchain", "filter_list" },
Anton Khirnova4208b92013-03-13 13:24:452247 { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) },
2248 "read stream filtergraph description from a file", "filename" },
Anton Khirnov8fc83fb2012-08-11 15:00:302249 { "filter_complex", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex },
2250 "create a complex filtergraph", "graph_description" },
Anton Khirnova4208b92013-03-13 13:24:452251 { "filter_complex_script", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex_script },
2252 "read complex filtergraph description from a file", "filename" },
Anton Khirnov8fc83fb2012-08-11 15:00:302253 { "stats", OPT_BOOL, { &print_stats },
2254 "print progress report during encoding", },
Anton Khirnov9d3009c2013-02-20 07:02:162255 { "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2256 OPT_OUTPUT, { .func_arg = opt_attach },
Anton Khirnov8fc83fb2012-08-11 15:00:302257 "add an attachment to the output file", "filename" },
Anton Khirnov9d3009c2013-02-20 07:02:162258 { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |
2259 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(dump_attachment) },
Anton Khirnov8fc83fb2012-08-11 15:00:302260 "extract an attachment into a file", "filename" },
Anton Khirnovf5e66822012-08-01 16:23:122261
2262 /* video options */
Anton Khirnov9d3009c2013-02-20 07:02:162263 { "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302264 "set the number of video frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162265 { "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2266 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_rates) },
Anton Khirnov8fc83fb2012-08-11 15:00:302267 "set frame rate (Hz value, fraction or abbreviation)", "rate" },
Anton Khirnov9d3009c2013-02-20 07:02:162268 { "s", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2269 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_sizes) },
Anton Khirnov8fc83fb2012-08-11 15:00:302270 "set frame size (WxH or abbreviation)", "size" },
Anton Khirnov9d3009c2013-02-20 07:02:162271 { "aspect", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2272 OPT_OUTPUT, { .off = OFFSET(frame_aspect_ratios) },
Anton Khirnov8fc83fb2012-08-11 15:00:302273 "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
Anton Khirnov9d3009c2013-02-20 07:02:162274 { "pix_fmt", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2275 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_pix_fmts) },
Anton Khirnov8fc83fb2012-08-11 15:00:302276 "set pixel format", "format" },
Anton Khirnov9d3009c2013-02-20 07:02:162277 { "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(video_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302278 "disable video" },
2279 { "vdt", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &video_discard },
2280 "discard threshold", "n" },
Anton Khirnov9d3009c2013-02-20 07:02:162281 { "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2282 OPT_OUTPUT, { .off = OFFSET(rc_overrides) },
Anton Khirnov8fc83fb2012-08-11 15:00:302283 "rate control override for specific intervals", "override" },
Anton Khirnov9d3009c2013-02-20 07:02:162284 { "vcodec", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_INPUT |
2285 OPT_OUTPUT, { .func_arg = opt_video_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302286 "force video codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162287 { "pass", OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT | OPT_OUTPUT, { .off = OFFSET(pass) },
Anton Khirnov8fc83fb2012-08-11 15:00:302288 "select the pass number (1 or 2)", "n" },
Anton Khirnov9d3009c2013-02-20 07:02:162289 { "passlogfile", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
2290 OPT_OUTPUT, { .off = OFFSET(passlogfiles) },
Anton Khirnov8fc83fb2012-08-11 15:00:302291 "select two pass log file name prefix", "prefix" },
Anton Khirnov8fc83fb2012-08-11 15:00:302292 { "vstats", OPT_VIDEO | OPT_EXPERT , { &opt_vstats },
2293 "dump video coding statistics to file" },
2294 { "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { opt_vstats_file },
2295 "dump video coding statistics to file", "file" },
Anton Khirnov9d3009c2013-02-20 07:02:162296 { "vf", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_filters },
Anton Khirnov8fc83fb2012-08-11 15:00:302297 "video filters", "filter list" },
Anton Khirnov9d3009c2013-02-20 07:02:162298 { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2299 OPT_OUTPUT, { .off = OFFSET(intra_matrices) },
Anton Khirnov8fc83fb2012-08-11 15:00:302300 "specify intra matrix coeffs", "matrix" },
Anton Khirnov9d3009c2013-02-20 07:02:162301 { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2302 OPT_OUTPUT, { .off = OFFSET(inter_matrices) },
Anton Khirnov8fc83fb2012-08-11 15:00:302303 "specify inter matrix coeffs", "matrix" },
Anton Khirnov9d3009c2013-02-20 07:02:162304 { "top", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_INT| OPT_SPEC |
2305 OPT_OUTPUT, { .off = OFFSET(top_field_first) },
Anton Khirnov8fc83fb2012-08-11 15:00:302306 "top=1/bottom=0/auto=-1 field first", "" },
2307 { "dc", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &intra_dc_precision },
2308 "intra_dc_precision", "precision" },
Anton Khirnov9d3009c2013-02-20 07:02:162309 { "vtag", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2310 OPT_OUTPUT, { .func_arg = opt_video_tag },
Anton Khirnov8fc83fb2012-08-11 15:00:302311 "force video tag/fourcc", "fourcc/tag" },
2312 { "qphist", OPT_VIDEO | OPT_BOOL | OPT_EXPERT , { &qp_hist },
2313 "show QP histogram" },
Anton Khirnov9d3009c2013-02-20 07:02:162314 { "force_fps", OPT_VIDEO | OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2315 OPT_OUTPUT, { .off = OFFSET(force_fps) },
Anton Khirnov8fc83fb2012-08-11 15:00:302316 "force the selected framerate, disable the best supported framerate selection" },
Anton Khirnov9d3009c2013-02-20 07:02:162317 { "streamid", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2318 OPT_OUTPUT, { .func_arg = opt_streamid },
Anton Khirnov8fc83fb2012-08-11 15:00:302319 "set the value of an outfile streamid", "streamIndex:value" },
Anton Khirnov9d3009c2013-02-20 07:02:162320 { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2321 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(forced_key_frames) },
2322 "force key frames at specified timestamps", "timestamps" },
Anton Khirnov07fd0a22013-11-02 21:06:362323 { "hwaccel", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2324 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccels) },
2325 "use HW accelerated decoding", "hwaccel name" },
2326 { "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2327 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) },
2328 "select a device for HW acceleration" "devicename" },
Anton Khirnovf5e66822012-08-01 16:23:122329
2330 /* audio options */
Anton Khirnov9d3009c2013-02-20 07:02:162331 { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302332 "set the number of audio frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162333 { "aq", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_qscale },
Anton Khirnov8fc83fb2012-08-11 15:00:302334 "set audio quality (codec-specific)", "quality", },
Anton Khirnov9d3009c2013-02-20 07:02:162335 { "ar", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2336 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_sample_rate) },
Anton Khirnov8fc83fb2012-08-11 15:00:302337 "set audio sampling rate (in Hz)", "rate" },
Anton Khirnov9d3009c2013-02-20 07:02:162338 { "ac", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2339 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_channels) },
Anton Khirnov8fc83fb2012-08-11 15:00:302340 "set number of audio channels", "channels" },
Anton Khirnov9d3009c2013-02-20 07:02:162341 { "an", OPT_AUDIO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(audio_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302342 "disable audio" },
Anton Khirnov9d3009c2013-02-20 07:02:162343 { "acodec", OPT_AUDIO | HAS_ARG | OPT_PERFILE |
2344 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_audio_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302345 "force audio codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162346 { "atag", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2347 OPT_OUTPUT, { .func_arg = opt_audio_tag },
Anton Khirnov8fc83fb2012-08-11 15:00:302348 "force audio tag/fourcc", "fourcc/tag" },
2349 { "vol", OPT_AUDIO | HAS_ARG | OPT_INT, { &audio_volume },
2350 "change audio volume (256=normal)" , "volume" },
Anton Khirnov9d3009c2013-02-20 07:02:162351 { "sample_fmt", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_SPEC |
2352 OPT_STRING | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(sample_fmts) },
Anton Khirnov8fc83fb2012-08-11 15:00:302353 "set sample format", "format" },
Anton Khirnov9d3009c2013-02-20 07:02:162354 { "channel_layout", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2355 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_channel_layout },
Anton Khirnov8fc83fb2012-08-11 15:00:302356 "set channel layout", "layout" },
Anton Khirnov9d3009c2013-02-20 07:02:162357 { "af", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_filters },
Anton Khirnov8fc83fb2012-08-11 15:00:302358 "audio filters", "filter list" },
Anton Khirnovf5e66822012-08-01 16:23:122359
2360 /* subtitle options */
Anton Khirnov9d3009c2013-02-20 07:02:162361 { "sn", OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(subtitle_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302362 "disable subtitle" },
Anton Khirnov9d3009c2013-02-20 07:02:162363 { "scodec", OPT_SUBTITLE | HAS_ARG | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_subtitle_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302364 "force subtitle codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162365 { "stag", OPT_SUBTITLE | HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_subtitle_tag }
Anton Khirnov8fc83fb2012-08-11 15:00:302366 , "force subtitle tag/fourcc", "fourcc/tag" },
Anton Khirnovf5e66822012-08-01 16:23:122367
2368 /* grab options */
Anton Khirnov79600a82012-08-11 17:19:532369 { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
Anton Khirnovf5e66822012-08-01 16:23:122370
2371 /* muxer options */
Anton Khirnov9d3009c2013-02-20 07:02:162372 { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_max_delay) },
Anton Khirnov8fc83fb2012-08-11 15:00:302373 "set the maximum demux-decode delay", "seconds" },
Anton Khirnov9d3009c2013-02-20 07:02:162374 { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
Anton Khirnov8fc83fb2012-08-11 15:00:302375 "set the initial demux-decode delay", "seconds" },
Anton Khirnovf5e66822012-08-01 16:23:122376
Anton Khirnov9d3009c2013-02-20 07:02:162377 { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
Anton Khirnov8fc83fb2012-08-11 15:00:302378 "A comma-separated list of bitstream filters", "bitstream_filters" },
Anton Khirnovf5e66822012-08-01 16:23:122379
2380 /* data codec support */
Anton Khirnov9d3009c2013-02-20 07:02:162381 { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302382 "force data codec ('copy' to copy stream)", "codec" },
Anton Khirnovf5e66822012-08-01 16:23:122383
Anton Khirnovf5e66822012-08-01 16:23:122384 { NULL, },
2385};