Commit e6ca8e83 authored by Urvang Joshi's avatar Urvang Joshi

Add a new experiment SMOOTH_HV.

This experiment extends ALT_INTRA by adding two new modes:
smooth horizontal and smooth vertical.

Improvement on *intra frames* in BDRate (PSNR):
===============================================

AWCY (high latency): -0.46%
(Also, -1.0% or more on PSNR Cb,Cr and APSNR Cb,Cr).

AWCY (low latency): -0.43%
(Also, -0.88% to -0.94% on PSNR Cb,Cr and APSNR Cb,Cr).

Google sets:
lowres: -0.454
midres: -0.484
hdres:  -0.525

Improvement on *video overall* in BDRate (PSNR):
================================================

AWCY (high latency): -0.15%

Google sets:
lowres: -0.085
midres: -0.079

Change-Id: I9f4e7c1b8ded1fe244c72838f336103ccc715d50
parent 0c33b15f
......@@ -49,6 +49,9 @@ if (aom_config("CONFIG_TX64X64") eq "yes") {
@pred_names = qw/dc dc_top dc_left dc_128 v h d207e d63e d45e d117 d135 d153/;
if (aom_config("CONFIG_ALT_INTRA") eq "yes") {
push @pred_names, qw/paeth smooth/;
if (aom_config("CONFIG_SMOOTH_HV") eq "yes") {
push @pred_names, qw/smooth_v smooth_h/;
}
} else {
push @pred_names, 'tm';
}
......
......@@ -277,6 +277,70 @@ static INLINE void smooth_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
}
}
#if CONFIG_SMOOTH_HV
static INLINE void smooth_v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
const uint8_t *above,
const uint8_t *left) {
const uint8_t below_pred = left[bs - 1]; // estimated by bottom-left pixel
const int arr_index = get_msb(bs) - 1;
assert(arr_index >= 0);
assert(arr_index < NUM_BLOCK_DIMS);
const uint8_t *const sm_weights = sm_weight_arrays[arr_index];
// scale = 2^sm_weight_log2_scale
const int log2_scale = sm_weight_log2_scale;
const uint16_t scale = (1 << sm_weight_log2_scale);
sm_weights_sanity_checks(sm_weights, scale, log2_scale + sizeof(*dst));
int r;
for (r = 0; r < bs; r++) {
int c;
for (c = 0; c < bs; ++c) {
const uint8_t pixels[] = { above[c], below_pred };
const uint8_t weights[] = { sm_weights[r], scale - sm_weights[r] };
uint32_t this_pred = 0;
assert(scale >= sm_weights[r]);
int i;
for (i = 0; i < 2; ++i) {
this_pred += weights[i] * pixels[i];
}
dst[c] = clip_pixel(divide_round(this_pred, log2_scale));
}
dst += stride;
}
}
static INLINE void smooth_h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
const uint8_t *above,
const uint8_t *left) {
const uint8_t right_pred = above[bs - 1]; // estimated by top-right pixel
const int arr_index = get_msb(bs) - 1;
assert(arr_index >= 0);
assert(arr_index < NUM_BLOCK_DIMS);
const uint8_t *const sm_weights = sm_weight_arrays[arr_index];
// scale = 2^sm_weight_log2_scale
const int log2_scale = sm_weight_log2_scale;
const uint16_t scale = (1 << sm_weight_log2_scale);
sm_weights_sanity_checks(sm_weights, scale, log2_scale + sizeof(*dst));
int r;
for (r = 0; r < bs; r++) {
int c;
for (c = 0; c < bs; ++c) {
const uint8_t pixels[] = { left[r], right_pred };
const uint8_t weights[] = { sm_weights[c], scale - sm_weights[c] };
uint32_t this_pred = 0;
assert(scale >= sm_weights[c]);
int i;
for (i = 0; i < 2; ++i) {
this_pred += weights[i] * pixels[i];
}
dst[c] = clip_pixel(divide_round(this_pred, log2_scale));
}
dst += stride;
}
}
#endif // CONFIG_SMOOTH_HV
#else
static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
......@@ -770,6 +834,68 @@ static INLINE void highbd_smooth_predictor(uint16_t *dst, ptrdiff_t stride,
}
}
static INLINE void highbd_smooth_v_predictor(uint16_t *dst, ptrdiff_t stride,
int bs, const uint16_t *above,
const uint16_t *left, int bd) {
const uint16_t below_pred = left[bs - 1]; // estimated by bottom-left pixel
const int arr_index = get_msb(bs) - 1;
assert(arr_index >= 0);
assert(arr_index < NUM_BLOCK_DIMS);
const uint8_t *const sm_weights = sm_weight_arrays[arr_index];
// scale = 2^sm_weight_log2_scale
const int log2_scale = sm_weight_log2_scale;
const uint16_t scale = (1 << sm_weight_log2_scale);
sm_weights_sanity_checks(sm_weights, scale, log2_scale + sizeof(*dst));
int r;
for (r = 0; r < bs; r++) {
int c;
for (c = 0; c < bs; ++c) {
const uint16_t pixels[] = { above[c], below_pred };
const uint8_t weights[] = { sm_weights[r], scale - sm_weights[r] };
uint32_t this_pred = 0;
assert(scale >= sm_weights[r]);
int i;
for (i = 0; i < 2; ++i) {
this_pred += weights[i] * pixels[i];
}
dst[c] = clip_pixel_highbd(divide_round(this_pred, log2_scale), bd);
}
dst += stride;
}
}
static INLINE void highbd_smooth_h_predictor(uint16_t *dst, ptrdiff_t stride,
int bs, const uint16_t *above,
const uint16_t *left, int bd) {
const uint16_t right_pred = above[bs - 1]; // estimated by top-right pixel
const int arr_index = get_msb(bs) - 1;
assert(arr_index >= 0);
assert(arr_index < NUM_BLOCK_DIMS);
const uint8_t *const sm_weights = sm_weight_arrays[arr_index];
// scale = 2^sm_weight_log2_scale
const int log2_scale = sm_weight_log2_scale;
const uint16_t scale = (1 << sm_weight_log2_scale);
sm_weights_sanity_checks(sm_weights, scale, log2_scale + sizeof(*dst));
int r;
for (r = 0; r < bs; r++) {
int c;
for (c = 0; c < bs; ++c) {
const uint16_t pixels[] = { left[r], right_pred };
const uint8_t weights[] = { sm_weights[c], scale - sm_weights[c] };
uint32_t this_pred = 0;
assert(scale >= sm_weights[c]);
int i;
for (i = 0; i < 2; ++i) {
this_pred += weights[i] * pixels[i];
}
dst[c] = clip_pixel_highbd(divide_round(this_pred, log2_scale), bd);
}
dst += stride;
}
}
#else
static INLINE void highbd_tm_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
const uint16_t *above,
......@@ -958,8 +1084,12 @@ intra_pred_above_4x4(d153)
intra_pred_allsizes(v)
intra_pred_allsizes(h)
#if CONFIG_ALT_INTRA
intra_pred_allsizes(paeth)
intra_pred_allsizes(smooth)
#if CONFIG_SMOOTH_HV
intra_pred_allsizes(smooth_v)
intra_pred_allsizes(smooth_h)
#endif // CONFIG_SMOOTH_HV
intra_pred_allsizes(paeth)
#else
intra_pred_allsizes(tm)
#endif // CONFIG_ALT_INTRA
......
......@@ -267,7 +267,10 @@ static const int mode_lf_lut[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // INTRA_MODES
#if CONFIG_ALT_INTRA
0,
#endif
#if CONFIG_SMOOTH_HV
0, 0,
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
1, 1, 0, 1, // INTER_MODES (ZEROMV == 0)
#if CONFIG_EXT_INTER
1, 1, 1, 1, 1, 1, 1, 1, 0, 1 // INTER_COMPOUND_MODES (ZERO_ZEROMV == 0)
......
......@@ -703,6 +703,10 @@ static const TX_TYPE intra_mode_to_tx_type_context[INTRA_MODES] = {
ADST_DCT, // D63
#if CONFIG_ALT_INTRA
ADST_ADST, // SMOOTH
#if CONFIG_SMOOTH_HV
ADST_DCT, // SMOOTH_V
DCT_ADST, // SMOOTH_H
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
ADST_ADST, // TM
};
......
This diff is collapsed.
......@@ -320,8 +320,12 @@ typedef enum ATTRIBUTE_PACKED {
D63_PRED, // Directional 63 deg = round(arctan(2/1) * 180/pi)
#if CONFIG_ALT_INTRA
SMOOTH_PRED, // Combination of horizontal and vertical interpolation
#endif // CONFIG_ALT_INTRA
TM_PRED, // True-motion
#if CONFIG_SMOOTH_HV
SMOOTH_V_PRED, // Vertical interpolation
SMOOTH_H_PRED, // Horizontal interpolation
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
TM_PRED, // True-motion
NEARESTMV,
NEARMV,
ZEROMV,
......
......@@ -47,7 +47,11 @@ static const uint8_t extend_modes[INTRA_MODES] = {
NEED_LEFT | NEED_BOTTOMLEFT, // D207
NEED_ABOVE | NEED_ABOVERIGHT, // D63
#if CONFIG_ALT_INTRA
NEED_LEFT | NEED_ABOVE, // SMOOTH
NEED_LEFT | NEED_ABOVE, // SMOOTH
#if CONFIG_SMOOTH_HV
NEED_LEFT | NEED_ABOVE, // SMOOTH_V
NEED_LEFT | NEED_ABOVE, // SMOOTH_H
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT, // TM
};
......@@ -590,6 +594,10 @@ static void av1_init_intra_predictors_internal(void) {
#if CONFIG_ALT_INTRA
INIT_ALL_SIZES(pred[TM_PRED], paeth);
INIT_ALL_SIZES(pred[SMOOTH_PRED], smooth);
#if CONFIG_SMOOTH_HV
INIT_ALL_SIZES(pred[SMOOTH_V_PRED], smooth_v);
INIT_ALL_SIZES(pred[SMOOTH_H_PRED], smooth_h);
#endif // CONFIG_SMOOTH_HV
#else
INIT_ALL_SIZES(pred[TM_PRED], tm);
#endif // CONFIG_ALT_INTRA
......@@ -612,6 +620,10 @@ static void av1_init_intra_predictors_internal(void) {
#if CONFIG_ALT_INTRA
INIT_ALL_SIZES(pred_high[TM_PRED], highbd_paeth);
INIT_ALL_SIZES(pred_high[SMOOTH_PRED], highbd_smooth);
#if CONFIG_SMOOTH_HV
INIT_ALL_SIZES(pred_high[SMOOTH_V_PRED], highbd_smooth_v);
INIT_ALL_SIZES(pred_high[SMOOTH_H_PRED], highbd_smooth_h);
#endif // CONFIG_SMOOTH_HV
#else
INIT_ALL_SIZES(pred_high[TM_PRED], highbd_tm);
#endif // CONFIG_ALT_INTRA
......
......@@ -63,6 +63,9 @@ static INLINE int av1_is_directional_mode(PREDICTION_MODE mode,
return mode != DC_PRED && mode != TM_PRED &&
#if CONFIG_ALT_INTRA
mode != SMOOTH_PRED &&
#if CONFIG_SMOOTH_HV
mode != SMOOTH_V_PRED && mode != SMOOTH_H_PRED &&
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
bsize >= BLOCK_8X8;
}
......
......@@ -1243,7 +1243,11 @@ static void update_state(const AV1_COMP *const cpi, ThreadData *td,
THR_D63_PRED /*D63_PRED*/,
#if CONFIG_ALT_INTRA
THR_SMOOTH, /*SMOOTH_PRED*/
#endif // CONFIG_ALT_INTRA
#if CONFIG_SMOOTH_HV
THR_SMOOTH_V, /*SMOOTH_V_PRED*/
THR_SMOOTH_H, /*SMOOTH_H_PRED*/
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
THR_TM /*TM_PRED*/,
};
++mode_chosen_counts[kf_mode_index[mbmi->mode]];
......
......@@ -130,6 +130,10 @@ typedef enum {
#if CONFIG_ALT_INTRA
THR_SMOOTH,
#if CONFIG_SMOOTH_HV
THR_SMOOTH_V,
THR_SMOOTH_H,
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
#if CONFIG_EXT_INTER
......
......@@ -217,6 +217,10 @@ static const MODE_DEFINITION av1_mode_order[MAX_MODES] = {
#if CONFIG_ALT_INTRA
{ SMOOTH_PRED, { INTRA_FRAME, NONE_FRAME } },
#if CONFIG_SMOOTH_HV
{ SMOOTH_V_PRED, { INTRA_FRAME, NONE_FRAME } },
{ SMOOTH_H_PRED, { INTRA_FRAME, NONE_FRAME } },
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
#if CONFIG_EXT_INTER
......@@ -9549,12 +9553,10 @@ void av1_rd_pick_inter_mode_sb(const AV1_COMP *cpi, TileDataEnc *tile_data,
const int *const intra_mode_cost = cpi->mbmode_cost[size_group_lookup[bsize]];
int best_skip2 = 0;
uint8_t ref_frame_skip_mask[2] = { 0 };
#if CONFIG_EXT_INTER
uint32_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
#if CONFIG_EXT_INTER
MV_REFERENCE_FRAME best_single_inter_ref = LAST_FRAME;
int64_t best_single_inter_rd = INT64_MAX;
#else
uint16_t mode_skip_mask[TOTAL_REFS_PER_FRAME] = { 0 };
#endif // CONFIG_EXT_INTER
int mode_skip_start = sf->mode_skip_start + 1;
const int *const rd_threshes = rd_opt->threshes[segment_id][bsize];
......
......@@ -24,6 +24,9 @@ enum {
(1 << D207_PRED) | (1 << D63_PRED) |
#if CONFIG_ALT_INTRA
(1 << SMOOTH_PRED) |
#if CONFIG_SMOOTH_HV
(1 << SMOOTH_V_PRED) | (1 << SMOOTH_H_PRED) |
#endif // CONFIG_SMOOTH_HV
#endif // CONFIG_ALT_INTRA
(1 << TM_PRED),
INTRA_DC = (1 << DC_PRED),
......
......@@ -321,6 +321,7 @@ EXPERIMENT_LIST="
compound_singleref
aom_qm
lowdelay_compound
smooth_hv
"
CONFIG_LIST="
dependency_tracking
......@@ -517,6 +518,8 @@ post_process_cmdline() {
enabled ext_delta_q && soft_enable delta_q
enabled txk_sel && soft_enable lv_map
enabled compound_round && soft_enable convolve_round
enabled smooth_hv && soft_enable alt_intra
if ! enabled delta_q && enabled ext_delta_q; then
log_echo "ext_delta_q requires delta_q, so disabling ext_delta_q"
disable_feature ext_delta_q
......
This diff is collapsed.
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