1 
2 /*!
3  *************************************************************************************
4  * \file mv_direct.c
5  *
6  * \brief
7  *    Direct Motion Vector Generation
8  *
9  * \author
10  *    Main contributors (see contributors.h for copyright, address and affiliation details)
11  *      - Alexis Michael Tourapis         <alexismt@ieee.org>
12  *
13  *************************************************************************************
14 */
15 
16 #include "contributors.h"
17 
18 #include <math.h>
19 #include <limits.h>
20 #include <time.h>
21 
22 #include "global.h"
23 
24 #include "image.h"
25 #include "mv_search.h"
26 #include "refbuf.h"
27 #include "memalloc.h"
28 #include "mb_access.h"
29 #include "macroblock.h"
30 #include "mc_prediction.h"
31 #include "conformance.h"
32 #include "mode_decision.h"
33 
34 /*!
35  ************************************************************************
36  * \brief
37  *    Calculate Temporal Direct Mode Motion Vectors
38  ************************************************************************
39  */
Get_Direct_MV_Temporal(Macroblock * currMB)40 void Get_Direct_MV_Temporal (Macroblock *currMB)
41 {
42   Slice *currSlice = currMB->p_Slice;
43   int   block_x, block_y, pic_block_x, pic_block_y, opic_block_x, opic_block_y;
44   MotionVector *****all_mvs;
45   int   mv_scale;
46   int refList;
47   int ref_idx;
48   VideoParameters *p_Vid = currMB->p_Vid;
49   int list_offset = currMB->list_offset;
50 
51   StorablePicture **list1 = currSlice->listX[LIST_1 + list_offset];
52 
53   PicMotionParams colocated;
54 
55   //temporal direct mode copy from decoder
56   for (block_y = 0; block_y < 4; block_y++)
57   {
58     pic_block_y  = currMB->block_y + block_y;
59     opic_block_y = (currMB->opix_y >> 2) + block_y;
60 
61     for (block_x = 0; block_x < 4; block_x++)
62     {
63       pic_block_x  = currMB->block_x + block_x;
64       opic_block_x = (currMB->pix_x>>2) + block_x;
65 
66       all_mvs = currSlice->all_mv;
67       if (p_Vid->active_sps->direct_8x8_inference_flag)
68       {
69         if(currMB->p_Inp->separate_colour_plane_flag && currMB->p_Vid->yuv_format==YUV444)
70           colocated = list1[0]->JVmv_info[currMB->p_Slice->colour_plane_id][RSD(opic_block_y)][RSD(opic_block_x)];
71         else
72           colocated = list1[0]->mv_info[RSD(opic_block_y)][RSD(opic_block_x)];
73         if(currSlice->mb_aff_frame_flag && currMB->mb_field && currSlice->listX[LIST_1][0]->coded_frame)
74         {
75           int iPosBlkY;
76           if(currSlice->listX[LIST_1][0]->motion.mb_field[currMB->mbAddrX] )
77             iPosBlkY = (opic_block_y>>2)*8+4*(currMB->mbAddrX&1)+(opic_block_y&0x03);
78           else
79             iPosBlkY = RSD(opic_block_y)*2;
80 
81           if(colocated.ref_idx[LIST_0]>=0)
82             colocated.ref_pic[LIST_0] = list1[0]->frame->mv_info[iPosBlkY][RSD(opic_block_x)].ref_pic[LIST_0];
83           if(colocated.ref_idx[LIST_1]>=0)
84             colocated.ref_pic[LIST_1] = list1[0]->frame->mv_info[iPosBlkY][RSD(opic_block_x)].ref_pic[LIST_1];
85         }
86       }
87       else
88       {
89         if(currMB->p_Inp->separate_colour_plane_flag && currMB->p_Vid->yuv_format==YUV444)
90           colocated = list1[0]->JVmv_info[currMB->p_Slice->colour_plane_id][opic_block_y][opic_block_x];
91         else
92           colocated = list1[0]->mv_info[opic_block_y][opic_block_x];
93       }
94       if(currSlice->mb_aff_frame_flag)
95       {
96         if(!currMB->mb_field && ((currSlice->listX[LIST_1][0]->coded_frame && currSlice->listX[LIST_1][0]->motion.mb_field[currMB->mbAddrX]) ||
97           (!currSlice->listX[LIST_1][0]->coded_frame)))
98         {
99           if (iabs(p_Vid->enc_picture->poc - currSlice->listX[LIST_1+4][0]->poc)> iabs(p_Vid->enc_picture->poc -currSlice->listX[LIST_1+2][0]->poc) )
100           {
101             if ( p_Vid->active_sps->direct_8x8_inference_flag)
102             {
103               if(currMB->p_Inp->separate_colour_plane_flag && currMB->p_Vid->yuv_format==YUV444)
104                 colocated = currSlice->listX[LIST_1+2][0]->JVmv_info[currMB->p_Slice->colour_plane_id][RSD(opic_block_y)>>1][RSD(opic_block_x)];
105               else
106                 colocated = currSlice->listX[LIST_1+2][0]->mv_info[RSD(opic_block_y)>>1][RSD(opic_block_x)];
107             }
108             else
109             {
110               if(currMB->p_Inp->separate_colour_plane_flag && currMB->p_Vid->yuv_format==YUV444)
111                 colocated = currSlice->listX[LIST_1+2][0]->JVmv_info[currMB->p_Slice->colour_plane_id][(opic_block_y)>>1][(opic_block_x)];
112               else
113                 colocated = currSlice->listX[LIST_1+2][0]->mv_info[(opic_block_y)>>1][opic_block_x];
114             }
115             if(currSlice->listX[LIST_1][0]->coded_frame)
116             {
117               int iPosBlkY = (RSD(opic_block_y)>>3)*8 + ((RSD(opic_block_y)>>1) & 0x03);
118               if(colocated.ref_idx[LIST_0] >=0) // && !colocated.ref_pic[LIST_0])
119                 colocated.ref_pic[LIST_0] = currSlice->listX[LIST_1+2][0]->frame->mv_info[iPosBlkY][RSD(opic_block_x)].ref_pic[LIST_0];
120               if(colocated.ref_idx[LIST_1] >=0) // && !colocated.ref_pic[LIST_1])
121                 colocated.ref_pic[LIST_1] = currSlice->listX[LIST_1+2][0]->frame->mv_info[iPosBlkY][RSD(opic_block_x)].ref_pic[LIST_1];
122             }
123           }
124           else
125           {
126             if (p_Vid->active_sps->direct_8x8_inference_flag )
127             {
128               if(currMB->p_Inp->separate_colour_plane_flag && currMB->p_Vid->yuv_format==YUV444)
129                 colocated = currSlice->listX[LIST_1+4][0]->JVmv_info[currMB->p_Slice->colour_plane_id][RSD(opic_block_y)>>1][RSD(opic_block_x)];
130               else
131                 colocated = currSlice->listX[LIST_1+4][0]->mv_info[RSD(opic_block_y)>>1][RSD(opic_block_x)];
132 
133             }
134             else
135             {
136               if(currMB->p_Inp->separate_colour_plane_flag && currMB->p_Vid->yuv_format==YUV444)
137                 colocated = currSlice->listX[LIST_1+4][0]->JVmv_info[currMB->p_Slice->colour_plane_id][(opic_block_y)>>1][opic_block_x];
138               else
139                 colocated = currSlice->listX[LIST_1+4][0]->mv_info[(opic_block_y)>>1][opic_block_x];
140             }
141             if(currSlice->listX[LIST_1][0]->coded_frame)
142             {
143               int iPosBlkY = (RSD(opic_block_y)>>3)*8 + ((RSD(opic_block_y)>>1) & 0x03)+4;
144               if(colocated.ref_idx[LIST_0] >=0) // && !colocated.ref_pic[LIST_0])
145                 colocated.ref_pic[LIST_0] = currSlice->listX[LIST_1+4][0]->frame->mv_info[iPosBlkY][RSD(opic_block_x)].ref_pic[LIST_0];
146               if(colocated.ref_idx[LIST_1] >=0)// && !colocated.ref_pic[LIST_1])
147                 colocated.ref_pic[LIST_1] = currSlice->listX[LIST_1+4][0]->frame->mv_info[iPosBlkY][RSD(opic_block_x)].ref_pic[LIST_1];
148             }
149           }
150         }
151       }
152       else if(!p_Vid->active_sps->frame_mbs_only_flag && !currSlice->structure && !currSlice->listX[LIST_1][0]->coded_frame)
153       {
154         if (iabs(p_Vid->enc_picture->poc - list1[0]->bottom_field->poc)> iabs(p_Vid->enc_picture->poc -list1[0]->top_field->poc) )
155         {
156           colocated = p_Vid->active_sps->direct_8x8_inference_flag ?
157             list1[0]->top_field->mv_info[RSD(opic_block_y)>>1][RSD(opic_block_x)] : list1[0]->top_field->mv_info[(opic_block_y)>>1][opic_block_x];
158         }
159         else
160         {
161           colocated = p_Vid->active_sps->direct_8x8_inference_flag ?
162             list1[0]->bottom_field->mv_info[RSD(opic_block_y)>>1][RSD(opic_block_x)] : list1[0]->bottom_field->mv_info[(opic_block_y)>>1][opic_block_x];
163         }
164       }
165       else if(!p_Vid->active_sps->frame_mbs_only_flag && currSlice->structure && list1[0]->coded_frame)
166       {
167         int iPosBlkY;
168         int currentmb = 2*(list1[0]->size_x>>4) * (opic_block_y >> 2)+ (opic_block_x>>2)*2 + ((opic_block_y>>1) & 0x01);
169         if(currSlice->structure!=list1[0]->structure)
170         {
171           if (currSlice->structure == TOP_FIELD)
172           {
173             colocated = p_Vid->active_sps->direct_8x8_inference_flag ?
174               list1[0]->frame->top_field->mv_info[RSD(opic_block_y)][RSD(opic_block_x)] : list1[0]->frame->top_field->mv_info[opic_block_y][opic_block_x];
175           }
176           else
177           {
178             colocated = p_Vid->active_sps->direct_8x8_inference_flag ?
179               list1[0]->frame->bottom_field->mv_info[RSD(opic_block_y)][RSD(opic_block_x)] : list1[0]->frame->bottom_field->mv_info[opic_block_y][opic_block_x];
180           }
181         }
182 
183         if(!currSlice->listX[LIST_1][0]->frame->mb_aff_frame_flag || !list1[0]->frame->motion.mb_field[currentmb])
184           iPosBlkY = 2*(RSD(opic_block_y));
185         else
186           iPosBlkY = (RSD(opic_block_y)>>2)*8 + (RSD(opic_block_y) & 0x03)+4*(currSlice->structure == BOTTOM_FIELD);
187         if(colocated.ref_idx[LIST_0] >=0) // && !colocated.ref_pic[LIST_0])
188           colocated.ref_pic[LIST_0] = list1[0]->frame->mv_info[iPosBlkY][RSD(opic_block_x)].ref_pic[LIST_0];
189         if(colocated.ref_idx[LIST_1] >=0)// && !colocated.ref_pic[LIST_1])
190           colocated.ref_pic[LIST_1] = list1[0]->frame->mv_info[iPosBlkY][RSD(opic_block_x)].ref_pic[LIST_1];
191       }
192 
193       refList = ((colocated.ref_idx[LIST_0] == -1 || (p_Vid->view_id && colocated.ref_idx[LIST_0]==list1[0]->ref_pic_na[0]))? LIST_1 : LIST_0);
194       ref_idx = colocated.ref_idx[refList];
195 
196       // next P is intra mode
197       if (ref_idx == -1 || (p_Vid->view_id && ref_idx==list1[0]->ref_pic_na[refList]))
198       {
199         all_mvs[LIST_0][0][0][block_y][block_x] = zero_mv;
200         all_mvs[LIST_1][0][0][block_y][block_x] = zero_mv;
201         currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_0] = 0;
202         currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_1] = 0;
203         currSlice->direct_pdir[pic_block_y][pic_block_x] = 2;
204       }
205       // next P is skip or inter mode
206       else
207       {
208         int mapped_idx=INVALIDINDEX;
209         int iref;
210         if (colocated.ref_pic[refList] == NULL)
211         {
212            printf("invalid index found\n");
213         }
214         else
215         {
216           if( (currSlice->mb_aff_frame_flag && ( (currMB->mb_field && colocated.ref_pic[refList]->structure==FRAME) ||
217             (!currMB->mb_field && colocated.ref_pic[refList]->structure!=FRAME))) ||
218             (!currSlice->mb_aff_frame_flag && ((currSlice->structure==FRAME && colocated.ref_pic[refList]->structure!=FRAME)||
219             (currSlice->structure!=FRAME && colocated.ref_pic[refList]->structure==FRAME))) )
220           {
221             //! Frame with field co-located
222             for (iref = 0; iref < imin(currSlice->num_ref_idx_active[LIST_0], currSlice->listXsize[LIST_0 + list_offset]); iref++)
223             {
224               if (currSlice->listX[LIST_0 + list_offset][iref]->top_field == colocated.ref_pic[refList] ||
225                 currSlice->listX[LIST_0 + list_offset][iref]->bottom_field == colocated.ref_pic[refList] ||
226                 currSlice->listX[LIST_0 + list_offset][iref]->frame == colocated.ref_pic[refList] )
227               {
228                 if ((p_Vid->field_picture==1) && (currSlice->listX[LIST_0 + list_offset][iref]->structure != currSlice->structure))
229                 {
230                   mapped_idx=INVALIDINDEX;
231                 }
232                 else
233                 {
234                   mapped_idx = iref;
235                   break;
236                 }
237               }
238               else //! invalid index. Default to zero even though this case should not happen
239                 mapped_idx=INVALIDINDEX;
240             }
241           }
242           else
243           {
244             for (iref = 0; iref < imin(currSlice->num_ref_idx_active[LIST_0], currSlice->listXsize[LIST_0 + list_offset]);iref++)
245             {
246               if(currSlice->listX[LIST_0 + list_offset][iref] == colocated.ref_pic[refList])
247               {
248                 mapped_idx = iref;
249                 break;
250               }
251               else //! invalid index. Default to zero even though this case should not happen
252               {
253                 mapped_idx=INVALIDINDEX;
254               }
255             }
256           }
257         }
258         if (mapped_idx != INVALIDINDEX)
259         {
260           MotionVector mv = colocated.mv[refList];
261           mv_scale = currSlice->mvscale[LIST_0 + list_offset][mapped_idx];
262 
263           if((currSlice->mb_aff_frame_flag && !currMB->mb_field && colocated.ref_pic[refList]->structure!=FRAME) ||
264             (!currSlice->mb_aff_frame_flag && currSlice->structure==FRAME && colocated.ref_pic[refList]->structure!=FRAME))
265             mv.mv_y *= 2;
266           else if((currSlice->mb_aff_frame_flag && currMB->mb_field && colocated.ref_pic[refList]->structure==FRAME) ||
267             (!currSlice->mb_aff_frame_flag && currSlice->structure!=FRAME && colocated.ref_pic[refList]->structure==FRAME))
268             mv.mv_y /= 2;
269 
270           if (mv_scale==9999)
271           {
272             // forward
273             all_mvs[LIST_0][0][0][block_y][block_x] = mv;
274             // backward
275             all_mvs[LIST_1][0][0][block_y][block_x] = zero_mv;
276           }
277           else
278           {
279             // forward
280             all_mvs[LIST_0][mapped_idx][0][block_y][block_x].mv_x = (short) ((mv_scale * mv.mv_x + 128) >> 8);
281             all_mvs[LIST_0][mapped_idx][0][block_y][block_x].mv_y = (short) ((mv_scale * mv.mv_y + 128) >> 8);
282             // backward
283             all_mvs[LIST_1][         0][0][block_y][block_x].mv_x = (short) (((mv_scale - 256) * mv.mv_x + 128) >> 8);
284             all_mvs[LIST_1][         0][0][block_y][block_x].mv_y = (short) (((mv_scale - 256) * mv.mv_y + 128) >> 8);
285 
286           }
287 
288           // Test Level Limits if satisfied.
289           if ( out_of_bounds_mvs(p_Vid, &all_mvs[LIST_0][mapped_idx][0][block_y][block_x])|| out_of_bounds_mvs(p_Vid, &all_mvs[LIST_1][0][0][block_y][block_x]))
290           {
291             currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_0] = -1;
292             currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_1] = -1;
293             currSlice->direct_pdir[pic_block_y][pic_block_x] = -1;
294           }
295           else
296           {
297             currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_0] = (char) mapped_idx;
298             currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_1] = 0;
299             currSlice->direct_pdir[pic_block_y][pic_block_x] = 2;
300           }
301         }
302         else
303         {
304           currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_0] = -1;
305           currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_1] = -1;
306           currSlice->direct_pdir[pic_block_y][pic_block_x] = -1;
307         }
308       }
309 
310       if (p_Vid->active_pps->weighted_bipred_idc == 1 && currSlice->direct_pdir[pic_block_y][pic_block_x] == 2)
311       {
312         int weight_sum, i;
313         short l0_refX = currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_0];
314         short l1_refX = currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_1];
315         for (i=0;i< (p_Vid->active_sps->chroma_format_idc == YUV400 ? 1 : 3); i++)
316         {
317           weight_sum = currSlice->wbp_weight[0][l0_refX][l1_refX][i] + currSlice->wbp_weight[1][l0_refX][l1_refX][i];
318           if (weight_sum < -128 ||  weight_sum > 127)
319           {
320             currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_0] = -1;
321             currSlice->direct_ref_idx[pic_block_y][pic_block_x][LIST_1] = -1;
322             currSlice->direct_pdir   [pic_block_y][pic_block_x]         = -1;
323             break;
324           }
325         }
326       }
327     }
328   }
329 }
330 
set_direct_references(const PixelPos * mb,char * l0_rFrame,char * l1_rFrame,PicMotionParams ** mv_info)331 static inline void set_direct_references(const PixelPos *mb, char *l0_rFrame, char *l1_rFrame, PicMotionParams **mv_info)
332 {
333   if (mb->available)
334   {
335     char *ref_idx = mv_info[mb->pos_y][mb->pos_x].ref_idx;
336     *l0_rFrame  = ref_idx[LIST_0];
337     *l1_rFrame  = ref_idx[LIST_1];
338   }
339   else
340   {
341     *l0_rFrame  = -1;
342     *l1_rFrame  = -1;
343   }
344 }
345 
set_direct_references_mb_field(const PixelPos * mb,char * l0_rFrame,char * l1_rFrame,PicMotionParams ** mv_info,Macroblock * mb_data)346 static void set_direct_references_mb_field(const PixelPos *mb, char *l0_rFrame, char *l1_rFrame, PicMotionParams **mv_info, Macroblock *mb_data)
347 {
348   if (mb->available)
349   {
350     char *ref_idx = mv_info[mb->pos_y][mb->pos_x].ref_idx;
351     if (mb_data[mb->mb_addr].mb_field)
352     {
353       *l0_rFrame  = ref_idx[LIST_0];
354       *l1_rFrame  = ref_idx[LIST_1];
355     }
356     else
357     {
358       *l0_rFrame  = (ref_idx[LIST_0] < 0) ? ref_idx[LIST_0] : ref_idx[LIST_0] * 2;
359       *l1_rFrame  = (ref_idx[LIST_1] < 0) ? ref_idx[LIST_1] : ref_idx[LIST_1] * 2;
360     }
361   }
362   else
363   {
364     *l0_rFrame  = -1;
365     *l1_rFrame  = -1;
366   }
367 }
368 
set_direct_references_mb_frame(const PixelPos * mb,char * l0_rFrame,char * l1_rFrame,PicMotionParams ** mv_info,Macroblock * mb_data)369 static void set_direct_references_mb_frame(const PixelPos *mb, char *l0_rFrame, char *l1_rFrame, PicMotionParams **mv_info, Macroblock *mb_data)
370 {
371   if (mb->available)
372   {
373     char *ref_idx = mv_info[mb->pos_y][mb->pos_x].ref_idx;
374     if (mb_data[mb->mb_addr].mb_field)
375     {
376       *l0_rFrame  = (ref_idx[LIST_0] >> 1);
377       *l1_rFrame  = (ref_idx[LIST_1] >> 1);
378     }
379     else
380     {
381       *l0_rFrame  = ref_idx[LIST_0];
382       *l1_rFrame  = ref_idx[LIST_1];
383     }
384   }
385   else
386   {
387     *l0_rFrame  = -1;
388     *l1_rFrame  = -1;
389   }
390 }
391 
test_valid_direct(Slice * currSlice,seq_parameter_set_rbsp_t * active_sps,char * direct_ref_idx,short l0_refX,short l1_refX,int pic_block_y,int pic_block_x)392 static void test_valid_direct(Slice *currSlice, seq_parameter_set_rbsp_t *active_sps, char  *direct_ref_idx, short l0_refX, short l1_refX, int pic_block_y, int pic_block_x)
393 {
394   int weight_sum, i;
395   Boolean invalid_wp = FALSE;
396   for (i=0;i< (active_sps->chroma_format_idc == YUV400 ? 1 : 3); i++)
397   {
398     weight_sum = currSlice->wbp_weight[0][l0_refX][l1_refX][i] + currSlice->wbp_weight[1][l0_refX][l1_refX][i];
399     if (weight_sum < -128 ||  weight_sum > 127)
400     {
401       invalid_wp = TRUE;
402       break;
403     }
404   }
405   if (invalid_wp == FALSE)
406     currSlice->direct_pdir[pic_block_y][pic_block_x] = 2;
407   else
408   {
409     direct_ref_idx[LIST_0] = -1;
410     direct_ref_idx[LIST_1] = -1;
411     currSlice->direct_pdir[pic_block_y][pic_block_x] = -1;
412   }
413 }
414 
415 /*!
416 *************************************************************************************
417 * \brief
418 *    Temporary function for colocated info when direct_inference is enabled.
419 *
420 *************************************************************************************
421 */
get_colocated_info(Macroblock * currMB,StorablePicture * list1,int i,int j)422 int get_colocated_info(Macroblock *currMB, StorablePicture *list1, int i, int j)
423 {
424   if (list1->is_long_term)
425     return 1;
426   else
427   {
428     Slice *currSlice = currMB->p_Slice;
429     VideoParameters *p_Vid = currMB->p_Vid;
430     if( (currSlice->mb_aff_frame_flag) ||
431       (!p_Vid->active_sps->frame_mbs_only_flag && ((!currSlice->structure && !list1->coded_frame) || (currSlice->structure!=list1->structure && list1->coded_frame))))
432     {
433       int jj = RSD(j);
434       int ii = RSD(i);
435       int jdiv = (jj>>1);
436       int moving;
437       PicMotionParams *fs = &list1->mv_info[jj][ii];
438 
439       if(currSlice->structure && currSlice->structure!=list1->structure && list1->coded_frame)
440       {
441          if(currSlice->structure == TOP_FIELD)
442            fs = list1->top_field->mv_info[jj] + ii;
443          else
444            fs = list1->bottom_field->mv_info[jj] + ii;
445       }
446       else
447       {
448         if( (currSlice->mb_aff_frame_flag && ((!currMB->mb_field && list1->motion.mb_field[currMB->mbAddrX]) ||
449           (!currMB->mb_field && !list1->coded_frame)))
450           || (!currSlice->mb_aff_frame_flag))
451         {
452           if (iabs(p_Vid->enc_picture->poc - list1->bottom_field->poc)> iabs(p_Vid->enc_picture->poc -list1->top_field->poc) )
453           {
454             fs = list1->top_field->mv_info[jdiv] + ii;
455           }
456           else
457           {
458             fs = list1->bottom_field->mv_info[jdiv] + ii;
459           }
460         }
461       }
462       moving = !((((fs->ref_idx[LIST_0] == 0)
463         &&  (iabs(fs->mv[LIST_0].mv_x)>>1 == 0)
464         &&  (iabs(fs->mv[LIST_0].mv_y)>>1 == 0)))
465         || ((fs->ref_idx[LIST_0] == -1)
466         &&  (fs->ref_idx[LIST_1] == 0)
467         &&  (iabs(fs->mv[LIST_1].mv_x)>>1 == 0)
468         &&  (iabs(fs->mv[LIST_1].mv_y)>>1 == 0)));
469       return moving;
470     }
471     else
472     {
473       PicMotionParams *fs = &list1->mv_info[RSD(j)][RSD(i)];
474       int moving;
475       if(currMB->p_Vid->yuv_format == YUV444 && !currSlice->P444_joined)
476         fs = &list1->JVmv_info[(int)(p_Vid->colour_plane_id)][RSD(j)][RSD(i)];
477       moving= !((((fs->ref_idx[LIST_0] == 0)
478         &&  (iabs(fs->mv[LIST_0].mv_x)>>1 == 0)
479         &&  (iabs(fs->mv[LIST_0].mv_y)>>1 == 0)))
480         || ((fs->ref_idx[LIST_0] == -1)
481         &&  (fs->ref_idx[LIST_1] == 0)
482         &&  (iabs(fs->mv[LIST_1].mv_x)>>1 == 0)
483         &&  (iabs(fs->mv[LIST_1].mv_y)>>1 == 0)));
484 
485       return moving;
486     }
487   }
488 }
489 
490 /*!
491 *************************************************************************************
492 * \brief
493 *    Colocated info <= direct_inference is disabled.
494 *************************************************************************************
495 */
get_colocated_info_4x4(Macroblock * currMB,StorablePicture * list1,int i,int j)496 int get_colocated_info_4x4(Macroblock *currMB, StorablePicture *list1, int i, int j)
497 {
498   if (list1->is_long_term)
499     return 1;
500   else
501   {
502     PicMotionParams *fs = &list1->mv_info[j][i];
503 
504     int moving = !((((fs->ref_idx[LIST_0] == 0)
505       &&  (iabs(fs->mv[LIST_0].mv_x)>>1 == 0)
506       &&  (iabs(fs->mv[LIST_0].mv_y)>>1 == 0)))
507       || ((fs->ref_idx[LIST_0] == -1)
508       &&  (fs->ref_idx[LIST_1] == 0)
509       &&  (iabs(fs->mv[LIST_1].mv_x)>>1 == 0)
510       &&  (iabs(fs->mv[LIST_1].mv_y)>>1 == 0)));
511 
512     return moving;
513   }
514 }
515 
516 /*!
517 ************************************************************************
518 * \brief
519 *    Calculate Spatial Direct Mode Motion Vectors
520 ************************************************************************
521 */
Get_Direct_MV_Spatial_Normal(Macroblock * currMB)522 void Get_Direct_MV_Spatial_Normal (Macroblock *currMB)
523 {
524   Slice *currSlice = currMB->p_Slice;
525   VideoParameters *p_Vid = currMB->p_Vid;
526   PicMotionParams **mv_info = p_Vid->enc_picture->mv_info;
527   char l0_refA, l0_refB, l0_refC;
528   char l1_refA, l1_refB, l1_refC;
529   char l0_refX,l1_refX;
530   MotionVector pmvfw = zero_mv, pmvbw = zero_mv;
531 
532   int   block_x, block_y, pic_block_x, pic_block_y, opic_block_x, opic_block_y;
533   MotionVector *****all_mvs;
534   char  *direct_ref_idx;
535   StorablePicture **list1 = currSlice->listX[LIST_1];
536 
537   PixelPos mb[4];
538   get_neighbors(currMB, mb, 0, 0, 16);
539 
540   set_direct_references(&mb[0], &l0_refA,  &l1_refA,  mv_info);
541   set_direct_references(&mb[1], &l0_refB,  &l1_refB,  mv_info);
542   set_direct_references(&mb[2], &l0_refC,  &l1_refC,  mv_info);
543 
544   l0_refX = (char) imin(imin((unsigned char) l0_refA, (unsigned char) l0_refB), (unsigned char) l0_refC);
545   l1_refX = (char) imin(imin((unsigned char) l1_refA, (unsigned char) l1_refB), (unsigned char) l1_refC);
546 
547   if (l0_refX >= 0)
548     currMB->GetMVPredictor (currMB, mb, &pmvfw, l0_refX, mv_info, LIST_0, 0, 0, 16, 16);
549 
550   if (l1_refX >= 0)
551     currMB->GetMVPredictor (currMB, mb, &pmvbw, l1_refX, mv_info, LIST_1, 0, 0, 16, 16);
552 
553   if (l0_refX == -1 && l1_refX == -1)
554   {
555     for (block_y=0; block_y<4; block_y++)
556     {
557       pic_block_y  = currMB->block_y + block_y;
558       for (block_x=0; block_x<4; block_x++)
559       {
560         pic_block_x  = currMB->block_x + block_x;
561         direct_ref_idx = currSlice->direct_ref_idx[pic_block_y][pic_block_x];
562 
563         currSlice->all_mv[LIST_0][0][0][block_y][block_x] = zero_mv;
564         currSlice->all_mv[LIST_1][0][0][block_y][block_x] = zero_mv;
565 
566         direct_ref_idx[LIST_0] = direct_ref_idx[LIST_1] = 0;
567 
568         if (p_Vid->active_pps->weighted_bipred_idc == 1)
569           test_valid_direct(currSlice, currSlice->active_sps, direct_ref_idx, 0, 0, pic_block_y, pic_block_x);
570         else
571           currSlice->direct_pdir[pic_block_y][pic_block_x] = 2;
572       }
573     }
574   }
575   else if (l0_refX == 0 || l1_refX == 0)
576   {
577     int (*get_colocated)(Macroblock *currMB, StorablePicture *list1, int i, int j) =
578       p_Vid->active_sps->direct_8x8_inference_flag ? get_colocated_info : get_colocated_info_4x4;
579 
580     int is_moving_block;
581     for (block_y = 0; block_y < 4; block_y++)
582     {
583       pic_block_y  = currMB->block_y + block_y;
584       opic_block_y = (currMB->opix_y >> 2) + block_y;
585 
586       for (block_x=0; block_x<4; block_x++)
587       {
588         pic_block_x    = currMB->block_x + block_x;
589         direct_ref_idx = currSlice->direct_ref_idx[pic_block_y][pic_block_x];
590         opic_block_x   = (currMB->pix_x >> 2) + block_x;
591 
592         all_mvs = currSlice->all_mv;
593         is_moving_block = (get_colocated(currMB, list1[0], opic_block_x, opic_block_y) == 0);
594 
595         if (l0_refX < 0)
596         {
597           all_mvs[LIST_0][0][0][block_y][block_x] = zero_mv;
598           direct_ref_idx[LIST_0] = -1;
599         }
600         else if ((l0_refX == 0) && is_moving_block)
601         {
602           all_mvs[LIST_0][0][0][block_y][block_x] = zero_mv;
603           direct_ref_idx[LIST_0] = 0;
604         }
605         else
606         {
607           all_mvs[LIST_0][(short) l0_refX][0][block_y][block_x] = pmvfw;
608           direct_ref_idx[LIST_0] = (char)l0_refX;
609         }
610 
611         if (l1_refX < 0)
612         {
613           all_mvs[LIST_1][0][0][block_y][block_x] = zero_mv;
614           direct_ref_idx[LIST_1] = -1;
615         }
616         else if((l1_refX == 0) && is_moving_block)
617         {
618           all_mvs[LIST_1][0][0][block_y][block_x] = zero_mv;
619           direct_ref_idx[LIST_1] = 0;
620         }
621         else
622         {
623           all_mvs[LIST_1][(short) l1_refX][0][block_y][block_x] = pmvbw;
624           direct_ref_idx[LIST_1] = (char)l1_refX;
625         }
626 
627         if      (direct_ref_idx[LIST_1] == -1)
628           currSlice->direct_pdir[pic_block_y][pic_block_x] = 0;
629         else if (direct_ref_idx[LIST_0] == -1)
630           currSlice->direct_pdir[pic_block_y][pic_block_x] = 1;
631         else if (p_Vid->active_pps->weighted_bipred_idc == 1)
632           test_valid_direct(currSlice, currSlice->active_sps, direct_ref_idx, l0_refX, l1_refX, pic_block_y, pic_block_x);
633         else
634           currSlice->direct_pdir[pic_block_y][pic_block_x] = 2;
635       }
636     }
637   }
638   else
639   {
640     for (block_y=0; block_y<4; block_y++)
641     {
642       pic_block_y  = currMB->block_y + block_y;
643 
644       for (block_x=0; block_x<4; block_x++)
645       {
646         pic_block_x  = currMB->block_x + block_x;
647         direct_ref_idx = currSlice->direct_ref_idx[pic_block_y][pic_block_x];
648 
649         all_mvs = currSlice->all_mv;
650 
651         if (l0_refX > 0)
652         {
653           all_mvs[LIST_0][(short) l0_refX][0][block_y][block_x] = pmvfw;
654           direct_ref_idx[LIST_0]= (char)l0_refX;
655         }
656         else
657         {
658           all_mvs[LIST_0][0][0][block_y][block_x] = zero_mv;
659           direct_ref_idx[LIST_0]=-1;
660         }
661 
662         if (l1_refX > 0)
663         {
664           all_mvs[LIST_1][(short) l1_refX][0][block_y][block_x] = pmvbw;
665           direct_ref_idx[LIST_1] = (char)l1_refX;
666         }
667         else
668         {
669           all_mvs[LIST_1][0][0][block_y][block_x] = zero_mv;
670           direct_ref_idx[LIST_1] = -1;
671         }
672 
673         if      (direct_ref_idx[LIST_1] == -1)
674           currSlice->direct_pdir[pic_block_y][pic_block_x] = 0;
675         else if (direct_ref_idx[LIST_0] == -1)
676           currSlice->direct_pdir[pic_block_y][pic_block_x] = 1;
677         else if (p_Vid->active_pps->weighted_bipred_idc == 1)
678           test_valid_direct(currSlice, currSlice->active_sps, direct_ref_idx, l0_refX, l1_refX, pic_block_y, pic_block_x);
679         else
680           currSlice->direct_pdir[pic_block_y][pic_block_x] = 2;
681       }
682     }
683   }
684 }
685 
686 
687 /*!
688 ************************************************************************
689 * \brief
690 *    Calculate Spatial Direct Mode Motion Vectors
691 ************************************************************************
692 */
Get_Direct_MV_Spatial_MBAFF(Macroblock * currMB)693 void Get_Direct_MV_Spatial_MBAFF (Macroblock *currMB)
694 {
695   char l0_refA, l0_refB, l0_refC;
696   char l1_refA, l1_refB, l1_refC;
697   char l0_refX,l1_refX;
698   MotionVector pmvfw = zero_mv, pmvbw = zero_mv;
699 
700   int   block_x, block_y, pic_block_x, pic_block_y, opic_block_x, opic_block_y;
701   MotionVector *****all_mvs;
702   char  *direct_ref_idx;
703   int is_moving_block;
704   Slice *currSlice = currMB->p_Slice;
705   VideoParameters *p_Vid = currMB->p_Vid;
706   PicMotionParams **mv_info = p_Vid->enc_picture->mv_info;
707   StorablePicture **list1 = currSlice->listX[LIST_1 + currMB->list_offset];
708 
709   int (*get_colocated)(Macroblock *currMB, StorablePicture *list1, int i, int j) =
710     p_Vid->active_sps->direct_8x8_inference_flag ? get_colocated_info : get_colocated_info_4x4;
711 
712   PixelPos mb[4];
713   get_neighbors(currMB, mb, 0, 0, 16);
714 
715 
716   if (currMB->mb_field)
717   {
718     set_direct_references_mb_field(&mb[0], &l0_refA, &l1_refA, mv_info, p_Vid->mb_data);
719     set_direct_references_mb_field(&mb[1], &l0_refB, &l1_refB, mv_info, p_Vid->mb_data);
720     set_direct_references_mb_field(&mb[2], &l0_refC, &l1_refC, mv_info, p_Vid->mb_data);
721   }
722   else
723   {
724     set_direct_references_mb_frame(&mb[0], &l0_refA, &l1_refA, mv_info, p_Vid->mb_data);
725     set_direct_references_mb_frame(&mb[1], &l0_refB, &l1_refB, mv_info, p_Vid->mb_data);
726     set_direct_references_mb_frame(&mb[2], &l0_refC, &l1_refC, mv_info, p_Vid->mb_data);
727   }
728 
729   l0_refX = (char) imin(imin((unsigned char) l0_refA, (unsigned char) l0_refB), (unsigned char) l0_refC);
730   l1_refX = (char) imin(imin((unsigned char) l1_refA, (unsigned char) l1_refB), (unsigned char) l1_refC);
731 
732   if (l0_refX >=0)
733     currMB->GetMVPredictor (currMB, mb, &pmvfw, l0_refX, mv_info, LIST_0, 0, 0, 16, 16);
734 
735   if (l1_refX >=0)
736     currMB->GetMVPredictor (currMB, mb, &pmvbw, l1_refX, mv_info, LIST_1, 0, 0, 16, 16);
737 
738   for (block_y=0; block_y<4; block_y++)
739   {
740     pic_block_y  = currMB->block_y + block_y;
741     opic_block_y = (currMB->opix_y >> 2) + block_y;
742 
743     for (block_x=0; block_x<4; block_x++)
744     {
745       pic_block_x  = currMB->block_x + block_x;
746       direct_ref_idx = currSlice->direct_ref_idx[pic_block_y][pic_block_x];
747       opic_block_x = (currMB->pix_x >> 2) + block_x;
748       is_moving_block = (get_colocated(currMB, list1[0], opic_block_x, opic_block_y) == 0);
749 
750       all_mvs = currSlice->all_mv;
751 
752       if (l0_refX >=0)
753       {
754         if (!l0_refX  && is_moving_block)
755         {
756           all_mvs[LIST_0][0][0][block_y][block_x] = zero_mv;
757           direct_ref_idx[LIST_0] = 0;
758         }
759         else
760         {
761           all_mvs[LIST_0][(short) l0_refX][0][block_y][block_x] = pmvfw;
762           direct_ref_idx[LIST_0] = (char)l0_refX;
763         }
764       }
765       else
766       {
767         all_mvs[LIST_0][0][0][block_y][block_x] = zero_mv;
768         direct_ref_idx[LIST_0] = -1;
769       }
770 
771       if (l1_refX >=0)
772       {
773         if(l1_refX==0 && is_moving_block)
774         {
775           all_mvs[LIST_1][0][0][block_y][block_x] = zero_mv;
776           direct_ref_idx[LIST_1] = (char)l1_refX;
777         }
778         else
779         {
780           all_mvs[LIST_1][(short) l1_refX][0][block_y][block_x] = pmvbw;
781           direct_ref_idx[LIST_1] = (char)l1_refX;
782         }
783       }
784       else
785       {
786         all_mvs[LIST_1][0][0][block_y][block_x] = zero_mv;
787         direct_ref_idx[LIST_1] = -1;
788       }
789 
790      // Test Level Limits if satisfied.
791 
792       // Test Level Limits if satisfied.
793       if ((out_of_bounds_mvs(p_Vid, &all_mvs[LIST_0][l0_refX < 0? 0 : l0_refX][0][block_y][block_x])
794         ||  out_of_bounds_mvs(p_Vid, &all_mvs[LIST_1][l1_refX < 0? 0 : l1_refX][0][block_y][block_x])))
795       {
796         direct_ref_idx[LIST_0] = -1;
797         direct_ref_idx[LIST_1] = -1;
798         currSlice->direct_pdir   [pic_block_y][pic_block_x]         = -1;
799       }
800       else
801       {
802         if (l0_refX < 0 && l1_refX < 0)
803         {
804           direct_ref_idx[LIST_0] = direct_ref_idx[LIST_1] = 0;
805           l0_refX = 0;
806           l1_refX = 0;
807         }
808 
809         if      (direct_ref_idx[LIST_1] == -1)
810           currSlice->direct_pdir[pic_block_y][pic_block_x] = 0;
811         else if (direct_ref_idx[LIST_0] == -1)
812           currSlice->direct_pdir[pic_block_y][pic_block_x] = 1;
813         else if (p_Vid->active_pps->weighted_bipred_idc == 1)
814           test_valid_direct(currSlice, currSlice->active_sps, direct_ref_idx, l0_refX, l1_refX, pic_block_y, pic_block_x);
815         else
816           currSlice->direct_pdir[pic_block_y][pic_block_x] = 2;
817       }
818     }
819   }
820 }
821