ref: a1f15814be0eb9921a6b5bb102354df7eeb936b2
parent: 1760c39bcee3a6fc8e5998619bc7970755b528f6
author: John Koleszar <jkoleszar@google.com>
date: Tue Nov 27 06:16:15 EST 2012
Clamp decoded feature data Not all segment feature data elements are full-range powers of two, so there are values that can be encoded that are invalid. Add a new function to clamp values to the maximum allowed. Change-Id: Ie47cb80ef2d54292e6b8db9f699c57214a915bc4
--- 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 <assert.h>
+#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 @@
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 @@
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;
}
--- a/vp9/common/vp9_seg_common.h
+++ b/vp9/common/vp9_seg_common.h
@@ -29,7 +29,7 @@
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);
--- a/vp9/decoder/vp9_dboolhuff.c
+++ b/vp9/decoder/vp9_dboolhuff.c
@@ -98,3 +98,15 @@
}
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;
+}
--- a/vp9/decoder/vp9_dboolhuff.h
+++ b/vp9/decoder/vp9_dboolhuff.h
@@ -150,4 +150,6 @@
return 0;
}
+extern int vp9_decode_unsigned_max(BOOL_DECODER *br, int max);
+
#endif
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -1134,13 +1134,13 @@
// 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;
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1911,19 +1911,19 @@
// 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);
}
--- 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 <assert.h>
#include "vp9_boolhuff.h"
#if defined(SECTIONBITS_OUTPUT)
@@ -62,6 +62,15 @@
for (bit = bits - 1; bit >= 0; bit--)
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) {
--- a/vp9/encoder/vp9_boolhuff.h
+++ b/vp9/encoder/vp9_boolhuff.h
@@ -37,6 +37,7 @@
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];
--
⑨