mirror of
https://github.com/ultravideo/uvg266.git
synced 2024-11-23 18:14:06 +00:00
Remove duplicate implementation of intra_build_reference_border.
The search_buildReferenceBorder was an ugly hack and a place for bugs to hide that should never have existed. Now it doesn't. The change reduces PSNR a little, but also reduces the bitrate, when the expected result was to have no change in either. I'm guessing there was still some bug in the search_buildReferenceBorder, but the bug could also be in intra_build_reference_border. Will have to do more testing to be sure, but having one place to look at will be better than having two.
This commit is contained in:
parent
d1b093c2ee
commit
7bb9c25447
|
@ -2395,7 +2395,8 @@ void encode_block_residual(encoder_control *encoder,
|
|||
// re-doing the search here with actual reconstructed reference lowered
|
||||
// bitrate by 4% and improved luma PSNR by 0.03dB. Doing it here might
|
||||
// not be worth it.
|
||||
intra_build_reference_border(encoder->in.cur_pic, x_ctb * 8, y_ctb * 8,
|
||||
intra_build_reference_border(encoder->in.cur_pic, encoder->in.cur_pic->y_recdata,
|
||||
x_ctb * 8, y_ctb * 8,
|
||||
width * 2 + 8, rec, width * 2 + 8, 0);
|
||||
cur_cu->intra[0].mode = (int8_t)intra_prediction(encoder->in.cur_pic->y_data,
|
||||
encoder->in.width,
|
||||
|
@ -2419,8 +2420,9 @@ void encode_block_residual(encoder_control *encoder,
|
|||
recbase_y = &encoder->in.cur_pic->y_recdata[x_pos + y_pos * encoder->in.width];
|
||||
|
||||
rec_shift = &rec[width * 2 + 8 + 1];
|
||||
intra_build_reference_border(encoder->in.cur_pic, x_pos, y_pos,
|
||||
width * 2 + 8, rec, width * 2 + 8, 0);
|
||||
intra_build_reference_border(encoder->in.cur_pic, encoder->in.cur_pic->y_recdata,
|
||||
x_pos, y_pos,
|
||||
width * 2 + 8, rec, width * 2 + 8, 0);
|
||||
intra_recon(rec_shift, width * 2 + 8,
|
||||
x_pos, y_pos,
|
||||
width, recbase_y, rec_stride, cur_cu->intra[i].mode, 0);
|
||||
|
@ -2439,10 +2441,11 @@ void encode_block_residual(encoder_control *encoder,
|
|||
}
|
||||
|
||||
rec_shift = &rec[width_c * 2 + 8 + 1];
|
||||
intra_build_reference_border(encoder->in.cur_pic, x_ctb << MIN_SIZE, y_ctb << MIN_SIZE,
|
||||
width_c * 2 + 8, rec,
|
||||
width_c * 2 + 8,
|
||||
1);
|
||||
intra_build_reference_border(encoder->in.cur_pic, encoder->in.cur_pic->u_recdata,
|
||||
x_ctb << MIN_SIZE, y_ctb << MIN_SIZE,
|
||||
width_c * 2 + 8, rec,
|
||||
width_c * 2 + 8,
|
||||
1);
|
||||
intra_recon(rec_shift,
|
||||
width_c * 2 + 8,
|
||||
x_ctb * width_c,
|
||||
|
@ -2453,10 +2456,11 @@ void encode_block_residual(encoder_control *encoder,
|
|||
cur_cu->intra[0].mode_chroma != 36 ? cur_cu->intra[0].mode_chroma : cur_cu->intra[0].mode,
|
||||
1);
|
||||
|
||||
intra_build_reference_border(encoder->in.cur_pic, x_ctb << MIN_SIZE, y_ctb << MIN_SIZE,
|
||||
width_c * 2 + 8,
|
||||
rec, width_c * 2 + 8,
|
||||
2);
|
||||
intra_build_reference_border(encoder->in.cur_pic, encoder->in.cur_pic->v_recdata,
|
||||
x_ctb << MIN_SIZE, y_ctb << MIN_SIZE,
|
||||
width_c * 2 + 8,
|
||||
rec, width_c * 2 + 8,
|
||||
2);
|
||||
intra_recon(rec_shift,
|
||||
width_c * 2 + 8,
|
||||
x_ctb * width_c,
|
||||
|
|
|
@ -432,7 +432,7 @@ void intra_recon(pixel* rec,uint32_t recstride, uint32_t xpos, uint32_t ypos,uin
|
|||
* The end result is 2*width+8 x 2*width+8 array, with only the top and left
|
||||
* edge pixels filled with the reconstructed pixels.
|
||||
*/
|
||||
void intra_build_reference_border(picture *pic, int32_t x_luma, int32_t y_luma, int16_t outwidth,
|
||||
void intra_build_reference_border(picture *pic, const pixel *src, int32_t x_luma, int32_t y_luma, int16_t outwidth,
|
||||
pixel *dst, int32_t dststride, int8_t chroma)
|
||||
{
|
||||
// Some other function might make use of the arrays num_ref_pixels_top and
|
||||
|
@ -495,7 +495,7 @@ void intra_build_reference_border(picture *pic, int32_t x_luma, int32_t y_luma,
|
|||
const int src_height = pic->height >> is_chroma;
|
||||
|
||||
// input picture pointer
|
||||
const pixel * const src = (!chroma) ? pic->y_recdata : ((chroma == 1) ? pic->u_recdata : pic->v_recdata);
|
||||
//const pixel * const src = (!chroma) ? pic->y_recdata : ((chroma == 1) ? pic->u_recdata : pic->v_recdata);
|
||||
|
||||
// Convert luma coordinates to chroma coordinates for chroma.
|
||||
const int x = chroma ? x_luma / 2 : x_luma;
|
||||
|
|
|
@ -35,7 +35,7 @@ int8_t intra_get_block_mode(picture* pic, uint32_t x_ctb, uint32_t y_ctb, uint8_
|
|||
int8_t intra_get_dir_luma_predictor(picture* pic,uint32_t x_ctb, uint32_t y_ctb, uint8_t depth, int8_t* preds);
|
||||
void intra_dc_pred_filtering(pixel* src, int32_t src_stride, pixel* dst, int32_t dst_stride, int32_t width, int32_t height );
|
||||
|
||||
void intra_build_reference_border(picture* pic, int32_t x_ctb, int32_t y_ctb, int16_t out_width, pixel* dst, int32_t dst_stride, int8_t chroma);
|
||||
void intra_build_reference_border(picture* pic, const pixel *src, int32_t x_ctb, int32_t y_ctb, int16_t out_width, pixel* dst, int32_t dst_stride, int8_t chroma);
|
||||
void intra_filter(pixel* ref, int32_t stride, int32_t width, int8_t mode);
|
||||
|
||||
/* Predictions */
|
||||
|
|
93
src/search.c
93
src/search.c
|
@ -279,89 +279,6 @@ unsigned search_mv_full(unsigned depth,
|
|||
return best_cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief
|
||||
*/
|
||||
void search_buildReferenceBorder(picture *pic, int32_t x, int32_t y,
|
||||
int16_t outwidth, pixel *dst,
|
||||
int32_t dststride, int8_t chroma)
|
||||
{
|
||||
int32_t left_col; // left column iterator
|
||||
pixel val; // variable to store extrapolated value
|
||||
int32_t i; // index iterator
|
||||
pixel dc_val = 1 << (g_bitdepth - 1); // default predictor value
|
||||
int32_t top_row; // top row iterator
|
||||
int32_t src_width = (pic->width >> (chroma ? 1 : 0)); // source picture width
|
||||
int32_t src_height = (pic->height >> (chroma ? 1 : 0)); // source picture height
|
||||
pixel *src_pic = (!chroma) ? pic->y_data : ((chroma == 1) ? pic->u_data : pic->v_data); // input picture pointer
|
||||
int16_t scu_width = LCU_WIDTH >> (MAX_DEPTH + (chroma ? 1 : 0)); // Smallest Coding Unit width
|
||||
int x_ctb = x >> MIN_SIZE;
|
||||
int y_ctb = y >> MIN_SIZE;
|
||||
pixel *src_shifted = &src_pic[x_ctb * scu_width + y_ctb * scu_width * src_width]; // input picture pointer shifted to start from the left-top corner of the current block
|
||||
int32_t width_in_scu = pic->width_in_lcu << MAX_DEPTH; // picture width in SCU
|
||||
|
||||
// Fill left column
|
||||
if (x_ctb) {
|
||||
// Loop SCU's
|
||||
for (left_col = 1; left_col < outwidth / scu_width; left_col++) {
|
||||
// If over the picture height or block not yet searched, stop
|
||||
if ((y_ctb + left_col) * scu_width >= src_height
|
||||
|| pic->cu_array[MAX_DEPTH][x_ctb - 1 + (y_ctb + left_col) * width_in_scu].type == CU_NOTSET) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the pixels to output
|
||||
for (i = 0; i < left_col * scu_width - 1; i++) {
|
||||
dst[(i + 1) * dststride] = src_shifted[i * src_width - 1];
|
||||
}
|
||||
|
||||
// if the loop was not completed, extrapolate the last pixel pushed to output
|
||||
if (left_col != outwidth / scu_width) {
|
||||
val = src_shifted[(left_col * scu_width - 1) * src_width - 1];
|
||||
for (i = (left_col * scu_width); i < outwidth; i++) {
|
||||
dst[i * dststride] = val;
|
||||
}
|
||||
}
|
||||
} else { // If left column not available, copy from toprow or use the default predictor
|
||||
val = y_ctb ? src_shifted[-src_width] : dc_val;
|
||||
for (i = 0; i < outwidth; i++) {
|
||||
dst[i * dststride] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (y_ctb) {
|
||||
// Loop top SCU's
|
||||
for (top_row = 1; top_row < outwidth / scu_width; top_row++) {
|
||||
if ((x_ctb + top_row) * scu_width >= src_width
|
||||
|| pic->cu_array[MAX_DEPTH][x_ctb + top_row + (y_ctb - 1) * width_in_scu].type
|
||||
== CU_NOTSET) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < top_row * scu_width - 1; i++) {
|
||||
dst[i + 1] = src_shifted[i - src_width];
|
||||
}
|
||||
|
||||
if (top_row != outwidth / scu_width) {
|
||||
val = src_shifted[(top_row * scu_width) - src_width - 1];
|
||||
for (i = (top_row * scu_width); i < outwidth; i++) {
|
||||
dst[i] = val;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val = x_ctb ? src_shifted[-1] : dc_val;
|
||||
for (i = 1; i < outwidth; i++) {
|
||||
dst[i] = val;
|
||||
}
|
||||
}
|
||||
// Topleft corner
|
||||
dst[0] = (x_ctb && y_ctb) ? src_shifted[-src_width - 1] : dst[dststride];
|
||||
|
||||
}
|
||||
|
||||
|
||||
void search_inter(encoder_control *encoder, uint16_t x_ctb, uint16_t y_ctb, uint8_t depth) {
|
||||
picture *cur_pic = encoder->in.cur_pic;
|
||||
picture *ref_pic = encoder->ref->pics[0];
|
||||
|
@ -404,8 +321,9 @@ void search_intra(encoder_control *encoder, uint16_t x_ctb, uint16_t y_ctb, uint
|
|||
pixel *recShift = &rec[(LCU_WIDTH >> (depth)) * 2 + 8 + 1];
|
||||
|
||||
// Build reconstructed block to use in prediction with extrapolated borders
|
||||
search_buildReferenceBorder(encoder->in.cur_pic, x, y,
|
||||
width * 2 + 8, rec, width * 2 + 8, 0);
|
||||
intra_build_reference_border(cur_pic, cur_pic->y_data,
|
||||
x, y,
|
||||
width * 2 + 8, rec, width * 2 + 8, 0);
|
||||
cur_cu->intra[0].mode = (uint8_t) intra_prediction(encoder->in.cur_pic->y_data,
|
||||
encoder->in.width, recShift, width * 2 + 8, x, y,
|
||||
width, pred, width, &cur_cu->intra[0].cost);
|
||||
|
@ -426,8 +344,9 @@ void search_intra(encoder_control *encoder, uint16_t x_ctb, uint16_t y_ctb, uint
|
|||
for (i = 0; i < 4; ++i) {
|
||||
int x_pos = x + offsets[i].x * width;
|
||||
int y_pos = y + offsets[i].y * width;
|
||||
search_buildReferenceBorder(encoder->in.cur_pic, x_pos, y_pos,
|
||||
width * 2 + 8, rec, width * 2 + 8, 0);
|
||||
intra_build_reference_border(cur_pic, cur_pic->y_recdata,
|
||||
x_pos, y_pos,
|
||||
width * 2 + 8, rec, width * 2 + 8, 0);
|
||||
cur_cu->intra[i].mode = (uint8_t) intra_prediction(encoder->in.cur_pic->y_data,
|
||||
encoder->in.width, recShift, width * 2 + 8, x_pos, y_pos,
|
||||
width, pred, width, &cur_cu->intra[i].cost);
|
||||
|
|
Loading…
Reference in a new issue