[mtt] remove depth from cbf

This commit is contained in:
Joose Sainio 2022-09-14 11:47:26 +03:00 committed by Marko Viitanen
parent e3dbeda7f7
commit 9a29d9ded3
10 changed files with 98 additions and 99 deletions

View file

@ -132,6 +132,8 @@ typedef struct
uint16_t cbf; uint16_t cbf;
uint8_t root_cbf;
uint32_t split_tree : 3 * 9; uint32_t split_tree : 3 * 9;
/** /**
@ -536,34 +538,31 @@ static INLINE unsigned xy_to_zorder(unsigned width, unsigned x, unsigned y)
} while(0) } while(0)
#define NUM_CBF_DEPTHS 5
static const uint16_t cbf_masks[NUM_CBF_DEPTHS] = { 0x1f, 0x0f, 0x07, 0x03, 0x1 };
/** /**
* Check if CBF in a given level >= depth is true. * Check if CBF in a given level >= depth is true.
*/ */
static INLINE int cbf_is_set(uint16_t cbf, int depth, color_t plane) static INLINE int cbf_is_set(uint16_t cbf, color_t plane)
{ {
return (cbf & (cbf_masks[depth] << (NUM_CBF_DEPTHS * plane))) != 0; return (cbf & (1 << (plane))) != 0;
} }
/** /**
* Check if CBF in a given level >= depth is true. * Check if CBF in a given level >= depth is true.
*/ */
static INLINE int cbf_is_set_any(uint16_t cbf, int depth) static INLINE int cbf_is_set_any(uint16_t cbf)
{ {
return cbf_is_set(cbf, depth, COLOR_Y) || return cbf_is_set(cbf, COLOR_Y) ||
cbf_is_set(cbf, depth, COLOR_U) || cbf_is_set(cbf, COLOR_U) ||
cbf_is_set(cbf, depth, COLOR_V); cbf_is_set(cbf, COLOR_V);
} }
/** /**
* Set CBF in a level to true. * Set CBF in a level to true.
*/ */
static INLINE void cbf_set(uint16_t *cbf, int depth, color_t plane) static INLINE void cbf_set(uint16_t *cbf, color_t plane)
{ {
// Return value of the bit corresponding to the level. // Return value of the bit corresponding to the level.
*cbf |= (0x10 >> depth) << (NUM_CBF_DEPTHS * plane); *cbf |= (1) << (plane);
} }
/** /**
@ -572,20 +571,20 @@ static INLINE void cbf_set(uint16_t *cbf, int depth, color_t plane)
*/ */
static INLINE void cbf_set_conditionally(uint16_t *cbf, uint16_t child_cbfs[3], int depth, color_t plane) static INLINE void cbf_set_conditionally(uint16_t *cbf, uint16_t child_cbfs[3], int depth, color_t plane)
{ {
bool child_cbf_set = cbf_is_set(child_cbfs[0], depth + 1, plane) || bool child_cbf_set = cbf_is_set(child_cbfs[0], plane) ||
cbf_is_set(child_cbfs[1], depth + 1, plane) || cbf_is_set(child_cbfs[1], plane) ||
cbf_is_set(child_cbfs[2], depth + 1, plane); cbf_is_set(child_cbfs[2], plane);
if (child_cbf_set) { if (child_cbf_set) {
cbf_set(cbf, depth, plane); cbf_set(cbf, plane);
} }
} }
/** /**
* Set CBF in a levels <= depth to false. * Set CBF in a levels <= depth to false.
*/ */
static INLINE void cbf_clear(uint16_t *cbf, int depth, color_t plane) static INLINE void cbf_clear(uint16_t *cbf, color_t plane)
{ {
*cbf &= ~(cbf_masks[depth] << (NUM_CBF_DEPTHS * plane)); *cbf &= ~(1 << (plane));
} }
/** /**
@ -593,8 +592,8 @@ static INLINE void cbf_clear(uint16_t *cbf, int depth, color_t plane)
*/ */
static INLINE void cbf_copy(uint16_t *cbf, uint16_t src, color_t plane) static INLINE void cbf_copy(uint16_t *cbf, uint16_t src, color_t plane)
{ {
cbf_clear(cbf, 0, plane); cbf_clear(cbf, plane);
*cbf |= src & (cbf_masks[0] << (NUM_CBF_DEPTHS * plane)); *cbf |= src & (1 << plane);
} }
#define GET_SPLITDATA(CU,curDepth) (((CU)->split_tree >> (curDepth)) & 7) #define GET_SPLITDATA(CU,curDepth) (((CU)->split_tree >> (curDepth)) & 7)

View file

@ -466,7 +466,7 @@ static void encode_chroma_tu(
uvg_get_sub_coeff(coeff_u, coeff->u, x_local, y_local, cu_loc->chroma_width, cu_loc->chroma_height, LCU_WIDTH_C); uvg_get_sub_coeff(coeff_u, coeff->u, x_local, y_local, cu_loc->chroma_width, cu_loc->chroma_height, LCU_WIDTH_C);
uvg_get_sub_coeff(coeff_v, coeff->v, x_local, y_local, cu_loc->chroma_width, cu_loc->chroma_height, LCU_WIDTH_C); uvg_get_sub_coeff(coeff_v, coeff->v, x_local, y_local, cu_loc->chroma_width, cu_loc->chroma_height, LCU_WIDTH_C);
if (cbf_is_set(cur_pu->cbf, depth, COLOR_U)) { if (cbf_is_set(cur_pu->cbf, COLOR_U)) {
// TODO: height for this check and the others below // TODO: height for this check and the others below
if(state->encoder_control->cfg.trskip_enable && width_c <= (1 << state->encoder_control->cfg.trskip_max_size)){ if(state->encoder_control->cfg.trskip_enable && width_c <= (1 << state->encoder_control->cfg.trskip_max_size)){
cabac->cur_ctx = &cabac->ctx.transform_skip_model_chroma; cabac->cur_ctx = &cabac->ctx.transform_skip_model_chroma;
@ -477,7 +477,7 @@ static void encode_chroma_tu(
uvg_encode_coeff_nxn(state, &state->cabac, coeff_u, cu_loc, COLOR_U, *scan_idx, cur_pu, NULL); uvg_encode_coeff_nxn(state, &state->cabac, coeff_u, cu_loc, COLOR_U, *scan_idx, cur_pu, NULL);
} }
if (cbf_is_set(cur_pu->cbf, depth, COLOR_V)) { if (cbf_is_set(cur_pu->cbf, COLOR_V)) {
if (state->encoder_control->cfg.trskip_enable && width_c <= (1 << state->encoder_control->cfg.trskip_max_size)) { if (state->encoder_control->cfg.trskip_enable && width_c <= (1 << state->encoder_control->cfg.trskip_max_size)) {
cabac->cur_ctx = &cabac->ctx.transform_skip_model_chroma; cabac->cur_ctx = &cabac->ctx.transform_skip_model_chroma;
CABAC_BIN(cabac, (cur_pu->tr_skip >> COLOR_V) & 1, "transform_skip_flag"); CABAC_BIN(cabac, (cur_pu->tr_skip >> COLOR_V) & 1, "transform_skip_flag");
@ -526,7 +526,7 @@ static void encode_transform_unit(
int8_t scan_idx = uvg_get_scan_order(cur_pu->type, cur_pu->intra.mode, depth); int8_t scan_idx = uvg_get_scan_order(cur_pu->type, cur_pu->intra.mode, depth);
int cbf_y = cbf_is_set(cur_pu->cbf, depth, COLOR_Y); int cbf_y = cbf_is_set(cur_pu->cbf, COLOR_Y);
if (cbf_y && !only_chroma) { if (cbf_y && !only_chroma) {
int x_local = x % LCU_WIDTH; int x_local = x % LCU_WIDTH;
@ -573,8 +573,8 @@ static void encode_transform_unit(
} }
} }
bool chroma_cbf_set = cbf_is_set(cur_pu->cbf, depth, COLOR_U) || bool chroma_cbf_set = cbf_is_set(cur_pu->cbf, COLOR_U) ||
cbf_is_set(cur_pu->cbf, depth, COLOR_V); cbf_is_set(cur_pu->cbf, COLOR_V);
if ((chroma_cbf_set || joint_chroma) && last_split) { if ((chroma_cbf_set || joint_chroma) && last_split) {
//Need to drop const to get lfnst constraints //Need to drop const to get lfnst constraints
// Use original dimensions instead of ISP split dimensions // Use original dimensions instead of ISP split dimensions
@ -644,9 +644,9 @@ static void encode_transform_coeff(
int8_t split = (cu_loc->width > TR_MAX_WIDTH || cu_loc->height > TR_MAX_WIDTH); int8_t split = (cu_loc->width > TR_MAX_WIDTH || cu_loc->height > TR_MAX_WIDTH);
const int cb_flag_y = tree_type != UVG_CHROMA_T ? cbf_is_set(cur_pu->cbf, depth, COLOR_Y) : 0; const int cb_flag_y = tree_type != UVG_CHROMA_T ? cbf_is_set(cur_pu->cbf, COLOR_Y) : 0;
const int cb_flag_u = tree_type != UVG_LUMA_T ?( cur_pu->joint_cb_cr ? (cur_pu->joint_cb_cr >> 1) & 1 : cbf_is_set(cur_cu->cbf, depth, COLOR_U)) : 0; const int cb_flag_u = tree_type != UVG_LUMA_T ?( cur_pu->joint_cb_cr ? (cur_pu->joint_cb_cr >> 1) & 1 : cbf_is_set(cur_cu->cbf, COLOR_U)) : 0;
const int cb_flag_v = tree_type != UVG_LUMA_T ? (cur_pu->joint_cb_cr ? cur_pu->joint_cb_cr & 1 : cbf_is_set(cur_cu->cbf, depth, COLOR_V)) : 0; const int cb_flag_v = tree_type != UVG_LUMA_T ? (cur_pu->joint_cb_cr ? cur_pu->joint_cb_cr & 1 : cbf_is_set(cur_cu->cbf, COLOR_V)) : 0;
// The split_transform_flag is not signaled when: // The split_transform_flag is not signaled when:
// - transform size is greater than 32 (depth == 0) // - transform size is greater than 32 (depth == 0)
@ -1610,15 +1610,15 @@ void uvg_encode_coding_tree(
} }
{ {
int cbf = cbf_is_set_any(cur_cu->cbf, depth);
// Only need to signal coded block flag if not skipped or merged // Only need to signal coded block flag if not skipped or merged
// skip = no coded residual, merge = coded residual // skip = no coded residual, merge = coded residual
const bool has_coeffs = cur_pu->root_cbf || cur_pu->cbf;
if (!cur_cu->merged) { if (!cur_cu->merged) {
cabac->cur_ctx = &(cabac->ctx.cu_qt_root_cbf_model); cabac->cur_ctx = &(cabac->ctx.cu_qt_root_cbf_model);
CABAC_BIN(cabac, cbf, "rqt_root_cbf"); CABAC_BIN(cabac, has_coeffs, "rqt_root_cbf");
} }
// Code (possible) coeffs to bitstream // Code (possible) coeffs to bitstream
if (cbf) { if (has_coeffs) {
int luma_cbf_ctx = 0; int luma_cbf_ctx = 0;
encode_transform_coeff(state, cu_loc, depth, 0, 0, 0, 0, coeff, tree_type, true, false, &luma_cbf_ctx, cu_loc); encode_transform_coeff(state, cu_loc, depth, 0, 0, 0, 0, coeff, tree_type, true, false, &luma_cbf_ctx, cu_loc);
} }

View file

@ -667,12 +667,12 @@ static void set_cu_qps(encoder_state_t *state, const cu_loc_t* const cu_loc, int
for (int y_scu = cu_loc->y; !cbf_found && y_scu < y_limit; y_scu += tu_width) { for (int y_scu = cu_loc->y; !cbf_found && y_scu < y_limit; y_scu += tu_width) {
for (int x_scu = cu_loc->x; !cbf_found && x_scu < x_limit; x_scu += tu_width) { for (int x_scu = cu_loc->x; !cbf_found && x_scu < x_limit; x_scu += tu_width) {
cu_info_t *tu = uvg_cu_array_at(state->tile->frame->cu_array, x_scu, y_scu); cu_info_t *tu = uvg_cu_array_at(state->tile->frame->cu_array, x_scu, y_scu);
if (cbf_is_set_any(tu->cbf, cu->depth)) { if (cbf_is_set_any(tu->cbf)) {
cbf_found = true; cbf_found = true;
} }
} }
} }
} else if (cbf_is_set_any(cu->cbf, cu->depth)) { } else if (cbf_is_set_any(cu->cbf)) {
cbf_found = true; cbf_found = true;
} }
@ -2045,9 +2045,9 @@ static void _encode_one_frame_add_bitstream_deps(const encoder_state_t * const s
void uvg_encode_one_frame(encoder_state_t * const state, uvg_picture* frame) void uvg_encode_one_frame(encoder_state_t * const state, uvg_picture* frame)
{ {
#if UVG_DEBUG_PRINT_CABAC == 1 #if UVG_DEBUG_PRINT_CABAC == 1
uvg_cabac_bins_count = 0; // uvg_cabac_bins_count = 0;
if (state->frame->num == 0) uvg_cabac_bins_verbose = true; if (state->frame->num == 0) uvg_cabac_bins_verbose = true;
else uvg_cabac_bins_verbose = false; // else uvg_cabac_bins_verbose = false;
#endif #endif

View file

@ -757,8 +757,8 @@ static void filter_deblock_edge_luma(encoder_state_t * const state,
cu_q = uvg_cu_array_at(frame->cu_array, x_coord, y); cu_q = uvg_cu_array_at(frame->cu_array, x_coord, y);
} }
bool nonzero_coeffs = cbf_is_set(cu_q->cbf, cu_q->tr_depth, COLOR_Y) bool nonzero_coeffs = cbf_is_set(cu_q->cbf, COLOR_Y)
|| cbf_is_set(cu_p->cbf, cu_p->tr_depth, COLOR_Y); || cbf_is_set(cu_p->cbf, COLOR_Y);
// Filter strength // Filter strength
strength = 0; strength = 0;
@ -1122,10 +1122,10 @@ static void filter_deblock_edge_chroma(encoder_state_t * const state,
c_strength[1] = 2; c_strength[1] = 2;
} }
else if (tu_boundary){ //TODO: Add ciip/IBC related stuff else if (tu_boundary){ //TODO: Add ciip/IBC related stuff
bool nonzero_coeffs_U = cbf_is_set(cu_q->cbf, cu_q->tr_depth, COLOR_U) bool nonzero_coeffs_U = cbf_is_set(cu_q->cbf, COLOR_U)
|| cbf_is_set(cu_p->cbf, cu_p->tr_depth, COLOR_U); || cbf_is_set(cu_p->cbf, COLOR_U);
bool nonzero_coeffs_V = cbf_is_set(cu_q->cbf, cu_q->tr_depth, COLOR_V) bool nonzero_coeffs_V = cbf_is_set(cu_q->cbf, COLOR_V)
|| cbf_is_set(cu_p->cbf, cu_p->tr_depth, COLOR_V); || cbf_is_set(cu_p->cbf, COLOR_V);
c_strength[0] = nonzero_coeffs_U ? 1 : 0; c_strength[0] = nonzero_coeffs_U ? 1 : 0;
c_strength[1] = nonzero_coeffs_V ? 1 : 0; c_strength[1] = nonzero_coeffs_V ? 1 : 0;
} }

View file

@ -1792,11 +1792,11 @@ void uvg_intra_recon_cu(
// Reset CBFs because CBFs might have been set // Reset CBFs because CBFs might have been set
// for depth earlier // for depth earlier
if (recon_luma) { if (recon_luma) {
cbf_clear(&cur_cu->cbf, depth, COLOR_Y); cbf_clear(&cur_cu->cbf, COLOR_Y);
} }
if (recon_chroma) { if (recon_chroma) {
cbf_clear(&cur_cu->cbf, depth, COLOR_U); cbf_clear(&cur_cu->cbf, COLOR_U);
cbf_clear(&cur_cu->cbf, depth, COLOR_V); cbf_clear(&cur_cu->cbf, COLOR_V);
} }
if (width > TR_MAX_WIDTH || height > TR_MAX_WIDTH) { if (width > TR_MAX_WIDTH || height > TR_MAX_WIDTH) {
@ -1820,13 +1820,13 @@ void uvg_intra_recon_cu(
LCU_GET_CU_AT_PX(lcu, (lcu_px.x + half_width) >> (tree_type == UVG_CHROMA_T), (lcu_px.y + half_height) >> (tree_type == UVG_CHROMA_T))->cbf, LCU_GET_CU_AT_PX(lcu, (lcu_px.x + half_width) >> (tree_type == UVG_CHROMA_T), (lcu_px.y + half_height) >> (tree_type == UVG_CHROMA_T))->cbf,
}; };
if (recon_luma && depth <= MAX_DEPTH) { //if (recon_luma && depth <= MAX_DEPTH) {
cbf_set_conditionally(&cur_cu->cbf, child_cbfs, depth, COLOR_Y); // cbf_set_conditionally(&cur_cu->cbf, child_cbfs, depth, COLOR_Y);
} //}
if (recon_chroma && depth <= MAX_DEPTH) { //if (recon_chroma && depth <= MAX_DEPTH) {
cbf_set_conditionally(&cur_cu->cbf, child_cbfs, depth, COLOR_U); // cbf_set_conditionally(&cur_cu->cbf, child_cbfs, depth, COLOR_U);
cbf_set_conditionally(&cur_cu->cbf, child_cbfs, depth, COLOR_V); // cbf_set_conditionally(&cur_cu->cbf, child_cbfs, depth, COLOR_V);
} //}
return; return;
} }
if (search_data->pred_cu.intra.isp_mode != ISP_MODE_NO_ISP && recon_luma ) { if (search_data->pred_cu.intra.isp_mode != ISP_MODE_NO_ISP && recon_luma ) {
@ -1848,7 +1848,7 @@ void uvg_intra_recon_cu(
uvg_quantize_lcu_residual(state, true, false, false, uvg_quantize_lcu_residual(state, true, false, false,
&tu_loc, depth, cur_cu, lcu, &tu_loc, depth, cur_cu, lcu,
false, tree_type); false, tree_type);
search_data->best_isp_cbfs |= cbf_is_set(cur_cu->cbf, depth, COLOR_Y) << i; search_data->best_isp_cbfs |= cbf_is_set(cur_cu->cbf, COLOR_Y) << i;
} }
} }
const bool has_luma = recon_luma && search_data->pred_cu.intra.isp_mode == ISP_MODE_NO_ISP; const bool has_luma = recon_luma && search_data->pred_cu.intra.isp_mode == ISP_MODE_NO_ISP;

View file

@ -1732,7 +1732,7 @@ void uvg_rdoq(
assert(0); assert(0);
} }
// This cbf should work even with non-square blocks // This cbf should work even with non-square blocks
ctx_cbf = ( color != COLOR_V ? 0 : cbf_is_set(cbf, 5 - uvg_math_floor_log2(width), COLOR_U)); ctx_cbf = ( color != COLOR_V ? 0 : cbf_is_set(cbf, COLOR_U));
best_cost = block_uncoded_cost + lambda * CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],0); best_cost = block_uncoded_cost + lambda * CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],0);
base_cost += lambda * CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],1); base_cost += lambda * CTX_ENTROPY_BITS(&base_cbf_model[ctx_cbf],1);
} }

View file

@ -361,11 +361,11 @@ double uvg_cu_rd_cost_luma(
if (pred_cu->type == CU_INTER || pred_cu->intra.isp_mode == ISP_MODE_NO_ISP) { if (pred_cu->type == CU_INTER || pred_cu->intra.isp_mode == ISP_MODE_NO_ISP) {
const int depth = 6 - uvg_g_convert_to_log2[cu_loc->width]; const int depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
const int is_tr_split = tr_cu->tr_depth - tr_cu->depth; const int is_tr_split = tr_cu->tr_depth - tr_cu->depth;
int is_set = cbf_is_set(pred_cu->cbf, depth, COLOR_Y); int is_set = cbf_is_set(pred_cu->cbf, COLOR_Y);
if (pred_cu->type == CU_INTRA || if (pred_cu->type == CU_INTRA ||
is_tr_split || is_tr_split ||
cbf_is_set(tr_cu->cbf, depth, COLOR_U) || cbf_is_set(tr_cu->cbf, COLOR_U) ||
cbf_is_set(tr_cu->cbf, depth, COLOR_V)) cbf_is_set(tr_cu->cbf, COLOR_V))
{ {
cabac_ctx_t* ctx = &(cabac->ctx.qt_cbf_model_luma[0]); cabac_ctx_t* ctx = &(cabac->ctx.qt_cbf_model_luma[0]);
@ -455,8 +455,8 @@ double uvg_cu_rd_cost_chroma(
} }
const int depth = 6 - uvg_g_convert_to_log2[cu_loc->width]; const int depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
int u_is_set = pred_cu->joint_cb_cr ? (pred_cu->joint_cb_cr & 2) >> 1 : cbf_is_set(pred_cu->cbf, depth, COLOR_U); int u_is_set = pred_cu->joint_cb_cr ? (pred_cu->joint_cb_cr & 2) >> 1 : cbf_is_set(pred_cu->cbf, COLOR_U);
int v_is_set = pred_cu->joint_cb_cr ? (pred_cu->joint_cb_cr & 1) : cbf_is_set(pred_cu->cbf, depth, COLOR_V); int v_is_set = pred_cu->joint_cb_cr ? (pred_cu->joint_cb_cr & 1) : cbf_is_set(pred_cu->cbf, COLOR_V);
if (cu_loc->width > TR_MAX_WIDTH || cu_loc->height > TR_MAX_WIDTH) { if (cu_loc->width > TR_MAX_WIDTH || cu_loc->height > TR_MAX_WIDTH) {
double sum = 0; double sum = 0;
@ -482,11 +482,11 @@ double uvg_cu_rd_cost_chroma(
cabac_data_t* cabac = (cabac_data_t*)&state->search_cabac; cabac_data_t* cabac = (cabac_data_t*)&state->search_cabac;
cabac_ctx_t* ctx = &(cabac->ctx.qt_cbf_model_cb[0]); cabac_ctx_t* ctx = &(cabac->ctx.qt_cbf_model_cb[0]);
cabac->cur_ctx = ctx; cabac->cur_ctx = ctx;
if (tr_depth == 0 || cbf_is_set(pred_cu->cbf, depth - 1, COLOR_U)) { if (tr_depth == 0 || cbf_is_set(pred_cu->cbf, COLOR_U)) {
CABAC_FBITS_UPDATE(cabac, ctx, u_is_set, tr_tree_bits, "cbf_cb_search"); CABAC_FBITS_UPDATE(cabac, ctx, u_is_set, tr_tree_bits, "cbf_cb_search");
} }
ctx = &(cabac->ctx.qt_cbf_model_cr[u_is_set]); ctx = &(cabac->ctx.qt_cbf_model_cr[u_is_set]);
if (tr_depth == 0 || cbf_is_set(pred_cu->cbf, depth - 1, COLOR_V)) { if (tr_depth == 0 || cbf_is_set(pred_cu->cbf, COLOR_V)) {
CABAC_FBITS_UPDATE(cabac, ctx, v_is_set, tr_tree_bits, "cbf_cb_search"); CABAC_FBITS_UPDATE(cabac, ctx, v_is_set, tr_tree_bits, "cbf_cb_search");
} }
} }
@ -558,13 +558,13 @@ static double cu_rd_cost_tr_split_accurate(
const int depth = 6 - uvg_g_convert_to_log2[cu_loc->width]; const int depth = 6 - uvg_g_convert_to_log2[cu_loc->width];
const int cb_flag_u = tr_cu->joint_cb_cr ? tr_cu->joint_cb_cr >> 1 : cbf_is_set(tr_cu->cbf, depth, COLOR_U); const int cb_flag_u = tr_cu->joint_cb_cr ? tr_cu->joint_cb_cr >> 1 : cbf_is_set(tr_cu->cbf, COLOR_U);
const int cb_flag_v = tr_cu->joint_cb_cr ? tr_cu->joint_cb_cr & 1 : cbf_is_set(tr_cu->cbf, depth, COLOR_V); const int cb_flag_v = tr_cu->joint_cb_cr ? tr_cu->joint_cb_cr & 1 : cbf_is_set(tr_cu->cbf, COLOR_V);
cabac_data_t* cabac = (cabac_data_t*)&state->search_cabac; cabac_data_t* cabac = (cabac_data_t*)&state->search_cabac;
{ {
int cbf = cbf_is_set_any(tr_cu->cbf, depth); int cbf = cbf_is_set_any(tr_cu->cbf);
// Only need to signal coded block flag if not skipped or merged // Only need to signal coded block flag if not skipped or merged
// skip = no coded residual, merge = coded residual // skip = no coded residual, merge = coded residual
if (pred_cu->type != CU_INTRA && (!pred_cu->merged)) { if (pred_cu->type != CU_INTRA && (!pred_cu->merged)) {
@ -596,7 +596,7 @@ static double cu_rd_cost_tr_split_accurate(
CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.qt_cbf_model_cr[cb_flag_u]), cb_flag_v, tr_tree_bits, "cbf_cr"); CABAC_FBITS_UPDATE(cabac, &(cabac->ctx.qt_cbf_model_cr[cb_flag_u]), cb_flag_v, tr_tree_bits, "cbf_cr");
} }
const int cb_flag_y = cbf_is_set(tr_cu->cbf, depth, COLOR_Y) && tree_type != UVG_CHROMA_T; const int cb_flag_y = cbf_is_set(tr_cu->cbf, COLOR_Y) && tree_type != UVG_CHROMA_T;
const bool is_isp = !(pred_cu->type == CU_INTER || pred_cu->intra.isp_mode == ISP_MODE_NO_ISP); const bool is_isp = !(pred_cu->type == CU_INTER || pred_cu->intra.isp_mode == ISP_MODE_NO_ISP);
// Add transform_tree cbf_luma bit cost. // Add transform_tree cbf_luma bit cost.
@ -1182,8 +1182,8 @@ static double search_cu(
const int split_type = intra_search.pred_cu.intra.isp_mode; const int split_type = intra_search.pred_cu.intra.isp_mode;
const int split_num = split_type == ISP_MODE_NO_ISP ? 0 : uvg_get_isp_split_num(cu_width, cu_height, split_type, true); const int split_num = split_type == ISP_MODE_NO_ISP ? 0 : uvg_get_isp_split_num(cu_width, cu_height, split_type, true);
const int cbf_cb = cbf_is_set(cur_cu->cbf, split_tree.current_depth, COLOR_U); const int cbf_cb = cbf_is_set(cur_cu->cbf, COLOR_U);
const int cbf_cr = cbf_is_set(cur_cu->cbf, split_tree.current_depth, COLOR_V); const int cbf_cr = cbf_is_set(cur_cu->cbf, COLOR_V);
const int jccr = cur_cu->joint_cb_cr; const int jccr = cur_cu->joint_cb_cr;
for (int i = 0; i < split_num; ++i) { for (int i = 0; i < split_num; ++i) {
cu_loc_t isp_loc; cu_loc_t isp_loc;
@ -1195,14 +1195,14 @@ static double search_cu(
uvg_get_isp_cu_arr_coords(&tmp_x, &tmp_y); uvg_get_isp_cu_arr_coords(&tmp_x, &tmp_y);
cu_info_t* split_cu = LCU_GET_CU_AT_PX(lcu, tmp_x % LCU_WIDTH, tmp_y % LCU_WIDTH); cu_info_t* split_cu = LCU_GET_CU_AT_PX(lcu, tmp_x % LCU_WIDTH, tmp_y % LCU_WIDTH);
bool cur_cbf = (intra_search.best_isp_cbfs >> i) & 1; bool cur_cbf = (intra_search.best_isp_cbfs >> i) & 1;
cbf_clear(&split_cu->cbf, split_tree.current_depth, COLOR_Y); cbf_clear(&split_cu->cbf, COLOR_Y);
cbf_clear(&split_cu->cbf, split_tree.current_depth, COLOR_U); cbf_clear(&split_cu->cbf, COLOR_U);
cbf_clear(&split_cu->cbf, split_tree.current_depth, COLOR_V); cbf_clear(&split_cu->cbf, COLOR_V);
if (cur_cbf) { if (cur_cbf) {
cbf_set(&split_cu->cbf, split_tree.current_depth, COLOR_Y); cbf_set(&split_cu->cbf, COLOR_Y);
} }
if(cbf_cb) cbf_set(&split_cu->cbf, split_tree.current_depth, COLOR_U); if(cbf_cb) cbf_set(&split_cu->cbf, COLOR_U);
if(cbf_cr) cbf_set(&split_cu->cbf, split_tree.current_depth, COLOR_V); if(cbf_cr) cbf_set(&split_cu->cbf, COLOR_V);
split_cu->joint_cb_cr = jccr; split_cu->joint_cb_cr = jccr;
} }
lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_width, cur_cu); lcu_fill_cu_info(lcu, x_local, y_local, cu_width, cu_width, cur_cu);
@ -1241,7 +1241,7 @@ static double search_cu(
false, false,
tree_type); tree_type);
int cbf = cbf_is_set_any(cur_cu->cbf, split_tree.current_depth); int cbf = cbf_is_set_any(cur_cu->cbf);
if (cur_cu->merged && !cbf) { if (cur_cu->merged && !cbf) {
cur_cu->merged = 0; cur_cu->merged = 0;
@ -1327,7 +1327,7 @@ static double search_cu(
int half_cu = cu_width >> (tree_type != UVG_CHROMA_T); int half_cu = cu_width >> (tree_type != UVG_CHROMA_T);
double split_cost = 0.0; double split_cost = 0.0;
int cbf = cbf_is_set_any(cur_cu->cbf, split_tree.current_depth); int cbf = cbf_is_set_any(cur_cu->cbf);
cabac_data_t post_seach_cabac; cabac_data_t post_seach_cabac;
memcpy(&post_seach_cabac, &state->search_cabac, sizeof(post_seach_cabac)); memcpy(&post_seach_cabac, &state->search_cabac, sizeof(post_seach_cabac));
memcpy(&state->search_cabac, &pre_search_cabac, sizeof(post_seach_cabac)); memcpy(&state->search_cabac, &pre_search_cabac, sizeof(post_seach_cabac));

View file

@ -1816,7 +1816,7 @@ static void search_pu_inter(
uvg_quantize_lcu_residual(state, true, false, false, cu_loc, depth, cur_pu, lcu, true, UVG_BOTH_T); uvg_quantize_lcu_residual(state, true, false, false, cu_loc, depth, cur_pu, lcu, true, UVG_BOTH_T);
if (cbf_is_set(cur_pu->cbf, depth, COLOR_Y)) { if (cbf_is_set(cur_pu->cbf, COLOR_Y)) {
continue; continue;
} }
else if (has_chroma) { else if (has_chroma) {
@ -1827,7 +1827,7 @@ static void search_pu_inter(
cu_loc, depth, cur_pu, lcu, cu_loc, depth, cur_pu, lcu,
true, true,
UVG_BOTH_T); UVG_BOTH_T);
if (!cbf_is_set_any(cur_pu->cbf, depth)) { if (!cbf_is_set_any(cur_pu->cbf)) {
cur_pu->type = CU_INTER; cur_pu->type = CU_INTER;
cur_pu->merge_idx = merge_idx; cur_pu->merge_idx = merge_idx;
cur_pu->skipped = true; cur_pu->skipped = true;
@ -2228,20 +2228,20 @@ void uvg_cu_cost_inter_rd2(
v_resi, v_resi,
&chorma_ts_out, &chorma_ts_out,
UVG_BOTH_T); UVG_BOTH_T);
cbf_clear(&cur_cu->cbf, depth, COLOR_U); cbf_clear(&cur_cu->cbf, COLOR_U);
cbf_clear(&cur_cu->cbf, depth, COLOR_V); cbf_clear(&cur_cu->cbf, COLOR_V);
if (chorma_ts_out.best_u_cost + chorma_ts_out.best_v_cost < chorma_ts_out.best_combined_cost) { if (chorma_ts_out.best_u_cost + chorma_ts_out.best_v_cost < chorma_ts_out.best_combined_cost) {
cur_cu->joint_cb_cr = 0; cur_cu->joint_cb_cr = 0;
cur_cu->tr_skip |= (chorma_ts_out.best_u_index == CHROMA_TS) << COLOR_U; cur_cu->tr_skip |= (chorma_ts_out.best_u_index == CHROMA_TS) << COLOR_U;
cur_cu->tr_skip |= (chorma_ts_out.best_v_index == CHROMA_TS) << COLOR_V; cur_cu->tr_skip |= (chorma_ts_out.best_v_index == CHROMA_TS) << COLOR_V;
if(chorma_ts_out.best_u_index != NO_RESIDUAL) cbf_set(&cur_cu->cbf, depth, COLOR_U); if(chorma_ts_out.best_u_index != NO_RESIDUAL) cbf_set(&cur_cu->cbf, COLOR_U);
if(chorma_ts_out.best_v_index != NO_RESIDUAL) cbf_set(&cur_cu->cbf, depth, COLOR_V); if(chorma_ts_out.best_v_index != NO_RESIDUAL) cbf_set(&cur_cu->cbf, COLOR_V);
chroma_cost += chorma_ts_out.best_u_cost + chorma_ts_out.best_v_cost; chroma_cost += chorma_ts_out.best_u_cost + chorma_ts_out.best_v_cost;
} }
else { else {
cur_cu->joint_cb_cr = chorma_ts_out.best_combined_index; cur_cu->joint_cb_cr = chorma_ts_out.best_combined_index;
if (chorma_ts_out.best_combined_index & 2) cbf_set(&cur_cu->cbf, depth, COLOR_U); if (chorma_ts_out.best_combined_index & 2) cbf_set(&cur_cu->cbf, COLOR_U);
if (chorma_ts_out.best_combined_index & 1) cbf_set(&cur_cu->cbf, depth, COLOR_V); if (chorma_ts_out.best_combined_index & 1) cbf_set(&cur_cu->cbf, COLOR_V);
chroma_cost += chorma_ts_out.best_combined_cost; chroma_cost += chorma_ts_out.best_combined_cost;
} }
} }
@ -2257,7 +2257,7 @@ void uvg_cu_cost_inter_rd2(
UVG_BOTH_T); UVG_BOTH_T);
} }
int cbf = cbf_is_set_any(cur_cu->cbf, depth); int cbf = cbf_is_set_any(cur_cu->cbf);
if(cbf) { if(cbf) {
*inter_cost = uvg_cu_rd_cost_luma(state, cu_loc, cur_cu, lcu, 0); *inter_cost = uvg_cu_rd_cost_luma(state, cu_loc, cur_cu, lcu, 0);

View file

@ -304,10 +304,10 @@ static double search_intra_trdepth(
nosplit_cost = 0.0; nosplit_cost = 0.0;
cbf_clear(&pred_cu->cbf, depth, COLOR_Y); cbf_clear(&pred_cu->cbf, COLOR_Y);
if (reconstruct_chroma) { if (reconstruct_chroma) {
cbf_clear(&pred_cu->cbf, depth, COLOR_U); cbf_clear(&pred_cu->cbf, COLOR_U);
cbf_clear(&pred_cu->cbf, depth, COLOR_V); cbf_clear(&pred_cu->cbf, COLOR_V);
} }
const int8_t chroma_mode = reconstruct_chroma ? (!pred_cu->intra.mip_flag ? pred_cu->intra.mode : 0) : -1; const int8_t chroma_mode = reconstruct_chroma ? (!pred_cu->intra.mip_flag ? pred_cu->intra.mode : 0) : -1;
@ -398,7 +398,7 @@ static double search_intra_trdepth(
); );
if (pred_cu->intra.isp_mode != ISP_MODE_NO_ISP && search_data->best_isp_cbfs == 0) continue; if (pred_cu->intra.isp_mode != ISP_MODE_NO_ISP && search_data->best_isp_cbfs == 0) continue;
if (trafo != 0 && !cbf_is_set(pred_cu->cbf, depth, COLOR_Y)) continue; if (trafo != 0 && !cbf_is_set(pred_cu->cbf, COLOR_Y)) continue;
derive_mts_constraints(pred_cu, lcu, width, height, lcu_px); derive_mts_constraints(pred_cu, lcu, width, height, lcu_px);
if (pred_cu->tr_idx > 1) { if (pred_cu->tr_idx > 1) {
@ -424,7 +424,7 @@ static double search_intra_trdepth(
COLOR_Y); COLOR_Y);
} }
if (!constraints[1] && cbf_is_set(pred_cu->cbf, depth, COLOR_Y)) { if (!constraints[1] && cbf_is_set(pred_cu->cbf, COLOR_Y)) {
//end_idx = 0; //end_idx = 0;
if (pred_cu->lfnst_idx > 0) { if (pred_cu->lfnst_idx > 0) {
continue; continue;
@ -1347,7 +1347,7 @@ static int8_t search_intra_rdo(
best_isp_mode = isp_mode; best_isp_mode = isp_mode;
best_bits = search_data[mode].bits; best_bits = search_data[mode].bits;
} }
if (state->encoder_control->cfg.intra_rdo_et && !cbf_is_set_any(search_data[mode].pred_cu.cbf, depth)) { if (state->encoder_control->cfg.intra_rdo_et && !cbf_is_set_any(search_data[mode].pred_cu.cbf)) {
modes_to_check = mode + 1; modes_to_check = mode + 1;
break; break;
} }

View file

@ -446,7 +446,7 @@ static void quantize_chroma(
if (transforms[i] == DCT7_CHROMA) { if (transforms[i] == DCT7_CHROMA) {
uint16_t temp_cbf = 0; uint16_t temp_cbf = 0;
if (*u_has_coeffs)cbf_set(&temp_cbf, depth, COLOR_U); if (*u_has_coeffs)cbf_set(&temp_cbf, COLOR_U);
uvg_rdoq(state, &v_coeff[i * trans_offset], v_quant_coeff, width, height, COLOR_V, uvg_rdoq(state, &v_coeff[i * trans_offset], v_quant_coeff, width, height, COLOR_V,
scan_order, CU_INTRA, temp_cbf, lfnst_idx); scan_order, CU_INTRA, temp_cbf, lfnst_idx);
@ -1289,7 +1289,7 @@ static void quantize_tr_residual(
for (int j = 0; j < tr_height; ++j) { for (int j = 0; j < tr_height; ++j) {
memcpy(&dst_coeff[j * lcu_width], &coeff[j * tr_width], tr_width * sizeof(coeff_t)); memcpy(&dst_coeff[j * lcu_width], &coeff[j * tr_width], tr_width * sizeof(coeff_t));
} }
cbf_set(&cur_pu->cbf, depth, color); cbf_set(&cur_pu->cbf, color);
} }
else { else {
for (int j = 0; j < tr_height; ++j) { for (int j = 0; j < tr_height; ++j) {
@ -1318,13 +1318,12 @@ static void quantize_tr_residual(
} }
// ISP_TODO: does this cu point to correct cbf when ISP is used for small blocks? cbf_clear(&cur_pu->cbf, color);
cbf_clear(&cur_pu->cbf, depth, color);
if (has_coeffs) { if (has_coeffs) {
for (int j = 0; j < tr_height; ++j) { for (int j = 0; j < tr_height; ++j) {
memcpy(&dst_coeff[j * lcu_width], &coeff[j * tr_width], tr_width * sizeof(coeff_t)); memcpy(&dst_coeff[j * lcu_width], &coeff[j * tr_width], tr_width * sizeof(coeff_t));
} }
cbf_set(&cur_pu->cbf, depth, color); cbf_set(&cur_pu->cbf, color);
} }
else { else {
for (int j = 0; j < tr_height; ++j) { for (int j = 0; j < tr_height; ++j) {
@ -1387,11 +1386,11 @@ void uvg_quantize_lcu_residual(
// for depth earlier // for depth earlier
// ISP_TODO: does this cur_cu point to the correct place when ISP is used for small blocks? // ISP_TODO: does this cur_cu point to the correct place when ISP is used for small blocks?
if (luma) { if (luma) {
cbf_clear(&cur_pu->cbf, depth, COLOR_Y); cbf_clear(&cur_pu->cbf, COLOR_Y);
} }
if (chroma || jccr) { if (chroma || jccr) {
cbf_clear(&cur_pu->cbf, depth, COLOR_U); cbf_clear(&cur_pu->cbf, COLOR_U);
cbf_clear(&cur_pu->cbf, depth, COLOR_V); cbf_clear(&cur_pu->cbf, COLOR_V);
} }
if (depth == 0 || cur_pu->tr_depth > depth) { if (depth == 0 || cur_pu->tr_depth > depth) {
@ -1423,9 +1422,10 @@ void uvg_quantize_lcu_residual(
}; };
if (depth <= MAX_DEPTH) { if (depth <= MAX_DEPTH) {
cbf_set_conditionally(&cur_pu->cbf, child_cbfs, depth, COLOR_Y); cur_pu->root_cbf = cbf_is_set_any(cur_pu->cbf)
cbf_set_conditionally(&cur_pu->cbf, child_cbfs, depth, COLOR_U); || cbf_is_set_any(child_cbfs[0])
cbf_set_conditionally(&cur_pu->cbf, child_cbfs, depth, COLOR_V); || cbf_is_set_any(child_cbfs[1])
|| cbf_is_set_any(child_cbfs[2]);
} }
} else { } else {