From b093248ca7f15ff095745abcfc8e6f96e7391278 Mon Sep 17 00:00:00 2001 From: Joose Sainio Date: Tue, 12 Apr 2022 08:39:30 +0300 Subject: [PATCH] Maybe working for regular intra search --- src/encode_coding_tree.c | 3 +- src/intra.c | 4 +- src/intra.h | 3 + src/search.c | 15 +- src/search_intra.c | 375 +++++++++++++-------------------------- 5 files changed, 135 insertions(+), 265 deletions(-) diff --git a/src/encode_coding_tree.c b/src/encode_coding_tree.c index e37b9f16..e6f39926 100644 --- a/src/encode_coding_tree.c +++ b/src/encode_coding_tree.c @@ -1507,8 +1507,7 @@ void kvz_encode_coding_tree(encoder_state_t * const state, // For 4x4 the chroma PU/TU is coded after the last if (state->encoder_control->chroma_format != KVZ_CSP_400 && depth == 4 && x % 8 && y % 8) { encode_chroma_intra_cu(cabac, cur_cu, state->encoder_control->cfg.cclm); - encode_transform_coeff(state, x, y, depth, 0, 0, 0, 1, coeff); - + encode_transform_coeff(state, x, y, depth, 0, 0, 0, 1, coeff); } } diff --git a/src/intra.c b/src/intra.c index 12314e14..09ced04b 100644 --- a/src/intra.c +++ b/src/intra.c @@ -1588,6 +1588,8 @@ void kvz_intra_recon_cu( intra_recon_tb_leaf(state, x, y, depth, lcu, COLOR_V, search_data); } - kvz_quantize_lcu_residual(state, has_luma, has_chroma, search_data->pred_cu.joint_cb_cr != 4, x, y, depth, cur_cu, lcu, false); + kvz_quantize_lcu_residual(state, has_luma, has_chroma, + search_data->pred_cu.joint_cb_cr != 4 && state->encoder_control->cfg.jccr && (x % 8 == 0 && y % 8 == 0), + x, y, depth, cur_cu, lcu, false); } } diff --git a/src/intra.h b/src/intra.h index 2982bff3..59aa10c9 100644 --- a/src/intra.h +++ b/src/intra.h @@ -72,6 +72,9 @@ typedef struct { double distortion; } intra_search_data_t ; + +#define KVZ_NUM_INTRA_MODES 67 + /** * \brief Function for deriving intra luma predictions * \param x x-coordinate of the PU in pixels diff --git a/src/search.c b/src/search.c index 01dc9447..93f78561 100644 --- a/src/search.c +++ b/src/search.c @@ -1008,6 +1008,8 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth, depth, &intra_search, NULL, lcu); + cur_cu->intra.mode_chroma = intra_search.pred_cu.intra.mode_chroma; + cur_cu->joint_cb_cr = intra_search.pred_cu.joint_cb_cr; if(depth != 0 && state->encoder_control->cfg.jccr) { kvz_select_jccr_mode(state, x & ~7, y & ~7, @@ -1201,19 +1203,10 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth, const bool has_chroma = state->encoder_control->chroma_format != KVZ_CSP_400; const int8_t mode_chroma = has_chroma ? cur_cu->intra.mode_chroma : -1; - intra_parameters_t intra_parameters = { - .luma_mode = cur_cu->intra.mode, - .chroma_mode = mode_chroma, - .cclm_parameters ={{0, 0, 0}, {0, 0 ,0}}, - 0, - 0, - 0, - 0, - -1, - }; + kvz_intra_recon_cu(state, x, y, - depth, , + depth, NULL, NULL, lcu); diff --git a/src/search_intra.c b/src/search_intra.c index b4e94900..5f6ad457 100644 --- a/src/search_intra.c +++ b/src/search_intra.c @@ -171,18 +171,23 @@ static void get_cost_dual(encoder_state_t * const state, } -void INLINE rough_cost_prediction_mode(const encoder_state_t* const state, +double static INLINE rough_cost_prediction_mode(const encoder_state_t* const state, kvz_intra_references* const references, const cu_loc_t* const cu_loc, - const int depth, + kvz_pixel *ref_pixels, const color_t color, intra_search_data_t * data, lcu_t* lcu) { - const int width = MAX(4, (color == COLOR_Y ? LCU_WIDTH : LCU_WIDTH_C) >> depth); - const int height= MAX(4, (color == COLOR_Y ? LCU_WIDTH : LCU_WIDTH_C) >> depth); - kvz_pixel pred[TR_MAX_WIDTH * TR_MAX_WIDTH + SIMD_ALIGNMENT]; - // kvz_intra_predict(state, references, width, height, pred, data); + const int width = color == COLOR_Y ? cu_loc->width : cu_loc->chroma_width; + cost_pixel_nxn_func* satd_func = kvz_pixels_get_satd_func(width); + cost_pixel_nxn_func* sad_func = kvz_pixels_get_sad_func(width); + + kvz_pixel _pred[TR_MAX_WIDTH * TR_MAX_WIDTH + SIMD_ALIGNMENT]; + kvz_pixel* pred = ALIGNED_POINTER(_pred, SIMD_ALIGNMENT); + kvz_intra_predict(state, references, cu_loc, color, pred, data, lcu); + + double cost = get_cost(state, pred, ref_pixels, satd_func, sad_func, width); } @@ -375,6 +380,7 @@ static double search_intra_trdepth( } } if(reconstruct_chroma) { + int8_t luma_mode = pred_cu->intra.mode; pred_cu->intra.mode = -1; pred_cu->intra.mode_chroma = chroma_mode; pred_cu->joint_cb_cr= 4; // TODO: Maybe check the jccr mode here also but holy shit is the interface of search_intra_rdo bad currently @@ -384,6 +390,7 @@ static double search_intra_trdepth( pred_cu, lcu); best_rd_cost += kvz_cu_rd_cost_chroma(state, lcu_px.x, lcu_px.y, depth, pred_cu, lcu); + pred_cu->intra.mode = luma_mode; } pred_cu->tr_skip = best_tr_idx == MTS_SKIP; pred_cu->tr_idx = best_tr_idx; @@ -569,11 +576,15 @@ static void search_intra_chroma_rough( * * \return Number of prediction modes in param modes. */ -static int8_t search_intra_rough(encoder_state_t * const state, - kvz_pixel *orig, int32_t origstride, - kvz_intra_references *refs, - int log2_width, int8_t *intra_preds, - int8_t modes[67], double costs[67]) +static int8_t search_intra_rough( + encoder_state_t * const state, + kvz_pixel *orig, + int32_t origstride, + kvz_intra_references *refs, + int log2_width, + int8_t *intra_preds, + intra_search_data_t* modes_out, + cu_info_t* const pred_cu) { #define PARALLEL_BLKS 2 // TODO: use 4 for AVX-512 in the future? assert(log2_width >= 2 && log2_width <= 5); @@ -582,6 +593,8 @@ static int8_t search_intra_rough(encoder_state_t * const state, cost_pixel_nxn_func *sad_func = kvz_pixels_get_sad_func(width); cost_pixel_nxn_multi_func *satd_dual_func = kvz_pixels_get_satd_dual_func(width); cost_pixel_nxn_multi_func *sad_dual_func = kvz_pixels_get_sad_dual_func(width); + int8_t modes[KVZ_NUM_INTRA_MODES]; + double costs[KVZ_NUM_INTRA_MODES]; const kvz_config *cfg = &state->encoder_control->cfg; const bool filter_boundary = !(cfg->lossless && cfg->implicit_rdpcm); @@ -616,6 +629,7 @@ static int8_t search_intra_rough(encoder_state_t * const state, cu_loc_t loc = { 0, 0, width, width, width, width }; intra_search_data_t search_proxy; FILL(search_proxy, 0); + search_proxy.pred_cu = *pred_cu; for (int mode = 2; mode <= 66; mode += PARALLEL_BLKS * offset) { @@ -685,10 +699,10 @@ static int8_t search_intra_rough(encoder_state_t * const state, } } - int8_t add_modes[5] = {intra_preds[0], intra_preds[1], intra_preds[2], 0, 1}; + int8_t add_modes[INTRA_MPM_COUNT + 2] = {intra_preds[0], intra_preds[1], intra_preds[2], intra_preds[3], intra_preds[4], intra_preds[5], 0, 1}; // Add DC, planar and missing predicted modes. - for (int8_t pred_i = 0; pred_i < 5; ++pred_i) { + for (int8_t pred_i = 0; pred_i < (INTRA_MPM_COUNT + 2); ++pred_i) { bool has_mode = false; int8_t mode = add_modes[pred_i]; @@ -719,10 +733,10 @@ static int8_t search_intra_rough(encoder_state_t * const state, int smaller_than_pred = 0; double bits; for(; i < INTRA_MPM_COUNT; i++) { - if (intra_preds[i] == mode_i) { + if (intra_preds[i] == modes[mode_i]) { break; } - if(mode_i > intra_preds[i]) { + if(modes[mode_i] > intra_preds[i]) { smaller_than_pred += 1; } } @@ -736,12 +750,25 @@ static int8_t search_intra_rough(encoder_state_t * const state, bits = not_mpm_mode_bit + 5 + (mode_i - smaller_than_pred > 3); } costs[mode_i] += state->lambda_sqrt * bits; + modes_out[mode_i].cost = costs[mode_i]; + modes_out[mode_i].pred_cu = *pred_cu; + modes_out[mode_i].pred_cu.intra.mode = modes[mode_i]; + modes_out[mode_i].pred_cu.intra.mode_chroma = modes[mode_i]; } #undef PARALLEL_BLKS return modes_selected; } + +void search_mip_rough( + encoder_state_t* const state, + cu_loc_t* const cu_loc) +{ + +} + + /** * \brief Find best intra mode out of the ones listed in parameter modes. * @@ -768,147 +795,41 @@ static int8_t search_intra_rough(encoder_state_t * const state, * \param[out] lcu If transform split searching is used, the transform split * information for the best mode is saved in lcu.cu structure. */ -static int8_t search_intra_rdo(encoder_state_t * const state, - int x_px, int y_px, int depth, - kvz_pixel *orig, int32_t origstride, - int8_t *intra_preds, - int modes_to_check, - int8_t modes[67], int8_t trafo[67], double costs[67], - int num_mip_modes_full, - int8_t mip_modes[32], int8_t mip_trafo[32], double mip_costs[32], - lcu_t *lcu, - uint8_t multi_ref_idx) +static int8_t search_intra_rdo( + encoder_state_t * const state, + int x_px, + int y_px, + int depth, + int modes_to_check, + intra_search_data_t *search_data, + lcu_t *lcu) { const int tr_depth = CLIP(1, MAX_PU_DEPTH, depth + state->encoder_control->cfg.tr_depth_intra); - const int width = LCU_WIDTH >> depth; - const int height = width; // TODO: proper height for non-square blocks - - kvz_pixel orig_block[LCU_WIDTH * LCU_WIDTH + 1]; - - kvz_pixels_blit(orig, orig_block, width, height, origstride, width); - - // Check that the predicted modes are in the RDO mode list - if (modes_to_check < 67) { - int pred_mode = 0; - // Skip planar if searching modes for MRL - if (multi_ref_idx != 0) { - pred_mode = 1; - } - for (; pred_mode < 6; pred_mode++) { - int mode_found = 0; - for (int rdo_mode = 0; rdo_mode < modes_to_check; rdo_mode++) { - if (intra_preds[pred_mode] == modes[rdo_mode]) { - mode_found = 1; - break; - } - } - // Add this prediction mode to RDO checking - if (!mode_found) { - modes[modes_to_check] = intra_preds[pred_mode]; - modes_to_check++; - } - } - } - - // MIP_TODO: implement this inside the standard intra for loop. Code duplication is bad. - // MIP_TODO: loop through normal intra modes first - for (int mip = 0; mip <= 1; mip++) { - const int transp_off = mip ? num_mip_modes_full >> 1 : 0; - uint8_t multi_ref_index = mip ? 0 : multi_ref_idx; - int *num_modes = mip ? &num_mip_modes_full : &modes_to_check; + for (int mode = 0; mode < modes_to_check; mode++) { + double rdo_bitcost = kvz_luma_mode_bits(state, &search_data[mode].pred_cu, x_px, y_px, depth, lcu); + search_data[mode].bits = rdo_bitcost; + search_data[mode].cost = rdo_bitcost * state->lambda; - for (uint8_t i = 0; i < *num_modes; i++) { - int8_t mode = mip ? mip_modes[i] : modes[i]; - double *mode_cost_p = mip ? &mip_costs[i] : &costs[i]; - int8_t *mode_trafo_p = mip ? &mip_trafo[i] : &trafo[i]; - - // Mip related stuff - // There can be 32 MIP modes, but only mode numbers [0, 15] are ever written to bitstream. - // Half of the modes [16, 31] are indicated with the separate transpose flag. - // Number of possible modes is less for larger blocks. - const bool is_transposed = mip ? (mode >= transp_off ? true : false) : 0; - int8_t pred_mode = (is_transposed ? mode - transp_off : mode); - - // Perform transform split search and save mode RD cost for the best one. - cu_info_t pred_cu; - pred_cu.depth = depth; - pred_cu.type = CU_INTRA; - pred_cu.part_size = ((depth == MAX_PU_DEPTH) ? SIZE_NxN : SIZE_2Nx2N); // TODO: non-square blocks - pred_cu.skipped = 0; - pred_cu.merged = 0; - pred_cu.bdpcmMode = 0; - pred_cu.intra.mode = pred_mode; - pred_cu.intra.mode_chroma = pred_mode; - pred_cu.intra.multi_ref_idx = multi_ref_index; - pred_cu.intra.mip_is_transposed = is_transposed; - pred_cu.intra.mip_flag = mip ? true : false; - pred_cu.joint_cb_cr = 0; - FILL(pred_cu.cbf, 0); - - double rdo_bitcost = kvz_luma_mode_bits(state, &pred_cu, x_px, y_px, depth, lcu); - *mode_cost_p = rdo_bitcost * state->lambda; - - // Reset transform split data in lcu.cu for this area. - kvz_lcu_fill_trdepth(lcu, x_px, y_px, depth, depth); - - double mode_cost = search_intra_trdepth(state, x_px, y_px, depth, tr_depth, MAX_INT, , lcu); - *mode_cost_p += mode_cost; - *mode_trafo_p = pred_cu.tr_idx; - - // Early termination if no coefficients has to be coded - if (state->encoder_control->cfg.intra_rdo_et && !cbf_is_set_any(pred_cu.cbf, depth)) { - *num_modes = i + 1; - break; - } + double mode_cost = search_intra_trdepth(state, x_px, y_px, depth, tr_depth, MAX_INT, &search_data[mode], lcu); + search_data[mode].cost += mode_cost; + if (state->encoder_control->cfg.intra_rdo_et && !cbf_is_set_any(search_data[mode].pred_cu.cbf, depth)) { + modes_to_check = mode + 1; + break; } } // Update order according to new costs - kvz_sort_modes_intra_luma(modes, trafo, costs, modes_to_check); - bool use_mip = false; - if (num_mip_modes_full) { - kvz_sort_modes_intra_luma(mip_modes, mip_trafo, mip_costs, num_mip_modes_full); - if (costs[0] > mip_costs[0]) { - use_mip = true; + double best_cost = MAX_INT; + int best_mode; + for (int mode = 0; mode < modes_to_check; mode++) { + if(search_data[mode].cost < best_cost) { + best_cost = search_data[mode].cost; + best_mode = mode; } } - + search_data[0] = search_data[best_mode]; - - // The best transform split hierarchy is not saved anywhere, so to get the - // transform split hierarchy the search has to be performed again with the - // best mode. - //if (tr_depth != depth) { - // cu_info_t pred_cu; - // pred_cu.depth = depth; - // pred_cu.type = CU_INTRA; - // pred_cu.part_size = ((depth == MAX_PU_DEPTH) ? SIZE_NxN : SIZE_2Nx2N); - // pred_cu.skipped = 0; - // pred_cu.merged = 0; - // pred_cu.bdpcmMode = 0; - // if (use_mip) { - // int transp_off = num_mip_modes_full >> 1; - // bool is_transposed = (mip_modes[0] >= transp_off ? true : false); - // int8_t pred_mode = (is_transposed ? mip_modes[0] - transp_off : mip_modes[0]); - // pred_cu.intra.mode = pred_mode; - // pred_cu.intra.mode_chroma = pred_mode; - // pred_cu.intra.multi_ref_idx = 0; - // pred_cu.intra.mip_flag = true; - // pred_cu.intra.mip_is_transposed = is_transposed; - // } - // else { - // pred_cu.intra.mode = modes[0]; - // pred_cu.intra.mode_chroma = modes[0]; - // pred_cu.intra.multi_ref_idx = multi_ref_idx; - // pred_cu.intra.mip_flag = false; - // pred_cu.intra.mip_is_transposed = false; - // } - // FILL(pred_cu.cbf, 0); - // search_intra_trdepth(state, x_px, y_px, depth, tr_depth, pred_cu.intra.mode, MAX_INT, &pred_cu, lcu, NULL, trafo[0]); - //} - - // TODO: modes to check does not consider mip modes. Maybe replace with array when mip search is optimized? return modes_to_check; } @@ -1106,7 +1027,7 @@ void kvz_search_cu_intra( const int x_px, const int y_px, const int depth, - intra_search_data_t* search_data, + intra_search_data_t* mode_out, lcu_t *lcu) { const vector2d_t lcu_px = { SUB_SCU(x_px), SUB_SCU(y_px) }; @@ -1118,6 +1039,8 @@ void kvz_search_cu_intra( kvz_intra_references refs; int8_t candidate_modes[INTRA_MPM_COUNT]; + // Normal intra modes + mrl modes + mip modes + intra_search_data_t search_data[KVZ_NUM_INTRA_MODES +(MAX_REF_LINE_IDX - 1) * (INTRA_MPM_COUNT - 1) + 32]; cu_info_t *left_cu = 0; cu_info_t *above_cu = 0; @@ -1140,62 +1063,64 @@ void kvz_search_cu_intra( kvz_intra_build_reference(log2_width, COLOR_Y, &luma_px, &pic_px, lcu, &refs, state->encoder_control->cfg.wpp, NULL, 0); } - int8_t modes[MAX_REF_LINE_IDX][67]; - int8_t trafo[MAX_REF_LINE_IDX][67] = { 0 }; - double costs[MAX_REF_LINE_IDX][67]; - - bool enable_mip = state->encoder_control->cfg.mip; - // The maximum number of mip modes is 32. Max modes can be less depending on block size. - // Half of the possible modes are transposed, which is indicated by a separate transpose flag - int8_t mip_modes[32]; - int8_t mip_trafo[32]; - double mip_costs[32]; - // The maximum number of possible MIP modes depend on block size & shape int width = LCU_WIDTH >> depth; int height = width; // TODO: proper height for non-square blocks. - int num_mip_modes = 0; - - if (enable_mip) { - for (int i = 0; i < 32; ++i) { - mip_modes[i] = i; - mip_costs[i] = MAX_INT; - } - // MIP is not allowed for 64 x 4 or 4 x 64 blocks - if (!((width == 64 && height == 4) || (width == 4 && height == 64))) { - num_mip_modes = NUM_MIP_MODES_FULL(width, height); - } - } // Find best intra mode for 2Nx2N. kvz_pixel *ref_pixels = &lcu->ref.y[lcu_px.x + lcu_px.y * LCU_WIDTH]; - int8_t number_of_modes[MAX_REF_LINE_IDX] = { 0 }; + // Need to set some data for all cus + cu_info_t temp_pred_cu; + FILL(temp_pred_cu, 0); + temp_pred_cu.depth = depth; + temp_pred_cu.type = CU_INTRA; + + int8_t number_of_modes; bool skip_rough_search = (depth == 0 || state->encoder_control->cfg.rdo >= 4); if (!skip_rough_search) { - number_of_modes[0] = search_intra_rough(state, - ref_pixels, LCU_WIDTH, + number_of_modes = search_intra_rough(state, + ref_pixels, + LCU_WIDTH, &refs, log2_width, candidate_modes, - modes[0], costs[0]); - // Copy rough results for other reference lines - for (int line = 1; line < MAX_REF_LINE_IDX; ++line) { - number_of_modes[line] = number_of_modes[0]; - for (int i = 0; i < number_of_modes[line]; ++i) { - modes[line][i] = modes[0][i]; - costs[line][i] = costs[0][i]; - } - } + search_data, &temp_pred_cu); + } else { - for(int line = 0; line < MAX_REF_LINE_IDX; ++line) { - number_of_modes[line] = 67; - for (int i = 0; i < number_of_modes[line]; ++i) { - modes[line][i] = i; - costs[line][i] = MAX_INT; + for (int8_t i = 0; i < KVZ_NUM_INTRA_MODES; i++) { + search_data[i].pred_cu = temp_pred_cu; + search_data[i].pred_cu.intra.mode = i; + search_data[i].pred_cu.intra.mode_chroma = i; + search_data[i].cost = MAX_INT; + } + number_of_modes = KVZ_NUM_INTRA_MODES; + } + + int num_mip_modes = 0; + if (state->encoder_control->cfg.mip) { + // MIP is not allowed for 64 x 4 or 4 x 64 blocks + if (!((width == 64 && height == 4) || (width == 4 && height == 64))) { + num_mip_modes = NUM_MIP_MODES_FULL(width, height); + } + for (int transpose = 0; transpose < 2; transpose++) { + const int half_mip_modes = NUM_MIP_MODES_HALF(width, height); + for (int i = 0; i < half_mip_modes; ++i) { + const int index = i + number_of_modes + transpose * half_mip_modes; + search_data[index].pred_cu = temp_pred_cu; + search_data[index].pred_cu.intra.mip_flag = 1; + search_data[index].pred_cu.intra.mode = i; + search_data[index].pred_cu.intra.mip_is_transposed = transpose; + search_data[index].pred_cu.intra.mode_chroma = 0; + search_data[index].cost = MAX_INT; } } + if(!skip_rough_search) { + + } + } + uint8_t lines = 1; // Find modes with multiple reference lines if in use. Do not use if CU in first row. if (state->encoder_control->cfg.mrl && (y_px % LCU_WIDTH) != 0) { @@ -1216,72 +1141,20 @@ void kvz_search_cu_intra( // Check only the predicted modes. number_of_modes_to_search = 0; } + sort_modes(search_data, number_of_modes); + + + // TODO: if rough search is implemented for MIP, sort mip_modes here. + search_intra_rdo( + state, + x_px, + y_px, + depth, + number_of_modes_to_search, + search_data, + lcu); - for(int8_t line = 0; line < lines; ++line) { - // For extra reference lines, only check predicted modes & no MIP search. - if (line != 0) { - number_of_modes_to_search = 0; - num_mip_modes = 0; - } - int num_modes_to_check = MIN(number_of_modes[line], number_of_modes_to_search); - kvz_sort_modes(modes[line], costs[line], number_of_modes[line]); - // TODO: if rough search is implemented for MIP, sort mip_modes here. - number_of_modes[line] = search_intra_rdo(state, - x_px, y_px, depth, - ref_pixels, LCU_WIDTH, - candidate_modes, - num_modes_to_check, - modes[line], trafo[line], costs[line], - num_mip_modes, - mip_modes, mip_trafo, mip_costs, - lcu, line); - } } - uint8_t best_line = 0; - double best_line_mode_cost = costs[0][0]; - uint8_t best_mip_mode_idx = 0; - uint8_t best_mode_indices[MAX_REF_LINE_IDX]; - - int8_t tmp_best_mode; - int8_t tmp_best_trafo; - double tmp_best_cost; - bool tmp_mip_flag = false; - bool tmp_mip_transp = false; - - for (int line = 0; line < lines; ++line) { - best_mode_indices[line] = select_best_mode_index(modes[line], costs[line], number_of_modes[line]); - if (best_line_mode_cost > costs[line][best_mode_indices[line]]) { - best_line_mode_cost = costs[line][best_mode_indices[line]]; - best_line = line; - } - } - - tmp_best_mode = modes[best_line][best_mode_indices[best_line]]; - tmp_best_trafo = trafo[best_line][best_mode_indices[best_line]]; - tmp_best_cost = costs[best_line][best_mode_indices[best_line]]; - - if (num_mip_modes) { - best_mip_mode_idx = select_best_mode_index(mip_modes, mip_costs, num_mip_modes); - if (tmp_best_cost > mip_costs[best_mip_mode_idx]) { - tmp_best_mode = mip_modes[best_mip_mode_idx]; - tmp_best_trafo = mip_trafo[best_mip_mode_idx]; - tmp_best_cost = mip_costs[best_mip_mode_idx]; - tmp_mip_flag = true; - tmp_mip_transp = (tmp_best_mode >= (num_mip_modes >> 1)) ? 1 : 0; - } - } - - if (tmp_mip_flag) { - // Transform best mode index to proper form. - // Max mode index is half of max number of modes - 1 (i. e. for size id 2, max mode id is 5) - tmp_best_mode = (tmp_mip_transp ? tmp_best_mode - (num_mip_modes >> 1) : tmp_best_mode); - } - - search_data->luma_mode = tmp_best_mode; - search_data->mts_idx = tmp_best_trafo; - *cost_out = tmp_best_cost; - search_data->mip_flag = tmp_mip_flag; - search_data->mip_transp = tmp_mip_transp; - search_data->multi_ref_idx = tmp_mip_flag ? 0 : best_line; + *mode_out = search_data[0]; }