Commit c0cf71df authored by hui su's avatar hui su Committed by Hui Su

Calculate coeff token cost from CDF

AWCY results:
PSNR	PSNR HVS  SSIM	CIEDE 2000
-0.09	-0.04	  -0.02	  -0.03

On Google testsets:
lowres  -0.18%
midres  -0.20%

Above results are obtained with
--disable-ext-refs --disable-dual-filter --disable-loop-restoration
--disable-global-motion --disable-warped-motion

Change-Id: Iba58d5e5ec9a65d0afba29609aa2e379a80d7236
parent 9b0f7038
......@@ -60,10 +60,8 @@ typedef struct macroblock_plane {
#endif // CONFIG_NEW_QUANT
} MACROBLOCK_PLANE;
/* The [2] dimension is for whether we skip the EOB node (i.e. if previous
* coefficient in this block was zero) or not. */
typedef unsigned int av1_coeff_cost[PLANE_TYPES][REF_TYPES][COEF_BANDS][2]
[COEFF_CONTEXTS][ENTROPY_TOKENS];
typedef int av1_coeff_cost[PLANE_TYPES][REF_TYPES][COEF_BANDS][COEFF_CONTEXTS]
[TAIL_TOKENS];
typedef struct {
int_mv ref_mvs[MODE_CTX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
......@@ -169,8 +167,8 @@ struct macroblock {
int skip_chroma_rd;
#endif
// note that token_costs is the cost when eob node is skipped
av1_coeff_cost token_costs[TX_SIZES];
av1_coeff_cost token_head_costs[TX_SIZES];
av1_coeff_cost token_tail_costs[TX_SIZES];
// mode costs
int mbmode_cost[BLOCK_SIZE_GROUPS][INTRA_MODES];
......
......@@ -115,15 +115,7 @@ static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
{ 10, 7 }, { 8, 5 },
};
static INLINE unsigned int get_token_bit_costs(
unsigned int token_costs[2][COEFF_CONTEXTS][ENTROPY_TOKENS], int skip_eob,
int ctx, int token) {
(void)skip_eob;
return token_costs[token == ZERO_TOKEN || token == EOB_TOKEN][ctx][token];
}
#if !CONFIG_LV_MAP
static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
int blk_row, int blk_col, int block,
TX_SIZE tx_size, int ctx) {
......@@ -164,8 +156,10 @@ static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
int16_t t0, t1;
int i, final_eob;
const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
mb->token_costs[txsize_sqr_map[tx_size]][plane_type][ref];
int(*head_token_costs)[COEFF_CONTEXTS][TAIL_TOKENS] =
mb->token_head_costs[txsize_sqr_map[tx_size]][plane_type][ref];
int(*tail_token_costs)[COEFF_CONTEXTS][TAIL_TOKENS] =
mb->token_tail_costs[txsize_sqr_map[tx_size]][plane_type][ref];
const int default_eob = tx_size_2d[tx_size];
assert(mb->qindex > 0);
......@@ -181,9 +175,6 @@ static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
token_cache[rc] = av1_pt_energy_class[av1_get_token(qcoeff[rc])];
}
unsigned int(*token_costs_ptr)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
token_costs;
final_eob = 0;
int64_t eob_cost0, eob_cost1;
......@@ -197,12 +188,12 @@ static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
// This ensures that it never goes negative.
int64_t accu_error = ((int64_t)1) << 50;
rate0 = get_token_bit_costs(*(token_costs_ptr + band_translate[0]), 0, ctx0,
EOB_TOKEN);
rate0 = head_token_costs[0][ctx0][0];
int64_t best_block_rd_cost = RDCOST(rdmult, rate0, accu_error);
// int64_t best_block_rd_cost_all0 = best_block_rd_cost;
int x_prev = 1;
const int seg_eob =
av1_get_tx_eob(&cm->seg, xd->mi[0]->mbmi.segment_id, tx_size);
for (i = 0; i < eob; i++) {
const int rc = scan[i];
int x = qcoeff[rc];
......@@ -210,15 +201,17 @@ static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
int band_cur = band_translate[i];
int ctx_cur = (i == 0) ? ctx : get_coef_context(nb, token_cache, i);
int token_tree_sel_cur = (x_prev == 0);
const int eob_val =
(i + 1 == eob) ? (i + 1 == seg_eob ? LAST_EOB : EARLY_EOB) : NO_EOB;
const int is_first = (i == 0);
if (x == 0) {
// no need to search when x == 0
int token = av1_get_token(x);
rate0 = get_token_bit_costs(*(token_costs_ptr + band_cur),
token_tree_sel_cur, ctx_cur, token);
rate0 = av1_get_coeff_token_cost(token, eob_val, is_first,
head_token_costs[band_cur][ctx_cur],
tail_token_costs[band_cur][ctx_cur]);
accu_rate += rate0;
x_prev = 0;
// accu_error does not change when x==0
} else {
/* Computing distortion
......@@ -286,66 +279,70 @@ static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
/* Computing rates and r-d cost
*/
int best_x, best_eob_x;
int64_t base_bits, next_bits0, next_bits1;
int64_t next_eob_bits0, next_eob_bits1;
int64_t base_bits;
// rate cost of x
base_bits = av1_get_token_cost(x, &t0, cat6_bits);
rate0 = base_bits + get_token_bit_costs(*(token_costs_ptr + band_cur),
token_tree_sel_cur, ctx_cur, t0);
rate0 = base_bits +
av1_get_coeff_token_cost(t0, eob_val, is_first,
head_token_costs[band_cur][ctx_cur],
tail_token_costs[band_cur][ctx_cur]);
base_bits = av1_get_token_cost(x_a, &t1, cat6_bits);
rate1 = base_bits + get_token_bit_costs(*(token_costs_ptr + band_cur),
token_tree_sel_cur, ctx_cur, t1);
next_bits0 = 0;
next_bits1 = 0;
next_eob_bits0 = 0;
next_eob_bits1 = 0;
if (t1 == ZERO_TOKEN && eob_val) {
rate1 = base_bits;
} else {
rate1 = base_bits +
av1_get_coeff_token_cost(t1, eob_val, is_first,
head_token_costs[band_cur][ctx_cur],
tail_token_costs[band_cur][ctx_cur]);
}
int64_t next_bits0 = 0, next_bits1 = 0;
if (i < default_eob - 1) {
int ctx_next, token_tree_sel_next;
int ctx_next;
int band_next = band_translate[i + 1];
int token_next =
i + 1 != eob ? av1_get_token(qcoeff[scan[i + 1]]) : EOB_TOKEN;
(i + 1 != eob) ? av1_get_token(qcoeff[scan[i + 1]]) : EOB_TOKEN;
const int eob_val_next =
(i + 2 == eob) ? (i + 2 == seg_eob ? LAST_EOB : EARLY_EOB) : NO_EOB;
token_cache[rc] = av1_pt_energy_class[t0];
ctx_next = get_coef_context(nb, token_cache, i + 1);
token_tree_sel_next = (x == 0);
next_bits0 =
get_token_bit_costs(*(token_costs_ptr + band_next),
token_tree_sel_next, ctx_next, token_next);
next_eob_bits0 =
get_token_bit_costs(*(token_costs_ptr + band_next),
token_tree_sel_next, ctx_next, EOB_TOKEN);
if (token_next != EOB_TOKEN) {
next_bits0 =
av1_get_coeff_token_cost(token_next, eob_val_next, 0,
head_token_costs[band_next][ctx_next],
tail_token_costs[band_next][ctx_next]);
}
token_cache[rc] = av1_pt_energy_class[t1];
ctx_next = get_coef_context(nb, token_cache, i + 1);
token_tree_sel_next = (x_a == 0);
next_bits1 =
get_token_bit_costs(*(token_costs_ptr + band_next),
token_tree_sel_next, ctx_next, token_next);
if (x_a != 0) {
next_eob_bits1 =
get_token_bit_costs(*(token_costs_ptr + band_next),
token_tree_sel_next, ctx_next, EOB_TOKEN);
if (token_next != EOB_TOKEN) {
next_bits1 =
av1_get_coeff_token_cost(token_next, eob_val_next, 0,
head_token_costs[band_next][ctx_next],
tail_token_costs[band_next][ctx_next]);
}
}
rd_cost0 = RDCOST(rdmult, (rate0 + next_bits0), d2);
rd_cost1 = RDCOST(rdmult, (rate1 + next_bits1), d2_a);
int best_x = (rd_cost1 < rd_cost0);
best_x = (rd_cost1 < rd_cost0);
eob_cost0 = RDCOST(rdmult, (accu_rate + rate0 + next_eob_bits0),
(accu_error + d2 - d0));
int eob_v = (i + 1 == seg_eob) ? LAST_EOB : EARLY_EOB;
int64_t next_eob_bits0, next_eob_bits1;
int best_eob_x;
next_eob_bits0 = av1_get_coeff_token_cost(
t0, eob_v, is_first, head_token_costs[band_cur][ctx_cur],
tail_token_costs[band_cur][ctx_cur]);
eob_cost0 =
RDCOST(rdmult, (accu_rate + next_eob_bits0), (accu_error + d2 - d0));
eob_cost1 = eob_cost0;
if (x_a != 0) {
eob_cost1 = RDCOST(rdmult, (accu_rate + rate1 + next_eob_bits1),
next_eob_bits1 = av1_get_coeff_token_cost(
t1, eob_v, is_first, head_token_costs[band_cur][ctx_cur],
tail_token_costs[band_cur][ctx_cur]);
eob_cost1 = RDCOST(rdmult, (accu_rate + next_eob_bits1),
(accu_error + d2_a - d0));
best_eob_x = (eob_cost1 < eob_cost0);
} else {
......@@ -392,8 +389,6 @@ static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
}
assert(accu_error >= 0);
x_prev = qcoeff[rc];
// determine whether to move the eob position to i+1
int use_a = (x_a != 0) && (best_eob_x);
int64_t best_eob_cost_i = use_a ? eob_cost1 : eob_cost0;
......
......@@ -1574,7 +1574,7 @@ void av1_update_and_record_txb_context(int plane, int block, int blk_row,
const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi);
const int16_t *scan = scan_order->scan;
const int16_t *iscan = scan_order->iscan;
const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size);
const int seg_eob = av1_get_tx_eob(&cpi->common.seg, segment_id, tx_size);
int c, i;
TXB_CTX txb_ctx;
get_txb_ctx(plane_bsize, tx_size, plane, pd->above_context + blk_col,
......
......@@ -247,25 +247,6 @@ void av1_fill_mode_rates(AV1_COMMON *const cm, MACROBLOCK *x,
}
}
void av1_fill_token_costs(av1_coeff_cost *c,
av1_coeff_probs_model (*p)[PLANE_TYPES]) {
int i, j, k, l;
TX_SIZE t;
for (t = 0; t < TX_SIZES; ++t)
for (i = 0; i < PLANE_TYPES; ++i)
for (j = 0; j < REF_TYPES; ++j)
for (k = 0; k < COEF_BANDS; ++k)
for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l) {
aom_prob probs[ENTROPY_NODES];
av1_model_to_full_probs(p[t][i][j][k][l], probs);
av1_cost_tokens((int *)c[t][i][j][k][0][l], probs, av1_coef_tree);
av1_cost_tokens_skip((int *)c[t][i][j][k][1][l], probs,
av1_coef_tree);
assert(c[t][i][j][k][0][l][EOB_TOKEN] ==
c[t][i][j][k][1][l][EOB_TOKEN]);
}
}
// Values are now correlated to quantizer.
static int sad_per_bit16lut_8[QINDEX_RANGE];
static int sad_per_bit4lut_8[QINDEX_RANGE];
......@@ -440,6 +421,22 @@ void av1_set_mvcost(MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame, int ref,
x->nmvjointcost = x->nmv_vec_cost[nmv_ctx];
}
void fill_token_costs_from_cdf(av1_coeff_cost *cost,
coeff_cdf_model (*cdf)[PLANE_TYPES]) {
for (int tx = 0; tx < TX_SIZES; ++tx) {
for (int pt = 0; pt < PLANE_TYPES; ++pt) {
for (int rt = 0; rt < REF_TYPES; ++rt) {
for (int band = 0; band < COEF_BANDS; ++band) {
for (int ctx = 0; ctx < BAND_COEFF_CONTEXTS(band); ++ctx) {
av1_cost_tokens_from_cdf(cost[tx][pt][rt][band][ctx],
cdf[tx][pt][rt][band][ctx], NULL);
}
}
}
}
}
}
void av1_initialize_rd_consts(AV1_COMP *cpi) {
AV1_COMMON *const cm = &cpi->common;
MACROBLOCK *const x = &cpi->td.mb;
......@@ -475,7 +472,8 @@ void av1_initialize_rd_consts(AV1_COMP *cpi) {
#endif
if (cpi->oxcf.pass != 1) {
av1_fill_token_costs(x->token_costs, cm->fc->coef_probs);
fill_token_costs_from_cdf(x->token_head_costs, cm->fc->coef_head_cdfs);
fill_token_costs_from_cdf(x->token_tail_costs, cm->fc->coef_tail_cdfs);
#if CONFIG_GLOBAL_MOTION
for (int i = 0; i < TRANS_TYPES; ++i)
cpi->gmtype_cost[i] = (1 + (i > 0 ? GLOBAL_TYPE_BITS : 0))
......
......@@ -631,6 +631,16 @@ static INLINE void av1_merge_rd_stats(RD_STATS *rd_stats_dst,
#endif
}
static INLINE int av1_get_coeff_token_cost(int token, int eob_val, int is_first,
const int *head_cost_table,
const int *tail_cost_table) {
if (eob_val == LAST_EOB) return av1_cost_zero(128);
const int comb_symb = 2 * AOMMIN(token, TWO_TOKEN) - eob_val + is_first;
int cost = head_cost_table[comb_symb];
if (token > ONE_TOKEN) cost += tail_cost_table[token - TWO_TOKEN];
return cost;
}
struct TileInfo;
struct TileDataEnc;
struct AV1_COMP;
......@@ -676,9 +686,6 @@ void av1_update_rd_thresh_fact(const AV1_COMMON *const cm,
int (*fact)[MAX_MODES], int rd_thresh, int bsize,
int best_mode_index);
void av1_fill_token_costs(av1_coeff_cost *c,
av1_coeff_probs_model (*p)[PLANE_TYPES]);
static INLINE int rd_less_than_thresh(int64_t best_rd, int thresh,
int thresh_fact) {
return best_rd < ((int64_t)thresh * thresh_fact >> 5) || thresh == INT_MAX;
......
......@@ -1526,11 +1526,6 @@ static int64_t av1_block_error2_c(const tran_low_t *coeff,
#endif // CONFIG_PVQ
#if !CONFIG_PVQ || CONFIG_VAR_TX
/* The trailing '0' is a terminator which is used inside av1_cost_coeffs() to
* decide whether to include cost of a trailing EOB node or not (i.e. we
* can skip this if the last coefficient in this transform block, e.g. the
* 16th coefficient in a 4x4 block or the 64th coefficient in a 8x8 block,
* were non-zero). */
#if !CONFIG_LV_MAP
static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
int block, TX_SIZE tx_size, const SCAN_ORDER *scan_order,
......@@ -1545,16 +1540,18 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
const int eob = p->eobs[block];
const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
const int tx_size_ctx = txsize_sqr_map[tx_size];
unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
x->token_costs[tx_size_ctx][type][is_inter_block(mbmi)];
uint8_t token_cache[MAX_TX_SQUARE];
int pt = combine_entropy_contexts(*a, *l);
int c, cost;
const int16_t *scan = scan_order->scan;
const int16_t *nb = scan_order->neighbors;
const int ref = is_inter_block(mbmi);
aom_prob *blockz_probs =
cm->fc->blockzero_probs[txsize_sqr_map[tx_size]][type][ref];
int(*head_token_costs)[COEFF_CONTEXTS][TAIL_TOKENS] =
x->token_head_costs[tx_size_ctx][type][ref];
int(*tail_token_costs)[COEFF_CONTEXTS][TAIL_TOKENS] =
x->token_tail_costs[tx_size_ctx][type][ref];
const int seg_eob = av1_get_tx_eob(&cm->seg, mbmi->segment_id, tx_size);
int eob_val;
#if CONFIG_HIGHBITDEPTH
const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
......@@ -1569,8 +1566,8 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
(void)cm;
if (eob == 0) {
// single eob token
cost = av1_cost_bit(blockz_probs[pt], 0);
// block zero
cost = (*head_token_costs)[pt][0];
} else {
if (use_fast_coef_costing) {
int band_left = *band_count++;
......@@ -1579,10 +1576,13 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
int v = qcoeff[0];
int16_t prev_t;
cost = av1_get_token_cost(v, &prev_t, cat6_bits);
cost += (*token_costs)[!prev_t][pt][prev_t];
eob_val = (eob == 1) ? EARLY_EOB : NO_EOB;
cost += av1_get_coeff_token_cost(
prev_t, eob_val, 1, (*head_token_costs)[pt], (*tail_token_costs)[pt]);
token_cache[0] = av1_pt_energy_class[prev_t];
++token_costs;
++head_token_costs;
++tail_token_costs;
// ac tokens
for (c = 1; c < eob; c++) {
......@@ -1591,17 +1591,18 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
v = qcoeff[rc];
cost += av1_get_token_cost(v, &t, cat6_bits);
cost += (*token_costs)[!t][!prev_t][t];
eob_val =
(c + 1 == eob) ? (c + 1 == seg_eob ? LAST_EOB : EARLY_EOB) : NO_EOB;
cost += av1_get_coeff_token_cost(t, eob_val, 0,
(*head_token_costs)[!prev_t],
(*tail_token_costs)[!prev_t]);
prev_t = t;
if (!--band_left) {
band_left = *band_count++;
++token_costs;
++head_token_costs;
++tail_token_costs;
}
}
// eob token
cost += (*token_costs)[0][!prev_t][EOB_TOKEN];
} else { // !use_fast_coef_costing
int band_left = *band_count++;
......@@ -1609,10 +1610,13 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
int v = qcoeff[0];
int16_t tok;
cost = av1_get_token_cost(v, &tok, cat6_bits);
cost += (*token_costs)[!tok][pt][tok];
eob_val = (eob == 1) ? EARLY_EOB : NO_EOB;
cost += av1_get_coeff_token_cost(tok, eob_val, 1, (*head_token_costs)[pt],
(*tail_token_costs)[pt]);
token_cache[0] = av1_pt_energy_class[tok];
++token_costs;
++head_token_costs;
++tail_token_costs;
// ac tokens
for (c = 1; c < eob; c++) {
......@@ -1621,17 +1625,17 @@ static int cost_coeffs(const AV1_COMMON *const cm, MACROBLOCK *x, int plane,
v = qcoeff[rc];
cost += av1_get_token_cost(v, &tok, cat6_bits);
pt = get_coef_context(nb, token_cache, c);
cost += (*token_costs)[!tok][pt][tok];
eob_val =
(c + 1 == eob) ? (c + 1 == seg_eob ? LAST_EOB : EARLY_EOB) : NO_EOB;
cost += av1_get_coeff_token_cost(
tok, eob_val, 0, (*head_token_costs)[pt], (*tail_token_costs)[pt]);
token_cache[rc] = av1_pt_energy_class[tok];
if (!--band_left) {
band_left = *band_count++;
++token_costs;
++head_token_costs;
++tail_token_costs;
}
}
// eob token
pt = get_coef_context(nb, token_cache, c);
cost += (*token_costs)[0][pt][EOB_TOKEN];
}
}
......@@ -4679,8 +4683,8 @@ static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
#else
int tx_size_ctx = txsize_sqr_map[tx_size];
int coeff_ctx = get_entropy_context(tx_size, pta, ptl);
zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
[coeff_ctx][EOB_TOKEN];
zero_blk_rate =
x->token_head_costs[tx_size_ctx][pd->plane_type][1][0][coeff_ctx][0];
#endif
rd_stats->ref_rdcost = ref_best_rd;
......@@ -4757,8 +4761,8 @@ static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
tx_size_ctx = txsize_sqr_map[quarter_txsize];
coeff_ctx = get_entropy_context(quarter_txsize, pta, ptl);
zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
[coeff_ctx][EOB_TOKEN];
zero_blk_rate =
x->token_head_costs[tx_size_ctx][pd->plane_type][1][0][coeff_ctx][0];
if ((RDCOST(x->rdmult, rd_stats_qttx.rate, rd_stats_qttx.dist) >=
RDCOST(x->rdmult, zero_blk_rate, rd_stats_qttx.sse) ||
rd_stats_qttx.skip == 1) &&
......@@ -4787,8 +4791,8 @@ static void select_tx_block(const AV1_COMP *cpi, MACROBLOCK *x, int blk_row,
av1_set_txb_context(x, plane, 0, quarter_txsize, pta, ptl);
coeff_ctx = get_entropy_context(quarter_txsize, pta + blk_col_offset,
ptl + blk_row_offset);
zero_blk_rate = x->token_costs[tx_size_ctx][pd->plane_type][1][0][0]
[coeff_ctx][EOB_TOKEN];
zero_blk_rate =
x->token_head_costs[tx_size_ctx][pd->plane_type][1][0][coeff_ctx][0];
if ((RDCOST(x->rdmult, rd_stats_tmp.rate, rd_stats_tmp.dist) >=
RDCOST(x->rdmult, zero_blk_rate, rd_stats_tmp.sse) ||
rd_stats_tmp.skip == 1) &&
......
......@@ -456,7 +456,7 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
td->counts->blockz_count[txsize_sqr_map[tx_size]][type][ref];
int eob_val;
int first_val = 1;
const int seg_eob = get_tx_eob(&cpi->common.seg, segment_id, tx_size);
const int seg_eob = av1_get_tx_eob(&cpi->common.seg, segment_id, tx_size);
unsigned int(*const eob_branch)[COEFF_CONTEXTS] =
td->counts->eob_branch[txsize_sqr_map[tx_size]][type][ref];
const uint8_t *const band = get_band_translate(tx_size);
......
......@@ -138,13 +138,11 @@ static INLINE int av1_get_token_cost(int v, int16_t *token, int cat6_bits) {
return av1_dct_cat_lt_10_value_cost[v];
}
#if !CONFIG_PVQ || CONFIG_VAR_TX
static INLINE int get_tx_eob(const struct segmentation *seg, int segment_id,
TX_SIZE tx_size) {
static INLINE int av1_get_tx_eob(const struct segmentation *seg, int segment_id,
TX_SIZE tx_size) {
const int eob_max = tx_size_2d[tx_size];
return segfeature_active(seg, segment_id, SEG_LVL_SKIP) ? 0 : eob_max;
}
#endif
#ifdef __cplusplus
} // extern "C"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment