1 
2 /*!
3  *************************************************************************************
4  * \file quant8x8_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  *
12  *************************************************************************************
13  */
14 
15 #include "contributors.h"
16 
17 #include <math.h>
18 
19 #include "global.h"
20 #include "image.h"
21 #include "mb_access.h"
22 #include "vlc.h"
23 #include "transform.h"
24 #include "mc_prediction.h"
25 #include "q_offsets.h"
26 #include "q_matrix.h"
27 #include "quant8x8.h"
28 #include "rdoq.h"
29 
30 /*!
31 ************************************************************************
32 * \brief
33 *    Rate distortion optimized Quantization process for
34 *    all coefficients in a 8x8 block
35 *
36 ************************************************************************
37 */
rdoq_8x8_CABAC(Macroblock * currMB,int ** tblock,int block_x,int qp_per,int qp_rem,LevelQuantParams ** q_params_8x8,const byte * p_scan,int levelTrellis[64])38 static void rdoq_8x8_CABAC(Macroblock *currMB, int **tblock, int block_x,int qp_per, int qp_rem,
39               LevelQuantParams **q_params_8x8, const byte *p_scan, int levelTrellis[64])
40 {
41   VideoParameters *p_Vid = currMB->p_Vid;
42   levelDataStruct levelData[64];
43   double  lambda_md = 0.0;
44   int kStart = 0, kStop = 0, noCoeff = 0;
45 
46   lambda_md = p_Vid->lambda_rdoq[p_Vid->type][p_Vid->masterQP];
47 
48   noCoeff = init_trellis_data_8x8_CABAC(currMB, tblock, block_x, qp_per, qp_rem, q_params_8x8, p_scan, &levelData[0], &kStart, &kStop);
49   est_writeRunLevel_CABAC(currMB, levelData, levelTrellis, LUMA_8x8, lambda_md, kStart, kStop, noCoeff, 0);
50 }
51 
52 /*!
53 ************************************************************************
54 * \brief
55 *    Rate distortion optimized Quantization process for
56 *    all coefficients in a 8x8 block
57 *
58 ************************************************************************
59 */
rdoq_8x8_CAVLC(Macroblock * currMB,int ** tblock,int block_y,int block_x,int qp_per,int qp_rem,LevelQuantParams ** q_params_8x8,const byte * p_scan,int levelTrellis[4][16])60 static void rdoq_8x8_CAVLC(Macroblock *currMB, int **tblock, int block_y, int block_x, int qp_per, int qp_rem,
61                     LevelQuantParams **q_params_8x8, const byte *p_scan, int levelTrellis[4][16])
62 {
63   VideoParameters *p_Vid = currMB->p_Vid;
64   int k;
65   levelDataStruct levelData[4][16];
66   double lambda_md = 0.0;
67 
68   int b8 = ((block_y >> 3) << 1) + (block_x >> 3);
69 
70   lambda_md = p_Vid->lambda_rdoq[p_Vid->type][p_Vid->masterQP];
71 
72   init_trellis_data_8x8_CAVLC (currMB, tblock, block_x, qp_per, qp_rem, q_params_8x8, p_scan, levelData);
73 
74   for (k = 0; k < 4; k++)
75     est_RunLevel_CAVLC(currMB, levelData[k], levelTrellis[k], LUMA, b8, k, 16, lambda_md);
76 }
77 
78 
79 /*!
80  ************************************************************************
81  * \brief
82  *    Quantization process for All coefficients for a 8x8 block
83  *
84  * \par Input:
85  *
86  * \par Output:
87  *
88  ************************************************************************
89  */
quant_8x8_trellis(Macroblock * currMB,int ** tblock,struct quant_methods * q_method)90 int quant_8x8_trellis(Macroblock *currMB, int **tblock, struct quant_methods *q_method)
91 {
92   QuantParameters *p_Quant = currMB->p_Vid->p_Quant;
93   int block_x = q_method->block_x;
94   int  qp = q_method->qp;
95   int*  ACLevel = q_method->ACLevel;
96   int*  ACRun   = q_method->ACRun;
97   LevelQuantParams **q_params_8x8 = q_method->q_params;
98   const byte (*pos_scan)[2] = q_method->pos_scan;
99   const byte *c_cost = q_method->c_cost;
100   int *coeff_cost = q_method->coeff_cost;
101 
102   int i,j, coeff_ctr;
103 
104   int  *m7;
105   int   level, run = 0;
106   int   nonzero = FALSE;
107   int   qp_per = p_Quant->qp_per_matrix[qp];
108   int   qp_rem = p_Quant->qp_rem_matrix[qp];
109   const byte *p_scan = &pos_scan[0][0];
110   int*  ACL = &ACLevel[0];
111   int*  ACR = &ACRun[0];
112   int   levelTrellis[64];
113 
114   rdoq_8x8_CABAC(currMB, tblock, block_x, qp_per, qp_rem, q_params_8x8, p_scan, levelTrellis);
115 
116   // Quantization
117   for (coeff_ctr = 0; coeff_ctr < 64; coeff_ctr++)
118   {
119     i = *p_scan++;  // horizontal position
120     j = *p_scan++;  // vertical position
121 
122     m7 = &tblock[j][block_x + i];
123     if (*m7 != 0)
124     {
125       level = levelTrellis[coeff_ctr];
126 
127       if (level != 0)
128       {
129         nonzero = TRUE;
130 
131         *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[run];
132 
133         level  = isignab(level, *m7);
134         *m7    = rshift_rnd_sf(((level * q_params_8x8[j][i].InvScaleComp) << qp_per), 6);
135         *ACL++ = level;
136         *ACR++ = run;
137         // reset zero level counter
138         run    = 0;
139       }
140       else
141       {
142         run++;
143         *m7 = 0;
144       }
145     }
146     else
147     {
148       run++;
149     }
150   }
151 
152   *ACL = 0;
153 
154   return nonzero;
155 }
156 
157 /*!
158  ************************************************************************
159  * \brief
160  *    Quantization process for All coefficients for a 8x8 block
161  *    CAVLC version
162  *
163  * \par Input:
164  *
165  * \par Output:
166  *
167  ************************************************************************
168  */
quant_8x8cavlc_trellis(Macroblock * currMB,int ** tblock,struct quant_methods * q_method,int *** cofAC)169 int quant_8x8cavlc_trellis(Macroblock *currMB, int **tblock, struct quant_methods *q_method, int***  cofAC)
170 {
171   QuantParameters *p_Quant = currMB->p_Vid->p_Quant;
172   int block_x = q_method->block_x;
173   int block_y = q_method->block_y;
174   int  qp = q_method->qp;
175   LevelQuantParams **q_params_8x8 = q_method->q_params;
176   const byte (*pos_scan)[2] = q_method->pos_scan;
177   const byte *c_cost = q_method->c_cost;
178   int *coeff_cost = q_method->coeff_cost;
179 
180   int i,j, k, coeff_ctr;
181 
182   int *m7;
183   int level, runs[4] = { 0 };
184   int nonzero = FALSE;
185   int qp_per = p_Quant->qp_per_matrix[qp];
186   int qp_rem = p_Quant->qp_rem_matrix[qp];
187   const byte *p_scan = &pos_scan[0][0];
188   int*  ACL[4];
189   int*  ACR[4];
190 
191   int levelTrellis[4][16];
192 
193   rdoq_8x8_CAVLC(currMB, tblock, block_y, block_x, qp_per, qp_rem, q_params_8x8, p_scan, levelTrellis);
194 
195   for (k = 0; k < 4; k++)
196   {
197     ACL[k] = &cofAC[k][0][0];
198     ACR[k] = &cofAC[k][1][0];
199   }
200 
201   // Quantization
202   for (k = 0; k < 4; k++)
203   {
204     for (coeff_ctr = 0; coeff_ctr < 16; coeff_ctr++)
205     {
206       i = *p_scan++;  // horizontal position
207       j = *p_scan++;  // vertical position
208 
209       m7 = &tblock[j][block_x + i];
210 
211       if (m7 != 0)
212       {
213         level = levelTrellis[k][coeff_ctr];
214 
215         if (level != 0)
216         {
217           nonzero=TRUE;
218 
219           *coeff_cost += (level > 1) ? MAX_VALUE : c_cost[runs[k]];
220 
221           level  = isignab(level, *m7);
222           *m7    = rshift_rnd_sf(((level * q_params_8x8[j][i].InvScaleComp) << qp_per), 6);
223 
224           *(ACL[k])++ = level;
225           *(ACR[k])++ = runs[k];
226           // reset zero level counter
227           runs[k] = 0;
228         }
229         else
230         {
231           runs[k]++;
232           *m7 = 0;
233         }
234       }
235       else
236       {
237         runs[k]++;
238       }
239     }
240   }
241 
242   for(k = 0; k < 4; k++)
243     *(ACL[k]) = 0;
244 
245   return nonzero;
246 }
247 
248