From d4bbdbd03893e900d8bcf0b46e8307a877d1a3ae Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Mon, 29 Aug 2011 10:36:06 +0200 Subject: [PATCH] g3dvl: Fix a bug not decoding the last 32-64 bits of an mpeg2 bitstream. Another bug found by Andy Furniss. --- src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c | 10 ++++------ src/gallium/auxiliary/vl/vl_vlc.h | 5 +++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c index db05b151f95..9e48bdb9ac5 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c @@ -806,11 +806,10 @@ decode_slice(struct vl_mpg12_bs *bs) while (vl_vlc_get_uimsbf(&bs->vlc, 9) & 1) vl_vlc_fillbits(&bs->vlc); + vl_vlc_fillbits(&bs->vlc); do { int inc = 0; - vl_vlc_fillbits(&bs->vlc); - while (vl_vlc_peekbits(&bs->vlc, 11) == 15) { vl_vlc_eatbits(&bs->vlc, 11); vl_vlc_fillbits(&bs->vlc); @@ -924,7 +923,8 @@ decode_slice(struct vl_mpg12_bs *bs) } else mb.coded_block_pattern = 0; - } while (vl_vlc_bytes_left(&bs->vlc) && vl_vlc_peekbits(&bs->vlc, 23)); + vl_vlc_fillbits(&bs->vlc); + } while (vl_vlc_bits_left(&bs->vlc) && vl_vlc_peekbits(&bs->vlc, 23)); mb.num_skipped_macroblocks = 0; bs->decoder->decode_macroblock(bs->decoder, &mb.base, 1); @@ -974,9 +974,7 @@ vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, unsigned num_bytes, const uint8_t *bu if (!decode_slice(bs)) return; - /* it's possible for the vlc to consume up to eight extra bytes */ - consumed = num_bytes - vl_vlc_bytes_left(&bs->vlc); - consumed = consumed > 8 ? consumed - 8 : 0; + consumed = num_bytes - vl_vlc_bits_left(&bs->vlc) / 8; /* crap, this is a bug we have consumed more bytes than left in the buffer */ assert(consumed <= num_bytes); diff --git a/src/gallium/auxiliary/vl/vl_vlc.h b/src/gallium/auxiliary/vl/vl_vlc.h index 4db1334d6a4..e17eae83fb3 100644 --- a/src/gallium/auxiliary/vl/vl_vlc.h +++ b/src/gallium/auxiliary/vl/vl_vlc.h @@ -113,9 +113,10 @@ vl_vlc_init(struct vl_vlc *vlc, const uint8_t *data, unsigned len) } static INLINE unsigned -vl_vlc_bytes_left(struct vl_vlc *vlc) +vl_vlc_bits_left(struct vl_vlc *vlc) { - return ((uint8_t*)vlc->end)-((uint8_t*)vlc->data); + signed bytes_left = ((uint8_t*)vlc->end)-((uint8_t*)vlc->data); + return bytes_left * 8 + vlc->valid_bits; } static INLINE unsigned -- 2.30.2