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