Commit 830d4ce4 authored by Joe Young's avatar Joe Young

[intra-edge] Convert 4x4 VP9 to ext-intra; upsample edge samples

Updates to intra-edge experiment

- Convert VP9-style intra pred to Ext-intra style
- Upsample edge predictors by 2x based on angle and edge size

BD-rate, 1-kf AWCY
  360p:  -0.11%
  720p:  -0.54
  1080p: -0.96

Change-Id: Ib73805d31d5d286e607a7ee7470fcbdf11edbbff
parent 71adf529
This diff is collapsed.
......@@ -73,10 +73,27 @@ static const INTERINTRA_MODE intra_to_interintra_mode[INTRA_MODES] = {
#define FILTER_INTRA_PREC_BITS 10
#endif // CONFIG_FILTER_INTRA
#define CONFIG_INTRA_EDGE_UPSAMPLE CONFIG_INTRA_EDGE
#define CONFIG_USE_ANGLE_DELTA_SUB8X8 0
#if CONFIG_EXT_INTRA
static INLINE int av1_is_directional_mode(PREDICTION_MODE mode,
BLOCK_SIZE bsize) {
#if CONFIG_INTRA_EDGE_UPSAMPLE
(void)bsize;
return mode >= V_PRED && mode <= D63_PRED;
#else
return mode >= V_PRED && mode <= D63_PRED && bsize >= BLOCK_8X8;
#endif
}
static INLINE int av1_use_angle_delta(BLOCK_SIZE bsize) {
(void)bsize;
#if CONFIG_USE_ANGLE_DELTA_SUB8X8
return 1;
#else
return bsize >= BLOCK_8X8;
#endif
}
#endif // CONFIG_EXT_INTRA
......
......@@ -866,7 +866,11 @@ static void read_intra_angle_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
#endif // CONFIG_INTRA_INTERP
(void)cm;
if (bsize < BLOCK_8X8) return;
mbmi->angle_delta[0] = 0;
mbmi->angle_delta[1] = 0;
if (!av1_use_angle_delta(bsize)) return;
if (av1_is_directional_mode(mbmi->mode, bsize)) {
mbmi->angle_delta[0] =
......@@ -1160,6 +1164,9 @@ static void read_intra_frame_mode_info(AV1_COMMON *const cm,
#endif // CONFIG_CFL
#if CONFIG_CB4X4
} else {
// Avoid decoding angle_info if there is is no chroma prediction
mbmi->uv_mode = DC_PRED;
}
#endif
......
......@@ -1451,7 +1451,7 @@ static void write_intra_angle_info(const MACROBLOCKD *xd,
#endif // CONFIG_INTRA_INTERP
(void)ec_ctx;
if (bsize < BLOCK_8X8) return;
if (!av1_use_angle_delta(bsize)) return;
if (av1_is_directional_mode(mbmi->mode, bsize)) {
write_uniform(w, 2 * MAX_ANGLE_DELTA + 1,
......
......@@ -2458,7 +2458,8 @@ static int64_t intra_model_yrd(const AV1_COMP *const cpi, MACROBLOCK *const x,
model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &this_rd_stats.rate,
&this_rd_stats.dist, &this_rd_stats.skip, &temp_sse);
#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)) {
mode_cost += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
}
......@@ -3579,8 +3580,8 @@ static void angle_estimation(const uint8_t *src, int src_stride, int rows,
uint8_t *directional_mode_skip_mask) {
memset(directional_mode_skip_mask, 0,
INTRA_MODES * sizeof(*directional_mode_skip_mask));
// Sub-8x8 blocks do not use extra directions.
if (bsize < BLOCK_8X8) return;
// Check if angle_delta is used
if (!av1_use_angle_delta(bsize)) return;
uint64_t hist[DIRECTIONAL_MODES];
memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
src += src_stride;
......@@ -3634,8 +3635,8 @@ static void highbd_angle_estimation(const uint8_t *src8, int src_stride,
uint8_t *directional_mode_skip_mask) {
memset(directional_mode_skip_mask, 0,
INTRA_MODES * sizeof(*directional_mode_skip_mask));
// Sub-8x8 blocks do not use extra directions.
if (bsize < BLOCK_8X8) return;
// Check if angle_delta is used
if (!av1_use_angle_delta(bsize)) return;
uint16_t *src = CONVERT_TO_SHORTPTR(src8);
uint64_t hist[DIRECTIONAL_MODES];
memset(hist, 0, DIRECTIONAL_MODES * sizeof(hist[0]));
......@@ -3791,7 +3792,7 @@ static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
#if CONFIG_EXT_INTRA
is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
if (is_directional_mode && directional_mode_skip_mask[mbmi->mode]) continue;
if (is_directional_mode) {
if (is_directional_mode && av1_use_angle_delta(bsize)) {
this_rd_stats.rate = INT_MAX;
rd_pick_intra_angle_sby(cpi, x, &this_rate, &this_rd_stats, bsize,
bmode_costs[mbmi->mode], best_rd, &best_model_rd);
......@@ -3837,8 +3838,10 @@ static int64_t rd_pick_intra_sby_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
this_rate +=
cpi->intra_filter_cost[intra_filter_ctx][mbmi->intra_filter];
#endif // CONFIG_INTRA_INTERP
this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
if (av1_use_angle_delta(bsize)) {
this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
}
}
#endif // CONFIG_EXT_INTRA
this_rd = RDCOST(x->rdmult, this_rate, this_distortion);
......@@ -4921,7 +4924,7 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
mbmi->uv_mode = mode;
#if CONFIG_EXT_INTRA
mbmi->angle_delta[1] = 0;
if (is_directional_mode) {
if (is_directional_mode && av1_use_angle_delta(mbmi->sb_type)) {
const int rate_overhead = cpi->intra_uv_mode_cost[mbmi->mode][mode] +
write_uniform_cost(2 * MAX_ANGLE_DELTA + 1, 0);
if (!rd_pick_intra_angle_sbuv(cpi, x, bsize, rate_overhead, best_rd,
......@@ -4942,7 +4945,7 @@ static int64_t rd_pick_intra_sbuv_mode(const AV1_COMP *const cpi, MACROBLOCK *x,
tokenonly_rd_stats.rate + cpi->intra_uv_mode_cost[mbmi->mode][mode];
#if CONFIG_EXT_INTRA
if (is_directional_mode) {
if (is_directional_mode && av1_use_angle_delta(mbmi->sb_type)) {
this_rate += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
}
......@@ -9013,7 +9016,8 @@ static void pick_filter_intra_interframe(
rate2 += write_uniform_cost(
FILTER_INTRA_MODES, mbmi->filter_intra_mode_info.filter_intra_mode[0]);
#if CONFIG_EXT_INTRA
if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
if (av1_is_directional_mode(mbmi->uv_mode, bsize) &&
av1_use_angle_delta(bsize)) {
rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
}
......@@ -9760,7 +9764,7 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
struct macroblockd_plane *const pd = &xd->plane[1];
#if CONFIG_EXT_INTRA
is_directional_mode = av1_is_directional_mode(mbmi->mode, bsize);
if (is_directional_mode) {
if (is_directional_mode && av1_use_angle_delta(bsize)) {
int rate_dummy;
int64_t model_rd = INT64_MAX;
if (!angle_stats_ready) {
......@@ -9873,10 +9877,13 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
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_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
if (av1_use_angle_delta(bsize)) {
rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[0]);
}
}
if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
if (av1_is_directional_mode(mbmi->uv_mode, bsize) &&
av1_use_angle_delta(bsize)) {
rate2 += write_uniform_cost(2 * MAX_ANGLE_DELTA + 1,
MAX_ANGLE_DELTA + mbmi->angle_delta[1]);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment