diff --git a/vp9/common/vp9_seg_common.c b/vp9/common/vp9_seg_common.c index 6ac27e396..46a6ee454 100644 --- a/vp9/common/vp9_seg_common.c +++ b/vp9/common/vp9_seg_common.c @@ -8,11 +8,13 @@ * be found in the AUTHORS file in the root of the source tree. */ +#include +#include "vp9/common/vp9_blockd.h" #include "vp9/common/vp9_seg_common.h" static const int segfeaturedata_signed[SEG_LVL_MAX] = { 1, 1, 0, 0, 0, 0 }; -static const int seg_feature_data_bits[SEG_LVL_MAX] = - { QINDEX_BITS, 6, 4, 5, 8, 2 }; +static const int seg_feature_data_max[SEG_LVL_MAX] = + { MAXQ, 63, 0xf, MB_MODE_COUNT - 1, 255, TX_SIZE_MAX - 1}; // These functions provide access to new segment level features. // Eventually these function may be "optimized out" but for the moment, @@ -45,8 +47,8 @@ void vp9_disable_segfeature(MACROBLOCKD *xd, xd->segment_feature_mask[segment_id] &= ~(1 << feature_id); } -int vp9_seg_feature_data_bits(SEG_LVL_FEATURES feature_id) { - return seg_feature_data_bits[feature_id]; +int vp9_seg_feature_data_max(SEG_LVL_FEATURES feature_id) { + return seg_feature_data_max[feature_id]; } int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id) { @@ -63,6 +65,12 @@ void vp9_set_segdata(MACROBLOCKD *xd, int segment_id, SEG_LVL_FEATURES feature_id, int seg_data) { + assert(seg_data <= seg_feature_data_max[feature_id]); + if (seg_data < 0) { + assert(segfeaturedata_signed[feature_id]); + assert(-seg_data <= seg_feature_data_max[feature_id]); + } + xd->segment_feature_data[segment_id][feature_id] = seg_data; } diff --git a/vp9/common/vp9_seg_common.h b/vp9/common/vp9_seg_common.h index fb0570c6b..20959a705 100644 --- a/vp9/common/vp9_seg_common.h +++ b/vp9/common/vp9_seg_common.h @@ -29,7 +29,7 @@ void vp9_disable_segfeature(MACROBLOCKD *xd, int segment_id, SEG_LVL_FEATURES feature_id); -int vp9_seg_feature_data_bits(SEG_LVL_FEATURES feature_id); +int vp9_seg_feature_data_max(SEG_LVL_FEATURES feature_id); int vp9_is_segfeature_signed(SEG_LVL_FEATURES feature_id); diff --git a/vp9/decoder/vp9_dboolhuff.c b/vp9/decoder/vp9_dboolhuff.c index dc3878e9d..885ec0df6 100644 --- a/vp9/decoder/vp9_dboolhuff.c +++ b/vp9/decoder/vp9_dboolhuff.c @@ -98,3 +98,15 @@ int vp9_decode_term_subexp(BOOL_DECODER *br, int k, int num_syms) { } return word; } + +int vp9_decode_unsigned_max(BOOL_DECODER *br, int max) { + int data = 0, bit = 0, lmax = max; + + while (lmax) { + data |= decode_bool(br, 128) << bit++; + lmax >>= 1; + } + if (data > max) + return max; + return data; +} diff --git a/vp9/decoder/vp9_dboolhuff.h b/vp9/decoder/vp9_dboolhuff.h index d46d81bb4..6529170ab 100644 --- a/vp9/decoder/vp9_dboolhuff.h +++ b/vp9/decoder/vp9_dboolhuff.h @@ -150,4 +150,6 @@ static int bool_error(BOOL_DECODER *br) { return 0; } +extern int vp9_decode_unsigned_max(BOOL_DECODER *br, int max); + #endif diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index a89670108..2adbb903b 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -1141,13 +1141,13 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) { // Update the feature data and mask vp9_enable_segfeature(xd, i, j); - data = (signed char)vp9_read_literal( - &header_bc, vp9_seg_feature_data_bits(j)); + data = vp9_decode_unsigned_max(&header_bc, + vp9_seg_feature_data_max(j)); // Is the segment data signed.. if (vp9_is_segfeature_signed(j)) { if (vp9_read_bit(&header_bc)) - data = - data; + data = -data; } } else data = 0; diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c index ae8a7c616..73c116766 100644 --- a/vp9/encoder/vp9_bitstream.c +++ b/vp9/encoder/vp9_bitstream.c @@ -1911,19 +1911,19 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest, // Encode the relevant feature data if (Data < 0) { Data = - Data; - vp9_write_literal(&header_bc, Data, - vp9_seg_feature_data_bits(j)); + vp9_encode_unsigned_max(&header_bc, Data, + vp9_seg_feature_data_max(j)); vp9_write_bit(&header_bc, 1); } else { - vp9_write_literal(&header_bc, Data, - vp9_seg_feature_data_bits(j)); + vp9_encode_unsigned_max(&header_bc, Data, + vp9_seg_feature_data_max(j)); vp9_write_bit(&header_bc, 0); } } // Unsigned data element so no sign bit needed else - vp9_write_literal(&header_bc, Data, - vp9_seg_feature_data_bits(j)); + vp9_encode_unsigned_max(&header_bc, Data, + vp9_seg_feature_data_max(j)); } else vp9_write_bit(&header_bc, 0); } diff --git a/vp9/encoder/vp9_boolhuff.c b/vp9/encoder/vp9_boolhuff.c index 7619dfadf..2689ab601 100644 --- a/vp9/encoder/vp9_boolhuff.c +++ b/vp9/encoder/vp9_boolhuff.c @@ -8,7 +8,7 @@ * be found in the AUTHORS file in the root of the source tree. */ - +#include #include "vp9_boolhuff.h" #if defined(SECTIONBITS_OUTPUT) @@ -64,6 +64,15 @@ void vp9_encode_value(BOOL_CODER *br, int data, int bits) { encode_bool(br, (1 & (data >> bit)), 0x80); } +void vp9_encode_unsigned_max(BOOL_CODER *br, int data, int max) { + assert(data <= max); + while (max) { + encode_bool(br, data & 1, 128); + data >>= 1; + max >>= 1; + } +} + int vp9_recenter_nonneg(int v, int m) { if (v > (m << 1)) return v; else if (v >= m) return ((v - m) << 1); diff --git a/vp9/encoder/vp9_boolhuff.h b/vp9/encoder/vp9_boolhuff.h index 2fad86b2e..1958a41e1 100644 --- a/vp9/encoder/vp9_boolhuff.h +++ b/vp9/encoder/vp9_boolhuff.h @@ -37,6 +37,7 @@ typedef struct { extern void vp9_start_encode(BOOL_CODER *bc, unsigned char *buffer); extern void vp9_encode_value(BOOL_CODER *br, int data, int bits); +extern void vp9_encode_unsigned_max(BOOL_CODER *br, int data, int max); extern void vp9_stop_encode(BOOL_CODER *bc); extern const unsigned int vp9_prob_cost[256];