### Use same intra prediction for all block size

```The commmit changed to use same intra prediction function for all
block sizes.

Some details on the changes:
1. All directional modes except DC/TM/V/H now have built-in filtering
for all pixels with filter taps either (1, 2, 1)/4 or (1, 1)/2.
2. Above edge get automatic extended to double width (bw*2), which
makes a lot of the prediciton mode computation simpler.
3. Same intra prediction function is called with different size
for i4x4_pred and all other larger size.

Overall, the change helped keyframe only coding for both cif size
and std-hd size test sets by .5% consistently on all encodings.
For normal coding with single/auto key frame, the change now also
is consistently net positive for all encodings. The overall gains
is about .15% on std-hd set.

Change-Id: I01ceb31fbc73d49776262e6bdc06853b03bbd1d1```
parent 9dcbbe3d
 ... ... @@ -38,50 +38,33 @@ static void d27_predictor(uint8_t *ypred_ptr, int y_stride, int bw, int bh, uint8_t *yabove_row, uint8_t *yleft_col) { int r, c; r = 0; for (c = 0; c < bw - 2; c++) { int a = c & 1 ? yleft_col[r + 1] : ROUND_POWER_OF_TWO(yleft_col[r] + yleft_col[r + 1], 1); int b = yabove_row[c + 2]; ypred_ptr[c] = iscale_round(2 * a + (c + 1) * b, 1 + c); } for (r = 1; r < bh / 2 - 1; r++) { for (c = 0; c < bw - 2 - 2 * r; c++) { int a = c & 1 ? yleft_col[r + 1] : ROUND_POWER_OF_TWO(yleft_col[r] + yleft_col[r + 1], 1); int b = ypred_ptr[(r - 1) * y_stride + c + 2]; ypred_ptr[r * y_stride + c] = iscale_round(2 * a + (c + 1) * b, 1 + c); } // first column for (r = 0; r < bh - 1; ++r) { ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r] + yleft_col[r + 1], 1); } for (; r < bh - 1; r++) { for (c = 0; c < bw; c++) { int v = c & 1 ? yleft_col[r + 1] : ROUND_POWER_OF_TWO(yleft_col[r] + yleft_col[r + 1], 1); int h = r - c / 2; ypred_ptr[h * y_stride + c] = v; } ypred_ptr[(bh - 1) * y_stride] = yleft_col[bh-1]; ypred_ptr++; // second column for (r = 0; r < bh - 2; ++r) { ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r] + yleft_col[r + 1] * 2 + yleft_col[r + 2], 2); } ypred_ptr[(bh - 2) * y_stride] = ROUND_POWER_OF_TWO(yleft_col[bh - 2] + yleft_col[bh - 1] * 3, 2); ypred_ptr[(bh - 1) * y_stride] = yleft_col[bh-1]; ypred_ptr++; c = 0; r = bh - 1; ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(ypred_ptr[(r - 1) * y_stride] + yleft_col[r], 1); for (r = bh - 2; r >= bh / 2; --r) { const int w = c + (bh - 1 - r) * 2; ypred_ptr[r * y_stride + w] = ROUND_POWER_OF_TWO(ypred_ptr[(r - 1) * y_stride + w] + ypred_ptr[r * y_stride + w - 1], 1); // rest of last row for (c = 0; c < bw - 2; ++c) { ypred_ptr[(bh - 1) * y_stride + c] = yleft_col[bh-1]; } for (c = 1; c < bw; c++) { for (r = bh - 1; r >= bh / 2 + c / 2; --r) { const int w = c + (bh - 1 - r) * 2; ypred_ptr[r * y_stride + w] = ROUND_POWER_OF_TWO(ypred_ptr[(r - 1) * y_stride + w] + ypred_ptr[r * y_stride + w - 1], 1); for (r = bh - 2; r >= 0; --r) { for (c = 0; c < bw - 2; ++c) { ypred_ptr[r * y_stride + c] = ypred_ptr[(r + 1) * y_stride + c - 2]; } } } ... ... @@ -90,50 +73,18 @@ static void d63_predictor(uint8_t *ypred_ptr, int y_stride, int bw, int bh, uint8_t *yabove_row, uint8_t *yleft_col) { int r, c; c = 0; for (r = 0; r < bh - 2; r++) { int a = r & 1 ? yabove_row[c + 1] : ROUND_POWER_OF_TWO(yabove_row[c] + yabove_row[c + 1], 1); int b = yleft_col[r + 2]; ypred_ptr[r * y_stride] = iscale_round(2 * a + (r + 1) * b, 1 + r); } for (c = 1; c < bw / 2 - 1; c++) { for (r = 0; r < bh - 2 - 2 * c; r++) { int a = r & 1 ? yabove_row[c + 1] : ROUND_POWER_OF_TWO(yabove_row[c] + yabove_row[c + 1], 1); int b = ypred_ptr[(r + 2) * y_stride + c - 1]; ypred_ptr[r * y_stride + c] = iscale_round(2 * a + (c + 1) * b, 1 + c); } } for (; c < bw - 1; ++c) { for (r = 0; r < bh; r++) { int v = r & 1 ? yabove_row[c + 1] : ROUND_POWER_OF_TWO(yabove_row[c] + yabove_row[c + 1], 1); int w = c - r / 2; ypred_ptr[r * y_stride + w] = v; } } r = 0; c = bw - 1; ypred_ptr[c] = ROUND_POWER_OF_TWO(ypred_ptr[(c - 1)] + yabove_row[c], 1); for (c = bw - 2; c >= bw / 2; --c) { const int h = r + (bw - 1 - c) * 2; ypred_ptr[h * y_stride + c] = ROUND_POWER_OF_TWO(ypred_ptr[h * y_stride + c - 1] + ypred_ptr[(h - 1) * y_stride + c], 1); } for (r = 1; r < bh; r++) { for (c = bw - 1; c >= bw / 2 + r / 2; --c) { const int h = r + (bw - 1 - c) * 2; ypred_ptr[h * y_stride + c] = ROUND_POWER_OF_TWO(ypred_ptr[h * y_stride + c - 1] + ypred_ptr[(h - 1) * y_stride + c], 1); for (r = 0; r < bh; ++r) { for (c = 0; c < bw; ++c) { if (r & 1) { ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[r/2 + c] + yabove_row[r/2 + c + 1] * 2 + yabove_row[r/2 + c + 2], 2); } else { ypred_ptr[c] =ROUND_POWER_OF_TWO(yabove_row[r/2 + c] + yabove_row[r/2+ c + 1], 1); } } ypred_ptr += y_stride; } } ... ... @@ -141,29 +92,16 @@ static void d45_predictor(uint8_t *ypred_ptr, int y_stride, int bw, int bh, uint8_t *yabove_row, uint8_t *yleft_col) { int r, c; for (r = 0; r < bh - 1; ++r) { for (c = 0; c <= r; ++c) { ypred_ptr[(r - c) * y_stride + c] = iscale_round( yabove_row[r + 1] * (c + 1) + yleft_col[r + 1] * (r - c + 1), r); } } for (c = 0; c <= r; ++c) { int yabove_ext = yabove_row[r]; // clip_pixel(2 * yabove_row[r] - // yabove_row[r - 1]); int yleft_ext = yleft_col[r]; // clip_pixel(2 * yleft_col[r] - // yleft_col[r-1]); ypred_ptr[(r - c) * y_stride + c] = iscale_round(yabove_ext * (c + 1) + yleft_ext * (r - c + 1), r); } for (r = 1; r < bh; ++r) { for (c = bw - r; c < bw; ++c) { const int yabove_ext = ypred_ptr[(r - 1) * y_stride + c]; const int yleft_ext = ypred_ptr[r * y_stride + c - 1]; ypred_ptr[r * y_stride + c] = ROUND_POWER_OF_TWO(yabove_ext + yleft_ext, 1); for (r = 0; r < bh; ++r) { for (c = 0; c < bw; ++c) { if (r + c + 2 < bw * 2) ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[r + c] + yabove_row[r + c + 1] * 2 + yabove_row[r + c + 2], 2); else ypred_ptr[c] = yabove_row[bw]; } ypred_ptr += y_stride; } } ... ... @@ -171,29 +109,61 @@ static void d117_predictor(uint8_t *ypred_ptr, int y_stride, int bw, int bh, uint8_t *yabove_row, uint8_t *yleft_col) { int r, c; // first row for (c = 0; c < bw; c++) ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[c - 1] + yabove_row[c], 1); ypred_ptr += y_stride; for (c = 0; c < bw; c++) ypred_ptr[c] = yabove_row[c - 1]; // second row ypred_ptr = ROUND_POWER_OF_TWO(yleft_col + yabove_row[-1] * 2 + yabove_row, 2); for (c = 1; c < bw; c++) ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[c - 2] + yabove_row[c - 1] * 2 + yabove_row[c], 2); ypred_ptr += y_stride; // the rest of first col ypred_ptr = ROUND_POWER_OF_TWO(yabove_row[-1] + yleft_col * 2 + yleft_col, 2); for (r = 3; r < bh; ++r) ypred_ptr[(r-2) * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r - 3] + yleft_col[r - 2] * 2 + yleft_col[r - 1], 2); // the rest of the block for (r = 2; r < bh; ++r) { ypred_ptr = yleft_col[r - 2]; for (c = 1; c < bw; c++) ypred_ptr[c] = ypred_ptr[-2 * y_stride + c - 1]; ypred_ptr += y_stride; } } static void d135_predictor(uint8_t *ypred_ptr, int y_stride, int bw, int bh, uint8_t *yabove_row, uint8_t *yleft_col) { int r, c; ypred_ptr = yabove_row[-1]; ypred_ptr = ROUND_POWER_OF_TWO(yleft_col + yabove_row[-1] * 2 + yabove_row, 2); for (c = 1; c < bw; c++) ypred_ptr[c] = yabove_row[c - 1]; for (r = 1; r < bh; ++r) ypred_ptr[r * y_stride] = yleft_col[r - 1]; ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[c - 2] + yabove_row[c - 1] * 2 + yabove_row[c], 2); ypred_ptr[y_stride] = ROUND_POWER_OF_TWO(yabove_row[-1] + yleft_col * 2 + yleft_col, 2); for (r = 2; r < bh - 1; ++r) ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r - 2] + yleft_col[r - 1] * 2 + yleft_col[r + 1], 2); ypred_ptr[(bh - 1) * y_stride] = ROUND_POWER_OF_TWO(yleft_col[bh - 2] + yleft_col[bh - 1] * 3, 2); ypred_ptr += y_stride; for (r = 1; r < bh; ++r) { ... ... @@ -203,22 +173,34 @@ static void d135_predictor(uint8_t *ypred_ptr, int y_stride, } } static void d153_predictor(uint8_t *ypred_ptr, int y_stride, static void d153_predictor(uint8_t *ypred_ptr, int y_stride, int bw, int bh, uint8_t *yabove_row, uint8_t *yleft_col) { uint8_t *yabove_row, uint8_t *yleft_col) { int r, c; ypred_ptr = ROUND_POWER_OF_TWO(yabove_row[-1] + yleft_col, 1); for (r = 1; r < bh; r++) ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r - 1] + yleft_col[r], 1); ypred_ptr++; ypred_ptr = yabove_row[-1]; for (r = 1; r < bh; r++) ypred_ptr[r * y_stride] = yleft_col[r - 1]; ypred_ptr = ROUND_POWER_OF_TWO(yleft_col + yabove_row[-1] * 2 + yabove_row, 2); ypred_ptr[y_stride] = ROUND_POWER_OF_TWO(yabove_row[-1] + yleft_col * 2 + yleft_col, 2); for (r = 2; r < bh; r++) ypred_ptr[r * y_stride] = ROUND_POWER_OF_TWO(yleft_col[r - 2] + yleft_col[r - 1] * 2 + yleft_col[r], 2); ypred_ptr++; for (c = 0; c < bw - 2; c++) ypred_ptr[c] = yabove_row[c]; ypred_ptr[c] = ROUND_POWER_OF_TWO(yabove_row[c - 1] + yabove_row[c] * 2 + yabove_row[c + 1], 2); ypred_ptr += y_stride; for (r = 1; r < bh; ++r) { for (c = 0; c < bw - 2; c++) ... ... @@ -234,7 +216,7 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride, int up_available, int left_available, int right_available) { int r, c, i; uint8_t yleft_col, yabove_data, ytop_left; uint8_t yleft_col, yabove_data, ytop_left; uint8_t *yabove_row = yabove_data + 1; // 127 127 127 .. 127 127 127 127 127 127 ... ... @@ -254,14 +236,14 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride, if (up_available) { uint8_t *yabove_ptr = src - src_stride; vpx_memcpy(yabove_row, yabove_ptr, bw); vpx_memset(yabove_row + bw, yabove_row[bw -1], bw); ytop_left = left_available ? yabove_ptr[-1] : 127; } else { vpx_memset(yabove_row, 127, bw); vpx_memset(yabove_row, 127, bw * 2); ytop_left = 127; } yabove_row[-1] = ytop_left; switch (mode) { case DC_PRED: { int i; ... ... @@ -275,7 +257,6 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride, average += yabove_row[i]; count += bw; } if (left_available) { for (i = 0; i < bh; i++) average += yleft_col[i]; ... ... @@ -283,7 +264,6 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride, } expected_dc = (average + (count >> 1)) / count; } for (r = 0; r < bh; r++) { vpx_memset(ypred_ptr, expected_dc, bw); ypred_ptr += y_stride; ... ... @@ -306,7 +286,6 @@ void vp9_build_intra_predictors(uint8_t *src, int src_stride, for (r = 0; r < bh; r++) { for (c = 0; c < bw; c++) ypred_ptr[c] = clip_pixel(yleft_col[r] + yabove_row[c] - ytop_left); ypred_ptr += y_stride; } break; ... ... @@ -624,7 +603,21 @@ void vp9_intra8x8_predict(MACROBLOCKD *xd, mode, 8, 8, have_top, have_left, have_right); } #if !CONFIG_NEWBINTRAMODES void vp9_intra4x4_predict(MACROBLOCKD *xd, int block_idx, int mode, uint8_t *predictor, int pre_stride) { const int have_top = (block_idx >> 2) || xd->up_available; const int have_left = (block_idx & 3) || xd->left_available; const int have_right = ((block_idx & 3) != 3) || xd->right_available; vp9_build_intra_predictors(predictor, pre_stride, predictor, pre_stride, mode, 4, 4, have_top, have_left, have_right); } #endif void vp9_intra_uv4x4_predict(MACROBLOCKD *xd, int block4x4_idx, int mode, ... ...
 ... ... @@ -157,7 +157,6 @@ B_PREDICTION_MODE vp9_find_bpred_context(MACROBLOCKD *xd, int block_idx, return B_DC_PRED; return vp9_find_dominant_direction(ptr, stride, 4, tx, ty); } #endif void vp9_intra4x4_predict(MACROBLOCKD *xd, int block_idx, ... ... @@ -449,3 +448,4 @@ void vp9_intra4x4_predict(MACROBLOCKD *xd, #endif } } #endif
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
{"ft_lang_label":"__label__en","ft_lang_prob":0.82991874,"math_prob":0.99921066,"size":933,"snap":"2021-21-2021-25","text_gpt3_token_len":242,"char_repetition_ratio":0.11840689,"word_repetition_ratio":0.0,"special_character_ratio":0.24651662,"punctuation_ratio":0.11111111,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.999547,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2021-06-23T01:52:00Z\",\"WARC-Record-ID\":\"<urn:uuid:8924e683-b411-4e5e-a68f-5dcc6a1e4310>\",\"Content-Length\":\"692361\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:c452f727-89cc-458b-8745-2cd019fda741>\",\"WARC-Concurrent-To\":\"<urn:uuid:13dda55f-9523-4ced-967c-a723bb88aa9e>\",\"WARC-IP-Address\":\"140.211.166.4\",\"WARC-Target-URI\":\"https://gitlab.xiph.org/xiph/aom-rav1e/-/commit/3d655805f24dbdfbd641e82ccb2d9939850f5e6e\",\"WARC-Payload-Digest\":\"sha1:HZXZ4ZJIZTN6VMMVPX2SJG6YASH4OIBZ\",\"WARC-Block-Digest\":\"sha1:KXNTD2L7L3JWLJLXB46AEJTT4XAZI7KE\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2021/CC-MAIN-2021-25/CC-MAIN-2021-25_segments_1623488528979.69_warc_CC-MAIN-20210623011557-20210623041557-00617.warc.gz\"}"}