/src/vvenc/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) 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 ContextModelling.cpp |
45 | | \brief Classes providing probability descriptions and contexts |
46 | | */ |
47 | | |
48 | | #include "ContextModelling.h" |
49 | | #include "UnitTools.h" |
50 | | #include "CodingStructure.h" |
51 | | #include "Picture.h" |
52 | | |
53 | | //! \ingroup CommonLib |
54 | | //! \{ |
55 | | |
56 | | namespace vvenc { |
57 | | |
58 | | static const int prefix_ctx[7] = { 0, 0, 0, 3, 6, 10, 15 }; |
59 | | |
60 | | CoeffCodingContext::CoeffCodingContext( const TransformUnit& tu, ComponentID component, bool signHide, bool bdpcm, CtxTpl* tplBuf ) |
61 | 0 | : m_compID (component) |
62 | 0 | , m_chType (toChannelType(m_compID)) |
63 | 0 | , m_width (tu.block(m_compID).width) |
64 | 0 | , m_height (tu.block(m_compID).height) |
65 | 0 | , m_log2CGWidth ( g_log2SbbSize[ Log2(m_width) ][ Log2(m_height) ][0] ) |
66 | 0 | , m_log2CGHeight ( g_log2SbbSize[ Log2(m_width) ][ Log2(m_height) ][1] ) |
67 | 0 | , m_log2CGSize (m_log2CGWidth + m_log2CGHeight) |
68 | 0 | , m_widthInGroups (std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width) >> m_log2CGWidth) |
69 | 0 | , m_heightInGroups (std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_height) >> m_log2CGHeight) |
70 | 0 | , m_log2WidthInGroups (Log2(m_widthInGroups)) |
71 | 0 | , m_log2BlockWidth (Log2(m_width)) |
72 | 0 | , m_log2BlockHeight (Log2(m_height)) |
73 | 0 | , m_maxNumCoeff (m_width * m_height) |
74 | 0 | , m_signHiding (signHide) |
75 | 0 | , m_maxLog2TrDynamicRange (tu.cs->sps->getMaxLog2TrDynamicRange()) |
76 | 0 | , m_scan (getScanOrder( SCAN_GROUPED_4x4, m_log2BlockWidth, m_log2BlockHeight )) |
77 | 0 | , m_scanCG (getScanOrder( SCAN_UNGROUPED , Log2(m_widthInGroups), Log2(m_heightInGroups))) |
78 | 0 | , m_CtxSetLastX (Ctx::LastX[m_chType]) |
79 | 0 | , m_CtxSetLastY (Ctx::LastY[m_chType]) |
80 | 0 | , m_maxLastPosX (g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width) - 1]) |
81 | 0 | , m_maxLastPosY (g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_height) - 1]) |
82 | 0 | , m_lastOffsetX ((m_chType == CH_C) ? 0 :prefix_ctx[ m_log2BlockWidth ]) |
83 | 0 | , m_lastOffsetY ((m_chType == CH_C) ? 0 :prefix_ctx[ m_log2BlockHeight ]) |
84 | 0 | , m_lastShiftX ((m_chType == CH_C) ? Clip3( 0, 2, int( m_width >> 3) ) : (m_log2BlockWidth + 1) >> 2) |
85 | 0 | , m_lastShiftY ((m_chType == CH_C) ? Clip3( 0, 2, int( m_height >> 3) ) : (m_log2BlockHeight + 1) >> 2) |
86 | 0 | , m_scanPosLast (-1) |
87 | 0 | , m_subSetId (-1) |
88 | 0 | , m_subSetPos (-1) |
89 | 0 | , m_subSetPosX (-1) |
90 | 0 | , m_subSetPosY (-1) |
91 | 0 | , m_minSubPos (-1) |
92 | 0 | , m_maxSubPos (-1) |
93 | 0 | , m_sigGroupCtxId (-1) |
94 | 0 | , m_tmplCpSum1 (-1) |
95 | 0 | , m_tmplCpDiag (-1) |
96 | 0 | , m_sigFlagCtxSet { Ctx::SigFlag[m_chType], Ctx::SigFlag[m_chType+2], Ctx::SigFlag[m_chType+4] } |
97 | 0 | , m_parFlagCtxSet ( Ctx::ParFlag[m_chType] ) |
98 | 0 | , m_gtxFlagCtxSet { Ctx::GtxFlag[m_chType], Ctx::GtxFlag[m_chType+2] } |
99 | 0 | , m_sigGroupCtxIdTS (-1) |
100 | 0 | , m_tsSigFlagCtxSet ( Ctx::TsSigFlag ) |
101 | 0 | , m_tsParFlagCtxSet ( Ctx::TsParFlag ) |
102 | 0 | , m_tsGtxFlagCtxSet ( Ctx::TsGtxFlag ) |
103 | 0 | , m_tsLrg1FlagCtxSet (Ctx::TsLrg1Flag) |
104 | 0 | , m_tsSignFlagCtxSet (Ctx::TsResidualSign) |
105 | 0 | , m_sigCoeffGroupFlag () |
106 | 0 | , m_bdpcm (bdpcm) |
107 | 0 | , m_tplBuf (tplBuf + m_width * m_height - 1) |
108 | 0 | { |
109 | 0 | if( tplBuf && ( tu.mtsIdx[ component ] != MTS_SKIP || tu.cu->slice->tsResidualCodingDisabled ) ) |
110 | 0 | memset( tplBuf, 0, m_width * m_height * sizeof( CtxTpl ) ); |
111 | 0 | } |
112 | | |
113 | | void CoeffCodingContext::initSubblock( int SubsetId, bool sigGroupFlag ) |
114 | 0 | { |
115 | 0 | m_subSetId = SubsetId; |
116 | 0 | m_subSetPos = m_scanCG[m_subSetId].idx; |
117 | 0 | m_subSetPosY = m_subSetPos >> m_log2WidthInGroups; |
118 | 0 | m_subSetPosX = m_subSetPos - ( m_subSetPosY << m_log2WidthInGroups ); |
119 | 0 | m_minSubPos = m_subSetId << m_log2CGSize; |
120 | 0 | m_maxSubPos = m_minSubPos + ( 1 << m_log2CGSize ) - 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( ( CGPosX + 1 ) < m_widthInGroups ? m_sigCoeffGroupFlag[ m_subSetPos + 1 ] : false ); |
128 | 0 | unsigned sigLower = unsigned( ( CGPosY + 1 ) < m_heightInGroups ? m_sigCoeffGroupFlag[ m_subSetPos + m_widthInGroups ] : false ); |
129 | 0 | m_sigGroupCtxId = Ctx::SigCoeffGroup[m_chType]( sigRight | sigLower ); |
130 | 0 | unsigned sigLeft = unsigned( CGPosX > 0 ? m_sigCoeffGroupFlag[m_subSetPos - 1 ] : false ); |
131 | 0 | unsigned sigAbove = unsigned( CGPosY > 0 ? m_sigCoeffGroupFlag[m_subSetPos - m_widthInGroups] : false ); |
132 | 0 | m_sigGroupCtxIdTS = Ctx::TsSigCoeffGroup( sigLeft + sigAbove ); |
133 | 0 | } |
134 | | |
135 | | |
136 | | void DeriveCtx::determineNeighborCus( const CodingStructure& cs, const UnitArea& ua, const ChannelType ch, const TreeType _treeType ) |
137 | 0 | { |
138 | 0 | const Position& posLuma = ua.lumaPos(); |
139 | 0 | const Position& pos = ch == CH_L ? posLuma : ua.chromaPos(); |
140 | 0 | const uint32_t curSliceIdx = cs.slice->independentSliceIdx; |
141 | 0 | const uint32_t curTileIdx = cs.pps->getTileIdx( posLuma ); |
142 | |
|
143 | 0 | cuRestrictedLeft[ch] = cs.getCURestricted( pos.offset(-1, 0), pos, curSliceIdx, curTileIdx, ch, _treeType ); |
144 | 0 | cuRestrictedAbove[ch] = cs.getCURestricted( pos.offset(0, -1), pos, curSliceIdx, curTileIdx, ch, _treeType ); |
145 | 0 | } |
146 | | |
147 | | void DeriveCtx::CtxSplit( const Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, const bool canSplit[6] ) const |
148 | 0 | { |
149 | 0 | const ChannelType chType = partitioner.chType; |
150 | 0 | const CodingUnit* cuLeft = cuRestrictedLeft[chType]; |
151 | 0 | const CodingUnit* cuAbove = cuRestrictedAbove[chType]; |
152 | | |
153 | | /////////////////////// |
154 | | // CTX do split (0-8) |
155 | | /////////////////////// |
156 | 0 | const unsigned widthCurr = partitioner.currArea().blocks[chType].width; |
157 | 0 | const unsigned heightCurr = partitioner.currArea().blocks[chType].height; |
158 | |
|
159 | 0 | ctxSpl = 0; |
160 | |
|
161 | 0 | if( cuLeft ) |
162 | 0 | { |
163 | 0 | const unsigned heightLeft = cuLeft->blocks[chType].height; |
164 | 0 | ctxSpl += ( heightLeft < heightCurr ? 1 : 0 ); |
165 | 0 | } |
166 | 0 | if( cuAbove ) |
167 | 0 | { |
168 | 0 | const unsigned widthAbove = cuAbove->blocks[chType].width; |
169 | 0 | ctxSpl += ( widthAbove < widthCurr ? 1 : 0 ); |
170 | 0 | } |
171 | |
|
172 | 0 | unsigned numSplit = 0; |
173 | 0 | if( canSplit[1] ) numSplit += 2; |
174 | 0 | if( canSplit[2] ) numSplit += 1; |
175 | 0 | if( canSplit[3] ) numSplit += 1; |
176 | 0 | if( canSplit[4] ) numSplit += 1; |
177 | 0 | if( canSplit[5] ) numSplit += 1; |
178 | |
|
179 | 0 | if( numSplit > 0 ) numSplit--; |
180 | |
|
181 | 0 | ctxSpl += 3 * ( numSplit >> 1 ); |
182 | | |
183 | | ////////////////////////// |
184 | | // CTX is qt split (0-5) |
185 | | ////////////////////////// |
186 | 0 | ctxQt = ( cuLeft && cuLeft->qtDepth > partitioner.currQtDepth ) ? 1 : 0; |
187 | 0 | ctxQt += ( cuAbove && cuAbove->qtDepth > partitioner.currQtDepth ) ? 1 : 0; |
188 | 0 | ctxQt += partitioner.currQtDepth < 2 ? 0 : 3; |
189 | | |
190 | | //////////////////////////// |
191 | | // CTX is ver split (0-4) |
192 | | //////////////////////////// |
193 | 0 | ctxHv = 0; |
194 | |
|
195 | 0 | const unsigned numHor = ( canSplit[2] ? 1 : 0 ) + ( canSplit[4] ? 1 : 0 ); |
196 | 0 | const unsigned numVer = ( canSplit[3] ? 1 : 0 ) + ( canSplit[5] ? 1 : 0 ); |
197 | |
|
198 | 0 | if( numVer == numHor ) |
199 | 0 | { |
200 | 0 | const Area& area = partitioner.currArea().blocks[chType]; |
201 | |
|
202 | 0 | const unsigned wAbove = cuAbove ? cuAbove->blocks[chType].width : 1; |
203 | 0 | const unsigned hLeft = cuLeft ? cuLeft ->blocks[chType].height : 1; |
204 | |
|
205 | 0 | const unsigned depAbove = area.width / wAbove; |
206 | 0 | const unsigned depLeft = area.height / hLeft; |
207 | |
|
208 | 0 | if( depAbove == depLeft || !cuLeft || !cuAbove ) ctxHv = 0; |
209 | 0 | else if( depAbove < depLeft ) ctxHv = 1; |
210 | 0 | else ctxHv = 2; |
211 | 0 | } |
212 | 0 | else if( numVer < numHor ) |
213 | 0 | { |
214 | 0 | ctxHv = 3; |
215 | 0 | } |
216 | 0 | else |
217 | 0 | { |
218 | 0 | ctxHv = 4; |
219 | 0 | } |
220 | | |
221 | | ////////////////////////// |
222 | | // CTX is h/v bt (0-3) |
223 | | ////////////////////////// |
224 | 0 | ctxHorBt = ( partitioner.currMtDepth <= 1 ? 1 : 0 ); |
225 | 0 | ctxVerBt = ( partitioner.currMtDepth <= 1 ? 3 : 2 ); |
226 | 0 | } |
227 | | |
228 | | |
229 | | |
230 | | void MergeCtx::setMergeInfo( CodingUnit& cu, int candIdx ) const |
231 | 0 | { |
232 | 0 | CHECK( candIdx >= numValidMergeCand, "Merge candidate does not exist" ); |
233 | 0 | cu.mergeFlag = true; |
234 | 0 | cu.mmvdMergeFlag = false; |
235 | 0 | cu.interDir = interDirNeighbours[candIdx]; |
236 | 0 | cu.imv = (!cu.geo && useAltHpelIf[candIdx]) ? IMV_HPEL : IMV_OFF; |
237 | 0 | cu.mergeIdx = candIdx; |
238 | 0 | cu.mergeType = mrgTypeNeighbours[candIdx]; |
239 | 0 | cu.mv [REF_PIC_LIST_0][0] = mvFieldNeighbours[candIdx][0].mv; |
240 | 0 | cu.mv [REF_PIC_LIST_1][0] = mvFieldNeighbours[candIdx][1].mv; |
241 | 0 | cu.mvd [REF_PIC_LIST_0][0] = Mv(); |
242 | 0 | cu.mvd [REF_PIC_LIST_1][0] = Mv(); |
243 | 0 | cu.refIdx [REF_PIC_LIST_0] = mvFieldNeighbours[candIdx][0].refIdx; |
244 | 0 | cu.refIdx [REF_PIC_LIST_1] = mvFieldNeighbours[candIdx][1].refIdx; |
245 | 0 | cu.mvpIdx [REF_PIC_LIST_0] = NOT_VALID; |
246 | 0 | cu.mvpIdx [REF_PIC_LIST_1] = NOT_VALID; |
247 | 0 | cu.mvpNum [REF_PIC_LIST_0] = NOT_VALID; |
248 | 0 | cu.mvpNum [REF_PIC_LIST_1] = NOT_VALID; |
249 | 0 | if( CU::isIBC( cu ) ) |
250 | 0 | { |
251 | 0 | cu.imv = cu.imv == IMV_HPEL ? IMV_OFF : cu.imv; |
252 | 0 | } |
253 | 0 | cu.BcwIdx = interDirNeighbours[candIdx] == 3 ? BcwIdx[candIdx] : BCW_DEFAULT; |
254 | 0 | cu.mcControl = 0; |
255 | 0 | cu.mvRefine = false; |
256 | |
|
257 | 0 | CU::restrictBiPredMergeCandsOne( cu ); |
258 | 0 | } |
259 | | |
260 | | |
261 | | void MergeCtx::getMmvdDeltaMv( const Slice &slice, const MmvdIdx candIdx, Mv deltaMv[ NUM_REF_PIC_LIST_01 ] ) const |
262 | 0 | { |
263 | 0 | const int mvdBaseIdx = candIdx.pos.baseIdx; |
264 | 0 | const int mvdStep = candIdx.pos.step; |
265 | 0 | const int mvdPosition = candIdx.pos.position; |
266 | |
|
267 | 0 | int offset = 1 << ( mvdStep + MV_FRACTIONAL_BITS_DIFF ); |
268 | 0 | if( slice.picHeader->disFracMMVD ) |
269 | 0 | { |
270 | 0 | offset <<= 2; |
271 | 0 | } |
272 | 0 | const int refList0 = mmvdBaseMv[mvdBaseIdx][REF_PIC_LIST_0].refIdx; |
273 | 0 | const int refList1 = mmvdBaseMv[mvdBaseIdx][REF_PIC_LIST_1].refIdx; |
274 | |
|
275 | 0 | const Mv dMvTable[ 4 ] = { Mv( offset,0 ), Mv( -offset,0 ), Mv( 0, offset ), Mv( 0, -offset ) }; |
276 | 0 | if( ( refList0 != -1 ) && ( refList1 != -1 ) ) |
277 | 0 | { |
278 | 0 | const int poc0 = slice.getRefPOC( REF_PIC_LIST_0, refList0 ); |
279 | 0 | const int poc1 = slice.getRefPOC( REF_PIC_LIST_1, refList1 ); |
280 | 0 | const int currPoc = slice.poc; |
281 | |
|
282 | 0 | deltaMv[0] = dMvTable[mvdPosition]; |
283 | |
|
284 | 0 | if( ( poc0 - currPoc ) == ( poc1 - currPoc ) ) |
285 | 0 | { |
286 | 0 | deltaMv[1] = deltaMv[0]; |
287 | 0 | } |
288 | 0 | else if( abs( poc1 - currPoc ) > abs( poc0 - currPoc ) ) |
289 | 0 | { |
290 | 0 | const int scale = CU::getDistScaleFactor( currPoc, poc0, currPoc, poc1 ); |
291 | 0 | const bool isL0RefLongTerm = slice.getRefPic(REF_PIC_LIST_0, refList0)->isLongTerm; |
292 | 0 | const bool isL1RefLongTerm = slice.getRefPic(REF_PIC_LIST_1, refList1)->isLongTerm; |
293 | 0 | deltaMv[1] = deltaMv[0]; |
294 | |
|
295 | 0 | if( isL0RefLongTerm || isL1RefLongTerm ) |
296 | 0 | { |
297 | 0 | if( ( poc1 - currPoc ) * ( poc0 - currPoc ) > 0 ) |
298 | 0 | { |
299 | 0 | deltaMv[0] = deltaMv[1]; |
300 | 0 | } |
301 | 0 | else |
302 | 0 | { |
303 | 0 | deltaMv[0].set( -1 * deltaMv[1].hor, -1 * deltaMv[1].ver ); |
304 | 0 | } |
305 | 0 | } |
306 | 0 | else |
307 | 0 | { |
308 | 0 | deltaMv[0] = deltaMv[1].scaleMv( scale ); |
309 | 0 | } |
310 | 0 | } |
311 | 0 | else |
312 | 0 | { |
313 | 0 | const int scale = CU::getDistScaleFactor(currPoc, poc1, currPoc, poc0); |
314 | 0 | const bool isL0RefLongTerm = slice.getRefPic(REF_PIC_LIST_0, refList0)->isLongTerm; |
315 | 0 | const bool isL1RefLongTerm = slice.getRefPic(REF_PIC_LIST_1, refList1)->isLongTerm; |
316 | |
|
317 | 0 | if( isL0RefLongTerm || isL1RefLongTerm ) |
318 | 0 | { |
319 | 0 | if( ( poc1 - currPoc ) * ( poc0 - currPoc ) > 0 ) |
320 | 0 | { |
321 | 0 | deltaMv[1] = deltaMv[0]; |
322 | 0 | } |
323 | 0 | else |
324 | 0 | { |
325 | 0 | deltaMv[1].set( -1 * deltaMv[0].hor, -1 * deltaMv[0].ver ); |
326 | 0 | } |
327 | 0 | } |
328 | 0 | else |
329 | 0 | { |
330 | 0 | deltaMv[1] = deltaMv[0].scaleMv( scale ); |
331 | 0 | } |
332 | 0 | } |
333 | 0 | } |
334 | 0 | else if( refList0 != -1 ) |
335 | 0 | { |
336 | 0 | deltaMv[0] = dMvTable[mvdPosition]; |
337 | 0 | } |
338 | 0 | else if( refList1 != -1 ) |
339 | 0 | { |
340 | 0 | deltaMv[1] = dMvTable[mvdPosition]; |
341 | 0 | } |
342 | 0 | } |
343 | | |
344 | | void MergeCtx::setMmvdMergeCandiInfo( CodingUnit &cu, const MmvdIdx candIdx ) const |
345 | 0 | { |
346 | 0 | Mv tempMv[NUM_REF_PIC_LIST_01]; |
347 | |
|
348 | 0 | getMmvdDeltaMv( *cu.cs->slice, candIdx, tempMv ); |
349 | 0 | const int mvdBaseIdx = candIdx.pos.baseIdx; |
350 | |
|
351 | 0 | const int refList0 = mmvdBaseMv[mvdBaseIdx][0].refIdx; |
352 | 0 | const int refList1 = mmvdBaseMv[mvdBaseIdx][1].refIdx; |
353 | |
|
354 | 0 | if( refList0 != NOT_VALID && refList1 != NOT_VALID ) |
355 | 0 | { |
356 | 0 | cu.interDir = 3; |
357 | 0 | cu.mv [REF_PIC_LIST_0][0] = mmvdBaseMv[mvdBaseIdx][0].mv + tempMv[0]; |
358 | 0 | cu.refIdx[REF_PIC_LIST_0] = refList0; |
359 | 0 | cu.mv [REF_PIC_LIST_1][0] = mmvdBaseMv[mvdBaseIdx][1].mv + tempMv[1]; |
360 | 0 | cu.refIdx[REF_PIC_LIST_1] = refList1; |
361 | 0 | } |
362 | 0 | else if( refList0 != NOT_VALID ) |
363 | 0 | { |
364 | 0 | cu.interDir = 1; |
365 | 0 | cu.mv [REF_PIC_LIST_0][0] = mmvdBaseMv[mvdBaseIdx][0].mv + tempMv[0]; |
366 | 0 | cu.refIdx[REF_PIC_LIST_0] = refList0; |
367 | 0 | cu.mv [REF_PIC_LIST_1][0] = Mv(0, 0); |
368 | 0 | cu.refIdx[REF_PIC_LIST_1] = -1; |
369 | 0 | } |
370 | 0 | else if( refList1 != NOT_VALID ) |
371 | 0 | { |
372 | 0 | cu.interDir = 2; |
373 | 0 | cu.mv [REF_PIC_LIST_0][0] = Mv(0, 0); |
374 | 0 | cu.refIdx[REF_PIC_LIST_0] = -1; |
375 | 0 | cu.mv [REF_PIC_LIST_1][0] = mmvdBaseMv[mvdBaseIdx][1].mv + tempMv[1]; |
376 | 0 | cu.refIdx[REF_PIC_LIST_1] = refList1; |
377 | 0 | } |
378 | |
|
379 | 0 | cu.mmvdMergeFlag = true; |
380 | 0 | cu.mmvdMergeIdx = candIdx; |
381 | 0 | cu.mergeFlag = true; |
382 | 0 | cu.mergeIdx = candIdx.val; |
383 | 0 | cu.mergeType = MRG_TYPE_DEFAULT_N; |
384 | |
|
385 | 0 | cu.mvd[REF_PIC_LIST_0][0] = Mv(); |
386 | 0 | cu.mvd[REF_PIC_LIST_1][0] = Mv(); |
387 | 0 | cu.mvpIdx[REF_PIC_LIST_0] = NOT_VALID; |
388 | 0 | cu.mvpIdx[REF_PIC_LIST_1] = NOT_VALID; |
389 | 0 | cu.mvpNum[REF_PIC_LIST_0] = NOT_VALID; |
390 | 0 | cu.mvpNum[REF_PIC_LIST_1] = NOT_VALID; |
391 | 0 | cu.imv = mmvdUseAltHpelIf[mvdBaseIdx] ? IMV_HPEL : IMV_OFF; |
392 | |
|
393 | 0 | cu.BcwIdx = interDirNeighbours[mvdBaseIdx] == 3 ? BcwIdx[mvdBaseIdx] : BCW_DEFAULT; |
394 | |
|
395 | 0 | for( int refList = 0; refList < 2; refList++ ) |
396 | 0 | { |
397 | 0 | if( cu.refIdx[refList] >= 0 ) |
398 | 0 | { |
399 | 0 | cu.mv[refList][0].clipToStorageBitDepth(); |
400 | 0 | } |
401 | 0 | } |
402 | |
|
403 | 0 | CU::restrictBiPredMergeCandsOne( cu ); |
404 | 0 | } |
405 | | |
406 | | unsigned DeriveCtx::CtxMipFlag( const CodingUnit& cu ) const |
407 | 0 | { |
408 | 0 | unsigned ctxId = 0; |
409 | 0 | const CodingUnit *cuLeft = cuRestrictedLeft[CH_L]; |
410 | 0 | ctxId = (cuLeft && cuLeft->mipFlag) ? 1 : 0; |
411 | |
|
412 | 0 | const CodingUnit *cuAbove = cuRestrictedAbove[CH_L]; |
413 | 0 | ctxId += (cuAbove && cuAbove->mipFlag) ? 1 : 0; |
414 | |
|
415 | 0 | ctxId = (cu.lwidth() > 2*cu.lheight() || cu.lheight() > 2*cu.lwidth()) ? 3 : ctxId; |
416 | |
|
417 | 0 | return ctxId; |
418 | 0 | } |
419 | | |
420 | | } // namespace vvenc |
421 | | |
422 | | //! \} |
423 | | |