tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

vp9prob.c (10338B)


      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 "vp9.h"
     25 #include "vp9dec.h"
     26 
     27 static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1,
     28                                        int max_count, int update_factor)
     29 {
     30    unsigned ct = ct0 + ct1, p2, p1;
     31 
     32    if (!ct)
     33        return;
     34 
     35    update_factor = FASTDIV(update_factor * FFMIN(ct, max_count), max_count);
     36    p1 = *p;
     37    p2 = ((((int64_t) ct0) << 8) + (ct >> 1)) / ct;
     38    p2 = av_clip(p2, 1, 255);
     39 
     40    // (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8
     41    *p = p1 + (((p2 - p1) * update_factor + 128) >> 8);
     42 }
     43 
     44 void ff_vp9_adapt_probs(VP9Context *s)
     45 {
     46    int i, j, k, l, m;
     47    ProbContext *p = &s->prob_ctx[s->s.h.framectxid].p;
     48    int uf = (s->s.h.keyframe || s->s.h.intraonly || !s->last_keyframe) ? 112 : 128;
     49 
     50    // coefficients
     51    for (i = 0; i < 4; i++)
     52        for (j = 0; j < 2; j++)
     53            for (k = 0; k < 2; k++)
     54                for (l = 0; l < 6; l++)
     55                    for (m = 0; m < 6; m++) {
     56                        uint8_t *pp = s->prob_ctx[s->s.h.framectxid].coef[i][j][k][l][m];
     57                        unsigned *e = s->td[0].counts.eob[i][j][k][l][m];
     58                        unsigned *c = s->td[0].counts.coef[i][j][k][l][m];
     59 
     60                        if (l == 0 && m >= 3) // dc only has 3 pt
     61                            break;
     62 
     63                        adapt_prob(&pp[0], e[0], e[1], 24, uf);
     64                        adapt_prob(&pp[1], c[0], c[1] + c[2], 24, uf);
     65                        adapt_prob(&pp[2], c[1], c[2], 24, uf);
     66                    }
     67 
     68    if (s->s.h.keyframe || s->s.h.intraonly) {
     69        memcpy(p->skip,  s->prob.p.skip,  sizeof(p->skip));
     70        memcpy(p->tx32p, s->prob.p.tx32p, sizeof(p->tx32p));
     71        memcpy(p->tx16p, s->prob.p.tx16p, sizeof(p->tx16p));
     72        memcpy(p->tx8p,  s->prob.p.tx8p,  sizeof(p->tx8p));
     73        return;
     74    }
     75 
     76    // skip flag
     77    for (i = 0; i < 3; i++)
     78        adapt_prob(&p->skip[i], s->td[0].counts.skip[i][0],
     79                   s->td[0].counts.skip[i][1], 20, 128);
     80 
     81    // intra/inter flag
     82    for (i = 0; i < 4; i++)
     83        adapt_prob(&p->intra[i], s->td[0].counts.intra[i][0],
     84                   s->td[0].counts.intra[i][1], 20, 128);
     85 
     86    // comppred flag
     87    if (s->s.h.comppredmode == PRED_SWITCHABLE) {
     88        for (i = 0; i < 5; i++)
     89            adapt_prob(&p->comp[i], s->td[0].counts.comp[i][0],
     90                       s->td[0].counts.comp[i][1], 20, 128);
     91    }
     92 
     93    // reference frames
     94    if (s->s.h.comppredmode != PRED_SINGLEREF) {
     95        for (i = 0; i < 5; i++)
     96            adapt_prob(&p->comp_ref[i], s->td[0].counts.comp_ref[i][0],
     97                       s->td[0].counts.comp_ref[i][1], 20, 128);
     98    }
     99 
    100    if (s->s.h.comppredmode != PRED_COMPREF) {
    101        for (i = 0; i < 5; i++) {
    102            uint8_t *pp = p->single_ref[i];
    103            unsigned (*c)[2] = s->td[0].counts.single_ref[i];
    104 
    105            adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128);
    106            adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128);
    107        }
    108    }
    109 
    110    // block partitioning
    111    for (i = 0; i < 4; i++)
    112        for (j = 0; j < 4; j++) {
    113            uint8_t *pp = p->partition[i][j];
    114            unsigned *c = s->td[0].counts.partition[i][j];
    115 
    116            adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
    117            adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
    118            adapt_prob(&pp[2], c[2], c[3], 20, 128);
    119        }
    120 
    121    // tx size
    122    if (s->s.h.txfmmode == TX_SWITCHABLE) {
    123        for (i = 0; i < 2; i++) {
    124            unsigned *c16 = s->td[0].counts.tx16p[i], *c32 = s->td[0].counts.tx32p[i];
    125 
    126            adapt_prob(&p->tx8p[i], s->td[0].counts.tx8p[i][0],
    127                       s->td[0].counts.tx8p[i][1], 20, 128);
    128            adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128);
    129            adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128);
    130            adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128);
    131            adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128);
    132            adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128);
    133        }
    134    }
    135 
    136    // interpolation filter
    137    if (s->s.h.filtermode == FILTER_SWITCHABLE) {
    138        for (i = 0; i < 4; i++) {
    139            uint8_t *pp = p->filter[i];
    140            unsigned *c = s->td[0].counts.filter[i];
    141 
    142            adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128);
    143            adapt_prob(&pp[1], c[1], c[2], 20, 128);
    144        }
    145    }
    146 
    147    // inter modes
    148    for (i = 0; i < 7; i++) {
    149        uint8_t *pp = p->mv_mode[i];
    150        unsigned *c = s->td[0].counts.mv_mode[i];
    151 
    152        adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128);
    153        adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128);
    154        adapt_prob(&pp[2], c[1], c[3], 20, 128);
    155    }
    156 
    157    // mv joints
    158    {
    159        uint8_t *pp = p->mv_joint;
    160        unsigned *c = s->td[0].counts.mv_joint;
    161 
    162        adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
    163        adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
    164        adapt_prob(&pp[2], c[2], c[3], 20, 128);
    165    }
    166 
    167    // mv components
    168    for (i = 0; i < 2; i++) {
    169        uint8_t *pp;
    170        unsigned *c, (*c2)[2], sum;
    171 
    172        adapt_prob(&p->mv_comp[i].sign, s->td[0].counts.mv_comp[i].sign[0],
    173                   s->td[0].counts.mv_comp[i].sign[1], 20, 128);
    174 
    175        pp  = p->mv_comp[i].classes;
    176        c   = s->td[0].counts.mv_comp[i].classes;
    177        sum = c[1] + c[2] + c[3] + c[4] + c[5] +
    178              c[6] + c[7] + c[8] + c[9] + c[10];
    179        adapt_prob(&pp[0], c[0], sum, 20, 128);
    180        sum -= c[1];
    181        adapt_prob(&pp[1], c[1], sum, 20, 128);
    182        sum -= c[2] + c[3];
    183        adapt_prob(&pp[2], c[2] + c[3], sum, 20, 128);
    184        adapt_prob(&pp[3], c[2], c[3], 20, 128);
    185        sum -= c[4] + c[5];
    186        adapt_prob(&pp[4], c[4] + c[5], sum, 20, 128);
    187        adapt_prob(&pp[5], c[4], c[5], 20, 128);
    188        sum -= c[6];
    189        adapt_prob(&pp[6], c[6], sum, 20, 128);
    190        adapt_prob(&pp[7], c[7] + c[8], c[9] + c[10], 20, 128);
    191        adapt_prob(&pp[8], c[7], c[8], 20, 128);
    192        adapt_prob(&pp[9], c[9], c[10], 20, 128);
    193 
    194        adapt_prob(&p->mv_comp[i].class0, s->td[0].counts.mv_comp[i].class0[0],
    195                   s->td[0].counts.mv_comp[i].class0[1], 20, 128);
    196        pp = p->mv_comp[i].bits;
    197        c2 = s->td[0].counts.mv_comp[i].bits;
    198        for (j = 0; j < 10; j++)
    199            adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128);
    200 
    201        for (j = 0; j < 2; j++) {
    202            pp = p->mv_comp[i].class0_fp[j];
    203            c  = s->td[0].counts.mv_comp[i].class0_fp[j];
    204            adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
    205            adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
    206            adapt_prob(&pp[2], c[2], c[3], 20, 128);
    207        }
    208        pp = p->mv_comp[i].fp;
    209        c  = s->td[0].counts.mv_comp[i].fp;
    210        adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
    211        adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
    212        adapt_prob(&pp[2], c[2], c[3], 20, 128);
    213 
    214        if (s->s.h.highprecisionmvs) {
    215            adapt_prob(&p->mv_comp[i].class0_hp,
    216                       s->td[0].counts.mv_comp[i].class0_hp[0],
    217                       s->td[0].counts.mv_comp[i].class0_hp[1], 20, 128);
    218            adapt_prob(&p->mv_comp[i].hp, s->td[0].counts.mv_comp[i].hp[0],
    219                       s->td[0].counts.mv_comp[i].hp[1], 20, 128);
    220        }
    221    }
    222 
    223    // y intra modes
    224    for (i = 0; i < 4; i++) {
    225        uint8_t *pp = p->y_mode[i];
    226        unsigned *c = s->td[0].counts.y_mode[i], sum, s2;
    227 
    228        sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
    229        adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
    230        sum -= c[TM_VP8_PRED];
    231        adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
    232        sum -= c[VERT_PRED];
    233        adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
    234        s2   = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
    235        sum -= s2;
    236        adapt_prob(&pp[3], s2, sum, 20, 128);
    237        s2 -= c[HOR_PRED];
    238        adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
    239        adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED],
    240                   20, 128);
    241        sum -= c[DIAG_DOWN_LEFT_PRED];
    242        adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
    243        sum -= c[VERT_LEFT_PRED];
    244        adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
    245        adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
    246    }
    247 
    248    // uv intra modes
    249    for (i = 0; i < 10; i++) {
    250        uint8_t *pp = p->uv_mode[i];
    251        unsigned *c = s->td[0].counts.uv_mode[i], sum, s2;
    252 
    253        sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
    254        adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
    255        sum -= c[TM_VP8_PRED];
    256        adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
    257        sum -= c[VERT_PRED];
    258        adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
    259        s2   = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
    260        sum -= s2;
    261        adapt_prob(&pp[3], s2, sum, 20, 128);
    262        s2 -= c[HOR_PRED];
    263        adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
    264        adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED],
    265                   20, 128);
    266        sum -= c[DIAG_DOWN_LEFT_PRED];
    267        adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
    268        sum -= c[VERT_LEFT_PRED];
    269        adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
    270        adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
    271    }
    272 }