diff options
author | Christian König <[email protected]> | 2013-09-09 03:47:10 -0600 |
---|---|---|
committer | Christian König <[email protected]> | 2013-09-25 10:58:58 +0200 |
commit | e3ecea9ddf49e1ec9e1a52ec0ab29c4a4e871a10 (patch) | |
tree | 7b83c1e0b97310d6092ea315311ef490121fcdea /src/gallium | |
parent | 59157d1c96f33ca56d9aba6cff75145d732dbbab (diff) |
vl/vlc: add fast forward search for byte value
Commonly used to find start codes and has far less overhead
to searching manually.
Signed-off-by: Christian König <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/auxiliary/vl/vl_vlc.h | 84 |
1 files changed, 74 insertions, 10 deletions
diff --git a/src/gallium/auxiliary/vl/vl_vlc.h b/src/gallium/auxiliary/vl/vl_vlc.h index 6223fabf577..0dc1df98fb8 100644 --- a/src/gallium/auxiliary/vl/vl_vlc.h +++ b/src/gallium/auxiliary/vl/vl_vlc.h @@ -91,7 +91,6 @@ vl_vlc_init_table(struct vl_vlc_entry *dst, unsigned dst_size, const struct vl_v static INLINE void vl_vlc_next_input(struct vl_vlc *vlc) { - const uint8_t* data = vlc->inputs[0]; unsigned len = vlc->sizes[0]; assert(vlc); @@ -99,15 +98,8 @@ vl_vlc_next_input(struct vl_vlc *vlc) vlc->bytes_left -= len; - /* align the data pointer */ - while (len && pointer_to_uintptr(data) & 3) { - vlc->buffer |= (uint64_t)*data << (24 + vlc->invalid_bits); - ++data; - --len; - vlc->invalid_bits -= 8; - } - vlc->data = data; - vlc->end = data + len; + vlc->data = vlc->inputs[0]; + vlc->end = vlc->data + len; --vlc->num_inputs; ++vlc->inputs; @@ -115,6 +107,20 @@ vl_vlc_next_input(struct vl_vlc *vlc) } /** + * align the data pointer to the next dword + */ +static INLINE void +vl_vlc_align_data_ptr(struct vl_vlc *vlc) +{ + /* align the data pointer */ + while (vlc->data != vlc->end && pointer_to_uintptr(vlc->data) & 3) { + vlc->buffer |= (uint64_t)*vlc->data << (24 + vlc->invalid_bits); + ++vlc->data; + vlc->invalid_bits -= 8; + } +} + +/** * fill the bit buffer, so that at least 32 bits are valid */ static INLINE void @@ -185,6 +191,7 @@ vl_vlc_init(struct vl_vlc *vlc, unsigned num_inputs, vlc->bytes_left += sizes[i]; vl_vlc_next_input(vlc); + vl_vlc_align_data_ptr(vlc); vl_vlc_fillbits(vlc); vl_vlc_fillbits(vlc); } @@ -274,4 +281,61 @@ vl_vlc_get_vlclbf(struct vl_vlc *vlc, const struct vl_vlc_entry *tbl, unsigned n return tbl->value; } +/** + * fast forward search for a specific byte value + */ +static INLINE boolean +vl_vlc_search_byte(struct vl_vlc *vlc, unsigned num_bits, uint8_t value) +{ + /* make sure we are on a byte boundary */ + assert((vl_vlc_valid_bits(vlc) % 8) == 0); + assert(num_bits == ~0 || (num_bits % 8) == 0); + + /* deplete the bit buffer */ + while (vl_vlc_valid_bits(vlc) > 0) { + + if (vl_vlc_peekbits(vlc, 8) == value) { + vl_vlc_fillbits(vlc); + return TRUE; + } + + vl_vlc_eatbits(vlc, 8); + + if (num_bits != ~0) { + num_bits -= 8; + if (num_bits == 0) + return FALSE; + } + } + + /* deplete the byte buffers */ + while (1) { + + /* if this input is depleted */ + if (vlc->data == vlc->end) { + if (vlc->num_inputs) + /* go on to next input */ + vl_vlc_next_input(vlc); + else + /* or give up since we don't have anymore inputs */ + return FALSE; + } + + if (*vlc->data == value) { + vl_vlc_align_data_ptr(vlc); + vl_vlc_fillbits(vlc); + return TRUE; + } + + ++vlc->data; + if (num_bits != ~0) { + num_bits -= 8; + if (num_bits == 0) { + vl_vlc_align_data_ptr(vlc); + return FALSE; + } + } + } +} + #endif /* vl_vlc_h */ |