Coverage Report

Created: 2026-05-16 07:49

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