Pack txfm-search records in MACROBLOCK to TxfmSearchInfo
This CL introduces TxfmSearchInfo struct that is meant to store the
intermediate results during txfm search.
Bug=aomedia:2618
Change-Id: Id5860a6017fceeaec742066644a03645114669e6
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 3e9dce9..ba6892f 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -297,6 +297,61 @@
TX_MODE tx_mode_search_type;
} TxfmSearchParams;
+#define MAX_NUM_8X8_TXBS ((MAX_MIB_SIZE >> 1) * (MAX_MIB_SIZE >> 1))
+#define MAX_NUM_16X16_TXBS ((MAX_MIB_SIZE >> 2) * (MAX_MIB_SIZE >> 2))
+#define MAX_NUM_32X32_TXBS ((MAX_MIB_SIZE >> 3) * (MAX_MIB_SIZE >> 3))
+#define MAX_NUM_64X64_TXBS ((MAX_MIB_SIZE >> 4) * (MAX_MIB_SIZE >> 4))
+
+// This struct stores various encoding/search decisions related to txfm search.
+// This can include cache of previous txfm results, the current encoding
+// decision, etc.
+typedef struct {
+ // Skips transform and quantization on a partition block level.
+ int skip_txfm;
+
+ // Skips transform and quantization on a transform block level inside the
+ // current partition block. Each element of this array is used as a bit-field.
+ // So for example, the we are skipping on the luma plane, then the last bit
+ // would be set to 1.
+ uint8_t blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
+
+ // Keeps a record of what kind of transform to use for each of the transform
+ // block inside the partition block. A quick note here: the buffer here is
+ // NEVER directly used. Instead, this just allocates the memory for
+ // MACROBLOCKD::tx_type_map during rdopt on the partition block. So if we need
+ // to save memory, we could move the allocation to pick_sb_mode instead.
+ uint8_t tx_type_map_[MAX_MIB_SIZE * MAX_MIB_SIZE];
+
+ // Records of a partition block's inter-mode txfm result hashed by its
+ // residue. This is similar to txb_rd_record_*, but this operates on the whole
+ // prediction block.
+ MB_RD_RECORD mb_rd_record;
+
+ // Records of a transform block's result hashed by residue within the
+ // transform block. This operates on txb level only and only applies to square
+ // txfms.
+ // Inter transform block RD search
+ TXB_RD_RECORD txb_rd_record_8X8[MAX_NUM_8X8_TXBS];
+ TXB_RD_RECORD txb_rd_record_16X16[MAX_NUM_16X16_TXBS];
+ TXB_RD_RECORD txb_rd_record_32X32[MAX_NUM_32X32_TXBS];
+ TXB_RD_RECORD txb_rd_record_64X64[MAX_NUM_64X64_TXBS];
+ // Intra transform block RD search
+ TXB_RD_RECORD txb_rd_record_intra;
+
+ // Keep track of how many times we've used split partition for transform
+ // blocks. Misleadingly, his parameter doesn't actually keep track of the
+ // count of the current block. Instead, it's a cumulative count across of the
+ // whole frame. The main usage is that if txb_split_count is zero, then we
+ // can signal TX_MODE_LARGEST at frame level.
+ // TODO(chiyotsai@google.com): Move this to a more appropriate location such
+ // as ThreadData.
+ unsigned int txb_split_count;
+#if CONFIG_SPEED_STATS
+ // For debugging. Used to check how many txfm searches we are doing.
+ unsigned int tx_search_count;
+#endif // CONFIG_SPEED_STATS
+} TxfmSearchInfo;
+
struct inter_modes_info;
typedef struct macroblock MACROBLOCK;
struct macroblock {
@@ -310,18 +365,6 @@
// prune_comp_search_by_single_result (3:MAX_REF_MV_SEARCH)
SimpleRDState simple_rd_state[SINGLE_REF_MODES][3];
- // Inter macroblock RD search info.
- MB_RD_RECORD mb_rd_record;
-
- // Inter transform block RD search info. for square TX sizes.
- TXB_RD_RECORD txb_rd_record_8X8[(MAX_MIB_SIZE >> 1) * (MAX_MIB_SIZE >> 1)];
- TXB_RD_RECORD txb_rd_record_16X16[(MAX_MIB_SIZE >> 2) * (MAX_MIB_SIZE >> 2)];
- TXB_RD_RECORD txb_rd_record_32X32[(MAX_MIB_SIZE >> 3) * (MAX_MIB_SIZE >> 3)];
- TXB_RD_RECORD txb_rd_record_64X64[(MAX_MIB_SIZE >> 4) * (MAX_MIB_SIZE >> 4)];
-
- // Intra transform block RD search info. for square TX sizes.
- TXB_RD_RECORD txb_rd_record_intra;
-
MACROBLOCKD e_mbd;
MB_MODE_INFO_EXT *mbmi_ext;
MB_MODE_INFO_EXT_FRAME *mbmi_ext_frame;
@@ -341,11 +384,6 @@
int mb_energy;
int sb_energy_level;
- unsigned int txb_split_count;
-#if CONFIG_SPEED_STATS
- unsigned int tx_search_count;
-#endif // CONFIG_SPEED_STATS
-
// These are set to their default values at the beginning, and then adjusted
// further in the encoding process.
BLOCK_SIZE min_partition_size;
@@ -395,11 +433,6 @@
// Stores the entropy cost needed to encode a motion vector.
MvCostInfo mv_cost_info;
- uint8_t blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
- uint8_t tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
-
- // Forces the coding block to skip transform and quantization.
- int skip_txfm;
int skip_txfm_cost[SKIP_CONTEXTS][2];
// Skip mode tries to use the closest forward and backward references for
@@ -410,7 +443,6 @@
LV_MAP_COEFF_COST coeff_costs[TX_SIZES][PLANE_TYPES];
LV_MAP_EOB_COST eob_costs[7][2];
- uint16_t cb_offset;
// mode costs
int intra_inter_cost[INTRA_INTER_CONTEXTS][2];
@@ -494,8 +526,6 @@
COMP_RD_STATS comp_rd_stats[MAX_COMP_RD_STATS];
int comp_rd_stats_idx;
- CB_COEFF_BUFFER *cb_coef_buff;
-
#if !CONFIG_REALTIME_ONLY
int quad_tree_idx;
int cnn_output_valid;
@@ -518,11 +548,22 @@
uint8_t color_sensitivity[2];
int nonrd_prune_ref_frame_search;
+ uint8_t search_ref_frame[REF_FRAMES];
+
// Stores various txfm search related parameters such as txfm_type, txfm_size,
// trellis eob search, etc.
TxfmSearchParams txfm_search_params;
- uint8_t search_ref_frame[REF_FRAMES];
+ // Caches old txfm search results and keeps the current txfm decisions.
+ TxfmSearchInfo txfm_search_info;
+
+ // Points to cb_coef_buff in the AV1_COMP struct, which contains the finalized
+ // coefficients. This is here to conveniently copy the best coefficients to
+ // frame level for bitstream packing. Since CB_COEFF_BUFFER is allocated on a
+ // superblock level, we need to combine it with cb_offset to get the proper
+ // position for the current coding block.
+ CB_COEFF_BUFFER *cb_coef_buff;
+ uint16_t cb_offset;
// The information on a whole superblock level.
// TODO(chiyotsai@google.com): Refactor this out of macroblock
@@ -585,34 +626,34 @@
return depth;
}
-static INLINE void set_blk_skip(MACROBLOCK *x, int plane, int blk_idx,
+static INLINE void set_blk_skip(uint8_t txb_skip[], int plane, int blk_idx,
int skip) {
if (skip)
- x->blk_skip[blk_idx] |= 1UL << plane;
+ txb_skip[blk_idx] |= 1UL << plane;
else
- x->blk_skip[blk_idx] &= ~(1UL << plane);
+ txb_skip[blk_idx] &= ~(1UL << plane);
#ifndef NDEBUG
// Set chroma planes to uninitialized states when luma is set to check if
// it will be set later
if (plane == 0) {
- x->blk_skip[blk_idx] |= 1UL << (1 + 4);
- x->blk_skip[blk_idx] |= 1UL << (2 + 4);
+ txb_skip[blk_idx] |= 1UL << (1 + 4);
+ txb_skip[blk_idx] |= 1UL << (2 + 4);
}
// Clear the initialization checking bit
- x->blk_skip[blk_idx] &= ~(1UL << (plane + 4));
+ txb_skip[blk_idx] &= ~(1UL << (plane + 4));
#endif
}
-static INLINE int is_blk_skip(MACROBLOCK *x, int plane, int blk_idx) {
+static INLINE int is_blk_skip(uint8_t *txb_skip, int plane, int blk_idx) {
#ifndef NDEBUG
// Check if this is initialized
- assert(!(x->blk_skip[blk_idx] & (1UL << (plane + 4))));
+ assert(!(txb_skip[blk_idx] & (1UL << (plane + 4))));
// The magic number is 0x77, this is to test if there is garbage data
- assert((x->blk_skip[blk_idx] & 0x88) == 0);
+ assert((txb_skip[blk_idx] & 0x88) == 0);
#endif
- return (x->blk_skip[blk_idx] >> plane) & 1;
+ return (txb_skip[blk_idx] >> plane) & 1;
}
#ifdef __cplusplus
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 720f9cf..b52c85c 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -488,6 +488,7 @@
static AOM_INLINE void reset_tx_size(MACROBLOCK *x, MB_MODE_INFO *mbmi,
const TX_MODE tx_mode) {
MACROBLOCKD *const xd = &x->e_mbd;
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
if (xd->lossless[mbmi->segment_id]) {
mbmi->tx_size = TX_4X4;
} else if (tx_mode != TX_MODE_SELECT) {
@@ -506,8 +507,8 @@
memset(xd->tx_type_map + row * stride, DCT_DCT,
bw * sizeof(xd->tx_type_map[0]));
}
- av1_zero(x->blk_skip);
- x->skip_txfm = 0;
+ av1_zero(txfm_info->blk_skip);
+ txfm_info->skip_txfm = 0;
}
// This function will copy the best reference mode information from
@@ -546,6 +547,7 @@
const int mis = mi_params->mi_stride;
const int mi_width = mi_size_wide[bsize];
const int mi_height = mi_size_high[bsize];
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
assert(mi->sb_type == bsize);
@@ -553,9 +555,10 @@
copy_mbmi_ext_frame_to_mbmi_ext(x->mbmi_ext, &ctx->mbmi_ext_best,
av1_ref_frame_type(ctx->mic.ref_frame));
- memcpy(x->blk_skip, ctx->blk_skip, sizeof(x->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(txfm_info->blk_skip, ctx->blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
- x->skip_txfm = ctx->rd_stats.skip_txfm;
+ txfm_info->skip_txfm = ctx->rd_stats.skip_txfm;
xd->tx_type_map = ctx->tx_type_map;
xd->tx_type_map_stride = mi_size_wide[bsize];
@@ -588,7 +591,7 @@
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
av1_cyclic_refresh_update_segment(cpi, mi_addr, mi_row, mi_col, bsize,
ctx->rd_stats.rate, ctx->rd_stats.dist,
- x->skip_txfm);
+ txfm_info->skip_txfm);
}
if (mi_addr->uv_mode == UV_CFL_PRED && !is_cfl_allowed(xd))
mi_addr->uv_mode = UV_DC_PRED;
@@ -750,6 +753,8 @@
struct macroblock_plane *const p = x->plane;
struct macroblockd_plane *const pd = xd->plane;
const AQ_MODE aq_mode = cpi->oxcf.aq_mode;
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
+
int i;
#if CONFIG_COLLECT_COMPONENT_TIMING
@@ -767,7 +772,8 @@
mbmi->mi_col = mi_col;
#endif
- xd->tx_type_map = x->tx_type_map;
+ // Sets up the tx_type_map buffer in MACROBLOCKD.
+ xd->tx_type_map = txfm_info->tx_type_map_;
xd->tx_type_map_stride = mi_size_wide[bsize];
for (i = 0; i < num_planes; ++i) {
@@ -2879,7 +2885,8 @@
// when debugging.
// bit 0, 1, 2 are blk_skip of each plane
// bit 4, 5, 6 are initialization checking of each plane
- memset(x->blk_skip, 0x77, sizeof(x->blk_skip));
+ memset(x->txfm_search_info.blk_skip, 0x77,
+ sizeof(x->txfm_search_info.blk_skip));
#endif // NDEBUG
assert(mi_size_wide[bsize] == mi_size_high[bsize]);
@@ -4663,7 +4670,7 @@
save_context(x, &sb_fp_stats->x_ctx, mi_row, mi_col, sb_size, num_planes);
sb_fp_stats->rd_count = cpi->td.rd_counts;
- sb_fp_stats->split_count = cpi->td.mb.txb_split_count;
+ sb_fp_stats->split_count = x->txfm_search_info.txb_split_count;
sb_fp_stats->fc = *td->counts;
@@ -4696,7 +4703,7 @@
restore_context(x, &sb_fp_stats->x_ctx, mi_row, mi_col, sb_size, num_planes);
cpi->td.rd_counts = sb_fp_stats->rd_count;
- cpi->td.mb.txb_split_count = sb_fp_stats->split_count;
+ x->txfm_search_info.txb_split_count = sb_fp_stats->split_count;
*td->counts = sb_fp_stats->fc;
@@ -4854,7 +4861,7 @@
#endif
// Reset hash state for transform/mode rd hash information
- reset_hash_records(x, cpi->sf.tx_sf.use_inter_txb_hash);
+ reset_hash_records(&x->txfm_search_info, cpi->sf.tx_sf.use_inter_txb_hash);
av1_zero(x->picked_ref_frames_mask);
av1_zero(x->pred_mv);
av1_invalid_rd_stats(rd_cost);
@@ -5244,7 +5251,8 @@
if (cpi->oxcf.enable_cfl_intra) cfl_init(&td->mb.e_mbd.cfl, &cm->seq_params);
- av1_crc32c_calculator_init(&td->mb.mb_rd_record.crc_calculator);
+ av1_crc32c_calculator_init(
+ &td->mb.txfm_search_info.mb_rd_record.crc_calculator);
for (int mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
mi_row += cm->seq_params.mib_size) {
@@ -6066,9 +6074,9 @@
// Figure out which ref frames can be skipped at frame level.
setup_prune_ref_frame_mask(cpi);
- x->txb_split_count = 0;
+ x->txfm_search_info.txb_split_count = 0;
#if CONFIG_SPEED_STATS
- x->tx_search_count = 0;
+ x->txfm_search_info.tx_search_count = 0;
#endif // CONFIG_SPEED_STATS
#if CONFIG_COLLECT_COMPONENT_TIMING
@@ -6324,7 +6332,7 @@
if (!cm->tiles.large_scale) {
if (features->tx_mode == TX_MODE_SELECT &&
- cpi->td.mb.txb_split_count == 0)
+ cpi->td.mb.txfm_search_info.txb_split_count == 0)
features->tx_mode = TX_MODE_LARGEST;
}
} else {
@@ -6376,7 +6384,7 @@
#endif
if (allow_update_cdf)
update_cdf(xd->tile_ctx->txfm_partition_cdf[ctx], 1, 2);
- ++x->txb_split_count;
+ ++x->txfm_search_info.txb_split_count;
if (sub_txs == TX_4X4) {
mbmi->inter_tx_size[txb_size_index] = TX_4X4;
@@ -6595,7 +6603,7 @@
tile_data->allow_update_cdf);
} else {
if (mbmi->tx_size != max_txsize_rect_lookup[bsize])
- ++x->txb_split_count;
+ ++x->txfm_search_info.txb_split_count;
if (block_signals_txsize(bsize)) {
const int tx_size_ctx = get_tx_size_context(xd);
const int32_t tx_size_cat = bsize_to_tx_size_cat(bsize);
@@ -6632,7 +6640,8 @@
mi_row + j < cm->mi_params.mi_rows)
mi_4x4[mis * j + i]->tx_size = intra_tx_size;
- if (intra_tx_size != max_txsize_rect_lookup[bsize]) ++x->txb_split_count;
+ if (intra_tx_size != max_txsize_rect_lookup[bsize])
+ ++x->txfm_search_info.txb_split_count;
}
}
diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c
index a6cc72e..5a986b1 100644
--- a/av1/encoder/encodemb.c
+++ b/av1/encoder/encodemb.c
@@ -366,7 +366,9 @@
l = &args->tl[blk_row];
TX_TYPE tx_type = DCT_DCT;
- if (!is_blk_skip(x, plane, blk_row * bw + blk_col) && !mbmi->skip_mode) {
+ if (!is_blk_skip(x->txfm_search_info.blk_skip, plane,
+ blk_row * bw + blk_col) &&
+ !mbmi->skip_mode) {
tx_type = av1_get_tx_type(xd, pd->plane_type, blk_row, blk_col, tx_size,
cm->features.reduced_tx_set_used);
TxfmParam txfm_param;
@@ -601,7 +603,7 @@
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *mbmi = xd->mi[0];
mbmi->skip_txfm = 1;
- if (x->skip_txfm) return;
+ if (x->txfm_search_info.skip_txfm) return;
struct optimize_ctx ctx;
struct encode_b_args arg = {
@@ -690,7 +692,8 @@
TX_TYPE tx_type = DCT_DCT;
const int bw = mi_size_wide[plane_bsize];
- if (plane == 0 && is_blk_skip(x, plane, blk_row * bw + blk_col)) {
+ if (plane == 0 && is_blk_skip(x->txfm_search_info.blk_skip, plane,
+ blk_row * bw + blk_col)) {
*eob = 0;
p->txb_entropy_ctx[block] = 0;
} else {
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index e027b6a..b976f09 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -6939,8 +6939,8 @@
#endif // CONFIG_INTERNAL_STATS
#if CONFIG_SPEED_STATS
if (!is_stat_generation_stage(cpi) && !cm->show_existing_frame) {
- cpi->tx_search_count += cpi->td.mb.tx_search_count;
- cpi->td.mb.tx_search_count = 0;
+ cpi->tx_search_count += cpi->td.mb.txfm_search_info.tx_search_count;
+ cpi->td.mb.txfm_search_info.tx_search_count = 0;
}
#endif // CONFIG_SPEED_STATS
diff --git a/av1/encoder/ethread.c b/av1/encoder/ethread.c
index 09039af..753bd2b 100644
--- a/av1/encoder/ethread.c
+++ b/av1/encoder/ethread.c
@@ -401,7 +401,8 @@
&td->mb.e_mbd);
cfl_init(&td->mb.e_mbd.cfl, &cm->seq_params);
- av1_crc32c_calculator_init(&td->mb.mb_rd_record.crc_calculator);
+ av1_crc32c_calculator_init(
+ &td->mb.txfm_search_info.mb_rd_record.crc_calculator);
av1_encode_sb_row(cpi, td, tile_row, tile_col, current_mi_row);
#if CONFIG_MULTITHREAD
@@ -595,9 +596,11 @@
if (i > 0) {
av1_accumulate_frame_counts(&cpi->counts, thread_data->td->counts);
accumulate_rd_opt(&cpi->td, thread_data->td);
- cpi->td.mb.txb_split_count += thread_data->td->mb.txb_split_count;
+ cpi->td.mb.txfm_search_info.txb_split_count +=
+ thread_data->td->mb.txfm_search_info.txb_split_count;
#if CONFIG_SPEED_STATS
- cpi->td.mb.tx_search_count += thread_data->td->mb.tx_search_count;
+ cpi->td.mb.txfm_search_info.tx_search_count +=
+ thread_data->td->mb.txfm_search_info.tx_search_count;
#endif // CONFIG_SPEED_STATS
}
}
diff --git a/av1/encoder/intra_mode_search.c b/av1/encoder/intra_mode_search.c
index 39fc8db..f1b5723 100644
--- a/av1/encoder/intra_mode_search.c
+++ b/av1/encoder/intra_mode_search.c
@@ -286,7 +286,8 @@
this_rd = RDCOST(x->rdmult, this_rate, tokenonly_rd_stats.dist);
if (this_rd < *best_rd) {
- memcpy(best_blk_skip, x->blk_skip, sizeof(best_blk_skip[0]) * n4);
+ memcpy(best_blk_skip, x->txfm_search_info.blk_skip,
+ sizeof(best_blk_skip[0]) * n4);
av1_copy_array(best_tx_type_map, xd->tx_type_map, n4);
*best_rd = this_rd;
*best_angle_delta = mbmi->angle_delta[PLANE_TYPE_Y];
@@ -455,8 +456,8 @@
best_tx_size = mbmi->tx_size;
filter_intra_mode_info = mbmi->filter_intra_mode_info;
av1_copy_array(best_tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
- memcpy(ctx->blk_skip, x->blk_skip,
- sizeof(x->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(ctx->blk_skip, x->txfm_search_info.blk_skip,
+ sizeof(x->txfm_search_info.blk_skip[0]) * ctx->num_4x4_blk);
*rate = this_rate;
*rate_tokenonly = tokenonly_rd_stats.rate;
*distortion = tokenonly_rd_stats.dist;
@@ -627,7 +628,8 @@
memcpy(best_palette_color_map, color_map,
block_width * block_height * sizeof(color_map[0]));
*best_mbmi = *mbmi;
- memcpy(blk_skip, x->blk_skip, sizeof(x->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(blk_skip, x->txfm_search_info.blk_skip,
+ sizeof(x->txfm_search_info.blk_skip[0]) * ctx->num_4x4_blk);
av1_copy_array(tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
if (rate) *rate = this_rate;
if (rate_tokenonly) *rate_tokenonly = tokenonly_rd_stats.rate;
@@ -1569,7 +1571,7 @@
return skippable;
}
- memcpy(x->blk_skip, best_blk_skip,
+ memcpy(x->txfm_search_info.blk_skip, best_blk_skip,
sizeof(best_blk_skip[0]) * bsize_to_num_blk(bsize));
av1_copy_array(xd->tx_type_map, best_tx_type_map, ctx->num_4x4_blk);
memcpy(color_map, best_palette_color_map,
@@ -1648,7 +1650,8 @@
*rate_tokenonly = this_rate_tokenonly;
*distortion = rd_stats.dist;
*skippable = rd_stats.skip_txfm;
- av1_copy_array(ctx->blk_skip, x->blk_skip, ctx->num_4x4_blk);
+ av1_copy_array(ctx->blk_skip, x->txfm_search_info.blk_skip,
+ ctx->num_4x4_blk);
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
return 1;
}
@@ -1716,7 +1719,8 @@
mbmi->tx_size = best_tx_size;
mbmi->angle_delta[PLANE_TYPE_Y] = best_angle_delta;
const int n4 = bsize_to_num_blk(bsize);
- memcpy(x->blk_skip, best_blk_skip, sizeof(best_blk_skip[0]) * n4);
+ memcpy(x->txfm_search_info.blk_skip, best_blk_skip,
+ sizeof(best_blk_skip[0]) * n4);
av1_copy_array(xd->tx_type_map, best_tx_type_map, n4);
}
return best_rd;
@@ -1797,7 +1801,7 @@
TX_SIZE best_tx_size = mbmi->tx_size;
FILTER_INTRA_MODE best_fi_mode = FILTER_DC_PRED;
uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
- memcpy(best_blk_skip, x->blk_skip,
+ memcpy(best_blk_skip, x->txfm_search_info.blk_skip,
sizeof(best_blk_skip[0]) * ctx->num_4x4_blk);
uint8_t best_tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
av1_copy_array(best_tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
@@ -1820,7 +1824,7 @@
if (this_rd_tmp < best_rd_so_far) {
best_tx_size = mbmi->tx_size;
av1_copy_array(best_tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
- memcpy(best_blk_skip, x->blk_skip,
+ memcpy(best_blk_skip, x->txfm_search_info.blk_skip,
sizeof(best_blk_skip[0]) * ctx->num_4x4_blk);
best_fi_mode = fi_mode;
*rd_stats_y = rd_stats_y_fi;
@@ -1831,8 +1835,8 @@
mbmi->tx_size = best_tx_size;
av1_copy_array(xd->tx_type_map, best_tx_type_map, ctx->num_4x4_blk);
- memcpy(x->blk_skip, best_blk_skip,
- sizeof(x->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(x->txfm_search_info.blk_skip, best_blk_skip,
+ sizeof(x->txfm_search_info.blk_skip[0]) * ctx->num_4x4_blk);
if (filter_intra_selected_flag) {
mbmi->filter_intra_mode_info.use_filter_intra = 1;
@@ -2053,8 +2057,8 @@
*rate_tokenonly = this_rate_tokenonly;
*distortion = this_distortion;
*skippable = s;
- memcpy(ctx->blk_skip, x->blk_skip,
- sizeof(x->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(ctx->blk_skip, x->txfm_search_info.blk_skip,
+ sizeof(x->txfm_search_info.blk_skip[0]) * ctx->num_4x4_blk);
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
}
}
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 0dcb3a0..93528e3 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -918,19 +918,21 @@
static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
#endif // CONFIG_INTERNAL_STATS
MACROBLOCKD *const xd = &x->e_mbd;
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
// Take a snapshot of the coding context so it can be
// restored if we decide to encode this way
- ctx->rd_stats.skip_txfm = x->skip_txfm;
+ ctx->rd_stats.skip_txfm = txfm_info->skip_txfm;
+
memset(ctx->blk_skip, 0, sizeof(ctx->blk_skip[0]) * ctx->num_4x4_blk);
memset(ctx->tx_type_map, DCT_DCT,
sizeof(ctx->tx_type_map[0]) * ctx->num_4x4_blk);
- ctx->skippable = x->skip_txfm;
+ ctx->skippable = txfm_info->skip_txfm;
#if CONFIG_INTERNAL_STATS
ctx->best_mode_index = mode_index;
#endif // CONFIG_INTERNAL_STATS
ctx->mic = *xd->mi[0];
- ctx->skippable = x->skip_txfm;
+ ctx->skippable = txfm_info->skip_txfm;
av1_copy_mbmi_ext_to_mbmi_ext_frame(&ctx->mbmi_ext_best, x->mbmi_ext,
av1_ref_frame_type(xd->mi[0]->ref_frame));
ctx->comp_pred_diff = 0;
@@ -1738,6 +1740,7 @@
struct buf_2d orig_dst = pd->dst;
const CommonQuantParams *quant_params = &cm->quant_params;
const TxfmSearchParams *txfm_params = &x->txfm_search_params;
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
#if COLLECT_PICK_MODE_STAT
aom_usec_timer_start(&ms_stat.timer2);
#endif
@@ -1768,7 +1771,7 @@
tmp[3].in_use = 0;
}
- x->skip_txfm = 0;
+ txfm_info->skip_txfm = 0;
// Instead of using av1_get_pred_context_switchable_interp(xd) to assign
// filter_ref, we use a less strict condition on assigning filter_ref.
@@ -2107,7 +2110,7 @@
if (reuse_inter_pred) free_pred_buffer(this_mode_pred);
}
if (best_early_term && idx > 0) {
- x->skip_txfm = 1;
+ txfm_info->skip_txfm = 1;
break;
}
}
@@ -2119,7 +2122,7 @@
mi->ref_frame[0] = best_pickmode.best_ref_frame;
mi->mv[0].as_int =
frame_mv[best_pickmode.best_mode][best_pickmode.best_ref_frame].as_int;
- x->skip_txfm = best_rdc.skip_txfm;
+ txfm_info->skip_txfm = best_rdc.skip_txfm;
// Perform intra prediction search, if the best SAD is above a certain
// threshold.
diff --git a/av1/encoder/rd.h b/av1/encoder/rd.h
index 4cf3816..32aea44 100644
--- a/av1/encoder/rd.h
+++ b/av1/encoder/rd.h
@@ -310,7 +310,7 @@
}
// Used to reset the state of tx/mb rd hash information
-static INLINE void reset_hash_records(MACROBLOCK *const x,
+static INLINE void reset_hash_records(TxfmSearchInfo *const txfm_info,
int use_inter_txb_hash) {
int32_t record_idx;
@@ -318,27 +318,28 @@
if (use_inter_txb_hash) {
for (record_idx = 0;
record_idx < ((MAX_MIB_SIZE >> 1) * (MAX_MIB_SIZE >> 1)); record_idx++)
- x->txb_rd_record_8X8[record_idx].num =
- x->txb_rd_record_8X8[record_idx].index_start = 0;
+ txfm_info->txb_rd_record_8X8[record_idx].num =
+ txfm_info->txb_rd_record_8X8[record_idx].index_start = 0;
for (record_idx = 0;
record_idx < ((MAX_MIB_SIZE >> 2) * (MAX_MIB_SIZE >> 2)); record_idx++)
- x->txb_rd_record_16X16[record_idx].num =
- x->txb_rd_record_16X16[record_idx].index_start = 0;
+ txfm_info->txb_rd_record_16X16[record_idx].num =
+ txfm_info->txb_rd_record_16X16[record_idx].index_start = 0;
for (record_idx = 0;
record_idx < ((MAX_MIB_SIZE >> 3) * (MAX_MIB_SIZE >> 3)); record_idx++)
- x->txb_rd_record_32X32[record_idx].num =
- x->txb_rd_record_32X32[record_idx].index_start = 0;
+ txfm_info->txb_rd_record_32X32[record_idx].num =
+ txfm_info->txb_rd_record_32X32[record_idx].index_start = 0;
for (record_idx = 0;
record_idx < ((MAX_MIB_SIZE >> 4) * (MAX_MIB_SIZE >> 4)); record_idx++)
- x->txb_rd_record_64X64[record_idx].num =
- x->txb_rd_record_64X64[record_idx].index_start = 0;
+ txfm_info->txb_rd_record_64X64[record_idx].num =
+ txfm_info->txb_rd_record_64X64[record_idx].index_start = 0;
}
// Reset the state for use_intra_txb_hash
- x->txb_rd_record_intra.num = x->txb_rd_record_intra.index_start = 0;
+ txfm_info->txb_rd_record_intra.num =
+ txfm_info->txb_rd_record_intra.index_start = 0;
// Reset the state for use_mb_rd_hash
- x->mb_rd_record.num = x->mb_rd_record.index_start = 0;
+ txfm_info->mb_rd_record.num = txfm_info->mb_rd_record.index_start = 0;
}
void av1_setup_pred_block(const MACROBLOCKD *xd,
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 655d0de..8588928 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -901,7 +901,7 @@
// Take a snapshot of the coding context so it can be
// restored if we decide to encode this way
- ctx->rd_stats.skip_txfm = x->skip_txfm;
+ ctx->rd_stats.skip_txfm = x->txfm_search_info.skip_txfm;
ctx->skippable = skippable;
#if CONFIG_INTERNAL_STATS
ctx->best_mode_index = mode_index;
@@ -1232,6 +1232,7 @@
int do_tx_search, InterModesInfo *inter_modes_info, int eval_motion_mode) {
const AV1_COMMON *const cm = &cpi->common;
const FeatureFlags *const features = &cm->features;
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
const int num_planes = av1_num_planes(cm);
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = xd->mi[0];
@@ -1326,7 +1327,7 @@
best_rd_stats_y = simple_states->rd_stats_y;
best_rd_stats_uv = simple_states->rd_stats_uv;
memcpy(best_blk_skip, simple_states->blk_skip,
- sizeof(x->blk_skip[0]) * xd->height * xd->width);
+ sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
av1_copy_array(best_tx_type_map, simple_states->tx_type_map,
xd->height * xd->width);
best_xskip_txfm = simple_states->skip_txfm;
@@ -1428,7 +1429,7 @@
// current mode
if (!av1_check_newmv_joint_nonzero(cm, x)) continue;
- x->skip_txfm = 0;
+ txfm_info->skip_txfm = 0;
rd_stats->dist = 0;
rd_stats->sse = 0;
rd_stats->skip_txfm = 1;
@@ -1559,8 +1560,8 @@
simple_states->rd_stats.rdcost = tmp_rd;
simple_states->rd_stats_y = *rd_stats_y;
simple_states->rd_stats_uv = *rd_stats_uv;
- memcpy(simple_states->blk_skip, x->blk_skip,
- sizeof(x->blk_skip[0]) * xd->height * xd->width);
+ memcpy(simple_states->blk_skip, txfm_info->blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
av1_copy_array(simple_states->tx_type_map, xd->tx_type_map,
xd->height * xd->width);
simple_states->skip_txfm = mbmi->skip_txfm;
@@ -1574,8 +1575,8 @@
best_rd_stats_y = *rd_stats_y;
best_rate_mv = tmp_rate_mv;
if (num_planes > 1) best_rd_stats_uv = *rd_stats_uv;
- memcpy(best_blk_skip, x->blk_skip,
- sizeof(x->blk_skip[0]) * xd->height * xd->width);
+ memcpy(best_blk_skip, txfm_info->blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
av1_copy_array(best_tx_type_map, xd->tx_type_map, xd->height * xd->width);
best_xskip_txfm = mbmi->skip_txfm;
best_disable_skip_txfm = *disable_skip_txfm;
@@ -1595,10 +1596,10 @@
*rd_stats = best_rd_stats;
*rd_stats_y = best_rd_stats_y;
if (num_planes > 1) *rd_stats_uv = best_rd_stats_uv;
- memcpy(x->blk_skip, best_blk_skip,
- sizeof(x->blk_skip[0]) * xd->height * xd->width);
+ memcpy(txfm_info->blk_skip, best_blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
av1_copy_array(xd->tx_type_map, best_tx_type_map, xd->height * xd->width);
- x->skip_txfm = best_xskip_txfm;
+ txfm_info->skip_txfm = best_xskip_txfm;
*disable_skip_txfm = best_disable_skip_txfm;
restore_dst_buf(xd, *orig_dst, num_planes);
@@ -2378,6 +2379,7 @@
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = xd->mi[0];
MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
const int is_comp_pred = has_second_ref(mbmi);
const PREDICTION_MODE this_mode = mbmi->mode;
@@ -2659,8 +2661,8 @@
best_rd = tmp_rd;
best_mbmi = *mbmi;
best_disable_skip_txfm = *disable_skip_txfm;
- best_xskip_txfm = x->skip_txfm;
- memcpy(best_blk_skip, x->blk_skip,
+ best_xskip_txfm = txfm_info->skip_txfm;
+ memcpy(best_blk_skip, txfm_info->blk_skip,
sizeof(best_blk_skip[0]) * xd->height * xd->width);
av1_copy_array(best_tx_type_map, xd->tx_type_map,
xd->height * xd->width);
@@ -2684,10 +2686,10 @@
*rd_stats_uv = best_rd_stats_uv;
*mbmi = best_mbmi;
*disable_skip_txfm = best_disable_skip_txfm;
- x->skip_txfm = best_xskip_txfm;
+ txfm_info->skip_txfm = best_xskip_txfm;
assert(IMPLIES(mbmi->comp_group_idx == 1,
mbmi->interinter_comp.type != COMPOUND_AVERAGE));
- memcpy(x->blk_skip, best_blk_skip,
+ memcpy(txfm_info->blk_skip, best_blk_skip,
sizeof(best_blk_skip[0]) * xd->height * xd->width);
av1_copy_array(xd->tx_type_map, best_tx_type_map, xd->height * xd->width);
@@ -2707,6 +2709,8 @@
MACROBLOCKD *const xd = &x->e_mbd;
const TileInfo *tile = &xd->tile;
MB_MODE_INFO *mbmi = xd->mi[0];
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
+
const int mi_row = xd->mi_row;
const int mi_col = xd->mi_col;
const int w = block_size_wide[bsize];
@@ -2865,15 +2869,15 @@
best_rd = rd_stats_yuv.rdcost;
best_mbmi = *mbmi;
best_rdstats = rd_stats_yuv;
- memcpy(best_blk_skip, x->blk_skip,
- sizeof(x->blk_skip[0]) * xd->height * xd->width);
+ memcpy(best_blk_skip, txfm_info->blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
av1_copy_array(best_tx_type_map, xd->tx_type_map, xd->height * xd->width);
}
}
*mbmi = best_mbmi;
*rd_stats = best_rdstats;
- memcpy(x->blk_skip, best_blk_skip,
- sizeof(x->blk_skip[0]) * xd->height * xd->width);
+ memcpy(txfm_info->blk_skip, best_blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
av1_copy_array(xd->tx_type_map, best_tx_type_map, ctx->num_4x4_blk);
#if CONFIG_RD_DEBUG
mbmi->rd_stats = *rd_stats;
@@ -2888,6 +2892,7 @@
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = xd->mi[0];
const int num_planes = av1_num_planes(cm);
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
int y_skip_txfm = 0, uv_skip_txfm = 0;
int64_t dist_y = 0, dist_uv = 0;
@@ -2912,8 +2917,8 @@
xd->cfl.store_y = store_cfl_required_rdo(cm, x);
if (xd->cfl.store_y) {
// Restore reconstructed luma values.
- memcpy(x->blk_skip, ctx->blk_skip,
- sizeof(x->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(txfm_info->blk_skip, ctx->blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
av1_copy_array(xd->tx_type_map, ctx->tx_type_map, ctx->num_4x4_blk);
av1_encode_intra_block_plane(cpi, x, bsize, AOM_PLANE_Y, DRY_RUN_NORMAL,
cpi->optimize_seg_arr[mbmi->segment_id]);
@@ -2944,8 +2949,8 @@
best_rd = rd_cost->rdcost;
if (rd_pick_intrabc_mode_sb(cpi, x, ctx, rd_cost, bsize, best_rd) < best_rd) {
ctx->rd_stats.skip_txfm = mbmi->skip_txfm;
- memcpy(ctx->blk_skip, x->blk_skip,
- sizeof(x->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(ctx->blk_skip, txfm_info->blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
assert(rd_cost->rate != INT_MAX);
}
if (rd_cost->rate == INT_MAX) return;
@@ -3116,7 +3121,7 @@
search_state->best_skip2 = 1;
search_state->best_mode_skippable = 1;
- x->skip_txfm = 1;
+ x->txfm_search_info.skip_txfm = 1;
}
}
@@ -3161,6 +3166,7 @@
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = xd->mi[0];
TxfmSearchParams *txfm_params = &x->txfm_search_params;
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
int64_t best_rd;
const int num_planes = av1_num_planes(cm);
@@ -3226,7 +3232,7 @@
memset(mbmi->inter_tx_size, mbmi->tx_size,
sizeof(mbmi->inter_tx_size));
for (int i = 0; i < xd->height * xd->width; ++i)
- set_blk_skip(x, 0, i, rd_stats_y.skip_txfm);
+ set_blk_skip(txfm_info->blk_skip, 0, i, rd_stats_y.skip_txfm);
}
} else {
av1_pick_uniform_tx_size_type_yrd(cpi, x, &rd_stats_y, bsize,
@@ -3262,7 +3268,7 @@
if (best_rd > this_rd) {
*best_mbmode = *mbmi;
*best_mode_index = winner_mode_index;
- av1_copy_array(ctx->blk_skip, x->blk_skip, ctx->num_4x4_blk);
+ av1_copy_array(ctx->blk_skip, txfm_info->blk_skip, ctx->num_4x4_blk);
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
rd_cost->rate = this_rate;
rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
@@ -4222,6 +4228,7 @@
const int mode_is_intra =
(av1_mode_defs[new_best_mode].mode < INTRA_MODE_END);
const int skip_txfm = mbmi->skip_txfm && !mode_is_intra;
+ const TxfmSearchInfo *txfm_info = &x->txfm_search_info;
search_state->best_rd = new_best_rd_stats->rdcost;
search_state->best_mode_index = new_best_mode;
@@ -4231,7 +4238,7 @@
search_state->best_mode_skippable = new_best_rd_stats->skip_txfm;
// When !txfm_search_done, new_best_rd_stats won't provide correct rate_y and
// rate_uv because av1_txfm_search process is replaced by rd estimation.
- // Therfore, we should avoid updating best_rate_y and best_rate_uv here.
+ // Therefore, we should avoid updating best_rate_y and best_rate_uv here.
// These two values will be updated when av1_txfm_search is called.
if (txfm_search_done) {
search_state->best_rate_y =
@@ -4239,7 +4246,8 @@
x->skip_txfm_cost[skip_ctx][new_best_rd_stats->skip_txfm || skip_txfm];
search_state->best_rate_uv = new_best_rd_stats_uv->rate;
}
- memcpy(ctx->blk_skip, x->blk_skip, sizeof(x->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(ctx->blk_skip, txfm_info->blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
}
@@ -4304,7 +4312,7 @@
// Continue if the best candidate is compound.
if (!is_inter_singleref_mode(mbmi->mode)) continue;
- x->skip_txfm = 0;
+ x->txfm_search_info.skip_txfm = 0;
const int mode_index = get_prediction_mode_idx(
mbmi->mode, mbmi->ref_frame[0], mbmi->ref_frame[1]);
struct macroblockd_plane *p = xd->plane;
@@ -4555,6 +4563,7 @@
const SPEED_FEATURES *const sf = &cpi->sf;
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = xd->mi[0];
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
int i;
const int *comp_inter_cost =
x->comp_inter_cost[av1_get_reference_mode_context(xd)];
@@ -4759,7 +4768,7 @@
init_mbmi(mbmi, this_mode, ref_frames, cm);
- x->skip_txfm = 0;
+ txfm_info->skip_txfm = 0;
set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
// Apply speed features to decide if this inter mode can be skipped
@@ -4891,7 +4900,7 @@
int64_t curr_est_rd = inter_modes_info->est_rd_arr[data_idx];
if (curr_est_rd * 0.80 > top_est_rd) break;
- x->skip_txfm = 0;
+ txfm_info->skip_txfm = 0;
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
// Select prediction reference frames.
@@ -5004,7 +5013,7 @@
assert(av1_mode_defs[mode_enum].ref_frame[0] == INTRA_FRAME);
assert(av1_mode_defs[mode_enum].ref_frame[1] == NONE_FRAME);
init_mbmi(mbmi, this_mode, av1_mode_defs[mode_enum].ref_frame, cm);
- x->skip_txfm = 0;
+ txfm_info->skip_txfm = 0;
if (this_mode != DC_PRED) {
// Only search the oblique modes if the best so far is
@@ -5079,8 +5088,8 @@
search_state.best_mbmode = *mbmi;
search_state.best_skip2 = 0;
search_state.best_mode_skippable = this_skippable;
- memcpy(ctx->blk_skip, x->blk_skip,
- sizeof(x->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(ctx->blk_skip, txfm_info->blk_skip,
+ sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
}
}
@@ -5129,7 +5138,7 @@
// macroblock modes
*mbmi = search_state.best_mbmode;
- x->skip_txfm |= search_state.best_skip2;
+ txfm_info->skip_txfm |= search_state.best_skip2;
// Note: this section is needed since the mode may have been forced to
// GLOBALMV by the all-zero mode handling of ref-mv.
@@ -5153,7 +5162,7 @@
}
}
- x->skip_txfm |= search_state.best_mode_skippable;
+ txfm_info->skip_txfm |= search_state.best_mode_skippable;
assert(search_state.best_mode_index != THR_INVALID);
@@ -5226,7 +5235,7 @@
mi_row, features->cur_frame_force_integer_mv)
.as_int;
mbmi->tx_size = max_txsize_lookup[bsize];
- x->skip_txfm = 1;
+ x->txfm_search_info.skip_txfm = 1;
mbmi->ref_mv_idx = 0;
diff --git a/av1/encoder/rdopt_utils.h b/av1/encoder/rdopt_utils.h
index 752a0b8..3e2c267 100644
--- a/av1/encoder/rdopt_utils.h
+++ b/av1/encoder/rdopt_utils.h
@@ -467,6 +467,7 @@
const SPEED_FEATURES *sf = &cpi->sf;
const WinnerModeParams *winner_mode_params = &cpi->winner_mode_params;
TxfmSearchParams *txfm_params = &x->txfm_search_params;
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
switch (mode_eval_type) {
case DEFAULT_EVAL:
@@ -543,7 +544,7 @@
// the decisions would have been sub-optimal
// TODO(any): Move the evaluation of palette/IntraBC modes before winner
// mode is processed and clean-up the code below
- reset_hash_records(x, cpi->sf.tx_sf.use_inter_txb_hash);
+ reset_hash_records(txfm_info, cpi->sf.tx_sf.use_inter_txb_hash);
break;
default: assert(0);
diff --git a/av1/encoder/tx_search.c b/av1/encoder/tx_search.c
index 7aeda66..808f44c 100644
--- a/av1/encoder/tx_search.c
+++ b/av1/encoder/tx_search.c
@@ -252,10 +252,11 @@
// the form of a quadtree for easier access in actual TX size search.
static int find_tx_size_rd_records(MACROBLOCK *x, BLOCK_SIZE bsize,
TXB_RD_INFO_NODE *dst_rd_info) {
- TXB_RD_RECORD *rd_records_table[4] = { x->txb_rd_record_8X8,
- x->txb_rd_record_16X16,
- x->txb_rd_record_32X32,
- x->txb_rd_record_64X64 };
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
+ TXB_RD_RECORD *rd_records_table[4] = { txfm_info->txb_rd_record_8X8,
+ txfm_info->txb_rd_record_16X16,
+ txfm_info->txb_rd_record_32X32,
+ txfm_info->txb_rd_record_64X64 };
const TX_SIZE max_square_tx_size = max_txsize_lookup[bsize];
const int bw = block_size_wide[bsize];
const int bh = block_size_high[bsize];
@@ -301,9 +302,9 @@
cur_hash_row += cur_tx_bw;
cur_diff_row += diff_stride;
}
- const int hash = av1_get_crc32c_value(&x->mb_rd_record.crc_calculator,
- (uint8_t *)hash_data,
- 2 * cur_tx_bw * cur_tx_bh);
+ const int hash = av1_get_crc32c_value(
+ &txfm_info->mb_rd_record.crc_calculator, (uint8_t *)hash_data,
+ 2 * cur_tx_bw * cur_tx_bh);
// Find corresponding RD info based on the hash value.
const int record_idx =
row_in_sb * (MAX_MIB_SIZE >> (tx_size_idx + 1)) + col_in_sb;
@@ -325,8 +326,9 @@
const int rows = block_size_high[bsize];
const int cols = block_size_wide[bsize];
const int16_t *diff = x->plane[0].src_diff;
- const uint32_t hash = av1_get_crc32c_value(&x->mb_rd_record.crc_calculator,
- (uint8_t *)diff, 2 * rows * cols);
+ const uint32_t hash =
+ av1_get_crc32c_value(&x->txfm_search_info.mb_rd_record.crc_calculator,
+ (uint8_t *)diff, 2 * rows * cols);
return (hash << 5) + bsize;
}
@@ -355,7 +357,7 @@
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = xd->mi[0];
mbmi->tx_size = tx_rd_info->tx_size;
- memcpy(x->blk_skip, tx_rd_info->blk_skip,
+ memcpy(x->txfm_search_info.blk_skip, tx_rd_info->blk_skip,
sizeof(tx_rd_info->blk_skip[0]) * n4);
av1_copy(mbmi->inter_tx_size, tx_rd_info->inter_tx_size);
av1_copy_array(xd->tx_type_map, tx_rd_info->tx_type_map, n4);
@@ -463,7 +465,8 @@
memset(xd->tx_type_map, DCT_DCT, sizeof(xd->tx_type_map[0]) * n4);
memset(mbmi->inter_tx_size, tx_size, sizeof(mbmi->inter_tx_size));
mbmi->tx_size = tx_size;
- for (int i = 0; i < n4; ++i) set_blk_skip(x, 0, i, 1);
+ for (int i = 0; i < n4; ++i)
+ set_blk_skip(x->txfm_search_info.blk_skip, 0, i, 1);
rd_stats->skip_txfm = 1;
if (is_cur_buf_hbd(xd)) dist = ROUND_POWER_OF_TWO(dist, (xd->bd - 8) * 2);
rd_stats->dist = rd_stats->sse = (dist << 4);
@@ -512,7 +515,7 @@
const MB_MODE_INFO *const mbmi = xd->mi[0];
tx_rd_info->hash_value = hash;
tx_rd_info->tx_size = mbmi->tx_size;
- memcpy(tx_rd_info->blk_skip, x->blk_skip,
+ memcpy(tx_rd_info->blk_skip, x->txfm_search_info.blk_skip,
sizeof(tx_rd_info->blk_skip[0]) * n4);
av1_copy(tx_rd_info->inter_tx_size, mbmi->inter_tx_size);
av1_copy_array(tx_rd_info->tx_type_map, xd->tx_type_map, n4);
@@ -1248,7 +1251,7 @@
}
hash_data = (uint8_t *)tmp_data;
}
- CRC32C *crc = &x->mb_rd_record.crc_calculator;
+ CRC32C *crc = &x->txfm_search_info.mb_rd_record.crc_calculator;
const uint32_t hash = av1_get_crc32c_value(crc, hash_data, 2 * txb_w * txb_h);
return (hash << 5) + tx_size;
}
@@ -1265,17 +1268,19 @@
const int tx_type_map_idx,
uint16_t *cur_joint_ctx) {
MACROBLOCKD *xd = &x->e_mbd;
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
assert(cpi->sf.tx_sf.use_intra_txb_hash &&
frame_is_intra_only(&cpi->common) && !is_inter_block(xd->mi[0]) &&
plane == 0 && tx_size_wide[tx_size] == tx_size_high[tx_size]);
const uint32_t intra_hash =
get_intra_txb_hash(x, plane, blk_row, blk_col, plane_bsize, tx_size);
const int intra_hash_idx =
- find_tx_size_rd_info(&x->txb_rd_record_intra, intra_hash);
- *intra_txb_rd_info = &x->txb_rd_record_intra.tx_rd_info[intra_hash_idx];
+ find_tx_size_rd_info(&txfm_info->txb_rd_record_intra, intra_hash);
+ *intra_txb_rd_info =
+ &txfm_info->txb_rd_record_intra.tx_rd_info[intra_hash_idx];
*cur_joint_ctx = (txb_ctx->dc_sign_ctx << 8) + txb_ctx->txb_skip_ctx;
if ((*intra_txb_rd_info)->entropy_context == *cur_joint_ctx &&
- x->txb_rd_record_intra.tx_rd_info[intra_hash_idx].valid) {
+ txfm_info->txb_rd_record_intra.tx_rd_info[intra_hash_idx].valid) {
xd->tx_type_map[tx_type_map_idx] = (*intra_txb_rd_info)->tx_type;
const TX_TYPE ref_tx_type =
av1_get_tx_type(xd, get_plane_type(plane), blk_row, blk_col, tx_size,
@@ -2509,7 +2514,8 @@
update_txk_array(xd, blk_row, blk_col, tx_size, DCT_DCT);
}
rd_stats->skip_txfm = pick_skip_txfm;
- set_blk_skip(x, 0, blk_row * bw + blk_col, pick_skip_txfm);
+ set_blk_skip(x->txfm_search_info.blk_skip, 0, blk_row * bw + blk_col,
+ pick_skip_txfm);
if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
rd_stats->rate += x->txfm_partition_cost[txfm_partition_ctx][0];
@@ -2663,7 +2669,8 @@
mbmi->tx_size = tx_size;
update_txk_array(xd, blk_row, blk_col, tx_size, no_split.tx_type);
const int bw = mi_size_wide[plane_bsize];
- set_blk_skip(x, 0, blk_row * bw + blk_col, rd_stats->skip_txfm);
+ set_blk_skip(x->txfm_search_info.blk_skip, 0, blk_row * bw + blk_col,
+ rd_stats->skip_txfm);
} else {
*rd_stats = split_rd_stats;
if (split_rd_stats.rdcost == INT64_MAX) *is_cost_valid = 0;
@@ -2774,6 +2781,7 @@
const int num_blks = bsize_to_num_blk(bs);
x->rd_model = FULL_TXFM_RD;
int64_t rd[MAX_TX_DEPTH + 1] = { INT64_MAX, INT64_MAX, INT64_MAX };
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
for (int tx_size = start_tx, depth = init_depth; depth <= MAX_TX_DEPTH;
depth++, tx_size = sub_tx_size_map[tx_size]) {
if (!cpi->oxcf.enable_tx64 && txsize_sqr_up_map[tx_size] == TX_64X64) {
@@ -2784,7 +2792,7 @@
rd[depth] = av1_uniform_txfm_yrd(cpi, x, &this_rd_stats, ref_best_rd, bs,
tx_size, FTXS_NONE, skip_trellis);
if (rd[depth] < best_rd) {
- av1_copy_array(best_blk_skip, x->blk_skip, num_blks);
+ av1_copy_array(best_blk_skip, txfm_info->blk_skip, num_blks);
av1_copy_array(best_txk_type_map, xd->tx_type_map, num_blks);
best_tx_size = tx_size;
best_rd = rd[depth];
@@ -2802,7 +2810,7 @@
if (rd_stats->rate != INT_MAX) {
mbmi->tx_size = best_tx_size;
av1_copy_array(xd->tx_type_map, best_txk_type_map, num_blks);
- av1_copy_array(x->blk_skip, best_blk_skip, num_blks);
+ av1_copy_array(txfm_info->blk_skip, best_blk_skip, num_blks);
}
}
@@ -2852,10 +2860,13 @@
const int blk_idx =
blk_row * (block_size_wide[plane_bsize] >> MI_SIZE_LOG2) + blk_col;
+
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
if (plane == 0)
- set_blk_skip(x, plane, blk_idx, x->plane[plane].eobs[block] == 0);
+ set_blk_skip(txfm_info->blk_skip, plane, blk_idx,
+ x->plane[plane].eobs[block] == 0);
else
- set_blk_skip(x, plane, blk_idx, 0);
+ set_blk_skip(txfm_info->blk_skip, plane, blk_idx, 0);
int64_t rd;
if (is_inter) {
@@ -2976,19 +2987,20 @@
tx_type_rd(cpi, x, tx_size, blk_row, blk_col, block, plane_bsize, &txb_ctx,
rd_stats, ftxs_mode, ref_best_rd, NULL);
const int mi_width = mi_size_wide[plane_bsize];
+ TxfmSearchInfo *txfm_info = &x->txfm_search_info;
if (RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist) >=
RDCOST(x->rdmult, zero_blk_rate, rd_stats->sse) ||
rd_stats->skip_txfm == 1) {
rd_stats->rate = zero_blk_rate;
rd_stats->dist = rd_stats->sse;
rd_stats->skip_txfm = 1;
- set_blk_skip(x, 0, blk_row * mi_width + blk_col, 1);
+ set_blk_skip(txfm_info->blk_skip, 0, blk_row * mi_width + blk_col, 1);
x->plane[0].eobs[block] = 0;
x->plane[0].txb_entropy_ctx[block] = 0;
update_txk_array(xd, blk_row, blk_col, tx_size, DCT_DCT);
} else {
rd_stats->skip_txfm = 0;
- set_blk_skip(x, 0, blk_row * mi_width + blk_col, 0);
+ set_blk_skip(txfm_info->blk_skip, 0, blk_row * mi_width + blk_col, 0);
}
if (tx_size > TX_4X4 && depth < MAX_VARTX_DEPTH)
rd_stats->rate += x->txfm_partition_cost[ctx][0];
@@ -3259,7 +3271,7 @@
const int n4 = bsize_to_num_blk(bsize);
if (is_mb_rd_hash_enabled) {
hash = get_block_residue_hash(x, bsize);
- mb_rd_record = &x->mb_rd_record;
+ mb_rd_record = &x->txfm_search_info.mb_rd_record;
const int match_index = find_mb_rd_info(mb_rd_record, ref_best_rd, hash);
if (match_index != -1) {
MB_RD_INFO *tx_rd_info = &mb_rd_record->tx_rd_info[match_index];
@@ -3281,7 +3293,7 @@
return;
}
#if CONFIG_SPEED_STATS
- ++x->tx_search_count;
+ ++x->txfm_search_info.tx_search_count;
#endif // CONFIG_SPEED_STATS
// Pre-compute residue hashes (transform block level) and find existing or
@@ -3346,7 +3358,7 @@
(mi_col + mi_size_wide[bs] < xd->tile.mi_col_end);
if (within_border) {
hash = get_block_residue_hash(x, bs);
- mb_rd_record = &x->mb_rd_record;
+ mb_rd_record = &x->txfm_search_info.mb_rd_record;
const int match_index = find_mb_rd_info(mb_rd_record, ref_best_rd, hash);
if (match_index != -1) {
MB_RD_INFO *tx_rd_info = &mb_rd_record->tx_rd_info[match_index];
@@ -3543,7 +3555,7 @@
av1_pick_uniform_tx_size_type_yrd(cpi, x, rd_stats_y, bsize, rd_thresh);
memset(mbmi->inter_tx_size, mbmi->tx_size, sizeof(mbmi->inter_tx_size));
for (int i = 0; i < xd->height * xd->width; ++i)
- set_blk_skip(x, 0, i, rd_stats_y->skip_txfm);
+ set_blk_skip(x->txfm_search_info.blk_skip, 0, i, rd_stats_y->skip_txfm);
}
if (rd_stats_y->rate == INT_MAX) return 0;