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