Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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 | |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 24 | #include "vp9.h" |
Ronald S. Bultje | f8c0199 | 2017-03-27 20:47:46 | [diff] [blame] | 25 | #include "vp9dec.h" |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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]; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 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]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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++) |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 78 | adapt_prob(&p->skip[i], s->td[0].counts.skip[i][0], |
| 79 | s->td[0].counts.skip[i][1], 20, 128); |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 80 | |
| 81 | // intra/inter flag |
| 82 | for (i = 0; i < 4; i++) |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 83 | adapt_prob(&p->intra[i], s->td[0].counts.intra[i][0], |
| 84 | s->td[0].counts.intra[i][1], 20, 128); |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 85 | |
| 86 | // comppred flag |
| 87 | if (s->s.h.comppredmode == PRED_SWITCHABLE) { |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 88 | for (i = 0; i < 5; i++) |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 89 | adapt_prob(&p->comp[i], s->td[0].counts.comp[i][0], |
| 90 | s->td[0].counts.comp[i][1], 20, 128); |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 91 | } |
| 92 | |
| 93 | // reference frames |
| 94 | if (s->s.h.comppredmode != PRED_SINGLEREF) { |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 95 | for (i = 0; i < 5; i++) |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 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); |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | if (s->s.h.comppredmode != PRED_COMPREF) { |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 101 | for (i = 0; i < 5; i++) { |
| 102 | uint8_t *pp = p->single_ref[i]; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 103 | unsigned (*c)[2] = s->td[0].counts.single_ref[i]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 104 | |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 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 | } |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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]; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 114 | unsigned *c = s->td[0].counts.partition[i][j]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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) { |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 123 | for (i = 0; i < 2; i++) { |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 124 | unsigned *c16 = s->td[0].counts.tx16p[i], *c32 = s->td[0].counts.tx32p[i]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 125 | |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 126 | adapt_prob(&p->tx8p[i], s->td[0].counts.tx8p[i][0], |
| 127 | s->td[0].counts.tx8p[i][1], 20, 128); |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 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 | } |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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]; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 140 | unsigned *c = s->td[0].counts.filter[i]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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]; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 150 | unsigned *c = s->td[0].counts.mv_mode[i]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 160 | unsigned *c = s->td[0].counts.mv_joint; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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 | |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 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); |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 174 | |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 175 | pp = p->mv_comp[i].classes; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 176 | c = s->td[0].counts.mv_comp[i].classes; |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 177 | sum = c[1] + c[2] + c[3] + c[4] + c[5] + |
| 178 | c[6] + c[7] + c[8] + c[9] + c[10]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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 | |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 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); |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 196 | pp = p->mv_comp[i].bits; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 197 | c2 = s->td[0].counts.mv_comp[i].bits; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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]; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 203 | c = s->td[0].counts.mv_comp[i].class0_fp[j]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 209 | c = s->td[0].counts.mv_comp[i].fp; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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) { |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 215 | adapt_prob(&p->mv_comp[i].class0_hp, |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 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); |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 220 | } |
| 221 | } |
| 222 | |
| 223 | // y intra modes |
| 224 | for (i = 0; i < 4; i++) { |
| 225 | uint8_t *pp = p->y_mode[i]; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 226 | unsigned *c = s->td[0].counts.y_mode[i], sum, s2; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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); |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 234 | s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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); |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 239 | adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], |
| 240 | 20, 128); |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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]; |
Ilia Valiakhmetov | e59da0f | 2017-09-07 21:02:49 | [diff] [blame] | 251 | unsigned *c = s->td[0].counts.uv_mode[i], sum, s2; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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); |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 259 | s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED]; |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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); |
Clément Bœsch | 875f695 | 2017-03-25 11:40:48 | [diff] [blame] | 264 | adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], |
| 265 | 20, 128); |
Clément Bœsch | 1c9f4b5 | 2017-03-25 11:10:13 | [diff] [blame] | 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 | } |