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