Commit 056d1f40 authored by Luc Trudeau's avatar Luc Trudeau

[CFL] Support for 4:2:0 High Bit Depth

high bit depth (_hbd) and low bit depth (_lbd) versions
of the cfl functions: sum_above_row, sum_left_col,
cfl_build_prediction, cfl_luma_subsampling_420 (4:4:4 will
be added in subsequent commit) and cfl_alpha_dist. For
cfl_alpha_dist, special care is given to scale the SSE
according to the bit depth.

BUG=aomedia:835

Change-Id: I5b72845100d88fb8a438efe665bcae7fe1ba50b8
parent e58b564d
This diff is collapsed.
......@@ -5856,11 +5856,10 @@ static int rd_pick_intra_angle_sbuv(const AV1_COMP *const cpi, MACROBLOCK *x,
#endif // CONFIG_EXT_INTRA
#if CONFIG_CFL
// TODO(ltrudeau) add support for HBD.
static int64_t cfl_alpha_dist(const int16_t *pred_buf_q3, const uint8_t *src,
int src_stride, int width, int height,
int dc_pred, int alpha_q3,
int64_t *dist_neg_out) {
static int64_t cfl_alpha_dist_lbd(const int16_t *pred_buf_q3,
const uint8_t *src, int src_stride, int width,
int height, int dc_pred, int alpha_q3,
int64_t *dist_neg_out) {
int64_t dist = 0;
int diff;
......@@ -5898,6 +5897,69 @@ static int64_t cfl_alpha_dist(const int16_t *pred_buf_q3, const uint8_t *src,
return dist;
}
#if CONFIG_HIGHBITDEPTH
static int64_t cfl_alpha_dist_hbd(const int16_t *pred_buf_q3,
const uint16_t *src, int src_stride,
int width, int height, int dc_pred,
int alpha_q3, int bit_depth,
int64_t *dist_neg_out) {
const int shift = 2 * (bit_depth - 8);
const int rounding = shift > 0 ? (1 << shift) >> 1 : 0;
int64_t dist = 0;
int diff;
if (alpha_q3 == 0) {
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
diff = src[i] - dc_pred;
dist += diff * diff;
}
src += src_stride;
}
dist = (dist + rounding) >> shift;
if (dist_neg_out) *dist_neg_out = dist;
return dist;
}
int64_t dist_neg = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
const int uv = src[i];
const int scaled_luma = get_scaled_luma_q0(alpha_q3, pred_buf_q3[i]);
diff = uv - clip_pixel_highbd(scaled_luma + dc_pred, bit_depth);
dist += diff * diff;
diff = uv - clip_pixel_highbd(-scaled_luma + dc_pred, bit_depth);
dist_neg += diff * diff;
}
pred_buf_q3 += MAX_SB_SIZE;
src += src_stride;
}
if (dist_neg_out) *dist_neg_out = (dist_neg + rounding) >> shift;
return (dist + rounding) >> shift;
}
#endif // CONFIG_HIGHBITDEPTH
static int64_t cfl_alpha_dist(const int16_t *pred_buf_q3, const uint8_t *src,
int src_stride, int width, int height,
int dc_pred, int alpha_q3, int use_hbd,
int bit_depth, int64_t *dist_neg_out) {
#if CONFIG_HIGHBITDEPTH
if (use_hbd) {
const uint16_t *src_16 = CONVERT_TO_SHORTPTR(src);
return cfl_alpha_dist_hbd(pred_buf_q3, src_16, src_stride, width, height,
dc_pred, alpha_q3, bit_depth, dist_neg_out);
}
#endif // CONFIG_HIGHBITDEPTH
(void)use_hbd;
(void)bit_depth;
return cfl_alpha_dist_lbd(pred_buf_q3, src, src_stride, width, height,
dc_pred, alpha_q3, dist_neg_out);
}
static int cfl_rd_pick_alpha(MACROBLOCK *const x, TX_SIZE tx_size) {
const struct macroblock_plane *const p_u = &x->plane[AOM_PLANE_U];
......@@ -5917,22 +5979,25 @@ static int cfl_rd_pick_alpha(MACROBLOCK *const x, TX_SIZE tx_size) {
const int dc_pred_u = cfl->dc_pred[CFL_PRED_U];
const int dc_pred_v = cfl->dc_pred[CFL_PRED_V];
const int16_t *pred_buf_q3 = cfl->pred_buf_q3;
const int use_hbd = get_bitdepth_data_path_index(xd);
int64_t sse[CFL_PRED_PLANES][CFL_MAGS_SIZE];
sse[CFL_PRED_U][0] = cfl_alpha_dist(pred_buf_q3, src_u, src_stride_u, width,
height, dc_pred_u, 0, NULL);
sse[CFL_PRED_V][0] = cfl_alpha_dist(pred_buf_q3, src_v, src_stride_v, width,
height, dc_pred_v, 0, NULL);
sse[CFL_PRED_U][0] =
cfl_alpha_dist(pred_buf_q3, src_u, src_stride_u, width, height, dc_pred_u,
0, use_hbd, xd->bd, NULL);
sse[CFL_PRED_V][0] =
cfl_alpha_dist(pred_buf_q3, src_v, src_stride_v, width, height, dc_pred_v,
0, use_hbd, xd->bd, NULL);
for (int c = 0; c < CFL_ALPHABET_SIZE; c++) {
const int m = c * 2 + 1;
const int abs_alpha_q3 = c + 1;
sse[CFL_PRED_U][m] =
cfl_alpha_dist(pred_buf_q3, src_u, src_stride_u, width, height,
dc_pred_u, abs_alpha_q3, &sse[CFL_PRED_U][m + 1]);
sse[CFL_PRED_V][m] =
cfl_alpha_dist(pred_buf_q3, src_v, src_stride_v, width, height,
dc_pred_v, abs_alpha_q3, &sse[CFL_PRED_V][m + 1]);
sse[CFL_PRED_U][m] = cfl_alpha_dist(
pred_buf_q3, src_u, src_stride_u, width, height, dc_pred_u,
abs_alpha_q3, use_hbd, xd->bd, &sse[CFL_PRED_U][m + 1]);
sse[CFL_PRED_V][m] = cfl_alpha_dist(
pred_buf_q3, src_v, src_stride_v, width, height, dc_pred_v,
abs_alpha_q3, use_hbd, xd->bd, &sse[CFL_PRED_V][m + 1]);
}
int64_t dist;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment