Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | bde4ac8 | 2016-11-28 15:26:06 -0800 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | bde4ac8 | 2016-11-28 15:26:06 -0800 | [diff] [blame] | 4 | * 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 Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #include <assert.h> |
| 13 | #include <float.h> |
| 14 | #include <limits.h> |
| 15 | #include <math.h> |
| 16 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 17 | #include "./aom_scale_rtcd.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 18 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 19 | #include "aom_dsp/aom_dsp_common.h" |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 20 | #include "aom_dsp/binary_codes_writer.h" |
| 21 | #include "aom_dsp/psnr.h" |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 22 | #include "aom_mem/aom_mem.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 23 | #include "aom_ports/mem.h" |
Jingning Han | 041c67b | 2017-04-14 21:39:26 -0700 | [diff] [blame] | 24 | #include "aom_ports/system_state.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 25 | |
| 26 | #include "av1/common/onyxc_int.h" |
| 27 | #include "av1/common/quant_common.h" |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 28 | #include "av1/common/restoration.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 29 | |
Tom Finegan | 17ce8b1 | 2017-02-08 12:46:31 -0800 | [diff] [blame] | 30 | #include "av1/encoder/av1_quantize.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 31 | #include "av1/encoder/encoder.h" |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 32 | #include "av1/encoder/mathutils.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 33 | #include "av1/encoder/picklpf.h" |
| 34 | #include "av1/encoder/pickrst.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 35 | |
Debargha Mukherjee | fdbe3f7 | 2017-04-06 12:09:19 -0700 | [diff] [blame] | 36 | // When set to RESTORE_WIENER or RESTORE_SGRPROJ only those are allowed. |
Tom Finegan | 8af64ae | 2017-09-07 08:13:06 -0700 | [diff] [blame] | 37 | // When set to RESTORE_TYPES we allow switchable. |
Tom Finegan | 50c62ee | 2017-09-07 12:44:16 -0700 | [diff] [blame] | 38 | static const RestorationType force_restore_type = RESTORE_TYPES; |
Debargha Mukherjee | 1b3dbf0 | 2017-03-13 14:47:21 -0700 | [diff] [blame] | 39 | |
| 40 | // Number of Wiener iterations |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 41 | #define NUM_WIENER_ITERS 5 |
Debargha Mukherjee | 1b3dbf0 | 2017-03-13 14:47:21 -0700 | [diff] [blame] | 42 | |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 43 | typedef double (*search_restore_type)(const YV12_BUFFER_CONFIG *src, |
Debargha Mukherjee | 00c5433 | 2017-03-03 15:44:17 -0800 | [diff] [blame] | 44 | AV1_COMP *cpi, int partial_frame, |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 45 | int plane, RestorationInfo *info, |
Debargha Mukherjee | 994ccd7 | 2017-01-06 11:18:23 -0800 | [diff] [blame] | 46 | RestorationType *rest_level, |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 47 | int64_t *best_tile_cost, |
David Barker | 9666e75 | 2016-12-08 11:25:47 +0000 | [diff] [blame] | 48 | YV12_BUFFER_CONFIG *dst_frame); |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 49 | |
Debargha Mukherjee | b3c43bc | 2017-02-01 13:09:03 -0800 | [diff] [blame] | 50 | const int frame_level_restore_bits[RESTORE_TYPES] = { 2, 2, 2, 2 }; |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 51 | |
| 52 | static int64_t sse_restoration_tile(const YV12_BUFFER_CONFIG *src, |
David Barker | 9666e75 | 2016-12-08 11:25:47 +0000 | [diff] [blame] | 53 | const YV12_BUFFER_CONFIG *dst, |
| 54 | const AV1_COMMON *cm, int h_start, |
Debargha Mukherjee | 874d36d | 2016-12-14 16:53:17 -0800 | [diff] [blame] | 55 | int width, int v_start, int height, |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 56 | int components_pattern) { |
| 57 | int64_t filt_err = 0; |
Debargha Mukherjee | d748914 | 2017-01-05 13:58:16 -0800 | [diff] [blame] | 58 | (void)cm; |
| 59 | // Y and UV components cannot be mixed |
| 60 | assert(components_pattern == 1 || components_pattern == 2 || |
| 61 | components_pattern == 4 || components_pattern == 6); |
Sebastien Alaiwan | 71e8784 | 2017-04-12 16:03:28 +0200 | [diff] [blame] | 62 | #if CONFIG_HIGHBITDEPTH |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 63 | if (cm->use_highbitdepth) { |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 64 | if ((components_pattern >> AOM_PLANE_Y) & 1) { |
| 65 | filt_err += |
| 66 | aom_highbd_get_y_sse_part(src, dst, h_start, width, v_start, height); |
| 67 | } |
| 68 | if ((components_pattern >> AOM_PLANE_U) & 1) { |
Debargha Mukherjee | d748914 | 2017-01-05 13:58:16 -0800 | [diff] [blame] | 69 | filt_err += |
| 70 | aom_highbd_get_u_sse_part(src, dst, h_start, width, v_start, height); |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 71 | } |
| 72 | if ((components_pattern >> AOM_PLANE_V) & 1) { |
Debargha Mukherjee | d748914 | 2017-01-05 13:58:16 -0800 | [diff] [blame] | 73 | filt_err += |
| 74 | aom_highbd_get_v_sse_part(src, dst, h_start, width, v_start, height); |
Debargha Mukherjee | 874d36d | 2016-12-14 16:53:17 -0800 | [diff] [blame] | 75 | } |
| 76 | return filt_err; |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 77 | } |
Sebastien Alaiwan | 71e8784 | 2017-04-12 16:03:28 +0200 | [diff] [blame] | 78 | #endif // CONFIG_HIGHBITDEPTH |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 79 | if ((components_pattern >> AOM_PLANE_Y) & 1) { |
| 80 | filt_err += aom_get_y_sse_part(src, dst, h_start, width, v_start, height); |
| 81 | } |
| 82 | if ((components_pattern >> AOM_PLANE_U) & 1) { |
Debargha Mukherjee | d748914 | 2017-01-05 13:58:16 -0800 | [diff] [blame] | 83 | filt_err += aom_get_u_sse_part(src, dst, h_start, width, v_start, height); |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 84 | } |
| 85 | if ((components_pattern >> AOM_PLANE_V) & 1) { |
Debargha Mukherjee | d748914 | 2017-01-05 13:58:16 -0800 | [diff] [blame] | 86 | filt_err += aom_get_v_sse_part(src, dst, h_start, width, v_start, height); |
Debargha Mukherjee | 874d36d | 2016-12-14 16:53:17 -0800 | [diff] [blame] | 87 | } |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 88 | return filt_err; |
| 89 | } |
| 90 | |
David Barker | 60a055b | 2017-01-18 15:10:43 +0000 | [diff] [blame] | 91 | static int64_t sse_restoration_frame(AV1_COMMON *const cm, |
| 92 | const YV12_BUFFER_CONFIG *src, |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 93 | const YV12_BUFFER_CONFIG *dst, |
| 94 | int components_pattern) { |
| 95 | int64_t filt_err = 0; |
Sebastien Alaiwan | 71e8784 | 2017-04-12 16:03:28 +0200 | [diff] [blame] | 96 | #if CONFIG_HIGHBITDEPTH |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 97 | if (cm->use_highbitdepth) { |
| 98 | if ((components_pattern >> AOM_PLANE_Y) & 1) { |
| 99 | filt_err += aom_highbd_get_y_sse(src, dst); |
| 100 | } |
| 101 | if ((components_pattern >> AOM_PLANE_U) & 1) { |
| 102 | filt_err += aom_highbd_get_u_sse(src, dst); |
| 103 | } |
| 104 | if ((components_pattern >> AOM_PLANE_V) & 1) { |
| 105 | filt_err += aom_highbd_get_v_sse(src, dst); |
| 106 | } |
| 107 | return filt_err; |
| 108 | } |
David Barker | 60a055b | 2017-01-18 15:10:43 +0000 | [diff] [blame] | 109 | #else |
| 110 | (void)cm; |
Sebastien Alaiwan | 71e8784 | 2017-04-12 16:03:28 +0200 | [diff] [blame] | 111 | #endif // CONFIG_HIGHBITDEPTH |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 112 | if ((components_pattern >> AOM_PLANE_Y) & 1) { |
| 113 | filt_err = aom_get_y_sse(src, dst); |
| 114 | } |
| 115 | if ((components_pattern >> AOM_PLANE_U) & 1) { |
| 116 | filt_err += aom_get_u_sse(src, dst); |
| 117 | } |
| 118 | if ((components_pattern >> AOM_PLANE_V) & 1) { |
| 119 | filt_err += aom_get_v_sse(src, dst); |
| 120 | } |
| 121 | return filt_err; |
| 122 | } |
| 123 | |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 124 | static int64_t try_restoration_tile(const YV12_BUFFER_CONFIG *src, |
| 125 | AV1_COMP *const cpi, RestorationInfo *rsi, |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 126 | int components_pattern, int partial_frame, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 127 | int tile_idx, |
David Barker | 9666e75 | 2016-12-08 11:25:47 +0000 | [diff] [blame] | 128 | YV12_BUFFER_CONFIG *dst_frame) { |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 129 | AV1_COMMON *const cm = &cpi->common; |
Debargha Mukherjee | d748914 | 2017-01-05 13:58:16 -0800 | [diff] [blame] | 130 | |
| 131 | // Y and UV components cannot be mixed |
| 132 | assert(components_pattern == 1 || components_pattern == 2 || |
| 133 | components_pattern == 4 || components_pattern == 6); |
| 134 | |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 135 | const int is_uv = components_pattern > 1; |
| 136 | const int width = src->crop_widths[is_uv]; |
| 137 | const int height = src->crop_heights[is_uv]; |
| 138 | |
| 139 | const int rtile_size = cm->rst_info[is_uv].restoration_tilesize; |
| 140 | const int ss_y = is_uv && cm->subsampling_y; |
| 141 | |
| 142 | int nhtiles, nvtiles; |
| 143 | av1_get_rest_ntiles(width, height, rtile_size, &nhtiles, &nvtiles); |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 144 | |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 145 | av1_loop_restoration_frame(cm->frame_to_show, cm, rsi, components_pattern, |
| 146 | partial_frame, dst_frame); |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 147 | RestorationTileLimits limits = av1_get_rest_tile_limits( |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 148 | tile_idx, nhtiles, nvtiles, rtile_size, width, height, ss_y); |
| 149 | int64_t filt_err = sse_restoration_tile( |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 150 | src, dst_frame, cm, limits.h_start, limits.h_end - limits.h_start, |
| 151 | limits.v_start, limits.v_end - limits.v_start, components_pattern); |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 152 | |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 153 | return filt_err; |
| 154 | } |
| 155 | |
| 156 | static int64_t try_restoration_frame(const YV12_BUFFER_CONFIG *src, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 157 | AV1_COMP *const cpi, RestorationInfo *rsi, |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 158 | int components_pattern, int partial_frame, |
David Barker | 9666e75 | 2016-12-08 11:25:47 +0000 | [diff] [blame] | 159 | YV12_BUFFER_CONFIG *dst_frame) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 160 | AV1_COMMON *const cm = &cpi->common; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 161 | int64_t filt_err; |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 162 | av1_loop_restoration_frame(cm->frame_to_show, cm, rsi, components_pattern, |
| 163 | partial_frame, dst_frame); |
David Barker | 60a055b | 2017-01-18 15:10:43 +0000 | [diff] [blame] | 164 | filt_err = sse_restoration_frame(cm, src, dst_frame, components_pattern); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 165 | return filt_err; |
| 166 | } |
| 167 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 168 | static int64_t get_pixel_proj_error(const uint8_t *src8, int width, int height, |
| 169 | int src_stride, const uint8_t *dat8, |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 170 | int dat_stride, int use_highbitdepth, |
David Barker | 3a0df18 | 2016-12-21 10:44:52 +0000 | [diff] [blame] | 171 | int32_t *flt1, int flt1_stride, |
| 172 | int32_t *flt2, int flt2_stride, int *xqd) { |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 173 | int i, j; |
| 174 | int64_t err = 0; |
| 175 | int xq[2]; |
| 176 | decode_xq(xqd, xq); |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 177 | if (!use_highbitdepth) { |
David Barker | 3a0df18 | 2016-12-21 10:44:52 +0000 | [diff] [blame] | 178 | const uint8_t *src = src8; |
| 179 | const uint8_t *dat = dat8; |
| 180 | for (i = 0; i < height; ++i) { |
| 181 | for (j = 0; j < width; ++j) { |
| 182 | const int32_t u = |
| 183 | (int32_t)(dat[i * dat_stride + j] << SGRPROJ_RST_BITS); |
| 184 | const int32_t f1 = (int32_t)flt1[i * flt1_stride + j] - u; |
| 185 | const int32_t f2 = (int32_t)flt2[i * flt2_stride + j] - u; |
David Barker | ce110cc | 2017-02-22 10:38:59 +0000 | [diff] [blame] | 186 | const int32_t v = xq[0] * f1 + xq[1] * f2 + (u << SGRPROJ_PRJ_BITS); |
David Barker | 3a0df18 | 2016-12-21 10:44:52 +0000 | [diff] [blame] | 187 | const int32_t e = |
| 188 | ROUND_POWER_OF_TWO(v, SGRPROJ_RST_BITS + SGRPROJ_PRJ_BITS) - |
| 189 | src[i * src_stride + j]; |
| 190 | err += e * e; |
| 191 | } |
| 192 | } |
| 193 | } else { |
| 194 | const uint16_t *src = CONVERT_TO_SHORTPTR(src8); |
| 195 | const uint16_t *dat = CONVERT_TO_SHORTPTR(dat8); |
| 196 | for (i = 0; i < height; ++i) { |
| 197 | for (j = 0; j < width; ++j) { |
| 198 | const int32_t u = |
| 199 | (int32_t)(dat[i * dat_stride + j] << SGRPROJ_RST_BITS); |
| 200 | const int32_t f1 = (int32_t)flt1[i * flt1_stride + j] - u; |
| 201 | const int32_t f2 = (int32_t)flt2[i * flt2_stride + j] - u; |
David Barker | ce110cc | 2017-02-22 10:38:59 +0000 | [diff] [blame] | 202 | const int32_t v = xq[0] * f1 + xq[1] * f2 + (u << SGRPROJ_PRJ_BITS); |
David Barker | 3a0df18 | 2016-12-21 10:44:52 +0000 | [diff] [blame] | 203 | const int32_t e = |
| 204 | ROUND_POWER_OF_TWO(v, SGRPROJ_RST_BITS + SGRPROJ_PRJ_BITS) - |
| 205 | src[i * src_stride + j]; |
| 206 | err += e * e; |
| 207 | } |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 208 | } |
| 209 | } |
| 210 | return err; |
| 211 | } |
| 212 | |
Debargha Mukherjee | 749f5cd | 2017-05-31 11:26:51 -0700 | [diff] [blame] | 213 | #define USE_SGRPROJ_REFINEMENT_SEARCH 1 |
| 214 | static int64_t finer_search_pixel_proj_error( |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 215 | const uint8_t *src8, int width, int height, int src_stride, |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 216 | const uint8_t *dat8, int dat_stride, int use_highbitdepth, int32_t *flt1, |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 217 | int flt1_stride, int32_t *flt2, int flt2_stride, int start_step, int *xqd) { |
Debargha Mukherjee | 749f5cd | 2017-05-31 11:26:51 -0700 | [diff] [blame] | 218 | int64_t err = get_pixel_proj_error(src8, width, height, src_stride, dat8, |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 219 | dat_stride, use_highbitdepth, flt1, |
| 220 | flt1_stride, flt2, flt2_stride, xqd); |
Debargha Mukherjee | 749f5cd | 2017-05-31 11:26:51 -0700 | [diff] [blame] | 221 | (void)start_step; |
| 222 | #if USE_SGRPROJ_REFINEMENT_SEARCH |
| 223 | int64_t err2; |
| 224 | int tap_min[] = { SGRPROJ_PRJ_MIN0, SGRPROJ_PRJ_MIN1 }; |
| 225 | int tap_max[] = { SGRPROJ_PRJ_MAX0, SGRPROJ_PRJ_MAX1 }; |
| 226 | for (int s = start_step; s >= 1; s >>= 1) { |
| 227 | for (int p = 0; p < 2; ++p) { |
| 228 | int skip = 0; |
| 229 | do { |
| 230 | if (xqd[p] - s >= tap_min[p]) { |
| 231 | xqd[p] -= s; |
| 232 | err2 = get_pixel_proj_error(src8, width, height, src_stride, dat8, |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 233 | dat_stride, use_highbitdepth, flt1, |
| 234 | flt1_stride, flt2, flt2_stride, xqd); |
Debargha Mukherjee | 749f5cd | 2017-05-31 11:26:51 -0700 | [diff] [blame] | 235 | if (err2 > err) { |
| 236 | xqd[p] += s; |
| 237 | } else { |
| 238 | err = err2; |
| 239 | skip = 1; |
| 240 | // At the highest step size continue moving in the same direction |
| 241 | if (s == start_step) continue; |
| 242 | } |
| 243 | } |
| 244 | break; |
| 245 | } while (1); |
| 246 | if (skip) break; |
| 247 | do { |
| 248 | if (xqd[p] + s <= tap_max[p]) { |
| 249 | xqd[p] += s; |
| 250 | err2 = get_pixel_proj_error(src8, width, height, src_stride, dat8, |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 251 | dat_stride, use_highbitdepth, flt1, |
| 252 | flt1_stride, flt2, flt2_stride, xqd); |
Debargha Mukherjee | 749f5cd | 2017-05-31 11:26:51 -0700 | [diff] [blame] | 253 | if (err2 > err) { |
| 254 | xqd[p] -= s; |
| 255 | } else { |
| 256 | err = err2; |
| 257 | // At the highest step size continue moving in the same direction |
| 258 | if (s == start_step) continue; |
| 259 | } |
| 260 | } |
| 261 | break; |
| 262 | } while (1); |
| 263 | } |
| 264 | } |
| 265 | #endif // USE_SGRPROJ_REFINEMENT_SEARCH |
| 266 | return err; |
| 267 | } |
| 268 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 269 | static void get_proj_subspace(const uint8_t *src8, int width, int height, |
David Barker | 3a0df18 | 2016-12-21 10:44:52 +0000 | [diff] [blame] | 270 | int src_stride, uint8_t *dat8, int dat_stride, |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 271 | int use_highbitdepth, int32_t *flt1, |
| 272 | int flt1_stride, int32_t *flt2, int flt2_stride, |
| 273 | int *xq) { |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 274 | int i, j; |
| 275 | double H[2][2] = { { 0, 0 }, { 0, 0 } }; |
| 276 | double C[2] = { 0, 0 }; |
| 277 | double Det; |
| 278 | double x[2]; |
| 279 | const int size = width * height; |
| 280 | |
Jingning Han | 041c67b | 2017-04-14 21:39:26 -0700 | [diff] [blame] | 281 | aom_clear_system_state(); |
| 282 | |
Debargha Mukherjee | b7bb097 | 2017-03-09 06:47:43 -0800 | [diff] [blame] | 283 | // Default |
| 284 | xq[0] = 0; |
| 285 | xq[1] = 0; |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 286 | if (!use_highbitdepth) { |
David Barker | 3a0df18 | 2016-12-21 10:44:52 +0000 | [diff] [blame] | 287 | const uint8_t *src = src8; |
| 288 | const uint8_t *dat = dat8; |
| 289 | for (i = 0; i < height; ++i) { |
| 290 | for (j = 0; j < width; ++j) { |
| 291 | const double u = (double)(dat[i * dat_stride + j] << SGRPROJ_RST_BITS); |
| 292 | const double s = |
| 293 | (double)(src[i * src_stride + j] << SGRPROJ_RST_BITS) - u; |
| 294 | const double f1 = (double)flt1[i * flt1_stride + j] - u; |
| 295 | const double f2 = (double)flt2[i * flt2_stride + j] - u; |
| 296 | H[0][0] += f1 * f1; |
| 297 | H[1][1] += f2 * f2; |
| 298 | H[0][1] += f1 * f2; |
| 299 | C[0] += f1 * s; |
| 300 | C[1] += f2 * s; |
| 301 | } |
| 302 | } |
| 303 | } else { |
| 304 | const uint16_t *src = CONVERT_TO_SHORTPTR(src8); |
| 305 | const uint16_t *dat = CONVERT_TO_SHORTPTR(dat8); |
| 306 | for (i = 0; i < height; ++i) { |
| 307 | for (j = 0; j < width; ++j) { |
| 308 | const double u = (double)(dat[i * dat_stride + j] << SGRPROJ_RST_BITS); |
| 309 | const double s = |
| 310 | (double)(src[i * src_stride + j] << SGRPROJ_RST_BITS) - u; |
| 311 | const double f1 = (double)flt1[i * flt1_stride + j] - u; |
| 312 | const double f2 = (double)flt2[i * flt2_stride + j] - u; |
| 313 | H[0][0] += f1 * f1; |
| 314 | H[1][1] += f2 * f2; |
| 315 | H[0][1] += f1 * f2; |
| 316 | C[0] += f1 * s; |
| 317 | C[1] += f2 * s; |
| 318 | } |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 319 | } |
| 320 | } |
| 321 | H[0][0] /= size; |
| 322 | H[0][1] /= size; |
| 323 | H[1][1] /= size; |
| 324 | H[1][0] = H[0][1]; |
| 325 | C[0] /= size; |
| 326 | C[1] /= size; |
| 327 | Det = (H[0][0] * H[1][1] - H[0][1] * H[1][0]); |
| 328 | if (Det < 1e-8) return; // ill-posed, return default values |
| 329 | x[0] = (H[1][1] * C[0] - H[0][1] * C[1]) / Det; |
| 330 | x[1] = (H[0][0] * C[1] - H[1][0] * C[0]) / Det; |
| 331 | xq[0] = (int)rint(x[0] * (1 << SGRPROJ_PRJ_BITS)); |
| 332 | xq[1] = (int)rint(x[1] * (1 << SGRPROJ_PRJ_BITS)); |
| 333 | } |
| 334 | |
| 335 | void encode_xq(int *xq, int *xqd) { |
Debargha Mukherjee | b7bb097 | 2017-03-09 06:47:43 -0800 | [diff] [blame] | 336 | xqd[0] = xq[0]; |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 337 | xqd[0] = clamp(xqd[0], SGRPROJ_PRJ_MIN0, SGRPROJ_PRJ_MAX0); |
Debargha Mukherjee | b7bb097 | 2017-03-09 06:47:43 -0800 | [diff] [blame] | 338 | xqd[1] = (1 << SGRPROJ_PRJ_BITS) - xqd[0] - xq[1]; |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 339 | xqd[1] = clamp(xqd[1], SGRPROJ_PRJ_MIN1, SGRPROJ_PRJ_MAX1); |
| 340 | } |
| 341 | |
| 342 | static void search_selfguided_restoration(uint8_t *dat8, int width, int height, |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 343 | int dat_stride, const uint8_t *src8, |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 344 | int src_stride, int use_highbitdepth, |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 345 | int bit_depth, int pu_width, |
| 346 | int pu_height, int *eps, int *xqd, |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 347 | int32_t *rstbuf) { |
David Barker | 3a0df18 | 2016-12-21 10:44:52 +0000 | [diff] [blame] | 348 | int32_t *flt1 = rstbuf; |
Debargha Mukherjee | 519dbcf | 2016-12-16 03:13:02 -0800 | [diff] [blame] | 349 | int32_t *flt2 = flt1 + RESTORATION_TILEPELS_MAX; |
David Barker | 506eb72 | 2017-03-08 13:35:49 +0000 | [diff] [blame] | 350 | int ep, bestep = 0; |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 351 | int64_t err, besterr = -1; |
| 352 | int exqd[2], bestxqd[2] = { 0, 0 }; |
Debargha Mukherjee | 22bbe4c | 2017-08-31 12:30:10 -0700 | [diff] [blame] | 353 | int flt1_stride = ((width + 7) & ~7) + 8; |
| 354 | int flt2_stride = ((width + 7) & ~7) + 8; |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 355 | assert(pu_width == (RESTORATION_PROC_UNIT_SIZE >> 1) || |
| 356 | pu_width == RESTORATION_PROC_UNIT_SIZE); |
| 357 | assert(pu_height == (RESTORATION_PROC_UNIT_SIZE >> 1) || |
| 358 | pu_height == RESTORATION_PROC_UNIT_SIZE); |
Yaowu Xu | 069cc31 | 2017-09-06 09:03:03 -0700 | [diff] [blame] | 359 | #if !CONFIG_HIGHBITDEPTH |
| 360 | (void)bit_depth; |
| 361 | #endif |
David Barker | 3a0df18 | 2016-12-21 10:44:52 +0000 | [diff] [blame] | 362 | |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 363 | for (ep = 0; ep < SGRPROJ_PARAMS; ep++) { |
| 364 | int exq[2]; |
Sebastien Alaiwan | 71e8784 | 2017-04-12 16:03:28 +0200 | [diff] [blame] | 365 | #if CONFIG_HIGHBITDEPTH |
Rupert Swarbrick | 32d150b | 2017-09-04 10:35:51 +0100 | [diff] [blame] | 366 | if (use_highbitdepth) { |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 367 | uint16_t *dat = CONVERT_TO_SHORTPTR(dat8); |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 368 | for (int i = 0; i < height; i += pu_height) |
| 369 | for (int j = 0; j < width; j += pu_width) { |
| 370 | const int w = AOMMIN(pu_width, width - j); |
| 371 | const int h = AOMMIN(pu_height, height - i); |
| 372 | uint16_t *dat_p = dat + i * dat_stride + j; |
| 373 | int32_t *flt1_p = flt1 + i * flt1_stride + j; |
| 374 | int32_t *flt2_p = flt2 + i * flt2_stride + j; |
Debargha Mukherjee | b7bb097 | 2017-03-09 06:47:43 -0800 | [diff] [blame] | 375 | #if USE_HIGHPASS_IN_SGRPROJ |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 376 | av1_highpass_filter_highbd(dat_p, w, h, dat_stride, flt1_p, |
| 377 | flt1_stride, sgr_params[ep].corner, |
| 378 | sgr_params[ep].edge); |
Debargha Mukherjee | b7bb097 | 2017-03-09 06:47:43 -0800 | [diff] [blame] | 379 | #else |
Debargha Mukherjee | 22bbe4c | 2017-08-31 12:30:10 -0700 | [diff] [blame] | 380 | av1_selfguided_restoration_highbd( |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 381 | dat_p, w, h, dat_stride, flt1_p, flt1_stride, bit_depth, |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 382 | sgr_params[ep].r1, sgr_params[ep].e1); |
Debargha Mukherjee | b7bb097 | 2017-03-09 06:47:43 -0800 | [diff] [blame] | 383 | #endif // USE_HIGHPASS_IN_SGRPROJ |
Debargha Mukherjee | 22bbe4c | 2017-08-31 12:30:10 -0700 | [diff] [blame] | 384 | av1_selfguided_restoration_highbd( |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 385 | dat_p, w, h, dat_stride, flt2_p, flt2_stride, bit_depth, |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 386 | sgr_params[ep].r2, sgr_params[ep].e2); |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 387 | } |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 388 | } else { |
David Barker | 506eb72 | 2017-03-08 13:35:49 +0000 | [diff] [blame] | 389 | #endif |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 390 | for (int i = 0; i < height; i += pu_height) |
| 391 | for (int j = 0; j < width; j += pu_width) { |
| 392 | const int w = AOMMIN(pu_width, width - j); |
| 393 | const int h = AOMMIN(pu_height, height - i); |
| 394 | uint8_t *dat_p = dat8 + i * dat_stride + j; |
| 395 | int32_t *flt1_p = flt1 + i * flt1_stride + j; |
| 396 | int32_t *flt2_p = flt2 + i * flt2_stride + j; |
Debargha Mukherjee | b7bb097 | 2017-03-09 06:47:43 -0800 | [diff] [blame] | 397 | #if USE_HIGHPASS_IN_SGRPROJ |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 398 | av1_highpass_filter(dat_p, w, h, dat_stride, flt1_p, flt1_stride, |
| 399 | sgr_params[ep].corner, sgr_params[ep].edge); |
Debargha Mukherjee | b7bb097 | 2017-03-09 06:47:43 -0800 | [diff] [blame] | 400 | #else |
Debargha Mukherjee | 22bbe4c | 2017-08-31 12:30:10 -0700 | [diff] [blame] | 401 | av1_selfguided_restoration(dat_p, w, h, dat_stride, flt1_p, flt1_stride, |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 402 | sgr_params[ep].r1, sgr_params[ep].e1); |
Debargha Mukherjee | b7bb097 | 2017-03-09 06:47:43 -0800 | [diff] [blame] | 403 | #endif // USE_HIGHPASS_IN_SGRPROJ |
Debargha Mukherjee | 22bbe4c | 2017-08-31 12:30:10 -0700 | [diff] [blame] | 404 | av1_selfguided_restoration(dat_p, w, h, dat_stride, flt2_p, |
| 405 | flt2_stride, sgr_params[ep].r2, |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 406 | sgr_params[ep].e2); |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 407 | } |
Sebastien Alaiwan | 71e8784 | 2017-04-12 16:03:28 +0200 | [diff] [blame] | 408 | #if CONFIG_HIGHBITDEPTH |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 409 | } |
David Barker | 506eb72 | 2017-03-08 13:35:49 +0000 | [diff] [blame] | 410 | #endif |
Debargha Mukherjee | 7ae7aea | 2017-05-04 15:17:17 -0700 | [diff] [blame] | 411 | aom_clear_system_state(); |
David Barker | 3a0df18 | 2016-12-21 10:44:52 +0000 | [diff] [blame] | 412 | get_proj_subspace(src8, width, height, src_stride, dat8, dat_stride, |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 413 | use_highbitdepth, flt1, flt1_stride, flt2, flt2_stride, |
| 414 | exq); |
Debargha Mukherjee | 7ae7aea | 2017-05-04 15:17:17 -0700 | [diff] [blame] | 415 | aom_clear_system_state(); |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 416 | encode_xq(exq, exqd); |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 417 | err = finer_search_pixel_proj_error( |
| 418 | src8, width, height, src_stride, dat8, dat_stride, use_highbitdepth, |
| 419 | flt1, flt1_stride, flt2, flt2_stride, 2, exqd); |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 420 | if (besterr == -1 || err < besterr) { |
| 421 | bestep = ep; |
| 422 | besterr = err; |
| 423 | bestxqd[0] = exqd[0]; |
| 424 | bestxqd[1] = exqd[1]; |
| 425 | } |
| 426 | } |
| 427 | *eps = bestep; |
| 428 | xqd[0] = bestxqd[0]; |
| 429 | xqd[1] = bestxqd[1]; |
| 430 | } |
| 431 | |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 432 | static int count_sgrproj_bits(SgrprojInfo *sgrproj_info, |
| 433 | SgrprojInfo *ref_sgrproj_info) { |
| 434 | int bits = SGRPROJ_PARAMS_BITS; |
| 435 | bits += aom_count_primitive_refsubexpfin( |
| 436 | SGRPROJ_PRJ_MAX0 - SGRPROJ_PRJ_MIN0 + 1, SGRPROJ_PRJ_SUBEXP_K, |
| 437 | ref_sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0, |
| 438 | sgrproj_info->xqd[0] - SGRPROJ_PRJ_MIN0); |
| 439 | bits += aom_count_primitive_refsubexpfin( |
| 440 | SGRPROJ_PRJ_MAX1 - SGRPROJ_PRJ_MIN1 + 1, SGRPROJ_PRJ_SUBEXP_K, |
| 441 | ref_sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1, |
| 442 | sgrproj_info->xqd[1] - SGRPROJ_PRJ_MIN1); |
| 443 | return bits; |
| 444 | } |
| 445 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 446 | struct rest_search_ctxt { |
| 447 | const YV12_BUFFER_CONFIG *src; |
| 448 | AV1_COMP *cpi; |
| 449 | uint8_t *dgd_buffer; |
| 450 | const uint8_t *src_buffer; |
| 451 | int dgd_stride; |
| 452 | int src_stride; |
| 453 | int partial_frame; |
| 454 | RestorationInfo *info; |
| 455 | RestorationType *type; |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 456 | int64_t *best_tile_cost; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 457 | int plane; |
| 458 | int plane_width; |
| 459 | int plane_height; |
| 460 | int nrtiles_x; |
| 461 | int nrtiles_y; |
| 462 | YV12_BUFFER_CONFIG *dst_frame; |
| 463 | }; |
| 464 | |
| 465 | // Fill in ctxt. Returns the number of restoration tiles for this plane |
| 466 | static INLINE int init_rest_search_ctxt( |
| 467 | const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi, int partial_frame, int plane, |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 468 | RestorationInfo *info, RestorationType *type, int64_t *best_tile_cost, |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 469 | YV12_BUFFER_CONFIG *dst_frame, struct rest_search_ctxt *ctxt) { |
| 470 | AV1_COMMON *const cm = &cpi->common; |
| 471 | ctxt->src = src; |
| 472 | ctxt->cpi = cpi; |
| 473 | ctxt->partial_frame = partial_frame; |
| 474 | ctxt->info = info; |
| 475 | ctxt->type = type; |
| 476 | ctxt->best_tile_cost = best_tile_cost; |
| 477 | ctxt->plane = plane; |
| 478 | ctxt->dst_frame = dst_frame; |
| 479 | |
| 480 | const YV12_BUFFER_CONFIG *dgd = cm->frame_to_show; |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 481 | const int is_uv = plane != AOM_PLANE_Y; |
| 482 | ctxt->plane_width = src->crop_widths[is_uv]; |
| 483 | ctxt->plane_height = src->crop_heights[is_uv]; |
| 484 | ctxt->src_buffer = src->buffers[plane]; |
| 485 | ctxt->src_stride = src->strides[is_uv]; |
| 486 | ctxt->dgd_buffer = dgd->buffers[plane]; |
| 487 | ctxt->dgd_stride = dgd->strides[is_uv]; |
| 488 | assert(src->crop_widths[is_uv] == dgd->crop_widths[is_uv]); |
| 489 | assert(src->crop_heights[is_uv] == dgd->crop_heights[is_uv]); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 490 | |
| 491 | return av1_get_rest_ntiles(ctxt->plane_width, ctxt->plane_height, |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 492 | cm->rst_info[plane].restoration_tilesize, |
| 493 | &ctxt->nrtiles_x, &ctxt->nrtiles_y); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 494 | } |
| 495 | |
| 496 | typedef void (*rtile_visitor_t)(const struct rest_search_ctxt *search_ctxt, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 497 | int rtile_idx, |
| 498 | const RestorationTileLimits *limits, void *arg); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 499 | |
| 500 | static void foreach_rtile_in_tile(const struct rest_search_ctxt *ctxt, |
| 501 | int tile_row, int tile_col, |
| 502 | rtile_visitor_t fun, void *arg) { |
| 503 | const AV1_COMMON *const cm = &ctxt->cpi->common; |
| 504 | const RestorationInfo *rsi = ctxt->cpi->rst_search; |
Dominic Symes | c27f542 | 2017-10-03 09:58:17 +0200 | [diff] [blame] | 505 | TileInfo tile_info; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 506 | |
Dominic Symes | c27f542 | 2017-10-03 09:58:17 +0200 | [diff] [blame] | 507 | av1_tile_set_row(&tile_info, cm, tile_row); |
| 508 | av1_tile_set_col(&tile_info, cm, tile_col); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 509 | |
Dominic Symes | c27f542 | 2017-10-03 09:58:17 +0200 | [diff] [blame] | 510 | int tile_col_start = tile_info.mi_col_start * MI_SIZE; |
| 511 | int tile_col_end = tile_info.mi_col_end * MI_SIZE; |
| 512 | int tile_row_start = tile_info.mi_row_start * MI_SIZE; |
| 513 | int tile_row_end = tile_info.mi_row_end * MI_SIZE; |
| 514 | if (ctxt->plane > 0) { |
| 515 | tile_col_start = ROUND_POWER_OF_TWO(tile_col_start, cm->subsampling_x); |
| 516 | tile_col_end = ROUND_POWER_OF_TWO(tile_col_end, cm->subsampling_x); |
| 517 | tile_row_start = ROUND_POWER_OF_TWO(tile_row_start, cm->subsampling_y); |
| 518 | tile_row_end = ROUND_POWER_OF_TWO(tile_row_end, cm->subsampling_y); |
| 519 | } |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 520 | |
Rupert Swarbrick | b66894a | 2017-10-06 15:11:01 +0100 | [diff] [blame] | 521 | #if CONFIG_FRAME_SUPERRES |
| 522 | // If upscaling is enabled, the tile limits need scaling to match the |
| 523 | // upscaled frame where the restoration tiles live. To do this, scale up the |
| 524 | // top-left and bottom-right of the tile. |
| 525 | if (!av1_superres_unscaled(cm)) { |
Urvang Joshi | 69fde2e | 2017-10-09 15:34:18 -0700 | [diff] [blame] | 526 | av1_calculate_unscaled_superres_size(&tile_col_start, &tile_row_start, |
| 527 | cm->superres_scale_denominator); |
| 528 | av1_calculate_unscaled_superres_size(&tile_col_end, &tile_row_end, |
| 529 | cm->superres_scale_denominator); |
Rupert Swarbrick | b66894a | 2017-10-06 15:11:01 +0100 | [diff] [blame] | 530 | // Make sure we don't fall off the bottom-right of the frame. |
| 531 | tile_col_end = AOMMIN(tile_col_end, ctxt->plane_width); |
| 532 | tile_row_end = AOMMIN(tile_row_end, ctxt->plane_height); |
| 533 | } |
| 534 | #endif // CONFIG_FRAME_SUPERRES |
| 535 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 536 | const int rtile_size = rsi->restoration_tilesize; |
Dominic Symes | c27f542 | 2017-10-03 09:58:17 +0200 | [diff] [blame] | 537 | const int rtile_col0 = (tile_col_start + rtile_size - 1) / rtile_size; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 538 | const int rtile_col1 = |
Dominic Symes | c27f542 | 2017-10-03 09:58:17 +0200 | [diff] [blame] | 539 | AOMMIN((tile_col_end + rtile_size - 1) / rtile_size, ctxt->nrtiles_x); |
| 540 | const int rtile_row0 = (tile_row_start + rtile_size - 1) / rtile_size; |
| 541 | const int rtile_row1 = |
| 542 | AOMMIN((tile_row_end + rtile_size - 1) / rtile_size, ctxt->nrtiles_y); |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 543 | const int ss_y = ctxt->plane > 0 && cm->subsampling_y; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 544 | |
| 545 | for (int rtile_row = rtile_row0; rtile_row < rtile_row1; ++rtile_row) { |
| 546 | for (int rtile_col = rtile_col0; rtile_col < rtile_col1; ++rtile_col) { |
| 547 | const int rtile_idx = rtile_row * ctxt->nrtiles_x + rtile_col; |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 548 | RestorationTileLimits limits = av1_get_rest_tile_limits( |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 549 | rtile_idx, ctxt->nrtiles_x, ctxt->nrtiles_y, rtile_size, |
| 550 | ctxt->plane_width, ctxt->plane_height, ss_y); |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 551 | fun(ctxt, rtile_idx, &limits, arg); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 552 | } |
| 553 | } |
| 554 | } |
| 555 | |
| 556 | static void search_sgrproj_for_rtile(const struct rest_search_ctxt *ctxt, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 557 | int rtile_idx, |
| 558 | const RestorationTileLimits *limits, |
| 559 | void *arg) { |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 560 | const MACROBLOCK *const x = &ctxt->cpi->td.mb; |
| 561 | const AV1_COMMON *const cm = &ctxt->cpi->common; |
| 562 | RestorationInfo *rsi = ctxt->cpi->rst_search; |
| 563 | SgrprojInfo *sgrproj_info = ctxt->info->sgrproj_info; |
| 564 | |
| 565 | SgrprojInfo *ref_sgrproj_info = (SgrprojInfo *)arg; |
| 566 | |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 567 | int64_t err = |
| 568 | sse_restoration_tile(ctxt->src, cm->frame_to_show, cm, limits->h_start, |
| 569 | limits->h_end - limits->h_start, limits->v_start, |
| 570 | limits->v_end - limits->v_start, (1 << ctxt->plane)); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 571 | // #bits when a tile is not restored |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 572 | int bits = x->sgrproj_restore_cost[0]; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 573 | double cost_norestore = RDCOST_DBL(x->rdmult, (bits >> 4), err); |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 574 | ctxt->best_tile_cost[rtile_idx] = INT64_MAX; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 575 | |
| 576 | RestorationInfo *plane_rsi = &rsi[ctxt->plane]; |
| 577 | SgrprojInfo *rtile_sgrproj_info = &plane_rsi->sgrproj_info[rtile_idx]; |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 578 | uint8_t *dgd_start = |
| 579 | ctxt->dgd_buffer + limits->v_start * ctxt->dgd_stride + limits->h_start; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 580 | const uint8_t *src_start = |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 581 | ctxt->src_buffer + limits->v_start * ctxt->src_stride + limits->h_start; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 582 | |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 583 | search_selfguided_restoration( |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 584 | dgd_start, limits->h_end - limits->h_start, |
| 585 | limits->v_end - limits->v_start, ctxt->dgd_stride, src_start, |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 586 | ctxt->src_stride, |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 587 | #if CONFIG_HIGHBITDEPTH |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 588 | cm->use_highbitdepth, cm->bit_depth, |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 589 | #else |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 590 | 0, 8, |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 591 | #endif // CONFIG_HIGHBITDEPTH |
Debargha Mukherjee | 7a5587a | 2017-08-31 07:41:30 -0700 | [diff] [blame] | 592 | rsi[ctxt->plane].procunit_width, rsi[ctxt->plane].procunit_height, |
| 593 | &rtile_sgrproj_info->ep, rtile_sgrproj_info->xqd, |
| 594 | cm->rst_internal.tmpbuf); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 595 | plane_rsi->restoration_type[rtile_idx] = RESTORE_SGRPROJ; |
| 596 | err = try_restoration_tile(ctxt->src, ctxt->cpi, rsi, (1 << ctxt->plane), |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 597 | ctxt->partial_frame, rtile_idx, ctxt->dst_frame); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 598 | bits = |
| 599 | count_sgrproj_bits(&plane_rsi->sgrproj_info[rtile_idx], ref_sgrproj_info) |
| 600 | << AV1_PROB_COST_SHIFT; |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 601 | bits += x->sgrproj_restore_cost[1]; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 602 | double cost_sgrproj = RDCOST_DBL(x->rdmult, (bits >> 4), err); |
| 603 | if (cost_sgrproj >= cost_norestore) { |
| 604 | ctxt->type[rtile_idx] = RESTORE_NONE; |
| 605 | } else { |
| 606 | ctxt->type[rtile_idx] = RESTORE_SGRPROJ; |
| 607 | *ref_sgrproj_info = sgrproj_info[rtile_idx] = |
| 608 | plane_rsi->sgrproj_info[rtile_idx]; |
| 609 | ctxt->best_tile_cost[rtile_idx] = err; |
| 610 | } |
| 611 | plane_rsi->restoration_type[rtile_idx] = RESTORE_NONE; |
| 612 | } |
| 613 | |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 614 | static double search_sgrproj(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi, |
| 615 | int partial_frame, int plane, |
| 616 | RestorationInfo *info, RestorationType *type, |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 617 | int64_t *best_tile_cost, |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 618 | YV12_BUFFER_CONFIG *dst_frame) { |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 619 | const MACROBLOCK *const x = &cpi->td.mb; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 620 | struct rest_search_ctxt ctxt; |
| 621 | const int nrtiles = |
| 622 | init_rest_search_ctxt(src, cpi, partial_frame, plane, info, type, |
| 623 | best_tile_cost, dst_frame, &ctxt); |
| 624 | |
| 625 | RestorationInfo *plane_rsi = &cpi->rst_search[plane]; |
| 626 | plane_rsi->frame_restoration_type = RESTORE_SGRPROJ; |
| 627 | for (int rtile_idx = 0; rtile_idx < nrtiles; ++rtile_idx) { |
| 628 | plane_rsi->restoration_type[rtile_idx] = RESTORE_NONE; |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 629 | } |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 630 | |
| 631 | // Compute best Sgrproj filters for each rtile, one (encoder/decoder) |
| 632 | // tile at a time. |
| 633 | const AV1_COMMON *const cm = &cpi->common; |
Debargha Mukherjee | e168a78 | 2017-08-31 12:30:10 -0700 | [diff] [blame] | 634 | #if CONFIG_HIGHBITDEPTH |
| 635 | if (cm->use_highbitdepth) |
| 636 | extend_frame_highbd(CONVERT_TO_SHORTPTR(ctxt.dgd_buffer), ctxt.plane_width, |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 637 | ctxt.plane_height, ctxt.dgd_stride, SGRPROJ_BORDER_HORZ, |
| 638 | SGRPROJ_BORDER_VERT); |
Debargha Mukherjee | e168a78 | 2017-08-31 12:30:10 -0700 | [diff] [blame] | 639 | else |
| 640 | #endif |
| 641 | extend_frame(ctxt.dgd_buffer, ctxt.plane_width, ctxt.plane_height, |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 642 | ctxt.dgd_stride, SGRPROJ_BORDER_HORZ, SGRPROJ_BORDER_VERT); |
Debargha Mukherjee | e168a78 | 2017-08-31 12:30:10 -0700 | [diff] [blame] | 643 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 644 | for (int tile_row = 0; tile_row < cm->tile_rows; ++tile_row) { |
| 645 | for (int tile_col = 0; tile_col < cm->tile_cols; ++tile_col) { |
| 646 | SgrprojInfo ref_sgrproj_info; |
| 647 | set_default_sgrproj(&ref_sgrproj_info); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 648 | foreach_rtile_in_tile(&ctxt, tile_row, tile_col, search_sgrproj_for_rtile, |
| 649 | &ref_sgrproj_info); |
| 650 | } |
| 651 | } |
| 652 | |
| 653 | // Cost for Sgrproj filtering |
Debargha Mukherjee | d23ceea | 2017-05-18 20:33:52 -0700 | [diff] [blame] | 654 | SgrprojInfo ref_sgrproj_info; |
| 655 | set_default_sgrproj(&ref_sgrproj_info); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 656 | SgrprojInfo *sgrproj_info = info->sgrproj_info; |
Debargha Mukherjee | d23ceea | 2017-05-18 20:33:52 -0700 | [diff] [blame] | 657 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 658 | int bits = frame_level_restore_bits[plane_rsi->frame_restoration_type] |
| 659 | << AV1_PROB_COST_SHIFT; |
| 660 | for (int rtile_idx = 0; rtile_idx < nrtiles; ++rtile_idx) { |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 661 | bits += x->sgrproj_restore_cost[type[rtile_idx] != RESTORE_NONE]; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 662 | plane_rsi->sgrproj_info[rtile_idx] = sgrproj_info[rtile_idx]; |
| 663 | if (type[rtile_idx] == RESTORE_SGRPROJ) { |
| 664 | bits += count_sgrproj_bits(&plane_rsi->sgrproj_info[rtile_idx], |
Debargha Mukherjee | d23ceea | 2017-05-18 20:33:52 -0700 | [diff] [blame] | 665 | &ref_sgrproj_info) |
| 666 | << AV1_PROB_COST_SHIFT; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 667 | ref_sgrproj_info = plane_rsi->sgrproj_info[rtile_idx]; |
Debargha Mukherjee | d23ceea | 2017-05-18 20:33:52 -0700 | [diff] [blame] | 668 | } |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 669 | plane_rsi->restoration_type[rtile_idx] = type[rtile_idx]; |
Debargha Mukherjee | d23ceea | 2017-05-18 20:33:52 -0700 | [diff] [blame] | 670 | } |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 671 | int64_t err = try_restoration_frame(src, cpi, cpi->rst_search, (1 << plane), |
| 672 | partial_frame, dst_frame); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 673 | double cost_sgrproj = RDCOST_DBL(cpi->td.mb.rdmult, (bits >> 4), err); |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 674 | return cost_sgrproj; |
| 675 | } |
| 676 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 677 | static double find_average(const uint8_t *src, int h_start, int h_end, |
| 678 | int v_start, int v_end, int stride) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 679 | uint64_t sum = 0; |
| 680 | double avg = 0; |
| 681 | int i, j; |
Jingning Han | 041c67b | 2017-04-14 21:39:26 -0700 | [diff] [blame] | 682 | aom_clear_system_state(); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 683 | for (i = v_start; i < v_end; i++) |
| 684 | for (j = h_start; j < h_end; j++) sum += src[i * stride + j]; |
| 685 | avg = (double)sum / ((v_end - v_start) * (h_end - h_start)); |
| 686 | return avg; |
| 687 | } |
| 688 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 689 | static void compute_stats(int wiener_win, const uint8_t *dgd, |
| 690 | const uint8_t *src, int h_start, int h_end, |
| 691 | int v_start, int v_end, int dgd_stride, |
| 692 | int src_stride, double *M, double *H) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 693 | int i, j, k, l; |
Debargha Mukherjee | 999d2f6 | 2016-12-15 13:23:21 -0800 | [diff] [blame] | 694 | double Y[WIENER_WIN2]; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 695 | const int wiener_win2 = wiener_win * wiener_win; |
| 696 | const int wiener_halfwin = (wiener_win >> 1); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 697 | const double avg = |
| 698 | find_average(dgd, h_start, h_end, v_start, v_end, dgd_stride); |
| 699 | |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 700 | memset(M, 0, sizeof(*M) * wiener_win2); |
| 701 | memset(H, 0, sizeof(*H) * wiener_win2 * wiener_win2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 702 | for (i = v_start; i < v_end; i++) { |
| 703 | for (j = h_start; j < h_end; j++) { |
| 704 | const double X = (double)src[i * src_stride + j] - avg; |
| 705 | int idx = 0; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 706 | for (k = -wiener_halfwin; k <= wiener_halfwin; k++) { |
| 707 | for (l = -wiener_halfwin; l <= wiener_halfwin; l++) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 708 | Y[idx] = (double)dgd[(i + l) * dgd_stride + (j + k)] - avg; |
| 709 | idx++; |
| 710 | } |
| 711 | } |
Debargha Mukherjee | a1a1e36 | 2017-10-04 20:01:03 -0700 | [diff] [blame] | 712 | assert(idx == wiener_win2); |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 713 | for (k = 0; k < wiener_win2; ++k) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 714 | M[k] += Y[k] * X; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 715 | H[k * wiener_win2 + k] += Y[k] * Y[k]; |
| 716 | for (l = k + 1; l < wiener_win2; ++l) { |
David Barker | 33f3bfd | 2017-01-06 15:34:50 +0000 | [diff] [blame] | 717 | // H is a symmetric matrix, so we only need to fill out the upper |
| 718 | // triangle here. We can copy it down to the lower triangle outside |
| 719 | // the (i, j) loops. |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 720 | H[k * wiener_win2 + l] += Y[k] * Y[l]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 721 | } |
| 722 | } |
| 723 | } |
| 724 | } |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 725 | for (k = 0; k < wiener_win2; ++k) { |
| 726 | for (l = k + 1; l < wiener_win2; ++l) { |
| 727 | H[l * wiener_win2 + k] = H[k * wiener_win2 + l]; |
David Barker | 33f3bfd | 2017-01-06 15:34:50 +0000 | [diff] [blame] | 728 | } |
| 729 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 730 | } |
| 731 | |
Sebastien Alaiwan | 71e8784 | 2017-04-12 16:03:28 +0200 | [diff] [blame] | 732 | #if CONFIG_HIGHBITDEPTH |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 733 | static double find_average_highbd(const uint16_t *src, int h_start, int h_end, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 734 | int v_start, int v_end, int stride) { |
| 735 | uint64_t sum = 0; |
| 736 | double avg = 0; |
| 737 | int i, j; |
Jingning Han | 041c67b | 2017-04-14 21:39:26 -0700 | [diff] [blame] | 738 | aom_clear_system_state(); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 739 | for (i = v_start; i < v_end; i++) |
| 740 | for (j = h_start; j < h_end; j++) sum += src[i * stride + j]; |
| 741 | avg = (double)sum / ((v_end - v_start) * (h_end - h_start)); |
| 742 | return avg; |
| 743 | } |
| 744 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 745 | static void compute_stats_highbd(int wiener_win, const uint8_t *dgd8, |
| 746 | const uint8_t *src8, int h_start, int h_end, |
| 747 | int v_start, int v_end, int dgd_stride, |
| 748 | int src_stride, double *M, double *H) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 749 | int i, j, k, l; |
Debargha Mukherjee | 999d2f6 | 2016-12-15 13:23:21 -0800 | [diff] [blame] | 750 | double Y[WIENER_WIN2]; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 751 | const int wiener_win2 = wiener_win * wiener_win; |
| 752 | const int wiener_halfwin = (wiener_win >> 1); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 753 | const uint16_t *src = CONVERT_TO_SHORTPTR(src8); |
| 754 | const uint16_t *dgd = CONVERT_TO_SHORTPTR(dgd8); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 755 | const double avg = |
| 756 | find_average_highbd(dgd, h_start, h_end, v_start, v_end, dgd_stride); |
| 757 | |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 758 | memset(M, 0, sizeof(*M) * wiener_win2); |
| 759 | memset(H, 0, sizeof(*H) * wiener_win2 * wiener_win2); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 760 | for (i = v_start; i < v_end; i++) { |
| 761 | for (j = h_start; j < h_end; j++) { |
| 762 | const double X = (double)src[i * src_stride + j] - avg; |
| 763 | int idx = 0; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 764 | for (k = -wiener_halfwin; k <= wiener_halfwin; k++) { |
| 765 | for (l = -wiener_halfwin; l <= wiener_halfwin; l++) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 766 | Y[idx] = (double)dgd[(i + l) * dgd_stride + (j + k)] - avg; |
| 767 | idx++; |
| 768 | } |
| 769 | } |
Debargha Mukherjee | a1a1e36 | 2017-10-04 20:01:03 -0700 | [diff] [blame] | 770 | assert(idx == wiener_win2); |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 771 | for (k = 0; k < wiener_win2; ++k) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 772 | M[k] += Y[k] * X; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 773 | H[k * wiener_win2 + k] += Y[k] * Y[k]; |
| 774 | for (l = k + 1; l < wiener_win2; ++l) { |
David Barker | 33f3bfd | 2017-01-06 15:34:50 +0000 | [diff] [blame] | 775 | // H is a symmetric matrix, so we only need to fill out the upper |
| 776 | // triangle here. We can copy it down to the lower triangle outside |
| 777 | // the (i, j) loops. |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 778 | H[k * wiener_win2 + l] += Y[k] * Y[l]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 779 | } |
| 780 | } |
| 781 | } |
| 782 | } |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 783 | for (k = 0; k < wiener_win2; ++k) { |
| 784 | for (l = k + 1; l < wiener_win2; ++l) { |
| 785 | H[l * wiener_win2 + k] = H[k * wiener_win2 + l]; |
David Barker | 33f3bfd | 2017-01-06 15:34:50 +0000 | [diff] [blame] | 786 | } |
| 787 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 788 | } |
Sebastien Alaiwan | 71e8784 | 2017-04-12 16:03:28 +0200 | [diff] [blame] | 789 | #endif // CONFIG_HIGHBITDEPTH |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 790 | |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 791 | static INLINE int wrap_index(int i, int wiener_win) { |
| 792 | const int wiener_halfwin1 = (wiener_win >> 1) + 1; |
| 793 | return (i >= wiener_halfwin1 ? wiener_win - 1 - i : i); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 794 | } |
| 795 | |
| 796 | // Fix vector b, update vector a |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 797 | static void update_a_sep_sym(int wiener_win, double **Mc, double **Hc, |
| 798 | double *a, double *b) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 799 | int i, j; |
Debargha Mukherjee | 999d2f6 | 2016-12-15 13:23:21 -0800 | [diff] [blame] | 800 | double S[WIENER_WIN]; |
Debargha Mukherjee | 6ae588f | 2017-04-14 00:40:02 -0700 | [diff] [blame] | 801 | double A[WIENER_HALFWIN1], B[WIENER_HALFWIN1 * WIENER_HALFWIN1]; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 802 | const int wiener_win2 = wiener_win * wiener_win; |
| 803 | const int wiener_halfwin1 = (wiener_win >> 1) + 1; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 804 | memset(A, 0, sizeof(A)); |
| 805 | memset(B, 0, sizeof(B)); |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 806 | for (i = 0; i < wiener_win; i++) { |
| 807 | for (j = 0; j < wiener_win; ++j) { |
| 808 | const int jj = wrap_index(j, wiener_win); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 809 | A[jj] += Mc[i][j] * b[i]; |
| 810 | } |
| 811 | } |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 812 | for (i = 0; i < wiener_win; i++) { |
| 813 | for (j = 0; j < wiener_win; j++) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 814 | int k, l; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 815 | for (k = 0; k < wiener_win; ++k) |
| 816 | for (l = 0; l < wiener_win; ++l) { |
| 817 | const int kk = wrap_index(k, wiener_win); |
| 818 | const int ll = wrap_index(l, wiener_win); |
| 819 | B[ll * wiener_halfwin1 + kk] += |
| 820 | Hc[j * wiener_win + i][k * wiener_win2 + l] * b[i] * b[j]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 821 | } |
| 822 | } |
| 823 | } |
| 824 | // Normalization enforcement in the system of equations itself |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 825 | for (i = 0; i < wiener_halfwin1 - 1; ++i) |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 826 | A[i] -= |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 827 | A[wiener_halfwin1 - 1] * 2 + |
| 828 | B[i * wiener_halfwin1 + wiener_halfwin1 - 1] - |
| 829 | 2 * B[(wiener_halfwin1 - 1) * wiener_halfwin1 + (wiener_halfwin1 - 1)]; |
| 830 | for (i = 0; i < wiener_halfwin1 - 1; ++i) |
| 831 | for (j = 0; j < wiener_halfwin1 - 1; ++j) |
| 832 | B[i * wiener_halfwin1 + j] -= |
| 833 | 2 * (B[i * wiener_halfwin1 + (wiener_halfwin1 - 1)] + |
| 834 | B[(wiener_halfwin1 - 1) * wiener_halfwin1 + j] - |
| 835 | 2 * B[(wiener_halfwin1 - 1) * wiener_halfwin1 + |
| 836 | (wiener_halfwin1 - 1)]); |
| 837 | if (linsolve(wiener_halfwin1 - 1, B, wiener_halfwin1, A, S)) { |
| 838 | S[wiener_halfwin1 - 1] = 1.0; |
| 839 | for (i = wiener_halfwin1; i < wiener_win; ++i) { |
| 840 | S[i] = S[wiener_win - 1 - i]; |
| 841 | S[wiener_halfwin1 - 1] -= 2 * S[i]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 842 | } |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 843 | memcpy(a, S, wiener_win * sizeof(*a)); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 844 | } |
| 845 | } |
| 846 | |
| 847 | // Fix vector a, update vector b |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 848 | static void update_b_sep_sym(int wiener_win, double **Mc, double **Hc, |
| 849 | double *a, double *b) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 850 | int i, j; |
Debargha Mukherjee | 999d2f6 | 2016-12-15 13:23:21 -0800 | [diff] [blame] | 851 | double S[WIENER_WIN]; |
Debargha Mukherjee | 6ae588f | 2017-04-14 00:40:02 -0700 | [diff] [blame] | 852 | double A[WIENER_HALFWIN1], B[WIENER_HALFWIN1 * WIENER_HALFWIN1]; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 853 | const int wiener_win2 = wiener_win * wiener_win; |
| 854 | const int wiener_halfwin1 = (wiener_win >> 1) + 1; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 855 | memset(A, 0, sizeof(A)); |
| 856 | memset(B, 0, sizeof(B)); |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 857 | for (i = 0; i < wiener_win; i++) { |
| 858 | const int ii = wrap_index(i, wiener_win); |
| 859 | for (j = 0; j < wiener_win; j++) A[ii] += Mc[i][j] * a[j]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 860 | } |
| 861 | |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 862 | for (i = 0; i < wiener_win; i++) { |
| 863 | for (j = 0; j < wiener_win; j++) { |
| 864 | const int ii = wrap_index(i, wiener_win); |
| 865 | const int jj = wrap_index(j, wiener_win); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 866 | int k, l; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 867 | for (k = 0; k < wiener_win; ++k) |
| 868 | for (l = 0; l < wiener_win; ++l) |
| 869 | B[jj * wiener_halfwin1 + ii] += |
| 870 | Hc[i * wiener_win + j][k * wiener_win2 + l] * a[k] * a[l]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 871 | } |
| 872 | } |
| 873 | // Normalization enforcement in the system of equations itself |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 874 | for (i = 0; i < wiener_halfwin1 - 1; ++i) |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 875 | A[i] -= |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 876 | A[wiener_halfwin1 - 1] * 2 + |
| 877 | B[i * wiener_halfwin1 + wiener_halfwin1 - 1] - |
| 878 | 2 * B[(wiener_halfwin1 - 1) * wiener_halfwin1 + (wiener_halfwin1 - 1)]; |
| 879 | for (i = 0; i < wiener_halfwin1 - 1; ++i) |
| 880 | for (j = 0; j < wiener_halfwin1 - 1; ++j) |
| 881 | B[i * wiener_halfwin1 + j] -= |
| 882 | 2 * (B[i * wiener_halfwin1 + (wiener_halfwin1 - 1)] + |
| 883 | B[(wiener_halfwin1 - 1) * wiener_halfwin1 + j] - |
| 884 | 2 * B[(wiener_halfwin1 - 1) * wiener_halfwin1 + |
| 885 | (wiener_halfwin1 - 1)]); |
| 886 | if (linsolve(wiener_halfwin1 - 1, B, wiener_halfwin1, A, S)) { |
| 887 | S[wiener_halfwin1 - 1] = 1.0; |
| 888 | for (i = wiener_halfwin1; i < wiener_win; ++i) { |
| 889 | S[i] = S[wiener_win - 1 - i]; |
| 890 | S[wiener_halfwin1 - 1] -= 2 * S[i]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 891 | } |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 892 | memcpy(b, S, wiener_win * sizeof(*b)); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 893 | } |
| 894 | } |
| 895 | |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 896 | static int wiener_decompose_sep_sym(int wiener_win, double *M, double *H, |
| 897 | double *a, double *b) { |
Debargha Mukherjee | 0c18b2c | 2017-05-15 21:15:30 -0700 | [diff] [blame] | 898 | static const int init_filt[WIENER_WIN] = { |
| 899 | WIENER_FILT_TAP0_MIDV, WIENER_FILT_TAP1_MIDV, WIENER_FILT_TAP2_MIDV, |
| 900 | WIENER_FILT_TAP3_MIDV, WIENER_FILT_TAP2_MIDV, WIENER_FILT_TAP1_MIDV, |
| 901 | WIENER_FILT_TAP0_MIDV, |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 902 | }; |
Debargha Mukherjee | 999d2f6 | 2016-12-15 13:23:21 -0800 | [diff] [blame] | 903 | double *Hc[WIENER_WIN2]; |
| 904 | double *Mc[WIENER_WIN]; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 905 | int i, j, iter; |
| 906 | const int plane_off = (WIENER_WIN - wiener_win) >> 1; |
| 907 | const int wiener_win2 = wiener_win * wiener_win; |
| 908 | for (i = 0; i < wiener_win; i++) { |
| 909 | a[i] = b[i] = (double)init_filt[i + plane_off] / WIENER_FILT_STEP; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 910 | } |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 911 | for (i = 0; i < wiener_win; i++) { |
| 912 | Mc[i] = M + i * wiener_win; |
| 913 | for (j = 0; j < wiener_win; j++) { |
| 914 | Hc[i * wiener_win + j] = |
| 915 | H + i * wiener_win * wiener_win2 + j * wiener_win; |
| 916 | } |
Debargha Mukherjee | 0c18b2c | 2017-05-15 21:15:30 -0700 | [diff] [blame] | 917 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 918 | |
| 919 | iter = 1; |
Debargha Mukherjee | 1b3dbf0 | 2017-03-13 14:47:21 -0700 | [diff] [blame] | 920 | while (iter < NUM_WIENER_ITERS) { |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 921 | update_a_sep_sym(wiener_win, Mc, Hc, a, b); |
| 922 | update_b_sep_sym(wiener_win, Mc, Hc, a, b); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 923 | iter++; |
| 924 | } |
| 925 | return 1; |
| 926 | } |
| 927 | |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 928 | // Computes the function x'*H*x - x'*M for the learned 2D filter x, and compares |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 929 | // against identity filters; Final score is defined as the difference between |
| 930 | // the function values |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 931 | static double compute_score(int wiener_win, double *M, double *H, |
| 932 | InterpKernel vfilt, InterpKernel hfilt) { |
Debargha Mukherjee | 999d2f6 | 2016-12-15 13:23:21 -0800 | [diff] [blame] | 933 | double ab[WIENER_WIN * WIENER_WIN]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 934 | int i, k, l; |
| 935 | double P = 0, Q = 0; |
| 936 | double iP = 0, iQ = 0; |
| 937 | double Score, iScore; |
Debargha Mukherjee | 999d2f6 | 2016-12-15 13:23:21 -0800 | [diff] [blame] | 938 | double a[WIENER_WIN], b[WIENER_WIN]; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 939 | const int plane_off = (WIENER_WIN - wiener_win) >> 1; |
| 940 | const int wiener_win2 = wiener_win * wiener_win; |
Jingning Han | 041c67b | 2017-04-14 21:39:26 -0700 | [diff] [blame] | 941 | |
| 942 | aom_clear_system_state(); |
| 943 | |
Debargha Mukherjee | 999d2f6 | 2016-12-15 13:23:21 -0800 | [diff] [blame] | 944 | a[WIENER_HALFWIN] = b[WIENER_HALFWIN] = 1.0; |
| 945 | for (i = 0; i < WIENER_HALFWIN; ++i) { |
| 946 | a[i] = a[WIENER_WIN - i - 1] = (double)vfilt[i] / WIENER_FILT_STEP; |
| 947 | b[i] = b[WIENER_WIN - i - 1] = (double)hfilt[i] / WIENER_FILT_STEP; |
| 948 | a[WIENER_HALFWIN] -= 2 * a[i]; |
| 949 | b[WIENER_HALFWIN] -= 2 * b[i]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 950 | } |
Debargha Mukherjee | a1a1e36 | 2017-10-04 20:01:03 -0700 | [diff] [blame] | 951 | memset(ab, 0, sizeof(ab)); |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 952 | for (k = 0; k < wiener_win; ++k) { |
| 953 | for (l = 0; l < wiener_win; ++l) |
| 954 | ab[k * wiener_win + l] = a[l + plane_off] * b[k + plane_off]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 955 | } |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 956 | for (k = 0; k < wiener_win2; ++k) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 957 | P += ab[k] * M[k]; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 958 | for (l = 0; l < wiener_win2; ++l) |
| 959 | Q += ab[k] * H[k * wiener_win2 + l] * ab[l]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 960 | } |
| 961 | Score = Q - 2 * P; |
| 962 | |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 963 | iP = M[wiener_win2 >> 1]; |
| 964 | iQ = H[(wiener_win2 >> 1) * wiener_win2 + (wiener_win2 >> 1)]; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 965 | iScore = iQ - 2 * iP; |
| 966 | |
| 967 | return Score - iScore; |
| 968 | } |
| 969 | |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 970 | static void quantize_sym_filter(int wiener_win, double *f, InterpKernel fi) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 971 | int i; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 972 | const int wiener_halfwin = (wiener_win >> 1); |
| 973 | for (i = 0; i < wiener_halfwin; ++i) { |
Debargha Mukherjee | 999d2f6 | 2016-12-15 13:23:21 -0800 | [diff] [blame] | 974 | fi[i] = RINT(f[i] * WIENER_FILT_STEP); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 975 | } |
| 976 | // Specialize for 7-tap filter |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 977 | if (wiener_win == WIENER_WIN) { |
| 978 | fi[0] = CLIP(fi[0], WIENER_FILT_TAP0_MINV, WIENER_FILT_TAP0_MAXV); |
| 979 | fi[1] = CLIP(fi[1], WIENER_FILT_TAP1_MINV, WIENER_FILT_TAP1_MAXV); |
| 980 | fi[2] = CLIP(fi[2], WIENER_FILT_TAP2_MINV, WIENER_FILT_TAP2_MAXV); |
| 981 | } else { |
| 982 | fi[2] = CLIP(fi[1], WIENER_FILT_TAP2_MINV, WIENER_FILT_TAP2_MAXV); |
| 983 | fi[1] = CLIP(fi[0], WIENER_FILT_TAP1_MINV, WIENER_FILT_TAP1_MAXV); |
| 984 | fi[0] = 0; |
| 985 | } |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 986 | // Satisfy filter constraints |
| 987 | fi[WIENER_WIN - 1] = fi[0]; |
| 988 | fi[WIENER_WIN - 2] = fi[1]; |
| 989 | fi[WIENER_WIN - 3] = fi[2]; |
David Barker | 1e8e6b9 | 2017-01-13 13:45:51 +0000 | [diff] [blame] | 990 | // The central element has an implicit +WIENER_FILT_STEP |
| 991 | fi[3] = -2 * (fi[0] + fi[1] + fi[2]); |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 992 | } |
| 993 | |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 994 | static int count_wiener_bits(int wiener_win, WienerInfo *wiener_info, |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 995 | WienerInfo *ref_wiener_info) { |
| 996 | int bits = 0; |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 997 | if (wiener_win == WIENER_WIN) |
| 998 | bits += aom_count_primitive_refsubexpfin( |
| 999 | WIENER_FILT_TAP0_MAXV - WIENER_FILT_TAP0_MINV + 1, |
| 1000 | WIENER_FILT_TAP0_SUBEXP_K, |
| 1001 | ref_wiener_info->vfilter[0] - WIENER_FILT_TAP0_MINV, |
| 1002 | wiener_info->vfilter[0] - WIENER_FILT_TAP0_MINV); |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1003 | bits += aom_count_primitive_refsubexpfin( |
| 1004 | WIENER_FILT_TAP1_MAXV - WIENER_FILT_TAP1_MINV + 1, |
| 1005 | WIENER_FILT_TAP1_SUBEXP_K, |
| 1006 | ref_wiener_info->vfilter[1] - WIENER_FILT_TAP1_MINV, |
| 1007 | wiener_info->vfilter[1] - WIENER_FILT_TAP1_MINV); |
| 1008 | bits += aom_count_primitive_refsubexpfin( |
| 1009 | WIENER_FILT_TAP2_MAXV - WIENER_FILT_TAP2_MINV + 1, |
| 1010 | WIENER_FILT_TAP2_SUBEXP_K, |
| 1011 | ref_wiener_info->vfilter[2] - WIENER_FILT_TAP2_MINV, |
| 1012 | wiener_info->vfilter[2] - WIENER_FILT_TAP2_MINV); |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 1013 | if (wiener_win == WIENER_WIN) |
| 1014 | bits += aom_count_primitive_refsubexpfin( |
| 1015 | WIENER_FILT_TAP0_MAXV - WIENER_FILT_TAP0_MINV + 1, |
| 1016 | WIENER_FILT_TAP0_SUBEXP_K, |
| 1017 | ref_wiener_info->hfilter[0] - WIENER_FILT_TAP0_MINV, |
| 1018 | wiener_info->hfilter[0] - WIENER_FILT_TAP0_MINV); |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1019 | bits += aom_count_primitive_refsubexpfin( |
| 1020 | WIENER_FILT_TAP1_MAXV - WIENER_FILT_TAP1_MINV + 1, |
| 1021 | WIENER_FILT_TAP1_SUBEXP_K, |
| 1022 | ref_wiener_info->hfilter[1] - WIENER_FILT_TAP1_MINV, |
| 1023 | wiener_info->hfilter[1] - WIENER_FILT_TAP1_MINV); |
| 1024 | bits += aom_count_primitive_refsubexpfin( |
| 1025 | WIENER_FILT_TAP2_MAXV - WIENER_FILT_TAP2_MINV + 1, |
| 1026 | WIENER_FILT_TAP2_SUBEXP_K, |
| 1027 | ref_wiener_info->hfilter[2] - WIENER_FILT_TAP2_MINV, |
| 1028 | wiener_info->hfilter[2] - WIENER_FILT_TAP2_MINV); |
| 1029 | return bits; |
| 1030 | } |
| 1031 | |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1032 | #define USE_WIENER_REFINEMENT_SEARCH 1 |
| 1033 | static int64_t finer_tile_search_wiener(const YV12_BUFFER_CONFIG *src, |
| 1034 | AV1_COMP *cpi, RestorationInfo *rsi, |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 1035 | int start_step, int plane, |
| 1036 | int wiener_win, int tile_idx, |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1037 | int partial_frame, |
| 1038 | YV12_BUFFER_CONFIG *dst_frame) { |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 1039 | const int plane_off = (WIENER_WIN - wiener_win) >> 1; |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1040 | int64_t err = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1041 | tile_idx, dst_frame); |
Debargha Mukherjee | 749f5cd | 2017-05-31 11:26:51 -0700 | [diff] [blame] | 1042 | (void)start_step; |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1043 | #if USE_WIENER_REFINEMENT_SEARCH |
| 1044 | int64_t err2; |
| 1045 | int tap_min[] = { WIENER_FILT_TAP0_MINV, WIENER_FILT_TAP1_MINV, |
| 1046 | WIENER_FILT_TAP2_MINV }; |
| 1047 | int tap_max[] = { WIENER_FILT_TAP0_MAXV, WIENER_FILT_TAP1_MAXV, |
| 1048 | WIENER_FILT_TAP2_MAXV }; |
| 1049 | // printf("err pre = %"PRId64"\n", err); |
Debargha Mukherjee | 0c18b2c | 2017-05-15 21:15:30 -0700 | [diff] [blame] | 1050 | for (int s = start_step; s >= 1; s >>= 1) { |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 1051 | for (int p = plane_off; p < WIENER_HALFWIN; ++p) { |
Debargha Mukherjee | 0c18b2c | 2017-05-15 21:15:30 -0700 | [diff] [blame] | 1052 | int skip = 0; |
| 1053 | do { |
| 1054 | if (rsi[plane].wiener_info[tile_idx].hfilter[p] - s >= tap_min[p]) { |
| 1055 | rsi[plane].wiener_info[tile_idx].hfilter[p] -= s; |
| 1056 | rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] -= s; |
| 1057 | rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] += 2 * s; |
| 1058 | err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1059 | tile_idx, dst_frame); |
Debargha Mukherjee | 0c18b2c | 2017-05-15 21:15:30 -0700 | [diff] [blame] | 1060 | if (err2 > err) { |
| 1061 | rsi[plane].wiener_info[tile_idx].hfilter[p] += s; |
| 1062 | rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] += s; |
| 1063 | rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] -= 2 * s; |
| 1064 | } else { |
| 1065 | err = err2; |
| 1066 | skip = 1; |
| 1067 | // At the highest step size continue moving in the same direction |
| 1068 | if (s == start_step) continue; |
| 1069 | } |
| 1070 | } |
| 1071 | break; |
| 1072 | } while (1); |
| 1073 | if (skip) break; |
| 1074 | do { |
| 1075 | if (rsi[plane].wiener_info[tile_idx].hfilter[p] + s <= tap_max[p]) { |
| 1076 | rsi[plane].wiener_info[tile_idx].hfilter[p] += s; |
| 1077 | rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] += s; |
| 1078 | rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] -= 2 * s; |
| 1079 | err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1080 | tile_idx, dst_frame); |
Debargha Mukherjee | 0c18b2c | 2017-05-15 21:15:30 -0700 | [diff] [blame] | 1081 | if (err2 > err) { |
| 1082 | rsi[plane].wiener_info[tile_idx].hfilter[p] -= s; |
| 1083 | rsi[plane].wiener_info[tile_idx].hfilter[WIENER_WIN - p - 1] -= s; |
| 1084 | rsi[plane].wiener_info[tile_idx].hfilter[WIENER_HALFWIN] += 2 * s; |
| 1085 | } else { |
| 1086 | err = err2; |
| 1087 | // At the highest step size continue moving in the same direction |
| 1088 | if (s == start_step) continue; |
| 1089 | } |
| 1090 | } |
| 1091 | break; |
| 1092 | } while (1); |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1093 | } |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 1094 | for (int p = plane_off; p < WIENER_HALFWIN; ++p) { |
Debargha Mukherjee | 0c18b2c | 2017-05-15 21:15:30 -0700 | [diff] [blame] | 1095 | int skip = 0; |
| 1096 | do { |
| 1097 | if (rsi[plane].wiener_info[tile_idx].vfilter[p] - s >= tap_min[p]) { |
| 1098 | rsi[plane].wiener_info[tile_idx].vfilter[p] -= s; |
| 1099 | rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] -= s; |
| 1100 | rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] += 2 * s; |
| 1101 | err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1102 | tile_idx, dst_frame); |
Debargha Mukherjee | 0c18b2c | 2017-05-15 21:15:30 -0700 | [diff] [blame] | 1103 | if (err2 > err) { |
| 1104 | rsi[plane].wiener_info[tile_idx].vfilter[p] += s; |
| 1105 | rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] += s; |
| 1106 | rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] -= 2 * s; |
| 1107 | } else { |
| 1108 | err = err2; |
| 1109 | skip = 1; |
| 1110 | // At the highest step size continue moving in the same direction |
| 1111 | if (s == start_step) continue; |
| 1112 | } |
| 1113 | } |
| 1114 | break; |
| 1115 | } while (1); |
| 1116 | if (skip) break; |
| 1117 | do { |
| 1118 | if (rsi[plane].wiener_info[tile_idx].vfilter[p] + s <= tap_max[p]) { |
| 1119 | rsi[plane].wiener_info[tile_idx].vfilter[p] += s; |
| 1120 | rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] += s; |
| 1121 | rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] -= 2 * s; |
| 1122 | err2 = try_restoration_tile(src, cpi, rsi, 1 << plane, partial_frame, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1123 | tile_idx, dst_frame); |
Debargha Mukherjee | 0c18b2c | 2017-05-15 21:15:30 -0700 | [diff] [blame] | 1124 | if (err2 > err) { |
| 1125 | rsi[plane].wiener_info[tile_idx].vfilter[p] -= s; |
| 1126 | rsi[plane].wiener_info[tile_idx].vfilter[WIENER_WIN - p - 1] -= s; |
| 1127 | rsi[plane].wiener_info[tile_idx].vfilter[WIENER_HALFWIN] += 2 * s; |
| 1128 | } else { |
| 1129 | err = err2; |
| 1130 | // At the highest step size continue moving in the same direction |
| 1131 | if (s == start_step) continue; |
| 1132 | } |
| 1133 | } |
| 1134 | break; |
| 1135 | } while (1); |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1136 | } |
| 1137 | } |
| 1138 | // printf("err post = %"PRId64"\n", err); |
| 1139 | #endif // USE_WIENER_REFINEMENT_SEARCH |
| 1140 | return err; |
| 1141 | } |
| 1142 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1143 | static void search_wiener_for_rtile(const struct rest_search_ctxt *ctxt, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1144 | int rtile_idx, |
| 1145 | const RestorationTileLimits *limits, |
| 1146 | void *arg) { |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1147 | const MACROBLOCK *const x = &ctxt->cpi->td.mb; |
| 1148 | const AV1_COMMON *const cm = &ctxt->cpi->common; |
| 1149 | RestorationInfo *rsi = ctxt->cpi->rst_search; |
| 1150 | |
| 1151 | const int wiener_win = |
| 1152 | (ctxt->plane == AOM_PLANE_Y) ? WIENER_WIN : WIENER_WIN_CHROMA; |
| 1153 | |
| 1154 | double M[WIENER_WIN2]; |
| 1155 | double H[WIENER_WIN2 * WIENER_WIN2]; |
| 1156 | double vfilterd[WIENER_WIN], hfilterd[WIENER_WIN]; |
| 1157 | |
| 1158 | WienerInfo *ref_wiener_info = (WienerInfo *)arg; |
| 1159 | |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1160 | int64_t err = |
| 1161 | sse_restoration_tile(ctxt->src, cm->frame_to_show, cm, limits->h_start, |
| 1162 | limits->h_end - limits->h_start, limits->v_start, |
| 1163 | limits->v_end - limits->v_start, (1 << ctxt->plane)); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1164 | // #bits when a tile is not restored |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 1165 | int bits = x->wiener_restore_cost[0]; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1166 | double cost_norestore = RDCOST_DBL(x->rdmult, (bits >> 4), err); |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 1167 | ctxt->best_tile_cost[rtile_idx] = INT64_MAX; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1168 | |
| 1169 | #if CONFIG_HIGHBITDEPTH |
| 1170 | if (cm->use_highbitdepth) |
| 1171 | compute_stats_highbd(wiener_win, ctxt->dgd_buffer, ctxt->src_buffer, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1172 | limits->h_start, limits->h_end, limits->v_start, |
| 1173 | limits->v_end, ctxt->dgd_stride, ctxt->src_stride, M, |
| 1174 | H); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1175 | else |
| 1176 | #endif // CONFIG_HIGHBITDEPTH |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1177 | compute_stats(wiener_win, ctxt->dgd_buffer, ctxt->src_buffer, |
| 1178 | limits->h_start, limits->h_end, limits->v_start, |
| 1179 | limits->v_end, ctxt->dgd_stride, ctxt->src_stride, M, H); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1180 | |
| 1181 | ctxt->type[rtile_idx] = RESTORE_WIENER; |
| 1182 | |
| 1183 | if (!wiener_decompose_sep_sym(wiener_win, M, H, vfilterd, hfilterd)) { |
| 1184 | ctxt->type[rtile_idx] = RESTORE_NONE; |
| 1185 | return; |
| 1186 | } |
| 1187 | |
| 1188 | RestorationInfo *plane_rsi = &rsi[ctxt->plane]; |
| 1189 | WienerInfo *rtile_wiener_info = &plane_rsi->wiener_info[rtile_idx]; |
| 1190 | quantize_sym_filter(wiener_win, vfilterd, rtile_wiener_info->vfilter); |
| 1191 | quantize_sym_filter(wiener_win, hfilterd, rtile_wiener_info->hfilter); |
| 1192 | |
| 1193 | // Filter score computes the value of the function x'*A*x - x'*b for the |
| 1194 | // learned filter and compares it against identity filer. If there is no |
| 1195 | // reduction in the function, the filter is reverted back to identity |
| 1196 | double score = compute_score(wiener_win, M, H, rtile_wiener_info->vfilter, |
| 1197 | rtile_wiener_info->hfilter); |
| 1198 | if (score > 0.0) { |
| 1199 | ctxt->type[rtile_idx] = RESTORE_NONE; |
| 1200 | return; |
| 1201 | } |
| 1202 | aom_clear_system_state(); |
| 1203 | |
| 1204 | plane_rsi->restoration_type[rtile_idx] = RESTORE_WIENER; |
| 1205 | err = finer_tile_search_wiener(ctxt->src, ctxt->cpi, rsi, 4, ctxt->plane, |
| 1206 | wiener_win, rtile_idx, ctxt->partial_frame, |
| 1207 | ctxt->dst_frame); |
| 1208 | if (wiener_win != WIENER_WIN) { |
| 1209 | assert(rtile_wiener_info->vfilter[0] == 0 && |
| 1210 | rtile_wiener_info->vfilter[WIENER_WIN - 1] == 0); |
| 1211 | assert(rtile_wiener_info->hfilter[0] == 0 && |
| 1212 | rtile_wiener_info->hfilter[WIENER_WIN - 1] == 0); |
| 1213 | } |
| 1214 | bits = count_wiener_bits(wiener_win, rtile_wiener_info, ref_wiener_info) |
| 1215 | << AV1_PROB_COST_SHIFT; |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 1216 | bits += x->wiener_restore_cost[1]; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1217 | double cost_wiener = RDCOST_DBL(x->rdmult, (bits >> 4), err); |
| 1218 | if (cost_wiener >= cost_norestore) { |
| 1219 | ctxt->type[rtile_idx] = RESTORE_NONE; |
| 1220 | } else { |
| 1221 | ctxt->type[rtile_idx] = RESTORE_WIENER; |
| 1222 | *ref_wiener_info = ctxt->info->wiener_info[rtile_idx] = *rtile_wiener_info; |
| 1223 | ctxt->best_tile_cost[rtile_idx] = err; |
| 1224 | } |
| 1225 | plane_rsi->restoration_type[rtile_idx] = RESTORE_NONE; |
| 1226 | } |
| 1227 | |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1228 | static double search_wiener(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi, |
| 1229 | int partial_frame, int plane, RestorationInfo *info, |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 1230 | RestorationType *type, int64_t *best_tile_cost, |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1231 | YV12_BUFFER_CONFIG *dst_frame) { |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 1232 | const MACROBLOCK *const x = &cpi->td.mb; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1233 | struct rest_search_ctxt ctxt; |
| 1234 | const int nrtiles = |
| 1235 | init_rest_search_ctxt(src, cpi, partial_frame, plane, info, type, |
| 1236 | best_tile_cost, dst_frame, &ctxt); |
| 1237 | |
| 1238 | RestorationInfo *plane_rsi = &cpi->rst_search[plane]; |
| 1239 | plane_rsi->frame_restoration_type = RESTORE_WIENER; |
| 1240 | for (int tile_idx = 0; tile_idx < nrtiles; ++tile_idx) { |
| 1241 | plane_rsi->restoration_type[tile_idx] = RESTORE_NONE; |
| 1242 | } |
| 1243 | |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 1244 | AV1_COMMON *const cm = &cpi->common; |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1245 | // Construct a (WIENER_HALFWIN)-pixel border around the frame |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 1246 | // Note use this border to gather stats even though the actual filter |
| 1247 | // may use less border on the top/bottom of a processing unit. |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1248 | #if CONFIG_HIGHBITDEPTH |
| 1249 | if (cm->use_highbitdepth) |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1250 | extend_frame_highbd(CONVERT_TO_SHORTPTR(ctxt.dgd_buffer), ctxt.plane_width, |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 1251 | ctxt.plane_height, ctxt.dgd_stride, WIENER_HALFWIN, |
| 1252 | WIENER_HALFWIN); |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1253 | else |
| 1254 | #endif |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1255 | extend_frame(ctxt.dgd_buffer, ctxt.plane_width, ctxt.plane_height, |
Debargha Mukherjee | 1330dfd | 2017-09-03 22:22:27 -0700 | [diff] [blame] | 1256 | ctxt.dgd_stride, WIENER_HALFWIN, WIENER_HALFWIN); |
Debargha Mukherjee | 994ccd7 | 2017-01-06 11:18:23 -0800 | [diff] [blame] | 1257 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1258 | // Compute best Wiener filters for each rtile, one (encoder/decoder) |
| 1259 | // tile at a time. |
| 1260 | for (int tile_row = 0; tile_row < cm->tile_rows; ++tile_row) { |
| 1261 | for (int tile_col = 0; tile_col < cm->tile_cols; ++tile_col) { |
| 1262 | WienerInfo ref_wiener_info; |
| 1263 | set_default_wiener(&ref_wiener_info); |
Debargha Mukherjee | 994ccd7 | 2017-01-06 11:18:23 -0800 | [diff] [blame] | 1264 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1265 | foreach_rtile_in_tile(&ctxt, tile_row, tile_col, search_wiener_for_rtile, |
| 1266 | &ref_wiener_info); |
David Barker | 33f3bfd | 2017-01-06 15:34:50 +0000 | [diff] [blame] | 1267 | } |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 1268 | } |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1269 | |
| 1270 | // cost for Wiener filtering |
| 1271 | WienerInfo ref_wiener_info; |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1272 | set_default_wiener(&ref_wiener_info); |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1273 | int bits = frame_level_restore_bits[plane_rsi->frame_restoration_type] |
| 1274 | << AV1_PROB_COST_SHIFT; |
| 1275 | WienerInfo *wiener_info = info->wiener_info; |
| 1276 | const int wiener_win = |
| 1277 | (plane == AOM_PLANE_Y) ? WIENER_WIN : WIENER_WIN_CHROMA; |
| 1278 | |
| 1279 | for (int tile_idx = 0; tile_idx < nrtiles; ++tile_idx) { |
Debargha Mukherjee | bc732ef | 2017-10-12 12:40:25 -0700 | [diff] [blame] | 1280 | bits += x->wiener_restore_cost[type[tile_idx] != RESTORE_NONE]; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1281 | plane_rsi->wiener_info[tile_idx] = wiener_info[tile_idx]; |
| 1282 | |
Debargha Mukherjee | 994ccd7 | 2017-01-06 11:18:23 -0800 | [diff] [blame] | 1283 | if (type[tile_idx] == RESTORE_WIENER) { |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1284 | bits += count_wiener_bits(wiener_win, &plane_rsi->wiener_info[tile_idx], |
Debargha Mukherjee | 1cb757c | 2017-08-21 02:46:31 -0700 | [diff] [blame] | 1285 | &ref_wiener_info) |
| 1286 | << AV1_PROB_COST_SHIFT; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1287 | ref_wiener_info = plane_rsi->wiener_info[tile_idx]; |
Debargha Mukherjee | 994ccd7 | 2017-01-06 11:18:23 -0800 | [diff] [blame] | 1288 | } |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1289 | plane_rsi->restoration_type[tile_idx] = type[tile_idx]; |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 1290 | } |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1291 | int64_t err = try_restoration_frame(src, cpi, cpi->rst_search, 1 << plane, |
| 1292 | partial_frame, dst_frame); |
| 1293 | double cost_wiener = RDCOST_DBL(cpi->td.mb.rdmult, (bits >> 4), err); |
Debargha Mukherjee | 8f209a8 | 2016-10-12 10:47:01 -0700 | [diff] [blame] | 1294 | |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1295 | return cost_wiener; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1296 | } |
| 1297 | |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1298 | static double search_norestore(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi, |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1299 | int partial_frame, int plane, |
| 1300 | RestorationInfo *info, RestorationType *type, |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 1301 | int64_t *best_tile_cost, |
David Barker | 9666e75 | 2016-12-08 11:25:47 +0000 | [diff] [blame] | 1302 | YV12_BUFFER_CONFIG *dst_frame) { |
Debargha Mukherjee | d23ceea | 2017-05-18 20:33:52 -0700 | [diff] [blame] | 1303 | int64_t err; |
| 1304 | double cost_norestore; |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1305 | int bits; |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 1306 | MACROBLOCK *x = &cpi->td.mb; |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1307 | AV1_COMMON *const cm = &cpi->common; |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 1308 | int tile_idx, nhtiles, nvtiles; |
| 1309 | |
| 1310 | const int is_uv = plane > 0; |
| 1311 | const int ss_y = plane > 0 && cm->subsampling_y; |
| 1312 | const int width = src->crop_widths[is_uv]; |
| 1313 | const int height = src->crop_heights[is_uv]; |
| 1314 | |
| 1315 | const int rtile_size = cm->rst_info[plane].restoration_tilesize; |
| 1316 | |
| 1317 | const int ntiles = |
| 1318 | av1_get_rest_ntiles(width, height, rtile_size, &nhtiles, &nvtiles); |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1319 | (void)info; |
David Barker | 9666e75 | 2016-12-08 11:25:47 +0000 | [diff] [blame] | 1320 | (void)dst_frame; |
Debargha Mukherjee | 00c5433 | 2017-03-03 15:44:17 -0800 | [diff] [blame] | 1321 | (void)partial_frame; |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 1322 | |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1323 | info->frame_restoration_type = RESTORE_NONE; |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 1324 | for (tile_idx = 0; tile_idx < ntiles; ++tile_idx) { |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1325 | RestorationTileLimits limits = av1_get_rest_tile_limits( |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 1326 | tile_idx, nhtiles, nvtiles, rtile_size, width, height, ss_y); |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1327 | err = sse_restoration_tile(src, cm->frame_to_show, cm, limits.h_start, |
| 1328 | limits.h_end - limits.h_start, limits.v_start, |
| 1329 | limits.v_end - limits.v_start, 1 << plane); |
Debargha Mukherjee | 994ccd7 | 2017-01-06 11:18:23 -0800 | [diff] [blame] | 1330 | type[tile_idx] = RESTORE_NONE; |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1331 | best_tile_cost[tile_idx] = err; |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1332 | } |
| 1333 | // RD cost associated with no restoration |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1334 | err = sse_restoration_frame(cm, src, cm->frame_to_show, (1 << plane)); |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1335 | bits = frame_level_restore_bits[RESTORE_NONE] << AV1_PROB_COST_SHIFT; |
Urvang Joshi | 70006e4 | 2017-06-14 16:08:55 -0700 | [diff] [blame] | 1336 | cost_norestore = RDCOST_DBL(x->rdmult, (bits >> 4), err); |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1337 | return cost_norestore; |
| 1338 | } |
| 1339 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1340 | struct switchable_rest_search_ctxt { |
| 1341 | SgrprojInfo sgrproj_info; |
| 1342 | WienerInfo wiener_info; |
| 1343 | RestorationType *const *restore_types; |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 1344 | int64_t *const *tile_cost; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1345 | double cost_switchable; |
| 1346 | }; |
| 1347 | |
| 1348 | static void search_switchable_for_rtile(const struct rest_search_ctxt *ctxt, |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1349 | int rtile_idx, |
| 1350 | const RestorationTileLimits *limits, |
| 1351 | void *arg) { |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1352 | const MACROBLOCK *x = &ctxt->cpi->td.mb; |
| 1353 | RestorationInfo *rsi = &ctxt->cpi->common.rst_info[ctxt->plane]; |
| 1354 | struct switchable_rest_search_ctxt *swctxt = |
| 1355 | (struct switchable_rest_search_ctxt *)arg; |
| 1356 | |
Rupert Swarbrick | 5d2e729 | 2017-09-26 11:32:17 +0100 | [diff] [blame] | 1357 | (void)limits; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1358 | |
| 1359 | double best_cost = |
| 1360 | RDCOST_DBL(x->rdmult, (x->switchable_restore_cost[RESTORE_NONE] >> 4), |
| 1361 | swctxt->tile_cost[RESTORE_NONE][rtile_idx]); |
| 1362 | rsi->restoration_type[rtile_idx] = RESTORE_NONE; |
| 1363 | for (RestorationType r = 1; r < RESTORE_SWITCHABLE_TYPES; r++) { |
Debargha Mukherjee | 1b4ccc2 | 2017-09-30 13:33:03 -0700 | [diff] [blame] | 1364 | if (force_restore_type != RESTORE_TYPES) |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1365 | if (r != force_restore_type) continue; |
| 1366 | int tilebits = 0; |
| 1367 | if (swctxt->restore_types[r][rtile_idx] != r) continue; |
| 1368 | if (r == RESTORE_WIENER) |
| 1369 | tilebits += count_wiener_bits( |
| 1370 | (ctxt->plane == AOM_PLANE_Y ? WIENER_WIN : WIENER_WIN - 2), |
| 1371 | &rsi->wiener_info[rtile_idx], &swctxt->wiener_info); |
| 1372 | else if (r == RESTORE_SGRPROJ) |
| 1373 | tilebits += count_sgrproj_bits(&rsi->sgrproj_info[rtile_idx], |
| 1374 | &swctxt->sgrproj_info); |
| 1375 | tilebits <<= AV1_PROB_COST_SHIFT; |
| 1376 | tilebits += x->switchable_restore_cost[r]; |
| 1377 | double cost = |
| 1378 | RDCOST_DBL(x->rdmult, tilebits >> 4, swctxt->tile_cost[r][rtile_idx]); |
| 1379 | |
| 1380 | if (cost < best_cost) { |
| 1381 | rsi->restoration_type[rtile_idx] = r; |
| 1382 | best_cost = cost; |
| 1383 | } |
| 1384 | } |
| 1385 | if (rsi->restoration_type[rtile_idx] == RESTORE_WIENER) |
| 1386 | swctxt->wiener_info = rsi->wiener_info[rtile_idx]; |
| 1387 | else if (rsi->restoration_type[rtile_idx] == RESTORE_SGRPROJ) |
| 1388 | swctxt->sgrproj_info = rsi->sgrproj_info[rtile_idx]; |
Debargha Mukherjee | 1b4ccc2 | 2017-09-30 13:33:03 -0700 | [diff] [blame] | 1389 | if (force_restore_type != RESTORE_TYPES) |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1390 | assert(rsi->restoration_type[rtile_idx] == force_restore_type || |
| 1391 | rsi->restoration_type[rtile_idx] == RESTORE_NONE); |
| 1392 | swctxt->cost_switchable += best_cost; |
| 1393 | } |
| 1394 | |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1395 | static double search_switchable_restoration( |
Debargha Mukherjee | 2dd982e | 2017-06-05 13:55:12 -0700 | [diff] [blame] | 1396 | const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi, int partial_frame, int plane, |
Debargha Mukherjee | 6f0566e | 2017-06-23 13:15:33 -0700 | [diff] [blame] | 1397 | RestorationType *const restore_types[RESTORE_SWITCHABLE_TYPES], |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 1398 | int64_t *const tile_cost[RESTORE_SWITCHABLE_TYPES], RestorationInfo *rsi) { |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1399 | const AV1_COMMON *const cm = &cpi->common; |
| 1400 | struct rest_search_ctxt ctxt; |
| 1401 | init_rest_search_ctxt(src, cpi, partial_frame, plane, NULL, NULL, NULL, NULL, |
| 1402 | &ctxt); |
| 1403 | struct switchable_rest_search_ctxt swctxt; |
| 1404 | swctxt.restore_types = restore_types; |
| 1405 | swctxt.tile_cost = tile_cost; |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1406 | |
| 1407 | rsi->frame_restoration_type = RESTORE_SWITCHABLE; |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1408 | int bits = frame_level_restore_bits[rsi->frame_restoration_type] |
| 1409 | << AV1_PROB_COST_SHIFT; |
| 1410 | swctxt.cost_switchable = RDCOST_DBL(cpi->td.mb.rdmult, bits >> 4, 0); |
Debargha Mukherjee | cfc12f3 | 2017-04-18 07:03:32 -0700 | [diff] [blame] | 1411 | |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1412 | for (int tile_row = 0; tile_row < cm->tile_rows; ++tile_row) { |
| 1413 | for (int tile_col = 0; tile_col < cm->tile_cols; ++tile_col) { |
| 1414 | set_default_sgrproj(&swctxt.sgrproj_info); |
| 1415 | set_default_wiener(&swctxt.wiener_info); |
| 1416 | foreach_rtile_in_tile(&ctxt, tile_row, tile_col, |
| 1417 | search_switchable_for_rtile, &swctxt); |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 1418 | } |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 1419 | } |
Rupert Swarbrick | 09b5b16 | 2017-08-31 16:32:29 +0100 | [diff] [blame] | 1420 | |
| 1421 | return swctxt.cost_switchable; |
Debargha Mukherjee | 5cd2ab9 | 2016-09-08 15:15:17 -0700 | [diff] [blame] | 1422 | } |
| 1423 | |
| 1424 | void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *src, AV1_COMP *cpi, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1425 | LPF_PICK_METHOD method) { |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1426 | static search_restore_type search_restore_fun[RESTORE_SWITCHABLE_TYPES] = { |
Debargha Mukherjee | 4bfd72e | 2017-03-08 22:20:31 -0800 | [diff] [blame] | 1427 | search_norestore, search_wiener, search_sgrproj, |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1428 | }; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 1429 | AV1_COMMON *const cm = &cpi->common; |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1430 | double cost_restore[RESTORE_TYPES]; |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 1431 | int64_t *tile_cost[RESTORE_SWITCHABLE_TYPES]; |
Debargha Mukherjee | 994ccd7 | 2017-01-06 11:18:23 -0800 | [diff] [blame] | 1432 | RestorationType *restore_types[RESTORE_SWITCHABLE_TYPES]; |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1433 | double best_cost_restore; |
| 1434 | RestorationType r, best_restore; |
Debargha Mukherjee | 2dd982e | 2017-06-05 13:55:12 -0700 | [diff] [blame] | 1435 | const int ywidth = src->y_crop_width; |
| 1436 | const int yheight = src->y_crop_height; |
| 1437 | const int uvwidth = src->uv_crop_width; |
| 1438 | const int uvheight = src->uv_crop_height; |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1439 | |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 1440 | const int ntiles_y = av1_get_rest_ntiles( |
| 1441 | ywidth, yheight, cm->rst_info[0].restoration_tilesize, NULL, NULL); |
Debargha Mukherjee | d23ceea | 2017-05-18 20:33:52 -0700 | [diff] [blame] | 1442 | const int ntiles_uv = av1_get_rest_ntiles( |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 1443 | uvwidth, uvheight, cm->rst_info[1].restoration_tilesize, NULL, NULL); |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1444 | |
| 1445 | // Assume ntiles_uv is never larger that ntiles_y and so the same arrays work. |
Rupert Swarbrick | 64b8bbd | 2017-10-16 15:53:07 +0100 | [diff] [blame^] | 1446 | assert(ntiles_uv <= ntiles_y); |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1447 | for (r = 0; r < RESTORE_SWITCHABLE_TYPES; r++) { |
Debargha Mukherjee | 0c65e0a | 2017-10-08 09:19:39 -0700 | [diff] [blame] | 1448 | tile_cost[r] = (int64_t *)aom_malloc(sizeof(*tile_cost[0]) * ntiles_y); |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1449 | restore_types[r] = |
| 1450 | (RestorationType *)aom_malloc(sizeof(*restore_types[0]) * ntiles_y); |
| 1451 | } |
| 1452 | |
| 1453 | for (int plane = AOM_PLANE_Y; plane <= AOM_PLANE_V; ++plane) { |
| 1454 | for (r = 0; r < RESTORE_SWITCHABLE_TYPES; ++r) { |
| 1455 | cost_restore[r] = DBL_MAX; |
Tom Finegan | 8af64ae | 2017-09-07 08:13:06 -0700 | [diff] [blame] | 1456 | if (force_restore_type != RESTORE_TYPES) |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1457 | if (r != RESTORE_NONE && r != force_restore_type) continue; |
| 1458 | cost_restore[r] = |
| 1459 | search_restore_fun[r](src, cpi, method == LPF_PICK_FROM_SUBIMAGE, |
| 1460 | plane, &cm->rst_info[plane], restore_types[r], |
| 1461 | tile_cost[r], &cpi->trial_frame_rst); |
| 1462 | } |
| 1463 | if (plane == AOM_PLANE_Y) |
Debargha Mukherjee | 2dd982e | 2017-06-05 13:55:12 -0700 | [diff] [blame] | 1464 | cost_restore[RESTORE_SWITCHABLE] = search_switchable_restoration( |
Debargha Mukherjee | 6f0566e | 2017-06-23 13:15:33 -0700 | [diff] [blame] | 1465 | src, cpi, method == LPF_PICK_FROM_SUBIMAGE, plane, restore_types, |
| 1466 | tile_cost, &cm->rst_info[plane]); |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1467 | else |
| 1468 | cost_restore[RESTORE_SWITCHABLE] = DBL_MAX; |
| 1469 | best_cost_restore = DBL_MAX; |
| 1470 | best_restore = 0; |
| 1471 | for (r = 0; r < RESTORE_TYPES; ++r) { |
Tom Finegan | 8af64ae | 2017-09-07 08:13:06 -0700 | [diff] [blame] | 1472 | if (force_restore_type != RESTORE_TYPES) |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1473 | if (r != RESTORE_NONE && r != force_restore_type) continue; |
| 1474 | if (cost_restore[r] < best_cost_restore) { |
| 1475 | best_restore = r; |
| 1476 | best_cost_restore = cost_restore[r]; |
| 1477 | } |
| 1478 | } |
| 1479 | cm->rst_info[plane].frame_restoration_type = best_restore; |
Tom Finegan | 8af64ae | 2017-09-07 08:13:06 -0700 | [diff] [blame] | 1480 | if (force_restore_type != RESTORE_TYPES) |
Debargha Mukherjee | d48f573 | 2017-05-19 14:58:07 -0700 | [diff] [blame] | 1481 | assert(best_restore == force_restore_type || |
| 1482 | best_restore == RESTORE_NONE); |
| 1483 | if (best_restore != RESTORE_SWITCHABLE) { |
| 1484 | const int nt = (plane == AOM_PLANE_Y ? ntiles_y : ntiles_uv); |
| 1485 | memcpy(cm->rst_info[plane].restoration_type, restore_types[best_restore], |
| 1486 | nt * sizeof(restore_types[best_restore][0])); |
Debargha Mukherjee | d23ceea | 2017-05-18 20:33:52 -0700 | [diff] [blame] | 1487 | } |
| 1488 | } |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1489 | /* |
Debargha Mukherjee | e39e2ee | 2017-05-11 03:38:03 -0700 | [diff] [blame] | 1490 | printf("Frame %d/%d restore types: %d %d %d\n", cm->current_video_frame, |
| 1491 | cm->show_frame, cm->rst_info[0].frame_restoration_type, |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 1492 | cm->rst_info[1].frame_restoration_type, |
| 1493 | cm->rst_info[2].frame_restoration_type); |
Debargha Mukherjee | b3c43bc | 2017-02-01 13:09:03 -0800 | [diff] [blame] | 1494 | printf("Frame %d/%d frame_restore_type %d : %f %f %f %f\n", |
| 1495 | cm->current_video_frame, cm->show_frame, |
| 1496 | cm->rst_info[0].frame_restoration_type, cost_restore[0], |
| 1497 | cost_restore[1], cost_restore[2], cost_restore[3]); |
Debargha Mukherjee | 5d89a63 | 2016-09-17 13:16:58 -0700 | [diff] [blame] | 1498 | */ |
Debargha Mukherjee | a43a2d9 | 2017-01-03 15:14:57 -0800 | [diff] [blame] | 1499 | |
Debargha Mukherjee | 994ccd7 | 2017-01-06 11:18:23 -0800 | [diff] [blame] | 1500 | for (r = 0; r < RESTORE_SWITCHABLE_TYPES; r++) { |
| 1501 | aom_free(tile_cost[r]); |
| 1502 | aom_free(restore_types[r]); |
| 1503 | } |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1504 | } |