/src/vvdec/source/Lib/CommonLib/ContextModelling.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) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC 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 | | /** \file ContextModelling.cpp |
44 | | \brief Classes providing probability descriptions and contexts |
45 | | */ |
46 | | |
47 | | #include "ContextModelling.h" |
48 | | #include "UnitTools.h" |
49 | | #include "CodingStructure.h" |
50 | | #include "Picture.h" |
51 | | |
52 | | namespace vvdec |
53 | | { |
54 | | |
55 | | static const int prefix_ctx[8] = { 0, 0, 0, 3, 6, 10, 15, 21 }; |
56 | | |
57 | | CoeffCodingContext::CoeffCodingContext( const TransformUnit& tu, ComponentID component, bool signHide, CtxTpl* tplBuf ) |
58 | 0 | : m_chType (toChannelType(component)) |
59 | 0 | , m_width (tu.block(component).width) |
60 | 0 | , m_height (tu.block(component).height) |
61 | 0 | , m_log2CGWidth ( g_log2SbbSize[ getLog2(m_width) ][ getLog2(m_height) ][0] ) |
62 | 0 | , m_log2CGHeight ( g_log2SbbSize[ getLog2(m_width) ][ getLog2(m_height) ][1] ) |
63 | 0 | , m_log2CGSize (m_log2CGWidth + m_log2CGHeight) |
64 | 0 | , m_widthInGroups (std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width ) >> m_log2CGWidth ) |
65 | 0 | , m_heightInGroups (std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_height) >> m_log2CGHeight) |
66 | 0 | , m_log2BlockWidth (getLog2(m_width )) |
67 | 0 | , m_log2BlockHeight (getLog2(m_height)) |
68 | 0 | , m_log2BlockSize ((m_log2BlockWidth + m_log2BlockHeight)>>1) |
69 | 0 | , m_maxNumCoeff (m_width * m_height) |
70 | 0 | , m_signHiding (signHide) |
71 | 0 | , m_maxLog2TrDynamicRange (tu.cu->sps->getMaxLog2TrDynamicRange(m_chType)) |
72 | 0 | , m_scan (g_scanOrder [SCAN_GROUPED_4x4][g_sizeIdxInfo.idxFrom(m_width )][g_sizeIdxInfo.idxFrom(m_height )]) |
73 | 0 | , m_scanCG (g_scanOrder [SCAN_UNGROUPED ][g_sizeIdxInfo.idxFrom(m_widthInGroups)][g_sizeIdxInfo.idxFrom(m_heightInGroups)]) |
74 | 0 | , m_CtxSetLastX (Ctx::LastX[m_chType]) |
75 | 0 | , m_CtxSetLastY (Ctx::LastY[m_chType]) |
76 | 0 | , m_maxLastPosX (g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width) - 1]) |
77 | 0 | , m_maxLastPosY (g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_height) - 1]) |
78 | 0 | , m_lastOffsetX (isLuma( m_chType ) ? prefix_ctx[ m_log2BlockWidth ] : 0) |
79 | 0 | , m_lastOffsetY (isLuma( m_chType ) ? prefix_ctx[ m_log2BlockHeight ] : 0) |
80 | 0 | , m_lastShiftX (isChroma( m_chType ) ? Clip3( 0, 2, int( m_width >> 3 ) ) : (m_log2BlockWidth + 1) >> 2 ) |
81 | 0 | , m_lastShiftY (isChroma( m_chType ) ? Clip3( 0, 2, int( m_height >> 3 ) ) : (m_log2BlockHeight + 1) >> 2 ) |
82 | 0 | , m_scanPosLast (-1) |
83 | 0 | , m_subSetId (-1) |
84 | 0 | , m_subSetPos (-1) |
85 | 0 | , m_subSetPosX (-1) |
86 | 0 | , m_subSetPosY (-1) |
87 | 0 | , m_minSubPos (-1) |
88 | 0 | , m_maxSubPos (-1) |
89 | 0 | , m_sigGroupCtxId (-1) |
90 | 0 | , m_tmplCpSum1 (-1) |
91 | 0 | , m_tmplCpDiag (-1) |
92 | 0 | , m_sigFlagCtxSet { Ctx::SigFlag[m_chType], Ctx::SigFlag[m_chType+2], Ctx::SigFlag[m_chType+4] } |
93 | 0 | , m_parFlagCtxSet ( Ctx::ParFlag[m_chType] ) |
94 | 0 | , m_gtxFlagCtxSet { Ctx::GtxFlag[m_chType], Ctx::GtxFlag[m_chType+2] } |
95 | 0 | , m_sigGroupCtxIdTS (-1) |
96 | 0 | , m_tsSigFlagCtxSet ( Ctx::TsSigFlag ) |
97 | 0 | , m_tsParFlagCtxSet ( Ctx::TsParFlag ) |
98 | 0 | , m_tsGtxFlagCtxSet ( Ctx::TsGtxFlag ) |
99 | 0 | , m_tsLrg1FlagCtxSet (Ctx::TsLrg1Flag) |
100 | 0 | , m_tsSignFlagCtxSet (Ctx::TsResidualSign) |
101 | 0 | , m_sigCoeffGroupFlag () |
102 | 0 | , m_bdpcm (isLuma(component) ? tu.cu->bdpcmMode() : tu.cu->bdpcmModeChroma()) |
103 | 0 | , m_regBinLimit ( ( TU::getTbAreaAfterCoefZeroOut( tu, component ) * ( isLuma( component ) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA ) ) >> 4 ) |
104 | 0 | , m_ts (tu.mtsIdx( component ) == MTS_SKIP) |
105 | 0 | , m_tplBuf (tplBuf) |
106 | 0 | { |
107 | 0 | if( !m_ts || tu.cu->slice->getTSResidualCodingDisabledFlag() ) |
108 | 0 | memset( tplBuf, 0, m_width * m_height * sizeof( CtxTpl ) ); |
109 | 0 | } |
110 | | |
111 | | void CoeffCodingContext::initSubblock( int SubsetId, bool sigGroupFlag ) |
112 | 0 | { |
113 | 0 | m_subSetId = SubsetId; |
114 | 0 | m_subSetPos = m_scanCG[ m_subSetId ]; |
115 | 0 | m_subSetPosY = m_subSetPos >> getLog2( m_widthInGroups ); |
116 | 0 | m_subSetPosX = m_subSetPos - ( m_subSetPosY * m_widthInGroups ); |
117 | 0 | m_minSubPos = m_subSetId << m_log2CGSize; |
118 | 0 | m_maxSubPos = m_minSubPos + ( 1 << m_log2CGSize ) - 1; |
119 | 0 | const bool lastHorGrp = m_subSetPosX == m_widthInGroups - 1; |
120 | 0 | const bool lastVerGrp = m_subSetPosY == m_heightInGroups - 1; |
121 | 0 | if( sigGroupFlag ) |
122 | 0 | { |
123 | 0 | m_sigCoeffGroupFlag.set ( m_subSetPos ); |
124 | 0 | } |
125 | 0 | unsigned CGPosY = m_subSetPosY; |
126 | 0 | unsigned CGPosX = m_subSetPosX; |
127 | 0 | unsigned sigRight = unsigned( !lastHorGrp ? m_sigCoeffGroupFlag[ m_subSetPos + 1 ] : false ); |
128 | 0 | unsigned sigLower = unsigned( !lastVerGrp ? m_sigCoeffGroupFlag[ m_subSetPos + m_widthInGroups ] : false ); |
129 | 0 | m_sigGroupCtxId = Ctx::SigCoeffGroup[m_chType]( sigRight | sigLower ); |
130 | |
|
131 | 0 | if( m_ts ) |
132 | 0 | { |
133 | 0 | unsigned sigLeft = unsigned( CGPosX > 0 ? m_sigCoeffGroupFlag[m_subSetPos - 1 ] : false ); |
134 | 0 | unsigned sigAbove = unsigned( CGPosY > 0 ? m_sigCoeffGroupFlag[m_subSetPos - m_widthInGroups] : false ); |
135 | 0 | m_sigGroupCtxIdTS = Ctx::TsSigCoeffGroup( sigLeft + sigAbove ); |
136 | 0 | } |
137 | 0 | } |
138 | | |
139 | | |
140 | | unsigned DeriveCtx::CtxModeConsFlag( const CodingStructure& cs, Partitioner& partitioner ) |
141 | 0 | { |
142 | 0 | CHECKD( partitioner.chType != CHANNEL_TYPE_LUMA, "Channel type has to be luma" ); |
143 | | |
144 | 0 | const CodingUnit* cuLeft = partitioner.currPartLevel().cuLeft; |
145 | 0 | const CodingUnit* cuAbove = partitioner.currPartLevel().cuAbove; |
146 | |
|
147 | 0 | unsigned ctxId = ( ( cuAbove && cuAbove->predMode() == MODE_INTRA ) || ( cuLeft && cuLeft->predMode() == MODE_INTRA ) ) ? 1 : 0; |
148 | 0 | return ctxId; |
149 | 0 | } |
150 | | |
151 | | |
152 | | void DeriveCtx::CtxSplit( const CodingStructure& cs, Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, bool *canSplit /*= nullptr */ ) |
153 | 0 | { |
154 | | // get left depth |
155 | 0 | const CodingUnit* cuLeft = partitioner.currPartLevel().cuLeft; |
156 | | // get above depth |
157 | 0 | const CodingUnit* cuAbove = partitioner.currPartLevel().cuAbove; |
158 | | |
159 | | /////////////////////// |
160 | | // CTX do split (0-8) |
161 | | /////////////////////// |
162 | 0 | const unsigned widthCurr = partitioner.currArea().blocks[partitioner.chType].width; |
163 | 0 | const unsigned heightCurr = partitioner.currArea().blocks[partitioner.chType].height; |
164 | |
|
165 | 0 | ctxSpl = !!( cuLeft && cuLeft ->blocks[partitioner.chType].height < heightCurr ); |
166 | 0 | ctxSpl += !!( cuAbove && cuAbove->blocks[partitioner.chType].width < widthCurr ); |
167 | |
|
168 | 0 | unsigned |
169 | 0 | numSplit = canSplit[1] ? 2 : 0; |
170 | 0 | numSplit += canSplit[2]; |
171 | 0 | numSplit += canSplit[3]; |
172 | 0 | numSplit += canSplit[4]; |
173 | 0 | numSplit += canSplit[5]; |
174 | |
|
175 | 0 | if( numSplit > 0 ) numSplit--; |
176 | |
|
177 | 0 | ctxSpl += 3 * ( numSplit >> 1 ); |
178 | | |
179 | | ////////////////////////// |
180 | | // CTX is qt split (0-5) |
181 | | ////////////////////////// |
182 | 0 | ctxQt = !!( cuLeft && cuLeft->qtDepth > partitioner.currQtDepth ); |
183 | 0 | ctxQt += !!( cuAbove && cuAbove->qtDepth > partitioner.currQtDepth ); |
184 | 0 | ctxQt += partitioner.currQtDepth < 2 ? 0 : 3; |
185 | | |
186 | | //////////////////////////// |
187 | | // CTX is ver split (0-4) |
188 | | //////////////////////////// |
189 | 0 | ctxHv = 0; |
190 | |
|
191 | 0 | const unsigned numHor = ( !!canSplit[2] ) + ( !!canSplit[4] ); |
192 | 0 | const unsigned numVer = ( !!canSplit[3] ) + ( !!canSplit[5] ); |
193 | |
|
194 | 0 | if( numVer == numHor ) |
195 | 0 | { |
196 | 0 | const unsigned wIdxAbove = cuAbove ? getLog2( cuAbove->blocks[partitioner.chType].width ) : 0; |
197 | 0 | const unsigned hIdxLeft = cuLeft ? getLog2( cuLeft ->blocks[partitioner.chType].height ) : 0; |
198 | |
|
199 | 0 | const unsigned depAbove = widthCurr >> wIdxAbove; |
200 | 0 | const unsigned depLeft = heightCurr >> hIdxLeft; |
201 | |
|
202 | 0 | if( depAbove == depLeft || !cuLeft || !cuAbove ) ctxHv = 0; |
203 | 0 | else if( depAbove < depLeft ) ctxHv = 1; |
204 | 0 | else ctxHv = 2; |
205 | 0 | } |
206 | 0 | else if( numVer < numHor ) |
207 | 0 | { |
208 | 0 | ctxHv = 3; |
209 | 0 | } |
210 | 0 | else |
211 | 0 | { |
212 | 0 | ctxHv = 4; |
213 | 0 | } |
214 | | |
215 | | ////////////////////////// |
216 | | // CTX is h/v bt (0-3) |
217 | | ////////////////////////// |
218 | 0 | ctxHorBt = !!( partitioner.currMtDepth <= 1 ); |
219 | 0 | ctxVerBt = !!( partitioner.currMtDepth <= 1 ) + 2; |
220 | 0 | } |
221 | | |
222 | | unsigned DeriveCtx::CtxQtCbf( const ComponentID compID, const bool prevCbCbf, const int ispIdx ) |
223 | 0 | { |
224 | 0 | if( ispIdx && isLuma( compID ) ) |
225 | 0 | { |
226 | 0 | return 2 + ( int ) prevCbCbf; |
227 | 0 | } |
228 | 0 | if( compID == COMPONENT_Cr ) |
229 | 0 | { |
230 | 0 | return ( prevCbCbf ? 1 : 0 ); |
231 | 0 | } |
232 | 0 | return 0; |
233 | 0 | } |
234 | | |
235 | | unsigned DeriveCtx::CtxInterDir( const CodingUnit& cu ) |
236 | 0 | { |
237 | 0 | { |
238 | 0 | return ( 7 - ( ( getLog2( cu.lumaSize().width ) + getLog2( cu.lumaSize().height ) + 1 ) >> 1 ) ); |
239 | 0 | } |
240 | 0 | return cu.qtDepth; |
241 | 0 | } |
242 | | |
243 | | unsigned DeriveCtx::CtxAffineFlag( const CodingUnit& cu ) |
244 | 0 | { |
245 | 0 | unsigned ctxId = 0; |
246 | |
|
247 | 0 | const CodingUnit *cuLeft = cu.left; |
248 | 0 | ctxId = ( cuLeft && cuLeft ->affineFlag() ) ? 1 : 0; |
249 | |
|
250 | 0 | const CodingUnit *cuAbove = cu.above; |
251 | 0 | ctxId += ( cuAbove && cuAbove->affineFlag() ) ? 1 : 0; |
252 | |
|
253 | 0 | return ctxId; |
254 | 0 | } |
255 | | unsigned DeriveCtx::CtxSkipFlag( const CodingUnit& cu ) |
256 | 0 | { |
257 | 0 | unsigned ctxId = 0; |
258 | | |
259 | | // Get BCBP of left PU |
260 | 0 | const CodingUnit *cuLeft = cu.left; |
261 | 0 | ctxId = ( cuLeft && cuLeft->skip() ) ? 1 : 0; |
262 | | |
263 | | // Get BCBP of above PU |
264 | 0 | const CodingUnit *cuAbove = cu.above; |
265 | 0 | ctxId += ( cuAbove && cuAbove->skip() ) ? 1 : 0; |
266 | |
|
267 | 0 | return ctxId; |
268 | 0 | } |
269 | | |
270 | | unsigned DeriveCtx::CtxPredModeFlag( const CodingUnit& cu ) |
271 | 0 | { |
272 | 0 | const CodingUnit *cuLeft = cu.left; |
273 | 0 | const CodingUnit *cuAbove = cu.above; |
274 | |
|
275 | 0 | unsigned ctxId = ( ( cuAbove && cuAbove->predMode() == MODE_INTRA ) || ( cuLeft && cuLeft->predMode() == MODE_INTRA ) ) ? 1 : 0; |
276 | |
|
277 | 0 | return ctxId; |
278 | 0 | } |
279 | | |
280 | | unsigned DeriveCtx::CtxIBCFlag( const CodingUnit& cu ) |
281 | 0 | { |
282 | 0 | unsigned ctxId = 0; |
283 | |
|
284 | 0 | const CodingUnit *cuLeft = cu.left; |
285 | 0 | ctxId += ( cuLeft && CU::isIBC( *cuLeft ) ) ? 1 : 0; |
286 | |
|
287 | 0 | const CodingUnit *cuAbove = cu.above; |
288 | 0 | ctxId += ( cuAbove && CU::isIBC( *cuAbove ) ) ? 1 : 0; |
289 | |
|
290 | 0 | return ctxId; |
291 | 0 | } |
292 | | |
293 | | void MergeCtx::setMergeInfo( CodingUnit& cu, int candIdx ) |
294 | 0 | { |
295 | 0 | CHECK( candIdx >= numValidMergeCand, "Merge candidate does not exist" ); |
296 | | |
297 | | //cu.setMergeFlag ( true ); |
298 | | //cu.setMmvdFlag ( false ); |
299 | 0 | cu.setInterDir ( interDirNeighbours[candIdx] ); |
300 | 0 | cu.setImv ( ( !cu.geoFlag() && useAltHpelIf[candIdx] ) ? IMV_HPEL : 0 ); |
301 | | //cu.setMergeIdx ( candIdx ); |
302 | 0 | cu.setMergeType ( mrgTypeNeighbours[candIdx] ); |
303 | 0 | cu.mv [REF_PIC_LIST_0][0] = mvFieldNeighbours[(candIdx << 1) + 0].mv; |
304 | 0 | cu.mv [REF_PIC_LIST_1][0] = mvFieldNeighbours[(candIdx << 1) + 1].mv; |
305 | 0 | cu.refIdx [REF_PIC_LIST_0] = mvFieldNeighbours[( candIdx << 1 ) + 0].mfRefIdx; |
306 | 0 | cu.refIdx [REF_PIC_LIST_1] = mvFieldNeighbours[( candIdx << 1 ) + 1].mfRefIdx; |
307 | 0 | cu.mvpIdx [REF_PIC_LIST_0] = NOT_VALID; |
308 | 0 | cu.mvpIdx [REF_PIC_LIST_1] = NOT_VALID; |
309 | 0 | cu.setBcwIdx ( ( interDirNeighbours[candIdx] == 3 ) ? BcwIdx[candIdx] : BCW_DEFAULT ); |
310 | |
|
311 | 0 | PU::restrictBiPredMergeCandsOne( cu ); |
312 | 0 | } |
313 | | |
314 | | void MergeCtx::setMmvdMergeCandiInfo( CodingUnit& cu, int candIdx ) |
315 | 0 | { |
316 | 0 | const Slice &slice = *cu.slice; |
317 | 0 | const int mvShift = MV_FRACTIONAL_BITS_DIFF; |
318 | 0 | const int refMvdCands[8] = { 1 << mvShift , 2 << mvShift , 4 << mvShift , 8 << mvShift , 16 << mvShift , 32 << mvShift, 64 << mvShift , 128 << mvShift }; |
319 | |
|
320 | 0 | int fPosGroup = 0; |
321 | 0 | int fPosBaseIdx = 0; |
322 | 0 | int fPosStep = 0; |
323 | 0 | int tempIdx = 0; |
324 | 0 | int fPosPosition = 0; |
325 | |
|
326 | 0 | Mv tempMv[2]; |
327 | |
|
328 | 0 | tempIdx = candIdx; |
329 | 0 | fPosGroup = tempIdx / (MMVD_BASE_MV_NUM * MMVD_MAX_REFINE_NUM); |
330 | 0 | tempIdx = tempIdx - fPosGroup * (MMVD_BASE_MV_NUM * MMVD_MAX_REFINE_NUM); |
331 | 0 | fPosBaseIdx = tempIdx / MMVD_MAX_REFINE_NUM; |
332 | 0 | tempIdx = tempIdx - fPosBaseIdx * (MMVD_MAX_REFINE_NUM); |
333 | 0 | fPosStep = tempIdx / 4; |
334 | 0 | fPosPosition = tempIdx - fPosStep * (4); |
335 | 0 | int offset = refMvdCands[fPosStep]; |
336 | |
|
337 | 0 | if( cu.slice->getPicHeader()->getDisFracMMVD() ) |
338 | 0 | { |
339 | 0 | offset <<= 2; |
340 | 0 | } |
341 | 0 | const int refList0 = mmvdBaseMv[fPosBaseIdx][0].mfRefIdx; |
342 | 0 | const int refList1 = mmvdBaseMv[fPosBaseIdx][1].mfRefIdx; |
343 | |
|
344 | 0 | if( ( refList0 != -1 ) && ( refList1 != -1 ) ) |
345 | 0 | { |
346 | 0 | const int poc0 = slice.getRefPOC(REF_PIC_LIST_0, refList0); |
347 | 0 | const int poc1 = slice.getRefPOC(REF_PIC_LIST_1, refList1); |
348 | 0 | const int currPoc = slice.getPOC(); |
349 | |
|
350 | 0 | if( fPosPosition == 0 ) |
351 | 0 | { |
352 | 0 | tempMv[0] = Mv( offset, 0 ); |
353 | 0 | } |
354 | 0 | else if( fPosPosition == 1 ) |
355 | 0 | { |
356 | 0 | tempMv[0] = Mv( -offset, 0 ); |
357 | 0 | } |
358 | 0 | else if( fPosPosition == 2 ) |
359 | 0 | { |
360 | 0 | tempMv[0] = Mv( 0, offset ); |
361 | 0 | } |
362 | 0 | else |
363 | 0 | { |
364 | 0 | tempMv[0] = Mv( 0, -offset ); |
365 | 0 | } |
366 | 0 | if( ( poc0 - currPoc ) == ( poc1 - currPoc ) ) |
367 | 0 | { |
368 | 0 | tempMv[1] = tempMv[0]; |
369 | 0 | } |
370 | 0 | else if( abs( poc1 - currPoc ) > abs( poc0 - currPoc ) ) |
371 | 0 | { |
372 | 0 | tempMv[1] = tempMv[0]; |
373 | |
|
374 | 0 | const int scale = PU::getDistScaleFactor( currPoc, poc0, currPoc, poc1 ); |
375 | 0 | const bool isL0RefLongTerm = cu.slice->getRPL( REF_PIC_LIST_0 )->isRefPicLongterm( refList0 ); |
376 | 0 | const bool isL1RefLongTerm = cu.slice->getRPL( REF_PIC_LIST_1 )->isRefPicLongterm( refList1 ); |
377 | |
|
378 | 0 | if( isL0RefLongTerm || isL1RefLongTerm ) |
379 | 0 | { |
380 | 0 | if( ( poc1 - currPoc ) * ( poc0 - currPoc ) > 0 ) |
381 | 0 | { |
382 | 0 | tempMv[0] = tempMv[1]; |
383 | 0 | } |
384 | 0 | else |
385 | 0 | { |
386 | 0 | tempMv[0].set( -1 * tempMv[1].getHor(), -1 * tempMv[1].getVer() ); |
387 | 0 | } |
388 | 0 | } |
389 | 0 | else |
390 | 0 | tempMv[0] = tempMv[1].scaleMv( scale ); |
391 | 0 | } |
392 | 0 | else |
393 | 0 | { |
394 | 0 | const int scale = PU::getDistScaleFactor( currPoc, poc1, currPoc, poc0 ); |
395 | 0 | const bool isL0RefLongTerm = cu.slice->getRPL( REF_PIC_LIST_0 )->isRefPicLongterm( refList0 ); |
396 | 0 | const bool isL1RefLongTerm = cu.slice->getRPL( REF_PIC_LIST_1 )->isRefPicLongterm( refList1 ); |
397 | |
|
398 | 0 | if( isL0RefLongTerm || isL1RefLongTerm ) |
399 | 0 | { |
400 | 0 | if( ( poc1 - currPoc ) * ( poc0 - currPoc ) > 0 ) |
401 | 0 | { |
402 | 0 | tempMv[1] = tempMv[0]; |
403 | 0 | } |
404 | 0 | else |
405 | 0 | { |
406 | 0 | tempMv[1].set( -1 * tempMv[0].getHor(), -1 * tempMv[0].getVer() ); |
407 | 0 | } |
408 | 0 | } |
409 | 0 | else |
410 | 0 | tempMv[1] = tempMv[0].scaleMv( scale ); |
411 | 0 | } |
412 | |
|
413 | 0 | cu.setInterDir ( 3 ); |
414 | 0 | cu.mv [L0][0] = mmvdBaseMv[fPosBaseIdx][0].mv + tempMv[0]; |
415 | 0 | cu.refIdx[L0] = refList0; |
416 | 0 | cu.mv [L1][0] = mmvdBaseMv[fPosBaseIdx][1].mv + tempMv[1]; |
417 | 0 | cu.refIdx[L1] = refList1; |
418 | 0 | } |
419 | 0 | else if( refList0 != -1 ) |
420 | 0 | { |
421 | 0 | if( fPosPosition == 0 ) |
422 | 0 | { |
423 | 0 | tempMv[0] = Mv( offset, 0 ); |
424 | 0 | } |
425 | 0 | else if( fPosPosition == 1 ) |
426 | 0 | { |
427 | 0 | tempMv[0] = Mv( -offset, 0 ); |
428 | 0 | } |
429 | 0 | else if( fPosPosition == 2 ) |
430 | 0 | { |
431 | 0 | tempMv[0] = Mv( 0, offset ); |
432 | 0 | } |
433 | 0 | else |
434 | 0 | { |
435 | 0 | tempMv[0] = Mv( 0, -offset ); |
436 | 0 | } |
437 | |
|
438 | 0 | cu.setInterDir ( 1 ); |
439 | 0 | cu.mv [L0][0] = mmvdBaseMv[fPosBaseIdx][0].mv + tempMv[0]; |
440 | 0 | cu.refIdx[L0] = refList0; |
441 | 0 | cu.mv [L1][0] = Mv(0, 0); |
442 | 0 | cu.refIdx[L1] = NOT_VALID; |
443 | 0 | } |
444 | 0 | else if( refList1 != -1 ) |
445 | 0 | { |
446 | 0 | if( fPosPosition == 0 ) |
447 | 0 | { |
448 | 0 | tempMv[1] = Mv( offset, 0 ); |
449 | 0 | } |
450 | 0 | else if( fPosPosition == 1 ) |
451 | 0 | { |
452 | 0 | tempMv[1] = Mv( -offset, 0 ); |
453 | 0 | } |
454 | 0 | else if( fPosPosition == 2 ) |
455 | 0 | { |
456 | 0 | tempMv[1] = Mv( 0, offset ); |
457 | 0 | } |
458 | 0 | else |
459 | 0 | { |
460 | 0 | tempMv[1] = Mv( 0, -offset ); |
461 | 0 | } |
462 | |
|
463 | 0 | cu.setInterDir ( 2 ); |
464 | 0 | cu.mv [REF_PIC_LIST_0][0] = Mv(0, 0); |
465 | 0 | cu.refIdx[REF_PIC_LIST_0] = NOT_VALID; |
466 | 0 | cu.mv [REF_PIC_LIST_1][0] = mmvdBaseMv[fPosBaseIdx][1].mv + tempMv[1]; |
467 | 0 | cu.refIdx[REF_PIC_LIST_1] = refList1; |
468 | 0 | } |
469 | | |
470 | | //cu.setMmvdFlag ( true ); |
471 | 0 | cu.mmvdIdx = candIdx; |
472 | | //cu.setMergeFlag ( true ); |
473 | | //cu.setMergeIdx ( candIdx ); |
474 | | //cu.setMergeType ( MRG_TYPE_DEFAULT_N ); |
475 | 0 | cu.mvpIdx [L0] = NOT_VALID; |
476 | 0 | cu.mvpIdx [L1] = NOT_VALID; |
477 | 0 | cu.setImv ( mmvdUseAltHpelIf[fPosBaseIdx] ? IMV_HPEL : 0 ); |
478 | 0 | cu.setBcwIdx ( ( interDirNeighbours[fPosBaseIdx] == 3 ) ? BcwIdx[fPosBaseIdx] : BCW_DEFAULT ); |
479 | |
|
480 | 0 | for( int refList = 0; refList < 2; refList++ ) |
481 | 0 | { |
482 | 0 | if( cu.refIdx[refList] >= 0 ) |
483 | 0 | { |
484 | 0 | cu.mv[refList][0].clipToStorageBitDepth(); |
485 | 0 | } |
486 | 0 | } |
487 | |
|
488 | 0 | PU::restrictBiPredMergeCandsOne( cu ); |
489 | 0 | } |
490 | | |
491 | | unsigned DeriveCtx::CtxMipFlag( const CodingUnit& cu ) |
492 | 0 | { |
493 | 0 | unsigned ctxId = 0; |
494 | |
|
495 | 0 | const CodingUnit *cuLeft = cu.left; |
496 | 0 | ctxId = ( cuLeft && cuLeft->mipFlag() ) ? 1 : 0; |
497 | |
|
498 | 0 | const CodingUnit *cuAbove = cu.above; |
499 | 0 | ctxId += ( cuAbove && cuAbove->mipFlag() ) ? 1 : 0; |
500 | |
|
501 | 0 | ctxId = ( cu.lwidth() > 2 * cu.lheight() || cu.lheight() > 2 * cu.lwidth() ) ? 3 : ctxId; |
502 | |
|
503 | 0 | return ctxId; |
504 | 0 | } |
505 | | |
506 | | } |