1 /* 2 * Copyright (c) 2014 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 #include "./vp9_rtcd.h" 11 #include "vp9/common/vp9_common.h" 12 #include "vpx_ports/mem.h" 13 14 unsigned int vp9_avg_8x8_c(const uint8_t *s, int p) { 15 int i, j; 16 int sum = 0; 17 for (i = 0; i < 8; ++i, s+=p) 18 for (j = 0; j < 8; sum += s[j], ++j) {} 19 20 return (sum + 32) >> 6; 21 } 22 23 unsigned int vp9_avg_4x4_c(const uint8_t *s, int p) { 24 int i, j; 25 int sum = 0; 26 for (i = 0; i < 4; ++i, s+=p) 27 for (j = 0; j < 4; sum += s[j], ++j) {} 28 29 return (sum + 8) >> 4; 30 } 31 32 // src_diff: first pass, 9 bit, dynamic range [-255, 255] 33 // second pass, 12 bit, dynamic range [-2040, 2040] 34 static void hadamard_col8(const int16_t *src_diff, int src_stride, 35 int16_t *coeff) { 36 int16_t b0 = src_diff[0 * src_stride] + src_diff[1 * src_stride]; 37 int16_t b1 = src_diff[0 * src_stride] - src_diff[1 * src_stride]; 38 int16_t b2 = src_diff[2 * src_stride] + src_diff[3 * src_stride]; 39 int16_t b3 = src_diff[2 * src_stride] - src_diff[3 * src_stride]; 40 int16_t b4 = src_diff[4 * src_stride] + src_diff[5 * src_stride]; 41 int16_t b5 = src_diff[4 * src_stride] - src_diff[5 * src_stride]; 42 int16_t b6 = src_diff[6 * src_stride] + src_diff[7 * src_stride]; 43 int16_t b7 = src_diff[6 * src_stride] - src_diff[7 * src_stride]; 44 45 int16_t c0 = b0 + b2; 46 int16_t c1 = b1 + b3; 47 int16_t c2 = b0 - b2; 48 int16_t c3 = b1 - b3; 49 int16_t c4 = b4 + b6; 50 int16_t c5 = b5 + b7; 51 int16_t c6 = b4 - b6; 52 int16_t c7 = b5 - b7; 53 54 coeff[0] = c0 + c4; 55 coeff[7] = c1 + c5; 56 coeff[3] = c2 + c6; 57 coeff[4] = c3 + c7; 58 coeff[2] = c0 - c4; 59 coeff[6] = c1 - c5; 60 coeff[1] = c2 - c6; 61 coeff[5] = c3 - c7; 62 } 63 64 void vp9_hadamard_8x8_c(int16_t const *src_diff, int src_stride, 65 int16_t *coeff) { 66 int idx; 67 int16_t buffer[64]; 68 int16_t *tmp_buf = &buffer[0]; 69 for (idx = 0; idx < 8; ++idx) { 70 hadamard_col8(src_diff, src_stride, tmp_buf); // src_diff: 9 bit 71 // dynamic range [-255, 255] 72 tmp_buf += 8; 73 ++src_diff; 74 } 75 76 tmp_buf = &buffer[0]; 77 for (idx = 0; idx < 8; ++idx) { 78 hadamard_col8(tmp_buf, 8, coeff); // tmp_buf: 12 bit 79 // dynamic range [-2040, 2040] 80 coeff += 8; // coeff: 15 bit 81 // dynamic range [-16320, 16320] 82 ++tmp_buf; 83 } 84 } 85 86 // In place 16x16 2D Hadamard transform 87 void vp9_hadamard_16x16_c(int16_t const *src_diff, int src_stride, 88 int16_t *coeff) { 89 int idx; 90 for (idx = 0; idx < 4; ++idx) { 91 // src_diff: 9 bit, dynamic range [-255, 255] 92 int16_t const *src_ptr = src_diff + (idx >> 1) * 8 * src_stride 93 + (idx & 0x01) * 8; 94 vp9_hadamard_8x8_c(src_ptr, src_stride, coeff + idx * 64); 95 } 96 97 // coeff: 15 bit, dynamic range [-16320, 16320] 98 for (idx = 0; idx < 64; ++idx) { 99 int16_t a0 = coeff[0]; 100 int16_t a1 = coeff[64]; 101 int16_t a2 = coeff[128]; 102 int16_t a3 = coeff[192]; 103 104 int16_t b0 = (a0 + a1) >> 1; // (a0 + a1): 16 bit, [-32640, 32640] 105 int16_t b1 = (a0 - a1) >> 1; // b0-b3: 15 bit, dynamic range 106 int16_t b2 = (a2 + a3) >> 1; // [-16320, 16320] 107 int16_t b3 = (a2 - a3) >> 1; 108 109 coeff[0] = b0 + b2; // 16 bit, [-32640, 32640] 110 coeff[64] = b1 + b3; 111 coeff[128] = b0 - b2; 112 coeff[192] = b1 - b3; 113 114 ++coeff; 115 } 116 } 117 118 // coeff: 16 bits, dynamic range [-32640, 32640]. 119 // length: value range {16, 64, 256, 1024}. 120 int16_t vp9_satd_c(const int16_t *coeff, int length) { 121 int i; 122 int satd = 0; 123 for (i = 0; i < length; ++i) 124 satd += abs(coeff[i]); 125 126 // satd: 26 bits, dynamic range [-32640 * 1024, 32640 * 1024] 127 return (int16_t)satd; 128 } 129 130 // Integer projection onto row vectors. 131 // height: value range {16, 32, 64}. 132 void vp9_int_pro_row_c(int16_t hbuf[16], uint8_t const *ref, 133 const int ref_stride, const int height) { 134 int idx; 135 const int norm_factor = height >> 1; 136 for (idx = 0; idx < 16; ++idx) { 137 int i; 138 hbuf[idx] = 0; 139 // hbuf[idx]: 14 bit, dynamic range [0, 16320]. 140 for (i = 0; i < height; ++i) 141 hbuf[idx] += ref[i * ref_stride]; 142 // hbuf[idx]: 9 bit, dynamic range [0, 510]. 143 hbuf[idx] /= norm_factor; 144 ++ref; 145 } 146 } 147 148 // width: value range {16, 32, 64}. 149 int16_t vp9_int_pro_col_c(uint8_t const *ref, const int width) { 150 int idx; 151 int16_t sum = 0; 152 // sum: 14 bit, dynamic range [0, 16320] 153 for (idx = 0; idx < width; ++idx) 154 sum += ref[idx]; 155 return sum; 156 } 157 158 // ref: [0 - 510] 159 // src: [0 - 510] 160 // bwl: {2, 3, 4} 161 int vp9_vector_var_c(int16_t const *ref, int16_t const *src, 162 const int bwl) { 163 int i; 164 int width = 4 << bwl; 165 int sse = 0, mean = 0, var; 166 167 for (i = 0; i < width; ++i) { 168 int diff = ref[i] - src[i]; // diff: dynamic range [-510, 510], 10 bits. 169 mean += diff; // mean: dynamic range 16 bits. 170 sse += diff * diff; // sse: dynamic range 26 bits. 171 } 172 173 // (mean * mean): dynamic range 31 bits. 174 var = sse - ((mean * mean) >> (bwl + 2)); 175 return var; 176 } 177 178 void vp9_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, 179 int *min, int *max) { 180 int i, j; 181 *min = 255; 182 *max = 0; 183 for (i = 0; i < 8; ++i, s += p, d += dp) { 184 for (j = 0; j < 8; ++j) { 185 int diff = abs(s[j]-d[j]); 186 *min = diff < *min ? diff : *min; 187 *max = diff > *max ? diff : *max; 188 } 189 } 190 } 191 192 #if CONFIG_VP9_HIGHBITDEPTH 193 unsigned int vp9_highbd_avg_8x8_c(const uint8_t *s8, int p) { 194 int i, j; 195 int sum = 0; 196 const uint16_t* s = CONVERT_TO_SHORTPTR(s8); 197 for (i = 0; i < 8; ++i, s+=p) 198 for (j = 0; j < 8; sum += s[j], ++j) {} 199 200 return (sum + 32) >> 6; 201 } 202 203 unsigned int vp9_highbd_avg_4x4_c(const uint8_t *s8, int p) { 204 int i, j; 205 int sum = 0; 206 const uint16_t* s = CONVERT_TO_SHORTPTR(s8); 207 for (i = 0; i < 4; ++i, s+=p) 208 for (j = 0; j < 4; sum += s[j], ++j) {} 209 210 return (sum + 8) >> 4; 211 } 212 213 void vp9_highbd_minmax_8x8_c(const uint8_t *s8, int p, const uint8_t *d8, 214 int dp, int *min, int *max) { 215 int i, j; 216 const uint16_t* s = CONVERT_TO_SHORTPTR(s8); 217 const uint16_t* d = CONVERT_TO_SHORTPTR(d8); 218 *min = 255; 219 *max = 0; 220 for (i = 0; i < 8; ++i, s += p, d += dp) { 221 for (j = 0; j < 8; ++j) { 222 int diff = abs(s[j]-d[j]); 223 *min = diff < *min ? diff : *min; 224 *max = diff > *max ? diff : *max; 225 } 226 } 227 } 228 #endif // CONFIG_VP9_HIGHBITDEPTH 229 230 231