Commit 3edad6e8 authored by Jingning Han's avatar Jingning Han

Enable entropy coding of recursive transform block partition

This commit enables the entropy coding of the recursive transform
block partition syntax.

Change-Id: I0c2509fb7b9822d12a721f9ebf9327fac83c777e
parent bdaa2576
......@@ -97,6 +97,10 @@ void vp10_free_context_buffers(VP10_COMMON *cm) {
cm->above_context = NULL;
vpx_free(cm->above_seg_context);
cm->above_seg_context = NULL;
#if CONFIG_VAR_TX
vpx_free(cm->above_txfm_context);
cm->above_txfm_context = NULL;
#endif
}
int vp10_alloc_context_buffers(VP10_COMMON *cm, int width, int height) {
......@@ -128,6 +132,14 @@ int vp10_alloc_context_buffers(VP10_COMMON *cm, int width, int height) {
cm->above_seg_context = (PARTITION_CONTEXT *)vpx_calloc(
mi_cols_aligned_to_sb(cm->mi_cols), sizeof(*cm->above_seg_context));
if (!cm->above_seg_context) goto fail;
#if CONFIG_VAR_TX
vpx_free(cm->above_txfm_context);
cm->above_txfm_context = (TXFM_CONTEXT *)vpx_calloc(
mi_cols_aligned_to_sb(cm->mi_cols), sizeof(*cm->above_txfm_context));
if (!cm->above_txfm_context) goto fail;
#endif
cm->above_context_alloc_cols = cm->mi_cols;
}
......
......@@ -216,6 +216,12 @@ typedef struct macroblockd {
PARTITION_CONTEXT *above_seg_context;
PARTITION_CONTEXT left_seg_context[8];
#if CONFIG_VAR_TX
TXFM_CONTEXT *above_txfm_context;
TXFM_CONTEXT *left_txfm_context;
TXFM_CONTEXT left_txfm_context_buffer[8];
#endif
#if CONFIG_VP9_HIGHBITDEPTH
/* Bit depth: 8, 10, 12 */
int bd;
......
......@@ -742,6 +742,12 @@ void vp10_tx_counts_to_branch_counts_8x8(const unsigned int *tx_count_8x8p,
ct_8x8p[0][1] = tx_count_8x8p[TX_8X8];
}
#if CONFIG_VAR_TX
static const vpx_prob default_txfm_partition_probs[TXFM_PARTITION_CONTEXTS] = {
192, 128, 64, 192, 128, 64, 192, 128, 64,
};
#endif
static const vpx_prob default_skip_probs[SKIP_CONTEXTS] = {
192, 128, 64
};
......@@ -959,6 +965,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
vp10_copy(fc->comp_ref_prob, default_comp_ref_p);
vp10_copy(fc->single_ref_prob, default_single_ref_p);
fc->tx_probs = default_tx_probs;
#if CONFIG_VAR_TX
vp10_copy(fc->txfm_partition_prob, default_txfm_partition_probs);
#endif
vp10_copy(fc->skip_probs, default_skip_probs);
vp10_copy(fc->inter_mode_probs, default_inter_mode_probs);
#if CONFIG_EXT_TX
......@@ -1054,6 +1063,14 @@ void vp10_adapt_intra_frame_probs(VP10_COMMON *cm) {
}
}
#if CONFIG_VAR_TX
if (cm->tx_mode == TX_MODE_SELECT)
for (i = 0; i < TXFM_PARTITION_CONTEXTS; ++i)
fc->txfm_partition_prob[i] =
mode_mv_merge_probs(pre_fc->txfm_partition_prob[i],
counts->txfm_partition[i]);
#endif
for (i = 0; i < SKIP_CONTEXTS; ++i)
fc->skip_probs[i] = mode_mv_merge_probs(
pre_fc->skip_probs[i], counts->skip[i]);
......
......@@ -67,6 +67,9 @@ typedef struct frame_contexts {
vpx_prob single_ref_prob[REF_CONTEXTS][2];
vpx_prob comp_ref_prob[REF_CONTEXTS];
struct tx_probs tx_probs;
#if CONFIG_VAR_TX
vpx_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS];
#endif
vpx_prob skip_probs[SKIP_CONTEXTS];
nmv_context nmvc;
#if CONFIG_EXT_TX
......@@ -96,6 +99,9 @@ typedef struct FRAME_COUNTS {
unsigned int single_ref[REF_CONTEXTS][2][2];
unsigned int comp_ref[REF_CONTEXTS][2];
struct tx_counts tx;
#if CONFIG_VAR_TX
unsigned int txfm_partition[TXFM_PARTITION_CONTEXTS][2];
#endif
unsigned int skip[SKIP_CONTEXTS][2];
nmv_context_counts mv;
#if CONFIG_EXT_TX
......
......@@ -187,6 +187,11 @@ typedef uint8_t PREDICTION_MODE;
#define COMP_INTER_CONTEXTS 5
#define REF_CONTEXTS 5
#if CONFIG_VAR_TX
#define TXFM_PARTITION_CONTEXTS 9
typedef TX_SIZE TXFM_CONTEXT;
#endif
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -301,6 +301,9 @@ typedef struct VP10Common {
PARTITION_CONTEXT *above_seg_context;
ENTROPY_CONTEXT *above_context;
#if CONFIG_VAR_TX
TXFM_CONTEXT *above_txfm_context;
#endif
int above_context_alloc_cols;
// scratch memory for intraonly/keyframe forward updates from default tables
......@@ -397,6 +400,9 @@ static INLINE void vp10_init_macroblockd(VP10_COMMON *cm, MACROBLOCKD *xd,
}
xd->above_seg_context = cm->above_seg_context;
#if CONFIG_VAR_TX
xd->above_txfm_context = cm->above_txfm_context;
#endif
xd->mi_stride = cm->mi_stride;
xd->error_info = &cm->error;
}
......@@ -489,6 +495,28 @@ static INLINE int partition_plane_context(const MACROBLOCKD *xd,
return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
}
#if CONFIG_VAR_TX
static INLINE void txfm_partition_update(TXFM_CONTEXT *above_ctx,
TXFM_CONTEXT *left_ctx,
TX_SIZE tx_size) {
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
int bs = num_8x8_blocks_high_lookup[bsize];
int i;
for (i = 0; i < bs; ++i) {
above_ctx[i] = tx_size;
left_ctx[i] = tx_size;
}
}
static INLINE int txfm_partition_context(TXFM_CONTEXT *above_ctx,
TXFM_CONTEXT *left_ctx,
TX_SIZE tx_size) {
int above = *above_ctx < tx_size;
int left = *left_ctx < tx_size;
return (tx_size - 1) * 3 + above + left;
}
#endif
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -401,6 +401,12 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts,
for (i = 0; i < TX_SIZES; i++)
cm->counts.tx.tx_totals[i] += counts->tx.tx_totals[i];
#if CONFIG_VAR_TX
for (i = 0; i < TXFM_PARTITION_CONTEXTS; ++i)
for (j = 0; j < 2; ++j)
cm->counts.txfm_partition[i][j] += counts->txfm_partition[i][j];
#endif
for (i = 0; i < SKIP_CONTEXTS; i++)
for (j = 0; j < 2; j++)
cm->counts.skip[i][j] += counts->skip[i][j];
......
......@@ -1619,6 +1619,11 @@ static const uint8_t *decode_tiles(VP10Decoder *pbi,
memset(cm->above_seg_context, 0,
sizeof(*cm->above_seg_context) * aligned_cols);
#if CONFIG_VAR_TX
memset(cm->above_txfm_context, 0,
sizeof(*cm->above_txfm_context) * aligned_cols);
#endif
get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers);
if (pbi->tile_data == NULL ||
......@@ -1665,6 +1670,9 @@ static const uint8_t *decode_tiles(VP10Decoder *pbi,
vp10_tile_set_col(&tile, tile_data->cm, col);
vp10_zero(tile_data->xd.left_context);
vp10_zero(tile_data->xd.left_seg_context);
#if CONFIG_VAR_TX
vp10_zero(tile_data->xd.left_txfm_context_buffer);
#endif
for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end;
mi_col += MI_BLOCK_SIZE) {
decode_partition(pbi, &tile_data->xd, mi_row,
......@@ -1738,6 +1746,9 @@ static int tile_worker_hook(TileWorkerData *const tile_data,
mi_row += MI_BLOCK_SIZE) {
vp10_zero(tile_data->xd.left_context);
vp10_zero(tile_data->xd.left_seg_context);
#if CONFIG_VAR_TX
vp10_zero(tile_data->xd.left_txfm_context_buffer);
#endif
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
mi_col += MI_BLOCK_SIZE) {
decode_partition(tile_data->pbi, &tile_data->xd,
......@@ -1815,7 +1826,10 @@ static const uint8_t *decode_tiles_mt(VP10Decoder *pbi,
sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_mi_cols);
memset(cm->above_seg_context, 0,
sizeof(*cm->above_seg_context) * aligned_mi_cols);
#if CONFIG_VAR_TX
memset(cm->above_txfm_context, 0,
sizeof(*cm->above_txfm_context) * aligned_mi_cols);
#endif
// Load tile data into tile_buffers
get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers);
......@@ -2270,6 +2284,11 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data,
read_tx_mode_probs(&fc->tx_probs, &r);
read_coef_probs(fc, cm->tx_mode, &r);
#if CONFIG_VAR_TX
for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
vp10_diff_update_prob(&r, &fc->txfm_partition_prob[k]);
#endif
for (k = 0; k < SKIP_CONTEXTS; ++k)
vp10_diff_update_prob(&r, &fc->skip_probs[k]);
......
......@@ -80,13 +80,17 @@ static int read_segment_id(vpx_reader *r,
#if CONFIG_VAR_TX
static void read_tx_size_inter(VP10_COMMON *cm, MACROBLOCKD *xd,
MB_MODE_INFO *mbmi,
MB_MODE_INFO *mbmi, FRAME_COUNTS *counts,
TX_SIZE tx_size, int blk_row, int blk_col,
vpx_reader *r) {
int is_split = 0;
const int tx_idx = (blk_row >> 1) * 8 + (blk_col >> 1);
int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
int ctx = txfm_partition_context(xd->above_txfm_context + (blk_col >> 1),
xd->left_txfm_context + (blk_row >> 1),
tx_size);
if (xd->mb_to_bottom_edge < 0)
max_blocks_high += xd->mb_to_bottom_edge >> 5;
if (xd->mb_to_right_edge < 0)
......@@ -95,15 +99,21 @@ static void read_tx_size_inter(VP10_COMMON *cm, MACROBLOCKD *xd,
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
return;
is_split = vpx_read_bit(r);
is_split = vpx_read(r, cm->fc->txfm_partition_prob[ctx]);
if (is_split) {
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
int bsl = b_width_log2_lookup[bsize];
int i;
if (counts)
++counts->txfm_partition[ctx][1];
if (tx_size == TX_8X8) {
mbmi->inter_tx_size[tx_idx] = TX_4X4;
mbmi->tx_size = mbmi->inter_tx_size[tx_idx];
txfm_partition_update(xd->above_txfm_context + (blk_col >> 1),
xd->left_txfm_context + (blk_row >> 1), TX_4X4);
return;
}
......@@ -112,7 +122,8 @@ static void read_tx_size_inter(VP10_COMMON *cm, MACROBLOCKD *xd,
for (i = 0; i < 4; ++i) {
int offsetr = blk_row + ((i >> 1) << bsl);
int offsetc = blk_col + ((i & 0x01) << bsl);
read_tx_size_inter(cm, xd, mbmi, tx_size - 1, offsetr, offsetc, r);
read_tx_size_inter(cm, xd, mbmi, counts,
tx_size - 1, offsetr, offsetc, r);
}
} else {
int idx, idy;
......@@ -121,6 +132,10 @@ static void read_tx_size_inter(VP10_COMMON *cm, MACROBLOCKD *xd,
for (idx = 0; idx < (1 << tx_size) / 2; ++idx)
mbmi->inter_tx_size[tx_idx + (idy << 3) + idx] = tx_size;
mbmi->tx_size = mbmi->inter_tx_size[tx_idx];
if (counts)
++counts->txfm_partition[ctx][0];
txfm_partition_update(xd->above_txfm_context + (blk_col >> 1),
xd->left_txfm_context + (blk_row >> 1), tx_size);
}
}
#endif
......@@ -764,9 +779,11 @@ static void read_inter_frame_mode_info(VP10Decoder *const pbi,
const int width = num_4x4_blocks_wide_lookup[bsize];
const int height = num_4x4_blocks_high_lookup[bsize];
int idx, idy;
xd->above_txfm_context = cm->above_txfm_context + mi_col;
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
for (idy = 0; idy < height; idy += bs)
for (idx = 0; idx < width; idx += bs)
read_tx_size_inter(cm, xd, mbmi, max_tx_size,
read_tx_size_inter(cm, xd, mbmi, xd->counts, max_tx_size,
idy, idx, r);
if (xd->counts) {
const int ctx = get_tx_size_context(xd);
......
......@@ -160,6 +160,10 @@ static void write_tx_size_inter(const VP10_COMMON *cm,
const int tx_idx = (blk_row >> 1) * 8 + (blk_col >> 1);
int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
int ctx = txfm_partition_context(xd->above_txfm_context + (blk_col >> 1),
xd->left_txfm_context + (blk_row >> 1),
tx_size);
if (xd->mb_to_bottom_edge < 0)
max_blocks_high += xd->mb_to_bottom_edge >> 5;
if (xd->mb_to_right_edge < 0)
......@@ -169,15 +173,20 @@ static void write_tx_size_inter(const VP10_COMMON *cm,
return;
if (tx_size == mbmi->inter_tx_size[tx_idx]) {
vpx_write_bit(w, 0);
vpx_write(w, 0, cm->fc->txfm_partition_prob[ctx]);
txfm_partition_update(xd->above_txfm_context + (blk_col >> 1),
xd->left_txfm_context + (blk_row >> 1), tx_size);
} else {
const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
int bsl = b_width_log2_lookup[bsize];
int i;
vpx_write_bit(w, 1);
vpx_write(w, 1, cm->fc->txfm_partition_prob[ctx]);
if (tx_size == TX_8X8)
if (tx_size == TX_8X8) {
txfm_partition_update(xd->above_txfm_context + (blk_col >> 1),
xd->left_txfm_context + (blk_row >> 1), TX_4X4);
return;
}
assert(bsl > 0);
--bsl;
......@@ -188,6 +197,14 @@ static void write_tx_size_inter(const VP10_COMMON *cm,
}
}
}
static void update_txfm_partition_probs(VP10_COMMON *cm, vpx_writer *w,
FRAME_COUNTS *counts) {
int k;
for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
vp10_cond_prob_diff_update(w, &cm->fc->txfm_partition_prob[k],
counts->txfm_partition[k]);
}
#endif
static void write_selected_tx_size(const VP10_COMMON *cm,
......@@ -498,8 +515,8 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
vpx_writer *w) {
VP10_COMMON *const cm = &cpi->common;
const nmv_context *nmvc = &cm->fc->nmvc;
const MACROBLOCK *const x = &cpi->td.mb;
const MACROBLOCKD *const xd = &x->e_mbd;
const MACROBLOCK *x = &cpi->td.mb;
const MACROBLOCKD *xd = &x->e_mbd;
const struct segmentation *const seg = &cm->seg;
#if CONFIG_MISC_FIXES
const struct segmentation_probs *const segp = &cm->fc->seg;
......@@ -750,6 +767,10 @@ static void write_modes_b(VP10_COMP *cpi, const TileInfo *const tile,
if (frame_is_intra_only(cm)) {
write_mb_modes_kf(cm, xd, xd->mi, w);
} else {
#if CONFIG_VAR_TX
xd->above_txfm_context = cm->above_txfm_context + mi_col;
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
#endif
pack_inter_mode_mvs(cpi, m, w);
}
......@@ -897,6 +918,9 @@ static void write_modes(VP10_COMP *cpi,
for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
mi_row += MI_BLOCK_SIZE) {
vp10_zero(xd->left_seg_context);
#if CONFIG_VAR_TX
vp10_zero(xd->left_txfm_context_buffer);
#endif
for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end;
mi_col += MI_BLOCK_SIZE)
write_modes_sb(cpi, tile, w, tok, tok_end, mi_row, mi_col,
......@@ -1385,6 +1409,10 @@ static size_t encode_tiles(VP10_COMP *cpi, uint8_t *data_ptr,
memset(cm->above_seg_context, 0,
sizeof(*cm->above_seg_context) * mi_cols_aligned_to_sb(cm->mi_cols));
#if CONFIG_VAR_TX
memset(cm->above_txfm_context, 0,
sizeof(*cm->above_txfm_context) * mi_cols_aligned_to_sb(cm->mi_cols));
#endif
for (tile_row = 0; tile_row < tile_rows; tile_row++) {
for (tile_col = 0; tile_col < tile_cols; tile_col++) {
......@@ -1659,6 +1687,11 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) {
update_txfm_probs(cm, &header_bc, counts);
#endif
update_coef_probs(cpi, &header_bc);
#if CONFIG_VAR_TX
update_txfm_partition_probs(cm, &header_bc, counts);
#endif
update_skip_probs(cm, &header_bc, counts);
#if CONFIG_MISC_FIXES
update_seg_probs(cpi, &header_bc);
......
This diff is collapsed.
......@@ -1708,6 +1708,7 @@ static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
int blk_row, int blk_col, int plane, int block,
TX_SIZE tx_size, BLOCK_SIZE plane_bsize,
ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl,
TXFM_CONTEXT *tx_above, TXFM_CONTEXT *tx_left,
int *rate, int64_t *dist,
int64_t *bsse, int *skip,
int64_t ref_best_rd, int *is_cost_valid) {
......@@ -1724,9 +1725,12 @@ static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
ENTROPY_CONTEXT *ptl = tl + blk_row;
ENTROPY_CONTEXT stxa = 0, stxl = 0;
int coeff_ctx, i;
int ctx = txfm_partition_context(tx_above + (blk_col >> 1),
tx_left + (blk_row >> 1), tx_size);
int64_t sum_dist = 0, sum_bsse = 0;
int64_t sum_rd = INT64_MAX;
int sum_rate = vp10_cost_bit(128, 1);
int sum_rate = vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 1);
int all_skip = 1;
int tmp_eob = 0;
......@@ -1776,7 +1780,7 @@ static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
tx_block_rd_b(cpi, x, tx_size, blk_row, blk_col, plane, block,
plane_bsize, coeff_ctx, rate, dist, bsse, skip);
if (tx_size > TX_4X4)
*rate += vp10_cost_bit(128, 0);
*rate += vp10_cost_bit(cpi->common.fc->txfm_partition_prob[ctx], 0);
this_rd = RDCOST(x->rdmult, x->rddiv, *rate, *dist);
tmp_eob = p->eobs[block];
}
......@@ -1799,7 +1803,8 @@ static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
int offsetc = (i & 0x01) << bsl;
select_tx_block(cpi, x, blk_row + offsetr, blk_col + offsetc,
plane, block + i * sub_step, tx_size - 1,
plane_bsize, ta, tl, &this_rate, &this_dist,
plane_bsize, ta, tl, tx_above, tx_left,
&this_rate, &this_dist,
&this_bsse, &this_skip,
ref_best_rd - tmp_rd, &this_cost_valid);
sum_rate += this_rate;
......@@ -1818,6 +1823,8 @@ static void select_tx_block(const VP10_COMP *cpi, MACROBLOCK *x,
int idx, idy;
for (i = 0; i < (1 << tx_size); ++i)
pta[i] = ptl[i] = !(tmp_eob == 0);
txfm_partition_update(tx_above + (blk_col >> 1),
tx_left + (blk_row >> 1), tx_size);
mbmi->inter_tx_size[tx_idx] = tx_size;
for (idy = 0; idy < (1 << tx_size) / 2; ++idy)
......@@ -1867,17 +1874,23 @@ static void inter_block_yrd(const VP10_COMP *cpi, MACROBLOCK *x,
int block = 0;
int step = 1 << (max_txsize_lookup[plane_bsize] * 2);
ENTROPY_CONTEXT ctxa[16], ctxl[16];
TXFM_CONTEXT tx_above[8], tx_left[8];
int pnrate = 0, pnskip = 1;
int64_t pndist = 0, pnsse = 0;
vp10_get_entropy_contexts(bsize, TX_4X4, pd, ctxa, ctxl);
memcpy(tx_above, xd->above_txfm_context,
sizeof(TXFM_CONTEXT) * (mi_width >> 1));
memcpy(tx_left, xd->left_txfm_context,
sizeof(TXFM_CONTEXT) * (mi_height >> 1));
for (idy = 0; idy < mi_height; idy += bh) {
for (idx = 0; idx < mi_width; idx += bh) {
select_tx_block(cpi, x, idy, idx, 0, block,
max_txsize_lookup[plane_bsize], plane_bsize,
ctxa, ctxl, &pnrate, &pndist, &pnsse, &pnskip,
ctxa, ctxl, tx_above, tx_left,
&pnrate, &pndist, &pnsse, &pnskip,
ref_best_rd - this_rd, &is_cost_valid);
*rate += pnrate;
*distortion += pndist;
......
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