Coverage Report

Created: 2026-06-16 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
144k
  : m_chType                    (toChannelType(component))
59
144k
  , m_width                     (tu.block(component).width)
60
144k
  , m_height                    (tu.block(component).height)
61
144k
  , m_log2CGWidth               ( g_log2SbbSize[ getLog2(m_width) ][ getLog2(m_height) ][0] )
62
144k
  , m_log2CGHeight              ( g_log2SbbSize[ getLog2(m_width) ][ getLog2(m_height) ][1] )
63
144k
  , m_log2CGSize                (m_log2CGWidth + m_log2CGHeight)
64
144k
  , m_widthInGroups             (std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width ) >> m_log2CGWidth )
65
144k
  , m_heightInGroups            (std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_height) >> m_log2CGHeight)
66
144k
  , m_log2BlockWidth            (getLog2(m_width ))
67
144k
  , m_log2BlockHeight           (getLog2(m_height))
68
144k
  , m_log2BlockSize             ((m_log2BlockWidth + m_log2BlockHeight)>>1)
69
144k
  , m_maxNumCoeff               (m_width * m_height)
70
144k
  , m_signHiding                (signHide)
71
144k
  , m_maxLog2TrDynamicRange     (tu.cu->sps->getMaxLog2TrDynamicRange(m_chType))
72
144k
  , m_scan                      (g_scanOrder     [SCAN_GROUPED_4x4][g_sizeIdxInfo.idxFrom(m_width        )][g_sizeIdxInfo.idxFrom(m_height        )])
73
144k
  , m_scanCG                    (g_scanOrder     [SCAN_UNGROUPED  ][g_sizeIdxInfo.idxFrom(m_widthInGroups)][g_sizeIdxInfo.idxFrom(m_heightInGroups)])
74
144k
  , m_CtxSetLastX               (Ctx::LastX[m_chType])
75
144k
  , m_CtxSetLastY               (Ctx::LastY[m_chType])
76
144k
  , m_maxLastPosX               (g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width)  - 1])
77
144k
  , m_maxLastPosY               (g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_height) - 1])
78
144k
  , m_lastOffsetX               (isLuma( m_chType ) ? prefix_ctx[ m_log2BlockWidth  ] : 0)
79
144k
  , m_lastOffsetY               (isLuma( m_chType ) ? prefix_ctx[ m_log2BlockHeight ] : 0)
80
144k
  , m_lastShiftX                (isChroma( m_chType ) ? Clip3( 0, 2, int( m_width  >> 3 ) ) : (m_log2BlockWidth  + 1) >> 2 )
81
144k
  , m_lastShiftY                (isChroma( m_chType ) ? Clip3( 0, 2, int( m_height >> 3 ) ) : (m_log2BlockHeight + 1) >> 2 )
82
144k
  , m_scanPosLast               (-1)
83
144k
  , m_subSetId                  (-1)
84
144k
  , m_subSetPos                 (-1)
85
144k
  , m_subSetPosX                (-1)
86
144k
  , m_subSetPosY                (-1)
87
144k
  , m_minSubPos                 (-1)
88
144k
  , m_maxSubPos                 (-1)
89
144k
  , m_sigGroupCtxId             (-1)
90
144k
  , m_tmplCpSum1                (-1)
91
144k
  , m_tmplCpDiag                (-1)
92
144k
  , m_sigFlagCtxSet             { Ctx::SigFlag[m_chType], Ctx::SigFlag[m_chType+2], Ctx::SigFlag[m_chType+4] }
93
144k
  , m_parFlagCtxSet             ( Ctx::ParFlag[m_chType] )
94
144k
  , m_gtxFlagCtxSet             { Ctx::GtxFlag[m_chType], Ctx::GtxFlag[m_chType+2] }
95
144k
  , m_sigGroupCtxIdTS           (-1)
96
144k
  , m_tsSigFlagCtxSet           ( Ctx::TsSigFlag )
97
144k
  , m_tsParFlagCtxSet           ( Ctx::TsParFlag )
98
144k
  , m_tsGtxFlagCtxSet           ( Ctx::TsGtxFlag )
99
144k
  , m_tsLrg1FlagCtxSet          (Ctx::TsLrg1Flag)
100
144k
  , m_tsSignFlagCtxSet          (Ctx::TsResidualSign)
101
144k
  , m_sigCoeffGroupFlag         ()
102
144k
  , m_bdpcm                     (isLuma(component) ? tu.cu->bdpcmMode() : tu.cu->bdpcmModeChroma())
103
144k
  , 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
144k
  , m_ts                        (tu.mtsIdx( component ) == MTS_SKIP)
105
144k
  , m_tplBuf                    (tplBuf)
106
144k
{
107
144k
  if( !m_ts || tu.cu->slice->getTSResidualCodingDisabledFlag() )
108
135k
    memset( tplBuf, 0, m_width * m_height * sizeof( CtxTpl ) );
109
144k
}
110
111
void CoeffCodingContext::initSubblock( int SubsetId, bool sigGroupFlag )
112
349k
{
113
349k
  m_subSetId                = SubsetId;
114
349k
  m_subSetPos               = m_scanCG[ m_subSetId ];
115
349k
  m_subSetPosY              = m_subSetPos >> getLog2( m_widthInGroups );
116
349k
  m_subSetPosX              = m_subSetPos - ( m_subSetPosY * m_widthInGroups );
117
349k
  m_minSubPos               = m_subSetId << m_log2CGSize;
118
349k
  m_maxSubPos               = m_minSubPos + ( 1 << m_log2CGSize ) - 1;
119
349k
  const bool lastHorGrp     = m_subSetPosX == m_widthInGroups  - 1;
120
349k
  const bool lastVerGrp     = m_subSetPosY == m_heightInGroups - 1;
121
349k
  if( sigGroupFlag )
122
0
  {
123
0
    m_sigCoeffGroupFlag.set ( m_subSetPos );
124
0
  }
125
349k
  unsigned  CGPosY    = m_subSetPosY;
126
349k
  unsigned  CGPosX    = m_subSetPosX;
127
349k
  unsigned  sigRight  = unsigned( !lastHorGrp  ? m_sigCoeffGroupFlag[ m_subSetPos + 1               ] : false );
128
349k
  unsigned  sigLower  = unsigned( !lastVerGrp  ? m_sigCoeffGroupFlag[ m_subSetPos + m_widthInGroups ] : false );
129
349k
  m_sigGroupCtxId     = Ctx::SigCoeffGroup[m_chType]( sigRight | sigLower );
130
131
349k
  if( m_ts )
132
62.5k
  {
133
62.5k
    unsigned sigLeft  = unsigned( CGPosX > 0 ? m_sigCoeffGroupFlag[m_subSetPos - 1              ] : false );
134
62.5k
    unsigned sigAbove = unsigned( CGPosY > 0 ? m_sigCoeffGroupFlag[m_subSetPos - m_widthInGroups] : false );
135
62.5k
    m_sigGroupCtxIdTS = Ctx::TsSigCoeffGroup( sigLeft  + sigAbove );
136
62.5k
  }
137
349k
}
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
222k
{
224
222k
  if( ispIdx && isLuma( compID ) )
225
25.6k
  {
226
25.6k
    return 2 + ( int ) prevCbCbf;
227
25.6k
  }
228
196k
  if( compID == COMPONENT_Cr )
229
68.6k
  {
230
68.6k
    return ( prevCbCbf ? 1 : 0 );
231
68.6k
  }
232
128k
  return 0;
233
196k
}
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
112k
{
257
112k
  unsigned ctxId = 0;
258
259
  // Get BCBP of left PU
260
112k
  const CodingUnit *cuLeft  = cu.left;
261
112k
  ctxId  = ( cuLeft  && cuLeft->skip() )  ? 1 : 0;
262
263
  // Get BCBP of above PU
264
112k
  const CodingUnit *cuAbove = cu.above;
265
112k
  ctxId += ( cuAbove && cuAbove->skip() ) ? 1 : 0;
266
267
112k
  return ctxId;
268
112k
}
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
107k
{
282
107k
  unsigned ctxId = 0;
283
284
107k
  const CodingUnit *cuLeft  = cu.left;
285
107k
  ctxId += ( cuLeft  && CU::isIBC( *cuLeft ) )  ? 1 : 0;
286
287
107k
  const CodingUnit *cuAbove = cu.above;
288
107k
  ctxId += ( cuAbove && CU::isIBC( *cuAbove ) ) ? 1 : 0;
289
290
107k
  return ctxId;
291
107k
}
292
293
void MergeCtx::setMergeInfo( CodingUnit& cu, int candIdx )
294
11.0k
{
295
11.0k
  CHECK( candIdx >= numValidMergeCand, "Merge candidate does not exist" );
296
297
  //cu.setMergeFlag            ( true );
298
  //cu.setMmvdFlag             ( false );
299
11.0k
  cu.setInterDir             ( interDirNeighbours[candIdx] );
300
11.0k
  cu.setImv                  ( ( !cu.geoFlag() && useAltHpelIf[candIdx] ) ? IMV_HPEL : 0 );
301
  //cu.setMergeIdx             ( candIdx );
302
11.0k
  cu.setMergeType            ( mrgTypeNeighbours[candIdx] );
303
11.0k
  cu.mv  [REF_PIC_LIST_0][0] = mvFieldNeighbours[(candIdx << 1) + 0].mv;
304
11.0k
  cu.mv  [REF_PIC_LIST_1][0] = mvFieldNeighbours[(candIdx << 1) + 1].mv;
305
11.0k
  cu.refIdx [REF_PIC_LIST_0] = mvFieldNeighbours[( candIdx << 1 ) + 0].mfRefIdx;
306
11.0k
  cu.refIdx [REF_PIC_LIST_1] = mvFieldNeighbours[( candIdx << 1 ) + 1].mfRefIdx;
307
11.0k
  cu.mvpIdx [REF_PIC_LIST_0] = NOT_VALID;
308
11.0k
  cu.mvpIdx [REF_PIC_LIST_1] = NOT_VALID;
309
11.0k
  cu.setBcwIdx               ( ( interDirNeighbours[candIdx] == 3 ) ? BcwIdx[candIdx] : BCW_DEFAULT );
310
311
11.0k
  PU::restrictBiPredMergeCandsOne( cu );
312
11.0k
}
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
65.7k
{
493
65.7k
  unsigned ctxId = 0;
494
495
65.7k
  const CodingUnit *cuLeft  = cu.left;
496
65.7k
  ctxId  = ( cuLeft  && cuLeft->mipFlag()  ) ? 1 : 0;
497
498
65.7k
  const CodingUnit *cuAbove = cu.above;
499
65.7k
  ctxId += ( cuAbove && cuAbove->mipFlag() ) ? 1 : 0;
500
501
65.7k
  ctxId = ( cu.lwidth() > 2 * cu.lheight() || cu.lheight() > 2 * cu.lwidth() ) ? 3 : ctxId;
502
503
65.7k
  return ctxId;
504
65.7k
}
505
506
}