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 Libav.
7 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * H.264 / AVC / MPEG4 part10 direct mb/block decoding.
25 * @author Michael Niedermayer <michaelni@gmx.at>
30 #include "mpegvideo.h"
32 #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 const int poc
= h
->cur_pic_ptr
->field_poc
[h
->picture_structure
== PICT_BOTTOM_FIELD
];
53 const int poc1
= h
->ref_list
[1][0].poc
;
57 for (field
= 0; field
< 2; field
++){
58 const int poc
= h
->cur_pic_ptr
->field_poc
[field
];
59 const int poc1
= h
->ref_list
[1][0].field_poc
[field
];
60 for (i
= 0; i
< 2 * h
->ref_count
[0]; i
++)
61 h
->dist_scale_factor_field
[field
][i
^field
] =
62 get_scale_factor(h
, poc
, poc1
, i
+16);
65 for (i
= 0; i
< h
->ref_count
[0]; i
++){
66 h
->dist_scale_factor
[i
] = get_scale_factor(h
, poc
, poc1
, i
);
70 static void fill_colmap(H264Context
*h
, int map
[2][16+32], int list
, int field
, int colfield
, int mbafi
){
71 Picture
* const ref1
= &h
->ref_list
[1][0];
72 int j
, old_ref
, rfield
;
73 int start
= mbafi
? 16 : 0;
74 int end
= mbafi
? 16+2*h
->ref_count
[0] : h
->ref_count
[0];
75 int interl
= mbafi
|| h
->picture_structure
!= PICT_FRAME
;
77 /* bogus; fills in for missing frames */
78 memset(map
[list
], 0, sizeof(map
[list
]));
80 for(rfield
=0; rfield
<2; rfield
++){
81 for(old_ref
=0; old_ref
<ref1
->ref_count
[colfield
][list
]; old_ref
++){
82 int poc
= ref1
->ref_poc
[colfield
][list
][old_ref
];
86 else if( interl
&& (poc
&3) == 3) // FIXME: store all MBAFF references so this is not needed
87 poc
= (poc
&~3) + rfield
+ 1;
89 for(j
=start
; j
<end
; j
++){
90 if (4 * h
->ref_list
[0][j
].frame_num
+ (h
->ref_list
[0][j
].reference
& 3) == poc
) {
91 int cur_ref
= mbafi
? (j
-16)^field
: j
;
93 map
[list
][2 * old_ref
+ (rfield
^field
) + 16] = cur_ref
;
94 if(rfield
== field
|| !interl
)
95 map
[list
][old_ref
] = cur_ref
;
103 void ff_h264_direct_ref_list_init(H264Context
* const h
){
104 Picture
* const ref1
= &h
->ref_list
[1][0];
105 Picture
* const cur
= h
->cur_pic_ptr
;
107 int sidx
= (h
->picture_structure
&1)^1;
108 int ref1sidx
= (ref1
->reference
&1)^1;
110 for(list
=0; list
<2; list
++){
111 cur
->ref_count
[sidx
][list
] = h
->ref_count
[list
];
112 for(j
=0; j
<h
->ref_count
[list
]; j
++)
113 cur
->ref_poc
[sidx
][list
][j
] = 4 * h
->ref_list
[list
][j
].frame_num
+ (h
->ref_list
[list
][j
].reference
& 3);
116 if(h
->picture_structure
== PICT_FRAME
){
117 memcpy(cur
->ref_count
[1], cur
->ref_count
[0], sizeof(cur
->ref_count
[0]));
118 memcpy(cur
->ref_poc
[1], cur
->ref_poc
[0], sizeof(cur
->ref_poc
[0]));
121 cur
->mbaff
= FRAME_MBAFF
;
124 if(h
->picture_structure
== PICT_FRAME
){
125 int cur_poc
= h
->cur_pic_ptr
->poc
;
126 int *col_poc
= h
->ref_list
[1]->field_poc
;
127 h
->col_parity
= (FFABS(col_poc
[0] - cur_poc
) >= FFABS(col_poc
[1] - cur_poc
));
128 ref1sidx
=sidx
= h
->col_parity
;
129 } else if (!(h
->picture_structure
& h
->ref_list
[1][0].reference
) && !h
->ref_list
[1][0].mbaff
) { // FL -> FL & differ parity
130 h
->col_fieldoff
= 2 * h
->ref_list
[1][0].reference
- 3;
133 if (h
->slice_type_nos
!= AV_PICTURE_TYPE_B
|| h
->direct_spatial_mv_pred
)
136 for(list
=0; list
<2; list
++){
137 fill_colmap(h
, h
->map_col_to_list0
, list
, sidx
, ref1sidx
, 0);
139 for(field
=0; field
<2; field
++)
140 fill_colmap(h
, h
->map_col_to_list0_field
[field
], list
, field
, field
, 1);
144 static void await_reference_mb_row(H264Context
* const h
, Picture
*ref
, int mb_y
)
146 int ref_field
= ref
->reference
- 1;
147 int ref_field_picture
= ref
->field_picture
;
148 int ref_height
= 16*h
->mb_height
>> ref_field_picture
;
150 if(!HAVE_THREADS
|| !(h
->avctx
->active_thread_type
&FF_THREAD_FRAME
))
153 //FIXME it can be safe to access mb stuff
154 //even if pixels aren't deblocked yet
156 ff_thread_await_progress(&ref
->tf
,
157 FFMIN(16 * mb_y
>> ref_field_picture
, ref_height
- 1),
158 ref_field_picture
&& ref_field
);
161 static void pred_spatial_direct_motion(H264Context
* const h
, int *mb_type
){
163 int b4_stride
= h
->b_stride
;
164 int mb_xy
= h
->mb_xy
, mb_y
= h
->mb_y
;
166 const int16_t (*l1mv0
)[2], (*l1mv1
)[2];
167 const int8_t *l1ref0
, *l1ref1
;
168 const int is_b8x8
= IS_8X8(*mb_type
);
169 unsigned int sub_mb_type
= MB_TYPE_L0L1
;
175 assert(h
->ref_list
[1][0].reference
& 3);
177 await_reference_mb_row(h
, &h
->ref_list
[1][0], h
->mb_y
+ !!IS_INTERLACED(*mb_type
));
179 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)
182 /* ref = min(neighbors) */
183 for(list
=0; list
<2; list
++){
184 int left_ref
= h
->ref_cache
[list
][scan8
[0] - 1];
185 int top_ref
= h
->ref_cache
[list
][scan8
[0] - 8];
186 int refc
= h
->ref_cache
[list
][scan8
[0] - 8 + 4];
187 const int16_t *C
= h
->mv_cache
[list
][ scan8
[0] - 8 + 4];
188 if(refc
== PART_NOT_AVAILABLE
){
189 refc
= h
->ref_cache
[list
][scan8
[0] - 8 - 1];
190 C
= h
-> mv_cache
[list
][scan8
[0] - 8 - 1];
192 ref
[list
] = FFMIN3((unsigned)left_ref
, (unsigned)top_ref
, (unsigned)refc
);
194 //this is just pred_motion() but with the cases removed that cannot happen for direct blocks
195 const int16_t * const A
= h
->mv_cache
[list
][ scan8
[0] - 1 ];
196 const int16_t * const B
= h
->mv_cache
[list
][ scan8
[0] - 8 ];
198 int match_count
= (left_ref
==ref
[list
]) + (top_ref
==ref
[list
]) + (refc
==ref
[list
]);
199 if(match_count
> 1){ //most common
200 mv
[list
]= pack16to32(mid_pred(A
[0], B
[0], C
[0]),
201 mid_pred(A
[1], B
[1], C
[1]) );
203 assert(match_count
==1);
204 if(left_ref
==ref
[list
]){
205 mv
[list
]= AV_RN32A(A
);
206 }else if(top_ref
==ref
[list
]){
207 mv
[list
]= AV_RN32A(B
);
209 mv
[list
]= AV_RN32A(C
);
213 int mask
= ~(MB_TYPE_L0
<< (2*list
));
221 if(ref
[0] < 0 && ref
[1] < 0){
224 *mb_type
|= MB_TYPE_L0L1
;
225 sub_mb_type
|= MB_TYPE_L0L1
;
228 if(!(is_b8x8
|mv
[0]|mv
[1])){
229 fill_rectangle(&h
->ref_cache
[0][scan8
[0]], 4, 4, 8, (uint8_t)ref
[0], 1);
230 fill_rectangle(&h
->ref_cache
[1][scan8
[0]], 4, 4, 8, (uint8_t)ref
[1], 1);
231 fill_rectangle(&h
->mv_cache
[0][scan8
[0]], 4, 4, 8, 0, 4);
232 fill_rectangle(&h
->mv_cache
[1][scan8
[0]], 4, 4, 8, 0, 4);
233 *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
;
237 if (IS_INTERLACED(h
->ref_list
[1][0].mb_type
[mb_xy
])) { // AFL/AFR/FR/FL -> AFL/FL
238 if (!IS_INTERLACED(*mb_type
)) { // AFR/FR -> AFL/FL
239 mb_y
= (h
->mb_y
&~1) + h
->col_parity
;
240 mb_xy
= h
->mb_x
+ ((h
->mb_y
&~1) + h
->col_parity
)*h
->mb_stride
;
243 mb_y
+= h
->col_fieldoff
;
244 mb_xy
+= h
->mb_stride
*h
->col_fieldoff
; // non zero for FL -> FL & differ parity
247 }else{ // AFL/AFR/FR/FL -> AFR/FR
248 if(IS_INTERLACED(*mb_type
)){ // AFL /FL -> AFR/FR
250 mb_xy
= h
->mb_x
+ (h
->mb_y
&~1)*h
->mb_stride
;
251 mb_type_col
[0] = h
->ref_list
[1][0].mb_type
[mb_xy
];
252 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
+ h
->mb_stride
];
253 b8_stride
= 2+4*h
->mb_stride
;
255 if (IS_INTERLACED(mb_type_col
[0]) != IS_INTERLACED(mb_type_col
[1])) {
256 mb_type_col
[0] &= ~MB_TYPE_INTERLACED
;
257 mb_type_col
[1] &= ~MB_TYPE_INTERLACED
;
260 sub_mb_type
|= MB_TYPE_16x16
|MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
261 if( (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)
262 && (mb_type_col
[1] & MB_TYPE_16x16_OR_INTRA
)
264 *mb_type
|= MB_TYPE_16x8
|MB_TYPE_DIRECT2
; /* B_16x8 */
266 *mb_type
|= MB_TYPE_8x8
;
268 }else{ // AFR/FR -> AFR/FR
271 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
];
273 sub_mb_type
|= MB_TYPE_16x16
|MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
274 if(!is_b8x8
&& (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)){
275 *mb_type
|= MB_TYPE_16x16
|MB_TYPE_DIRECT2
; /* B_16x16 */
276 }else if(!is_b8x8
&& (mb_type_col
[0] & (MB_TYPE_16x8
|MB_TYPE_8x16
))){
277 *mb_type
|= MB_TYPE_DIRECT2
| (mb_type_col
[0] & (MB_TYPE_16x8
|MB_TYPE_8x16
));
279 if(!h
->sps
.direct_8x8_inference_flag
){
280 /* FIXME save sub mb types from previous frames (or derive from MVs)
281 * so we know exactly what block size to use */
282 sub_mb_type
+= (MB_TYPE_8x8
-MB_TYPE_16x16
); /* B_SUB_4x4 */
284 *mb_type
|= MB_TYPE_8x8
;
289 await_reference_mb_row(h
, &h
->ref_list
[1][0], mb_y
);
291 l1mv0
= &h
->ref_list
[1][0].motion_val
[0][h
->mb2b_xy
[mb_xy
]];
292 l1mv1
= &h
->ref_list
[1][0].motion_val
[1][h
->mb2b_xy
[mb_xy
]];
293 l1ref0
= &h
->ref_list
[1][0].ref_index
[0][4 * mb_xy
];
294 l1ref1
= &h
->ref_list
[1][0].ref_index
[1][4 * mb_xy
];
299 l1mv0
+= 2*b4_stride
;
300 l1mv1
+= 2*b4_stride
;
305 if(IS_INTERLACED(*mb_type
) != IS_INTERLACED(mb_type_col
[0])){
307 for(i8
=0; i8
<4; i8
++){
310 int xy8
= x8
+y8
*b8_stride
;
311 int xy4
= 3*x8
+y8
*b4_stride
;
314 if(is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
316 h
->sub_mb_type
[i8
] = sub_mb_type
;
318 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, (uint8_t)ref
[0], 1);
319 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
*4]], 2, 2, 8, (uint8_t)ref
[1], 1);
320 if(!IS_INTRA(mb_type_col
[y8
]) && !h
->ref_list
[1][0].long_ref
321 && ( (l1ref0
[xy8
] == 0 && FFABS(l1mv0
[xy4
][0]) <= 1 && FFABS(l1mv0
[xy4
][1]) <= 1)
322 || (l1ref0
[xy8
] < 0 && l1ref1
[xy8
] == 0 && FFABS(l1mv1
[xy4
][0]) <= 1 && FFABS(l1mv1
[xy4
][1]) <= 1))){
333 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, a
, 4);
334 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, b
, 4);
336 if(!is_b8x8
&& !(n
&3))
337 *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
;
338 }else if(IS_16X16(*mb_type
)){
341 fill_rectangle(&h
->ref_cache
[0][scan8
[0]], 4, 4, 8, (uint8_t)ref
[0], 1);
342 fill_rectangle(&h
->ref_cache
[1][scan8
[0]], 4, 4, 8, (uint8_t)ref
[1], 1);
343 if(!IS_INTRA(mb_type_col
[0]) && !h
->ref_list
[1][0].long_ref
344 && ( (l1ref0
[0] == 0 && FFABS(l1mv0
[0][0]) <= 1 && FFABS(l1mv0
[0][1]) <= 1)
345 || (l1ref0
[0] < 0 && l1ref1
[0] == 0 && FFABS(l1mv1
[0][0]) <= 1 && FFABS(l1mv1
[0][1]) <= 1
346 && h
->x264_build
>33U))){
356 fill_rectangle(&h
->mv_cache
[0][scan8
[0]], 4, 4, 8, a
, 4);
357 fill_rectangle(&h
->mv_cache
[1][scan8
[0]], 4, 4, 8, b
, 4);
360 for(i8
=0; i8
<4; i8
++){
362 const int y8
= i8
>>1;
364 if(is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
366 h
->sub_mb_type
[i8
] = sub_mb_type
;
368 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, mv
[0], 4);
369 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, mv
[1], 4);
370 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, (uint8_t)ref
[0], 1);
371 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
*4]], 2, 2, 8, (uint8_t)ref
[1], 1);
373 assert(b8_stride
==2);
375 if(!IS_INTRA(mb_type_col
[0]) && !h
->ref_list
[1][0].long_ref
&& ( l1ref0
[i8
] == 0
376 || (l1ref0
[i8
] < 0 && l1ref1
[i8
] == 0
377 && h
->x264_build
>33U))){
378 const int16_t (*l1mv
)[2]= l1ref0
[i8
] == 0 ? l1mv0
: l1mv1
;
379 if(IS_SUB_8X8(sub_mb_type
)){
380 const int16_t *mv_col
= l1mv
[x8
*3 + y8
*3*b4_stride
];
381 if(FFABS(mv_col
[0]) <= 1 && FFABS(mv_col
[1]) <= 1){
383 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 4);
385 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 4);
390 for(i4
=0; i4
<4; i4
++){
391 const int16_t *mv_col
= l1mv
[x8
*2 + (i4
&1) + (y8
*2 + (i4
>>1))*b4_stride
];
392 if(FFABS(mv_col
[0]) <= 1 && FFABS(mv_col
[1]) <= 1){
394 AV_ZERO32(h
->mv_cache
[0][scan8
[i8
*4+i4
]]);
396 AV_ZERO32(h
->mv_cache
[1][scan8
[i8
*4+i4
]]);
401 h
->sub_mb_type
[i8
]+= MB_TYPE_16x16
- MB_TYPE_8x8
;
406 if(!is_b8x8
&& !(n
&15))
407 *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
;
411 static void pred_temp_direct_motion(H264Context
* const h
, int *mb_type
){
413 int b4_stride
= h
->b_stride
;
414 int mb_xy
= h
->mb_xy
, mb_y
= h
->mb_y
;
416 const int16_t (*l1mv0
)[2], (*l1mv1
)[2];
417 const int8_t *l1ref0
, *l1ref1
;
418 const int is_b8x8
= IS_8X8(*mb_type
);
419 unsigned int sub_mb_type
;
422 assert(h
->ref_list
[1][0].reference
& 3);
424 await_reference_mb_row(h
, &h
->ref_list
[1][0], h
->mb_y
+ !!IS_INTERLACED(*mb_type
));
426 if (IS_INTERLACED(h
->ref_list
[1][0].mb_type
[mb_xy
])) { // AFL/AFR/FR/FL -> AFL/FL
427 if (!IS_INTERLACED(*mb_type
)) { // AFR/FR -> AFL/FL
428 mb_y
= (h
->mb_y
&~1) + h
->col_parity
;
429 mb_xy
= h
->mb_x
+ ((h
->mb_y
&~1) + h
->col_parity
)*h
->mb_stride
;
432 mb_y
+= h
->col_fieldoff
;
433 mb_xy
+= h
->mb_stride
*h
->col_fieldoff
; // non zero for FL -> FL & differ parity
436 }else{ // AFL/AFR/FR/FL -> AFR/FR
437 if(IS_INTERLACED(*mb_type
)){ // AFL /FL -> AFR/FR
439 mb_xy
= h
->mb_x
+ (h
->mb_y
&~1)*h
->mb_stride
;
440 mb_type_col
[0] = h
->ref_list
[1][0].mb_type
[mb_xy
];
441 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
+ h
->mb_stride
];
442 b8_stride
= 2+4*h
->mb_stride
;
444 if (IS_INTERLACED(mb_type_col
[0]) != IS_INTERLACED(mb_type_col
[1])) {
445 mb_type_col
[0] &= ~MB_TYPE_INTERLACED
;
446 mb_type_col
[1] &= ~MB_TYPE_INTERLACED
;
449 sub_mb_type
= MB_TYPE_16x16
|MB_TYPE_P0L0
|MB_TYPE_P0L1
|MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
451 if( (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)
452 && (mb_type_col
[1] & MB_TYPE_16x16_OR_INTRA
)
454 *mb_type
|= MB_TYPE_16x8
|MB_TYPE_L0L1
|MB_TYPE_DIRECT2
; /* B_16x8 */
456 *mb_type
|= MB_TYPE_8x8
|MB_TYPE_L0L1
;
458 }else{ // AFR/FR -> AFR/FR
461 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
];
463 sub_mb_type
= MB_TYPE_16x16
|MB_TYPE_P0L0
|MB_TYPE_P0L1
|MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
464 if(!is_b8x8
&& (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)){
465 *mb_type
|= MB_TYPE_16x16
|MB_TYPE_P0L0
|MB_TYPE_P0L1
|MB_TYPE_DIRECT2
; /* B_16x16 */
466 }else if(!is_b8x8
&& (mb_type_col
[0] & (MB_TYPE_16x8
|MB_TYPE_8x16
))){
467 *mb_type
|= MB_TYPE_L0L1
|MB_TYPE_DIRECT2
| (mb_type_col
[0] & (MB_TYPE_16x8
|MB_TYPE_8x16
));
469 if(!h
->sps
.direct_8x8_inference_flag
){
470 /* FIXME save sub mb types from previous frames (or derive from MVs)
471 * so we know exactly what block size to use */
472 sub_mb_type
= MB_TYPE_8x8
|MB_TYPE_P0L0
|MB_TYPE_P0L1
|MB_TYPE_DIRECT2
; /* B_SUB_4x4 */
474 *mb_type
|= MB_TYPE_8x8
|MB_TYPE_L0L1
;
479 await_reference_mb_row(h
, &h
->ref_list
[1][0], mb_y
);
481 l1mv0
= &h
->ref_list
[1][0].motion_val
[0][h
->mb2b_xy
[mb_xy
]];
482 l1mv1
= &h
->ref_list
[1][0].motion_val
[1][h
->mb2b_xy
[mb_xy
]];
483 l1ref0
= &h
->ref_list
[1][0].ref_index
[0][4 * mb_xy
];
484 l1ref1
= &h
->ref_list
[1][0].ref_index
[1][4 * mb_xy
];
489 l1mv0
+= 2*b4_stride
;
490 l1mv1
+= 2*b4_stride
;
495 const int *map_col_to_list0
[2] = {h
->map_col_to_list0
[0], h
->map_col_to_list0
[1]};
496 const int *dist_scale_factor
= h
->dist_scale_factor
;
499 if(FRAME_MBAFF
&& IS_INTERLACED(*mb_type
)){
500 map_col_to_list0
[0] = h
->map_col_to_list0_field
[h
->mb_y
&1][0];
501 map_col_to_list0
[1] = h
->map_col_to_list0_field
[h
->mb_y
&1][1];
502 dist_scale_factor
=h
->dist_scale_factor_field
[h
->mb_y
&1];
504 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
506 if(IS_INTERLACED(*mb_type
) != IS_INTERLACED(mb_type_col
[0])){
507 int y_shift
= 2*!IS_INTERLACED(*mb_type
);
508 assert(h
->sps
.direct_8x8_inference_flag
);
510 for(i8
=0; i8
<4; i8
++){
512 const int y8
= i8
>>1;
514 const int16_t (*l1mv
)[2]= l1mv0
;
516 if(is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
518 h
->sub_mb_type
[i8
] = sub_mb_type
;
520 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 1);
521 if(IS_INTRA(mb_type_col
[y8
])){
522 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 1);
523 fill_rectangle(&h
-> mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 4);
524 fill_rectangle(&h
-> mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 4);
528 ref0
= l1ref0
[x8
+ y8
*b8_stride
];
530 ref0
= map_col_to_list0
[0][ref0
+ ref_offset
];
532 ref0
= map_col_to_list0
[1][l1ref1
[x8
+ y8
*b8_stride
] + ref_offset
];
535 scale
= dist_scale_factor
[ref0
];
536 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, ref0
, 1);
539 const int16_t *mv_col
= l1mv
[x8
*3 + y8
*b4_stride
];
540 int my_col
= (mv_col
[1]<<y_shift
)/2;
541 int mx
= (scale
* mv_col
[0] + 128) >> 8;
542 int my
= (scale
* my_col
+ 128) >> 8;
543 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, pack16to32(mx
,my
), 4);
544 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, pack16to32(mx
-mv_col
[0],my
-my_col
), 4);
550 /* one-to-one mv scaling */
552 if(IS_16X16(*mb_type
)){
555 fill_rectangle(&h
->ref_cache
[1][scan8
[0]], 4, 4, 8, 0, 1);
556 if(IS_INTRA(mb_type_col
[0])){
559 const int ref0
= l1ref0
[0] >= 0 ? map_col_to_list0
[0][l1ref0
[0] + ref_offset
]
560 : map_col_to_list0
[1][l1ref1
[0] + ref_offset
];
561 const int scale
= dist_scale_factor
[ref0
];
562 const int16_t *mv_col
= l1ref0
[0] >= 0 ? l1mv0
[0] : l1mv1
[0];
564 mv_l0
[0] = (scale
* mv_col
[0] + 128) >> 8;
565 mv_l0
[1] = (scale
* mv_col
[1] + 128) >> 8;
567 mv0
= pack16to32(mv_l0
[0],mv_l0
[1]);
568 mv1
= pack16to32(mv_l0
[0]-mv_col
[0],mv_l0
[1]-mv_col
[1]);
570 fill_rectangle(&h
->ref_cache
[0][scan8
[0]], 4, 4, 8, ref
, 1);
571 fill_rectangle(&h
-> mv_cache
[0][scan8
[0]], 4, 4, 8, mv0
, 4);
572 fill_rectangle(&h
-> mv_cache
[1][scan8
[0]], 4, 4, 8, mv1
, 4);
574 for(i8
=0; i8
<4; i8
++){
576 const int y8
= i8
>>1;
578 const int16_t (*l1mv
)[2]= l1mv0
;
580 if(is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
582 h
->sub_mb_type
[i8
] = sub_mb_type
;
583 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 1);
584 if(IS_INTRA(mb_type_col
[0])){
585 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 1);
586 fill_rectangle(&h
-> mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, 0, 4);
587 fill_rectangle(&h
-> mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, 0, 4);
591 assert(b8_stride
== 2);
594 ref0
= map_col_to_list0
[0][ref0
+ ref_offset
];
596 ref0
= map_col_to_list0
[1][l1ref1
[i8
] + ref_offset
];
599 scale
= dist_scale_factor
[ref0
];
601 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
*4]], 2, 2, 8, ref0
, 1);
602 if(IS_SUB_8X8(sub_mb_type
)){
603 const int16_t *mv_col
= l1mv
[x8
*3 + y8
*3*b4_stride
];
604 int mx
= (scale
* mv_col
[0] + 128) >> 8;
605 int my
= (scale
* mv_col
[1] + 128) >> 8;
606 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
*4]], 2, 2, 8, pack16to32(mx
,my
), 4);
607 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
*4]], 2, 2, 8, pack16to32(mx
-mv_col
[0],my
-mv_col
[1]), 4);
609 for(i4
=0; i4
<4; i4
++){
610 const int16_t *mv_col
= l1mv
[x8
*2 + (i4
&1) + (y8
*2 + (i4
>>1))*b4_stride
];
611 int16_t *mv_l0
= h
->mv_cache
[0][scan8
[i8
*4+i4
]];
612 mv_l0
[0] = (scale
* mv_col
[0] + 128) >> 8;
613 mv_l0
[1] = (scale
* mv_col
[1] + 128) >> 8;
614 AV_WN32A(h
->mv_cache
[1][scan8
[i8
*4+i4
]],
615 pack16to32(mv_l0
[0]-mv_col
[0],mv_l0
[1]-mv_col
[1]));
622 void ff_h264_pred_direct_motion(H264Context
* const h
, int *mb_type
){
623 if(h
->direct_spatial_mv_pred
){
624 pred_spatial_direct_motion(h
, mb_type
);
626 pred_temp_direct_motion(h
, mb_type
);