summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian König <[email protected]>2013-09-09 03:47:10 -0600
committerChristian König <[email protected]>2013-09-25 10:58:58 +0200
commite3ecea9ddf49e1ec9e1a52ec0ab29c4a4e871a10 (patch)
tree7b83c1e0b97310d6092ea315311ef490121fcdea /src
parent59157d1c96f33ca56d9aba6cff75145d732dbbab (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')
-rw-r--r--src/gallium/auxiliary/vl/vl_vlc.h84
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 */