1 /*!
2 ***************************************************************************
3 * \file rdopt.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 <math.h>
19 #include <limits.h>
20
21 #include "global.h"
22
23 #include "rdopt.h"
24 #include "q_around.h"
25 #include "rdopt_coding_state.h"
26 #include "memalloc.h"
27 #include "mb_access.h"
28 #include "elements.h"
29 #include "intrarefresh.h"
30 #include "image.h"
31 #include "transform8x8.h"
32 #include "cabac.h"
33 #include "biariencode.h"
34 #include "slice.h"
35 #include "vlc.h"
36 #include "ratectl.h" // head file for rate control
37 #include "mode_decision.h"
38 #include "rd_intra_jm.h"
39 #include "rd_intra_jm444.h"
40 #include "macroblock.h"
41 #include "q_offsets.h"
42 #include "conformance.h"
43 #include "errdo.h"
44 #include "mv_search.h"
45 #include "md_common.h"
46 #include "md_distortion.h"
47 #include "intra16x16.h"
48
49 #define FASTMODE 1
50
51 static void set_stored_macroblock_parameters (Macroblock *currMB);
52 static void set_stored_macroblock_parameters_sp (Macroblock *currMB);
53 static void set_stored_macroblock_parameters_mpass(Macroblock *currMB);
54 static void set_ref_and_motion_vectors_P_slice (Macroblock *currMB, PicMotionParams **motion, Info8x8 *pred, int);
55 static void set_ref_and_motion_vectors_B_slice (Macroblock *currMB, PicMotionParams **motion, Info8x8 *pred, int);
56
57 static distblk compute_sad4x4_cost (VideoParameters *p_Vid, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, distblk min_cost);
58 static distblk compute_sse4x4_cost (VideoParameters *p_Vid, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, distblk min_cost);
59 static distblk compute_satd4x4_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, distblk min_cost);
60 static distblk compute_comp4x4_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, distblk min_cost);
61
62 static distblk rdcost_for_4x4_intra_blocks (Macroblock *currMB, int* nonzero, int b8, int b4, int ipmode, int lambda, int mostProbableMode, distblk min_rdcost);
63 static distblk rdcost_for_4x4_intra_blocks_444 (Macroblock *currMB, int* nonzero, int b8, int b4, int ipmode, int lambda, int mostProbableMode, distblk min_rdcost);
64
copy_motion_vectors_MB(Slice * currSlice,RD_DATA * rdopt)65 static inline void copy_motion_vectors_MB (Slice *currSlice, RD_DATA *rdopt)
66 {
67 memcpy(&currSlice->all_mv [LIST_0][0][0][0][0], &rdopt->all_mv [LIST_0][0][0][0][0], 288 * currSlice->max_num_references * sizeof(MotionVector));
68 }
69
init_info_8x8_struct(void)70 Info8x8 init_info_8x8_struct(void)
71 {
72 Info8x8 i8x8;
73 i8x8.mode = 0;
74 i8x8.pdir = 0;
75 i8x8.ref[LIST_0] = 0;
76 i8x8.ref[LIST_1] = -1;
77 i8x8.bipred = 0;
78
79 return i8x8;
80 }
81
alloc_rd8x8data(RD_8x8DATA * rd_data)82 void alloc_rd8x8data (RD_8x8DATA *rd_data)
83 {
84 get_mem2Dint(&rd_data->lrec, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
85 get_mem2Dpel(&rd_data->mpr8x8, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
86 get_mem3Dpel(&rd_data->mpr8x8CbCr, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
87 get_mem2Dpel(&rd_data->rec_mbY8x8, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
88 get_mem3Dpel(&rd_data->rec_mb8x8_cr, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
89 }
90
free_rd8x8data(RD_8x8DATA * rd_data)91 void free_rd8x8data (RD_8x8DATA *rd_data)
92 {
93 free_mem3Dpel(rd_data->rec_mb8x8_cr);
94 free_mem2Dpel(rd_data->rec_mbY8x8);
95 free_mem3Dpel(rd_data->mpr8x8CbCr);
96 free_mem2Dpel(rd_data->mpr8x8);
97 free_mem2Dint(rd_data->lrec);
98 }
99
100 /*!
101 ************************************************************************
102 * \brief
103 * delete structure for RD-optimized mode decision
104 ************************************************************************
105 */
clear_rdopt(Slice * currSlice)106 void clear_rdopt (Slice *currSlice)
107 {
108 VideoParameters *p_Vid = currSlice->p_Vid;
109 InputParameters *p_Inp = currSlice->p_Inp;
110 RDOPTStructure *p_RDO = currSlice->p_RDO;
111
112 free_mem_DCcoeff (p_RDO->cofDC);
113 free_mem_ACcoeff (p_RDO->cofAC);
114 free_mem_ACcoeff (p_RDO->cofAC4x4intern);
115 free_mem_ACcoeff_new(p_RDO->coefAC8x8);
116 free_mem_ACcoeff_new(p_RDO->coefAC8x8intra);
117
118 if (p_Inp->Transform8x8Mode)
119 {
120 free_mem_ACcoeff_new(p_RDO->cofAC8x8ts);
121 }
122
123 if (p_Vid->P444_joined)
124 {
125 free_mem_ACcoeff_new(p_RDO->cofAC4x4CbCrintern);
126 }
127
128 // Should create new functions for free/alloc of RD_8x8DATA
129 free_rd8x8data(p_RDO->tr4x4);
130 free(p_RDO->tr4x4);
131 free_rd8x8data(p_RDO->tr8x8);
132 free(p_RDO->tr8x8);
133
134 free_mem4Dmv(p_RDO->all_mv8x8);
135
136 free_mem3Dpel(p_RDO->rec4x4);
137 free_mem3Dpel(p_RDO->rec8x8);
138 free_mem2Dpel(p_RDO->pred);
139 free_mem3Dpel(p_RDO->rec_mb);
140
141 if (p_Inp->ProfileIDC == EXTENDED)
142 {
143 free_mem2Dint(p_RDO->lrec_rec);
144 free_mem3Dint(p_RDO->lrec_rec_uv);
145 }
146
147 free_mem2D((byte **) p_RDO->l0_refframe);
148 free_mem2D((byte **) p_RDO->l1_refframe);
149
150 // structure for saving the coding state
151 delete_coding_state (p_RDO->cs_mb);
152 delete_coding_state (p_RDO->cs_b8);
153 delete_coding_state (p_RDO->cs_cm);
154 delete_coding_state (p_RDO->cs_tmp);
155 }
156
setupDistCost(Slice * currSlice,InputParameters * p_Inp)157 void setupDistCost(Slice *currSlice, InputParameters *p_Inp)
158 {
159 switch(p_Inp->ModeDecisionMetric)
160 {
161 case ERROR_SAD:
162 currSlice->compute_cost4x4 = compute_sad4x4_cost;
163 currSlice->compute_cost8x8 = compute_sad8x8_cost;
164 currSlice->distI16x16 = distI16x16_sad;
165 break;
166 case ERROR_SSE:
167 currSlice->compute_cost4x4 = compute_sse4x4_cost;
168 currSlice->compute_cost8x8 = compute_sse8x8_cost;
169 currSlice->distI16x16 = distI16x16_sse;
170 break;
171 case ERROR_SATD:
172 currSlice->compute_cost4x4 = compute_satd4x4_cost;
173 currSlice->compute_cost8x8 = compute_satd8x8_cost;
174 currSlice->distI16x16 = distI16x16_satd;
175 break;
176 default:
177 currSlice->compute_cost4x4 = compute_comp4x4_cost;
178 currSlice->compute_cost8x8 = compute_comp8x8_cost;
179 currSlice->distI16x16 = distI16x16_satd;
180 break;
181 }
182 }
183
184
185 /*!
186 ************************************************************************
187 * \brief
188 * create structure for RD-optimized mode decision
189 ************************************************************************
190 */
init_rdopt(Slice * currSlice)191 void init_rdopt (Slice *currSlice)
192 {
193 VideoParameters *p_Vid = currSlice->p_Vid;
194 InputParameters *p_Inp = currSlice->p_Inp;
195 RDOPTStructure *p_RDO = currSlice->p_RDO;
196
197 get_mem_DCcoeff (&p_RDO->cofDC);
198 get_mem_ACcoeff (p_Vid, &p_RDO->cofAC);
199 get_mem_ACcoeff (p_Vid, &p_RDO->cofAC4x4intern);
200 p_RDO->cofAC4x4 = p_RDO->cofAC4x4intern[0][0];
201 get_mem_ACcoeff_new(&p_RDO->coefAC8x8, 3);
202 get_mem_ACcoeff_new(&p_RDO->coefAC8x8intra, 3);
203
204 if (p_Inp->Transform8x8Mode)
205 {
206 get_mem_ACcoeff_new(&p_RDO->cofAC8x8ts, 3);
207 }
208
209 if (((p_RDO->tr4x4) = (RD_8x8DATA *) calloc(1, sizeof(RD_8x8DATA)))==NULL)
210 no_mem_exit("init_rdopt: p_RDO->tr4x4");
211 alloc_rd8x8data(p_RDO->tr4x4);
212 if (((p_RDO->tr8x8) = (RD_8x8DATA *) calloc(1, sizeof(RD_8x8DATA)))==NULL)
213 no_mem_exit("init_rdopt: p_RDO->tr4x4");
214 alloc_rd8x8data(p_RDO->tr8x8);
215
216 get_mem2Dpel(&p_RDO->pred, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
217 get_mem3Dpel(&p_RDO->rec8x8, 3, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8);
218 get_mem3Dpel(&p_RDO->rec4x4, 3, BLOCK_SIZE, BLOCK_SIZE);
219 get_mem3Dpel(&p_RDO->rec_mb, 3, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
220
221 if (p_Inp->ProfileIDC == EXTENDED)
222 {
223 get_mem2Dint(&p_RDO->lrec_rec, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
224 get_mem3Dint(&p_RDO->lrec_rec_uv, 2, MB_BLOCK_SIZE, MB_BLOCK_SIZE);
225 }
226
227 get_mem2D((byte ***) &p_RDO->l0_refframe, 4, 4);
228 get_mem2D((byte ***) &p_RDO->l1_refframe, 4, 4);
229
230 get_mem4Dmv(&p_RDO->all_mv8x8, 2, 2, 4, 4);
231
232 if (p_Vid->P444_joined)
233 {
234 get_mem_ACcoeff_new(&p_RDO->cofAC4x4CbCrintern, 2);
235
236 p_RDO->cofAC4x4CbCr[0] = p_RDO->cofAC4x4CbCrintern[0][0][0];
237 p_RDO->cofAC4x4CbCr[1] = p_RDO->cofAC4x4CbCrintern[0][1][0];
238 }
239
240 currSlice->set_lagrangian_multipliers = p_Inp->rdopt == 0 ? SetLagrangianMultipliersOff : SetLagrangianMultipliersOn;
241
242 switch (p_Inp->rdopt)
243 {
244 case 0:
245 currSlice->encode_one_macroblock = encode_one_macroblock_low;
246 break;
247 case 1:
248 default:
249 currSlice->encode_one_macroblock = encode_one_macroblock_high;
250 break;
251 case 2:
252 currSlice->encode_one_macroblock = encode_one_macroblock_highfast;
253 break;
254 case 3:
255 currSlice->encode_one_macroblock = encode_one_macroblock_highloss;
256 break;
257 case 4:
258 currSlice->encode_one_macroblock = encode_one_macroblock_high_updated;
259 break;
260 }
261
262 if (currSlice->mb_aff_frame_flag || (currSlice->UseRDOQuant && currSlice->RDOQ_QP_Num > 1))
263 currSlice->set_stored_mb_parameters = set_stored_macroblock_parameters_mpass;
264 else
265 {
266 if (currSlice->slice_type == SP_SLICE || currSlice->slice_type == SI_SLICE)
267 currSlice->set_stored_mb_parameters = set_stored_macroblock_parameters_sp;
268 else
269 currSlice->set_stored_mb_parameters = set_stored_macroblock_parameters;
270 }
271
272 // structure for saving the coding state
273 p_RDO->cs_mb = create_coding_state (p_Inp);
274 p_RDO->cs_b8 = create_coding_state (p_Inp);
275 p_RDO->cs_cm = create_coding_state (p_Inp);
276 p_RDO->cs_tmp = create_coding_state (p_Inp);
277 if (p_Inp->CtxAdptLagrangeMult == 1)
278 {
279 p_Vid->mb16x16_cost = CALM_MF_FACTOR_THRESHOLD;
280 p_RDO->lambda_mf_factor = 1.0;
281 }
282
283 currSlice->rdcost_for_4x4_intra_blocks = (p_Vid->yuv_format == YUV444) ? rdcost_for_4x4_intra_blocks_444 : rdcost_for_4x4_intra_blocks;
284 currSlice->rdcost_for_8x8_intra_blocks = (p_Vid->yuv_format == YUV444) ? rdcost_for_8x8_intra_blocks_444 : rdcost_for_8x8_intra_blocks;
285
286 if (currSlice->mb_aff_frame_flag)
287 currSlice->intra_chroma_RD_decision = intra_chroma_RD_decision_mbaff;
288 else
289 currSlice->intra_chroma_RD_decision = intra_chroma_RD_decision;
290 if (p_Inp->rdopt == 0)
291 {
292 currSlice->mode_decision_for_I8x8_blocks = (p_Vid->yuv_format == YUV444) ? mode_decision_for_I8x8_blocks_JM_Low444 : mode_decision_for_I8x8_blocks_JM_Low;
293 currSlice->mode_decision_for_I4x4_blocks = (p_Vid->yuv_format == YUV444) ? mode_decision_for_I4x4_blocks_JM_Low444 : mode_decision_for_I4x4_blocks_JM_Low;
294 }
295 else
296 {
297 currSlice->mode_decision_for_I8x8_blocks = (p_Vid->yuv_format == YUV444) ? mode_decision_for_I8x8_blocks_JM_High444 : mode_decision_for_I8x8_blocks_JM_High;
298 currSlice->mode_decision_for_I4x4_blocks = (p_Vid->yuv_format == YUV444) ? mode_decision_for_I4x4_blocks_JM_High444 : mode_decision_for_I4x4_blocks_JM_High;
299 }
300
301 currSlice->find_sad_16x16 = find_sad_16x16_JM;
302
303 if (currSlice->slice_type == B_SLICE)
304 currSlice->set_ref_and_motion_vectors = set_ref_and_motion_vectors_B_slice;
305 else
306 currSlice->set_ref_and_motion_vectors = set_ref_and_motion_vectors_P_slice;
307
308 setupDistortion(currSlice);
309 setupDistCost (currSlice, p_Inp);
310 }
311
312 /*!
313 *************************************************************************************
314 * \brief
315 * Updates the pixel map that shows, which reference frames are reliable for
316 * each MB-area of the picture.
317 *
318 * \note
319 * The new values of the p_Vid->pixel_map are taken from the temporary buffer p_Vid->refresh_map
320 *
321 *************************************************************************************
322 */
UpdatePixelMap(VideoParameters * p_Vid,InputParameters * p_Inp)323 void UpdatePixelMap(VideoParameters *p_Vid, InputParameters *p_Inp)
324 {
325 int mx,my,y,x,i,j;
326 if (p_Vid->type==I_SLICE)
327 {
328 memset(p_Vid->pixel_map, 1, p_Vid->height * p_Vid->width * sizeof(byte));
329 }
330 else
331 {
332 for (my=0; my<p_Vid->height >> 3; my++)
333 {
334 for (mx=0; mx<p_Vid->width >> 3; mx++)
335 {
336 j = my*8 + 8;
337 i = mx*8 + 8;
338 if (p_Vid->refresh_map[my][mx])
339 {
340 for (y=my*8; y<j; y++)
341 memset(&p_Vid->pixel_map[y][mx*8], 1, 8 * sizeof(byte));
342 }
343 else
344 {
345 for (y=my*8; y<j; y++)
346 {
347 for (x=mx*8; x<i; x++)
348 {
349 p_Vid->pixel_map[y][x] = (byte) imin(p_Vid->pixel_map[y][x] + 1, p_Inp->num_ref_frames+1);
350 }
351 }
352 }
353 }
354 }
355 }
356 }
357
358 /*!
359 *************************************************************************************
360 * \brief
361 * Checks if a given reference frame is reliable for the current
362 * macroblock, given the motion vectors that the motion search has
363 * returned.
364 *
365 * \return
366 * If the return value is 1, the reference frame is reliable. If it
367 * is 0, then it is not reliable.
368 *
369 * \note
370 * A specific area in each reference frame is assumed to be unreliable
371 * if the same area has been intra-refreshed in a subsequent frame.
372 * The information about intra-refreshed areas is kept in the p_Vid->pixel_map.
373 *
374 *************************************************************************************
375 */
CheckReliabilityOfRef(Macroblock * currMB,int block,int list_idx,int ref,int mode)376 int CheckReliabilityOfRef (Macroblock *currMB, int block, int list_idx, int ref, int mode)
377 {
378 Slice *currSlice = currMB->p_Slice;
379 VideoParameters *p_Vid = currMB->p_Vid;
380
381 int y,x, block_y, block_x, dy, dx, y_pos, x_pos, yy, xx, pres_x, pres_y;
382 int maxold_x = p_Vid->width - 1;
383 int maxold_y = p_Vid->height - 1;
384 int ref_frame = ref + 1;
385
386 int by0 = (mode>=4?2*(block >> 1):mode==2?2*block:0);
387 int by1 = by0 + (mode>=4||mode==2?2:4);
388 int bx0 = (mode>=4?2*(block & 0x01):mode==3?2*block:0);
389 int bx1 = bx0 + (mode>=4||mode==3?2:4);
390
391 for (block_y=by0; block_y<by1; block_y++)
392 {
393 for (block_x=bx0; block_x<bx1; block_x++)
394 {
395 y_pos = currSlice->all_mv[list_idx][ref][mode][block_y][block_x].mv_y;
396 y_pos += (currMB->block_y + block_y) * BLOCK_SIZE * 4;
397 x_pos = currSlice->all_mv[list_idx][ref][mode][block_y][block_x].mv_x;
398 x_pos += (currMB->block_x + block_x) * BLOCK_SIZE * 4;
399
400 /* Here we specify which pixels of the reference frame influence
401 the reference values and check their reliability. This is
402 based on the function Get_Reference_Pixel */
403
404 dy = y_pos & 3;
405 dx = x_pos & 3;
406
407 y_pos = (y_pos - dy) >> 2;
408 x_pos = (x_pos - dx) >> 2;
409
410 if (dy==0 && dx==0) //full-pel
411 {
412 for (y=y_pos ; y < y_pos + BLOCK_SIZE ; y++)
413 for (x=x_pos ; x < x_pos + BLOCK_SIZE ; x++)
414 if (p_Vid->pixel_map[iClip3(0,maxold_y,y)][iClip3(0,maxold_x,x)] < ref_frame)
415 return 0;
416 }
417 else /* other positions */
418 {
419 if (dy == 0)
420 {
421 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
422 {
423 pres_y = iClip3(0, maxold_y, y);
424 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
425 {
426 for(xx = -2 ; xx < 4 ; xx++)
427 {
428 pres_x = iClip3(0, maxold_x, x + xx);
429 if (p_Vid->pixel_map[pres_y][pres_x] < ref_frame)
430 return 0;
431 }
432 }
433 }
434 }
435 else if (dx == 0)
436 {
437 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
438 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
439 {
440 pres_x = iClip3(0,maxold_x,x);
441 for(yy=-2;yy<4;yy++)
442 {
443 pres_y = iClip3(0,maxold_y, yy + y);
444 if (p_Vid->pixel_map[pres_y][pres_x] < ref_frame)
445 return 0;
446 }
447 }
448 }
449 else if (dx == 2)
450 {
451 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
452 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
453 {
454 for(yy=-2;yy<4;yy++)
455 {
456 pres_y = iClip3(0,maxold_y, yy + y);
457 for(xx=-2;xx<4;xx++)
458 {
459 pres_x = iClip3(0,maxold_x, xx + x);
460 if (p_Vid->pixel_map[pres_y][pres_x] < ref_frame)
461 return 0;
462 }
463 }
464 }
465 }
466 else if (dy == 2)
467 {
468 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
469 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
470 {
471 for(xx=-2;xx<4;xx++)
472 {
473 pres_x = iClip3(0,maxold_x, xx + x);
474 for(yy=-2;yy<4;yy++)
475 {
476 pres_y = iClip3(0,maxold_y, yy + y);
477 if (p_Vid->pixel_map[pres_y][pres_x] < ref_frame)
478 return 0;
479 }
480 }
481 }
482 }
483 else
484 {
485 for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
486 {
487 for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
488 {
489 pres_y = dy == 1 ? y : y + 1;
490 pres_y = iClip3(0,maxold_y,pres_y);
491
492 for(xx = -2; xx < 4; xx++)
493 {
494 pres_x = iClip3(0,maxold_x,xx + x);
495 if (p_Vid->pixel_map[pres_y][pres_x] < ref_frame)
496 return 0;
497 }
498
499 pres_x = dx == 1 ? x : x + 1;
500 pres_x = iClip3(0,maxold_x,pres_x);
501
502 for(yy=-2;yy<4;yy++)
503 {
504 pres_y = iClip3(0,maxold_y, yy + y);
505 if (p_Vid->pixel_map[pres_y][pres_x] < ref_frame)
506 return 0;
507 }
508 }
509 }
510 }
511 }
512 }
513 }
514 return 1;
515 }
516
517 /*!
518 *************************************************************************************
519 * \brief
520 * R-D Cost for an 4x4 Intra block
521 *************************************************************************************
522 */
rdcost_for_4x4_intra_blocks(Macroblock * currMB,int * nonzero,int b8,int b4,int ipmode,int lambda,int mostProbableMode,distblk min_rdcost)523 static distblk rdcost_for_4x4_intra_blocks (Macroblock *currMB,
524 int* nonzero,
525 int b8,
526 int b4,
527 int ipmode,
528 int lambda,
529 int mostProbableMode,
530 distblk min_rdcost)
531 {
532 Slice *currSlice = currMB->p_Slice;
533 VideoParameters *p_Vid = currMB->p_Vid;
534 distblk rdcost;
535 int dummy = 0, rate;
536 distblk distortion = 0;
537 int block_x = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
538 int block_y = ((b8 >> 1) << 3) + ((b4 >> 1) << 2);
539 int pic_pix_x = currMB->pix_x + block_x;
540 int pic_pix_y = currMB->pix_y + block_y;
541 int pic_opix_y = currMB->opix_y + block_y;
542
543 SyntaxElement se;
544 const int *partMap = assignSE2partition[currSlice->partition_mode];
545 //--- choose data partition ---
546 DataPartition *dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
547
548 //===== perform forward transform, Q, IQ, inverse transform, Reconstruction =====
549 //select_transform(currMB);
550
551 currMB->ipmode_DPCM = (short) ipmode;
552 *nonzero = currMB->residual_transform_quant_luma_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1);
553
554 //===== get distortion (SSD) of 4x4 block =====
555 distortion += compute_SSE4x4(&p_Vid->pCurImg[pic_opix_y], &p_Vid->enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x);
556 #if INTRA_RDCOSTCALC_ET
557 // check if already distortion larger than min_rdcost
558 if (distortion >= min_rdcost)
559 {
560 return (distortion);
561 }
562 #endif
563 currMB->ipmode_DPCM = NO_INTRA_PMODE;
564
565 //===== RATE for INTRA PREDICTION MODE (SYMBOL MODE MUST BE SET TO CAVLC) =====
566 se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode - 1;
567
568 //--- set position and type ---
569 se.context = (b8 << 2) + b4;
570 se.type = SE_INTRAPREDMODE;
571
572 //--- encode and update rate ---
573 currSlice->writeIntraPredMode (&se, dataPart);
574 rate = se.len;
575
576 //===== RATE for LUMINANCE COEFFICIENTS =====
577 if (currSlice->symbol_mode == CAVLC)
578 {
579 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, b4, 0);
580 }
581 else
582 {
583 rate += writeCoeff4x4_CABAC (currMB, PLANE_Y, b8, b4, 1);
584 }
585
586 rdcost = distortion + weighted_cost(lambda, rate); //((distblk)lambda) * rate;
587
588 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
589
590 return rdcost;
591 }
592
593
594 /*!
595 *************************************************************************************
596 * \brief
597 * R-D Cost for an 4x4 Intra block (for 4:4:4 formats)
598 *************************************************************************************
599 */
rdcost_for_4x4_intra_blocks_444(Macroblock * currMB,int * nonzero,int b8,int b4,int ipmode,int lambda,int mostProbableMode,distblk min_rdcost)600 static distblk rdcost_for_4x4_intra_blocks_444 (Macroblock *currMB,
601 int* nonzero,
602 int b8,
603 int b4,
604 int ipmode,
605 int lambda,
606 int mostProbableMode,
607 distblk min_rdcost)
608 {
609 Slice *currSlice = currMB->p_Slice;
610 VideoParameters *p_Vid = currMB->p_Vid;
611 distblk rdcost;
612 int dummy = 0, rate;
613 distblk distortion = 0;
614 int block_x = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
615 int block_y = ((b8 >> 1) << 3) + ((b4 >> 1) << 2);
616 int pic_pix_x = currMB->pix_x + block_x;
617 int pic_pix_y = currMB->pix_y + block_y;
618 int pic_opix_y = currMB->opix_y + block_y;
619
620 SyntaxElement se;
621 const int *partMap = assignSE2partition[currSlice->partition_mode];
622 DataPartition *dataPart;
623 ColorPlane k;
624
625 //===== perform forward transform, Q, IQ, inverse transform, Reconstruction =====
626 //select_transform(currMB);
627 *nonzero = currMB->residual_transform_quant_luma_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1);
628
629 //===== get distortion (SSD) of 4x4 block =====
630 distortion += compute_SSE4x4(&p_Vid->pCurImg[pic_opix_y], &p_Vid->enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x);
631
632 if(p_Vid->P444_joined)
633 {
634 for (k = PLANE_U; k <= PLANE_V; k++)
635 {
636 select_plane(p_Vid, k);
637 currMB->c_nzCbCr[k] = currMB->residual_transform_quant_luma_4x4(currMB, k, block_x, block_y, &dummy, 1);
638 distortion += compute_SSE4x4(&p_Vid->pCurImg[pic_opix_y], &p_Vid->enc_picture->p_curr_img[pic_pix_y], pic_pix_x, pic_pix_x);
639 }
640 select_plane(p_Vid, PLANE_Y);
641 }
642 currMB->ipmode_DPCM = NO_INTRA_PMODE;
643
644 //===== RATE for INTRA PREDICTION MODE (SYMBOL MODE MUST BE SET TO CAVLC) =====
645 se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode - 1;
646
647 //--- set position and type ---
648 se.context = (b8 << 2) + b4;
649 se.type = SE_INTRAPREDMODE;
650
651 //--- choose data partition ---
652 dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
653 //--- encode and update rate ---
654 currSlice->writeIntraPredMode (&se, dataPart);
655 rate = se.len;
656
657 //===== RATE for LUMINANCE COEFFICIENTS =====
658 if (currSlice->symbol_mode == CAVLC)
659 {
660 rate += currSlice->writeCoeff4x4_CAVLC (currMB, LUMA, b8, b4, 0);
661 if(p_Vid->P444_joined)
662 {
663 rate += currSlice->writeCoeff4x4_CAVLC (currMB, CB, b8, b4, 0);
664 rate += currSlice->writeCoeff4x4_CAVLC (currMB, CR, b8, b4, 0);
665 }
666 }
667 else
668 {
669 rate += writeCoeff4x4_CABAC (currMB, PLANE_Y, b8, b4, 1);
670 if(p_Vid->P444_joined)
671 {
672 rate += writeCoeff4x4_CABAC (currMB, PLANE_U, b8, b4, 1);
673 rate += writeCoeff4x4_CABAC (currMB, PLANE_V, b8, b4, 1);
674 }
675 }
676 rdcost = distortion + weight_cost(lambda,rate);
677 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
678
679 return rdcost;
680 }
681
682 /*!
683 *************************************************************************************
684 * \brief
685 * R-D Cost for an 8x8 Partition
686 *************************************************************************************
687 */
rdcost_for_8x8blocks(Macroblock * currMB,RD_8x8DATA * dataTr,int * cnt_nonz,int64 * cbp_blk,int lambda,int block,short mode,Info8x8 * part,distblk min_rdcost)688 distblk rdcost_for_8x8blocks (Macroblock *currMB, // --> Current macroblock to code
689 RD_8x8DATA *dataTr,
690 int* cnt_nonz, // --> number of nonzero coefficients
691 int64* cbp_blk, // --> cbp blk
692 int lambda, // <-- lagrange multiplier
693 int block, // <-- 8x8 block number
694 short mode, // <-- partitioning mode
695 Info8x8 *part, // <-- partition information
696 distblk min_rdcost)
697 {
698 Slice *currSlice = currMB->p_Slice;
699 VideoParameters *p_Vid = currMB->p_Vid;
700 InputParameters *p_Inp = currMB->p_Inp;
701 pic_parameter_set_rbsp_t *active_pps = p_Vid->active_pps;
702 int rate=0;
703 distblk distortion=0;
704
705 int dummy = 0, mrate;
706 int list_mode[2];
707 int cbp = 0;
708 int pax = 8*(block & 0x01);
709 int pay = 8*(block >> 1);
710 int i0 = pax >> 2;
711 int j0 = pay >> 2;
712 int direct = (currSlice->slice_type == B_SLICE && mode==0);
713 int b8value = B8Mode2Value (currSlice, (short) mode, part->pdir);
714
715 SyntaxElement se;
716 DataPartition *dataPart;
717 const int *partMap = assignSE2partition[currSlice->partition_mode];
718
719 EncodingEnvironmentPtr eep_dp;
720
721 short pdir = part->pdir;
722 int l0_ref = part->ref[LIST_0];
723 int l1_ref = part->ref[LIST_1];
724
725 //=====
726 //===== GET COEFFICIENTS, RECONSTRUCTIONS, CBP
727 //=====
728 currMB->b8x8[block].bipred = part->bipred;
729 currMB->ar_mode = (short) ((mode != 0)? mode: P8x8);
730
731
732 if (direct)
733 {
734 int p_dir = currSlice->direct_pdir[currMB->block_y + j0][currMB->block_x + i0];
735 if (p_dir < 0) // mode not allowed
736 return (DISTBLK_MAX);
737 else
738 {
739 int list_mode[2] = {0, 0};
740 *cnt_nonz = currSlice->luma_residual_coding_8x8 (currMB, &cbp, cbp_blk, block, (short) p_dir, list_mode,
741 currSlice->direct_ref_idx[currMB->block_y+j0][currMB->block_x+i0]);
742 }
743 }
744 else
745 {
746 if (pdir == 2 && active_pps->weighted_bipred_idc == 1)
747 {
748
749 int weight_sum = (active_pps->weighted_bipred_idc == 1)? currSlice->wbp_weight[0][l0_ref][l1_ref][0] + currSlice->wbp_weight[1][l0_ref][l1_ref][0] : 0;
750 if (weight_sum < -128 || weight_sum > 127)
751 {
752 return (DISTBLK_MAX);
753 }
754 }
755
756 list_mode[0] = (pdir==0||pdir==2 ? mode : 0);
757 list_mode[1] = (pdir==1||pdir==2 ? mode : 0);
758 *cnt_nonz = currSlice->luma_residual_coding_8x8 (currMB, &cbp, cbp_blk, block, pdir, list_mode, part->ref);
759 }
760
761 if(p_Vid->P444_joined)
762 {
763 *cnt_nonz += ( currSlice->coeff_cost_cr[1] + currSlice->coeff_cost_cr[2] );
764 }
765
766 // RDOPT with losses
767 if (p_Inp->rdopt==3)
768 {
769 //Zhifeng 090611
770 distortion = p_Vid->estimate_distortion(currMB, block, 8, mode, pdir, min_rdcost); //===== get residue =====
771 }
772 else
773 {
774 distortion += compute_SSE8x8(&p_Vid->pCurImg[currMB->opix_y + pay], &p_Vid->enc_picture->imgY[currMB->pix_y + pay], currMB->pix_x + pax, currMB->pix_x + pax);
775 }
776
777 if (p_Vid->P444_joined)
778 {
779 distortion += compute_SSE8x8(&p_Vid->pImgOrg[1][currMB->opix_y + pay], &p_Vid->enc_picture->imgUV[0][currMB->pix_y + pay], currMB->pix_x + pax, currMB->pix_x + pax);
780 distortion += compute_SSE8x8(&p_Vid->pImgOrg[2][currMB->opix_y + pay], &p_Vid->enc_picture->imgUV[1][currMB->pix_y + pay], currMB->pix_x + pax, currMB->pix_x + pax);
781 }
782
783 // Early termination
784 if (distortion >= min_rdcost)
785 return (distortion);
786 //printf("distortion %.2f %.2f\n", (double) distortion, min_rdcost);
787
788 if(p_Vid->P444_joined)
789 {
790 cbp |= currSlice->cmp_cbp[1];
791 cbp |= currSlice->cmp_cbp[2];
792
793 currSlice->cmp_cbp[1] = cbp;
794 currSlice->cmp_cbp[2] = cbp;
795 }
796
797 //=====
798 //===== GET RATE
799 //=====
800 //----- block 8x8 mode -----
801 if (currSlice->symbol_mode == CAVLC)
802 {
803 ue_linfo (b8value, dummy, &mrate, &dummy);
804 rate += mrate;
805 }
806 else
807 {
808 se.value1 = b8value;
809 se.type = SE_MBTYPE;
810 dataPart = &(currSlice->partArr[partMap[se.type]]);
811 currSlice->writeB8_typeInfo(&se, dataPart);
812 rate += se.len;
813 }
814
815 //----- motion information -----
816 if (!direct)
817 {
818 if ((currSlice->num_ref_idx_active[LIST_0] > 1 ) && (pdir==0 || pdir==2))
819 rate += writeReferenceFrame (currMB, i0, j0, LIST_0, l0_ref);
820
821 if ((currSlice->num_ref_idx_active[LIST_1] > 1 && currSlice->slice_type == B_SLICE ) && (pdir==1 || pdir==2))
822 {
823 rate += writeReferenceFrame (currMB, i0, j0, LIST_1, l1_ref);
824 }
825
826 if (pdir==0 || pdir==2)
827 {
828 rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l0_ref, LIST_0, mode, currMB->b8x8[block].bipred);
829 }
830 if (pdir==1 || pdir==2)
831 {
832 rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l1_ref, LIST_1, mode, currMB->b8x8[block].bipred);
833 }
834 }
835
836 //----- coded block pattern (for CABAC only) -----
837 if (!(currSlice->symbol_mode == CAVLC))
838 {
839 dataPart = &(currSlice->partArr[partMap[SE_CBP]]);
840 eep_dp = &(dataPart->ee_cabac);
841 mrate = arienco_bits_written (eep_dp);
842 writeCBP_BIT_CABAC (currMB, block, ((*cnt_nonz>0)?1:0), dataTr->cbp8x8, eep_dp, currSlice->tex_ctx);
843 mrate = arienco_bits_written (eep_dp) - mrate;
844 rate += mrate;
845 }
846
847 //----- luminance coefficients -----
848 if (*cnt_nonz)
849 {
850 rate += writeCoeff8x8 ( currMB, PLANE_Y, block, mode, currMB->luma_transform_size_8x8_flag);
851 }
852
853 if(p_Vid->P444_joined)
854 {
855 rate += writeCoeff8x8( currMB, PLANE_U, block, mode, currMB->luma_transform_size_8x8_flag );
856 rate += writeCoeff8x8( currMB, PLANE_V, block, mode, currMB->luma_transform_size_8x8_flag );
857 }
858 return (distortion + weight_cost(lambda, rate));
859 }
860
861
862 /*
863 *************************************************************************************
864 * \brief
865 * Gets mode offset for intra16x16 mode
866 *************************************************************************************
867 */
I16Offset(int cbp,short i16mode)868 short I16Offset (int cbp, short i16mode)
869 {
870 return (short) ((cbp & 15 ? 13 : 1) + i16mode + ((cbp & 0x30) >> 2));
871 }
872
873
874 /*!
875 *************************************************************************************
876 * \brief
877 * Sets modes and reference frames for a macroblock
878 *************************************************************************************
879 */
set_modes_and_refs_for_blocks_i_slice(Macroblock * currMB,short mode)880 void set_modes_and_refs_for_blocks_i_slice(Macroblock *currMB, short mode)
881 {
882 VideoParameters *p_Vid = currMB->p_Vid;
883
884 int i,j;
885 Block8x8Info *b8x8info = p_Vid->b8x8info;
886 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
887
888 //--- macroblock type ---
889 currMB->mb_type = mode;
890 currMB->ar_mode = mode;
891
892 for( i = 0; i < 4; i++)
893 {
894 currMB->b8x8[i] = b8x8info->best[mode][i];
895 }
896
897 //--- block 8x8 mode and prediction direction ---
898 switch (mode)
899 {
900 case I4MB:
901 for(i=0;i<4;i++)
902 {
903 currMB->b8x8[i].mode = IBLOCK;
904 currMB->b8x8[i].pdir = -1;
905 }
906 break;
907 case I16MB:
908 //memset(currMB->b8x8, 0, 4 * sizeof(short));
909 currMB->b8x8[0].mode = 0;
910 currMB->b8x8[1].mode = 0;
911 currMB->b8x8[2].mode = 0;
912 currMB->b8x8[3].mode = 0;
913 for(i=0;i<4;i++)
914 {
915 currMB->b8x8[i].pdir = -1;
916 }
917 break;
918 case I8MB:
919 for(i=0;i<4;i++)
920 {
921 currMB->b8x8[i].mode = I8MB;
922 currMB->b8x8[i].pdir = -1;
923 }
924 //switch to 8x8 transform
925 currMB->luma_transform_size_8x8_flag = TRUE;
926 break;
927 case IPCM:
928 for(i=0;i<4;i++)
929 {
930 currMB->b8x8[i].mode = IPCM;
931 currMB->b8x8[i].pdir = -1;
932 }
933 currMB->luma_transform_size_8x8_flag = FALSE;
934 break;
935 default:
936 printf ("Unsupported mode in set_modes_and_refs_for_blocks!\n");
937 exit (1);
938 }
939
940 //--- reference frame arrays ---
941 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
942 {
943 for (i = currMB->block_x; i < currMB->block_x + 4;i++)
944 {
945 motion[j][i].ref_pic [LIST_0] = NULL;
946 motion[j][i].ref_idx [LIST_0] = -1;
947 }
948 }
949 }
950
951
952 /*!
953 *************************************************************************************
954 * \brief
955 * Sets modes and reference frames for a macroblock
956 *************************************************************************************
957 */
set_modes_and_refs_for_blocks_p_slice(Macroblock * currMB,short mode)958 void set_modes_and_refs_for_blocks_p_slice(Macroblock *currMB, short mode)
959 {
960 Slice *currSlice = currMB->p_Slice;
961 VideoParameters *p_Vid = currMB->p_Vid;
962
963 int i,j,k;
964
965 Block8x8Info *b8x8info = p_Vid->b8x8info;
966 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
967
968 //--- macroblock type ---
969 currMB->mb_type = mode;
970
971 for( i = 0; i < 4; i++)
972 {
973 currMB->b8x8[i] = b8x8info->best[mode][i];
974 }
975
976 currMB->ar_mode = mode;
977
978 //--- block 8x8 mode and prediction direction ---
979 switch (mode)
980 {
981 case 0:
982 currMB->b8x8[0].mode = 0;
983 currMB->b8x8[1].mode = 0;
984 currMB->b8x8[2].mode = 0;
985 currMB->b8x8[3].mode = 0;
986 currMB->b8x8[0].pdir = 0;
987 currMB->b8x8[1].pdir = 0;
988 currMB->b8x8[2].pdir = 0;
989 currMB->b8x8[3].pdir = 0;
990 break;
991 case 1:
992 case 2:
993 case 3:
994 for(i=0;i<4;i++)
995 {
996 currMB->b8x8[i].mode = (char) mode;
997 }
998 break;
999 case P8x8:
1000 break;
1001 case I4MB:
1002 for(i=0;i<4;i++)
1003 {
1004 currMB->b8x8[i].mode = IBLOCK;
1005 currMB->b8x8[i].pdir = -1;
1006 }
1007 break;
1008 case I16MB:
1009 //memset(currMB->b8x8, 0, 4 * sizeof(short));
1010 currMB->b8x8[0].mode = 0;
1011 currMB->b8x8[1].mode = 0;
1012 currMB->b8x8[2].mode = 0;
1013 currMB->b8x8[3].mode = 0;
1014 for(i=0;i<4;i++)
1015 {
1016 currMB->b8x8[i].pdir = -1;
1017 }
1018 break;
1019 case I8MB:
1020 for(i=0;i<4;i++)
1021 {
1022 currMB->b8x8[i].mode = I8MB;
1023 currMB->b8x8[i].pdir = -1;
1024 }
1025 //switch to 8x8 transform
1026 currMB->luma_transform_size_8x8_flag = TRUE;
1027 break;
1028 case IPCM:
1029 for(i=0;i<4;i++)
1030 {
1031 currMB->b8x8[i].mode = IPCM;
1032 currMB->b8x8[i].pdir = -1;
1033 }
1034 currMB->luma_transform_size_8x8_flag = FALSE;
1035 break;
1036 default:
1037 printf ("Unsupported mode in set_modes_and_refs_for_blocks!\n");
1038 exit (1);
1039 }
1040
1041 //--- reference frame arrays ---
1042 if (mode==0 || mode==I4MB || mode==I16MB || mode==I8MB || mode == IPCM || mode == SI4MB)
1043 {
1044 if (!mode) // Skip
1045 {
1046 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
1047 for (i = currMB->block_x; i < currMB->block_x + 4; i++)
1048 motion[j][i].ref_idx[LIST_0] = 0;
1049 }
1050 else // Intra
1051 {
1052 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
1053 for (i = currMB->block_x; i < currMB->block_x + 4; i++)
1054 motion[j][i].ref_idx[LIST_0] = -1;
1055 }
1056 }
1057 else
1058 {
1059 if (mode == 1)
1060 {
1061 short curref = b8x8info->best[mode][0].pdir == 0 ? b8x8info->best[mode][0].ref[LIST_0] : -1;
1062 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
1063 {
1064 for (i = currMB->block_x; i < currMB->block_x + 4;i++)
1065 {
1066 motion[j][i].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][curref];
1067 motion[j][i].ref_idx [LIST_0] = (char) curref;
1068 }
1069 }
1070 }
1071 else if (mode == 2)
1072 {
1073 short curref = b8x8info->best[mode][0].pdir == 0 ? b8x8info->best[mode][0].ref[LIST_0] : -1;
1074 for (j = currMB->block_y; j < currMB->block_y + 2; j++)
1075 {
1076 for (i = currMB->block_x; i < currMB->block_x + 4;i++)
1077 {
1078 motion[j][i].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][curref];
1079 motion[j][i].ref_idx [LIST_0] = (char) curref;
1080 }
1081 }
1082 curref = b8x8info->best[mode][2].pdir == 0 ? b8x8info->best[mode][2].ref[LIST_0] : -1;
1083 for (j = currMB->block_y + 2; j < currMB->block_y + 4; j++)
1084 {
1085 for (i = currMB->block_x; i < currMB->block_x + 4;i++)
1086 {
1087 motion[j][i].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][curref];
1088 motion[j][i].ref_idx [LIST_0] = (char) curref;
1089 }
1090 }
1091 }
1092 else if (mode == 3)
1093 {
1094 short curref = (b8x8info->best[mode][0].pdir == 0) ? b8x8info->best[mode][0].ref[LIST_0] : -1;
1095 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
1096 {
1097 for (i = currMB->block_x; i < currMB->block_x + 2;i++)
1098 {
1099 motion[j][i].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][curref];
1100 motion[j][i].ref_idx [LIST_0] = (char) curref;
1101 }
1102 }
1103 curref = (b8x8info->best[mode][1].pdir == 0) ? b8x8info->best[mode][1].ref[LIST_0] : -1;
1104 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
1105 {
1106 for (i = currMB->block_x + 2; i < currMB->block_x + 4;i++)
1107 {
1108 motion[j][i].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][curref];
1109 motion[j][i].ref_idx [LIST_0] = (char) curref;
1110 }
1111 }
1112 }
1113 else
1114 {
1115 int block_x, block_y;
1116 int curref;
1117 for (j = 0; j < 4; j++)
1118 {
1119 block_x = currMB->block_x;
1120 block_y = currMB->block_y + j;
1121 k = 2*(j >> 1);
1122 curref = b8x8info->best[mode][k++].ref[LIST_0];
1123 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][curref];
1124 motion[block_y][block_x++].ref_idx[LIST_0] = (char) curref;
1125 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][curref];
1126 motion[block_y][block_x++].ref_idx[LIST_0] = (char) curref;
1127 curref = b8x8info->best[mode][k].ref[LIST_0];
1128 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][curref];
1129 motion[block_y][block_x++].ref_idx[LIST_0] = (char) curref;
1130 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][curref];
1131 motion[block_y][block_x].ref_idx[LIST_0] = (char) curref;
1132 }
1133 }
1134 }
1135 }
1136
1137
1138 /*!
1139 *************************************************************************************
1140 * \brief
1141 * Sets modes and reference frames for a macroblock
1142 *************************************************************************************
1143 */
set_modes_and_refs_for_blocks_b_slice(Macroblock * currMB,short mode)1144 void set_modes_and_refs_for_blocks_b_slice(Macroblock *currMB, short mode)
1145 {
1146 Slice *currSlice = currMB->p_Slice;
1147 VideoParameters *p_Vid = currMB->p_Vid;
1148
1149 int i,j,k;
1150 int block_x, block_y, block8x8, block4x4;
1151 int cur_ref;
1152 int clist;
1153 char curref, bestref;
1154 Block8x8Info *b8x8info = p_Vid->b8x8info;
1155 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
1156
1157 //--- macroblock type ---
1158 currMB->mb_type = mode;
1159 currMB->ar_mode = mode;
1160
1161 for( i = 0; i < 4; i++)
1162 {
1163 currMB->b8x8[i] = b8x8info->best[mode][i];
1164 }
1165
1166 //--- block 8x8 mode and prediction direction ---
1167 switch (mode)
1168 {
1169 case 0:
1170 currMB->b8x8[0].mode = 0;
1171 currMB->b8x8[1].mode = 0;
1172 currMB->b8x8[2].mode = 0;
1173 currMB->b8x8[3].mode = 0;
1174
1175 currMB->b8x8[0].pdir = currSlice->direct_pdir[currMB->block_y ][currMB->block_x ];
1176 currMB->b8x8[1].pdir = currSlice->direct_pdir[currMB->block_y ][currMB->block_x + 2];
1177 currMB->b8x8[2].pdir = currSlice->direct_pdir[currMB->block_y + 2][currMB->block_x ];
1178 currMB->b8x8[3].pdir = currSlice->direct_pdir[currMB->block_y + 2][currMB->block_x + 2];
1179 break;
1180 case 1:
1181 case 2:
1182 case 3:
1183 for(i=0;i<4;i++)
1184 {
1185 currMB->b8x8[i].mode = (char) mode;
1186 }
1187 break;
1188 case P8x8:
1189 break;
1190 case I4MB:
1191 for(i=0;i<4;i++)
1192 {
1193 currMB->b8x8[i].mode = IBLOCK;
1194 currMB->b8x8[i].pdir = -1;
1195 }
1196 break;
1197 case I16MB:
1198 for(i=0;i<4;i++)
1199 {
1200 currMB->b8x8[i].mode = 0;
1201 currMB->b8x8[i].pdir = -1;
1202 }
1203 break;
1204 case I8MB:
1205 for(i=0;i<4;i++)
1206 {
1207 currMB->b8x8[i].mode = I8MB;
1208 currMB->b8x8[i].pdir = -1;
1209 }
1210 //switch to 8x8 transform
1211 currMB->luma_transform_size_8x8_flag = TRUE;
1212 break;
1213 case IPCM:
1214 for(i=0;i<4;i++)
1215 {
1216 currMB->b8x8[i].mode = IPCM;
1217 currMB->b8x8[i].pdir = -1;
1218 }
1219 currMB->luma_transform_size_8x8_flag = FALSE;
1220 break;
1221 default:
1222 printf ("Unsupported mode in set_modes_and_refs_for_blocks!\n");
1223 exit (1);
1224 }
1225
1226 #define IS_FW ((b8x8info->best[mode][k].pdir==0 || b8x8info->best[mode][k].pdir==2) && (mode!=P8x8 || b8x8info->best[mode][k].mode!=0))
1227 #define IS_BW ((b8x8info->best[mode][k].pdir==1 || b8x8info->best[mode][k].pdir==2) && (mode!=P8x8 || b8x8info->best[mode][k].mode!=0))
1228
1229 //--- reference frame arrays ---
1230 if (mode == 0) // Direct
1231 {
1232 for (clist = LIST_0; clist <= LIST_1; clist++)
1233 {
1234 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
1235 {
1236 for (i = currMB->block_x; i < currMB->block_x + 4; i++)
1237 motion[j][i].ref_idx[clist] = currSlice->direct_ref_idx[j][i][clist];
1238 }
1239 }
1240 }
1241 else if (mode==I4MB || mode==I16MB || mode==I8MB || mode == IPCM)
1242 {
1243 for (clist = LIST_0; clist <= LIST_1; clist++)
1244 {
1245 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
1246 {
1247 for (i = currMB->block_x; i < currMB->block_x + 4; i++)
1248 motion[j][i].ref_idx[clist] = -1;
1249 }
1250 }
1251 }
1252 else if (mode == 1 || mode == 2 || mode == 3)
1253 {
1254 for (block8x8 = 0; block8x8 < 4; block8x8++)
1255 {
1256 for (clist = LIST_0; clist <= LIST_1; clist++)
1257 {
1258 bestref = b8x8info->best[mode][block8x8].ref[clist];
1259
1260 if ( b8x8info->best[mode][block8x8].pdir == 2)
1261 {
1262 curref = (b8x8info->best[mode][block8x8].bipred) ? 0 : bestref;
1263 }
1264 else
1265 {
1266 curref = (clist == b8x8info->best[mode][block8x8].pdir) ? bestref : -1;
1267 }
1268
1269 for (block4x4 = 0; block4x4 < 4; block4x4++)
1270 {
1271 block_x = currMB->block_x + 2 * (block8x8 & 0x01) + (block4x4 & 0x01);
1272 block_y = currMB->block_y + 2 * (block8x8 >> 1) + (block4x4 >> 1);
1273 motion[block_y][block_x].ref_idx[clist] = curref;
1274 }
1275 }
1276 }
1277 }
1278 else // mode == P8x8
1279 {
1280 for (j = 0; j < 4; j++)
1281 {
1282 block_y = currMB->block_y + j;
1283 for (i = 0; i < 4; i++)
1284 {
1285 block_x = currMB->block_x + i;
1286 k = 2*(j >> 1) + (i >> 1);
1287
1288 if(b8x8info->best[mode][k].mode==0)
1289 {
1290 motion[block_y][block_x].ref_idx[LIST_0] = currSlice->direct_ref_idx[block_y][block_x][LIST_0];
1291 motion[block_y][block_x].ref_idx[LIST_1] = currSlice->direct_ref_idx[block_y][block_x][LIST_1];
1292 }
1293 else
1294 {
1295 motion[block_y][block_x].ref_idx[LIST_0] = (IS_FW ? b8x8info->best[mode][k].ref[LIST_0] : -1);
1296 motion[block_y][block_x].ref_idx[LIST_1] = (IS_BW ? b8x8info->best[mode][k].ref[LIST_1] : -1);
1297 }
1298 }
1299 }
1300 }
1301
1302 for (clist = LIST_0; clist <= LIST_1; clist++)
1303 {
1304 StorablePicture **ref_pic = currSlice->listX[clist + currMB->list_offset];
1305 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
1306 {
1307 for (i = currMB->block_x; i < currMB->block_x + 4;i++)
1308 {
1309 cur_ref = (int) motion[j][i].ref_idx[clist];
1310 motion[j][i].ref_pic [clist] = (cur_ref < 0 ? NULL : ref_pic[cur_ref]);
1311 }
1312 }
1313 }
1314
1315 #undef IS_FW
1316 #undef IS_BW
1317 }
1318
1319
1320 /*!
1321 *************************************************************************************
1322 * \brief
1323 * Sets Coefficients and reconstruction for an 8x8 block
1324 *************************************************************************************
1325 */
set_coeff_and_recon_8x8_p_slice(Macroblock * currMB)1326 void set_coeff_and_recon_8x8_p_slice (Macroblock* currMB)
1327 {
1328 VideoParameters *p_Vid = currMB->p_Vid;
1329 InputParameters *p_Inp = currMB->p_Inp;
1330 Slice *currSlice = currMB->p_Slice;
1331 RDOPTStructure *p_RDO = currSlice->p_RDO;
1332
1333 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
1334 int block, k, j, i, uv;
1335 int cur_ref;
1336
1337 //============= MIXED TRANSFORM SIZES FOR 8x8 PARTITION ==============
1338 //--------------------------------------------------------------------
1339 if (currMB->luma_transform_size_8x8_flag && (currMB->valid_8x8))
1340 {
1341 //============= set mode and ref. frames ==============
1342 memcpy(currMB->b8x8, p_RDO->tr8x8->part, 4 * sizeof(Info8x8));
1343
1344 for (j = 0; j < 4; j++)
1345 {
1346 for (i = 0; i < 4; i++)
1347 {
1348 k = 2*(j >> 1)+(i >> 1);
1349 motion[currMB->block_y+j][currMB->block_x+i].ref_idx[LIST_0] = p_RDO->tr8x8->part[k].ref[LIST_0];
1350 }
1351 }
1352
1353 for (j = currMB->block_y;j<currMB->block_y + BLOCK_MULTIPLE;j++)
1354 {
1355 for (i = currMB->block_x;i<currMB->block_x + BLOCK_MULTIPLE;i++)
1356 {
1357 cur_ref = (int) motion[j][i].ref_idx[LIST_0];
1358 motion[j][i].ref_pic[LIST_0] =(cur_ref >= 0 ? currSlice->listX[LIST_0 + currMB->list_offset][cur_ref] : NULL);
1359 }
1360 }
1361
1362
1363 //====== set the mv's for 8x8 partition with transform size 8x8 ======
1364 //save the mv data for 4x4 transform
1365 StoreMV8x8(currSlice, 1);
1366 //set new mv data for 8x8 transform
1367 RestoreMV8x8(currSlice, 0);
1368
1369 //============= get pre-calculated data ==============
1370 //restore coefficients from 8x8 transform
1371
1372 for (block = 0; block<4; block++)
1373 {
1374 memcpy (currSlice->cofAC[block][0][0],p_RDO->cofAC8x8ts[block][0][0][0], 4 * 2 * 65 * sizeof(int));
1375 }
1376
1377 if (p_Vid->P444_joined)
1378 {
1379 for (uv=0; uv<2; uv++)
1380 {
1381 for (block = 0; block<4; block++)
1382 {
1383 memcpy (currSlice->cofAC[4+block+uv*4][0][0],p_RDO->cofAC8x8ts[block][uv + 1][0][0], 4 * 2 * 65 * sizeof(int));
1384 }
1385 }
1386 }
1387
1388 //restore reconstruction
1389 if (p_RDO->tr8x8->cnt_nonz_8x8 <= _LUMA_8x8_COEFF_COST_ &&
1390 ((currMB->qp_scaled[0])!=0 || p_Vid->active_sps->lossless_qpprime_flag==0) &&
1391 (currSlice->slice_type != SP_SLICE))// modif ES added last condition (we probably never go there so is the next modification useful ? check)
1392 {
1393 currMB->cbp = 0;
1394 currMB->cbp_blk = 0;
1395
1396 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], p_RDO->tr8x8->mpr8x8, currMB->pix_x, 0);
1397
1398 if(p_Inp->rdopt == 3)
1399 {
1400 p_Vid->p_decs->rec_type = 0;
1401 }
1402
1403 if(currSlice->slice_type == SP_SLICE && !p_Vid->sp2_frame_indicator)
1404 {
1405 for (j = 0; j < MB_BLOCK_SIZE; j++)
1406 {
1407 memcpy(&p_Vid->lrec[currMB->pix_y+j][currMB->pix_x],p_RDO->tr8x8->lrec[j], MB_BLOCK_SIZE * sizeof(int));
1408 }
1409 }
1410
1411 //memset( currSlice->cofAC[0][0][0], 0, 2080 * sizeof(int)); // 4 * 4 * 2 * 65
1412
1413 if(p_Vid->P444_joined)
1414 {
1415 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
1416 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr8x8->mpr8x8CbCr[0], currMB->pix_x, 0);
1417 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr8x8->mpr8x8CbCr[1], currMB->pix_x, 0);
1418
1419 for (uv=0; uv<2; uv++)
1420 {
1421 for (block = 0; block<4; block++)
1422 {
1423 memset( currSlice->cofAC[4+block+uv*4][0][0], 0, 4 * 2 * 65 * sizeof(int));
1424 }
1425 }
1426 }
1427 }
1428 else
1429 {
1430 currMB->cbp = p_RDO->tr8x8->cbp8x8;
1431 currMB->cbp_blk = p_RDO->tr8x8->cbp_blk8x8;
1432
1433 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], p_RDO->tr8x8->rec_mbY8x8, currMB->pix_x, 0);
1434
1435 if (p_Inp->rdopt == 3)
1436 {
1437 p_Vid->p_decs->rec_type = 1;
1438 }
1439
1440 if(currSlice->slice_type == SP_SLICE && !p_Vid->sp2_frame_indicator)
1441 {
1442 for (j = 0; j < MB_BLOCK_SIZE; j++)
1443 {
1444 memcpy (&p_Vid->lrec[currMB->pix_y+j][currMB->pix_x],p_RDO->tr8x8->lrec[j], MB_BLOCK_SIZE * sizeof(int));
1445 }
1446 }
1447
1448 if (p_Vid->P444_joined)
1449 {
1450 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = p_RDO->tr8x8->cbp8x8;
1451 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr8x8->rec_mb8x8_cr[0], currMB->pix_x, 0);
1452 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr8x8->rec_mb8x8_cr[1], currMB->pix_x, 0);
1453 }
1454 }
1455 if (p_Inp->rdopt == 3)
1456 {
1457 errdo_get_best_P8x8(currMB, 1);
1458 }
1459 }
1460 else
1461 {
1462 //============= get pre-calculated data ==============
1463 //---------------------------------------------------
1464 //--- restore coefficients ---
1465 for (block = 0; block < 4; block ++)
1466 {
1467 memcpy (currSlice->cofAC[block][0][0],p_RDO->coefAC8x8[block][0][0][0], 4 * 2 * 65 * sizeof(int));
1468 }
1469
1470 if (currSlice->P444_joined)
1471 {
1472 for (block = 0; block<4; block++)
1473 {
1474 memcpy (currSlice->cofAC[block+4][0][0],p_RDO->coefAC8x8[block][1][0][0], 4 * 2 * 65 * sizeof(int));
1475 memcpy (currSlice->cofAC[block+8][0][0],p_RDO->coefAC8x8[block][2][0][0], 4 * 2 * 65 * sizeof(int));
1476 }
1477 }
1478
1479 if (((p_Inp->disthres && p_RDO->tr4x4->cnt_nonz_8x8 <= 0) || (p_RDO->tr4x4->cnt_nonz_8x8 <= 5)) && currSlice->slice_type != SP_SLICE &&
1480 ((currMB->qp_scaled[0])!=0 || p_Vid->active_sps->lossless_qpprime_flag==0))
1481 {
1482 currMB->cbp = 0;
1483 currMB->cbp_blk = 0;
1484
1485 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], p_RDO->tr4x4->mpr8x8, currMB->pix_x, 0);
1486
1487 if(p_Inp->rdopt == 3)
1488 {
1489 p_Vid->p_decs->rec_type = 0;
1490 }
1491
1492 if(currSlice->slice_type == SP_SLICE && !p_Vid->sp2_frame_indicator)
1493 {
1494 for (j = 0; j < MB_BLOCK_SIZE; j++)
1495 {
1496 memcpy (&p_Vid->lrec[currMB->pix_y+j][currMB->pix_x],p_RDO->tr4x4->lrec[j], MB_BLOCK_SIZE * sizeof(int)); // restore coeff. SP frame
1497 }
1498 }
1499
1500 //memset( currSlice->cofAC[0][0][0], 0, 2080 * sizeof(int)); // 4 * 4 * 2 * 65
1501
1502 if (currSlice->P444_joined)
1503 {
1504 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
1505
1506 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr4x4->mpr8x8CbCr[0], currMB->pix_x, 0);
1507 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr4x4->mpr8x8CbCr[1], currMB->pix_x, 0);
1508
1509 for (uv=0; uv<2; uv++)
1510 {
1511 for (block = 0; block<4; block++)
1512 {
1513 memset( currSlice->cofAC[4+block+uv*4][0][0], 0, 4 * 2 * 65 * sizeof(int));
1514 }
1515 }
1516 }
1517 }
1518 else
1519 {
1520 currMB->cbp = p_RDO->tr4x4->cbp8x8;
1521 currMB->cbp_blk = p_RDO->tr4x4->cbp_blk8x8;
1522
1523 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], p_RDO->tr4x4->rec_mbY8x8, currMB->pix_x, 0);
1524
1525 if(p_Inp->rdopt == 3)
1526 {
1527 p_Vid->p_decs->rec_type = 1;
1528 }
1529
1530 if(currSlice->slice_type == SP_SLICE && !p_Vid->sp2_frame_indicator)
1531 {
1532 for (j = 0; j < MB_BLOCK_SIZE; j++)
1533 {
1534 memcpy (&p_Vid->lrec[currMB->pix_y+j][currMB->pix_x],p_RDO->tr4x4->lrec[j], MB_BLOCK_SIZE * sizeof(int));
1535 }
1536 }
1537 if (currSlice->P444_joined)
1538 {
1539 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = p_RDO->tr4x4->cbp8x8;
1540 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr4x4->rec_mb8x8_cr[0], currMB->pix_x, 0);
1541 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr4x4->rec_mb8x8_cr[1], currMB->pix_x, 0);
1542 }
1543 }
1544 if (p_Inp->rdopt == 3)
1545 {
1546 errdo_get_best_P8x8(currMB, 0);
1547 }
1548 }
1549 }
1550
1551
1552 /*!
1553 *************************************************************************************
1554 * \brief
1555 * Sets Coefficients and reconstruction for an 8x8 block
1556 *************************************************************************************
1557 */
set_coeff_and_recon_8x8_b_slice(Macroblock * currMB)1558 void set_coeff_and_recon_8x8_b_slice (Macroblock* currMB)
1559 {
1560 VideoParameters *p_Vid = currMB->p_Vid;
1561 InputParameters *p_Inp = currMB->p_Inp;
1562 Slice *currSlice = currMB->p_Slice;
1563 RDOPTStructure *p_RDO = currSlice->p_RDO;
1564
1565 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
1566 int block, k, j, i, uv;
1567 int cur_ref;
1568
1569 //============= MIXED TRANSFORM SIZES FOR 8x8 PARTITION ==============
1570 //--------------------------------------------------------------------
1571 if (currMB->luma_transform_size_8x8_flag && (currMB->valid_8x8))
1572 {
1573 //============= set mode and ref. frames ==============
1574 memcpy(currMB->b8x8, p_RDO->tr8x8->part, 4 * sizeof(Info8x8));
1575
1576 for (j = 0;j<4;j++)
1577 {
1578 for (i = 0;i<4;i++)
1579 {
1580 k = 2*(j >> 1)+(i >> 1);
1581 motion[currMB->block_y+j][currMB->block_x+i].ref_idx[LIST_0] = ((currMB->b8x8[k].pdir & 0x01) == 0) ? p_RDO->tr8x8->part[k].ref[LIST_0] : - 1;
1582 motion[currMB->block_y+j][currMB->block_x+i].ref_idx[LIST_1] = (currMB->b8x8[k].pdir > 0) ? p_RDO->tr8x8->part[k].ref[LIST_1] : - 1;
1583 }
1584 }
1585
1586 for (j = currMB->block_y;j<currMB->block_y + BLOCK_MULTIPLE;j++)
1587 {
1588 for (i = currMB->block_x;i<currMB->block_x + BLOCK_MULTIPLE;i++)
1589 {
1590 cur_ref = (int) motion[j][i].ref_idx[LIST_0];
1591 motion[j][i].ref_pic[LIST_0] =(cur_ref >= 0 ? currSlice->listX[LIST_0 + currMB->list_offset][cur_ref] : NULL);
1592 }
1593 }
1594
1595 for (j = currMB->block_y;j<currMB->block_y + BLOCK_MULTIPLE;j++)
1596 {
1597 for (i = currMB->block_x;i<currMB->block_x + BLOCK_MULTIPLE;i++)
1598 {
1599 cur_ref = (int) motion[j][i].ref_idx[LIST_1];
1600 motion[j][i].ref_pic[LIST_1] =(cur_ref >= 0 ? currSlice->listX[LIST_1 + currMB->list_offset][cur_ref] : NULL);
1601 }
1602 }
1603
1604 //====== set the mv's for 8x8 partition with transform size 8x8 ======
1605 //save the mv data for 4x4 transform
1606 StoreMV8x8(currSlice, 1);
1607 //set new mv data for 8x8 transform
1608 RestoreMV8x8(currSlice, 0);
1609
1610 //============= get pre-calculated data ==============
1611 //restore coefficients from 8x8 transform
1612
1613 for (block = 0; block<4; block++)
1614 {
1615 memcpy (currSlice->cofAC[block][0][0],p_RDO->cofAC8x8ts[block][0][0][0], 4 * 2 * 65 * sizeof(int));
1616 }
1617
1618 if (p_Vid->P444_joined)
1619 {
1620 for (uv=0; uv<2; uv++)
1621 {
1622 for (block = 0; block<4; block++)
1623 {
1624 memcpy (currSlice->cofAC[4+block+uv*4][0][0],p_RDO->cofAC8x8ts[block][uv + 1][0][0], 4 * 2 * 65 * sizeof(int));
1625 }
1626 }
1627 }
1628
1629 //restore reconstruction
1630 if (p_RDO->tr8x8->cnt_nonz_8x8 <= _LUMA_8x8_COEFF_COST_ &&
1631 ((currMB->qp_scaled[0])!=0 || p_Vid->active_sps->lossless_qpprime_flag==0))// modif ES added last condition (we probably never go there so is the next modification useful ? check)
1632 {
1633 currMB->cbp = 0;
1634 currMB->cbp_blk = 0;
1635
1636 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], p_RDO->tr8x8->mpr8x8, currMB->pix_x, 0);
1637
1638 if(p_Inp->rdopt == 3)
1639 {
1640 p_Vid->p_decs->rec_type = 0;
1641 }
1642
1643
1644 //memset( currSlice->cofAC[0][0][0], 0, 2080 * sizeof(int)); // 4 * 4 * 2 * 65
1645
1646 if(p_Vid->P444_joined)
1647 {
1648 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
1649 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr8x8->mpr8x8CbCr[0], currMB->pix_x, 0);
1650 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr8x8->mpr8x8CbCr[1], currMB->pix_x, 0);
1651
1652 for (uv=0; uv<2; uv++)
1653 {
1654 for (block = 0; block<4; block++)
1655 {
1656 memset( currSlice->cofAC[4+block+uv*4][0][0], 0, 4 * 2 * 65 * sizeof(int));
1657 }
1658 }
1659 }
1660 }
1661 else
1662 {
1663 currMB->cbp = p_RDO->tr8x8->cbp8x8;
1664 currMB->cbp_blk = p_RDO->tr8x8->cbp_blk8x8;
1665
1666 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], p_RDO->tr8x8->rec_mbY8x8, currMB->pix_x, 0);
1667
1668 if(p_Inp->rdopt == 3)
1669 {
1670 p_Vid->p_decs->rec_type = 1;
1671 }
1672
1673
1674 if (p_Vid->P444_joined)
1675 {
1676 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = p_RDO->tr8x8->cbp8x8;
1677 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr8x8->rec_mb8x8_cr[0], currMB->pix_x, 0);
1678 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr8x8->rec_mb8x8_cr[1], currMB->pix_x, 0);
1679 }
1680 }
1681 if (p_Inp->rdopt == 3)
1682 {
1683 errdo_get_best_P8x8(currMB, 1);
1684 }
1685 }
1686 else
1687 {
1688 if (currMB->valid_8x8)
1689 {
1690 StoreMV8x8(currSlice, 1);
1691 }
1692
1693 //============= get pre-calculated data ==============
1694 //---------------------------------------------------
1695 //--- restore coefficients ---
1696 for (block = 0; block < 4; block ++)
1697 {
1698 memcpy (currSlice->cofAC[block][0][0],p_RDO->coefAC8x8[block][0][0][0], 4 * 2 * 65 * sizeof(int));
1699 }
1700
1701 if (currSlice->P444_joined)
1702 {
1703 for (block = 0; block<4; block++)
1704 {
1705 memcpy (currSlice->cofAC[block+4][0][0],p_RDO->coefAC8x8[block][1][0][0], 4 * 2 * 65 * sizeof(int));
1706 memcpy (currSlice->cofAC[block+8][0][0],p_RDO->coefAC8x8[block][2][0][0], 4 * 2 * 65 * sizeof(int));
1707 }
1708 }
1709
1710 if (((p_Inp->disthres && p_RDO->tr4x4->cnt_nonz_8x8 <= 0) || (p_RDO->tr4x4->cnt_nonz_8x8 <= 5)) &&
1711 ((currMB->qp_scaled[0])!=0 || p_Vid->active_sps->lossless_qpprime_flag==0))
1712 {
1713 currMB->cbp = 0;
1714 currMB->cbp_blk = 0;
1715
1716 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], p_RDO->tr4x4->mpr8x8, currMB->pix_x, 0);
1717
1718 if(p_Inp->rdopt == 3)
1719 {
1720 p_Vid->p_decs->rec_type = 0;
1721 }
1722
1723 if (currSlice->P444_joined)
1724 {
1725 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
1726
1727 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr4x4->mpr8x8CbCr[0], currMB->pix_x, 0);
1728 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr4x4->mpr8x8CbCr[1], currMB->pix_x, 0);
1729
1730 for (uv=0; uv<2; uv++)
1731 {
1732 for (block = 0; block<4; block++)
1733 {
1734 memset( currSlice->cofAC[4+block+uv*4][0][0], 0, 4 * 2 * 65 * sizeof(int));
1735 }
1736 }
1737 }
1738 }
1739 else
1740 {
1741 currMB->cbp = p_RDO->tr4x4->cbp8x8;
1742 currMB->cbp_blk = p_RDO->tr4x4->cbp_blk8x8;
1743
1744 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], p_RDO->tr4x4->rec_mbY8x8, currMB->pix_x, 0);
1745
1746 if(p_Inp->rdopt == 3)
1747 {
1748 p_Vid->p_decs->rec_type = 1;
1749 }
1750
1751 if (currSlice->P444_joined)
1752 {
1753 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = p_RDO->tr4x4->cbp8x8;
1754 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[0][currMB->pix_y], p_RDO->tr4x4->rec_mb8x8_cr[0], currMB->pix_x, 0);
1755 copy_image_data_16x16(&p_Vid->enc_picture->imgUV[1][currMB->pix_y], p_RDO->tr4x4->rec_mb8x8_cr[1], currMB->pix_x, 0);
1756 }
1757 }
1758 if (p_Inp->rdopt == 3)
1759 {
1760 errdo_get_best_P8x8(currMB, 0);
1761 }
1762 }
1763 }
1764
1765 /*!
1766 *************************************************************************************
1767 * \brief
1768 * Restore Non zero coefficients
1769 *************************************************************************************
1770 */
restore_nz_coeff(Macroblock * currMB)1771 void restore_nz_coeff(Macroblock *currMB)
1772 {
1773 #ifdef BEST_NZ_COEFF
1774 VideoParameters *p_Vid = currMB->p_Vid;
1775 int i, j;
1776 int **nz_coeff = p_Vid->nz_coeff[currMB->mbAddrX];
1777 for (j=0;j<4;j++)
1778 for (i=0; i<(4+p_Vid->num_blk8x8_uv); i++)
1779 nz_coeff[j][i] = p_Vid->gaaiMBAFF_NZCoeff[j][i];
1780 #endif
1781 }
1782
1783
prepare_ipcm_mode(Macroblock * currMB)1784 void prepare_ipcm_mode(Macroblock *currMB)
1785 {
1786 int i, j;
1787 VideoParameters *p_Vid = currMB->p_Vid;
1788 InputParameters *p_Inp = currMB->p_Inp;
1789 // LUMA
1790 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], &p_Vid->pCurImg[currMB->opix_y], currMB->pix_x, currMB->pix_x);
1791
1792 // CHROMA
1793 if ((p_Vid->yuv_format != YUV400) && (p_Inp->separate_colour_plane_flag == 0))
1794 {
1795 copy_image_data(&p_Vid->enc_picture->imgUV[0][currMB->pix_c_y], &p_Vid->pImgOrg[1][currMB->opix_c_y], currMB->pix_c_x, currMB->pix_c_x, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
1796 copy_image_data(&p_Vid->enc_picture->imgUV[1][currMB->pix_c_y], &p_Vid->pImgOrg[2][currMB->opix_c_y], currMB->pix_c_x, currMB->pix_c_x, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
1797 }
1798
1799 for (j=0;j<4;j++)
1800 for (i=0; i<(4+p_Vid->num_blk8x8_uv); i++)
1801 p_Vid->nz_coeff[currMB->mbAddrX][j][i] = 16;
1802 }
1803
1804 /*!
1805 *************************************************************************************
1806 * \brief
1807 * R-D Cost for a macroblock
1808 *************************************************************************************
1809 */
RDCost_for_macroblocks(Macroblock * currMB,int lambda,short mode)1810 int RDCost_for_macroblocks (Macroblock *currMB, // <-- Current Macroblock to code
1811 int lambda, // <-- lagrange multiplier
1812 short mode) // <-- mode (0-COPY/DIRECT, 1-16x16, 2-16x8, 3-8x16, 4-8x8(+), 5-Intra4x4, 6-Intra16x16)
1813 {
1814 Slice *currSlice = currMB->p_Slice;
1815 RDOPTStructure *p_RDO = currSlice->p_RDO;
1816 VideoParameters *p_Vid = currMB->p_Vid;
1817 InputParameters *p_Inp = currMB->p_Inp;
1818
1819 seq_parameter_set_rbsp_t *active_sps = p_Vid->active_sps;
1820
1821 int rate = 0, coeff_rate = 0;
1822 distblk distortion = 0;
1823 Macroblock *prevMB = currMB->PrevMB;
1824 int tmp_cc;
1825
1826 int use_of_cc = (currSlice->slice_type != I_SLICE && currSlice->slice_type != SI_SLICE && currSlice->symbol_mode == CAVLC);
1827 int cc_rate, dummy;
1828
1829 distblk rdcost;
1830 distblk dummy_d;
1831 imgpel **mb_pred = currSlice->mb_pred[0];
1832 imgpel ***curr_mpr_16x16 = currSlice->mpr_16x16[0];
1833
1834 // Test MV limits for Skip Mode. This could be necessary for MBAFF case Frame MBs.
1835 if ((currSlice->mb_aff_frame_flag) && (!currMB->mb_field) && (currSlice->slice_type == P_SLICE) && (mode==0) )
1836 {
1837 if (out_of_bounds_mvs(p_Vid, &currSlice->all_mv[LIST_0][0][0][0][0]))
1838 return 0;
1839 }
1840
1841 if (mode == P8x8)
1842 {
1843 if((currMB->luma_transform_size_8x8_flag && !currMB->valid_8x8) || (!currMB->luma_transform_size_8x8_flag && !currMB->valid_4x4))
1844 return 0;
1845 }
1846
1847 //=====
1848 //===== Set Reference Pictures and Block modes
1849 //=====
1850 currSlice->set_modes_and_refs_for_blocks (currMB, mode);
1851 //=====
1852 //===== Set Motion Vectors
1853 //=====
1854 currSlice->set_motion_vectors_mb (currMB);
1855
1856 //=====
1857 //===== Get coefficients, reconstruction values, CBP etc
1858 //=====
1859 if (mode < P8x8)
1860 {
1861 currSlice->luma_residual_coding(currMB);
1862 }
1863 else if (mode == P8x8)
1864 {
1865 currSlice->set_coeff_and_recon_8x8 (currMB);
1866 }
1867 else if (mode==I4MB)
1868 {
1869 currMB->cbp = mode_decision_for_I4x4_MB (currMB, lambda, &dummy_d);
1870 }
1871 else if (mode==I16MB)
1872 {
1873 currMB->cbp = currSlice->mode_decision_for_I16x16_MB (currMB, lambda);
1874 }
1875 else if(mode==I8MB)
1876 {
1877 currMB->cbp = mode_decision_for_I8x8_MB(currMB, lambda, &dummy_d);
1878 }
1879 else if(mode==IPCM)
1880 {
1881 prepare_ipcm_mode(currMB);
1882 }
1883
1884 //if (p_Inp->rdopt == 3)
1885 //{
1886 // // We need the reconstructed prediction residue for the simulated decoders.
1887 // compute_residue_block (currMB, &p_Vid->enc_picture->p_curr_img[currMB->pix_y], p_Vid->p_decs->res_img[0], mode == I16MB ? currSlice->mpr_16x16[0][ (short) currMB->i16mode] : currSlice->mb_pred[0], 0, 16);
1888 //}
1889
1890 //Rate control
1891 if (p_Inp->RCEnable)
1892 {
1893 if (mode == I16MB)
1894 memcpy(p_RDO->pred[0], curr_mpr_16x16[ (short) currMB->i16mode][0], MB_PIXELS * sizeof(imgpel));
1895 else
1896 memcpy(p_RDO->pred[0], mb_pred[0], MB_PIXELS * sizeof(imgpel));
1897 }
1898
1899 currMB->i16offset = 0;
1900 dummy = 0;
1901
1902 if (((p_Vid->yuv_format != YUV400) && (active_sps->chroma_format_idc != YUV444)) && (mode != IPCM))
1903 currSlice->chroma_residual_coding (currMB);
1904
1905 if (mode==I16MB)
1906 currMB->i16offset = I16Offset (currMB->cbp, currMB->i16mode);
1907
1908 //=====
1909 //===== GET DISTORTION
1910 //=====
1911 // LUMA
1912 if (p_Inp->rdopt == 3)
1913 {
1914 distortion = p_Vid->estimate_distortion(currMB, 0, 16, mode, 0, currMB->min_rdcost);
1915 //if (errdo_distortion (currMB, mode, &distortion) == 0)
1916 // return 0;
1917 }
1918 else
1919 {
1920
1921 distortion = currSlice->getDistortion(currMB);
1922 }
1923 if (distortion > currMB->min_rdcost)
1924 return 0;
1925 //printf("passed distortion %.2f %.2f\n", (double)distortion, currMB->min_rdcost);
1926
1927 if (currMB->qp_scaled[0] == 0 && p_Vid->active_sps->lossless_qpprime_flag == 1 && distortion != 0)
1928 return 0;
1929
1930 //===== S T O R E C O D I N G S T A T E =====
1931 //---------------------------------------------------
1932 currSlice->store_coding_state (currMB, currSlice->p_RDO->cs_cm);
1933
1934 //=====
1935 //===== GET RATE
1936 //=====
1937 //----- macroblock header -----
1938 if (use_of_cc)
1939 {
1940 if (currMB->mb_type!=0 || (currSlice->slice_type == B_SLICE && currMB->cbp!=0))
1941 {
1942 // cod counter and macroblock mode are written ==> do not consider code counter
1943 tmp_cc = p_Vid->cod_counter;
1944
1945 rate = currSlice->write_MB_layer (currMB, 1, &coeff_rate);
1946
1947 ue_linfo (tmp_cc, dummy, &cc_rate, &dummy);
1948 rate -= cc_rate;
1949 p_Vid->cod_counter = tmp_cc;
1950 }
1951 else
1952 {
1953 // cod counter is just increased ==> get additional rate
1954 ue_linfo (p_Vid->cod_counter + 1, dummy, &rate, &dummy);
1955 ue_linfo (p_Vid->cod_counter , dummy, &cc_rate, &dummy);
1956 rate -= cc_rate;
1957 }
1958 }
1959 else
1960 {
1961 rate = currSlice->write_MB_layer (currMB, 1, &coeff_rate);
1962 }
1963
1964 //===== R E S T O R E C O D I N G S T A T E =====
1965 //-------------------------------------------------------
1966 currSlice->reset_coding_state (currMB, currSlice->p_RDO->cs_cm);
1967
1968 if (p_Inp->ForceTrueRateRDO == 1)
1969 rdcost = distortion + weight_cost(lambda, rate);
1970 else if (p_Inp->ForceTrueRateRDO == 2)
1971 rdcost = distortion + weight_cost(lambda, (rate + is_intra(currMB)));
1972 else
1973 rdcost = distortion + (rate>0? (weight_cost(lambda, rate)): (weight_cost(lambda, 1)/2));
1974
1975 #if JCOST_OVERFLOWCHECK //overflow checking;
1976 if(rdcost < distortion)
1977 {
1978 printf("lambda: %d, rate: %d, error: %s: %d\n", lambda, rate, __FILE__, __LINE__);
1979 exit(-1);
1980 }
1981 #endif //end;
1982
1983 //
1984 if ((currSlice->slice_type != I_SLICE) && (p_Inp->BiasSkipRDO == 1) && (mode == 1) && (currMB->best_mode == 0) && (currMB->min_dcost > 4 * distortion) && (currMB->min_dcost > ((64 * (256 + 2 * p_Vid->mb_cr_size_y * p_Vid->mb_cr_size_x)) << LAMBDA_ACCURACY_BITS)))
1985 {
1986 currMB->min_rdcost = rdcost + 1;
1987 }
1988
1989 if ((rdcost >= currMB->min_rdcost) ||
1990 ((currMB->qp_scaled[0]) == 0 && p_Vid->active_sps->lossless_qpprime_flag == 1 && distortion != 0))
1991 {
1992 #if FASTMODE
1993 // Reordering RDCost comparison order of mode 0 and mode 1 in P_SLICE
1994 // if RDcost of mode 0 and mode 1 is same, we choose best_mode is 0
1995 // This might not always be good since mode 0 is more biased towards rate than quality.
1996 if((currSlice->slice_type != P_SLICE || mode != 0 || rdcost != currMB->min_rdcost) || is_FREXT_profile(p_Inp->ProfileIDC))
1997 #endif
1998 return 0;
1999 }
2000
2001
2002 if ((currSlice->mb_aff_frame_flag) && (mode ? 0: ((currSlice->slice_type == B_SLICE) ? !currMB->cbp:1))) // AFF and current is skip
2003 {
2004 if (currMB->mbAddrX & 0x01) //bottom
2005 {
2006 if (prevMB->mb_type ? 0:((currSlice->slice_type == B_SLICE) ? !prevMB->cbp:1)) //top is skip
2007 {
2008 if (!(field_flag_inference(currMB) == currMB->mb_field)) //skip only allowed when correct inference
2009 return 0;
2010 }
2011 }
2012 }
2013
2014 //===== U P D A T E M I N I M U M C O S T =====
2015 //-----------------------------------------------------
2016 currMB->min_rdcost = rdcost;
2017 currMB->min_dcost = distortion;
2018 currMB->min_rate = weight_cost(lambda, coeff_rate);
2019 currMB->min_bits = rate;
2020
2021 #ifdef BEST_NZ_COEFF
2022 for (j=0;j<4;j++)
2023 memcpy(&p_Vid->gaaiMBAFF_NZCoeff[j][0], &p_Vid->nz_coeff[currMB->mbAddrX][j][0], (4 + p_Vid->num_blk8x8_uv) * sizeof(int));
2024 #endif
2025
2026 return 1;
2027 }
2028
2029 /*!
2030 *************************************************************************************
2031 * \brief
2032 * Initialize best mode information
2033 *************************************************************************************
2034 */
init_md_best(BestMode * best)2035 void init_md_best(BestMode *best)
2036 {
2037 best->cbp = 0;
2038 best->cost = DISTBLK_MAX; //(1i64<<(20+LAMBDA_ACCURACY_BITS));
2039 best->rdcost = 1e20;
2040 best->dcost = 1e20;
2041 best->rate = 1e20;
2042 best->c_imode = 0;
2043 best->i16offset = 0;
2044 best->mode = 10;
2045 }
2046
2047 /*!
2048 *************************************************************************************
2049 * \brief
2050 * Store macroblock parameters
2051 *************************************************************************************
2052 */
store_macroblock_parameters(Macroblock * currMB,int mode)2053 void store_macroblock_parameters (Macroblock *currMB, int mode)
2054 {
2055 Slice *currSlice = currMB->p_Slice;
2056 RDOPTStructure *p_RDO = currSlice->p_RDO;
2057 VideoParameters *p_Vid = currMB->p_Vid;
2058 InputParameters *p_Inp = currMB->p_Inp;
2059 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
2060
2061 int i, j, ****i4p, ***i3p;
2062
2063 //--- store best mode ---
2064 currMB->best_mode = (short) mode;
2065 currMB->best_c_imode = currMB->c_ipred_mode;
2066 currMB->best_i16offset = currMB->i16offset;
2067 currMB->best_i16mode = currMB->i16mode;
2068 currMB->best_cbp = currMB->cbp;
2069
2070 memcpy(currSlice->p_RDO->best8x8, currMB->b8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
2071
2072 memcpy(currSlice->b4_intra_pred_modes, currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
2073 memcpy(currSlice->b8_intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
2074
2075 for (j = 0 ; j < BLOCK_MULTIPLE; j++)
2076 {
2077 memcpy(&currSlice->b4_ipredmode[j * BLOCK_MULTIPLE],&p_Vid->ipredmode [currMB->block_y + j][currMB->block_x],BLOCK_MULTIPLE * sizeof(char));
2078 memcpy(&currSlice->b8_ipredmode8x8[j][0], &p_Vid->ipredmode8x8[currMB->block_y + j][currMB->block_x],BLOCK_MULTIPLE * sizeof(char));
2079 }
2080 //--- reconstructed blocks ----
2081 copy_image_data_16x16(p_RDO->rec_mb[0], &p_Vid->enc_picture->imgY[currMB->pix_y], 0, currMB->pix_x);
2082
2083 if((currSlice->slice_type == SP_SLICE) && p_Vid->sp2_frame_indicator==0)
2084 {
2085 for (j = 0; j < MB_BLOCK_SIZE; j++)
2086 {
2087 memcpy(p_RDO->lrec_rec[j], &p_Vid->lrec[currMB->pix_y+j][currMB->pix_x], MB_BLOCK_SIZE * sizeof(int));//store coefficients SP frame
2088 }
2089 }
2090
2091 //modes 0, and 1 of a B frame
2092 if (p_Vid->AdaptiveRounding && (currSlice->slice_type == B_SLICE) && mode <= 1)
2093 {
2094 if (currMB->luma_transform_size_8x8_flag)
2095 store_adaptive_rounding_16x16( p_Vid, p_Vid->ARCofAdj8x8, mode);
2096 else
2097 store_adaptive_rounding_16x16( p_Vid, p_Vid->ARCofAdj4x4, mode);
2098 }
2099
2100 if (p_Vid->yuv_format != YUV400)
2101 {
2102 int k;
2103 for (k = 0; k < 2; k++)
2104 {
2105 copy_image_data(p_RDO->rec_mb[k + 1], &p_Vid->enc_picture->imgUV[k][currMB->pix_c_y], 0, currMB->pix_c_x, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
2106 }
2107
2108 if((currSlice->slice_type == SP_SLICE) && p_Vid->sp2_frame_indicator==0)
2109 {
2110 //store uv coefficients SP frame
2111 for (k = 0; k < 2; k++)
2112 {
2113 for (j = 0; j<p_Vid->mb_cr_size_y; j++)
2114 {
2115 memcpy(p_RDO->lrec_rec_uv[k][j],&p_Vid->lrec_uv[k][currMB->pix_c_y + j][currMB->pix_c_x], p_Vid->mb_cr_size_x * sizeof(int));
2116 }
2117 }
2118 }
2119 }
2120
2121 //--- store results of decoders ---
2122 if (p_Inp->rdopt == 3)
2123 {
2124 errdo_store_best_MB(currMB);
2125 }
2126
2127 //--- coeff, cbp, kac ---
2128 if (mode || currSlice->slice_type == B_SLICE)
2129 {
2130 i4p = p_RDO->cofAC;
2131 p_RDO->cofAC = currSlice->cofAC;
2132 currSlice->cofAC = i4p;
2133 i3p = p_RDO->cofDC;
2134 p_RDO->cofDC = currSlice->cofDC;
2135 currSlice->cofDC = i3p;
2136 p_RDO->cbp = currMB->cbp;
2137 currSlice->curr_cbp[0] = currSlice->cmp_cbp[1];
2138 currSlice->curr_cbp[1] = currSlice->cmp_cbp[2];
2139
2140 currSlice->cur_cbp_blk[0] = currMB->cbp_blk;
2141 }
2142 else
2143 {
2144 currSlice->cur_cbp_blk[0] = p_RDO->cbp = 0;
2145 currSlice->cmp_cbp[1] = currSlice->cmp_cbp[2] = 0;
2146 }
2147
2148 //--- store transform size ---
2149 currMB->temp_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
2150
2151 if (currSlice->slice_type != B_SLICE)
2152 {
2153 for (j = 0; j < 4; j++)
2154 {
2155 for (i = 0; i < 4; i++)
2156 {
2157 p_RDO->l0_refframe[j][i] = motion[currMB->block_y + j][currMB->block_x + i].ref_idx[LIST_0];
2158 }
2159 }
2160 }
2161 else
2162 {
2163 for (j = 0; j < 4; j++)
2164 {
2165 for (i = 0; i < 4; i++)
2166 {
2167 p_RDO->l0_refframe[j][i] = motion[currMB->block_y + j][currMB->block_x + i].ref_idx[LIST_0];
2168 p_RDO->l1_refframe[j][i] = motion[currMB->block_y + j][currMB->block_x + i].ref_idx[LIST_1];
2169 }
2170 }
2171 }
2172 }
2173
2174 /*!
2175 *************************************************************************************
2176 * \brief
2177 * Set stored macroblock parameters
2178 *************************************************************************************
2179 */
set_stored_macroblock_parameters_mpass(Macroblock * currMB)2180 static void set_stored_macroblock_parameters_mpass (Macroblock *currMB)
2181 {
2182 Slice *currSlice = currMB->p_Slice;
2183 RDOPTStructure *p_RDO = currSlice->p_RDO;
2184 VideoParameters *p_Vid = currMB->p_Vid;
2185 InputParameters *p_Inp = currMB->p_Inp;
2186
2187 imgpel **imgY = p_Vid->enc_picture->imgY;
2188 imgpel ***imgUV = p_Vid->enc_picture->imgUV;
2189
2190 int mode = currMB->best_mode;
2191 int i, j, k, ****i4p, ***i3p;
2192 int block_x, block_y;
2193 char **ipredmodes = p_Vid->ipredmode;
2194
2195 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
2196
2197 //===== reconstruction values =====
2198
2199 // Luma
2200 copy_image_data_16x16(&imgY[currMB->pix_y], p_RDO->rec_mb[0], currMB->pix_x, 0);
2201
2202 // Copy coding info into rddata structure for MBAFF or RDOQ
2203 copy_image_data_16x16(currSlice->rddata->rec_mb[0], p_RDO->rec_mb[0], 0, 0);
2204
2205 if((currSlice->slice_type == SP_SLICE) && p_Vid->sp2_frame_indicator==0)
2206 {
2207 for (j = 0; j < MB_BLOCK_SIZE; j++)
2208 memcpy(&p_Vid->lrec[currMB->pix_y+j][currMB->pix_x], p_RDO->lrec_rec[j], MB_BLOCK_SIZE * sizeof(int)); //restore coeff SP frame
2209 }
2210
2211 if (p_Vid->AdaptiveRounding)
2212 {
2213 update_offset_params(currMB, mode, currMB->temp_transform_size_8x8_flag);
2214 }
2215
2216 if (p_Vid->yuv_format != YUV400)
2217 {
2218 for (k = 0; k < 2; k++)
2219 {
2220 copy_image_data(&imgUV[k][currMB->pix_c_y], p_RDO->rec_mb[k + 1], currMB->pix_c_x, 0, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
2221 }
2222
2223 // Copy coding info into rddata structure for MBAFF or RDOQ
2224 copy_image_data(currSlice->rddata->rec_mb[1], p_RDO->rec_mb[1], 0, 0, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
2225 copy_image_data(currSlice->rddata->rec_mb[2], p_RDO->rec_mb[2], 0, 0, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
2226
2227 if((currSlice->slice_type == SP_SLICE) && !p_Vid->sp2_frame_indicator)
2228 {
2229 for (k = 0; k < 2; k++)
2230 {
2231 for (j = 0; j<p_Vid->mb_cr_size_y; j++)
2232 {
2233 memcpy(&p_Vid->lrec_uv[k][currMB->pix_c_y + j][currMB->pix_c_x], p_RDO->lrec_rec_uv[k][j], p_Vid->mb_cr_size_x * sizeof(int));
2234 }
2235 }
2236 }
2237 }
2238
2239 //===== coefficients and cbp =====
2240 i4p = p_RDO->cofAC;
2241 p_RDO->cofAC = currSlice->cofAC;
2242 currSlice->cofAC = i4p;
2243
2244 i3p = p_RDO->cofDC;
2245 p_RDO->cofDC = currSlice->cofDC;
2246 currSlice->cofDC = i3p;
2247 currMB->cbp = p_RDO->cbp;
2248 currMB->cbp_blk = currSlice->cur_cbp_blk[0];
2249 currMB->cbp |= currSlice->curr_cbp[0];
2250 currMB->cbp |= currSlice->curr_cbp[1];
2251 currSlice->cmp_cbp[1] = currMB->cbp;
2252 currSlice->cmp_cbp[2] = currMB->cbp;
2253
2254 //==== macroblock type ====
2255 currMB->mb_type = (short) mode;
2256
2257 memcpy(currMB->b8x8, currSlice->p_RDO->best8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
2258
2259 // Copy coding info into rddata structure for MBAFF or RDOQ
2260 currSlice->rddata->mode = mode;
2261 currSlice->rddata->i16offset = currMB->i16offset;
2262 currSlice->rddata->i16mode = currMB->i16mode;
2263 currSlice->rddata->cbp = p_RDO->cbp;
2264 currSlice->rddata->cbp_blk = currSlice->cur_cbp_blk[0];
2265 currSlice->rddata->mb_type = (short) mode;
2266
2267 currSlice->rddata->prev_qp = currMB->prev_qp;
2268 currSlice->rddata->prev_dqp = currMB->prev_dqp;
2269 currSlice->rddata->qp = currMB->qp;
2270 currSlice->rddata->prev_cbp = currMB->prev_cbp;
2271
2272 memcpy(currSlice->rddata->cofAC[0][0][0], currSlice->cofAC[0][0][0], (4+p_Vid->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
2273 memcpy(currSlice->rddata->cofDC[0][0], currSlice->cofDC[0][0], 3 * 2 * 18 * sizeof(int));
2274
2275 memcpy(currSlice->rddata->b8x8, currSlice->p_RDO->best8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
2276
2277 //if P8x8 mode and transform size 4x4 choosen, restore motion vector data for this transform size
2278 if (mode == P8x8 && !currMB->temp_transform_size_8x8_flag && p_Inp->Transform8x8Mode && (currMB->valid_8x8 == TRUE))
2279 {
2280 RestoreMV8x8(currSlice, 1);
2281 }
2282
2283 //==== transform size flag ====
2284 if (p_Vid->P444_joined)
2285 {
2286 if (((currMB->cbp == 0) && currSlice->cmp_cbp[1] == 0 && currSlice->cmp_cbp[2] == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
2287 currMB->luma_transform_size_8x8_flag = FALSE;
2288 else
2289 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
2290 }
2291 else
2292 {
2293
2294 if (((currMB->cbp & 15) == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
2295 currMB->luma_transform_size_8x8_flag = FALSE;
2296 else
2297 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
2298 }
2299
2300 currSlice->rddata->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
2301
2302 if (p_Inp->rdopt == 3)
2303 {
2304 errdo_get_best_MB(currMB);
2305 }
2306
2307 //==== reference frames =====
2308 for (j = 0; j < 4; j++)
2309 {
2310 block_y = currMB->block_y + j;
2311 for (i = 0; i < 4; i++)
2312 {
2313 block_x = currMB->block_x + i;
2314 k = 2*(j >> 1)+(i >> 1);
2315
2316 // backward prediction or intra
2317 if ((currMB->b8x8[k].pdir == 1) || is_intra(currMB))
2318 {
2319 motion[block_y][block_x].ref_idx [LIST_0] = -1;
2320 motion[block_y][block_x].mv [LIST_0] = zero_mv;
2321 motion[block_y][block_x].ref_pic [LIST_0] = NULL;
2322
2323 // MBAFF or RDOQ
2324 currSlice->rddata->refar[LIST_0][j][i] = -1;
2325 }
2326 else
2327 {
2328 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Vid, currMB->mb_type))
2329 {
2330 motion[block_y][block_x].ref_idx [LIST_0] = 0;
2331 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][0];
2332 motion[block_y][block_x].mv [LIST_0] = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_0][0][(short) currMB->b8x8[k].mode][j][i];
2333
2334 // MBAFF or RDOQ
2335 currSlice->rddata->refar[LIST_0][j][i] = 0;
2336 }
2337 else
2338 {
2339 char cur_ref = p_RDO->l0_refframe[j][i];
2340 motion[block_y][block_x].ref_idx [LIST_0] = cur_ref;
2341 if(cur_ref >=0)
2342 {
2343 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][(short)cur_ref];
2344 motion[block_y][block_x].mv [LIST_0] = currSlice->all_mv[LIST_0][(short)cur_ref][(short) currMB->b8x8[k].mode][j][i];
2345 }
2346 // MBAFF or RDOQ
2347 currSlice->rddata->refar[LIST_0][j][i] = cur_ref;
2348 }
2349 }
2350
2351 // forward prediction or intra
2352 if ((currMB->b8x8[k].pdir == 0) || is_intra(currMB))
2353 {
2354 motion[block_y][block_x].ref_idx [LIST_1] = -1;
2355 motion[block_y][block_x].ref_pic [LIST_1] = NULL;
2356 motion[block_y][block_x].mv [LIST_1] = zero_mv;
2357
2358 // MBAFF or RDOQ
2359 currSlice->rddata->refar[LIST_1][j][i] = -1;
2360 }
2361 }
2362 }
2363
2364 if (currSlice->slice_type == B_SLICE)
2365 {
2366 for (j=0; j<4; j++)
2367 {
2368 block_y = currMB->block_y + j;
2369 for (i=0; i<4; i++)
2370 {
2371 block_x = currMB->block_x + i;
2372 k = 2*(j >> 1)+(i >> 1);
2373
2374 // forward
2375 if (is_intra(currMB)||(currMB->b8x8[k].pdir == 0))
2376 {
2377 motion[block_y][block_x].ref_idx [LIST_1] = -1;
2378 motion[block_y][block_x].ref_pic [LIST_1] = NULL;
2379 motion[block_y][block_x].mv [LIST_1] = zero_mv;
2380
2381 // MBAFF or RDOQ
2382 currSlice->rddata->refar[LIST_1][j][i] = -1;
2383 }
2384 else
2385 {
2386 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Vid, currMB->mb_type))
2387 {
2388 motion[block_y][block_x].ref_idx [LIST_1] = 0;
2389 motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1 + currMB->list_offset][0];
2390 motion[block_y][block_x].mv [LIST_1] = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_1][0][(short) currMB->b8x8[k].mode][j][i];
2391
2392 // MBAFF or RDOQ
2393 currSlice->rddata->refar[LIST_1][j][i] = 0;
2394 }
2395 else
2396 {
2397 motion[block_y][block_x].ref_idx [LIST_1] = p_RDO->l1_refframe[j][i];
2398 motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1 + currMB->list_offset][(short)p_RDO->l1_refframe[j][i]];
2399 motion[block_y][block_x].mv [LIST_1] = currSlice->all_mv[LIST_1][(short)p_RDO->l1_refframe[j][i]][(short) currMB->b8x8[k].mode][j][i];
2400
2401 // MBAFF or RDOQ
2402 currSlice->rddata->refar[LIST_1][j][i] = p_RDO->l1_refframe[j][i];
2403 }
2404 }
2405 }
2406 }
2407 }
2408
2409 //==== intra prediction modes ====
2410 currMB->c_ipred_mode = currMB->best_c_imode;
2411 currMB->i16offset = currMB->best_i16offset;
2412 currMB->i16mode = currMB->best_i16mode;
2413 currMB->cbp = currMB->best_cbp;
2414
2415 if(currMB->mb_type == I8MB)
2416 {
2417 memcpy(currMB->intra_pred_modes8x8,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
2418 memcpy(currMB->intra_pred_modes ,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
2419 for(j = 0; j < BLOCK_MULTIPLE; j++)
2420 {
2421 memcpy(&p_Vid->ipredmode [currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
2422 memcpy(&p_Vid->ipredmode8x8[currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
2423 }
2424 }
2425 else if (mode!=I4MB && mode!=I8MB)
2426 {
2427 memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
2428 for(j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
2429 memset(&p_Vid->ipredmode[j][currMB->block_x], DC_PRED, BLOCK_MULTIPLE * sizeof(char));
2430 }
2431 // Residue Color Transform
2432 else if (mode == I4MB)
2433 {
2434 memcpy(currMB->intra_pred_modes,currSlice->b4_intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
2435 for(j = 0; j < BLOCK_MULTIPLE; j++)
2436 memcpy(&p_Vid->ipredmode[currMB->block_y + j][currMB->block_x],&currSlice->b4_ipredmode[BLOCK_MULTIPLE * j], BLOCK_MULTIPLE * sizeof(char));
2437 }
2438
2439 // Copy coding info into rddata structure for MBAFF or RDOQ
2440 currSlice->rddata->c_ipred_mode = currMB->c_ipred_mode;
2441 currSlice->rddata->i16offset = currMB->i16offset;
2442 currSlice->rddata->i16mode = currMB->i16mode;
2443 currSlice->rddata->cbp = currMB->cbp;
2444 currSlice->rddata->cbp_blk = currMB->cbp_blk;
2445 memcpy(currSlice->rddata->intra_pred_modes,currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
2446 memcpy(currSlice->rddata->intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
2447 for(j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
2448 memcpy(&currSlice->rddata->ipredmode[j][currMB->block_x],&ipredmodes[j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
2449
2450 //==== motion vectors =====
2451 currSlice->set_motion_vectors_mb (currMB);
2452 }
2453
2454 /*!
2455 *************************************************************************************
2456 * \brief
2457 * Set stored macroblock parameters (non RDOQ or MBAFF)
2458 *************************************************************************************
2459 */
set_stored_macroblock_parameters(Macroblock * currMB)2460 static void set_stored_macroblock_parameters (Macroblock *currMB)
2461 {
2462 Slice *currSlice = currMB->p_Slice;
2463 RDOPTStructure *p_RDO = currSlice->p_RDO;
2464 VideoParameters *p_Vid = currMB->p_Vid;
2465 InputParameters *p_Inp = currMB->p_Inp;
2466
2467 imgpel **imgY = p_Vid->enc_picture->imgY;
2468 imgpel ***imgUV = p_Vid->enc_picture->imgUV;
2469
2470 int mode = currMB->best_mode;
2471 int i, j, k, ****i4p, ***i3p;
2472 int block_x, block_y;
2473
2474 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
2475
2476 //===== reconstruction values =====
2477
2478 // Luma
2479 copy_image_data_16x16(&imgY[currMB->pix_y], p_RDO->rec_mb[0], currMB->pix_x, 0);
2480
2481 if (p_Vid->AdaptiveRounding)
2482 {
2483 update_offset_params(currMB, mode, currMB->temp_transform_size_8x8_flag);
2484 }
2485
2486 if (p_Vid->yuv_format != YUV400)
2487 {
2488 for (k = 0; k < 2; k++)
2489 {
2490 copy_image_data(&imgUV[k][currMB->pix_c_y], p_RDO->rec_mb[k + 1], currMB->pix_c_x, 0, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
2491 }
2492 }
2493
2494 //===== coefficients and cbp =====
2495 i4p = p_RDO->cofAC;
2496 p_RDO->cofAC = currSlice->cofAC;
2497 currSlice->cofAC = i4p;
2498
2499 i3p = p_RDO->cofDC;
2500 p_RDO->cofDC = currSlice->cofDC;
2501 currSlice->cofDC = i3p;
2502 currMB->cbp = p_RDO->cbp;
2503 currMB->cbp_blk = currSlice->cur_cbp_blk[0];
2504 currMB->cbp |= currSlice->curr_cbp[0];
2505 currMB->cbp |= currSlice->curr_cbp[1];
2506 currSlice->cmp_cbp[1] = currMB->cbp;
2507 currSlice->cmp_cbp[2] = currMB->cbp;
2508
2509 //==== macroblock type ====
2510 currMB->mb_type = (short) mode;
2511
2512 memcpy(currMB->b8x8, currSlice->p_RDO->best8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
2513
2514
2515 //if P8x8 mode and transform size 4x4 choosen, restore motion vector data for this transform size
2516 if (mode == P8x8 && !currMB->temp_transform_size_8x8_flag && p_Inp->Transform8x8Mode && (currMB->valid_8x8 == TRUE))
2517 {
2518 RestoreMV8x8(currSlice, 1);
2519 }
2520
2521 //==== transform size flag ====
2522 if (p_Vid->P444_joined)
2523 {
2524 if (((currMB->cbp == 0) && currSlice->cmp_cbp[1] == 0 && currSlice->cmp_cbp[2] == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
2525 currMB->luma_transform_size_8x8_flag = FALSE;
2526 else
2527 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
2528 }
2529 else
2530 {
2531
2532 if (((currMB->cbp & 15) == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
2533 currMB->luma_transform_size_8x8_flag = FALSE;
2534 else
2535 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
2536 }
2537
2538 currSlice->rddata->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
2539
2540 if (p_Inp->rdopt == 3)
2541 {
2542 errdo_get_best_MB(currMB);
2543 }
2544
2545 //==== reference frames =====
2546 for (j = 0; j < 4; j++)
2547 {
2548 block_y = currMB->block_y + j;
2549 for (i = 0; i < 4; i++)
2550 {
2551 block_x = currMB->block_x + i;
2552 k = 2*(j >> 1)+(i >> 1);
2553
2554 // backward prediction or intra
2555 if ((currMB->b8x8[k].pdir == 1) || is_intra(currMB))
2556 {
2557 motion[block_y][block_x].ref_idx [LIST_0] = -1;
2558 motion[block_y][block_x].ref_pic [LIST_0] = NULL;
2559 motion[block_y][block_x].mv [LIST_0] = zero_mv;
2560 }
2561 else
2562 {
2563 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Vid, currMB->mb_type))
2564 {
2565 motion[block_y][block_x].ref_idx [LIST_0] = 0;
2566 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][0];
2567 motion[block_y][block_x].mv [LIST_0] = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_0][0][(short) currMB->b8x8[k].mode][j][i];
2568 }
2569 else
2570 {
2571 char cur_ref = p_RDO->l0_refframe[j][i];
2572 motion[block_y][block_x].ref_idx [LIST_0] = cur_ref;
2573 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][(short)cur_ref];
2574 motion[block_y][block_x].mv [LIST_0] = currSlice->all_mv[LIST_0][(short)cur_ref][(short) currMB->b8x8[k].mode][j][i];
2575 }
2576 }
2577
2578 // forward prediction or intra
2579 if ((currMB->b8x8[k].pdir == 0) || is_intra(currMB))
2580 {
2581 motion[block_y][block_x].ref_idx [LIST_1] = -1;
2582 motion[block_y][block_x].ref_pic [LIST_1] = NULL;
2583 motion[block_y][block_x].mv [LIST_1] = zero_mv;
2584 }
2585 }
2586 }
2587
2588 if (currSlice->slice_type == B_SLICE)
2589 {
2590 for (j=0; j<4; j++)
2591 {
2592 block_y = currMB->block_y + j;
2593 for (i=0; i<4; i++)
2594 {
2595 block_x = currMB->block_x + i;
2596 k = 2*(j >> 1)+(i >> 1);
2597
2598 // forward
2599 if (is_intra(currMB)||(currMB->b8x8[k].pdir == 0))
2600 {
2601 motion[block_y][block_x].ref_idx [LIST_1] = -1;
2602 motion[block_y][block_x].ref_pic [LIST_1] = NULL;
2603 motion[block_y][block_x].mv [LIST_1] = zero_mv;
2604 }
2605 else
2606 {
2607 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Vid, currMB->mb_type))
2608 {
2609 motion[block_y][block_x].ref_idx [LIST_1] = 0;
2610 motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1 + currMB->list_offset][0];
2611 motion[block_y][block_x].mv [LIST_1] = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_1][0][(short) currMB->b8x8[k].mode][j][i];
2612 }
2613 else
2614 {
2615 motion[block_y][block_x].ref_idx [LIST_1] = p_RDO->l1_refframe[j][i];
2616 motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1 + currMB->list_offset][(short)p_RDO->l1_refframe[j][i]];
2617 motion[block_y][block_x].mv [LIST_1] = currSlice->all_mv[LIST_1][(short)p_RDO->l1_refframe[j][i]][(short) currMB->b8x8[k].mode][j][i];
2618 }
2619 }
2620 }
2621 }
2622 }
2623
2624 //==== intra prediction modes ====
2625 currMB->c_ipred_mode = currMB->best_c_imode;
2626 currMB->i16offset = currMB->best_i16offset;
2627 currMB->i16mode = currMB->best_i16mode;
2628 currMB->cbp = currMB->best_cbp;
2629
2630 if(currMB->mb_type == I8MB)
2631 {
2632 memcpy(currMB->intra_pred_modes8x8,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
2633 memcpy(currMB->intra_pred_modes ,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
2634 for(j = 0; j < BLOCK_MULTIPLE; j++)
2635 {
2636 memcpy(&p_Vid->ipredmode [currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
2637 memcpy(&p_Vid->ipredmode8x8[currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
2638 }
2639 }
2640 else if (mode!=I4MB && mode!=I8MB)
2641 {
2642 memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
2643 for(j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
2644 memset(&p_Vid->ipredmode[j][currMB->block_x], DC_PRED, BLOCK_MULTIPLE * sizeof(char));
2645 }
2646 // Residue Color Transform
2647 else if (mode == I4MB)
2648 {
2649 memcpy(currMB->intra_pred_modes,currSlice->b4_intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
2650 for(j = 0; j < BLOCK_MULTIPLE; j++)
2651 memcpy(&p_Vid->ipredmode[currMB->block_y + j][currMB->block_x],&currSlice->b4_ipredmode[BLOCK_MULTIPLE * j], BLOCK_MULTIPLE * sizeof(char));
2652 }
2653
2654 //==== motion vectors =====
2655 currSlice->set_motion_vectors_mb (currMB);
2656 }
2657
2658
2659 /*!
2660 *************************************************************************************
2661 * \brief
2662 * Set stored macroblock parameters (non RDOQ or MBAFF)
2663 *************************************************************************************
2664 */
set_stored_macroblock_parameters_sp(Macroblock * currMB)2665 static void set_stored_macroblock_parameters_sp (Macroblock *currMB)
2666 {
2667 Slice *currSlice = currMB->p_Slice;
2668 RDOPTStructure *p_RDO = currSlice->p_RDO;
2669 VideoParameters *p_Vid = currMB->p_Vid;
2670 InputParameters *p_Inp = currMB->p_Inp;
2671
2672 imgpel **imgY = p_Vid->enc_picture->imgY;
2673 imgpel ***imgUV = p_Vid->enc_picture->imgUV;
2674
2675 int mode = currMB->best_mode;
2676 int i, j, k, ****i4p, ***i3p;
2677 int block_x, block_y;
2678 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
2679
2680 //===== reconstruction values =====
2681
2682 // Luma
2683 copy_image_data_16x16(&imgY[currMB->pix_y], p_RDO->rec_mb[0], currMB->pix_x, 0);
2684
2685 if((currSlice->slice_type == SP_SLICE) && p_Vid->sp2_frame_indicator==0)
2686 {
2687 for (j = 0; j < MB_BLOCK_SIZE; j++)
2688 memcpy(&p_Vid->lrec[currMB->pix_y+j][currMB->pix_x], p_RDO->lrec_rec[j], MB_BLOCK_SIZE * sizeof(int)); //restore coeff SP frame
2689 }
2690
2691 if (p_Vid->AdaptiveRounding)
2692 {
2693 update_offset_params(currMB, mode, currMB->temp_transform_size_8x8_flag);
2694 }
2695
2696 if (p_Vid->yuv_format != YUV400)
2697 {
2698 for (k = 0; k < 2; k++)
2699 {
2700 copy_image_data(&imgUV[k][currMB->pix_c_y], p_RDO->rec_mb[k + 1], currMB->pix_c_x, 0, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
2701 }
2702
2703 if((currSlice->slice_type == SP_SLICE) && !p_Vid->sp2_frame_indicator)
2704 {
2705 for (k = 0; k < 2; k++)
2706 {
2707 for (j = 0; j<p_Vid->mb_cr_size_y; j++)
2708 {
2709 memcpy(&p_Vid->lrec_uv[k][currMB->pix_c_y + j][currMB->pix_c_x], p_RDO->lrec_rec_uv[k][j], p_Vid->mb_cr_size_x * sizeof(int));
2710 }
2711 }
2712 }
2713 }
2714
2715 //===== coefficients and cbp =====
2716 i4p = p_RDO->cofAC;
2717 p_RDO->cofAC = currSlice->cofAC;
2718 currSlice->cofAC = i4p;
2719
2720 i3p = p_RDO->cofDC;
2721 p_RDO->cofDC = currSlice->cofDC;
2722 currSlice->cofDC = i3p;
2723 currMB->cbp = p_RDO->cbp;
2724 currMB->cbp_blk = currSlice->cur_cbp_blk[0];
2725 currMB->cbp |= currSlice->curr_cbp[0];
2726 currMB->cbp |= currSlice->curr_cbp[1];
2727 currSlice->cmp_cbp[1] = currMB->cbp;
2728 currSlice->cmp_cbp[2] = currMB->cbp;
2729
2730 //==== macroblock type ====
2731 currMB->mb_type = (short) mode;
2732
2733 memcpy(currMB->b8x8, currSlice->p_RDO->best8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
2734
2735 //if P8x8 mode and transform size 4x4 choosen, restore motion vector data for this transform size
2736 if (mode == P8x8 && !currMB->temp_transform_size_8x8_flag && p_Inp->Transform8x8Mode && (currMB->valid_8x8 == TRUE))
2737 {
2738 RestoreMV8x8(currSlice, 1);
2739 }
2740
2741 //==== transform size flag ====
2742 if (p_Vid->P444_joined)
2743 {
2744 if (((currMB->cbp == 0) && currSlice->cmp_cbp[1] == 0 && currSlice->cmp_cbp[2] == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
2745 currMB->luma_transform_size_8x8_flag = FALSE;
2746 else
2747 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
2748 }
2749 else
2750 {
2751
2752 if (((currMB->cbp & 15) == 0) && (currMB->mb_type != I4MB && currMB->mb_type != I8MB))
2753 currMB->luma_transform_size_8x8_flag = FALSE;
2754 else
2755 currMB->luma_transform_size_8x8_flag = currMB->temp_transform_size_8x8_flag;
2756 }
2757
2758 currSlice->rddata->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
2759
2760 if (p_Inp->rdopt == 3)
2761 {
2762 errdo_get_best_MB(currMB);
2763 }
2764
2765 //==== reference frames =====
2766 for (j = 0; j < 4; j++)
2767 {
2768 block_y = currMB->block_y + j;
2769 for (i = 0; i < 4; i++)
2770 {
2771 block_x = currMB->block_x + i;
2772 k = 2*(j >> 1)+(i >> 1);
2773
2774 // backward prediction or intra
2775 if ((currMB->b8x8[k].pdir == 1) || is_intra(currMB))
2776 {
2777 motion[block_y][block_x].ref_idx [LIST_0] = -1;
2778 motion[block_y][block_x].ref_pic [LIST_0] = NULL;
2779 motion[block_y][block_x].mv [LIST_0] = zero_mv;
2780 }
2781 else
2782 {
2783 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Vid, currMB->mb_type))
2784 {
2785 motion[block_y][block_x].ref_idx [LIST_0] = 0;
2786 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][0];
2787 motion[block_y][block_x].mv [LIST_0] = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_0][0][(short) currMB->b8x8[k].mode][j][i];
2788 }
2789 else
2790 {
2791 char cur_ref = p_RDO->l0_refframe[j][i];
2792 motion[block_y][block_x].ref_idx [LIST_0] = cur_ref;
2793 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][(short)cur_ref];
2794 motion[block_y][block_x].mv [LIST_0] = currSlice->all_mv[LIST_0][(short)cur_ref][(short) currMB->b8x8[k].mode][j][i];
2795 }
2796 }
2797
2798 // forward prediction or intra
2799 if ((currMB->b8x8[k].pdir == 0) || is_intra(currMB))
2800 {
2801 motion[block_y][block_x].ref_idx [LIST_1] = -1;
2802 motion[block_y][block_x].ref_pic [LIST_1] = NULL;
2803 motion[block_y][block_x].mv [LIST_1] = zero_mv;
2804 }
2805 }
2806 }
2807
2808 if (currSlice->slice_type == B_SLICE)
2809 {
2810 for (j=0; j<4; j++)
2811 {
2812 block_y = currMB->block_y + j;
2813 for (i=0; i<4; i++)
2814 {
2815 block_x = currMB->block_x + i;
2816 k = 2*(j >> 1)+(i >> 1);
2817
2818 // forward
2819 if (is_intra(currMB)||(currMB->b8x8[k].pdir == 0))
2820 {
2821 motion[block_y][block_x].ref_idx [LIST_1] = -1;
2822 motion[block_y][block_x].ref_pic [LIST_1] = NULL;
2823 motion[block_y][block_x].mv [LIST_1] = zero_mv;
2824 }
2825 else
2826 {
2827 if (currMB->b8x8[k].bipred && (currMB->b8x8[k].pdir == 2) && is_bipred_enabled(p_Vid, currMB->mb_type))
2828 {
2829 motion[block_y][block_x].ref_idx [LIST_1] = 0;
2830 motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1 + currMB->list_offset][0];
2831 motion[block_y][block_x].mv [LIST_1] = currSlice->bipred_mv[currMB->b8x8[k].bipred - 1][LIST_1][0][(short) currMB->b8x8[k].mode][j][i];
2832 }
2833 else
2834 {
2835 motion[block_y][block_x].ref_idx [LIST_1] = p_RDO->l1_refframe[j][i];
2836 motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1 + currMB->list_offset][(short)p_RDO->l1_refframe[j][i]];
2837 motion[block_y][block_x].mv [LIST_1] = currSlice->all_mv[LIST_1][(short)p_RDO->l1_refframe[j][i]][(short) currMB->b8x8[k].mode][j][i];
2838 }
2839 }
2840 }
2841 }
2842 }
2843
2844 //==== intra prediction modes ====
2845 currMB->c_ipred_mode = currMB->best_c_imode;
2846 currMB->i16offset = currMB->best_i16offset;
2847 currMB->i16mode = currMB->best_i16mode;
2848 currMB->cbp = currMB->best_cbp;
2849
2850 if(currMB->mb_type == I8MB)
2851 {
2852 memcpy(currMB->intra_pred_modes8x8,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
2853 memcpy(currMB->intra_pred_modes ,currSlice->b8_intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
2854 for(j = 0; j < BLOCK_MULTIPLE; j++)
2855 {
2856 memcpy(&p_Vid->ipredmode [currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
2857 memcpy(&p_Vid->ipredmode8x8[currMB->block_y+j][currMB->block_x], currSlice->b8_ipredmode8x8[j], BLOCK_MULTIPLE * sizeof(char));
2858 }
2859 }
2860 else if (mode!=I4MB && mode!=I8MB)
2861 {
2862 memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
2863 for(j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
2864 memset(&p_Vid->ipredmode[j][currMB->block_x], DC_PRED, BLOCK_MULTIPLE * sizeof(char));
2865 }
2866 // Residue Color Transform
2867 else if (mode == I4MB)
2868 {
2869 memcpy(currMB->intra_pred_modes,currSlice->b4_intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
2870 for(j = 0; j < BLOCK_MULTIPLE; j++)
2871 memcpy(&p_Vid->ipredmode[currMB->block_y + j][currMB->block_x],&currSlice->b4_ipredmode[BLOCK_MULTIPLE * j], BLOCK_MULTIPLE * sizeof(char));
2872 }
2873
2874 //==== motion vectors =====
2875 currSlice->set_motion_vectors_mb (currMB);
2876 }
2877
2878
2879 /*!
2880 *************************************************************************************
2881 * \brief
2882 * Set reference frames and motion vectors
2883 *************************************************************************************
2884 */
set_ref_and_motion_vectors_P_slice(Macroblock * currMB,PicMotionParams ** motion,Info8x8 * part,int block)2885 void set_ref_and_motion_vectors_P_slice (Macroblock *currMB, PicMotionParams **motion, Info8x8 *part, int block)
2886 {
2887 int mode = part->mode;
2888 int j = 0, i;
2889 int pmode = (mode==1||mode==2||mode==3 ? mode : 4);
2890 int j0 = ((block >> 1)<<1);
2891 int i0 = ((block & 0x01)<<1);
2892 int i1 = i0 + part_size[pmode][0];
2893 int j1 = j0 + part_size[pmode][1];
2894 PicMotionParams *mv = NULL;
2895
2896 if (part->pdir < 0)
2897 {
2898 for (j = currMB->block_y + j0; j < currMB->block_y + j1; j++)
2899 {
2900 for (i = currMB->block_x + i0; i < currMB->block_x + i1; i++)
2901 {
2902 mv = &motion[j][i];
2903 mv->ref_pic[LIST_0] = NULL;
2904 mv->ref_pic[LIST_1] = NULL;
2905 mv->mv [LIST_0] = zero_mv;
2906 mv->mv [LIST_1] = zero_mv;
2907 mv->ref_idx[LIST_0] = -1;
2908 mv->ref_idx[LIST_1] = -1;
2909 }
2910 }
2911 return;
2912 }
2913 else
2914 {
2915 Slice *currSlice = currMB->p_Slice;
2916 int block_y;
2917 int fwref = part->ref[LIST_0];
2918 for (j = j0; j < j1; j++)
2919 {
2920 block_y = currMB->block_y + j;
2921 for (i = i0; i < i1; i++)
2922 {
2923 mv = &motion[block_y][currMB->block_x + i];
2924 mv->ref_pic[LIST_0] = currSlice->listX[LIST_0+currMB->list_offset][fwref];;
2925 mv->mv [LIST_0] = currSlice->all_mv[LIST_0][fwref][mode][j][i];
2926 mv->ref_idx[LIST_0] = (char) fwref;
2927 }
2928 }
2929 return;
2930 }
2931 }
2932
2933
2934 /*!
2935 *************************************************************************************
2936 * \brief
2937 * Set reference frames and motion vectors
2938 *************************************************************************************
2939 */
set_ref_and_motion_vectors_B_slice(Macroblock * currMB,PicMotionParams ** motion,Info8x8 * part,int block)2940 static void set_ref_and_motion_vectors_B_slice (Macroblock *currMB, PicMotionParams **motion, Info8x8 *part, int block)
2941 {
2942 int mode = part->mode;
2943 int i, j=0;
2944 int pmode = (mode==1||mode==2||mode==3 ? mode : 4);
2945 int j0 = ((block >> 1)<<1);
2946 int i0 = ((block & 0x01)<<1);
2947 int i1 = i0 + part_size[pmode][0];
2948 int j1 = j0 + part_size[pmode][1];
2949 PicMotionParams *mv = NULL;
2950
2951 if (part->pdir < 0)
2952 {
2953 for (j = currMB->block_y + j0; j < currMB->block_y + j1; j++)
2954 {
2955 for (i = currMB->block_x + i0; i < currMB->block_x + i1; i++)
2956 {
2957 mv = &motion[j][i];
2958 mv->ref_pic[LIST_0] = NULL;
2959 mv->ref_pic[LIST_1] = NULL;
2960 mv->mv [LIST_0] = zero_mv;
2961 mv->mv [LIST_1] = zero_mv;
2962 mv->ref_idx[LIST_0] = -1;
2963 mv->ref_idx[LIST_1] = -1;
2964 }
2965 }
2966 return;
2967 }
2968 else
2969 {
2970 Slice *currSlice = currMB->p_Slice;
2971 VideoParameters *p_Vid = currMB->p_Vid;
2972
2973 int block_x, block_y;
2974
2975 if ((part->pdir == 0 || part->pdir == 2))
2976 {
2977 if (part->bipred && (part->pdir == 2) && is_bipred_enabled(p_Vid, mode))
2978 {
2979 for (j=j0; j<j1; j++)
2980 {
2981 block_y = currMB->block_y + j;
2982 for (i=i0; i<i1; i++)
2983 {
2984 block_x = currMB->block_x + i;
2985
2986 motion[block_y][block_x].mv [LIST_0] = currSlice->bipred_mv[part->bipred - 1][LIST_0][0][mode][j][i];
2987 motion[block_y][block_x].ref_idx [LIST_0] = 0;
2988 motion[block_y][block_x].ref_pic [LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][0];
2989 }
2990 }
2991 }
2992 else
2993 {
2994 if (mode==0)
2995 {
2996 int fwref;
2997 for (j=j0; j<j1; j++)
2998 {
2999 block_y = currMB->block_y + j;
3000 for (i=i0; i<i1; i++)
3001 {
3002 block_x = currMB->block_x + i;
3003 fwref = currSlice->direct_ref_idx[block_y][block_x][LIST_0];
3004 motion[block_y][block_x].ref_pic[LIST_0] = currSlice->listX[LIST_0 + currMB->list_offset][fwref];
3005 motion[block_y][block_x].mv [LIST_0] = currSlice->all_mv[LIST_0][fwref][mode][j][i];
3006 motion[block_y][block_x].ref_idx[LIST_0] = (char) fwref;
3007 }
3008 }
3009 }
3010 else
3011 {
3012 int fwref = part->ref[LIST_0];
3013 for (j=j0; j<j1; j++)
3014 {
3015 block_y = currMB->block_y + j;
3016 for (i = i0; i < i1; i++)
3017 {
3018 block_x = currMB->block_x + i;
3019 motion[block_y][block_x].ref_pic[LIST_0] = currSlice->listX[LIST_0+currMB->list_offset][fwref];
3020 motion[block_y][block_x].mv [LIST_0] = currSlice->all_mv[LIST_0][fwref][mode][j][i];
3021 motion[block_y][block_x].ref_idx[LIST_0] = (char) fwref;
3022 }
3023 }
3024 }
3025 }
3026 }
3027 else
3028 {
3029 for (j=currMB->block_y + j0; j < currMB->block_y + j1; j++)
3030 {
3031 for (i = currMB->block_x + i0; i < currMB->block_x + i1; i++)
3032 {
3033 motion[j][i].ref_pic [LIST_0] = NULL;
3034 motion[j][i].mv [LIST_0] = zero_mv;
3035 motion[j][i].ref_idx [LIST_0] = -1;
3036 }
3037 }
3038 }
3039
3040
3041 if ((part->pdir==1 || part->pdir==2))
3042 {
3043 if (part->bipred && (part->pdir == 2) && is_bipred_enabled(p_Vid, mode))
3044 {
3045 for (j=j0; j<j1; j++)
3046 {
3047 block_y = currMB->block_y + j;
3048
3049 for (i=i0; i<i1; i++)
3050 {
3051 block_x = currMB->block_x + i;
3052
3053 motion[block_y][block_x].mv [LIST_1] = currSlice->bipred_mv[part->bipred - 1][LIST_1][0][mode][j][i];
3054 motion[block_y][block_x].ref_idx [LIST_1] = 0;
3055 motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1+currMB->list_offset][0];
3056 }
3057 }
3058 }
3059 else
3060 {
3061 if (mode==0)
3062 {
3063 int bwref = part->ref[LIST_1];
3064 for (j=j0; j<j1; j++)
3065 {
3066 block_y = currMB->block_y + j;
3067
3068 for (i = i0; i < i1; i++)
3069 {
3070 block_x = currMB->block_x + i;
3071 if (bwref != currSlice->direct_ref_idx[block_y][block_x][LIST_1])
3072 printf("error\n");
3073 motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1+currMB->list_offset][bwref];
3074 motion[block_y][block_x].mv [LIST_1] = currSlice->all_mv[LIST_1][bwref][mode][j][i];
3075 motion[block_y][block_x].ref_idx [LIST_1] = (char) bwref; // currSlice->direct_ref_idx[block_y][block_x][LIST_1];
3076 //motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1+currMB->list_offset][(short)motion[block_y][block_x].ref_idx [LIST_1]];
3077 }
3078 }
3079 }
3080 else
3081 {
3082 int bwref = part->ref[LIST_1];
3083 for (j=j0; j<j1; j++)
3084 {
3085 block_y = currMB->block_y + j;
3086 for (i = i0; i < i1; i++)
3087 {
3088 block_x = currMB->block_x + i;
3089
3090 motion[block_y][block_x].ref_pic [LIST_1] = currSlice->listX[LIST_1+currMB->list_offset][bwref];
3091 motion[block_y][block_x].mv [LIST_1] = currSlice->all_mv[LIST_1][bwref][mode][j][i];
3092 motion[block_y][block_x].ref_idx [LIST_1] = (char) bwref;
3093 }
3094 }
3095 }
3096 }
3097 }
3098 else
3099 {
3100 for (block_y = currMB->block_y + j0; block_y < currMB->block_y + j1; block_y++)
3101 {
3102 for (block_x = currMB->block_x + i0; block_x < currMB->block_x + i1; block_x++)
3103 {
3104 motion[block_y][block_x].ref_pic[LIST_1] = NULL;
3105 motion[block_y][block_x].mv [LIST_1] = zero_mv;
3106 motion[block_y][block_x].ref_idx[LIST_1] = -1;
3107 }
3108 }
3109 }
3110 }
3111 }
3112
3113 /*!
3114 *************************************************************************************
3115 * \brief
3116 * skip macroblock field inference
3117 * \return
3118 * inferred field flag
3119 *************************************************************************************
3120 */
field_flag_inference(Macroblock * currMB)3121 byte field_flag_inference(Macroblock *currMB)
3122 {
3123 VideoParameters *p_Vid = currMB->p_Vid;
3124 byte mb_field;
3125
3126 if (currMB->mbAvailA)
3127 {
3128 mb_field = p_Vid->mb_data[currMB->mbAddrA].mb_field;
3129 }
3130 else
3131 {
3132 // check top macroblock pair
3133 if (currMB->mbAvailB)
3134 mb_field = p_Vid->mb_data[currMB->mbAddrB].mb_field;
3135 else
3136 mb_field = 0;
3137 }
3138
3139 return mb_field;
3140 }
3141
3142 /*!
3143 *************************************************************************************
3144 * \brief
3145 * Store motion vectors for 8x8 partition
3146 *************************************************************************************
3147 */
3148
StoreMVBlock8x8(Slice * currSlice,int dir,int block8x8,int mode,Info8x8 * B8x8Info)3149 void StoreMVBlock8x8(Slice *currSlice, int dir, int block8x8, int mode, Info8x8 *B8x8Info)
3150 {
3151 RDOPTStructure *p_RDO = currSlice->p_RDO;
3152 int i0 = (block8x8 & 0x01) << 1;
3153 int j0 = (block8x8 >> 1) << 1;
3154 int j1 = j0 + 1;
3155
3156 MotionVector *****all_mv = currSlice->all_mv;
3157 MotionVector **lc_l0_mv8x8 = p_RDO->all_mv8x8[dir][LIST_0];
3158 MotionVector **lc_l1_mv8x8 = p_RDO->all_mv8x8[dir][LIST_1];
3159
3160 if (currSlice->slice_type != B_SLICE )
3161 {
3162 if (B8x8Info->pdir >= 0) //(mode8!=IBLOCK)&&(mode8!=I16MB)) // && ref != -1)
3163 {
3164 int l0_ref = B8x8Info->ref[LIST_0];
3165 memcpy(&lc_l0_mv8x8[j0][i0], &all_mv[LIST_0][l0_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3166 memcpy(&lc_l0_mv8x8[j1][i0], &all_mv[LIST_0][l0_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3167 }
3168 }
3169 else
3170 {
3171 int bipred_me = B8x8Info->bipred;
3172 int pdir8 = B8x8Info->pdir;
3173
3174 if (pdir8 == 0) // list0
3175 {
3176 int l0_ref = B8x8Info->ref[LIST_0];
3177 memcpy(&lc_l0_mv8x8[j0][i0], &all_mv[LIST_0][l0_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3178 memcpy(&lc_l0_mv8x8[j1][i0], &all_mv[LIST_0][l0_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3179 }
3180 else if (pdir8 == 1) // list1
3181 {
3182 int l1_ref = B8x8Info->ref[LIST_1];
3183 memcpy(&lc_l1_mv8x8[j0][i0], &all_mv[LIST_1][l1_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3184 memcpy(&lc_l1_mv8x8[j1][i0], &all_mv[LIST_1][l1_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3185 }
3186 else if (pdir8==2) // bipred
3187 {
3188 int l0_ref = B8x8Info->ref[LIST_0];
3189 int l1_ref = B8x8Info->ref[LIST_1];
3190 if (bipred_me)
3191 {
3192 all_mv = currSlice->bipred_mv[bipred_me - 1];
3193 }
3194
3195 memcpy(&lc_l0_mv8x8[j0][i0], &all_mv[LIST_0][l0_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3196 memcpy(&lc_l0_mv8x8[j1][i0], &all_mv[LIST_0][l0_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3197 memcpy(&lc_l1_mv8x8[j0][i0], &all_mv[LIST_1][l1_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3198 memcpy(&lc_l1_mv8x8[j1][i0], &all_mv[LIST_1][l1_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3199 }
3200 else
3201 {
3202 error("invalid direction mode", 255);
3203 }
3204 }
3205 }
3206
3207 /*!
3208 *************************************************************************************
3209 * \brief
3210 * Store motion vectors of 8x8 partitions of one macroblock
3211 *************************************************************************************
3212 */
StoreMV8x8(Slice * currSlice,int dir)3213 void StoreMV8x8(Slice *currSlice, int dir)
3214 {
3215 RDOPTStructure *p_RDO = currSlice->p_RDO;
3216 int block8x8;
3217
3218 for (block8x8=0; block8x8<4; block8x8++)
3219 StoreMVBlock8x8(currSlice, dir, block8x8, p_RDO->tr8x8->part[block8x8].mode, &p_RDO->tr8x8->part[block8x8]);
3220 }
3221
3222 /*!
3223 *************************************************************************************
3224 * \brief
3225 * Restore motion vectors for 8x8 partition
3226 *************************************************************************************
3227 */
RestoreMVBlock8x8(Slice * currSlice,int dir,int block8x8,RD_8x8DATA * tr)3228 void RestoreMVBlock8x8(Slice *currSlice, int dir, int block8x8, RD_8x8DATA *tr)
3229 {
3230 RDOPTStructure *p_RDO = currSlice->p_RDO;
3231 MotionVector *****all_mv = currSlice->all_mv;
3232 MotionVector **lc_l0_mv8x8 = p_RDO->all_mv8x8[dir][LIST_0];
3233 MotionVector **lc_l1_mv8x8 = p_RDO->all_mv8x8[dir][LIST_1];
3234
3235 short pdir8 = tr->part[block8x8].pdir;
3236 short mode = tr->part[block8x8].mode;
3237 short l0_ref = tr->part[block8x8].ref[LIST_0];
3238 short l1_ref = tr->part[block8x8].ref[LIST_1];
3239 short bipred_me = tr->part[block8x8].bipred;
3240
3241 int i0 = (block8x8 & 0x01) << 1;
3242 int j0 = (block8x8 >> 1) << 1;
3243 int j1 = j0 + 1;
3244
3245 if (currSlice->slice_type != B_SLICE)
3246 {
3247 if (pdir8>=0) //(mode8!=IBLOCK)&&(mode8!=I16MB)) // && ref != -1)
3248 {
3249 memcpy(&all_mv[LIST_0][l0_ref][4][j0][i0], &lc_l0_mv8x8[j0][i0], 2 * sizeof(MotionVector));
3250 memcpy(&all_mv[LIST_0][l0_ref][4][j1][i0], &lc_l0_mv8x8[j1][i0], 2 * sizeof(MotionVector));
3251 }
3252 }
3253 else
3254 {
3255 if (pdir8==0) // list0
3256 {
3257 memcpy(&all_mv[LIST_0][l0_ref][mode][j0][i0], &lc_l0_mv8x8[j0][i0], 2 * sizeof(MotionVector));
3258 memcpy(&all_mv[LIST_0][l0_ref][mode][j1][i0], &lc_l0_mv8x8[j1][i0], 2 * sizeof(MotionVector));
3259 }
3260 else if (pdir8==1) // list1
3261 {
3262 memcpy(&all_mv[LIST_1][l1_ref][mode][j0][i0], &lc_l1_mv8x8[j0][i0], 2 * sizeof(MotionVector));
3263 memcpy(&all_mv[LIST_1][l1_ref][mode][j1][i0], &lc_l1_mv8x8[j1][i0], 2 * sizeof(MotionVector));
3264 }
3265 else if (pdir8==2) // bipred
3266 {
3267 if(bipred_me)
3268 {
3269 all_mv = currSlice->bipred_mv[bipred_me - 1];
3270 }
3271
3272 memcpy(&all_mv[LIST_0][l0_ref][mode][j0][i0], &lc_l0_mv8x8[j0][i0], 2 * sizeof(MotionVector));
3273 memcpy(&all_mv[LIST_0][l0_ref][mode][j1][i0], &lc_l0_mv8x8[j1][i0], 2 * sizeof(MotionVector));
3274 memcpy(&all_mv[LIST_1][l1_ref][mode][j0][i0], &lc_l1_mv8x8[j0][i0], 2 * sizeof(MotionVector));
3275 memcpy(&all_mv[LIST_1][l1_ref][mode][j1][i0], &lc_l1_mv8x8[j1][i0], 2 * sizeof(MotionVector));
3276 }
3277 else
3278 {
3279 error("invalid direction mode", 255);
3280 }
3281 }
3282 }
3283
3284 /*!
3285 *************************************************************************************
3286 * \brief
3287 * Restore motion vectors of 8x8 partitions of one macroblock
3288 *************************************************************************************
3289 */
RestoreMV8x8(Slice * currSlice,int dir)3290 void RestoreMV8x8(Slice *currSlice, int dir)
3291 {
3292 RDOPTStructure *p_RDO = currSlice->p_RDO;
3293 int block8x8;
3294
3295 for (block8x8=0; block8x8<4; block8x8++)
3296 RestoreMVBlock8x8(currSlice, dir, block8x8, p_RDO->tr8x8);
3297 }
3298
3299
3300 /*!
3301 *************************************************************************************
3302 * \brief
3303 * Store predictors for 8x8 partition
3304 *************************************************************************************
3305 */
StoreNewMotionVectorsBlock8x8(Slice * currSlice,int dir,int block8x8,Info8x8 * B8x8Info)3306 void StoreNewMotionVectorsBlock8x8(Slice *currSlice, int dir, int block8x8, Info8x8 *B8x8Info)
3307 {
3308 RDOPTStructure *p_RDO = currSlice->p_RDO;
3309 int mode = B8x8Info->mode;
3310 int i0 = (block8x8 & 0x01) << 1;
3311 int j0 = (block8x8 >> 1) << 1;
3312 int j1 = j0 + 1;
3313
3314 MotionVector ****all_mv_l0 = currSlice->all_mv[LIST_0];
3315 MotionVector ****all_mv_l1 = currSlice->all_mv[LIST_1];
3316 MotionVector **lc_l0_mv8x8 = &p_RDO->all_mv8x8[dir][LIST_0][j0];
3317 MotionVector **lc_l1_mv8x8 = &p_RDO->all_mv8x8[dir][LIST_1][j0];
3318
3319
3320 if (B8x8Info->pdir < 0)
3321 {
3322 memset(&lc_l0_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3323 memset(&lc_l0_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3324 memset(&lc_l1_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3325 memset(&lc_l1_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3326 return;
3327 }
3328
3329 if (currSlice->slice_type != B_SLICE)
3330 {
3331 int l0_ref = B8x8Info->ref[LIST_0];
3332 memcpy(&lc_l0_mv8x8[0][i0], &all_mv_l0[l0_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3333 memcpy(&lc_l0_mv8x8[1][i0], &all_mv_l0[l0_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3334 memset(&lc_l1_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3335 memset(&lc_l1_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3336 return;
3337 }
3338 else
3339 {
3340 int bipred_me = B8x8Info->bipred;
3341 int pdir8 = B8x8Info->pdir;
3342 if (bipred_me)
3343 {
3344 all_mv_l0 = currSlice->bipred_mv[bipred_me - 1][LIST_0];
3345 all_mv_l1 = currSlice->bipred_mv[bipred_me - 1][LIST_1];
3346 }
3347
3348 if ((pdir8==0 || pdir8==2))
3349 {
3350 int l0_ref = B8x8Info->ref[LIST_0];
3351 memcpy(&lc_l0_mv8x8[0][i0], &all_mv_l0[l0_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3352 memcpy(&lc_l0_mv8x8[1][i0], &all_mv_l0[l0_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3353 }
3354 else
3355 {
3356 memset(&lc_l0_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3357 memset(&lc_l0_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3358 }
3359
3360 if ((pdir8==1 || pdir8==2))
3361 {
3362 int l1_ref = B8x8Info->ref[LIST_1];
3363 memcpy(&lc_l1_mv8x8[0][i0], &all_mv_l1[l1_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3364 memcpy(&lc_l1_mv8x8[1][i0], &all_mv_l1[l1_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3365 }
3366 else
3367 {
3368 memset(&lc_l1_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3369 memset(&lc_l1_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3370 }
3371 }
3372 }
3373
3374
3375 /*!
3376 *************************************************************************************
3377 * \brief
3378 * Store predictors for 8x8 partition
3379 *************************************************************************************
3380 */
store_8x8_motion_vectors_p_slice(Slice * currSlice,int dir,int block8x8,Info8x8 * B8x8Info)3381 void store_8x8_motion_vectors_p_slice(Slice *currSlice, int dir, int block8x8, Info8x8 *B8x8Info)
3382 {
3383 RDOPTStructure *p_RDO = currSlice->p_RDO;
3384
3385 int i0 = (block8x8 & 0x01) << 1;
3386 int j0 = (block8x8 >> 1) << 1;
3387
3388 MotionVector **lc_l0_mv8x8 = &p_RDO->all_mv8x8[dir][LIST_0][j0];
3389 MotionVector **lc_l1_mv8x8 = &p_RDO->all_mv8x8[dir][LIST_1][j0];
3390
3391 if (B8x8Info->pdir < 0)
3392 {
3393 memset(&lc_l0_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3394 memset(&lc_l0_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3395 memset(&lc_l1_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3396 memset(&lc_l1_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3397 }
3398 else
3399 {
3400 int j1 = j0 + 1;
3401 MotionVector **all_mv_l0 = currSlice->all_mv[LIST_0][(short) B8x8Info->ref[LIST_0]][(short)B8x8Info->mode];
3402 memcpy(&lc_l0_mv8x8[0][i0], &all_mv_l0[j0][i0], 2 * sizeof(MotionVector));
3403 memcpy(&lc_l0_mv8x8[1][i0], &all_mv_l0[j1][i0], 2 * sizeof(MotionVector));
3404 memset(&lc_l1_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3405 memset(&lc_l1_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3406 }
3407 }
3408
3409
3410 /*!
3411 *************************************************************************************
3412 * \brief
3413 * Store predictors for 8x8 partition
3414 *************************************************************************************
3415 */
store_8x8_motion_vectors_b_slice(Slice * currSlice,int dir,int block8x8,Info8x8 * B8x8Info)3416 void store_8x8_motion_vectors_b_slice(Slice *currSlice, int dir, int block8x8, Info8x8 *B8x8Info)
3417 {
3418 RDOPTStructure *p_RDO = currSlice->p_RDO;
3419 int i0 = (block8x8 & 0x01) << 1;
3420 int j0 = (block8x8 >> 1) << 1;
3421
3422 MotionVector **lc_l0_mv8x8 = &p_RDO->all_mv8x8[dir][LIST_0][j0];
3423 MotionVector **lc_l1_mv8x8 = &p_RDO->all_mv8x8[dir][LIST_1][j0];
3424
3425 if (B8x8Info->pdir < 0)
3426 {
3427 memset(&lc_l0_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3428 memset(&lc_l0_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3429 memset(&lc_l1_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3430 memset(&lc_l1_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3431 }
3432 else
3433 {
3434 int mode = B8x8Info->mode;
3435 int j1 = j0 + 1;
3436 MotionVector ****all_mv_l0 = currSlice->all_mv[LIST_0];
3437 MotionVector ****all_mv_l1 = currSlice->all_mv[LIST_1];
3438
3439 int bipred_me = B8x8Info->bipred;
3440 int pdir8 = B8x8Info->pdir;
3441 if (bipred_me)
3442 {
3443 all_mv_l0 = currSlice->bipred_mv[bipred_me - 1][LIST_0];
3444 all_mv_l1 = currSlice->bipred_mv[bipred_me - 1][LIST_1];
3445 }
3446
3447 if ((pdir8==0 || pdir8==2))
3448 {
3449 int l0_ref = B8x8Info->ref[LIST_0];
3450 memcpy(&lc_l0_mv8x8[0][i0], &all_mv_l0[l0_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3451 memcpy(&lc_l0_mv8x8[1][i0], &all_mv_l0[l0_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3452 }
3453 else
3454 {
3455 memset(&lc_l0_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3456 memset(&lc_l0_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3457 }
3458
3459 if ((pdir8==1 || pdir8==2))
3460 {
3461 int l1_ref = B8x8Info->ref[LIST_1];
3462 memcpy(&lc_l1_mv8x8[0][i0], &all_mv_l1[l1_ref][mode][j0][i0], 2 * sizeof(MotionVector));
3463 memcpy(&lc_l1_mv8x8[1][i0], &all_mv_l1[l1_ref][mode][j1][i0], 2 * sizeof(MotionVector));
3464 }
3465 else
3466 {
3467 memset(&lc_l1_mv8x8[0][i0], 0, 2 * sizeof(MotionVector));
3468 memset(&lc_l1_mv8x8[1][i0], 0, 2 * sizeof(MotionVector));
3469 }
3470 }
3471 }
3472
3473
3474 /*!
3475 ************************************************************************
3476 * \brief
3477 * Sets MBAFF RD parameters
3478 ************************************************************************
3479 */
set_mbaff_parameters(Macroblock * currMB)3480 void set_mbaff_parameters(Macroblock *currMB)
3481 {
3482 VideoParameters *p_Vid = currMB->p_Vid;
3483 InputParameters *p_Inp = currMB->p_Inp;
3484 Slice *currSlice = currMB->p_Slice;
3485
3486 int j, i;
3487 int mode = currMB->best_mode;
3488 char **ipredmodes = p_Vid->ipredmode;
3489 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
3490 RD_DATA *rdopt = currSlice->rddata;
3491
3492
3493 //===== reconstruction values =====
3494 copy_image_data_16x16(rdopt->rec_mb[0], &p_Vid->enc_picture->imgY[currMB->pix_y], 0, currMB->pix_x);
3495
3496 if (p_Vid->yuv_format != YUV400)
3497 {
3498 copy_image_data(rdopt->rec_mb[1], &p_Vid->enc_picture->imgUV[0][currMB->pix_c_y], 0, currMB->pix_c_x, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
3499 copy_image_data(rdopt->rec_mb[2], &p_Vid->enc_picture->imgUV[1][currMB->pix_c_y], 0, currMB->pix_c_x, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
3500 }
3501
3502 //===== coefficients and cbp =====
3503 rdopt->mode = mode;
3504 rdopt->i16offset = currMB->i16offset;
3505 rdopt->i16mode = currMB->i16mode;
3506 rdopt->cbp = currMB->cbp;
3507 rdopt->cbp_blk = currMB->cbp_blk;
3508 rdopt->mb_type = currMB->mb_type;
3509
3510 rdopt->luma_transform_size_8x8_flag = currMB->luma_transform_size_8x8_flag;
3511
3512 if(rdopt->mb_type == 0 && mode != 0)
3513 {
3514 mode=0;
3515 rdopt->mode=0;
3516 }
3517
3518 memcpy(rdopt->cofAC[0][0][0], currSlice->cofAC[0][0][0], (4+p_Vid->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
3519 memcpy(rdopt->cofDC[0][0], currSlice->cofDC[0][0], 3 * 2 * 18 * sizeof(int));
3520
3521 memcpy(rdopt->b8x8, currMB->b8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
3522
3523 //==== reference frames =====
3524 if (currSlice->slice_type == B_SLICE)
3525 {
3526 if (p_Inp->BiPredMERefinements == 1)
3527 {
3528 int k;
3529 for (j = 0; j < BLOCK_MULTIPLE; j++)
3530 {
3531 for (i = 0; i < BLOCK_MULTIPLE; i++)
3532 {
3533 k = 2*(j >> 1)+(i >> 1);
3534 if (currMB->b8x8[k].bipred == 0)
3535 {
3536 rdopt->refar[LIST_0][j][i] = motion[currMB->block_y + j][currMB->block_x + i].ref_idx[LIST_0];
3537 rdopt->refar[LIST_1][j][i] = motion[currMB->block_y + j][currMB->block_x + i].ref_idx[LIST_1];
3538 }
3539 else
3540 {
3541 rdopt->refar[LIST_0][j][i] = 0;
3542 rdopt->refar[LIST_1][j][i] = 0;
3543 }
3544 }
3545 }
3546 }
3547 else
3548 {
3549 for (j = 0; j < BLOCK_MULTIPLE; j++)
3550 {
3551 for (i = 0; i < BLOCK_MULTIPLE; i++)
3552 {
3553 rdopt->refar[LIST_0][j][i] = motion[currMB->block_y + j][currMB->block_x + i].ref_idx[LIST_0];
3554 rdopt->refar[LIST_1][j][i] = motion[currMB->block_y + j][currMB->block_x + i].ref_idx[LIST_1];
3555 }
3556 }
3557 }
3558 }
3559 else
3560 {
3561 for (j = 0; j < BLOCK_MULTIPLE; j++)
3562 {
3563 for (i = 0; i < BLOCK_MULTIPLE; i++)
3564 {
3565 rdopt->refar[LIST_0][j][i] = motion[currMB->block_y + j][currMB->block_x + i].ref_idx[LIST_0];
3566 //rdopt->refar[LIST_1][j][i] = motion[currMB->block_y + j][currMB->block_x + i].ref_idx[LIST_1];
3567 }
3568 }
3569 }
3570
3571 memcpy(rdopt->intra_pred_modes, currMB->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
3572 memcpy(rdopt->intra_pred_modes8x8,currMB->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
3573 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
3574 {
3575 memcpy(&rdopt->ipredmode[j][currMB->block_x],&ipredmodes[j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
3576 }
3577 }
3578
3579
assign_enc_picture_params(Macroblock * currMB,int mode,Info8x8 * best,int block)3580 void assign_enc_picture_params (Macroblock *currMB, int mode, Info8x8 *best, int block)
3581 {
3582 int i,j;
3583 int block_y, block_x;
3584 int list;
3585 MotionVector **curr_mv = NULL;
3586 int list_offset = currMB->list_offset;
3587 VideoParameters *p_Vid = currMB->p_Vid;
3588 Slice *currSlice = currMB->p_Slice;
3589 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
3590 int maxlist = (currSlice->slice_type == B_SLICE) ? 1: 0;
3591 StorablePicture *listX = NULL;
3592
3593 int start_x = 0, start_y = 0, end_x = BLOCK_MULTIPLE, end_y = BLOCK_MULTIPLE;
3594
3595 switch (mode)
3596 {
3597 case 1:
3598 start_x = 0;
3599 start_y = 0;
3600 end_x = BLOCK_MULTIPLE;
3601 end_y = BLOCK_MULTIPLE;
3602 break;
3603 case 2:
3604 start_x = 0;
3605 start_y = block;
3606 end_x = BLOCK_MULTIPLE;
3607 end_y = block + 2;
3608 break;
3609 case 3:
3610 start_x = block;
3611 start_y = 0;
3612 end_x = block + 2;
3613 end_y = BLOCK_MULTIPLE;
3614 break;
3615 case 4: //P8x8
3616 default:
3617 start_x = ((block>>1) & 0x01)* 2;
3618 start_y = ((block>>1) & 0x02);
3619 end_x = start_x + 2;
3620 end_y = start_y + 2;
3621 break;
3622 }
3623
3624 for (list = 0; list <= maxlist; list++)
3625 {
3626 if ((best->pdir != 2) && (best->pdir != list))
3627 {
3628 for (j = currMB->block_y + start_y; j < currMB->block_y + end_y; j++)
3629 {
3630 for (i = currMB->block_x + start_x; i < currMB->block_x + end_x; i++)
3631 {
3632 motion[j][i].ref_pic[list] = NULL;
3633 motion[j][i].mv[list] = zero_mv;
3634 motion[j][i].ref_idx[list] = - 1;
3635 }
3636 }
3637 }
3638 else
3639 {
3640 switch (best->bipred)
3641 {
3642 case 0:
3643 {
3644 int bestref = best->ref[list];
3645 curr_mv = currSlice->all_mv[list][bestref][mode];
3646 listX = currSlice->listX[list + list_offset][bestref];
3647 }
3648 break;
3649 case 1:
3650 curr_mv = currSlice->bipred_mv[0][list][0][mode] ; //best->ref[LIST_0] has to be zero in this case
3651 listX = currSlice->listX[list + list_offset][0];
3652 break;
3653 case 2:
3654 curr_mv = currSlice->bipred_mv[1][list][0][mode] ; //best->ref[LIST_0] has to be zero in this case
3655 listX = currSlice->listX[list + list_offset][0];
3656 break;
3657 default:
3658 break;
3659 }
3660
3661 for (j = start_y; j < end_y; j++)
3662 {
3663 block_y = currMB->block_y + j;
3664 for (i = start_x; i < end_x; i++)
3665 {
3666 block_x = currMB->block_x + i;
3667 motion[block_y][block_x].ref_pic [list] = listX;
3668 motion[block_y][block_x].mv [list] = curr_mv[j][i];
3669 }
3670 }
3671 }
3672 }
3673 }
3674
3675 /*!
3676 *************************************************************************************
3677 * \brief
3678 * Set block 8x8 mode information
3679 *************************************************************************************
3680 */
set_block8x8_info(Block8x8Info * b8x8info,int mode,int block,Info8x8 * best)3681 void set_block8x8_info(Block8x8Info *b8x8info, int mode, int block, Info8x8 *best)
3682 {
3683 //----- set reference frame and direction parameters -----
3684 if (mode==3)
3685 {
3686 b8x8info->best[3][block ] = *best;
3687 b8x8info->best[3][block+2] = *best;
3688 }
3689 else if (mode==2)
3690 {
3691 b8x8info->best[2][2*block ] = *best;
3692 b8x8info->best[2][2*block + 1] = *best;
3693 }
3694 else if (mode==1)
3695 {
3696 b8x8info->best[1][0] = *best;
3697 b8x8info->best[1][1] = *best;
3698 b8x8info->best[1][2] = *best;
3699 b8x8info->best[1][3] = *best;
3700
3701 }
3702 else //P8x8
3703 {
3704 b8x8info->best[mode][block] = *best;
3705 }
3706 }
3707
3708 /*!
3709 *************************************************************************************
3710 * \brief
3711 * Set block 8x8 mode information for P8x8 mode
3712 *************************************************************************************
3713 */
set_subblock8x8_info(Block8x8Info * b8x8info,int mode,int block,RD_8x8DATA * tr)3714 void set_subblock8x8_info(Block8x8Info *b8x8info,int mode, int block, RD_8x8DATA *tr)
3715 {
3716 b8x8info->best [mode][block] = tr->part[block];
3717 }
3718
3719
3720
update_refresh_map(Macroblock * currMB,int intra,int intra1)3721 void update_refresh_map(Macroblock *currMB, int intra, int intra1)
3722 {
3723 VideoParameters *p_Vid = currMB->p_Vid;
3724 InputParameters *p_Inp = currMB->p_Inp;
3725
3726 if (p_Inp->RestrictRef==1)
3727 {
3728 // Modified for Fast Mode Decision. Inchoon Choi, SungKyunKwan Univ.
3729 if (p_Inp->rdopt<2)
3730 {
3731 p_Vid->refresh_map[2*currMB->mb_y ][2*currMB->mb_x ] = (byte) (intra ? 1 : 0);
3732 p_Vid->refresh_map[2*currMB->mb_y ][2*currMB->mb_x+1] = (byte) (intra ? 1 : 0);
3733 p_Vid->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x ] = (byte) (intra ? 1 : 0);
3734 p_Vid->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x+1] = (byte) (intra ? 1 : 0);
3735 }
3736 else if (p_Inp->rdopt == 3)
3737 {
3738 p_Vid->refresh_map[2*currMB->mb_y ][2*currMB->mb_x ] = (byte) (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
3739 p_Vid->refresh_map[2*currMB->mb_y ][2*currMB->mb_x+1] = (byte) (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
3740 p_Vid->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x ] = (byte) (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
3741 p_Vid->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x+1] = (byte) (intra1==0 && (currMB->mb_type==I16MB || currMB->mb_type==I4MB) ? 1 : 0);
3742 }
3743 }
3744 else if (p_Inp->RestrictRef==2)
3745 {
3746 p_Vid->refresh_map[2*currMB->mb_y ][2*currMB->mb_x ] = (byte) (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
3747 p_Vid->refresh_map[2*currMB->mb_y ][2*currMB->mb_x+1] = (byte) (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
3748 p_Vid->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x ] = (byte) (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
3749 p_Vid->refresh_map[2*currMB->mb_y + 1][2*currMB->mb_x+1] = (byte) (currMB->mb_type==I16MB || currMB->mb_type==I4MB ? 1 : 0);
3750 }
3751 }
3752
valid_intra_mode(Slice * currSlice,int ipmode)3753 int valid_intra_mode(Slice *currSlice, int ipmode)
3754 {
3755 InputParameters *p_Inp = currSlice->p_Inp;
3756
3757 if (p_Inp->IntraDisableInterOnly==0 || (currSlice->slice_type != I_SLICE && currSlice->slice_type != SI_SLICE))
3758 {
3759 if (p_Inp->Intra4x4ParDisable && (ipmode==VERT_PRED||ipmode==HOR_PRED))
3760 return 0;
3761
3762 if (p_Inp->Intra4x4DiagDisable && (ipmode==DIAG_DOWN_LEFT_PRED||ipmode==DIAG_DOWN_RIGHT_PRED))
3763 return 0;
3764
3765 if (p_Inp->Intra4x4DirDisable && ipmode>=VERT_RIGHT_PRED)
3766 return 0;
3767 }
3768 return 1;
3769 }
3770
compute_sad4x4_cost(VideoParameters * p_Vid,imgpel ** cur_img,imgpel ** prd_img,int pic_opix_x,distblk min_cost)3771 distblk compute_sad4x4_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, distblk min_cost)
3772 {
3773 imgpel *cur_line, *prd_line;
3774 int i32Cost = 0;
3775 int imin_cost = dist_down(min_cost);
3776
3777 int j;
3778 for (j = 0; j < BLOCK_SIZE; j++)
3779 {
3780 cur_line = &cur_img[j][pic_opix_x];
3781 prd_line = prd_img[j];
3782
3783 i32Cost += iabs(cur_line[0] - prd_line[0]);
3784 i32Cost += iabs(cur_line[1] - prd_line[1]);
3785 i32Cost += iabs(cur_line[2] - prd_line[2]);
3786 i32Cost += iabs(cur_line[3] - prd_line[3]);
3787
3788 if (i32Cost > imin_cost)
3789 {
3790 return(min_cost);
3791 }
3792 }
3793 return dist_scale(i32Cost);
3794 }
3795
compute_sse4x4_cost(VideoParameters * p_Vid,imgpel ** cur_img,imgpel ** prd_img,int pic_opix_x,distblk min_cost)3796 distblk compute_sse4x4_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, distblk min_cost)
3797 {
3798 int j, i;
3799 imgpel *cur_line, *prd_line;
3800 int i32Cost = 0;
3801 int imin_cost = dist_down(min_cost);
3802 for (j = 0; j < BLOCK_SIZE; j++)
3803 {
3804 cur_line = &cur_img[j][pic_opix_x];
3805 prd_line = prd_img[j];
3806 for (i = 0; i < BLOCK_SIZE; i++)
3807 {
3808 i32Cost += iabs2(*cur_line++ - *prd_line++);
3809 }
3810
3811 if (i32Cost > imin_cost)
3812 {
3813 return(min_cost);
3814 }
3815 }
3816 return dist_scale(i32Cost);
3817 }
3818
compute_satd4x4_cost(VideoParameters * p_Vid,imgpel ** cur_img,imgpel ** prd_img,int pic_opix_x,distblk min_cost)3819 distblk compute_satd4x4_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, distblk min_cost)
3820 {
3821 int j, i;
3822 imgpel *cur_line, *prd_line;
3823 short diff[16];
3824
3825 short *d = &diff[0];
3826
3827 for (j = 0; j < BLOCK_SIZE; j++)
3828 {
3829 cur_line = &cur_img[j][pic_opix_x];
3830 prd_line = prd_img[j];
3831
3832 for (i = 0; i < BLOCK_SIZE; i++)
3833 {
3834 *d++ = *cur_line++ - *prd_line++;
3835 }
3836 }
3837
3838 return dist_scale(HadamardSAD4x4 (diff));
3839 }
3840
compute_comp4x4_cost(VideoParameters * p_Vid,imgpel ** cur_img,imgpel ** prd_img,int pic_opix_x,distblk min_cost)3841 static distblk compute_comp4x4_cost(VideoParameters *p_Vid, imgpel **cur_img, imgpel **prd_img, int pic_opix_x, distblk min_cost)
3842 {
3843 int j, i;
3844 imgpel *cur_line, *prd_line;
3845 short diff[16];
3846
3847 short *d = &diff[0];
3848
3849 for (j = 0; j < BLOCK_SIZE; j++)
3850 {
3851 cur_line = &cur_img[j][pic_opix_x];
3852 prd_line = prd_img[j];
3853
3854 for (i = 0; i < BLOCK_SIZE; i++)
3855 {
3856 *d++ = *cur_line++ - *prd_line++;
3857 }
3858 }
3859 return(p_Vid->distortion4x4 (diff, min_cost));
3860 }
3861
3862
3863
update_qp_cbp_tmp(Macroblock * currMB,int cbp)3864 void update_qp_cbp_tmp(Macroblock *currMB, int cbp)
3865 {
3866 if (((cbp!=0 || currMB->best_mode==I16MB) && (currMB->best_mode!=IPCM) ))
3867 currMB->prev_cbp = 1;
3868 else if ((cbp==0) || (currMB->best_mode==IPCM))
3869 {
3870 currMB->prev_cbp = 0;
3871 currMB->qp = currMB->prev_qp;
3872 currMB->p_Vid->qp = currMB->qp;
3873 update_qp(currMB);
3874 }
3875 }
3876
3877 /*!
3878 *************************************************************************************
3879 * \brief
3880 * Update QP Parameters (in case of SKIP MBs or MBAFF)
3881 *************************************************************************************
3882 */
3883
update_qp_cbp(Macroblock * currMB)3884 void update_qp_cbp(Macroblock *currMB)
3885 {
3886 VideoParameters *p_Vid = currMB->p_Vid;
3887 InputParameters *p_Inp = currMB->p_Inp;
3888
3889 // delta_qp is present only for non-skipped macroblocks
3890 if ((currMB->cbp!=0 || currMB->best_mode == I16MB) && (currMB->best_mode != IPCM))
3891 currMB->prev_cbp = 1;
3892 else
3893 {
3894 currMB->prev_cbp = 0;
3895 currMB->qp = currMB->prev_qp;
3896 p_Vid->qp = currMB->qp;
3897 update_qp(currMB);
3898 }
3899
3900 if (p_Inp->MbInterlace)
3901 {
3902 Slice *currSlice = currMB->p_Slice;
3903 // update rdopt buffered qps...
3904 currSlice->rddata->qp = currMB->qp;
3905 currSlice->rddata->prev_cbp = currMB->prev_cbp;
3906 }
3907 }
3908
3909 /*!
3910 ***************************************************************************
3911 // For MB level field/frame coding
3912 ***************************************************************************
3913 */
copy_rdopt_data(Macroblock * currMB)3914 void copy_rdopt_data (Macroblock *currMB)
3915 {
3916 Slice *currSlice = currMB->p_Slice;
3917 VideoParameters *p_Vid = currMB->p_Vid;
3918 PicMotionParams **motion = p_Vid->enc_picture->mv_info;
3919 int i, j;
3920 RD_DATA *rdopt = currSlice->rddata;
3921
3922 int mode;
3923 short b8mode, b8pdir;
3924 int block_y;
3925
3926 int list_offset = currMB->list_offset;
3927
3928 mode = rdopt->mode;
3929 currMB->mb_type = rdopt->mb_type; // copy mb_type
3930 currMB->cbp = rdopt->cbp; // copy cbp
3931 currMB->cbp_blk = rdopt->cbp_blk; // copy cbp_blk
3932 currMB->i16offset = rdopt->i16offset;
3933 currMB->i16mode = rdopt->i16mode;
3934
3935 currMB->prev_qp = rdopt->prev_qp;
3936 currMB->prev_dqp = rdopt->prev_dqp;
3937 currMB->prev_cbp = rdopt->prev_cbp;
3938 currMB->qp = rdopt->qp;
3939 update_qp (currMB);
3940
3941 currMB->c_ipred_mode = rdopt->c_ipred_mode;
3942
3943 memcpy(currSlice->cofAC[0][0][0],rdopt->cofAC[0][0][0], (4 + p_Vid->num_blk8x8_uv) * 4 * 2 * 65 * sizeof(int));
3944 memcpy(currSlice->cofDC[0][0],rdopt->cofDC[0][0], 3 * 2 * 18 * sizeof(int));
3945
3946 for (j = 0; j < BLOCK_MULTIPLE; j++)
3947 {
3948 block_y = currMB->block_y + j;
3949 for (i = 0; i < BLOCK_MULTIPLE; i++)
3950 {
3951 motion[block_y][currMB->block_x + i].ref_idx [LIST_0] = rdopt->refar[LIST_0][j][i];
3952 motion[block_y][currMB->block_x + i].ref_pic [LIST_0] = rdopt->refar[LIST_0][j][i] < 0 ? NULL :
3953 currSlice->listX[LIST_0 + list_offset][(short)rdopt->refar[LIST_0][j][i]];
3954 }
3955 }
3956
3957 if (currSlice->slice_type == B_SLICE)
3958 {
3959 for (j = 0; j < BLOCK_MULTIPLE; j++)
3960 {
3961 block_y = currMB->block_y + j;
3962 for (i = 0; i < BLOCK_MULTIPLE; i++)
3963 {
3964 motion[block_y][currMB->block_x + i].ref_idx [LIST_1] = rdopt->refar[LIST_1][j][i];
3965 motion[block_y][currMB->block_x + i].ref_pic [LIST_1] = rdopt->refar[LIST_1][j][i] < 0 ? NULL :
3966 currSlice->listX[LIST_1 + list_offset][(short) rdopt->refar[LIST_1][j][i]];
3967 }
3968 }
3969 }
3970
3971
3972 //===== reconstruction values =====
3973 copy_image_data_16x16(&p_Vid->enc_picture->imgY[currMB->pix_y], rdopt->rec_mb[0], currMB->pix_x, 0);
3974
3975 if (p_Vid->yuv_format != YUV400)
3976 {
3977 copy_image_data(&p_Vid->enc_picture->imgUV[0][currMB->pix_c_y], rdopt->rec_mb[1], currMB->pix_c_x, 0, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
3978 copy_image_data(&p_Vid->enc_picture->imgUV[1][currMB->pix_c_y], rdopt->rec_mb[2], currMB->pix_c_x, 0, p_Vid->mb_cr_size_x, p_Vid->mb_cr_size_y);
3979 }
3980
3981
3982 memcpy(currMB->b8x8, rdopt->b8x8, BLOCK_MULTIPLE * sizeof(Info8x8));
3983
3984 currMB->luma_transform_size_8x8_flag = rdopt->luma_transform_size_8x8_flag;
3985
3986 //==== intra prediction modes ====
3987 if (mode == P8x8)
3988 {
3989 memcpy(currMB->intra_pred_modes,rdopt->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
3990 for (j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
3991 memcpy(&p_Vid->ipredmode[j][currMB->block_x],&rdopt->ipredmode[j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
3992 }
3993 else if (mode != I4MB && mode != I8MB)
3994 {
3995 memset(currMB->intra_pred_modes,DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
3996 for (j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
3997 memset(&p_Vid->ipredmode[j][currMB->block_x],DC_PRED, BLOCK_MULTIPLE * sizeof(char));
3998 }
3999 else if (mode == I4MB || mode == I8MB)
4000 {
4001 memcpy(currMB->intra_pred_modes,rdopt->intra_pred_modes, MB_BLOCK_PARTITIONS * sizeof(char));
4002 memcpy(currMB->intra_pred_modes8x8,rdopt->intra_pred_modes8x8, MB_BLOCK_PARTITIONS * sizeof(char));
4003 for (j = currMB->block_y; j < currMB->block_y + BLOCK_MULTIPLE; j++)
4004 {
4005 memcpy(&p_Vid->ipredmode[j][currMB->block_x],&rdopt->ipredmode[j][currMB->block_x], BLOCK_MULTIPLE * sizeof(char));
4006 }
4007 }
4008
4009 if (currSlice->mb_aff_frame_flag || (currSlice->UseRDOQuant && currSlice->RDOQ_QP_Num > 1))
4010 {
4011 // motion vectors
4012 if (currSlice->slice_type != I_SLICE && currSlice->slice_type != SI_SLICE)
4013 copy_motion_vectors_MB (currSlice, rdopt);
4014
4015 if (!is_intra(currMB))
4016 {
4017 currMB->b8x8[0].bipred = 0;
4018 currMB->b8x8[1].bipred = 0;
4019 currMB->b8x8[2].bipred = 0;
4020 currMB->b8x8[3].bipred = 0;
4021
4022 for (j = 0; j < 4; j++)
4023 {
4024 for (i = 0; i < 4; i++)
4025 {
4026 b8mode = currMB->b8x8[(i >> 1) + 2 * (j >> 1)].mode;
4027 b8pdir = currMB->b8x8[(i >> 1) + 2 * (j >> 1)].pdir;
4028
4029 if (b8pdir!=1)
4030 {
4031 motion[j+currMB->block_y][i+currMB->block_x].mv[LIST_0] = rdopt->all_mv[LIST_0][(short)rdopt->refar[LIST_0][j][i]][b8mode][j][i];
4032 }
4033 else
4034 {
4035 motion[j+currMB->block_y][i+currMB->block_x].mv[LIST_0] = zero_mv;
4036 }
4037 if (currSlice->slice_type == B_SLICE)
4038 {
4039 if (b8pdir!=0)
4040 {
4041 motion[j+currMB->block_y][i+currMB->block_x].mv[LIST_1] = rdopt->all_mv[LIST_1][(short)rdopt->refar[LIST_1][j][i]][b8mode][j][i];
4042 }
4043 else
4044 {
4045 motion[j+currMB->block_y][i+currMB->block_x].mv[LIST_1] = zero_mv;
4046 }
4047 }
4048 }
4049 }
4050 }
4051 else
4052 {
4053
4054 if (currSlice->slice_type == B_SLICE)
4055 {
4056 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
4057 {
4058 for (i = currMB->block_x; i < currMB->block_x + 4; i++)
4059 {
4060 motion[j][i].mv[LIST_0] = zero_mv;
4061 motion[j][i].mv[LIST_1] = zero_mv;
4062 }
4063 }
4064 }
4065 else
4066 {
4067 for (j = currMB->block_y; j < currMB->block_y + 4; j++)
4068 {
4069 for (i = currMB->block_x; i < currMB->block_x + 4; i++)
4070 {
4071 motion[j][i].mv[LIST_0] = zero_mv;
4072 }
4073 }
4074 }
4075 }
4076 }
4077 } // end of copy_rdopt_data
4078
4079
4080
4081