/src/vvenc/source/Lib/EncoderLib/BinEncoder.h
Line | Count | Source |
1 | | /* ----------------------------------------------------------------------------- |
2 | | The copyright in this software is being made available under the Clear BSD |
3 | | License, included below. No patent rights, trademark rights and/or |
4 | | other Intellectual Property Rights other than the copyrights concerning |
5 | | the Software are granted under this license. |
6 | | |
7 | | The Clear BSD License |
8 | | |
9 | | Copyright (c) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC Authors. |
10 | | All rights reserved. |
11 | | |
12 | | Redistribution and use in source and binary forms, with or without modification, |
13 | | are permitted (subject to the limitations in the disclaimer below) provided that |
14 | | the following conditions are met: |
15 | | |
16 | | * Redistributions of source code must retain the above copyright notice, |
17 | | this list of conditions and the following disclaimer. |
18 | | |
19 | | * Redistributions in binary form must reproduce the above copyright |
20 | | notice, this list of conditions and the following disclaimer in the |
21 | | documentation and/or other materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the copyright holder nor the names of its |
24 | | contributors may be used to endorse or promote products derived from this |
25 | | software without specific prior written permission. |
26 | | |
27 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY |
28 | | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
29 | | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
30 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
31 | | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
32 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
33 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
34 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
35 | | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
36 | | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
37 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | | POSSIBILITY OF SUCH DAMAGE. |
39 | | |
40 | | |
41 | | ------------------------------------------------------------------------------------------- */ |
42 | | #pragma once |
43 | | |
44 | | #include "CommonLib/Contexts.h" |
45 | | #include "CommonLib/BitStream.h" |
46 | | #include "CommonLib/dtrace_next.h" |
47 | | |
48 | | //! \ingroup EncoderLib |
49 | | //! \{ |
50 | | |
51 | | namespace vvenc { |
52 | | |
53 | | class BinStore |
54 | | { |
55 | | public: |
56 | 0 | BinStore () : m_inUse(false), m_allocated(false) {} |
57 | 0 | ~BinStore() {} |
58 | | |
59 | | void reset () |
60 | 0 | { |
61 | 0 | if( m_inUse ) |
62 | 0 | { |
63 | 0 | for( unsigned n = 0; n < Ctx::NumberOfContexts; n++ ) |
64 | 0 | { |
65 | 0 | m_binBuffer[n].clear(); |
66 | 0 | } |
67 | 0 | } |
68 | 0 | } |
69 | | void addBin ( unsigned bin, unsigned ctxId ) |
70 | 0 | { |
71 | 0 | if( m_inUse ) |
72 | 0 | { |
73 | 0 | std::vector<bool>& binBuffer = m_binBuffer[ctxId]; |
74 | 0 | if( binBuffer.size() < m_maxNumBins ) |
75 | 0 | { |
76 | 0 | binBuffer.push_back( bin == 1 ); |
77 | 0 | } |
78 | 0 | } |
79 | 0 | } |
80 | | |
81 | 0 | void setUse ( bool useStore ) { m_inUse = useStore; if(m_inUse){xCheckAlloc();} } |
82 | 0 | bool inUse () const { return m_inUse; } |
83 | 0 | const std::vector<bool>& getBinVector( unsigned ctxId ) const { return m_binBuffer[ctxId]; } |
84 | | |
85 | | private: |
86 | | void xCheckAlloc() |
87 | 0 | { |
88 | 0 | if( !m_allocated ) |
89 | 0 | { |
90 | 0 | m_binBuffer.resize( Ctx::NumberOfContexts ); |
91 | 0 | for( unsigned n = 0; n < Ctx::NumberOfContexts; n++ ) |
92 | 0 | { |
93 | 0 | m_binBuffer[n].reserve( m_maxNumBins ); |
94 | 0 | } |
95 | 0 | m_allocated = true; |
96 | 0 | } |
97 | 0 | } |
98 | | |
99 | | private: |
100 | | static const std::size_t m_maxNumBins = 100000; |
101 | | bool m_inUse; |
102 | | bool m_allocated; |
103 | | std::vector< std::vector<bool> > m_binBuffer; |
104 | | }; |
105 | | |
106 | | |
107 | | class BinEncIf : public Ctx |
108 | | { |
109 | | protected: |
110 | | template <class BinProbModel> |
111 | 0 | BinEncIf( const BinProbModel* dummy ) : Ctx( dummy ) {} |
112 | | public: |
113 | 0 | virtual ~BinEncIf() {} |
114 | | public: |
115 | | virtual void init ( OutputBitstream* bitstream ) = 0; |
116 | | virtual void uninit () = 0; |
117 | | virtual void start () = 0; |
118 | | virtual void finish () = 0; |
119 | | virtual void restart () = 0; |
120 | | virtual void reset ( int qp, int initId ) = 0; |
121 | | public: |
122 | | virtual void resetBits () = 0; |
123 | | virtual uint64_t getEstFracBits () const = 0; |
124 | | virtual unsigned getNumBins ( unsigned ctxId ) const = 0; |
125 | | public: |
126 | | virtual void encodeBin ( unsigned bin, unsigned ctxId ) = 0; |
127 | | virtual void encodeBinEP ( unsigned bin ) = 0; |
128 | | virtual void encodeBinsEP ( unsigned bins, unsigned numBins ) = 0; |
129 | | virtual void encodeRemAbsEP ( unsigned bins, |
130 | | unsigned goRicePar, |
131 | | unsigned cutoff, |
132 | | int maxLog2TrDynamicRange ) = 0; |
133 | | virtual void encodeBinTrm ( unsigned bin ) = 0; |
134 | | virtual void align () = 0; |
135 | | public: |
136 | | virtual uint32_t getNumBins () = 0; |
137 | | virtual bool isEncoding () = 0; |
138 | | virtual unsigned getNumWrittenBits () = 0; |
139 | | public: |
140 | | virtual void setBinStorage ( bool b ) = 0; |
141 | | virtual const BinStore* getBinStore () const = 0; |
142 | | virtual BinEncIf* getTestBinEncoder () const = 0; |
143 | | }; |
144 | | |
145 | | |
146 | | |
147 | | class BinCounter |
148 | | { |
149 | | public: |
150 | | BinCounter(); |
151 | 0 | ~BinCounter() {} |
152 | | public: |
153 | | void reset (); |
154 | 0 | void addCtx ( unsigned ctxId ) { m_NumBinsCtx[ctxId]++; } |
155 | 0 | void addEP ( unsigned num ) { m_NumBinsEP+=num; } |
156 | 0 | void addEP () { m_NumBinsEP++; } |
157 | 0 | void addTrm () { m_NumBinsTrm++; } |
158 | | uint32_t getAll () const; |
159 | 0 | uint32_t getCtx ( unsigned ctxId ) const { return m_NumBinsCtx[ctxId]; } |
160 | 0 | uint32_t getEP () const { return m_NumBinsEP; } |
161 | 0 | uint32_t getTrm () const { return m_NumBinsTrm; } |
162 | | private: |
163 | | std::vector<uint32_t> m_CtxBinsCodedBuffer; |
164 | | uint32_t* m_NumBinsCtx; |
165 | | uint32_t m_NumBinsEP; |
166 | | uint32_t m_NumBinsTrm; |
167 | | }; |
168 | | |
169 | | |
170 | | |
171 | | class BinEncoderBase : public BinEncIf, public BinCounter |
172 | | { |
173 | | protected: |
174 | | BinEncoderBase ( const BinProbModel* dummy ); |
175 | | public: |
176 | 0 | ~BinEncoderBase() {} |
177 | | public: |
178 | | void init ( OutputBitstream* bitstream ); |
179 | | void uninit (); |
180 | | void start (); |
181 | | void finish (); |
182 | | void restart (); |
183 | | void reset ( int qp, int initId ); |
184 | | |
185 | | void resetBits (); |
186 | 0 | uint64_t getEstFracBits () const { THROW( "not supported" ); return 0; } |
187 | 0 | unsigned getNumBins ( unsigned ctxId ) const { return BinCounter::getCtx(ctxId); } |
188 | | |
189 | | void encodeBinEP ( unsigned bin ); |
190 | | void encodeBinsEP ( unsigned bins, unsigned numBins ); |
191 | | void encodeRemAbsEP ( unsigned bins, |
192 | | unsigned goRicePar, |
193 | | unsigned cutoff, |
194 | | int maxLog2TrDynamicRange ); |
195 | | void encodeBinTrm ( unsigned bin ); |
196 | | void align (); |
197 | 0 | unsigned getNumWrittenBits () { return ( m_Bitstream->getNumberOfWrittenBits() + 8 * m_numBufferedBytes + 23 - m_bitsLeft ); } |
198 | | |
199 | 0 | uint32_t getNumBins () { return BinCounter::getAll(); } |
200 | 0 | bool isEncoding () { return true; } |
201 | | protected: |
202 | | void encodeAlignedBinsEP ( unsigned bins, unsigned numBins ); |
203 | | void writeOut (); |
204 | | protected: |
205 | | OutputBitstream* m_Bitstream; |
206 | | uint32_t m_Low; |
207 | | uint32_t m_Range; |
208 | | uint32_t m_bufferedByte; |
209 | | int32_t m_numBufferedBytes; |
210 | | int32_t m_bitsLeft; |
211 | | BinStore m_BinStore; |
212 | | }; |
213 | | |
214 | | |
215 | | |
216 | | class BinEncoder : public BinEncoderBase |
217 | | { |
218 | | public: |
219 | | BinEncoder (); |
220 | 0 | ~BinEncoder() {} |
221 | | void encodeBin ( unsigned bin, unsigned ctxId ); |
222 | | public: |
223 | 0 | void setBinStorage ( bool b ) { m_BinStore.setUse(b); } |
224 | 0 | const BinStore* getBinStore () const { return &m_BinStore; } |
225 | | BinEncIf* getTestBinEncoder () const; |
226 | | private: |
227 | | CtxStore& m_Ctx; |
228 | | }; |
229 | | |
230 | | |
231 | | |
232 | | |
233 | | |
234 | | class BitEstimatorBase : public BinEncIf |
235 | | { |
236 | | protected: |
237 | | BitEstimatorBase ( const BinProbModel* dummy ); |
238 | | public: |
239 | 0 | ~BitEstimatorBase() {} |
240 | | public: |
241 | 0 | void init ( OutputBitstream* bitstream ) {} |
242 | 0 | void uninit () {} |
243 | 0 | void start () { m_EstFracBits = 0; } |
244 | 0 | void finish () {} |
245 | 0 | void restart () { m_EstFracBits = (m_EstFracBits >> SCALE_BITS) << SCALE_BITS; } |
246 | 0 | void reset ( int qp, int initId ) { Ctx::init( qp, initId ); m_EstFracBits = 0;} |
247 | | public: |
248 | 0 | void resetBits () { m_EstFracBits = 0; } |
249 | | |
250 | 0 | uint64_t getEstFracBits () const { return m_EstFracBits; } |
251 | 0 | unsigned getNumBins ( unsigned ctxId ) const { THROW( "not supported for BitEstimator" ); return 0; } |
252 | | public: |
253 | 0 | void encodeBinEP ( unsigned bin ) { m_EstFracBits += BinProbModelBase::estFracBitsEP (); } |
254 | 0 | void encodeBinsEP ( unsigned bins, unsigned numBins ) { m_EstFracBits += BinProbModelBase::estFracBitsEP ( numBins ); } |
255 | | void encodeRemAbsEP ( unsigned bins, |
256 | | unsigned goRicePar, |
257 | | unsigned cutoff, |
258 | | int maxLog2TrDynamicRange ); |
259 | | void align (); |
260 | | public: |
261 | 0 | uint32_t getNumBins () { THROW("Not supported"); return 0; } |
262 | 0 | bool isEncoding () { return false; } |
263 | 0 | unsigned getNumWrittenBits () { /*THROW( "Not supported" );*/ return (uint32_t)( 0/*m_EstFracBits*//* >> SCALE_BITS*/ ); } |
264 | | |
265 | | protected: |
266 | | uint64_t m_EstFracBits; |
267 | | }; |
268 | | |
269 | | |
270 | | |
271 | | class BitEstimator : public BitEstimatorBase |
272 | | { |
273 | | public: |
274 | | BitEstimator (); |
275 | 0 | ~BitEstimator() {} |
276 | 0 | void encodeBin ( unsigned bin, unsigned ctxId ) { m_Ctx[ctxId].estFracBitsUpdate( bin, m_EstFracBits ); } |
277 | 0 | void encodeBinTrm ( unsigned bin ) { m_EstFracBits += BinProbModel::estFracBitsTrm( bin ); } |
278 | 0 | void setBinStorage ( bool b ) {} |
279 | 0 | const BinStore* getBinStore () const { return 0; } |
280 | 0 | BinEncIf* getTestBinEncoder () const { return 0; } |
281 | | private: |
282 | | CtxStore& m_Ctx; |
283 | | }; |
284 | | |
285 | | } // namespace vvenc |
286 | | |
287 | | //! \} |
288 | | |