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,
kvz_intra_references *const refs,
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) };
cu_info_t* cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
assert(extra_ref_lines == NULL && multi_ref_idx != 0 && "Trying to use MRL with NULL extra references.");
// 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
/*if (luma_px->x > 0 && luma_px->y > 0) {
@ -1029,7 +1029,7 @@ static void intra_recon_tb_leaf(
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];
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 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 multi_ref_idx Multi reference line index for the prediction block.
*/
void kvz_intra_build_reference(
const int_fast8_t log2_width,
@ -97,7 +98,8 @@ void kvz_intra_build_reference(
const lcu_t *const lcu,
kvz_intra_references *const refs,
bool entropy_sync,
kvz_pixel *extra_refs);
kvz_pixel *extra_refs,
int8_t multi_ref_idx);
/**
* \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->part_size = SIZE_2Nx2N;
cur_cu->qp = state->qp;
cur_cu->intra.multi_ref_idx = 0;
cur_cu->bdpcmMode = 0;
cur_cu->tr_idx = 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_trafo;
double intra_cost;
int8_t multi_ref_index = 0;
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) {
cost = intra_cost;
cur_cu->type = CU_INTRA;
cur_cu->part_size = depth > MAX_DEPTH ? SIZE_NxN : SIZE_2Nx2N;
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.
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,
int modes_to_check,
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 width = LCU_WIDTH >> depth;
@ -732,7 +733,7 @@ static int8_t search_intra_rdo(encoder_state_t * const state,
if (modes_to_check < 67) {
int pred_mode = 0;
// Skip planar if searching modes for MRL
if (cur_cu->intra.multi_ref_idx != 0) {
if (multi_ref_idx != 0) {
pred_mode = 1;
}
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.intra.mode = 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;
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 };
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_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 };
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,
int8_t *mode_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 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 };
// 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) {
videoframe_t* const frame = state->tile->frame;
//if (x_px > 0 && lcu_px.x == 0 && lcu_px.y > 0) {
// videoframe_t* const frame = state->tile->frame;
// Copy extra ref lines, including ref line 1 and top left corner.
for (int i = 0; i < MAX_REF_LINE_IDX; ++i) {
int height = (LCU_WIDTH >> depth) * 2 + 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)],
&extra_refs[i * 2 * 128],
1, height,
frame->rec->stride, 1);
}
}
// // Copy extra ref lines, including ref line 1 and top left corner.
// for (int i = 0; i < MAX_REF_LINE_IDX; ++i) {
// int height = (LCU_WIDTH >> depth) * 2 + 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)],
// &extra_refs[i * 2 * 128],
// 1, height,
// 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];
@ -1127,20 +1131,19 @@ void kvz_search_cu_intra(encoder_state_t * const state,
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
if (line != 0) {
number_of_modes_to_search = 0;
}
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]);
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], lcu);
modes[line], trafo[line], costs[line], lcu, line);
}
}
@ -1154,10 +1157,9 @@ void kvz_search_cu_intra(encoder_state_t * const state,
best_line = line;
}
}
cur_cu->intra.multi_ref_idx = best_line;
*mode_out = modes[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]];
*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,
int8_t *mode_out,
int8_t *trafo_out,
double *cost_out);
double *cost_out,
int8_t *multi_ref_idx_out);
#endif // SEARCH_INTRA_H_