xref: /third_party/ffmpeg/libavcodec/vp9mvs.c (revision cabdff1a)
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#include "threadframe.h"
25#include "vp56.h"
26#include "vp9.h"
27#include "vp9data.h"
28#include "vp9dec.h"
29
30static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src,
31                                      VP9TileData *td)
32{
33    dst->x = av_clip(src->x, td->min_mv.x, td->max_mv.x);
34    dst->y = av_clip(src->y, td->min_mv.y, td->max_mv.y);
35}
36
37static void find_ref_mvs(VP9TileData *td,
38                         VP56mv *pmv, int ref, int z, int idx, int sb)
39{
40    static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = {
41        [BS_64x64] = { {  3, -1 }, { -1,  3 }, {  4, -1 }, { -1,  4 },
42                       { -1, -1 }, {  0, -1 }, { -1,  0 }, {  6, -1 } },
43        [BS_64x32] = { {  0, -1 }, { -1,  0 }, {  4, -1 }, { -1,  2 },
44                       { -1, -1 }, {  0, -3 }, { -3,  0 }, {  2, -1 } },
45        [BS_32x64] = { { -1,  0 }, {  0, -1 }, { -1,  4 }, {  2, -1 },
46                       { -1, -1 }, { -3,  0 }, {  0, -3 }, { -1,  2 } },
47        [BS_32x32] = { {  1, -1 }, { -1,  1 }, {  2, -1 }, { -1,  2 },
48                       { -1, -1 }, {  0, -3 }, { -3,  0 }, { -3, -3 } },
49        [BS_32x16] = { {  0, -1 }, { -1,  0 }, {  2, -1 }, { -1, -1 },
50                       { -1,  1 }, {  0, -3 }, { -3,  0 }, { -3, -3 } },
51        [BS_16x32] = { { -1,  0 }, {  0, -1 }, { -1,  2 }, { -1, -1 },
52                       {  1, -1 }, { -3,  0 }, {  0, -3 }, { -3, -3 } },
53        [BS_16x16] = { {  0, -1 }, { -1,  0 }, {  1, -1 }, { -1,  1 },
54                       { -1, -1 }, {  0, -3 }, { -3,  0 }, { -3, -3 } },
55        [BS_16x8]  = { {  0, -1 }, { -1,  0 }, {  1, -1 }, { -1, -1 },
56                       {  0, -2 }, { -2,  0 }, { -2, -1 }, { -1, -2 } },
57        [BS_8x16]  = { { -1,  0 }, {  0, -1 }, { -1,  1 }, { -1, -1 },
58                       { -2,  0 }, {  0, -2 }, { -1, -2 }, { -2, -1 } },
59        [BS_8x8]   = { {  0, -1 }, { -1,  0 }, { -1, -1 }, {  0, -2 },
60                       { -2,  0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
61        [BS_8x4]   = { {  0, -1 }, { -1,  0 }, { -1, -1 }, {  0, -2 },
62                       { -2,  0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
63        [BS_4x8]   = { {  0, -1 }, { -1,  0 }, { -1, -1 }, {  0, -2 },
64                       { -2,  0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
65        [BS_4x4]   = { {  0, -1 }, { -1,  0 }, { -1, -1 }, {  0, -2 },
66                       { -2,  0 }, { -1, -2 }, { -2, -1 }, { -2, -2 } },
67    };
68    VP9Context *s = td->s;
69    VP9Block *b = td->b;
70    int row = td->row, col = td->col, row7 = td->row7;
71    const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
72#define INVALID_MV 0x80008000U
73    uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV;
74    int i;
75
76#define RETURN_DIRECT_MV(mv)                    \
77    do {                                        \
78        uint32_t m = AV_RN32A(&mv);             \
79        if (!idx) {                             \
80            AV_WN32A(pmv, m);                   \
81            return;                             \
82        } else if (mem == INVALID_MV) {         \
83            mem = m;                            \
84        } else if (m != mem) {                  \
85            AV_WN32A(pmv, m);                   \
86            return;                             \
87        }                                       \
88    } while (0)
89
90    if (sb >= 0) {
91        if (sb == 2 || sb == 1) {
92            RETURN_DIRECT_MV(b->mv[0][z]);
93        } else if (sb == 3) {
94            RETURN_DIRECT_MV(b->mv[2][z]);
95            RETURN_DIRECT_MV(b->mv[1][z]);
96            RETURN_DIRECT_MV(b->mv[0][z]);
97        }
98
99#define RETURN_MV(mv)                                                  \
100    do {                                                               \
101        if (sb > 0) {                                                  \
102            VP56mv tmp;                                                \
103            uint32_t m;                                                \
104            av_assert2(idx == 1);                                      \
105            av_assert2(mem != INVALID_MV);                             \
106            if (mem_sub8x8 == INVALID_MV) {                            \
107                clamp_mv(&tmp, &mv, td);                               \
108                m = AV_RN32A(&tmp);                                    \
109                if (m != mem) {                                        \
110                    AV_WN32A(pmv, m);                                  \
111                    return;                                            \
112                }                                                      \
113                mem_sub8x8 = AV_RN32A(&mv);                            \
114            } else if (mem_sub8x8 != AV_RN32A(&mv)) {                  \
115                clamp_mv(&tmp, &mv, td);                               \
116                m = AV_RN32A(&tmp);                                    \
117                if (m != mem) {                                        \
118                    AV_WN32A(pmv, m);                                  \
119                } else {                                               \
120                    /* BUG I'm pretty sure this isn't the intention */ \
121                    AV_WN32A(pmv, 0);                                  \
122                }                                                      \
123                return;                                                \
124            }                                                          \
125        } else {                                                       \
126            uint32_t m = AV_RN32A(&mv);                                \
127            if (!idx) {                                                \
128                clamp_mv(pmv, &mv, td);                                \
129                return;                                                \
130            } else if (mem == INVALID_MV) {                            \
131                mem = m;                                               \
132            } else if (m != mem) {                                     \
133                clamp_mv(pmv, &mv, td);                                \
134                return;                                                \
135            }                                                          \
136        }                                                              \
137    } while (0)
138
139        if (row > 0) {
140            VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col];
141            if (mv->ref[0] == ref)
142                RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
143            else if (mv->ref[1] == ref)
144                RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]);
145        }
146        if (col > td->tile_col_start) {
147            VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1];
148            if (mv->ref[0] == ref)
149                RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][0]);
150            else if (mv->ref[1] == ref)
151                RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][1]);
152        }
153        i = 2;
154    } else {
155        i = 0;
156    }
157
158    // previously coded MVs in this neighborhood, using same reference frame
159    for (; i < 8; i++) {
160        int c = p[i][0] + col, r = p[i][1] + row;
161
162        if (c >= td->tile_col_start && c < s->cols &&
163            r >= 0 && r < s->rows) {
164            VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
165
166            if (mv->ref[0] == ref)
167                RETURN_MV(mv->mv[0]);
168            else if (mv->ref[1] == ref)
169                RETURN_MV(mv->mv[1]);
170        }
171    }
172
173    // MV at this position in previous frame, using same reference frame
174    if (s->s.h.use_last_frame_mvs) {
175        VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
176
177        if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass)
178            ff_thread_await_progress(&s->s.frames[REF_FRAME_MVPAIR].tf, row >> 3, 0);
179        if (mv->ref[0] == ref)
180            RETURN_MV(mv->mv[0]);
181        else if (mv->ref[1] == ref)
182            RETURN_MV(mv->mv[1]);
183    }
184
185#define RETURN_SCALE_MV(mv, scale)              \
186    do {                                        \
187        if (scale) {                            \
188            VP56mv mv_temp = { -mv.x, -mv.y };  \
189            RETURN_MV(mv_temp);                 \
190        } else {                                \
191            RETURN_MV(mv);                      \
192        }                                       \
193    } while (0)
194
195    // previously coded MVs in this neighborhood, using different reference frame
196    for (i = 0; i < 8; i++) {
197        int c = p[i][0] + col, r = p[i][1] + row;
198
199        if (c >= td->tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
200            VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
201
202            if (mv->ref[0] != ref && mv->ref[0] >= 0)
203                RETURN_SCALE_MV(mv->mv[0],
204                                s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]);
205            if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
206                // BUG - libvpx has this condition regardless of whether
207                // we used the first ref MV and pre-scaling
208                AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
209                RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]);
210            }
211        }
212    }
213
214    // MV at this position in previous frame, using different reference frame
215    if (s->s.h.use_last_frame_mvs) {
216        VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
217
218        // no need to await_progress, because we already did that above
219        if (mv->ref[0] != ref && mv->ref[0] >= 0)
220            RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]);
221        if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
222            // BUG - libvpx has this condition regardless of whether
223            // we used the first ref MV and pre-scaling
224            AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
225            RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]);
226        }
227    }
228
229    AV_ZERO32(pmv);
230    clamp_mv(pmv, pmv, td);
231#undef INVALID_MV
232#undef RETURN_MV
233#undef RETURN_SCALE_MV
234}
235
236static av_always_inline int read_mv_component(VP9TileData *td, int idx, int hp)
237{
238    VP9Context *s = td->s;
239    int bit, sign = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].sign);
240    int n, c = vp8_rac_get_tree(td->c, ff_vp9_mv_class_tree,
241                                s->prob.p.mv_comp[idx].classes);
242
243    td->counts.mv_comp[idx].sign[sign]++;
244    td->counts.mv_comp[idx].classes[c]++;
245    if (c) {
246        int m;
247
248        for (n = 0, m = 0; m < c; m++) {
249            bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].bits[m]);
250            n |= bit << m;
251            td->counts.mv_comp[idx].bits[m][bit]++;
252        }
253        n <<= 3;
254        bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree,
255                               s->prob.p.mv_comp[idx].fp);
256        n  |= bit << 1;
257        td->counts.mv_comp[idx].fp[bit]++;
258        if (hp) {
259            bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].hp);
260            td->counts.mv_comp[idx].hp[bit]++;
261            n |= bit;
262        } else {
263            n |= 1;
264            // bug in libvpx - we count for bw entropy purposes even if the
265            // bit wasn't coded
266            td->counts.mv_comp[idx].hp[1]++;
267        }
268        n += 8 << c;
269    } else {
270        n = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0);
271        td->counts.mv_comp[idx].class0[n]++;
272        bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree,
273                               s->prob.p.mv_comp[idx].class0_fp[n]);
274        td->counts.mv_comp[idx].class0_fp[n][bit]++;
275        n = (n << 3) | (bit << 1);
276        if (hp) {
277            bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0_hp);
278            td->counts.mv_comp[idx].class0_hp[bit]++;
279            n |= bit;
280        } else {
281            n |= 1;
282            // bug in libvpx - we count for bw entropy purposes even if the
283            // bit wasn't coded
284            td->counts.mv_comp[idx].class0_hp[1]++;
285        }
286    }
287
288    return sign ? -(n + 1) : (n + 1);
289}
290
291void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb)
292{
293    VP9Context *s = td->s;
294    VP9Block *b = td->b;
295
296    if (mode == ZEROMV) {
297        AV_ZERO64(mv);
298    } else {
299        int hp;
300
301        // FIXME cache this value and reuse for other subblocks
302        find_ref_mvs(td, &mv[0], b->ref[0], 0, mode == NEARMV,
303                     mode == NEWMV ? -1 : sb);
304        // FIXME maybe move this code into find_ref_mvs()
305        if ((mode == NEWMV || sb == -1) &&
306            !(hp = s->s.h.highprecisionmvs &&
307              abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) {
308            if (mv[0].y & 1) {
309                if (mv[0].y < 0)
310                    mv[0].y++;
311                else
312                    mv[0].y--;
313            }
314            if (mv[0].x & 1) {
315                if (mv[0].x < 0)
316                    mv[0].x++;
317                else
318                    mv[0].x--;
319            }
320        }
321        if (mode == NEWMV) {
322            enum MVJoint j = vp8_rac_get_tree(td->c, ff_vp9_mv_joint_tree,
323                                              s->prob.p.mv_joint);
324
325            td->counts.mv_joint[j]++;
326            if (j >= MV_JOINT_V)
327                mv[0].y += read_mv_component(td, 0, hp);
328            if (j & 1)
329                mv[0].x += read_mv_component(td, 1, hp);
330        }
331
332        if (b->comp) {
333            // FIXME cache this value and reuse for other subblocks
334            find_ref_mvs(td, &mv[1], b->ref[1], 1, mode == NEARMV,
335                         mode == NEWMV ? -1 : sb);
336            if ((mode == NEWMV || sb == -1) &&
337                !(hp = s->s.h.highprecisionmvs &&
338                  abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) {
339                if (mv[1].y & 1) {
340                    if (mv[1].y < 0)
341                        mv[1].y++;
342                    else
343                        mv[1].y--;
344                }
345                if (mv[1].x & 1) {
346                    if (mv[1].x < 0)
347                        mv[1].x++;
348                    else
349                        mv[1].x--;
350                }
351            }
352            if (mode == NEWMV) {
353                enum MVJoint j = vp8_rac_get_tree(td->c, ff_vp9_mv_joint_tree,
354                                                  s->prob.p.mv_joint);
355
356                td->counts.mv_joint[j]++;
357                if (j >= MV_JOINT_V)
358                    mv[1].y += read_mv_component(td, 0, hp);
359                if (j & 1)
360                    mv[1].x += read_mv_component(td, 1, hp);
361            }
362        }
363    }
364}
365