picklpf.c 13.5 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>
#include <limits.h>

#include "./vpx_scale_rtcd.h"

16
#include "vpx_dsp/vpx_dsp_common.h"
Jingning Han's avatar
Jingning Han committed
17
18
19
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"

20
21
22
#include "vp10/common/loopfilter.h"
#include "vp10/common/onyxc_int.h"
#include "vp10/common/quant_common.h"
Jingning Han's avatar
Jingning Han committed
23

24
25
26
#include "vp10/encoder/encoder.h"
#include "vp10/encoder/picklpf.h"
#include "vp10/encoder/quantize.h"
Jingning Han's avatar
Jingning Han committed
27

Yaowu Xu's avatar
Yaowu Xu committed
28
static int get_max_filter_level(const VP10_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
29
30
31
32
33
34
35
36
  if (cpi->oxcf.pass == 2) {
    return cpi->twopass.section_intra_rating > 8 ? MAX_LOOP_FILTER * 3 / 4
                                                 : MAX_LOOP_FILTER;
  } else {
    return MAX_LOOP_FILTER;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
37
38
#if !CONFIG_LOOP_RESTORATION
#if !JOINT_FILTER_RESTORATION_SEARCH
Jingning Han's avatar
Jingning Han committed
39
static int64_t try_filter_frame(const YV12_BUFFER_CONFIG *sd,
Yaowu Xu's avatar
Yaowu Xu committed
40
                                VP10_COMP *const cpi,
Jingning Han's avatar
Jingning Han committed
41
                                int filt_level, int partial_frame) {
Yaowu Xu's avatar
Yaowu Xu committed
42
  VP10_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
43
44
  int64_t filt_err;

Jingning Han's avatar
Jingning Han committed
45
46
#if CONFIG_VAR_TX
  vp10_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filt_level,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
47
                         1, partial_frame);
Jingning Han's avatar
Jingning Han committed
48
#else
Jingning Han's avatar
Jingning Han committed
49
50
  if (cpi->num_workers > 1)
    vp10_loop_filter_frame_mt(cm->frame_to_show, cm, cpi->td.mb.e_mbd.plane,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
51
52
53
                              filt_level, 1, partial_frame,
                              cpi->workers, cpi->num_workers,
                              &cpi->lf_row_sync);
Jingning Han's avatar
Jingning Han committed
54
55
  else
    vp10_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filt_level,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
56
                           1, partial_frame);
Jingning Han's avatar
Jingning Han committed
57
#endif
Jingning Han's avatar
Jingning Han committed
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

#if CONFIG_VP9_HIGHBITDEPTH
  if (cm->use_highbitdepth) {
    filt_err = vp10_highbd_get_y_sse(sd, cm->frame_to_show);
  } else {
    filt_err = vp10_get_y_sse(sd, cm->frame_to_show);
  }
#else
  filt_err = vp10_get_y_sse(sd, cm->frame_to_show);
#endif  // CONFIG_VP9_HIGHBITDEPTH

  // Re-instate the unfiltered frame
  vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show);

  return filt_err;
}
Yaowu Xu's avatar
Yaowu Xu committed
74
75
#endif
#endif
Jingning Han's avatar
Jingning Han committed
76

Debargha Mukherjee's avatar
Debargha Mukherjee committed
77
#if CONFIG_LOOP_RESTORATION
78
#define JOINT_FILTER_RESTORATION_SEARCH
Debargha Mukherjee's avatar
Debargha Mukherjee committed
79
#define USE_RD_LOOP_POSTFILTER_SEARCH
80
81
82
83
static int try_restoration_frame(const YV12_BUFFER_CONFIG *sd,
                                 VP10_COMP *const cpi,
                                 int restoration_level,
                                 int partial_frame) {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
84
85
  VP10_COMMON *const cm = &cpi->common;
  int filt_err;
86
87
  vp10_loop_restoration_frame(cm->frame_to_show, cm,
                              restoration_level, 1, partial_frame);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#if CONFIG_VP9_HIGHBITDEPTH
  if (cm->use_highbitdepth) {
    filt_err = vp10_highbd_get_y_sse(sd, cm->frame_to_show);
  } else {
    filt_err = vp10_get_y_sse(sd, cm->frame_to_show);
  }
#else
  filt_err = vp10_get_y_sse(sd, cm->frame_to_show);
#endif  // CONFIG_VP9_HIGHBITDEPTH

  // Re-instate the unfiltered frame
  vpx_yv12_copy_y(&cpi->last_frame_db, cm->frame_to_show);
  return filt_err;
}

103
104
105
106
static int search_restoration_level(const YV12_BUFFER_CONFIG *sd,
                                    VP10_COMP *cpi,
                                    int filter_level, int partial_frame,
                                    double *best_cost_ret) {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
107
  VP10_COMMON *const cm = &cpi->common;
108
  int i, restoration_best, err;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
109
110
  double best_cost;
  double cost;
111
112
  const int restoration_level_bits = vp10_restoration_level_bits(&cpi->common);
  const int restoration_levels = 1 << restoration_level_bits;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
113
114
115
116
117
118
119
120
121
122
123
#ifdef USE_RD_LOOP_POSTFILTER_SEARCH
  MACROBLOCK *x = &cpi->td.mb;
  int bits;
#endif

  //  Make a copy of the unfiltered / processed recon buffer
  vpx_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf);
  vp10_loop_filter_frame(cm->frame_to_show, cm, &cpi->td.mb.e_mbd, filter_level,
                         1, partial_frame);
  vpx_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_db);

124
125
  restoration_best = 0;
  err = try_restoration_frame(sd, cpi, 0, partial_frame);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
126
#ifdef USE_RD_LOOP_POSTFILTER_SEARCH
127
  bits = cm->lf.last_restoration_level == 0 ? 0 : restoration_level_bits;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
128
129
130
131
132
  cost = RDCOST_DBL(x->rdmult, x->rddiv, (bits << 2), err);
#else
  cost = (double)err;
#endif  // USE_RD_LOOP_POSTFILTER_SEARCH
  best_cost = cost;
133
134
  for (i = 1; i <= restoration_levels; ++i) {
    err = try_restoration_frame(sd, cpi, i, partial_frame);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
135
136
137
138
#ifdef USE_RD_LOOP_POSTFILTER_SEARCH
    // Normally the rate is rate in bits * 256 and dist is sum sq err * 64
    // when RDCOST is used.  However below we just scale both in the correct
    // ratios appropriately but not exactly by these values.
139
    bits = cm->lf.last_restoration_level == i ? 0 : restoration_level_bits;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
140
141
142
143
144
    cost = RDCOST_DBL(x->rdmult, x->rddiv, (bits << 2), err);
#else
    cost = (double)err;
#endif  // USE_RD_LOOP_POSTFILTER_SEARCH
    if (cost < best_cost) {
145
      restoration_best = i;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
146
147
148
149
150
      best_cost = cost;
    }
  }
  if (best_cost_ret) *best_cost_ret = best_cost;
  vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show);
151
  return restoration_best;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
152
153
}

154
155
156
157
158
#ifdef JOINT_FILTER_RESTORATION_SEARCH
static int search_filter_restoration_level(const YV12_BUFFER_CONFIG *sd,
                                           VP10_COMP *cpi,
                                           int partial_frame,
                                           int *restoration_level) {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
159
160
161
162
163
  const VP10_COMMON *const cm = &cpi->common;
  const struct loopfilter *const lf = &cm->lf;
  const int min_filter_level = 0;
  const int max_filter_level = get_max_filter_level(cpi);
  int filt_direction = 0;
164
  int filt_best, restoration_best;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
165
166
167
168
169
170
171
172
173
174
175
176
177
178
  double best_err;
  int i;

  // Start the search at the previous frame filter level unless it is now out of
  // range.
  int filt_mid = clamp(lf->filter_level, min_filter_level, max_filter_level);
  int filter_step = filt_mid < 16 ? 4 : filt_mid / 4;
  double ss_err[MAX_LOOP_FILTER + 1];
  int bilateral;

  // Set each entry to -1
  for (i = 0; i <= MAX_LOOP_FILTER; ++i)
    ss_err[i] = -1.0;

179
180
  bilateral = search_restoration_level(sd, cpi, filt_mid,
                                       partial_frame, &best_err);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
181
  filt_best = filt_mid;
182
  restoration_best = bilateral;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  ss_err[filt_mid] = best_err;

  while (filter_step > 0) {
    const int filt_high = VPXMIN(filt_mid + filter_step, max_filter_level);
    const int filt_low = VPXMAX(filt_mid - filter_step, min_filter_level);

    // Bias against raising loop filter in favor of lowering it.
    double bias = (best_err / (1 << (15 - (filt_mid / 8)))) * filter_step;

    if ((cpi->oxcf.pass == 2) && (cpi->twopass.section_intra_rating < 20))
      bias = (bias * cpi->twopass.section_intra_rating) / 20;

    // yx, bias less for large block size
    if (cm->tx_mode != ONLY_4X4)
      bias /= 2;

    if (filt_direction <= 0 && filt_low != filt_mid) {
      // Get Low filter error score
      if (ss_err[filt_low] < 0) {
202
203
204
        bilateral = search_restoration_level(sd, cpi, filt_low,
                                             partial_frame,
                                             &ss_err[filt_low]);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
205
206
207
208
209
210
211
212
213
214
      }
      // If value is close to the best so far then bias towards a lower loop
      // filter value.
      if ((ss_err[filt_low] - bias) < best_err) {
        // Was it actually better than the previous best?
        if (ss_err[filt_low] < best_err) {
          best_err = ss_err[filt_low];
        }

        filt_best = filt_low;
215
        restoration_best = bilateral;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
216
217
218
219
220
221
      }
    }

    // Now look at filt_high
    if (filt_direction >= 0 && filt_high != filt_mid) {
      if (ss_err[filt_high] < 0) {
222
223
        bilateral = search_restoration_level(sd, cpi, filt_high, partial_frame,
                                             &ss_err[filt_high]);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
224
225
226
227
228
      }
      // Was it better than the previous best?
      if (ss_err[filt_high] < (best_err - bias)) {
        best_err = ss_err[filt_high];
        filt_best = filt_high;
229
        restoration_best = bilateral;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
230
231
232
233
234
235
236
237
238
239
240
241
      }
    }

    // Half the step distance if the best filter value was the same as last time
    if (filt_best == filt_mid) {
      filter_step /= 2;
      filt_direction = 0;
    } else {
      filt_direction = (filt_best < filt_mid) ? -1 : 1;
      filt_mid = filt_best;
    }
  }
242
  *restoration_level = restoration_best;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
243
244
  return filt_best;
}
245
#endif  // JOINT_FILTER_RESTORATION_SEARCH
Debargha Mukherjee's avatar
Debargha Mukherjee committed
246
247
#endif  // CONFIG_LOOP_RESTORATION

Yaowu Xu's avatar
Yaowu Xu committed
248
249
#if !CONFIG_LOOP_RESTORATION
#if !JOINT_FILTER_RESTORATION_SEARCH
Yaowu Xu's avatar
Yaowu Xu committed
250
static int search_filter_level(const YV12_BUFFER_CONFIG *sd, VP10_COMP *cpi,
Jingning Han's avatar
Jingning Han committed
251
                               int partial_frame) {
Yaowu Xu's avatar
Yaowu Xu committed
252
  const VP10_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
  const struct loopfilter *const lf = &cm->lf;
  const int min_filter_level = 0;
  const int max_filter_level = get_max_filter_level(cpi);
  int filt_direction = 0;
  int64_t best_err;
  int filt_best;

  // Start the search at the previous frame filter level unless it is now out of
  // range.
  int filt_mid = clamp(lf->filter_level, min_filter_level, max_filter_level);
  int filter_step = filt_mid < 16 ? 4 : filt_mid / 4;
  // Sum squared error at each filter level
  int64_t ss_err[MAX_LOOP_FILTER + 1];

  // Set each entry to -1
  memset(ss_err, 0xFF, sizeof(ss_err));

  //  Make a copy of the unfiltered / processed recon buffer
  vpx_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf);

  best_err = try_filter_frame(sd, cpi, filt_mid, partial_frame);
  filt_best = filt_mid;
  ss_err[filt_mid] = best_err;

  while (filter_step > 0) {
278
279
    const int filt_high = VPXMIN(filt_mid + filter_step, max_filter_level);
    const int filt_low = VPXMAX(filt_mid - filter_step, min_filter_level);
Jingning Han's avatar
Jingning Han committed
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

    // Bias against raising loop filter in favor of lowering it.
    int64_t bias = (best_err >> (15 - (filt_mid / 8))) * filter_step;

    if ((cpi->oxcf.pass == 2) && (cpi->twopass.section_intra_rating < 20))
      bias = (bias * cpi->twopass.section_intra_rating) / 20;

    // yx, bias less for large block size
    if (cm->tx_mode != ONLY_4X4)
      bias >>= 1;

    if (filt_direction <= 0 && filt_low != filt_mid) {
      // Get Low filter error score
      if (ss_err[filt_low] < 0) {
        ss_err[filt_low] = try_filter_frame(sd, cpi, filt_low, partial_frame);
      }
      // If value is close to the best so far then bias towards a lower loop
      // filter value.
      if ((ss_err[filt_low] - bias) < best_err) {
        // Was it actually better than the previous best?
        if (ss_err[filt_low] < best_err)
          best_err = ss_err[filt_low];

        filt_best = filt_low;
      }
    }

    // Now look at filt_high
    if (filt_direction >= 0 && filt_high != filt_mid) {
      if (ss_err[filt_high] < 0) {
        ss_err[filt_high] = try_filter_frame(sd, cpi, filt_high, partial_frame);
      }
      // Was it better than the previous best?
      if (ss_err[filt_high] < (best_err - bias)) {
        best_err = ss_err[filt_high];
        filt_best = filt_high;
      }
    }

    // Half the step distance if the best filter value was the same as last time
    if (filt_best == filt_mid) {
      filter_step /= 2;
      filt_direction = 0;
    } else {
      filt_direction = (filt_best < filt_mid) ? -1 : 1;
      filt_mid = filt_best;
    }
  }

  return filt_best;
}
Yaowu Xu's avatar
Yaowu Xu committed
331
332
#endif
#endif
Jingning Han's avatar
Jingning Han committed
333

Yaowu Xu's avatar
Yaowu Xu committed
334
void vp10_pick_filter_level(const YV12_BUFFER_CONFIG *sd, VP10_COMP *cpi,
Jingning Han's avatar
Jingning Han committed
335
                           LPF_PICK_METHOD method) {
Yaowu Xu's avatar
Yaowu Xu committed
336
  VP10_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
  struct loopfilter *const lf = &cm->lf;

  lf->sharpness_level = cm->frame_type == KEY_FRAME ? 0
                                                    : cpi->oxcf.sharpness;

  if (method == LPF_PICK_MINIMAL_LPF && lf->filter_level) {
      lf->filter_level = 0;
  } else if (method >= LPF_PICK_FROM_Q) {
    const int min_filter_level = 0;
    const int max_filter_level = get_max_filter_level(cpi);
    const int q = vp10_ac_quant(cm->base_qindex, 0, cm->bit_depth);
    // These values were determined by linear fitting the result of the
    // searched level, filt_guess = q * 0.316206 + 3.87252
#if CONFIG_VP9_HIGHBITDEPTH
    int filt_guess;
    switch (cm->bit_depth) {
      case VPX_BITS_8:
        filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 1015158, 18);
        break;
      case VPX_BITS_10:
        filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 4060632, 20);
        break;
      case VPX_BITS_12:
        filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 16242526, 22);
        break;
      default:
        assert(0 && "bit_depth should be VPX_BITS_8, VPX_BITS_10 "
                    "or VPX_BITS_12");
        return;
    }
#else
    int filt_guess = ROUND_POWER_OF_TWO(q * 20723 + 1015158, 18);
#endif  // CONFIG_VP9_HIGHBITDEPTH
    if (cm->frame_type == KEY_FRAME)
      filt_guess -= 4;
    lf->filter_level = clamp(filt_guess, min_filter_level, max_filter_level);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
373
#if CONFIG_LOOP_RESTORATION
374
    lf->restoration_level = search_restoration_level(
Debargha Mukherjee's avatar
Debargha Mukherjee committed
375
376
        sd, cpi, lf->filter_level, method == LPF_PICK_FROM_SUBIMAGE, NULL);
#endif  // CONFIG_LOOP_RESTORATION
Jingning Han's avatar
Jingning Han committed
377
  } else {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
378
#if CONFIG_LOOP_RESTORATION
379
380
381
#ifdef JOINT_FILTER_RESTORATION_SEARCH
    lf->filter_level = search_filter_restoration_level(
        sd, cpi, method == LPF_PICK_FROM_SUBIMAGE, &lf->restoration_level);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
382
383
384
#else
    lf->filter_level = search_filter_level(
        sd, cpi, method == LPF_PICK_FROM_SUBIMAGE);
385
    lf->restoration_level = search_restoration_level(
Debargha Mukherjee's avatar
Debargha Mukherjee committed
386
        sd, cpi, lf->filter_level, method == LPF_PICK_FROM_SUBIMAGE, NULL);
387
#endif  // JOINT_FILTER_RESTORATION_SEARCH
Debargha Mukherjee's avatar
Debargha Mukherjee committed
388
389
390
391
#else
    lf->filter_level = search_filter_level(
        sd, cpi, method == LPF_PICK_FROM_SUBIMAGE);
#endif  // CONFIG_LOOP_RESTORATION
Jingning Han's avatar
Jingning Han committed
392
393
  }
}