[Mesa-dev] [PATCH 1/3] vl: Only initialize vlc once
Maarten Lankhorst
m.b.lankhorst at gmail.com
Tue Dec 20 03:43:23 PST 2011
And add more sanity checks to stream. This shouldn't break things beyond those that aren't broken already.
Signed-off-by: Maarten Lankhorst <m.b.lankhorst at gmail.com>
---
And yes Andy, I mean that I haven't found a good video yet to fix the playback parts that are still broken..
src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c | 56 +++++++++++-------------
src/gallium/auxiliary/vl/vl_vlc.h | 33 +++++++++-----
2 files changed, 47 insertions(+), 42 deletions(-)
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
index 936cf2c..62d08d7 100644
--- a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
@@ -787,7 +787,7 @@ entry:
}
static INLINE bool
-decode_slice(struct vl_mpg12_bs *bs)
+decode_slice(struct vl_mpg12_bs *bs, unsigned code)
{
struct pipe_mpeg12_macroblock mb;
short dct_blocks[64*6];
@@ -796,24 +796,29 @@ decode_slice(struct vl_mpg12_bs *bs)
memset(&mb, 0, sizeof(mb));
mb.base.codec = PIPE_VIDEO_CODEC_MPEG12;
- mb.y = vl_vlc_get_uimsbf(&bs->vlc, 8) - 1;
+ mb.y = code - 1;
mb.blocks = dct_blocks;
reset_predictor(bs);
+ vl_vlc_fillbits(&bs->vlc);
dct_scale = quant_scale[bs->desc.q_scale_type][vl_vlc_get_uimsbf(&bs->vlc, 5)];
- if (vl_vlc_get_uimsbf(&bs->vlc, 1))
+ if (vl_vlc_get_uimsbf(&bs->vlc, 1)) {
+ vl_vlc_fillbits(&bs->vlc);
while (vl_vlc_get_uimsbf(&bs->vlc, 9) & 1)
vl_vlc_fillbits(&bs->vlc);
+ }
vl_vlc_fillbits(&bs->vlc);
+ assert(vl_vlc_bits_left(&bs->vlc) > 23 && vl_vlc_peekbits(&bs->vlc, 23));
do {
int inc = 0;
- while (vl_vlc_peekbits(&bs->vlc, 11) == 15) {
- vl_vlc_eatbits(&bs->vlc, 11);
- vl_vlc_fillbits(&bs->vlc);
- }
+ if (bs->decoder->profile == PIPE_VIDEO_PROFILE_MPEG1)
+ while (vl_vlc_peekbits(&bs->vlc, 11) == 15) {
+ vl_vlc_eatbits(&bs->vlc, 11);
+ vl_vlc_fillbits(&bs->vlc);
+ }
while (vl_vlc_peekbits(&bs->vlc, 11) == 8) {
vl_vlc_eatbits(&bs->vlc, 11);
@@ -959,32 +964,23 @@ void
vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, unsigned num_bytes, const uint8_t *buffer)
{
assert(bs);
- assert(buffer && num_bytes);
-
- while(num_bytes > 2) {
- if (buffer[0] == 0x00 && buffer[1] == 0x00 && buffer[2] == 0x01 &&
- buffer[3] >= 0x01 && buffer[3] < 0xAF) {
- unsigned consumed;
- buffer += 3;
- num_bytes -= 3;
+ vl_vlc_init(&bs->vlc, 1, num_bytes, (void const * const *)&buffer, &num_bytes);
- vl_vlc_init(&bs->vlc, buffer, num_bytes);
-
- if (!decode_slice(bs))
+ while (vl_vlc_bits_left(&bs->vlc) >= 32) {
+ vl_vlc_fillbits(&bs->vlc);
+ if (vl_vlc_peekbits(&bs->vlc, 24) == 0x000001) {
+ unsigned code;
+ vl_vlc_eatbits(&bs->vlc, 24);
+ code = vl_vlc_get_uimsbf(&bs->vlc, 8);
+ if (!code || code > 0xaf)
+ continue;
+ if (!decode_slice(bs, code))
return;
-
- 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);
-
- num_bytes -= consumed;
- buffer += consumed;
-
+ vl_vlc_bitalign(&bs->vlc);
} else {
- ++buffer;
- --num_bytes;
+ vl_vlc_eatbits(&bs->vlc, 8);
+ continue;
}
}
}
diff --git a/src/gallium/auxiliary/vl/vl_vlc.h b/src/gallium/auxiliary/vl/vl_vlc.h
index dc4faed..a4ded70 100644
--- a/src/gallium/auxiliary/vl/vl_vlc.h
+++ b/src/gallium/auxiliary/vl/vl_vlc.h
@@ -38,7 +38,7 @@
struct vl_vlc
{
uint64_t buffer;
- unsigned valid_bits;
+ uint32_t valid_bits;
uint32_t *data;
uint32_t *end;
};
@@ -74,11 +74,9 @@ vl_vlc_init_table(struct vl_vlc_entry *dst, unsigned dst_size, const struct vl_v
static INLINE void
vl_vlc_fillbits(struct vl_vlc *vlc)
{
- if (vlc->valid_bits < 32) {
+ if (vlc->valid_bits < 32 && vlc->data < vlc->end) {
uint32_t value = *vlc->data;
- //assert(vlc->data <= vlc->end);
-
#ifndef PIPE_ARCH_BIG_ENDIAN
value = util_bswap32(value);
#endif
@@ -90,10 +88,14 @@ vl_vlc_fillbits(struct vl_vlc *vlc)
}
static INLINE void
-vl_vlc_init(struct vl_vlc *vlc, const uint8_t *data, unsigned len)
+vl_vlc_init(struct vl_vlc *vlc,
+ const unsigned array_size, unsigned total_len,
+ const const void *const *datas, const unsigned *lens)
{
+ const uint8_t *data = datas[0];
assert(vlc);
- assert(data && len);
+ assert(array_size == 1); // TODO
+ assert(datas[0] && lens[0]);
vlc->buffer = 0;
vlc->valid_bits = 0;
@@ -102,11 +104,11 @@ vl_vlc_init(struct vl_vlc *vlc, const uint8_t *data, unsigned len)
while (pointer_to_uintptr(data) & 3) {
vlc->buffer |= (uint64_t)*data << (56 - vlc->valid_bits);
++data;
- --len;
+ --total_len;
vlc->valid_bits += 8;
}
vlc->data = (uint32_t*)data;
- vlc->end = (uint32_t*)(data + len);
+ vlc->end = (uint32_t*)(data + total_len);
vl_vlc_fillbits(vlc);
vl_vlc_fillbits(vlc);
@@ -122,7 +124,7 @@ vl_vlc_bits_left(struct vl_vlc *vlc)
static INLINE unsigned
vl_vlc_peekbits(struct vl_vlc *vlc, unsigned num_bits)
{
- //assert(vlc->valid_bits >= num_bits);
+ assert(vlc->valid_bits >= num_bits || vl_vlc_bits_left(vlc) < num_bits);
return vlc->buffer >> (64 - num_bits);
}
@@ -130,7 +132,7 @@ vl_vlc_peekbits(struct vl_vlc *vlc, unsigned num_bits)
static INLINE void
vl_vlc_eatbits(struct vl_vlc *vlc, unsigned num_bits)
{
- //assert(vlc->valid_bits > num_bits);
+ assert(vlc->valid_bits >= num_bits);
vlc->buffer <<= num_bits;
vlc->valid_bits -= num_bits;
@@ -141,7 +143,7 @@ vl_vlc_get_uimsbf(struct vl_vlc *vlc, unsigned num_bits)
{
unsigned value;
- //assert(vlc->valid_bits >= num_bits);
+ assert(vlc->valid_bits >= num_bits);
value = vlc->buffer >> (64 - num_bits);
vl_vlc_eatbits(vlc, num_bits);
@@ -154,7 +156,7 @@ vl_vlc_get_simsbf(struct vl_vlc *vlc, unsigned num_bits)
{
signed value;
- //assert(vlc->valid_bits >= num_bits);
+ assert(vlc->valid_bits >= num_bits);
value = ((int64_t)vlc->buffer) >> (64 - num_bits);
vl_vlc_eatbits(vlc, num_bits);
@@ -167,7 +169,14 @@ vl_vlc_get_vlclbf(struct vl_vlc *vlc, const struct vl_vlc_entry *tbl, unsigned n
{
tbl += vl_vlc_peekbits(vlc, num_bits);
vl_vlc_eatbits(vlc, tbl->length);
+ assert(tbl->length);
return tbl->value;
}
+static INLINE void
+vl_vlc_bitalign(struct vl_vlc *vlc)
+{
+ vl_vlc_eatbits(vlc, vlc->valid_bits & 7);
+}
+
#endif /* vl_vlc_h */
More information about the mesa-dev
mailing list