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