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