Commit fdeb1169 authored by Imdad Sardharwalla's avatar Imdad Sardharwalla Committed by Debargha Mukherjee

Add encoder/bitstream support for SKIP_SGR

The encoder can now make use of SGR filters with r == 0 when
SKIP_SGR == 1. If r == 0 for a filter, no blending coefficient
for that filter is written to/read from the bitstream.

Change-Id: I8496b87a7fa7b29f5ee9e7687bd117f93e90e649
parent 9aea97d1
......@@ -29,12 +29,17 @@
const sgr_params_type sgr_params[SGRPROJ_PARAMS] = {
// r1, eps1, r2, eps2
#if CONFIG_SKIP_SGR
// Setting r = 0 skips the filter
#endif // CONFIG_SKIP_SGR
// Setting r = 0 skips the filter
{ 2, 12, 1, 4 }, { 2, 15, 1, 6 }, { 2, 18, 1, 8 }, { 2, 20, 1, 9 },
{ 2, 22, 1, 10 }, { 2, 25, 1, 11 }, { 2, 35, 1, 12 }, { 2, 45, 1, 13 },
{ 2, 55, 1, 14 }, { 2, 65, 1, 15 }, { 2, 75, 1, 16 }, { 2, 30, 1, 6 },
{ 2, 50, 1, 12 }, { 2, 60, 1, 13 }, { 2, 70, 1, 14 }, { 2, 80, 1, 15 },
#else // CONFIG_SKIP_SGR
{ 2, 12, 1, 4 }, { 2, 15, 1, 6 }, { 2, 18, 1, 8 }, { 2, 20, 1, 9 },
{ 2, 22, 1, 10 }, { 2, 25, 1, 11 }, { 2, 35, 1, 12 }, { 2, 45, 1, 13 },
{ 2, 55, 1, 14 }, { 2, 65, 1, 15 }, { 2, 75, 1, 16 }, { 2, 30, 1, 6 },
{ 2, 50, 1, 12 }, { 2, 60, 1, 13 }, { 2, 70, 1, 14 }, { 2, 80, 1, 15 },
#endif // CONFIG_SKIP_SGR
};
// Count horizontal or vertical units per tile (use a width or height for
......@@ -740,10 +745,27 @@ static void boxsum(int32_t *src, int width, int height, int src_stride, int r,
assert(0 && "Invalid value of r in self-guided filter");
}
#if CONFIG_SKIP_SGR
void decode_xq(const int *xqd, int *xq, const sgr_params_type *params) {
if (params->r1 == 0) {
assert(xqd[0] == 0);
xq[0] = 0;
xq[1] = (1 << SGRPROJ_PRJ_BITS) - xqd[1];
} else if (params->r2 == 0) {
assert(xqd[1] == 0);
xq[0] = xqd[0];
xq[1] = 0;
} else {
xq[0] = xqd[0];
xq[1] = (1 << SGRPROJ_PRJ_BITS) - xq[0] - xqd[1];
}
}
#else // CONFIG_SKIP_SGR
void decode_xq(const int *xqd, int *xq) {
xq[0] = xqd[0];
xq[1] = (1 << SGRPROJ_PRJ_BITS) - xq[0] - xqd[1];
}
#endif // CONFIG_SKIP_SGR
const int32_t x_by_xplus1[256] = {
// Special case: Map 0 -> 1 (corresponding to a value of 1/256)
......@@ -1059,21 +1081,14 @@ void av1_selfguided_restoration_c(const uint8_t *dgd8, int width, int height,
assert(!(params->r1 == 0 && params->r2 == 0));
#if CONFIG_FAST_SGR
if (params->r1 > 0) {
// r == 2 filter
assert(params->r1 == 2);
if (params->r1 > 0)
av1_selfguided_restoration_fast_internal(dgd32, width, height, dgd32_stride,
flt1, flt_stride, bit_depth,
params->r1, params->e1);
}
if (params->r2 > 0) {
// r == 1 filter
assert(params->r2 == 1);
if (params->r2 > 0)
av1_selfguided_restoration_internal(dgd32, width, height, dgd32_stride,
flt2, flt_stride, bit_depth, params->r2,
params->e2);
}
#else
if (params->r1 > 0)
av1_selfguided_restoration_internal(dgd32, width, height, dgd32_stride,
......@@ -1111,7 +1126,6 @@ void apply_selfguided_restoration_c(const uint8_t *dat8, int width, int height,
uint8_t *dst8, int dst_stride,
int32_t *tmpbuf, int bit_depth,
int highbd) {
int xq[2];
int32_t *flt1 = tmpbuf;
int32_t *flt2 = flt1 + RESTORATION_TILEPELS_MAX;
assert(width * height <= RESTORATION_TILEPELS_MAX);
......@@ -1120,11 +1134,14 @@ void apply_selfguided_restoration_c(const uint8_t *dat8, int width, int height,
const sgr_params_type *params = &sgr_params[eps];
av1_selfguided_restoration_c(dat8, width, height, stride, flt1, flt2, width,
params, bit_depth, highbd);
int xq[2];
decode_xq(xqd, xq, params);
#else // CONFIG_SKIP_SGR
av1_selfguided_restoration_c(dat8, width, height, stride, flt1, flt2, width,
&sgr_params[eps], bit_depth, highbd);
#endif // CONFIG_SKIP_SGR
int xq[2];
decode_xq(xqd, xq);
#endif // CONFIG_SKIP_SGR
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
const int k = i * width + j;
......
......@@ -273,7 +273,11 @@ void av1_free_restoration_struct(RestorationInfo *rst_info);
void extend_frame(uint8_t *data, int width, int height, int stride,
int border_horz, int border_vert, int highbd);
#if CONFIG_SKIP_SGR
void decode_xq(const int *xqd, int *xq, const sgr_params_type *params);
#else // CONFIG_SKIP_SGR
void decode_xq(const int *xqd, int *xq);
#endif // CONFIG_SKIP_SGR
// Filter a single loop restoration unit.
//
......
......@@ -594,8 +594,6 @@ void av1_selfguided_restoration_avx2(const uint8_t *dgd8, int width, int height,
assert(params->r2 < AOMMIN(SGRPROJ_BORDER_VERT, SGRPROJ_BORDER_HORZ));
if (params->r1 > 0) {
// r == 2 filter
assert(params->r1 == 2);
calc_ab_fast(A, B, C, D, width, height, buf_stride, params->e1, bit_depth,
params->r1);
final_filter_fast(flt1, flt_stride, A, B, buf_stride, dgd8, dgd_stride,
......@@ -603,8 +601,6 @@ void av1_selfguided_restoration_avx2(const uint8_t *dgd8, int width, int height,
}
if (params->r2 > 0) {
// r == 1 filter
assert(params->r2 == 1);
calc_ab(A, B, C, D, width, height, buf_stride, params->e2, bit_depth,
params->r2);
final_filter(flt2, flt_stride, A, B, buf_stride, dgd8, dgd_stride, width,
......@@ -670,13 +666,14 @@ void apply_selfguided_restoration_avx2(const uint8_t *dat8, int width,
const sgr_params_type *params = &sgr_params[eps];
av1_selfguided_restoration_avx2(dat8, width, height, stride, flt1, flt2,
width, params, bit_depth, highbd);
int xq[2];
decode_xq(xqd, xq, params);
#else // CONFIG_SKIP_SGR
av1_selfguided_restoration_avx2(dat8, width, height, stride, flt1, flt2,
width, &sgr_params[eps], bit_depth, highbd);
#endif // CONFIG_SKIP_SGR
int xq[2];
decode_xq(xqd, xq);
#endif // CONFIG_SKIP_SGR
__m256i xq0 = _mm256_set1_epi32(xq[0]);
__m256i xq1 = _mm256_set1_epi32(xq[1]);
......
......@@ -549,8 +549,6 @@ void av1_selfguided_restoration_sse4_1(const uint8_t *dgd8, int width,
assert(params->r2 < AOMMIN(SGRPROJ_BORDER_VERT, SGRPROJ_BORDER_HORZ));
if (params->r1 > 0) {
// r == 2 filter
assert(params->r1 == 2);
calc_ab_fast(A, B, C, D, width, height, buf_stride, params->e1, bit_depth,
params->r1);
final_filter_fast2(flt1, flt_stride, A, B, buf_stride, dgd8, dgd_stride,
......@@ -558,8 +556,6 @@ void av1_selfguided_restoration_sse4_1(const uint8_t *dgd8, int width,
}
if (params->r2 > 0) {
// r == 1 filter
assert(params->r2 == 1);
calc_ab(A, B, C, D, width, height, buf_stride, params->e2, bit_depth,
params->r2);
final_filter(flt2, flt_stride, A, B, buf_stride, dgd8, dgd_stride, width,
......@@ -625,13 +621,14 @@ void apply_selfguided_restoration_sse4_1(const uint8_t *dat8, int width,
const sgr_params_type *params = &sgr_params[eps];
av1_selfguided_restoration_sse4_1(dat8, width, height, stride, flt1, flt2,
width, params, bit_depth, highbd);
int xq[2];
decode_xq(xqd, xq, params);
#else // CONFIG_SKIP_SGR
av1_selfguided_restoration_sse4_1(dat8, width, height, stride, flt1, flt2,
width, &sgr_params[eps], bit_depth, highbd);
#endif // CONFIG_SKIP_SGR
int xq[2];
decode_xq(xqd, xq);
#endif // CONFIG_SKIP_SGR
__m128i xq0 = _mm_set1_epi32(xq[0]);
__m128i xq1 = _mm_set1_epi32(xq[1]);
......
......@@ -911,6 +911,42 @@ static void read_wiener_filter(int wiener_win, WienerInfo *wiener_info,
memcpy(ref_wiener_info, wiener_info, sizeof(*wiener_info));
}
#if CONFIG_SKIP_SGR
static void read_sgrproj_filter(SgrprojInfo *sgrproj_info,
SgrprojInfo *ref_sgrproj_info, aom_reader *rb) {
sgrproj_info->ep = aom_read_literal(rb, SGRPROJ_PARAMS_BITS, ACCT_STR);
const sgr_params_type *params = &sgr_params[sgrproj_info->ep];
if (params->r1 == 0) {
sgrproj_info->xqd[0] = 0;
sgrproj_info->xqd[1] =
aom_read_primitive_refsubexpfin(
rb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K,
ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1, ACCT_STR) +
SGRPROJ_PRJ_MIN1;
} else if (params->r2 == 0) {
sgrproj_info->xqd[0] =
aom_read_primitive_refsubexpfin(
rb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K,
ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0, ACCT_STR) +
SGRPROJ_PRJ_MIN0;
sgrproj_info->xqd[1] = 0;
} else {
sgrproj_info->xqd[0] =
aom_read_primitive_refsubexpfin(
rb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K,
ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0, ACCT_STR) +
SGRPROJ_PRJ_MIN0;
sgrproj_info->xqd[1] =
aom_read_primitive_refsubexpfin(
rb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K,
ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1, ACCT_STR) +
SGRPROJ_PRJ_MIN1;
}
memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info));
}
#else // CONFIG_SKIP_SGR
static void read_sgrproj_filter(SgrprojInfo *sgrproj_info,
SgrprojInfo *ref_sgrproj_info, aom_reader *rb) {
sgrproj_info->ep = aom_read_literal(rb, SGRPROJ_PARAMS_BITS, ACCT_STR);
......@@ -926,6 +962,7 @@ static void read_sgrproj_filter(SgrprojInfo *sgrproj_info,
SGRPROJ_PRJ_MIN1;
memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info));
}
#endif // CONFIG_SKIP_SGR
static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm,
MACROBLOCKD *xd,
......
......@@ -2187,6 +2187,39 @@ static void write_wiener_filter(int wiener_win, const WienerInfo *wiener_info,
memcpy(ref_wiener_info, wiener_info, sizeof(*wiener_info));
}
#if CONFIG_SKIP_SGR
static void write_sgrproj_filter(const SgrprojInfo *sgrproj_info,
SgrprojInfo *ref_sgrproj_info,
aom_writer *wb) {
aom_write_literal(wb, sgrproj_info->ep, SGRPROJ_PARAMS_BITS);
const sgr_params_type *params = &sgr_params[sgrproj_info->ep];
if (params->r1 == 0) {
assert(sgrproj_info->xqd[0] == 0);
aom_write_primitive_refsubexpfin(
wb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K,
ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1,
sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1);
} else if (params->r2 == 0) {
aom_write_primitive_refsubexpfin(
wb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K,
ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0,
sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0);
assert(sgrproj_info->xqd[1] == 0);
} else {
aom_write_primitive_refsubexpfin(
wb, SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K,
ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0,
sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0);
aom_write_primitive_refsubexpfin(
wb, SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K,
ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1,
sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1);
}
memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info));
}
#else // CONFIG_SKIP_SGR
static void write_sgrproj_filter(const SgrprojInfo *sgrproj_info,
SgrprojInfo *ref_sgrproj_info,
aom_writer *wb) {
......@@ -2201,6 +2234,7 @@ static void write_sgrproj_filter(const SgrprojInfo *sgrproj_info,
sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1);
memcpy(ref_sgrproj_info, sgrproj_info, sizeof(*sgrproj_info));
}
#endif // CONFIG_SKIP_SGR
static void loop_restoration_write_sb_coeffs(const AV1_COMMON *const cm,
MACROBLOCKD *xd,
......
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