1 /*!
2 ***************************************************************************
3 * \file transform8x8.c
4 *
5 * \brief
6 * 8x8 transform functions
7 *
8 * \author
9 * Main contributors (see contributors.h for copyright, address and affiliation details)
10 * - Yuri Vatis
11 * - Jan Muenster
12 * - Lowell Winger <lwinger@lsil.com>
13 * \date
14 * 12. October 2003
15 **************************************************************************
16 */
17
18 #include <math.h>
19 #include <limits.h>
20
21 #include "global.h"
22
23 #include "image.h"
24 #include "mb_access.h"
25 #include "blk_prediction.h"
26 #include "elements.h"
27 #include "vlc.h"
28 #include "transform8x8.h"
29 #include "transform.h"
30 #include "macroblock.h"
31 #include "symbol.h"
32 #include "mc_prediction.h"
33 #include "md_distortion.h"
34 #include "quant8x8.h"
35 #include "rdoq.h"
36 #include "q_matrix.h"
37 #include "q_offsets.h"
38 #include "rdopt.h"
39 #include "md_common.h"
40 #include "intra8x8.h"
41 #include "rdopt_coding_state.h"
42
43 //! single scan pattern
44 static const byte SNGL_SCAN8x8[64][2] = {
45 {0,0}, {1,0}, {0,1}, {0,2}, {1,1}, {2,0}, {3,0}, {2,1},
46 {1,2}, {0,3}, {0,4}, {1,3}, {2,2}, {3,1}, {4,0}, {5,0},
47 {4,1}, {3,2}, {2,3}, {1,4}, {0,5}, {0,6}, {1,5}, {2,4},
48 {3,3}, {4,2}, {5,1}, {6,0}, {7,0}, {6,1}, {5,2}, {4,3},
49 {3,4}, {2,5}, {1,6}, {0,7}, {1,7}, {2,6}, {3,5}, {4,4},
50 {5,3}, {6,2}, {7,1}, {7,2}, {6,3}, {5,4}, {4,5}, {3,6},
51 {2,7}, {3,7}, {4,6}, {5,5}, {6,4}, {7,3}, {7,4}, {6,5},
52 {5,6}, {4,7}, {5,7}, {6,6}, {7,5}, {7,6}, {6,7}, {7,7}
53 };
54
55 static const byte SNGL_SCAN8x8_CAVLC[64][2] = {
56 {0,0}, {1,1}, {1,2}, {2,2}, {4,1}, {0,5}, {3,3}, {7,0}, {3,4}, {1,7}, {5,3}, {6,3}, {2,7}, {6,4}, {5,6}, {7,5},
57 {1,0}, {2,0}, {0,3}, {3,1}, {3,2}, {0,6}, {4,2}, {6,1}, {2,5}, {2,6}, {6,2}, {5,4}, {3,7}, {7,3}, {4,7}, {7,6},
58 {0,1}, {3,0}, {0,4}, {4,0}, {2,3}, {1,5}, {5,1}, {5,2}, {1,6}, {3,5}, {7,1}, {4,5}, {4,6}, {7,4}, {5,7}, {6,7},
59 {0,2}, {2,1}, {1,3}, {5,0}, {1,4}, {2,4}, {6,0}, {4,3}, {0,7}, {4,4}, {7,2}, {3,6}, {5,5}, {6,5}, {6,6}, {7,7}
60 };
61
62 //! field scan pattern
63 static const byte FIELD_SCAN8x8[64][2] = { // 8x8
64 {0,0}, {0,1}, {0,2}, {1,0}, {1,1}, {0,3}, {0,4}, {1,2},
65 {2,0}, {1,3}, {0,5}, {0,6}, {0,7}, {1,4}, {2,1}, {3,0},
66 {2,2}, {1,5}, {1,6}, {1,7}, {2,3}, {3,1}, {4,0}, {3,2},
67 {2,4}, {2,5}, {2,6}, {2,7}, {3,3}, {4,1}, {5,0}, {4,2},
68 {3,4}, {3,5}, {3,6}, {3,7}, {4,3}, {5,1}, {6,0}, {5,2},
69 {4,4}, {4,5}, {4,6}, {4,7}, {5,3}, {6,1}, {6,2}, {5,4},
70 {5,5}, {5,6}, {5,7}, {6,3}, {7,0}, {7,1}, {6,4}, {6,5},
71 {6,6}, {6,7}, {7,2}, {7,3}, {7,4}, {7,5}, {7,6}, {7,7}
72 };
73
74 static const byte FIELD_SCAN8x8_CAVLC[64][2] = {
75 {0,0}, {1,1}, {2,0}, {0,7}, {2,2}, {2,3}, {2,4}, {3,3}, {3,4}, {4,3}, {4,4}, {5,3}, {5,5}, {7,0}, {6,6}, {7,4},
76 {0,1}, {0,3}, {1,3}, {1,4}, {1,5}, {3,1}, {2,5}, {4,1}, {3,5}, {5,1}, {4,5}, {6,1}, {5,6}, {7,1}, {6,7}, {7,5},
77 {0,2}, {0,4}, {0,5}, {2,1}, {1,6}, {4,0}, {2,6}, {5,0}, {3,6}, {6,0}, {4,6}, {6,2}, {5,7}, {6,4}, {7,2}, {7,6},
78 {1,0}, {1,2}, {0,6}, {3,0}, {1,7}, {3,2}, {2,7}, {4,2}, {3,7}, {5,2}, {4,7}, {5,4}, {6,3}, {6,5}, {7,3}, {7,7}
79 };
80
81
82 //! array used to find expensive coefficients
83 static const byte COEFF_COST8x8[2][64] =
84 {
85 {3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,
86 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
87 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
88 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
89 {9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
90 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
91 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
92 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9}
93 };
94
95
96 // Predictor array index definitions
97 #define P_Z (PredPel[0])
98 #define P_A (PredPel[1])
99 #define P_B (PredPel[2])
100 #define P_C (PredPel[3])
101 #define P_D (PredPel[4])
102 #define P_E (PredPel[5])
103 #define P_F (PredPel[6])
104 #define P_G (PredPel[7])
105 #define P_H (PredPel[8])
106 #define P_I (PredPel[9])
107 #define P_J (PredPel[10])
108 #define P_K (PredPel[11])
109 #define P_L (PredPel[12])
110 #define P_M (PredPel[13])
111 #define P_N (PredPel[14])
112 #define P_O (PredPel[15])
113 #define P_P (PredPel[16])
114 #define P_Q (PredPel[17])
115 #define P_R (PredPel[18])
116 #define P_S (PredPel[19])
117 #define P_T (PredPel[20])
118 #define P_U (PredPel[21])
119 #define P_V (PredPel[22])
120 #define P_W (PredPel[23])
121 #define P_X (PredPel[24])
122
123
124
125 /*!
126 ************************************************************************
127 * \brief
128 * Residual DPCM for Intra lossless coding
129 *
130 * \par Input:
131 * block_x,block_y: Block position inside a macro block (0,8).
132 ************************************************************************
133 */
134 //For residual DPCM
Residual_DPCM_8x8(int ipmode,int ** ores,int ** rres,int block_y,int block_x)135 static int Residual_DPCM_8x8(int ipmode, int **ores, int **rres,int block_y, int block_x)
136 {
137 int i,j;
138 int temp[8][8];
139
140 if(ipmode==VERT_PRED)
141 {
142 for (j=0; j<8; j++)
143 temp[0][j] = ores[block_y][block_x+j];
144
145 for (i=1; i<8; i++)
146 for (j=0; j<8; j++)
147 temp[i][j] = ores[block_y+i][block_x+j] - ores[block_y+i-1][block_x+j];
148
149 for (i = 0; i < 8; i++)
150 for (j = 0; j < 8; j++)
151 rres[block_y+i][block_x+j] = temp[i][j];
152 }
153 else //HOR_PRED
154 {
155 for (i=0; i<8; i++)
156 temp[i][0] = ores[block_y + i][block_x];
157
158 for (i=0; i<8; i++)
159 for (j=1; j<8; j++)
160 temp[i][j] = ores[block_y+i][block_x+j] - ores[block_y+i][block_x+j-1];
161
162 for (i=0; i<8; i++)
163 for (j=0; j<8; j++)
164 rres[block_y+i][block_x+j] = temp[i][j];
165 }
166 return 0;
167 }
168
169 /*!
170 ************************************************************************
171 * \brief
172 * Inverse residual DPCM for Intra lossless coding
173 *
174 * \par Input:
175 * block_x,block_y: Block position inside a macro block (0,8).
176 ************************************************************************
177 */
178 //For residual DPCM
Inv_Residual_DPCM_8x8(Macroblock * currMB,int ** m7,int block_y,int block_x)179 static int Inv_Residual_DPCM_8x8(Macroblock *currMB, int **m7, int block_y, int block_x)
180 {
181 int i;
182 int temp[8][8];
183
184 if(currMB->ipmode_DPCM == VERT_PRED)
185 {
186 for(i=0; i<8; i++)
187 {
188 temp[0][i] = m7[block_y+0][block_x+i];
189 temp[1][i] = temp[0][i] + m7[block_y+1][block_x+i];
190 temp[2][i] = temp[1][i] + m7[block_y+2][block_x+i];
191 temp[3][i] = temp[2][i] + m7[block_y+3][block_x+i];
192 temp[4][i] = temp[3][i] + m7[block_y+4][block_x+i];
193 temp[5][i] = temp[4][i] + m7[block_y+5][block_x+i];
194 temp[6][i] = temp[5][i] + m7[block_y+6][block_x+i];
195 temp[7][i] = temp[6][i] + m7[block_y+7][block_x+i];
196 }
197 for(i=0; i<8; i++)
198 {
199 m7[block_y+1][block_x+i] = temp[1][i];
200 m7[block_y+2][block_x+i] = temp[2][i];
201 m7[block_y+3][block_x+i] = temp[3][i];
202 m7[block_y+4][block_x+i] = temp[4][i];
203 m7[block_y+5][block_x+i] = temp[5][i];
204 m7[block_y+6][block_x+i] = temp[6][i];
205 m7[block_y+7][block_x+i] = temp[7][i];
206 }
207 }
208 else //HOR_PRED
209 {
210 for(i=0; i<8; i++)
211 {
212 temp[i][0] = m7[block_y+i][block_x+0];
213 temp[i][1] = temp[i][0] + m7[block_y+i][block_x+1];
214 temp[i][2] = temp[i][1] + m7[block_y+i][block_x+2];
215 temp[i][3] = temp[i][2] + m7[block_y+i][block_x+3];
216 temp[i][4] = temp[i][3] + m7[block_y+i][block_x+4];
217 temp[i][5] = temp[i][4] + m7[block_y+i][block_x+5];
218 temp[i][6] = temp[i][5] + m7[block_y+i][block_x+6];
219 temp[i][7] = temp[i][6] + m7[block_y+i][block_x+7];
220 }
221 for(i=0; i<8; i++)
222 {
223 m7[block_y+i][block_x+1] = temp[i][1];
224 m7[block_y+i][block_x+2] = temp[i][2];
225 m7[block_y+i][block_x+3] = temp[i][3];
226 m7[block_y+i][block_x+4] = temp[i][4];
227 m7[block_y+i][block_x+5] = temp[i][5];
228 m7[block_y+i][block_x+6] = temp[i][6];
229 m7[block_y+i][block_x+7] = temp[i][7];
230 }
231 }
232 return 0;
233 }
234
235 /*!
236 *************************************************************************************
237 * \brief
238 * 8x8 Intra mode decision for a macroblock
239 *************************************************************************************
240 */
mode_decision_for_I8x8_MB(Macroblock * currMB,int lambda,distblk * min_cost)241 int mode_decision_for_I8x8_MB (Macroblock *currMB, int lambda, distblk *min_cost)
242 {
243 Slice *currSlice = currMB->p_Slice;
244 int cur_cbp = 0, b8;
245 //int cr_cbp[3] = { 0, 0, 0};
246 distblk cost8x8;
247 *min_cost = weighted_cost(lambda, 6); //6 bits overhead;
248
249 if (currSlice->P444_joined == 0)
250 {
251 for (b8=0; b8<4; b8++)
252 {
253 if (currSlice->mode_decision_for_I8x8_blocks (currMB, b8, lambda, &cost8x8))
254 {
255 cur_cbp |= (1<<b8);
256 }
257 *min_cost += cost8x8;
258 }
259 }
260 else
261 {
262 int k;
263 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
264 currMB->cr_cbp[0] = 0;
265 currMB->cr_cbp[1] = 0;
266 currMB->cr_cbp[2] = 0;
267
268 for (b8 = 0; b8 < 4; b8++)
269 {
270 if (currSlice->mode_decision_for_I8x8_blocks (currMB, b8, lambda, &cost8x8))
271 {
272 cur_cbp |= (1<<b8);
273 }
274 *min_cost += cost8x8;
275
276 for (k = 1; k < 3; k++)
277 {
278 if(currMB->cr_cbp[k]) //if (cr_cbp[k])
279 {
280 currSlice->cmp_cbp[k] |= (1 << b8);
281 cur_cbp |= currSlice->cmp_cbp[k];
282 currSlice->cmp_cbp[k] = cur_cbp;
283 }
284 }
285 }
286 }
287
288 return cur_cbp;
289 }
290
291
292 /*!
293 *************************************************************************************
294 * \brief
295 * R-D Cost for an 8x8 Intra block
296 *************************************************************************************
297 */
rdcost_for_8x8_intra_blocks(Macroblock * currMB,int * nonzero,int b8,int ipmode,int lambda,distblk min_rdcost,int mostProbableMode)298 distblk rdcost_for_8x8_intra_blocks(Macroblock *currMB, int *nonzero, int b8, int ipmode, int lambda, distblk min_rdcost, int mostProbableMode)
299 {
300 VideoParameters *p_Vid = currMB->p_Vid;
301 Slice *currSlice = currMB->p_Slice;
302 distblk rdcost = 0;
303 int dummy = 0;
304 int rate;
305 distblk distortion = 0;
306 int block_x = (b8 & 0x01) << 3;
307 int block_y = (b8 >> 1) << 3;
308 int pic_pix_x = currMB->pix_x + block_x;
309 int pic_pix_y = currMB->pix_y + block_y;
310 int pic_opix_y = currMB->opix_y + block_y;
311
312 SyntaxElement se;
313 const int *partMap = assignSE2partition[currSlice->partition_mode];
314 DataPartition *dataPart;
315
316 //===== perform forward transform, Q, IQ, inverse transform, Reconstruction =====
317 *nonzero = currMB->residual_transform_quant_luma_8x8 (currMB, PLANE_Y, b8, &dummy, 1);
318
319 //===== get distortion (SSD) of 8x8 block =====
320 distortion += compute_SSE8x8(&p_Vid->pCurImg[pic_opix_y], &p_Vid->enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x);
321 if (distortion > min_rdcost)
322 {
323 //currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
324 return distortion;
325 }
326 currMB->ipmode_DPCM = NO_INTRA_PMODE;
327
328 //===== RATE for INTRA PREDICTION MODE (SYMBOL MODE MUST BE SET TO CAVLC) =====
329 se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode-1;
330
331 //--- set position and type ---
332 se.context = b8;
333 se.type = SE_INTRAPREDMODE;
334
335 //--- choose data partition ---
336 if (currSlice->slice_type != B_SLICE)
337 dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
338 else
339 dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
340
341 //--- encode and update rate ---
342 currSlice->writeIntraPredMode (&se, dataPart);
343
344 rate = se.len;
345
346 //===== RATE for LUMINANCE COEFFICIENTS =====
347
348 if (currSlice->symbol_mode == CAVLC)
349 {
350 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, 0, 0);
351 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, 1, 0);
352 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, 2, 0);
353 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, 3, 0);
354 }
355 else
356 {
357 rate += writeCoeff8x8_CABAC (currMB, PLANE_Y, b8, 1);
358 }
359 rdcost = distortion + weight_cost(lambda, rate);
360 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
361
362 return rdcost;
363 }
364
365
366 /*!
367 *************************************************************************************
368 * \brief
369 * R-D Cost for an 8x8 Intra block
370 *************************************************************************************
371 */
rdcost_for_8x8_intra_blocks_444(Macroblock * currMB,int * nonzero,int b8,int ipmode,int lambda,distblk min_rdcost,int mostProbableMode)372 distblk rdcost_for_8x8_intra_blocks_444(Macroblock *currMB, int *nonzero, int b8, int ipmode, int lambda, distblk min_rdcost, int mostProbableMode)
373 {
374 VideoParameters *p_Vid = currMB->p_Vid;
375 Slice *currSlice = currMB->p_Slice;
376 distblk rdcost = 0;
377 int dummy = 0;
378 int rate;
379 distblk distortion = 0;
380 int block_x = (b8 & 0x01) << 3;
381 int block_y = (b8 >> 1) << 3;
382 int pic_pix_x = currMB->pix_x + block_x;
383 int pic_pix_y = currMB->pix_y + block_y;
384 int pic_opix_y = currMB->opix_y + block_y;
385
386 SyntaxElement se;
387 const int *partMap = assignSE2partition[currSlice->partition_mode];
388 DataPartition *dataPart;
389
390 if(currSlice->P444_joined == 0)
391 {
392 //===== perform forward transform, Q, IQ, inverse transform, Reconstruction =====
393 *nonzero = currMB->residual_transform_quant_luma_8x8 (currMB, PLANE_Y, b8, &dummy, 1);
394
395 //===== get distortion (SSD) of 8x8 block =====
396 distortion += compute_SSE8x8(&p_Vid->pCurImg[pic_opix_y], &p_Vid->enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x);
397
398 currMB->ipmode_DPCM = NO_INTRA_PMODE;
399
400 //===== RATE for INTRA PREDICTION MODE (SYMBOL MODE MUST BE SET TO CAVLC) =====
401 se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode-1;
402
403 //--- set position and type ---
404 se.context = b8;
405 se.type = SE_INTRAPREDMODE;
406
407 //--- choose data partition ---
408 if (currSlice->slice_type != B_SLICE)
409 dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
410 else
411 dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
412
413 //--- encode and update rate ---
414 currSlice->writeIntraPredMode (&se, dataPart);
415
416 rate = se.len;
417
418 //===== RATE for LUMINANCE COEFFICIENTS =====
419
420 if (currSlice->symbol_mode == CAVLC)
421 {
422 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, 0, 0);
423 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, 1, 0);
424 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, 2, 0);
425 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, 3, 0);
426 }
427 else
428 {
429 rate += writeCoeff8x8_CABAC (currMB, PLANE_Y, b8, 1);
430 }
431 }
432 else
433 {
434 ColorPlane k;
435 //===== perform forward transform, Q, IQ, inverse transform, Reconstruction =====
436 *nonzero = currMB->residual_transform_quant_luma_8x8 (currMB, PLANE_Y, b8, &dummy, 1);
437
438 //===== get distortion (SSD) of 8x8 block =====
439 distortion += compute_SSE8x8(&p_Vid->pCurImg[pic_opix_y], &p_Vid->enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x);
440
441 for (k = PLANE_U; k <= PLANE_V; k++)
442 {
443 select_plane(p_Vid, k);
444 currMB->c_nzCbCr[k ]= currMB->residual_transform_quant_luma_8x8(currMB, k, b8, &dummy,1);
445 distortion += compute_SSE8x8(&p_Vid->pImgOrg[k][pic_opix_y], &p_Vid->enc_picture->p_curr_img[pic_pix_y], pic_pix_x, pic_pix_x);
446 }
447 currMB->ipmode_DPCM = NO_INTRA_PMODE;
448 select_plane(p_Vid, PLANE_Y);
449
450 //===== RATE for INTRA PREDICTION MODE (SYMBOL MODE MUST BE SET TO CAVLC) =====
451 se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode-1;
452
453 //--- set position and type ---
454 se.context = b8;
455 se.type = SE_INTRAPREDMODE;
456
457 //--- choose data partition ---
458 if (currSlice->slice_type != B_SLICE)
459 dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
460 else
461 dataPart = &(currSlice->partArr[partMap[SE_BFRAME]]);
462
463 //--- encode and update rate ---
464 currSlice->writeIntraPredMode (&se, dataPart);
465 rate = se.len;
466
467 //===== RATE for LUMINANCE COEFFICIENTS =====
468
469 if (currSlice->symbol_mode == CAVLC)
470 {
471 int b4;
472 for(b4=0; b4<4; b4++)
473 {
474 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, b4, 0);
475 rate += currSlice->writeCoeff4x4_CAVLC (currMB, CB, b8, b4, 0);
476 rate += currSlice->writeCoeff4x4_CAVLC (currMB, CR, b8, b4, 0);
477 }
478 }
479 else
480 {
481 rate += writeCoeff8x8_CABAC (currMB, PLANE_Y, b8, 1);
482 rate += writeCoeff8x8_CABAC (currMB, PLANE_U, b8, 1);
483 rate += writeCoeff8x8_CABAC (currMB, PLANE_V, b8, 1);
484 }
485 }
486 rdcost = distortion + weight_cost(lambda, rate);
487 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
488
489 return rdcost;
490 }
491
check_zero(int ** mb_ores,int block_x)492 static inline int check_zero(int **mb_ores, int block_x)
493 {
494 int i, j, k = 0;
495
496 for (j = 0; (j < BLOCK_SIZE_8x8) && (k == 0); j++)
497 {
498 for (i = block_x; (i< block_x + BLOCK_SIZE_8x8) && (k == 0); i++)
499 {
500 //k |= (mb_ores[j][i] != 0);
501 k |= mb_ores[j][i];
502 }
503 }
504 return k;
505 }
506
507 /*!
508 ************************************************************************
509 * \brief
510 * The routine performs transform,quantization,inverse transform, adds the diff.
511 * to the prediction and writes the result to the decoded luma frame. Includes the
512 * RD constrained quantization also.
513 *
514 * \par Input:
515 * b8: Block position inside a macro block (0,1,2,3).
516 *
517 * \par Output:
518 * nonzero: 0 if no levels are nonzero. 1 if there are nonzero levels.
519 * coeff_cost: Counter for nonzero coefficients, used to discard expensive levels.
520 ************************************************************************
521 */
residual_transform_quant_luma_8x8(Macroblock * currMB,ColorPlane pl,int b8,int * coeff_cost,int intra)522 int residual_transform_quant_luma_8x8(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra)
523 {
524 VideoParameters *p_Vid = currMB->p_Vid;
525 int nonzero = FALSE;
526
527 int block_x = 8*(b8 & 0x01);
528 int block_y = 8*(b8 >> 1);
529 int pl_off = b8+ (pl<<2);
530 Slice *currSlice = currMB->p_Slice;
531 imgpel **img_enc = p_Vid->enc_picture->p_curr_img;
532
533 imgpel **mb_pred = currSlice->mb_pred[pl];
534 int **mb_ores = currSlice->mb_ores[pl];
535 int **mb_rres = currSlice->mb_rres[pl];
536
537 int max_imgpel_value = p_Vid->max_imgpel_value;
538
539 if (check_zero(&mb_ores[block_y], block_x) != 0)
540 {
541 int qp = (p_Vid->yuv_format==YUV444 && !currSlice->P444_joined)? currMB->qp_scaled[(int)(p_Vid->colour_plane_id)]: currMB->qp_scaled[pl];
542
543 // Variable p_Quant and some of its parameters could be all set outside
544 // to speed up the code (e.g. field mode, coeff_cost, etc).
545 QuantParameters *p_Quant = p_Vid->p_Quant;
546
547 QuantMethods quant_methods;
548 quant_methods.block_x = block_x;
549 quant_methods.block_y = block_y;
550
551 quant_methods.ACLevel = currSlice->cofAC[pl_off][0][0];
552 quant_methods.ACRun = currSlice->cofAC[pl_off][0][1];
553
554 quant_methods.qp = qp;
555 quant_methods.q_params = p_Quant->q_params_8x8[pl][intra][qp];
556 quant_methods.fadjust = p_Vid->AdaptiveRounding ? (&p_Vid->ARCofAdj8x8[pl][currMB->ar_mode][block_y]) : NULL;
557 quant_methods.coeff_cost = coeff_cost;
558 quant_methods.pos_scan = currMB->is_field_mode ? FIELD_SCAN8x8 : SNGL_SCAN8x8;
559 quant_methods.c_cost = COEFF_COST8x8[currSlice->disthres];
560
561 // Forward 8x8 transform
562 forward8x8(mb_ores, mb_rres, block_y, block_x);
563
564 // Quantization process
565 nonzero = currSlice->quant_8x8(currMB, &mb_rres[block_y], &quant_methods);
566 }
567 else
568 {
569 currSlice->cofAC[pl_off][0][0][0] = 0;
570 }
571
572 if (nonzero)
573 {
574 // Inverse 8x8 transform
575 inverse8x8(&mb_rres[block_y], &mb_rres[block_y], block_x);
576
577 // generate final block
578 sample_reconstruct (&img_enc[currMB->pix_y + block_y], &mb_pred[block_y], &mb_rres[block_y], block_x, currMB->pix_x + block_x, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, max_imgpel_value, DQ_BITS_8);
579 }
580 else // if (nonzero) => No transformed residual. Just use prediction.
581 {
582 copy_image_data_8x8 (&img_enc[currMB->pix_y + block_y], &mb_pred[block_y], currMB->pix_x + block_x, block_x);
583 }
584
585 // Decoded block moved to frame memory
586 return nonzero;
587 }
588
589 /*!
590 ************************************************************************
591 * \brief
592 * The routine performs transform,quantization,inverse transform, adds the diff.
593 * to the prediction and writes the result to the decoded luma frame. Includes the
594 * RD constrained quantization also. Used for CAVLC.
595 *
596 * \par Input:
597 * b8: Block position inside a macro block (0,1,2,3).
598 *
599 * \par Output:
600 * nonzero: 0 if no levels are nonzero. 1 if there are nonzero levels.
601 * coeff_cost: Counter for nonzero coefficients, used to discard expensive levels.
602 ************************************************************************
603 */
residual_transform_quant_luma_8x8_cavlc(Macroblock * currMB,ColorPlane pl,int b8,int * coeff_cost,int intra)604 int residual_transform_quant_luma_8x8_cavlc(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra)
605 {
606 VideoParameters *p_Vid = currMB->p_Vid;
607 int nonzero = FALSE;
608
609 int block_x = 8*(b8 & 0x01);
610 int block_y = 8*(b8 >> 1);
611 int pl_off = b8+ (pl<<2);
612 imgpel **img_enc = p_Vid->enc_picture->p_curr_img;
613 Slice *currSlice = currMB->p_Slice;
614 imgpel **mb_pred = currSlice->mb_pred[pl];
615 int **mb_ores = currSlice->mb_ores[pl];
616 int **mb_rres = currSlice->mb_rres[pl];
617
618 int max_imgpel_value = p_Vid->max_imgpel_value;
619
620 int qp = currMB->qp_scaled[pl];
621
622 //if (check_zero(&mb_ores[block_y], block_x) != 0)
623 {
624 // Variable p_Quant and some of its parameters could be all set outside
625 // to speed up the code (e.g. field mode, coeff_cost, etc).
626 QuantParameters *p_Quant = p_Vid->p_Quant;
627
628 QuantMethods quant_methods;
629 quant_methods.block_x = block_x;
630 quant_methods.block_y = block_y;
631 quant_methods.qp = qp;
632 quant_methods.q_params = p_Quant->q_params_8x8[pl][intra][qp];
633 quant_methods.fadjust = p_Vid->AdaptiveRounding ? (&p_Vid->ARCofAdj8x8[pl][currMB->ar_mode][block_y]) : NULL;
634 quant_methods.coeff_cost = coeff_cost;
635 // quant_methods.pos_scan = currMB->is_field_mode ? FIELD_SCAN8x8 : SNGL_SCAN8x8;
636 quant_methods.pos_scan = currMB->is_field_mode ? FIELD_SCAN8x8_CAVLC : SNGL_SCAN8x8_CAVLC;
637 quant_methods.c_cost = COEFF_COST8x8[currSlice->disthres];
638
639 // Forward 8x8 transform
640 forward8x8(mb_ores, mb_rres, block_y, block_x);
641
642 // Quantization process
643 nonzero = currSlice->quant_8x8cavlc(currMB, &mb_rres[block_y], &quant_methods, currSlice->cofAC[pl_off]);
644 }
645
646 if (nonzero)
647 {
648 // Inverse 8x8 transform
649 inverse8x8(&mb_rres[block_y], &mb_rres[block_y], block_x);
650
651 // generate final block
652 sample_reconstruct (&img_enc[currMB->pix_y + block_y], &mb_pred[block_y], &mb_rres[block_y], block_x, currMB->pix_x + block_x, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, max_imgpel_value, DQ_BITS_8);
653 }
654 else // if (nonzero) => No transformed residual. Just use prediction.
655 {
656 copy_image_data_8x8(&img_enc[currMB->pix_y + block_y], &mb_pred[block_y], currMB->pix_x + block_x, block_x);
657 }
658
659 // Decoded block moved to frame memory
660 return nonzero;
661 }
662
residual_transform_quant_luma_8x8_ls(Macroblock * currMB,ColorPlane pl,int b8,int * coeff_cost,int intra)663 int residual_transform_quant_luma_8x8_ls(Macroblock *currMB, ColorPlane pl, int b8, int *coeff_cost, int intra)
664 {
665 VideoParameters *p_Vid = currMB->p_Vid;
666 int i,j,coeff_ctr;
667 int scan_pos = 0,run = -1;
668 int nonzero = FALSE;
669
670 int block_x = 8*(b8 & 0x01);
671 int block_y = 8*(b8 >> 1);
672 int pl_off = b8 + (pl<<2);
673 Slice *currSlice = currMB->p_Slice;
674 int* ACLevel = currSlice->cofAC[pl_off][0][0];
675 int* ACRun = currSlice->cofAC[pl_off][0][1];
676 imgpel **img_enc = p_Vid->enc_picture->p_curr_img;
677 imgpel **mb_pred = currSlice->mb_pred[pl];
678 int **mb_ores = currSlice->mb_ores[pl];
679 int **mb_rres = currSlice->mb_rres[pl];
680
681 int scan_poss[4] = { 0 }, runs[4] = { -1, -1, -1, -1 };
682 int MCcoeff = 0;
683 int *m7;
684 int is_cavlc = (currSlice->symbol_mode == CAVLC);
685
686 const byte (*pos_scan)[2] = currMB->is_field_mode ? FIELD_SCAN8x8 : SNGL_SCAN8x8;
687
688 int **fadjust8x8 = p_Vid->AdaptiveRounding ? (&p_Vid->ARCofAdj8x8[pl][currMB->ar_mode][block_y]) :NULL;
689
690 runs[0]=runs[1]=runs[2]=runs[3]=-1;
691 scan_poss[0] = scan_poss[1] = scan_poss[2] = scan_poss[3] = 0;
692
693 if( (currMB->ipmode_DPCM < 2)&&(intra))
694 {
695 Residual_DPCM_8x8(currMB->ipmode_DPCM, mb_ores, mb_rres, block_y, block_x);
696 }
697 else
698 {
699 for (j = block_y ; j < block_y + BLOCK_SIZE_8x8 ; j ++)
700 for (i = block_x ; i < block_x + BLOCK_SIZE_8x8 ; i ++)
701 mb_rres[j][i] = mb_ores[j][i] ;
702 }
703
704 for (coeff_ctr=0; coeff_ctr < 64; coeff_ctr++)
705 {
706 i=pos_scan[coeff_ctr][0];
707 j=pos_scan[coeff_ctr][1];
708
709 run++;
710
711 if (currMB->luma_transform_size_8x8_flag && is_cavlc)
712 {
713 MCcoeff = (coeff_ctr & 3);
714 runs[MCcoeff]++;
715 }
716
717 m7 = &mb_rres[block_y + j][block_x + i];
718
719 if (p_Vid->AdaptiveRounding)
720 {
721 fadjust8x8[j][block_x+i] = 0;
722 }
723
724 if (*m7 != 0)
725 {
726 nonzero = TRUE;
727
728 if (currMB->luma_transform_size_8x8_flag && is_cavlc)
729 {
730 *m7 = iClip3(-CAVLC_LEVEL_LIMIT, CAVLC_LEVEL_LIMIT, *m7);
731 *coeff_cost += MAX_VALUE;
732
733 currSlice->cofAC[pl_off][MCcoeff][0][scan_poss[MCcoeff] ] = *m7;
734 currSlice->cofAC[pl_off][MCcoeff][1][scan_poss[MCcoeff]++] = runs[MCcoeff];
735 ++scan_pos;
736 runs[MCcoeff]=-1;
737 }
738 else
739 {
740 *coeff_cost += MAX_VALUE;
741 ACLevel[scan_pos ] = *m7;
742 ACRun [scan_pos++] = run;
743 run=-1; // reset zero level counter
744 }
745 }
746 }
747
748 if (!currMB->luma_transform_size_8x8_flag || !is_cavlc)
749 ACLevel[scan_pos] = 0;
750 else
751 {
752 for(i=0; i<4; i++)
753 currSlice->cofAC[pl_off][i][0][scan_poss[i]] = 0;
754 }
755
756 if( (currMB->ipmode_DPCM < 2) && (intra))
757 {
758 Inv_Residual_DPCM_8x8(currMB, mb_rres, block_y, block_x);
759 }
760
761 for( j=block_y; j<block_y + BLOCK_SIZE_8x8; j++)
762 {
763 for( i=block_x; i< block_x + BLOCK_SIZE_8x8; i++)
764 {
765 mb_rres[j][i] += (int) mb_pred[j][i];
766 img_enc[currMB->pix_y + j][currMB->pix_x + i]= (imgpel) mb_rres[j][i];
767 }
768 }
769
770 // Decoded block moved to frame memory
771 return nonzero;
772 }
773
774
775 /*static inline void compute_diff(int *diff, imgpel *cimg, imgpel *cmpr, int width)
776 {
777 int i;
778 for (i = 0; i < width; i++)
779 {
780 *(diff++) = *(cimg++) - *(cmpr++);
781 }
782 }*/
783
784 /*!
785 *************************************************************************************
786 * \brief
787 * distortion for an 8x8 Intra block
788 *************************************************************************************
789 */
compute_comp8x8_cost(VideoParameters * p_Vid,imgpel ** cur_img,imgpel ** mpr8x8,int pic_opix_x,distblk min_cost)790 distblk compute_comp8x8_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **mpr8x8, int pic_opix_x, distblk min_cost)
791 {
792 short diff64[64];
793
794 int i, j;
795 short *diff = &diff64[0];
796 imgpel *cimg, *cmpr;
797
798 for (j=0; j<8; j++)
799 {
800 // compute_diff(diff, &cur_img[j][pic_opix_x], &mpr8x8[j][0], BLOCK_SIZE_8x8);
801
802 cimg = &cur_img[j][pic_opix_x];
803 cmpr = &mpr8x8[j][0];
804 for (i=0; i<8; i++)
805 {
806 *diff++ = *cimg++ - *cmpr++;
807 }
808
809 }
810 return p_Vid->distortion8x8 (diff64, min_cost);
811 }
812
813
814 /*!
815 *************************************************************************************
816 * \brief
817 * SAD distortion for an 8x8 Intra block
818 *************************************************************************************
819 */
compute_sad8x8_cost(VideoParameters * p_Vid,imgpel ** cur_img,imgpel ** mpr8x8,int pic_opix_x,distblk min_cost)820 distblk compute_sad8x8_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **mpr8x8, int pic_opix_x, distblk min_cost)
821 {
822 imgpel *cimg, *cmpr;
823 int i32Cost = 0;
824 int i, j;
825 int imin_cost = dist_down(min_cost);
826
827 for (j=0; j<8; j++)
828 {
829 cimg = &cur_img[j][pic_opix_x];
830 cmpr = &mpr8x8[j][0];
831 for (i=0; i<8; i++)
832 {
833 i32Cost += iabs(*cimg++ - *cmpr++);
834 }
835
836 if (i32Cost > imin_cost)
837 {
838 return min_cost;
839 }
840 }
841 return dist_scale(i32Cost);
842 }
843
844 /*!
845 *************************************************************************************
846 * \brief
847 * SSE distortion for an 8x8 Intra block
848 *************************************************************************************
849 */
compute_sse8x8_cost(VideoParameters * p_Vid,imgpel ** cur_img,imgpel ** mpr8x8,int pic_opix_x,distblk min_cost)850 distblk compute_sse8x8_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **mpr8x8, int pic_opix_x, distblk min_cost)
851 {
852 int i, j;
853 imgpel *cimg, *cmpr;
854 int imin_cost = dist_down(min_cost);
855 int distortion = 0;
856
857 for (j=0; j<8; j++)
858 {
859 cimg = &cur_img[j][pic_opix_x];
860 cmpr = &mpr8x8[j][0];
861
862 for (i=0; i<8; i++)
863 {
864 distortion += iabs2(*cimg++ - *cmpr++);
865 }
866
867 if (distortion > imin_cost)
868 {
869 return min_cost;
870 }
871 }
872 return dist_scale(distortion);
873 }
874 /*!
875 *************************************************************************************
876 * \brief
877 * SATD distortion for an 8x8 Intra block
878 *************************************************************************************
879 */
compute_satd8x8_cost(VideoParameters * p_Vid,imgpel ** cur_img,imgpel ** mpr8x8,int pic_opix_x,distblk min_cost)880 distblk compute_satd8x8_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **mpr8x8, int pic_opix_x, distblk min_cost)
881 {
882 int i, j;
883 short diff64[64];
884
885 short *diff = &diff64[0];
886 imgpel *cimg, *cmpr;
887
888 for (j=0; j<8; j++)
889 {
890 cimg = &cur_img[j][pic_opix_x];
891 cmpr = &mpr8x8[j][0];
892 for (i=0; i<8; i++)
893 {
894 *diff++ = *cimg++ - *cmpr++;
895 }
896 }
897
898 return (dist_scale(HadamardSAD8x8 (diff64)));
899 }
900
901