Refactor av1_update_neighbors
Beside above and left positions, additional above-left,
above-right, and bottom-left positions are added as
neighbor candidates.
In av1_update_neighbors, two available positions will be picked as
context neighbors.
The picking priority is
above -> left -> above-left -> above->right -> bottom->left
Change-Id: I82eaf0b23d0189caaea008ecc86776492886a05b
diff --git a/av1/common/scan.c b/av1/common/scan.c
index bf161ab..b5cde7c 100644
--- a/av1/common/scan.c
+++ b/av1/common/scan.c
@@ -6500,19 +6500,32 @@
const int coeff_idx = scan[scan_idx];
const int r = coeff_idx / tx1d_size;
const int c = coeff_idx % tx1d_size;
- const int has_left = c > 0 && iscan[coeff_idx - 1] < scan_idx;
- const int has_above = r > 0 && iscan[coeff_idx - tx1d_size] < scan_idx;
+ const int nb_offset_r[5] = { -1, 0, -1, -1, 1 };
+ const int nb_offset_c[5] = { 0, -1, -1, 1, -1 };
+ const int nb_num = 5;
+ int nb_count = 0;
+ int nb_idx;
- if (has_left && has_above) {
- neighbors[scan_idx * MAX_NEIGHBORS + 0] = coeff_idx - 1;
- neighbors[scan_idx * MAX_NEIGHBORS + 1] = coeff_idx - tx1d_size;
- } else if (has_left) {
- neighbors[scan_idx * MAX_NEIGHBORS + 0] = coeff_idx - 1;
- neighbors[scan_idx * MAX_NEIGHBORS + 1] = coeff_idx - 1;
- } else if (has_above) {
- neighbors[scan_idx * MAX_NEIGHBORS + 0] = coeff_idx - tx1d_size;
- neighbors[scan_idx * MAX_NEIGHBORS + 1] = coeff_idx - tx1d_size;
- } else {
+ for (nb_idx = 0; nb_idx < nb_num; ++nb_idx) {
+ if (nb_count < 2) {
+ int nb_r = r + nb_offset_r[nb_idx];
+ int nb_c = c + nb_offset_c[nb_idx];
+ int nb_coeff_idx = nb_r * tx1d_size + nb_c;
+ int valid_pos =
+ nb_r >= 0 && nb_r < tx1d_size && nb_c >= 0 && nb_c < tx1d_size;
+ if (valid_pos && iscan[nb_coeff_idx] < scan_idx) {
+ neighbors[scan_idx * MAX_NEIGHBORS + nb_count] = nb_coeff_idx;
+ ++nb_count;
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (nb_count == 1) {
+ neighbors[scan_idx * MAX_NEIGHBORS + 1] =
+ neighbors[scan_idx * MAX_NEIGHBORS + 0];
+ } else if (nb_count == 0) {
neighbors[scan_idx * MAX_NEIGHBORS + 0] = scan[0];
neighbors[scan_idx * MAX_NEIGHBORS + 1] = scan[0];
}
diff --git a/test/scan_test.cc b/test/scan_test.cc
index 6c7fecf..5724883 100644
--- a/test/scan_test.cc
+++ b/test/scan_test.cc
@@ -81,13 +81,14 @@
const int16_t scan[16] = { 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15 };
int16_t nb[(16 + 1) * 2];
- const int16_t ref_nb[(16 + 1) * 2] = { 0, 0, 0, 0, 1, 1, 2, 2, 0,
- 0, 4, 1, 5, 2, 6, 3, 4, 4,
- 8, 5, 9, 6, 10, 7, 8, 8, 12,
- 9, 13, 10, 14, 11, 0, 0 };
+ const int16_t ref_nb[(16 + 1) * 2] = { 0, 0, 0, 0, 1, 1, 2, 2, 0,
+ 1, 1, 4, 2, 5, 3, 6, 4, 5,
+ 5, 8, 6, 9, 7, 10, 8, 9, 9,
+ 12, 10, 13, 11, 14, 0, 0 };
// raster order's scan and iscan are the same
av1_update_neighbors(tx_size, scan, scan, nb);
+
for (int i = 0; i < (16 + 1) * 2; ++i) {
EXPECT_EQ(ref_nb[i], nb[i]);
}