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