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
diff --git a/av1/common/restoration.c b/av1/common/restoration.c
index e3a3ea7..e861243 100644
--- a/av1/common/restoration.c
+++ b/av1/common/restoration.c
@@ -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 @@
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 @@
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 @@
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 @@
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;
diff --git a/av1/common/restoration.h b/av1/common/restoration.h
index 8734754..520cfa5 100644
--- a/av1/common/restoration.h
+++ b/av1/common/restoration.h
@@ -273,7 +273,11 @@
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.
//
diff --git a/av1/common/x86/selfguided_avx2.c b/av1/common/x86/selfguided_avx2.c
index db82db4..bc82bec 100644
--- a/av1/common/x86/selfguided_avx2.c
+++ b/av1/common/x86/selfguided_avx2.c
@@ -594,8 +594,6 @@
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 @@
}
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 @@
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]);
diff --git a/av1/common/x86/selfguided_sse4.c b/av1/common/x86/selfguided_sse4.c
index 7f94fd9..8cbb84f 100644
--- a/av1/common/x86/selfguided_sse4.c
+++ b/av1/common/x86/selfguided_sse4.c
@@ -549,8 +549,6 @@
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 @@
}
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 @@
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]);
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index cf7a1fd..d3fa2ff 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -911,6 +911,42 @@
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 @@
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,
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 2693b26..21e23ea 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2187,6 +2187,39 @@
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 @@
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,
diff --git a/av1/encoder/pickrst.c b/av1/encoder/pickrst.c
index 8491806..5d1d269 100644
--- a/av1/encoder/pickrst.c
+++ b/av1/encoder/pickrst.c
@@ -179,11 +179,20 @@
int src_stride, const uint8_t *dat8,
int dat_stride, int use_highbitdepth,
int32_t *flt1, int flt1_stride,
- int32_t *flt2, int flt2_stride, int *xqd) {
+ int32_t *flt2, int flt2_stride, int *xqd
+#if CONFIG_SKIP_SGR
+ ,
+ const sgr_params_type *params
+#endif // CONFIG_SKIP_SGR
+) {
int i, j;
int64_t err = 0;
int xq[2];
+#if CONFIG_SKIP_SGR
+ decode_xq(xqd, xq, params);
+#else // CONFIG_SKIP_SGR
decode_xq(xqd, xq);
+#endif // CONFIG_SKIP_SGR
if (!use_highbitdepth) {
const uint8_t *src = src8;
const uint8_t *dat = dat8;
@@ -191,9 +200,15 @@
for (j = 0; j < width; ++j) {
const int32_t u =
(int32_t)(dat[i * dat_stride + j] << SGRPROJ_RST_BITS);
+#if CONFIG_SKIP_SGR
+ int32_t v = u << SGRPROJ_PRJ_BITS;
+ if (params->r1 > 0) v += xq[0] * (flt1[i * flt1_stride + j] - u);
+ if (params->r2 > 0) v += xq[1] * (flt2[i * flt2_stride + j] - u);
+#else // CONFIG_SKIP_SGR
const int32_t f1 = (int32_t)flt1[i * flt1_stride + j] - u;
const int32_t f2 = (int32_t)flt2[i * flt2_stride + j] - u;
const int32_t v = xq[0] * f1 + xq[1] * f2 + (u << SGRPROJ_PRJ_BITS);
+#endif // CONFIG_SKIP_SGR
const int32_t e =
ROUND_POWER_OF_TWO(v, SGRPROJ_RST_BITS + SGRPROJ_PRJ_BITS) -
src[i * src_stride + j];
@@ -207,9 +222,15 @@
for (j = 0; j < width; ++j) {
const int32_t u =
(int32_t)(dat[i * dat_stride + j] << SGRPROJ_RST_BITS);
+#if CONFIG_SKIP_SGR
+ int32_t v = u << SGRPROJ_PRJ_BITS;
+ if (params->r1 > 0) v += xq[0] * (flt1[i * flt1_stride + j] - u);
+ if (params->r2 > 0) v += xq[1] * (flt2[i * flt2_stride + j] - u);
+#else // CONFIG_SKIP_SGR
const int32_t f1 = (int32_t)flt1[i * flt1_stride + j] - u;
const int32_t f2 = (int32_t)flt2[i * flt2_stride + j] - u;
const int32_t v = xq[0] * f1 + xq[1] * f2 + (u << SGRPROJ_PRJ_BITS);
+#endif // CONFIG_SKIP_SGR
const int32_t e =
ROUND_POWER_OF_TWO(v, SGRPROJ_RST_BITS + SGRPROJ_PRJ_BITS) -
src[i * src_stride + j];
@@ -224,10 +245,21 @@
static int64_t finer_search_pixel_proj_error(
const uint8_t *src8, int width, int height, int src_stride,
const uint8_t *dat8, int dat_stride, int use_highbitdepth, int32_t *flt1,
- int flt1_stride, int32_t *flt2, int flt2_stride, int start_step, int *xqd) {
+ int flt1_stride, int32_t *flt2, int flt2_stride, int start_step, int *xqd
+#if CONFIG_SKIP_SGR
+ ,
+ const sgr_params_type *params
+#endif // CONFIG_SKIP_SGR
+) {
+#if CONFIG_SKIP_SGR
+ int64_t err = get_pixel_proj_error(
+ src8, width, height, src_stride, dat8, dat_stride, use_highbitdepth, flt1,
+ flt1_stride, flt2, flt2_stride, xqd, params);
+#else // CONFIG_SKIP_SGR
int64_t err = get_pixel_proj_error(src8, width, height, src_stride, dat8,
dat_stride, use_highbitdepth, flt1,
flt1_stride, flt2, flt2_stride, xqd);
+#endif // CONFIG_SKIP_SGR
(void)start_step;
#if USE_SGRPROJ_REFINEMENT_SEARCH
int64_t err2;
@@ -235,13 +267,23 @@
int tap_max[] = { SGRPROJ_PRJ_MAX0, SGRPROJ_PRJ_MAX1 };
for (int s = start_step; s >= 1; s >>= 1) {
for (int p = 0; p < 2; ++p) {
+#if CONFIG_SKIP_SGR
+ if ((params->r1 == 0 && p == 0) || (params->r2 == 0 && p == 1)) continue;
+#endif
int skip = 0;
do {
if (xqd[p] - s >= tap_min[p]) {
xqd[p] -= s;
+#if CONFIG_SKIP_SGR
+ err2 =
+ get_pixel_proj_error(src8, width, height, src_stride, dat8,
+ dat_stride, use_highbitdepth, flt1,
+ flt1_stride, flt2, flt2_stride, xqd, params);
+#else // CONFIG_SKIP_SGR
err2 = get_pixel_proj_error(src8, width, height, src_stride, dat8,
dat_stride, use_highbitdepth, flt1,
flt1_stride, flt2, flt2_stride, xqd);
+#endif // CONFIG_SKIP_SGR
if (err2 > err) {
xqd[p] += s;
} else {
@@ -257,9 +299,16 @@
do {
if (xqd[p] + s <= tap_max[p]) {
xqd[p] += s;
+#if CONFIG_SKIP_SGR
+ err2 =
+ get_pixel_proj_error(src8, width, height, src_stride, dat8,
+ dat_stride, use_highbitdepth, flt1,
+ flt1_stride, flt2, flt2_stride, xqd, params);
+#else // CONFIG_SKIP_SGR
err2 = get_pixel_proj_error(src8, width, height, src_stride, dat8,
dat_stride, use_highbitdepth, flt1,
flt1_stride, flt2, flt2_stride, xqd);
+#endif // CONFIG_SKIP_SGR
if (err2 > err) {
xqd[p] -= s;
} else {
@@ -280,7 +329,12 @@
int src_stride, const uint8_t *dat8,
int dat_stride, int use_highbitdepth,
int32_t *flt1, int flt1_stride, int32_t *flt2,
- int flt2_stride, int *xq) {
+ int flt2_stride, int *xq
+#if CONFIG_SKIP_SGR
+ ,
+ const sgr_params_type *params
+#endif // CONFIG_SKIP_SGR
+) {
int i, j;
double H[2][2] = { { 0, 0 }, { 0, 0 } };
double C[2] = { 0, 0 };
@@ -301,8 +355,15 @@
const double u = (double)(dat[i * dat_stride + j] << SGRPROJ_RST_BITS);
const double s =
(double)(src[i * src_stride + j] << SGRPROJ_RST_BITS) - u;
+#if CONFIG_SKIP_SGR
+ const double f1 =
+ (params->r1 > 0) ? (double)flt1[i * flt1_stride + j] - u : 0;
+ const double f2 =
+ (params->r2 > 0) ? (double)flt2[i * flt2_stride + j] - u : 0;
+#else // CONFIG_SKIP_SGR
const double f1 = (double)flt1[i * flt1_stride + j] - u;
const double f2 = (double)flt2[i * flt2_stride + j] - u;
+#endif // CONFIG_SKIP_SGR
H[0][0] += f1 * f1;
H[1][1] += f2 * f2;
H[0][1] += f1 * f2;
@@ -318,8 +379,15 @@
const double u = (double)(dat[i * dat_stride + j] << SGRPROJ_RST_BITS);
const double s =
(double)(src[i * src_stride + j] << SGRPROJ_RST_BITS) - u;
+#if CONFIG_SKIP_SGR
+ const double f1 =
+ (params->r1 > 0) ? (double)flt1[i * flt1_stride + j] - u : 0;
+ const double f2 =
+ (params->r2 > 0) ? (double)flt2[i * flt2_stride + j] - u : 0;
+#else // CONFIG_SKIP_SGR
const double f1 = (double)flt1[i * flt1_stride + j] - u;
const double f2 = (double)flt2[i * flt2_stride + j] - u;
+#endif // CONFIG_SKIP_SGR
H[0][0] += f1 * f1;
H[1][1] += f2 * f2;
H[0][1] += f1 * f2;
@@ -334,20 +402,69 @@
H[1][0] = H[0][1];
C[0] /= size;
C[1] /= size;
+#if CONFIG_SKIP_SGR
+ if (params->r1 == 0) {
+ // H matrix is now only the scalar H[1][1]
+ // C vector is now only the scalar C[1]
+ Det = H[1][1];
+ if (Det < 1e-8) return; // ill-posed, return default values
+ x[0] = 0;
+ x[1] = C[1] / Det;
+
+ xq[0] = 0;
+ xq[1] = (int)rint(x[1] * (1 << SGRPROJ_PRJ_BITS));
+ } else if (params->r2 == 0) {
+ // H matrix is now only the scalar H[0][0]
+ // C vector is now only the scalar C[0]
+ Det = H[0][0];
+ if (Det < 1e-8) return; // ill-posed, return default values
+ x[0] = C[0] / Det;
+ x[1] = 0;
+
+ xq[0] = (int)rint(x[0] * (1 << SGRPROJ_PRJ_BITS));
+ xq[1] = 0;
+ } else {
+ Det = (H[0][0] * H[1][1] - H[0][1] * H[1][0]);
+ if (Det < 1e-8) return; // ill-posed, return default values
+ x[0] = (H[1][1] * C[0] - H[0][1] * C[1]) / Det;
+ x[1] = (H[0][0] * C[1] - H[1][0] * C[0]) / Det;
+
+ xq[0] = (int)rint(x[0] * (1 << SGRPROJ_PRJ_BITS));
+ xq[1] = (int)rint(x[1] * (1 << SGRPROJ_PRJ_BITS));
+ }
+#else // CONFIG_SKIP_SGR
Det = (H[0][0] * H[1][1] - H[0][1] * H[1][0]);
if (Det < 1e-8) return; // ill-posed, return default values
x[0] = (H[1][1] * C[0] - H[0][1] * C[1]) / Det;
x[1] = (H[0][0] * C[1] - H[1][0] * C[0]) / Det;
xq[0] = (int)rint(x[0] * (1 << SGRPROJ_PRJ_BITS));
xq[1] = (int)rint(x[1] * (1 << SGRPROJ_PRJ_BITS));
+#endif // CONFIG_SKIP_SGR
}
+#if CONFIG_SKIP_SGR
+void encode_xq(int *xq, int *xqd, const sgr_params_type *params) {
+ if (params->r1 == 0) {
+ xqd[0] = 0;
+ xqd[1] = clamp((1 << SGRPROJ_PRJ_BITS) - xq[1], SGRPROJ_PRJ_MIN1,
+ SGRPROJ_PRJ_MAX1);
+ } else if (params->r2 == 0) {
+ xqd[0] = clamp(xq[0], SGRPROJ_PRJ_MIN0, SGRPROJ_PRJ_MAX0);
+ xqd[1] = 0;
+ } else {
+ xqd[0] = clamp(xq[0], SGRPROJ_PRJ_MIN0, SGRPROJ_PRJ_MAX0);
+ xqd[1] = clamp((1 << SGRPROJ_PRJ_BITS) - xqd[0] - xq[1], SGRPROJ_PRJ_MIN1,
+ SGRPROJ_PRJ_MAX1);
+ }
+}
+#else // CONFIG_SKIP_SGR
void encode_xq(int *xq, int *xqd) {
xqd[0] = xq[0];
xqd[0] = clamp(xqd[0], SGRPROJ_PRJ_MIN0, SGRPROJ_PRJ_MAX0);
xqd[1] = (1 << SGRPROJ_PRJ_BITS) - xqd[0] - xq[1];
xqd[1] = clamp(xqd[1], SGRPROJ_PRJ_MIN1, SGRPROJ_PRJ_MAX1);
}
+#endif // CONFIG_SKIP_SGR
// Apply the self-guided filter across an entire restoration unit.
static void apply_sgr(const sgr_params_type *params, const uint8_t *dat8,
@@ -386,19 +503,33 @@
pu_height == RESTORATION_PROC_UNIT_SIZE);
for (ep = 0; ep < SGRPROJ_PARAMS; ep++) {
+ const sgr_params_type *params = &sgr_params[ep];
int exq[2];
- apply_sgr(&sgr_params[ep], dat8, width, height, dat_stride,
- use_highbitdepth, bit_depth, pu_width, pu_height, flt1, flt2,
- flt_stride);
+
+ apply_sgr(params, dat8, width, height, dat_stride, use_highbitdepth,
+ bit_depth, pu_width, pu_height, flt1, flt2, flt_stride);
aom_clear_system_state();
+#if CONFIG_SKIP_SGR
+ get_proj_subspace(src8, width, height, src_stride, dat8, dat_stride,
+ use_highbitdepth, flt1, flt_stride, flt2, flt_stride, exq,
+ params);
+#else // CONFIG_SKIP_SGR
get_proj_subspace(src8, width, height, src_stride, dat8, dat_stride,
use_highbitdepth, flt1, flt_stride, flt2, flt_stride,
exq);
+#endif // CONFIG_SKIP_SGR
aom_clear_system_state();
+#if CONFIG_SKIP_SGR
+ encode_xq(exq, exqd, params);
+ int64_t err = finer_search_pixel_proj_error(
+ src8, width, height, src_stride, dat8, dat_stride, use_highbitdepth,
+ flt1, flt_stride, flt2, flt_stride, 2, exqd, params);
+#else // CONFIG_SKIP_SGR
encode_xq(exq, exqd);
int64_t err = finer_search_pixel_proj_error(
src8, width, height, src_stride, dat8, dat_stride, use_highbitdepth,
flt1, flt_stride, flt2, flt_stride, 2, exqd);
+#endif // CONFIG_SKIP_SGR
if (besterr == -1 || err < besterr) {
bestep = ep;
besterr = err;
@@ -417,6 +548,19 @@
static int count_sgrproj_bits(SgrprojInfo *sgrproj_info,
SgrprojInfo *ref_sgrproj_info) {
int bits = SGRPROJ_PARAMS_BITS;
+#if CONFIG_SKIP_SGR
+ const sgr_params_type *params = &sgr_params[sgrproj_info->ep];
+ if (params->r1 > 0)
+ bits += aom_count_primitive_refsubexpfin(
+ 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);
+ if (params->r2 > 0)
+ bits += aom_count_primitive_refsubexpfin(
+ 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 // CONFIG_SKIP_SGR
bits += aom_count_primitive_refsubexpfin(
SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K,
ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0,
@@ -425,6 +569,7 @@
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);
+#endif // CONFIG_SKIP_SGR
return bits;
}