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:
Ari Koivula 2014-02-03 18:21:57 +02:00
parent d1b093c2ee
commit 7bb9c25447
4 changed files with 24 additions and 101 deletions

View file

@ -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,

View file

@ -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;

View file

@ -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 */

View file

@ -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);