From 46cf9b6871924b40266a4133bc7fcda7a50c461e Mon Sep 17 00:00:00 2001 From: Ari Lemmetti Date: Mon, 6 Sep 2021 19:56:06 +0300 Subject: [PATCH] [SIMD] Make strategy out of PDPC for planar and DC --- src/intra.c | 15 +----------- src/strategies/generic/intra-generic.c | 34 ++++++++++++++++++++++++++ src/strategies/strategies-intra.c | 1 + src/strategies/strategies-intra.h | 10 ++++++++ 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/intra.c b/src/intra.c index d5924c01..fcb4aada 100644 --- a/src/intra.c +++ b/src/intra.c @@ -289,20 +289,7 @@ void kvz_intra_predict( //bool pdpcCondition = (mode == 0 || mode == 1 || mode == 18 || mode == 50); //if (pdpcCondition) { - // TODO: replace latter log2_width with log2_height - const int scale = ((log2_width - 2 + log2_width - 2 + 2) >> 2); - - if (mode == 0 || mode == 1) { // planar or DC - // TODO: replace width with height - for (int y = 0; y < width; y++) { - int wT = 32 >> MIN(31, ((y << 1) >> scale)); - for (int x = 0; x < width; x++) { - int wL = 32 >> MIN(31, ((x << 1) >> scale)); - dst[x + y * width] = dst[x + y * width] + ((wL * (used_ref->left[y + 1] - dst[x + y * width]) - + wT * (used_ref->top[x + 1] - dst[x + y * width]) + 32) >> 6); - } - } - } + kvz_pdpc_planar_dc(mode, width, log2_width, used_ref, dst); } } diff --git a/src/strategies/generic/intra-generic.c b/src/strategies/generic/intra-generic.c index 3a4af314..0caac133 100644 --- a/src/strategies/generic/intra-generic.c +++ b/src/strategies/generic/intra-generic.c @@ -22,6 +22,7 @@ #include +#include "intra.h" #include "kvazaar.h" #include "strategyselector.h" #include "kvz_math.h" @@ -455,6 +456,38 @@ static void kvz_intra_pred_filtered_dc_generic( } } +// TODO: update all ranges from HEVC to VVC + +/** +* \brief Position Dependent Prediction Combination for Planar and DC modes. +* \param log2_width Log2 of width, range 2..5. +* \param width Block width matching log2_width. +* \param used_ref Pointer used reference pixel struct. +* \param dst Buffer of size width*width. +*/ +static void kvz_pdpc_planar_dc_generic( + const int mode, + const int width, + const int log2_width, + const kvz_intra_ref *const used_ref, + kvz_pixel *const dst) +{ + // TODO: replace latter log2_width with log2_height + const int scale = ((log2_width - 2 + log2_width - 2 + 2) >> 2); + + if (mode == 0 || mode == 1) { // planar or DC + // TODO: replace width with height + for (int y = 0; y < width; y++) { + int wT = 32 >> MIN(31, ((y << 1) >> scale)); + for (int x = 0; x < width; x++) { + int wL = 32 >> MIN(31, ((x << 1) >> scale)); + dst[x + y * width] = dst[x + y * width] + ((wL * (used_ref->left[y + 1] - dst[x + y * width]) + + wT * (used_ref->top[x + 1] - dst[x + y * width]) + 32) >> 6); + } + } + } +} + int kvz_strategy_register_intra_generic(void* opaque, uint8_t bitdepth) { @@ -463,6 +496,7 @@ int kvz_strategy_register_intra_generic(void* opaque, uint8_t bitdepth) success &= kvz_strategyselector_register(opaque, "angular_pred", "generic", 0, &kvz_angular_pred_generic); success &= kvz_strategyselector_register(opaque, "intra_pred_planar", "generic", 0, &kvz_intra_pred_planar_generic); success &= kvz_strategyselector_register(opaque, "intra_pred_filtered_dc", "generic", 0, &kvz_intra_pred_filtered_dc_generic); + success &= kvz_strategyselector_register(opaque, "pdpc_planar_dc", "generic", 0, &kvz_pdpc_planar_dc_generic); return success; } diff --git a/src/strategies/strategies-intra.c b/src/strategies/strategies-intra.c index c4de7353..ff6fcbe6 100644 --- a/src/strategies/strategies-intra.c +++ b/src/strategies/strategies-intra.c @@ -29,6 +29,7 @@ angular_pred_func *kvz_angular_pred; intra_pred_planar_func *kvz_intra_pred_planar; intra_pred_filtered_dc_func *kvz_intra_pred_filtered_dc; +pdpc_planar_dc_func *kvz_pdpc_planar_dc; int kvz_strategy_register_intra(void* opaque, uint8_t bitdepth) { bool success = true; diff --git a/src/strategies/strategies-intra.h b/src/strategies/strategies-intra.h index 04050921..ee4a3bcc 100644 --- a/src/strategies/strategies-intra.h +++ b/src/strategies/strategies-intra.h @@ -27,6 +27,7 @@ */ #include "global.h" // IWYU pragma: keep +#include "intra.h" #include "kvazaar.h" @@ -50,10 +51,18 @@ typedef void (intra_pred_filtered_dc_func)( const kvz_pixel *const ref_left, kvz_pixel *const out_block); +typedef void (pdpc_planar_dc_func)( + const int mode, + const int width, + const int log2_width, + const kvz_intra_ref *const used_ref, + kvz_pixel *const dst); + // Declare function pointers. extern angular_pred_func * kvz_angular_pred; extern intra_pred_planar_func * kvz_intra_pred_planar; extern intra_pred_filtered_dc_func * kvz_intra_pred_filtered_dc; +extern pdpc_planar_dc_func * kvz_pdpc_planar_dc; int kvz_strategy_register_intra(void* opaque, uint8_t bitdepth); @@ -62,6 +71,7 @@ int kvz_strategy_register_intra(void* opaque, uint8_t bitdepth); {"angular_pred", (void**) &kvz_angular_pred}, \ {"intra_pred_planar", (void**) &kvz_intra_pred_planar}, \ {"intra_pred_filtered_dc", (void**) &kvz_intra_pred_filtered_dc}, \ + {"pdpc_planar_dc", (void**) &kvz_pdpc_planar_dc}, \