1 /*!
2  ***************************************************************************
3  * \file rd_intra_jm444.c
4  *
5  * \brief
6  *    Rate-Distortion optimized mode decision
7  *
8  * \author
9  *    - Heiko Schwarz
10  *    - Valeri George
11  *    - Lowell Winger              <lwinger@lsil.com>
12  *    - Alexis Michael Tourapis    <alexismt@ieee.org>
13  * \date
14  *    12. April 2001
15  **************************************************************************
16  */
17 
18 #include <limits.h>
19 
20 #include "global.h"
21 
22 #include "image.h"
23 #include "macroblock.h"
24 #include "mb_access.h"
25 #include "rdopt_coding_state.h"
26 #include "mode_decision.h"
27 #include "rdopt.h"
28 #include "rd_intra_jm.h"
29 #include "q_around.h"
30 #include "intra4x4.h"
31 #include "rd_intra_jm.h"
32 #include "blk_prediction.h"
33 
34 /*!
35  *************************************************************************************
36  * \brief
37  *    Mode Decision for an 4x4 Intra block
38  *************************************************************************************
39  */
mode_decision_for_I4x4_blocks_JM_High444(Macroblock * currMB,int b8,int b4,int lambda,distblk * min_cost)40 int mode_decision_for_I4x4_blocks_JM_High444 (Macroblock *currMB, int  b8,  int  b4,  int  lambda,  distblk*  min_cost)
41 {
42   VideoParameters *p_Vid = currMB->p_Vid;
43   InputParameters *p_Inp = currMB->p_Inp;
44   Slice *currSlice = currMB->p_Slice;
45   RDOPTStructure  *p_RDO = currSlice->p_RDO;
46 
47   int    ipmode, best_ipmode = 0, y, dummy;
48   int    c_nz, nonzero = 0;
49   int*   ACLevel = currSlice->cofAC[b8][b4][0];
50   int*   ACRun   = currSlice->cofAC[b8][b4][1];
51   int    uv;
52   distblk rdcost = 0;
53   distblk min_rdcost  = DISTBLK_MAX;
54   int    block_x     = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
55   int    block_y     = ((b8 >> 1) << 3)  + ((b4 >> 1) << 2);
56   int    pic_pix_x   = currMB->pix_x  + block_x;
57   int    pic_pix_y   = currMB->pix_y  + block_y;
58   int    pic_opix_x  = currMB->pix_x + block_x;
59   int    pic_opix_y  = currMB->opix_y + block_y;
60   int    pic_block_x = pic_pix_x >> 2;
61   int    pic_block_y = pic_pix_y >> 2;
62 
63   int left_available, up_available, all_available;
64   int *mb_size = p_Vid->mb_size[IS_LUMA];
65 
66   char   upMode, leftMode;
67   int    mostProbableMode;
68 
69   PixelPos left_block, top_block;
70 
71   int  lrec4x4[4][4];
72   int best_nz_coeff = 0;
73   int block_x4 = block_x>>2;
74   int block_y4 = block_y>>2;
75 
76 #ifdef BEST_NZ_COEFF
77   int best_coded_block_flag = 0;
78   int bit_pos = 1 + ((((b8>>1)<<1)+(b4>>1))<<2) + (((b8&1)<<1)+(b4&1));
79   int64 cbp_bits;
80 
81   if (b8==0 && b4==0)
82     cbp_bits = 0;
83 #endif
84 
85   get4x4Neighbour(currMB, block_x - 1, block_y    , mb_size, &left_block);
86   get4x4Neighbour(currMB, block_x,     block_y - 1, mb_size, &top_block );
87 
88   // constrained intra pred
89   if (p_Inp->UseConstrainedIntraPred)
90   {
91     left_block.available = left_block.available ? p_Vid->intra_block[left_block.mb_addr] : 0;
92     top_block.available  = top_block.available  ? p_Vid->intra_block[top_block.mb_addr]  : 0;
93   }
94 
95   upMode            =  top_block.available ? p_Vid->ipredmode[top_block.pos_y ][top_block.pos_x ] : -1;
96   leftMode          = left_block.available ? p_Vid->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
97 
98   mostProbableMode  = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
99   *min_cost = DISTBLK_MAX;
100   currMB->ipmode_DPCM = NO_INTRA_PMODE; ////For residual DPCM
101 
102   //===== INTRA PREDICTION FOR 4x4 BLOCK =====
103   // set intra prediction values for 4x4 intra prediction
104   currSlice->set_intrapred_4x4(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_4x4(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_4x4(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 4x4 INTRA PREDICTION MODES =====
116   for (ipmode = 0; ipmode < NO_INTRA_PMODE; ipmode++)
117   {
118     int available_mode =  (all_available) || (ipmode==DC_PRED) ||
119       (up_available && (ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED)) ||
120       (left_available && (ipmode==HOR_PRED||ipmode==HOR_UP_PRED));
121 
122     if (valid_intra_mode(currSlice, ipmode) == 0)
123       continue;
124 
125     if( available_mode)
126     {
127       // generate intra 4x4 prediction block given availability
128       get_intrapred_4x4(currMB, PLANE_Y, ipmode, block_x, block_y, left_available, up_available);
129 
130       // get prediction and prediction error
131       generate_pred_error_4x4(&p_Vid->pCurImg[pic_opix_y], currSlice->mpr_4x4[0][ipmode], &currSlice->mb_pred[0][block_y], &currSlice->mb_ores[0][block_y], pic_opix_x, block_x);
132 
133       if (p_Vid->yuv_format == YUV444)
134       {
135         currMB->ipmode_DPCM = (short) ipmode;
136         if (p_Inp->separate_colour_plane_flag == 0)
137         {
138           // generate intra 4x4 prediction block given availability
139           get_intrapred_4x4(currMB, PLANE_U, ipmode, block_x, block_y, left_available, up_available);
140           generate_pred_error_4x4(&p_Vid->pImgOrg[1][pic_opix_y], currSlice->mpr_4x4[1][ipmode], &currSlice->mb_pred[1][block_y], &currSlice->mb_ores[1][block_y], pic_opix_x, block_x);
141           // generate intra 4x4 prediction block given availability
142           get_intrapred_4x4(currMB, PLANE_V, ipmode, block_x, block_y, left_available, up_available);
143           generate_pred_error_4x4(&p_Vid->pImgOrg[2][pic_opix_y], currSlice->mpr_4x4[2][ipmode], &currSlice->mb_pred[2][block_y], &currSlice->mb_ores[2][block_y], pic_opix_x, block_x);
144         }
145       }
146 
147       // get and check rate-distortion cost
148 #ifdef BEST_NZ_COEFF
149       currMB->cbp_bits[0] = cbp_bits;
150 #endif
151 
152       rdcost = currSlice->rdcost_for_4x4_intra_blocks (currMB, &c_nz, b8, b4, ipmode, lambda, mostProbableMode, min_rdcost);
153       if ((rdcost < min_rdcost) || (rdcost == min_rdcost && ipmode == mostProbableMode))
154       {
155         //--- set coefficients ---
156         memcpy(p_RDO->cofAC4x4[0], ACLevel, 18 * sizeof(int));
157         memcpy(p_RDO->cofAC4x4[1], ACRun,   18 * sizeof(int));
158 
159         //--- set reconstruction ---
160         copy_4x4block(p_RDO->rec4x4[PLANE_Y], &p_Vid->enc_picture->imgY[pic_pix_y], 0, pic_pix_x);
161 
162         // SP/SI reconstruction
163         if(currSlice->slice_type == SP_SLICE && !currSlice->sp2_frame_indicator)
164         {
165           for (y=0; y<4; y++)
166           {
167             memcpy(lrec4x4[y],&p_Vid->lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));// stores the mode coefficients
168           }
169         }
170 
171         if(currSlice->P444_joined)
172         {
173           //--- set coefficients ---
174           for (uv=0; uv < 2; uv++)
175           {
176             memcpy(p_RDO->cofAC4x4CbCr[uv][0],currSlice->cofAC[b8+4+uv*4][b4][0], 18 * sizeof(int));
177             memcpy(p_RDO->cofAC4x4CbCr[uv][1],currSlice->cofAC[b8+4+uv*4][b4][1], 18 * sizeof(int));
178             currMB->cr_cbp[uv + 1] = currMB->c_nzCbCr[uv + 1];
179 
180             //--- set reconstruction ---
181             copy_4x4block(p_RDO->rec4x4[uv + 1], &p_Vid->enc_picture->imgUV[uv][pic_pix_y], 0, pic_pix_x);
182           }
183         }
184         //--- flag if transform coefficients must be coded ---
185         nonzero = c_nz;
186 
187         //--- set best mode update minimum cost ---
188         *min_cost     = rdcost;
189         min_rdcost    = rdcost;
190         best_ipmode   = ipmode;
191 
192         best_nz_coeff = p_Vid->nz_coeff [currMB->mbAddrX][block_x4][block_y4];
193 #ifdef BEST_NZ_COEFF
194         best_coded_block_flag = (int)((currMB->cbp_bits[0] >> bit_pos)&(int64)(1));
195 #endif
196         if (p_Vid->AdaptiveRounding)
197         {
198           store_adaptive_rounding_4x4 (p_Vid, p_Vid->ARCofAdj4x4, I4MB, block_y, block_x);
199         }
200       }
201     }
202   }
203 #if INTRA_RDCOSTCALC_NNZ
204   p_Vid->nz_coeff [currMB->mbAddrX][block_x4][block_y4] = best_nz_coeff;
205 #endif
206 #ifdef BEST_NZ_COEFF
207   cbp_bits &= (~(int64)(1<<bit_pos));
208   cbp_bits |= (int64)(best_coded_block_flag<<bit_pos);
209 #endif
210 
211   //===== set intra mode prediction =====
212   p_Vid->ipredmode[pic_block_y][pic_block_x] = (char) best_ipmode;
213   currMB->intra_pred_modes[4*b8+b4] =
214     (char) (mostProbableMode == best_ipmode ? -1 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));
215 
216   if(currSlice->P444_joined)
217   {
218     ColorPlane k;
219     for (k = PLANE_U; k <= PLANE_V; k++)
220     {
221       select_plane(p_Vid, k);
222 
223       copy_4x4block(&currSlice->mb_pred[k][block_y], currSlice->mpr_4x4[k][best_ipmode], block_x, 0);
224       /*
225       for (j=0; j<4; j++)
226       {
227         for (i=0; i<4; i++)
228         {
229           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_4x4[k][best_ipmode][j][i];
230         }
231       }
232       */
233       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, 4, 4);
234       currMB->cr_cbp[k] = currMB->residual_transform_quant_luma_4x4(currMB, k, block_x,block_y,&dummy,1);
235     }
236     select_plane(p_Vid, PLANE_Y);
237   }
238 
239   //===== restore coefficients =====
240   memcpy (ACLevel, p_RDO->cofAC4x4[0], 18 * sizeof(int));
241   memcpy (ACRun,   p_RDO->cofAC4x4[1], 18 * sizeof(int));
242 
243   //===== restore reconstruction and prediction (needed if single coeffs are removed) =====
244   copy_4x4block(&p_Vid->enc_picture->imgY[pic_pix_y], p_RDO->rec4x4[PLANE_Y], pic_pix_x, 0);
245   copy_4x4block(&currSlice->mb_pred[0][block_y], currSlice->mpr_4x4[0][best_ipmode], block_x, 0);
246 
247   // SP/SI reconstuction
248   if(currSlice->slice_type == SP_SLICE && !p_Vid->sp2_frame_indicator)
249   {
250     for (y=0; y<BLOCK_SIZE; y++)
251     {
252       memcpy (&p_Vid->lrec[pic_pix_y+y][pic_pix_x], lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame
253     }
254   }
255   if (currSlice->P444_joined)
256   {
257     for (uv=0; uv < 2; uv++ )
258     {
259       //===== restore coefficients =====
260       memcpy(currSlice->cofAC[b8+4+uv*4][b4][0], p_RDO->cofAC4x4CbCr[uv][0], 18 * sizeof(int));
261       memcpy(currSlice->cofAC[b8+4+uv*4][b4][1], p_RDO->cofAC4x4CbCr[uv][1], 18 * sizeof(int));
262       //===== restore reconstruction and prediction (needed if single coeffs are removed) =====
263       copy_4x4block(&p_Vid->enc_picture->imgUV[uv][pic_pix_y], p_RDO->rec4x4[uv + 1], pic_pix_x, 0);
264       copy_4x4block(&currSlice->mb_pred[uv + 1][block_y], currSlice->mpr_4x4[uv + 1][best_ipmode], block_x, 0);
265     }
266   }
267 
268   if (p_Vid->AdaptiveRounding)
269   {
270     update_adaptive_rounding_4x4 (p_Vid,p_Vid->ARCofAdj4x4, I4MB, block_y, block_x);
271   }
272 
273   return nonzero;
274 }
275 
276 /*!
277  *************************************************************************************
278  * \brief
279  *    Mode Decision for an 4x4 Intra block
280  *************************************************************************************
281  */
mode_decision_for_I4x4_blocks_JM_Low444(Macroblock * currMB,int b8,int b4,int lambda,distblk * min_cost)282 int mode_decision_for_I4x4_blocks_JM_Low444 (Macroblock *currMB, int  b8,  int  b4,  int  lambda,  distblk*  min_cost)
283 {
284   VideoParameters *p_Vid = currMB->p_Vid;
285   InputParameters *p_Inp = currMB->p_Inp;
286   Slice *currSlice = currMB->p_Slice;
287 
288   int     ipmode, best_ipmode = 0, dummy;
289   distblk cost;
290   int     nonzero = 0;
291 
292   int  block_x     = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
293   int  block_y     = ((b8 >> 1) << 3)  + ((b4 >> 1) << 2);
294   int  pic_pix_x   = currMB->pix_x  + block_x;
295   int  pic_pix_y   = currMB->pix_y  + block_y;
296   int  pic_opix_x  = currMB->pix_x + block_x;
297   int  pic_opix_y  = currMB->opix_y + block_y;
298   int  pic_block_x = pic_pix_x >> 2;
299   int  pic_block_y = pic_pix_y >> 2;
300 
301   int left_available, up_available, all_available;
302 
303   char   upMode, leftMode;
304   int    mostProbableMode;
305 
306   PixelPos left_block;
307   PixelPos top_block;
308 
309   distblk  fixedcost = weighted_cost(lambda, 4);   //(int) floor(4 * lambda );
310   int  *mb_size  = p_Vid->mb_size[IS_LUMA];
311   int best_nz_coeff = 0;
312   int block_x4 = block_x>>2;
313   int block_y4 = block_y>>2;
314 
315 #ifdef BEST_NZ_COEFF
316   int best_coded_block_flag = 0;
317   int bit_pos = 1 + ((((b8>>1)<<1)+(b4>>1))<<2) + (((b8&1)<<1)+(b4&1));
318   int64 cbp_bits;
319 
320   if (b8==0 && b4==0)
321     cbp_bits = 0;
322 #endif
323 
324   get4x4Neighbour(currMB, block_x - 1, block_y    , mb_size, &left_block);
325   get4x4Neighbour(currMB, block_x,     block_y - 1, mb_size, &top_block );
326 
327   // constrained intra pred
328   if (p_Inp->UseConstrainedIntraPred)
329   {
330     left_block.available = left_block.available ? p_Vid->intra_block[left_block.mb_addr] : 0;
331     top_block.available  = top_block.available  ? p_Vid->intra_block[top_block.mb_addr]  : 0;
332   }
333 
334   upMode            =  top_block.available ? p_Vid->ipredmode[top_block.pos_y ][top_block.pos_x ] : -1;
335   leftMode          = left_block.available ? p_Vid->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
336 
337   mostProbableMode  = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
338   *min_cost = DISTBLK_MAX;
339   currMB->ipmode_DPCM = NO_INTRA_PMODE; ////For residual DPCM
340 
341   //===== INTRA PREDICTION FOR 4x4 BLOCK =====
342   // set intra prediction values for 4x4 intra prediction
343   currSlice->set_intrapred_4x4(currMB, PLANE_Y, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
344 
345   if (currSlice->P444_joined)
346   {
347     select_plane(p_Vid, PLANE_U);
348     currSlice->set_intrapred_4x4(currMB, PLANE_U, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
349     select_plane(p_Vid, PLANE_V);
350     currSlice->set_intrapred_4x4(currMB, PLANE_V, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
351     select_plane(p_Vid, PLANE_Y);
352   }
353 
354   //===== LOOP OVER ALL 4x4 INTRA PREDICTION MODES =====
355   for (ipmode = 0; ipmode < NO_INTRA_PMODE; ipmode++)
356   {
357     int available_mode =  (all_available) || (ipmode==DC_PRED) ||
358       (up_available && (ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED)) ||
359       (left_available && (ipmode==HOR_PRED||ipmode==HOR_UP_PRED));
360 
361     if (valid_intra_mode(currSlice, ipmode) == 0)
362       continue;
363 
364     if( available_mode)
365     {
366       // generate intra 4x4 prediction block given availability
367       // Note that some checks may not be necessary internally since the "available_mode" test has already tested
368       // mode availability.
369       get_intrapred_4x4(currMB, PLANE_Y, ipmode, block_x, block_y, left_available, up_available);
370       cost  = (ipmode == mostProbableMode) ? 0 : fixedcost;
371       cost += currSlice->compute_cost4x4(p_Vid, &p_Vid->pCurImg[pic_opix_y], currSlice->mpr_4x4[0][ipmode], pic_opix_x, *min_cost - cost);
372       if (currSlice->P444_joined)
373       {
374         get_intrapred_4x4(currMB, PLANE_U, ipmode, block_x, block_y, left_available, up_available);
375         cost += currSlice->compute_cost4x4(p_Vid, &p_Vid->pImgOrg[1][pic_opix_y], currSlice->mpr_4x4[1][ipmode], pic_opix_x, *min_cost - cost);
376         get_intrapred_4x4(currMB, PLANE_V, ipmode, block_x, block_y, left_available, up_available);
377         cost += currSlice->compute_cost4x4(p_Vid, &p_Vid->pImgOrg[2][pic_opix_y], currSlice->mpr_4x4[2][ipmode], pic_opix_x, *min_cost - cost);
378       }
379 
380       if (cost < *min_cost)
381       {
382         best_ipmode = ipmode;
383         *min_cost   = cost;
384       }
385     }
386   }
387 
388 #if INTRA_RDCOSTCALC_NNZ
389   p_Vid->nz_coeff [currMB->mbAddrX][block_x4][block_y4] = best_nz_coeff;
390 #endif
391 #ifdef BEST_NZ_COEFF
392   cbp_bits &= (~(int64)(1<<bit_pos));
393   cbp_bits |= (int64)(best_coded_block_flag<<bit_pos);
394 #endif
395   //===== set intra mode prediction =====
396   p_Vid->ipredmode[pic_block_y][pic_block_x] = (char) best_ipmode;
397   currMB->intra_pred_modes[4*b8+b4] =
398     (char) (mostProbableMode == best_ipmode ? -1 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));
399 
400   // get prediction and prediction error
401   generate_pred_error_4x4(&p_Vid->pCurImg[pic_opix_y], currSlice->mpr_4x4[0][best_ipmode], &currSlice->mb_pred[0][block_y], &currSlice->mb_ores[0][block_y], pic_opix_x, block_x);
402 
403   currMB->ipmode_DPCM = (short) best_ipmode;
404 
405   select_transform(currMB);
406   nonzero = currMB->cr_cbp[0] = currMB->residual_transform_quant_luma_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1);
407 
408   if (currSlice->P444_joined)
409   {
410     ColorPlane k;
411     for (k = PLANE_U; k <= PLANE_V; k++)
412     {
413       select_plane(p_Vid, k);
414       /*
415       for (j=0; j<4; j++)
416       {
417         for (i=0; i<4; i++)
418         {
419           currSlice->mb_pred[k][block_y + j][block_x+i] = currSlice->mpr_4x4[k][best_ipmode][j][i];
420           currSlice->mb_ores[k][block_y + j][block_x+i] = p_Vid->pImgOrg[k][pic_opix_y+j][pic_opix_x+i] - currSlice->mpr_4x4[k][best_ipmode][j][i];
421         }
422       }
423       */
424       copy_4x4block(&currSlice->mb_pred[k][block_y], currSlice->mpr_4x4[k][best_ipmode], block_x, 0);
425       compute_residue(&(p_Vid->pImgOrg[k][pic_opix_y]), &currSlice->mb_pred[k][block_y], &currSlice->mb_ores[k][block_y], block_x, pic_opix_x, 4, 4);
426       currMB->cr_cbp[k] = currMB->residual_transform_quant_luma_4x4 (currMB, k, block_x, block_y, &dummy, 1);
427     }
428     select_plane(p_Vid, PLANE_Y);
429   }
430 
431   return nonzero;
432 }
433 
434 /*!
435 *************************************************************************************
436 * \brief
437 *    Intra 16x16 mode decision
438 *************************************************************************************
439 */
mode_decision_for_I16x16_MB_444(Macroblock * currMB,int lambda)440 int mode_decision_for_I16x16_MB_444 (Macroblock* currMB, int lambda)
441 {
442   Slice *currSlice = currMB->p_Slice;
443   int cbp;
444   find_best_mode_I16x16_MB(currMB, lambda, DISTBLK_MAX);
445 
446   if (!currSlice->P444_joined)
447   {
448     cbp = currMB->residual_transform_quant_luma_16x16 (currMB, PLANE_Y);
449   }
450   else
451   {
452     VideoParameters *p_Vid = currSlice->p_Vid;
453 
454     cbp = currMB->residual_transform_quant_luma_16x16 (currMB, PLANE_Y);
455     select_plane(p_Vid, PLANE_U);
456     currSlice->cmp_cbp[1] = currMB->residual_transform_quant_luma_16x16 (currMB, PLANE_U);
457     select_plane(p_Vid, PLANE_V);
458     currSlice->cmp_cbp[2] = currMB->residual_transform_quant_luma_16x16 (currMB, PLANE_V);
459     select_plane(p_Vid, PLANE_Y);
460 
461     cbp |= (currSlice->cmp_cbp[1] | currSlice->cmp_cbp[2]);
462     currSlice->cmp_cbp[1] = cbp;
463     currSlice->cmp_cbp[2] = cbp;
464   }
465 
466   return cbp;
467 }
468 
469