1538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/*
2538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *
4538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  Use of this source code is governed by a BSD-style license
5538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  that can be found in the LICENSE file in the root of the source
6538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  tree. An additional intellectual property rights grant can be found
7538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  in the file PATENTS.  All contributing project authors may
8538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
9538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber */
10538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
11538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
1279f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/onyxc_int.h"
13538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "onyx_int.h"
1479f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/systemdependent.h"
15538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "quantize.h"
1679f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/alloccommon.h"
17538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "mcomp.h"
18538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "firstpass.h"
19538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "psnr.h"
20538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "vpx_scale/vpxscale.h"
2179f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/extend.h"
22538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "ratectrl.h"
2379f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/quant_common.h"
24538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "segmentation.h"
2579f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/g_common.h"
26538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "vpx_scale/yv12extend.h"
2779f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/postproc.h"
28538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "vpx_mem/vpx_mem.h"
2979f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/swapyv12buffer.h"
3079f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/threading.h"
31538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "vpx_ports/vpx_timer.h"
32538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
33538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <math.h>
34538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <limits.h>
35538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
36538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ALT_REF_MC_ENABLED 1    // dis/enable MC in AltRef filtering
37538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ALT_REF_SUBPEL_ENABLED 1 // dis/enable subpel in MC AltRef filtering
38538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
39538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if VP8_TEMPORAL_ALT_REF
40538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
4179f15823c34ae1e423108295e416213200bb280fAndreas Huberstatic void vp8_temporal_filter_predictors_mb_c
42538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber(
43538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    MACROBLOCKD *x,
44538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *y_mb_ptr,
45538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *u_mb_ptr,
46538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *v_mb_ptr,
47538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int stride,
48538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int mv_row,
49538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int mv_col,
50538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *pred
51538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber)
52538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{
53538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int offset;
54538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *yptr, *uptr, *vptr;
55538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
56538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // Y
57538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    yptr = y_mb_ptr + (mv_row >> 3) * stride + (mv_col >> 3);
58538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
59538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    if ((mv_row | mv_col) & 7)
60538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
61538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        x->subpixel_predict16x16(yptr, stride,
62538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                                    mv_col & 7, mv_row & 7, &pred[0], 16);
63538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
64538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    else
65538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
66538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        RECON_INVOKE(&x->rtcd->recon, copy16x16)(yptr, stride, &pred[0], 16);
67538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
68538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
69538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // U & V
70538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    mv_row >>= 1;
71538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    mv_col >>= 1;
7279f15823c34ae1e423108295e416213200bb280fAndreas Huber    stride = (stride + 1) >> 1;
73538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    offset = (mv_row >> 3) * stride + (mv_col >> 3);
74538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    uptr = u_mb_ptr + offset;
75538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    vptr = v_mb_ptr + offset;
76538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
77538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    if ((mv_row | mv_col) & 7)
78538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
79538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        x->subpixel_predict8x8(uptr, stride,
80538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                            mv_col & 7, mv_row & 7, &pred[256], 8);
81538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        x->subpixel_predict8x8(vptr, stride,
82538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                            mv_col & 7, mv_row & 7, &pred[320], 8);
83538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
84538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    else
85538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
86538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        RECON_INVOKE(&x->rtcd->recon, copy8x8)(uptr, stride, &pred[256], 8);
87538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        RECON_INVOKE(&x->rtcd->recon, copy8x8)(vptr, stride, &pred[320], 8);
88538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
89538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
9079f15823c34ae1e423108295e416213200bb280fAndreas Hubervoid vp8_temporal_filter_apply_c
91538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber(
92538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *frame1,
93538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned int stride,
94538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *frame2,
95538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned int block_size,
96538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int strength,
97538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int filter_weight,
98538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned int *accumulator,
9979f15823c34ae1e423108295e416213200bb280fAndreas Huber    unsigned short *count
100538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber)
101538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{
102538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int i, j, k;
103538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int modifier;
104538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int byte = 0;
105538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
106538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    for (i = 0,k = 0; i < block_size; i++)
107538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
108538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        for (j = 0; j < block_size; j++, k++)
109538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        {
110538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
111538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            int src_byte = frame1[byte];
112538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            int pixel_value = *frame2++;
113538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
11479f15823c34ae1e423108295e416213200bb280fAndreas Huber            modifier   = src_byte - pixel_value;
11579f15823c34ae1e423108295e416213200bb280fAndreas Huber            // This is an integer approximation of:
11679f15823c34ae1e423108295e416213200bb280fAndreas Huber            // float coeff = (3.0 * modifer * modifier) / pow(2, strength);
11779f15823c34ae1e423108295e416213200bb280fAndreas Huber            // modifier =  (int)roundf(coeff > 16 ? 0 : 16-coeff);
118538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            modifier  *= modifier;
119538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            modifier  *= 3;
12079f15823c34ae1e423108295e416213200bb280fAndreas Huber            modifier  += 1 << (strength - 1);
12179f15823c34ae1e423108295e416213200bb280fAndreas Huber            modifier >>= strength;
122538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
123538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            if (modifier > 16)
124538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                modifier = 16;
125538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
126538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            modifier = 16 - modifier;
127538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            modifier *= filter_weight;
128538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
129538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            count[k] += modifier;
130538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            accumulator[k] += modifier * pixel_value;
131538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
132538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            byte++;
133538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
134538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
135538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        byte += stride - block_size;
136538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
137538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
138538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
139538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if ALT_REF_MC_ENABLED
140538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int dummy_cost[2*mv_max+1];
141538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
14279f15823c34ae1e423108295e416213200bb280fAndreas Huberstatic int vp8_temporal_filter_find_matching_mb_c
143538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber(
144538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    VP8_COMP *cpi,
145538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    YV12_BUFFER_CONFIG *arf_frame,
146538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    YV12_BUFFER_CONFIG *frame_ptr,
147538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int mb_offset,
148538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int error_thresh
149538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber)
150538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{
151538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    MACROBLOCK *x = &cpi->mb;
152538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int thissme;
153538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int step_param;
154538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int further_steps;
155538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int n = 0;
156538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int sadpb = x->sadperbit16;
157538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int bestsme = INT_MAX;
158538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int num00 = 0;
159538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
160538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    BLOCK *b = &x->block[0];
161538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    BLOCKD *d = &x->e_mbd.block[0];
162538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    MV best_ref_mv1 = {0,0};
163538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
164538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int *mvcost[2]    = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
165538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int *mvsadcost[2] = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
166538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
167538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // Save input state
168538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char **base_src = b->base_src;
169538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int src = b->src;
170538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int src_stride = b->src_stride;
171538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char **base_pre = d->base_pre;
172538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int pre = d->pre;
173538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int pre_stride = d->pre_stride;
174538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
175538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // Setup frame pointers
176538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    b->base_src = &arf_frame->y_buffer;
177538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    b->src_stride = arf_frame->y_stride;
178538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    b->src = mb_offset;
179538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
180538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    d->base_pre = &frame_ptr->y_buffer;
181538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    d->pre_stride = frame_ptr->y_stride;
182538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    d->pre = mb_offset;
183538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
184538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // Further step/diamond searches as necessary
185538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    if (cpi->Speed < 8)
186538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
187538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        step_param = cpi->sf.first_step +
188538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    ((cpi->Speed > 5) ? 1 : 0);
189538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        further_steps =
190538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            (cpi->sf.max_step_search_steps - 1)-step_param;
191538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
192538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    else
193538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
194538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        step_param = cpi->sf.first_step + 2;
195538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        further_steps = 0;
196538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
197538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
198538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    if (1/*cpi->sf.search_method == HEX*/)
199538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
200538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // TODO Check that the 16x16 vf & sdf are selected here
201538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        bestsme = vp8_hex_search(x, b, d,
202538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            &best_ref_mv1, &d->bmi.mv.as_mv,
203538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            step_param,
204538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            sadpb/*x->errorperbit*/,
205538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            &num00, &cpi->fn_ptr[BLOCK_16X16],
20679f15823c34ae1e423108295e416213200bb280fAndreas Huber            mvsadcost, mvcost, &best_ref_mv1);
207538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
208538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    else
209538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
210538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        int mv_x, mv_y;
211538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
212538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        bestsme = cpi->diamond_search_sad(x, b, d,
213538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            &best_ref_mv1, &d->bmi.mv.as_mv,
214538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            step_param,
215538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            sadpb / 2/*x->errorperbit*/,
216538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            &num00, &cpi->fn_ptr[BLOCK_16X16],
21779f15823c34ae1e423108295e416213200bb280fAndreas Huber            mvsadcost, mvcost, &best_ref_mv1); //sadpb < 9
218538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
219538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // Further step/diamond searches as necessary
220538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        n = 0;
221538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        //further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
222538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
223538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        n = num00;
224538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        num00 = 0;
225538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
226538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        while (n < further_steps)
227538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        {
228538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            n++;
229538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
230538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            if (num00)
231538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                num00--;
232538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            else
233538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            {
234538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                thissme = cpi->diamond_search_sad(x, b, d,
235538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    &best_ref_mv1, &d->bmi.mv.as_mv,
236538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    step_param + n,
237538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    sadpb / 4/*x->errorperbit*/,
238538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    &num00, &cpi->fn_ptr[BLOCK_16X16],
23979f15823c34ae1e423108295e416213200bb280fAndreas Huber                    mvsadcost, mvcost, &best_ref_mv1); //sadpb = 9
240538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
241538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                if (thissme < bestsme)
242538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                {
243538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    bestsme = thissme;
244538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    mv_y = d->bmi.mv.as_mv.row;
245538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    mv_x = d->bmi.mv.as_mv.col;
246538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                }
247538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                else
248538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                {
249538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    d->bmi.mv.as_mv.row = mv_y;
250538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    d->bmi.mv.as_mv.col = mv_x;
251538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                }
252538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            }
253538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
254538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
255538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
256538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if ALT_REF_SUBPEL_ENABLED
257538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // Try sub-pixel MC?
258538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    //if (bestsme > error_thresh && bestsme < INT_MAX)
259538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
260538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        bestsme = cpi->find_fractional_mv_step(x, b, d,
261538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    &d->bmi.mv.as_mv, &best_ref_mv1,
262538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    x->errorperbit, &cpi->fn_ptr[BLOCK_16X16],
26379f15823c34ae1e423108295e416213200bb280fAndreas Huber                    mvcost);
264538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
265538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
266538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
267538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // Save input state
268538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    b->base_src = base_src;
269538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    b->src = src;
270538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    b->src_stride = src_stride;
271538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    d->base_pre = base_pre;
272538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    d->pre = pre;
273538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    d->pre_stride = pre_stride;
274538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
275538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    return bestsme;
276538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
277538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
278538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
27979f15823c34ae1e423108295e416213200bb280fAndreas Huberstatic void vp8_temporal_filter_iterate_c
280538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber(
281538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    VP8_COMP *cpi,
282538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int frame_count,
283538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int alt_ref_index,
284538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int strength
285538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber)
286538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{
287538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int byte;
288538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int frame;
289538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int mb_col, mb_row;
29079f15823c34ae1e423108295e416213200bb280fAndreas Huber    unsigned int filter_weight;
29179f15823c34ae1e423108295e416213200bb280fAndreas Huber    int mb_cols = cpi->common.mb_cols;
29279f15823c34ae1e423108295e416213200bb280fAndreas Huber    int mb_rows = cpi->common.mb_rows;
293538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int MBs  = cpi->common.MBs;
294538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int mb_y_offset = 0;
295538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int mb_uv_offset = 0;
29679f15823c34ae1e423108295e416213200bb280fAndreas Huber    DECLARE_ALIGNED_ARRAY(16, unsigned int, accumulator, 16*16 + 8*8 + 8*8);
29779f15823c34ae1e423108295e416213200bb280fAndreas Huber    DECLARE_ALIGNED_ARRAY(16, unsigned short, count, 16*16 + 8*8 + 8*8);
298538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    MACROBLOCKD *mbd = &cpi->mb.e_mbd;
299538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    YV12_BUFFER_CONFIG *f = cpi->frames[alt_ref_index];
300538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *dst1, *dst2;
30179f15823c34ae1e423108295e416213200bb280fAndreas Huber    DECLARE_ALIGNED_ARRAY(16, unsigned char,  predictor, 16*16 + 8*8 + 8*8);
302538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
303538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // Save input state
304538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *y_buffer = mbd->pre.y_buffer;
305538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *u_buffer = mbd->pre.u_buffer;
306538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned char *v_buffer = mbd->pre.v_buffer;
307538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
30879f15823c34ae1e423108295e416213200bb280fAndreas Huber    for (mb_row = 0; mb_row < mb_rows; mb_row++)
309538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
310538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if ALT_REF_MC_ENABLED
311538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // Reduced search extent by 3 for 6-tap filter & smaller UMV border
312538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        cpi->mb.mv_row_min = -((mb_row * 16) + (VP8BORDERINPIXELS - 19));
313538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        cpi->mb.mv_row_max = ((cpi->common.mb_rows - 1 - mb_row) * 16)
314538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                                + (VP8BORDERINPIXELS - 19);
315538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
316538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
31779f15823c34ae1e423108295e416213200bb280fAndreas Huber        for (mb_col = 0; mb_col < mb_cols; mb_col++)
318538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        {
319538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            int i, j, k, w;
320538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            int weight_cap;
321538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            int stride;
322538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
323538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            vpx_memset(accumulator, 0, 384*sizeof(unsigned int));
32479f15823c34ae1e423108295e416213200bb280fAndreas Huber            vpx_memset(count, 0, 384*sizeof(unsigned short));
325538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
326538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if ALT_REF_MC_ENABLED
327538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            // Reduced search extent by 3 for 6-tap filter & smaller UMV border
328538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            cpi->mb.mv_col_min = -((mb_col * 16) + (VP8BORDERINPIXELS - 19));
329538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            cpi->mb.mv_col_max = ((cpi->common.mb_cols - 1 - mb_col) * 16)
330538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                                    + (VP8BORDERINPIXELS - 19);
331538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
332538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
333538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            for (frame = 0; frame < frame_count; frame++)
334538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            {
33579f15823c34ae1e423108295e416213200bb280fAndreas Huber                int err = 0;
336538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
337538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                if (cpi->frames[frame] == NULL)
338538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    continue;
339538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
340538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                mbd->block[0].bmi.mv.as_mv.row = 0;
341538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                mbd->block[0].bmi.mv.as_mv.col = 0;
342538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
343538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#if ALT_REF_MC_ENABLED
344538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define THRESH_LOW   10000
345538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define THRESH_HIGH  20000
346538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
34779f15823c34ae1e423108295e416213200bb280fAndreas Huber                // Find best match in this frame by MC
34879f15823c34ae1e423108295e416213200bb280fAndreas Huber                err = vp8_temporal_filter_find_matching_mb_c
34979f15823c34ae1e423108295e416213200bb280fAndreas Huber                      (cpi,
35079f15823c34ae1e423108295e416213200bb280fAndreas Huber                       cpi->frames[alt_ref_index],
35179f15823c34ae1e423108295e416213200bb280fAndreas Huber                       cpi->frames[frame],
35279f15823c34ae1e423108295e416213200bb280fAndreas Huber                       mb_y_offset,
35379f15823c34ae1e423108295e416213200bb280fAndreas Huber                       THRESH_LOW);
35479f15823c34ae1e423108295e416213200bb280fAndreas Huber
355538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
35679f15823c34ae1e423108295e416213200bb280fAndreas Huber                // Assign higher weight to matching MB if it's error
35779f15823c34ae1e423108295e416213200bb280fAndreas Huber                // score is lower. If not applying MC default behavior
35879f15823c34ae1e423108295e416213200bb280fAndreas Huber                // is to weight all MBs equal.
35979f15823c34ae1e423108295e416213200bb280fAndreas Huber                filter_weight = err<THRESH_LOW
36079f15823c34ae1e423108295e416213200bb280fAndreas Huber                                  ? 2 : err<THRESH_HIGH ? 1 : 0;
36179f15823c34ae1e423108295e416213200bb280fAndreas Huber
36279f15823c34ae1e423108295e416213200bb280fAndreas Huber                if (filter_weight != 0)
363538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                {
364538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    // Construct the predictors
36579f15823c34ae1e423108295e416213200bb280fAndreas Huber                    vp8_temporal_filter_predictors_mb_c
36679f15823c34ae1e423108295e416213200bb280fAndreas Huber                        (mbd,
36779f15823c34ae1e423108295e416213200bb280fAndreas Huber                         cpi->frames[frame]->y_buffer + mb_y_offset,
36879f15823c34ae1e423108295e416213200bb280fAndreas Huber                         cpi->frames[frame]->u_buffer + mb_uv_offset,
36979f15823c34ae1e423108295e416213200bb280fAndreas Huber                         cpi->frames[frame]->v_buffer + mb_uv_offset,
37079f15823c34ae1e423108295e416213200bb280fAndreas Huber                         cpi->frames[frame]->y_stride,
37179f15823c34ae1e423108295e416213200bb280fAndreas Huber                         mbd->block[0].bmi.mv.as_mv.row,
37279f15823c34ae1e423108295e416213200bb280fAndreas Huber                         mbd->block[0].bmi.mv.as_mv.col,
37379f15823c34ae1e423108295e416213200bb280fAndreas Huber                         predictor);
374538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
375538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    // Apply the filter (YUV)
37679f15823c34ae1e423108295e416213200bb280fAndreas Huber                    TEMPORAL_INVOKE(&cpi->rtcd.temporal, apply)
37779f15823c34ae1e423108295e416213200bb280fAndreas Huber                        (f->y_buffer + mb_y_offset,
37879f15823c34ae1e423108295e416213200bb280fAndreas Huber                         f->y_stride,
37979f15823c34ae1e423108295e416213200bb280fAndreas Huber                         predictor,
38079f15823c34ae1e423108295e416213200bb280fAndreas Huber                         16,
38179f15823c34ae1e423108295e416213200bb280fAndreas Huber                         strength,
38279f15823c34ae1e423108295e416213200bb280fAndreas Huber                         filter_weight,
38379f15823c34ae1e423108295e416213200bb280fAndreas Huber                         accumulator,
38479f15823c34ae1e423108295e416213200bb280fAndreas Huber                         count);
38579f15823c34ae1e423108295e416213200bb280fAndreas Huber
38679f15823c34ae1e423108295e416213200bb280fAndreas Huber                    TEMPORAL_INVOKE(&cpi->rtcd.temporal, apply)
38779f15823c34ae1e423108295e416213200bb280fAndreas Huber                        (f->u_buffer + mb_uv_offset,
38879f15823c34ae1e423108295e416213200bb280fAndreas Huber                         f->uv_stride,
38979f15823c34ae1e423108295e416213200bb280fAndreas Huber                         predictor + 256,
39079f15823c34ae1e423108295e416213200bb280fAndreas Huber                         8,
39179f15823c34ae1e423108295e416213200bb280fAndreas Huber                         strength,
39279f15823c34ae1e423108295e416213200bb280fAndreas Huber                         filter_weight,
39379f15823c34ae1e423108295e416213200bb280fAndreas Huber                         accumulator + 256,
39479f15823c34ae1e423108295e416213200bb280fAndreas Huber                         count + 256);
39579f15823c34ae1e423108295e416213200bb280fAndreas Huber
39679f15823c34ae1e423108295e416213200bb280fAndreas Huber                    TEMPORAL_INVOKE(&cpi->rtcd.temporal, apply)
39779f15823c34ae1e423108295e416213200bb280fAndreas Huber                        (f->v_buffer + mb_uv_offset,
39879f15823c34ae1e423108295e416213200bb280fAndreas Huber                         f->uv_stride,
39979f15823c34ae1e423108295e416213200bb280fAndreas Huber                         predictor + 320,
40079f15823c34ae1e423108295e416213200bb280fAndreas Huber                         8,
40179f15823c34ae1e423108295e416213200bb280fAndreas Huber                         strength,
40279f15823c34ae1e423108295e416213200bb280fAndreas Huber                         filter_weight,
40379f15823c34ae1e423108295e416213200bb280fAndreas Huber                         accumulator + 320,
40479f15823c34ae1e423108295e416213200bb280fAndreas Huber                         count + 320);
405538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                }
406538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            }
407538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
408538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            // Normalize filter output to produce AltRef frame
409538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            dst1 = cpi->alt_ref_buffer.source_buffer.y_buffer;
410538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            stride = cpi->alt_ref_buffer.source_buffer.y_stride;
411538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            byte = mb_y_offset;
412538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            for (i = 0,k = 0; i < 16; i++)
413538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            {
414538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                for (j = 0; j < 16; j++, k++)
415538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                {
416538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    unsigned int pval = accumulator[k] + (count[k] >> 1);
417538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    pval *= cpi->fixed_divide[count[k]];
418538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    pval >>= 19;
419538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
420538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    dst1[byte] = (unsigned char)pval;
421538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
422538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    // move to next pixel
423538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    byte++;
424538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                }
425538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
426538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                byte += stride - 16;
427538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            }
428538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
429538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            dst1 = cpi->alt_ref_buffer.source_buffer.u_buffer;
430538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            dst2 = cpi->alt_ref_buffer.source_buffer.v_buffer;
431538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            stride = cpi->alt_ref_buffer.source_buffer.uv_stride;
432538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            byte = mb_uv_offset;
433538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            for (i = 0,k = 256; i < 8; i++)
434538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            {
435538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                for (j = 0; j < 8; j++, k++)
436538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                {
437538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    int m=k+64;
438538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
439538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    // U
440538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    unsigned int pval = accumulator[k] + (count[k] >> 1);
441538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    pval *= cpi->fixed_divide[count[k]];
442538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    pval >>= 19;
443538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    dst1[byte] = (unsigned char)pval;
444538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
445538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    // V
446538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    pval = accumulator[m] + (count[m] >> 1);
447538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    pval *= cpi->fixed_divide[count[m]];
448538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    pval >>= 19;
449538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    dst2[byte] = (unsigned char)pval;
450538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
451538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    // move to next pixel
452538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    byte++;
453538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                }
454538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
455538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                byte += stride - 8;
456538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            }
457538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
458538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            mb_y_offset += 16;
459538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            mb_uv_offset += 8;
460538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
461538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
46279f15823c34ae1e423108295e416213200bb280fAndreas Huber        mb_y_offset += 16*(f->y_stride-mb_cols);
46379f15823c34ae1e423108295e416213200bb280fAndreas Huber        mb_uv_offset += 8*(f->uv_stride-mb_cols);
464538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
465538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
466538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // Restore input state
467538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    mbd->pre.y_buffer = y_buffer;
468538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    mbd->pre.u_buffer = u_buffer;
469538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    mbd->pre.v_buffer = v_buffer;
470538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
471538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
47279f15823c34ae1e423108295e416213200bb280fAndreas Hubervoid vp8_temporal_filter_prepare_c
473538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber(
474538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    VP8_COMP *cpi
475538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber)
476538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{
477538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int frame = 0;
478538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
479538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int num_frames_backward = 0;
480538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int num_frames_forward = 0;
481538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int frames_to_blur_backward = 0;
482538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int frames_to_blur_forward = 0;
483538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int frames_to_blur = 0;
484538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int start_frame = 0;
485538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    unsigned int filtered = 0;
486538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
487538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int strength = cpi->oxcf.arnr_strength;
488538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
489538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int blur_type = cpi->oxcf.arnr_type;
490538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
491538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int max_frames = cpi->active_arnr_frames;
492538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
493538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    num_frames_backward = cpi->last_alt_ref_sei - cpi->source_encode_index;
494538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
495538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    if (num_frames_backward < 0)
496538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        num_frames_backward += cpi->oxcf.lag_in_frames;
497538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
498538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    num_frames_forward = cpi->oxcf.lag_in_frames - (num_frames_backward + 1);
499538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
500538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    switch (blur_type)
501538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
502538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    case 1:
503538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /////////////////////////////////////////
504538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // Backward Blur
505538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
506538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        frames_to_blur_backward = num_frames_backward;
507538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
508538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (frames_to_blur_backward >= max_frames)
509538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            frames_to_blur_backward = max_frames - 1;
510538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
511538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        frames_to_blur = frames_to_blur_backward + 1;
512538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        break;
513538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
514538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    case 2:
515538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /////////////////////////////////////////
516538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // Forward Blur
517538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
518538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        frames_to_blur_forward = num_frames_forward;
519538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
520538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (frames_to_blur_forward >= max_frames)
521538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            frames_to_blur_forward = max_frames - 1;
522538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
523538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        frames_to_blur = frames_to_blur_forward + 1;
524538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        break;
525538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
526538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    case 3:
527538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    default:
528538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        /////////////////////////////////////////
529538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // Center Blur
530538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        frames_to_blur_forward = num_frames_forward;
531538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        frames_to_blur_backward = num_frames_backward;
532538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
533538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (frames_to_blur_forward > frames_to_blur_backward)
534538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            frames_to_blur_forward = frames_to_blur_backward;
535538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
536538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (frames_to_blur_backward > frames_to_blur_forward)
537538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            frames_to_blur_backward = frames_to_blur_forward;
538538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
539538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // When max_frames is even we have 1 more frame backward than forward
540538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (frames_to_blur_forward > (max_frames - 1) / 2)
541538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            frames_to_blur_forward = ((max_frames - 1) / 2);
542538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
543538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (frames_to_blur_backward > (max_frames / 2))
544538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            frames_to_blur_backward = (max_frames / 2);
545538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
546538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        frames_to_blur = frames_to_blur_backward + frames_to_blur_forward + 1;
547538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        break;
548538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
549538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
550538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    start_frame = (cpi->last_alt_ref_sei
551538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    + frames_to_blur_forward) % cpi->oxcf.lag_in_frames;
552538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
553538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#ifdef DEBUGFWG
554538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // DEBUG FWG
555538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    printf("max:%d FBCK:%d FFWD:%d ftb:%d ftbbck:%d ftbfwd:%d sei:%d lasei:%d start:%d"
556538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber           , max_frames
557538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber           , num_frames_backward
558538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber           , num_frames_forward
559538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber           , frames_to_blur
560538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber           , frames_to_blur_backward
561538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber           , frames_to_blur_forward
562538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber           , cpi->source_encode_index
563538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber           , cpi->last_alt_ref_sei
564538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber           , start_frame);
565538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
566538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
567538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    // Setup frame pointers, NULL indicates frame not included in filter
568538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    vpx_memset(cpi->frames, 0, max_frames*sizeof(YV12_BUFFER_CONFIG *));
569538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    for (frame = 0; frame < frames_to_blur; frame++)
570538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    {
571538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        int which_buffer =  start_frame - frame;
572538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
573538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (which_buffer < 0)
574538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            which_buffer += cpi->oxcf.lag_in_frames;
575538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
576538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        cpi->frames[frames_to_blur-1-frame]
577538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                = &cpi->src_buffer[which_buffer].source_buffer;
578538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
579538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
58079f15823c34ae1e423108295e416213200bb280fAndreas Huber    vp8_temporal_filter_iterate_c (
581538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        cpi,
582538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        frames_to_blur,
583538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        frames_to_blur_backward,
584538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        strength );
585538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}
586538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#endif
587