OSDN Git Service

Windows MinGW環境ビルドエラー対応(Windows7 Mingw32 gcc4.5.2)
[coroid/ffmpeg_saccubus.git] / avconv.c
index 984c263..cfe187a 100644 (file)
--- a/avconv.c
+++ b/avconv.c
@@ -1,21 +1,21 @@
 /*
- * avconv main
- * Copyright (c) 2000-2011 The libav developers.
+ * ffmpeg main
+ * Copyright (c) 2000-2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/libm.h"
 #include "libavformat/os_support.h"
 
+#include "libavformat/ffm.h" // not public API
+
 #if CONFIG_AVFILTER
+# include "libavfilter/avcodec.h"
 # include "libavfilter/avfilter.h"
 # include "libavfilter/avfiltergraph.h"
+# include "libavfilter/buffersink.h"
 # include "libavfilter/vsrc_buffer.h"
+# include "libavfilter/avtool.h"
 #endif
 
 #if HAVE_SYS_RESOURCE_H
 #include <sys/select.h>
 #endif
 
+#if HAVE_TERMIOS_H
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <termios.h>
+#elif HAVE_KBHIT
+#include <conio.h>
+#endif
 #include <time.h>
 
 #include "cmdutils.h"
@@ -97,46 +110,26 @@ typedef struct MetadataMap {
 
 static const OptionDef options[];
 
-/* indexed by output file stream index */
-static int *streamid_map = NULL;
-static int nb_streamid_map = 0;
-
-static int frame_width  = 0;
-static int frame_height = 0;
-static float frame_aspect_ratio = 0;
-static enum PixelFormat frame_pix_fmt = PIX_FMT_NONE;
-static AVRational frame_rate;
-static float video_qscale = 0;
-static uint16_t *intra_matrix = NULL;
-static uint16_t *inter_matrix = NULL;
-static const char *video_rc_override_string=NULL;
+#define MAX_STREAMS 1024    /* arbitrary sanity check value */
+
+static int frame_bits_per_raw_sample = 0;
 static int video_discard = 0;
 static int same_quant = 0;
 static int do_deinterlace = 0;
-static int top_field_first = -1;
-static int me_threshold = 0;
 static int intra_dc_precision = 8;
 static int qp_hist = 0;
-#if CONFIG_AVFILTER
-static char *vfilters = NULL;
-#endif
-
-static int audio_sample_rate = 0;
-#define QSCALE_NONE -99999
-static float audio_qscale = QSCALE_NONE;
 
 static int file_overwrite = 0;
 static int do_benchmark = 0;
 static int do_hex_dump = 0;
 static int do_pkt_dump = 0;
-static int do_psnr = 0;
 static int do_pass = 0;
-static char *pass_logfilename_prefix = NULL;
+static const char *pass_logfilename_prefix;
 static int video_sync_method= -1;
 static int audio_sync_method= 0;
 static float audio_drift_threshold= 0.1;
 static int copy_ts= 0;
-static int copy_tb;
+static int copy_tb= 0;
 static int opt_shortest = 0;
 static char *vstats_filename;
 static FILE *vstats_file;
@@ -147,14 +140,14 @@ static int audio_volume = 256;
 static int exit_on_error = 0;
 static int using_stdin = 0;
 static int verbose = 1;
+static int run_as_daemon  = 0;
+static int q_pressed = 0;
 static int64_t video_size = 0;
 static int64_t audio_size = 0;
 static int64_t extra_size = 0;
 static int nb_frames_dup = 0;
 static int nb_frames_drop = 0;
 static int input_sync;
-static int force_fps = 0;
-static char *forced_key_frames = NULL;
 
 static float dts_delta_threshold = 10;
 
@@ -177,7 +170,6 @@ typedef struct InputStream {
     int64_t       next_pts;  /* synthetic pts for cases where pkt.pts
                                 is not defined */
     int64_t       pts;       /* current pts */
-    PtsCorrectionContext pts_ctx;
     double ts_scale;
     int is_start;            /* is 1 at the start and after a discontinuity */
     int showed_multi_packet_warning;
@@ -213,12 +205,14 @@ typedef struct OutputStream {
 
     /* video only */
     int video_resample;
-    AVFrame pict_tmp;      /* temporary image for resampling */
+    AVFrame resample_frame;              /* temporary frame for image resampling */
     struct SwsContext *img_resample_ctx; /* for image resampling */
     int resample_height;
     int resample_width;
     int resample_pix_fmt;
     AVRational frame_rate;
+    int force_fps;
+    int top_field_first;
 
     float frame_aspect_ratio;
 
@@ -251,6 +245,11 @@ typedef struct OutputStream {
    int is_past_recording_time;
 } OutputStream;
 
+#if HAVE_TERMIOS_H
+
+/* init terminal so that we can grab keys */
+static struct termios oldtty;
+#endif
 
 typedef struct OutputFile {
     AVFormatContext *ctx;
@@ -280,6 +279,14 @@ typedef struct OptionsContext {
     int        nb_codec_names;
     SpecifierOpt *audio_channels;
     int        nb_audio_channels;
+    SpecifierOpt *audio_sample_rate;
+    int        nb_audio_sample_rate;
+    SpecifierOpt *frame_rates;
+    int        nb_frame_rates;
+    SpecifierOpt *frame_sizes;
+    int        nb_frame_sizes;
+    SpecifierOpt *frame_pix_fmts;
+    int        nb_frame_pix_fmts;
 
     /* input options */
     int64_t input_ts_offset;
@@ -310,6 +317,10 @@ typedef struct OptionsContext {
     int subtitle_disable;
     int data_disable;
 
+    /* indexed by output file stream index */
+    int   *streamid_map;
+    int nb_streamid_map;
+
     SpecifierOpt *metadata;
     int        nb_metadata;
     SpecifierOpt *max_frames;
@@ -320,6 +331,26 @@ typedef struct OptionsContext {
     int        nb_codec_tags;
     SpecifierOpt *sample_fmts;
     int        nb_sample_fmts;
+    SpecifierOpt *qscale;
+    int        nb_qscale;
+    SpecifierOpt *forced_key_frames;
+    int        nb_forced_key_frames;
+    SpecifierOpt *force_fps;
+    int        nb_force_fps;
+    SpecifierOpt *frame_aspect_ratios;
+    int        nb_frame_aspect_ratios;
+    SpecifierOpt *rc_overrides;
+    int        nb_rc_overrides;
+    SpecifierOpt *intra_matrices;
+    int        nb_intra_matrices;
+    SpecifierOpt *inter_matrices;
+    int        nb_inter_matrices;
+    SpecifierOpt *top_field_first;
+    int        nb_top_field_first;
+#if CONFIG_AVFILTER
+    SpecifierOpt *filters;
+    int        nb_filters;
+#endif
 } OptionsContext;
 
 #define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
@@ -359,6 +390,7 @@ static void reset_options(OptionsContext *o)
 
     av_freep(&o->stream_maps);
     av_freep(&o->meta_data_maps);
+    av_freep(&o->streamid_map);
 
     memset(o, 0, sizeof(*o));
 
@@ -380,7 +412,8 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
     /** filter graph containing all filters including input & output */
     AVCodecContext *codec = ost->st->codec;
     AVCodecContext *icodec = ist->st->codec;
-    FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt };
+    enum PixelFormat pix_fmts[] = { codec->pix_fmt, PIX_FMT_NONE };
+    AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();
     AVRational sample_aspect_ratio;
     char args[255];
     int ret;
@@ -400,8 +433,15 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
                                        "src", args, NULL, ost->graph);
     if (ret < 0)
         return ret;
-    ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink,
-                                       "out", NULL, &ffsink_ctx, ost->graph);
+#if FF_API_OLD_VSINK_API
+    ret = avfilter_graph_create_filter(&ost->output_video_filter, avfilter_get_by_name("buffersink"),
+                                       "out", NULL, pix_fmts, ost->graph);
+#else
+    buffersink_params->pixel_fmts = pix_fmts;
+    ret = avfilter_graph_create_filter(&ost->output_video_filter, avfilter_get_by_name("buffersink"),
+                                       "out", NULL, buffersink_params, ost->graph);
+#endif
+    av_freep(&buffersink_params);
     if (ret < 0)
         return ret;
     last_filter = ost->input_video_filter;
@@ -423,8 +463,8 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
     ost->graph->scale_sws_opts = av_strdup(args);
 
     if (ost->avfilter) {
-        AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
-        AVFilterInOut *inputs  = av_malloc(sizeof(AVFilterInOut));
+        AVFilterInOut *outputs = avfilter_inout_alloc();
+        AVFilterInOut *inputs  = avfilter_inout_alloc();
 
         outputs->name    = av_strdup("in");
         outputs->filter_ctx = last_filter;
@@ -436,7 +476,7 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
         inputs->pad_idx = 0;
         inputs->next    = NULL;
 
-        if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, inputs, outputs, NULL)) < 0)
+        if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, &inputs, &outputs, NULL)) < 0)
             return ret;
         av_freep(&ost->avfilter);
     } else {
@@ -460,22 +500,47 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
 
 static void term_exit(void)
 {
-    av_log(NULL, AV_LOG_QUIET, "");
+    av_log(NULL, AV_LOG_QUIET, "%s", "");
+#if HAVE_TERMIOS_H
+    if(!run_as_daemon)
+        tcsetattr (0, TCSANOW, &oldtty);
+#endif
 }
 
 static volatile int received_sigterm = 0;
-static volatile int received_nb_signals = 0;
 
 static void
 sigterm_handler(int sig)
 {
     received_sigterm = sig;
-    received_nb_signals++;
+    q_pressed++;
     term_exit();
 }
 
 static void term_init(void)
 {
+#if HAVE_TERMIOS_H
+    if(!run_as_daemon){
+    struct termios tty;
+
+    tcgetattr (0, &tty);
+    oldtty = tty;
+    atexit(term_exit);
+
+    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+                          |INLCR|IGNCR|ICRNL|IXON);
+    tty.c_oflag |= OPOST;
+    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
+    tty.c_cflag &= ~(CSIZE|PARENB);
+    tty.c_cflag |= CS8;
+    tty.c_cc[VMIN] = 1;
+    tty.c_cc[VTIME] = 0;
+
+    tcsetattr (0, TCSANOW, &tty);
+    signal(SIGQUIT, sigterm_handler); /* Quit (POSIX).  */
+    }
+#endif
+
     signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).  */
     signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
 #ifdef SIGXCPU
@@ -483,9 +548,41 @@ static void term_init(void)
 #endif
 }
 
+/* read a key without blocking */
+static int read_key(void)
+{
+#if HAVE_TERMIOS_H
+    int n = 1;
+    unsigned char ch;
+    struct timeval tv;
+    fd_set rfds;
+
+    if(run_as_daemon)
+        return -1;
+
+    FD_ZERO(&rfds);
+    FD_SET(0, &rfds);
+    tv.tv_sec = 0;
+    tv.tv_usec = 0;
+    n = select(1, &rfds, NULL, NULL, &tv);
+    if (n > 0) {
+        n = read(0, &ch, 1);
+        if (n == 1)
+            return ch;
+
+        return n;
+    }
+#elif HAVE_KBHIT
+    if(kbhit())
+        return(getch());
+#endif
+    return -1;
+}
+
 static int decode_interrupt_cb(void)
 {
-    return received_nb_signals > 1;
+    q_pressed += read_key() == 'q';
+    return q_pressed > 1;
 }
 
 void exit_program(int ret)
@@ -506,9 +603,6 @@ void exit_program(int ret)
     for (i = 0; i < nb_input_streams; i++)
         av_dict_free(&input_streams[i].opts);
 
-    av_free(intra_matrix);
-    av_free(inter_matrix);
-
     if (vstats_file)
         fclose(vstats_file);
     av_free(vstats_filename);
@@ -573,6 +667,9 @@ static void choose_sample_fmt(AVStream *st, AVCodec *codec)
                 break;
         }
         if (*p == -1) {
+            if((codec->capabilities & CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0]))
+                av_log(NULL, AV_LOG_ERROR, "Convertion will not be lossless'\n");
+            if(av_get_sample_fmt_name(st->codec->sample_fmt))
             av_log(NULL, AV_LOG_WARNING,
                    "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
                    av_get_sample_fmt_name(st->codec->sample_fmt),
@@ -583,46 +680,6 @@ static void choose_sample_fmt(AVStream *st, AVCodec *codec)
     }
 }
 
-/**
- * Update the requested input sample format based on the output sample format.
- * This is currently only used to request float output from decoders which
- * support multiple sample formats, one of which is AV_SAMPLE_FMT_FLT.
- * Ideally this will be removed in the future when decoders do not do format
- * conversion and only output in their native format.
- */
-static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec,
-                              AVCodecContext *enc)
-{
-    /* if sample formats match or a decoder sample format has already been
-       requested, just return */
-    if (enc->sample_fmt == dec->sample_fmt ||
-        dec->request_sample_fmt > AV_SAMPLE_FMT_NONE)
-        return;
-
-    /* if decoder supports more than one output format */
-    if (dec_codec && dec_codec->sample_fmts &&
-        dec_codec->sample_fmts[0] != AV_SAMPLE_FMT_NONE &&
-        dec_codec->sample_fmts[1] != AV_SAMPLE_FMT_NONE) {
-        const enum AVSampleFormat *p;
-        int min_dec = -1, min_inc = -1;
-
-        /* find a matching sample format in the encoder */
-        for (p = dec_codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) {
-            if (*p == enc->sample_fmt) {
-                dec->request_sample_fmt = *p;
-                return;
-            } else if (*p > enc->sample_fmt) {
-                min_inc = FFMIN(min_inc, *p - enc->sample_fmt);
-            } else
-                min_dec = FFMIN(min_dec, enc->sample_fmt - *p);
-        }
-
-        /* if none match, provide the one that matches quality closest */
-        dec->request_sample_fmt = min_inc > 0 ? enc->sample_fmt + min_inc :
-                                  enc->sample_fmt - min_dec;
-    }
-}
-
 static void choose_sample_rate(AVStream *st, AVCodec *codec)
 {
     if(codec && codec->supported_samplerates){
@@ -750,7 +807,7 @@ need_realloc:
         exit_program(1);
     }
 
-    if (enc->channels != dec->channels || enc->sample_rate != dec->sample_rate)
+    if (enc->channels != dec->channels)
         ost->audio_resample = 1;
 
     resample_changed = ost->resample_sample_fmt  != dec->sample_fmt ||
@@ -776,7 +833,7 @@ need_realloc:
             ost->resample_sample_rate == enc->sample_rate) {
             ost->resample = NULL;
             ost->audio_resample = 0;
-        } else if (ost->audio_resample) {
+        } else {
             if (dec->sample_fmt != AV_SAMPLE_FMT_S16)
                 fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n");
             ost->resample = av_audio_resample_init(enc->channels,    dec->channels,
@@ -1066,36 +1123,46 @@ static void do_video_resample(OutputStream *ost,
 {
     int resample_changed = 0;
     AVCodecContext *dec = ist->st->codec;
+    AVCodecContext *enc = ost->st->codec;
     *out_picture = in_picture;
 
     resample_changed = ost->resample_width   != dec->width  ||
                        ost->resample_height  != dec->height ||
                        ost->resample_pix_fmt != dec->pix_fmt;
 
+#if !CONFIG_AVFILTER
     if (resample_changed) {
         av_log(NULL, AV_LOG_INFO,
                "Input stream #%d.%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
                ist->file_index, ist->st->index,
                ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt),
                dec->width         , dec->height         , av_get_pix_fmt_name(dec->pix_fmt));
-        if(!ost->video_resample)
-            ost->video_resample = 1;
+        ost->resample_width   = dec->width;
+        ost->resample_height  = dec->height;
+        ost->resample_pix_fmt = dec->pix_fmt;
     }
 
-#if !CONFIG_AVFILTER
+    ost->video_resample = dec->width   != enc->width  ||
+                          dec->height  != enc->height ||
+                          dec->pix_fmt != enc->pix_fmt;
+
     if (ost->video_resample) {
-        *out_picture = &ost->pict_tmp;
-        if (resample_changed) {
+        *out_picture = &ost->resample_frame;
+        if (!ost->img_resample_ctx || resample_changed) {
+            /* initialize the destination picture */
+            if (!ost->resample_frame.data[0]) {
+                avcodec_get_frame_defaults(&ost->resample_frame);
+                if (avpicture_alloc((AVPicture *)&ost->resample_frame, enc->pix_fmt,
+                                    enc->width, enc->height)) {
+                    fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n");
+                    exit_program(1);
+                }
+            }
             /* initialize a new scaler context */
             sws_freeContext(ost->img_resample_ctx);
-            ost->img_resample_ctx = sws_getContext(
-                ist->st->codec->width,
-                ist->st->codec->height,
-                ist->st->codec->pix_fmt,
-                ost->st->codec->width,
-                ost->st->codec->height,
-                ost->st->codec->pix_fmt,
-                ost->sws_flags, NULL, NULL, NULL);
+            ost->img_resample_ctx = sws_getContext(dec->width, dec->height, dec->pix_fmt,
+                                                   enc->width, enc->height, enc->pix_fmt,
+                                                   ost->sws_flags, NULL, NULL, NULL);
             if (ost->img_resample_ctx == NULL) {
                 fprintf(stderr, "Cannot get resampling context\n");
                 exit_program(1);
@@ -1202,16 +1269,16 @@ static void do_video_out(AVFormatContext *s,
                settings */
             big_picture.interlaced_frame = in_picture->interlaced_frame;
             if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) {
-                if(top_field_first == -1)
+                if (ost->top_field_first == -1)
                     big_picture.top_field_first = in_picture->top_field_first;
                 else
-                    big_picture.top_field_first = top_field_first;
+                    big_picture.top_field_first = !!ost->top_field_first;
             }
 
             /* handles same_quant here. This is not correct because it may
                not be a global option */
             big_picture.quality = quality;
-            if(!me_threshold)
+            if (!enc->me_threshold)
                 big_picture.pict_type = 0;
 //            big_picture.pts = AV_NOPTS_VALUE;
             big_picture.pts= ost->sync_opts;
@@ -1308,7 +1375,8 @@ static void print_report(OutputFile *output_files,
     int64_t total_size;
     AVCodecContext *enc;
     int frame_number, vid, i;
-    double bitrate, ti1, pts;
+    double bitrate;
+    int64_t pts = INT64_MAX;
     static int64_t last_time = -1;
     static int qp_histogram[52];
 
@@ -1333,7 +1401,6 @@ static void print_report(OutputFile *output_files,
         total_size= avio_tell(oc->pb);
 
     buf[0] = '\0';
-    ti1 = 1e10;
     vid = 0;
     for(i=0;i<nb_ostreams;i++) {
         float q = -1;
@@ -1384,19 +1451,28 @@ static void print_report(OutputFile *output_files,
             vid = 1;
         }
         /* compute min output value */
-        pts = (double)ost->st->pts.val * av_q2d(ost->st->time_base);
-        if ((pts < ti1) && (pts > 0))
-            ti1 = pts;
+        pts = FFMIN(pts, av_rescale_q(ost->st->pts.val,
+                                      ost->st->time_base, AV_TIME_BASE_Q));
     }
-    if (ti1 < 0.01)
-        ti1 = 0.01;
 
     if (verbose > 0 || is_last_report) {
-        bitrate = (double)(total_size * 8) / ti1 / 1000.0;
+        int hours, mins, secs, us;
+        secs = pts / AV_TIME_BASE;
+        us = pts % AV_TIME_BASE;
+        mins = secs / 60;
+        secs %= 60;
+        hours = mins / 60;
+        mins %= 60;
 
+        bitrate = pts ? total_size * 8 / (pts / 1000.0) : 0;
+
+        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                 "size=%8.0fkB time=", total_size / 1024.0);
         snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-            "size=%8.0fkB time=%0.2f bitrate=%6.1fkbits/s",
-            (double)total_size / 1024, ti1, bitrate);
+                 "%02d:%02d:%02d.%02d ", hours, mins, secs,
+                 (100 * us) / AV_TIME_BASE);
+        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                 "bitrate=%6.1fkbits/s", bitrate);
 
         if (nb_frames_dup || nb_frames_drop)
           snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
@@ -1618,7 +1694,7 @@ static int output_packet(InputStream *ist, int ist_index,
                         /* no picture yet */
                         goto discard_packet;
                     }
-                    ist->next_pts = ist->pts = guess_correct_pts(&ist->pts_ctx, picture.pkt_pts, picture.pkt_dts);
+                    ist->next_pts = ist->pts = picture.best_effort_timestamp;
                     if (ist->st->codec->time_base.num != 0) {
                         int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame;
                         ist->next_pts += ((int64_t)AV_TIME_BASE *
@@ -1703,21 +1779,24 @@ static int output_packet(InputStream *ist, int ist_index,
 #if CONFIG_AVFILTER
             if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
                 ost->input_video_filter) {
-                AVRational sar;
-                if (ist->st->sample_aspect_ratio.num)
-                    sar = ist->st->sample_aspect_ratio;
-                else
-                    sar = ist->st->codec->sample_aspect_ratio;
-                av_vsrc_buffer_add_frame(ost->input_video_filter, &picture, ist->pts, sar);
+                if (!picture.sample_aspect_ratio.num)
+                    picture.sample_aspect_ratio = ist->st->sample_aspect_ratio;
+                picture.pts = ist->pts;
+
+                av_vsrc_buffer_add_frame(ost->input_video_filter, &picture, AV_VSRC_BUF_FLAG_OVERWRITE);
             }
             frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
                 !ost->output_video_filter || avfilter_poll_frame(ost->output_video_filter->inputs[0]);
             while (frame_available) {
-                AVRational ist_pts_tb;
-                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter)
-                    get_filtered_video_frame(ost->output_video_filter, &picture, &ost->picref, &ist_pts_tb);
-                if (ost->picref)
-                    ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
+                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter) {
+                    AVRational ist_pts_tb = ost->output_video_filter->inputs[0]->time_base;
+                    if (av_buffersink_get_buffer_ref(ost->output_video_filter, &ost->picref, 0) < 0)
+                        goto cont;
+                    if (ost->picref) {
+                        avfilter_fill_frame_from_video_buffer_ref(&picture, ost->picref);
+                        ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
+                    }
+                }
 #endif
                 os = output_files[ost->file_index].ctx;
 
@@ -1733,10 +1812,10 @@ static int output_packet(InputStream *ist, int ist_index,
                     case AVMEDIA_TYPE_VIDEO:
 #if CONFIG_AVFILTER
                         if (ost->picref->video && !ost->frame_aspect_ratio)
-                            ost->st->codec->sample_aspect_ratio = ost->picref->video->pixel_aspect;
+                            ost->st->codec->sample_aspect_ratio = ost->picref->video->sample_aspect_ratio;
 #endif
                         do_video_out(os, ost, ist, &picture, &frame_size,
-                                     same_quant ? quality : ost->st->codec->global_quality);
+                                        same_quant ? quality : ost->st->codec->global_quality);
                         if (vstats_filename && frame_size)
                             do_video_stats(os, ost, frame_size);
                         break;
@@ -1749,9 +1828,9 @@ static int output_packet(InputStream *ist, int ist_index,
                     }
                 } else {
                     AVFrame avframe; //FIXME/XXX remove this
+                    AVPicture pict;
                     AVPacket opkt;
                     int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
-
                     av_init_packet(&opkt);
 
                     if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes)
@@ -1802,6 +1881,13 @@ static int output_packet(InputStream *ist, int ist_index,
                         opkt.size = data_size;
                     }
 
+                    if (os->oformat->flags & AVFMT_RAWPICTURE) {
+                        /* store AVPicture in AVPacket, as expected by the output format */
+                        avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height);
+                        opkt.data = (uint8_t *)&pict;
+                        opkt.size = sizeof(AVPicture);
+                        opkt.flags |= AV_PKT_FLAG_KEY;
+                    }
                     write_frame(os, &opkt, ost->st->codec, ost->bitstream_filters);
                     ost->st->codec->frame_number++;
                     ost->frame_number++;
@@ -1859,16 +1945,6 @@ static int init_input_stream(int ist_index, OutputStream *output_streams, int nb
             return AVERROR(EINVAL);
         }
 
-        /* update requested sample format for the decoder based on the
-           corresponding encoder sample format */
-        for (i = 0; i < nb_output_streams; i++) {
-            OutputStream *ost = &output_streams[i];
-            if (ost->source_index == ist_index) {
-                update_sample_fmt(ist->st->codec, codec, ost->st->codec);
-                break;
-            }
-        }
-
         if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) {
             snprintf(error, error_len, "Error while opening decoder for input stream #%d.%d",
                     ist->file_index, ist->st->index);
@@ -1880,7 +1956,6 @@ static int init_input_stream(int ist_index, OutputStream *output_streams, int nb
 
     ist->pts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames*AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0;
     ist->next_pts = AV_NOPTS_VALUE;
-    init_pts_correction(&ist->pts_ctx);
     ist->is_start = 1;
 
     return 0;
@@ -1957,13 +2032,23 @@ static int transcode_init(OutputFile *output_files,
             }
             memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);
             codec->extradata_size= icodec->extradata_size;
-            if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){
-                codec->time_base = icodec->time_base;
-                codec->time_base.num *= icodec->ticks_per_frame;
-                av_reduce(&codec->time_base.num, &codec->time_base.den,
-                          codec->time_base.num, codec->time_base.den, INT_MAX);
-            }else
-                codec->time_base = ist->st->time_base;
+
+            codec->time_base = ist->st->time_base;
+            if(!strcmp(os->oformat->name, "avi")) {
+                if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > 2*av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){
+                    codec->time_base = icodec->time_base;
+                    codec->time_base.num *= icodec->ticks_per_frame;
+                    codec->time_base.den *= 2;
+                }
+            } else if(!(os->oformat->flags & AVFMT_VARIABLE_FPS)) {
+                if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){
+                    codec->time_base = icodec->time_base;
+                    codec->time_base.num *= icodec->ticks_per_frame;
+                }
+            }
+            av_reduce(&codec->time_base.num, &codec->time_base.den,
+                        codec->time_base.num, codec->time_base.den, INT_MAX);
+
             switch(codec->codec_type) {
             case AVMEDIA_TYPE_AUDIO:
                 if(audio_volume != 256) {
@@ -2015,17 +2100,16 @@ static int transcode_init(OutputFile *output_files,
                 ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE);
                 if (!codec->sample_rate) {
                     codec->sample_rate = icodec->sample_rate;
-                    if (icodec->lowres)
-                        codec->sample_rate >>= icodec->lowres;
                 }
                 choose_sample_rate(ost->st, ost->enc);
                 codec->time_base = (AVRational){1, codec->sample_rate};
                 if (codec->sample_fmt == AV_SAMPLE_FMT_NONE)
                     codec->sample_fmt = icodec->sample_fmt;
                 choose_sample_fmt(ost->st, ost->enc);
-                if (!codec->channels)
+                if (!codec->channels) {
                     codec->channels = icodec->channels;
-                codec->channel_layout = icodec->channel_layout;
+                    codec->channel_layout = icodec->channel_layout;
+                }
                 if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)
                     codec->channel_layout = 0;
                 ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;
@@ -2055,27 +2139,7 @@ static int transcode_init(OutputFile *output_files,
                                       codec->height  != icodec->height ||
                                       codec->pix_fmt != icodec->pix_fmt;
                 if (ost->video_resample) {
-#if !CONFIG_AVFILTER
-                    avcodec_get_frame_defaults(&ost->pict_tmp);
-                    if(avpicture_alloc((AVPicture*)&ost->pict_tmp, codec->pix_fmt,
-                                       codec->width, codec->height)) {
-                        fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n");
-                        exit_program(1);
-                    }
-                    ost->img_resample_ctx = sws_getContext(
-                        icodec->width,
-                        icodec->height,
-                        icodec->pix_fmt,
-                        codec->width,
-                        codec->height,
-                        codec->pix_fmt,
-                        ost->sws_flags, NULL, NULL, NULL);
-                    if (ost->img_resample_ctx == NULL) {
-                        fprintf(stderr, "Cannot get resampling context\n");
-                        exit_program(1);
-                    }
-#endif
-                    codec->bits_per_raw_sample= 0;
+                    codec->bits_per_raw_sample= frame_bits_per_raw_sample;
                 }
 
                 ost->resample_height = icodec->height;
@@ -2086,13 +2150,19 @@ static int transcode_init(OutputFile *output_files,
 
                 if (!ost->frame_rate.num)
                     ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25,1};
-                if (ost->enc && ost->enc->supported_framerates && !force_fps) {
+                if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) {
                     int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
                     ost->frame_rate = ost->enc->supported_framerates[idx];
                 }
                 codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num};
+                if(   av_q2d(codec->time_base) < 0.001 && video_sync_method
+                   && (video_sync_method==1 || (video_sync_method<0 && !(os->oformat->flags & AVFMT_VARIABLE_FPS)))){
+                    av_log(os, AV_LOG_WARNING, "Frame rate very high for a muxer not effciciently supporting it.\n"
+                                               "Please consider specifiying a lower framerate, a different muxer or -vsync 2\n");
+                }
 
 #if CONFIG_AVFILTER
+                tool_registerInfo(input_files[nb_input_files - 1].ctx->duration, output_files[nb_output_files - 1].recording_time);
                 if (configure_video_filters(ist, ost)) {
                     fprintf(stderr, "Error opening filters!\n");
                     exit(1);
@@ -2108,7 +2178,7 @@ static int transcode_init(OutputFile *output_files,
                 break;
             }
             /* two pass mode */
-            if (ost->encoding_needed &&
+            if (ost->encoding_needed && codec->codec_id != CODEC_ID_H264 &&
                 (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
                 char logfilename[1024];
                 FILE *f;
@@ -2135,8 +2205,9 @@ static int transcode_init(OutputFile *output_files,
             }
         }
         if(codec->codec_type == AVMEDIA_TYPE_VIDEO){
+            /* maximum video buffer size is 6-bytes per pixel, plus DPX header size */
             int size= codec->width * codec->height;
-            bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 200);
+            bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 1664);
         }
     }
 
@@ -2181,6 +2252,9 @@ static int transcode_init(OutputFile *output_files,
                 av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
                                              "It takes bits/s as argument, not kbits/s\n");
             extra_size += ost->st->codec->extradata_size;
+
+            if (ost->st->codec->me_threshold)
+                input_streams[ost->source_index].st->codec->debug |= FF_DEBUG_MV;
         }
     }
 
@@ -2213,7 +2287,7 @@ static int transcode_init(OutputFile *output_files,
             ret = AVERROR(EINVAL);
             goto dump_format;
         }
-        assert_avoptions(output_files[i].opts);
+//        assert_avoptions(output_files[i].opts);
         if (strcmp(os->oformat->name, "rtp")) {
             want_sdp = 0;
         }
@@ -2277,6 +2351,7 @@ static int transcode(OutputFile *output_files,
     uint8_t *no_packet;
     int no_packet_count=0;
     int64_t timer_start;
+    int key;
 
     if (!(no_packet = av_mallocz(nb_input_files)))
         exit_program(1);
@@ -2285,8 +2360,11 @@ static int transcode(OutputFile *output_files,
     if (ret < 0)
         goto fail;
 
-    if (verbose >= 0)
-        fprintf(stderr, "Press ctrl-c to stop encoding\n");
+    if (!using_stdin) {
+        if(verbose >= 0)
+            fprintf(stderr, "Press [q] to stop, [?] for help\n");
+        avio_set_interrupt_cb(decode_interrupt_cb);
+    }
     term_init();
 
     timer_start = av_gettime();
@@ -2299,6 +2377,57 @@ static int transcode(OutputFile *output_files,
 
         ipts_min = INT64_MAX;
         opts_min= 1e100;
+        /* if 'q' pressed, exits */
+        if (!using_stdin) {
+            if (q_pressed)
+                break;
+            /* read_key() returns 0 on EOF */
+            key = read_key();
+            if (key == 'q')
+                break;
+            if (key == '+') verbose++;
+            if (key == '-') verbose--;
+            if (key == 's') qp_hist     ^= 1;
+            if (key == 'h'){
+                if (do_hex_dump){
+                    do_hex_dump = do_pkt_dump = 0;
+                } else if(do_pkt_dump){
+                    do_hex_dump = 1;
+                } else
+                    do_pkt_dump = 1;
+                av_log_set_level(AV_LOG_DEBUG);
+            }
+            if (key == 'd' || key == 'D'){
+                int debug=0;
+                if(key == 'D') {
+                    debug = input_streams[0].st->codec->debug<<1;
+                    if(!debug) debug = 1;
+                    while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash
+                        debug += debug;
+                }else
+                    scanf("%d", &debug);
+                for(i=0;i<nb_input_streams;i++) {
+                    input_streams[i].st->codec->debug = debug;
+                }
+                for(i=0;i<nb_output_streams;i++) {
+                    ost = &output_streams[i];
+                    ost->st->codec->debug = debug;
+                }
+                if(debug) av_log_set_level(AV_LOG_DEBUG);
+                fprintf(stderr,"debug=%d\n", debug);
+            }
+            if (key == '?'){
+                fprintf(stderr, "key    function\n"
+                                "?      show this help\n"
+                                "+      increase verbosity\n"
+                                "-      decrease verbosity\n"
+                                "D      cycle through available debug modes\n"
+                                "h      dump packets/hex press to cycle through the 3 states\n"
+                                "q      quit\n"
+                                "s      Show QP histogram\n"
+                );
+            }
+        }
 
         /* select the stream that we must read now by looking at the
            smallest output pts */
@@ -2481,7 +2610,7 @@ static int transcode(OutputFile *output_files,
                 av_fifo_free(ost->fifo); /* works even if fifo is not
                                              initialized but set to zero */
                 av_freep(&ost->st->codec->subtitle_header);
-                av_free(ost->pict_tmp.data[0]);
+                av_free(ost->resample_frame.data[0]);
                 av_free(ost->forced_kf_pts);
                 if (ost->video_resample)
                     sws_freeContext(ost->img_resample_ctx);
@@ -2496,58 +2625,13 @@ static int transcode(OutputFile *output_files,
     return ret;
 }
 
-static int opt_video_rc_override_string(const char *opt, const char *arg)
-{
-    video_rc_override_string = arg;
-    return 0;
-}
-
-static int opt_me_threshold(const char *opt, const char *arg)
-{
-    me_threshold = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
-    return 0;
-}
-
 static int opt_verbose(const char *opt, const char *arg)
 {
     verbose = parse_number_or_die(opt, arg, OPT_INT64, -10, 10);
     return 0;
 }
 
-static int opt_frame_rate(const char *opt, const char *arg)
-{
-    if (av_parse_video_rate(&frame_rate, arg) < 0) {
-        fprintf(stderr, "Incorrect value for %s: %s\n", opt, arg);
-        exit_program(1);
-    }
-    return 0;
-}
-
-static int opt_frame_size(const char *opt, const char *arg)
-{
-    if (av_parse_video_size(&frame_width, &frame_height, arg) < 0) {
-        fprintf(stderr, "Incorrect frame size\n");
-        return AVERROR(EINVAL);
-    }
-    return 0;
-}
-
-static int opt_frame_pix_fmt(const char *opt, const char *arg)
-{
-    if (strcmp(arg, "list")) {
-        frame_pix_fmt = av_get_pix_fmt(arg);
-        if (frame_pix_fmt == PIX_FMT_NONE) {
-            fprintf(stderr, "Unknown pixel format requested: %s\n", arg);
-            return AVERROR(EINVAL);
-        }
-    } else {
-        show_pix_fmts();
-        exit_program(0);
-    }
-    return 0;
-}
-
-static int opt_frame_aspect_ratio(const char *opt, const char *arg)
+static double parse_frame_aspect_ratio(const char *arg)
 {
     int x = 0, y = 0;
     double ar = 0;
@@ -2566,32 +2650,9 @@ static int opt_frame_aspect_ratio(const char *opt, const char *arg)
 
     if (!ar) {
         fprintf(stderr, "Incorrect aspect ratio specification.\n");
-        return AVERROR(EINVAL);
-    }
-    frame_aspect_ratio = ar;
-    return 0;
-}
-
-static int opt_qscale(const char *opt, const char *arg)
-{
-    video_qscale = parse_number_or_die(opt, arg, OPT_FLOAT, 0, 255);
-    if (video_qscale == 0) {
-        fprintf(stderr, "qscale must be > 0.0 and <= 255\n");
-        return AVERROR(EINVAL);
+        exit_program(1);
     }
-    return 0;
-}
-
-static int opt_top_field_first(const char *opt, const char *arg)
-{
-    top_field_first = parse_number_or_die(opt, arg, OPT_INT, 0, 1);
-    return 0;
-}
-
-static int opt_audio_rate(const char *opt, const char *arg)
-{
-    audio_sample_rate = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
-    return 0;
+    return ar;
 }
 
 static int opt_audio_codec(OptionsContext *o, const char *opt, const char *arg)
@@ -2818,19 +2879,19 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
 
         switch (dec->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
-            if (o->audio_disable)
+            if(!ist->dec)
+                ist->dec = avcodec_find_decoder(dec->codec_id);
+            if(o->audio_disable)
                 st->discard= AVDISCARD_ALL;
             break;
         case AVMEDIA_TYPE_VIDEO:
+            if(!ist->dec)
+                ist->dec = avcodec_find_decoder(dec->codec_id);
             rfps      = ic->streams[i]->r_frame_rate.num;
             rfps_base = ic->streams[i]->r_frame_rate.den;
             if (dec->lowres) {
                 dec->flags |= CODEC_FLAG_EMU_EDGE;
-                dec->height >>= dec->lowres;
-                dec->width  >>= dec->lowres;
             }
-            if(me_threshold)
-                dec->debug |= FF_DEBUG_MV;
 
             if (dec->time_base.den != rfps*dec->ticks_per_frame || dec->time_base.num != rfps_base) {
 
@@ -2849,7 +2910,9 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
         case AVMEDIA_TYPE_DATA:
             break;
         case AVMEDIA_TYPE_SUBTITLE:
-            if (o->subtitle_disable)
+            if(!ist->dec)
+                ist->dec = avcodec_find_decoder(dec->codec_id);
+            if(o->subtitle_disable)
                 st->discard = AVDISCARD_ALL;
             break;
         case AVMEDIA_TYPE_ATTACHMENT:
@@ -2890,24 +2953,22 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena
         print_error(filename, AVERROR(ENOMEM));
         exit_program(1);
     }
-    if (audio_sample_rate) {
-        snprintf(buf, sizeof(buf), "%d", audio_sample_rate);
+    if (o->nb_audio_sample_rate) {
+        snprintf(buf, sizeof(buf), "%d", o->audio_sample_rate[o->nb_audio_sample_rate - 1].u.i);
         av_dict_set(&format_opts, "sample_rate", buf, 0);
     }
     if (o->nb_audio_channels) {
         snprintf(buf, sizeof(buf), "%d", o->audio_channels[o->nb_audio_channels - 1].u.i);
         av_dict_set(&format_opts, "channels", buf, 0);
     }
-    if (frame_rate.num) {
-        snprintf(buf, sizeof(buf), "%d/%d", frame_rate.num, frame_rate.den);
-        av_dict_set(&format_opts, "framerate", buf, 0);
+    if (o->nb_frame_rates) {
+        av_dict_set(&format_opts, "framerate", o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
     }
-    if (frame_width && frame_height) {
-        snprintf(buf, sizeof(buf), "%dx%d", frame_width, frame_height);
-        av_dict_set(&format_opts, "video_size", buf, 0);
+    if (o->nb_frame_sizes) {
+        av_dict_set(&format_opts, "video_size", o->frame_sizes[o->nb_frame_sizes - 1].u.str, 0);
     }
-    if (frame_pix_fmt != PIX_FMT_NONE)
-        av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(frame_pix_fmt), 0);
+    if (o->nb_frame_pix_fmts)
+        av_dict_set(&format_opts, "pixel_format", o->frame_pix_fmts[o->nb_frame_pix_fmts - 1].u.str, 0);
 
     ic->flags |= AVFMT_FLAG_NONBLOCK;
 
@@ -2963,12 +3024,6 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena
     input_files[nb_input_files - 1].ts_offset  = o->input_ts_offset - (copy_ts ? 0 : timestamp);
     input_files[nb_input_files - 1].nb_streams = ic->nb_streams;
 
-    frame_rate    = (AVRational){0, 0};
-    frame_pix_fmt = PIX_FMT_NONE;
-    frame_height = 0;
-    frame_width  = 0;
-    audio_sample_rate = 0;
-
     for (i = 0; i < orig_nb_streams; i++)
         av_dict_free(&opts[i]);
     av_freep(&opts);
@@ -3003,11 +3058,12 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost,
 static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
 {
     OutputStream *ost;
-    AVStream *st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
+    AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0);
     int idx      = oc->nb_streams - 1;
     int64_t max_frames = INT64_MAX;
     char *bsf = NULL, *next, *codec_tag = NULL;
     AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
+    double qscale = -1;
 
     if (!st) {
         av_log(NULL, AV_LOG_ERROR, "Could not alloc stream.\n");
@@ -3057,10 +3113,33 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
         st->codec->codec_tag = tag;
     }
 
+    MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
+    if (qscale >= 0 || same_quant) {
+        st->codec->flags |= CODEC_FLAG_QSCALE;
+        st->codec->global_quality = FF_QP2LAMBDA * qscale;
+    }
+
     ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
     return ost;
 }
 
+static void parse_matrix_coeffs(uint16_t *dest, const char *str)
+{
+    int i;
+    const char *p = str;
+    for(i = 0;; i++) {
+        dest[i] = atoi(p);
+        if(i == 63)
+            break;
+        p = strchr(p, ',');
+        if(!p) {
+            fprintf(stderr, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
+            exit_program(1);
+        }
+        p++;
+    }
+}
+
 static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
 {
     AVStream *st;
@@ -3069,47 +3148,60 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
 
     ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
     st  = ost->st;
-    if (!st->stream_copy) {
-        ost->frame_aspect_ratio = frame_aspect_ratio;
-        frame_aspect_ratio = 0;
-#if CONFIG_AVFILTER
-        ost->avfilter= vfilters;
-        vfilters = NULL;
-#endif
-    }
-
     video_enc = st->codec;
 
     if(oc->oformat->flags & AVFMT_GLOBALHEADER) {
         video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
     }
 
-    if (st->stream_copy) {
-        video_enc->sample_aspect_ratio =
-        st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
-    } else {
-        const char *p;
-        int i;
+    if (!st->stream_copy) {
+        const char *p = NULL;
+        char *forced_key_frames = NULL, *frame_rate = NULL, *frame_size = NULL;
+        char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL;
+        char *intra_matrix = NULL, *inter_matrix = NULL, *filters = NULL;
+        int i, force_fps = 0, top_field_first = -1;
+
+        MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
+        if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Invalid framerate value: %s\n", frame_rate);
+            exit_program(1);
+        }
 
-        if (frame_rate.num)
-            ost->frame_rate = frame_rate;
+        MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
+        if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Invalid frame size: %s.\n", frame_size);
+            exit_program(1);
+        }
 
-        video_enc->width = frame_width;
-        video_enc->height = frame_height;
-        video_enc->pix_fmt = frame_pix_fmt;
-        st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
+        MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
+        if (frame_aspect_ratio)
+            ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio);
 
-        if (video_qscale || same_quant) {
-            video_enc->flags |= CODEC_FLAG_QSCALE;
-            video_enc->global_quality = FF_QP2LAMBDA * video_qscale;
+        MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
+        if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == PIX_FMT_NONE) {
+            av_log(NULL, AV_LOG_ERROR, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
+            exit_program(1);
         }
+        st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
 
-        if(intra_matrix)
-            video_enc->intra_matrix = intra_matrix;
-        if(inter_matrix)
-            video_enc->inter_matrix = inter_matrix;
+        MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
+        if (intra_matrix) {
+            if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
+                av_log(NULL, AV_LOG_ERROR, "Could not allocate memory for intra matrix.\n");
+                exit_program(1);
+            }
+            parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
+        }
+        MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
+        if (inter_matrix) {
+            if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
+                av_log(NULL, AV_LOG_ERROR, "Could not allocate memory for inter matrix.\n");
+                exit_program(1);
+            }
+            parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
+        }
 
-        p= video_rc_override_string;
+        MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
         for(i=0; p; i++){
             int start, end, q;
             int e=sscanf(p, "%d,%d,%d", &start, &end, &q);
@@ -3136,12 +3228,8 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
         video_enc->rc_override_count=i;
         if (!video_enc->rc_initial_buffer_occupancy)
             video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size*3/4;
-        video_enc->me_threshold= me_threshold;
         video_enc->intra_dc_precision= intra_dc_precision - 8;
 
-        if (do_psnr)
-            video_enc->flags|= CODEC_FLAG_PSNR;
-
         /* two pass mode */
         if (do_pass) {
             if (do_pass == 1) {
@@ -3151,13 +3239,23 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
             }
         }
 
+        MATCH_PER_STREAM_OPT(forced_key_frames, str, forced_key_frames, oc, st);
         if (forced_key_frames)
             parse_forced_key_frames(forced_key_frames, ost, video_enc);
+
+        MATCH_PER_STREAM_OPT(force_fps, i, force_fps, oc, st);
+        ost->force_fps = force_fps;
+
+        MATCH_PER_STREAM_OPT(top_field_first, i, top_field_first, oc, st);
+        ost->top_field_first = top_field_first;
+
+#if CONFIG_AVFILTER
+        MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
+        if (filters)
+            ost->avfilter = av_strdup(filters);
+#endif
     }
 
-    /* reset some key parameters */
-    av_freep(&forced_key_frames);
-    frame_pix_fmt = PIX_FMT_NONE;
     return ost;
 }
 
@@ -3179,10 +3277,6 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
     if (!st->stream_copy) {
         char *sample_fmt = NULL;
 
-        if (audio_qscale > QSCALE_NONE) {
-            audio_enc->flags |= CODEC_FLAG_QSCALE;
-            audio_enc->global_quality = FF_QP2LAMBDA * audio_qscale;
-        }
         MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
 
         MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
@@ -3192,8 +3286,7 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
             exit_program(1);
         }
 
-        if (audio_sample_rate)
-            audio_enc->sample_rate = audio_sample_rate;
+        MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
     }
 
     return ost;
@@ -3240,7 +3333,7 @@ static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
 }
 
 /* arg format is "output-stream-index:streamid-value". */
-static int opt_streamid(const char *opt, const char *arg)
+static int opt_streamid(OptionsContext *o, const char *opt, const char *arg)
 {
     int idx;
     char *p;
@@ -3255,9 +3348,9 @@ static int opt_streamid(const char *opt, const char *arg)
         exit_program(1);
     }
     *p++ = '\0';
-    idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
-    streamid_map = grow_array(streamid_map, sizeof(*streamid_map), &nb_streamid_map, idx+1);
-    streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
+    idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
+    o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
+    o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
     return 0;
 }
 
@@ -3301,7 +3394,7 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
     return 0;
 }
 
-static int read_avserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
+static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
 {
     int i, err;
     AVFormatContext *ic = NULL;
@@ -3321,7 +3414,8 @@ static int read_avserver_streams(OptionsContext *o, AVFormatContext *s, const ch
 
         // FIXME: a more elegant solution is needed
         memcpy(st, ic->streams[i], sizeof(AVStream));
-        st->info = NULL;
+        st->info = av_malloc(sizeof(*st->info));
+        memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
         avcodec_copy_context(st->codec, ic->streams[i]->codec);
 
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !st->stream_copy)
@@ -3346,35 +3440,19 @@ static void opt_output_file(void *optctx, const char *filename)
     if (!strcmp(filename, "-"))
         filename = "pipe:";
 
-    oc = avformat_alloc_context();
+    err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
     if (!oc) {
-        print_error(filename, AVERROR(ENOMEM));
+        print_error(filename, err);
         exit_program(1);
     }
 
-    if (o->format) {
-        file_oformat = av_guess_format(o->format, NULL, NULL);
-        if (!file_oformat) {
-            fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", o->format);
-            exit_program(1);
-        }
-    } else {
-        file_oformat = av_guess_format(NULL, filename, NULL);
-        if (!file_oformat) {
-            fprintf(stderr, "Unable to find a suitable output format for '%s'\n",
-                    filename);
-            exit_program(1);
-        }
-    }
-
-    oc->oformat = file_oformat;
-    av_strlcpy(oc->filename, filename, sizeof(oc->filename));
+    file_oformat= oc->oformat;
 
     if (!strcmp(file_oformat->name, "ffm") &&
         av_strstart(filename, "http:", NULL)) {
-        /* special case for files sent to avserver: we get the stream
-           parameters from avserver */
-        int err = read_avserver_streams(o, oc, filename);
+        /* special case for files sent to ffserver: we get the stream
+           parameters from ffserver */
+        int err = read_ffserver_streams(o, oc, filename);
         if (err < 0) {
             print_error(filename, err);
             exit_program(1);
@@ -3499,7 +3577,6 @@ static void opt_output_file(void *optctx, const char *filename)
 
     oc->preload   = (int)(o->mux_preload   * AV_TIME_BASE);
     oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
-    oc->flags |= AVFMT_FLAG_NONBLOCK;
 
     /* copy chapters */
     if (o->chapters_input_file >= nb_input_files) {
@@ -3519,7 +3596,7 @@ static void opt_output_file(void *optctx, const char *filename)
     }
     if (o->chapters_input_file >= 0)
         copy_chapters(&input_files[o->chapters_input_file], &output_files[nb_output_files - 1],
-                      o->metadata_chapters_manual);
+                      !o->metadata_chapters_manual);
 
     /* copy metadata */
     for (i = 0; i < o->nb_meta_data_maps; i++) {
@@ -3601,14 +3678,14 @@ static void opt_output_file(void *optctx, const char *filename)
                 av_log(NULL, AV_LOG_ERROR, "Invalid stream index %d in metadata specifier.\n", index);
                 exit_program(1);
             }
-            m = &oc->streams[i]->metadata;
+            m = &oc->streams[index]->metadata;
             break;
         case 'c':
             if (index < 0 || index >= oc->nb_chapters) {
                 av_log(NULL, AV_LOG_ERROR, "Invalid chapter index %d in metadata specifier.\n", index);
                 exit_program(1);
             }
-            m = &oc->chapters[i]->metadata;
+            m = &oc->chapters[index]->metadata;
             break;
         default:
             av_log(NULL, AV_LOG_ERROR, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
@@ -3618,15 +3695,6 @@ static void opt_output_file(void *optctx, const char *filename)
         av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
     }
 
-    frame_rate    = (AVRational){0, 0};
-    frame_width   = 0;
-    frame_height  = 0;
-    audio_sample_rate = 0;
-
-    av_freep(&streamid_map);
-    nb_streamid_map = 0;
-
-    av_freep(&forced_key_frames);
     reset_options(o);
 }
 
@@ -3673,33 +3741,9 @@ static int64_t getmaxrss(void)
 #endif
 }
 
-static void parse_matrix_coeffs(uint16_t *dest, const char *str)
-{
-    int i;
-    const char *p = str;
-    for(i = 0;; i++) {
-        dest[i] = atoi(p);
-        if(i == 63)
-            break;
-        p = strchr(p, ',');
-        if(!p) {
-            fprintf(stderr, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
-            exit_program(1);
-        }
-        p++;
-    }
-}
-
-static void opt_inter_matrix(const char *arg)
-{
-    inter_matrix = av_mallocz(sizeof(uint16_t) * 64);
-    parse_matrix_coeffs(inter_matrix, arg);
-}
-
-static void opt_intra_matrix(const char *arg)
+static int opt_audio_qscale(OptionsContext *o, const char *opt, const char *arg)
 {
-    intra_matrix = av_mallocz(sizeof(uint16_t) * 64);
-    parse_matrix_coeffs(intra_matrix, arg);
+    return parse_option(o, "q:a", arg, options);
 }
 
 static void show_usage(void)
@@ -3709,7 +3753,7 @@ static void show_usage(void)
     printf("\n");
 }
 
-static void show_help(void)
+static int opt_help(const char *opt, const char *arg)
 {
     AVCodec *c;
     AVOutputFormat *oformat = NULL;
@@ -3777,6 +3821,7 @@ static void show_help(void)
 
     class = sws_get_class();
     av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
+    return 0;
 }
 
 static int opt_target(OptionsContext *o, const char *opt, const char *arg)
@@ -3794,34 +3839,25 @@ static int opt_target(OptionsContext *o, const char *opt, const char *arg)
         norm = FILM;
         arg += 5;
     } else {
-        int fr;
-        /* Calculate FR via float to avoid int overflow */
-        fr = (int)(frame_rate.num * 1000.0 / frame_rate.den);
-        if(fr == 25000) {
-            norm = PAL;
-        } else if((fr == 29970) || (fr == 23976)) {
-            norm = NTSC;
-        } else {
-            /* Try to determine PAL/NTSC by peeking in the input files */
-            if(nb_input_files) {
-                int i, j;
-                for (j = 0; j < nb_input_files; j++) {
-                    for (i = 0; i < input_files[j].nb_streams; i++) {
-                        AVCodecContext *c = input_files[j].ctx->streams[i]->codec;
-                        if(c->codec_type != AVMEDIA_TYPE_VIDEO)
-                            continue;
-                        fr = c->time_base.den * 1000 / c->time_base.num;
-                        if(fr == 25000) {
-                            norm = PAL;
-                            break;
-                        } else if((fr == 29970) || (fr == 23976)) {
-                            norm = NTSC;
-                            break;
-                        }
-                    }
-                    if(norm != UNKNOWN)
+        /* Try to determine PAL/NTSC by peeking in the input files */
+        if(nb_input_files) {
+            int i, j, fr;
+            for (j = 0; j < nb_input_files; j++) {
+                for (i = 0; i < input_files[j].nb_streams; i++) {
+                    AVCodecContext *c = input_files[j].ctx->streams[i]->codec;
+                    if(c->codec_type != AVMEDIA_TYPE_VIDEO)
+                        continue;
+                    fr = c->time_base.den * 1000 / c->time_base.num;
+                    if(fr == 25000) {
+                        norm = PAL;
+                        break;
+                    } else if((fr == 29970) || (fr == 23976)) {
+                        norm = NTSC;
                         break;
+                    }
                 }
+                if(norm != UNKNOWN)
+                    break;
             }
         }
         if(verbose > 0 && norm != UNKNOWN)
@@ -3840,8 +3876,8 @@ static int opt_target(OptionsContext *o, const char *opt, const char *arg)
         opt_audio_codec(o, "c:a", "mp2");
         parse_option(o, "f", "vcd", options);
 
-        opt_frame_size("s", norm == PAL ? "352x288" : "352x240");
-        opt_frame_rate("r", frame_rates[norm]);
+        parse_option(o, "s", norm == PAL ? "352x288" : "352x240", options);
+        parse_option(o, "r", frame_rates[norm], options);
         opt_default("g", norm == PAL ? "15" : "18");
 
         opt_default("b", "1150000");
@@ -3850,7 +3886,7 @@ static int opt_target(OptionsContext *o, const char *opt, const char *arg)
         opt_default("bufsize", "327680"); // 40*1024*8;
 
         opt_default("b:a", "224000");
-        audio_sample_rate = 44100;
+        parse_option(o, "ar", "44100", options);
         parse_option(o, "ac", "2", options);
 
         opt_default("packetsize", "2324");
@@ -3868,8 +3904,8 @@ static int opt_target(OptionsContext *o, const char *opt, const char *arg)
         opt_audio_codec(o, "c:a", "mp2");
         parse_option(o, "f", "svcd", options);
 
-        opt_frame_size("s", norm == PAL ? "480x576" : "480x480");
-        opt_frame_rate("r", frame_rates[norm]);
+        parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
+        parse_option(o, "r", frame_rates[norm], options);
         opt_default("g", norm == PAL ? "15" : "18");
 
         opt_default("b", "2040000");
@@ -3880,7 +3916,7 @@ static int opt_target(OptionsContext *o, const char *opt, const char *arg)
 
 
         opt_default("b:a", "224000");
-        audio_sample_rate = 44100;
+        parse_option(o, "ar", "44100", options);
 
         opt_default("packetsize", "2324");
 
@@ -3890,8 +3926,8 @@ static int opt_target(OptionsContext *o, const char *opt, const char *arg)
         opt_audio_codec(o, "c:a", "ac3");
         parse_option(o, "f", "dvd", options);
 
-        opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480");
-        opt_frame_rate("r", frame_rates[norm]);
+        parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
+        parse_option(o, "r", frame_rates[norm], options);
         opt_default("g", norm == PAL ? "15" : "18");
 
         opt_default("b", "6000000");
@@ -3903,18 +3939,18 @@ static int opt_target(OptionsContext *o, const char *opt, const char *arg)
         opt_default("muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
 
         opt_default("b:a", "448000");
-        audio_sample_rate = 48000;
+        parse_option(o, "ar", "48000", options);
 
     } else if(!strncmp(arg, "dv", 2)) {
 
         parse_option(o, "f", "dv", options);
 
-        opt_frame_size("s", norm == PAL ? "720x576" : "720x480");
-        opt_frame_pix_fmt("pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
-                          norm == PAL ? "yuv420p" : "yuv411p");
-        opt_frame_rate("r", frame_rates[norm]);
+        parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
+        parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
+                          norm == PAL ? "yuv420p" : "yuv411p", options);
+        parse_option(o, "r", frame_rates[norm], options);
 
-        audio_sample_rate = 48000;
+        parse_option(o, "ar", "48000", options);
         parse_option(o, "ac", "2", options);
 
     } else {
@@ -3957,6 +3993,20 @@ static int opt_data_frames(OptionsContext *o, const char *opt, const char *arg)
     return parse_option(o, "frames:d", arg, options);
 }
 
+static void log_callback_null(void* ptr, int level, const char* fmt, va_list vl)
+{
+}
+
+static int opt_passlogfile(const char *opt, const char *arg)
+{
+    pass_logfilename_prefix = arg;
+#if CONFIG_LIBX264_ENCODER
+    return opt_default("passlogfile", arg);
+#else
+    return 0;
+#endif
+}
+
 static int opt_video_tag(OptionsContext *o, const char *opt, const char *arg)
 {
     return parse_option(o, "tag:v", arg, options);
@@ -3972,6 +4022,11 @@ static int opt_subtitle_tag(OptionsContext *o, const char *opt, const char *arg)
     return parse_option(o, "tag:s", arg, options);
 }
 
+static int opt_video_filters(OptionsContext *o, const char *opt, const char *arg)
+{
+    return parse_option(o, "filter:v", arg, options);
+}
+
 #define OFFSET(x) offsetof(OptionsContext, x)
 static const OptionDef options[] = {
     /* main options */
@@ -4013,45 +4068,49 @@ static const OptionDef options[] = {
     { "copyinkf", OPT_BOOL | OPT_EXPERT, {(void*)&copy_initial_nonkeyframes}, "copy initial non-keyframes" },
     { "frames", OPT_INT64 | HAS_ARG | OPT_SPEC, {.off = OFFSET(max_frames)}, "set the number of frames to record", "number" },
     { "tag",   OPT_STRING | HAS_ARG | OPT_SPEC, {.off = OFFSET(codec_tags)}, "force codec tag/fourcc", "fourcc/tag" },
+    { "q", HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(qscale)}, "use fixed quality scale (VBR)", "q" },
+    { "qscale", HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC, {.off = OFFSET(qscale)}, "use fixed quality scale (VBR)", "q" },
+#if CONFIG_AVFILTER
+    { "filter", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(filters)}, "set stream filterchain", "filter_list" },
+#endif
 
     /* video options */
     { "vframes", HAS_ARG | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_frames}, "set the number of video frames to record", "number" },
-    { "r", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_rate}, "set frame rate (Hz value, fraction or abbreviation)", "rate" },
-    { "s", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_size}, "set frame size (WxH or abbreviation)", "size" },
-    { "aspect", HAS_ARG | OPT_VIDEO, {(void*)opt_frame_aspect_ratio}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
-    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_frame_pix_fmt}, "set pixel format, 'list' as argument shows all the pixel formats supported", "format" },
+    { "r", HAS_ARG | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_rates)}, "set frame rate (Hz value, fraction or abbreviation)", "rate" },
+    { "s", HAS_ARG | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_sizes)}, "set frame size (WxH or abbreviation)", "size" },
+    { "aspect", HAS_ARG | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_aspect_ratios)}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
+    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_pix_fmts)}, "set pixel format", "format" },
+    { "bits_per_raw_sample", OPT_INT | HAS_ARG | OPT_VIDEO, {(void*)&frame_bits_per_raw_sample}, "set the number of bits per raw sample", "number" },
     { "vn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET, {.off = OFFSET(video_disable)}, "disable video" },
     { "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" },
-    { "qscale", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_qscale}, "use fixed video quantizer scale (VBR)", "q" },
-    { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_video_rc_override_string}, "rate control override for specific intervals", "override" },
+    { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(rc_overrides)}, "rate control override for specific intervals", "override" },
     { "vcodec", HAS_ARG | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" },
-    { "me_threshold", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_me_threshold}, "motion estimation threshold",  "threshold" },
     { "same_quant", OPT_BOOL | OPT_VIDEO, {(void*)&same_quant},
       "use same quantizer as source (implies VBR)" },
     { "pass", HAS_ARG | OPT_VIDEO, {(void*)opt_pass}, "select the pass number (1 or 2)", "n" },
-    { "passlogfile", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void*)&pass_logfilename_prefix}, "select two pass log file name prefix", "prefix" },
+    { "passlogfile", HAS_ARG | OPT_VIDEO, {(void*)&opt_passlogfile}, "select two pass log file name prefix", "prefix" },
     { "deinterlace", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_deinterlace},
       "deinterlace pictures" },
-    { "psnr", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_psnr}, "calculate PSNR of compressed frames" },
     { "vstats", OPT_EXPERT | OPT_VIDEO, {(void*)&opt_vstats}, "dump video coding statistics to file" },
     { "vstats_file", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_vstats_file}, "dump video coding statistics to file", "file" },
 #if CONFIG_AVFILTER
-    { "vf", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
+// さきゅばすインタフェース互換性維持のため処置 引数を新しいvfでなく古いvfiltersのままとする
+    { "vfilters", HAS_ARG | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_filters}, "video filters", "filter list" },
 #endif
-    { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
-    { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" },
-    { "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_top_field_first}, "top=1/bottom=0/auto=-1 field first", "" },
+    { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(intra_matrices)}, "specify intra matrix coeffs", "matrix" },
+    { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(inter_matrices)}, "specify inter matrix coeffs", "matrix" },
+    { "top", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_INT| OPT_SPEC, {.off = OFFSET(top_field_first)}, "top=1/bottom=0/auto=-1 field first", "" },
     { "dc", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&intra_dc_precision}, "intra_dc_precision", "precision" },
     { "vtag", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_FUNC2, {(void*)opt_video_tag}, "force video tag/fourcc", "fourcc/tag" },
     { "qphist", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&qp_hist }, "show QP histogram" },
-    { "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&force_fps}, "force the selected framerate, disable the best supported framerate selection" },
-    { "streamid", HAS_ARG | OPT_EXPERT, {(void*)opt_streamid}, "set the value of an outfile streamid", "streamIndex:value" },
-    { "force_key_frames", OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void *)&forced_key_frames}, "force key frames at specified timestamps", "timestamps" },
+    { "force_fps", OPT_BOOL | OPT_EXPERT | OPT_VIDEO | OPT_SPEC, {.off = OFFSET(force_fps)}, "force the selected framerate, disable the best supported framerate selection" },
+    { "streamid", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_streamid}, "set the value of an outfile streamid", "streamIndex:value" },
+    { "force_key_frames", OPT_STRING | HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_SPEC, {.off = OFFSET(forced_key_frames)}, "force key frames at specified timestamps", "timestamps" },
 
     /* audio options */
     { "aframes", HAS_ARG | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_frames}, "set the number of audio frames to record", "number" },
-    { "aq", OPT_FLOAT | HAS_ARG | OPT_AUDIO, {(void*)&audio_qscale}, "set audio quality (codec-specific)", "quality", },
-    { "ar", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_rate}, "set audio sampling rate (in Hz)", "rate" },
+    { "aq", HAS_ARG | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_qscale}, "set audio quality (codec-specific)", "quality", },
+    { "ar", HAS_ARG | OPT_AUDIO | OPT_INT | OPT_SPEC, {.off = OFFSET(audio_sample_rate)}, "set audio sampling rate (in Hz)", "rate" },
     { "ac", HAS_ARG | OPT_AUDIO | OPT_INT | OPT_SPEC, {.off = OFFSET(audio_channels)}, "set number of audio channels", "channels" },
     { "an", OPT_BOOL | OPT_AUDIO | OPT_OFFSET, {.off = OFFSET(audio_disable)}, "disable audio" },
     { "acodec", HAS_ARG | OPT_AUDIO | OPT_FUNC2, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" },
@@ -4089,6 +4148,14 @@ int main(int argc, char **argv)
 
     av_log_set_flags(AV_LOG_SKIP_REPEATED);
 
+    if(argc>1 && !strcmp(argv[1], "-d")){
+        run_as_daemon=1;
+        verbose=-1;
+        av_log_set_callback(log_callback_null);
+        argc--;
+        argv++;
+    }
+
     avcodec_register_all();
 #if CONFIG_AVDEVICE
     avdevice_register_all();
@@ -4098,9 +4165,13 @@ int main(int argc, char **argv)
 #endif
     av_register_all();
 
-    avio_set_interrupt_cb(decode_interrupt_cb);
+#if HAVE_ISATTY
+    if(isatty(STDIN_FILENO))
+        avio_set_interrupt_cb(decode_interrupt_cb);
+#endif
 
-    show_banner();
+    if(verbose>=0)
+        show_banner();
 
     /* parse options */
     parse_options(&o, argc, argv, options, opt_output_file);