Coverage Report

Created: 2026-06-15 06:25

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
6.80k
static void output_bitstream_unit_dctor(EbPtr p) {
25
6.80k
    OutputBitstreamUnit* obj = (OutputBitstreamUnit*)p;
26
6.80k
    EB_FREE_ARRAY(obj->buffer_begin_av1);
27
6.80k
}
28
29
/**********************************
30
 * Constructor
31
 **********************************/
32
6.80k
EbErrorType svt_aom_output_bitstream_unit_ctor(OutputBitstreamUnit* bitstream_ptr, uint32_t buffer_size) {
33
6.80k
    bitstream_ptr->dctor = output_bitstream_unit_dctor;
34
6.80k
    if (buffer_size) {
35
6.80k
        bitstream_ptr->size = buffer_size;
36
6.80k
        EB_MALLOC_ARRAY(bitstream_ptr->buffer_begin_av1, bitstream_ptr->size);
37
6.80k
        bitstream_ptr->buffer_av1 = bitstream_ptr->buffer_begin_av1;
38
6.80k
    } 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
6.80k
    return EB_ErrorNone;
45
6.80k
}
46
47
/**********************************
48
 * Reset Bitstream
49
 **********************************/
50
431
EbErrorType svt_aom_output_bitstream_reset(OutputBitstreamUnit* bitstream_ptr) {
51
431
    EbErrorType return_error = EB_ErrorNone;
52
53
    // Reset the write ptr to the beginning of the buffer
54
431
    bitstream_ptr->buffer_av1 = bitstream_ptr->buffer_begin_av1;
55
56
431
    return return_error;
57
431
}
58
59
/********************************************************************************************************************************/
60
/********************************************************************************************************************************/
61
/********************************************************************************************************************************/
62
/********************************************************************************************************************************/
63
/* Realloc when bitstream pointer size is not enough to write data of size sz */
64
4.82k
EbErrorType svt_realloc_output_bitstream_unit(OutputBitstreamUnit* output_bitstream_ptr, uint32_t sz) {
65
4.82k
    if (output_bitstream_ptr && sz > 0) {
66
        // Must add offset to realloc'd buffer to save any previously written bits
67
4.82k
        uint64_t offset = output_bitstream_ptr->buffer_av1 - output_bitstream_ptr->buffer_begin_av1;
68
4.82k
        assert(output_bitstream_ptr->buffer_av1 >= output_bitstream_ptr->buffer_begin_av1);
69
4.82k
        output_bitstream_ptr->size = sz;
70
4.82k
        EB_REALLOC_ARRAY(output_bitstream_ptr->buffer_begin_av1, output_bitstream_ptr->size);
71
4.82k
        output_bitstream_ptr->buffer_av1 = output_bitstream_ptr->buffer_begin_av1 + offset;
72
4.82k
    }
73
4.82k
    return EB_ErrorNone;
74
4.82k
}
75
76
// ptr points one past the last written byte; propagate carry backward
77
4.28k
static inline void propagate_carry_bwd(unsigned char* ptr) {
78
4.31k
    while (!++*--ptr) {}
79
4.28k
}
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
12.8k
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
12.8k
    int s              = c + d;
114
12.8k
    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
12.8k
    c += 24 - num_bits_ready;
120
121
    // Extract ready bits from low
122
12.8k
    uint64_t output = low >> c;
123
124
    // Separate carry bit from data
125
12.8k
    uint64_t mask = (uint64_t)1 << num_bits_ready;
126
127
12.8k
    if (output & mask) {
128
2.52k
        assert(enc->ptr > enc->buf);
129
2.52k
        propagate_carry_bwd(enc->ptr);
130
2.52k
    }
131
132
    // Write to buffer. Carry bit will be shifted away, no need to mask
133
    // output &= mask - 1;
134
12.8k
    const uint64_t reg = HToBE64(output << (64 - num_bits_ready));
135
12.8k
    memcpy(enc->ptr, &reg, 8);
136
137
12.8k
    enc->ptr += num_bits_ready >> 3;
138
139
12.8k
    low &= (((uint64_t)1 << c) - 1);
140
141
12.8k
    enc->low = low << d;
142
12.8k
    enc->rng = rng << d;
143
12.8k
    enc->cnt = (s & 7) - 8;
144
12.8k
}
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
850k
static inline void svt_od_ec_enc_normalize(OdEcEnc* enc, OdEcWindow low, unsigned rng) {
152
850k
    int c = enc->cnt;
153
850k
    assert(rng <= 65535U);
154
    /*The number of leading zeros in the 16-bit binary representation of rng.*/
155
850k
    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
850k
    if (EB_UNLIKELY(c + d >= 40)) { // 56 - 16
168
12.8k
        od_ec_enc_flush(enc, low, rng, c, d);
169
837k
    } else {
170
837k
        enc->low = low << d;
171
837k
        enc->rng = rng << d;
172
837k
        enc->cnt = c + d;
173
837k
    }
174
850k
}
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
4.65k
void svt_od_ec_enc_init(OdEcEnc* enc) {
180
4.65k
    enc->buf = NULL;
181
4.65k
    svt_od_ec_enc_reset(enc);
182
4.65k
}
183
184
/*Reinitializes the encoder.*/
185
9.30k
void svt_od_ec_enc_reset(OdEcEnc* enc) {
186
9.30k
    enc->ptr = enc->buf;
187
9.30k
    enc->low = 0;
188
9.30k
    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
9.30k
    enc->cnt   = -9;
192
9.30k
    enc->error = 0;
193
#if OD_MEASURE_EC_OVERHEAD
194
    enc->entropy    = 0;
195
    enc->nb_symbols = 0;
196
#endif
197
9.30k
}
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
5.73k
EbErrorType svt_aom_ec_ensure_capacity(AomWriter* w, uint32_t min_free) {
211
5.73k
    EbErrorType          ret    = EB_ErrorNone;
212
5.73k
    OutputBitstreamUnit* parent = w->buffer_parent;
213
5.73k
    OdEcEnc*             enc    = &w->ec;
214
5.73k
    uint32_t             offs   = (uint32_t)(enc->ptr - enc->buf);
215
5.73k
    uint32_t             needed = offs + min_free;
216
5.73k
    if (needed > parent->size) {
217
        // Realloc through the OutputBitstreamUnit that owns the buffer
218
4.82k
        ret = svt_realloc_output_bitstream_unit(parent, needed);
219
4.82k
        if (ret != EB_ErrorNone) {
220
0
            enc->error = -1;
221
4.82k
        } else {
222
            // Update EC's borrowed pointers
223
4.82k
            enc->buf = parent->buffer_begin_av1;
224
4.82k
            enc->ptr = enc->buf + offs;
225
4.82k
        }
226
4.82k
    }
227
5.73k
    return ret;
228
5.73k
}
229
230
/*Encode a single binary value with 1/2 probability.
231
  val: The value to encode (0 or 1).*/
232
196k
void svt_od_ec_encode_bool_eq_q15(OdEcEnc* enc, int val) {
233
196k
    OdEcWindow l = enc->low;
234
196k
    uint32_t   r = enc->rng;
235
196k
    assert(32768U <= r);
236
196k
    uint32_t v = ((r >> 8) << (CDF_PROB_BITS - 1 - 7)) + EC_MIN_PROB;
237
196k
    r -= v;
238
196k
    if (val) {
239
63.2k
        l += r;
240
63.2k
        r = v;
241
63.2k
    }
242
196k
    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
196k
}
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
168k
void svt_od_ec_encode_bool_q15(OdEcEnc* enc, int val, uint32_t f) {
253
168k
    assert(f < 32768U);
254
168k
    OdEcWindow l = enc->low;
255
168k
    uint32_t   r = enc->rng;
256
168k
    assert(32768U <= r);
257
168k
    EB_ASSUME(f <= 32768);
258
168k
    uint32_t v = ((r >> 8) * (f >> EC_PROB_SHIFT) >> (7 - EC_PROB_SHIFT)) + EC_MIN_PROB;
259
168k
    r -= v;
260
168k
    if (val) {
261
144k
        l += r;
262
144k
        r = v;
263
144k
    }
264
168k
    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
168k
}
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
484k
void svt_od_ec_encode_cdf_q15(OdEcEnc* enc, int s, const uint16_t* icdf, int nsyms) {
280
484k
    assert(s >= 0);
281
484k
    assert(s < nsyms);
282
484k
    assert(icdf[nsyms - 1] == OD_ICDF(CDF_PROB_TOP));
283
284
484k
    OdEcWindow l = enc->low;
285
484k
    uint32_t   r = enc->rng;
286
484k
    assert(32768U <= r);
287
484k
    assert(7 - EC_PROB_SHIFT >= 0);
288
484k
    const uint32_t r_hi = r >> 8;
289
484k
    const uint32_t temp = EC_MIN_PROB * (nsyms - 1 - s);
290
484k
    if (0 < s) {
291
104k
        uint32_t u = (r_hi * (icdf[s - 1] >> EC_PROB_SHIFT) >> (7 - EC_PROB_SHIFT)) + temp + EC_MIN_PROB;
292
104k
        l += r - u;
293
104k
        r = u;
294
104k
    }
295
484k
    r -= (r_hi * (icdf[s] >> EC_PROB_SHIFT) >> (7 - EC_PROB_SHIFT)) + temp;
296
484k
    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
484k
}
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
4.65k
unsigned char* svt_od_ec_enc_done(OdEcEnc* enc, uint32_t* nbytes) {
310
4.65k
    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
4.65k
    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
4.65k
    OdEcWindow m = 0x3FFF;
328
4.65k
    OdEcWindow e = ((enc->low + m) & ~m) | (m + 1);
329
4.65k
    OdEcWindow v = e >> (c + 16);
330
4.65k
    if (v & 0x0100) {
331
1.76k
        assert(enc->ptr > enc->buf);
332
1.76k
        propagate_carry_bwd(enc->ptr);
333
1.76k
    }
334
18.2k
    do {
335
18.2k
        *enc->ptr++ = (unsigned char)((e >> (c + 16)) & 0xFF);
336
337
18.2k
        c -= 8;
338
18.2k
    } while (10 + c > 0);
339
340
4.65k
    *nbytes = (uint32_t)(enc->ptr - enc->buf);
341
342
4.65k
    return enc->buf;
343
4.65k
}
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
/********************************************************************************************************************************/