summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-03-15 01:21:16 +0100
committerMichael Niedermayer <michaelni@gmx.at>2012-03-15 01:27:10 +0100
commit67235dfa1d2b4bab2c8015e5b8e43ea63a681892 (patch)
tree6de0622de5bbdf40c5770899bcfb989b31bcd2a4
parent9e2ee46206a5a4db91ee4d26737b515797e6b08e (diff)
parente0febda22d0e0fab094a9c886b0e0f0f662df1ef (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: h264: stricter reference limit enforcement. h264: increase reference poc list from 16 to 32. xa_adpcm: limit filter to prevent xa_adpcm_table[] array bounds overruns. snow: check reference frame indices. snow: reject unsupported chroma shifts. Add ffvhuff encoding and decoding regression test anm: convert to bytestream2 API bytestream: add more unchecked variants for bytestream2 API jvdec: unbreak video decoding jv demux: set video stream duration fate: add pam image regression test Conflicts: libavcodec/adpcm.c libavcodec/anm.c libavcodec/h264.c libavcodec/mpegvideo.h libavcodec/snowdec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/adpcm.c16
-rw-r--r--libavcodec/anm.c60
-rw-r--r--libavcodec/bytestream.h32
-rw-r--r--libavcodec/h264.c12
-rw-r--r--libavcodec/jvdec.c2
-rw-r--r--libavcodec/snowdec.c26
-rw-r--r--libavformat/jvdec.c1
-rwxr-xr-xtests/codec-regression.sh5
-rwxr-xr-xtests/lavf-regression.sh4
-rw-r--r--tests/ref/lavf/pam3
-rw-r--r--tests/ref/vsynth1/ffvhuff4
-rw-r--r--tests/ref/vsynth2/ffvhuff4
12 files changed, 113 insertions, 56 deletions
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 559eb293ce..dec23a37e4 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -265,8 +265,9 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c
return c->predictor;
}
-static void xa_decode(short *out, const unsigned char *in,
- ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc)
+static int xa_decode(AVCodecContext *avctx,
+ short *out, const unsigned char *in,
+ ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc)
{
int i, j;
int shift,filter,f0,f1;
@@ -278,7 +279,7 @@ static void xa_decode(short *out, const unsigned char *in,
shift = 12 - (in[4+i*2] & 15);
filter = in[4+i*2] >> 4;
if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) {
- av_log_ask_for_sample(NULL, "unknown filter %d\n", filter);
+ av_log_ask_for_sample(avctx, "unknown XA-ADPCM filter %d\n", filter);
filter=0;
}
f0 = xa_adpcm_table[filter][0];
@@ -309,7 +310,7 @@ static void xa_decode(short *out, const unsigned char *in,
shift = 12 - (in[5+i*2] & 15);
filter = in[5+i*2] >> 4;
if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) {
- av_log_ask_for_sample(NULL, "unknown filter %d\n", filter);
+ av_log_ask_for_sample(avctx, "unknown XA-ADPCM filter %d\n", filter);
filter=0;
}
@@ -336,6 +337,8 @@ static void xa_decode(short *out, const unsigned char *in,
left->sample2 = s_2;
}
}
+
+ return 0;
}
/**
@@ -823,8 +826,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
break;
case CODEC_ID_ADPCM_XA:
while (buf_size >= 128) {
- xa_decode(samples, src, &c->status[0], &c->status[1],
- avctx->channels);
+ if ((ret = xa_decode(avctx, samples, src, &c->status[0],
+ &c->status[1], avctx->channels)) < 0)
+ return ret;
src += 128;
samples += 28 * 8;
buf_size -= 128;
diff --git a/libavcodec/anm.c b/libavcodec/anm.c
index 5493be6842..37cd870126 100644
--- a/libavcodec/anm.c
+++ b/libavcodec/anm.c
@@ -30,26 +30,26 @@
typedef struct AnmContext {
AVFrame frame;
int palette[AVPALETTE_COUNT];
+ GetByteContext gb;
int x; ///< x coordinate position
} AnmContext;
static av_cold int decode_init(AVCodecContext *avctx)
{
AnmContext *s = avctx->priv_data;
- const uint8_t *buf;
int i;
avctx->pix_fmt = PIX_FMT_PAL8;
- if (avctx->extradata_size != 16*8 + 4*256)
- return -1;
-
avcodec_get_frame_defaults(&s->frame);
s->frame.reference = 3;
+ bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
+ if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256)
+ return -1;
- buf = avctx->extradata + 16*8;
+ bytestream2_skipu(&s->gb, 16 * 8);
for (i = 0; i < 256; i++)
- s->palette[i] = bytestream_get_le32(&buf);
+ s->palette[i] = bytestream2_get_le32u(&s->gb);
return 0;
}
@@ -57,7 +57,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
/**
* Perform decode operation
* @param dst, dst_end Destination image buffer
- * @param buf, buf_end Source buffer (optional, see below)
+ * @param gb, GetByteContext (optional, see below)
* @param pixel Fill color (optional, see below)
* @param count Pixel count
* @param x Pointer to x-axis counter
@@ -65,24 +65,22 @@ static av_cold int decode_init(AVCodecContext *avctx)
* @param linesize Destination image buffer linesize
* @return non-zero if destination buffer is exhausted
*
- * a copy operation is achieved when 'buf' is set
- * a fill operation is acheived when 'buf' is null and pixel is >= 0
- * a skip operation is acheived when 'buf' is null and pixel is < 0
+ * a copy operation is achieved when 'gb' is set
+ * a fill operation is acheived when 'gb' is null and pixel is >= 0
+ * a skip operation is acheived when 'gb' is null and pixel is < 0
*/
static inline int op(uint8_t **dst, const uint8_t *dst_end,
- const uint8_t **buf, const uint8_t *buf_end,
+ GetByteContext *gb,
int pixel, int count,
int *x, int width, int linesize)
{
int remaining = width - *x;
while(count > 0) {
int striplen = FFMIN(count, remaining);
- if (buf) {
- striplen = FFMIN(striplen, buf_end - *buf);
- if (*buf >= buf_end)
+ if (gb) {
+ if (bytestream2_get_bytes_left(gb) < striplen)
goto exhausted;
- memcpy(*dst, *buf, striplen);
- *buf += striplen;
+ bytestream2_get_bufferu(gb, *dst, striplen);
} else if (pixel >= 0)
memset(*dst, pixel, striplen);
*dst += striplen;
@@ -111,9 +109,7 @@ static int decode_frame(AVCodecContext *avctx,
AVPacket *avpkt)
{
AnmContext *s = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
const int buf_size = avpkt->size;
- const uint8_t *buf_end = buf + buf_size;
uint8_t *dst, *dst_end;
int count;
@@ -124,35 +120,37 @@ static int decode_frame(AVCodecContext *avctx,
dst = s->frame.data[0];
dst_end = s->frame.data[0] + s->frame.linesize[0]*avctx->height;
- if (buf[0] != 0x42) {
+ bytestream2_init(&s->gb, avpkt->data, buf_size);
+
+ if (bytestream2_get_byte(&s->gb) != 0x42) {
av_log_ask_for_sample(avctx, "unknown record type\n");
return buf_size;
}
- if (buf[1]) {
+ if (bytestream2_get_byte(&s->gb)) {
av_log_ask_for_sample(avctx, "padding bytes not supported\n");
return buf_size;
}
- buf += 4;
+ bytestream2_skip(&s->gb, 2);
s->x = 0;
do {
/* if statements are ordered by probability */
-#define OP(buf, pixel, count) \
- op(&dst, dst_end, (buf), buf_end, (pixel), (count), &s->x, avctx->width, s->frame.linesize[0])
+#define OP(gb, pixel, count) \
+ op(&dst, dst_end, (gb), (pixel), (count), &s->x, avctx->width, s->frame.linesize[0])
- int type = bytestream_get_byte(&buf);
+ int type = bytestream2_get_byte(&s->gb);
count = type & 0x7F;
type >>= 7;
if (count) {
- if (OP(type ? NULL : &buf, -1, count)) break;
+ if (OP(type ? NULL : &s->gb, -1, count)) break;
} else if (!type) {
int pixel;
- count = bytestream_get_byte(&buf); /* count==0 gives nop */
- pixel = bytestream_get_byte(&buf);
+ count = bytestream2_get_byte(&s->gb); /* count==0 gives nop */
+ pixel = bytestream2_get_byte(&s->gb);
if (OP(NULL, pixel, count)) break;
} else {
int pixel;
- type = bytestream_get_le16(&buf);
+ type = bytestream2_get_le16(&s->gb);
count = type & 0x3FFF;
type >>= 14;
if (!count) {
@@ -164,11 +162,11 @@ static int decode_frame(AVCodecContext *avctx,
}
continue;
}
- pixel = type == 3 ? bytestream_get_byte(&buf) : -1;
+ pixel = type == 3 ? bytestream2_get_byte(&s->gb) : -1;
if (type == 1) count += 0x4000;
- if (OP(type == 2 ? &buf : NULL, pixel, count)) break;
+ if (OP(type == 2 ? &s->gb : NULL, pixel, count)) break;
}
- } while (buf + 1 < buf_end);
+ } while (bytestream2_get_bytes_left(&s->gb) > 0);
memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h
index cba2dbb22d..2d9ca47508 100644
--- a/libavcodec/bytestream.h
+++ b/libavcodec/bytestream.h
@@ -170,6 +170,12 @@ static av_always_inline void bytestream2_skip(GetByteContext *g,
g->buffer += FFMIN(g->buffer_end - g->buffer, size);
}
+static av_always_inline void bytestream2_skipu(GetByteContext *g,
+ unsigned int size)
+{
+ g->buffer += size;
+}
+
static av_always_inline void bytestream2_skip_p(PutByteContext *p,
unsigned int size)
{
@@ -257,6 +263,15 @@ static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g,
return size2;
}
+static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g,
+ uint8_t *dst,
+ unsigned int size)
+{
+ memcpy(dst, g->buffer, size);
+ g->buffer += size;
+ return size;
+}
+
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
const uint8_t *src,
unsigned int size)
@@ -272,6 +287,15 @@ static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p,
return size2;
}
+static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p,
+ const uint8_t *src,
+ unsigned int size)
+{
+ memcpy(p->buffer, src, size);
+ p->buffer += size;
+ return size;
+}
+
static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
const uint8_t c,
unsigned int size)
@@ -286,6 +310,14 @@ static av_always_inline void bytestream2_set_buffer(PutByteContext *p,
p->buffer += size2;
}
+static av_always_inline void bytestream2_set_bufferu(PutByteContext *p,
+ const uint8_t c,
+ unsigned int size)
+{
+ memset(p->buffer, c, size);
+ p->buffer += size;
+}
+
static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p)
{
return p->eof;
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 2cb56028de..66174778df 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -3034,7 +3034,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);
}
@@ -3044,13 +3045,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/jvdec.c b/libavcodec/jvdec.c
index aea2cc1bed..d371950b6e 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/snowdec.c b/libavcodec/snowdec.c
index 537a6c6e8f..1db431884e 100644
--- a/libavcodec/snowdec.c
+++ b/libavcodec/snowdec.c
@@ -142,6 +142,7 @@ static int decode_q_branch(SnowContext *s, int level, int x, int y){
const BlockNode *tl = y && x ? &s->block[index-w-1] : left;
const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
+ int res;
if(s->keyframe){
set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);
@@ -170,7 +171,7 @@ static int decode_q_branch(SnowContext *s, int level, int x, int y){
ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
if (ref >= s->ref_frames) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid ref\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
pred_mv(s, &mx, &my, ref, left, top, tr);
mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
@@ -178,14 +179,11 @@ static int decode_q_branch(SnowContext *s, int level, int x, int y){
}
set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);
}else{
- if (decode_q_branch(s, level+1, 2*x+0, 2*y+0)<0)
- return -1;
- if (decode_q_branch(s, level+1, 2*x+1, 2*y+0)<0)
- return -1;
- if (decode_q_branch(s, level+1, 2*x+0, 2*y+1)<0)
- return -1;
- if (decode_q_branch(s, level+1, 2*x+1, 2*y+1)<0)
- return -1;
+ if ((res = decode_q_branch(s, level+1, 2*x+0, 2*y+0)) < 0 ||
+ (res = decode_q_branch(s, level+1, 2*x+1, 2*y+0)) < 0 ||
+ (res = decode_q_branch(s, level+1, 2*x+0, 2*y+1)) < 0 ||
+ (res = decode_q_branch(s, level+1, 2*x+1, 2*y+1)) < 0)
+ return res;
}
return 0;
}
@@ -367,11 +365,12 @@ static int decode_blocks(SnowContext *s){
int x, y;
int w= s->b_width;
int h= s->b_height;
+ int res;
for(y=0; y<h; y++){
for(x=0; x<w; x++){
- if (decode_q_branch(s, 0, x, y) < 0)
- return -1;
+ if ((res = decode_q_branch(s, 0, x, y)) < 0)
+ return res;
}
}
return 0;
@@ -385,6 +384,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
int bytes_read;
AVFrame *picture = data;
int level, orientation, plane_index;
+ int res;
ff_init_range_decoder(c, buf, buf_size);
ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
@@ -413,8 +413,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
if(avctx->debug&FF_DEBUG_PICT_INFO)
av_log(avctx, AV_LOG_ERROR, "keyframe:%d qlog:%d\n", s->keyframe, s->qlog);
- if (decode_blocks(s) < 0)
- return -1;
+ if ((res = decode_blocks(s)) < 0)
+ return res;
for(plane_index=0; plane_index<3; plane_index++){
Plane *p= &s->plane[plane_index];
diff --git a/libavformat/jvdec.c b/libavformat/jvdec.c
index 31cba6f468..fbd4f1e5f4 100644
--- a/libavformat/jvdec.c
+++ b/libavformat/jvdec.c
@@ -79,6 +79,7 @@ static int read_header(AVFormatContext *s)
vst->codec->codec_tag = 0; /* no fourcc */
vst->codec->width = avio_rl16(pb);
vst->codec->height = avio_rl16(pb);
+ vst->duration =
vst->nb_frames =
ast->nb_index_entries = avio_rl16(pb);
avpriv_set_pts_info(vst, 64, avio_rl16(pb), 1000);
diff --git a/tests/codec-regression.sh b/tests/codec-regression.sh
index cd6512c725..714a94fb2f 100755
--- a/tests/codec-regression.sh
+++ b/tests/codec-regression.sh
@@ -227,6 +227,11 @@ do_video_encoding ffv1.avi "-strict -2 -an -vcodec ffv1"
do_video_decoding
fi
+if [ -n "$do_ffvhuff" ] ; then
+do_video_encoding ffvhuff.avi "-an -vcodec ffvhuff"
+do_video_decoding ""
+fi
+
if [ -n "$do_snow" ] ; then
do_video_encoding snow.avi "-strict -2 -an -vcodec snow -qscale 2 -flags +qpel -me_method iter -dia_size 2 -cmp 12 -subcmp 12 -s 128x64"
do_video_decoding "" "-s 352x288"
diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh
index bfca359a58..f0fcac3511 100755
--- a/tests/lavf-regression.sh
+++ b/tests/lavf-regression.sh
@@ -211,6 +211,10 @@ if [ -n "$do_jpg" ] ; then
do_image_formats jpg "-pix_fmt yuvj420p" "-f image2"
fi
+if [ -n "$do_pam" ] ; then
+do_image_formats pam
+fi
+
if [ -n "$do_pcx" ] ; then
do_image_formats pcx
fi
diff --git a/tests/ref/lavf/pam b/tests/ref/lavf/pam
new file mode 100644
index 0000000000..972d72825e
--- /dev/null
+++ b/tests/ref/lavf/pam
@@ -0,0 +1,3 @@
+0dce5565222cf0f8b309467f279aecd2 *./tests/data/images/pam/02.pam
+./tests/data/images/pam/%02d.pam CRC=0x6da01946
+ 304191 ./tests/data/images/pam/02.pam
diff --git a/tests/ref/vsynth1/ffvhuff b/tests/ref/vsynth1/ffvhuff
new file mode 100644
index 0000000000..c6d7627b24
--- /dev/null
+++ b/tests/ref/vsynth1/ffvhuff
@@ -0,0 +1,4 @@
+0632ffae6f1e06dd299bf41a845b9099 *./tests/data/vsynth1/ffvhuff.avi
+ 5987208 ./tests/data/vsynth1/ffvhuff.avi
+c5ccac874dbf808e9088bc3107860042 *./tests/data/ffvhuff.vsynth1.out.yuv
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200
diff --git a/tests/ref/vsynth2/ffvhuff b/tests/ref/vsynth2/ffvhuff
new file mode 100644
index 0000000000..6d77e2a027
--- /dev/null
+++ b/tests/ref/vsynth2/ffvhuff
@@ -0,0 +1,4 @@
+63926d8835dd5779dca0a4bc081ca8ae *./tests/data/vsynth2/ffvhuff.avi
+ 4988056 ./tests/data/vsynth2/ffvhuff.avi
+dde5895817ad9d219f79a52d0bdfb001 *./tests/data/ffvhuff.vsynth2.out.yuv
+stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 7603200/ 7603200