CDEF: computing MSE only on the filtered blocks Change-Id: I16881cd6267922a3e156defb90577d6ad2b46d5b
diff --git a/av1/encoder/pickcdef.c b/av1/encoder/pickcdef.c index 72e4ada..9a9813c 100644 --- a/av1/encoder/pickcdef.c +++ b/av1/encoder/pickcdef.c
@@ -77,21 +77,6 @@ return best_tot_mse; } -static double compute_dist(uint16_t *x, int xstride, uint16_t *y, int ystride, - int nhb, int nvb, int coeff_shift, int bsize) { - int i, j; - double sum; - sum = 0; - for (i = 0; i < nvb << bsize; i++) { - for (j = 0; j < nhb << bsize; j++) { - double tmp; - tmp = x[i * xstride + j] - y[i * ystride + j]; - sum += tmp * tmp; - } - } - return sum / (double)(1 << 2 * coeff_shift); -} - /* FIXME: SSE-optimize this. */ static void copy_sb16_16(uint16_t *dst, int dstride, const uint16_t *src, int src_voffset, int src_hoffset, int sstride, @@ -105,6 +90,56 @@ } } +static INLINE uint64_t mse_8x8_16bit(uint16_t *dst, int dstride, uint16_t *src, + int sstride) { + uint64_t sum = 0; + int i, j; + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + int e = dst[i * dstride + j] - src[i * sstride + j]; + sum += e * e; + } + } + return sum; +} + +static INLINE uint64_t mse_4x4_16bit(uint16_t *dst, int dstride, uint16_t *src, + int sstride) { + uint64_t sum = 0; + int i, j; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + int e = dst[i * dstride + j] - src[i * sstride + j]; + sum += e * e; + } + } + return sum; +} + +/* Compute MSE only on the blocks we filtered. */ +uint64_t compute_dering_mse(uint16_t *dst, int dstride, uint16_t *src, + dering_list *dlist, int dering_count, int bsize, + int coeff_shift) { + uint64_t sum = 0; + int bi, bx, by; + if (bsize == 3) { + for (bi = 0; bi < dering_count; bi++) { + by = dlist[bi].by; + bx = dlist[bi].bx; + sum += mse_8x8_16bit(&dst[(by << 3) * dstride + (bx << 3)], dstride, + &src[bi << 2 * bsize], 1 << bsize); + } + } else { + for (bi = 0; bi < dering_count; bi++) { + by = dlist[bi].by; + bx = dlist[bi].bx; + sum += mse_4x4_16bit(&dst[(by << 2) * dstride + (bx << 2)], dstride, + &src[bi << 2 * bsize], 1 << bsize); + } + } + return sum >> 2 * coeff_shift; +} + void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref, AV1_COMMON *cm, MACROBLOCKD *xd) { int r, c; @@ -139,7 +174,6 @@ int nplanes = 3; DECLARE_ALIGNED(32, uint16_t, inbuf[OD_DERING_INBUF_SIZE]); uint16_t *in; - DECLARE_ALIGNED(32, uint16_t, dst[MAX_MIB_SIZE * MAX_MIB_SIZE * 8 * 8]); DECLARE_ALIGNED(32, uint16_t, tmp_dst[MAX_MIB_SIZE * MAX_MIB_SIZE * 8 * 8]); int chroma_dering = xd->plane[1].subsampling_x == xd->plane[1].subsampling_y && @@ -205,12 +239,6 @@ sbc * MAX_MIB_SIZE, dlist); if (dering_count == 0) continue; for (pli = 0; pli < nplanes; pli++) { - /* Copy the dst buffer only once since it will always be written at - the same place. */ - copy_sb16_16(dst, MAX_MIB_SIZE << bsize[pli], src[pli], - sbr * MAX_MIB_SIZE << bsize[pli], - sbc * MAX_MIB_SIZE << bsize[pli], stride[pli], - nvb << bsize[pli], nhb << bsize[pli]); for (i = 0; i < OD_DERING_INBUF_SIZE; i++) inbuf[i] = OD_DERING_VERY_LARGE; for (gi = 0; gi < TOTAL_STRENGTHS; gi++) { @@ -238,13 +266,12 @@ dering_count, threshold, clpf_strength + (clpf_strength == 3), clpf_damping, coeff_shift); - copy_dering_16bit_to_16bit(dst, MAX_MIB_SIZE << bsize[pli], tmp_dst, - dlist, dering_count, bsize[pli]); - mse[pli][sb_count][gi] = (int)compute_dist( - dst, MAX_MIB_SIZE << bsize[pli], - &ref_coeff[pli][(sbr * stride[pli] * MAX_MIB_SIZE << bsize[pli]) + - (sbc * MAX_MIB_SIZE << bsize[pli])], - stride[pli], nhb, nvb, coeff_shift, bsize[pli]); + mse[pli][sb_count][gi] = compute_dering_mse( + ref_coeff[pli] + + (sbr * MAX_MIB_SIZE << bsize[pli]) * stride[pli] + + (sbc * MAX_MIB_SIZE << bsize[pli]), + stride[pli], tmp_dst, dlist, dering_count, bsize[pli], + coeff_shift); sb_index[sb_count] = MAX_MIB_SIZE * sbr * cm->mi_stride + MAX_MIB_SIZE * sbc; }