/work/vvenc/source/Lib/CommonLib/ContextModelling.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 | | /** \file ContextModelling.h |
43 | | * \brief Classes providing probability descriptions and contexts (header) |
44 | | */ |
45 | | |
46 | | #pragma once |
47 | | |
48 | | #include "CommonDef.h" |
49 | | #include "Contexts.h" |
50 | | #include "Slice.h" |
51 | | #include "Unit.h" |
52 | | #include "UnitPartitioner.h" |
53 | | |
54 | | #include <bitset> |
55 | | |
56 | | //! \ingroup CommonLib |
57 | | //! \{ |
58 | | |
59 | | namespace vvenc |
60 | | { |
61 | | |
62 | | struct CtxTpl |
63 | | { |
64 | | // lower 5 bits are absSum1, upper 3 bits are numPos |
65 | | uint8_t ctxTpl; |
66 | | }; |
67 | | |
68 | | struct CoeffCodingContext |
69 | | { |
70 | | public: |
71 | | CoeffCodingContext( const TransformUnit& tu, ComponentID component, bool signHide, bool bdpcm = false, CtxTpl* tplBuf = nullptr ); |
72 | | public: |
73 | | void initSubblock ( int SubsetId, bool sigGroupFlag = false ); |
74 | | public: |
75 | 10.7k | void resetSigGroup () { m_sigCoeffGroupFlag.reset( m_subSetPos ); } |
76 | 432k | void setSigGroup () { m_sigCoeffGroupFlag.set( m_subSetPos ); } |
77 | 0 | bool noneSigGroup () { return m_sigCoeffGroupFlag.none(); } |
78 | 426k | int lastSubSet () { return ( maxNumCoeff() - 1 ) >> log2CGSize(); } |
79 | 362k | bool isLastSubSet () { return lastSubSet() == m_subSetId; } |
80 | 63.9k | bool only1stSigGroup () { return m_sigCoeffGroupFlag.count()-m_sigCoeffGroupFlag[lastSubSet()]==0; } |
81 | 844k | void setScanPosLast ( int posLast ) { m_scanPosLast = posLast; } |
82 | | public: |
83 | 0 | ComponentID compID () const { return m_compID; } |
84 | 596k | int subSetId () const { return m_subSetId; } |
85 | 0 | int subSetPos () const { return m_subSetPos; } |
86 | 43.4k | int cgPosY () const { return m_subSetPosY; } |
87 | 43.4k | int cgPosX () const { return m_subSetPosX; } |
88 | 1.68M | unsigned width () const { return m_width; } |
89 | 0 | unsigned height () const { return m_height; } |
90 | 5.63k | unsigned log2CGWidth () const { return m_log2CGWidth; } |
91 | 0 | unsigned log2CGHeight () const { return m_log2CGHeight; } |
92 | 6.06M | unsigned log2CGSize () const { return m_log2CGSize; } |
93 | 4.95M | int maxLog2TrDRange () const { return m_maxLog2TrDynamicRange; } |
94 | 6.86M | unsigned maxNumCoeff () const { return m_maxNumCoeff; } |
95 | 12.0M | int scanPosLast () const { return m_scanPosLast; } |
96 | 10.8M | int minSubPos () const { return m_minSubPos; } |
97 | 387k | int maxSubPos () const { return m_maxSubPos; } |
98 | 869k | bool isLast () const { return ( ( m_scanPosLast >> m_log2CGSize ) == m_subSetId ); } |
99 | 43.4k | bool isNotFirst () const { return ( m_subSetId != 0 ); } |
100 | 0 | bool isSigGroup ( int scanPosCG ) const { return m_sigCoeffGroupFlag[m_scanCG[scanPosCG].idx]; } |
101 | 1.01M | bool isSigGroup () const { return m_sigCoeffGroupFlag[ m_subSetPos ]; } |
102 | 9.01k | bool signHiding () const { return m_signHiding; } |
103 | | bool hideSign ( int posFirst, |
104 | 861k | int posLast ) const { return ( m_signHiding && ( posLast - posFirst >= SBH_THRESHOLD ) ); } |
105 | 54.0M | unsigned blockPos ( int scanPos ) const { return m_scan[scanPos].idx; } |
106 | 9.14M | unsigned posX ( int scanPos ) const { return m_scan[scanPos].x; } |
107 | 9.14M | unsigned posY ( int scanPos ) const { return m_scan[scanPos].y; } |
108 | 844k | unsigned maxLastPosX () const { return m_maxLastPosX; } |
109 | 844k | unsigned maxLastPosY () const { return m_maxLastPosY; } |
110 | 1.92M | unsigned lastXCtxId ( unsigned posLastX ) const { return m_CtxSetLastX( m_lastOffsetX + ( posLastX >> m_lastShiftX ) ); } |
111 | 1.97M | unsigned lastYCtxId ( unsigned posLastY ) const { return m_CtxSetLastY( m_lastOffsetY + ( posLastY >> m_lastShiftY ) ); } |
112 | 958k | unsigned sigGroupCtxId ( bool ts = false ) const { return ts ? m_sigGroupCtxIdTS : m_sigGroupCtxId; } |
113 | 6.06M | bool bdpcm () const { return m_bdpcm; } |
114 | | |
115 | | unsigned sigCtxIdAbs( int scanPos, const TCoeffSig* coeff, const int state ) |
116 | 0 | { |
117 | 0 | const uint32_t posY = m_scan[scanPos].y; |
118 | 0 | const uint32_t posX = m_scan[scanPos].x; |
119 | 0 | const TCoeffSig* pData = coeff + posX + posY * m_width; |
120 | 0 | const int diag = posX + posY; |
121 | 0 | int numPos = 0; |
122 | 0 | int sumAbs = 0; |
123 | 0 | #define UPDATE(x) {int a=abs(x);sumAbs+=std::min(4+(a&1),a);numPos+=!!a;} |
124 | 0 | if( posX < m_width-1 ) |
125 | 0 | { |
126 | 0 | UPDATE( pData[1] ); |
127 | 0 | if( posX < m_width-2 ) |
128 | 0 | { |
129 | 0 | UPDATE( pData[2] ); |
130 | 0 | } |
131 | 0 | if( posY < m_height-1 ) |
132 | 0 | { |
133 | 0 | UPDATE( pData[m_width+1] ); |
134 | 0 | } |
135 | 0 | } |
136 | 0 | if( posY < m_height-1 ) |
137 | 0 | { |
138 | 0 | UPDATE( pData[m_width] ); |
139 | 0 | if( posY < m_height-2 ) |
140 | 0 | { |
141 | 0 | UPDATE( pData[m_width<<1] ); |
142 | 0 | } |
143 | 0 | } |
144 | 0 | #undef UPDATE |
145 | |
|
146 | 0 | int ctxOfs = std::min((sumAbs+1)>>1, 3) + ( diag < 2 ? 4 : 0 ); |
147 | |
|
148 | 0 | if( m_chType == CH_L ) |
149 | 0 | { |
150 | 0 | ctxOfs += diag < 5 ? 4 : 0; |
151 | 0 | } |
152 | |
|
153 | 0 | m_tmplCpDiag = diag; |
154 | 0 | m_tmplCpSum1 = sumAbs - numPos; |
155 | 0 | return m_sigFlagCtxSet[std::max( 0, state-1 )]( ctxOfs ); |
156 | 0 | } |
157 | | |
158 | | // sigCtxIdAbsWithAcc and absVal1stPass run for every coefficient position of residual coding |
159 | | ALWAYS_INLINE unsigned sigCtxIdAbsWithAcc( const int scanPos, const int state ) |
160 | 5.99M | { |
161 | 5.99M | const auto scanEl = m_scan[scanPos]; |
162 | 5.99M | const uint32_t posY = scanEl.y; |
163 | 5.99M | const uint32_t posX = scanEl.x; |
164 | 5.99M | const int32_t blkPos = scanEl.idx; |
165 | 5.99M | const int diag = posX + posY; |
166 | 5.99M | const int tplVal = m_tplBuf[-blkPos].ctxTpl; |
167 | 5.99M | const int numPos = tplVal >> 5u; |
168 | 5.99M | const int sumAbs = tplVal & 31; |
169 | | |
170 | 5.99M | int ctxOfs = std::min( ( sumAbs + 1 ) >> 1, 3 ) + ( diag < 2 ? 4 : 0 ); |
171 | | |
172 | 5.99M | if( isLuma( m_chType ) ) |
173 | 423k | { |
174 | 423k | ctxOfs += diag < 5 ? 4 : 0; |
175 | 423k | } |
176 | 5.99M | m_tmplCpDiag = diag; |
177 | 5.99M | m_tmplCpSum1 = sumAbs - numPos; |
178 | 5.99M | return m_sigFlagCtxSet[std::max( 0, state-1 )]( ctxOfs ); |
179 | 5.99M | } |
180 | | |
181 | | ALWAYS_INLINE void absVal1stPass( const int scanPos, const TCoeffSig absLevel1 ) |
182 | 6.31M | { |
183 | 6.31M | CHECKD( !absLevel1, "Shound not be called if '0'!" ); |
184 | | |
185 | 6.31M | const auto scanEl = m_scan[scanPos]; |
186 | 6.31M | const uint32_t posY = scanEl.y; |
187 | 6.31M | const uint32_t posX = scanEl.x; |
188 | 6.31M | const int32_t blkPos = scanEl.idx; |
189 | | |
190 | 6.31M | auto update_deps = [&]( int offset ) |
191 | 16.5M | { |
192 | 16.5M | auto& ctx = m_tplBuf[-blkPos + offset]; |
193 | 16.5M | ctx.ctxTpl += uint8_t( 32 + absLevel1 ); |
194 | 16.5M | }; |
195 | | |
196 | 6.31M | if( posY > 1 ) update_deps( 2 * m_width ); |
197 | 6.31M | if( posY > 0 |
198 | 4.24M | && posX > 0 ) update_deps( m_width + 1 ); |
199 | 6.31M | if( posY > 0 ) update_deps( m_width ); |
200 | 6.31M | if( posX > 1 ) update_deps( 2 ); |
201 | 6.31M | if( posX > 0 ) update_deps( 1 ); |
202 | 6.31M | } |
203 | | |
204 | | |
205 | | void remAbsVal1stPass( const int scanPos, const TCoeffSig absLevel1 ) |
206 | 0 | { |
207 | 0 | CHECKD( !absLevel1, "Shound not be called if '0'!" ); |
208 | |
|
209 | 0 | const auto scanEl = m_scan[scanPos]; |
210 | 0 | const uint32_t posY = scanEl.y; |
211 | 0 | const uint32_t posX = scanEl.x; |
212 | 0 | const int32_t blkPos = scanEl.idx; |
213 | |
|
214 | 0 | auto update_deps = [&]( int offset ) |
215 | 0 | { |
216 | 0 | auto& ctx = m_tplBuf[-blkPos + offset]; |
217 | 0 | ctx.ctxTpl -= uint8_t( 32 + absLevel1 ); |
218 | 0 | }; |
219 | |
|
220 | 0 | if( posY > 1 ) update_deps( 2 * m_width ); |
221 | 0 | if( posY > 0 |
222 | 0 | && posX > 0 ) update_deps( m_width + 1 ); |
223 | 0 | if( posY > 0 ) update_deps( m_width ); |
224 | 0 | if( posX > 1 ) update_deps( 2 ); |
225 | 0 | if( posX > 0 ) update_deps( 1 ); |
226 | 0 | } |
227 | | |
228 | | uint8_t ctxOffsetAbs() |
229 | 6.31M | { |
230 | 6.31M | int offset = 0; |
231 | 6.31M | if( m_tmplCpDiag != -1 ) |
232 | 5.46M | { |
233 | 5.46M | offset = std::min( m_tmplCpSum1, 4 ) + 1; |
234 | 5.46M | offset += ( !m_tmplCpDiag ? ( m_chType == CH_L ? 15 : 5 ) : m_chType == CH_L ? m_tmplCpDiag < 3 ? 10 : ( m_tmplCpDiag < 10 ? 5 : 0 ) : 0 ); |
235 | 5.46M | } |
236 | 6.31M | return uint8_t(offset); |
237 | 6.31M | } |
238 | | |
239 | 5.45M | unsigned parityCtxIdAbs ( uint8_t offset ) const { return m_parFlagCtxSet ( offset ); } |
240 | 6.31M | unsigned greater1CtxIdAbs ( uint8_t offset ) const { return m_gtxFlagCtxSet[1]( offset ); } |
241 | 5.45M | unsigned greater2CtxIdAbs ( uint8_t offset ) const { return m_gtxFlagCtxSet[0]( offset ); } |
242 | | |
243 | | unsigned templateAbsSum( int scanPos, const TCoeffSig* coeff, int baseLevel ) |
244 | 4.44M | { |
245 | 4.44M | const uint32_t posY = m_scan[scanPos].y; |
246 | 4.44M | const uint32_t posX = m_scan[scanPos].x; |
247 | 4.44M | const TCoeffSig* pData = coeff + posX + posY * m_width; |
248 | 4.44M | int sum = 0; |
249 | 4.44M | if (posX < m_width - 1) |
250 | 4.36M | { |
251 | 4.36M | sum += abs(pData[1]); |
252 | 4.36M | if (posX < m_width - 2) |
253 | 4.19M | { |
254 | 4.19M | sum += abs(pData[2]); |
255 | 4.19M | } |
256 | 4.36M | if (posY < m_height - 1) |
257 | 4.22M | { |
258 | 4.22M | sum += abs(pData[m_width + 1]); |
259 | 4.22M | } |
260 | 4.36M | } |
261 | 4.44M | if (posY < m_height - 1) |
262 | 4.31M | { |
263 | 4.31M | sum += abs(pData[m_width]); |
264 | 4.31M | if (posY < m_height - 2) |
265 | 4.10M | { |
266 | 4.10M | sum += abs(pData[m_width << 1]); |
267 | 4.10M | } |
268 | 4.31M | } |
269 | 4.44M | return std::max(std::min(sum - 5 * baseLevel, 31), 0); |
270 | 4.44M | } |
271 | | |
272 | | unsigned sigCtxIdAbsTS( int scanPos, const TCoeffSig* coeff ) |
273 | 11.6M | { |
274 | 11.6M | const uint32_t posY = m_scan[scanPos].y; |
275 | 11.6M | const uint32_t posX = m_scan[scanPos].x; |
276 | 11.6M | const TCoeffSig* posC = coeff + posX + posY * m_width; |
277 | 11.6M | int numPos = 0; |
278 | 20.5M | #define UPDATE(x) {int a=abs(x);numPos+=!!a;} |
279 | 11.6M | if( posX > 0 ) |
280 | 10.4M | { |
281 | 10.4M | UPDATE( posC[-1] ); |
282 | 10.4M | } |
283 | 11.6M | if( posY > 0 ) |
284 | 10.1M | { |
285 | 10.1M | UPDATE( posC[-(int)m_width] ); |
286 | 10.1M | } |
287 | 11.6M | #undef UPDATE |
288 | | |
289 | 11.6M | return m_tsSigFlagCtxSet( numPos ); |
290 | 11.6M | } |
291 | | |
292 | 10.0M | unsigned parityCtxIdAbsTS () const { return m_tsParFlagCtxSet( 0 ); } |
293 | 3.43M | unsigned greaterXCtxIdAbsTS ( uint8_t offset ) const { return m_tsGtxFlagCtxSet( offset ); } |
294 | | |
295 | | unsigned lrg1CtxIdAbsTS(int scanPos, const TCoeffSig* coeff, int bdpcm) |
296 | 10.0M | { |
297 | 10.0M | const uint32_t posY = m_scan[scanPos].y; |
298 | 10.0M | const uint32_t posX = m_scan[scanPos].x; |
299 | 10.0M | const TCoeffSig* posC = coeff + posX + posY * m_width; |
300 | | |
301 | 10.0M | int numPos = 0; |
302 | 10.0M | #define UPDATE(x) {int a=abs(x);numPos+=!!a;} |
303 | | |
304 | 10.0M | if (bdpcm) |
305 | 9.55M | { |
306 | 9.55M | numPos = 3; |
307 | 9.55M | } |
308 | 473k | else |
309 | 473k | { |
310 | 473k | if (posX > 0) |
311 | 436k | { |
312 | 436k | UPDATE(posC[-1]); |
313 | 436k | } |
314 | 473k | if (posY > 0) |
315 | 436k | { |
316 | 436k | UPDATE(posC[-(int)m_width]); |
317 | 436k | } |
318 | 473k | } |
319 | | |
320 | 10.0M | #undef UPDATE |
321 | 10.0M | return m_tsLrg1FlagCtxSet(numPos); |
322 | 10.0M | } |
323 | | |
324 | | unsigned signCtxIdAbsTS(int scanPos, const TCoeffSig* coeff, int bdpcm) |
325 | 10.0M | { |
326 | 10.0M | const uint32_t posY = m_scan[scanPos].y; |
327 | 10.0M | const uint32_t posX = m_scan[scanPos].x; |
328 | 10.0M | const TCoeffSig* pData = coeff + posX + posY * m_width; |
329 | | |
330 | 10.0M | int rightSign = 0, belowSign = 0; |
331 | 10.0M | unsigned signCtx = 0; |
332 | | |
333 | 10.0M | if (posX > 0) |
334 | 9.04M | { |
335 | 9.04M | rightSign = pData[-1]; |
336 | 9.04M | } |
337 | 10.0M | if (posY > 0) |
338 | 8.54M | { |
339 | 8.54M | belowSign = pData[-(int)m_width]; |
340 | 8.54M | } |
341 | | |
342 | 10.0M | if ((rightSign == 0 && belowSign == 0) || ((rightSign*belowSign) < 0)) |
343 | 8.72M | { |
344 | 8.72M | signCtx = 0; |
345 | 8.72M | } |
346 | 1.30M | else if (rightSign >= 0 && belowSign >= 0) |
347 | 497 | { |
348 | 497 | signCtx = 1; |
349 | 497 | } |
350 | 1.30M | else |
351 | 1.30M | { |
352 | 1.30M | signCtx = 2; |
353 | 1.30M | } |
354 | 10.0M | if (bdpcm) |
355 | 9.55M | { |
356 | 9.55M | signCtx += 3; |
357 | 9.55M | } |
358 | 10.0M | return m_tsSignFlagCtxSet(signCtx); |
359 | 10.0M | } |
360 | | |
361 | | void neighTS(int& rightPixel, int& belowPixel, int scanPos, const TCoeffSig* coeff) |
362 | 14.3M | { |
363 | 14.3M | const uint32_t posY = m_scan[scanPos].y; |
364 | 14.3M | const uint32_t posX = m_scan[scanPos].x; |
365 | 14.3M | const TCoeffSig* data = coeff + posX + posY * m_width; |
366 | | |
367 | 14.3M | rightPixel = belowPixel = 0; |
368 | | |
369 | 14.3M | if (posX > 0) |
370 | 12.8M | { |
371 | 12.8M | rightPixel = data[-1]; |
372 | 12.8M | } |
373 | 14.3M | if (posY > 0) |
374 | 11.7M | { |
375 | 11.7M | belowPixel = data[-(int)m_width]; |
376 | 11.7M | } |
377 | 14.3M | } |
378 | | |
379 | | int deriveModCoeff(int rightPixel, int belowPixel, int absCoeff, int bdpcm = 0) |
380 | 7.48M | { |
381 | 7.48M | if (absCoeff == 0) |
382 | 3.66M | return 0; |
383 | | |
384 | 3.82M | int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel); |
385 | | |
386 | 3.82M | int absCoeffMod = absCoeff; |
387 | | |
388 | 3.82M | if (bdpcm == 0) |
389 | 503k | { |
390 | 503k | pred1 = std::max(absBelow, absRight); |
391 | | |
392 | 503k | if (absCoeff == pred1) |
393 | 0 | { |
394 | 0 | absCoeffMod = 1; |
395 | 0 | } |
396 | 503k | else |
397 | 503k | { |
398 | 503k | absCoeffMod = absCoeff < pred1 ? absCoeff + 1 : absCoeff; |
399 | 503k | } |
400 | 503k | } |
401 | | |
402 | 3.82M | return(absCoeffMod); |
403 | 7.48M | } |
404 | | |
405 | | int decDeriveModCoeff(int rightPixel, int belowPixel, int absCoeff) |
406 | 0 | { |
407 | 0 | if (absCoeff == 0) |
408 | 0 | return 0; |
409 | 0 |
|
410 | 0 | int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel); |
411 | 0 | pred1 = std::max(absBelow, absRight); |
412 | 0 |
|
413 | 0 | int absCoeffMod; |
414 | 0 |
|
415 | 0 | if (absCoeff == 1 && pred1 > 0) |
416 | 0 | { |
417 | 0 | absCoeffMod = pred1; |
418 | 0 | } |
419 | 0 | else |
420 | 0 | { |
421 | 0 | absCoeffMod = absCoeff - (absCoeff <= pred1); |
422 | 0 | } |
423 | 0 | return(absCoeffMod); |
424 | 0 | } |
425 | | |
426 | | //unsigned templateAbsSumTS( int scanPos, const TCoeffSig* coeff ) |
427 | | //{ |
428 | | // return 1; |
429 | | //} |
430 | | |
431 | | int remRegBins; |
432 | | |
433 | | private: |
434 | | // constant |
435 | | const ComponentID m_compID; |
436 | | const ChannelType m_chType; |
437 | | const unsigned m_width; |
438 | | const unsigned m_height; |
439 | | const unsigned m_log2CGWidth; |
440 | | const unsigned m_log2CGHeight; |
441 | | const unsigned m_log2CGSize; |
442 | | const unsigned m_widthInGroups; |
443 | | const unsigned m_heightInGroups; |
444 | | const unsigned m_log2WidthInGroups; |
445 | | const unsigned m_log2BlockWidth; |
446 | | const unsigned m_log2BlockHeight; |
447 | | const unsigned m_maxNumCoeff; |
448 | | const bool m_signHiding; |
449 | | const int m_maxLog2TrDynamicRange; |
450 | | const ScanElement * m_scan; |
451 | | const ScanElement * m_scanCG; |
452 | | const CtxSet m_CtxSetLastX; |
453 | | const CtxSet m_CtxSetLastY; |
454 | | const unsigned m_maxLastPosX; |
455 | | const unsigned m_maxLastPosY; |
456 | | const int m_lastOffsetX; |
457 | | const int m_lastOffsetY; |
458 | | const int m_lastShiftX; |
459 | | const int m_lastShiftY; |
460 | | // modified |
461 | | int m_scanPosLast; |
462 | | int m_subSetId; |
463 | | int m_subSetPos; |
464 | | int m_subSetPosX; |
465 | | int m_subSetPosY; |
466 | | int m_minSubPos; |
467 | | int m_maxSubPos; |
468 | | unsigned m_sigGroupCtxId; |
469 | | int m_tmplCpSum1; |
470 | | int m_tmplCpDiag; |
471 | | CtxSet m_sigFlagCtxSet[3]; |
472 | | CtxSet m_parFlagCtxSet; |
473 | | CtxSet m_gtxFlagCtxSet[2]; |
474 | | unsigned m_sigGroupCtxIdTS; |
475 | | CtxSet m_tsSigFlagCtxSet; |
476 | | CtxSet m_tsParFlagCtxSet; |
477 | | CtxSet m_tsGtxFlagCtxSet; |
478 | | CtxSet m_tsLrg1FlagCtxSet; |
479 | | CtxSet m_tsSignFlagCtxSet; |
480 | | std::bitset<MLS_GRP_NUM> m_sigCoeffGroupFlag; |
481 | | const bool m_bdpcm; |
482 | | CtxTpl* m_tplBuf; |
483 | | }; |
484 | | |
485 | | |
486 | | struct CUCtx |
487 | | { |
488 | 412k | CUCtx() : isDQPCoded(false), isChromaQpAdjCoded(false), |
489 | 412k | qgStart(false) |
490 | 412k | { |
491 | 412k | violatesLfnstConstrained[CH_L] = false; |
492 | 412k | violatesLfnstConstrained[CH_C] = false; |
493 | 412k | violatesMtsCoeffConstraint = false; |
494 | 412k | mtsLastScanPos = false; |
495 | 412k | lfnstLastScanPos = false; |
496 | 412k | } |
497 | 14.0k | CUCtx(int _qp) : isDQPCoded(false), isChromaQpAdjCoded(false), |
498 | 14.0k | qgStart(false), |
499 | 14.0k | qp(_qp) |
500 | 14.0k | { |
501 | 14.0k | violatesLfnstConstrained[CH_L] = false; |
502 | 14.0k | violatesLfnstConstrained[CH_C] = false; |
503 | 14.0k | violatesMtsCoeffConstraint = false; |
504 | 14.0k | mtsLastScanPos = false; |
505 | 14.0k | lfnstLastScanPos = false; |
506 | 14.0k | } |
507 | | |
508 | | bool isDQPCoded; |
509 | | bool isChromaQpAdjCoded; |
510 | | bool qgStart; |
511 | | bool lfnstLastScanPos; |
512 | | int8_t qp; // used as a previous(last) QP and for QP prediction |
513 | | bool violatesLfnstConstrained[MAX_NUM_CH]; |
514 | | bool violatesMtsCoeffConstraint; |
515 | | bool mtsLastScanPos; |
516 | | }; |
517 | | |
518 | | struct MergeCtx |
519 | | { |
520 | 563k | MergeCtx() : numValidMergeCand( 0 ), hasMergedCandList( false ) { for( unsigned i = 0; i < MRG_MAX_NUM_CANDS; i++ ) mrgTypeNeighbours[i] = MRG_TYPE_DEFAULT_N; } |
521 | | |
522 | | void setMmvdMergeCandiInfo ( CodingUnit& cu, const MmvdIdx candIdx) const; |
523 | | void setMergeInfo ( CodingUnit& cu, const int candIdx) const; |
524 | | void getMmvdDeltaMv ( const Slice& slice, const MmvdIdx candIdx, Mv deltaMv[NUM_REF_PIC_LIST_01] ) const; |
525 | | |
526 | | MvField mvFieldNeighbours [MRG_MAX_NUM_CANDS][NUM_REF_PIC_LIST_01]; |
527 | | uint8_t BcwIdx [MRG_MAX_NUM_CANDS]; |
528 | | unsigned char interDirNeighbours[MRG_MAX_NUM_CANDS]; |
529 | | MergeType mrgTypeNeighbours [MRG_MAX_NUM_CANDS]; |
530 | | int numValidMergeCand; |
531 | | bool hasMergedCandList; |
532 | | |
533 | | MvField mmvdBaseMv [MMVD_BASE_MV_NUM][NUM_REF_PIC_LIST_01]; |
534 | | bool mmvdUseAltHpelIf [MMVD_BASE_MV_NUM]; |
535 | | bool useAltHpelIf [MRG_MAX_NUM_CANDS]; |
536 | | }; |
537 | | |
538 | | struct AffineMergeCtx |
539 | | { |
540 | 0 | AffineMergeCtx() : numValidMergeCand( 0 ) { for ( unsigned i = 0; i < AFFINE_MRG_MAX_NUM_CANDS; i++ ) affineType[i] = AFFINEMODEL_4PARAM; } |
541 | | |
542 | | MvField mvFieldNeighbours [AFFINE_MRG_MAX_NUM_CANDS][NUM_REF_PIC_LIST_01][3]; |
543 | | unsigned char interDirNeighbours[AFFINE_MRG_MAX_NUM_CANDS]; |
544 | | EAffineModel affineType [AFFINE_MRG_MAX_NUM_CANDS]; |
545 | | uint8_t BcwIdx [AFFINE_MRG_MAX_NUM_CANDS]; |
546 | | int numValidMergeCand; |
547 | | int maxNumMergeCand; |
548 | | |
549 | | MergeType mergeType[AFFINE_MRG_MAX_NUM_CANDS]; |
550 | | MotionBuf subPuMvpMiBuf; |
551 | | }; |
552 | | |
553 | | |
554 | | struct DeriveCtx |
555 | | { |
556 | | const CodingUnit* cuRestrictedLeft[MAX_NUM_CH]; |
557 | | const CodingUnit* cuRestrictedAbove[MAX_NUM_CH]; |
558 | | |
559 | | void determineNeighborCus ( const CodingStructure& cs, const UnitArea& ua, const ChannelType ch, const TreeType treeType ); |
560 | | |
561 | 3.48M | inline static unsigned CtxQtCbf ( const ComponentID compID, const bool prevCbf = false, const int ispIdx = 0 ) { return ( ispIdx && isLuma( compID ) ) ? (2 + (int)prevCbf) : (((compID == COMP_Cr) && prevCbf) ? 1 : 0); } |
562 | | void CtxSplit ( const Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, const bool canSplit[6] ) const; |
563 | | unsigned CtxMipFlag ( const CodingUnit& cu ) const; |
564 | 0 | unsigned CtxInterDir ( const CodingUnit& cu ) const { return ( 7 - ((Log2(cu.lumaSize().area()) + 1) >> 1) ); } |
565 | | |
566 | | unsigned CtxModeConsFlag() const |
567 | 0 | { |
568 | 0 | const CodingUnit* cuLeft = cuRestrictedLeft[CH_L]; const CodingUnit* cuAbove = cuRestrictedAbove[CH_L]; |
569 | 0 | return ((cuAbove && cuAbove->predMode == MODE_INTRA) || (cuLeft && cuLeft->predMode == MODE_INTRA)) ? 1 : 0; |
570 | 0 | } |
571 | | |
572 | | unsigned CtxAffineFlag() const |
573 | 0 | { |
574 | 0 | const CodingUnit *cuLeft = cuRestrictedLeft[CH_L]; const CodingUnit *cuAbove = cuRestrictedAbove[CH_L]; |
575 | 0 | return (( cuLeft && cuLeft->affine ) ? 1 : 0) + (( cuAbove && cuAbove->affine ) ? 1 : 0); |
576 | 0 | } |
577 | | |
578 | | unsigned CtxSkipFlag() const |
579 | 89.4k | { |
580 | 89.4k | const CodingUnit *cuLeft = cuRestrictedLeft[CH_L]; const CodingUnit *cuAbove = cuRestrictedAbove[CH_L]; |
581 | 89.4k | return (( cuLeft && cuLeft->skip ) ? 1 : 0) + (( cuAbove && cuAbove->skip ) ? 1 : 0); |
582 | 89.4k | } |
583 | | |
584 | | unsigned CtxPredModeFlag() const |
585 | 0 | { |
586 | 0 | const CodingUnit *cuLeft = cuRestrictedLeft[CH_L]; const CodingUnit *cuAbove = cuRestrictedAbove[CH_L]; |
587 | 0 | return ((cuAbove && cuAbove->predMode == MODE_INTRA) || (cuLeft && cuLeft->predMode == MODE_INTRA)) ? 1 : 0; |
588 | 0 | } |
589 | | |
590 | | unsigned CtxIBCFlag(const CodingUnit& cu) const |
591 | 262k | { |
592 | 262k | const CodingUnit *cuLeft = cuRestrictedLeft[cu.chType]; const CodingUnit *cuAbove = cuRestrictedAbove[cu.chType]; |
593 | 262k | return ((cuLeft && cuLeft->predMode == MODE_IBC) ? 1 : 0) + ((cuAbove && cuAbove->predMode == MODE_IBC) ? 1 : 0); |
594 | 262k | } |
595 | | |
596 | | }; |
597 | | |
598 | | } // namespace vvenc |
599 | | |
600 | | //! \} |
601 | | |