blob: d62d11f5e6592efa0dca2e66ae228ecbc16fc4bc [file] [log] [blame]
Anton Khirnovf5e66822012-08-01 16:23:121/*
2 * avconv option parsing
3 *
4 * This file is part of Libav.
5 *
6 * Libav is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * Libav is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Libav; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <stdint.h>
22
23#include "avconv.h"
24#include "cmdutils.h"
25
26#include "libavformat/avformat.h"
27
28#include "libavcodec/avcodec.h"
29
30#include "libavfilter/avfilter.h"
Anton Khirnovf5e66822012-08-01 16:23:1231
Anton Khirnovf5e66822012-08-01 16:23:1232#include "libavutil/avassert.h"
33#include "libavutil/avstring.h"
34#include "libavutil/avutil.h"
Justin Rugglesa903f8f2012-11-10 15:00:0035#include "libavutil/channel_layout.h"
Anton Khirnovf5e66822012-08-01 16:23:1236#include "libavutil/intreadwrite.h"
37#include "libavutil/fifo.h"
38#include "libavutil/mathematics.h"
39#include "libavutil/opt.h"
40#include "libavutil/parseutils.h"
41#include "libavutil/pixdesc.h"
42#include "libavutil/pixfmt.h"
43
44#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
45{\
46 int i, ret;\
47 for (i = 0; i < o->nb_ ## name; i++) {\
48 char *spec = o->name[i].specifier;\
49 if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
50 outvar = o->name[i].u.type;\
51 else if (ret < 0)\
Martin Storsjöb85dbe62013-07-31 10:44:1752 exit_program(1);\
Anton Khirnovf5e66822012-08-01 16:23:1253 }\
54}
55
Anton Khirnov07fd0a22013-11-02 21:06:3656const HWAccel hwaccels[] = {
Anton Khirnov7671dd72013-11-03 18:21:0057#if HAVE_VDPAU_X11
58 { "vdpau", vdpau_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU },
59#endif
Anton Khirnov07fd0a22013-11-02 21:06:3660 { 0 },
61};
62
Anton Khirnovf5e66822012-08-01 16:23:1263char *vstats_filename;
64
65float audio_drift_threshold = 0.1;
66float dts_delta_threshold = 10;
67
68int audio_volume = 256;
69int audio_sync_method = 0;
70int video_sync_method = VSYNC_AUTO;
Anton Khirnovf5e66822012-08-01 16:23:1271int do_benchmark = 0;
72int do_hex_dump = 0;
73int do_pkt_dump = 0;
74int copy_ts = 0;
75int copy_tb = 1;
Anton Khirnovf5e66822012-08-01 16:23:1276int exit_on_error = 0;
77int print_stats = 1;
78int qp_hist = 0;
Anton Khirnovf5e66822012-08-01 16:23:1279
80static int file_overwrite = 0;
Vittorio Giovara7748dd42013-07-31 12:48:4981static int file_skip = 0;
Anton Khirnovf5e66822012-08-01 16:23:1282static int video_discard = 0;
83static int intra_dc_precision = 8;
Anton Khirnovf5e66822012-08-01 16:23:1284static int using_stdin = 0;
85static int input_sync;
86
Anton Khirnov77bd1bc2012-06-08 19:35:1687static void uninit_options(OptionsContext *o)
Anton Khirnovf5e66822012-08-01 16:23:1288{
89 const OptionDef *po = options;
90 int i;
91
92 /* all OPT_SPEC and OPT_STRING can be freed in generic way */
93 while (po->name) {
94 void *dst = (uint8_t*)o + po->u.off;
95
96 if (po->flags & OPT_SPEC) {
97 SpecifierOpt **so = dst;
98 int i, *count = (int*)(so + 1);
99 for (i = 0; i < *count; i++) {
100 av_freep(&(*so)[i].specifier);
101 if (po->flags & OPT_STRING)
102 av_freep(&(*so)[i].u.str);
103 }
104 av_freep(so);
105 *count = 0;
106 } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
107 av_freep(dst);
108 po++;
109 }
110
111 for (i = 0; i < o->nb_stream_maps; i++)
112 av_freep(&o->stream_maps[i].linklabel);
113 av_freep(&o->stream_maps);
114 av_freep(&o->meta_data_maps);
115 av_freep(&o->streamid_map);
Anton Khirnov77bd1bc2012-06-08 19:35:16116}
Anton Khirnovf5e66822012-08-01 16:23:12117
Anton Khirnov77bd1bc2012-06-08 19:35:16118static void init_options(OptionsContext *o)
119{
Anton Khirnovf5e66822012-08-01 16:23:12120 memset(o, 0, sizeof(*o));
121
122 o->mux_max_delay = 0.7;
Anton Khirnov56ee3f92013-06-15 07:35:10123 o->start_time = AV_NOPTS_VALUE;
Anton Khirnovf5e66822012-08-01 16:23:12124 o->recording_time = INT64_MAX;
125 o->limit_filesize = UINT64_MAX;
126 o->chapters_input_file = INT_MAX;
Anton Khirnov811bd072013-06-15 07:59:40127 o->accurate_seek = 1;
Anton Khirnovf5e66822012-08-01 16:23:12128}
129
Anton Khirnove7553f42013-02-21 09:58:46130/* return a copy of the input with the stream specifiers removed from the keys */
131static AVDictionary *strip_specifiers(AVDictionary *dict)
132{
133 AVDictionaryEntry *e = NULL;
134 AVDictionary *ret = NULL;
135
136 while ((e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))) {
137 char *p = strchr(e->key, ':');
138
139 if (p)
140 *p = 0;
141 av_dict_set(&ret, e->key, e->value, 0);
142 if (p)
143 *p = ':';
144 }
145 return ret;
146}
147
Anton Khirnovf5e66822012-08-01 16:23:12148static double parse_frame_aspect_ratio(const char *arg)
149{
150 int x = 0, y = 0;
151 double ar = 0;
152 const char *p;
153 char *end;
154
155 p = strchr(arg, ':');
156 if (p) {
157 x = strtol(arg, &end, 10);
158 if (end == p)
159 y = strtol(end + 1, &end, 10);
160 if (x > 0 && y > 0)
161 ar = (double)x / (double)y;
162 } else
163 ar = strtod(arg, NULL);
164
165 if (!ar) {
166 av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17167 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12168 }
169 return ar;
170}
171
Anton Khirnovd3810c42012-08-11 14:30:26172static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12173{
Anton Khirnovd3810c42012-08-11 14:30:26174 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12175 return parse_option(o, "codec:a", arg, options);
176}
177
Anton Khirnovd3810c42012-08-11 14:30:26178static int opt_video_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12179{
Anton Khirnovd3810c42012-08-11 14:30:26180 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12181 return parse_option(o, "codec:v", arg, options);
182}
183
Anton Khirnovd3810c42012-08-11 14:30:26184static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12185{
Anton Khirnovd3810c42012-08-11 14:30:26186 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12187 return parse_option(o, "codec:s", arg, options);
188}
189
Anton Khirnovd3810c42012-08-11 14:30:26190static int opt_data_codec(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12191{
Anton Khirnovd3810c42012-08-11 14:30:26192 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12193 return parse_option(o, "codec:d", arg, options);
194}
195
Anton Khirnovd3810c42012-08-11 14:30:26196static int opt_map(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12197{
Anton Khirnovd3810c42012-08-11 14:30:26198 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:12199 StreamMap *m = NULL;
200 int i, negative = 0, file_idx;
201 int sync_file_idx = -1, sync_stream_idx;
202 char *p, *sync;
203 char *map;
204
205 if (*arg == '-') {
206 negative = 1;
207 arg++;
208 }
209 map = av_strdup(arg);
210
211 /* parse sync stream first, just pick first matching stream */
212 if (sync = strchr(map, ',')) {
213 *sync = 0;
214 sync_file_idx = strtol(sync + 1, &sync, 0);
215 if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
216 av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
Martin Storsjöb85dbe62013-07-31 10:44:17217 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12218 }
219 if (*sync)
220 sync++;
221 for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
222 if (check_stream_specifier(input_files[sync_file_idx]->ctx,
223 input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
224 sync_stream_idx = i;
225 break;
226 }
227 if (i == input_files[sync_file_idx]->nb_streams) {
228 av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
229 "match any streams.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17230 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12231 }
232 }
233
234
235 if (map[0] == '[') {
236 /* this mapping refers to lavfi output */
237 const char *c = map + 1;
Anton Khirnov10bca662012-06-07 19:52:07238 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
Anton Khirnovf5e66822012-08-01 16:23:12239 m = &o->stream_maps[o->nb_stream_maps - 1];
240 m->linklabel = av_get_token(&c, "]");
241 if (!m->linklabel) {
242 av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
Martin Storsjöb85dbe62013-07-31 10:44:17243 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12244 }
245 } else {
246 file_idx = strtol(map, &p, 0);
247 if (file_idx >= nb_input_files || file_idx < 0) {
248 av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
Martin Storsjöb85dbe62013-07-31 10:44:17249 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12250 }
251 if (negative)
252 /* disable some already defined maps */
253 for (i = 0; i < o->nb_stream_maps; i++) {
254 m = &o->stream_maps[i];
255 if (file_idx == m->file_index &&
256 check_stream_specifier(input_files[m->file_index]->ctx,
257 input_files[m->file_index]->ctx->streams[m->stream_index],
258 *p == ':' ? p + 1 : p) > 0)
259 m->disabled = 1;
260 }
261 else
262 for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
263 if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
264 *p == ':' ? p + 1 : p) <= 0)
265 continue;
Anton Khirnov10bca662012-06-07 19:52:07266 GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
Anton Khirnovf5e66822012-08-01 16:23:12267 m = &o->stream_maps[o->nb_stream_maps - 1];
268
269 m->file_index = file_idx;
270 m->stream_index = i;
271
272 if (sync_file_idx >= 0) {
273 m->sync_file_index = sync_file_idx;
274 m->sync_stream_index = sync_stream_idx;
275 } else {
276 m->sync_file_index = file_idx;
277 m->sync_stream_index = i;
278 }
279 }
280 }
281
282 if (!m) {
283 av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17284 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12285 }
286
287 av_freep(&map);
288 return 0;
289}
290
Anton Khirnovd3810c42012-08-11 14:30:26291static int opt_attach(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:12292{
Anton Khirnovd3810c42012-08-11 14:30:26293 OptionsContext *o = optctx;
Anton Khirnov10bca662012-06-07 19:52:07294 GROW_ARRAY(o->attachments, o->nb_attachments);
Anton Khirnovf5e66822012-08-01 16:23:12295 o->attachments[o->nb_attachments - 1] = arg;
296 return 0;
297}
298
299/**
Diego Biurrunc1ef30a2012-08-24 11:31:50300 * Parse a metadata specifier passed as 'arg' parameter.
Diego Biurrun02e42752012-10-24 17:20:13301 * @param arg metadata string to parse
Anton Khirnovf5e66822012-08-01 16:23:12302 * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
303 * @param index for type c/p, chapter/program index is written here
304 * @param stream_spec for type s, the stream specifier is written here
305 */
306static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
307{
308 if (*arg) {
309 *type = *arg;
310 switch (*arg) {
311 case 'g':
312 break;
313 case 's':
314 if (*(++arg) && *arg != ':') {
315 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
Martin Storsjöb85dbe62013-07-31 10:44:17316 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12317 }
318 *stream_spec = *arg == ':' ? arg + 1 : "";
319 break;
320 case 'c':
321 case 'p':
322 if (*(++arg) == ':')
323 *index = strtol(++arg, NULL, 0);
324 break;
325 default:
326 av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
Martin Storsjöb85dbe62013-07-31 10:44:17327 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12328 }
329 } else
330 *type = 'g';
331}
332
333static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
334{
335 AVDictionary **meta_in = NULL;
336 AVDictionary **meta_out;
337 int i, ret = 0;
338 char type_in, type_out;
339 const char *istream_spec = NULL, *ostream_spec = NULL;
340 int idx_in = 0, idx_out = 0;
341
342 parse_meta_type(inspec, &type_in, &idx_in, &istream_spec);
343 parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
344
345 if (type_in == 'g' || type_out == 'g')
346 o->metadata_global_manual = 1;
347 if (type_in == 's' || type_out == 's')
348 o->metadata_streams_manual = 1;
349 if (type_in == 'c' || type_out == 'c')
350 o->metadata_chapters_manual = 1;
351
Anton Khirnova119c642012-10-16 07:53:39352 /* ic is NULL when just disabling automatic mappings */
353 if (!ic)
354 return 0;
355
Anton Khirnovf5e66822012-08-01 16:23:12356#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
357 if ((index) < 0 || (index) >= (nb_elems)) {\
358 av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
359 (desc), (index));\
Martin Storsjöb85dbe62013-07-31 10:44:17360 exit_program(1);\
Anton Khirnovf5e66822012-08-01 16:23:12361 }
362
363#define SET_DICT(type, meta, context, index)\
364 switch (type) {\
365 case 'g':\
366 meta = &context->metadata;\
367 break;\
368 case 'c':\
369 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
370 meta = &context->chapters[index]->metadata;\
371 break;\
372 case 'p':\
373 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
374 meta = &context->programs[index]->metadata;\
375 break;\
Anton Khirnov4632abc2012-11-24 06:55:42376 case 's':\
377 break; /* handled separately below */ \
Anton Khirnovf5e66822012-08-01 16:23:12378 default: av_assert0(0);\
379 }\
380
381 SET_DICT(type_in, meta_in, ic, idx_in);
382 SET_DICT(type_out, meta_out, oc, idx_out);
383
384 /* for input streams choose first matching stream */
385 if (type_in == 's') {
386 for (i = 0; i < ic->nb_streams; i++) {
387 if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
388 meta_in = &ic->streams[i]->metadata;
389 break;
390 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:17391 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12392 }
393 if (!meta_in) {
394 av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
Martin Storsjöb85dbe62013-07-31 10:44:17395 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12396 }
397 }
398
399 if (type_out == 's') {
400 for (i = 0; i < oc->nb_streams; i++) {
401 if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
402 meta_out = &oc->streams[i]->metadata;
403 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
404 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:17405 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12406 }
407 } else
408 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
409
410 return 0;
411}
412
413static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
414{
Anton Khirnovdb4766a2012-08-11 13:40:12415 const AVCodecDescriptor *desc;
Anton Khirnovf5e66822012-08-01 16:23:12416 const char *codec_string = encoder ? "encoder" : "decoder";
417 AVCodec *codec;
418
419 codec = encoder ?
420 avcodec_find_encoder_by_name(name) :
421 avcodec_find_decoder_by_name(name);
Anton Khirnovdb4766a2012-08-11 13:40:12422
423 if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
424 codec = encoder ? avcodec_find_encoder(desc->id) :
425 avcodec_find_decoder(desc->id);
426 if (codec)
427 av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
428 codec_string, codec->name, desc->name);
429 }
430
Anton Khirnovf5e66822012-08-01 16:23:12431 if (!codec) {
432 av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
Martin Storsjöb85dbe62013-07-31 10:44:17433 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12434 }
435 if (codec->type != type) {
436 av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
Martin Storsjöb85dbe62013-07-31 10:44:17437 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12438 }
439 return codec;
440}
441
442static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
443{
444 char *codec_name = NULL;
445
446 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
447 if (codec_name) {
448 AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
449 st->codec->codec_id = codec->id;
450 return codec;
451 } else
452 return avcodec_find_decoder(st->codec->codec_id);
453}
454
Diego Biurrunc1ef30a2012-08-24 11:31:50455/* Add all the streams from the given input file to the global
456 * list of input streams. */
Anton Khirnovf5e66822012-08-01 16:23:12457static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
458{
459 int i;
460
461 for (i = 0; i < ic->nb_streams; i++) {
462 AVStream *st = ic->streams[i];
463 AVCodecContext *dec = st->codec;
464 InputStream *ist = av_mallocz(sizeof(*ist));
Anton Khirnov07fd0a22013-11-02 21:06:36465 char *framerate = NULL, *hwaccel = NULL, *hwaccel_device = NULL;
Anton Khirnovf5e66822012-08-01 16:23:12466
467 if (!ist)
Martin Storsjöb85dbe62013-07-31 10:44:17468 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12469
Anton Khirnov10bca662012-06-07 19:52:07470 GROW_ARRAY(input_streams, nb_input_streams);
Anton Khirnovf5e66822012-08-01 16:23:12471 input_streams[nb_input_streams - 1] = ist;
472
473 ist->st = st;
474 ist->file_index = nb_input_files;
475 ist->discard = 1;
476 st->discard = AVDISCARD_ALL;
Anton Khirnovf5e66822012-08-01 16:23:12477
478 ist->ts_scale = 1.0;
479 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
480
481 ist->dec = choose_decoder(o, ic, st);
Anton Khirnove82cb792012-12-15 10:45:59482 ist->opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, ist->dec);
Anton Khirnovf5e66822012-08-01 16:23:12483
484 switch (dec->codec_type) {
485 case AVMEDIA_TYPE_VIDEO:
486 ist->resample_height = dec->height;
487 ist->resample_width = dec->width;
488 ist->resample_pix_fmt = dec->pix_fmt;
489
490 MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
491 if (framerate && av_parse_video_rate(&ist->framerate,
492 framerate) < 0) {
493 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
494 framerate);
Martin Storsjöb85dbe62013-07-31 10:44:17495 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12496 }
497
Anton Khirnov07fd0a22013-11-02 21:06:36498 MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
499 if (hwaccel) {
500 if (!strcmp(hwaccel, "none"))
501 ist->hwaccel_id = HWACCEL_NONE;
502 else if (!strcmp(hwaccel, "auto"))
503 ist->hwaccel_id = HWACCEL_AUTO;
504 else {
505 int i;
506 for (i = 0; hwaccels[i].name; i++) {
507 if (!strcmp(hwaccels[i].name, hwaccel)) {
508 ist->hwaccel_id = hwaccels[i].id;
509 break;
510 }
511 }
512
513 if (!ist->hwaccel_id) {
514 av_log(NULL, AV_LOG_FATAL, "Unrecognized hwaccel: %s.\n",
515 hwaccel);
516 av_log(NULL, AV_LOG_FATAL, "Supported hwaccels: ");
517 for (i = 0; hwaccels[i].name; i++)
518 av_log(NULL, AV_LOG_FATAL, "%s ", hwaccels[i].name);
519 av_log(NULL, AV_LOG_FATAL, "\n");
520 exit_program(1);
521 }
522 }
523 }
524
525 MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
526 if (hwaccel_device) {
527 ist->hwaccel_device = av_strdup(hwaccel_device);
528 if (!ist->hwaccel_device)
529 exit_program(1);
530 }
Anton Khirnovc255f0b2013-11-23 13:07:48531 ist->hwaccel_pix_fmt = AV_PIX_FMT_NONE;
Anton Khirnov07fd0a22013-11-02 21:06:36532
Anton Khirnovf5e66822012-08-01 16:23:12533 break;
534 case AVMEDIA_TYPE_AUDIO:
535 guess_input_channel_layout(ist);
536
537 ist->resample_sample_fmt = dec->sample_fmt;
538 ist->resample_sample_rate = dec->sample_rate;
539 ist->resample_channels = dec->channels;
540 ist->resample_channel_layout = dec->channel_layout;
541
542 break;
543 case AVMEDIA_TYPE_DATA:
544 case AVMEDIA_TYPE_SUBTITLE:
545 case AVMEDIA_TYPE_ATTACHMENT:
546 case AVMEDIA_TYPE_UNKNOWN:
547 break;
548 default:
549 abort();
550 }
551 }
552}
553
554static void assert_file_overwrite(const char *filename)
555{
Vittorio Giovara7748dd42013-07-31 12:48:49556 if (file_overwrite && file_skip) {
557 fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n");
558 exit_program(1);
559 }
560
Anton Khirnovf5e66822012-08-01 16:23:12561 if (!file_overwrite &&
562 (strchr(filename, ':') == NULL || filename[1] == ':' ||
563 av_strstart(filename, "file:", NULL))) {
564 if (avio_check(filename, 0) == 0) {
Vittorio Giovara7748dd42013-07-31 12:48:49565 if (!using_stdin && !file_skip) {
Anton Khirnovf5e66822012-08-01 16:23:12566 fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
567 fflush(stderr);
568 if (!read_yesno()) {
569 fprintf(stderr, "Not overwriting - exiting\n");
Martin Storsjöb85dbe62013-07-31 10:44:17570 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12571 }
572 }
573 else {
574 fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
Martin Storsjöb85dbe62013-07-31 10:44:17575 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12576 }
577 }
578 }
579}
580
581static void dump_attachment(AVStream *st, const char *filename)
582{
583 int ret;
584 AVIOContext *out = NULL;
585 AVDictionaryEntry *e;
586
587 if (!st->codec->extradata_size) {
588 av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
589 nb_input_files - 1, st->index);
590 return;
591 }
592 if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
593 filename = e->value;
594 if (!*filename) {
595 av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
596 "in stream #%d:%d.\n", nb_input_files - 1, st->index);
Martin Storsjöb85dbe62013-07-31 10:44:17597 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12598 }
599
600 assert_file_overwrite(filename);
601
602 if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
603 av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
604 filename);
Martin Storsjöb85dbe62013-07-31 10:44:17605 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12606 }
607
608 avio_write(out, st->codec->extradata, st->codec->extradata_size);
609 avio_flush(out);
610 avio_close(out);
611}
612
Anton Khirnov77bd1bc2012-06-08 19:35:16613static int open_input_file(OptionsContext *o, const char *filename)
Anton Khirnovf5e66822012-08-01 16:23:12614{
Anton Khirnov41d20082013-02-21 08:53:28615 InputFile *f;
Anton Khirnovf5e66822012-08-01 16:23:12616 AVFormatContext *ic;
617 AVInputFormat *file_iformat = NULL;
618 int err, i, ret;
619 int64_t timestamp;
620 uint8_t buf[128];
621 AVDictionary **opts;
Anton Khirnove7553f42013-02-21 09:58:46622 AVDictionary *unused_opts = NULL;
623 AVDictionaryEntry *e = NULL;
Anton Khirnovf5e66822012-08-01 16:23:12624 int orig_nb_streams; // number of streams before avformat_find_stream_info
625
626 if (o->format) {
627 if (!(file_iformat = av_find_input_format(o->format))) {
628 av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
Martin Storsjöb85dbe62013-07-31 10:44:17629 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12630 }
631 }
632
633 if (!strcmp(filename, "-"))
634 filename = "pipe:";
635
636 using_stdin |= !strncmp(filename, "pipe:", 5) ||
637 !strcmp(filename, "/dev/stdin");
638
639 /* get default parameters from command line */
640 ic = avformat_alloc_context();
641 if (!ic) {
642 print_error(filename, AVERROR(ENOMEM));
Martin Storsjöb85dbe62013-07-31 10:44:17643 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12644 }
645 if (o->nb_audio_sample_rate) {
646 snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
Anton Khirnov77bd1bc2012-06-08 19:35:16647 av_dict_set(&o->g->format_opts, "sample_rate", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:12648 }
649 if (o->nb_audio_channels) {
650 /* because we set audio_channels based on both the "ac" and
651 * "channel_layout" options, we need to check that the specified
652 * demuxer actually has the "channels" option before setting it */
653 if (file_iformat && file_iformat->priv_class &&
654 av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
655 AV_OPT_SEARCH_FAKE_OBJ)) {
656 snprintf(buf, sizeof(buf), "%d",
657 o->audio_channels[o->nb_audio_channels - 1].u.i);
Anton Khirnov77bd1bc2012-06-08 19:35:16658 av_dict_set(&o->g->format_opts, "channels", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:12659 }
660 }
661 if (o->nb_frame_rates) {
662 /* set the format-level framerate option;
663 * this is important for video grabbers, e.g. x11 */
664 if (file_iformat && file_iformat->priv_class &&
665 av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
666 AV_OPT_SEARCH_FAKE_OBJ)) {
Anton Khirnov77bd1bc2012-06-08 19:35:16667 av_dict_set(&o->g->format_opts, "framerate",
Anton Khirnovf5e66822012-08-01 16:23:12668 o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
669 }
670 }
671 if (o->nb_frame_sizes) {
Anton Khirnov77bd1bc2012-06-08 19:35:16672 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:12673 }
674 if (o->nb_frame_pix_fmts)
Anton Khirnov77bd1bc2012-06-08 19:35:16675 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:12676
677 ic->flags |= AVFMT_FLAG_NONBLOCK;
678 ic->interrupt_callback = int_cb;
679
680 /* open the input file with generic libav function */
Anton Khirnov77bd1bc2012-06-08 19:35:16681 err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
Anton Khirnovf5e66822012-08-01 16:23:12682 if (err < 0) {
683 print_error(filename, err);
Martin Storsjöb85dbe62013-07-31 10:44:17684 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12685 }
Anton Khirnov77bd1bc2012-06-08 19:35:16686 assert_avoptions(o->g->format_opts);
Anton Khirnovf5e66822012-08-01 16:23:12687
688 /* apply forced codec ids */
689 for (i = 0; i < ic->nb_streams; i++)
690 choose_decoder(o, ic, ic->streams[i]);
691
692 /* Set AVCodecContext options for avformat_find_stream_info */
Anton Khirnov77bd1bc2012-06-08 19:35:16693 opts = setup_find_stream_info_opts(ic, o->g->codec_opts);
Anton Khirnovf5e66822012-08-01 16:23:12694 orig_nb_streams = ic->nb_streams;
695
696 /* If not enough info to get the stream parameters, we decode the
697 first frames to get it. (used in mpeg case for example) */
698 ret = avformat_find_stream_info(ic, opts);
699 if (ret < 0) {
700 av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
701 avformat_close_input(&ic);
Martin Storsjöb85dbe62013-07-31 10:44:17702 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12703 }
704
Anton Khirnov56ee3f92013-06-15 07:35:10705 timestamp = (o->start_time == AV_NOPTS_VALUE) ? 0 : o->start_time;
Anton Khirnovf5e66822012-08-01 16:23:12706 /* add the stream start time */
707 if (ic->start_time != AV_NOPTS_VALUE)
708 timestamp += ic->start_time;
709
710 /* if seeking requested, we execute it */
Anton Khirnov56ee3f92013-06-15 07:35:10711 if (o->start_time != AV_NOPTS_VALUE) {
Anton Khirnovf5e66822012-08-01 16:23:12712 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
713 if (ret < 0) {
714 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
715 filename, (double)timestamp / AV_TIME_BASE);
716 }
717 }
718
719 /* update the current parameters so that they match the one of the input stream */
720 add_input_streams(o, ic);
721
722 /* dump the file content */
723 av_dump_format(ic, nb_input_files, filename, 0);
724
Anton Khirnov10bca662012-06-07 19:52:07725 GROW_ARRAY(input_files, nb_input_files);
Anton Khirnov41d20082013-02-21 08:53:28726 f = av_mallocz(sizeof(*f));
727 if (!f)
Martin Storsjöb85dbe62013-07-31 10:44:17728 exit_program(1);
Anton Khirnov41d20082013-02-21 08:53:28729 input_files[nb_input_files - 1] = f;
Anton Khirnovf5e66822012-08-01 16:23:12730
Anton Khirnov41d20082013-02-21 08:53:28731 f->ctx = ic;
732 f->ist_index = nb_input_streams - ic->nb_streams;
Anton Khirnov811bd072013-06-15 07:59:40733 f->start_time = o->start_time;
Anton Khirnov488a0fa2013-06-18 09:12:09734 f->recording_time = o->recording_time;
Anton Khirnov41d20082013-02-21 08:53:28735 f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
736 f->nb_streams = ic->nb_streams;
737 f->rate_emu = o->rate_emu;
Anton Khirnov811bd072013-06-15 07:59:40738 f->accurate_seek = o->accurate_seek;
Anton Khirnovf5e66822012-08-01 16:23:12739
Anton Khirnove7553f42013-02-21 09:58:46740 /* check if all codec options have been used */
741 unused_opts = strip_specifiers(o->g->codec_opts);
742 for (i = f->ist_index; i < nb_input_streams; i++) {
743 e = NULL;
744 while ((e = av_dict_get(input_streams[i]->opts, "", e,
745 AV_DICT_IGNORE_SUFFIX)))
746 av_dict_set(&unused_opts, e->key, NULL, 0);
747 }
748
749 e = NULL;
750 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
751 const AVClass *class = avcodec_get_class();
752 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
753 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
754 if (!option)
755 continue;
756 if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
757 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
758 "input file #%d (%s) is not a decoding option.\n", e->key,
759 option->help ? option->help : "", nb_input_files - 1,
760 filename);
Martin Storsjöb85dbe62013-07-31 10:44:17761 exit_program(1);
Anton Khirnove7553f42013-02-21 09:58:46762 }
763
764 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
765 "input file #%d (%s) has not been used for any stream. The most "
766 "likely reason is either wrong type (e.g. a video option with "
767 "no video streams) or that it is a private option of some decoder "
768 "which was not actually used for any stream.\n", e->key,
769 option->help ? option->help : "", nb_input_files - 1, filename);
770 }
771 av_dict_free(&unused_opts);
772
Anton Khirnovf5e66822012-08-01 16:23:12773 for (i = 0; i < o->nb_dump_attachment; i++) {
774 int j;
775
776 for (j = 0; j < ic->nb_streams; j++) {
777 AVStream *st = ic->streams[j];
778
779 if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
780 dump_attachment(st, o->dump_attachment[i].u.str);
781 }
782 }
783
784 for (i = 0; i < orig_nb_streams; i++)
785 av_dict_free(&opts[i]);
786 av_freep(&opts);
787
Anton Khirnovf5e66822012-08-01 16:23:12788 return 0;
789}
790
791static uint8_t *get_line(AVIOContext *s)
792{
793 AVIOContext *line;
794 uint8_t *buf;
795 char c;
796
797 if (avio_open_dyn_buf(&line) < 0) {
798 av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17799 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12800 }
801
802 while ((c = avio_r8(s)) && c != '\n')
803 avio_w8(line, c);
804 avio_w8(line, 0);
805 avio_close_dyn_buf(line, &buf);
806
807 return buf;
808}
809
810static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
811{
812 int i, ret = 1;
813 char filename[1000];
814 const char *base[3] = { getenv("AVCONV_DATADIR"),
815 getenv("HOME"),
816 AVCONV_DATADIR,
817 };
818
819 for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
820 if (!base[i])
821 continue;
822 if (codec_name) {
823 snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
824 i != 1 ? "" : "/.avconv", codec_name, preset_name);
825 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
826 }
827 if (ret) {
828 snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
829 i != 1 ? "" : "/.avconv", preset_name);
830 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
831 }
832 }
833 return ret;
834}
835
836static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
837{
838 char *codec_name = NULL;
839
840 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
841 if (!codec_name) {
842 ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
843 NULL, ost->st->codec->codec_type);
844 ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
845 } else if (!strcmp(codec_name, "copy"))
846 ost->stream_copy = 1;
847 else {
848 ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
849 ost->st->codec->codec_id = ost->enc->id;
850 }
851}
852
853static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
854{
855 OutputStream *ost;
856 AVStream *st = avformat_new_stream(oc, NULL);
857 int idx = oc->nb_streams - 1, ret = 0;
858 char *bsf = NULL, *next, *codec_tag = NULL;
859 AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
860 double qscale = -1;
Anton Khirnovf5e66822012-08-01 16:23:12861
862 if (!st) {
863 av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17864 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12865 }
866
867 if (oc->nb_streams - 1 < o->nb_streamid_map)
868 st->id = o->streamid_map[oc->nb_streams - 1];
869
Anton Khirnov10bca662012-06-07 19:52:07870 GROW_ARRAY(output_streams, nb_output_streams);
Anton Khirnovf5e66822012-08-01 16:23:12871 if (!(ost = av_mallocz(sizeof(*ost))))
Martin Storsjöb85dbe62013-07-31 10:44:17872 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12873 output_streams[nb_output_streams - 1] = ost;
874
Anton Khirnov3d624422013-04-10 12:46:20875 ost->file_index = nb_output_files - 1;
Anton Khirnovf5e66822012-08-01 16:23:12876 ost->index = idx;
877 ost->st = st;
878 st->codec->codec_type = type;
879 choose_encoder(o, oc, ost);
880 if (ost->enc) {
Anton Khirnov4e61a382012-10-22 20:40:22881 AVIOContext *s = NULL;
882 char *buf = NULL, *arg = NULL, *preset = NULL;
883
Anton Khirnov77bd1bc2012-06-08 19:35:16884 ost->opts = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
Anton Khirnov4e61a382012-10-22 20:40:22885
886 MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
887 if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
888 do {
889 buf = get_line(s);
890 if (!buf[0] || buf[0] == '#') {
891 av_free(buf);
892 continue;
893 }
894 if (!(arg = strchr(buf, '='))) {
895 av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
Martin Storsjöb85dbe62013-07-31 10:44:17896 exit_program(1);
Anton Khirnov4e61a382012-10-22 20:40:22897 }
898 *arg++ = 0;
899 av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
900 av_free(buf);
901 } while (!s->eof_reached);
902 avio_close(s);
903 }
904 if (ret) {
905 av_log(NULL, AV_LOG_FATAL,
906 "Preset %s specified for stream %d:%d, but could not be opened.\n",
907 preset, ost->file_index, ost->index);
Martin Storsjöb85dbe62013-07-31 10:44:17908 exit_program(1);
Anton Khirnov4e61a382012-10-22 20:40:22909 }
Martin Storsjödf0229a2013-02-27 21:22:39910 } else {
911 ost->opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL);
Anton Khirnovf5e66822012-08-01 16:23:12912 }
913
914 avcodec_get_context_defaults3(st->codec, ost->enc);
915 st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
916
Anton Khirnovf5e66822012-08-01 16:23:12917 ost->max_frames = INT64_MAX;
918 MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
919
920 MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
921 while (bsf) {
922 if (next = strchr(bsf, ','))
923 *next++ = 0;
924 if (!(bsfc = av_bitstream_filter_init(bsf))) {
925 av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
Martin Storsjöb85dbe62013-07-31 10:44:17926 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12927 }
928 if (bsfc_prev)
929 bsfc_prev->next = bsfc;
930 else
931 ost->bitstream_filters = bsfc;
932
933 bsfc_prev = bsfc;
934 bsf = next;
935 }
936
937 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
938 if (codec_tag) {
939 uint32_t tag = strtol(codec_tag, &next, 0);
940 if (*next)
941 tag = AV_RL32(codec_tag);
942 st->codec->codec_tag = tag;
943 }
944
945 MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
Anton Khirnovfb722a92012-10-09 15:40:20946 if (qscale >= 0) {
Anton Khirnovf5e66822012-08-01 16:23:12947 st->codec->flags |= CODEC_FLAG_QSCALE;
948 st->codec->global_quality = FF_QP2LAMBDA * qscale;
949 }
950
951 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
952 st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
953
Anton Khirnov77bd1bc2012-06-08 19:35:16954 av_opt_get_int(o->g->sws_opts, "sws_flags", 0, &ost->sws_flags);
Anton Khirnovf5e66822012-08-01 16:23:12955
Justin Ruggles5c7db092012-12-19 02:47:28956 av_dict_copy(&ost->resample_opts, o->g->resample_opts, 0);
957
Anton Khirnov716d4132012-10-06 10:10:34958 ost->pix_fmts[0] = ost->pix_fmts[1] = AV_PIX_FMT_NONE;
Anton Khirnov76d23f42013-04-24 06:34:44959 ost->last_mux_dts = AV_NOPTS_VALUE;
Anton Khirnovf5e66822012-08-01 16:23:12960
961 return ost;
962}
963
964static void parse_matrix_coeffs(uint16_t *dest, const char *str)
965{
966 int i;
967 const char *p = str;
968 for (i = 0;; i++) {
969 dest[i] = atoi(p);
970 if (i == 63)
971 break;
972 p = strchr(p, ',');
973 if (!p) {
974 av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
Martin Storsjöb85dbe62013-07-31 10:44:17975 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:12976 }
977 p++;
978 }
979}
980
Anton Khirnova4208b92013-03-13 13:24:45981/* read file contents into a string */
982static uint8_t *read_file(const char *filename)
983{
984 AVIOContext *pb = NULL;
985 AVIOContext *dyn_buf = NULL;
986 int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
987 uint8_t buf[1024], *str;
988
989 if (ret < 0) {
990 av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
991 return NULL;
992 }
993
994 ret = avio_open_dyn_buf(&dyn_buf);
995 if (ret < 0) {
996 avio_closep(&pb);
997 return NULL;
998 }
999 while ((ret = avio_read(pb, buf, sizeof(buf))) > 0)
1000 avio_write(dyn_buf, buf, ret);
1001 avio_w8(dyn_buf, 0);
1002 avio_closep(&pb);
1003
1004 ret = avio_close_dyn_buf(dyn_buf, &str);
1005 if (ret < 0)
1006 return NULL;
1007 return str;
1008}
1009
1010static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
1011 OutputStream *ost)
1012{
1013 AVStream *st = ost->st;
1014 char *filter = NULL, *filter_script = NULL;
1015
1016 MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
1017 MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
1018
1019 if (filter_script && filter) {
1020 av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
1021 "output stream #%d:%d.\n", nb_output_files, st->index);
Martin Storsjöb85dbe62013-07-31 10:44:171022 exit_program(1);
Anton Khirnova4208b92013-03-13 13:24:451023 }
1024
1025 if (filter_script)
1026 return read_file(filter_script);
1027 else if (filter)
1028 return av_strdup(filter);
1029
1030 return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
1031 "null" : "anull");
1032}
1033
Anton Khirnovf5e66822012-08-01 16:23:121034static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
1035{
1036 AVStream *st;
1037 OutputStream *ost;
1038 AVCodecContext *video_enc;
Anton Khirnov538bf762013-05-26 13:31:091039 char *frame_aspect_ratio = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121040
1041 ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
1042 st = ost->st;
1043 video_enc = st->codec;
1044
Anton Khirnov538bf762013-05-26 13:31:091045 MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
1046 if (frame_aspect_ratio)
1047 ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio);
1048
Anton Khirnovf5e66822012-08-01 16:23:121049 if (!ost->stream_copy) {
1050 const char *p = NULL;
1051 char *frame_rate = NULL, *frame_size = NULL;
Anton Khirnov538bf762013-05-26 13:31:091052 char *frame_pix_fmt = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121053 char *intra_matrix = NULL, *inter_matrix = NULL;
Anton Khirnov038c0b12012-08-19 06:29:441054 int do_pass = 0;
Anton Khirnovf5e66822012-08-01 16:23:121055 int i;
1056
1057 MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
1058 if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
1059 av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
Martin Storsjöb85dbe62013-07-31 10:44:171060 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121061 }
1062
1063 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
1064 if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
1065 av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
Martin Storsjöb85dbe62013-07-31 10:44:171066 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121067 }
1068
Anton Khirnovf5e66822012-08-01 16:23:121069 MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
Anton Khirnov716d4132012-10-06 10:10:341070 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:121071 av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
Martin Storsjöb85dbe62013-07-31 10:44:171072 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121073 }
1074 st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
1075
1076 MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
1077 if (intra_matrix) {
1078 if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
1079 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171080 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121081 }
1082 parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
1083 }
1084 MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
1085 if (inter_matrix) {
1086 if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
1087 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171088 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121089 }
1090 parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
1091 }
1092
1093 MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
1094 for (i = 0; p; i++) {
1095 int start, end, q;
1096 int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
1097 if (e != 3) {
1098 av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
Martin Storsjöb85dbe62013-07-31 10:44:171099 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121100 }
1101 video_enc->rc_override =
1102 av_realloc(video_enc->rc_override,
1103 sizeof(RcOverride) * (i + 1));
1104 video_enc->rc_override[i].start_frame = start;
1105 video_enc->rc_override[i].end_frame = end;
1106 if (q > 0) {
1107 video_enc->rc_override[i].qscale = q;
1108 video_enc->rc_override[i].quality_factor = 1.0;
1109 }
1110 else {
1111 video_enc->rc_override[i].qscale = 0;
1112 video_enc->rc_override[i].quality_factor = -q/100.0;
1113 }
1114 p = strchr(p, '/');
1115 if (p) p++;
1116 }
1117 video_enc->rc_override_count = i;
Anton Khirnovf5e66822012-08-01 16:23:121118 video_enc->intra_dc_precision = intra_dc_precision - 8;
1119
1120 /* two pass mode */
Anton Khirnov038c0b12012-08-19 06:29:441121 MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
Anton Khirnovf5e66822012-08-01 16:23:121122 if (do_pass) {
1123 if (do_pass == 1) {
1124 video_enc->flags |= CODEC_FLAG_PASS1;
1125 } else {
1126 video_enc->flags |= CODEC_FLAG_PASS2;
1127 }
1128 }
1129
Anton Khirnovbbcedad2012-08-19 07:15:481130 MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
1131 if (ost->logfile_prefix &&
1132 !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
Martin Storsjöb85dbe62013-07-31 10:44:171133 exit_program(1);
Anton Khirnovbbcedad2012-08-19 07:15:481134
Anton Khirnovf5e66822012-08-01 16:23:121135 MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
1136 if (ost->forced_keyframes)
1137 ost->forced_keyframes = av_strdup(ost->forced_keyframes);
1138
1139 MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
1140
1141 ost->top_field_first = -1;
1142 MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
1143
Anton Khirnova4208b92013-03-13 13:24:451144
1145 ost->avfilter = get_ost_filters(o, oc, ost);
1146 if (!ost->avfilter)
Martin Storsjöb85dbe62013-07-31 10:44:171147 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121148 } else {
1149 MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
1150 }
1151
1152 return ost;
1153}
1154
1155static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
1156{
1157 AVStream *st;
1158 OutputStream *ost;
1159 AVCodecContext *audio_enc;
1160
1161 ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO);
1162 st = ost->st;
1163
1164 audio_enc = st->codec;
1165 audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
1166
1167 if (!ost->stream_copy) {
1168 char *sample_fmt = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121169
1170 MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
1171
1172 MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
1173 if (sample_fmt &&
1174 (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
1175 av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
Martin Storsjöb85dbe62013-07-31 10:44:171176 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121177 }
1178
1179 MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
1180
Anton Khirnova4208b92013-03-13 13:24:451181 ost->avfilter = get_ost_filters(o, oc, ost);
1182 if (!ost->avfilter)
Martin Storsjöb85dbe62013-07-31 10:44:171183 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121184 }
1185
1186 return ost;
1187}
1188
1189static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
1190{
1191 OutputStream *ost;
1192
1193 ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
1194 if (!ost->stream_copy) {
1195 av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
Martin Storsjöb85dbe62013-07-31 10:44:171196 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121197 }
1198
1199 return ost;
1200}
1201
1202static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc)
1203{
1204 OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
1205 ost->stream_copy = 1;
Anton Khirnov3e175a22013-03-14 08:44:071206 ost->finished = 1;
Anton Khirnovf5e66822012-08-01 16:23:121207 return ost;
1208}
1209
1210static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
1211{
1212 AVStream *st;
1213 OutputStream *ost;
1214 AVCodecContext *subtitle_enc;
1215
1216 ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE);
1217 st = ost->st;
1218 subtitle_enc = st->codec;
1219
1220 subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
1221
1222 return ost;
1223}
1224
1225/* arg format is "output-stream-index:streamid-value". */
Anton Khirnovd3810c42012-08-11 14:30:261226static int opt_streamid(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121227{
Anton Khirnovd3810c42012-08-11 14:30:261228 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121229 int idx;
1230 char *p;
1231 char idx_str[16];
1232
1233 av_strlcpy(idx_str, arg, sizeof(idx_str));
1234 p = strchr(idx_str, ':');
1235 if (!p) {
1236 av_log(NULL, AV_LOG_FATAL,
1237 "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
1238 arg, opt);
Martin Storsjöb85dbe62013-07-31 10:44:171239 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121240 }
1241 *p++ = '\0';
1242 idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
1243 o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
1244 o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
1245 return 0;
1246}
1247
1248static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
1249{
1250 AVFormatContext *is = ifile->ctx;
1251 AVFormatContext *os = ofile->ctx;
Janne Grunau18ff4d22012-10-09 13:20:151252 AVChapter **tmp;
Anton Khirnovf5e66822012-08-01 16:23:121253 int i;
1254
Janne Grunau18ff4d22012-10-09 13:20:151255 tmp = av_realloc(os->chapters, sizeof(*os->chapters) * (is->nb_chapters + os->nb_chapters));
1256 if (!tmp)
1257 return AVERROR(ENOMEM);
1258 os->chapters = tmp;
1259
Anton Khirnovf5e66822012-08-01 16:23:121260 for (i = 0; i < is->nb_chapters; i++) {
1261 AVChapter *in_ch = is->chapters[i], *out_ch;
Anton Khirnov56ee3f92013-06-15 07:35:101262 int64_t start_time = (ofile->start_time == AV_NOPTS_VALUE) ? 0 : ofile->start_time;
1263 int64_t ts_off = av_rescale_q(start_time - ifile->ts_offset,
Anton Khirnovf5e66822012-08-01 16:23:121264 AV_TIME_BASE_Q, in_ch->time_base);
1265 int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
1266 av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
1267
1268
1269 if (in_ch->end < ts_off)
1270 continue;
1271 if (rt != INT64_MAX && in_ch->start > rt + ts_off)
1272 break;
1273
1274 out_ch = av_mallocz(sizeof(AVChapter));
1275 if (!out_ch)
1276 return AVERROR(ENOMEM);
1277
1278 out_ch->id = in_ch->id;
1279 out_ch->time_base = in_ch->time_base;
1280 out_ch->start = FFMAX(0, in_ch->start - ts_off);
1281 out_ch->end = FFMIN(rt, in_ch->end - ts_off);
1282
1283 if (copy_metadata)
1284 av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
1285
Janne Grunau18ff4d22012-10-09 13:20:151286 os->chapters[os->nb_chapters++] = out_ch;
Anton Khirnovf5e66822012-08-01 16:23:121287 }
1288 return 0;
1289}
1290
1291static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
1292 AVFormatContext *oc)
1293{
1294 OutputStream *ost;
1295
1296 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1297 ofilter->out_tmp->pad_idx)) {
1298 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1299 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1300 default:
1301 av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
1302 "currently.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171303 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121304 }
1305
1306 ost->source_index = -1;
1307 ost->filter = ofilter;
1308
1309 ofilter->ost = ost;
1310
1311 if (ost->stream_copy) {
1312 av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
1313 "which is fed from a complex filtergraph. Filtering and streamcopy "
1314 "cannot be used together.\n", ost->file_index, ost->index);
Martin Storsjöb85dbe62013-07-31 10:44:171315 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121316 }
1317
1318 if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
1319 av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171320 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121321 }
1322 avfilter_inout_free(&ofilter->out_tmp);
1323}
1324
1325static int configure_complex_filters(void)
1326{
1327 int i, ret = 0;
1328
1329 for (i = 0; i < nb_filtergraphs; i++)
1330 if (!filtergraphs[i]->graph &&
1331 (ret = configure_filtergraph(filtergraphs[i])) < 0)
1332 return ret;
1333 return 0;
1334}
1335
Anton Khirnov77bd1bc2012-06-08 19:35:161336static int open_output_file(OptionsContext *o, const char *filename)
Anton Khirnovf5e66822012-08-01 16:23:121337{
Anton Khirnovf5e66822012-08-01 16:23:121338 AVFormatContext *oc;
1339 int i, j, err;
1340 AVOutputFormat *file_oformat;
Anton Khirnov1da54e92013-02-21 08:53:281341 OutputFile *of;
Anton Khirnovf5e66822012-08-01 16:23:121342 OutputStream *ost;
1343 InputStream *ist;
Anton Khirnove7553f42013-02-21 09:58:461344 AVDictionary *unused_opts = NULL;
1345 AVDictionaryEntry *e = NULL;
Anton Khirnovf5e66822012-08-01 16:23:121346
1347 if (configure_complex_filters() < 0) {
1348 av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
Martin Storsjöb85dbe62013-07-31 10:44:171349 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121350 }
1351
Anton Khirnov3d624422013-04-10 12:46:201352 GROW_ARRAY(output_files, nb_output_files);
1353 of = av_mallocz(sizeof(*of));
1354 if (!of)
Martin Storsjöb85dbe62013-07-31 10:44:171355 exit_program(1);
Anton Khirnov3d624422013-04-10 12:46:201356 output_files[nb_output_files - 1] = of;
1357
1358 of->ost_index = nb_output_streams;
1359 of->recording_time = o->recording_time;
1360 of->start_time = o->start_time;
1361 of->limit_filesize = o->limit_filesize;
1362 of->shortest = o->shortest;
1363 av_dict_copy(&of->opts, o->g->format_opts, 0);
1364
Anton Khirnovf5e66822012-08-01 16:23:121365 if (!strcmp(filename, "-"))
1366 filename = "pipe:";
1367
1368 oc = avformat_alloc_context();
1369 if (!oc) {
1370 print_error(filename, AVERROR(ENOMEM));
Martin Storsjöb85dbe62013-07-31 10:44:171371 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121372 }
Anton Khirnov3d624422013-04-10 12:46:201373 of->ctx = oc;
1374 if (o->recording_time != INT64_MAX)
1375 oc->duration = o->recording_time;
Anton Khirnovf5e66822012-08-01 16:23:121376
1377 if (o->format) {
1378 file_oformat = av_guess_format(o->format, NULL, NULL);
1379 if (!file_oformat) {
1380 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:171381 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121382 }
1383 } else {
1384 file_oformat = av_guess_format(NULL, filename, NULL);
1385 if (!file_oformat) {
1386 av_log(NULL, AV_LOG_FATAL, "Unable to find a suitable output format for '%s'\n",
1387 filename);
Martin Storsjöb85dbe62013-07-31 10:44:171388 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121389 }
1390 }
1391
1392 oc->oformat = file_oformat;
1393 oc->interrupt_callback = int_cb;
1394 av_strlcpy(oc->filename, filename, sizeof(oc->filename));
1395
1396 /* create streams for all unlabeled output pads */
1397 for (i = 0; i < nb_filtergraphs; i++) {
1398 FilterGraph *fg = filtergraphs[i];
1399 for (j = 0; j < fg->nb_outputs; j++) {
1400 OutputFilter *ofilter = fg->outputs[j];
1401
1402 if (!ofilter->out_tmp || ofilter->out_tmp->name)
1403 continue;
1404
1405 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
1406 ofilter->out_tmp->pad_idx)) {
1407 case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break;
1408 case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break;
1409 case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
1410 }
1411 init_output_filter(ofilter, o, oc);
1412 }
1413 }
1414
1415 if (!o->nb_stream_maps) {
1416 /* pick the "best" stream of each type */
1417#define NEW_STREAM(type, index)\
1418 if (index >= 0) {\
1419 ost = new_ ## type ## _stream(o, oc);\
1420 ost->source_index = index;\
1421 ost->sync_ist = input_streams[index];\
1422 input_streams[index]->discard = 0;\
1423 input_streams[index]->st->discard = AVDISCARD_NONE;\
1424 }
1425
1426 /* video: highest resolution */
1427 if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
1428 int area = 0, idx = -1;
1429 for (i = 0; i < nb_input_streams; i++) {
1430 ist = input_streams[i];
1431 if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
1432 ist->st->codec->width * ist->st->codec->height > area) {
1433 area = ist->st->codec->width * ist->st->codec->height;
1434 idx = i;
1435 }
1436 }
1437 NEW_STREAM(video, idx);
1438 }
1439
1440 /* audio: most channels */
1441 if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
1442 int channels = 0, idx = -1;
1443 for (i = 0; i < nb_input_streams; i++) {
1444 ist = input_streams[i];
1445 if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
1446 ist->st->codec->channels > channels) {
1447 channels = ist->st->codec->channels;
1448 idx = i;
1449 }
1450 }
1451 NEW_STREAM(audio, idx);
1452 }
1453
1454 /* subtitles: pick first */
1455 if (!o->subtitle_disable && oc->oformat->subtitle_codec != AV_CODEC_ID_NONE) {
1456 for (i = 0; i < nb_input_streams; i++)
1457 if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1458 NEW_STREAM(subtitle, i);
1459 break;
1460 }
1461 }
1462 /* do something with data? */
1463 } else {
1464 for (i = 0; i < o->nb_stream_maps; i++) {
1465 StreamMap *map = &o->stream_maps[i];
1466
1467 if (map->disabled)
1468 continue;
1469
1470 if (map->linklabel) {
1471 FilterGraph *fg;
1472 OutputFilter *ofilter = NULL;
1473 int j, k;
1474
1475 for (j = 0; j < nb_filtergraphs; j++) {
1476 fg = filtergraphs[j];
1477 for (k = 0; k < fg->nb_outputs; k++) {
1478 AVFilterInOut *out = fg->outputs[k]->out_tmp;
1479 if (out && !strcmp(out->name, map->linklabel)) {
1480 ofilter = fg->outputs[k];
1481 goto loop_end;
1482 }
1483 }
1484 }
1485loop_end:
1486 if (!ofilter) {
1487 av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
1488 "in any defined filter graph.\n", map->linklabel);
Martin Storsjöb85dbe62013-07-31 10:44:171489 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121490 }
1491 init_output_filter(ofilter, o, oc);
1492 } else {
1493 ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
1494 switch (ist->st->codec->codec_type) {
1495 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
1496 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
1497 case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
1498 case AVMEDIA_TYPE_DATA: ost = new_data_stream(o, oc); break;
1499 case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
1500 default:
1501 av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
1502 map->file_index, map->stream_index);
Martin Storsjöb85dbe62013-07-31 10:44:171503 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121504 }
1505
1506 ost->source_index = input_files[map->file_index]->ist_index + map->stream_index;
1507 ost->sync_ist = input_streams[input_files[map->sync_file_index]->ist_index +
1508 map->sync_stream_index];
1509 ist->discard = 0;
1510 ist->st->discard = AVDISCARD_NONE;
1511 }
1512 }
1513 }
1514
1515 /* handle attached files */
1516 for (i = 0; i < o->nb_attachments; i++) {
1517 AVIOContext *pb;
1518 uint8_t *attachment;
1519 const char *p;
1520 int64_t len;
1521
1522 if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
1523 av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
1524 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171525 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121526 }
1527 if ((len = avio_size(pb)) <= 0) {
1528 av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
1529 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171530 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121531 }
1532 if (!(attachment = av_malloc(len))) {
1533 av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
1534 o->attachments[i]);
Martin Storsjöb85dbe62013-07-31 10:44:171535 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121536 }
1537 avio_read(pb, attachment, len);
1538
1539 ost = new_attachment_stream(o, oc);
1540 ost->stream_copy = 0;
1541 ost->source_index = -1;
1542 ost->attachment_filename = o->attachments[i];
1543 ost->st->codec->extradata = attachment;
1544 ost->st->codec->extradata_size = len;
1545
1546 p = strrchr(o->attachments[i], '/');
1547 av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
1548 avio_close(pb);
1549 }
1550
Anton Khirnove7553f42013-02-21 09:58:461551 /* check if all codec options have been used */
1552 unused_opts = strip_specifiers(o->g->codec_opts);
1553 for (i = of->ost_index; i < nb_output_streams; i++) {
1554 e = NULL;
1555 while ((e = av_dict_get(output_streams[i]->opts, "", e,
1556 AV_DICT_IGNORE_SUFFIX)))
1557 av_dict_set(&unused_opts, e->key, NULL, 0);
1558 }
1559
1560 e = NULL;
1561 while ((e = av_dict_get(unused_opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
1562 const AVClass *class = avcodec_get_class();
1563 const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
1564 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
1565 if (!option)
1566 continue;
1567 if (!(option->flags & AV_OPT_FLAG_ENCODING_PARAM)) {
1568 av_log(NULL, AV_LOG_ERROR, "Codec AVOption %s (%s) specified for "
1569 "output file #%d (%s) is not an encoding option.\n", e->key,
1570 option->help ? option->help : "", nb_output_files - 1,
1571 filename);
Martin Storsjöb85dbe62013-07-31 10:44:171572 exit_program(1);
Anton Khirnove7553f42013-02-21 09:58:461573 }
1574
1575 av_log(NULL, AV_LOG_WARNING, "Codec AVOption %s (%s) specified for "
1576 "output file #%d (%s) has not been used for any stream. The most "
1577 "likely reason is either wrong type (e.g. a video option with "
1578 "no video streams) or that it is a private option of some encoder "
1579 "which was not actually used for any stream.\n", e->key,
1580 option->help ? option->help : "", nb_output_files - 1, filename);
1581 }
1582 av_dict_free(&unused_opts);
1583
Anton Khirnovf5e66822012-08-01 16:23:121584 /* check filename in case of an image number is expected */
1585 if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
1586 if (!av_filename_number_test(oc->filename)) {
1587 print_error(oc->filename, AVERROR(EINVAL));
Martin Storsjöb85dbe62013-07-31 10:44:171588 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121589 }
1590 }
1591
1592 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
1593 /* test if it already exists to avoid losing precious files */
1594 assert_file_overwrite(filename);
1595
1596 /* open the file */
1597 if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
1598 &oc->interrupt_callback,
Anton Khirnov1da54e92013-02-21 08:53:281599 &of->opts)) < 0) {
Anton Khirnovf5e66822012-08-01 16:23:121600 print_error(filename, err);
Martin Storsjöb85dbe62013-07-31 10:44:171601 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121602 }
1603 }
1604
1605 if (o->mux_preload) {
1606 uint8_t buf[64];
1607 snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
Anton Khirnov1da54e92013-02-21 08:53:281608 av_dict_set(&of->opts, "preload", buf, 0);
Anton Khirnovf5e66822012-08-01 16:23:121609 }
1610 oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
1611 oc->flags |= AVFMT_FLAG_NONBLOCK;
1612
1613 /* copy metadata */
1614 for (i = 0; i < o->nb_metadata_map; i++) {
1615 char *p;
1616 int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
1617
Anton Khirnovf5e66822012-08-01 16:23:121618 if (in_file_index >= nb_input_files) {
1619 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:171620 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121621 }
Anton Khirnova119c642012-10-16 07:53:391622 copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
1623 in_file_index >= 0 ?
1624 input_files[in_file_index]->ctx : NULL, o);
Anton Khirnovf5e66822012-08-01 16:23:121625 }
1626
1627 /* copy chapters */
1628 if (o->chapters_input_file >= nb_input_files) {
1629 if (o->chapters_input_file == INT_MAX) {
1630 /* copy chapters from the first input file that has them*/
1631 o->chapters_input_file = -1;
1632 for (i = 0; i < nb_input_files; i++)
1633 if (input_files[i]->ctx->nb_chapters) {
1634 o->chapters_input_file = i;
1635 break;
1636 }
1637 } else {
1638 av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
1639 o->chapters_input_file);
Martin Storsjöb85dbe62013-07-31 10:44:171640 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121641 }
1642 }
1643 if (o->chapters_input_file >= 0)
Anton Khirnov1da54e92013-02-21 08:53:281644 copy_chapters(input_files[o->chapters_input_file], of,
Anton Khirnovf5e66822012-08-01 16:23:121645 !o->metadata_chapters_manual);
1646
1647 /* copy global metadata by default */
1648 if (!o->metadata_global_manual && nb_input_files)
1649 av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
1650 AV_DICT_DONT_OVERWRITE);
1651 if (!o->metadata_streams_manual)
Anton Khirnov1da54e92013-02-21 08:53:281652 for (i = of->ost_index; i < nb_output_streams; i++) {
Anton Khirnovf5e66822012-08-01 16:23:121653 InputStream *ist;
1654 if (output_streams[i]->source_index < 0) /* this is true e.g. for attached files */
1655 continue;
1656 ist = input_streams[output_streams[i]->source_index];
1657 av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
1658 }
1659
1660 /* process manually set metadata */
1661 for (i = 0; i < o->nb_metadata; i++) {
1662 AVDictionary **m;
1663 char type, *val;
1664 const char *stream_spec;
1665 int index = 0, j, ret;
1666
1667 val = strchr(o->metadata[i].u.str, '=');
1668 if (!val) {
1669 av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
1670 o->metadata[i].u.str);
Martin Storsjöb85dbe62013-07-31 10:44:171671 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121672 }
1673 *val++ = 0;
1674
1675 parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
1676 if (type == 's') {
1677 for (j = 0; j < oc->nb_streams; j++) {
1678 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
1679 av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
1680 } else if (ret < 0)
Martin Storsjöb85dbe62013-07-31 10:44:171681 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121682 }
1683 }
1684 else {
1685 switch (type) {
1686 case 'g':
1687 m = &oc->metadata;
1688 break;
1689 case 'c':
1690 if (index < 0 || index >= oc->nb_chapters) {
1691 av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
Martin Storsjöb85dbe62013-07-31 10:44:171692 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121693 }
1694 m = &oc->chapters[index]->metadata;
1695 break;
1696 default:
1697 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
Martin Storsjöb85dbe62013-07-31 10:44:171698 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121699 }
1700 av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
1701 }
1702 }
1703
Anton Khirnov77bd1bc2012-06-08 19:35:161704 return 0;
Anton Khirnovf5e66822012-08-01 16:23:121705}
1706
Anton Khirnovd3810c42012-08-11 14:30:261707static int opt_target(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121708{
Anton Khirnovd3810c42012-08-11 14:30:261709 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121710 enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
1711 static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
1712
1713 if (!strncmp(arg, "pal-", 4)) {
1714 norm = PAL;
1715 arg += 4;
1716 } else if (!strncmp(arg, "ntsc-", 5)) {
1717 norm = NTSC;
1718 arg += 5;
1719 } else if (!strncmp(arg, "film-", 5)) {
1720 norm = FILM;
1721 arg += 5;
1722 } else {
1723 /* Try to determine PAL/NTSC by peeking in the input files */
1724 if (nb_input_files) {
1725 int i, j, fr;
1726 for (j = 0; j < nb_input_files; j++) {
1727 for (i = 0; i < input_files[j]->nb_streams; i++) {
1728 AVCodecContext *c = input_files[j]->ctx->streams[i]->codec;
1729 if (c->codec_type != AVMEDIA_TYPE_VIDEO)
1730 continue;
1731 fr = c->time_base.den * 1000 / c->time_base.num;
1732 if (fr == 25000) {
1733 norm = PAL;
1734 break;
1735 } else if ((fr == 29970) || (fr == 23976)) {
1736 norm = NTSC;
1737 break;
1738 }
1739 }
1740 if (norm != UNKNOWN)
1741 break;
1742 }
1743 }
1744 if (norm != UNKNOWN)
1745 av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
1746 }
1747
1748 if (norm == UNKNOWN) {
1749 av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
1750 av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
1751 av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
Martin Storsjöb85dbe62013-07-31 10:44:171752 exit_program(1);
Anton Khirnovf5e66822012-08-01 16:23:121753 }
1754
1755 if (!strcmp(arg, "vcd")) {
1756 opt_video_codec(o, "c:v", "mpeg1video");
1757 opt_audio_codec(o, "c:a", "mp2");
1758 parse_option(o, "f", "vcd", options);
1759
1760 parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
1761 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221762 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121763
Anton Khirnov11d957f2012-08-29 12:37:221764 opt_default(NULL, "b", "1150000");
1765 opt_default(NULL, "maxrate", "1150000");
1766 opt_default(NULL, "minrate", "1150000");
1767 opt_default(NULL, "bufsize", "327680"); // 40*1024*8;
Anton Khirnovf5e66822012-08-01 16:23:121768
Anton Khirnov11d957f2012-08-29 12:37:221769 opt_default(NULL, "b:a", "224000");
Anton Khirnovf5e66822012-08-01 16:23:121770 parse_option(o, "ar", "44100", options);
1771 parse_option(o, "ac", "2", options);
1772
Anton Khirnov11d957f2012-08-29 12:37:221773 opt_default(NULL, "packetsize", "2324");
1774 opt_default(NULL, "muxrate", "1411200"); // 2352 * 75 * 8;
Anton Khirnovf5e66822012-08-01 16:23:121775
1776 /* We have to offset the PTS, so that it is consistent with the SCR.
1777 SCR starts at 36000, but the first two packs contain only padding
1778 and the first pack from the other stream, respectively, may also have
1779 been written before.
1780 So the real data starts at SCR 36000+3*1200. */
1781 o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
1782 } else if (!strcmp(arg, "svcd")) {
1783
1784 opt_video_codec(o, "c:v", "mpeg2video");
1785 opt_audio_codec(o, "c:a", "mp2");
1786 parse_option(o, "f", "svcd", options);
1787
1788 parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
1789 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221790 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121791
Anton Khirnov11d957f2012-08-29 12:37:221792 opt_default(NULL, "b", "2040000");
1793 opt_default(NULL, "maxrate", "2516000");
1794 opt_default(NULL, "minrate", "0"); // 1145000;
1795 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
1796 opt_default(NULL, "flags", "+scan_offset");
Anton Khirnovf5e66822012-08-01 16:23:121797
1798
Anton Khirnov11d957f2012-08-29 12:37:221799 opt_default(NULL, "b:a", "224000");
Anton Khirnovf5e66822012-08-01 16:23:121800 parse_option(o, "ar", "44100", options);
1801
Anton Khirnov11d957f2012-08-29 12:37:221802 opt_default(NULL, "packetsize", "2324");
Anton Khirnovf5e66822012-08-01 16:23:121803
1804 } else if (!strcmp(arg, "dvd")) {
1805
1806 opt_video_codec(o, "c:v", "mpeg2video");
1807 opt_audio_codec(o, "c:a", "ac3");
1808 parse_option(o, "f", "dvd", options);
1809
1810 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
1811 parse_option(o, "r", frame_rates[norm], options);
Anton Khirnov11d957f2012-08-29 12:37:221812 opt_default(NULL, "g", norm == PAL ? "15" : "18");
Anton Khirnovf5e66822012-08-01 16:23:121813
Anton Khirnov11d957f2012-08-29 12:37:221814 opt_default(NULL, "b", "6000000");
1815 opt_default(NULL, "maxrate", "9000000");
1816 opt_default(NULL, "minrate", "0"); // 1500000;
1817 opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
Anton Khirnovf5e66822012-08-01 16:23:121818
Anton Khirnov11d957f2012-08-29 12:37:221819 opt_default(NULL, "packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
1820 opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
Anton Khirnovf5e66822012-08-01 16:23:121821
Anton Khirnov11d957f2012-08-29 12:37:221822 opt_default(NULL, "b:a", "448000");
Anton Khirnovf5e66822012-08-01 16:23:121823 parse_option(o, "ar", "48000", options);
1824
1825 } else if (!strncmp(arg, "dv", 2)) {
1826
1827 parse_option(o, "f", "dv", options);
1828
1829 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
1830 parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
1831 norm == PAL ? "yuv420p" : "yuv411p", options);
1832 parse_option(o, "r", frame_rates[norm], options);
1833
1834 parse_option(o, "ar", "48000", options);
1835 parse_option(o, "ac", "2", options);
1836
1837 } else {
1838 av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
1839 return AVERROR(EINVAL);
1840 }
1841 return 0;
1842}
1843
Anton Khirnov11d957f2012-08-29 12:37:221844static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121845{
1846 av_free (vstats_filename);
1847 vstats_filename = av_strdup (arg);
1848 return 0;
1849}
1850
Anton Khirnov11d957f2012-08-29 12:37:221851static int opt_vstats(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121852{
1853 char filename[40];
1854 time_t today2 = time(NULL);
1855 struct tm *today = localtime(&today2);
1856
1857 snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
1858 today->tm_sec);
Anton Khirnov11d957f2012-08-29 12:37:221859 return opt_vstats_file(NULL, opt, filename);
Anton Khirnovf5e66822012-08-01 16:23:121860}
1861
Anton Khirnovd3810c42012-08-11 14:30:261862static int opt_video_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121863{
Anton Khirnovd3810c42012-08-11 14:30:261864 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121865 return parse_option(o, "frames:v", arg, options);
1866}
1867
Anton Khirnovd3810c42012-08-11 14:30:261868static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121869{
Anton Khirnovd3810c42012-08-11 14:30:261870 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121871 return parse_option(o, "frames:a", arg, options);
1872}
1873
Anton Khirnovd3810c42012-08-11 14:30:261874static int opt_data_frames(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121875{
Anton Khirnovd3810c42012-08-11 14:30:261876 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121877 return parse_option(o, "frames:d", arg, options);
1878}
1879
Anton Khirnovd3810c42012-08-11 14:30:261880static int opt_video_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121881{
Anton Khirnovd3810c42012-08-11 14:30:261882 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121883 return parse_option(o, "tag:v", arg, options);
1884}
1885
Anton Khirnovd3810c42012-08-11 14:30:261886static int opt_audio_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121887{
Anton Khirnovd3810c42012-08-11 14:30:261888 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121889 return parse_option(o, "tag:a", arg, options);
1890}
1891
Anton Khirnovd3810c42012-08-11 14:30:261892static int opt_subtitle_tag(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121893{
Anton Khirnovd3810c42012-08-11 14:30:261894 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121895 return parse_option(o, "tag:s", arg, options);
1896}
1897
Anton Khirnovd3810c42012-08-11 14:30:261898static int opt_video_filters(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121899{
Anton Khirnovd3810c42012-08-11 14:30:261900 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121901 return parse_option(o, "filter:v", arg, options);
1902}
1903
Anton Khirnovd3810c42012-08-11 14:30:261904static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121905{
Anton Khirnovd3810c42012-08-11 14:30:261906 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121907 return parse_option(o, "filter:a", arg, options);
1908}
1909
Anton Khirnov11d957f2012-08-29 12:37:221910static int opt_vsync(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121911{
1912 if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR;
1913 else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR;
1914 else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
1915
1916 if (video_sync_method == VSYNC_AUTO)
1917 video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
1918 return 0;
1919}
1920
Anton Khirnovd3810c42012-08-11 14:30:261921static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121922{
Anton Khirnovd3810c42012-08-11 14:30:261923 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121924 char layout_str[32];
1925 char *stream_str;
1926 char *ac_str;
1927 int ret, channels, ac_str_size;
1928 uint64_t layout;
1929
1930 layout = av_get_channel_layout(arg);
1931 if (!layout) {
1932 av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
1933 return AVERROR(EINVAL);
1934 }
1935 snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
Anton Khirnov11d957f2012-08-29 12:37:221936 ret = opt_default(NULL, opt, layout_str);
Anton Khirnovf5e66822012-08-01 16:23:121937 if (ret < 0)
1938 return ret;
1939
1940 /* set 'ac' option based on channel layout */
1941 channels = av_get_channel_layout_nb_channels(layout);
1942 snprintf(layout_str, sizeof(layout_str), "%d", channels);
1943 stream_str = strchr(opt, ':');
1944 ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
1945 ac_str = av_mallocz(ac_str_size);
1946 if (!ac_str)
1947 return AVERROR(ENOMEM);
1948 av_strlcpy(ac_str, "ac", 3);
1949 if (stream_str)
1950 av_strlcat(ac_str, stream_str, ac_str_size);
1951 ret = parse_option(o, ac_str, layout_str, options);
1952 av_free(ac_str);
1953
1954 return ret;
1955}
1956
Anton Khirnovd3810c42012-08-11 14:30:261957static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121958{
Anton Khirnovd3810c42012-08-11 14:30:261959 OptionsContext *o = optctx;
Anton Khirnovf5e66822012-08-01 16:23:121960 return parse_option(o, "q:a", arg, options);
1961}
1962
Anton Khirnov11d957f2012-08-29 12:37:221963static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121964{
Anton Khirnov10bca662012-06-07 19:52:071965 GROW_ARRAY(filtergraphs, nb_filtergraphs);
Anton Khirnovf5e66822012-08-01 16:23:121966 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
1967 return AVERROR(ENOMEM);
Anton Khirnova4208b92013-03-13 13:24:451968 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
1969 filtergraphs[nb_filtergraphs - 1]->graph_desc = av_strdup(arg);
1970 if (!filtergraphs[nb_filtergraphs - 1]->graph_desc)
1971 return AVERROR(ENOMEM);
1972 return 0;
1973}
1974
1975static int opt_filter_complex_script(void *optctx, const char *opt, const char *arg)
1976{
1977 uint8_t *graph_desc = read_file(arg);
1978 if (!graph_desc)
1979 return AVERROR(EINVAL);
1980
1981 GROW_ARRAY(filtergraphs, nb_filtergraphs);
1982 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
1983 return AVERROR(ENOMEM);
1984 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
1985 filtergraphs[nb_filtergraphs - 1]->graph_desc = graph_desc;
Anton Khirnovf5e66822012-08-01 16:23:121986 return 0;
1987}
1988
Anton Khirnova3ad68d2012-08-13 18:06:251989void show_help_default(const char *opt, const char *arg)
Anton Khirnovf5e66822012-08-01 16:23:121990{
Anton Khirnovf9fada22012-08-15 08:31:461991 /* per-file options have at least one of those set */
Anton Khirnov11d957f2012-08-29 12:37:221992 const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
Anton Khirnov6e3857f2012-08-14 06:56:321993 int show_advanced = 0, show_avoptions = 0;
1994
Janne Grunau8d09d392012-10-10 18:35:261995 if (opt && *opt) {
Anton Khirnov6e3857f2012-08-14 06:56:321996 if (!strcmp(opt, "long"))
1997 show_advanced = 1;
1998 else if (!strcmp(opt, "full"))
1999 show_advanced = show_avoptions = 1;
2000 else
2001 av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
2002 }
Anton Khirnova3ad68d2012-08-13 18:06:252003
Anton Khirnovf5e66822012-08-01 16:23:122004 show_usage();
Anton Khirnov6e3857f2012-08-14 06:56:322005
2006 printf("Getting help:\n"
2007 " -h -- print basic options\n"
2008 " -h long -- print more options\n"
2009 " -h full -- print all options (including all format and codec specific options, very long)\n"
2010 " See man %s for detailed description of the options.\n"
2011 "\n", program_name);
2012
Anton Khirnovf8b1e662012-08-14 06:21:422013 show_help_options(options, "Print help / information / capabilities:",
Anton Khirnovf9fada22012-08-15 08:31:462014 OPT_EXIT, 0, 0);
2015
2016 show_help_options(options, "Global options (affect whole program "
2017 "instead of just one file:",
2018 0, per_file | OPT_EXIT | OPT_EXPERT, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322019 if (show_advanced)
Anton Khirnovf9fada22012-08-15 08:31:462020 show_help_options(options, "Advanced global options:", OPT_EXPERT,
2021 per_file | OPT_EXIT, 0);
2022
2023 show_help_options(options, "Per-file main options:", 0,
2024 OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
2025 OPT_EXIT, per_file);
2026 if (show_advanced)
2027 show_help_options(options, "Advanced per-file options:",
2028 OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
Anton Khirnov6e3857f2012-08-14 06:56:322029
Anton Khirnovdc4c24a2012-08-11 17:33:272030 show_help_options(options, "Video options:",
Anton Khirnovf9fada22012-08-15 08:31:462031 OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322032 if (show_advanced)
2033 show_help_options(options, "Advanced Video options:",
Anton Khirnovf9fada22012-08-15 08:31:462034 OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322035
Anton Khirnovdc4c24a2012-08-11 17:33:272036 show_help_options(options, "Audio options:",
Anton Khirnovf9fada22012-08-15 08:31:462037 OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
Anton Khirnov6e3857f2012-08-14 06:56:322038 if (show_advanced)
2039 show_help_options(options, "Advanced Audio options:",
Anton Khirnovf9fada22012-08-15 08:31:462040 OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
Anton Khirnovdc4c24a2012-08-11 17:33:272041 show_help_options(options, "Subtitle options:",
Anton Khirnovf9fada22012-08-15 08:31:462042 OPT_SUBTITLE, 0, 0);
Anton Khirnovf5e66822012-08-01 16:23:122043 printf("\n");
Anton Khirnov6e3857f2012-08-14 06:56:322044
2045 if (show_avoptions) {
2046 int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
2047 show_help_children(avcodec_get_class(), flags);
2048 show_help_children(avformat_get_class(), flags);
2049 show_help_children(sws_get_class(), flags);
Anton Khirnovdc574652013-03-13 08:10:342050 show_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM);
Anton Khirnov6e3857f2012-08-14 06:56:322051 }
Anton Khirnovf5e66822012-08-01 16:23:122052}
2053
2054void show_usage(void)
2055{
2056 printf("Hyper fast Audio and Video encoder\n");
2057 printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
2058 printf("\n");
2059}
2060
Anton Khirnov77bd1bc2012-06-08 19:35:162061enum OptGroup {
2062 GROUP_OUTFILE,
2063 GROUP_INFILE,
2064};
2065
2066static const OptionGroupDef groups[] = {
Anton Khirnov9d3009c2013-02-20 07:02:162067 [GROUP_OUTFILE] = { "output file", NULL, OPT_OUTPUT },
2068 [GROUP_INFILE] = { "input file", "i", OPT_INPUT },
Anton Khirnov77bd1bc2012-06-08 19:35:162069};
2070
2071static int open_files(OptionGroupList *l, const char *inout,
2072 int (*open_file)(OptionsContext*, const char*))
2073{
2074 int i, ret;
2075
2076 for (i = 0; i < l->nb_groups; i++) {
2077 OptionGroup *g = &l->groups[i];
2078 OptionsContext o;
2079
2080 init_options(&o);
2081 o.g = g;
2082
2083 ret = parse_optgroup(&o, g);
2084 if (ret < 0) {
2085 av_log(NULL, AV_LOG_ERROR, "Error parsing options for %s file "
2086 "%s.\n", inout, g->arg);
2087 return ret;
2088 }
2089
2090 av_log(NULL, AV_LOG_DEBUG, "Opening an %s file: %s.\n", inout, g->arg);
2091 ret = open_file(&o, g->arg);
2092 uninit_options(&o);
2093 if (ret < 0) {
2094 av_log(NULL, AV_LOG_ERROR, "Error opening %s file %s.\n",
2095 inout, g->arg);
2096 return ret;
2097 }
Anton Khirnovdb2d65c2013-02-21 09:57:572098 av_log(NULL, AV_LOG_DEBUG, "Successfully opened the file.\n");
Anton Khirnov77bd1bc2012-06-08 19:35:162099 }
2100
2101 return 0;
2102}
2103
2104int avconv_parse_options(int argc, char **argv)
2105{
2106 OptionParseContext octx;
2107 uint8_t error[128];
2108 int ret;
2109
2110 memset(&octx, 0, sizeof(octx));
2111
2112 /* split the commandline into an internal representation */
Anton Khirnovc661cb62012-12-19 20:53:222113 ret = split_commandline(&octx, argc, argv, options, groups,
2114 FF_ARRAY_ELEMS(groups));
Anton Khirnov77bd1bc2012-06-08 19:35:162115 if (ret < 0) {
2116 av_log(NULL, AV_LOG_FATAL, "Error splitting the argument list: ");
2117 goto fail;
2118 }
2119
2120 /* apply global options */
2121 ret = parse_optgroup(NULL, &octx.global_opts);
2122 if (ret < 0) {
2123 av_log(NULL, AV_LOG_FATAL, "Error parsing global options: ");
2124 goto fail;
2125 }
2126
2127 /* open input files */
2128 ret = open_files(&octx.groups[GROUP_INFILE], "input", open_input_file);
2129 if (ret < 0) {
2130 av_log(NULL, AV_LOG_FATAL, "Error opening input files: ");
2131 goto fail;
2132 }
2133
2134 /* open output files */
2135 ret = open_files(&octx.groups[GROUP_OUTFILE], "output", open_output_file);
2136 if (ret < 0) {
2137 av_log(NULL, AV_LOG_FATAL, "Error opening output files: ");
2138 goto fail;
2139 }
2140
2141fail:
2142 uninit_parse_context(&octx);
2143 if (ret < 0) {
2144 av_strerror(ret, error, sizeof(error));
2145 av_log(NULL, AV_LOG_FATAL, "%s\n", error);
2146 }
2147 return ret;
2148}
Anton Khirnovf5e66822012-08-01 16:23:122149
2150#define OFFSET(x) offsetof(OptionsContext, x)
2151const OptionDef options[] = {
2152 /* main options */
2153#include "cmdutils_common_opts.h"
Anton Khirnov9d3009c2013-02-20 07:02:162154 { "f", HAS_ARG | OPT_STRING | OPT_OFFSET |
2155 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(format) },
Anton Khirnov8fc83fb2012-08-11 15:00:302156 "force format", "fmt" },
Anton Khirnov8fc83fb2012-08-11 15:00:302157 { "y", OPT_BOOL, { &file_overwrite },
2158 "overwrite output files" },
Vittorio Giovara7748dd42013-07-31 12:48:492159 { "n", OPT_BOOL, { &file_skip },
2160 "never overwrite output files" },
Anton Khirnov9d3009c2013-02-20 07:02:162161 { "c", HAS_ARG | OPT_STRING | OPT_SPEC |
2162 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
Anton Khirnov8fc83fb2012-08-11 15:00:302163 "codec name", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162164 { "codec", HAS_ARG | OPT_STRING | OPT_SPEC |
2165 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(codec_names) },
Anton Khirnov8fc83fb2012-08-11 15:00:302166 "codec name", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162167 { "pre", HAS_ARG | OPT_STRING | OPT_SPEC |
2168 OPT_OUTPUT, { .off = OFFSET(presets) },
Anton Khirnov8fc83fb2012-08-11 15:00:302169 "preset name", "preset" },
Anton Khirnov9d3009c2013-02-20 07:02:162170 { "map", HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2171 OPT_OUTPUT, { .func_arg = opt_map },
Anton Khirnov8fc83fb2012-08-11 15:00:302172 "set input stream mapping",
2173 "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
Anton Khirnov9d3009c2013-02-20 07:02:162174 { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC |
2175 OPT_OUTPUT, { .off = OFFSET(metadata_map) },
Anton Khirnov8fc83fb2012-08-11 15:00:302176 "set metadata information of outfile from infile",
2177 "outfile[,metadata]:infile[,metadata]" },
Anton Khirnov9d3009c2013-02-20 07:02:162178 { "map_chapters", HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET |
2179 OPT_OUTPUT, { .off = OFFSET(chapters_input_file) },
Anton Khirnov8fc83fb2012-08-11 15:00:302180 "set chapters mapping", "input_file_index" },
Anton Khirnov488a0fa2013-06-18 09:12:092181 { "t", HAS_ARG | OPT_TIME | OPT_OFFSET |
2182 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(recording_time) },
Anton Khirnov8fc83fb2012-08-11 15:00:302183 "record or transcode \"duration\" seconds of audio/video",
2184 "duration" },
Anton Khirnov9d3009c2013-02-20 07:02:162185 { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(limit_filesize) },
Anton Khirnov8fc83fb2012-08-11 15:00:302186 "set the limit file size in bytes", "limit_size" },
Anton Khirnov9d3009c2013-02-20 07:02:162187 { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET |
2188 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(start_time) },
Anton Khirnov8fc83fb2012-08-11 15:00:302189 "set the start time offset", "time_off" },
Anton Khirnov811bd072013-06-15 07:59:402190 { "accurate_seek", OPT_BOOL | OPT_OFFSET | OPT_EXPERT |
2191 OPT_INPUT, { .off = OFFSET(accurate_seek) },
2192 "enable/disable accurate seeking with -ss" },
Anton Khirnov9d3009c2013-02-20 07:02:162193 { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET |
2194 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(input_ts_offset) },
Anton Khirnov8fc83fb2012-08-11 15:00:302195 "set the input ts offset", "time_off" },
Anton Khirnov9d3009c2013-02-20 07:02:162196 { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC |
2197 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(ts_scale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302198 "set the input ts scale", "scale" },
Anton Khirnov9d3009c2013-02-20 07:02:162199 { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) },
Anton Khirnov8fc83fb2012-08-11 15:00:302200 "add metadata", "string=string" },
Anton Khirnov9d3009c2013-02-20 07:02:162201 { "dframes", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2202 OPT_OUTPUT, { .func_arg = opt_data_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302203 "set the number of data frames to record", "number" },
2204 { "benchmark", OPT_BOOL | OPT_EXPERT, { &do_benchmark },
2205 "add timings for benchmarking" },
Anton Khirnov602b1892012-08-15 08:33:362206 { "timelimit", HAS_ARG | OPT_EXPERT, { .func_arg = opt_timelimit },
Anton Khirnov8fc83fb2012-08-11 15:00:302207 "set max runtime in seconds", "limit" },
2208 { "dump", OPT_BOOL | OPT_EXPERT, { &do_pkt_dump },
2209 "dump each input packet" },
2210 { "hex", OPT_BOOL | OPT_EXPERT, { &do_hex_dump },
2211 "when dumping packets, also dump the payload" },
Anton Khirnov9d3009c2013-02-20 07:02:162212 { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2213 OPT_INPUT, { .off = OFFSET(rate_emu) },
Anton Khirnov8fc83fb2012-08-11 15:00:302214 "read input at native frame rate", "" },
Anton Khirnov9d3009c2013-02-20 07:02:162215 { "target", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_target },
Anton Khirnov8fc83fb2012-08-11 15:00:302216 "specify target file type (\"vcd\", \"svcd\", \"dvd\","
2217 " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
2218 { "vsync", HAS_ARG | OPT_EXPERT, { opt_vsync },
2219 "video sync method", "" },
2220 { "async", HAS_ARG | OPT_INT | OPT_EXPERT, { &audio_sync_method },
2221 "audio sync method", "" },
2222 { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &audio_drift_threshold },
2223 "audio drift threshold", "threshold" },
2224 { "copyts", OPT_BOOL | OPT_EXPERT, { &copy_ts },
2225 "copy timestamps" },
2226 { "copytb", OPT_BOOL | OPT_EXPERT, { &copy_tb },
2227 "copy input stream time base when stream copying" },
Anton Khirnov9d3009c2013-02-20 07:02:162228 { "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET |
2229 OPT_OUTPUT, { .off = OFFSET(shortest) },
Anton Khirnov8fc83fb2012-08-11 15:00:302230 "finish encoding within shortest input" },
2231 { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &dts_delta_threshold },
2232 "timestamp discontinuity delta threshold", "threshold" },
Anton Khirnov602b1892012-08-15 08:33:362233 { "xerror", OPT_BOOL | OPT_EXPERT, { &exit_on_error },
Anton Khirnov8fc83fb2012-08-11 15:00:302234 "exit on error", "error" },
Anton Khirnov9d3009c2013-02-20 07:02:162235 { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2236 OPT_OUTPUT, { .off = OFFSET(copy_initial_nonkeyframes) },
Anton Khirnov8fc83fb2012-08-11 15:00:302237 "copy initial non-keyframes" },
Anton Khirnov9d3009c2013-02-20 07:02:162238 { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
Anton Khirnov8fc83fb2012-08-11 15:00:302239 "set the number of frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162240 { "tag", OPT_STRING | HAS_ARG | OPT_SPEC |
2241 OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(codec_tags) },
Anton Khirnov8fc83fb2012-08-11 15:00:302242 "force codec tag/fourcc", "fourcc/tag" },
Anton Khirnov9d3009c2013-02-20 07:02:162243 { "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2244 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302245 "use fixed quality scale (VBR)", "q" },
Anton Khirnov9d3009c2013-02-20 07:02:162246 { "qscale", HAS_ARG | OPT_EXPERT | OPT_DOUBLE |
2247 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(qscale) },
Anton Khirnov8fc83fb2012-08-11 15:00:302248 "use fixed quality scale (VBR)", "q" },
Anton Khirnov9d3009c2013-02-20 07:02:162249 { "filter", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filters) },
Anton Khirnov8fc83fb2012-08-11 15:00:302250 "set stream filterchain", "filter_list" },
Anton Khirnova4208b92013-03-13 13:24:452251 { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) },
2252 "read stream filtergraph description from a file", "filename" },
Anton Khirnov8fc83fb2012-08-11 15:00:302253 { "filter_complex", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex },
2254 "create a complex filtergraph", "graph_description" },
Anton Khirnova4208b92013-03-13 13:24:452255 { "filter_complex_script", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex_script },
2256 "read complex filtergraph description from a file", "filename" },
Anton Khirnov8fc83fb2012-08-11 15:00:302257 { "stats", OPT_BOOL, { &print_stats },
2258 "print progress report during encoding", },
Anton Khirnov9d3009c2013-02-20 07:02:162259 { "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT |
2260 OPT_OUTPUT, { .func_arg = opt_attach },
Anton Khirnov8fc83fb2012-08-11 15:00:302261 "add an attachment to the output file", "filename" },
Anton Khirnov9d3009c2013-02-20 07:02:162262 { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |
2263 OPT_EXPERT | OPT_INPUT, { .off = OFFSET(dump_attachment) },
Anton Khirnov8fc83fb2012-08-11 15:00:302264 "extract an attachment into a file", "filename" },
Anton Khirnovf5e66822012-08-01 16:23:122265
2266 /* video options */
Anton Khirnov9d3009c2013-02-20 07:02:162267 { "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302268 "set the number of video frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162269 { "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2270 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_rates) },
Anton Khirnov8fc83fb2012-08-11 15:00:302271 "set frame rate (Hz value, fraction or abbreviation)", "rate" },
Anton Khirnov9d3009c2013-02-20 07:02:162272 { "s", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2273 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_sizes) },
Anton Khirnov8fc83fb2012-08-11 15:00:302274 "set frame size (WxH or abbreviation)", "size" },
Anton Khirnov9d3009c2013-02-20 07:02:162275 { "aspect", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
2276 OPT_OUTPUT, { .off = OFFSET(frame_aspect_ratios) },
Anton Khirnov8fc83fb2012-08-11 15:00:302277 "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
Anton Khirnov9d3009c2013-02-20 07:02:162278 { "pix_fmt", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2279 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(frame_pix_fmts) },
Anton Khirnov8fc83fb2012-08-11 15:00:302280 "set pixel format", "format" },
Anton Khirnov9d3009c2013-02-20 07:02:162281 { "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(video_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302282 "disable video" },
2283 { "vdt", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &video_discard },
2284 "discard threshold", "n" },
Anton Khirnov9d3009c2013-02-20 07:02:162285 { "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2286 OPT_OUTPUT, { .off = OFFSET(rc_overrides) },
Anton Khirnov8fc83fb2012-08-11 15:00:302287 "rate control override for specific intervals", "override" },
Anton Khirnov9d3009c2013-02-20 07:02:162288 { "vcodec", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_INPUT |
2289 OPT_OUTPUT, { .func_arg = opt_video_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302290 "force video codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162291 { "pass", OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT | OPT_OUTPUT, { .off = OFFSET(pass) },
Anton Khirnov8fc83fb2012-08-11 15:00:302292 "select the pass number (1 or 2)", "n" },
Anton Khirnov9d3009c2013-02-20 07:02:162293 { "passlogfile", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC |
2294 OPT_OUTPUT, { .off = OFFSET(passlogfiles) },
Anton Khirnov8fc83fb2012-08-11 15:00:302295 "select two pass log file name prefix", "prefix" },
Anton Khirnov8fc83fb2012-08-11 15:00:302296 { "vstats", OPT_VIDEO | OPT_EXPERT , { &opt_vstats },
2297 "dump video coding statistics to file" },
2298 { "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { opt_vstats_file },
2299 "dump video coding statistics to file", "file" },
Anton Khirnov9d3009c2013-02-20 07:02:162300 { "vf", OPT_VIDEO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_video_filters },
Anton Khirnov8fc83fb2012-08-11 15:00:302301 "video filters", "filter list" },
Anton Khirnov9d3009c2013-02-20 07:02:162302 { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2303 OPT_OUTPUT, { .off = OFFSET(intra_matrices) },
Anton Khirnov8fc83fb2012-08-11 15:00:302304 "specify intra matrix coeffs", "matrix" },
Anton Khirnov9d3009c2013-02-20 07:02:162305 { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC |
2306 OPT_OUTPUT, { .off = OFFSET(inter_matrices) },
Anton Khirnov8fc83fb2012-08-11 15:00:302307 "specify inter matrix coeffs", "matrix" },
Anton Khirnov9d3009c2013-02-20 07:02:162308 { "top", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_INT| OPT_SPEC |
2309 OPT_OUTPUT, { .off = OFFSET(top_field_first) },
Anton Khirnov8fc83fb2012-08-11 15:00:302310 "top=1/bottom=0/auto=-1 field first", "" },
2311 { "dc", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &intra_dc_precision },
2312 "intra_dc_precision", "precision" },
Anton Khirnov9d3009c2013-02-20 07:02:162313 { "vtag", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2314 OPT_OUTPUT, { .func_arg = opt_video_tag },
Anton Khirnov8fc83fb2012-08-11 15:00:302315 "force video tag/fourcc", "fourcc/tag" },
2316 { "qphist", OPT_VIDEO | OPT_BOOL | OPT_EXPERT , { &qp_hist },
2317 "show QP histogram" },
Anton Khirnov9d3009c2013-02-20 07:02:162318 { "force_fps", OPT_VIDEO | OPT_BOOL | OPT_EXPERT | OPT_SPEC |
2319 OPT_OUTPUT, { .off = OFFSET(force_fps) },
Anton Khirnov8fc83fb2012-08-11 15:00:302320 "force the selected framerate, disable the best supported framerate selection" },
Anton Khirnov9d3009c2013-02-20 07:02:162321 { "streamid", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2322 OPT_OUTPUT, { .func_arg = opt_streamid },
Anton Khirnov8fc83fb2012-08-11 15:00:302323 "set the value of an outfile streamid", "streamIndex:value" },
Anton Khirnov9d3009c2013-02-20 07:02:162324 { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2325 OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(forced_key_frames) },
2326 "force key frames at specified timestamps", "timestamps" },
Anton Khirnov07fd0a22013-11-02 21:06:362327 { "hwaccel", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2328 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccels) },
2329 "use HW accelerated decoding", "hwaccel name" },
2330 { "hwaccel_device", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT |
2331 OPT_SPEC | OPT_INPUT, { .off = OFFSET(hwaccel_devices) },
2332 "select a device for HW acceleration" "devicename" },
Anton Khirnovf5e66822012-08-01 16:23:122333
2334 /* audio options */
Anton Khirnov9d3009c2013-02-20 07:02:162335 { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_frames },
Anton Khirnov8fc83fb2012-08-11 15:00:302336 "set the number of audio frames to record", "number" },
Anton Khirnov9d3009c2013-02-20 07:02:162337 { "aq", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_qscale },
Anton Khirnov8fc83fb2012-08-11 15:00:302338 "set audio quality (codec-specific)", "quality", },
Anton Khirnov9d3009c2013-02-20 07:02:162339 { "ar", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2340 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_sample_rate) },
Anton Khirnov8fc83fb2012-08-11 15:00:302341 "set audio sampling rate (in Hz)", "rate" },
Anton Khirnov9d3009c2013-02-20 07:02:162342 { "ac", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC |
2343 OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(audio_channels) },
Anton Khirnov8fc83fb2012-08-11 15:00:302344 "set number of audio channels", "channels" },
Anton Khirnov9d3009c2013-02-20 07:02:162345 { "an", OPT_AUDIO | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(audio_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302346 "disable audio" },
Anton Khirnov9d3009c2013-02-20 07:02:162347 { "acodec", OPT_AUDIO | HAS_ARG | OPT_PERFILE |
2348 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_audio_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302349 "force audio codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162350 { "atag", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2351 OPT_OUTPUT, { .func_arg = opt_audio_tag },
Anton Khirnov8fc83fb2012-08-11 15:00:302352 "force audio tag/fourcc", "fourcc/tag" },
2353 { "vol", OPT_AUDIO | HAS_ARG | OPT_INT, { &audio_volume },
2354 "change audio volume (256=normal)" , "volume" },
Anton Khirnov9d3009c2013-02-20 07:02:162355 { "sample_fmt", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_SPEC |
2356 OPT_STRING | OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(sample_fmts) },
Anton Khirnov8fc83fb2012-08-11 15:00:302357 "set sample format", "format" },
Anton Khirnov9d3009c2013-02-20 07:02:162358 { "channel_layout", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE |
2359 OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_channel_layout },
Anton Khirnov8fc83fb2012-08-11 15:00:302360 "set channel layout", "layout" },
Anton Khirnov9d3009c2013-02-20 07:02:162361 { "af", OPT_AUDIO | HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_audio_filters },
Anton Khirnov8fc83fb2012-08-11 15:00:302362 "audio filters", "filter list" },
Anton Khirnovf5e66822012-08-01 16:23:122363
2364 /* subtitle options */
Anton Khirnov9d3009c2013-02-20 07:02:162365 { "sn", OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(subtitle_disable) },
Anton Khirnov8fc83fb2012-08-11 15:00:302366 "disable subtitle" },
Anton Khirnov9d3009c2013-02-20 07:02:162367 { "scodec", OPT_SUBTITLE | HAS_ARG | OPT_PERFILE | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_subtitle_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302368 "force subtitle codec ('copy' to copy stream)", "codec" },
Anton Khirnov9d3009c2013-02-20 07:02:162369 { "stag", OPT_SUBTITLE | HAS_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_subtitle_tag }
Anton Khirnov8fc83fb2012-08-11 15:00:302370 , "force subtitle tag/fourcc", "fourcc/tag" },
Anton Khirnovf5e66822012-08-01 16:23:122371
2372 /* grab options */
Anton Khirnov79600a82012-08-11 17:19:532373 { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
Anton Khirnovf5e66822012-08-01 16:23:122374
2375 /* muxer options */
Anton Khirnov9d3009c2013-02-20 07:02:162376 { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_max_delay) },
Anton Khirnov8fc83fb2012-08-11 15:00:302377 "set the maximum demux-decode delay", "seconds" },
Anton Khirnov9d3009c2013-02-20 07:02:162378 { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT, { .off = OFFSET(mux_preload) },
Anton Khirnov8fc83fb2012-08-11 15:00:302379 "set the initial demux-decode delay", "seconds" },
Anton Khirnovf5e66822012-08-01 16:23:122380
Anton Khirnov9d3009c2013-02-20 07:02:162381 { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT | OPT_OUTPUT, { .off = OFFSET(bitstream_filters) },
Anton Khirnov8fc83fb2012-08-11 15:00:302382 "A comma-separated list of bitstream filters", "bitstream_filters" },
Anton Khirnovf5e66822012-08-01 16:23:122383
2384 /* data codec support */
Anton Khirnov9d3009c2013-02-20 07:02:162385 { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT | OPT_INPUT | OPT_OUTPUT, { .func_arg = opt_data_codec },
Anton Khirnov8fc83fb2012-08-11 15:00:302386 "force data codec ('copy' to copy stream)", "codec" },
Anton Khirnovf5e66822012-08-01 16:23:122387
Anton Khirnovf5e66822012-08-01 16:23:122388 { NULL, },
2389};