quantize.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*
  2. * Copyright (c) 2015 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 <assert.h>
  11. #include "./vpx_dsp_rtcd.h"
  12. #include "vpx_dsp/quantize.h"
  13. #include "vpx_mem/vpx_mem.h"
  14. void vpx_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
  15. const int16_t *round_ptr, const int16_t quant,
  16. tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
  17. const int16_t dequant_ptr, uint16_t *eob_ptr) {
  18. const int rc = 0;
  19. const int coeff = coeff_ptr[rc];
  20. const int coeff_sign = (coeff >> 31);
  21. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  22. int tmp, eob = -1;
  23. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  24. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  25. if (!skip_block) {
  26. tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
  27. tmp = (tmp * quant) >> 16;
  28. qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
  29. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr;
  30. if (tmp) eob = 0;
  31. }
  32. *eob_ptr = eob + 1;
  33. }
  34. #if CONFIG_VP9_HIGHBITDEPTH
  35. void vpx_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
  36. int skip_block, const int16_t *round_ptr,
  37. const int16_t quant, tran_low_t *qcoeff_ptr,
  38. tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
  39. uint16_t *eob_ptr) {
  40. int eob = -1;
  41. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  42. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  43. if (!skip_block) {
  44. const int coeff = coeff_ptr[0];
  45. const int coeff_sign = (coeff >> 31);
  46. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  47. const int64_t tmp = abs_coeff + round_ptr[0];
  48. const int abs_qcoeff = (int)((tmp * quant) >> 16);
  49. qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
  50. dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr;
  51. if (abs_qcoeff) eob = 0;
  52. }
  53. *eob_ptr = eob + 1;
  54. }
  55. #endif
  56. void vpx_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
  57. const int16_t *round_ptr, const int16_t quant,
  58. tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
  59. const int16_t dequant_ptr, uint16_t *eob_ptr) {
  60. const int n_coeffs = 1024;
  61. const int rc = 0;
  62. const int coeff = coeff_ptr[rc];
  63. const int coeff_sign = (coeff >> 31);
  64. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  65. int tmp, eob = -1;
  66. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  67. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  68. if (!skip_block) {
  69. tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
  70. INT16_MIN, INT16_MAX);
  71. tmp = (tmp * quant) >> 15;
  72. qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
  73. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr / 2;
  74. if (tmp) eob = 0;
  75. }
  76. *eob_ptr = eob + 1;
  77. }
  78. #if CONFIG_VP9_HIGHBITDEPTH
  79. void vpx_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
  80. const int16_t *round_ptr, const int16_t quant,
  81. tran_low_t *qcoeff_ptr,
  82. tran_low_t *dqcoeff_ptr,
  83. const int16_t dequant_ptr,
  84. uint16_t *eob_ptr) {
  85. const int n_coeffs = 1024;
  86. int eob = -1;
  87. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  88. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  89. if (!skip_block) {
  90. const int coeff = coeff_ptr[0];
  91. const int coeff_sign = (coeff >> 31);
  92. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  93. const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], 1);
  94. const int abs_qcoeff = (int)((tmp * quant) >> 15);
  95. qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
  96. dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant_ptr / 2;
  97. if (abs_qcoeff) eob = 0;
  98. }
  99. *eob_ptr = eob + 1;
  100. }
  101. #endif
  102. void vpx_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
  103. int skip_block, const int16_t *zbin_ptr,
  104. const int16_t *round_ptr, const int16_t *quant_ptr,
  105. const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
  106. tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr,
  107. uint16_t *eob_ptr, const int16_t *scan,
  108. const int16_t *iscan) {
  109. int i, non_zero_count = (int)n_coeffs, eob = -1;
  110. const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
  111. const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
  112. (void)iscan;
  113. (void)skip_block;
  114. assert(!skip_block);
  115. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  116. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  117. // Pre-scan pass
  118. for (i = (int)n_coeffs - 1; i >= 0; i--) {
  119. const int rc = scan[i];
  120. const int coeff = coeff_ptr[rc];
  121. if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
  122. non_zero_count--;
  123. else
  124. break;
  125. }
  126. // Quantization pass: All coefficients with index >= zero_flag are
  127. // skippable. Note: zero_flag can be zero.
  128. for (i = 0; i < non_zero_count; i++) {
  129. const int rc = scan[i];
  130. const int coeff = coeff_ptr[rc];
  131. const int coeff_sign = (coeff >> 31);
  132. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  133. if (abs_coeff >= zbins[rc != 0]) {
  134. int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
  135. tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
  136. quant_shift_ptr[rc != 0]) >>
  137. 16; // quantization
  138. qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
  139. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
  140. if (tmp) eob = i;
  141. }
  142. }
  143. *eob_ptr = eob + 1;
  144. }
  145. #if CONFIG_VP9_HIGHBITDEPTH
  146. void vpx_highbd_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
  147. int skip_block, const int16_t *zbin_ptr,
  148. const int16_t *round_ptr, const int16_t *quant_ptr,
  149. const int16_t *quant_shift_ptr,
  150. tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
  151. const int16_t *dequant_ptr, uint16_t *eob_ptr,
  152. const int16_t *scan, const int16_t *iscan) {
  153. int i, non_zero_count = (int)n_coeffs, eob = -1;
  154. const int zbins[2] = { zbin_ptr[0], zbin_ptr[1] };
  155. const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
  156. (void)iscan;
  157. (void)skip_block;
  158. assert(!skip_block);
  159. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  160. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  161. // Pre-scan pass
  162. for (i = (int)n_coeffs - 1; i >= 0; i--) {
  163. const int rc = scan[i];
  164. const int coeff = coeff_ptr[rc];
  165. if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
  166. non_zero_count--;
  167. else
  168. break;
  169. }
  170. // Quantization pass: All coefficients with index >= zero_flag are
  171. // skippable. Note: zero_flag can be zero.
  172. for (i = 0; i < non_zero_count; i++) {
  173. const int rc = scan[i];
  174. const int coeff = coeff_ptr[rc];
  175. const int coeff_sign = (coeff >> 31);
  176. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  177. if (abs_coeff >= zbins[rc != 0]) {
  178. const int64_t tmp1 = abs_coeff + round_ptr[rc != 0];
  179. const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
  180. const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 16);
  181. qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
  182. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
  183. if (abs_qcoeff) eob = i;
  184. }
  185. }
  186. *eob_ptr = eob + 1;
  187. }
  188. #endif
  189. void vpx_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
  190. int skip_block, const int16_t *zbin_ptr,
  191. const int16_t *round_ptr, const int16_t *quant_ptr,
  192. const int16_t *quant_shift_ptr,
  193. tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
  194. const int16_t *dequant_ptr, uint16_t *eob_ptr,
  195. const int16_t *scan, const int16_t *iscan) {
  196. const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
  197. ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
  198. const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
  199. int idx = 0;
  200. int idx_arr[1024];
  201. int i, eob = -1;
  202. (void)iscan;
  203. (void)skip_block;
  204. assert(!skip_block);
  205. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  206. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  207. // Pre-scan pass
  208. for (i = 0; i < n_coeffs; i++) {
  209. const int rc = scan[i];
  210. const int coeff = coeff_ptr[rc];
  211. // If the coefficient is out of the base ZBIN range, keep it for
  212. // quantization.
  213. if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) idx_arr[idx++] = i;
  214. }
  215. // Quantization pass: only process the coefficients selected in
  216. // pre-scan pass. Note: idx can be zero.
  217. for (i = 0; i < idx; i++) {
  218. const int rc = scan[idx_arr[i]];
  219. const int coeff = coeff_ptr[rc];
  220. const int coeff_sign = (coeff >> 31);
  221. int tmp;
  222. int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  223. abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
  224. abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
  225. tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) *
  226. quant_shift_ptr[rc != 0]) >>
  227. 15;
  228. qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
  229. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
  230. if (tmp) eob = idx_arr[i];
  231. }
  232. *eob_ptr = eob + 1;
  233. }
  234. #if CONFIG_VP9_HIGHBITDEPTH
  235. void vpx_highbd_quantize_b_32x32_c(
  236. const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
  237. const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
  238. const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
  239. tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
  240. const int16_t *scan, const int16_t *iscan) {
  241. const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
  242. ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
  243. const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
  244. int idx = 0;
  245. int idx_arr[1024];
  246. int i, eob = -1;
  247. (void)iscan;
  248. (void)skip_block;
  249. assert(!skip_block);
  250. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  251. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  252. // Pre-scan pass
  253. for (i = 0; i < n_coeffs; i++) {
  254. const int rc = scan[i];
  255. const int coeff = coeff_ptr[rc];
  256. // If the coefficient is out of the base ZBIN range, keep it for
  257. // quantization.
  258. if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) idx_arr[idx++] = i;
  259. }
  260. // Quantization pass: only process the coefficients selected in
  261. // pre-scan pass. Note: idx can be zero.
  262. for (i = 0; i < idx; i++) {
  263. const int rc = scan[idx_arr[i]];
  264. const int coeff = coeff_ptr[rc];
  265. const int coeff_sign = (coeff >> 31);
  266. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  267. const int64_t tmp1 = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
  268. const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
  269. const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
  270. qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
  271. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
  272. if (abs_qcoeff) eob = idx_arr[i];
  273. }
  274. *eob_ptr = eob + 1;
  275. }
  276. #endif