]> git.sesse.net Git - ffmpeg/blob - libavcodec/h264_direct.c
Merge commit '34d4c605e9a5116d5289b35633ade5b01cacab24'
[ffmpeg] / libavcodec / h264_direct.c
1 /*
2  * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding
3  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21
22 /**
23  * @file
24  * H.264 / AVC / MPEG4 part10 direct mb/block decoding.
25  * @author Michael Niedermayer <michaelni@gmx.at>
26  */
27
28 #include "internal.h"
29 #include "avcodec.h"
30 #include "h264.h"
31 #include "mpegutils.h"
32 #include "rectangle.h"
33 #include "thread.h"
34
35 #include <assert.h>
36
37 static int get_scale_factor(H264SliceContext *sl,
38                             int poc, int poc1, int i)
39 {
40     int poc0 = sl->ref_list[0][i].poc;
41     int td = av_clip_int8(poc1 - poc0);
42     if (td == 0 || sl->ref_list[0][i].long_ref) {
43         return 256;
44     } else {
45         int tb = av_clip_int8(poc - poc0);
46         int tx = (16384 + (FFABS(td) >> 1)) / td;
47         return av_clip_intp2((tb * tx + 32) >> 6, 10);
48     }
49 }
50
51 void ff_h264_direct_dist_scale_factor(const H264Context *const h,
52                                       H264SliceContext *sl)
53 {
54     const int poc  = FIELD_PICTURE(h) ? h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]
55                                       : h->cur_pic_ptr->poc;
56     const int poc1 = sl->ref_list[1][0].poc;
57     int i, field;
58
59     if (FRAME_MBAFF(h))
60         for (field = 0; field < 2; field++) {
61             const int poc  = h->cur_pic_ptr->field_poc[field];
62             const int poc1 = sl->ref_list[1][0].field_poc[field];
63             for (i = 0; i < 2 * sl->ref_count[0]; i++)
64                 sl->dist_scale_factor_field[field][i ^ field] =
65                     get_scale_factor(sl, poc, poc1, i + 16);
66         }
67
68     for (i = 0; i < sl->ref_count[0]; i++)
69         sl->dist_scale_factor[i] = get_scale_factor(sl, poc, poc1, i);
70 }
71
72 static void fill_colmap(const H264Context *h, H264SliceContext *sl,
73                         int map[2][16 + 32], int list,
74                         int field, int colfield, int mbafi)
75 {
76     H264Picture *const ref1 = &sl->ref_list[1][0];
77     int j, old_ref, rfield;
78     int start  = mbafi ? 16                       : 0;
79     int end    = mbafi ? 16 + 2 * sl->ref_count[0] : sl->ref_count[0];
80     int interl = mbafi || h->picture_structure != PICT_FRAME;
81
82     /* bogus; fills in for missing frames */
83     memset(map[list], 0, sizeof(map[list]));
84
85     for (rfield = 0; rfield < 2; rfield++) {
86         for (old_ref = 0; old_ref < ref1->ref_count[colfield][list]; old_ref++) {
87             int poc = ref1->ref_poc[colfield][list][old_ref];
88
89             if (!interl)
90                 poc |= 3;
91             // FIXME: store all MBAFF references so this is not needed
92             else if (interl && (poc & 3) == 3)
93                 poc = (poc & ~3) + rfield + 1;
94
95             for (j = start; j < end; j++) {
96                 if (4 * sl->ref_list[0][j].frame_num +
97                     (sl->ref_list[0][j].reference & 3) == poc) {
98                     int cur_ref = mbafi ? (j - 16) ^ field : j;
99                     if (ref1->mbaff)
100                         map[list][2 * old_ref + (rfield ^ field) + 16] = cur_ref;
101                     if (rfield == field || !interl)
102                         map[list][old_ref] = cur_ref;
103                     break;
104                 }
105             }
106         }
107     }
108 }
109
110 void ff_h264_direct_ref_list_init(const H264Context *const h, H264SliceContext *sl)
111 {
112     H264Picture *const ref1 = &sl->ref_list[1][0];
113     H264Picture *const cur = h->cur_pic_ptr;
114     int list, j, field;
115     int sidx     = (h->picture_structure & 1) ^ 1;
116     int ref1sidx = (ref1->reference      & 1) ^ 1;
117
118     for (list = 0; list < 2; list++) {
119         cur->ref_count[sidx][list] = sl->ref_count[list];
120         for (j = 0; j < sl->ref_count[list]; j++)
121             cur->ref_poc[sidx][list][j] = 4 * sl->ref_list[list][j].frame_num +
122                                           (sl->ref_list[list][j].reference & 3);
123     }
124
125     if (h->picture_structure == PICT_FRAME) {
126         memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
127         memcpy(cur->ref_poc[1],   cur->ref_poc[0],   sizeof(cur->ref_poc[0]));
128     }
129
130     cur->mbaff = FRAME_MBAFF(h);
131
132     sl->col_fieldoff = 0;
133     if (h->picture_structure == PICT_FRAME) {
134         int cur_poc  = h->cur_pic_ptr->poc;
135         int *col_poc = sl->ref_list[1]->field_poc;
136         sl->col_parity = (FFABS(col_poc[0] - cur_poc) >=
137                           FFABS(col_poc[1] - cur_poc));
138         ref1sidx =
139         sidx     = sl->col_parity;
140     // FL -> FL & differ parity
141     } else if (!(h->picture_structure & sl->ref_list[1][0].reference) &&
142                !sl->ref_list[1][0].mbaff) {
143         sl->col_fieldoff = 2 * sl->ref_list[1][0].reference - 3;
144     }
145
146     if (sl->slice_type_nos != AV_PICTURE_TYPE_B || sl->direct_spatial_mv_pred)
147         return;
148
149     for (list = 0; list < 2; list++) {
150         fill_colmap(h, sl, sl->map_col_to_list0, list, sidx, ref1sidx, 0);
151         if (FRAME_MBAFF(h))
152             for (field = 0; field < 2; field++)
153                 fill_colmap(h, sl, sl->map_col_to_list0_field[field], list, field,
154                             field, 1);
155     }
156 }
157
158 static void await_reference_mb_row(const H264Context *const h, H264Picture *ref,
159                                    int mb_y)
160 {
161     int ref_field         = ref->reference - 1;
162     int ref_field_picture = ref->field_picture;
163     int ref_height        = 16 * h->mb_height >> ref_field_picture;
164
165     if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_FRAME))
166         return;
167
168     /* FIXME: It can be safe to access mb stuff
169      * even if pixels aren't deblocked yet. */
170
171     ff_thread_await_progress(&ref->tf,
172                              FFMIN(16 * mb_y >> ref_field_picture,
173                                    ref_height - 1),
174                              ref_field_picture && ref_field);
175 }
176
177 static void pred_spatial_direct_motion(const H264Context *const h, H264SliceContext *sl,
178                                        int *mb_type)
179 {
180     int b8_stride = 2;
181     int b4_stride = h->b_stride;
182     int mb_xy = sl->mb_xy, mb_y = sl->mb_y;
183     int mb_type_col[2];
184     const int16_t (*l1mv0)[2], (*l1mv1)[2];
185     const int8_t *l1ref0, *l1ref1;
186     const int is_b8x8 = IS_8X8(*mb_type);
187     unsigned int sub_mb_type = MB_TYPE_L0L1;
188     int i8, i4;
189     int ref[2];
190     int mv[2];
191     int list;
192
193     assert(sl->ref_list[1][0].reference & 3);
194
195     await_reference_mb_row(h, &sl->ref_list[1][0],
196                            sl->mb_y + !!IS_INTERLACED(*mb_type));
197
198 #define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16 | MB_TYPE_INTRA4x4 | \
199                                 MB_TYPE_INTRA16x16 | MB_TYPE_INTRA_PCM)
200
201     /* ref = min(neighbors) */
202     for (list = 0; list < 2; list++) {
203         int left_ref     = sl->ref_cache[list][scan8[0] - 1];
204         int top_ref      = sl->ref_cache[list][scan8[0] - 8];
205         int refc         = sl->ref_cache[list][scan8[0] - 8 + 4];
206         const int16_t *C = sl->mv_cache[list][scan8[0]  - 8 + 4];
207         if (refc == PART_NOT_AVAILABLE) {
208             refc = sl->ref_cache[list][scan8[0] - 8 - 1];
209             C    = sl->mv_cache[list][scan8[0]  - 8 - 1];
210         }
211         ref[list] = FFMIN3((unsigned)left_ref,
212                            (unsigned)top_ref,
213                            (unsigned)refc);
214         if (ref[list] >= 0) {
215             /* This is just pred_motion() but with the cases removed that
216              * cannot happen for direct blocks. */
217             const int16_t *const A = sl->mv_cache[list][scan8[0] - 1];
218             const int16_t *const B = sl->mv_cache[list][scan8[0] - 8];
219
220             int match_count = (left_ref == ref[list]) +
221                               (top_ref  == ref[list]) +
222                               (refc     == ref[list]);
223
224             if (match_count > 1) { // most common
225                 mv[list] = pack16to32(mid_pred(A[0], B[0], C[0]),
226                                       mid_pred(A[1], B[1], C[1]));
227             } else {
228                 assert(match_count == 1);
229                 if (left_ref == ref[list])
230                     mv[list] = AV_RN32A(A);
231                 else if (top_ref == ref[list])
232                     mv[list] = AV_RN32A(B);
233                 else
234                     mv[list] = AV_RN32A(C);
235             }
236             av_assert2(ref[list] < (sl->ref_count[list] << !!FRAME_MBAFF(h)));
237         } else {
238             int mask = ~(MB_TYPE_L0 << (2 * list));
239             mv[list]  = 0;
240             ref[list] = -1;
241             if (!is_b8x8)
242                 *mb_type &= mask;
243             sub_mb_type &= mask;
244         }
245     }
246     if (ref[0] < 0 && ref[1] < 0) {
247         ref[0] = ref[1] = 0;
248         if (!is_b8x8)
249             *mb_type |= MB_TYPE_L0L1;
250         sub_mb_type |= MB_TYPE_L0L1;
251     }
252
253     if (!(is_b8x8 | mv[0] | mv[1])) {
254         fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
255         fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
256         fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
257         fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4);
258         *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
259                                  MB_TYPE_P1L0 | MB_TYPE_P1L1)) |
260                    MB_TYPE_16x16 | MB_TYPE_DIRECT2;
261         return;
262     }
263
264     if (IS_INTERLACED(sl->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
265         if (!IS_INTERLACED(*mb_type)) {                    //     AFR/FR    -> AFL/FL
266             mb_y  = (sl->mb_y & ~1) + sl->col_parity;
267             mb_xy = sl->mb_x +
268                     ((sl->mb_y & ~1) + sl->col_parity) * h->mb_stride;
269             b8_stride = 0;
270         } else {
271             mb_y  += sl->col_fieldoff;
272             mb_xy += h->mb_stride * sl->col_fieldoff; // non-zero for FL -> FL & differ parity
273         }
274         goto single_col;
275     } else {                                             // AFL/AFR/FR/FL -> AFR/FR
276         if (IS_INTERLACED(*mb_type)) {                   // AFL       /FL -> AFR/FR
277             mb_y           =  sl->mb_y & ~1;
278             mb_xy          = (sl->mb_y & ~1) * h->mb_stride + sl->mb_x;
279             mb_type_col[0] = sl->ref_list[1][0].mb_type[mb_xy];
280             mb_type_col[1] = sl->ref_list[1][0].mb_type[mb_xy + h->mb_stride];
281             b8_stride      = 2 + 4 * h->mb_stride;
282             b4_stride     *= 6;
283             if (IS_INTERLACED(mb_type_col[0]) !=
284                 IS_INTERLACED(mb_type_col[1])) {
285                 mb_type_col[0] &= ~MB_TYPE_INTERLACED;
286                 mb_type_col[1] &= ~MB_TYPE_INTERLACED;
287             }
288
289             sub_mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_SUB_8x8 */
290             if ((mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) &&
291                 (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) &&
292                 !is_b8x8) {
293                 *mb_type |= MB_TYPE_16x8 | MB_TYPE_DIRECT2;  /* B_16x8 */
294             } else {
295                 *mb_type |= MB_TYPE_8x8;
296             }
297         } else {                                         //     AFR/FR    -> AFR/FR
298 single_col:
299             mb_type_col[0] =
300             mb_type_col[1] = sl->ref_list[1][0].mb_type[mb_xy];
301
302             sub_mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_SUB_8x8 */
303             if (!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)) {
304                 *mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_16x16 */
305             } else if (!is_b8x8 &&
306                        (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16))) {
307                 *mb_type |= MB_TYPE_DIRECT2 |
308                             (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16));
309             } else {
310                 if (!h->sps.direct_8x8_inference_flag) {
311                     /* FIXME: Save sub mb types from previous frames (or derive
312                      * from MVs) so we know exactly what block size to use. */
313                     sub_mb_type += (MB_TYPE_8x8 - MB_TYPE_16x16); /* B_SUB_4x4 */
314                 }
315                 *mb_type |= MB_TYPE_8x8;
316             }
317         }
318     }
319
320     await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
321
322     l1mv0  = (void*)&sl->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]];
323     l1mv1  = (void*)&sl->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]];
324     l1ref0 = &sl->ref_list[1][0].ref_index[0][4 * mb_xy];
325     l1ref1 = &sl->ref_list[1][0].ref_index[1][4 * mb_xy];
326     if (!b8_stride) {
327         if (sl->mb_y & 1) {
328             l1ref0 += 2;
329             l1ref1 += 2;
330             l1mv0  += 2 * b4_stride;
331             l1mv1  += 2 * b4_stride;
332         }
333     }
334
335     if (IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])) {
336         int n = 0;
337         for (i8 = 0; i8 < 4; i8++) {
338             int x8  = i8 & 1;
339             int y8  = i8 >> 1;
340             int xy8 = x8     + y8 * b8_stride;
341             int xy4 = x8 * 3 + y8 * b4_stride;
342             int a, b;
343
344             if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
345                 continue;
346             sl->sub_mb_type[i8] = sub_mb_type;
347
348             fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
349                            (uint8_t)ref[0], 1);
350             fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8,
351                            (uint8_t)ref[1], 1);
352             if (!IS_INTRA(mb_type_col[y8]) && !sl->ref_list[1][0].long_ref &&
353                 ((l1ref0[xy8] == 0 &&
354                   FFABS(l1mv0[xy4][0]) <= 1 &&
355                   FFABS(l1mv0[xy4][1]) <= 1) ||
356                  (l1ref0[xy8] < 0 &&
357                   l1ref1[xy8] == 0 &&
358                   FFABS(l1mv1[xy4][0]) <= 1 &&
359                   FFABS(l1mv1[xy4][1]) <= 1))) {
360                 a =
361                 b = 0;
362                 if (ref[0] > 0)
363                     a = mv[0];
364                 if (ref[1] > 0)
365                     b = mv[1];
366                 n++;
367             } else {
368                 a = mv[0];
369                 b = mv[1];
370             }
371             fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, a, 4);
372             fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, b, 4);
373         }
374         if (!is_b8x8 && !(n & 3))
375             *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
376                                      MB_TYPE_P1L0 | MB_TYPE_P1L1)) |
377                        MB_TYPE_16x16 | MB_TYPE_DIRECT2;
378     } else if (IS_16X16(*mb_type)) {
379         int a, b;
380
381         fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
382         fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
383         if (!IS_INTRA(mb_type_col[0]) && !sl->ref_list[1][0].long_ref &&
384             ((l1ref0[0] == 0 &&
385               FFABS(l1mv0[0][0]) <= 1 &&
386               FFABS(l1mv0[0][1]) <= 1) ||
387              (l1ref0[0] < 0 && !l1ref1[0] &&
388               FFABS(l1mv1[0][0]) <= 1 &&
389               FFABS(l1mv1[0][1]) <= 1 &&
390               h->x264_build > 33U))) {
391             a = b = 0;
392             if (ref[0] > 0)
393                 a = mv[0];
394             if (ref[1] > 0)
395                 b = mv[1];
396         } else {
397             a = mv[0];
398             b = mv[1];
399         }
400         fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, a, 4);
401         fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, b, 4);
402     } else {
403         int n = 0;
404         for (i8 = 0; i8 < 4; i8++) {
405             const int x8 = i8 & 1;
406             const int y8 = i8 >> 1;
407
408             if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
409                 continue;
410             sl->sub_mb_type[i8] = sub_mb_type;
411
412             fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, mv[0], 4);
413             fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, mv[1], 4);
414             fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
415                            (uint8_t)ref[0], 1);
416             fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8,
417                            (uint8_t)ref[1], 1);
418
419             assert(b8_stride == 2);
420             /* col_zero_flag */
421             if (!IS_INTRA(mb_type_col[0]) && !sl->ref_list[1][0].long_ref &&
422                 (l1ref0[i8] == 0 ||
423                  (l1ref0[i8] < 0 &&
424                   l1ref1[i8] == 0 &&
425                   h->x264_build > 33U))) {
426                 const int16_t (*l1mv)[2] = l1ref0[i8] == 0 ? l1mv0 : l1mv1;
427                 if (IS_SUB_8X8(sub_mb_type)) {
428                     const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride];
429                     if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) {
430                         if (ref[0] == 0)
431                             fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2,
432                                            8, 0, 4);
433                         if (ref[1] == 0)
434                             fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2,
435                                            8, 0, 4);
436                         n += 4;
437                     }
438                 } else {
439                     int m = 0;
440                     for (i4 = 0; i4 < 4; i4++) {
441                         const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) +
442                                                      (y8 * 2 + (i4 >> 1)) * b4_stride];
443                         if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) {
444                             if (ref[0] == 0)
445                                 AV_ZERO32(sl->mv_cache[0][scan8[i8 * 4 + i4]]);
446                             if (ref[1] == 0)
447                                 AV_ZERO32(sl->mv_cache[1][scan8[i8 * 4 + i4]]);
448                             m++;
449                         }
450                     }
451                     if (!(m & 3))
452                         sl->sub_mb_type[i8] += MB_TYPE_16x16 - MB_TYPE_8x8;
453                     n += m;
454                 }
455             }
456         }
457         if (!is_b8x8 && !(n & 15))
458             *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
459                                      MB_TYPE_P1L0 | MB_TYPE_P1L1)) |
460                        MB_TYPE_16x16 | MB_TYPE_DIRECT2;
461     }
462 }
463
464 static void pred_temp_direct_motion(const H264Context *const h, H264SliceContext *sl,
465                                     int *mb_type)
466 {
467     int b8_stride = 2;
468     int b4_stride = h->b_stride;
469     int mb_xy = sl->mb_xy, mb_y = sl->mb_y;
470     int mb_type_col[2];
471     const int16_t (*l1mv0)[2], (*l1mv1)[2];
472     const int8_t *l1ref0, *l1ref1;
473     const int is_b8x8 = IS_8X8(*mb_type);
474     unsigned int sub_mb_type;
475     int i8, i4;
476
477     assert(sl->ref_list[1][0].reference & 3);
478
479     await_reference_mb_row(h, &sl->ref_list[1][0],
480                            sl->mb_y + !!IS_INTERLACED(*mb_type));
481
482     if (IS_INTERLACED(sl->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
483         if (!IS_INTERLACED(*mb_type)) {                    //     AFR/FR    -> AFL/FL
484             mb_y  = (sl->mb_y & ~1) + sl->col_parity;
485             mb_xy = sl->mb_x +
486                     ((sl->mb_y & ~1) + sl->col_parity) * h->mb_stride;
487             b8_stride = 0;
488         } else {
489             mb_y  += sl->col_fieldoff;
490             mb_xy += h->mb_stride * sl->col_fieldoff; // non-zero for FL -> FL & differ parity
491         }
492         goto single_col;
493     } else {                                        // AFL/AFR/FR/FL -> AFR/FR
494         if (IS_INTERLACED(*mb_type)) {              // AFL       /FL -> AFR/FR
495             mb_y           = sl->mb_y & ~1;
496             mb_xy          = sl->mb_x + (sl->mb_y & ~1) * h->mb_stride;
497             mb_type_col[0] = sl->ref_list[1][0].mb_type[mb_xy];
498             mb_type_col[1] = sl->ref_list[1][0].mb_type[mb_xy + h->mb_stride];
499             b8_stride      = 2 + 4 * h->mb_stride;
500             b4_stride     *= 6;
501             if (IS_INTERLACED(mb_type_col[0]) !=
502                 IS_INTERLACED(mb_type_col[1])) {
503                 mb_type_col[0] &= ~MB_TYPE_INTERLACED;
504                 mb_type_col[1] &= ~MB_TYPE_INTERLACED;
505             }
506
507             sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
508                           MB_TYPE_DIRECT2;                  /* B_SUB_8x8 */
509
510             if ((mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) &&
511                 (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) &&
512                 !is_b8x8) {
513                 *mb_type |= MB_TYPE_16x8 | MB_TYPE_L0L1 |
514                             MB_TYPE_DIRECT2;                /* B_16x8 */
515             } else {
516                 *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;
517             }
518         } else {                                    //     AFR/FR    -> AFR/FR
519 single_col:
520             mb_type_col[0]     =
521                 mb_type_col[1] = sl->ref_list[1][0].mb_type[mb_xy];
522
523             sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
524                           MB_TYPE_DIRECT2;                  /* B_SUB_8x8 */
525             if (!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)) {
526                 *mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
527                             MB_TYPE_DIRECT2;                /* B_16x16 */
528             } else if (!is_b8x8 &&
529                        (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16))) {
530                 *mb_type |= MB_TYPE_L0L1 | MB_TYPE_DIRECT2 |
531                             (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16));
532             } else {
533                 if (!h->sps.direct_8x8_inference_flag) {
534                     /* FIXME: save sub mb types from previous frames (or derive
535                      * from MVs) so we know exactly what block size to use */
536                     sub_mb_type = MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
537                                   MB_TYPE_DIRECT2;          /* B_SUB_4x4 */
538                 }
539                 *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;
540             }
541         }
542     }
543
544     await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
545
546     l1mv0  = (void*)&sl->ref_list[1][0].motion_val[0][h->mb2b_xy[mb_xy]];
547     l1mv1  = (void*)&sl->ref_list[1][0].motion_val[1][h->mb2b_xy[mb_xy]];
548     l1ref0 = &sl->ref_list[1][0].ref_index[0][4 * mb_xy];
549     l1ref1 = &sl->ref_list[1][0].ref_index[1][4 * mb_xy];
550     if (!b8_stride) {
551         if (sl->mb_y & 1) {
552             l1ref0 += 2;
553             l1ref1 += 2;
554             l1mv0  += 2 * b4_stride;
555             l1mv1  += 2 * b4_stride;
556         }
557     }
558
559     {
560         const int *map_col_to_list0[2] = { sl->map_col_to_list0[0],
561                                            sl->map_col_to_list0[1] };
562         const int *dist_scale_factor = sl->dist_scale_factor;
563         int ref_offset;
564
565         if (FRAME_MBAFF(h) && IS_INTERLACED(*mb_type)) {
566             map_col_to_list0[0] = sl->map_col_to_list0_field[sl->mb_y & 1][0];
567             map_col_to_list0[1] = sl->map_col_to_list0_field[sl->mb_y & 1][1];
568             dist_scale_factor   = sl->dist_scale_factor_field[sl->mb_y & 1];
569         }
570         ref_offset = (sl->ref_list[1][0].mbaff << 4) & (mb_type_col[0] >> 3);
571
572         if (IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])) {
573             int y_shift = 2 * !IS_INTERLACED(*mb_type);
574             assert(h->sps.direct_8x8_inference_flag);
575
576             for (i8 = 0; i8 < 4; i8++) {
577                 const int x8 = i8 & 1;
578                 const int y8 = i8 >> 1;
579                 int ref0, scale;
580                 const int16_t (*l1mv)[2] = l1mv0;
581
582                 if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
583                     continue;
584                 sl->sub_mb_type[i8] = sub_mb_type;
585
586                 fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);
587                 if (IS_INTRA(mb_type_col[y8])) {
588                     fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);
589                     fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);
590                     fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);
591                     continue;
592                 }
593
594                 ref0 = l1ref0[x8 + y8 * b8_stride];
595                 if (ref0 >= 0)
596                     ref0 = map_col_to_list0[0][ref0 + ref_offset];
597                 else {
598                     ref0 = map_col_to_list0[1][l1ref1[x8 + y8 * b8_stride] +
599                                                ref_offset];
600                     l1mv = l1mv1;
601                 }
602                 scale = dist_scale_factor[ref0];
603                 fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
604                                ref0, 1);
605
606                 {
607                     const int16_t *mv_col = l1mv[x8 * 3 + y8 * b4_stride];
608                     int my_col            = (mv_col[1] << y_shift) / 2;
609                     int mx                = (scale * mv_col[0] + 128) >> 8;
610                     int my                = (scale * my_col    + 128) >> 8;
611                     fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,
612                                    pack16to32(mx, my), 4);
613                     fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,
614                                    pack16to32(mx - mv_col[0], my - my_col), 4);
615                 }
616             }
617             return;
618         }
619
620         /* one-to-one mv scaling */
621
622         if (IS_16X16(*mb_type)) {
623             int ref, mv0, mv1;
624
625             fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1);
626             if (IS_INTRA(mb_type_col[0])) {
627                 ref = mv0 = mv1 = 0;
628             } else {
629                 const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset]
630                                                 : map_col_to_list0[1][l1ref1[0] + ref_offset];
631                 const int scale = dist_scale_factor[ref0];
632                 const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];
633                 int mv_l0[2];
634                 mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
635                 mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
636                 ref      = ref0;
637                 mv0      = pack16to32(mv_l0[0], mv_l0[1]);
638                 mv1      = pack16to32(mv_l0[0] - mv_col[0], mv_l0[1] - mv_col[1]);
639             }
640             fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
641             fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4);
642             fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4);
643         } else {
644             for (i8 = 0; i8 < 4; i8++) {
645                 const int x8 = i8 & 1;
646                 const int y8 = i8 >> 1;
647                 int ref0, scale;
648                 const int16_t (*l1mv)[2] = l1mv0;
649
650                 if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
651                     continue;
652                 sl->sub_mb_type[i8] = sub_mb_type;
653                 fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);
654                 if (IS_INTRA(mb_type_col[0])) {
655                     fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);
656                     fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);
657                     fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);
658                     continue;
659                 }
660
661                 assert(b8_stride == 2);
662                 ref0 = l1ref0[i8];
663                 if (ref0 >= 0)
664                     ref0 = map_col_to_list0[0][ref0 + ref_offset];
665                 else {
666                     ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset];
667                     l1mv = l1mv1;
668                 }
669                 scale = dist_scale_factor[ref0];
670
671                 fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
672                                ref0, 1);
673                 if (IS_SUB_8X8(sub_mb_type)) {
674                     const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride];
675                     int mx                = (scale * mv_col[0] + 128) >> 8;
676                     int my                = (scale * mv_col[1] + 128) >> 8;
677                     fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,
678                                    pack16to32(mx, my), 4);
679                     fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,
680                                    pack16to32(mx - mv_col[0], my - mv_col[1]), 4);
681                 } else {
682                     for (i4 = 0; i4 < 4; i4++) {
683                         const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) +
684                                                      (y8 * 2 + (i4 >> 1)) * b4_stride];
685                         int16_t *mv_l0 = sl->mv_cache[0][scan8[i8 * 4 + i4]];
686                         mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
687                         mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
688                         AV_WN32A(sl->mv_cache[1][scan8[i8 * 4 + i4]],
689                                  pack16to32(mv_l0[0] - mv_col[0],
690                                             mv_l0[1] - mv_col[1]));
691                     }
692                 }
693             }
694         }
695     }
696 }
697
698 void ff_h264_pred_direct_motion(const H264Context *const h, H264SliceContext *sl,
699                                 int *mb_type)
700 {
701     if (sl->direct_spatial_mv_pred)
702         pred_spatial_direct_motion(h, sl, mb_type);
703     else
704         pred_temp_direct_motion(h, sl, mb_type);
705 }