g3dvl: Fix a bug not decoding the last 32-64 bits of an mpeg2 bitstream.
authorChristian König <deathsimple@vodafone.de>
Mon, 29 Aug 2011 08:36:06 +0000 (10:36 +0200)
committerChristian König <deathsimple@vodafone.de>
Mon, 29 Aug 2011 08:36:06 +0000 (10:36 +0200)
Another bug found by Andy Furniss.

src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
src/gallium/auxiliary/vl/vl_vlc.h

index db05b151f95104a2fa67eb7537d3531873239f00..9e48bdb9ac5de62fded33c54fe5cd80d3b55af99 100644 (file)
@@ -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);
index 4db1334d6a46976d441a57185a6bfe8c4101ff85..e17eae83fb3a993675cbfb9cf3a7524b55d2af84 100644 (file)
@@ -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