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 <math.h>
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <limits.h>
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_onyxc_int.h"
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_reconinter.h"
16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_onyx_int.h"
17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_systemdependent.h"
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_quantize.h"
19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_alloccommon.h"
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_mcomp.h"
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_firstpass.h"
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_psnr.h"
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_scale/vpx_scale.h"
24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_extend.h"
25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_ratectrl.h"
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_quant_common.h"
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_segmentation.h"
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_mem/vpx_mem.h"
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_ports/vpx_timer.h"
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define ALT_REF_MC_ENABLED 1    // dis/enable MC in AltRef filtering
325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#define ALT_REF_SUBPEL_ENABLED 1  // dis/enable subpel in MC AltRef filtering
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void temporal_filter_predictors_mb_c(MACROBLOCKD *xd,
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                            uint8_t *y_mb_ptr,
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                            uint8_t *u_mb_ptr,
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                            uint8_t *v_mb_ptr,
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                            int stride,
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                            int mv_row,
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                            int mv_col,
415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                            uint8_t *pred,
425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                            struct scale_factors *scale) {
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int which_mv = 0;
44f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang  MV mv = { mv_row, mv_col };
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vp9_build_inter_predictor(y_mb_ptr, stride,
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            &pred[0], 16,
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            &mv,
495ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                            scale,
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            16, 16,
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                            which_mv,
5291037db265ecdd914a26e056cf69207b4f50924ehkuang                            &xd->subpix, MV_PRECISION_Q3);
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  stride = (stride + 1) >> 1;
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
5691037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_build_inter_predictor(u_mb_ptr, stride,
5791037db265ecdd914a26e056cf69207b4f50924ehkuang                            &pred[256], 8,
5891037db265ecdd914a26e056cf69207b4f50924ehkuang                            &mv,
595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                            scale,
6091037db265ecdd914a26e056cf69207b4f50924ehkuang                            8, 8,
6191037db265ecdd914a26e056cf69207b4f50924ehkuang                            which_mv,
6291037db265ecdd914a26e056cf69207b4f50924ehkuang                            &xd->subpix, MV_PRECISION_Q4);
6391037db265ecdd914a26e056cf69207b4f50924ehkuang
6491037db265ecdd914a26e056cf69207b4f50924ehkuang  vp9_build_inter_predictor(v_mb_ptr, stride,
6591037db265ecdd914a26e056cf69207b4f50924ehkuang                            &pred[320], 8,
6691037db265ecdd914a26e056cf69207b4f50924ehkuang                            &mv,
675ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                            scale,
6891037db265ecdd914a26e056cf69207b4f50924ehkuang                            8, 8,
6991037db265ecdd914a26e056cf69207b4f50924ehkuang                            which_mv,
7091037db265ecdd914a26e056cf69207b4f50924ehkuang                            &xd->subpix, MV_PRECISION_Q4);
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_temporal_filter_apply_c(uint8_t *frame1,
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 unsigned int stride,
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 uint8_t *frame2,
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 unsigned int block_size,
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int strength,
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 int filter_weight,
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 unsigned int *accumulator,
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 uint16_t *count) {
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int i, j, k;
82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int modifier;
83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int byte = 0;
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0, k = 0; i < block_size; i++) {
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < block_size; j++, k++) {
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int src_byte = frame1[byte];
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int pixel_value = *frame2++;
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      modifier   = src_byte - pixel_value;
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // This is an integer approximation of:
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // float coeff = (3.0 * modifer * modifier) / pow(2, strength);
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // modifier =  (int)roundf(coeff > 16 ? 0 : 16-coeff);
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      modifier  *= modifier;
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      modifier  *= 3;
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      modifier  += 1 << (strength - 1);
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      modifier >>= strength;
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (modifier > 16)
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        modifier = 16;
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      modifier = 16 - modifier;
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      modifier *= filter_weight;
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      count[k] += modifier;
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      accumulator[k] += modifier * pixel_value;
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      byte++;
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    byte += stride - block_size;
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if ALT_REF_MC_ENABLED
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic int temporal_filter_find_matching_mb_c(VP9_COMP *cpi,
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              uint8_t *arf_frame_buf,
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              uint8_t *frame_ptr_buf,
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              int stride,
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              int error_thresh) {
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCK *x = &cpi->mb;
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD* const xd = &x->e_mbd;
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int step_param;
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int sadpb = x->sadperbit16;
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int bestsme = INT_MAX;
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv best_ref_mv1;
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int_mv *ref_mv;
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Save input state
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct buf_2d src = x->plane[0].src;
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  struct buf_2d pre = xd->plane[0].pre[0];
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  best_ref_mv1.as_int = 0;
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  best_ref_mv1_full.as_mv.col = best_ref_mv1.as_mv.col >> 3;
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  best_ref_mv1_full.as_mv.row = best_ref_mv1.as_mv.row >> 3;
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Setup frame pointers
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->plane[0].src.buf = arf_frame_buf;
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->plane[0].src.stride = stride;
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  xd->plane[0].pre[0].buf = frame_ptr_buf;
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  xd->plane[0].pre[0].stride = stride;
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Further step/diamond searches as necessary
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cpi->speed < 8)
14891037db265ecdd914a26e056cf69207b4f50924ehkuang    step_param = cpi->sf.reduce_first_step_size + ((cpi->speed > 5) ? 1 : 0);
149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else
15091037db265ecdd914a26e056cf69207b4f50924ehkuang    step_param = cpi->sf.reduce_first_step_size + 2;
15191037db265ecdd914a26e056cf69207b4f50924ehkuang  step_param = MIN(step_param, (cpi->sf.max_step_search_steps - 2));
152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /*cpi->sf.search_method == HEX*/
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Ignore mv costing by sending NULL pointer instead of cost arrays
1551184aebb761cbeac9124c37189a80a1a58f04b6bhkuang  ref_mv = &x->e_mbd.mi_8x8[0]->bmi[0].as_mv[0];
1565ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  bestsme = vp9_hex_search(x, &best_ref_mv1_full.as_mv,
1571184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                           step_param, sadpb, 1,
1581184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                           &cpi->fn_ptr[BLOCK_16X16],
1595ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                           0, &best_ref_mv1.as_mv, &ref_mv->as_mv);
160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
161ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if ALT_REF_SUBPEL_ENABLED
162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Try sub-pixel MC?
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // if (bestsme > error_thresh && bestsme < INT_MAX)
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  {
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int distortion;
166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    unsigned int sse;
167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Ignore mv costing by sending NULL pointer instead of cost array
1685ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang    bestsme = cpi->find_fractional_mv_step(x, &ref_mv->as_mv,
1695ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                           &best_ref_mv1.as_mv,
1705ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                           cpi->common.allow_high_precision_mv,
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           x->errorperbit,
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           &cpi->fn_ptr[BLOCK_16X16],
1731184aebb761cbeac9124c37189a80a1a58f04b6bhkuang                                           0, cpi->sf.subpel_iters_per_step,
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           NULL, NULL,
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           &distortion, &sse);
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
179ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Restore input state
180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  x->plane[0].src = src;
181ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  xd->plane[0].pre[0] = pre;
182ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return bestsme;
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
187ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void temporal_filter_iterate_c(VP9_COMP *cpi,
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                      int frame_count,
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                      int alt_ref_index,
1905ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      int strength,
1915ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                                      struct scale_factors *scale) {
192ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int byte;
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int frame;
194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mb_col, mb_row;
195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int filter_weight;
196ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mb_cols = cpi->common.mb_cols;
197ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mb_rows = cpi->common.mb_rows;
198ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mb_y_offset = 0;
199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int mb_uv_offset = 0;
200ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  DECLARE_ALIGNED_ARRAY(16, unsigned int, accumulator, 16 * 16 + 8 * 8 + 8 * 8);
201ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  DECLARE_ALIGNED_ARRAY(16, uint16_t, count, 16 * 16 + 8 * 8 + 8 * 8);
202ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  MACROBLOCKD *mbd = &cpi->mb.e_mbd;
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  YV12_BUFFER_CONFIG *f = cpi->frames[alt_ref_index];
204ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t *dst1, *dst2;
205ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  DECLARE_ALIGNED_ARRAY(16, uint8_t,  predictor, 16 * 16 + 8 * 8 + 8 * 8);
206ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Save input state
208ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  uint8_t* input_buffer[MAX_MB_PLANE];
209ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i;
210ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < MAX_MB_PLANE; i++)
212ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    input_buffer[i] = mbd->plane[i].pre[0].buf;
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (mb_row = 0; mb_row < mb_rows; mb_row++) {
215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if ALT_REF_MC_ENABLED
216ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Source frames are extended to 16 pixels.  This is different than
217ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    //  L/A/G reference frames that have a border of 32 (VP9BORDERINPIXELS)
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // A 6/8 tap filter is used for motion search.  This requires 2 pixels
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    //  before and 3 pixels after.  So the largest Y mv on a border would
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    //  then be 16 - VP9_INTERP_EXTEND. The UV blocks are half the size of the
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    //  Y and therefore only extended by 8.  The largest mv that a UV block
222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    //  can support is 8 - VP9_INTERP_EXTEND.  A UV mv is half of a Y mv.
223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    //  (16 - VP9_INTERP_EXTEND) >> 1 which is greater than
224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    //  8 - VP9_INTERP_EXTEND.
225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // To keep the mv in play for both Y and UV planes the max that it
226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    //  can be on a border is therefore 16 - (2*VP9_INTERP_EXTEND+1).
227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cpi->mb.mv_row_min = -((mb_row * 16) + (17 - 2 * VP9_INTERP_EXTEND));
228ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cpi->mb.mv_row_max = ((cpi->common.mb_rows - 1 - mb_row) * 16)
229ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                         + (17 - 2 * VP9_INTERP_EXTEND);
230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
232ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (mb_col = 0; mb_col < mb_cols; mb_col++) {
233ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int i, j, k;
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      int stride;
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
236ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vpx_memset(accumulator, 0, 384 * sizeof(unsigned int));
237ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      vpx_memset(count, 0, 384 * sizeof(uint16_t));
238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
239ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if ALT_REF_MC_ENABLED
240ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cpi->mb.mv_col_min = -((mb_col * 16) + (17 - 2 * VP9_INTERP_EXTEND));
241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cpi->mb.mv_col_max = ((cpi->common.mb_cols - 1 - mb_col) * 16)
242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           + (17 - 2 * VP9_INTERP_EXTEND);
243ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (frame = 0; frame < frame_count; frame++) {
246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (cpi->frames[frame] == NULL)
247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          continue;
248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2491184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        mbd->mi_8x8[0]->bmi[0].as_mv[0].as_mv.row = 0;
2501184aebb761cbeac9124c37189a80a1a58f04b6bhkuang        mbd->mi_8x8[0]->bmi[0].as_mv[0].as_mv.col = 0;
251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (frame == alt_ref_index) {
253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          filter_weight = 2;
254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        } else {
255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int err = 0;
256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#if ALT_REF_MC_ENABLED
257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define THRESH_LOW   10000
258ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define THRESH_HIGH  20000
259ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // Find best match in this frame by MC
261ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          err = temporal_filter_find_matching_mb_c
262ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                (cpi,
263ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 cpi->frames[alt_ref_index]->y_buffer + mb_y_offset,
264ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 cpi->frames[frame]->y_buffer + mb_y_offset,
265ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 cpi->frames[frame]->y_stride,
266ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                 THRESH_LOW);
267ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
268ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // Assign higher weight to matching MB if it's error
269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // score is lower. If not applying MC default behavior
270ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // is to weight all MBs equal.
271ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          filter_weight = err < THRESH_LOW
272ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                          ? 2 : err < THRESH_HIGH ? 1 : 0;
273ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
274ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
275ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        if (filter_weight != 0) {
276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // Construct the predictors
277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          temporal_filter_predictors_mb_c
278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          (mbd,
279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           cpi->frames[frame]->y_buffer + mb_y_offset,
280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           cpi->frames[frame]->u_buffer + mb_uv_offset,
281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           cpi->frames[frame]->v_buffer + mb_uv_offset,
282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           cpi->frames[frame]->y_stride,
2831184aebb761cbeac9124c37189a80a1a58f04b6bhkuang           mbd->mi_8x8[0]->bmi[0].as_mv[0].as_mv.row,
2841184aebb761cbeac9124c37189a80a1a58f04b6bhkuang           mbd->mi_8x8[0]->bmi[0].as_mv[0].as_mv.col,
2855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang           predictor, scale);
286ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
287ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // Apply the filter (YUV)
288ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_temporal_filter_apply(f->y_buffer + mb_y_offset, f->y_stride,
289ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    predictor, 16, strength, filter_weight,
290ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    accumulator, count);
291ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
292ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_temporal_filter_apply(f->u_buffer + mb_uv_offset, f->uv_stride,
293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    predictor + 256, 8, strength, filter_weight,
294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    accumulator + 256, count + 256);
295ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          vp9_temporal_filter_apply(f->v_buffer + mb_uv_offset, f->uv_stride,
297ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    predictor + 320, 8, strength, filter_weight,
298ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                    accumulator + 320, count + 320);
299ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
300ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
301ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
302ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Normalize filter output to produce AltRef frame
303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      dst1 = cpi->alt_ref_buffer.y_buffer;
304ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      stride = cpi->alt_ref_buffer.y_stride;
305ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      byte = mb_y_offset;
306ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0, k = 0; i < 16; i++) {
307ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (j = 0; j < 16; j++, k++) {
308ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          unsigned int pval = accumulator[k] + (count[k] >> 1);
309ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          pval *= cpi->fixed_divide[count[k]];
310ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          pval >>= 19;
311ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
312ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          dst1[byte] = (uint8_t)pval;
313ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
314ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // move to next pixel
315ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          byte++;
316ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
318ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        byte += stride - 16;
319ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
320ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
321ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      dst1 = cpi->alt_ref_buffer.u_buffer;
322ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      dst2 = cpi->alt_ref_buffer.v_buffer;
323ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      stride = cpi->alt_ref_buffer.uv_stride;
324ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      byte = mb_uv_offset;
325ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      for (i = 0, k = 256; i < 8; i++) {
326ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        for (j = 0; j < 8; j++, k++) {
327ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          int m = k + 64;
328ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
329ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // U
330ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          unsigned int pval = accumulator[k] + (count[k] >> 1);
331ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          pval *= cpi->fixed_divide[count[k]];
332ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          pval >>= 19;
333ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          dst1[byte] = (uint8_t)pval;
334ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
335ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // V
336ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          pval = accumulator[m] + (count[m] >> 1);
337ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          pval *= cpi->fixed_divide[count[m]];
338ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          pval >>= 19;
339ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          dst2[byte] = (uint8_t)pval;
340ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
341ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          // move to next pixel
342ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang          byte++;
343ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        }
344ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
345ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        byte += stride - 8;
346ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
347ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
348ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mb_y_offset += 16;
349ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      mb_uv_offset += 8;
350ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
351ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
352ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mb_y_offset += 16 * (f->y_stride - mb_cols);
353ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mb_uv_offset += 8 * (f->uv_stride - mb_cols);
354ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
356ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Restore input state
357ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < MAX_MB_PLANE; i++)
358ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    mbd->plane[i].pre[0].buf = input_buffer[i];
359ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
360ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
361ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vp9_temporal_filter_prepare(VP9_COMP *cpi, int distance) {
362ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  VP9_COMMON *const cm = &cpi->common;
363ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
364ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int frame = 0;
365ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
366ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int frames_to_blur_backward = 0;
367ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int frames_to_blur_forward = 0;
368ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int frames_to_blur = 0;
369ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int start_frame = 0;
370ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
371ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int strength = cpi->active_arnr_strength;
372ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int blur_type = cpi->oxcf.arnr_type;
373ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int max_frames = cpi->active_arnr_frames;
374ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
375ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int num_frames_backward = distance;
376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  const int num_frames_forward = vp9_lookahead_depth(cpi->lookahead)
377ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                               - (num_frames_backward + 1);
378ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
3795ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct scale_factors scale;
3805ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  struct scale_factors_common scale_comm;
3815ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang
382ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  switch (blur_type) {
383ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case 1:
384ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Backward Blur
385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_to_blur_backward = num_frames_backward;
386ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
387ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_to_blur_backward >= max_frames)
388ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_to_blur_backward = max_frames - 1;
389ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
390ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_to_blur = frames_to_blur_backward + 1;
391ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
392ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
393ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case 2:
394ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Forward Blur
395ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
396ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_to_blur_forward = num_frames_forward;
397ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
398ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_to_blur_forward >= max_frames)
399ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_to_blur_forward = max_frames - 1;
400ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
401ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_to_blur = frames_to_blur_forward + 1;
402ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
403ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
404ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case 3:
405ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    default:
406ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Center Blur
407ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_to_blur_forward = num_frames_forward;
408ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_to_blur_backward = num_frames_backward;
409ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
410ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_to_blur_forward > frames_to_blur_backward)
411ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_to_blur_forward = frames_to_blur_backward;
412ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
413ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_to_blur_backward > frames_to_blur_forward)
414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_to_blur_backward = frames_to_blur_forward;
415ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
416ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // When max_frames is even we have 1 more frame backward than forward
417ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_to_blur_forward > (max_frames - 1) / 2)
418ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_to_blur_forward = ((max_frames - 1) / 2);
419ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
420ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_to_blur_backward > (max_frames / 2))
421ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_to_blur_backward = (max_frames / 2);
422ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
423ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1;
424ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
425ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
426ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
427ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  start_frame = distance + frames_to_blur_forward;
428ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifdef DEBUGFWG
430ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // DEBUG FWG
4315ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  printf(
4325ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      "max:%d FBCK:%d FFWD:%d ftb:%d ftbbck:%d ftbfwd:%d sei:%d lasei:%d "
4335ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      "start:%d",
4345ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      max_frames, num_frames_backward, num_frames_forward, frames_to_blur,
4355ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      frames_to_blur_backward, frames_to_blur_forward, cpi->source_encode_index,
4365ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      cpi->last_alt_ref_sei, start_frame);
437ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif
438ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
439ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Setup scaling factors. Scaling on each of the arnr frames is not supported
4405ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_setup_scale_factors_for_frame(&scale, &scale_comm,
4415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      get_frame_new_buffer(cm)->y_crop_width,
4425ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang      get_frame_new_buffer(cm)->y_crop_height,
443ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cm->width, cm->height);
444ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
445ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Setup frame pointers, NULL indicates frame not included in filter
4465ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang  vp9_zero(cpi->frames);
447ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (frame = 0; frame < frames_to_blur; frame++) {
448ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    int which_buffer = start_frame - frame;
449ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead,
450ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                                     which_buffer);
451ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cpi->frames[frames_to_blur - 1 - frame] = &buf->img;
452ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
453ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
454ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  temporal_filter_iterate_c(cpi, frames_to_blur, frames_to_blur_backward,
4555ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang                            strength, &scale);
456ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
457ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
458ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid configure_arnr_filter(VP9_COMP *cpi, const unsigned int this_frame,
459ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                           const int group_boost) {
460ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int half_gf_int;
461ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int frames_after_arf;
462ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int frames_bwd = cpi->oxcf.arnr_max_frames - 1;
463ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int frames_fwd = cpi->oxcf.arnr_max_frames - 1;
464ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int q;
465ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
466ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Define the arnr filter width for this group of frames:
467ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // We only filter frames that lie within a distance of half
468ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // the GF interval from the ARF frame. We also have to trap
469ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // cases where the filter extends beyond the end of clip.
470ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Note: this_frame->frame has been updated in the loop
471ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // so it now points at the ARF frame.
472ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  half_gf_int = cpi->baseline_gf_interval >> 1;
473ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  frames_after_arf = (int)(cpi->twopass.total_stats.count - this_frame - 1);
474ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
475ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  switch (cpi->oxcf.arnr_type) {
476ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case 1:  // Backward filter
477ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_fwd = 0;
478ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_bwd > half_gf_int)
479ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_bwd = half_gf_int;
480ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
481ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
482ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case 2:  // Forward filter
483ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_fwd > half_gf_int)
484ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_fwd = half_gf_int;
485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_fwd > frames_after_arf)
486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_fwd = frames_after_arf;
487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_bwd = 0;
488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    case 3:  // Centered filter
491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    default:
492ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_fwd >>= 1;
493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_fwd > frames_after_arf)
494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_fwd = frames_after_arf;
495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_fwd > half_gf_int)
496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_fwd = half_gf_int;
497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      frames_bwd = frames_fwd;
499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // For even length filter there is one more frame backward
501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff.
502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (frames_bwd < half_gf_int)
503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        frames_bwd += (cpi->oxcf.arnr_max_frames + 1) & 0x1;
504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      break;
505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
507ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  cpi->active_arnr_frames = frames_bwd + 1 + frames_fwd;
508ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
509ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Adjust the strength based on active max q
510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  q = ((int)vp9_convert_qindex_to_q(cpi->active_worst_quality) >> 1);
511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (q > 8) {
512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cpi->active_arnr_strength = cpi->oxcf.arnr_strength;
513ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cpi->active_arnr_strength = cpi->oxcf.arnr_strength - (8 - q);
515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (cpi->active_arnr_strength < 0)
516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      cpi->active_arnr_strength = 0;
517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
519ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  // Adjust number of frames in filter and strength based on gf boost level.
520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cpi->active_arnr_frames > (group_boost / 150)) {
521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cpi->active_arnr_frames = (group_boost / 150);
522ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cpi->active_arnr_frames += !(cpi->active_arnr_frames & 1);
523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (cpi->active_arnr_strength > (group_boost / 300)) {
525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    cpi->active_arnr_strength = (group_boost / 300);
526ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
528