2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
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.
12 #include "./vpx_dsp_rtcd.h"
13 #include "vpx_ports/mem.h"
15 unsigned int vpx_avg_8x8_c(const uint8_t *s
, int p
) {
18 for (i
= 0; i
< 8; ++i
, s
+=p
)
19 for (j
= 0; j
< 8; sum
+= s
[j
], ++j
) {}
21 return (sum
+ 32) >> 6;
24 unsigned int vpx_avg_4x4_c(const uint8_t *s
, int p
) {
27 for (i
= 0; i
< 4; ++i
, s
+=p
)
28 for (j
= 0; j
< 4; sum
+= s
[j
], ++j
) {}
30 return (sum
+ 8) >> 4;
33 // src_diff: first pass, 9 bit, dynamic range [-255, 255]
34 // second pass, 12 bit, dynamic range [-2040, 2040]
35 static void hadamard_col8(const int16_t *src_diff
, int src_stride
,
37 int16_t b0
= src_diff
[0 * src_stride
] + src_diff
[1 * src_stride
];
38 int16_t b1
= src_diff
[0 * src_stride
] - src_diff
[1 * src_stride
];
39 int16_t b2
= src_diff
[2 * src_stride
] + src_diff
[3 * src_stride
];
40 int16_t b3
= src_diff
[2 * src_stride
] - src_diff
[3 * src_stride
];
41 int16_t b4
= src_diff
[4 * src_stride
] + src_diff
[5 * src_stride
];
42 int16_t b5
= src_diff
[4 * src_stride
] - src_diff
[5 * src_stride
];
43 int16_t b6
= src_diff
[6 * src_stride
] + src_diff
[7 * src_stride
];
44 int16_t b7
= src_diff
[6 * src_stride
] - src_diff
[7 * src_stride
];
65 // The order of the output coeff of the hadamard is not important. For
66 // optimization purposes the final transpose may be skipped.
67 void vpx_hadamard_8x8_c(const int16_t *src_diff
, int src_stride
,
71 int16_t *tmp_buf
= &buffer
[0];
72 for (idx
= 0; idx
< 8; ++idx
) {
73 hadamard_col8(src_diff
, src_stride
, tmp_buf
); // src_diff: 9 bit
74 // dynamic range [-255, 255]
80 for (idx
= 0; idx
< 8; ++idx
) {
81 hadamard_col8(tmp_buf
, 8, coeff
); // tmp_buf: 12 bit
82 // dynamic range [-2040, 2040]
83 coeff
+= 8; // coeff: 15 bit
84 // dynamic range [-16320, 16320]
89 // In place 16x16 2D Hadamard transform
90 void vpx_hadamard_16x16_c(const int16_t *src_diff
, int src_stride
,
93 for (idx
= 0; idx
< 4; ++idx
) {
94 // src_diff: 9 bit, dynamic range [-255, 255]
95 const int16_t *src_ptr
= src_diff
+ (idx
>> 1) * 8 * src_stride
97 vpx_hadamard_8x8_c(src_ptr
, src_stride
, coeff
+ idx
* 64);
100 // coeff: 15 bit, dynamic range [-16320, 16320]
101 for (idx
= 0; idx
< 64; ++idx
) {
102 int16_t a0
= coeff
[0];
103 int16_t a1
= coeff
[64];
104 int16_t a2
= coeff
[128];
105 int16_t a3
= coeff
[192];
107 int16_t b0
= (a0
+ a1
) >> 1; // (a0 + a1): 16 bit, [-32640, 32640]
108 int16_t b1
= (a0
- a1
) >> 1; // b0-b3: 15 bit, dynamic range
109 int16_t b2
= (a2
+ a3
) >> 1; // [-16320, 16320]
110 int16_t b3
= (a2
- a3
) >> 1;
112 coeff
[0] = b0
+ b2
; // 16 bit, [-32640, 32640]
114 coeff
[128] = b0
- b2
;
115 coeff
[192] = b1
- b3
;
121 // coeff: 16 bits, dynamic range [-32640, 32640].
122 // length: value range {16, 64, 256, 1024}.
123 int vpx_satd_c(const int16_t *coeff
, int length
) {
126 for (i
= 0; i
< length
; ++i
)
127 satd
+= abs(coeff
[i
]);
129 // satd: 26 bits, dynamic range [-32640 * 1024, 32640 * 1024]
133 // Integer projection onto row vectors.
134 // height: value range {16, 32, 64}.
135 void vpx_int_pro_row_c(int16_t hbuf
[16], const uint8_t *ref
,
136 const int ref_stride
, const int height
) {
138 const int norm_factor
= height
>> 1;
139 for (idx
= 0; idx
< 16; ++idx
) {
142 // hbuf[idx]: 14 bit, dynamic range [0, 16320].
143 for (i
= 0; i
< height
; ++i
)
144 hbuf
[idx
] += ref
[i
* ref_stride
];
145 // hbuf[idx]: 9 bit, dynamic range [0, 510].
146 hbuf
[idx
] /= norm_factor
;
151 // width: value range {16, 32, 64}.
152 int16_t vpx_int_pro_col_c(const uint8_t *ref
, const int width
) {
155 // sum: 14 bit, dynamic range [0, 16320]
156 for (idx
= 0; idx
< width
; ++idx
)
164 int vpx_vector_var_c(const int16_t *ref
, const int16_t *src
,
167 int width
= 4 << bwl
;
168 int sse
= 0, mean
= 0, var
;
170 for (i
= 0; i
< width
; ++i
) {
171 int diff
= ref
[i
] - src
[i
]; // diff: dynamic range [-510, 510], 10 bits.
172 mean
+= diff
; // mean: dynamic range 16 bits.
173 sse
+= diff
* diff
; // sse: dynamic range 26 bits.
176 // (mean * mean): dynamic range 31 bits.
177 var
= sse
- ((mean
* mean
) >> (bwl
+ 2));
181 void vpx_minmax_8x8_c(const uint8_t *s
, int p
, const uint8_t *d
, int dp
,
182 int *min
, int *max
) {
186 for (i
= 0; i
< 8; ++i
, s
+= p
, d
+= dp
) {
187 for (j
= 0; j
< 8; ++j
) {
188 int diff
= abs(s
[j
]-d
[j
]);
189 *min
= diff
< *min
? diff
: *min
;
190 *max
= diff
> *max
? diff
: *max
;
195 #if CONFIG_VP9_HIGHBITDEPTH
196 unsigned int vpx_highbd_avg_8x8_c(const uint8_t *s8
, int p
) {
199 const uint16_t* s
= CONVERT_TO_SHORTPTR(s8
);
200 for (i
= 0; i
< 8; ++i
, s
+=p
)
201 for (j
= 0; j
< 8; sum
+= s
[j
], ++j
) {}
203 return (sum
+ 32) >> 6;
206 unsigned int vpx_highbd_avg_4x4_c(const uint8_t *s8
, int p
) {
209 const uint16_t* s
= CONVERT_TO_SHORTPTR(s8
);
210 for (i
= 0; i
< 4; ++i
, s
+=p
)
211 for (j
= 0; j
< 4; sum
+= s
[j
], ++j
) {}
213 return (sum
+ 8) >> 4;
216 void vpx_highbd_minmax_8x8_c(const uint8_t *s8
, int p
, const uint8_t *d8
,
217 int dp
, int *min
, int *max
) {
219 const uint16_t* s
= CONVERT_TO_SHORTPTR(s8
);
220 const uint16_t* d
= CONVERT_TO_SHORTPTR(d8
);
223 for (i
= 0; i
< 8; ++i
, s
+= p
, d
+= dp
) {
224 for (j
= 0; j
< 8; ++j
) {
225 int diff
= abs(s
[j
]-d
[j
]);
226 *min
= diff
< *min
? diff
: *min
;
227 *max
= diff
> *max
? diff
: *max
;
231 #endif // CONFIG_VP9_HIGHBITDEPTH