Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 30 Dec 2011 02:46:24 +0000 (03:46 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 30 Dec 2011 02:46:24 +0000 (03:46 +0100)
* qatar/master:
  fate: split off DPCM codec FATE tests into their own file
  fate: split off PCM codec FATE tests into their own file
  libvorbis: K&R reformatting cosmetics
  libmp3lame: K&R formatting cosmetics
  fate: Add a video test for xxan decoder
  mpegvideo_enc: K&R cosmetics (line 1000-2000).
  avconv: K&R cosmetics
  qt-faststart: Fix up indentation
  indeo4: remove two unused variables
  doxygen: cleanup style to support older doxy
  fate: add more tests for VC-1 decoder
  applehttpproto: Apply the same reload interval changes as for the demuxer
  applehttp: Use half the target duration as interval if the playlist didn't update
  applehttp: Use the last segment duration as reload interval
  lagarith: add decode support for arith rgb24 mode

Conflicts:
avconv.c
libavcodec/libmp3lame.c
libavcodec/mpegvideo_enc.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
avconv.c
ffmpeg.c
libavcodec/libmp3lame.c
libavcodec/libvorbis.c
libavcodec/mpegvideo_enc.c
libavformat/applehttp.c
libavformat/applehttpproto.c
tests/Makefile
tests/fate.mak
tools/qt-faststart.c

diff --cc avconv.c
+++ b/avconv.c
@@@ -126,11 -110,11 +126,11 @@@ static int do_benchmark = 0
  static int do_hex_dump = 0;
  static int do_pkt_dump = 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 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 = 1;
  static int opt_shortest = 0;
  static char *vstats_filename;
@@@ -674,29 -641,7 +674,29 @@@ sigterm_handler(int sig
  
  static void term_init(void)
  {
-     signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).  */
 +#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
      signal(SIGXCPU, sigterm_handler);
@@@ -840,23 -750,63 +840,23 @@@ static void choose_sample_fmt(AVStream 
      }
  }
  
 -/**
 - * 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){
-         const int *p= codec->supported_samplerates;
-         int best=0;
-         int best_dist=INT_MAX;
-         for(; *p; p++){
-             int dist= abs(st->codec->sample_rate - *p);
-             if(dist < best_dist){
-                 best_dist= dist;
-                 best= *p;
+     if (codec && codec->supported_samplerates) {
+         const int *p  = codec->supported_samplerates;
+         int best      = 0;
+         int best_dist = INT_MAX;
+         for (; *p; p++) {
+             int dist = abs(st->codec->sample_rate - *p);
+             if (dist < best_dist) {
+                 best_dist = dist;
+                 best      = *p;
              }
          }
-         if(best_dist){
+         if (best_dist) {
              av_log(st->codec, AV_LOG_WARNING, "Requested sampling rate unsupported using closest supported (%d)\n", best);
          }
-         st->codec->sample_rate= best;
+         st->codec->sample_rate = best;
      }
  }
  
@@@ -1568,12 -1509,13 +1571,12 @@@ static void print_report(OutputFile *ou
      oc = output_files[0].ctx;
  
      total_size = avio_size(oc->pb);
-     if(total_size<0) // FIXME improve avio_size() so it works with non seekable output too
-         total_size= avio_tell(oc->pb);
+     if (total_size < 0) // FIXME improve avio_size() so it works with non seekable output too
+         total_size = avio_tell(oc->pb);
  
      buf[0] = '\0';
 -    ti1 = 1e10;
      vid = 0;
-     for(i=0;i<nb_ostreams;i++) {
+     for (i = 0; i < nb_ostreams; i++) {
          float q = -1;
          ost = &ost_table[i];
          enc = ost->st->codec;
@@@ -2229,8 -2162,9 +2233,8 @@@ static int init_input_stream(int ist_in
          assert_avoptions(ist->opts);
      }
  
-     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->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;
@@@ -2474,10 -2420,9 +2478,10 @@@ static int transcode_init(OutputFile *o
                  }
              }
          }
-         if(codec->codec_type == AVMEDIA_TYPE_VIDEO){
+         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 + 1664);
 -            bit_buffer_size = FFMAX(bit_buffer_size, 6 * size + 200);
++            bit_buffer_size = FFMAX(bit_buffer_size, 6 * size + 1664);
          }
      }
  
@@@ -2625,9 -2570,8 +2629,9 @@@ static int transcode(OutputFile *output
      OutputStream *ost;
      InputStream *ist;
      uint8_t *no_packet;
-     int no_packet_count=0;
+     int no_packet_count = 0;
      int64_t timer_start;
 +    int key;
  
      if (!(no_packet = av_mallocz(nb_input_files)))
          exit_program(1);
          double opts_min;
  
          ipts_min = INT64_MAX;
-         opts_min= 1e100;
+         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 == '+') av_log_set_level(av_log_get_level()+10);
 +            if (key == '-') av_log_set_level(av_log_get_level()-10);
 +            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 */
@@@ -3198,21 -3093,19 +3207,21 @@@ static void add_input_streams(OptionsCo
  
          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;
+                 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 (dec->time_base.den != rfps*dec->ticks_per_frame || dec->time_base.num != rfps_base) {
+             if (dec->time_base.den != rfps * dec->ticks_per_frame || dec->time_base.num != rfps_base) {
  
                  av_log(NULL, AV_LOG_INFO,"\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d)\n",
                         i, (float)dec->time_base.den / dec->time_base.num, dec->time_base.den, dec->time_base.num,
diff --cc ffmpeg.c
+++ b/ffmpeg.c
@@@ -143,12 -188,16 +143,12 @@@ 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 int audio_stream_copy = 0;
 -static int video_stream_copy = 0;
 -static int subtitle_stream_copy = 0;
 -static int data_stream_copy = 0;
 -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 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= -1;
++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 = -1;
  static int opt_shortest = 0;
  static char *vstats_filename;
  static FILE *vstats_file;
@@@ -234,12 -249,11 +234,12 @@@ typedef struct OutputStream 
      int frame_number;
      /* input pts and corresponding output pts
         for A/V sync */
--    //double sync_ipts;        /* dts from the AVPacket of the demuxer in second units */
++    // double sync_ipts;        /* dts from the AVPacket of the demuxer in second units */
      struct InputStream *sync_ist; /* input stream to sync against */
--    int64_t sync_opts;       /* output frame counter, could be changed to some true timestamp */ //FIXME look at frame_number
++    int64_t sync_opts;       /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number
      AVBitStreamFilterContext *bitstream_filters;
      AVCodec *enc;
 +    int64_t max_frames;
  
      /* video only */
      int video_resample;
      AVFilterGraph *graph;
  #endif
  
 -   int sws_flags;
 -   AVDictionary *opts;
 +    int64_t sws_flags;
 +    AVDictionary *opts;
 +    int is_past_recording_time;
 +    int stream_copy;
 +    const char *attachment_filename;
 +    int copy_initial_nonkeyframes;
  } OutputStream;
  
 -static OutputStream **output_streams_for_file[MAX_FILES] = { NULL };
 -static int nb_output_streams_for_file[MAX_FILES] = { 0 };
  
 -typedef struct InputStream {
 -    int file_index;
 -    AVStream *st;
 -    int discard;             /* true if stream data should be discarded */
 -    int decoding_needed;     /* true if the packets must be decoded in 'raw_fifo' */
 -    AVCodec *dec;
 +#if HAVE_TERMIOS_H
  
 -    int64_t       start;     /* time when read started */
 -    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;
 -    int is_past_recording_time;
 -    AVDictionary *opts;
 -} InputStream;
 +/* init terminal so that we can grab keys */
 +static struct termios oldtty;
 +#endif
  
 -typedef struct InputFile {
 +typedef struct OutputFile {
      AVFormatContext *ctx;
 -    int eof_reached;      /* true if eof reached */
 -    int ist_index;        /* index of first stream in ist_table */
 -    int buffer_size;      /* current total buffer size */
 -    int64_t ts_offset;
 -    int nb_streams;       /* nb streams we are aware of */
 -} InputFile;
 +    AVDictionary *opts;
 +    int ost_index;       /* index of the first stream in output_streams */
 +    int64_t recording_time; /* desired length of the resulting file in microseconds */
 +    int64_t start_time;     /* start time in microseconds */
 +    uint64_t limit_filesize;
 +} OutputFile;
  
--static InputStream *input_streams = NULL;
++static InputStream *input_streams   = NULL;
  static int         nb_input_streams = 0;
--static InputFile   *input_files   = NULL;
++static InputFile   *input_files     = NULL;
  static int         nb_input_files   = 0;
  
 +static OutputStream *output_streams = NULL;
 +static int        nb_output_streams = 0;
 +static OutputFile   *output_files   = NULL;
 +static int        nb_output_files   = 0;
 +
 +typedef struct OptionsContext {
 +    /* input/output options */
 +    int64_t start_time;
 +    const char *format;
 +
 +    SpecifierOpt *codec_names;
 +    int        nb_codec_names;
 +    SpecifierOpt *audio_channels;
 +    int        nb_audio_channels;
 +    SpecifierOpt *audio_sample_rate;
 +    int        nb_audio_sample_rate;
 +    SpecifierOpt *rematrix_volume;
 +    int        nb_rematrix_volume;
 +    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;
 +    int rate_emu;
 +
 +    SpecifierOpt *ts_scale;
 +    int        nb_ts_scale;
 +    SpecifierOpt *dump_attachment;
 +    int        nb_dump_attachment;
 +
 +    /* output options */
 +    StreamMap *stream_maps;
 +    int     nb_stream_maps;
 +    AudioChannelMap *audio_channel_maps; ///< one info entry per -map_channel
 +    int           nb_audio_channel_maps; ///< number of (valid) -map_channel settings
 +    /* first item specifies output metadata, second is input */
 +    MetadataMap (*meta_data_maps)[2];
 +    int nb_meta_data_maps;
 +    int metadata_global_manual;
 +    int metadata_streams_manual;
 +    int metadata_chapters_manual;
 +    const char **attachments;
 +    int       nb_attachments;
 +
 +    int chapters_input_file;
 +
 +    int64_t recording_time;
 +    uint64_t limit_filesize;
 +    float mux_preload;
 +    float mux_max_delay;
 +
 +    int video_disable;
 +    int audio_disable;
 +    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;
 +    int        nb_max_frames;
 +    SpecifierOpt *bitstream_filters;
 +    int        nb_bitstream_filters;
 +    SpecifierOpt *codec_tags;
 +    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;
 +    SpecifierOpt *metadata_map;
 +    int        nb_metadata_map;
 +    SpecifierOpt *presets;
 +    int        nb_presets;
 +    SpecifierOpt *copy_initial_nonkeyframes;
 +    int        nb_copy_initial_nonkeyframes;
 +#if CONFIG_AVFILTER
 +    SpecifierOpt *filters;
 +    int        nb_filters;
 +#endif
 +} OptionsContext;
 +
 +#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
 +{\
 +    int i, ret;\
 +    for (i = 0; i < o->nb_ ## name; i++) {\
 +        char *spec = o->name[i].specifier;\
 +        if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
 +            outvar = o->name[i].u.type;\
 +        else if (ret < 0)\
 +            exit_program(1);\
 +    }\
 +}
 +
 +static void reset_options(OptionsContext *o, int is_input)
 +{
 +    const OptionDef *po = options;
 +    OptionsContext bak= *o;
 +
 +    /* all OPT_SPEC and OPT_STRING can be freed in generic way */
 +    while (po->name) {
 +        void *dst = (uint8_t*)o + po->u.off;
 +
 +        if (po->flags & OPT_SPEC) {
 +            SpecifierOpt **so = dst;
 +            int i, *count = (int*)(so + 1);
 +            for (i = 0; i < *count; i++) {
 +                av_freep(&(*so)[i].specifier);
 +                if (po->flags & OPT_STRING)
 +                    av_freep(&(*so)[i].u.str);
 +            }
 +            av_freep(so);
 +            *count = 0;
 +        } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
 +            av_freep(dst);
 +        po++;
 +    }
 +
 +    av_freep(&o->stream_maps);
 +    av_freep(&o->audio_channel_maps);
 +    av_freep(&o->meta_data_maps);
 +    av_freep(&o->streamid_map);
 +
 +    memset(o, 0, sizeof(*o));
 +
 +    if(is_input) o->recording_time = bak.recording_time;
 +    else         o->recording_time = INT64_MAX;
 +    o->mux_max_delay  = 0.7;
 +    o->limit_filesize = UINT64_MAX;
 +    o->chapters_input_file = INT_MAX;
 +
 +    uninit_opts();
 +    init_opts();
 +}
 +
 +static int alloc_buffer(InputStream *ist, FrameBuffer **pbuf)
 +{
 +    AVCodecContext *s = ist->st->codec;
 +    FrameBuffer  *buf = av_mallocz(sizeof(*buf));
 +    int ret, i;
 +    const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1;
 +    int h_chroma_shift, v_chroma_shift;
 +    int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1
 +    int w = s->width, h = s->height;
 +
 +    if (!buf)
 +        return AVERROR(ENOMEM);
 +
 +    if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
 +        w += 2*edge;
 +        h += 2*edge;
 +    }
 +
 +    avcodec_align_dimensions(s, &w, &h);
 +    if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
 +                              s->pix_fmt, 32)) < 0) {
 +        av_freep(&buf);
 +        return ret;
 +    }
 +    /* XXX this shouldn't be needed, but some tests break without this line
 +     * those decoders are buggy and need to be fixed.
 +     * the following tests fail:
 +     * bethsoft-vid, cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
 +     */
 +    memset(buf->base[0], 128, ret);
 +
 +    avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
 +    for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
 +        const int h_shift = i==0 ? 0 : h_chroma_shift;
 +        const int v_shift = i==0 ? 0 : v_chroma_shift;
 +        if (s->flags & CODEC_FLAG_EMU_EDGE)
 +            buf->data[i] = buf->base[i];
 +        else
 +            buf->data[i] = buf->base[i] +
 +                           FFALIGN((buf->linesize[i]*edge >> v_shift) +
 +                                   (pixel_size*edge >> h_shift), 32);
 +    }
 +    buf->w       = s->width;
 +    buf->h       = s->height;
 +    buf->pix_fmt = s->pix_fmt;
 +    buf->ist     = ist;
 +
 +    *pbuf = buf;
 +    return 0;
 +}
 +
 +static void free_buffer_pool(InputStream *ist)
 +{
 +    FrameBuffer *buf = ist->buffer_pool;
 +    while (buf) {
 +        ist->buffer_pool = buf->next;
 +        av_freep(&buf->base[0]);
 +        av_free(buf);
 +        buf = ist->buffer_pool;
 +    }
 +}
 +
 +static void unref_buffer(InputStream *ist, FrameBuffer *buf)
 +{
 +    av_assert0(buf->refcount);
 +    buf->refcount--;
 +    if (!buf->refcount) {
 +        buf->next = ist->buffer_pool;
 +        ist->buffer_pool = buf;
 +    }
 +}
 +
 +static int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
 +{
 +    InputStream *ist = s->opaque;
 +    FrameBuffer *buf;
 +    int ret, i;
 +
 +    if (!ist->buffer_pool && (ret = alloc_buffer(ist, &ist->buffer_pool)) < 0)
 +        return ret;
 +
 +    buf              = ist->buffer_pool;
 +    ist->buffer_pool = buf->next;
 +    buf->next        = NULL;
 +    if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) {
 +        av_freep(&buf->base[0]);
 +        av_free(buf);
 +        ist->dr1 = 0;
 +        if ((ret = alloc_buffer(ist, &buf)) < 0)
 +            return ret;
 +    }
 +    buf->refcount++;
 +
 +    frame->opaque        = buf;
 +    frame->type          = FF_BUFFER_TYPE_USER;
 +    frame->extended_data = frame->data;
 +    frame->pkt_pts       = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE;
 +
 +    for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
 +        frame->base[i]     = buf->base[i];  // XXX h264.c uses base though it shouldn't
 +        frame->data[i]     = buf->data[i];
 +        frame->linesize[i] = buf->linesize[i];
 +    }
 +
 +    return 0;
 +}
 +
 +static void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
 +{
 +    InputStream *ist = s->opaque;
 +    FrameBuffer *buf = frame->opaque;
 +    int i;
 +
 +    if(frame->type!=FF_BUFFER_TYPE_USER)
 +        return avcodec_default_release_buffer(s, frame);
 +
 +    for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
 +        frame->data[i] = NULL;
 +
 +    unref_buffer(ist, buf);
 +}
 +
 +static void filter_release_buffer(AVFilterBuffer *fb)
 +{
 +    FrameBuffer *buf = fb->priv;
 +    av_free(fb);
 +    unref_buffer(buf->ist, buf);
 +}
 +
  #if CONFIG_AVFILTER
  
  static int configure_video_filters(InputStream *ist, OutputStream *ost)
  
      ost->graph = avfilter_graph_alloc();
  
--    if (ist->st->sample_aspect_ratio.num){
++    if (ist->st->sample_aspect_ratio.num) {
          sample_aspect_ratio = ist->st->sample_aspect_ratio;
--    }else
++    } else
          sample_aspect_ratio = ist->st->codec->sample_aspect_ratio;
  
      snprintf(args, 255, "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
          return ret;
      last_filter = ost->input_video_filter;
  
--    if (codec->width  != icodec->width || codec->height != icodec->height) {
++    if (codec->width != icodec->width || codec->height != icodec->height) {
          snprintf(args, 255, "%d:%d:flags=0x%X",
                   codec->width,
                   codec->height,
      codec->width  = ost->output_video_filter->inputs[0]->w;
      codec->height = ost->output_video_filter->inputs[0]->h;
      codec->sample_aspect_ratio = ost->st->sample_aspect_ratio =
 -        ost->frame_aspect_ratio ? // overriden by the -aspect cli option
 -        av_d2q(ost->frame_aspect_ratio*codec->height/codec->width, 255) :
 +        ost->frame_aspect_ratio ? // overridden by the -aspect cli option
-         av_d2q(ost->frame_aspect_ratio*codec->height/codec->width, 255) :
++        av_d2q(ost->frame_aspect_ratio * codec->height/codec->width, 255) :
          ost->output_video_filter->inputs[0]->sample_aspect_ratio;
  
      return 0;
@@@ -709,30 -434,7 +709,30 @@@ static void sigterm_handler(int sig
  
  static void term_init(void)
  {
 -    signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).  */
 +#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
 +    avformat_network_deinit();
 +
-     signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).  */
++    signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
      signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
  #ifdef SIGXCPU
      signal(SIGXCPU, sigterm_handler);
@@@ -805,22 -451,22 +805,22 @@@ void av_noreturn exit_program(int ret
      int i;
  
      /* close files */
--    for(i=0;i<nb_output_files;i++) {
 -        AVFormatContext *s = output_files[i];
++    for (i = 0; i < nb_output_files; i++) {
 +        AVFormatContext *s = output_files[i].ctx;
          if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
              avio_close(s->pb);
          avformat_free_context(s);
 -        av_free(output_streams_for_file[i]);
 -        av_dict_free(&output_opts[i]);
 +        av_dict_free(&output_files[i].opts);
      }
--    for(i=0;i<nb_input_files;i++) {
 -        av_close_input_file(input_files[i].ctx);
++    for (i = 0; i < nb_input_files; i++) {
 +        avformat_close_input(&input_files[i].ctx);
      }
 -    for (i = 0; i < nb_input_streams; i++)
 +    for (i = 0; i < nb_input_streams; i++) {
 +        av_freep(&input_streams[i].decoded_frame);
 +        av_freep(&input_streams[i].filtered_frame);
          av_dict_free(&input_streams[i].opts);
 -
 -    av_free(intra_matrix);
 -    av_free(inter_matrix);
 +        free_buffer_pool(&input_streams[i]);
 +    }
  
      if (vstats_file)
          fclose(vstats_file);
      uninit_opts();
      av_free(audio_buf);
      av_free(audio_out);
--    allocated_audio_buf_size= allocated_audio_out_size= 0;
 -    av_free(samples);
++    allocated_audio_buf_size = allocated_audio_out_size = 0;
  
  #if CONFIG_AVFILTER
      avfilter_uninit();
@@@ -880,10 -533,10 +880,10 @@@ static void assert_codec_experimental(A
  
  static void choose_sample_fmt(AVStream *st, AVCodec *codec)
  {
--    if(codec && codec->sample_fmts){
--        const enum AVSampleFormat *p= codec->sample_fmts;
--        for(; *p!=-1; p++){
--            if(*p == st->codec->sample_fmt)
++    if (codec && codec->sample_fmts) {
++        const enum AVSampleFormat *p = codec->sample_fmts;
++        for (; *p != -1; p++) {
++            if (*p == st->codec->sample_fmt)
                  break;
          }
          if (*p == -1) {
      }
  }
  
 -/**
 - * 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){
--        const int *p= codec->supported_samplerates;
--        int best=0;
--        int best_dist=INT_MAX;
--        for(; *p; p++){
--            int dist= abs(st->codec->sample_rate - *p);
--            if(dist < best_dist){
--                best_dist= dist;
--                best= *p;
++    if (codec && codec->supported_samplerates) {
++        const int *p  = codec->supported_samplerates;
++        int best      = 0;
++        int best_dist = INT_MAX;
++        for (; *p; p++) {
++            int dist = abs(st->codec->sample_rate - *p);
++            if (dist < best_dist) {
++                best_dist = dist;
++                best      = *p;
              }
          }
--        if(best_dist){
++        if (best_dist) {
              av_log(st->codec, AV_LOG_WARNING, "Requested sampling rate unsupported using closest supported (%d)\n", best);
          }
--        st->codec->sample_rate= best;
++        st->codec->sample_rate = best;
      }
  }
  
  static void choose_pixel_fmt(AVStream *st, AVCodec *codec)
  {
--    if(codec && codec->pix_fmts){
--        const enum PixelFormat *p= codec->pix_fmts;
 -        if(st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL){
 -            if(st->codec->codec_id==CODEC_ID_MJPEG){
 -                p= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE};
 -            }else if(st->codec->codec_id==CODEC_ID_LJPEG){
 -                p= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ444P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_BGRA, PIX_FMT_NONE};
++    if (codec && codec->pix_fmts) {
++        const enum PixelFormat *p = codec->pix_fmts;
 +        int has_alpha= av_pix_fmt_descriptors[st->codec->pix_fmt].nb_components % 2 == 0;
 +        enum PixelFormat best= PIX_FMT_NONE;
-         if(st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL){
-             if(st->codec->codec_id==CODEC_ID_MJPEG){
-                 p= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE};
-             }else if(st->codec->codec_id==CODEC_ID_LJPEG){
-                 p= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ444P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_BGRA, PIX_FMT_NONE};
++        if (st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
++            if (st->codec->codec_id == CODEC_ID_MJPEG) {
++                p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE };
++            } else if (st->codec->codec_id == CODEC_ID_LJPEG) {
++                p = (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ444P, PIX_FMT_YUV420P,
++                                                 PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_BGRA, PIX_FMT_NONE };
              }
          }
 -        for(; *p!=-1; p++){
 -            if(*p == st->codec->pix_fmt)
 +        for (; *p != PIX_FMT_NONE; p++) {
 +            best= avcodec_find_best_pix_fmt2(best, *p, st->codec->pix_fmt, has_alpha, NULL);
-             if(*p == st->codec->pix_fmt)
++            if (*p == st->codec->pix_fmt)
                  break;
          }
 -        if (*p == -1) {
 -            if(st->codec->pix_fmt != PIX_FMT_NONE)
 +        if (*p == PIX_FMT_NONE) {
-             if(st->codec->pix_fmt != PIX_FMT_NONE)
++            if (st->codec->pix_fmt != PIX_FMT_NONE)
                  av_log(NULL, AV_LOG_WARNING,
--                        "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
--                        av_pix_fmt_descriptors[st->codec->pix_fmt].name,
--                        codec->name,
-                         av_pix_fmt_descriptors[best].name);
 -                        av_pix_fmt_descriptors[codec->pix_fmts[0]].name);
 -            st->codec->pix_fmt = codec->pix_fmts[0];
 -        }
 -    }
 -}
 -
 -static OutputStream *new_output_stream(AVFormatContext *oc, int file_idx, AVCodec *codec)
 -{
 -    OutputStream *ost;
 -    AVStream *st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);
 -    int idx      = oc->nb_streams - 1;
 -
 -    if (!st) {
 -        av_log(NULL, AV_LOG_ERROR, "Could not alloc stream.\n");
 -        exit_program(1);
 -    }
 -
 -    output_streams_for_file[file_idx] =
 -        grow_array(output_streams_for_file[file_idx],
 -                   sizeof(*output_streams_for_file[file_idx]),
 -                   &nb_output_streams_for_file[file_idx],
 -                   oc->nb_streams);
 -    ost = output_streams_for_file[file_idx][idx] =
 -        av_mallocz(sizeof(OutputStream));
 -    if (!ost) {
 -        fprintf(stderr, "Could not alloc output stream\n");
 -        exit_program(1);
 -    }
 -    ost->file_index = file_idx;
 -    ost->index = idx;
 -    ost->st    = st;
 -    ost->enc   = codec;
 -    if (codec)
 -        ost->opts  = filter_codec_opts(codec_opts, codec->id, oc, st);
 -
 -    avcodec_get_context_defaults3(st->codec, codec);
 -
 -    ost->sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
 -    return ost;
 -}
 -
 -static int read_avserver_streams(AVFormatContext *s, const char *filename)
 -{
 -    int i, err;
 -    AVFormatContext *ic = NULL;
 -
 -    err = avformat_open_input(&ic, filename, NULL, NULL);
 -    if (err < 0)
 -        return err;
 -    /* copy stream format */
 -    for(i=0;i<ic->nb_streams;i++) {
 -        AVStream *st;
 -        OutputStream *ost;
 -        AVCodec *codec;
 -
 -        codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
 -        ost   = new_output_stream(s, nb_output_files, codec);
 -        st    = ost->st;
 -
 -        // FIXME: a more elegant solution is needed
 -        memcpy(st, ic->streams[i], sizeof(AVStream));
 -        st->info = NULL;
 -        avcodec_copy_context(st->codec, ic->streams[i]->codec);
 -
 -        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
 -            if (audio_stream_copy) {
 -                st->stream_copy = 1;
 -            } else
 -                choose_sample_fmt(st, codec);
 -        } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 -            if (video_stream_copy) {
 -                st->stream_copy = 1;
 -            } else
 -                choose_pixel_fmt(st, codec);
++                       "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
++                       av_pix_fmt_descriptors[st->codec->pix_fmt].name,
++                       codec->name,
++                       av_pix_fmt_descriptors[best].name);
 +            st->codec->pix_fmt = best;
          }
      }
 -
 -    av_close_input_file(ic);
 -    return 0;
  }
  
 -static double
 -get_sync_ipts(const OutputStream *ost)
 +static double get_sync_ipts(const OutputStream *ost)
  {
      const InputStream *ist = ost->sync_ist;
 -    return (double)(ist->pts - start_time)/AV_TIME_BASE;
 +    OutputFile *of = &output_files[ost->file_index];
-     return (double)(ist->pts - of->start_time)/AV_TIME_BASE;
++    return (double)(ist->pts - of->start_time) / AV_TIME_BASE;
  }
  
 -static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx, AVBitStreamFilterContext *bsfc){
 +static void write_frame(AVFormatContext *s, AVPacket *pkt, AVCodecContext *avctx, AVBitStreamFilterContext *bsfc)
 +{
      int ret;
  
--    while(bsfc){
--        AVPacket new_pkt= *pkt;
--        int a= av_bitstream_filter_filter(bsfc, avctx, NULL,
--                                          &new_pkt.data, &new_pkt.size,
--                                          pkt->data, pkt->size,
--                                          pkt->flags & AV_PKT_FLAG_KEY);
--        if(a>0){
++    while (bsfc) {
++        AVPacket new_pkt = *pkt;
++        int a = av_bitstream_filter_filter(bsfc, avctx, NULL,
++                                           &new_pkt.data, &new_pkt.size,
++                                           pkt->data, pkt->size,
++                                           pkt->flags & AV_PKT_FLAG_KEY);
++        if (a > 0) {
              av_free_packet(pkt);
--            new_pkt.destruct= av_destruct_packet;
--        } else if(a<0){
 -            fprintf(stderr, "%s failed for stream %d, codec %s",
 -                    bsfc->filter->name, pkt->stream_index,
 -                    avctx->codec ? avctx->codec->name : "copy");
++            new_pkt.destruct = av_destruct_packet;
++        } else if (a < 0) {
 +            av_log(NULL, AV_LOG_ERROR, "%s failed for stream %d, codec %s",
 +                   bsfc->filter->name, pkt->stream_index,
 +                   avctx->codec ? avctx->codec->name : "copy");
              print_error("", a);
              if (exit_on_error)
                  exit_program(1);
          }
--        *pkt= new_pkt;
++        *pkt = new_pkt;
  
--        bsfc= bsfc->next;
++        bsfc = bsfc->next;
      }
  
--    ret= av_interleaved_write_frame(s, pkt);
--    if(ret < 0){
++    ret = av_interleaved_write_frame(s, pkt);
++    if (ret < 0) {
          print_error("av_interleaved_write_frame()", ret);
          exit_program(1);
      }
@@@ -1003,38 -760,36 +1004,38 @@@ static void do_audio_out(AVFormatContex
  {
      uint8_t *buftmp;
      int64_t audio_out_size, audio_buf_size;
 -    int64_t allocated_for_size= size;
  
      int size_out, frame_bytes, ret, resample_changed;
--    AVCodecContext *enc= ost->st->codec;
--    AVCodecContext *dec= ist->st->codec;
++    AVCodecContext *enc = ost->st->codec;
++    AVCodecContext *dec = ist->st->codec;
      int osize = av_get_bytes_per_sample(enc->sample_fmt);
      int isize = av_get_bytes_per_sample(dec->sample_fmt);
      const int coded_bps = av_get_bits_per_sample(enc->codec->id);
 +    uint8_t *buf = decoded_frame->data[0];
 +    int size     = decoded_frame->nb_samples * dec->channels * isize;
 +    int64_t allocated_for_size = size;
  
  need_realloc:
--    audio_buf_size= (allocated_for_size + isize*dec->channels - 1) / (isize*dec->channels);
--    audio_buf_size= (audio_buf_size*enc->sample_rate + dec->sample_rate) / dec->sample_rate;
--    audio_buf_size= audio_buf_size*2 + 10000; //safety factors for the deprecated resampling API
--    audio_buf_size= FFMAX(audio_buf_size, enc->frame_size);
--    audio_buf_size*= osize*enc->channels;
--
--    audio_out_size= FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels);
--    if(coded_bps > 8*osize)
--        audio_out_size= audio_out_size * coded_bps / (8*osize);
++    audio_buf_size  = (allocated_for_size + isize * dec->channels - 1) / (isize * dec->channels);
++    audio_buf_size  = (audio_buf_size * enc->sample_rate + dec->sample_rate) / dec->sample_rate;
++    audio_buf_size  = audio_buf_size * 2 + 10000; // safety factors for the deprecated resampling API
++    audio_buf_size  = FFMAX(audio_buf_size, enc->frame_size);
++    audio_buf_size *= osize * enc->channels;
++
++    audio_out_size = FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels);
++    if (coded_bps > 8 * osize)
++        audio_out_size = audio_out_size * coded_bps / (8*osize);
      audio_out_size += FF_MIN_BUFFER_SIZE;
  
--    if(audio_out_size > INT_MAX || audio_buf_size > INT_MAX){
 -        fprintf(stderr, "Buffer sizes too large\n");
++    if (audio_out_size > INT_MAX || audio_buf_size > INT_MAX) {
 +        av_log(NULL, AV_LOG_FATAL, "Buffer sizes too large\n");
          exit_program(1);
      }
  
      av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size);
      av_fast_malloc(&audio_out, &allocated_audio_out_size, audio_out_size);
--    if (!audio_buf || !audio_out){
 -        fprintf(stderr, "Out of memory in do_audio_out\n");
++    if (!audio_buf || !audio_out) {
 +        av_log(NULL, AV_LOG_FATAL, "Out of memory in do_audio_out\n");
          exit_program(1);
      }
  
          }
      }
  
 -#define MAKE_SFMT_PAIR(a,b) ((a)+AV_SAMPLE_FMT_NB*(b))
 -    if (!ost->audio_resample && dec->sample_fmt!=enc->sample_fmt &&
 -        MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt)!=ost->reformat_pair) {
 -        if (ost->reformat_ctx)
 -            av_audio_convert_free(ost->reformat_ctx);
 -        ost->reformat_ctx = av_audio_convert_alloc(enc->sample_fmt, 1,
 -                                                   dec->sample_fmt, 1, NULL, 0);
 -        if (!ost->reformat_ctx) {
 -            fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",
 -                av_get_sample_fmt_name(dec->sample_fmt),
 -                av_get_sample_fmt_name(enc->sample_fmt));
 -            exit_program(1);
 -        }
 -        ost->reformat_pair=MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt);
 -    }
 +    av_assert0(ost->audio_resample || dec->sample_fmt==enc->sample_fmt);
  
--    if(audio_sync_method){
--        double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts
-                 - av_fifo_size(ost->fifo)/(enc->channels * osize);
 -                - av_fifo_size(ost->fifo)/(enc->channels * 2);
 -        double idelta= delta*dec->sample_rate / enc->sample_rate;
 -        int byte_delta= ((int)idelta)*2*dec->channels;
++    if (audio_sync_method) {
++        double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts -
++                       av_fifo_size(ost->fifo) / (enc->channels * osize);
 +        int idelta = delta * dec->sample_rate / enc->sample_rate;
 +        int byte_delta = idelta * isize * dec->channels;
  
--        //FIXME resample delay
--        if(fabs(delta) > 50){
--            if(ist->is_start || fabs(delta) > audio_drift_threshold*enc->sample_rate){
--                if(byte_delta < 0){
--                    byte_delta= FFMAX(byte_delta, -size);
++        // FIXME resample delay
++        if (fabs(delta) > 50) {
++            if (ist->is_start || fabs(delta) > audio_drift_threshold*enc->sample_rate) {
++                if (byte_delta < 0) {
++                    byte_delta = FFMAX(byte_delta, -size);
                      size += byte_delta;
                      buf  -= byte_delta;
 -                    if(verbose > 2)
 -                        fprintf(stderr, "discarding %d audio samples\n", (int)-delta);
 -                    if(!size)
 +                    av_log(NULL, AV_LOG_VERBOSE, "discarding %d audio samples\n",
 +                           -byte_delta / (isize * dec->channels));
-                     if(!size)
++                    if (!size)
                          return;
--                    ist->is_start=0;
--                }else{
 -                    static uint8_t *input_tmp= NULL;
--                    input_tmp= av_realloc(input_tmp, byte_delta + size);
++                    ist->is_start = 0;
++                } else {
++                    input_tmp = av_realloc(input_tmp, byte_delta + size);
  
--                    if(byte_delta > allocated_for_size - size){
--                        allocated_for_size= byte_delta + (int64_t)size;
++                    if (byte_delta > allocated_for_size - size) {
++                        allocated_for_size = byte_delta + (int64_t)size;
                          goto need_realloc;
                      }
--                    ist->is_start=0;
++                    ist->is_start = 0;
  
 -                    memset(input_tmp, 0, byte_delta);
 +                    generate_silence(input_tmp, dec->sample_fmt, byte_delta);
                      memcpy(input_tmp + byte_delta, buf, size);
--                    buf= input_tmp;
++                    buf = input_tmp;
                      size += byte_delta;
 -                    if(verbose > 2)
 -                        fprintf(stderr, "adding %d audio samples of silence\n", (int)delta);
 +                    av_log(NULL, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", idelta);
                  }
--            }else if(audio_sync_method>1){
--                int comp= av_clip(delta, -audio_sync_method, audio_sync_method);
++            } else if (audio_sync_method > 1) {
++                int comp = av_clip(delta, -audio_sync_method, audio_sync_method);
                  av_assert0(ost->audio_resample);
 -                if(verbose > 2)
 -                    fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);
 +                av_log(NULL, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n",
 +                       delta, comp, enc->sample_rate);
  //                fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));
 -                av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);
 +                swr_compensate(ost->swr, comp, enc->sample_rate);
              }
          }
--    }else
--        ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate)
-                         - av_fifo_size(ost->fifo)/(enc->channels * osize); //FIXME wrong
 -                        - av_fifo_size(ost->fifo)/(enc->channels * 2); //FIXME wrong
++    } else
++        ost->sync_opts = lrintf(get_sync_ipts(ost) * enc->sample_rate) -
++                                av_fifo_size(ost->fifo) / (enc->channels * osize); // FIXME wrong
  
      if (ost->audio_resample) {
          buftmp = audio_buf;
  
              av_fifo_generic_read(ost->fifo, audio_buf, frame_bytes, NULL);
  
--            //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
++            // FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
  
              ret = avcodec_encode_audio(enc, audio_out, audio_out_size,
                                         (short *)audio_buf);
                  exit_program(1);
              }
              audio_size += ret;
--            pkt.stream_index= ost->index;
--            pkt.data= audio_out;
--            pkt.size= ret;
--            if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
--                pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
++            pkt.stream_index = ost->index;
++            pkt.data = audio_out;
++            pkt.size = ret;
++            if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
++                pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
              pkt.flags |= AV_PKT_FLAG_KEY;
              write_frame(s, &pkt, enc, ost->bitstream_filters);
  
          /* determine the size of the coded buffer */
          size_out /= osize;
          if (coded_bps)
--            size_out = size_out*coded_bps/8;
++            size_out = size_out * coded_bps / 8;
  
--        if(size_out > audio_out_size){
 -            fprintf(stderr, "Internal error, buffer size too small\n");
++        if (size_out > audio_out_size) {
 +            av_log(NULL, AV_LOG_FATAL, "Internal error, buffer size too small\n");
              exit_program(1);
          }
  
--        //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
++        // FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()
          ret = avcodec_encode_audio(enc, audio_out, size_out,
                                     (short *)buftmp);
          if (ret < 0) {
              exit_program(1);
          }
          audio_size += ret;
--        pkt.stream_index= ost->index;
--        pkt.data= audio_out;
--        pkt.size= ret;
--        if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
--            pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
++        pkt.stream_index = ost->index;
++        pkt.data = audio_out;
++        pkt.size = ret;
++        if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
++            pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
          pkt.flags |= AV_PKT_FLAG_KEY;
          write_frame(s, &pkt, enc, ost->bitstream_filters);
      }
@@@ -1241,17 -1012,17 +1242,17 @@@ static void pre_process_video_frame(Inp
  
          /* create temporary picture */
          size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);
--        buf = av_malloc(size);
++        buf  = av_malloc(size);
          if (!buf)
              return;
  
          picture2 = &picture_tmp;
          avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height);
  
--        if(avpicture_deinterlace(picture2, picture,
++        if (avpicture_deinterlace(picture2, picture,
                                   dec->pix_fmt, dec->width, dec->height) < 0) {
              /* if error, do not deinterlace */
 -            fprintf(stderr, "Deinterlacing failed\n");
 +            av_log(NULL, AV_LOG_WARNING, "Deinterlacing failed\n");
              av_free(buf);
              buf = NULL;
              picture2 = picture;
@@@ -1298,11 -1072,11 +1299,11 @@@ static void do_subtitle_out(AVFormatCon
      else
          nb = 1;
  
--    for(i = 0; i < nb; i++) {
++    for (i = 0; i < nb; i++) {
          sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q);
          // start_display_time is required to be 0
--        sub->pts              += av_rescale_q(sub->start_display_time, (AVRational){1, 1000}, AV_TIME_BASE_Q);
--        sub->end_display_time -= sub->start_display_time;
++        sub->pts               += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q);
++        sub->end_display_time  -= sub->start_display_time;
          sub->start_display_time = 0;
          subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out,
                                                      subtitle_out_max_size, sub);
          pkt.stream_index = ost->index;
          pkt.data = subtitle_out;
          pkt.size = subtitle_out_size;
--        pkt.pts = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base);
++        pkt.pts  = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base);
          if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) {
              /* XXX: the pts correction is handled here. Maybe handling
                 it in the codec would be better */
      }
  }
  
--static int bit_buffer_size= 1024*256;
--static uint8_t *bit_buffer= NULL;
++static int bit_buffer_size = 1024 * 256;
++static uint8_t *bit_buffer = NULL;
  
 -static void do_video_out(AVFormatContext *s,
 -                         OutputStream *ost,
 -                         InputStream *ist,
 -                         AVFrame *in_picture,
 -                         int *frame_size, float quality)
 +static void do_video_resample(OutputStream *ost,
 +                              InputStream *ist,
 +                              AVFrame *in_picture,
 +                              AVFrame **out_picture)
  {
 -    int nb_frames, i, ret, resample_changed;
 -    AVFrame *final_picture, *formatted_picture;
 -    AVCodecContext *enc, *dec;
 -    double sync_ipts;
 +#if CONFIG_AVFILTER
 +    *out_picture = in_picture;
 +#else
 +    AVCodecContext *dec = ist->st->codec;
 +    AVCodecContext *enc = ost->st->codec;
 +    int resample_changed = ost->resample_width   != dec->width  ||
 +                           ost->resample_height  != dec->height ||
 +                           ost->resample_pix_fmt != dec->pix_fmt;
  
 -    enc = ost->st->codec;
 -    dec = ist->st->codec;
 +    *out_picture = in_picture;
 +    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));
 +        ost->resample_width   = dec->width;
 +        ost->resample_height  = dec->height;
 +        ost->resample_pix_fmt = dec->pix_fmt;
 +    }
 +
 +    ost->video_resample = dec->width   != enc->width  ||
 +                          dec->height  != enc->height ||
 +                          dec->pix_fmt != enc->pix_fmt;
 +
 +    if (ost->video_resample) {
 +        *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)) {
 +                    av_log(NULL, AV_LOG_FATAL, "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(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) {
 +                av_log(NULL, AV_LOG_FATAL, "Cannot get resampling context\n");
 +                exit_program(1);
 +            }
 +        }
 +        sws_scale(ost->img_resample_ctx, in_picture->data, in_picture->linesize,
 +              0, ost->resample_height, (*out_picture)->data, (*out_picture)->linesize);
 +    }
 +#endif
 +}
 +
 +
 +static void do_video_out(AVFormatContext *s,
 +                         OutputStream *ost,
 +                         InputStream *ist,
 +                         AVFrame *in_picture,
 +                         int *frame_size, float quality)
 +{
 +    int nb_frames, i, ret, format_video_sync;
 +    AVFrame *final_picture;
 +    AVCodecContext *enc;
 +    double sync_ipts;
 +    double duration = 0;
 +
 +    enc = ost->st->codec;
 +
 +    if (ist->st->start_time != AV_NOPTS_VALUE && ist->st->first_dts != AV_NOPTS_VALUE) {
 +        duration = FFMAX(av_q2d(ist->st->time_base), av_q2d(ist->st->codec->time_base));
 +        if(ist->st->avg_frame_rate.num)
 +            duration= FFMAX(duration, 1/av_q2d(ist->st->avg_frame_rate));
 +
 +        duration /= av_q2d(enc->time_base);
 +    }
  
      sync_ipts = get_sync_ipts(ost) / av_q2d(enc->time_base);
  
  
      *frame_size = 0;
  
 -    if(video_sync_method){
 -        double vdelta = sync_ipts - ost->sync_opts;
 -        //FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
 +    format_video_sync = video_sync_method;
 +    if (format_video_sync < 0)
 +        format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? 0 : 2) : 1;
 +
 +    if (format_video_sync) {
 +        double vdelta = sync_ipts - ost->sync_opts + duration;
-         //FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
++        // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
          if (vdelta < -1.1)
              nb_frames = 0;
 -        else if (video_sync_method == 2 || (video_sync_method<0 && (s->oformat->flags & AVFMT_VARIABLE_FPS))){
 -            if(vdelta<=-0.6){
 -                nb_frames=0;
 -            }else if(vdelta>0.6)
 -                ost->sync_opts= lrintf(sync_ipts);
 -        }else if (vdelta > 1.1)
 +        else if (format_video_sync == 2) {
-             if(vdelta<=-0.6){
-                 nb_frames=0;
-             }else if(vdelta>0.6)
-                 ost->sync_opts= lrintf(sync_ipts);
-         }else if (vdelta > 1.1)
++            if (vdelta <= -0.6) {
++                nb_frames = 0;
++            } else if (vdelta > 0.6)
++                ost->sync_opts = lrintf(sync_ipts);
++        } else if (vdelta > 1.1)
              nb_frames = lrintf(vdelta);
  //fprintf(stderr, "vdelta:%f, ost->sync_opts:%"PRId64", ost->sync_ipts:%f nb_frames:%d\n", vdelta, ost->sync_opts, get_sync_ipts(ost), nb_frames);
--        if (nb_frames == 0){
++        if (nb_frames == 0) {
              ++nb_frames_drop;
 -            if (verbose>2)
 -                fprintf(stderr, "*** drop!\n");
 -        }else if (nb_frames > 1) {
 +            av_log(NULL, AV_LOG_VERBOSE, "*** drop!\n");
-         }else if (nb_frames > 1) {
++        } else if (nb_frames > 1) {
              nb_frames_dup += nb_frames - 1;
-             av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames-1);
 -            if (verbose>2)
 -                fprintf(stderr, "*** %d dup!\n", nb_frames-1);
++            av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1);
          }
--    }else
--        ost->sync_opts= lrintf(sync_ipts);
++    } else
++        ost->sync_opts = lrintf(sync_ipts);
  
 -    nb_frames= FFMIN(nb_frames, max_frames[AVMEDIA_TYPE_VIDEO] - ost->frame_number);
 +    nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
      if (nb_frames <= 0)
          return;
  
 -    formatted_picture = in_picture;
 -    final_picture = formatted_picture;
 -
 -    resample_changed = ost->resample_width   != dec->width  ||
 -                       ost->resample_height  != dec->height ||
 -                       ost->resample_pix_fmt != dec->pix_fmt;
 -
 -    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)
 -            exit_program(1);
 -    }
 -
 -#if !CONFIG_AVFILTER
 -    if (ost->video_resample) {
 -        final_picture = &ost->pict_tmp;
 -        if (resample_changed) {
 -            /* 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);
 -            if (ost->img_resample_ctx == NULL) {
 -                fprintf(stderr, "Cannot get resampling context\n");
 -                exit_program(1);
 -            }
 -        }
 -        sws_scale(ost->img_resample_ctx, formatted_picture->data, formatted_picture->linesize,
 -              0, ost->resample_height, final_picture->data, final_picture->linesize);
 -    }
 -#endif
 +    do_video_resample(ost, ist, in_picture, &final_picture);
  
      /* duplicates frame if needed */
--    for(i=0;i<nb_frames;i++) {
++    for (i = 0; i < nb_frames; i++) {
          AVPacket pkt;
          av_init_packet(&pkt);
--        pkt.stream_index= ost->index;
++        pkt.stream_index = ost->index;
  
 -        if (s->oformat->flags & AVFMT_RAWPICTURE) {
 +        if (s->oformat->flags & AVFMT_RAWPICTURE &&
 +            enc->codec->id == CODEC_ID_RAWVIDEO) {
              /* raw pictures are written as AVPicture structure to
 -               avoid any copies. We support temorarily the older
 +               avoid any copies. We support temporarily the older
                 method. */
 -            AVFrame* old_frame = enc->coded_frame;
 -            enc->coded_frame = dec->coded_frame; //FIXME/XXX remove this hack
 -            pkt.data= (uint8_t *)final_picture;
 -            pkt.size=  sizeof(AVPicture);
 -            pkt.pts= av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base);
 +            enc->coded_frame->interlaced_frame = in_picture->interlaced_frame;
 +            enc->coded_frame->top_field_first  = in_picture->top_field_first;
-             pkt.data= (uint8_t *)final_picture;
-             pkt.size=  sizeof(AVPicture);
-             pkt.pts= av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base);
++            pkt.data   = (uint8_t *)final_picture;
++            pkt.size   =  sizeof(AVPicture);
++            pkt.pts    = av_rescale_q(ost->sync_opts, enc->time_base, ost->st->time_base);
              pkt.flags |= AV_PKT_FLAG_KEY;
  
              write_frame(s, &pkt, ost->st->codec, ost->bitstream_filters);
          } else {
              AVFrame big_picture;
  
--            big_picture= *final_picture;
++            big_picture = *final_picture;
              /* better than nothing: use input picture interlaced
                 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 sameq here. This is not correct because it may
 +            /* 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;
++            big_picture.pts = ost->sync_opts;
  //            big_picture.pts= av_rescale(ost->sync_opts, AV_TIME_BASE*(int64_t)enc->time_base.num, enc->time_base.den);
--//av_log(NULL, AV_LOG_DEBUG, "%"PRId64" -> encoder\n", ost->sync_opts);
++// av_log(NULL, AV_LOG_DEBUG, "%"PRId64" -> encoder\n", ost->sync_opts);
              if (ost->forced_kf_index < ost->forced_kf_count &&
                  big_picture.pts >= ost->forced_kf_pts[ost->forced_kf_index]) {
                  big_picture.pict_type = AV_PICTURE_TYPE_I;
                  exit_program(1);
              }
  
--            if(ret>0){
--                pkt.data= bit_buffer;
--                pkt.size= ret;
--                if(enc->coded_frame->pts != AV_NOPTS_VALUE)
--                    pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
++            if (ret > 0) {
++                pkt.data = bit_buffer;
++                pkt.size = ret;
++                if (enc->coded_frame->pts != AV_NOPTS_VALUE)
++                    pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
  /*av_log(NULL, AV_LOG_DEBUG, "encoder -> %"PRId64"/%"PRId64"\n",
     pkt.pts != AV_NOPTS_VALUE ? av_rescale(pkt.pts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1,
     pkt.dts != AV_NOPTS_VALUE ? av_rescale(pkt.dts, enc->time_base.den, AV_TIME_BASE*(int64_t)enc->time_base.num) : -1);*/
  
--                if(enc->coded_frame->key_frame)
++                if (enc->coded_frame->key_frame)
                      pkt.flags |= AV_PKT_FLAG_KEY;
                  write_frame(s, &pkt, ost->st->codec, ost->bitstream_filters);
                  *frame_size = ret;
                  video_size += ret;
--                //fprintf(stderr,"\nFrame: %3d size: %5d type: %d",
--                //        enc->frame_number-1, ret, enc->pict_type);
++                // fprintf(stderr,"\nFrame: %3d size: %5d type: %d",
++                //         enc->frame_number-1, ret, enc->pict_type);
                  /* if two pass, output log */
                  if (ost->logfile && enc->stats_out) {
                      fprintf(ost->logfile, "%s", enc->stats_out);
      }
  }
  
 -static double psnr(double d){
 -    return -10.0*log(d)/log(10.0);
 +static double psnr(double d)
 +{
-     return -10.0*log(d)/log(10.0);
++    return -10.0 * log(d) / log(10.0);
  }
  
  static void do_video_stats(AVFormatContext *os, OutputStream *ost,
      enc = ost->st->codec;
      if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
          frame_number = ost->frame_number;
--        fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality/(float)FF_QP2LAMBDA);
++        fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, enc->coded_frame->quality / (float)FF_QP2LAMBDA);
          if (enc->flags&CODEC_FLAG_PSNR)
--            fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0]/(enc->width*enc->height*255.0*255.0)));
++            fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0] / (enc->width * enc->height * 255.0 * 255.0)));
  
          fprintf(vstats_file,"f_size= %6d ", frame_size);
          /* compute pts value */
          if (ti1 < 0.01)
              ti1 = 0.01;
  
--        bitrate = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0;
++        bitrate     = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0;
          avg_bitrate = (double)(video_size * 8) / ti1 / 1000.0;
          fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
--            (double)video_size / 1024, ti1, bitrate, avg_bitrate);
++               (double)video_size / 1024, ti1, bitrate, avg_bitrate);
          fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(enc->coded_frame->pict_type));
      }
  }
@@@ -1606,23 -1347,21 +1607,23 @@@ static void print_report(OutputFile *ou
      }
  
  
 -    oc = output_files[0];
 +    oc = output_files[0].ctx;
  
      total_size = avio_size(oc->pb);
 -    if(total_size<0) // FIXME improve avio_size() so it works with non seekable output too
 -        total_size= avio_tell(oc->pb);
 +    if (total_size < 0) { // FIXME improve avio_size() so it works with non seekable output too
-         total_size= avio_tell(oc->pb);
++        total_size = avio_tell(oc->pb);
 +        if (total_size < 0)
 +            total_size = 0;
 +    }
  
      buf[0] = '\0';
 -    ti1 = 1e10;
      vid = 0;
--    for(i=0;i<nb_ostreams;i++) {
++    for (i = 0; i < nb_ostreams; i++) {
          float q = -1;
 -        ost = ost_table[i];
 +        ost = &ost_table[i];
          enc = ost->st->codec;
 -        if (!ost->st->stream_copy && enc->coded_frame)
 -            q = enc->coded_frame->quality/(float)FF_QP2LAMBDA;
 +        if (!ost->stream_copy && enc->coded_frame)
-             q = enc->coded_frame->quality/(float)FF_QP2LAMBDA;
++            q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;
          if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
              snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
          }
  
              frame_number = ost->frame_number;
              snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3d q=%3.1f ",
--                     frame_number, (t>1)?(int)(frame_number/t+0.5) : 0, q);
--            if(is_last_report)
++                     frame_number, (t > 1) ? (int)(frame_number / t + 0.5) : 0, q);
++            if (is_last_report)
                  snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");
--            if(qp_hist){
++            if (qp_hist) {
                  int j;
                  int qp = lrintf(q);
--                if(qp>=0 && qp<FF_ARRAY_ELEMS(qp_histogram))
++                if (qp >= 0 && qp < FF_ARRAY_ELEMS(qp_histogram))
                      qp_histogram[qp]++;
--                for(j=0; j<32; j++)
--                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log(qp_histogram[j]+1)/log(2)));
++                for (j = 0; j < 32; j++)
++                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log(qp_histogram[j] + 1) / log(2)));
              }
--            if (enc->flags&CODEC_FLAG_PSNR){
++            if (enc->flags&CODEC_FLAG_PSNR) {
                  int j;
--                double error, error_sum=0;
--                double scale, scale_sum=0;
--                char type[3]= {'Y','U','V'};
++                double error, error_sum = 0;
++                double scale, scale_sum = 0;
++                char type[3] = { 'Y','U','V' };
                  snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR=");
--                for(j=0; j<3; j++){
--                    if(is_last_report){
--                        error= enc->error[j];
--                        scale= enc->width*enc->height*255.0*255.0*frame_number;
--                    }else{
--                        error= enc->coded_frame->error[j];
--                        scale= enc->width*enc->height*255.0*255.0;
++                for (j = 0; j < 3; j++) {
++                    if (is_last_report) {
++                        error = enc->error[j];
++                        scale = enc->width * enc->height * 255.0 * 255.0 * frame_number;
++                    } else {
++                        error = enc->coded_frame->error[j];
++                        scale = enc->width * enc->height * 255.0 * 255.0;
                      }
--                    if(j) scale/=4;
++                    if (j)
++                        scale /= 4;
                      error_sum += error;
                      scale_sum += scale;
--                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], psnr(error/scale));
++                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], psnr(error / scale));
                  }
--                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum/scale_sum));
++                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum));
              }
              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;
 +    secs = pts / AV_TIME_BASE;
 +    us = pts % AV_TIME_BASE;
 +    mins = secs / 60;
 +    secs %= 60;
 +    hours = mins / 60;
 +    mins %= 60;
  
 -        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
 -            "size=%8.0fkB time=%0.2f bitrate=%6.1fkbits/s",
 -            (double)total_size / 1024, ti1, bitrate);
 +    bitrate = pts ? total_size * 8 / (pts / 1000.0) : 0;
  
 -        if (nb_frames_dup || nb_frames_drop)
 -          snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
 -                  nb_frames_dup, nb_frames_drop);
 +    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
 +             "size=%8.0fkB time=", total_size / 1024.0);
 +    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
 +             "%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 (verbose >= 0)
 -            fprintf(stderr, "%s    \r", buf);
 +    if (nb_frames_dup || nb_frames_drop)
 +        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
 +                nb_frames_dup, nb_frames_drop);
  
 -        fflush(stderr);
 -    }
 +    av_log(NULL, AV_LOG_INFO, "%s    \r", buf);
  
 -    if (is_last_report && verbose >= 0){
 +    fflush(stderr);
 +
 +    if (is_last_report) {
          int64_t raw= audio_size + video_size + extra_size;
 -        fprintf(stderr, "\n");
 -        fprintf(stderr, "video:%1.0fkB audio:%1.0fkB global headers:%1.0fkB muxing overhead %f%%\n",
 -                video_size/1024.0,
 -                audio_size/1024.0,
 -                extra_size/1024.0,
 -                100.0*(total_size - raw)/raw
 +        av_log(NULL, AV_LOG_INFO, "\n");
 +        av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB global headers:%1.0fkB muxing overhead %f%%\n",
-                video_size/1024.0,
-                audio_size/1024.0,
-                extra_size/1024.0,
-                100.0*(total_size - raw)/raw
++               video_size / 1024.0,
++               audio_size / 1024.0,
++               extra_size / 1024.0,
++               100.0 * (total_size - raw) / raw
          );
 +        if(video_size + audio_size + extra_size == 0){
 +            av_log(NULL, AV_LOG_WARNING, "Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)\n");
 +        }
      }
  }
  
 -static void generate_silence(uint8_t* buf, enum AVSampleFormat sample_fmt, size_t size)
 -{
 -    int fill_char = 0x00;
 -    if (sample_fmt == AV_SAMPLE_FMT_U8)
 -        fill_char = 0x80;
 -    memset(buf, fill_char, size);
 -}
 -
 -/* pkt = NULL means EOF (needed to flush decoder buffers) */
 -static int output_packet(InputStream *ist, int ist_index,
 -                         OutputStream **ost_table, int nb_ostreams,
 -                         const AVPacket *pkt)
 +static void flush_encoders(OutputStream *ost_table, int nb_ostreams)
  {
 -    AVFormatContext *os;
 -    OutputStream *ost;
 -    int ret, i;
 -    int got_output;
 -    AVFrame picture;
 -    void *buffer_to_free = NULL;
 -    static unsigned int samples_size= 0;
 -    AVSubtitle subtitle, *subtitle_to_free;
 -    int64_t pkt_pts = AV_NOPTS_VALUE;
 -#if CONFIG_AVFILTER
 -    int frame_available;
 -#endif
 -    float quality;
 -
 -    AVPacket avpkt;
 -    int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt);
 +    int i, ret;
  
 -    if(ist->next_pts == AV_NOPTS_VALUE)
 -        ist->next_pts= ist->pts;
 +    for (i = 0; i < nb_ostreams; i++) {
 +        OutputStream   *ost = &ost_table[i];
 +        AVCodecContext *enc = ost->st->codec;
 +        AVFormatContext *os = output_files[ost->file_index].ctx;
  
 -    if (pkt == NULL) {
 -        /* EOF handling */
 -        av_init_packet(&avpkt);
 -        avpkt.data = NULL;
 -        avpkt.size = 0;
 -        goto handle_eof;
 -    } else {
 -        avpkt = *pkt;
 -    }
 +        if (!ost->encoding_needed)
 +            continue;
  
-         if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1)
 -    if(pkt->dts != AV_NOPTS_VALUE)
 -        ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
 -    if(pkt->pts != AV_NOPTS_VALUE)
 -        pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);
++        if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1)
 +            continue;
 +        if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == CODEC_ID_RAWVIDEO)
 +            continue;
  
-         for(;;) {
 -    //while we have more to decode or while the decoder did output something on EOF
 -    while (avpkt.size > 0 || (!pkt && got_output)) {
 -        uint8_t *data_buf, *decoded_data_buf;
 -        int data_size, decoded_data_size;
 -    handle_eof:
 -        ist->pts= ist->next_pts;
++        for (;;) {
 +            AVPacket pkt;
 +            int fifo_bytes;
 +            av_init_packet(&pkt);
-             pkt.stream_index= ost->index;
++            pkt.stream_index = ost->index;
  
 -        if(avpkt.size && avpkt.size != pkt->size &&
 -           ((!ist->showed_multi_packet_warning && verbose>0) || verbose>1)){
 -            fprintf(stderr, "Multiple frames in a packet from stream %d\n", pkt->stream_index);
 -            ist->showed_multi_packet_warning=1;
 -        }
 +            switch (ost->st->codec->codec_type) {
 +            case AVMEDIA_TYPE_AUDIO:
 +                fifo_bytes = av_fifo_size(ost->fifo);
 +                ret = 0;
 +                /* encode any samples remaining in fifo */
 +                if (fifo_bytes > 0) {
 +                    int osize = av_get_bytes_per_sample(enc->sample_fmt);
 +                    int fs_tmp = enc->frame_size;
 +
 +                    av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
 +                    if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
 +                        enc->frame_size = fifo_bytes / (osize * enc->channels);
 +                    } else { /* pad */
 +                        int frame_bytes = enc->frame_size*osize*enc->channels;
 +                        if (allocated_audio_buf_size < frame_bytes)
 +                            exit_program(1);
 +                        generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes);
 +                    }
  
 -        /* decode the packet if needed */
 -        decoded_data_buf = NULL; /* fail safe */
 -        decoded_data_size= 0;
 -        data_buf  = avpkt.data;
 -        data_size = avpkt.size;
 -        subtitle_to_free = NULL;
 -        if (ist->decoding_needed) {
 -            switch(ist->st->codec->codec_type) {
 -            case AVMEDIA_TYPE_AUDIO:{
 -                if(pkt && samples_size < FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE)) {
 -                    samples_size = FFMAX(pkt->size*sizeof(*samples), AVCODEC_MAX_AUDIO_FRAME_SIZE);
 -                    av_free(samples);
 -                    samples= av_malloc(samples_size);
 +                    ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf);
 +                    pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den,
 +                                              ost->st->time_base.num, enc->sample_rate);
 +                    enc->frame_size = fs_tmp;
                  }
 -                decoded_data_size= samples_size;
 -                    /* XXX: could avoid copy if PCM 16 bits with same
 -                       endianness as CPU */
 -                ret = avcodec_decode_audio3(ist->st->codec, samples, &decoded_data_size,
 -                                            &avpkt);
 -                if (ret < 0)
 -                    return ret;
 -                avpkt.data += ret;
 -                avpkt.size -= ret;
 -                data_size   = ret;
 -                got_output  = decoded_data_size > 0;
 -                /* Some bug in mpeg audio decoder gives */
 -                /* decoded_data_size < 0, it seems they are overflows */
 -                if (!got_output) {
 -                    /* no audio frame */
 -                    continue;
 +                if (ret <= 0) {
 +                    ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL);
                  }
 -                decoded_data_buf = (uint8_t *)samples;
 -                ist->next_pts += ((int64_t)AV_TIME_BASE/bps * decoded_data_size) /
 -                    (ist->st->codec->sample_rate * ist->st->codec->channels);
 -                break;}
 -            case AVMEDIA_TYPE_VIDEO:
 -                    decoded_data_size = (ist->st->codec->width * ist->st->codec->height * 3) / 2;
 -                    /* XXX: allocate picture correctly */
 -                    avcodec_get_frame_defaults(&picture);
 -                    avpkt.pts = pkt_pts;
 -                    avpkt.dts = ist->pts;
 -                    pkt_pts = AV_NOPTS_VALUE;
 -
 -                    ret = avcodec_decode_video2(ist->st->codec,
 -                                                &picture, &got_output, &avpkt);
 -                    quality = same_quality ? picture.quality : 0;
 -                    if (ret < 0)
 -                        return ret;
 -                    if (!got_output) {
 -                        /* no picture yet */
 -                        goto discard_packet;
 -                    }
 -                    ist->next_pts = ist->pts = guess_correct_pts(&ist->pts_ctx, picture.pkt_pts, picture.pkt_dts);
 -                    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 *
 -                                          ist->st->codec->time_base.num * ticks) /
 -                            ist->st->codec->time_base.den;
 -                    }
 -                    avpkt.size = 0;
 -                    buffer_to_free = NULL;
 -                    pre_process_video_frame(ist, (AVPicture *)&picture, &buffer_to_free);
 -                    break;
 -            case AVMEDIA_TYPE_SUBTITLE:
 -                ret = avcodec_decode_subtitle2(ist->st->codec,
 -                                               &subtitle, &got_output, &avpkt);
 -                if (ret < 0)
 -                    return ret;
 -                if (!got_output) {
 -                    goto discard_packet;
 +                if (ret < 0) {
 +                    av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
 +                    exit_program(1);
                  }
 -                subtitle_to_free = &subtitle;
 -                avpkt.size = 0;
 -                break;
 -            default:
 -                return -1;
 -            }
 -        } else {
 -            switch(ist->st->codec->codec_type) {
 -            case AVMEDIA_TYPE_AUDIO:
 -                ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /
 -                    ist->st->codec->sample_rate;
 +                audio_size += ret;
-                 pkt.flags |= AV_PKT_FLAG_KEY;
++                pkt.flags  |= AV_PKT_FLAG_KEY;
                  break;
              case AVMEDIA_TYPE_VIDEO:
 -                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 *
 -                                      ist->st->codec->time_base.num * ticks) /
 -                        ist->st->codec->time_base.den;
 +                ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL);
 +                if (ret < 0) {
 +                    av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
 +                    exit_program(1);
                  }
 -                break;
 -            }
 -            ret = avpkt.size;
 -            avpkt.size = 0;
 -        }
 -
 -#if CONFIG_AVFILTER
 -        if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 -            for (i = 0; i < nb_ostreams; i++) {
 -                ost = ost_table[i];
 -                if (ost->input_video_filter && ost->source_index == ist_index) {
 -                    AVRational sar;
 -                    if (ist->st->sample_aspect_ratio.num)
 -                        sar = ist->st->sample_aspect_ratio;
 -                    else
 -                        sar = ist->st->codec->sample_aspect_ratio;
 -                    // add it to be filtered
 -                    av_vsrc_buffer_add_frame(ost->input_video_filter, &picture,
 -                                             ist->pts,
 -                                             sar);
 +                video_size += ret;
-                 if(enc->coded_frame && enc->coded_frame->key_frame)
++                if (enc->coded_frame && enc->coded_frame->key_frame)
 +                    pkt.flags |= AV_PKT_FLAG_KEY;
 +                if (ost->logfile && enc->stats_out) {
 +                    fprintf(ost->logfile, "%s", enc->stats_out);
                  }
-                 ret=-1;
 +                break;
 +            default:
++                ret = -1;
              }
 -        }
 -#endif
  
 -        // preprocess audio (volume)
 -        if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
 -            if (audio_volume != 256) {
 -                short *volp;
 -                volp = samples;
 -                for(i=0;i<(decoded_data_size / sizeof(short));i++) {
 -                    int v = ((*volp) * audio_volume + 128) >> 8;
 -                    if (v < -32768) v = -32768;
 -                    if (v >  32767) v = 32767;
 -                    *volp++ = v;
 -                }
 -            }
 +            if (ret <= 0)
 +                break;
 +            pkt.data = bit_buffer;
 +            pkt.size = ret;
 +            if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
-                 pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
++                pkt.pts = av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
 +            write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters);
          }
 +    }
 +}
  
 -        /* frame rate emulation */
 -        if (rate_emu) {
 -            int64_t pts = av_rescale(ist->pts, 1000000, AV_TIME_BASE);
 -            int64_t now = av_gettime() - ist->start;
 -            if (pts > now)
 -                usleep(pts - now);
 -        }
 -        /* if output time reached then transcode raw format,
 -           encode packets and output them */
 -        if (start_time == 0 || ist->pts >= start_time)
 -            for(i=0;i<nb_ostreams;i++) {
 -                int frame_size;
 -
 -                ost = ost_table[i];
 -                if (ost->source_index == ist_index) {
 -#if CONFIG_AVFILTER
 -                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);
 -#endif
 -                    os = output_files[ost->file_index];
 -
 -                    /* set the input output pts pairs */
 -                    //ost->sync_ipts = (double)(ist->pts + input_files[ist->file_index].ts_offset - start_time)/ AV_TIME_BASE;
 -
 -                    if (ost->encoding_needed) {
 -                        av_assert0(ist->decoding_needed);
 -                        switch(ost->st->codec->codec_type) {
 -                        case AVMEDIA_TYPE_AUDIO:
 -                            do_audio_out(os, ost, ist, decoded_data_buf, decoded_data_size);
 -                            break;
 -                        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;
 -#endif
 -                            do_video_out(os, ost, ist, &picture, &frame_size,
 -                                         same_quality ? quality : ost->st->codec->global_quality);
 -                            if (vstats_filename && frame_size)
 -                                do_video_stats(os, ost, frame_size);
 -                            break;
 -                        case AVMEDIA_TYPE_SUBTITLE:
 -                            do_subtitle_out(os, ost, ist, &subtitle,
 -                                            pkt->pts);
 -                            break;
 -                        default:
 -                            abort();
 -                        }
 -                    } else {
 -                        AVFrame avframe; //FIXME/XXX remove this
 -                        AVPacket opkt;
 -                        int64_t ost_tb_start_time= av_rescale_q(start_time, AV_TIME_BASE_Q, ost->st->time_base);
 +/*
 + * Check whether a packet from ist should be written into ost at this time
 + */
 +static int check_output_constraints(InputStream *ist, OutputStream *ost)
 +{
 +    OutputFile *of = &output_files[ost->file_index];
 +    int ist_index  = ist - input_streams;
  
 -                        av_init_packet(&opkt);
 +    if (ost->source_index != ist_index)
 +        return 0;
  
 -                        if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes)
 -#if !CONFIG_AVFILTER
 -                            continue;
 -#else
 -                            goto cont;
 -#endif
 +    if (of->start_time && ist->pts < of->start_time)
 +        return 0;
  
 -                        /* no reencoding needed : output the packet directly */
 -                        /* force the input stream PTS */
 +    if (of->recording_time != INT64_MAX &&
 +        av_compare_ts(ist->pts, AV_TIME_BASE_Q, of->recording_time + of->start_time,
-                       (AVRational){1, 1000000}) >= 0) {
++                      (AVRational){ 1, 1000000 }) >= 0) {
 +        ost->is_past_recording_time = 1;
 +        return 0;
 +    }
  
 -                        avcodec_get_frame_defaults(&avframe);
 -                        ost->st->codec->coded_frame= &avframe;
 -                        avframe.key_frame = pkt->flags & AV_PKT_FLAG_KEY;
 +    return 1;
 +}
  
 -                        if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
 -                            audio_size += data_size;
 -                        else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 -                            video_size += data_size;
 -                            ost->sync_opts++;
 -                        }
 +static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt)
 +{
 +    OutputFile *of = &output_files[ost->file_index];
 +    int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
 +    AVPicture pict;
 +    AVPacket opkt;
  
 -                        opkt.stream_index= ost->index;
 -                        if(pkt->pts != AV_NOPTS_VALUE)
 -                            opkt.pts= av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time;
 -                        else
 -                            opkt.pts= AV_NOPTS_VALUE;
 -
 -                        if (pkt->dts == AV_NOPTS_VALUE)
 -                            opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base);
 -                        else
 -                            opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
 -                        opkt.dts -= ost_tb_start_time;
 -
 -                        opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
 -                        opkt.flags= pkt->flags;
 -
 -                        //FIXME remove the following 2 lines they shall be replaced by the bitstream filters
 -                        if(   ost->st->codec->codec_id != CODEC_ID_H264
 -                           && ost->st->codec->codec_id != CODEC_ID_MPEG1VIDEO
 -                           && ost->st->codec->codec_id != CODEC_ID_MPEG2VIDEO
 -                           ) {
 -                            if(av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, data_buf, data_size, pkt->flags & AV_PKT_FLAG_KEY))
 -                                opkt.destruct= av_destruct_packet;
 -                        } else {
 -                            opkt.data = data_buf;
 -                            opkt.size = data_size;
 -                        }
 +    av_init_packet(&opkt);
  
 -                        write_frame(os, &opkt, ost->st->codec, ost->bitstream_filters);
 -                        ost->st->codec->frame_number++;
 -                        ost->frame_number++;
 -                        av_free_packet(&opkt);
 -                    }
 -#if CONFIG_AVFILTER
 -                    cont:
 -                    frame_available = (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
 -                                       ost->output_video_filter && avfilter_poll_frame(ost->output_video_filter->inputs[0]);
 -                    if (ost->picref)
 -                        avfilter_unref_buffer(ost->picref);
 -                }
 -#endif
 -                }
 -            }
 +    if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) &&
 +        !ost->copy_initial_nonkeyframes)
 +        return;
  
 -        av_free(buffer_to_free);
 -        /* XXX: allocate the subtitles in the codec ? */
 -        if (subtitle_to_free) {
 -            avsubtitle_free(subtitle_to_free);
 -            subtitle_to_free = NULL;
 -        }
 +    /* force the input stream PTS */
 +    if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
 +        audio_size += pkt->size;
 +    else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 +        video_size += pkt->size;
 +        ost->sync_opts++;
      }
 - discard_packet:
 -    if (pkt == NULL) {
 -        /* EOF handling */
  
 -        for(i=0;i<nb_ostreams;i++) {
 -            ost = ost_table[i];
 -            if (ost->source_index == ist_index) {
 -                AVCodecContext *enc= ost->st->codec;
 -                os = output_files[ost->file_index];
 -
 -                if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <=1)
 -                    continue;
 -                if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE))
 -                    continue;
 -
 -                if (ost->encoding_needed) {
 -                    for(;;) {
 -                        AVPacket pkt;
 -                        int fifo_bytes;
 -                        av_init_packet(&pkt);
 -                        pkt.stream_index= ost->index;
 -
 -                        switch(ost->st->codec->codec_type) {
 -                        case AVMEDIA_TYPE_AUDIO:
 -                            fifo_bytes = av_fifo_size(ost->fifo);
 -                            ret = 0;
 -                            /* encode any samples remaining in fifo */
 -                            if (fifo_bytes > 0) {
 -                                int osize = av_get_bytes_per_sample(enc->sample_fmt);
 -                                int fs_tmp = enc->frame_size;
 -
 -                                av_fifo_generic_read(ost->fifo, audio_buf, fifo_bytes, NULL);
 -                                if (enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
 -                                    enc->frame_size = fifo_bytes / (osize * enc->channels);
 -                                } else { /* pad */
 -                                    int frame_bytes = enc->frame_size*osize*enc->channels;
 -                                    if (allocated_audio_buf_size < frame_bytes)
 -                                        exit_program(1);
 -                                    generate_silence(audio_buf+fifo_bytes, enc->sample_fmt, frame_bytes - fifo_bytes);
 -                                }
 -
 -                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, (short *)audio_buf);
 -                                pkt.duration = av_rescale((int64_t)enc->frame_size*ost->st->time_base.den,
 -                                                          ost->st->time_base.num, enc->sample_rate);
 -                                enc->frame_size = fs_tmp;
 -                            }
 -                            if(ret <= 0) {
 -                                ret = avcodec_encode_audio(enc, bit_buffer, bit_buffer_size, NULL);
 -                            }
 -                            if (ret < 0) {
 -                                fprintf(stderr, "Audio encoding failed\n");
 -                                exit_program(1);
 -                            }
 -                            audio_size += ret;
 -                            pkt.flags |= AV_PKT_FLAG_KEY;
 -                            break;
 -                        case AVMEDIA_TYPE_VIDEO:
 -                            ret = avcodec_encode_video(enc, bit_buffer, bit_buffer_size, NULL);
 -                            if (ret < 0) {
 -                                fprintf(stderr, "Video encoding failed\n");
 -                                exit_program(1);
 -                            }
 -                            video_size += ret;
 -                            if(enc->coded_frame && enc->coded_frame->key_frame)
 -                                pkt.flags |= AV_PKT_FLAG_KEY;
 -                            if (ost->logfile && enc->stats_out) {
 -                                fprintf(ost->logfile, "%s", enc->stats_out);
 -                            }
 -                            break;
 -                        default:
 -                            ret=-1;
 -                        }
 +    opkt.stream_index = ost->index;
 +    if (pkt->pts != AV_NOPTS_VALUE)
 +        opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time;
 +    else
 +        opkt.pts = AV_NOPTS_VALUE;
  
 -                        if(ret<=0)
 -                            break;
 -                        pkt.data= bit_buffer;
 -                        pkt.size= ret;
 -                        if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
 -                            pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);
 -                        write_frame(os, &pkt, ost->st->codec, ost->bitstream_filters);
 -                    }
 -                }
 -            }
 -        }
 +    if (pkt->dts == AV_NOPTS_VALUE)
 +        opkt.dts = av_rescale_q(ist->pts, AV_TIME_BASE_Q, ost->st->time_base);
 +    else
 +        opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
 +    opkt.dts -= ost_tb_start_time;
 +
 +    opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
 +    opkt.flags    = pkt->flags;
 +
-     //FIXME remove the following 2 lines they shall be replaced by the bitstream filters
-     if(   ost->st->codec->codec_id != CODEC_ID_H264
++    // FIXME remove the following 2 lines they shall be replaced by the bitstream filters
++    if (  ost->st->codec->codec_id != CODEC_ID_H264
 +       && ost->st->codec->codec_id != CODEC_ID_MPEG1VIDEO
 +       && ost->st->codec->codec_id != CODEC_ID_MPEG2VIDEO
 +       ) {
 +        if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY))
 +            opkt.destruct = av_destruct_packet;
 +    } else {
 +        opkt.data = pkt->data;
 +        opkt.size = pkt->size;
 +    }
 +    if (of->ctx->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;
      }
  
 -    return 0;
 +    write_frame(of->ctx, &opkt, ost->st->codec, ost->bitstream_filters);
 +    ost->st->codec->frame_number++;
 +    ost->frame_number++;
 +    av_free_packet(&opkt);
  }
  
 -static void print_sdp(AVFormatContext **avc, int n)
 +static void rate_emu_sleep(InputStream *ist)
  {
 -    char sdp[2048];
 -
 -    av_sdp_create(avc, n, sdp, sizeof(sdp));
 -    printf("SDP:\n%s\n", sdp);
 -    fflush(stdout);
 +    if (input_files[ist->file_index].rate_emu) {
 +        int64_t pts = av_rescale(ist->pts, 1000000, AV_TIME_BASE);
 +        int64_t now = av_gettime() - ist->start;
 +        if (pts > now)
 +            usleep(pts - now);
 +    }
  }
  
 -static int copy_chapters(int infile, int outfile)
 +static int transcode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
  {
 -    AVFormatContext *is = input_files[infile].ctx;
 -    AVFormatContext *os = output_files[outfile];
 -    int i;
 +    AVFrame *decoded_frame;
 +    AVCodecContext *avctx = ist->st->codec;
 +    int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt);
 +    int i, ret;
  
 -    for (i = 0; i < is->nb_chapters; i++) {
 -        AVChapter *in_ch = is->chapters[i], *out_ch;
 -        int64_t ts_off   = av_rescale_q(start_time - input_files[infile].ts_offset,
 -                                      AV_TIME_BASE_Q, in_ch->time_base);
 -        int64_t rt       = (recording_time == INT64_MAX) ? INT64_MAX :
 -                           av_rescale_q(recording_time, AV_TIME_BASE_Q, in_ch->time_base);
 +    if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
 +        return AVERROR(ENOMEM);
 +    else
 +        avcodec_get_frame_defaults(ist->decoded_frame);
 +    decoded_frame = ist->decoded_frame;
  
 +    ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt);
 +    if (ret < 0) {
 +        return ret;
 +    }
  
 -        if (in_ch->end < ts_off)
 -            continue;
 -        if (rt != INT64_MAX && in_ch->start > rt + ts_off)
 -            break;
 +    if (!*got_output) {
 +        /* no audio frame */
 +        return ret;
 +    }
  
 -        out_ch = av_mallocz(sizeof(AVChapter));
 -        if (!out_ch)
 -            return AVERROR(ENOMEM);
 +    /* if the decoder provides a pts, use it instead of the last packet pts.
 +       the decoder could be delaying output by a packet or more. */
 +    if (decoded_frame->pts != AV_NOPTS_VALUE)
 +        ist->next_pts = decoded_frame->pts;
 +
 +    /* increment next_pts to use for the case where the input stream does not
 +       have timestamps or there are multiple frames in the packet */
 +    ist->next_pts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) /
 +                     avctx->sample_rate;
 +
 +    // preprocess audio (volume)
 +    if (audio_volume != 256) {
 +        int decoded_data_size = decoded_frame->nb_samples * avctx->channels * bps;
 +        void *samples = decoded_frame->data[0];
 +        switch (avctx->sample_fmt) {
 +        case AV_SAMPLE_FMT_U8:
 +        {
 +            uint8_t *volp = samples;
 +            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
 +                int v = (((*volp - 128) * audio_volume + 128) >> 8) + 128;
 +                *volp++ = av_clip_uint8(v);
 +            }
 +            break;
 +        }
 +        case AV_SAMPLE_FMT_S16:
 +        {
 +            int16_t *volp = samples;
 +            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
 +                int v = ((*volp) * audio_volume + 128) >> 8;
 +                *volp++ = av_clip_int16(v);
 +            }
 +            break;
 +        }
 +        case AV_SAMPLE_FMT_S32:
 +        {
 +            int32_t *volp = samples;
 +            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
 +                int64_t v = (((int64_t)*volp * audio_volume + 128) >> 8);
 +                *volp++ = av_clipl_int32(v);
 +            }
 +            break;
 +        }
 +        case AV_SAMPLE_FMT_FLT:
 +        {
 +            float *volp = samples;
 +            float scale = audio_volume / 256.f;
 +            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
 +                *volp++ *= scale;
 +            }
 +            break;
 +        }
 +        case AV_SAMPLE_FMT_DBL:
 +        {
 +            double *volp = samples;
 +            double scale = audio_volume / 256.;
 +            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
 +                *volp++ *= scale;
 +            }
 +            break;
 +        }
 +        default:
 +            av_log(NULL, AV_LOG_FATAL,
 +                   "Audio volume adjustment on sample format %s is not supported.\n",
 +                   av_get_sample_fmt_name(ist->st->codec->sample_fmt));
 +            exit_program(1);
 +        }
 +    }
  
 -        out_ch->id        = in_ch->id;
 -        out_ch->time_base = in_ch->time_base;
 -        out_ch->start     = FFMAX(0,  in_ch->start - ts_off);
 -        out_ch->end       = FFMIN(rt, in_ch->end   - ts_off);
 +    rate_emu_sleep(ist);
  
 -        if (metadata_chapters_autocopy)
 -            av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
 +    for (i = 0; i < nb_output_streams; i++) {
 +        OutputStream *ost = &output_streams[i];
  
 -        os->nb_chapters++;
 -        os->chapters = av_realloc(os->chapters, sizeof(AVChapter)*os->nb_chapters);
 -        if (!os->chapters)
 -            return AVERROR(ENOMEM);
 -        os->chapters[os->nb_chapters - 1] = out_ch;
 +        if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
 +            continue;
 +        do_audio_out(output_files[ost->file_index].ctx, ost, ist, decoded_frame);
      }
 -    return 0;
 +
 +    return ret;
  }
  
 -static void parse_forced_key_frames(char *kf, OutputStream *ost,
 -                                    AVCodecContext *avctx)
 +static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_t *pkt_pts, int64_t *pkt_dts)
  {
 -    char *p;
 -    int n = 1, i;
 -    int64_t t;
 +    AVFrame *decoded_frame, *filtered_frame = NULL;
 +    void *buffer_to_free = NULL;
 +    int i, ret = 0;
 +    float quality = 0;
 +#if CONFIG_AVFILTER
 +    int frame_available = 1;
 +#endif
 +    int duration=0;
 +    int64_t *best_effort_timestamp;
 +    AVRational *frame_sample_aspect;
  
 -    for (p = kf; *p; p++)
 -        if (*p == ',')
 -            n++;
 -    ost->forced_kf_count = n;
 -    ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
 -    if (!ost->forced_kf_pts) {
 -        av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
 -        exit_program(1);
 +    if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
 +        return AVERROR(ENOMEM);
 +    else
 +        avcodec_get_frame_defaults(ist->decoded_frame);
 +    decoded_frame = ist->decoded_frame;
 +    pkt->pts  = *pkt_pts;
 +    pkt->dts  = *pkt_dts;
 +    *pkt_pts  = AV_NOPTS_VALUE;
 +
 +    if (pkt->duration) {
 +        duration = av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
 +    } else 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;
 +        duration = ((int64_t)AV_TIME_BASE *
 +                          ist->st->codec->time_base.num * ticks) /
 +                          ist->st->codec->time_base.den;
      }
 -    for (i = 0; i < n; i++) {
 -        p = i ? strchr(p, ',') + 1 : kf;
 -        t = parse_time_or_die("force_key_frames", p, 1);
 -        ost->forced_kf_pts[i] = av_rescale_q(t, AV_TIME_BASE_Q, avctx->time_base);
 +
 +    if(*pkt_dts != AV_NOPTS_VALUE && duration) {
 +        *pkt_dts += duration;
 +    }else
 +        *pkt_dts = AV_NOPTS_VALUE;
 +
 +    ret = avcodec_decode_video2(ist->st->codec,
 +                                decoded_frame, got_output, pkt);
 +    if (ret < 0)
 +        return ret;
 +
 +    quality = same_quant ? decoded_frame->quality : 0;
 +    if (!*got_output) {
 +        /* no picture yet */
 +        return ret;
      }
 -}
  
 -/*
 - * The following code is the main loop of the file converter
 - */
 -static int transcode(AVFormatContext **output_files,
 -                     int nb_output_files,
 -                     InputFile *input_files,
 -                     int nb_input_files,
 -                     StreamMap *stream_maps, int nb_stream_maps)
 +    best_effort_timestamp= av_opt_ptr(avcodec_get_frame_class(), decoded_frame, "best_effort_timestamp");
 +    if(*best_effort_timestamp != AV_NOPTS_VALUE)
 +        ist->next_pts = ist->pts = *best_effort_timestamp;
 +
 +    ist->next_pts += duration;
 +    pkt->size = 0;
 +
 +    pre_process_video_frame(ist, (AVPicture *)decoded_frame, &buffer_to_free);
 +
 +#if CONFIG_AVFILTER
 +    frame_sample_aspect= av_opt_ptr(avcodec_get_frame_class(), decoded_frame, "sample_aspect_ratio");
 +    for(i=0;i<nb_output_streams;i++) {
 +        OutputStream *ost = ost = &output_streams[i];
 +        if(check_output_constraints(ist, ost)){
 +            if (!frame_sample_aspect->num)
 +                *frame_sample_aspect = ist->st->sample_aspect_ratio;
 +            decoded_frame->pts = ist->pts;
 +            if (ist->dr1 && decoded_frame->type==FF_BUFFER_TYPE_USER) {
 +                FrameBuffer      *buf = decoded_frame->opaque;
 +                AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(
 +                                            decoded_frame->data, decoded_frame->linesize,
 +                                            AV_PERM_READ | AV_PERM_PRESERVE,
 +                                            ist->st->codec->width, ist->st->codec->height,
 +                                            ist->st->codec->pix_fmt);
 +
 +                avfilter_copy_frame_props(fb, decoded_frame);
 +                fb->pts                 = ist->pts;
 +                fb->buf->priv           = buf;
 +                fb->buf->free           = filter_release_buffer;
 +
 +                buf->refcount++;
 +                av_buffersrc_buffer(ost->input_video_filter, fb);
 +            } else
 +            if((av_vsrc_buffer_add_frame(ost->input_video_filter, decoded_frame, AV_VSRC_BUF_FLAG_OVERWRITE)) < 0){
 +                av_log(0, AV_LOG_FATAL, "Failed to inject frame into filter network\n");
 +                exit_program(1);
 +            }
 +        }
 +    }
 +#endif
 +
 +    rate_emu_sleep(ist);
 +
 +    for (i = 0; i < nb_output_streams; i++) {
 +        OutputStream *ost = &output_streams[i];
 +        int frame_size;
 +
 +        if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
 +            continue;
 +
 +#if CONFIG_AVFILTER
 +        if (ost->input_video_filter) {
 +            frame_available = av_buffersink_poll_frame(ost->output_video_filter);
 +        }
 +        while (frame_available) {
 +            if (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){
 +                    av_log(0, AV_LOG_WARNING, "AV Filter told us it has a frame available but failed to output one\n");
 +                    goto cont;
 +                }
 +                if (!ist->filtered_frame && !(ist->filtered_frame = avcodec_alloc_frame())) {
 +                    av_free(buffer_to_free);
 +                    return AVERROR(ENOMEM);
 +                } else
 +                    avcodec_get_frame_defaults(ist->filtered_frame);
 +                filtered_frame = ist->filtered_frame;
 +                *filtered_frame= *decoded_frame; //for me_threshold
 +                if (ost->picref) {
 +                    avfilter_fill_frame_from_video_buffer_ref(filtered_frame, ost->picref);
 +                    ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
 +                }
 +            }
 +            if (ost->picref->video && !ost->frame_aspect_ratio)
 +                ost->st->codec->sample_aspect_ratio = ost->picref->video->sample_aspect_ratio;
 +#else
 +            filtered_frame = decoded_frame;
 +#endif
 +
 +            do_video_out(output_files[ost->file_index].ctx, ost, ist, filtered_frame, &frame_size,
 +                         same_quant ? quality : ost->st->codec->global_quality);
 +            if (vstats_filename && frame_size)
 +                do_video_stats(output_files[ost->file_index].ctx, ost, frame_size);
 +#if CONFIG_AVFILTER
 +            cont:
 +            frame_available = ost->output_video_filter && av_buffersink_poll_frame(ost->output_video_filter);
 +            avfilter_unref_buffer(ost->picref);
 +        }
 +#endif
 +    }
 +
 +    av_free(buffer_to_free);
 +    return ret;
 +}
 +
 +static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
  {
 -    int ret = 0, i, j, k, n, nb_ostreams = 0;
 -    AVFormatContext *is, *os;
 -    AVCodecContext *codec, *icodec;
 -    OutputStream *ost, **ost_table = NULL;
 -    InputStream *ist;
 -    char error[1024];
 -    int want_sdp = 1;
 -    uint8_t no_packet[MAX_FILES]={0};
 -    int no_packet_count=0;
 +    AVSubtitle subtitle;
 +    int i, ret = avcodec_decode_subtitle2(ist->st->codec,
 +                                          &subtitle, got_output, pkt);
 +    if (ret < 0)
 +        return ret;
 +    if (!*got_output)
 +        return ret;
  
 -    if (rate_emu)
 -        for (i = 0; i < nb_input_streams; i++)
 -            input_streams[i].start = av_gettime();
 +    rate_emu_sleep(ist);
  
 -    /* output stream init */
 -    nb_ostreams = 0;
 -    for(i=0;i<nb_output_files;i++) {
 -        os = output_files[i];
 -        if (!os->nb_streams && !(os->oformat->flags & AVFMT_NOSTREAMS)) {
 -            av_dump_format(output_files[i], i, output_files[i]->filename, 1);
 -            fprintf(stderr, "Output file #%d does not contain any stream\n", i);
 -            ret = AVERROR(EINVAL);
 -            goto fail;
 +    for (i = 0; i < nb_output_streams; i++) {
 +        OutputStream *ost = &output_streams[i];
 +
 +        if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
 +            continue;
 +
 +        do_subtitle_out(output_files[ost->file_index].ctx, ost, ist, &subtitle, pkt->pts);
 +    }
 +
 +    avsubtitle_free(&subtitle);
 +    return ret;
 +}
 +
 +/* pkt = NULL means EOF (needed to flush decoder buffers) */
 +static int output_packet(InputStream *ist,
 +                         OutputStream *ost_table, int nb_ostreams,
 +                         const AVPacket *pkt)
 +{
 +    int ret = 0, i;
 +    int got_output;
 +    int64_t pkt_dts = AV_NOPTS_VALUE;
 +    int64_t pkt_pts = AV_NOPTS_VALUE;
 +
 +    AVPacket avpkt;
 +
 +    if (ist->next_pts == AV_NOPTS_VALUE)
 +        ist->next_pts = ist->pts;
 +
 +    if (pkt == NULL) {
 +        /* EOF handling */
 +        av_init_packet(&avpkt);
 +        avpkt.data = NULL;
 +        avpkt.size = 0;
 +        goto handle_eof;
 +    } else {
 +        avpkt = *pkt;
 +    }
 +
-     if(pkt->dts != AV_NOPTS_VALUE){
-         if(ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || !ist->decoding_needed)
++    if (pkt->dts != AV_NOPTS_VALUE) {
++        if (ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || !ist->decoding_needed)
 +            ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
 +        pkt_dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
 +    }
 +    if(pkt->pts != AV_NOPTS_VALUE)
 +        pkt_pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);
 +
-     //while we have more to decode or while the decoder did output something on EOF
++    // while we have more to decode or while the decoder did output something on EOF
 +    while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && got_output))) {
 +    handle_eof:
 +
 +        ist->pts = ist->next_pts;
 +
 +        if (avpkt.size && avpkt.size != pkt->size) {
 +            av_log(NULL, ist->showed_multi_packet_warning ? AV_LOG_VERBOSE : AV_LOG_WARNING,
 +                   "Multiple frames in a packet from stream %d\n", pkt->stream_index);
 +            ist->showed_multi_packet_warning = 1;
 +        }
 +
-         switch(ist->st->codec->codec_type) {
++        switch (ist->st->codec->codec_type) {
 +        case AVMEDIA_TYPE_AUDIO:
 +            ret = transcode_audio    (ist, &avpkt, &got_output);
 +            break;
 +        case AVMEDIA_TYPE_VIDEO:
 +            ret = transcode_video    (ist, &avpkt, &got_output, &pkt_pts, &pkt_dts);
 +            break;
 +        case AVMEDIA_TYPE_SUBTITLE:
 +            ret = transcode_subtitles(ist, &avpkt, &got_output);
 +            break;
 +        default:
 +            return -1;
 +        }
 +
 +        if (ret < 0)
 +            return ret;
 +
 +        avpkt.dts=
 +        avpkt.pts= AV_NOPTS_VALUE;
 +
 +        // touch data and size only if not EOF
 +        if (pkt) {
 +            if(ist->st->codec->codec_type != AVMEDIA_TYPE_AUDIO)
 +                ret = avpkt.size;
 +            avpkt.data += ret;
 +            avpkt.size -= ret;
 +        }
 +        if (!got_output) {
 +            continue;
          }
 -        nb_ostreams += os->nb_streams;
      }
 -    if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {
 -        fprintf(stderr, "Number of stream maps must match number of output streams\n");
 -        ret = AVERROR(EINVAL);
 -        goto fail;
 +
 +    /* handle stream copy */
 +    if (!ist->decoding_needed) {
 +        rate_emu_sleep(ist);
 +        ist->pts = ist->next_pts;
 +        switch (ist->st->codec->codec_type) {
 +        case AVMEDIA_TYPE_AUDIO:
 +            ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /
 +                             ist->st->codec->sample_rate;
 +            break;
 +        case AVMEDIA_TYPE_VIDEO:
 +            if (pkt->duration) {
 +                ist->next_pts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
 +            } else 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;
++                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 *
 +                                  ist->st->codec->time_base.num * ticks) /
 +                                  ist->st->codec->time_base.den;
 +            }
 +            break;
 +        }
      }
 +    for (i = 0; pkt && i < nb_ostreams; i++) {
 +        OutputStream *ost = &ost_table[i];
 +
 +        if (!check_output_constraints(ist, ost) || ost->encoding_needed)
 +            continue;
  
 -    /* Sanity check the mapping args -- do the input files & streams exist? */
 -    for(i=0;i<nb_stream_maps;i++) {
 -        int fi = stream_maps[i].file_index;
 -        int si = stream_maps[i].stream_index;
 +        do_streamcopy(ist, ost, pkt);
 +    }
  
 -        if (fi < 0 || fi > nb_input_files - 1 ||
 -            si < 0 || si > input_files[fi].nb_streams - 1) {
 -            fprintf(stderr,"Could not find input stream #%d.%d\n", fi, si);
 -            ret = AVERROR(EINVAL);
 -            goto fail;
 +    return 0;
 +}
 +
 +static void print_sdp(OutputFile *output_files, int n)
 +{
 +    char sdp[2048];
 +    int i;
-     AVFormatContext **avc = av_malloc(sizeof(*avc)*n);
++    AVFormatContext **avc = av_malloc(sizeof(*avc) * n);
 +
 +    if (!avc)
 +        exit_program(1);
 +    for (i = 0; i < n; i++)
 +        avc[i] = output_files[i].ctx;
 +
 +    av_sdp_create(avc, n, sdp, sizeof(sdp));
 +    printf("SDP:\n%s\n", sdp);
 +    fflush(stdout);
 +    av_freep(&avc);
 +}
 +
 +static int init_input_stream(int ist_index, OutputStream *output_streams, int nb_output_streams,
 +                             char *error, int error_len)
 +{
 +    InputStream *ist = &input_streams[ist_index];
 +    if (ist->decoding_needed) {
 +        AVCodec *codec = ist->dec;
 +        if (!codec) {
 +            snprintf(error, error_len, "Decoder (codec %s) not found for input stream #%d:%d",
 +                    avcodec_get_name(ist->st->codec->codec_id), ist->file_index, ist->st->index);
 +            return AVERROR(EINVAL);
          }
 -        fi = stream_maps[i].sync_file_index;
 -        si = stream_maps[i].sync_stream_index;
 -        if (fi < 0 || fi > nb_input_files - 1 ||
 -            si < 0 || si > input_files[fi].nb_streams - 1) {
 -            fprintf(stderr,"Could not find sync stream #%d.%d\n", fi, si);
 -            ret = AVERROR(EINVAL);
 -            goto fail;
 +
 +        ist->dr1 = codec->capabilities & CODEC_CAP_DR1;
 +        if (codec->type == AVMEDIA_TYPE_VIDEO && ist->dr1) {
 +            ist->st->codec->get_buffer     = codec_get_buffer;
 +            ist->st->codec->release_buffer = codec_release_buffer;
 +            ist->st->codec->opaque         = ist;
 +        }
 +
 +        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);
 +            return AVERROR(EINVAL);
          }
 +        assert_codec_experimental(ist->st->codec, 0);
 +        assert_avoptions(ist->opts);
      }
  
-     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;
 -    ost_table = av_mallocz(sizeof(OutputStream *) * nb_ostreams);
 -    if (!ost_table)
 -        goto fail;
 -    n = 0;
 -    for(k=0;k<nb_output_files;k++) {
 -        os = output_files[k];
 -        for(i=0;i<os->nb_streams;i++,n++) {
 -            int found;
 -            ost = ost_table[n] = output_streams_for_file[k][i];
 -            if (nb_stream_maps > 0) {
 -                ost->source_index = input_files[stream_maps[n].file_index].ist_index +
 -                    stream_maps[n].stream_index;
 -
 -                /* Sanity check that the stream types match */
 -                if (input_streams[ost->source_index].st->codec->codec_type != ost->st->codec->codec_type) {
 -                    int i= ost->file_index;
 -                    av_dump_format(output_files[i], i, output_files[i]->filename, 1);
 -                    fprintf(stderr, "Codec type mismatch for mapping #%d.%d -> #%d.%d\n",
 -                        stream_maps[n].file_index, stream_maps[n].stream_index,
 -                        ost->file_index, ost->index);
 -                    exit_program(1);
 -                }
++    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;
 +    ist->is_start = 1;
  
 -            } else {
 -                int best_nb_frames=-1;
 -                /* get corresponding input stream index : we select the first one with the right type */
 -                found = 0;
 -                for (j = 0; j < nb_input_streams; j++) {
 -                    int skip=0;
 -                    ist = &input_streams[j];
 -                    if(opt_programid){
 -                        int pi,si;
 -                        AVFormatContext *f = input_files[ist->file_index].ctx;
 -                        skip=1;
 -                        for(pi=0; pi<f->nb_programs; pi++){
 -                            AVProgram *p= f->programs[pi];
 -                            if(p->id == opt_programid)
 -                                for(si=0; si<p->nb_stream_indexes; si++){
 -                                    if(f->streams[ p->stream_index[si] ] == ist->st)
 -                                        skip=0;
 -                                }
 -                        }
 -                    }
 -                    if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip &&
 -                        ist->st->codec->codec_type == ost->st->codec->codec_type) {
 -                        if(best_nb_frames < ist->st->codec_info_nb_frames){
 -                            best_nb_frames= ist->st->codec_info_nb_frames;
 -                            ost->source_index = j;
 -                            found = 1;
 -                        }
 -                    }
 -                }
 +    return 0;
 +}
  
 -                if (!found) {
 -                    if(! opt_programid) {
 -                        /* try again and reuse existing stream */
 -                        for (j = 0; j < nb_input_streams; j++) {
 -                            ist = &input_streams[j];
 -                            if (   ist->st->codec->codec_type == ost->st->codec->codec_type
 -                                && ist->st->discard != AVDISCARD_ALL) {
 -                                ost->source_index = j;
 -                                found = 1;
 -                            }
 -                        }
 -                    }
 -                    if (!found) {
 -                        int i= ost->file_index;
 -                        av_dump_format(output_files[i], i, output_files[i]->filename, 1);
 -                        fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n",
 -                                ost->file_index, ost->index);
 -                        exit_program(1);
 -                    }
 -                }
 -            }
 -            ist = &input_streams[ost->source_index];
 -            ist->discard = 0;
 -            ost->sync_ist = (nb_stream_maps > 0) ?
 -                &input_streams[input_files[stream_maps[n].sync_file_index].ist_index +
 -                         stream_maps[n].sync_stream_index] : ist;
 +static int transcode_init(OutputFile *output_files, int nb_output_files,
 +                          InputFile  *input_files,  int nb_input_files)
 +{
 +    int ret = 0, i, j, k;
 +    AVFormatContext *oc;
 +    AVCodecContext *codec, *icodec;
 +    OutputStream *ost;
 +    InputStream *ist;
 +    char error[1024];
 +    int want_sdp = 1;
 +
 +    /* init framerate emulation */
 +    for (i = 0; i < nb_input_files; i++) {
 +        InputFile *ifile = &input_files[i];
 +        if (ifile->rate_emu)
 +            for (j = 0; j < ifile->nb_streams; j++)
 +                input_streams[j + ifile->ist_index].start = av_gettime();
 +    }
 +
 +    /* output stream init */
 +    for (i = 0; i < nb_output_files; i++) {
 +        oc = output_files[i].ctx;
 +        if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
 +            av_dump_format(oc, i, oc->filename, 1);
 +            av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", i);
 +            return AVERROR(EINVAL);
          }
      }
  
                      codec->codec_tag = icodec->codec_tag;
              }
  
 -            codec->bit_rate = icodec->bit_rate;
 +            codec->bit_rate       = icodec->bit_rate;
              codec->rc_max_rate    = icodec->rc_max_rate;
              codec->rc_buffer_size = icodec->rc_buffer_size;
 -            codec->extradata= av_mallocz(extra_size);
 -            if (!codec->extradata)
 -                goto fail;
 +            codec->field_order    = icodec->field_order;
 +            codec->extradata      = av_mallocz(extra_size);
 +            if (!codec->extradata) {
 +                return AVERROR(ENOMEM);
 +            }
              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;
 -            switch(codec->codec_type) {
 +
 +            codec->time_base = ist->st->time_base;
 +            if(!strcmp(oc->oformat->name, "avi")) {
 +                if (   copy_tb<0 && 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
 +                    || copy_tb==0){
 +                    codec->time_base = icodec->time_base;
 +                    codec->time_base.num *= icodec->ticks_per_frame;
 +                    codec->time_base.den *= 2;
 +                }
 +            } else if(!(oc->oformat->flags & AVFMT_VARIABLE_FPS)
 +                      && strcmp(oc->oformat->name, "mov") && strcmp(oc->oformat->name, "mp4") && strcmp(oc->oformat->name, "3gp")
 +                      && strcmp(oc->oformat->name, "3g2") && strcmp(oc->oformat->name, "psp") && strcmp(oc->oformat->name, "ipod")
 +            ) {
 +                if(   copy_tb<0 && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base)
 +                                && av_q2d(ist->st->time_base) < 1.0/500
 +                   || copy_tb==0){
 +                    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) {
++            switch (codec->codec_type) {
              case AVMEDIA_TYPE_AUDIO:
--                if(audio_volume != 256) {
 -                    fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n");
++                if (audio_volume != 256) {
 +                    av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n");
                      exit_program(1);
                  }
 -                codec->channel_layout = icodec->channel_layout;
 -                codec->sample_rate = icodec->sample_rate;
 -                codec->channels = icodec->channels;
 -                codec->frame_size = icodec->frame_size;
 +                codec->channel_layout     = icodec->channel_layout;
 +                codec->sample_rate        = icodec->sample_rate;
 +                codec->channels           = icodec->channels;
 +                codec->frame_size         = icodec->frame_size;
                  codec->audio_service_type = icodec->audio_service_type;
 -                codec->block_align= icodec->block_align;
 -                if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3)
 -                    codec->block_align= 0;
 -                if(codec->codec_id == CODEC_ID_AC3)
 -                    codec->block_align= 0;
 +                codec->block_align        = icodec->block_align;
                  break;
              case AVMEDIA_TYPE_VIDEO:
 -                codec->pix_fmt = icodec->pix_fmt;
 -                codec->width = icodec->width;
 -                codec->height = icodec->height;
 -                codec->has_b_frames = icodec->has_b_frames;
 +                codec->pix_fmt            = icodec->pix_fmt;
 +                codec->width              = icodec->width;
 +                codec->height             = icodec->height;
 +                codec->has_b_frames       = icodec->has_b_frames;
                  if (!codec->sample_aspect_ratio.num) {
 -                    codec->sample_aspect_ratio =
 +                    codec->sample_aspect_ratio   =
                      ost->st->sample_aspect_ratio =
                          ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :
                          ist->st->codec->sample_aspect_ratio.num ?
          } else {
              if (!ost->enc)
                  ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
 -            switch(codec->codec_type) {
 +
 +            ist->decoding_needed = 1;
 +            ost->encoding_needed = 1;
 +
-             switch(codec->codec_type) {
++            switch (codec->codec_type) {
              case AVMEDIA_TYPE_AUDIO:
 -                ost->fifo= av_fifo_alloc(1024);
 -                if(!ost->fifo)
 -                    goto fail;
 -                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;
 +                ost->fifo = av_fifo_alloc(1024);
 +                if (!ost->fifo) {
 +                    return AVERROR(ENOMEM);
                  }
 +                if (!codec->sample_rate)
 +                    codec->sample_rate = icodec->sample_rate;
                  choose_sample_rate(ost->st, ost->enc);
--                codec->time_base = (AVRational){1, codec->sample_rate};
++                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);
                                        codec->height  != icodec->height ||
                                        codec->pix_fmt != icodec->pix_fmt;
                  if (ost->video_resample) {
-                     codec->bits_per_raw_sample= frame_bits_per_raw_sample;
 -#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;
 -                ost->resample_width  = icodec->width;
 -                ost->resample_pix_fmt= icodec->pix_fmt;
 -                ost->encoding_needed = 1;
 -                ist->decoding_needed = 1;
 +                ost->resample_height  = icodec->height;
 +                ost->resample_width   = icodec->width;
 +                ost->resample_pix_fmt = icodec->pix_fmt;
  
                  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) {
++                    ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational) { 25, 1 };
 +                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
++                if (   av_q2d(codec->time_base) < 0.001 && video_sync_method
 +                   && (video_sync_method==1 || (video_sync_method<0 && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){
 +                    av_log(oc, 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");
 +                }
 +                for (j = 0; j < ost->forced_kf_count; j++)
 +                    ost->forced_kf_pts[j] = av_rescale_q(ost->forced_kf_pts[j],
 +                                                         AV_TIME_BASE_Q,
 +                                                         codec->time_base);
  
  #if CONFIG_AVFILTER
                  if (configure_video_filters(ist, ost)) {
                      }
                      codec->stats_in = logbuffer;
                  }
 +                if (codec->flags & CODEC_FLAG_PASS1) {
 +                    f = fopen(logfilename, "wb");
 +                    if (!f) {
 +                        av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
 +                               logfilename, strerror(errno));
 +                        exit_program(1);
 +                    }
 +                    ost->logfile = f;
 +                }
              }
          }
--        if(codec->codec_type == AVMEDIA_TYPE_VIDEO){
 -            int size= codec->width * codec->height;
 -            bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 200);
++        if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 +            /* maximum video buffer size is 6-bytes per pixel, plus DPX header size (1664)*/
 +            int size        = codec->width * codec->height;
 +            bit_buffer_size = FFMAX(bit_buffer_size, 7*size + 10000);
          }
      }
  
          }
      }
  
 -    /* init pts */
 -    for (i = 0; i < nb_input_streams; i++) {
 -        AVStream *st;
 -        ist = &input_streams[i];
 -        st= ist->st;
 -        ist->pts = st->avg_frame_rate.num ? - st->codec->has_b_frames*AV_TIME_BASE / av_q2d(st->avg_frame_rate) : 0;
 -        ist->next_pts = AV_NOPTS_VALUE;
 -        init_pts_correction(&ist->pts_ctx);
 -        ist->is_start = 1;
 -    }
 -
 -    /* set meta data information from input file if required */
 -    for (i=0;i<nb_meta_data_maps;i++) {
 -        AVFormatContext *files[2];
 -        AVDictionary    **meta[2];
 -        int j;
 -
 -#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
 -        if ((index) < 0 || (index) >= (nb_elems)) {\
 -            snprintf(error, sizeof(error), "Invalid %s index %d while processing metadata maps\n",\
 -                     (desc), (index));\
 -            ret = AVERROR(EINVAL);\
 -            goto dump_format;\
 +    /* open files and write file headers */
 +    for (i = 0; i < nb_output_files; i++) {
 +        oc = output_files[i].ctx;
 +        oc->interrupt_callback = int_cb;
 +        if (avformat_write_header(oc, &output_files[i].opts) < 0) {
 +            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
 +            ret = AVERROR(EINVAL);
 +            goto dump_format;
          }
 -
 -        int out_file_index = meta_data_maps[i][0].file;
 -        int in_file_index = meta_data_maps[i][1].file;
 -        if (in_file_index < 0 || out_file_index < 0)
 -            continue;
 -        METADATA_CHECK_INDEX(out_file_index, nb_output_files, "output file")
 -        METADATA_CHECK_INDEX(in_file_index, nb_input_files, "input file")
 -
 -        files[0] = output_files[out_file_index];
 -        files[1] = input_files[in_file_index].ctx;
 -
 -        for (j = 0; j < 2; j++) {
 -            MetadataMap *map = &meta_data_maps[i][j];
 -
 -            switch (map->type) {
 -            case 'g':
 -                meta[j] = &files[j]->metadata;
 -                break;
 -            case 's':
 -                METADATA_CHECK_INDEX(map->index, files[j]->nb_streams, "stream")
 -                meta[j] = &files[j]->streams[map->index]->metadata;
 -                break;
 -            case 'c':
 -                METADATA_CHECK_INDEX(map->index, files[j]->nb_chapters, "chapter")
 -                meta[j] = &files[j]->chapters[map->index]->metadata;
 -                break;
 -            case 'p':
 -                METADATA_CHECK_INDEX(map->index, files[j]->nb_programs, "program")
 -                meta[j] = &files[j]->programs[map->index]->metadata;
 -                break;
 -            }
 +//        assert_avoptions(output_files[i].opts);
 +        if (strcmp(oc->oformat->name, "rtp")) {
 +            want_sdp = 0;
          }
 -
 -        av_dict_copy(meta[0], *meta[1], AV_DICT_DONT_OVERWRITE);
      }
  
 -    /* copy global metadata by default */
 -    if (metadata_global_autocopy) {
 -
 -        for (i = 0; i < nb_output_files; i++)
 -            av_dict_copy(&output_files[i]->metadata, input_files[0].ctx->metadata,
 -                         AV_DICT_DONT_OVERWRITE);
 + dump_format:
 +    /* dump the file output parameters - cannot be done before in case
 +       of stream copy */
 +    for (i = 0; i < nb_output_files; i++) {
 +        av_dump_format(output_files[i].ctx, i, output_files[i].ctx->filename, 1);
      }
  
 -    /* copy chapters according to chapter maps */
 -    for (i = 0; i < nb_chapter_maps; i++) {
 -        int infile  = chapter_maps[i].in_file;
 -        int outfile = chapter_maps[i].out_file;
 -
 -        if (infile < 0 || outfile < 0)
 +    /* dump the stream mapping */
 +    av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
 +    for (i = 0; i < nb_output_streams; i++) {
 +        ost = &output_streams[i];
 +
 +        if (ost->attachment_filename) {
 +            /* an attached file */
 +            av_log(NULL, AV_LOG_INFO, "  File %s -> Stream #%d:%d\n",
 +                   ost->attachment_filename, ost->file_index, ost->index);
              continue;
 -        if (infile >= nb_input_files) {
 -            snprintf(error, sizeof(error), "Invalid input file index %d in chapter mapping.\n", infile);
 -            ret = AVERROR(EINVAL);
 -            goto dump_format;
          }
 -        if (outfile >= nb_output_files) {
 -            snprintf(error, sizeof(error), "Invalid output file index %d in chapter mapping.\n",outfile);
 -            ret = AVERROR(EINVAL);
 -            goto dump_format;
 +        av_log(NULL, AV_LOG_INFO, "  Stream #%d:%d -> #%d:%d",
 +               input_streams[ost->source_index].file_index,
 +               input_streams[ost->source_index].st->index,
 +               ost->file_index,
 +               ost->index);
 +        if (ost->audio_channels_mapped) {
 +            av_log(NULL, AV_LOG_INFO, " [ch:");
 +            for (j = 0; j < ost->audio_channels_mapped; j++)
 +                if (ost->audio_channels_map[j] == -1)
 +                    av_log(NULL, AV_LOG_INFO, " M");
 +                else
 +                    av_log(NULL, AV_LOG_INFO, " %d", ost->audio_channels_map[j]);
 +            av_log(NULL, AV_LOG_INFO, "]");
          }
 -        copy_chapters(infile, outfile);
 +        if (ost->sync_ist != &input_streams[ost->source_index])
 +            av_log(NULL, AV_LOG_INFO, " [sync #%d:%d]",
 +                   ost->sync_ist->file_index,
 +                   ost->sync_ist->st->index);
 +        if (ost->stream_copy)
 +            av_log(NULL, AV_LOG_INFO, " (copy)");
 +        else
 +            av_log(NULL, AV_LOG_INFO, " (%s -> %s)", input_streams[ost->source_index].dec ?
 +                   input_streams[ost->source_index].dec->name : "?",
 +                   ost->enc ? ost->enc->name : "?");
 +        av_log(NULL, AV_LOG_INFO, "\n");
      }
  
 -    /* copy chapters from the first input file that has them*/
 -    if (!nb_chapter_maps)
 -        for (i = 0; i < nb_input_files; i++) {
 -            if (!input_files[i].ctx->nb_chapters)
 -                continue;
 -
 -            for (j = 0; j < nb_output_files; j++)
 -                if ((ret = copy_chapters(i, j)) < 0)
 -                    goto dump_format;
 -            break;
 -        }
 -
 -    /* open files and write file headers */
 -    for(i=0;i<nb_output_files;i++) {
 -        os = output_files[i];
 -        if (avformat_write_header(os, &output_opts[i]) < 0) {
 -            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);
 -            ret = AVERROR(EINVAL);
 -            goto dump_format;
 -        }
 -        assert_avoptions(output_opts[i]);
 -        if (strcmp(output_files[i]->oformat->name, "rtp")) {
 -            want_sdp = 0;
 -        }
 +    if (ret) {
 +        av_log(NULL, AV_LOG_ERROR, "%s\n", error);
 +        return ret;
      }
  
 - dump_format:
 -    /* dump the file output parameters - cannot be done before in case
 -       of stream copy */
 -    for(i=0;i<nb_output_files;i++) {
 -        av_dump_format(output_files[i], i, output_files[i]->filename, 1);
 +    if (want_sdp) {
 +        print_sdp(output_files, nb_output_files);
      }
  
 -    /* dump the stream mapping */
 -    if (verbose >= 0) {
 -        fprintf(stderr, "Stream mapping:\n");
 -        for(i=0;i<nb_ostreams;i++) {
 -            ost = ost_table[i];
 -            fprintf(stderr, "  Stream #%d.%d -> #%d.%d",
 -                    input_streams[ost->source_index].file_index,
 -                    input_streams[ost->source_index].st->index,
 -                    ost->file_index,
 -                    ost->index);
 -            if (ost->sync_ist != &input_streams[ost->source_index])
 -                fprintf(stderr, " [sync #%d.%d]",
 -                        ost->sync_ist->file_index,
 -                        ost->sync_ist->st->index);
 -            fprintf(stderr, "\n");
 -        }
 -    }
 +    return 0;
 +}
  
 -    if (ret) {
 -        fprintf(stderr, "%s\n", error);
 +/*
 + * The following code is the main loop of the file converter
 + */
 +static int transcode(OutputFile *output_files, int nb_output_files,
 +                     InputFile  *input_files,  int nb_input_files)
 +{
 +    int ret, i;
 +    AVFormatContext *is, *os;
 +    OutputStream *ost;
 +    InputStream *ist;
 +    uint8_t *no_packet;
-     int no_packet_count=0;
++    int no_packet_count = 0;
 +    int64_t timer_start;
 +    int key;
 +
 +    if (!(no_packet = av_mallocz(nb_input_files)))
 +        exit_program(1);
 +
 +    ret = transcode_init(output_files, nb_output_files, input_files, nb_input_files);
 +    if (ret < 0)
          goto fail;
 -    }
  
 -    if (want_sdp) {
 -        print_sdp(output_files, nb_output_files);
 +    if (!using_stdin) {
 +        av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
      }
  
 -    if (verbose >= 0)
 -        fprintf(stderr, "Press ctrl-c to stop encoding\n");
 -    term_init();
 -
      timer_start = av_gettime();
  
--    for(; received_sigterm == 0;) {
++    for (; received_sigterm == 0;) {
          int file_index, ist_index;
          AVPacket pkt;
 -        double ipts_min;
 +        int64_t ipts_min;
          double opts_min;
 -
 -    redo:
 -        ipts_min= 1e100;
 -        opts_min= 1e100;
 +        int64_t cur_time= av_gettime();
 +
-         ipts_min= INT64_MAX;
-         opts_min= 1e100;
++        ipts_min = INT64_MAX;
++        opts_min = 1e100;
 +        /* if 'q' pressed, exits */
 +        if (!using_stdin) {
 +            static int64_t last_time;
 +            if (received_nb_signals)
 +                break;
 +            /* read_key() returns 0 on EOF */
 +            if(cur_time - last_time >= 100000 && !run_as_daemon){
 +                key =  read_key();
 +                last_time = cur_time;
 +            }else
 +                key = -1;
 +            if (key == 'q')
 +                break;
 +            if (key == '+') av_log_set_level(av_log_get_level()+10);
 +            if (key == '-') av_log_set_level(av_log_get_level()-10);
 +            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 CONFIG_AVFILTER
 +            if (key == 'c' || key == 'C'){
 +                char buf[4096], target[64], command[256], arg[256] = {0};
 +                double time;
 +                int k, n = 0;
 +                fprintf(stderr, "\nEnter command: <target> <time> <command>[ <argument>]\n");
 +                i = 0;
 +                while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
 +                    if (k > 0)
 +                        buf[i++] = k;
 +                buf[i] = 0;
 +                if (k > 0 &&
 +                    (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
 +                    av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
 +                           target, time, command, arg);
 +                    for (i = 0; i < nb_output_streams; i++) {
 +                        ost = &output_streams[i];
 +                        if (ost->graph) {
 +                            if (time < 0) {
 +                                ret = avfilter_graph_send_command(ost->graph, target, command, arg, buf, sizeof(buf),
 +                                                                  key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0);
 +                                fprintf(stderr, "Command reply for stream %d: ret:%d res:%s\n", i, ret, buf);
 +                            } else {
 +                                ret = avfilter_graph_queue_command(ost->graph, target, command, arg, 0, time);
 +                            }
 +                        }
 +                    }
 +                } else {
 +                    av_log(NULL, AV_LOG_ERROR,
 +                           "Parse error, at least 3 arguments were expected, "
 +                           "only %d given in string '%s'\n", n, buf);
 +                }
 +            }
 +#endif
 +            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
 +                    if(scanf("%d", &debug)!=1)
 +                        fprintf(stderr,"error parsing debug value\n");
 +                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"
 +                                "c      Send command to filtergraph\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 */
          file_index = -1;
 -        for(i=0;i<nb_ostreams;i++) {
 -            double ipts, opts;
 -            ost = ost_table[i];
 -            os = output_files[ost->file_index];
 +        for (i = 0; i < nb_output_streams; i++) {
 +            OutputFile *of;
 +            int64_t ipts;
 +            double  opts;
 +            ost = &output_streams[i];
 +            of = &output_files[ost->file_index];
 +            os = output_files[ost->file_index].ctx;
              ist = &input_streams[ost->source_index];
 -            if(ist->is_past_recording_time || no_packet[ist->file_index])
 +            if (ost->is_past_recording_time || no_packet[ist->file_index] ||
 +                (os->pb && avio_tell(os->pb) >= of->limit_filesize))
                  continue;
 -                opts = ost->st->pts.val * av_q2d(ost->st->time_base);
 -            ipts = (double)ist->pts;
 -            if (!input_files[ist->file_index].eof_reached){
 -                if(ipts < ipts_min) {
 +            opts = ost->st->pts.val * av_q2d(ost->st->time_base);
 +            ipts = ist->pts;
-             if (!input_files[ist->file_index].eof_reached){
-                 if(ipts < ipts_min) {
++            if (!input_files[ist->file_index].eof_reached) {
++                if (ipts < ipts_min) {
                      ipts_min = ipts;
--                    if(input_sync ) file_index = ist->file_index;
++                    if (input_sync)
++                        file_index = ist->file_index;
                  }
--                if(opts < opts_min) {
++                if (opts < opts_min) {
                      opts_min = opts;
--                    if(!input_sync) file_index = ist->file_index;
++                    if (!input_sync) file_index = ist->file_index;
                  }
              }
 -            if(ost->frame_number >= max_frames[ost->st->codec->codec_type]){
 -                file_index= -1;
 -                break;
 +            if (ost->frame_number >= ost->max_frames) {
 +                int j;
 +                for (j = 0; j < of->ctx->nb_streams; j++)
 +                    output_streams[of->ost_index + j].is_past_recording_time = 1;
 +                continue;
              }
          }
          /* if none, if is finished */
          if (file_index < 0) {
--            if(no_packet_count){
--                no_packet_count=0;
 -                memset(no_packet, 0, sizeof(no_packet));
++            if (no_packet_count) {
++                no_packet_count = 0;
 +                memset(no_packet, 0, nb_input_files);
                  usleep(10000);
                  continue;
              }
              break;
          }
  
 -        /* finish if limit size exhausted */
 -        if (limit_filesize != 0 && limit_filesize <= avio_tell(output_files[0]->pb))
 -            break;
 -
          /* read a frame from it and output it in the fifo */
--        is = input_files[file_index].ctx;
--        ret= av_read_frame(is, &pkt);
--        if(ret == AVERROR(EAGAIN)){
--            no_packet[file_index]=1;
++        is  = input_files[file_index].ctx;
++        ret = av_read_frame(is, &pkt);
++        if (ret == AVERROR(EAGAIN)) {
++            no_packet[file_index] = 1;
              no_packet_count++;
              continue;
          }
                  continue;
          }
  
--        no_packet_count=0;
 -        memset(no_packet, 0, sizeof(no_packet));
++        no_packet_count = 0;
 +        memset(no_packet, 0, nb_input_files);
  
          if (do_pkt_dump) {
              av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump,
          if (pkt.pts != AV_NOPTS_VALUE)
              pkt.pts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
  
-         if(pkt.pts != AV_NOPTS_VALUE)
 -        if (ist->ts_scale) {
 -            if(pkt.pts != AV_NOPTS_VALUE)
 -                pkt.pts *= ist->ts_scale;
 -            if(pkt.dts != AV_NOPTS_VALUE)
 -                pkt.dts *= ist->ts_scale;
 -        }
++        if (pkt.pts != AV_NOPTS_VALUE)
 +            pkt.pts *= ist->ts_scale;
-         if(pkt.dts != AV_NOPTS_VALUE)
++        if (pkt.dts != AV_NOPTS_VALUE)
 +            pkt.dts *= ist->ts_scale;
  
--//        fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files[ist->file_index].ts_offset, ist->st->codec->codec_type);
++        //fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n",
++        //        ist->next_pts,
++        //        pkt.dts, input_files[ist->file_index].ts_offset,
++        //        ist->st->codec->codec_type);
          if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE
              && (is->iformat->flags & AVFMT_TS_DISCONT)) {
--            int64_t pkt_dts= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
--            int64_t delta= pkt_dts - ist->next_pts;
 -            if((FFABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE || pkt_dts+1<ist->pts)&& !copy_ts){
++            int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
++            int64_t delta   = pkt_dts - ist->next_pts;
 +            if((delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
 +                (delta > 1LL*dts_delta_threshold*AV_TIME_BASE &&
 +                 ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) ||
 +                pkt_dts+1<ist->pts)&& !copy_ts){
                  input_files[ist->file_index].ts_offset -= delta;
-                 av_log(NULL, AV_LOG_DEBUG, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
 -                if (verbose > 2)
 -                    fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
 -                            delta, input_files[ist->file_index].ts_offset);
++                av_log(NULL, AV_LOG_DEBUG,
++                       "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
 +                       delta, input_files[ist->file_index].ts_offset);
                  pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
--                if(pkt.pts != AV_NOPTS_VALUE)
++                if (pkt.pts != AV_NOPTS_VALUE)
                      pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
              }
          }
  
 -        /* finish if recording time exhausted */
 -        if (recording_time != INT64_MAX &&
 -            av_compare_ts(pkt.pts, ist->st->time_base, recording_time + start_time, (AVRational){1, 1000000}) >= 0) {
 -            ist->is_past_recording_time = 1;
 -            goto discard_packet;
 -        }
 -
--        //fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size);
 -        if (output_packet(ist, ist_index, ost_table, nb_ostreams, &pkt) < 0) {
++        // fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size);
 +        if (output_packet(ist, output_streams, nb_output_streams, &pkt) < 0) {
  
 -            if (verbose >= 0)
 -                fprintf(stderr, "Error while decoding stream #%d.%d\n",
 -                        ist->file_index, ist->st->index);
 +            av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
 +                   ist->file_index, ist->st->index);
              if (exit_on_error)
                  exit_program(1);
              av_free_packet(&pkt);
      term_exit();
  
      /* write the trailer if needed and close file */
--    for(i=0;i<nb_output_files;i++) {
 -        os = output_files[i];
++    for (i = 0; i < nb_output_files; i++) {
 +        os = output_files[i].ctx;
          av_write_trailer(os);
      }
  
@@@ -3090,7 -2817,7 +3097,7 @@@ static double parse_frame_aspect_ratio(
      if (p) {
          x = strtol(arg, &end, 10);
          if (end == p)
--            y = strtol(end+1, &end, 10);
++            y = strtol(end + 1, &end, 10);
          if (x > 0 && y > 0)
              ar = (double)x / (double)y;
      } else
@@@ -3416,187 -3119,39 +3423,187 @@@ static AVCodec *find_codec_or_die(cons
      codec = encoder ?
          avcodec_find_encoder_by_name(name) :
          avcodec_find_decoder_by_name(name);
--    if(!codec) {
 -        fprintf(stderr, "Unknown %s '%s'\n", codec_string, name);
++    if (!codec) {
 +        av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
          exit_program(1);
      }
--    if(codec->type != type) {
 -        fprintf(stderr, "Invalid %s type '%s'\n", codec_string, name);
++    if (codec->type != type) {
 +        av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
          exit_program(1);
      }
 -    return codec->id;
 +    return codec;
  }
  
 -static int opt_input_file(const char *opt, const char *filename)
 +static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
  {
 -    AVFormatContext *ic;
 -    AVInputFormat *file_iformat = NULL;
 -    int err, i, ret, rfps, rfps_base;
 -    int64_t timestamp;
 -    uint8_t buf[128];
 -    AVDictionary **opts;
 -    int orig_nb_streams;                     // number of streams before avformat_find_stream_info
 +    char *codec_name = NULL;
  
 -    if (last_asked_format) {
 -        if (!(file_iformat = av_find_input_format(last_asked_format))) {
 -            fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format);
 -            exit_program(1);
 -        }
 -        last_asked_format = NULL;
 -    }
 +    MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
 +    if (codec_name) {
 +        AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
 +        st->codec->codec_id = codec->id;
 +        return codec;
 +    } else
 +        return avcodec_find_decoder(st->codec->codec_id);
 +}
  
 -    if (!strcmp(filename, "-"))
 -        filename = "pipe:";
 +/**
 + * Add all the streams from the given input file to the global
 + * list of input streams.
 + */
 +static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
 +{
 +    int i, rfps, rfps_base;
 +    char *next, *codec_tag = NULL;
 +
 +    for (i = 0; i < ic->nb_streams; i++) {
 +        AVStream *st = ic->streams[i];
 +        AVCodecContext *dec = st->codec;
 +        InputStream *ist;
 +
 +        input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1);
 +        ist = &input_streams[nb_input_streams - 1];
 +        ist->st = st;
 +        ist->file_index = nb_input_files;
 +        ist->discard = 1;
 +        ist->opts = filter_codec_opts(codec_opts, choose_decoder(o, ic, st), ic, st);
 +
 +        ist->ts_scale = 1.0;
 +        MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
 +
 +        MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
 +        if (codec_tag) {
 +            uint32_t tag = strtol(codec_tag, &next, 0);
 +            if (*next)
 +                tag = AV_RL32(codec_tag);
 +            st->codec->codec_tag = tag;
 +        }
 +
 +        ist->dec = choose_decoder(o, ic, st);
 +
 +        switch (dec->codec_type) {
 +        case AVMEDIA_TYPE_AUDIO:
-             if(!ist->dec)
++            if (!ist->dec)
 +                ist->dec = avcodec_find_decoder(dec->codec_id);
-             if(o->audio_disable)
-                 st->discard= AVDISCARD_ALL;
++            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;
 +            }
 +
-             if (dec->time_base.den != rfps*dec->ticks_per_frame || dec->time_base.num != rfps_base) {
++            if (dec->time_base.den != rfps * dec->ticks_per_frame || dec->time_base.num != rfps_base) {
 +
 +                av_log(NULL, AV_LOG_INFO,"\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d)\n",
 +                       i, (float)dec->time_base.den / dec->time_base.num, dec->time_base.den, dec->time_base.num,
 +                       (float)rfps / rfps_base, rfps, rfps_base);
 +            }
 +
 +            if (o->video_disable)
-                 st->discard= AVDISCARD_ALL;
-             else if(video_discard)
-                 st->discard= video_discard;
++                st->discard = AVDISCARD_ALL;
++            else if (video_discard)
++                st->discard = video_discard;
 +            break;
 +        case AVMEDIA_TYPE_DATA:
 +            if (o->data_disable)
 +                st->discard= AVDISCARD_ALL;
 +            break;
 +        case AVMEDIA_TYPE_SUBTITLE:
 +            if(!ist->dec)
 +                ist->dec = avcodec_find_decoder(dec->codec_id);
 +            if(o->subtitle_disable)
 +                st->discard = AVDISCARD_ALL;
 +            break;
 +        case AVMEDIA_TYPE_ATTACHMENT:
 +        case AVMEDIA_TYPE_UNKNOWN:
 +            break;
 +        default:
 +            abort();
 +        }
 +    }
 +}
 +
 +static void assert_file_overwrite(const char *filename)
 +{
 +    if ((!file_overwrite || no_file_overwrite) &&
 +        (strchr(filename, ':') == NULL || filename[1] == ':' ||
 +         av_strstart(filename, "file:", NULL))) {
 +        if (avio_check(filename, 0) == 0) {
 +            if (!using_stdin && (!no_file_overwrite || file_overwrite)) {
 +                fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
 +                fflush(stderr);
 +                term_exit();
 +                signal(SIGINT, SIG_DFL);
 +                if (!read_yesno()) {
 +                    av_log(0, AV_LOG_FATAL, "Not overwriting - exiting\n");
 +                    exit_program(1);
 +                }
 +                term_init();
 +            }
 +            else {
 +                av_log(0, AV_LOG_FATAL, "File '%s' already exists. Exiting.\n", filename);
 +                exit_program(1);
 +            }
 +        }
 +    }
 +}
 +
 +static void dump_attachment(AVStream *st, const char *filename)
 +{
 +    int ret;
 +    AVIOContext *out = NULL;
 +    AVDictionaryEntry *e;
 +
 +    if (!st->codec->extradata_size) {
 +        av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
 +               nb_input_files - 1, st->index);
 +        return;
 +    }
 +    if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
 +        filename = e->value;
 +    if (!*filename) {
 +        av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
 +               "in stream #%d:%d.\n", nb_input_files - 1, st->index);
 +        exit_program(1);
 +    }
 +
 +    assert_file_overwrite(filename);
 +
 +    if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
 +        av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
 +               filename);
 +        exit_program(1);
 +    }
 +
 +    avio_write(out, st->codec->extradata, st->codec->extradata_size);
 +    avio_flush(out);
 +    avio_close(out);
 +}
 +
 +static int opt_input_file(OptionsContext *o, const char *opt, const char *filename)
 +{
 +    AVFormatContext *ic;
 +    AVInputFormat *file_iformat = NULL;
 +    int err, i, ret;
 +    int64_t timestamp;
 +    uint8_t buf[128];
 +    AVDictionary **opts;
 +    int orig_nb_streams;                     // number of streams before avformat_find_stream_info
 +
 +    if (o->format) {
 +        if (!(file_iformat = av_find_input_format(o->format))) {
 +            av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
 +            exit_program(1);
 +        }
 +    }
 +
 +    if (!strcmp(filename, "-"))
 +        filename = "pipe:";
  
      using_stdin |= !strncmp(filename, "pipe:", 5) ||
                      !strcmp(filename, "/dev/stdin");
      return 0;
  }
  
 -static void check_inputs(int *has_video_ptr,
 -                         int *has_audio_ptr,
 -                         int *has_subtitle_ptr,
 -                         int *has_data_ptr)
 +static void parse_forced_key_frames(char *kf, OutputStream *ost)
  {
 -    int has_video, has_audio, has_subtitle, has_data, i, j;
 -    AVFormatContext *ic;
 +    char *p;
 +    int n = 1, i;
  
 -    has_video = 0;
 -    has_audio = 0;
 -    has_subtitle = 0;
 -    has_data = 0;
 +    for (p = kf; *p; p++)
 +        if (*p == ',')
 +            n++;
 +    ost->forced_kf_count = n;
-     ost->forced_kf_pts = av_malloc(sizeof(*ost->forced_kf_pts) * n);
++    ost->forced_kf_pts   = av_malloc(sizeof(*ost->forced_kf_pts) * n);
 +    if (!ost->forced_kf_pts) {
 +        av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
 +        exit_program(1);
 +    }
 +    for (i = 0; i < n; i++) {
 +        p = i ? strchr(p, ',') + 1 : kf;
 +        ost->forced_kf_pts[i] = parse_time_or_die("force_key_frames", p, 1);
 +    }
 +}
  
 -    for(j=0;j<nb_input_files;j++) {
 -        ic = input_files[j].ctx;
 -        for(i=0;i<ic->nb_streams;i++) {
 -            AVCodecContext *enc = ic->streams[i]->codec;
 -            switch(enc->codec_type) {
 -            case AVMEDIA_TYPE_AUDIO:
 -                has_audio = 1;
 -                break;
 -            case AVMEDIA_TYPE_VIDEO:
 -                has_video = 1;
 -                break;
 -            case AVMEDIA_TYPE_SUBTITLE:
 -                has_subtitle = 1;
 -                break;
 -            case AVMEDIA_TYPE_DATA:
 -            case AVMEDIA_TYPE_ATTACHMENT:
 -            case AVMEDIA_TYPE_UNKNOWN:
 -                has_data = 1;
 -                break;
 -            default:
 -                abort();
 -            }
 +static uint8_t *get_line(AVIOContext *s)
 +{
 +    AVIOContext *line;
 +    uint8_t *buf;
 +    char c;
 +
 +    if (avio_open_dyn_buf(&line) < 0) {
 +        av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
 +        exit_program(1);
 +    }
 +
 +    while ((c = avio_r8(s)) && c != '\n')
 +        avio_w8(line, c);
 +    avio_w8(line, 0);
 +    avio_close_dyn_buf(line, &buf);
 +
 +    return buf;
 +}
 +
 +static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
 +{
 +    int i, ret = 1;
 +    char filename[1000];
 +    const char *base[3] = { getenv("AVCONV_DATADIR"),
 +                            getenv("HOME"),
 +                            AVCONV_DATADIR,
 +                            };
 +
 +    for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
 +        if (!base[i])
 +            continue;
 +        if (codec_name) {
 +            snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
 +                     i != 1 ? "" : "/.avconv", codec_name, preset_name);
 +            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
 +        }
 +        if (ret) {
 +            snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
 +                     i != 1 ? "" : "/.avconv", preset_name);
 +            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
          }
      }
 -    *has_video_ptr = has_video;
 -    *has_audio_ptr = has_audio;
 -    *has_subtitle_ptr = has_subtitle;
 -    *has_data_ptr = has_data;
 +    return ret;
  }
  
 -static void new_video_stream(AVFormatContext *oc, int file_idx)
 +static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
 +{
 +    char *codec_name = NULL;
 +
 +    MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
 +    if (!codec_name) {
 +        ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
 +                                                  NULL, ost->st->codec->codec_type);
 +        ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
 +    } else if (!strcmp(codec_name, "copy"))
 +        ost->stream_copy = 1;
 +    else {
 +        ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
 +        ost->st->codec->codec_id = ost->enc->id;
 +    }
 +}
 +
 +static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
  {
 -    AVStream *st;
      OutputStream *ost;
 -    AVCodecContext *video_enc;
 -    enum CodecID codec_id = CODEC_ID_NONE;
 -    AVCodec *codec= NULL;
 +    AVStream *st = avformat_new_stream(oc, NULL);
 +    int idx      = oc->nb_streams - 1, ret = 0;
 +    char *bsf = NULL, *next, *codec_tag = NULL;
 +    AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
 +    double qscale = -1;
 +    char *buf = NULL, *arg = NULL, *preset = NULL;
 +    AVIOContext *s = NULL;
  
 -    if(!video_stream_copy){
 -        if (video_codec_name) {
 -            codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1);
 -            codec = avcodec_find_encoder_by_name(video_codec_name);
 -        } else {
 -            codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
 -            codec = avcodec_find_encoder(codec_id);
 -        }
 +    if (!st) {
 +        av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
 +        exit_program(1);
      }
  
 -    ost = new_output_stream(oc, file_idx, codec);
 -    st  = ost->st;
 -    if (!video_stream_copy) {
 -        ost->frame_aspect_ratio = frame_aspect_ratio;
 -        frame_aspect_ratio = 0;
 -#if CONFIG_AVFILTER
 -        ost->avfilter= vfilters;
 -        vfilters = NULL;
 -#endif
 +    if (oc->nb_streams - 1 < o->nb_streamid_map)
 +        st->id = o->streamid_map[oc->nb_streams - 1];
 +
 +    output_streams = grow_array(output_streams, sizeof(*output_streams), &nb_output_streams,
 +                                nb_output_streams + 1);
 +    ost = &output_streams[nb_output_streams - 1];
 +    ost->file_index = nb_output_files;
-     ost->index = idx;
-     ost->st    = st;
++    ost->index      = idx;
++    ost->st         = st;
 +    st->codec->codec_type = type;
 +    choose_encoder(o, oc, ost);
 +    if (ost->enc) {
 +        ost->opts  = filter_codec_opts(codec_opts, ost->enc, oc, st);
      }
  
 -    ost->bitstream_filters = video_bitstream_filters;
 -    video_bitstream_filters= NULL;
 +    avcodec_get_context_defaults3(st->codec, ost->enc);
 +    st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
 +
 +    MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
 +    if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
 +        do  {
 +            buf = get_line(s);
 +            if (!buf[0] || buf[0] == '#') {
 +                av_free(buf);
 +                continue;
 +            }
 +            if (!(arg = strchr(buf, '='))) {
 +                av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
 +                exit_program(1);
 +            }
 +            *arg++ = 0;
 +            av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
 +            av_free(buf);
 +        } while (!s->eof_reached);
 +        avio_close(s);
 +    }
 +    if (ret) {
 +        av_log(NULL, AV_LOG_FATAL,
 +               "Preset %s specified for stream %d:%d, but could not be opened.\n",
 +               preset, ost->file_index, ost->index);
 +        exit_program(1);
 +    }
  
 -    st->codec->thread_count= thread_count;
 +    ost->max_frames = INT64_MAX;
 +    MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
  
 -    video_enc = st->codec;
 +    MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
 +    while (bsf) {
 +        if (next = strchr(bsf, ','))
 +            *next++ = 0;
 +        if (!(bsfc = av_bitstream_filter_init(bsf))) {
 +            av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
 +            exit_program(1);
 +        }
 +        if (bsfc_prev)
 +            bsfc_prev->next = bsfc;
 +        else
 +            ost->bitstream_filters = bsfc;
  
 -    if(video_codec_tag)
 -        video_enc->codec_tag= video_codec_tag;
 +        bsfc_prev = bsfc;
 +        bsf       = next;
 +    }
  
 -    if(oc->oformat->flags & AVFMT_GLOBALHEADER) {
 -        video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
 +    MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
 +    if (codec_tag) {
 +        uint32_t tag = strtol(codec_tag, &next, 0);
 +        if (*next)
 +            tag = AV_RL32(codec_tag);
 +        st->codec->codec_tag = tag;
      }
  
 -    video_enc->codec_type = AVMEDIA_TYPE_VIDEO;
 -    if (video_stream_copy) {
 -        st->stream_copy = 1;
 -        video_enc->sample_aspect_ratio =
 -        st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255);
 -    } else {
 -        const char *p;
 +    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;
 +    }
 +
 +    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
 +        st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
 +
 +    av_opt_get_int(sws_opts, "sws_flags", 0, &ost->sws_flags);
 +    return ost;
 +}
 +
 +static void parse_matrix_coeffs(uint16_t *dest, const char *str)
 +{
 +    int i;
 +    const char *p = str;
-     for(i = 0;; i++) {
++    for (i = 0;; i++) {
 +        dest[i] = atoi(p);
-         if(i == 63)
++        if (i == 63)
 +            break;
 +        p = strchr(p, ',');
-         if(!p) {
++        if (!p) {
 +            av_log(NULL, AV_LOG_FATAL, "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;
 +    OutputStream *ost;
 +    AVCodecContext *video_enc;
 +
 +    ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
 +    st  = ost->st;
 +    video_enc = st->codec;
 +
 +    if (!ost->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;
  
 -        if (frame_rate.num)
 -            ost->frame_rate = frame_rate;
 -        video_enc->codec_id = codec_id;
 +        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_FATAL, "Invalid framerate value: %s\n", frame_rate);
 +            exit_program(1);
 +        }
 +
 +        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_FATAL, "Invalid frame size: %s.\n", frame_size);
 +            exit_program(1);
 +        }
 +
 +        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);
  
 -        video_enc->width = frame_width;
 -        video_enc->height = frame_height;
 -        video_enc->pix_fmt = frame_pix_fmt;
 +        video_enc->bits_per_raw_sample = frame_bits_per_raw_sample;
 +        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_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
 +            exit_program(1);
 +        }
          st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
  
          if (intra_only)
              video_enc->gop_size = 0;
 -        if (video_qscale || same_quality) {
 -            video_enc->flags |= CODEC_FLAG_QSCALE;
 -            video_enc->global_quality = FF_QP2LAMBDA * video_qscale;
 +        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_FATAL, "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_FATAL, "Could not allocate memory for inter matrix.\n");
 +                exit_program(1);
 +            }
 +            parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
          }
  
 -        if(intra_matrix)
 -            video_enc->intra_matrix = intra_matrix;
 -        if(inter_matrix)
 -            video_enc->inter_matrix = inter_matrix;
 -
 -        p= video_rc_override_string;
 -        for(i=0; p; i++){
 +        MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
-         for(i=0; p; i++){
++        for (i = 0; p; i++) {
              int start, end, q;
--            int e=sscanf(p, "%d,%d,%d", &start, &end, &q);
--            if(e!=3){
 -                fprintf(stderr, "error parsing rc_override\n");
++            int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
++            if (e != 3) {
 +                av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
                  exit_program(1);
              }
 -            video_enc->rc_override=
 +            /* FIXME realloc failure */
-             video_enc->rc_override=
++            video_enc->rc_override =
                  av_realloc(video_enc->rc_override,
--                           sizeof(RcOverride)*(i+1));
--            video_enc->rc_override[i].start_frame= start;
--            video_enc->rc_override[i].end_frame  = end;
--            if(q>0){
--                video_enc->rc_override[i].qscale= q;
--                video_enc->rc_override[i].quality_factor= 1.0;
++                           sizeof(RcOverride) * (i + 1));
++            video_enc->rc_override[i].start_frame = start;
++            video_enc->rc_override[i].end_frame   = end;
++            if (q > 0) {
++                video_enc->rc_override[i].qscale         = q;
++                video_enc->rc_override[i].quality_factor = 1.0;
              }
--            else{
--                video_enc->rc_override[i].qscale= 0;
--                video_enc->rc_override[i].quality_factor= -q/100.0;
++            else {
++                video_enc->rc_override[i].qscale         = 0;
++                video_enc->rc_override[i].quality_factor = -q/100.0;
              }
--            p= strchr(p, '/');
--            if(p) p++;
++            p = strchr(p, '/');
++            if (p) p++;
          }
--        video_enc->rc_override_count=i;
++        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;
++            video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size * 3 / 4;
++        video_enc->intra_dc_precision = intra_dc_precision - 8;
  
          if (do_psnr)
              video_enc->flags|= CODEC_FLAG_PSNR;
@@@ -4135,88 -3699,9 +4142,88 @@@ static int opt_streamid(OptionsContext 
          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;
 +}
 +
 +static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
 +{
 +    AVFormatContext *is = ifile->ctx;
 +    AVFormatContext *os = ofile->ctx;
 +    int i;
 +
 +    for (i = 0; i < is->nb_chapters; i++) {
 +        AVChapter *in_ch = is->chapters[i], *out_ch;
 +        int64_t ts_off   = av_rescale_q(ofile->start_time - ifile->ts_offset,
-                                       AV_TIME_BASE_Q, in_ch->time_base);
++                                       AV_TIME_BASE_Q, in_ch->time_base);
 +        int64_t rt       = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
 +                           av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
 +
 +
 +        if (in_ch->end < ts_off)
 +            continue;
 +        if (rt != INT64_MAX && in_ch->start > rt + ts_off)
 +            break;
 +
 +        out_ch = av_mallocz(sizeof(AVChapter));
 +        if (!out_ch)
 +            return AVERROR(ENOMEM);
 +
 +        out_ch->id        = in_ch->id;
 +        out_ch->time_base = in_ch->time_base;
 +        out_ch->start     = FFMAX(0,  in_ch->start - ts_off);
 +        out_ch->end       = FFMIN(rt, in_ch->end   - ts_off);
 +
 +        if (copy_metadata)
 +            av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
 +
 +        os->nb_chapters++;
 +        os->chapters = av_realloc_f(os->chapters, os->nb_chapters, sizeof(AVChapter));
 +        if (!os->chapters)
 +            return AVERROR(ENOMEM);
 +        os->chapters[os->nb_chapters - 1] = out_ch;
 +    }
 +    return 0;
 +}
 +
 +static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
 +{
 +    int i, err;
 +    AVFormatContext *ic = avformat_alloc_context();
 +
 +    ic->interrupt_callback = int_cb;
 +    err = avformat_open_input(&ic, filename, NULL, NULL);
 +    if (err < 0)
 +        return err;
 +    /* copy stream format */
 +    for(i=0;i<ic->nb_streams;i++) {
 +        AVStream *st;
 +        OutputStream *ost;
 +        AVCodec *codec;
 +        AVCodecContext *avctx;
 +
 +        codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
 +        ost   = new_output_stream(o, s, codec->type);
 +        st    = ost->st;
 +        avctx = st->codec;
 +        ost->enc = codec;
 +
 +        // FIXME: a more elegant solution is needed
 +        memcpy(st, ic->streams[i], sizeof(AVStream));
 +        st->info = av_malloc(sizeof(*st->info));
 +        memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
 +        st->codec= avctx;
 +        avcodec_copy_context(st->codec, ic->streams[i]->codec);
 +
 +        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
 +            choose_sample_fmt(st, codec);
 +        else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
 +            choose_pixel_fmt(st, codec);
 +    }
 +
 +    av_close_input_file(ic);
      return 0;
  }
  
@@@ -4232,120 -3715,25 +4239,120 @@@ static void opt_output_file(void *optct
      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);
      }
 +    file_oformat= oc->oformat;
 +    oc->interrupt_callback = int_cb;
  
 -    if (last_asked_format) {
 -        file_oformat = av_guess_format(last_asked_format, NULL, NULL);
 -        if (!file_oformat) {
 -            fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", last_asked_format);
 +    if (!strcmp(file_oformat->name, "ffm") &&
 +        av_strstart(filename, "http:", NULL)) {
 +        int j;
 +        /* 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);
          }
 -        last_asked_format = NULL;
 +        for(j = nb_output_streams - oc->nb_streams; j < nb_output_streams; j++) {
 +            ost = &output_streams[j];
 +            for (i = 0; i < nb_input_streams; i++) {
 +                ist = &input_streams[i];
 +                if(ist->st->codec->codec_type == ost->st->codec->codec_type){
 +                    ost->sync_ist= ist;
 +                    ost->source_index= i;
 +                    ist->discard = 0;
 +                    break;
 +                }
 +            }
 +            if(!ost->sync_ist){
 +                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));
 +                exit_program(1);
 +            }
 +        }
 +    } else if (!o->nb_stream_maps) {
 +        /* pick the "best" stream of each type */
 +#define NEW_STREAM(type, index)\
 +        if (index >= 0) {\
 +            ost = new_ ## type ## _stream(o, oc);\
 +            ost->source_index = index;\
 +            ost->sync_ist     = &input_streams[index];\
 +            input_streams[index].discard = 0;\
 +        }
 +
 +        /* video: highest resolution */
 +        if (!o->video_disable && oc->oformat->video_codec != CODEC_ID_NONE) {
 +            int area = 0, idx = -1;
 +            for (i = 0; i < nb_input_streams; i++) {
 +                ist = &input_streams[i];
 +                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
 +                    ist->st->codec->width * ist->st->codec->height > area) {
 +                    area = ist->st->codec->width * ist->st->codec->height;
 +                    idx = i;
 +                }
 +            }
 +            NEW_STREAM(video, idx);
 +        }
 +
 +        /* audio: most channels */
 +        if (!o->audio_disable && oc->oformat->audio_codec != CODEC_ID_NONE) {
 +            int channels = 0, idx = -1;
 +            for (i = 0; i < nb_input_streams; i++) {
 +                ist = &input_streams[i];
 +                if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
 +                    ist->st->codec->channels > channels) {
 +                    channels = ist->st->codec->channels;
 +                    idx = i;
 +                }
 +            }
 +            NEW_STREAM(audio, idx);
 +        }
 +
 +        /* subtitles: pick first */
 +        if (!o->subtitle_disable && (oc->oformat->subtitle_codec != CODEC_ID_NONE || subtitle_codec_name)) {
 +            for (i = 0; i < nb_input_streams; i++)
 +                if (input_streams[i].st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
 +                    NEW_STREAM(subtitle, i);
 +                    break;
 +                }
 +        }
 +        /* do something with data? */
      } 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);
 +        for (i = 0; i < o->nb_stream_maps; i++) {
 +            StreamMap *map = &o->stream_maps[i];
 +
 +            if (map->disabled)
 +                continue;
 +
 +            ist = &input_streams[input_files[map->file_index].ist_index + map->stream_index];
 +            if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
 +                continue;
 +            if(o->   audio_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
 +                continue;
 +            if(o->   video_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
 +                continue;
 +            if(o->    data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA)
 +                continue;
 +
 +            switch (ist->st->codec->codec_type) {
 +            case AVMEDIA_TYPE_VIDEO:    ost = new_video_stream(o, oc);    break;
 +            case AVMEDIA_TYPE_AUDIO:    ost = new_audio_stream(o, oc);    break;
 +            case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
 +            case AVMEDIA_TYPE_DATA:     ost = new_data_stream(o, oc);     break;
 +            case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
 +            default:
 +                av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
 +                       map->file_index, map->stream_index);
 +                exit_program(1);
 +            }
 +
 +            ost->source_index = input_files[map->file_index].ist_index + map->stream_index;
-             ost->sync_ist = &input_streams[input_files[map->sync_file_index].ist_index +
++            ost->sync_ist     = &input_streams[input_files[map->sync_file_index].ist_index +
 +                                           map->sync_stream_index];
 +            ist->discard = 0;
          }
      }
  
@@@ -4608,70 -3957,109 +4615,70 @@@ static int opt_help(const char *opt, co
                        OPT_GRAB,
                        OPT_GRAB);
      printf("\n");
 -    class = avcodec_get_class();
 -    av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
 -    printf("\n");
 -
 -    /* individual codec options */
 -    c = NULL;
 -    while ((c = av_codec_next(c))) {
 -        if (c->priv_class) {
 -            av_opt_show2(&c->priv_class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
 -            printf("\n");
 -        }
 -    }
 -
 -    class = avformat_get_class();
 -    av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
 -    printf("\n");
 -
 -    /* individual muxer options */
 -    while ((oformat = av_oformat_next(oformat))) {
 -        if (oformat->priv_class) {
 -            av_opt_show2(&oformat->priv_class, NULL, AV_OPT_FLAG_ENCODING_PARAM, 0);
 -            printf("\n");
 -        }
 -    }
 +    show_help_children(avcodec_get_class(), flags);
 +    show_help_children(avformat_get_class(), flags);
 +    show_help_children(sws_get_class(), flags);
  
 -    /* individual demuxer options */
 -    while ((iformat = av_iformat_next(iformat))) {
 -        if (iformat->priv_class) {
 -            av_opt_show2(&iformat->priv_class, NULL, AV_OPT_FLAG_DECODING_PARAM, 0);
 -            printf("\n");
 -        }
 -    }
 -
 -    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(const char *opt, const char *arg)
 +static int opt_target(OptionsContext *o, const char *opt, const char *arg)
  {
      enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
--    static const char *const frame_rates[] = {"25", "30000/1001", "24000/1001"};
++    static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
  
--    if(!strncmp(arg, "pal-", 4)) {
++    if (!strncmp(arg, "pal-", 4)) {
          norm = PAL;
          arg += 4;
--    } else if(!strncmp(arg, "ntsc-", 5)) {
++    } else if (!strncmp(arg, "ntsc-", 5)) {
          norm = NTSC;
          arg += 5;
--    } else if(!strncmp(arg, "film-", 5)) {
++    } else if (!strncmp(arg, "film-", 5)) {
          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].ctx->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) {
++        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)
++                    if (c->codec_type != AVMEDIA_TYPE_VIDEO)
 +                        continue;
 +                    fr = c->time_base.den * 1000 / c->time_base.num;
-                     if(fr == 25000) {
++                    if (fr == 25000) {
 +                        norm = PAL;
 +                        break;
-                     } else if((fr == 29970) || (fr == 23976)) {
++                    } else if ((fr == 29970) || (fr == 23976)) {
 +                        norm = NTSC;
                          break;
 +                    }
                  }
-                 if(norm != UNKNOWN)
++                if (norm != UNKNOWN)
 +                    break;
              }
          }
 -        if(verbose > 0 && norm != UNKNOWN)
 -            fprintf(stderr, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
 +        if (norm != UNKNOWN)
 +            av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
      }
  
--    if(norm == UNKNOWN) {
 -        fprintf(stderr, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
 -        fprintf(stderr, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
 -        fprintf(stderr, "or set a framerate with \"-r xxx\".\n");
++    if (norm == UNKNOWN) {
 +        av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
 +        av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
 +        av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
          exit_program(1);
      }
  
--    if(!strcmp(arg, "vcd")) {
 -        opt_video_codec("vcodec", "mpeg1video");
 -        opt_audio_codec("vcodec", "mp2");
 -        opt_format("f", "vcd");
++    if (!strcmp(arg, "vcd")) {
 +        opt_video_codec(o, "c:v", "mpeg1video");
 +        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");
 +        opt_default("b:v", "1150000");
          opt_default("maxrate", "1150000");
          opt_default("minrate", "1150000");
          opt_default("bufsize", "327680"); // 40*1024*8;
             and the first pack from the other stream, respectively, may also have
             been written before.
             So the real data starts at SCR 36000+3*1200. */
-         o->mux_preload = (36000+3*1200) / 90000.0; //0.44
 -        mux_preload= (36000+3*1200) / 90000.0; //0.44
--    } else if(!strcmp(arg, "svcd")) {
++        o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
++    } else if (!strcmp(arg, "svcd")) {
  
 -        opt_video_codec("vcodec", "mpeg2video");
 -        opt_audio_codec("acodec", "mp2");
 -        opt_format("f", "svcd");
 +        opt_video_codec(o, "c:v", "mpeg2video");
 +        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);
 +        parse_option(o, "pix_fmt", "yuv420p", options);
          opt_default("g", norm == PAL ? "15" : "18");
  
 -        opt_default("b", "2040000");
 +        opt_default("b:v", "2040000");
          opt_default("maxrate", "2516000");
--        opt_default("minrate", "0"); //1145000;
--        opt_default("bufsize", "1835008"); //224*1024*8;
++        opt_default("minrate", "0"); // 1145000;
++        opt_default("bufsize", "1835008"); // 224*1024*8;
          opt_default("flags", "+scan_offset");
  
  
  
          opt_default("packetsize", "2324");
  
--    } else if(!strcmp(arg, "dvd")) {
++    } else if (!strcmp(arg, "dvd")) {
  
 -        opt_video_codec("vcodec", "mpeg2video");
 -        opt_audio_codec("vcodec", "ac3");
 -        opt_format("f", "dvd");
 +        opt_video_codec(o, "c:v", "mpeg2video");
 +        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);
 +        parse_option(o, "pix_fmt", "yuv420p", options);
          opt_default("g", norm == PAL ? "15" : "18");
  
 -        opt_default("b", "6000000");
 +        opt_default("b:v", "6000000");
          opt_default("maxrate", "9000000");
--        opt_default("minrate", "0"); //1500000;
--        opt_default("bufsize", "1835008"); //224*1024*8;
++        opt_default("minrate", "0"); // 1500000;
++        opt_default("bufsize", "1835008"); // 224*1024*8;
  
          opt_default("packetsize", "2048");  // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack.
          opt_default("muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8
  
 -        opt_default("ab", "448000");
 -        audio_sample_rate = 48000;
 +        opt_default("b:a", "448000");
 +        parse_option(o, "ar", "48000", options);
  
--    } else if(!strncmp(arg, "dv", 2)) {
++    } else if (!strncmp(arg, "dv", 2)) {
  
 -        opt_format("f", "dv");
 +        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;
 -        audio_channels = 2;
 +        parse_option(o, "ar", "48000", options);
 +        parse_option(o, "ac", "2", options);
  
      } else {
 -        fprintf(stderr, "Unknown target: %s\n", arg);
 +        av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
          return AVERROR(EINVAL);
      }
      return 0;
  static int opt_vstats_file(const char *opt, const char *arg)
  {
      av_free (vstats_filename);
--    vstats_filename=av_strdup (arg);
++    vstats_filename = av_strdup (arg);
      return 0;
  }
  
@@@ -5034,16 -4370,22 +5041,16 @@@ int main(int argc, char **argv
      av_register_all();
      avformat_network_init();
  
 -    avio_set_interrupt_cb(decode_interrupt_cb);
 +    show_banner(argc, argv, options);
  
 -    init_opts();
 -
 -    show_banner();
 -
 -    av_log(NULL, AV_LOG_WARNING, "This program is not developed anymore and is only "
 -                                 "provided for compatibility. Use avconv instead "
 -                                 "(see Changelog for the list of incompatible changes).\n");
 +    term_init();
  
      /* parse options */
 -    parse_options(NULL, argc, argv, options, opt_output_file);
 +    parse_options(&o, argc, argv, options, opt_output_file);
  
--    if(nb_output_files <= 0 && nb_input_files == 0) {
++    if (nb_output_files <= 0 && nb_input_files == 0) {
          show_usage();
 -        fprintf(stderr, "Use -h to get full help or, even better, run 'man ffmpeg'\n");
 +        av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
          exit_program(1);
      }
  
@@@ -82,28 -75,10 +82,28 @@@ static av_cold int MP3lame_encode_init(
      if (lame_init_params(s->gfp) < 0)
          goto err_close;
  
-     avctx->frame_size = lame_get_framesize(s->gfp);
+     avctx->frame_size             = lame_get_framesize(s->gfp);
 -    avctx->coded_frame            = avcodec_alloc_frame();
 +
 +    if(!(avctx->coded_frame= avcodec_alloc_frame())) {
 +        lame_close(s->gfp);
 +
 +        return AVERROR(ENOMEM);
 +    }
-     avctx->coded_frame->key_frame= 1;
+     avctx->coded_frame->key_frame = 1;
  
 +    if(AV_SAMPLE_FMT_S32 == avctx->sample_fmt && s->stereo) {
 +        int nelem = 2 * avctx->frame_size;
 +
 +        if(! (s->s32_data.left = av_malloc(nelem * sizeof(int)))) {
 +            av_freep(&avctx->coded_frame);
 +            lame_close(s->gfp);
 +
 +            return AVERROR(ENOMEM);
 +        }
 +
 +        s->s32_data.right = s->s32_data.left + avctx->frame_size;
 +    }
 +
      return 0;
  
  err_close:
@@@ -178,69 -155,29 +180,71 @@@ static int MP3lame_encode_frame(AVCodec
  
      /* lame 3.91 dies on '1-channel interleaved' data */
  
-     if(!data){
 -    if (data) {
++    if (!data){
 +        lame_result= lame_encode_flush(
 +                s->gfp,
 +                s->buffer + s->buffer_index,
 +                BUFFER_SIZE - s->buffer_index
 +                );
 +#if 2147483647 == INT_MAX
 +    }else if(AV_SAMPLE_FMT_S32 == avctx->sample_fmt){
          if (s->stereo) {
 -            lame_result = lame_encode_buffer_interleaved(s->gfp, data,
 -                                                         avctx->frame_size,
 -                                                         s->buffer + s->buffer_index,
 -                                                         BUFFER_SIZE - s->buffer_index);
 +            int32_t *rp = data;
 +            int32_t *mp = rp + 2*avctx->frame_size;
 +            int *wpl = s->s32_data.left;
 +            int *wpr = s->s32_data.right;
 +
 +            while (rp < mp) {
 +                *wpl++ = *rp++;
 +                *wpr++ = *rp++;
 +            }
 +
 +            lame_result = lame_encode_buffer_int(
 +                s->gfp,
 +                s->s32_data.left,
 +                s->s32_data.right,
 +                avctx->frame_size,
 +                s->buffer + s->buffer_index,
 +                BUFFER_SIZE - s->buffer_index
 +                );
          } else {
 -            lame_result = lame_encode_buffer(s->gfp, data, data,
 -                                             avctx->frame_size, s->buffer +
 -                                             s->buffer_index, BUFFER_SIZE -
 -                                             s->buffer_index);
 +            lame_result = lame_encode_buffer_int(
 +                s->gfp,
 +                data,
 +                data,
 +                avctx->frame_size,
 +                s->buffer + s->buffer_index,
 +                BUFFER_SIZE - s->buffer_index
 +                );
 +        }
 +#endif
 +    }else{
 +        if (s->stereo) {
 +            lame_result = lame_encode_buffer_interleaved(
 +                s->gfp,
 +                data,
 +                avctx->frame_size,
 +                s->buffer + s->buffer_index,
 +                BUFFER_SIZE - s->buffer_index
 +                );
 +        } else {
 +            lame_result = lame_encode_buffer(
 +                s->gfp,
 +                data,
 +                data,
 +                avctx->frame_size,
 +                s->buffer + s->buffer_index,
 +                BUFFER_SIZE - s->buffer_index
 +                );
          }
 -    } else {
 -        lame_result = lame_encode_flush(s->gfp, s->buffer + s->buffer_index,
 -                                        BUFFER_SIZE - s->buffer_index);
      }
  
-     if(lame_result < 0){
-         if(lame_result==-1) {
+     if (lame_result < 0) {
+         if (lame_result == -1) {
              /* output buffer too small */
-             av_log(avctx, AV_LOG_ERROR, "lame: output buffer too small (buffer index: %d, free bytes: %d)\n", s->buffer_index, BUFFER_SIZE - s->buffer_index);
+             av_log(avctx, AV_LOG_ERROR,
+                    "lame: output buffer too small (buffer index: %d, free bytes: %d)\n",
+                    s->buffer_index, BUFFER_SIZE - s->buffer_index);
          }
          return -1;
      }
@@@ -292,20 -229,17 +297,20 @@@ static const AVClass libmp3lame_class 
  };
  
  AVCodec ff_libmp3lame_encoder = {
-     .name           = "libmp3lame",
-     .type           = AVMEDIA_TYPE_AUDIO,
-     .id             = CODEC_ID_MP3,
-     .priv_data_size = sizeof(Mp3AudioContext),
-     .init           = MP3lame_encode_init,
-     .encode         = MP3lame_encode_frame,
-     .close          = MP3lame_encode_close,
-     .capabilities= CODEC_CAP_DELAY,
-     .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,
+     .name                  = "libmp3lame",
+     .type                  = AVMEDIA_TYPE_AUDIO,
+     .id                    = CODEC_ID_MP3,
+     .priv_data_size        = sizeof(Mp3AudioContext),
+     .init                  = MP3lame_encode_init,
+     .encode                = MP3lame_encode_frame,
+     .close                 = MP3lame_encode_close,
+     .capabilities          = CODEC_CAP_DELAY,
+     .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
 +#if 2147483647 == INT_MAX
 +    AV_SAMPLE_FMT_S32,
 +#endif
-     AV_SAMPLE_FMT_NONE},
-     .supported_samplerates= sSampleRates,
-     .long_name= NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
-     .priv_class     = &libmp3lame_class,
+                                                              AV_SAMPLE_FMT_NONE },
+     .supported_samplerates = sSampleRates,
+     .long_name             = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
+     .priv_class            = &libmp3lame_class,
  };
Simple merge
@@@ -1703,18 -1768,26 +1775,26 @@@ static av_always_inline void encode_mb_
  
      wrap_y = s->linesize;
      wrap_c = s->uvlinesize;
-     ptr_y  = s->new_picture.f.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
-     ptr_cb = s->new_picture.f.data[1] + (mb_y * mb_block_height * wrap_c) + mb_x * 8;
-     ptr_cr = s->new_picture.f.data[2] + (mb_y * mb_block_height * wrap_c) + mb_x * 8;
+     ptr_y  = s->new_picture.f.data[0] +
+              (mb_y * 16 * wrap_y)              + mb_x * 16;
+     ptr_cb = s->new_picture.f.data[1] +
+              (mb_y * mb_block_height * wrap_c) + mb_x * 8;
+     ptr_cr = s->new_picture.f.data[2] +
+              (mb_y * mb_block_height * wrap_c) + mb_x * 8;
  
 -    if (mb_x * 16 + 16 > s->width || mb_y * 16 + 16 > s->height) {
 +    if((mb_x*16+16 > s->width || mb_y*16+16 > s->height) && s->codec_id != CODEC_ID_AMV){
-         uint8_t *ebuf= s->edge_emu_buffer + 32;
-         s->dsp.emulated_edge_mc(ebuf            , ptr_y , wrap_y,16,16,mb_x*16,mb_y*16, s->width   , s->height);
-         ptr_y= ebuf;
-         s->dsp.emulated_edge_mc(ebuf+18*wrap_y  , ptr_cb, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
-         ptr_cb= ebuf+18*wrap_y;
-         s->dsp.emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
-         ptr_cr= ebuf+18*wrap_y+8;
+         uint8_t *ebuf = s->edge_emu_buffer + 32;
+         s->dsp.emulated_edge_mc(ebuf, ptr_y, wrap_y, 16, 16, mb_x * 16,
+                                 mb_y * 16, s->width, s->height);
+         ptr_y = ebuf;
+         s->dsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb, wrap_c, 8,
+                                 mb_block_height, mb_x * 8, mb_y * 8,
+                                 s->width >> 1, s->height >> 1);
+         ptr_cb = ebuf + 18 * wrap_y;
+         s->dsp.emulated_edge_mc(ebuf + 18 * wrap_y + 8, ptr_cr, wrap_c, 8,
+                                 mb_block_height, mb_x * 8, mb_y * 8,
+                                 s->width >> 1, s->height >> 1);
+         ptr_cr = ebuf + 18 * wrap_y + 8;
      }
  
      if (s->mb_intra) {
Simple merge
Simple merge
diff --cc tests/Makefile
Simple merge
diff --cc tests/fate.mak
@@@ -104,14 -80,8 +80,12 @@@ FATE_TESTS += fate-frw
  fate-frwu: CMD = framecrc  -i $(SAMPLES)/frwu/frwu.avi
  FATE_TESTS += fate-funcom-iss
  fate-funcom-iss: CMD = md5  -i $(SAMPLES)/funcom-iss/0004010100.iss -f s16le
 +FATE_TESTS += fate-g729-0
 +fate-g729-0: CMD = framecrc  -i $(SAMPLES)/act/REC03.act -t 10
 +FATE_TESTS += fate-g729-1
 +fate-g729-1: CMD = framecrc  -i $(SAMPLES)/act/REC05.act -t 10
  FATE_TESTS += fate-id-cin-video
  fate-id-cin-video: CMD = framecrc  -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
- FATE_TESTS += fate-idroq-video-dpcm
- fate-idroq-video-dpcm: CMD = framecrc  -i $(SAMPLES)/idroq/idlogo.roq
  FATE_TESTS-$(CONFIG_AVFILTER) += fate-idroq-video-encode
  fate-idroq-video-encode: CMD = md5  -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f RoQ -t 0.2
  FATE_TESTS += fate-iff-byterun1
Simple merge