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