Use per-channel array for blk_skip to avoid uninitialized values
The old `blk_skip` array was used as a bit-field, combining blk_skip values of 3 planes into one value. However, for sub-8x8 blocks, where a chroma block can cover multiple luma blocks, the `blk_skip` values for chroma planes were uninitialized / garbage during RDO in some cases, because saving/restoring logic was only using the luma block size.
Also, added back an assertion which checked for uninitialized values -- it was removed during adoption of SDP.
The issue was observed in lossless mode only for now (see #160 ), where all transform sizes are forced to be 4x4.
No change in stats for lossy encoding in release build.
Fixes #160
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index d8f0cec..ef01c11 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -755,11 +755,10 @@
/*! \brief Whether to skip transform and quantization on a txfm block level.
*
* 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.
+ * current partition block. For each plane, when we are skipping transform and
+ * quantization, the last bit will be set to 1.
*/
- uint8_t blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
+ uint8_t blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE];
/*! \brief Transform types inside the partition block
*
@@ -1929,31 +1928,26 @@
!xd->lossless[mbmi->segment_id];
}
-static INLINE void set_blk_skip(uint8_t txb_skip[], int plane, int blk_idx,
- int skip) {
+static INLINE void set_blk_skip(uint8_t txb_skip[], int blk_idx, int skip) {
if (skip)
- txb_skip[blk_idx] |= 1UL << plane;
+ txb_skip[blk_idx] |= 1UL;
else
- txb_skip[blk_idx] &= ~(1UL << plane);
+ txb_skip[blk_idx] &= ~(1UL);
#ifndef NDEBUG
- // Set chroma planes to uninitialized states when luma is set to check if
- // it will be set later
- if (plane == 0) {
- txb_skip[blk_idx] |= 1UL << (1 + 4);
- txb_skip[blk_idx] |= 1UL << (2 + 4);
- }
-
- // Clear the initialization checking bit
- txb_skip[blk_idx] &= ~(1UL << (plane + 4));
+ // Mark this block as initialized (0).
+ txb_skip[blk_idx] &= ~(1UL << 4);
#endif
}
-static INLINE int is_blk_skip(uint8_t *txb_skip, int plane, int blk_idx) {
+static INLINE int is_blk_skip(uint8_t *txb_skip, int blk_idx) {
#ifndef NDEBUG
- // The magic number is 0x77, this is to test if there is garbage data
- assert((txb_skip[blk_idx] & 0x88) == 0);
+ // Ensure that this block is initialized.
+ assert((txb_skip[blk_idx] & (1U << 4)) == 0);
+ // These were initialized to fixed pattern 0x11 in `av1_rd_pick_partition`.
+ // Ensure other bits are 0 to make sure there is no garbage data.
+ assert((txb_skip[blk_idx] & 0xEE) == 0);
#endif
- return (txb_skip[blk_idx] >> plane) & 1;
+ return txb_skip[blk_idx] & 1;
}
#if CONFIG_EXT_RECUR_PARTITIONS
diff --git a/av1/encoder/context_tree.c b/av1/encoder/context_tree.c
index 75f0307..e6ed6ae 100644
--- a/av1/encoder/context_tree.c
+++ b/av1/encoder/context_tree.c
@@ -24,7 +24,7 @@
};
void av1_copy_tree_context(PICK_MODE_CONTEXT *dst_ctx,
- PICK_MODE_CONTEXT *src_ctx) {
+ PICK_MODE_CONTEXT *src_ctx, int num_planes) {
dst_ctx->mic = src_ctx->mic;
#if CONFIG_C071_SUBBLK_WARPMV
if (is_warp_mode(src_ctx->mic.motion_mode)) {
@@ -37,8 +37,12 @@
dst_ctx->num_4x4_blk_chroma = src_ctx->num_4x4_blk_chroma;
dst_ctx->skippable = src_ctx->skippable;
- memcpy(dst_ctx->blk_skip, src_ctx->blk_skip,
- sizeof(uint8_t) * src_ctx->num_4x4_blk);
+ for (int i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (i == 0) ? src_ctx->num_4x4_blk : src_ctx->num_4x4_blk_chroma;
+ memcpy(dst_ctx->blk_skip[i], src_ctx->blk_skip[i],
+ sizeof(*src_ctx->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(dst_ctx->tx_type_map, src_ctx->tx_type_map,
src_ctx->num_4x4_blk);
av1_copy_array(dst_ctx->cctx_type_map, src_ctx->cctx_type_map,
@@ -131,8 +135,6 @@
ctx->num_4x4_blk = num_blk;
ctx->num_4x4_blk_chroma = num_pix_chroma / 16;
- AOM_CHECK_MEM_ERROR(&error, ctx->blk_skip,
- aom_calloc(num_blk, sizeof(*ctx->blk_skip)));
AOM_CHECK_MEM_ERROR(&error, ctx->tx_type_map,
aom_calloc(num_blk, sizeof(*ctx->tx_type_map)));
#if CONFIG_C071_SUBBLK_WARPMV
@@ -154,6 +156,8 @@
#else
const int num_blk_plane = ctx->num_4x4_blk;
#endif // CONFIG_FLEX_PARTITION
+ AOM_CHECK_MEM_ERROR(&error, ctx->blk_skip[i],
+ aom_calloc(num_blk_plane, sizeof(*ctx->blk_skip[i])));
AOM_CHECK_MEM_ERROR(
&error, ctx->eobs[i],
aom_memalign(32, num_blk_plane * sizeof(*ctx->eobs[i])));
@@ -185,8 +189,10 @@
free(ctx->submic);
}
#endif // CONFIG_C071_SUBBLK_WARPMV
- aom_free(ctx->blk_skip);
- ctx->blk_skip = NULL;
+ for (int i = 0; i < MAX_MB_PLANE; ++i) {
+ aom_free(ctx->blk_skip[i]);
+ ctx->blk_skip[i] = NULL;
+ }
aom_free(ctx->tx_type_map);
aom_free(ctx->cctx_type_map);
for (int i = 0; i < num_planes; ++i) {
@@ -596,7 +602,7 @@
dst->none_chroma =
av1_alloc_pmc(cm, tree_type, mi_row, mi_col, bsize, dst,
PARTITION_NONE, 0, ss_x, ss_y, shared_bufs);
- av1_copy_tree_context(dst->none_chroma, src->none_chroma);
+ av1_copy_tree_context(dst->none_chroma, src->none_chroma, num_planes);
}
}
#endif // CONFIG_EXTENDED_SDP
@@ -613,7 +619,7 @@
av1_alloc_pmc(cm, tree_type, mi_row, mi_col, bsize, dst,
PARTITION_NONE, 0, ss_x, ss_y, shared_bufs);
av1_copy_tree_context(dst->none[cur_region_type],
- src->none[cur_region_type]);
+ src->none[cur_region_type], num_planes);
#if CONFIG_MVP_IMPROVEMENT
if (is_inter_block(&src->none[cur_region_type]->mic, xd->tree_type)) {
#if WARP_CU_BANK
@@ -631,7 +637,7 @@
if (src->none) {
dst->none = av1_alloc_pmc(cm, tree_type, mi_row, mi_col, bsize, dst,
PARTITION_NONE, 0, ss_x, ss_y, shared_bufs);
- av1_copy_tree_context(dst->none, src->none);
+ av1_copy_tree_context(dst->none, src->none, num_planes);
#if CONFIG_MVP_IMPROVEMENT
if (is_inter_block(&src->none->mic, xd->tree_type)) {
#if WARP_CU_BANK
diff --git a/av1/encoder/context_tree.h b/av1/encoder/context_tree.h
index 37c8744..9cd1298 100644
--- a/av1/encoder/context_tree.h
+++ b/av1/encoder/context_tree.h
@@ -40,7 +40,7 @@
#endif // CONFIG_C071_SUBBLK_WARPMV
MB_MODE_INFO_EXT_FRAME mbmi_ext_best;
uint8_t *color_index_map[2];
- uint8_t *blk_skip;
+ uint8_t *blk_skip[MAX_MB_PLANE];
tran_low_t *coeff[MAX_MB_PLANE];
tran_low_t *qcoeff[MAX_MB_PLANE];
@@ -180,7 +180,7 @@
PC_TREE_SHARED_BUFFERS *shared_bufs);
void av1_free_pmc(PICK_MODE_CONTEXT *ctx, int num_planes);
void av1_copy_tree_context(PICK_MODE_CONTEXT *dst_ctx,
- PICK_MODE_CONTEXT *src_ctx);
+ PICK_MODE_CONTEXT *src_ctx, int num_planes);
void av1_setup_sms_tree(struct AV1_COMP *const cpi, struct ThreadData *td);
void av1_free_sms_tree(struct ThreadData *td);
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c
index c352e68..ddc725a 100644
--- a/av1/encoder/encodeframe_utils.c
+++ b/av1/encoder/encodeframe_utils.c
@@ -288,8 +288,12 @@
#endif // CONFIG_SEP_COMP_DRL
);
- memcpy(txfm_info->blk_skip, ctx->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
+ for (i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (i == AOM_PLANE_Y) ? ctx->num_4x4_blk : ctx->num_4x4_blk_chroma;
+ memcpy(txfm_info->blk_skip[i], ctx->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
txfm_info->skip_txfm = ctx->rd_stats.skip_txfm;
if (xd->tree_type != CHROMA_PART) {
diff --git a/av1/encoder/encodemb.c b/av1/encoder/encodemb.c
index 1ee70ad..7afde0a 100644
--- a/av1/encoder/encodemb.c
+++ b/av1/encoder/encodemb.c
@@ -757,7 +757,7 @@
CctxType cctx_type =
plane ? av1_get_cctx_type(xd, blk_row, blk_col) : CCTX_NONE;
- if (!is_blk_skip(x->txfm_search_info.blk_skip, plane,
+ if (!is_blk_skip(x->txfm_search_info.blk_skip[plane],
blk_row * bw + blk_col) &&
(plane < AOM_PLANE_V || !is_cctx_allowed(cm, xd) ||
#if CCTX_C2_DROPPED
@@ -1343,7 +1343,7 @@
}
#endif
- if (plane == 0 && is_blk_skip(x->txfm_search_info.blk_skip, plane,
+ if (plane == 0 && is_blk_skip(x->txfm_search_info.blk_skip[plane],
blk_row * bw + blk_col)) {
*eob = 0;
*bob_code = 0;
diff --git a/av1/encoder/intra_mode_search.c b/av1/encoder/intra_mode_search.c
index e8254f7..f93b486 100644
--- a/av1/encoder/intra_mode_search.c
+++ b/av1/encoder/intra_mode_search.c
@@ -101,8 +101,10 @@
#endif // CONFIG_NEW_TX_PARTITION
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->txfm_search_info.blk_skip,
- sizeof(x->txfm_search_info.blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(ctx->blk_skip[AOM_PLANE_Y],
+ x->txfm_search_info.blk_skip[AOM_PLANE_Y],
+ sizeof(*x->txfm_search_info.blk_skip[AOM_PLANE_Y]) *
+ ctx->num_4x4_blk);
*rate = this_rate;
*rate_tokenonly = tokenonly_rd_stats.rate;
*distortion = tokenonly_rd_stats.dist;
@@ -956,7 +958,7 @@
return skippable;
}
- memcpy(x->txfm_search_info.blk_skip, best_blk_skip,
+ memcpy(x->txfm_search_info.blk_skip[AOM_PLANE_Y], 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,
@@ -1078,8 +1080,8 @@
*rate_tokenonly = this_rate_tokenonly;
*distortion = rd_stats.dist;
*skippable = rd_stats.skip_txfm;
- av1_copy_array(ctx->blk_skip, x->txfm_search_info.blk_skip,
- ctx->num_4x4_blk);
+ av1_copy_array(ctx->blk_skip[AOM_PLANE_Y],
+ x->txfm_search_info.blk_skip[AOM_PLANE_Y], ctx->num_4x4_blk);
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
return 1;
}
@@ -1117,7 +1119,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->txfm_search_info.blk_skip,
+ memcpy(best_blk_skip, x->txfm_search_info.blk_skip[AOM_PLANE_Y],
sizeof(best_blk_skip[0]) * ctx->num_4x4_blk);
TX_TYPE best_tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
#if CONFIG_NEW_TX_PARTITION
@@ -1145,7 +1147,7 @@
best_tx_partition = mbmi->tx_partition_type[0];
#endif // CONFIG_NEW_TX_PARTITION
av1_copy_array(best_tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
- memcpy(best_blk_skip, x->txfm_search_info.blk_skip,
+ memcpy(best_blk_skip, x->txfm_search_info.blk_skip[AOM_PLANE_Y],
sizeof(best_blk_skip[0]) * ctx->num_4x4_blk);
best_fi_mode = fi_mode;
*rd_stats_y = rd_stats_y_fi;
@@ -1159,8 +1161,8 @@
mbmi->tx_partition_type[0] = best_tx_partition;
#endif // CONFIG_NEW_TX_PARTITION
av1_copy_array(xd->tx_type_map, best_tx_type_map, 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);
+ memcpy(x->txfm_search_info.blk_skip[AOM_PLANE_Y], best_blk_skip,
+ sizeof(*x->txfm_search_info.blk_skip[AOM_PLANE_Y]) * ctx->num_4x4_blk);
if (filter_intra_selected_flag) {
mbmi->filter_intra_mode_info.use_filter_intra = 1;
@@ -1747,8 +1749,10 @@
best_filt = 0;
best_angle_delta = mbmi->angle_delta[PLANE_TYPE_Y];
av1_copy_array(best_tx_type_map, xd->tx_type_map, 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);
+ memcpy(ctx->blk_skip[AOM_PLANE_Y],
+ x->txfm_search_info.blk_skip[AOM_PLANE_Y],
+ sizeof(*x->txfm_search_info.blk_skip[AOM_PLANE_Y]) *
+ ctx->num_4x4_blk);
*rate = this_rate;
*rate_tokenonly = tokenonly_rd_stats.rate;
*distortion = tokenonly_rd_stats.dist;
@@ -2048,8 +2052,10 @@
*rate_tokenonly = this_rate_tokenonly;
*distortion = this_distortion;
*skippable = s;
- memcpy(ctx->blk_skip, x->txfm_search_info.blk_skip,
- sizeof(x->txfm_search_info.blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(ctx->blk_skip[AOM_PLANE_Y],
+ x->txfm_search_info.blk_skip[AOM_PLANE_Y],
+ sizeof(*x->txfm_search_info.blk_skip[AOM_PLANE_Y]) *
+ ctx->num_4x4_blk);
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
}
}
@@ -2089,7 +2095,7 @@
&best_mbmi, best_palette_color_map, &best_rd,
&best_model_rd, rate, rate_tokenonly,
distortion, skippable, &beat_best_rd, ctx,
- ctx->blk_skip, ctx->tx_type_map);
+ ctx->blk_skip[AOM_PLANE_Y], ctx->tx_type_map);
}
// Searches filter_intra
diff --git a/av1/encoder/palette.c b/av1/encoder/palette.c
index 342ac55..421078e 100644
--- a/av1/encoder/palette.c
+++ b/av1/encoder/palette.c
@@ -297,8 +297,9 @@
memcpy(best_palette_color_map, color_map,
block_width * block_height * sizeof(color_map[0]));
*best_mbmi = *mbmi;
- memcpy(blk_skip, x->txfm_search_info.blk_skip,
- sizeof(x->txfm_search_info.blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(
+ blk_skip, x->txfm_search_info.blk_skip[AOM_PLANE_Y],
+ sizeof(*x->txfm_search_info.blk_skip[AOM_PLANE_Y]) * 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;
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c
index fc1851d..0af18db 100644
--- a/av1/encoder/partition_search.c
+++ b/av1/encoder/partition_search.c
@@ -5198,12 +5198,14 @@
// Copy of mode search results if the ctx is ready.
if (is_ctx_ready[ab_part_type][0]) {
av1_copy_tree_context(cur_part_ctxs[ab_part_type][0],
- mode_srch_ctx[ab_part_type][0][0]);
+ mode_srch_ctx[ab_part_type][0][0],
+ av1_num_planes(cm));
cur_part_ctxs[ab_part_type][0]->mic.partition = part_type;
cur_part_ctxs[ab_part_type][0]->rd_mode_is_ready = 1;
if (is_ctx_ready[ab_part_type][1]) {
av1_copy_tree_context(cur_part_ctxs[ab_part_type][1],
- mode_srch_ctx[ab_part_type][1][0]);
+ mode_srch_ctx[ab_part_type][1][0],
+ av1_num_planes(cm));
cur_part_ctxs[ab_part_type][1]->mic.partition = part_type;
cur_part_ctxs[ab_part_type][1]->rd_mode_is_ready = 1;
}
@@ -8738,12 +8740,15 @@
#ifndef NDEBUG
// Nothing should rely on the default value of this array (which is just
- // leftover from encoding the previous block. Setting it to fixed pattern
+ // leftover from encoding the previous block). Setting it to fixed pattern
// when debugging.
- // bit 0, 1, 2 are blk_skip of each plane
- // bit 4, 5, 6 are initialization checking of each plane
- memset(x->txfm_search_info.blk_skip, 0x77,
- sizeof(x->txfm_search_info.blk_skip));
+ // bit 0 is blk_skip of each plane.
+ // bit 4 is initialization checking bit (1 = uninitialized).
+ // See related logic in `set_blk_skip` and `is_blk_skip`.
+ for (int i = (xd->tree_type == CHROMA_PART); i < num_planes; ++i) {
+ memset(x->txfm_search_info.blk_skip[i], 0x11,
+ sizeof(x->txfm_search_info.blk_skip[i]));
+ }
#endif // NDEBUG
assert(bsize < BLOCK_SIZES_ALL);
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index d96450b..e5d4d3e 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -2082,7 +2082,7 @@
const int rate2_nocoeff = rd_stats->rate;
int best_xskip_txfm = 0;
RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
- uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
+ uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE];
TX_TYPE best_tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
CctxType best_cctx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
const int rate_mv0 =
@@ -3218,8 +3218,13 @@
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, txfm_info->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
+ for (int i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (xd->plane[i].height * xd->plane[i].width) >>
+ (2 * MI_SIZE_LOG2);
+ memcpy(best_blk_skip[i], txfm_info->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(best_tx_type_map, xd->tx_type_map,
xd->height * xd->width);
av1_copy_array(
@@ -3248,8 +3253,12 @@
*rd_stats = best_rd_stats;
*rd_stats_y = best_rd_stats_y;
if (num_planes > 1) *rd_stats_uv = best_rd_stats_uv;
- memcpy(txfm_info->blk_skip, best_blk_skip,
- sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
+ for (int i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (xd->plane[i].height * xd->plane[i].width) >> (2 * MI_SIZE_LOG2);
+ memcpy(txfm_info->blk_skip[i], best_blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(xd->tx_type_map, best_tx_type_map, xd->height * xd->width);
av1_copy_array(
xd->cctx_type_map, best_cctx_type_map,
@@ -5035,7 +5044,7 @@
int64_t ret_val = INT64_MAX;
RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
int64_t best_rd = INT64_MAX;
- uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
+ uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE];
TX_TYPE best_tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
CctxType best_cctx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
MB_MODE_INFO best_mbmi = *mbmi;
@@ -6295,8 +6304,13 @@
}
#endif // CONFIG_C071_SUBBLK_WARPMV
best_xskip_txfm = txfm_info->skip_txfm;
- memcpy(best_blk_skip, txfm_info->blk_skip,
- sizeof(best_blk_skip[0]) * xd->height * xd->width);
+ for (i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (xd->plane[i].height * xd->plane[i].width) >>
+ (2 * MI_SIZE_LOG2);
+ memcpy(best_blk_skip[i], txfm_info->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(best_tx_type_map, xd->tx_type_map,
xd->height * xd->width);
av1_copy_array(
@@ -6368,8 +6382,12 @@
txfm_info->skip_txfm = best_xskip_txfm;
assert(IMPLIES(mbmi->comp_group_idx == 1,
mbmi->interinter_comp.type != COMPOUND_AVERAGE));
- memcpy(txfm_info->blk_skip, best_blk_skip,
- sizeof(best_blk_skip[0]) * xd->height * xd->width);
+ for (i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (xd->plane[i].height * xd->plane[i].width) >> (2 * MI_SIZE_LOG2);
+ memcpy(txfm_info->blk_skip[i], best_blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(xd->tx_type_map, best_tx_type_map, xd->height * xd->width);
av1_copy_array(
xd->cctx_type_map, best_cctx_type_map,
@@ -6693,7 +6711,7 @@
#endif // CONFIG_MORPH_PRED
MB_MODE_INFO best_mbmi = *mbmi;
RD_STATS best_rdstats = *rd_stats;
- uint8_t best_blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE] = { 0 };
+ uint8_t best_blk_skip[MAX_MB_PLANE][MAX_MIB_SIZE * MAX_MIB_SIZE] = { 0 };
TX_TYPE 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);
CctxType best_cctx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
@@ -7070,8 +7088,12 @@
best_rd = rd_stats_yuv.rdcost;
best_mbmi = *mbmi;
best_rdstats = rd_stats_yuv;
- memcpy(best_blk_skip, txfm_info->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
+ for (int i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (xd->plane[i].height * xd->plane[i].width) >> (2 * MI_SIZE_LOG2);
+ memcpy(best_blk_skip[i], txfm_info->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(best_tx_type_map, xd->tx_type_map,
xd->height * xd->width);
av1_copy_array(best_cctx_type_map, xd->cctx_type_map,
@@ -7089,8 +7111,12 @@
best_rd = rd_stats_yuv.rdcost;
best_mbmi = *mbmi;
best_rdstats = rd_stats_yuv;
- memcpy(best_blk_skip, txfm_info->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
+ for (int i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (xd->plane[i].height * xd->plane[i].width) >> (2 * MI_SIZE_LOG2);
+ memcpy(best_blk_skip[i], txfm_info->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(best_tx_type_map, xd->tx_type_map, xd->height * xd->width);
av1_copy_array(
best_cctx_type_map, xd->cctx_type_map,
@@ -7108,8 +7134,12 @@
#endif // CONFIG_IBC_BV_IMPROVEMENT
*rd_stats = best_rdstats;
- memcpy(txfm_info->blk_skip, best_blk_skip,
- sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
+ for (int i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (xd->plane[i].height * xd->plane[i].width) >> (2 * MI_SIZE_LOG2);
+ memcpy(txfm_info->blk_skip[i], best_blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(xd->tx_type_map, best_tx_type_map, ctx->num_4x4_blk);
av1_copy_array(xd->cctx_type_map, best_cctx_type_map,
ctx->num_4x4_blk_chroma);
@@ -7161,8 +7191,8 @@
// Set up the tx variables for reproducing the y predictions in case we
// need it for chroma-from-luma.
if (xd->is_chroma_ref && store_cfl_required_rdo(cm, x)) {
- memcpy(txfm_info->blk_skip, ctx->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
+ memcpy(txfm_info->blk_skip[AOM_PLANE_Y], ctx->blk_skip[AOM_PLANE_Y],
+ sizeof(*txfm_info->blk_skip[AOM_PLANE_Y]) * ctx->num_4x4_blk);
av1_copy_array(xd->tx_type_map, ctx->tx_type_map, ctx->num_4x4_blk);
}
const TX_SIZE max_uv_tx_size = av1_get_tx_size(AOM_PLANE_U, xd);
@@ -7191,8 +7221,12 @@
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[xd->tree_type == CHROMA_PART];
- memcpy(ctx->blk_skip, txfm_info->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
+ for (int i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (i == AOM_PLANE_Y) ? ctx->num_4x4_blk : ctx->num_4x4_blk_chroma;
+ memcpy(ctx->blk_skip[i], txfm_info->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
assert(rd_cost->rate != INT_MAX);
}
if (rd_cost->rate == INT_MAX) return;
@@ -7648,8 +7682,12 @@
restore_dst_buf(xd, orig_dst, num_planes);
} else {
x->txfm_search_info.skip_txfm = 0;
- memcpy(ctx->blk_skip, txfm_info->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
+ for (int i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (i == AOM_PLANE_Y) ? ctx->num_4x4_blk : ctx->num_4x4_blk_chroma;
+ memcpy(ctx->blk_skip[i], txfm_info->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
av1_copy_array(ctx->cctx_type_map, xd->cctx_type_map,
ctx->num_4x4_blk_chroma);
@@ -8003,7 +8041,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(txfm_info->blk_skip, 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,
@@ -8048,7 +8086,12 @@
RDCOST(x->rdmult, this_rate, (rd_stats_y.dist + rd_stats_uv.dist));
if (best_rd > this_rd) {
*best_mbmode = *mbmi;
- av1_copy_array(ctx->blk_skip, txfm_info->blk_skip, ctx->num_4x4_blk);
+ for (int i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (i == AOM_PLANE_Y) ? ctx->num_4x4_blk : ctx->num_4x4_blk_chroma;
+ av1_copy_array(ctx->blk_skip[i], txfm_info->blk_skip[i],
+ num_blk_plane);
+ }
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
av1_copy_array(ctx->cctx_type_map, xd->cctx_type_map,
ctx->num_4x4_blk_chroma);
@@ -9287,8 +9330,12 @@
#endif // CONFIG_SKIP_TXFM_OPT
search_state->best_rate_uv = new_best_rd_stats_uv->rate;
}
- memcpy(ctx->blk_skip, txfm_info->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
+ for (int i = 0; i < av1_num_planes(cm); ++i) {
+ const int num_blk_plane =
+ (i == AOM_PLANE_Y) ? ctx->num_4x4_blk : ctx->num_4x4_blk_chroma;
+ memcpy(ctx->blk_skip[i], txfm_info->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
av1_copy_array(ctx->cctx_type_map, xd->cctx_type_map,
ctx->num_4x4_blk_chroma);
@@ -10561,8 +10608,12 @@
search_state.best_mbmode = *mbmi;
search_state.best_skip2 = 0;
search_state.best_mode_skippable = this_skippable;
- memcpy(ctx->blk_skip, txfm_info->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
+ for (i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (i == AOM_PLANE_Y) ? ctx->num_4x4_blk : ctx->num_4x4_blk_chroma;
+ memcpy(ctx->blk_skip[i], txfm_info->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
av1_copy_array(ctx->cctx_type_map, xd->cctx_type_map,
ctx->num_4x4_blk_chroma);
@@ -10617,8 +10668,13 @@
search_state.best_skip2 = mbmi->skip_txfm[xd->tree_type == CHROMA_PART];
search_state.best_mode_skippable =
mbmi->skip_txfm[xd->tree_type == CHROMA_PART];
- memcpy(ctx->blk_skip, txfm_info->blk_skip,
- sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
+
+ for (i = 0; i < num_planes; ++i) {
+ const int num_blk_plane =
+ (i == AOM_PLANE_Y) ? ctx->num_4x4_blk : ctx->num_4x4_blk_chroma;
+ memcpy(ctx->blk_skip[i], txfm_info->blk_skip[i],
+ sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
+ }
av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
av1_copy_array(ctx->cctx_type_map, xd->cctx_type_map,
ctx->num_4x4_blk_chroma);
diff --git a/av1/encoder/tx_search.c b/av1/encoder/tx_search.c
index b6705dc..df37302 100644
--- a/av1/encoder/tx_search.c
+++ b/av1/encoder/tx_search.c
@@ -410,8 +410,8 @@
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = xd->mi[0];
mbmi->tx_size = tx_rd_info->tx_size;
- memcpy(x->txfm_search_info.blk_skip, tx_rd_info->blk_skip,
- sizeof(tx_rd_info->blk_skip[0]) * n4);
+ memcpy(x->txfm_search_info.blk_skip[AOM_PLANE_Y], tx_rd_info->blk_skip,
+ sizeof(*tx_rd_info->blk_skip) * n4);
av1_copy(mbmi->inter_tx_size, tx_rd_info->inter_tx_size);
#if CONFIG_NEW_TX_PARTITION
av1_copy(mbmi->tx_partition_type, tx_rd_info->tx_partition_type);
@@ -571,7 +571,7 @@
#endif // CONFIG_NEW_TX_PARTITION
mbmi->tx_size = tx_size;
for (int i = 0; i < n4; ++i)
- set_blk_skip(x->txfm_search_info.blk_skip, 0, i, 1);
+ set_blk_skip(x->txfm_search_info.blk_skip[0], i, 1);
rd_stats->skip_txfm = 1;
dist = ROUND_POWER_OF_TWO(dist, (xd->bd - 8) * 2);
rd_stats->dist = rd_stats->sse = (dist << 4);
@@ -630,8 +630,8 @@
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->txfm_search_info.blk_skip,
- sizeof(tx_rd_info->blk_skip[0]) * n4);
+ memcpy(tx_rd_info->blk_skip, x->txfm_search_info.blk_skip[AOM_PLANE_Y],
+ sizeof(*tx_rd_info->blk_skip) * n4);
av1_copy(tx_rd_info->inter_tx_size, mbmi->inter_tx_size);
#if CONFIG_NEW_TX_PARTITION
av1_copy(tx_rd_info->tx_partition_type, mbmi->tx_partition_type);
@@ -3436,7 +3436,7 @@
update_txk_array(xd, blk_row, blk_col, tx_size, DCT_DCT);
}
rd_stats->skip_txfm = pick_skip_txfm;
- set_blk_skip(x->txfm_search_info.blk_skip, 0, blk_row * bw + blk_col,
+ set_blk_skip(x->txfm_search_info.blk_skip[0], blk_row * bw + blk_col,
pick_skip_txfm);
#if !CONFIG_NEW_TX_PARTITION
@@ -3817,7 +3817,7 @@
mbmi->inter_tx_size[index] = tx_size_selected;
update_txk_array(xd, offsetr, offsetc, sub_tx,
best_partition_tx_types[txb_idx]);
- set_blk_skip(x->txfm_search_info.blk_skip, 0, offsetr * bw + offsetc,
+ set_blk_skip(x->txfm_search_info.blk_skip[0], offsetr * bw + offsetc,
full_blk_skip[txb_idx]);
block += sub_step;
}
@@ -3850,7 +3850,7 @@
mbmi->tx_size = tx_size_selected;
update_txk_array(xd, offsetr, offsetc, sub_tx,
best_partition_tx_types[cur_partition]);
- set_blk_skip(x->txfm_search_info.blk_skip, 0, offsetr * bw + offsetc,
+ set_blk_skip(x->txfm_search_info.blk_skip[0], offsetr * bw + offsetc,
full_blk_skip[cur_partition]);
block += sub_step;
cur_partition++;
@@ -3949,7 +3949,7 @@
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->txfm_search_info.blk_skip, 0, blk_row * bw + blk_col,
+ 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;
@@ -4120,7 +4120,7 @@
cur_tx_size, FTXS_NONE, 0);
if (cur_rd < best_rd) {
- av1_copy_array(best_blk_skip, txfm_info->blk_skip, num_blks);
+ av1_copy_array(best_blk_skip, txfm_info->blk_skip[AOM_PLANE_Y], num_blks);
av1_copy_array(best_txk_type_map, xd->tx_type_map, num_blks);
best_tx_size = cur_tx_size;
#if CONFIG_WAIP
@@ -4167,7 +4167,7 @@
mbmi->tx_partition_type[0] = best_tx_partition_type;
#endif // CONFIG_TX_PARTITION_TYPE_EXT
av1_copy_array(xd->tx_type_map, best_txk_type_map, num_blks);
- av1_copy_array(txfm_info->blk_skip, best_blk_skip, num_blks);
+ av1_copy_array(txfm_info->blk_skip[AOM_PLANE_Y], best_blk_skip, num_blks);
}
}
#else
@@ -4327,10 +4327,10 @@
TxfmSearchInfo *txfm_info = &x->txfm_search_info;
if (plane == 0)
- set_blk_skip(txfm_info->blk_skip, plane, blk_idx,
+ set_blk_skip(txfm_info->blk_skip[plane], blk_idx,
x->plane[plane].eobs[block] == 0);
else
- set_blk_skip(txfm_info->blk_skip, plane, blk_idx, 0);
+ set_blk_skip(txfm_info->blk_skip[plane], blk_idx, 0);
int64_t rd;
if (is_inter) {
@@ -4488,13 +4488,13 @@
rd_stats->rate = zero_blk_rate;
rd_stats->dist = rd_stats->sse;
rd_stats->skip_txfm = 1;
- set_blk_skip(txfm_info->blk_skip, 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(txfm_info->blk_skip, 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->mode_costs.txfm_partition_cost[ctx][0];
@@ -4673,7 +4673,7 @@
const int blk_idx =
blk_row * (block_size_wide[plane_bsize] >> MI_SIZE_LOG2) + blk_col;
TxfmSearchInfo *txfm_info = &x->txfm_search_info;
- set_blk_skip(txfm_info->blk_skip, plane, blk_idx, 0);
+ set_blk_skip(txfm_info->blk_skip[plane], blk_idx, 0);
int64_t rd;
if (is_inter) {
@@ -5296,7 +5296,7 @@
sizeof(mbmi->tx_partition_type));
#endif // CONFIG_NEW_TX_PARTITION
for (int i = 0; i < xd->height * xd->width; ++i)
- set_blk_skip(x->txfm_search_info.blk_skip, 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;