Coverage Report

Created: 2025-11-16 07:20

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