Newer
Older
{
break;
}
}
}
}
DTRACE(g_trace_ctx, D_SYNTAX, "MmvdStepMvpIdx() MmvdStepMvpIdx=%d\n", var1);
m_BinEncoder.encodeBinsEP(var2, 2);
DTRACE(g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", var2);
DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", pu.mmvdMergeIdx);
}

Karsten Suehring
committed
void CABACWriter::inter_pred_idc( const PredictionUnit& pu )
{
if( !pu.cs->slice->isInterB() )
{
return;
}

Karsten Suehring
committed
{
unsigned ctxId = DeriveCtx::CtxInterDir(pu);
if( pu.interDir == 3 )
{
m_BinEncoder.encodeBin( 1, Ctx::InterDir(ctxId) );
DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=%d value=%d pos=(%d,%d)\n", ctxId, pu.interDir, pu.lumaPos().x, pu.lumaPos().y );
return;
}
else
{
m_BinEncoder.encodeBin( 0, Ctx::InterDir(ctxId) );
}
}
m_BinEncoder.encodeBin( ( pu.interDir == 2 ), Ctx::InterDir( 4 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=4 value=%d pos=(%d,%d)\n", pu.interDir, pu.lumaPos().x, pu.lumaPos().y );
}
void CABACWriter::ref_idx( const PredictionUnit& pu, RefPicList eRefList )
{
if ( pu.cu->smvdMode )
{
CHECK( pu.refIdx[eRefList] != pu.cs->slice->getSymRefIdx( eRefList ), "Invalid reference index!\n" );
return;
}

Karsten Suehring
committed
int numRef = pu.cs->slice->getNumRefIdx(eRefList);
if (eRefList == REF_PIC_LIST_0 && pu.cs->sps->getIBCFlag())
{
if (CU::isIBC(*pu.cu))
return;
}

Karsten Suehring
committed
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
if( numRef <= 1 )
{
return;
}
int refIdx = pu.refIdx[eRefList];
m_BinEncoder.encodeBin( (refIdx > 0), Ctx::RefPic() );
if( numRef <= 2 || refIdx == 0 )
{
DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, pu.lumaPos().x, pu.lumaPos().y );
return;
}
m_BinEncoder.encodeBin( (refIdx > 1), Ctx::RefPic(1) );
if( numRef <= 3 || refIdx == 1 )
{
DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, pu.lumaPos().x, pu.lumaPos().y );
return;
}
for( int idx = 3; idx < numRef; idx++ )
{
if( refIdx > idx - 1 )
{
m_BinEncoder.encodeBinEP( 1 );
}
else
{
m_BinEncoder.encodeBinEP( 0 );
break;
}
}
DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, pu.lumaPos().x, pu.lumaPos().y );
}
void CABACWriter::mvp_flag( const PredictionUnit& pu, RefPicList eRefList )
{
m_BinEncoder.encodeBin( pu.mvpIdx[eRefList], Ctx::MVPIdx() );
DTRACE( g_trace_ctx, D_SYNTAX, "mvp_flag() value=%d pos=(%d,%d)\n", pu.mvpIdx[eRefList], pu.lumaPos().x, pu.lumaPos().y );
DTRACE( g_trace_ctx, D_SYNTAX, "mvpIdx(refList:%d)=%d\n", eRefList, pu.mvpIdx[eRefList] );
}
void CABACWriter::MHIntra_flag(const PredictionUnit& pu)
{
if (!pu.cs->sps->getUseMHIntra())
CHECK(pu.mhIntraFlag == true, "invalid MHIntra SPS");
return;
}
if (pu.cu->skip)
{
CHECK(pu.mhIntraFlag == true, "invalid MHIntra and skip");
return;
}
#if !JVET_O0249_MERGE_SYNTAX
if (pu.mmvdMergeFlag)
{
CHECK(pu.mhIntraFlag == true, "invalid MHIntra and mmvd");
return;
}
if (pu.cu->affine)
{
CHECK(pu.mhIntraFlag == true, "invalid MHIntra and affine");
return;
}
if (pu.cu->lwidth() * pu.cu->lheight() < 64 || pu.cu->lwidth() >= MAX_CU_SIZE || pu.cu->lheight() >= MAX_CU_SIZE)
{
CHECK(pu.mhIntraFlag == true, "invalid MHIntra and blk");
return;
}
m_BinEncoder.encodeBin(pu.mhIntraFlag, Ctx::MHIntraFlag());
DTRACE(g_trace_ctx, D_SYNTAX, "MHIntra_flag() MHIntra=%d pos=(%d,%d) size=%dx%d\n", pu.mhIntraFlag ? 1 : 0, pu.lumaPos().x, pu.lumaPos().y, pu.lumaSize().width, pu.lumaSize().height);

Karsten Suehring
committed
//================================================================================
// clause 7.3.8.7
//--------------------------------------------------------------------------------
// void pcm_samples( tu )
//================================================================================
void CABACWriter::pcm_samples( const TransformUnit& tu )
{
CHECK( !tu.cu->ipcm, "pcm mode expected" );
const SPS& sps = *tu.cu->cs->sps;
const CodingStructure *cs = tu.cs;
const ChannelType chType = tu.chType;
ComponentID compStr = (CS::isDualITree(*cs) && !isLuma(chType)) ? COMPONENT_Cb: COMPONENT_Y;
ComponentID compEnd = (CS::isDualITree(*cs) && isLuma(chType)) ? COMPONENT_Y : COMPONENT_Cr;
for( ComponentID compID = compStr; compID <= compEnd; compID = ComponentID(compID+1) )

Karsten Suehring
committed
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
{
const CPelBuf samples = tu.getPcmbuf( compID );
const unsigned sampleBits = sps.getPCMBitDepth( toChannelType(compID) );
for( unsigned y = 0; y < samples.height; y++ )
{
for( unsigned x = 0; x < samples.width; x++ )
{
m_BinEncoder.encodeBinsPCM( samples.at(x, y), sampleBits );
}
}
}
m_BinEncoder.restart();
}
//================================================================================
// clause 7.3.8.8
//--------------------------------------------------------------------------------
// void transform_tree ( cs, area, cuCtx, chromaCbfs )
// bool split_transform_flag( split, depth )
// bool cbf_comp ( cbf, area, depth )
//================================================================================
#if JVET_O0596_CBF_SIG_ALIGN_TO_SPEC
void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, const PartSplit ispType, const int subTuIdx )
#else
void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, ChromaCbfs& chromaCbfs, const PartSplit ispType, const int subTuIdx )
#endif

Karsten Suehring
committed
{
#if JVET_O0596_CBF_SIG_ALIGN_TO_SPEC
const UnitArea& area = partitioner.currArea();
int subTuCounter = subTuIdx;
const TransformUnit& tu = *cs.getTU(area.blocks[partitioner.chType].pos(), partitioner.chType, subTuIdx);
const CodingUnit& cu = *tu.cu;
const unsigned trDepth = partitioner.currTrDepth;
const bool split = (tu.depth > trDepth);
#else
ChromaCbfs chromaCbfsLastDepth;
chromaCbfsLastDepth.Cb = chromaCbfs.Cb;
chromaCbfsLastDepth.Cr = chromaCbfs.Cr;

Karsten Suehring
committed
const UnitArea& area = partitioner.currArea();
int subTuCounter = subTuIdx;
const TransformUnit& tu = *cs.getTU( area.blocks[partitioner.chType].pos(), partitioner.chType, subTuIdx );

Karsten Suehring
committed
const CodingUnit& cu = *tu.cu;
const unsigned trDepth = partitioner.currTrDepth;
const bool split = ( tu.depth > trDepth );
const bool chromaCbfISP = area.blocks[COMPONENT_Cb].valid() && cu.ispMode && !split;
bool max_tu_split = false;
#endif

Karsten Suehring
committed
// split_transform_flag

Karsten Suehring
committed
{
#if !JVET_O0596_CBF_SIG_ALIGN_TO_SPEC
max_tu_split = true;
#endif

Karsten Suehring
committed
}
else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
{
CHECK( !split, "transform split implied - sbt" );
}
CHECK( split && !cu.ispMode, "transform split not allowed with QTBT" );
#if !JVET_O0596_CBF_SIG_ALIGN_TO_SPEC

Karsten Suehring
committed
// cbf_cb & cbf_cr
if( area.chromaFormat != CHROMA_400 && area.blocks[COMPONENT_Cb].valid() && ( !CS::isDualITree( cs ) || partitioner.chType == CHANNEL_TYPE_CHROMA ) && ( !cu.ispMode || chromaCbfISP ) )

Karsten Suehring
committed
{
{
unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth;
if (!max_tu_split || chromaCbfISP)
{
chromaCbfs.Cb = TU::getCbfAtDepth( tu, COMPONENT_Cb, trDepth );
if( !( cu.sbtInfo && trDepth == 1 ) )
cbf_comp( cs, chromaCbfs.Cb, area.blocks[COMPONENT_Cb], cbfDepth );
}
if (!max_tu_split || chromaCbfISP)
{
chromaCbfs.Cr = TU::getCbfAtDepth( tu, COMPONENT_Cr, trDepth );
if( !( cu.sbtInfo && trDepth == 1 ) )
cbf_comp( cs, chromaCbfs.Cr, area.blocks[COMPONENT_Cr], cbfDepth, chromaCbfs.Cb );
}

Karsten Suehring
committed
}
}
else if( CS::isDualITree( cs ) )
{
chromaCbfs = ChromaCbfs( false );
}
#endif

Karsten Suehring
committed
if( split )
{
#if !JVET_O0596_CBF_SIG_ALIGN_TO_SPEC

Karsten Suehring
committed
if( area.chromaFormat != CHROMA_400 )
{
chromaCbfs.Cb = TU::getCbfAtDepth( tu, COMPONENT_Cb, trDepth );
chromaCbfs.Cr = TU::getCbfAtDepth( tu, COMPONENT_Cr, trDepth );
}
#endif

Karsten Suehring
committed
if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
{
#if ENABLE_TRACING
const CompArea &tuArea = partitioner.currArea().blocks[partitioner.chType];
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 );
#endif
partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
}
else if( cu.ispMode )
{
partitioner.splitCurrArea( ispType, cs );
}
else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
{
partitioner.splitCurrArea( PartSplit( cu.getSbtTuSplit() ), cs );
}

Karsten Suehring
committed
else
THROW( "Implicit TU split not available" );
do
{
#if JVET_O0596_CBF_SIG_ALIGN_TO_SPEC
transform_tree( cs, partitioner, cuCtx, ispType, subTuCounter );
#else

Karsten Suehring
committed
ChromaCbfs subChromaCbfs = chromaCbfs;
transform_tree( cs, partitioner, cuCtx, subChromaCbfs, ispType, subTuCounter );
#endif
subTuCounter += subTuCounter != -1 ? 1 : 0;

Karsten Suehring
committed
} while( partitioner.nextPart( cs ) );
partitioner.exitCurrSplit();
}
else
{
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 );
#if JVET_O0596_CBF_SIG_ALIGN_TO_SPEC
transform_unit( tu, cuCtx, partitioner, subTuCounter);
#else

Karsten Suehring
committed
if( !isChroma( partitioner.chType ) )
{
if( !CU::isIntra( cu ) && trDepth == 0 && !chromaCbfs.sigChroma( area.chromaFormat ) )
{
CHECK( !TU::getCbfAtDepth( tu, COMPONENT_Y, trDepth ), "Luma cbf must be true for inter units with no chroma coeffs" );
}
else if( cu.sbtInfo && tu.noResidual )
{
CHECK( TU::getCbfAtDepth( tu, COMPONENT_Y, trDepth ), "Luma cbf must be false for inter sbt no-residual tu" );
}
else if( cu.sbtInfo && !chromaCbfsLastDepth.sigChroma( area.chromaFormat ) )
{
assert( !tu.noResidual );
CHECK( !TU::getCbfAtDepth( tu, COMPONENT_Y, trDepth ), "Luma cbf must be true for inter sbt residual tu" );
}

Karsten Suehring
committed
else
{
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
bool previousCbf = false;
bool rootCbfSoFar = false;
bool lastCbfIsInferred = false;
if( cu.ispMode )
{
uint32_t nTus = cu.ispMode == HOR_INTRA_SUBPARTITIONS ? cu.lheight() >> g_aucLog2[tu.lheight()] : cu.lwidth() >> g_aucLog2[tu.lwidth()];
if( subTuCounter == nTus - 1 )
{
TransformUnit* tuPointer = cu.firstTU;
for( int tuIdx = 0; tuIdx < subTuCounter; tuIdx++ )
{
rootCbfSoFar |= TU::getCbfAtDepth( *tuPointer, COMPONENT_Y, trDepth );
tuPointer = tuPointer->next;
}
if( !rootCbfSoFar )
{
lastCbfIsInferred = true;
}
}
if( !lastCbfIsInferred )
{
previousCbf = TU::getPrevTuCbfAtDepth( tu, COMPONENT_Y, partitioner.currTrDepth );
}
}
if( !lastCbfIsInferred )
{
cbf_comp( cs, TU::getCbfAtDepth( tu, COMPONENT_Y, trDepth ), tu.Y(), trDepth, previousCbf, cu.ispMode );
}

Karsten Suehring
committed
}
}
transform_unit( tu, cuCtx, chromaCbfs );
#endif

Karsten Suehring
committed
}
}
Santiago de Luxán Hernández
committed
void CABACWriter::cbf_comp( const CodingStructure& cs, bool cbf, const CompArea& area, unsigned depth, const bool prevCbf, const bool useISP )
#if JVET_O0193_REMOVE_TR_DEPTH_IN_CBF_CTX
Santiago de Luxán Hernández
committed
const unsigned ctxId = DeriveCtx::CtxQtCbf( area.compID, prevCbf, useISP && isLuma(area.compID) );
Santiago de Luxán Hernández
committed
const unsigned ctxId = DeriveCtx::CtxQtCbf( area.compID, depth, prevCbf, useISP && isLuma(area.compID) );

Karsten Suehring
committed
const CtxSet& ctxSet = Ctx::QtCbf[ area.compID ];
if( area.compID == COMPONENT_Y && cs.getCU( area.pos(), ChannelType( area.compID ) )->bdpcmMode )
{
#if JVET_O0193_REMOVE_TR_DEPTH_IN_CBF_CTX
m_BinEncoder.encodeBin( cbf, ctxSet( 1 ) );
#else
m_BinEncoder.encodeBin( cbf, ctxSet( 4 ) );

Karsten Suehring
committed
m_BinEncoder.encodeBin( cbf, ctxSet( ctxId ) );

Karsten Suehring
committed
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 );
}
//================================================================================
// clause 7.3.8.9
//--------------------------------------------------------------------------------
// void mvd_coding( pu, refList )
//================================================================================
void CABACWriter::mvd_coding( const Mv &rMvd, int8_t imv )

Karsten Suehring
committed
{
int horMvd = rMvd.getHor();
int verMvd = rMvd.getVer();

Karsten Suehring
committed
{
#if JVET_O0057_ALTHPELIF
CHECK((horMvd % 2) != 0 && (verMvd % 2) != 0, "IMV: MVD is not a multiple of 2");
horMvd >>= 1;
verMvd >>= 1;
if (imv < IMV_HPEL)
{
CHECK((horMvd % 2) != 0 && (verMvd % 2) != 0, "IMV: MVD is not a multiple of 4");
horMvd >>= 1;
verMvd >>= 1;
if (imv == IMV_4PEL)//IMV_4PEL
{
CHECK((horMvd % 4) != 0 && (verMvd % 4) != 0, "IMV: MVD is not a multiple of 16");
horMvd >>= 2;
verMvd >>= 2;
}
}
#else

Karsten Suehring
committed
CHECK( (horMvd % 4) != 0 && (verMvd % 4) != 0, "IMV: MVD is not a multiple of 4" );
horMvd >>= 2;
verMvd >>= 2;
if( imv == 2 )//IMV_4PEL
{
CHECK( (horMvd % 4) != 0 && (verMvd % 4) != 0, "IMV: MVD is not a multiple of 16" );

Karsten Suehring
committed
horMvd >>= 2;
verMvd >>= 2;
}

Karsten Suehring
committed
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
}
unsigned horAbs = unsigned( horMvd < 0 ? -horMvd : horMvd );
unsigned verAbs = unsigned( verMvd < 0 ? -verMvd : verMvd );
// abs_mvd_greater0_flag[ 0 | 1 ]
m_BinEncoder.encodeBin( (horAbs > 0), Ctx::Mvd() );
m_BinEncoder.encodeBin( (verAbs > 0), Ctx::Mvd() );
// abs_mvd_greater1_flag[ 0 | 1 ]
if( horAbs > 0 )
{
m_BinEncoder.encodeBin( (horAbs > 1), Ctx::Mvd(1) );
}
if( verAbs > 0 )
{
m_BinEncoder.encodeBin( (verAbs > 1), Ctx::Mvd(1) );
}
// abs_mvd_minus2[ 0 | 1 ] and mvd_sign_flag[ 0 | 1 ]
if( horAbs > 0 )
{
if( horAbs > 1 )
{
exp_golomb_eqprob( horAbs - 2, 1 );
}
m_BinEncoder.encodeBinEP( (horMvd < 0) );
}
if( verAbs > 0 )
{
if( verAbs > 1 )
{
exp_golomb_eqprob( verAbs - 2, 1 );
}
m_BinEncoder.encodeBinEP( (verMvd < 0) );
}
}
//================================================================================
// clause 7.3.8.10
//--------------------------------------------------------------------------------
// void transform_unit ( tu, cuCtx, chromaCbfs )
// void cu_qp_delta ( cu )
// void cu_chroma_qp_offset ( cu )
//================================================================================
#if JVET_O0596_CBF_SIG_ALIGN_TO_SPEC
void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, Partitioner& partitioner, const int subTuCounter)
#else

Karsten Suehring
committed
void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, ChromaCbfs& chromaCbfs )
#endif

Karsten Suehring
committed
{
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
#if JVET_O0596_CBF_SIG_ALIGN_TO_SPEC
const CodingStructure& cs = *tu.cs;
const CodingUnit& cu = *tu.cu;
const UnitArea& area = partitioner.currArea();
const unsigned trDepth = partitioner.currTrDepth;
const bool chromaCbfISP = area.blocks[COMPONENT_Cb].valid() && cu.ispMode;
ChromaCbfs chromaCbfs;
CHECK(tu.depth != trDepth, " transform unit should be not be futher partitioned");
// cbf_cb & cbf_cr
if (area.chromaFormat != CHROMA_400 && area.blocks[COMPONENT_Cb].valid() && (!CS::isDualITree(cs) || partitioner.chType == CHANNEL_TYPE_CHROMA) && (!cu.ispMode || chromaCbfISP))
{
{
unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth;
{
chromaCbfs.Cb = TU::getCbfAtDepth(tu, COMPONENT_Cb, trDepth);
//if (!(cu.sbtInfo && trDepth == 1))
if (!(cu.sbtInfo && tu.noResidual))
cbf_comp(cs, chromaCbfs.Cb, area.blocks[COMPONENT_Cb], cbfDepth);
}
{
chromaCbfs.Cr = TU::getCbfAtDepth(tu, COMPONENT_Cr, trDepth);
//if (!(cu.sbtInfo && trDepth == 1))
if (!(cu.sbtInfo && tu.noResidual))
cbf_comp(cs, chromaCbfs.Cr, area.blocks[COMPONENT_Cr], cbfDepth, chromaCbfs.Cb);
}
}
}
else if (CS::isDualITree(cs))
{
chromaCbfs = ChromaCbfs(false);
}
if (!isChroma(partitioner.chType))
{
if (!CU::isIntra(cu) && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat))
{
CHECK(!TU::getCbfAtDepth(tu, COMPONENT_Y, trDepth), "Luma cbf must be true for inter units with no chroma coeffs");
}
else if (cu.sbtInfo && tu.noResidual)
{
CHECK(TU::getCbfAtDepth(tu, COMPONENT_Y, trDepth), "Luma cbf must be false for inter sbt no-residual tu");
}
else if (cu.sbtInfo && !chromaCbfs.sigChroma(area.chromaFormat))
{
assert(!tu.noResidual);
CHECK(!TU::getCbfAtDepth(tu, COMPONENT_Y, trDepth), "Luma cbf must be true for inter sbt residual tu");
}
else
{
bool previousCbf = false;
bool rootCbfSoFar = false;
bool lastCbfIsInferred = false;
if (cu.ispMode)
{
uint32_t nTus = cu.ispMode == HOR_INTRA_SUBPARTITIONS ? cu.lheight() >> g_aucLog2[tu.lheight()] : cu.lwidth() >> g_aucLog2[tu.lwidth()];
if (subTuCounter == nTus - 1)
{
TransformUnit* tuPointer = cu.firstTU;
for (int tuIdx = 0; tuIdx < subTuCounter; tuIdx++)
{
rootCbfSoFar |= TU::getCbfAtDepth(*tuPointer, COMPONENT_Y, trDepth);
tuPointer = tuPointer->next;
}
if (!rootCbfSoFar)
{
lastCbfIsInferred = true;
}
}
if (!lastCbfIsInferred)
{
previousCbf = TU::getPrevTuCbfAtDepth(tu, COMPONENT_Y, partitioner.currTrDepth);
}
}
if (!lastCbfIsInferred)
{
cbf_comp(cs, TU::getCbfAtDepth(tu, COMPONENT_Y, trDepth), tu.Y(), trDepth, previousCbf, cu.ispMode);
}
}
}
#else

Karsten Suehring
committed
CodingUnit& cu = *tu.cu;
#endif

Karsten Suehring
committed
bool lumaOnly = ( cu.chromaFormat == CHROMA_400 || !tu.blocks[COMPONENT_Cb].valid() );
bool cbf[3] = { TU::getCbf( tu, COMPONENT_Y ), chromaCbfs.Cb, chromaCbfs.Cr };
bool cbfLuma = ( cbf[ COMPONENT_Y ] != 0 );
bool cbfChroma = false;
Santiago de Luxán Hernández
committed
if( !lumaOnly )

Karsten Suehring
committed
{
if( tu.blocks[COMPONENT_Cb].valid() )
{
cbf [ COMPONENT_Cb ] = TU::getCbf( tu, COMPONENT_Cb );
cbf [ COMPONENT_Cr ] = TU::getCbf( tu, COMPONENT_Cr );
}
cbfChroma = ( cbf[ COMPONENT_Cb ] || cbf[ COMPONENT_Cr ] );
}
#if JVET_O0105_ICT
if( !lumaOnly )
{
joint_cb_cr( tu, ( cbf[COMPONENT_Cb] ? 2 : 0 ) + ( cbf[COMPONENT_Cr] ? 1 : 0 ) );
}
#endif
Brian Heng
committed
#if JVET_O0046_DQ_SIGNALLING
if( cu.lwidth() > 64 || cu.lheight() > 64 || cbfLuma || cbfChroma )
#else

Karsten Suehring
committed
if( cbfLuma || cbfChroma )
Brian Heng
committed
#endif

Karsten Suehring
committed
{
if( cu.cs->pps->getUseDQP() && !cuCtx.isDQPCoded )
{

Christian Helmrich
committed
if (!CS::isDualITree(*tu.cs) || isLuma(tu.chType))
{
cu_qp_delta(cu, cuCtx.qp, cu.qp);
cuCtx.qp = cu.qp;
cuCtx.isDQPCoded = true;
}

Karsten Suehring
committed
}
#if JVET_O1168_CU_CHROMA_QP_OFFSET
if (cu.cs->slice->getUseChromaQpAdj() && cbfChroma && !cuCtx.isChromaQpAdjCoded)
#else

Karsten Suehring
committed
if( cu.cs->slice->getUseChromaQpAdj() && cbfChroma && !cu.transQuantBypass && !cuCtx.isChromaQpAdjCoded )

Karsten Suehring
committed
{
cu_chroma_qp_offset( cu );
cuCtx.isChromaQpAdjCoded = true;
}
if( cbfLuma )
{
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS
residual_coding( tu, COMPONENT_Y, &cuCtx );
#else

Karsten Suehring
committed
residual_coding( tu, COMPONENT_Y );

Karsten Suehring
committed
}
if( !lumaOnly )
{
for( ComponentID compID = COMPONENT_Cb; compID <= COMPONENT_Cr; compID = ComponentID( compID + 1 ) )
{
if( TU::hasCrossCompPredInfo( tu, compID ) )
{
cross_comp_pred( tu, compID );
}
if( cbf[ compID ] )
{
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS
residual_coding( tu, compID, &cuCtx );
#else

Karsten Suehring
committed
residual_coding( tu, compID );

Karsten Suehring
committed
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
}
}
}
}
}
void CABACWriter::cu_qp_delta( const CodingUnit& cu, int predQP, const int8_t qp )
{
CHECK(!( predQP != std::numeric_limits<int>::max()), "Unspecified error");
int DQp = qp - predQP;
int qpBdOffsetY = cu.cs->sps->getQpBDOffset( CHANNEL_TYPE_LUMA );
DQp = ( DQp + (MAX_QP + 1) + (MAX_QP + 1) / 2 + qpBdOffsetY + (qpBdOffsetY / 2)) % ((MAX_QP + 1) + qpBdOffsetY) - (MAX_QP + 1) / 2 - (qpBdOffsetY / 2);
unsigned absDQP = unsigned( DQp < 0 ? -DQp : DQp );
unsigned unaryDQP = std::min<unsigned>( absDQP, CU_DQP_TU_CMAX );
unary_max_symbol( unaryDQP, Ctx::DeltaQP(), Ctx::DeltaQP(1), CU_DQP_TU_CMAX );
if( absDQP >= CU_DQP_TU_CMAX )
{
exp_golomb_eqprob( absDQP - CU_DQP_TU_CMAX, CU_DQP_EG_k );
}
if( absDQP > 0 )
{
m_BinEncoder.encodeBinEP( DQp < 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 );
}
void CABACWriter::cu_chroma_qp_offset( const CodingUnit& cu )
{
// cu_chroma_qp_offset_flag
unsigned qpAdj = cu.chromaQpAdj;
if( qpAdj == 0 )
{
m_BinEncoder.encodeBin( 0, Ctx::ChromaQpAdjFlag() );
}
else
{
m_BinEncoder.encodeBin( 1, Ctx::ChromaQpAdjFlag() );
int length = cu.cs->pps->getPpsRangeExtension().getChromaQpOffsetListLen();
if( length > 1 )
{
unary_max_symbol( qpAdj-1, Ctx::ChromaQpAdjIdc(), Ctx::ChromaQpAdjIdc(), length-1 );
}
}
}
//================================================================================
// clause 7.3.8.11
//--------------------------------------------------------------------------------
// void residual_coding ( tu, compID )
// void transform_skip_flag ( tu, compID )
// void explicit_rdpcm_mode ( tu, compID )
// void last_sig_coeff ( coeffCtx )
// void residual_coding_subblock( coeffCtx )
//================================================================================
#if JVET_O0105_ICT
void CABACWriter::joint_cb_cr( const TransformUnit& tu, const int cbfMask )
{
CHECK( tu.jointCbCr && tu.jointCbCr != cbfMask, "wrong value of jointCbCr (" << (int)tu.jointCbCr << " vs " << (int)cbfMask << ")" );
#if JVET_O0543_ICT_ICU_ONLY
if( ( CU::isIntra( *tu.cu ) && cbfMask ) || ( cbfMask == 3 ) )
#else
if( cbfMask )
#endif
{
m_BinEncoder.encodeBin( tu.jointCbCr ? 1 : 0, Ctx::JointCbCrFlag( cbfMask - 1 ) );
}
}
#else
void CABACWriter::joint_cb_cr( const TransformUnit& tu )
{
m_BinEncoder.encodeBin( tu.jointCbCr ? 1 : 0, Ctx::JointCbCrFlag( 0 ) );
}
#if JVET_O0094_LFNST_ZERO_PRIM_COEFFS || JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx )
#else
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID)
#endif

Karsten Suehring
committed
{
const CodingUnit& cu = *tu.cu;
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 );
#if JVET_O0105_ICT
if( compID == COMPONENT_Cr && tu.jointCbCr == 3 )
return;
#else
// Joint Cb-Cr residual mode is signalled if both Cb and Cr cbfs are true
if ( compID == COMPONENT_Cr && TU::getCbf( tu, COMPONENT_Cb ) )
{
joint_cb_cr( tu );
// No Cr residual in bitstream in joint Cb-Cr residual mode
if ( tu.jointCbCr )
return;
}

Karsten Suehring
committed
// code transform skip and explicit rdpcm mode

Karsten Suehring
committed
explicit_rdpcm_mode( tu, compID );
if( isLuma( compID ) && ( tu.mtsIdx == MTS_SKIP || tu.cu->bdpcmMode ) )
{
residual_codingTS( tu, compID );
return;
}

Karsten Suehring
committed
// determine sign hiding
bool signHiding = ( cu.cs->slice->getSignDataHidingEnabledFlag() && !cu.transQuantBypass && tu.rdpcm[compID] == RDPCM_OFF );
if( signHiding && CU::isIntra(cu) && CU::isRDPCMEnabled(cu) && tu.mtsIdx==MTS_SKIP )

Karsten Suehring
committed
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
{
const ChannelType chType = toChannelType( compID );
const unsigned intraMode = PU::getFinalIntraMode( *cu.cs->getPU( tu.blocks[compID].pos(), chType ), chType );
if( intraMode == HOR_IDX || intraMode == VER_IDX )
{
signHiding = false;
}
}
// init coeff coding context
CoeffCodingContext cctx ( tu, compID, signHiding );
const TCoeff* coeff = tu.getCoeffs( compID ).buf;
// determine and set last coeff position and sig group flags
int scanPosLast = -1;
std::bitset<MLS_GRP_NUM> sigGroupFlags;
for( int scanPos = 0; scanPos < cctx.maxNumCoeff(); scanPos++)
{
unsigned blkPos = cctx.blockPos( scanPos );
if( coeff[blkPos] )
{
scanPosLast = scanPos;
sigGroupFlags.set( scanPos >> cctx.log2CGSize() );
}
}
CHECK( scanPosLast < 0, "Coefficient coding called for empty TU" );
cctx.setScanPosLast(scanPosLast);
if( cuCtx && tu.mtsIdx != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
{
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;
cuCtx->violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos;
}
#endif
#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS
if( cuCtx && tu.mtsIdx != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
{
cuCtx->lastScanPos[compID] = cctx.scanPosLast();
}

Karsten Suehring
committed
// code last coeff position

Karsten Suehring
committed
// code subblocks
const int stateTab = ( tu.cs->slice->getDepQuantEnabledFlag() ? 32040 : 0 );
int state = 0;
#if JVET_O0052_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT
int ctxBinSampleRatio = (compID == COMPONENT_Y) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA;
cctx.regBinLimit = (tu.getTbAreaAfterCoefZeroOut(compID) * ctxBinSampleRatio) >> 4;
#endif

Karsten Suehring
committed
for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--)
{
cctx.initSubblock ( subSetId, sigGroupFlags[subSetId] );
if( ( tu.mtsIdx > MTS_SKIP || ( tu.cu->sbtInfo != 0 && tu.blocks[ compID ].height <= 32 && tu.blocks[ compID ].width <= 32 ) ) && !tu.cu->transQuantBypass && compID == COMPONENT_Y )
{
if( ( tu.blocks[ compID ].height == 32 && cctx.cgPosY() >= ( 16 >> cctx.log2CGHeight() ) )
|| ( tu.blocks[ compID ].width == 32 && cctx.cgPosX() >= ( 16 >> cctx.log2CGWidth() ) ) )
{
continue;
}
}
residual_coding_subblock( cctx, coeff, stateTab, state );

Karsten Suehring
committed
}
}
void CABACWriter::mts_coding( const TransformUnit& tu, ComponentID compID )
{
const bool tsAllowed = TU::isTSAllowed ( tu, compID );
const bool mtsAllowed = TU::isMTSAllowed( tu, compID );
if( !mtsAllowed && !tsAllowed ) return;
int symbol = 0;
int ctxIdx = 0;
if( tsAllowed )
{
#if JVET_O0294_TRANSFORM_CLEANUP
symbol = (tu.mtsIdx == MTS_SKIP) ? 1 : 0;
#else
symbol = (tu.mtsIdx == MTS_SKIP) ? 0 : 1;
ctxIdx = 6;
m_BinEncoder.encodeBin( symbol, Ctx::MTSIndex( ctxIdx ) );
}
symbol = tu.mtsIdx != MTS_DCT2_DCT2 ? 1 : 0;
#if JVET_O0294_TRANSFORM_CLEANUP
ctxIdx = 0;
#else

Karsten Suehring
committed
if( symbol )
{
ctxIdx = 7;
for( int i = 0; i < 3; i++, ctxIdx++ )
{
symbol = tu.mtsIdx > i + MTS_DST7_DST7 ? 1 : 0;
m_BinEncoder.encodeBin( symbol, Ctx::MTSIndex( ctxIdx ) );
if( !symbol )
{
break;
}
}
}
}
}
#if JVET_O0294_TRANSFORM_CLEANUP
DTRACE( g_trace_ctx, D_SYNTAX, "mts_coding() etype=%d pos=(%d,%d) mtsIdx=%d\n", COMPONENT_Y, tu.cu->lx(), tu.cu->ly(), tu.mtsIdx);
#else
DTRACE( g_trace_ctx, D_SYNTAX, "mts_coding() etype=%d pos=(%d,%d) mtsIdx=%d\n", COMPONENT_Y, cu.lx(), cu.ly(), tu.mtsIdx );

Karsten Suehring
committed
void CABACWriter::isp_mode( const CodingUnit& cu )
{
Santiago de Luxán Hernández
committed
if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx || cu.ipcm || !cu.cs->sps->getUseISP() || cu.bdpcmMode || !CU::canUseISP( cu, getFirstComponentOfChannel( cu.chType ) ) )
Santiago de Luxán Hernández
committed
CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "cu.ispMode != 0" );
return;
}
Santiago de Luxán Hernández
committed
if ( cu.ispMode == NOT_INTRA_SUBPARTITIONS )
{
m_BinEncoder.encodeBin( 0, Ctx::ISPMode( 0 ) );
}
else
{
m_BinEncoder.encodeBin( 1, Ctx::ISPMode( 0 ) );
Santiago de Luxán Hernández
committed
m_BinEncoder.encodeBin( cu.ispMode - 1, Ctx::ISPMode( 1 ) );
}
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 );
}

Karsten Suehring
committed
void CABACWriter::explicit_rdpcm_mode( const TransformUnit& tu, ComponentID compID )
{
const CodingUnit& cu = *tu.cu;
if( !CU::isIntra(cu) && CU::isRDPCMEnabled(cu) && ( tu.mtsIdx==MTS_SKIP || cu.transQuantBypass ) )

Karsten Suehring
committed
{
ChannelType chType = toChannelType( compID );
switch( tu.rdpcm[compID] )
{
case RDPCM_VER:
m_BinEncoder.encodeBin( 1, Ctx::RdpcmFlag(chType) );
m_BinEncoder.encodeBin( 1, Ctx::RdpcmDir (chType) );
break;
case RDPCM_HOR:
m_BinEncoder.encodeBin( 1, Ctx::RdpcmFlag(chType) );
m_BinEncoder.encodeBin( 0, Ctx::RdpcmDir (chType) );
break;
default: // RDPCM_OFF
m_BinEncoder.encodeBin( 0, Ctx::RdpcmFlag(chType) );
}
}
}
void CABACWriter::residual_lfnst_mode( const CodingUnit& cu, CUCtx& cuCtx )
{
if( cu.ispMode != NOT_INTRA_SUBPARTITIONS || cu.mipFlag == true ||
( CS::isDualITree( *cu.cs ) && cu.chType == CHANNEL_TYPE_CHROMA && std::min( cu.blocks[ 1 ].width, cu.blocks[ 1 ].height ) < 4 )
#if JVET_O0213_RESTRICT_LFNST_TO_MAX_TB_SIZE
|| ( cu.blocks[ 0 ].width > MAX_TB_SIZEY || cu.blocks[ 0 ].height > MAX_TB_SIZEY )
#endif
)
{
return;
}
if( cu.cs->sps->getUseLFNST() && CU::isIntra( cu ) && !CU::isLosslessCoded( cu ) )
{
const bool lumaFlag = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? true : false ) : true;
const bool chromaFlag = CS::isDualITree( *cu.cs ) ? ( isChroma( cu.chType ) ? true : false ) : true;
#if !JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS
bool nonZeroCoeffNonTs;
bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_LUMA] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] );
#else
bool nonZeroCoeffNonTsCorner8x8 = CU::getNumNonZeroCoeffNonTsCorner8x8( cu, lumaFlag, chromaFlag ) > 0;
#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS
const bool skipLfnst = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? ( cuCtx.lastScanPos[ COMPONENT_Y ] < LFNST_LAST_SIG_LUMA ) :
( cuCtx.lastScanPos[ COMPONENT_Cb ] < LFNST_LAST_SIG_CHROMA && cuCtx.lastScanPos[ COMPONENT_Cr ] < LFNST_LAST_SIG_CHROMA ) ) :
( cuCtx.lastScanPos[ COMPONENT_Y ] < LFNST_LAST_SIG_LUMA && cuCtx.lastScanPos[ COMPONENT_Cb ] < LFNST_LAST_SIG_CHROMA && cuCtx.lastScanPos[ COMPONENT_Cr ] < LFNST_LAST_SIG_CHROMA );
#else
const int nonZeroCoeffThr = CS::isDualITree( *cu.cs ) ? ( isLuma( cu.chType ) ? LFNST_SIG_NZ_LUMA : LFNST_SIG_NZ_CHROMA ) : LFNST_SIG_NZ_LUMA + LFNST_SIG_NZ_CHROMA;
cuCtx.numNonZeroCoeffNonTs = CU::getNumNonZeroCoeffNonTs( cu, lumaFlag, chromaFlag );
nonZeroCoeffNonTs = cuCtx.numNonZeroCoeffNonTs > nonZeroCoeffThr;
Hilmi Egilmez
committed
#if JVET_O0368_LFNST_WITH_DCT2_ONLY
const bool isNonDCT2 = (TU::getCbf(*cu.firstTU, ComponentID(COMPONENT_Y)) && cu.firstTU->mtsIdx != MTS_DCT2_DCT2);
#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS
if( skipLfnst || nonZeroCoeffNonTsCorner8x8 || isNonDCT2 )
#else
Hilmi Egilmez
committed
if (!nonZeroCoeffNonTs || nonZeroCoeffNonTsCorner8x8 || isNonDCT2 )
#endif
#else
#if JVET_O0472_LFNST_SIGNALLING_LAST_SCAN_POS
if( skipLfnst || nonZeroCoeffNonTsCorner8x8 )
Hilmi Egilmez
committed
#else
if( !nonZeroCoeffNonTs || nonZeroCoeffNonTsCorner8x8 )
Hilmi Egilmez
committed
#endif
{
return;
}
}
else
{
return;
}
unsigned cctx = 0;
Hilmi Egilmez
committed
#if JVET_O0368_LFNST_WITH_DCT2_ONLY
if ( CS::isDualITree(*cu.cs) ) cctx++;
#else
#if JVET_O0545_MAX_TB_SIGNALLING
if( ( cu.firstTU->mtsIdx < MTS_DST7_DST7 || !TU::getCbf(*cu.firstTU, COMPONENT_Y) ) && CS::isDualITree( *cu.cs ) ) cctx++;
Hilmi Egilmez
committed
#else
if( cu.firstTU->mtsIdx < MTS_DST7_DST7 && CS::isDualITree( *cu.cs ) ) cctx++;
Hilmi Egilmez
committed
#endif
const uint32_t idxLFNST = cu.lfnstIdx;
assert( idxLFNST < 3 );
m_BinEncoder.encodeBin( idxLFNST ? 1 : 0, Ctx::LFNSTIdx( cctx ) );
if( idxLFNST )
{
m_BinEncoder.encodeBinEP( ( idxLFNST - 1 ) ? 1 : 0 );
}
DTRACE( g_trace_ctx, D_SYNTAX, "residual_lfnst_mode() etype=%d pos=(%d,%d) mode=%d\n", COMPONENT_Y, cu.lx(), cu.ly(), ( int ) cu.lfnstIdx );
}

Karsten Suehring
committed
void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit& tu, ComponentID compID )

Karsten Suehring
committed
{
unsigned blkPos = cctx.blockPos( cctx.scanPosLast() );
unsigned posX, posY;
{
posY = blkPos / cctx.width();
posX = blkPos - ( posY * cctx.width() );
}
unsigned CtxLast;
unsigned GroupIdxX = g_uiGroupIdx[ posX ];
unsigned GroupIdxY = g_uiGroupIdx[ posY ];
unsigned maxLastPosX = cctx.maxLastPosX();
unsigned maxLastPosY = cctx.maxLastPosY();