mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-27 11:24:05 +00:00
[mrl] Pass multi_ref_idx to generic angular and DC prediction funcs. Fix some outdated comments.
This commit is contained in:
parent
a5dc2a3ce1
commit
511ce4991b
35
src/intra.c
35
src/intra.c
|
@ -212,24 +212,26 @@ static void intra_filter_reference(
|
|||
|
||||
|
||||
/**
|
||||
* \brief Generage planar prediction.
|
||||
* \brief Generate dc prediction.
|
||||
* \param log2_width Log2 of width, range 2..5.
|
||||
* \param in_ref_above Pointer to -1 index of above reference, length=width*2+1.
|
||||
* \param in_ref_left Pointer to -1 index of left reference, length=width*2+1.
|
||||
* \param ref_top Pointer to -1 index of above reference, length=width*2+1.
|
||||
* \param ref_left Pointer to -1 index of left reference, length=width*2+1.
|
||||
* \param dst Buffer of size width*width.
|
||||
* \param multi_ref_idx Multi reference line index for use with MRL.
|
||||
*/
|
||||
static void intra_pred_dc(
|
||||
const int_fast8_t log2_width,
|
||||
const kvz_pixel *const ref_top,
|
||||
const kvz_pixel *const ref_left,
|
||||
kvz_pixel *const out_block)
|
||||
kvz_pixel *const out_block,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
int_fast8_t width = 1 << log2_width;
|
||||
|
||||
int_fast16_t sum = 0;
|
||||
for (int_fast8_t i = 0; i < width; ++i) {
|
||||
sum += ref_top[i + 1];
|
||||
sum += ref_left[i + 1];
|
||||
sum += ref_top[i + 1 + multi_ref_idx];
|
||||
sum += ref_left[i + 1 + multi_ref_idx];
|
||||
}
|
||||
|
||||
// JVET_K0122
|
||||
|
@ -549,11 +551,15 @@ void kvz_intra_predict(
|
|||
int_fast8_t mode,
|
||||
color_t color,
|
||||
kvz_pixel *dst,
|
||||
bool filter_boundary)
|
||||
bool filter_boundary,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
const int_fast8_t width = 1 << log2_width;
|
||||
const kvz_config *cfg = &state->encoder_control->cfg;
|
||||
|
||||
// MRL only for luma
|
||||
uint8_t multi_ref_index = color == COLOR_Y ? multi_ref_idx : 0;
|
||||
|
||||
const kvz_intra_ref *used_ref = &refs->ref;
|
||||
if (cfg->intra_smoothing_disabled || color != COLOR_Y || mode == 1 || width == 4) {
|
||||
// For chroma, DC and 4x4 blocks, always use unfiltered reference.
|
||||
|
@ -586,9 +592,9 @@ void kvz_intra_predict(
|
|||
if (mode == 0) {
|
||||
kvz_intra_pred_planar(log2_width, used_ref->top, used_ref->left, dst);
|
||||
} else if (mode == 1) {
|
||||
intra_pred_dc(log2_width, used_ref->top, used_ref->left, dst);
|
||||
intra_pred_dc(log2_width, used_ref->top, used_ref->left, dst, multi_ref_index);
|
||||
} else {
|
||||
kvz_angular_pred(log2_width, mode, color, used_ref->top, used_ref->left, dst);
|
||||
kvz_angular_pred(log2_width, mode, color, used_ref->top, used_ref->left, dst, multi_ref_index);
|
||||
}
|
||||
|
||||
// pdpc
|
||||
|
@ -608,7 +614,7 @@ void kvz_intra_build_reference_any(
|
|||
const vector2d_t *const pic_px,
|
||||
const lcu_t *const lcu,
|
||||
kvz_intra_references *const refs,
|
||||
const uint8_t mri)
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
assert(log2_width >= 2 && log2_width <= 5);
|
||||
|
||||
|
@ -621,7 +627,7 @@ void kvz_intra_build_reference_any(
|
|||
const int_fast8_t width = 1 << log2_width;
|
||||
|
||||
// Get multiRefIdx from CU under prediction. Do not use MRL if not luma
|
||||
const uint8_t multi_ref_index = !is_chroma ? mri : 0;
|
||||
const uint8_t multi_ref_index = !is_chroma ? multi_ref_idx : 0;
|
||||
|
||||
// Convert luma coordinates to chroma coordinates for chroma.
|
||||
const vector2d_t lcu_px = {
|
||||
|
@ -737,7 +743,7 @@ void kvz_intra_build_reference_inner(
|
|||
const lcu_t *const lcu,
|
||||
kvz_intra_references *const refs,
|
||||
bool entropy_sync,
|
||||
const uint8_t mri)
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
assert(log2_width >= 2 && log2_width <= 5);
|
||||
|
||||
|
@ -749,7 +755,7 @@ void kvz_intra_build_reference_inner(
|
|||
const int_fast8_t width = 1 << log2_width;
|
||||
|
||||
// Get multiRefIdx from CU under prediction. Do not use MRL if not luma
|
||||
const uint8_t multi_ref_index = !is_chroma ? mri : 0;
|
||||
const uint8_t multi_ref_index = !is_chroma ? multi_ref_idx : 0;
|
||||
|
||||
// Convert luma coordinates to chroma coordinates for chroma.
|
||||
const vector2d_t lcu_px = {
|
||||
|
@ -915,6 +921,7 @@ static void intra_recon_tb_leaf(
|
|||
int x_scu = SUB_SCU(x);
|
||||
int y_scu = SUB_SCU(y);
|
||||
const vector2d_t lcu_px = {x_scu >> shift, y_scu >> shift };
|
||||
cu_info_t* cur_cu = LCU_GET_CU_AT_PX(lcu, lcu_px.x, lcu_px.y);
|
||||
|
||||
kvz_intra_references refs;
|
||||
kvz_intra_build_reference(log2width, color, &luma_px, &pic_px, lcu, &refs, cfg->wpp);
|
||||
|
@ -923,7 +930,7 @@ static void intra_recon_tb_leaf(
|
|||
int stride = state->tile->frame->source->stride;
|
||||
const bool filter_boundary = color == COLOR_Y && !(cfg->lossless && cfg->implicit_rdpcm);
|
||||
if(intra_mode < 68) {
|
||||
kvz_intra_predict(state, &refs, log2width, intra_mode, color, pred, filter_boundary);
|
||||
kvz_intra_predict(state, &refs, log2width, intra_mode, color, pred, filter_boundary, cur_cu->intra.multi_ref_idx);
|
||||
} else {
|
||||
kvz_pixels_blit(&state->tile->frame->cclm_luma_rec[x / 2 + (y * stride) / 4], pred, width, width, stride / 2, width);
|
||||
if(cclm_params == NULL) {
|
||||
|
|
19
src/intra.h
19
src/intra.h
|
@ -79,14 +79,14 @@ int8_t kvz_intra_get_dir_luma_predictor(
|
|||
const cu_info_t *const above_pu);
|
||||
|
||||
/**
|
||||
* \brief Generage angular predictions.
|
||||
* \param width Width in pixels, range 4..32.
|
||||
* \param color What color pixels to use.
|
||||
* \param luma_px Luma coordinates of the prediction block.
|
||||
* \param pic_px Picture dimensions in luma pixels.
|
||||
* \param lcu LCU struct.
|
||||
* \param out_left_ref Left reference pixels, index 0 is the top-left.
|
||||
* \param out_top_ref Top reference pixels, index 0 is the top-left.
|
||||
* \brief Build intra prediction reference buffers.
|
||||
* \param log2_width Log2 of width, range 2..5.
|
||||
* \param color What color pixels to use.
|
||||
* \param luma_px Luma coordinates of the prediction block.
|
||||
* \param pic_px Picture dimensions in luma pixels.
|
||||
* \param lcu LCU struct.
|
||||
* \param refs Pointer to top and left references.
|
||||
* \param entropy_sync Indicate that top right is not available if WPP is enabled.
|
||||
*/
|
||||
void kvz_intra_build_reference(
|
||||
const int_fast8_t log2_width,
|
||||
|
@ -113,7 +113,8 @@ void kvz_intra_predict(
|
|||
int_fast8_t mode,
|
||||
color_t color,
|
||||
kvz_pixel *dst,
|
||||
bool filter_boundary);
|
||||
bool filter_boundary,
|
||||
const uint8_t multi_ref_idx);
|
||||
|
||||
void kvz_intra_recon_cu(
|
||||
encoder_state_t *const state,
|
||||
|
|
|
@ -480,7 +480,7 @@ static void search_intra_chroma_rough(encoder_state_t * const state,
|
|||
kvz_pixels_blit(orig_u, orig_block, width, width, origstride, width);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (modes[i] == -1) continue;
|
||||
kvz_intra_predict(state, refs_u, log2_width_c, modes[i], COLOR_U, pred, false);
|
||||
kvz_intra_predict(state, refs_u, log2_width_c, modes[i], COLOR_U, pred, false, 0);
|
||||
//costs[i] += get_cost(encoder_state, pred, orig_block, satd_func, sad_func, width);
|
||||
costs[i] += satd_func(pred, orig_block);
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ static void search_intra_chroma_rough(encoder_state_t * const state,
|
|||
kvz_pixels_blit(orig_v, orig_block, width, width, origstride, width);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
if (modes[i] == -1) continue;
|
||||
kvz_intra_predict(state, refs_v, log2_width_c, modes[i], COLOR_V, pred, false);
|
||||
kvz_intra_predict(state, refs_v, log2_width_c, modes[i], COLOR_V, pred, false, 0);
|
||||
//costs[i] += get_cost(encoder_state, pred, orig_block, satd_func, sad_func, width);
|
||||
costs[i] += satd_func(pred, orig_block);
|
||||
}
|
||||
|
@ -588,7 +588,7 @@ static int8_t search_intra_rough(encoder_state_t * const state,
|
|||
double costs_out[PARALLEL_BLKS] = { 0 };
|
||||
for (int i = 0; i < PARALLEL_BLKS; ++i) {
|
||||
if (mode + i * offset <= 66) {
|
||||
kvz_intra_predict(state, refs, log2_width, mode + i * offset, COLOR_Y, preds[i], filter_boundary);
|
||||
kvz_intra_predict(state, refs, log2_width, mode + i * offset, COLOR_Y, preds[i], filter_boundary, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -627,7 +627,7 @@ static int8_t search_intra_rough(encoder_state_t * const state,
|
|||
if (mode_in_range) {
|
||||
for (int i = 0; i < PARALLEL_BLKS; ++i) {
|
||||
if (test_modes[i] >= 2 && test_modes[i] <= 66) {
|
||||
kvz_intra_predict(state, refs, log2_width, test_modes[i], COLOR_Y, preds[i], filter_boundary);
|
||||
kvz_intra_predict(state, refs, log2_width, test_modes[i], COLOR_Y, preds[i], filter_boundary, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,7 +664,7 @@ static int8_t search_intra_rough(encoder_state_t * const state,
|
|||
}
|
||||
|
||||
if (!has_mode) {
|
||||
kvz_intra_predict(state, refs, log2_width, mode, COLOR_Y, preds[0], filter_boundary);
|
||||
kvz_intra_predict(state, refs, log2_width, mode, COLOR_Y, preds[0], filter_boundary, 0);
|
||||
costs[modes_selected] = get_cost(state, preds[0], orig_block, satd_func, sad_func, width);
|
||||
modes[modes_selected] = mode;
|
||||
++modes_selected;
|
||||
|
|
|
@ -446,6 +446,25 @@ static void kvz_angular_pred_avx2(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generage angular predictions.
|
||||
* \param log2_width Log2 of width, range 2..5.
|
||||
* \param intra_mode Angular mode in range 2..34.
|
||||
* \param in_ref_above Pointer to -1 index of above reference, length=width*2+1.
|
||||
* \param in_ref_left Pointer to -1 index of left reference, length=width*2+1.
|
||||
* \param dst Buffer of size width*width.
|
||||
* \param multi_ref_idx Multi reference line index for use with MRL.
|
||||
*/
|
||||
static void kvz_angular_pred_avx2(
|
||||
const int_fast8_t log2_width,
|
||||
const int_fast8_t intra_mode,
|
||||
const uint8_t *const in_ref_above,
|
||||
const uint8_t *const in_ref_left,
|
||||
uint8_t *const dst,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
assert(log2_width >= 2 && log2_width <= 5);
|
||||
assert(intra_mode >= 2 && intra_mode <= 34);
|
||||
// Flip the block if this is was a horizontal mode.
|
||||
if (!vertical_mode) {
|
||||
|
||||
|
@ -459,6 +478,12 @@ static void kvz_angular_pred_avx2(
|
|||
const __m128i vseq = _mm_setr_epi32(0, 1, 2, 3);
|
||||
const __m128i vidx = _mm_slli_epi32(vseq, log2_width);
|
||||
|
||||
// TODO: implement usage of multi_ref_idx
|
||||
|
||||
// Temporary buffer for modes 11-25.
|
||||
// It only needs to be big enough to hold indices from -width to width-1.
|
||||
uint8_t tmp_ref[2 * 32];
|
||||
const int_fast8_t width = 1 << log2_width;
|
||||
// Transpose as 4x4 subblocks
|
||||
for (int_fast32_t y = 0; y + 3 < width; y += 4) {
|
||||
for (int_fast32_t x = y; x + 3 < width; x += 4) {
|
||||
|
@ -590,7 +615,8 @@ static void kvz_intra_pred_planar_avx2(
|
|||
// addends etc can be preinitialized for each position.
|
||||
static void pred_filtered_dc_4x4(const uint8_t *ref_top,
|
||||
const uint8_t *ref_left,
|
||||
uint8_t *out_block)
|
||||
uint8_t *out_block,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
const uint32_t rt_u32 = *(const uint32_t *)(ref_top + 1);
|
||||
const uint32_t rl_u32 = *(const uint32_t *)(ref_left + 1);
|
||||
|
@ -651,7 +677,8 @@ static void pred_filtered_dc_4x4(const uint8_t *ref_top,
|
|||
|
||||
static void pred_filtered_dc_8x8(const uint8_t *ref_top,
|
||||
const uint8_t *ref_left,
|
||||
uint8_t *out_block)
|
||||
uint8_t *out_block,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
const uint64_t rt_u64 = *(const uint64_t *)(ref_top + 1);
|
||||
const uint64_t rl_u64 = *(const uint64_t *)(ref_left + 1);
|
||||
|
@ -755,7 +782,8 @@ static INLINE __m256i cvt_u32_si256(const uint32_t u)
|
|||
|
||||
static void pred_filtered_dc_16x16(const uint8_t *ref_top,
|
||||
const uint8_t *ref_left,
|
||||
uint8_t *out_block)
|
||||
uint8_t *out_block,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
const __m128i rt_128 = _mm_loadu_si128((const __m128i *)(ref_top + 1));
|
||||
const __m128i rl_128 = _mm_loadu_si128((const __m128i *)(ref_left + 1));
|
||||
|
@ -831,7 +859,8 @@ static void pred_filtered_dc_16x16(const uint8_t *ref_top,
|
|||
|
||||
static void pred_filtered_dc_32x32(const uint8_t *ref_top,
|
||||
const uint8_t *ref_left,
|
||||
uint8_t *out_block)
|
||||
uint8_t *out_block,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
const __m256i rt = _mm256_loadu_si256((const __m256i *)(ref_top + 1));
|
||||
const __m256i rl = _mm256_loadu_si256((const __m256i *)(ref_left + 1));
|
||||
|
@ -913,23 +942,26 @@ static void pred_filtered_dc_32x32(const uint8_t *ref_top,
|
|||
* \param in_ref_above Pointer to -1 index of above reference, length=width*2+1.
|
||||
* \param in_ref_left Pointer to -1 index of left reference, length=width*2+1.
|
||||
* \param dst Buffer of size width*width.
|
||||
* \param multi_ref_idx Reference line index. May be non-zero when MRL is used.
|
||||
*/
|
||||
static void kvz_intra_pred_filtered_dc_avx2(
|
||||
const int_fast8_t log2_width,
|
||||
const uint8_t *ref_top,
|
||||
const uint8_t *ref_left,
|
||||
uint8_t *out_block)
|
||||
uint8_t *out_block,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
assert(log2_width >= 2 && log2_width <= 5);
|
||||
|
||||
// TODO: implement multi reference index for all subfunctions
|
||||
if (log2_width == 2) {
|
||||
pred_filtered_dc_4x4(ref_top, ref_left, out_block);
|
||||
pred_filtered_dc_4x4(ref_top, ref_left, out_block, multi_ref_idx);
|
||||
} else if (log2_width == 3) {
|
||||
pred_filtered_dc_8x8(ref_top, ref_left, out_block);
|
||||
pred_filtered_dc_8x8(ref_top, ref_left, out_block, multi_ref_idx);
|
||||
} else if (log2_width == 4) {
|
||||
pred_filtered_dc_16x16(ref_top, ref_left, out_block);
|
||||
pred_filtered_dc_16x16(ref_top, ref_left, out_block, multi_ref_idx);
|
||||
} else if (log2_width == 5) {
|
||||
pred_filtered_dc_32x32(ref_top, ref_left, out_block);
|
||||
pred_filtered_dc_32x32(ref_top, ref_left, out_block, multi_ref_idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
* \param in_ref_above Pointer to -1 index of above reference, length=width*2+1.
|
||||
* \param in_ref_left Pointer to -1 index of left reference, length=width*2+1.
|
||||
* \param dst Buffer of size width*width.
|
||||
* \param multi_ref_idx Multi reference line index for use with MRL.
|
||||
*/
|
||||
static void kvz_angular_pred_generic(
|
||||
const int_fast8_t log2_width,
|
||||
|
@ -56,7 +57,8 @@ static void kvz_angular_pred_generic(
|
|||
const int_fast8_t channel_type,
|
||||
const kvz_pixel *const in_ref_above,
|
||||
const kvz_pixel *const in_ref_left,
|
||||
kvz_pixel *const dst)
|
||||
kvz_pixel *const dst,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
|
||||
assert(log2_width >= 2 && log2_width <= 5);
|
||||
|
@ -113,8 +115,7 @@ static void kvz_angular_pred_generic(
|
|||
|
||||
uint32_t pred_mode = intra_mode; // ToDo: handle WAIP
|
||||
|
||||
// TODO: pass the multiRefIdx to this function and assign to this variable
|
||||
uint8_t multi_ref_index = 0;
|
||||
uint8_t multi_ref_index = multi_ref_idx;
|
||||
|
||||
// Whether to swap references to always project on the left reference row.
|
||||
const bool vertical_mode = intra_mode >= 34;
|
||||
|
@ -418,12 +419,14 @@ static void kvz_intra_pred_planar_generic(
|
|||
* \param in_ref_above Pointer to -1 index of above reference, length=width*2+1.
|
||||
* \param in_ref_left Pointer to -1 index of left reference, length=width*2+1.
|
||||
* \param dst Buffer of size width*width.
|
||||
* \param multi_ref_idx Reference line index. May be non-zero when MRL is used.
|
||||
*/
|
||||
static void kvz_intra_pred_filtered_dc_generic(
|
||||
const int_fast8_t log2_width,
|
||||
const kvz_pixel *const ref_top,
|
||||
const kvz_pixel *const ref_left,
|
||||
kvz_pixel *const out_block)
|
||||
kvz_pixel *const out_block,
|
||||
const uint8_t multi_ref_idx)
|
||||
{
|
||||
assert(log2_width >= 2 && log2_width <= 5);
|
||||
|
||||
|
@ -432,8 +435,8 @@ static void kvz_intra_pred_filtered_dc_generic(
|
|||
|
||||
int_fast16_t sum = 0;
|
||||
for (int_fast8_t i = 0; i < width; ++i) {
|
||||
sum += ref_top[i + 1];
|
||||
sum += ref_left[i + 1];
|
||||
sum += ref_top[i + 1 + multi_ref_idx];
|
||||
sum += ref_left[i + 1 + multi_ref_idx];
|
||||
}
|
||||
|
||||
const kvz_pixel dc_val = (sum + width) >> (log2_width + 1);
|
||||
|
|
|
@ -49,7 +49,8 @@ typedef void (angular_pred_func)(
|
|||
const int_fast8_t channel_type,
|
||||
const kvz_pixel *const in_ref_above,
|
||||
const kvz_pixel *const in_ref_left,
|
||||
kvz_pixel *const dst);
|
||||
kvz_pixel *const dst,
|
||||
const uint8_t multi_ref_idx);
|
||||
|
||||
typedef void (intra_pred_planar_func)(
|
||||
const int_fast8_t log2_width,
|
||||
|
@ -61,7 +62,8 @@ typedef void (intra_pred_filtered_dc_func)(
|
|||
const int_fast8_t log2_width,
|
||||
const kvz_pixel *const ref_top,
|
||||
const kvz_pixel *const ref_left,
|
||||
kvz_pixel *const out_block);
|
||||
kvz_pixel *const out_block,
|
||||
const uint8_t multi_ref_idx);
|
||||
|
||||
typedef void (pdpc_planar_dc_func)(
|
||||
const int mode,
|
||||
|
|
Loading…
Reference in a new issue