Commit d867c9aa authored by Cheng Chen's avatar Cheng Chen

JNT_COMP: 1. Init version of experiment JNT_COMP

Enable to assign distance based weight for joint compound prediction.

(w0, w1) are weights for two predictors of different distance to
current frame.

Use 4 bit precision for quantized distance weight. e.g.
the prediction is generated as

value = (w0 * p0 + w1 * p1) >> n
w0 + w1 = (1 << n), n = 4;

Change-Id: Ib0ff0c41c82b9ebb033f498e90c18a03d18969e4
parent 8a92cd0b
...@@ -1933,6 +1933,14 @@ static const BLOCK_SIZE bsize_2_sqr_bsize[BLOCK_SIZES] = { ...@@ -1933,6 +1933,14 @@ static const BLOCK_SIZE bsize_2_sqr_bsize[BLOCK_SIZES] = {
#define EOB_THRESHOLD_NUM 2 #define EOB_THRESHOLD_NUM 2
#endif #endif
#if CONFIG_JNT_COMP
static const double quant_dist_category[4] = { 1.5, 2.5, 3.5, 255 };
static const int quant_dist_lookup_table[2][4][2] = {
{ { 8, 8 }, { 11, 5 }, { 12, 4 }, { 13, 3 } },
{ { 8, 8 }, { 5, 11 }, { 4, 12 }, { 3, 13 } },
};
#endif // CONFIG_JNT_COMP
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
......
...@@ -361,10 +361,27 @@ void av1_convolve_2d_c(const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst, ...@@ -361,10 +361,27 @@ void av1_convolve_2d_c(const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst,
sum += y_filter[k] * src_vert[(y - fo_vert + k) * im_stride + x]; sum += y_filter[k] * src_vert[(y - fo_vert + k) * im_stride + x];
} }
CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1); CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1);
#if CONFIG_JNT_COMP
if (conv_params->bck_offset == -1) {
if (conv_params->do_average)
dst[y * dst_stride + x] += res;
else
dst[y * dst_stride + x] = res;
} else {
if (conv_params->do_average == 0) {
dst[y * dst_stride + x] = res * conv_params->fwd_offset;
} else {
dst[y * dst_stride + x] += res * conv_params->bck_offset;
dst[y * dst_stride + x] >>= (DIST_PRECISION_BITS - 1);
}
}
#else
if (conv_params->do_average) if (conv_params->do_average)
dst[y * dst_stride + x] += res; dst[y * dst_stride + x] += res;
else else
dst[y * dst_stride + x] = res; dst[y * dst_stride + x] = res;
#endif // CONFIG_JNT_COMP
} }
} }
} }
...@@ -419,10 +436,27 @@ void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride, ...@@ -419,10 +436,27 @@ void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride,
sum += y_filter[k] * src_y[(k - fo_vert) * im_stride]; sum += y_filter[k] * src_y[(k - fo_vert) * im_stride];
} }
CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1); CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1);
#if CONFIG_JNT_COMP
if (conv_params->bck_offset == -1) {
if (conv_params->do_average)
dst[y * dst_stride + x] += res;
else
dst[y * dst_stride + x] = res;
} else {
if (conv_params->do_average == 0) {
dst[y * dst_stride + x] = res * conv_params->fwd_offset;
} else {
dst[y * dst_stride + x] += res * conv_params->bck_offset;
dst[y * dst_stride + x] >>= (DIST_PRECISION_BITS - 1);
}
}
#else
if (conv_params->do_average) if (conv_params->do_average)
dst[y * dst_stride + x] += res; dst[y * dst_stride + x] += res;
else else
dst[y * dst_stride + x] = res; dst[y * dst_stride + x] = res;
#endif // CONFIG_JNT_COMP
} }
src_vert++; src_vert++;
} }
...@@ -481,10 +515,27 @@ void av1_convolve_2d_c(const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst, ...@@ -481,10 +515,27 @@ void av1_convolve_2d_c(const uint8_t *src, int src_stride, CONV_BUF_TYPE *dst,
CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1) - CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1) -
((1 << (offset_bits - conv_params->round_1)) + ((1 << (offset_bits - conv_params->round_1)) +
(1 << (offset_bits - conv_params->round_1 - 1))); (1 << (offset_bits - conv_params->round_1 - 1)));
#if CONFIG_JNT_COMP
if (conv_params->fwd_offset == -1) {
if (conv_params->do_average)
dst[y * dst_stride + x] += res;
else
dst[y * dst_stride + x] = res;
} else {
if (conv_params->do_average) {
dst[y * dst_stride + x] += res * conv_params->bck_offset;
dst[y * dst_stride + x] >>= (DIST_PRECISION_BITS - 1);
} else {
dst[y * dst_stride + x] = res * conv_params->fwd_offset;
}
}
#else
if (conv_params->do_average) if (conv_params->do_average)
dst[y * dst_stride + x] += res; dst[y * dst_stride + x] += res;
else else
dst[y * dst_stride + x] = res; dst[y * dst_stride + x] = res;
#endif // CONFIG_JNT_COMP
} }
} }
} }
...@@ -545,10 +596,27 @@ void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride, ...@@ -545,10 +596,27 @@ void av1_convolve_2d_scale_c(const uint8_t *src, int src_stride,
CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1) - CONV_BUF_TYPE res = ROUND_POWER_OF_TWO(sum, conv_params->round_1) -
((1 << (offset_bits - conv_params->round_1)) + ((1 << (offset_bits - conv_params->round_1)) +
(1 << (offset_bits - conv_params->round_1 - 1))); (1 << (offset_bits - conv_params->round_1 - 1)));
#if CONFIG_JNT_COMP
if (conv_params->fwd_offset == -1) {
if (conv_params->do_average)
dst[y * dst_stride + x] += res;
else
dst[y * dst_stride + x] = res;
} else {
if (conv_params->do_average) {
dst[y * dst_stride + x] += res * conv_params->bck_offset;
dst[y * dst_stride + x] >>= (DIST_PRECISION_BITS - 1);
} else {
dst[y * dst_stride + x] = res * conv_params->fwd_offset;
}
}
#else
if (conv_params->do_average) if (conv_params->do_average)
dst[y * dst_stride + x] += res; dst[y * dst_stride + x] += res;
else else
dst[y * dst_stride + x] = res; dst[y * dst_stride + x] = res;
#endif // CONFIG_JNT_COMP
} }
src_vert++; src_vert++;
} }
...@@ -584,7 +652,19 @@ void av1_convolve_2d_facade(const uint8_t *src, int src_stride, uint8_t *dst, ...@@ -584,7 +652,19 @@ void av1_convolve_2d_facade(const uint8_t *src, int src_stride, uint8_t *dst,
transpose_int32(tr_dst, tr_dst_stride, conv_params->dst, transpose_int32(tr_dst, tr_dst_stride, conv_params->dst,
conv_params->dst_stride, w, h); conv_params->dst_stride, w, h);
// horizontal and vertical parameters are swapped because of the transpose // horizontal and vertical parameters are swapped because of the transpose
#if CONFIG_JNT_COMP
if (scaled)
av1_convolve_2d_scale_c(tr_src + fo_horiz * tr_src_stride + fo_vert,
tr_src_stride, tr_dst, tr_dst_stride, h, w,
&filter_params_y, &filter_params_x, subpel_y_q4,
y_step_q4, subpel_x_q4, x_step_q4, conv_params);
else
av1_convolve_2d_c(tr_src + fo_horiz * tr_src_stride + fo_vert,
tr_src_stride, tr_dst, tr_dst_stride, h, w,
&filter_params_y, &filter_params_x, subpel_y_q4,
subpel_x_q4, conv_params);
#else
if (scaled) if (scaled)
av1_convolve_2d_scale(tr_src + fo_horiz * tr_src_stride + fo_vert, av1_convolve_2d_scale(tr_src + fo_horiz * tr_src_stride + fo_vert,
tr_src_stride, tr_dst, tr_dst_stride, h, w, tr_src_stride, tr_dst, tr_dst_stride, h, w,
...@@ -595,9 +675,22 @@ void av1_convolve_2d_facade(const uint8_t *src, int src_stride, uint8_t *dst, ...@@ -595,9 +675,22 @@ void av1_convolve_2d_facade(const uint8_t *src, int src_stride, uint8_t *dst,
tr_src_stride, tr_dst, tr_dst_stride, h, w, tr_src_stride, tr_dst, tr_dst_stride, h, w,
&filter_params_y, &filter_params_x, subpel_y_q4, &filter_params_y, &filter_params_x, subpel_y_q4,
subpel_x_q4, conv_params); subpel_x_q4, conv_params);
#endif // CONFIG_JNT_COMP
transpose_int32(conv_params->dst, conv_params->dst_stride, tr_dst, transpose_int32(conv_params->dst, conv_params->dst_stride, tr_dst,
tr_dst_stride, h, w); tr_dst_stride, h, w);
} else { } else {
#if CONFIG_JNT_COMP
if (scaled)
av1_convolve_2d_scale_c(src, src_stride, conv_params->dst,
conv_params->dst_stride, w, h, &filter_params_x,
&filter_params_y, subpel_x_q4, x_step_q4,
subpel_y_q4, y_step_q4, conv_params);
else
av1_convolve_2d_c(src, src_stride, conv_params->dst,
conv_params->dst_stride, w, h, &filter_params_x,
&filter_params_y, subpel_x_q4, subpel_y_q4,
conv_params);
#else
if (scaled) if (scaled)
av1_convolve_2d_scale(src, src_stride, conv_params->dst, av1_convolve_2d_scale(src, src_stride, conv_params->dst,
conv_params->dst_stride, w, h, &filter_params_x, conv_params->dst_stride, w, h, &filter_params_x,
...@@ -607,6 +700,7 @@ void av1_convolve_2d_facade(const uint8_t *src, int src_stride, uint8_t *dst, ...@@ -607,6 +700,7 @@ void av1_convolve_2d_facade(const uint8_t *src, int src_stride, uint8_t *dst,
av1_convolve_2d(src, src_stride, conv_params->dst, av1_convolve_2d(src, src_stride, conv_params->dst,
conv_params->dst_stride, w, h, &filter_params_x, conv_params->dst_stride, w, h, &filter_params_x,
&filter_params_y, subpel_x_q4, subpel_y_q4, conv_params); &filter_params_y, subpel_x_q4, subpel_y_q4, conv_params);
#endif // CONFIG_JNT_COMP
} }
} }
......
...@@ -35,6 +35,10 @@ typedef struct ConvolveParams { ...@@ -35,6 +35,10 @@ typedef struct ConvolveParams {
int round_1; int round_1;
int plane; int plane;
int do_post_rounding; int do_post_rounding;
#if CONFIG_JNT_COMP
int fwd_offset;
int bck_offset;
#endif
} ConvolveParams; } ConvolveParams;
static INLINE ConvolveParams get_conv_params(int ref, int do_average, static INLINE ConvolveParams get_conv_params(int ref, int do_average,
......
...@@ -103,6 +103,16 @@ extern "C" { ...@@ -103,6 +103,16 @@ extern "C" {
#define USE_LOOP_FILTER_SUPERBLOCK 1 #define USE_LOOP_FILTER_SUPERBLOCK 1
#endif // CONFIG_LPF_SB #endif // CONFIG_LPF_SB
#if CONFIG_JNT_COMP
typedef enum COMPOUND_DIST_WEIGHT_MODE {
DIST,
} COMPOUND_DIST_WEIGHT_MODE;
#define COMPOUND_WEIGHT_MODE DIST
#define DIST_PRECISION_BITS 4
#define DIST_PRECISION (1 << DIST_PRECISION_BITS) // 16
#endif // CONFIG_JNT_COMP
// Bitstream profiles indicated by 2-3 bits in the uncompressed header. // Bitstream profiles indicated by 2-3 bits in the uncompressed header.
// 00: Profile 0. 8-bit 4:2:0 only. // 00: Profile 0. 8-bit 4:2:0 only.
// 10: Profile 1. 8-bit 4:4:4, 4:2:2, and 4:4:0. // 10: Profile 1. 8-bit 4:4:4, 4:2:2, and 4:4:0.
......
...@@ -1104,6 +1104,60 @@ typedef struct SubpelParams { ...@@ -1104,6 +1104,60 @@ typedef struct SubpelParams {
int subpel_y; int subpel_y;
} SubpelParams; } SubpelParams;
#if CONFIG_JNT_COMP
static void jnt_comp_weight_assign(const AV1_COMMON *cm,
const MB_MODE_INFO *mbmi,
ConvolveParams *conv_params,
int is_compound) {
if (is_compound) {
int bck_idx = cm->frame_refs[mbmi->ref_frame[0] - LAST_FRAME].idx;
int fwd_idx = cm->frame_refs[mbmi->ref_frame[1] - LAST_FRAME].idx;
int bck_frame_index = 0, fwd_frame_index = 0;
int cur_frame_index = cm->cur_frame->cur_frame_offset;
if (bck_idx >= 0) {
bck_frame_index = cm->buffer_pool->frame_bufs[bck_idx].cur_frame_offset;
}
if (fwd_idx >= 0) {
fwd_frame_index = cm->buffer_pool->frame_bufs[fwd_idx].cur_frame_offset;
}
conv_params->bck_offset = abs(cur_frame_index - bck_frame_index);
conv_params->fwd_offset = abs(fwd_frame_index - cur_frame_index);
const double fwd = abs(fwd_frame_index - cur_frame_index);
const double bck = abs(cur_frame_index - bck_frame_index);
int order;
double ratio;
if (COMPOUND_WEIGHT_MODE == DIST) {
if (fwd > bck) {
ratio = (bck != 0) ? fwd / bck : 5.0;
order = 0;
} else {
ratio = (fwd != 0) ? bck / fwd : 5.0;
order = 1;
}
int quant_dist_idx;
for (quant_dist_idx = 0; quant_dist_idx < 4; ++quant_dist_idx) {
if (ratio < quant_dist_category[quant_dist_idx]) break;
}
conv_params->fwd_offset =
quant_dist_lookup_table[0][quant_dist_idx][order];
conv_params->bck_offset =
quant_dist_lookup_table[0][quant_dist_idx][1 - order];
} else {
conv_params->fwd_offset = (DIST_PRECISION >> 1);
conv_params->bck_offset = (DIST_PRECISION >> 1);
}
} else {
conv_params->bck_offset = -1;
conv_params->fwd_offset = -1;
}
}
#endif // CONFIG_JNT_COMP
static INLINE void build_inter_predictors( static INLINE void build_inter_predictors(
const AV1_COMMON *cm, MACROBLOCKD *xd, int plane, const AV1_COMMON *cm, MACROBLOCKD *xd, int plane,
#if CONFIG_MOTION_VAR #if CONFIG_MOTION_VAR
...@@ -1194,6 +1248,10 @@ static INLINE void build_inter_predictors( ...@@ -1194,6 +1248,10 @@ static INLINE void build_inter_predictors(
#else #else
ConvolveParams conv_params = get_conv_params(0, 0, plane); ConvolveParams conv_params = get_conv_params(0, 0, plane);
#endif #endif
#if CONFIG_JNT_COMP
conv_params.fwd_offset = -1;
conv_params.bck_offset = -1;
#endif // CONFIG_JNT_COMP
struct buf_2d *const dst_buf = &pd->dst; struct buf_2d *const dst_buf = &pd->dst;
x = x_base + idx; x = x_base + idx;
y = y_base + idy; y = y_base + idy;
...@@ -1425,6 +1483,10 @@ static INLINE void build_inter_predictors( ...@@ -1425,6 +1483,10 @@ static INLINE void build_inter_predictors(
#if CONFIG_CONVOLVE_ROUND #if CONFIG_CONVOLVE_ROUND
ConvolveParams conv_params = ConvolveParams conv_params =
get_conv_params_no_round(ref, ref, plane, tmp_dst, MAX_SB_SIZE); get_conv_params_no_round(ref, ref, plane, tmp_dst, MAX_SB_SIZE);
#if CONFIG_JNT_COMP
jnt_comp_weight_assign(cm, &mi->mbmi, &conv_params, is_compound);
#endif // CONFIG_JNT_COMP
#else #else
ConvolveParams conv_params = get_conv_params(ref, ref, plane); ConvolveParams conv_params = get_conv_params(ref, ref, plane);
#endif // CONFIG_CONVOLVE_ROUND #endif // CONFIG_CONVOLVE_ROUND
......
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