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 };