mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
Fix MRL to work when inter coding is enabled.
This commit is contained in:
parent
0dc25b86e2
commit
65cf515070
10
src/intra.c
10
src/intra.c
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_
|
||||
|
|
Loading…
Reference in a new issue