From d2291fea83262fafee032781e7deff3bb26edb64 Mon Sep 17 00:00:00 2001 From: Sami Ahovainio Date: Thu, 30 Aug 2018 17:17:06 +0300 Subject: [PATCH] Intra mode scaling moved from angular prediction to kvz_intra_predict. pdpc implemented in kvz_intra_predict. --- src/intra.c | 64 +++++++++++++++++++++++++- src/strategies/generic/intra-generic.c | 13 ++---- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/intra.c b/src/intra.c index 0e3a0f23..516e9d69 100644 --- a/src/intra.c +++ b/src/intra.c @@ -299,6 +299,12 @@ void kvz_intra_predict( kvz_pixel *dst, bool filter_boundary) { + static const uint8_t intra_mode_33_to_65_angle[36] = + // H D V + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, DM + { 0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68 }; + mode = intra_mode_33_to_65_angle[mode]; + const int_fast8_t width = 1 << log2_width; const kvz_intra_ref *used_ref = &refs->ref; @@ -312,7 +318,7 @@ void kvz_intra_predict( // to being either vertical or horizontal. static const int kvz_intra_hor_ver_dist_thres[5] = { 0, 7, 1, 0, 0 }; int filter_threshold = kvz_intra_hor_ver_dist_thres[kvz_math_floor_log2(width) - 2]; - int dist_from_vert_or_hor = MIN(abs(mode - 26), abs(mode - 10)); + int dist_from_vert_or_hor = MIN(abs(mode - 50), abs(mode - 18)); if (dist_from_vert_or_hor > filter_threshold) { used_ref = &refs->filtered_ref; } @@ -342,6 +348,62 @@ void kvz_intra_predict( // } //} } + + // pdpc + 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) { // planar + // 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] = CLIP_TO_PIXEL((wL * used_ref->left[y + 1] + + wT * used_ref->top[x + 1] + + (64 - wL - wT) * dst[x + y * width] + 32) >> 6); + } + } + } + else if (mode == 1) { // DC + 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)); + int wTL = (wL >> 4) + (wT >> 4); + dst[x + y * width] = CLIP_TO_PIXEL((wL * used_ref->left[y + 1] + + wT * used_ref->top[x + 1] + - wTL * used_ref->top[0] + + (64 - wL - wT + wTL) * dst[x + y * width] + 32) >> 6); + } + } + } + else if (mode == 18) { // horizontal + for (int y = 0; y < width; y++) { + int wT = 32 >> MIN(31, ((y << 1) >> scale)); + for (int x = 0; x < width; x++) { + int wTL = wT; + dst[x + y * width] = CLIP_TO_PIXEL((wT * used_ref->top[x + 1] + - wTL * used_ref->top[0] + + (64 - wT + wTL) * dst[x + y * width] + 32) >> 6); + } + } + } + else if (mode == 50) { // vertical + for (int y = 0; y < width; y++) { + for (int x = 0; x < width; x++) { + int wL = 32 >> MIN(31, ((x << 1) >> scale)); + int wTL = wL; + dst[x + y * width] = CLIP_TO_PIXEL((wL * used_ref->left[y + 1] + - wTL * used_ref->top[0] + + (64 - wL + wTL) * dst[x + y * width] + 32) >> 6); + } + } + } + } } diff --git a/src/strategies/generic/intra-generic.c b/src/strategies/generic/intra-generic.c index e277c7b8..464a0ab5 100644 --- a/src/strategies/generic/intra-generic.c +++ b/src/strategies/generic/intra-generic.c @@ -44,14 +44,7 @@ static void kvz_angular_pred_generic( { assert(log2_width >= 2 && log2_width <= 5); - assert(intra_mode >= 2 && intra_mode <= 34); - - static const uint8_t intra_mode_33_to_65_angle[36] = - // H D V - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, DM - { 0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68 }; - const int_fast8_t intra_mode_65 = intra_mode_33_to_65_angle[intra_mode]; - + assert(intra_mode >= 2 && intra_mode <= 66); static const int8_t modedisp2sampledisp[27] = { 0, 1, 2, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 26, 29, 32, 35, 39, 45, 49, 54, 60, 68, 79, 93, 114 }; static const int16_t modedisp2invsampledisp[27] = { 0, 8192, 4096, 2731, 1638, 1170, 910, 745, 630, 546, 482, 431, 390, 356, 315, 282, 256, 234, 210, 182, 167, 152, 137, 120, 104, 88, 72 }; // (256 * 32) / sampledisp @@ -62,9 +55,9 @@ static void kvz_angular_pred_generic( const int_fast8_t width = 1 << log2_width; // Whether to swap references to always project on the left reference row. - const bool vertical_mode = intra_mode_65 >= 34; + const bool vertical_mode = intra_mode >= 34; // Modes distance to horizontal or vertical mode. - const int_fast8_t mode_disp = vertical_mode ? intra_mode_65 - 50 : 18 - intra_mode_65; + const int_fast8_t mode_disp = vertical_mode ? intra_mode - 50 : 18 - intra_mode; //const int_fast8_t mode_disp = vertical_mode ? intra_mode - 26 : 10 - intra_mode; // Sample displacement per column in fractions of 32.