1 /*!
2 ***************************************************************************
3 * \file rd_intra_jm.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 #include "md_common.h"
33 #include "transform8x8.h"
34 #include "md_distortion.h"
35 #include "elements.h"
36 #include "symbol.h"
37 #include "intra16x16.h"
38 #include "intra4x4.h"
39 #include "intra8x8.h"
40
41 extern int MBType2Value (Macroblock* currMB);
42
43 /*!
44 *************************************************************************************
45 * \brief
46 * Mode Decision for an 4x4 Intra block
47 *************************************************************************************
48 */
mode_decision_for_I4x4_blocks_JM_High(Macroblock * currMB,int b8,int b4,int lambda,distblk * min_cost)49 int mode_decision_for_I4x4_blocks_JM_High (Macroblock *currMB, int b8, int b4, int lambda, distblk* min_cost)
50 {
51 VideoParameters *p_Vid = currMB->p_Vid;
52 InputParameters *p_Inp = currMB->p_Inp;
53 Slice *currSlice = currMB->p_Slice;
54 RDOPTStructure *p_RDO = currSlice->p_RDO;
55
56 int ipmode, best_ipmode = 0, y;
57 int available_mode;
58 int c_nz, nonzero = 0;
59 int* ACLevel = currSlice->cofAC[b8][b4][0];
60 int* ACRun = currSlice->cofAC[b8][b4][1];
61 distblk rdcost = 0;
62 distblk min_rdcost = DISTBLK_MAX;
63 int block_x = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
64 int block_y = ((b8 >> 1) << 3) + ((b4 >> 1) << 2);
65 int pic_pix_x = currMB->pix_x + block_x;
66 int pic_pix_y = currMB->pix_y + block_y;
67 int pic_opix_x = currMB->pix_x + block_x;
68 int pic_opix_y = currMB->opix_y + block_y;
69 int pic_block_x = pic_pix_x >> 2;
70 int pic_block_y = pic_pix_y >> 2;
71
72 int left_available, up_available, all_available;
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 int lrec4x4[4][4];
81 int best_nz_coeff = 0;
82 int block_x4 = block_x>>2;
83 int block_y4 = block_y>>2;
84
85 #ifdef BEST_NZ_COEFF
86 int best_coded_block_flag = 0;
87 int bit_pos = 1 + ((((b8>>1)<<1)+(b4>>1))<<2) + (((b8&1)<<1)+(b4&1));
88 int64 cbp_bits;
89
90 if (b8==0 && b4==0)
91 cbp_bits = 0;
92 #endif
93
94 get4x4Neighbour(currMB, block_x - 1, block_y , mb_size, &left_block);
95 get4x4Neighbour(currMB, block_x, block_y - 1, mb_size, &top_block );
96
97 // constrained intra pred
98 if (p_Inp->UseConstrainedIntraPred)
99 {
100 left_block.available = left_block.available ? p_Vid->intra_block[left_block.mb_addr] : 0;
101 top_block.available = top_block.available ? p_Vid->intra_block[top_block.mb_addr] : 0;
102 }
103
104 upMode = top_block.available ? p_Vid->ipredmode[top_block.pos_y ][top_block.pos_x ] : (char) -1;
105 leftMode = left_block.available ? p_Vid->ipredmode[left_block.pos_y][left_block.pos_x] : (char) -1;
106
107 mostProbableMode = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
108 *min_cost = DISTBLK_MAX;
109
110 currMB->ipmode_DPCM = NO_INTRA_PMODE; ////For residual DPCM
111
112 //===== INTRA PREDICTION FOR 4x4 BLOCK =====
113 // set intra prediction values for 4x4 intra prediction
114 currSlice->set_intrapred_4x4(currMB, PLANE_Y, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
115
116 //===== LOOP OVER ALL 4x4 INTRA PREDICTION MODES =====
117 for (ipmode = 0; ipmode < NO_INTRA_PMODE; ipmode++)
118 {
119 available_mode = (all_available) || (ipmode==DC_PRED) ||
120 (up_available && (ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED)) ||
121 (left_available && (ipmode==HOR_PRED||ipmode==HOR_UP_PRED));
122
123 if (valid_intra_mode(currSlice, ipmode) == 0)
124 continue;
125
126 if( available_mode)
127 {
128 // generate intra 4x4 prediction block given availability
129 get_intrapred_4x4(currMB, PLANE_Y, ipmode, block_x, block_y, left_available, up_available);
130
131 // get prediction and prediction error
132 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);
133
134 // get and check rate-distortion cost
135 #ifdef BEST_NZ_COEFF
136 currMB->cbp_bits[0] = cbp_bits;
137 #endif
138
139 rdcost = currSlice->rdcost_for_4x4_intra_blocks (currMB, &c_nz, b8, b4, ipmode, lambda, mostProbableMode, min_rdcost);
140 if ((rdcost < min_rdcost) || (rdcost == min_rdcost && ipmode == mostProbableMode))
141 {
142 //--- set coefficients ---
143 memcpy(p_RDO->cofAC4x4[0], ACLevel, 18 * sizeof(int));
144 memcpy(p_RDO->cofAC4x4[1], ACRun, 18 * sizeof(int));
145
146 //--- set reconstruction ---
147 copy_4x4block(p_RDO->rec4x4[PLANE_Y], &p_Vid->enc_picture->imgY[pic_pix_y], 0, pic_pix_x);
148
149 // SP/SI reconstruction
150 if(currSlice->slice_type == SP_SLICE && !currSlice->sp2_frame_indicator)
151 {
152 for (y=0; y<4; y++)
153 {
154 memcpy(lrec4x4[y],&p_Vid->lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));// stores the mode coefficients
155 }
156 }
157
158 //--- flag if transform-coefficients must be coded ---
159 nonzero = c_nz;
160
161 //--- set best mode update minimum cost ---
162 *min_cost = rdcost;
163 min_rdcost = rdcost;
164 best_ipmode = ipmode;
165
166 best_nz_coeff = p_Vid->nz_coeff [currMB->mbAddrX][block_x4][block_y4];
167 #ifdef BEST_NZ_COEFF
168 best_coded_block_flag = (int)((currMB->cbp_bits[0] >> bit_pos)&(int64)(1));
169 #endif
170 if (p_Vid->AdaptiveRounding)
171 {
172 store_adaptive_rounding_4x4 (p_Vid, p_Vid->ARCofAdj4x4, I4MB, block_y, block_x);
173 }
174 }
175 }
176 }
177 #if INTRA_RDCOSTCALC_NNZ
178 p_Vid->nz_coeff [currMB->mbAddrX][block_x4][block_y4] = best_nz_coeff;
179 #endif
180 #ifdef BEST_NZ_COEFF
181 cbp_bits &= (~(int64)(1<<bit_pos));
182 cbp_bits |= (int64)(best_coded_block_flag<<bit_pos);
183 #endif
184
185 //===== set intra mode prediction =====
186 p_Vid->ipredmode[pic_block_y][pic_block_x] = (char) best_ipmode;
187 currMB->intra_pred_modes[4*b8+b4] =
188 (char) (mostProbableMode == best_ipmode ? -1 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));
189
190 //===== restore coefficients =====
191 memcpy (ACLevel, p_RDO->cofAC4x4[0], 18 * sizeof(int));
192 memcpy (ACRun, p_RDO->cofAC4x4[1], 18 * sizeof(int));
193
194 //===== restore reconstruction and prediction (needed if single coeffs are removed) =====
195 copy_4x4block(&p_Vid->enc_picture->imgY[pic_pix_y], p_RDO->rec4x4[PLANE_Y], pic_pix_x, 0);
196 copy_4x4block(&currSlice->mb_pred[0][block_y], currSlice->mpr_4x4[0][best_ipmode], block_x, 0);
197
198 // SP/SI reconstuction
199 if(currSlice->slice_type == SP_SLICE && !currSlice->sp2_frame_indicator)
200 {
201 for (y=0; y<BLOCK_SIZE; y++)
202 {
203 memcpy (&p_Vid->lrec[pic_pix_y+y][pic_pix_x], lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame
204 }
205 }
206
207 if (p_Vid->AdaptiveRounding)
208 {
209 update_adaptive_rounding_4x4 (p_Vid,p_Vid->ARCofAdj4x4, I4MB, block_y, block_x);
210 }
211
212 return nonzero;
213 }
214
215 /*!
216 *************************************************************************************
217 * \brief
218 * 8x8 Intra mode decision for a macroblock - High complexity
219 *************************************************************************************
220 */
mode_decision_for_I8x8_blocks_JM_High(Macroblock * currMB,int b8,int lambda,distblk * min_cost)221 int mode_decision_for_I8x8_blocks_JM_High (Macroblock *currMB, int b8, int lambda, distblk *min_cost)
222 {
223 VideoParameters *p_Vid = currMB->p_Vid;
224 InputParameters *p_Inp = currMB->p_Inp;
225 Slice *currSlice = currMB->p_Slice;
226 RDOPTStructure *p_RDO = currSlice->p_RDO;
227
228 int ipmode, best_ipmode = 0, j;
229 int c_nz, nonzero = 0;
230 distblk rdcost = 0;
231 distblk min_rdcost = DISTBLK_MAX;
232 int block_x = (b8 & 0x01) << 3;
233 int block_y = (b8 >> 1) << 3;
234 int pic_pix_x = currMB->pix_x + block_x;
235 int pic_pix_y = currMB->pix_y + block_y;
236 int pic_opix_x = currMB->pix_x + block_x;
237 int pic_opix_y = currMB->opix_y + block_y;
238 int pic_block_x = pic_pix_x >> 2;
239 int pic_block_y = pic_pix_y >> 2;
240 int mb_block_y = (currMB->block_y) + ((b8 >> 1) << 1);
241 int mb_block_x = (currMB->block_x) + ((b8 & 0x01) << 1);
242 int *p_AC8x8 = p_RDO->coefAC8x8intra[b8][0][0][0];
243 int *cofAC = currSlice->cofAC[b8][0][0];
244
245 int left_available, up_available, all_available;
246 int **mb_ores = currSlice->mb_ores[0];
247 imgpel **mb_pred = currSlice->mb_pred[0];
248
249 char upMode, leftMode;
250 int mostProbableMode;
251
252 PixelPos left_block, top_block;
253
254 int *mb_size = p_Vid->mb_size[IS_LUMA];
255
256 get4x4Neighbour(currMB, block_x - 1, block_y , mb_size, &left_block);
257 get4x4Neighbour(currMB, block_x, block_y - 1, mb_size, &top_block );
258
259 // constrained intra pred
260 if (p_Inp->UseConstrainedIntraPred)
261 {
262 left_block.available = left_block.available ? p_Vid->intra_block [left_block.mb_addr] : 0;
263 top_block.available = top_block.available ? p_Vid->intra_block [top_block.mb_addr ] : 0;
264 }
265
266 if(b8 >> 1)
267 upMode = top_block.available ? p_Vid->ipredmode8x8[top_block.pos_y ][top_block.pos_x ] : (char) -1;
268 else
269 upMode = top_block.available ? p_Vid->ipredmode [top_block.pos_y ][top_block.pos_x ] : (char) -1;
270
271 if(b8 & 0x01)
272 leftMode = left_block.available ? p_Vid->ipredmode8x8[left_block.pos_y][left_block.pos_x] : (char) -1;
273 else
274 leftMode = left_block.available ? p_Vid->ipredmode[left_block.pos_y][left_block.pos_x] : (char) -1;
275
276 mostProbableMode = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
277 *min_cost = DISTBLK_MAX;
278 currMB->ipmode_DPCM = NO_INTRA_PMODE; //For residual DPCM
279
280 //===== INTRA PREDICTION FOR 8x8 BLOCK =====
281 currSlice->set_intrapred_8x8(currMB, PLANE_Y, pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
282
283 //===== LOOP OVER ALL 8x8 INTRA PREDICTION MODES =====
284 for (ipmode = 0; ipmode < NO_INTRA_PMODE; ipmode++)
285 {
286 if( (ipmode==DC_PRED) ||
287 ((ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED) && up_available ) ||
288 ((ipmode==HOR_PRED||ipmode==HOR_UP_PRED) && left_available ) ||
289 (all_available) )
290 {
291 get_intrapred_8x8(currMB, PLANE_Y, ipmode, left_available, up_available);
292 // get prediction and prediction error
293 generate_pred_error_8x8(&p_Vid->pCurImg[pic_opix_y], currSlice->mpr_8x8[0][ipmode], &mb_pred[block_y], &mb_ores[block_y], pic_opix_x, block_x);
294
295 currMB->ipmode_DPCM = (short) ipmode;
296
297 // get and check rate-distortion cost
298
299 rdcost = currSlice->rdcost_for_8x8_intra_blocks (currMB, &c_nz, b8, ipmode, lambda, min_rdcost, mostProbableMode);
300 if ((rdcost < min_rdcost) || (rdcost == min_rdcost && ipmode == mostProbableMode))
301 {
302 //--- set coefficients ---
303 memcpy(p_AC8x8, cofAC, 4 * 2 * 65 * sizeof(int));
304
305 //--- set reconstruction ---
306 copy_image_data_8x8(p_RDO->rec8x8[PLANE_Y], &p_Vid->enc_picture->imgY[pic_pix_y], 0, pic_pix_x);
307
308 if (p_Vid->AdaptiveRounding)
309 {
310 for (j = block_y; j < block_y + 8; j++)
311 memcpy(&p_Vid->ARCofAdj8x8[0][DUMMY][j][block_x],&p_Vid->ARCofAdj8x8[0][I8MB][j][block_x], 8 * sizeof(int));
312 }
313
314 //--- flag if transform coefficients must be coded ---
315 nonzero = c_nz;
316
317 //--- set best mode update minimum cost ---
318 *min_cost = rdcost;
319 min_rdcost = rdcost;
320 best_ipmode = ipmode;
321 }
322 }
323 }
324
325 //===== set intra mode prediction =====
326 p_Vid->ipredmode8x8[pic_block_y][pic_block_x] = (char) best_ipmode;
327 currMB->ipmode_DPCM = (short) best_ipmode; //For residual DPCM
328
329 currMB->intra_pred_modes8x8[4*b8] = (char) ((mostProbableMode == best_ipmode)
330 ? -1
331 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode - 1));
332
333 memset(&p_Vid->ipredmode8x8[mb_block_y ][mb_block_x], best_ipmode, 2 * sizeof(char));
334 memset(&p_Vid->ipredmode8x8[mb_block_y + 1][mb_block_x], best_ipmode, 2 * sizeof(char));
335
336 //===== restore coefficients =====
337 memcpy(cofAC, p_AC8x8, 4 * 2 * 65 * sizeof(int));
338
339 if (p_Vid->AdaptiveRounding)
340 {
341 for (j=block_y; j< block_y + 8; j++)
342 memcpy(&p_Vid->ARCofAdj8x8[0][I8MB][j][block_x], &p_Vid->ARCofAdj8x8[0][DUMMY][j][block_x], 8 * sizeof(int));
343 }
344
345 //===== restore reconstruction and prediction (needed if single coeffs are removed) =====
346 copy_image_data_8x8(&p_Vid->enc_picture->imgY[pic_pix_y], p_RDO->rec8x8[0], pic_pix_x, 0);
347 copy_image_data_8x8(&mb_pred[block_y], currSlice->mpr_8x8[0][best_ipmode], block_x, 0);
348
349 return nonzero;
350 }
351
352 /*!
353 *************************************************************************************
354 * \brief
355 * Mode Decision for an 8x8 Intra block
356 *************************************************************************************
357 */
Mode_Decision_for_IntraSubMBlocks(Macroblock * currMB,int b8,int lambda,distblk * cost,int non_zero[3])358 int Mode_Decision_for_IntraSubMBlocks(Macroblock *currMB, int b8, int lambda, distblk *cost, int non_zero[3])
359 {
360 Slice *currSlice = currMB->p_Slice;
361 int b4;
362 distblk cost4x4;
363 currMB->cr_cbp[0] = 0;
364 currMB->cr_cbp[1] = 0;
365 currMB->cr_cbp[2] = 0;
366
367 memset(non_zero, 0, 3 * sizeof(int));
368 *cost = weighted_cost(lambda, 6); //6 * lambda;
369 for (b4=0; b4<4; b4++)
370 {
371 non_zero[0] |= currSlice->mode_decision_for_I4x4_blocks (currMB, b8, b4, lambda, &cost4x4);
372 non_zero[1] |= currMB->cr_cbp[1];
373 non_zero[2] |= currMB->cr_cbp[2];
374 *cost += cost4x4;
375 }
376
377 return non_zero[0];
378 }
379
380 /*!
381 *************************************************************************************
382 * \brief
383 * 4x4 Intra mode decision for an macroblock
384 *************************************************************************************
385 */
mode_decision_for_I4x4_MB(Macroblock * currMB,int lambda,distblk * cost)386 int mode_decision_for_I4x4_MB (Macroblock *currMB, int lambda, distblk* cost)
387 {
388 Slice *currSlice = currMB->p_Slice;
389 int cbp=0, b8;
390 distblk cost8x8;
391 int non_zero[3] = {0, 0, 0};
392
393 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
394
395 for (*cost=0, b8=0; b8<4; b8++)
396 {
397 if (Mode_Decision_for_IntraSubMBlocks (currMB, b8, lambda, &cost8x8, non_zero))
398 {
399 cbp |= (1<<b8);
400 }
401 *cost += cost8x8;
402 if (non_zero[1])
403 {
404 currSlice->cmp_cbp[1] |= (1<<b8);
405 cbp |= currSlice->cmp_cbp[1];
406 currSlice->cmp_cbp[1] = cbp;
407 currSlice->cmp_cbp[2] = cbp;
408 }
409 if (non_zero[2])
410 {
411 currSlice->cmp_cbp[2] |= (1<<b8);
412 cbp |= currSlice->cmp_cbp[2];
413 currSlice->cmp_cbp[1] = cbp;
414 currSlice->cmp_cbp[2] = cbp;
415 }
416 }
417 return cbp;
418 }
419
find_best_mode_I16x16_MB(Macroblock * currMB,int lambda,distblk min_cost)420 int find_best_mode_I16x16_MB (Macroblock *currMB, int lambda, distblk min_cost)
421 {
422 Slice *currSlice = currMB->p_Slice;
423 currMB->luma_transform_size_8x8_flag = FALSE;
424 return (int) currSlice->find_sad_16x16 (currMB);
425 }
426
427 /*!
428 *************************************************************************************
429 * \brief
430 * Intra 16x16 mode decision
431 *************************************************************************************
432 */
mode_decision_for_I16x16_MB(Macroblock * currMB,int lambda)433 int mode_decision_for_I16x16_MB (Macroblock* currMB, int lambda)
434 {
435 find_best_mode_I16x16_MB (currMB, lambda, DISTBLK_MAX);
436 return currMB->residual_transform_quant_luma_16x16 (currMB, PLANE_Y);
437 }
438
439
440 /************************************************************************************
441 * \brief
442 * Intra 16x16 mode decision using Rate-Distortion Optimization
443 *************************************************************************************
444 */
mode_decision_for_I16x16_MB_RDO(Macroblock * currMB,int lambda)445 int mode_decision_for_I16x16_MB_RDO (Macroblock* currMB, int lambda)
446 {
447 VideoParameters *p_Vid = currMB->p_Vid;
448 InputParameters *p_Inp = currMB->p_Inp;
449 Slice *currSlice = currMB->p_Slice;
450
451 SyntaxElement se;
452 const int* partMap = assignSE2partition[currSlice->partition_mode];
453 DataPartition* dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
454
455 distblk min_rdcost = DISTBLK_MAX, rdcost;
456 distblk distortionY;
457 int rate;
458 int i,k;
459 int b8, b4;
460
461
462 int up_avail, left_avail, left_up_avail;
463
464 int best_mode = 0, best_cbp = 0;
465 int bestCofAC[4][4][2][65];
466 int bestCofDC[2][18];
467 imgpel bestRec[MB_BLOCK_SIZE][MB_BLOCK_SIZE];
468
469 currMB->mb_type = I16MB;
470
471 currSlice->set_intrapred_16x16(currMB, PLANE_Y, &left_avail, &up_avail, &left_up_avail);
472
473 for (k = 0;k < 4; k++)
474 {
475 if (p_Inp->IntraDisableInterOnly == 0 || (currSlice->slice_type != I_SLICE && currSlice->slice_type != SI_SLICE))
476 {
477 if (p_Inp->Intra16x16ParDisable && (k==VERT_PRED_16||k==HOR_PRED_16))
478 continue;
479
480 if (p_Inp->Intra16x16PlaneDisable && k==PLANE_16)
481 continue;
482 }
483
484 if ((k==0 && !up_avail) || (k==1 && !left_avail) || (k==3 && (!left_avail || !up_avail || !left_up_avail)))
485 continue;
486
487 get_intrapred_16x16(currMB, PLANE_Y, k, left_avail, up_avail);
488
489 currMB->i16mode = (char) k;
490 currMB->cbp = currMB->residual_transform_quant_luma_16x16(currMB, PLANE_Y);
491 distortionY = compute_SSE16x16_thres(&p_Vid->pCurImg[currMB->opix_y], &p_Vid->enc_picture->p_curr_img[currMB->pix_y], currMB->pix_x, currMB->pix_x, min_rdcost);
492
493 if (distortionY < min_rdcost - weighted_cost(lambda, 4))
494 {
495 currSlice->store_coding_state (currMB, currSlice->p_RDO->cs_tmp);
496 currMB->i16offset = I16Offset (currMB->cbp, currMB->i16mode);
497 se.value1 = MBType2Value (currMB);
498 se.value2 = 0;
499 se.type = SE_MBTYPE;
500
501 currSlice->writeMB_typeInfo (currMB, &se, dataPart);
502
503 rate = se.len;
504 if (distortionY + weighted_cost(lambda, rate) < min_rdcost)
505 {
506 rate += currSlice->writeCoeff16x16 (currMB, PLANE_Y);
507 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_tmp);
508
509 rdcost = distortionY + weighted_cost(lambda, rate);
510
511 if(rdcost < min_rdcost)
512 {
513 min_rdcost = rdcost;
514 best_mode = k;
515 best_cbp = currMB->cbp;
516 for(b8 = 0; b8 < 4; b8++)
517 {
518 for(b4 = 0; b4 < 4; b4++)
519 {
520 memcpy(bestCofAC[b8][b4][0], currSlice->cofAC[b8][b4][0], sizeof(int) * 65);
521 memcpy(bestCofAC[b8][b4][1], currSlice->cofAC[b8][b4][1], sizeof(int) * 65);
522 }
523 }
524
525 memcpy(bestCofDC[0], currSlice->cofDC[0][0], sizeof(int)*18);
526 memcpy(bestCofDC[1], currSlice->cofDC[0][1], sizeof(int)*18);
527
528 for(i = 0; i < MB_BLOCK_SIZE; i++)
529 memcpy(bestRec[i], &p_Vid->enc_picture->p_curr_img[currMB->pix_y + i][currMB->pix_x], sizeof(imgpel)*MB_BLOCK_SIZE);
530 }
531 }
532 else
533 {
534 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_tmp);
535 }
536 }
537 }
538
539 currMB->i16mode = (char) best_mode;
540 currMB->cbp = best_cbp;
541 currMB->i16offset = I16Offset (currMB->cbp, currMB->i16mode);
542
543 for(b8 = 0; b8 < 4; b8++)
544 {
545 for(b4 = 0; b4 < 4; b4++)
546 {
547 memcpy(currSlice->cofAC[b8][b4][0], bestCofAC[b8][b4][0], sizeof(int)*65);
548 memcpy(currSlice->cofAC[b8][b4][1], bestCofAC[b8][b4][1], sizeof(int)*65);
549 }
550 }
551
552 memcpy(currSlice->cofDC[0][0], bestCofDC[0], sizeof(int)*18);
553 memcpy(currSlice->cofDC[0][1], bestCofDC[1], sizeof(int)*18);
554
555 for(i = 0; i < MB_BLOCK_SIZE; i++)
556 {
557 memcpy(&p_Vid->enc_picture->p_curr_img[currMB->pix_y+i][currMB->pix_x], bestRec[i], MB_BLOCK_SIZE*sizeof(imgpel));
558 }
559
560 return currMB->cbp;
561 }
562
563
564