1 /*!
2  ***************************************************************************
3  * \file transform8x8_H444.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 "elements.h"
26 #include "vlc.h"
27 #include "transform8x8.h"
28 #include "transform.h"
29 #include "macroblock.h"
30 #include "symbol.h"
31 #include "mc_prediction.h"
32 #include "quant8x8.h"
33 #include "rdoq.h"
34 #include "q_matrix.h"
35 #include "q_offsets.h"
36 #include "rdopt.h"
37 #include "md_common.h"
38 #include "intra8x8.h"
39 #include "rdopt_coding_state.h"
40 #include "blk_prediction.h"
41 
42 /*!
43  *************************************************************************************
44  * \brief
45  *    8x8 Intra mode decision for a macroblock - Low complexity
46  *************************************************************************************
47  */
mode_decision_for_I8x8_blocks_JM_Low444(Macroblock * currMB,int b8,int lambda,distblk * min_cost)48 int mode_decision_for_I8x8_blocks_JM_Low444 (Macroblock *currMB, int b8, int lambda, distblk *min_cost)
49 {
50   VideoParameters *p_Vid = currMB->p_Vid;
51   InputParameters *p_Inp = currMB->p_Inp;
52   Slice *currSlice = currMB->p_Slice;
53 
54   int     ipmode, best_ipmode = 0, j, dummy;
55   distblk   cost;
56   int     nonzero = 0;
57   int     block_x     = (b8 & 0x01) << 3;
58   int     block_y     = (b8 >> 1) << 3;
59   int     pic_pix_x   = currMB->pix_x + block_x;
60   int     pic_pix_y   = currMB->pix_y + block_y;
61   int     pic_opix_x  = currMB->pix_x + block_x;
62   int     pic_opix_y  = currMB->opix_y + block_y;
63   int     pic_block_x = pic_pix_x >> 2;
64   int     pic_block_y = pic_pix_y >> 2;
65   int     mb_block_y  = (currMB->block_y) + ((b8 >> 1) << 1);
66   int     mb_block_x  = (currMB->block_x) + ((b8 & 0x01) << 1);
67 
68   //imgpel    *img_org, *img_prd;
69   //int       *residual;
70   int left_available, up_available, all_available;
71   int    **mb_ores = currSlice->mb_ores[0];
72   imgpel **mb_pred = currSlice->mb_pred[0];
73   int *mb_size = p_Vid->mb_size[IS_LUMA];
74 
75   char   upMode, leftMode;
76   int    mostProbableMode;
77 
78   PixelPos left_block, top_block;
79 
80   get4x4Neighbour(currMB, block_x - 1, block_y    , mb_size, &left_block);
81   get4x4Neighbour(currMB, block_x,     block_y - 1, mb_size, &top_block );
82 
83   if (p_Inp->UseConstrainedIntraPred)
84   {
85     top_block.available  = top_block.available  ? p_Vid->intra_block [top_block.mb_addr] : 0;
86     left_block.available = left_block.available ? p_Vid->intra_block [left_block.mb_addr] : 0;
87   }
88 
89   if(b8 >> 1)
90     upMode    =  top_block.available ? p_Vid->ipredmode8x8[top_block.pos_y ][top_block.pos_x ] : -1;
91   else
92     upMode    =  top_block.available ? p_Vid->ipredmode   [top_block.pos_y ][top_block.pos_x ] : -1;
93 
94   if(b8 & 0x01)
95     leftMode  = left_block.available ? p_Vid->ipredmode8x8[left_block.pos_y][left_block.pos_x] : -1;
96   else
97     leftMode  = left_block.available ? p_Vid->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
98 
99   mostProbableMode  = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
100   *min_cost = DISTBLK_MAX;
101   currMB->ipmode_DPCM = NO_INTRA_PMODE; //For residual DPCM
102 
103   //===== INTRA PREDICTION FOR 8x8 BLOCK =====
104   currSlice->set_intrapred_8x8(currMB, PLANE_Y, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
105 
106   if(currSlice->P444_joined)
107   {
108     select_plane(p_Vid, PLANE_U);
109     currSlice->set_intrapred_8x8(currMB, PLANE_U, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
110     select_plane(p_Vid, PLANE_V);
111     currSlice->set_intrapred_8x8(currMB, PLANE_V, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
112     select_plane(p_Vid, PLANE_Y);
113   }
114 
115   //===== LOOP OVER ALL 8x8 INTRA PREDICTION MODES =====
116   for (ipmode = 0; ipmode < NO_INTRA_PMODE; ipmode++)
117   {
118     if( (ipmode==DC_PRED) ||
119       ((ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED) && up_available ) ||
120       ((ipmode==HOR_PRED||ipmode==HOR_UP_PRED) && left_available ) ||
121       (all_available) )
122     {
123       get_intrapred_8x8(currMB, PLANE_Y, ipmode, left_available, up_available);
124       cost  = (ipmode == mostProbableMode) ? 0 : ( weighted_cost(lambda, 4) );
125       cost += currSlice->compute_cost8x8(p_Vid, &p_Vid->pImgOrg[0][pic_opix_y], currSlice->mpr_8x8[0][ipmode], pic_opix_x, *min_cost - cost);
126 
127       if(currSlice->P444_joined)
128       {
129         get_intrapred_8x8(currMB, PLANE_U, ipmode, left_available, up_available);
130         cost += currSlice->compute_cost8x8(p_Vid, &p_Vid->pImgOrg[PLANE_U][pic_opix_y], currSlice->mpr_8x8[PLANE_U][ipmode], pic_opix_x, *min_cost - cost);
131         get_intrapred_8x8(currMB, PLANE_V, ipmode, left_available, up_available);
132         cost += currSlice->compute_cost8x8(p_Vid, &p_Vid->pImgOrg[PLANE_V][pic_opix_y], currSlice->mpr_8x8[PLANE_V][ipmode], pic_opix_x, *min_cost - cost);
133       }
134 
135       if (cost < *min_cost)
136       {
137         best_ipmode = ipmode;
138         *min_cost   = cost;
139       }
140     }
141   }
142 
143   //===== set intra mode prediction =====
144   p_Vid->ipredmode8x8[pic_block_y][pic_block_x] = (char) best_ipmode;
145   currMB->ipmode_DPCM = (char) best_ipmode; //For residual DPCM
146 
147   if(currSlice->P444_joined)
148   {
149     ColorPlane k;
150     p_Vid->CbCr_predmode_8x8[b8] = best_ipmode;
151     for (k = PLANE_U; k <= PLANE_V; k++)
152     {
153       currMB->cr_cbp[k] = 0;
154       select_plane(p_Vid, k);
155       /*
156       for (j=0; j<8; j++)
157       {
158         for (i=0; i<8; i++)
159         {
160           currSlice->mb_pred[k][block_y+j][block_x+i] = currSlice->mpr_8x8[k][best_ipmode][j][i];
161           currSlice->mb_ores[k][block_y+j][block_x+i] = p_Vid->pImgOrg[k][currMB->pix_y + block_y + j][currMB->pix_x + block_x + i] - currSlice->mpr_8x8[k][best_ipmode][j][i];
162         }
163       }
164       */
165       copy_image_data_8x8(&currSlice->mb_pred[k][block_y], currSlice->mpr_8x8[k][best_ipmode], block_x, 0);
166       compute_residue(&(p_Vid->pImgOrg[k][currMB->pix_y+block_y]), &currSlice->mb_pred[k][block_y], &currSlice->mb_ores[k][block_y], block_x, currMB->pix_x+block_x, 8, 8);
167 
168       currMB->ipmode_DPCM = (short) best_ipmode;
169       if (currMB->residual_transform_quant_luma_8x8(currMB, k, b8, &dummy, 1))
170         currMB->cr_cbp[k] = 1;
171     }
172     select_plane(p_Vid, PLANE_Y);
173   }
174 
175   currMB->intra_pred_modes8x8[4*b8] = (char) ((mostProbableMode == best_ipmode)
176     ? -1
177     : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));
178 
179   for(j = mb_block_y; j < mb_block_y + 2; j++)   //loop 4x4s in the subblock for 8x8 prediction setting
180     memset(&p_Vid->ipredmode8x8[j][mb_block_x], best_ipmode, 2 * sizeof(char));
181 
182   // get prediction and prediction error
183   /*
184   for (j = block_y; j < block_y + 8; j++)
185   {
186     memcpy(&mb_pred[j][block_x],currSlice->mpr_8x8[0][best_ipmode][j - block_y], 8 * sizeof(imgpel));
187     img_org  = &p_Vid->pCurImg[currMB->opix_y + j][pic_opix_x];
188     img_prd  = &mb_pred[j][block_x];
189     residual = &mb_ores[j][block_x];
190     for (i=0; i<8; i++)
191     {
192       *residual++ = *img_org++ - *img_prd++;
193     }
194   }
195   */
196   generate_pred_error_8x8(&p_Vid->pCurImg[currMB->opix_y+block_y], currSlice->mpr_8x8[0][best_ipmode], &mb_pred[block_y], &mb_ores[block_y], pic_opix_x, block_x);
197 
198   currMB->ipmode_DPCM = (short) best_ipmode;
199   nonzero = currMB->residual_transform_quant_luma_8x8 (currMB, PLANE_Y, b8, &dummy, 1);
200   return nonzero;
201 }
202 
203 /*!
204 *************************************************************************************
205 * \brief
206 *    8x8 Intra mode decision for a macroblock - High complexity
207 *************************************************************************************
208 */
mode_decision_for_I8x8_blocks_JM_High444(Macroblock * currMB,int b8,int lambda,distblk * min_cost)209 int mode_decision_for_I8x8_blocks_JM_High444 (Macroblock *currMB, int b8, int lambda, distblk *min_cost)
210 {
211   VideoParameters *p_Vid = currMB->p_Vid;
212   InputParameters *p_Inp = currMB->p_Inp;
213   Slice *currSlice = currMB->p_Slice;
214   RDOPTStructure  *p_RDO = currSlice->p_RDO;
215 
216   int     ipmode, best_ipmode = 0, j, dummy;
217   int     c_nz, nonzero = 0;
218   distblk  rdcost = 0;
219   distblk  min_rdcost  = DISTBLK_MAX;
220   int     block_x     = (b8 & 0x01) << 3;
221   int     block_y     = (b8 >> 1) << 3;
222   int     pic_pix_x   = currMB->pix_x + block_x;
223   int     pic_pix_y   = currMB->pix_y + block_y;
224   int     pic_opix_x  = currMB->pix_x + block_x;
225   int     pic_opix_y  = currMB->opix_y + block_y;
226   int     pic_block_x = pic_pix_x >> 2;
227   int     pic_block_y = pic_pix_y >> 2;
228   int     mb_block_y  = (currMB->block_y) + ((b8 >> 1) << 1);
229   int     mb_block_x  = (currMB->block_x) + ((b8 & 0x01) << 1);
230 
231   int uv;
232   int left_available, up_available, all_available;
233 
234   char   upMode, leftMode;
235   int    mostProbableMode;
236 
237   PixelPos left_block, top_block;
238 
239   int *mb_size = p_Vid->mb_size[IS_LUMA];
240 
241   get4x4Neighbour(currMB, block_x - 1, block_y    , mb_size, &left_block);
242   get4x4Neighbour(currMB, block_x,     block_y - 1, mb_size, &top_block );
243 
244   if (p_Inp->UseConstrainedIntraPred)
245   {
246     top_block.available  = top_block.available  ? p_Vid->intra_block [top_block.mb_addr ] : 0;
247     left_block.available = left_block.available ? p_Vid->intra_block [left_block.mb_addr] : 0;
248   }
249 
250   if(b8 >> 1)
251     upMode    =  top_block.available ? p_Vid->ipredmode8x8[top_block.pos_y ][top_block.pos_x ] : -1;
252   else
253     upMode    =  top_block.available ? p_Vid->ipredmode   [top_block.pos_y ][top_block.pos_x ] : -1;
254 
255   if(b8 & 0x01)
256     leftMode  = left_block.available ? p_Vid->ipredmode8x8[left_block.pos_y][left_block.pos_x] : -1;
257   else
258     leftMode  = left_block.available ? p_Vid->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
259 
260   mostProbableMode  = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
261   *min_cost = DISTBLK_MAX;
262   currMB->ipmode_DPCM = NO_INTRA_PMODE; //For residual DPCM
263 
264   //===== INTRA PREDICTION FOR 8x8 BLOCK =====
265   currSlice->set_intrapred_8x8(currMB, PLANE_Y, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
266 
267   if(currSlice->P444_joined)
268   {
269     select_plane(p_Vid, PLANE_U);
270     currSlice->set_intrapred_8x8(currMB, PLANE_U, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
271     select_plane(p_Vid, PLANE_V);
272     currSlice->set_intrapred_8x8(currMB, PLANE_V, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
273     select_plane(p_Vid, PLANE_Y);
274   }
275 
276   //===== LOOP OVER ALL 8x8 INTRA PREDICTION MODES =====
277   for (ipmode = 0; ipmode < NO_INTRA_PMODE; ipmode++)
278   {
279     if( (ipmode==DC_PRED) ||
280       ((ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED) && up_available ) ||
281       ((ipmode==HOR_PRED||ipmode==HOR_UP_PRED) && left_available ) ||
282       (all_available) )
283     {
284       get_intrapred_8x8(currMB, PLANE_Y, ipmode, left_available, up_available);
285 
286       // get prediction and prediction error
287       generate_pred_error_8x8(&p_Vid->pImgOrg[0][pic_opix_y], currSlice->mpr_8x8[0][ipmode], &currSlice->mb_pred[0][block_y], &currSlice->mb_ores[0][block_y], pic_opix_x, block_x);
288 
289       if(currSlice->P444_joined)
290       {
291         get_intrapred_8x8(currMB, PLANE_U, ipmode, left_available, up_available);
292         generate_pred_error_8x8(&p_Vid->pImgOrg[1][pic_opix_y], currSlice->mpr_8x8[1][ipmode], &currSlice->mb_pred[1][block_y], &currSlice->mb_ores[1][block_y], pic_opix_x, block_x);
293         get_intrapred_8x8(currMB, PLANE_V, ipmode, left_available, up_available);
294         generate_pred_error_8x8(&p_Vid->pImgOrg[2][pic_opix_y], currSlice->mpr_8x8[2][ipmode], &currSlice->mb_pred[2][block_y], &currSlice->mb_ores[2][block_y], pic_opix_x, block_x);
295       }
296 
297       currMB->ipmode_DPCM = (short) ipmode;
298 
299       // get and check rate-distortion cost
300 
301       rdcost = currSlice->rdcost_for_8x8_intra_blocks (currMB, &c_nz, b8, ipmode, lambda, min_rdcost, mostProbableMode);
302       if ((rdcost < min_rdcost) || (rdcost == min_rdcost && ipmode == mostProbableMode))
303       {
304         //--- set coefficients ---
305         memcpy(p_RDO->coefAC8x8intra[b8][0][0][0],currSlice->cofAC[b8][0][0], 4 * 2 * 65 * sizeof(int));
306 
307         //--- set reconstruction ---
308         copy_image_data_8x8(p_RDO->rec8x8[PLANE_Y], &p_Vid->enc_picture->imgY[pic_pix_y], 0, pic_pix_x);
309 
310         if (p_Vid->AdaptiveRounding)
311         {
312           for (j = block_y; j < block_y + 8; j++)
313             memcpy(&p_Vid->ARCofAdj8x8[0][DUMMY][j][block_x],&p_Vid->ARCofAdj8x8[0][I8MB][j][block_x], 8 * sizeof(int));
314 
315           if (currSlice->P444_joined)
316           {
317             for (j = block_y; j < block_y + 8; j++)
318             {
319               memcpy(&p_Vid->ARCofAdj8x8[1][DUMMY][j][block_x],&p_Vid->ARCofAdj8x8[1][I8MB][j][block_x], 8 * sizeof(int));
320               memcpy(&p_Vid->ARCofAdj8x8[2][DUMMY][j][block_x],&p_Vid->ARCofAdj8x8[2][I8MB][j][block_x], 8 * sizeof(int));
321             }
322           }
323         }
324 
325         if (currSlice->P444_joined)
326         {
327           //--- set coefficients ---
328           for (uv=0; uv < 2; uv++)
329           {
330             memcpy(p_RDO->coefAC8x8intra[b8][uv + 1][0][0],currSlice->cofAC[4+b8+4*uv][0][0], 2 * 4 * 65 * sizeof(int));
331 
332             currMB->cr_cbp[uv + 1] = currMB->c_nzCbCr[uv + 1];
333             //--- set reconstruction ---
334             copy_image_data_8x8(p_RDO->rec8x8[uv + 1], &p_Vid->enc_picture->imgUV[uv][pic_pix_y], 0, pic_pix_x);
335           }
336         }
337 
338         //--- flag if transform coefficients must be coded ---
339         nonzero = c_nz;
340 
341         //--- set best mode update minimum cost ---
342         *min_cost   = rdcost;
343         min_rdcost  = rdcost;
344         best_ipmode = ipmode;
345       }
346     }
347   }
348 
349   //===== set intra mode prediction =====
350   p_Vid->ipredmode8x8[pic_block_y][pic_block_x] = (char) best_ipmode;
351   currMB->ipmode_DPCM = (short) best_ipmode; //For residual DPCM
352 
353   if(currSlice->P444_joined)
354   {
355     ColorPlane k;
356     p_Vid->CbCr_predmode_8x8[b8] = best_ipmode;
357     for (k = PLANE_U; k <= PLANE_V; k++)
358     {
359       currMB->cr_cbp[k] = 0;
360       select_plane(p_Vid, k);
361       /*
362       for (j=0; j<8; j++)
363       {
364         for (i=0; i<8; i++)
365         {
366           currSlice->mb_pred[k][block_y+j][block_x+i] = currSlice->mpr_8x8[k][best_ipmode][j][i];
367           currSlice->mb_ores[k][block_y+j][block_x+i] = p_Vid->pImgOrg[k][currMB->pix_y + block_y + j][currMB->pix_x + block_x + i] - currSlice->mpr_8x8[k][best_ipmode][j][i];
368         }
369       }
370       */
371       generate_pred_error_8x8(&p_Vid->pImgOrg[k][currMB->pix_y + block_y], currSlice->mpr_8x8[k][best_ipmode], &currSlice->mb_pred[k][block_y], &currSlice->mb_ores[k][block_y], currMB->pix_x + block_x, block_x);
372       currMB->ipmode_DPCM = (short) best_ipmode;
373 
374       if (currMB->residual_transform_quant_luma_8x8(currMB, k, b8, &dummy, 1))
375         currMB->cr_cbp[k] = 1;
376     }
377     select_plane(p_Vid, PLANE_Y);
378   }
379 
380   currMB->intra_pred_modes8x8[4*b8] = (char) ((mostProbableMode == best_ipmode)
381     ? -1
382     : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));
383 
384   memset(&p_Vid->ipredmode8x8[mb_block_y    ][mb_block_x], best_ipmode, 2 * sizeof(char));
385   memset(&p_Vid->ipredmode8x8[mb_block_y + 1][mb_block_x], best_ipmode, 2 * sizeof(char));
386 
387   //===== restore coefficients =====
388   memcpy(currSlice->cofAC[b8][0][0], p_RDO->coefAC8x8intra[b8][0][0][0], 4 * 2 * 65 * sizeof(int));
389 
390   if (p_Vid->AdaptiveRounding)
391   {
392     for (j=block_y; j< block_y + 8; j++)
393       memcpy(&p_Vid->ARCofAdj8x8[0][I8MB][j][block_x], &p_Vid->ARCofAdj8x8[0][DUMMY][j][block_x], 8 * sizeof(int));
394 
395     if (currSlice->P444_joined)
396     {
397       for (j=0; j<8; j++)
398       {
399         memcpy(&p_Vid->ARCofAdj8x8[1][I8MB][block_y + j][block_x], &p_Vid->ARCofAdj8x8[1][DUMMY][block_y + j][block_x], 8 * sizeof(int));
400         memcpy(&p_Vid->ARCofAdj8x8[2][I8MB][block_y + j][block_x], &p_Vid->ARCofAdj8x8[2][DUMMY][block_y + j][block_x], 8 * sizeof(int));
401       }
402     }
403   }
404 
405   //===== restore reconstruction and prediction (needed if single coeffs are removed) =====
406   copy_image_data_8x8(&p_Vid->enc_picture->imgY[pic_pix_y], p_RDO->rec8x8[0], pic_pix_x, 0);
407   copy_image_data_8x8(&currSlice->mb_pred[0][block_y], currSlice->mpr_8x8[0][best_ipmode], block_x, 0);
408 
409   if (currSlice->P444_joined)
410   {
411     //===== restore coefficients =====
412     memcpy(currSlice->cofAC[4 + b8 + 4*0][0][0], p_RDO->coefAC8x8intra[b8][1][0][0], 4 * 2 * 65 * sizeof(int));
413     memcpy(currSlice->cofAC[4 + b8 + 4*1][0][0], p_RDO->coefAC8x8intra[b8][2][0][0], 4 * 2 * 65 * sizeof(int));
414 
415     //===== restore reconstruction and prediction (needed if single coeffs are removed) =====
416     copy_image_data_8x8(&p_Vid->enc_picture->imgUV[0][pic_pix_y], p_RDO->rec8x8[1], pic_pix_x, 0);
417     copy_image_data_8x8(&p_Vid->enc_picture->imgUV[1][pic_pix_y], p_RDO->rec8x8[2], pic_pix_x, 0);
418     copy_image_data_8x8(&currSlice->mb_pred[1][block_y], currSlice->mpr_8x8[1][best_ipmode], block_x, 0);
419     copy_image_data_8x8(&currSlice->mb_pred[2][block_y], currSlice->mpr_8x8[2][best_ipmode], block_x, 0);
420   }
421 
422   return nonzero;
423 }
424 
425