LCOV - code coverage report
Current view: top level - libavcodec - vp9mvs.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 150 150 100.0 %
Date: 2017-12-17 23:02:56 Functions: 4 4 100.0 %

          Line data    Source code
       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 "internal.h"
      25             : #include "vp56.h"
      26             : #include "vp9.h"
      27             : #include "vp9data.h"
      28             : #include "vp9dec.h"
      29             : 
      30      609994 : static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src,
      31             :                                       VP9TileData *td)
      32             : {
      33      609994 :     dst->x = av_clip(src->x, td->min_mv.x, td->max_mv.x);
      34      609994 :     dst->y = av_clip(src->y, td->min_mv.y, td->max_mv.y);
      35      609994 : }
      36             : 
      37      629131 : static 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      629131 :     VP9Context *s = td->s;
      69      629131 :     VP9Block *b = td->b;
      70      629131 :     int row = td->row, col = td->col, row7 = td->row7;
      71      629131 :     const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
      72             : #define INVALID_MV 0x80008000U
      73      629131 :     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      629131 :     if (sb >= 0) {
      91       71677 :         if (sb == 2 || sb == 1) {
      92       33343 :             RETURN_DIRECT_MV(b->mv[0][z]);
      93       38334 :         } else if (sb == 3) {
      94        9992 :             RETURN_DIRECT_MV(b->mv[2][z]);
      95        3597 :             RETURN_DIRECT_MV(b->mv[1][z]);
      96         596 :             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       47695 :         if (row > 0) {
     140       37375 :             VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col];
     141       37375 :             if (mv->ref[0] == ref)
     142       32757 :                 RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
     143        4618 :             else if (mv->ref[1] == ref)
     144         677 :                 RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]);
     145             :         }
     146       25888 :         if (col > td->tile_col_start) {
     147       25230 :             VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1];
     148       25230 :             if (mv->ref[0] == ref)
     149       22754 :                 RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][0]);
     150        2476 :             else if (mv->ref[1] == ref)
     151         363 :                 RETURN_MV(td->left_mv_ctx[2 * row7 + (sb >> 1)][1]);
     152             :         }
     153        5615 :         i = 2;
     154             :     } else {
     155      557454 :         i = 0;
     156             :     }
     157             : 
     158             :     // previously coded MVs in this neighborhood, using same reference frame
     159      986135 :     for (; i < 8; i++) {
     160      963343 :         int c = p[i][0] + col, r = p[i][1] + row;
     161             : 
     162      963343 :         if (c >= td->tile_col_start && c < s->cols &&
     163      878326 :             r >= 0 && r < s->rows) {
     164      878304 :             VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
     165             : 
     166      878304 :             if (mv->ref[0] == ref)
     167      649656 :                 RETURN_MV(mv->mv[0]);
     168      228648 :             else if (mv->ref[1] == ref)
     169       36239 :                 RETURN_MV(mv->mv[1]);
     170             :         }
     171             :     }
     172             : 
     173             :     // MV at this position in previous frame, using same reference frame
     174       22792 :     if (s->s.h.use_last_frame_mvs) {
     175       21746 :         VP9mvrefPair *mv = &s->s.frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
     176             : 
     177       21746 :         if (!s->s.frames[REF_FRAME_MVPAIR].uses_2pass)
     178       21746 :             ff_thread_await_progress(&s->s.frames[REF_FRAME_MVPAIR].tf, row >> 3, 0);
     179       21746 :         if (mv->ref[0] == ref)
     180        9483 :             RETURN_MV(mv->mv[0]);
     181       12263 :         else if (mv->ref[1] == ref)
     182         296 :             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       41207 :     for (i = 0; i < 8; i++) {
     197       38358 :         int c = p[i][0] + col, r = p[i][1] + row;
     198             : 
     199       38358 :         if (c >= td->tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
     200       23721 :             VP9mvrefPair *mv = &s->s.frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
     201             : 
     202       23721 :             if (mv->ref[0] != ref && mv->ref[0] >= 0)
     203       12403 :                 RETURN_SCALE_MV(mv->mv[0],
     204             :                                 s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]);
     205       13201 :             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         134 :                 AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
     209          92 :                 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        2849 :     if (s->s.h.use_last_frame_mvs) {
     216        2648 :         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        2648 :         if (mv->ref[0] != ref && mv->ref[0] >= 0)
     220        1496 :             RETURN_SCALE_MV(mv->mv[0], s->s.h.signbias[mv->ref[0]] != s->s.h.signbias[ref]);
     221        1236 :         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           5 :             AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
     225           5 :             RETURN_SCALE_MV(mv->mv[1], s->s.h.signbias[mv->ref[1]] != s->s.h.signbias[ref]);
     226             :         }
     227             :     }
     228             : 
     229        1428 :     AV_ZERO32(pmv);
     230        1428 :     clamp_mv(pmv, pmv, td);
     231             : #undef INVALID_MV
     232             : #undef RETURN_MV
     233             : #undef RETURN_SCALE_MV
     234             : }
     235             : 
     236      418571 : static av_always_inline int read_mv_component(VP9TileData *td, int idx, int hp)
     237             : {
     238      418571 :     VP9Context *s = td->s;
     239      418571 :     int bit, sign = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].sign);
     240      418571 :     int n, c = vp8_rac_get_tree(td->c, ff_vp9_mv_class_tree,
     241      418571 :                                 s->prob.p.mv_comp[idx].classes);
     242             : 
     243      418571 :     td->counts.mv_comp[idx].sign[sign]++;
     244      418571 :     td->counts.mv_comp[idx].classes[c]++;
     245      418571 :     if (c) {
     246             :         int m;
     247             : 
     248      155234 :         for (n = 0, m = 0; m < c; m++) {
     249      102260 :             bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].bits[m]);
     250      102260 :             n |= bit << m;
     251      102260 :             td->counts.mv_comp[idx].bits[m][bit]++;
     252             :         }
     253       52974 :         n <<= 3;
     254       52974 :         bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree,
     255       52974 :                                s->prob.p.mv_comp[idx].fp);
     256       52974 :         n  |= bit << 1;
     257       52974 :         td->counts.mv_comp[idx].fp[bit]++;
     258       52974 :         if (hp) {
     259       28459 :             bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].hp);
     260       28459 :             td->counts.mv_comp[idx].hp[bit]++;
     261       28459 :             n |= bit;
     262             :         } else {
     263       24515 :             n |= 1;
     264             :             // bug in libvpx - we count for bw entropy purposes even if the
     265             :             // bit wasn't coded
     266       24515 :             td->counts.mv_comp[idx].hp[1]++;
     267             :         }
     268       52974 :         n += 8 << c;
     269             :     } else {
     270      365597 :         n = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0);
     271      365597 :         td->counts.mv_comp[idx].class0[n]++;
     272      365597 :         bit = vp8_rac_get_tree(td->c, ff_vp9_mv_fp_tree,
     273      365597 :                                s->prob.p.mv_comp[idx].class0_fp[n]);
     274      365597 :         td->counts.mv_comp[idx].class0_fp[n][bit]++;
     275      365597 :         n = (n << 3) | (bit << 1);
     276      365597 :         if (hp) {
     277      190711 :             bit = vp56_rac_get_prob(td->c, s->prob.p.mv_comp[idx].class0_hp);
     278      190711 :             td->counts.mv_comp[idx].class0_hp[bit]++;
     279      190711 :             n |= bit;
     280             :         } else {
     281      174886 :             n |= 1;
     282             :             // bug in libvpx - we count for bw entropy purposes even if the
     283             :             // bit wasn't coded
     284      174886 :             td->counts.mv_comp[idx].class0_hp[1]++;
     285             :         }
     286             :     }
     287             : 
     288      418571 :     return sign ? -(n + 1) : (n + 1);
     289             : }
     290             : 
     291      612015 : void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb)
     292             : {
     293      612015 :     VP9Context *s = td->s;
     294      612015 :     VP9Block *b = td->b;
     295             : 
     296      612015 :     if (mode == ZEROMV) {
     297       10883 :         AV_ZERO64(mv);
     298             :     } else {
     299             :         int hp;
     300             : 
     301             :         // FIXME cache this value and reuse for other subblocks
     302      601132 :         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     1131997 :         if ((mode == NEWMV || sb == -1) &&
     306     1408523 :             !(hp = s->s.h.highprecisionmvs &&
     307      856134 :               abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) {
     308      246465 :             if (mv[0].y & 1) {
     309        1747 :                 if (mv[0].y < 0)
     310         734 :                     mv[0].y++;
     311             :                 else
     312        1013 :                     mv[0].y--;
     313             :             }
     314      246465 :             if (mv[0].x & 1) {
     315        2198 :                 if (mv[0].x < 0)
     316         767 :                     mv[0].x++;
     317             :                 else
     318        1431 :                     mv[0].x--;
     319             :             }
     320             :         }
     321      601132 :         if (mode == NEWMV) {
     322      266636 :             enum MVJoint j = vp8_rac_get_tree(td->c, ff_vp9_mv_joint_tree,
     323      266636 :                                               s->prob.p.mv_joint);
     324             : 
     325      266636 :             td->counts.mv_joint[j]++;
     326      266636 :             if (j >= MV_JOINT_V)
     327      220910 :                 mv[0].y += read_mv_component(td, 0, hp);
     328      266636 :             if (j & 1)
     329      177191 :                 mv[0].x += read_mv_component(td, 1, hp);
     330             :         }
     331             : 
     332      601132 :         if (b->comp) {
     333             :             // FIXME cache this value and reuse for other subblocks
     334       27999 :             find_ref_mvs(td, &mv[1], b->ref[1], 1, mode == NEARMV,
     335             :                          mode == NEWMV ? -1 : sb);
     336       54588 :             if ((mode == NEWMV || sb == -1) &&
     337       62973 :                 !(hp = s->s.h.highprecisionmvs &&
     338       35827 :                   abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) {
     339       17957 :                 if (mv[1].y & 1) {
     340          80 :                     if (mv[1].y < 0)
     341          30 :                         mv[1].y++;
     342             :                     else
     343          50 :                         mv[1].y--;
     344             :                 }
     345       17957 :                 if (mv[1].x & 1) {
     346          64 :                     if (mv[1].x < 0)
     347          54 :                         mv[1].x++;
     348             :                     else
     349          10 :                         mv[1].x--;
     350             :                 }
     351             :             }
     352       27999 :             if (mode == NEWMV) {
     353       13369 :                 enum MVJoint j = vp8_rac_get_tree(td->c, ff_vp9_mv_joint_tree,
     354       13369 :                                                   s->prob.p.mv_joint);
     355             : 
     356       13369 :                 td->counts.mv_joint[j]++;
     357       13369 :                 if (j >= MV_JOINT_V)
     358       10926 :                     mv[1].y += read_mv_component(td, 0, hp);
     359       13369 :                 if (j & 1)
     360        9544 :                     mv[1].x += read_mv_component(td, 1, hp);
     361             :             }
     362             :         }
     363             :     }
     364      612015 : }

Generated by: LCOV version 1.13