/src/vvenc/source/Lib/EncoderLib/CABACWriter.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 CABACWriter.cpp |
45 | | * \brief Writer for low level syntax |
46 | | */ |
47 | | |
48 | | #include "CABACWriter.h" |
49 | | #include "EncLib.h" |
50 | | #include "CommonLib/Contexts.h" |
51 | | #include "CommonLib/UnitTools.h" |
52 | | #include "CommonLib/SampleAdaptiveOffset.h" |
53 | | #include "CommonLib/dtrace_buffer.h" |
54 | | |
55 | | #include <map> |
56 | | #include <algorithm> |
57 | | |
58 | | //! \ingroup EncoderLib |
59 | | //! \{ |
60 | | |
61 | | namespace vvenc { |
62 | | |
63 | | void CABACWriter::initCtxModels( const Slice& slice ) |
64 | 0 | { |
65 | 0 | int qp = slice.sliceQp; |
66 | 0 | SliceType sliceType = slice.sliceType; |
67 | 0 | SliceType encCABACTableIdx = slice.encCABACTableIdx; |
68 | 0 | if( !slice.isIntra() && (encCABACTableIdx==VVENC_B_SLICE || encCABACTableIdx==VVENC_P_SLICE) && slice.pps->cabacInitPresent ) |
69 | 0 | { |
70 | 0 | sliceType = encCABACTableIdx; |
71 | 0 | } |
72 | 0 | m_BinEncoder.reset( qp, (int)sliceType ); |
73 | 0 | } |
74 | | |
75 | | |
76 | | |
77 | | SliceType xGetCtxInitId( const Slice& slice, const BinEncIf& binEncoder, Ctx& ctxTest ) |
78 | 0 | { |
79 | 0 | const CtxStore& ctxStoreTest = static_cast<const CtxStore&>( ctxTest ); |
80 | 0 | const CtxStore& ctxStoreRef = static_cast<const CtxStore&>( binEncoder.getCtx() ); |
81 | 0 | int qp = slice.sliceQp; |
82 | 0 | if( !slice.isIntra() ) |
83 | 0 | { |
84 | 0 | SliceType aSliceTypeChoices[] = { VVENC_B_SLICE, VVENC_P_SLICE }; |
85 | 0 | uint64_t bestCost = std::numeric_limits<uint64_t>::max(); |
86 | 0 | SliceType bestSliceType = aSliceTypeChoices[0]; |
87 | 0 | for (uint32_t idx=0; idx<2; idx++) |
88 | 0 | { |
89 | 0 | uint64_t curCost = 0; |
90 | 0 | SliceType curSliceType = aSliceTypeChoices[idx]; |
91 | 0 | ctxTest.init( qp, (int)curSliceType ); |
92 | 0 | for( int k = 0; k < Ctx::NumberOfContexts; k++ ) |
93 | 0 | { |
94 | 0 | if( binEncoder.getNumBins(k) > 0 ) |
95 | 0 | { |
96 | 0 | curCost += uint64_t( binEncoder.getNumBins(k) ) * ctxStoreRef[k].estFracExcessBits( ctxStoreTest[k] ); |
97 | 0 | } |
98 | 0 | } |
99 | 0 | if (curCost < bestCost) |
100 | 0 | { |
101 | 0 | bestSliceType = curSliceType; |
102 | 0 | bestCost = curCost; |
103 | 0 | } |
104 | 0 | } |
105 | 0 | return bestSliceType; |
106 | 0 | } |
107 | 0 | else |
108 | 0 | { |
109 | 0 | return VVENC_I_SLICE; |
110 | 0 | } |
111 | 0 | } |
112 | | |
113 | | |
114 | | SliceType CABACWriter::getCtxInitId( const Slice& slice ) |
115 | 0 | { |
116 | 0 | return xGetCtxInitId( slice, m_BinEncoder, m_TestCtx ); |
117 | 0 | } |
118 | | |
119 | | |
120 | | unsigned estBits( BinEncIf& binEnc, const std::vector<bool>& bins, const Ctx& ctx, const int ctxId, const uint8_t winSize ) |
121 | 0 | { |
122 | 0 | binEnc.initCtxAndWinSize( ctxId, ctx, winSize ); |
123 | 0 | binEnc.start(); |
124 | 0 | const std::size_t numBins = bins.size(); |
125 | 0 | unsigned startBits = binEnc.getNumWrittenBits(); |
126 | 0 | for( std::size_t binId = 0; binId < numBins; binId++ ) |
127 | 0 | { |
128 | 0 | unsigned bin = ( bins[binId] ? 1 : 0 ); |
129 | 0 | binEnc.encodeBin( bin, ctxId ); |
130 | 0 | } |
131 | 0 | unsigned endBits = binEnc.getNumWrittenBits(); |
132 | 0 | unsigned codedBits = endBits - startBits; |
133 | 0 | return codedBits; |
134 | 0 | } |
135 | | |
136 | | |
137 | | //================================================================================ |
138 | | // clause 7.3.8.1 |
139 | | //-------------------------------------------------------------------------------- |
140 | | // void end_of_slice() |
141 | | //================================================================================ |
142 | | |
143 | | void CABACWriter::end_of_slice() |
144 | 0 | { |
145 | 0 | m_BinEncoder.encodeBinTrm ( 1 ); |
146 | 0 | m_BinEncoder.finish (); |
147 | 0 | } |
148 | | |
149 | | |
150 | | //================================================================================ |
151 | | // clause 7.3.8.2 |
152 | | //-------------------------------------------------------------------------------- |
153 | | // bool coding_tree_unit( cs, area, qp, ctuRsAddr, skipSao, skipAlf ) |
154 | | //================================================================================ |
155 | | |
156 | | void CABACWriter::coding_tree_unit( CodingStructure& cs, const UnitArea& area, int (&qps)[2], unsigned ctuRsAddr, bool skipSao /* = false */, bool skipAlf /* = false */ ) |
157 | 0 | { |
158 | 0 | CUCtx cuCtx( qps[CH_L] ); |
159 | 0 | Partitioner *partitioner = &m_partitioner[0]; |
160 | |
|
161 | 0 | partitioner->initCtu( area, CH_L, *cs.slice ); |
162 | |
|
163 | 0 | if( !skipSao ) |
164 | 0 | { |
165 | 0 | sao( *cs.slice, ctuRsAddr ); |
166 | 0 | } |
167 | |
|
168 | 0 | if (!skipAlf) |
169 | 0 | { |
170 | 0 | for (int compIdx = 0; compIdx < MAX_NUM_COMP; compIdx++) |
171 | 0 | { |
172 | 0 | if(cs.slice->alfEnabled[compIdx]) |
173 | 0 | { |
174 | 0 | codeAlfCtuEnabledFlag(cs, ctuRsAddr, compIdx); |
175 | 0 | if (isLuma(ComponentID(compIdx))) |
176 | 0 | { |
177 | 0 | codeAlfCtuFilterIndex(cs, ctuRsAddr); |
178 | 0 | } |
179 | 0 | if (isChroma(ComponentID(compIdx))) |
180 | 0 | { |
181 | 0 | codeAlfCtuAlternative(cs, ctuRsAddr, compIdx, &cs.slice->alfAps[cs.slice->chromaApsId]->alfParam ); |
182 | 0 | } |
183 | 0 | } |
184 | 0 | } |
185 | 0 | } |
186 | |
|
187 | 0 | if ( !skipAlf ) |
188 | 0 | { |
189 | 0 | for ( int compIdx = 1; compIdx < getNumberValidComponents( cs.pcv->chrFormat ); compIdx++ ) |
190 | 0 | { |
191 | 0 | if (cs.slice->ccAlfFilterParam.ccAlfFilterEnabled[compIdx - 1]) |
192 | 0 | { |
193 | 0 | const int filterCount = cs.slice->ccAlfFilterParam.ccAlfFilterCount[compIdx - 1]; |
194 | |
|
195 | 0 | const int ry = ctuRsAddr / cs.pcv->widthInCtus; |
196 | 0 | const int rx = ctuRsAddr % cs.pcv->widthInCtus; |
197 | 0 | const Position lumaPos(rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize); |
198 | |
|
199 | 0 | codeCcAlfFilterControlIdc(cs.slice->ccAlfFilterControl[compIdx - 1][ctuRsAddr], cs, ComponentID(compIdx), |
200 | 0 | ctuRsAddr, cs.slice->ccAlfFilterControl[compIdx - 1], lumaPos, filterCount); |
201 | 0 | } |
202 | 0 | } |
203 | 0 | } |
204 | |
|
205 | 0 | if ( CS::isDualITree(cs) && cs.pcv->chrFormat != CHROMA_400 && cs.pcv->maxCUSize > 64 ) |
206 | 0 | { |
207 | 0 | CUCtx chromaCuCtx(qps[CH_C]); |
208 | 0 | Partitioner *chromaPartitioner = &m_partitioner[1]; |
209 | 0 | chromaPartitioner->initCtu(area, CH_C, *cs.slice); |
210 | 0 | coding_tree(cs, *partitioner, cuCtx, chromaPartitioner, &chromaCuCtx); |
211 | 0 | qps[CH_L] = cuCtx.qp; |
212 | 0 | qps[CH_C] = chromaCuCtx.qp; |
213 | 0 | } |
214 | 0 | else |
215 | 0 | { |
216 | 0 | coding_tree( cs, *partitioner, cuCtx ); |
217 | 0 | qps[CH_L] = cuCtx.qp; |
218 | 0 | if( CS::isDualITree( cs ) && cs.pcv->chrFormat != CHROMA_400 ) |
219 | 0 | { |
220 | 0 | CUCtx cuCtxChroma( qps[CH_C] ); |
221 | 0 | partitioner->initCtu( area, CH_C, *cs.slice ); |
222 | 0 | coding_tree( cs, *partitioner, cuCtxChroma ); |
223 | 0 | qps[CH_C] = cuCtxChroma.qp; |
224 | 0 | } |
225 | 0 | } |
226 | 0 | } |
227 | | |
228 | | |
229 | | //================================================================================ |
230 | | // clause 7.3.8.3 |
231 | | //-------------------------------------------------------------------------------- |
232 | | // void sao ( slice, ctuRsAddr ) |
233 | | // void sao_block_pars ( saoPars, bitDepths, sliceEnabled, leftMergeAvail, aboveMergeAvail, onlyEstMergeInfo ) |
234 | | // void sao_offset_pars ( ctbPars, compID, sliceEnabled, bitDepth ) |
235 | | //================================================================================ |
236 | | |
237 | | void CABACWriter::sao( const Slice& slice, unsigned ctuRsAddr ) |
238 | 0 | { |
239 | 0 | const SPS& sps = *slice.sps; |
240 | 0 | if( !sps.saoEnabled ) |
241 | 0 | { |
242 | 0 | return; |
243 | 0 | } |
244 | | |
245 | 0 | CodingStructure& cs = *slice.pic->cs; |
246 | 0 | const PreCalcValues& pcv = *cs.pcv; |
247 | 0 | const SAOBlkParam& sao_ctu_pars = cs.picture->getSAO()[ctuRsAddr]; |
248 | 0 | bool slice_sao_luma_flag = ( slice.saoEnabled[ CH_L ] ); |
249 | 0 | bool slice_sao_chroma_flag = ( slice.saoEnabled[ CH_C ] && sps.chromaFormatIdc != CHROMA_400 ); |
250 | 0 | if( !slice_sao_luma_flag && !slice_sao_chroma_flag ) |
251 | 0 | { |
252 | 0 | return; |
253 | 0 | } |
254 | | |
255 | 0 | bool sliceEnabled[3] = { slice_sao_luma_flag, slice_sao_chroma_flag, slice_sao_chroma_flag }; |
256 | 0 | int frame_width_in_ctus = pcv.widthInCtus; |
257 | 0 | int ry = ctuRsAddr / frame_width_in_ctus; |
258 | 0 | int rx = ctuRsAddr - ry * frame_width_in_ctus; |
259 | 0 | const Position pos ( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize ); |
260 | 0 | const unsigned curSliceIdx = slice.independentSliceIdx; |
261 | 0 | const unsigned curTileIdx = cs.pps->getTileIdx( pos ); |
262 | 0 | bool leftMergeAvail = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0 ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false; |
263 | 0 | bool aboveMergeAvail = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false; |
264 | 0 | sao_block_pars( sao_ctu_pars, sps.bitDepths, sliceEnabled, leftMergeAvail, aboveMergeAvail, false ); |
265 | 0 | } |
266 | | |
267 | | |
268 | | void CABACWriter::sao_block_pars( const SAOBlkParam& saoPars, const BitDepths& bitDepths, const bool* sliceEnabled, bool leftMergeAvail, bool aboveMergeAvail, bool onlyEstMergeInfo ) |
269 | 0 | { |
270 | 0 | bool isLeftMerge = false; |
271 | 0 | bool isAboveMerge = false; |
272 | 0 | if( leftMergeAvail ) |
273 | 0 | { |
274 | | // sao_merge_left_flag |
275 | 0 | isLeftMerge = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_LEFT ); |
276 | 0 | m_BinEncoder.encodeBin( (isLeftMerge), Ctx::SaoMergeFlag() ); |
277 | 0 | } |
278 | 0 | if( aboveMergeAvail && !isLeftMerge ) |
279 | 0 | { |
280 | | // sao_merge_above_flag |
281 | 0 | isAboveMerge = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_ABOVE ); |
282 | 0 | m_BinEncoder.encodeBin( (isAboveMerge), Ctx::SaoMergeFlag() ); |
283 | 0 | } |
284 | 0 | if( onlyEstMergeInfo ) |
285 | 0 | { |
286 | 0 | return; //only for RDO |
287 | 0 | } |
288 | 0 | if( !isLeftMerge && !isAboveMerge ) |
289 | 0 | { |
290 | | // explicit parameters |
291 | 0 | for( int compIdx=0; compIdx < MAX_NUM_COMP; compIdx++ ) |
292 | 0 | { |
293 | 0 | sao_offset_pars( saoPars[compIdx], ComponentID(compIdx), sliceEnabled[compIdx], bitDepths[ toChannelType(ComponentID(compIdx)) ] ); |
294 | 0 | } |
295 | 0 | } |
296 | 0 | } |
297 | | |
298 | | |
299 | | void CABACWriter::sao_offset_pars( const SAOOffset& ctbPars, ComponentID compID, bool sliceEnabled, int bitDepth ) |
300 | 0 | { |
301 | 0 | if( !sliceEnabled ) |
302 | 0 | { |
303 | 0 | CHECK( ctbPars.modeIdc != SAO_MODE_OFF, "Sao must be off, if it is disabled on slice level" ); |
304 | 0 | return; |
305 | 0 | } |
306 | 0 | const bool isFirstCompOfChType = ( getFirstComponentOfChannel( toChannelType(compID) ) == compID ); |
307 | |
|
308 | 0 | if( isFirstCompOfChType ) |
309 | 0 | { |
310 | | // sao_type_idx_luma / sao_type_idx_chroma |
311 | 0 | if( ctbPars.modeIdc == SAO_MODE_OFF ) |
312 | 0 | { |
313 | 0 | m_BinEncoder.encodeBin ( 0, Ctx::SaoTypeIdx() ); |
314 | 0 | } |
315 | 0 | else if( ctbPars.typeIdc == SAO_TYPE_BO ) |
316 | 0 | { |
317 | 0 | m_BinEncoder.encodeBin ( 1, Ctx::SaoTypeIdx() ); |
318 | 0 | m_BinEncoder.encodeBinEP( 0 ); |
319 | 0 | } |
320 | 0 | else |
321 | 0 | { |
322 | 0 | CHECK(!( ctbPars.typeIdc < SAO_TYPE_START_BO ), "Unspecified error"); |
323 | 0 | m_BinEncoder.encodeBin ( 1, Ctx::SaoTypeIdx() ); |
324 | 0 | m_BinEncoder.encodeBinEP( 1 ); |
325 | 0 | } |
326 | 0 | } |
327 | | |
328 | 0 | if( ctbPars.modeIdc == SAO_MODE_NEW ) |
329 | 0 | { |
330 | 0 | const int maxOffsetQVal = SampleAdaptiveOffset::getMaxOffsetQVal( bitDepth ); |
331 | 0 | int numClasses = ( ctbPars.typeIdc == SAO_TYPE_BO ? 4 : NUM_SAO_EO_CLASSES ); |
332 | 0 | int k = 0; |
333 | 0 | int offset[4]; |
334 | 0 | for( int i = 0; i < numClasses; i++ ) |
335 | 0 | { |
336 | 0 | if( ctbPars.typeIdc != SAO_TYPE_BO && i == SAO_CLASS_EO_PLAIN ) |
337 | 0 | { |
338 | 0 | continue; |
339 | 0 | } |
340 | 0 | int classIdx = ( ctbPars.typeIdc == SAO_TYPE_BO ? ( ctbPars.typeAuxInfo + i ) % NUM_SAO_BO_CLASSES : i ); |
341 | 0 | offset[k++] = ctbPars.offset[classIdx]; |
342 | 0 | } |
343 | | |
344 | | // sao_offset_abs |
345 | 0 | for( int i = 0; i < 4; i++ ) |
346 | 0 | { |
347 | 0 | unsigned absOffset = ( offset[i] < 0 ? -offset[i] : offset[i] ); |
348 | 0 | unary_max_eqprob( absOffset, maxOffsetQVal ); |
349 | 0 | } |
350 | | |
351 | | // band offset mode |
352 | 0 | if( ctbPars.typeIdc == SAO_TYPE_BO ) |
353 | 0 | { |
354 | | // sao_offset_sign |
355 | 0 | for( int i = 0; i < 4; i++ ) |
356 | 0 | { |
357 | 0 | if( offset[i] ) |
358 | 0 | { |
359 | 0 | m_BinEncoder.encodeBinEP( (offset[i] < 0) ); |
360 | 0 | } |
361 | 0 | } |
362 | | // sao_band_position |
363 | 0 | m_BinEncoder.encodeBinsEP( ctbPars.typeAuxInfo, NUM_SAO_BO_CLASSES_LOG2 ); |
364 | 0 | } |
365 | | // edge offset mode |
366 | 0 | else |
367 | 0 | { |
368 | 0 | if( isFirstCompOfChType ) |
369 | 0 | { |
370 | | // sao_eo_class_luma / sao_eo_class_chroma |
371 | 0 | CHECK( ctbPars.typeIdc - SAO_TYPE_START_EO < 0, "sao edge offset class is outside valid range" ); |
372 | 0 | m_BinEncoder.encodeBinsEP( ctbPars.typeIdc - SAO_TYPE_START_EO, NUM_SAO_EO_TYPES_LOG2 ); |
373 | 0 | } |
374 | 0 | } |
375 | 0 | } |
376 | 0 | } |
377 | | |
378 | | |
379 | | //================================================================================ |
380 | | // clause 7.3.8.4 |
381 | | //-------------------------------------------------------------------------------- |
382 | | // void coding_tree ( cs, partitioner, cuCtx ) |
383 | | // void split_cu_flag ( split, cs, partitioner ) |
384 | | // void split_cu_mode_mt ( split, cs, partitioner ) |
385 | | //================================================================================ |
386 | | |
387 | | void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, Partitioner* pPartitionerChroma, CUCtx* pCuCtxChroma) |
388 | 0 | { |
389 | 0 | const PPS &pps = *cs.pps; |
390 | 0 | const UnitArea& currArea = partitioner.currArea(); |
391 | 0 | const CodingUnit &cu = *cs.getCU( currArea.blocks[partitioner.chType], partitioner.chType, partitioner.treeType ); |
392 | | |
393 | | // Reset delta QP coding flag and ChromaQPAdjustemt coding flag |
394 | | //Note: do not reset qg at chroma CU |
395 | 0 | if( pps.useDQP && partitioner.currQgEnable() && !isChroma( partitioner.chType ) ) |
396 | 0 | { |
397 | 0 | cuCtx.qgStart = true; |
398 | 0 | cuCtx.isDQPCoded = false; |
399 | 0 | } |
400 | 0 | if( cs.slice->chromaQpAdjEnabled && partitioner.currQgChromaEnable() ) |
401 | 0 | { |
402 | 0 | cuCtx.isChromaQpAdjCoded = false; |
403 | 0 | } |
404 | | // Reset delta QP coding flag and ChromaQPAdjustemt coding flag |
405 | 0 | if (CS::isDualITree(cs) && pPartitionerChroma != nullptr) |
406 | 0 | { |
407 | 0 | if (pps.useDQP && pPartitionerChroma->currQgEnable()) |
408 | 0 | { |
409 | 0 | pCuCtxChroma->qgStart = true; |
410 | 0 | pCuCtxChroma->isDQPCoded = false; |
411 | 0 | } |
412 | 0 | if (cs.slice->chromaQpAdjEnabled && pPartitionerChroma->currQgChromaEnable()) |
413 | 0 | { |
414 | 0 | pCuCtxChroma->isChromaQpAdjCoded = false; |
415 | 0 | } |
416 | 0 | } |
417 | |
|
418 | 0 | determineNeighborCus( cs, partitioner.currArea(), partitioner.chType, partitioner.treeType ); |
419 | |
|
420 | 0 | const PartSplit splitMode = CU::getSplitAtDepth( cu, partitioner.currDepth ); |
421 | |
|
422 | 0 | split_cu_mode( splitMode, cs, partitioner ); |
423 | |
|
424 | 0 | CHECK( !partitioner.canSplit( splitMode, cs ), "The chosen split mode is invalid!" ); |
425 | |
|
426 | 0 | if( splitMode != CU_DONT_SPLIT ) |
427 | 0 | { |
428 | 0 | if (CS::isDualITree(cs) && pPartitionerChroma != nullptr && (partitioner.currArea().lwidth() >= 64 || partitioner.currArea().lheight() >= 64)) |
429 | 0 | { |
430 | 0 | partitioner.splitCurrArea(CU_QUAD_SPLIT, cs); |
431 | 0 | pPartitionerChroma->splitCurrArea(CU_QUAD_SPLIT, cs); |
432 | 0 | bool beContinue = true; |
433 | 0 | bool lumaContinue = true; |
434 | 0 | bool chromaContinue = true; |
435 | |
|
436 | 0 | while (beContinue) |
437 | 0 | { |
438 | 0 | if (partitioner.currArea().lwidth() > 64 || partitioner.currArea().lheight() > 64) |
439 | 0 | { |
440 | 0 | if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos())) |
441 | 0 | { |
442 | 0 | coding_tree(cs, partitioner, cuCtx, pPartitionerChroma, pCuCtxChroma); |
443 | 0 | } |
444 | 0 | lumaContinue = partitioner.nextPart(cs); |
445 | 0 | chromaContinue = pPartitionerChroma->nextPart(cs); |
446 | 0 | CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched"); |
447 | 0 | beContinue = lumaContinue; |
448 | 0 | } |
449 | 0 | else |
450 | 0 | { |
451 | | //dual tree coding under 64x64 block |
452 | 0 | if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos())) |
453 | 0 | { |
454 | 0 | coding_tree(cs, partitioner, cuCtx); |
455 | 0 | } |
456 | 0 | lumaContinue = partitioner.nextPart(cs); |
457 | 0 | if (cs.picture->blocks[pPartitionerChroma->chType].contains(pPartitionerChroma->currArea().blocks[pPartitionerChroma->chType].pos())) |
458 | 0 | { |
459 | 0 | coding_tree(cs, *pPartitionerChroma, *pCuCtxChroma); |
460 | 0 | } |
461 | 0 | chromaContinue = pPartitionerChroma->nextPart(cs); |
462 | 0 | CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched"); |
463 | 0 | beContinue = lumaContinue; |
464 | 0 | } |
465 | 0 | } |
466 | 0 | partitioner.exitCurrSplit(); |
467 | 0 | pPartitionerChroma->exitCurrSplit(); |
468 | |
|
469 | 0 | } |
470 | 0 | else |
471 | 0 | { |
472 | 0 | const ModeType modeTypeParent = partitioner.modeType; |
473 | 0 | const ModeType modeTypeChild = CU::getModeTypeAtDepth( cu, partitioner.currDepth ); |
474 | 0 | mode_constraint( splitMode, cs, partitioner, modeTypeChild ); |
475 | 0 | partitioner.modeType = modeTypeChild; |
476 | |
|
477 | 0 | bool chromaNotSplit = modeTypeParent == MODE_TYPE_ALL && modeTypeChild == MODE_TYPE_INTRA ? true : false; |
478 | 0 | CHECK( chromaNotSplit && partitioner.chType != CH_L, "chType must be luma" ); |
479 | 0 | if( partitioner.treeType == TREE_D ) |
480 | 0 | { |
481 | 0 | partitioner.treeType = chromaNotSplit ? TREE_L : TREE_D; |
482 | 0 | } |
483 | 0 | partitioner.splitCurrArea( splitMode, cs ); |
484 | |
|
485 | 0 | do |
486 | 0 | { |
487 | 0 | if( cs.picture->blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) ) |
488 | 0 | { |
489 | 0 | coding_tree( cs, partitioner, cuCtx ); |
490 | 0 | } |
491 | 0 | } while( partitioner.nextPart( cs ) ); |
492 | |
|
493 | 0 | partitioner.exitCurrSplit(); |
494 | 0 | if( chromaNotSplit ) |
495 | 0 | { |
496 | 0 | if (isChromaEnabled(cs.pcv->chrFormat)) |
497 | 0 | { |
498 | 0 | CHECK( partitioner.chType != CH_L, "must be luma status" ); |
499 | 0 | partitioner.chType = CH_C; |
500 | 0 | partitioner.treeType = TREE_C; |
501 | |
|
502 | 0 | if( cs.picture->blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) ) |
503 | 0 | { |
504 | 0 | coding_tree( cs, partitioner, cuCtx ); |
505 | 0 | } |
506 | 0 | } |
507 | | //recover |
508 | 0 | partitioner.chType = CH_L; |
509 | 0 | partitioner.treeType = TREE_D; |
510 | 0 | } |
511 | 0 | partitioner.modeType = modeTypeParent; |
512 | 0 | } |
513 | 0 | return; |
514 | 0 | } |
515 | | |
516 | | // Predict QP on start of quantization group |
517 | 0 | if( cuCtx.qgStart ) |
518 | 0 | { |
519 | 0 | cuCtx.qgStart = false; |
520 | 0 | cuCtx.qp = CU::predictQP( cu, cuCtx.qp ); |
521 | 0 | } |
522 | 0 | CHECK( cu.treeType != partitioner.treeType, "treeType mismatch" ); |
523 | | |
524 | | |
525 | | // coding unit |
526 | 0 | coding_unit( cu, partitioner, cuCtx ); |
527 | |
|
528 | 0 | if( cu.chType == CH_C ) |
529 | 0 | { |
530 | 0 | DTRACE_COND( (isEncoding()), g_trace_ctx, D_QP, "[chroma CU]x=%d, y=%d, w=%d, h=%d, qp=%d\n", cu.Cb().x, cu.Cb().y, cu.Cb().width, cu.Cb().height, cu.qp ); |
531 | 0 | } |
532 | 0 | else |
533 | 0 | { |
534 | 0 | DTRACE_COND( ( isEncoding() ), g_trace_ctx, D_QP, "x=%d, y=%d, w=%d, h=%d, qp=%d\n", cu.Y().x, cu.Y().y, cu.Y().width, cu.Y().height, cu.qp ); |
535 | 0 | } |
536 | 0 | DTRACE_BLOCK_REC_COND( ( !isEncoding() ), cs.picture->getRecoBuf( cu ), cu, cu.predMode ); |
537 | 0 | } |
538 | | |
539 | | |
540 | | void CABACWriter::mode_constraint( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner, const ModeType modeType ) |
541 | 0 | { |
542 | 0 | CHECK( split == CU_DONT_SPLIT, "splitMode shall not be no split" ); |
543 | 0 | int val = CS::signalModeCons( cs, partitioner.currArea(), split, partitioner.modeType); |
544 | 0 | if( val == LDT_MODE_TYPE_SIGNAL ) |
545 | 0 | { |
546 | 0 | CHECK( modeType == MODE_TYPE_ALL, "shall not be no constraint case" ); |
547 | 0 | bool flag = modeType == MODE_TYPE_INTRA; |
548 | 0 | int ctxIdx = DeriveCtx::CtxModeConsFlag(); |
549 | 0 | m_BinEncoder.encodeBin( flag, Ctx::ModeConsFlag( ctxIdx ) ); |
550 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "mode_cons_flag() flag=%d\n", flag ); |
551 | 0 | } |
552 | 0 | else if( val == LDT_MODE_TYPE_INFER ) |
553 | 0 | { |
554 | 0 | CHECK( modeType != MODE_TYPE_INTRA, "Wrong mode type" ); |
555 | 0 | } |
556 | 0 | else |
557 | 0 | { |
558 | 0 | CHECK( modeType != partitioner.modeType, "Wrong mode type" ); |
559 | 0 | } |
560 | 0 | } |
561 | | |
562 | | |
563 | | void CABACWriter::split_cu_mode( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner ) |
564 | 0 | { |
565 | 0 | bool canNo, canQt, canBh, canBv, canTh, canTv; |
566 | 0 | partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv ); |
567 | |
|
568 | 0 | const bool canSpl[6] = { canNo, canQt, canBh, canBv, canTh, canTv }; |
569 | |
|
570 | 0 | unsigned ctxSplit = 0, ctxQtSplit = 0, ctxBttHV = 0, ctxBttH12 = 0, ctxBttV12; |
571 | 0 | DeriveCtx::CtxSplit( partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl ); |
572 | |
|
573 | 0 | const bool canSplit = canBh || canBv || canTh || canTv || canQt; |
574 | 0 | const bool isNo = split == CU_DONT_SPLIT; |
575 | |
|
576 | 0 | if( canNo && canSplit ) |
577 | 0 | { |
578 | 0 | m_BinEncoder.encodeBin( !isNo, Ctx::SplitFlag( ctxSplit ) ); |
579 | 0 | } |
580 | |
|
581 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d split=%d\n", ctxSplit, !isNo ); |
582 | |
|
583 | 0 | if( isNo ) |
584 | 0 | { |
585 | 0 | return; |
586 | 0 | } |
587 | | |
588 | 0 | const bool canBtt = canBh || canBv || canTh || canTv; |
589 | 0 | const bool isQt = split == CU_QUAD_SPLIT; |
590 | |
|
591 | 0 | if( canQt && canBtt ) |
592 | 0 | { |
593 | 0 | m_BinEncoder.encodeBin( isQt, Ctx::SplitQtFlag( ctxQtSplit ) ); |
594 | 0 | } |
595 | |
|
596 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d qt=%d\n", ctxQtSplit, isQt ); |
597 | |
|
598 | 0 | if( isQt ) |
599 | 0 | { |
600 | 0 | return; |
601 | 0 | } |
602 | | |
603 | 0 | const bool canHor = canBh || canTh; |
604 | 0 | const bool canVer = canBv || canTv; |
605 | 0 | const bool isVer = split == CU_VERT_SPLIT || split == CU_TRIV_SPLIT; |
606 | |
|
607 | 0 | if( canVer && canHor ) |
608 | 0 | { |
609 | 0 | m_BinEncoder.encodeBin( isVer, Ctx::SplitHvFlag( ctxBttHV ) ); |
610 | 0 | } |
611 | |
|
612 | 0 | const bool can14 = isVer ? canTv : canTh; |
613 | 0 | const bool can12 = isVer ? canBv : canBh; |
614 | 0 | const bool is12 = isVer ? ( split == CU_VERT_SPLIT ) : ( split == CU_HORZ_SPLIT ); |
615 | |
|
616 | 0 | if( can12 && can14 ) |
617 | 0 | { |
618 | 0 | m_BinEncoder.encodeBin( is12, Ctx::Split12Flag( isVer ? ctxBttV12 : ctxBttH12 ) ); |
619 | 0 | } |
620 | |
|
621 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctxHv=%d ctx12=%d mode=%d\n", ctxBttHV, isVer ? ctxBttV12 : ctxBttH12, split ); |
622 | 0 | } |
623 | | |
624 | | |
625 | | //================================================================================ |
626 | | // clause 7.3.8.5 |
627 | | //-------------------------------------------------------------------------------- |
628 | | // void coding_unit ( cu, partitioner, cuCtx ) |
629 | | // void cu_skip_flag ( cu ) |
630 | | // void pred_mode ( cu ) |
631 | | // void part_mode ( cu ) |
632 | | // void cu_pred_data ( pus ) |
633 | | // void cu_lic_flag ( cu ) |
634 | | // void intra_luma_pred_modes ( pus ) |
635 | | // void intra_chroma_pred_mode ( cu ) |
636 | | // void cu_residual ( cu, partitioner, cuCtx ) |
637 | | // void rqt_root_cbf ( cu ) |
638 | | // void end_of_ctu ( cu, cuCtx ) |
639 | | //================================================================================ |
640 | | |
641 | | void CABACWriter::coding_unit( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx ) |
642 | 0 | { |
643 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "coding_unit() treeType=%d modeType=%d\n", cu.treeType, cu.modeType ); |
644 | 0 | STAT_COUNT_CU_MODES( isEncoding() && partitioner.chType == CH_L, g_cuCounters1D[CU_CODED_FINALLY][0][!cu.slice->isIntra() + cu.slice->depth] ); |
645 | 0 | STAT_COUNT_CU_MODES( isEncoding() && partitioner.chType == CH_L && !cu.slice->isIntra(), g_cuCounters2D[CU_CODED_FINALLY][Log2( cu.lheight() )][Log2( cu.lwidth() )] ); |
646 | |
|
647 | 0 | CodingStructure& cs = *cu.cs; |
648 | | |
649 | | // skip flag |
650 | 0 | if ((!cs.slice->isIntra() || cs.slice->sps->IBC) && cu.Y().valid()) |
651 | 0 | { |
652 | 0 | cu_skip_flag( cu ); |
653 | 0 | } |
654 | | |
655 | | // skip data |
656 | 0 | if( cu.skip ) |
657 | 0 | { |
658 | 0 | CHECK( !cu.mergeFlag, "Merge flag has to be on!" ); |
659 | 0 | prediction_unit ( cu ); |
660 | 0 | CHECK(cu.colorTransform, "ACT should not be enabled for skip mode"); |
661 | 0 | end_of_ctu ( cu, cuCtx ); |
662 | 0 | return; |
663 | 0 | } |
664 | | |
665 | | // prediction mode and partitioning data |
666 | 0 | pred_mode ( cu ); |
667 | 0 | if (CU::isIntra(cu)) |
668 | 0 | { |
669 | 0 | adaptive_color_transform(cu); |
670 | 0 | } |
671 | 0 | if (CU::isPLT(cu)) |
672 | 0 | { |
673 | 0 | THROW("no support"); |
674 | 0 | return; |
675 | 0 | } |
676 | | |
677 | | // prediction data ( intra prediction modes / reference indexes + motion vectors ) |
678 | 0 | cu_pred_data( cu ); |
679 | | |
680 | | // residual data ( coded block flags + transform coefficient levels ) |
681 | 0 | cu_residual( cu, partitioner, cuCtx ); |
682 | | |
683 | | // end of cu |
684 | 0 | end_of_ctu( cu, cuCtx ); |
685 | 0 | } |
686 | | |
687 | | |
688 | | void CABACWriter::cu_skip_flag( const CodingUnit& cu ) |
689 | 0 | { |
690 | 0 | unsigned ctxId = DeriveCtx::CtxSkipFlag(); |
691 | |
|
692 | 0 | if ((cu.slice->isIntra() || CU::isConsIntra(cu)) && cu.cs->slice->sps->IBC) |
693 | 0 | { |
694 | 0 | if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64 |
695 | 0 | { |
696 | 0 | m_BinEncoder.encodeBin((cu.skip), Ctx::SkipFlag(ctxId)); |
697 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "cu_skip_flag() ctx=%d skip=%d\n", ctxId, cu.skip ? 1 : 0); |
698 | 0 | } |
699 | 0 | return; |
700 | 0 | } |
701 | 0 | if ( !cu.cs->slice->sps->IBC && cu.lwidth() == 4 && cu.lheight() == 4 ) |
702 | 0 | { |
703 | 0 | return; |
704 | 0 | } |
705 | 0 | if( !cu.cs->slice->sps->IBC && CU::isConsIntra(cu) ) |
706 | 0 | { |
707 | 0 | return; |
708 | 0 | } |
709 | 0 | m_BinEncoder.encodeBin( ( cu.skip ), Ctx::SkipFlag( ctxId ) ); |
710 | |
|
711 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "cu_skip_flag() ctx=%d skip=%d\n", ctxId, cu.skip ? 1 : 0 ); |
712 | 0 | if (cu.skip && cu.cs->slice->sps->IBC) |
713 | 0 | { |
714 | 0 | if (cu.lwidth() < 128 && cu.lheight() < 128 && !CU::isConsInter(cu)) // disable IBC mode larger than 64x64 and disable IBC when only allowing inter mode |
715 | 0 | { |
716 | 0 | if ( cu.lwidth() == 4 && cu.lheight() == 4 ) |
717 | 0 | { |
718 | 0 | return; |
719 | 0 | } |
720 | 0 | unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu); |
721 | 0 | m_BinEncoder.encodeBin(CU::isIBC(cu) ? 1 : 0, Ctx::IBCFlag(ctxidx)); |
722 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "ibc() ctx=%d cu.predMode=%d\n", ctxidx, cu.predMode); |
723 | 0 | } |
724 | 0 | } |
725 | 0 | } |
726 | | |
727 | | |
728 | | void CABACWriter::pred_mode( const CodingUnit& cu ) |
729 | 0 | { |
730 | 0 | if (cu.cs->slice->sps->IBC && cu.chType != CH_C) |
731 | 0 | { |
732 | 0 | if( CU::isConsInter(cu) ) |
733 | 0 | { |
734 | 0 | assert( CU::isInter( cu ) ); |
735 | 0 | return; |
736 | 0 | } |
737 | | |
738 | 0 | if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) ) |
739 | 0 | { |
740 | 0 | if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64 |
741 | 0 | { |
742 | 0 | unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu); |
743 | 0 | m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx)); |
744 | 0 | } |
745 | 0 | if (!CU::isIBC(cu) && cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64 && (cu.lumaSize().width * cu.lumaSize().height > 16)) |
746 | 0 | { |
747 | 0 | m_BinEncoder.encodeBin(CU::isPLT(cu), Ctx::PLTFlag(0)); |
748 | 0 | } |
749 | 0 | } |
750 | 0 | else |
751 | 0 | { |
752 | 0 | if( CU::isConsInter(cu) ) |
753 | 0 | { |
754 | 0 | return; |
755 | 0 | } |
756 | 0 | m_BinEncoder.encodeBin((CU::isIntra(cu) || CU::isPLT(cu)), Ctx::PredMode(DeriveCtx::CtxPredModeFlag())); |
757 | 0 | if (CU::isIntra(cu) || CU::isPLT(cu)) |
758 | 0 | { |
759 | 0 | if (cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64 && (cu.lumaSize().width * cu.lumaSize().height > 16)) |
760 | 0 | { |
761 | 0 | m_BinEncoder.encodeBin(CU::isPLT(cu), Ctx::PLTFlag(0)); |
762 | 0 | } |
763 | 0 | } |
764 | 0 | else |
765 | 0 | { |
766 | 0 | if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64 |
767 | 0 | { |
768 | 0 | unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu); |
769 | 0 | m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx)); |
770 | 0 | } |
771 | 0 | } |
772 | 0 | } |
773 | 0 | } |
774 | 0 | else |
775 | 0 | { |
776 | 0 | if( CU::isConsInter(cu) ) |
777 | 0 | { |
778 | 0 | assert( CU::isInter( cu ) ); |
779 | 0 | return; |
780 | 0 | } |
781 | | |
782 | 0 | if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) ) |
783 | 0 | { |
784 | 0 | if (cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64 && ( ( (!isLuma(cu.chType)) && (cu.chromaSize().width * cu.chromaSize().height > 16) ) || ((isLuma(cu.chType)) && ((cu.lumaSize().width * cu.lumaSize().height) > 16 ) ) ) && (!CU::isLocalSepTree(cu) || isLuma(cu.chType) ) ) |
785 | 0 | { |
786 | 0 | m_BinEncoder.encodeBin((CU::isPLT(cu)), Ctx::PLTFlag(0)); |
787 | 0 | } |
788 | 0 | return; |
789 | 0 | } |
790 | 0 | m_BinEncoder.encodeBin((CU::isIntra(cu) || CU::isPLT(cu)), Ctx::PredMode(DeriveCtx::CtxPredModeFlag())); |
791 | 0 | if ((CU::isIntra(cu) || CU::isPLT(cu)) && cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64&& ( ( (!isLuma(cu.chType)) && (cu.chromaSize().width * cu.chromaSize().height > 16) ) || ((isLuma(cu.chType)) && ((cu.lumaSize().width * cu.lumaSize().height) > 16 ) ) ) && (!CU::isLocalSepTree(cu) || isLuma(cu.chType) ) ) |
792 | 0 | { |
793 | 0 | m_BinEncoder.encodeBin((CU::isPLT(cu)), Ctx::PLTFlag(0)); |
794 | 0 | } |
795 | 0 | } |
796 | 0 | } |
797 | | |
798 | | |
799 | | void CABACWriter::bdpcm_mode( const CodingUnit& cu, const ComponentID compID ) |
800 | 0 | { |
801 | 0 | if( !cu.cs->sps->BDPCM) return; |
802 | 0 | if( !CU::bdpcmAllowed( cu, compID ) ) return; |
803 | | |
804 | 0 | int bdpcmMode = cu.bdpcmM[toChannelType(compID)]; |
805 | |
|
806 | 0 | unsigned ctxId = isLuma(compID) ? 0 : 2; |
807 | 0 | m_BinEncoder.encodeBin(bdpcmMode > 0 ? 1 : 0, Ctx::BDPCMMode(ctxId)); |
808 | 0 | if (bdpcmMode) |
809 | 0 | { |
810 | 0 | m_BinEncoder.encodeBin(bdpcmMode > 1 ? 1 : 0, Ctx::BDPCMMode(ctxId+1)); |
811 | 0 | } |
812 | 0 | if (isLuma(compID)) |
813 | 0 | { |
814 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "bdpcm_mode(%d) x=%d, y=%d, w=%d, h=%d, bdpcm=%d\n", CH_L, cu.lumaPos().x, cu.lumaPos().y, cu.lwidth(), cu.lheight(), cu.bdpcmM[CH_L]); |
815 | 0 | } |
816 | 0 | else |
817 | 0 | { |
818 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "bdpcm_mode(%d) x=%d, y=%d, w=%d, h=%d, bdpcm=%d\n", CH_C, cu.chromaPos().x, cu.chromaPos().y, cu.chromaSize().width, cu.chromaSize().height, cu.bdpcmM[CH_C]); |
819 | 0 | } |
820 | 0 | } |
821 | | |
822 | | |
823 | | void CABACWriter::cu_pred_data( const CodingUnit& cu ) |
824 | 0 | { |
825 | 0 | if( CU::isIntra( cu ) ) |
826 | 0 | { |
827 | 0 | if( cu.Y().valid() ) |
828 | 0 | { |
829 | 0 | bdpcm_mode( cu, COMP_Y ); |
830 | 0 | } |
831 | 0 | intra_luma_pred_modes ( cu ); |
832 | 0 | if( ( !cu.Y().valid() || ( !CU::isSepTree(cu) && cu.Y().valid() ) ) && isChromaEnabled(cu.chromaFormat) ) |
833 | 0 | { |
834 | 0 | bdpcm_mode( cu, ComponentID(CH_C) ); |
835 | 0 | } |
836 | 0 | intra_chroma_pred_modes( cu ); |
837 | 0 | return; |
838 | 0 | } |
839 | 0 | if (!cu.Y().valid()) // dual tree chroma CU |
840 | 0 | { |
841 | 0 | return; |
842 | 0 | } |
843 | | |
844 | 0 | prediction_unit ( cu ); |
845 | 0 | imv_mode ( cu ); |
846 | 0 | affine_amvr_mode( cu ); |
847 | 0 | cu_bcw_flag ( cu ); |
848 | 0 | } |
849 | | |
850 | | |
851 | | void CABACWriter::cu_bcw_flag(const CodingUnit& cu) |
852 | 0 | { |
853 | 0 | if(!CU::isBcwIdxCoded(cu)) |
854 | 0 | { |
855 | 0 | return; |
856 | 0 | } |
857 | | |
858 | 0 | CHECK(!(BCW_NUM > 1 && (BCW_NUM == 2 || (BCW_NUM & 0x01) == 1)), " !( BCW_NUM > 1 && ( BCW_NUM == 2 || ( BCW_NUM & 0x01 ) == 1 ) ) "); |
859 | 0 | const uint8_t bcwCodingIdx = (uint8_t)g_BcwCodingOrder[CU::getValidBcwIdx(cu)]; |
860 | |
|
861 | 0 | const int32_t numBcw = (cu.slice->checkLDC) ? 5 : 3; |
862 | 0 | m_BinEncoder.encodeBin((bcwCodingIdx == 0 ? 0 : 1), Ctx::BcwIdx(0)); |
863 | 0 | if(numBcw > 2 && bcwCodingIdx != 0) |
864 | 0 | { |
865 | 0 | const uint32_t prefixNumBits = numBcw - 2; |
866 | 0 | const uint32_t step = 1; |
867 | |
|
868 | 0 | uint8_t idx = 1; |
869 | 0 | for(int ui = 0; ui < prefixNumBits; ++ui) |
870 | 0 | { |
871 | 0 | if (bcwCodingIdx == idx) |
872 | 0 | { |
873 | 0 | m_BinEncoder.encodeBinEP(0); |
874 | 0 | break; |
875 | 0 | } |
876 | 0 | else |
877 | 0 | { |
878 | 0 | m_BinEncoder.encodeBinEP(1); |
879 | 0 | idx += step; |
880 | 0 | } |
881 | 0 | } |
882 | 0 | } |
883 | |
|
884 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "cu_bcw_flag() bcw_idx=%d\n", cu.BcwIdx ? 1 : 0); |
885 | 0 | } |
886 | | |
887 | | |
888 | | void CABACWriter::xWriteTruncBinCode(uint32_t symbol, uint32_t maxSymbol) |
889 | 0 | { |
890 | 0 | int thresh; |
891 | 0 | if (maxSymbol > 256) |
892 | 0 | { |
893 | 0 | int threshVal = 1 << 8; |
894 | 0 | thresh = 8; |
895 | 0 | while (threshVal <= maxSymbol) |
896 | 0 | { |
897 | 0 | thresh++; |
898 | 0 | threshVal <<= 1; |
899 | 0 | } |
900 | 0 | thresh--; |
901 | 0 | } |
902 | 0 | else |
903 | 0 | { |
904 | 0 | thresh = g_tbMax[maxSymbol]; |
905 | 0 | } |
906 | |
|
907 | 0 | int val = 1 << thresh; |
908 | 0 | assert(val <= maxSymbol); |
909 | 0 | assert((val << 1) > maxSymbol); |
910 | 0 | assert(symbol < maxSymbol); |
911 | 0 | int b = maxSymbol - val; |
912 | 0 | assert(b < val); |
913 | 0 | if (symbol < val - b) |
914 | 0 | { |
915 | 0 | m_BinEncoder.encodeBinsEP(symbol, thresh); |
916 | 0 | } |
917 | 0 | else |
918 | 0 | { |
919 | 0 | symbol += val - b; |
920 | 0 | assert(symbol < (val << 1)); |
921 | 0 | assert((symbol >> 1) >= val - b); |
922 | 0 | m_BinEncoder.encodeBinsEP(symbol, thresh + 1); |
923 | 0 | } |
924 | 0 | } |
925 | | |
926 | | |
927 | | void CABACWriter::extend_ref_line(const CodingUnit& cu) |
928 | 0 | { |
929 | 0 | if ( !cu.Y().valid() || cu.predMode != MODE_INTRA || !isLuma(cu.chType) || cu.bdpcmM[CH_L] ) |
930 | 0 | { |
931 | 0 | return; |
932 | 0 | } |
933 | 0 | if( !cu.cs->sps->MRL ) |
934 | 0 | { |
935 | 0 | return; |
936 | 0 | } |
937 | | |
938 | 0 | bool isFirstLineOfCtu = (((cu.block(COMP_Y).y)&((cu.cs->sps)->CTUSize - 1)) == 0); |
939 | 0 | if (isFirstLineOfCtu) |
940 | 0 | { |
941 | 0 | return; |
942 | 0 | } |
943 | 0 | int multiRefIdx = cu.multiRefIdx; |
944 | 0 | if (MRL_NUM_REF_LINES > 1) |
945 | 0 | { |
946 | 0 | m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], Ctx::MultiRefLineIdx(0)); |
947 | 0 | if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0]) |
948 | 0 | { |
949 | 0 | m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1)); |
950 | 0 | } |
951 | 0 | } |
952 | 0 | } |
953 | | |
954 | | |
955 | | void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu ) |
956 | 0 | { |
957 | 0 | if( !cu.Y().valid() || cu.bdpcmM[CH_L] ) |
958 | 0 | { |
959 | 0 | return; |
960 | 0 | } |
961 | | |
962 | 0 | mip_flag(cu); |
963 | 0 | if (cu.mipFlag) |
964 | 0 | { |
965 | 0 | mip_pred_modes(cu); |
966 | 0 | return; |
967 | 0 | } |
968 | 0 | extend_ref_line( cu ); |
969 | |
|
970 | 0 | isp_mode( cu ); |
971 | |
|
972 | 0 | const int numMPMs = NUM_MOST_PROBABLE_MODES; |
973 | 0 | unsigned mpm_pred [numMPMs]; |
974 | 0 | unsigned mpm_idx; |
975 | 0 | unsigned ipred_mode ; |
976 | | |
977 | | // prev_intra_luma_pred_flag |
978 | 0 | { |
979 | 0 | CU::getIntraMPMs( cu, mpm_pred ); |
980 | |
|
981 | 0 | ipred_mode = cu.intraDir[0]; |
982 | 0 | mpm_idx = numMPMs; |
983 | 0 | for( unsigned idx = 0; idx < numMPMs; idx++ ) |
984 | 0 | { |
985 | 0 | if( ipred_mode == mpm_pred[idx] ) |
986 | 0 | { |
987 | 0 | mpm_idx = idx; |
988 | 0 | break; |
989 | 0 | } |
990 | 0 | } |
991 | 0 | if ( cu.multiRefIdx ) |
992 | 0 | { |
993 | 0 | CHECK(mpm_idx >= numMPMs, "use of non-MPM"); |
994 | 0 | } |
995 | 0 | else |
996 | 0 | { |
997 | 0 | m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag()); |
998 | 0 | } |
999 | 0 | } |
1000 | | |
1001 | | // mpm_idx / rem_intra_luma_pred_mode |
1002 | 0 | { |
1003 | 0 | if( mpm_idx < numMPMs ) |
1004 | 0 | { |
1005 | 0 | { |
1006 | 0 | unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0); |
1007 | 0 | if (cu.multiRefIdx == 0) |
1008 | 0 | m_BinEncoder.encodeBin(mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx)); |
1009 | 0 | if( mpm_idx ) |
1010 | 0 | { |
1011 | 0 | m_BinEncoder.encodeBinEP( mpm_idx > 1 ); |
1012 | 0 | } |
1013 | 0 | if (mpm_idx > 1) |
1014 | 0 | { |
1015 | 0 | m_BinEncoder.encodeBinEP(mpm_idx > 2); |
1016 | 0 | } |
1017 | 0 | if (mpm_idx > 2) |
1018 | 0 | { |
1019 | 0 | m_BinEncoder.encodeBinEP(mpm_idx > 3); |
1020 | 0 | } |
1021 | 0 | if (mpm_idx > 3) |
1022 | 0 | { |
1023 | 0 | m_BinEncoder.encodeBinEP(mpm_idx > 4); |
1024 | 0 | } |
1025 | 0 | } |
1026 | 0 | } |
1027 | 0 | else |
1028 | 0 | { |
1029 | | // sorting of MPMs |
1030 | 0 | std::sort( mpm_pred, mpm_pred + numMPMs ); |
1031 | |
|
1032 | 0 | { |
1033 | 0 | for (int idx = numMPMs - 1; idx >= 0; idx--) |
1034 | 0 | { |
1035 | 0 | if (ipred_mode > mpm_pred[idx]) |
1036 | 0 | { |
1037 | 0 | ipred_mode--; |
1038 | 0 | } |
1039 | 0 | } |
1040 | 0 | CHECK(ipred_mode >= 64, "Incorrect mode"); |
1041 | 0 | xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES); // Remaining mode is truncated binary coded |
1042 | 0 | } |
1043 | 0 | } |
1044 | | |
1045 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) mode=%d\n", 0, cu.lumaPos().x, cu.lumaPos().y, cu.intraDir[0] ); |
1046 | 0 | } |
1047 | 0 | } |
1048 | | |
1049 | | |
1050 | | void CABACWriter::intra_luma_pred_mode( const CodingUnit& cu, const unsigned *mpmLst ) |
1051 | 0 | { |
1052 | 0 | if( cu.bdpcmM[CH_L] ) |
1053 | 0 | { |
1054 | 0 | return; |
1055 | 0 | } |
1056 | | |
1057 | 0 | mip_flag(cu); |
1058 | 0 | if (cu.mipFlag) |
1059 | 0 | { |
1060 | 0 | mip_pred_mode(cu); |
1061 | 0 | return; |
1062 | 0 | } |
1063 | 0 | extend_ref_line( cu ); |
1064 | |
|
1065 | 0 | isp_mode( cu ); |
1066 | | |
1067 | | // prev_intra_luma_pred_flag |
1068 | 0 | unsigned ipred_mode = cu.intraDir[0]; |
1069 | 0 | static constexpr int numMPMs = NUM_MOST_PROBABLE_MODES; |
1070 | 0 | unsigned mpm_idx = numMPMs; |
1071 | 0 | unsigned mpm_pred[numMPMs]; |
1072 | |
|
1073 | 0 | if (mpmLst) |
1074 | 0 | { |
1075 | 0 | memcpy(mpm_pred, mpmLst, sizeof(unsigned) * numMPMs); |
1076 | 0 | } |
1077 | 0 | else |
1078 | 0 | { |
1079 | 0 | CU::getIntraMPMs(cu, mpm_pred); |
1080 | 0 | } |
1081 | |
|
1082 | 0 | for (int idx = 0; idx < numMPMs; idx++) |
1083 | 0 | { |
1084 | 0 | if (ipred_mode == mpm_pred[idx]) |
1085 | 0 | { |
1086 | 0 | mpm_idx = idx; |
1087 | 0 | break; |
1088 | 0 | } |
1089 | 0 | } |
1090 | 0 | if (cu.multiRefIdx) |
1091 | 0 | { |
1092 | 0 | CHECK(mpm_idx >= numMPMs, "use of non-MPM"); |
1093 | 0 | } |
1094 | 0 | else |
1095 | 0 | { |
1096 | 0 | m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag()); |
1097 | 0 | } |
1098 | | |
1099 | | // mpm_idx / rem_intra_luma_pred_mode |
1100 | 0 | if( mpm_idx < numMPMs ) |
1101 | 0 | { |
1102 | 0 | unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0); |
1103 | 0 | if (cu.multiRefIdx == 0) |
1104 | 0 | m_BinEncoder.encodeBin( mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx) ); |
1105 | 0 | if( mpm_idx ) |
1106 | 0 | { |
1107 | 0 | m_BinEncoder.encodeBinEP( mpm_idx > 1 ); |
1108 | 0 | } |
1109 | 0 | if (mpm_idx > 1) |
1110 | 0 | { |
1111 | 0 | m_BinEncoder.encodeBinEP(mpm_idx > 2); |
1112 | 0 | } |
1113 | 0 | if (mpm_idx > 2) |
1114 | 0 | { |
1115 | 0 | m_BinEncoder.encodeBinEP(mpm_idx > 3); |
1116 | 0 | } |
1117 | 0 | if (mpm_idx > 3) |
1118 | 0 | { |
1119 | 0 | m_BinEncoder.encodeBinEP(mpm_idx > 4); |
1120 | 0 | } |
1121 | 0 | } |
1122 | 0 | else |
1123 | 0 | { |
1124 | | // mpm_pred[0] is always 0, i.e. PLANAR, so its always first in the list |
1125 | 0 | std::sort( mpm_pred + 1, mpm_pred + numMPMs ); |
1126 | |
|
1127 | 0 | for (int idx = numMPMs - 1; idx >= 0; idx--) |
1128 | 0 | { |
1129 | 0 | if (ipred_mode > mpm_pred[idx]) |
1130 | 0 | { |
1131 | 0 | ipred_mode--; |
1132 | 0 | } |
1133 | 0 | } |
1134 | |
|
1135 | 0 | xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES); // Remaining mode is truncated binary coded |
1136 | 0 | } |
1137 | 0 | } |
1138 | | |
1139 | | |
1140 | | void CABACWriter::intra_chroma_pred_modes( const CodingUnit& cu ) |
1141 | 0 | { |
1142 | 0 | if( cu.chromaFormat == CHROMA_400 || ( CU::isSepTree(cu) && cu.chType == CH_L ) || cu.bdpcmM[CH_C] ) |
1143 | 0 | { |
1144 | 0 | return; |
1145 | 0 | } |
1146 | | |
1147 | 0 | intra_chroma_pred_mode( cu ); |
1148 | 0 | } |
1149 | | |
1150 | | |
1151 | | void CABACWriter::intra_chroma_lmc_mode(const CodingUnit& cu) |
1152 | 0 | { |
1153 | 0 | const unsigned intraDir = cu.intraDir[1]; |
1154 | 0 | int lmModeList[10]; |
1155 | 0 | CU::getLMSymbolList(cu, lmModeList); |
1156 | 0 | int symbol = -1; |
1157 | 0 | for (int k = 0; k < LM_SYMBOL_NUM; k++) |
1158 | 0 | { |
1159 | 0 | if (lmModeList[k] == intraDir) |
1160 | 0 | { |
1161 | 0 | symbol = k; |
1162 | 0 | break; |
1163 | 0 | } |
1164 | 0 | } |
1165 | 0 | CHECK(symbol < 0, "invalid symbol found"); |
1166 | |
|
1167 | 0 | m_BinEncoder.encodeBin(symbol == 0 ? 0 : 1, Ctx::CclmModeIdx(0)); |
1168 | |
|
1169 | 0 | if (symbol > 0) |
1170 | 0 | { |
1171 | 0 | CHECK(symbol > 2, "invalid symbol for MMLM"); |
1172 | 0 | unsigned int symbol_minus_1 = symbol - 1; |
1173 | 0 | m_BinEncoder.encodeBinEP(symbol_minus_1); |
1174 | 0 | } |
1175 | 0 | } |
1176 | | |
1177 | | |
1178 | | void CABACWriter::intra_chroma_pred_mode(const CodingUnit& cu) |
1179 | 0 | { |
1180 | 0 | if (cu.colorTransform) |
1181 | 0 | { |
1182 | 0 | CHECK(cu.intraDir[CH_C] != DM_CHROMA_IDX, "chroma should use DM for adaptive color transform"); |
1183 | 0 | return; |
1184 | 0 | } |
1185 | | |
1186 | 0 | const unsigned intraDir = cu.intraDir[1]; |
1187 | 0 | if (cu.cs->sps->LMChroma && CU::checkCCLMAllowed(cu)) |
1188 | 0 | { |
1189 | 0 | m_BinEncoder.encodeBin(CU::isLMCMode(intraDir) ? 1 : 0, Ctx::CclmModeFlag(0)); |
1190 | 0 | if (CU::isLMCMode(intraDir)) |
1191 | 0 | { |
1192 | 0 | intra_chroma_lmc_mode(cu); |
1193 | 0 | return; |
1194 | 0 | } |
1195 | 0 | } |
1196 | | |
1197 | 0 | const bool isDerivedMode = intraDir == DM_CHROMA_IDX; |
1198 | 0 | m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0)); |
1199 | 0 | if (isDerivedMode) |
1200 | 0 | { |
1201 | 0 | return; |
1202 | 0 | } |
1203 | | |
1204 | | // chroma candidate index |
1205 | 0 | unsigned chromaCandModes[NUM_CHROMA_MODE]; |
1206 | 0 | CU::getIntraChromaCandModes(cu, chromaCandModes); |
1207 | |
|
1208 | 0 | int candId = 0; |
1209 | 0 | for (; candId < NUM_CHROMA_MODE; candId++) |
1210 | 0 | { |
1211 | 0 | if (intraDir == chromaCandModes[candId]) |
1212 | 0 | { |
1213 | 0 | break; |
1214 | 0 | } |
1215 | 0 | } |
1216 | |
|
1217 | 0 | CHECK(candId >= NUM_CHROMA_MODE, "Chroma prediction mode index out of bounds"); |
1218 | 0 | CHECK(chromaCandModes[candId] == DM_CHROMA_IDX, "The intra dir cannot be DM_CHROMA for this path"); |
1219 | 0 | { |
1220 | 0 | m_BinEncoder.encodeBinsEP(candId, 2); |
1221 | 0 | } |
1222 | 0 | } |
1223 | | |
1224 | | |
1225 | | void CABACWriter::cu_residual( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx ) |
1226 | 0 | { |
1227 | 0 | if (!CU::isIntra(cu)) |
1228 | 0 | { |
1229 | 0 | if( !cu.mergeFlag ) |
1230 | 0 | { |
1231 | 0 | rqt_root_cbf( cu ); |
1232 | 0 | } |
1233 | 0 | if( cu.rootCbf ) |
1234 | 0 | { |
1235 | 0 | sbt_mode( cu ); |
1236 | 0 | } |
1237 | |
|
1238 | 0 | if( !cu.rootCbf ) |
1239 | 0 | { |
1240 | 0 | CHECK(cu.colorTransform, "ACT should not be enabled for root_cbf = 0"); |
1241 | 0 | return; |
1242 | 0 | } |
1243 | 0 | } |
1244 | | |
1245 | 0 | if( CU::isInter( cu ) || CU::isIBC( cu ) ) |
1246 | 0 | { |
1247 | 0 | adaptive_color_transform(cu); |
1248 | 0 | } |
1249 | |
|
1250 | 0 | cuCtx.violatesLfnstConstrained[CH_L] = false; |
1251 | 0 | cuCtx.violatesLfnstConstrained[CH_C] = false; |
1252 | 0 | cuCtx.lfnstLastScanPos = false; |
1253 | 0 | cuCtx.violatesMtsCoeffConstraint = false; |
1254 | 0 | cuCtx.mtsLastScanPos = false; |
1255 | |
|
1256 | 0 | if( cu.ispMode && isLuma( partitioner.chType ) ) |
1257 | 0 | { |
1258 | 0 | transform_tree( *cu.cs, partitioner, cuCtx, CU::getISPType( cu, getFirstComponentOfChannel( partitioner.chType ) ), 0 ); |
1259 | 0 | } |
1260 | 0 | else |
1261 | 0 | { |
1262 | 0 | transform_tree( *cu.cs, partitioner, cuCtx ); |
1263 | 0 | } |
1264 | |
|
1265 | 0 | residual_lfnst_mode( cu, cuCtx ); |
1266 | 0 | mts_idx ( cu, &cuCtx ); |
1267 | 0 | } |
1268 | | |
1269 | | |
1270 | | void CABACWriter::rqt_root_cbf( const CodingUnit& cu ) |
1271 | 0 | { |
1272 | 0 | m_BinEncoder.encodeBin( cu.rootCbf, Ctx::QtRootCbf() ); |
1273 | |
|
1274 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "rqt_root_cbf() ctx=0 root_cbf=%d pos=(%d,%d)\n", cu.rootCbf ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y ); |
1275 | 0 | } |
1276 | | |
1277 | | |
1278 | | void CABACWriter::adaptive_color_transform(const CodingUnit& cu) |
1279 | 0 | { |
1280 | 0 | if (!cu.slice->sps->useColorTrans ) |
1281 | 0 | { |
1282 | 0 | return; |
1283 | 0 | } |
1284 | | |
1285 | 0 | if (CU::isSepTree(cu)) |
1286 | 0 | { |
1287 | 0 | CHECK(cu.colorTransform, "adaptive color transform should be disabled when dualtree and localtree are enabled"); |
1288 | 0 | return; |
1289 | 0 | } |
1290 | | |
1291 | 0 | if (CU::isInter(cu) || CU::isIBC(cu) || CU::isIntra(cu)) |
1292 | 0 | { |
1293 | 0 | m_BinEncoder.encodeBin(cu.colorTransform, Ctx::ACTFlag()); |
1294 | 0 | } |
1295 | 0 | } |
1296 | | |
1297 | | |
1298 | | void CABACWriter::sbt_mode( const CodingUnit& cu ) |
1299 | 0 | { |
1300 | 0 | uint8_t sbtAllowed = CU::checkAllowedSbt(cu); |
1301 | 0 | if( !sbtAllowed ) |
1302 | 0 | { |
1303 | 0 | return; |
1304 | 0 | } |
1305 | | |
1306 | 0 | SizeType cuWidth = cu.lwidth(); |
1307 | 0 | SizeType cuHeight = cu.lheight(); |
1308 | 0 | uint8_t sbtIdx = CU::getSbtIdx( cu.sbtInfo ); |
1309 | 0 | uint8_t sbtPos = CU::getSbtPos( cu.sbtInfo ); |
1310 | | |
1311 | | //bin - flag |
1312 | 0 | bool sbtFlag = cu.sbtInfo != 0; |
1313 | 0 | uint8_t ctxIdx = ( cuWidth * cuHeight <= 256 ) ? 1 : 0; |
1314 | 0 | m_BinEncoder.encodeBin( sbtFlag, Ctx::SbtFlag( ctxIdx ) ); |
1315 | 0 | if( !sbtFlag ) |
1316 | 0 | { |
1317 | 0 | return; |
1318 | 0 | } |
1319 | | |
1320 | 0 | bool sbtQuadFlag = sbtIdx == SBT_HOR_QUAD || sbtIdx == SBT_VER_QUAD; |
1321 | 0 | bool sbtHorFlag = sbtIdx == SBT_HOR_HALF || sbtIdx == SBT_HOR_QUAD; |
1322 | 0 | bool sbtPosFlag = sbtPos == SBT_POS1; |
1323 | |
|
1324 | 0 | uint8_t sbtVerHalfAllow = CU::targetSbtAllowed( SBT_VER_HALF, sbtAllowed ); |
1325 | 0 | uint8_t sbtHorHalfAllow = CU::targetSbtAllowed( SBT_HOR_HALF, sbtAllowed ); |
1326 | 0 | uint8_t sbtVerQuadAllow = CU::targetSbtAllowed( SBT_VER_QUAD, sbtAllowed ); |
1327 | 0 | uint8_t sbtHorQuadAllow = CU::targetSbtAllowed( SBT_HOR_QUAD, sbtAllowed ); |
1328 | | //bin - type |
1329 | 0 | if( ( sbtHorHalfAllow || sbtVerHalfAllow ) && ( sbtHorQuadAllow || sbtVerQuadAllow ) ) |
1330 | 0 | { |
1331 | 0 | m_BinEncoder.encodeBin( sbtQuadFlag, Ctx::SbtQuadFlag( 0 ) ); |
1332 | 0 | } |
1333 | 0 | else |
1334 | 0 | { |
1335 | 0 | assert( sbtQuadFlag == 0 ); |
1336 | 0 | } |
1337 | | |
1338 | | //bin - dir |
1339 | 0 | if( ( sbtQuadFlag && sbtVerQuadAllow && sbtHorQuadAllow ) || ( !sbtQuadFlag && sbtVerHalfAllow && sbtHorHalfAllow ) ) //both direction allowed |
1340 | 0 | { |
1341 | 0 | uint8_t ctxIdx = ( cuWidth == cuHeight ) ? 0 : ( cuWidth < cuHeight ? 1 : 2 ); |
1342 | 0 | m_BinEncoder.encodeBin( sbtHorFlag, Ctx::SbtHorFlag( ctxIdx ) ); |
1343 | 0 | } |
1344 | 0 | else |
1345 | 0 | { |
1346 | 0 | assert( sbtHorFlag == ( ( sbtQuadFlag && sbtHorQuadAllow ) || ( !sbtQuadFlag && sbtHorHalfAllow ) ) ); |
1347 | 0 | } |
1348 | | |
1349 | | //bin - pos |
1350 | 0 | m_BinEncoder.encodeBin( sbtPosFlag, Ctx::SbtPosFlag( 0 ) ); |
1351 | |
|
1352 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "sbt_mode() pos=(%d,%d) sbtInfo=%d\n", cu.lx(), cu.ly(), (int)cu.sbtInfo ); |
1353 | 0 | } |
1354 | | |
1355 | | |
1356 | | void CABACWriter::end_of_ctu( const CodingUnit& cu, CUCtx& cuCtx ) |
1357 | 0 | { |
1358 | 0 | const bool isLastSubCUOfCtu = CU::isLastSubCUOfCtu( cu ); |
1359 | |
|
1360 | 0 | if ( isLastSubCUOfCtu |
1361 | 0 | && ( !CU::isSepTree(cu) || cu.chromaFormat == CHROMA_400 || isChroma( cu.chType ) ) |
1362 | 0 | ) |
1363 | 0 | { |
1364 | 0 | cuCtx.isDQPCoded = ( cu.cs->pps->useDQP && !cuCtx.isDQPCoded ); |
1365 | |
|
1366 | 0 | } |
1367 | 0 | } |
1368 | | |
1369 | | |
1370 | | void CABACWriter::cu_palette_info(const CodingUnit& cu, ComponentID compBegin, uint32_t numComp, CUCtx& cuCtx) |
1371 | 0 | { |
1372 | 0 | THROW("no support"); |
1373 | 0 | } |
1374 | | |
1375 | | |
1376 | | //================================================================================ |
1377 | | // clause 7.3.8.6 |
1378 | | //-------------------------------------------------------------------------------- |
1379 | | // void prediction_unit ( cu ); |
1380 | | // void merge_flag ( cu ); |
1381 | | // void merge_idx ( cu ); |
1382 | | // void inter_pred_idc ( cu ); |
1383 | | // void ref_idx ( cu, refList ); |
1384 | | // void mvp_flag ( cu, refList ); |
1385 | | //================================================================================ |
1386 | | |
1387 | | void CABACWriter::prediction_unit( const CodingUnit& cu ) |
1388 | 0 | { |
1389 | 0 | CHECK( cu.treeType == TREE_C, "cannot be chroma CU" ); |
1390 | 0 | if( cu.skip ) |
1391 | 0 | { |
1392 | 0 | CHECK( !cu.mergeFlag, "merge_flag must be true for skipped CUs" ); |
1393 | 0 | } |
1394 | 0 | else |
1395 | 0 | { |
1396 | 0 | merge_flag( cu ); |
1397 | 0 | } |
1398 | 0 | if( cu.mergeFlag ) |
1399 | 0 | { |
1400 | 0 | merge_data(cu); |
1401 | 0 | } |
1402 | 0 | else if (CU::isIBC(cu)) |
1403 | 0 | { |
1404 | 0 | ref_idx(cu, REF_PIC_LIST_0); |
1405 | 0 | Mv mvd = cu.mvd[REF_PIC_LIST_0][0]; |
1406 | 0 | mvd.changeIbcPrecInternal2Amvr(cu.imv); |
1407 | 0 | mvd_coding(mvd, 0); // already changed to signaling precision |
1408 | 0 | if ( cu.slice->sps->maxNumIBCMergeCand == 1 ) |
1409 | 0 | { |
1410 | 0 | CHECK( cu.mvpIdx[REF_PIC_LIST_0], "mvpIdx for IBC mode should be 0" ); |
1411 | 0 | } |
1412 | 0 | else |
1413 | 0 | mvp_flag(cu, REF_PIC_LIST_0); |
1414 | 0 | } |
1415 | 0 | else |
1416 | 0 | { |
1417 | 0 | inter_pred_idc( cu ); |
1418 | 0 | affine_flag ( cu ); |
1419 | 0 | smvd_mode( cu ); |
1420 | 0 | if( cu.interDir != 2 /* PRED_L1 */ ) |
1421 | 0 | { |
1422 | 0 | ref_idx ( cu, REF_PIC_LIST_0 ); |
1423 | 0 | if ( cu.affine ) |
1424 | 0 | { |
1425 | 0 | Mv mvd = cu.mvd[REF_PIC_LIST_0][0]; |
1426 | 0 | mvd.changeAffinePrecInternal2Amvr(cu.imv); |
1427 | 0 | mvd_coding(mvd, 0); // already changed to signaling precision |
1428 | 0 | mvd = cu.mvd[REF_PIC_LIST_0][1]; |
1429 | 0 | mvd.changeAffinePrecInternal2Amvr(cu.imv); |
1430 | 0 | mvd_coding(mvd, 0); // already changed to signaling precision |
1431 | 0 | if ( cu.affineType == AFFINEMODEL_6PARAM ) |
1432 | 0 | { |
1433 | 0 | mvd = cu.mvd[REF_PIC_LIST_0][2]; |
1434 | 0 | mvd.changeAffinePrecInternal2Amvr(cu.imv); |
1435 | 0 | mvd_coding(mvd, 0); // already changed to signaling precision |
1436 | 0 | } |
1437 | 0 | } |
1438 | 0 | else |
1439 | 0 | { |
1440 | 0 | Mv mvd = cu.mvd[REF_PIC_LIST_0][0]; |
1441 | 0 | mvd.changeTransPrecInternal2Amvr(cu.imv); |
1442 | 0 | mvd_coding(mvd, 0); // already changed to signaling precision |
1443 | 0 | } |
1444 | 0 | mvp_flag ( cu, REF_PIC_LIST_0 ); |
1445 | 0 | } |
1446 | 0 | if( cu.interDir != 1 /* PRED_L0 */ ) |
1447 | 0 | { |
1448 | 0 | if ( cu.smvdMode != 1 ) |
1449 | 0 | { |
1450 | 0 | ref_idx ( cu, REF_PIC_LIST_1 ); |
1451 | 0 | if( !cu.cs->picHeader->mvdL1Zero || cu.interDir != 3 /* PRED_BI */ ) |
1452 | 0 | { |
1453 | 0 | if ( cu.affine ) |
1454 | 0 | { |
1455 | 0 | Mv mvd = cu.mvd[REF_PIC_LIST_1][0]; |
1456 | 0 | mvd.changeAffinePrecInternal2Amvr(cu.imv); |
1457 | 0 | mvd_coding(mvd, 0); // already changed to signaling precision |
1458 | 0 | mvd = cu.mvd[REF_PIC_LIST_1][1]; |
1459 | 0 | mvd.changeAffinePrecInternal2Amvr(cu.imv); |
1460 | 0 | mvd_coding(mvd, 0); // already changed to signaling precision |
1461 | 0 | if ( cu.affineType == AFFINEMODEL_6PARAM ) |
1462 | 0 | { |
1463 | 0 | mvd = cu.mvd[REF_PIC_LIST_1][2]; |
1464 | 0 | mvd.changeAffinePrecInternal2Amvr(cu.imv); |
1465 | 0 | mvd_coding(mvd, 0); // already changed to signaling precision |
1466 | 0 | } |
1467 | 0 | } |
1468 | 0 | else |
1469 | 0 | { |
1470 | 0 | Mv mvd = cu.mvd[REF_PIC_LIST_1][0]; |
1471 | 0 | mvd.changeTransPrecInternal2Amvr(cu.imv); |
1472 | 0 | mvd_coding(mvd, 0); // already changed to signaling precision |
1473 | 0 | } |
1474 | 0 | } |
1475 | 0 | } |
1476 | 0 | mvp_flag ( cu, REF_PIC_LIST_1 ); |
1477 | 0 | } |
1478 | 0 | } |
1479 | 0 | } |
1480 | | |
1481 | | |
1482 | | void CABACWriter::smvd_mode( const CodingUnit& cu ) |
1483 | 0 | { |
1484 | 0 | if ( cu.interDir != 3 || cu.affine ) |
1485 | 0 | { |
1486 | 0 | return; |
1487 | 0 | } |
1488 | | |
1489 | 0 | if ( cu.cs->slice->biDirPred == false ) |
1490 | 0 | { |
1491 | 0 | return; |
1492 | 0 | } |
1493 | | |
1494 | 0 | m_BinEncoder.encodeBin( cu.smvdMode ? 1 : 0, Ctx::SmvdFlag() ); |
1495 | |
|
1496 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "symmvd_flag() symmvd=%d pos=(%d,%d) size=%dx%d\n", cu.smvdMode ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height ); |
1497 | 0 | } |
1498 | | |
1499 | | |
1500 | | void CABACWriter::subblock_merge_flag( const CodingUnit& cu ) |
1501 | 0 | { |
1502 | |
|
1503 | 0 | if ( !cu.cs->slice->isIntra() && (cu.slice->picHeader->maxNumAffineMergeCand > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 ) |
1504 | 0 | { |
1505 | 0 | unsigned ctxId = DeriveCtx::CtxAffineFlag(); |
1506 | 0 | m_BinEncoder.encodeBin( cu.affine, Ctx::SubblockMergeFlag( ctxId ) ); |
1507 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "subblock_merge_flag() subblock_merge_flag=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y ); |
1508 | 0 | } |
1509 | 0 | } |
1510 | | |
1511 | | |
1512 | | void CABACWriter::affine_flag( const CodingUnit& cu ) |
1513 | 0 | { |
1514 | 0 | if ( !cu.cs->slice->isIntra() && cu.cs->sps->Affine && cu.lumaSize().width > 8 && cu.lumaSize().height > 8 ) |
1515 | 0 | { |
1516 | 0 | unsigned ctxId = DeriveCtx::CtxAffineFlag(); |
1517 | 0 | m_BinEncoder.encodeBin( cu.affine, Ctx::AffineFlag( ctxId ) ); |
1518 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "affine_flag() affine=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y ); |
1519 | |
|
1520 | 0 | if ( cu.affine && cu.cs->sps->AffineType ) |
1521 | 0 | { |
1522 | 0 | unsigned ctxId = 0; |
1523 | 0 | m_BinEncoder.encodeBin( cu.affineType, Ctx::AffineType( ctxId ) ); |
1524 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "affine_type() affine_type=%d ctx=%d pos=(%d,%d)\n", cu.affineType ? 1 : 0, ctxId, cu.Y().x, cu.Y().y ); |
1525 | 0 | } |
1526 | 0 | } |
1527 | 0 | } |
1528 | | |
1529 | | |
1530 | | void CABACWriter::merge_flag( const CodingUnit& cu ) |
1531 | 0 | { |
1532 | 0 | m_BinEncoder.encodeBin( cu.mergeFlag, Ctx::MergeFlag() ); |
1533 | |
|
1534 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "merge_flag() merge=%d pos=(%d,%d) size=%dx%d\n", cu.mergeFlag ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height ); |
1535 | 0 | } |
1536 | | |
1537 | | |
1538 | | void CABACWriter::merge_data(const CodingUnit& cu) |
1539 | 0 | { |
1540 | 0 | if (CU::isIBC(cu)) |
1541 | 0 | { |
1542 | 0 | merge_idx(cu); |
1543 | 0 | return; |
1544 | 0 | } |
1545 | 0 | subblock_merge_flag(cu); |
1546 | 0 | if (cu.affine) |
1547 | 0 | { |
1548 | 0 | merge_idx(cu); |
1549 | 0 | return; |
1550 | 0 | } |
1551 | | |
1552 | 0 | const bool ciipAvailable = cu.cs->sps->CIIP && !cu.skip && cu.Y().maxDim() < MAX_CU_SIZE && cu.Y().area() >= 64; |
1553 | 0 | const bool geoAvailable = cu.cs->slice->sps->GEO && cu.cs->slice->isInterB() && cu.cs->sps->maxNumGeoCand > 1 |
1554 | 0 | && cu.Y().minDim() >= GEO_MIN_CU_SIZE && cu.Y().maxDim() <= GEO_MAX_CU_SIZE |
1555 | 0 | && cu.Y().maxDim() < 8 * cu.Y().minDim(); |
1556 | |
|
1557 | 0 | if (geoAvailable || ciipAvailable) |
1558 | 0 | { |
1559 | 0 | m_BinEncoder.encodeBin(!cu.geo && !cu.ciip, Ctx::RegularMergeFlag(cu.skip ? 0 : 1)); |
1560 | 0 | } |
1561 | 0 | if (!cu.geo && !cu.ciip) |
1562 | 0 | { |
1563 | 0 | if (cu.cs->sps->MMVD) |
1564 | 0 | { |
1565 | 0 | m_BinEncoder.encodeBin(cu.mmvdMergeFlag, Ctx::MmvdFlag(0)); |
1566 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_flag() mmvd_merge=%d pos=(%d,%d) size=%dx%d\n", cu.mmvdMergeFlag ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height); |
1567 | 0 | } |
1568 | 0 | if (cu.mmvdMergeFlag || cu.mmvdSkip) |
1569 | 0 | { |
1570 | 0 | mmvd_merge_idx(cu); |
1571 | 0 | } |
1572 | 0 | else |
1573 | 0 | { |
1574 | 0 | merge_idx(cu); |
1575 | 0 | } |
1576 | 0 | } |
1577 | 0 | else |
1578 | 0 | { |
1579 | 0 | if (geoAvailable && ciipAvailable) |
1580 | 0 | { |
1581 | 0 | ciip_flag(cu); |
1582 | 0 | } |
1583 | 0 | merge_idx(cu); |
1584 | 0 | } |
1585 | 0 | } |
1586 | | |
1587 | | |
1588 | | void CABACWriter::imv_mode( const CodingUnit& cu ) |
1589 | 0 | { |
1590 | 0 | const SPS *sps = cu.cs->sps; |
1591 | |
|
1592 | 0 | if( !sps->AMVR ) |
1593 | 0 | { |
1594 | 0 | return; |
1595 | 0 | } |
1596 | 0 | if ( cu.affine ) |
1597 | 0 | { |
1598 | 0 | return; |
1599 | 0 | } |
1600 | | |
1601 | 0 | bool bNonZeroMvd = CU::hasSubCUNonZeroMVd( cu ); |
1602 | 0 | if( !bNonZeroMvd ) |
1603 | 0 | { |
1604 | 0 | return; |
1605 | 0 | } |
1606 | | |
1607 | 0 | if (CU::isIBC(cu) == false) |
1608 | 0 | m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 0 ) ); |
1609 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 0), 0 ); |
1610 | |
|
1611 | 0 | if( sps->AMVR && cu.imv > 0 ) |
1612 | 0 | { |
1613 | 0 | if (!CU::isIBC(cu)) |
1614 | 0 | { |
1615 | 0 | m_BinEncoder.encodeBin(cu.imv < IMV_HPEL, Ctx::ImvFlag(4)); |
1616 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", cu.imv < 3, 4); |
1617 | 0 | } |
1618 | 0 | if (cu.imv < IMV_HPEL) |
1619 | 0 | { |
1620 | 0 | m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 1 ) ); |
1621 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 1), 1 ); |
1622 | 0 | } |
1623 | 0 | } |
1624 | |
|
1625 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() IMVFlag=%d\n", cu.imv ); |
1626 | 0 | } |
1627 | | |
1628 | | |
1629 | | void CABACWriter::affine_amvr_mode( const CodingUnit& cu ) |
1630 | 0 | { |
1631 | 0 | const SPS* sps = cu.slice->sps; |
1632 | |
|
1633 | 0 | if( !sps->AffineAmvr || !cu.affine ) |
1634 | 0 | { |
1635 | 0 | return; |
1636 | 0 | } |
1637 | | |
1638 | 0 | if ( !CU::hasSubCUNonZeroAffineMVd( cu ) ) |
1639 | 0 | { |
1640 | 0 | return; |
1641 | 0 | } |
1642 | | |
1643 | 0 | m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 2 ) ); |
1644 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 0), 2 ); |
1645 | |
|
1646 | 0 | if( cu.imv > 0 ) |
1647 | 0 | { |
1648 | 0 | m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 3 ) ); |
1649 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 1), 3 ); |
1650 | 0 | } |
1651 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() IMVFlag=%d\n", cu.imv ); |
1652 | 0 | } |
1653 | | |
1654 | | |
1655 | | void CABACWriter::merge_idx( const CodingUnit& cu ) |
1656 | 0 | { |
1657 | 0 | if ( cu.affine ) |
1658 | 0 | { |
1659 | 0 | int numCandminus1 = int( cu.cs->picHeader->maxNumAffineMergeCand ) - 1; |
1660 | 0 | if ( numCandminus1 > 0 ) |
1661 | 0 | { |
1662 | 0 | if ( cu.mergeIdx == 0 ) |
1663 | 0 | { |
1664 | 0 | m_BinEncoder.encodeBin( 0, Ctx::AffMergeIdx() ); |
1665 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", cu.mergeIdx ); |
1666 | 0 | return; |
1667 | 0 | } |
1668 | 0 | else |
1669 | 0 | { |
1670 | 0 | m_BinEncoder.encodeBin( 1, Ctx::AffMergeIdx() ); |
1671 | 0 | for ( unsigned idx = 1; idx < numCandminus1; idx++ ) |
1672 | 0 | { |
1673 | 0 | m_BinEncoder.encodeBinEP( cu.mergeIdx == idx ? 0 : 1 ); |
1674 | 0 | if ( cu.mergeIdx == idx ) |
1675 | 0 | { |
1676 | 0 | break; |
1677 | 0 | } |
1678 | 0 | } |
1679 | 0 | } |
1680 | 0 | } |
1681 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", cu.mergeIdx ); |
1682 | 0 | } |
1683 | 0 | else |
1684 | 0 | { |
1685 | 0 | if( cu.geo ) |
1686 | 0 | { |
1687 | 0 | uint8_t splitDir = cu.geoSplitDir; |
1688 | 0 | uint8_t candIdx0 = cu.geoMergeIdx[0]; |
1689 | 0 | uint8_t candIdx1 = cu.geoMergeIdx[1]; |
1690 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_split_dir=%d\n", splitDir ); |
1691 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_idx0=%d\n", candIdx0 ); |
1692 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_idx1=%d\n", candIdx1 ); |
1693 | 0 | xWriteTruncBinCode(splitDir, GEO_NUM_PARTITION_MODE); |
1694 | 0 | candIdx1 -= candIdx1 < candIdx0 ? 0 : 1; |
1695 | 0 | const int maxNumGeoCand = cu.cs->sps->maxNumGeoCand; |
1696 | 0 | CHECK(maxNumGeoCand < 2, "Incorrect max number of geo candidates"); |
1697 | 0 | CHECK(candIdx0 >= maxNumGeoCand, "Incorrect candIdx0"); |
1698 | 0 | CHECK(candIdx1 >= maxNumGeoCand, "Incorrect candIdx1"); |
1699 | 0 | int numCandminus2 = maxNumGeoCand - 2; |
1700 | 0 | m_BinEncoder.encodeBin( candIdx0 == 0 ? 0 : 1, Ctx::MergeIdx() ); |
1701 | 0 | if( candIdx0 > 0 ) |
1702 | 0 | { |
1703 | 0 | unary_max_eqprob(candIdx0 - 1, numCandminus2); |
1704 | 0 | } |
1705 | 0 | if (numCandminus2 > 0) |
1706 | 0 | { |
1707 | 0 | m_BinEncoder.encodeBin(candIdx1 == 0 ? 0 : 1, Ctx::MergeIdx()); |
1708 | 0 | if (candIdx1 > 0) |
1709 | 0 | { |
1710 | 0 | unary_max_eqprob(candIdx1 - 1, numCandminus2 - 1); |
1711 | 0 | } |
1712 | 0 | } |
1713 | 0 | return; |
1714 | 0 | } |
1715 | 0 | int numCandminus1 = (cu.predMode == MODE_IBC) ? (int(cu.cs->sps->maxNumIBCMergeCand) - 1) : (int(cu.cs->sps->maxNumMergeCand) - 1); |
1716 | 0 | if( numCandminus1 > 0 ) |
1717 | 0 | { |
1718 | 0 | if( cu.mergeIdx == 0 ) |
1719 | 0 | { |
1720 | 0 | m_BinEncoder.encodeBin( 0, Ctx::MergeIdx() ); |
1721 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", cu.mergeIdx ); |
1722 | 0 | return; |
1723 | 0 | } |
1724 | 0 | else |
1725 | 0 | { |
1726 | 0 | m_BinEncoder.encodeBin( 1, Ctx::MergeIdx() ); |
1727 | 0 | for( unsigned idx = 1; idx < numCandminus1; idx++ ) |
1728 | 0 | { |
1729 | 0 | m_BinEncoder.encodeBinEP( cu.mergeIdx == idx ? 0 : 1 ); |
1730 | 0 | if( cu.mergeIdx == idx ) |
1731 | 0 | { |
1732 | 0 | break; |
1733 | 0 | } |
1734 | 0 | } |
1735 | 0 | } |
1736 | 0 | } |
1737 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", cu.mergeIdx ); |
1738 | 0 | } |
1739 | 0 | } |
1740 | | |
1741 | | |
1742 | | void CABACWriter::mmvd_merge_idx( const CodingUnit &cu ) |
1743 | 0 | { |
1744 | 0 | const int mvdBaseIdx = cu.mmvdMergeIdx.pos.baseIdx; |
1745 | 0 | const int mvdStep = cu.mmvdMergeIdx.pos.step; |
1746 | 0 | const int mvdPosition = cu.mmvdMergeIdx.pos.position; |
1747 | |
|
1748 | 0 | if( cu.cs->sps->maxNumMergeCand > 1 ) |
1749 | 0 | { |
1750 | 0 | static_assert( MMVD_BASE_MV_NUM == 2, "" ); |
1751 | 0 | CHECK( mvdBaseIdx >= 2, "Invalid mvdBaseIdx" ); |
1752 | 0 | m_BinEncoder.encodeBin( mvdBaseIdx, Ctx::MmvdMergeIdx() ); |
1753 | 0 | } |
1754 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "base_mvp_idx() base_mvp_idx=%d\n", mvdBaseIdx ); |
1755 | |
|
1756 | 0 | int numCandminus1_step = MMVD_REFINE_STEP - 1; |
1757 | 0 | if( numCandminus1_step > 0 ) |
1758 | 0 | { |
1759 | 0 | if( mvdStep == 0 ) |
1760 | 0 | { |
1761 | 0 | m_BinEncoder.encodeBin( 0, Ctx::MmvdStepMvpIdx() ); |
1762 | 0 | } |
1763 | 0 | else |
1764 | 0 | { |
1765 | 0 | m_BinEncoder.encodeBin( 1, Ctx::MmvdStepMvpIdx() ); |
1766 | 0 | for( unsigned idx = 1; idx < numCandminus1_step; idx++ ) |
1767 | 0 | { |
1768 | 0 | m_BinEncoder.encodeBinEP( mvdStep == idx ? 0 : 1 ); |
1769 | 0 | if( mvdStep == idx ) |
1770 | 0 | { |
1771 | 0 | break; |
1772 | 0 | } |
1773 | 0 | } |
1774 | 0 | } |
1775 | 0 | } |
1776 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "MmvdStepMvpIdx() MmvdStepMvpIdx=%d\n", mvdStep ); |
1777 | |
|
1778 | 0 | m_BinEncoder.encodeBinsEP( mvdPosition, 2 ); |
1779 | |
|
1780 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", mvdPosition ); |
1781 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", cu.mmvdMergeIdx.val ); |
1782 | 0 | } |
1783 | | |
1784 | | |
1785 | | void CABACWriter::inter_pred_idc( const CodingUnit& cu ) |
1786 | 0 | { |
1787 | 0 | if( !cu.cs->slice->isInterB() ) |
1788 | 0 | { |
1789 | 0 | return; |
1790 | 0 | } |
1791 | 0 | if( !(CU::isBipredRestriction(cu)) ) |
1792 | 0 | { |
1793 | 0 | unsigned ctxId = DeriveCtx::CtxInterDir(cu); |
1794 | 0 | if( cu.interDir == 3 ) |
1795 | 0 | { |
1796 | 0 | m_BinEncoder.encodeBin( 1, Ctx::InterDir(ctxId) ); |
1797 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=%d value=%d pos=(%d,%d)\n", ctxId, cu.interDir, cu.lumaPos().x, cu.lumaPos().y ); |
1798 | 0 | return; |
1799 | 0 | } |
1800 | 0 | else |
1801 | 0 | { |
1802 | 0 | m_BinEncoder.encodeBin( 0, Ctx::InterDir(ctxId) ); |
1803 | 0 | } |
1804 | 0 | } |
1805 | 0 | m_BinEncoder.encodeBin( ( cu.interDir == 2 ), Ctx::InterDir( 5 ) ); |
1806 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=5 value=%d pos=(%d,%d)\n", cu.interDir, cu.lumaPos().x, cu.lumaPos().y ); |
1807 | 0 | } |
1808 | | |
1809 | | |
1810 | | void CABACWriter::ref_idx( const CodingUnit& cu, RefPicList eRefList ) |
1811 | 0 | { |
1812 | 0 | if ( cu.smvdMode ) |
1813 | 0 | { |
1814 | 0 | CHECK( cu.refIdx[eRefList] != cu.cs->slice->symRefIdx[ eRefList ], "Invalid reference index!\n" ); |
1815 | 0 | return; |
1816 | 0 | } |
1817 | | |
1818 | 0 | int numRef = cu.cs->slice->numRefIdx[eRefList]; |
1819 | |
|
1820 | 0 | if (eRefList == REF_PIC_LIST_0 && cu.cs->sps->IBC) |
1821 | 0 | { |
1822 | 0 | if (CU::isIBC(cu)) |
1823 | 0 | return; |
1824 | 0 | } |
1825 | | |
1826 | 0 | if( numRef <= 1 ) |
1827 | 0 | { |
1828 | 0 | return; |
1829 | 0 | } |
1830 | 0 | int refIdx = cu.refIdx[eRefList]; |
1831 | 0 | m_BinEncoder.encodeBin( (refIdx > 0), Ctx::RefPic() ); |
1832 | 0 | if( numRef <= 2 || refIdx == 0 ) |
1833 | 0 | { |
1834 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y ); |
1835 | 0 | return; |
1836 | 0 | } |
1837 | 0 | m_BinEncoder.encodeBin( (refIdx > 1), Ctx::RefPic(1) ); |
1838 | 0 | if( numRef <= 3 || refIdx == 1 ) |
1839 | 0 | { |
1840 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y ); |
1841 | 0 | return; |
1842 | 0 | } |
1843 | 0 | for( int idx = 3; idx < numRef; idx++ ) |
1844 | 0 | { |
1845 | 0 | if( refIdx > idx - 1 ) |
1846 | 0 | { |
1847 | 0 | m_BinEncoder.encodeBinEP( 1 ); |
1848 | 0 | } |
1849 | 0 | else |
1850 | 0 | { |
1851 | 0 | m_BinEncoder.encodeBinEP( 0 ); |
1852 | 0 | break; |
1853 | 0 | } |
1854 | 0 | } |
1855 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y ); |
1856 | 0 | } |
1857 | | |
1858 | | |
1859 | | void CABACWriter::mvp_flag( const CodingUnit& cu, RefPicList eRefList ) |
1860 | 0 | { |
1861 | 0 | m_BinEncoder.encodeBin( cu.mvpIdx[eRefList], Ctx::MVPIdx() ); |
1862 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "mvp_flag() value=%d pos=(%d,%d)\n", cu.mvpIdx[eRefList], cu.lumaPos().x, cu.lumaPos().y ); |
1863 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "mvpIdx(refList:%d)=%d\n", eRefList, cu.mvpIdx[eRefList] ); |
1864 | 0 | } |
1865 | | |
1866 | | |
1867 | | void CABACWriter::ciip_flag(const CodingUnit& cu) |
1868 | 0 | { |
1869 | 0 | if (!cu.cs->sps->CIIP) |
1870 | 0 | { |
1871 | 0 | CHECK(cu.ciip == true, "invalid Ciip SPS"); |
1872 | 0 | return; |
1873 | 0 | } |
1874 | 0 | if (cu.skip) |
1875 | 0 | { |
1876 | 0 | CHECK(cu.ciip == true, "invalid Ciip and skip"); |
1877 | 0 | return; |
1878 | 0 | } |
1879 | 0 | m_BinEncoder.encodeBin(cu.ciip, Ctx::CiipFlag()); |
1880 | 0 | DTRACE(g_trace_ctx, D_SYNTAX, "Ciip_flag() Ciip=%d pos=(%d,%d) size=%dx%d\n", cu.ciip ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height); |
1881 | 0 | } |
1882 | | |
1883 | | |
1884 | | //================================================================================ |
1885 | | // clause 7.3.8.8 |
1886 | | //-------------------------------------------------------------------------------- |
1887 | | // void transform_tree ( cs, area, cuCtx, chromaCbfs ) |
1888 | | // bool split_transform_flag( split, depth ) |
1889 | | // bool cbf_comp ( cbf, area, depth ) |
1890 | | //================================================================================ |
1891 | | |
1892 | | void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, const PartSplit ispType, const int subTuIdx ) |
1893 | 0 | { |
1894 | 0 | const UnitArea& area = partitioner.currArea(); |
1895 | 0 | int subTuCounter = subTuIdx; |
1896 | 0 | const TransformUnit& tu = *cs.getTU(area.blocks[partitioner.chType].pos(), partitioner.chType, subTuIdx); |
1897 | 0 | const CodingUnit& cu = *tu.cu; |
1898 | 0 | const unsigned trDepth = partitioner.currTrDepth; |
1899 | 0 | const bool split = (tu.depth > trDepth); |
1900 | 0 | if( split ) |
1901 | 0 | { |
1902 | 0 | PartSplit partSplit; |
1903 | |
|
1904 | 0 | if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) ) |
1905 | 0 | { |
1906 | | #if ENABLE_TRACING |
1907 | | const CompArea& tuArea = partitioner.currArea().blocks[partitioner.chType]; |
1908 | | DTRACE( g_trace_ctx, D_SYNTAX, "transform_tree() maxTrSplit chType=%d pos=(%d,%d) size=%dx%d\n", partitioner.chType, tuArea.x, tuArea.y, tuArea.width, tuArea.height ); |
1909 | | |
1910 | | #endif |
1911 | 0 | partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs ); |
1912 | 0 | } |
1913 | 0 | else if( cu.ispMode ) |
1914 | 0 | { |
1915 | 0 | partitioner.splitCurrArea( ispType, cs ); |
1916 | 0 | } |
1917 | 0 | else if( cu.sbtInfo && partitioner.canSplit( partSplit = CU::getSbtTuSplit( cu.sbtInfo ), cs ) ) |
1918 | 0 | { |
1919 | 0 | partitioner.splitCurrArea( partSplit, cs ); |
1920 | 0 | } |
1921 | 0 | else |
1922 | 0 | THROW( "Implicit TU split not available" ); |
1923 | | |
1924 | 0 | do |
1925 | 0 | { |
1926 | 0 | transform_tree( cs, partitioner, cuCtx, ispType, subTuCounter ); |
1927 | 0 | subTuCounter += subTuCounter != -1 ? 1 : 0; |
1928 | 0 | } while( partitioner.nextPart( cs ) ); |
1929 | |
|
1930 | 0 | partitioner.exitCurrSplit(); |
1931 | 0 | } |
1932 | 0 | else |
1933 | 0 | { |
1934 | | // split_transform_flag |
1935 | 0 | CHECK( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) || (cu.sbtInfo && partitioner.canSplit( CU::getSbtTuSplit( cu.sbtInfo ), cs)), "transform split implied" ); |
1936 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "transform_unit() pos=(%d,%d) size=%dx%d depth=%d trDepth=%d\n", tu.blocks[tu.chType].x, tu.blocks[tu.chType].y, tu.blocks[tu.chType].width, tu.blocks[tu.chType].height, cu.depth, partitioner.currTrDepth ); |
1937 | |
|
1938 | 0 | transform_unit( tu, cuCtx, partitioner, subTuCounter); |
1939 | 0 | } |
1940 | 0 | } |
1941 | | |
1942 | | |
1943 | | void CABACWriter::cbf_comp( const CodingUnit& cu, bool cbf, const CompArea& area, unsigned depth, const bool prevCbf, const bool useISP ) |
1944 | 0 | { |
1945 | 0 | const CtxSet& ctxSet = Ctx::QtCbf[ area.compID ]; |
1946 | 0 | unsigned ctxId; |
1947 | 0 | if( cu.bdpcmM[toChannelType(area.compID)] ) |
1948 | 0 | { |
1949 | 0 | ctxId = (area.compID != COMP_Cr) ? 1 : 2; |
1950 | 0 | m_BinEncoder.encodeBin(cbf, ctxSet(ctxId)); |
1951 | 0 | } |
1952 | 0 | else |
1953 | 0 | { |
1954 | 0 | ctxId = DeriveCtx::CtxQtCbf(area.compID, prevCbf, useISP && isLuma(area.compID)); |
1955 | 0 | m_BinEncoder.encodeBin( cbf, ctxSet( ctxId ) ); |
1956 | 0 | } |
1957 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "cbf_comp() etype=%d pos=(%d,%d) ctx=%d cbf=%d\n", area.compID, area.x, area.y, ctxId, cbf ); |
1958 | 0 | } |
1959 | | |
1960 | | |
1961 | | |
1962 | | //================================================================================ |
1963 | | // clause 7.3.8.9 |
1964 | | //-------------------------------------------------------------------------------- |
1965 | | // void mvd_coding( cu, refList ) |
1966 | | //================================================================================ |
1967 | | void CABACWriter::mvd_coding( const Mv &rMvd, int8_t imv ) |
1968 | 0 | { |
1969 | 0 | int horMvd = rMvd.hor; |
1970 | 0 | int verMvd = rMvd.ver; |
1971 | 0 | if ( imv > 0 ) |
1972 | 0 | { |
1973 | 0 | int shift = 1; |
1974 | 0 | if (imv < IMV_HPEL) |
1975 | 0 | { |
1976 | 0 | shift = 2; |
1977 | 0 | if (imv == IMV_4PEL) |
1978 | 0 | { |
1979 | 0 | shift = 4; |
1980 | 0 | } |
1981 | 0 | } |
1982 | |
|
1983 | 0 | CHECK((horMvd % (1<<shift)) != 0 && (verMvd % (4<<shift)) != 0, "IMV: MVD is not a multiple of 2^N "); |
1984 | 0 | horMvd >>= shift; |
1985 | 0 | verMvd >>= shift; |
1986 | 0 | } |
1987 | 0 | unsigned horAbs = unsigned( horMvd < 0 ? -horMvd : horMvd ); |
1988 | 0 | unsigned verAbs = unsigned( verMvd < 0 ? -verMvd : verMvd ); |
1989 | | |
1990 | | |
1991 | | // abs_mvd_greater0_flag[ 0 | 1 ] |
1992 | 0 | m_BinEncoder.encodeBin( (horAbs > 0), Ctx::Mvd() ); |
1993 | 0 | m_BinEncoder.encodeBin( (verAbs > 0), Ctx::Mvd() ); |
1994 | | |
1995 | | // abs_mvd_greater1_flag[ 0 | 1 ] |
1996 | 0 | if( horAbs > 0 ) |
1997 | 0 | { |
1998 | 0 | m_BinEncoder.encodeBin( (horAbs > 1), Ctx::Mvd(1) ); |
1999 | 0 | } |
2000 | 0 | if( verAbs > 0 ) |
2001 | 0 | { |
2002 | 0 | m_BinEncoder.encodeBin( (verAbs > 1), Ctx::Mvd(1) ); |
2003 | 0 | } |
2004 | | |
2005 | | // abs_mvd_minus2[ 0 | 1 ] and mvd_sign_flag[ 0 | 1 ] |
2006 | 0 | if( horAbs > 0 ) |
2007 | 0 | { |
2008 | 0 | if( horAbs > 1 ) |
2009 | 0 | { |
2010 | 0 | m_BinEncoder.encodeRemAbsEP(horAbs - 2, 1, 0, MV_BITS - 1); |
2011 | 0 | } |
2012 | 0 | m_BinEncoder.encodeBinEP( (horMvd < 0) ); |
2013 | 0 | } |
2014 | 0 | if( verAbs > 0 ) |
2015 | 0 | { |
2016 | 0 | if( verAbs > 1 ) |
2017 | 0 | { |
2018 | 0 | m_BinEncoder.encodeRemAbsEP(verAbs - 2, 1, 0, MV_BITS - 1); |
2019 | 0 | } |
2020 | 0 | m_BinEncoder.encodeBinEP( (verMvd < 0) ); |
2021 | 0 | } |
2022 | 0 | } |
2023 | | |
2024 | | |
2025 | | //================================================================================ |
2026 | | // clause 7.3.8.10 |
2027 | | //-------------------------------------------------------------------------------- |
2028 | | // void transform_unit ( tu, cuCtx, chromaCbfs ) |
2029 | | // void cu_qp_delta ( cu ) |
2030 | | // void cu_chroma_qp_offset ( cu ) |
2031 | | //================================================================================ |
2032 | | void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, Partitioner& partitioner, const int subTuCounter) |
2033 | 0 | { |
2034 | 0 | const CodingUnit& cu = *tu.cu; |
2035 | 0 | const UnitArea& area = partitioner.currArea(); |
2036 | 0 | const unsigned trDepth = partitioner.currTrDepth; |
2037 | 0 | ChromaCbfs chromaCbfs; |
2038 | 0 | CHECK(tu.depth != trDepth, " transform unit should be not be futher partitioned"); |
2039 | | |
2040 | | // cbf_cb & cbf_cr |
2041 | 0 | if (area.chromaFormat != CHROMA_400) |
2042 | 0 | { |
2043 | 0 | const bool chromaCbfISP = area.blocks[COMP_Cb].valid() && cu.ispMode; |
2044 | 0 | if (area.blocks[COMP_Cb].valid() && (!CU::isSepTree(cu) || partitioner.chType == CH_C) && (!cu.ispMode || chromaCbfISP)) |
2045 | 0 | { |
2046 | 0 | unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth; |
2047 | 0 | { |
2048 | 0 | chromaCbfs.Cb = TU::getCbfAtDepth(tu, COMP_Cb, trDepth); |
2049 | | //if (!(cu.sbtInfo && trDepth == 1)) |
2050 | 0 | if (!(cu.sbtInfo && tu.noResidual)) |
2051 | 0 | cbf_comp(*tu.cu, chromaCbfs.Cb, area.blocks[COMP_Cb], cbfDepth); |
2052 | 0 | } |
2053 | |
|
2054 | 0 | { |
2055 | 0 | chromaCbfs.Cr = TU::getCbfAtDepth(tu, COMP_Cr, trDepth); |
2056 | | //if (!(cu.sbtInfo && trDepth == 1)) |
2057 | 0 | if (!(cu.sbtInfo && tu.noResidual)) |
2058 | 0 | cbf_comp(*tu.cu, chromaCbfs.Cr, area.blocks[COMP_Cr], cbfDepth, chromaCbfs.Cb); |
2059 | 0 | } |
2060 | 0 | } |
2061 | 0 | else if (CU::isSepTree(cu)) |
2062 | 0 | { |
2063 | 0 | chromaCbfs = ChromaCbfs(false); |
2064 | 0 | } |
2065 | 0 | } |
2066 | 0 | else if (CU::isSepTree(cu)) |
2067 | 0 | { |
2068 | 0 | chromaCbfs = ChromaCbfs(false); |
2069 | 0 | } |
2070 | |
|
2071 | 0 | if (!isChroma(partitioner.chType)) |
2072 | 0 | { |
2073 | 0 | if (!CU::isIntra(cu) && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat)) |
2074 | 0 | { |
2075 | 0 | CHECK(!TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be true for inter units with no chroma coeffs"); |
2076 | 0 | } |
2077 | 0 | else if (cu.sbtInfo && tu.noResidual) |
2078 | 0 | { |
2079 | 0 | CHECK(TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be false for inter sbt no-residual tu"); |
2080 | 0 | } |
2081 | 0 | else if (cu.sbtInfo && !chromaCbfs.sigChroma(area.chromaFormat)) |
2082 | 0 | { |
2083 | 0 | assert(!tu.noResidual); |
2084 | 0 | CHECK(!TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be true for inter sbt residual tu"); |
2085 | 0 | } |
2086 | 0 | else |
2087 | 0 | { |
2088 | 0 | bool previousCbf = false; |
2089 | 0 | bool rootCbfSoFar = false; |
2090 | 0 | bool lumaCbfIsInferredACT = (cu.colorTransform && cu.predMode == MODE_INTRA && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat)); |
2091 | 0 | CHECK(lumaCbfIsInferredACT && !TU::getCbfAtDepth(tu, COMP_Y, trDepth), "adaptive color transform cannot have all zero coefficients"); |
2092 | 0 | bool lastCbfIsInferred = lumaCbfIsInferredACT; // ISP and ACT are mutually exclusive |
2093 | 0 | if (cu.ispMode) |
2094 | 0 | { |
2095 | 0 | uint32_t nTus = cu.ispMode == HOR_INTRA_SUBPARTITIONS ? cu.lheight() >> Log2(tu.lheight()) : cu.lwidth() >> Log2(tu.lwidth()); |
2096 | 0 | if (subTuCounter == nTus - 1) |
2097 | 0 | { |
2098 | 0 | TransformUnit* tuPointer = cu.firstTU; |
2099 | 0 | for (int tuIdx = 0; tuIdx < subTuCounter; tuIdx++) |
2100 | 0 | { |
2101 | 0 | rootCbfSoFar |= TU::getCbfAtDepth(*tuPointer, COMP_Y, trDepth); |
2102 | 0 | tuPointer = tuPointer->next; |
2103 | 0 | } |
2104 | 0 | if (!rootCbfSoFar) |
2105 | 0 | { |
2106 | 0 | lastCbfIsInferred = true; |
2107 | 0 | } |
2108 | 0 | } |
2109 | 0 | if (!lastCbfIsInferred) |
2110 | 0 | { |
2111 | 0 | previousCbf = TU::getPrevTuCbfAtDepth(tu, COMP_Y, partitioner.currTrDepth); |
2112 | 0 | } |
2113 | 0 | } |
2114 | 0 | if (!lastCbfIsInferred) |
2115 | 0 | { |
2116 | 0 | cbf_comp(*tu.cu, TU::getCbfAtDepth(tu, COMP_Y, trDepth), tu.Y(), trDepth, previousCbf, cu.ispMode); |
2117 | 0 | } |
2118 | 0 | } |
2119 | 0 | } |
2120 | 0 | bool lumaOnly = ( cu.chromaFormat == CHROMA_400 || !tu.blocks[COMP_Cb].valid() ); |
2121 | 0 | bool cbf[3] = { TU::getCbf( tu, COMP_Y ), chromaCbfs.Cb, chromaCbfs.Cr }; |
2122 | 0 | bool cbfLuma = ( cbf[ COMP_Y ] != 0 ); |
2123 | 0 | bool cbfChroma = false; |
2124 | |
|
2125 | 0 | if( !lumaOnly ) |
2126 | 0 | { |
2127 | 0 | if( tu.blocks[COMP_Cb].valid() ) |
2128 | 0 | { |
2129 | 0 | cbf [ COMP_Cb ] = TU::getCbf( tu, COMP_Cb ); |
2130 | 0 | cbf [ COMP_Cr ] = TU::getCbf( tu, COMP_Cr ); |
2131 | 0 | } |
2132 | 0 | cbfChroma = ( cbf[ COMP_Cb ] || cbf[ COMP_Cr ] ); |
2133 | 0 | } |
2134 | |
|
2135 | 0 | if( ( cu.lwidth() > 64 || cu.lheight() > 64 || cbfLuma || cbfChroma ) && |
2136 | 0 | (!CU::isSepTree(*tu.cu) || isLuma(tu.chType)) ) |
2137 | 0 | { |
2138 | 0 | if( cu.cs->pps->useDQP && !cuCtx.isDQPCoded ) |
2139 | 0 | { |
2140 | 0 | cu_qp_delta(cu, cuCtx.qp, cu.qp); |
2141 | 0 | cuCtx.qp = cu.qp; |
2142 | 0 | cuCtx.isDQPCoded = true; |
2143 | 0 | } |
2144 | 0 | } |
2145 | 0 | if (cu.cs->slice->chromaQpAdjEnabled && cbfChroma && !cuCtx.isChromaQpAdjCoded) |
2146 | 0 | { |
2147 | 0 | cu_chroma_qp_offset( cu ); |
2148 | 0 | cuCtx.isChromaQpAdjCoded = true; |
2149 | 0 | } |
2150 | |
|
2151 | 0 | if( !lumaOnly ) |
2152 | 0 | { |
2153 | 0 | joint_cb_cr( tu, ( cbf[COMP_Cb] ? 2 : 0 ) + ( cbf[COMP_Cr] ? 1 : 0 ) ); |
2154 | 0 | } |
2155 | |
|
2156 | 0 | if( cbfLuma ) |
2157 | 0 | { |
2158 | 0 | residual_coding( tu, COMP_Y, &cuCtx ); |
2159 | 0 | } |
2160 | 0 | if( !lumaOnly ) |
2161 | 0 | { |
2162 | 0 | for( ComponentID compID = COMP_Cb; compID <= COMP_Cr; compID = ComponentID( compID + 1 ) ) |
2163 | 0 | { |
2164 | 0 | if( cbf[ compID ] ) |
2165 | 0 | { |
2166 | 0 | residual_coding( tu, compID, &cuCtx ); |
2167 | 0 | } |
2168 | 0 | } |
2169 | 0 | } |
2170 | 0 | } |
2171 | | |
2172 | | |
2173 | | void CABACWriter::cu_qp_delta( const CodingUnit& cu, int predQP, const int8_t qp ) |
2174 | 0 | { |
2175 | 0 | CHECK(!( predQP != std::numeric_limits<int>::max()), "Unspecified error"); |
2176 | 0 | int DQp = qp - predQP; |
2177 | 0 | int qpBdOffsetY = cu.cs->sps->qpBDOffset[ CH_L ]; |
2178 | 0 | DQp = ( DQp + (MAX_QP + 1) + (MAX_QP + 1) / 2 + qpBdOffsetY + (qpBdOffsetY / 2)) % ((MAX_QP + 1) + qpBdOffsetY) - (MAX_QP + 1) / 2 - (qpBdOffsetY / 2); |
2179 | 0 | unsigned absDQP = unsigned( DQp < 0 ? -DQp : DQp ); |
2180 | 0 | unsigned unaryDQP = std::min<unsigned>( absDQP, CU_DQP_TU_CMAX ); |
2181 | |
|
2182 | 0 | unary_max_symbol( unaryDQP, Ctx::DeltaQP(), Ctx::DeltaQP(1), CU_DQP_TU_CMAX ); |
2183 | 0 | if( absDQP >= CU_DQP_TU_CMAX ) |
2184 | 0 | { |
2185 | 0 | exp_golomb_eqprob( absDQP - CU_DQP_TU_CMAX, CU_DQP_EG_k ); |
2186 | 0 | } |
2187 | 0 | if( absDQP > 0 ) |
2188 | 0 | { |
2189 | 0 | m_BinEncoder.encodeBinEP( DQp < 0 ); |
2190 | 0 | } |
2191 | |
|
2192 | 0 | DTRACE_COND( ( isEncoding() ), g_trace_ctx, D_DQP, "x=%d, y=%d, d=%d, pred_qp=%d, DQp=%d, qp=%d\n", cu.blocks[cu.chType].lumaPos().x, cu.blocks[cu.chType].lumaPos().y, cu.qtDepth, predQP, DQp, qp ); |
2193 | 0 | } |
2194 | | |
2195 | | |
2196 | | void CABACWriter::cu_chroma_qp_offset( const CodingUnit& cu ) |
2197 | 0 | { |
2198 | | // cu_chroma_qp_offset_flag |
2199 | 0 | unsigned qpAdj = cu.chromaQpAdj; |
2200 | 0 | if( qpAdj == 0 ) |
2201 | 0 | { |
2202 | 0 | m_BinEncoder.encodeBin( 0, Ctx::ChromaQpAdjFlag() ); |
2203 | 0 | } |
2204 | 0 | else |
2205 | 0 | { |
2206 | 0 | m_BinEncoder.encodeBin( 1, Ctx::ChromaQpAdjFlag() ); |
2207 | 0 | int length = cu.cs->pps->chromaQpOffsetListLen; |
2208 | 0 | if( length > 1 ) |
2209 | 0 | { |
2210 | 0 | unary_max_symbol( qpAdj-1, Ctx::ChromaQpAdjIdc(), Ctx::ChromaQpAdjIdc(), length-1 ); |
2211 | 0 | } |
2212 | 0 | } |
2213 | 0 | } |
2214 | | |
2215 | | |
2216 | | //================================================================================ |
2217 | | // clause 7.3.8.11 |
2218 | | //-------------------------------------------------------------------------------- |
2219 | | // void residual_coding ( tu, compID ) |
2220 | | // void transform_skip_flag ( tu, compID ) |
2221 | | // void last_sig_coeff ( coeffCtx ) |
2222 | | // void residual_coding_subblock( coeffCtx ) |
2223 | | //================================================================================ |
2224 | | |
2225 | | void CABACWriter::joint_cb_cr( const TransformUnit& tu, const int cbfMask ) |
2226 | 0 | { |
2227 | 0 | if ( !tu.cu->slice->sps->jointCbCr ) |
2228 | 0 | { |
2229 | 0 | return; |
2230 | 0 | } |
2231 | | |
2232 | 0 | CHECK( tu.jointCbCr && tu.jointCbCr != cbfMask, "wrong value of jointCbCr (" << (int)tu.jointCbCr << " vs " << (int)cbfMask << ")" ); |
2233 | 0 | if( ( CU::isIntra( *tu.cu ) && cbfMask ) || ( cbfMask == 3 ) ) |
2234 | 0 | { |
2235 | 0 | m_BinEncoder.encodeBin( tu.jointCbCr ? 1 : 0, Ctx::JointCbCrFlag( cbfMask - 1 ) ); |
2236 | 0 | } |
2237 | 0 | } |
2238 | | |
2239 | | |
2240 | | void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx ) |
2241 | 0 | { |
2242 | 0 | const CodingUnit& cu = *tu.cu; |
2243 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "residual_coding() etype=%d pos=(%d,%d) size=%dx%d predMode=%d\n", tu.blocks[compID].compID, tu.blocks[compID].x, tu.blocks[compID].y, tu.blocks[compID].width, tu.blocks[compID].height, cu.predMode ); |
2244 | |
|
2245 | 0 | if( compID == COMP_Cr && tu.jointCbCr == 3 ) |
2246 | 0 | { |
2247 | 0 | return; |
2248 | 0 | } |
2249 | | |
2250 | 0 | ts_flag ( tu, compID ); |
2251 | |
|
2252 | 0 | if( tu.mtsIdx[compID] == MTS_SKIP && !tu.cs->slice->tsResidualCodingDisabled ) |
2253 | 0 | { |
2254 | 0 | residual_codingTS( tu, compID ); |
2255 | 0 | return; |
2256 | 0 | } |
2257 | | |
2258 | | // determine sign hiding |
2259 | 0 | bool signHiding = cu.cs->slice->signDataHidingEnabled; |
2260 | | |
2261 | | // init coeff coding context |
2262 | 0 | CoeffCodingContext cctx ( tu, compID, signHiding, false, m_tplBuf ); |
2263 | 0 | const TCoeffSig* coeff = tu.getCoeffs( compID ).buf; |
2264 | | |
2265 | | // determine and set last coeff position and sig group flags |
2266 | 0 | int scanPosLast = tu.lastPos[compID]; |
2267 | 0 | std::bitset<MLS_GRP_NUM> sigGroupFlags; |
2268 | |
|
2269 | 0 | for( int subSetId = 0; subSetId <= ( scanPosLast >> cctx.log2CGSize() ); subSetId++ ) |
2270 | 0 | { |
2271 | 0 | const int scanPosStart = subSetId << cctx.log2CGSize(); |
2272 | 0 | const int scanPosEnd = scanPosStart + ( 1 << cctx.log2CGSize() ) - 1; |
2273 | |
|
2274 | 0 | for( int scanPos = scanPosEnd; scanPos >= scanPosStart; scanPos-- ) |
2275 | 0 | { |
2276 | 0 | unsigned blkPos = cctx.blockPos( scanPos ); |
2277 | |
|
2278 | 0 | if( coeff[blkPos] ) |
2279 | 0 | { |
2280 | 0 | sigGroupFlags.set( subSetId ); |
2281 | 0 | break; |
2282 | 0 | } |
2283 | 0 | } |
2284 | 0 | } |
2285 | 0 | CHECK( scanPosLast < 0, "Coefficient coding called for empty TU" ); |
2286 | 0 | cctx.setScanPosLast(scanPosLast); |
2287 | |
|
2288 | 0 | if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 ) |
2289 | 0 | { |
2290 | 0 | const int maxLfnstPos = ((tu.blocks[compID].height == 4 && tu.blocks[compID].width == 4) || (tu.blocks[compID].height == 8 && tu.blocks[compID].width == 8)) ? 7 : 15; |
2291 | 0 | cuCtx->violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos; |
2292 | 0 | } |
2293 | 0 | if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 ) |
2294 | 0 | { |
2295 | 0 | const int lfnstLastScanPosTh = isLuma( compID ) ? LFNST_LAST_SIG_LUMA : LFNST_LAST_SIG_CHROMA; |
2296 | 0 | cuCtx->lfnstLastScanPos |= cctx.scanPosLast() >= lfnstLastScanPosTh; |
2297 | 0 | } |
2298 | 0 | if (cuCtx && isLuma(compID) && tu.mtsIdx[compID] != MTS_SKIP) |
2299 | 0 | { |
2300 | 0 | cuCtx->mtsLastScanPos |= cctx.scanPosLast() >= 1; |
2301 | 0 | } |
2302 | | |
2303 | | // code last coeff position |
2304 | 0 | last_sig_coeff( cctx, tu, compID ); |
2305 | | |
2306 | | // code subblocks |
2307 | 0 | const int stateTab = ( tu.cs->slice->depQuantEnabled ? 32040 : 0 ); |
2308 | 0 | int state = 0; |
2309 | |
|
2310 | 0 | int ctxBinSampleRatio = MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT; |
2311 | 0 | cctx.remRegBins = (tu.getTbAreaAfterCoefZeroOut(compID) * ctxBinSampleRatio) >> 4; |
2312 | |
|
2313 | 0 | const bool zeroOutCheck = isLuma( compID ) && tu.cs->sps->MTS && tu.cu->sbtInfo != 0 && tu.blocks[compID].height <= 32 && tu.blocks[compID].width <= 32; |
2314 | 0 | const bool zeroOutWidth = tu.blocks[compID].width; |
2315 | 0 | const bool zeroOutHeight = tu.blocks[compID].height; |
2316 | |
|
2317 | 0 | for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--) |
2318 | 0 | { |
2319 | 0 | cctx.initSubblock( subSetId, sigGroupFlags[subSetId] ); |
2320 | |
|
2321 | 0 | if( zeroOutCheck ) |
2322 | 0 | { |
2323 | 0 | if( ( zeroOutHeight && cctx.cgPosY() >= ( 16 >> cctx.log2CGHeight() ) ) || ( zeroOutWidth && cctx.cgPosX() >= ( 16 >> cctx.log2CGWidth() ) ) ) |
2324 | 0 | { |
2325 | 0 | continue; |
2326 | 0 | } |
2327 | 0 | } |
2328 | | |
2329 | 0 | residual_coding_subblock( cctx, coeff, stateTab, state ); |
2330 | 0 | if ( cuCtx && isLuma(compID) && cctx.isSigGroup() && ( cctx.cgPosY() > 3 || cctx.cgPosX() > 3 ) ) |
2331 | 0 | { |
2332 | 0 | cuCtx->violatesMtsCoeffConstraint = true; |
2333 | 0 | } |
2334 | 0 | } |
2335 | 0 | } |
2336 | | |
2337 | | |
2338 | | void CABACWriter::ts_flag( const TransformUnit& tu, ComponentID compID ) |
2339 | 0 | { |
2340 | 0 | int tsFlag = tu.mtsIdx[compID] == MTS_SKIP ? 1 : 0; |
2341 | 0 | int ctxIdx = isLuma(compID) ? 0 : 1; |
2342 | | |
2343 | 0 | if( TU::isTSAllowed ( tu, compID ) ) |
2344 | 0 | { |
2345 | 0 | m_BinEncoder.encodeBin( tsFlag, Ctx::TransformSkipFlag(ctxIdx)); |
2346 | 0 | } |
2347 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "ts_flag() etype=%d pos=(%d,%d) mtsIdx=%d\n", COMP_Y, tu.cu->lx(), tu.cu->ly(), tsFlag ); |
2348 | 0 | } |
2349 | | |
2350 | | |
2351 | | void CABACWriter::mts_idx( const CodingUnit& cu, CUCtx* cuCtx ) |
2352 | 0 | { |
2353 | 0 | TransformUnit &tu = *cu.firstTU; |
2354 | 0 | int mtsIdx = tu.mtsIdx[COMP_Y]; |
2355 | | |
2356 | 0 | if( CU::isMTSAllowed( cu, COMP_Y ) && cuCtx && !cuCtx->violatesMtsCoeffConstraint && |
2357 | 0 | cuCtx->mtsLastScanPos && cu.lfnstIdx == 0 && mtsIdx != MTS_SKIP) |
2358 | 0 | { |
2359 | 0 | int symbol = mtsIdx != MTS_DCT2_DCT2 ? 1 : 0; |
2360 | 0 | int ctxIdx = 0; |
2361 | | |
2362 | 0 | m_BinEncoder.encodeBin( symbol, Ctx::MTSIdx(ctxIdx)); |
2363 | | |
2364 | 0 | if( symbol ) |
2365 | 0 | { |
2366 | 0 | ctxIdx = 1; |
2367 | 0 | for( int i = 0; i < 3; i++, ctxIdx++ ) |
2368 | 0 | { |
2369 | 0 | symbol = mtsIdx > i + MTS_DST7_DST7 ? 1 : 0; |
2370 | 0 | m_BinEncoder.encodeBin( symbol, Ctx::MTSIdx(ctxIdx)); |
2371 | | |
2372 | 0 | if( !symbol ) |
2373 | 0 | { |
2374 | 0 | break; |
2375 | 0 | } |
2376 | 0 | } |
2377 | 0 | } |
2378 | 0 | } |
2379 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "mts_idx() etype=%d pos=(%d,%d) mtsIdx=%d\n", COMP_Y, tu.cu->lx(), tu.cu->ly(), mtsIdx); |
2380 | 0 | } |
2381 | | |
2382 | | |
2383 | | void CABACWriter::isp_mode( const CodingUnit& cu ) |
2384 | 0 | { |
2385 | 0 | if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.multiRefIdx || !cu.cs->sps->ISP || cu.bdpcmM[CH_L] || !CU::canUseISP( cu, getFirstComponentOfChannel( cu.chType ) ) || cu.colorTransform) |
2386 | 0 | { |
2387 | 0 | CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "cu.ispMode != 0" ); |
2388 | 0 | return; |
2389 | 0 | } |
2390 | 0 | if ( cu.ispMode == NOT_INTRA_SUBPARTITIONS ) |
2391 | 0 | { |
2392 | 0 | m_BinEncoder.encodeBin( 0, Ctx::ISPMode( 0 ) ); |
2393 | 0 | } |
2394 | 0 | else |
2395 | 0 | { |
2396 | 0 | m_BinEncoder.encodeBin( 1, Ctx::ISPMode( 0 ) ); |
2397 | 0 | m_BinEncoder.encodeBin( cu.ispMode - 1, Ctx::ISPMode( 1 ) ); |
2398 | 0 | } |
2399 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "intra_subPartitions() etype=%d pos=(%d,%d) ispIdx=%d\n", cu.chType, cu.blocks[cu.chType].x, cu.blocks[cu.chType].y, (int)cu.ispMode ); |
2400 | 0 | } |
2401 | | |
2402 | | |
2403 | | void CABACWriter::residual_lfnst_mode( const CodingUnit& cu, CUCtx& cuCtx ) |
2404 | 0 | { |
2405 | 0 | int chIdx = CS::isDualITree( *cu.cs ) && cu.chType == CH_C ? 1 : 0; |
2406 | 0 | if( ( cu.ispMode && !CU::canUseLfnstWithISP( cu, cu.chType ) ) || |
2407 | 0 | (cu.cs->sps->LFNST && CU::isIntra(cu) && cu.mipFlag && !allowLfnstWithMip(cu.lumaSize())) || |
2408 | 0 | ( CU::isSepTree(cu) && cu.chType == CH_C && std::min( cu.blocks[ 1 ].width, cu.blocks[ 1 ].height ) < 4 ) |
2409 | 0 | || ( cu.blocks[ chIdx ].lumaSize().width > cu.cs->sps->getMaxTbSize() || cu.blocks[ chIdx ].lumaSize().height > cu.cs->sps->getMaxTbSize() ) |
2410 | 0 | ) |
2411 | 0 | { |
2412 | 0 | return; |
2413 | 0 | } |
2414 | | |
2415 | 0 | if( cu.cs->sps->LFNST && CU::isIntra( cu ) ) |
2416 | 0 | { |
2417 | 0 | const bool lumaFlag = CU::isSepTree(cu) ? ( isLuma( cu.chType ) ? true : false ) : true; |
2418 | 0 | const bool chromaFlag = CU::isSepTree(cu) ? ( isChroma( cu.chType ) ? true : false ) : true; |
2419 | 0 | bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CH_L] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CH_C] ); |
2420 | |
|
2421 | 0 | bool isTrSkip = false; |
2422 | |
|
2423 | 0 | for( const auto& currTU : cTUTraverser( cu.firstTU, cu.lastTU->next ) ) |
2424 | 0 | { |
2425 | 0 | const uint32_t numValidComp = getNumberValidComponents(cu.chromaFormat); |
2426 | 0 | for (uint32_t compID = COMP_Y; compID < numValidComp; compID++) |
2427 | 0 | { |
2428 | 0 | if (currTU.blocks[compID].valid() && TU::getCbf(currTU, (ComponentID)compID) && currTU.mtsIdx[compID] == MTS_SKIP) |
2429 | 0 | { |
2430 | 0 | isTrSkip = true; |
2431 | 0 | break; |
2432 | 0 | } |
2433 | 0 | } |
2434 | 0 | } |
2435 | |
|
2436 | 0 | if( (!cuCtx.lfnstLastScanPos && !cu.ispMode) || nonZeroCoeffNonTsCorner8x8 || isTrSkip ) |
2437 | 0 | { |
2438 | 0 | return; |
2439 | 0 | } |
2440 | 0 | } |
2441 | 0 | else |
2442 | 0 | { |
2443 | 0 | return; |
2444 | 0 | } |
2445 | | |
2446 | 0 | unsigned cctx = 0; |
2447 | 0 | if ( CU::isSepTree(cu) ) cctx++; |
2448 | |
|
2449 | 0 | const uint32_t idxLFNST = cu.lfnstIdx; |
2450 | 0 | assert( idxLFNST < 3 ); |
2451 | 0 | m_BinEncoder.encodeBin( idxLFNST ? 1 : 0, Ctx::LFNSTIdx( cctx ) ); |
2452 | |
|
2453 | 0 | if( idxLFNST ) |
2454 | 0 | { |
2455 | 0 | m_BinEncoder.encodeBin( (idxLFNST - 1) ? 1 : 0, Ctx::LFNSTIdx(2)); |
2456 | 0 | } |
2457 | |
|
2458 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "residual_lfnst_mode() etype=%d pos=(%d,%d) mode=%d\n", COMP_Y, cu.lx(), cu.ly(), ( int ) cu.lfnstIdx ); |
2459 | 0 | } |
2460 | | |
2461 | | |
2462 | | void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit& tu, ComponentID compID ) |
2463 | 0 | { |
2464 | 0 | unsigned blkPos = cctx.blockPos( cctx.scanPosLast() ); |
2465 | 0 | unsigned posX, posY; |
2466 | 0 | { |
2467 | 0 | posY = blkPos / cctx.width(); |
2468 | 0 | posX = blkPos - ( posY * cctx.width() ); |
2469 | 0 | } |
2470 | |
|
2471 | 0 | unsigned CtxLast; |
2472 | 0 | unsigned GroupIdxX = g_uiGroupIdx[ posX ]; |
2473 | 0 | unsigned GroupIdxY = g_uiGroupIdx[ posY ]; |
2474 | |
|
2475 | 0 | unsigned maxLastPosX = cctx.maxLastPosX(); |
2476 | 0 | unsigned maxLastPosY = cctx.maxLastPosY(); |
2477 | |
|
2478 | 0 | if( tu.cs->sps->MTS && tu.cu->sbtInfo != 0 && tu.blocks[ compID ].width <= 32 && tu.blocks[ compID ].height <= 32 && compID == COMP_Y ) |
2479 | 0 | { |
2480 | 0 | maxLastPosX = ( tu.blocks[compID].width == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosX; |
2481 | 0 | maxLastPosY = ( tu.blocks[compID].height == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosY; |
2482 | 0 | } |
2483 | |
|
2484 | 0 | for( CtxLast = 0; CtxLast < GroupIdxX; CtxLast++ ) |
2485 | 0 | { |
2486 | 0 | m_BinEncoder.encodeBin( 1, cctx.lastXCtxId( CtxLast ) ); |
2487 | 0 | } |
2488 | 0 | if( GroupIdxX < maxLastPosX ) |
2489 | 0 | { |
2490 | 0 | m_BinEncoder.encodeBin( 0, cctx.lastXCtxId( CtxLast ) ); |
2491 | 0 | } |
2492 | 0 | for( CtxLast = 0; CtxLast < GroupIdxY; CtxLast++ ) |
2493 | 0 | { |
2494 | 0 | m_BinEncoder.encodeBin( 1, cctx.lastYCtxId( CtxLast ) ); |
2495 | 0 | } |
2496 | 0 | if( GroupIdxY < maxLastPosY ) |
2497 | 0 | { |
2498 | 0 | m_BinEncoder.encodeBin( 0, cctx.lastYCtxId( CtxLast ) ); |
2499 | 0 | } |
2500 | 0 | if( GroupIdxX > 3 ) |
2501 | 0 | { |
2502 | 0 | posX -= g_uiMinInGroup[ GroupIdxX ]; |
2503 | 0 | for (int i = ( ( GroupIdxX - 2 ) >> 1 ) - 1 ; i >= 0; i-- ) |
2504 | 0 | { |
2505 | 0 | m_BinEncoder.encodeBinEP( ( posX >> i ) & 1 ); |
2506 | 0 | } |
2507 | 0 | } |
2508 | 0 | if( GroupIdxY > 3 ) |
2509 | 0 | { |
2510 | 0 | posY -= g_uiMinInGroup[ GroupIdxY ]; |
2511 | 0 | for ( int i = ( ( GroupIdxY - 2 ) >> 1 ) - 1 ; i >= 0; i-- ) |
2512 | 0 | { |
2513 | 0 | m_BinEncoder.encodeBinEP( ( posY >> i ) & 1 ); |
2514 | 0 | } |
2515 | 0 | } |
2516 | 0 | } |
2517 | | |
2518 | | |
2519 | | void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoeffSig* coeff, const int stateTransTable, int& state ) |
2520 | 0 | { |
2521 | | //===== init ===== |
2522 | 0 | const int minSubPos = cctx.minSubPos(); |
2523 | 0 | const bool isLast = cctx.isLast(); |
2524 | 0 | int firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() ); |
2525 | 0 | int nextSigPos = firstSigPos; |
2526 | | |
2527 | | //===== encode significant_coeffgroup_flag ===== |
2528 | 0 | if( !isLast && cctx.isNotFirst() ) |
2529 | 0 | { |
2530 | 0 | if( cctx.isSigGroup() ) |
2531 | 0 | { |
2532 | 0 | m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId() ); |
2533 | 0 | } |
2534 | 0 | else |
2535 | 0 | { |
2536 | 0 | m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId() ); |
2537 | 0 | return; |
2538 | 0 | } |
2539 | 0 | } |
2540 | | |
2541 | | //===== encode absolute values ===== |
2542 | 0 | const int inferSigPos = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos; |
2543 | 0 | int firstNZPos = nextSigPos; |
2544 | 0 | int lastNZPos = -1; |
2545 | 0 | int remAbsLevel = -1; |
2546 | 0 | int numNonZero = 0; |
2547 | 0 | unsigned signPattern = 0; |
2548 | 0 | int remRegBins = cctx.remRegBins; |
2549 | 0 | int firstPosMode2 = minSubPos - 1; |
2550 | |
|
2551 | 0 | for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- ) |
2552 | 0 | { |
2553 | 0 | const int blkPos = cctx.blockPos( nextSigPos ); |
2554 | 0 | TCoeff Coeff = coeff[ blkPos ]; |
2555 | 0 | unsigned sigFlag = ( Coeff != 0 ); |
2556 | 0 | if( numNonZero || nextSigPos != inferSigPos ) |
2557 | 0 | { |
2558 | 0 | const unsigned sigCtxId = cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); |
2559 | 0 | m_BinEncoder.encodeBin( sigFlag, sigCtxId ); |
2560 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId ); |
2561 | 0 | remRegBins--; |
2562 | 0 | } |
2563 | 0 | else if( nextSigPos != cctx.scanPosLast() ) |
2564 | 0 | { |
2565 | 0 | cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); // required for setting variables that are needed for gtx/par context selection |
2566 | 0 | } |
2567 | |
|
2568 | 0 | if( sigFlag ) |
2569 | 0 | { |
2570 | 0 | uint8_t ctxOff = cctx.ctxOffsetAbs(); |
2571 | 0 | numNonZero++; |
2572 | 0 | firstNZPos = nextSigPos; |
2573 | 0 | lastNZPos = std::max<int>( lastNZPos, nextSigPos ); |
2574 | 0 | int absLevel= abs( Coeff ); |
2575 | 0 | remAbsLevel = absLevel - 1; |
2576 | |
|
2577 | 0 | if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1; |
2578 | 0 | if( Coeff < 0 ) signPattern++; |
2579 | |
|
2580 | 0 | unsigned gt1 = !!remAbsLevel; |
2581 | 0 | m_BinEncoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) ); |
2582 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) ); |
2583 | 0 | remRegBins--; |
2584 | |
|
2585 | 0 | if( gt1 ) |
2586 | 0 | { |
2587 | 0 | remAbsLevel -= 1; |
2588 | 0 | m_BinEncoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) ); |
2589 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) ); |
2590 | 0 | remAbsLevel >>= 1; |
2591 | |
|
2592 | 0 | remRegBins--; |
2593 | 0 | unsigned gt2 = !!remAbsLevel; |
2594 | 0 | m_BinEncoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff)); |
2595 | 0 | DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff)); |
2596 | 0 | remRegBins--; |
2597 | 0 | } |
2598 | |
|
2599 | 0 | cctx.absVal1stPass( nextSigPos, std::min<TCoeff>( 4 + ( absLevel & 1 ), absLevel ) ); |
2600 | 0 | } |
2601 | |
|
2602 | 0 | state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3; |
2603 | 0 | } |
2604 | 0 | firstPosMode2 = nextSigPos; |
2605 | 0 | cctx.remRegBins = remRegBins; |
2606 | | |
2607 | | |
2608 | | //===== 2nd PASS: Go-rice codes ===== |
2609 | 0 | for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- ) |
2610 | 0 | { |
2611 | 0 | unsigned absLevel = abs( coeff[cctx.blockPos( scanPos )] ); |
2612 | |
|
2613 | 0 | if( absLevel >= 4 ) |
2614 | 0 | { |
2615 | 0 | int sumAll = cctx.templateAbsSum( scanPos, coeff, 4 ); |
2616 | 0 | unsigned ricePar = g_auiGoRiceParsCoeff[sumAll]; |
2617 | 0 | unsigned rem = ( absLevel - 4 ) >> 1; |
2618 | 0 | m_BinEncoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() ); |
2619 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar ); |
2620 | 0 | } |
2621 | 0 | } |
2622 | | |
2623 | | //===== coeff bypass ==== |
2624 | 0 | for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- ) |
2625 | 0 | { |
2626 | 0 | TCoeff Coeff = coeff[ cctx.blockPos( scanPos ) ]; |
2627 | 0 | unsigned absLevel = abs( Coeff ); |
2628 | 0 | int sumAll = cctx.templateAbsSum(scanPos, coeff, 0); |
2629 | 0 | int rice = g_auiGoRiceParsCoeff[sumAll]; |
2630 | 0 | int pos0 = g_auiGoRicePosCoeff0(state, rice); |
2631 | 0 | unsigned rem = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel ); |
2632 | 0 | m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() ); |
2633 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice ); |
2634 | 0 | state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3; |
2635 | 0 | if( absLevel ) |
2636 | 0 | { |
2637 | 0 | numNonZero++; |
2638 | 0 | firstNZPos = scanPos; |
2639 | 0 | lastNZPos = std::max<int>( lastNZPos, scanPos ); |
2640 | 0 | signPattern <<= 1; |
2641 | 0 | if( Coeff < 0 ) signPattern++; |
2642 | 0 | } |
2643 | 0 | } |
2644 | | |
2645 | | //===== encode sign's ===== |
2646 | 0 | unsigned numSigns = numNonZero; |
2647 | 0 | if( cctx.hideSign( firstNZPos, lastNZPos ) ) |
2648 | 0 | { |
2649 | 0 | numSigns --; |
2650 | 0 | signPattern >>= 1; |
2651 | 0 | } |
2652 | 0 | m_BinEncoder.encodeBinsEP( signPattern, numSigns ); |
2653 | 0 | } |
2654 | | |
2655 | | |
2656 | | void CABACWriter::residual_codingTS( const TransformUnit& tu, ComponentID compID ) |
2657 | 0 | { |
2658 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "residual_codingTS() etype=%d pos=(%d,%d) size=%dx%d\n", tu.blocks[compID].compID, tu.blocks[compID].x, tu.blocks[compID].y, tu.blocks[compID].width, tu.blocks[compID].height ); |
2659 | | |
2660 | | // init coeff coding context |
2661 | 0 | CoeffCodingContext cctx ( tu, compID, false, tu.cu->bdpcmM[toChannelType(compID)] ); |
2662 | 0 | const TCoeffSig* coeff = tu.getCoeffs( compID ).buf; |
2663 | 0 | int maxCtxBins = (cctx.maxNumCoeff() * 7) >> 2; |
2664 | 0 | cctx.remRegBins = maxCtxBins; |
2665 | | |
2666 | | // determine and set last coeff position and sig group flags |
2667 | 0 | std::bitset<MLS_GRP_NUM> sigGroupFlags; |
2668 | 0 | for( int scanPos = 0; scanPos < cctx.maxNumCoeff(); scanPos++) |
2669 | 0 | { |
2670 | 0 | unsigned blkPos = cctx.blockPos( scanPos ); |
2671 | 0 | if( coeff[blkPos] ) |
2672 | 0 | { |
2673 | 0 | sigGroupFlags.set( scanPos >> cctx.log2CGSize() ); |
2674 | 0 | } |
2675 | 0 | } |
2676 | | |
2677 | | // code subblocks |
2678 | 0 | for( int subSetId = 0; subSetId <= ( cctx.maxNumCoeff() - 1 ) >> cctx.log2CGSize(); subSetId++ ) |
2679 | 0 | { |
2680 | 0 | cctx.initSubblock ( subSetId, sigGroupFlags[subSetId] ); |
2681 | 0 | residual_coding_subblockTS( cctx, coeff ); |
2682 | 0 | } |
2683 | 0 | } |
2684 | | |
2685 | | |
2686 | | void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TCoeffSig* coeff ) |
2687 | 0 | { |
2688 | | //===== init ===== |
2689 | 0 | const int minSubPos = cctx.maxSubPos(); |
2690 | 0 | int firstSigPos = cctx.minSubPos(); |
2691 | 0 | int nextSigPos = firstSigPos; |
2692 | | |
2693 | | //===== encode significant_coeffgroup_flag ===== |
2694 | 0 | if( !cctx.isLastSubSet() || !cctx.only1stSigGroup() ) |
2695 | 0 | { |
2696 | 0 | if( cctx.isSigGroup() ) |
2697 | 0 | { |
2698 | 0 | m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId( true ) ); |
2699 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 1, cctx.sigGroupCtxId() ); |
2700 | 0 | } |
2701 | 0 | else |
2702 | 0 | { |
2703 | 0 | m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId( true ) ); |
2704 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 0, cctx.sigGroupCtxId() ); |
2705 | 0 | return; |
2706 | 0 | } |
2707 | 0 | } |
2708 | | |
2709 | | //===== encode absolute values ===== |
2710 | 0 | const int inferSigPos = minSubPos; |
2711 | 0 | int remAbsLevel = -1; |
2712 | 0 | int numNonZero = 0; |
2713 | |
|
2714 | 0 | int rightPixel, belowPixel, modAbsCoeff; |
2715 | |
|
2716 | 0 | int lastScanPosPass1 = -1; |
2717 | 0 | int lastScanPosPass2 = -1; |
2718 | 0 | for (; nextSigPos <= minSubPos && cctx.remRegBins >= 4; nextSigPos++) |
2719 | 0 | { |
2720 | 0 | TCoeff Coeff = coeff[ cctx.blockPos( nextSigPos ) ]; |
2721 | 0 | unsigned sigFlag = ( Coeff != 0 ); |
2722 | 0 | if( numNonZero || nextSigPos != inferSigPos ) |
2723 | 0 | { |
2724 | 0 | const unsigned sigCtxId = cctx.sigCtxIdAbsTS( nextSigPos, coeff ); |
2725 | 0 | m_BinEncoder.encodeBin( sigFlag, sigCtxId ); |
2726 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId ); |
2727 | 0 | cctx.remRegBins--; |
2728 | 0 | } |
2729 | |
|
2730 | 0 | if( sigFlag ) |
2731 | 0 | { |
2732 | | //===== encode sign's ===== |
2733 | 0 | int sign = Coeff < 0; |
2734 | 0 | const unsigned signCtxId = cctx.signCtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm()); |
2735 | 0 | m_BinEncoder.encodeBin(sign, signCtxId); |
2736 | 0 | cctx.remRegBins--; |
2737 | 0 | numNonZero++; |
2738 | 0 | cctx.neighTS(rightPixel, belowPixel, nextSigPos, coeff); |
2739 | 0 | modAbsCoeff = cctx.deriveModCoeff(rightPixel, belowPixel, abs(Coeff), cctx.bdpcm()); |
2740 | 0 | remAbsLevel = modAbsCoeff - 1; |
2741 | |
|
2742 | 0 | unsigned gt1 = !!remAbsLevel; |
2743 | 0 | const unsigned gt1CtxId = cctx.lrg1CtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm()); |
2744 | 0 | m_BinEncoder.encodeBin(gt1, gt1CtxId); |
2745 | 0 | DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_gt1_flag() bin=%d ctx=%d\n", gt1, gt1CtxId); |
2746 | 0 | cctx.remRegBins--; |
2747 | |
|
2748 | 0 | if( gt1 ) |
2749 | 0 | { |
2750 | 0 | remAbsLevel -= 1; |
2751 | 0 | m_BinEncoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbsTS() ); |
2752 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbsTS() ); |
2753 | 0 | cctx.remRegBins--; |
2754 | 0 | } |
2755 | 0 | } |
2756 | 0 | lastScanPosPass1 = nextSigPos; |
2757 | 0 | } |
2758 | |
|
2759 | 0 | int cutoffVal = 2; |
2760 | 0 | int numGtBins = 4; |
2761 | |
|
2762 | 0 | for (int scanPos = firstSigPos; scanPos <= minSubPos && cctx.remRegBins >= 4; scanPos++) |
2763 | 0 | { |
2764 | 0 | unsigned absLevel; |
2765 | 0 | cctx.neighTS(rightPixel, belowPixel, scanPos, coeff); |
2766 | 0 | absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm()); |
2767 | 0 | cutoffVal = 2; |
2768 | 0 | for (int i = 0; i < numGtBins; i++) |
2769 | 0 | { |
2770 | 0 | if (absLevel >= cutoffVal) |
2771 | 0 | { |
2772 | 0 | unsigned gt2 = (absLevel >= (cutoffVal + 2)); |
2773 | 0 | m_BinEncoder.encodeBin(gt2, cctx.greaterXCtxIdAbsTS(cutoffVal >> 1)); |
2774 | 0 | DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_gt%d_flag() bin=%d ctx=%d sp=%d coeff=%d\n", i, gt2, cctx.greaterXCtxIdAbsTS(cutoffVal >> 1), scanPos, std::min<int>(absLevel, cutoffVal + 2)); |
2775 | 0 | cctx.remRegBins--; |
2776 | 0 | } |
2777 | 0 | cutoffVal += 2; |
2778 | 0 | } |
2779 | 0 | lastScanPosPass2 = scanPos; |
2780 | 0 | } |
2781 | | |
2782 | | //===== coeff bypass ==== |
2783 | 0 | for( int scanPos = firstSigPos; scanPos <= minSubPos; scanPos++ ) |
2784 | 0 | { |
2785 | 0 | unsigned absLevel; |
2786 | 0 | cctx.neighTS(rightPixel, belowPixel, scanPos, coeff); |
2787 | 0 | cutoffVal = (scanPos <= lastScanPosPass2 ? 10 : (scanPos <= lastScanPosPass1 ? 2 : 0)); |
2788 | 0 | absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm()||!cutoffVal); |
2789 | 0 | if( absLevel >= cutoffVal ) |
2790 | 0 | { |
2791 | | //int rice = cctx.templateAbsSumTS( scanPos, coeff ); |
2792 | 0 | int rice = 1; |
2793 | 0 | unsigned rem = scanPos <= lastScanPosPass1 ? (absLevel - cutoffVal) >> 1 : absLevel; |
2794 | 0 | m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() ); |
2795 | 0 | DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_rem_val() bin=%d ctx=%d sp=%d\n", rem, rice, scanPos ); |
2796 | |
|
2797 | 0 | if (absLevel && scanPos > lastScanPosPass1) |
2798 | 0 | { |
2799 | 0 | int sign = coeff[cctx.blockPos(scanPos)] < 0; |
2800 | 0 | m_BinEncoder.encodeBinEP(sign); |
2801 | 0 | } |
2802 | 0 | } |
2803 | 0 | } |
2804 | 0 | } |
2805 | | |
2806 | | |
2807 | | //================================================================================ |
2808 | | // helper functions |
2809 | | //-------------------------------------------------------------------------------- |
2810 | | // void unary_max_symbol ( symbol, ctxId0, ctxIdN, maxSymbol ) |
2811 | | // void unary_max_eqprob ( symbol, maxSymbol ) |
2812 | | // void exp_golomb_eqprob ( symbol, count ) |
2813 | | //================================================================================ |
2814 | | |
2815 | | void CABACWriter::unary_max_symbol( unsigned symbol, unsigned ctxId0, unsigned ctxIdN, unsigned maxSymbol ) |
2816 | 0 | { |
2817 | 0 | CHECK( symbol > maxSymbol, "symbol > maxSymbol" ); |
2818 | 0 | const unsigned totalBinsToWrite = std::min( symbol + 1, maxSymbol ); |
2819 | 0 | for( unsigned binsWritten = 0; binsWritten < totalBinsToWrite; ++binsWritten ) |
2820 | 0 | { |
2821 | 0 | const unsigned nextBin = symbol > binsWritten; |
2822 | 0 | m_BinEncoder.encodeBin( nextBin, binsWritten == 0 ? ctxId0 : ctxIdN ); |
2823 | 0 | } |
2824 | 0 | } |
2825 | | |
2826 | | |
2827 | | void CABACWriter::unary_max_eqprob( unsigned symbol, unsigned maxSymbol ) |
2828 | 0 | { |
2829 | 0 | if( maxSymbol == 0 ) |
2830 | 0 | { |
2831 | 0 | return; |
2832 | 0 | } |
2833 | 0 | bool codeLast = ( maxSymbol > symbol ); |
2834 | 0 | unsigned bins = 0; |
2835 | 0 | unsigned numBins = 0; |
2836 | 0 | while( symbol-- ) |
2837 | 0 | { |
2838 | 0 | bins <<= 1; |
2839 | 0 | bins ++; |
2840 | 0 | numBins++; |
2841 | 0 | } |
2842 | 0 | if( codeLast ) |
2843 | 0 | { |
2844 | 0 | bins <<= 1; |
2845 | 0 | numBins++; |
2846 | 0 | } |
2847 | 0 | CHECK(!( numBins <= 32 ), "Unspecified error"); |
2848 | 0 | m_BinEncoder.encodeBinsEP( bins, numBins ); |
2849 | 0 | } |
2850 | | |
2851 | | |
2852 | | void CABACWriter::exp_golomb_eqprob( unsigned symbol, unsigned count ) |
2853 | 0 | { |
2854 | 0 | unsigned bins = 0; |
2855 | 0 | unsigned numBins = 0; |
2856 | 0 | while( symbol >= (unsigned)(1<<count) ) |
2857 | 0 | { |
2858 | 0 | bins <<= 1; |
2859 | 0 | bins++; |
2860 | 0 | numBins++; |
2861 | 0 | symbol -= 1 << count; |
2862 | 0 | count++; |
2863 | 0 | } |
2864 | 0 | bins <<= 1; |
2865 | 0 | numBins++; |
2866 | 0 | bins = (bins << count) | symbol; |
2867 | 0 | numBins += count; |
2868 | 0 | CHECK(!( numBins <= 32 ), "Unspecified error"); |
2869 | 0 | m_BinEncoder.encodeBinsEP( bins, numBins ); |
2870 | 0 | } |
2871 | | |
2872 | | |
2873 | | void CABACWriter::codeAlfCtuEnabled( CodingStructure& cs, ChannelType channel, AlfParam* alfParam, const int numCtus ) |
2874 | 0 | { |
2875 | 0 | if( isLuma( channel ) ) |
2876 | 0 | { |
2877 | 0 | if (alfParam->alfEnabled[COMP_Y]) |
2878 | 0 | codeAlfCtuEnabled( cs, COMP_Y, alfParam, numCtus ); |
2879 | 0 | } |
2880 | 0 | else |
2881 | 0 | { |
2882 | 0 | if (alfParam->alfEnabled[COMP_Cb]) |
2883 | 0 | codeAlfCtuEnabled( cs, COMP_Cb, alfParam, numCtus ); |
2884 | 0 | if (alfParam->alfEnabled[COMP_Cr]) |
2885 | 0 | codeAlfCtuEnabled( cs, COMP_Cr, alfParam, numCtus ); |
2886 | 0 | } |
2887 | 0 | } |
2888 | | |
2889 | | |
2890 | | void CABACWriter::codeAlfCtuEnabled( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus ) |
2891 | 0 | { |
2892 | 0 | for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ ) |
2893 | 0 | { |
2894 | 0 | codeAlfCtuEnabledFlag( cs, ctuIdx, compID ); |
2895 | 0 | } |
2896 | 0 | } |
2897 | | |
2898 | | |
2899 | | void CABACWriter::codeAlfCtuEnabledFlag( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx) |
2900 | 0 | { |
2901 | 0 | CHECKD( !cs.sps->alfEnabled, "ALF is disabled in SPS" ); |
2902 | |
|
2903 | 0 | const PreCalcValues& pcv = *cs.pcv; |
2904 | 0 | int frame_width_in_ctus = pcv.widthInCtus; |
2905 | 0 | int ry = ctuRsAddr / frame_width_in_ctus; |
2906 | 0 | int rx = ctuRsAddr - ry * frame_width_in_ctus; |
2907 | 0 | const Position pos( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize ); |
2908 | 0 | const uint32_t curSliceIdx = cs.slice->independentSliceIdx; |
2909 | 0 | const uint32_t curTileIdx = cs.pps->getTileIdx( pos ); |
2910 | 0 | bool leftAvail = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0 ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false; |
2911 | 0 | bool aboveAvail = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false; |
2912 | |
|
2913 | 0 | int leftCTUAddr = leftAvail ? ctuRsAddr - 1 : -1; |
2914 | 0 | int aboveCTUAddr = aboveAvail ? ctuRsAddr - frame_width_in_ctus : -1; |
2915 | |
|
2916 | 0 | const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data(); |
2917 | 0 | int ctx = 0; |
2918 | 0 | ctx += leftCTUAddr > -1 ? ( ctbAlfFlag[leftCTUAddr] ? 1 : 0 ) : 0; |
2919 | 0 | ctx += aboveCTUAddr > -1 ? ( ctbAlfFlag[aboveCTUAddr] ? 1 : 0 ) : 0; |
2920 | 0 | m_BinEncoder.encodeBin( ctbAlfFlag[ctuRsAddr], Ctx::ctbAlfFlag( compIdx * 3 + ctx ) ); |
2921 | 0 | } |
2922 | | |
2923 | | |
2924 | | void CABACWriter::codeCcAlfFilterControlIdc(uint8_t idcVal, CodingStructure &cs, const ComponentID compID, |
2925 | | const int curIdx, const uint8_t *filterControlIdc, Position lumaPos, |
2926 | | const int filterCount) |
2927 | 0 | { |
2928 | 0 | CHECK(idcVal > filterCount, "Filter index is too large"); |
2929 | |
|
2930 | 0 | const uint32_t curSliceIdx = cs.slice->independentSliceIdx; |
2931 | 0 | const uint32_t curTileIdx = cs.pps->getTileIdx( lumaPos ); |
2932 | 0 | Position leftLumaPos = lumaPos.offset(-(int)cs.pcv->maxCUSize, 0); |
2933 | 0 | Position aboveLumaPos = lumaPos.offset(0, -(int)cs.pcv->maxCUSize); |
2934 | 0 | bool leftAvail = cs.getCURestricted( leftLumaPos, lumaPos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false; |
2935 | 0 | bool aboveAvail = cs.getCURestricted( aboveLumaPos, lumaPos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false; |
2936 | 0 | int ctxt = 0; |
2937 | |
|
2938 | 0 | if (leftAvail) |
2939 | 0 | { |
2940 | 0 | ctxt += ( filterControlIdc[curIdx - 1]) ? 1 : 0; |
2941 | 0 | } |
2942 | 0 | if (aboveAvail) |
2943 | 0 | { |
2944 | 0 | ctxt += (filterControlIdc[curIdx - cs.pcv->widthInCtus]) ? 1 : 0; |
2945 | 0 | } |
2946 | 0 | ctxt += ( compID == COMP_Cr ) ? 3 : 0; |
2947 | |
|
2948 | 0 | m_BinEncoder.encodeBin( ( idcVal == 0 ) ? 0 : 1, Ctx::CcAlfFilterControlFlag( ctxt ) ); // ON/OFF flag is context coded |
2949 | 0 | if ( idcVal > 0 ) |
2950 | 0 | { |
2951 | 0 | int val = (idcVal - 1); |
2952 | 0 | while ( val ) |
2953 | 0 | { |
2954 | 0 | m_BinEncoder.encodeBinEP( 1 ); |
2955 | 0 | val--; |
2956 | 0 | } |
2957 | 0 | if ( idcVal < filterCount ) |
2958 | 0 | { |
2959 | 0 | m_BinEncoder.encodeBinEP( 0 ); |
2960 | 0 | } |
2961 | 0 | } |
2962 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "ccAlfFilterControlIdc() compID=%d pos=(%d,%d) ctxt=%d, filterCount=%d, idcVal=%d\n", compID, lumaPos.x, lumaPos.y, ctxt, filterCount, idcVal ); |
2963 | 0 | } |
2964 | | |
2965 | | |
2966 | | void CABACWriter::mip_flag( const CodingUnit& cu ) |
2967 | 0 | { |
2968 | 0 | if( !cu.Y().valid() ) |
2969 | 0 | { |
2970 | 0 | return; |
2971 | 0 | } |
2972 | 0 | if( !cu.cs->sps->MIP ) |
2973 | 0 | { |
2974 | 0 | return; |
2975 | 0 | } |
2976 | | |
2977 | 0 | unsigned ctxId = DeriveCtx::CtxMipFlag( cu ); |
2978 | 0 | m_BinEncoder.encodeBin( cu.mipFlag, Ctx::MipFlag( ctxId ) ); |
2979 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "mip_flag() pos=(%d,%d) mode=%d\n", cu.lumaPos().x, cu.lumaPos().y, cu.mipFlag ? 1 : 0 ); |
2980 | 0 | } |
2981 | | |
2982 | | |
2983 | | void CABACWriter::mip_pred_modes( const CodingUnit& cu ) |
2984 | 0 | { |
2985 | 0 | if( !cu.Y().valid() ) |
2986 | 0 | { |
2987 | 0 | return; |
2988 | 0 | } |
2989 | | |
2990 | 0 | mip_pred_mode( cu ); |
2991 | 0 | } |
2992 | | |
2993 | | |
2994 | | void CABACWriter::mip_pred_mode( const CodingUnit& cu ) |
2995 | 0 | { |
2996 | 0 | m_BinEncoder.encodeBinEP( (cu.mipTransposedFlag ? 1 : 0) ); |
2997 | |
|
2998 | 0 | const int numModes = getNumModesMip( cu.Y() ); |
2999 | 0 | CHECKD( cu.intraDir[CH_L] < 0 || cu.intraDir[CH_L] >= numModes, "Invalid MIP mode" ); |
3000 | 0 | xWriteTruncBinCode( cu.intraDir[CH_L], numModes ); |
3001 | |
|
3002 | 0 | DTRACE( g_trace_ctx, D_SYNTAX, "mip_pred_mode() pos=(%d,%d) mode=%d transposed=%d\n", cu.lumaPos().x, cu.lumaPos().y, cu.intraDir[CH_L], cu.mipTransposedFlag ? 1 : 0 ); |
3003 | 0 | } |
3004 | | |
3005 | | |
3006 | | void CABACWriter::codeAlfCtuFilterIndex(CodingStructure& cs, uint32_t ctuRsAddr) |
3007 | 0 | { |
3008 | 0 | const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ COMP_Y ].data(); |
3009 | 0 | if (!ctbAlfFlag[ctuRsAddr]) |
3010 | 0 | { |
3011 | 0 | return; |
3012 | 0 | } |
3013 | | |
3014 | 0 | const short* alfCtbFilterIndex = cs.slice->pic->m_alfCtbFilterIndex.data(); |
3015 | 0 | const unsigned filterSetIdx = alfCtbFilterIndex[ctuRsAddr]; |
3016 | 0 | unsigned numAps = cs.slice->numAps; |
3017 | 0 | unsigned numAvailableFiltSets = numAps + NUM_FIXED_FILTER_SETS; |
3018 | 0 | if (numAvailableFiltSets > NUM_FIXED_FILTER_SETS) |
3019 | 0 | { |
3020 | 0 | int useTemporalFilt = (filterSetIdx >= NUM_FIXED_FILTER_SETS) ? 1 : 0; |
3021 | 0 | m_BinEncoder.encodeBin(useTemporalFilt, Ctx::AlfUseTemporalFilt()); |
3022 | 0 | if (useTemporalFilt) |
3023 | 0 | { |
3024 | 0 | CHECK((filterSetIdx - NUM_FIXED_FILTER_SETS) >= (numAvailableFiltSets - NUM_FIXED_FILTER_SETS), "temporal non-latest set"); |
3025 | 0 | if (numAps > 1) |
3026 | 0 | { |
3027 | 0 | xWriteTruncBinCode(filterSetIdx - NUM_FIXED_FILTER_SETS, numAvailableFiltSets - NUM_FIXED_FILTER_SETS); |
3028 | 0 | } |
3029 | 0 | } |
3030 | 0 | else |
3031 | 0 | { |
3032 | 0 | CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set larger than temporal"); |
3033 | 0 | xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS); |
3034 | 0 | } |
3035 | 0 | } |
3036 | 0 | else |
3037 | 0 | { |
3038 | 0 | CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set numavail < num_fixed"); |
3039 | 0 | xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS); |
3040 | 0 | } |
3041 | 0 | } |
3042 | | |
3043 | | |
3044 | | void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ChannelType channel, AlfParam* alfParam, const int numCtus ) |
3045 | 0 | { |
3046 | 0 | if( isChroma( channel ) ) |
3047 | 0 | { |
3048 | 0 | if (alfParam->alfEnabled[COMP_Cb]) |
3049 | 0 | codeAlfCtuAlternatives( cs, COMP_Cb, alfParam, numCtus ); |
3050 | 0 | if (alfParam->alfEnabled[COMP_Cr]) |
3051 | 0 | codeAlfCtuAlternatives( cs, COMP_Cr, alfParam, numCtus ); |
3052 | 0 | } |
3053 | 0 | } |
3054 | | |
3055 | | |
3056 | | void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus) |
3057 | 0 | { |
3058 | 0 | if( compID == COMP_Y ) |
3059 | 0 | return; |
3060 | 0 | const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compID ].data(); |
3061 | |
|
3062 | 0 | for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ ) |
3063 | 0 | { |
3064 | 0 | if( ctbAlfFlag[ctuIdx] ) |
3065 | 0 | { |
3066 | 0 | codeAlfCtuAlternative( cs, ctuIdx, compID, alfParam ); |
3067 | 0 | } |
3068 | 0 | } |
3069 | 0 | } |
3070 | | |
3071 | | |
3072 | | void CABACWriter::codeAlfCtuAlternative( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx, const AlfParam* alfParam) |
3073 | 0 | { |
3074 | 0 | if( compIdx == COMP_Y ) |
3075 | 0 | return; |
3076 | | |
3077 | 0 | { |
3078 | 0 | const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data(); |
3079 | |
|
3080 | 0 | if( ctbAlfFlag[ctuRsAddr] ) |
3081 | 0 | { |
3082 | 0 | const int numAlts = alfParam->numAlternativesChroma; |
3083 | 0 | const uint8_t* ctbAlfAlternative = cs.slice->pic->m_alfCtuAlternative[compIdx].data(); |
3084 | 0 | unsigned numOnes = ctbAlfAlternative[ctuRsAddr]; |
3085 | 0 | assert( ctbAlfAlternative[ctuRsAddr] < numAlts ); |
3086 | 0 | for( int i = 0; i < numOnes; ++i ) |
3087 | 0 | m_BinEncoder.encodeBin( 1, Ctx::ctbAlfAlternative( compIdx-1 ) ); |
3088 | 0 | if( numOnes < numAlts-1 ) |
3089 | 0 | m_BinEncoder.encodeBin( 0, Ctx::ctbAlfAlternative( compIdx-1 ) ); |
3090 | 0 | } |
3091 | 0 | } |
3092 | 0 | } |
3093 | | |
3094 | | } // namespace vvenc |
3095 | | |
3096 | | //! \} |
3097 | | |