/work/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 | 11.3M | { |
64 | 11.3M | const uint32_t csx = getComponentScaleX(compID, chromaFormat); |
65 | 11.3M | const uint32_t csy = getComponentScaleY(compID, chromaFormat); |
66 | | |
67 | 11.3M | x >>= csx; |
68 | 11.3M | y >>= csy; |
69 | 11.3M | width >>= csx; |
70 | 11.3M | height >>= csy; |
71 | 11.3M | } |
72 | | |
73 | | Position CompArea::chromaPos() const |
74 | 51.3k | { |
75 | 51.3k | 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 | 51.3k | else |
83 | 51.3k | { |
84 | 51.3k | return *this; |
85 | 51.3k | } |
86 | 51.3k | } |
87 | | |
88 | | Size CompArea::lumaSize() const |
89 | 2.61M | { |
90 | 2.61M | if( isChroma( compID ) ) |
91 | 2.08M | { |
92 | 2.08M | uint32_t scaleX = getComponentScaleX( compID, chromaFormat ); |
93 | 2.08M | uint32_t scaleY = getComponentScaleY( compID, chromaFormat ); |
94 | | |
95 | 2.08M | return Size( width << scaleX, height << scaleY ); |
96 | 2.08M | } |
97 | 529k | else |
98 | 529k | { |
99 | 529k | return *this; |
100 | 529k | } |
101 | 2.61M | } |
102 | | |
103 | | Size CompArea::chromaSize() const |
104 | 102k | { |
105 | 102k | 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 | 102k | else |
113 | 102k | { |
114 | 102k | return *this; |
115 | 102k | } |
116 | 102k | } |
117 | | |
118 | | Position CompArea::lumaPos() const |
119 | 1.21M | { |
120 | 1.21M | if( isChroma( compID ) ) |
121 | 962k | { |
122 | 962k | uint32_t scaleX = getComponentScaleX( compID, chromaFormat ); |
123 | 962k | uint32_t scaleY = getComponentScaleY( compID, chromaFormat ); |
124 | | |
125 | 962k | return Position( x << scaleX, y << scaleY ); |
126 | 962k | } |
127 | 250k | else |
128 | 250k | { |
129 | 250k | return *this; |
130 | 250k | } |
131 | 1.21M | } |
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 | 775k | UnitArea::UnitArea(const ChromaFormat _chromaFormat) : chromaFormat(_chromaFormat) { } |
148 | | |
149 | 4.25M | UnitArea::UnitArea(const ChromaFormat _chromaFormat, const Area& _area) : chromaFormat(_chromaFormat), blocks(getNumberValidComponents(_chromaFormat)) |
150 | 4.25M | { |
151 | 4.25M | const uint32_t numCh = getNumberValidComponents(chromaFormat); |
152 | | |
153 | 15.5M | for (uint32_t i = 0; i < numCh; i++) |
154 | 11.3M | { |
155 | 11.3M | new (&blocks[i]) CompArea(ComponentID(i), chromaFormat, _area, true); |
156 | 11.3M | } |
157 | 4.25M | } |
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 | 490k | { |
169 | 490k | bool ret = true; |
170 | 490k | bool any = false; |
171 | | |
172 | 490k | for( const auto &blk : other.blocks ) |
173 | 1.47M | { |
174 | 1.47M | if( blk.valid() && blocks[blk.compID].valid() ) |
175 | 1.21M | { |
176 | 1.21M | ret &= blocks[blk.compID].contains( blk ); |
177 | 1.21M | any = true; |
178 | 1.21M | } |
179 | 1.47M | } |
180 | | |
181 | 490k | return any && ret; |
182 | 490k | } |
183 | | |
184 | | bool UnitArea::contains( const UnitArea& other, const ChannelType chType ) const |
185 | 51.3k | { |
186 | 51.3k | bool ret = true; |
187 | 51.3k | bool any = false; |
188 | | |
189 | 51.3k | for( const auto &blk : other.blocks ) |
190 | 154k | { |
191 | 154k | if( toChannelType( blk.compID ) == chType && blk.valid() && blocks[blk.compID].valid() ) |
192 | 102k | { |
193 | 102k | ret &= blocks[blk.compID].contains( blk ); |
194 | 102k | any = true; |
195 | 102k | } |
196 | 154k | } |
197 | | |
198 | 51.3k | return any && ret; |
199 | 51.3k | } |
200 | | |
201 | | void UnitArea::repositionTo(const UnitArea& unitArea) |
202 | 624k | { |
203 | 2.49M | for(uint32_t i = 0; i < blocks.size(); i++) |
204 | 1.87M | { |
205 | 1.87M | blocks[i].repositionTo(unitArea.blocks[i]); |
206 | 1.87M | } |
207 | 624k | } |
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 | 558k | { |
230 | 558k | UnitArea ret(chromaFormat); |
231 | | |
232 | 558k | for (const auto &blk : blocks) |
233 | 1.67M | { |
234 | 1.67M | if (toChannelType(blk.compID) == chType) |
235 | 768k | { |
236 | 768k | ret.blocks.push_back(blk); |
237 | 768k | } |
238 | 907k | else |
239 | 907k | { |
240 | 907k | ret.blocks.push_back(CompArea()); |
241 | 907k | } |
242 | 1.67M | } |
243 | | |
244 | 558k | return ret; |
245 | 558k | } |
246 | | |
247 | | // --------------------------------------------------------------------------- |
248 | | // coding unit method definitions |
249 | | // --------------------------------------------------------------------------- |
250 | | |
251 | 22.7k | 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 | 140k | { |
256 | 140k | slice = other.slice; |
257 | 140k | predMode = other.predMode; |
258 | 140k | qtDepth = other.qtDepth; |
259 | 140k | depth = other.depth; |
260 | 140k | btDepth = other.btDepth; |
261 | 140k | mtDepth = other.mtDepth; |
262 | 140k | splitSeries = other.splitSeries; |
263 | 140k | skip = other.skip; |
264 | 140k | mmvdSkip = other.mmvdSkip; |
265 | 140k | affine = other.affine; |
266 | 140k | affineType = other.affineType; |
267 | 140k | colorTransform = other.colorTransform; |
268 | 140k | geo = other.geo; |
269 | 140k | geo = other.geo; |
270 | 140k | bdpcmM[CH_L] = other.bdpcmM[CH_L]; |
271 | 140k | bdpcmM[CH_C] = other.bdpcmM[CH_C]; |
272 | 140k | qp = other.qp; |
273 | 140k | chromaQpAdj = other.chromaQpAdj; |
274 | 140k | rootCbf = other.rootCbf; |
275 | 140k | sbtInfo = other.sbtInfo; |
276 | 140k | mtsFlag = other.mtsFlag; |
277 | 140k | lfnstIdx = other.lfnstIdx; |
278 | 140k | tileIdx = other.tileIdx; |
279 | 140k | imv = other.imv; |
280 | 140k | imvNumCand = other.imvNumCand; |
281 | 140k | BcwIdx = other.BcwIdx; |
282 | | |
283 | 140k | smvdMode = other.smvdMode; |
284 | 140k | ispMode = other.ispMode; |
285 | 140k | mipFlag = other.mipFlag; |
286 | | |
287 | 140k | treeType = other.treeType; |
288 | 140k | modeType = other.modeType; |
289 | 140k | modeTypeSeries = other.modeTypeSeries; |
290 | | |
291 | 140k | const IntraPredictionData& ipd = other; |
292 | 140k | *this = ipd; |
293 | | |
294 | 140k | const InterPredictionData& tpd = other; |
295 | 140k | *this = tpd; |
296 | 140k | return *this; |
297 | 140k | } |
298 | | |
299 | | void CodingUnit::initData() |
300 | 282k | { |
301 | 282k | predMode = NUMBER_OF_PREDICTION_MODES; |
302 | 282k | qtDepth = 0; |
303 | 282k | depth = 0; |
304 | 282k | btDepth = 0; |
305 | 282k | mtDepth = 0; |
306 | 282k | splitSeries = 0; |
307 | 282k | skip = false; |
308 | 282k | mmvdSkip = false; |
309 | 282k | affine = false; |
310 | 282k | affineType = 0; |
311 | 282k | colorTransform = false; |
312 | 282k | geo = false; |
313 | 282k | bdpcmM[CH_L] = 0; |
314 | 282k | bdpcmM[CH_C] = 0; |
315 | 282k | qp = 0; |
316 | 282k | chromaQpAdj = 0; |
317 | 282k | rootCbf = true; |
318 | 282k | sbtInfo = 0; |
319 | 282k | mtsFlag = 0; |
320 | 282k | lfnstIdx = 0; |
321 | 282k | tileIdx = 0; |
322 | 282k | imv = IMV_OFF; |
323 | 282k | imvNumCand = 0; |
324 | 282k | BcwIdx = BCW_DEFAULT; |
325 | 282k | smvdMode = 0; |
326 | 282k | ispMode = 0; |
327 | 282k | mipFlag = false; |
328 | | |
329 | 282k | treeType = TREE_D; |
330 | 282k | modeType = MODE_TYPE_ALL; |
331 | 282k | modeTypeSeries = 0; |
332 | 282k | mcControl = 0; |
333 | 282k | } |
334 | | |
335 | | |
336 | | |
337 | | |
338 | | // --------------------------------------------------------------------------- |
339 | | // prediction unit method definitions |
340 | | // --------------------------------------------------------------------------- |
341 | | |
342 | | void CodingUnit::initPuData() |
343 | 164k | { |
344 | | // intra data - need this default initialization for PCM |
345 | 164k | intraDir[0] = DC_IDX; |
346 | 164k | intraDir[1] = PLANAR_IDX; |
347 | 164k | multiRefIdx = 0; |
348 | 164k | mipTransposedFlag = false; |
349 | | |
350 | | // inter data |
351 | 164k | mergeFlag = false; |
352 | 164k | ciip = false; |
353 | 164k | mvRefine = false; |
354 | 164k | mmvdMergeFlag = false; |
355 | 164k | mergeIdx = MAX_UCHAR; |
356 | 164k | geoSplitDir = MAX_UCHAR; |
357 | 164k | geoMergeIdx = { MAX_SCHAR, MAX_SCHAR }; |
358 | | |
359 | 164k | mcControl = 0; |
360 | | |
361 | 164k | interDir = MAX_UCHAR; |
362 | 164k | mmvdMergeIdx.val = MmvdIdx::INVALID; |
363 | 164k | mergeType = MRG_TYPE_DEFAULT_N; |
364 | | |
365 | 164k | if( mvdL0SubPu ) |
366 | 66.6k | { |
367 | 66.6k | int maxDmvrMvds = std::max<int>( 1, lwidth() >> DMVR_SUBCU_SIZE_LOG2 ) * std::max<int>( 1, lheight() >> DMVR_SUBCU_SIZE_LOG2 ); |
368 | 391k | for (uint32_t i = 0; i < maxDmvrMvds; i++) |
369 | 324k | { |
370 | 324k | mvdL0SubPu[i].setZero(); |
371 | 324k | } |
372 | 66.6k | } |
373 | | |
374 | 494k | for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) |
375 | 329k | { |
376 | 329k | mvpIdx[i] = MAX_UCHAR; |
377 | 329k | mvpNum[i] = MAX_UCHAR; |
378 | 329k | refIdx[i] = -1; |
379 | 1.31M | for( uint32_t j = 0; j < 3; j++ ) |
380 | 989k | { |
381 | 989k | mvd[i][j].setZero(); |
382 | 989k | mv [i][j].setZero(); |
383 | 989k | } |
384 | 329k | } |
385 | 164k | } |
386 | | |
387 | | CodingUnit& CodingUnit::operator=( const IntraPredictionData& other ) |
388 | 140k | { |
389 | 421k | for( uint32_t i = 0; i < MAX_NUM_CH; i++ ) |
390 | 280k | { |
391 | 280k | intraDir[ i ] = other.intraDir[ i ]; |
392 | 280k | } |
393 | 140k | mipTransposedFlag = other.mipTransposedFlag; |
394 | 140k | multiRefIdx = other.multiRefIdx; |
395 | 140k | return *this; |
396 | 140k | } |
397 | | |
398 | | CodingUnit& CodingUnit::operator=( const InterPredictionData& other ) |
399 | 140k | { |
400 | 140k | mergeFlag = other.mergeFlag; |
401 | 140k | mergeIdx = other.mergeIdx; |
402 | 140k | geoSplitDir = other.geoSplitDir; |
403 | 140k | geoMergeIdx = other.geoMergeIdx; |
404 | 140k | mmvdMergeFlag = other.mmvdMergeFlag; |
405 | 140k | mmvdMergeIdx = other.mmvdMergeIdx; |
406 | 140k | interDir = other.interDir; |
407 | 140k | mergeType = other.mergeType; |
408 | 140k | mvRefine = other.mvRefine; |
409 | | |
410 | 140k | 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 | 421k | for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) |
418 | 280k | { |
419 | 280k | mvpIdx[i] = other.mvpIdx[i]; |
420 | 280k | mvpNum[i] = other.mvpNum[i]; |
421 | 280k | refIdx[i] = other.refIdx[i]; |
422 | 1.12M | for( uint32_t j = 0; j < 3; j++ ) |
423 | 842k | { |
424 | 842k | mvd[i][j] = other.mvd[i][j]; |
425 | 842k | mv [i][j] = other.mv [i][j]; |
426 | 842k | } |
427 | 280k | } |
428 | 140k | ciip = other.ciip; |
429 | 140k | return *this; |
430 | 140k | } |
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 | 20.2k | { |
458 | 20.2k | return cs->getMotionBuf( *this ); |
459 | 20.2k | } |
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 | 876k | { |
493 | 3.50M | for( unsigned i = 0; i < MAX_NUM_TBLOCKS; i++ ) |
494 | 2.62M | { |
495 | 2.62M | cbf[i] = 0; |
496 | 2.62M | mtsIdx[i] = MTS_DCT2_DCT2; |
497 | 2.62M | lastPos[i] = 0; |
498 | 2.62M | } |
499 | 876k | depth = 0; |
500 | 876k | noResidual = false; |
501 | 876k | jointCbCr = 0; |
502 | 876k | chromaAdj = 0; |
503 | 876k | } |
504 | | |
505 | | void TransformUnit::init(TCoeffSig** coeffs) |
506 | 467k | { |
507 | 467k | uint32_t numBlocks = getNumberValidComponents( chromaFormat ); |
508 | | |
509 | 1.87M | for (uint32_t i = 0; i < numBlocks; i++) |
510 | 1.40M | { |
511 | 1.40M | m_coeffs[i] = coeffs[i]; |
512 | 1.40M | } |
513 | 467k | } |
514 | | |
515 | | TransformUnit& TransformUnit::operator=( const TransformUnit& other ) |
516 | 35.5k | { |
517 | 35.5k | CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" ); |
518 | | |
519 | 35.5k | unsigned numBlocks = getNumberValidTBlocks(*cs->pcv); |
520 | 142k | for( unsigned i = 0; i < numBlocks; i++ ) |
521 | 106k | { |
522 | 106k | CHECKD( blocks[i].area() != other.blocks[i].area(), "Transformation units cover different areas" ); |
523 | | |
524 | 106k | cbf[i] = other.cbf[i]; |
525 | 106k | bool cpyRsi = other.cbf[i] || ( i && other.jointCbCr && numBlocks > 1 && ( TU::getCbf( other, COMP_Cb ) || TU::getCbf( other, COMP_Cr ) ) ); |
526 | 106k | if( m_coeffs[i] && other.m_coeffs[i] && m_coeffs[i] != other.m_coeffs[i] && cpyRsi ) |
527 | 3.45k | { |
528 | 3.45k | uint32_t area = blocks[i].area(); |
529 | 3.45k | memcpy( m_coeffs[i], other.m_coeffs[i], sizeof( TCoeffSig ) * area ); |
530 | 3.45k | } |
531 | 106k | mtsIdx[i] = other.mtsIdx[i]; |
532 | 106k | lastPos[i] = other.lastPos[i]; |
533 | 106k | } |
534 | 35.5k | depth = other.depth; |
535 | 35.5k | noResidual = other.noResidual; |
536 | 35.5k | jointCbCr = other.jointCbCr; |
537 | 35.5k | return *this; |
538 | 35.5k | } |
539 | | |
540 | | void TransformUnit::copyComponentFrom( const TransformUnit& other, const ComponentID i ) |
541 | 3.17M | { |
542 | 3.17M | CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" ); |
543 | 3.17M | CHECKD( blocks[i].area() != other.blocks[i].area(), "Transformation units cover different areas" ); |
544 | | |
545 | 3.17M | bool cpyRsi = other.cbf[i] || ( i && other.jointCbCr && blocks.size() > 1 && ( TU::getCbf( other, COMP_Cb ) || TU::getCbf( other, COMP_Cr ) ) ); |
546 | 3.17M | if( m_coeffs[i] && other.m_coeffs[i] && m_coeffs[i] != other.m_coeffs[i] && cpyRsi ) |
547 | 1.20M | { |
548 | 1.20M | uint32_t area = blocks[i].area(); |
549 | 1.20M | memcpy( m_coeffs[i], other.m_coeffs[i], sizeof( TCoeffSig ) * area ); |
550 | 1.20M | } |
551 | | |
552 | 3.17M | cbf[i] = other.cbf[i]; |
553 | | |
554 | 3.17M | depth = other.depth; |
555 | 3.17M | mtsIdx[i] = other.mtsIdx[i]; |
556 | 3.17M | noResidual = other.noResidual; |
557 | 3.17M | jointCbCr = isChroma( i ) ? other.jointCbCr : jointCbCr; |
558 | 3.17M | lastPos[i] = other.lastPos[i]; |
559 | 3.17M | } |
560 | | |
561 | | void TransformUnit::checkTuNoResidual( unsigned idx ) |
562 | 20.2k | { |
563 | 20.2k | if( CU::getSbtIdx( cu->sbtInfo ) == SBT_OFF_DCT ) |
564 | 20.2k | { |
565 | 20.2k | return; |
566 | 20.2k | } |
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 | 795k | { |
576 | 795k | int tbArea = blocks[compID].width * blocks[compID].height; |
577 | 795k | int tbZeroOutWidth = blocks[compID].width; |
578 | 795k | int tbZeroOutHeight = blocks[compID].height; |
579 | | |
580 | 795k | 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 | 795k | tbZeroOutWidth = std::min<int>(JVET_C0024_ZERO_OUT_TH, tbZeroOutWidth); |
586 | 795k | tbZeroOutHeight = std::min<int>(JVET_C0024_ZERO_OUT_TH, tbZeroOutHeight); |
587 | 795k | tbArea = tbZeroOutWidth * tbZeroOutHeight; |
588 | 795k | return tbArea; |
589 | 795k | } |
590 | | |
591 | | } // namespace vvenc |
592 | | |
593 | | //! \} |
594 | | |