Coverage Report

Created: 2026-04-01 07:49

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
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
}