vp9_subpelvar.h revision ba164dffc5a6795bce97fae02b51ccf3330e15e4
1ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/*
2ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
4ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  Use of this source code is governed by a BSD-style license
5ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  that can be found in the LICENSE file in the root of the source
6ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  tree. An additional intellectual property rights grant can be found
7ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  in the file PATENTS.  All contributing project authors may
8ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  be found in the AUTHORS file in the root of the source tree.
9ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang */
10ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
11ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#ifndef VP9_COMMON_VP9_SUBPELVAR_H_
12ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define VP9_COMMON_VP9_SUBPELVAR_H_
13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
14ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp9/common/vp9_filter.h"
15ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
16ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void variance(const uint8_t *src_ptr,
17ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int  source_stride,
18ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     const uint8_t *ref_ptr,
19ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int  recon_stride,
20ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int  w,
21ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int  h,
22ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     unsigned int *sse,
23ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                     int *sum) {
24ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int i, j;
25ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int diff;
26ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *sum = 0;
28ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  *sse = 0;
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < h; i++) {
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < w; j++) {
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      diff = src_ptr[j] - ref_ptr[j];
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *sum += diff;
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      *sse += diff * diff;
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    src_ptr += source_stride;
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ref_ptr += recon_stride;
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/****************************************************************************
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  ROUTINE       : filter_block2d_bil_first_pass
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  INPUTS        : uint8_t  *src_ptr          : Pointer to source block.
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t src_pixels_per_line : Stride of input block.
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t pixel_step        : Offset between filter input samples (see notes).
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t output_height     : Input block height.
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t output_width      : Input block width.
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  int32_t  *vp9_filter          : Array of 2 bi-linear filter taps.
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  OUTPUTS       : int32_t *output_ptr        : Pointer to filtered block.
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  RETURNS       : void
56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
57ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  FUNCTION      : Applies a 1-D 2-tap bi-linear filter to the source block in
58ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  either horizontal or vertical direction to produce the
59ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  filtered output block. Used to implement first-pass
60ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  of 2-D separable filter.
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
62ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  SPECIAL NOTES : Produces int32_t output to retain precision for next pass.
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  Two filter taps should sum to VP9_FILTER_WEIGHT.
64ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  pixel_step defines whether the filter is applied
65ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  horizontally (pixel_step=1) or vertically (pixel_step=stride).
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  It defines the offset required to move from one input
67ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  to the next.
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ****************************************************************************/
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void var_filter_block2d_bil_first_pass(const uint8_t *src_ptr,
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              uint16_t *output_ptr,
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              unsigned int src_pixels_per_line,
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              int pixel_step,
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              unsigned int output_height,
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              unsigned int output_width,
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                              const int16_t *vp9_filter) {
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int i, j;
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < output_height; i++) {
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < output_width; j++) {
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Apply bilinear filter
82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      output_ptr[j] = (((int)src_ptr[0]          * vp9_filter[0]) +
83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       ((int)src_ptr[pixel_step] * vp9_filter[1]) +
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       (VP9_FILTER_WEIGHT / 2)) >> VP9_FILTER_SHIFT;
85ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      src_ptr++;
86ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
87ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
88ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Next row...
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    src_ptr    += src_pixels_per_line - output_width;
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    output_ptr += output_width;
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/****************************************************************************
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  ROUTINE       : filter_block2d_bil_second_pass
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  INPUTS        : int32_t  *src_ptr          : Pointer to source block.
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t src_pixels_per_line : Stride of input block.
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t pixel_step        : Offset between filter input samples (see notes).
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t output_height     : Input block height.
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  uint32_t output_width      : Input block width.
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  int32_t  *vp9_filter          : Array of 2 bi-linear filter taps.
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  OUTPUTS       : uint16_t *output_ptr       : Pointer to filtered block.
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  RETURNS       : void
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
109ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  FUNCTION      : Applies a 1-D 2-tap bi-linear filter to the source block in
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  either horizontal or vertical direction to produce the
111ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  filtered output block. Used to implement second-pass
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  of 2-D separable filter.
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *  SPECIAL NOTES : Requires 32-bit input as produced by filter_block2d_bil_first_pass.
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  Two filter taps should sum to VP9_FILTER_WEIGHT.
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  pixel_step defines whether the filter is applied
117ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  horizontally (pixel_step=1) or vertically (pixel_step=stride).
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  It defines the offset required to move from one input
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *                  to the next.
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang *
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang ****************************************************************************/
122ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangstatic void var_filter_block2d_bil_second_pass(const uint16_t *src_ptr,
123ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               uint8_t *output_ptr,
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               unsigned int src_pixels_per_line,
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               unsigned int pixel_step,
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               unsigned int output_height,
127ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               unsigned int output_width,
128ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                               const int16_t *vp9_filter) {
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  unsigned int  i, j;
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  int  Temp;
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
132ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  for (i = 0; i < output_height; i++) {
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    for (j = 0; j < output_width; j++) {
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      // Apply filter
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      Temp = ((int)src_ptr[0]         * vp9_filter[0]) +
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang             ((int)src_ptr[pixel_step] * vp9_filter[1]) +
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang             (VP9_FILTER_WEIGHT / 2);
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      output_ptr[j] = (unsigned int)(Temp >> VP9_FILTER_SHIFT);
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      src_ptr++;
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    }
141ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    // Next row...
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    src_ptr    += src_pixels_per_line - output_width;
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    output_ptr += output_width;
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang}
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#endif  // VP9_COMMON_VP9_SUBPELVAR_H_
149