diff options
Diffstat (limited to 'third_party/aom/av1/common/cfl.c')
-rw-r--r-- | third_party/aom/av1/common/cfl.c | 91 |
1 files changed, 47 insertions, 44 deletions
diff --git a/third_party/aom/av1/common/cfl.c b/third_party/aom/av1/common/cfl.c index d66a989ad..749a5354f 100644 --- a/third_party/aom/av1/common/cfl.c +++ b/third_party/aom/av1/common/cfl.c @@ -47,23 +47,27 @@ void cfl_dc_pred(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize, TX_SIZE tx_size) { : tx_size_high[tx_size]; // Number of pixel on the top and left borders. - const int num_pel = block_width + block_height; + const double num_pel = block_width + block_height; int sum_u = 0; int sum_v = 0; - // Match behavior of build_intra_predictors (reconintra.c) at superblock - // boundaries: - // - // 127 127 127 .. 127 127 127 127 127 127 - // 129 A B .. Y Z - // 129 C D .. W X - // 129 E F .. U V - // 129 G H .. S T T T T T - // .. - - // TODO(ltrudeau) replace this with DC_PRED assembly +// Match behavior of build_intra_predictors (reconintra.c) at superblock +// boundaries: +// +// 127 127 127 .. 127 127 127 127 127 127 +// 129 A B .. Y Z +// 129 C D .. W X +// 129 E F .. U V +// 129 G H .. S T T T T T +// .. + +#if CONFIG_CHROMA_SUB8X8 + if (xd->chroma_up_available && xd->mb_to_right_edge >= 0) { +#else if (xd->up_available && xd->mb_to_right_edge >= 0) { +#endif + // TODO(ltrudeau) replace this with DC_PRED assembly for (int i = 0; i < block_width; i++) { sum_u += dst_u[-dst_u_stride + i]; sum_v += dst_v[-dst_v_stride + i]; @@ -73,7 +77,11 @@ void cfl_dc_pred(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize, TX_SIZE tx_size) { sum_v = block_width * 127; } +#if CONFIG_CHROMA_SUB8X8 + if (xd->chroma_left_available && xd->mb_to_bottom_edge >= 0) { +#else if (xd->left_available && xd->mb_to_bottom_edge >= 0) { +#endif for (int i = 0; i < block_height; i++) { sum_u += dst_u[i * dst_u_stride - 1]; sum_v += dst_v[i * dst_v_stride - 1]; @@ -83,25 +91,22 @@ void cfl_dc_pred(MACROBLOCKD *xd, BLOCK_SIZE plane_bsize, TX_SIZE tx_size) { sum_v += block_height * 129; } - xd->cfl->dc_pred[CFL_PRED_U] = (sum_u + (num_pel >> 1)) / num_pel; - xd->cfl->dc_pred[CFL_PRED_V] = (sum_v + (num_pel >> 1)) / num_pel; + xd->cfl->dc_pred[CFL_PRED_U] = sum_u / num_pel; + xd->cfl->dc_pred[CFL_PRED_V] = sum_v / num_pel; } // Predict the current transform block using CfL. -// it is assumed that dst points at the start of the transform block void cfl_predict_block(const CFL_CTX *cfl, uint8_t *dst, int dst_stride, - int row, int col, TX_SIZE tx_size, int dc_pred) { - const int tx_block_width = tx_size_wide[tx_size]; - const int tx_block_height = tx_size_high[tx_size]; - - // TODO(ltrudeau) implement alpha - // Place holder for alpha - const double alpha = 0; - const double y_avg = cfl_load(cfl, dst, dst_stride, row, col, tx_size); - - for (int j = 0; j < tx_block_height; j++) { - for (int i = 0; i < tx_block_width; i++) { - dst[i] = (uint8_t)(alpha * y_avg + dc_pred + 0.5); + int row, int col, TX_SIZE tx_size, double dc_pred, + double alpha) { + const int width = tx_size_wide[tx_size]; + const int height = tx_size_high[tx_size]; + + const double y_avg = cfl_load(cfl, dst, dst_stride, row, col, width, height); + + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { + dst[i] = (uint8_t)(alpha * (dst[i] - y_avg) + dc_pred + 0.5); } dst += dst_stride; } @@ -142,9 +147,7 @@ void cfl_store(CFL_CTX *cfl, const uint8_t *input, int input_stride, int row, // Load from the CfL pixel buffer into output double cfl_load(const CFL_CTX *cfl, uint8_t *output, int output_stride, int row, - int col, TX_SIZE tx_size) { - const int tx_width = tx_size_wide[tx_size]; - const int tx_height = tx_size_high[tx_size]; + int col, int width, int height) { const int sub_x = cfl->subsampling_x; const int sub_y = cfl->subsampling_y; const int tx_off_log2 = tx_size_wide_log2[0]; @@ -161,12 +164,12 @@ double cfl_load(const CFL_CTX *cfl, uint8_t *output, int output_stride, int row, // TODO(ltrudeau) add support for 4:2:2 if (sub_y == 0 && sub_x == 0) { y_pix = &cfl->y_pix[(row * MAX_SB_SIZE + col) << tx_off_log2]; - int uv_width = (col << tx_off_log2) + tx_width; + int uv_width = (col << tx_off_log2) + width; diff_width = uv_width - cfl->y_width; - int uv_height = (row << tx_off_log2) + tx_width; + int uv_height = (row << tx_off_log2) + height; diff_height = uv_height - cfl->y_height; - for (int j = 0; j < tx_height; j++) { - for (int i = 0; i < tx_width; i++) { + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { // In 4:4:4, pixels match 1 to 1 output[output_row_offset + i] = y_pix[pred_row_offset + i]; } @@ -175,12 +178,12 @@ double cfl_load(const CFL_CTX *cfl, uint8_t *output, int output_stride, int row, } } else if (sub_y == 1 && sub_x == 1) { y_pix = &cfl->y_pix[(row * MAX_SB_SIZE + col) << (tx_off_log2 + sub_y)]; - int uv_width = ((col << tx_off_log2) + tx_width) << sub_x; + int uv_width = ((col << tx_off_log2) + width) << sub_x; diff_width = (uv_width - cfl->y_width) >> sub_x; - int uv_height = ((row << tx_off_log2) + tx_width) << sub_y; + int uv_height = ((row << tx_off_log2) + height) << sub_y; diff_height = (uv_height - cfl->y_height) >> sub_y; - for (int j = 0; j < tx_height; j++) { - for (int i = 0; i < tx_width; i++) { + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { top_left = (pred_row_offset + i) << sub_y; bot_left = top_left + MAX_SB_SIZE; // In 4:2:0, average pixels in 2x2 grid @@ -206,9 +209,9 @@ double cfl_load(const CFL_CTX *cfl, uint8_t *output, int output_stride, int row, // frame, the columns will be copied over them. if (diff_width > 0) { int last_pixel; - output_row_offset = tx_width - diff_width; + output_row_offset = width - diff_width; - for (int j = 0; j < tx_height; j++) { + for (int j = 0; j < height; j++) { last_pixel = output_row_offset - 1; for (int i = 0; i < diff_width; i++) { output[output_row_offset + i] = output[last_pixel]; @@ -221,7 +224,7 @@ double cfl_load(const CFL_CTX *cfl, uint8_t *output, int output_stride, int row, output_row_offset = diff_height * output_stride; const int last_row_offset = output_row_offset - output_stride; for (int j = 0; j < diff_height; j++) { - for (int i = 0; i < tx_width; i++) { + for (int i = 0; i < width; i++) { output[output_row_offset + i] = output[last_row_offset + i]; } output_row_offset += output_stride; @@ -230,11 +233,11 @@ double cfl_load(const CFL_CTX *cfl, uint8_t *output, int output_stride, int row, int avg = 0; output_row_offset = 0; - for (int j = 0; j < tx_height; j++) { - for (int i = 0; i < tx_width; i++) { + for (int j = 0; j < height; j++) { + for (int i = 0; i < width; i++) { avg += output[output_row_offset + i]; } output_row_offset += output_stride; } - return avg / (double)(tx_width * tx_height); + return avg / (double)(width * height); } |