From: Christian König Date: Mon, 9 Sep 2013 09:47:10 +0000 (-0600) Subject: vl/vlc: add fast forward search for byte value X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e3ecea9ddf49e1ec9e1a52ec0ab29c4a4e871a10;p=mesa.git 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 --- 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,21 +98,28 @@ 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; ++vlc->sizes; } +/** + * 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 */ @@ -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 */