mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
[isp] Fix reference building. When ISP was in use, not enough samples were generated. Uninitialized memory was referenced. Fix some typos.
This commit is contained in:
parent
b16c404362
commit
0ec16967a1
53
src/intra.c
53
src/intra.c
|
@ -234,7 +234,6 @@ static void intra_filter_reference(
|
||||||
filtered_ref->top[ref_width - 1] = ref->top[ref_width - 1];
|
filtered_ref->top[ref_width - 1] = ref->top[ref_width - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Generate dc prediction.
|
* \brief Generate dc prediction.
|
||||||
* \param cu_loc CU location and size data.
|
* \param cu_loc CU location and size data.
|
||||||
|
@ -254,7 +253,7 @@ static void intra_pred_dc(
|
||||||
{
|
{
|
||||||
const int width = color == COLOR_Y ? cu_loc->width : cu_loc->chroma_width;
|
const int width = color == COLOR_Y ? cu_loc->width : cu_loc->chroma_width;
|
||||||
const int height = color == COLOR_Y ? cu_loc->height : cu_loc->chroma_height;
|
const int height = color == COLOR_Y ? cu_loc->height : cu_loc->chroma_height;
|
||||||
|
|
||||||
int_fast16_t sum = 0;
|
int_fast16_t sum = 0;
|
||||||
// Only one loop is done for non-square blocks.
|
// Only one loop is done for non-square blocks.
|
||||||
// In case of non-square blocks, only the longer reference is summed.
|
// In case of non-square blocks, only the longer reference is summed.
|
||||||
|
@ -1004,6 +1003,8 @@ void uvg_intra_build_reference_any(
|
||||||
const int cu_x = cu_loc->x;
|
const int cu_x = cu_loc->x;
|
||||||
const int cu_y = cu_loc->y;
|
const int cu_y = cu_loc->y;
|
||||||
|
|
||||||
|
bool is_first_isp_block = isp_mode ? pu_x == cu_x && pu_y == cu_y : false;
|
||||||
|
|
||||||
assert((log2_width >= 1 && log2_width <= 5) && (log2_height >= 1 && log2_height <= 5));
|
assert((log2_width >= 1 && log2_width <= 5) && (log2_height >= 1 && log2_height <= 5));
|
||||||
|
|
||||||
refs->filtered_initialized = false;
|
refs->filtered_initialized = false;
|
||||||
|
@ -1071,7 +1072,7 @@ void uvg_intra_build_reference_any(
|
||||||
if (luma_px->x > 0) {
|
if (luma_px->x > 0) {
|
||||||
// Get the number of reference pixels based on the PU coordinate within the LCU.
|
// Get the number of reference pixels based on the PU coordinate within the LCU.
|
||||||
int px_available_left;
|
int px_available_left;
|
||||||
if (isp_mode && !is_chroma) {
|
if (isp_mode && !is_first_isp_block && !is_chroma) {
|
||||||
if (isp_mode == ISP_MODE_VER) {
|
if (isp_mode == ISP_MODE_VER) {
|
||||||
px_available_left = height;
|
px_available_left = height;
|
||||||
}
|
}
|
||||||
|
@ -1099,13 +1100,18 @@ void uvg_intra_build_reference_any(
|
||||||
}
|
}
|
||||||
// Extend the last pixel for the rest of the reference values.
|
// Extend the last pixel for the rest of the reference values.
|
||||||
uvg_pixel nearest_pixel = left_border[(px_available_left - 1) * left_stride];
|
uvg_pixel nearest_pixel = left_border[(px_available_left - 1) * left_stride];
|
||||||
for (int i = px_available_left; i < cu_height * 2 + multi_ref_index * 2; ++i) {
|
|
||||||
|
// If first isp split, take samples as if it were normal square block
|
||||||
|
int tmp_h = is_first_isp_block ? cu_height * 2 : (isp_mode ? cu_height + height : height * 2);
|
||||||
|
for (int i = px_available_left; i < tmp_h + multi_ref_index * 2; ++i) {
|
||||||
out_left_ref[i + 1 + multi_ref_index] = nearest_pixel;
|
out_left_ref[i + 1 + multi_ref_index] = nearest_pixel;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If we are on the left edge, extend the first pixel of the top row.
|
// If we are on the left edge, extend the first pixel of the top row.
|
||||||
uvg_pixel nearest_pixel = luma_px->y > 0 ? top_border[0] : dc_val;
|
uvg_pixel nearest_pixel = luma_px->y > 0 ? top_border[0] : dc_val;
|
||||||
for (int i = 0; i < height * 2 + multi_ref_index; i++) {
|
// If first isp split, take samples as if it were normal square block
|
||||||
|
int tmp_h = is_first_isp_block ? cu_height * 2 : (isp_mode ? cu_height + height : height * 2);
|
||||||
|
for (int i = 0; i < tmp_h + multi_ref_index; i++) {
|
||||||
// Reserve space for top left reference
|
// Reserve space for top left reference
|
||||||
out_left_ref[i + 1 + multi_ref_index] = nearest_pixel;
|
out_left_ref[i + 1 + multi_ref_index] = nearest_pixel;
|
||||||
}
|
}
|
||||||
|
@ -1191,7 +1197,7 @@ void uvg_intra_build_reference_any(
|
||||||
int px_available_top;
|
int px_available_top;
|
||||||
if (luma_px->y > 0) {
|
if (luma_px->y > 0) {
|
||||||
// Get the number of reference pixels based on the PU coordinate within the LCU.
|
// Get the number of reference pixels based on the PU coordinate within the LCU.
|
||||||
if (isp_mode && !is_chroma) {
|
if (isp_mode && !is_first_isp_block && !is_chroma) {
|
||||||
if (isp_mode == ISP_MODE_HOR) {
|
if (isp_mode == ISP_MODE_HOR) {
|
||||||
px_available_top = width;
|
px_available_top = width;
|
||||||
}
|
}
|
||||||
|
@ -1214,13 +1220,19 @@ void uvg_intra_build_reference_any(
|
||||||
}
|
}
|
||||||
// Extend the last pixel for the rest of the reference values.
|
// Extend the last pixel for the rest of the reference values.
|
||||||
uvg_pixel nearest_pixel = top_border[px_available_top - 1];
|
uvg_pixel nearest_pixel = top_border[px_available_top - 1];
|
||||||
for (int i = px_available_top; i < width * 2 + multi_ref_index * 2; ++i) {
|
|
||||||
|
// If first isp split, take samples as if it were normal square block
|
||||||
|
int tmp_w = is_first_isp_block ? cu_width * 2 : (isp_mode ? cu_width + width : width * 2);
|
||||||
|
for (int i = px_available_top; i < tmp_w + multi_ref_index * 2; ++i) {
|
||||||
out_top_ref[i + 1 + multi_ref_index] = nearest_pixel;
|
out_top_ref[i + 1 + multi_ref_index] = nearest_pixel;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Extend nearest pixel.
|
// Extend nearest pixel.
|
||||||
uvg_pixel nearest_pixel = luma_px->x > 0 ? left_border[0] : dc_val;
|
uvg_pixel nearest_pixel = luma_px->x > 0 ? left_border[0] : dc_val;
|
||||||
for (int i = 0; i < cu_width * 2 + multi_ref_index; i++) {
|
|
||||||
|
// If first isp split, take samples as if it were normal square block
|
||||||
|
int tmp_w = is_first_isp_block ? cu_width * 2 : (isp_mode ? cu_width + width : width * 2);
|
||||||
|
for (int i = 0; i < tmp_w + multi_ref_index * 2; i++) {
|
||||||
out_top_ref[i + 1] = nearest_pixel;
|
out_top_ref[i + 1] = nearest_pixel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1252,6 +1264,8 @@ void uvg_intra_build_reference_inner(
|
||||||
const int cu_x = cu_loc->x;
|
const int cu_x = cu_loc->x;
|
||||||
const int cu_y = cu_loc->y;
|
const int cu_y = cu_loc->y;
|
||||||
|
|
||||||
|
bool is_first_isp_block = isp_mode ? pu_x == cu_x && pu_y == cu_y : false;
|
||||||
|
|
||||||
// Log2_dim 1 is possible with ISP blocks
|
// Log2_dim 1 is possible with ISP blocks
|
||||||
assert((log2_width >= 1 && log2_width <= 5) && (log2_height >= 1 && log2_height <= 5));
|
assert((log2_width >= 1 && log2_width <= 5) && (log2_height >= 1 && log2_height <= 5));
|
||||||
|
|
||||||
|
@ -1361,7 +1375,7 @@ void uvg_intra_build_reference_inner(
|
||||||
|
|
||||||
// Get the number of reference pixels based on the PU coordinate within the LCU.
|
// Get the number of reference pixels based on the PU coordinate within the LCU.
|
||||||
int px_available_left;
|
int px_available_left;
|
||||||
if (isp_mode && !is_chroma) {
|
if (isp_mode && !is_first_isp_block && !is_chroma) {
|
||||||
if (isp_mode == ISP_MODE_VER) {
|
if (isp_mode == ISP_MODE_VER) {
|
||||||
px_available_left = height;
|
px_available_left = height;
|
||||||
}
|
}
|
||||||
|
@ -1406,7 +1420,10 @@ void uvg_intra_build_reference_inner(
|
||||||
|
|
||||||
// Extend the last pixel for the rest of the reference values.
|
// Extend the last pixel for the rest of the reference values.
|
||||||
uvg_pixel nearest_pixel = out_left_ref[i];
|
uvg_pixel nearest_pixel = out_left_ref[i];
|
||||||
for (; i < cu_height * 2; i += 4) {
|
|
||||||
|
// If first isp split, take samples as if it were normal square block
|
||||||
|
int tmp_h = is_first_isp_block ? cu_height * 2 : (isp_mode ? cu_height + height : height * 2);
|
||||||
|
for (; i < tmp_h; i += 4) {
|
||||||
out_left_ref[i + 1] = nearest_pixel;
|
out_left_ref[i + 1] = nearest_pixel;
|
||||||
out_left_ref[i + 2] = nearest_pixel;
|
out_left_ref[i + 2] = nearest_pixel;
|
||||||
out_left_ref[i + 3] = nearest_pixel;
|
out_left_ref[i + 3] = nearest_pixel;
|
||||||
|
@ -1424,7 +1441,7 @@ void uvg_intra_build_reference_inner(
|
||||||
|
|
||||||
// Get the number of reference pixels based on the PU coordinate within the LCU.
|
// Get the number of reference pixels based on the PU coordinate within the LCU.
|
||||||
int px_available_top;
|
int px_available_top;
|
||||||
if (isp_mode && !is_chroma) {
|
if (isp_mode && !is_first_isp_block && !is_chroma) {
|
||||||
if (isp_mode == ISP_MODE_HOR) {
|
if (isp_mode == ISP_MODE_HOR) {
|
||||||
px_available_top = width;
|
px_available_top = width;
|
||||||
}
|
}
|
||||||
|
@ -1452,7 +1469,10 @@ void uvg_intra_build_reference_inner(
|
||||||
|
|
||||||
// Extend the last pixel for the rest of the reference values.
|
// Extend the last pixel for the rest of the reference values.
|
||||||
nearest_pixel = out_top_ref[i + multi_ref_index];
|
nearest_pixel = out_top_ref[i + multi_ref_index];
|
||||||
for (; i < (cu_width + multi_ref_index) * 2; i += 4) {
|
|
||||||
|
// If first isp split, take samples as if it were normal square block
|
||||||
|
int tmp_w = is_first_isp_block ? cu_width * 2 : (isp_mode ? cu_width + width : width * 2);
|
||||||
|
for (; i < tmp_w + (multi_ref_index * 2); i += 4) {
|
||||||
out_top_ref[i + 1 + multi_ref_index] = nearest_pixel;
|
out_top_ref[i + 1 + multi_ref_index] = nearest_pixel;
|
||||||
out_top_ref[i + 2 + multi_ref_index] = nearest_pixel;
|
out_top_ref[i + 2 + multi_ref_index] = nearest_pixel;
|
||||||
out_top_ref[i + 3 + multi_ref_index] = nearest_pixel;
|
out_top_ref[i + 3 + multi_ref_index] = nearest_pixel;
|
||||||
|
@ -1476,14 +1496,14 @@ void uvg_intra_build_reference(
|
||||||
{
|
{
|
||||||
assert(!(extra_ref_lines == NULL && multi_ref_idx != 0) && "Trying to use MRL with NULL extra references.");
|
assert(!(extra_ref_lines == NULL && multi_ref_idx != 0) && "Trying to use MRL with NULL extra references.");
|
||||||
|
|
||||||
bool first_split = color == COLOR_Y && isp_mode && pu_loc->x == cu_loc->x && pu_loc->y == cu_loc->y;
|
//bool first_split = color == COLOR_Y && isp_mode && pu_loc->x == cu_loc->x && pu_loc->y == cu_loc->y;
|
||||||
uint8_t isp = first_split ? 0 : isp_mode;
|
//uint8_t isp = first_split ? 0 : isp_mode;
|
||||||
|
|
||||||
// Much logic can be discarded if not on the edge
|
// Much logic can be discarded if not on the edge
|
||||||
if (luma_px->x > 0 && luma_px->y > 0) {
|
if (luma_px->x > 0 && luma_px->y > 0) {
|
||||||
uvg_intra_build_reference_inner(pu_loc, cu_loc, color, luma_px, pic_px, lcu, refs, entropy_sync, multi_ref_idx, extra_ref_lines, isp);
|
uvg_intra_build_reference_inner(pu_loc, cu_loc, color, luma_px, pic_px, lcu, refs, entropy_sync, multi_ref_idx, extra_ref_lines, isp_mode);
|
||||||
} else {
|
} else {
|
||||||
uvg_intra_build_reference_any(pu_loc, cu_loc, color, luma_px, pic_px, lcu, refs, multi_ref_idx, extra_ref_lines, isp);
|
uvg_intra_build_reference_any(pu_loc, cu_loc, color, luma_px, pic_px, lcu, refs, multi_ref_idx, extra_ref_lines, isp_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1676,6 +1696,7 @@ static void intra_recon_tb_leaf(
|
||||||
uint8_t isp_mode = color == COLOR_Y ? search_data->pred_cu.intra.isp_mode : 0;
|
uint8_t isp_mode = color == COLOR_Y ? search_data->pred_cu.intra.isp_mode : 0;
|
||||||
|
|
||||||
uvg_intra_references refs;
|
uvg_intra_references refs;
|
||||||
|
|
||||||
// Extra reference lines for use with MRL. Extra lines needed only for left edge.
|
// Extra reference lines for use with MRL. Extra lines needed only for left edge.
|
||||||
uvg_pixel extra_refs[128 * MAX_REF_LINE_IDX] = { 0 };
|
uvg_pixel extra_refs[128 * MAX_REF_LINE_IDX] = { 0 };
|
||||||
|
|
||||||
|
|
|
@ -141,7 +141,7 @@ static void uvg_angular_pred_generic(
|
||||||
|
|
||||||
const int cu_dim = MAX(width, height);
|
const int cu_dim = MAX(width, height);
|
||||||
const int top_ref_length = isp_mode ? width + cu_dim : width << 1;
|
const int top_ref_length = isp_mode ? width + cu_dim : width << 1;
|
||||||
const int left_ref_lenght = isp_mode ? height + cu_dim : height << 1;
|
const int left_ref_length = isp_mode ? height + cu_dim : height << 1;
|
||||||
|
|
||||||
// Set ref_main and ref_side such that, when indexed with 0, they point to
|
// Set ref_main and ref_side such that, when indexed with 0, they point to
|
||||||
// index 0 in block coordinates.
|
// index 0 in block coordinates.
|
||||||
|
@ -159,7 +159,7 @@ static void uvg_angular_pred_generic(
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memcpy(&temp_above[0], &in_ref_above[0], (top_ref_length + 1 + multi_ref_index) * sizeof(uvg_pixel));
|
memcpy(&temp_above[0], &in_ref_above[0], (top_ref_length + 1 + multi_ref_index) * sizeof(uvg_pixel));
|
||||||
memcpy(&temp_left[0], &in_ref_left[0], (left_ref_lenght + 1 + multi_ref_index) * sizeof(uvg_pixel));
|
memcpy(&temp_left[0], &in_ref_left[0], (left_ref_length + 1 + multi_ref_index) * sizeof(uvg_pixel));
|
||||||
|
|
||||||
ref_main = vertical_mode ? temp_above : temp_left;
|
ref_main = vertical_mode ? temp_above : temp_left;
|
||||||
ref_side = vertical_mode ? temp_left : temp_above;
|
ref_side = vertical_mode ? temp_left : temp_above;
|
||||||
|
@ -169,7 +169,7 @@ static void uvg_angular_pred_generic(
|
||||||
const int max_index = (multi_ref_index << s) + 2;
|
const int max_index = (multi_ref_index << s) + 2;
|
||||||
int ref_length;
|
int ref_length;
|
||||||
if (isp_mode) {
|
if (isp_mode) {
|
||||||
ref_length = vertical_mode ? top_ref_length : left_ref_lenght;
|
ref_length = vertical_mode ? top_ref_length : left_ref_length;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ref_length = vertical_mode ? width << 1 : height << 1;
|
ref_length = vertical_mode ? width << 1 : height << 1;
|
||||||
|
|
Loading…
Reference in a new issue