Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 23 Sep 2011 22:54:59 +0000 (00:54 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 23 Sep 2011 23:03:07 +0000 (01:03 +0200)
* qatar/master:
  rtp: factorize  dynamic payload type fallback
  flvdec: Ignore the index if it's from a creator known to be different
  cmdutils: move grow_array out of #if CONFIG_AVFILTER
  avconv: actually set InputFile.rate_emu
  ratecontrol: update last_qscale_for sooner
  Fix unnecessary shift with 9/10bit vertical scaling
  prores: mark prores as intra-only in libavformat/utils.c:is_intra_only()
  prores: return more meaningful error values
  prores: improve error message wording
  prores: cosmetics: prettyprinting, drop useless parentheses
  prores: lowercase AVCodec name entry

Conflicts:
cmdutils.c
libavcodec/proresdec_lgpl.c
tests/ref/lavfi/pixfmts_scale

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
avconv.c
libavcodec/proresdec_lgpl.c
libavcodec/ratecontrol.c
libavformat/flvdec.c
libavformat/rtp.c
libavformat/rtpenc.c
libavformat/sdp.c
libavformat/utils.c
libswscale/swscale.c
tests/ref/lavfi/pixfmts_scale

diff --combined avconv.c
index 75186544a2bd0dee8d7304726c29cb6a6c073481,fb744bd537a1cae1215f06b4b6adcd7f5a424836..aecf1d5cf339fcd5bf544eda50fe6e200bdb507f
+++ b/avconv.c
@@@ -1,21 -1,21 +1,21 @@@
  /*
 - * avconv main
 - * Copyright (c) 2000-2011 The libav developers.
 + * ffmpeg main
 + * Copyright (c) 2000-2003 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
  #include "libavutil/libm.h"
  #include "libavformat/os_support.h"
  
 +#include "libavformat/ffm.h" // not public API
 +
  #if CONFIG_AVFILTER
 +# include "libavfilter/avcodec.h"
  # include "libavfilter/avfilter.h"
  # include "libavfilter/avfiltergraph.h"
 +# include "libavfilter/buffersink.h"
  # include "libavfilter/vsrc_buffer.h"
  #endif
  
  #include <sys/select.h>
  #endif
  
 +#if HAVE_TERMIOS_H
 +#include <fcntl.h>
 +#include <sys/ioctl.h>
 +#include <sys/time.h>
 +#include <termios.h>
 +#elif HAVE_KBHIT
 +#include <conio.h>
 +#endif
  #include <time.h>
  
  #include "cmdutils.h"
@@@ -109,9 -97,6 +109,9 @@@ typedef struct MetadataMap 
  
  static const OptionDef options[];
  
 +#define MAX_STREAMS 1024    /* arbitrary sanity check value */
 +
 +static int frame_bits_per_raw_sample = 0;
  static int video_discard = 0;
  static int same_quant = 0;
  static int do_deinterlace = 0;
@@@ -123,12 -108,12 +123,12 @@@ 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 copy_tb;
 +static int copy_tb= 0;
  static int opt_shortest = 0;
  static char *vstats_filename;
  static FILE *vstats_file;
@@@ -139,8 -124,6 +139,8 @@@ static int audio_volume = 256
  static int exit_on_error = 0;
  static int using_stdin = 0;
  static int verbose = 1;
 +static int run_as_daemon  = 0;
 +static int q_pressed = 0;
  static int64_t video_size = 0;
  static int64_t audio_size = 0;
  static int64_t extra_size = 0;
@@@ -169,6 -152,7 +169,6 @@@ typedef struct InputStream 
      int64_t       next_pts;  /* synthetic pts for cases where pkt.pts
                                  is not defined */
      int64_t       pts;       /* current pts */
 -    PtsCorrectionContext pts_ctx;
      double ts_scale;
      int is_start;            /* is 1 at the start and after a discontinuity */
      int showed_multi_packet_warning;
@@@ -204,7 -188,7 +204,7 @@@ typedef struct OutputStream 
  
      /* video only */
      int video_resample;
 -    AVFrame pict_tmp;      /* temporary image for resampling */
 +    AVFrame resample_frame;              /* temporary frame for image resampling */
      struct SwsContext *img_resample_ctx; /* for image resampling */
      int resample_height;
      int resample_width;
     int is_past_recording_time;
  } OutputStream;
  
 +#if HAVE_TERMIOS_H
 +
 +/* init terminal so that we can grab keys */
 +static struct termios oldtty;
 +#endif
  
  typedef struct OutputFile {
      AVFormatContext *ctx;
@@@ -411,8 -390,7 +411,8 @@@ static int configure_video_filters(Inpu
      /** filter graph containing all filters including input & output */
      AVCodecContext *codec = ost->st->codec;
      AVCodecContext *icodec = ist->st->codec;
 -    FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt };
 +    enum PixelFormat pix_fmts[] = { codec->pix_fmt, PIX_FMT_NONE };
 +    AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();
      AVRational sample_aspect_ratio;
      char args[255];
      int ret;
                                         "src", args, NULL, ost->graph);
      if (ret < 0)
          return ret;
 -    ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink,
 -                                       "out", NULL, &ffsink_ctx, ost->graph);
 +#if FF_API_OLD_VSINK_API
 +    ret = avfilter_graph_create_filter(&ost->output_video_filter, avfilter_get_by_name("buffersink"),
 +                                       "out", NULL, pix_fmts, ost->graph);
 +#else
 +    buffersink_params->pixel_fmts = pix_fmts;
 +    ret = avfilter_graph_create_filter(&ost->output_video_filter, avfilter_get_by_name("buffersink"),
 +                                       "out", NULL, buffersink_params, ost->graph);
 +#endif
 +    av_freep(&buffersink_params);
      if (ret < 0)
          return ret;
      last_filter = ost->input_video_filter;
      ost->graph->scale_sws_opts = av_strdup(args);
  
      if (ost->avfilter) {
 -        AVFilterInOut *outputs = av_malloc(sizeof(AVFilterInOut));
 -        AVFilterInOut *inputs  = av_malloc(sizeof(AVFilterInOut));
 +        AVFilterInOut *outputs = avfilter_inout_alloc();
 +        AVFilterInOut *inputs  = avfilter_inout_alloc();
  
          outputs->name    = av_strdup("in");
          outputs->filter_ctx = last_filter;
          inputs->pad_idx = 0;
          inputs->next    = NULL;
  
 -        if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, inputs, outputs, NULL)) < 0)
 +        if ((ret = avfilter_graph_parse(ost->graph, ost->avfilter, &inputs, &outputs, NULL)) < 0)
              return ret;
          av_freep(&ost->avfilter);
      } else {
  
  static void term_exit(void)
  {
 -    av_log(NULL, AV_LOG_QUIET, "");
 +    av_log(NULL, AV_LOG_QUIET, "%s", "");
 +#if HAVE_TERMIOS_H
 +    if(!run_as_daemon)
 +        tcsetattr (0, TCSANOW, &oldtty);
 +#endif
  }
  
  static volatile int received_sigterm = 0;
 -static volatile int received_nb_signals = 0;
  
  static void
  sigterm_handler(int sig)
  {
      received_sigterm = sig;
 -    received_nb_signals++;
 +    q_pressed++;
      term_exit();
  }
  
  static void term_init(void)
  {
 +#if HAVE_TERMIOS_H
 +    if(!run_as_daemon){
 +    struct termios tty;
 +
 +    tcgetattr (0, &tty);
 +    oldtty = tty;
 +    atexit(term_exit);
 +
 +    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
 +                          |INLCR|IGNCR|ICRNL|IXON);
 +    tty.c_oflag |= OPOST;
 +    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
 +    tty.c_cflag &= ~(CSIZE|PARENB);
 +    tty.c_cflag |= CS8;
 +    tty.c_cc[VMIN] = 1;
 +    tty.c_cc[VTIME] = 0;
 +
 +    tcsetattr (0, TCSANOW, &tty);
 +    signal(SIGQUIT, sigterm_handler); /* Quit (POSIX).  */
 +    }
 +#endif
 +
      signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).  */
      signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
  #ifdef SIGXCPU
  #endif
  }
  
 +/* read a key without blocking */
 +static int read_key(void)
 +{
 +#if HAVE_TERMIOS_H
 +    int n = 1;
 +    unsigned char ch;
 +    struct timeval tv;
 +    fd_set rfds;
 +
 +    if(run_as_daemon)
 +        return -1;
 +
 +    FD_ZERO(&rfds);
 +    FD_SET(0, &rfds);
 +    tv.tv_sec = 0;
 +    tv.tv_usec = 0;
 +    n = select(1, &rfds, NULL, NULL, &tv);
 +    if (n > 0) {
 +        n = read(0, &ch, 1);
 +        if (n == 1)
 +            return ch;
 +
 +        return n;
 +    }
 +#elif HAVE_KBHIT
 +    if(kbhit())
 +        return(getch());
 +#endif
 +    return -1;
 +}
 +
  static int decode_interrupt_cb(void)
  {
 -    return received_nb_signals > 1;
 +    q_pressed += read_key() == 'q';
 +    return q_pressed > 1;
  }
  
  void exit_program(int ret)
@@@ -666,9 -580,6 +666,9 @@@ static void choose_sample_fmt(AVStream 
                  break;
          }
          if (*p == -1) {
 +            if((codec->capabilities & CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0]))
 +                av_log(NULL, AV_LOG_ERROR, "Convertion will not be lossless'\n");
 +            if(av_get_sample_fmt_name(st->codec->sample_fmt))
              av_log(NULL, AV_LOG_WARNING,
                     "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
                     av_get_sample_fmt_name(st->codec->sample_fmt),
      }
  }
  
 -/**
 - * 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){
@@@ -806,7 -757,7 +806,7 @@@ need_realloc
          exit_program(1);
      }
  
 -    if (enc->channels != dec->channels || enc->sample_rate != dec->sample_rate)
 +    if (enc->channels != dec->channels)
          ost->audio_resample = 1;
  
      resample_changed = ost->resample_sample_fmt  != dec->sample_fmt ||
              ost->resample_sample_rate == enc->sample_rate) {
              ost->resample = NULL;
              ost->audio_resample = 0;
 -        } else if (ost->audio_resample) {
 +        } else {
              if (dec->sample_fmt != AV_SAMPLE_FMT_S16)
                  fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n");
              ost->resample = av_audio_resample_init(enc->channels,    dec->channels,
@@@ -1122,46 -1073,36 +1122,46 @@@ static void do_video_resample(OutputStr
  {
      int resample_changed = 0;
      AVCodecContext *dec = ist->st->codec;
 +    AVCodecContext *enc = ost->st->codec;
      *out_picture = in_picture;
  
      resample_changed = ost->resample_width   != dec->width  ||
                         ost->resample_height  != dec->height ||
                         ost->resample_pix_fmt != dec->pix_fmt;
  
 +#if !CONFIG_AVFILTER
      if (resample_changed) {
          av_log(NULL, AV_LOG_INFO,
                 "Input stream #%d.%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
                 ist->file_index, ist->st->index,
                 ost->resample_width, ost->resample_height, av_get_pix_fmt_name(ost->resample_pix_fmt),
                 dec->width         , dec->height         , av_get_pix_fmt_name(dec->pix_fmt));
 -        if(!ost->video_resample)
 -            ost->video_resample = 1;
 +        ost->resample_width   = dec->width;
 +        ost->resample_height  = dec->height;
 +        ost->resample_pix_fmt = dec->pix_fmt;
      }
  
 -#if !CONFIG_AVFILTER
 +    ost->video_resample = dec->width   != enc->width  ||
 +                          dec->height  != enc->height ||
 +                          dec->pix_fmt != enc->pix_fmt;
 +
      if (ost->video_resample) {
 -        *out_picture = &ost->pict_tmp;
 -        if (resample_changed) {
 +        *out_picture = &ost->resample_frame;
 +        if (!ost->img_resample_ctx || resample_changed) {
 +            /* initialize the destination picture */
 +            if (!ost->resample_frame.data[0]) {
 +                avcodec_get_frame_defaults(&ost->resample_frame);
 +                if (avpicture_alloc((AVPicture *)&ost->resample_frame, enc->pix_fmt,
 +                                    enc->width, enc->height)) {
 +                    fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n");
 +                    exit_program(1);
 +                }
 +            }
              /* initialize a new scaler context */
              sws_freeContext(ost->img_resample_ctx);
 -            ost->img_resample_ctx = sws_getContext(
 -                ist->st->codec->width,
 -                ist->st->codec->height,
 -                ist->st->codec->pix_fmt,
 -                ost->st->codec->width,
 -                ost->st->codec->height,
 -                ost->st->codec->pix_fmt,
 -                ost->sws_flags, NULL, NULL, NULL);
 +            ost->img_resample_ctx = sws_getContext(dec->width, dec->height, dec->pix_fmt,
 +                                                   enc->width, enc->height, enc->pix_fmt,
 +                                                   ost->sws_flags, NULL, NULL, NULL);
              if (ost->img_resample_ctx == NULL) {
                  fprintf(stderr, "Cannot get resampling context\n");
                  exit_program(1);
@@@ -1374,8 -1315,7 +1374,8 @@@ static void print_report(OutputFile *ou
      int64_t total_size;
      AVCodecContext *enc;
      int frame_number, vid, i;
 -    double bitrate, ti1, pts;
 +    double bitrate;
 +    int64_t pts = INT64_MAX;
      static int64_t last_time = -1;
      static int qp_histogram[52];
  
          total_size= avio_tell(oc->pb);
  
      buf[0] = '\0';
 -    ti1 = 1e10;
      vid = 0;
      for(i=0;i<nb_ostreams;i++) {
          float q = -1;
              vid = 1;
          }
          /* compute min output value */
 -        pts = (double)ost->st->pts.val * av_q2d(ost->st->time_base);
 -        if ((pts < ti1) && (pts > 0))
 -            ti1 = pts;
 +        pts = FFMIN(pts, av_rescale_q(ost->st->pts.val,
 +                                      ost->st->time_base, AV_TIME_BASE_Q));
      }
 -    if (ti1 < 0.01)
 -        ti1 = 0.01;
  
      if (verbose > 0 || is_last_report) {
 -        bitrate = (double)(total_size * 8) / ti1 / 1000.0;
 +        int hours, mins, secs, us;
 +        secs = pts / AV_TIME_BASE;
 +        us = pts % AV_TIME_BASE;
 +        mins = secs / 60;
 +        secs %= 60;
 +        hours = mins / 60;
 +        mins %= 60;
  
 +        bitrate = pts ? total_size * 8 / (pts / 1000.0) : 0;
 +
 +        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
 +                 "size=%8.0fkB time=", total_size / 1024.0);
 +        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
 +                 "%02d:%02d:%02d.%02d ", hours, mins, secs,
 +                 (100 * us) / AV_TIME_BASE);
          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=%6.1fkbits/s", bitrate);
  
          if (nb_frames_dup || nb_frames_drop)
            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
@@@ -1693,7 -1625,7 +1693,7 @@@ static int output_packet(InputStream *i
                          /* no picture yet */
                          goto discard_packet;
                      }
 -                    ist->next_pts = ist->pts = guess_correct_pts(&ist->pts_ctx, picture.pkt_pts, picture.pkt_dts);
 +                    ist->next_pts = ist->pts = picture.best_effort_timestamp;
                      if (ist->st->codec->time_base.num != 0) {
                          int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame;
                          ist->next_pts += ((int64_t)AV_TIME_BASE *
  #if CONFIG_AVFILTER
              if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
                  ost->input_video_filter) {
 -                AVRational sar;
 -                if (ist->st->sample_aspect_ratio.num)
 -                    sar = ist->st->sample_aspect_ratio;
 -                else
 -                    sar = ist->st->codec->sample_aspect_ratio;
 -                av_vsrc_buffer_add_frame(ost->input_video_filter, &picture, ist->pts, sar);
 +                if (!picture.sample_aspect_ratio.num)
 +                    picture.sample_aspect_ratio = ist->st->sample_aspect_ratio;
 +                picture.pts = ist->pts;
 +
 +                av_vsrc_buffer_add_frame(ost->input_video_filter, &picture, AV_VSRC_BUF_FLAG_OVERWRITE);
              }
              frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO ||
                  !ost->output_video_filter || avfilter_poll_frame(ost->output_video_filter->inputs[0]);
              while (frame_available) {
 -                AVRational ist_pts_tb;
 -                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter)
 -                    get_filtered_video_frame(ost->output_video_filter, &picture, &ost->picref, &ist_pts_tb);
 -                if (ost->picref)
 -                    ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
 +                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter) {
 +                    AVRational ist_pts_tb = ost->output_video_filter->inputs[0]->time_base;
 +                    if (av_buffersink_get_buffer_ref(ost->output_video_filter, &ost->picref, 0) < 0)
 +                        goto cont;
 +                    if (ost->picref) {
 +                        avfilter_fill_frame_from_video_buffer_ref(&picture, ost->picref);
 +                        ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q);
 +                    }
 +                }
  #endif
                  os = output_files[ost->file_index].ctx;
  
                      case AVMEDIA_TYPE_VIDEO:
  #if CONFIG_AVFILTER
                          if (ost->picref->video && !ost->frame_aspect_ratio)
 -                            ost->st->codec->sample_aspect_ratio = ost->picref->video->pixel_aspect;
 +                            ost->st->codec->sample_aspect_ratio = ost->picref->video->sample_aspect_ratio;
  #endif
                          do_video_out(os, ost, ist, &picture, &frame_size,
 -                                     same_quant ? quality : ost->st->codec->global_quality);
 +                                        same_quant ? quality : ost->st->codec->global_quality);
                          if (vstats_filename && frame_size)
                              do_video_stats(os, ost, frame_size);
                          break;
                      }
                  } else {
                      AVFrame avframe; //FIXME/XXX remove this
 +                    AVPicture pict;
                      AVPacket opkt;
                      int64_t ost_tb_start_time= av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
 -
                      av_init_packet(&opkt);
  
                      if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) && !copy_initial_nonkeyframes)
                          opkt.size = data_size;
                      }
  
 +                    if (os->oformat->flags & AVFMT_RAWPICTURE) {
 +                        /* store AVPicture in AVPacket, as expected by the output format */
 +                        avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height);
 +                        opkt.data = (uint8_t *)&pict;
 +                        opkt.size = sizeof(AVPicture);
 +                        opkt.flags |= AV_PKT_FLAG_KEY;
 +                    }
                      write_frame(os, &opkt, ost->st->codec, ost->bitstream_filters);
                      ost->st->codec->frame_number++;
                      ost->frame_number++;
@@@ -1944,6 -1866,16 +1944,6 @@@ static int init_input_stream(int ist_in
              return AVERROR(EINVAL);
          }
  
 -        /* update requested sample format for the decoder based on the
 -           corresponding encoder sample format */
 -        for (i = 0; i < nb_output_streams; i++) {
 -            OutputStream *ost = &output_streams[i];
 -            if (ost->source_index == ist_index) {
 -                update_sample_fmt(ist->st->codec, codec, ost->st->codec);
 -                break;
 -            }
 -        }
 -
          if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) {
              snprintf(error, error_len, "Error while opening decoder for input stream #%d.%d",
                      ist->file_index, ist->st->index);
  
      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;
@@@ -2031,23 -1964,13 +2031,23 @@@ static int transcode_init(OutputFile *o
              }
              memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);
              codec->extradata_size= icodec->extradata_size;
 -            if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){
 -                codec->time_base = icodec->time_base;
 -                codec->time_base.num *= icodec->ticks_per_frame;
 -                av_reduce(&codec->time_base.num, &codec->time_base.den,
 -                          codec->time_base.num, codec->time_base.den, INT_MAX);
 -            }else
 -                codec->time_base = ist->st->time_base;
 +
 +            codec->time_base = ist->st->time_base;
 +            if(!strcmp(os->oformat->name, "avi")) {
 +                if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > 2*av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){
 +                    codec->time_base = icodec->time_base;
 +                    codec->time_base.num *= icodec->ticks_per_frame;
 +                    codec->time_base.den *= 2;
 +                }
 +            } else if(!(os->oformat->flags & AVFMT_VARIABLE_FPS)) {
 +                if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){
 +                    codec->time_base = icodec->time_base;
 +                    codec->time_base.num *= icodec->ticks_per_frame;
 +                }
 +            }
 +            av_reduce(&codec->time_base.num, &codec->time_base.den,
 +                        codec->time_base.num, codec->time_base.den, INT_MAX);
 +
              switch(codec->codec_type) {
              case AVMEDIA_TYPE_AUDIO:
                  if(audio_volume != 256) {
                  ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE);
                  if (!codec->sample_rate) {
                      codec->sample_rate = icodec->sample_rate;
 -                    if (icodec->lowres)
 -                        codec->sample_rate >>= icodec->lowres;
                  }
                  choose_sample_rate(ost->st, ost->enc);
                  codec->time_base = (AVRational){1, codec->sample_rate};
                  if (codec->sample_fmt == AV_SAMPLE_FMT_NONE)
                      codec->sample_fmt = icodec->sample_fmt;
                  choose_sample_fmt(ost->st, ost->enc);
 -                if (!codec->channels)
 +                if (!codec->channels) {
                      codec->channels = icodec->channels;
 -                codec->channel_layout = icodec->channel_layout;
 +                    codec->channel_layout = icodec->channel_layout;
 +                }
                  if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)
                      codec->channel_layout = 0;
                  ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;
                                        codec->height  != icodec->height ||
                                        codec->pix_fmt != icodec->pix_fmt;
                  if (ost->video_resample) {
 -#if !CONFIG_AVFILTER
 -                    avcodec_get_frame_defaults(&ost->pict_tmp);
 -                    if(avpicture_alloc((AVPicture*)&ost->pict_tmp, codec->pix_fmt,
 -                                       codec->width, codec->height)) {
 -                        fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n");
 -                        exit_program(1);
 -                    }
 -                    ost->img_resample_ctx = sws_getContext(
 -                        icodec->width,
 -                        icodec->height,
 -                        icodec->pix_fmt,
 -                        codec->width,
 -                        codec->height,
 -                        codec->pix_fmt,
 -                        ost->sws_flags, NULL, NULL, NULL);
 -                    if (ost->img_resample_ctx == NULL) {
 -                        fprintf(stderr, "Cannot get resampling context\n");
 -                        exit_program(1);
 -                    }
 -#endif
 -                    codec->bits_per_raw_sample= 0;
 +                    codec->bits_per_raw_sample= frame_bits_per_raw_sample;
                  }
  
                  ost->resample_height = icodec->height;
                      ost->frame_rate = ost->enc->supported_framerates[idx];
                  }
                  codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num};
 +                if(   av_q2d(codec->time_base) < 0.001 && video_sync_method
 +                   && (video_sync_method==1 || (video_sync_method<0 && !(os->oformat->flags & AVFMT_VARIABLE_FPS)))){
 +                    av_log(os, AV_LOG_WARNING, "Frame rate very high for a muxer not effciciently supporting it.\n"
 +                                               "Please consider specifiying a lower framerate, a different muxer or -vsync 2\n");
 +                }
  
  #if CONFIG_AVFILTER
                  if (configure_video_filters(ist, ost)) {
                  break;
              }
              /* two pass mode */
 -            if (ost->encoding_needed &&
 +            if (ost->encoding_needed && codec->codec_id != CODEC_ID_H264 &&
                  (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
                  char logfilename[1024];
                  FILE *f;
              }
          }
          if(codec->codec_type == AVMEDIA_TYPE_VIDEO){
 +            /* maximum video buffer size is 6-bytes per pixel, plus DPX header size */
              int size= codec->width * codec->height;
 -            bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 200);
 +            bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 1664);
          }
      }
  
              ret = AVERROR(EINVAL);
              goto dump_format;
          }
 -        assert_avoptions(output_files[i].opts);
 +//        assert_avoptions(output_files[i].opts);
          if (strcmp(os->oformat->name, "rtp")) {
              want_sdp = 0;
          }
@@@ -2349,7 -2287,6 +2349,7 @@@ static int transcode(OutputFile *output
      uint8_t *no_packet;
      int no_packet_count=0;
      int64_t timer_start;
 +    int key;
  
      if (!(no_packet = av_mallocz(nb_input_files)))
          exit_program(1);
      if (ret < 0)
          goto fail;
  
 -    if (verbose >= 0)
 -        fprintf(stderr, "Press ctrl-c to stop encoding\n");
 +    if (!using_stdin) {
 +        if(verbose >= 0)
 +            fprintf(stderr, "Press [q] to stop, [?] for help\n");
 +        avio_set_interrupt_cb(decode_interrupt_cb);
 +    }
      term_init();
  
      timer_start = av_gettime();
  
          ipts_min = INT64_MAX;
          opts_min= 1e100;
 +        /* if 'q' pressed, exits */
 +        if (!using_stdin) {
 +            if (q_pressed)
 +                break;
 +            /* read_key() returns 0 on EOF */
 +            key = read_key();
 +            if (key == 'q')
 +                break;
 +            if (key == '+') verbose++;
 +            if (key == '-') verbose--;
 +            if (key == 's') qp_hist     ^= 1;
 +            if (key == 'h'){
 +                if (do_hex_dump){
 +                    do_hex_dump = do_pkt_dump = 0;
 +                } else if(do_pkt_dump){
 +                    do_hex_dump = 1;
 +                } else
 +                    do_pkt_dump = 1;
 +                av_log_set_level(AV_LOG_DEBUG);
 +            }
 +            if (key == 'd' || key == 'D'){
 +                int debug=0;
 +                if(key == 'D') {
 +                    debug = input_streams[0].st->codec->debug<<1;
 +                    if(!debug) debug = 1;
 +                    while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash
 +                        debug += debug;
 +                }else
 +                    scanf("%d", &debug);
 +                for(i=0;i<nb_input_streams;i++) {
 +                    input_streams[i].st->codec->debug = debug;
 +                }
 +                for(i=0;i<nb_output_streams;i++) {
 +                    ost = &output_streams[i];
 +                    ost->st->codec->debug = debug;
 +                }
 +                if(debug) av_log_set_level(AV_LOG_DEBUG);
 +                fprintf(stderr,"debug=%d\n", debug);
 +            }
 +            if (key == '?'){
 +                fprintf(stderr, "key    function\n"
 +                                "?      show this help\n"
 +                                "+      increase verbosity\n"
 +                                "-      decrease verbosity\n"
 +                                "D      cycle through available debug modes\n"
 +                                "h      dump packets/hex press to cycle through the 3 states\n"
 +                                "q      quit\n"
 +                                "s      Show QP histogram\n"
 +                );
 +            }
 +        }
  
          /* select the stream that we must read now by looking at the
             smallest output pts */
                  av_fifo_free(ost->fifo); /* works even if fifo is not
                                               initialized but set to zero */
                  av_freep(&ost->st->codec->subtitle_header);
 -                av_free(ost->pict_tmp.data[0]);
 +                av_free(ost->resample_frame.data[0]);
                  av_free(ost->forced_kf_pts);
                  if (ost->video_resample)
                      sws_freeContext(ost->img_resample_ctx);
@@@ -2877,18 -2760,16 +2877,18 @@@ 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;
              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) {
          case AVMEDIA_TYPE_DATA:
              break;
          case AVMEDIA_TYPE_SUBTITLE:
 -            if (o->subtitle_disable)
 +            if(!ist->dec)
 +                ist->dec = avcodec_find_decoder(dec->codec_id);
 +            if(o->subtitle_disable)
                  st->discard = AVDISCARD_ALL;
              break;
          case AVMEDIA_TYPE_ATTACHMENT:
@@@ -3021,6 -2900,7 +3021,7 @@@ static int opt_input_file(OptionsContex
      input_files[nb_input_files - 1].ist_index  = nb_input_streams - ic->nb_streams;
      input_files[nb_input_files - 1].ts_offset  = o->input_ts_offset - (copy_ts ? 0 : timestamp);
      input_files[nb_input_files - 1].nb_streams = ic->nb_streams;
+     input_files[nb_input_files - 1].rate_emu   = o->rate_emu;
  
      for (i = 0; i < orig_nb_streams; i++)
          av_dict_free(&opts[i]);
@@@ -3346,7 -3226,7 +3347,7 @@@ static int opt_streamid(OptionsContext 
          exit_program(1);
      }
      *p++ = '\0';
 -    idx = parse_number_or_die(opt, idx_str, 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;
@@@ -3392,7 -3272,7 +3393,7 @@@ static int copy_chapters(InputFile *ifi
      return 0;
  }
  
 -static int read_avserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
 +static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
  {
      int i, err;
      AVFormatContext *ic = NULL;
  
          // FIXME: a more elegant solution is needed
          memcpy(st, ic->streams[i], sizeof(AVStream));
 -        st->info = NULL;
 +        st->info = av_malloc(sizeof(*st->info));
 +        memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
          avcodec_copy_context(st->codec, ic->streams[i]->codec);
  
          if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !st->stream_copy)
@@@ -3438,19 -3317,35 +3439,19 @@@ 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);
      }
  
 -    if (o->format) {
 -        file_oformat = av_guess_format(o->format, NULL, NULL);
 -        if (!file_oformat) {
 -            fprintf(stderr, "Requested output format '%s' is not a suitable output format\n", o->format);
 -            exit_program(1);
 -        }
 -    } else {
 -        file_oformat = av_guess_format(NULL, filename, NULL);
 -        if (!file_oformat) {
 -            fprintf(stderr, "Unable to find a suitable output format for '%s'\n",
 -                    filename);
 -            exit_program(1);
 -        }
 -    }
 -
 -    oc->oformat = file_oformat;
 -    av_strlcpy(oc->filename, filename, sizeof(oc->filename));
 +    file_oformat= oc->oformat;
  
      if (!strcmp(file_oformat->name, "ffm") &&
          av_strstart(filename, "http:", NULL)) {
 -        /* special case for files sent to avserver: we get the stream
 -           parameters from avserver */
 -        int err = read_avserver_streams(o, oc, filename);
 +        /* special case for files sent to ffserver: we get the stream
 +           parameters from ffserver */
 +        int err = read_ffserver_streams(o, oc, filename);
          if (err < 0) {
              print_error(filename, err);
              exit_program(1);
  
      oc->preload   = (int)(o->mux_preload   * AV_TIME_BASE);
      oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
 -    oc->flags |= AVFMT_FLAG_NONBLOCK;
  
      /* copy chapters */
      if (o->chapters_input_file >= nb_input_files) {
@@@ -3751,7 -3647,7 +3752,7 @@@ static void show_usage(void
      printf("\n");
  }
  
 -static void show_help(void)
 +static int opt_help(const char *opt, const char *arg)
  {
      AVCodec *c;
      AVOutputFormat *oformat = NULL;
  
      class = sws_get_class();
      av_opt_show2(&class, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0);
 +    return 0;
  }
  
  static int opt_target(OptionsContext *o, const char *opt, const char *arg)
@@@ -3991,20 -3886,6 +3992,20 @@@ static int opt_data_frames(OptionsConte
      return parse_option(o, "frames:d", arg, options);
  }
  
 +static void log_callback_null(void* ptr, int level, const char* fmt, va_list vl)
 +{
 +}
 +
 +static int opt_passlogfile(const char *opt, const char *arg)
 +{
 +    pass_logfilename_prefix = arg;
 +#if CONFIG_LIBX264_ENCODER
 +    return opt_default("passlogfile", arg);
 +#else
 +    return 0;
 +#endif
 +}
 +
  static int opt_video_tag(OptionsContext *o, const char *opt, const char *arg)
  {
      return parse_option(o, "tag:v", arg, options);
@@@ -4078,7 -3959,6 +4079,7 @@@ static const OptionDef options[] = 
      { "s", HAS_ARG | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_sizes)}, "set frame size (WxH or abbreviation)", "size" },
      { "aspect", HAS_ARG | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_aspect_ratios)}, "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
      { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(frame_pix_fmts)}, "set pixel format", "format" },
 +    { "bits_per_raw_sample", OPT_INT | HAS_ARG | OPT_VIDEO, {(void*)&frame_bits_per_raw_sample}, "set the number of bits per raw sample", "number" },
      { "vn", OPT_BOOL | OPT_VIDEO | OPT_OFFSET, {.off = OFFSET(video_disable)}, "disable video" },
      { "vdt", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&video_discard}, "discard threshold", "n" },
      { "rc_override", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_STRING | OPT_SPEC, {.off = OFFSET(rc_overrides)}, "rate control override for specific intervals", "override" },
      { "same_quant", OPT_BOOL | OPT_VIDEO, {(void*)&same_quant},
        "use same quantizer as source (implies VBR)" },
      { "pass", HAS_ARG | OPT_VIDEO, {(void*)opt_pass}, "select the pass number (1 or 2)", "n" },
 -    { "passlogfile", HAS_ARG | OPT_STRING | OPT_VIDEO, {(void*)&pass_logfilename_prefix}, "select two pass log file name prefix", "prefix" },
 +    { "passlogfile", HAS_ARG | OPT_VIDEO, {(void*)&opt_passlogfile}, "select two pass log file name prefix", "prefix" },
      { "deinterlace", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_deinterlace},
        "deinterlace pictures" },
      { "vstats", OPT_EXPERT | OPT_VIDEO, {(void*)&opt_vstats}, "dump video coding statistics to file" },
@@@ -4145,14 -4025,6 +4146,14 @@@ int main(int argc, char **argv
  
      av_log_set_flags(AV_LOG_SKIP_REPEATED);
  
 +    if(argc>1 && !strcmp(argv[1], "-d")){
 +        run_as_daemon=1;
 +        verbose=-1;
 +        av_log_set_callback(log_callback_null);
 +        argc--;
 +        argv++;
 +    }
 +
      avcodec_register_all();
  #if CONFIG_AVDEVICE
      avdevice_register_all();
  #endif
      av_register_all();
  
 -    avio_set_interrupt_cb(decode_interrupt_cb);
 +#if HAVE_ISATTY
 +    if(isatty(STDIN_FILENO))
 +        avio_set_interrupt_cb(decode_interrupt_cb);
 +#endif
  
 -    show_banner();
 +    if(verbose>=0)
 +        show_banner();
  
      /* parse options */
      parse_options(&o, argc, argv, options, opt_output_file);
index c52799aa218f3204c343a64993c2bb3cc65449b8,759c10b6e5f8806893aa90cd7baa68b62977da92..a3d762bf082ec1e49f774b5238f6b812126234a3
@@@ -129,31 -129,31 +129,31 @@@ static int decode_frame_header(ProresCo
  
      hdr_size = AV_RB16(buf);
      if (hdr_size > data_size) {
-         av_log(avctx, AV_LOG_ERROR, "frame data too short!\n");
-         return -1;
+         av_log(avctx, AV_LOG_ERROR, "frame data too small\n");
+         return AVERROR_INVALIDDATA;
      }
  
      version = AV_RB16(buf + 2);
      if (version >= 2) {
          av_log(avctx, AV_LOG_ERROR,
                 "unsupported header version: %d\n", version);
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
  
      width  = AV_RB16(buf + 8);
      height = AV_RB16(buf + 10);
      if (width != avctx->width || height != avctx->height) {
          av_log(avctx, AV_LOG_ERROR,
-                "picture dimension changed! Old: %d x %d, new: %d x %d\n",
+                "picture dimension changed: old: %d x %d, new: %d x %d\n",
                 avctx->width, avctx->height, width, height);
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
  
      ctx->frame_type = (buf[12] >> 2) & 3;
      if (ctx->frame_type > 2) {
          av_log(avctx, AV_LOG_ERROR,
-                "unsupported frame type: %d!\n", ctx->frame_type);
-         return -1;
+                "unsupported frame type: %d\n", ctx->frame_type);
+         return AVERROR_INVALIDDATA;
      }
  
      ctx->chroma_factor     = (buf[12] >> 6) & 3;
          break;
      default:
          av_log(avctx, AV_LOG_ERROR,
-                "unsupported picture format: %d!\n", ctx->pic_format);
-         return -1;
+                "unsupported picture format: %d\n", ctx->pic_format);
+         return AVERROR_INVALIDDATA;
      }
  
      if (ctx->scantable_type != ctx->frame_type) {
      flags = buf[19];
      if (flags & 2) {
          if (ptr - buf > hdr_size - 64) {
-             av_log(avctx, AV_LOG_ERROR, "Too short header data\n");
-             return -1;
+             av_log(avctx, AV_LOG_ERROR, "header data too small\n");
+             return AVERROR_INVALIDDATA;
          }
          if (memcmp(ctx->qmat_luma, ptr, 64)) {
              memcpy(ctx->qmat_luma, ptr, 64);
  
      if (flags & 1) {
          if (ptr - buf > hdr_size - 64) {
-             av_log(avctx, AV_LOG_ERROR, "Too short header data\n");
+             av_log(avctx, AV_LOG_ERROR, "header data too small\n");
              return -1;
          }
          if (memcmp(ctx->qmat_chroma, ptr, 64)) {
@@@ -233,32 -233,32 +233,32 @@@ static int decode_picture_header(Prores
  
      hdr_size = data_size > 0 ? buf[0] >> 3 : 0;
      if (hdr_size < 8 || hdr_size > data_size) {
-         av_log(avctx, AV_LOG_ERROR, "picture header too short!\n");
-         return -1;
+         av_log(avctx, AV_LOG_ERROR, "picture header too small\n");
+         return AVERROR_INVALIDDATA;
      }
  
      pic_data_size = AV_RB32(buf + 1);
      if (pic_data_size > data_size) {
-         av_log(avctx, AV_LOG_ERROR, "picture data too short!\n");
-         return -1;
+         av_log(avctx, AV_LOG_ERROR, "picture data too small\n");
+         return AVERROR_INVALIDDATA;
      }
  
      slice_width_factor  = buf[7] >> 4;
      slice_height_factor = buf[7] & 0xF;
      if (slice_width_factor > 3 || slice_height_factor) {
          av_log(avctx, AV_LOG_ERROR,
-                "unsupported slice dimension: %d x %d!\n",
+                "unsupported slice dimension: %d x %d\n",
                 1 << slice_width_factor, 1 << slice_height_factor);
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
  
      ctx->slice_width_factor  = slice_width_factor;
      ctx->slice_height_factor = slice_height_factor;
  
      ctx->num_x_mbs = (avctx->width + 15) >> 4;
-     ctx->num_y_mbs =
-         (avctx->height + (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
-         (4 + ctx->picture.interlaced_frame);
+     ctx->num_y_mbs = (avctx->height +
+                       (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
+                      (4 + ctx->picture.interlaced_frame);
  
      remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
      num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
  
      num_slices = num_x_slices * ctx->num_y_mbs;
      if (num_slices != AV_RB16(buf + 5)) {
-         av_log(avctx, AV_LOG_ERROR, "invalid number of slices!\n");
-         return -1;
+         av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n");
+         return AVERROR_INVALIDDATA;
      }
  
      if (ctx->total_slices != num_slices) {
          av_freep(&ctx->slice_data_index);
-         ctx->slice_data_index =
-             av_malloc((num_slices + 1) * sizeof(uint8_t*));
+         ctx->slice_data_index = av_malloc((num_slices + 1) * sizeof(uint8_t*));
          if (!ctx->slice_data_index)
              return AVERROR(ENOMEM);
          ctx->total_slices = num_slices;
      }
  
      if (hdr_size + num_slices * 2 > data_size) {
-         av_log(avctx, AV_LOG_ERROR, "slice table too short!\n");
-         return -1;
+         av_log(avctx, AV_LOG_ERROR, "slice table too small\n");
+         return AVERROR_INVALIDDATA;
      }
  
      /* parse slice table allowing quick access to the slice data */
      ctx->slice_data_index[i] = data_ptr;
  
      if (data_ptr > buf + data_size) {
-         av_log(avctx, AV_LOG_ERROR, "out of slice data!\n");
+         av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
          return -1;
      }
  
@@@ -330,7 -329,7 +329,7 @@@ static inline int decode_vlc_codeword(G
              LAST_SKIP_BITS(re, gb, log + 1);
          } else {
              prefix_len = log + 1;
-             code = (log << rice_order) + NEG_USR32((buf << prefix_len), rice_order);
+             code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order);
              LAST_SKIP_BITS(re, gb, prefix_len + rice_order);
          }
      } else { /* otherwise we got a exp golomb code */
@@@ -519,8 -518,7 +518,7 @@@ static void decode_slice_plane(ProresCo
      /* inverse quantization, inverse transform and output */
      block_ptr = ctx->blocks;
  
-     for (blk_num = 0; blk_num < blocks_per_slice;
-          blk_num++, block_ptr += 64) {
+     for (blk_num = 0; blk_num < blocks_per_slice; blk_num++, block_ptr += 64) {
          /* TODO: the correct solution shoud be (block_ptr[i] * qmat[i]) >> 1
           * and the input of the inverse transform should be scaled by 2
           * in order to avoid rounding errors.
@@@ -572,8 -570,8 +570,8 @@@ static int decode_slice(ProresContext *
      }
  
      if (slice_data_size < 6) {
-         av_log(avctx, AV_LOG_ERROR, "slice data too short!\n");
-         return -1;
+         av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
+         return AVERROR_INVALIDDATA;
      }
  
      /* parse slice header */
      v_data_size = slice_data_size - y_data_size - u_data_size - hdr_size;
  
      if (v_data_size < 0 || hdr_size < 6) {
-         av_log(avctx, AV_LOG_ERROR, "invalid data sizes!\n");
-         return -1;
+         av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
+         return AVERROR_INVALIDDATA;
      }
  
      sf = av_clip(buf[1], 1, 224);
      if (ctx->qmat_changed || sf != ctx->prev_slice_sf) {
          ctx->prev_slice_sf = sf;
          for (i = 0; i < 64; i++) {
-             ctx->qmat_luma_scaled[i]   = ctx->qmat_luma[i] * sf;
+             ctx->qmat_luma_scaled[i]   = ctx->qmat_luma[i]   * sf;
              ctx->qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * sf;
          }
      }
@@@ -671,14 -669,14 +669,14 @@@ static int decode_frame(AVCodecContext 
      if (buf_size < 28 || buf_size < AV_RB32(buf) ||
          AV_RB32(buf + 4) != FRAME_ID) {
          av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
-         return -1;
+         return AVERROR_INVALIDDATA;
      }
  
      MOVE_DATA_PTR(8);
  
      frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
      if (frame_hdr_size < 0)
-         return -1;
+         return AVERROR_INVALIDDATA;
  
      MOVE_DATA_PTR(frame_hdr_size);
  
      for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
          pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
          if (pic_data_size < 0)
-             return -1;
+             return AVERROR_INVALIDDATA;
  
          if (decode_picture(ctx, pic_num, avctx))
              return -1;
@@@ -720,8 -718,8 +718,8 @@@ static av_cold int decode_close(AVCodec
  }
  
  
 -AVCodec ff_prores_decoder = {
 -    .name           = "prores",
 +AVCodec ff_prores_lgpl_decoder = {
-     .name           = "ProRes_lgpl",
++    .name           = "prores_lgpl",
      .type           = AVMEDIA_TYPE_VIDEO,
      .id             = CODEC_ID_PRORES,
      .priv_data_size = sizeof(ProresContext),
diff --combined libavcodec/ratecontrol.c
index d085f04113215ab4efda49aace50fcf34fc20035,e984ed5b29cf9a6834eedb19d9f96bcb83c1e992..41b7d97d32db358d13f490edd772c1b3c7c65a70
@@@ -3,20 -3,20 +3,20 @@@
   *
   * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -861,17 -861,13 +861,19 @@@ static int init_pass2(MpegEncContext *s
  
          /* find qscale */
          for(i=0; i<rcc->num_entries; i++){
+             RateControlEntry *rce= &rcc->entry[i];
              qscale[i]= get_qscale(s, &rcc->entry[i], rate_factor, i);
+             rcc->last_qscale_for[rce->pict_type] = qscale[i];
          }
          assert(filter_size%2==1);
  
          /* fixed I/B QP relative to P mode */
 +        for(i=FFMAX(0, rcc->num_entries-300); i<rcc->num_entries; i++){
 +            RateControlEntry *rce= &rcc->entry[i];
 +
 +            qscale[i]= get_diff_limited_q(s, rce, qscale[i]);
 +        }
 +
          for(i=rcc->num_entries-1; i>=0; i--){
              RateControlEntry *rce= &rcc->entry[i];
  
diff --combined libavformat/flvdec.c
index 74330e8658b3f80dae2bc1c275ae85d52b88d147,569d7343c3a9f4b7c40af506f423bb3d496c5d36..828d25fda3df95ee32d18bc476d2e054e16d5ce5
@@@ -1,26 -1,26 +1,26 @@@
  /*
   * FLV demuxer
 - * Copyright (c) 2003 The Libav Project
 + * Copyright (c) 2003 The FFmpeg Project
   *
   * This demuxer will generate a 1 byte extradata for VP6F content.
   * It is composed of:
   *  - upper 4bits: difference between encoded width and visible width
   *  - lower 4bits: difference between encoded height and visible height
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
  #include "avio_internal.h"
  #include "flv.h"
  
 -#define KEYFRAMES_TAG            "keyframes"
 -#define KEYFRAMES_TIMESTAMP_TAG  "times"
 -#define KEYFRAMES_BYTEOFFSET_TAG "filepositions"
 -
  typedef struct {
      int wrong_dts; ///< wrong dts due to negative cts
  } FLVContext;
@@@ -91,7 -95,6 +91,7 @@@ static int flv_set_video_codec(AVFormat
      AVCodecContext *vcodec = vstream->codec;
      switch(flv_codecid) {
          case FLV_CODECID_H263  : vcodec->codec_id = CODEC_ID_FLV1   ; break;
 +        case FLV_CODECID_REALH263: vcodec->codec_id = CODEC_ID_H263 ; break; // Really mean it this time
          case FLV_CODECID_SCREEN: vcodec->codec_id = CODEC_ID_FLASHSV; break;
          case FLV_CODECID_SCREEN2: vcodec->codec_id = CODEC_ID_FLASHSV2; break;
          case FLV_CODECID_VP6   : vcodec->codec_id = CODEC_ID_VP6F   ;
          case FLV_CODECID_H264:
              vcodec->codec_id = CODEC_ID_H264;
              return 3; // not 4, reading packet type will consume one byte
 +        case FLV_CODECID_MPEG4:
 +            vcodec->codec_id = CODEC_ID_MPEG4;
 +            return 3;
          default:
              av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
              vcodec->codec_tag = flv_codecid;
@@@ -133,43 -133,60 +133,55 @@@ static int amf_get_string(AVIOContext *
  }
  
  static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream *vstream, int64_t max_pos) {
 -    unsigned int arraylen = 0, timeslen = 0, fileposlen = 0, i;
 -    double num_val;
 +    unsigned int timeslen = 0, fileposlen = 0, i;
      char str_val[256];
      int64_t *times = NULL;
      int64_t *filepositions = NULL;
      int ret = AVERROR(ENOSYS);
      int64_t initial_pos = avio_tell(ioc);
+     AVDictionaryEntry *creator = av_dict_get(s->metadata, "metadatacreator",
+                                              NULL, 0);
+     if (creator && !strcmp(creator->value, "MEGA")) {
+         /* Files with this metadatacreator tag seem to have filepositions
+          * pointing at the 4 trailer bytes of the previous packet,
+          * which isn't the norm (nor what we expect here, nor what
+          * jwplayer + lighttpd expect, nor what flvtool2 produces).
+          * Just ignore the index in this case, instead of risking trying
+          * to adjust it to something that might or might not work. */
+         return 0;
+     }
  
      while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
 -        int64_t* current_array;
 +        int64_t** current_array;
 +        unsigned int arraylen;
  
          // Expect array object in context
          if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY)
              break;
  
          arraylen = avio_rb32(ioc);
 -        /*
 -         * Expect only 'times' or 'filepositions' sub-arrays in other case refuse to use such metadata
 -         * for indexing
 -         */
 -        if (!strcmp(KEYFRAMES_TIMESTAMP_TAG, str_val) && !times) {
 -            if (!(times = av_mallocz(sizeof(*times) * arraylen))) {
 -                ret = AVERROR(ENOMEM);
 -                goto finish;
 -            }
 -            timeslen = arraylen;
 -            current_array = times;
 -        } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions) {
 -            if (!(filepositions = av_mallocz(sizeof(*filepositions) * arraylen))) {
 -                ret = AVERROR(ENOMEM);
 -                goto finish;
 -            }
 -            fileposlen = arraylen;
 -            current_array = filepositions;
 -        } else // unexpected metatag inside keyframes, will not use such metadata for indexing
 +        if(arraylen>>28)
 +            break;
 +
 +        if       (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times){
 +            current_array= &times;
 +            timeslen= arraylen;
 +        }else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions){
 +            current_array= &filepositions;
 +            fileposlen= arraylen;
 +        }else // unexpected metatag inside keyframes, will not use such metadata for indexing
              break;
  
 +        if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) {
 +            ret = AVERROR(ENOMEM);
 +            goto finish;
 +        }
 +
          for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
              if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER)
                  goto finish;
 -            num_val = av_int2dbl(avio_rb64(ioc));
 -            current_array[i] = num_val;
 +            current_array[0][i] = av_int2dbl(avio_rb64(ioc));
          }
          if (times && filepositions) {
              // All done, exiting at a position allowing amf_parse_object
          }
      }
  
 -    if (timeslen == fileposlen)
 -         for(i = 0; i < arraylen; i++)
 +    if (timeslen == fileposlen) {
 +         for(i = 0; i < timeslen; i++)
               av_add_index_entry(vstream, filepositions[i], times[i]*1000, 0, 0, AVINDEX_KEYFRAME);
 -    else
 +    else
          av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n");
  
  finish:
      av_freep(&times);
      av_freep(&filepositions);
 -    // If we got unexpected data, but successfully reset back to
 -    // the start pos, the caller can continue parsing
 -    if (ret < 0 && avio_seek(ioc, initial_pos, SEEK_SET) > 0)
 -        return 0;
 +    avio_seek(ioc, initial_pos, SEEK_SET);
      return ret;
  }
  
@@@ -216,9 -236,9 +228,9 @@@ static int amf_parse_object(AVFormatCon
          case AMF_DATA_TYPE_OBJECT: {
              unsigned int keylen;
  
 -            if (key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
 +            if (ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
                  if (parse_keyframes_index(s, ioc, vstream, max_pos) < 0)
 -                    return -1;
 +                    av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
  
              while(avio_tell(ioc) < max_pos - 2 && (keylen = avio_rb16(ioc))) {
                  avio_skip(ioc, keylen); //skip key string
                  vcodec->bit_rate = num_val * 1024.0;
              else if(!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
                  acodec->bit_rate = num_val * 1024.0;
 +        } else if(amf_type == AMF_DATA_TYPE_OBJECT){
 +            if(s->nb_streams==1 && ((!acodec && !strcmp(key, "audiocodecid")) || (!vcodec && !strcmp(key, "videocodecid")))){
 +                s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object
 +            }
          } else if (amf_type == AMF_DATA_TYPE_STRING)
              av_dict_set(&s->metadata, key, str_val, 0);
      }
  
  static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
      AMFDataType type;
 -    AVStream *stream, *astream, *vstream;
 +    AVStream *stream, *astream, *vstream, *dstream;
      AVIOContext *ioc;
      int i;
      char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want.
  
 -    astream = NULL;
 -    vstream = NULL;
 +    vstream = astream = dstream = NULL;
      ioc = s->pb;
  
      //first object needs to be "onMetaData" string
      //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
      for(i = 0; i < s->nb_streams; i++) {
          stream = s->streams[i];
 -        if     (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
 -        else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
 +        if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
 +        else if(stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
 +        else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) dstream = stream;
      }
  
      //parse the second object (we want a mixed array)
      return 0;
  }
  
 -static AVStream *create_stream(AVFormatContext *s, int is_audio){
 -    AVStream *st = av_new_stream(s, is_audio);
 +static AVStream *create_stream(AVFormatContext *s, int stream_type){
 +    AVStream *st = av_new_stream(s, stream_type);
      if (!st)
          return NULL;
 -    st->codec->codec_type = is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO;
 +    switch(stream_type) {
 +        case FLV_STREAM_TYPE_VIDEO:    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;    break;
 +        case FLV_STREAM_TYPE_AUDIO:    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;    break;
 +        case FLV_STREAM_TYPE_DATA:
 +            st->codec->codec_type = AVMEDIA_TYPE_DATA;
 +            st->codec->codec_id = CODEC_ID_NONE; // Going to rely on copy for now
 +            av_log(s, AV_LOG_DEBUG, "Data stream created\n");
 +    }
      av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
      return st;
  }
@@@ -351,15 -360,13 +363,15 @@@ static int flv_read_header(AVFormatCont
          s->ctx_flags |= AVFMTCTX_NOHEADER;
  
      if(flags & FLV_HEADER_FLAG_HASVIDEO){
 -        if(!create_stream(s, 0))
 +        if(!create_stream(s, FLV_STREAM_TYPE_VIDEO))
              return AVERROR(ENOMEM);
      }
      if(flags & FLV_HEADER_FLAG_HASAUDIO){
 -        if(!create_stream(s, 1))
 +        if(!create_stream(s, FLV_STREAM_TYPE_AUDIO))
              return AVERROR(ENOMEM);
      }
 +    // Flag doesn't indicate whether or not there is script-data present. Must
 +    // create that stream if it's encountered.
  
      offset = avio_rb32(s->pb);
      avio_seek(s->pb, offset, SEEK_SET);
@@@ -384,8 -391,7 +396,8 @@@ static int flv_get_extradata(AVFormatCo
  static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
  {
      FLVContext *flv = s->priv_data;
 -    int ret, i, type, size, flags, is_audio;
 +    int ret, i, type, size, flags;
 +    int stream_type=-1;
      int64_t next, pos;
      int64_t dts, pts = AV_NOPTS_VALUE;
      AVStream *st = NULL;
      dts = avio_rb24(s->pb);
      dts |= avio_r8(s->pb) << 24;
      av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
 -    if (s->pb->eof_reached)
 +    if (url_feof(s->pb))
          return AVERROR_EOF;
      avio_skip(s->pb, 3); /* stream id, always 0 */
      flags = 0;
      next= size + avio_tell(s->pb);
  
      if (type == FLV_TAG_TYPE_AUDIO) {
 -        is_audio=1;
 +        stream_type=FLV_STREAM_TYPE_AUDIO;
          flags = avio_r8(s->pb);
          size--;
      } else if (type == FLV_TAG_TYPE_VIDEO) {
 -        is_audio=0;
 +        stream_type=FLV_STREAM_TYPE_VIDEO;
          flags = avio_r8(s->pb);
          size--;
          if ((flags & 0xf0) == 0x50) /* video info / command frame */
              goto skip;
 -    } else {
 -        if (type == FLV_TAG_TYPE_META && size > 13+1+4)
 +    } else if (type == FLV_TAG_TYPE_META) {
 +        if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff
              flv_read_metabody(s, next);
 -        else /* skip packet */
 -            av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
 +            goto skip;
 +        } else if (dts != 0) { // Script-data "special" metadata frames - don't skip
 +            stream_type=FLV_STREAM_TYPE_DATA;
 +        } else {
 +            goto skip;
 +        }
 +    } else {
 +        av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
      skip:
          avio_seek(s->pb, next, SEEK_SET);
          continue;
      /* now find stream */
      for(i=0;i<s->nb_streams;i++) {
          st = s->streams[i];
 -        if (st->id == is_audio)
 +        if (st->id == stream_type)
              break;
      }
      if(i == s->nb_streams){
 -        av_log(s, AV_LOG_ERROR, "invalid stream\n");
 -        st= create_stream(s, is_audio);
 +        av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
 +        st= create_stream(s, stream_type);
          s->ctx_flags &= ~AVFMTCTX_NOHEADER;
      }
 -    av_dlog(s, "%d %X %d \n", is_audio, flags, st->discard);
 -    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||         is_audio))
 -       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio))
 +    av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
 +    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
 +       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
         || st->discard >= AVDISCARD_ALL
         ){
          avio_seek(s->pb, next, SEEK_SET);
          avio_seek(s->pb, pos, SEEK_SET);
      }
  
 -    if(is_audio){
 +    if(stream_type == FLV_STREAM_TYPE_AUDIO){
          if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) {
              st->codec->channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
              st->codec->sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
          if(!st->codec->codec_id){
              flv_set_audio_codec(s, st, flags & FLV_AUDIO_CODECID_MASK);
          }
 -    }else{
 +    } else if(stream_type == FLV_STREAM_TYPE_VIDEO) {
          size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK);
      }
  
      if (st->codec->codec_id == CODEC_ID_AAC ||
 -        st->codec->codec_id == CODEC_ID_H264) {
 +        st->codec->codec_id == CODEC_ID_H264 ||
 +        st->codec->codec_id == CODEC_ID_MPEG4) {
          int type = avio_r8(s->pb);
          size--;
 -        if (st->codec->codec_id == CODEC_ID_H264) {
 +        if (st->codec->codec_id == CODEC_ID_H264 || st->codec->codec_id == CODEC_ID_MPEG4) {
              int32_t cts = (avio_rb24(s->pb)+0xff800000)^0xff800000; // sign extension
              pts = dts + cts;
              if (cts < 0) { // dts are wrong
              if (flv->wrong_dts)
                  dts = AV_NOPTS_VALUE;
          }
 -        if (type == 0) {
 +
 +        if (type == 0 && !st->codec->extradata) {
              if ((ret = flv_get_extradata(s, st, size)) < 0)
                  return ret;
              if (st->codec->codec_id == CODEC_ID_AAC) {
      pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
      pkt->stream_index = st->index;
  
 -    if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY))
 +    if (    stream_type == FLV_STREAM_TYPE_AUDIO ||
 +            ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) ||
 +            stream_type == FLV_STREAM_TYPE_DATA)
          pkt->flags |= AV_PKT_FLAG_KEY;
  
  leave:
diff --combined libavformat/rtp.c
index 70c5e997041d470961aa48751fe7289c1ed21512,35edb5066a14fee1b5f4b13c0632069902d39f6b..ab815233ab77f98f64a623d36dceaa5f5531b7fe
@@@ -2,20 -2,20 +2,20 @@@
   * RTP input/output format
   * Copyright (c) 2002 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -103,6 -103,11 +103,11 @@@ int ff_rtp_get_payload_type(AVCodecCont
                      continue;
              payload_type = AVRtpPayloadTypes[i].pt;
          }
+     /* dynamic payload type */
+     if (payload_type < 0)
+         payload_type = RTP_PT_PRIVATE + (codec->codec_type == AVMEDIA_TYPE_AUDIO);
      return payload_type;
  }
  
diff --combined libavformat/rtpenc.c
index a99fca0aed374860721c6db2e0176008de90d283,1f5d9ba37aebceb24c973e6660dc86141993d3b1..0cc68fc64ab7eae3568d5453438ed4d0652f533f
@@@ -2,20 -2,20 +2,20 @@@
   * RTP output format
   * Copyright (c) 2002 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -87,15 -87,12 +87,12 @@@ static int rtp_write_header(AVFormatCon
          return -1;
      st = s1->streams[0];
      if (!is_supported(st->codec->codec_id)) {
 -        av_log(s1, AV_LOG_ERROR, "Unsupported codec %x\n", st->codec->codec_id);
 +        av_log(s1, AV_LOG_ERROR, "Unsupported codec %s\n", avcodec_get_name(st->codec->codec_id));
  
          return -1;
      }
  
      s->payload_type = ff_rtp_get_payload_type(st->codec);
-     if (s->payload_type < 0)
-         s->payload_type = RTP_PT_PRIVATE + (st->codec->codec_type == AVMEDIA_TYPE_AUDIO);
      s->base_timestamp = av_get_random_seed();
      s->timestamp = s->base_timestamp;
      s->cur_timestamp = 0;
diff --combined libavformat/sdp.c
index 32cef499169fde9dedc0c6f16c3937c68a3d06d6,f27a89936ca8e83aad55797f4b69e8729723f4f5..fb351bb97b65b569d60b7d873aa6f4642e6603ac
@@@ -1,20 -1,20 +1,20 @@@
  /*
   * copyright (c) 2007 Luca Abeni
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -533,9 -533,6 +533,6 @@@ void ff_sdp_write_media(char *buff, in
      int payload_type;
  
      payload_type = ff_rtp_get_payload_type(c);
-     if (payload_type < 0) {
-         payload_type = RTP_PT_PRIVATE + (c->codec_type == AVMEDIA_TYPE_AUDIO);
-     }
  
      switch (c->codec_type) {
          case AVMEDIA_TYPE_VIDEO   : type = "video"      ; break;
diff --combined libavformat/utils.c
index 4dcf0ac2dfa77f7e17db785a550c3581022137ce,17b342e8ad333ed3a1e3964c7a1ec45240e05caf..72990f62301e19e5292ce0b64da3e4877ad29b33
@@@ -1,21 -1,21 +1,21 @@@
  /*
 - * various utility functions for use within Libav
 + * various utility functions for use within FFmpeg
   * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -25,7 -25,6 +25,7 @@@
  #include "avio_internal.h"
  #include "internal.h"
  #include "libavcodec/internal.h"
 +#include "libavcodec/raw.h"
  #include "libavutil/opt.h"
  #include "libavutil/dict.h"
  #include "libavutil/pixdesc.h"
@@@ -49,7 -48,7 +49,7 @@@
  
  /**
   * @file
 - * various utility functions for use within Libav
 + * various utility functions for use within FFmpeg
   */
  
  unsigned avformat_version(void)
  
  const char *avformat_configuration(void)
  {
 -    return LIBAV_CONFIGURATION;
 +    return FFMPEG_CONFIGURATION;
  }
  
  const char *avformat_license(void)
  {
  #define LICENSE_PREFIX "libavformat license: "
 -    return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
 +    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
  }
  
  /* fraction handling */
@@@ -305,11 -304,11 +305,11 @@@ int av_filename_number_test(const char 
      return filename && (av_get_frame_filename(buf, sizeof(buf), filename, 1)>=0);
  }
  
 -AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)
 +AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret)
  {
      AVProbeData lpd = *pd;
      AVInputFormat *fmt1 = NULL, *fmt;
 -    int score, id3 = 0;
 +    int score, score_max=0;
  
      if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
          int id3len = ff_id3v2_tag_len(lpd.buf);
              lpd.buf += id3len;
              lpd.buf_size -= id3len;
          }
 -        id3 = 1;
      }
  
      fmt = NULL;
          score = 0;
          if (fmt1->read_probe) {
              score = fmt1->read_probe(&lpd);
 +            if(!score && fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions))
 +                score = 1;
          } else if (fmt1->extensions) {
              if (av_match_ext(lpd.filename, fmt1->extensions)) {
                  score = 50;
              }
          }
 -        if (score > *score_max) {
 -            *score_max = score;
 +        if (score > score_max) {
 +            score_max = score;
              fmt = fmt1;
 -        }else if (score == *score_max)
 +        }else if (score == score_max)
              fmt = NULL;
      }
 -
 -    /* a hack for files with huge id3v2 tags -- try to guess by file extension. */
 -    if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4) {
 -        while ((fmt = av_iformat_next(fmt)))
 -            if (fmt->extensions && av_match_ext(lpd.filename, fmt->extensions)) {
 -                *score_max = AVPROBE_SCORE_MAX/4;
 -                break;
 -            }
 -    }
 -
 +    *score_ret= score_max;
      return fmt;
  }
  
 +AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)
 +{
 +    int score_ret;
 +    AVInputFormat *fmt= av_probe_input_format3(pd, is_opened, &score_ret);
 +    if(score_ret > *score_max){
 +        *score_max= score_ret;
 +        return fmt;
 +    }else
 +        return NULL;
 +}
 +
  AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){
      int score=0;
      return av_probe_input_format2(pd, is_opened, &score);
  }
  
 -static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd, int score)
 +static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd)
  {
      static const struct {
          const char *name; enum CodecID id; enum AVMediaType type;
          { "dts"      , CODEC_ID_DTS       , AVMEDIA_TYPE_AUDIO },
          { "eac3"     , CODEC_ID_EAC3      , AVMEDIA_TYPE_AUDIO },
          { "h264"     , CODEC_ID_H264      , AVMEDIA_TYPE_VIDEO },
 +        { "loas"     , CODEC_ID_AAC_LATM  , AVMEDIA_TYPE_AUDIO },
          { "m4v"      , CODEC_ID_MPEG4     , AVMEDIA_TYPE_VIDEO },
          { "mp3"      , CODEC_ID_MP3       , AVMEDIA_TYPE_AUDIO },
          { "mpegvideo", CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO },
          { 0 }
      };
 -    AVInputFormat *fmt = av_probe_input_format2(pd, 1, &score);
 +    int score;
 +    AVInputFormat *fmt = av_probe_input_format3(pd, 1, &score);
  
      if (fmt) {
          int i;
              }
          }
      }
 -    return !!fmt;
 +    return score;
  }
  
  /************************************************************/
@@@ -459,7 -453,7 +459,7 @@@ int av_open_input_stream(AVFormatContex
      opts = convert_format_parameters(ap);
  
      if(!ap->prealloced_context)
 -        ic = avformat_alloc_context();
 +        *ic_ptr = ic = avformat_alloc_context();
      else
          ic = *ic_ptr;
      if (!ic) {
@@@ -483,22 -477,6 +483,22 @@@ fail
  }
  #endif
  
 +int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap){
 +    int err;
 +
 +    if (ic->iformat->read_header) {
 +        err = ic->iformat->read_header(ic, ap);
 +        if (err < 0)
 +            return err;
 +    }
 +
 +    if (ic->pb && !ic->data_offset)
 +        ic->data_offset = avio_tell(ic->pb);
 +
 +    return 0;
 +}
 +
 +
  /** size of probe buffer, for guessing file type from file contents */
  #define PROBE_BUF_MIN 2048
  #define PROBE_BUF_MAX (1<<20)
@@@ -527,19 -505,13 +527,19 @@@ int av_probe_input_buffer(AVIOContext *
          probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) {
          int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0;
          int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1;
 +        void *buftmp;
  
          if (probe_size < offset) {
              continue;
          }
  
          /* read probe data */
 -        buf = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);
 +        buftmp = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);
 +        if(!buftmp){
 +            av_free(buf);
 +            return AVERROR(ENOMEM);
 +        }
 +        buf=buftmp;
          if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) {
              /* fail if error was not end of file, otherwise, lower score */
              if (ret != AVERROR_EOF) {
          *fmt = av_probe_input_format2(&pd, 1, &score);
          if(*fmt){
              if(score <= AVPROBE_SCORE_MAX/4){ //this can only be true in the last iteration
 -                av_log(logctx, AV_LOG_WARNING, "Format detected only with low score of %d, misdetection possible!\n", score);
 +                av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, misdetection possible!\n", (*fmt)->name, score);
              }else
 -                av_log(logctx, AV_LOG_DEBUG, "Probed with size=%d and score=%d\n", probe_size, score);
 +                av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score);
          }
      }
  
@@@ -606,8 -578,7 +606,8 @@@ static int init_input(AVFormatContext *
          if (!s->iformat)
              return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0);
          else if (s->iformat->flags & AVFMT_NOFILE)
 -            return AVERROR(EINVAL);
 +            av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
 +                                      "will be ignored with AVFMT_NOFILE format.\n");
          return 0;
      }
  
@@@ -672,11 -643,11 +672,11 @@@ int avformat_open_input(AVFormatContex
      if (s->pb)
          ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
  
 -    if (s->iformat->read_header)
 +    if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
          if ((ret = s->iformat->read_header(s, &ap)) < 0)
              goto fail;
  
 -    if (s->pb && !s->data_offset)
 +    if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->data_offset)
          s->data_offset = avio_tell(s->pb);
  
      s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
@@@ -726,7 -697,12 +726,7 @@@ int av_read_packet(AVFormatContext *s, 
  
          if (pktl) {
              *pkt = pktl->pkt;
 -            if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE ||
 -               !s->streams[pkt->stream_index]->probe_packets ||
 -               s->raw_packet_buffer_remaining_size < pkt->size){
 -                AVProbeData *pd = &s->streams[pkt->stream_index]->probe_data;
 -                av_freep(&pd->buf);
 -                pd->buf_size = 0;
 +            if(s->streams[pkt->stream_index]->request_probe <= 0){
                  s->raw_packet_buffer = pktl->next;
                  s->raw_packet_buffer_remaining_size += pkt->size;
                  av_free(pktl);
              if (!pktl || ret == AVERROR(EAGAIN))
                  return ret;
              for (i = 0; i < s->nb_streams; i++)
 -                s->streams[i]->probe_packets = 0;
 +                if(s->streams[i]->request_probe > 0)
 +                    s->streams[i]->request_probe = -1;
              continue;
          }
  
              continue;
          }
  
 +        if(!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
 +            av_packet_merge_side_data(pkt);
 +
          st= s->streams[pkt->stream_index];
  
          switch(st->codec->codec_type){
              break;
          }
  
 -        if(!pktl && (st->codec->codec_id != CODEC_ID_PROBE ||
 -                     !st->probe_packets))
 +        if(!pktl && st->request_probe <= 0)
              return ret;
  
          add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
          s->raw_packet_buffer_remaining_size -= pkt->size;
  
 -        if(st->codec->codec_id == CODEC_ID_PROBE){
 +        if(st->request_probe>0){
              AVProbeData *pd = &st->probe_data;
 -            av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index);
 +            int end;
 +            av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets);
              --st->probe_packets;
  
              pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
              pd->buf_size += pkt->size;
              memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
  
 -            if(av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
 -                //FIXME we dont reduce score to 0 for the case of running out of buffer space in bytes
 -                set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0);
 -                if(st->codec->codec_id != CODEC_ID_PROBE){
 +            end=    s->raw_packet_buffer_remaining_size <= 0
 +                 || st->probe_packets<=0;
 +
 +            if(end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
 +                int score= set_codec_from_probe_data(s, st, pd);
 +                if(    (st->codec->codec_id != CODEC_ID_NONE && score > AVPROBE_SCORE_MAX/4)
 +                    || end){
                      pd->buf_size=0;
                      av_freep(&pd->buf);
 +                    st->request_probe= -1;
 +                    if(st->codec->codec_id != CODEC_ID_NONE){
                      av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
 +                    }else
 +                        av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index);
                  }
              }
          }
@@@ -887,6 -852,7 +887,7 @@@ static int is_intra_only(AVCodecContex
          case CODEC_ID_MJPEG:
          case CODEC_ID_MJPEGB:
          case CODEC_ID_LJPEG:
+         case CODEC_ID_PRORES:
          case CODEC_ID_RAWVIDEO:
          case CODEC_ID_DVVIDEO:
          case CODEC_ID_HUFFYUV:
          case CODEC_ID_VCR1:
          case CODEC_ID_DNXHD:
          case CODEC_ID_JPEG2000:
-         case CODEC_ID_PRORES:
              return 1;
          default: break;
          }
@@@ -1000,7 -965,8 +1000,7 @@@ static void compute_pkt_fields(AVFormat
          pc && pc->pict_type != AV_PICTURE_TYPE_B)
          presentation_delayed = 1;
  
 -    if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && pkt->dts > pkt->pts && st->pts_wrap_bits<63
 -       /*&& pkt->dts-(1LL<<st->pts_wrap_bits) < pkt->pts*/){
 +    if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && pkt->dts - (1LL<<(st->pts_wrap_bits-1)) > pkt->pts && st->pts_wrap_bits<63){
          pkt->dts -= 1LL<<st->pts_wrap_bits;
      }
  
      // we take the conservative approach and discard both
      // Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly.
      if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){
 -        av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination\n");
 +        av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination %Ld\n", pkt->dts);
          pkt->dts= pkt->pts= AV_NOPTS_VALUE;
      }
  
@@@ -1146,10 -1112,7 +1146,10 @@@ static int read_frame_internal(AVFormat
              if (!st->need_parsing || !st->parser) {
                  /* no parsing needed: we just output the packet as is */
                  /* raw data support */
 -                *pkt = st->cur_pkt; st->cur_pkt.data= NULL;
 +                *pkt = st->cur_pkt;
 +                st->cur_pkt.data= NULL;
 +                st->cur_pkt.side_data_elems = 0;
 +                st->cur_pkt.side_data = NULL;
                  compute_pkt_fields(s, st, NULL, pkt);
                  s->cur_st = NULL;
                  if ((s->iformat->flags & AVFMT_GENERIC_INDEX) &&
                      compute_pkt_fields(s, st, st->parser, pkt);
  
                      if((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & AV_PKT_FLAG_KEY){
 +                        int64_t pos= (st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) ? pkt->pos : st->parser->frame_offset;
                          ff_reduce_index(s, st->index);
 -                        av_add_index_entry(st, st->parser->frame_offset, pkt->dts,
 +                        av_add_index_entry(st, pos, pkt->dts,
                                             0, 0, AVINDEX_KEYFRAME);
                      }
  
              if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
                  st->parser = av_parser_init(st->codec->codec_id);
                  if (!st->parser) {
 +                    av_log(s, AV_LOG_WARNING, "parser not found for codec "
 +                           "%s, packets or times may be invalid.\n",
 +                           avcodec_get_name(st->codec->codec_id));
                      /* no parser available: just output the raw packets */
                      st->need_parsing = AVSTREAM_PARSE_NONE;
                  }else if(st->need_parsing == AVSTREAM_PARSE_HEADERS){
@@@ -1855,8 -1814,6 +1855,8 @@@ static int has_duration(AVFormatContex
  {
      int i;
      AVStream *st;
 +    if(ic->duration != AV_NOPTS_VALUE)
 +        return 1;
  
      for(i = 0;i < ic->nb_streams; i++) {
          st = ic->streams[i];
   */
  static void update_stream_timings(AVFormatContext *ic)
  {
 -    int64_t start_time, start_time1, end_time, end_time1;
 +    int64_t start_time, start_time1, start_time_text, end_time, end_time1;
      int64_t duration, duration1;
      int i;
      AVStream *st;
  
      start_time = INT64_MAX;
 +    start_time_text = INT64_MAX;
      end_time = INT64_MIN;
      duration = INT64_MIN;
      for(i = 0;i < ic->nb_streams; i++) {
          st = ic->streams[i];
          if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
              start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
 +            if (st->codec->codec_id == CODEC_ID_DVB_TELETEXT) {
 +                if (start_time1 < start_time_text)
 +                    start_time_text = start_time1;
 +            } else
              if (start_time1 < start_time)
                  start_time = start_time1;
              if (st->duration != AV_NOPTS_VALUE) {
                  duration = duration1;
          }
      }
 +    if (start_time == INT64_MAX || (start_time > start_time_text && start_time - start_time_text < AV_TIME_BASE))
 +        start_time = start_time_text;
      if (start_time != INT64_MAX) {
          ic->start_time = start_time;
          if (end_time != INT64_MIN) {
                  duration = end_time - start_time;
          }
      }
 -    if (duration != INT64_MIN) {
 +    if (duration != INT64_MIN && ic->duration == AV_NOPTS_VALUE) {
          ic->duration = duration;
 -        if (ic->file_size > 0) {
 +    }
 +        if (ic->file_size > 0 && ic->duration != AV_NOPTS_VALUE) {
              /* compute the bitrate */
              ic->bit_rate = (double)ic->file_size * 8.0 * AV_TIME_BASE /
                  (double)ic->duration;
          }
 -    }
  }
  
  static void fill_all_stream_timings(AVFormatContext *ic)
@@@ -2110,21 -2060,18 +2110,21 @@@ static int has_codec_parameters(AVCodec
      switch (avctx->codec_type) {
      case AVMEDIA_TYPE_AUDIO:
          val = avctx->sample_rate && avctx->channels && avctx->sample_fmt != AV_SAMPLE_FMT_NONE;
 -        if (!avctx->frame_size &&
 -            (avctx->codec_id == CODEC_ID_VORBIS ||
 -             avctx->codec_id == CODEC_ID_AAC ||
 -             avctx->codec_id == CODEC_ID_MP1 ||
 -             avctx->codec_id == CODEC_ID_MP2 ||
 -             avctx->codec_id == CODEC_ID_MP3 ||
 -             avctx->codec_id == CODEC_ID_SPEEX))
 +        if(!avctx->frame_size &&
 +           (avctx->codec_id == CODEC_ID_VORBIS ||
 +            avctx->codec_id == CODEC_ID_AAC ||
 +            avctx->codec_id == CODEC_ID_MP1 ||
 +            avctx->codec_id == CODEC_ID_MP2 ||
 +            avctx->codec_id == CODEC_ID_MP3 ||
 +            avctx->codec_id == CODEC_ID_SPEEX ||
 +            avctx->codec_id == CODEC_ID_CELT))
              return 0;
          break;
      case AVMEDIA_TYPE_VIDEO:
          val = avctx->width && avctx->pix_fmt != PIX_FMT_NONE;
          break;
 +    case AVMEDIA_TYPE_DATA:
 +        if(avctx->codec_id == CODEC_ID_NONE) return 1;
      default:
          val = 1;
          break;
@@@ -2287,15 -2234,6 +2287,15 @@@ int avformat_find_stream_info(AVFormatC
      for(i=0;i<ic->nb_streams;i++) {
          AVCodec *codec;
          st = ic->streams[i];
 +        if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size) {
 +            // We need to discard these since they can be plain wrong for
 +            // backwards compatible HE-AAC signaling.
 +            // But when we have no extradata we need to keep them or we can't
 +            // play anything at all.
 +            st->codec->sample_rate = 0;
 +            st->codec->frame_size = 0;
 +            st->codec->channels = 0;
 +        }
  
          if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
              st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
  
          //try to just open decoders, in case this is enough to get parameters
          if(!has_codec_parameters(st->codec)){
 -            if (codec && !st->codec->codec)
 -                avcodec_open2(st->codec, codec, options ? &options[i] : NULL);
 +            if (codec && !st->codec->codec){
 +                AVDictionary *tmp = NULL;
 +                if (options){
 +                    av_dict_copy(&tmp, options[i], 0);
 +                    av_dict_set(&tmp, "threads", 0, 0);
 +                }
 +                avcodec_open2(st->codec, codec, options ? &tmp : NULL);
 +                av_dict_free(&tmp);
 +            }
          }
      }
  
                  break;
              if(st->parser && st->parser->parser->split && !st->codec->extradata)
                  break;
 -            if(st->first_dts == AV_NOPTS_VALUE)
 +            if(st->first_dts == AV_NOPTS_VALUE && (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || st->codec->codec_type == AVMEDIA_TYPE_AUDIO))
                  break;
          }
          if (i == ic->nb_streams) {
  
          st = ic->streams[pkt->stream_index];
          if (st->codec_info_nb_frames>1) {
 -            if (st->time_base.den > 0 && av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
 -                av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
 +            int64_t t;
 +            if (st->time_base.den > 0 && (t=av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q)) >= ic->max_analyze_duration) {
 +                av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached at %"PRId64"\n", ic->max_analyze_duration, t);
                  break;
              }
              st->info->codec_info_duration += pkt->duration;
              int64_t duration= pkt->dts - last;
  
              if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && duration>0){
 -                double dur= duration * av_q2d(st->time_base);
 +                double dts= pkt->dts * av_q2d(st->time_base);
  
  //                if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
  //                    av_log(NULL, AV_LOG_ERROR, "%f\n", dur);
 -                if (st->info->duration_count < 2)
 -                    memset(st->info->duration_error, 0, sizeof(st->info->duration_error));
 -                for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error); i++) {
 +                for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error[0][0]); i++) {
                      int framerate= get_std_framerate(i);
 -                    int ticks= lrintf(dur*framerate/(1001*12));
 -                    double error= dur - ticks*1001*12/(double)framerate;
 -                    st->info->duration_error[i] += error*error;
 +                    double sdts= dts*framerate/(1001*12);
 +                    for(j=0; j<2; j++){
 +                        int ticks= lrintf(sdts+j*0.5);
 +                        double error= sdts - ticks + j*0.5;
 +                        st->info->duration_error[j][0][i] += error;
 +                        st->info->duration_error[j][1][i] += error*error;
 +                    }
                  }
                  st->info->duration_count++;
                  // ignore the first 4 values, they might have some random jitter
                       (st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,
                        st->info->codec_info_duration*(int64_t)st->time_base.num, 60000);
          if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 -            if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample)
 -                st->codec->codec_tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
 +            if(st->codec->codec_id == CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample){
 +                uint32_t tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
 +                if(ff_find_pix_fmt(ff_raw_pix_fmt_tags, tag) == st->codec->pix_fmt)
 +                    st->codec->codec_tag= tag;
 +            }
  
              // the check for tb_unreliable() is not completely correct, since this is not about handling
              // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
              // ipmovie.c produces.
 -            if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > 1 && !st->r_frame_rate.num)
 +            if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num)
                  av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX);
              if (st->info->duration_count && !st->r_frame_rate.num
                 && tb_unreliable(st->codec) /*&&
                 //FIXME we should not special-case MPEG-2, but this needs testing with non-MPEG-2 ...
                 st->time_base.num*duration_sum[i]/st->info->duration_count*101LL > st->time_base.den*/){
                  int num = 0;
 -                double best_error= 2*av_q2d(st->time_base);
 -                best_error = best_error*best_error*st->info->duration_count*1000*12*30;
 -
 -                for (j=1; j<FF_ARRAY_ELEMS(st->info->duration_error); j++) {
 -                    double error = st->info->duration_error[j] * get_std_framerate(j);
 -//                    if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
 -//                        av_log(NULL, AV_LOG_ERROR, "%f %f\n", get_std_framerate(j) / 12.0/1001, error);
 -                    if(error < best_error){
 -                        best_error= error;
 -                        num = get_std_framerate(j);
 +                double best_error= 0.01;
 +
 +                for (j=1; j<FF_ARRAY_ELEMS(st->info->duration_error[0][0]); j++) {
 +                    int k;
 +
 +                    if(st->info->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j))
 +                        continue;
 +                    for(k=0; k<2; k++){
 +                        int n= st->info->duration_count;
 +                        double a= st->info->duration_error[k][0][j] / n;
 +                        double error= st->info->duration_error[k][1][j]/n - a*a;
 +
 +                        if(error < best_error && best_error> 0.000000001){
 +                            best_error= error;
 +                            num = get_std_framerate(j);
 +                        }
 +                        if(error < 0.02)
 +                            av_log(NULL, AV_LOG_DEBUG, "rfps: %f %f\n", get_std_framerate(j) / 12.0/1001, error);
                      }
                  }
                  // do not increase frame rate by more than 1 % in order to match a standard rate.
      return ret;
  }
  
 -static AVProgram *find_program_from_stream(AVFormatContext *ic, int s)
 +AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s)
  {
      int i, j;
  
 -    for (i = 0; i < ic->nb_programs; i++)
 -        for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
 -            if (ic->programs[i]->stream_index[j] == s)
 -                return ic->programs[i];
 +    for (i = 0; i < ic->nb_programs; i++) {
 +        if (ic->programs[i] == last) {
 +            last = NULL;
 +        } else {
 +            if (!last)
 +                for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
 +                    if (ic->programs[i]->stream_index[j] == s)
 +                        return ic->programs[i];
 +        }
 +    }
      return NULL;
  }
  
@@@ -2625,7 -2536,7 +2625,7 @@@ int av_find_best_stream(AVFormatContex
      AVCodec *decoder = NULL, *best_decoder = NULL;
  
      if (related_stream >= 0 && wanted_stream_nb < 0) {
 -        AVProgram *p = find_program_from_stream(ic, related_stream);
 +        AVProgram *p = av_find_program_from_stream(ic, NULL, related_stream);
          if (p) {
              program = p->stream_index;
              nb_streams = p->nb_stream_indexes;
@@@ -2848,6 -2759,8 +2848,6 @@@ AVChapter *ff_new_chapter(AVFormatConte
  #if FF_API_FORMAT_PARAMETERS
  int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
  {
 -    int ret;
 -
      if (s->oformat->priv_data_size > 0) {
          s->priv_data = av_mallocz(s->oformat->priv_data_size);
          if (!s->priv_data)
      } else
          s->priv_data = NULL;
  
 -    if (s->oformat->set_parameters) {
 -        ret = s->oformat->set_parameters(s, ap);
 -        if (ret < 0)
 -            return ret;
 +    return 0;
 +}
 +#endif
 +
 +int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
 +                                   const char *format, const char *filename)
 +{
 +    AVFormatContext *s = avformat_alloc_context();
 +    int ret = 0;
 +
 +    *avctx = NULL;
 +    if (!s)
 +        goto nomem;
 +
 +    if (!oformat) {
 +        if (format) {
 +            oformat = av_guess_format(format, NULL, NULL);
 +            if (!oformat) {
 +                av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
 +                ret = AVERROR(EINVAL);
 +                goto error;
 +            }
 +        } else {
 +            oformat = av_guess_format(NULL, filename, NULL);
 +            if (!oformat) {
 +                ret = AVERROR(EINVAL);
 +                av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n",
 +                       filename);
 +                goto error;
 +            }
 +        }
      }
 +
 +    s->oformat = oformat;
 +    if (s->oformat->priv_data_size > 0) {
 +        s->priv_data = av_mallocz(s->oformat->priv_data_size);
 +        if (!s->priv_data)
 +            goto nomem;
 +        if (s->oformat->priv_class) {
 +            *(const AVClass**)s->priv_data= s->oformat->priv_class;
 +            av_opt_set_defaults(s->priv_data);
 +        }
 +    } else
 +        s->priv_data = NULL;
 +
 +    if (filename)
 +        av_strlcpy(s->filename, filename, sizeof(s->filename));
 +    *avctx = s;
      return 0;
 +nomem:
 +    av_log(s, AV_LOG_ERROR, "Out of memory\n");
 +    ret = AVERROR(ENOMEM);
 +error:
 +    avformat_free_context(s);
 +    return ret;
 +}
 +
 +#if FF_API_ALLOC_OUTPUT_CONTEXT
 +AVFormatContext *avformat_alloc_output_context(const char *format,
 +                                               AVOutputFormat *oformat, const char *filename)
 +{
 +    AVFormatContext *avctx;
 +    int ret = avformat_alloc_output_context2(&avctx, oformat, format, filename);
 +    return ret < 0 ? NULL : avctx;
  }
  #endif
  
@@@ -2976,9 -2831,6 +2976,9 @@@ int avformat_write_header(AVFormatConte
          av_dict_copy(&tmp, *options, 0);
      if ((ret = av_opt_set_dict(s, &tmp)) < 0)
          goto fail;
 +    if (s->priv_data && s->oformat->priv_class && *(const AVClass**)s->priv_data==s->oformat->priv_class &&
 +        (ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
 +        goto fail;
  
      // some sanity checks
      if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) {
                  ret = AVERROR(EINVAL);
                  goto fail;
              }
 -            if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){
 +            if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)
 +               && FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(st->codec->sample_aspect_ratio)) > 0.001
 +            ){
                  av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n");
                  ret = AVERROR(EINVAL);
                  goto fail;
@@@ -3145,7 -2995,7 +3145,7 @@@ static int compute_pkt_fields2(AVFormat
          pkt->dts= st->pts_buffer[0];
      }
  
 -    if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){
 +    if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) && st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)){
          av_log(s, AV_LOG_ERROR,
                 "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %"PRId64" >= %"PRId64"\n",
                 st->index, st->cur_dts, pkt->dts);
@@@ -3245,44 -3095,17 +3245,44 @@@ static int ff_interleave_compare_dts(AV
  
  int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){
      AVPacketList *pktl;
 -    int stream_count=0;
 +    int stream_count=0, noninterleaved_count=0;
 +    int64_t delta_dts_max = 0;
      int i;
  
      if(pkt){
          ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
      }
  
 -    for(i=0; i < s->nb_streams; i++)
 -        stream_count+= !!s->streams[i]->last_in_packet_buffer;
 +    for(i=0; i < s->nb_streams; i++) {
 +        if (s->streams[i]->last_in_packet_buffer) {
 +            ++stream_count;
 +        } else if(s->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
 +            ++noninterleaved_count;
 +        }
 +    }
  
 -    if(stream_count && (s->nb_streams == stream_count || flush)){
 +    if (s->nb_streams == stream_count) {
 +        flush = 1;
 +    } else if (!flush){
 +        for(i=0; i < s->nb_streams; i++) {
 +            if (s->streams[i]->last_in_packet_buffer) {
 +                int64_t delta_dts =
 +                    av_rescale_q(s->streams[i]->last_in_packet_buffer->pkt.dts,
 +                                s->streams[i]->time_base,
 +                                AV_TIME_BASE_Q) -
 +                    av_rescale_q(s->packet_buffer->pkt.dts,
 +                                s->streams[s->packet_buffer->pkt.stream_index]->time_base,
 +                                AV_TIME_BASE_Q);
 +                delta_dts_max= FFMAX(delta_dts_max, delta_dts);
 +            }
 +        }
 +        if(s->nb_streams == stream_count+noninterleaved_count &&
 +           delta_dts_max > 20*AV_TIME_BASE) {
 +            av_log(s, AV_LOG_DEBUG, "flushing with %d noninterleaved\n", noninterleaved_count);
 +            flush = 1;
 +        }
 +    }
 +    if(stream_count && flush){
          pktl= s->packet_buffer;
          *out= pktl->pkt;
  
@@@ -3347,8 -3170,6 +3347,8 @@@ int av_interleaved_write_frame(AVFormat
  
          if(ret<0)
              return ret;
 +        if(url_ferror(s->pb))
 +            return url_ferror(s->pb);
      }
  }
  
@@@ -3372,15 -3193,11 +3372,15 @@@ int av_write_trailer(AVFormatContext *s
  
          if(ret<0)
              goto fail;
 +        if(url_ferror(s->pb))
 +            goto fail;
      }
  
      if(s->oformat->write_trailer)
          ret = s->oformat->write_trailer(s);
  fail:
 +    if(ret == 0)
 +       ret=url_ferror(s->pb);
      for(i=0;i<s->nb_streams;i++) {
          av_freep(&s->streams[i]->priv_data);
          av_freep(&s->streams[i]->index_entries);
      return ret;
  }
  
 +int av_get_output_timestamp(struct AVFormatContext *s, int stream,
 +                            int64_t *dts, int64_t *wall)
 +{
 +    if (!s->oformat || !s->oformat->get_output_timestamp)
 +        return AVERROR(ENOSYS);
 +    s->oformat->get_output_timestamp(s, stream, dts, wall);
 +    return 0;
 +}
 +
  void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx)
  {
      int i, j;
@@@ -3442,13 -3250,8 +3442,13 @@@ static void dump_metadata(void *ctx, AV
  
          av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent);
          while((tag=av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) {
 -            if(strcmp("language", tag->key))
 -                av_log(ctx, AV_LOG_INFO, "%s  %-16s: %s\n", indent, tag->key, tag->value);
 +            if(strcmp("language", tag->key)){
 +                char tmp[256];
 +                int i;
 +                av_strlcpy(tmp, tag->value, sizeof(tmp));
 +                for(i=0; i<strlen(tmp); i++) if(tmp[i]==0xd) tmp[i]=' ';
 +                av_log(ctx, AV_LOG_INFO, "%s  %-16s: %s\n", indent, tag->key, tmp);
 +            }
          }
      }
  }
@@@ -3462,7 -3265,7 +3462,7 @@@ static void dump_stream_format(AVFormat
      int g = av_gcd(st->time_base.num, st->time_base.den);
      AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
      avcodec_string(buf, sizeof(buf), st->codec, is_output);
 -    av_log(NULL, AV_LOG_INFO, "    Stream #%d.%d", index, i);
 +    av_log(NULL, AV_LOG_INFO, "    Stream #%d:%d", index, i);
      /* the pid is an important information, so we display it */
      /* XXX: add a generic system */
      if (flags & AVFMT_SHOW_IDS)
                    st->codec->width*st->sample_aspect_ratio.num,
                    st->codec->height*st->sample_aspect_ratio.den,
                    1024*1024);
 -        av_log(NULL, AV_LOG_INFO, ", PAR %d:%d DAR %d:%d",
 +        av_log(NULL, AV_LOG_INFO, ", SAR %d:%d DAR %d:%d",
                   st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
                   display_aspect_ratio.num, display_aspect_ratio.den);
      }
diff --combined libswscale/swscale.c
index 2f70d8ca35fdc8ef3f4b62d609caacdfde68585e,5d90250acf97972ebe70955f8f3418ce92997aa4..e06be55780a310a44b75130be8bc07782999c423
@@@ -1,20 -1,20 +1,20 @@@
  /*
   * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
   *
 - * This file is part of Libav.
 + * This file is part of FFmpeg.
   *
 - * Libav is free software; you can redistribute it and/or
 + * FFmpeg is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
 - * Libav is distributed in the hope that it will be useful,
 + * FFmpeg is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
 - * License along with Libav; if not, write to the Free Software
 + * License along with FFmpeg; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   */
  
@@@ -60,7 -60,6 +60,7 @@@ untested special converter
  #include "swscale.h"
  #include "swscale_internal.h"
  #include "rgb2rgb.h"
 +#include "libavutil/avassert.h"
  #include "libavutil/intreadwrite.h"
  #include "libavutil/cpu.h"
  #include "libavutil/avutil.h"
@@@ -68,6 -67,7 +68,6 @@@
  #include "libavutil/bswap.h"
  #include "libavutil/pixdesc.h"
  
 -#define DITHER1XBPP
  
  #define RGB2YUV_SHIFT 15
  #define BY ( (int)(0.114*219/255*(1<<RGB2YUV_SHIFT)+0.5))
@@@ -195,101 -195,6 +195,101 @@@ DECLARE_ALIGNED(8, const uint8_t, dithe
  DECLARE_ALIGNED(8, const uint8_t, ff_sws_pb_64)[8] =
  {  64, 64, 64, 64, 64, 64, 64, 64 };
  
 +DECLARE_ALIGNED(8, const uint8_t, dithers)[8][8][8]={
 +{
 +  {   0,  1,  0,  1,  0,  1,  0,  1,},
 +  {   1,  0,  1,  0,  1,  0,  1,  0,},
 +  {   0,  1,  0,  1,  0,  1,  0,  1,},
 +  {   1,  0,  1,  0,  1,  0,  1,  0,},
 +  {   0,  1,  0,  1,  0,  1,  0,  1,},
 +  {   1,  0,  1,  0,  1,  0,  1,  0,},
 +  {   0,  1,  0,  1,  0,  1,  0,  1,},
 +  {   1,  0,  1,  0,  1,  0,  1,  0,},
 +},{
 +  {   1,  2,  1,  2,  1,  2,  1,  2,},
 +  {   3,  0,  3,  0,  3,  0,  3,  0,},
 +  {   1,  2,  1,  2,  1,  2,  1,  2,},
 +  {   3,  0,  3,  0,  3,  0,  3,  0,},
 +  {   1,  2,  1,  2,  1,  2,  1,  2,},
 +  {   3,  0,  3,  0,  3,  0,  3,  0,},
 +  {   1,  2,  1,  2,  1,  2,  1,  2,},
 +  {   3,  0,  3,  0,  3,  0,  3,  0,},
 +},{
 +  {   2,  4,  3,  5,  2,  4,  3,  5,},
 +  {   6,  0,  7,  1,  6,  0,  7,  1,},
 +  {   3,  5,  2,  4,  3,  5,  2,  4,},
 +  {   7,  1,  6,  0,  7,  1,  6,  0,},
 +  {   2,  4,  3,  5,  2,  4,  3,  5,},
 +  {   6,  0,  7,  1,  6,  0,  7,  1,},
 +  {   3,  5,  2,  4,  3,  5,  2,  4,},
 +  {   7,  1,  6,  0,  7,  1,  6,  0,},
 +},{
 +  {   4,  8,  7, 11,  4,  8,  7, 11,},
 +  {  12,  0, 15,  3, 12,  0, 15,  3,},
 +  {   6, 10,  5,  9,  6, 10,  5,  9,},
 +  {  14,  2, 13,  1, 14,  2, 13,  1,},
 +  {   4,  8,  7, 11,  4,  8,  7, 11,},
 +  {  12,  0, 15,  3, 12,  0, 15,  3,},
 +  {   6, 10,  5,  9,  6, 10,  5,  9,},
 +  {  14,  2, 13,  1, 14,  2, 13,  1,},
 +},{
 +  {   9, 17, 15, 23,  8, 16, 14, 22,},
 +  {  25,  1, 31,  7, 24,  0, 30,  6,},
 +  {  13, 21, 11, 19, 12, 20, 10, 18,},
 +  {  29,  5, 27,  3, 28,  4, 26,  2,},
 +  {   8, 16, 14, 22,  9, 17, 15, 23,},
 +  {  24,  0, 30,  6, 25,  1, 31,  7,},
 +  {  12, 20, 10, 18, 13, 21, 11, 19,},
 +  {  28,  4, 26,  2, 29,  5, 27,  3,},
 +},{
 +  {  18, 34, 30, 46, 17, 33, 29, 45,},
 +  {  50,  2, 62, 14, 49,  1, 61, 13,},
 +  {  26, 42, 22, 38, 25, 41, 21, 37,},
 +  {  58, 10, 54,  6, 57,  9, 53,  5,},
 +  {  16, 32, 28, 44, 19, 35, 31, 47,},
 +  {  48,  0, 60, 12, 51,  3, 63, 15,},
 +  {  24, 40, 20, 36, 27, 43, 23, 39,},
 +  {  56,  8, 52,  4, 59, 11, 55,  7,},
 +},{
 +  {  18, 34, 30, 46, 17, 33, 29, 45,},
 +  {  50,  2, 62, 14, 49,  1, 61, 13,},
 +  {  26, 42, 22, 38, 25, 41, 21, 37,},
 +  {  58, 10, 54,  6, 57,  9, 53,  5,},
 +  {  16, 32, 28, 44, 19, 35, 31, 47,},
 +  {  48,  0, 60, 12, 51,  3, 63, 15,},
 +  {  24, 40, 20, 36, 27, 43, 23, 39,},
 +  {  56,  8, 52,  4, 59, 11, 55,  7,},
 +},{
 +  {  36, 68, 60, 92, 34, 66, 58, 90,},
 +  { 100,  4,124, 28, 98,  2,122, 26,},
 +  {  52, 84, 44, 76, 50, 82, 42, 74,},
 +  { 116, 20,108, 12,114, 18,106, 10,},
 +  {  32, 64, 56, 88, 38, 70, 62, 94,},
 +  {  96,  0,120, 24,102,  6,126, 30,},
 +  {  48, 80, 40, 72, 54, 86, 46, 78,},
 +  { 112, 16,104,  8,118, 22,110, 14,},
 +}};
 +
 +static const uint8_t flat64[8]={64,64,64,64,64,64,64,64};
 +
 +const uint16_t dither_scale[15][16]={
 +{    2,    3,    3,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,},
 +{    2,    3,    7,    7,   13,   13,   25,   25,   25,   25,   25,   25,   25,   25,   25,   25,},
 +{    3,    3,    4,   15,   15,   29,   57,   57,   57,  113,  113,  113,  113,  113,  113,  113,},
 +{    3,    4,    4,    5,   31,   31,   61,  121,  241,  241,  241,  241,  481,  481,  481,  481,},
 +{    3,    4,    5,    5,    6,   63,   63,  125,  249,  497,  993,  993,  993,  993,  993, 1985,},
 +{    3,    5,    6,    6,    6,    7,  127,  127,  253,  505, 1009, 2017, 4033, 4033, 4033, 4033,},
 +{    3,    5,    6,    7,    7,    7,    8,  255,  255,  509, 1017, 2033, 4065, 8129,16257,16257,},
 +{    3,    5,    6,    8,    8,    8,    8,    9,  511,  511, 1021, 2041, 4081, 8161,16321,32641,},
 +{    3,    5,    7,    8,    9,    9,    9,    9,   10, 1023, 1023, 2045, 4089, 8177,16353,32705,},
 +{    3,    5,    7,    8,   10,   10,   10,   10,   10,   11, 2047, 2047, 4093, 8185,16369,32737,},
 +{    3,    5,    7,    8,   10,   11,   11,   11,   11,   11,   12, 4095, 4095, 8189,16377,32753,},
 +{    3,    5,    7,    9,   10,   12,   12,   12,   12,   12,   12,   13, 8191, 8191,16381,32761,},
 +{    3,    5,    7,    9,   10,   12,   13,   13,   13,   13,   13,   13,   14,16383,16383,32765,},
 +{    3,    5,    7,    9,   10,   12,   14,   14,   14,   14,   14,   14,   14,   15,32767,32767,},
 +{    3,    5,    7,    9,   11,   12,   14,   15,   15,   15,   15,   15,   15,   15,   16,65535,},
 +};
 +
  static av_always_inline void
  yuv2yuvX16_c_template(const int16_t *lumFilter, const int32_t **lumSrc,
                        int lumFilterSize, const int16_t *chrFilter,
  {
      //FIXME Optimize (just quickly written not optimized..)
      int i;
 +    int dword= output_bits == 16;
      uint16_t *yDest = dest[0], *uDest = dest[1], *vDest = dest[2],
               *aDest = CONFIG_SWSCALE_ALPHA ? dest[3] : NULL;
 -    int shift = 15 + 16 - output_bits - 1;
 +    int shift = 11 + 4*dword + 16 - output_bits - 1;
  
  #define output_pixel(pos, val) \
      if (big_endian) { \
          AV_WL16(pos, av_clip_uint16(val >> shift)); \
      }
      for (i = 0; i < dstW; i++) {
 -        int val = 1 << (30-output_bits - 1);
 +        int val = 1 << (26-output_bits + 4*dword - 1);
          int j;
  
          for (j = 0; j < lumFilterSize; j++)
 -            val += (lumSrc[j][i] * lumFilter[j]) >> 1;
 +            val += ((dword ? lumSrc[j][i] : ((int16_t**)lumSrc)[j][i]) * lumFilter[j])>>1;
  
          output_pixel(&yDest[i], val);
      }
  
      if (uDest) {
          for (i = 0; i < chrDstW; i++) {
 -            int u = 1 << (30-output_bits - 1);
 -            int v = 1 << (30-output_bits - 1);
 +            int u = 1 << (26-output_bits + 4*dword - 1);
 +            int v = 1 << (26-output_bits + 4*dword - 1);
              int j;
  
              for (j = 0; j < chrFilterSize; j++) {
 -                u += (chrUSrc[j][i] * chrFilter[j]) >> 1;
 -                v += (chrVSrc[j][i] * chrFilter[j]) >> 1;
 +                u += ((dword ? chrUSrc[j][i] : ((int16_t**)chrUSrc)[j][i]) * chrFilter[j]) >> 1;
 +                v += ((dword ? chrVSrc[j][i] : ((int16_t**)chrVSrc)[j][i]) * chrFilter[j]) >> 1;
              }
  
              output_pixel(&uDest[i], u);
  
      if (CONFIG_SWSCALE_ALPHA && aDest) {
          for (i = 0; i < dstW; i++) {
 -            int val = 1 << (30-output_bits - 1);
 +            int val = 1 << (26-output_bits + 4*dword - 1);
              int j;
  
              for (j = 0; j < lumFilterSize; j++)
 -                val += (alpSrc[j][i] * lumFilter[j]) >> 1;
 +                val += ((dword ? alpSrc[j][i] : ((int16_t**)alpSrc)[j][i]) * lumFilter[j]) >> 1;
  
              output_pixel(&aDest[i], val);
          }
@@@ -363,7 -267,7 +363,7 @@@ yuv2yuvX10_c_template(const int16_t *lu
      int i;
      uint16_t *yDest = dest[0], *uDest = dest[1], *vDest = dest[2],
               *aDest = CONFIG_SWSCALE_ALPHA ? dest[3] : NULL;
-     int shift = 11 + 16 - output_bits - 1;
+     int shift = 11 + 16 - output_bits;
  
  #define output_pixel(pos, val) \
      if (big_endian) { \
          AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits)); \
      }
      for (i = 0; i < dstW; i++) {
-         int val = 1 << (26-output_bits - 1);
+         int val = 1 << (26-output_bits);
          int j;
  
          for (j = 0; j < lumFilterSize; j++)
-             val += (lumSrc[j][i] * lumFilter[j]) >> 1;
+             val += lumSrc[j][i] * lumFilter[j];
  
          output_pixel(&yDest[i], val);
      }
  
      if (uDest) {
          for (i = 0; i < chrDstW; i++) {
-             int u = 1 << (26-output_bits - 1);
-             int v = 1 << (26-output_bits - 1);
+             int u = 1 << (26-output_bits);
+             int v = 1 << (26-output_bits);
              int j;
  
              for (j = 0; j < chrFilterSize; j++) {
-                 u += (chrUSrc[j][i] * chrFilter[j]) >> 1;
-                 v += (chrVSrc[j][i] * chrFilter[j]) >> 1;
+                 u += chrUSrc[j][i] * chrFilter[j];
+                 v += chrVSrc[j][i] * chrFilter[j];
              }
  
              output_pixel(&uDest[i], u);
  
      if (CONFIG_SWSCALE_ALPHA && aDest) {
          for (i = 0; i < dstW; i++) {
-             int val = 1 << (26-output_bits - 1);
+             int val = 1 << (26-output_bits);
              int j;
  
              for (j = 0; j < lumFilterSize; j++)
-                 val += (alpSrc[j][i] * lumFilter[j]) >> 1;
+                 val += alpSrc[j][i] * lumFilter[j];
  
              output_pixel(&aDest[i], val);
          }
@@@ -631,8 -535,8 +631,8 @@@ yuv2gray16_1_c_template(SwsContext *c, 
      int i;
  
      for (i = 0; i < (dstW >> 1); i++) {
 -        int Y1 = buf0[i * 2    ] << 1;
 -        int Y2 = buf0[i * 2 + 1] << 1;
 +        int Y1 = (buf0[i * 2    ]+4)>>3;
 +        int Y2 = (buf0[i * 2 + 1]+4)>>3;
  
          output_pixel(&dest[i * 2 + 0], Y1);
          output_pixel(&dest[i * 2 + 1], Y2);
@@@ -1080,8 -984,8 +1080,8 @@@ yuv2rgb48_1_c_template(SwsContext *c, c
          for (i = 0; i < (dstW >> 1); i++) {
              int Y1 = (buf0[i * 2]    ) >> 2;
              int Y2 = (buf0[i * 2 + 1]) >> 2;
 -            int U  = (ubuf0[i] + ubuf1[i] + (-128 << 11)) >> 3;
 -            int V  = (vbuf0[i] + vbuf1[i] + (-128 << 11)) >> 3;
 +            int U  = (ubuf0[i] + ubuf1[i] + (-128 << 12)) >> 3;
 +            int V  = (vbuf0[i] + vbuf1[i] + (-128 << 12)) >> 3;
              int R, G, B;
  
              Y1 -= c->yuv2rgb_y_offset;
@@@ -1152,7 -1056,6 +1152,7 @@@ yuv2rgb_write(uint8_t *_dest, int i, in
  
  #define r_b ((target == PIX_FMT_RGB24) ? r : b)
  #define b_r ((target == PIX_FMT_RGB24) ? b : r)
 +
          dest[i * 6 + 0] = r_b[Y1];
          dest[i * 6 + 1] =   g[Y1];
          dest[i * 6 + 2] = b_r[Y1];
@@@ -1443,9 -1346,9 +1443,9 @@@ yuv2rgb_full_X_c_template(SwsContext *c
  
      for (i = 0; i < dstW; i++) {
          int j;
 -        int Y = 0;
 -        int U = -128 << 19;
 -        int V = -128 << 19;
 +        int Y = 1<<9;
 +        int U = (1<<9)-(128 << 19);
 +        int V = (1<<9)-(128 << 19);
          int av_unused A;
          int R, G, B;
  
          U >>= 10;
          V >>= 10;
          if (hasAlpha) {
 -            A = 1 << 21;
 +            A = 1 << 18;
              for (j = 0; j < lumFilterSize; j++) {
                  A += alpSrc[j][i] * lumFilter[j];
              }
              dest[1] = B >> 22;
              dest[2] = G >> 22;
              dest[3] = R >> 22;
 -            dest += 4;
              break;
          case PIX_FMT_BGR24:
              dest[0] = B >> 22;
@@@ -1648,14 -1552,14 +1648,14 @@@ rgb48funcs(bgr, BE, PIX_FMT_BGR48BE)
                          (isBE(origin) ? AV_RB16(&src[(i)*2]) : AV_RL16(&src[(i)*2])))
  
  static av_always_inline void
 -rgb16_32ToY_c_template(uint8_t *dst, const uint8_t *src,
 +rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src,
                         int width, enum PixelFormat origin,
                         int shr,   int shg,   int shb, int shp,
                         int maskr, int maskg, int maskb,
                         int rsh,   int gsh,   int bsh, int S)
  {
      const int ry = RY << rsh, gy = GY << gsh, by = BY << bsh,
 -              rnd = 33 << (S - 1);
 +              rnd = (32<<((S)-1)) + (1<<(S-7));
      int i;
  
      for (i = 0; i < width; i++) {
          int g = (px & maskg) >> shg;
          int r = (px & maskr) >> shr;
  
 -        dst[i] = (ry * r + gy * g + by * b + rnd) >> S;
 +        dst[i] = (ry * r + gy * g + by * b + rnd) >> ((S)-6);
      }
  }
  
  static av_always_inline void
 -rgb16_32ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
 +rgb16_32ToUV_c_template(int16_t *dstU, int16_t *dstV,
                          const uint8_t *src, int width,
                          enum PixelFormat origin,
                          int shr,   int shg,   int shb, int shp,
  {
      const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
                rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
 -              rnd = 257 << (S - 1);
 +              rnd = (256<<((S)-1)) + (1<<(S-7));
      int i;
  
      for (i = 0; i < width; i++) {
          int g = (px & maskg) >> shg;
          int r = (px & maskr) >> shr;
  
 -        dstU[i] = (ru * r + gu * g + bu * b + rnd) >> S;
 -        dstV[i] = (rv * r + gv * g + bv * b + rnd) >> S;
 +        dstU[i] = (ru * r + gu * g + bu * b + rnd) >> ((S)-6);
 +        dstV[i] = (rv * r + gv * g + bv * b + rnd) >> ((S)-6);
      }
  }
  
  static av_always_inline void
 -rgb16_32ToUV_half_c_template(uint8_t *dstU, uint8_t *dstV,
 +rgb16_32ToUV_half_c_template(int16_t *dstU, int16_t *dstV,
                               const uint8_t *src, int width,
                               enum PixelFormat origin,
                               int shr,   int shg,   int shb, int shp,
  {
      const int ru = RU << rsh, gu = GU << gsh, bu = BU << bsh,
                rv = RV << rsh, gv = GV << gsh, bv = BV << bsh,
 -              rnd = 257 << S, maskgx = ~(maskr | maskb);
 +              rnd = (256U<<(S)) + (1<<(S-6)), maskgx = ~(maskr | maskb);
      int i;
  
      maskr |= maskr << 1; maskb |= maskb << 1; maskg |= maskg << 1;
          }
          r = (rb & maskr) >> shr;
  
 -        dstU[i] = (ru * r + gu * g + bu * b + rnd) >> (S + 1);
 -        dstV[i] = (rv * r + gv * g + bv * b + rnd) >> (S + 1);
 +        dstU[i] = (ru * r + gu * g + bu * b + (unsigned)rnd) >> ((S)-6+1);
 +        dstV[i] = (rv * r + gv * g + bv * b + (unsigned)rnd) >> ((S)-6+1);
      }
  }
  
  static void name ## ToY_c(uint8_t *dst, const uint8_t *src, \
                            int width, uint32_t *unused) \
  { \
 -    rgb16_32ToY_c_template(dst, src, width, fmt, shr, shg, shb, shp, \
 +    rgb16_32ToY_c_template((int16_t*)dst, src, width, fmt, \
 +                           shr, shg, shb, shp, \
                             maskr, maskg, maskb, rsh, gsh, bsh, S); \
  } \
   \
@@@ -1742,8 -1645,7 +1742,8 @@@ static void name ## ToUV_c(uint8_t *dst
                             const uint8_t *src, const uint8_t *dummy, \
                             int width, uint32_t *unused) \
  { \
 -    rgb16_32ToUV_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
 +    rgb16_32ToUV_c_template((int16_t*)dstU, (int16_t*)dstV, src, width, fmt,  \
 +                            shr, shg, shb, shp, \
                              maskr, maskg, maskb, rsh, gsh, bsh, S); \
  } \
   \
@@@ -1751,8 -1653,7 +1751,8 @@@ static void name ## ToUV_half_c(uint8_
                                  const uint8_t *src, const uint8_t *dummy, \
                                  int width, uint32_t *unused) \
  { \
 -    rgb16_32ToUV_half_c_template(dstU, dstV, src, width, fmt, shr, shg, shb, shp, \
 +    rgb16_32ToUV_half_c_template((int16_t*)dstU, (int16_t*)dstV, src, width, fmt, \
 +                                 shr, shg, shb, shp, \
                                   maskr, maskg, maskb, rsh, gsh, bsh, S); \
  }
  
@@@ -1769,83 -1670,65 +1769,83 @@@ rgb16_32_wrapper(PIX_FMT_BGR555BE, bgr1
  rgb16_32_wrapper(PIX_FMT_RGB565BE, rgb16be, 0, 0,  0, 0,   0xF800, 0x07E0,   0x001F,  0, 5, 11, RGB2YUV_SHIFT+8);
  rgb16_32_wrapper(PIX_FMT_RGB555BE, rgb15be, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT+7);
  
 -static void abgrToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
 +static void abgrToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
  {
      int i;
      for (i=0; i<width; i++) {
 -        dst[i]= src[4*i];
 +        dst[i]= src[4*i]<<6;
      }
  }
  
 -static void rgbaToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
 +static void rgbaToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
  {
      int i;
      for (i=0; i<width; i++) {
 -        dst[i]= src[4*i+3];
 +        dst[i]= src[4*i+3]<<6;
      }
  }
  
 -static void palToY_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *pal)
 +static void palToA_c(int16_t *dst, const uint8_t *src, int width, uint32_t *pal)
  {
      int i;
      for (i=0; i<width; i++) {
          int d= src[i];
  
 -        dst[i]= pal[d] & 0xFF;
 +        dst[i]= (pal[d] >> 24)<<6;
      }
  }
  
 -static void palToUV_c(uint8_t *dstU, uint8_t *dstV,
 -                      const uint8_t *src1, const uint8_t *src2,
 -                      int width, uint32_t *pal)
 +static void palToY_c(int16_t *dst, const uint8_t *src, long width, uint32_t *pal)
 +{
 +    int i;
 +    for (i=0; i<width; i++) {
 +        int d= src[i];
 +
 +        dst[i]= (pal[d] & 0xFF)<<6;
 +    }
 +}
 +
 +static void palToUV_c(uint16_t *dstU, int16_t *dstV,
 +                           const uint8_t *src1, const uint8_t *src2,
 +                           int width, uint32_t *pal)
  {
      int i;
      assert(src1 == src2);
      for (i=0; i<width; i++) {
          int p= pal[src1[i]];
  
 -        dstU[i]= p>>8;
 -        dstV[i]= p>>16;
 +        dstU[i]= (uint8_t)(p>> 8)<<6;
 +        dstV[i]= (uint8_t)(p>>16)<<6;
      }
  }
  
 -static void monowhite2Y_c(uint8_t *dst, const uint8_t *src,
 -                          int width, uint32_t *unused)
 +static void monowhite2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
  {
      int i, j;
      for (i=0; i<width/8; i++) {
          int d= ~src[i];
          for(j=0; j<8; j++)
 -            dst[8*i+j]= ((d>>(7-j))&1)*255;
 +            dst[8*i+j]= ((d>>(7-j))&1)*16383;
 +    }
 +    if(width&7){
 +        int d= ~src[i];
 +        for(j=0; j<(width&7); j++)
 +            dst[8*i+j]= ((d>>(7-j))&1)*16383;
      }
  }
  
 -static void monoblack2Y_c(uint8_t *dst, const uint8_t *src,
 -                          int width, uint32_t *unused)
 +static void monoblack2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused)
  {
      int i, j;
      for (i=0; i<width/8; i++) {
          int d= src[i];
          for(j=0; j<8; j++)
 -            dst[8*i+j]= ((d>>(7-j))&1)*255;
 +            dst[8*i+j]= ((d>>(7-j))&1)*16383;
 +    }
 +    if(width&7){
 +        int d= src[i];
 +        for(j=0; j<(width&7); j++)
 +            dst[8*i+j]= ((d>>(7-j))&1)*16383;
      }
  }
  
@@@ -1940,7 -1823,7 +1940,7 @@@ static void nv21ToUV_c(uint8_t *dstU, u
  
  #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
  
 -static void bgr24ToY_c(uint8_t *dst, const uint8_t *src,
 +static void bgr24ToY_c(int16_t *dst, const uint8_t *src,
                         int width, uint32_t *unused)
  {
      int i;
          int g= src[i*3+1];
          int r= src[i*3+2];
  
 -        dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
 +        dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
      }
  }
  
 -static void bgr24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
 +static void bgr24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
                          const uint8_t *src2, int width, uint32_t *unused)
  {
      int i;
          int g= src1[3*i + 1];
          int r= src1[3*i + 2];
  
 -        dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
 -        dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
 +        dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
 +        dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
      }
      assert(src1 == src2);
  }
  
 -static void bgr24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
 +static void bgr24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
                               const uint8_t *src2, int width, uint32_t *unused)
  {
      int i;
          int g= src1[6*i + 1] + src1[6*i + 4];
          int r= src1[6*i + 2] + src1[6*i + 5];
  
 -        dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
 -        dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
 +        dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
 +        dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
      }
      assert(src1 == src2);
  }
  
 -static void rgb24ToY_c(uint8_t *dst, const uint8_t *src, int width,
 +static void rgb24ToY_c(int16_t *dst, const uint8_t *src, int width,
                         uint32_t *unused)
  {
      int i;
          int g= src[i*3+1];
          int b= src[i*3+2];
  
 -        dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT);
 +        dst[i]= ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
      }
  }
  
 -static void rgb24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
 +static void rgb24ToUV_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
                          const uint8_t *src2, int width, uint32_t *unused)
  {
      int i;
          int g= src1[3*i + 1];
          int b= src1[3*i + 2];
  
 -        dstU[i]= (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
 -        dstV[i]= (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1)))>>RGB2YUV_SHIFT;
 +        dstU[i]= (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
 +        dstV[i]= (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
      }
  }
  
 -static void rgb24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
 -                             const uint8_t *src2, int width, uint32_t *unused)
 +static void rgb24ToUV_half_c(int16_t *dstU, int16_t *dstV, const uint8_t *src1,
 +                                    const uint8_t *src2, int width, uint32_t *unused)
  {
      int i;
      assert(src1==src2);
          int g= src1[6*i + 1] + src1[6*i + 4];
          int b= src1[6*i + 2] + src1[6*i + 5];
  
 -        dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
 -        dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT))>>(RGB2YUV_SHIFT+1);
 +        dstU[i]= (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
 +        dstV[i]= (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
      }
  }
  
@@@ -2036,9 -1919,6 +2036,9 @@@ static void hScale16To19_c(SwsContext *
      int bits = av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
      int sh = bits - 4;
  
 +    if((isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8) && av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1<15)
 +        sh= 9;
 +
      for (i = 0; i < dstW; i++) {
          int j;
          int srcPos = filterPos[i];
@@@ -2060,9 -1940,6 +2060,9 @@@ static void hScale16To15_c(SwsContext *
      const uint16_t *src = (const uint16_t *) _src;
      int sh = av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
  
 +    if(sh<15)
 +        sh= isAnyRGB(c->srcFormat) || c->srcFormat==PIX_FMT_PAL8 ? 13 : av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1;
 +
      for (i = 0; i < dstW; i++) {
          int j;
          int srcPos = filterPos[i];
@@@ -2177,7 -2054,7 +2177,7 @@@ static void lumRangeFromJpeg16_c(int16_
      int i;
      int32_t *dst = (int32_t *) _dst;
      for (i = 0; i < width; i++)
 -        dst[i] = (dst[i]*14071 + (33561947<<4))>>14;
 +        dst[i] = (dst[i]*(14071/4) + (33561947<<4)/4)>>12;
  }
  
  static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
          dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;
          xpos+=xInc;
      }
 +    for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
 +        dst[i] = src[srcW-1]*128;
  }
  
  // *** horizontal scale Y line to temp buffer
@@@ -2234,10 -2109,6 +2234,10 @@@ static void hcscale_fast_c(SwsContext *
          dst2[i]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);
          xpos+=xInc;
      }
 +    for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {
 +        dst1[i] = src1[srcW-1]*128;
 +        dst2[i] = src2[srcW-1]*128;
 +    }
  }
  
  static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth,
                                       uint8_t *formatConvBuffer, uint32_t *pal)
  {
      if (c->chrToYV12) {
 -        uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW * FFALIGN(c->srcBpc, 8) >> 3, 16);
 +        uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW*2+78, 16);
          c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
          src1= formatConvBuffer;
          src2= buf2;
@@@ -2351,10 -2222,7 +2351,10 @@@ find_c_packed_planar_out_funcs(SwsConte
              *yuv2packedX = yuv2bgr24_full_X_c;
              break;
          }
 +        if(!*yuv2packedX)
 +            goto YUV_PACKED;
      } else {
 +        YUV_PACKED:
          switch (dstFormat) {
          case PIX_FMT_GRAY16BE:
              *yuv2packed1 = yuv2gray16BE_1_c;
@@@ -2547,13 -2415,12 +2547,13 @@@ static int swScale(SwsContext *c, cons
      const int chrSrcSliceH= -((-srcSliceH) >> c->chrSrcVSubSample);
      int lastDstY;
      uint32_t *pal=c->pal_yuv;
 +
 +    int should_dither= isNBPS(c->srcFormat) || is16BPS(c->srcFormat);
      yuv2planar1_fn yuv2yuv1 = c->yuv2yuv1;
      yuv2planarX_fn yuv2yuvX = c->yuv2yuvX;
      yuv2packed1_fn yuv2packed1 = c->yuv2packed1;
      yuv2packed2_fn yuv2packed2 = c->yuv2packed2;
      yuv2packedX_fn yuv2packedX = c->yuv2packedX;
 -    int should_dither = is9_OR_10BPS(c->srcFormat) || is16BPS(c->srcFormat);
  
      /* vars which will change and which we need to store back in the context */
      int dstY= c->dstY;
              const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
              const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
              const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
 +
              if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
                  const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
                  if ((dstY&chrSkipMask) || isGray(dstFormat))
@@@ -2798,8 -2664,8 +2798,8 @@@ static av_cold void sws_init_swScale_c(
          case PIX_FMT_YUV444P9LE:
          case PIX_FMT_YUV420P9LE:
          case PIX_FMT_YUV422P10LE:
 -        case PIX_FMT_YUV444P10LE:
          case PIX_FMT_YUV420P10LE:
 +        case PIX_FMT_YUV444P10LE:
          case PIX_FMT_YUV420P16LE:
          case PIX_FMT_YUV422P16LE:
          case PIX_FMT_YUV444P16LE: c->chrToYV12 = bswap16UV_c; break;
  #if HAVE_BIGENDIAN
      case PIX_FMT_YUV444P9LE:
      case PIX_FMT_YUV420P9LE:
 -    case PIX_FMT_YUV444P10LE:
      case PIX_FMT_YUV422P10LE:
      case PIX_FMT_YUV420P10LE:
 +    case PIX_FMT_YUV444P10LE:
      case PIX_FMT_YUV420P16LE:
      case PIX_FMT_YUV422P16LE:
      case PIX_FMT_YUV444P16LE:
          case PIX_FMT_ABGR:
          case PIX_FMT_ARGB:  c->alpToYV12 = abgrToA_c; break;
          case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
 +        case PIX_FMT_PAL8 : c->alpToYV12 = palToA_c; break;
          }
      }
  
 +
      if (c->srcBpc == 8) {
          if (c->dstBpc <= 10) {
              c->hyScale = c->hcScale = hScale8To15_c;
index 281c8eb7ca62f33e7b0e31f0dc77f14066c2b642,27636284a05c85cbf329c479073a350de2284513..0210ca1dfe32a19f9b8b3fa144434d55d09bd70f
@@@ -1,45 -1,45 +1,45 @@@
 -abgr                d894cb97f6c80eb21bdbe8a4eea62d86
 -argb                54346f2b2eef10919e0f247241df3b24
 -bgr24               570f8d6b51a838aed022ef67535f6bdc
 +abgr                cff82561a074874027ac1cc896fd2730
 +argb                756dd1eaa5baca2238ce23dbdc452684
 +bgr24               e44192347a45586c6c157e3059610cd1
  bgr48be             390d3058a12a99c2b153ed7922508bea
  bgr48le             39fe06feb4ec1d9730dccc04a0cfac4c
  bgr4_byte           ee1d35a7baf8e9016891929a2f565c0b
 -bgr555be            de8901c1358834fddea060fcb3a67beb
 -bgr555le            36b745067197f9ca8c1731cac51329c9
 -bgr565be            922a2503767036ae9536f4f7823c04ee
 -bgr565le            3a514a298c6161a071ddf9963c06509d
 +bgr555be            6a2d335856db12e3ea72173d71610e21
 +bgr555le            41e3e0961478dc634bf68a7bbd670cc9
 +bgr565be            21077a3744c889b97032414b11232933
 +bgr565le            614897eaeb422bd9a972f8ee51909be5
  bgr8                7f007fa6c153a16e808a9c51605a4016
 -bgra                a5e7040f9a80cccd65e5acf2ca09ace5
 +bgra                01cfdda1f72fcabb6c46424e27f8c519
  gray                d7786a7d9d99ac74230cc045cab5632c
 -gray16be            b554d6c1cc8da23967445be4dd3e4a86
 -gray16le            715a33aa1c19cb26b14f5cc000e7a3d1
 -monob               88c4c050758e64d120f50c7eff694381
 -monow               d31772ebaa877fc2a78565937f7f9673
 +gray16be            a8fc0d7fea36407b5c319e3e736c7127
 +gray16le            495c89186178308ef171d385bbd8bd70
 +monob               cb62f31b701c6e987b574974d1b31e32
 +monow               fd5d417ab7728acddffc06870661df61
  nv12                4676d59db43d657dc12841f6bc3ab452
  nv21                69c699510ff1fb777b118ebee1002f14
 -rgb24               514692e28e8ff6860e415ce4fcf6eb8c
 +rgb24               13ff53ebeab74dc05492836f1cfbd2c1
  rgb48be             8fac63787a711886030f8e056872b488
  rgb48le             ab92f2763a2eb264c3870cc758f97149
  rgb4_byte           d81ffd3add95842a618eec81024f0b5c
 -rgb555be            4607309f9f217d51cbb53d13b84b4537
 -rgb555le            a350ef1dc2c9688ed49e7ba018843795
 -rgb565be            678ce231c4ea13629c1353b1df4ffbef
 -rgb565le            6f4bb711238baa762d73305213f8d035
 +rgb555be            491dc49ff83258ffe415289bdcfb50b2
 +rgb555le            bd698d86c03170c4a16607c0fd1f750f
 +rgb565be            35682c17c85f307147041f23ac8092aa
 +rgb565le            bfa0c639d80c3c03fd0c9e5f34296a5e
  rgb8                091d0170b354ef0e97312b95feb5483f
 -rgba                a3d362f222098a00e63867f612018659
 +rgba                16873e3ac914e76116629a5ff8940ac4
  uyvy422             314bd486277111a95d9369b944fa0400
  yuv410p             7df8f6d69b56a8dcb6c7ee908e5018b5
  yuv411p             1143e7c5cc28fe0922b051b17733bc4c
  yuv420p             fdad2d8df8985e3d17e73c71f713cb14
- yuv420p10be         dfa4d57bbc0e1a81f86a3895ab4feac0
- yuv420p10le         af898206e757b0fca844a336f71d0091
 -yuv420p10be         c143e77e97d2f7d62c3b518857ba9f9b
 -yuv420p10le         72d90eccf5c34691ff057dafb7447aa2
 -yuv420p16be         9688e33e03b8c8275ab2fb1df0f06bee
 -yuv420p16le         cba8b390ad5e7b8678e419b8ce79c008
 -yuv420p9be          bb87fddca65d1742412c8d2b1caf96c6
 -yuv420p9le          828eec50014a41258a5423c1fe56ac97
++yuv420p10be         6d335e75b553da590135cf8bb999610c
++yuv420p10le         d510ddbabefd03ef39ec943fcb51b709
 +yuv420p16be         2a75942af24fbdc1fdfe189c6e7bf589
 +yuv420p16le         c4264d92a7c273967a778f4f5daddbe3
- yuv420p9be          046091d96f2a78e224036f203d8c9601
- yuv420p9le          c9abfffee99fcf5fcbfc5adcda14e4b4
++yuv420p9be          ec4983b7a949c0472110a7a2c58e278a
++yuv420p9le          c136dce5913a722eee44ab72cff664b2
  yuv422p             918e37701ee7377d16a8a6c119c56a40
- yuv422p10be         35206fcd7e00ee582a8c366b37d57d1d
- yuv422p10le         396f930e2da02f149ab9dd5b781cbe8d
+ yuv422p10be         cea7ca6b0e66d6f29539885896c88603
+ yuv422p10le         a10c4a5837547716f13cd61918b145f9
  yuv422p16be         285993ee0c0f4f8e511ee46f93c5f38c
  yuv422p16le         61bfcee8e54465f760164f5a75d40b5e
  yuv440p             461503fdb9b90451020aa3b25ddf041c