blob: dce76863231a88c0c9b243e02d3d24ff49976b5b [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <string.h>
Jean-Marc Valin6d5a7a92016-08-22 15:47:09 -040013#include <math.h>
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "./aom_scale_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070016#include "av1/common/dering.h"
17#include "av1/common/onyxc_int.h"
18#include "av1/common/reconinter.h"
19#include "av1/encoder/encoder.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom/aom_integer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021
22static double compute_dist(int16_t *x, int xstride, int16_t *y, int ystride,
23 int nhb, int nvb, int coeff_shift) {
24 int i, j;
25 double sum;
26 sum = 0;
27 for (i = 0; i < nvb << 3; i++) {
28 for (j = 0; j < nhb << 3; j++) {
29 double tmp;
30 tmp = x[i * xstride + j] - y[i * ystride + j];
31 sum += tmp * tmp;
32 }
33 }
34 return sum / (double)(1 << 2 * coeff_shift);
35}
36
Yaowu Xuf883b422016-08-30 14:01:10 -070037int av1_dering_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
38 AV1_COMMON *cm, MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070039 int r, c;
40 int sbr, sbc;
41 int nhsb, nvsb;
Jean-Marc Valin39ee1092016-10-25 19:30:49 -040042 int16_t *src;
Yaowu Xuc27fc142016-08-22 16:08:15 -070043 int16_t *ref_coeff;
Jean-Marc Valin39d92a02016-11-02 02:33:46 -040044 dering_list dlist[MAX_MIB_SIZE * MAX_MIB_SIZE];
Yaowu Xuc27fc142016-08-22 16:08:15 -070045 int dir[OD_DERING_NBLOCKS][OD_DERING_NBLOCKS] = { { 0 } };
46 int stride;
47 int bsize[3];
48 int dec[3];
49 int pli;
Yaowu Xuc27fc142016-08-22 16:08:15 -070050 int level;
51 int best_level;
Jean-Marc Valin3e44bcc2016-10-11 16:53:59 -040052 int dering_count;
Yaowu Xuf883b422016-08-30 14:01:10 -070053 int coeff_shift = AOMMAX(cm->bit_depth - 8, 0);
54 src = aom_malloc(sizeof(*src) * cm->mi_rows * cm->mi_cols * 64);
55 ref_coeff = aom_malloc(sizeof(*ref_coeff) * cm->mi_rows * cm->mi_cols * 64);
Yaowu Xuf883b422016-08-30 14:01:10 -070056 av1_setup_dst_planes(xd->plane, frame, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070057 for (pli = 0; pli < 3; pli++) {
58 dec[pli] = xd->plane[pli].subsampling_x;
Jean-Marc Valine2542412016-10-26 01:26:25 -040059 bsize[pli] = OD_DERING_SIZE_LOG2 - dec[pli];
Yaowu Xuc27fc142016-08-22 16:08:15 -070060 }
Jean-Marc Valin8e941782016-10-13 14:44:22 -040061 stride = cm->mi_cols << bsize[0];
62 for (r = 0; r < cm->mi_rows << bsize[0]; ++r) {
63 for (c = 0; c < cm->mi_cols << bsize[0]; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -070064#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070065 if (cm->use_highbitdepth) {
66 src[r * stride + c] = CONVERT_TO_SHORTPTR(
67 xd->plane[0].dst.buf)[r * xd->plane[0].dst.stride + c];
68 ref_coeff[r * stride + c] =
69 CONVERT_TO_SHORTPTR(ref->y_buffer)[r * ref->y_stride + c];
70 } else {
71#endif
72 src[r * stride + c] =
73 xd->plane[0].dst.buf[r * xd->plane[0].dst.stride + c];
74 ref_coeff[r * stride + c] = ref->y_buffer[r * ref->y_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -070075#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070076 }
77#endif
78 }
79 }
Yaowu Xuc27fc142016-08-22 16:08:15 -070080 nvsb = (cm->mi_rows + MAX_MIB_SIZE - 1) / MAX_MIB_SIZE;
81 nhsb = (cm->mi_cols + MAX_MIB_SIZE - 1) / MAX_MIB_SIZE;
Jean-Marc Valin6d5a7a92016-08-22 15:47:09 -040082 /* Pick a base threshold based on the quantizer. The threshold will then be
83 adjusted on a 64x64 basis. We use a threshold of the form T = a*Q^b,
84 where a and b are derived empirically trying to optimize rate-distortion
85 at different quantizer settings. */
Jean-Marc Valin209f8302016-10-08 14:10:39 -040086 best_level = AOMMIN(
87 MAX_DERING_LEVEL - 1,
88 (int)floor(.5 +
89 .45 * pow(av1_ac_quant(cm->base_qindex, 0, cm->bit_depth) >>
90 (cm->bit_depth - 8),
91 0.6)));
Yaowu Xuc27fc142016-08-22 16:08:15 -070092 for (sbr = 0; sbr < nvsb; sbr++) {
93 for (sbc = 0; sbc < nhsb; sbc++) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070094 int nvb, nhb;
Jean-Marc Valin6d5a7a92016-08-22 15:47:09 -040095 int gi;
96 int best_gi;
97 int32_t best_mse = INT32_MAX;
Yaowu Xuc27fc142016-08-22 16:08:15 -070098 int16_t dst[MAX_MIB_SIZE * MAX_MIB_SIZE * 8 * 8];
Jean-Marc Valin82c65fc2016-10-12 18:09:48 -040099 int16_t tmp_dst[MAX_MIB_SIZE * MAX_MIB_SIZE * 8 * 8];
Yaowu Xuf883b422016-08-30 14:01:10 -0700100 nhb = AOMMIN(MAX_MIB_SIZE, cm->mi_cols - MAX_MIB_SIZE * sbc);
101 nvb = AOMMIN(MAX_MIB_SIZE, cm->mi_rows - MAX_MIB_SIZE * sbr);
Jean-Marc Valin39d92a02016-11-02 02:33:46 -0400102 dering_count = sb_compute_dering_list(cm, sbr * MAX_MIB_SIZE,
103 sbc * MAX_MIB_SIZE, dlist);
104 if (dering_count == 0) continue;
Jean-Marc Valin6d5a7a92016-08-22 15:47:09 -0400105 best_gi = 0;
106 for (gi = 0; gi < DERING_REFINEMENT_LEVELS; gi++) {
Yaowu Xu9c323bc2016-09-01 11:35:16 -0700107 int cur_mse;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700108 int threshold;
Jean-Marc Valinca1eb5d2016-10-13 15:24:39 -0400109 int16_t inbuf[OD_DERING_INBUF_SIZE];
110 int16_t *in;
111 int i, j;
Jean-Marc Valin6d5a7a92016-08-22 15:47:09 -0400112 level = compute_level_from_index(best_level, gi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700113 threshold = level << coeff_shift;
Jean-Marc Valin8e941782016-10-13 14:44:22 -0400114 for (r = 0; r < nvb << bsize[0]; r++) {
115 for (c = 0; c < nhb << bsize[0]; c++) {
116 dst[(r * MAX_MIB_SIZE << bsize[0]) + c] =
117 src[((sbr * MAX_MIB_SIZE << bsize[0]) + r) * stride +
118 (sbc * MAX_MIB_SIZE << bsize[0]) + c];
Jean-Marc Valinbcf35802016-10-12 17:39:54 -0400119 }
120 }
Jean-Marc Valinca1eb5d2016-10-13 15:24:39 -0400121 in = inbuf + OD_FILT_VBORDER * OD_FILT_BSTRIDE + OD_FILT_HBORDER;
122 /* We avoid filtering the pixels for which some of the pixels to average
Jean-Marc Valin39d92a02016-11-02 02:33:46 -0400123 are outside the frame. We could change the filter instead, but it
124 would
Jean-Marc Valinca1eb5d2016-10-13 15:24:39 -0400125 add special cases for any future vectorization. */
Jean-Marc Valin39d92a02016-11-02 02:33:46 -0400126 for (i = 0; i < OD_DERING_INBUF_SIZE; i++)
127 inbuf[i] = OD_DERING_VERY_LARGE;
Jean-Marc Valinca1eb5d2016-10-13 15:24:39 -0400128 for (i = -OD_FILT_VBORDER * (sbr != 0);
129 i < (nvb << bsize[0]) + OD_FILT_VBORDER * (sbr != nvsb - 1); i++) {
130 for (j = -OD_FILT_HBORDER * (sbc != 0);
Jean-Marc Valin39d92a02016-11-02 02:33:46 -0400131 j < (nhb << bsize[0]) + OD_FILT_HBORDER * (sbc != nhsb - 1);
132 j++) {
Jean-Marc Valinca1eb5d2016-10-13 15:24:39 -0400133 int16_t *x;
134 x = &src[(sbr * stride * MAX_MIB_SIZE << bsize[0]) +
135 (sbc * MAX_MIB_SIZE << bsize[0])];
136 in[i * OD_FILT_BSTRIDE + j] = x[i * stride + j];
137 }
138 }
Jean-Marc Valine0465032016-10-18 15:56:37 -0400139 od_dering(tmp_dst, in, 0, dir, 0, dlist, dering_count, threshold,
Jean-Marc Valin39d92a02016-11-02 02:33:46 -0400140 coeff_shift);
141 copy_dering_16bit_to_16bit(dst, MAX_MIB_SIZE << bsize[0], tmp_dst,
142 dlist, dering_count, bsize[0]);
Yaowu Xu9c323bc2016-09-01 11:35:16 -0700143 cur_mse = (int)compute_dist(
Jean-Marc Valin8e941782016-10-13 14:44:22 -0400144 dst, MAX_MIB_SIZE << bsize[0],
145 &ref_coeff[(sbr * stride * MAX_MIB_SIZE << bsize[0]) +
146 (sbc * MAX_MIB_SIZE << bsize[0])],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700147 stride, nhb, nvb, coeff_shift);
Jean-Marc Valin6d5a7a92016-08-22 15:47:09 -0400148 if (cur_mse < best_mse) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700149 best_gi = gi;
Jean-Marc Valin6d5a7a92016-08-22 15:47:09 -0400150 best_mse = cur_mse;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700151 }
152 }
153 cm->mi_grid_visible[MAX_MIB_SIZE * sbr * cm->mi_stride +
154 MAX_MIB_SIZE * sbc]
155 ->mbmi.dering_gain = best_gi;
156 }
157 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700158 aom_free(src);
159 aom_free(ref_coeff);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700160 return best_level;
161}