• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 
12 #include "vpx_ports/config.h"
13 #include <math.h>
14 #include "subpixel.h"
15 #include "vpx_ports/mem.h"
16 
17 #define BLOCK_HEIGHT_WIDTH 4
18 #define VP8_FILTER_WEIGHT 128
19 #define VP8_FILTER_SHIFT  7
20 
21 DECLARE_ALIGNED(16, static const short, sub_pel_filters[8][6]) =
22 {
23     { 0,  0,  128,    0,   0,  0 },         /* note that 1/8 pel positions are just as per alpha -0.5 bicubic */
24     { 0, -6,  123,   12,  -1,  0 },
25     { 2, -11, 108,   36,  -8,  1 },         /* New 1/4 pel 6 tap filter */
26     { 0, -9,   93,   50,  -6,  0 },
27     { 3, -16,  77,   77, -16,  3 },         /* New 1/2 pel 6 tap filter */
28     { 0, -6,   50,   93,  -9,  0 },
29     { 1, -8,   36,  108, -11,  2 },         /* New 1/4 pel 6 tap filter */
30     { 0, -1,   12,  123,  -6,  0 },
31 };
32 
33 
34 extern void vp8_filter_block2d_first_pass_armv6
35 (
36     unsigned char *src_ptr,
37     short         *output_ptr,
38     unsigned int src_pixels_per_line,
39     unsigned int output_width,
40     unsigned int output_height,
41     const short *vp8_filter
42 );
43 
44 extern void vp8_filter_block2d_second_pass_armv6
45 (
46     short         *src_ptr,
47     unsigned char *output_ptr,
48     unsigned int output_pitch,
49     unsigned int cnt,
50     const short *vp8_filter
51 );
52 
53 extern void vp8_filter4_block2d_second_pass_armv6
54 (
55     short         *src_ptr,
56     unsigned char *output_ptr,
57     unsigned int output_pitch,
58     unsigned int cnt,
59     const short *vp8_filter
60 );
61 
62 extern void vp8_filter_block2d_first_pass_only_armv6
63 (
64     unsigned char *src_ptr,
65     unsigned char *output_ptr,
66     unsigned int src_pixels_per_line,
67     unsigned int cnt,
68     unsigned int output_pitch,
69     const short *vp8_filter
70 );
71 
72 
73 extern void vp8_filter_block2d_second_pass_only_armv6
74 (
75     unsigned char *src_ptr,
76     unsigned char *output_ptr,
77     unsigned int src_pixels_per_line,
78     unsigned int cnt,
79     unsigned int output_pitch,
80     const short *vp8_filter
81 );
82 
83 #if HAVE_ARMV6
vp8_sixtap_predict_armv6(unsigned char * src_ptr,int src_pixels_per_line,int xoffset,int yoffset,unsigned char * dst_ptr,int dst_pitch)84 void vp8_sixtap_predict_armv6
85 (
86     unsigned char  *src_ptr,
87     int  src_pixels_per_line,
88     int  xoffset,
89     int  yoffset,
90     unsigned char *dst_ptr,
91     int  dst_pitch
92 )
93 {
94     const short  *HFilter;
95     const short  *VFilter;
96     DECLARE_ALIGNED_ARRAY(4, short, FData, 12*4); /* Temp data bufffer used in filtering */
97 
98 
99     HFilter = sub_pel_filters[xoffset];   /* 6 tap */
100     VFilter = sub_pel_filters[yoffset];       /* 6 tap */
101 
102     /* Vfilter is null. First pass only */
103     if (xoffset && !yoffset)
104     {
105         /*vp8_filter_block2d_first_pass_armv6 ( src_ptr, FData+2, src_pixels_per_line, 4, 4, HFilter );
106         vp8_filter_block2d_second_pass_armv6 ( FData+2, dst_ptr, dst_pitch, 4, VFilter );*/
107 
108         vp8_filter_block2d_first_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 4, dst_pitch, HFilter);
109     }
110     /* Hfilter is null. Second pass only */
111     else if (!xoffset && yoffset)
112     {
113         vp8_filter_block2d_second_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 4, dst_pitch, VFilter);
114     }
115     else
116     {
117         /* Vfilter is a 4 tap filter */
118         if (yoffset & 0x1)
119         {
120             vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 4, 7, HFilter);
121             vp8_filter4_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 4, VFilter);
122         }
123         /* Vfilter is 6 tap filter */
124         else
125         {
126             vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 4, 9, HFilter);
127             vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 4, VFilter);
128         }
129     }
130 }
131 
132 #if 0
133 void vp8_sixtap_predict8x4_armv6
134 (
135     unsigned char  *src_ptr,
136     int  src_pixels_per_line,
137     int  xoffset,
138     int  yoffset,
139     unsigned char *dst_ptr,
140     int  dst_pitch
141 )
142 {
143     const short  *HFilter;
144     const short  *VFilter;
145     DECLARE_ALIGNED_ARRAY(4, short, FData, 16*8); /* Temp data bufffer used in filtering */
146 
147     HFilter = sub_pel_filters[xoffset];   /* 6 tap */
148     VFilter = sub_pel_filters[yoffset];       /* 6 tap */
149 
150 
151     /*if (xoffset && !yoffset)
152     {
153         vp8_filter_block2d_first_pass_only_armv6 (  src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, HFilter );
154     }*/
155     /* Hfilter is null. Second pass only */
156     /*else if (!xoffset && yoffset)
157     {
158         vp8_filter_block2d_second_pass_only_armv6 ( src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, VFilter );
159     }
160     else
161     {
162         if (yoffset & 0x1)
163             vp8_filter_block2d_first_pass_armv6 ( src_ptr-src_pixels_per_line, FData+1, src_pixels_per_line, 8, 7, HFilter );
164         else*/
165 
166         vp8_filter_block2d_first_pass_armv6 ( src_ptr-(2*src_pixels_per_line), FData, src_pixels_per_line, 8, 9, HFilter );
167 
168         vp8_filter_block2d_second_pass_armv6 ( FData+2, dst_ptr, dst_pitch, 4, 8, VFilter );
169     /*}*/
170 }
171 #endif
172 
vp8_sixtap_predict8x8_armv6(unsigned char * src_ptr,int src_pixels_per_line,int xoffset,int yoffset,unsigned char * dst_ptr,int dst_pitch)173 void vp8_sixtap_predict8x8_armv6
174 (
175     unsigned char  *src_ptr,
176     int  src_pixels_per_line,
177     int  xoffset,
178     int  yoffset,
179     unsigned char *dst_ptr,
180     int  dst_pitch
181 )
182 {
183     const short  *HFilter;
184     const short  *VFilter;
185     DECLARE_ALIGNED_ARRAY(4, short, FData, 16*8); /* Temp data bufffer used in filtering */
186 
187     HFilter = sub_pel_filters[xoffset];   /* 6 tap */
188     VFilter = sub_pel_filters[yoffset];       /* 6 tap */
189 
190     if (xoffset && !yoffset)
191     {
192         vp8_filter_block2d_first_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, HFilter);
193     }
194     /* Hfilter is null. Second pass only */
195     else if (!xoffset && yoffset)
196     {
197         vp8_filter_block2d_second_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 8, dst_pitch, VFilter);
198     }
199     else
200     {
201         if (yoffset & 0x1)
202         {
203             vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 8, 11, HFilter);
204             vp8_filter4_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 8, VFilter);
205         }
206         else
207         {
208             vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 8, 13, HFilter);
209             vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 8, VFilter);
210         }
211     }
212 }
213 
214 
vp8_sixtap_predict16x16_armv6(unsigned char * src_ptr,int src_pixels_per_line,int xoffset,int yoffset,unsigned char * dst_ptr,int dst_pitch)215 void vp8_sixtap_predict16x16_armv6
216 (
217     unsigned char  *src_ptr,
218     int  src_pixels_per_line,
219     int  xoffset,
220     int  yoffset,
221     unsigned char *dst_ptr,
222     int  dst_pitch
223 )
224 {
225     const short  *HFilter;
226     const short  *VFilter;
227     DECLARE_ALIGNED_ARRAY(4, short, FData, 24*16);    /* Temp data bufffer used in filtering */
228 
229     HFilter = sub_pel_filters[xoffset];   /* 6 tap */
230     VFilter = sub_pel_filters[yoffset];       /* 6 tap */
231 
232     if (xoffset && !yoffset)
233     {
234         vp8_filter_block2d_first_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 16, dst_pitch, HFilter);
235     }
236     /* Hfilter is null. Second pass only */
237     else if (!xoffset && yoffset)
238     {
239         vp8_filter_block2d_second_pass_only_armv6(src_ptr, dst_ptr, src_pixels_per_line, 16, dst_pitch, VFilter);
240     }
241     else
242     {
243         if (yoffset & 0x1)
244         {
245             vp8_filter_block2d_first_pass_armv6(src_ptr - src_pixels_per_line, FData + 1, src_pixels_per_line, 16, 19, HFilter);
246             vp8_filter4_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 16, VFilter);
247         }
248         else
249         {
250             vp8_filter_block2d_first_pass_armv6(src_ptr - (2 * src_pixels_per_line), FData, src_pixels_per_line, 16, 21, HFilter);
251             vp8_filter_block2d_second_pass_armv6(FData + 2, dst_ptr, dst_pitch, 16, VFilter);
252         }
253     }
254 
255 }
256 #endif
257