CDEF encode buffering optimizations Change-Id: I6b178d5ebf353bca98f18d8add2aa8b77e03cc4f
diff --git a/av1/encoder/pickcdef.c b/av1/encoder/pickcdef.c index 1655a65..337b922 100644 --- a/av1/encoder/pickcdef.c +++ b/av1/encoder/pickcdef.c
@@ -92,6 +92,19 @@ 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, + int vsize, int hsize) { + int r, c; + const uint16_t *base = &src[src_voffset * sstride + src_hoffset]; + for (r = 0; r < vsize; r++) { + for (c = 0; c < hsize; c++) { + dst[r * dstride + c] = base[r * sstride + c]; + } + } +} + void av1_cdef_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref, AV1_COMMON *cm, MACROBLOCKD *xd) { int r, c; @@ -181,7 +194,8 @@ int nvb, nhb; int gi; int dirinit = 0; - DECLARE_ALIGNED(32, uint16_t, dst[MAX_MIB_SIZE * MAX_MIB_SIZE * 8 * 8]); + DECLARE_ALIGNED(32, uint16_t, + dst[3][MAX_MIB_SIZE * MAX_MIB_SIZE * 8 * 8]); DECLARE_ALIGNED(32, uint16_t, tmp_dst[MAX_MIB_SIZE * MAX_MIB_SIZE * 8 * 8]); nhb = AOMMIN(MAX_MIB_SIZE, cm->mi_cols - MAX_MIB_SIZE * sbc); @@ -189,24 +203,23 @@ dering_count = sb_compute_dering_list(cm, sbr * MAX_MIB_SIZE, 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[pli], 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 (gi = 0; gi < TOTAL_STRENGTHS; gi++) { int threshold; int clpf_strength; DECLARE_ALIGNED(32, uint16_t, inbuf[OD_DERING_INBUF_SIZE]); uint16_t *in; - int j; level = dering_level_table[gi / CLPF_STRENGTHS]; threshold = level << coeff_shift; for (pli = 0; pli < nplanes; pli++) { if (pli > 0 && !chroma_dering) threshold = 0; - for (r = 0; r < nvb << bsize[pli]; r++) { - for (c = 0; c < nhb << bsize[pli]; c++) { - dst[(r * MAX_MIB_SIZE << bsize[pli]) + c] = - src[pli] - [((sbr * MAX_MIB_SIZE << bsize[pli]) + r) * stride[pli] + - (sbc * MAX_MIB_SIZE << bsize[pli]) + c]; - } - } in = inbuf + OD_FILT_VBORDER * OD_FILT_BSTRIDE + OD_FILT_HBORDER; /* We avoid filtering the pixels for which some of the pixels to average @@ -214,27 +227,25 @@ would add special cases for any future vectorization. */ for (i = 0; i < OD_DERING_INBUF_SIZE; i++) inbuf[i] = OD_DERING_VERY_LARGE; - for (i = -OD_FILT_VBORDER * (sbr != 0); - i < (nvb << bsize[pli]) + OD_FILT_VBORDER * (sbr != nvsb - 1); - i++) { - for (j = -OD_FILT_HBORDER * (sbc != 0); - j < (nhb << bsize[pli]) + OD_FILT_HBORDER * (sbc != nhsb - 1); - j++) { - uint16_t *x; - x = &src[pli][(sbr * stride[pli] * MAX_MIB_SIZE << bsize[pli]) + - (sbc * MAX_MIB_SIZE << bsize[pli])]; - in[i * OD_FILT_BSTRIDE + j] = x[i * stride[pli] + j]; - } - } + int yoff = OD_FILT_VBORDER * (sbr != 0); + int xoff = OD_FILT_HBORDER * (sbc != 0); + int ysize = + (nvb << bsize[pli]) + OD_FILT_VBORDER * (sbr != nvsb - 1) + yoff; + int xsize = + (nhb << bsize[pli]) + OD_FILT_HBORDER * (sbc != nhsb - 1) + xoff; + copy_sb16_16(&in[(-yoff * OD_FILT_BSTRIDE - xoff)], OD_FILT_BSTRIDE, + src[pli], (sbr * MAX_MIB_SIZE << bsize[pli]) - yoff, + (sbc * MAX_MIB_SIZE << bsize[pli]) - xoff, stride[pli], + ysize, xsize); clpf_strength = gi % CLPF_STRENGTHS; od_dering(tmp_dst, in, dec[pli], dir, &dirinit, var, pli, dlist, 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]); + copy_dering_16bit_to_16bit(dst[pli], 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], + dst[pli], 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]);