[XviD-devel] Bitstream problems for RISC architectures
Eric R. Smith
ersmith at hfx.eastlink.ca
Thu Apr 3 23:40:45 CEST 2003
I've been porting XviD to a RISC architecture and ran into a problem
with the bitstream code. The version currently in CVS (and also in the
0.9.1 release) does loads of a uint32_t from arbitrary addresses. This
works on the x86, but not on many RISCs, where uint32_t accesses must be
32 bit aligned.
The solution is quite straightforward: it's just to start the stream at
the previous word boundary and skip the necessary number of bits at the
beginning of the stream. Once the stream is aligned it will stay
aligned. I've appended a patch below. I've verified that this still
works on the x86 (and in fact is very slightly faster, since even when
unaligned loads are allowed they are slower than aligned ones). I've
only tested the decoder; I don't know if any more changes may be
necessary to the encoder.
(Incidentally, kudos for the very clean and easy to follow code; XviD is
the best written video codec I've come across!)
Regards,
Eric
Index: src/global.h
===================================================================
RCS file: /xvid/xvidcore/src/global.h,v
retrieving revision 1.21
diff -u -b -r1.21 global.h
--- src/global.h 21 Feb 2003 14:49:28 -0000 1.21
+++ src/global.h 3 Apr 2003 22:41:14 -0000
@@ -94,6 +94,7 @@
uint32_t *tail;
uint32_t *start;
uint32_t length;
+ uint32_t initpos;
}
Bitstream;
Index: src/bitstream/bitstream.h
===================================================================
RCS file: /xvid/xvidcore/src/bitstream/bitstream.h,v
retrieving revision 1.17
diff -u -b -r1.17 bitstream.h
--- src/bitstream/bitstream.h 15 Feb 2003 15:22:18 -0000 1.17
+++ src/bitstream/bitstream.h 3 Apr 2003 22:41:14 -0000
@@ -173,23 +173,29 @@
uint32_t length)
{
uint32_t tmp;
+ size_t bitpos;
+ ptr_t adjbitstream = (ptr_t)bitstream;
- bs->start = bs->tail = (uint32_t *) bitstream;
+ /* Start the stream on a uint32_t boundary, by rounding down to the
+ previous uint32_t and skipping the intervening bytes. */
+ bitpos = ((sizeof(uint32_t)-1) & (size_t)bitstream);
+ adjbitstream = adjbitstream - bitpos;
+ bs->start = bs->tail = (uint32_t *) adjbitstream;
- tmp = *(uint32_t *) bitstream;
+ tmp = *bs->start;
#ifndef ARCH_IS_BIG_ENDIAN
BSWAP(tmp);
#endif
bs->bufa = tmp;
- tmp = *((uint32_t *) bitstream + 1);
+ tmp = *(bs->start + 1);
#ifndef ARCH_IS_BIG_ENDIAN
BSWAP(tmp);
#endif
bs->bufb = tmp;
bs->buf = 0;
- bs->pos = 0;
+ bs->pos = bs->initpos = bitpos*8;
bs->length = length;
}
@@ -216,7 +222,7 @@
bs->bufb = tmp;
bs->buf = 0;
- bs->pos = 0;
+ bs->pos = bs->initpos;
}
@@ -309,7 +315,7 @@
static uint32_t __inline
BitstreamPos(const Bitstream * const bs)
{
- return 8 * ((ptr_t)bs->tail - (ptr_t)bs->start) + bs->pos;
+ return 8 * ((ptr_t)bs->tail - (ptr_t)bs->start) + bs->pos - bs->initpos;
}
@@ -332,7 +338,9 @@
len += (bs->pos + 7) / 8;
}
-
+ if (bs->initpos) {
+ len -= bs->initpos/8; /* initpos is always on a byte
boundary */
+ }
return len;
}
More information about the XviD-devel
mailing list