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