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