Coverage Report

Created: 2026-10-17 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/libde265/libde265/cabac.h
Line
Count
Source
1
/*
2
 * H.265 video codec.
3
 * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
4
 *
5
 * This file is part of libde265.
6
 *
7
 * libde265 is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation, either version 3 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * libde265 is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with libde265.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#ifndef DE265_CABAC_H
22
#define DE265_CABAC_H
23
24
#include <stdint.h>
25
#include "contextmodel.h"
26
27
28
class CABAC_decoder {
29
public:
30
  void init(uint8_t* bitstream, int length);
31
  void init_CABAC();
32
  int  decode_bit(context_model* model);
33
  int  decode_TU(int cMax, context_model* model);
34
  int  decode_term_bit();
35
36
  int  decode_bypass();
37
  void align_bypass();
38
  int  decode_TU_bypass(int cMax);
39
  uint32_t  decode_FL_bypass(int nBits);
40
  int  decode_TR_bypass(int cRiceParam, int cTRMax);
41
  uint32_t  decode_EGk_bypass(int k);
42
43
  uint8_t* bitstream_start = nullptr;
44
  uint8_t* bitstream_curr = nullptr;
45
  uint8_t* bitstream_end = nullptr;
46
47
private:
48
  uint32_t range = 0;
49
  uint32_t value = 0;
50
  int16_t  bits_needed = 0;
51
52
  int  decode_FL_bypass_parallel(int nBits);
53
};
54
55
56
// ---------------------------------------------------------------------------
57
58
class CABAC_encoder
59
{
60
public:
61
0
 CABAC_encoder() : mCtxModels(nullptr) { }
62
0
  virtual ~CABAC_encoder() { }
63
64
  virtual int size() const = 0;
65
  virtual void reset() = 0;
66
67
  // --- VLC ---
68
69
  virtual void write_bits(uint32_t bits,int n) = 0;
70
0
  virtual void write_bit(int bit) { write_bits(bit,1); }
71
  virtual void write_uvlc(int value);
72
  virtual void write_svlc(int value);
73
  virtual bool write_startcode() = 0;
74
  virtual void skip_bits(int nBits) = 0;
75
76
  virtual void add_trailing_bits();
77
  virtual int  number_free_bits_in_byte() const = 0;
78
79
  // output all remaining bits and fill with zeros to next byte boundary
80
0
  virtual void flush_VLC() { }
81
82
83
  // --- CABAC ---
84
85
0
  void set_context_models(context_model_table* models) { mCtxModels=models; }
86
87
0
  virtual void init_CABAC() { }
88
  virtual void write_CABAC_bit(int modelIdx, int bit) = 0;
89
  virtual void write_CABAC_bypass(int bit) = 0;
90
  virtual void write_CABAC_TU_bypass(int value, int cMax);
91
  virtual void write_CABAC_FL_bypass(int value, int nBits);
92
  virtual void write_CABAC_term_bit(int bit) = 0;
93
0
  virtual void flush_CABAC()  { }
94
95
  void write_CABAC_EGk(int absolute_symbol, int k); // absolute_symbol >= 0
96
97
  virtual bool modifies_context() const = 0;
98
99
  float RDBits_for_CABAC_bin(int modelIdx, int bit);
100
101
 protected:
102
  context_model_table* mCtxModels;
103
};
104
105
106
class CABAC_encoder_bitstream : public CABAC_encoder
107
{
108
public:
109
  CABAC_encoder_bitstream();
110
  ~CABAC_encoder_bitstream();
111
112
  void reset() override;
113
114
0
  int size() const override { return data_size; }
115
0
  uint8_t* data() const { return data_mem; }
116
117
  // --- VLC ---
118
119
  void write_bits(uint32_t bits,int n) override;
120
  bool write_startcode() override;
121
  void skip_bits(int nBits) override;
122
123
  int  number_free_bits_in_byte() const override;
124
125
  // output all remaining bits and fill with zeros to next byte boundary
126
  void flush_VLC() override;
127
128
129
  // --- CABAC ---
130
131
  void init_CABAC() override;
132
  void write_CABAC_bit(int modelIdx, int bit) override;
133
  void write_CABAC_bypass(int bit) override;
134
  void write_CABAC_term_bit(int bit) override;
135
  void flush_CABAC() override;
136
137
0
  bool modifies_context() const override { return true; }
138
139
private:
140
  // data buffer
141
142
  uint8_t* data_mem = nullptr;
143
  uint32_t data_capacity = 0;
144
  uint32_t data_size = 0;
145
  char     state = 0; // for inserting emulation-prevention bytes
146
147
  // VLC
148
149
  uint32_t vlc_buffer;
150
  uint32_t vlc_buffer_len = 0;
151
152
153
  // CABAC
154
155
  uint32_t range;
156
  uint32_t low;
157
  int8_t   bits_left;
158
  uint8_t  buffered_byte;
159
  uint16_t num_buffered_bytes;
160
161
162
  bool check_size_and_resize(int nBytes);
163
  void testAndWriteOut();
164
  void write_out();
165
  bool append_byte(int byte);
166
};
167
168
169
class CABAC_encoder_estim : public CABAC_encoder
170
{
171
public:
172
0
  CABAC_encoder_estim() : mFracBits(0) { }
173
174
0
  void reset() override { mFracBits=0; }
175
176
0
  int size() const override { return mFracBits>>(15+3); }
177
178
0
  uint64_t getFracBits() const { return mFracBits; }
179
0
  float    getRDBits() const { return mFracBits / float(1<<15); }
180
181
  // --- VLC ---
182
183
0
  void write_bits(uint32_t bits,int n) override { mFracBits += n<<15; }
184
0
  void write_bit(int bit) override { mFracBits+=1<<15; }
185
0
  bool write_startcode() override { mFracBits += (1<<15)*8*3; return true; }
186
0
  void skip_bits(int nBits) override { mFracBits += nBits<<15; }
187
0
  int  number_free_bits_in_byte() const override { return 0; } // TODO, good enough for now
188
189
  // --- CABAC ---
190
191
  void write_CABAC_bit(int modelIdx, int bit) override;
192
0
  void write_CABAC_bypass(int bit) override {
193
0
    mFracBits += 0x8000;
194
0
  }
195
0
  void write_CABAC_FL_bypass(int value, int nBits) override {
196
0
    mFracBits += nBits<<15;
197
0
  }
198
0
  void write_CABAC_term_bit(int bit) override { /* not implemented (not needed) */ }
199
200
0
  bool modifies_context() const override { return true; }
201
202
 protected:
203
  uint64_t mFracBits;
204
};
205
206
207
class CABAC_encoder_estim_constant : public CABAC_encoder_estim
208
{
209
 public:
210
  void write_CABAC_bit(int modelIdx, int bit) override;
211
212
0
  bool modifies_context() const override { return false; }
213
};
214
215
#endif