quantize.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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_dsp/vpx_dsp_common.h"
  14. #include "vpx_mem/vpx_mem.h"
  15. void vpx_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
  16. const int16_t *round_ptr, const int16_t quant,
  17. tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
  18. const int16_t dequant, uint16_t *eob_ptr) {
  19. const int rc = 0;
  20. const int coeff = coeff_ptr[rc];
  21. const int coeff_sign = (coeff >> 31);
  22. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  23. int tmp, eob = -1;
  24. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  25. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  26. if (!skip_block) {
  27. tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
  28. tmp = (tmp * quant) >> 16;
  29. qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
  30. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant;
  31. if (tmp) eob = 0;
  32. }
  33. *eob_ptr = eob + 1;
  34. }
  35. #if CONFIG_VP9_HIGHBITDEPTH
  36. void vpx_highbd_quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
  37. int skip_block, const int16_t *round_ptr,
  38. const int16_t quant, tran_low_t *qcoeff_ptr,
  39. tran_low_t *dqcoeff_ptr, const int16_t dequant,
  40. uint16_t *eob_ptr) {
  41. int eob = -1;
  42. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  43. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  44. if (!skip_block) {
  45. const int coeff = coeff_ptr[0];
  46. const int coeff_sign = (coeff >> 31);
  47. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  48. const int64_t tmp = abs_coeff + round_ptr[0];
  49. const int abs_qcoeff = (int)((tmp * quant) >> 16);
  50. qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
  51. dqcoeff_ptr[0] = qcoeff_ptr[0] * dequant;
  52. if (abs_qcoeff) eob = 0;
  53. }
  54. *eob_ptr = eob + 1;
  55. }
  56. #endif
  57. void vpx_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
  58. const int16_t *round_ptr, const int16_t quant,
  59. tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
  60. const int16_t dequant, uint16_t *eob_ptr) {
  61. const int n_coeffs = 1024;
  62. const int rc = 0;
  63. const int coeff = coeff_ptr[rc];
  64. const int coeff_sign = (coeff >> 31);
  65. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  66. int tmp, eob = -1;
  67. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  68. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  69. if (!skip_block) {
  70. tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1),
  71. INT16_MIN, INT16_MAX);
  72. tmp = (tmp * quant) >> 15;
  73. qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
  74. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant / 2;
  75. if (tmp) eob = 0;
  76. }
  77. *eob_ptr = eob + 1;
  78. }
  79. #if CONFIG_VP9_HIGHBITDEPTH
  80. void vpx_highbd_quantize_dc_32x32(const tran_low_t *coeff_ptr, int skip_block,
  81. const int16_t *round_ptr, const int16_t quant,
  82. tran_low_t *qcoeff_ptr,
  83. tran_low_t *dqcoeff_ptr,
  84. const int16_t dequant, 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 / 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. #if (ARCH_X86 || ARCH_X86_64) && !CONFIG_VP9_HIGHBITDEPTH
  230. // When tran_low_t is only 16 bits dqcoeff can outrange it. Rather than
  231. // truncating with a cast, saturate the value. This is easier to implement
  232. // on x86 and preserves the sign of the value.
  233. dqcoeff_ptr[rc] =
  234. clamp(qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2, INT16_MIN, INT16_MAX);
  235. #else
  236. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
  237. #endif // ARCH_X86 && CONFIG_VP9_HIGHBITDEPTH
  238. if (tmp) eob = idx_arr[i];
  239. }
  240. *eob_ptr = eob + 1;
  241. }
  242. #if CONFIG_VP9_HIGHBITDEPTH
  243. void vpx_highbd_quantize_b_32x32_c(
  244. const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block,
  245. const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
  246. const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
  247. tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
  248. const int16_t *scan, const int16_t *iscan) {
  249. const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0], 1),
  250. ROUND_POWER_OF_TWO(zbin_ptr[1], 1) };
  251. const int nzbins[2] = { zbins[0] * -1, zbins[1] * -1 };
  252. int idx = 0;
  253. int idx_arr[1024];
  254. int i, eob = -1;
  255. (void)iscan;
  256. (void)skip_block;
  257. assert(!skip_block);
  258. memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
  259. memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
  260. // Pre-scan pass
  261. for (i = 0; i < n_coeffs; i++) {
  262. const int rc = scan[i];
  263. const int coeff = coeff_ptr[rc];
  264. // If the coefficient is out of the base ZBIN range, keep it for
  265. // quantization.
  266. if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0]) idx_arr[idx++] = i;
  267. }
  268. // Quantization pass: only process the coefficients selected in
  269. // pre-scan pass. Note: idx can be zero.
  270. for (i = 0; i < idx; i++) {
  271. const int rc = scan[idx_arr[i]];
  272. const int coeff = coeff_ptr[rc];
  273. const int coeff_sign = (coeff >> 31);
  274. const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
  275. const int64_t tmp1 = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
  276. const int64_t tmp2 = ((tmp1 * quant_ptr[rc != 0]) >> 16) + tmp1;
  277. const int abs_qcoeff = (int)((tmp2 * quant_shift_ptr[rc != 0]) >> 15);
  278. qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
  279. dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
  280. if (abs_qcoeff) eob = idx_arr[i];
  281. }
  282. *eob_ptr = eob + 1;
  283. }
  284. #endif