00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdint.h>
00022
00023 #include "ffmpeg.h"
00024 #include "cmdutils.h"
00025
00026 #include "libavformat/avformat.h"
00027
00028 #include "libavcodec/avcodec.h"
00029
00030 #include "libavfilter/avfilter.h"
00031 #include "libavfilter/avfiltergraph.h"
00032
00033 #include "libavutil/avassert.h"
00034 #include "libavutil/avstring.h"
00035 #include "libavutil/avutil.h"
00036 #include "libavutil/channel_layout.h"
00037 #include "libavutil/intreadwrite.h"
00038 #include "libavutil/fifo.h"
00039 #include "libavutil/mathematics.h"
00040 #include "libavutil/opt.h"
00041 #include "libavutil/parseutils.h"
00042 #include "libavutil/pixdesc.h"
00043 #include "libavutil/pixfmt.h"
00044
00045 #define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
00046 {\
00047 int i, ret;\
00048 for (i = 0; i < o->nb_ ## name; i++) {\
00049 char *spec = o->name[i].specifier;\
00050 if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
00051 outvar = o->name[i].u.type;\
00052 else if (ret < 0)\
00053 exit(1);\
00054 }\
00055 }
00056
00057 #define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\
00058 {\
00059 int i;\
00060 for (i = 0; i < o->nb_ ## name; i++) {\
00061 char *spec = o->name[i].specifier;\
00062 if (!strcmp(spec, mediatype))\
00063 outvar = o->name[i].u.type;\
00064 }\
00065 }
00066 char *vstats_filename;
00067
00068 float audio_drift_threshold = 0.1;
00069 float dts_delta_threshold = 10;
00070 float dts_error_threshold = 3600*30;
00071
00072 int audio_volume = 256;
00073 int audio_sync_method = 0;
00074 int video_sync_method = VSYNC_AUTO;
00075 int do_deinterlace = 0;
00076 int do_benchmark = 0;
00077 int do_benchmark_all = 0;
00078 int do_hex_dump = 0;
00079 int do_pkt_dump = 0;
00080 int copy_ts = 0;
00081 int copy_tb = -1;
00082 int debug_ts = 0;
00083 int exit_on_error = 0;
00084 int print_stats = 1;
00085 int qp_hist = 0;
00086 int stdin_interaction = 1;
00087 int frame_bits_per_raw_sample = 0;
00088
00089
00090 static int intra_only = 0;
00091 static int file_overwrite = 0;
00092 static int no_file_overwrite = 0;
00093 static int video_discard = 0;
00094 static int intra_dc_precision = 8;
00095 static int do_psnr = 0;
00096 static int input_sync;
00097
00098 void reset_options(OptionsContext *o, int is_input)
00099 {
00100 const OptionDef *po = options;
00101 OptionsContext bak= *o;
00102 int i;
00103
00104
00105 while (po->name) {
00106 void *dst = (uint8_t*)o + po->u.off;
00107
00108 if (po->flags & OPT_SPEC) {
00109 SpecifierOpt **so = dst;
00110 int i, *count = (int*)(so + 1);
00111 for (i = 0; i < *count; i++) {
00112 av_freep(&(*so)[i].specifier);
00113 if (po->flags & OPT_STRING)
00114 av_freep(&(*so)[i].u.str);
00115 }
00116 av_freep(so);
00117 *count = 0;
00118 } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
00119 av_freep(dst);
00120 po++;
00121 }
00122
00123 for (i = 0; i < o->nb_stream_maps; i++)
00124 av_freep(&o->stream_maps[i].linklabel);
00125 av_freep(&o->stream_maps);
00126 av_freep(&o->audio_channel_maps);
00127 av_freep(&o->streamid_map);
00128
00129 memset(o, 0, sizeof(*o));
00130
00131 if (is_input) {
00132 o->recording_time = bak.recording_time;
00133 if (o->recording_time != INT64_MAX)
00134 av_log(NULL, AV_LOG_WARNING,
00135 "-t is not an input option, keeping it for the next output;"
00136 " consider fixing your command line.\n");
00137 } else
00138 o->recording_time = INT64_MAX;
00139 o->mux_max_delay = 0.7;
00140 o->limit_filesize = UINT64_MAX;
00141 o->chapters_input_file = INT_MAX;
00142
00143 uninit_opts();
00144 init_opts();
00145 }
00146
00147
00148 static int opt_frame_crop(void *optctx, const char *opt, const char *arg)
00149 {
00150 av_log(NULL, AV_LOG_FATAL, "Option '%s' has been removed, use the crop filter instead\n", opt);
00151 return AVERROR(EINVAL);
00152 }
00153
00154 static int opt_pad(void *optctx, const char *opt, const char *arg)
00155 {
00156 av_log(NULL, AV_LOG_FATAL, "Option '%s' has been removed, use the pad filter instead\n", opt);
00157 return -1;
00158 }
00159
00160 static int opt_sameq(void *optctx, const char *opt, const char *arg)
00161 {
00162 av_log(NULL, AV_LOG_ERROR, "Option '%s' was removed. "
00163 "If you are looking for an option to preserve the quality (which is not "
00164 "what -%s was for), use -qscale 0 or an equivalent quality factor option.\n",
00165 opt, opt);
00166 return AVERROR(EINVAL);
00167 }
00168
00169 static int opt_video_channel(void *optctx, const char *opt, const char *arg)
00170 {
00171 av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -channel.\n");
00172 return opt_default(optctx, "channel", arg);
00173 }
00174
00175 static int opt_video_standard(void *optctx, const char *opt, const char *arg)
00176 {
00177 av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -standard.\n");
00178 return opt_default(optctx, "standard", arg);
00179 }
00180
00181 static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
00182 {
00183 OptionsContext *o = optctx;
00184 return parse_option(o, "codec:a", arg, options);
00185 }
00186
00187 static int opt_video_codec(void *optctx, const char *opt, const char *arg)
00188 {
00189 OptionsContext *o = optctx;
00190 return parse_option(o, "codec:v", arg, options);
00191 }
00192
00193 static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
00194 {
00195 OptionsContext *o = optctx;
00196 return parse_option(o, "codec:s", arg, options);
00197 }
00198
00199 static int opt_data_codec(void *optctx, const char *opt, const char *arg)
00200 {
00201 OptionsContext *o = optctx;
00202 return parse_option(o, "codec:d", arg, options);
00203 }
00204
00205 static int opt_map(void *optctx, const char *opt, const char *arg)
00206 {
00207 OptionsContext *o = optctx;
00208 StreamMap *m = NULL;
00209 int i, negative = 0, file_idx;
00210 int sync_file_idx = -1, sync_stream_idx = 0;
00211 char *p, *sync;
00212 char *map;
00213
00214 if (*arg == '-') {
00215 negative = 1;
00216 arg++;
00217 }
00218 map = av_strdup(arg);
00219
00220
00221 if (sync = strchr(map, ',')) {
00222 *sync = 0;
00223 sync_file_idx = strtol(sync + 1, &sync, 0);
00224 if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
00225 av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
00226 exit(1);
00227 }
00228 if (*sync)
00229 sync++;
00230 for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
00231 if (check_stream_specifier(input_files[sync_file_idx]->ctx,
00232 input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
00233 sync_stream_idx = i;
00234 break;
00235 }
00236 if (i == input_files[sync_file_idx]->nb_streams) {
00237 av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
00238 "match any streams.\n", arg);
00239 exit(1);
00240 }
00241 }
00242
00243
00244 if (map[0] == '[') {
00245
00246 const char *c = map + 1;
00247 o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps),
00248 &o->nb_stream_maps, o->nb_stream_maps + 1);
00249 m = &o->stream_maps[o->nb_stream_maps - 1];
00250 m->linklabel = av_get_token(&c, "]");
00251 if (!m->linklabel) {
00252 av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
00253 exit(1);
00254 }
00255 } else {
00256 file_idx = strtol(map, &p, 0);
00257 if (file_idx >= nb_input_files || file_idx < 0) {
00258 av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
00259 exit(1);
00260 }
00261 if (negative)
00262
00263 for (i = 0; i < o->nb_stream_maps; i++) {
00264 m = &o->stream_maps[i];
00265 if (file_idx == m->file_index &&
00266 check_stream_specifier(input_files[m->file_index]->ctx,
00267 input_files[m->file_index]->ctx->streams[m->stream_index],
00268 *p == ':' ? p + 1 : p) > 0)
00269 m->disabled = 1;
00270 }
00271 else
00272 for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
00273 if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
00274 *p == ':' ? p + 1 : p) <= 0)
00275 continue;
00276 o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps),
00277 &o->nb_stream_maps, o->nb_stream_maps + 1);
00278 m = &o->stream_maps[o->nb_stream_maps - 1];
00279
00280 m->file_index = file_idx;
00281 m->stream_index = i;
00282
00283 if (sync_file_idx >= 0) {
00284 m->sync_file_index = sync_file_idx;
00285 m->sync_stream_index = sync_stream_idx;
00286 } else {
00287 m->sync_file_index = file_idx;
00288 m->sync_stream_index = i;
00289 }
00290 }
00291 }
00292
00293 if (!m) {
00294 av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
00295 exit(1);
00296 }
00297
00298 av_freep(&map);
00299 return 0;
00300 }
00301
00302 static int opt_attach(void *optctx, const char *opt, const char *arg)
00303 {
00304 OptionsContext *o = optctx;
00305 o->attachments = grow_array(o->attachments, sizeof(*o->attachments),
00306 &o->nb_attachments, o->nb_attachments + 1);
00307 o->attachments[o->nb_attachments - 1] = arg;
00308 return 0;
00309 }
00310
00311 static int opt_map_channel(void *optctx, const char *opt, const char *arg)
00312 {
00313 OptionsContext *o = optctx;
00314 int n;
00315 AVStream *st;
00316 AudioChannelMap *m;
00317
00318 o->audio_channel_maps =
00319 grow_array(o->audio_channel_maps, sizeof(*o->audio_channel_maps),
00320 &o->nb_audio_channel_maps, o->nb_audio_channel_maps + 1);
00321 m = &o->audio_channel_maps[o->nb_audio_channel_maps - 1];
00322
00323
00324 n = sscanf(arg, "%d:%d.%d", &m->channel_idx, &m->ofile_idx, &m->ostream_idx);
00325 if ((n == 1 || n == 3) && m->channel_idx == -1) {
00326 m->file_idx = m->stream_idx = -1;
00327 if (n == 1)
00328 m->ofile_idx = m->ostream_idx = -1;
00329 return 0;
00330 }
00331
00332
00333 n = sscanf(arg, "%d.%d.%d:%d.%d",
00334 &m->file_idx, &m->stream_idx, &m->channel_idx,
00335 &m->ofile_idx, &m->ostream_idx);
00336
00337 if (n != 3 && n != 5) {
00338 av_log(NULL, AV_LOG_FATAL, "Syntax error, mapchan usage: "
00339 "[file.stream.channel|-1][:syncfile:syncstream]\n");
00340 exit(1);
00341 }
00342
00343 if (n != 5)
00344 m->ofile_idx = m->ostream_idx = -1;
00345
00346
00347 if (m->file_idx < 0 || m->file_idx >= nb_input_files) {
00348 av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file index: %d\n",
00349 m->file_idx);
00350 exit(1);
00351 }
00352 if (m->stream_idx < 0 ||
00353 m->stream_idx >= input_files[m->file_idx]->nb_streams) {
00354 av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file stream index #%d.%d\n",
00355 m->file_idx, m->stream_idx);
00356 exit(1);
00357 }
00358 st = input_files[m->file_idx]->ctx->streams[m->stream_idx];
00359 if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
00360 av_log(NULL, AV_LOG_FATAL, "mapchan: stream #%d.%d is not an audio stream.\n",
00361 m->file_idx, m->stream_idx);
00362 exit(1);
00363 }
00364 if (m->channel_idx < 0 || m->channel_idx >= st->codec->channels) {
00365 av_log(NULL, AV_LOG_FATAL, "mapchan: invalid audio channel #%d.%d.%d\n",
00366 m->file_idx, m->stream_idx, m->channel_idx);
00367 exit(1);
00368 }
00369 return 0;
00370 }
00371
00379 static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
00380 {
00381 if (*arg) {
00382 *type = *arg;
00383 switch (*arg) {
00384 case 'g':
00385 break;
00386 case 's':
00387 if (*(++arg) && *arg != ':') {
00388 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
00389 exit(1);
00390 }
00391 *stream_spec = *arg == ':' ? arg + 1 : "";
00392 break;
00393 case 'c':
00394 case 'p':
00395 if (*(++arg) == ':')
00396 *index = strtol(++arg, NULL, 0);
00397 break;
00398 default:
00399 av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
00400 exit(1);
00401 }
00402 } else
00403 *type = 'g';
00404 }
00405
00406 static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
00407 {
00408 AVDictionary **meta_in = NULL;
00409 AVDictionary **meta_out = NULL;
00410 int i, ret = 0;
00411 char type_in, type_out;
00412 const char *istream_spec = NULL, *ostream_spec = NULL;
00413 int idx_in = 0, idx_out = 0;
00414
00415 parse_meta_type(inspec, &type_in, &idx_in, &istream_spec);
00416 parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
00417
00418 if (!ic) {
00419 if (type_out == 'g' || !*outspec)
00420 o->metadata_global_manual = 1;
00421 if (type_out == 's' || !*outspec)
00422 o->metadata_streams_manual = 1;
00423 if (type_out == 'c' || !*outspec)
00424 o->metadata_chapters_manual = 1;
00425 return 0;
00426 }
00427
00428 if (type_in == 'g' || type_out == 'g')
00429 o->metadata_global_manual = 1;
00430 if (type_in == 's' || type_out == 's')
00431 o->metadata_streams_manual = 1;
00432 if (type_in == 'c' || type_out == 'c')
00433 o->metadata_chapters_manual = 1;
00434
00435
00436 if (!ic)
00437 return 0;
00438
00439 #define METADATA_CHECK_INDEX(index, nb_elems, desc)\
00440 if ((index) < 0 || (index) >= (nb_elems)) {\
00441 av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
00442 (desc), (index));\
00443 exit(1);\
00444 }
00445
00446 #define SET_DICT(type, meta, context, index)\
00447 switch (type) {\
00448 case 'g':\
00449 meta = &context->metadata;\
00450 break;\
00451 case 'c':\
00452 METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
00453 meta = &context->chapters[index]->metadata;\
00454 break;\
00455 case 'p':\
00456 METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
00457 meta = &context->programs[index]->metadata;\
00458 break;\
00459 case 's':\
00460 break; \
00461 default: av_assert0(0);\
00462 }\
00463
00464 SET_DICT(type_in, meta_in, ic, idx_in);
00465 SET_DICT(type_out, meta_out, oc, idx_out);
00466
00467
00468 if (type_in == 's') {
00469 for (i = 0; i < ic->nb_streams; i++) {
00470 if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
00471 meta_in = &ic->streams[i]->metadata;
00472 break;
00473 } else if (ret < 0)
00474 exit(1);
00475 }
00476 if (!meta_in) {
00477 av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match any streams.\n", istream_spec);
00478 exit(1);
00479 }
00480 }
00481
00482 if (type_out == 's') {
00483 for (i = 0; i < oc->nb_streams; i++) {
00484 if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
00485 meta_out = &oc->streams[i]->metadata;
00486 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
00487 } else if (ret < 0)
00488 exit(1);
00489 }
00490 } else
00491 av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
00492
00493 return 0;
00494 }
00495
00496 static int opt_recording_timestamp(void *optctx, const char *opt, const char *arg)
00497 {
00498 OptionsContext *o = optctx;
00499 char buf[128];
00500 int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6;
00501 struct tm time = *gmtime((time_t*)&recording_timestamp);
00502 strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time);
00503 parse_option(o, "metadata", buf, options);
00504
00505 av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata "
00506 "tag instead.\n", opt);
00507 return 0;
00508 }
00509
00510 static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
00511 {
00512 const AVCodecDescriptor *desc;
00513 const char *codec_string = encoder ? "encoder" : "decoder";
00514 AVCodec *codec;
00515
00516 codec = encoder ?
00517 avcodec_find_encoder_by_name(name) :
00518 avcodec_find_decoder_by_name(name);
00519
00520 if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
00521 codec = encoder ? avcodec_find_encoder(desc->id) :
00522 avcodec_find_decoder(desc->id);
00523 if (codec)
00524 av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
00525 codec_string, codec->name, desc->name);
00526 }
00527
00528 if (!codec) {
00529 av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
00530 exit(1);
00531 }
00532 if (codec->type != type) {
00533 av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
00534 exit(1);
00535 }
00536 return codec;
00537 }
00538
00539 static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
00540 {
00541 char *codec_name = NULL;
00542
00543 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
00544 if (codec_name) {
00545 AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
00546 st->codec->codec_id = codec->id;
00547 return codec;
00548 } else
00549 return avcodec_find_decoder(st->codec->codec_id);
00550 }
00551
00552
00553
00554 static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
00555 {
00556 int i;
00557 char *next, *codec_tag = NULL;
00558
00559 for (i = 0; i < ic->nb_streams; i++) {
00560 AVStream *st = ic->streams[i];
00561 AVCodecContext *dec = st->codec;
00562 InputStream *ist = av_mallocz(sizeof(*ist));
00563 char *framerate = NULL;
00564
00565 if (!ist)
00566 exit(1);
00567
00568 input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1);
00569 input_streams[nb_input_streams - 1] = ist;
00570
00571 ist->st = st;
00572 ist->file_index = nb_input_files;
00573 ist->discard = 1;
00574 st->discard = AVDISCARD_ALL;
00575 ist->opts = filter_codec_opts(codec_opts, ist->st->codec->codec_id, ic, st, choose_decoder(o, ic, st));
00576
00577 ist->ts_scale = 1.0;
00578 MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
00579
00580 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
00581 if (codec_tag) {
00582 uint32_t tag = strtol(codec_tag, &next, 0);
00583 if (*next)
00584 tag = AV_RL32(codec_tag);
00585 st->codec->codec_tag = tag;
00586 }
00587
00588 ist->dec = choose_decoder(o, ic, st);
00589
00590 ist->reinit_filters = -1;
00591 MATCH_PER_STREAM_OPT(reinit_filters, i, ist->reinit_filters, ic, st);
00592
00593 ist->filter_in_rescale_delta_last = AV_NOPTS_VALUE;
00594
00595 switch (dec->codec_type) {
00596 case AVMEDIA_TYPE_VIDEO:
00597 if(!ist->dec)
00598 ist->dec = avcodec_find_decoder(dec->codec_id);
00599 if (dec->lowres) {
00600 dec->flags |= CODEC_FLAG_EMU_EDGE;
00601 }
00602
00603 ist->resample_height = dec->height;
00604 ist->resample_width = dec->width;
00605 ist->resample_pix_fmt = dec->pix_fmt;
00606
00607 MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
00608 if (framerate && av_parse_video_rate(&ist->framerate,
00609 framerate) < 0) {
00610 av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
00611 framerate);
00612 exit(1);
00613 }
00614
00615 ist->top_field_first = -1;
00616 MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
00617
00618 break;
00619 case AVMEDIA_TYPE_AUDIO:
00620 guess_input_channel_layout(ist);
00621
00622 ist->resample_sample_fmt = dec->sample_fmt;
00623 ist->resample_sample_rate = dec->sample_rate;
00624 ist->resample_channels = dec->channels;
00625 ist->resample_channel_layout = dec->channel_layout;
00626
00627 break;
00628 case AVMEDIA_TYPE_DATA:
00629 case AVMEDIA_TYPE_SUBTITLE:
00630 if(!ist->dec)
00631 ist->dec = avcodec_find_decoder(dec->codec_id);
00632 MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
00633 break;
00634 case AVMEDIA_TYPE_ATTACHMENT:
00635 case AVMEDIA_TYPE_UNKNOWN:
00636 break;
00637 default:
00638 abort();
00639 }
00640 }
00641 }
00642
00643 static void assert_file_overwrite(const char *filename)
00644 {
00645 if ((!file_overwrite || no_file_overwrite) &&
00646 (strchr(filename, ':') == NULL || filename[1] == ':' ||
00647 av_strstart(filename, "file:", NULL))) {
00648 if (avio_check(filename, 0) == 0) {
00649 if (stdin_interaction && (!no_file_overwrite || file_overwrite)) {
00650 fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
00651 fflush(stderr);
00652 term_exit();
00653 signal(SIGINT, SIG_DFL);
00654 if (!read_yesno()) {
00655 av_log(NULL, AV_LOG_FATAL, "Not overwriting - exiting\n");
00656 exit(1);
00657 }
00658 term_init();
00659 }
00660 else {
00661 av_log(NULL, AV_LOG_FATAL, "File '%s' already exists. Exiting.\n", filename);
00662 exit(1);
00663 }
00664 }
00665 }
00666 }
00667
00668 static void dump_attachment(AVStream *st, const char *filename)
00669 {
00670 int ret;
00671 AVIOContext *out = NULL;
00672 AVDictionaryEntry *e;
00673
00674 if (!st->codec->extradata_size) {
00675 av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
00676 nb_input_files - 1, st->index);
00677 return;
00678 }
00679 if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
00680 filename = e->value;
00681 if (!*filename) {
00682 av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
00683 "in stream #%d:%d.\n", nb_input_files - 1, st->index);
00684 exit(1);
00685 }
00686
00687 assert_file_overwrite(filename);
00688
00689 if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
00690 av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
00691 filename);
00692 exit(1);
00693 }
00694
00695 avio_write(out, st->codec->extradata, st->codec->extradata_size);
00696 avio_flush(out);
00697 avio_close(out);
00698 }
00699
00700 static int opt_input_file(void *optctx, const char *opt, const char *filename)
00701 {
00702 OptionsContext *o = optctx;
00703 AVFormatContext *ic;
00704 AVInputFormat *file_iformat = NULL;
00705 int err, i, ret;
00706 int64_t timestamp;
00707 uint8_t buf[128];
00708 AVDictionary **opts;
00709 int orig_nb_streams;
00710 char * video_codec_name = NULL;
00711 char * audio_codec_name = NULL;
00712 char *subtitle_codec_name = NULL;
00713
00714 if (o->format) {
00715 if (!(file_iformat = av_find_input_format(o->format))) {
00716 av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
00717 exit(1);
00718 }
00719 }
00720
00721 if (!strcmp(filename, "-"))
00722 filename = "pipe:";
00723
00724 stdin_interaction &= strncmp(filename, "pipe:", 5) &&
00725 strcmp(filename, "/dev/stdin");
00726
00727
00728 ic = avformat_alloc_context();
00729 if (!ic) {
00730 print_error(filename, AVERROR(ENOMEM));
00731 exit(1);
00732 }
00733 if (o->nb_audio_sample_rate) {
00734 snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
00735 av_dict_set(&format_opts, "sample_rate", buf, 0);
00736 }
00737 if (o->nb_audio_channels) {
00738
00739
00740
00741 if (file_iformat && file_iformat->priv_class &&
00742 av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
00743 AV_OPT_SEARCH_FAKE_OBJ)) {
00744 snprintf(buf, sizeof(buf), "%d",
00745 o->audio_channels[o->nb_audio_channels - 1].u.i);
00746 av_dict_set(&format_opts, "channels", buf, 0);
00747 }
00748 }
00749 if (o->nb_frame_rates) {
00750
00751
00752 if (file_iformat && file_iformat->priv_class &&
00753 av_opt_find(&file_iformat->priv_class, "framerate", NULL, 0,
00754 AV_OPT_SEARCH_FAKE_OBJ)) {
00755 av_dict_set(&format_opts, "framerate",
00756 o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
00757 }
00758 }
00759 if (o->nb_frame_sizes) {
00760 av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
00761 }
00762 if (o->nb_frame_pix_fmts)
00763 av_dict_set(&format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
00764
00765 MATCH_PER_TYPE_OPT(codec_names, str, video_codec_name, ic, "v");
00766 MATCH_PER_TYPE_OPT(codec_names, str, audio_codec_name, ic, "a");
00767 MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, ic, "s");
00768
00769 ic->video_codec_id = video_codec_name ?
00770 find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0)->id : AV_CODEC_ID_NONE;
00771 ic->audio_codec_id = audio_codec_name ?
00772 find_codec_or_die(audio_codec_name , AVMEDIA_TYPE_AUDIO , 0)->id : AV_CODEC_ID_NONE;
00773 ic->subtitle_codec_id= subtitle_codec_name ?
00774 find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0)->id : AV_CODEC_ID_NONE;
00775 ic->flags |= AVFMT_FLAG_NONBLOCK;
00776 ic->interrupt_callback = int_cb;
00777
00778
00779 err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
00780 if (err < 0) {
00781 print_error(filename, err);
00782 exit(1);
00783 }
00784 assert_avoptions(format_opts);
00785
00786
00787 for (i = 0; i < ic->nb_streams; i++)
00788 choose_decoder(o, ic, ic->streams[i]);
00789
00790
00791 opts = setup_find_stream_info_opts(ic, codec_opts);
00792 orig_nb_streams = ic->nb_streams;
00793
00794
00795
00796 ret = avformat_find_stream_info(ic, opts);
00797 if (ret < 0) {
00798 av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
00799 avformat_close_input(&ic);
00800 exit(1);
00801 }
00802
00803 timestamp = o->start_time;
00804
00805 if (ic->start_time != AV_NOPTS_VALUE)
00806 timestamp += ic->start_time;
00807
00808
00809 if (o->start_time != 0) {
00810 ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, timestamp, 0);
00811 if (ret < 0) {
00812 av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
00813 filename, (double)timestamp / AV_TIME_BASE);
00814 }
00815 }
00816
00817
00818 add_input_streams(o, ic);
00819
00820
00821 av_dump_format(ic, nb_input_files, filename, 0);
00822
00823 input_files = grow_array(input_files, sizeof(*input_files), &nb_input_files, nb_input_files + 1);
00824 if (!(input_files[nb_input_files - 1] = av_mallocz(sizeof(*input_files[0]))))
00825 exit(1);
00826
00827 input_files[nb_input_files - 1]->ctx = ic;
00828 input_files[nb_input_files - 1]->ist_index = nb_input_streams - ic->nb_streams;
00829 input_files[nb_input_files - 1]->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp);
00830 input_files[nb_input_files - 1]->nb_streams = ic->nb_streams;
00831 input_files[nb_input_files - 1]->rate_emu = o->rate_emu;
00832
00833 for (i = 0; i < o->nb_dump_attachment; i++) {
00834 int j;
00835
00836 for (j = 0; j < ic->nb_streams; j++) {
00837 AVStream *st = ic->streams[j];
00838
00839 if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
00840 dump_attachment(st, o->dump_attachment[i].u.str);
00841 }
00842 }
00843
00844 for (i = 0; i < orig_nb_streams; i++)
00845 av_dict_free(&opts[i]);
00846 av_freep(&opts);
00847
00848 reset_options(o, 1);
00849 return 0;
00850 }
00851
00852 static uint8_t *get_line(AVIOContext *s)
00853 {
00854 AVIOContext *line;
00855 uint8_t *buf;
00856 char c;
00857
00858 if (avio_open_dyn_buf(&line) < 0) {
00859 av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
00860 exit(1);
00861 }
00862
00863 while ((c = avio_r8(s)) && c != '\n')
00864 avio_w8(line, c);
00865 avio_w8(line, 0);
00866 avio_close_dyn_buf(line, &buf);
00867
00868 return buf;
00869 }
00870
00871 static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
00872 {
00873 int i, ret = 1;
00874 char filename[1000];
00875 const char *base[3] = { getenv("AVCONV_DATADIR"),
00876 getenv("HOME"),
00877 AVCONV_DATADIR,
00878 };
00879
00880 for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
00881 if (!base[i])
00882 continue;
00883 if (codec_name) {
00884 snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
00885 i != 1 ? "" : "/.avconv", codec_name, preset_name);
00886 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
00887 }
00888 if (ret) {
00889 snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
00890 i != 1 ? "" : "/.avconv", preset_name);
00891 ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
00892 }
00893 }
00894 return ret;
00895 }
00896
00897 static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
00898 {
00899 char *codec_name = NULL;
00900
00901 MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
00902 if (!codec_name) {
00903 ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
00904 NULL, ost->st->codec->codec_type);
00905 ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
00906 } else if (!strcmp(codec_name, "copy"))
00907 ost->stream_copy = 1;
00908 else {
00909 ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
00910 ost->st->codec->codec_id = ost->enc->id;
00911 }
00912 }
00913
00914 static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type, int source_index)
00915 {
00916 OutputStream *ost;
00917 AVStream *st = avformat_new_stream(oc, NULL);
00918 int idx = oc->nb_streams - 1, ret = 0;
00919 char *bsf = NULL, *next, *codec_tag = NULL;
00920 AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
00921 double qscale = -1;
00922
00923 if (!st) {
00924 av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
00925 exit(1);
00926 }
00927
00928 if (oc->nb_streams - 1 < o->nb_streamid_map)
00929 st->id = o->streamid_map[oc->nb_streams - 1];
00930
00931 output_streams = grow_array(output_streams, sizeof(*output_streams), &nb_output_streams,
00932 nb_output_streams + 1);
00933 if (!(ost = av_mallocz(sizeof(*ost))))
00934 exit(1);
00935 output_streams[nb_output_streams - 1] = ost;
00936
00937 ost->file_index = nb_output_files;
00938 ost->index = idx;
00939 ost->st = st;
00940 st->codec->codec_type = type;
00941 choose_encoder(o, oc, ost);
00942 if (ost->enc) {
00943 AVIOContext *s = NULL;
00944 char *buf = NULL, *arg = NULL, *preset = NULL;
00945
00946 ost->opts = filter_codec_opts(codec_opts, ost->enc->id, oc, st, ost->enc);
00947
00948 MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
00949 if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
00950 do {
00951 buf = get_line(s);
00952 if (!buf[0] || buf[0] == '#') {
00953 av_free(buf);
00954 continue;
00955 }
00956 if (!(arg = strchr(buf, '='))) {
00957 av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
00958 exit(1);
00959 }
00960 *arg++ = 0;
00961 av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
00962 av_free(buf);
00963 } while (!s->eof_reached);
00964 avio_close(s);
00965 }
00966 if (ret) {
00967 av_log(NULL, AV_LOG_FATAL,
00968 "Preset %s specified for stream %d:%d, but could not be opened.\n",
00969 preset, ost->file_index, ost->index);
00970 exit(1);
00971 }
00972 }
00973
00974 avcodec_get_context_defaults3(st->codec, ost->enc);
00975 st->codec->codec_type = type;
00976
00977 ost->max_frames = INT64_MAX;
00978 MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
00979
00980 ost->copy_prior_start = -1;
00981 MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st);
00982
00983 MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
00984 while (bsf) {
00985 if (next = strchr(bsf, ','))
00986 *next++ = 0;
00987 if (!(bsfc = av_bitstream_filter_init(bsf))) {
00988 av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
00989 exit(1);
00990 }
00991 if (bsfc_prev)
00992 bsfc_prev->next = bsfc;
00993 else
00994 ost->bitstream_filters = bsfc;
00995
00996 bsfc_prev = bsfc;
00997 bsf = next;
00998 }
00999
01000 MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
01001 if (codec_tag) {
01002 uint32_t tag = strtol(codec_tag, &next, 0);
01003 if (*next)
01004 tag = AV_RL32(codec_tag);
01005 st->codec->codec_tag = tag;
01006 }
01007
01008 MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
01009 if (qscale >= 0) {
01010 st->codec->flags |= CODEC_FLAG_QSCALE;
01011 st->codec->global_quality = FF_QP2LAMBDA * qscale;
01012 }
01013
01014 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
01015 st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
01016
01017 av_opt_get_int(sws_opts, "sws_flags", 0, &ost->sws_flags);
01018 av_opt_get_int (swr_opts, "filter_type" , 0, &ost->swr_filter_type);
01019 av_opt_get_int (swr_opts, "dither_method", 0, &ost->swr_dither_method);
01020 av_opt_get_double(swr_opts, "dither_scale" , 0, &ost->swr_dither_scale);
01021
01022 ost->source_index = source_index;
01023 if (source_index >= 0) {
01024 ost->sync_ist = input_streams[source_index];
01025 input_streams[source_index]->discard = 0;
01026 input_streams[source_index]->st->discard = AVDISCARD_NONE;
01027 }
01028
01029 return ost;
01030 }
01031
01032 static void parse_matrix_coeffs(uint16_t *dest, const char *str)
01033 {
01034 int i;
01035 const char *p = str;
01036 for (i = 0;; i++) {
01037 dest[i] = atoi(p);
01038 if (i == 63)
01039 break;
01040 p = strchr(p, ',');
01041 if (!p) {
01042 av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
01043 exit(1);
01044 }
01045 p++;
01046 }
01047 }
01048
01049 static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
01050 {
01051 AVStream *st;
01052 OutputStream *ost;
01053 AVCodecContext *video_enc;
01054 char *frame_rate = NULL;
01055
01056 ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);
01057 st = ost->st;
01058 video_enc = st->codec;
01059
01060 MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
01061 if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
01062 av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
01063 exit(1);
01064 }
01065
01066 if (!ost->stream_copy) {
01067 const char *p = NULL;
01068 char *frame_size = NULL;
01069 char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL;
01070 char *intra_matrix = NULL, *inter_matrix = NULL;
01071 const char *filters = "null";
01072 int do_pass = 0;
01073 int i;
01074
01075 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
01076 if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
01077 av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
01078 exit(1);
01079 }
01080
01081 MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
01082 if (frame_aspect_ratio) {
01083 AVRational q;
01084 if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
01085 q.num <= 0 || q.den <= 0) {
01086 av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
01087 exit(1);
01088 }
01089 ost->frame_aspect_ratio = av_q2d(q);
01090 }
01091
01092 video_enc->bits_per_raw_sample = frame_bits_per_raw_sample;
01093 MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
01094 if (frame_pix_fmt && *frame_pix_fmt == '+') {
01095 ost->keep_pix_fmt = 1;
01096 if (!*++frame_pix_fmt)
01097 frame_pix_fmt = NULL;
01098 }
01099 if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
01100 av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
01101 exit(1);
01102 }
01103 st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
01104
01105 if (intra_only)
01106 video_enc->gop_size = 0;
01107 MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
01108 if (intra_matrix) {
01109 if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
01110 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
01111 exit(1);
01112 }
01113 parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
01114 }
01115 MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
01116 if (inter_matrix) {
01117 if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
01118 av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
01119 exit(1);
01120 }
01121 parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
01122 }
01123
01124 MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
01125 for (i = 0; p; i++) {
01126 int start, end, q;
01127 int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
01128 if (e != 3) {
01129 av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
01130 exit(1);
01131 }
01132
01133 video_enc->rc_override =
01134 av_realloc(video_enc->rc_override,
01135 sizeof(RcOverride) * (i + 1));
01136 video_enc->rc_override[i].start_frame = start;
01137 video_enc->rc_override[i].end_frame = end;
01138 if (q > 0) {
01139 video_enc->rc_override[i].qscale = q;
01140 video_enc->rc_override[i].quality_factor = 1.0;
01141 }
01142 else {
01143 video_enc->rc_override[i].qscale = 0;
01144 video_enc->rc_override[i].quality_factor = -q/100.0;
01145 }
01146 p = strchr(p, '/');
01147 if (p) p++;
01148 }
01149 video_enc->rc_override_count = i;
01150 if (!video_enc->rc_initial_buffer_occupancy)
01151 video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size * 3 / 4;
01152 video_enc->intra_dc_precision = intra_dc_precision - 8;
01153
01154 if (do_psnr)
01155 video_enc->flags|= CODEC_FLAG_PSNR;
01156
01157
01158 MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
01159 if (do_pass) {
01160 if (do_pass & 1) {
01161 video_enc->flags |= CODEC_FLAG_PASS1;
01162 }
01163 if (do_pass & 2) {
01164 video_enc->flags |= CODEC_FLAG_PASS2;
01165 }
01166 }
01167
01168 MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
01169 if (ost->logfile_prefix &&
01170 !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
01171 exit(1);
01172
01173 MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
01174 if (ost->forced_keyframes)
01175 ost->forced_keyframes = av_strdup(ost->forced_keyframes);
01176
01177 MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
01178
01179 ost->top_field_first = -1;
01180 MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
01181
01182 MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
01183 ost->avfilter = av_strdup(filters);
01184 } else {
01185 MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
01186 }
01187
01188 return ost;
01189 }
01190
01191 static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
01192 {
01193 int n;
01194 AVStream *st;
01195 OutputStream *ost;
01196 AVCodecContext *audio_enc;
01197
01198 ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO, source_index);
01199 st = ost->st;
01200
01201 audio_enc = st->codec;
01202 audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
01203
01204 if (!ost->stream_copy) {
01205 char *sample_fmt = NULL;
01206 const char *filters = "anull";
01207
01208 MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
01209
01210 MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
01211 if (sample_fmt &&
01212 (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
01213 av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
01214 exit(1);
01215 }
01216
01217 MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
01218
01219 MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
01220
01221 av_assert1(filters);
01222 ost->avfilter = av_strdup(filters);
01223
01224
01225 for (n = 0; n < o->nb_audio_channel_maps; n++) {
01226 AudioChannelMap *map = &o->audio_channel_maps[n];
01227 InputStream *ist = input_streams[ost->source_index];
01228 if ((map->channel_idx == -1 || (ist->file_index == map->file_idx && ist->st->index == map->stream_idx)) &&
01229 (map->ofile_idx == -1 || ost->file_index == map->ofile_idx) &&
01230 (map->ostream_idx == -1 || ost->st->index == map->ostream_idx)) {
01231 if (ost->audio_channels_mapped < FF_ARRAY_ELEMS(ost->audio_channels_map))
01232 ost->audio_channels_map[ost->audio_channels_mapped++] = map->channel_idx;
01233 else
01234 av_log(NULL, AV_LOG_FATAL, "Max channel mapping for output %d.%d reached\n",
01235 ost->file_index, ost->st->index);
01236 }
01237 }
01238 }
01239
01240 return ost;
01241 }
01242
01243 static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
01244 {
01245 OutputStream *ost;
01246
01247 ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA, source_index);
01248 if (!ost->stream_copy) {
01249 av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
01250 exit(1);
01251 }
01252
01253 return ost;
01254 }
01255
01256 static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
01257 {
01258 OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT, source_index);
01259 ost->stream_copy = 1;
01260 return ost;
01261 }
01262
01263 static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
01264 {
01265 AVStream *st;
01266 OutputStream *ost;
01267 AVCodecContext *subtitle_enc;
01268
01269 ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE, source_index);
01270 st = ost->st;
01271 subtitle_enc = st->codec;
01272
01273 subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
01274
01275 MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc, st);
01276
01277 if (!ost->stream_copy) {
01278 char *frame_size = NULL;
01279
01280 MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
01281 if (frame_size && av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size) < 0) {
01282 av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
01283 exit(1);
01284 }
01285 }
01286
01287 return ost;
01288 }
01289
01290
01291 static int opt_streamid(void *optctx, const char *opt, const char *arg)
01292 {
01293 OptionsContext *o = optctx;
01294 int idx;
01295 char *p;
01296 char idx_str[16];
01297
01298 av_strlcpy(idx_str, arg, sizeof(idx_str));
01299 p = strchr(idx_str, ':');
01300 if (!p) {
01301 av_log(NULL, AV_LOG_FATAL,
01302 "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
01303 arg, opt);
01304 exit(1);
01305 }
01306 *p++ = '\0';
01307 idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
01308 o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
01309 o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
01310 return 0;
01311 }
01312
01313 static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
01314 {
01315 AVFormatContext *is = ifile->ctx;
01316 AVFormatContext *os = ofile->ctx;
01317 AVChapter **tmp;
01318 int i;
01319
01320 tmp = av_realloc_f(os->chapters, is->nb_chapters + os->nb_chapters, sizeof(*os->chapters));
01321 if (!tmp)
01322 return AVERROR(ENOMEM);
01323 os->chapters = tmp;
01324
01325 for (i = 0; i < is->nb_chapters; i++) {
01326 AVChapter *in_ch = is->chapters[i], *out_ch;
01327 int64_t ts_off = av_rescale_q(ofile->start_time - ifile->ts_offset,
01328 AV_TIME_BASE_Q, in_ch->time_base);
01329 int64_t rt = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
01330 av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
01331
01332
01333 if (in_ch->end < ts_off)
01334 continue;
01335 if (rt != INT64_MAX && in_ch->start > rt + ts_off)
01336 break;
01337
01338 out_ch = av_mallocz(sizeof(AVChapter));
01339 if (!out_ch)
01340 return AVERROR(ENOMEM);
01341
01342 out_ch->id = in_ch->id;
01343 out_ch->time_base = in_ch->time_base;
01344 out_ch->start = FFMAX(0, in_ch->start - ts_off);
01345 out_ch->end = FFMIN(rt, in_ch->end - ts_off);
01346
01347 if (copy_metadata)
01348 av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
01349
01350 os->chapters[os->nb_chapters++] = out_ch;
01351 }
01352 return 0;
01353 }
01354
01355 static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
01356 {
01357 int i, err;
01358 AVFormatContext *ic = avformat_alloc_context();
01359
01360 ic->interrupt_callback = int_cb;
01361 err = avformat_open_input(&ic, filename, NULL, NULL);
01362 if (err < 0)
01363 return err;
01364
01365 for(i=0;i<ic->nb_streams;i++) {
01366 AVStream *st;
01367 OutputStream *ost;
01368 AVCodec *codec;
01369 AVCodecContext *avctx;
01370
01371 codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
01372 ost = new_output_stream(o, s, codec->type, -1);
01373 st = ost->st;
01374 avctx = st->codec;
01375 ost->enc = codec;
01376
01377
01378 memcpy(st, ic->streams[i], sizeof(AVStream));
01379 st->cur_dts = 0;
01380 st->info = av_malloc(sizeof(*st->info));
01381 memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
01382 st->codec= avctx;
01383 avcodec_copy_context(st->codec, ic->streams[i]->codec);
01384
01385 if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
01386 choose_sample_fmt(st, codec);
01387 else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
01388 choose_pixel_fmt(st, codec, st->codec->pix_fmt);
01389 }
01390
01391
01392 err = parse_option(o, "metadata", "creation_time=now", options);
01393
01394 avformat_close_input(&ic);
01395 return err;
01396 }
01397
01398 static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
01399 AVFormatContext *oc)
01400 {
01401 OutputStream *ost;
01402
01403 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
01404 ofilter->out_tmp->pad_idx)) {
01405 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc, -1); break;
01406 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, -1); break;
01407 default:
01408 av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
01409 "currently.\n");
01410 exit(1);
01411 }
01412
01413 ost->source_index = -1;
01414 ost->filter = ofilter;
01415
01416 ofilter->ost = ost;
01417
01418 if (ost->stream_copy) {
01419 av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
01420 "which is fed from a complex filtergraph. Filtering and streamcopy "
01421 "cannot be used together.\n", ost->file_index, ost->index);
01422 exit(1);
01423 }
01424
01425 if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
01426 av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
01427 exit(1);
01428 }
01429 avfilter_inout_free(&ofilter->out_tmp);
01430 }
01431
01432 static int configure_complex_filters(void)
01433 {
01434 int i, ret = 0;
01435
01436 for (i = 0; i < nb_filtergraphs; i++)
01437 if (!filtergraphs[i]->graph &&
01438 (ret = configure_filtergraph(filtergraphs[i])) < 0)
01439 return ret;
01440 return 0;
01441 }
01442
01443 void opt_output_file(void *optctx, const char *filename)
01444 {
01445 OptionsContext *o = optctx;
01446 AVFormatContext *oc;
01447 int i, j, err;
01448 AVOutputFormat *file_oformat;
01449 OutputStream *ost;
01450 InputStream *ist;
01451
01452 if (configure_complex_filters() < 0) {
01453 av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
01454 exit(1);
01455 }
01456
01457 if (!strcmp(filename, "-"))
01458 filename = "pipe:";
01459
01460 err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
01461 if (!oc) {
01462 print_error(filename, err);
01463 exit(1);
01464 }
01465 file_oformat= oc->oformat;
01466 oc->interrupt_callback = int_cb;
01467
01468
01469 for (i = 0; i < nb_filtergraphs; i++) {
01470 FilterGraph *fg = filtergraphs[i];
01471 for (j = 0; j < fg->nb_outputs; j++) {
01472 OutputFilter *ofilter = fg->outputs[j];
01473
01474 if (!ofilter->out_tmp || ofilter->out_tmp->name)
01475 continue;
01476
01477 switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
01478 ofilter->out_tmp->pad_idx)) {
01479 case AVMEDIA_TYPE_VIDEO: o->video_disable = 1; break;
01480 case AVMEDIA_TYPE_AUDIO: o->audio_disable = 1; break;
01481 case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
01482 }
01483 init_output_filter(ofilter, o, oc);
01484 }
01485 }
01486
01487 if (!strcmp(file_oformat->name, "ffm") &&
01488 av_strstart(filename, "http:", NULL)) {
01489 int j;
01490
01491
01492 int err = read_ffserver_streams(o, oc, filename);
01493 if (err < 0) {
01494 print_error(filename, err);
01495 exit(1);
01496 }
01497 for(j = nb_output_streams - oc->nb_streams; j < nb_output_streams; j++) {
01498 ost = output_streams[j];
01499 for (i = 0; i < nb_input_streams; i++) {
01500 ist = input_streams[i];
01501 if(ist->st->codec->codec_type == ost->st->codec->codec_type){
01502 ost->sync_ist= ist;
01503 ost->source_index= i;
01504 if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) ost->avfilter = av_strdup("anull");
01505 if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) ost->avfilter = av_strdup("null");
01506 ist->discard = 0;
01507 ist->st->discard = AVDISCARD_NONE;
01508 break;
01509 }
01510 }
01511 if(!ost->sync_ist){
01512 av_log(NULL, AV_LOG_FATAL, "Missing %s stream which is required by this ffm\n", av_get_media_type_string(ost->st->codec->codec_type));
01513 exit(1);
01514 }
01515 }
01516 } else if (!o->nb_stream_maps) {
01517 char *subtitle_codec_name = NULL;
01518
01519
01520
01521 if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
01522 int area = 0, idx = -1;
01523 int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
01524 for (i = 0; i < nb_input_streams; i++) {
01525 int new_area;
01526 ist = input_streams[i];
01527 new_area = ist->st->codec->width * ist->st->codec->height;
01528 if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
01529 new_area = 1;
01530 if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
01531 new_area > area) {
01532 if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
01533 continue;
01534 area = new_area;
01535 idx = i;
01536 }
01537 }
01538 if (idx >= 0)
01539 new_video_stream(o, oc, idx);
01540 }
01541
01542
01543 if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
01544 int channels = 0, idx = -1;
01545 for (i = 0; i < nb_input_streams; i++) {
01546 ist = input_streams[i];
01547 if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
01548 ist->st->codec->channels > channels) {
01549 channels = ist->st->codec->channels;
01550 idx = i;
01551 }
01552 }
01553 if (idx >= 0)
01554 new_audio_stream(o, oc, idx);
01555 }
01556
01557
01558 MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");
01559 if (!o->subtitle_disable && (oc->oformat->subtitle_codec != AV_CODEC_ID_NONE || subtitle_codec_name)) {
01560 for (i = 0; i < nb_input_streams; i++)
01561 if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
01562 new_subtitle_stream(o, oc, i);
01563 break;
01564 }
01565 }
01566
01567 } else {
01568 for (i = 0; i < o->nb_stream_maps; i++) {
01569 StreamMap *map = &o->stream_maps[i];
01570 int src_idx = input_files[map->file_index]->ist_index + map->stream_index;
01571
01572 if (map->disabled)
01573 continue;
01574
01575 if (map->linklabel) {
01576 FilterGraph *fg;
01577 OutputFilter *ofilter = NULL;
01578 int j, k;
01579
01580 for (j = 0; j < nb_filtergraphs; j++) {
01581 fg = filtergraphs[j];
01582 for (k = 0; k < fg->nb_outputs; k++) {
01583 AVFilterInOut *out = fg->outputs[k]->out_tmp;
01584 if (out && !strcmp(out->name, map->linklabel)) {
01585 ofilter = fg->outputs[k];
01586 goto loop_end;
01587 }
01588 }
01589 }
01590 loop_end:
01591 if (!ofilter) {
01592 av_log(NULL, AV_LOG_FATAL, "Output with label '%s' does not exist "
01593 "in any defined filter graph.\n", map->linklabel);
01594 exit(1);
01595 }
01596 init_output_filter(ofilter, o, oc);
01597 } else {
01598 ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
01599 if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
01600 continue;
01601 if(o-> audio_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
01602 continue;
01603 if(o-> video_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
01604 continue;
01605 if(o-> data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA)
01606 continue;
01607
01608 switch (ist->st->codec->codec_type) {
01609 case AVMEDIA_TYPE_VIDEO: ost = new_video_stream (o, oc, src_idx); break;
01610 case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream (o, oc, src_idx); break;
01611 case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream (o, oc, src_idx); break;
01612 case AVMEDIA_TYPE_DATA: ost = new_data_stream (o, oc, src_idx); break;
01613 case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break;
01614 default:
01615 av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
01616 map->file_index, map->stream_index);
01617 exit(1);
01618 }
01619 }
01620 }
01621 }
01622
01623
01624 for (i = nb_output_streams - oc->nb_streams; i < nb_output_streams; i++) {
01625 AVDictionaryEntry *e;
01626 ost = output_streams[i];
01627
01628 if ( ost->stream_copy
01629 && (e = av_dict_get(codec_opts, "flags", NULL, AV_DICT_IGNORE_SUFFIX))
01630 && (!e->key[5] || check_stream_specifier(oc, ost->st, e->key+6)))
01631 if (av_opt_set(ost->st->codec, "flags", e->value, 0) < 0)
01632 exit(1);
01633 }
01634
01635
01636 for (i = 0; i < o->nb_attachments; i++) {
01637 AVIOContext *pb;
01638 uint8_t *attachment;
01639 const char *p;
01640 int64_t len;
01641
01642 if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
01643 av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
01644 o->attachments[i]);
01645 exit(1);
01646 }
01647 if ((len = avio_size(pb)) <= 0) {
01648 av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
01649 o->attachments[i]);
01650 exit(1);
01651 }
01652 if (!(attachment = av_malloc(len))) {
01653 av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
01654 o->attachments[i]);
01655 exit(1);
01656 }
01657 avio_read(pb, attachment, len);
01658
01659 ost = new_attachment_stream(o, oc, -1);
01660 ost->stream_copy = 0;
01661 ost->attachment_filename = o->attachments[i];
01662 ost->st->codec->extradata = attachment;
01663 ost->st->codec->extradata_size = len;
01664
01665 p = strrchr(o->attachments[i], '/');
01666 av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
01667 avio_close(pb);
01668 }
01669
01670 output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1);
01671 if (!(output_files[nb_output_files - 1] = av_mallocz(sizeof(*output_files[0]))))
01672 exit(1);
01673
01674 output_files[nb_output_files - 1]->ctx = oc;
01675 output_files[nb_output_files - 1]->ost_index = nb_output_streams - oc->nb_streams;
01676 output_files[nb_output_files - 1]->recording_time = o->recording_time;
01677 if (o->recording_time != INT64_MAX)
01678 oc->duration = o->recording_time;
01679 output_files[nb_output_files - 1]->start_time = o->start_time;
01680 output_files[nb_output_files - 1]->limit_filesize = o->limit_filesize;
01681 output_files[nb_output_files - 1]->shortest = o->shortest;
01682 av_dict_copy(&output_files[nb_output_files - 1]->opts, format_opts, 0);
01683
01684
01685 if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
01686 if (!av_filename_number_test(oc->filename)) {
01687 print_error(oc->filename, AVERROR(EINVAL));
01688 exit(1);
01689 }
01690 }
01691
01692 if (!(oc->oformat->flags & AVFMT_NOFILE)) {
01693
01694 assert_file_overwrite(filename);
01695
01696
01697 if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
01698 &oc->interrupt_callback,
01699 &output_files[nb_output_files - 1]->opts)) < 0) {
01700 print_error(filename, err);
01701 exit(1);
01702 }
01703 }
01704
01705 if (o->mux_preload) {
01706 uint8_t buf[64];
01707 snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
01708 av_dict_set(&output_files[nb_output_files - 1]->opts, "preload", buf, 0);
01709 }
01710 oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
01711
01712
01713 for (i = 0; i < o->nb_metadata_map; i++) {
01714 char *p;
01715 int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
01716
01717 if (in_file_index >= nb_input_files) {
01718 av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
01719 exit(1);
01720 }
01721 copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc,
01722 in_file_index >= 0 ?
01723 input_files[in_file_index]->ctx : NULL, o);
01724 }
01725
01726
01727 if (o->chapters_input_file >= nb_input_files) {
01728 if (o->chapters_input_file == INT_MAX) {
01729
01730 o->chapters_input_file = -1;
01731 for (i = 0; i < nb_input_files; i++)
01732 if (input_files[i]->ctx->nb_chapters) {
01733 o->chapters_input_file = i;
01734 break;
01735 }
01736 } else {
01737 av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
01738 o->chapters_input_file);
01739 exit(1);
01740 }
01741 }
01742 if (o->chapters_input_file >= 0)
01743 copy_chapters(input_files[o->chapters_input_file], output_files[nb_output_files - 1],
01744 !o->metadata_chapters_manual);
01745
01746
01747 if (!o->metadata_global_manual && nb_input_files){
01748 av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
01749 AV_DICT_DONT_OVERWRITE);
01750 if(o->recording_time != INT64_MAX)
01751 av_dict_set(&oc->metadata, "duration", NULL, 0);
01752 av_dict_set(&oc->metadata, "creation_time", NULL, 0);
01753 }
01754 if (!o->metadata_streams_manual)
01755 for (i = output_files[nb_output_files - 1]->ost_index; i < nb_output_streams; i++) {
01756 InputStream *ist;
01757 if (output_streams[i]->source_index < 0)
01758 continue;
01759 ist = input_streams[output_streams[i]->source_index];
01760 av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
01761 }
01762
01763
01764 for (i = 0; i < o->nb_metadata; i++) {
01765 AVDictionary **m;
01766 char type, *val;
01767 const char *stream_spec;
01768 int index = 0, j, ret = 0;
01769
01770 val = strchr(o->metadata[i].u.str, '=');
01771 if (!val) {
01772 av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
01773 o->metadata[i].u.str);
01774 exit(1);
01775 }
01776 *val++ = 0;
01777
01778 parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
01779 if (type == 's') {
01780 for (j = 0; j < oc->nb_streams; j++) {
01781 if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
01782 av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
01783 } else if (ret < 0)
01784 exit(1);
01785 }
01786 }
01787 else {
01788 switch (type) {
01789 case 'g':
01790 m = &oc->metadata;
01791 break;
01792 case 'c':
01793 if (index < 0 || index >= oc->nb_chapters) {
01794 av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
01795 exit(1);
01796 }
01797 m = &oc->chapters[index]->metadata;
01798 break;
01799 default:
01800 av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
01801 exit(1);
01802 }
01803 av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
01804 }
01805 }
01806
01807 reset_options(o, 0);
01808 }
01809
01810 static int opt_target(void *optctx, const char *opt, const char *arg)
01811 {
01812 OptionsContext *o = optctx;
01813 enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
01814 static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
01815
01816 if (!strncmp(arg, "pal-", 4)) {
01817 norm = PAL;
01818 arg += 4;
01819 } else if (!strncmp(arg, "ntsc-", 5)) {
01820 norm = NTSC;
01821 arg += 5;
01822 } else if (!strncmp(arg, "film-", 5)) {
01823 norm = FILM;
01824 arg += 5;
01825 } else {
01826
01827 if (nb_input_files) {
01828 int i, j, fr;
01829 for (j = 0; j < nb_input_files; j++) {
01830 for (i = 0; i < input_files[j]->nb_streams; i++) {
01831 AVCodecContext *c = input_files[j]->ctx->streams[i]->codec;
01832 if (c->codec_type != AVMEDIA_TYPE_VIDEO)
01833 continue;
01834 fr = c->time_base.den * 1000 / c->time_base.num;
01835 if (fr == 25000) {
01836 norm = PAL;
01837 break;
01838 } else if ((fr == 29970) || (fr == 23976)) {
01839 norm = NTSC;
01840 break;
01841 }
01842 }
01843 if (norm != UNKNOWN)
01844 break;
01845 }
01846 }
01847 if (norm != UNKNOWN)
01848 av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
01849 }
01850
01851 if (norm == UNKNOWN) {
01852 av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
01853 av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
01854 av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
01855 exit(1);
01856 }
01857
01858 if (!strcmp(arg, "vcd")) {
01859 opt_video_codec(o, "c:v", "mpeg1video");
01860 opt_audio_codec(o, "c:a", "mp2");
01861 parse_option(o, "f", "vcd", options);
01862
01863 parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
01864 parse_option(o, "r", frame_rates[norm], options);
01865 opt_default(NULL, "g", norm == PAL ? "15" : "18");
01866
01867 opt_default(NULL, "b:v", "1150000");
01868 opt_default(NULL, "maxrate", "1150000");
01869 opt_default(NULL, "minrate", "1150000");
01870 opt_default(NULL, "bufsize", "327680");
01871
01872 opt_default(NULL, "b:a", "224000");
01873 parse_option(o, "ar", "44100", options);
01874 parse_option(o, "ac", "2", options);
01875
01876 opt_default(NULL, "packetsize", "2324");
01877 opt_default(NULL, "muxrate", "1411200");
01878
01879
01880
01881
01882
01883
01884 o->mux_preload = (36000 + 3 * 1200) / 90000.0;
01885 } else if (!strcmp(arg, "svcd")) {
01886
01887 opt_video_codec(o, "c:v", "mpeg2video");
01888 opt_audio_codec(o, "c:a", "mp2");
01889 parse_option(o, "f", "svcd", options);
01890
01891 parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
01892 parse_option(o, "r", frame_rates[norm], options);
01893 parse_option(o, "pix_fmt", "yuv420p", options);
01894 opt_default(NULL, "g", norm == PAL ? "15" : "18");
01895
01896 opt_default(NULL, "b:v", "2040000");
01897 opt_default(NULL, "maxrate", "2516000");
01898 opt_default(NULL, "minrate", "0");
01899 opt_default(NULL, "bufsize", "1835008");
01900 opt_default(NULL, "scan_offset", "1");
01901
01902 opt_default(NULL, "b:a", "224000");
01903 parse_option(o, "ar", "44100", options);
01904
01905 opt_default(NULL, "packetsize", "2324");
01906
01907 } else if (!strcmp(arg, "dvd")) {
01908
01909 opt_video_codec(o, "c:v", "mpeg2video");
01910 opt_audio_codec(o, "c:a", "ac3");
01911 parse_option(o, "f", "dvd", options);
01912
01913 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
01914 parse_option(o, "r", frame_rates[norm], options);
01915 parse_option(o, "pix_fmt", "yuv420p", options);
01916 opt_default(NULL, "g", norm == PAL ? "15" : "18");
01917
01918 opt_default(NULL, "b:v", "6000000");
01919 opt_default(NULL, "maxrate", "9000000");
01920 opt_default(NULL, "minrate", "0");
01921 opt_default(NULL, "bufsize", "1835008");
01922
01923 opt_default(NULL, "packetsize", "2048");
01924 opt_default(NULL, "muxrate", "10080000");
01925
01926 opt_default(NULL, "b:a", "448000");
01927 parse_option(o, "ar", "48000", options);
01928
01929 } else if (!strncmp(arg, "dv", 2)) {
01930
01931 parse_option(o, "f", "dv", options);
01932
01933 parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
01934 parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
01935 norm == PAL ? "yuv420p" : "yuv411p", options);
01936 parse_option(o, "r", frame_rates[norm], options);
01937
01938 parse_option(o, "ar", "48000", options);
01939 parse_option(o, "ac", "2", options);
01940
01941 } else {
01942 av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
01943 return AVERROR(EINVAL);
01944 }
01945 return 0;
01946 }
01947
01948 static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
01949 {
01950 av_free (vstats_filename);
01951 vstats_filename = av_strdup (arg);
01952 return 0;
01953 }
01954
01955 static int opt_vstats(void *optctx, const char *opt, const char *arg)
01956 {
01957 char filename[40];
01958 time_t today2 = time(NULL);
01959 struct tm *today = localtime(&today2);
01960
01961 snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
01962 today->tm_sec);
01963 return opt_vstats_file(NULL, opt, filename);
01964 }
01965
01966 static int opt_video_frames(void *optctx, const char *opt, const char *arg)
01967 {
01968 OptionsContext *o = optctx;
01969 return parse_option(o, "frames:v", arg, options);
01970 }
01971
01972 static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
01973 {
01974 OptionsContext *o = optctx;
01975 return parse_option(o, "frames:a", arg, options);
01976 }
01977
01978 static int opt_data_frames(void *optctx, const char *opt, const char *arg)
01979 {
01980 OptionsContext *o = optctx;
01981 return parse_option(o, "frames:d", arg, options);
01982 }
01983
01984 static int opt_preset(void *optctx, const char *opt, const char *arg)
01985 {
01986 OptionsContext *o = optctx;
01987 FILE *f=NULL;
01988 char filename[1000], line[1000], tmp_line[1000];
01989 const char *codec_name = NULL;
01990
01991 tmp_line[0] = *opt;
01992 tmp_line[1] = 0;
01993 MATCH_PER_TYPE_OPT(codec_names, str, codec_name, NULL, tmp_line);
01994
01995 if (!(f = get_preset_file(filename, sizeof(filename), arg, *opt == 'f', codec_name))) {
01996 if(!strncmp(arg, "libx264-lossless", strlen("libx264-lossless"))){
01997 av_log(NULL, AV_LOG_FATAL, "Please use -preset <speed> -qp 0\n");
01998 }else
01999 av_log(NULL, AV_LOG_FATAL, "File for preset '%s' not found\n", arg);
02000 exit(1);
02001 }
02002
02003 while (fgets(line, sizeof(line), f)) {
02004 char *key = tmp_line, *value, *endptr;
02005
02006 if (strcspn(line, "#\n\r") == 0)
02007 continue;
02008 strcpy(tmp_line, line);
02009 if (!av_strtok(key, "=", &value) ||
02010 !av_strtok(value, "\r\n", &endptr)) {
02011 av_log(NULL, AV_LOG_FATAL, "%s: Invalid syntax: '%s'\n", filename, line);
02012 exit(1);
02013 }
02014 av_log(NULL, AV_LOG_DEBUG, "ffpreset[%s]: set '%s' = '%s'\n", filename, key, value);
02015
02016 if (!strcmp(key, "acodec")) opt_audio_codec (o, key, value);
02017 else if (!strcmp(key, "vcodec")) opt_video_codec (o, key, value);
02018 else if (!strcmp(key, "scodec")) opt_subtitle_codec(o, key, value);
02019 else if (!strcmp(key, "dcodec")) opt_data_codec (o, key, value);
02020 else if (opt_default(NULL, key, value) < 0) {
02021 av_log(NULL, AV_LOG_FATAL, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n",
02022 filename, line, key, value);
02023 exit(1);
02024 }
02025 }
02026
02027 fclose(f);
02028
02029 return 0;
02030 }
02031
02032 static int opt_old2new(void *optctx, const char *opt, const char *arg)
02033 {
02034 OptionsContext *o = optctx;
02035 char *s = av_asprintf("%s:%c", opt + 1, *opt);
02036 int ret = parse_option(o, s, arg, options);
02037 av_free(s);
02038 return ret;
02039 }
02040
02041 static int opt_bitrate(void *optctx, const char *opt, const char *arg)
02042 {
02043 OptionsContext *o = optctx;
02044 if(!strcmp(opt, "b")){
02045 av_log(NULL, AV_LOG_WARNING, "Please use -b:a or -b:v, -b is ambiguous\n");
02046 return parse_option(o, "b:v", arg, options);
02047 }
02048 return opt_default(optctx, opt, arg);
02049 }
02050
02051 static int opt_qscale(void *optctx, const char *opt, const char *arg)
02052 {
02053 OptionsContext *o = optctx;
02054 char *s;
02055 int ret;
02056 if(!strcmp(opt, "qscale")){
02057 av_log(NULL, AV_LOG_WARNING, "Please use -q:a or -q:v, -qscale is ambiguous\n");
02058 return parse_option(o, "q:v", arg, options);
02059 }
02060 s = av_asprintf("q%s", opt + 6);
02061 ret = parse_option(o, s, arg, options);
02062 av_free(s);
02063 return ret;
02064 }
02065
02066 static int opt_profile(void *optctx, const char *opt, const char *arg)
02067 {
02068 OptionsContext *o = optctx;
02069 if(!strcmp(opt, "profile")){
02070 av_log(NULL, AV_LOG_WARNING, "Please use -profile:a or -profile:v, -profile is ambiguous\n");
02071 return parse_option(o, "profile:v", arg, options);
02072 }
02073 return opt_default(optctx, opt, arg);
02074
02075 }
02076
02077 static int opt_video_filters(void *optctx, const char *opt, const char *arg)
02078 {
02079 OptionsContext *o = optctx;
02080 return parse_option(o, "filter:v", arg, options);
02081 }
02082
02083 static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
02084 {
02085 OptionsContext *o = optctx;
02086 return parse_option(o, "filter:a", arg, options);
02087 }
02088
02089 static int opt_vsync(void *optctx, const char *opt, const char *arg)
02090 {
02091 if (!av_strcasecmp(arg, "cfr")) video_sync_method = VSYNC_CFR;
02092 else if (!av_strcasecmp(arg, "vfr")) video_sync_method = VSYNC_VFR;
02093 else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
02094 else if (!av_strcasecmp(arg, "drop")) video_sync_method = VSYNC_DROP;
02095
02096 if (video_sync_method == VSYNC_AUTO)
02097 video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
02098 return 0;
02099 }
02100
02101 static int opt_deinterlace(void *optctx, const char *opt, const char *arg)
02102 {
02103 av_log(NULL, AV_LOG_WARNING, "-%s is deprecated, use -filter:v yadif instead\n", opt);
02104 do_deinterlace = 1;
02105 return 0;
02106 }
02107
02108 static int opt_timecode(void *optctx, const char *opt, const char *arg)
02109 {
02110 OptionsContext *o = optctx;
02111 char *tcr = av_asprintf("timecode=%s", arg);
02112 int ret = parse_option(o, "metadata:g", tcr, options);
02113 if (ret >= 0)
02114 ret = opt_default(optctx, "gop_timecode", arg);
02115 av_free(tcr);
02116 return ret;
02117 }
02118
02119 static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
02120 {
02121 OptionsContext *o = optctx;
02122 char layout_str[32];
02123 char *stream_str;
02124 char *ac_str;
02125 int ret, channels, ac_str_size;
02126 uint64_t layout;
02127
02128 layout = av_get_channel_layout(arg);
02129 if (!layout) {
02130 av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
02131 return AVERROR(EINVAL);
02132 }
02133 snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
02134 ret = opt_default(NULL, opt, layout_str);
02135 if (ret < 0)
02136 return ret;
02137
02138
02139 channels = av_get_channel_layout_nb_channels(layout);
02140 snprintf(layout_str, sizeof(layout_str), "%d", channels);
02141 stream_str = strchr(opt, ':');
02142 ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
02143 ac_str = av_mallocz(ac_str_size);
02144 if (!ac_str)
02145 return AVERROR(ENOMEM);
02146 av_strlcpy(ac_str, "ac", 3);
02147 if (stream_str)
02148 av_strlcat(ac_str, stream_str, ac_str_size);
02149 ret = parse_option(o, ac_str, layout_str, options);
02150 av_free(ac_str);
02151
02152 return ret;
02153 }
02154
02155 static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
02156 {
02157 OptionsContext *o = optctx;
02158 return parse_option(o, "q:a", arg, options);
02159 }
02160
02161 static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
02162 {
02163 filtergraphs = grow_array(filtergraphs, sizeof(*filtergraphs),
02164 &nb_filtergraphs, nb_filtergraphs + 1);
02165 if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
02166 return AVERROR(ENOMEM);
02167 filtergraphs[nb_filtergraphs - 1]->index = nb_filtergraphs - 1;
02168 filtergraphs[nb_filtergraphs - 1]->graph_desc = arg;
02169 return 0;
02170 }
02171
02172 void show_help_default(const char *opt, const char *arg)
02173 {
02174
02175 const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
02176 int show_advanced = 0, show_avoptions = 0;
02177
02178 if (opt && *opt) {
02179 if (!strcmp(opt, "long"))
02180 show_advanced = 1;
02181 else if (!strcmp(opt, "full"))
02182 show_advanced = show_avoptions = 1;
02183 else
02184 av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
02185 }
02186
02187 show_usage();
02188
02189 printf("Getting help:\n"
02190 " -h -- print basic options\n"
02191 " -h long -- print more options\n"
02192 " -h full -- print all options (including all format and codec specific options, very long)\n"
02193 " See man %s for detailed description of the options.\n"
02194 "\n", program_name);
02195
02196 show_help_options(options, "Print help / information / capabilities:",
02197 OPT_EXIT, 0, 0);
02198
02199 show_help_options(options, "Global options (affect whole program "
02200 "instead of just one file:",
02201 0, per_file | OPT_EXIT | OPT_EXPERT, 0);
02202 if (show_advanced)
02203 show_help_options(options, "Advanced global options:", OPT_EXPERT,
02204 per_file | OPT_EXIT, 0);
02205
02206 show_help_options(options, "Per-file main options:", 0,
02207 OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
02208 OPT_EXIT, per_file);
02209 if (show_advanced)
02210 show_help_options(options, "Advanced per-file options:",
02211 OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
02212
02213 show_help_options(options, "Video options:",
02214 OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
02215 if (show_advanced)
02216 show_help_options(options, "Advanced Video options:",
02217 OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
02218
02219 show_help_options(options, "Audio options:",
02220 OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
02221 if (show_advanced)
02222 show_help_options(options, "Advanced Audio options:",
02223 OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
02224 show_help_options(options, "Subtitle options:",
02225 OPT_SUBTITLE, 0, 0);
02226 printf("\n");
02227
02228 if (show_avoptions) {
02229 int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
02230 show_help_children(avcodec_get_class(), flags);
02231 show_help_children(avformat_get_class(), flags);
02232 show_help_children(sws_get_class(), flags);
02233 show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
02234 show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
02235 }
02236 }
02237
02238 void show_usage(void)
02239 {
02240 av_log(NULL, AV_LOG_INFO, "Hyper fast Audio and Video encoder\n");
02241 av_log(NULL, AV_LOG_INFO, "usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
02242 av_log(NULL, AV_LOG_INFO, "\n");
02243 }
02244
02245
02246 static int opt_progress(void *optctx, const char *opt, const char *arg)
02247 {
02248 AVIOContext *avio = NULL;
02249 int ret;
02250
02251 if (!strcmp(arg, "-"))
02252 arg = "pipe:";
02253 ret = avio_open2(&avio, arg, AVIO_FLAG_WRITE, &int_cb, NULL);
02254 if (ret < 0) {
02255 av_log(NULL, AV_LOG_ERROR, "Failed to open progress URL \"%s\": %s\n",
02256 arg, av_err2str(ret));
02257 return ret;
02258 }
02259 progress_avio = avio;
02260 return 0;
02261 }
02262
02263 #define OFFSET(x) offsetof(OptionsContext, x)
02264 const OptionDef options[] = {
02265
02266 #include "cmdutils_common_opts.h"
02267 { "f", HAS_ARG | OPT_STRING | OPT_OFFSET, { .off = OFFSET(format) },
02268 "force format", "fmt" },
02269 { "i", HAS_ARG | OPT_PERFILE, { .func_arg = opt_input_file },
02270 "input file name", "filename" },
02271 { "y", OPT_BOOL, { &file_overwrite },
02272 "overwrite output files" },
02273 { "n", OPT_BOOL, { &no_file_overwrite },
02274 "do not overwrite output files" },
02275 { "c", HAS_ARG | OPT_STRING | OPT_SPEC, { .off = OFFSET(codec_names) },
02276 "codec name", "codec" },
02277 { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, { .off = OFFSET(codec_names) },
02278 "codec name", "codec" },
02279 { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, { .off = OFFSET(presets) },
02280 "preset name", "preset" },
02281 { "map", HAS_ARG | OPT_EXPERT | OPT_PERFILE, { .func_arg = opt_map },
02282 "set input stream mapping",
02283 "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
02284 { "map_channel", HAS_ARG | OPT_EXPERT | OPT_PERFILE, { .func_arg = opt_map_channel },
02285 "map an audio channel from one stream to another", "file.stream.channel[:syncfile.syncstream]" },
02286 { "map_metadata", HAS_ARG | OPT_STRING | OPT_SPEC, { .off = OFFSET(metadata_map) },
02287 "set metadata information of outfile from infile",
02288 "outfile[,metadata]:infile[,metadata]" },
02289 { "map_chapters", HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(chapters_input_file) },
02290 "set chapters mapping", "input_file_index" },
02291 { "t", HAS_ARG | OPT_TIME | OPT_OFFSET, { .off = OFFSET(recording_time) },
02292 "record or transcode \"duration\" seconds of audio/video",
02293 "duration" },
02294 { "fs", HAS_ARG | OPT_INT64 | OPT_OFFSET, { .off = OFFSET(limit_filesize) },
02295 "set the limit file size in bytes", "limit_size" },
02296 { "ss", HAS_ARG | OPT_TIME | OPT_OFFSET, { .off = OFFSET(start_time) },
02297 "set the start time offset", "time_off" },
02298 { "itsoffset", HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_EXPERT,{ .off = OFFSET(input_ts_offset) },
02299 "set the input ts offset", "time_off" },
02300 { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC | OPT_EXPERT,{ .off = OFFSET(ts_scale) },
02301 "set the input ts scale", "scale" },
02302 { "timestamp", HAS_ARG | OPT_PERFILE, { .func_arg = opt_recording_timestamp },
02303 "set the recording timestamp ('now' to set the current time)", "time" },
02304 { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC, { .off = OFFSET(metadata) },
02305 "add metadata", "string=string" },
02306 { "dframes", HAS_ARG | OPT_PERFILE | OPT_EXPERT, { .func_arg = opt_data_frames },
02307 "set the number of data frames to record", "number" },
02308 { "benchmark", OPT_BOOL | OPT_EXPERT, { &do_benchmark },
02309 "add timings for benchmarking" },
02310 { "benchmark_all", OPT_BOOL | OPT_EXPERT, { &do_benchmark_all },
02311 "add timings for each task" },
02312 { "progress", HAS_ARG | OPT_EXPERT, { .func_arg = opt_progress },
02313 "write program-readable progress information", "url" },
02314 { "stdin", OPT_BOOL | OPT_EXPERT, { &stdin_interaction },
02315 "enable or disable interaction on standard input" },
02316 { "timelimit", HAS_ARG | OPT_EXPERT, { .func_arg = opt_timelimit },
02317 "set max runtime in seconds", "limit" },
02318 { "dump", OPT_BOOL | OPT_EXPERT, { &do_pkt_dump },
02319 "dump each input packet" },
02320 { "hex", OPT_BOOL | OPT_EXPERT, { &do_hex_dump },
02321 "when dumping packets, also dump the payload" },
02322 { "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(rate_emu) },
02323 "read input at native frame rate", "" },
02324 { "target", HAS_ARG | OPT_PERFILE, { .func_arg = opt_target },
02325 "specify target file type (\"vcd\", \"svcd\", \"dvd\","
02326 " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
02327 { "vsync", HAS_ARG | OPT_EXPERT, { opt_vsync },
02328 "video sync method", "" },
02329 { "async", HAS_ARG | OPT_INT | OPT_EXPERT, { &audio_sync_method },
02330 "audio sync method", "" },
02331 { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &audio_drift_threshold },
02332 "audio drift threshold", "threshold" },
02333 { "copyts", OPT_BOOL | OPT_EXPERT, { ©_ts },
02334 "copy timestamps" },
02335 { "copytb", HAS_ARG | OPT_INT | OPT_EXPERT, { ©_tb },
02336 "copy input stream time base when stream copying", "mode" },
02337 { "shortest", OPT_BOOL | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(shortest) },
02338 "finish encoding within shortest input" },
02339 { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &dts_delta_threshold },
02340 "timestamp discontinuity delta threshold", "threshold" },
02341 { "dts_error_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT, { &dts_error_threshold },
02342 "timestamp error delta threshold", "threshold" },
02343 { "xerror", OPT_BOOL | OPT_EXPERT, { &exit_on_error },
02344 "exit on error", "error" },
02345 { "copyinkf", OPT_BOOL | OPT_EXPERT | OPT_SPEC, { .off = OFFSET(copy_initial_nonkeyframes) },
02346 "copy initial non-keyframes" },
02347 { "copypriorss", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_SPEC, { .off = OFFSET(copy_prior_start) },
02348 "copy or discard frames before start time" },
02349 { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC, { .off = OFFSET(max_frames) },
02350 "set the number of frames to record", "number" },
02351 { "tag", OPT_STRING | HAS_ARG | OPT_SPEC | OPT_EXPERT,{ .off = OFFSET(codec_tags) },
02352 "force codec tag/fourcc", "fourcc/tag" },
02353 { "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC,{ .off = OFFSET(qscale) },
02354 "use fixed quality scale (VBR)", "q" },
02355 { "qscale", HAS_ARG | OPT_EXPERT | OPT_PERFILE, { .func_arg = opt_qscale },
02356 "use fixed quality scale (VBR)", "q" },
02357 { "profile", HAS_ARG | OPT_EXPERT | OPT_PERFILE, { .func_arg = opt_profile },
02358 "set profile", "profile" },
02359 { "filter", HAS_ARG | OPT_STRING | OPT_SPEC, { .off = OFFSET(filters) },
02360 "set stream filterchain", "filter_list" },
02361 { "reinit_filter", HAS_ARG | OPT_INT | OPT_SPEC, { .off = OFFSET(reinit_filters) },
02362 "reinit filtergraph on input parameter changes", "" },
02363 { "filter_complex", HAS_ARG | OPT_EXPERT, { .func_arg = opt_filter_complex },
02364 "create a complex filtergraph", "graph_description" },
02365 { "stats", OPT_BOOL, { &print_stats },
02366 "print progress report during encoding", },
02367 { "attach", HAS_ARG | OPT_PERFILE | OPT_EXPERT, { .func_arg = opt_attach },
02368 "add an attachment to the output file", "filename" },
02369 { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |OPT_EXPERT,{ .off = OFFSET(dump_attachment) },
02370 "extract an attachment into a file", "filename" },
02371 { "debug_ts", OPT_BOOL | OPT_EXPERT, { &debug_ts },
02372 "print timestamp debugging info" },
02373
02374
02375 { "vframes", OPT_VIDEO | HAS_ARG | OPT_PERFILE, { .func_arg = opt_video_frames },
02376 "set the number of video frames to record", "number" },
02377 { "r", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC, { .off = OFFSET(frame_rates) },
02378 "set frame rate (Hz value, fraction or abbreviation)", "rate" },
02379 { "s", OPT_VIDEO | HAS_ARG | OPT_SUBTITLE | OPT_STRING | OPT_SPEC,{ .off = OFFSET(frame_sizes) },
02380 "set frame size (WxH or abbreviation)", "size" },
02381 { "aspect", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC, { .off = OFFSET(frame_aspect_ratios) },
02382 "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
02383 { "pix_fmt", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC, { .off = OFFSET(frame_pix_fmts) },
02384 "set pixel format", "format" },
02385 { "bits_per_raw_sample", OPT_VIDEO | OPT_INT | HAS_ARG, { &frame_bits_per_raw_sample },
02386 "set the number of bits per raw sample", "number" },
02387 { "croptop", OPT_VIDEO | HAS_ARG, { .func_arg = opt_frame_crop },
02388 "Removed, use the crop filter instead", "size" },
02389 { "cropbottom", OPT_VIDEO | HAS_ARG, { .func_arg = opt_frame_crop },
02390 "Removed, use the crop filter instead", "size" },
02391 { "cropleft", OPT_VIDEO | HAS_ARG, { .func_arg = opt_frame_crop },
02392 "Removed, use the crop filter instead", "size" },
02393 { "cropright", OPT_VIDEO | HAS_ARG, { .func_arg = opt_frame_crop },
02394 "Removed, use the crop filter instead", "size" },
02395 { "padtop", OPT_VIDEO | HAS_ARG, { .func_arg = opt_pad },
02396 "Removed, use the pad filter instead", "size" },
02397 { "padbottom", OPT_VIDEO | HAS_ARG, { .func_arg = opt_pad },
02398 "Removed, use the pad filter instead", "size" },
02399 { "padleft", OPT_VIDEO | HAS_ARG, { .func_arg = opt_pad },
02400 "Removed, use the pad filter instead", "size" },
02401 { "padright", OPT_VIDEO | HAS_ARG, { .func_arg = opt_pad },
02402 "Removed, use the pad filter instead", "size" },
02403 { "padcolor", OPT_VIDEO | HAS_ARG, { .func_arg = opt_pad },
02404 "Removed, use the pad filter instead", "color" },
02405 { "intra", OPT_VIDEO | OPT_BOOL | OPT_EXPERT, { &intra_only },
02406 "deprecated use -g 1" },
02407 { "vn", OPT_VIDEO | OPT_BOOL | OPT_OFFSET, { .off = OFFSET(video_disable) },
02408 "disable video" },
02409 { "vdt", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &video_discard },
02410 "discard threshold", "n" },
02411 { "rc_override", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC, { .off = OFFSET(rc_overrides) },
02412 "rate control override for specific intervals", "override" },
02413 { "vcodec", OPT_VIDEO | HAS_ARG | OPT_PERFILE, { .func_arg = opt_video_codec },
02414 "force video codec ('copy' to copy stream)", "codec" },
02415 { "sameq", OPT_VIDEO | OPT_EXPERT , { .func_arg = opt_sameq },
02416 "Removed" },
02417 { "same_quant", OPT_VIDEO | OPT_EXPERT , { .func_arg = opt_sameq },
02418 "Removed" },
02419 { "timecode", OPT_VIDEO | HAS_ARG | OPT_PERFILE, { .func_arg = opt_timecode },
02420 "set initial TimeCode value.", "hh:mm:ss[:;.]ff" },
02421 { "pass", OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT, { .off = OFFSET(pass) },
02422 "select the pass number (1 to 3)", "n" },
02423 { "passlogfile", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC, { .off = OFFSET(passlogfiles) },
02424 "select two pass log file name prefix", "prefix" },
02425 { "deinterlace", OPT_VIDEO | OPT_EXPERT , { .func_arg = opt_deinterlace },
02426 "this option is deprecated, use the yadif filter instead" },
02427 { "psnr", OPT_VIDEO | OPT_BOOL | OPT_EXPERT, { &do_psnr },
02428 "calculate PSNR of compressed frames" },
02429 { "vstats", OPT_VIDEO | OPT_EXPERT , { &opt_vstats },
02430 "dump video coding statistics to file" },
02431 { "vstats_file", OPT_VIDEO | HAS_ARG | OPT_EXPERT , { opt_vstats_file },
02432 "dump video coding statistics to file", "file" },
02433 { "vf", OPT_VIDEO | HAS_ARG | OPT_PERFILE, { .func_arg = opt_video_filters },
02434 "video filters", "filter list" },
02435 { "intra_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC, { .off = OFFSET(intra_matrices) },
02436 "specify intra matrix coeffs", "matrix" },
02437 { "inter_matrix", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_STRING | OPT_SPEC, { .off = OFFSET(inter_matrices) },
02438 "specify inter matrix coeffs", "matrix" },
02439 { "top", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_INT| OPT_SPEC, { .off = OFFSET(top_field_first) },
02440 "top=1/bottom=0/auto=-1 field first", "" },
02441 { "dc", OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT , { &intra_dc_precision },
02442 "intra_dc_precision", "precision" },
02443 { "vtag", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE, { .func_arg = opt_old2new },
02444 "force video tag/fourcc", "fourcc/tag" },
02445 { "qphist", OPT_VIDEO | OPT_BOOL | OPT_EXPERT , { &qp_hist },
02446 "show QP histogram" },
02447 { "force_fps", OPT_VIDEO | OPT_BOOL | OPT_EXPERT | OPT_SPEC, { .off = OFFSET(force_fps) },
02448 "force the selected framerate, disable the best supported framerate selection" },
02449 { "streamid", OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE, { .func_arg = opt_streamid },
02450 "set the value of an outfile streamid", "streamIndex:value" },
02451 { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_SPEC,
02452 { .off = OFFSET(forced_key_frames) },
02453 "force key frames at specified timestamps", "timestamps" },
02454 { "b", OPT_VIDEO | HAS_ARG | OPT_PERFILE, { .func_arg = opt_bitrate },
02455 "video bitrate (please use -b:v)", "bitrate" },
02456
02457
02458 { "aframes", OPT_AUDIO | HAS_ARG | OPT_PERFILE, { .func_arg = opt_audio_frames },
02459 "set the number of audio frames to record", "number" },
02460 { "aq", OPT_AUDIO | HAS_ARG | OPT_PERFILE, { .func_arg = opt_audio_qscale },
02461 "set audio quality (codec-specific)", "quality", },
02462 { "ar", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC, { .off = OFFSET(audio_sample_rate) },
02463 "set audio sampling rate (in Hz)", "rate" },
02464 { "ac", OPT_AUDIO | HAS_ARG | OPT_INT | OPT_SPEC, { .off = OFFSET(audio_channels) },
02465 "set number of audio channels", "channels" },
02466 { "an", OPT_AUDIO | OPT_BOOL | OPT_OFFSET, { .off = OFFSET(audio_disable) },
02467 "disable audio" },
02468 { "acodec", OPT_AUDIO | HAS_ARG | OPT_PERFILE, { .func_arg = opt_audio_codec },
02469 "force audio codec ('copy' to copy stream)", "codec" },
02470 { "atag", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE, { .func_arg = opt_old2new },
02471 "force audio tag/fourcc", "fourcc/tag" },
02472 { "vol", OPT_AUDIO | HAS_ARG | OPT_INT, { &audio_volume },
02473 "change audio volume (256=normal)" , "volume" },
02474 { "sample_fmt", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_SPEC | OPT_STRING, { .off = OFFSET(sample_fmts) },
02475 "set sample format", "format" },
02476 { "channel_layout", OPT_AUDIO | HAS_ARG | OPT_EXPERT | OPT_PERFILE, { .func_arg = opt_channel_layout },
02477 "set channel layout", "layout" },
02478 { "af", OPT_AUDIO | HAS_ARG | OPT_PERFILE, { .func_arg = opt_audio_filters },
02479 "audio filters", "filter list" },
02480
02481
02482 { "sn", OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET, { .off = OFFSET(subtitle_disable) },
02483 "disable subtitle" },
02484 { "scodec", OPT_SUBTITLE | HAS_ARG | OPT_PERFILE, { .func_arg = opt_subtitle_codec },
02485 "force subtitle codec ('copy' to copy stream)", "codec" },
02486 { "stag", OPT_SUBTITLE | HAS_ARG | OPT_EXPERT | OPT_PERFILE, { .func_arg = opt_old2new }
02487 , "force subtitle tag/fourcc", "fourcc/tag" },
02488 { "fix_sub_duration", OPT_BOOL | OPT_EXPERT | OPT_SUBTITLE | OPT_SPEC, { .off = OFFSET(fix_sub_duration) },
02489 "fix subtitles duration" },
02490
02491
02492 { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_video_channel },
02493 "deprecated, use -channel", "channel" },
02494 { "tvstd", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_video_standard },
02495 "deprecated, use -standard", "standard" },
02496 { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
02497
02498
02499 { "muxdelay", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(mux_max_delay) },
02500 "set the maximum demux-decode delay", "seconds" },
02501 { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(mux_preload) },
02502 "set the initial demux-decode delay", "seconds" },
02503
02504 { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT, { .off = OFFSET(bitstream_filters) },
02505 "A comma-separated list of bitstream filters", "bitstream_filters" },
02506 { "absf", HAS_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE, { .func_arg = opt_old2new },
02507 "deprecated", "audio bitstream_filters" },
02508 { "vbsf", OPT_VIDEO | HAS_ARG | OPT_EXPERT| OPT_PERFILE, { .func_arg = opt_old2new },
02509 "deprecated", "video bitstream_filters" },
02510
02511 { "apre", HAS_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE, { .func_arg = opt_preset },
02512 "set the audio options to the indicated preset", "preset" },
02513 { "vpre", OPT_VIDEO | HAS_ARG | OPT_EXPERT| OPT_PERFILE, { .func_arg = opt_preset },
02514 "set the video options to the indicated preset", "preset" },
02515 { "spre", HAS_ARG | OPT_SUBTITLE | OPT_EXPERT| OPT_PERFILE, { .func_arg = opt_preset },
02516 "set the subtitle options to the indicated preset", "preset" },
02517 { "fpre", HAS_ARG | OPT_EXPERT| OPT_PERFILE, { .func_arg = opt_preset },
02518 "set options from indicated preset file", "filename" },
02519
02520 { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT, { .func_arg = opt_data_codec },
02521 "force data codec ('copy' to copy stream)", "codec" },
02522 { "dn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET, { .off = OFFSET(data_disable) },
02523 "disable data" },
02524
02525 { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default },
02526 "generic catch all option", "" },
02527 { NULL, },
02528 };