aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-04-02 01:25:31 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-04-02 01:25:31 +0200
commitb6cc1c77fd7d6a037c0c0c848c3621c7b1ff33b6 (patch)
treec199a1262a7f194a52cb3790790614e4f7f05590
parentceeaf424513fc019228f2cb88ea468940eb61648 (diff)
parentbc5d86d23d1ad377addf54d65ee665327836075e (diff)
downloadffmpeg-b6cc1c77fd7d6a037c0c0c848c3621c7b1ff33b6.tar.gz
Merge remote-tracking branch 'qatar/release/0.7' into release/0.8
* qatar/release/0.7: (84 commits) id3v2: fix skipping extended header in id3v2.4 Update RELEASE file for 0.7.5 lcl: use AVERROR_INVALIDDATA instead of AVERROR_UNKNOWN kgv1dec: Increase offsets array size so it is large enough. kgv1: use avctx->get/release_buffer(). kvmc: fix invalid reads nsvdec: Propagate error values instead of returning 0 in nsv_read_header(). mjpegbdec: Fix overflow in SOS. shorten: Use separate pointers for the allocated memory for decoded samples. shorten: check for realloc failure (cherry picked from commit 9e5e2c2d010c05c10337e9c1ec9d0d61495e0c9c) atrac3: Fix crash in tonal component decoding. ws_snd1: Fix wrong samples count and crash. ws_snd: add some checks to prevent buffer overread or overwrite. (cherry picked from commit 417364ce1f979031ef6fee661fc15e1869bdb1b4) ws_snd: decode to AV_SAMPLE_FMT_U8 instead of S16. dca: include libavutil/mathematics.h for possibly missing M_SQRT1_2 h264: stricter reference limit enforcement. jvdec: unbreak video decoding xxan: don't read before start of buffer in av_memcpy_backptr(). dsicinvideo: validate buffer offset before copying pixels. huffyuv: add padding to classic (v1) huffman tables. ... Conflicts: RELEASE libavcodec/atrac3.c libavcodec/h264.c libavcodec/h264_parser.c libavcodec/kgv1dec.c libavcodec/shorten.c libavcodec/svq3.c libavcodec/ws-snd1.c libavcodec/xxan.c libswscale/utils.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/aacdec.c25
-rw-r--r--libavcodec/ac3dsp.c8
-rw-r--r--libavcodec/alsdec.c2
-rw-r--r--libavcodec/atrac3.c2
-rw-r--r--libavcodec/cook.c4
-rw-r--r--libavcodec/cscd.c4
-rw-r--r--libavcodec/dca.c1
-rw-r--r--libavcodec/dsicinav.c40
-rw-r--r--libavcodec/flacdec.c9
-rw-r--r--libavcodec/fraps.c14
-rw-r--r--libavcodec/golomb.h6
-rw-r--r--libavcodec/h263dec.c9
-rw-r--r--libavcodec/h264.c12
-rw-r--r--libavcodec/h264_cabac.c2
-rw-r--r--libavcodec/h264_parser.c6
-rw-r--r--libavcodec/huffyuv.c14
-rw-r--r--libavcodec/jvdec.c2
-rw-r--r--libavcodec/kgv1dec.c89
-rw-r--r--libavcodec/kmvc.c82
-rw-r--r--libavcodec/lcldec.c37
-rw-r--r--libavcodec/mjpegbdec.c11
-rw-r--r--libavcodec/qdm2.c4
-rw-r--r--libavcodec/qtrle.c2
-rw-r--r--libavcodec/rawdec.c6
-rw-r--r--libavcodec/rpza.c4
-rw-r--r--libavcodec/rv10.c6
-rw-r--r--libavcodec/shorten.c3
-rw-r--r--libavcodec/smacker.c22
-rw-r--r--libavcodec/srtdec.c4
-rw-r--r--libavcodec/svq3.c19
-rw-r--r--libavcodec/tiff.c35
-rw-r--r--libavcodec/truemotion2.c2
-rw-r--r--libavcodec/vmnc.c1
-rw-r--r--libavcodec/vorbis.c19
-rw-r--r--libavcodec/vorbisdec.c10
-rw-r--r--libavcodec/vp5.c5
-rw-r--r--libavcodec/vp6.c6
-rw-r--r--libavcodec/wma.c2
-rw-r--r--libavcodec/wmadec.c4
-rw-r--r--libavcodec/wmaenc.c23
-rw-r--r--libavcodec/x86/h264_deblock_10bit.asm2
-rw-r--r--libavformat/asfdec.c15
-rw-r--r--libavformat/dv.c29
-rw-r--r--libavformat/id3v2.c13
-rw-r--r--libavformat/isom.c5
-rw-r--r--libavformat/matroskadec.c37
-rw-r--r--libavformat/nsvdec.c23
-rw-r--r--libavformat/rmdec.c20
-rw-r--r--libavformat/smacker.c9
-rw-r--r--libavformat/swfdec.c14
-rw-r--r--libswscale/utils.c18
-rw-r--r--libswscale/x86/swscale_mmx.c38
-rw-r--r--tests/ref/acodec/wmav16
-rw-r--r--tests/ref/acodec/wmav26
54 files changed, 560 insertions, 231 deletions
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index e9f2cc53e9..5b02d010a3 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -754,19 +754,20 @@ static int decode_band_types(AACContext *ac, enum BandType band_type[120],
av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n");
return -1;
}
- while ((sect_len_incr = get_bits(gb, bits)) == (1 << bits) - 1)
+ do {
+ sect_len_incr = get_bits(gb, bits);
sect_end += sect_len_incr;
- sect_end += sect_len_incr;
- if (get_bits_left(gb) < 0) {
- av_log(ac->avctx, AV_LOG_ERROR, overread_err);
- return -1;
- }
- if (sect_end > ics->max_sfb) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Number of bands (%d) exceeds limit (%d).\n",
- sect_end, ics->max_sfb);
- return -1;
- }
+ if (get_bits_left(gb) < 0) {
+ av_log(ac->avctx, AV_LOG_ERROR, overread_err);
+ return -1;
+ }
+ if (sect_end > ics->max_sfb) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Number of bands (%d) exceeds limit (%d).\n",
+ sect_end, ics->max_sfb);
+ return -1;
+ }
+ } while (sect_len_incr == (1 << bits) - 1);
for (; k < sect_end; k++) {
band_type [idx] = sect_band_type;
band_type_run_end[idx++] = sect_end;
diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c
index 619addc3d5..675f779b5d 100644
--- a/libavcodec/ac3dsp.c
+++ b/libavcodec/ac3dsp.c
@@ -108,7 +108,7 @@ static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd,
int snr_offset, int floor,
const uint8_t *bap_tab, uint8_t *bap)
{
- int bin, band;
+ int bin, band, band_end;
/* special case, if snr offset is -960, set all bap's to zero */
if (snr_offset == -960) {
@@ -120,12 +120,14 @@ static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd,
band = ff_ac3_bin_to_band_tab[start];
do {
int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor;
- int band_end = FFMIN(ff_ac3_band_start_tab[band+1], end);
+ band_end = ff_ac3_band_start_tab[++band];
+ band_end = FFMIN(band_end, end);
+
for (; bin < band_end; bin++) {
int address = av_clip((psd[bin] - m) >> 5, 0, 63);
bap[bin] = bap_tab[address];
}
- } while (end > ff_ac3_band_start_tab[band++]);
+ } while (end > band_end);
}
static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap,
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 509d49c694..505af26b67 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -1010,7 +1010,7 @@ static void zero_remaining(unsigned int b, unsigned int b_max,
{
unsigned int count = 0;
- while (b < b_max)
+ for (; b < b_max; b++)
count += div_blocks[b];
if (count)
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index f16630450d..d80cec41ec 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -395,7 +395,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent
for (k=0; k<coded_components; k++) {
sfIndx = get_bits(gb,6);
- if(component_count>=64)
+ if (component_count >= 64)
return AVERROR_INVALIDDATA;
pComponent[component_count].pos = j * 64 + (get_bits(gb,6));
max_coded_values = 1024 - pComponent[component_count].pos;
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index 96b889380a..a5da74efcc 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -1066,6 +1066,10 @@ static av_cold int cook_decode_init(AVCodecContext *avctx)
q->sample_rate = avctx->sample_rate;
q->nb_channels = avctx->channels;
q->bit_rate = avctx->bit_rate;
+ if (!q->nb_channels) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
+ return AVERROR_INVALIDDATA;
+ }
/* Initialize RNG. */
av_lfg_init(&q->random_state, 0);
diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c
index 9255503e05..45268e6687 100644
--- a/libavcodec/cscd.c
+++ b/libavcodec/cscd.c
@@ -228,7 +228,7 @@ static av_cold int decode_init(AVCodecContext *avctx) {
av_log(avctx, AV_LOG_ERROR,
"CamStudio codec error: invalid depth %i bpp\n",
avctx->bits_per_coded_sample);
- return 1;
+ return AVERROR_INVALIDDATA;
}
c->bpp = avctx->bits_per_coded_sample;
avcodec_get_frame_defaults(&c->pic);
@@ -242,7 +242,7 @@ static av_cold int decode_init(AVCodecContext *avctx) {
c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING);
if (!c->decomp_buf) {
av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
- return 1;
+ return AVERROR(ENOMEM);
}
return 0;
}
diff --git a/libavcodec/dca.c b/libavcodec/dca.c
index 24153ebdd2..9a5c36df9a 100644
--- a/libavcodec/dca.c
+++ b/libavcodec/dca.c
@@ -29,6 +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"
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index d4dbb35472..3163e10b1a 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -146,11 +146,11 @@ static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned c
return dst_cur - dst;
}
-static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
+static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
{
uint16_t cmd;
int i, sz, offset, code;
- unsigned char *dst_end = dst + dst_size;
+ unsigned char *dst_end = dst + dst_size, *dst_start = dst;
const unsigned char *src_end = src + src_size;
while (src < src_end && dst < dst_end) {
@@ -161,6 +161,8 @@ static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned cha
} else {
cmd = AV_RL16(src); src += 2;
offset = cmd >> 4;
+ if ((int) (dst - dst_start) < offset + 1)
+ return AVERROR_INVALIDDATA;
sz = (cmd & 0xF) + 2;
/* don't use memcpy/memmove here as the decoding routine (ab)uses */
/* buffer overlappings to repeat bytes in the destination */
@@ -172,6 +174,8 @@ static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned cha
}
}
}
+
+ return 0;
}
static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
@@ -201,13 +205,7 @@ static int cinvideo_decode_frame(AVCodecContext *avctx,
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
CinVideoContext *cin = avctx->priv_data;
- int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size;
-
- cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
- if (avctx->reget_buffer(avctx, &cin->frame)) {
- av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
- return -1;
- }
+ int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size, res = 0;
palette_type = buf[0];
palette_colors_count = AV_RL16(buf+1);
@@ -233,8 +231,6 @@ static int cinvideo_decode_frame(AVCodecContext *avctx,
bitmap_frame_size -= 4;
}
}
- memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
- cin->frame.palette_has_changed = 1;
/* note: the decoding routines below assumes that surface.width = surface.pitch */
switch (bitmap_frame_type) {
@@ -267,17 +263,31 @@ static int cinvideo_decode_frame(AVCodecContext *avctx,
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
break;
case 38:
- cin_decode_lzss(buf, bitmap_frame_size,
- cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+ res = cin_decode_lzss(buf, bitmap_frame_size,
+ cin->bitmap_table[CIN_CUR_BMP],
+ cin->bitmap_size);
+ if (res < 0)
+ return res;
break;
case 39:
- cin_decode_lzss(buf, bitmap_frame_size,
- cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
+ res = cin_decode_lzss(buf, bitmap_frame_size,
+ cin->bitmap_table[CIN_CUR_BMP],
+ cin->bitmap_size);
+ if (res < 0)
+ return res;
cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
break;
}
+ cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
+ if (avctx->reget_buffer(avctx, &cin->frame)) {
+ av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
+ return -1;
+ }
+
+ memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
+ cin->frame.palette_has_changed = 1;
for (y = 0; y < cin->avctx->height; ++y)
memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 011c75faae..9a0144d04c 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -420,7 +420,16 @@ static inline int decode_subframe(FLACContext *s, int channel)
type = get_bits(&s->gb, 6);
if (get_bits1(&s->gb)) {
+ int left = get_bits_left(&s->gb);
wasted = 1;
+ if ( left < 0 ||
+ (left < s->curr_bps && !show_bits_long(&s->gb, left)) ||
+ !show_bits_long(&s->gb, s->curr_bps)) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid number of wasted bits > available bits (%d) - left=%d\n",
+ s->curr_bps, left);
+ return AVERROR_INVALIDDATA;
+ }
while (!get_bits1(&s->gb))
wasted++;
s->curr_bps -= wasted;
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index 7e96b0d312..ed80038c4a 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -135,7 +135,7 @@ static int decode_frame(AVCodecContext *avctx,
uint32_t *luma1,*luma2,*cb,*cr;
uint32_t offs[4];
int i, j, is_chroma, planes;
-
+ enum PixelFormat pix_fmt;
header = AV_RL32(buf);
version = header & 0xff;
@@ -152,12 +152,16 @@ static int decode_frame(AVCodecContext *avctx,
if (header_size == 8)
buf+=4;
+ pix_fmt = version & 1 ? PIX_FMT_BGR24 : PIX_FMT_YUVJ420P;
+ if (avctx->pix_fmt != pix_fmt && f->data[0]) {
+ avctx->release_buffer(avctx, f);
+ }
+ avctx->pix_fmt = pix_fmt;
+
switch(version) {
case 0:
default:
/* Fraps v0 is a reordered YUV420 */
- avctx->pix_fmt = PIX_FMT_YUVJ420P;
-
if ( (buf_size != avctx->width*avctx->height*3/2+header_size) &&
(buf_size != header_size) ) {
av_log(avctx, AV_LOG_ERROR,
@@ -205,8 +209,6 @@ static int decode_frame(AVCodecContext *avctx,
case 1:
/* Fraps v1 is an upside-down BGR24 */
- avctx->pix_fmt = PIX_FMT_BGR24;
-
if ( (buf_size != avctx->width*avctx->height*3+header_size) &&
(buf_size != header_size) ) {
av_log(avctx, AV_LOG_ERROR,
@@ -241,7 +243,6 @@ static int decode_frame(AVCodecContext *avctx,
* Fraps v2 is Huffman-coded YUV420 planes
* Fraps v4 is virtually the same
*/
- avctx->pix_fmt = PIX_FMT_YUVJ420P;
planes = 3;
f->reference = 1;
f->buffer_hints = FF_BUFFER_HINTS_VALID |
@@ -286,7 +287,6 @@ static int decode_frame(AVCodecContext *avctx,
case 3:
case 5:
/* Virtually the same as version 4, but is for RGB24 */
- avctx->pix_fmt = PIX_FMT_BGR24;
planes = 3;
f->reference = 1;
f->buffer_hints = FF_BUFFER_HINTS_VALID |
diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 8dff0322a7..c24ff9eee4 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -123,7 +123,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){
}else{
int ret = 1;
- while (1) {
+ do {
buf >>= 32 - 8;
LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8));
@@ -135,7 +135,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){
ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf];
UPDATE_CACHE(re, gb);
buf = GET_CACHE(re, gb);
- }
+ } while (ret);
CLOSE_READER(re, gb);
return ret - 1;
@@ -301,7 +301,7 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int
return buf;
}else{
int i;
- for(i=0; SHOW_UBITS(re, gb, 1) == 0; i++){
+ for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) {
LAST_SKIP_BITS(re, gb, 1);
UPDATE_CACHE(re, gb);
}
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index e142c339c5..96422ef491 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -564,8 +564,7 @@ retry:
#if HAVE_MMX
if (s->codec_id == CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) {
avctx->idct_algo= FF_IDCT_XVIDMMX;
- avctx->coded_width= 0; // force reinit
-// dsputil_init(&s->dsp, avctx);
+ ff_dct_common_init(s);
s->picture_number=0;
}
#endif
@@ -579,6 +578,12 @@ retry:
|| s->height != avctx->coded_height) {
/* H.263 could change picture size any time */
ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
+
+ if (HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_FRAME)) {
+ av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0);
+ return -1; // width / height changed during parallelized decoding
+ }
+
s->parse_context.buffer=0;
MPV_common_end(s);
s->parse_context= pc;
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 8e4b44a584..462fae2a98 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -2886,7 +2886,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
h->ref_count[1]= h->pps.ref_count[1];
if(h->slice_type_nos != AV_PICTURE_TYPE_I){
- unsigned max= (16<<(s->picture_structure != PICT_FRAME))-1;
+ unsigned max= s->picture_structure == PICT_FRAME ? 15 : 31;
+
if(h->slice_type_nos == AV_PICTURE_TYPE_B){
h->direct_spatial_mv_pred= get_bits1(&s->gb);
}
@@ -2896,13 +2897,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
h->ref_count[0]= get_ue_golomb(&s->gb) + 1;
if(h->slice_type_nos==AV_PICTURE_TYPE_B)
h->ref_count[1]= get_ue_golomb(&s->gb) + 1;
-
}
- if(h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){
+
+ if (h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){
av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");
- h->ref_count[0]= h->ref_count[1]= 1;
- return -1;
+ h->ref_count[0] = h->ref_count[1] = 1;
+ return AVERROR_INVALIDDATA;
}
+
if(h->slice_type_nos == AV_PICTURE_TYPE_B)
h->list_count= 2;
else
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 55152d772d..b91883a8f5 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -1959,6 +1959,8 @@ decode_intra_mb:
}
// The pixels are stored in the same order as levels in h->mb array.
+ if ((int) (h->cabac.bytestream_end - ptr) < mb_size)
+ return -1;
memcpy(h->mb, ptr, mb_size); ptr+=mb_size;
ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr);
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index d560d3f86a..0d6aeccdb2 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -251,6 +251,12 @@ static int h264_parse(AVCodecParserContext *s,
h->got_first = 1;
if (avctx->extradata_size) {
h->s.avctx = avctx;
+ // must be done like in decoder, otherwise opening the parser,
+ // letting it create extradata and then closing and opening again
+ // will cause has_b_frames to be always set.
+ // Note that estimate_timings_from_pts does exactly this.
+ if (!avctx->has_b_frames)
+ h->s.low_delay = 1;
ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size);
}
}
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index 0f59421bb7..b69be258f9 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -82,13 +82,15 @@ 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
};
-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
@@ -184,7 +186,7 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb){
if(repeat==0)
repeat= get_bits(gb, 8);
//printf("%d %d\n", val, repeat);
- if(i+repeat > 256) {
+ if(i+repeat > 256 || get_bits_left(gb) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n");
return -1;
}
@@ -366,10 +368,10 @@ static int read_old_huffman_tables(HYuvContext *s){
GetBitContext gb;
int i;
- init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*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);
+ init_get_bits(&gb, classic_shift_chroma, classic_shift_chroma_table_size*8);
if(read_len_table(s->len[1], &gb)<0)
return -1;
@@ -515,7 +517,7 @@ s->bgr32=1;
}
break;
default:
- assert(0);
+ return AVERROR_INVALIDDATA;
}
alloc_temp(s);
diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c
index f1fdee5d43..288e53c9d8 100644
--- a/libavcodec/jvdec.c
+++ b/libavcodec/jvdec.c
@@ -150,7 +150,7 @@ static int decode_frame(AVCodecContext *avctx,
if (video_type == 0 || video_type == 1) {
GetBitContext gb;
- init_get_bits(&gb, buf, FFMIN(video_size, (buf_end - buf) * 8));
+ init_get_bits(&gb, buf, 8 * FFMIN(video_size, buf_end - buf));
for (j = 0; j < avctx->height; j += 8)
for (i = 0; i < avctx->width; i += 8)
diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c
index 3e3922774e..264efa2a29 100644
--- a/libavcodec/kgv1dec.c
+++ b/libavcodec/kgv1dec.c
@@ -30,19 +30,26 @@
typedef struct {
AVCodecContext *avctx;
- AVFrame pic;
- uint16_t *prev, *cur;
+ AVFrame prev, cur;
} KgvContext;
+static void decode_flush(AVCodecContext *avctx)
+{
+ KgvContext * const c = avctx->priv_data;
+
+ if (c->prev.data[0])
+ avctx->release_buffer(avctx, &c->prev);
+}
+
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
const uint8_t *buf_end = buf + avpkt->size;
KgvContext * const c = avctx->priv_data;
- int offsets[7];
+ int offsets[8];
uint16_t *out, *prev;
int outcnt = 0, maxcnt;
- int w, h, i;
+ int w, h, i, res;
if (avpkt->size < 2)
return -1;
@@ -54,22 +61,25 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
if (av_image_check_size(w, h, 0, avctx))
return -1;
- if (w != avctx->width || h != avctx->height)
+ if (w != avctx->width || h != avctx->height) {
+ if (c->prev.data[0])
+ avctx->release_buffer(avctx, &c->prev);
avcodec_set_dimensions(avctx, w, h);
+ }
maxcnt = w * h;
- out = av_realloc(c->cur, w * h * 2);
- if (!out)
- return -1;
- c->cur = out;
-
- prev = av_realloc(c->prev, w * h * 2);
- if (!prev)
- return -1;
- c->prev = prev;
+ c->cur.reference = 3;
+ if ((res = avctx->get_buffer(avctx, &c->cur)) < 0)
+ return res;
+ out = (uint16_t *) c->cur.data[0];
+ if (c->prev.data[0]) {
+ prev = (uint16_t *) c->prev.data[0];
+ } else {
+ prev = NULL;
+ }
- for (i = 0; i < 7; i++)
+ for (i = 0; i < 8; i++)
offsets[i] = -1;
while (outcnt < maxcnt && buf_end - 2 > buf) {
@@ -80,6 +90,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
out[outcnt++] = code; // rgb555 pixel coded directly
} else {
int count;
+ int inp_off;
uint16_t *inp;
if ((code & 0x6000) == 0x6000) {
@@ -101,7 +112,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
if (maxcnt - start < count)
break;
- inp = prev + start;
+ if (!prev) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Frame reference does not exist\n");
+ break;
+ }
+
+ inp = prev;
+ inp_off = start;
} else {
// copy from earlier in this frame
int offset = (code & 0x1FFF) + 1;
@@ -119,27 +137,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
if (outcnt < offset)
break;
- inp = out + outcnt - offset;
+ inp = out;
+ inp_off = outcnt - offset;
}
if (maxcnt - outcnt < count)
break;
- for (i = 0; i < count; i++)
+ for (i = inp_off; i < count + inp_off; i++) {
out[outcnt++] = inp[i];
+ }
}
}
if (outcnt - maxcnt)
av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt);
- c->pic.data[0] = (uint8_t *)c->cur;
- c->pic.linesize[0] = w * 2;
-
*data_size = sizeof(AVFrame);
- *(AVFrame*)data = c->pic;
+ *(AVFrame*)data = c->cur;
- FFSWAP(uint16_t *, c->cur, c->prev);
+ if (c->prev.data[0])
+ avctx->release_buffer(avctx, &c->prev);
+ FFSWAP(AVFrame, c->cur, c->prev);
return avpkt->size;
}
@@ -150,29 +169,25 @@ static av_cold int decode_init(AVCodecContext *avctx)
c->avctx = avctx;
avctx->pix_fmt = PIX_FMT_RGB555;
- avcodec_get_frame_defaults(&c->pic);
+ avctx->flags |= CODEC_FLAG_EMU_EDGE;
return 0;
}
static av_cold int decode_end(AVCodecContext *avctx)
{
- KgvContext * const c = avctx->priv_data;
-
- av_freep(&c->cur);
- av_freep(&c->prev);
-
+ decode_flush(avctx);
return 0;
}
AVCodec ff_kgv1_decoder = {
- "kgv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_KGV1,
- sizeof(KgvContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
+ .name = "kgv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_KGV1,
+ .priv_data_size = sizeof(KgvContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .flush = decode_flush,
.long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"),
};
diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c
index aa2aaace6c..3681575daa 100644
--- a/libavcodec/kmvc.c
+++ b/libavcodec/kmvc.c
@@ -57,17 +57,21 @@ typedef struct BitBuf {
#define kmvc_init_getbits(bb, src) bb.bits = 7; bb.bitbuf = *src++;
-#define kmvc_getbit(bb, src, res) {\
+#define kmvc_getbit(bb, src, src_end, res) {\
res = 0; \
if (bb.bitbuf & (1 << bb.bits)) res = 1; \
bb.bits--; \
if(bb.bits == -1) { \
+ if (src >= src_end) { \
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); \
+ return AVERROR_INVALIDDATA; \
+ } \
bb.bitbuf = *src++; \
bb.bits = 7; \
} \
}
-static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h)
+static int kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int src_size, int w, int h)
{
BitBuf bb;
int res, val;
@@ -75,13 +79,18 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w,
int bx, by;
int l0x, l1x, l0y, l1y;
int mx, my;
+ const uint8_t *src_end = src + src_size;
kmvc_init_getbits(bb, src);
for (by = 0; by < h; by += 8)
for (bx = 0; bx < w; bx += 8) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 8x8 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
for (i = 0; i < 64; i++)
BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
@@ -89,14 +98,22 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w,
for (i = 0; i < 4; i++) {
l0x = bx + (i & 1) * 4;
l0y = by + (i & 2) * 2;
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 4x4 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
for (j = 0; j < 16; j++)
BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
} else { // copy block from already decoded place
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
mx = val & 0xF;
my = val >> 4;
@@ -108,16 +125,24 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w,
for (j = 0; j < 4; j++) {
l1x = l0x + (j & 1) * 2;
l1y = l0y + (j & 2);
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 2x2 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
BLK(ctx->cur, l1x, l1y) = val;
BLK(ctx->cur, l1x + 1, l1y) = val;
BLK(ctx->cur, l1x, l1y + 1) = val;
BLK(ctx->cur, l1x + 1, l1y + 1) = val;
} else { // copy block from already decoded place
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
mx = val & 0xF;
my = val >> 4;
@@ -140,9 +165,11 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w,
}
}
}
+
+ return 0;
}
-static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h)
+static int kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int src_size, int w, int h)
{
BitBuf bb;
int res, val;
@@ -150,15 +177,20 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w,
int bx, by;
int l0x, l1x, l0y, l1y;
int mx, my;
+ const uint8_t *src_end = src + src_size;
kmvc_init_getbits(bb, src);
for (by = 0; by < h; by += 8)
for (bx = 0; bx < w; bx += 8) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 8x8 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
for (i = 0; i < 64; i++)
BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
@@ -171,14 +203,22 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w,
for (i = 0; i < 4; i++) {
l0x = bx + (i & 1) * 4;
l0y = by + (i & 2) * 2;
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 4x4 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
for (j = 0; j < 16; j++)
BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
} else { // copy block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
mx = (val & 0xF) - 8;
my = (val >> 4) - 8;
@@ -190,16 +230,24 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w,
for (j = 0; j < 4; j++) {
l1x = l0x + (j & 1) * 2;
l1y = l0y + (j & 2);
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) {
- kmvc_getbit(bb, src, res);
+ kmvc_getbit(bb, src, src_end, res);
if (!res) { // fill whole 2x2 block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
BLK(ctx->cur, l1x, l1y) = val;
BLK(ctx->cur, l1x + 1, l1y) = val;
BLK(ctx->cur, l1x, l1y + 1) = val;
BLK(ctx->cur, l1x + 1, l1y + 1) = val;
} else { // copy block
+ if (src >= src_end) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
+ return AVERROR_INVALIDDATA;
+ }
val = *src++;
mx = (val & 0xF) - 8;
my = (val >> 4) - 8;
@@ -222,6 +270,8 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w,
}
}
}
+
+ return 0;
}
static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt)
@@ -299,10 +349,10 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa
memcpy(ctx->cur, ctx->prev, 320 * 200);
break;
case 3:
- kmvc_decode_intra_8x8(ctx, buf, avctx->width, avctx->height);
+ kmvc_decode_intra_8x8(ctx, buf, buf_size, avctx->width, avctx->height);
break;
case 4:
- kmvc_decode_inter_8x8(ctx, buf, avctx->width, avctx->height);
+ kmvc_decode_inter_8x8(ctx, buf, buf_size, avctx->width, avctx->height);
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD);
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index 57735ac6ff..8f753ea088 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -223,8 +223,29 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
len = mszh_dlen;
}
break;
- case COMP_MSZH_NOCOMP:
+ case COMP_MSZH_NOCOMP: {
+ int bppx2;
+ switch (c->imgtype) {
+ case IMGTYPE_YUV111:
+ case IMGTYPE_RGB24:
+ bppx2 = 6;
+ break;
+ case IMGTYPE_YUV422:
+ case IMGTYPE_YUV211:
+ bppx2 = 4;
+ break;
+ case IMGTYPE_YUV411:
+ case IMGTYPE_YUV420:
+ bppx2 = 3;
+ break;
+ default:
+ bppx2 = 0; // will error out below
+ break;
+ }
+ if (len < ((width * height * bppx2) >> 1))
+ return AVERROR_INVALIDDATA;
break;
+ }
default:
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
return -1;
@@ -456,7 +477,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
avcodec_get_frame_defaults(&c->pic);
if (avctx->extradata_size < 8) {
av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
- return 1;
+ return AVERROR_INVALIDDATA;
}
/* Check codec type */
@@ -505,7 +526,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
- return 1;
+ return AVERROR_INVALIDDATA;
}
/* Detect compression method */
@@ -522,7 +543,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression);
- return 1;
+ return AVERROR_INVALIDDATA;
}
break;
#if CONFIG_ZLIB_DECODER
@@ -540,7 +561,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
default:
if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) {
av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression);
- return 1;
+ return AVERROR_INVALIDDATA;
}
av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression);
}
@@ -548,14 +569,14 @@ static av_cold int decode_init(AVCodecContext *avctx)
#endif
default:
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
- return 1;
+ return AVERROR_INVALIDDATA;
}
/* Allocate decompression buffer */
if (c->decomp_size) {
if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) {
av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
- return 1;
+ return AVERROR(ENOMEM);
}
}
@@ -581,7 +602,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
if (zret != Z_OK) {
av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
av_freep(&c->decomp_buf);
- return 1;
+ return AVERROR_INVALIDDATA;
}
}
#endif
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c
index 5f863433ef..3d5c490686 100644
--- a/libavcodec/mjpegbdec.c
+++ b/libavcodec/mjpegbdec.c
@@ -59,6 +59,9 @@ read_header:
s->restart_count = 0;
s->mjpb_skiptosod = 0;
+ if (buf_end - buf_ptr >= 1 << 28)
+ return AVERROR_INVALIDDATA;
+
init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8);
skip_bits(&hgb, 32); /* reserved zeros */
@@ -66,7 +69,7 @@ read_header:
if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g'))
{
av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n");
- return 0;
+ return AVERROR_INVALIDDATA;
}
field_size = get_bits_long(&hgb, 32); /* field size */
@@ -109,8 +112,8 @@ read_header:
av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs);
if (sos_offs)
{
-// init_get_bits(&s->gb, buf+sos_offs, (buf_end - (buf+sos_offs))*8);
- init_get_bits(&s->gb, buf_ptr+sos_offs, field_size*8);
+ init_get_bits(&s->gb, buf_ptr + sos_offs,
+ 8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs));
s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16));
s->start_code = SOS;
ff_mjpeg_decode_sos(s, NULL, NULL);
@@ -142,7 +145,7 @@ read_header:
picture->quality*= FF_QP2LAMBDA;
}
- return buf_ptr - buf;
+ return buf_size;
}
AVCodec ff_mjpegb_decoder = {
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index e000df8efd..06bebb13bb 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -1816,6 +1816,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx)
extradata += 4;
s->checksum_size = AV_RB32(extradata);
+ if (s->checksum_size >= 1U << 28) {
+ av_log(avctx, AV_LOG_ERROR, "data block size too large (%u)\n", s->checksum_size);
+ return AVERROR_INVALIDDATA;
+ }
s->fft_order = av_log2(s->fft_size) + 1;
s->fft_frame_size = 2 * s->fft_size; // complex has two floats
diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
index 124106fc16..58f842a092 100644
--- a/libavcodec/qtrle.c
+++ b/libavcodec/qtrle.c
@@ -419,7 +419,7 @@ static av_cold int qtrle_decode_init(AVCodecContext *avctx)
default:
av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
avctx->bits_per_coded_sample);
- break;
+ return AVERROR_INVALIDDATA;
}
avcodec_get_frame_defaults(&s->frame);
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index 503351e68a..1c1f52f3a9 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -151,6 +151,9 @@ static int raw_decode(AVCodecContext *avctx,
frame->top_field_first = context->tff;
}
+ if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0))
+ return -1;
+
//2bpp and 4bpp raw in avi and mov (yes this is ugly ...)
if (context->buffer) {
int i;
@@ -175,9 +178,6 @@ static int raw_decode(AVCodecContext *avctx,
avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))
buf += buf_size - context->length;
- if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0))
- return -1;
-
avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height);
if((avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length) ||
(avctx->pix_fmt!=PIX_FMT_PAL8 &&
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index 12558563c6..d8082f6d8e 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -183,6 +183,8 @@ static void rpza_decode_stream(RpzaContext *s)
color4[1] |= ((11 * ta + 21 * tb) >> 5);
color4[2] |= ((21 * ta + 11 * tb) >> 5);
+ if (s->size - stream_ptr < n_blocks * 4)
+ return;
while (n_blocks--) {
block_ptr = row_ptr + pixel_ptr;
for (pixel_y = 0; pixel_y < 4; pixel_y++) {
@@ -200,6 +202,8 @@ static void rpza_decode_stream(RpzaContext *s)
/* Fill block with 16 colors */
case 0x00:
+ if (s->size - stream_ptr < 16)
+ return;
block_ptr = row_ptr + pixel_ptr;
for (pixel_y = 0; pixel_y < 4; pixel_y++) {
for (pixel_x = 0; pixel_x < 4; pixel_x++){
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 189b79f4d0..adb7eeb416 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -672,8 +672,12 @@ static int rv10_decode_frame(AVCodecContext *avctx,
if(!avctx->slice_count){
slice_count = (*buf++) + 1;
+ buf_size--;
slices_hdr = buf + 4;
buf += 8 * slice_count;
+ buf_size -= 8 * slice_count;
+ if (buf_size <= 0)
+ return AVERROR_INVALIDDATA;
}else
slice_count = avctx->slice_count;
@@ -712,7 +716,7 @@ static int rv10_decode_frame(AVCodecContext *avctx,
s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
}
- return buf_size;
+ return avpkt->size;
}
AVCodec ff_rv10_decoder = {
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index 621281fc75..50332aaf68 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -131,7 +131,8 @@ static int allocate_buffers(ShortenContext *s)
return AVERROR(ENOMEM);
s->offset[chan] = tmp_ptr;
- tmp_ptr = av_realloc(s->decoded_base[chan], sizeof(int32_t)*(s->blocksize + s->nwrap));
+ tmp_ptr = av_realloc(s->decoded_base[chan], (s->blocksize + s->nwrap) *
+ sizeof(s->decoded_base[0][0]));
if (!tmp_ptr)
return AVERROR(ENOMEM);
s->decoded_base[chan] = tmp_ptr;
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index 0b7a19aa32..ae01b9928b 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -127,12 +127,12 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref
*/
static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx)
{
+ if (hc->current + 1 >= hc->length) {
+ av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n");
+ return -1;
+ }
if(!get_bits1(gb)){ //Leaf
int val, i1, i2, b1, b2;
- if(hc->current >= hc->length){
- av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n");
- return -1;
- }
b1 = get_bits_count(gb);
i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) : 0;
b1 = get_bits_count(gb) - b1;
@@ -156,7 +156,7 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx
hc->values[hc->current++] = val;
return 1;
} else { //Node
- int r = 0, t;
+ int r = 0, r_new, t;
t = hc->current++;
r = smacker_decode_bigtree(gb, hc, ctx);
@@ -164,8 +164,10 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx
return r;
hc->values[t] = SMK_NODE | r;
r++;
- r += smacker_decode_bigtree(gb, hc, ctx);
- return r;
+ r_new = smacker_decode_bigtree(gb, hc, ctx);
+ if (r_new < 0)
+ return r_new;
+ return r + r_new;
}
}
@@ -180,6 +182,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
VLC vlc[2];
int escapes[3];
DBCtx ctx;
+ int err = 0;
if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow
av_log(smk->avctx, AV_LOG_ERROR, "size too large\n");
@@ -253,7 +256,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
huff.current = 0;
huff.values = av_mallocz(huff.length * sizeof(int));
- smacker_decode_bigtree(gb, &huff, &ctx);
+ if (smacker_decode_bigtree(gb, &huff, &ctx) < 0)
+ err = -1;
skip_bits1(gb);
if(ctx.last[0] == -1) ctx.last[0] = huff.current++;
if(ctx.last[1] == -1) ctx.last[1] = huff.current++;
@@ -272,7 +276,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int
av_free(tmp2.lengths);
av_free(tmp2.values);
- return 0;
+ return err;
}
static int decode_header_trees(SmackVContext *smk) {
diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c
index aa73f4c7bf..b6f2dade0c 100644
--- a/libavcodec/srtdec.c
+++ b/libavcodec/srtdec.c
@@ -110,7 +110,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end,
for (j=sptr-2; j>=0; j--)
if (stack[j].param[i][0]) {
out += snprintf(out, out_end-out,
- stack[j].param[i]);
+ "%s", stack[j].param[i]);
break;
}
} else {
@@ -146,7 +146,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end,
for (i=0; i<PARAM_NUMBER; i++)
if (stack[sptr].param[i][0])
out += snprintf(out, out_end-out,
- stack[sptr].param[i]);
+ "%s", stack[sptr].param[i]);
}
} else if (!buffer[1] && strspn(buffer, "bisu") == 1) {
out += snprintf(out, out_end-out,
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index 2deb16ad3c..eb883b4f4f 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -811,7 +811,9 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
MpegEncContext *s = &h->s;
int m;
unsigned char *extradata;
+ unsigned char *extradata_end;
unsigned int size;
+ int marker_found = 0;
if (ff_h264_decode_init(avctx) < 0)
return -1;
@@ -832,19 +834,26 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
/* prowl for the "SEQH" marker in the extradata */
extradata = (unsigned char *)avctx->extradata;
- for (m = 0; m < avctx->extradata_size; m++) {
- if (!memcmp(extradata, "SEQH", 4))
- break;
- extradata++;
+ extradata_end = avctx->extradata + avctx->extradata_size;
+ if (extradata) {
+ for (m = 0; m + 8 < avctx->extradata_size; m++) {
+ if (!memcmp(extradata, "SEQH", 4)) {
+ marker_found = 1;
+ break;
+ }
+ extradata++;
+ }
}
/* if a match was found, parse the extra data */
- if (extradata && !memcmp(extradata, "SEQH", 4)) {
+ if (marker_found) {
GetBitContext gb;
int frame_size_code;
size = AV_RB32(&extradata[4]);
+ if (size > extradata_end - extradata - 8)
+ return AVERROR_INVALIDDATA;
init_get_bits(&gb, extradata + 8, size*8);
/* 'frame size code' and optional 'width, height' */
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index ed01b70147..e43cecb22c 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -56,24 +56,24 @@ typedef struct TiffContext {
LZWState *lzw;
} TiffContext;
-static int tget_short(const uint8_t **p, int le){
- int v = le ? AV_RL16(*p) : AV_RB16(*p);
+static unsigned tget_short(const uint8_t **p, int le) {
+ unsigned v = le ? AV_RL16(*p) : AV_RB16(*p);
*p += 2;
return v;
}
-static int tget_long(const uint8_t **p, int le){
- int v = le ? AV_RL32(*p) : AV_RB32(*p);
+static unsigned tget_long(const uint8_t **p, int le) {
+ unsigned v = le ? AV_RL32(*p) : AV_RB32(*p);
*p += 4;
return v;
}
-static int tget(const uint8_t **p, int type, int le){
+static unsigned tget(const uint8_t **p, int type, int le) {
switch(type){
case TIFF_BYTE : return *(*p)++;
case TIFF_SHORT: return tget_short(p, le);
case TIFF_LONG : return tget_long (p, le);
- default : return -1;
+ default : return UINT_MAX;
}
}
@@ -274,7 +274,7 @@ static int init_image(TiffContext *s)
static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf)
{
- int tag, type, count, off, value = 0;
+ unsigned tag, type, count, off, value = 0;
int i, j;
uint32_t *pal;
const uint8_t *rp, *gp, *bp;
@@ -286,6 +286,11 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *
count = tget_long(&buf, s->le);
off = tget_long(&buf, s->le);
+ if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {
+ av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n", type);
+ return 0;
+ }
+
if(count == 1){
switch(type){
case TIFF_BYTE:
@@ -304,13 +309,15 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *
break;
}
default:
- value = -1;
+ value = UINT_MAX;
+ buf = start + off;
+ }
+ } else {
+ if (count <= 4 && type_sizes[type] * count <= 4) {
+ buf -= 4;
+ } else {
buf = start + off;
}
- }else if(type_sizes[type] * count <= 4){
- buf -= 4;
- }else{
- buf = start + off;
}
if(buf && (buf < start || buf > end_buf)){
@@ -388,7 +395,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *
}
break;
case TIFF_ROWSPERSTRIP:
- if(type == TIFF_LONG && value == -1)
+ if (type == TIFF_LONG && value == UINT_MAX)
value = s->avctx->height;
if(value < 1){
av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n");
@@ -526,6 +533,8 @@ static int decode_frame(AVCodecContext *avctx,
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) {
diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c
index 2b9a0cba72..c753a0806e 100644
--- a/libavcodec/truemotion2.c
+++ b/libavcodec/truemotion2.c
@@ -132,7 +132,7 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code)
huff.val_bits, huff.max_bits);
return -1;
}
- if((huff.nodes < 0) || (huff.nodes > 0x10000)) {
+ if((huff.nodes <= 0) || (huff.nodes > 0x10000)) {
av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree nodes: %i\n", huff.nodes);
return -1;
}
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index 6455d86f77..50f5f51501 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -484,6 +484,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp);
+ return AVERROR_INVALIDDATA;
}
return 0;
diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c
index 731463d1bc..8f21cc2613 100644
--- a/libavcodec/vorbis.c
+++ b/libavcodec/vorbis.c
@@ -150,7 +150,7 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values)
}
}
-static inline void render_line_unrolled(intptr_t x, uint8_t y, int x1,
+static inline void render_line_unrolled(intptr_t x, int y, int x1,
intptr_t sy, int ady, int adx,
float *buf)
{
@@ -162,30 +162,30 @@ static inline void render_line_unrolled(intptr_t x, uint8_t y, int x1,
if (err >= 0) {
err += ady - adx;
y += sy;
- buf[x++] = ff_vorbis_floor1_inverse_db_table[y];
+ buf[x++] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)];
}
- buf[x] = ff_vorbis_floor1_inverse_db_table[y];
+ buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)];
}
if (x <= 0) {
if (err + ady >= 0)
y += sy;
- buf[x] = ff_vorbis_floor1_inverse_db_table[y];
+ buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)];
}
}
-static void render_line(int x0, uint8_t y0, int x1, int y1, float *buf)
+static void render_line(int x0, int y0, int x1, int y1, float *buf)
{
int dy = y1 - y0;
int adx = x1 - x0;
int ady = FFABS(dy);
int sy = dy < 0 ? -1 : 1;
- buf[x0] = ff_vorbis_floor1_inverse_db_table[y0];
+ buf[x0] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y0)];
if (ady*2 <= adx) { // optimized common case
render_line_unrolled(x0, y0, x1, sy, ady, adx, buf);
} else {
int base = dy / adx;
int x = x0;
- uint8_t y = y0;
+ int y = y0;
int err = -adx;
ady -= FFABS(base) * adx;
while (++x < x1) {
@@ -195,7 +195,7 @@ static void render_line(int x0, uint8_t y0, int x1, int y1, float *buf)
err -= adx;
y += sy;
}
- buf[x] = ff_vorbis_floor1_inverse_db_table[y];
+ buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)];
}
}
}
@@ -204,8 +204,7 @@ void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values,
uint16_t *y_list, int *flag,
int multiplier, float *out, int samples)
{
- int lx, i;
- uint8_t ly;
+ int lx, ly, i;
lx = 0;
ly = y_list[0] * multiplier;
for (i = 1; i < values; i++) {
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index ddb9bd6d5d..4038a6b2f7 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -1232,20 +1232,20 @@ static int vorbis_floor1_decode(vorbis_context *vc,
floor1_flag[i] = 1;
if (val >= room) {
if (highroom > lowroom) {
- floor1_Y_final[i] = val - lowroom + predicted;
+ floor1_Y_final[i] = av_clip_uint16(val - lowroom + predicted);
} else {
- floor1_Y_final[i] = predicted - val + highroom - 1;
+ floor1_Y_final[i] = av_clip_uint16(predicted - val + highroom - 1);
}
} else {
if (val & 1) {
- floor1_Y_final[i] = predicted - (val + 1) / 2;
+ floor1_Y_final[i] = av_clip_uint16(predicted - (val + 1) / 2);
} else {
- floor1_Y_final[i] = predicted + val / 2;
+ floor1_Y_final[i] = av_clip_uint16(predicted + val / 2);
}
}
} else {
floor1_flag[i] = 0;
- floor1_Y_final[i] = predicted;
+ floor1_Y_final[i] = av_clip_uint16(predicted);
}
av_dlog(NULL, " Decoded floor(%d) = %u / val %u\n",
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index 47a82e0253..9a89f5d216 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -55,6 +55,11 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
}
rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */
cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */
+ if (!rows || !cols) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n",
+ cols << 4, rows << 4);
+ return 0;
+ }
vp56_rac_gets(c, 8); /* number of displayed macroblock rows */
vp56_rac_gets(c, 8); /* number of displayed macroblock cols */
vp56_rac_gets(c, 2);
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index bcb437db57..8294c72dc0 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -75,6 +75,10 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
cols = buf[3]; /* number of stored macroblock cols */
/* buf[4] is number of displayed macroblock rows */
/* buf[5] is number of displayed macroblock cols */
+ if (!rows || !cols) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4);
+ return 0;
+ }
if (!s->macroblocks || /* first frame */
16*cols != s->avctx->coded_width ||
@@ -95,7 +99,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
vrt_shift = 5;
s->sub_version = sub_version;
} else {
- if (!s->sub_version)
+ if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height)
return 0;
if (separated_coeff || !s->filter_header) {
diff --git a/libavcodec/wma.c b/libavcodec/wma.c
index 8f464619c2..feb121b591 100644
--- a/libavcodec/wma.c
+++ b/libavcodec/wma.c
@@ -85,7 +85,7 @@ int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version,
} else if (sample_rate <= 22050 ||
(sample_rate <= 32000 && version == 1)) {
frame_len_bits = 10;
- } else if (sample_rate <= 48000) {
+ } else if (sample_rate <= 48000 || version < 3) {
frame_len_bits = 11;
} else if (sample_rate <= 96000) {
frame_len_bits = 12;
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index 11895a3996..11740203fb 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -364,7 +364,7 @@ static int decode_exp_vlc(WMACodecContext *s, int ch)
}
/* NOTE: this offset is the same as MPEG4 AAC ! */
last_exp += code - 60;
- if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) {
+ if ((unsigned)last_exp + 60 >= FF_ARRAY_ELEMS(pow_tab)) {
av_log(s->avctx, AV_LOG_ERROR, "Exponent out of range: %d\n",
last_exp);
return -1;
@@ -882,6 +882,8 @@ static int wma_decode_superframe(AVCodecContext *avctx,
/* read each frame starting from bit_offset */
pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3;
+ if (pos >= MAX_CODED_SUPERFRAME_SIZE * 8)
+ return AVERROR_INVALIDDATA;
init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8);
len = pos & 7;
if (len > 0)
diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c
index 0bafe1a64d..0a3264afc6 100644
--- a/libavcodec/wmaenc.c
+++ b/libavcodec/wmaenc.c
@@ -39,6 +39,12 @@ static int encode_init(AVCodecContext * avctx){
return AVERROR(EINVAL);
}
+ if (avctx->sample_rate > 48000) {
+ av_log(avctx, AV_LOG_ERROR, "sample rate is too high: %d > 48kHz",
+ avctx->sample_rate);
+ return AVERROR(EINVAL);
+ }
+
if(avctx->bit_rate < 24*1000) {
av_log(avctx, AV_LOG_ERROR, "bitrate too low: got %i, need 24000 or higher\n",
avctx->bit_rate);
@@ -64,6 +70,8 @@ static int encode_init(AVCodecContext * avctx){
s->use_exp_vlc = flags2 & 0x0001;
s->use_bit_reservoir = flags2 & 0x0002;
s->use_variable_block_len = flags2 & 0x0004;
+ if (avctx->channels == 2)
+ s->ms_stereo = 1;
ff_wma_init(avctx, flags2);
@@ -71,8 +79,12 @@ static int encode_init(AVCodecContext * avctx){
for(i = 0; i < s->nb_block_sizes; i++)
ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0, 1.0);
- avctx->block_align=
- s->block_align= avctx->bit_rate*(int64_t)s->frame_len / (avctx->sample_rate*8);
+ s->block_align = avctx->bit_rate * (int64_t)s->frame_len /
+ (avctx->sample_rate * 8);
+ s->block_align = FFMIN(s->block_align, MAX_CODED_SUPERFRAME_SIZE);
+ avctx->block_align = s->block_align;
+ avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate /
+ s->frame_len;
//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", s->block_align, avctx->bit_rate, s->frame_len, avctx->sample_rate);
avctx->frame_size= s->frame_len;
@@ -181,7 +193,7 @@ static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE],
}
if (s->nb_channels == 2) {
- put_bits(&s->pb, 1, s->ms_stereo= 1);
+ put_bits(&s->pb, 1, !!s->ms_stereo);
}
for(ch = 0; ch < s->nb_channels; ch++) {
@@ -355,6 +367,11 @@ static int encode_superframe(AVCodecContext *avctx,
}
}
+ if (buf_size < 2 * MAX_CODED_SUPERFRAME_SIZE) {
+ av_log(avctx, AV_LOG_ERROR, "output buffer size is too small\n");
+ return AVERROR(EINVAL);
+ }
+
#if 1
total_gain= 128;
for(i=64; i; i>>=1){
diff --git a/libavcodec/x86/h264_deblock_10bit.asm b/libavcodec/x86/h264_deblock_10bit.asm
index ee316258d3..dc3a26c355 100644
--- a/libavcodec/x86/h264_deblock_10bit.asm
+++ b/libavcodec/x86/h264_deblock_10bit.asm
@@ -876,7 +876,7 @@ cglobal deblock_v_chroma_10_%1, 5,7-(mmsize/16),8*(mmsize/16)
%if mmsize < 16
add r0, mmsize
add r5, mmsize
- add r4, mmsize/8
+ add r4, mmsize/4
dec r6
jg .loop
REP_RET
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index be8885d904..53f62dea96 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -196,6 +196,8 @@ static int asf_read_file_properties(AVFormatContext *s, int64_t size)
asf->hdr.flags = avio_rl32(pb);
asf->hdr.min_pktsize = avio_rl32(pb);
asf->hdr.max_pktsize = avio_rl32(pb);
+ if (asf->hdr.min_pktsize >= (1U<<29))
+ return AVERROR_INVALIDDATA;
asf->hdr.max_bitrate = avio_rl32(pb);
s->packet_size = asf->hdr.max_pktsize;
@@ -609,7 +611,9 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (gsize < 24)
return -1;
if (!ff_guidcmp(&g, &ff_asf_file_header)) {
- asf_read_file_properties(s, gsize);
+ int ret = asf_read_file_properties(s, gsize);
+ if (ret < 0)
+ return ret;
} else if (!ff_guidcmp(&g, &ff_asf_stream_header)) {
asf_read_stream_properties(s, gsize);
} else if (!ff_guidcmp(&g, &ff_asf_comment_header)) {
@@ -750,7 +754,7 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
c= avio_r8(pb);
d= avio_r8(pb);
rsize+=3;
- }else{
+ } else if (!pb->eof_reached) {
avio_seek(pb, -1, SEEK_CUR); //FIXME
}
@@ -782,6 +786,13 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
asf->packet_segments = 1;
asf->packet_segsizetype = 0x80;
}
+ if (rsize > packet_length - padsize) {
+ asf->packet_size_left = 0;
+ av_log(s, AV_LOG_ERROR,
+ "invalid packet header length %d for pktlen %d-%d at %"PRId64"\n",
+ rsize, packet_length, padsize, avio_tell(pb));
+ return -1;
+ }
asf->packet_size_left = packet_length - padsize - rsize;
if (packet_length < asf->hdr.min_pktsize)
padsize += asf->hdr.min_pktsize - packet_length;
diff --git a/libavformat/dv.c b/libavformat/dv.c
index 750c950df8..b02009c8e4 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -119,16 +119,23 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
if (quant > 1)
return -1; /* unsupported quantization */
+ if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency))
+ return AVERROR_INVALIDDATA;
+
size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */
half_ch = sys->difseg_size / 2;
/* We work with 720p frames split in half, thus even frames have
* channels 0,1 and odd 2,3. */
ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0;
- pcm = ppcm[ipcm++];
/* for each DIF channel */
for (chan = 0; chan < sys->n_difchan; chan++) {
+ /* next stereo channel (50Mbps and 100Mbps only) */
+ pcm = ppcm[ipcm++];
+ if (!pcm)
+ break;
+
/* for each DIF segment */
for (i = 0; i < sys->difseg_size; i++) {
frame += 6 * 80; /* skip DIF segment header */
@@ -176,11 +183,6 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */
}
}
-
- /* next stereo channel (50Mbps and 100Mbps only) */
- pcm = ppcm[ipcm++];
- if (!pcm)
- break;
}
return size;
@@ -202,6 +204,18 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
stype = (as_pack[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */
quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */
+ if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) {
+ av_log(c->fctx, AV_LOG_ERROR,
+ "Unrecognized audio sample rate index (%d)\n", freq);
+ return 0;
+ }
+
+ if (stype > 3) {
+ av_log(c->fctx, AV_LOG_ERROR, "stype %d is invalid\n", stype);
+ c->ach = 0;
+ return 0;
+ }
+
/* note: ach counts PAIRS of channels (i.e. stereo channels) */
ach = ((int[4]){ 1, 0, 2, 4})[stype];
if (ach == 1 && quant && freq == 2)
@@ -336,7 +350,8 @@ int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;
ppcm[i] = c->audio_buf[i];
}
- dv_extract_audio(buf, ppcm, c->sys);
+ if (c->ach)
+ dv_extract_audio(buf, ppcm, c->sys);
/* We work with 720p frames split in half, thus even frames have
* channels 0,1 and odd 2,3. */
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 930ab5c870..b20501701e 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -224,8 +224,17 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
unsync = flags & 0x80;
- if (isv34 && flags & 0x40) /* Extended header present, just skip over it */
- avio_skip(s->pb, get_size(s->pb, 4));
+ if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */
+ int extlen = get_size(s->pb, 4);
+ if (version == 4)
+ extlen -= 4; // in v2.4 the length includes the length field we just read
+
+ if (extlen < 0) {
+ reason = "invalid extended header length";
+ goto error;
+ }
+ avio_skip(s->pb, extlen);
+ }
while (len >= taghdrlen) {
unsigned int tflags = 0;
diff --git a/libavformat/isom.c b/libavformat/isom.c
index e471ac580f..162ef5369d 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -149,10 +149,13 @@ const AVCodecTag codec_movvideo_tags[] = {
{ CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') }, /* MPEG2 HDV 720p30 */
{ CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 HDV 1080i60 */
{ CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* MPEG2 HDV 1080i50 */
+ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '4') }, /* MPEG2 HDV 720p24 */
{ CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') }, /* MPEG2 HDV 720p25 */
{ CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') }, /* MPEG2 HDV 1080p24 */
{ CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') }, /* MPEG2 HDV 1080p25 */
{ CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') }, /* MPEG2 HDV 1080p30 */
+ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '9') }, /* MPEG2 HDV 720p60 JVC */
+ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', 'a') }, /* MPEG2 HDV 720p50 */
{ CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG2 IMX NTSC 525/60 50mb/s produced by FCP */
{ CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG2 IMX PAL 625/50 50mb/s produced by FCP */
{ CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') }, /* MPEG2 IMX NTSC 525/60 40mb/s produced by FCP */
@@ -183,6 +186,8 @@ const AVCodecTag codec_movvideo_tags[] = {
{ CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') }, /* XDCAM EX 1080p24 VBR */
{ CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') }, /* XDCAM EX 1080p25 VBR */
{ CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') }, /* XDCAM EX 1080p30 VBR */
+ { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', 'd') }, /* XDCAM HD 540p */
+ { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', '2') }, /* XDCAM HD422 540p */
{ CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') }, /* AVID IMX PAL */
{ CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index e45fd90278..ad505f28b4 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -664,16 +664,19 @@ static int ebml_read_float(AVIOContext *pb, int size, double *num)
*/
static int ebml_read_ascii(AVIOContext *pb, int size, char **str)
{
- av_free(*str);
+ char *res;
+
/* EBML strings are usually not 0-terminated, so we allocate one
* byte more, read the string and NULL-terminate it ourselves. */
- if (!(*str = av_malloc(size + 1)))
+ if (!(res = av_malloc(size + 1)))
return AVERROR(ENOMEM);
- if (avio_read(pb, (uint8_t *) *str, size) != size) {
- av_freep(str);
+ if (avio_read(pb, (uint8_t *) res, size) != size) {
+ av_free(res);
return AVERROR(EIO);
}
- (*str)[size] = '\0';
+ (res)[size] = '\0';
+ av_free(*str);
+ *str = res;
return 0;
}
@@ -1427,7 +1430,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap)
} else if (codec_id == CODEC_ID_AAC && !track->codec_priv.size) {
int profile = matroska_aac_profile(track->codec_id);
int sri = matroska_aac_sri(track->audio.samplerate);
- extradata = av_malloc(5);
+ extradata = av_mallocz(5 + FF_INPUT_BUFFER_PADDING_SIZE);
if (extradata == NULL)
return AVERROR(ENOMEM);
extradata[0] = (profile << 3) | ((sri&0x0E) >> 1);
@@ -1836,15 +1839,31 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
if (!track->audio.pkt_cnt) {
if (track->audio.sub_packet_cnt == 0)
track->audio.buf_timecode = timecode;
- if (st->codec->codec_id == CODEC_ID_RA_288)
+ if (st->codec->codec_id == CODEC_ID_RA_288) {
+ if (size < cfs * h / 2) {
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Corrupt int4 RM-style audio packet size\n");
+ return AVERROR_INVALIDDATA;
+ }
for (x=0; x<h/2; x++)
memcpy(track->audio.buf+x*2*w+y*cfs,
data+x*cfs, cfs);
- else if (st->codec->codec_id == CODEC_ID_SIPR)
+ } else if (st->codec->codec_id == CODEC_ID_SIPR) {
+ if (size < w) {
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Corrupt sipr RM-style audio packet size\n");
+ return AVERROR_INVALIDDATA;
+ }
memcpy(track->audio.buf + y*w, data, w);
- else
+ } else {
+ if (size < sps * w / sps) {
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Corrupt generic RM-style audio packet size\n");
+ return AVERROR_INVALIDDATA;
+ }
for (x=0; x<w/sps; x++)
memcpy(track->audio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps);
+ }
if (++track->audio.sub_packet_cnt >= h) {
if (st->codec->codec_id == CODEC_ID_SIPR)
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index 4898187f3a..7791d3aa6e 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -308,7 +308,9 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
char *token, *value;
char quote;
- p = strings = av_mallocz(strings_size + 1);
+ p = strings = av_mallocz((size_t)strings_size + 1);
+ if (!p)
+ return AVERROR(ENOMEM);
endp = strings + strings_size;
avio_read(pb, strings, strings_size);
while (p < endp) {
@@ -343,6 +345,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t))
return -1;
nsv->nsvs_file_offset = av_malloc((unsigned)table_entries_used * sizeof(uint32_t));
+ if (!nsv->nsvs_file_offset)
+ return AVERROR(ENOMEM);
for(i=0;i<table_entries_used;i++)
nsv->nsvs_file_offset[i] = avio_rl32(pb) + size;
@@ -350,6 +354,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap)
if(table_entries > table_entries_used &&
avio_rl32(pb) == MKTAG('T','O','C','2')) {
nsv->nsvs_timestamps = av_malloc((unsigned)table_entries_used*sizeof(uint32_t));
+ if (!nsv->nsvs_timestamps)
+ return AVERROR(ENOMEM);
for(i=0;i<table_entries_used;i++) {
nsv->nsvs_timestamps[i] = avio_rl32(pb);
}
@@ -518,11 +524,16 @@ static int nsv_read_header(AVFormatContext *s, AVFormatParameters *ap)
for (i = 0; i < NSV_MAX_RESYNC_TRIES; i++) {
if (nsv_resync(s) < 0)
return -1;
- if (nsv->state == NSV_FOUND_NSVF)
+ if (nsv->state == NSV_FOUND_NSVF) {
err = nsv_parse_NSVf_header(s, ap);
+ if (err < 0)
+ return err;
+ }
/* we need the first NSVs also... */
if (nsv->state == NSV_FOUND_NSVS) {
err = nsv_parse_NSVs_header(s, ap);
+ if (err < 0)
+ return err;
break; /* we just want the first one */
}
}
@@ -597,12 +608,12 @@ null_chunk_retry:
}
/* map back streams to v,a */
- if (s->streams[0])
+ if (s->nb_streams > 0)
st[s->streams[0]->id] = s->streams[0];
- if (s->streams[1])
+ if (s->nb_streams > 1)
st[s->streams[1]->id] = s->streams[1];
- if (vsize/* && st[NSV_ST_VIDEO]*/) {
+ if (vsize && st[NSV_ST_VIDEO]) {
nst = st[NSV_ST_VIDEO]->priv_data;
pkt = &nsv->ahead[NSV_ST_VIDEO];
av_get_packet(pb, pkt, vsize);
@@ -615,7 +626,7 @@ null_chunk_retry:
if(st[NSV_ST_VIDEO])
((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset++;
- if (asize/*st[NSV_ST_AUDIO]*/) {
+ if (asize && st[NSV_ST_AUDIO]) {
nst = st[NSV_ST_AUDIO]->priv_data;
pkt = &nsv->ahead[NSV_ST_AUDIO];
/* read raw audio specific header on the first audio chunk... */
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index 708187e16f..fec95a5714 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -378,8 +378,19 @@ static int rm_read_index(AVFormatContext *s)
st = s->streams[n];
break;
}
- if (n == s->nb_streams)
+ if (n == s->nb_streams) {
+ av_log(s, AV_LOG_ERROR,
+ "Invalid stream index %d for index at pos %"PRId64"\n",
+ str_id, avio_tell(pb));
goto skip;
+ } else if ((avio_size(pb) - avio_tell(pb)) / 14 < n_pkts) {
+ av_log(s, AV_LOG_ERROR,
+ "Nr. of packets in packet index for stream index %d "
+ "exceeds filesize (%"PRId64" at %"PRId64" = %d)\n",
+ str_id, avio_size(pb), avio_tell(pb),
+ (avio_size(pb) - avio_tell(pb)) / 14);
+ goto skip;
+ }
for (n = 0; n < n_pkts; n++) {
avio_skip(pb, 2);
@@ -391,9 +402,12 @@ static int rm_read_index(AVFormatContext *s)
}
skip:
- if (next_off && avio_tell(pb) != next_off &&
- avio_seek(pb, next_off, SEEK_SET) < 0)
+ if (next_off && avio_tell(pb) < next_off &&
+ avio_seek(pb, next_off, SEEK_SET) < 0) {
+ av_log(s, AV_LOG_ERROR,
+ "Non-linear index detected, not supported\n");
return -1;
+ }
} while (next_off);
return 0;
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index ad6f265c83..80e2fa694e 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -261,8 +261,15 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
sz += (t & 0x7F) + 1;
pal += ((t & 0x7F) + 1) * 3;
} else if(t & 0x40){ /* copy with offset */
- off = avio_r8(s->pb) * 3;
+ off = avio_r8(s->pb);
j = (t & 0x3F) + 1;
+ if (off + j > 0xff) {
+ av_log(s, AV_LOG_ERROR,
+ "Invalid palette update, offset=%d length=%d extends beyond palette size\n",
+ off, j);
+ return AVERROR_INVALIDDATA;
+ }
+ off *= 3;
while(j-- && sz < 256) {
*pal++ = oldpal[off + 0];
*pal++ = oldpal[off + 1];
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
index f90564f3db..f47ad7a8c6 100644
--- a/libavformat/swfdec.c
+++ b/libavformat/swfdec.c
@@ -84,7 +84,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
SWFContext *swf = s->priv_data;
AVIOContext *pb = s->pb;
AVStream *vst = NULL, *ast = NULL, *st = 0;
- int tag, len, i, frame, v;
+ int tag, len, i, frame, v, res;
for(;;) {
uint64_t pos = avio_tell(pb);
@@ -147,7 +147,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
st = s->streams[i];
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) {
frame = avio_rl16(pb);
- av_get_packet(pb, pkt, len-2);
+ if ((res = av_get_packet(pb, pkt, len-2)) < 0)
+ return res;
pkt->pos = pos;
pkt->pts = frame;
pkt->stream_index = st->index;
@@ -160,9 +161,11 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) {
if (st->codec->codec_id == CODEC_ID_MP3) {
avio_skip(pb, 4);
- av_get_packet(pb, pkt, len-4);
+ if ((res = av_get_packet(pb, pkt, len-4)) < 0)
+ return res;
} else { // ADPCM, PCM
- av_get_packet(pb, pkt, len);
+ if ((res = av_get_packet(pb, pkt, len)) < 0)
+ return res;
}
pkt->pos = pos;
pkt->stream_index = st->index;
@@ -186,7 +189,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
st = vst;
}
avio_rl16(pb); /* BITMAP_ID */
- av_new_packet(pkt, len-2);
+ if ((res = av_new_packet(pkt, len-2)) < 0)
+ return res;
avio_read(pb, pkt->data, 4);
if (AV_RB32(pkt->data) == 0xffd8ffd9 ||
AV_RB32(pkt->data) == 0xffd9ffd8) {
diff --git a/libswscale/utils.c b/libswscale/utils.c
index bdbc5bcadc..36bb0fa703 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -272,7 +272,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi
xDstInSrc+= xInc;
}
} else {
- int xDstInSrc;
+ int64_t xDstInSrc;
int sizeFactor;
if (flags&SWS_BICUBIC) sizeFactor= 4;
@@ -291,7 +291,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi
if (xInc <= 1<<16) filterSize= 1 + sizeFactor; // upscale
else filterSize= 1 + (sizeFactor*srcW + dstW - 1)/ dstW;
- if (filterSize > srcW-2) filterSize=srcW-2;
+ filterSize = av_clip(filterSize, 1, srcW - 2);
FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail);
@@ -824,8 +824,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
if (!dstFilter) dstFilter= &dummyFilter;
if (!srcFilter) srcFilter= &dummyFilter;
- c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW;
- c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH;
+ c->lumXInc= (((int64_t)srcW<<16) + (dstW>>1))/dstW;
+ c->lumYInc= (((int64_t)srcH<<16) + (dstH>>1))/dstH;
c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[dstFormat]);
c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[srcFormat]);
c->vRounder= 4* 0x0001000100010001ULL;
@@ -887,8 +887,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
else
c->canMMX2BeUsed=0;
- c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW;
- c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH;
+ c->chrXInc= (((int64_t)c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW;
+ c->chrYInc= (((int64_t)c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH;
// match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst
// but only for the FAST_BILINEAR mode otherwise do correct scaling
@@ -903,8 +903,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
}
//we don't use the x86 asm scaler if MMX is available
else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) {
- c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20;
- c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;
+ c->lumXInc = ((int64_t)(srcW-2)<<16)/(dstW-2) - 20;
+ c->chrXInc = ((int64_t)(c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20;
}
}
@@ -1008,7 +1008,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter)
c->vLumBufSize= c->vLumFilterSize;
c->vChrBufSize= c->vChrFilterSize;
for (i=0; i<dstH; i++) {
- int chrI= (int64_t)i*c->chrDstH / dstH;
+ int chrI = (int64_t) i * c->chrDstH / dstH;
int nextSlice= FFMAX(c->vLumFilterPos[i ] + c->vLumFilterSize - 1,
((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)<<c->chrSrcVSubSample));
diff --git a/libswscale/x86/swscale_mmx.c b/libswscale/x86/swscale_mmx.c
index 775d5f683d..2f54f49f91 100644
--- a/libswscale/x86/swscale_mmx.c
+++ b/libswscale/x86/swscale_mmx.c
@@ -132,6 +132,44 @@ void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufI
const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
int i;
+
+ if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->srcH) {
+ const int16_t **tmpY = (const int16_t **) lumPixBuf + 2 * vLumBufSize;
+ int neg = -firstLumSrcY, i, end = FFMIN(c->srcH - firstLumSrcY, vLumFilterSize);
+ for (i = 0; i < neg; i++)
+ tmpY[i] = lumSrcPtr[neg];
+ for ( ; i < end; i++)
+ tmpY[i] = lumSrcPtr[i];
+ for ( ; i < vLumFilterSize; i++)
+ tmpY[i] = tmpY[i-1];
+ lumSrcPtr = tmpY;
+
+ if (alpSrcPtr) {
+ const int16_t **tmpA = (const int16_t **) alpPixBuf + 2 * vLumBufSize;
+ for (i = 0; i < neg; i++)
+ tmpA[i] = alpSrcPtr[neg];
+ for ( ; i < end; i++)
+ tmpA[i] = alpSrcPtr[i];
+ for ( ; i < vLumFilterSize; i++)
+ tmpA[i] = tmpA[i - 1];
+ alpSrcPtr = tmpA;
+ }
+ }
+ if (firstChrSrcY < 0 || firstChrSrcY + vChrFilterSize > c->chrSrcH) {
+ const int16_t **tmpU = (const int16_t **) chrUPixBuf + 2 * vChrBufSize;
+ int neg = -firstChrSrcY, i, end = FFMIN(c->chrSrcH - firstChrSrcY, vChrFilterSize);
+ for (i = 0; i < neg; i++) {
+ tmpU[i] = chrUSrcPtr[neg];
+ }
+ for ( ; i < end; i++) {
+ tmpU[i] = chrUSrcPtr[i];
+ }
+ for ( ; i < vChrFilterSize; i++) {
+ tmpU[i] = tmpU[i - 1];
+ }
+ chrUSrcPtr = tmpU;
+ }
+
if (flags & SWS_ACCURATE_RND) {
int s= APCK_SIZE / 8;
for (i=0; i<vLumFilterSize; i+=2) {
diff --git a/tests/ref/acodec/wmav1 b/tests/ref/acodec/wmav1
index 916e4a8ab6..117aa12a8c 100644
--- a/tests/ref/acodec/wmav1
+++ b/tests/ref/acodec/wmav1
@@ -1,4 +1,4 @@
-26a7f6b0f0b7181df8df3fa589f6bf81 *./tests/data/acodec/wmav1.asf
+0260385b8a54df11ad349f9ba8240fd8 *./tests/data/acodec/wmav1.asf
106004 ./tests/data/acodec/wmav1.asf
-stddev:12245.52 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400
-stddev: 2095.89 PSNR: 29.90 MAXDIFF:27658 bytes: 1056768/ 1058400
+stddev:12241.90 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400
+stddev: 2074.79 PSNR: 29.99 MAXDIFF:27658 bytes: 1056768/ 1058400
diff --git a/tests/ref/acodec/wmav2 b/tests/ref/acodec/wmav2
index 622b6fcc36..43b19b7530 100644
--- a/tests/ref/acodec/wmav2
+++ b/tests/ref/acodec/wmav2
@@ -1,4 +1,4 @@
-7c6c0cb692af01b312ae345723674b5f *./tests/data/acodec/wmav2.asf
+bdb4c312fb109f990be83a70f8ec9bdc *./tests/data/acodec/wmav2.asf
106044 ./tests/data/acodec/wmav2.asf
-stddev:12249.93 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400
-stddev: 2089.21 PSNR: 29.93 MAXDIFF:27650 bytes: 1056768/ 1058400
+stddev:12246.35 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400
+stddev: 2068.08 PSNR: 30.02 MAXDIFF:27650 bytes: 1056768/ 1058400