2 * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * @file libavcodec/h264_direct.c
24 * H.264 / AVC / MPEG4 part10 direct mb/block decoding.
25 * @author Michael Niedermayer <michaelni@gmx.at>
31 #include "mpegvideo.h"
33 #include "rectangle.h"
39 static int get_scale_factor(H264Context
* const h
, int poc
, int poc1
, int i
){
40 int poc0
= h
->ref_list
[0][i
].poc
;
41 int td
= av_clip(poc1
- poc0
, -128, 127);
42 if(td
== 0 || h
->ref_list
[0][i
].long_ref
){
45 int tb
= av_clip(poc
- poc0
, -128, 127);
46 int tx
= (16384 + (FFABS(td
) >> 1)) / td
;
47 return av_clip((tb
*tx
+ 32) >> 6, -1024, 1023);
51 void ff_h264_direct_dist_scale_factor(H264Context
* const h
){
52 MpegEncContext
* const s
= &h
->s
;
53 const int poc
= h
->s
.current_picture_ptr
->field_poc
[ s
->picture_structure
== PICT_BOTTOM_FIELD
];
54 const int poc1
= h
->ref_list
[1][0].poc
;
56 for(field
=0; field
<2; field
++){
57 const int poc
= h
->s
.current_picture_ptr
->field_poc
[field
];
58 const int poc1
= h
->ref_list
[1][0].field_poc
[field
];
59 for(i
=0; i
< 2*h
->ref_count
[0]; i
++)
60 h
->dist_scale_factor_field
[field
][i
^field
] = get_scale_factor(h
, poc
, poc1
, i
+16);
63 for(i
=0; i
<h
->ref_count
[0]; i
++){
64 h
->dist_scale_factor
[i
] = get_scale_factor(h
, poc
, poc1
, i
);
68 static void fill_colmap(H264Context
*h
, int map
[2][16+32], int list
, int field
, int colfield
, int mbafi
){
69 MpegEncContext
* const s
= &h
->s
;
70 Picture
* const ref1
= &h
->ref_list
[1][0];
71 int j
, old_ref
, rfield
;
72 int start
= mbafi ?
16 : 0;
73 int end
= mbafi ?
16+2*h
->ref_count
[0] : h
->ref_count
[0];
74 int interl
= mbafi
|| s
->picture_structure
!= PICT_FRAME
;
76 /* bogus; fills in for missing frames */
77 memset(map
[list
], 0, sizeof(map
[list
]));
79 for(rfield
=0; rfield
<2; rfield
++){
80 for(old_ref
=0; old_ref
<ref1
->ref_count
[colfield
][list
]; old_ref
++){
81 int poc
= ref1
->ref_poc
[colfield
][list
][old_ref
];
85 else if( interl
&& (poc
&3) == 3) //FIXME store all MBAFF references so this isnt needed
86 poc
= (poc
&~3) + rfield
+ 1;
88 for(j
=start
; j
<end
; j
++){
89 if(4*h
->ref_list
[0][j
].frame_num
+ (h
->ref_list
[0][j
].reference
&3) == poc
){
90 int cur_ref
= mbafi ?
(j
-16)^field
: j
;
91 map
[list
][2*old_ref
+ (rfield
^field
) + 16] = cur_ref
;
92 if(rfield
== field
|| !interl
)
93 map
[list
][old_ref
] = cur_ref
;
101 void ff_h264_direct_ref_list_init(H264Context
* const h
){
102 MpegEncContext
* const s
= &h
->s
;
103 Picture
* const ref1
= &h
->ref_list
[1][0];
104 Picture
* const cur
= s
->current_picture_ptr
;
106 int sidx
= (s
->picture_structure
&1)^1;
107 int ref1sidx
= (ref1
->reference
&1)^1;
109 for(list
=0; list
<2; list
++){
110 cur
->ref_count
[sidx
][list
] = h
->ref_count
[list
];
111 for(j
=0; j
<h
->ref_count
[list
]; j
++)
112 cur
->ref_poc
[sidx
][list
][j
] = 4*h
->ref_list
[list
][j
].frame_num
+ (h
->ref_list
[list
][j
].reference
&3);
115 if(s
->picture_structure
== PICT_FRAME
){
116 memcpy(cur
->ref_count
[1], cur
->ref_count
[0], sizeof(cur
->ref_count
[0]));
117 memcpy(cur
->ref_poc
[1], cur
->ref_poc
[0], sizeof(cur
->ref_poc
[0]));
120 cur
->mbaff
= FRAME_MBAFF
;
123 if(s
->picture_structure
== PICT_FRAME
){
124 int cur_poc
= s
->current_picture_ptr
->poc
;
125 int *col_poc
= h
->ref_list
[1]->field_poc
;
126 h
->col_parity
= (FFABS(col_poc
[0] - cur_poc
) >= FFABS(col_poc
[1] - cur_poc
));
127 ref1sidx
=sidx
= h
->col_parity
;
128 }else if(!(s
->picture_structure
& h
->ref_list
[1][0].reference
) && !h
->ref_list
[1][0].mbaff
){ // FL -> FL & differ parity
129 h
->col_fieldoff
= s
->mb_stride
*(2*(h
->ref_list
[1][0].reference
) - 3);
132 if(cur
->pict_type
!= FF_B_TYPE
|| h
->direct_spatial_mv_pred
)
135 for(list
=0; list
<2; list
++){
136 fill_colmap(h
, h
->map_col_to_list0
, list
, sidx
, ref1sidx
, 0);
138 for(field
=0; field
<2; field
++)
139 fill_colmap(h
, h
->map_col_to_list0_field
[field
], list
, field
, field
, 1);
143 static void pred_spatial_direct_motion(H264Context
* const h
, int *mb_type
){
144 MpegEncContext
* const s
= &h
->s
;
145 int b8_stride
= h
->b8_stride
;
146 int b4_stride
= h
->b_stride
;
147 int mb_xy
= h
->mb_xy
;
149 const int16_t (*l1mv0
)[2], (*l1mv1
)[2];
150 const int8_t *l1ref0
, *l1ref1
;
151 const int is_b8x8
= IS_8X8(*mb_type
);
152 unsigned int sub_mb_type
= MB_TYPE_L0L1
;;
158 assert(h
->ref_list
[1][0].reference
&3);
160 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)
162 *mb_type
|= MB_TYPE_L0L1
;
164 /* ref = min(neighbors) */
165 for(list
=0; list
<2; list
++){
166 int left_ref
= h
->ref_cache
[list
][scan8
[0] - 1];
167 int top_ref
= h
->ref_cache
[list
][scan8
[0] - 8];
168 int refc
= h
->ref_cache
[list
][scan8
[0] - 8 + 4];
169 const int16_t *C
= h
->mv_cache
[list
][ scan8
[0] - 8 + 4];
170 if(refc
== PART_NOT_AVAILABLE
){
171 refc
= h
->ref_cache
[list
][scan8
[0] - 8 - 1];
172 C
= h
-> mv_cache
[list
][scan8
[0] - 8 - 1];
174 ref
[list
] = FFMIN3((unsigned)left_ref
, (unsigned)top_ref
, (unsigned)refc
);
176 //this is just pred_motion() but with the cases removed that cannot happen for direct blocks
177 const int16_t * const A
= h
->mv_cache
[list
][ scan8
[0] - 1 ];
178 const int16_t * const B
= h
->mv_cache
[list
][ scan8
[0] - 8 ];
180 int match_count
= (left_ref
==ref
[list
]) + (top_ref
==ref
[list
]) + (refc
==ref
[list
]);
181 if(match_count
> 1){ //most common
182 mv
[list
]= (mid_pred(A
[0], B
[0], C
[0])&0xFFFF)
183 +(mid_pred(A
[1], B
[1], C
[1])<<16);
185 assert(match_count
==1);
186 if(left_ref
==ref
[list
]){
187 mv
[list
]= *(uint32_t*)A
;
188 }else if(top_ref
==ref
[list
]){
189 mv
[list
]= *(uint32_t*)B
;
191 mv
[list
]= *(uint32_t*)C
;
195 int mask
= ~(MB_TYPE_L0
<< (2*list
));
203 if(ref
[0] < 0 && ref
[1] < 0){
206 *mb_type
|= MB_TYPE_L0L1
;
207 sub_mb_type
|= MB_TYPE_L0L1
;
210 if(!(is_b8x8
|mv
[0]|mv
[1])){
211 fill_rectangle(&h
->ref_cache
[0][scan8
[0]], 4, 4, 8, (uint8_t)ref
[0], 1);
212 fill_rectangle(&h
->ref_cache
[1][scan8
[0]], 4, 4, 8, (uint8_t)ref
[1], 1);
213 fill_rectangle(&h
->mv_cache
[0][scan8
[0]], 4, 4, 8, 0, 4);
214 fill_rectangle(&h
->mv_cache
[1][scan8
[0]], 4, 4, 8, 0, 4);
215 *mb_type
= (*mb_type
& ~(MB_TYPE_8x8
|MB_TYPE_16x8
|MB_TYPE_8x16
|MB_TYPE_P1L0
|MB_TYPE_P1L1
))|MB_TYPE_16x16
|MB_TYPE_DIRECT2
;
219 if(IS_INTERLACED(h
->ref_list
[1][0].mb_type
[mb_xy
])){ // AFL/AFR/FR/FL -> AFL/FL
220 if(!IS_INTERLACED(*mb_type
)){ // AFR/FR -> AFL/FL
221 mb_xy
= s
->mb_x
+ ((s
->mb_y
&~1) + h
->col_parity
)*s
->mb_stride
;
224 mb_xy
+= h
->col_fieldoff
; // non zero for FL -> FL & differ parity
227 }else{ // AFL/AFR/FR/FL -> AFR/FR
228 if(IS_INTERLACED(*mb_type
)){ // AFL /FL -> AFR/FR
229 mb_xy
= s
->mb_x
+ (s
->mb_y
&~1)*s
->mb_stride
;
230 mb_type_col
[0] = h
->ref_list
[1][0].mb_type
[mb_xy
];
231 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
+ s
->mb_stride
];
235 sub_mb_type
|= MB_TYPE_16x16
|MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
236 if( (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)
237 && (mb_type_col
[1] & MB_TYPE_16x16_OR_INTRA
)
239 *mb_type
|= MB_TYPE_16x8
|MB_TYPE_DIRECT2
; /* B_16x8 */
241 *mb_type
|= MB_TYPE_8x8
;
243 }else{ // AFR/FR -> AFR/FR
246 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
];
248 sub_mb_type
|= MB_TYPE_16x16
|MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
249 if(!is_b8x8
&& (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)){
250 *mb_type
|= MB_TYPE_16x16
|MB_TYPE_DIRECT2
; /* B_16x16 */
251 }else if(!is_b8x8
&& (mb_type_col
[0] & (MB_TYPE_16x8
|MB_TYPE_8x16
))){
252 *mb_type
|= MB_TYPE_DIRECT2
| (mb_type_col
[0] & (MB_TYPE_16x8
|MB_TYPE_8x16
));
254 if(!h
->sps
.direct_8x8_inference_flag
){
255 /* FIXME save sub mb types from previous frames (or derive from MVs)
256 * so we know exactly what block size to use */
257 sub_mb_type
+= (MB_TYPE_8x8
-MB_TYPE_16x16
); /* B_SUB_4x4 */
259 *mb_type
|= MB_TYPE_8x8
;
264 l1mv0
= &h
->ref_list
[1][0].motion_val
[0][h
->mb2b_xy
[mb_xy
]];
265 l1mv1
= &h
->ref_list
[1][0].motion_val
[1][h
->mb2b_xy
[mb_xy
]];
266 l1ref0
= &h
->ref_list
[1][0].ref_index
[0][h
->mb2b8_xy
[mb_xy
]];
267 l1ref1
= &h
->ref_list
[1][0].ref_index
[1][h
->mb2b8_xy
[mb_xy
]];
270 l1ref0
+= h
->b8_stride
;
271 l1ref1
+= h
->b8_stride
;
272 l1mv0
+= 2*b4_stride
;
273 l1mv1
+= 2*b4_stride
;
278 if(IS_INTERLACED(*mb_type
) != IS_INTERLACED(mb_type_col
[0])){
280 for(i8
=0; i8
<4; i8
++){
283 int xy8
= x8
+y8
*b8_stride
;
284 int xy4
= 3*x8
+y8
*b4_stride
;
287 if(is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
289 h
->sub_mb_type
[i8
] = sub_mb_type
;
291 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, (uint8_t)ref
[0], 1);
292 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
*4]], 2, 2, 8, (uint8_t)ref
[1], 1);
293 if(!IS_INTRA(mb_type_col
[y8
]) && !h
->ref_list
[1][0].long_ref
294 && ( (l1ref0
[xy8
] == 0 && FFABS(l1mv0
[xy4
][0]) <= 1 && FFABS(l1mv0
[xy4
][1]) <= 1)
295 || (l1ref0
[xy8
] < 0 && l1ref1
[xy8
] == 0 && FFABS(l1mv1
[xy4
][0]) <= 1 && FFABS(l1mv1
[xy4
][1]) <= 1))){
306 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, a
, 4);
307 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, b
, 4);
309 if(!is_b8x8
&& !(n
&3))
310 *mb_type
= (*mb_type
& ~(MB_TYPE_8x8
|MB_TYPE_16x8
|MB_TYPE_8x16
|MB_TYPE_P1L0
|MB_TYPE_P1L1
))|MB_TYPE_16x16
|MB_TYPE_DIRECT2
;
311 }else if(IS_16X16(*mb_type
)){
314 fill_rectangle(&h
->ref_cache
[0][scan8
[0]], 4, 4, 8, (uint8_t)ref
[0], 1);
315 fill_rectangle(&h
->ref_cache
[1][scan8
[0]], 4, 4, 8, (uint8_t)ref
[1], 1);
316 if(!IS_INTRA(mb_type_col
[0]) && !h
->ref_list
[1][0].long_ref
317 && ( (l1ref0
[0] == 0 && FFABS(l1mv0
[0][0]) <= 1 && FFABS(l1mv0
[0][1]) <= 1)
318 || (l1ref0
[0] < 0 && l1ref1
[0] == 0 && FFABS(l1mv1
[0][0]) <= 1 && FFABS(l1mv1
[0][1]) <= 1
319 && h
->x264_build
>33U))){
329 fill_rectangle(&h
->mv_cache
[0][scan8
[0]], 4, 4, 8, a
, 4);
330 fill_rectangle(&h
->mv_cache
[1][scan8
[0]], 4, 4, 8, b
, 4);
333 for(i8
=0; i8
<4; i8
++){
335 const int y8
= i8
>>1;
337 if(is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
339 h
->sub_mb_type
[i8
] = sub_mb_type
;
341 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, mv
[0], 4);
342 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, mv
[1], 4);
343 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, (uint8_t)ref
[0], 1);
344 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
*4]], 2, 2, 8, (uint8_t)ref
[1], 1);
347 if(!IS_INTRA(mb_type_col
[0]) && !h
->ref_list
[1][0].long_ref
&& ( l1ref0
[x8
+ y8
*b8_stride
] == 0
348 || (l1ref0
[x8
+ y8
*b8_stride
] < 0 && l1ref1
[x8
+ y8
*b8_stride
] == 0
349 && h
->x264_build
>33U))){
350 const int16_t (*l1mv
)[2]= l1ref0
[x8
+ y8
*b8_stride
] == 0 ? l1mv0
: l1mv1
;
351 if(IS_SUB_8X8(sub_mb_type
)){
352 const int16_t *mv_col
= l1mv
[x8
*3 + y8
*3*b4_stride
];
353 if(FFABS(mv_col
[0]) <= 1 && FFABS(mv_col
[1]) <= 1){
355 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 4);
357 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 4);
362 for(i4
=0; i4
<4; i4
++){
363 const int16_t *mv_col
= l1mv
[x8
*2 + (i4
&1) + (y8
*2 + (i4
>>1))*b4_stride
];
364 if(FFABS(mv_col
[0]) <= 1 && FFABS(mv_col
[1]) <= 1){
366 *(uint32_t*)h
->mv_cache
[0][scan8
[i8
*4+i4
]] = 0;
368 *(uint32_t*)h
->mv_cache
[1][scan8
[i8
*4+i4
]] = 0;
373 h
->sub_mb_type
[i8
]+= MB_TYPE_16x16
- MB_TYPE_8x8
;
378 if(!is_b8x8
&& !(n
&15))
379 *mb_type
= (*mb_type
& ~(MB_TYPE_8x8
|MB_TYPE_16x8
|MB_TYPE_8x16
|MB_TYPE_P1L0
|MB_TYPE_P1L1
))|MB_TYPE_16x16
|MB_TYPE_DIRECT2
;
383 static void pred_temp_direct_motion(H264Context
* const h
, int *mb_type
){
384 MpegEncContext
* const s
= &h
->s
;
385 int b8_stride
= h
->b8_stride
;
386 int b4_stride
= h
->b_stride
;
387 int mb_xy
= h
->mb_xy
;
389 const int16_t (*l1mv0
)[2], (*l1mv1
)[2];
390 const int8_t *l1ref0
, *l1ref1
;
391 const int is_b8x8
= IS_8X8(*mb_type
);
392 unsigned int sub_mb_type
;
395 assert(h
->ref_list
[1][0].reference
&3);
397 if(IS_INTERLACED(h
->ref_list
[1][0].mb_type
[mb_xy
])){ // AFL/AFR/FR/FL -> AFL/FL
398 if(!IS_INTERLACED(*mb_type
)){ // AFR/FR -> AFL/FL
399 mb_xy
= s
->mb_x
+ ((s
->mb_y
&~1) + h
->col_parity
)*s
->mb_stride
;
402 mb_xy
+= h
->col_fieldoff
; // non zero for FL -> FL & differ parity
405 }else{ // AFL/AFR/FR/FL -> AFR/FR
406 if(IS_INTERLACED(*mb_type
)){ // AFL /FL -> AFR/FR
407 mb_xy
= s
->mb_x
+ (s
->mb_y
&~1)*s
->mb_stride
;
408 mb_type_col
[0] = h
->ref_list
[1][0].mb_type
[mb_xy
];
409 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
+ s
->mb_stride
];
413 sub_mb_type
= MB_TYPE_16x16
|MB_TYPE_P0L0
|MB_TYPE_P0L1
|MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
415 if( (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)
416 && (mb_type_col
[1] & MB_TYPE_16x16_OR_INTRA
)
418 *mb_type
|= MB_TYPE_16x8
|MB_TYPE_L0L1
|MB_TYPE_DIRECT2
; /* B_16x8 */
420 *mb_type
|= MB_TYPE_8x8
|MB_TYPE_L0L1
;
422 }else{ // AFR/FR -> AFR/FR
425 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
];
427 sub_mb_type
= MB_TYPE_16x16
|MB_TYPE_P0L0
|MB_TYPE_P0L1
|MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
428 if(!is_b8x8
&& (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)){
429 *mb_type
|= MB_TYPE_16x16
|MB_TYPE_P0L0
|MB_TYPE_P0L1
|MB_TYPE_DIRECT2
; /* B_16x16 */
430 }else if(!is_b8x8
&& (mb_type_col
[0] & (MB_TYPE_16x8
|MB_TYPE_8x16
))){
431 *mb_type
|= MB_TYPE_L0L1
|MB_TYPE_DIRECT2
| (mb_type_col
[0] & (MB_TYPE_16x8
|MB_TYPE_8x16
));
433 if(!h
->sps
.direct_8x8_inference_flag
){
434 /* FIXME save sub mb types from previous frames (or derive from MVs)
435 * so we know exactly what block size to use */
436 sub_mb_type
= MB_TYPE_8x8
|MB_TYPE_P0L0
|MB_TYPE_P0L1
|MB_TYPE_DIRECT2
; /* B_SUB_4x4 */
438 *mb_type
|= MB_TYPE_8x8
|MB_TYPE_L0L1
;
443 l1mv0
= &h
->ref_list
[1][0].motion_val
[0][h
->mb2b_xy
[mb_xy
]];
444 l1mv1
= &h
->ref_list
[1][0].motion_val
[1][h
->mb2b_xy
[mb_xy
]];
445 l1ref0
= &h
->ref_list
[1][0].ref_index
[0][h
->mb2b8_xy
[mb_xy
]];
446 l1ref1
= &h
->ref_list
[1][0].ref_index
[1][h
->mb2b8_xy
[mb_xy
]];
449 l1ref0
+= h
->b8_stride
;
450 l1ref1
+= h
->b8_stride
;
451 l1mv0
+= 2*b4_stride
;
452 l1mv1
+= 2*b4_stride
;
457 const int *map_col_to_list0
[2] = {h
->map_col_to_list0
[0], h
->map_col_to_list0
[1]};
458 const int *dist_scale_factor
= h
->dist_scale_factor
;
461 if(FRAME_MBAFF
&& IS_INTERLACED(*mb_type
)){
462 map_col_to_list0
[0] = h
->map_col_to_list0_field
[s
->mb_y
&1][0];
463 map_col_to_list0
[1] = h
->map_col_to_list0_field
[s
->mb_y
&1][1];
464 dist_scale_factor
=h
->dist_scale_factor_field
[s
->mb_y
&1];
466 ref_offset
= (h
->ref_list
[1][0].mbaff
<<4) & (mb_type_col
[0]>>3); //if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0])) ref_offset=16 else 0
468 if(IS_INTERLACED(*mb_type
) != IS_INTERLACED(mb_type_col
[0])){
469 int y_shift
= 2*!IS_INTERLACED(*mb_type
);
470 assert(h
->sps
.direct_8x8_inference_flag
);
472 for(i8
=0; i8
<4; i8
++){
474 const int y8
= i8
>>1;
476 const int16_t (*l1mv
)[2]= l1mv0
;
478 if(is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
480 h
->sub_mb_type
[i8
] = sub_mb_type
;
482 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 1);
483 if(IS_INTRA(mb_type_col
[y8
])){
484 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 1);
485 fill_rectangle(&h
-> mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 4);
486 fill_rectangle(&h
-> mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 4);
490 ref0
= l1ref0
[x8
+ y8
*b8_stride
];
492 ref0
= map_col_to_list0
[0][ref0
+ ref_offset
];
494 ref0
= map_col_to_list0
[1][l1ref1
[x8
+ y8
*b8_stride
] + ref_offset
];
497 scale
= dist_scale_factor
[ref0
];
498 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, ref0
, 1);
501 const int16_t *mv_col
= l1mv
[x8
*3 + y8
*b4_stride
];
502 int my_col
= (mv_col
[1]<<y_shift
)/2;
503 int mx
= (scale
* mv_col
[0] + 128) >> 8;
504 int my
= (scale
* my_col
+ 128) >> 8;
505 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, pack16to32(mx
,my
), 4);
506 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, pack16to32(mx
-mv_col
[0],my
-my_col
), 4);
512 /* one-to-one mv scaling */
514 if(IS_16X16(*mb_type
)){
517 fill_rectangle(&h
->ref_cache
[1][scan8
[0]], 4, 4, 8, 0, 1);
518 if(IS_INTRA(mb_type_col
[0])){
521 const int ref0
= l1ref0
[0] >= 0 ? map_col_to_list0
[0][l1ref0
[0] + ref_offset
]
522 : map_col_to_list0
[1][l1ref1
[0] + ref_offset
];
523 const int scale
= dist_scale_factor
[ref0
];
524 const int16_t *mv_col
= l1ref0
[0] >= 0 ? l1mv0
[0] : l1mv1
[0];
526 mv_l0
[0] = (scale
* mv_col
[0] + 128) >> 8;
527 mv_l0
[1] = (scale
* mv_col
[1] + 128) >> 8;
529 mv0
= pack16to32(mv_l0
[0],mv_l0
[1]);
530 mv1
= pack16to32(mv_l0
[0]-mv_col
[0],mv_l0
[1]-mv_col
[1]);
532 fill_rectangle(&h
->ref_cache
[0][scan8
[0]], 4, 4, 8, ref
, 1);
533 fill_rectangle(&h
-> mv_cache
[0][scan8
[0]], 4, 4, 8, mv0
, 4);
534 fill_rectangle(&h
-> mv_cache
[1][scan8
[0]], 4, 4, 8, mv1
, 4);
536 for(i8
=0; i8
<4; i8
++){
538 const int y8
= i8
>>1;
540 const int16_t (*l1mv
)[2]= l1mv0
;
542 if(is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
544 h
->sub_mb_type
[i8
] = sub_mb_type
;
545 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 1);
546 if(IS_INTRA(mb_type_col
[0])){
547 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 1);
548 fill_rectangle(&h
-> mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 4);
549 fill_rectangle(&h
-> mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 4);
553 ref0
= l1ref0
[x8
+ y8
*b8_stride
];
555 ref0
= map_col_to_list0
[0][ref0
+ ref_offset
];
557 ref0
= map_col_to_list0
[1][l1ref1
[x8
+ y8
*b8_stride
] + ref_offset
];
560 scale
= dist_scale_factor
[ref0
];
562 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, ref0
, 1);
563 if(IS_SUB_8X8(sub_mb_type
)){
564 const int16_t *mv_col
= l1mv
[x8
*3 + y8
*3*b4_stride
];
565 int mx
= (scale
* mv_col
[0] + 128) >> 8;
566 int my
= (scale
* mv_col
[1] + 128) >> 8;
567 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, pack16to32(mx
,my
), 4);
568 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, pack16to32(mx
-mv_col
[0],my
-mv_col
[1]), 4);
570 for(i4
=0; i4
<4; i4
++){
571 const int16_t *mv_col
= l1mv
[x8
*2 + (i4
&1) + (y8
*2 + (i4
>>1))*b4_stride
];
572 int16_t *mv_l0
= h
->mv_cache
[0][scan8
[i8
*4+i4
]];
573 mv_l0
[0] = (scale
* mv_col
[0] + 128) >> 8;
574 mv_l0
[1] = (scale
* mv_col
[1] + 128) >> 8;
575 *(uint32_t*)h
->mv_cache
[1][scan8
[i8
*4+i4
]] =
576 pack16to32(mv_l0
[0]-mv_col
[0],mv_l0
[1]-mv_col
[1]);
583 void ff_h264_pred_direct_motion(H264Context
* const h
, int *mb_type
){
584 if(h
->direct_spatial_mv_pred
){
585 pred_spatial_direct_motion(h
, mb_type
);
587 pred_temp_direct_motion(h
, mb_type
);