Commit 3ca43bf0 authored by Joe Young's avatar Joe Young

Ext-intra modification/tuning

For ext-intra direcation intra modes:

1. Use neighbor block modes to modify edge filtering strength
   Coding gain (lowres/midres/hdres):
     (8 keyframes)
     PSNR: -0.19 -0.22 -0.10
     SSIM: -0.29 -0.27 -0.13

2. Use context-based cdf to code angle_delta syntax
     (8 keyframes)
     PSNR: -0.20 -0.24 -0.27
     SSIM: -0.29 -0.33 -0.37

3. Filter corner sample:
     (8 keyframes)
     PSNR: -0.01 -0.02 -0.05
     SSIM: -0.03 -0.04 -0.05

Combined Bd-rate improvement for 8 keyframes
     PSNR: -0.40 -0.47 -0.40
     SSIM: -0.57 -0.60 -0.51

Change-Id: Id47ac17b6bf91cd810b70cacfc5b457341f417f3
parent 88f0dd64
...@@ -1146,8 +1146,6 @@ static INLINE TX_SIZE tx_size_from_tx_mode(BLOCK_SIZE bsize, TX_MODE tx_mode, ...@@ -1146,8 +1146,6 @@ static INLINE TX_SIZE tx_size_from_tx_mode(BLOCK_SIZE bsize, TX_MODE tx_mode,
} }
#if CONFIG_EXT_INTRA #if CONFIG_EXT_INTRA
#define MAX_ANGLE_DELTA 3
#define ANGLE_STEP 3
extern const int16_t dr_intra_derivative[90]; extern const int16_t dr_intra_derivative[90];
static const uint8_t mode_to_angle_map[] = { static const uint8_t mode_to_angle_map[] = {
0, 90, 180, 45, 135, 111, 157, 203, 67, 0, 0, 0, 90, 180, 45, 135, 111, 157, 203, 67, 0, 0,
......
...@@ -6160,6 +6160,28 @@ static const aom_cdf_prob ...@@ -6160,6 +6160,28 @@ static const aom_cdf_prob
}; };
#endif // CONFIG_LPF_SB #endif // CONFIG_LPF_SB
#if CONFIG_EXT_INTRA_MOD
const aom_cdf_prob default_angle_delta_cdf[DIRECTIONAL_MODES][CDF_SIZE(
2 * MAX_ANGLE_DELTA + 1)] = {
{ AOM_ICDF(2340), AOM_ICDF(5327), AOM_ICDF(7611), AOM_ICDF(23102),
AOM_ICDF(27196), AOM_ICDF(30546), AOM_ICDF(32768), 0 },
{ AOM_ICDF(3267), AOM_ICDF(8071), AOM_ICDF(11970), AOM_ICDF(21822),
AOM_ICDF(25619), AOM_ICDF(30034), AOM_ICDF(32768), 0 },
{ AOM_ICDF(3417), AOM_ICDF(9937), AOM_ICDF(12286), AOM_ICDF(16420),
AOM_ICDF(19941), AOM_ICDF(30669), AOM_ICDF(32768), 0 },
{ AOM_ICDF(5167), AOM_ICDF(11735), AOM_ICDF(15254), AOM_ICDF(16662),
AOM_ICDF(20697), AOM_ICDF(28276), AOM_ICDF(32768), 0 },
{ AOM_ICDF(1728), AOM_ICDF(10973), AOM_ICDF(14103), AOM_ICDF(18547),
AOM_ICDF(22684), AOM_ICDF(27007), AOM_ICDF(32768), 0 },
{ AOM_ICDF(2764), AOM_ICDF(10700), AOM_ICDF(12517), AOM_ICDF(16957),
AOM_ICDF(20590), AOM_ICDF(30390), AOM_ICDF(32768), 0 },
{ AOM_ICDF(2407), AOM_ICDF(12749), AOM_ICDF(16527), AOM_ICDF(20823),
AOM_ICDF(22781), AOM_ICDF(29642), AOM_ICDF(32768), 0 },
{ AOM_ICDF(3068), AOM_ICDF(10132), AOM_ICDF(12079), AOM_ICDF(16542),
AOM_ICDF(19943), AOM_ICDF(30448), AOM_ICDF(32768), 0 }
};
#endif // CONFIG_EXT_INTRA_MOD
static void init_mode_probs(FRAME_CONTEXT *fc) { static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->partition_prob, default_partition_probs); av1_copy(fc->partition_prob, default_partition_probs);
av1_copy(fc->intra_inter_prob, default_intra_inter_p); av1_copy(fc->intra_inter_prob, default_intra_inter_p);
...@@ -6169,6 +6191,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) { ...@@ -6169,6 +6191,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
av1_copy(fc->palette_y_color_index_cdf, default_palette_y_color_index_cdf); av1_copy(fc->palette_y_color_index_cdf, default_palette_y_color_index_cdf);
av1_copy(fc->palette_uv_color_index_cdf, default_palette_uv_color_index_cdf); av1_copy(fc->palette_uv_color_index_cdf, default_palette_uv_color_index_cdf);
av1_copy(fc->kf_y_cdf, default_kf_y_mode_cdf); av1_copy(fc->kf_y_cdf, default_kf_y_mode_cdf);
#if CONFIG_EXT_INTRA_MOD
av1_copy(fc->angle_delta_cdf, default_angle_delta_cdf);
#endif // CONFIG_EXT_INTRA_MOD
#if CONFIG_MRC_TX #if CONFIG_MRC_TX
av1_copy(fc->mrc_mask_inter_cdf, default_mrc_mask_inter_cdf); av1_copy(fc->mrc_mask_inter_cdf, default_mrc_mask_inter_cdf);
av1_copy(fc->mrc_mask_intra_cdf, default_mrc_mask_intra_cdf); av1_copy(fc->mrc_mask_intra_cdf, default_mrc_mask_intra_cdf);
......
...@@ -338,6 +338,12 @@ typedef struct frame_contexts { ...@@ -338,6 +338,12 @@ typedef struct frame_contexts {
#else #else
aom_cdf_prob kf_y_cdf[INTRA_MODES][INTRA_MODES][CDF_SIZE(INTRA_MODES)]; aom_cdf_prob kf_y_cdf[INTRA_MODES][INTRA_MODES][CDF_SIZE(INTRA_MODES)];
#endif #endif
#if CONFIG_EXT_INTRA_MOD
aom_cdf_prob angle_delta_cdf[DIRECTIONAL_MODES]
[CDF_SIZE(2 * MAX_ANGLE_DELTA + 1)];
#endif // CONFIG_EXT_INTRA_MOD
aom_cdf_prob tx_size_cdf[MAX_TX_DEPTH][TX_SIZE_CONTEXTS] aom_cdf_prob tx_size_cdf[MAX_TX_DEPTH][TX_SIZE_CONTEXTS]
[CDF_SIZE(MAX_TX_DEPTH + 1)]; [CDF_SIZE(MAX_TX_DEPTH + 1)];
aom_cdf_prob delta_q_cdf[CDF_SIZE(DELTA_Q_PROBS + 1)]; aom_cdf_prob delta_q_cdf[CDF_SIZE(DELTA_Q_PROBS + 1)];
...@@ -383,6 +389,7 @@ typedef struct FRAME_COUNTS { ...@@ -383,6 +389,7 @@ typedef struct FRAME_COUNTS {
// aggregates built solely from 'unsigned int' fields/elements // aggregates built solely from 'unsigned int' fields/elements
#if CONFIG_ENTROPY_STATS #if CONFIG_ENTROPY_STATS
unsigned int kf_y_mode[INTRA_MODES][INTRA_MODES][INTRA_MODES]; unsigned int kf_y_mode[INTRA_MODES][INTRA_MODES][INTRA_MODES];
unsigned int angle_delta[DIRECTIONAL_MODES][2 * MAX_ANGLE_DELTA + 1];
unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES]; unsigned int y_mode[BLOCK_SIZE_GROUPS][INTRA_MODES];
unsigned int uv_mode[INTRA_MODES][UV_INTRA_MODES]; unsigned int uv_mode[INTRA_MODES][UV_INTRA_MODES];
#endif // CONFIG_ENTROPY_STATS #endif // CONFIG_ENTROPY_STATS
......
...@@ -628,6 +628,8 @@ typedef enum ATTRIBUTE_PACKED { ...@@ -628,6 +628,8 @@ typedef enum ATTRIBUTE_PACKED {
#if CONFIG_EXT_INTRA #if CONFIG_EXT_INTRA
#define DIRECTIONAL_MODES 8 #define DIRECTIONAL_MODES 8
#define MAX_ANGLE_DELTA 3
#define ANGLE_STEP 3
#endif // CONFIG_EXT_INTRA #endif // CONFIG_EXT_INTRA
#define INTER_MODES (1 + NEWMV - NEARESTMV) #define INTER_MODES (1 + NEWMV - NEARESTMV)
......
...@@ -40,7 +40,7 @@ enum { ...@@ -40,7 +40,7 @@ enum {
#define INTRA_EDGE_FILT 3 #define INTRA_EDGE_FILT 3
#define INTRA_EDGE_TAPS 5 #define INTRA_EDGE_TAPS 5
#if CONFIG_INTRA_EDGE_UPSAMPLE #if CONFIG_INTRA_EDGE_UPSAMPLE
#define MAX_UPSAMPLE_SZ 12 #define MAX_UPSAMPLE_SZ 16
#endif // CONFIG_INTRA_EDGE_UPSAMPLE #endif // CONFIG_INTRA_EDGE_UPSAMPLE
#endif // CONFIG_INTRA_EDGE #endif // CONFIG_INTRA_EDGE
...@@ -1748,11 +1748,62 @@ static void highbd_filter_intra_predictors(FILTER_INTRA_MODE mode, ...@@ -1748,11 +1748,62 @@ static void highbd_filter_intra_predictors(FILTER_INTRA_MODE mode,
#endif // CONFIG_FILTER_INTRA #endif // CONFIG_FILTER_INTRA
#if CONFIG_INTRA_EDGE #if CONFIG_INTRA_EDGE
static int intra_edge_filter_strength(int bsz, int delta) { static int is_smooth(MB_MODE_INFO *mbmi) {
return (mbmi->mode == SMOOTH_PRED || mbmi->mode == SMOOTH_V_PRED ||
mbmi->mode == SMOOTH_H_PRED);
}
static int get_filt_type(const MACROBLOCKD *xd) {
MB_MODE_INFO *ab = xd->up_available ? &xd->mi[-xd->mi_stride]->mbmi : 0;
MB_MODE_INFO *le = xd->left_available ? &xd->mi[-1]->mbmi : 0;
const int ab_sm = ab ? is_smooth(ab) : 0;
const int le_sm = le ? is_smooth(le) : 0;
return (ab_sm || le_sm) ? 1 : 0;
}
static int intra_edge_filter_strength(int bs0, int bs1, int delta, int type) {
const int d = abs(delta); const int d = abs(delta);
int strength = 0; int strength = 0;
switch (bsz) { #if CONFIG_EXT_INTRA_MOD
const int blk_wh = bs0 + bs1;
if (type == 0) {
if (blk_wh <= 8) {
if (d >= 56) strength = 1;
} else if (blk_wh <= 12) {
if (d >= 40) strength = 1;
} else if (blk_wh <= 16) {
if (d >= 40) strength = 1;
} else if (blk_wh <= 24) {
if (d >= 8) strength = 1;
if (d >= 16) strength = 2;
if (d >= 32) strength = 3;
} else if (blk_wh <= 32) {
if (d >= 1) strength = 1;
if (d >= 4) strength = 2;
if (d >= 32) strength = 3;
} else {
if (d >= 1) strength = 3;
}
} else {
if (blk_wh <= 8) {
if (d >= 40) strength = 1;
if (d >= 64) strength = 2;
} else if (blk_wh <= 16) {
if (d >= 20) strength = 1;
if (d >= 48) strength = 2;
} else if (blk_wh <= 24) {
if (d >= 4) strength = 3;
} else {
if (d >= 1) strength = 3;
}
}
#else
(void)type;
(void)bs1;
switch (bs0) {
case 4: case 4:
if (d < 56) { if (d < 56) {
strength = 0; strength = 0;
...@@ -1787,7 +1838,7 @@ static int intra_edge_filter_strength(int bsz, int delta) { ...@@ -1787,7 +1838,7 @@ static int intra_edge_filter_strength(int bsz, int delta) {
break; break;
default: strength = 0; break; default: strength = 0; break;
} }
#endif // CONFIG_EXT_INTRA_MOD
return strength; return strength;
} }
...@@ -1814,6 +1865,18 @@ void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength) { ...@@ -1814,6 +1865,18 @@ void av1_filter_intra_edge_c(uint8_t *p, int sz, int strength) {
} }
} }
#if CONFIG_EXT_INTRA_MOD
void av1_filter_intra_edge_corner(uint8_t *p_above, uint8_t *p_left) {
const int kernel[3] = { 5, 6, 5 };
int s = (p_left[0] * kernel[0]) + (p_above[-1] * kernel[1]) +
(p_above[0] * kernel[2]);
s = (s + 8) >> 4;
p_above[-1] = s;
p_left[-1] = s;
}
#endif // CONFIG_EXT_INTRA_MOD
#if CONFIG_HIGHBITDEPTH #if CONFIG_HIGHBITDEPTH
void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength) { void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength) {
if (!strength) return; if (!strength) return;
...@@ -1837,12 +1900,34 @@ void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength) { ...@@ -1837,12 +1900,34 @@ void av1_filter_intra_edge_high_c(uint16_t *p, int sz, int strength) {
p[i] = s; p[i] = s;
} }
} }
#if CONFIG_EXT_INTRA_MOD
void av1_filter_intra_edge_corner_high(uint16_t *p_above, uint16_t *p_left) {
const int kernel[3] = { 5, 6, 5 };
int s = (p_left[0] * kernel[0]) + (p_above[-1] * kernel[1]) +
(p_above[0] * kernel[2]);
s = (s + 8) >> 4;
p_above[-1] = s;
p_left[-1] = s;
}
#endif // CONFIG_EXT_INTRA_MOD
#endif // CONFIG_HIGHBITDEPTH #endif // CONFIG_HIGHBITDEPTH
#if CONFIG_INTRA_EDGE_UPSAMPLE #if CONFIG_INTRA_EDGE_UPSAMPLE
static int use_intra_edge_upsample(int bsz, int delta) { static int use_intra_edge_upsample(int bs0, int bs1, int delta, int type) {
const int d = abs(delta); const int d = abs(delta);
return (bsz == 4 && d > 0 && d < 56);
#if CONFIG_EXT_INTRA_MOD
const int blk_wh = bs0 + bs1;
if (d <= 0 || d >= 40) return 0;
return type ? (blk_wh <= 8) : (blk_wh <= 16);
#else
(void)type;
(void)bs1;
return (bs0 == 4 && d > 0 && d < 56);
#endif // CONFIG_EXT_INTRA_MOD
} }
void av1_upsample_intra_edge_c(uint8_t *p, int sz) { void av1_upsample_intra_edge_c(uint8_t *p, int sz) {
...@@ -2087,27 +2172,37 @@ static void build_intra_predictors_high( ...@@ -2087,27 +2172,37 @@ static void build_intra_predictors_high(
#if CONFIG_INTRA_EDGE #if CONFIG_INTRA_EDGE
const int need_right = p_angle < 90; const int need_right = p_angle < 90;
const int need_bottom = p_angle > 180; const int need_bottom = p_angle > 180;
const int filt_type = get_filt_type(xd);
if (p_angle != 90 && p_angle != 180) { if (p_angle != 90 && p_angle != 180) {
const int ab_le = need_above_left ? 1 : 0; const int ab_le = need_above_left ? 1 : 0;
#if CONFIG_EXT_INTRA_MOD
if (need_above && need_left && (txwpx + txhpx >= 24)) {
av1_filter_intra_edge_corner_high(above_row, left_col);
}
#endif // CONFIG_EXT_INTRA_MOD
if (need_above && n_top_px > 0) { if (need_above && n_top_px > 0) {
const int strength = intra_edge_filter_strength(txwpx, p_angle - 90); const int strength =
intra_edge_filter_strength(txwpx, txhpx, p_angle - 90, filt_type);
const int n_px = n_top_px + ab_le + (need_right ? n_topright_px : 0); const int n_px = n_top_px + ab_le + (need_right ? n_topright_px : 0);
av1_filter_intra_edge_high(above_row - ab_le, n_px, strength); av1_filter_intra_edge_high(above_row - ab_le, n_px, strength);
} }
if (need_left && n_left_px > 0) { if (need_left && n_left_px > 0) {
const int strength = intra_edge_filter_strength(txhpx, p_angle - 180); const int strength =
intra_edge_filter_strength(txhpx, txwpx, p_angle - 180, filt_type);
const int n_px = const int n_px =
n_left_px + ab_le + (need_bottom ? n_bottomleft_px : 0); n_left_px + ab_le + (need_bottom ? n_bottomleft_px : 0);
av1_filter_intra_edge_high(left_col - ab_le, n_px, strength); av1_filter_intra_edge_high(left_col - ab_le, n_px, strength);
} }
} }
#if CONFIG_INTRA_EDGE_UPSAMPLE #if CONFIG_INTRA_EDGE_UPSAMPLE
const int upsample_above = use_intra_edge_upsample(txwpx, p_angle - 90); const int upsample_above =
use_intra_edge_upsample(txwpx, txhpx, p_angle - 90, filt_type);
if (need_above && upsample_above) { if (need_above && upsample_above) {
const int n_px = txwpx + (need_right ? txhpx : 0); const int n_px = txwpx + (need_right ? txhpx : 0);
av1_upsample_intra_edge_high(above_row, n_px, xd->bd); av1_upsample_intra_edge_high(above_row, n_px, xd->bd);
} }
const int upsample_left = use_intra_edge_upsample(txhpx, p_angle - 180); const int upsample_left =
use_intra_edge_upsample(txhpx, txwpx, p_angle - 180, filt_type);
if (need_left && upsample_left) { if (need_left && upsample_left) {
const int n_px = txhpx + (need_bottom ? txwpx : 0); const int n_px = txhpx + (need_bottom ? txwpx : 0);
av1_upsample_intra_edge_high(left_col, n_px, xd->bd); av1_upsample_intra_edge_high(left_col, n_px, xd->bd);
...@@ -2321,27 +2416,37 @@ static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref, ...@@ -2321,27 +2416,37 @@ static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref,
#if CONFIG_INTRA_EDGE #if CONFIG_INTRA_EDGE
const int need_right = p_angle < 90; const int need_right = p_angle < 90;
const int need_bottom = p_angle > 180; const int need_bottom = p_angle > 180;
const int filt_type = get_filt_type(xd);
if (p_angle != 90 && p_angle != 180) { if (p_angle != 90 && p_angle != 180) {
const int ab_le = need_above_left ? 1 : 0; const int ab_le = need_above_left ? 1 : 0;
#if CONFIG_EXT_INTRA_MOD
if (need_above && need_left && (txwpx + txhpx >= 24)) {
av1_filter_intra_edge_corner(above_row, left_col);
}
#endif // CONFIG_EXT_INTRA_MOD
if (need_above && n_top_px > 0) { if (need_above && n_top_px > 0) {
const int strength = intra_edge_filter_strength(txwpx, p_angle - 90); const int strength =
intra_edge_filter_strength(txwpx, txhpx, p_angle - 90, filt_type);
const int n_px = n_top_px + ab_le + (need_right ? n_topright_px : 0); const int n_px = n_top_px + ab_le + (need_right ? n_topright_px : 0);
av1_filter_intra_edge(above_row - ab_le, n_px, strength); av1_filter_intra_edge(above_row - ab_le, n_px, strength);
} }
if (need_left && n_left_px > 0) { if (need_left && n_left_px > 0) {
const int strength = intra_edge_filter_strength(txhpx, p_angle - 180); const int strength =
intra_edge_filter_strength(txhpx, txwpx, p_angle - 180, filt_type);
const int n_px = const int n_px =
n_left_px + ab_le + (need_bottom ? n_bottomleft_px : 0); n_left_px + ab_le + (need_bottom ? n_bottomleft_px : 0);
av1_filter_intra_edge(left_col - ab_le, n_px, strength); av1_filter_intra_edge(left_col - ab_le, n_px, strength);
} }
} }
#if CONFIG_INTRA_EDGE_UPSAMPLE #if CONFIG_INTRA_EDGE_UPSAMPLE
const int upsample_above = use_intra_edge_upsample(txwpx, p_angle - 90); const int upsample_above =
use_intra_edge_upsample(txwpx, txhpx, p_angle - 90, filt_type);
if (need_above && upsample_above) { if (need_above && upsample_above) {
const int n_px = txwpx + (need_right ? txhpx : 0); const int n_px = txwpx + (need_right ? txhpx : 0);
av1_upsample_intra_edge(above_row, n_px); av1_upsample_intra_edge(above_row, n_px);
} }
const int upsample_left = use_intra_edge_upsample(txhpx, p_angle - 180); const int upsample_left =
use_intra_edge_upsample(txhpx, txwpx, p_angle - 180, filt_type);
if (need_left && upsample_left) { if (need_left && upsample_left) {
const int n_px = txhpx + (need_bottom ? txwpx : 0); const int n_px = txhpx + (need_bottom ? txwpx : 0);
av1_upsample_intra_edge(left_col, n_px); av1_upsample_intra_edge(left_col, n_px);
......
...@@ -883,21 +883,42 @@ static void read_filter_intra_mode_info(AV1_COMMON *const cm, ...@@ -883,21 +883,42 @@ static void read_filter_intra_mode_info(AV1_COMMON *const cm,
#endif // CONFIG_FILTER_INTRA #endif // CONFIG_FILTER_INTRA
#if CONFIG_EXT_INTRA #if CONFIG_EXT_INTRA
#if CONFIG_EXT_INTRA_MOD
static int read_angle_delta(aom_reader *r, aom_cdf_prob *cdf) {
const int sym = aom_read_symbol(r, cdf, 2 * MAX_ANGLE_DELTA + 1, ACCT_STR);
return sym - MAX_ANGLE_DELTA;
}
#endif // CONFIG_EXT_INTRA_MOD
static void read_intra_angle_info(MACROBLOCKD *const xd, aom_reader *r) { static void read_intra_angle_info(MACROBLOCKD *const xd, aom_reader *r) {
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
const BLOCK_SIZE bsize = mbmi->sb_type; const BLOCK_SIZE bsize = mbmi->sb_type;
#if CONFIG_EXT_INTRA_MOD
FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
#endif // CONFIG_EXT_INTRA_MOD
mbmi->angle_delta[0] = 0; mbmi->angle_delta[0] = 0;
mbmi->angle_delta[1] = 0; mbmi->angle_delta[1] = 0;
if (!av1_use_angle_delta(bsize)) return; if (!av1_use_angle_delta(bsize)) return;
if (av1_is_directional_mode(mbmi->mode, bsize)) { if (av1_is_directional_mode(mbmi->mode, bsize)) {
#if CONFIG_EXT_INTRA_MOD
mbmi->angle_delta[0] =
read_angle_delta(r, ec_ctx->angle_delta_cdf[mbmi->mode - V_PRED]);
#else
mbmi->angle_delta[0] = mbmi->angle_delta[0] =
av1_read_uniform(r, 2 * MAX_ANGLE_DELTA + 1) - MAX_ANGLE_DELTA; av1_read_uniform(r, 2 * MAX_ANGLE_DELTA + 1) - MAX_ANGLE_DELTA;
#endif // CONFIG_EXT_INTRA_MOD
} }
if (av1_is_directional_mode(get_uv_mode(mbmi->uv_mode), bsize)) { if (av1_is_directional_mode(get_uv_mode(mbmi->uv_mode), bsize)) {
#if CONFIG_EXT_INTRA_MOD
mbmi->angle_delta[1] =
read_angle_delta(r, ec_ctx->angle_delta_cdf[mbmi->uv_mode - V_PRED]);
#else
mbmi->angle_delta[1] = mbmi->angle_delta[1] =
av1_read_uniform(r, 2 * MAX_ANGLE_DELTA + 1) - MAX_ANGLE_DELTA; av1_read_uniform(r, 2 * MAX_ANGLE_DELTA + 1) - MAX_ANGLE_DELTA;
#endif // CONFIG_EXT_INTRA_MOD
} }
} }
#endif // CONFIG_EXT_INTRA #endif // CONFIG_EXT_INTRA
......
...@@ -1049,19 +1049,33 @@ static void write_filter_intra_mode_info(const AV1_COMMON *const cm, ...@@ -1049,19 +1049,33 @@ static void write_filter_intra_mode_info(const AV1_COMMON *const cm,
#endif // CONFIG_FILTER_INTRA #endif // CONFIG_FILTER_INTRA
#if CONFIG_EXT_INTRA #if CONFIG_EXT_INTRA
static void write_intra_angle_info(const MACROBLOCKD *xd, aom_writer *w) { static void write_intra_angle_info(const MACROBLOCKD *xd,
FRAME_CONTEXT *const ec_ctx, aom_writer *w) {
const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi; const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
const BLOCK_SIZE bsize = mbmi->sb_type; const BLOCK_SIZE bsize = mbmi->sb_type;
if (!av1_use_angle_delta(bsize)) return; if (!av1_use_angle_delta(bsize)) return;
if (av1_is_directional_mode(mbmi->mode, bsize)) { if (av1_is_directional_mode(mbmi->mode, bsize)) {
#if CONFIG_EXT_INTRA_MOD
aom_write_symbol(w, mbmi->angle_delta[0] + MAX_ANGLE_DELTA,
ec_ctx->angle_delta_cdf[mbmi->mode - V_PRED],
2 * MAX_ANGLE_DELTA + 1);
#else
(void)ec_ctx;
write_uniform(w, 2 * MAX_ANGLE_DELTA + 1, write_uniform(w, 2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[0]); MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
#endif // CONFIG_EXT_INTRA_MOD
} }
if (av1_is_directional_mode(get_uv_mode(mbmi->uv_mode), bsize)) { if (av1_is_directional_mode(get_uv_mode(mbmi->uv_mode), bsize)) {
#if CONFIG_EXT_INTRA_MOD
aom_write_symbol(w, mbmi->angle_delta[1] + MAX_ANGLE_DELTA,
ec_ctx->angle_delta_cdf[mbmi->uv_mode - V_PRED],
2 * MAX_ANGLE_DELTA + 1);
#else
write_uniform(w, 2 * MAX_ANGLE_DELTA + 1, write_uniform(w, 2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[1]); MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
#endif
} }
} }
#endif // CONFIG_EXT_INTRA #endif // CONFIG_EXT_INTRA
...@@ -1594,7 +1608,7 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row, ...@@ -1594,7 +1608,7 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row,
} }
#if CONFIG_EXT_INTRA #if CONFIG_EXT_INTRA
write_intra_angle_info(xd, w); write_intra_angle_info(xd, ec_ctx, w);
#endif // CONFIG_EXT_INTRA #endif // CONFIG_EXT_INTRA
if (av1_allow_palette(cm->allow_screen_content_tools, bsize)) if (av1_allow_palette(cm->allow_screen_content_tools, bsize))
write_palette_mode_info(cm, xd, mi, w); write_palette_mode_info(cm, xd, mi, w);
...@@ -1933,7 +1947,7 @@ static void write_mb_modes_kf(AV1_COMMON *cm, MACROBLOCKD *xd, ...@@ -1933,7 +1947,7 @@ static void write_mb_modes_kf(AV1_COMMON *cm, MACROBLOCKD *xd,
} }
#if CONFIG_EXT_INTRA #if CONFIG_EXT_INTRA
write_intra_angle_info(xd, w); write_intra_angle_info(xd, ec_ctx, w);
#endif // CONFIG_EXT_INTRA #endif // CONFIG_EXT_INTRA
if (av1_allow_palette(cm->allow_screen_content_tools, bsize)) if (av1_allow_palette(cm->allow_screen_content_tools, bsize))
write_palette_mode_info(cm, xd, mi, w); write_palette_mode_info(cm, xd, mi, w);
......
...@@ -284,6 +284,9 @@ struct macroblock { ...@@ -284,6 +284,9 @@ struct macroblock {
int intra_tx_type_costs[EXT_TX_SIZES][TX_TYPES][TX_TYPES]; int intra_tx_type_costs[EXT_TX_SIZES][TX_TYPES][TX_TYPES];
int inter_tx_type_costs[EXT_TX_SIZES][TX_TYPES]; int inter_tx_type_costs[EXT_TX_SIZES][TX_TYPES];
#endif // CONFIG_EXT_TX #endif // CONFIG_EXT_TX
#if CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
int angle_delta_cost[DIRECTIONAL_MODES][2 * MAX_ANGLE_DELTA + 1];
#endif // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
#if CONFIG_LOOP_RESTORATION #if CONFIG_LOOP_RESTORATION
int switchable_restore_cost[RESTORE_SWITCHABLE_TYPES]; int switchable_restore_cost[RESTORE_SWITCHABLE_TYPES];
int wiener_restore_cost[2]; int wiener_restore_cost[2];
......
...@@ -4265,10 +4265,32 @@ static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd, ...@@ -4265,10 +4265,32 @@ static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
FILTER_INTRA_MODES); FILTER_INTRA_MODES);
} }
#endif // CONFIG_FILTER_INTRA #endif // CONFIG_FILTER_INTRA
#if CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
if (av1_is_directional_mode(mbmi->mode, bsize) &&
av1_use_angle_delta(bsize)) {
#if CONFIG_ENTROPY_STATS
++counts->angle_delta[mbmi->mode - V_PRED]
[mbmi->angle_delta[0] + MAX_ANGLE_DELTA];
#endif
update_cdf(fc->angle_delta_cdf[mbmi->mode - V_PRED],
mbmi->angle_delta[0] + MAX_ANGLE_DELTA, 2 * MAX_ANGLE_DELTA + 1);
}
#endif // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
if (!is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x, if (!is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
xd->plane[1].subsampling_y)) xd->plane[1].subsampling_y))
return; return;
#if CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
if (av1_is_directional_mode(mbmi->uv_mode, bsize) &&
av1_use_angle_delta(bsize)) {
#if CONFIG_ENTROPY_STATS
++counts->angle_delta[mbmi->uv_mode - V_PRED]
[mbmi->angle_delta[1] + MAX_ANGLE_DELTA];
#endif
update_cdf(fc->angle_delta_cdf[mbmi->uv_mode - V_PRED],
mbmi->angle_delta[1] + MAX_ANGLE_DELTA, 2 * MAX_ANGLE_DELTA + 1);
}
#endif // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
#if CONFIG_ENTROPY_STATS #if CONFIG_ENTROPY_STATS
++counts->uv_mode[y_mode][uv_mode]; ++counts->uv_mode[y_mode][uv_mode];
#endif // CONFIG_ENTROPY_STATS #endif // CONFIG_ENTROPY_STATS
......
...@@ -293,6 +293,12 @@ void av1_fill_mode_rates(AV1_COMMON *const cm, MACROBLOCK *x, ...@@ -293,6 +293,12 @@ void av1_fill_mode_rates(AV1_COMMON *const cm, MACROBLOCK *x,
av1_ext_tx_inv); av1_ext_tx_inv);
} }
#endif // CONFIG_EXT_TX #endif // CONFIG_EXT_TX
#if CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
for (i = 0; i < DIRECTIONAL_MODES; ++i) {
av1_cost_tokens_from_cdf(x->angle_delta_cost[i], fc->angle_delta_cdf[i],
NULL);
}
#endif // CONFIG_EXT_INTRA && CONFIG_EXT_INTRA_MOD
#if CONFIG_LOOP_RESTORATION #if CONFIG_LOOP_RESTORATION
av1_cost_tokens_from_cdf(x->switchable_restore_cost, av1_cost_tokens_from_cdf(x->switchable_restore_cost,
fc->switchable_restore_cdf, NULL); fc->switchable_restore_cdf, NULL);
......
...@@ -3024,8 +3024,13 @@ static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x, ...@@ -3024,8 +3024,13 @@ static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
#if CONFIG_EXT_INTRA #if CONFIG_EXT_INTRA
if (av1_is_directional_mode(mbmi->mode, bsize) && if (av1_is_directional_mode(mbmi->mode, bsize) &&
av1_use_angle_delta(bsize)) { av1_use_angle_delta(bsize)) {
#if CONFIG_EXT_INTRA_MOD
mode_cost += x->angle_delta_cost[mbmi->mode - V_PRED]
[MAX_ANGLE_DELTA + mbmi->angle_delta[0]];
#else
mode_cost += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1, mode_cost += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[0]); MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
#endif // CONFIG_EXT_INTRA_MOD
} }
#endif // CONFIG_EXT_INTRA #endif // CONFIG_EXT_INTRA
#if CONFIG_FILTER_INTRA