1 /* -----------------------------------------------------------------------------
2 The copyright in this software is being made available under the 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 For any license concerning other Intellectual Property rights than the software,
8 especially patent licenses, a separate Agreement needs to be closed.
9 For more information please contact:
10
11 Fraunhofer Heinrich Hertz Institute
12 Einsteinufer 37
13 10587 Berlin, Germany
14 www.hhi.fraunhofer.de/vvc
15 vvc@hhi.fraunhofer.de
16
17 Copyright (c) 2018-2021, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
18 All rights reserved.
19
20 Redistribution and use in source and binary forms, with or without
21 modification, are permitted provided that the following conditions are met:
22
23 * Redistributions of source code must retain the above copyright notice,
24 this list of conditions and the following disclaimer.
25 * Redistributions in binary form must reproduce the above copyright notice,
26 this list of conditions and the following disclaimer in the documentation
27 and/or other materials provided with the distribution.
28 * Neither the name of Fraunhofer nor the names of its contributors may
29 be used to endorse or promote products derived from this software without
30 specific prior written permission.
31
32 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
36 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
42 THE POSSIBILITY OF SUCH DAMAGE.
43
44
45 ------------------------------------------------------------------------------------------- */
46
47 /** \file Quant.cpp
48 \brief transform and quantization class
49 */
50
51 #include "Quant.h"
52
53 #include "UnitTools.h"
54 #include "ContextModelling.h"
55 #include "CodingStructure.h"
56
57 #include "dtrace_buffer.h"
58
59 #include <stdlib.h>
60 #include <limits>
61 #include <memory.h>
62
63 namespace vvdec
64 {
65
66 // ====================================================================================================================
67 // QpParam constructor
68 // ====================================================================================================================
69
QpParam(const TransformUnit & tu,const ComponentID & compIDX,const bool allowACTQpoffset)70 QpParam::QpParam( const TransformUnit& tu, const ComponentID& compIDX, const bool allowACTQpoffset )
71 {
72 const ComponentID compID = MAP_CHROMA( compIDX );
73 const ChannelType chType = toChannelType( compID );
74 const SPS& sps = *tu.cu->sps;
75 const int qpBdOffset = sps.getQpBDOffset( chType );
76 const bool useJQP = isChroma( compID ) && TU::getICTMode( tu, false ) == 2;
77 const ComponentID jCbCr = useJQP ? JOINT_CbCr : compID;
78
79 int baseQp;
80 int qpy = tu.cu->qp;
81 //bool skip = tu.mtsIdx[compID] == MTS_SKIP;
82
83 if( isLuma( compID ) )
84 {
85 baseQp = qpy + qpBdOffset;
86 }
87 else
88 {
89 const PPS &pps = *tu.cu->pps;
90 int
91 chromaQpOffset = pps.getQpOffset ( jCbCr );
92 chromaQpOffset += tu.cu->slice->getSliceChromaQpDelta( jCbCr );
93 chromaQpOffset += pps.getChromaQpOffsetListEntry( tu.cu->chromaQpAdj ).u.offset[int( jCbCr ) - 1];
94
95 int qpi = Clip3( -qpBdOffset, MAX_QP, qpy );
96 baseQp = sps.getMappedChromaQpValue( jCbCr, qpi );
97 baseQp = Clip3( 0, MAX_QP + qpBdOffset, baseQp + chromaQpOffset + qpBdOffset );
98 }
99
100 if( allowACTQpoffset && tu.cu->colorTransform() )
101 {
102 baseQp += DELTA_QP_ACT[jCbCr];
103 baseQp = Clip3( 0, MAX_QP + qpBdOffset, baseQp );
104 }
105
106 // TODO: ensure clip not needed for non-ACT
107
108 //if( !skip )
109 {
110 Qps [0] = baseQp;
111 pers[0] = baseQp / 6;
112 rems[0] = baseQp - ( pers[0] << 2 ) - ( pers[0] << 1 );
113 }
114 //else
115 {
116 int internalMinusInputBitDepth = sps.getInternalMinusInputBitDepth( chType );
117 int baseQpTS = std::max( baseQp, 4 + 6 * internalMinusInputBitDepth );
118 Qps [1] = baseQpTS;
119 pers[1] = baseQpTS / 6;
120 rems[1] = baseQpTS - ( pers[1] << 2 ) - ( pers[1] << 1 );;
121 }
122 }
123
124 // ====================================================================================================================
125 // Quant class member functions
126 // ====================================================================================================================
127
DeQuantCore(const int maxX,const int restX,const int maxY,const int scale,const TCoeffSig * const piQCoef,const size_t piQCfStride,TCoeff * const piCoef,const int rightShift,const int inputMaximum,const TCoeff transformMaximum)128 static void DeQuantCore( const int maxX,
129 const int restX,
130 const int maxY,
131 const int scale,
132 const TCoeffSig* const piQCoef,
133 const size_t piQCfStride,
134 TCoeff* const piCoef,
135 const int rightShift,
136 const int inputMaximum,
137 const TCoeff transformMaximum )
138 {
139 const int inputMinimum = -( inputMaximum + 1 );
140 const TCoeff transformMinimum = -( transformMaximum );
141
142 if (rightShift>0)
143 {
144 const Intermediate_Int iAdd = (Intermediate_Int) 1 << (rightShift - 1);
145
146
147 for( int y = 0, n = 0; y <= maxY; y++)
148 {
149 for( int x = 0; x <= maxX; x++, n++ )
150 {
151 const TCoeff level = piQCoef[x + y * piQCfStride];
152
153 if( level )
154 {
155 const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, level));
156 Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale + iAdd) >> rightShift;
157 piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
158 }
159 }
160 n += restX;
161 }
162 }
163 else // rightshift <0
164 {
165 int leftShift = -rightShift;
166 for( int y = 0, n = 0; y <= maxY; y++)
167 {
168 for( int x = 0; x <= maxX; x++, n++ )
169 {
170 const TCoeff level = piQCoef[x + y * piQCfStride];
171
172 if( level )
173 {
174 const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, level));
175 const Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale) << leftShift;
176
177 piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
178 }
179 }
180 n += restX;
181 }
182
183 }
184 }
185
DeQuantPCMCore(const int maxX,const int restX,const int maxY,const int scale,TCoeff * const piQCoef,const size_t piQCfStride,TCoeff * const piCoef,const int rightShift,const int inputMaximum,const TCoeff transformMaximum)186 static void DeQuantPCMCore( const int maxX,
187 const int restX,
188 const int maxY,
189 const int scale,
190 TCoeff* const piQCoef,
191 const size_t piQCfStride,
192 TCoeff* const piCoef,
193 const int rightShift,
194 const int inputMaximum,
195 const TCoeff transformMaximum )
196 {
197 const int inputMinimum = -( inputMaximum + 1 );
198 const TCoeff transformMinimum = -( transformMaximum );
199
200 if (rightShift > 0)
201 {
202 const Intermediate_Int iAdd = (Intermediate_Int) 1 << (rightShift - 1);
203 for( int y = 0, n = 0; y <= maxY; y++)
204 {
205 for( int x = 0; x <= maxX; x++, n++ )
206 {
207 const TCoeff level = piQCoef[x + y * piQCfStride];
208 if( level )
209 {
210 const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, level));
211 const Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale + iAdd) >> rightShift;
212
213 piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
214 }
215 }
216 n += restX;
217 }
218 }
219 else
220 {
221 int leftShift = -rightShift;
222 for( int y = 0, n = 0; y <= maxY; y++)
223 {
224 for( int x = 0; x <= maxX; x++, n++ )
225 {
226 const TCoeff level = piQCoef[x + y * piQCfStride];
227 if( level )
228 {
229 const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, level));
230 const Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale) << leftShift;
231
232 piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
233 }
234 }
235 n += restX;
236 }
237 }
238 }
239
Quant()240 Quant::Quant()
241 {
242 xInitScalingList( nullptr );
243 DeQuant= DeQuantCore;
244 DeQuantPCM = DeQuantPCMCore;
245 #if ENABLE_SIMD_OPT_QUANT && defined( TARGET_SIMD_X86 )
246 initQuantX86();
247 #endif
248
249 }
250
~Quant()251 Quant::~Quant()
252 {
253 xDestroyScalingList();
254 }
255
invResDPCM(const TransformUnit & tu,const ComponentID & compID,CoeffBuf & dstBuf)256 void invResDPCM( const TransformUnit &tu, const ComponentID &compID, CoeffBuf &dstBuf )
257 {
258 const CompArea& rect = tu.blocks[compID];
259 const int wdt = rect.width;
260 const int hgt = rect.height;
261 const CCoeffSigBuf coeffs = tu.cu->cs->getRecoBuf( tu.block( compID ) );
262
263 const int maxLog2TrDynamicRange = tu.cu->sps->getMaxLog2TrDynamicRange(toChannelType(compID));
264 const TCoeff inputMinimum = -(1 << maxLog2TrDynamicRange);
265 const TCoeff inputMaximum = (1 << maxLog2TrDynamicRange) - 1;
266
267 const TCoeffSig* coef = &coeffs.buf[0];
268 TCoeff* dst = &dstBuf.buf[0];
269
270 if( isLuma( compID ) ? tu.cu->bdpcmMode() == 1 : tu.cu->bdpcmModeChroma() == 1 )
271 {
272 for( int y = 0; y < hgt; y++ )
273 {
274 dst[0] = coef[0];
275 for( int x = 1; x < wdt; x++ )
276 {
277 dst[x] = Clip3(inputMinimum, inputMaximum, dst[x - 1] + coef[x]);
278 }
279 coef += coeffs.stride;
280 dst += dstBuf.stride;
281 }
282 }
283 else
284 {
285 for( int x = 0; x < wdt; x++ )
286 {
287 dst[x] = coef[x];
288 }
289 for( int y = 0; y < hgt - 1; y++ )
290 {
291 for( int x = 0; x < wdt; x++ )
292 {
293 dst[dstBuf.stride + x] = Clip3(inputMinimum, inputMaximum, dst[x] + coef[coeffs.stride + x]);
294 }
295 coef += coeffs.stride;
296 dst += dstBuf.stride;
297 }
298 }
299 }
300
dequant(const TransformUnit & tu,CoeffBuf & dstCoeff,const ComponentID & compID,const QpParam & cQP)301 void Quant::dequant( const TransformUnit& tu, CoeffBuf& dstCoeff, const ComponentID& compID, const QpParam& cQP )
302 {
303 const SPS* sps = tu.cu->sps;
304 const CompArea& area = tu.blocks[compID];
305 const CCoeffSigBuf coeffBuf = tu.cu->cs->getRecoBuf( tu.block( compID ) );
306 const TCoeffSig* const piQCoef = coeffBuf.buf;
307 const size_t piQCfStride = coeffBuf.stride;
308 TCoeff* const piCoef = dstCoeff.buf;
309 const int maxLog2TrDynamicRange = sps->getMaxLog2TrDynamicRange( toChannelType( compID ) );
310 const TCoeff transformMinimum = -( 1 << maxLog2TrDynamicRange );
311 const TCoeff transformMaximum = ( 1 << maxLog2TrDynamicRange ) - 1;
312 const bool isTransformSkip = ( tu.mtsIdx( compID ) == MTS_SKIP );
313 setUseScalingList( tu.cu->slice->getExplicitScalingListUsed() );
314 const bool disableSMForLFNST = tu.cu->slice->getExplicitScalingListUsed() ? sps->getDisableScalingMatrixForLfnstBlks() : false;
315 const bool isLfnstApplied = tu.cu->lfnstIdx() > 0 && ( CU::isSepTree( *tu.cu ) ? true : isLuma( compID ) );
316 const bool disableSMForACT = tu.cu->sps->getScalingMatrixForAlternativeColourSpaceDisabledFlag() && tu.cu->sps->getScalingMatrixDesignatedColourSpaceFlag() == tu.cu->colorTransform();
317 const bool enableScalingLists = getUseScalingList( isTransformSkip, isLfnstApplied, disableSMForLFNST, disableSMForACT );
318 const int scalingListType = getScalingListType( tu.cu->predMode(), compID );
319 const int channelBitDepth = sps->getBitDepth( toChannelType( compID ) );
320
321 int maxX, maxY;
322
323
324 if( ( tu.cu->bdpcmMode() && isLuma(compID) ) || ( tu.cu->bdpcmModeChroma() && isChroma(compID) ) )
325 {
326 invResDPCM( tu, compID, dstCoeff );
327 maxX = area.width - 1;
328 maxY = area.height - 1;
329 }
330 else
331 {
332 maxX = tu.maxScanPosX[compID];
333 maxY = tu.maxScanPosY[compID];
334 }
335
336 CHECK(scalingListType >= SCALING_LIST_NUM, "Invalid scaling list");
337
338 // Represents scaling through forward transform
339 const bool bClipTransformShiftTo0 = false;// tu.mtsIdx[compID] != 1 && sps->getSpsRangeExtension().getExtendedPrecisionProcessingFlag();
340 const int originalTransformShift = getTransformShift(channelBitDepth, area.size(), maxLog2TrDynamicRange);
341 const bool needSqrtAdjustment = TU::needsBlockSizeTrafoScale( tu, compID );
342 const int iTransformShift = (bClipTransformShiftTo0 ? std::max<int>(0, originalTransformShift) : originalTransformShift) + (needSqrtAdjustment?-1:0);
343 const bool depQuant = tu.cu->slice->getDepQuantEnabledFlag() && ( tu.mtsIdx( compID ) != MTS_SKIP );
344 const int QP_per = depQuant ? ( ( cQP.Qp( isTransformSkip ) + 1 ) / 6 ) : cQP.per( isTransformSkip );
345 const int QP_rem = depQuant ? ( cQP.Qp( isTransformSkip ) + 1 - 6 * QP_per ) : cQP.rem( isTransformSkip );
346 const int rightShift = (IQUANT_SHIFT + ( depQuant ? 1 : 0 ) - ((isTransformSkip ? 0 : iTransformShift) + QP_per)) + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0);
347
348 {
349 const uint32_t uiLog2TrWidth = getLog2(area.width);
350 const uint32_t uiLog2TrHeight = getLog2(area.height);
351
352 int scale = g_InvQuantScales[needSqrtAdjustment?1:0][QP_rem];
353
354 const int scaleBits = ( IQUANT_SHIFT + 1 );
355
356 //from the dequantisation equation:
357 //iCoeffQ = Intermediate_Int((int64_t(clipQCoef) * scale + iAdd) >> rightShift);
358 //(sizeof(Intermediate_Int) * 8) = inputBitDepth + scaleBits - rightShift
359 const uint32_t targetInputBitDepth = std::min<uint32_t>((maxLog2TrDynamicRange + 1), (((sizeof(Intermediate_Int) * 8) + rightShift) - scaleBits));
360 const Intermediate_Int inputMinimum = -(1 << (targetInputBitDepth - 1));
361 const Intermediate_Int inputMaximum = (1 << (targetInputBitDepth - 1)) - 1;
362
363 const int restX = area.width - maxX - 1;
364
365 if (!enableScalingLists)
366 {
367 if( ( tu.cu->bdpcmMode() && isLuma( compID ) ) || ( tu.cu->bdpcmModeChroma() && isChroma( compID ) ) )
368 {
369 TCoeff* dst = &dstCoeff.buf[0];
370 DeQuantPCM(maxX,restX,maxY,scale,dst,dstCoeff.stride,piCoef,rightShift,inputMaximum,transformMaximum);
371
372 }
373 else
374 {
375 DeQuant(maxX,restX,maxY,scale,piQCoef,piQCfStride,piCoef,rightShift,inputMaximum,transformMaximum);
376 }
377 }
378 else
379 {
380 int* piDequantCoef = getDequantCoeff( scalingListType, QP_rem, uiLog2TrWidth, uiLog2TrHeight );
381
382 if( ( tu.cu->bdpcmMode() && isLuma(compID) ) || ( tu.cu->bdpcmModeChroma() && isChroma(compID) ) )
383 {
384 TCoeff* dst = &dstCoeff.buf[0];
385
386 if (rightShift > 0)
387 {
388 const Intermediate_Int iAdd = (Intermediate_Int) 1 << (rightShift - 1);
389 for( int y = 0, n = 0; y <= maxY; y++)
390 {
391 for( int x = 0; x <= maxX; x++, n++ )
392 {
393 const TCoeff level = dst[x + y * dstCoeff.stride];
394
395 if( level )
396 {
397 scale = piDequantCoef[n];
398
399 const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, level));
400 const Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale + iAdd) >> rightShift;
401
402 piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
403 }
404 }
405 n += restX;
406 }
407 }
408 else
409 {
410 int leftShift = -rightShift;
411 for( int y = 0, n = 0; y <= maxY; y++)
412 {
413 for( int x = 0; x <= maxX; x++, n++ )
414 {
415 const TCoeff level = dst[x + y * dstCoeff.stride];
416
417 if( level )
418 {
419 scale = piDequantCoef[n];
420
421 const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, level));
422 const Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale) << leftShift;
423
424 piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
425 }
426 }
427 n += restX;
428 }
429 }
430 }
431 else
432 {
433 if (rightShift > 0)
434 {
435 const Intermediate_Int iAdd = (Intermediate_Int) 1 << (rightShift - 1);
436
437 for( int y = 0, n = 0; y <= maxY; y++)
438 {
439 for( int x = 0; x <= maxX; x++, n++ )
440 {
441 const TCoeff level = piQCoef[x + y * piQCfStride];
442
443 if( level )
444 {
445 scale = piDequantCoef[n];
446
447 const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, level));
448 Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale + iAdd) >> rightShift;
449
450 piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
451 }
452 }
453 n += restX;
454 }
455 }
456 else
457 {
458 int leftShift = -rightShift;
459 for( int y = 0, n = 0; y <= maxY; y++)
460 {
461 for( int x = 0; x <= maxX; x++, n++ )
462 {
463 const TCoeff level = piQCoef[x + y * piQCfStride];
464
465 if( level )
466 {
467 scale = piDequantCoef[n];
468
469 const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, level));
470 const Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale) << leftShift;
471
472 piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
473 }
474 }
475 n += restX;
476 }
477 }
478 }
479 }
480 }
481 }
482
483 /** set quantized matrix coefficient for decode
484 * \param scalingList quantized matrix address
485 * \param format chroma format
486 */
setScalingListDec(ScalingList & scalingList)487 void Quant::setScalingListDec( ScalingList& scalingList )
488 {
489 const int minimumQp = 0;
490 const int maximumQp = SCALING_LIST_REM_NUM;
491
492 int scalingListId = 0;
493 int recScalingListId = 0;
494 for( uint32_t size = SCALING_LIST_FIRST_CODED; size <= SCALING_LIST_LAST_CODED; size++ )
495 {
496 for( uint32_t list = 0; list < SCALING_LIST_NUM; list++ )
497 {
498 if( size == SCALING_LIST_2x2 && list < 4 ) // skip 2x2 luma
499 {
500 continue;
501 }
502 scalingListId = g_scalingListId[size][list];
503 for( int qp = minimumQp; qp < maximumQp; qp++ )
504 {
505 xSetScalingListDec( scalingList, list, size, qp, scalingListId );
506 }
507 }
508 }
509 // based on square result and apply downsample technology
510 for( uint32_t sizew = 0; sizew <= SCALING_LIST_LAST_CODED; sizew++ ) // 7
511 {
512 for( uint32_t sizeh = 0; sizeh <= SCALING_LIST_LAST_CODED; sizeh++ ) // 7
513 {
514 if( sizew == sizeh || ( sizew == SCALING_LIST_1x1 && sizeh < SCALING_LIST_4x4 ) || ( sizeh == SCALING_LIST_1x1 && sizew < SCALING_LIST_4x4 ) )
515 {
516 continue;
517 }
518 for( uint32_t list = 0; list < SCALING_LIST_NUM; list++ ) // 9
519 {
520 int largerSide = ( sizew > sizeh ) ? sizew : sizeh;
521 CHECK( largerSide < SCALING_LIST_4x4, "Rectangle Error!" );
522 recScalingListId = g_scalingListId[largerSide][list];
523 for( int qp = minimumQp; qp < maximumQp; qp++ )
524 {
525 xSetRecScalingListDec( scalingList, list, sizew, sizeh, qp, recScalingListId );
526 }
527 }
528 }
529 }
530 }
531
532 /** set quantized matrix coefficient for decode
533 * \param scalingList quantaized matrix address
534 * \param listId List index
535 * \param sizeId size index
536 * \param qp Quantization parameter
537 * \param format chroma format
538 */
xSetScalingListDec(const ScalingList & scalingList,uint32_t listId,uint32_t sizeId,int qp,uint32_t scalingListId)539 void Quant::xSetScalingListDec(const ScalingList &scalingList, uint32_t listId, uint32_t sizeId, int qp, uint32_t scalingListId)
540 {
541 uint32_t width = g_vvcScalingListSizeX[sizeId];
542 uint32_t height = g_vvcScalingListSizeX[sizeId];
543 uint32_t ratio = g_vvcScalingListSizeX[sizeId]/std::min(MAX_MATRIX_SIZE_NUM,(int)g_vvcScalingListSizeX[sizeId]);
544 int *dequantcoeff;
545 const int *coeff = scalingList.getScalingListAddress(scalingListId);
546
547 dequantcoeff = getDequantCoeff(listId, qp, sizeId, sizeId);
548
549 const int blockIsNotPowerOf4 = ( getLog2( width ) + getLog2( height ) ) & 1;
550 int invQuantScale = g_InvQuantScales[blockIsNotPowerOf4][qp];
551
552 processScalingListDec(coeff,
553 dequantcoeff,
554 invQuantScale,
555 height, width, ratio,
556 std::min(MAX_MATRIX_SIZE_NUM, (int)g_vvcScalingListSizeX[sizeId]),
557 scalingList.getScalingListDC(scalingListId));
558 }
559
560 /** set quantized matrix coefficient for decode
561 * \param scalingList quantaized matrix address
562 * \param listId List index
563 * \param sizeId size index
564 * \param qp Quantization parameter
565 * \param format chroma format
566 */
xSetRecScalingListDec(const ScalingList & scalingList,uint32_t listId,uint32_t sizeIdw,uint32_t sizeIdh,int qp,uint32_t scalingListId)567 void Quant::xSetRecScalingListDec(const ScalingList &scalingList, uint32_t listId, uint32_t sizeIdw, uint32_t sizeIdh, int qp, uint32_t scalingListId)
568 {
569 if (sizeIdw == sizeIdh) return;
570 uint32_t width = g_vvcScalingListSizeX[sizeIdw];
571 uint32_t height = g_vvcScalingListSizeX[sizeIdh];
572 uint32_t largeSideId = (sizeIdw > sizeIdh) ? sizeIdw : sizeIdh; //16
573
574 const int *coeff = scalingList.getScalingListAddress(scalingListId);
575 int *dequantcoeff;
576 dequantcoeff = getDequantCoeff(listId, qp, sizeIdw, sizeIdh);
577 const int blockIsNotPowerOf4 = ( getLog2( width ) + getLog2( height ) ) & 1;
578 int invQuantScale = g_InvQuantScales[blockIsNotPowerOf4][qp];
579 processScalingListDec(coeff,
580 dequantcoeff,
581 invQuantScale,
582 height, width, (largeSideId>3) ? 2 : 1,
583 (largeSideId >= 3 ? 8 : 4),
584 scalingList.getScalingListDC(scalingListId));
585 }
586
587 /** set quantized matrix coefficient for decode
588 * \param coeff quantaized matrix address
589 * \param dequantcoeff quantaized matrix address
590 * \param invQuantScales IQ(QP%6))
591 * \param height height
592 * \param width width
593 * \param ratio ratio for upscale
594 * \param sizuNum matrix size
595 * \param dc dc parameter
596 */
processScalingListDec(const int * coeff,int * dequantcoeff,int invQuantScales,uint32_t height,uint32_t width,uint32_t ratio,int sizuNum,uint32_t dc)597 void Quant::processScalingListDec( const int *coeff, int *dequantcoeff, int invQuantScales, uint32_t height, uint32_t width, uint32_t ratio, int sizuNum, uint32_t dc)
598 {
599 if (height != width)
600 {
601 for (uint32_t j = 0; j<height; j++)
602 {
603 for (uint32_t i = 0; i<width; i++)
604 {
605 if (i >= JVET_C0024_ZERO_OUT_TH || j >= JVET_C0024_ZERO_OUT_TH)
606 {
607 dequantcoeff[j*width + i] = 0;
608 continue;
609 }
610 int ratioWH = height > width ? height / width : width / height;
611 int ratioH = height / sizuNum ? height / sizuNum : sizuNum / height;
612 int ratioW = width / sizuNum ? width / sizuNum : sizuNum / width;
613 //sizeNum = 8/4
614 if (height > width)
615 {
616 dequantcoeff[j*width + i] = invQuantScales * coeff[sizuNum * (j / ratioH) + ((i * ratioWH) / ratioH)];
617 }
618 else //ratioH < ratioW
619 {
620 dequantcoeff[j*width + i] = invQuantScales * coeff[sizuNum * ((j * ratioWH) / ratioW) + (i / ratioW)];
621 }
622 int largeOne = std::max( width, height );
623 if( largeOne > 8 )
624 {
625 dequantcoeff[0] = invQuantScales * dc;
626 }
627 }
628 }
629 return;
630 }
631 for(uint32_t j=0;j<height;j++)
632 {
633 for(uint32_t i=0;i<width;i++)
634 {
635 dequantcoeff[j*width + i] = invQuantScales * coeff[sizuNum * (j / ratio) + i / ratio];
636 }
637 }
638
639 if(ratio > 1)
640 {
641 dequantcoeff[0] = invQuantScales * dc;
642 }
643 }
644
645 /** initialization process of scaling list array
646 */
xInitScalingList(const Quant * other)647 void Quant::xInitScalingList( const Quant* other )
648 {
649 size_t numQuants = 0;
650
651 for(uint32_t sizeIdX = 0; sizeIdX < SCALING_LIST_SIZE_NUM; sizeIdX++)
652 {
653 for(uint32_t sizeIdY = 0; sizeIdY < SCALING_LIST_SIZE_NUM; sizeIdY++)
654 {
655 for(uint32_t qp = 0; qp < SCALING_LIST_REM_NUM; qp++)
656 {
657 for(uint32_t listId = 0; listId < SCALING_LIST_NUM; listId++)
658 {
659 m_dequantCoef [sizeIdX][sizeIdY][listId][qp] = &m_dequantCoefBuf[numQuants];
660 numQuants += g_vvcScalingListSizeX[sizeIdX] * g_vvcScalingListSizeX[sizeIdY];
661 } // listID loop
662 }
663 }
664 }
665 }
666
667 /** destroy quantization matrix array
668 */
xDestroyScalingList()669 void Quant::xDestroyScalingList()
670 {
671 }
672
init(const Picture * pic)673 void Quant::init( const Picture *pic )
674 {
675 const Slice* scalingListSlice = nullptr;
676
677 for( const Slice* slice : pic->slices )
678 {
679 if( slice->getExplicitScalingListUsed() )
680 {
681 scalingListSlice = slice;
682 break;
683 }
684 }
685
686 const Slice* slice = scalingListSlice;
687
688 if( slice && slice->getExplicitScalingListUsed() )
689 {
690 std::shared_ptr<APS> scalingListAPS = slice->getPicHeader()->getScalingListAPS();
691 if( slice->getNalUnitLayerId() != scalingListAPS->getLayerId() )
692 {
693 CHECK( scalingListAPS->getLayerId() > slice->getNalUnitLayerId(), "Layer Id of APS cannot be greater than layer Id of VCL NAL unit the refer to it" );
694 CHECK( slice->getSPS()->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of APS and layer Id of current slice are different" );
695 for( int i = 0; i < slice->getVPS()->getNumOutputLayerSets(); i++ )
696 {
697 bool isCurrLayerInOls = false;
698 bool isRefLayerInOls = false;
699 for( int j = slice->getVPS()->getNumLayersInOls(i) - 1; j >= 0; j-- )
700 {
701 if( slice->getVPS()->getLayerIdInOls(i, j) == slice->getNalUnitLayerId() )
702 {
703 isCurrLayerInOls = true;
704 }
705 if( slice->getVPS()->getLayerIdInOls(i, j) == scalingListAPS->getLayerId() )
706 {
707 isRefLayerInOls = true;
708 }
709 }
710 CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to APS in layer B, all OLS that contains layer A shall also contains layer B" );
711 }
712 }
713 ScalingList scalingList = scalingListAPS->getScalingList();
714 setScalingListDec(scalingList);
715 setUseScalingList(true);
716 }
717 else
718 {
719 setUseScalingList( false );
720 }
721 }
722
723 }
724