Add intra-interp experiment flag intra-interp experiment allows intra prediction to use different interpolation filters. It was part of the ext-intra in the nextgenv2 branch. Change-Id: I27ab692494dc79bb92e457dbf9a72988577f1c6d
diff --git a/av1/common/blockd.c b/av1/common/blockd.c index e86338a..8a887f9 100644 --- a/av1/common/blockd.c +++ b/av1/common/blockd.c
@@ -223,6 +223,7 @@ 54, 49, 45, 40, 35, 31, 26, 22, 17, 13, 8, 4, }; +#if CONFIG_INTRA_INTERP int av1_is_intra_filter_switchable(int angle) { assert(angle > 0 && angle < 270); if (angle % 45 == 0) return 0; @@ -234,4 +235,5 @@ 0xFF) > 0; } } +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA
diff --git a/av1/common/blockd.h b/av1/common/blockd.h index 793561a..eb7f915 100644 --- a/av1/common/blockd.h +++ b/av1/common/blockd.h
@@ -302,9 +302,12 @@ FILTER_INTRA_MODE_INFO filter_intra_mode_info; #endif // CONFIG_FILTER_INTRA #if CONFIG_EXT_INTRA + // The actual prediction angle is the base angle + (angle_delta * step). int8_t angle_delta[2]; +#if CONFIG_INTRA_INTERP // To-Do (huisu): this may be replaced by interp_filter INTRA_FILTER intra_filter; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_EXT_INTER @@ -697,9 +700,11 @@ 0, 90, 180, 45, 135, 111, 157, 203, 67, 0, }; +#if CONFIG_INTRA_INTERP // Returns whether filter selection is needed for a given // intra prediction angle. int av1_is_intra_filter_switchable(int angle); +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_EXT_TILE
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c index cbad10a..09868dc 100644 --- a/av1/common/entropymode.c +++ b/av1/common/entropymode.c
@@ -1636,6 +1636,7 @@ #endif // CONFIG_EXT_TX #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP static const aom_prob default_intra_filter_probs[INTRA_FILTERS + 1] [INTRA_FILTERS - 1] = { { 98, 63, 60 }, @@ -1648,6 +1649,7 @@ -INTRA_FILTER_LINEAR, 2, -INTRA_FILTER_8TAP, 4, -INTRA_FILTER_8TAP_SHARP, -INTRA_FILTER_8TAP_SMOOTH, }; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_FILTER_INTRA @@ -1723,7 +1725,9 @@ av1_copy(fc->seg.tree_probs, default_segment_tree_probs); av1_copy(fc->seg.pred_probs, default_segment_pred_probs); #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP av1_copy(fc->intra_filter_probs, default_intra_filter_probs); +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_FILTER_INTRA av1_copy(fc->filter_intra_probs, default_filter_intra_probs); @@ -2036,10 +2040,12 @@ mode_mv_merge_probs(pre_fc->delta_q_prob[i], counts->delta_q[i]); #endif #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP for (i = 0; i < INTRA_FILTERS + 1; ++i) { aom_tree_merge_probs(av1_intra_filter_tree, pre_fc->intra_filter_probs[i], counts->intra_filter[i], fc->intra_filter_probs[i]); } +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_FILTER_INTRA for (i = 0; i < PLANE_TYPES; ++i) {
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h index dd753a1..63211dc 100644 --- a/av1/common/entropymode.h +++ b/av1/common/entropymode.h
@@ -152,7 +152,9 @@ #endif // CONFIG_SUPERTX struct segmentation_probs seg; #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP aom_prob intra_filter_probs[INTRA_FILTERS + 1][INTRA_FILTERS - 1]; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_FILTER_INTRA aom_prob filter_intra_probs[PLANE_TYPES]; @@ -271,7 +273,9 @@ #endif // CONFIG_SUPERTX struct seg_counts seg; #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP unsigned int intra_filter[INTRA_FILTERS + 1][INTRA_FILTERS]; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_FILTER_INTRA unsigned int filter_intra[PLANE_TYPES][2]; @@ -328,7 +332,9 @@ #endif // CONFIG_PALETTE extern const aom_tree_index av1_tx_size_tree[MAX_TX_DEPTH][TREE_SIZE(TX_SIZES)]; #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP extern const aom_tree_index av1_intra_filter_tree[TREE_SIZE(INTRA_FILTERS)]; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_EXT_TX extern const aom_tree_index av1_ext_tx_inter_tree[EXT_TX_SETS_INTER]
diff --git a/av1/common/filter.c b/av1/common/filter.c index 3f1cdbb..0d6bc3b 100644 --- a/av1/common/filter.c +++ b/av1/common/filter.c
@@ -194,12 +194,14 @@ #endif // CONFIG_EXT_INTERP #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP const InterpKernel *av1_intra_filter_kernels[INTRA_FILTERS] = { bilinear_filters, // INTRA_FILTER_LINEAR sub_pel_filters_8, // INTRA_FILTER_8TAP sub_pel_filters_8sharp, // INTRA_FILTER_8TAP_SHARP sub_pel_filters_8smooth, // INTRA_FILTER_8TAP_SMOOTH }; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_EXT_INTERP
diff --git a/av1/common/filter.h b/av1/common/filter.h index 44f8f02..020d7dd 100644 --- a/av1/common/filter.h +++ b/av1/common/filter.h
@@ -64,6 +64,7 @@ typedef uint8_t InterpFilter; #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP typedef enum { INTRA_FILTER_LINEAR, INTRA_FILTER_8TAP, @@ -73,6 +74,7 @@ } INTRA_FILTER; extern const InterpKernel *av1_intra_filter_kernels[INTRA_FILTERS]; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA typedef struct InterpFilterParams {
diff --git a/av1/common/pred_common.c b/av1/common/pred_common.c index e522725..bbf21c9 100644 --- a/av1/common/pred_common.c +++ b/av1/common/pred_common.c
@@ -96,6 +96,7 @@ #endif #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP // Obtain the reference filter type from the above/left neighbor blocks. static INTRA_FILTER get_ref_intra_filter(const MB_MODE_INFO *ref_mbmi) { INTRA_FILTER ref_type = INTRA_FILTERS; @@ -143,6 +144,7 @@ else return INTRA_FILTERS; } +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA // The mode info data structure has a one element border above and to the
diff --git a/av1/common/pred_common.h b/av1/common/pred_common.h index 71865f2..49d09fc 100644 --- a/av1/common/pred_common.h +++ b/av1/common/pred_common.h
@@ -74,7 +74,9 @@ #endif #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP int av1_get_pred_context_intra_interp(const MACROBLOCKD *xd); +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA int av1_get_intra_inter_context(const MACROBLOCKD *xd);
diff --git a/av1/common/reconintra.c b/av1/common/reconintra.c index db44a23..5a6583b 100644 --- a/av1/common/reconintra.c +++ b/av1/common/reconintra.c
@@ -407,6 +407,7 @@ } #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP static int intra_subpel_interp(int base, int shift, const uint8_t *ref, int ref_start_idx, int ref_end_idx, INTRA_FILTER filter_type) { @@ -435,11 +436,15 @@ return val; } +#endif // CONFIG_INTRA_INTERP // Directional prediction, zone 1: 0 < angle < 90 static void dr_prediction_z1(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left, int dx, - int dy, INTRA_FILTER filter_type) { + const uint8_t *above, const uint8_t *left, +#if CONFIG_INTRA_INTERP + INTRA_FILTER filter_type, +#endif // CONFIG_INTRA_INTERP + int dx, int dy) { int r, c, x, base, shift, val; (void)left; @@ -447,6 +452,7 @@ assert(dy == 1); assert(dx < 0); +#if CONFIG_INTRA_INTERP if (filter_type != INTRA_FILTER_LINEAR) { const int pad_size = SUBPEL_TAPS >> 1; int len; @@ -505,8 +511,8 @@ } return; } +#endif // CONFIG_INTRA_INTERP - // For linear filter, C code is faster. x = -dx; for (r = 0; r < bs; ++r, dst += stride, x -= dx) { base = x >> 8; @@ -535,8 +541,11 @@ // Directional prediction, zone 2: 90 < angle < 180 static void dr_prediction_z2(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left, int dx, - int dy, INTRA_FILTER filter_type) { + const uint8_t *above, const uint8_t *left, +#if CONFIG_INTRA_INTERP + INTRA_FILTER filter_type, +#endif // CONFIG_INTRA_INTERP + int dx, int dy) { int r, c, x, y, shift1, shift2, val, base1, base2; assert(dx > 0); @@ -549,14 +558,24 @@ for (c = 0; c < bs; ++c, ++base1, y -= dy) { if (base1 >= -1) { shift1 = x & 0xFF; +#if CONFIG_INTRA_INTERP val = intra_subpel_interp(base1, shift1, above, -1, bs - 1, filter_type); +#else + val = above[base1] * (256 - shift1) + above[base1 + 1] * shift1; + val = ROUND_POWER_OF_TWO(val, 8); +#endif // CONFIG_INTRA_INTERP } else { base2 = y >> 8; if (base2 >= 0) { shift2 = y & 0xFF; +#if CONFIG_INTRA_INTERP val = intra_subpel_interp(base2, shift2, left, 0, bs - 1, filter_type); +#else + val = left[base2] * (256 - shift2) + left[base2 + 1] * shift2; + val = ROUND_POWER_OF_TWO(val, 8); +#endif // CONFIG_INTRA_INTERP } else { val = left[0]; } @@ -568,8 +587,11 @@ // Directional prediction, zone 3: 180 < angle < 270 static void dr_prediction_z3(uint8_t *dst, ptrdiff_t stride, int bs, - const uint8_t *above, const uint8_t *left, int dx, - int dy, INTRA_FILTER filter_type) { + const uint8_t *above, const uint8_t *left, +#if CONFIG_INTRA_INTERP + INTRA_FILTER filter_type, +#endif // CONFIG_INTRA_INTERP + int dx, int dy) { int r, c, y, base, shift, val; (void)above; @@ -578,6 +600,7 @@ assert(dx == 1); assert(dy < 0); +#if CONFIG_INTRA_INTERP if (filter_type != INTRA_FILTER_LINEAR) { const int pad_size = SUBPEL_TAPS >> 1; int len, i; @@ -646,8 +669,8 @@ } return; } +#endif // CONFIG_INTRA_INTERP - // For linear filter, C code is faster. y = -dy; for (c = 0; c < bs; ++c, y -= dy) { base = y >> 8; @@ -697,19 +720,34 @@ } static void dr_predictor(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size, - const uint8_t *above, const uint8_t *left, int angle, - INTRA_FILTER filter_type) { + const uint8_t *above, const uint8_t *left, +#if CONFIG_INTRA_INTERP + INTRA_FILTER filter_type, +#endif // CONFIG_INTRA_INTERP + int angle) { const int dx = get_dx(angle); const int dy = get_dy(angle); const int bs = tx_size_wide[tx_size]; assert(angle > 0 && angle < 270); if (angle > 0 && angle < 90) { - dr_prediction_z1(dst, stride, bs, above, left, dx, dy, filter_type); + dr_prediction_z1(dst, stride, bs, above, left, +#if CONFIG_INTRA_INTERP + filter_type, +#endif // CONFIG_INTRA_INTERP + dx, dy); } else if (angle > 90 && angle < 180) { - dr_prediction_z2(dst, stride, bs, above, left, dx, dy, filter_type); + dr_prediction_z2(dst, stride, bs, above, left, +#if CONFIG_INTRA_INTERP + filter_type, +#endif // CONFIG_INTRA_INTERP + dx, dy); } else if (angle > 180 && angle < 270) { - dr_prediction_z3(dst, stride, bs, above, left, dx, dy, filter_type); + dr_prediction_z3(dst, stride, bs, above, left, +#if CONFIG_INTRA_INTERP + filter_type, +#endif // CONFIG_INTRA_INTERP + dx, dy); } else if (angle == 90) { pred[V_PRED][tx_size](dst, stride, above, left); } else if (angle == 180) { @@ -718,6 +756,7 @@ } #if CONFIG_AOM_HIGHBITDEPTH +#if CONFIG_INTRA_INTERP static int highbd_intra_subpel_interp(int base, int shift, const uint16_t *ref, int ref_start_idx, int ref_end_idx, INTRA_FILTER filter_type) { @@ -746,12 +785,15 @@ return val; } +#endif // CONFIG_INTRA_INTERP // Directional prediction, zone 1: 0 < angle < 90 static void highbd_dr_prediction_z1(uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, - int dx, int dy, int bd, - INTRA_FILTER filter_type) { +#if CONFIG_INTRA_INTERP + INTRA_FILTER filter_type, +#endif // CONFIG_INTRA_INTERP + int dx, int dy, int bd) { int r, c, x, y, base, shift, val; (void)left; @@ -766,8 +808,13 @@ base = x >> 8; shift = x & 0xFF; if (base < 2 * bs - 1) { +#if CONFIG_INTRA_INTERP val = highbd_intra_subpel_interp(base, shift, above, 0, 2 * bs - 1, filter_type); +#else + val = above[base] * (256 - shift) + above[base + 1] * shift; + val = ROUND_POWER_OF_TWO(val, 8); +#endif // CONFIG_INTRA_INTERP dst[c] = clip_pixel_highbd(val, bd); } else { dst[c] = above[2 * bs - 1]; @@ -780,8 +827,10 @@ // Directional prediction, zone 2: 90 < angle < 180 static void highbd_dr_prediction_z2(uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, - int dx, int dy, int bd, - INTRA_FILTER filter_type) { +#if CONFIG_INTRA_INTERP + INTRA_FILTER filter_type, +#endif // CONFIG_INTRA_INTERP + int dx, int dy, int bd) { int r, c, x, y, shift, val, base; assert(dx > 0); @@ -794,16 +843,26 @@ base = x >> 8; if (base >= -1) { shift = x & 0xFF; +#if CONFIG_INTRA_INTERP val = highbd_intra_subpel_interp(base, shift, above, -1, bs - 1, filter_type); +#else + val = above[base] * (256 - shift) + above[base + 1] * shift; + val = ROUND_POWER_OF_TWO(val, 8); +#endif // CONFIG_INTRA_INTERP } else { x = c + 1; y = (r << 8) - x * dy; base = y >> 8; if (base >= 0) { shift = y & 0xFF; +#if CONFIG_INTRA_INTERP val = highbd_intra_subpel_interp(base, shift, left, 0, bs - 1, filter_type); +#else + val = left[base] * (256 - shift) + left[base + 1] * shift; + val = ROUND_POWER_OF_TWO(val, 8); +#endif // CONFIG_INTRA_INTERP } else { val = left[0]; } @@ -817,8 +876,10 @@ // Directional prediction, zone 3: 180 < angle < 270 static void highbd_dr_prediction_z3(uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, - int dx, int dy, int bd, - INTRA_FILTER filter_type) { +#if CONFIG_INTRA_INTERP + INTRA_FILTER filter_type, +#endif // CONFIG_INTRA_INTERP + int dx, int dy, int bd) { int r, c, x, y, base, shift, val; (void)above; @@ -833,8 +894,13 @@ base = y >> 8; shift = y & 0xFF; if (base < 2 * bs - 1) { +#if CONFIG_INTRA_INTERP val = highbd_intra_subpel_interp(base, shift, left, 0, 2 * bs - 1, filter_type); +#else + val = left[base] * (256 - shift) + left[base + 1] * shift; + val = ROUND_POWER_OF_TWO(val, 8); +#endif // CONFIG_INTRA_INTERP dst[c] = clip_pixel_highbd(val, bd); } else { dst[c] = left[2 * bs - 1]; @@ -870,17 +936,32 @@ static void highbd_dr_predictor(uint16_t *dst, ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left, - int angle, int bd, INTRA_FILTER filter) { +#if CONFIG_INTRA_INTERP + INTRA_FILTER filter, +#endif // CONFIG_INTRA_INTERP + int angle, int bd) { const int dx = get_dx(angle); const int dy = get_dy(angle); assert(angle > 0 && angle < 270); if (angle > 0 && angle < 90) { - highbd_dr_prediction_z1(dst, stride, bs, above, left, dx, dy, bd, filter); + highbd_dr_prediction_z1(dst, stride, bs, above, left, +#if CONFIG_INTRA_INTERP + filter, +#endif // CONFIG_INTRA_INTERP + dx, dy, bd); } else if (angle > 90 && angle < 180) { - highbd_dr_prediction_z2(dst, stride, bs, above, left, dx, dy, bd, filter); + highbd_dr_prediction_z2(dst, stride, bs, above, left, +#if CONFIG_INTRA_INTERP + filter, +#endif // CONFIG_INTRA_INTERP + dx, dy, bd); } else if (angle > 180 && angle < 270) { - highbd_dr_prediction_z3(dst, stride, bs, above, left, dx, dy, bd, filter); + highbd_dr_prediction_z3(dst, stride, bs, above, left, +#if CONFIG_INTRA_INTERP + filter, +#endif // CONFIG_INTRA_INTERP + dx, dy, bd); } else if (angle == 90) { highbd_v_predictor(dst, stride, bs, above, left, bd); } else if (angle == 180) { @@ -1397,11 +1478,16 @@ #if CONFIG_EXT_INTRA if (is_dr_mode) { +#if CONFIG_INTRA_INTERP INTRA_FILTER filter = INTRA_FILTER_LINEAR; if (plane == 0 && av1_is_intra_filter_switchable(p_angle)) filter = xd->mi[0]->mbmi.intra_filter; - highbd_dr_predictor(dst, dst_stride, bs, const_above_row, left_col, p_angle, - xd->bd, filter); +#endif // CONFIG_INTRA_INTERP + highbd_dr_predictor(dst, dst_stride, bs, const_above_row, left_col, +#if CONFIG_INTRA_INTERP + filter, +#endif // CONFIG_INTRA_INTERP + p_angle, xd->bd); return; } #endif // CONFIG_EXT_INTRA @@ -1555,11 +1641,16 @@ #endif // CONFIG_FILTER_INTRA #if CONFIG_EXT_INTRA if (is_dr_mode) { +#if CONFIG_INTRA_INTERP INTRA_FILTER filter = INTRA_FILTER_LINEAR; if (plane == 0 && av1_is_intra_filter_switchable(p_angle)) filter = xd->mi[0]->mbmi.intra_filter; - dr_predictor(dst, dst_stride, tx_size, const_above_row, left_col, p_angle, - filter); +#endif // CONFIG_INTRA_INTERP + dr_predictor(dst, dst_stride, tx_size, const_above_row, left_col, +#if CONFIG_INTRA_INTERP + filter, +#endif // CONFIG_INTRA_INTERP + p_angle); return; } #endif // CONFIG_EXT_INTRA
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 70948d0..e35bda6 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c
@@ -4237,9 +4237,11 @@ #endif // CONFIG_EXT_PARTITION_TYPES #endif // EC_ADAPT, DAALA_EC #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP for (i = 0; i < INTRA_FILTERS + 1; ++i) for (j = 0; j < INTRA_FILTERS - 1; ++j) av1_diff_update_prob(&r, &fc->intra_filter_probs[i][j], ACCT_STR); +#endif // CONFIG_INTRA_INTERP #endif // EC_ADAPT, DAALA_EC if (frame_is_intra_only(cm)) {
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c index 7e9dd9a..5709407 100644 --- a/av1/decoder/decodemv.c +++ b/av1/decoder/decodemv.c
@@ -653,14 +653,18 @@ aom_reader *r) { MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const BLOCK_SIZE bsize = mbmi->sb_type; +#if CONFIG_INTRA_INTERP const int ctx = av1_get_pred_context_intra_interp(xd); int p_angle; +#endif // CONFIG_INTRA_INTERP + (void)cm; if (bsize < BLOCK_8X8) return; if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) { mbmi->angle_delta[0] = read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS; +#if CONFIG_INTRA_INTERP p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP; if (av1_is_intra_filter_switchable(p_angle)) { FRAME_COUNTS *counts = xd->counts; @@ -670,6 +674,7 @@ } else { mbmi->intra_filter = INTRA_FILTER_LINEAR; } +#endif // CONFIG_INTRA_INTERP } if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) { @@ -1786,7 +1791,9 @@ #if CONFIG_EXT_INTRA mbmi->angle_delta[0] = 0; mbmi->angle_delta[1] = 0; +#if CONFIG_INTRA_INTERP mbmi->intra_filter = INTRA_FILTER_LINEAR; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_FILTER_INTRA mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 92afa69..78ccf6b 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -110,7 +110,9 @@ static struct av1_token global_motion_types_encodings[GLOBAL_TRANS_TYPES]; #endif // CONFIG_GLOBAL_MOTION #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP static struct av1_token intra_filter_encodings[INTRA_FILTERS]; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_EXT_INTER static struct av1_token interintra_mode_encodings[INTERINTRA_MODES]; @@ -155,7 +157,9 @@ #endif // CONFIG_PALETTE #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP av1_tokens_from_tree(intra_filter_encodings, av1_intra_filter_tree); +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_EXT_INTER av1_tokens_from_tree(interintra_mode_encodings, av1_interintra_mode_tree); @@ -1031,20 +1035,25 @@ aom_writer *w) { const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const BLOCK_SIZE bsize = mbmi->sb_type; +#if CONFIG_INTRA_INTERP const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd); int p_angle; +#endif // CONFIG_INTRA_INTERP + (void)cm; if (bsize < BLOCK_8X8) return; if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) { write_uniform(w, 2 * MAX_ANGLE_DELTAS + 1, MAX_ANGLE_DELTAS + mbmi->angle_delta[0]); +#if CONFIG_INTRA_INTERP p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP; if (av1_is_intra_filter_switchable(p_angle)) { av1_write_token(w, av1_intra_filter_tree, cm->fc->intra_filter_probs[intra_filter_ctx], &intra_filter_encodings[mbmi->intra_filter]); } +#endif // CONFIG_INTRA_INTERP } if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) { @@ -4201,9 +4210,11 @@ #endif // CONFIG_EC_ADAPT, CONFIG_DAALA_EC #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP for (i = 0; i < INTRA_FILTERS + 1; ++i) prob_diff_update(av1_intra_filter_tree, fc->intra_filter_probs[i], counts->intra_filter[i], INTRA_FILTERS, probwt, header_bc); +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #endif // CONFIG_EC_ADAPT, CONFIG_DAALA_EC if (frame_is_intra_only(cm)) {
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index 47ca2fc..7bd1ee1 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c
@@ -5493,6 +5493,7 @@ } #endif // CONFIG_FILTER_INTRA #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) { int p_angle; const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd); @@ -5501,6 +5502,7 @@ if (av1_is_intra_filter_switchable(p_angle)) ++counts->intra_filter[intra_filter_ctx][mbmi->intra_filter]; } +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA }
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h index b20b2a1..0ee5576 100644 --- a/av1/encoder/encoder.h +++ b/av1/encoder/encoder.h
@@ -565,7 +565,9 @@ int inter_tx_type_costs[EXT_TX_SIZES][TX_TYPES]; #endif // CONFIG_EXT_TX #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP int intra_filter_cost[INTRA_FILTERS + 1][INTRA_FILTERS]; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_LOOP_RESTORATION int switchable_restore_cost[RESTORE_SWITCHABLE_TYPES];
diff --git a/av1/encoder/rd.c b/av1/encoder/rd.c index 012386c..2797ebc 100644 --- a/av1/encoder/rd.c +++ b/av1/encoder/rd.c
@@ -148,9 +148,11 @@ } #endif // CONFIG_EXT_TX #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP for (i = 0; i < INTRA_FILTERS + 1; ++i) av1_cost_tokens(cpi->intra_filter_cost[i], fc->intra_filter_probs[i], av1_intra_filter_tree); +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_LOOP_RESTORATION av1_cost_tokens(cpi->switchable_restore_cost, fc->switchable_restore_prob,
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index 3b62c1c..a701e80 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -2408,7 +2408,9 @@ const int *bmode_costs = cpi->mbmode_cost[0]; #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP mic->mbmi.intra_filter = INTRA_FILTER_LINEAR; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_FILTER_INTRA mic->mbmi.filter_intra_mode_info.use_filter_intra_mode[0] = 0; @@ -2553,7 +2555,10 @@ static void pick_intra_angle_routine_sby( const AV1_COMP *const cpi, MACROBLOCK *x, int *rate, int *rate_tokenonly, int64_t *distortion, int *skippable, int *best_angle_delta, - TX_SIZE *best_tx_size, TX_TYPE *best_tx_type, INTRA_FILTER *best_filter, + TX_SIZE *best_tx_size, TX_TYPE *best_tx_type, +#if CONFIG_INTRA_INTERP + INTRA_FILTER *best_filter, +#endif // CONFIG_INTRA_INTERP BLOCK_SIZE bsize, int rate_overhead, int64_t *best_rd) { int this_rate; RD_STATS tokenonly_rd_stats; @@ -2569,7 +2574,9 @@ *best_rd = this_rd; *best_angle_delta = mbmi->angle_delta[0]; *best_tx_size = mbmi->tx_size; +#if CONFIG_INTRA_INTERP *best_filter = mbmi->intra_filter; +#endif // CONFIG_INTRA_INTERP *best_tx_type = mbmi->tx_type; *rate = this_rate; *rate_tokenonly = tokenonly_rd_stats.rate; @@ -2588,9 +2595,12 @@ MB_MODE_INFO *mbmi = &mic->mbmi; int this_rate; RD_STATS tokenonly_rd_stats; - int angle_delta, best_angle_delta = 0, p_angle; + int angle_delta, best_angle_delta = 0; +#if CONFIG_INTRA_INTERP + int p_angle; const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd); INTRA_FILTER filter, best_filter = INTRA_FILTER_LINEAR; +#endif // CONFIG_INTRA_INTERP const double rd_adjust = 1.2; int64_t this_rd; TX_SIZE best_tx_size = mic->mbmi.tx_size; @@ -2602,54 +2612,62 @@ { -1, 1 }, { -3, -1 }, { 1, 3 }, }; const int level1 = 3, level2 = 2; - int i, j, best_i = -1; + int i, j, best_i = -1, first_try = 1; for (i = 0; i < level1; ++i) { + int64_t tmp_best_rd; mic->mbmi.angle_delta[0] = deltas_level1[i]; +#if CONFIG_INTRA_INTERP p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP; for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) { - int64_t tmp_best_rd; if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) && filter != INTRA_FILTER_LINEAR) continue; mic->mbmi.intra_filter = filter; - tmp_best_rd = - (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX) - ? (int64_t)(best_rd * rd_adjust) - : best_rd; +#endif // CONFIG_INTRA_INTERP + tmp_best_rd = (first_try && best_rd < INT64_MAX) + ? (int64_t)(best_rd * rd_adjust) + : best_rd; super_block_yrd(cpi, x, &tokenonly_rd_stats, bsize, tmp_best_rd); if (tokenonly_rd_stats.rate == INT_MAX) { - if (i == 0 && filter == INTRA_FILTER_LINEAR) + if (first_try) return best_rd; else continue; } - this_rate = tokenonly_rd_stats.rate + rate_overhead + - cpi->intra_filter_cost[intra_filter_ctx][filter]; + this_rate = tokenonly_rd_stats.rate + rate_overhead; +#if CONFIG_INTRA_INTERP + this_rate += cpi->intra_filter_cost[intra_filter_ctx][filter]; +#endif // CONFIG_INTRA_INTERP this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, tokenonly_rd_stats.dist); - if (i == 0 && filter == INTRA_FILTER_LINEAR && best_rd < INT64_MAX && - this_rd > best_rd * rd_adjust) + if (first_try && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust) return best_rd; + first_try = 0; if (this_rd < best_rd) { best_i = i; best_rd = this_rd; best_angle_delta = mbmi->angle_delta[0]; best_tx_size = mbmi->tx_size; +#if CONFIG_INTRA_INTERP best_filter = mbmi->intra_filter; +#endif // CONFIG_INTRA_INTERP best_tx_type = mbmi->tx_type; *rate = this_rate; *rate_tokenonly = tokenonly_rd_stats.rate; *distortion = tokenonly_rd_stats.dist; *skippable = tokenonly_rd_stats.skip; } +#if CONFIG_INTRA_INTERP } +#endif // CONFIG_INTRA_INTERP } if (best_i >= 0) { for (j = 0; j < level2; ++j) { mic->mbmi.angle_delta[0] = deltas_level2[best_i][j]; +#if CONFIG_INTRA_INTERP p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP; for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) { @@ -2658,19 +2676,30 @@ !av1_is_intra_filter_switchable(p_angle)) && filter != INTRA_FILTER_LINEAR) continue; +#endif // CONFIG_INTRA_INTERP pick_intra_angle_routine_sby( cpi, x, rate, rate_tokenonly, distortion, skippable, - &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter, + &best_angle_delta, &best_tx_size, &best_tx_type, +#if CONFIG_INTRA_INTERP + &best_filter, +#endif // CONFIG_INTRA_INTERP bsize, +#if CONFIG_INTRA_INTERP rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter], +#else + rate_overhead, +#endif // CONFIG_INTRA_INTERP &best_rd); +#if CONFIG_INTRA_INTERP } +#endif // CONFIG_INTRA_INTERP } } } else { for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS; ++angle_delta) { mbmi->angle_delta[0] = angle_delta; +#if CONFIG_INTRA_INTERP p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP; for (filter = INTRA_FILTER_LINEAR; filter < INTRA_FILTERS; ++filter) { @@ -2678,16 +2707,27 @@ if ((FILTER_FAST_SEARCH || !av1_is_intra_filter_switchable(p_angle)) && filter != INTRA_FILTER_LINEAR) continue; +#endif // CONFIG_INTRA_INTERP pick_intra_angle_routine_sby( cpi, x, rate, rate_tokenonly, distortion, skippable, - &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter, + &best_angle_delta, &best_tx_size, &best_tx_type, +#if CONFIG_INTRA_INTERP + &best_filter, +#endif // CONFIG_INTRA_INTERP bsize, +#if CONFIG_INTRA_INTERP rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter], +#else + rate_overhead, +#endif // CONFIG_INTRA_INTERP &best_rd); +#if CONFIG_INTRA_INTERP } +#endif // CONFIG_INTRA_INTERP } } +#if CONFIG_INTRA_INTERP if (FILTER_FAST_SEARCH && *rate_tokenonly < INT_MAX) { mbmi->angle_delta[0] = best_angle_delta; p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP; @@ -2698,15 +2738,22 @@ cpi, x, rate, rate_tokenonly, distortion, skippable, &best_angle_delta, &best_tx_size, &best_tx_type, &best_filter, bsize, +#if CONFIG_INTRA_INTERP rate_overhead + cpi->intra_filter_cost[intra_filter_ctx][filter], +#else + rate_overhead, +#endif // CONFIG_INTRA_INTERP &best_rd); } } } +#endif // CONFIG_INTRA_INTERP mbmi->tx_size = best_tx_size; mbmi->angle_delta[0] = best_angle_delta; +#if CONFIG_INTRA_INTERP mic->mbmi.intra_filter = best_filter; +#endif // CONFIG_INTRA_INTERP mbmi->tx_type = best_tx_type; return best_rd; } @@ -2857,9 +2904,11 @@ const int cols = block_size_wide[bsize]; #endif // CONFIG_EXT_INTRA || CONFIG_PALETTE #if CONFIG_EXT_INTRA +#if CONFIG_INTRA_INTERP const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd); - int is_directional_mode, rate_overhead, best_angle_delta = 0; INTRA_FILTER best_filter = INTRA_FILTER_LINEAR; +#endif // CONFIG_INTRA_INTERP + int is_directional_mode, rate_overhead, best_angle_delta = 0; uint8_t directional_mode_skip_mask[INTRA_MODES]; const int src_stride = x->plane[0].src.stride; const uint8_t *src = x->plane[0].src.buf; @@ -2987,15 +3036,17 @@ #endif // CONFIG_FILTER_INTRA #if CONFIG_EXT_INTRA if (is_directional_mode) { +#if CONFIG_INTRA_INTERP int p_angle; - this_rate += - write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, - MAX_ANGLE_DELTAS + mic->mbmi.angle_delta[0]); p_angle = mode_to_angle_map[mic->mbmi.mode] + mic->mbmi.angle_delta[0] * ANGLE_STEP; if (av1_is_intra_filter_switchable(p_angle)) this_rate += cpi->intra_filter_cost[intra_filter_ctx][mic->mbmi.intra_filter]; +#endif // CONFIG_INTRA_INTERP + this_rate += + write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, + MAX_ANGLE_DELTAS + mic->mbmi.angle_delta[0]); } #endif // CONFIG_EXT_INTRA this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion); @@ -3011,7 +3062,9 @@ best_tx = mic->mbmi.tx_size; #if CONFIG_EXT_INTRA best_angle_delta = mic->mbmi.angle_delta[0]; +#if CONFIG_INTRA_INTERP best_filter = mic->mbmi.intra_filter; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_FILTER_INTRA beat_best_rd = 1; @@ -3066,7 +3119,9 @@ mic->mbmi.tx_size = best_tx; #if CONFIG_EXT_INTRA mic->mbmi.angle_delta[0] = best_angle_delta; +#if CONFIG_INTRA_INTERP mic->mbmi.intra_filter = best_filter; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA mic->mbmi.tx_type = best_tx_type; #if CONFIG_PALETTE @@ -9191,14 +9246,16 @@ } #if CONFIG_EXT_INTRA if (is_directional_mode) { +#if CONFIG_INTRA_INTERP int p_angle; const int intra_filter_ctx = av1_get_pred_context_intra_interp(xd); - rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, - MAX_ANGLE_DELTAS + mbmi->angle_delta[0]); p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP; if (av1_is_intra_filter_switchable(p_angle)) rate2 += cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter]; +#endif // CONFIG_INTRA_INTERP + rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, + MAX_ANGLE_DELTAS + mbmi->angle_delta[0]); } if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) { rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, @@ -9258,7 +9315,9 @@ #if CONFIG_EXT_INTRA mbmi->angle_delta[0] = 0; mbmi->angle_delta[1] = 0; +#if CONFIG_INTRA_INTERP mbmi->intra_filter = INTRA_FILTER_LINEAR; +#endif // CONFIG_INTRA_INTERP #endif // CONFIG_EXT_INTRA #if CONFIG_FILTER_INTRA mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
diff --git a/configure b/configure index fc6ac65..fd1d931 100755 --- a/configure +++ b/configure
@@ -263,6 +263,7 @@ tx64x64 sub8x8_mc ext_intra + intra_interp filter_intra ext_inter ext_interp