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
24 * H.264 / AVC / MPEG4 part10 direct mb/block decoding.
25 * @author Michael Niedermayer <michaelni@gmx.at>
31 #include "mpegutils.h"
32 #include "rectangle.h"
37 static int get_scale_factor(H264Context
*const h
, int poc
, int poc1
, int i
)
39 int poc0
= h
->ref_list
[0][i
].poc
;
40 int td
= av_clip(poc1
- poc0
, -128, 127);
41 if (td
== 0 || h
->ref_list
[0][i
].long_ref
) {
44 int tb
= av_clip(poc
- poc0
, -128, 127);
45 int tx
= (16384 + (FFABS(td
) >> 1)) / td
;
46 return av_clip((tb
* tx
+ 32) >> 6, -1024, 1023);
50 void ff_h264_direct_dist_scale_factor(H264Context
*const h
)
52 const int poc
= FIELD_PICTURE(h
) ? h
->cur_pic_ptr
->field_poc
[h
->picture_structure
== PICT_BOTTOM_FIELD
]
53 : h
->cur_pic_ptr
->poc
;
54 const int poc1
= h
->ref_list
[1][0].poc
;
58 for (field
= 0; field
< 2; field
++) {
59 const int poc
= h
->cur_pic_ptr
->field_poc
[field
];
60 const int poc1
= h
->ref_list
[1][0].field_poc
[field
];
61 for (i
= 0; i
< 2 * h
->ref_count
[0]; i
++)
62 h
->dist_scale_factor_field
[field
][i
^ field
] =
63 get_scale_factor(h
, poc
, poc1
, i
+ 16);
66 for (i
= 0; i
< h
->ref_count
[0]; i
++)
67 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
,
71 int field
, int colfield
, int mbafi
)
73 H264Picture
*const ref1
= &h
->ref_list
[1][0];
74 int j
, old_ref
, rfield
;
75 int start
= mbafi
? 16 : 0;
76 int end
= mbafi
? 16 + 2 * h
->ref_count
[0] : h
->ref_count
[0];
77 int interl
= mbafi
|| h
->picture_structure
!= PICT_FRAME
;
79 /* bogus; fills in for missing frames */
80 memset(map
[list
], 0, sizeof(map
[list
]));
82 for (rfield
= 0; rfield
< 2; rfield
++) {
83 for (old_ref
= 0; old_ref
< ref1
->ref_count
[colfield
][list
]; old_ref
++) {
84 int poc
= ref1
->ref_poc
[colfield
][list
][old_ref
];
88 // FIXME: store all MBAFF references so this is not needed
89 else if (interl
&& (poc
& 3) == 3)
90 poc
= (poc
& ~3) + rfield
+ 1;
92 for (j
= start
; j
< end
; j
++) {
93 if (4 * h
->ref_list
[0][j
].frame_num
+
94 (h
->ref_list
[0][j
].reference
& 3) == poc
) {
95 int cur_ref
= mbafi
? (j
- 16) ^ field
: j
;
97 map
[list
][2 * old_ref
+ (rfield
^ field
) + 16] = cur_ref
;
98 if (rfield
== field
|| !interl
)
99 map
[list
][old_ref
] = cur_ref
;
107 void ff_h264_direct_ref_list_init(H264Context
*const h
)
109 H264Picture
*const ref1
= &h
->ref_list
[1][0];
110 H264Picture
*const cur
= h
->cur_pic_ptr
;
112 int sidx
= (h
->picture_structure
& 1) ^ 1;
113 int ref1sidx
= (ref1
->reference
& 1) ^ 1;
115 for (list
= 0; list
< 2; list
++) {
116 cur
->ref_count
[sidx
][list
] = h
->ref_count
[list
];
117 for (j
= 0; j
< h
->ref_count
[list
]; j
++)
118 cur
->ref_poc
[sidx
][list
][j
] = 4 * h
->ref_list
[list
][j
].frame_num
+
119 (h
->ref_list
[list
][j
].reference
& 3);
122 if (h
->picture_structure
== PICT_FRAME
) {
123 memcpy(cur
->ref_count
[1], cur
->ref_count
[0], sizeof(cur
->ref_count
[0]));
124 memcpy(cur
->ref_poc
[1], cur
->ref_poc
[0], sizeof(cur
->ref_poc
[0]));
127 cur
->mbaff
= FRAME_MBAFF(h
);
130 if (h
->picture_structure
== PICT_FRAME
) {
131 int cur_poc
= h
->cur_pic_ptr
->poc
;
132 int *col_poc
= h
->ref_list
[1]->field_poc
;
133 h
->col_parity
= (FFABS(col_poc
[0] - cur_poc
) >=
134 FFABS(col_poc
[1] - cur_poc
));
136 sidx
= h
->col_parity
;
137 // FL -> FL & differ parity
138 } else if (!(h
->picture_structure
& h
->ref_list
[1][0].reference
) &&
139 !h
->ref_list
[1][0].mbaff
) {
140 h
->col_fieldoff
= 2 * h
->ref_list
[1][0].reference
- 3;
143 if (h
->slice_type_nos
!= AV_PICTURE_TYPE_B
|| h
->direct_spatial_mv_pred
)
146 for (list
= 0; list
< 2; list
++) {
147 fill_colmap(h
, h
->map_col_to_list0
, list
, sidx
, ref1sidx
, 0);
149 for (field
= 0; field
< 2; field
++)
150 fill_colmap(h
, h
->map_col_to_list0_field
[field
], list
, field
,
155 static void await_reference_mb_row(H264Context
*const h
, H264Picture
*ref
,
158 int ref_field
= ref
->reference
- 1;
159 int ref_field_picture
= ref
->field_picture
;
160 int ref_height
= 16 * h
->mb_height
>> ref_field_picture
;
162 if (!HAVE_THREADS
|| !(h
->avctx
->active_thread_type
& FF_THREAD_FRAME
))
165 /* FIXME: It can be safe to access mb stuff
166 * even if pixels aren't deblocked yet. */
168 ff_thread_await_progress(&ref
->tf
,
169 FFMIN(16 * mb_y
>> ref_field_picture
,
171 ref_field_picture
&& ref_field
);
174 static void pred_spatial_direct_motion(H264Context
*const h
, int *mb_type
)
177 int b4_stride
= h
->b_stride
;
178 int mb_xy
= h
->mb_xy
, mb_y
= h
->mb_y
;
180 const int16_t (*l1mv0
)[2], (*l1mv1
)[2];
181 const int8_t *l1ref0
, *l1ref1
;
182 const int is_b8x8
= IS_8X8(*mb_type
);
183 unsigned int sub_mb_type
= MB_TYPE_L0L1
;
189 assert(h
->ref_list
[1][0].reference
& 3);
191 await_reference_mb_row(h
, &h
->ref_list
[1][0],
192 h
->mb_y
+ !!IS_INTERLACED(*mb_type
));
194 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16 | MB_TYPE_INTRA4x4 | \
195 MB_TYPE_INTRA16x16 | MB_TYPE_INTRA_PCM)
197 /* ref = min(neighbors) */
198 for (list
= 0; list
< 2; list
++) {
199 int left_ref
= h
->ref_cache
[list
][scan8
[0] - 1];
200 int top_ref
= h
->ref_cache
[list
][scan8
[0] - 8];
201 int refc
= h
->ref_cache
[list
][scan8
[0] - 8 + 4];
202 const int16_t *C
= h
->mv_cache
[list
][scan8
[0] - 8 + 4];
203 if (refc
== PART_NOT_AVAILABLE
) {
204 refc
= h
->ref_cache
[list
][scan8
[0] - 8 - 1];
205 C
= h
->mv_cache
[list
][scan8
[0] - 8 - 1];
207 ref
[list
] = FFMIN3((unsigned)left_ref
,
210 if (ref
[list
] >= 0) {
211 /* This is just pred_motion() but with the cases removed that
212 * cannot happen for direct blocks. */
213 const int16_t *const A
= h
->mv_cache
[list
][scan8
[0] - 1];
214 const int16_t *const B
= h
->mv_cache
[list
][scan8
[0] - 8];
216 int match_count
= (left_ref
== ref
[list
]) +
217 (top_ref
== ref
[list
]) +
220 if (match_count
> 1) { // most common
221 mv
[list
] = pack16to32(mid_pred(A
[0], B
[0], C
[0]),
222 mid_pred(A
[1], B
[1], C
[1]));
224 assert(match_count
== 1);
225 if (left_ref
== ref
[list
])
226 mv
[list
] = AV_RN32A(A
);
227 else if (top_ref
== ref
[list
])
228 mv
[list
] = AV_RN32A(B
);
230 mv
[list
] = AV_RN32A(C
);
232 av_assert2(ref
[list
] < (h
->ref_count
[list
] << !!FRAME_MBAFF(h
)));
234 int mask
= ~(MB_TYPE_L0
<< (2 * list
));
242 if (ref
[0] < 0 && ref
[1] < 0) {
245 *mb_type
|= MB_TYPE_L0L1
;
246 sub_mb_type
|= MB_TYPE_L0L1
;
249 if (!(is_b8x8
| mv
[0] | mv
[1])) {
250 fill_rectangle(&h
->ref_cache
[0][scan8
[0]], 4, 4, 8, (uint8_t)ref
[0], 1);
251 fill_rectangle(&h
->ref_cache
[1][scan8
[0]], 4, 4, 8, (uint8_t)ref
[1], 1);
252 fill_rectangle(&h
->mv_cache
[0][scan8
[0]], 4, 4, 8, 0, 4);
253 fill_rectangle(&h
->mv_cache
[1][scan8
[0]], 4, 4, 8, 0, 4);
254 *mb_type
= (*mb_type
& ~(MB_TYPE_8x8
| MB_TYPE_16x8
| MB_TYPE_8x16
|
255 MB_TYPE_P1L0
| MB_TYPE_P1L1
)) |
256 MB_TYPE_16x16
| MB_TYPE_DIRECT2
;
260 if (IS_INTERLACED(h
->ref_list
[1][0].mb_type
[mb_xy
])) { // AFL/AFR/FR/FL -> AFL/FL
261 if (!IS_INTERLACED(*mb_type
)) { // AFR/FR -> AFL/FL
262 mb_y
= (h
->mb_y
& ~1) + h
->col_parity
;
264 ((h
->mb_y
& ~1) + h
->col_parity
) * h
->mb_stride
;
267 mb_y
+= h
->col_fieldoff
;
268 mb_xy
+= h
->mb_stride
* h
->col_fieldoff
; // non-zero for FL -> FL & differ parity
271 } else { // AFL/AFR/FR/FL -> AFR/FR
272 if (IS_INTERLACED(*mb_type
)) { // AFL /FL -> AFR/FR
274 mb_xy
= (h
->mb_y
& ~1) * h
->mb_stride
+ h
->mb_x
;
275 mb_type_col
[0] = h
->ref_list
[1][0].mb_type
[mb_xy
];
276 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
+ h
->mb_stride
];
277 b8_stride
= 2 + 4 * h
->mb_stride
;
279 if (IS_INTERLACED(mb_type_col
[0]) !=
280 IS_INTERLACED(mb_type_col
[1])) {
281 mb_type_col
[0] &= ~MB_TYPE_INTERLACED
;
282 mb_type_col
[1] &= ~MB_TYPE_INTERLACED
;
285 sub_mb_type
|= MB_TYPE_16x16
| MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
286 if ((mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
) &&
287 (mb_type_col
[1] & MB_TYPE_16x16_OR_INTRA
) &&
289 *mb_type
|= MB_TYPE_16x8
| MB_TYPE_DIRECT2
; /* B_16x8 */
291 *mb_type
|= MB_TYPE_8x8
;
293 } else { // AFR/FR -> AFR/FR
296 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
];
298 sub_mb_type
|= MB_TYPE_16x16
| MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
299 if (!is_b8x8
&& (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)) {
300 *mb_type
|= MB_TYPE_16x16
| MB_TYPE_DIRECT2
; /* B_16x16 */
301 } else if (!is_b8x8
&&
302 (mb_type_col
[0] & (MB_TYPE_16x8
| MB_TYPE_8x16
))) {
303 *mb_type
|= MB_TYPE_DIRECT2
|
304 (mb_type_col
[0] & (MB_TYPE_16x8
| MB_TYPE_8x16
));
306 if (!h
->sps
.direct_8x8_inference_flag
) {
307 /* FIXME: Save sub mb types from previous frames (or derive
308 * from MVs) so we know exactly what block size to use. */
309 sub_mb_type
+= (MB_TYPE_8x8
- MB_TYPE_16x16
); /* B_SUB_4x4 */
311 *mb_type
|= MB_TYPE_8x8
;
316 await_reference_mb_row(h
, &h
->ref_list
[1][0], mb_y
);
318 l1mv0
= (void*)&h
->ref_list
[1][0].motion_val
[0][h
->mb2b_xy
[mb_xy
]];
319 l1mv1
= (void*)&h
->ref_list
[1][0].motion_val
[1][h
->mb2b_xy
[mb_xy
]];
320 l1ref0
= &h
->ref_list
[1][0].ref_index
[0][4 * mb_xy
];
321 l1ref1
= &h
->ref_list
[1][0].ref_index
[1][4 * mb_xy
];
326 l1mv0
+= 2 * b4_stride
;
327 l1mv1
+= 2 * b4_stride
;
331 if (IS_INTERLACED(*mb_type
) != IS_INTERLACED(mb_type_col
[0])) {
333 for (i8
= 0; i8
< 4; i8
++) {
336 int xy8
= x8
+ y8
* b8_stride
;
337 int xy4
= x8
* 3 + y8
* b4_stride
;
340 if (is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
342 h
->sub_mb_type
[i8
] = sub_mb_type
;
344 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
* 4]], 2, 2, 8,
346 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
* 4]], 2, 2, 8,
348 if (!IS_INTRA(mb_type_col
[y8
]) && !h
->ref_list
[1][0].long_ref
&&
349 ((l1ref0
[xy8
] == 0 &&
350 FFABS(l1mv0
[xy4
][0]) <= 1 &&
351 FFABS(l1mv0
[xy4
][1]) <= 1) ||
354 FFABS(l1mv1
[xy4
][0]) <= 1 &&
355 FFABS(l1mv1
[xy4
][1]) <= 1))) {
367 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
* 4]], 2, 2, 8, a
, 4);
368 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
* 4]], 2, 2, 8, b
, 4);
370 if (!is_b8x8
&& !(n
& 3))
371 *mb_type
= (*mb_type
& ~(MB_TYPE_8x8
| MB_TYPE_16x8
| MB_TYPE_8x16
|
372 MB_TYPE_P1L0
| MB_TYPE_P1L1
)) |
373 MB_TYPE_16x16
| MB_TYPE_DIRECT2
;
374 } else if (IS_16X16(*mb_type
)) {
377 fill_rectangle(&h
->ref_cache
[0][scan8
[0]], 4, 4, 8, (uint8_t)ref
[0], 1);
378 fill_rectangle(&h
->ref_cache
[1][scan8
[0]], 4, 4, 8, (uint8_t)ref
[1], 1);
379 if (!IS_INTRA(mb_type_col
[0]) && !h
->ref_list
[1][0].long_ref
&&
381 FFABS(l1mv0
[0][0]) <= 1 &&
382 FFABS(l1mv0
[0][1]) <= 1) ||
383 (l1ref0
[0] < 0 && !l1ref1
[0] &&
384 FFABS(l1mv1
[0][0]) <= 1 &&
385 FFABS(l1mv1
[0][1]) <= 1 &&
386 h
->x264_build
> 33U))) {
396 fill_rectangle(&h
->mv_cache
[0][scan8
[0]], 4, 4, 8, a
, 4);
397 fill_rectangle(&h
->mv_cache
[1][scan8
[0]], 4, 4, 8, b
, 4);
400 for (i8
= 0; i8
< 4; i8
++) {
401 const int x8
= i8
& 1;
402 const int y8
= i8
>> 1;
404 if (is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
406 h
->sub_mb_type
[i8
] = sub_mb_type
;
408 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
* 4]], 2, 2, 8, mv
[0], 4);
409 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
* 4]], 2, 2, 8, mv
[1], 4);
410 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
* 4]], 2, 2, 8,
412 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
* 4]], 2, 2, 8,
415 assert(b8_stride
== 2);
417 if (!IS_INTRA(mb_type_col
[0]) && !h
->ref_list
[1][0].long_ref
&&
421 h
->x264_build
> 33U))) {
422 const int16_t (*l1mv
)[2] = l1ref0
[i8
] == 0 ? l1mv0
: l1mv1
;
423 if (IS_SUB_8X8(sub_mb_type
)) {
424 const int16_t *mv_col
= l1mv
[x8
* 3 + y8
* 3 * b4_stride
];
425 if (FFABS(mv_col
[0]) <= 1 && FFABS(mv_col
[1]) <= 1) {
427 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
* 4]], 2, 2,
430 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
* 4]], 2, 2,
436 for (i4
= 0; i4
< 4; i4
++) {
437 const int16_t *mv_col
= l1mv
[x8
* 2 + (i4
& 1) +
438 (y8
* 2 + (i4
>> 1)) * b4_stride
];
439 if (FFABS(mv_col
[0]) <= 1 && FFABS(mv_col
[1]) <= 1) {
441 AV_ZERO32(h
->mv_cache
[0][scan8
[i8
* 4 + i4
]]);
443 AV_ZERO32(h
->mv_cache
[1][scan8
[i8
* 4 + i4
]]);
448 h
->sub_mb_type
[i8
] += MB_TYPE_16x16
- MB_TYPE_8x8
;
453 if (!is_b8x8
&& !(n
& 15))
454 *mb_type
= (*mb_type
& ~(MB_TYPE_8x8
| MB_TYPE_16x8
| MB_TYPE_8x16
|
455 MB_TYPE_P1L0
| MB_TYPE_P1L1
)) |
456 MB_TYPE_16x16
| MB_TYPE_DIRECT2
;
460 static void pred_temp_direct_motion(H264Context
*const h
, int *mb_type
)
463 int b4_stride
= h
->b_stride
;
464 int mb_xy
= h
->mb_xy
, mb_y
= h
->mb_y
;
466 const int16_t (*l1mv0
)[2], (*l1mv1
)[2];
467 const int8_t *l1ref0
, *l1ref1
;
468 const int is_b8x8
= IS_8X8(*mb_type
);
469 unsigned int sub_mb_type
;
472 assert(h
->ref_list
[1][0].reference
& 3);
474 await_reference_mb_row(h
, &h
->ref_list
[1][0],
475 h
->mb_y
+ !!IS_INTERLACED(*mb_type
));
477 if (IS_INTERLACED(h
->ref_list
[1][0].mb_type
[mb_xy
])) { // AFL/AFR/FR/FL -> AFL/FL
478 if (!IS_INTERLACED(*mb_type
)) { // AFR/FR -> AFL/FL
479 mb_y
= (h
->mb_y
& ~1) + h
->col_parity
;
481 ((h
->mb_y
& ~1) + h
->col_parity
) * h
->mb_stride
;
484 mb_y
+= h
->col_fieldoff
;
485 mb_xy
+= h
->mb_stride
* h
->col_fieldoff
; // non-zero for FL -> FL & differ parity
488 } else { // AFL/AFR/FR/FL -> AFR/FR
489 if (IS_INTERLACED(*mb_type
)) { // AFL /FL -> AFR/FR
491 mb_xy
= h
->mb_x
+ (h
->mb_y
& ~1) * h
->mb_stride
;
492 mb_type_col
[0] = h
->ref_list
[1][0].mb_type
[mb_xy
];
493 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
+ h
->mb_stride
];
494 b8_stride
= 2 + 4 * h
->mb_stride
;
496 if (IS_INTERLACED(mb_type_col
[0]) !=
497 IS_INTERLACED(mb_type_col
[1])) {
498 mb_type_col
[0] &= ~MB_TYPE_INTERLACED
;
499 mb_type_col
[1] &= ~MB_TYPE_INTERLACED
;
502 sub_mb_type
= MB_TYPE_16x16
| MB_TYPE_P0L0
| MB_TYPE_P0L1
|
503 MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
505 if ((mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
) &&
506 (mb_type_col
[1] & MB_TYPE_16x16_OR_INTRA
) &&
508 *mb_type
|= MB_TYPE_16x8
| MB_TYPE_L0L1
|
509 MB_TYPE_DIRECT2
; /* B_16x8 */
511 *mb_type
|= MB_TYPE_8x8
| MB_TYPE_L0L1
;
513 } else { // AFR/FR -> AFR/FR
516 mb_type_col
[1] = h
->ref_list
[1][0].mb_type
[mb_xy
];
518 sub_mb_type
= MB_TYPE_16x16
| MB_TYPE_P0L0
| MB_TYPE_P0L1
|
519 MB_TYPE_DIRECT2
; /* B_SUB_8x8 */
520 if (!is_b8x8
&& (mb_type_col
[0] & MB_TYPE_16x16_OR_INTRA
)) {
521 *mb_type
|= MB_TYPE_16x16
| MB_TYPE_P0L0
| MB_TYPE_P0L1
|
522 MB_TYPE_DIRECT2
; /* B_16x16 */
523 } else if (!is_b8x8
&&
524 (mb_type_col
[0] & (MB_TYPE_16x8
| MB_TYPE_8x16
))) {
525 *mb_type
|= MB_TYPE_L0L1
| MB_TYPE_DIRECT2
|
526 (mb_type_col
[0] & (MB_TYPE_16x8
| MB_TYPE_8x16
));
528 if (!h
->sps
.direct_8x8_inference_flag
) {
529 /* FIXME: save sub mb types from previous frames (or derive
530 * from MVs) so we know exactly what block size to use */
531 sub_mb_type
= MB_TYPE_8x8
| MB_TYPE_P0L0
| MB_TYPE_P0L1
|
532 MB_TYPE_DIRECT2
; /* B_SUB_4x4 */
534 *mb_type
|= MB_TYPE_8x8
| MB_TYPE_L0L1
;
539 await_reference_mb_row(h
, &h
->ref_list
[1][0], mb_y
);
541 l1mv0
= (void*)&h
->ref_list
[1][0].motion_val
[0][h
->mb2b_xy
[mb_xy
]];
542 l1mv1
= (void*)&h
->ref_list
[1][0].motion_val
[1][h
->mb2b_xy
[mb_xy
]];
543 l1ref0
= &h
->ref_list
[1][0].ref_index
[0][4 * mb_xy
];
544 l1ref1
= &h
->ref_list
[1][0].ref_index
[1][4 * mb_xy
];
549 l1mv0
+= 2 * b4_stride
;
550 l1mv1
+= 2 * b4_stride
;
555 const int *map_col_to_list0
[2] = { h
->map_col_to_list0
[0],
556 h
->map_col_to_list0
[1] };
557 const int *dist_scale_factor
= h
->dist_scale_factor
;
560 if (FRAME_MBAFF(h
) && IS_INTERLACED(*mb_type
)) {
561 map_col_to_list0
[0] = h
->map_col_to_list0_field
[h
->mb_y
& 1][0];
562 map_col_to_list0
[1] = h
->map_col_to_list0_field
[h
->mb_y
& 1][1];
563 dist_scale_factor
= h
->dist_scale_factor_field
[h
->mb_y
& 1];
565 ref_offset
= (h
->ref_list
[1][0].mbaff
<< 4) & (mb_type_col
[0] >> 3);
567 if (IS_INTERLACED(*mb_type
) != IS_INTERLACED(mb_type_col
[0])) {
568 int y_shift
= 2 * !IS_INTERLACED(*mb_type
);
569 assert(h
->sps
.direct_8x8_inference_flag
);
571 for (i8
= 0; i8
< 4; i8
++) {
572 const int x8
= i8
& 1;
573 const int y8
= i8
>> 1;
575 const int16_t (*l1mv
)[2] = l1mv0
;
577 if (is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
579 h
->sub_mb_type
[i8
] = sub_mb_type
;
581 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
* 4]], 2, 2, 8, 0, 1);
582 if (IS_INTRA(mb_type_col
[y8
])) {
583 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
* 4]], 2, 2, 8, 0, 1);
584 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
* 4]], 2, 2, 8, 0, 4);
585 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
* 4]], 2, 2, 8, 0, 4);
589 ref0
= l1ref0
[x8
+ y8
* b8_stride
];
591 ref0
= map_col_to_list0
[0][ref0
+ ref_offset
];
593 ref0
= map_col_to_list0
[1][l1ref1
[x8
+ y8
* b8_stride
] +
597 scale
= dist_scale_factor
[ref0
];
598 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
* 4]], 2, 2, 8,
602 const int16_t *mv_col
= l1mv
[x8
* 3 + y8
* b4_stride
];
603 int my_col
= (mv_col
[1] << y_shift
) / 2;
604 int mx
= (scale
* mv_col
[0] + 128) >> 8;
605 int my
= (scale
* my_col
+ 128) >> 8;
606 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
* 4]], 2, 2, 8,
607 pack16to32(mx
, my
), 4);
608 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
* 4]], 2, 2, 8,
609 pack16to32(mx
- mv_col
[0], my
- my_col
), 4);
615 /* one-to-one mv scaling */
617 if (IS_16X16(*mb_type
)) {
620 fill_rectangle(&h
->ref_cache
[1][scan8
[0]], 4, 4, 8, 0, 1);
621 if (IS_INTRA(mb_type_col
[0])) {
624 const int ref0
= l1ref0
[0] >= 0 ? map_col_to_list0
[0][l1ref0
[0] + ref_offset
]
625 : map_col_to_list0
[1][l1ref1
[0] + ref_offset
];
626 const int scale
= dist_scale_factor
[ref0
];
627 const int16_t *mv_col
= l1ref0
[0] >= 0 ? l1mv0
[0] : l1mv1
[0];
629 mv_l0
[0] = (scale
* mv_col
[0] + 128) >> 8;
630 mv_l0
[1] = (scale
* mv_col
[1] + 128) >> 8;
632 mv0
= pack16to32(mv_l0
[0], mv_l0
[1]);
633 mv1
= pack16to32(mv_l0
[0] - mv_col
[0], mv_l0
[1] - mv_col
[1]);
635 fill_rectangle(&h
->ref_cache
[0][scan8
[0]], 4, 4, 8, ref
, 1);
636 fill_rectangle(&h
->mv_cache
[0][scan8
[0]], 4, 4, 8, mv0
, 4);
637 fill_rectangle(&h
->mv_cache
[1][scan8
[0]], 4, 4, 8, mv1
, 4);
639 for (i8
= 0; i8
< 4; i8
++) {
640 const int x8
= i8
& 1;
641 const int y8
= i8
>> 1;
643 const int16_t (*l1mv
)[2] = l1mv0
;
645 if (is_b8x8
&& !IS_DIRECT(h
->sub_mb_type
[i8
]))
647 h
->sub_mb_type
[i8
] = sub_mb_type
;
648 fill_rectangle(&h
->ref_cache
[1][scan8
[i8
* 4]], 2, 2, 8, 0, 1);
649 if (IS_INTRA(mb_type_col
[0])) {
650 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
* 4]], 2, 2, 8, 0, 1);
651 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
* 4]], 2, 2, 8, 0, 4);
652 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
* 4]], 2, 2, 8, 0, 4);
656 assert(b8_stride
== 2);
659 ref0
= map_col_to_list0
[0][ref0
+ ref_offset
];
661 ref0
= map_col_to_list0
[1][l1ref1
[i8
] + ref_offset
];
664 scale
= dist_scale_factor
[ref0
];
666 fill_rectangle(&h
->ref_cache
[0][scan8
[i8
* 4]], 2, 2, 8,
668 if (IS_SUB_8X8(sub_mb_type
)) {
669 const int16_t *mv_col
= l1mv
[x8
* 3 + y8
* 3 * b4_stride
];
670 int mx
= (scale
* mv_col
[0] + 128) >> 8;
671 int my
= (scale
* mv_col
[1] + 128) >> 8;
672 fill_rectangle(&h
->mv_cache
[0][scan8
[i8
* 4]], 2, 2, 8,
673 pack16to32(mx
, my
), 4);
674 fill_rectangle(&h
->mv_cache
[1][scan8
[i8
* 4]], 2, 2, 8,
675 pack16to32(mx
- mv_col
[0], my
- mv_col
[1]), 4);
677 for (i4
= 0; i4
< 4; i4
++) {
678 const int16_t *mv_col
= l1mv
[x8
* 2 + (i4
& 1) +
679 (y8
* 2 + (i4
>> 1)) * b4_stride
];
680 int16_t *mv_l0
= h
->mv_cache
[0][scan8
[i8
* 4 + i4
]];
681 mv_l0
[0] = (scale
* mv_col
[0] + 128) >> 8;
682 mv_l0
[1] = (scale
* mv_col
[1] + 128) >> 8;
683 AV_WN32A(h
->mv_cache
[1][scan8
[i8
* 4 + i4
]],
684 pack16to32(mv_l0
[0] - mv_col
[0],
685 mv_l0
[1] - mv_col
[1]));
693 void ff_h264_pred_direct_motion(H264Context
*const h
, int *mb_type
)
695 if (h
->direct_spatial_mv_pred
)
696 pred_spatial_direct_motion(h
, mb_type
);
698 pred_temp_direct_motion(h
, mb_type
);