vp10: code sign bit before absolute value in non-arithcoded header.

For reading, this makes the operation branchless, although it still
requires two shifts. For writing, this makes the operation as fast
as writing an unsigned value, branchlessly. This is also how other
codecs typically code signed, non-arithcoded bitstream elements.

See issue 1039.

Change-Id: I6a8182cc88a16842fb431688c38f6b52d7f24ead
This commit is contained in:
Ronald S. Bultje 2015-09-08 14:26:42 -04:00
parent 3c8e04e939
commit a3df343cda
6 changed files with 34 additions and 9 deletions

View File

@ -1095,17 +1095,17 @@ static void setup_loopfilter(struct loopfilter *lf,
for (i = 0; i < MAX_REF_FRAMES; i++) for (i = 0; i < MAX_REF_FRAMES; i++)
if (vpx_rb_read_bit(rb)) if (vpx_rb_read_bit(rb))
lf->ref_deltas[i] = vpx_rb_read_signed_literal(rb, 6); lf->ref_deltas[i] = vpx_rb_read_inv_signed_literal(rb, 6);
for (i = 0; i < MAX_MODE_LF_DELTAS; i++) for (i = 0; i < MAX_MODE_LF_DELTAS; i++)
if (vpx_rb_read_bit(rb)) if (vpx_rb_read_bit(rb))
lf->mode_deltas[i] = vpx_rb_read_signed_literal(rb, 6); lf->mode_deltas[i] = vpx_rb_read_inv_signed_literal(rb, 6);
} }
} }
} }
static INLINE int read_delta_q(struct vpx_read_bit_buffer *rb) { static INLINE int read_delta_q(struct vpx_read_bit_buffer *rb) {
return vpx_rb_read_bit(rb) ? vpx_rb_read_signed_literal(rb, 4) : 0; return vpx_rb_read_bit(rb) ? vpx_rb_read_inv_signed_literal(rb, 4) : 0;
} }
static void setup_quantization(VP10_COMMON *const cm, MACROBLOCKD *const xd, static void setup_quantization(VP10_COMMON *const cm, MACROBLOCKD *const xd,

View File

@ -714,8 +714,7 @@ static void encode_loopfilter(struct loopfilter *lf,
vpx_wb_write_bit(wb, changed); vpx_wb_write_bit(wb, changed);
if (changed) { if (changed) {
lf->last_ref_deltas[i] = delta; lf->last_ref_deltas[i] = delta;
vpx_wb_write_literal(wb, abs(delta) & 0x3F, 6); vpx_wb_write_inv_signed_literal(wb, delta, 6);
vpx_wb_write_bit(wb, delta < 0);
} }
} }
@ -725,8 +724,7 @@ static void encode_loopfilter(struct loopfilter *lf,
vpx_wb_write_bit(wb, changed); vpx_wb_write_bit(wb, changed);
if (changed) { if (changed) {
lf->last_mode_deltas[i] = delta; lf->last_mode_deltas[i] = delta;
vpx_wb_write_literal(wb, abs(delta) & 0x3F, 6); vpx_wb_write_inv_signed_literal(wb, delta, 6);
vpx_wb_write_bit(wb, delta < 0);
} }
} }
} }
@ -736,8 +734,7 @@ static void encode_loopfilter(struct loopfilter *lf,
static void write_delta_q(struct vpx_write_bit_buffer *wb, int delta_q) { static void write_delta_q(struct vpx_write_bit_buffer *wb, int delta_q) {
if (delta_q != 0) { if (delta_q != 0) {
vpx_wb_write_bit(wb, 1); vpx_wb_write_bit(wb, 1);
vpx_wb_write_literal(wb, abs(delta_q), 4); vpx_wb_write_inv_signed_literal(wb, delta_q, 4);
vpx_wb_write_bit(wb, delta_q < 0);
} else { } else {
vpx_wb_write_bit(wb, 0); vpx_wb_write_bit(wb, 0);
} }

View File

@ -7,6 +7,7 @@
* in the file PATENTS. All contributing project authors may * in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "./vpx_config.h"
#include "./bitreader_buffer.h" #include "./bitreader_buffer.h"
size_t vpx_rb_bytes_read(struct vpx_read_bit_buffer *rb) { size_t vpx_rb_bytes_read(struct vpx_read_bit_buffer *rb) {
@ -39,3 +40,14 @@ int vpx_rb_read_signed_literal(struct vpx_read_bit_buffer *rb,
const int value = vpx_rb_read_literal(rb, bits); const int value = vpx_rb_read_literal(rb, bits);
return vpx_rb_read_bit(rb) ? -value : value; return vpx_rb_read_bit(rb) ? -value : value;
} }
int vpx_rb_read_inv_signed_literal(struct vpx_read_bit_buffer *rb,
int bits) {
#if CONFIG_MISC_FIXES
const int nbits = sizeof(unsigned) * 8 - bits - 1;
const unsigned value = vpx_rb_read_literal(rb, bits + 1) << nbits;
return ((int) value) >> nbits;
#else
return vpx_rb_read_signed_literal(rb, bits);
#endif
}

View File

@ -38,6 +38,8 @@ int vpx_rb_read_literal(struct vpx_read_bit_buffer *rb, int bits);
int vpx_rb_read_signed_literal(struct vpx_read_bit_buffer *rb, int bits); int vpx_rb_read_signed_literal(struct vpx_read_bit_buffer *rb, int bits);
int vpx_rb_read_inv_signed_literal(struct vpx_read_bit_buffer *rb, int bits);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View File

@ -9,7 +9,9 @@
*/ */
#include <limits.h> #include <limits.h>
#include <stdlib.h>
#include "./vpx_config.h"
#include "./bitwriter_buffer.h" #include "./bitwriter_buffer.h"
size_t vpx_wb_bytes_written(const struct vpx_write_bit_buffer *wb) { size_t vpx_wb_bytes_written(const struct vpx_write_bit_buffer *wb) {
@ -34,3 +36,13 @@ void vpx_wb_write_literal(struct vpx_write_bit_buffer *wb, int data, int bits) {
for (bit = bits - 1; bit >= 0; bit--) for (bit = bits - 1; bit >= 0; bit--)
vpx_wb_write_bit(wb, (data >> bit) & 1); vpx_wb_write_bit(wb, (data >> bit) & 1);
} }
void vpx_wb_write_inv_signed_literal(struct vpx_write_bit_buffer *wb,
int data, int bits) {
#if CONFIG_MISC_FIXES
vpx_wb_write_literal(wb, data, bits + 1);
#else
vpx_wb_write_literal(wb, abs(data), bits);
vpx_wb_write_bit(wb, data < 0);
#endif
}

View File

@ -28,6 +28,8 @@ void vpx_wb_write_bit(struct vpx_write_bit_buffer *wb, int bit);
void vpx_wb_write_literal(struct vpx_write_bit_buffer *wb, int data, int bits); void vpx_wb_write_literal(struct vpx_write_bit_buffer *wb, int data, int bits);
void vpx_wb_write_inv_signed_literal(struct vpx_write_bit_buffer *wb, int data,
int bits);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"