]> git.sesse.net Git - ffmpeg/commitdiff
Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 9 Mar 2012 00:22:31 +0000 (01:22 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 9 Mar 2012 00:22:31 +0000 (01:22 +0100)
* qatar/master:
  ttadec: unbreak playback of matroska files
  vorbisdec: avoid invalid memory access
  Fix uninitialized reads on malformed ogg files.
  huffyuv: add padding to classic (v1) huffman tables.
  png: convert to bytestream2 API.
  dca: include libavutil/mathematics.h for possibly missing M_SQRT1_2
  avs: fix infinite loop on end-of-stream.
  tiffdec: Prevent illegal memory access caused by recycled pointers.
  rtpenc: Fix the AVRational used for av_rescale_q_rnd
  wma: fix off-by-one in array bounds check.

Conflicts:
libavcodec/huffyuv.c
libavcodec/pngdec.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/cavsdec.c
libavcodec/dca.c
libavcodec/huffyuv.c
libavcodec/pngdec.c
libavcodec/tiff.c
libavcodec/tta.c
libavcodec/vorbisdec.c
libavformat/oggdec.c
libavformat/rtpenc.c

diff --combined libavcodec/cavsdec.c
index b06bd53c00aa1e74dee2760c2fc3395d0e92ac73,e3201343be8f7a2669f864adcaa93a602d83813c..6e5539c2d7ff1408eafe2eff0229b521a711bc36
@@@ -2,20 -2,20 +2,20 @@@
   * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
   * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
   *
 - * 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
   */
  
@@@ -115,8 -115,7 +115,8 @@@ static inline int get_ue_code(GetBitCon
  static int decode_residual_block(AVSContext *h, GetBitContext *gb,
                                   const struct dec_2dvlc *r, int esc_golomb_order,
                                   int qp, uint8_t *dst, int stride) {
 -    int i, level_code, esc_code, level, run, mask;
 +    int i, esc_code, level, mask;
 +    unsigned int level_code, run;
      DCTELEM level_buf[65];
      uint8_t run_buf[65];
      DCTELEM *block = h->block;
          level_code = get_ue_code(gb,r->golomb_order);
          if(level_code >= ESCAPE_CODE) {
              run = ((level_code - ESCAPE_CODE) >> 1) + 1;
 +            if(run > 64)
 +                return -1;
              esc_code = get_ue_code(gb,esc_golomb_order);
              level = esc_code + (run > r->max_run ? 1 : r->level_add[run]);
              while(level > r->inc_limit)
                  r++;
              mask = -(level_code & 1);
              level = (level^mask) - mask;
 -        } else if (level_code >= 0) {
 +        } else {
              level = r->rltab[level_code][0];
              if(!level) //end of block signal
                  break;
              run   = r->rltab[level_code][1];
              r += r->rltab[level_code][2];
 -        } else {
 -            break;
          }
          level_buf[i] = level;
          run_buf[i] = run;
@@@ -166,7 -165,7 +166,7 @@@ static inline int decode_residual_inter
  
      /* get coded block pattern */
      int cbp= get_ue_golomb(&h->s.gb);
 -    if(cbp > 63){
 +    if(cbp > 63U){
          av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n");
          return -1;
      }
@@@ -226,7 -225,7 +226,7 @@@ static int decode_mb_i(AVSContext *h, i
      /* get coded block pattern */
      if(h->pic_type == AV_PICTURE_TYPE_I)
          cbp_code = get_ue_golomb(gb);
 -    if(cbp_code > 63){
 +    if(cbp_code > 63U){
          av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n");
          return -1;
      }
@@@ -657,6 -656,7 +657,7 @@@ static int cavs_decode_frame(AVCodecCon
          if (!s->low_delay && h->DPB[0].f.data[0]) {
              *data_size = sizeof(AVPicture);
              *picture = h->DPB[0].f;
+             memset(&h->DPB[0], 0, sizeof(h->DPB[0]));
          }
          return 0;
      }
diff --combined libavcodec/dca.c
index a37341af0c06e13dc62411aecd752cd3aa72aa0b,103f0588e3ef97759248b797129af1cb548de34f..d9fafbad01e3d8c81fc5bedeb930381f7b3569c1
@@@ -5,20 -5,20 +5,20 @@@
   * Copyright (C) 2006 Benjamin Larsson
   * Copyright (C) 2007 Konstantin Shishkov
   *
 - * 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
   */
  
@@@ -29,6 -29,7 +29,7 @@@
  #include "libavutil/common.h"
  #include "libavutil/intmath.h"
  #include "libavutil/intreadwrite.h"
+ #include "libavutil/mathematics.h"
  #include "libavutil/audioconvert.h"
  #include "avcodec.h"
  #include "dsputil.h"
@@@ -314,6 -315,7 +315,6 @@@ typedef struct 
  
      /* Primary audio coding header */
      int subframes;              ///< number of subframes
 -    int is_channels_set;        ///< check for if the channel number is already set
      int total_channels;         ///< number of channels including extensions
      int prim_channels;          ///< number of primary audio channels
      int subband_activity[DCA_PRIM_CHANNELS_MAX];    ///< subband activity count
@@@ -832,7 -834,6 +833,7 @@@ static int dca_subframe_header(DCAConte
  
      /* Low frequency effect data */
      if (!base_channel && s->lfe) {
 +        int quant7;
          /* LFE samples */
          int lfe_samples = 2 * s->lfe * (4 + block_index);
          int lfe_end_sample = 2 * s->lfe * (4 + block_index + s->subsubframes[s->current_subframe]);
          }
  
          /* Scale factor index */
 -        skip_bits(&s->gb, 1);
 -        s->lfe_scale_factor = scale_factor_quant7[get_bits(&s->gb, 7)];
 +        quant7 = get_bits(&s->gb, 8);
 +        if (quant7 > 127) {
 +            av_log_ask_for_sample(s->avctx, "LFEScaleIndex larger than 127\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +        s->lfe_scale_factor = scale_factor_quant7[quant7];
  
          /* Quantization step size * scale factor */
          lfe_scale = 0.035 * s->lfe_scale_factor;
@@@ -1419,11 -1416,11 +1420,11 @@@ static int dca_exss_parse_asset_header(
  {
      int header_pos = get_bits_count(&s->gb);
      int header_size;
 -    int channels;
 +    int channels = 0;
      int embedded_stereo = 0;
      int embedded_6ch    = 0;
      int drc_code_present;
 -    int extensions_mask;
 +    int av_uninit(extensions_mask);
      int i, j;
  
      if (get_bits_left(&s->gb) < 16)
@@@ -1828,19 -1825,25 +1829,19 @@@ static int dca_decode_frame(AVCodecCont
              s->output = DCA_STEREO;
              avctx->channel_layout = AV_CH_LAYOUT_STEREO;
          }
 +        else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) {
 +            static const int8_t dca_channel_order_native[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
 +            s->channel_order_tab = dca_channel_order_native;
 +        }
      } else {
          av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode);
          return AVERROR_INVALIDDATA;
      }
  
 -
 -    /* There is nothing that prevents a dts frame to change channel configuration
 -       but Libav doesn't support that so only set the channels if it is previously
 -       unset. Ideally during the first probe for channels the crc should be checked
 -       and only set avctx->channels when the crc is ok. Right now the decoder could
 -       set the channels based on a broken first frame.*/
 -    if (s->is_channels_set == 0) {
 -        s->is_channels_set = 1;
 -        avctx->channels = channels;
 -    }
      if (avctx->channels != channels) {
 -        av_log(avctx, AV_LOG_ERROR, "DCA decoder does not support number of "
 -               "channels changing in stream. Skipping frame.\n");
 -        return AVERROR_PATCHWELCOME;
 +        if (avctx->channels)
 +            av_log(avctx, AV_LOG_INFO, "Number of channels changed in DCA decoder (%d -> %d)\n", avctx->channels, channels);
 +        avctx->channels = channels;
      }
  
      /* get output buffer */
diff --combined libavcodec/huffyuv.c
index ff52eaac733f669330e31b19facc3301b4c58adf,278948d195c91f08a9cb7199732d97b43b451839..81144a1c4234e3ed796a05fc060053753e76394e
@@@ -6,20 -6,20 +6,20 @@@
   * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
   * the algorithm used
   *
 - * 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
   */
  
@@@ -82,18 -82,18 +82,20 @@@ typedef struct HYuvContext
      DSPContext dsp;
  }HYuvContext;
  
- static const unsigned char classic_shift_luma[] = {
+ #define classic_shift_luma_table_size 42
+ static const unsigned char classic_shift_luma[classic_shift_luma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = {
    34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
    16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
 -  69,68, 0
 +  69,68, 0,
 +  0,0,0,0,0,0,0,0,
  };
  
- static const unsigned char classic_shift_chroma[] = {
+ #define classic_shift_chroma_table_size 59
+ static const unsigned char classic_shift_chroma[classic_shift_chroma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = {
    66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
    56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
 -  214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0
 +  214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0,
 +  0,0,0,0,0,0,0,0,
  };
  
  static const unsigned char classic_add_luma[256] = {
@@@ -154,55 -154,27 +156,55 @@@ static inline int sub_left_prediction(H
      }
  }
  
 -static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
 +static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue, int *alpha){
      int i;
 -    int r,g,b;
 +    int r,g,b,a;
      r= *red;
      g= *green;
      b= *blue;
 +    a= *alpha;
      for(i=0; i<FFMIN(w,4); i++){
          const int rt= src[i*4+R];
          const int gt= src[i*4+G];
          const int bt= src[i*4+B];
 +        const int at= src[i*4+A];
          dst[i*4+R]= rt - r;
          dst[i*4+G]= gt - g;
          dst[i*4+B]= bt - b;
 +        dst[i*4+A]= at - a;
          r = rt;
          g = gt;
          b = bt;
 +        a = at;
      }
      s->dsp.diff_bytes(dst+16, src+16, src+12, w*4-16);
      *red=   src[(w-1)*4+R];
      *green= src[(w-1)*4+G];
      *blue=  src[(w-1)*4+B];
 +    *alpha= src[(w-1)*4+A];
 +}
 +
 +static inline void sub_left_prediction_rgb24(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
 +    int i;
 +    int r,g,b;
 +    r= *red;
 +    g= *green;
 +    b= *blue;
 +    for(i=0; i<FFMIN(w,16); i++){
 +        const int rt= src[i*3+0];
 +        const int gt= src[i*3+1];
 +        const int bt= src[i*3+2];
 +        dst[i*3+0]= rt - r;
 +        dst[i*3+1]= gt - g;
 +        dst[i*3+2]= bt - b;
 +        r = rt;
 +        g = gt;
 +        b = bt;
 +    }
 +    s->dsp.diff_bytes(dst+48, src+48, src+48-3, w*3-48);
 +    *red=   src[(w-1)*3+0];
 +    *green= src[(w-1)*3+1];
 +    *blue=  src[(w-1)*3+2];
  }
  
  static int read_len_table(uint8_t *dst, GetBitContext *gb){
@@@ -396,10 -368,10 +398,10 @@@ static int read_old_huffman_tables(HYuv
      GetBitContext gb;
      int i;
  
-     init_get_bits(&gb, classic_shift_luma, (sizeof(classic_shift_luma)-8)*8);
+     init_get_bits(&gb, classic_shift_luma, classic_shift_luma_table_size*8);
      if(read_len_table(s->len[0], &gb)<0)
          return -1;
-     init_get_bits(&gb, classic_shift_chroma, (sizeof(classic_shift_chroma)-8)*8);
+     init_get_bits(&gb, classic_shift_chroma, classic_shift_chroma_table_size*8);
      if(read_len_table(s->len[1], &gb)<0)
          return -1;
  
@@@ -463,7 -435,6 +465,7 @@@ static av_cold int decode_init(AVCodecC
      memset(s->vlc, 0, 3*sizeof(VLC));
  
      avctx->coded_frame= &s->picture;
 +    avcodec_get_frame_defaults(&s->picture);
      s->interlaced= s->height > 288;
  
  s->bgr32=1;
@@@ -623,9 -594,6 +625,9 @@@ static av_cold int encode_init(AVCodecC
          s->bitstream_bpp= 16;
          break;
      case PIX_FMT_RGB32:
 +        s->bitstream_bpp= 32;
 +        break;
 +    case PIX_FMT_RGB24:
          s->bitstream_bpp= 24;
          break;
      default:
@@@ -912,29 -880,26 +914,29 @@@ static void decode_bgr_bitstream(HYuvCo
      }
  }
  
 -static int encode_bgr_bitstream(HYuvContext *s, int count){
 +static inline int encode_bgra_bitstream(HYuvContext *s, int count, int planes){
      int i;
  
 -    if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3*4*count){
 +    if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*planes*count){
          av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
          return -1;
      }
  
  #define LOAD3\
 -            int g= s->temp[0][4*i+G];\
 -            int b= (s->temp[0][4*i+B] - g) & 0xff;\
 -            int r= (s->temp[0][4*i+R] - g) & 0xff;
 +            int g= s->temp[0][planes==3 ? 3*i+1 : 4*i+G];\
 +            int b= (s->temp[0][planes==3 ? 3*i+2 : 4*i+B] - g) & 0xff;\
 +            int r= (s->temp[0][planes==3 ? 3*i+0 : 4*i+R] - g) & 0xff;\
 +            int a= s->temp[0][planes*i+A];
  #define STAT3\
              s->stats[0][b]++;\
              s->stats[1][g]++;\
 -            s->stats[2][r]++;
 +            s->stats[2][r]++;\
 +            if(planes==4) s->stats[2][a]++;
  #define WRITE3\
              put_bits(&s->pb, s->len[1][g], s->bits[1][g]);\
              put_bits(&s->pb, s->len[0][b], s->bits[0][b]);\
 -            put_bits(&s->pb, s->len[2][r], s->bits[2][r]);
 +            put_bits(&s->pb, s->len[2][r], s->bits[2][r]);\
 +            if(planes==4) put_bits(&s->pb, s->len[2][a], s->bits[2][a]);
  
      if((s->flags&CODEC_FLAG_PASS1) && (s->avctx->flags2&CODEC_FLAG2_NO_OUTPUT)){
          for(i=0; i<count; i++){
@@@ -1410,50 -1375,25 +1412,50 @@@ static int encode_frame(AVCodecContext 
          const int stride = -p->linesize[0];
          const int fake_stride = -fake_ystride;
          int y;
 -        int leftr, leftg, leftb;
 +        int leftr, leftg, leftb, lefta;
  
 +        put_bits(&s->pb, 8, lefta= data[A]);
          put_bits(&s->pb, 8, leftr= data[R]);
          put_bits(&s->pb, 8, leftg= data[G]);
          put_bits(&s->pb, 8, leftb= data[B]);
 -        put_bits(&s->pb, 8, 0);
  
 -        sub_left_prediction_bgr32(s, s->temp[0], data+4, width-1, &leftr, &leftg, &leftb);
 -        encode_bgr_bitstream(s, width-1);
 +        sub_left_prediction_bgr32(s, s->temp[0], data+4, width-1, &leftr, &leftg, &leftb, &lefta);
 +        encode_bgra_bitstream(s, width-1, 4);
  
          for(y=1; y<s->height; y++){
              uint8_t *dst = data + y*stride;
              if(s->predictor == PLANE && s->interlaced < y){
                  s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width*4);
 -                sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb);
 +                sub_left_prediction_bgr32(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb, &lefta);
 +            }else{
 +                sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb, &lefta);
 +            }
 +            encode_bgra_bitstream(s, width, 4);
 +        }
 +    }else if(avctx->pix_fmt == PIX_FMT_RGB24){
 +        uint8_t *data = p->data[0] + (height-1)*p->linesize[0];
 +        const int stride = -p->linesize[0];
 +        const int fake_stride = -fake_ystride;
 +        int y;
 +        int leftr, leftg, leftb;
 +
 +        put_bits(&s->pb, 8, leftr= data[0]);
 +        put_bits(&s->pb, 8, leftg= data[1]);
 +        put_bits(&s->pb, 8, leftb= data[2]);
 +        put_bits(&s->pb, 8, 0);
 +
 +        sub_left_prediction_rgb24(s, s->temp[0], data+3, width-1, &leftr, &leftg, &leftb);
 +        encode_bgra_bitstream(s, width-1, 3);
 +
 +        for(y=1; y<s->height; y++){
 +            uint8_t *dst = data + y*stride;
 +            if(s->predictor == PLANE && s->interlaced < y){
 +                s->dsp.diff_bytes(s->temp[1], dst, dst - fake_stride, width*3);
 +                sub_left_prediction_rgb24(s, s->temp[0], s->temp[1], width, &leftr, &leftg, &leftb);
              }else{
 -                sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb);
 +                sub_left_prediction_rgb24(s, s->temp[0], dst, width, &leftr, &leftg, &leftb);
              }
 -            encode_bgr_bitstream(s, width);
 +            encode_bgra_bitstream(s, width, 3);
          }
      }else{
          av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
@@@ -1546,7 -1486,7 +1548,7 @@@ AVCodec ff_huffyuv_encoder = 
      .init           = encode_init,
      .encode2        = encode_frame,
      .close          = encode_end,
 -    .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE},
 +    .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_NONE},
      .long_name = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
  };
  #endif
@@@ -1560,7 -1500,7 +1562,7 @@@ AVCodec ff_ffvhuff_encoder = 
      .init           = encode_init,
      .encode2        = encode_frame,
      .close          = encode_end,
 -    .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_RGB32, PIX_FMT_NONE},
 +    .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_NONE},
      .long_name = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
  };
  #endif
diff --combined libavcodec/pngdec.c
index 55df8b0a576ebb25e5e8793d3fa3d9515f2a7ea5,56bda7c300958be3c18b1d626894726782f304ae..398c48b41964adaa89ebe687cdc42e25e88761de
@@@ -2,25 -2,22 +2,25 @@@
   * PNG image format
   * Copyright (c) 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
   */
 +
 +//#define DEBUG
 +
  #include "libavutil/imgutils.h"
  #include "avcodec.h"
  #include "bytestream.h"
@@@ -28,7 -25,7 +28,7 @@@
  #include "pngdsp.h"
  
  /* TODO:
 - * - add 2, 4 and 16 bit depth support
 + * - add 16 bit depth support
   */
  
  #include <zlib.h>
@@@ -38,9 -35,7 +38,7 @@@
  typedef struct PNGDecContext {
      PNGDSPContext dsp;
  
-     const uint8_t *bytestream;
-     const uint8_t *bytestream_start;
-     const uint8_t *bytestream_end;
+     GetByteContext gb;
      AVFrame picture1, picture2;
      AVFrame *current_picture, *last_picture;
  
@@@ -71,7 -66,7 +69,7 @@@
  
  /* Mask to determine which y pixels can be written in a pass */
  static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
 -    0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55,
 +    0xff, 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
  };
  
  /* Mask to determine which pixels to overwrite while displaying */
@@@ -94,50 -89,35 +92,50 @@@ static void png_put_interlaced_row(uint
      dsp_mask = png_pass_dsp_mask[pass];
      switch(bits_per_pixel) {
      case 1:
 -        /* we must initialize the line to zero before writing to it */
 -        if (pass == 0)
 -            memset(dst, 0, (width + 7) >> 3);
          src_x = 0;
          for(x = 0; x < width; x++) {
              j = (x & 7);
              if ((dsp_mask << j) & 0x80) {
                  b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
 +                dst[x >> 3] &= 0xFF7F>>j;
                  dst[x >> 3] |= b << (7 - j);
              }
              if ((mask << j) & 0x80)
                  src_x++;
          }
          break;
 +    case 2:
 +        src_x = 0;
 +        for(x = 0; x < width; x++) {
 +            int j2 = 2*(x&3);
 +            j = (x & 7);
 +            if ((dsp_mask << j) & 0x80) {
 +                b = (src[src_x >> 2] >> (6 - 2*(src_x & 3))) & 3;
 +                dst[x >> 2] &= 0xFF3F>>j2;
 +                dst[x >> 2] |= b << (6 - j2);
 +            }
 +            if ((mask << j) & 0x80)
 +                src_x++;
 +        }
 +        break;
 +    case 4:
 +        src_x = 0;
 +        for(x = 0; x < width; x++) {
 +            int j2 = 4*(x&1);
 +            j = (x & 7);
 +            if ((dsp_mask << j) & 0x80) {
 +                b = (src[src_x >> 1] >> (4 - 4*(src_x & 1))) & 15;
 +                dst[x >> 1] &= 0xFF0F>>j2;
 +                dst[x >> 1] |= b << (4 - j2);
 +            }
 +            if ((mask << j) & 0x80)
 +                src_x++;
 +        }
 +        break;
      default:
          bpp = bits_per_pixel >> 3;
          d = dst;
          s = src;
 -        if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
 -            for(x = 0; x < width; x++) {
 -                j = x & 7;
 -                if ((dsp_mask << j) & 0x80) {
 -                    *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2];
 -                }
 -                d += bpp;
 -                if ((mask << j) & 0x80)
 -                    s += bpp;
 -            }
 -        } else {
              for(x = 0; x < width; x++) {
                  j = x & 7;
                  if ((dsp_mask << j) & 0x80) {
                  if ((mask << j) & 0x80)
                      s += bpp;
              }
 -        }
          break;
      }
  }
@@@ -249,7 -230,7 +247,7 @@@ static void png_filter_row(PNGDSPContex
              p = last[i];
              dst[i] = p + src[i];
          }
 -        if(bpp > 1 && size > 4) {
 +        if(bpp > 2 && size > 4) {
              // would write off the end of the array if we let it process the last pixel with bpp=3
              int w = bpp==4 ? size : size-3;
              dsp->add_paeth_prediction(dst+i, src+i, last+i, w-i, bpp);
      }
  }
  
 -static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *src, int width, int loco)
 -{
 -    int j;
 -    unsigned int r, g, b, a;
 -
 -    for(j = 0;j < width; j++) {
 -        r = src[0];
 -        g = src[1];
 -        b = src[2];
 -        a = src[3];
 -        if(loco) {
 -            r = (r+g)&0xff;
 -            b = (b+g)&0xff;
 -        }
 -        *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
 -        dst += 4;
 -        src += 4;
 -    }
 +/* This used to be called "deloco" in FFmpeg
 + * and is actually an inverse reversible colorspace transformation */
 +#define YUV2RGB(NAME, TYPE) \
 +static void deloco_ ## NAME(TYPE *dst, int size, int alpha) \
 +{ \
 +    int i; \
 +    for (i = 0; i < size; i += 3 + alpha) { \
 +        int g = dst [i+1]; \
 +        dst[i+0] += g; \
 +        dst[i+2] += g; \
 +    } \
  }
  
 -static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int loco)
 -{
 -    if(loco)
 -        convert_to_rgb32_loco(dst, src, width, 1);
 -    else
 -        convert_to_rgb32_loco(dst, src, width, 0);
 -}
 -
 -static void deloco_rgb24(uint8_t *dst, int size)
 -{
 -    int i;
 -    for(i=0; i<size; i+=3) {
 -        int g = dst[i+1];
 -        dst[i+0] += g;
 -        dst[i+2] += g;
 -    }
 -}
 +YUV2RGB(rgb8, uint8_t)
 +YUV2RGB(rgb16, uint16_t)
  
  /* process exactly one decompressed row */
  static void png_handle_row(PNGDecContext *s)
  
      if (!s->interlace_type) {
          ptr = s->image_buf + s->image_linesize * s->y;
 -        /* need to swap bytes correctly for RGB_ALPHA */
 -        if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
 -            png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
 -                           s->last_row, s->row_size, s->bpp);
 -            convert_to_rgb32(ptr, s->tmp_row, s->width, s->filter_type == PNG_FILTER_TYPE_LOCO);
 -            FFSWAP(uint8_t*, s->last_row, s->tmp_row);
 -        } else {
 -            /* in normal case, we avoid one copy */
              if (s->y == 0)
                  last_row = s->last_row;
              else
  
              png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
                             last_row, s->row_size, s->bpp);
 -        }
          /* loco lags by 1 row so that it doesn't interfere with top prediction */
 -        if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
 -            s->color_type == PNG_COLOR_TYPE_RGB && s->y > 0)
 -            deloco_rgb24(ptr - s->image_linesize, s->row_size);
 +        if (s->filter_type == PNG_FILTER_TYPE_LOCO && s->y > 0) {
 +            if (s->bit_depth == 16) {
 +                deloco_rgb16((uint16_t *)(ptr - s->image_linesize), s->row_size / 2,
 +                             s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
 +            } else {
 +                deloco_rgb8(ptr - s->image_linesize, s->row_size,
 +                            s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
 +            }
 +        }
          s->y++;
          if (s->y == s->height) {
              s->state |= PNG_ALLIMAGE;
 -            if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
 -                s->color_type == PNG_COLOR_TYPE_RGB)
 -                deloco_rgb24(ptr, s->row_size);
 +            if (s->filter_type == PNG_FILTER_TYPE_LOCO) {
 +                if (s->bit_depth == 16) {
 +                    deloco_rgb16((uint16_t *)ptr, s->row_size / 2,
 +                                 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
 +                } else {
 +                    deloco_rgb8(ptr, s->row_size,
 +                                s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
 +                }
 +            }
          }
      } else {
          got_line = 0;
                  got_line = 1;
              }
              if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
 -                /* NOTE: RGB32 is handled directly in png_put_interlaced_row */
                  png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
                                         s->color_type, s->last_row);
              }
              s->y++;
              if (s->y == s->height) {
 +                memset(s->last_row, 0, s->row_size);
                  for(;;) {
                      if (s->pass == NB_PASSES - 1) {
                          s->state |= PNG_ALLIMAGE;
  static int png_decode_idat(PNGDecContext *s, int length)
  {
      int ret;
-     s->zstream.avail_in = length;
-     s->zstream.next_in = s->bytestream;
-     s->bytestream += length;
-     if(s->bytestream > s->bytestream_end)
-         return -1;
+     s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
+     s->zstream.next_in = s->gb.buffer;
+     bytestream2_skip(&s->gb, length);
  
      /* decode one line if possible */
      while (s->zstream.avail_in > 0) {
@@@ -401,17 -398,13 +396,15 @@@ static int decode_frame(AVCodecContext 
      avctx->coded_frame= s->current_picture;
      p = s->current_picture;
  
-     s->bytestream_start=
-     s->bytestream= buf;
-     s->bytestream_end= buf + buf_size;
      /* check signature */
-     if (memcmp(s->bytestream, ff_pngsig, 8) != 0 &&
-         memcmp(s->bytestream, ff_mngsig, 8) != 0) {
+     if (buf_size < 8 ||
+         memcmp(buf, ff_pngsig, 8) != 0 &&
 -        memcmp(buf, ff_mngsig, 8) != 0)
++        memcmp(buf, ff_mngsig, 8) != 0) {
 +        av_log(avctx, AV_LOG_ERROR, "Missing png signature\n");
          return -1;
-     s->bytestream+= 8;
 +    }
+     bytestream2_init(&s->gb, buf + 8, buf_size - 8);
      s->y=
      s->state=0;
  //    memset(s, 0, sizeof(PNGDecContext));
      if (ret != Z_OK)
          return -1;
      for(;;) {
-         int tag32;
-         if (s->bytestream >= s->bytestream_end)
+         if (bytestream2_get_bytes_left(&s->gb) <= 0)
              goto fail;
-         length = bytestream_get_be32(&s->bytestream);
-         if (length > 0x7fffffff || length > s->bytestream_end - s->bytestream)
++
+         length = bytestream2_get_be32(&s->gb);
 -        if (length > 0x7fffffff)
++        if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb))
              goto fail;
-         tag32 = bytestream_get_be32(&s->bytestream);
-         tag = av_bswap32(tag32);
+         tag = bytestream2_get_le32(&s->gb);
 -        av_dlog(avctx, "png: tag=%c%c%c%c length=%u\n",
 +        if (avctx->debug & FF_DEBUG_STARTCODE)
 +            av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
                  (tag & 0xff),
                  ((tag >> 8) & 0xff),
                  ((tag >> 16) & 0xff),
          case MKTAG('I', 'H', 'D', 'R'):
              if (length != 13)
                  goto fail;
-             s->width = bytestream_get_be32(&s->bytestream);
-             s->height = bytestream_get_be32(&s->bytestream);
+             s->width  = bytestream2_get_be32(&s->gb);
+             s->height = bytestream2_get_be32(&s->gb);
              if(av_image_check_size(s->width, s->height, 0, avctx)){
                  s->width= s->height= 0;
                  goto fail;
              }
-             s->bit_depth = *s->bytestream++;
-             s->color_type = *s->bytestream++;
-             s->compression_type = *s->bytestream++;
-             s->filter_type = *s->bytestream++;
-             s->interlace_type = *s->bytestream++;
-             s->bytestream += 4; /* crc */
+             s->bit_depth        = bytestream2_get_byte(&s->gb);
+             s->color_type       = bytestream2_get_byte(&s->gb);
+             s->compression_type = bytestream2_get_byte(&s->gb);
+             s->filter_type      = bytestream2_get_byte(&s->gb);
+             s->interlace_type   = bytestream2_get_byte(&s->gb);
+             bytestream2_skip(&s->gb, 4); /* crc */
              s->state |= PNG_IHDR;
 -            av_dlog(avctx, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n",
 +            if (avctx->debug & FF_DEBUG_PICT_INFO)
 +                av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n",
                      s->width, s->height, s->bit_depth, s->color_type,
                      s->compression_type, s->filter_type, s->interlace_type);
              break;
                  s->bpp = (s->bits_per_pixel + 7) >> 3;
                  s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
  
 -                if (s->bit_depth == 8 &&
 +                if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
                      s->color_type == PNG_COLOR_TYPE_RGB) {
                      avctx->pix_fmt = PIX_FMT_RGB24;
 -                } else if (s->bit_depth == 8 &&
 +                } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
                             s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
 -                    avctx->pix_fmt = PIX_FMT_RGB32;
 -                } else if (s->bit_depth == 8 &&
 +                    avctx->pix_fmt = PIX_FMT_RGBA;
 +                } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
                             s->color_type == PNG_COLOR_TYPE_GRAY) {
                      avctx->pix_fmt = PIX_FMT_GRAY8;
                  } else if (s->bit_depth == 16 &&
                  } else if (s->bit_depth == 16 &&
                             s->color_type == PNG_COLOR_TYPE_RGB) {
                      avctx->pix_fmt = PIX_FMT_RGB48BE;
 -                } else if (s->bit_depth == 1 &&
 -                           s->color_type == PNG_COLOR_TYPE_GRAY) {
 -                    avctx->pix_fmt = PIX_FMT_MONOBLACK;
 +                } else if (s->bit_depth == 16 &&
 +                           s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
 +                    avctx->pix_fmt = PIX_FMT_RGBA64BE;
                  } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
                      avctx->pix_fmt = PIX_FMT_PAL8;
 -                } else if (s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
 -                    avctx->pix_fmt = PIX_FMT_Y400A;
 +                } else if (s->bit_depth == 1) {
 +                    avctx->pix_fmt = PIX_FMT_MONOBLACK;
 +                } else if (s->bit_depth == 8 &&
 +                           s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
 +                    avctx->pix_fmt = PIX_FMT_GRAY8A;
                  } else {
 +                    av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d "
 +                                                "and color type %d\n",
 +                                                 s->bit_depth, s->color_type);
                      goto fail;
                  }
                  if(p->data[0])
                      avctx->release_buffer(avctx, p);
  
 -                p->reference= 0;
 +                p->reference= 3;
                  if(avctx->get_buffer(avctx, p) < 0){
                      av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                      goto fail;
                  s->image_buf = p->data[0];
                  s->image_linesize = p->linesize[0];
                  /* copy the palette if needed */
 -                if (s->color_type == PNG_COLOR_TYPE_PALETTE)
 +                if (avctx->pix_fmt == PIX_FMT_PAL8)
                      memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
                  /* empty row is used if differencing to the first row */
                  s->last_row = av_mallocz(s->row_size);
              s->state |= PNG_IDAT;
              if (png_decode_idat(s, length) < 0)
                  goto fail;
-             s->bytestream += 4; /* crc */
+             bytestream2_skip(&s->gb, 4); /* crc */
              break;
          case MKTAG('P', 'L', 'T', 'E'):
              {
                  /* read the palette */
                  n = length / 3;
                  for(i=0;i<n;i++) {
-                     r = *s->bytestream++;
-                     g = *s->bytestream++;
-                     b = *s->bytestream++;
+                     r = bytestream2_get_byte(&s->gb);
+                     g = bytestream2_get_byte(&s->gb);
+                     b = bytestream2_get_byte(&s->gb);
                      s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
                  }
                  for(;i<256;i++) {
                      s->palette[i] = (0xff << 24);
                  }
                  s->state |= PNG_PLTE;
-                 s->bytestream += 4; /* crc */
+                 bytestream2_skip(&s->gb, 4); /* crc */
              }
              break;
          case MKTAG('t', 'R', 'N', 'S'):
                      !(s->state & PNG_PLTE))
                      goto skip_tag;
                  for(i=0;i<length;i++) {
-                     v = *s->bytestream++;
+                     v = bytestream2_get_byte(&s->gb);
                      s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
                  }
-                 s->bytestream += 4; /* crc */
+                 bytestream2_skip(&s->gb, 4); /* crc */
              }
              break;
          case MKTAG('I', 'E', 'N', 'D'):
              if (!(s->state & PNG_ALLIMAGE))
                  goto fail;
-             s->bytestream += 4; /* crc */
+             bytestream2_skip(&s->gb, 4); /* crc */
              goto exit_loop;
          default:
              /* skip tag */
          skip_tag:
-             s->bytestream += length + 4;
+             bytestream2_skip(&s->gb, length + 4);
              break;
          }
      }
   exit_loop:
 +
 +    if(s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){
 +        int i, j;
 +        uint8_t *pd = s->current_picture->data[0];
 +        for(j=0; j < s->height; j++) {
 +            for(i=s->width/8-1; i>=0; i--) {
 +                pd[8*i+7]=  pd[i]    &1;
 +                pd[8*i+6]= (pd[i]>>1)&1;
 +                pd[8*i+5]= (pd[i]>>2)&1;
 +                pd[8*i+4]= (pd[i]>>3)&1;
 +                pd[8*i+3]= (pd[i]>>4)&1;
 +                pd[8*i+2]= (pd[i]>>5)&1;
 +                pd[8*i+1]= (pd[i]>>6)&1;
 +                pd[8*i+0]=  pd[i]>>7;
 +            }
 +            pd += s->image_linesize;
 +        }
 +    }
 +    if(s->bits_per_pixel == 2){
 +        int i, j;
 +        uint8_t *pd = s->current_picture->data[0];
 +        for(j=0; j < s->height; j++) {
 +            if (s->color_type == PNG_COLOR_TYPE_PALETTE){
 +            for(i=s->width/4-1; i>=0; i--) {
 +                pd[4*i+3]=  pd[i]    &3;
 +                pd[4*i+2]= (pd[i]>>2)&3;
 +                pd[4*i+1]= (pd[i]>>4)&3;
 +                pd[4*i+0]=  pd[i]>>6;
 +            }
 +            } else {
 +                for(i=s->width/4-1; i>=0; i--) {
 +                    pd[4*i+3]= ( pd[i]    &3)*0x55;
 +                    pd[4*i+2]= ((pd[i]>>2)&3)*0x55;
 +                    pd[4*i+1]= ((pd[i]>>4)&3)*0x55;
 +                    pd[4*i+0]= ( pd[i]>>6   )*0x55;
 +                }
 +            }
 +            pd += s->image_linesize;
 +        }
 +    }
 +    if(s->bits_per_pixel == 4){
 +        int i, j;
 +        uint8_t *pd = s->current_picture->data[0];
 +        for(j=0; j < s->height; j++) {
 +            if (s->color_type == PNG_COLOR_TYPE_PALETTE){
 +            for(i=s->width/2-1; i>=0; i--) {
 +                pd[2*i+1]= pd[i]&15;
 +                pd[2*i+0]= pd[i]>>4;
 +            }
 +            } else {
 +                for(i=s->width/2-1; i>=0; i--) {
 +                    pd[2*i+1]= (pd[i]&15)*0x11;
 +                    pd[2*i+0]= (pd[i]>>4)*0x11;
 +                }
 +            }
 +            pd += s->image_linesize;
 +        }
 +    }
 +
       /* handle p-frames only if a predecessor frame is available */
       if(s->last_picture->data[0] != NULL) {
           if(!(avpkt->flags & AV_PKT_FLAG_KEY)) {
      *picture= *s->current_picture;
      *data_size = sizeof(AVFrame);
  
-     ret = s->bytestream - s->bytestream_start;
+     ret = bytestream2_tell(&s->gb);
   the_end:
      inflateEnd(&s->zstream);
      av_free(crow_buf_base);
      goto the_end;
  }
  
 -static av_cold int png_dec_init(AVCodecContext *avctx){
 +static av_cold int png_dec_init(AVCodecContext *avctx)
 +{
      PNGDecContext *s = avctx->priv_data;
  
      s->current_picture = &s->picture1;
      s->last_picture = &s->picture2;
      avcodec_get_frame_defaults(&s->picture1);
      avcodec_get_frame_defaults(&s->picture2);
 +
      ff_pngdsp_init(&s->dsp);
  
      return 0;
diff --combined libavcodec/tiff.c
index 5adf5a3b55f8d19e0052179d92818da14bf5c4d7,9ca91636a1dc53233664148b351352f779607cb0..28bae611c19cf85800aafa0387a6317d0e1d0f77
@@@ -1,20 -1,21 +1,20 @@@
  /*
 - * TIFF image decoder
   * Copyright (c) 2006 Konstantin Shishkov
   *
 - * 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
   */
  
@@@ -102,46 -103,6 +102,46 @@@ static int tiff_uncompress(uint8_t *dst
  }
  #endif
  
 +static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst,
 +                                             int usePtr, const uint8_t *src,
 +                                             uint8_t c, int width, int offset)
 +{
 +    switch (bpp) {
 +    case 1:
 +        while (--width >= 0) {
 +            dst[(width+offset)*8+7] = (usePtr ? src[width] : c)      & 0x1;
 +            dst[(width+offset)*8+6] = (usePtr ? src[width] : c) >> 1 & 0x1;
 +            dst[(width+offset)*8+5] = (usePtr ? src[width] : c) >> 2 & 0x1;
 +            dst[(width+offset)*8+4] = (usePtr ? src[width] : c) >> 3 & 0x1;
 +            dst[(width+offset)*8+3] = (usePtr ? src[width] : c) >> 4 & 0x1;
 +            dst[(width+offset)*8+2] = (usePtr ? src[width] : c) >> 5 & 0x1;
 +            dst[(width+offset)*8+1] = (usePtr ? src[width] : c) >> 6 & 0x1;
 +            dst[(width+offset)*8+0] = (usePtr ? src[width] : c) >> 7;
 +        }
 +        break;
 +    case 2:
 +        while (--width >= 0) {
 +            dst[(width+offset)*4+3] = (usePtr ? src[width] : c) & 0x3;
 +            dst[(width+offset)*4+2] = (usePtr ? src[width] : c) >> 2 & 0x3;
 +            dst[(width+offset)*4+1] = (usePtr ? src[width] : c) >> 4 & 0x3;
 +            dst[(width+offset)*4+0] = (usePtr ? src[width] : c) >> 6;
 +        }
 +        break;
 +    case 4:
 +        while (--width >= 0) {
 +            dst[(width+offset)*2+1] = (usePtr ? src[width] : c) & 0xF;
 +            dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
 +        }
 +        break;
 +    default:
 +        if (usePtr) {
 +            memcpy(dst + offset, src, width);
 +        } else {
 +            memset(dst + offset, c, width);
 +        }
 +    }
 +}
 +
  static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uint8_t *src, int size, int lines){
      int c, line, pixels, code;
      const uint8_t *ssrc = src;
          }
          src = zbuf;
          for(line = 0; line < lines; line++){
 -            memcpy(dst, src, width);
 +            if(s->bpp < 8 && s->avctx->pix_fmt == PIX_FMT_PAL8){
 +                horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
 +            }else{
 +                memcpy(dst, src, width);
 +            }
              dst += stride;
              src += width;
          }
              ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride, s->compr, s->fax_opts);
              break;
          }
 +        if (s->bpp < 8 && s->avctx->pix_fmt == PIX_FMT_PAL8)
 +            for (line = 0; line < lines; line++) {
 +                horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
 +                dst += stride;
 +            }
          av_free(src2);
          return ret;
      }
              if (ssrc + size - src < width)
                  return AVERROR_INVALIDDATA;
              if (!s->fill_order) {
 -                memcpy(dst, src, width);
 +                horizontal_fill(s->bpp * (s->avctx->pix_fmt == PIX_FMT_PAL8),
 +                                dst, 1, src, 0, width, 0);
              } else {
                  int i;
                  for (i = 0; i < width; i++)
                          av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n");
                          return -1;
                      }
 -                    memcpy(dst + pixels, src, code);
 +                    horizontal_fill(s->bpp * (s->avctx->pix_fmt == PIX_FMT_PAL8),
 +                                    dst, 1, src, 0, code, pixels);
                      src += code;
                      pixels += code;
                  }else if(code != -128){ // -127..-1
                          return -1;
                      }
                      c = *src++;
 -                    memset(dst + pixels, c, code);
 +                    horizontal_fill(s->bpp * (s->avctx->pix_fmt == PIX_FMT_PAL8),
 +                                    dst, 0, NULL, c, code, pixels);
                      pixels += code;
                  }
              }
                  av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n", pixels, width);
                  return -1;
              }
 +            if (s->bpp < 8 && s->avctx->pix_fmt == PIX_FMT_PAL8)
 +                horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
              break;
          }
          dst += stride;
@@@ -281,12 -228,8 +281,12 @@@ static int init_image(TiffContext *s
  
      switch (s->bpp * 10 + s->bppcount) {
      case 11:
 -        s->avctx->pix_fmt = PIX_FMT_MONOBLACK;
 -        break;
 +        if (!s->palette_is_set) {
 +            s->avctx->pix_fmt = PIX_FMT_MONOBLACK;
 +            break;
 +        }
 +    case 21:
 +    case 41:
      case 81:
          s->avctx->pix_fmt = PIX_FMT_PAL8;
          break;
      case 161:
          s->avctx->pix_fmt = PIX_FMT_GRAY16BE;
          break;
 +    case 162:
 +        s->avctx->pix_fmt = PIX_FMT_GRAY8A;
 +        break;
      case 324:
          s->avctx->pix_fmt = PIX_FMT_RGBA;
          break;
      case 483:
          s->avctx->pix_fmt = s->le ? PIX_FMT_RGB48LE : PIX_FMT_RGB48BE;
          break;
 +    case 644:
 +        s->avctx->pix_fmt = s->le ? PIX_FMT_RGBA64LE : PIX_FMT_RGBA64BE;
 +        break;
      default:
          av_log(s->avctx, AV_LOG_ERROR,
                 "This format is not supported (bpp=%d, bppcount=%d)\n",
          } else {
              /* make default grayscale pal */
              pal = (uint32_t *) s->picture.data[1];
 -            for (i = 0; i < 256; i++)
 -                pal[i] = i * 0x010101;
 +            for (i = 0; i < 1<<s->bpp; i++)
 +                pal[i] = 0xFF << 24 | i * 255 / ((1<<s->bpp) - 1) * 0x010101;
          }
      }
      return 0;
@@@ -498,13 -435,6 +498,13 @@@ static int tiff_decode_tag(TiffContext 
              return -1;
          }
          break;
 +    case TIFF_TILE_BYTE_COUNTS:
 +    case TIFF_TILE_LENGTH:
 +    case TIFF_TILE_OFFSETS:
 +    case TIFF_TILE_WIDTH:
 +        av_log(s->avctx, AV_LOG_ERROR, "Tiled images are not supported\n");
 +        return AVERROR_PATCHWELCOME;
 +        break;
      case TIFF_PREDICTOR:
          s->predictor = value;
          break;
          bp = buf + count / 3 * off * 2;
          off = (type_sizes[type] - 1) << 3;
          for(i = 0; i < count / 3; i++){
 -            j = (tget(&rp, type, s->le) >> off) << 16;
 +            j = 0xff << 24;
 +            j |= (tget(&rp, type, s->le) >> off) << 16;
              j |= (tget(&gp, type, s->le) >> off) << 8;
              j |= tget(&bp, type, s->le) >> off;
              pal[i] = j;
@@@ -606,6 -535,8 +606,8 @@@ static int decode_frame(AVCodecContext 
          av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n");
          return -1;
      }
+     // Reset these pointers so we can tell if they were set this frame
+     s->stripsizes = s->stripdata = NULL;
      /* parse image file directory */
      off = tget_long(&buf, le);
      if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) {
          dst = p->data[0];
          soff = s->bpp >> 3;
          ssize = s->width * soff;
 -        for(i = 0; i < s->height; i++) {
 -            for(j = soff; j < ssize; j++)
 -                dst[j] += dst[j - soff];
 -            dst += stride;
 +        if (s->avctx->pix_fmt == PIX_FMT_RGB48LE ||
 +            s->avctx->pix_fmt == PIX_FMT_RGBA64LE) {
 +            for (i = 0; i < s->height; i++) {
 +                for (j = soff; j < ssize; j += 2)
 +                    AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff));
 +                dst += stride;
 +            }
 +        } else if (s->avctx->pix_fmt == PIX_FMT_RGB48BE ||
 +                   s->avctx->pix_fmt == PIX_FMT_RGBA64BE) {
 +            for (i = 0; i < s->height; i++) {
 +                for (j = soff; j < ssize; j += 2)
 +                    AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff));
 +                dst += stride;
 +            }
 +        } else {
 +            for(i = 0; i < s->height; i++) {
 +                for(j = soff; j < ssize; j++)
 +                    dst[j] += dst[j - soff];
 +                dst += stride;
 +            }
          }
      }
  
      if(s->invert){
 -        uint8_t *src;
 -        int j;
 -
 -        src = s->picture.data[0];
 -        for(j = 0; j < s->height; j++){
 -            for(i = 0; i < s->picture.linesize[0]; i++)
 -                src[i] = 255 - src[i];
 -            src += s->picture.linesize[0];
 +        dst = s->picture.data[0];
 +        for(i = 0; i < s->height; i++){
 +            for(j = 0; j < s->picture.linesize[0]; j++)
 +                dst[j] = (s->avctx->pix_fmt == PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j];
 +            dst += s->picture.linesize[0];
          }
      }
      *picture   = s->picture;
diff --combined libavcodec/tta.c
index 4dc879cd09f4072f56e46d47882aeebc2fcb2363,ad8024652575acb067f8a79142cd6ebd326c8fdc..b463946724ada35b97702132d1355d53cdbf3f5d
@@@ -2,20 -2,20 +2,20 @@@
   * TTA (The Lossless True Audio) decoder
   * Copyright (c) 2006 Alex Beregszaszi
   *
 - * 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
   */
  
@@@ -179,16 -179,6 +179,16 @@@ static int tta_get_unary(GetBitContext 
      return ret;
  }
  
 +static const int64_t tta_channel_layouts[7] = {
 +    AV_CH_LAYOUT_STEREO,
 +    AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY,
 +    AV_CH_LAYOUT_QUAD,
 +    0,
 +    AV_CH_LAYOUT_5POINT1_BACK,
 +    AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER,
 +    AV_CH_LAYOUT_7POINT1_WIDE
 +};
 +
  static int tta_check_crc(TTAContext *s, const uint8_t *buf, int buf_size)
  {
      uint32_t crc, CRC;
@@@ -218,8 -208,7 +218,7 @@@ static av_cold int tta_decode_init(AVCo
      {
          if (avctx->err_recognition & AV_EF_CRCCHECK) {
              s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
-             if (tta_check_crc(s, avctx->extradata, 18))
-                 return AVERROR_INVALIDDATA;
+             tta_check_crc(s, avctx->extradata, 18);
          }
  
          /* signature */
              return AVERROR(EINVAL);
          }
          avctx->channels = s->channels = get_bits(&s->gb, 16);
 +        if (s->channels > 1 && s->channels < 9)
 +            avctx->channel_layout = tta_channel_layouts[s->channels-2];
          avctx->bits_per_coded_sample = get_bits(&s->gb, 16);
          s->bps = (avctx->bits_per_coded_sample + 7) / 8;
          avctx->sample_rate = get_bits_long(&s->gb, 32);
          }
  
          switch(s->bps) {
 +        case 1: avctx->sample_fmt = AV_SAMPLE_FMT_U8; break;
          case 2:
              avctx->sample_fmt = AV_SAMPLE_FMT_S16;
              avctx->bits_per_raw_sample = 16;
              avctx->sample_fmt = AV_SAMPLE_FMT_S32;
              avctx->bits_per_raw_sample = 24;
              break;
 +        //case 4: avctx->sample_fmt = AV_SAMPLE_FMT_S32; break;
          default:
              av_log(avctx, AV_LOG_ERROR, "Invalid/unsupported sample format.\n");
              return AVERROR_INVALIDDATA;
              return -1;
          }
  
 -        if (s->bps == 2) {
 +        if (s->bps < 3) {
              s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels);
              if (!s->decode_buffer)
                  return AVERROR(ENOMEM);
 -        }
 +        } else
 +            s->decode_buffer = NULL;
          s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx));
          if (!s->ch_ctx) {
              av_freep(&s->decode_buffer);
@@@ -447,28 -431,17 +446,28 @@@ static int tta_decode_frame(AVCodecCont
      skip_bits_long(&s->gb, 32); // frame crc
  
      // convert to output buffer
 -    if (s->bps == 2) {
 -        int16_t *samples = (int16_t *)s->frame.data[0];
 +    switch (s->bps) {
 +    case 1: {
 +        uint8_t *samples = (uint8_t *)s->frame.data[0];
 +        for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
 +            *samples++ = *p + 0x80;
 +        break;
 +        }
 +    case 2: {
 +        uint16_t *samples = (int16_t *)s->frame.data[0];
          for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
              *samples++ = *p;
 -    } else {
 +        break;
 +        }
 +    case 3: {
          // shift samples for 24-bit sample format
          int32_t *samples = (int32_t *)s->frame.data[0];
 -        for (i = 0; i < framelen * s->channels; i++)
 +        for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
              *samples++ <<= 8;
          // reset decode buffer
          s->decode_buffer = NULL;
 +        break;
 +        }
      }
  
      *got_frame_ptr   = 1;
@@@ -485,9 -458,7 +484,9 @@@ error
  static av_cold int tta_decode_close(AVCodecContext *avctx) {
      TTAContext *s = avctx->priv_data;
  
 -    av_free(s->decode_buffer);
 +    if (s->bps < 3)
 +        av_free(s->decode_buffer);
 +    s->decode_buffer = NULL;
      av_freep(&s->ch_ctx);
  
      return 0;
diff --combined libavcodec/vorbisdec.c
index 702c0d0429d5d6695b945ff530ab07de7561dc75,4a7d6097b12778f987716eaea7f8e73b09bbc8dd..08a2c48df91221338b270838cd7642a90579ee54
@@@ -1,22 -1,18 +1,22 @@@
 -/*
 - * This file is part of Libav.
 +/**
 + * @file
 + * Vorbis I decoder
 + * @author Denes Balatoni  ( dbalatoni programozo hu )
 + *
 + * 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
   */
  
@@@ -579,14 -575,6 +579,14 @@@ static int vorbis_parse_setup_hdr_floor
  
  // Precalculate order of x coordinates - needed for decode
              ff_vorbis_ready_floor1_list(floor_setup->data.t1.list, floor_setup->data.t1.x_list_dim);
 +
 +            for (j=1; j<floor_setup->data.t1.x_list_dim; j++) {
 +                if (   floor_setup->data.t1.list[ floor_setup->data.t1.list[j-1].sort ].x
 +                    == floor_setup->data.t1.list[ floor_setup->data.t1.list[j  ].sort ].x) {
 +                    av_log(vc->avccontext, AV_LOG_ERROR, "Non unique x values in floor type 1\n");
 +                    return AVERROR_INVALIDDATA;
 +                }
 +            }
          } else if (floor_setup->floor_type == 0) {
              unsigned max_codebook_dim = 0;
  
@@@ -942,12 -930,12 +942,12 @@@ static int vorbis_parse_id_hdr(vorbis_c
      vc->bitrate_minimum = get_bits_long(gb, 32);
      bl0 = get_bits(gb, 4);
      bl1 = get_bits(gb, 4);
 -    vc->blocksize[0] = (1 << bl0);
 -    vc->blocksize[1] = (1 << bl1);
      if (bl0 > 13 || bl0 < 6 || bl1 > 13 || bl1 < 6 || bl1 < bl0) {
          av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n");
          return AVERROR_INVALIDDATA;
      }
 +    vc->blocksize[0] = (1 << bl0);
 +    vc->blocksize[1] = (1 << bl1);
      vc->win[0] = ff_vorbis_vwin[bl0 - 6];
      vc->win[1] = ff_vorbis_vwin[bl1 - 6];
  
@@@ -1170,7 -1158,7 +1170,7 @@@ static int vorbis_floor1_decode(vorbis_
      uint16_t floor1_Y[258];
      uint16_t floor1_Y_final[258];
      int floor1_flag[258];
 -    unsigned class, cdim, cbits, csub, cval, offset, i, j;
 +    unsigned partition_class, cdim, cbits, csub, cval, offset, i, j;
      int book, adx, ady, dy, off, predicted, err;
  
  
  
      offset = 2;
      for (i = 0; i < vf->partitions; ++i) {
 -        class = vf->partition_class[i];
 -        cdim   = vf->class_dimensions[class];
 -        cbits  = vf->class_subclasses[class];
 +        partition_class = vf->partition_class[i];
 +        cdim   = vf->class_dimensions[partition_class];
 +        cbits  = vf->class_subclasses[partition_class];
          csub = (1 << cbits) - 1;
          cval = 0;
  
          av_dlog(NULL, "Cbits %u\n", cbits);
  
          if (cbits) // this reads all subclasses for this partition's class
 -            cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[class]].vlc.table,
 -                            vc->codebooks[vf->class_masterbook[class]].nb_bits, 3);
 +            cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[partition_class]].vlc.table,
 +                            vc->codebooks[vf->class_masterbook[partition_class]].nb_bits, 3);
  
          for (j = 0; j < cdim; ++j) {
 -            book = vf->subclass_books[class][cval & csub];
 +            book = vf->subclass_books[partition_class][cval & csub];
  
              av_dlog(NULL, "book %d Cbits %u cval %u  bits:%d\n",
                      book, cbits, cval, get_bits_count(gb));
@@@ -1593,6 -1581,9 +1593,9 @@@ static int vorbis_parse_audio_packet(vo
          ch_left -= ch;
      }
  
+     if (ch_left > 0)
+         return AVERROR_INVALIDDATA;
  // Inverse coupling
  
      for (i = mapping->coupling_steps - 1; i >= 0; --i) { //warning: i has to be signed
diff --combined libavformat/oggdec.c
index 39f99e5f657d4e903ad618ad99cfe02733878a46,e04a4e7973fa55886ef0d7b8236ccf5efc0c20a9..bdd2c5ba772c5c8abceca9765c207dfa1ff092e5
@@@ -28,6 -28,7 +28,6 @@@
      DEALINGS IN THE SOFTWARE.
   */
  
 -
  #include <stdio.h>
  #include "oggdec.h"
  #include "avformat.h"
@@@ -69,8 -70,7 +69,7 @@@ static int ogg_save(AVFormatContext *s
  
      for (i = 0; i < ogg->nstreams; i++){
          struct ogg_stream *os = ogg->streams + i;
-         os->buf = av_malloc (os->bufsize);
-         memset (os->buf, 0, os->bufsize);
+         os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
          memcpy (os->buf, ost->streams[i].buf, os->bufpos);
      }
  
@@@ -167,7 -167,7 +166,7 @@@ static int ogg_new_stream(AVFormatConte
      os = ogg->streams + idx;
      os->serial = serial;
      os->bufsize = DECODER_BUFFER_SIZE;
-     os->buf = av_malloc(os->bufsize);
+     os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
      os->header = -1;
  
      if (new_avstream) {
  static int ogg_new_buf(struct ogg *ogg, int idx)
  {
      struct ogg_stream *os = ogg->streams + idx;
-     uint8_t *nb = av_malloc(os->bufsize);
+     uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
      int size = os->bufpos - os->pstart;
      if(os->buf){
          memcpy(nb, os->buf + os->pstart, size);
@@@ -224,7 -224,7 +223,7 @@@ static int ogg_read_page(AVFormatContex
              break;
  
          c = avio_r8(bc);
 -        if (bc->eof_reached)
 +        if (url_feof(bc))
              return AVERROR_EOF;
          sync[sp++ & 3] = c;
      }while (i++ < MAX_PAGE_SIZE);
  
      if (flags & OGG_FLAG_CONT || os->incomplete){
          if (!os->psize){
 +            // If this is the very first segment we started
 +            // playback in the middle of a continuation packet.
 +            // Discard it since we missed the start of it.
              while (os->segp < os->nsegs){
                  int seg = os->segments[os->segp++];
                  os->pstart += seg;
      }
  
      if (os->bufsize - os->bufpos < size){
-         uint8_t *nb = av_malloc (os->bufsize *= 2);
+         uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
          memcpy (nb, os->buf, os->bufpos);
          av_free (os->buf);
          os->buf = nb;
      os->granule = gp;
      os->flags = flags;
  
+     memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
      if (str)
          *str = idx;
  
@@@ -371,14 -369,12 +371,14 @@@ static int ogg_packet(AVFormatContext *
  
          if (!complete && os->segp == os->nsegs){
              ogg->curidx = -1;
 -            os->incomplete = 1;
 +            // Do not set incomplete for empty packets.
 +            // Together with the code in ogg_read_page
 +            // that discards all continuation of empty packets
 +            // we would get an infinite loop.
 +            os->incomplete = !!os->psize;
          }
      }while (!complete);
  
 -    av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
 -            idx, os->psize, os->pstart);
  
      if (os->granule == -1)
          av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
              *fpos = os->sync_pos;
          os->pstart += os->psize;
          os->psize = 0;
 +        if(os->pstart == os->bufpos)
 +            os->bufpos = os->pstart = 0;
          os->sync_pos = os->page_pos;
      }
  
@@@ -469,7 -463,6 +469,7 @@@ static int ogg_get_length(AVFormatConte
      struct ogg *ogg = s->priv_data;
      int i;
      int64_t size, end;
 +    int streams_left=0;
  
      if(!s->pb->seekable)
          return 0;
              ogg->streams[i].codec) {
              s->streams[i]->duration =
                  ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
 -            if (s->streams[i]->start_time != AV_NOPTS_VALUE)
 +            if (s->streams[i]->start_time != AV_NOPTS_VALUE){
                  s->streams[i]->duration -= s->streams[i]->start_time;
 +                streams_left-= (ogg->streams[i].got_start==-1);
 +                ogg->streams[i].got_start= 1;
 +            }else if(!ogg->streams[i].got_start){
 +                ogg->streams[i].got_start= -1;
 +                streams_left++;
 +            }
          }
      }
  
      ogg_restore (s, 0);
  
 +    ogg_save (s);
 +    avio_seek (s->pb, 0, SEEK_SET);
 +    while (!ogg_read_page (s, &i)){
 +        if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
 +            ogg->streams[i].codec) {
 +            if(s->streams[i]->duration && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
 +                int64_t start= ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
 +                if(av_rescale_q(start, s->streams[i]->time_base, AV_TIME_BASE_Q) > AV_TIME_BASE)
 +                    s->streams[i]->duration -= start;
 +                ogg->streams[i].got_start= 1;
 +                streams_left--;
 +            }
 +            if(streams_left<=0)
 +                break;
 +        }
 +    }
 +    ogg_restore (s, 0);
 +
      return 0;
  }
  
@@@ -576,19 -545,6 +576,19 @@@ static int64_t ogg_calc_pts(AVFormatCon
      return pts;
  }
  
 +static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
 +{
 +    struct ogg *ogg = s->priv_data;
 +    struct ogg_stream *os = ogg->streams + idx;
 +    if (psize && s->streams[idx]->codec->codec_id == CODEC_ID_THEORA) {
 +        if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
 +            os->pflags ^= AV_PKT_FLAG_KEY;
 +            av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
 +                   (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
 +        }
 +    }
 +}
 +
  static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
  {
      struct ogg *ogg;
@@@ -610,7 -566,6 +610,7 @@@ retry
  
      // pflags might not be set until after this
      pts = ogg_calc_pts(s, idx, &dts);
 +    ogg_validate_keyframe(s, idx, pstart, psize);
  
      if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
          goto retry;
@@@ -651,27 -606,16 +651,27 @@@ static int64_t ogg_read_timestamp(AVFor
      struct ogg *ogg = s->priv_data;
      AVIOContext *bc = s->pb;
      int64_t pts = AV_NOPTS_VALUE;
 +    int64_t keypos = -1;
      int i = -1;
 +    int pstart, psize;
      avio_seek(bc, *pos_arg, SEEK_SET);
      ogg_reset(ogg);
  
 -    while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
 +    while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
          if (i == stream_index) {
              struct ogg_stream *os = ogg->streams + stream_index;
              pts = ogg_calc_pts(s, i, NULL);
 -            if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
 -                pts = AV_NOPTS_VALUE;
 +            ogg_validate_keyframe(s, i, pstart, psize);
 +            if (os->pflags & AV_PKT_FLAG_KEY) {
 +                keypos = *pos_arg;
 +            } else if (os->keyframe_seek) {
 +                // if we had a previous keyframe but no pts for it,
 +                // return that keyframe with this pts value.
 +                if (keypos >= 0)
 +                    *pos_arg = keypos;
 +                else
 +                    pts = AV_NOPTS_VALUE;
 +            }
          }
          if (pts != AV_NOPTS_VALUE)
              break;
@@@ -687,10 -631,6 +687,10 @@@ static int ogg_read_seek(AVFormatContex
      struct ogg_stream *os = ogg->streams + stream_index;
      int ret;
  
 +    // Ensure everything is reset even when seeking via
 +    // the generated index.
 +    ogg_reset(ogg);
 +
      // Try seeking to a keyframe first. If this fails (very possible),
      // av_seek_frame will fall back to ignoring keyframes
      if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
diff --combined libavformat/rtpenc.c
index 1e1dac5ef0390a44697bb96f72843672630cdcdb,5df25e4b8884bbbebf03c3beb91af182a524f7d0..6c1029b19c9999377ad43ec82c2fb0bc059d11fd
@@@ -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
   */
  
@@@ -92,7 -92,7 +92,7 @@@ static int rtp_write_header(AVFormatCon
      }
      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->max_frames_per_packet =
                          av_rescale_q_rnd(s1->max_delay,
                                           AV_TIME_BASE_Q,
-                                          (AVRational){ frame_size / st->codec->sample_rate },
+                                          (AVRational){ frame_size, st->codec->sample_rate },
                                           AV_ROUND_DOWN);
              }
          }