Coverage Report

Created: 2026-09-14 08:00

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