Coverage Report

Created: 2026-06-10 07:00

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