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