blob: 726a4c10ffb0c817073e30d4d29a7ce69e6e14b1 [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>
13
Yaowu Xuf883b422016-08-30 14:01:10 -070014#include "./aom_scale_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070015#include "av1/common/dering.h"
16#include "av1/common/onyxc_int.h"
17#include "av1/common/reconinter.h"
18#include "av1/encoder/encoder.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070019#include "aom/aom_integer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070020
21static double compute_dist(int16_t *x, int xstride, int16_t *y, int ystride,
22 int nhb, int nvb, int coeff_shift) {
23 int i, j;
24 double sum;
25 sum = 0;
26 for (i = 0; i < nvb << 3; i++) {
27 for (j = 0; j < nhb << 3; j++) {
28 double tmp;
29 tmp = x[i * xstride + j] - y[i * ystride + j];
30 sum += tmp * tmp;
31 }
32 }
33 return sum / (double)(1 << 2 * coeff_shift);
34}
35
Yaowu Xuf883b422016-08-30 14:01:10 -070036int av1_dering_search(YV12_BUFFER_CONFIG *frame, const YV12_BUFFER_CONFIG *ref,
37 AV1_COMMON *cm, MACROBLOCKD *xd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070038 int r, c;
39 int sbr, sbc;
40 int nhsb, nvsb;
41 od_dering_in *src;
42 int16_t *ref_coeff;
43 unsigned char *bskip;
44 int dir[OD_DERING_NBLOCKS][OD_DERING_NBLOCKS] = { { 0 } };
45 int stride;
46 int bsize[3];
47 int dec[3];
48 int pli;
49 int(*mse)[MAX_DERING_LEVEL];
Yaowu Xuc27fc142016-08-22 16:08:15 -070050 double tot_mse[MAX_DERING_LEVEL] = { 0 };
51 int level;
52 int best_level;
53 int global_level;
54 double best_tot_mse = 1e15;
Yaowu Xuf883b422016-08-30 14:01:10 -070055 int coeff_shift = AOMMAX(cm->bit_depth - 8, 0);
56 src = aom_malloc(sizeof(*src) * cm->mi_rows * cm->mi_cols * 64);
57 ref_coeff = aom_malloc(sizeof(*ref_coeff) * cm->mi_rows * cm->mi_cols * 64);
58 bskip = aom_malloc(sizeof(*bskip) * cm->mi_rows * cm->mi_cols);
59 av1_setup_dst_planes(xd->plane, frame, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -070060 for (pli = 0; pli < 3; pli++) {
61 dec[pli] = xd->plane[pli].subsampling_x;
62 bsize[pli] = 8 >> dec[pli];
63 }
64 stride = bsize[0] * cm->mi_cols;
65 for (r = 0; r < bsize[0] * cm->mi_rows; ++r) {
66 for (c = 0; c < bsize[0] * cm->mi_cols; ++c) {
Yaowu Xuf883b422016-08-30 14:01:10 -070067#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070068 if (cm->use_highbitdepth) {
69 src[r * stride + c] = CONVERT_TO_SHORTPTR(
70 xd->plane[0].dst.buf)[r * xd->plane[0].dst.stride + c];
71 ref_coeff[r * stride + c] =
72 CONVERT_TO_SHORTPTR(ref->y_buffer)[r * ref->y_stride + c];
73 } else {
74#endif
75 src[r * stride + c] =
76 xd->plane[0].dst.buf[r * xd->plane[0].dst.stride + c];
77 ref_coeff[r * stride + c] = ref->y_buffer[r * ref->y_stride + c];
Yaowu Xuf883b422016-08-30 14:01:10 -070078#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070079 }
80#endif
81 }
82 }
83 for (r = 0; r < cm->mi_rows; ++r) {
84 for (c = 0; c < cm->mi_cols; ++c) {
85 const MB_MODE_INFO *mbmi =
86 &cm->mi_grid_visible[r * cm->mi_stride + c]->mbmi;
87 bskip[r * cm->mi_cols + c] = mbmi->skip;
88 }
89 }
90 nvsb = (cm->mi_rows + MAX_MIB_SIZE - 1) / MAX_MIB_SIZE;
91 nhsb = (cm->mi_cols + MAX_MIB_SIZE - 1) / MAX_MIB_SIZE;
Yaowu Xuf883b422016-08-30 14:01:10 -070092 mse = aom_malloc(nvsb * nhsb * sizeof(*mse));
Yaowu Xuc27fc142016-08-22 16:08:15 -070093 for (sbr = 0; sbr < nvsb; sbr++) {
94 for (sbc = 0; sbc < nhsb; sbc++) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070095 int nvb, nhb;
96 int16_t dst[MAX_MIB_SIZE * MAX_MIB_SIZE * 8 * 8];
Yaowu Xuf883b422016-08-30 14:01:10 -070097 nhb = AOMMIN(MAX_MIB_SIZE, cm->mi_cols - MAX_MIB_SIZE * sbc);
98 nvb = AOMMIN(MAX_MIB_SIZE, cm->mi_rows - MAX_MIB_SIZE * sbr);
Yaowu Xuc27fc142016-08-22 16:08:15 -070099 for (level = 0; level < 64; level++) {
Yaowu Xu9c323bc2016-09-01 11:35:16 -0700100 int cur_mse;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700101 int threshold;
102 threshold = level << coeff_shift;
103 od_dering(
104 &OD_DERING_VTBL_C, dst, MAX_MIB_SIZE * bsize[0],
105 &src[sbr * stride * bsize[0] * MAX_MIB_SIZE +
106 sbc * bsize[0] * MAX_MIB_SIZE],
107 cm->mi_cols * bsize[0], nhb, nvb, sbc, sbr, nhsb, nvsb, 0, dir, 0,
108 &bskip[MAX_MIB_SIZE * sbr * cm->mi_cols + MAX_MIB_SIZE * sbc],
109 cm->mi_cols, threshold, OD_DERING_NO_CHECK_OVERLAP, coeff_shift);
Yaowu Xu9c323bc2016-09-01 11:35:16 -0700110 cur_mse = (int)compute_dist(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700111 dst, MAX_MIB_SIZE * bsize[0],
112 &ref_coeff[sbr * stride * bsize[0] * MAX_MIB_SIZE +
113 sbc * bsize[0] * MAX_MIB_SIZE],
114 stride, nhb, nvb, coeff_shift);
Yaowu Xu9c323bc2016-09-01 11:35:16 -0700115 mse[nhsb * sbr + sbc][level] = cur_mse;
116 tot_mse[level] += cur_mse;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700117 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700118 }
119 }
120#if DERING_REFINEMENT
121 best_level = 0;
122 /* Search for the best global level one value at a time. */
123 for (global_level = 2; global_level < MAX_DERING_LEVEL; global_level++) {
124 double tot_mse = 0;
125 for (sbr = 0; sbr < nvsb; sbr++) {
126 for (sbc = 0; sbc < nhsb; sbc++) {
127 int gi;
128 int best_mse = mse[nhsb * sbr + sbc][0];
129 for (gi = 1; gi < 4; gi++) {
130 level = compute_level_from_index(global_level, gi);
131 if (mse[nhsb * sbr + sbc][level] < best_mse) {
132 best_mse = mse[nhsb * sbr + sbc][level];
133 }
134 }
135 tot_mse += best_mse;
136 }
137 }
138 if (tot_mse < best_tot_mse) {
139 best_level = global_level;
140 best_tot_mse = tot_mse;
141 }
142 }
143 for (sbr = 0; sbr < nvsb; sbr++) {
144 for (sbc = 0; sbc < nhsb; sbc++) {
145 int gi;
146 int best_gi;
147 int best_mse = mse[nhsb * sbr + sbc][0];
148 best_gi = 0;
149 for (gi = 1; gi < DERING_REFINEMENT_LEVELS; gi++) {
150 level = compute_level_from_index(best_level, gi);
151 if (mse[nhsb * sbr + sbc][level] < best_mse) {
152 best_gi = gi;
153 best_mse = mse[nhsb * sbr + sbc][level];
154 }
155 }
156 cm->mi_grid_visible[MAX_MIB_SIZE * sbr * cm->mi_stride +
157 MAX_MIB_SIZE * sbc]
158 ->mbmi.dering_gain = best_gi;
159 }
160 }
161#else
162 best_level = 0;
163 for (level = 0; level < MAX_DERING_LEVEL; level++) {
164 if (tot_mse[level] < tot_mse[best_level]) best_level = level;
165 }
166#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700167 aom_free(src);
168 aom_free(ref_coeff);
169 aom_free(bskip);
170 aom_free(mse);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700171 return best_level;
172}