vp9: add keyframe profile 2/3 support.
[ffmpeg.git] / libavcodec / vp9_mc_template.c
1 /*
2  * VP9 compatible video decoder
3  *
4  * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
5  * Copyright (C) 2013 Clément Bœsch <u pkh me>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23
24 #define ROUNDED_DIV_MVx2(a, b) \
25     (VP56mv) { .x = ROUNDED_DIV(a.x + b.x, 2), .y = ROUNDED_DIV(a.y + b.y, 2) }
26 #define ROUNDED_DIV_MVx4(a, b, c, d) \
27     (VP56mv) { .x = ROUNDED_DIV(a.x + b.x + c.x + d.x, 4), \
28                .y = ROUNDED_DIV(a.y + b.y + c.y + d.y, 4) }
29
30 static void FN(inter_pred)(AVCodecContext *ctx)
31 {
32     static const uint8_t bwlog_tab[2][N_BS_SIZES] = {
33         { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },
34         { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 },
35     };
36     VP9Context *s = ctx->priv_data;
37     VP9Block *b = s->b;
38     int row = s->row, col = s->col;
39     ThreadFrame *tref1 = &s->refs[s->refidx[b->ref[0]]], *tref2;
40     AVFrame *ref1 = tref1->f, *ref2;
41     int w1 = ref1->width, h1 = ref1->height, w2, h2;
42     ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride;
43
44     if (b->comp) {
45         tref2 = &s->refs[s->refidx[b->ref[1]]];
46         ref2 = tref2->f;
47         w2 = ref2->width;
48         h2 = ref2->height;
49     }
50
51     // y inter pred
52     if (b->bs > BS_8x8) {
53         VP56mv uvmv;
54
55         if (b->bs == BS_8x4) {
56             mc_luma_dir(s, mc[3][b->filter][0], s->dst[0], ls_y,
57                         ref1->data[0], ref1->linesize[0], tref1,
58                         row << 3, col << 3, &b->mv[0][0], 8, 4, w1, h1, 0);
59             mc_luma_dir(s, mc[3][b->filter][0],
60                         s->dst[0] + 4 * ls_y, ls_y,
61                         ref1->data[0], ref1->linesize[0], tref1,
62                         (row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w1, h1, 0);
63             w1 = (w1 + s->ss_h) >> s->ss_h;
64             if (s->ss_v) {
65                 h1 = (h1 + 1) >> 1;
66                 uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]);
67                 mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0],
68                               s->dst[1], s->dst[2], ls_uv,
69                               ref1->data[1], ref1->linesize[1],
70                               ref1->data[2], ref1->linesize[2], tref1,
71                               row << 2, col << (3 - s->ss_h),
72                               &uvmv, 8 >> s->ss_h, 4, w1, h1, 0);
73             } else {
74                 mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0],
75                               s->dst[1], s->dst[2], ls_uv,
76                               ref1->data[1], ref1->linesize[1],
77                               ref1->data[2], ref1->linesize[2], tref1,
78                               row << 3, col << (3 - s->ss_h),
79                               &b->mv[0][0], 8 >> s->ss_h, 4, w1, h1, 0);
80                 // BUG for 4:2:2 bs=8x4, libvpx uses the wrong block index
81                 // to get the motion vector for the bottom 4x4 block
82                 // https://code.google.com/p/webm/issues/detail?id=993
83                 if (s->ss_h == 0) {
84                     uvmv = b->mv[2][0];
85                 } else {
86                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]);
87                 }
88                 mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0],
89                               s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
90                               ref1->data[1], ref1->linesize[1],
91                               ref1->data[2], ref1->linesize[2], tref1,
92                               (row << 3) + 4, col << (3 - s->ss_h),
93                               &uvmv, 8 >> s->ss_h, 4, w1, h1, 0);
94             }
95
96             if (b->comp) {
97                 mc_luma_dir(s, mc[3][b->filter][1], s->dst[0], ls_y,
98                             ref2->data[0], ref2->linesize[0], tref2,
99                             row << 3, col << 3, &b->mv[0][1], 8, 4, w2, h2, 1);
100                 mc_luma_dir(s, mc[3][b->filter][1],
101                             s->dst[0] + 4 * ls_y, ls_y,
102                             ref2->data[0], ref2->linesize[0], tref2,
103                             (row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w2, h2, 1);
104                 w2 = (w2 + s->ss_h) >> s->ss_h;
105                 if (s->ss_v) {
106                     h2 = (h2 + 1) >> 1;
107                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]);
108                     mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1],
109                                   s->dst[1], s->dst[2], ls_uv,
110                                   ref2->data[1], ref2->linesize[1],
111                                   ref2->data[2], ref2->linesize[2], tref2,
112                                   row << 2, col << (3 - s->ss_h),
113                                   &uvmv, 8 >> s->ss_h, 4, w2, h2, 1);
114                 } else {
115                     mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1],
116                                   s->dst[1], s->dst[2], ls_uv,
117                                   ref2->data[1], ref2->linesize[1],
118                                   ref2->data[2], ref2->linesize[2], tref2,
119                                   row << 3, col << (3 - s->ss_h),
120                                   &b->mv[0][1], 8 >> s->ss_h, 4, w2, h2, 1);
121                     // BUG for 4:2:2 bs=8x4, libvpx uses the wrong block index
122                     // to get the motion vector for the bottom 4x4 block
123                     // https://code.google.com/p/webm/issues/detail?id=993
124                     if (s->ss_h == 0) {
125                         uvmv = b->mv[2][1];
126                     } else {
127                         uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]);
128                     }
129                     mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1],
130                                   s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
131                                   ref2->data[1], ref2->linesize[1],
132                                   ref2->data[2], ref2->linesize[2], tref2,
133                                   (row << 3) + 4, col << (3 - s->ss_h),
134                                   &uvmv, 8 >> s->ss_h, 4, w2, h2, 1);
135                 }
136             }
137         } else if (b->bs == BS_4x8) {
138             mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y,
139                         ref1->data[0], ref1->linesize[0], tref1,
140                         row << 3, col << 3, &b->mv[0][0], 4, 8, w1, h1, 0);
141             mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4, ls_y,
142                         ref1->data[0], ref1->linesize[0], tref1,
143                         row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w1, h1, 0);
144             h1 = (h1 + s->ss_v) >> s->ss_v;
145             if (s->ss_h) {
146                 w1 = (w1 + 1) >> 1;
147                 uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]);
148                 mc_chroma_dir(s, mc[4][b->filter][0],
149                               s->dst[1], s->dst[2], ls_uv,
150                               ref1->data[1], ref1->linesize[1],
151                               ref1->data[2], ref1->linesize[2], tref1,
152                               row << (3 - s->ss_v), col << 2,
153                               &uvmv, 4, 8 >> s->ss_v, w1, h1, 0);
154             } else {
155                 mc_chroma_dir(s, mc[4][b->filter][0],
156                               s->dst[1], s->dst[2], ls_uv,
157                               ref1->data[1], ref1->linesize[1],
158                               ref1->data[2], ref1->linesize[2], tref1,
159                               row << (3 - s->ss_v), col << 3,
160                               &b->mv[0][0], 4, 8 >> s->ss_v, w1, h1, 0);
161                 mc_chroma_dir(s, mc[4][b->filter][0],
162                               s->dst[1] + 4, s->dst[2] + 4, ls_uv,
163                               ref1->data[1], ref1->linesize[1],
164                               ref1->data[2], ref1->linesize[2], tref1,
165                               row << (3 - s->ss_v), (col << 3) + 4,
166                               &b->mv[1][0], 4, 8 >> s->ss_v, w1, h1, 0);
167             }
168
169             if (b->comp) {
170                 mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y,
171                             ref2->data[0], ref2->linesize[0], tref2,
172                             row << 3, col << 3, &b->mv[0][1], 4, 8, w2, h2, 1);
173                 mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4, ls_y,
174                             ref2->data[0], ref2->linesize[0], tref2,
175                             row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w2, h2, 1);
176                 h2 = (h2 + s->ss_v) >> s->ss_v;
177                 if (s->ss_h) {
178                     w2 = (w2 + 1) >> 1;
179                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]);
180                     mc_chroma_dir(s, mc[4][b->filter][1],
181                                   s->dst[1], s->dst[2], ls_uv,
182                                   ref2->data[1], ref2->linesize[1],
183                                   ref2->data[2], ref2->linesize[2], tref2,
184                                   row << (3 - s->ss_v), col << 2,
185                                   &uvmv, 4, 8 >> s->ss_v, w2, h2, 1);
186                 } else {
187                     mc_chroma_dir(s, mc[4][b->filter][1],
188                                   s->dst[1], s->dst[2], ls_uv,
189                                   ref2->data[1], ref2->linesize[1],
190                                   ref2->data[2], ref2->linesize[2], tref2,
191                                   row << (3 - s->ss_v), col << 3,
192                                   &b->mv[0][1], 4, 8 >> s->ss_v, w2, h2, 1);
193                     mc_chroma_dir(s, mc[4][b->filter][1],
194                                   s->dst[1] + 4, s->dst[2] + 4, ls_uv,
195                                   ref2->data[1], ref2->linesize[1],
196                                   ref2->data[2], ref2->linesize[2], tref2,
197                                   row << (3 - s->ss_v), (col << 3) + 4,
198                                   &b->mv[1][1], 4, 8 >> s->ss_v, w2, h2, 1);
199                 }
200             }
201         } else {
202             av_assert2(b->bs == BS_4x4);
203
204             // FIXME if two horizontally adjacent blocks have the same MV,
205             // do a w8 instead of a w4 call
206             mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y,
207                         ref1->data[0], ref1->linesize[0], tref1,
208                         row << 3, col << 3, &b->mv[0][0], 4, 4, w1, h1, 0);
209             mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4, ls_y,
210                         ref1->data[0], ref1->linesize[0], tref1,
211                         row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w1, h1, 0);
212             mc_luma_dir(s, mc[4][b->filter][0],
213                         s->dst[0] + 4 * ls_y, ls_y,
214                         ref1->data[0], ref1->linesize[0], tref1,
215                         (row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w1, h1, 0);
216             mc_luma_dir(s, mc[4][b->filter][0],
217                         s->dst[0] + 4 * ls_y + 4, ls_y,
218                         ref1->data[0], ref1->linesize[0], tref1,
219                         (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w1, h1, 0);
220             if (s->ss_v) {
221                 h1 = (h1 + 1) >> 1;
222                 if (s->ss_h) {
223                     w1 = (w1 + 1) >> 1;
224                     uvmv = ROUNDED_DIV_MVx4(b->mv[0][0], b->mv[1][0],
225                                             b->mv[2][0], b->mv[3][0]);
226                     mc_chroma_dir(s, mc[4][b->filter][0],
227                                   s->dst[1], s->dst[2], ls_uv,
228                                   ref1->data[1], ref1->linesize[1],
229                                   ref1->data[2], ref1->linesize[2], tref1,
230                                   row << 2, col << 2,
231                                   &uvmv, 4, 4, w1, h1, 0);
232                 } else {
233                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]);
234                     mc_chroma_dir(s, mc[4][b->filter][0],
235                                   s->dst[1], s->dst[2], ls_uv,
236                                   ref1->data[1], ref1->linesize[1],
237                                   ref1->data[2], ref1->linesize[2], tref1,
238                                   row << 2, col << 3,
239                                   &uvmv, 4, 4, w1, h1, 0);
240                     uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[3][0]);
241                     mc_chroma_dir(s, mc[4][b->filter][0],
242                                   s->dst[1] + 4, s->dst[2] + 4, ls_uv,
243                                   ref1->data[1], ref1->linesize[1],
244                                   ref1->data[2], ref1->linesize[2], tref1,
245                                   row << 2, (col << 3) + 4,
246                                   &uvmv, 4, 4, w1, h1, 0);
247                 }
248             } else {
249                 if (s->ss_h) {
250                     w1 = (w1 + 1) >> 1;
251                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]);
252                     mc_chroma_dir(s, mc[4][b->filter][0],
253                                   s->dst[1], s->dst[2], ls_uv,
254                                   ref1->data[1], ref1->linesize[1],
255                                   ref1->data[2], ref1->linesize[2], tref1,
256                                   row << 3, col << 2,
257                                   &uvmv, 4, 4, w1, h1, 0);
258                     // BUG libvpx uses wrong block index for 4:2:2 bs=4x4
259                     // bottom block
260                     // https://code.google.com/p/webm/issues/detail?id=993
261                     uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[2][0]);
262                     mc_chroma_dir(s, mc[4][b->filter][0],
263                                   s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
264                                   ref1->data[1], ref1->linesize[1],
265                                   ref1->data[2], ref1->linesize[2], tref1,
266                                   (row << 3) + 4, col << 2,
267                                   &uvmv, 4, 4, w1, h1, 0);
268                 } else {
269                     mc_chroma_dir(s, mc[4][b->filter][0],
270                                   s->dst[1], s->dst[2], ls_uv,
271                                   ref1->data[1], ref1->linesize[1],
272                                   ref1->data[2], ref1->linesize[2], tref1,
273                                   row << 3, col << 3,
274                                   &b->mv[0][0], 4, 4, w1, h1, 0);
275                     mc_chroma_dir(s, mc[4][b->filter][0],
276                                   s->dst[1] + 4, s->dst[2] + 4, ls_uv,
277                                   ref1->data[1], ref1->linesize[1],
278                                   ref1->data[2], ref1->linesize[2], tref1,
279                                   row << 3, (col << 3) + 4,
280                                   &b->mv[1][0], 4, 4, w1, h1, 0);
281                     mc_chroma_dir(s, mc[4][b->filter][0],
282                                   s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
283                                   ref1->data[1], ref1->linesize[1],
284                                   ref1->data[2], ref1->linesize[2], tref1,
285                                   (row << 3) + 4, col << 3,
286                                   &b->mv[2][0], 4, 4, w1, h1, 0);
287                     mc_chroma_dir(s, mc[4][b->filter][0],
288                                   s->dst[1] + 4 * ls_uv + 4, s->dst[2] + 4 * ls_uv + 4, ls_uv,
289                                   ref1->data[1], ref1->linesize[1],
290                                   ref1->data[2], ref1->linesize[2], tref1,
291                                   (row << 3) + 4, (col << 3) + 4,
292                                   &b->mv[3][0], 4, 4, w1, h1, 0);
293                 }
294             }
295
296             if (b->comp) {
297                 mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y,
298                             ref2->data[0], ref2->linesize[0], tref2,
299                             row << 3, col << 3, &b->mv[0][1], 4, 4, w2, h2, 1);
300                 mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4, ls_y,
301                             ref2->data[0], ref2->linesize[0], tref2,
302                             row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w2, h2, 1);
303                 mc_luma_dir(s, mc[4][b->filter][1],
304                             s->dst[0] + 4 * ls_y, ls_y,
305                             ref2->data[0], ref2->linesize[0], tref2,
306                             (row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w2, h2, 1);
307                 mc_luma_dir(s, mc[4][b->filter][1],
308                             s->dst[0] + 4 * ls_y + 4, ls_y,
309                             ref2->data[0], ref2->linesize[0], tref2,
310                             (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w2, h2, 1);
311                 if (s->ss_v) {
312                     h2 = (h2 + 1) >> 1;
313                     if (s->ss_h) {
314                         w2 = (w2 + 1) >> 1;
315                         uvmv = ROUNDED_DIV_MVx4(b->mv[0][1], b->mv[1][1],
316                                                 b->mv[2][1], b->mv[3][1]);
317                         mc_chroma_dir(s, mc[4][b->filter][1],
318                                       s->dst[1], s->dst[2], ls_uv,
319                                       ref2->data[1], ref2->linesize[1],
320                                       ref2->data[2], ref2->linesize[2], tref2,
321                                       row << 2, col << 2,
322                                       &uvmv, 4, 4, w2, h2, 1);
323                     } else {
324                         uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]);
325                         mc_chroma_dir(s, mc[4][b->filter][1],
326                                       s->dst[1], s->dst[2], ls_uv,
327                                       ref2->data[1], ref2->linesize[1],
328                                       ref2->data[2], ref2->linesize[2], tref2,
329                                       row << 2, col << 3,
330                                       &uvmv, 4, 4, w2, h2, 1);
331                         uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[3][1]);
332                         mc_chroma_dir(s, mc[4][b->filter][1],
333                                       s->dst[1] + 4, s->dst[2] + 4, ls_uv,
334                                       ref2->data[1], ref2->linesize[1],
335                                       ref2->data[2], ref2->linesize[2], tref2,
336                                       row << 2, (col << 3) + 4,
337                                       &uvmv, 4, 4, w2, h2, 1);
338                     }
339                 } else {
340                     if (s->ss_h) {
341                         w2 = (w2 + 1) >> 1;
342                         uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]);
343                         mc_chroma_dir(s, mc[4][b->filter][1],
344                                       s->dst[1], s->dst[2], ls_uv,
345                                       ref2->data[1], ref2->linesize[1],
346                                       ref2->data[2], ref2->linesize[2], tref2,
347                                       row << 3, col << 2,
348                                       &uvmv, 4, 4, w2, h2, 1);
349                         // BUG libvpx uses wrong block index for 4:2:2 bs=4x4
350                         // bottom block
351                         // https://code.google.com/p/webm/issues/detail?id=993
352                         uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[2][1]);
353                         mc_chroma_dir(s, mc[4][b->filter][1],
354                                       s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
355                                       ref2->data[1], ref2->linesize[1],
356                                       ref2->data[2], ref2->linesize[2], tref2,
357                                       (row << 3) + 4, col << 2,
358                                       &uvmv, 4, 4, w2, h2, 1);
359                     } else {
360                         mc_chroma_dir(s, mc[4][b->filter][1],
361                                       s->dst[1], s->dst[2], ls_uv,
362                                       ref2->data[1], ref2->linesize[1],
363                                       ref2->data[2], ref2->linesize[2], tref2,
364                                       row << 3, col << 3,
365                                       &b->mv[0][1], 4, 4, w2, h2, 1);
366                         mc_chroma_dir(s, mc[4][b->filter][1],
367                                       s->dst[1] + 4, s->dst[2] + 4, ls_uv,
368                                       ref2->data[1], ref2->linesize[1],
369                                       ref2->data[2], ref2->linesize[2], tref2,
370                                       row << 3, (col << 3) + 4,
371                                       &b->mv[1][1], 4, 4, w2, h2, 1);
372                         mc_chroma_dir(s, mc[4][b->filter][1],
373                                       s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
374                                       ref2->data[1], ref2->linesize[1],
375                                       ref2->data[2], ref2->linesize[2], tref2,
376                                       (row << 3) + 4, col << 3,
377                                       &b->mv[2][1], 4, 4, w2, h2, 1);
378                         mc_chroma_dir(s, mc[4][b->filter][1],
379                                       s->dst[1] + 4 * ls_uv + 4, s->dst[2] + 4 * ls_uv + 4, ls_uv,
380                                       ref2->data[1], ref2->linesize[1],
381                                       ref2->data[2], ref2->linesize[2], tref2,
382                                       (row << 3) + 4, (col << 3) + 4,
383                                       &b->mv[3][1], 4, 4, w2, h2, 1);
384                     }
385                 }
386             }
387         }
388     } else {
389         int bwl = bwlog_tab[0][b->bs];
390         int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4;
391         int uvbw = bwh_tab[s->ss_h][b->bs][0] * 4, uvbh = bwh_tab[s->ss_v][b->bs][1] * 4;
392
393         mc_luma_dir(s, mc[bwl][b->filter][0], s->dst[0], ls_y,
394                     ref1->data[0], ref1->linesize[0], tref1,
395                     row << 3, col << 3, &b->mv[0][0], bw, bh, w1, h1, 0);
396         w1 = (w1 + s->ss_h) >> s->ss_h;
397         h1 = (h1 + s->ss_v) >> s->ss_v;
398         mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][0],
399                       s->dst[1], s->dst[2], ls_uv,
400                       ref1->data[1], ref1->linesize[1],
401                       ref1->data[2], ref1->linesize[2], tref1,
402                       row << (3 - s->ss_v), col << (3 - s->ss_h),
403                       &b->mv[0][0], uvbw, uvbh, w1, h1, 0);
404
405         if (b->comp) {
406             mc_luma_dir(s, mc[bwl][b->filter][1], s->dst[0], ls_y,
407                         ref2->data[0], ref2->linesize[0], tref2,
408                         row << 3, col << 3, &b->mv[0][1], bw, bh, w2, h2, 1);
409             w2 = (w2 + s->ss_h) >> s->ss_h;
410             h2 = (h2 + s->ss_v) >> s->ss_v;
411             mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][1],
412                           s->dst[1], s->dst[2], ls_uv,
413                           ref2->data[1], ref2->linesize[1],
414                           ref2->data[2], ref2->linesize[2], tref2,
415                           row << (3 - s->ss_v), col << (3 - s->ss_h),
416                           &b->mv[0][1], uvbw, uvbh, w2, h2, 1);
417         }
418     }
419 }