diff --git a/src/cu.c b/src/cu.c index 8998dafd..8c806733 100644 --- a/src/cu.c +++ b/src/cu.c @@ -364,18 +364,18 @@ int uvg_count_available_edge_cus(const cu_loc_t* const cu_loc, const lcu_t* cons if ((left && cu_loc->x == 0) || (!left && cu_loc->y == 0)) { return 0; } - if (left && cu_loc->local_x == 0) return (LCU_CU_WIDTH - cu_loc->local_y) / 4; - if (!left && cu_loc->local_y == 0) return (LCU_CU_WIDTH - cu_loc->local_x) / 4; + if (left && cu_loc->local_x == 0) return (LCU_WIDTH - cu_loc->local_y) / 4; + if (!left && cu_loc->local_y == 0) return (cu_loc->width) / 2; int amount = 0; if(left) { - while (LCU_GET_CU_AT_PX(lcu, cu_loc->local_x - TR_MIN_WIDTH, cu_loc->local_y + amount * TR_MIN_WIDTH)->type != CU_NOTSET) { - amount++; + while (LCU_GET_CU_AT_PX(lcu, cu_loc->local_x - TR_MIN_WIDTH, cu_loc->local_y + amount)->type != CU_NOTSET && (cu_loc->local_y + amount) < LCU_WIDTH) { + amount += TR_MIN_WIDTH; } - return amount; + return amount / TR_MIN_WIDTH; } - while (LCU_GET_CU_AT_PX(lcu, cu_loc->local_x + amount * TR_MIN_WIDTH, cu_loc->local_y - TR_MIN_WIDTH)->type != CU_NOTSET) { - amount++; + while (LCU_GET_CU_AT_PX(lcu, cu_loc->local_x + amount, cu_loc->local_y - TR_MIN_WIDTH)->type != CU_NOTSET && cu_loc->local_x + amount < LCU_WIDTH) { + amount += TR_MIN_WIDTH; } - return amount; + return amount / TR_MIN_WIDTH; } \ No newline at end of file diff --git a/src/intra.c b/src/intra.c index aacd238f..8e750a00 100644 --- a/src/intra.c +++ b/src/intra.c @@ -936,6 +936,21 @@ static void intra_predict_regular( uint8_t multi_ref_index = color == COLOR_Y ? multi_ref_idx : 0; uint8_t isp = color == COLOR_Y ? isp_mode : 0; + // Wide angle correction + int8_t pred_mode = mode; + if (!is_isp && width != height) { + if (mode > 1 && mode <= 66) { + const int modeShift[] = { 0, 6, 10, 12, 14, 15 }; + const int deltaSize = abs(log2_width - log2_height); + if (width > height && mode < 2 + modeShift[deltaSize]) { + pred_mode += (66 - 1); + } + else if (height > width && mode > 66 - modeShift[deltaSize]) { + pred_mode -= (66 - 1); + } + } + } + const uvg_intra_ref *used_ref = &refs->ref; if (cfg->intra_smoothing_disabled || color != COLOR_Y || mode == 1 || (width == 4 && height == 4) || multi_ref_index || isp_mode /*ISP_TODO: replace this fake ISP check*/) { // For chroma, DC and 4x4 blocks, always use unfiltered reference. @@ -949,11 +964,11 @@ static void intra_predict_regular( // to being either vertical or horizontal. static const int uvg_intra_hor_ver_dist_thres[8] = {24, 24, 24, 14, 2, 0, 0, 0 }; int filter_threshold = uvg_intra_hor_ver_dist_thres[(log2_width + log2_height) >> 1]; - int dist_from_vert_or_hor = MIN(abs(mode - 50), abs(mode - 18)); + int dist_from_vert_or_hor = MIN(abs(pred_mode - 50), abs(pred_mode - 18)); if (dist_from_vert_or_hor > filter_threshold) { static const int16_t modedisp2sampledisp[32] = { 0, 1, 2, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 23, 26, 29, 32, 35, 39, 45, 51, 57, 64, 73, 86, 102, 128, 171, 256, 341, 512, 1024 }; - const int_fast8_t mode_disp = (mode >= 34) ? mode - 50 : 18 - mode; + const int_fast8_t mode_disp = (pred_mode >= 34) ? pred_mode - 50 : 18 - pred_mode; const int_fast8_t sample_disp = (mode_disp < 0 ? -1 : 1) * modedisp2sampledisp[abs(mode_disp)]; if ((abs(sample_disp) & 0x1F) == 0) { used_ref = &refs->filtered_ref; @@ -970,7 +985,7 @@ static void intra_predict_regular( } else if (mode == 1) { intra_pred_dc(cu_loc, color, used_ref->top, used_ref->left, dst, multi_ref_index); } else { - uvg_angular_pred(cu_loc, mode, color, used_ref->top, used_ref->left, dst, multi_ref_index, isp); + uvg_angular_pred(cu_loc, pred_mode, color, used_ref->top, used_ref->left, dst, multi_ref_index, isp); } // pdpc @@ -1463,7 +1478,7 @@ void uvg_intra_build_reference_inner( } } else { - const int num_cus = uvg_count_available_edge_cus(cu_loc, lcu, true); + const int num_cus = uvg_count_available_edge_cus(cu_loc, lcu, false); px_available_top = is_dual_tree || !is_chroma ? num_cus * 4 : num_cus * 2; } diff --git a/src/strategies/generic/intra-generic.c b/src/strategies/generic/intra-generic.c index 6e712bf5..84373d21 100644 --- a/src/strategies/generic/intra-generic.c +++ b/src/strategies/generic/intra-generic.c @@ -68,7 +68,7 @@ static void uvg_angular_pred_generic( // Log2_dim 1 is possible with ISP blocks assert((log2_width >= 1 && log2_width <= 5) && (log2_height >= 1 && log2_height <= 5)); - assert(intra_mode >= 2 && intra_mode <= 66); + // assert(intra_mode >= 2 && intra_mode <= 66); static const int16_t modedisp2sampledisp[32] = { 0, 1, 2, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 23, 26, 29, 32, 35, 39, 45, 51, 57, 64, 73, 86, 102, 128, 171, 256, 341, 512, 1024 }; static const int16_t modedisp2invsampledisp[32] = { 0, 16384, 8192, 5461, 4096, 2731, 2048, 1638, 1365, 1170, 1024, 910, 819, 712, 630, 565, 512, 468, 420, 364, 321, 287, 256, 224, 191, 161, 128, 96, 64, 48, 32, 16 }; // (512 * 32) / sampledisp diff --git a/src/strategies/generic/quant-generic.c b/src/strategies/generic/quant-generic.c index daa302a3..7dc110d7 100644 --- a/src/strategies/generic/quant-generic.c +++ b/src/strategies/generic/quant-generic.c @@ -375,7 +375,7 @@ int uvg_quant_cbcr_residual_generic( //} const int temp = cur_cu->joint_cb_cr * (state->frame->jccr_sign ? -1 : 1); // Get quantized reconstruction. (residual + pred_in -> rec_out) - for (int y = 0; y < width; y++) { + for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (temp == 2) { u_residual[x + y * width] = combined_residual[x + y * width]; @@ -404,7 +404,7 @@ int uvg_quant_cbcr_residual_generic( } } } - for (int y = 0; y < width; ++y) { + for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { int16_t u_val = u_residual[x + y * width] + u_pred_in[x + y * in_stride]; u_rec_out[x + y * out_stride] = (uvg_pixel)CLIP(0, PIXEL_MAX, u_val); @@ -417,7 +417,7 @@ int uvg_quant_cbcr_residual_generic( // With no coeffs and rec_out == pred_int we skip copying the coefficients // because the reconstruction is just the prediction. - for (int y = 0; y < width; ++y) { + for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { u_rec_out[x + y * out_stride] = u_pred_in[x + y * in_stride]; v_rec_out[x + y * out_stride] = v_pred_in[x + y * in_stride];