Newer
Older
m_BinEncoder.encodeBinEP(mpm_idx > 1);
}
}
DTRACE(g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) mode=%d\n", k, pu->lumaPos().x, pu->lumaPos().y, pu->intraDir[0]);
pu = pu->next;
}
}

Karsten Suehring
committed
void CABACWriter::triangle_mode( const CodingUnit& cu )
{
if( !cu.cs->slice->getSPS()->getSpsNext().getUseTriangle() || !cu.cs->slice->isInterB() || cu.lwidth() * cu.lheight() < TRIANGLE_MIN_SIZE || cu.affine )
{
return;
}
Ruoyang Yu
committed
#if JVET_M0118_M0185_TRIANGLE_FLAG_FIX
if ( cu.firstPU->mmvdMergeFlag || cu.mmvdSkip )
{
return;
}
if ( cu.firstPU->mhIntraFlag )
{
return;
}
#endif
unsigned flag_idx = DeriveCtx::CtxTriangleFlag( cu );
m_BinEncoder.encodeBin( cu.triangle, Ctx::TriangleFlag(flag_idx) );
DTRACE( g_trace_ctx, D_SYNTAX, "triangle_mode() triangle_mode=%d pos=(%d,%d) size: %dx%d\n", cu.triangle, cu.Y().x, cu.Y().y, cu.lumaSize().width, cu.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
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
{
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_M0102_INTRA_SUBPARTITIONS
void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, ChromaCbfs& chromaCbfs, const PartSplit ispType, const int subTuIdx )
#else

Karsten Suehring
committed
void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, ChromaCbfs& chromaCbfs )

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

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

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

Karsten Suehring
committed
// split_transform_flag

Karsten Suehring
committed
{

Karsten Suehring
committed
}
#if JVET_M0102_INTRA_SUBPARTITIONS
CHECK( split && !cu.ispMode, "transform split not allowed with QTBT" );
#else
CHECK( split, "transform split not allowed with QTBT" );
#endif

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

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

Karsten Suehring
committed
{
{
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
#if JVET_M0102_INTRA_SUBPARTITIONS
unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth;
if( trDepth == 0 || chromaCbfs.Cb || chromaCbfISP )
{
chromaCbfs.Cb = TU::getCbfAtDepth( tu, COMPONENT_Cb, trDepth );
cbf_comp( cs, chromaCbfs.Cb, area.blocks[COMPONENT_Cb], cbfDepth );
}
else
{
CHECK( TU::getCbfAtDepth( tu, COMPONENT_Cb, cbfDepth ) != chromaCbfs.Cb, "incorrect Cb cbf" );
}
if( trDepth == 0 || chromaCbfs.Cr || chromaCbfISP )
{
chromaCbfs.Cr = TU::getCbfAtDepth( tu, COMPONENT_Cr, trDepth );
cbf_comp( cs, chromaCbfs.Cr, area.blocks[COMPONENT_Cr], cbfDepth, chromaCbfs.Cb );
}
else
{
CHECK( TU::getCbfAtDepth( tu, COMPONENT_Cr, cbfDepth ) != chromaCbfs.Cr, "incorrect Cr cbf" );
}
#else

Karsten Suehring
committed
if( trDepth == 0 || chromaCbfs.Cb )
{
chromaCbfs.Cb = TU::getCbfAtDepth( tu, COMPONENT_Cb, trDepth );
cbf_comp( cs, chromaCbfs.Cb, area.blocks[COMPONENT_Cb], trDepth );
}
else
{
CHECK( TU::getCbfAtDepth( tu, COMPONENT_Cb, trDepth ) != chromaCbfs.Cb, "incorrect Cb cbf" );
}
if( trDepth == 0 || chromaCbfs.Cr )
{
chromaCbfs.Cr = TU::getCbfAtDepth( tu, COMPONENT_Cr, trDepth );
cbf_comp( cs, chromaCbfs.Cr, area.blocks[COMPONENT_Cr], trDepth, chromaCbfs.Cb );
}
else
{
CHECK( TU::getCbfAtDepth( tu, COMPONENT_Cr, trDepth ) != chromaCbfs.Cr, "incorrect Cr cbf" );
}

Karsten Suehring
committed
}
}
else if( CS::isDualITree( cs ) )
{
chromaCbfs = ChromaCbfs( false );
}
if( split )
{
if( area.chromaFormat != CHROMA_400 )
{
chromaCbfs.Cb = TU::getCbfAtDepth( tu, COMPONENT_Cb, trDepth );
chromaCbfs.Cr = TU::getCbfAtDepth( tu, COMPONENT_Cr, trDepth );
}
#if JVET_M0102_INTRA_SUBPARTITIONS
if ( trDepth == 0 && !cu.ispMode ) emt_cu_flag( cu );
#else

Karsten Suehring
committed
if( trDepth == 0 ) emt_cu_flag( cu );

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 );
}
#if JVET_M0102_INTRA_SUBPARTITIONS
else if( cu.ispMode )
{
partitioner.splitCurrArea( ispType, cs );
}
#endif

Karsten Suehring
committed
else
THROW( "Implicit TU split not available" );
do
{
ChromaCbfs subChromaCbfs = chromaCbfs;
#if JVET_M0102_INTRA_SUBPARTITIONS
transform_tree( cs, partitioner, cuCtx, subChromaCbfs, ispType, subTuCounter );
subTuCounter += subTuCounter != -1 ? 1 : 0;
#else

Karsten Suehring
committed
transform_tree( cs, partitioner, cuCtx, subChromaCbfs );

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( !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
{
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
#if JVET_M0102_INTRA_SUBPARTITIONS
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
cbf_comp( cs, TU::getCbfAtDepth( tu, COMPONENT_Y, trDepth ), tu.Y(), trDepth );

Karsten Suehring
committed
}
}

Karsten Suehring
committed
if( trDepth == 0 && TU::getCbfAtDepth( tu, COMPONENT_Y, 0 ) ) emt_cu_flag( cu );

Karsten Suehring
committed
transform_unit( tu, cuCtx, chromaCbfs );
}
}
#if JVET_M0102_INTRA_SUBPARTITIONS
void CABACWriter::cbf_comp( const CodingStructure& cs, bool cbf, const CompArea& area, unsigned depth, const bool prevCbCbf, const bool useISP )
{
const unsigned ctxId = DeriveCtx::CtxQtCbf( area.compID, depth, prevCbCbf, useISP && isLuma(area.compID) );
#else

Karsten Suehring
committed
void CABACWriter::cbf_comp( const CodingStructure& cs, bool cbf, const CompArea& area, unsigned depth, const bool prevCbCbf )
{
const unsigned ctxId = DeriveCtx::CtxQtCbf( area.compID, depth, prevCbCbf );

Karsten Suehring
committed
const CtxSet& ctxSet = Ctx::QtCbf[ area.compID ];
m_BinEncoder.encodeBin( cbf, ctxSet( ctxId ) );
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 )
//================================================================================
#if JVET_M0246_AFFINE_AMVR
void CABACWriter::mvd_coding( const Mv &rMvd, int8_t imv )
#else

Karsten Suehring
committed
void CABACWriter::mvd_coding( const Mv &rMvd, uint8_t imv )

Karsten Suehring
committed
{
int horMvd = rMvd.getHor();
int verMvd = rMvd.getVer();
#if JVET_M0246_AFFINE_AMVR
if ( imv > 0 )
#else

Karsten Suehring
committed
if( imv )

Karsten Suehring
committed
2305
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
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
{
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 8" );
horMvd >>= 2;
verMvd >>= 2;
}
}
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 )
//================================================================================
void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, ChromaCbfs& chromaCbfs )
{
CodingUnit& cu = *tu.cu;
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;
if( cu.chromaFormat != CHROMA_400 )
{
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( cbfLuma || cbfChroma )
{
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
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
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
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
}
if( cu.cs->slice->getUseChromaQpAdj() && cbfChroma && !cu.transQuantBypass && !cuCtx.isChromaQpAdjCoded )
{
cu_chroma_qp_offset( cu );
cuCtx.isChromaQpAdjCoded = true;
}
if( cbfLuma )
{
residual_coding( tu, COMPONENT_Y );
}
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 ] )
{
residual_coding( tu, compID );
}
}
}
}
}
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 )
//================================================================================
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID )
{
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 );
// code transform skip and explicit rdpcm mode
#if JVET_M0464_UNI_MTS
mts_coding ( tu, compID );
#else

Karsten Suehring
committed
transform_skip_flag( tu, compID );

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

Karsten Suehring
committed
if( signHiding && CU::isIntra(cu) && CU::isRDPCMEnabled(cu) && tu.transformSkip[compID] )

Karsten Suehring
committed
{
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;
}
}
#endif
// init coeff coding context
#if HEVC_USE_SIGN_HIDING
CoeffCodingContext cctx ( tu, compID, signHiding );
#else
CoeffCodingContext cctx ( tu, compID );
#endif
const TCoeff* coeff = tu.getCoeffs( compID ).buf;

Karsten Suehring
committed
unsigned numSig = 0;

Karsten Suehring
committed
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
// 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);
// code last coeff position
last_sig_coeff( cctx );
// code subblocks
const int stateTab = ( tu.cs->slice->getDepQuantEnabledFlag() ? 32040 : 0 );
int state = 0;

Karsten Suehring
committed
bool useEmt = ( cu.cs->sps->getSpsNext().getUseIntraEMT() && cu.predMode == MODE_INTRA ) || ( cu.cs->sps->getSpsNext().getUseInterEMT() && cu.predMode != MODE_INTRA );
useEmt = useEmt && isLuma(compID);
#if JVET_M0102_INTRA_SUBPARTITIONS
useEmt = useEmt && !cu.ispMode;
#endif

Karsten Suehring
committed
for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--)
{
cctx.initSubblock ( subSetId, sigGroupFlags[subSetId] );
residual_coding_subblock( cctx, coeff, stateTab, state );

Karsten Suehring
committed
if (useEmt)
{
numSig += cctx.emtNumSigCoeff();
cctx.setEmtNumSigCoeff( 0 );
}

Karsten Suehring
committed
}

Karsten Suehring
committed
if( useEmt && !tu.transformSkip[compID] && compID == COMPONENT_Y && tu.cu->emtFlag )
{
if( CU::isIntra( *tu.cu ) )
{

Karsten Suehring
committed
}
else
{
emt_tu_index( tu );
}
}

Karsten Suehring
committed
}
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
#if JVET_M0464_UNI_MTS
void CABACWriter::mts_coding( const TransformUnit& tu, ComponentID compID )
{
const CodingUnit &cu = *tu.cu;
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 )
{
symbol = 1 - ( tu.mtsIdx == 1 ? 1 : 0 );
ctxIdx = 6;
m_BinEncoder.encodeBin( symbol, Ctx::MTSIndex( ctxIdx ) );
}
if( tu.mtsIdx != 1 )
{
if( mtsAllowed )
{
symbol = tu.mtsIdx != 0 ? 1 : 0;
ctxIdx = std::min( (int)cu.qtDepth, 5 );
m_BinEncoder.encodeBin( symbol, Ctx::MTSIndex( ctxIdx ) );

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

Karsten Suehring
committed
void CABACWriter::transform_skip_flag( const TransformUnit& tu, ComponentID compID )
{
#if JVET_M0102_INTRA_SUBPARTITIONS
if (!tu.cu->cs->pps->getUseTransformSkip() || tu.cu->transQuantBypass || !TU::hasTransformSkipFlag(*tu.cs, tu.blocks[compID]) || (isLuma(compID) && tu.cu->emtFlag) || (tu.cu->ispMode && isLuma(compID)))
#else

Karsten Suehring
committed
if( !tu.cu->cs->pps->getUseTransformSkip() || tu.cu->transQuantBypass || !TU::hasTransformSkipFlag( *tu.cs, tu.blocks[compID] ) || ( isLuma( compID ) && tu.cu->emtFlag ) )

Karsten Suehring
committed
{
return;
}
m_BinEncoder.encodeBin( tu.transformSkip[compID], Ctx::TransformSkipFlag(toChannelType(compID)) );
DTRACE( g_trace_ctx, D_SYNTAX, "transform_skip_flag() etype=%d pos=(%d,%d) trSkip=%d\n", compID, tu.blocks[compID].x, tu.blocks[compID].y, (int)tu.transformSkip[compID] );
}
void CABACWriter::emt_tu_index( const TransformUnit& tu )
{
int maxSizeEmtIntra = EMT_INTRA_MAX_CU_WITH_QTBT;
int maxSizeEmtInter = EMT_INTER_MAX_CU_WITH_QTBT;

Karsten Suehring
committed
if( CU::isIntra( *tu.cu ) && ( tu.cu->Y().width <= maxSizeEmtIntra ) && ( tu.cu->Y().height <= maxSizeEmtIntra ) )
{
uint8_t trIdx = tu.emtIdx;
m_BinEncoder.encodeBin( ( trIdx & 1 ) ? 1 : 0, Ctx::EMTTuIndex( 0 ) );
m_BinEncoder.encodeBin( ( trIdx / 2 ) ? 1 : 0, Ctx::EMTTuIndex( 1 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "emt_tu_index() etype=%d pos=(%d,%d) emtTrIdx=%d\n", COMPONENT_Y, tu.blocks[COMPONENT_Y].x, tu.blocks[COMPONENT_Y].y, ( int ) tu.emtIdx );
}
if( !CU::isIntra( *tu.cu ) && ( tu.cu->Y().width <= maxSizeEmtInter ) && ( tu.cu->Y().height <= maxSizeEmtInter ) )
{
uint8_t trIdx = tu.emtIdx;
m_BinEncoder.encodeBin( ( trIdx & 1 ) ? 1 : 0, Ctx::EMTTuIndex( 2 ) );
m_BinEncoder.encodeBin( ( trIdx / 2 ) ? 1 : 0, Ctx::EMTTuIndex( 3 ) );
DTRACE( g_trace_ctx, D_SYNTAX, "emt_tu_index() etype=%d pos=(%d,%d) emtTrIdx=%d\n", COMPONENT_Y, tu.blocks[COMPONENT_Y].x, tu.blocks[COMPONENT_Y].y, ( int ) tu.emtIdx );
}
}
//void CABACWriter::emt_cu_flag(const CodingUnit& cu, uint32_t depth, bool codeCuFlag, const int tuWidth,const int tuHeight)
void CABACWriter::emt_cu_flag( const CodingUnit& cu )
{
#if JVET_M0102_INTRA_SUBPARTITIONS
if ( CU::isIntra( cu ) && cu.ispMode )
{
return;
}
#endif

Karsten Suehring
committed
const CodingStructure& cs = *cu.cs;
if (!((cs.sps->getSpsNext().getUseIntraEMT() && CU::isIntra(cu)) || (cs.sps->getSpsNext().getUseInterEMT() && !CU::isIntra(cu))) || isChroma(cu.chType))
#else

Karsten Suehring
committed
if( !( ( cs.sps->getSpsNext().getUseIntraEMT() && CU::isIntra( cu ) ) || ( cs.sps->getSpsNext().getUseInterEMT() && CU::isInter( cu ) ) ) || isChroma( cu.chType ) )

Karsten Suehring
committed
{
return;
}
unsigned depth = cu.qtDepth;
const unsigned cuWidth = cu.lwidth();
const unsigned cuHeight = cu.lheight();

Karsten Suehring
committed
{

Karsten Suehring
committed
}
int maxSizeEmtIntra = EMT_INTRA_MAX_CU_WITH_QTBT;
int maxSizeEmtInter = EMT_INTER_MAX_CU_WITH_QTBT;

Karsten Suehring
committed
const unsigned maxSizeEmt = CU::isIntra( cu ) ? maxSizeEmtIntra : maxSizeEmtInter;
if( cuWidth <= maxSizeEmt && cuHeight <= maxSizeEmt )
{
m_BinEncoder.encodeBin( cu.emtFlag, Ctx::EMTCuFlag( depth ) );
DTRACE( g_trace_ctx, D_SYNTAX, "emt_cu_flag() etype=%d pos=(%d,%d) emtCuFlag=%d\n", COMPONENT_Y, cu.lx(), cu.ly(), ( int ) cu.emtFlag );
}
}

Karsten Suehring
committed
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
#if JVET_M0102_INTRA_SUBPARTITIONS
void CABACWriter::isp_mode( const CodingUnit& cu )
{
if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.firstPU->multiRefIdx )
{
CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "error: cu.intraSubPartitions != 0" );
return;
}
const ISPType allowedSplits = CU::canUseISPSplit( cu, getFirstComponentOfChannel( cu.chType ) );
if( allowedSplits == NOT_INTRA_SUBPARTITIONS ) return;
if( cu.ispMode == NOT_INTRA_SUBPARTITIONS )
{
m_BinEncoder.encodeBin( 0, Ctx::ISPMode( 0 ) );
}
else
{
m_BinEncoder.encodeBin( 1, Ctx::ISPMode( 0 ) );
if( allowedSplits == CAN_USE_VER_AND_HORL_SPLITS )
{
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 );
}
#endif

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

Karsten Suehring
committed
if( !CU::isIntra(cu) && CU::isRDPCMEnabled(cu) && ( tu.transformSkip[compID] || cu.transQuantBypass ) )

Karsten Suehring
committed
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
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
{
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::last_sig_coeff( CoeffCodingContext& cctx )
{
unsigned blkPos = cctx.blockPos( cctx.scanPosLast() );
unsigned posX, posY;
#if HEVC_USE_MDCS
if( cctx.scanType() == SCAN_VER )
{
posX = blkPos / cctx.width();
posY = blkPos - ( posX * cctx.width() );
}
else
#endif
{
posY = blkPos / cctx.width();
posX = blkPos - ( posY * cctx.width() );
}
unsigned CtxLast;
unsigned GroupIdxX = g_uiGroupIdx[ posX ];
unsigned GroupIdxY = g_uiGroupIdx[ posY ];
for( CtxLast = 0; CtxLast < GroupIdxX; CtxLast++ )
{
m_BinEncoder.encodeBin( 1, cctx.lastXCtxId( CtxLast ) );
}
if( GroupIdxX < cctx.maxLastPosX() )
{
m_BinEncoder.encodeBin( 0, cctx.lastXCtxId( CtxLast ) );
}
for( CtxLast = 0; CtxLast < GroupIdxY; CtxLast++ )
{
m_BinEncoder.encodeBin( 1, cctx.lastYCtxId( CtxLast ) );
}
if( GroupIdxY < cctx.maxLastPosY() )
{
m_BinEncoder.encodeBin( 0, cctx.lastYCtxId( CtxLast ) );
}
if( GroupIdxX > 3 )
{
posX -= g_uiMinInGroup[ GroupIdxX ];
for (int i = ( ( GroupIdxX - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
{
m_BinEncoder.encodeBinEP( ( posX >> i ) & 1 );
}
}
if( GroupIdxY > 3 )
{
posY -= g_uiMinInGroup[ GroupIdxY ];
for ( int i = ( ( GroupIdxY - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
{
m_BinEncoder.encodeBinEP( ( posY >> i ) & 1 );
}
}
}
void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoeff* coeff, const int stateTransTable, int& state )
{
//===== init =====
const int minSubPos = cctx.minSubPos();
const bool isLast = cctx.isLast();
int firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
int nextSigPos = firstSigPos;
//===== encode significant_coeffgroup_flag =====
if( !isLast && cctx.isNotFirst() )
{
if( cctx.isSigGroup() )
{
m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId() );
}
else
{
m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId() );
return;
}
}
uint8_t ctxOffset[16];
//===== encode absolute values =====
const int inferSigPos = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
#if HEVC_USE_SIGN_HIDING
int firstNZPos = nextSigPos;
int lastNZPos = -1;
#endif
int remAbsLevel = -1;
int numNonZero = 0;
unsigned signPattern = 0;
bool is2x2subblock = ( cctx.log2CGSize() == 2 );
#if JVET_M0173_MOVE_GT2_TO_FIRST_PASS
int remRegBins = ( is2x2subblock ? MAX_NUM_REG_BINS_2x2SUBBLOCK : MAX_NUM_REG_BINS_4x4SUBBLOCK );
#else
int remGt2Bins = ( is2x2subblock ? MAX_NUM_GT2_BINS_2x2SUBBLOCK : MAX_NUM_GT2_BINS_4x4SUBBLOCK );
int remRegBins = ( is2x2subblock ? MAX_NUM_REG_BINS_2x2SUBBLOCK : MAX_NUM_REG_BINS_4x4SUBBLOCK ) - remGt2Bins;
int firstPosMode2 = minSubPos - 1;
#if !JVET_M0173_MOVE_GT2_TO_FIRST_PASS
int firstPosMode1 = minSubPos - 1;

Karsten Suehring
committed
#if JVET_M0173_MOVE_GT2_TO_FIRST_PASS
for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- )
#else
for( ; nextSigPos >= minSubPos && remRegBins >= 3; nextSigPos-- )

Karsten Suehring
committed
{
TCoeff Coeff = coeff[ cctx.blockPos( nextSigPos ) ];
unsigned sigFlag = ( Coeff != 0 );
if( numNonZero || nextSigPos != inferSigPos )
{
const unsigned sigCtxId = cctx.sigCtxIdAbs( nextSigPos, coeff, state );
m_BinEncoder.encodeBin( sigFlag, sigCtxId );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
remRegBins--;

Karsten Suehring
committed
}
if( sigFlag )
{
uint8_t& ctxOff = ctxOffset[ nextSigPos - minSubPos ];
ctxOff = cctx.ctxOffsetAbs();
numNonZero++;
#if HEVC_USE_SIGN_HIDING
firstNZPos = nextSigPos;
lastNZPos = std::max<int>( lastNZPos, nextSigPos );
#endif
remAbsLevel = abs( Coeff ) - 1;
if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
if( Coeff < 0 ) signPattern++;
unsigned gt1 = !!remAbsLevel;
m_BinEncoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) );
remRegBins--;
if( gt1 )
{
remAbsLevel -= 1;
m_BinEncoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
remAbsLevel >>= 1;
remRegBins--;
#if JVET_M0173_MOVE_GT2_TO_FIRST_PASS
unsigned gt2 = !!remAbsLevel;
m_BinEncoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff));
DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff));
remRegBins--;
#else
if( remGt2Bins && !--remGt2Bins )
{
firstPosMode1 = nextSigPos - 1;
}

Karsten Suehring
committed
}
state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
}
firstPosMode2 = nextSigPos;
#if !JVET_M0173_MOVE_GT2_TO_FIRST_PASS
firstPosMode1 = ( firstPosMode1 > firstPosMode2 ? firstPosMode1 : firstPosMode2 );

Karsten Suehring
committed
#if !JVET_M0173_MOVE_GT2_TO_FIRST_PASS
//===== 2nd PASS: gt2 =====
for( int scanPos = firstSigPos; scanPos > firstPosMode1; scanPos-- )
{
unsigned absLevel = abs( coeff[ cctx.blockPos( scanPos ) ] );
if( absLevel >= 2 )
{
uint8_t& ctxOff = ctxOffset[ scanPos - minSubPos ];
unsigned gt2 = ( absLevel >= 4 );
m_BinEncoder.encodeBin( gt2, cctx.greater2CtxIdAbs(ctxOff) );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff) );
}
}
#if JVET_M0173_MOVE_GT2_TO_FIRST_PASS
//===== 2nd PASS: Go-rice codes =====
unsigned ricePar = 0;
for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
#else
//===== 3rd PASS: Go-rice codes =====
unsigned ricePar = 0;
for( int scanPos = firstSigPos; scanPos > firstPosMode1; scanPos-- )
{
unsigned absLevel = abs( coeff[ cctx.blockPos( scanPos ) ] );
if( absLevel >= 4 )
{
unsigned rem = ( absLevel - 4 ) >> 1;
m_BinEncoder.encodeRemAbsEP( rem, ricePar, cctx.extPrec(), cctx.maxLog2TrDRange() );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
if( ricePar < 3 && rem > (3<<ricePar)-1 )
{
ricePar++;
}
}
}
#if !JVET_M0173_MOVE_GT2_TO_FIRST_PASS
for( int scanPos = firstPosMode1; scanPos > firstPosMode2; scanPos-- )
{
unsigned absLevel = abs( coeff[ cctx.blockPos( scanPos ) ] );
if( absLevel >= 2 )
{
unsigned rem = ( absLevel - 2 ) >> 1;
m_BinEncoder.encodeRemAbsEP( rem, ricePar, cctx.extPrec(), cctx.maxLog2TrDRange() );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
if( ricePar < 3 && rem > (3<<ricePar)-1 )
{
ricePar++;
}
}
}
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
//===== coeff bypass ====
for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
{
TCoeff Coeff = coeff[ cctx.blockPos( scanPos ) ];
unsigned absLevel = abs( Coeff );
int sumAll = cctx.templateAbsSum(scanPos, coeff);
int rice = g_auiGoRiceParsCoeff [sumAll];
int pos0 = g_auiGoRicePosCoeff0[std::max(0, state - 1)][sumAll];
unsigned rem = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
m_BinEncoder.encodeRemAbsEP( rem, rice, cctx.extPrec(), cctx.maxLog2TrDRange() );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
if( absLevel )
{
numNonZero++;
#if HEVC_USE_SIGN_HIDING
lastNZPos = std::max<int>( lastNZPos, scanPos );
#endif
signPattern <<= 1;
if( Coeff < 0 ) signPattern++;
}
}

Karsten Suehring
committed
//===== encode sign's =====
#if HEVC_USE_SIGN_HIDING
unsigned numSigns = numNonZero;