vp9: add inter-frame profile 2/3 suport.
[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     int bytesperpixel = BYTES_PER_PIXEL;
44
45     if (b->comp) {
46         tref2 = &s->refs[s->refidx[b->ref[1]]];
47         ref2 = tref2->f;
48         w2 = ref2->width;
49         h2 = ref2->height;
50     }
51
52     // y inter pred
53     if (b->bs > BS_8x8) {
54         VP56mv uvmv;
55
56         if (b->bs == BS_8x4) {
57             mc_luma_dir(s, mc[3][b->filter][0], s->dst[0], ls_y,
58                         ref1->data[0], ref1->linesize[0], tref1,
59                         row << 3, col << 3, &b->mv[0][0], 8, 4, w1, h1, 0);
60             mc_luma_dir(s, mc[3][b->filter][0],
61                         s->dst[0] + 4 * ls_y, ls_y,
62                         ref1->data[0], ref1->linesize[0], tref1,
63                         (row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w1, h1, 0);
64             w1 = (w1 + s->ss_h) >> s->ss_h;
65             if (s->ss_v) {
66                 h1 = (h1 + 1) >> 1;
67                 uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]);
68                 mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0],
69                               s->dst[1], s->dst[2], ls_uv,
70                               ref1->data[1], ref1->linesize[1],
71                               ref1->data[2], ref1->linesize[2], tref1,
72                               row << 2, col << (3 - s->ss_h),
73                               &uvmv, 8 >> s->ss_h, 4, w1, h1, 0);
74             } else {
75                 mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0],
76                               s->dst[1], s->dst[2], ls_uv,
77                               ref1->data[1], ref1->linesize[1],
78                               ref1->data[2], ref1->linesize[2], tref1,
79                               row << 3, col << (3 - s->ss_h),
80                               &b->mv[0][0], 8 >> s->ss_h, 4, w1, h1, 0);
81                 // BUG for 4:2:2 bs=8x4, libvpx uses the wrong block index
82                 // to get the motion vector for the bottom 4x4 block
83                 // https://code.google.com/p/webm/issues/detail?id=993
84                 if (s->ss_h == 0) {
85                     uvmv = b->mv[2][0];
86                 } else {
87                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]);
88                 }
89                 mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][0],
90                               s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
91                               ref1->data[1], ref1->linesize[1],
92                               ref1->data[2], ref1->linesize[2], tref1,
93                               (row << 3) + 4, col << (3 - s->ss_h),
94                               &uvmv, 8 >> s->ss_h, 4, w1, h1, 0);
95             }
96
97             if (b->comp) {
98                 mc_luma_dir(s, mc[3][b->filter][1], s->dst[0], ls_y,
99                             ref2->data[0], ref2->linesize[0], tref2,
100                             row << 3, col << 3, &b->mv[0][1], 8, 4, w2, h2, 1);
101                 mc_luma_dir(s, mc[3][b->filter][1],
102                             s->dst[0] + 4 * ls_y, ls_y,
103                             ref2->data[0], ref2->linesize[0], tref2,
104                             (row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w2, h2, 1);
105                 w2 = (w2 + s->ss_h) >> s->ss_h;
106                 if (s->ss_v) {
107                     h2 = (h2 + 1) >> 1;
108                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]);
109                     mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1],
110                                   s->dst[1], s->dst[2], ls_uv,
111                                   ref2->data[1], ref2->linesize[1],
112                                   ref2->data[2], ref2->linesize[2], tref2,
113                                   row << 2, col << (3 - s->ss_h),
114                                   &uvmv, 8 >> s->ss_h, 4, w2, h2, 1);
115                 } else {
116                     mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1],
117                                   s->dst[1], s->dst[2], ls_uv,
118                                   ref2->data[1], ref2->linesize[1],
119                                   ref2->data[2], ref2->linesize[2], tref2,
120                                   row << 3, col << (3 - s->ss_h),
121                                   &b->mv[0][1], 8 >> s->ss_h, 4, w2, h2, 1);
122                     // BUG for 4:2:2 bs=8x4, libvpx uses the wrong block index
123                     // to get the motion vector for the bottom 4x4 block
124                     // https://code.google.com/p/webm/issues/detail?id=993
125                     if (s->ss_h == 0) {
126                         uvmv = b->mv[2][1];
127                     } else {
128                         uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]);
129                     }
130                     mc_chroma_dir(s, mc[3 + s->ss_h][b->filter][1],
131                                   s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
132                                   ref2->data[1], ref2->linesize[1],
133                                   ref2->data[2], ref2->linesize[2], tref2,
134                                   (row << 3) + 4, col << (3 - s->ss_h),
135                                   &uvmv, 8 >> s->ss_h, 4, w2, h2, 1);
136                 }
137             }
138         } else if (b->bs == BS_4x8) {
139             mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y,
140                         ref1->data[0], ref1->linesize[0], tref1,
141                         row << 3, col << 3, &b->mv[0][0], 4, 8, w1, h1, 0);
142             mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y,
143                         ref1->data[0], ref1->linesize[0], tref1,
144                         row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w1, h1, 0);
145             h1 = (h1 + s->ss_v) >> s->ss_v;
146             if (s->ss_h) {
147                 w1 = (w1 + 1) >> 1;
148                 uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]);
149                 mc_chroma_dir(s, mc[4][b->filter][0],
150                               s->dst[1], s->dst[2], ls_uv,
151                               ref1->data[1], ref1->linesize[1],
152                               ref1->data[2], ref1->linesize[2], tref1,
153                               row << (3 - s->ss_v), col << 2,
154                               &uvmv, 4, 8 >> s->ss_v, w1, h1, 0);
155             } else {
156                 mc_chroma_dir(s, mc[4][b->filter][0],
157                               s->dst[1], s->dst[2], ls_uv,
158                               ref1->data[1], ref1->linesize[1],
159                               ref1->data[2], ref1->linesize[2], tref1,
160                               row << (3 - s->ss_v), col << 3,
161                               &b->mv[0][0], 4, 8 >> s->ss_v, w1, h1, 0);
162                 mc_chroma_dir(s, mc[4][b->filter][0],
163                               s->dst[1] + 4 * bytesperpixel,
164                               s->dst[2] + 4 * bytesperpixel, ls_uv,
165                               ref1->data[1], ref1->linesize[1],
166                               ref1->data[2], ref1->linesize[2], tref1,
167                               row << (3 - s->ss_v), (col << 3) + 4,
168                               &b->mv[1][0], 4, 8 >> s->ss_v, w1, h1, 0);
169             }
170
171             if (b->comp) {
172                 mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y,
173                             ref2->data[0], ref2->linesize[0], tref2,
174                             row << 3, col << 3, &b->mv[0][1], 4, 8, w2, h2, 1);
175                 mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y,
176                             ref2->data[0], ref2->linesize[0], tref2,
177                             row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w2, h2, 1);
178                 h2 = (h2 + s->ss_v) >> s->ss_v;
179                 if (s->ss_h) {
180                     w2 = (w2 + 1) >> 1;
181                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]);
182                     mc_chroma_dir(s, mc[4][b->filter][1],
183                                   s->dst[1], s->dst[2], ls_uv,
184                                   ref2->data[1], ref2->linesize[1],
185                                   ref2->data[2], ref2->linesize[2], tref2,
186                                   row << (3 - s->ss_v), col << 2,
187                                   &uvmv, 4, 8 >> s->ss_v, w2, h2, 1);
188                 } else {
189                     mc_chroma_dir(s, mc[4][b->filter][1],
190                                   s->dst[1], s->dst[2], ls_uv,
191                                   ref2->data[1], ref2->linesize[1],
192                                   ref2->data[2], ref2->linesize[2], tref2,
193                                   row << (3 - s->ss_v), col << 3,
194                                   &b->mv[0][1], 4, 8 >> s->ss_v, w2, h2, 1);
195                     mc_chroma_dir(s, mc[4][b->filter][1],
196                                   s->dst[1] + 4 * bytesperpixel,
197                                   s->dst[2] + 4 * bytesperpixel, ls_uv,
198                                   ref2->data[1], ref2->linesize[1],
199                                   ref2->data[2], ref2->linesize[2], tref2,
200                                   row << (3 - s->ss_v), (col << 3) + 4,
201                                   &b->mv[1][1], 4, 8 >> s->ss_v, w2, h2, 1);
202                 }
203             }
204         } else {
205             av_assert2(b->bs == BS_4x4);
206
207             // FIXME if two horizontally adjacent blocks have the same MV,
208             // do a w8 instead of a w4 call
209             mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y,
210                         ref1->data[0], ref1->linesize[0], tref1,
211                         row << 3, col << 3, &b->mv[0][0], 4, 4, w1, h1, 0);
212             mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4 * bytesperpixel, ls_y,
213                         ref1->data[0], ref1->linesize[0], tref1,
214                         row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w1, h1, 0);
215             mc_luma_dir(s, mc[4][b->filter][0],
216                         s->dst[0] + 4 * ls_y, ls_y,
217                         ref1->data[0], ref1->linesize[0], tref1,
218                         (row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w1, h1, 0);
219             mc_luma_dir(s, mc[4][b->filter][0],
220                         s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y,
221                         ref1->data[0], ref1->linesize[0], tref1,
222                         (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w1, h1, 0);
223             if (s->ss_v) {
224                 h1 = (h1 + 1) >> 1;
225                 if (s->ss_h) {
226                     w1 = (w1 + 1) >> 1;
227                     uvmv = ROUNDED_DIV_MVx4(b->mv[0][0], b->mv[1][0],
228                                             b->mv[2][0], b->mv[3][0]);
229                     mc_chroma_dir(s, mc[4][b->filter][0],
230                                   s->dst[1], s->dst[2], ls_uv,
231                                   ref1->data[1], ref1->linesize[1],
232                                   ref1->data[2], ref1->linesize[2], tref1,
233                                   row << 2, col << 2,
234                                   &uvmv, 4, 4, w1, h1, 0);
235                 } else {
236                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[2][0]);
237                     mc_chroma_dir(s, mc[4][b->filter][0],
238                                   s->dst[1], s->dst[2], ls_uv,
239                                   ref1->data[1], ref1->linesize[1],
240                                   ref1->data[2], ref1->linesize[2], tref1,
241                                   row << 2, col << 3,
242                                   &uvmv, 4, 4, w1, h1, 0);
243                     uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[3][0]);
244                     mc_chroma_dir(s, mc[4][b->filter][0],
245                                   s->dst[1] + 4 * bytesperpixel,
246                                   s->dst[2] + 4 * bytesperpixel, ls_uv,
247                                   ref1->data[1], ref1->linesize[1],
248                                   ref1->data[2], ref1->linesize[2], tref1,
249                                   row << 2, (col << 3) + 4,
250                                   &uvmv, 4, 4, w1, h1, 0);
251                 }
252             } else {
253                 if (s->ss_h) {
254                     w1 = (w1 + 1) >> 1;
255                     uvmv = ROUNDED_DIV_MVx2(b->mv[0][0], b->mv[1][0]);
256                     mc_chroma_dir(s, mc[4][b->filter][0],
257                                   s->dst[1], s->dst[2], ls_uv,
258                                   ref1->data[1], ref1->linesize[1],
259                                   ref1->data[2], ref1->linesize[2], tref1,
260                                   row << 3, col << 2,
261                                   &uvmv, 4, 4, w1, h1, 0);
262                     // BUG libvpx uses wrong block index for 4:2:2 bs=4x4
263                     // bottom block
264                     // https://code.google.com/p/webm/issues/detail?id=993
265                     uvmv = ROUNDED_DIV_MVx2(b->mv[1][0], b->mv[2][0]);
266                     mc_chroma_dir(s, mc[4][b->filter][0],
267                                   s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
268                                   ref1->data[1], ref1->linesize[1],
269                                   ref1->data[2], ref1->linesize[2], tref1,
270                                   (row << 3) + 4, col << 2,
271                                   &uvmv, 4, 4, w1, h1, 0);
272                 } else {
273                     mc_chroma_dir(s, mc[4][b->filter][0],
274                                   s->dst[1], s->dst[2], ls_uv,
275                                   ref1->data[1], ref1->linesize[1],
276                                   ref1->data[2], ref1->linesize[2], tref1,
277                                   row << 3, col << 3,
278                                   &b->mv[0][0], 4, 4, w1, h1, 0);
279                     mc_chroma_dir(s, mc[4][b->filter][0],
280                                   s->dst[1] + 4 * bytesperpixel,
281                                   s->dst[2] + 4 * bytesperpixel, ls_uv,
282                                   ref1->data[1], ref1->linesize[1],
283                                   ref1->data[2], ref1->linesize[2], tref1,
284                                   row << 3, (col << 3) + 4,
285                                   &b->mv[1][0], 4, 4, w1, h1, 0);
286                     mc_chroma_dir(s, mc[4][b->filter][0],
287                                   s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
288                                   ref1->data[1], ref1->linesize[1],
289                                   ref1->data[2], ref1->linesize[2], tref1,
290                                   (row << 3) + 4, col << 3,
291                                   &b->mv[2][0], 4, 4, w1, h1, 0);
292                     mc_chroma_dir(s, mc[4][b->filter][0],
293                                   s->dst[1] + 4 * ls_uv + 4 * bytesperpixel,
294                                   s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv,
295                                   ref1->data[1], ref1->linesize[1],
296                                   ref1->data[2], ref1->linesize[2], tref1,
297                                   (row << 3) + 4, (col << 3) + 4,
298                                   &b->mv[3][0], 4, 4, w1, h1, 0);
299                 }
300             }
301
302             if (b->comp) {
303                 mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y,
304                             ref2->data[0], ref2->linesize[0], tref2,
305                             row << 3, col << 3, &b->mv[0][1], 4, 4, w2, h2, 1);
306                 mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4 * bytesperpixel, ls_y,
307                             ref2->data[0], ref2->linesize[0], tref2,
308                             row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w2, h2, 1);
309                 mc_luma_dir(s, mc[4][b->filter][1],
310                             s->dst[0] + 4 * ls_y, ls_y,
311                             ref2->data[0], ref2->linesize[0], tref2,
312                             (row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w2, h2, 1);
313                 mc_luma_dir(s, mc[4][b->filter][1],
314                             s->dst[0] + 4 * ls_y + 4 * bytesperpixel, ls_y,
315                             ref2->data[0], ref2->linesize[0], tref2,
316                             (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w2, h2, 1);
317                 if (s->ss_v) {
318                     h2 = (h2 + 1) >> 1;
319                     if (s->ss_h) {
320                         w2 = (w2 + 1) >> 1;
321                         uvmv = ROUNDED_DIV_MVx4(b->mv[0][1], b->mv[1][1],
322                                                 b->mv[2][1], b->mv[3][1]);
323                         mc_chroma_dir(s, mc[4][b->filter][1],
324                                       s->dst[1], s->dst[2], ls_uv,
325                                       ref2->data[1], ref2->linesize[1],
326                                       ref2->data[2], ref2->linesize[2], tref2,
327                                       row << 2, col << 2,
328                                       &uvmv, 4, 4, w2, h2, 1);
329                     } else {
330                         uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[2][1]);
331                         mc_chroma_dir(s, mc[4][b->filter][1],
332                                       s->dst[1], s->dst[2], ls_uv,
333                                       ref2->data[1], ref2->linesize[1],
334                                       ref2->data[2], ref2->linesize[2], tref2,
335                                       row << 2, col << 3,
336                                       &uvmv, 4, 4, w2, h2, 1);
337                         uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[3][1]);
338                         mc_chroma_dir(s, mc[4][b->filter][1],
339                                       s->dst[1] + 4 * bytesperpixel,
340                                       s->dst[2] + 4 * bytesperpixel, ls_uv,
341                                       ref2->data[1], ref2->linesize[1],
342                                       ref2->data[2], ref2->linesize[2], tref2,
343                                       row << 2, (col << 3) + 4,
344                                       &uvmv, 4, 4, w2, h2, 1);
345                     }
346                 } else {
347                     if (s->ss_h) {
348                         w2 = (w2 + 1) >> 1;
349                         uvmv = ROUNDED_DIV_MVx2(b->mv[0][1], b->mv[1][1]);
350                         mc_chroma_dir(s, mc[4][b->filter][1],
351                                       s->dst[1], s->dst[2], ls_uv,
352                                       ref2->data[1], ref2->linesize[1],
353                                       ref2->data[2], ref2->linesize[2], tref2,
354                                       row << 3, col << 2,
355                                       &uvmv, 4, 4, w2, h2, 1);
356                         // BUG libvpx uses wrong block index for 4:2:2 bs=4x4
357                         // bottom block
358                         // https://code.google.com/p/webm/issues/detail?id=993
359                         uvmv = ROUNDED_DIV_MVx2(b->mv[1][1], b->mv[2][1]);
360                         mc_chroma_dir(s, mc[4][b->filter][1],
361                                       s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
362                                       ref2->data[1], ref2->linesize[1],
363                                       ref2->data[2], ref2->linesize[2], tref2,
364                                       (row << 3) + 4, col << 2,
365                                       &uvmv, 4, 4, w2, h2, 1);
366                     } else {
367                         mc_chroma_dir(s, mc[4][b->filter][1],
368                                       s->dst[1], s->dst[2], ls_uv,
369                                       ref2->data[1], ref2->linesize[1],
370                                       ref2->data[2], ref2->linesize[2], tref2,
371                                       row << 3, col << 3,
372                                       &b->mv[0][1], 4, 4, w2, h2, 1);
373                         mc_chroma_dir(s, mc[4][b->filter][1],
374                                       s->dst[1] + 4 * bytesperpixel,
375                                       s->dst[2] + 4 * bytesperpixel, ls_uv,
376                                       ref2->data[1], ref2->linesize[1],
377                                       ref2->data[2], ref2->linesize[2], tref2,
378                                       row << 3, (col << 3) + 4,
379                                       &b->mv[1][1], 4, 4, w2, h2, 1);
380                         mc_chroma_dir(s, mc[4][b->filter][1],
381                                       s->dst[1] + 4 * ls_uv, s->dst[2] + 4 * ls_uv, ls_uv,
382                                       ref2->data[1], ref2->linesize[1],
383                                       ref2->data[2], ref2->linesize[2], tref2,
384                                       (row << 3) + 4, col << 3,
385                                       &b->mv[2][1], 4, 4, w2, h2, 1);
386                         mc_chroma_dir(s, mc[4][b->filter][1],
387                                       s->dst[1] + 4 * ls_uv + 4 * bytesperpixel,
388                                       s->dst[2] + 4 * ls_uv + 4 * bytesperpixel, ls_uv,
389                                       ref2->data[1], ref2->linesize[1],
390                                       ref2->data[2], ref2->linesize[2], tref2,
391                                       (row << 3) + 4, (col << 3) + 4,
392                                       &b->mv[3][1], 4, 4, w2, h2, 1);
393                     }
394                 }
395             }
396         }
397     } else {
398         int bwl = bwlog_tab[0][b->bs];
399         int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4;
400         int uvbw = bwh_tab[s->ss_h][b->bs][0] * 4, uvbh = bwh_tab[s->ss_v][b->bs][1] * 4;
401
402         mc_luma_dir(s, mc[bwl][b->filter][0], s->dst[0], ls_y,
403                     ref1->data[0], ref1->linesize[0], tref1,
404                     row << 3, col << 3, &b->mv[0][0], bw, bh, w1, h1, 0);
405         w1 = (w1 + s->ss_h) >> s->ss_h;
406         h1 = (h1 + s->ss_v) >> s->ss_v;
407         mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][0],
408                       s->dst[1], s->dst[2], ls_uv,
409                       ref1->data[1], ref1->linesize[1],
410                       ref1->data[2], ref1->linesize[2], tref1,
411                       row << (3 - s->ss_v), col << (3 - s->ss_h),
412                       &b->mv[0][0], uvbw, uvbh, w1, h1, 0);
413
414         if (b->comp) {
415             mc_luma_dir(s, mc[bwl][b->filter][1], s->dst[0], ls_y,
416                         ref2->data[0], ref2->linesize[0], tref2,
417                         row << 3, col << 3, &b->mv[0][1], bw, bh, w2, h2, 1);
418             w2 = (w2 + s->ss_h) >> s->ss_h;
419             h2 = (h2 + s->ss_v) >> s->ss_v;
420             mc_chroma_dir(s, mc[bwl + s->ss_h][b->filter][1],
421                           s->dst[1], s->dst[2], ls_uv,
422                           ref2->data[1], ref2->linesize[1],
423                           ref2->data[2], ref2->linesize[2], tref2,
424                           row << (3 - s->ss_v), col << (3 - s->ss_h),
425                           &b->mv[0][1], uvbw, uvbh, w2, h2, 1);
426         }
427     }
428 }