1 
2 /*!
3  *************************************************************************************
4  * \file quant4x4_trellis.c
5  *
6  * \brief
7  *    Quantization process for a 4x4 block using trellis based quantization
8  *
9  * \author
10  *    Main contributors (see contributors.h for copyright, address and affiliation details)
11  *    - Qualcomm
12  *    - Limin Liu                                <limin.liu@dolby.com>
13  *    - Alexis Michael Tourapis                  <alexismt@ieee.org>
14  *
15  *************************************************************************************
16  */
17 
18 #include "contributors.h"
19 
20 #include <math.h>
21 
22 #include "global.h"
23 
24 #include "image.h"
25 #include "mb_access.h"
26 #include "vlc.h"
27 #include "transform.h"
28 #include "mc_prediction.h"
29 #include "q_offsets.h"
30 #include "q_matrix.h"
31 #include "quant4x4.h"
32 #include "rdoq.h"
33 
34 /*!
35  ************************************************************************
36  * \brief
37  *    Quantization process for All coefficients for a 4x4 block
38  *
39  ************************************************************************
40  */
quant_4x4_trellis(Macroblock * currMB,int ** tblock,struct quant_methods * q_method)41 int quant_4x4_trellis(Macroblock *currMB, int **tblock, struct quant_methods *q_method)
42 {
43   int   block_x = q_method->block_x;
44 
45   int*  ACL = &q_method->ACLevel[0];
46   int*  ACR = &q_method->ACRun[0];
47   Slice *currSlice = currMB->p_Slice;
48   QuantParameters *p_Quant = currMB->p_Vid->p_Quant;
49   int  qp = q_method->qp;
50   LevelQuantParams **q_params_4x4 = q_method->q_params;
51   const byte (*pos_scan)[2] = q_method->pos_scan;
52   const byte *c_cost = q_method->c_cost;
53   int *coeff_cost = q_method->coeff_cost;
54 
55   Boolean is_cavlc = (Boolean) (currSlice->symbol_mode == CAVLC);
56 
57   int i,j, coeff_ctr;
58 
59   int *m7;
60 
61   int   level, run = 0;
62   int   nonzero = FALSE;
63   int   qp_per = p_Quant->qp_per_matrix[qp];
64   const byte *p_scan = &pos_scan[0][0];
65 
66   int levelTrellis[16];
67 
68   currSlice->rdoq_4x4(currMB, tblock, q_method, levelTrellis);
69 
70   // Quantization
71   for (coeff_ctr = 0; coeff_ctr < 16; ++coeff_ctr)
72   {
73     i = *p_scan++;  // horizontal position
74     j = *p_scan++;  // vertical position
75 
76     m7 = &tblock[j][block_x + i];
77 
78     if (*m7 != 0)
79     {
80       /*
81       scaled_coeff = iabs (*m7) * q_params_4x4[j][i].ScaleComp;
82       level = (scaled_coeff + q_params_4x4[j][i].OffsetComp) >> q_bits;
83       */
84       level = levelTrellis[coeff_ctr];
85 
86       if (level != 0)
87       {
88         if (is_cavlc)
89           level = imin(level, CAVLC_LEVEL_LIMIT);
90 
91         *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run];
92 
93         level   = isignab(level, *m7);
94         *m7     = rshift_rnd_sf(((level * q_params_4x4[j][i].InvScaleComp) << qp_per), 4);
95         *ACL++  = level;
96         *ACR++  = run;
97         // reset zero level counter
98         run     = 0;
99         nonzero = TRUE;
100       }
101       else
102       {
103         *m7 = 0;
104         ++run;
105       }
106     }
107     else
108     {
109       ++run;
110     }
111   }
112 
113   *ACL = 0;
114 
115   return nonzero;
116 }
117 
118 /*!
119 ************************************************************************
120 * \brief
121 *    Rate distortion optimized Quantization process for
122 *    all coefficients in a 4x4 block (CAVLC)
123 *
124 ************************************************************************
125 */
rdoq_4x4_CAVLC(Macroblock * currMB,int ** tblock,struct quant_methods * q_method,int levelTrellis[])126 void rdoq_4x4_CAVLC(Macroblock *currMB, int **tblock, struct quant_methods *q_method, int levelTrellis[])
127 {
128   VideoParameters *p_Vid = currMB->p_Vid;
129   int   block_x = q_method->block_x;
130   int   block_y = q_method->block_y;
131   LevelQuantParams **q_params_4x4 = q_method->q_params;
132   const byte (*pos_scan)[2] = q_method->pos_scan;
133   const byte *p_scan = &pos_scan[0][0];
134   int  qp = q_method->qp;
135   QuantParameters *p_Quant = currMB->p_Vid->p_Quant;
136   int   qp_per = p_Quant->qp_per_matrix[qp];
137   int   qp_rem = p_Quant->qp_rem_matrix[qp];
138 
139   levelDataStruct levelData[16];
140   double  lambda_md = p_Vid->lambda_rdoq[p_Vid->type][p_Vid->masterQP];
141 
142   int type = LUMA_4x4;
143   int   pos_x   = block_x >> BLOCK_SHIFT;
144   int   pos_y   = block_y >> BLOCK_SHIFT;
145   int   b8      = 2*(pos_y >> 1) + (pos_x >> 1);
146   int   b4      = 2*(pos_y & 0x01) + (pos_x & 0x01);
147 
148   init_trellis_data_4x4_CAVLC(currMB, tblock, block_x, qp_per, qp_rem, q_params_4x4, p_scan, &levelData[0], type);
149   est_RunLevel_CAVLC(currMB, levelData, levelTrellis, LUMA, b8, b4, 16, lambda_md);
150 }
151 /*!
152 ************************************************************************
153 * \brief
154 *    Rate distortion optimized Quantization process for
155 *    all coefficients in a 4x4 block (CABAC)
156 *
157 ************************************************************************
158 */
rdoq_4x4_CABAC(Macroblock * currMB,int ** tblock,struct quant_methods * q_method,int levelTrellis[])159 void rdoq_4x4_CABAC(Macroblock *currMB, int **tblock, struct quant_methods *q_method, int levelTrellis[])
160 {
161   VideoParameters *p_Vid = currMB->p_Vid;
162 
163   const byte (*pos_scan)[2] = q_method->pos_scan;
164   const byte *p_scan = &pos_scan[0][0];
165 
166   levelDataStruct levelData[16];
167   int kStart=0, kStop=0, noCoeff = 0, estBits;
168 
169   double lambda_md = p_Vid->lambda_rdoq[p_Vid->type][p_Vid->masterQP];
170 
171   noCoeff = init_trellis_data_4x4_CABAC(currMB, tblock, q_method, p_scan, &levelData[0], &kStart, &kStop, LUMA_4x4);
172   estBits = est_write_and_store_CBP_block_bit(currMB, LUMA_4x4);
173   est_writeRunLevel_CABAC(currMB, levelData, levelTrellis, LUMA_4x4, lambda_md, kStart, kStop, noCoeff, estBits);
174 }
175 
176 /*!
177  ************************************************************************
178  * \brief
179  *    Quantization process for All coefficients for a 4x4 block (LUMA_16AC or CHROMA_AC)
180  *
181  ************************************************************************
182  */
quant_ac4x4_trellis(Macroblock * currMB,int ** tblock,struct quant_methods * q_method)183 int quant_ac4x4_trellis(Macroblock *currMB, int **tblock, struct quant_methods *q_method)
184 {
185   int   block_x = q_method->block_x;
186 
187   int*  ACLevel = q_method->ACLevel;
188   int*  ACRun   = q_method->ACRun;
189   int qp = q_method->qp;
190   LevelQuantParams **q_params_4x4 = q_method->q_params;
191   const byte (*pos_scan)[2] = q_method->pos_scan;
192   const byte *c_cost = q_method->c_cost;
193   int *coeff_cost = q_method->coeff_cost;
194 
195   Slice *currSlice = currMB->p_Slice;
196   QuantParameters *p_Quant = currMB->p_Vid->p_Quant;
197   Boolean is_cavlc = (Boolean) (currSlice->symbol_mode == CAVLC);
198   int i,j, coeff_ctr;
199 
200   int *m7;
201   int   level, run = 0;
202   int   nonzero = FALSE;
203   int   qp_per = p_Quant->qp_per_matrix[qp];
204   const byte *p_scan = &pos_scan[1][0];
205   int*  ACL = &ACLevel[0];
206   int*  ACR = &ACRun[0];
207 
208   int levelTrellis[16];
209 
210   currSlice->rdoq_ac4x4(currMB, tblock, q_method, levelTrellis);
211 
212   // Quantization
213   for (coeff_ctr = 1; coeff_ctr < 16; coeff_ctr++)
214   {
215     i = *p_scan++;  // horizontal position
216     j = *p_scan++;  // vertical position
217 
218     m7 = &tblock[j][block_x + i];
219     if (*m7 != 0)
220     {
221       /*
222       scaled_coeff = iabs (*m7) * q_params_4x4[j][i].ScaleComp;
223       level = (scaled_coeff + q_params_4x4[j][i].OffsetComp) >> q_bits;
224       */
225       level=levelTrellis[coeff_ctr - 1];
226 
227       if (level != 0)
228       {
229         if (is_cavlc)
230           level = imin(level, CAVLC_LEVEL_LIMIT);
231 
232         *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run];
233 
234         level  = isignab(level, *m7);
235         *m7    = rshift_rnd_sf(((level * q_params_4x4[j][i].InvScaleComp) << qp_per), 4);
236         // inverse scale can be alternative performed as follows to ensure 16bit
237         // arithmetic is satisfied.
238         // *m7 = (qp_per<4) ? rshift_rnd_sf((level*q_params_4x4[j][i].InvScaleComp),4-qp_per) : (level*q_params_4x4[j][i].InvScaleComp)<<(qp_per-4);
239         *ACL++  = level;
240         *ACR++  = run;
241         // reset zero level counter
242         run     = 0;
243         nonzero = TRUE;
244       }
245       else
246       {
247         run++;
248         *m7 = 0;
249       }
250     }
251     else
252     {
253       run++;
254     }
255   }
256 
257   *ACL = 0;
258 
259   return nonzero;
260 }
261 
262 /*!
263 ************************************************************************
264 * \brief
265 *    Rate distortion optimized Quantization process for
266 *    all coefficients in a 4x4 block (CAVLC)
267 *
268 ************************************************************************
269 */
rdoq_ac4x4_CAVLC(Macroblock * currMB,int ** tblock,struct quant_methods * q_method,int levelTrellis[])270 void rdoq_ac4x4_CAVLC(Macroblock *currMB, int **tblock, struct quant_methods *q_method, int levelTrellis[])
271 {
272   VideoParameters *p_Vid = currMB->p_Vid;
273   int   block_x = q_method->block_x;
274   int   block_y = q_method->block_y;
275   LevelQuantParams **q_params_4x4 = q_method->q_params;
276   const byte (*pos_scan)[2] = q_method->pos_scan;
277   int  qp = q_method->qp;
278   int  type = q_method->type;
279   QuantParameters *p_Quant = p_Vid->p_Quant;
280   int   qp_per = p_Quant->qp_per_matrix[qp];
281   int   qp_rem = p_Quant->qp_rem_matrix[qp];
282 
283   const byte *p_scan = &pos_scan[1][0];
284   levelDataStruct levelData[16];
285   double  lambda_md = p_Vid->lambda_rdoq[p_Vid->type][p_Vid->masterQP];
286 
287   int   pos_x   = block_x >> BLOCK_SHIFT;
288   int   pos_y   = block_y >> BLOCK_SHIFT;
289   int   b8      = 2*(pos_y >> 1) + (pos_x >> 1);
290   int   b4      = 2*(pos_y & 0x01) + (pos_x & 0x01);
291   int   block_type = ( (type == CHROMA_AC) ? CHROMA_AC : LUMA_INTRA16x16AC);
292 
293   init_trellis_data_4x4_CAVLC(currMB, tblock, block_x, qp_per, qp_rem, q_params_4x4, p_scan, &levelData[0], type);
294   est_RunLevel_CAVLC(currMB, levelData, levelTrellis, block_type, b8, b4, 15, lambda_md);
295 }
296 /*!
297 ************************************************************************
298 * \brief
299 *    Rate distortion optimized Quantization process for
300 *    all coefficients in a 4x4 block (LUMA_16AC or CHROMA_AC) - CABAC
301 *
302 ************************************************************************
303 */
rdoq_ac4x4_CABAC(Macroblock * currMB,int ** tblock,struct quant_methods * q_method,int levelTrellis[])304 void rdoq_ac4x4_CABAC(Macroblock *currMB, int **tblock, struct quant_methods *q_method, int levelTrellis[])
305 {
306   VideoParameters *p_Vid = currMB->p_Vid;
307 
308   const byte (*pos_scan)[2] = q_method->pos_scan;
309   int  type = q_method->type;
310 
311   const byte *p_scan = &pos_scan[1][0];
312   levelDataStruct levelData[16];
313   double  lambda_md = p_Vid->lambda_rdoq[p_Vid->type][p_Vid->masterQP];
314   int kStart = 0, kStop = 0, noCoeff = 0, estBits;
315 
316   noCoeff = init_trellis_data_4x4_CABAC(currMB, tblock, q_method, p_scan, &levelData[0], &kStart, &kStop, type);
317   estBits = est_write_and_store_CBP_block_bit(currMB, type);
318   est_writeRunLevel_CABAC(currMB, levelData, levelTrellis, type, lambda_md, kStart, kStop, noCoeff, estBits);
319 }
320 
321 /*!
322  ************************************************************************
323  * \brief
324  *    Quantization process for All coefficients for a 4x4 DC block
325  *
326  ************************************************************************
327  */
quant_dc4x4_trellis(Macroblock * currMB,int ** tblock,int qp,int * DCLevel,int * DCRun,LevelQuantParams * q_params_4x4,const byte (* pos_scan)[2])328 int quant_dc4x4_trellis(Macroblock *currMB, int **tblock, int qp, int* DCLevel, int* DCRun,
329                        LevelQuantParams *q_params_4x4, const byte (*pos_scan)[2])
330 {
331   Slice *currSlice = currMB->p_Slice;
332   QuantParameters *p_Quant = currMB->p_Vid->p_Quant;
333   Boolean is_cavlc = (Boolean) (currSlice->symbol_mode == CAVLC);
334   int i,j, coeff_ctr;
335 
336   int *m7;
337 
338   int   level, run = 0;
339   int   nonzero = FALSE;
340   int   qp_per = p_Quant->qp_per_matrix[qp];
341   int   qp_rem = p_Quant->qp_rem_matrix[qp];
342   const byte *p_scan = &pos_scan[0][0];
343   int*  DCL = &DCLevel[0];
344   int*  DCR = &DCRun[0];
345 
346   int levelTrellis[16];
347 
348   currSlice->rdoq_dc(currMB, tblock, qp_per, qp_rem, q_params_4x4, pos_scan, levelTrellis, LUMA_16DC);
349 
350   // Quantization
351   for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++)
352   {
353     i = *p_scan++;  // horizontal position
354     j = *p_scan++;  // vertical position
355 
356     m7 = &tblock[j][i];
357 
358     if (*m7 != 0)
359     {
360       level = levelTrellis[coeff_ctr];
361 
362       if (level != 0)
363       {
364         if (is_cavlc)
365           level = imin(level, CAVLC_LEVEL_LIMIT);
366 
367         level   = isignab(level, *m7);
368         *m7     = level;
369         *DCL++  = level;
370         *DCR++  = run;
371         // reset zero level counter
372         run     = 0;
373         nonzero = TRUE;
374       }
375       else
376       {
377         run++;
378         *m7 = 0;
379       }
380     }
381     else
382     {
383       run++;
384     }
385   }
386 
387   *DCL = 0;
388 
389   return nonzero;
390 }
391 
392 /*!
393 ************************************************************************
394 * \brief
395 *    Rate distortion optimized Quantization process for
396 *    all coefficients in a luma DC block
397 *
398 ************************************************************************
399 */
rdoq_dc_CAVLC(Macroblock * currMB,int ** tblock,int qp_per,int qp_rem,LevelQuantParams * q_params_4x4,const byte (* pos_scan)[2],int levelTrellis[],int type)400 void rdoq_dc_CAVLC(Macroblock *currMB, int **tblock, int qp_per, int qp_rem, LevelQuantParams *q_params_4x4,
401                    const byte (*pos_scan)[2], int levelTrellis[], int type)
402 {
403   VideoParameters *p_Vid = currMB->p_Vid;
404   const byte *p_scan = &pos_scan[0][0];
405   levelDataStruct levelData[16];
406   double  lambda_md = p_Vid->lambda_rdoq[p_Vid->type][p_Vid->masterQP];
407 
408   init_trellis_data_DC_CAVLC(currMB, tblock, qp_per, qp_rem, q_params_4x4, p_scan, &levelData[0]);
409   est_RunLevel_CAVLC(currMB, levelData, levelTrellis, LUMA_INTRA16x16DC, 0, 0, 16, lambda_md);
410 }
411 
412 
413 /*!
414 ************************************************************************
415 * \brief
416 *    Rate distortion optimized Quantization process for
417 *    all coefficients in a luma DC block
418 *
419 ************************************************************************
420 */
rdoq_dc_CABAC(Macroblock * currMB,int ** tblock,int qp_per,int qp_rem,LevelQuantParams * q_params_4x4,const byte (* pos_scan)[2],int levelTrellis[],int type)421 void rdoq_dc_CABAC(Macroblock *currMB, int **tblock, int qp_per, int qp_rem, LevelQuantParams *q_params_4x4, const byte (*pos_scan)[2], int levelTrellis[], int type)
422 {
423   VideoParameters *p_Vid = currMB->p_Vid;
424   const byte *p_scan = &pos_scan[0][0];
425   levelDataStruct levelData[16];
426   double  lambda_md = p_Vid->lambda_rdoq[p_Vid->type][p_Vid->masterQP];
427   int kStart = 0, kStop = 0, noCoeff = 0, estBits;
428 
429   noCoeff = init_trellis_data_DC_CABAC(currMB, tblock, qp_per, qp_rem, q_params_4x4, p_scan, &levelData[0], &kStart, &kStop);
430   estBits = est_write_and_store_CBP_block_bit(currMB, type);
431   est_writeRunLevel_CABAC(currMB, levelData, levelTrellis, type, lambda_md, kStart, kStop, noCoeff, estBits);
432 }
433 
434