diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-03-15 01:21:16 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-03-15 01:27:10 +0100 |
commit | 67235dfa1d2b4bab2c8015e5b8e43ea63a681892 (patch) | |
tree | 6de0622de5bbdf40c5770899bcfb989b31bcd2a4 | |
parent | 9e2ee46206a5a4db91ee4d26737b515797e6b08e (diff) | |
parent | e0febda22d0e0fab094a9c886b0e0f0f662df1ef (diff) | |
download | ffmpeg-67235dfa1d2b4bab2c8015e5b8e43ea63a681892.tar.gz |
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.c | 16 | ||||
-rw-r--r-- | libavcodec/anm.c | 60 | ||||
-rw-r--r-- | libavcodec/bytestream.h | 32 | ||||
-rw-r--r-- | libavcodec/h264.c | 12 | ||||
-rw-r--r-- | libavcodec/jvdec.c | 2 | ||||
-rw-r--r-- | libavcodec/snowdec.c | 26 | ||||
-rw-r--r-- | libavformat/jvdec.c | 1 | ||||
-rwxr-xr-x | tests/codec-regression.sh | 5 | ||||
-rwxr-xr-x | tests/lavf-regression.sh | 4 | ||||
-rw-r--r-- | tests/ref/lavf/pam | 3 | ||||
-rw-r--r-- | tests/ref/vsynth1/ffvhuff | 4 | ||||
-rw-r--r-- | tests/ref/vsynth2/ffvhuff | 4 |
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 |