Add av1_cost_coeffs_txb() for lv_map experiment

Change-Id: I44842387207b19f8e0c3894d3f4e8d0646a4cafd
This commit is contained in:
Angie Chiang 2017-02-27 14:30:38 -08:00
Родитель bff32ac056
Коммит 47c7218942
2 изменённых файлов: 170 добавлений и 0 удалений

Просмотреть файл

@ -10,6 +10,7 @@
*/
#include "av1/common/scan.h"
#include "av1/encoder/cost.h"
#include "av1/encoder/encodetxb.h"
static void write_golomb(aom_writer *w, int level) {
@ -131,3 +132,171 @@ void av1_write_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
write_golomb(w, level - COEFF_BASE_RANGE - 1 - NUM_BASE_LEVELS);
}
}
static INLINE void get_base_ctx_set(const tran_low_t *tcoeffs,
int c, // raster order
const int bwl,
int ctx_set[NUM_BASE_LEVELS]) {
const int row = c >> bwl;
const int col = c - (row << bwl);
const int stride = 1 << bwl;
int mag[NUM_BASE_LEVELS] = { 0 };
int idx;
tran_low_t abs_coeff;
int i;
for (idx = 0; idx < BASE_CONTEXT_POSITION_NUM; ++idx) {
int ref_row = row + base_ref_offset[idx][0];
int ref_col = col + base_ref_offset[idx][1];
int pos = (ref_row << bwl) + ref_col;
if (ref_row < 0 || ref_col < 0 || ref_row >= stride || ref_col >= stride)
continue;
abs_coeff = abs(tcoeffs[pos]);
for (i = 0; i < NUM_BASE_LEVELS; ++i) {
ctx_set[i] += abs_coeff > i;
if (base_ref_offset[idx][0] >= 0 && base_ref_offset[idx][1] >= 0)
mag[i] |= abs_coeff > (i + 1);
}
}
for (i = 0; i < NUM_BASE_LEVELS; ++i) {
ctx_set[i] = (ctx_set[i] + 1) >> 1;
if (row == 0 && col == 0)
ctx_set[i] = (ctx_set[i] << 1) + mag[i];
else if (row == 0)
ctx_set[i] = 8 + (ctx_set[i] << 1) + mag[i];
else if (col == 0)
ctx_set[i] = 18 + (ctx_set[i] << 1) + mag[i];
else
ctx_set[i] = 28 + (ctx_set[i] << 1) + mag[i];
}
return;
}
int av1_cost_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
int block, TXB_CTX *txb_ctx, int *cul_level) {
MACROBLOCKD *const xd = &x->e_mbd;
const TX_SIZE tx_size = get_tx_size(plane, xd);
const PLANE_TYPE plane_type = get_plane_type(plane);
const TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
const struct macroblock_plane *p = &x->plane[plane];
const int eob = p->eobs[block];
const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
int c, cost;
const int seg_eob = AOMMIN(eob, (16 << (tx_size << 1)) - 1);
int txb_skip_ctx = txb_ctx->txb_skip_ctx;
aom_prob *nz_map = xd->fc->nz_map[tx_size][plane_type];
const int bwl = b_width_log2_lookup[txsize_to_bsize[tx_size]] + 2;
*cul_level = 0;
// txb_mask is only initialized for once here. After that, it will be set when
// coding zero map and then reset when coding level 1 info.
uint8_t txb_mask[32 * 32] = { 0 };
aom_prob(*coeff_base)[COEFF_BASE_CONTEXTS] =
xd->fc->coeff_base[tx_size][plane_type];
const SCAN_ORDER *const scan_order =
get_scan(cm, tx_size, tx_type, is_inter_block(mbmi));
const int16_t *scan = scan_order->scan;
cost = 0;
if (eob == 0) {
cost = av1_cost_bit(xd->fc->txb_skip[tx_size][txb_skip_ctx], 1);
return cost;
}
cost = av1_cost_bit(xd->fc->txb_skip[tx_size][txb_skip_ctx], 0);
for (c = 0; c < eob; ++c) {
tran_low_t v = qcoeff[scan[c]];
int is_nz = (v != 0);
int level = abs(v);
if (c < seg_eob) {
int coeff_ctx = get_nz_map_ctx(qcoeff, txb_mask, scan[c], bwl);
cost += av1_cost_bit(nz_map[coeff_ctx], is_nz);
}
if (is_nz) {
int ctx_ls[NUM_BASE_LEVELS] = { 0 };
int sign = (v < 0) ? 1 : 0;
// sign bit cost
if (c == 0) {
int dc_sign_ctx = txb_ctx->dc_sign_ctx;
cost += av1_cost_bit(xd->fc->dc_sign[plane_type][dc_sign_ctx], sign);
} else {
cost += av1_cost_bit(128, sign);
}
get_base_ctx_set(qcoeff, scan[c], bwl, ctx_ls);
int i;
for (i = 0; i < NUM_BASE_LEVELS; ++i) {
if (level <= i) continue;
if (level == i + 1) {
cost += av1_cost_bit(coeff_base[i][ctx_ls[i]], 1);
*cul_level += level;
continue;
}
cost += av1_cost_bit(coeff_base[i][ctx_ls[i]], 0);
}
if (level > NUM_BASE_LEVELS) {
int idx;
int ctx;
*cul_level += level;
ctx = get_level_ctx(qcoeff, scan[c], bwl);
for (idx = 0; idx < COEFF_BASE_RANGE; ++idx) {
if (level == (idx + 1 + NUM_BASE_LEVELS)) {
cost +=
av1_cost_bit(xd->fc->coeff_lps[tx_size][plane_type][ctx], 1);
break;
}
cost += av1_cost_bit(xd->fc->coeff_lps[tx_size][plane_type][ctx], 0);
}
if (idx >= COEFF_BASE_RANGE) {
// residual cost
int r = level - COEFF_BASE_RANGE - NUM_BASE_LEVELS;
int ri = r;
int length = 0;
while (ri) {
ri >>= 1;
++length;
}
for (ri = 0; ri < length - 1; ++ri) cost += av1_cost_bit(128, 0);
for (ri = length - 1; ri >= 0; --ri)
cost += av1_cost_bit(128, (r >> ri) & 0x01);
}
}
if (c < seg_eob) {
int eob_ctx = get_eob_ctx(qcoeff, scan[c], bwl);
cost += av1_cost_bit(xd->fc->eob_flag[tx_size][plane_type][eob_ctx],
c == (eob - 1));
}
}
txb_mask[scan[c]] = 1;
}
*cul_level = AOMMIN(63, *cul_level);
// DC value
set_dc_sign(cul_level, qcoeff[0]);
return cost;
}

Просмотреть файл

@ -16,6 +16,7 @@
#include "av1/common/blockd.h"
#include "av1/common/onyxc_int.h"
#include "av1/common/txb_common.h"
#include "av1/encoder/block.h"
#include "aom_dsp/bitwriter.h"
#ifdef __cplusplus
extern "C" {