restoration.h 8.45 KB
Newer Older
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3
 *
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 11
 */

Yaowu Xu's avatar
Yaowu Xu committed
12 13
#ifndef AV1_COMMON_RESTORATION_H_
#define AV1_COMMON_RESTORATION_H_
14

15
#include "aom_ports/mem.h"
Yaowu Xu's avatar
Yaowu Xu committed
16
#include "./aom_config.h"
17

18
#include "av1/common/blockd.h"
19 20 21 22 23

#ifdef __cplusplus
extern "C" {
#endif

24 25 26
#define CLIP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x))
#define RINT(x) ((x) < 0 ? (int)((x)-0.5) : (int)((x) + 0.5))

27 28 29 30 31
#define RESTORATION_TILESIZE_SML 128
#define RESTORATION_TILESIZE_BIG 256
#define RESTORATION_TILEPELS_MAX \
  (RESTORATION_TILESIZE_BIG * RESTORATION_TILESIZE_BIG * 9 / 4)

32 33 34 35 36 37 38 39 40
#define DOMAINTXFMRF_PARAMS_BITS 6
#define DOMAINTXFMRF_PARAMS (1 << DOMAINTXFMRF_PARAMS_BITS)
#define DOMAINTXFMRF_SIGMA_SCALEBITS 4
#define DOMAINTXFMRF_SIGMA_SCALE (1 << DOMAINTXFMRF_SIGMA_SCALEBITS)
#define DOMAINTXFMRF_ITERS 3
#define DOMAINTXFMRF_VTABLE_PRECBITS 8
#define DOMAINTXFMRF_VTABLE_PREC (1 << DOMAINTXFMRF_VTABLE_PRECBITS)
#define DOMAINTXFMRF_MULT \
  sqrt(((1 << (DOMAINTXFMRF_ITERS * 2)) - 1) * 2.0 / 3.0)
41 42
// A single 32 bit buffer needed for the filter
#define DOMAINTXFMRF_TMPBUF_SIZE (RESTORATION_TILEPELS_MAX * sizeof(int32_t))
43 44
#define DOMAINTXFMRF_BITS (DOMAINTXFMRF_PARAMS_BITS)

45 46 47 48 49
// 6 highprecision 64-bit buffers needed for the filter:
// 1 for the degraded frame, 2 for the restored versions and
// 3 for each restoration operation
// TODO(debargha): Explore if we can use 32-bit buffers
#define SGRPROJ_TMPBUF_SIZE (RESTORATION_TILEPELS_MAX * 6 * sizeof(int64_t))
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
#define SGRPROJ_PARAMS_BITS 3
#define SGRPROJ_PARAMS (1 << SGRPROJ_PARAMS_BITS)

// Precision bits for projection
#define SGRPROJ_PRJ_BITS 7
// Restoration precision bits generated higher than source before projection
#define SGRPROJ_RST_BITS 4
// Internal precision bits for core selfguided_restoration
#define SGRPROJ_SGR_BITS 8
#define SGRPROJ_SGR (1 << SGRPROJ_SGR_BITS)

#define SGRPROJ_PRJ_MIN0 (-(1 << SGRPROJ_PRJ_BITS) / 4)
#define SGRPROJ_PRJ_MAX0 (SGRPROJ_PRJ_MIN0 + (1 << SGRPROJ_PRJ_BITS) - 1)
#define SGRPROJ_PRJ_MIN1 (-(1 << SGRPROJ_PRJ_BITS) / 4)
#define SGRPROJ_PRJ_MAX1 (SGRPROJ_PRJ_MIN1 + (1 << SGRPROJ_PRJ_BITS) - 1)

#define SGRPROJ_BITS (SGRPROJ_PRJ_BITS * 2 + SGRPROJ_PARAMS_BITS)

68 69 70
// Max of SGRPROJ_TMPBUF_SIZE and DOMAINTXFMRF_TMPBUF_SIZE
#define RESTORATION_TMPBUF_SIZE (SGRPROJ_TMPBUF_SIZE)

clang-format's avatar
clang-format committed
71 72 73 74
#define RESTORATION_HALFWIN 3
#define RESTORATION_HALFWIN1 (RESTORATION_HALFWIN + 1)
#define RESTORATION_WIN (2 * RESTORATION_HALFWIN + 1)
#define RESTORATION_WIN2 ((RESTORATION_WIN) * (RESTORATION_WIN))
75

76 77
#define RESTORATION_FILT_BITS 7
#define RESTORATION_FILT_STEP (1 << RESTORATION_FILT_BITS)
78

79
#define WIENER_FILT_TAP0_MINV (-5)
clang-format's avatar
clang-format committed
80
#define WIENER_FILT_TAP1_MINV (-23)
81
#define WIENER_FILT_TAP2_MINV (-16)
82

clang-format's avatar
clang-format committed
83 84 85
#define WIENER_FILT_TAP0_BITS 4
#define WIENER_FILT_TAP1_BITS 5
#define WIENER_FILT_TAP2_BITS 6
86

87 88 89
#define WIENER_FILT_BITS \
  ((WIENER_FILT_TAP0_BITS + WIENER_FILT_TAP1_BITS + WIENER_FILT_TAP2_BITS) * 2)

90
#define WIENER_FILT_TAP0_MAXV \
clang-format's avatar
clang-format committed
91
  (WIENER_FILT_TAP0_MINV - 1 + (1 << WIENER_FILT_TAP0_BITS))
92
#define WIENER_FILT_TAP1_MAXV \
clang-format's avatar
clang-format committed
93
  (WIENER_FILT_TAP1_MINV - 1 + (1 << WIENER_FILT_TAP1_BITS))
94
#define WIENER_FILT_TAP2_MAXV \
clang-format's avatar
clang-format committed
95
  (WIENER_FILT_TAP2_MINV - 1 + (1 << WIENER_FILT_TAP2_BITS))
96

97 98 99 100 101
typedef struct {
  int level;
  int vfilter[RESTORATION_WIN], hfilter[RESTORATION_WIN];
} WienerInfo;

102 103 104 105 106 107 108 109 110 111 112 113 114
typedef struct {
  int r1;
  int e1;
  int r2;
  int e2;
} sgr_params_type;

typedef struct {
  int level;
  int ep;
  int xqd[2];
} SgrprojInfo;

115 116 117 118 119
typedef struct {
  int level;
  int sigma_r;
} DomaintxfmrfInfo;

120
typedef struct {
121 122
  RestorationType frame_restoration_type;
  RestorationType *restoration_type;
123
  // Wiener filter
124
  WienerInfo *wiener_info;
125 126
  // Selfguided proj filter
  SgrprojInfo *sgrproj_info;
127 128
  // Domain transform filter
  DomaintxfmrfInfo *domaintxfmrf_info;
129
} RestorationInfo;
130

131
typedef struct {
132 133
  RestorationInfo *rsi;
  int keyframe;
134 135 136 137 138
  int subsampling_x;
  int subsampling_y;
  int ntiles;
  int tile_width, tile_height;
  int nhtiles, nvtiles;
139
  uint8_t *tmpbuf;
140
} RestorationInternal;
141

142 143 144 145 146 147 148
static INLINE int get_rest_tilesize(int width, int height) {
  if (width * height <= 352 * 288)
    return RESTORATION_TILESIZE_SML;
  else
    return RESTORATION_TILESIZE_BIG;
}

149 150 151
static INLINE int av1_get_rest_ntiles(int width, int height, int *tile_width,
                                      int *tile_height, int *nhtiles,
                                      int *nvtiles) {
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
  int nhtiles_, nvtiles_;
  int tile_width_, tile_height_;
  int tilesize = get_rest_tilesize(width, height);
  tile_width_ = (tilesize < 0) ? width : AOMMIN(tilesize, width);
  tile_height_ = (tilesize < 0) ? height : AOMMIN(tilesize, height);
  nhtiles_ = (width + (tile_width_ >> 1)) / tile_width_;
  nvtiles_ = (height + (tile_height_ >> 1)) / tile_height_;
  if (tile_width) *tile_width = tile_width_;
  if (tile_height) *tile_height = tile_height_;
  if (nhtiles) *nhtiles = nhtiles_;
  if (nvtiles) *nvtiles = nvtiles_;
  return (nhtiles_ * nvtiles_);
}

static INLINE void av1_get_rest_tile_limits(
    int tile_idx, int subtile_idx, int subtile_bits, int nhtiles, int nvtiles,
    int tile_width, int tile_height, int im_width, int im_height, int clamp_h,
    int clamp_v, int *h_start, int *h_end, int *v_start, int *v_end) {
  const int htile_idx = tile_idx % nhtiles;
  const int vtile_idx = tile_idx / nhtiles;
  *h_start = htile_idx * tile_width;
  *v_start = vtile_idx * tile_height;
  *h_end = (htile_idx < nhtiles - 1) ? *h_start + tile_width : im_width;
  *v_end = (vtile_idx < nvtiles - 1) ? *v_start + tile_height : im_height;
  if (subtile_bits) {
    const int num_subtiles_1d = (1 << subtile_bits);
    const int subtile_width = (*h_end - *h_start) >> subtile_bits;
    const int subtile_height = (*v_end - *v_start) >> subtile_bits;
    const int subtile_idx_h = subtile_idx & (num_subtiles_1d - 1);
    const int subtile_idx_v = subtile_idx >> subtile_bits;
    *h_start += subtile_idx_h * subtile_width;
    *v_start += subtile_idx_v * subtile_height;
    *h_end = subtile_idx_h == num_subtiles_1d - 1 ? *h_end
                                                  : *h_start + subtile_width;
    *v_end = subtile_idx_v == num_subtiles_1d - 1 ? *v_end
                                                  : *v_start + subtile_height;
  }
  if (clamp_h) {
    *h_start = AOMMAX(*h_start, RESTORATION_HALFWIN);
    *h_end = AOMMIN(*h_end, im_width - RESTORATION_HALFWIN);
  }
  if (clamp_v) {
    *v_start = AOMMAX(*v_start, RESTORATION_HALFWIN);
    *v_end = AOMMIN(*v_end, im_height - RESTORATION_HALFWIN);
  }
}

199 200
extern const sgr_params_type sgr_params[SGRPROJ_PARAMS];

201 202 203 204
int av1_alloc_restoration_struct(RestorationInfo *rst_info, int width,
                                 int height);
void av1_free_restoration_struct(RestorationInfo *rst_info);

205 206
void av1_selfguided_restoration(int64_t *dgd, int width, int height, int stride,
                                int bit_depth, int r, int eps, void *tmpbuf);
207
void av1_domaintxfmrf_restoration(uint8_t *dgd, int width, int height,
208
                                  int stride, int param, uint8_t *dst,
209
                                  int dst_stride, int32_t *tmpbuf);
210 211
#if CONFIG_AOM_HIGHBITDEPTH
void av1_domaintxfmrf_restoration_highbd(uint16_t *dgd, int width, int height,
212
                                         int stride, int param, int bit_depth,
213 214
                                         uint16_t *dst, int dst_stride,
                                         int32_t *tmpbuf);
215
#endif  // CONFIG_AOM_HIGHBITDEPTH
216
void decode_xq(int *xqd, int *xq);
Yaowu Xu's avatar
Yaowu Xu committed
217 218 219 220
void av1_loop_restoration_init(RestorationInternal *rst, RestorationInfo *rsi,
                               int kf, int width, int height);
void av1_loop_restoration_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
                                RestorationInfo *rsi, int y_only,
221
                                int partial_frame, YV12_BUFFER_CONFIG *dst);
Yaowu Xu's avatar
Yaowu Xu committed
222
void av1_loop_restoration_rows(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
223 224
                               int start_mi_row, int end_mi_row, int y_only,
                               YV12_BUFFER_CONFIG *dst);
Yaowu Xu's avatar
Yaowu Xu committed
225
void av1_loop_restoration_precal();
226 227 228 229
#ifdef __cplusplus
}  // extern "C"
#endif

Yaowu Xu's avatar
Yaowu Xu committed
230
#endif  // AV1_COMMON_RESTORATION_H_