16fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org/* 26fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * 46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * Use of this source code is governed by a BSD-style license 56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * that can be found in the LICENSE file in the root of the source 66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * tree. An additional intellectual property rights grant can be found 76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * in the file PATENTS. All contributing project authors may 86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org * be found in the AUTHORS file in the root of the source tree. 96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */ 106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 113f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org#include <math.h> 123f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org#include <limits.h> 136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 14d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vp9/common/vp9_alloccommon.h" 156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/common/vp9_onyxc_int.h" 16d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vp9/common/vp9_quant_common.h" 173f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org#include "vp9/common/vp9_reconinter.h" 186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/common/vp9_systemdependent.h" 19d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vp9/encoder/vp9_extend.h" 206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/encoder/vp9_firstpass.h" 21d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vp9/encoder/vp9_mcomp.h" 22693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#include "vp9/encoder/vp9_encoder.h" 23d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vp9/encoder/vp9_quantize.h" 246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/encoder/vp9_ratectrl.h" 256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/encoder/vp9_segmentation.h" 266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vpx_mem/vpx_mem.h" 276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vpx_ports/vpx_timer.h" 28d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#include "vpx_scale/vpx_scale.h" 296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 309a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.orgstatic int fixed_divide[512]; 319a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org 32d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgstatic void temporal_filter_predictors_mb_c(MACROBLOCKD *xd, 33d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org uint8_t *y_mb_ptr, 34d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org uint8_t *u_mb_ptr, 35d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org uint8_t *v_mb_ptr, 36d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org int stride, 3788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int uv_block_width, 3888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org int uv_block_height, 39d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org int mv_row, 40d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org int mv_col, 41ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org uint8_t *pred, 420e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org struct scale_factors *scale, 430e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org int x, int y) { 443f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org const int which_mv = 0; 4593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const MV mv = { mv_row, mv_col }; 4693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const InterpKernel *const kernel = 4787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vp9_get_interp_kernel(xd->mi[0].src_mi->mbmi.interp_filter); 4893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 490e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org enum mv_precision mv_precision_uv; 500e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org int uv_stride; 5188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (uv_block_width == 8) { 520e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org uv_stride = (stride + 1) >> 1; 530e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org mv_precision_uv = MV_PRECISION_Q4; 540e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org } else { 550e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org uv_stride = stride; 560e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org mv_precision_uv = MV_PRECISION_Q3; 570e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org } 583f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org 593f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org vp9_build_inter_predictor(y_mb_ptr, stride, 603f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org &pred[0], 16, 6110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org &mv, 62ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org scale, 633f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org 16, 16, 6410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org which_mv, 6593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org kernel, MV_PRECISION_Q3, x, y); 663f0af3b06425f635f3559f0bd4f53efea95fa5e2johannkoenig@chromium.org 670e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org vp9_build_inter_predictor(u_mb_ptr, uv_stride, 6888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org &pred[256], uv_block_width, 6947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org &mv, 70ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org scale, 7188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uv_block_width, uv_block_height, 7247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org which_mv, 7393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org kernel, mv_precision_uv, x, y); 7447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org 750e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org vp9_build_inter_predictor(v_mb_ptr, uv_stride, 7688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org &pred[512], uv_block_width, 7747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org &mv, 78ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org scale, 7988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org uv_block_width, uv_block_height, 8047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org which_mv, 8193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org kernel, mv_precision_uv, x, y); 826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 83d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 849a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.orgvoid vp9_temporal_filter_init() { 859a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org int i; 869a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org 879a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org fixed_divide[0] = 0; 889a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org for (i = 1; i < 512; ++i) 899a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org fixed_divide[i] = 0x80000 / i; 909a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org} 919a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org 92d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgvoid vp9_temporal_filter_apply_c(uint8_t *frame1, 93d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org unsigned int stride, 94d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org uint8_t *frame2, 9588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org unsigned int block_width, 9688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org unsigned int block_height, 97d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org int strength, 98d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org int filter_weight, 99d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org unsigned int *accumulator, 100d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org uint16_t *count) { 1016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org unsigned int i, j, k; 1026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int modifier; 1036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int byte = 0; 104810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org const int rounding = strength > 0 ? 1 << (strength - 1) : 0; 1056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 10688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (i = 0, k = 0; i < block_height; i++) { 10788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (j = 0; j < block_width; j++, k++) { 1086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int src_byte = frame1[byte]; 1096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int pixel_value = *frame2++; 1106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org modifier = src_byte - pixel_value; 1126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // This is an integer approximation of: 1136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // float coeff = (3.0 * modifer * modifier) / pow(2, strength); 1146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // modifier = (int)roundf(coeff > 16 ? 0 : 16-coeff); 1156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org modifier *= modifier; 1166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org modifier *= 3; 117810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.org modifier += rounding; 1186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org modifier >>= strength; 1196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (modifier > 16) 1216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org modifier = 16; 1226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org modifier = 16 - modifier; 1246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org modifier *= filter_weight; 1256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org count[k] += modifier; 1276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org accumulator[k] += modifier * pixel_value; 1286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org byte++; 1306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 1316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 13288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org byte += stride - block_width; 1336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 1346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 1356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 136d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgstatic int temporal_filter_find_matching_mb_c(VP9_COMP *cpi, 13710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org uint8_t *arf_frame_buf, 13810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org uint8_t *frame_ptr_buf, 139411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org int stride) { 14088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MACROBLOCK *const x = &cpi->mb; 14188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org MACROBLOCKD *const xd = &x->e_mbd; 14288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv; 1436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int step_param; 1446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int sadpb = x->sadperbit16; 1456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int bestsme = INT_MAX; 146693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com int distortion; 147693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com unsigned int sse; 148d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org int sad_list[5]; 1496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 15076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org MV best_ref_mv1 = {0, 0}; 15176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */ 15287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org MV *ref_mv = &x->e_mbd.mi[0].src_mi->bmi[0].as_mv[0].as_mv; 1536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Save input state 15510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org struct buf_2d src = x->plane[0].src; 15610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org struct buf_2d pre = xd->plane[0].pre[0]; 1576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 15876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org best_ref_mv1_full.col = best_ref_mv1.col >> 3; 15976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org best_ref_mv1_full.row = best_ref_mv1.row >> 3; 1606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Setup frame pointers 16210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org x->plane[0].src.buf = arf_frame_buf; 16310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org x->plane[0].src.stride = stride; 16410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org xd->plane[0].pre[0].buf = frame_ptr_buf; 16510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org xd->plane[0].pre[0].stride = stride; 1666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 167e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org step_param = mv_sf->reduce_first_step_size; 168e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org step_param = MIN(step_param, MAX_MVSEARCH_STEPS - 2); 1696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Ignore mv costing by sending NULL pointer instead of cost arrays 17176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org vp9_hex_search(x, &best_ref_mv1_full, step_param, sadpb, 1, 172d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org cond_sad_list(cpi, sad_list), 17376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org &cpi->fn_ptr[BLOCK_16X16], 0, &best_ref_mv1, ref_mv); 1746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 175693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com // Ignore mv costing by sending NULL pointer instead of cost array 176693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com bestsme = cpi->find_fractional_mv_step(x, ref_mv, 177693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com &best_ref_mv1, 178693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com cpi->common.allow_high_precision_mv, 179693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com x->errorperbit, 180693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com &cpi->fn_ptr[BLOCK_16X16], 18188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org 0, mv_sf->subpel_iters_per_step, 182d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org cond_sad_list(cpi, sad_list), 183693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com NULL, NULL, 18495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com &distortion, &sse, NULL, 0, 0); 1856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 18610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org // Restore input state 18710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org x->plane[0].src = src; 18810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org xd->plane[0].pre[0] = pre; 1896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org return bestsme; 1916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 1926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 193d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgstatic void temporal_filter_iterate_c(VP9_COMP *cpi, 194d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org YV12_BUFFER_CONFIG **frames, 195d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org int frame_count, 196d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org int alt_ref_index, 197ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org int strength, 198ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org struct scale_factors *scale) { 1996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int byte; 2006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int frame; 2016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int mb_col, mb_row; 2026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org unsigned int filter_weight; 20387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int mb_cols = (frames[alt_ref_index]->y_crop_width + 15) >> 4; 20487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int mb_rows = (frames[alt_ref_index]->y_crop_height + 15) >> 4; 2056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int mb_y_offset = 0; 2066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int mb_uv_offset = 0; 2070e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, unsigned int, accumulator, 16 * 16 * 3); 2080e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, uint16_t, count, 16 * 16 * 3); 2096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org MACROBLOCKD *mbd = &cpi->mb.e_mbd; 210d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org YV12_BUFFER_CONFIG *f = frames[alt_ref_index]; 211d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org uint8_t *dst1, *dst2; 2120e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, uint8_t, predictor, 16 * 16 * 3); 2130e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org const int mb_uv_height = 16 >> mbd->plane[1].subsampling_y; 21488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int mb_uv_width = 16 >> mbd->plane[1].subsampling_x; 2156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Save input state 21710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org uint8_t* input_buffer[MAX_MB_PLANE]; 21810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org int i; 21910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org 22010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org for (i = 0; i < MAX_MB_PLANE; i++) 22110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org input_buffer[i] = mbd->plane[i].pre[0].buf; 2226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (mb_row = 0; mb_row < mb_rows; mb_row++) { 224693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com // Source frames are extended to 16 pixels. This is different than 225dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // L/A/G reference frames that have a border of 32 (VP9ENCBORDERINPIXELS) 2266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // A 6/8 tap filter is used for motion search. This requires 2 pixels 2276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // before and 3 pixels after. So the largest Y mv on a border would 2286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // then be 16 - VP9_INTERP_EXTEND. The UV blocks are half the size of the 2296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Y and therefore only extended by 8. The largest mv that a UV block 2306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // can support is 8 - VP9_INTERP_EXTEND. A UV mv is half of a Y mv. 2316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // (16 - VP9_INTERP_EXTEND) >> 1 which is greater than 2326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // 8 - VP9_INTERP_EXTEND. 2336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // To keep the mv in play for both Y and UV planes the max that it 2346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // can be on a border is therefore 16 - (2*VP9_INTERP_EXTEND+1). 2356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org cpi->mb.mv_row_min = -((mb_row * 16) + (17 - 2 * VP9_INTERP_EXTEND)); 23687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->mb.mv_row_max = ((mb_rows - 1 - mb_row) * 16) 2376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org + (17 - 2 * VP9_INTERP_EXTEND); 2386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (mb_col = 0; mb_col < mb_cols; mb_col++) { 2406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int i, j, k; 2416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org int stride; 2426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2430e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org vpx_memset(accumulator, 0, 16 * 16 * 3 * sizeof(accumulator[0])); 2440e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org vpx_memset(count, 0, 16 * 16 * 3 * sizeof(count[0])); 2456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org cpi->mb.mv_col_min = -((mb_col * 16) + (17 - 2 * VP9_INTERP_EXTEND)); 24787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->mb.mv_col_max = ((mb_cols - 1 - mb_col) * 16) 2486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org + (17 - 2 * VP9_INTERP_EXTEND); 2496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (frame = 0; frame < frame_count; frame++) { 251693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com const int thresh_low = 10000; 252693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com const int thresh_high = 20000; 253693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com 254d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (frames[frame] == NULL) 2556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org continue; 2566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 25787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org mbd->mi[0].src_mi->bmi[0].as_mv[0].as_mv.row = 0; 25887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org mbd->mi[0].src_mi->bmi[0].as_mv[0].as_mv.col = 0; 2596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (frame == alt_ref_index) { 2616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org filter_weight = 2; 2626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } else { 2636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Find best match in this frame by MC 264693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com int err = temporal_filter_find_matching_mb_c(cpi, 265d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames[alt_ref_index]->y_buffer + mb_y_offset, 266d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames[frame]->y_buffer + mb_y_offset, 267d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames[frame]->y_stride); 268693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com 2696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Assign higher weight to matching MB if it's error 2706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // score is lower. If not applying MC default behavior 2716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // is to weight all MBs equal. 272693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com filter_weight = err < thresh_low 273693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com ? 2 : err < thresh_high ? 1 : 0; 2746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 2756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (filter_weight != 0) { 2776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Construct the predictors 278693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com temporal_filter_predictors_mb_c(mbd, 279d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames[frame]->y_buffer + mb_y_offset, 280d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames[frame]->u_buffer + mb_uv_offset, 281d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames[frame]->v_buffer + mb_uv_offset, 282d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames[frame]->y_stride, 28388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org mb_uv_width, mb_uv_height, 28487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org mbd->mi[0].src_mi->bmi[0].as_mv[0].as_mv.row, 28587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org mbd->mi[0].src_mi->bmi[0].as_mv[0].as_mv.col, 286693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com predictor, scale, 287693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com mb_col * 16, mb_row * 16); 2886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Apply the filter (YUV) 2906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vp9_temporal_filter_apply(f->y_buffer + mb_y_offset, f->y_stride, 29188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org predictor, 16, 16, 29288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org strength, filter_weight, 2936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org accumulator, count); 2946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vp9_temporal_filter_apply(f->u_buffer + mb_uv_offset, f->uv_stride, 29588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org predictor + 256, 29688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org mb_uv_width, mb_uv_height, strength, 2970e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org filter_weight, accumulator + 256, 2980e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org count + 256); 2996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org vp9_temporal_filter_apply(f->v_buffer + mb_uv_offset, f->uv_stride, 30088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org predictor + 512, 30188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org mb_uv_width, mb_uv_height, strength, 3020e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org filter_weight, accumulator + 512, 3030e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org count + 512); 3046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Normalize filter output to produce AltRef frame 3086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org dst1 = cpi->alt_ref_buffer.y_buffer; 3096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org stride = cpi->alt_ref_buffer.y_stride; 3106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org byte = mb_y_offset; 3116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (i = 0, k = 0; i < 16; i++) { 3126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (j = 0; j < 16; j++, k++) { 3136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org unsigned int pval = accumulator[k] + (count[k] >> 1); 3149a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org pval *= fixed_divide[count[k]]; 3156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org pval >>= 19; 3166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 317d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org dst1[byte] = (uint8_t)pval; 3186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // move to next pixel 3206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org byte++; 3216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org byte += stride - 16; 3236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org dst1 = cpi->alt_ref_buffer.u_buffer; 3266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org dst2 = cpi->alt_ref_buffer.v_buffer; 3276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org stride = cpi->alt_ref_buffer.uv_stride; 3286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org byte = mb_uv_offset; 3290e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org for (i = 0, k = 256; i < mb_uv_height; i++) { 33088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org for (j = 0; j < mb_uv_width; j++, k++) { 3310e29f91ae7876791fc422e9c7cea72b1866439a6johannkoenig@chromium.org int m = k + 256; 3326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // U 3346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org unsigned int pval = accumulator[k] + (count[k] >> 1); 3359a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org pval *= fixed_divide[count[k]]; 3366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org pval >>= 19; 337d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org dst1[byte] = (uint8_t)pval; 3386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // V 3406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org pval = accumulator[m] + (count[m] >> 1); 3419a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org pval *= fixed_divide[count[m]]; 3426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org pval >>= 19; 343d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org dst2[byte] = (uint8_t)pval; 3446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // move to next pixel 3466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org byte++; 3476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 34888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org byte += stride - mb_uv_width; 3496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org mb_y_offset += 16; 35188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org mb_uv_offset += mb_uv_width; 3526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org mb_y_offset += 16 * (f->y_stride - mb_cols); 35488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org mb_uv_offset += mb_uv_height * f->uv_stride - mb_uv_width * mb_cols; 3556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Restore input state 35810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org for (i = 0; i < MAX_MB_PLANE; i++) 35910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org mbd->plane[i].pre[0].buf = input_buffer[i]; 3606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 3616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 36295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com// Apply buffer limits and context specific adjustments to arnr filter. 36395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.comstatic void adjust_arnr_filter(VP9_COMP *cpi, 36441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int distance, int group_boost, 36541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int *arnr_frames, int *arnr_strength) { 36641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org const VP9EncoderConfig *const oxcf = &cpi->oxcf; 36795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com const int frames_after_arf = 36841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org vp9_lookahead_depth(cpi->lookahead) - distance - 1; 36995aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com int frames_fwd = (cpi->oxcf.arnr_max_frames - 1) >> 1; 37095aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com int frames_bwd; 37141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org int q, frames, strength; 3726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 37395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com // Define the forward and backwards filter limits for this arnr group. 37495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com if (frames_fwd > frames_after_arf) 37595aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com frames_fwd = frames_after_arf; 37695aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com if (frames_fwd > distance) 37795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com frames_fwd = distance; 37810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org 37995aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com frames_bwd = frames_fwd; 38010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org 38195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com // For even length filter there is one more frame backward 38295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com // than forward: e.g. len=6 ==> bbbAff, len=7 ==> bbbAfff. 38395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com if (frames_bwd < distance) 38441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org frames_bwd += (oxcf->arnr_max_frames + 1) & 0x1; 38510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org 38695aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com // Set the baseline active filter size. 38741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org frames = frames_bwd + 1 + frames_fwd; 38810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org 38995aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com // Adjust the strength based on active max q. 39076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org if (cpi->common.current_video_frame > 1) 3919a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org q = ((int)vp9_convert_qindex_to_q( 39287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->rc.avg_frame_qindex[INTER_FRAME], cpi->common.bit_depth)); 39376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org else 3949a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org q = ((int)vp9_convert_qindex_to_q( 39587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->rc.avg_frame_qindex[KEY_FRAME], cpi->common.bit_depth)); 39676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org if (q > 16) { 39741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org strength = oxcf->arnr_strength; 39810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org } else { 39941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org strength = oxcf->arnr_strength - ((16 - q) / 2); 40041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (strength < 0) 40141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org strength = 0; 40210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org } 40310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org 40410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org // Adjust number of frames in filter and strength based on gf boost level. 40541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (frames > group_boost / 150) { 40641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org frames = group_boost / 150; 40741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org frames += !(frames & 1); 40810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org } 40941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 41041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (strength > group_boost / 300) { 41141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org strength = group_boost / 300; 41210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org } 41395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com 41495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com // Adjustments for second level arf in multi arf case. 41541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (cpi->oxcf.pass == 2 && cpi->multi_arf_allowed) { 41695aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com const GF_GROUP *const gf_group = &cpi->twopass.gf_group; 41795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com if (gf_group->rf_level[gf_group->index] != GF_ARF_STD) { 41841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org strength >>= 1; 41995aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com } 42095aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com } 42141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 42241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org *arnr_frames = frames; 42341294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org *arnr_strength = strength; 42495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com} 42595aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com 42695aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.comvoid vp9_temporal_filter(VP9_COMP *cpi, int distance) { 42795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com VP9_COMMON *const cm = &cpi->common; 42895aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com RATE_CONTROL *const rc = &cpi->rc; 42995aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com int frame; 43095aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com int frames_to_blur; 43195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com int start_frame; 43295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com int strength; 43395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com int frames_to_blur_backward; 43495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com int frames_to_blur_forward; 43595aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com struct scale_factors sf; 436d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = {NULL}; 43795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com 43895aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com // Apply context specific adjustments to the arnr filter parameters. 43941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org adjust_arnr_filter(cpi, distance, rc->gfu_boost, &frames_to_blur, &strength); 44095aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com frames_to_blur_backward = (frames_to_blur / 2); 44195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com frames_to_blur_forward = ((frames_to_blur - 1) / 2); 44295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com start_frame = distance + frames_to_blur_forward; 44395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com 44495aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com // Setup frame pointers, NULL indicates frame not included in filter. 44595aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com for (frame = 0; frame < frames_to_blur; ++frame) { 44695aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com const int which_buffer = start_frame - frame; 44795aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead, 44895aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com which_buffer); 449d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames[frames_to_blur - 1 - frame] = &buf->img; 45095aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com } 45195aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com 452ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org // Setup scaling factors. Scaling on each of the arnr frames is not supported 453d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (is_two_pass_svc(cpi)) { 454ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org // In spatial svc the scaling factors might be less then 1/2. So we will use 455ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org // non-normative scaling. 456ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org int frame_used = 0; 45787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 45887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vp9_setup_scale_factors_for_frame(&sf, 45987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org get_frame_new_buffer(cm)->y_crop_width, 46087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org get_frame_new_buffer(cm)->y_crop_height, 46187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org get_frame_new_buffer(cm)->y_crop_width, 46287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org get_frame_new_buffer(cm)->y_crop_height, 46387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cm->use_highbitdepth); 46487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#else 465ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org vp9_setup_scale_factors_for_frame(&sf, 466ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org get_frame_new_buffer(cm)->y_crop_width, 467ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org get_frame_new_buffer(cm)->y_crop_height, 468ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org get_frame_new_buffer(cm)->y_crop_width, 469ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org get_frame_new_buffer(cm)->y_crop_height); 47087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 471ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org for (frame = 0; frame < frames_to_blur; ++frame) { 472d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (cm->mi_cols * MI_SIZE != frames[frame]->y_width || 473d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org cm->mi_rows * MI_SIZE != frames[frame]->y_height) { 474ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org if (vp9_realloc_frame_buffer(&cpi->svc.scaled_frames[frame_used], 475ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org cm->width, cm->height, 476ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org cm->subsampling_x, cm->subsampling_y, 477d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 478d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org cm->use_highbitdepth, 479d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org#endif 480ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, 481ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org NULL)) 482ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, 483ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org "Failed to reallocate alt_ref_buffer"); 484ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 485d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames[frame] = vp9_scale_if_required(cm, frames[frame], 486d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org &cpi->svc.scaled_frames[frame_used]); 487ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org ++frame_used; 488ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } 489ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } 490ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } else { 49187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org // ARF is produced at the native frame size and resized when coded. 49287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 493ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org vp9_setup_scale_factors_for_frame(&sf, 49487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org frames[0]->y_crop_width, 49587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org frames[0]->y_crop_height, 49687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org frames[0]->y_crop_width, 49787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org frames[0]->y_crop_height, 49887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cm->use_highbitdepth); 49987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#else 50087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vp9_setup_scale_factors_for_frame(&sf, 50187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org frames[0]->y_crop_width, 50287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org frames[0]->y_crop_height, 50387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org frames[0]->y_crop_width, 50487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org frames[0]->y_crop_height); 50587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 506ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } 507ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 508d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org temporal_filter_iterate_c(cpi, frames, frames_to_blur, 509d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org frames_to_blur_backward, strength, &sf); 5106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 511