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