On 20.12.2011 12:43, Maarten Lankhorst wrote:
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.lankho...@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..
Why do you want to change that anyway?
The search for start codes was especially split out of the VLC stuff,
because start codes start are byte aligned anyway and it doesn't make
much sense to search for them using the slower peekbits & fillbits
functions.
Se below for some further comments.
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;
The correct sollution would be to let fillbits return a boolean
signaling that the buffer(s) are depleted.
- //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]);
Adding an interface definition without an implementation usually only
makes sense when we could have more than one different implementation.
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
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);
Hui? bits_left is calculation the total number of bits left in the
buffer, while valid_bits is the number of currently loaded bits, so that
check is erroneous.
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);
Just commenting in all checks isn't such a good idea, since that affect
performance very badly, a define which enables all assertions at once at
the beginning of the file seems the better idea.
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 */
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Christian.
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev