vp9_picklpf.c revision 5ae7ac49f08a179e4f054d99fcfc9dce78d26e58
1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/*
2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Use of this source code is governed by a BSD-style license
5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  that can be found in the LICENSE file in the root of the source
6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  tree. An additional intellectual property rights grant can be found
7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  in the file PATENTS.  All contributing project authors may
8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  be found in the AUTHORS file in the root of the source tree.
9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <assert.h>
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <limits.h>
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_onyxc_int.h"
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_onyx_int.h"
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_picklpf.h"
16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_quantize.h"
17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_mem/vpx_mem.h"
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_scale/vpx_scale.h"
19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_alloccommon.h"
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_loopfilter.h"
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "./vpx_scale_rtcd.h"
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_yv12_copy_partial_frame_c(YV12_BUFFER_CONFIG *src_ybc,
241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                   YV12_BUFFER_CONFIG *dst_ybc, int fraction) {
251184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int height = src_ybc->y_height;
261184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int stride = src_ybc->y_stride;
271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int offset = stride * ((height >> 5) * 16 - 8);
281184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int lines_to_copy = MAX(height >> (fraction + 4), 1) << 4;
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  assert(src_ybc->y_stride == dst_ybc->y_stride);
311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  vpx_memcpy(dst_ybc->y_buffer + offset, src_ybc->y_buffer + offset,
321184aebb761cbeac9124c37189a80a1a58f04b6bhkuang             stride * (lines_to_copy + 16));
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int calc_partial_ssl_err(YV12_BUFFER_CONFIG *source,
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                YV12_BUFFER_CONFIG *dest, int Fraction) {
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int Total = 0;
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int srcoffset, dstoffset;
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *src = source->y_buffer;
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *dst = dest->y_buffer;
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int linestocopy = (source->y_height >> (Fraction + 4));
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (linestocopy < 1)
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    linestocopy = 1;
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  linestocopy <<= 4;
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  srcoffset = source->y_stride   * (dest->y_height >> 5) * 16;
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dstoffset = dest->y_stride     * (dest->y_height >> 5) * 16;
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  src += srcoffset;
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  dst += dstoffset;
56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
575ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // Loop through the raw Y plane and reconstruction data summing the square
585ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // differences.
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < linestocopy; i += 16) {
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < source->y_width; j += 16) {
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      unsigned int sse;
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      Total += vp9_mse16x16(src + j, source->y_stride, dst + j, dest->y_stride,
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            &sse);
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    src += 16 * source->y_stride;
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    dst += 16 * dest->y_stride;
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return Total;
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// Enforce a minimum filter level based upon baseline Q
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int get_min_filter_level(VP9_COMP *cpi, int base_qindex) {
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int min_filter_level;
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  min_filter_level = 0;
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return min_filter_level;
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// Enforce a maximum filter level based upon baseline Q
82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int get_max_filter_level(VP9_COMP *cpi, int base_qindex) {
835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int max_filter_level = MAX_LOOP_FILTER;
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  (void)base_qindex;
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cpi->twopass.section_intra_rating > 8)
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    max_filter_level = MAX_LOOP_FILTER * 3 / 4;
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return max_filter_level;
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang// Stub function for now Alt LF not used
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_set_alt_lf_level(VP9_COMP *cpi, int filt_val) {
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
971184aebb761cbeac9124c37189a80a1a58f04b6bhkuangvoid vp9_pick_filter_level(YV12_BUFFER_CONFIG *sd, VP9_COMP *cpi, int partial) {
981184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  VP9_COMMON *const cm = &cpi->common;
991184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  struct loopfilter *const lf = &cm->lf;
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int best_err = 0;
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int filt_err = 0;
1031184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int min_filter_level = get_min_filter_level(cpi, cm->base_qindex);
1041184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  const int max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int filter_step;
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int filt_high = 0;
10891037db265ecdd914a26e056cf69207b4f50924ehkuang  // Start search at previous frame filter level
10991037db265ecdd914a26e056cf69207b4f50924ehkuang  int filt_mid = lf->filter_level;
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int filt_low = 0;
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int filt_best;
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int filt_direction = 0;
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1145ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  int Bias = 0;  // Bias against raising loop filter in favor of lowering it.
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  //  Make a copy of the unfiltered / processed recon buffer
1171184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  vpx_yv12_copy_y(cm->frame_to_show, &cpi->last_frame_uf);
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1191184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  lf->sharpness_level = cm->frame_type == KEY_FRAME ? 0
1201184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                                    : cpi->oxcf.Sharpness;
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1225ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // Start the search at the previous frame filter level unless it is now out of
1235ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  // range.
1241184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  filt_mid = clamp(lf->filter_level, min_filter_level, max_filter_level);
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Define the initial step size
1271184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  filter_step = filt_mid < 16 ? 4 : filt_mid / 4;
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Get baseline error score
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_set_alt_lf_level(cpi, filt_mid);
1311184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  vp9_loop_filter_frame(cm, &cpi->mb.e_mbd, filt_mid, 1, partial);
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  best_err = vp9_calc_ss_err(sd, cm->frame_to_show);
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  filt_best = filt_mid;
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  //  Re-instate the unfiltered frame
1371184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show);
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  while (filter_step > 0) {
1405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    Bias = (best_err >> (15 - (filt_mid / 8))) * filter_step;
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cpi->twopass.section_intra_rating < 20)
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      Bias = Bias * cpi->twopass.section_intra_rating / 20;
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // yx, bias less for large block size
14691037db265ecdd914a26e056cf69207b4f50924ehkuang    if (cpi->common.tx_mode != ONLY_4X4)
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      Bias >>= 1;
148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    filt_high = ((filt_mid + filter_step) > max_filter_level)
1505ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    ? max_filter_level
1515ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                    : (filt_mid + filter_step);
1525ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    filt_low = ((filt_mid - filter_step) < min_filter_level)
1535ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   ? min_filter_level
1545ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                   : (filt_mid - filter_step);
155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if ((filt_direction <= 0) && (filt_low != filt_mid)) {
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Get Low filter error score
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp9_set_alt_lf_level(cpi, filt_low);
1591184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      vp9_loop_filter_frame(cm, &cpi->mb.e_mbd, filt_low, 1, partial);
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      filt_err = vp9_calc_ss_err(sd, cm->frame_to_show);
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      //  Re-instate the unfiltered frame
1641184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show);
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1665ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // If value is close to the best so far then bias towards a lower loop
1675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      // filter value.
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if ((filt_err - Bias) < best_err) {
169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        // Was it actually better than the previous best?
170ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (filt_err < best_err)
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          best_err = filt_err;
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        filt_best = filt_low;
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Now look at filt_high
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if ((filt_direction >= 0) && (filt_high != filt_mid)) {
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vp9_set_alt_lf_level(cpi, filt_high);
1801184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      vp9_loop_filter_frame(cm, &cpi->mb.e_mbd, filt_high, 1, partial);
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      filt_err = vp9_calc_ss_err(sd, cm->frame_to_show);
183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      //  Re-instate the unfiltered frame
1851184aebb761cbeac9124c37189a80a1a58f04b6bhkuang      vpx_yv12_copy_y(&cpi->last_frame_uf, cm->frame_to_show);
186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Was it better than the previous best?
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (filt_err < (best_err - Bias)) {
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        best_err = filt_err;
190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        filt_best = filt_high;
191ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Half the step distance if the best filter value was the same as last time
195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (filt_best == filt_mid) {
196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      filter_step = filter_step / 2;
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      filt_direction = 0;
198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      filt_direction = (filt_best < filt_mid) ? -1 : 1;
200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      filt_mid = filt_best;
201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
20491037db265ecdd914a26e056cf69207b4f50924ehkuang  lf->filter_level = filt_best;
205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
206