Enable transform block partition entropy coding
Select the probability model for transform block partition coding conditioned on the neighbor transform block sizes. Change-Id: Ib701296e59009bad97dbd21d8dcd58bc5e552f39
This commit is contained in:
parent
79d6b8fc85
commit
948c6d882e
@ -114,6 +114,8 @@ void vp9_free_context_buffers(VP9_COMMON *cm) {
|
||||
cm->above_context = NULL;
|
||||
vpx_free(cm->above_seg_context);
|
||||
cm->above_seg_context = NULL;
|
||||
vpx_free(cm->above_txfm_context);
|
||||
cm->above_txfm_context = NULL;
|
||||
}
|
||||
|
||||
int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) {
|
||||
@ -137,6 +139,10 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) {
|
||||
mi_cols_aligned_to_sb(cm->mi_cols), sizeof(*cm->above_seg_context));
|
||||
if (!cm->above_seg_context) goto fail;
|
||||
|
||||
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;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
@ -29,6 +29,7 @@ extern "C" {
|
||||
#define BLOCK_SIZE_GROUPS 4
|
||||
#define SKIP_CONTEXTS 3
|
||||
#define INTER_MODE_CONTEXTS 7
|
||||
#define TXFM_PARTITION_CONTEXTS 9
|
||||
|
||||
/* Segment Feature Masks */
|
||||
#define MAX_MV_REF_CANDIDATES 2
|
||||
@ -46,6 +47,7 @@ typedef enum {
|
||||
#define MAX_MB_PLANE 3
|
||||
|
||||
typedef char ENTROPY_CONTEXT;
|
||||
typedef TX_SIZE TXFM_CONTEXT;
|
||||
|
||||
static INLINE int combine_entropy_contexts(ENTROPY_CONTEXT a,
|
||||
ENTROPY_CONTEXT b) {
|
||||
@ -219,6 +221,10 @@ typedef struct macroblockd {
|
||||
PARTITION_CONTEXT *above_seg_context;
|
||||
PARTITION_CONTEXT left_seg_context[8];
|
||||
|
||||
TXFM_CONTEXT *above_txfm_context;
|
||||
TXFM_CONTEXT *left_txfm_context;
|
||||
TXFM_CONTEXT left_txfm_context_buffer[8];
|
||||
|
||||
/* mc buffer */
|
||||
DECLARE_ALIGNED(16, uint8_t, mc_buf[80 * 2 * 80 * 2]);
|
||||
|
||||
|
@ -302,6 +302,11 @@ void tx_counts_to_branch_counts_8x8(const unsigned int *tx_count_8x8p,
|
||||
ct_8x8p[0][1] = tx_count_8x8p[TX_8X8];
|
||||
}
|
||||
|
||||
static const vp9_prob default_txfm_partition_probs[TXFM_PARTITION_CONTEXTS] = {
|
||||
// 64, 128, 192, 64, 128, 192, 64, 128, 192,
|
||||
192, 128, 64, 192, 128, 64, 192, 128, 64,
|
||||
};
|
||||
|
||||
static const vp9_prob default_skip_probs[SKIP_CONTEXTS] = {
|
||||
192, 128, 64
|
||||
};
|
||||
@ -324,6 +329,7 @@ void vp9_init_mode_probs(FRAME_CONTEXT *fc) {
|
||||
vp9_copy(fc->comp_ref_prob, default_comp_ref_p);
|
||||
vp9_copy(fc->single_ref_prob, default_single_ref_p);
|
||||
fc->tx_probs = default_tx_probs;
|
||||
vp9_copy(fc->txfm_partition_prob, default_txfm_partition_probs);
|
||||
vp9_copy(fc->skip_probs, default_skip_probs);
|
||||
vp9_copy(fc->inter_mode_probs, default_inter_mode_probs);
|
||||
}
|
||||
@ -402,6 +408,11 @@ void vp9_adapt_mode_probs(VP9_COMMON *cm) {
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
|
||||
for (i = 0; i < SKIP_CONTEXTS; ++i)
|
||||
fc->skip_probs[i] = mode_mv_merge_probs(
|
||||
pre_fc->skip_probs[i], counts->skip[i]);
|
||||
|
@ -49,6 +49,7 @@ typedef struct frame_contexts {
|
||||
vp9_prob single_ref_prob[REF_CONTEXTS][2];
|
||||
vp9_prob comp_ref_prob[REF_CONTEXTS];
|
||||
struct tx_probs tx_probs;
|
||||
vp9_prob txfm_partition_prob[TXFM_PARTITION_CONTEXTS];
|
||||
vp9_prob skip_probs[SKIP_CONTEXTS];
|
||||
nmv_context nmvc;
|
||||
int initialized;
|
||||
@ -70,6 +71,7 @@ typedef struct FRAME_COUNTS {
|
||||
unsigned int comp_ref[REF_CONTEXTS][2];
|
||||
struct tx_counts tx;
|
||||
unsigned int skip[SKIP_CONTEXTS][2];
|
||||
unsigned int txfm_partition[TXFM_PARTITION_CONTEXTS][2];
|
||||
nmv_context_counts mv;
|
||||
} FRAME_COUNTS;
|
||||
|
||||
|
@ -266,8 +266,9 @@ typedef struct VP9Common {
|
||||
// External BufferPool passed from outside.
|
||||
BufferPool *buffer_pool;
|
||||
|
||||
PARTITION_CONTEXT *above_seg_context;
|
||||
ENTROPY_CONTEXT *above_context;
|
||||
PARTITION_CONTEXT *above_seg_context;
|
||||
TXFM_CONTEXT *above_txfm_context;
|
||||
} VP9_COMMON;
|
||||
|
||||
// TODO(hkuang): Don't need to lock the whole pool after implementing atomic
|
||||
@ -328,6 +329,7 @@ static INLINE void init_macroblockd(VP9_COMMON *cm, MACROBLOCKD *xd) {
|
||||
}
|
||||
|
||||
xd->above_seg_context = cm->above_seg_context;
|
||||
xd->above_txfm_context = cm->above_txfm_context;
|
||||
xd->mi_stride = cm->mi_stride;
|
||||
xd->error_info = &cm->error;
|
||||
}
|
||||
@ -427,6 +429,29 @@ static INLINE int partition_plane_context(const MACROBLOCKD *xd,
|
||||
return (left * 2 + above) + bsl * PARTITION_PLOFFSET;
|
||||
}
|
||||
|
||||
static void txfm_partition_update(MACROBLOCKD *xd, int blk_row, int blk_col,
|
||||
TX_SIZE tx_size) {
|
||||
TXFM_CONTEXT *above_ctx = xd->above_txfm_context + (blk_col / 2);
|
||||
TXFM_CONTEXT *left_ctx = xd->left_txfm_context + (blk_row / 2);
|
||||
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 int txfm_partition_context(const MACROBLOCKD *xd,
|
||||
int blk_row, int blk_col,
|
||||
TX_SIZE tx_size) {
|
||||
const TXFM_CONTEXT *above_ctx = xd->above_txfm_context + (blk_col / 2);
|
||||
const TXFM_CONTEXT *left_ctx = xd->left_txfm_context + (blk_row / 2);
|
||||
int above = *above_ctx < tx_size;
|
||||
int left = *left_ctx < tx_size;
|
||||
return (tx_size - 1) * 3 + above + left;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -400,6 +400,10 @@ void vp9_accumulate_frame_counts(VP9_COMMON *cm, FRAME_COUNTS *counts,
|
||||
for (i = 0; i < TX_SIZES; i++)
|
||||
cm->counts.tx.tx_totals[i] += counts->tx.tx_totals[i];
|
||||
|
||||
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];
|
||||
|
||||
for (i = 0; i < SKIP_CONTEXTS; i++)
|
||||
for (j = 0; j < 2; j++)
|
||||
cm->counts.skip[i][j] += counts->skip[i][j];
|
||||
|
@ -504,7 +504,6 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd,
|
||||
mbmi->skip = 1; // skip loopfilter
|
||||
}
|
||||
}
|
||||
|
||||
xd->corrupted |= vp9_reader_has_error(r);
|
||||
}
|
||||
|
||||
@ -1017,9 +1016,10 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,
|
||||
// are allocated as part of the same buffer.
|
||||
vpx_memset(cm->above_context, 0,
|
||||
sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_cols);
|
||||
|
||||
vpx_memset(cm->above_seg_context, 0,
|
||||
sizeof(*cm->above_seg_context) * aligned_cols);
|
||||
vpx_memset(cm->above_txfm_context, 0,
|
||||
sizeof(*cm->above_txfm_context) * aligned_cols);
|
||||
|
||||
get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers);
|
||||
|
||||
@ -1062,6 +1062,7 @@ static const uint8_t *decode_tiles(VP9Decoder *pbi,
|
||||
vp9_tile_set_col(&tile, tile_data->cm, col);
|
||||
vp9_zero(tile_data->xd.left_context);
|
||||
vp9_zero(tile_data->xd.left_seg_context);
|
||||
vp9_zero(tile_data->xd.left_txfm_context_buffer);
|
||||
for (mi_col = tile.mi_col_start; mi_col < tile.mi_col_end;
|
||||
mi_col += MI_BLOCK_SIZE) {
|
||||
decode_partition(pbi, &tile_data->xd, &cm->counts, &tile, mi_row,
|
||||
@ -1135,6 +1136,7 @@ static int tile_worker_hook(TileWorkerData *const tile_data,
|
||||
mi_row += MI_BLOCK_SIZE) {
|
||||
vp9_zero(tile_data->xd.left_context);
|
||||
vp9_zero(tile_data->xd.left_seg_context);
|
||||
vp9_zero(tile_data->xd.left_txfm_context_buffer);
|
||||
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, &tile_data->counts,
|
||||
@ -1220,6 +1222,8 @@ static const uint8_t *decode_tiles_mt(VP9Decoder *pbi,
|
||||
sizeof(*cm->above_context) * MAX_MB_PLANE * 2 * aligned_mi_cols);
|
||||
vpx_memset(cm->above_seg_context, 0,
|
||||
sizeof(*cm->above_seg_context) * aligned_mi_cols);
|
||||
vpx_memset(cm->above_txfm_context, 0,
|
||||
sizeof(*cm->above_txfm_context) * aligned_mi_cols);
|
||||
|
||||
// Load tile data into tile_buffers
|
||||
get_tile_buffers(pbi, data, data_end, tile_cols, tile_rows, tile_buffers);
|
||||
@ -1590,6 +1594,9 @@ static int read_compressed_header(VP9Decoder *pbi, const uint8_t *data,
|
||||
read_tx_mode_probs(&fc->tx_probs, &r);
|
||||
read_coef_probs(fc, cm->tx_mode, &r);
|
||||
|
||||
for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
|
||||
vp9_diff_update_prob(&r, &fc->txfm_partition_prob[k]);
|
||||
|
||||
for (k = 0; k < SKIP_CONTEXTS; ++k)
|
||||
vp9_diff_update_prob(&r, &fc->skip_probs[k]);
|
||||
|
||||
|
@ -61,8 +61,8 @@ static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
|
||||
}
|
||||
|
||||
static void read_tx_size_inter(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||
TX_SIZE tx_size, int blk_row, int blk_col,
|
||||
vp9_reader *r) {
|
||||
FRAME_COUNTS *counts, TX_SIZE tx_size,
|
||||
int blk_row, int blk_col, vp9_reader *r) {
|
||||
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
int is_split = 0;
|
||||
int tx_idx = (blk_row / 2) * 8 + (blk_col / 2);
|
||||
@ -71,7 +71,7 @@ static void read_tx_size_inter(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int i, j;
|
||||
|
||||
int ctx = txfm_partition_context(xd, blk_row, blk_col, 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)
|
||||
@ -80,7 +80,7 @@ static void read_tx_size_inter(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
is_split = vp9_read_bit(r);
|
||||
is_split = vp9_read(r, cm->fc->txfm_partition_prob[ctx]);
|
||||
|
||||
if (!is_split) {
|
||||
mbmi->inter_tx_size[tx_idx] = tx_size;
|
||||
@ -88,17 +88,24 @@ static void read_tx_size_inter(VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||
for (i = 0; i < bh / 2; ++i)
|
||||
mbmi->inter_tx_size[tx_idx + j * 8 + i] = tx_size;
|
||||
mbmi->tx_size = tx_size;
|
||||
++counts->txfm_partition[ctx][0];
|
||||
txfm_partition_update(xd, blk_row, blk_col, tx_size);
|
||||
} else {
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int i;
|
||||
++counts->txfm_partition[ctx][1];
|
||||
if (tx_size == TX_8X8) {
|
||||
mbmi->inter_tx_size[tx_idx] = TX_4X4;
|
||||
mbmi->tx_size = TX_4X4;
|
||||
txfm_partition_update(xd, blk_row, blk_col, TX_4X4);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
read_tx_size_inter(cm, xd, tx_size - 1,
|
||||
read_tx_size_inter(cm, xd, counts, tx_size - 1,
|
||||
blk_row + offsetr, blk_col + offsetc, r);
|
||||
}
|
||||
}
|
||||
@ -628,9 +635,11 @@ static void read_inter_frame_mode_info(VP9Decoder *const pbi,
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
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 += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
read_tx_size_inter(cm, xd, max_txsize_lookup[mbmi->sb_type],
|
||||
read_tx_size_inter(cm, xd, counts, max_txsize_lookup[mbmi->sb_type],
|
||||
idy, idx, r);
|
||||
} else {
|
||||
int i;
|
||||
|
@ -76,13 +76,14 @@ static void prob_diff_update(const vp9_tree_index *tree,
|
||||
vp9_cond_prob_diff_update(w, &probs[i], branch_ct[i]);
|
||||
}
|
||||
|
||||
static void write_tx_size_inter(const VP9_COMMON *cm, const MACROBLOCKD *xd,
|
||||
static void write_tx_size_inter(const VP9_COMMON *cm, MACROBLOCKD *xd,
|
||||
TX_SIZE tx_size, int blk_row, int blk_col,
|
||||
vp9_writer *w) {
|
||||
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
int tx_idx = (blk_row / 2) * 8 + (blk_col / 2);
|
||||
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, blk_row, blk_col, 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)
|
||||
@ -93,16 +94,21 @@ static void write_tx_size_inter(const VP9_COMMON *cm, const MACROBLOCKD *xd,
|
||||
|
||||
// TODO(jingning): this assumes support of the possible 64x64 transform.
|
||||
if (tx_size == mbmi->inter_tx_size[tx_idx]) {
|
||||
vp9_write_bit(w, 0);
|
||||
vp9_write(w, 0, cm->fc->txfm_partition_prob[ctx]);
|
||||
txfm_partition_update(xd, blk_row, blk_col, tx_size);
|
||||
// vp9_write_bit(w, 0);
|
||||
} else { // further split
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int i;
|
||||
|
||||
vp9_write_bit(w, 1);
|
||||
vp9_write(w, 1, cm->fc->txfm_partition_prob[ctx]);
|
||||
// vp9_write_bit(w, 1);
|
||||
|
||||
if (tx_size == TX_8X8)
|
||||
if (tx_size == TX_8X8) {
|
||||
txfm_partition_update(xd, blk_row, blk_col, TX_4X4);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
@ -128,6 +134,14 @@ static void write_selected_tx_size(const VP9_COMMON *cm,
|
||||
}
|
||||
}
|
||||
|
||||
static void update_txfm_partition_probs(VP9_COMMON *cm, vp9_writer *w,
|
||||
FRAME_COUNTS *counts) {
|
||||
int k;
|
||||
for (k = 0; k < TXFM_PARTITION_CONTEXTS; ++k)
|
||||
vp9_cond_prob_diff_update(w, &cm->fc->txfm_partition_prob[k],
|
||||
counts->txfm_partition[k]);
|
||||
}
|
||||
|
||||
static int write_skip(const VP9_COMMON *cm, const MACROBLOCKD *xd,
|
||||
int segment_id, const MODE_INFO *mi, vp9_writer *w) {
|
||||
if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
|
||||
@ -275,8 +289,8 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
|
||||
vp9_writer *w) {
|
||||
VP9_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;
|
||||
MACROBLOCK *x = &cpi->td.mb;
|
||||
MACROBLOCKD *xd = &x->e_mbd;
|
||||
const struct segmentation *const seg = &cm->seg;
|
||||
const MB_MODE_INFO *const mbmi = &mi->mbmi;
|
||||
const PREDICTION_MODE mode = mbmi->mode;
|
||||
@ -439,6 +453,8 @@ static void write_modes_b(VP9_COMP *cpi, const TileInfo *const tile,
|
||||
if (frame_is_intra_only(cm)) {
|
||||
write_mb_modes_kf(cm, xd, xd->mi, w);
|
||||
} else {
|
||||
xd->above_txfm_context = cm->above_txfm_context + mi_col;
|
||||
xd->left_txfm_context = xd->left_txfm_context_buffer + (mi_row & 0x07);
|
||||
pack_inter_mode_mvs(cpi, m, w);
|
||||
}
|
||||
|
||||
@ -535,6 +551,7 @@ static void write_modes(VP9_COMP *cpi,
|
||||
for (mi_row = tile->mi_row_start; mi_row < tile->mi_row_end;
|
||||
mi_row += MI_BLOCK_SIZE) {
|
||||
vp9_zero(xd->left_seg_context);
|
||||
vp9_zero(xd->left_txfm_context_buffer);
|
||||
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,
|
||||
@ -978,6 +995,8 @@ static size_t encode_tiles(VP9_COMP *cpi, uint8_t *data_ptr) {
|
||||
|
||||
vpx_memset(cm->above_seg_context, 0, sizeof(*cm->above_seg_context) *
|
||||
mi_cols_aligned_to_sb(cm->mi_cols));
|
||||
vpx_memset(cm->above_txfm_context, 0, sizeof(*cm->above_txfm_context) *
|
||||
mi_cols_aligned_to_sb(cm->mi_cols));
|
||||
|
||||
for (tile_row = 0; tile_row < tile_rows; tile_row++) {
|
||||
for (tile_col = 0; tile_col < tile_cols; tile_col++) {
|
||||
@ -1206,6 +1225,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
|
||||
encode_txfm_probs(cm, &header_bc, counts);
|
||||
|
||||
update_coef_probs(cpi, &header_bc);
|
||||
update_txfm_partition_probs(cm, &header_bc, counts);
|
||||
update_skip_probs(cm, &header_bc, counts);
|
||||
|
||||
if (!frame_is_intra_only(cm)) {
|
||||
|
@ -2693,6 +2693,8 @@ static void encode_rd_sb_row(VP9_COMP *cpi,
|
||||
// Initialize the left context for the new SB row
|
||||
vpx_memset(&xd->left_context, 0, sizeof(xd->left_context));
|
||||
vpx_memset(xd->left_seg_context, 0, sizeof(xd->left_seg_context));
|
||||
vpx_memset(xd->left_txfm_context_buffer, 0,
|
||||
sizeof(xd->left_txfm_context_buffer));
|
||||
|
||||
// Code each SB in the row
|
||||
for (mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
|
||||
@ -2781,6 +2783,8 @@ static void init_encode_frame_mb_context(VP9_COMP *cpi) {
|
||||
2 * aligned_mi_cols * MAX_MB_PLANE);
|
||||
vpx_memset(xd->above_seg_context, 0,
|
||||
sizeof(*xd->above_seg_context) * aligned_mi_cols);
|
||||
vpx_memset(cm->above_txfm_context, 0,
|
||||
sizeof(*xd->above_txfm_context) * aligned_mi_cols);
|
||||
}
|
||||
|
||||
static int check_dual_ref_flags(VP9_COMP *cpi) {
|
||||
@ -4024,6 +4028,49 @@ static void sum_intra_stats(FRAME_COUNTS *counts, const MODE_INFO *mi) {
|
||||
++counts->uv_mode[y_mode][uv_mode];
|
||||
}
|
||||
|
||||
static void update_txfm_count(MACROBLOCKD *xd, FRAME_COUNTS *counts,
|
||||
TX_SIZE tx_size, int blk_row, int blk_col) {
|
||||
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
|
||||
int tx_idx = (blk_row / 2) * 8 + (blk_col / 2);
|
||||
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, blk_row, blk_col, tx_size);
|
||||
TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_idx];
|
||||
|
||||
if (xd->mb_to_bottom_edge < 0)
|
||||
max_blocks_high += xd->mb_to_bottom_edge >> 5;
|
||||
if (xd->mb_to_right_edge < 0)
|
||||
max_blocks_wide += xd->mb_to_right_edge >> 5;
|
||||
|
||||
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide)
|
||||
return;
|
||||
|
||||
if (tx_size == plane_tx_size) {
|
||||
++counts->txfm_partition[ctx][0];
|
||||
mbmi->tx_size = tx_size;
|
||||
txfm_partition_update(xd, blk_row, blk_col, tx_size);
|
||||
} else {
|
||||
BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
|
||||
int bh = num_4x4_blocks_high_lookup[bsize];
|
||||
int i;
|
||||
++counts->txfm_partition[ctx][1];
|
||||
|
||||
if (tx_size == TX_8X8) {
|
||||
mbmi->inter_tx_size[tx_idx] = TX_4X4;
|
||||
mbmi->tx_size = TX_4X4;
|
||||
txfm_partition_update(xd, blk_row, blk_col, TX_4X4);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
update_txfm_count(xd, counts, tx_size - 1,
|
||||
blk_row + offsetr, blk_col + offsetc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void encode_superblock(VP9_COMP *cpi, ThreadData *td,
|
||||
TOKENEXTRA **t, int output_enabled,
|
||||
int mi_row, int mi_col, BLOCK_SIZE bsize,
|
||||
@ -4091,9 +4138,22 @@ static void encode_superblock(VP9_COMP *cpi, ThreadData *td,
|
||||
if (cm->tx_mode == TX_MODE_SELECT &&
|
||||
mbmi->sb_type >= BLOCK_8X8 &&
|
||||
!(is_inter_block(mbmi) && (mbmi->skip || seg_skip))) {
|
||||
if (!is_inter_block(mbmi))
|
||||
if (!is_inter_block(mbmi)) {
|
||||
++get_tx_counts(max_txsize_lookup[bsize], vp9_get_tx_size_context(xd),
|
||||
&td->counts->tx)[mbmi->tx_size];
|
||||
} else {
|
||||
BLOCK_SIZE txb_size = txsize_to_bsize[max_txsize_lookup[bsize]];
|
||||
int bh = num_4x4_blocks_wide_lookup[txb_size];
|
||||
int width = num_4x4_blocks_wide_lookup[bsize];
|
||||
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 += bh)
|
||||
for (idx = 0; idx < width; idx += bh)
|
||||
update_txfm_count(xd, td->counts, max_txsize_lookup[mbmi->sb_type],
|
||||
idy, idx);
|
||||
}
|
||||
} else {
|
||||
int x, y;
|
||||
TX_SIZE tx_size;
|
||||
|
@ -1382,7 +1382,6 @@ static void select_tx_block(const VP9_COMP *cpi, MACROBLOCK *x,
|
||||
*dist = sum_dist;
|
||||
*bsse = sum_bsse;
|
||||
*skip = all_skip;
|
||||
|
||||
vpx_memcpy(pta, ctxa + (blk_col >> pd->subsampling_x),
|
||||
sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide_lookup[txb_bsize]);
|
||||
vpx_memcpy(ptl, ctxl + (blk_row >> pd->subsampling_y),
|
||||
@ -3749,8 +3748,7 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
|
||||
rate2 += intra_cost_penalty;
|
||||
distortion2 = distortion_y + distortion_uv;
|
||||
} else {
|
||||
this_rd = handle_inter_mode(cpi, x, bsize,
|
||||
tx_cache,
|
||||
this_rd = handle_inter_mode(cpi, x, bsize, tx_cache,
|
||||
&rate2, &distortion2, &skippable,
|
||||
&rate_y, &rate_uv,
|
||||
&disable_skip, frame_mv,
|
||||
|
@ -743,7 +743,7 @@ void tokenize_tx(VP9_COMP *cpi, ThreadData *td, TOKENEXTRA **t,
|
||||
for (i = 0; i < 4; ++i) {
|
||||
int offsetr = (i >> 1) * bh / 2;
|
||||
int offsetc = (i & 0x01) * bh / 2;
|
||||
int step = 1 << (2 *(tx_size - 1));
|
||||
int step = 1 << (2 * (tx_size - 1));
|
||||
tokenize_tx(cpi, td, t, dry_run, tx_size - 1, plane_bsize,
|
||||
blk_row + offsetr, blk_col + offsetc,
|
||||
block + i * step, plane, arg);
|
||||
|
Loading…
x
Reference in New Issue
Block a user