Coverage Report

Created: 2026-05-30 06:10

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