Merge "Adding experiment for supertransform" into nextgenv2
diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h
index c4dce60..03e34e0 100644
--- a/vp10/common/blockd.h
+++ b/vp10/common/blockd.h
@@ -89,7 +89,6 @@
// 1: an ext intra mode is used; 0: otherwise.
uint8_t use_ext_intra_mode[PLANE_TYPES];
EXT_INTRA_MODE ext_intra_mode[PLANE_TYPES];
- uint8_t ext_intra_angle[PLANE_TYPES];
} EXT_INTRA_MODE_INFO;
#endif // CONFIG_EXT_INTRA
@@ -124,6 +123,7 @@
#if CONFIG_EXT_INTRA
EXT_INTRA_MODE_INFO ext_intra_mode_info;
+ int8_t angle_delta[2];
#endif // CONFIG_EXT_INTRA
// TODO(slavarnway): Delete and use bmi[3].as_mv[] instead.
@@ -328,14 +328,14 @@
#endif // CONFIG_EXT_TX
#if CONFIG_EXT_INTRA
-// 0: use both directional and filter modes; 1: use directional modes only.
-#define DR_ONLY 0
-// 0: use slow exhaustive search; 1: use fast sub-optimal search.
+#define ALLOW_FILTER_INTRA_MODES 1
+#define ANGLE_STEP 3
+#define MAX_ANGLE_DELTAS 3
#define ANGLE_FAST_SEARCH 1
-// A parameter to adjust early termination in the fast search of angles.
-#define RD_ADJUSTER 1.4
-// Number of different angles that are supported
-#define EXT_INTRA_ANGLES 128
+
+static uint8_t mode_to_angle_map[INTRA_MODES] = {
+ 0, 90, 180, 45, 135, 111, 157, 203, 67, 0,
+};
static const TX_TYPE filter_intra_mode_to_tx_type_lookup[FILTER_INTRA_MODES] = {
DCT_DCT, // FILTER_DC
@@ -349,13 +349,6 @@
ADST_DCT, // FILTER_D63
ADST_ADST, // FILTER_TM
};
-
-// Maps the angle index to the actual prediction angle (in degrees).
-// Angle index is in the range [0, EXT_INTRA_ANGLES); the actual prediction
-// angle is in the range (0, 270).
-static INLINE int prediction_angle_map(int angle_in) {
- return (10 + 2 * angle_in);
-}
#endif // CONFIG_EXT_INTRA
static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type,
@@ -363,33 +356,44 @@
int block_idx, TX_SIZE tx_size) {
const MODE_INFO *const mi = xd->mi[0];
const MB_MODE_INFO *const mbmi = &mi->mbmi;
-#if CONFIG_EXT_INTRA
- const int use_ext_intra_mode_info =
- mbmi->ext_intra_mode_info.use_ext_intra_mode[plane_type];
- const EXT_INTRA_MODE ext_intra_mode =
- mbmi->ext_intra_mode_info.ext_intra_mode[plane_type];
- if (!is_inter_block(mbmi) && use_ext_intra_mode_info) {
- if (!xd->lossless[mbmi->segment_id] && tx_size < TX_32X32
+#if CONFIG_EXT_INTRA
+ if (!is_inter_block(mbmi)) {
+ const int use_ext_intra_mode_info =
+ mbmi->ext_intra_mode_info.use_ext_intra_mode[plane_type];
+ const EXT_INTRA_MODE ext_intra_mode =
+ mbmi->ext_intra_mode_info.ext_intra_mode[plane_type];
+ const PREDICTION_MODE mode = (plane_type == PLANE_TYPE_Y) ?
+ get_y_mode(mi, block_idx) : mbmi->uv_mode;
+
+ if (xd->lossless[mbmi->segment_id] || tx_size >= TX_32X32)
+ return DCT_DCT;
+
#if CONFIG_EXT_TX
- && !(mbmi->sb_type >= BLOCK_8X8 && plane_type == PLANE_TYPE_Y)
+ if (mbmi->sb_type >= BLOCK_8X8 && plane_type == PLANE_TYPE_Y)
+ return mbmi->tx_type;
#endif // CONFIG_EXT_TX
- ) {
- if (ext_intra_mode > FILTER_TM_PRED) {
- int angle = mbmi->ext_intra_mode_info.ext_intra_angle[plane_type];
- angle = prediction_angle_map(angle);
- assert(angle > 0 && angle < 270);
- if (angle == 135)
- return ADST_ADST;
- else if (angle < 45 || angle > 225)
- return DCT_DCT;
- else if (angle < 135)
- return ADST_DCT;
- else
- return DCT_ADST;
- } else {
- return filter_intra_mode_to_tx_type_lookup[ext_intra_mode];
- }
+
+ if (use_ext_intra_mode_info)
+ return filter_intra_mode_to_tx_type_lookup[ext_intra_mode];
+
+ if (mode == DC_PRED) {
+ return DCT_DCT;
+ } else if (mode == TM_PRED) {
+ return ADST_ADST;
+ } else {
+ int angle = mode_to_angle_map[mode];
+ if (mbmi->sb_type >= BLOCK_8X8)
+ angle += mbmi->angle_delta[plane_type] * ANGLE_STEP;
+ assert(angle > 0 && angle < 270);
+ if (angle == 135)
+ return ADST_ADST;
+ else if (angle < 45 || angle > 225)
+ return DCT_DCT;
+ else if (angle < 135)
+ return ADST_DCT;
+ else
+ return DCT_ADST;
}
}
#endif // CONFIG_EXT_INTRA
diff --git a/vp10/common/entropymode.c b/vp10/common/entropymode.c
index e347c23..ceb55df 100644
--- a/vp10/common/entropymode.c
+++ b/vp10/common/entropymode.c
@@ -1094,7 +1094,7 @@
#endif
#if CONFIG_EXT_INTRA
-static const vpx_prob default_ext_intra_probs[2] = {200, 200};
+static const vpx_prob default_ext_intra_probs[2] = {230, 230};
#endif // CONFIG_EXT_INTRA
static void init_mode_probs(FRAME_CONTEXT *fc) {
diff --git a/vp10/common/entropymode.h b/vp10/common/entropymode.h
index 00eacc5..2b5c948 100644
--- a/vp10/common/entropymode.h
+++ b/vp10/common/entropymode.h
@@ -32,11 +32,6 @@
#define PALETTE_BLOCK_SIZES (BLOCK_64X64 - BLOCK_8X8 + 1)
#define PALETTE_Y_MODE_CONTEXTS 3
-#if CONFIG_EXT_INTRA
-// Probability that an ext_intra mode is a directional prediction mode
-#define DR_EXT_INTRA_PROB 144
-#endif // CONFIG_EXT_INTRA
-
struct VP10Common;
struct tx_probs {
diff --git a/vp10/common/enums.h b/vp10/common/enums.h
index 56e9c90..3f9395e 100644
--- a/vp10/common/enums.h
+++ b/vp10/common/enums.h
@@ -168,7 +168,6 @@
FILTER_D207_PRED,
FILTER_D63_PRED,
FILTER_TM_PRED,
- EXT_DR_PRED,
EXT_INTRA_MODES,
} EXT_INTRA_MODE;
diff --git a/vp10/common/reconintra.c b/vp10/common/reconintra.c
index 474edbd..87dc13a 100644
--- a/vp10/common/reconintra.c
+++ b/vp10/common/reconintra.c
@@ -405,32 +405,11 @@
}
}
-static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
- const uint8_t *above, const uint8_t *left) {
- int r;
- (void) left;
-
- for (r = 0; r < bs; r++) {
- memcpy(dst, above, bs);
- dst += stride;
- }
-}
-
-static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
- const uint8_t *above, const uint8_t *left) {
- int r;
- (void) above;
-
- for (r = 0; r < bs; r++) {
- memset(dst, left[r], bs);
- dst += stride;
- }
-}
-
-static void dr_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
+static void dr_predictor(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
const uint8_t *above, const uint8_t *left, int angle) {
double t = 0;
int dx, dy;
+ int bs = 4 << tx_size;
if (angle != 90 && angle != 180)
t = tan(angle * PI / 180.0);
@@ -448,9 +427,9 @@
dy = -((int)(256 * t));
dr_prediction_z3(dst, stride, bs, above, left, dx, dy);
} else if (angle == 90) {
- v_predictor(dst, stride, bs, above, left);
+ pred[V_PRED][tx_size](dst, stride, above, left);
} else if (angle == 180) {
- h_predictor(dst, stride, bs, above, left);
+ pred[H_PRED][tx_size](dst, stride, above, left);
}
}
@@ -915,11 +894,7 @@
int i;
uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
-#if CONFIG_MISC_FIXES
- DECLARE_ALIGNED(16, uint16_t, left_col[32]);
-#else
DECLARE_ALIGNED(16, uint16_t, left_col[64]);
-#endif
DECLARE_ALIGNED(16, uint16_t, above_data[64 + 16]);
uint16_t *above_row = above_data + 16;
const uint16_t *const_above_row = above_row;
@@ -946,37 +921,38 @@
&xd->mi[0]->mbmi.ext_intra_mode_info;
const EXT_INTRA_MODE ext_intra_mode =
ext_intra_mode_info->ext_intra_mode[plane != 0];
- const int angle =
- prediction_angle_map(ext_intra_mode_info->ext_intra_angle[plane != 0]);
+ int p_angle = 0;
+
+ if (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
+ p_angle = mode_to_angle_map[mode] +
+ xd->mi[0]->mbmi.angle_delta[plane != 0] * ANGLE_STEP;
+#if CONFIG_MISC_FIXES
+ if (p_angle <= 90)
+ need_above = 1, need_left = 0;
+ else if (p_angle < 180)
+ need_above = 1, need_left = 1;
+ else
+ need_above = 0, need_left = 1;
+#else
+ if (p_angle < 90)
+ need_above = 0, need_aboveright = 1, need_left = 0;
+ else if (p_angle == 90)
+ need_above = 1, need_aboveright = 0, need_left = 0;
+ else if (p_angle < 180)
+ need_above = 1, need_aboveright = 0, need_left = 1;
+ else
+ need_above = 0, need_aboveright = 0, need_left = 1;
+#endif // CONFIG_MISC_FIXES
+ }
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
EXT_INTRA_MODE ext_intra_mode =
ext_intra_mode_info->ext_intra_mode[plane != 0];
- if (ext_intra_mode <= FILTER_TM_PRED) {
- need_left = ext_intra_extend_modes[ext_intra_mode] & NEED_LEFT;
- need_above = ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVE;
- need_aboveright =
- ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVERIGHT;
- } else {
- assert(angle > 0 && angle < 270);
-#if CONFIG_MISC_FIXES
- if (angle <= 90)
- need_above = 1, need_left = 0;
- else if (angle < 180)
- need_above = 1, need_left = 1;
- else
- need_above = 0, need_left = 1;
-#else
- if (angle < 90)
- need_above = 0, need_aboveright = 1, need_left = 0;
- else if (angle == 90)
- need_above = 1, need_aboveright = 0, need_left = 0;
- else if (angle < 180)
- need_above = 1, need_aboveright = 0, need_left = 1;
- else
- need_above = 0, need_aboveright = 0, need_left = 1;
-#endif // CONFIG_MISC_FIXES
- }
+ need_left = ext_intra_extend_modes[ext_intra_mode] & NEED_LEFT;
+ need_above = ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVE;
+ need_aboveright =
+ ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVERIGHT;
}
#endif // CONFIG_EXT_INTRA
@@ -993,10 +969,10 @@
#if CONFIG_EXT_INTRA
int need_bottom;
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
- if (ext_intra_mode <= FILTER_TM_PRED)
need_bottom = 0;
- else
- need_bottom = angle > 180;
+ } else if (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
+ need_bottom = p_angle > 180;
} else {
need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
}
@@ -1024,10 +1000,10 @@
#if CONFIG_EXT_INTRA
int need_right;
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
- if (ext_intra_mode <= FILTER_TM_PRED)
- need_right = 1;
- else
- need_right = angle < 90;
+ need_right = 1;
+ } else if (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
+ need_right = p_angle < 90;
} else {
need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
}
@@ -1052,7 +1028,9 @@
(void)need_aboveright;
#if CONFIG_EXT_INTRA
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0] ||
- (extend_modes[mode] & NEED_ABOVELEFT)) {
+ (extend_modes[mode] & NEED_ABOVELEFT) ||
+ (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8)) {
above_row[-1] = n_top_px > 0 ?
(n_left_px > 0 ? above_ref[-1] : base + 1) : base - 1;
}
@@ -1185,13 +1163,15 @@
#if CONFIG_EXT_INTRA
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
- if (ext_intra_mode <= FILTER_TM_PRED)
- highbd_filter_intra_predictors[ext_intra_mode](dst, dst_stride, bs,
- const_above_row, left_col,
- bd);
- else
- highbd_dr_predictor(dst, dst_stride, bs, const_above_row, left_col,
- angle, bd);
+ highbd_filter_intra_predictors[ext_intra_mode](dst, dst_stride, bs,
+ const_above_row, left_col, bd);
+ return;
+ }
+
+ if (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
+ highbd_dr_predictor(dst, dst_stride, bs, const_above_row, left_col,
+ p_angle, bd);
return;
}
#endif // CONFIG_EXT_INTRA
@@ -1247,37 +1227,39 @@
&xd->mi[0]->mbmi.ext_intra_mode_info;
const EXT_INTRA_MODE ext_intra_mode =
ext_intra_mode_info->ext_intra_mode[plane != 0];
- const int angle =
- prediction_angle_map(ext_intra_mode_info->ext_intra_angle[plane != 0]);
+ int p_angle = 0;
+
+ if (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
+ p_angle = mode_to_angle_map[mode] +
+ xd->mi[0]->mbmi.angle_delta[plane != 0] * ANGLE_STEP;
+
+#if CONFIG_MISC_FIXES
+ if (p_angle <= 90)
+ need_above = 1, need_left = 0;
+ else if (p_angle < 180)
+ need_above = 1, need_left = 1;
+ else
+ need_above = 0, need_left = 1;
+#else
+ if (p_angle < 90)
+ need_above = 0, need_aboveright = 1, need_left = 0;
+ else if (p_angle == 90)
+ need_above = 1, need_aboveright = 0, need_left = 0;
+ else if (p_angle < 180)
+ need_above = 1, need_aboveright = 0, need_left = 1;
+ else
+ need_above = 0, need_aboveright = 0, need_left = 1;
+#endif // CONFIG_MISC_FIXES
+ }
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
EXT_INTRA_MODE ext_intra_mode =
ext_intra_mode_info->ext_intra_mode[plane != 0];
- if (ext_intra_mode <= FILTER_TM_PRED) {
- need_left = ext_intra_extend_modes[ext_intra_mode] & NEED_LEFT;
- need_above = ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVE;
- need_aboveright =
- ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVERIGHT;
- } else {
- assert(angle > 0 && angle < 270);
-#if CONFIG_MISC_FIXES
- if (angle <= 90)
- need_above = 1, need_left = 0;
- else if (angle < 180)
- need_above = 1, need_left = 1;
- else
- need_above = 0, need_left = 1;
-#else
- if (angle < 90)
- need_above = 0, need_aboveright = 1, need_left = 0;
- else if (angle == 90)
- need_above = 1, need_aboveright = 0, need_left = 0;
- else if (angle < 180)
- need_above = 1, need_aboveright = 0, need_left = 1;
- else
- need_above = 0, need_aboveright = 0, need_left = 1;
-#endif // CONFIG_MISC_FIXES
- }
+ need_left = ext_intra_extend_modes[ext_intra_mode] & NEED_LEFT;
+ need_above = ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVE;
+ need_aboveright =
+ ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVERIGHT;
}
#endif // CONFIG_EXT_INTRA
@@ -1318,10 +1300,10 @@
#if CONFIG_EXT_INTRA
int need_bottom;
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
- if (ext_intra_mode <= FILTER_TM_PRED)
- need_bottom = 0;
- else
- need_bottom = angle > 180;
+ need_bottom = 0;
+ } else if (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
+ need_bottom = p_angle > 180;
} else {
need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
}
@@ -1373,10 +1355,10 @@
#if CONFIG_EXT_INTRA
int need_right;
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
- if (ext_intra_mode <= FILTER_TM_PRED)
- need_right = 1;
- else
- need_right = angle < 90;
+ need_right = 1;
+ } else if (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
+ need_right = p_angle < 90;
} else {
need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
}
@@ -1428,7 +1410,9 @@
(void)need_aboveright;
#if CONFIG_EXT_INTRA
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0] ||
- (extend_modes[mode] & NEED_ABOVELEFT)) {
+ (extend_modes[mode] & NEED_ABOVELEFT) ||
+ (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8)) {
above_row[-1] = n_top_px > 0 ? (n_left_px > 0 ? above_ref[-1] : 129) : 127;
}
#else
@@ -1486,11 +1470,14 @@
#if CONFIG_EXT_INTRA
if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
- if (ext_intra_mode <= FILTER_TM_PRED)
- filter_intra_predictors[ext_intra_mode](dst, dst_stride, bs,
- const_above_row, left_col);
- else
- dr_predictor(dst, dst_stride, bs, const_above_row, left_col, angle);
+ filter_intra_predictors[ext_intra_mode](dst, dst_stride, bs,
+ const_above_row, left_col);
+ return;
+ }
+
+ if (mode != DC_PRED && mode != TM_PRED &&
+ xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
+ dr_predictor(dst, dst_stride, tx_size, const_above_row, left_col, p_angle);
return;
}
#endif // CONFIG_EXT_INTRA
@@ -1510,10 +1497,10 @@
}
void vp10_predict_intra_block(const MACROBLOCKD *xd, int bwl_in, int bhl_in,
- TX_SIZE tx_size, PREDICTION_MODE mode,
- const uint8_t *ref, int ref_stride,
- uint8_t *dst, int dst_stride,
- int aoff, int loff, int plane) {
+ TX_SIZE tx_size, PREDICTION_MODE mode,
+ const uint8_t *ref, int ref_stride,
+ uint8_t *dst, int dst_stride,
+ int aoff, int loff, int plane) {
const int txw = (1 << tx_size);
const int have_top = loff || xd->up_available;
const int have_left = aoff || xd->left_available;
diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c
index cc0f3f0..a8868d4 100644
--- a/vp10/decoder/decodemv.c
+++ b/vp10/decoder/decodemv.c
@@ -346,18 +346,16 @@
MODE_INFO *const mi = xd->mi[0];
MB_MODE_INFO *const mbmi = &mi->mbmi;
FRAME_COUNTS *counts = xd->counts;
+
+#if !ALLOW_FILTER_INTRA_MODES
+ return;
+#endif
if (mbmi->mode == DC_PRED) {
mbmi->ext_intra_mode_info.use_ext_intra_mode[0] =
vpx_read(r, cm->fc->ext_intra_probs[0]);
if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
- if (DR_ONLY ? 1 : vpx_read(r, DR_EXT_INTRA_PROB)) {
- mbmi->ext_intra_mode_info.ext_intra_mode[0] = EXT_DR_PRED;
- mbmi->ext_intra_mode_info.ext_intra_angle[0] =
- read_uniform(r, EXT_INTRA_ANGLES);
- } else {
- mbmi->ext_intra_mode_info.ext_intra_mode[0] =
- read_uniform(r, FILTER_INTRA_MODES);
- }
+ mbmi->ext_intra_mode_info.ext_intra_mode[0] =
+ read_uniform(r, FILTER_INTRA_MODES);
}
if (counts)
++counts->ext_intra[0][mbmi->ext_intra_mode_info.use_ext_intra_mode[0]];
@@ -366,14 +364,8 @@
mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
vpx_read(r, cm->fc->ext_intra_probs[1]);
if (mbmi->ext_intra_mode_info.use_ext_intra_mode[1]) {
- if (DR_ONLY ? 1 : vpx_read(r, DR_EXT_INTRA_PROB)) {
- mbmi->ext_intra_mode_info.ext_intra_mode[1] = EXT_DR_PRED;
- mbmi->ext_intra_mode_info.ext_intra_angle[1] =
- read_uniform(r, EXT_INTRA_ANGLES);
- } else {
- mbmi->ext_intra_mode_info.ext_intra_mode[1] =
- read_uniform(r, FILTER_INTRA_MODES);
- }
+ mbmi->ext_intra_mode_info.ext_intra_mode[1] =
+ read_uniform(r, FILTER_INTRA_MODES);
}
if (counts)
++counts->ext_intra[1][mbmi->ext_intra_mode_info.use_ext_intra_mode[1]];
@@ -426,9 +418,20 @@
default:
mbmi->mode = read_intra_mode(r,
get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
+#if CONFIG_EXT_INTRA
+ if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
+ mbmi->angle_delta[0] =
+ read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
+#endif // CONFIG_EXT_INTRA
}
mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
+#if CONFIG_EXT_INTRA
+ if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED &&
+ bsize >= BLOCK_8X8)
+ mbmi->angle_delta[1] =
+ read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
+#endif
mbmi->palette_mode_info.palette_size[0] = 0;
mbmi->palette_mode_info.palette_size[1] = 0;
@@ -591,8 +594,6 @@
cm->fc->switchable_interp_prob[ctx]);
if (counts)
++counts->switchable_interp[ctx][type];
- // printf("%d/%d -> %d, %d\n", cm->current_video_frame, cm->show_frame,
- // xd->mi[0]->mbmi.sb_type, xd->mi[0]->mbmi.interp_filter);
return type;
}
@@ -626,9 +627,22 @@
break;
default:
mbmi->mode = read_intra_mode_y(cm, xd, r, size_group_lookup[bsize]);
+#if CONFIG_EXT_INTRA
+ mbmi->angle_delta[0] = 0;
+ if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
+ mbmi->angle_delta[0] =
+ read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
+#endif // CONFIG_EXT_INTRA
}
mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
+#if CONFIG_EXT_INTRA
+ if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED &&
+ bsize >= BLOCK_8X8)
+ mbmi->angle_delta[1] =
+ read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
+#endif // CONFIG_EXT_INTRA
+
mbmi->palette_mode_info.palette_size[0] = 0;
mbmi->palette_mode_info.palette_size[1] = 0;
#if CONFIG_EXT_INTRA
diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c
index beb3414..a7b1f24 100644
--- a/vp10/encoder/bitstream.c
+++ b/vp10/encoder/bitstream.c
@@ -520,19 +520,15 @@
static void write_ext_intra_mode_info(const VP10_COMMON *const cm,
const MB_MODE_INFO *const mbmi,
vpx_writer *w) {
+#if !ALLOW_FILTER_INTRA_MODES
+ return;
+#endif
if (mbmi->mode == DC_PRED) {
vpx_write(w, mbmi->ext_intra_mode_info.use_ext_intra_mode[0],
cm->fc->ext_intra_probs[0]);
if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
EXT_INTRA_MODE mode = mbmi->ext_intra_mode_info.ext_intra_mode[0];
- int dr_mode = mode > FILTER_TM_PRED;
- if (!DR_ONLY)
- vpx_write(w, dr_mode, DR_EXT_INTRA_PROB);
- if (dr_mode)
- write_uniform(w, EXT_INTRA_ANGLES,
- mbmi->ext_intra_mode_info.ext_intra_angle[0]);
- else
- write_uniform(w, FILTER_INTRA_MODES, mode);
+ write_uniform(w, FILTER_INTRA_MODES, mode);
}
}
if (mbmi->uv_mode == DC_PRED) {
@@ -540,14 +536,7 @@
cm->fc->ext_intra_probs[1]);
if (mbmi->ext_intra_mode_info.use_ext_intra_mode[1]) {
EXT_INTRA_MODE mode = mbmi->ext_intra_mode_info.ext_intra_mode[1];
- int dr_mode = mode > FILTER_TM_PRED;
- if (!DR_ONLY)
- vpx_write(w, dr_mode, DR_EXT_INTRA_PROB);
- if (dr_mode)
- write_uniform(w, EXT_INTRA_ANGLES,
- mbmi->ext_intra_mode_info.ext_intra_angle[1]);
- else
- write_uniform(w, FILTER_INTRA_MODES, mode);
+ write_uniform(w, FILTER_INTRA_MODES, mode);
}
}
}
@@ -644,6 +633,12 @@
if (!is_inter) {
if (bsize >= BLOCK_8X8) {
write_intra_mode(w, mode, cm->fc->y_mode_prob[size_group_lookup[bsize]]);
+#if CONFIG_EXT_INTRA
+ if (mode != DC_PRED && mode != TM_PRED) {
+ write_uniform(w, 2 * MAX_ANGLE_DELTAS + 1,
+ MAX_ANGLE_DELTAS + mbmi->angle_delta[0]);
+ }
+#endif // CONFIG_EXT_INTRA
} else {
int idx, idy;
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
@@ -657,6 +652,11 @@
}
write_intra_mode(w, mbmi->uv_mode, cm->fc->uv_mode_prob[mode]);
#if CONFIG_EXT_INTRA
+ if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED &&
+ bsize >= BLOCK_8X8)
+ write_uniform(w, 2 * MAX_ANGLE_DELTAS + 1,
+ MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
+
if (bsize >= BLOCK_8X8)
write_ext_intra_mode_info(cm, mbmi, w);
#endif // CONFIG_EXT_INTRA
@@ -782,6 +782,11 @@
if (bsize >= BLOCK_8X8) {
write_intra_mode(w, mbmi->mode,
get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
+#if CONFIG_EXT_INTRA
+ if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED)
+ write_uniform(w, 2 * MAX_ANGLE_DELTAS + 1,
+ MAX_ANGLE_DELTAS + mbmi->angle_delta[0]);
+#endif // CONFIG_EXT_INTRA
} else {
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
@@ -797,6 +802,12 @@
}
write_intra_mode(w, mbmi->uv_mode, cm->fc->uv_mode_prob[mbmi->mode]);
+#if CONFIG_EXT_INTRA
+ if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED &&
+ bsize >= BLOCK_8X8)
+ write_uniform(w, 2 * MAX_ANGLE_DELTAS + 1,
+ MAX_ANGLE_DELTAS + mbmi->angle_delta[1]);
+#endif // CONFIG_EXT_INTRA
if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools &&
mbmi->mode == DC_PRED)
diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c
index dc56563..5c447b2 100644
--- a/vp10/encoder/rdopt.c
+++ b/vp10/encoder/rdopt.c
@@ -1507,10 +1507,7 @@
MB_MODE_INFO *mbmi = &mic->mbmi;
int this_rate, this_rate_tokenonly, s;
int ext_intra_selected_flag = 0;
- int i, step, delta, angle, best_angle, best_angle_dir;
- int deltas[3] = {25, 5, 1};
- int branches[3] = {2, 2, 2};
- int64_t this_distortion, this_rd, best_angle_rd = INT64_MAX;
+ int64_t this_distortion, this_rd;
EXT_INTRA_MODE mode;
TX_SIZE best_tx_size = TX_4X4;
EXT_INTRA_MODE_INFO ext_intra_mode_info;
@@ -1522,123 +1519,30 @@
mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 1;
mbmi->mode = DC_PRED;
- if (!DR_ONLY) {
- for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
- mbmi->ext_intra_mode_info.ext_intra_mode[0] = mode;
- super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
- &s, NULL, bsize, *best_rd);
- if (this_rate_tokenonly == INT_MAX)
- continue;
+ for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
+ mbmi->ext_intra_mode_info.ext_intra_mode[0] = mode;
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, *best_rd);
+ if (this_rate_tokenonly == INT_MAX)
+ continue;
- this_rate = this_rate_tokenonly +
- vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 1) +
- vp10_cost_bit(DR_EXT_INTRA_PROB, 0) +
- write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
- this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ this_rate = this_rate_tokenonly +
+ vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 1) +
+ write_uniform_cost(FILTER_INTRA_MODES, mode) + mode_cost;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
- if (this_rd < *best_rd) {
- *best_rd = this_rd;
- best_tx_size = mic->mbmi.tx_size;
- ext_intra_mode_info = mbmi->ext_intra_mode_info;
+ if (this_rd < *best_rd) {
+ *best_rd = this_rd;
+ best_tx_size = mic->mbmi.tx_size;
+ ext_intra_mode_info = mbmi->ext_intra_mode_info;
#if CONFIG_EXT_TX
- best_tx_type = mic->mbmi.tx_type;
+ best_tx_type = mic->mbmi.tx_type;
#endif // CONFIG_EXT_TX
- *rate = this_rate;
- *rate_tokenonly = this_rate_tokenonly;
- *distortion = this_distortion;
- *skippable = s;
- ext_intra_selected_flag = 1;
- }
- }
- }
-
- mbmi->ext_intra_mode_info.ext_intra_mode[0] = EXT_DR_PRED;
- if (ANGLE_FAST_SEARCH) {
- best_angle = EXT_INTRA_ANGLES / 2;
- for (step = 0; step < 3; ++step) {
- delta = deltas[step];
- for (i = -branches[step]; i <= branches[step]; ++i) {
- int64_t rd_thresh;
- if (i == 0 && step != 0)
- continue;
- angle = best_angle + i * delta;
- if (angle < 0)
- angle = 0;
- if (angle >= EXT_INTRA_ANGLES)
- angle = EXT_INTRA_ANGLES - 1;
- if (angle == best_angle && step != 0)
- continue;
- mbmi->ext_intra_mode_info.ext_intra_angle[0] = angle;
- if (*best_rd == INT64_MAX)
- rd_thresh = best_angle_rd;
- else
- rd_thresh = VPXMIN(best_angle_rd, *best_rd * RD_ADJUSTER);
- super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
- &s, NULL, bsize, rd_thresh);
- if (this_rate_tokenonly == INT_MAX)
- continue;
- this_rate = this_rate_tokenonly +
- vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 1) +
- (DR_ONLY ? 0: vp10_cost_bit(DR_EXT_INTRA_PROB, 1)) +
- write_uniform_cost(EXT_INTRA_ANGLES, angle) + mode_cost;
- this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
- if (this_rd < *best_rd) {
- *best_rd = this_rd;
- best_tx_size = mic->mbmi.tx_size;
- ext_intra_mode_info = mbmi->ext_intra_mode_info;
-#if CONFIG_EXT_TX
- best_tx_type = mic->mbmi.tx_type;
-#endif // CONFIG_EXT_TX
- *rate = this_rate;
- *rate_tokenonly = this_rate_tokenonly;
- *distortion = this_distortion;
- *skippable = s;
- ext_intra_selected_flag = 1;
- }
- if (this_rd < best_angle_rd) {
- best_angle_rd = this_rd;
- best_angle_dir = i;
- }
- }
-
- best_angle += best_angle_dir * delta;
- if (best_angle < 0)
- best_angle = 0;
- if (best_angle >= EXT_INTRA_ANGLES)
- best_angle = EXT_INTRA_ANGLES - 1;
- if (*best_rd < best_angle_rd / RD_ADJUSTER)
- break;
- }
- } else {
- for (angle = 0; angle < EXT_INTRA_ANGLES; ++angle) {
- mbmi->ext_intra_mode_info.ext_intra_angle[0] = angle;
- if (prediction_angle_map(angle) == 90 ||
- prediction_angle_map(angle) == 180)
- continue;
- super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
- &s, NULL, bsize, *best_rd);
- if (this_rate_tokenonly == INT_MAX)
- continue;
-
- this_rate = this_rate_tokenonly +
- vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 1) +
- (DR_ONLY ? 0: vp10_cost_bit(DR_EXT_INTRA_PROB, 1)) +
- write_uniform_cost(EXT_INTRA_ANGLES, angle) + mode_cost;
- this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
-
- if (this_rd < *best_rd) {
- *best_rd = this_rd;
- best_tx_size = mic->mbmi.tx_size;
- ext_intra_mode_info = mbmi->ext_intra_mode_info;
-#if CONFIG_EXT_TX
- best_tx_type = mic->mbmi.tx_type;
-#endif // CONFIG_EXT_TX
- *rate = this_rate;
- *rate_tokenonly = this_rate_tokenonly;
- *distortion = this_distortion;
- *skippable = s;
- ext_intra_selected_flag = 1;
- }
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ ext_intra_selected_flag = 1;
}
}
@@ -1649,8 +1553,6 @@
ext_intra_mode_info.use_ext_intra_mode[0];
mbmi->ext_intra_mode_info.ext_intra_mode[0] =
ext_intra_mode_info.ext_intra_mode[0];
- mbmi->ext_intra_mode_info.ext_intra_angle[0] =
- ext_intra_mode_info.ext_intra_angle[0];
#if CONFIG_EXT_TX
mbmi->tx_type = best_tx_type;
#endif // CONFIG_EXT_TX
@@ -1659,6 +1561,132 @@
return 0;
}
}
+
+static int64_t rd_pick_intra_angle_sby(VP10_COMP *cpi, MACROBLOCK *x,
+ int *rate, int *rate_tokenonly,
+ int64_t *distortion, int *skippable,
+ BLOCK_SIZE bsize, int rate_overhead,
+ int64_t best_rd) {
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MODE_INFO *const mic = xd->mi[0];
+ MB_MODE_INFO *mbmi = &mic->mbmi;
+ int this_rate, this_rate_tokenonly, s;
+ int angle_delta, best_angle_delta = 0;
+ const double rd_adjust = 1.2;
+ int64_t this_distortion, this_rd, sse_dummy;
+ TX_SIZE best_tx_size = mic->mbmi.tx_size;
+#if CONFIG_EXT_TX
+ TX_TYPE best_tx_type = mbmi->tx_type;
+#endif // CONFIG_EXT_TX
+
+ if (ANGLE_FAST_SEARCH) {
+ int deltas_level1[3] = {0, -2, 2};
+ int deltas_level2[3][2] = {
+ {-1, 1}, {-3, -1}, {1, 3},
+ };
+ const int level1 = 3, level2 = 2;
+ int i, j, best_i = -1;
+
+ for (i = 0; i < level1; ++i) {
+ mic->mbmi.angle_delta[0] = deltas_level1[i];
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize,
+ (i == 0 && best_rd < INT64_MAX) ? best_rd * rd_adjust :
+ best_rd);
+ if (this_rate_tokenonly == INT_MAX) {
+ if (i == 0)
+ break;
+ else
+ continue;
+ }
+ this_rate = this_rate_tokenonly + rate_overhead;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
+ break;
+ 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_EXT_TX
+ best_tx_type = mbmi->tx_type;
+#endif // CONFIG_EXT_TX
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+
+ if (best_i >= 0) {
+ for (j = 0; j < level2; ++j) {
+ mic->mbmi.angle_delta[0] = deltas_level2[best_i][j];
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, best_rd);
+ if (this_rate_tokenonly == INT_MAX)
+ continue;
+ this_rate = this_rate_tokenonly + rate_overhead;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ if (this_rd < best_rd) {
+ best_rd = this_rd;
+ best_angle_delta = mbmi->angle_delta[0];
+ best_tx_size = mbmi->tx_size;
+#if CONFIG_EXT_TX
+ best_tx_type = mbmi->tx_type;
+#endif // CONFIG_EXT_TX
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+ }
+ } else {
+ for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
+ ++angle_delta) {
+ mic->mbmi.angle_delta[0] = angle_delta;
+
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, best_rd);
+ if (this_rate_tokenonly == INT_MAX)
+ continue;
+
+ this_rate = this_rate_tokenonly + rate_overhead;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+
+ if (this_rd < best_rd) {
+ best_rd = this_rd;
+ best_angle_delta = mbmi->angle_delta[0];
+ best_tx_size = mbmi->tx_size;
+#if CONFIG_EXT_TX
+ best_tx_type = mbmi->tx_type;
+#endif // CONFIG_EXT_TX
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+ }
+
+ mbmi->tx_size = best_tx_size;
+ mbmi->angle_delta[0] = best_angle_delta;
+#if CONFIG_EXT_TX
+ mbmi->tx_type = best_tx_type;
+#endif // CONFIG_EXT_TX
+
+ if (*rate_tokenonly < INT_MAX) {
+ txfm_rd_in_plane(x,
+#if CONFIG_VAR_TX
+ cpi,
+#endif
+ &this_rate_tokenonly, &this_distortion, &s,
+ &sse_dummy, INT64_MAX, 0, bsize, mbmi->tx_size,
+ cpi->sf.use_fast_coef_costing);
+ }
+
+ return best_rd;
+}
#endif // CONFIG_EXT_INTRA
// This function is used only for intra_only frames
@@ -1676,6 +1704,7 @@
TX_SIZE best_tx = TX_4X4;
#if CONFIG_EXT_INTRA
EXT_INTRA_MODE_INFO ext_intra_mode_info;
+ int is_directional_mode, rate_overhead, best_angle_delta = 0;
#endif // CONFIG_EXT_INTRA
#if CONFIG_EXT_TX
TX_TYPE best_tx_type = DCT_DCT;
@@ -1696,6 +1725,7 @@
#if CONFIG_EXT_INTRA
ext_intra_mode_info.use_ext_intra_mode[0] = 0;
mic->mbmi.ext_intra_mode_info.use_ext_intra_mode[0] = 0;
+ mic->mbmi.angle_delta[0] = 0;
#endif // CONFIG_EXT_INTRA
memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
palette_mode_info.palette_size[0] = 0;
@@ -1708,9 +1738,24 @@
/* Y Search for intra prediction mode */
for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
mic->mbmi.mode = mode;
-
+#if CONFIG_EXT_INTRA
+ is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
+ if (is_directional_mode) {
+ rate_overhead = bmode_costs[mode] +
+ write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
+ this_rate_tokenonly = INT_MAX;
+ this_rd =
+ rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rate_tokenonly,
+ &this_distortion, &s, bsize, rate_overhead,
+ best_rd);
+ } else {
+ mic->mbmi.angle_delta[0] = 0;
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
+ &s, NULL, bsize, best_rd);
+ }
+#endif // CONFIG_EXT_INTRA
super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
- &s, NULL, bsize, best_rd);
+ &s, NULL, bsize, best_rd);
if (this_rate_tokenonly == INT_MAX)
continue;
@@ -1721,8 +1766,12 @@
vp10_cost_bit(vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
[palette_ctx], 0);
#if CONFIG_EXT_INTRA
- if (mode == DC_PRED)
+ if (mode == DC_PRED && ALLOW_FILTER_INTRA_MODES)
this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[0], 0);
+ if (is_directional_mode)
+ 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);
@@ -1730,6 +1779,9 @@
mode_selected = mode;
best_rd = this_rd;
best_tx = mic->mbmi.tx_size;
+#if CONFIG_EXT_INTRA
+ best_angle_delta = mic->mbmi.angle_delta[0];
+#endif // CONFIG_EXT_INTRA
#if CONFIG_EXT_TX
best_tx_type = mic->mbmi.tx_type;
#endif // CONFIG_EXT_TX
@@ -1746,7 +1798,7 @@
&best_tx, &mode_selected, &best_rd);
#if CONFIG_EXT_INTRA
- if (!palette_mode_info.palette_size[0] > 0) {
+ if (!palette_mode_info.palette_size[0] > 0 && ALLOW_FILTER_INTRA_MODES) {
if (rd_pick_ext_intra_sby(cpi, x, rate, rate_tokenonly, distortion,
skippable, bsize, bmode_costs[DC_PRED],
&best_rd)) {
@@ -1764,13 +1816,14 @@
if (ext_intra_mode_info.use_ext_intra_mode[0]) {
mic->mbmi.ext_intra_mode_info.ext_intra_mode[0] =
ext_intra_mode_info.ext_intra_mode[0];
- mic->mbmi.ext_intra_mode_info.ext_intra_angle[0] =
- ext_intra_mode_info.ext_intra_angle[0];
}
#endif // CONFIG_EXT_INTRA
mic->mbmi.mode = mode_selected;
mic->mbmi.tx_size = best_tx;
+#if CONFIG_EXT_INTRA
+ mic->mbmi.angle_delta[0] = best_angle_delta;
+#endif // CONFIG_EXT_INTRA
#if CONFIG_EXT_TX
mic->mbmi.tx_type = best_tx_type;
#endif // CONFIG_EXT_TX
@@ -2468,127 +2521,38 @@
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
int ext_intra_selected_flag = 0;
int this_rate_tokenonly, this_rate, s;
- int64_t this_distortion, this_sse, this_rd, best_angle_rd = INT64_MAX;
+ int64_t this_distortion, this_sse, this_rd;
EXT_INTRA_MODE mode;
- int i, step, delta, angle, best_angle, best_angle_dir;
- int deltas[3] = {25, 5, 1};
- int branches[3] = {2, 2, 2};
EXT_INTRA_MODE_INFO ext_intra_mode_info;
vp10_zero(ext_intra_mode_info);
mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 1;
mbmi->uv_mode = DC_PRED;
- if (!DR_ONLY) {
- for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
- mbmi->ext_intra_mode_info.ext_intra_mode[1] = mode;
- if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
- &this_distortion, &s, &this_sse, bsize, *best_rd))
- continue;
+ for (mode = 0; mode < FILTER_INTRA_MODES; ++mode) {
+ mbmi->ext_intra_mode_info.ext_intra_mode[1] = mode;
+ if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
+ &this_distortion, &s, &this_sse, bsize, *best_rd))
+ continue;
- this_rate = this_rate_tokenonly +
- vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 1) +
- vp10_cost_bit(DR_EXT_INTRA_PROB, 0) +
- cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
- write_uniform_cost(FILTER_INTRA_MODES, mode);
- this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
- if (this_rd < *best_rd) {
- *best_rd = this_rd;
- *rate = this_rate;
- *rate_tokenonly = this_rate_tokenonly;
- *distortion = this_distortion;
- *skippable = s;
- ext_intra_mode_info = mbmi->ext_intra_mode_info;
- ext_intra_selected_flag = 1;
- if (!x->select_tx_size)
- swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
- }
+ this_rate = this_rate_tokenonly +
+ vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 1) +
+ cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
+ write_uniform_cost(FILTER_INTRA_MODES, mode);
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ if (this_rd < *best_rd) {
+ *best_rd = this_rd;
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ ext_intra_mode_info = mbmi->ext_intra_mode_info;
+ ext_intra_selected_flag = 1;
+ if (!x->select_tx_size)
+ swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
}
}
- mbmi->ext_intra_mode_info.ext_intra_mode[1] = EXT_DR_PRED;
- if (ANGLE_FAST_SEARCH) {
- best_angle = EXT_INTRA_ANGLES / 2;
- for (step = 0; step < 3; ++step) {
- delta = deltas[step];
- for (i = -branches[step]; i <= branches[step]; ++i) {
- int64_t rd_thresh;
- if (i == 0 && step != 0)
- continue;
- angle = best_angle + i * delta;
- if (angle < 0)
- angle = 0;
- if (angle >= EXT_INTRA_ANGLES)
- angle = EXT_INTRA_ANGLES - 1;
- if (angle == best_angle && step != 0)
- continue;
- mbmi->ext_intra_mode_info.ext_intra_angle[1] = angle;
- if (*best_rd == INT64_MAX)
- rd_thresh = best_angle_rd;
- else
- rd_thresh = VPXMIN(best_angle_rd, *best_rd * RD_ADJUSTER);
- if (!super_block_uvrd(cpi, x, &this_rate_tokenonly, &this_distortion,
- &s, &this_sse, bsize, rd_thresh))
- continue;
- this_rate = this_rate_tokenonly +
- vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 1) +
- (DR_ONLY ? 0: vp10_cost_bit(DR_EXT_INTRA_PROB, 1)) +
- cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
- write_uniform_cost(EXT_INTRA_ANGLES, angle);
- this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
- if (this_rd < *best_rd) {
- *best_rd = this_rd;
- *rate = this_rate;
- *rate_tokenonly = this_rate_tokenonly;
- *distortion = this_distortion;
- *skippable = s;
- ext_intra_mode_info = mbmi->ext_intra_mode_info;
- ext_intra_selected_flag = 1;
- if (!x->select_tx_size)
- swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
- }
- if (this_rd < best_angle_rd) {
- best_angle_rd = this_rd;
- best_angle_dir = i;
- }
- }
- best_angle += best_angle_dir * delta;
- if (best_angle < 0)
- best_angle = 0;
- if (best_angle >= EXT_INTRA_ANGLES)
- best_angle = EXT_INTRA_ANGLES - 1;
- if (*best_rd < best_angle_rd / RD_ADJUSTER)
- break;
- }
- } else {
- for (angle = 0; angle < EXT_INTRA_ANGLES; ++angle) {
- mbmi->ext_intra_mode_info.ext_intra_angle[1] = angle;
- if (prediction_angle_map(angle) == 90 ||
- prediction_angle_map(angle) == 180)
- continue;
- if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
- &this_distortion, &s, &this_sse, bsize, *best_rd))
- continue;
-
- this_rate = this_rate_tokenonly +
- vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 1) +
- (DR_ONLY ? 0: vp10_cost_bit(DR_EXT_INTRA_PROB, 1)) +
- cpi->intra_uv_mode_cost[mbmi->mode][mbmi->uv_mode] +
- write_uniform_cost(EXT_INTRA_ANGLES, angle);
- this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
- if (this_rd < *best_rd) {
- *best_rd = this_rd;
- *rate = this_rate;
- *rate_tokenonly = this_rate_tokenonly;
- *distortion = this_distortion;
- *skippable = s;
- ext_intra_mode_info = mbmi->ext_intra_mode_info;
- ext_intra_selected_flag = 1;
- if (!x->select_tx_size)
- swap_block_ptr(x, ctx, 2, 0, 1, MAX_MB_PLANE);
- }
- }
- }
if (ext_intra_selected_flag) {
mbmi->uv_mode = DC_PRED;
@@ -2596,14 +2560,105 @@
ext_intra_mode_info.use_ext_intra_mode[1];
mbmi->ext_intra_mode_info.ext_intra_mode[1] =
ext_intra_mode_info.ext_intra_mode[1];
- mbmi->ext_intra_mode_info.ext_intra_angle[1] =
- ext_intra_mode_info.ext_intra_angle[1];
-
return 1;
} else {
return 0;
}
}
+
+static int rd_pick_intra_angle_sbuv(VP10_COMP *cpi, MACROBLOCK *x,
+ PICK_MODE_CONTEXT *ctx,
+ int *rate, int *rate_tokenonly,
+ int64_t *distortion, int *skippable,
+ BLOCK_SIZE bsize, int rate_overhead,
+ int64_t best_rd) {
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
+ int this_rate_tokenonly, this_rate, s;
+ int64_t this_distortion, this_sse, this_rd;
+ int angle_delta, best_angle_delta = 0;
+ const double rd_adjust = 1.2;
+
+ (void)ctx;
+ *rate_tokenonly = INT_MAX;
+ if (ANGLE_FAST_SEARCH) {
+ int deltas_level1[3] = {0, -2, 2};
+ int deltas_level2[3][2] = {
+ {-1, 1}, {-3, -1}, {1, 3},
+ };
+ const int level1 = 3, level2 = 2;
+ int i, j, best_i = -1;
+
+ for (i = 0; i < level1; ++i) {
+ mbmi->angle_delta[1] = deltas_level1[i];
+ if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
+ &this_distortion, &s, &this_sse, bsize,
+ (i == 0 && best_rd < INT64_MAX) ?
+ best_rd * rd_adjust : best_rd)) {
+ if (i == 0)
+ break;
+ else
+ continue;
+ }
+ this_rate = this_rate_tokenonly + rate_overhead;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ if (i == 0 && best_rd < INT64_MAX && this_rd > best_rd * rd_adjust)
+ break;
+ if (this_rd < best_rd) {
+ best_i = i;
+ best_rd = this_rd;
+ best_angle_delta = mbmi->angle_delta[1];
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+
+ if (best_i >= 0) {
+ for (j = 0; j < level2; ++j) {
+ mbmi->angle_delta[1] = deltas_level2[best_i][j];
+ if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
+ &this_distortion, &s, &this_sse, bsize, best_rd))
+ continue;
+ this_rate = this_rate_tokenonly + rate_overhead;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ if (this_rd < best_rd) {
+ best_rd = this_rd;
+ best_angle_delta = mbmi->angle_delta[1];
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+ }
+ } else {
+ for (angle_delta = -MAX_ANGLE_DELTAS; angle_delta <= MAX_ANGLE_DELTAS;
+ ++angle_delta) {
+ mbmi->angle_delta[1] = angle_delta;
+ if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
+ &this_distortion, &s, &this_sse, bsize, best_rd))
+ continue;
+ this_rate = this_rate_tokenonly + rate_overhead;
+ this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
+ if (this_rd < best_rd) {
+ best_rd = this_rd;
+ best_angle_delta = mbmi->angle_delta[1];
+ *rate = this_rate;
+ *rate_tokenonly = this_rate_tokenonly;
+ *distortion = this_distortion;
+ *skippable = s;
+ }
+ }
+ }
+
+ mbmi->angle_delta[1] = best_angle_delta;
+ if (*rate_tokenonly != INT_MAX)
+ super_block_uvrd(cpi, x, &this_rate_tokenonly,
+ &this_distortion, &s, &this_sse, bsize, INT_MAX);
+ return *rate_tokenonly != INT_MAX;
+}
#endif // CONFIG_EXT_INTRA
static int64_t rd_pick_intra_sbuv_mode(VP10_COMP *cpi, MACROBLOCK *x,
@@ -2619,6 +2674,7 @@
int this_rate_tokenonly, this_rate, s;
int64_t this_distortion, this_sse;
#if CONFIG_EXT_INTRA
+ int is_directional_mode, rate_overhead, best_angle_delta = 0;
EXT_INTRA_MODE_INFO ext_intra_mode_info;
ext_intra_mode_info.use_ext_intra_mode[1] = 0;
@@ -2631,20 +2687,44 @@
continue;
mbmi->uv_mode = mode;
-
+#if CONFIG_EXT_INTRA
+ is_directional_mode = (mode != DC_PRED && mode != TM_PRED);
+ rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
+ write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0);
+ mbmi->angle_delta[1] = 0;
+ if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode) {
+ if (!rd_pick_intra_angle_sbuv(cpi, x, ctx, &this_rate,
+ &this_rate_tokenonly, &this_distortion, &s,
+ bsize, rate_overhead, best_rd))
+ continue;
+ } else {
+ if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
+ &this_distortion, &s, &this_sse, bsize, best_rd))
+ continue;
+ }
+ this_rate = this_rate_tokenonly +
+ cpi->intra_uv_mode_cost[mbmi->mode][mode];
+ if (mbmi->sb_type >= BLOCK_8X8 && is_directional_mode)
+ this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
+ MAX_ANGLE_DELTAS +
+ mbmi->angle_delta[1]);
+ if (mode == DC_PRED && 0)
+ this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 0);
+#else
if (!super_block_uvrd(cpi, x, &this_rate_tokenonly,
&this_distortion, &s, &this_sse, bsize, best_rd))
continue;
this_rate = this_rate_tokenonly +
cpi->intra_uv_mode_cost[xd->mi[0]->mbmi.mode][mode];
-#if CONFIG_EXT_INTRA
- if (mode == DC_PRED)
- this_rate += vp10_cost_bit(cpi->common.fc->ext_intra_probs[1], 0);
#endif // CONFIG_EXT_INTRA
+
this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
if (this_rd < best_rd) {
mode_selected = mode;
+#if CONFIG_EXT_INTRA
+ best_angle_delta = mbmi->angle_delta[1];
+#endif // CONFIG_EXT_INTRA
best_rd = this_rd;
*rate = this_rate;
*rate_tokenonly = this_rate_tokenonly;
@@ -2656,7 +2736,7 @@
}
#if CONFIG_EXT_INTRA
- if (mbmi->sb_type >= BLOCK_8X8) {
+ if (mbmi->sb_type >= BLOCK_8X8 && ALLOW_FILTER_INTRA_MODES) {
if (rd_pick_ext_intra_sbuv(cpi, x, ctx, rate, rate_tokenonly, distortion,
skippable, bsize, &best_rd)) {
mode_selected = mbmi->uv_mode;
@@ -2669,6 +2749,7 @@
if (ext_intra_mode_info.use_ext_intra_mode[1])
mbmi->ext_intra_mode_info.ext_intra_mode[1] =
ext_intra_mode_info.ext_intra_mode[1];
+ mbmi->angle_delta[1] = best_angle_delta;
#endif // CONFIG_EXT_INTRA
mbmi->uv_mode = mode_selected;
return best_rd;
@@ -4478,6 +4559,9 @@
PREDICTION_MODE mode_uv[TX_SIZES];
#if CONFIG_EXT_INTRA
EXT_INTRA_MODE_INFO ext_intra_mode_info_uv[TX_SIZES];
+ int8_t uv_angle_delta[TX_SIZES];
+ int is_directional_mode;
+ int rate_overhead, rate_dummy;
#endif // CONFIG_EXT_INTRA
const int intra_cost_penalty = vp10_get_intra_cost_penalty(
cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
@@ -4762,17 +4846,31 @@
TX_SIZE uv_tx;
struct macroblockd_plane *const pd = &xd->plane[1];
memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
- super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
- NULL, bsize, best_rd);
+
#if CONFIG_EXT_INTRA
+ is_directional_mode = (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED);
+ if (is_directional_mode) {
+ rate_overhead = write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1, 0) +
+ cpi->mbmode_cost[mbmi->mode];
+ rate_y = INT_MAX;
+ this_rd =
+ rd_pick_intra_angle_sby(cpi, x, &rate_dummy, &rate_y, &distortion_y,
+ &skippable, bsize, rate_overhead, best_rd);
+ } else {
+ mbmi->angle_delta[0] = 0;
+ super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
+ NULL, bsize, best_rd);
+ }
+
// TODO(huisu): ext-intra is turned off in lossless mode for now to
// avoid a unit test failure
- if (mbmi->mode == DC_PRED && !xd->lossless[mbmi->segment_id]) {
+ if (mbmi->mode == DC_PRED && !xd->lossless[mbmi->segment_id] &&
+ ALLOW_FILTER_INTRA_MODES) {
MB_MODE_INFO mbmi_copy = *mbmi;
- int rate_dummy;
if (rate_y != INT_MAX) {
- int this_rate = rate_y + cpi->mbmode_cost[mbmi->mode] +
+ int this_rate = rate_y +
+ cpi->mbmode_cost[mbmi->mode] +
vp10_cost_bit(cm->fc->ext_intra_probs[0], 0);
this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, distortion_y);
} else {
@@ -4784,7 +4882,11 @@
cpi->mbmode_cost[mbmi->mode], &this_rd))
*mbmi = mbmi_copy;
}
+#else
+ super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
+ NULL, bsize, best_rd);
#endif // CONFIG_EXT_INTRA
+
if (rate_y == INT_MAX)
continue;
uv_tx = get_uv_tx_size_impl(mbmi->tx_size, bsize, pd->subsampling_x,
@@ -4795,6 +4897,7 @@
&dist_uv[uv_tx], &skip_uv[uv_tx], &mode_uv[uv_tx]);
#if CONFIG_EXT_INTRA
ext_intra_mode_info_uv[uv_tx] = mbmi->ext_intra_mode_info;
+ uv_angle_delta[uv_tx] = mbmi->angle_delta[1];
#endif // CONFIG_EXT_INTRA
}
@@ -4803,32 +4906,29 @@
skippable = skippable && skip_uv[uv_tx];
mbmi->uv_mode = mode_uv[uv_tx];
#if CONFIG_EXT_INTRA
+ mbmi->angle_delta[1] = uv_angle_delta[uv_tx];
mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1];
if (ext_intra_mode_info_uv[uv_tx].use_ext_intra_mode[1]) {
mbmi->ext_intra_mode_info.ext_intra_mode[1] =
ext_intra_mode_info_uv[uv_tx].ext_intra_mode[1];
- mbmi->ext_intra_mode_info.ext_intra_angle[1] =
- ext_intra_mode_info_uv[uv_tx].ext_intra_angle[1];
}
#endif // CONFIG_EXT_INTRA
rate2 = rate_y + cpi->mbmode_cost[mbmi->mode] + rate_uv_intra[uv_tx];
#if CONFIG_EXT_INTRA
- if (mbmi->mode == DC_PRED) {
+ if (is_directional_mode)
+ rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTAS + 1,
+ MAX_ANGLE_DELTAS +
+ mbmi->angle_delta[0]);
+
+ if (mbmi->mode == DC_PRED && ALLOW_FILTER_INTRA_MODES) {
rate2 += vp10_cost_bit(cm->fc->ext_intra_probs[0],
mbmi->ext_intra_mode_info.use_ext_intra_mode[0]);
if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
EXT_INTRA_MODE ext_intra_mode =
mbmi->ext_intra_mode_info.ext_intra_mode[0];
- int angle = mbmi->ext_intra_mode_info.ext_intra_angle[0];
- if (!DR_ONLY)
- rate2 += vp10_cost_bit(DR_EXT_INTRA_PROB,
- ext_intra_mode > FILTER_TM_PRED);
- if (ext_intra_mode > FILTER_TM_PRED)
- rate2 += write_uniform_cost(EXT_INTRA_ANGLES, angle);
- else
- rate2 += write_uniform_cost(FILTER_INTRA_MODES, ext_intra_mode);
+ rate2 += write_uniform_cost(FILTER_INTRA_MODES, ext_intra_mode);
}
}
#endif // CONFIG_EXT_INTRA