1 /*!
2  ***************************************************************************
3  * \file rd_intra_jm_low.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 "intra8x8.h"
32 
33 /*!
34  *************************************************************************************
35  * \brief
36  *    Mode Decision for an 4x4 Intra block
37  *************************************************************************************
38  */
mode_decision_for_I4x4_blocks_JM_Low(Macroblock * currMB,int b8,int b4,int lambda,distblk * min_cost)39 int mode_decision_for_I4x4_blocks_JM_Low (Macroblock *currMB, int  b8,  int  b4,  int  lambda,  distblk*  min_cost)
40 {
41   VideoParameters *p_Vid = currMB->p_Vid;
42   InputParameters *p_Inp = currMB->p_Inp;
43   Slice *currSlice = currMB->p_Slice;
44 
45   int     ipmode, best_ipmode = 0, dummy;
46   int     nonzero = 0;
47   distblk cost;
48   int  block_x     = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
49   int  block_y     = ((b8 >> 1) << 3)  + ((b4 >> 1) << 2);
50   int  pic_pix_x   = currMB->pix_x  + block_x;
51   int  pic_pix_y   = currMB->pix_y  + block_y;
52   int  pic_opix_y  = currMB->opix_y + block_y;
53 
54   int left_available, up_available, all_available;
55   int  *mb_size  = p_Vid->mb_size[IS_LUMA];
56 
57   char   upMode, leftMode;
58   int    mostProbableMode;
59 
60   PixelPos left_block, top_block;
61 
62   distblk  fixedcost = weighted_cost(lambda, 4); //(int) floor(4 * lambda );
63   distblk  onecost   = weighted_cost(lambda, 1); //(int) floor( lambda );
64 
65   int best_nz_coeff = 0;
66   int block_x4 = block_x>>2;
67   int block_y4 = block_y>>2;
68   imgpel ***mpr4x4 = currSlice->mpr_4x4[0];
69   imgpel **cur_img = &p_Vid->pCurImg[pic_opix_y];
70 
71 #ifdef BEST_NZ_COEFF
72   int best_coded_block_flag = 0;
73   int bit_pos = 1 + ((((b8>>1)<<1)+(b4>>1))<<2) + (((b8&1)<<1)+(b4&1));
74   int64 cbp_bits;
75 
76   if (b8==0 && b4==0)
77     cbp_bits = 0;
78 #endif
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   // constrained intra pred
84   if (p_Inp->UseConstrainedIntraPred)
85   {
86     left_block.available = left_block.available ? p_Vid->intra_block[left_block.mb_addr] : 0;
87     top_block.available  = top_block.available  ? p_Vid->intra_block[top_block.mb_addr]  : 0;
88   }
89 
90   upMode            =  top_block.available ? p_Vid->ipredmode[top_block.pos_y ][top_block.pos_x ] : (char) -1;
91   leftMode          = left_block.available ? p_Vid->ipredmode[left_block.pos_y][left_block.pos_x] : (char) -1;
92 
93   mostProbableMode  = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
94   *min_cost = DISTBLK_MAX;
95 
96   currMB->ipmode_DPCM = NO_INTRA_PMODE; ////For residual DPCM
97 
98   //===== INTRA PREDICTION FOR 4x4 BLOCK =====
99   // set intra prediction values for 4x4 intra prediction
100   currSlice->set_intrapred_4x4(currMB, PLANE_Y, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
101 
102   //===== LOOP OVER ALL 4x4 INTRA PREDICTION MODES =====
103   for (ipmode = 0; ipmode < NO_INTRA_PMODE; ipmode++)
104   {
105     int available_mode =  (all_available) || (ipmode==DC_PRED) ||
106       (up_available && (ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED)) ||
107       (left_available && (ipmode==HOR_PRED||ipmode==HOR_UP_PRED));
108 
109     if( valid_intra_mode(currSlice, ipmode) != 0 && available_mode)
110     {
111       // generate intra 4x4 prediction block given availability
112       get_intrapred_4x4(currMB, PLANE_Y, ipmode, block_x, block_y, left_available, up_available);
113 
114       cost  = (ipmode == mostProbableMode) ? onecost : fixedcost;
115       if (cost < *min_cost)
116       {
117         cost += currSlice->compute_cost4x4(p_Vid, cur_img, mpr4x4[ipmode], pic_pix_x, *min_cost - cost);
118 
119         if (cost < *min_cost)
120         {
121           best_ipmode = ipmode;
122           *min_cost   = cost;
123         }
124       }
125     }
126   }
127 
128 #if INTRA_RDCOSTCALC_NNZ
129   p_Vid->nz_coeff [currMB->mbAddrX][block_x4][block_y4] = best_nz_coeff;
130 #endif
131 #ifdef BEST_NZ_COEFF
132   cbp_bits &= (~(int64)(1<<bit_pos));
133   cbp_bits |= (int64)(best_coded_block_flag<<bit_pos);
134 #endif
135 
136   //===== set intra mode prediction =====
137   p_Vid->ipredmode[pic_pix_y >> 2][pic_pix_x >> 2] = (char) best_ipmode;
138   currMB->intra_pred_modes[4*b8+b4] = (char) (mostProbableMode == best_ipmode ? -1 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode - 1));
139 
140   // get prediction and prediction error
141   generate_pred_error_4x4(cur_img, mpr4x4[best_ipmode], &currSlice->mb_pred[0][block_y], &currSlice->mb_ores[0][block_y], pic_pix_x, block_x);
142 
143   currMB->ipmode_DPCM = (short) best_ipmode;
144 
145   select_transform(currMB);
146 
147   if (currMB->mb_type == I4MB)
148     nonzero = currMB->cr_cbp[0] = residual_transform_quant_luma_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1);
149   else
150     nonzero = currMB->cr_cbp[0] = currMB->residual_transform_quant_luma_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1);
151 
152   return nonzero;
153 }
154 
155 
156 /*!
157  *************************************************************************************
158  * \brief
159  *    8x8 Intra mode decision for a macroblock - Low complexity
160  *************************************************************************************
161  */
mode_decision_for_I8x8_blocks_JM_Low(Macroblock * currMB,int b8,int lambda,distblk * min_cost)162 int mode_decision_for_I8x8_blocks_JM_Low (Macroblock *currMB, int b8, int lambda, distblk *min_cost)
163 {
164   VideoParameters *p_Vid = currMB->p_Vid;
165   InputParameters *p_Inp = currMB->p_Inp;
166   Slice *currSlice = currMB->p_Slice;
167 
168   int     ipmode, best_ipmode = 0, j, dummy;
169   distblk cost;
170   int     nonzero = 0;
171   int     block_x     = (b8 & 0x01) << 3;
172   int     block_y     = (b8 >> 1) << 3;
173   int     pic_pix_x   = currMB->pix_x + block_x;
174   int     pic_pix_y   = currMB->pix_y + block_y;
175   int     pic_opix_y  = currMB->opix_y + block_y;
176   int     mb_block_y  = (currMB->block_y) + (block_y >> 2);
177   int     mb_block_x  = (currMB->block_x) + (block_x >> 2);
178 
179   int left_available, up_available, all_available;
180   int    **mb_ores = currSlice->mb_ores[0];
181   imgpel **mb_pred = currSlice->mb_pred[0];
182   int *mb_size = p_Vid->mb_size[IS_LUMA];
183 
184   char   upMode;
185   char   leftMode;
186   int    mostProbableMode;
187   int    fixedcost = (int) weighted_cost(lambda, 4);
188   int    mprobcost = (int) weighted_cost(lambda, 1);
189 
190   PixelPos left_block, top_block;
191 
192   get4x4Neighbour(currMB, block_x - 1, block_y    , mb_size, &left_block);
193   get4x4Neighbour(currMB, block_x,     block_y - 1, mb_size, &top_block );
194 
195   if (p_Inp->UseConstrainedIntraPred)
196   {
197     top_block.available  = top_block.available ? p_Vid->intra_block [top_block.mb_addr] : 0;
198     left_block.available = left_block.available ? p_Vid->intra_block [left_block.mb_addr] : 0;
199   }
200 
201   if(b8 >> 1)
202     upMode    =  top_block.available ? p_Vid->ipredmode8x8[top_block.pos_y ][top_block.pos_x ] : -1;
203   else
204     upMode    =  top_block.available ? p_Vid->ipredmode   [top_block.pos_y ][top_block.pos_x ] : -1;
205 
206   if(b8 & 0x01)
207     leftMode  = left_block.available ? p_Vid->ipredmode8x8[left_block.pos_y][left_block.pos_x] : -1;
208   else
209     leftMode  = left_block.available ? p_Vid->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
210 
211   mostProbableMode  = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
212   *min_cost = DISTBLK_MAX;
213   currMB->ipmode_DPCM = NO_INTRA_PMODE; //For residual DPCM
214 
215   //===== INTRA PREDICTION FOR 8x8 BLOCK =====
216   currSlice->set_intrapred_8x8(currMB, PLANE_Y, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
217 
218   // first check most probable mode
219   ipmode = mostProbableMode;
220   {
221     if( (ipmode==DC_PRED) ||
222       ((ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED) && up_available ) ||
223       ((ipmode==HOR_PRED||ipmode==HOR_UP_PRED) && left_available ) ||
224       (all_available) )
225     {
226       get_intrapred_8x8(currMB, PLANE_Y, ipmode, left_available, up_available);
227       cost  = mprobcost;
228       cost += currSlice->compute_cost8x8(p_Vid, &p_Vid->pImgOrg[0][pic_opix_y], currSlice->mpr_8x8[0][ipmode], pic_pix_x, *min_cost - cost);
229       best_ipmode = mostProbableMode;
230       *min_cost   = cost;
231     }
232   }
233 
234   //===== LOOP OVER ALL 8x8 INTRA PREDICTION MODES =====
235   for (ipmode = 0; ipmode < NO_INTRA_PMODE; ipmode++)
236   {
237     if (ipmode != mostProbableMode)
238     {
239       if( (ipmode==DC_PRED) ||
240         ((ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED) && up_available ) ||
241         ((ipmode==HOR_PRED||ipmode==HOR_UP_PRED) && left_available ) ||
242         (all_available) )
243       {
244         get_intrapred_8x8(currMB, PLANE_Y, ipmode, left_available, up_available);
245         cost  = fixedcost;
246 
247         if (cost < *min_cost)
248         {
249           cost += currSlice->compute_cost8x8(p_Vid, &p_Vid->pImgOrg[0][pic_opix_y], currSlice->mpr_8x8[0][ipmode], pic_pix_x, *min_cost - cost);
250           if (cost < *min_cost)
251           {
252             best_ipmode = ipmode;
253             *min_cost   = cost;
254           }
255         }
256       }
257     }
258   }
259 
260   //===== set intra mode prediction =====
261   p_Vid->ipredmode8x8[pic_pix_y >> 2][pic_pix_x >> 2] = (char) best_ipmode;
262   currMB->ipmode_DPCM = (short) best_ipmode; //For residual DPCM
263 
264   currMB->intra_pred_modes8x8[4*b8] = (char)((mostProbableMode == best_ipmode)
265     ? -1
266     : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));
267 
268   for(j = mb_block_y; j < mb_block_y + 2; j++)   //loop 4x4s in the subblock for 8x8 prediction setting
269     memset(&p_Vid->ipredmode8x8[j][mb_block_x], best_ipmode, 2 * sizeof(char));
270 
271   // get prediction and prediction error
272   generate_pred_error_8x8(&p_Vid->pCurImg[pic_opix_y], currSlice->mpr_8x8[0][best_ipmode], &mb_pred[block_y], &mb_ores[block_y], pic_pix_x, block_x);
273   currMB->ipmode_DPCM = (short) best_ipmode;
274 
275   nonzero = currMB->residual_transform_quant_luma_8x8 (currMB, PLANE_Y, b8, &dummy, 1);
276   return nonzero;
277 }
278 
279