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 118b92989c89bec8632aa47dc58dc162f199d62edcJames Zern#include <assert.h> 12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <math.h> 13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include <limits.h> 14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/common/vp9_alloccommon.h" 168b92989c89bec8632aa47dc58dc162f199d62edcJames Zern#include "vp9/common/vp9_common.h" 17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_onyxc_int.h" 182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/common/vp9_quant_common.h" 19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_reconinter.h" 208b92989c89bec8632aa47dc58dc162f199d62edcJames Zern#include "vp9/encoder/vp9_encodeframe.h" 218b92989c89bec8632aa47dc58dc162f199d62edcJames Zern#include "vp9/encoder/vp9_ethread.h" 222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/encoder/vp9_extend.h" 23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_firstpass.h" 242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/encoder/vp9_mcomp.h" 25ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "vp9/encoder/vp9_encoder.h" 262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vp9/encoder/vp9_quantize.h" 27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_ratectrl.h" 28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/encoder/vp9_segmentation.h" 297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "vp9/encoder/vp9_temporal_filter.h" 30c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann#include "vpx_dsp/vpx_dsp_common.h" 31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_mem/vpx_mem.h" 327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#include "vpx_ports/mem.h" 33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vpx_ports/vpx_timer.h" 342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "vpx_scale/vpx_scale.h" 35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianstatic int fixed_divide[512]; 37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 387bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void temporal_filter_predictors_mb_c( 397bc9febe8749e98a3812a0dc4380ceae75c29450Johann MACROBLOCKD *xd, uint8_t *y_mb_ptr, uint8_t *u_mb_ptr, uint8_t *v_mb_ptr, 407bc9febe8749e98a3812a0dc4380ceae75c29450Johann int stride, int uv_block_width, int uv_block_height, int mv_row, int mv_col, 417bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint8_t *pred, struct scale_factors *scale, int x, int y) { 42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang const int which_mv = 0; 434fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang const MV mv = { mv_row, mv_col }; 4468e1c830ade592be74773e249bf94e2bbfb50de7Johann const InterpKernel *const kernel = vp9_filter_kernels[EIGHTTAP_SHARP]; 454fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang 462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian enum mv_precision mv_precision_uv; 472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int uv_stride; 48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (uv_block_width == 8) { 492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uv_stride = (stride + 1) >> 1; 502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian mv_precision_uv = MV_PRECISION_Q4; 512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } else { 522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian uv_stride = stride; 532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian mv_precision_uv = MV_PRECISION_Q3; 542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian } 55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH 577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { 588b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_highbd_build_inter_predictor(CONVERT_TO_SHORTPTR(y_mb_ptr), stride, 598b92989c89bec8632aa47dc58dc162f199d62edcJames Zern CONVERT_TO_SHORTPTR(&pred[0]), 16, &mv, 608b92989c89bec8632aa47dc58dc162f199d62edcJames Zern scale, 16, 16, which_mv, kernel, 618b92989c89bec8632aa47dc58dc162f199d62edcJames Zern MV_PRECISION_Q3, x, y, xd->bd); 627bc9febe8749e98a3812a0dc4380ceae75c29450Johann 638b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_highbd_build_inter_predictor(CONVERT_TO_SHORTPTR(u_mb_ptr), uv_stride, 648b92989c89bec8632aa47dc58dc162f199d62edcJames Zern CONVERT_TO_SHORTPTR(&pred[256]), 657bc9febe8749e98a3812a0dc4380ceae75c29450Johann uv_block_width, &mv, scale, uv_block_width, 667bc9febe8749e98a3812a0dc4380ceae75c29450Johann uv_block_height, which_mv, kernel, 677bc9febe8749e98a3812a0dc4380ceae75c29450Johann mv_precision_uv, x, y, xd->bd); 687bc9febe8749e98a3812a0dc4380ceae75c29450Johann 698b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_highbd_build_inter_predictor(CONVERT_TO_SHORTPTR(v_mb_ptr), uv_stride, 708b92989c89bec8632aa47dc58dc162f199d62edcJames Zern CONVERT_TO_SHORTPTR(&pred[512]), 717bc9febe8749e98a3812a0dc4380ceae75c29450Johann uv_block_width, &mv, scale, uv_block_width, 727bc9febe8749e98a3812a0dc4380ceae75c29450Johann uv_block_height, which_mv, kernel, 737bc9febe8749e98a3812a0dc4380ceae75c29450Johann mv_precision_uv, x, y, xd->bd); 747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian return; 757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif // CONFIG_VP9_HIGHBITDEPTH 7768e1c830ade592be74773e249bf94e2bbfb50de7Johann (void)xd; 787bc9febe8749e98a3812a0dc4380ceae75c29450Johann vp9_build_inter_predictor(y_mb_ptr, stride, &pred[0], 16, &mv, scale, 16, 16, 797bc9febe8749e98a3812a0dc4380ceae75c29450Johann which_mv, kernel, MV_PRECISION_Q3, x, y); 807bc9febe8749e98a3812a0dc4380ceae75c29450Johann 817bc9febe8749e98a3812a0dc4380ceae75c29450Johann vp9_build_inter_predictor(u_mb_ptr, uv_stride, &pred[256], uv_block_width, 827bc9febe8749e98a3812a0dc4380ceae75c29450Johann &mv, scale, uv_block_width, uv_block_height, 837bc9febe8749e98a3812a0dc4380ceae75c29450Johann which_mv, kernel, mv_precision_uv, x, y); 847bc9febe8749e98a3812a0dc4380ceae75c29450Johann 857bc9febe8749e98a3812a0dc4380ceae75c29450Johann vp9_build_inter_predictor(v_mb_ptr, uv_stride, &pred[512], uv_block_width, 867bc9febe8749e98a3812a0dc4380ceae75c29450Johann &mv, scale, uv_block_width, uv_block_height, 877bc9febe8749e98a3812a0dc4380ceae75c29450Johann which_mv, kernel, mv_precision_uv, x, y); 88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 907ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanianvoid vp9_temporal_filter_init(void) { 91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int i; 92ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian fixed_divide[0] = 0; 947bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (i = 1; i < 512; ++i) fixed_divide[i] = 0x80000 / i; 95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 978b92989c89bec8632aa47dc58dc162f199d62edcJames Zernvoid vp9_temporal_filter_apply_c(const uint8_t *frame1, unsigned int stride, 988b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const uint8_t *frame2, 998b92989c89bec8632aa47dc58dc162f199d62edcJames Zern unsigned int block_width, 1007bc9febe8749e98a3812a0dc4380ceae75c29450Johann unsigned int block_height, int strength, 1018b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int filter_weight, uint32_t *accumulator, 102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang uint16_t *count) { 103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int i, j, k; 104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int modifier; 105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int byte = 0; 106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int rounding = strength > 0 ? 1 << (strength - 1) : 0; 107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1088b92989c89bec8632aa47dc58dc162f199d62edcJames Zern assert(strength >= 0); 1098b92989c89bec8632aa47dc58dc162f199d62edcJames Zern assert(strength <= 6); 1108b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 1118b92989c89bec8632aa47dc58dc162f199d62edcJames Zern assert(filter_weight >= 0); 1128b92989c89bec8632aa47dc58dc162f199d62edcJames Zern assert(filter_weight <= 2); 1138b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (i = 0, k = 0; i < block_height; i++) { 115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (j = 0; j < block_width; j++, k++) { 11668e1c830ade592be74773e249bf94e2bbfb50de7Johann int pixel_value = *frame2; 11768e1c830ade592be74773e249bf94e2bbfb50de7Johann 11868e1c830ade592be74773e249bf94e2bbfb50de7Johann // non-local mean approach 11968e1c830ade592be74773e249bf94e2bbfb50de7Johann int diff_sse[9] = { 0 }; 12068e1c830ade592be74773e249bf94e2bbfb50de7Johann int idx, idy, index = 0; 12168e1c830ade592be74773e249bf94e2bbfb50de7Johann 12268e1c830ade592be74773e249bf94e2bbfb50de7Johann for (idy = -1; idy <= 1; ++idy) { 12368e1c830ade592be74773e249bf94e2bbfb50de7Johann for (idx = -1; idx <= 1; ++idx) { 12468e1c830ade592be74773e249bf94e2bbfb50de7Johann int row = (int)i + idy; 12568e1c830ade592be74773e249bf94e2bbfb50de7Johann int col = (int)j + idx; 12668e1c830ade592be74773e249bf94e2bbfb50de7Johann 1277bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (row >= 0 && row < (int)block_height && col >= 0 && 1287bc9febe8749e98a3812a0dc4380ceae75c29450Johann col < (int)block_width) { 12968e1c830ade592be74773e249bf94e2bbfb50de7Johann int diff = frame1[byte + idy * (int)stride + idx] - 1307bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame2[idy * (int)block_width + idx]; 13168e1c830ade592be74773e249bf94e2bbfb50de7Johann diff_sse[index] = diff * diff; 13268e1c830ade592be74773e249bf94e2bbfb50de7Johann ++index; 13368e1c830ade592be74773e249bf94e2bbfb50de7Johann } 13468e1c830ade592be74773e249bf94e2bbfb50de7Johann } 13568e1c830ade592be74773e249bf94e2bbfb50de7Johann } 13668e1c830ade592be74773e249bf94e2bbfb50de7Johann 13768e1c830ade592be74773e249bf94e2bbfb50de7Johann assert(index > 0); 13868e1c830ade592be74773e249bf94e2bbfb50de7Johann 13968e1c830ade592be74773e249bf94e2bbfb50de7Johann modifier = 0; 1407bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (idx = 0; idx < 9; ++idx) modifier += diff_sse[idx]; 14168e1c830ade592be74773e249bf94e2bbfb50de7Johann 14268e1c830ade592be74773e249bf94e2bbfb50de7Johann modifier *= 3; 14368e1c830ade592be74773e249bf94e2bbfb50de7Johann modifier /= index; 14468e1c830ade592be74773e249bf94e2bbfb50de7Johann 14568e1c830ade592be74773e249bf94e2bbfb50de7Johann ++frame2; 14668e1c830ade592be74773e249bf94e2bbfb50de7Johann 1477bc9febe8749e98a3812a0dc4380ceae75c29450Johann modifier += rounding; 148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang modifier >>= strength; 149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1507bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (modifier > 16) modifier = 16; 151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang modifier = 16 - modifier; 153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang modifier *= filter_weight; 154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang count[k] += modifier; 156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang accumulator[k] += modifier * pixel_value; 157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang byte++; 159ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 160ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 161ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian byte += stride - block_width; 162ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH 1667bc9febe8749e98a3812a0dc4380ceae75c29450Johannvoid vp9_highbd_temporal_filter_apply_c( 1678b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const uint8_t *frame1_8, unsigned int stride, const uint8_t *frame2_8, 1687bc9febe8749e98a3812a0dc4380ceae75c29450Johann unsigned int block_width, unsigned int block_height, int strength, 1698b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int filter_weight, uint32_t *accumulator, uint16_t *count) { 1708b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const uint16_t *frame1 = CONVERT_TO_SHORTPTR(frame1_8); 1718b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const uint16_t *frame2 = CONVERT_TO_SHORTPTR(frame2_8); 1727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian unsigned int i, j, k; 1737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int modifier; 1747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int byte = 0; 1757ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const int rounding = strength > 0 ? 1 << (strength - 1) : 0; 1767ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 1777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (i = 0, k = 0; i < block_height; i++) { 1787ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (j = 0; j < block_width; j++, k++) { 17968e1c830ade592be74773e249bf94e2bbfb50de7Johann int pixel_value = *frame2; 18068e1c830ade592be74773e249bf94e2bbfb50de7Johann int diff_sse[9] = { 0 }; 18168e1c830ade592be74773e249bf94e2bbfb50de7Johann int idx, idy, index = 0; 18268e1c830ade592be74773e249bf94e2bbfb50de7Johann 18368e1c830ade592be74773e249bf94e2bbfb50de7Johann for (idy = -1; idy <= 1; ++idy) { 18468e1c830ade592be74773e249bf94e2bbfb50de7Johann for (idx = -1; idx <= 1; ++idx) { 18568e1c830ade592be74773e249bf94e2bbfb50de7Johann int row = (int)i + idy; 18668e1c830ade592be74773e249bf94e2bbfb50de7Johann int col = (int)j + idx; 18768e1c830ade592be74773e249bf94e2bbfb50de7Johann 1887bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (row >= 0 && row < (int)block_height && col >= 0 && 1897bc9febe8749e98a3812a0dc4380ceae75c29450Johann col < (int)block_width) { 19068e1c830ade592be74773e249bf94e2bbfb50de7Johann int diff = frame1[byte + idy * (int)stride + idx] - 1917bc9febe8749e98a3812a0dc4380ceae75c29450Johann frame2[idy * (int)block_width + idx]; 19268e1c830ade592be74773e249bf94e2bbfb50de7Johann diff_sse[index] = diff * diff; 19368e1c830ade592be74773e249bf94e2bbfb50de7Johann ++index; 19468e1c830ade592be74773e249bf94e2bbfb50de7Johann } 19568e1c830ade592be74773e249bf94e2bbfb50de7Johann } 19668e1c830ade592be74773e249bf94e2bbfb50de7Johann } 19768e1c830ade592be74773e249bf94e2bbfb50de7Johann assert(index > 0); 19868e1c830ade592be74773e249bf94e2bbfb50de7Johann 19968e1c830ade592be74773e249bf94e2bbfb50de7Johann modifier = 0; 2007bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (idx = 0; idx < 9; ++idx) modifier += diff_sse[idx]; 20168e1c830ade592be74773e249bf94e2bbfb50de7Johann 2027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian modifier *= 3; 20368e1c830ade592be74773e249bf94e2bbfb50de7Johann modifier /= index; 20468e1c830ade592be74773e249bf94e2bbfb50de7Johann 20568e1c830ade592be74773e249bf94e2bbfb50de7Johann ++frame2; 2067ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian modifier += rounding; 2077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian modifier >>= strength; 2087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 2097bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (modifier > 16) modifier = 16; 2107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 2117ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian modifier = 16 - modifier; 2127ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian modifier *= filter_weight; 2137ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 2147ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian count[k] += modifier; 2157ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian accumulator[k] += modifier * pixel_value; 2167ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 2177ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian byte++; 2187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 2197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 2207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian byte += stride - block_width; 2217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 2227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian} 2237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif // CONFIG_VP9_HIGHBITDEPTH 2247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 2257bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic uint32_t temporal_filter_find_matching_mb_c(VP9_COMP *cpi, 2268b92989c89bec8632aa47dc58dc162f199d62edcJames Zern ThreadData *td, 2277bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint8_t *arf_frame_buf, 2287bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint8_t *frame_ptr_buf, 2298b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int stride, MV *ref_mv) { 2308b92989c89bec8632aa47dc58dc162f199d62edcJames Zern MACROBLOCK *const x = &td->mb; 231ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian MACROBLOCKD *const xd = &x->e_mbd; 232c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; 2338b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const SEARCH_METHODS search_method = HEX; 234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int step_param; 235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int sadpb = x->sadperbit16; 2367bc9febe8749e98a3812a0dc4380ceae75c29450Johann uint32_t bestsme = UINT_MAX; 23768e1c830ade592be74773e249bf94e2bbfb50de7Johann uint32_t distortion; 23868e1c830ade592be74773e249bf94e2bbfb50de7Johann uint32_t sse; 2397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int cost_list[5]; 2408b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const MvLimits tmp_mv_limits = x->mv_limits; 241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2427bc9febe8749e98a3812a0dc4380ceae75c29450Johann MV best_ref_mv1 = { 0, 0 }; 2432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */ 244ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 245ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Save input state 246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct buf_2d src = x->plane[0].src; 247ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang struct buf_2d pre = xd->plane[0].pre[0]; 248ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2492ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian best_ref_mv1_full.col = best_ref_mv1.col >> 3; 2502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian best_ref_mv1_full.row = best_ref_mv1.row >> 3; 251ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 252ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Setup frame pointers 253ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang x->plane[0].src.buf = arf_frame_buf; 254ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang x->plane[0].src.stride = stride; 255ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang xd->plane[0].pre[0].buf = frame_ptr_buf; 256ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang xd->plane[0].pre[0].stride = stride; 257ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 258ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian step_param = mv_sf->reduce_first_step_size; 259c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann step_param = VPXMIN(step_param, MAX_MVSEARCH_STEPS - 2); 260ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2618b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_set_mv_search_range(&x->mv_limits, &best_ref_mv1); 2628b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 263c927526be9a7b72fb5edb3f29c4e8ceabe0ec98aJohann vp9_full_pixel_search(cpi, x, BLOCK_16X16, &best_ref_mv1_full, step_param, 2648b92989c89bec8632aa47dc58dc162f199d62edcJames Zern search_method, sadpb, cond_cost_list(cpi, cost_list), 2658b92989c89bec8632aa47dc58dc162f199d62edcJames Zern &best_ref_mv1, ref_mv, 0, 0); 2668b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 2678b92989c89bec8632aa47dc58dc162f199d62edcJames Zern /* restore UMV window */ 2688b92989c89bec8632aa47dc58dc162f199d62edcJames Zern x->mv_limits = tmp_mv_limits; 269ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 270ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Ignore mv costing by sending NULL pointer instead of cost array 2717bc9febe8749e98a3812a0dc4380ceae75c29450Johann bestsme = cpi->find_fractional_mv_step( 2727bc9febe8749e98a3812a0dc4380ceae75c29450Johann x, ref_mv, &best_ref_mv1, cpi->common.allow_high_precision_mv, 2737bc9febe8749e98a3812a0dc4380ceae75c29450Johann x->errorperbit, &cpi->fn_ptr[BLOCK_16X16], 0, 2747bc9febe8749e98a3812a0dc4380ceae75c29450Johann mv_sf->subpel_iters_per_step, cond_cost_list(cpi, cost_list), NULL, NULL, 2757bc9febe8749e98a3812a0dc4380ceae75c29450Johann &distortion, &sse, NULL, 0, 0); 276ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 277ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Restore input state 278ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang x->plane[0].src = src; 279ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang xd->plane[0].pre[0] = pre; 280ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 281ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return bestsme; 282ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 283ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 2848b92989c89bec8632aa47dc58dc162f199d62edcJames Zernvoid vp9_temporal_filter_iterate_row_c(VP9_COMP *cpi, ThreadData *td, 2858b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int mb_row, int mb_col_start, 2868b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int mb_col_end) { 2878b92989c89bec8632aa47dc58dc162f199d62edcJames Zern ARNRFilterData *arnr_filter_data = &cpi->arnr_filter_data; 2888b92989c89bec8632aa47dc58dc162f199d62edcJames Zern YV12_BUFFER_CONFIG **frames = arnr_filter_data->frames; 2898b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int frame_count = arnr_filter_data->frame_count; 2908b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int alt_ref_index = arnr_filter_data->alt_ref_index; 2918b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int strength = arnr_filter_data->strength; 2928b92989c89bec8632aa47dc58dc162f199d62edcJames Zern struct scale_factors *scale = &arnr_filter_data->sf; 293ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int byte; 294ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang int frame; 2958b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int mb_col; 296ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int filter_weight; 2977ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int mb_cols = (frames[alt_ref_index]->y_crop_width + 15) >> 4; 2987ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int mb_rows = (frames[alt_ref_index]->y_crop_height + 15) >> 4; 2998b92989c89bec8632aa47dc58dc162f199d62edcJames Zern DECLARE_ALIGNED(16, uint32_t, accumulator[16 * 16 * 3]); 3007ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian DECLARE_ALIGNED(16, uint16_t, count[16 * 16 * 3]); 3018b92989c89bec8632aa47dc58dc162f199d62edcJames Zern MACROBLOCKD *mbd = &td->mb.e_mbd; 3027ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian YV12_BUFFER_CONFIG *f = frames[alt_ref_index]; 303ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang uint8_t *dst1, *dst2; 3047ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH 3057bc9febe8749e98a3812a0dc4380ceae75c29450Johann DECLARE_ALIGNED(16, uint16_t, predictor16[16 * 16 * 3]); 3067bc9febe8749e98a3812a0dc4380ceae75c29450Johann DECLARE_ALIGNED(16, uint8_t, predictor8[16 * 16 * 3]); 3077ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian uint8_t *predictor; 3087ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#else 3097bc9febe8749e98a3812a0dc4380ceae75c29450Johann DECLARE_ALIGNED(16, uint8_t, predictor[16 * 16 * 3]); 3107ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif 3112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian const int mb_uv_height = 16 >> mbd->plane[1].subsampling_y; 3127bc9febe8749e98a3812a0dc4380ceae75c29450Johann const int mb_uv_width = 16 >> mbd->plane[1].subsampling_x; 3138b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Addition of the tile col level offsets 3148b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int mb_y_offset = mb_row * 16 * (f->y_stride) + 16 * mb_col_start; 3158b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int mb_uv_offset = 3168b92989c89bec8632aa47dc58dc162f199d62edcJames Zern mb_row * mb_uv_height * f->uv_stride + mb_uv_width * mb_col_start; 317ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3187ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH 3197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { 3207ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian predictor = CONVERT_TO_BYTEPTR(predictor16); 3217ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else { 3227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian predictor = predictor8; 3237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 3247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif 325ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3268b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Source frames are extended to 16 pixels. This is different than 3278b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // L/A/G reference frames that have a border of 32 (VP9ENCBORDERINPIXELS) 3288b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // A 6/8 tap filter is used for motion search. This requires 2 pixels 3298b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // before and 3 pixels after. So the largest Y mv on a border would 3308b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // then be 16 - VP9_INTERP_EXTEND. The UV blocks are half the size of the 3318b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Y and therefore only extended by 8. The largest mv that a UV block 3328b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // can support is 8 - VP9_INTERP_EXTEND. A UV mv is half of a Y mv. 3338b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // (16 - VP9_INTERP_EXTEND) >> 1 which is greater than 3348b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // 8 - VP9_INTERP_EXTEND. 3358b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // To keep the mv in play for both Y and UV planes the max that it 3368b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // can be on a border is therefore 16 - (2*VP9_INTERP_EXTEND+1). 3378b92989c89bec8632aa47dc58dc162f199d62edcJames Zern td->mb.mv_limits.row_min = -((mb_row * 16) + (17 - 2 * VP9_INTERP_EXTEND)); 3388b92989c89bec8632aa47dc58dc162f199d62edcJames Zern td->mb.mv_limits.row_max = 3398b92989c89bec8632aa47dc58dc162f199d62edcJames Zern ((mb_rows - 1 - mb_row) * 16) + (17 - 2 * VP9_INTERP_EXTEND); 3408b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 3418b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (mb_col = mb_col_start; mb_col < mb_col_end; mb_col++) { 3428b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int i, j, k; 3438b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int stride; 3448b92989c89bec8632aa47dc58dc162f199d62edcJames Zern MV ref_mv; 3458b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 3468b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_zero_array(accumulator, 16 * 16 * 3); 3478b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_zero_array(count, 16 * 16 * 3); 3488b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 3498b92989c89bec8632aa47dc58dc162f199d62edcJames Zern td->mb.mv_limits.col_min = -((mb_col * 16) + (17 - 2 * VP9_INTERP_EXTEND)); 3508b92989c89bec8632aa47dc58dc162f199d62edcJames Zern td->mb.mv_limits.col_max = 3518b92989c89bec8632aa47dc58dc162f199d62edcJames Zern ((mb_cols - 1 - mb_col) * 16) + (17 - 2 * VP9_INTERP_EXTEND); 3528b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 3538b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (frame = 0; frame < frame_count; frame++) { 3548b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const uint32_t thresh_low = 10000; 3558b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const uint32_t thresh_high = 20000; 3568b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 3578b92989c89bec8632aa47dc58dc162f199d62edcJames Zern if (frames[frame] == NULL) continue; 3588b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 3598b92989c89bec8632aa47dc58dc162f199d62edcJames Zern ref_mv.row = 0; 3608b92989c89bec8632aa47dc58dc162f199d62edcJames Zern ref_mv.col = 0; 3618b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 3628b92989c89bec8632aa47dc58dc162f199d62edcJames Zern if (frame == alt_ref_index) { 3638b92989c89bec8632aa47dc58dc162f199d62edcJames Zern filter_weight = 2; 3648b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } else { 3658b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Find best match in this frame by MC 3668b92989c89bec8632aa47dc58dc162f199d62edcJames Zern uint32_t err = temporal_filter_find_matching_mb_c( 3678b92989c89bec8632aa47dc58dc162f199d62edcJames Zern cpi, td, frames[alt_ref_index]->y_buffer + mb_y_offset, 3688b92989c89bec8632aa47dc58dc162f199d62edcJames Zern frames[frame]->y_buffer + mb_y_offset, frames[frame]->y_stride, 3698b92989c89bec8632aa47dc58dc162f199d62edcJames Zern &ref_mv); 3708b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 3718b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Assign higher weight to matching MB if its error 3728b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // score is lower. If not applying MC default behavior 3738b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // is to weight all MBs equal. 3748b92989c89bec8632aa47dc58dc162f199d62edcJames Zern filter_weight = err < thresh_low ? 2 : err < thresh_high ? 1 : 0; 3758b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 376ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3778b92989c89bec8632aa47dc58dc162f199d62edcJames Zern if (filter_weight != 0) { 3788b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Construct the predictors 3798b92989c89bec8632aa47dc58dc162f199d62edcJames Zern temporal_filter_predictors_mb_c( 3808b92989c89bec8632aa47dc58dc162f199d62edcJames Zern mbd, frames[frame]->y_buffer + mb_y_offset, 3818b92989c89bec8632aa47dc58dc162f199d62edcJames Zern frames[frame]->u_buffer + mb_uv_offset, 3828b92989c89bec8632aa47dc58dc162f199d62edcJames Zern frames[frame]->v_buffer + mb_uv_offset, frames[frame]->y_stride, 3838b92989c89bec8632aa47dc58dc162f199d62edcJames Zern mb_uv_width, mb_uv_height, ref_mv.row, ref_mv.col, predictor, scale, 3848b92989c89bec8632aa47dc58dc162f199d62edcJames Zern mb_col * 16, mb_row * 16); 385ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 3867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH 3878b92989c89bec8632aa47dc58dc162f199d62edcJames Zern if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { 3888b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int adj_strength = strength + 2 * (mbd->bd - 8); 38968e1c830ade592be74773e249bf94e2bbfb50de7Johann // Apply the filter (YUV) 3908b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_highbd_temporal_filter_apply( 3918b92989c89bec8632aa47dc58dc162f199d62edcJames Zern f->y_buffer + mb_y_offset, f->y_stride, predictor, 16, 16, 3928b92989c89bec8632aa47dc58dc162f199d62edcJames Zern adj_strength, filter_weight, accumulator, count); 3938b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_highbd_temporal_filter_apply( 3948b92989c89bec8632aa47dc58dc162f199d62edcJames Zern f->u_buffer + mb_uv_offset, f->uv_stride, predictor + 256, 3958b92989c89bec8632aa47dc58dc162f199d62edcJames Zern mb_uv_width, mb_uv_height, adj_strength, filter_weight, 3968b92989c89bec8632aa47dc58dc162f199d62edcJames Zern accumulator + 256, count + 256); 3978b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_highbd_temporal_filter_apply( 3988b92989c89bec8632aa47dc58dc162f199d62edcJames Zern f->v_buffer + mb_uv_offset, f->uv_stride, predictor + 512, 3998b92989c89bec8632aa47dc58dc162f199d62edcJames Zern mb_uv_width, mb_uv_height, adj_strength, filter_weight, 4008b92989c89bec8632aa47dc58dc162f199d62edcJames Zern accumulator + 512, count + 512); 4018b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } else { 4028b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Apply the filter (YUV) 4038b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_temporal_filter_apply(f->y_buffer + mb_y_offset, f->y_stride, 4048b92989c89bec8632aa47dc58dc162f199d62edcJames Zern predictor, 16, 16, strength, filter_weight, 4058b92989c89bec8632aa47dc58dc162f199d62edcJames Zern accumulator, count); 4068b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_temporal_filter_apply(f->u_buffer + mb_uv_offset, f->uv_stride, 4078b92989c89bec8632aa47dc58dc162f199d62edcJames Zern predictor + 256, mb_uv_width, mb_uv_height, 4088b92989c89bec8632aa47dc58dc162f199d62edcJames Zern strength, filter_weight, accumulator + 256, 4098b92989c89bec8632aa47dc58dc162f199d62edcJames Zern count + 256); 4108b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_temporal_filter_apply(f->v_buffer + mb_uv_offset, f->uv_stride, 4118b92989c89bec8632aa47dc58dc162f199d62edcJames Zern predictor + 512, mb_uv_width, mb_uv_height, 4128b92989c89bec8632aa47dc58dc162f199d62edcJames Zern strength, filter_weight, accumulator + 512, 4138b92989c89bec8632aa47dc58dc162f199d62edcJames Zern count + 512); 414ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 4158b92989c89bec8632aa47dc58dc162f199d62edcJames Zern#else 4168b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Apply the filter (YUV) 4178b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_temporal_filter_apply(f->y_buffer + mb_y_offset, f->y_stride, 4188b92989c89bec8632aa47dc58dc162f199d62edcJames Zern predictor, 16, 16, strength, filter_weight, 4198b92989c89bec8632aa47dc58dc162f199d62edcJames Zern accumulator, count); 4208b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_temporal_filter_apply(f->u_buffer + mb_uv_offset, f->uv_stride, 4218b92989c89bec8632aa47dc58dc162f199d62edcJames Zern predictor + 256, mb_uv_width, mb_uv_height, 4228b92989c89bec8632aa47dc58dc162f199d62edcJames Zern strength, filter_weight, accumulator + 256, 4238b92989c89bec8632aa47dc58dc162f199d62edcJames Zern count + 256); 4248b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_temporal_filter_apply(f->v_buffer + mb_uv_offset, f->uv_stride, 4258b92989c89bec8632aa47dc58dc162f199d62edcJames Zern predictor + 512, mb_uv_width, mb_uv_height, 4268b92989c89bec8632aa47dc58dc162f199d62edcJames Zern strength, filter_weight, accumulator + 512, 4278b92989c89bec8632aa47dc58dc162f199d62edcJames Zern count + 512); 4288b92989c89bec8632aa47dc58dc162f199d62edcJames Zern#endif // CONFIG_VP9_HIGHBITDEPTH 429ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 4308b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 431ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 4327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH 4338b92989c89bec8632aa47dc58dc162f199d62edcJames Zern if (mbd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) { 4348b92989c89bec8632aa47dc58dc162f199d62edcJames Zern uint16_t *dst1_16; 4358b92989c89bec8632aa47dc58dc162f199d62edcJames Zern uint16_t *dst2_16; 4368b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Normalize filter output to produce AltRef frame 4378b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1 = cpi->alt_ref_buffer.y_buffer; 4388b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1_16 = CONVERT_TO_SHORTPTR(dst1); 4398b92989c89bec8632aa47dc58dc162f199d62edcJames Zern stride = cpi->alt_ref_buffer.y_stride; 4408b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte = mb_y_offset; 4418b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (i = 0, k = 0; i < 16; i++) { 4428b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (j = 0; j < 16; j++, k++) { 4438b92989c89bec8632aa47dc58dc162f199d62edcJames Zern unsigned int pval = accumulator[k] + (count[k] >> 1); 4448b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval *= fixed_divide[count[k]]; 4458b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval >>= 19; 4467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4478b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1_16[byte] = (uint16_t)pval; 4488b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 4498b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // move to next pixel 4508b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte++; 4517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4538b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte += stride - 16; 4548b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 4557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4568b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1 = cpi->alt_ref_buffer.u_buffer; 4578b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst2 = cpi->alt_ref_buffer.v_buffer; 4588b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1_16 = CONVERT_TO_SHORTPTR(dst1); 4598b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst2_16 = CONVERT_TO_SHORTPTR(dst2); 4608b92989c89bec8632aa47dc58dc162f199d62edcJames Zern stride = cpi->alt_ref_buffer.uv_stride; 4618b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte = mb_uv_offset; 4628b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (i = 0, k = 256; i < mb_uv_height; i++) { 4638b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (j = 0; j < mb_uv_width; j++, k++) { 4648b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int m = k + 256; 4657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 4668b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // U 4678b92989c89bec8632aa47dc58dc162f199d62edcJames Zern unsigned int pval = accumulator[k] + (count[k] >> 1); 4688b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval *= fixed_divide[count[k]]; 4698b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval >>= 19; 4708b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1_16[byte] = (uint16_t)pval; 4718b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 4728b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // V 4738b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval = accumulator[m] + (count[m] >> 1); 4748b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval *= fixed_divide[count[m]]; 4758b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval >>= 19; 4768b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst2_16[byte] = (uint16_t)pval; 4778b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 4788b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // move to next pixel 4798b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte++; 4807ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4818b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 4828b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte += stride - mb_uv_width; 4837ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 4848b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } else { 485ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Normalize filter output to produce AltRef frame 486ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dst1 = cpi->alt_ref_buffer.y_buffer; 487ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stride = cpi->alt_ref_buffer.y_stride; 488ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang byte = mb_y_offset; 489ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (i = 0, k = 0; i < 16; i++) { 490ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang for (j = 0; j < 16; j++, k++) { 491ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int pval = accumulator[k] + (count[k] >> 1); 492ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pval *= fixed_divide[count[k]]; 493ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pval >>= 19; 494ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 495ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dst1[byte] = (uint8_t)pval; 496ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 497ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // move to next pixel 498ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang byte++; 499ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 500ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang byte += stride - 16; 501ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 502ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 503ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dst1 = cpi->alt_ref_buffer.u_buffer; 504ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dst2 = cpi->alt_ref_buffer.v_buffer; 505ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang stride = cpi->alt_ref_buffer.uv_stride; 506ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang byte = mb_uv_offset; 5072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian for (i = 0, k = 256; i < mb_uv_height; i++) { 508ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (j = 0; j < mb_uv_width; j++, k++) { 5092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian int m = k + 256; 510ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 511ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // U 512ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang unsigned int pval = accumulator[k] + (count[k] >> 1); 513ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pval *= fixed_divide[count[k]]; 514ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pval >>= 19; 515ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dst1[byte] = (uint8_t)pval; 516ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 517ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // V 518ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pval = accumulator[m] + (count[m] >> 1); 519ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian pval *= fixed_divide[count[m]]; 520ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang pval >>= 19; 521ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang dst2[byte] = (uint8_t)pval; 522ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 523ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // move to next pixel 524ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang byte++; 525ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 526ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian byte += stride - mb_uv_width; 527ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 5288b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 5298b92989c89bec8632aa47dc58dc162f199d62edcJames Zern#else 5308b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Normalize filter output to produce AltRef frame 5318b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1 = cpi->alt_ref_buffer.y_buffer; 5328b92989c89bec8632aa47dc58dc162f199d62edcJames Zern stride = cpi->alt_ref_buffer.y_stride; 5338b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte = mb_y_offset; 5348b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (i = 0, k = 0; i < 16; i++) { 5358b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (j = 0; j < 16; j++, k++) { 5368b92989c89bec8632aa47dc58dc162f199d62edcJames Zern unsigned int pval = accumulator[k] + (count[k] >> 1); 5378b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval *= fixed_divide[count[k]]; 5388b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval >>= 19; 5398b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 5408b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1[byte] = (uint8_t)pval; 5418b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 5428b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // move to next pixel 5438b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte++; 5448b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 5458b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte += stride - 16; 5468b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 5478b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 5488b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1 = cpi->alt_ref_buffer.u_buffer; 5498b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst2 = cpi->alt_ref_buffer.v_buffer; 5508b92989c89bec8632aa47dc58dc162f199d62edcJames Zern stride = cpi->alt_ref_buffer.uv_stride; 5518b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte = mb_uv_offset; 5528b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (i = 0, k = 256; i < mb_uv_height; i++) { 5538b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (j = 0; j < mb_uv_width; j++, k++) { 5548b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int m = k + 256; 5558b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 5568b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // U 5578b92989c89bec8632aa47dc58dc162f199d62edcJames Zern unsigned int pval = accumulator[k] + (count[k] >> 1); 5588b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval *= fixed_divide[count[k]]; 5598b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval >>= 19; 5608b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst1[byte] = (uint8_t)pval; 5618b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 5628b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // V 5638b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval = accumulator[m] + (count[m] >> 1); 5648b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval *= fixed_divide[count[m]]; 5658b92989c89bec8632aa47dc58dc162f199d62edcJames Zern pval >>= 19; 5668b92989c89bec8632aa47dc58dc162f199d62edcJames Zern dst2[byte] = (uint8_t)pval; 5678b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 5688b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // move to next pixel 5698b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte++; 5708b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 5718b92989c89bec8632aa47dc58dc162f199d62edcJames Zern byte += stride - mb_uv_width; 5728b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 5737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif // CONFIG_VP9_HIGHBITDEPTH 5748b92989c89bec8632aa47dc58dc162f199d62edcJames Zern mb_y_offset += 16; 5758b92989c89bec8632aa47dc58dc162f199d62edcJames Zern mb_uv_offset += mb_uv_width; 5768b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 5778b92989c89bec8632aa47dc58dc162f199d62edcJames Zern} 5788b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 5798b92989c89bec8632aa47dc58dc162f199d62edcJames Zernstatic void temporal_filter_iterate_tile_c(VP9_COMP *cpi, int tile_row, 5808b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int tile_col) { 5818b92989c89bec8632aa47dc58dc162f199d62edcJames Zern VP9_COMMON *const cm = &cpi->common; 5828b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const int tile_cols = 1 << cm->log2_tile_cols; 5838b92989c89bec8632aa47dc58dc162f199d62edcJames Zern TileInfo *tile_info = 5848b92989c89bec8632aa47dc58dc162f199d62edcJames Zern &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info; 5858b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const int mb_row_start = (tile_info->mi_row_start) >> 1; 5868b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const int mb_row_end = (tile_info->mi_row_end + 1) >> 1; 5878b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const int mb_col_start = (tile_info->mi_col_start) >> 1; 5888b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const int mb_col_end = (tile_info->mi_col_end + 1) >> 1; 5898b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int mb_row; 5908b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 5918b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (mb_row = mb_row_start; mb_row < mb_row_end; mb_row++) { 5928b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_temporal_filter_iterate_row_c(cpi, &cpi->td, mb_row, mb_col_start, 5938b92989c89bec8632aa47dc58dc162f199d62edcJames Zern mb_col_end); 5948b92989c89bec8632aa47dc58dc162f199d62edcJames Zern } 5958b92989c89bec8632aa47dc58dc162f199d62edcJames Zern} 5968b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 5978b92989c89bec8632aa47dc58dc162f199d62edcJames Zernstatic void temporal_filter_iterate_c(VP9_COMP *cpi) { 5988b92989c89bec8632aa47dc58dc162f199d62edcJames Zern VP9_COMMON *const cm = &cpi->common; 5998b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const int tile_cols = 1 << cm->log2_tile_cols; 6008b92989c89bec8632aa47dc58dc162f199d62edcJames Zern const int tile_rows = 1 << cm->log2_tile_rows; 6018b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int tile_row, tile_col; 6028b92989c89bec8632aa47dc58dc162f199d62edcJames Zern MACROBLOCKD *mbd = &cpi->td.mb.e_mbd; 6038b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Save input state 6048b92989c89bec8632aa47dc58dc162f199d62edcJames Zern uint8_t *input_buffer[MAX_MB_PLANE]; 6058b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int i; 6068b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 6078b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (i = 0; i < MAX_MB_PLANE; i++) input_buffer[i] = mbd->plane[i].pre[0].buf; 6088b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 6098b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_init_tile_data(cpi); 6108b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 6118b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (tile_row = 0; tile_row < tile_rows; ++tile_row) { 6128b92989c89bec8632aa47dc58dc162f199d62edcJames Zern for (tile_col = 0; tile_col < tile_cols; ++tile_col) { 6138b92989c89bec8632aa47dc58dc162f199d62edcJames Zern temporal_filter_iterate_tile_c(cpi, tile_row, tile_col); 614ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 615ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 616ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 617ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Restore input state 6187bc9febe8749e98a3812a0dc4380ceae75c29450Johann for (i = 0; i < MAX_MB_PLANE; i++) mbd->plane[i].pre[0].buf = input_buffer[i]; 619ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 620ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 621ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian// Apply buffer limits and context specific adjustments to arnr filter. 6227bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic void adjust_arnr_filter(VP9_COMP *cpi, int distance, int group_boost, 6237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int *arnr_frames, int *arnr_strength) { 6247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian const VP9EncoderConfig *const oxcf = &cpi->oxcf; 625ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int frames_after_arf = 6267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian vp9_lookahead_depth(cpi->lookahead) - distance - 1; 627ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int frames_fwd = (cpi->oxcf.arnr_max_frames - 1) >> 1; 628ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int frames_bwd; 6297bc9febe8749e98a3812a0dc4380ceae75c29450Johann int q, frames, base_strength, strength; 6307bc9febe8749e98a3812a0dc4380ceae75c29450Johann 6317bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Context dependent two pass adjustment to strength. 6327bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (oxcf->pass == 2) { 6337bc9febe8749e98a3812a0dc4380ceae75c29450Johann base_strength = oxcf->arnr_strength + cpi->twopass.arnr_strength_adjustment; 6347bc9febe8749e98a3812a0dc4380ceae75c29450Johann // Clip to allowed range. 6357bc9febe8749e98a3812a0dc4380ceae75c29450Johann base_strength = VPXMIN(6, VPXMAX(0, base_strength)); 6367bc9febe8749e98a3812a0dc4380ceae75c29450Johann } else { 6377bc9febe8749e98a3812a0dc4380ceae75c29450Johann base_strength = oxcf->arnr_strength; 6387bc9febe8749e98a3812a0dc4380ceae75c29450Johann } 639ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 640ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Define the forward and backwards filter limits for this arnr group. 6417bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (frames_fwd > frames_after_arf) frames_fwd = frames_after_arf; 6427bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (frames_fwd > distance) frames_fwd = distance; 643ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 644ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frames_bwd = frames_fwd; 645ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 646ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // For even length filter there is one more frame backward 647ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff. 6487bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (frames_bwd < distance) frames_bwd += (oxcf->arnr_max_frames + 1) & 0x1; 649ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 650ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Set the baseline active filter size. 6517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frames = frames_bwd + 1 + frames_fwd; 652ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 653ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Adjust the strength based on active max q. 6542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (cpi->common.current_video_frame > 1) 6557bc9febe8749e98a3812a0dc4380ceae75c29450Johann q = ((int)vp9_convert_qindex_to_q(cpi->rc.avg_frame_qindex[INTER_FRAME], 6567bc9febe8749e98a3812a0dc4380ceae75c29450Johann cpi->common.bit_depth)); 6572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian else 6587bc9febe8749e98a3812a0dc4380ceae75c29450Johann q = ((int)vp9_convert_qindex_to_q(cpi->rc.avg_frame_qindex[KEY_FRAME], 6597bc9febe8749e98a3812a0dc4380ceae75c29450Johann cpi->common.bit_depth)); 6602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian if (q > 16) { 6617bc9febe8749e98a3812a0dc4380ceae75c29450Johann strength = base_strength; 662ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } else { 6637bc9febe8749e98a3812a0dc4380ceae75c29450Johann strength = base_strength - ((16 - q) / 2); 6647bc9febe8749e98a3812a0dc4380ceae75c29450Johann if (strength < 0) strength = 0; 665ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 666ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 667ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang // Adjust number of frames in filter and strength based on gf boost level. 6687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frames > group_boost / 150) { 6697ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frames = group_boost / 150; 6707ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frames += !(frames & 1); 671ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 6727ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 6737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (strength > group_boost / 300) { 6747ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian strength = group_boost / 300; 675ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang } 676ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 677ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Adjustments for second level arf in multi arf case. 678ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (cpi->oxcf.pass == 2 && cpi->multi_arf_allowed) { 679ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const GF_GROUP *const gf_group = &cpi->twopass.gf_group; 680ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian if (gf_group->rf_level[gf_group->index] != GF_ARF_STD) { 6817ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian strength >>= 1; 682ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 683ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 6847ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 6857ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *arnr_frames = frames; 6867ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian *arnr_strength = strength; 687ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian} 688ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 689ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid vp9_temporal_filter(VP9_COMP *cpi, int distance) { 690ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian VP9_COMMON *const cm = &cpi->common; 691ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian RATE_CONTROL *const rc = &cpi->rc; 6927ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; 6938b92989c89bec8632aa47dc58dc162f199d62edcJames Zern ARNRFilterData *arnr_filter_data = &cpi->arnr_filter_data; 694ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int frame; 695ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int frames_to_blur; 696ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int start_frame; 697ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int strength; 698ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int frames_to_blur_backward; 699ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian int frames_to_blur_forward; 7008b92989c89bec8632aa47dc58dc162f199d62edcJames Zern struct scale_factors *sf = &arnr_filter_data->sf; 7018b92989c89bec8632aa47dc58dc162f199d62edcJames Zern YV12_BUFFER_CONFIG **frames = arnr_filter_data->frames; 7028b92989c89bec8632aa47dc58dc162f199d62edcJames Zern int rdmult; 703ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 704ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Apply context specific adjustments to the arnr filter parameters. 7057ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian adjust_arnr_filter(cpi, distance, rc->gfu_boost, &frames_to_blur, &strength); 706ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frames_to_blur_backward = (frames_to_blur / 2); 707ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian frames_to_blur_forward = ((frames_to_blur - 1) / 2); 708ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian start_frame = distance + frames_to_blur_forward; 709ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7108b92989c89bec8632aa47dc58dc162f199d62edcJames Zern arnr_filter_data->strength = strength; 7118b92989c89bec8632aa47dc58dc162f199d62edcJames Zern arnr_filter_data->frame_count = frames_to_blur; 7128b92989c89bec8632aa47dc58dc162f199d62edcJames Zern arnr_filter_data->alt_ref_index = frames_to_blur_backward; 7138b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 714ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian // Setup frame pointers, NULL indicates frame not included in filter. 715ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian for (frame = 0; frame < frames_to_blur; ++frame) { 716ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian const int which_buffer = start_frame - frame; 7177bc9febe8749e98a3812a0dc4380ceae75c29450Johann struct lookahead_entry *buf = 7187bc9febe8749e98a3812a0dc4380ceae75c29450Johann vp9_lookahead_peek(cpi->lookahead, which_buffer); 7197ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frames[frames_to_blur - 1 - frame] = &buf->img; 720ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 721ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7227ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (frames_to_blur > 0) { 7237ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // Setup scaling factors. Scaling on each of the arnr frames is not 7247ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // supported. 7257ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (cpi->use_svc) { 7267ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // In spatial svc the scaling factors might be less then 1/2. 7277ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian // So we will use non-normative scaling. 7287ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian int frame_used = 0; 7297ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH 7307ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian vp9_setup_scale_factors_for_frame( 7318b92989c89bec8632aa47dc58dc162f199d62edcJames Zern sf, get_frame_new_buffer(cm)->y_crop_width, 7327ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian get_frame_new_buffer(cm)->y_crop_height, 7337ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian get_frame_new_buffer(cm)->y_crop_width, 7347bc9febe8749e98a3812a0dc4380ceae75c29450Johann get_frame_new_buffer(cm)->y_crop_height, cm->use_highbitdepth); 7357ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#else 7367ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian vp9_setup_scale_factors_for_frame( 7378b92989c89bec8632aa47dc58dc162f199d62edcJames Zern sf, get_frame_new_buffer(cm)->y_crop_width, 7387ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian get_frame_new_buffer(cm)->y_crop_height, 7397ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian get_frame_new_buffer(cm)->y_crop_width, 7407ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian get_frame_new_buffer(cm)->y_crop_height); 7417ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif // CONFIG_VP9_HIGHBITDEPTH 7427ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian 7437ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian for (frame = 0; frame < frames_to_blur; ++frame) { 7447ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (cm->mi_cols * MI_SIZE != frames[frame]->y_width || 7457ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cm->mi_rows * MI_SIZE != frames[frame]->y_height) { 7467ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian if (vpx_realloc_frame_buffer(&cpi->svc.scaled_frames[frame_used], 7477bc9febe8749e98a3812a0dc4380ceae75c29450Johann cm->width, cm->height, cm->subsampling_x, 7487bc9febe8749e98a3812a0dc4380ceae75c29450Johann cm->subsampling_y, 7497ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH 7507ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cm->use_highbitdepth, 7517ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif 7527ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian VP9_ENC_BORDER_IN_PIXELS, 7537bc9febe8749e98a3812a0dc4380ceae75c29450Johann cm->byte_alignment, NULL, NULL, NULL)) { 7547ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, 7557ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian "Failed to reallocate alt_ref_buffer"); 7567ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 7577ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian frames[frame] = vp9_scale_if_required( 7588b92989c89bec8632aa47dc58dc162f199d62edcJames Zern cm, frames[frame], &cpi->svc.scaled_frames[frame_used], 0, 7598b92989c89bec8632aa47dc58dc162f199d62edcJames Zern EIGHTTAP, 0); 7607ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian ++frame_used; 7617ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } 762ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 7637ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian cm->mi = cm->mip + cm->mi_stride + 1; 7647ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian xd->mi = cm->mi_grid_visible; 7657ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian xd->mi[0] = cm->mi; 7667ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian } else { 7677bc9febe8749e98a3812a0dc4380ceae75c29450Johann// ARF is produced at the native frame size and resized when coded. 7687ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#if CONFIG_VP9_HIGHBITDEPTH 7697bc9febe8749e98a3812a0dc4380ceae75c29450Johann vp9_setup_scale_factors_for_frame( 7708b92989c89bec8632aa47dc58dc162f199d62edcJames Zern sf, frames[0]->y_crop_width, frames[0]->y_crop_height, 7717bc9febe8749e98a3812a0dc4380ceae75c29450Johann frames[0]->y_crop_width, frames[0]->y_crop_height, 7727bc9febe8749e98a3812a0dc4380ceae75c29450Johann cm->use_highbitdepth); 7737ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#else 7747bc9febe8749e98a3812a0dc4380ceae75c29450Johann vp9_setup_scale_factors_for_frame( 7758b92989c89bec8632aa47dc58dc162f199d62edcJames Zern sf, frames[0]->y_crop_width, frames[0]->y_crop_height, 7767bc9febe8749e98a3812a0dc4380ceae75c29450Johann frames[0]->y_crop_width, frames[0]->y_crop_height); 7777ce0a1d1337c01056ba24006efab21f00e179e04Vignesh Venkatasubramanian#endif // CONFIG_VP9_HIGHBITDEPTH 778ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 779ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian } 780ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian 7818b92989c89bec8632aa47dc58dc162f199d62edcJames Zern // Initialize errorperbit and sabperbit. 7828b92989c89bec8632aa47dc58dc162f199d62edcJames Zern rdmult = (int)vp9_compute_rd_mult_based_on_qindex(cpi, ARNR_FILT_QINDEX); 7838b92989c89bec8632aa47dc58dc162f199d62edcJames Zern if (rdmult < 1) rdmult = 1; 7848b92989c89bec8632aa47dc58dc162f199d62edcJames Zern set_error_per_bit(&cpi->td.mb, rdmult); 7858b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_initialize_me_consts(cpi, &cpi->td.mb, ARNR_FILT_QINDEX); 7868b92989c89bec8632aa47dc58dc162f199d62edcJames Zern 7878b92989c89bec8632aa47dc58dc162f199d62edcJames Zern if (!cpi->row_mt) 7888b92989c89bec8632aa47dc58dc162f199d62edcJames Zern temporal_filter_iterate_c(cpi); 7898b92989c89bec8632aa47dc58dc162f199d62edcJames Zern else 7908b92989c89bec8632aa47dc58dc162f199d62edcJames Zern vp9_temporal_filter_row_mt(cpi); 791ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang} 792