Coverage Report

Created: 2026-09-01 06:54

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
104M
#define MIN_DELP_BITS 5
34
35
287M
static int recenter_nonneg(int v, int m) {
36
287M
  if (v > (m << 1))
37
76.9M
    return v;
38
210M
  else if (v >= m)
39
95.1M
    return ((v - m) << 1);
40
115M
  else
41
115M
    return ((m - v) << 1) - 1;
42
287M
}
43
44
287M
static int remap_prob(int v, int m) {
45
287M
  int i;
46
287M
  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
287M
    20,  21,  22,  23,  24,  25,  0,   26,  27,  28,  29,  30,  31,  32,  33,
50
287M
    34,  35,  36,  37,  1,   38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
51
287M
    48,  49,  2,   50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,
52
287M
    3,   62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  4,   74,
53
287M
    75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  5,   86,  87,  88,
54
287M
    89,  90,  91,  92,  93,  94,  95,  96,  97,  6,   98,  99,  100, 101, 102,
55
287M
    103, 104, 105, 106, 107, 108, 109, 7,   110, 111, 112, 113, 114, 115, 116,
56
287M
    117, 118, 119, 120, 121, 8,   122, 123, 124, 125, 126, 127, 128, 129, 130,
57
287M
    131, 132, 133, 9,   134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
58
287M
    145, 10,  146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 11,
59
287M
    158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 12,  170, 171,
60
287M
    172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 13,  182, 183, 184, 185,
61
287M
    186, 187, 188, 189, 190, 191, 192, 193, 14,  194, 195, 196, 197, 198, 199,
62
287M
    200, 201, 202, 203, 204, 205, 15,  206, 207, 208, 209, 210, 211, 212, 213,
63
287M
    214, 215, 216, 217, 16,  218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
64
287M
    228, 229, 17,  230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241,
65
287M
    18,  242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 19,
66
287M
  };
67
287M
  v--;
68
287M
  m--;
69
287M
  assert(m >= 0);
70
287M
  if ((m << 1) <= MAX_PROB)
71
130M
    i = recenter_nonneg(v, m) - 1;
72
156M
  else
73
156M
    i = recenter_nonneg(MAX_PROB - 1 - v, MAX_PROB - 1 - m) - 1;
74
75
287M
  assert(i >= 0 && (size_t)i < sizeof(map_table));
76
287M
  i = map_table[i];
77
287M
  return i;
78
287M
}
79
80
285M
static int prob_diff_update_cost(vpx_prob newp, vpx_prob oldp) {
81
285M
  int delp = remap_prob(newp, oldp);
82
285M
  return update_bits[delp] << VP9_PROB_COST_SHIFT;
83
285M
}
84
85
331k
static void encode_uniform(vpx_writer *w, int v) {
86
331k
  const int l = 8;
87
331k
  const int m = (1 << l) - 191;
88
331k
  if (v < m) {
89
138k
    vpx_write_literal(w, v, l - 1);
90
193k
  } else {
91
193k
    vpx_write_literal(w, m + ((v - m) >> 1), l - 1);
92
193k
    vpx_write_literal(w, (v - m) & 1, 1);
93
193k
  }
94
331k
}
95
96
2.91M
static INLINE int write_bit_gte(vpx_writer *w, int word, int test) {
97
2.91M
  vpx_write_literal(w, word >= test, 1);
98
2.91M
  return word >= test;
99
2.91M
}
100
101
1.77M
static void encode_term_subexp(vpx_writer *w, int word) {
102
1.77M
  if (!write_bit_gte(w, word, 16)) {
103
1.05M
    vpx_write_literal(w, word, 4);
104
1.05M
  } else if (!write_bit_gte(w, word, 32)) {
105
281k
    vpx_write_literal(w, word - 16, 4);
106
431k
  } else if (!write_bit_gte(w, word, 64)) {
107
99.4k
    vpx_write_literal(w, word - 32, 5);
108
331k
  } else {
109
331k
    encode_uniform(w, word - 64);
110
331k
  }
111
1.77M
}
112
113
1.77M
void vp9_write_prob_diff_update(vpx_writer *w, vpx_prob newp, vpx_prob oldp) {
114
1.77M
  const int delp = remap_prob(newp, oldp);
115
1.77M
  encode_term_subexp(w, delp);
116
1.77M
}
117
118
int64_t vp9_prob_diff_update_savings_search(const unsigned int *ct,
119
                                            vpx_prob oldp, vpx_prob *bestp,
120
87.7M
                                            vpx_prob upd) {
121
87.7M
  const int64_t old_b = cost_branch256(ct, oldp);
122
87.7M
  int64_t bestsavings = 0;
123
87.7M
  vpx_prob newp, bestnewp = oldp;
124
87.7M
  const int step = *bestp > oldp ? -1 : 1;
125
87.7M
  const int upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd);
126
127
87.7M
  if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) {
128
162M
    for (newp = *bestp; newp != oldp; newp += step) {
129
159M
      const int64_t new_b = cost_branch256(ct, newp);
130
159M
      const int64_t update_b = prob_diff_update_cost(newp, oldp) + upd_cost;
131
159M
      const int64_t savings = old_b - new_b - update_b;
132
159M
      if (savings > bestsavings) {
133
1.48M
        bestsavings = savings;
134
1.48M
        bestnewp = newp;
135
1.48M
      }
136
159M
    }
137
3.18M
  }
138
87.7M
  *bestp = bestnewp;
139
87.7M
  return bestsavings;
140
87.7M
}
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
16.4M
                                                  int stepsize) {
146
16.4M
  int64_t i, old_b, new_b, update_b, savings, bestsavings;
147
16.4M
  int64_t newp;
148
16.4M
  const int64_t step_sign = *bestp > oldp ? -1 : 1;
149
16.4M
  const int64_t step = stepsize * step_sign;
150
16.4M
  const int64_t upd_cost = vp9_cost_one(upd) - vp9_cost_zero(upd);
151
16.4M
  const vpx_prob *newplist, *oldplist;
152
16.4M
  vpx_prob bestnewp;
153
16.4M
  oldplist = vp9_pareto8_full[oldp - 1];
154
16.4M
  old_b = cost_branch256(ct + 2 * PIVOT_NODE, oldp);
155
147M
  for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i)
156
131M
    old_b += cost_branch256(ct + 2 * i, oldplist[i - UNCONSTRAINED_NODES]);
157
158
16.4M
  bestsavings = 0;
159
16.4M
  bestnewp = oldp;
160
161
16.4M
  assert(stepsize > 0);
162
163
16.4M
  if (old_b > upd_cost + (MIN_DELP_BITS << VP9_PROB_COST_SHIFT)) {
164
128M
    for (newp = *bestp; (newp - oldp) * step_sign < 0; newp += step) {
165
125M
      if (newp < 1 || newp > 255) continue;
166
125M
      newplist = vp9_pareto8_full[newp - 1];
167
125M
      new_b = cost_branch256(ct + 2 * PIVOT_NODE, (vpx_prob)newp);
168
1.13G
      for (i = UNCONSTRAINED_NODES; i < ENTROPY_NODES; ++i)
169
1.00G
        new_b += cost_branch256(ct + 2 * i, newplist[i - UNCONSTRAINED_NODES]);
170
125M
      update_b = prob_diff_update_cost((vpx_prob)newp, oldp) + upd_cost;
171
125M
      savings = old_b - new_b - update_b;
172
125M
      if (savings > bestsavings) {
173
4.53M
        bestsavings = savings;
174
4.53M
        bestnewp = (vpx_prob)newp;
175
4.53M
      }
176
125M
    }
177
2.98M
  }
178
179
16.4M
  *bestp = bestnewp;
180
16.4M
  return bestsavings;
181
16.4M
}
182
183
void vp9_cond_prob_diff_update(vpx_writer *w, vpx_prob *oldp,
184
54.9M
                               const unsigned int ct[2]) {
185
54.9M
  const vpx_prob upd = DIFF_UPDATE_PROB;
186
54.9M
  vpx_prob newp = get_binary_prob(ct[0], ct[1]);
187
54.9M
  const int64_t savings =
188
54.9M
      vp9_prob_diff_update_savings_search(ct, *oldp, &newp, upd);
189
54.9M
  assert(newp >= 1);
190
54.9M
  if (savings > 0) {
191
88.9k
    vpx_write(w, 1, upd);
192
88.9k
    vp9_write_prob_diff_update(w, newp, *oldp);
193
88.9k
    *oldp = newp;
194
54.8M
  } else {
195
54.8M
    vpx_write(w, 0, upd);
196
54.8M
  }
197
54.9M
}