/src/vvenc/source/Lib/CommonLib/DepQuant.cpp
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 | | |
43 | | #include "DepQuant.h" |
44 | | #include "TrQuant.h" |
45 | | #include "CodingStructure.h" |
46 | | #include "UnitTools.h" |
47 | | |
48 | | #include <bitset> |
49 | | |
50 | | //! \ingroup CommonLib |
51 | | //! \{ |
52 | | |
53 | | namespace vvenc { |
54 | | |
55 | | |
56 | | namespace DQIntern |
57 | | { |
58 | | void Rom::xInitScanArrays() |
59 | 0 | { |
60 | 0 | if( m_scansInitialized ) |
61 | 0 | { |
62 | 0 | return; |
63 | 0 | } |
64 | 0 | ::memset( m_scanId2NbInfoSbbArray, 0, sizeof(m_scanId2NbInfoSbbArray) ); |
65 | 0 | ::memset( m_scanId2NbInfoOutArray, 0, sizeof(m_scanId2NbInfoOutArray) ); |
66 | 0 | ::memset( m_tuParameters, 0, sizeof(m_tuParameters) ); |
67 | |
|
68 | 0 | uint32_t raster2id[ MAX_CU_SIZE * MAX_CU_SIZE ]; |
69 | 0 | ::memset(raster2id, 0, sizeof(raster2id)); |
70 | |
|
71 | 0 | for( int hd = 0; hd < MAX_TU_SIZE_IDX; hd++ ) |
72 | 0 | { |
73 | 0 | for( int vd = 0; vd < MAX_TU_SIZE_IDX; vd++ ) |
74 | 0 | { |
75 | 0 | if( (hd == 0 && vd <= 1) || (hd <= 1 && vd == 0) ) |
76 | 0 | { |
77 | 0 | continue; |
78 | 0 | } |
79 | 0 | const uint32_t blockWidth = (1 << hd); |
80 | 0 | const uint32_t blockHeight = (1 << vd); |
81 | 0 | const uint32_t log2CGWidth = g_log2SbbSize[hd][vd][0]; |
82 | 0 | const uint32_t log2CGHeight = g_log2SbbSize[hd][vd][1]; |
83 | 0 | const uint32_t groupWidth = 1 << log2CGWidth; |
84 | 0 | const uint32_t groupHeight = 1 << log2CGHeight; |
85 | 0 | const uint32_t groupSize = groupWidth * groupHeight; |
86 | 0 | const SizeType blkWidthIdx = Log2( blockWidth ); |
87 | 0 | const SizeType blkHeightIdx = Log2( blockHeight ); |
88 | 0 | const ScanElement * scanId2RP = getScanOrder( SCAN_GROUPED_4x4, blkWidthIdx, blkHeightIdx ); |
89 | 0 | NbInfoSbb*& sId2NbSbb = m_scanId2NbInfoSbbArray[hd][vd]; |
90 | 0 | NbInfoOut*& sId2NbOut = m_scanId2NbInfoOutArray[hd][vd]; |
91 | | // consider only non-zero-out region |
92 | 0 | const uint32_t blkWidthNZOut = std::min<unsigned>( JVET_C0024_ZERO_OUT_TH, blockWidth ); |
93 | 0 | const uint32_t blkHeightNZOut= std::min<unsigned>( JVET_C0024_ZERO_OUT_TH, blockHeight ); |
94 | 0 | const uint32_t totalValues = blkWidthNZOut * blkHeightNZOut; |
95 | |
|
96 | 0 | sId2NbSbb = new NbInfoSbb[ totalValues ]; |
97 | 0 | sId2NbOut = new NbInfoOut[ totalValues ]; |
98 | |
|
99 | 0 | for( uint32_t scanId = 0; scanId < totalValues; scanId++ ) |
100 | 0 | { |
101 | 0 | raster2id[scanId2RP[scanId].idx] = scanId; |
102 | 0 | sId2NbSbb[scanId].numInv = 0; |
103 | 0 | } |
104 | |
|
105 | 0 | for( unsigned scanId = 0; scanId < totalValues; scanId++ ) |
106 | 0 | { |
107 | 0 | const int posX = scanId2RP[scanId].x; |
108 | 0 | const int posY = scanId2RP[scanId].y; |
109 | 0 | const int rpos = scanId2RP[scanId].idx; |
110 | 0 | { |
111 | | //===== inside subband neighbours ===== |
112 | 0 | const int begSbb = scanId - ( scanId & (groupSize-1) ); // first pos in current subblock |
113 | 0 | int cpos[5]; |
114 | |
|
115 | 0 | cpos[0] = ( posX + 1 < blkWidthNZOut ? ( raster2id[rpos+1 ] < groupSize + begSbb ? raster2id[rpos+1 ] - begSbb : 0 ) : 0 ); |
116 | 0 | cpos[1] = ( posX + 2 < blkWidthNZOut ? ( raster2id[rpos+2 ] < groupSize + begSbb ? raster2id[rpos+2 ] - begSbb : 0 ) : 0 ); |
117 | 0 | cpos[2] = ( posX + 1 < blkWidthNZOut && posY + 1 < blkHeightNZOut ? ( raster2id[rpos+1+blockWidth] < groupSize + begSbb ? raster2id[rpos+1+blockWidth] - begSbb : 0 ) : 0 ); |
118 | 0 | cpos[3] = ( posY + 1 < blkHeightNZOut ? ( raster2id[rpos+ blockWidth] < groupSize + begSbb ? raster2id[rpos+ blockWidth] - begSbb : 0 ) : 0 ); |
119 | 0 | cpos[4] = ( posY + 2 < blkHeightNZOut ? ( raster2id[rpos+2*blockWidth] < groupSize + begSbb ? raster2id[rpos+2*blockWidth] - begSbb : 0 ) : 0 ); |
120 | |
|
121 | 0 | int num = 0; |
122 | 0 | int inPos[5] = { 0, }; |
123 | |
|
124 | 0 | while( true ) |
125 | 0 | { |
126 | 0 | int nk = -1; |
127 | 0 | for( int k = 0; k < 5; k++ ) |
128 | 0 | { |
129 | 0 | if( cpos[k] != 0 && ( nk < 0 || cpos[k] < cpos[nk] ) ) |
130 | 0 | { |
131 | 0 | nk = k; |
132 | 0 | } |
133 | 0 | } |
134 | 0 | if( nk < 0 ) |
135 | 0 | { |
136 | 0 | break; |
137 | 0 | } |
138 | 0 | inPos[ num++ ] = uint8_t( cpos[nk] ); |
139 | 0 | cpos[nk] = 0; |
140 | 0 | } |
141 | 0 | for( int k = num; k < 5; k++ ) |
142 | 0 | { |
143 | 0 | inPos[k] = 0; |
144 | 0 | } |
145 | 0 | for( int k = 0; k < num; k++ ) |
146 | 0 | { |
147 | 0 | CHECK( sId2NbSbb[begSbb + inPos[k]].numInv >= 5, "" ); |
148 | 0 | sId2NbSbb[begSbb + inPos[k]].invInPos[sId2NbSbb[begSbb + inPos[k]].numInv++] = scanId & ( groupSize - 1 ); |
149 | 0 | } |
150 | 0 | } |
151 | 0 | { |
152 | | //===== outside subband neighbours ===== |
153 | 0 | NbInfoOut& nbOut = sId2NbOut[ scanId ]; |
154 | 0 | const int begSbb = scanId - ( scanId & (groupSize-1) ); // first pos in current subblock |
155 | 0 | int cpos[5]; |
156 | |
|
157 | 0 | cpos[0] = ( posX + 1 < blkWidthNZOut ? ( raster2id[rpos+1 ] >= groupSize + begSbb ? raster2id[rpos+1 ] : 0 ) : 0 ); |
158 | 0 | cpos[1] = ( posX + 2 < blkWidthNZOut ? ( raster2id[rpos+2 ] >= groupSize + begSbb ? raster2id[rpos+2 ] : 0 ) : 0 ); |
159 | 0 | cpos[2] = ( posX + 1 < blkWidthNZOut && posY + 1 < blkHeightNZOut ? ( raster2id[rpos+1+blockWidth] >= groupSize + begSbb ? raster2id[rpos+1+blockWidth] : 0 ) : 0 ); |
160 | 0 | cpos[3] = ( posY + 1 < blkHeightNZOut ? ( raster2id[rpos+ blockWidth] >= groupSize + begSbb ? raster2id[rpos+ blockWidth] : 0 ) : 0 ); |
161 | 0 | cpos[4] = ( posY + 2 < blkHeightNZOut ? ( raster2id[rpos+2*blockWidth] >= groupSize + begSbb ? raster2id[rpos+2*blockWidth] : 0 ) : 0 ); |
162 | |
|
163 | 0 | for( nbOut.num = 0; true; ) |
164 | 0 | { |
165 | 0 | int nk = -1; |
166 | 0 | for( int k = 0; k < 5; k++ ) |
167 | 0 | { |
168 | 0 | if( cpos[k] != 0 && ( nk < 0 || cpos[k] < cpos[nk] ) ) |
169 | 0 | { |
170 | 0 | nk = k; |
171 | 0 | } |
172 | 0 | } |
173 | 0 | if( nk < 0 ) |
174 | 0 | { |
175 | 0 | break; |
176 | 0 | } |
177 | 0 | nbOut.outPos[ nbOut.num++ ] = uint16_t( cpos[nk] ); |
178 | 0 | cpos[nk] = 0; |
179 | 0 | } |
180 | 0 | for( int k = nbOut.num; k < 5; k++ ) |
181 | 0 | { |
182 | 0 | nbOut.outPos[k] = 0; |
183 | 0 | } |
184 | 0 | nbOut.maxDist = ( scanId == 0 ? 0 : sId2NbOut[scanId-1].maxDist ); |
185 | 0 | for( int k = 0; k < nbOut.num; k++ ) |
186 | 0 | { |
187 | 0 | if( nbOut.outPos[k] > nbOut.maxDist ) |
188 | 0 | { |
189 | 0 | nbOut.maxDist = nbOut.outPos[k]; |
190 | 0 | } |
191 | 0 | } |
192 | 0 | } |
193 | 0 | } |
194 | | |
195 | | // make it relative |
196 | 0 | for( unsigned scanId = 0; scanId < totalValues; scanId++ ) |
197 | 0 | { |
198 | 0 | NbInfoOut& nbOut = sId2NbOut[scanId]; |
199 | 0 | const int begSbb = scanId - ( scanId & (groupSize-1) ); // first pos in current subblock |
200 | 0 | for( int k = 0; k < nbOut.num; k++ ) |
201 | 0 | { |
202 | 0 | CHECK(begSbb > nbOut.outPos[k], "Position must be past sub block begin"); |
203 | 0 | nbOut.outPos[k] -= begSbb; |
204 | 0 | } |
205 | 0 | nbOut.maxDist -= scanId; |
206 | 0 | } |
207 | | |
208 | 0 | for( int chId = 0; chId < MAX_NUM_CH; chId++ ) |
209 | 0 | { |
210 | 0 | m_tuParameters[hd][vd][chId] = new TUParameters( *this, blockWidth, blockHeight, ChannelType(chId) ); |
211 | 0 | } |
212 | 0 | } |
213 | 0 | } |
214 | 0 | m_scansInitialized = true; |
215 | 0 | } |
216 | | |
217 | | void Rom::xUninitScanArrays() |
218 | 0 | { |
219 | 0 | if( !m_scansInitialized ) |
220 | 0 | { |
221 | 0 | return; |
222 | 0 | } |
223 | 0 | for( int hd = 0; hd < MAX_TU_SIZE_IDX; hd++ ) |
224 | 0 | { |
225 | 0 | for( int vd = 0; vd < MAX_TU_SIZE_IDX; vd++ ) |
226 | 0 | { |
227 | 0 | NbInfoSbb*& sId2NbSbb = m_scanId2NbInfoSbbArray[hd][vd]; |
228 | 0 | NbInfoOut*& sId2NbOut = m_scanId2NbInfoOutArray[hd][vd]; |
229 | 0 | if( sId2NbSbb ) |
230 | 0 | { |
231 | 0 | delete [] sId2NbSbb; |
232 | 0 | } |
233 | 0 | if( sId2NbOut ) |
234 | 0 | { |
235 | 0 | delete [] sId2NbOut; |
236 | 0 | } |
237 | 0 | for( int chId = 0; chId < MAX_NUM_CH; chId++ ) |
238 | 0 | { |
239 | 0 | TUParameters*& tuPars = m_tuParameters[hd][vd][chId]; |
240 | 0 | if( tuPars ) |
241 | 0 | { |
242 | 0 | delete tuPars; |
243 | 0 | } |
244 | 0 | } |
245 | 0 | } |
246 | 0 | } |
247 | 0 | m_scansInitialized = false; |
248 | 0 | } |
249 | | |
250 | | |
251 | | TUParameters::TUParameters( const Rom& rom, const unsigned width, const unsigned height, const ChannelType chType ) |
252 | 0 | { |
253 | 0 | m_chType = chType; |
254 | 0 | m_width = width; |
255 | 0 | m_height = height; |
256 | 0 | const uint32_t nonzeroWidth = std::min<uint32_t>(JVET_C0024_ZERO_OUT_TH, m_width); |
257 | 0 | const uint32_t nonzeroHeight = std::min<uint32_t>(JVET_C0024_ZERO_OUT_TH, m_height); |
258 | 0 | m_numCoeff = nonzeroWidth * nonzeroHeight; |
259 | 0 | m_log2SbbWidth = g_log2SbbSize[ Log2(m_width) ][ Log2(m_height) ][0]; |
260 | 0 | m_log2SbbHeight = g_log2SbbSize[ Log2(m_width) ][ Log2(m_height) ][1]; |
261 | 0 | m_log2SbbSize = m_log2SbbWidth + m_log2SbbHeight; |
262 | 0 | m_sbbSize = ( 1 << m_log2SbbSize ); |
263 | 0 | m_sbbMask = m_sbbSize - 1; |
264 | 0 | m_widthInSbb = nonzeroWidth >> m_log2SbbWidth; |
265 | 0 | m_heightInSbb = nonzeroHeight >> m_log2SbbHeight; |
266 | 0 | m_numSbb = m_widthInSbb * m_heightInSbb; |
267 | 0 | SizeType hsbb = Log2( m_widthInSbb ); |
268 | 0 | SizeType vsbb = Log2( m_heightInSbb ); |
269 | 0 | SizeType hsId = Log2( m_width ); |
270 | 0 | SizeType vsId = Log2( m_height ); |
271 | 0 | m_scanSbbId2SbbPos = getScanOrder( SCAN_UNGROUPED , hsbb , vsbb ); |
272 | 0 | m_scanId2BlkPos = getScanOrder( SCAN_GROUPED_4x4 , hsId , vsId ); |
273 | 0 | int log2W = Log2( m_width ); |
274 | 0 | int log2H = Log2( m_height ); |
275 | 0 | m_scanId2NbInfoSbb = rom.getNbInfoSbb( log2W, log2H ); |
276 | 0 | m_scanId2NbInfoOut = rom.getNbInfoOut( log2W, log2H ); |
277 | 0 | m_scanInfo = new ScanInfo[ m_numCoeff ]; |
278 | 0 | for( int scanIdx = 0; scanIdx < m_numCoeff; scanIdx++ ) |
279 | 0 | { |
280 | 0 | xSetScanInfo( m_scanInfo[scanIdx], scanIdx ); |
281 | 0 | } |
282 | 0 | } |
283 | | |
284 | | |
285 | | void TUParameters::xSetScanInfo( ScanInfo& scanInfo, int scanIdx ) |
286 | 0 | { |
287 | 0 | scanInfo.sbbSize = m_sbbSize; |
288 | 0 | scanInfo.numSbb = m_numSbb; |
289 | 0 | scanInfo.scanIdx = scanIdx; |
290 | 0 | scanInfo.rasterPos = m_scanId2BlkPos[scanIdx].idx; |
291 | 0 | scanInfo.sbbPos = m_scanSbbId2SbbPos[scanIdx >> m_log2SbbSize].idx; |
292 | 0 | scanInfo.insidePos = scanIdx & m_sbbMask; |
293 | 0 | scanInfo.spt = SCAN_ISCSBB; |
294 | 0 | if( scanInfo.insidePos == m_sbbMask && scanIdx > scanInfo.sbbSize && scanIdx < m_numCoeff - 1 ) |
295 | 0 | scanInfo.spt = SCAN_SOCSBB; |
296 | 0 | else if( scanInfo.insidePos == 0 && scanIdx > 0 && scanIdx < m_numCoeff - m_sbbSize ) |
297 | 0 | scanInfo.spt = SCAN_EOCSBB; |
298 | 0 | scanInfo.posX = m_scanId2BlkPos[scanIdx].x; |
299 | 0 | scanInfo.posY = m_scanId2BlkPos[scanIdx].y; |
300 | 0 | if( scanIdx ) |
301 | 0 | { |
302 | 0 | const int nextScanIdx = scanIdx - 1; |
303 | 0 | const int diag = m_scanId2BlkPos[nextScanIdx].x + m_scanId2BlkPos[nextScanIdx].y; |
304 | 0 | if( m_chType == CH_L ) |
305 | 0 | { |
306 | 0 | scanInfo.sigCtxOffsetNext = ( diag < 2 ? 8 : diag < 5 ? 4 : 0 ); |
307 | 0 | scanInfo.gtxCtxOffsetNext = ( diag < 1 ? 16 : diag < 3 ? 11 : diag < 10 ? 6 : 1 ); |
308 | 0 | } |
309 | 0 | else |
310 | 0 | { |
311 | 0 | scanInfo.sigCtxOffsetNext = ( diag < 2 ? 4 : 0 ); |
312 | 0 | scanInfo.gtxCtxOffsetNext = ( diag < 1 ? 6 : 1 ); |
313 | 0 | } |
314 | 0 | scanInfo.nextInsidePos = nextScanIdx & m_sbbMask; |
315 | 0 | scanInfo.currNbInfoSbb = m_scanId2NbInfoSbb[ scanIdx ]; |
316 | 0 | if( scanInfo.insidePos == 0 ) |
317 | 0 | { |
318 | 0 | const int nextSbbPos = m_scanSbbId2SbbPos[nextScanIdx >> m_log2SbbSize].idx; |
319 | 0 | const int nextSbbPosY = nextSbbPos / m_widthInSbb; |
320 | 0 | const int nextSbbPosX = nextSbbPos - nextSbbPosY * m_widthInSbb; |
321 | 0 | scanInfo.nextSbbRight = ( nextSbbPosX < m_widthInSbb - 1 ? nextSbbPos + 1 : 0 ); |
322 | 0 | scanInfo.nextSbbBelow = ( nextSbbPosY < m_heightInSbb - 1 ? nextSbbPos + m_widthInSbb : 0 ); |
323 | 0 | } |
324 | 0 | } |
325 | 0 | } |
326 | | |
327 | | void RateEstimator::initCtx( const TUParameters& tuPars, const TransformUnit& tu, const ComponentID compID, const FracBitsAccess& fracBitsAccess ) |
328 | 0 | { |
329 | 0 | m_scanId2Pos = tuPars.m_scanId2BlkPos; |
330 | 0 | xSetSigSbbFracBits ( fracBitsAccess, tuPars.m_chType ); |
331 | 0 | xSetSigFlagBits ( fracBitsAccess, tuPars.m_chType ); |
332 | 0 | xSetGtxFlagBits ( fracBitsAccess, tuPars.m_chType ); |
333 | 0 | xSetLastCoeffOffset ( fracBitsAccess, tuPars, tu, compID ); |
334 | 0 | } |
335 | | |
336 | | void RateEstimator::xSetLastCoeffOffset( const FracBitsAccess& fracBitsAccess, const TUParameters& tuPars, const TransformUnit& tu, const ComponentID compID ) |
337 | 0 | { |
338 | 0 | const ChannelType chType = ( compID == COMP_Y ? CH_L : CH_C ); |
339 | 0 | int32_t cbfDeltaBits = 0; |
340 | 0 | if( compID == COMP_Y && !CU::isIntra(*tu.cu) && !tu.depth ) |
341 | 0 | { |
342 | 0 | const BinFracBits bits = fracBitsAccess.getFracBitsArray( Ctx::QtRootCbf() ); |
343 | 0 | cbfDeltaBits = int32_t( bits.intBits[1] ) - int32_t( bits.intBits[0] ); |
344 | 0 | } |
345 | 0 | else |
346 | 0 | { |
347 | 0 | BinFracBits bits; |
348 | 0 | bool prevLumaCbf = false; |
349 | 0 | bool lastCbfIsInferred = false; |
350 | 0 | bool useIntraSubPartitions = tu.cu->ispMode && isLuma(chType); |
351 | 0 | if( useIntraSubPartitions ) |
352 | 0 | { |
353 | 0 | bool rootCbfSoFar = false; |
354 | 0 | bool isLastSubPartition = CU::isISPLast(*tu.cu, tu.Y(), compID); |
355 | 0 | uint32_t nTus = tu.cu->ispMode == HOR_INTRA_SUBPARTITIONS ? tu.cu->lheight() >> Log2(tu.lheight()) : tu.cu->lwidth() >> Log2(tu.lwidth()); |
356 | 0 | if( isLastSubPartition ) |
357 | 0 | { |
358 | 0 | TransformUnit* tuPointer = tu.cu->firstTU; |
359 | 0 | for( int tuIdx = 0; tuIdx < nTus - 1; tuIdx++ ) |
360 | 0 | { |
361 | 0 | rootCbfSoFar |= TU::getCbfAtDepth(*tuPointer, COMP_Y, tu.depth); |
362 | 0 | tuPointer = tuPointer->next; |
363 | 0 | } |
364 | 0 | if( !rootCbfSoFar ) |
365 | 0 | { |
366 | 0 | lastCbfIsInferred = true; |
367 | 0 | } |
368 | 0 | } |
369 | 0 | if( !lastCbfIsInferred ) |
370 | 0 | { |
371 | 0 | prevLumaCbf = TU::getPrevTuCbfAtDepth(tu, compID, tu.depth); |
372 | 0 | } |
373 | 0 | bits = fracBitsAccess.getFracBitsArray(Ctx::QtCbf[compID](DeriveCtx::CtxQtCbf(compID, prevLumaCbf, true))); |
374 | 0 | } |
375 | 0 | else |
376 | 0 | { |
377 | 0 | bits = fracBitsAccess.getFracBitsArray(Ctx::QtCbf[compID](DeriveCtx::CtxQtCbf(compID, tu.cbf[COMP_Cb]))); |
378 | 0 | } |
379 | 0 | cbfDeltaBits = lastCbfIsInferred ? 0 : int32_t(bits.intBits[1]) - int32_t(bits.intBits[0]); |
380 | 0 | } |
381 | |
|
382 | 0 | static const unsigned prefixCtx[] = { 0, 0, 0, 3, 6, 10, 15, 21 }; |
383 | 0 | uint32_t ctxBits [ LAST_SIGNIFICANT_GROUPS ]; |
384 | 0 | for( unsigned xy = 0; xy < 2; xy++ ) |
385 | 0 | { |
386 | 0 | int32_t bitOffset = ( xy ? cbfDeltaBits : 0 ); |
387 | 0 | int32_t* lastBits = ( xy ? m_lastBitsY : m_lastBitsX ); |
388 | 0 | const unsigned size = ( xy ? tuPars.m_height : tuPars.m_width ); |
389 | 0 | const unsigned log2Size = Log2( size ); |
390 | 0 | const bool useYCtx = ( xy != 0 ); |
391 | 0 | const CtxSet& ctxSetLast = ( useYCtx ? Ctx::LastY : Ctx::LastX )[ chType ]; |
392 | 0 | const unsigned lastShift = ( compID == COMP_Y ? (log2Size+1)>>2 : Clip3<unsigned>(0,2,size>>3) ); |
393 | 0 | const unsigned lastOffset = ( compID == COMP_Y ? ( prefixCtx[log2Size] ) : 0 ); |
394 | 0 | uint32_t sumFBits = 0; |
395 | 0 | unsigned maxCtxId = g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, size) - 1]; |
396 | 0 | for( unsigned ctxId = 0; ctxId < maxCtxId; ctxId++ ) |
397 | 0 | { |
398 | 0 | const BinFracBits bits = fracBitsAccess.getFracBitsArray( ctxSetLast( lastOffset + ( ctxId >> lastShift ) ) ); |
399 | 0 | ctxBits[ ctxId ] = sumFBits + bits.intBits[0] + ( ctxId>3 ? ((ctxId-2)>>1)<<SCALE_BITS : 0 ) + bitOffset; |
400 | 0 | sumFBits += bits.intBits[1]; |
401 | 0 | } |
402 | 0 | ctxBits [ maxCtxId ] = sumFBits + ( maxCtxId>3 ? ((maxCtxId-2)>>1)<<SCALE_BITS : 0 ) + bitOffset; |
403 | 0 | for (unsigned pos = 0; pos < std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, size); pos++) |
404 | 0 | { |
405 | 0 | lastBits[ pos ] = ctxBits[ g_uiGroupIdx[ pos ] ]; |
406 | 0 | } |
407 | 0 | } |
408 | 0 | } |
409 | | |
410 | | void RateEstimator::xSetSigSbbFracBits( const FracBitsAccess& fracBitsAccess, ChannelType chType ) |
411 | 0 | { |
412 | 0 | const CtxSet& ctxSet = Ctx::SigCoeffGroup[ chType ]; |
413 | 0 | for( unsigned ctxId = 0; ctxId < sm_maxNumSigSbbCtx; ctxId++ ) |
414 | 0 | { |
415 | 0 | m_sigSbbFracBits[ ctxId ] = fracBitsAccess.getFracBitsArray( ctxSet( ctxId ) ); |
416 | 0 | } |
417 | 0 | } |
418 | | |
419 | | void RateEstimator::xSetSigFlagBits( const FracBitsAccess& fracBitsAccess, ChannelType chType ) |
420 | 0 | { |
421 | 0 | for( unsigned ctxSetId = 0; ctxSetId < sm_numCtxSetsSig; ctxSetId++ ) |
422 | 0 | { |
423 | 0 | BinFracBits* bits = m_sigFracBits [ ctxSetId ]; |
424 | 0 | const CtxSet& ctxSet = Ctx::SigFlag [ chType + 2*ctxSetId ]; |
425 | 0 | const unsigned numCtx = ( chType == CH_L ? 12 : 8 ); |
426 | 0 | for( unsigned ctxId = 0; ctxId < numCtx; ctxId++ ) |
427 | 0 | { |
428 | 0 | bits[ ctxId ] = fracBitsAccess.getFracBitsArray( ctxSet( ctxId ) ); |
429 | 0 | } |
430 | 0 | } |
431 | 0 | } |
432 | | |
433 | | void RateEstimator::xSetGtxFlagBits( const FracBitsAccess& fracBitsAccess, ChannelType chType ) |
434 | 0 | { |
435 | 0 | const CtxSet& ctxSetPar = Ctx::ParFlag [ chType ]; |
436 | 0 | const CtxSet& ctxSetGt1 = Ctx::GtxFlag [ 2 + chType ]; |
437 | 0 | const CtxSet& ctxSetGt2 = Ctx::GtxFlag [ chType ]; |
438 | 0 | const unsigned numCtx = ( chType == CH_L ? 21 : 11 ); |
439 | 0 | for( unsigned ctxId = 0; ctxId < numCtx; ctxId++ ) |
440 | 0 | { |
441 | 0 | BinFracBits fbPar = fracBitsAccess.getFracBitsArray( ctxSetPar( ctxId ) ); |
442 | 0 | BinFracBits fbGt1 = fracBitsAccess.getFracBitsArray( ctxSetGt1( ctxId ) ); |
443 | 0 | BinFracBits fbGt2 = fracBitsAccess.getFracBitsArray( ctxSetGt2( ctxId ) ); |
444 | 0 | CoeffFracBits& cb = m_gtxFracBits[ ctxId ]; |
445 | 0 | int32_t par0 = (1<<SCALE_BITS) + int32_t(fbPar.intBits[0]); |
446 | 0 | int32_t par1 = (1<<SCALE_BITS) + int32_t(fbPar.intBits[1]); |
447 | 0 | cb.bits[0] = 0; |
448 | 0 | cb.bits[1] = fbGt1.intBits[0] + (1 << SCALE_BITS); |
449 | 0 | cb.bits[2] = fbGt1.intBits[1] + par0 + fbGt2.intBits[0]; |
450 | 0 | cb.bits[3] = fbGt1.intBits[1] + par1 + fbGt2.intBits[0]; |
451 | 0 | cb.bits[4] = fbGt1.intBits[1] + par0 + fbGt2.intBits[1]; |
452 | 0 | cb.bits[5] = fbGt1.intBits[1] + par1 + fbGt2.intBits[1]; |
453 | 0 | } |
454 | 0 | } |
455 | | |
456 | | void CommonCtx::update( const ScanInfo& scanInfo, const int prevId, int stateId, StateMem& curr ) |
457 | 0 | { |
458 | 0 | uint8_t* sbbFlags = m_currSbbCtx[stateId].sbbFlags; |
459 | 0 | uint8_t* levels = m_currSbbCtx[stateId].levels; |
460 | 0 | uint16_t maxDist = m_nbInfo[scanInfo.scanIdx - 1].maxDist; |
461 | 0 | uint16_t sbbSize = scanInfo.sbbSize; |
462 | 0 | std::size_t setCpSize = ( maxDist > sbbSize ? maxDist - sbbSize : 0 ) * sizeof( uint8_t ); |
463 | 0 | if( prevId >= 0 ) |
464 | 0 | { |
465 | 0 | ::memcpy( sbbFlags, m_prevSbbCtx[prevId].sbbFlags, scanInfo.numSbb * sizeof( uint8_t ) ); |
466 | 0 | ::memcpy( levels + scanInfo.scanIdx + sbbSize, m_prevSbbCtx[prevId].levels + scanInfo.scanIdx + sbbSize, setCpSize ); |
467 | 0 | } |
468 | 0 | else |
469 | 0 | { |
470 | 0 | ::memset( sbbFlags, 0, scanInfo.numSbb * sizeof( uint8_t ) ); |
471 | 0 | ::memset( levels + scanInfo.scanIdx + sbbSize, 0, setCpSize ); |
472 | 0 | } |
473 | 0 | sbbFlags[scanInfo.sbbPos] = !!curr.numSig[stateId]; |
474 | |
|
475 | 0 | const int sigNSbb = ( ( scanInfo.nextSbbRight ? sbbFlags[scanInfo.nextSbbRight] : false ) || ( scanInfo.nextSbbBelow ? sbbFlags[scanInfo.nextSbbBelow] : false ) ? 1 : 0 ); |
476 | 0 | curr.refSbbCtxId[stateId] = stateId; |
477 | 0 | const BinFracBits sbbBits = m_sbbFlagBits[sigNSbb]; |
478 | |
|
479 | 0 | curr.sbbBits0[stateId] = sbbBits.intBits[0]; |
480 | 0 | curr.sbbBits1[stateId] = sbbBits.intBits[1]; |
481 | |
|
482 | 0 | if( sigNSbb || ( ( scanInfo.nextSbbRight && scanInfo.nextSbbBelow ) ? sbbFlags[scanInfo.nextSbbBelow + 1] : false ) ) |
483 | 0 | { |
484 | 0 | const int scanBeg = scanInfo.scanIdx - scanInfo.sbbSize; |
485 | 0 | const NbInfoOut* nbOut = m_nbInfo + scanBeg; |
486 | 0 | const uint8_t* absLevels = levels + scanBeg; |
487 | |
|
488 | 0 | for( int id = 0; id < scanInfo.sbbSize; id++, nbOut++ ) |
489 | 0 | { |
490 | 0 | if( nbOut->num ) |
491 | 0 | { |
492 | 0 | TCoeff sumAbs = 0, sumAbs1 = 0, sumNum = 0; |
493 | 0 | #define UPDATE(k) {TCoeff t=absLevels[nbOut->outPos[k]]; sumAbs+=t; sumAbs1+=std::min<TCoeff>(4+(t&1),t); sumNum+=!!t; } |
494 | 0 | switch( nbOut->num ) |
495 | 0 | { |
496 | 0 | default: |
497 | 0 | case 5: |
498 | 0 | UPDATE( 4 ); |
499 | 0 | case 4: |
500 | 0 | UPDATE( 3 ); |
501 | 0 | case 3: |
502 | 0 | UPDATE( 2 ); |
503 | 0 | case 2: |
504 | 0 | UPDATE( 1 ); |
505 | 0 | case 1: |
506 | 0 | UPDATE( 0 ); |
507 | 0 | } |
508 | 0 | #undef UPDATE |
509 | 0 | curr.tplAcc[id][stateId] = ( sumNum << 5 ) | sumAbs1; |
510 | 0 | curr.sum1st[id][stateId] = ( uint8_t ) std::min( 255, sumAbs ); |
511 | 0 | } |
512 | 0 | } |
513 | 0 | } |
514 | 0 | } |
515 | | |
516 | | void Quantizer::initQuantBlock(const TransformUnit& tu, const ComponentID compID, const QpParam& cQP, const double lambda, int gValue) |
517 | 0 | { |
518 | 0 | CHECKD( lambda <= 0.0, "Lambda must be greater than 0" ); |
519 | |
|
520 | 0 | const int qpDQ = cQP.Qp(tu.mtsIdx[compID]==MTS_SKIP) + 1; |
521 | 0 | const int qpPer = qpDQ / 6; |
522 | 0 | const int qpRem = qpDQ - 6 * qpPer; |
523 | 0 | const SPS& sps = *tu.cs->sps; |
524 | 0 | const CompArea& area = tu.blocks[ compID ]; |
525 | 0 | const ChannelType chType = toChannelType( compID ); |
526 | 0 | const int channelBitDepth = sps.bitDepths[ chType ]; |
527 | 0 | const int maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange(); |
528 | 0 | const int nomTransformShift = getTransformShift( channelBitDepth, area.size(), maxLog2TrDynamicRange ); |
529 | 0 | const bool needsSqrt2ScaleAdjustment = TU::needsSqrt2Scale(tu, compID); |
530 | 0 | const int transformShift = nomTransformShift + (needsSqrt2ScaleAdjustment?-1:0); |
531 | | // quant parameters |
532 | 0 | m_QShift = QUANT_SHIFT - 1 + qpPer + transformShift; |
533 | 0 | m_QAdd = -( ( 3 << m_QShift ) >> 1 ); |
534 | 0 | Intermediate_Int invShift = IQUANT_SHIFT + 1 - qpPer - transformShift; |
535 | 0 | m_QScale = g_quantScales[needsSqrt2ScaleAdjustment?1:0][ qpRem ]; |
536 | 0 | const unsigned qIdxBD = std::min<unsigned>( maxLog2TrDynamicRange + 1, 8*sizeof(Intermediate_Int) + invShift - IQUANT_SHIFT - 1 ); |
537 | 0 | m_maxQIdx = ( 1 << (qIdxBD-1) ) - 4; |
538 | 0 | if( m_QShift ) |
539 | 0 | m_thresLast = TCoeff((int64_t(m_DqThrVal) << (m_QShift-1))); |
540 | 0 | else |
541 | 0 | m_thresLast = TCoeff((int64_t(m_DqThrVal>>1) << m_QShift)); |
542 | 0 | m_thresSSbb = TCoeff((int64_t(3) << m_QShift)); |
543 | | // distortion calculation parameters |
544 | 0 | const int64_t qScale = (gValue==-1) ? m_QScale : gValue; |
545 | 0 | const int nomDShift = |
546 | 0 | SCALE_BITS - 2 * (nomTransformShift + DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth)) + m_QShift + (needsSqrt2ScaleAdjustment ? 1 : 0); |
547 | 0 | const double qScale2 = double( qScale * qScale ); |
548 | 0 | const double nomDistFactor = ( nomDShift < 0 ? 1.0/(double(int64_t(1)<<(-nomDShift))*qScale2*lambda) : double(int64_t(1)<<nomDShift)/(qScale2*lambda) ); |
549 | 0 | const uint32_t pow2dfShift = (uint32_t)( nomDistFactor * qScale2 ) + 1; |
550 | 0 | const int dfShift = ceilLog2( pow2dfShift ); |
551 | 0 | m_DistShift = 62 + m_QShift - 2*maxLog2TrDynamicRange - dfShift; |
552 | 0 | m_DistAdd = (int64_t(1) << m_DistShift) >> 1; |
553 | 0 | m_DistStepAdd = ((m_DistShift+m_QShift)>=64 ? (int64_t)( nomDistFactor * pow(2,m_DistShift+m_QShift) + .5 ) : (int64_t)( nomDistFactor * double(int64_t(1)<<(m_DistShift+m_QShift)) + .5 )); |
554 | 0 | m_DistOrgFact = (int64_t)( nomDistFactor * double(int64_t(1)<<(m_DistShift+1 )) + .5 ); |
555 | 0 | } |
556 | | |
557 | | void Quantizer::dequantBlock( const TransformUnit& tu, const ComponentID compID, const QpParam& cQP, CoeffBuf& recCoeff, bool enableScalingLists, int* piDequantCoef) const |
558 | 0 | { |
559 | | |
560 | | //----- set basic parameters ----- |
561 | 0 | const CompArea& area = tu.blocks[ compID ]; |
562 | 0 | const int numCoeff = area.area(); |
563 | 0 | const SizeType hsId = Log2( area.width ); |
564 | 0 | const SizeType vsId = Log2( area.height ); |
565 | 0 | const ScanElement *scan = getScanOrder( SCAN_GROUPED_4x4, hsId, vsId ); |
566 | 0 | const TCoeffSig* qCoeff = tu.getCoeffs( compID ).buf; |
567 | 0 | TCoeff* tCoeff = recCoeff.buf; |
568 | | |
569 | | //----- reset coefficients and get last scan index ----- |
570 | 0 | ::memset( tCoeff, 0, numCoeff * sizeof( TCoeff ) ); |
571 | 0 | int lastScanIdx = tu.lastPos[compID]; |
572 | 0 | if( lastScanIdx < 0 ) |
573 | 0 | { |
574 | 0 | return; |
575 | 0 | } |
576 | | |
577 | | //----- set dequant parameters ----- |
578 | 0 | const int qpDQ = cQP.Qp(tu.mtsIdx[compID]==MTS_SKIP) + 1; |
579 | 0 | const int qpPer = qpDQ / 6; |
580 | 0 | const int qpRem = qpDQ - 6 * qpPer; |
581 | 0 | const SPS& sps = *tu.cs->sps; |
582 | 0 | const ChannelType chType = toChannelType( compID ); |
583 | 0 | const int channelBitDepth = sps.bitDepths[ chType ]; |
584 | 0 | const int maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange(); |
585 | 0 | const TCoeff minTCoeff = -( 1 << maxLog2TrDynamicRange ); |
586 | 0 | const TCoeff maxTCoeff = ( 1 << maxLog2TrDynamicRange ) - 1; |
587 | 0 | const int nomTransformShift = getTransformShift( channelBitDepth, area.size(), maxLog2TrDynamicRange ); |
588 | 0 | const bool needsSqrt2ScaleAdjustment = TU::needsSqrt2Scale(tu, compID); |
589 | 0 | const int transformShift = nomTransformShift + (needsSqrt2ScaleAdjustment?-1:0); |
590 | 0 | Intermediate_Int shift = IQUANT_SHIFT + 1 - qpPer - transformShift + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0); |
591 | 0 | Intermediate_Int invQScale = g_invQuantScales[needsSqrt2ScaleAdjustment?1:0][ qpRem ]; |
592 | 0 | Intermediate_Int add = (shift < 0) ? 0 : ((1 << shift) >> 1); |
593 | | //----- dequant coefficients ----- |
594 | 0 | for( int state = 0, scanIdx = lastScanIdx; scanIdx >= 0; scanIdx-- ) |
595 | 0 | { |
596 | 0 | const unsigned rasterPos = scan[scanIdx].idx; |
597 | 0 | const TCoeffSig& level = qCoeff[ rasterPos ]; |
598 | 0 | if( level ) |
599 | 0 | { |
600 | 0 | if (enableScalingLists) |
601 | 0 | invQScale = piDequantCoef[rasterPos];//scalingfactor*levelScale |
602 | 0 | if (shift < 0 && (enableScalingLists || scanIdx == lastScanIdx)) |
603 | 0 | { |
604 | 0 | invQScale <<= -shift; |
605 | 0 | } |
606 | 0 | Intermediate_Int qIdx = 2 * level + (level > 0 ? -(state>>1) : (state>>1)); |
607 | 0 | int64_t nomTCoeff = ((int64_t)qIdx * (int64_t)invQScale + add) >> ((shift < 0) ? 0 : shift); |
608 | 0 | tCoeff[rasterPos] = (TCoeff)Clip3<int64_t>(minTCoeff, maxTCoeff, nomTCoeff); |
609 | 0 | } |
610 | 0 | state = ( 32040 >> ((state<<2)+((level&1)<<1)) ) & 3; // the 16-bit value "32040" represent the state transition table |
611 | 0 | } |
612 | 0 | } |
613 | | |
614 | | bool Quantizer::preQuantCoeff( const TCoeff absCoeff, PQData* pqData, int quanCoeff ) const |
615 | 0 | { |
616 | 0 | int64_t scaledOrg = int64_t( absCoeff ) * quanCoeff; |
617 | 0 | TCoeff qIdx = TCoeff( ( scaledOrg + m_QAdd ) >> m_QShift ); |
618 | |
|
619 | 0 | if( qIdx < 0 ) |
620 | 0 | { |
621 | 0 | int64_t scaledAdd = m_DistStepAdd - scaledOrg * m_DistOrgFact; |
622 | 0 | PQData& pq_a = pqData[1]; |
623 | 0 | PQData& pq_b = pqData[2]; |
624 | |
|
625 | 0 | pq_a.deltaDist = ( ( scaledAdd + 0 * m_DistStepAdd ) * 1 + m_DistAdd ) >> m_DistShift; |
626 | 0 | pq_a.absLevel = 1; |
627 | |
|
628 | 0 | pq_b.deltaDist = ( ( scaledAdd + 1 * m_DistStepAdd ) * 2 + m_DistAdd ) >> m_DistShift; |
629 | 0 | pq_b.absLevel = 1; |
630 | | |
631 | 0 | return true; |
632 | 0 | } |
633 | | |
634 | 0 | qIdx = std::max<TCoeff>( 1, std::min<TCoeff>( m_maxQIdx, qIdx ) ); |
635 | 0 | int64_t scaledAdd = qIdx * m_DistStepAdd - scaledOrg * m_DistOrgFact; |
636 | |
|
637 | 0 | PQData& pq_a = pqData[( qIdx + 0 ) & 3]; |
638 | 0 | PQData& pq_b = pqData[( qIdx + 1 ) & 3]; |
639 | 0 | PQData& pq_c = pqData[( qIdx + 2 ) & 3]; |
640 | 0 | PQData& pq_d = pqData[( qIdx + 3 ) & 3]; |
641 | |
|
642 | 0 | pq_a.deltaDist = ( ( scaledAdd + 0 * m_DistStepAdd ) * ( qIdx + 0 ) + m_DistAdd ) >> m_DistShift; |
643 | 0 | pq_a.absLevel = ( qIdx + 1 ) >> 1; |
644 | |
|
645 | 0 | pq_b.deltaDist = ( ( scaledAdd + 1 * m_DistStepAdd ) * ( qIdx + 1 ) + m_DistAdd ) >> m_DistShift; |
646 | 0 | pq_b.absLevel = ( qIdx + 2 ) >> 1; |
647 | |
|
648 | 0 | pq_c.deltaDist = ( ( scaledAdd + 2 * m_DistStepAdd ) * ( qIdx + 2 ) + m_DistAdd ) >> m_DistShift; |
649 | 0 | pq_c.absLevel = ( qIdx + 3 ) >> 1; |
650 | |
|
651 | 0 | pq_d.deltaDist = ( ( scaledAdd + 3 * m_DistStepAdd ) * ( qIdx + 3 ) + m_DistAdd ) >> m_DistShift; |
652 | 0 | pq_d.absLevel = ( qIdx + 4 ) >> 1; |
653 | |
|
654 | 0 | return false; |
655 | 0 | } |
656 | | |
657 | | const int32_t g_goRiceBits[4][RICEMAX] = |
658 | | { |
659 | | { 32768, 65536, 98304, 131072, 163840, 196608, 262144, 262144, 327680, 327680, 327680, 327680, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752}, |
660 | | { 65536, 65536, 98304, 98304, 131072, 131072, 163840, 163840, 196608, 196608, 229376, 229376, 294912, 294912, 294912, 294912, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984}, |
661 | | { 98304, 98304, 98304, 98304, 131072, 131072, 131072, 131072, 163840, 163840, 163840, 163840, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 262144, 262144, 262144, 262144, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680}, |
662 | | {131072, 131072, 131072, 131072, 131072, 131072, 131072, 131072, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376} |
663 | | }; |
664 | | |
665 | | static inline void initStates( const int stateId, DQIntern::StateMem& state ) |
666 | 0 | { |
667 | 0 | state.rdCost[stateId] = DQIntern::rdCostInit; |
668 | 0 | state.ctx.cff[stateId] = 0; |
669 | 0 | state.ctx.sig[stateId] = 0; |
670 | 0 | state.numSig[stateId] = 0; |
671 | 0 | state.refSbbCtxId[stateId] = -1; |
672 | 0 | state.remRegBins[stateId] = 4; |
673 | 0 | state.cffBitsCtxOffset = 0; |
674 | 0 | state.m_goRicePar[stateId] = 0; |
675 | 0 | state.m_goRiceZero[stateId] = 0; |
676 | 0 | state.sbbBits0[stateId] = 0; |
677 | 0 | state.sbbBits1[stateId] = 0; |
678 | 0 | } |
679 | | |
680 | | template<bool rrgEnsured = false> |
681 | | static inline void checkRdCosts( const int stateId, const DQIntern::ScanPosType spt, const DQIntern::PQData& pqDataA, const DQIntern::PQData& pqDataB, DQIntern::Decisions& decisions, int idxAZ, int idxB, const DQIntern::StateMem& state ) |
682 | 0 | { |
683 | 0 | const int32_t* goRiceTab = DQIntern::g_goRiceBits[state.m_goRicePar[stateId]]; |
684 | 0 | int64_t rdCostA = state.rdCost[stateId] + pqDataA.deltaDist; |
685 | 0 | int64_t rdCostB = state.rdCost[stateId] + pqDataB.deltaDist; |
686 | 0 | int64_t rdCostZ = state.rdCost[stateId]; |
687 | |
|
688 | 0 | if( rrgEnsured || state.remRegBins[stateId] >= 4 ) |
689 | 0 | { |
690 | 0 | const CoeffFracBits& cffBits = state.m_gtxFracBitsArray[state.ctx.cff[stateId]]; |
691 | 0 | const BinFracBits sigBits = state.m_sigFracBitsArray[stateId][state.ctx.sig[stateId]]; |
692 | |
|
693 | 0 | if( pqDataA.absLevel < 4 ) |
694 | 0 | rdCostA += cffBits.bits[pqDataA.absLevel]; |
695 | 0 | else |
696 | 0 | { |
697 | 0 | const unsigned value = ( pqDataA.absLevel - 4 ) >> 1; |
698 | 0 | rdCostA += cffBits.bits[pqDataA.absLevel - ( value << 1 )] + goRiceTab[std::min<unsigned>( value, RICEMAX - 1 )]; |
699 | 0 | } |
700 | |
|
701 | 0 | if( pqDataB.absLevel < 4 ) |
702 | 0 | rdCostB += cffBits.bits[pqDataB.absLevel]; |
703 | 0 | else |
704 | 0 | { |
705 | 0 | const unsigned value = ( pqDataB.absLevel - 4 ) >> 1; |
706 | 0 | rdCostB += cffBits.bits[pqDataB.absLevel - ( value << 1 )] + goRiceTab[std::min<unsigned>( value, RICEMAX - 1 )]; |
707 | 0 | } |
708 | |
|
709 | 0 | if( spt == SCAN_ISCSBB ) |
710 | 0 | { |
711 | 0 | rdCostA += sigBits.intBits[1]; |
712 | 0 | rdCostB += sigBits.intBits[1]; |
713 | 0 | rdCostZ += sigBits.intBits[0]; |
714 | 0 | } |
715 | 0 | else if( spt == SCAN_SOCSBB ) |
716 | 0 | { |
717 | 0 | rdCostA += state.sbbBits1[stateId] + sigBits.intBits[1]; |
718 | 0 | rdCostB += state.sbbBits1[stateId] + sigBits.intBits[1]; |
719 | 0 | rdCostZ += state.sbbBits1[stateId] + sigBits.intBits[0]; |
720 | 0 | } |
721 | 0 | else if( state.numSig[stateId] ) |
722 | 0 | { |
723 | 0 | rdCostA += sigBits.intBits[1]; |
724 | 0 | rdCostB += sigBits.intBits[1]; |
725 | 0 | rdCostZ += sigBits.intBits[0]; |
726 | 0 | } |
727 | 0 | else |
728 | 0 | { |
729 | 0 | rdCostZ = rdCostInit; |
730 | 0 | } |
731 | 0 | } |
732 | 0 | else |
733 | 0 | { |
734 | 0 | rdCostA += ( 1 << SCALE_BITS ) + goRiceTab[pqDataA.absLevel <= state.m_goRiceZero[stateId] ? pqDataA.absLevel - 1 : std::min<int>( pqDataA.absLevel, RICEMAX - 1 )]; |
735 | 0 | rdCostB += ( 1 << SCALE_BITS ) + goRiceTab[pqDataB.absLevel <= state.m_goRiceZero[stateId] ? pqDataB.absLevel - 1 : std::min<int>( pqDataB.absLevel, RICEMAX - 1 )]; |
736 | 0 | rdCostZ += goRiceTab[state.m_goRiceZero[stateId]]; |
737 | 0 | } |
738 | |
|
739 | 0 | if( rdCostA < rdCostZ && rdCostA < decisions.rdCost[idxAZ] ) |
740 | 0 | { |
741 | 0 | decisions.rdCost[idxAZ] = rdCostA; |
742 | 0 | decisions.absLevel[idxAZ] = pqDataA.absLevel; |
743 | 0 | decisions.prevId[idxAZ] = stateId; |
744 | 0 | } |
745 | 0 | else if( rdCostZ < decisions.rdCost[idxAZ] ) |
746 | 0 | { |
747 | 0 | decisions.rdCost[idxAZ] = rdCostZ; |
748 | 0 | decisions.absLevel[idxAZ] = 0; |
749 | 0 | decisions.prevId[idxAZ] = stateId; |
750 | 0 | } |
751 | |
|
752 | 0 | if( rdCostB < decisions.rdCost[idxB] ) |
753 | 0 | { |
754 | 0 | decisions.rdCost[idxB] = rdCostB; |
755 | 0 | decisions.absLevel[idxB] = pqDataB.absLevel; |
756 | 0 | decisions.prevId[idxB] = stateId; |
757 | 0 | } |
758 | 0 | } Unexecuted instantiation: DepQuant.cpp:void vvenc::DQIntern::checkRdCosts<true>(int, vvenc::DQIntern::ScanPosType, vvenc::DQIntern::PQData const&, vvenc::DQIntern::PQData const&, vvenc::DQIntern::Decisions&, int, int, vvenc::DQIntern::StateMem const&) Unexecuted instantiation: DepQuant.cpp:void vvenc::DQIntern::checkRdCosts<false>(int, vvenc::DQIntern::ScanPosType, vvenc::DQIntern::PQData const&, vvenc::DQIntern::PQData const&, vvenc::DQIntern::Decisions&, int, int, vvenc::DQIntern::StateMem const&) |
759 | | |
760 | | void checkAllRdCosts( const DQIntern::ScanPosType spt, const DQIntern::PQData* pqData, DQIntern::Decisions& decisions, const DQIntern::StateMem& state ) |
761 | 0 | { |
762 | 0 | checkRdCosts<true>( 0, spt, pqData[0], pqData[2], decisions, 0, 2, state ); |
763 | 0 | checkRdCosts<true>( 1, spt, pqData[0], pqData[2], decisions, 2, 0, state ); |
764 | 0 | checkRdCosts<true>( 2, spt, pqData[3], pqData[1], decisions, 1, 3, state ); |
765 | 0 | checkRdCosts<true>( 3, spt, pqData[3], pqData[1], decisions, 3, 1, state ); |
766 | 0 | } |
767 | | |
768 | | template<bool rrgEnsured = false> |
769 | | static void checkRdCostsOdd1( const int stateId, const ScanPosType spt, const int64_t deltaDist, Decisions& decisions, int idxA, int idxZ, const StateMem& state ) |
770 | 0 | { |
771 | 0 | int64_t rdCostA = state.rdCost[stateId] + deltaDist; |
772 | 0 | int64_t rdCostZ = state.rdCost[stateId]; |
773 | |
|
774 | 0 | if( rrgEnsured || state.remRegBins[stateId] >= 4 ) |
775 | 0 | { |
776 | 0 | const BinFracBits sigBits = state.m_sigFracBitsArray[stateId][state.ctx.sig[stateId]]; |
777 | |
|
778 | 0 | rdCostA += state.cffBits1[state.ctx.cff[stateId]]; |
779 | |
|
780 | 0 | if( spt == SCAN_ISCSBB ) |
781 | 0 | { |
782 | 0 | rdCostA += sigBits.intBits[1]; |
783 | 0 | rdCostZ += sigBits.intBits[0]; |
784 | 0 | } |
785 | 0 | else if( spt == SCAN_SOCSBB ) |
786 | 0 | { |
787 | 0 | rdCostA += state.sbbBits1[stateId] + sigBits.intBits[1]; |
788 | 0 | rdCostZ += state.sbbBits1[stateId] + sigBits.intBits[0]; |
789 | 0 | } |
790 | 0 | else if( state.numSig[stateId] ) |
791 | 0 | { |
792 | 0 | rdCostA += sigBits.intBits[1]; |
793 | 0 | rdCostZ += sigBits.intBits[0]; |
794 | 0 | } |
795 | 0 | else |
796 | 0 | { |
797 | 0 | rdCostZ = rdCostInit; |
798 | 0 | } |
799 | 0 | } |
800 | 0 | else |
801 | 0 | { |
802 | 0 | const int32_t* goRiceTab = g_goRiceBits[state.m_goRicePar[stateId]]; |
803 | |
|
804 | 0 | rdCostA += ( 1 << SCALE_BITS ) + goRiceTab[0]; |
805 | 0 | rdCostZ += goRiceTab[state.m_goRiceZero[stateId]]; |
806 | 0 | } |
807 | |
|
808 | 0 | if( rdCostA < decisions.rdCost[idxA] ) |
809 | 0 | { |
810 | 0 | decisions.rdCost[idxA] = rdCostA; |
811 | 0 | decisions.absLevel[idxA] = 1; |
812 | 0 | decisions.prevId[idxA] = stateId; |
813 | 0 | } |
814 | |
|
815 | 0 | if( rdCostZ < decisions.rdCost[idxZ] ) |
816 | 0 | { |
817 | 0 | decisions.rdCost[idxZ] = rdCostZ; |
818 | 0 | decisions.absLevel[idxZ] = 0; |
819 | 0 | decisions.prevId[idxZ] = stateId; |
820 | 0 | } |
821 | 0 | } Unexecuted instantiation: DepQuant.cpp:void vvenc::DQIntern::checkRdCostsOdd1<true>(int, vvenc::DQIntern::ScanPosType, long, vvenc::DQIntern::Decisions&, int, int, vvenc::DQIntern::StateMem const&) Unexecuted instantiation: DepQuant.cpp:void vvenc::DQIntern::checkRdCostsOdd1<false>(int, vvenc::DQIntern::ScanPosType, long, vvenc::DQIntern::Decisions&, int, int, vvenc::DQIntern::StateMem const&) |
822 | | |
823 | | static void checkAllRdCostsOdd1( const DQIntern::ScanPosType spt, const int64_t pq_a_dist, const int64_t pq_b_dist, DQIntern::Decisions& decisions, const DQIntern::StateMem& state ) |
824 | 0 | { |
825 | 0 | checkRdCostsOdd1<true>( 0, spt, pq_b_dist, decisions, 2, 0, state ); |
826 | 0 | checkRdCostsOdd1<true>( 1, spt, pq_b_dist, decisions, 0, 2, state ); |
827 | 0 | checkRdCostsOdd1<true>( 2, spt, pq_a_dist, decisions, 3, 1, state ); |
828 | 0 | checkRdCostsOdd1<true>( 3, spt, pq_a_dist, decisions, 1, 3, state ); |
829 | 0 | } |
830 | | |
831 | | static inline void checkRdCostStart( int32_t lastOffset, const PQData& pqData, Decisions& decisions, int idx, const StateMem& state ) |
832 | 0 | { |
833 | 0 | const CoeffFracBits& cffBits = state.m_gtxFracBitsArray[0]; |
834 | |
|
835 | 0 | int64_t rdCost = pqData.deltaDist + lastOffset; |
836 | 0 | if( pqData.absLevel < 4 ) |
837 | 0 | { |
838 | 0 | rdCost += cffBits.bits[pqData.absLevel]; |
839 | 0 | } |
840 | 0 | else |
841 | 0 | { |
842 | 0 | const unsigned value = ( pqData.absLevel - 4 ) >> 1; |
843 | 0 | rdCost += cffBits.bits[pqData.absLevel - ( value << 1 )] + g_goRiceBits[0][value < RICEMAX ? value : RICEMAX - 1]; |
844 | 0 | } |
845 | |
|
846 | 0 | if( rdCost < decisions.rdCost[idx] ) |
847 | 0 | { |
848 | 0 | decisions.rdCost[idx] = rdCost; |
849 | 0 | decisions.absLevel[idx] = pqData.absLevel; |
850 | 0 | decisions.prevId[idx] = -1; |
851 | 0 | } |
852 | 0 | } |
853 | | |
854 | | static inline void checkRdCostSkipSbb( const int stateId, Decisions& decisions, int idx, const StateMem& state ) |
855 | 0 | { |
856 | 0 | int64_t rdCost = state.rdCost[stateId] + state.sbbBits0[stateId]; |
857 | 0 | if( rdCost < decisions.rdCost[idx] ) |
858 | 0 | { |
859 | 0 | decisions.rdCost[idx] = rdCost; |
860 | 0 | decisions.absLevel[idx] = 0; |
861 | 0 | decisions.prevId[idx] = 4 | stateId; |
862 | 0 | } |
863 | 0 | } |
864 | | |
865 | | static inline void checkRdCostSkipSbbZeroOut( const int stateId, Decisions& decisions, int idx, const StateMem& state ) |
866 | 0 | { |
867 | 0 | int64_t rdCost = state.rdCost[stateId] + state.sbbBits0[stateId]; |
868 | 0 | decisions.rdCost[idx] = rdCost; |
869 | 0 | decisions.absLevel[idx] = 0; |
870 | 0 | decisions.prevId[idx] = 4 | stateId; |
871 | 0 | } |
872 | | |
873 | | static inline void setRiceParam( const int stateId, const ScanInfo& scanInfo, StateMem& state, bool ge4 ) |
874 | 0 | { |
875 | 0 | if( state.remRegBins[stateId] < 4 || ge4 ) |
876 | 0 | { |
877 | 0 | TCoeff sumAbs = state.sum1st[scanInfo.insidePos][stateId]; |
878 | 0 | int sumSub = state.remRegBins[stateId] < 4 ? 0 : 4 * 5; |
879 | 0 | int sumAll = std::max( std::min( 31, ( int ) sumAbs - sumSub ), 0 ); |
880 | 0 | state.m_goRicePar[stateId] |
881 | 0 | = g_auiGoRiceParsCoeff[sumAll]; |
882 | |
|
883 | 0 | if( state.remRegBins[stateId] < 4 ) |
884 | 0 | { |
885 | 0 | state.m_goRiceZero[stateId] = g_auiGoRicePosCoeff0( stateId, state.m_goRicePar[stateId] ); |
886 | 0 | } |
887 | 0 | } |
888 | 0 | } |
889 | | |
890 | | static void update1State( int stateId, const DQIntern::ScanInfo& scanInfo, const DQIntern::Decisions& decisions, DQIntern::StateMem& curr, DQIntern::StateMem& prev ) |
891 | 0 | { |
892 | 0 | curr.rdCost[stateId] = decisions.rdCost[stateId]; |
893 | 0 | if( decisions.prevId[stateId] > -2 ) |
894 | 0 | { |
895 | 0 | if( decisions.prevId[stateId] >= 0 ) |
896 | 0 | { |
897 | 0 | const int prevId = decisions.prevId[stateId]; |
898 | 0 | curr.numSig[stateId] = prev.numSig[prevId] + !!decisions.absLevel[stateId]; |
899 | 0 | curr.refSbbCtxId[stateId] = prev.refSbbCtxId[prevId]; |
900 | 0 | curr.sbbBits0[stateId] = prev.sbbBits0[prevId]; |
901 | 0 | curr.sbbBits1[stateId] = prev.sbbBits1[prevId]; |
902 | 0 | curr.remRegBins[stateId] = prev.remRegBins[prevId] - 1; |
903 | |
|
904 | 0 | if( curr.remRegBins[stateId] >= 4 ) |
905 | 0 | { |
906 | 0 | curr.remRegBins[stateId] -= ( decisions.absLevel[stateId] < 2 ? decisions.absLevel[stateId] : 3 ); |
907 | 0 | } |
908 | |
|
909 | 0 | for( int i = 0; i < 16; i++ ) |
910 | 0 | { |
911 | 0 | curr.tplAcc[i][stateId] = prev.tplAcc[i][prevId]; |
912 | 0 | curr.sum1st[i][stateId] = prev.sum1st[i][prevId]; |
913 | 0 | curr.absVal[i][stateId] = prev.absVal[i][prevId]; |
914 | 0 | } |
915 | 0 | } |
916 | 0 | else |
917 | 0 | { |
918 | 0 | curr.numSig[stateId] = 1; |
919 | 0 | curr.refSbbCtxId[stateId] = -1; |
920 | 0 | curr.remRegBins[stateId] = prev.initRemRegBins; |
921 | 0 | curr.remRegBins[stateId] -= ( decisions.absLevel[stateId] < 2 ? decisions.absLevel[stateId] : 3 ); |
922 | |
|
923 | 0 | for( int i = 0; i < 16; i++ ) |
924 | 0 | { |
925 | 0 | curr.tplAcc[i][stateId] = 0; |
926 | 0 | curr.sum1st[i][stateId] = 0; |
927 | 0 | curr.absVal[i][stateId] = 0; |
928 | 0 | } |
929 | 0 | } |
930 | |
|
931 | 0 | if( decisions.absLevel[stateId] ) |
932 | 0 | { |
933 | 0 | curr.absVal[scanInfo.insidePos][stateId] = ( uint8_t ) std::min<TCoeff>( 126 + ( decisions.absLevel[stateId] & 1 ), decisions.absLevel[stateId] ); |
934 | |
|
935 | 0 | if( scanInfo.currNbInfoSbb.numInv ) |
936 | 0 | { |
937 | 0 | int min4_or_5 = std::min<TCoeff>( 4 + ( decisions.absLevel[stateId] & 1 ), decisions.absLevel[stateId] ); |
938 | |
|
939 | 0 | auto adds8 = []( uint8_t a, uint8_t b ) |
940 | 0 | { |
941 | 0 | uint8_t c = a + b; |
942 | 0 | if( c < a ) c = -1; |
943 | 0 | return c; |
944 | 0 | }; |
945 | |
|
946 | 0 | auto update_deps = [&]( int k ) |
947 | 0 | { |
948 | 0 | curr.tplAcc[scanInfo.currNbInfoSbb.invInPos[k]][stateId] += 32 + min4_or_5; |
949 | 0 | curr.sum1st[scanInfo.currNbInfoSbb.invInPos[k]][stateId] = adds8( curr.sum1st[scanInfo.currNbInfoSbb.invInPos[k]][stateId], decisions.absLevel[stateId] ); |
950 | 0 | }; |
951 | |
|
952 | 0 | switch( scanInfo.currNbInfoSbb.numInv ) |
953 | 0 | { |
954 | 0 | default: |
955 | 0 | case 5: |
956 | 0 | update_deps( 4 ); |
957 | 0 | case 4: |
958 | 0 | update_deps( 3 ); |
959 | 0 | case 3: |
960 | 0 | update_deps( 2 ); |
961 | 0 | case 2: |
962 | 0 | update_deps( 1 ); |
963 | 0 | case 1: |
964 | 0 | update_deps( 0 ); |
965 | 0 | } |
966 | 0 | } |
967 | 0 | } |
968 | |
|
969 | 0 | if( curr.remRegBins[stateId] >= 4 ) |
970 | 0 | { |
971 | 0 | TCoeff sumAbs1 = curr.tplAcc[scanInfo.nextInsidePos][stateId] & 31; |
972 | 0 | TCoeff sumNum = curr.tplAcc[scanInfo.nextInsidePos][stateId] >> 5u; |
973 | 0 | int sumGt1 = sumAbs1 - sumNum; |
974 | |
|
975 | 0 | curr.ctx.sig[stateId] = scanInfo.sigCtxOffsetNext + std::min( ( sumAbs1 + 1 ) >> 1, 3 ); |
976 | 0 | curr.ctx.cff[stateId] = scanInfo.gtxCtxOffsetNext + std::min( sumGt1, 4 ); |
977 | 0 | } |
978 | 0 | else |
979 | 0 | { |
980 | 0 | curr.anyRemRegBinsLt4 = true; |
981 | 0 | } |
982 | 0 | } |
983 | 0 | } |
984 | | |
985 | | static void update1StateEOS( const int stateId, const DQIntern::ScanInfo& scanInfo, const DQIntern::Decisions& decisions, const DQIntern::StateMem& skip, DQIntern::StateMem& curr, DQIntern::StateMem& prev, DQIntern::CommonCtx& commonCtx ) |
986 | 0 | { |
987 | 0 | curr.rdCost[stateId] = decisions.rdCost[stateId]; |
988 | |
|
989 | 0 | if( decisions.prevId[stateId] > -2 ) |
990 | 0 | { |
991 | 0 | if( decisions.prevId[stateId] >= 4 ) |
992 | 0 | { |
993 | 0 | CHECK( decisions.absLevel[stateId] != 0, "cannot happen" ); |
994 | |
|
995 | 0 | const int prevId = decisions.prevId[stateId] - 4; |
996 | 0 | curr.numSig [stateId] = 0; |
997 | 0 | curr.remRegBins[stateId] = skip.remRegBins[prevId]; |
998 | 0 | curr.refSbbCtxId[stateId] = prevId; |
999 | |
|
1000 | 0 | for( int i = 0; i < 16; i++ ) |
1001 | 0 | { |
1002 | 0 | curr.absVal[i][stateId] = 0; |
1003 | 0 | } |
1004 | 0 | } |
1005 | 0 | else if( decisions.prevId[stateId] >= 0 ) |
1006 | 0 | { |
1007 | 0 | const int prevId = decisions.prevId[stateId]; |
1008 | 0 | curr.numSig[stateId] = prev.numSig[prevId] + !!decisions.absLevel[stateId]; |
1009 | 0 | curr.refSbbCtxId[stateId] = prev.refSbbCtxId[prevId]; |
1010 | 0 | curr.remRegBins[stateId] = prev.remRegBins[prevId] - 1; |
1011 | |
|
1012 | 0 | if( curr.remRegBins[stateId] >= 4 ) |
1013 | 0 | { |
1014 | 0 | curr.remRegBins[stateId] -= ( decisions.absLevel[stateId] < 2 ? decisions.absLevel[stateId] : 3 ); |
1015 | 0 | } |
1016 | |
|
1017 | 0 | for( int i = 0; i < 16; i++ ) |
1018 | 0 | { |
1019 | 0 | curr.absVal[i][stateId] = prev.absVal[i][prevId]; |
1020 | 0 | } |
1021 | 0 | } |
1022 | 0 | else |
1023 | 0 | { |
1024 | 0 | curr.numSig[stateId] = 1; |
1025 | 0 | curr.refSbbCtxId[stateId] = -1; |
1026 | 0 | curr.remRegBins[stateId] = prev.initRemRegBins; |
1027 | 0 | curr.remRegBins[stateId] -= ( decisions.absLevel[stateId] < 2 ? decisions.absLevel[stateId] : 3 ); |
1028 | |
|
1029 | 0 | for( int i = 0; i < 16; i++ ) |
1030 | 0 | { |
1031 | 0 | curr.absVal[i][stateId] = 0; |
1032 | 0 | } |
1033 | 0 | } |
1034 | | |
1035 | 0 | curr.absVal[scanInfo.insidePos][stateId] = ( uint8_t ) std::min<TCoeff>( 126 + ( decisions.absLevel[stateId] & 1 ), decisions.absLevel[stateId] ); |
1036 | |
|
1037 | 0 | uint8_t* levels[4]; |
1038 | 0 | commonCtx.getLevelPtrs( scanInfo, levels[0], levels[1], levels[2], levels[3] ); |
1039 | 0 | for( int i = 0; i < 16; i++ ) |
1040 | 0 | { |
1041 | | // save abs levels to commonCtx |
1042 | 0 | levels[stateId][i] = curr.absVal[i][stateId]; |
1043 | | // clean the SBB ctx |
1044 | 0 | curr.tplAcc[i][stateId] = 0; |
1045 | 0 | curr.sum1st[i][stateId] = 0; |
1046 | 0 | curr.absVal[i][stateId] = 0; |
1047 | 0 | } |
1048 | |
|
1049 | 0 | commonCtx.update( scanInfo, curr.refSbbCtxId[stateId], stateId, curr ); |
1050 | |
|
1051 | 0 | curr.numSig[stateId] = 0; |
1052 | |
|
1053 | 0 | if( curr.remRegBins[stateId] >= 4 ) |
1054 | 0 | { |
1055 | 0 | TCoeff sumAbs1 = curr.tplAcc[scanInfo.nextInsidePos][stateId] & 31; |
1056 | 0 | TCoeff sumNum = curr.tplAcc[scanInfo.nextInsidePos][stateId] >> 5u; |
1057 | 0 | int sumGt1 = sumAbs1 - sumNum; |
1058 | |
|
1059 | 0 | curr.ctx.sig[stateId] = scanInfo.sigCtxOffsetNext + std::min( ( sumAbs1 + 1 ) >> 1, 3 ); |
1060 | 0 | curr.ctx.cff[stateId] = scanInfo.gtxCtxOffsetNext + std::min( sumGt1, 4 ); |
1061 | 0 | } |
1062 | 0 | else |
1063 | 0 | { |
1064 | 0 | curr.anyRemRegBinsLt4 = true; |
1065 | 0 | } |
1066 | 0 | } |
1067 | 0 | } |
1068 | | |
1069 | | static void updateStates( const DQIntern::ScanInfo& scanInfo, const DQIntern::Decisions& decisions, DQIntern::StateMem& curr ) |
1070 | 0 | { |
1071 | 0 | DQIntern::StateMem prev = curr; |
1072 | 0 | curr.anyRemRegBinsLt4 = false; |
1073 | |
|
1074 | 0 | update1State( 0, scanInfo, decisions, curr, prev ); |
1075 | 0 | update1State( 1, scanInfo, decisions, curr, prev ); |
1076 | 0 | update1State( 2, scanInfo, decisions, curr, prev ); |
1077 | 0 | update1State( 3, scanInfo, decisions, curr, prev ); |
1078 | |
|
1079 | 0 | curr.cffBitsCtxOffset = scanInfo.gtxCtxOffsetNext; |
1080 | 0 | } |
1081 | | |
1082 | | static void updateStatesEOS( const DQIntern::ScanInfo& scanInfo, const DQIntern::Decisions& decisions, const DQIntern::StateMem& skip, DQIntern::StateMem& curr, DQIntern::CommonCtx& commonCtx ) |
1083 | 0 | { |
1084 | 0 | DQIntern::StateMem prev = curr; |
1085 | 0 | curr.anyRemRegBinsLt4 = false; |
1086 | |
|
1087 | 0 | update1StateEOS( 0, scanInfo, decisions, skip, curr, prev, commonCtx ); |
1088 | 0 | update1StateEOS( 1, scanInfo, decisions, skip, curr, prev, commonCtx ); |
1089 | 0 | update1StateEOS( 2, scanInfo, decisions, skip, curr, prev, commonCtx ); |
1090 | 0 | update1StateEOS( 3, scanInfo, decisions, skip, curr, prev, commonCtx ); |
1091 | |
|
1092 | 0 | curr.cffBitsCtxOffset = scanInfo.gtxCtxOffsetNext; |
1093 | 0 | } |
1094 | | }; // namespace DQIntern |
1095 | | |
1096 | | static const DQIntern::Decisions startDec[2] = |
1097 | | { |
1098 | | DQIntern::Decisions |
1099 | | { |
1100 | | { DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2 }, |
1101 | | { -1, -1, -1, -1 }, |
1102 | | { -2, -2, -2, -2 }, |
1103 | | }, |
1104 | | DQIntern::Decisions |
1105 | | { |
1106 | | { DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2 }, |
1107 | | { 0, 0, 0, 0 }, |
1108 | | { 4, 5, 6, 7 }, |
1109 | | } |
1110 | | }; |
1111 | | |
1112 | | void DepQuant::xQuantDQ( TransformUnit& tu, const CCoeffBuf& srcCoeff, const ComponentID compID, const QpParam& cQP, const double lambda, const Ctx& ctx, TCoeff& absSum, bool enableScalingLists, int* quantCoeff ) |
1113 | 0 | { |
1114 | 0 | using namespace DQIntern; |
1115 | | |
1116 | | //===== reset / pre-init ===== |
1117 | 0 | const TUParameters& tuPars = *m_scansRom->getTUPars( tu.blocks[compID], compID ); |
1118 | 0 | m_quant.initQuantBlock ( tu, compID, cQP, lambda ); |
1119 | 0 | TCoeffSig* qCoeff = tu.getCoeffs( compID ).buf; |
1120 | 0 | const TCoeff* tCoeff = srcCoeff.buf; |
1121 | 0 | const int numCoeff = tu.blocks[compID].area(); |
1122 | 0 | ::memset( qCoeff, 0x00, numCoeff * sizeof( TCoeffSig ) ); |
1123 | 0 | absSum = 0; |
1124 | |
|
1125 | 0 | const CompArea& area = tu.blocks[ compID ]; |
1126 | 0 | const uint32_t width = area.width; |
1127 | 0 | const uint32_t height = area.height; |
1128 | 0 | const uint32_t lfnstIdx = tu.cu->lfnstIdx; |
1129 | | //===== scaling matrix ==== |
1130 | | //const int qpDQ = cQP.Qp + 1; |
1131 | | //const int qpPer = qpDQ / 6; |
1132 | | //const int qpRem = qpDQ - 6 * qpPer; |
1133 | | |
1134 | | //TCoeff thresTmp = thres; |
1135 | 0 | bool zeroOut = false; |
1136 | 0 | bool zeroOutforThres = false; |
1137 | 0 | int effWidth = tuPars.m_width, effHeight = tuPars.m_height; |
1138 | 0 | if( ( tu.mtsIdx[compID] > MTS_SKIP || ( tu.cs->sps->MTS && tu.cu->sbtInfo != 0 && tuPars.m_height <= 32 && tuPars.m_width <= 32 ) ) && compID == COMP_Y ) |
1139 | 0 | { |
1140 | 0 | effHeight = ( tuPars.m_height == 32 ) ? 16 : tuPars.m_height; |
1141 | 0 | effWidth = ( tuPars.m_width == 32 ) ? 16 : tuPars.m_width; |
1142 | 0 | zeroOut = ( effHeight < tuPars.m_height || effWidth < tuPars.m_width ); |
1143 | 0 | } |
1144 | 0 | zeroOutforThres = zeroOut || ( 32 < tuPars.m_height || 32 < tuPars.m_width ); |
1145 | | //===== find first test position ===== |
1146 | 0 | int firstTestPos = std::min<int>( tuPars.m_width, JVET_C0024_ZERO_OUT_TH ) * std::min<int>( tuPars.m_height, JVET_C0024_ZERO_OUT_TH ) - 1; |
1147 | 0 | if( lfnstIdx > 0 && tu.mtsIdx[compID] != MTS_SKIP && width >= 4 && height >= 4 ) |
1148 | 0 | { |
1149 | 0 | firstTestPos = ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) ) ? 7 : 15 ; |
1150 | 0 | } |
1151 | |
|
1152 | 0 | const TCoeff defaultQuantisationCoefficient = (TCoeff)m_quant.getQScale(); |
1153 | 0 | const TCoeff thres = m_quant.getLastThreshold(); |
1154 | 0 | const int zeroOutWidth = ( tuPars.m_width == 32 && zeroOut ) ? 16 : 32; |
1155 | 0 | const int zeroOutHeight = ( tuPars.m_height == 32 && zeroOut ) ? 16 : 32; |
1156 | |
|
1157 | 0 | if( enableScalingLists ) |
1158 | 0 | { |
1159 | 0 | for( ; firstTestPos >= 0; firstTestPos-- ) |
1160 | 0 | { |
1161 | 0 | if( zeroOutforThres && ( tuPars.m_scanId2BlkPos[firstTestPos].x >= zeroOutWidth || tuPars.m_scanId2BlkPos[firstTestPos].y >= zeroOutHeight ) ) continue; |
1162 | | |
1163 | 0 | const TCoeff thresTmp = TCoeff( thres / ( 4 * quantCoeff[tuPars.m_scanId2BlkPos[firstTestPos].idx] ) ); |
1164 | |
|
1165 | 0 | if( abs( tCoeff[tuPars.m_scanId2BlkPos[firstTestPos].idx] ) > thresTmp ) break; |
1166 | 0 | } |
1167 | 0 | } |
1168 | 0 | else |
1169 | 0 | { |
1170 | 0 | const TCoeff defaultTh = TCoeff( thres / ( defaultQuantisationCoefficient << 2 ) ); |
1171 | |
|
1172 | 0 | if( m_findFirstPos ) |
1173 | 0 | { |
1174 | 0 | m_findFirstPos( firstTestPos, tCoeff, tuPars, defaultTh, zeroOutforThres, zeroOutWidth, zeroOutHeight ); |
1175 | 0 | } |
1176 | |
|
1177 | 0 | for( ; firstTestPos >= 0; firstTestPos-- ) |
1178 | 0 | { |
1179 | 0 | if( zeroOutforThres && ( tuPars.m_scanId2BlkPos[firstTestPos].x >= zeroOutWidth || tuPars.m_scanId2BlkPos[firstTestPos].y >= zeroOutHeight ) ) continue; |
1180 | 0 | if( abs( tCoeff[tuPars.m_scanId2BlkPos[firstTestPos].idx] ) > defaultTh ) break; |
1181 | 0 | } |
1182 | 0 | } |
1183 | |
|
1184 | 0 | if( firstTestPos < 0 ) |
1185 | 0 | { |
1186 | 0 | tu.lastPos[compID] = -1; |
1187 | 0 | return; |
1188 | 0 | } |
1189 | | |
1190 | | //===== real init ===== |
1191 | 0 | RateEstimator::initCtx( tuPars, tu, compID, ctx.getFracBitsAcess() ); |
1192 | 0 | m_commonCtx.reset( tuPars, *this ); |
1193 | 0 | for( int k = 0; k < 4; k++ ) |
1194 | 0 | { |
1195 | 0 | DQIntern::initStates( k, m_state_curr ); |
1196 | 0 | DQIntern::initStates( k, m_state_skip ); |
1197 | 0 | m_state_curr.m_sigFracBitsArray[k] = RateEstimator::sigFlagBits(k); |
1198 | 0 | } |
1199 | |
|
1200 | 0 | m_state_curr.m_gtxFracBitsArray = RateEstimator::gtxFracBits(); |
1201 | | //memset( m_state_curr.tplAcc, 0, sizeof( m_state_curr.tplAcc ) ); // will be set in updateStates{,EOS} before first access |
1202 | 0 | memset( m_state_curr.sum1st, 0, sizeof( m_state_curr.sum1st ) ); // will be accessed in setRiceParam before updateState{,EOS} |
1203 | | //memset( m_state_curr.absVal, 0, sizeof( m_state_curr.absVal ) ); // will be set in updateStates{,EOS} before first access |
1204 | |
|
1205 | 0 | const int numCtx = isLuma( compID ) ? 21 : 11; |
1206 | 0 | const CoeffFracBits* const cffBits = gtxFracBits(); |
1207 | 0 | for( int i = 0; i < numCtx; i++ ) |
1208 | 0 | { |
1209 | 0 | m_state_curr.cffBits1[i] = cffBits[i].bits[1]; |
1210 | 0 | } |
1211 | |
|
1212 | 0 | int effectWidth = std::min( 32, effWidth ); |
1213 | 0 | int effectHeight = std::min( 32, effHeight ); |
1214 | 0 | m_state_curr.initRemRegBins = ( effectWidth * effectHeight * MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT ) / 16; |
1215 | 0 | m_state_curr.anyRemRegBinsLt4 = true; // for the first coeff use scalar impl., because it check against the init state, which |
1216 | | // prohibits some paths |
1217 | | |
1218 | | //===== populate trellis ===== |
1219 | 0 | for( int scanIdx = firstTestPos; scanIdx >= 0; scanIdx-- ) |
1220 | 0 | { |
1221 | 0 | const ScanInfo& scanInfo = tuPars.m_scanInfo[ scanIdx ]; |
1222 | 0 | if( enableScalingLists ) |
1223 | 0 | { |
1224 | 0 | m_quant.initQuantBlock( tu, compID, cQP, lambda, quantCoeff[scanInfo.rasterPos] ); |
1225 | 0 | xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos] ), scanInfo, zeroOut && ( scanInfo.posX >= effWidth || scanInfo.posY >= effHeight ), quantCoeff[scanInfo.rasterPos] ); |
1226 | 0 | } |
1227 | 0 | else |
1228 | 0 | xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos] ), scanInfo, zeroOut && ( scanInfo.posX >= effWidth || scanInfo.posY >= effHeight ), defaultQuantisationCoefficient ); |
1229 | 0 | } |
1230 | | |
1231 | | //===== find best path ===== |
1232 | 0 | int prevId = -1; |
1233 | 0 | int64_t minPathCost = 0; |
1234 | 0 | for( int8_t stateId = 0; stateId < 4; stateId++ ) |
1235 | 0 | { |
1236 | 0 | int64_t pathCost = m_trellis[0][0].rdCost[stateId]; |
1237 | 0 | if( pathCost < minPathCost ) |
1238 | 0 | { |
1239 | 0 | prevId = stateId; |
1240 | 0 | minPathCost = pathCost; |
1241 | 0 | } |
1242 | 0 | } |
1243 | | |
1244 | | //===== backward scanning ===== |
1245 | 0 | int scanIdx = 0; |
1246 | 0 | for( ; prevId >= 0; scanIdx++ ) |
1247 | 0 | { |
1248 | 0 | TCoeffSig absLevel = m_trellis[scanIdx][prevId >> 2].absLevel[prevId & 3]; |
1249 | 0 | int32_t blkpos = tuPars.m_scanId2BlkPos[scanIdx].idx; |
1250 | 0 | qCoeff[ blkpos ] = TCoeffSig( tCoeff[blkpos] < 0 ? -absLevel : absLevel ); |
1251 | 0 | absSum += absLevel; |
1252 | 0 | prevId = m_trellis[scanIdx][prevId >> 2].prevId[prevId & 3]; |
1253 | 0 | } |
1254 | |
|
1255 | 0 | tu.lastPos[compID] = scanIdx - 1; |
1256 | 0 | } |
1257 | | |
1258 | | void DepQuant::xDecide( const DQIntern::ScanInfo& scanInfo, const TCoeff absCoeff, const int lastOffset, DQIntern::Decisions& decisions, bool zeroOut, int quantCoeff ) |
1259 | 0 | { |
1260 | 0 | using namespace DQIntern; |
1261 | |
|
1262 | 0 | ::memcpy( &decisions, startDec, sizeof( Decisions ) ); |
1263 | |
|
1264 | 0 | StateMem& skip = m_state_skip; |
1265 | |
|
1266 | 0 | if( zeroOut ) |
1267 | 0 | { |
1268 | 0 | if( scanInfo.spt == SCAN_EOCSBB ) |
1269 | 0 | { |
1270 | 0 | checkRdCostSkipSbbZeroOut( 0, decisions, 0, skip ); |
1271 | 0 | checkRdCostSkipSbbZeroOut( 1, decisions, 1, skip ); |
1272 | 0 | checkRdCostSkipSbbZeroOut( 2, decisions, 2, skip ); |
1273 | 0 | checkRdCostSkipSbbZeroOut( 3, decisions, 3, skip ); |
1274 | 0 | } |
1275 | 0 | return; |
1276 | 0 | } |
1277 | | |
1278 | 0 | StateMem& prev = m_state_curr; |
1279 | | |
1280 | | /// start inline prequant |
1281 | 0 | int64_t scaledOrg = int64_t( absCoeff ) * quantCoeff; |
1282 | 0 | TCoeff qIdx = TCoeff( ( scaledOrg + m_quant.m_QAdd ) >> m_quant.m_QShift ); |
1283 | |
|
1284 | 0 | if( qIdx < 0 ) |
1285 | 0 | { |
1286 | 0 | int64_t scaledAdd = m_quant.m_DistStepAdd - scaledOrg * m_quant.m_DistOrgFact; |
1287 | 0 | int64_t pq_a_dist = ( ( scaledAdd + 0 * m_quant.m_DistStepAdd ) * 1 + m_quant.m_DistAdd ) >> m_quant.m_DistShift; |
1288 | 0 | int64_t pq_b_dist = ( ( scaledAdd + 1 * m_quant.m_DistStepAdd ) * 2 + m_quant.m_DistAdd ) >> m_quant.m_DistShift; |
1289 | | /// stop inline prequant |
1290 | |
|
1291 | 0 | if( prev.anyRemRegBinsLt4 ) |
1292 | 0 | { |
1293 | 0 | setRiceParam( 0, scanInfo, prev, false ); |
1294 | 0 | checkRdCostsOdd1( 0, scanInfo.spt, pq_b_dist, decisions, 2, 0, prev ); |
1295 | |
|
1296 | 0 | setRiceParam( 1, scanInfo, prev, false ); |
1297 | 0 | checkRdCostsOdd1( 1, scanInfo.spt, pq_b_dist, decisions, 0, 2, prev ); |
1298 | |
|
1299 | 0 | setRiceParam( 2, scanInfo, prev, false ); |
1300 | 0 | checkRdCostsOdd1( 2, scanInfo.spt, pq_a_dist, decisions, 3, 1, prev ); |
1301 | |
|
1302 | 0 | setRiceParam( 3, scanInfo, prev, false ); |
1303 | 0 | checkRdCostsOdd1( 3, scanInfo.spt, pq_a_dist, decisions, 1, 3, prev ); |
1304 | 0 | } |
1305 | 0 | else |
1306 | 0 | { |
1307 | | // has to be called as a first check, assumes no decision has been made yet |
1308 | 0 | m_checkAllRdCostsOdd1( scanInfo.spt, pq_a_dist, pq_b_dist, decisions, prev ); |
1309 | 0 | } |
1310 | |
|
1311 | 0 | checkRdCostStart( lastOffset, PQData{ 1, pq_b_dist }, decisions, 2, prev ); |
1312 | 0 | } |
1313 | 0 | else |
1314 | 0 | { |
1315 | | /// start inline prequant |
1316 | 0 | qIdx = std::max<TCoeff>( 1, std::min<TCoeff>( m_quant.m_maxQIdx, qIdx ) ); |
1317 | 0 | int64_t scaledAdd = qIdx * m_quant.m_DistStepAdd - scaledOrg * m_quant.m_DistOrgFact; |
1318 | |
|
1319 | 0 | PQData pqData[4]; |
1320 | |
|
1321 | 0 | PQData& pq_a = pqData[( qIdx + 0 ) & 3]; |
1322 | 0 | PQData& pq_b = pqData[( qIdx + 1 ) & 3]; |
1323 | 0 | PQData& pq_c = pqData[( qIdx + 2 ) & 3]; |
1324 | 0 | PQData& pq_d = pqData[( qIdx + 3 ) & 3]; |
1325 | |
|
1326 | 0 | pq_a.deltaDist = ( ( scaledAdd + 0 * m_quant.m_DistStepAdd ) * ( qIdx + 0 ) + m_quant.m_DistAdd ) >> m_quant.m_DistShift; |
1327 | 0 | pq_a.absLevel = ( qIdx + 1 ) >> 1; |
1328 | |
|
1329 | 0 | pq_b.deltaDist = ( ( scaledAdd + 1 * m_quant.m_DistStepAdd ) * ( qIdx + 1 ) + m_quant.m_DistAdd ) >> m_quant.m_DistShift; |
1330 | 0 | pq_b.absLevel = ( qIdx + 2 ) >> 1; |
1331 | |
|
1332 | 0 | pq_c.deltaDist = ( ( scaledAdd + 2 * m_quant.m_DistStepAdd ) * ( qIdx + 2 ) + m_quant.m_DistAdd ) >> m_quant.m_DistShift; |
1333 | 0 | pq_c.absLevel = ( qIdx + 3 ) >> 1; |
1334 | |
|
1335 | 0 | pq_d.deltaDist = ( ( scaledAdd + 3 * m_quant.m_DistStepAdd ) * ( qIdx + 3 ) + m_quant.m_DistAdd ) >> m_quant.m_DistShift; |
1336 | 0 | pq_d.absLevel = ( qIdx + 4 ) >> 1; |
1337 | | /// stop inline prequant |
1338 | |
|
1339 | 0 | bool cff02ge4 = pqData[0].absLevel >= 4/* || pqData[2].absLevel >= 4 */; |
1340 | 0 | bool cff13ge4 = /* pqData[1].absLevel >= 4 || */ pqData[3].absLevel >= 4; |
1341 | |
|
1342 | 0 | if( cff02ge4 || cff13ge4 || prev.anyRemRegBinsLt4 ) |
1343 | 0 | { |
1344 | 0 | if( prev.anyRemRegBinsLt4 || cff02ge4 ) |
1345 | 0 | { |
1346 | 0 | setRiceParam( 0, scanInfo, prev, cff02ge4 ); |
1347 | 0 | setRiceParam( 1, scanInfo, prev, cff02ge4 ); |
1348 | 0 | } |
1349 | |
|
1350 | 0 | if( prev.anyRemRegBinsLt4 || cff13ge4 ) |
1351 | 0 | { |
1352 | 0 | setRiceParam( 2, scanInfo, prev, cff13ge4 ); |
1353 | 0 | setRiceParam( 3, scanInfo, prev, cff13ge4 ); |
1354 | 0 | } |
1355 | |
|
1356 | 0 | checkRdCosts( 0, scanInfo.spt, pqData[0], pqData[2], decisions, 0, 2, prev ); |
1357 | 0 | checkRdCosts( 1, scanInfo.spt, pqData[0], pqData[2], decisions, 2, 0, prev ); |
1358 | 0 | checkRdCosts( 2, scanInfo.spt, pqData[3], pqData[1], decisions, 1, 3, prev ); |
1359 | 0 | checkRdCosts( 3, scanInfo.spt, pqData[3], pqData[1], decisions, 3, 1, prev ); |
1360 | 0 | } |
1361 | 0 | else |
1362 | 0 | { |
1363 | | // has to be called as a first check, assumes no decision has been made yet |
1364 | 0 | m_checkAllRdCosts( scanInfo.spt, pqData, decisions, prev ); |
1365 | 0 | } |
1366 | |
|
1367 | 0 | checkRdCostStart( lastOffset, pqData[0], decisions, 0, prev ); |
1368 | 0 | checkRdCostStart( lastOffset, pqData[2], decisions, 2, prev ); |
1369 | 0 | } |
1370 | |
|
1371 | 0 | if( scanInfo.spt == SCAN_EOCSBB ) |
1372 | 0 | { |
1373 | 0 | checkRdCostSkipSbb( 0, decisions, 0, skip ); |
1374 | 0 | checkRdCostSkipSbb( 1, decisions, 1, skip ); |
1375 | 0 | checkRdCostSkipSbb( 2, decisions, 2, skip ); |
1376 | 0 | checkRdCostSkipSbb( 3, decisions, 3, skip ); |
1377 | 0 | } |
1378 | 0 | } |
1379 | | |
1380 | | void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const DQIntern::ScanInfo& scanInfo, bool zeroOut, int quantCoeff ) |
1381 | 0 | { |
1382 | 0 | using namespace DQIntern; |
1383 | |
|
1384 | 0 | Decisions* decisions = &m_trellis[scanInfo.scanIdx][0]; |
1385 | |
|
1386 | 0 | xDecide( scanInfo, absCoeff, lastOffset( scanInfo.scanIdx ), *decisions, zeroOut, quantCoeff ); |
1387 | |
|
1388 | 0 | if( scanInfo.scanIdx ) |
1389 | 0 | { |
1390 | 0 | if( scanInfo.spt == SCAN_SOCSBB ) |
1391 | 0 | { |
1392 | 0 | memcpy( &m_state_skip, &m_state_curr, DQIntern::StateMemSkipCpySize ); |
1393 | 0 | } |
1394 | |
|
1395 | 0 | if( scanInfo.insidePos == 0 ) |
1396 | 0 | { |
1397 | 0 | m_commonCtx.swap(); |
1398 | 0 | m_updateStatesEOS( scanInfo, *decisions, m_state_skip, m_state_curr, m_commonCtx ); |
1399 | 0 | ::memcpy( decisions + 1, decisions, sizeof( Decisions ) ); |
1400 | 0 | } |
1401 | 0 | else if( !zeroOut ) |
1402 | 0 | { |
1403 | 0 | m_updateStates( scanInfo, *decisions, m_state_curr ); |
1404 | 0 | } |
1405 | 0 | } |
1406 | 0 | } |
1407 | | |
1408 | | void DepQuant::xDequantDQ( const TransformUnit& tu, CoeffBuf& recCoeff, const ComponentID compID, const QpParam& cQP, bool enableScalingLists, int* piDequantCoef ) |
1409 | 0 | { |
1410 | 0 | m_quant.dequantBlock( tu, compID, cQP, recCoeff, enableScalingLists, piDequantCoef ); |
1411 | 0 | } |
1412 | | |
1413 | 0 | DepQuant::DepQuant( const Quant* other, bool enc, bool useScalingLists ) : QuantRDOQ2( other, useScalingLists ), RateEstimator(), m_commonCtx() |
1414 | 0 | { |
1415 | 0 | const DepQuant* dq = dynamic_cast<const DepQuant*>( other ); |
1416 | 0 | CHECK( other && !dq, "The DepQuant cast must be successfull!" ); |
1417 | |
|
1418 | 0 | if( !dq ) |
1419 | 0 | { |
1420 | 0 | m_scansRom = std::make_shared<DQIntern::Rom>(); |
1421 | 0 | m_scansRom->init(); |
1422 | 0 | } |
1423 | 0 | else |
1424 | 0 | { |
1425 | 0 | m_scansRom = dq->m_scansRom; |
1426 | 0 | } |
1427 | |
|
1428 | 0 | for( int t = 0; t < ( MAX_TB_SIZEY * MAX_TB_SIZEY ); t++ ) |
1429 | 0 | { |
1430 | 0 | memcpy( m_trellis[t], startDec, sizeof( startDec ) ); |
1431 | 0 | } |
1432 | |
|
1433 | 0 | m_checkAllRdCosts = DQIntern::checkAllRdCosts; |
1434 | 0 | m_checkAllRdCostsOdd1 = DQIntern::checkAllRdCostsOdd1; |
1435 | 0 | m_updateStatesEOS = DQIntern::updateStatesEOS; |
1436 | 0 | m_updateStates = DQIntern::updateStates; |
1437 | 0 | m_findFirstPos = nullptr; |
1438 | |
|
1439 | 0 | #if defined( TARGET_SIMD_X86 ) && ENABLE_SIMD_OPT_QUANT |
1440 | 0 | initDepQuantX86(); |
1441 | 0 | #endif |
1442 | 0 | } |
1443 | | |
1444 | | DepQuant::~DepQuant() |
1445 | 0 | { |
1446 | 0 | } |
1447 | | |
1448 | | void DepQuant::quant( TransformUnit& tu, const ComponentID compID, const CCoeffBuf& pSrc, TCoeff& uiAbsSum, const QpParam& cQP, const Ctx& ctx ) |
1449 | 0 | { |
1450 | 0 | if( tu.cs->picture->useSelectiveRdoq && !xNeedRDOQ( tu, compID, pSrc, cQP ) ) |
1451 | 0 | { |
1452 | 0 | tu.lastPos[compID] = -1; |
1453 | 0 | uiAbsSum = 0; |
1454 | 0 | } |
1455 | 0 | else if( tu.cs->slice->depQuantEnabled && tu.mtsIdx[compID] != MTS_SKIP ) |
1456 | 0 | { |
1457 | | //===== scaling matrix ==== |
1458 | 0 | const int qpDQ = cQP.Qp(tu.mtsIdx[compID]==MTS_SKIP) + 1; |
1459 | 0 | const int qpPer = qpDQ / 6; |
1460 | 0 | const int qpRem = qpDQ - 6 * qpPer; |
1461 | 0 | const CompArea &rect = tu.blocks[compID]; |
1462 | 0 | const int width = rect.width; |
1463 | 0 | const int height = rect.height; |
1464 | 0 | uint32_t scalingListType = getScalingListType(tu.cu->predMode, compID); |
1465 | 0 | CHECK(scalingListType >= SCALING_LIST_NUM, "Invalid scaling list"); |
1466 | 0 | const uint32_t log2TrWidth = Log2(width); |
1467 | 0 | const uint32_t log2TrHeight = Log2(height); |
1468 | 0 | const bool isLfnstApplied = tu.cu->lfnstIdx > 0 && (CU::isSepTree(*tu.cu) ? true : isLuma(compID)); |
1469 | 0 | const bool enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx[compID] == MTS_SKIP), isLfnstApplied); |
1470 | 0 | xQuantDQ( tu, pSrc, compID, cQP, Quant::m_dLambda, ctx, uiAbsSum, enableScalingLists, Quant::getQuantCoeff(scalingListType, qpRem, log2TrWidth, log2TrHeight) ); |
1471 | 0 | } |
1472 | 0 | else |
1473 | 0 | { |
1474 | 0 | QuantRDOQ2::quant( tu, compID, pSrc, uiAbsSum, cQP, ctx ); |
1475 | 0 | } |
1476 | 0 | } |
1477 | | |
1478 | | void DepQuant::dequant( const TransformUnit& tu, CoeffBuf& dstCoeff, const ComponentID compID, const QpParam& cQP ) |
1479 | 0 | { |
1480 | 0 | if( tu.cs->slice->depQuantEnabled && (tu.mtsIdx[compID] != MTS_SKIP) ) |
1481 | 0 | { |
1482 | 0 | const int qpDQ = cQP.Qp(tu.mtsIdx[compID]==MTS_SKIP) + 1; |
1483 | 0 | const int qpPer = qpDQ / 6; |
1484 | 0 | const int qpRem = qpDQ - 6 * qpPer; |
1485 | 0 | const CompArea &rect = tu.blocks[compID]; |
1486 | 0 | const int width = rect.width; |
1487 | 0 | const int height = rect.height; |
1488 | 0 | uint32_t scalingListType = getScalingListType(tu.cu->predMode, compID); |
1489 | 0 | CHECK(scalingListType >= SCALING_LIST_NUM, "Invalid scaling list"); |
1490 | 0 | const uint32_t log2TrWidth = Log2(width); |
1491 | 0 | const uint32_t log2TrHeight = Log2(height); |
1492 | 0 | const bool isLfnstApplied = tu.cu->lfnstIdx > 0 && (CU::isSepTree(*tu.cu) ? true : isLuma(compID)); |
1493 | 0 | const bool enableScalingLists = getUseScalingList(width, height, (tu.mtsIdx[compID] == MTS_SKIP), isLfnstApplied); |
1494 | 0 | xDequantDQ( tu, dstCoeff, compID, cQP, enableScalingLists, Quant::getDequantCoeff(scalingListType, qpRem, log2TrWidth, log2TrHeight) ); |
1495 | 0 | } |
1496 | 0 | else |
1497 | 0 | { |
1498 | 0 | QuantRDOQ::dequant( tu, dstCoeff, compID, cQP ); |
1499 | 0 | } |
1500 | 0 | } |
1501 | | |
1502 | | void DepQuant::init( int rdoq, bool useRDOQTS, int thrVal ) |
1503 | 0 | { |
1504 | 0 | QuantRDOQ2::init( rdoq, useRDOQTS, thrVal ); |
1505 | 0 | m_quant.init( thrVal ); |
1506 | 0 | } |
1507 | | |
1508 | | } // namespace vvenc |
1509 | | |
1510 | | //! \} |
1511 | | |