variance.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. #include "./vpx_config.h"
  11. #include "./vpx_dsp_rtcd.h"
  12. #include "vpx_ports/mem.h"
  13. #include "vpx/vpx_integer.h"
  14. unsigned int vpx_get4x4sse_cs_c(const unsigned char *a, int a_stride,
  15. const unsigned char *b, int b_stride) {
  16. int distortion = 0;
  17. int r, c;
  18. for (r = 0; r < 4; r++) {
  19. for (c = 0; c < 4; c++) {
  20. int diff = a[c] - b[c];
  21. distortion += diff * diff;
  22. }
  23. a += a_stride;
  24. b += b_stride;
  25. }
  26. return distortion;
  27. }
  28. unsigned int vpx_get_mb_ss_c(const int16_t *a) {
  29. unsigned int i, sum = 0;
  30. for (i = 0; i < 256; ++i) {
  31. sum += a[i] * a[i];
  32. }
  33. return sum;
  34. }
  35. static void variance(const uint8_t *a, int a_stride,
  36. const uint8_t *b, int b_stride,
  37. int w, int h, unsigned int *sse, int *sum) {
  38. int i, j;
  39. *sum = 0;
  40. *sse = 0;
  41. for (i = 0; i < h; i++) {
  42. for (j = 0; j < w; j++) {
  43. const int diff = a[j] - b[j];
  44. *sum += diff;
  45. *sse += diff * diff;
  46. }
  47. a += a_stride;
  48. b += b_stride;
  49. }
  50. }
  51. #define VAR(W, H) \
  52. unsigned int vpx_variance##W##x##H##_c(const uint8_t *a, int a_stride, \
  53. const uint8_t *b, int b_stride, \
  54. unsigned int *sse) { \
  55. int sum; \
  56. variance(a, a_stride, b, b_stride, W, H, sse, &sum); \
  57. return *sse - (((int64_t)sum * sum) / (W * H)); \
  58. }
  59. /* Identical to the variance call except it takes an additional parameter, sum,
  60. * and returns that value using pass-by-reference instead of returning
  61. * sse - sum^2 / w*h
  62. */
  63. #define GET_VAR(W, H) \
  64. void vpx_get##W##x##H##var_c(const uint8_t *a, int a_stride, \
  65. const uint8_t *b, int b_stride, \
  66. unsigned int *sse, int *sum) { \
  67. variance(a, a_stride, b, b_stride, W, H, sse, sum); \
  68. }
  69. /* Identical to the variance call except it does not calculate the
  70. * sse - sum^2 / w*h and returns sse in addtion to modifying the passed in
  71. * variable.
  72. */
  73. #define MSE(W, H) \
  74. unsigned int vpx_mse##W##x##H##_c(const uint8_t *a, int a_stride, \
  75. const uint8_t *b, int b_stride, \
  76. unsigned int *sse) { \
  77. int sum; \
  78. variance(a, a_stride, b, b_stride, W, H, sse, &sum); \
  79. return *sse; \
  80. }
  81. VAR(64, 64)
  82. VAR(64, 32)
  83. VAR(32, 64)
  84. VAR(32, 32)
  85. VAR(32, 16)
  86. VAR(16, 32)
  87. VAR(16, 16)
  88. VAR(16, 8)
  89. VAR(8, 16)
  90. VAR(8, 8)
  91. VAR(8, 4)
  92. VAR(4, 8)
  93. VAR(4, 4)
  94. GET_VAR(16, 16)
  95. GET_VAR(8, 8)
  96. MSE(16, 16)
  97. MSE(16, 8)
  98. MSE(8, 16)
  99. MSE(8, 8)
  100. void vpx_comp_avg_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width,
  101. int height, const uint8_t *ref, int ref_stride) {
  102. int i, j;
  103. for (i = 0; i < height; i++) {
  104. for (j = 0; j < width; j++) {
  105. const int tmp = pred[j] + ref[j];
  106. comp_pred[j] = ROUND_POWER_OF_TWO(tmp, 1);
  107. }
  108. comp_pred += width;
  109. pred += width;
  110. ref += ref_stride;
  111. }
  112. }
  113. #if CONFIG_VP9_HIGHBITDEPTH
  114. static void highbd_variance64(const uint8_t *a8, int a_stride,
  115. const uint8_t *b8, int b_stride,
  116. int w, int h, uint64_t *sse, uint64_t *sum) {
  117. int i, j;
  118. uint16_t *a = CONVERT_TO_SHORTPTR(a8);
  119. uint16_t *b = CONVERT_TO_SHORTPTR(b8);
  120. *sum = 0;
  121. *sse = 0;
  122. for (i = 0; i < h; i++) {
  123. for (j = 0; j < w; j++) {
  124. const int diff = a[j] - b[j];
  125. *sum += diff;
  126. *sse += diff * diff;
  127. }
  128. a += a_stride;
  129. b += b_stride;
  130. }
  131. }
  132. static void highbd_8_variance(const uint8_t *a8, int a_stride,
  133. const uint8_t *b8, int b_stride,
  134. int w, int h, unsigned int *sse, int *sum) {
  135. uint64_t sse_long = 0;
  136. uint64_t sum_long = 0;
  137. highbd_variance64(a8, a_stride, b8, b_stride, w, h, &sse_long, &sum_long);
  138. *sse = (unsigned int)sse_long;
  139. *sum = (int)sum_long;
  140. }
  141. static void highbd_10_variance(const uint8_t *a8, int a_stride,
  142. const uint8_t *b8, int b_stride,
  143. int w, int h, unsigned int *sse, int *sum) {
  144. uint64_t sse_long = 0;
  145. uint64_t sum_long = 0;
  146. highbd_variance64(a8, a_stride, b8, b_stride, w, h, &sse_long, &sum_long);
  147. *sse = (unsigned int)ROUND_POWER_OF_TWO(sse_long, 4);
  148. *sum = (int)ROUND_POWER_OF_TWO(sum_long, 2);
  149. }
  150. static void highbd_12_variance(const uint8_t *a8, int a_stride,
  151. const uint8_t *b8, int b_stride,
  152. int w, int h, unsigned int *sse, int *sum) {
  153. uint64_t sse_long = 0;
  154. uint64_t sum_long = 0;
  155. highbd_variance64(a8, a_stride, b8, b_stride, w, h, &sse_long, &sum_long);
  156. *sse = (unsigned int)ROUND_POWER_OF_TWO(sse_long, 8);
  157. *sum = (int)ROUND_POWER_OF_TWO(sum_long, 4);
  158. }
  159. #define HIGHBD_VAR(W, H) \
  160. unsigned int vpx_highbd_8_variance##W##x##H##_c(const uint8_t *a, \
  161. int a_stride, \
  162. const uint8_t *b, \
  163. int b_stride, \
  164. unsigned int *sse) { \
  165. int sum; \
  166. highbd_8_variance(a, a_stride, b, b_stride, W, H, sse, &sum); \
  167. return *sse - (((int64_t)sum * sum) / (W * H)); \
  168. } \
  169. \
  170. unsigned int vpx_highbd_10_variance##W##x##H##_c(const uint8_t *a, \
  171. int a_stride, \
  172. const uint8_t *b, \
  173. int b_stride, \
  174. unsigned int *sse) { \
  175. int sum; \
  176. highbd_10_variance(a, a_stride, b, b_stride, W, H, sse, &sum); \
  177. return *sse - (((int64_t)sum * sum) / (W * H)); \
  178. } \
  179. \
  180. unsigned int vpx_highbd_12_variance##W##x##H##_c(const uint8_t *a, \
  181. int a_stride, \
  182. const uint8_t *b, \
  183. int b_stride, \
  184. unsigned int *sse) { \
  185. int sum; \
  186. highbd_12_variance(a, a_stride, b, b_stride, W, H, sse, &sum); \
  187. return *sse - (((int64_t)sum * sum) / (W * H)); \
  188. }
  189. #define HIGHBD_GET_VAR(S) \
  190. void vpx_highbd_8_get##S##x##S##var_c(const uint8_t *src, int src_stride, \
  191. const uint8_t *ref, int ref_stride, \
  192. unsigned int *sse, int *sum) { \
  193. highbd_8_variance(src, src_stride, ref, ref_stride, S, S, sse, sum); \
  194. } \
  195. \
  196. void vpx_highbd_10_get##S##x##S##var_c(const uint8_t *src, int src_stride, \
  197. const uint8_t *ref, int ref_stride, \
  198. unsigned int *sse, int *sum) { \
  199. highbd_10_variance(src, src_stride, ref, ref_stride, S, S, sse, sum); \
  200. } \
  201. \
  202. void vpx_highbd_12_get##S##x##S##var_c(const uint8_t *src, int src_stride, \
  203. const uint8_t *ref, int ref_stride, \
  204. unsigned int *sse, int *sum) { \
  205. highbd_12_variance(src, src_stride, ref, ref_stride, S, S, sse, sum); \
  206. }
  207. #define HIGHBD_MSE(W, H) \
  208. unsigned int vpx_highbd_8_mse##W##x##H##_c(const uint8_t *src, \
  209. int src_stride, \
  210. const uint8_t *ref, \
  211. int ref_stride, \
  212. unsigned int *sse) { \
  213. int sum; \
  214. highbd_8_variance(src, src_stride, ref, ref_stride, W, H, sse, &sum); \
  215. return *sse; \
  216. } \
  217. \
  218. unsigned int vpx_highbd_10_mse##W##x##H##_c(const uint8_t *src, \
  219. int src_stride, \
  220. const uint8_t *ref, \
  221. int ref_stride, \
  222. unsigned int *sse) { \
  223. int sum; \
  224. highbd_10_variance(src, src_stride, ref, ref_stride, W, H, sse, &sum); \
  225. return *sse; \
  226. } \
  227. \
  228. unsigned int vpx_highbd_12_mse##W##x##H##_c(const uint8_t *src, \
  229. int src_stride, \
  230. const uint8_t *ref, \
  231. int ref_stride, \
  232. unsigned int *sse) { \
  233. int sum; \
  234. highbd_12_variance(src, src_stride, ref, ref_stride, W, H, sse, &sum); \
  235. return *sse; \
  236. }
  237. HIGHBD_GET_VAR(8)
  238. HIGHBD_GET_VAR(16)
  239. HIGHBD_MSE(16, 16)
  240. HIGHBD_MSE(16, 8)
  241. HIGHBD_MSE(8, 16)
  242. HIGHBD_MSE(8, 8)
  243. HIGHBD_VAR(64, 64)
  244. HIGHBD_VAR(64, 32)
  245. HIGHBD_VAR(32, 64)
  246. HIGHBD_VAR(32, 32)
  247. HIGHBD_VAR(32, 16)
  248. HIGHBD_VAR(16, 32)
  249. HIGHBD_VAR(16, 16)
  250. HIGHBD_VAR(16, 8)
  251. HIGHBD_VAR(8, 16)
  252. HIGHBD_VAR(8, 8)
  253. HIGHBD_VAR(8, 4)
  254. HIGHBD_VAR(4, 8)
  255. HIGHBD_VAR(4, 4)
  256. void vpx_highbd_comp_avg_pred(uint16_t *comp_pred, const uint8_t *pred8,
  257. int width, int height, const uint8_t *ref8,
  258. int ref_stride) {
  259. int i, j;
  260. uint16_t *pred = CONVERT_TO_SHORTPTR(pred8);
  261. uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
  262. for (i = 0; i < height; i++) {
  263. for (j = 0; j < width; j++) {
  264. const int tmp = pred[j] + ref[j];
  265. comp_pred[j] = ROUND_POWER_OF_TWO(tmp, 1);
  266. }
  267. comp_pred += width;
  268. pred += width;
  269. ref += ref_stride;
  270. }
  271. }
  272. #endif // CONFIG_VP9_HIGHBITDEPTH