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