/src/vvenc/source/Lib/CommonLib/Unit.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 | | |
44 | | /** \file Unit.cpp |
45 | | * \brief defines unit as a set of blocks and basic unit types (coding, prediction, transform) |
46 | | */ |
47 | | |
48 | | #include "Unit.h" |
49 | | #include "Picture.h" |
50 | | #include "UnitTools.h" |
51 | | #include "UnitPartitioner.h" |
52 | | |
53 | | //! \ingroup CommonLib |
54 | | //! \{ |
55 | | |
56 | | namespace vvenc { |
57 | | |
58 | | // --------------------------------------------------------------------------- |
59 | | // block method definitions |
60 | | // --------------------------------------------------------------------------- |
61 | | |
62 | | void CompArea::xRecalcLumaToChroma() |
63 | 0 | { |
64 | 0 | const uint32_t csx = getComponentScaleX(compID, chromaFormat); |
65 | 0 | const uint32_t csy = getComponentScaleY(compID, chromaFormat); |
66 | |
|
67 | 0 | x >>= csx; |
68 | 0 | y >>= csy; |
69 | 0 | width >>= csx; |
70 | 0 | height >>= csy; |
71 | 0 | } |
72 | | |
73 | | Position CompArea::chromaPos() const |
74 | 0 | { |
75 | 0 | if (isLuma(compID)) |
76 | 0 | { |
77 | 0 | uint32_t scaleX = getComponentScaleX(compID, chromaFormat); |
78 | 0 | uint32_t scaleY = getComponentScaleY(compID, chromaFormat); |
79 | |
|
80 | 0 | return Position(x >> scaleX, y >> scaleY); |
81 | 0 | } |
82 | 0 | else |
83 | 0 | { |
84 | 0 | return *this; |
85 | 0 | } |
86 | 0 | } |
87 | | |
88 | | Size CompArea::lumaSize() const |
89 | 0 | { |
90 | 0 | if( isChroma( compID ) ) |
91 | 0 | { |
92 | 0 | uint32_t scaleX = getComponentScaleX( compID, chromaFormat ); |
93 | 0 | uint32_t scaleY = getComponentScaleY( compID, chromaFormat ); |
94 | |
|
95 | 0 | return Size( width << scaleX, height << scaleY ); |
96 | 0 | } |
97 | 0 | else |
98 | 0 | { |
99 | 0 | return *this; |
100 | 0 | } |
101 | 0 | } |
102 | | |
103 | | Size CompArea::chromaSize() const |
104 | 0 | { |
105 | 0 | if( isLuma( compID ) ) |
106 | 0 | { |
107 | 0 | uint32_t scaleX = getComponentScaleX( compID, chromaFormat ); |
108 | 0 | uint32_t scaleY = getComponentScaleY( compID, chromaFormat ); |
109 | |
|
110 | 0 | return Size( width >> scaleX, height >> scaleY ); |
111 | 0 | } |
112 | 0 | else |
113 | 0 | { |
114 | 0 | return *this; |
115 | 0 | } |
116 | 0 | } |
117 | | |
118 | | Position CompArea::lumaPos() const |
119 | 0 | { |
120 | 0 | if( isChroma( compID ) ) |
121 | 0 | { |
122 | 0 | uint32_t scaleX = getComponentScaleX( compID, chromaFormat ); |
123 | 0 | uint32_t scaleY = getComponentScaleY( compID, chromaFormat ); |
124 | |
|
125 | 0 | return Position( x << scaleX, y << scaleY ); |
126 | 0 | } |
127 | 0 | else |
128 | 0 | { |
129 | 0 | return *this; |
130 | 0 | } |
131 | 0 | } |
132 | | |
133 | | Position CompArea::compPos( const ComponentID compID ) const |
134 | 0 | { |
135 | 0 | return isLuma( compID ) ? lumaPos() : chromaPos(); |
136 | 0 | } |
137 | | |
138 | | Position CompArea::chanPos( const ChannelType chType ) const |
139 | 0 | { |
140 | 0 | return isLuma( chType ) ? lumaPos() : chromaPos(); |
141 | 0 | } |
142 | | |
143 | | // --------------------------------------------------------------------------- |
144 | | // unit method definitions |
145 | | // --------------------------------------------------------------------------- |
146 | | |
147 | 0 | UnitArea::UnitArea(const ChromaFormat _chromaFormat) : chromaFormat(_chromaFormat) { } |
148 | | |
149 | 0 | UnitArea::UnitArea(const ChromaFormat _chromaFormat, const Area& _area) : chromaFormat(_chromaFormat), blocks(getNumberValidComponents(_chromaFormat)) |
150 | 0 | { |
151 | 0 | const uint32_t numCh = getNumberValidComponents(chromaFormat); |
152 | |
|
153 | 0 | for (uint32_t i = 0; i < numCh; i++) |
154 | 0 | { |
155 | 0 | new (&blocks[i]) CompArea(ComponentID(i), chromaFormat, _area, true); |
156 | 0 | } |
157 | 0 | } |
158 | | |
159 | 0 | UnitArea::UnitArea(const ChromaFormat _chromaFormat, const CompArea& blkY) : chromaFormat(_chromaFormat), blocks { blkY } {} |
160 | | |
161 | 0 | UnitArea::UnitArea(const ChromaFormat _chromaFormat, CompArea&& blkY) : chromaFormat(_chromaFormat), blocks { std::forward<CompArea>(blkY) } {} |
162 | | |
163 | 0 | UnitArea::UnitArea(const ChromaFormat _chromaFormat, const CompArea& blkY, const CompArea& blkCb, const CompArea& blkCr) : chromaFormat(_chromaFormat), blocks { blkY, blkCb, blkCr } {} |
164 | | |
165 | 0 | UnitArea::UnitArea(const ChromaFormat _chromaFormat, CompArea&& blkY, CompArea&& blkCb, CompArea&& blkCr) : chromaFormat(_chromaFormat), blocks { std::forward<CompArea>(blkY), std::forward<CompArea>(blkCb), std::forward<CompArea>(blkCr) } {} |
166 | | |
167 | | bool UnitArea::contains(const UnitArea& other) const |
168 | 0 | { |
169 | 0 | bool ret = true; |
170 | 0 | bool any = false; |
171 | |
|
172 | 0 | for( const auto &blk : other.blocks ) |
173 | 0 | { |
174 | 0 | if( blk.valid() && blocks[blk.compID].valid() ) |
175 | 0 | { |
176 | 0 | ret &= blocks[blk.compID].contains( blk ); |
177 | 0 | any = true; |
178 | 0 | } |
179 | 0 | } |
180 | |
|
181 | 0 | return any && ret; |
182 | 0 | } |
183 | | |
184 | | bool UnitArea::contains( const UnitArea& other, const ChannelType chType ) const |
185 | 0 | { |
186 | 0 | bool ret = true; |
187 | 0 | bool any = false; |
188 | |
|
189 | 0 | for( const auto &blk : other.blocks ) |
190 | 0 | { |
191 | 0 | if( toChannelType( blk.compID ) == chType && blk.valid() && blocks[blk.compID].valid() ) |
192 | 0 | { |
193 | 0 | ret &= blocks[blk.compID].contains( blk ); |
194 | 0 | any = true; |
195 | 0 | } |
196 | 0 | } |
197 | |
|
198 | 0 | return any && ret; |
199 | 0 | } |
200 | | |
201 | | void UnitArea::repositionTo(const UnitArea& unitArea) |
202 | 0 | { |
203 | 0 | for(uint32_t i = 0; i < blocks.size(); i++) |
204 | 0 | { |
205 | 0 | blocks[i].repositionTo(unitArea.blocks[i]); |
206 | 0 | } |
207 | 0 | } |
208 | | |
209 | | const UnitArea UnitArea::singleComp(const ComponentID compID) const |
210 | 0 | { |
211 | 0 | UnitArea ret(chromaFormat); |
212 | |
|
213 | 0 | for (const auto &blk : blocks) |
214 | 0 | { |
215 | 0 | if (blk.compID == compID) |
216 | 0 | { |
217 | 0 | ret.blocks.push_back(blk); |
218 | 0 | } |
219 | 0 | else |
220 | 0 | { |
221 | 0 | ret.blocks.push_back(CompArea()); |
222 | 0 | } |
223 | 0 | } |
224 | |
|
225 | 0 | return ret; |
226 | 0 | } |
227 | | |
228 | | const UnitArea UnitArea::singleChan(const ChannelType chType) const |
229 | 0 | { |
230 | 0 | UnitArea ret(chromaFormat); |
231 | |
|
232 | 0 | for (const auto &blk : blocks) |
233 | 0 | { |
234 | 0 | if (toChannelType(blk.compID) == chType) |
235 | 0 | { |
236 | 0 | ret.blocks.push_back(blk); |
237 | 0 | } |
238 | 0 | else |
239 | 0 | { |
240 | 0 | ret.blocks.push_back(CompArea()); |
241 | 0 | } |
242 | 0 | } |
243 | |
|
244 | 0 | return ret; |
245 | 0 | } |
246 | | |
247 | | // --------------------------------------------------------------------------- |
248 | | // coding unit method definitions |
249 | | // --------------------------------------------------------------------------- |
250 | | |
251 | 0 | CodingUnit::CodingUnit(const UnitArea& unit) : UnitArea(unit), cs(nullptr), slice(nullptr), chType( CH_L ), next(nullptr), firstTU(nullptr), lastTU(nullptr) { initData(); initPuData(); } |
252 | 0 | CodingUnit::CodingUnit(const ChromaFormat _chromaFormat, const Area& _area) : UnitArea(_chromaFormat, _area), cs(nullptr), slice(nullptr), chType( CH_L ), next(nullptr), firstTU(nullptr), lastTU(nullptr) { initData(); initPuData(); } |
253 | | |
254 | | CodingUnit& CodingUnit::operator=( const CodingUnit& other ) |
255 | 0 | { |
256 | 0 | slice = other.slice; |
257 | 0 | predMode = other.predMode; |
258 | 0 | qtDepth = other.qtDepth; |
259 | 0 | depth = other.depth; |
260 | 0 | btDepth = other.btDepth; |
261 | 0 | mtDepth = other.mtDepth; |
262 | 0 | splitSeries = other.splitSeries; |
263 | 0 | skip = other.skip; |
264 | 0 | mmvdSkip = other.mmvdSkip; |
265 | 0 | affine = other.affine; |
266 | 0 | affineType = other.affineType; |
267 | 0 | colorTransform = other.colorTransform; |
268 | 0 | geo = other.geo; |
269 | 0 | geo = other.geo; |
270 | 0 | bdpcmM[CH_L] = other.bdpcmM[CH_L]; |
271 | 0 | bdpcmM[CH_C] = other.bdpcmM[CH_C]; |
272 | 0 | qp = other.qp; |
273 | 0 | chromaQpAdj = other.chromaQpAdj; |
274 | 0 | rootCbf = other.rootCbf; |
275 | 0 | sbtInfo = other.sbtInfo; |
276 | 0 | mtsFlag = other.mtsFlag; |
277 | 0 | lfnstIdx = other.lfnstIdx; |
278 | 0 | tileIdx = other.tileIdx; |
279 | 0 | imv = other.imv; |
280 | 0 | imvNumCand = other.imvNumCand; |
281 | 0 | BcwIdx = other.BcwIdx; |
282 | |
|
283 | 0 | smvdMode = other.smvdMode; |
284 | 0 | ispMode = other.ispMode; |
285 | 0 | mipFlag = other.mipFlag; |
286 | |
|
287 | 0 | treeType = other.treeType; |
288 | 0 | modeType = other.modeType; |
289 | 0 | modeTypeSeries = other.modeTypeSeries; |
290 | |
|
291 | 0 | const IntraPredictionData& ipd = other; |
292 | 0 | *this = ipd; |
293 | |
|
294 | 0 | const InterPredictionData& tpd = other; |
295 | 0 | *this = tpd; |
296 | 0 | return *this; |
297 | 0 | } |
298 | | |
299 | | void CodingUnit::initData() |
300 | 0 | { |
301 | 0 | predMode = NUMBER_OF_PREDICTION_MODES; |
302 | 0 | qtDepth = 0; |
303 | 0 | depth = 0; |
304 | 0 | btDepth = 0; |
305 | 0 | mtDepth = 0; |
306 | 0 | splitSeries = 0; |
307 | 0 | skip = false; |
308 | 0 | mmvdSkip = false; |
309 | 0 | affine = false; |
310 | 0 | affineType = 0; |
311 | 0 | colorTransform = false; |
312 | 0 | geo = false; |
313 | 0 | bdpcmM[CH_L] = 0; |
314 | 0 | bdpcmM[CH_C] = 0; |
315 | 0 | qp = 0; |
316 | 0 | chromaQpAdj = 0; |
317 | 0 | rootCbf = true; |
318 | 0 | sbtInfo = 0; |
319 | 0 | mtsFlag = 0; |
320 | 0 | lfnstIdx = 0; |
321 | 0 | tileIdx = 0; |
322 | 0 | imv = IMV_OFF; |
323 | 0 | imvNumCand = 0; |
324 | 0 | BcwIdx = BCW_DEFAULT; |
325 | 0 | smvdMode = 0; |
326 | 0 | ispMode = 0; |
327 | 0 | mipFlag = false; |
328 | |
|
329 | 0 | treeType = TREE_D; |
330 | 0 | modeType = MODE_TYPE_ALL; |
331 | 0 | modeTypeSeries = 0; |
332 | 0 | mcControl = 0; |
333 | 0 | } |
334 | | |
335 | | |
336 | | |
337 | | |
338 | | // --------------------------------------------------------------------------- |
339 | | // prediction unit method definitions |
340 | | // --------------------------------------------------------------------------- |
341 | | |
342 | | void CodingUnit::initPuData() |
343 | 0 | { |
344 | | // intra data - need this default initialization for PCM |
345 | 0 | intraDir[0] = DC_IDX; |
346 | 0 | intraDir[1] = PLANAR_IDX; |
347 | 0 | multiRefIdx = 0; |
348 | 0 | mipTransposedFlag = false; |
349 | | |
350 | | // inter data |
351 | 0 | mergeFlag = false; |
352 | 0 | ciip = false; |
353 | 0 | mvRefine = false; |
354 | 0 | mmvdMergeFlag = false; |
355 | 0 | mergeIdx = MAX_UCHAR; |
356 | 0 | geoSplitDir = MAX_UCHAR; |
357 | 0 | geoMergeIdx = { MAX_SCHAR, MAX_SCHAR }; |
358 | |
|
359 | 0 | mcControl = 0; |
360 | |
|
361 | 0 | interDir = MAX_UCHAR; |
362 | 0 | mmvdMergeIdx.val = MmvdIdx::INVALID; |
363 | 0 | mergeType = MRG_TYPE_DEFAULT_N; |
364 | |
|
365 | 0 | if( mvdL0SubPu ) |
366 | 0 | { |
367 | 0 | int maxDmvrMvds = std::max<int>( 1, lwidth() >> DMVR_SUBCU_SIZE_LOG2 ) * std::max<int>( 1, lheight() >> DMVR_SUBCU_SIZE_LOG2 ); |
368 | 0 | for (uint32_t i = 0; i < maxDmvrMvds; i++) |
369 | 0 | { |
370 | 0 | mvdL0SubPu[i].setZero(); |
371 | 0 | } |
372 | 0 | } |
373 | |
|
374 | 0 | for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) |
375 | 0 | { |
376 | 0 | mvpIdx[i] = MAX_UCHAR; |
377 | 0 | mvpNum[i] = MAX_UCHAR; |
378 | 0 | refIdx[i] = -1; |
379 | 0 | for( uint32_t j = 0; j < 3; j++ ) |
380 | 0 | { |
381 | 0 | mvd[i][j].setZero(); |
382 | 0 | mv [i][j].setZero(); |
383 | 0 | } |
384 | 0 | } |
385 | 0 | } |
386 | | |
387 | | CodingUnit& CodingUnit::operator=( const IntraPredictionData& other ) |
388 | 0 | { |
389 | 0 | for( uint32_t i = 0; i < MAX_NUM_CH; i++ ) |
390 | 0 | { |
391 | 0 | intraDir[ i ] = other.intraDir[ i ]; |
392 | 0 | } |
393 | 0 | mipTransposedFlag = other.mipTransposedFlag; |
394 | 0 | multiRefIdx = other.multiRefIdx; |
395 | 0 | return *this; |
396 | 0 | } |
397 | | |
398 | | CodingUnit& CodingUnit::operator=( const InterPredictionData& other ) |
399 | 0 | { |
400 | 0 | mergeFlag = other.mergeFlag; |
401 | 0 | mergeIdx = other.mergeIdx; |
402 | 0 | geoSplitDir = other.geoSplitDir; |
403 | 0 | geoMergeIdx = other.geoMergeIdx; |
404 | 0 | mmvdMergeFlag = other.mmvdMergeFlag; |
405 | 0 | mmvdMergeIdx = other.mmvdMergeIdx; |
406 | 0 | interDir = other.interDir; |
407 | 0 | mergeType = other.mergeType; |
408 | 0 | mvRefine = other.mvRefine; |
409 | |
|
410 | 0 | if( other.mergeFlag && mvdL0SubPu ) |
411 | 0 | { |
412 | 0 | const int maxDmvrMvds = std::max<int>( 1, lwidth() >> DMVR_SUBCU_SIZE_LOG2 ) * std::max<int>( 1, lheight() >> DMVR_SUBCU_SIZE_LOG2 ); |
413 | |
|
414 | 0 | memcpy( mvdL0SubPu, other.mvdL0SubPu, sizeof( Mv ) * maxDmvrMvds ); |
415 | 0 | } |
416 | |
|
417 | 0 | for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) |
418 | 0 | { |
419 | 0 | mvpIdx[i] = other.mvpIdx[i]; |
420 | 0 | mvpNum[i] = other.mvpNum[i]; |
421 | 0 | refIdx[i] = other.refIdx[i]; |
422 | 0 | for( uint32_t j = 0; j < 3; j++ ) |
423 | 0 | { |
424 | 0 | mvd[i][j] = other.mvd[i][j]; |
425 | 0 | mv [i][j] = other.mv [i][j]; |
426 | 0 | } |
427 | 0 | } |
428 | 0 | ciip = other.ciip; |
429 | 0 | return *this; |
430 | 0 | } |
431 | | |
432 | | CodingUnit& CodingUnit::operator=( const MotionInfo& mi ) |
433 | 0 | { |
434 | 0 | interDir = mi.interDir(); |
435 | |
|
436 | 0 | for( uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++ ) |
437 | 0 | { |
438 | 0 | refIdx[i] = mi.miRefIdx[i]; |
439 | 0 | mv [i][0] = mi.mv[i]; |
440 | 0 | } |
441 | |
|
442 | 0 | return *this; |
443 | 0 | } |
444 | | |
445 | | const MotionInfo& CodingUnit::getMotionInfo() const |
446 | 0 | { |
447 | 0 | return cs->getMotionInfo( lumaPos() ); |
448 | 0 | } |
449 | | |
450 | | const MotionInfo& CodingUnit::getMotionInfo( const Position& pos ) const |
451 | 0 | { |
452 | 0 | CHECKD( !Y().contains( pos ), "Trying to access motion info outsied of PU" ); |
453 | 0 | return cs->getMotionInfo( pos ); |
454 | 0 | } |
455 | | |
456 | | MotionBuf CodingUnit::getMotionBuf() |
457 | 0 | { |
458 | 0 | return cs->getMotionBuf( *this ); |
459 | 0 | } |
460 | | |
461 | | CMotionBuf CodingUnit::getMotionBuf() const |
462 | 0 | { |
463 | 0 | return cs->getMotionBuf( *this ); |
464 | 0 | } |
465 | | |
466 | | |
467 | | // --------------------------------------------------------------------------- |
468 | | // transform unit method definitions |
469 | | // --------------------------------------------------------------------------- |
470 | | |
471 | 0 | TransformUnit::TransformUnit(const UnitArea& unit) : UnitArea(unit), cu(nullptr), cs(nullptr), chType( CH_L ), next( nullptr ) |
472 | 0 | { |
473 | 0 | for( unsigned i = 0; i < MAX_NUM_TBLOCKS; i++ ) |
474 | 0 | { |
475 | 0 | m_coeffs[i] = nullptr; |
476 | 0 | } |
477 | |
|
478 | 0 | initData(); |
479 | 0 | } |
480 | | |
481 | 0 | TransformUnit::TransformUnit(const ChromaFormat _chromaFormat, const Area& _area) : UnitArea(_chromaFormat, _area), cu(nullptr), cs(nullptr), chType( CH_L ), next( nullptr ) |
482 | 0 | { |
483 | 0 | for( unsigned i = 0; i < MAX_NUM_TBLOCKS; i++ ) |
484 | 0 | { |
485 | 0 | m_coeffs[i] = nullptr; |
486 | 0 | } |
487 | |
|
488 | 0 | initData(); |
489 | 0 | } |
490 | | |
491 | | void TransformUnit::initData() |
492 | 0 | { |
493 | 0 | for( unsigned i = 0; i < MAX_NUM_TBLOCKS; i++ ) |
494 | 0 | { |
495 | 0 | cbf[i] = 0; |
496 | 0 | mtsIdx[i] = MTS_DCT2_DCT2; |
497 | 0 | lastPos[i] = 0; |
498 | 0 | } |
499 | 0 | depth = 0; |
500 | 0 | noResidual = false; |
501 | 0 | jointCbCr = 0; |
502 | 0 | chromaAdj = 0; |
503 | 0 | } |
504 | | |
505 | | void TransformUnit::init(TCoeffSig** coeffs) |
506 | 0 | { |
507 | 0 | uint32_t numBlocks = getNumberValidComponents( chromaFormat ); |
508 | |
|
509 | 0 | for (uint32_t i = 0; i < numBlocks; i++) |
510 | 0 | { |
511 | 0 | m_coeffs[i] = coeffs[i]; |
512 | 0 | } |
513 | 0 | } |
514 | | |
515 | | TransformUnit& TransformUnit::operator=( const TransformUnit& other ) |
516 | 0 | { |
517 | 0 | CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" ); |
518 | |
|
519 | 0 | unsigned numBlocks = getNumberValidTBlocks(*cs->pcv); |
520 | 0 | for( unsigned i = 0; i < numBlocks; i++ ) |
521 | 0 | { |
522 | 0 | CHECKD( blocks[i].area() != other.blocks[i].area(), "Transformation units cover different areas" ); |
523 | |
|
524 | 0 | cbf[i] = other.cbf[i]; |
525 | 0 | bool cpyRsi = other.cbf[i] || ( i && other.jointCbCr && numBlocks > 1 && ( TU::getCbf( other, COMP_Cb ) || TU::getCbf( other, COMP_Cr ) ) ); |
526 | 0 | if( m_coeffs[i] && other.m_coeffs[i] && m_coeffs[i] != other.m_coeffs[i] && cpyRsi ) |
527 | 0 | { |
528 | 0 | uint32_t area = blocks[i].area(); |
529 | 0 | memcpy( m_coeffs[i], other.m_coeffs[i], sizeof( TCoeffSig ) * area ); |
530 | 0 | } |
531 | 0 | mtsIdx[i] = other.mtsIdx[i]; |
532 | 0 | lastPos[i] = other.lastPos[i]; |
533 | 0 | } |
534 | 0 | depth = other.depth; |
535 | 0 | noResidual = other.noResidual; |
536 | 0 | jointCbCr = other.jointCbCr; |
537 | 0 | return *this; |
538 | 0 | } |
539 | | |
540 | | void TransformUnit::copyComponentFrom( const TransformUnit& other, const ComponentID i ) |
541 | 0 | { |
542 | 0 | CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" ); |
543 | 0 | CHECKD( blocks[i].area() != other.blocks[i].area(), "Transformation units cover different areas" ); |
544 | |
|
545 | 0 | bool cpyRsi = other.cbf[i] || ( i && other.jointCbCr && blocks.size() > 1 && ( TU::getCbf( other, COMP_Cb ) || TU::getCbf( other, COMP_Cr ) ) ); |
546 | 0 | if( m_coeffs[i] && other.m_coeffs[i] && m_coeffs[i] != other.m_coeffs[i] && cpyRsi ) |
547 | 0 | { |
548 | 0 | uint32_t area = blocks[i].area(); |
549 | 0 | memcpy( m_coeffs[i], other.m_coeffs[i], sizeof( TCoeffSig ) * area ); |
550 | 0 | } |
551 | |
|
552 | 0 | cbf[i] = other.cbf[i]; |
553 | |
|
554 | 0 | depth = other.depth; |
555 | 0 | mtsIdx[i] = other.mtsIdx[i]; |
556 | 0 | noResidual = other.noResidual; |
557 | 0 | jointCbCr = isChroma( i ) ? other.jointCbCr : jointCbCr; |
558 | 0 | lastPos[i] = other.lastPos[i]; |
559 | 0 | } |
560 | | |
561 | | void TransformUnit::checkTuNoResidual( unsigned idx ) |
562 | 0 | { |
563 | 0 | if( CU::getSbtIdx( cu->sbtInfo ) == SBT_OFF_DCT ) |
564 | 0 | { |
565 | 0 | return; |
566 | 0 | } |
567 | | |
568 | 0 | if( ( CU::getSbtPos( cu->sbtInfo ) == SBT_POS0 && idx == 1 ) || ( CU::getSbtPos( cu->sbtInfo ) == SBT_POS1 && idx == 0 ) ) |
569 | 0 | { |
570 | 0 | noResidual = true; |
571 | 0 | } |
572 | 0 | } |
573 | | |
574 | | int TransformUnit::getTbAreaAfterCoefZeroOut(ComponentID compID) const |
575 | 0 | { |
576 | 0 | int tbArea = blocks[compID].width * blocks[compID].height; |
577 | 0 | int tbZeroOutWidth = blocks[compID].width; |
578 | 0 | int tbZeroOutHeight = blocks[compID].height; |
579 | |
|
580 | 0 | if (cs->sps->MTS && cu->sbtInfo != 0 && blocks[compID].width <= 32 && blocks[compID].height <= 32 && compID == COMP_Y) |
581 | 0 | { |
582 | 0 | tbZeroOutWidth = (blocks[compID].width == 32) ? 16 : tbZeroOutWidth; |
583 | 0 | tbZeroOutHeight = (blocks[compID].height == 32) ? 16 : tbZeroOutHeight; |
584 | 0 | } |
585 | 0 | tbZeroOutWidth = std::min<int>(JVET_C0024_ZERO_OUT_TH, tbZeroOutWidth); |
586 | 0 | tbZeroOutHeight = std::min<int>(JVET_C0024_ZERO_OUT_TH, tbZeroOutHeight); |
587 | 0 | tbArea = tbZeroOutWidth * tbZeroOutHeight; |
588 | 0 | return tbArea; |
589 | 0 | } |
590 | | |
591 | | } // namespace vvenc |
592 | | |
593 | | //! \} |
594 | | |