Add update_level_down()
This function will update txb_cache and txb_info affected by
downgrading the coeff by one level
Change-Id: I57f9377eb7fb94b4244e677704b33c5eece83133
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index 6d82c64..50ed21d 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -591,6 +591,13 @@
return qc > 0 ? qc - 1 : qc + 1;
}
+static INLINE void update_mag_arr(int *mag_arr, int abs_qc) {
+ if (mag_arr[0] == abs_qc) {
+ mag_arr[1] -= 1;
+ assert(mag_arr[1] >= 0);
+ }
+}
+
static INLINE int get_mag_from_mag_arr(const int *mag_arr) {
int mag;
if (mag_arr[1] > 0) {
@@ -991,6 +998,110 @@
return sgn * ((abs(qc) * dqv) >> shift);
}
+// TODO(angiebird): add static to this function it's called
+void update_level_down(int coeff_idx, TxbCache *txb_cache, TxbInfo *txb_info) {
+ const tran_low_t qc = txb_info->qcoeff[coeff_idx];
+ const int abs_qc = abs(qc);
+ if (qc == 0) return;
+ const tran_low_t low_coeff = get_lower_coeff(qc);
+ txb_info->qcoeff[coeff_idx] = low_coeff;
+ const int dqv = txb_info->dequant[coeff_idx != 0];
+ txb_info->dqcoeff[coeff_idx] =
+ qcoeff_to_dqcoeff(low_coeff, dqv, txb_info->shift);
+
+ const int row = coeff_idx >> txb_info->bwl;
+ const int col = coeff_idx - (row << txb_info->bwl);
+ const int eob = txb_info->eob;
+ const int16_t *iscan = txb_info->scan_order->iscan;
+ for (int i = 0; i < SIG_REF_OFFSET_NUM; ++i) {
+ const int nb_row = row - sig_ref_offset[i][0];
+ const int nb_col = col - sig_ref_offset[i][1];
+ const int nb_coeff_idx = nb_row * txb_info->stride + nb_col;
+ const int nb_scan_idx = iscan[nb_coeff_idx];
+ if (nb_scan_idx < eob && nb_row >= 0 && nb_col >= 0 &&
+ nb_row < txb_info->stride && nb_col < txb_info->stride) {
+ const int scan_idx = iscan[coeff_idx];
+ if (scan_idx < nb_scan_idx) {
+ const int level = 1;
+ if (abs_qc == level) {
+ txb_cache->nz_count_arr[nb_coeff_idx] -= 1;
+ assert(txb_cache->nz_count_arr[nb_coeff_idx] >= 0);
+ }
+ const int count = txb_cache->nz_count_arr[nb_coeff_idx];
+ txb_cache->nz_ctx_arr[nb_coeff_idx][0] = get_nz_map_ctx_from_count(
+ count, txb_info->qcoeff, nb_coeff_idx, txb_info->bwl, iscan);
+ // int ref_ctx = get_nz_map_ctx2(txb_info->qcoeff, nb_coeff_idx,
+ // txb_info->bwl, iscan);
+ // if (ref_ctx != txb_cache->nz_ctx_arr[nb_coeff_idx][0])
+ // printf("nz ctx %d ref_ctx %d\n",
+ // txb_cache->nz_ctx_arr[nb_coeff_idx][0], ref_ctx);
+ }
+ }
+ }
+
+ for (int i = 0; i < BASE_CONTEXT_POSITION_NUM; ++i) {
+ const int nb_row = row - base_ref_offset[i][0];
+ const int nb_col = col - base_ref_offset[i][1];
+ const int nb_coeff_idx = nb_row * txb_info->stride + nb_col;
+ const tran_low_t nb_coeff = txb_info->qcoeff[nb_coeff_idx];
+ if (!has_base(nb_coeff, 0)) continue;
+ const int nb_scan_idx = iscan[nb_coeff_idx];
+ if (nb_scan_idx < eob && nb_row >= 0 && nb_col >= 0 &&
+ nb_row < txb_info->stride && nb_col < txb_info->stride) {
+ if (row >= nb_row && col >= nb_col)
+ update_mag_arr(txb_cache->base_mag_arr[nb_coeff_idx], abs_qc);
+ const int mag =
+ get_mag_from_mag_arr(txb_cache->base_mag_arr[nb_coeff_idx]);
+ for (int base_idx = 0; base_idx < NUM_BASE_LEVELS; ++base_idx) {
+ if (!has_base(nb_coeff, base_idx)) continue;
+ const int level = base_idx + 1;
+ if (abs_qc == level) {
+ txb_cache->base_count_arr[base_idx][nb_coeff_idx] -= 1;
+ assert(txb_cache->base_count_arr[base_idx][nb_coeff_idx] >= 0);
+ }
+ const int count = txb_cache->base_count_arr[base_idx][nb_coeff_idx];
+ txb_cache->base_ctx_arr[base_idx][nb_coeff_idx][0] =
+ get_base_ctx_from_count_mag(nb_row, nb_col, count, mag, level);
+ // int ref_ctx = get_base_ctx(txb_info->qcoeff, nb_coeff_idx,
+ // txb_info->bwl, level);
+ // if (ref_ctx != txb_cache->base_ctx_arr[base_idx][nb_coeff_idx][0]) {
+ // printf("base ctx %d ref_ctx %d\n",
+ // txb_cache->base_ctx_arr[base_idx][nb_coeff_idx][0], ref_ctx);
+ // }
+ }
+ }
+ }
+
+ for (int i = 0; i < BR_CONTEXT_POSITION_NUM; ++i) {
+ const int nb_row = row - br_ref_offset[i][0];
+ const int nb_col = col - br_ref_offset[i][1];
+ const int nb_coeff_idx = nb_row * txb_info->stride + nb_col;
+ const int nb_scan_idx = iscan[nb_coeff_idx];
+ const tran_low_t nb_coeff = txb_info->qcoeff[nb_coeff_idx];
+ if (!has_br(nb_coeff)) continue;
+ if (nb_scan_idx < eob && nb_row >= 0 && nb_col >= 0 &&
+ nb_row < txb_info->stride && nb_col < txb_info->stride) {
+ const int level = 1 + NUM_BASE_LEVELS;
+ if (abs_qc == level) {
+ txb_cache->br_count_arr[nb_coeff_idx] -= 1;
+ assert(txb_cache->br_count_arr[nb_coeff_idx] >= 0);
+ }
+ if (row >= nb_row && col >= nb_col)
+ update_mag_arr(txb_cache->br_mag_arr[nb_coeff_idx], abs_qc);
+ const int count = txb_cache->br_count_arr[nb_coeff_idx];
+ const int mag = get_mag_from_mag_arr(txb_cache->br_mag_arr[nb_coeff_idx]);
+ txb_cache->br_ctx_arr[nb_coeff_idx][0] =
+ get_br_ctx_from_count_mag(nb_row, nb_col, count, mag);
+ // int ref_ctx = get_level_ctx(txb_info->qcoeff, nb_coeff_idx,
+ // txb_info->bwl);
+ // if (ref_ctx != txb_cache->br_ctx_arr[nb_coeff_idx][0]) {
+ // printf("base ctx %d ref_ctx %d\n",
+ // txb_cache->br_ctx_arr[nb_coeff_idx][0], ref_ctx);
+ // }
+ }
+ }
+}
+
static int get_coeff_cost(tran_low_t qc, int scan_idx, TxbInfo *txb_info,
TxbProbs *txb_probs) {
const TXB_CTX *txb_ctx = txb_info->txb_ctx;