Coverage Report

Created: 2026-07-30 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/bitstream_unit.c
Line
Count
Source
1
/*
2
* Copyright(c) 2019 Intel Corporation
3
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
4
*
5
* This source code is subject to the terms of the BSD 2 Clause License and
6
* the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
7
* was not distributed with this source code in the LICENSE file, you can
8
* obtain it at https://www.aomedia.org/license/software-license. If the Alliance for Open
9
* Media Patent License 1.0 was not distributed with this source code in the
10
* PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
11
*/
12
13
#include <stdlib.h>
14
15
#include "bitstream_unit.h"
16
#include "definitions.h"
17
#include "utility.h"
18
#include "svt_log.h"
19
20
#if OD_MEASURE_EC_OVERHEAD
21
#include <stdio.h>
22
#endif
23
24
7.70k
static void output_bitstream_unit_dctor(EbPtr p) {
25
7.70k
    OutputBitstreamUnit* obj = (OutputBitstreamUnit*)p;
26
7.70k
    EB_FREE_ARRAY(obj->buffer_begin_av1);
27
7.70k
}
28
29
/**********************************
30
 * Constructor
31
 **********************************/
32
7.70k
EbErrorType svt_aom_output_bitstream_unit_ctor(OutputBitstreamUnit* bitstream_ptr, uint32_t buffer_size) {
33
7.70k
    bitstream_ptr->dctor = output_bitstream_unit_dctor;
34
7.70k
    if (buffer_size) {
35
7.70k
        bitstream_ptr->size = buffer_size;
36
7.70k
        EB_MALLOC_ARRAY(bitstream_ptr->buffer_begin_av1, bitstream_ptr->size);
37
7.70k
        bitstream_ptr->buffer_av1 = bitstream_ptr->buffer_begin_av1;
38
7.70k
    } else {
39
0
        bitstream_ptr->size             = 0;
40
0
        bitstream_ptr->buffer_begin_av1 = 0;
41
0
        bitstream_ptr->buffer_av1       = 0;
42
0
    }
43
44
7.70k
    return EB_ErrorNone;
45
7.70k
}
46
47
/**********************************
48
 * Reset Bitstream
49
 **********************************/
50
485
EbErrorType svt_aom_output_bitstream_reset(OutputBitstreamUnit* bitstream_ptr) {
51
485
    EbErrorType return_error = EB_ErrorNone;
52
53
    // Reset the write ptr to the beginning of the buffer
54
485
    bitstream_ptr->buffer_av1 = bitstream_ptr->buffer_begin_av1;
55
56
485
    return return_error;
57
485
}
58
59
/********************************************************************************************************************************/
60
/********************************************************************************************************************************/
61
/********************************************************************************************************************************/
62
/********************************************************************************************************************************/
63
/* Realloc when bitstream pointer size is not enough to write data of size sz */
64
6.50k
EbErrorType svt_realloc_output_bitstream_unit(OutputBitstreamUnit* output_bitstream_ptr, uint32_t sz) {
65
6.50k
    if (output_bitstream_ptr && sz > 0) {
66
        // Must add offset to realloc'd buffer to save any previously written bits
67
6.50k
        uint64_t offset = output_bitstream_ptr->buffer_av1 - output_bitstream_ptr->buffer_begin_av1;
68
6.50k
        assert(output_bitstream_ptr->buffer_av1 >= output_bitstream_ptr->buffer_begin_av1);
69
6.50k
        output_bitstream_ptr->size = sz;
70
6.50k
        EB_REALLOC_ARRAY(output_bitstream_ptr->buffer_begin_av1, output_bitstream_ptr->size);
71
6.50k
        output_bitstream_ptr->buffer_av1 = output_bitstream_ptr->buffer_begin_av1 + offset;
72
6.50k
    }
73
6.50k
    return EB_ErrorNone;
74
6.50k
}
75
76
// ptr points one past the last written byte; propagate carry backward
77
4.77k
static inline void propagate_carry_bwd(unsigned char* ptr) {
78
4.79k
    while (!++*--ptr) {}
79
4.77k
}
80
81
/*A range encoder.
82
  See entdec.c and the references for implementation details \cite{Mar79,MNW98}.
83
84
  @INPROCEEDINGS{Mar79,
85
   author="Martin, G.N.N.",
86
   title="Range encoding: an algorithm for removing redundancy from a digitised
87
    message",
88
   booktitle="Video \& Data Recording Conference",
89
   year=1979,
90
   address="Southampton",
91
   month=Jul,
92
   URL="http://www.compressconsult.com/rangecoder/rngcod.pdf.gz"
93
  }
94
  @ARTICLE{MNW98,
95
   author="Alistair Moffat and Radford Neal and Ian H. Witten",
96
   title="Arithmetic Coding Revisited",
97
   journal="{ACM} Transactions on Information Systems",
98
   year=1998,
99
   volume=16,
100
   number=3,
101
   pages="256--294",
102
   month=Jul,
103
   URL="http://researchcommons.waikato.ac.nz/bitstream/handle/10289/78/content.pdf"
104
  }*/
105
106
/*Flush accumulated bytes from the arithmetic coder to the output buffer.
107
  This is the cold path of normalize, kept out-of-line to reduce icache
108
  pressure on the hot (no-flush) path.
109
  Returns the residual low value after flushing.*/
110
14.5k
static NOINLINE void od_ec_enc_flush(OdEcEnc* enc, OdEcWindow low, unsigned rng, int c, int d) {
111
    // Need to add 1 byte here since enc->cnt always counts 1 byte less
112
    // (enc->cnt = -9) to ensure correct operation
113
14.5k
    int s              = c + d;
114
14.5k
    int num_bits_ready = (s & ~7) + 8;
115
116
    // Update "c" to contain the number of non-ready bits in "low". Since "low"
117
    // has 64-bit capacity, we need to add the (64 - 40) cushion bits and take
118
    // off the number of ready bits.
119
14.5k
    c += 24 - num_bits_ready;
120
121
    // Extract ready bits from low
122
14.5k
    uint64_t output = low >> c;
123
124
    // Separate carry bit from data
125
14.5k
    uint64_t mask = (uint64_t)1 << num_bits_ready;
126
127
14.5k
    if (output & mask) {
128
2.85k
        assert(enc->ptr > enc->buf);
129
2.85k
        propagate_carry_bwd(enc->ptr);
130
2.85k
    }
131
132
    // Write to buffer. Carry bit will be shifted away, no need to mask
133
    // output &= mask - 1;
134
14.5k
    const uint64_t reg = HToBE64(output << (64 - num_bits_ready));
135
14.5k
    memcpy(enc->ptr, &reg, 8);
136
137
14.5k
    enc->ptr += num_bits_ready >> 3;
138
139
14.5k
    low &= (((uint64_t)1 << c) - 1);
140
141
14.5k
    enc->low = low << d;
142
14.5k
    enc->rng = rng << d;
143
14.5k
    enc->cnt = (s & 7) - 8;
144
14.5k
}
145
146
/*Takes updated low and range values, renormalizes them so that
147
     32768 <= rng < 65536 (flushing bytes from low to the output buffer if
148
     necessary), and stores them back in the encoder context.
149
    low: The new value of low.
150
    rng: The new value of the range.*/
151
993k
static inline void svt_od_ec_enc_normalize(OdEcEnc* enc, OdEcWindow low, unsigned rng) {
152
993k
    int c = enc->cnt;
153
993k
    assert(rng <= 65535U);
154
    /*The number of leading zeros in the 16-bit binary representation of rng.*/
155
993k
    int d = 15 - svt_log2f(rng);
156
157
    /* We flush every time "low" cannot safely and efficiently accommodate any
158
       more data. Overall, c must not exceed 63 at the time of byte flush out. To
159
       facilitate this, "c+d" cannot exceed 56-bits because we have to keep 1 byte
160
       for carry. Also, we need to subtract 16 because we want to keep room for
161
       the next symbol worth "d"-bits (max 15). An alternate condition would be if
162
       (e < d), where e = number of leading zeros in "low", indicating there is
163
       not enough rooom to accommodate "rng" worth of "d"-bits in "low". However,
164
       this approach needs additional computations: (i) compute "e", (ii) push
165
       the leading 0x00's as a special case.
166
    */
167
993k
    if (EB_UNLIKELY(c + d >= 40)) { // 56 - 16
168
14.5k
        od_ec_enc_flush(enc, low, rng, c, d);
169
978k
    } else {
170
978k
        enc->low = low << d;
171
978k
        enc->rng = rng << d;
172
978k
        enc->cnt = c + d;
173
978k
    }
174
993k
}
175
176
/*Initializes the encoder.
177
  The EC does not own a buffer; it borrows one from the OutputBitstreamUnit
178
  via aom_start_encode(). This just zeroes the state.*/
179
5.28k
void svt_od_ec_enc_init(OdEcEnc* enc) {
180
5.28k
    enc->buf = NULL;
181
5.28k
    svt_od_ec_enc_reset(enc);
182
5.28k
}
183
184
/*Reinitializes the encoder.*/
185
10.5k
void svt_od_ec_enc_reset(OdEcEnc* enc) {
186
10.5k
    enc->ptr = enc->buf;
187
10.5k
    enc->low = 0;
188
10.5k
    enc->rng = 0x8000;
189
    /*This is initialized to -9 so that it crosses zero after we've accumulated
190
       one byte + one carry bit.*/
191
10.5k
    enc->cnt   = -9;
192
10.5k
    enc->error = 0;
193
#if OD_MEASURE_EC_OVERHEAD
194
    enc->entropy    = 0;
195
    enc->nb_symbols = 0;
196
#endif
197
10.5k
}
198
199
/*Frees the buffers used by the encoder.*/
200
0
void svt_od_ec_enc_clear(OdEcEnc* enc) {
201
    // EC borrows its buffer from OutputBitstreamUnit; nothing to free.
202
0
    enc->buf = NULL;
203
0
    enc->ptr = NULL;
204
0
}
205
206
/*Ensures the EC buffer has at least min_free bytes of free space.
207
  Reallocs through the AomWriter's buffer_parent (OutputBitstreamUnit)
208
  since EC borrows that buffer.  Should be called before encoding each SB
209
  to move capacity checks out of the per-symbol hot path.*/
210
6.59k
EbErrorType svt_aom_ec_ensure_capacity(AomWriter* w, uint32_t min_free) {
211
6.59k
    EbErrorType          ret    = EB_ErrorNone;
212
6.59k
    OutputBitstreamUnit* parent = w->buffer_parent;
213
6.59k
    OdEcEnc*             enc    = &w->ec;
214
6.59k
    uint32_t             offs   = (uint32_t)(enc->ptr - enc->buf);
215
6.59k
    uint32_t             needed = offs + min_free;
216
6.59k
    if (needed > parent->size) {
217
        // Realloc through the OutputBitstreamUnit that owns the buffer
218
6.50k
        ret = svt_realloc_output_bitstream_unit(parent, needed);
219
6.50k
        if (ret != EB_ErrorNone) {
220
0
            enc->error = -1;
221
6.50k
        } else {
222
            // Update EC's borrowed pointers
223
6.50k
            enc->buf = parent->buffer_begin_av1;
224
6.50k
            enc->ptr = enc->buf + offs;
225
6.50k
        }
226
6.50k
    }
227
6.59k
    return ret;
228
6.59k
}
229
230
/*Encode a single binary value with 1/2 probability.
231
  val: The value to encode (0 or 1).*/
232
220k
void svt_od_ec_encode_bool_eq_q15(OdEcEnc* enc, int val) {
233
220k
    OdEcWindow l = enc->low;
234
220k
    uint32_t   r = enc->rng;
235
220k
    assert(32768U <= r);
236
220k
    uint32_t v = ((r >> 8) << (CDF_PROB_BITS - 1 - 7)) + EC_MIN_PROB;
237
220k
    r -= v;
238
220k
    if (val) {
239
71.6k
        l += r;
240
71.6k
        r = v;
241
71.6k
    }
242
220k
    svt_od_ec_enc_normalize(enc, l, r);
243
#if OD_MEASURE_EC_OVERHEAD
244
    enc->entropy -= OD_LOG2((double)(val ? f : (32768 - f)) / 32768.);
245
    enc->nb_symbols++;
246
#endif
247
220k
}
248
249
/*Encode a single binary value.
250
  val: The value to encode (0 or 1).
251
  f: The probability that the val is one, scaled by 32768.*/
252
198k
void svt_od_ec_encode_bool_q15(OdEcEnc* enc, int val, uint32_t f) {
253
198k
    assert(f < 32768U);
254
198k
    OdEcWindow l = enc->low;
255
198k
    uint32_t   r = enc->rng;
256
198k
    assert(32768U <= r);
257
198k
    EB_ASSUME(f <= 32768);
258
198k
    uint32_t v = ((r >> 8) * (f >> EC_PROB_SHIFT) >> (7 - EC_PROB_SHIFT)) + EC_MIN_PROB;
259
198k
    r -= v;
260
198k
    if (val) {
261
171k
        l += r;
262
171k
        r = v;
263
171k
    }
264
198k
    svt_od_ec_enc_normalize(enc, l, r);
265
#if OD_MEASURE_EC_OVERHEAD
266
    enc->entropy -= OD_LOG2((double)(val ? f : (32768 - f)) / 32768.);
267
    enc->nb_symbols++;
268
#endif
269
198k
}
270
271
/*Encodes a symbol given a cumulative distribution function (CDF) table in Q15.
272
  s: The index of the symbol to encode.
273
  icdf: 32768 minus the CDF, such that symbol s falls in the range
274
         [s > 0 ? (32768 - icdf[s - 1]) : 0, 32768 - icdf[s]).
275
        The values must be monotonically decreasing, and icdf[nsyms - 1] must
276
         be 0.
277
  nsyms: The number of symbols in the alphabet.
278
         This should be at most 16.*/
279
575k
void svt_od_ec_encode_cdf_q15(OdEcEnc* enc, int s, const uint16_t* icdf, int nsyms) {
280
575k
    assert(s >= 0);
281
575k
    assert(s < nsyms);
282
575k
    assert(icdf[nsyms - 1] == OD_ICDF(CDF_PROB_TOP));
283
284
575k
    OdEcWindow l = enc->low;
285
575k
    uint32_t   r = enc->rng;
286
575k
    assert(32768U <= r);
287
575k
    assert(7 - EC_PROB_SHIFT >= 0);
288
575k
    const uint32_t r_hi = r >> 8;
289
575k
    const uint32_t temp = EC_MIN_PROB * (nsyms - 1 - s);
290
575k
    if (0 < s) {
291
121k
        uint32_t u = (r_hi * (icdf[s - 1] >> EC_PROB_SHIFT) >> (7 - EC_PROB_SHIFT)) + temp + EC_MIN_PROB;
292
121k
        l += r - u;
293
121k
        r = u;
294
121k
    }
295
575k
    r -= (r_hi * (icdf[s] >> EC_PROB_SHIFT) >> (7 - EC_PROB_SHIFT)) + temp;
296
575k
    svt_od_ec_enc_normalize(enc, l, r);
297
#if OD_MEASURE_EC_OVERHEAD
298
    enc->entropy -= OD_LOG2((double)(OD_ICDF(fh) - OD_ICDF(fl)) / CDF_PROB_TOP.);
299
    enc->nb_symbols++;
300
#endif
301
575k
}
302
303
/*Indicates that there are no more symbols to encode.
304
  All remaining output bytes are flushed to the output buffer.
305
  od_ec_enc_reset() should be called before using the encoder again.
306
  bytes: Returns the size of the encoded data in the returned buffer.
307
  Return: A pointer to the start of the final buffer, or NULL if there was an
308
           encoding error.*/
309
5.28k
unsigned char* svt_od_ec_enc_done(OdEcEnc* enc, uint32_t* nbytes) {
310
5.28k
    if (enc->error) {
311
0
        return NULL;
312
0
    }
313
#if OD_MEASURE_EC_OVERHEAD
314
    {
315
        uint32_t tell;
316
        /* Don't count the 1 bit we lose to raw bits as overhead. */
317
        tell = od_ec_enc_tell(enc) - 1;
318
        fprintf(stderr, "overhead: %f%%\n", 100 * (tell - enc->entropy) / enc->entropy);
319
        fprintf(stderr, "efficiency: %f bits/symbol\n", (double)tell / enc->nb_symbols);
320
    }
321
#endif
322
323
5.28k
    int c = enc->cnt;
324
325
    /*We output the minimum number of bits that ensures that the symbols encoded
326
       thus far will be decoded correctly regardless of the bits that follow.*/
327
5.28k
    OdEcWindow m = 0x3FFF;
328
5.28k
    OdEcWindow e = ((enc->low + m) & ~m) | (m + 1);
329
5.28k
    OdEcWindow v = e >> (c + 16);
330
5.28k
    if (v & 0x0100) {
331
1.91k
        assert(enc->ptr > enc->buf);
332
1.91k
        propagate_carry_bwd(enc->ptr);
333
1.91k
    }
334
21.5k
    do {
335
21.5k
        *enc->ptr++ = (unsigned char)((e >> (c + 16)) & 0xFF);
336
337
21.5k
        c -= 8;
338
21.5k
    } while (10 + c > 0);
339
340
5.28k
    *nbytes = (uint32_t)(enc->ptr - enc->buf);
341
342
5.28k
    return enc->buf;
343
5.28k
}
344
345
/*Returns the number of bits "used" by the encoded symbols so far.
346
  This same number can be computed in either the encoder or the decoder, and is
347
   suitable for making coding decisions.
348
  Warning: The value returned by this function can decrease compared to an
349
   earlier call, even after encoding more data, if there is an encoding error
350
   (i.e., a failure to allocate enough space for the output buffer).
351
  Return: The number of bits.
352
          This will always be slightly larger than the exact value (e.g., all
353
           rounding error is in the positive direction).*/
354
0
int svt_od_ec_enc_tell(const OdEcEnc* enc) {
355
    /*The 10 here counteracts the offset of -9 baked into cnt, and adds 1 extra
356
       bit, which we reserve for terminating the stream.*/
357
0
    return (enc->cnt + 10) + (int)(enc->ptr - enc->buf) * 8;
358
0
}
359
360
/*Given the current total integer number of bits used and the current value of
361
   rng, computes the fraction number of bits used to OD_BITRES precision.
362
  This is used by od_ec_enc_tell_frac() and od_ec_dec_tell_frac().
363
  nbits_total: The number of whole bits currently used, i.e., the value
364
                returned by od_ec_enc_tell() or od_ec_dec_tell().
365
  rng: The current value of rng from either the encoder or decoder state.
366
  Return: The number of bits scaled by 2**OD_BITRES.
367
          This will always be slightly larger than the exact value (e.g., all
368
           rounding error is in the positive direction).*/
369
0
uint32_t svt_od_ec_tell_frac(uint32_t nbits_total, uint32_t rng) {
370
0
    uint32_t nbits;
371
0
    int      l;
372
0
    int      i;
373
    /*To handle the non-integral number of bits still left in the encoder/decoder
374
       state, we compute the worst-case number of bits of val that must be
375
       encoded to ensure that the value is inside the range for any possible
376
       subsequent bits.
377
      The computation here is independent of val itself (the decoder does not
378
       even track that value), even though the real number of bits used after
379
       od_ec_enc_done() may be 1 smaller if rng is a power of two and the
380
       corresponding trailing bits of val are all zeros.
381
      If we did try to track that special case, then coding a value with a
382
       probability of 1/(1 << n) might sometimes appear to use more than n bits.
383
      This may help explain the surprising result that a newly initialized
384
       encoder or decoder claims to have used 1 bit.*/
385
0
    nbits = nbits_total << OD_BITRES;
386
0
    l     = 0;
387
0
    for (i = OD_BITRES; i-- > 0;) {
388
0
        int b;
389
0
        rng = rng * rng >> 15;
390
0
        b   = (int)(rng >> 16);
391
0
        l   = l << 1 | b;
392
0
        rng >>= b;
393
0
    }
394
0
    return nbits - l;
395
0
}
396
397
/*Returns the number of bits "used" by the encoded symbols so far.
398
  This same number can be computed in either the encoder or the decoder, and is
399
   suitable for making coding decisions.
400
  Warning: The value returned by this function can decrease compared to an
401
   earlier call, even after encoding more data, if there is an encoding error
402
   (i.e., a failure to allocate enough space for the output buffer).
403
  Return: The number of bits scaled by 2**OD_BITRES.
404
          This will always be slightly larger than the exact value (e.g., all
405
           rounding error is in the positive direction).*/
406
0
uint32_t svt_od_ec_enc_tell_frac(const OdEcEnc* enc) {
407
0
    return svt_od_ec_tell_frac(svt_od_ec_enc_tell(enc), enc->rng);
408
0
}
409
410
/********************************************************************************************************************************/
411
/********************************************************************************************************************************/
412
/********************************************************************************************************************************/