Coverage Report

Created: 2026-04-01 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvpx/vp9/encoder/vp9_subexp.c
Line
Count
Source
1
/*
2
 *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
 *  that can be found in the LICENSE file in the root of the source
6
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
9
 */
10
#include "vpx_dsp/bitwriter.h"
11
12
#include "vp9/common/vp9_common.h"
13
#include "vp9/common/vp9_entropy.h"
14
#include "vp9/encoder/vp9_cost.h"
15
#include "vp9/encoder/vp9_subexp.h"
16
17
static const uint8_t update_bits[255] = {
18
  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,
19
  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  8,  8,  8,  8,  8,  8,
20
  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
21
  8,  8,  8,  8,  8,  8,  8,  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
22
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
23
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
24
  10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11,
25
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
26
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
27
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
28
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
29
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
30
  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
31
  11, 11, 11, 11, 11, 11, 11, 0,
32
};
33
31.4M
#define MIN_DELP_BITS 5
34
35
201M
static int recenter_nonneg(int v, int m) {
36
201M
  if (v > (m << 1))
37
54.6M
    return v;
38
146M
  else if (v >= m)
39
69.0M
    return ((v - m) << 1);
40
77.4M
  else
41
77.4M
    return ((m - v) << 1) - 1;
42
201M
}
43
44
201M
static int remap_prob(int v, int m) {
45
201M
  int i;
46
201M
  static const uint8_t map_table[MAX_PROB - 1] = {
47
    // generated by:
48
    //   map_table[j] = split_index(j, MAX_PROB - 1, MODULUS_PARAM);
49
201M
    20,  21,  22,  23,  24,  25,  0,   26,  27,  28,  29,  30,  31,  32,  33,
50
201M
    34,  35,  36,  37,  1,   38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
51
201M
    48,  49,  2,   50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,
52
201M
    3,   62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  4,   74,
53
201M
    75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  5,   86,  87,  88,
54
201M
    89,  90,  91,  92,  93,  94,  95,  96,  97,  6,   98,  99,  100, 101, 102,
55
201M
    103, 104, 105, 106, 107, 108, 109, 7,   110, 111, 112, 113, 114, 115, 116,
56
201M
    117, 118, 119, 120, 121, 8,   122, 123, 124, 125, 126, 127, 128, 129, 130,
57
201M
    131, 132, 133, 9,   134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
58
201M
    145, 10,  146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 11,
59
201M
    158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 12,  170, 171,
60
201M
    172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 13,  182, 183, 184, 185,
61
201M
    186, 187, 188, 189, 190, 191, 192, 193, 14,  194, 195, 196, 197, 198, 199,
62
201M
    200, 201, 202, 203, 204, 205, 15,  206, 207, 208, 209, 210, 211, 212, 213,
63
201M
    214, 215, 216, 217, 16,  218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
64
201M
    228, 229, 17,  230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
65
201M
    18,  242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19,
66
201M
  };
67
201M
  v--;
68
201M
  m--;
69
201M
  assert(m >= 0);
70
201M
  if ((m << 1) <= MAX_PROB)
71
113M
    i = recenter_nonneg(v, m) - 1;
72
87.2M
  else
73
87.2M
    i = recenter_nonneg(MAX_PROB - 1 - v, MAX_PROB - 1 - m) - 1;
74
75
201M
  assert(i >= 0 && (size_t)i < sizeof(map_table));
76
201M
  i = map_table[i];
77
201M
  return i;
78
201M
}
79
80
200M
static int prob_diff_update_cost(vpx_prob newp, vpx_prob oldp) {
81
200M
  int delp = remap_prob(newp, oldp);
82
200M
  return update_bits[delp] << VP9_PROB_COST_SHIFT;
83
200M
}
84
85
44.2k
static void encode_uniform(vpx_writer *w, int v) {
86
44.2k
  const int l = 8;
87
44.2k
  const int m = (1 << l) - 191;
88
44.2k
  if (v < m) {
89
19.5k
    vpx_write_literal(w, v, l - 1);
90
24.7k
  } else {
91
24.7k
    vpx_write_literal(w, m + ((v - m) >> 1), l - 1);
92
24.7k
    vpx_write_literal(w, (v - m) & 1, 1);
93
24.7k
  }
94
44.2k
}
95
96
820k
static INLINE int write_bit_gte(vpx_writer *w, int word, int test) {
97
820k
  vpx_write_literal(w, word >= test, 1);
98
820k
  return word >= test;
99
820k
}
100
101
559k
static void encode_term_subexp(vpx_writer *w, int word) {
102
559k
  if (!write_bit_gte(w, word, 16)) {
103
376k
    vpx_write_literal(w, word, 4);
104
376k
  } else if (!write_bit_gte(w, word, 32)) {
105
103k
    vpx_write_literal(w, word - 16, 4);
106
103k
  } else if (!write_bit_gte(w, word, 64)) {
107
34.6k
    vpx_write_literal(w, word - 32, 5);
108
44.2k
  } else {
109
44.2k
    encode_uniform(w, word - 64);
110
44.2k
  }
111
559k
}
112
113
559k
void vp9_write_prob_diff_update(vpx_writer *w, vpx_prob newp, vpx_prob oldp) {
114
559k
  const int delp = remap_prob(newp, oldp);
115
559k
  encode_term_subexp(w, delp);
116
559k
}
117
118
int64_t vp9_prob_diff_update_savings_search(const unsigned int *ct,
119
                                            vpx_prob oldp, vpx_prob *bestp,
120
23.3M
                                            vpx_prob upd) {
121
23.3M
  const int64_t old_b = cost_branch256(ct, oldp);
122
23.3M
  int64_t bestsavings = 0;
123
23.3M
  vpx_prob newp, bestnewp = oldp;
124
23.3M
  const int step = *bestp > oldp ? -1 : 1;
125
23.3M
  const int upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd);
126
127
23.3M
  if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) {
128
88.8M
    for (newp = *bestp; newp != oldp; newp += step) {
129
86.6M
      const int64_t new_b = cost_branch256(ct, newp);
130
86.6M
      const int64_t update_b = prob_diff_update_cost(newp, oldp) + upd_cost;
131
86.6M
      const int64_t savings = old_b - new_b - update_b;
132
86.6M
      if (savings > bestsavings) {
133
737k
        bestsavings = savings;
134
737k
        bestnewp = newp;
135
737k
      }
136
86.6M
    }
137
2.19M
  }
138
23.3M
  *bestp = bestnewp;
139
23.3M
  return bestsavings;
140
23.3M
}
141
142
int64_t vp9_prob_diff_update_savings_search_model(const unsigned int *ct,
143
                                                  const vpx_prob oldp,
144
                                                  vpx_prob *bestp, vpx_prob upd,
145
8.08M
                                                  int stepsize) {
146
8.08M
  int64_t i, old_b, new_b, update_b, savings, bestsavings;
147
8.08M
  int64_t newp;
148
8.08M
  const int64_t step_sign = *bestp > oldp ? -1 : 1;
149
8.08M
  const int64_t step = stepsize * step_sign;
150
8.08M
  const int64_t upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd);
151
8.08M
  const vpx_prob *newplist, *oldplist;
152
8.08M
  vpx_prob bestnewp;
153
8.08M
  oldplist = vp9_pareto8_full[oldp - 1];
154
8.08M
  old_b = cost_branch256(ct + 2 * PIVOT_NODE, oldp);
155
72.7M
  for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i)
156
64.6M
    old_b += cost_branch256(ct + 2 * i, oldplist[i - UNCONSTRAINED_NODES]);
157
158
8.08M
  bestsavings = 0;
159
8.08M
  bestnewp = oldp;
160
161
8.08M
  assert(stepsize > 0);
162
163
8.08M
  if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) {
164
116M
    for (newp = *bestp; (newp - oldp) * step_sign < 0; newp += step) {
165
113M
      if (newp < 1 || newp > 255) continue;
166
113M
      newplist = vp9_pareto8_full[newp - 1];
167
113M
      new_b = cost_branch256(ct + 2 * PIVOT_NODE, (vpx_prob)newp);
168
1.02G
      for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i)
169
911M
        new_b += cost_branch256(ct + 2 * i, newplist[i - UNCONSTRAINED_NODES]);
170
113M
      update_b = prob_diff_update_cost((vpx_prob)newp, oldp) + upd_cost;
171
113M
      savings = old_b - new_b - update_b;
172
113M
      if (savings > bestsavings) {
173
2.93M
        bestsavings = savings;
174
2.93M
        bestnewp = (vpx_prob)newp;
175
2.93M
      }
176
113M
    }
177
2.24M
  }
178
179
8.08M
  *bestp = bestnewp;
180
8.08M
  return bestsavings;
181
8.08M
}
182
183
void vp9_cond_prob_diff_update(vpx_writer *w, vpx_prob *oldp,
184
7.17M
                               const unsigned int ct[2]) {
185
7.17M
  const vpx_prob upd = DIFF_UPDATE_PROB;
186
7.17M
  vpx_prob newp = get_binary_prob(ct[0], ct[1]);
187
7.17M
  const int64_t savings =
188
7.17M
      vp9_prob_diff_update_savings_search(ct, *oldp, &newp, upd);
189
7.17M
  assert(newp >= 1);
190
7.17M
  if (savings > 0) {
191
29.0k
    vpx_write(w, 1, upd);
192
29.0k
    vp9_write_prob_diff_update(w, newp, *oldp);
193
29.0k
    *oldp = newp;
194
7.15M
  } else {
195
7.15M
    vpx_write(w, 0, upd);
196
7.15M
  }
197
7.17M
}