Fix MRL to work when inter coding is enabled.

This commit is contained in:
siivonek 2021-11-19 15:12:58 +02:00
parent 0dc25b86e2
commit 65cf515070
5 changed files with 39 additions and 33 deletions

View file

@ -965,13 +965,13 @@ void kvz_intra_build_reference(
const lcu_t *const lcu, const lcu_t *const lcu,
kvz_intra_references *const refs, kvz_intra_references *const refs,
bool entropy_sync, bool entropy_sync,
kvz_pixel *extra_ref_lines) kvz_pixel *extra_ref_lines,
int8_t multi_ref_idx)
{ {
const vector2d_t lcu_px = { SUB_SCU(luma_px->x), SUB_SCU(luma_px->y) }; assert(extra_ref_lines == NULL && multi_ref_idx != 0 && "Trying to use MRL with NULL extra references.");
cu_info_t* cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
// Make this common case work with MRL, implement inner after this one works // Make this common case work with MRL, implement inner after this one works
kvz_intra_build_reference_any(log2_width, color, luma_px, pic_px, lcu, refs, cur_cu->intra.multi_ref_idx, extra_ref_lines); kvz_intra_build_reference_any(log2_width, color, luma_px, pic_px, lcu, refs, multi_ref_idx, extra_ref_lines);
// Much logic can be discarded if not on the edge // Much logic can be discarded if not on the edge
/*if (luma_px->x > 0 && luma_px->y > 0) { /*if (luma_px->x > 0 && luma_px->y > 0) {
@ -1029,7 +1029,7 @@ static void intra_recon_tb_leaf(
frame->rec->stride, 1); frame->rec->stride, 1);
} }
} }
kvz_intra_build_reference(log2width, color, &luma_px, &pic_px, lcu, &refs, cfg->wpp, extra_refs); kvz_intra_build_reference(log2width, color, &luma_px, &pic_px, lcu, &refs, cfg->wpp, extra_refs, cur_cu->intra.multi_ref_idx);
kvz_pixel pred[32 * 32]; kvz_pixel pred[32 * 32];
int stride = state->tile->frame->source->stride; int stride = state->tile->frame->source->stride;

View file

@ -88,6 +88,7 @@ int8_t kvz_intra_get_dir_luma_predictor(
* \param refs Pointer to top and left references. * \param refs Pointer to top and left references.
* \param entropy_sync Indicate that top right is not available if WPP is enabled. * \param entropy_sync Indicate that top right is not available if WPP is enabled.
* \param extra_refs Additional left edge reference lines for use with MRL. * \param extra_refs Additional left edge reference lines for use with MRL.
* \param multi_ref_idx Multi reference line index for the prediction block.
*/ */
void kvz_intra_build_reference( void kvz_intra_build_reference(
const int_fast8_t log2_width, const int_fast8_t log2_width,
@ -97,7 +98,8 @@ void kvz_intra_build_reference(
const lcu_t *const lcu, const lcu_t *const lcu,
kvz_intra_references *const refs, kvz_intra_references *const refs,
bool entropy_sync, bool entropy_sync,
kvz_pixel *extra_refs); kvz_pixel *extra_refs,
int8_t multi_ref_idx);
/** /**
* \brief Generate intra predictions. * \brief Generate intra predictions.

View file

@ -635,7 +635,6 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
cur_cu->type = CU_NOTSET; cur_cu->type = CU_NOTSET;
cur_cu->part_size = SIZE_2Nx2N; cur_cu->part_size = SIZE_2Nx2N;
cur_cu->qp = state->qp; cur_cu->qp = state->qp;
cur_cu->intra.multi_ref_idx = 0;
cur_cu->bdpcmMode = 0; cur_cu->bdpcmMode = 0;
cur_cu->tr_idx = 0; cur_cu->tr_idx = 0;
cur_cu->violates_mts_coeff_constraint = 0; cur_cu->violates_mts_coeff_constraint = 0;
@ -724,13 +723,15 @@ static double search_cu(encoder_state_t * const state, int x, int y, int depth,
int8_t intra_mode; int8_t intra_mode;
int8_t intra_trafo; int8_t intra_trafo;
double intra_cost; double intra_cost;
int8_t multi_ref_index = 0;
kvz_search_cu_intra(state, x, y, depth, lcu, kvz_search_cu_intra(state, x, y, depth, lcu,
&intra_mode, &intra_trafo, &intra_cost); &intra_mode, &intra_trafo, &intra_cost, &multi_ref_index);
if (intra_cost < cost) { if (intra_cost < cost) {
cost = intra_cost; cost = intra_cost;
cur_cu->type = CU_INTRA; cur_cu->type = CU_INTRA;
cur_cu->part_size = depth > MAX_DEPTH ? SIZE_NxN : SIZE_2Nx2N; cur_cu->part_size = depth > MAX_DEPTH ? SIZE_NxN : SIZE_2Nx2N;
cur_cu->intra.mode = intra_mode; cur_cu->intra.mode = intra_mode;
cur_cu->intra.multi_ref_idx = multi_ref_index;
//If the CU is not split from 64x64 block, the MTS is disabled for that CU. //If the CU is not split from 64x64 block, the MTS is disabled for that CU.
cur_cu->tr_idx = (depth > 0) ? intra_trafo : 0; cur_cu->tr_idx = (depth > 0) ? intra_trafo : 0;

View file

@ -715,7 +715,8 @@ static int8_t search_intra_rdo(encoder_state_t * const state,
int8_t *intra_preds, int8_t *intra_preds,
int modes_to_check, int modes_to_check,
int8_t modes[67], int8_t trafo[67], double costs[67], int8_t modes[67], int8_t trafo[67], double costs[67],
lcu_t *lcu) lcu_t *lcu,
int8_t multi_ref_idx)
{ {
const int tr_depth = CLIP(1, MAX_PU_DEPTH, depth + state->encoder_control->cfg.tr_depth_intra); 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 width = LCU_WIDTH >> depth;
@ -732,7 +733,7 @@ static int8_t search_intra_rdo(encoder_state_t * const state,
if (modes_to_check < 67) { if (modes_to_check < 67) {
int pred_mode = 0; int pred_mode = 0;
// Skip planar if searching modes for MRL // Skip planar if searching modes for MRL
if (cur_cu->intra.multi_ref_idx != 0) { if (multi_ref_idx != 0) {
pred_mode = 1; pred_mode = 1;
} }
for (; pred_mode < 6; pred_mode++) { for (; pred_mode < 6; pred_mode++) {
@ -762,6 +763,7 @@ static int8_t search_intra_rdo(encoder_state_t * const state,
pred_cu.part_size = ((depth == MAX_PU_DEPTH) ? SIZE_NxN : SIZE_2Nx2N); pred_cu.part_size = ((depth == MAX_PU_DEPTH) ? SIZE_NxN : SIZE_2Nx2N);
pred_cu.intra.mode = modes[rdo_mode]; pred_cu.intra.mode = modes[rdo_mode];
pred_cu.intra.mode_chroma = modes[rdo_mode]; pred_cu.intra.mode_chroma = modes[rdo_mode];
pred_cu.intra.multi_ref_idx = multi_ref_idx;
pred_cu.joint_cb_cr = 0; pred_cu.joint_cb_cr = 0;
FILL(pred_cu.cbf, 0); FILL(pred_cu.cbf, 0);
@ -991,10 +993,10 @@ int8_t kvz_search_cu_intra_chroma(encoder_state_t * const state,
const vector2d_t luma_px = { x_px, y_px }; const vector2d_t luma_px = { x_px, y_px };
kvz_intra_references refs_u; kvz_intra_references refs_u;
kvz_intra_build_reference(log2_width_c, COLOR_U, &luma_px, &pic_px, lcu, &refs_u, state->encoder_control->cfg.wpp, NULL); kvz_intra_build_reference(log2_width_c, COLOR_U, &luma_px, &pic_px, lcu, &refs_u, state->encoder_control->cfg.wpp, NULL, 0);
kvz_intra_references refs_v; kvz_intra_references refs_v;
kvz_intra_build_reference(log2_width_c, COLOR_V, &luma_px, &pic_px, lcu, &refs_v, state->encoder_control->cfg.wpp, NULL); kvz_intra_build_reference(log2_width_c, COLOR_V, &luma_px, &pic_px, lcu, &refs_v, state->encoder_control->cfg.wpp, NULL, 0);
vector2d_t lcu_cpx = { lcu_px.x / 2, lcu_px.y / 2 }; vector2d_t lcu_cpx = { lcu_px.x / 2, lcu_px.y / 2 };
kvz_pixel *ref_u = &lcu->ref.u[lcu_cpx.x + lcu_cpx.y * LCU_WIDTH_C]; kvz_pixel *ref_u = &lcu->ref.u[lcu_cpx.x + lcu_cpx.y * LCU_WIDTH_C];
@ -1024,7 +1026,8 @@ void kvz_search_cu_intra(encoder_state_t * const state,
const int depth, lcu_t *lcu, const int depth, lcu_t *lcu,
int8_t *mode_out, int8_t *mode_out,
int8_t *trafo_out, int8_t *trafo_out,
double *cost_out) double *cost_out,
int8_t *multi_ref_idx_out)
{ {
const vector2d_t lcu_px = { SUB_SCU(x_px), SUB_SCU(y_px) }; const vector2d_t lcu_px = { SUB_SCU(x_px), SUB_SCU(y_px) };
const int8_t cu_width = LCU_WIDTH >> depth; const int8_t cu_width = LCU_WIDTH >> depth;
@ -1054,23 +1057,24 @@ void kvz_search_cu_intra(encoder_state_t * const state,
const vector2d_t pic_px = { state->tile->frame->width, state->tile->frame->height }; const vector2d_t pic_px = { state->tile->frame->width, state->tile->frame->height };
// Extra reference lines for use with MRL. Extra lines needed only for left edge. // Extra reference lines for use with MRL. Extra lines needed only for left edge.
kvz_pixel extra_refs[2 * 128 * MAX_REF_LINE_IDX] = {0}; //kvz_pixel extra_refs[2 * 128 * MAX_REF_LINE_IDX] = {0};
if (x_px > 0 && lcu_px.x == 0 && lcu_px.y > 0) { //if (x_px > 0 && lcu_px.x == 0 && lcu_px.y > 0) {
videoframe_t* const frame = state->tile->frame; // videoframe_t* const frame = state->tile->frame;
// Copy extra ref lines, including ref line 1 and top left corner. // // Copy extra ref lines, including ref line 1 and top left corner.
for (int i = 0; i < MAX_REF_LINE_IDX; ++i) { // for (int i = 0; i < MAX_REF_LINE_IDX; ++i) {
int height = (LCU_WIDTH >> depth) * 2 + MAX_REF_LINE_IDX; // int height = (LCU_WIDTH >> depth) * 2 + MAX_REF_LINE_IDX;
height = MIN(height, pic_px.y - (y_px - MAX_REF_LINE_IDX)); // height = MIN(height, pic_px.y - (y_px - MAX_REF_LINE_IDX));
kvz_pixels_blit(&frame->rec->y[(y_px - MAX_REF_LINE_IDX) * frame->rec->stride + x_px - (1 + i)], // kvz_pixels_blit(&frame->rec->y[(y_px - MAX_REF_LINE_IDX) * frame->rec->stride + x_px - (1 + i)],
&extra_refs[i * 2 * 128], // &extra_refs[i * 2 * 128],
1, height, // 1, height,
frame->rec->stride, 1); // frame->rec->stride, 1);
} // }
} //}
kvz_intra_build_reference(log2_width, COLOR_Y, &luma_px, &pic_px, lcu, &refs, state->encoder_control->cfg.wpp, extra_refs); // These references will only be used with rough search. No need for MRL stuff here.
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 modes[MAX_REF_LINE_IDX][67];
@ -1127,20 +1131,19 @@ void kvz_search_cu_intra(encoder_state_t * const state,
number_of_modes_to_search = 0; number_of_modes_to_search = 0;
} }
for(int line = 0; line < lines; ++line) { for(int8_t line = 0; line < lines; ++line) {
// For extra reference lines, only check predicted modes // For extra reference lines, only check predicted modes
if (line != 0) { if (line != 0) {
number_of_modes_to_search = 0; number_of_modes_to_search = 0;
} }
int num_modes_to_check = MIN(number_of_modes[line], number_of_modes_to_search); int num_modes_to_check = MIN(number_of_modes[line], number_of_modes_to_search);
cur_cu->intra.multi_ref_idx = line;
kvz_sort_modes(modes[line], costs[line], number_of_modes[line]); kvz_sort_modes(modes[line], costs[line], number_of_modes[line]);
number_of_modes[line] = search_intra_rdo(state, number_of_modes[line] = search_intra_rdo(state,
x_px, y_px, depth, x_px, y_px, depth,
ref_pixels, LCU_WIDTH, ref_pixels, LCU_WIDTH,
candidate_modes, candidate_modes,
num_modes_to_check, num_modes_to_check,
modes[line], trafo[line], costs[line], lcu); modes[line], trafo[line], costs[line], lcu, line);
} }
} }
@ -1155,9 +1158,8 @@ void kvz_search_cu_intra(encoder_state_t * const state,
} }
} }
cur_cu->intra.multi_ref_idx = best_line;
*mode_out = modes[best_line][best_mode_indices[best_line]]; *mode_out = modes[best_line][best_mode_indices[best_line]];
*trafo_out = trafo[best_line][best_mode_indices[best_line]]; *trafo_out = trafo[best_line][best_mode_indices[best_line]];
*cost_out = costs[best_line][best_mode_indices[best_line]]; *cost_out = costs[best_line][best_mode_indices[best_line]];
*multi_ref_idx_out = best_line;
} }

View file

@ -59,6 +59,7 @@ void kvz_search_cu_intra(encoder_state_t * const state,
const int depth, lcu_t *lcu, const int depth, lcu_t *lcu,
int8_t *mode_out, int8_t *mode_out,
int8_t *trafo_out, int8_t *trafo_out,
double *cost_out); double *cost_out,
int8_t *multi_ref_idx_out);
#endif // SEARCH_INTRA_H_ #endif // SEARCH_INTRA_H_