Simpler threshold calculation for the second filter
PSNR YCbCr: 0.03% -0.00% 0.07%
PSNRHVS: 0.06%
SSIM: 0.12%
MSSSIM: 0.09%
CIEDE2000: 0.05%
Change-Id: I15ef9598a08f6713bc28ab98b0182310433e97ef
diff --git a/av1/common/od_dering.c b/av1/common/od_dering.c
index e7aee69..7ae8462 100644
--- a/av1/common/od_dering.c
+++ b/av1/common/od_dering.c
@@ -118,13 +118,13 @@
((OD_BSIZE_MAX + 2 * OD_FILT_BORDER) * (OD_BSIZE_MAX + 2 * OD_FILT_BORDER))
/* Smooth in the direction detected. */
-void od_filter_dering_direction_8x8_c(int16_t *y, int ystride,
- const int16_t *in, int threshold,
- int dir) {
+int od_filter_dering_direction_8x8_c(int16_t *y, int ystride, const int16_t *in,
+ int threshold, int dir) {
int i;
int j;
int k;
static const int taps[3] = { 3, 2, 1 };
+ int total_abs = 0;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
int16_t sum;
@@ -142,20 +142,23 @@
if (abs(p0) < threshold) sum += taps[k] * p0;
if (abs(p1) < threshold) sum += taps[k] * p1;
}
- yy = xx + ((sum + 8) >> 4);
+ sum = (sum + 8) >> 4;
+ total_abs += abs(sum);
+ yy = xx + sum;
y[i * ystride + j] = yy;
}
}
+ return (total_abs + 8) >> 4;
}
/* Smooth in the direction detected. */
-void od_filter_dering_direction_4x4_c(int16_t *y, int ystride,
- const int16_t *in, int threshold,
- int dir) {
+int od_filter_dering_direction_4x4_c(int16_t *y, int ystride, const int16_t *in,
+ int threshold, int dir) {
int i;
int j;
int k;
static const int taps[2] = { 4, 1 };
+ int total_abs = 0;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
int16_t sum;
@@ -173,16 +176,19 @@
if (abs(p0) < threshold) sum += taps[k] * p0;
if (abs(p1) < threshold) sum += taps[k] * p1;
}
- yy = xx + ((sum + 8) >> 4);
+ sum = (sum + 8) >> 4;
+ total_abs += abs(sum);
+ yy = xx + sum;
y[i * ystride + j] = yy;
}
}
+ return (total_abs + 2) >> 2;
}
/* Smooth in the direction orthogonal to what was detected. */
void od_filter_dering_orthogonal_8x8_c(int16_t *y, int ystride,
- const int16_t *in, const od_dering_in *x,
- int xstride, int threshold, int dir) {
+ const int16_t *in, int threshold,
+ int dir) {
int i;
int j;
int offset;
@@ -192,31 +198,19 @@
offset = 1;
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
- int16_t athresh;
int16_t yy;
int16_t sum;
int16_t p;
- /* Deringing orthogonal to the direction uses a tighter threshold
- because we want to be conservative. We've presumably already
- achieved some deringing, so the amount of change is expected
- to be low. Also, since we might be filtering across an edge, we
- want to make sure not to blur it. That being said, we might want
- to be a little bit more aggressive on pure horizontal/vertical
- since the ringing there tends to be directional, so it doesn't
- get removed by the directional filtering. */
- athresh = OD_MINI(
- threshold, threshold / 3 +
- abs(in[i * OD_FILT_BSTRIDE + j] - x[i * xstride + j]));
yy = in[i * OD_FILT_BSTRIDE + j];
sum = 0;
p = in[i * OD_FILT_BSTRIDE + j + offset] - yy;
- if (abs(p) < athresh) sum += p;
+ if (abs(p) < threshold) sum += p;
p = in[i * OD_FILT_BSTRIDE + j - offset] - yy;
- if (abs(p) < athresh) sum += p;
+ if (abs(p) < threshold) sum += p;
p = in[i * OD_FILT_BSTRIDE + j + 2 * offset] - yy;
- if (abs(p) < athresh) sum += p;
+ if (abs(p) < threshold) sum += p;
p = in[i * OD_FILT_BSTRIDE + j - 2 * offset] - yy;
- if (abs(p) < athresh) sum += p;
+ if (abs(p) < threshold) sum += p;
y[i * ystride + j] = yy + ((3 * sum + 8) >> 4);
}
}
@@ -224,8 +218,8 @@
/* Smooth in the direction orthogonal to what was detected. */
void od_filter_dering_orthogonal_4x4_c(int16_t *y, int ystride,
- const int16_t *in, const od_dering_in *x,
- int xstride, int threshold, int dir) {
+ const int16_t *in, int threshold,
+ int dir) {
int i;
int j;
int offset;
@@ -235,27 +229,15 @@
offset = 1;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
- int16_t athresh;
int16_t yy;
int16_t sum;
int16_t p;
- /* Deringing orthogonal to the direction uses a tighter threshold
- because we want to be conservative. We've presumably already
- achieved some deringing, so the amount of change is expected
- to be low. Also, since we might be filtering across an edge, we
- want to make sure not to blur it. That being said, we might want
- to be a little bit more aggressive on pure horizontal/vertical
- since the ringing there tends to be directional, so it doesn't
- get removed by the directional filtering. */
- athresh = OD_MINI(
- threshold, threshold / 3 +
- abs(in[i * OD_FILT_BSTRIDE + j] - x[i * xstride + j]));
yy = in[i * OD_FILT_BSTRIDE + j];
sum = 0;
p = in[i * OD_FILT_BSTRIDE + j + offset] - yy;
- if (abs(p) < athresh) sum += p;
+ if (abs(p) < threshold) sum += p;
p = in[i * OD_FILT_BSTRIDE + j - offset] - yy;
- if (abs(p) < athresh) sum += p;
+ if (abs(p) < threshold) sum += p;
y[i * ystride + j] = yy + ((5 * sum + 8) >> 4);
}
}
@@ -306,6 +288,7 @@
int bsize;
int32_t var[OD_DERING_NBLOCKS][OD_DERING_NBLOCKS];
int thresh[OD_DERING_NBLOCKS][OD_DERING_NBLOCKS];
+ int thresh2[OD_DERING_NBLOCKS][OD_DERING_NBLOCKS];
bsize = 3 - xdec;
in = inbuf + OD_FILT_BORDER * OD_FILT_BSTRIDE + OD_FILT_BORDER;
/* We avoid filtering the pixels for which some of the pixels to average
@@ -349,7 +332,15 @@
for (by = 0; by < nvb; by++) {
for (bx = 0; bx < nhb; bx++) {
if (thresh[by][bx] == 0) continue;
- (vtbl->filter_dering_direction[bsize - OD_LOG_BSIZE0])(
+ /* Deringing orthogonal to the direction uses a tighter threshold
+ because we want to be conservative. We've presumably already
+ achieved some deringing, so the amount of change is expected
+ to be low. Also, since we might be filtering across an edge, we
+ want to make sure not to blur it. That being said, we might want
+ to be a little bit more aggressive on pure horizontal/vertical
+ since the ringing there tends to be directional, so it doesn't
+ get removed by the directional filtering. */
+ thresh2[by][bx] = (vtbl->filter_dering_direction[bsize - OD_LOG_BSIZE0])(
&y[(by * ystride << bsize) + (bx << bsize)], ystride,
&in[(by * OD_FILT_BSTRIDE << bsize) + (bx << bsize)], thresh[by][bx],
dir[by][bx]);
@@ -365,8 +356,7 @@
if (thresh[by][bx] == 0) continue;
(vtbl->filter_dering_orthogonal[bsize - OD_LOG_BSIZE0])(
&y[(by * ystride << bsize) + (bx << bsize)], ystride,
- &in[(by * OD_FILT_BSTRIDE << bsize) + (bx << bsize)],
- &x[(by * xstride << bsize) + (bx << bsize)], xstride, thresh[by][bx],
+ &in[(by * OD_FILT_BSTRIDE << bsize) + (bx << bsize)], thresh2[by][bx],
dir[by][bx]);
}
}
diff --git a/av1/common/od_dering.h b/av1/common/od_dering.h
index 935ccac..b86fc6a 100644
--- a/av1/common/od_dering.h
+++ b/av1/common/od_dering.h
@@ -28,14 +28,12 @@
extern const int OD_DIRECTION_OFFSETS_TABLE[8][3];
-typedef void (*od_filter_dering_direction_func)(int16_t *y, int ystride,
- const int16_t *in,
- int threshold, int dir);
+typedef int (*od_filter_dering_direction_func)(int16_t *y, int ystride,
+ const int16_t *in, int threshold,
+ int dir);
typedef void (*od_filter_dering_orthogonal_func)(int16_t *y, int ystride,
const int16_t *in,
- const od_dering_in *x,
- int xstride, int threshold,
- int dir);
+ int threshold, int dir);
struct od_dering_opt_vtbl {
od_filter_dering_direction_func filter_dering_direction[OD_DERINGSIZES];
@@ -57,17 +55,15 @@
extern const od_dering_opt_vtbl OD_DERING_VTBL_C;
-void od_filter_dering_direction_4x4_c(int16_t *y, int ystride,
- const int16_t *in, int threshold,
- int dir);
-void od_filter_dering_direction_8x8_c(int16_t *y, int ystride,
- const int16_t *in, int threshold,
- int dir);
+int od_filter_dering_direction_4x4_c(int16_t *y, int ystride, const int16_t *in,
+ int threshold, int dir);
+int od_filter_dering_direction_8x8_c(int16_t *y, int ystride, const int16_t *in,
+ int threshold, int dir);
void od_filter_dering_orthogonal_4x4_c(int16_t *y, int ystride,
- const int16_t *in, const od_dering_in *x,
- int xstride, int threshold, int dir);
+ const int16_t *in, int threshold,
+ int dir);
void od_filter_dering_orthogonal_8x8_c(int16_t *y, int ystride,
- const int16_t *in, const od_dering_in *x,
- int xstride, int threshold, int dir);
+ const int16_t *in, int threshold,
+ int dir);
#endif