...
 
Commits (12)
......@@ -291,6 +291,12 @@ static const int AFFINE_MAX_NUM_V2 = 2; ///< max
static const int AFFINE_MAX_NUM_COMB = 12; ///< max number of combined motion candidates
static const int AFFINE_MIN_BLOCK_SIZE = 4; ///< Minimum affine MC block size
#if JVET_L0274
static const int MAX_NUM_REG_BINS_4x4SUBBLOCK = 32; ///< max number of context-coded bins (incl. gt2 bins) per 4x4 subblock
static const int MAX_NUM_GT2_BINS_4x4SUBBLOCK = 4; ///< max number of gt2 bins per 4x4 subblock
static const int MAX_NUM_REG_BINS_2x2SUBBLOCK = 8; ///< max number of context-coded bins (incl. gt2 bins) per 2x2 subblock (chroma)
static const int MAX_NUM_GT2_BINS_2x2SUBBLOCK = 2; ///< max number of gt2 bins per 2x2 subblock (chroma)
#endif
#if JVET_L0646_GBI
static const int GBI_NUM = 5; ///< the number of weight options
static const int GBI_DEFAULT = ((uint8_t)(GBI_NUM >> 1)); ///< Default weighting index representing for w=0.5
......
......@@ -107,7 +107,11 @@ public:
const int diag = posX + posY;
int numPos = 0;
int sumAbs = 0;
#if JVET_L0274
#define UPDATE(x) {int a=abs(x);sumAbs+=std::min(2+(a&1),a);numPos+=!!a;}
#else
#define UPDATE(x) {int a=abs(x);sumAbs+=std::min(4-(a&1),a);numPos+=!!a;}
#endif
if( posX < m_width-1 )
{
UPDATE( pData[1] );
......@@ -154,6 +158,36 @@ public:
unsigned greater1CtxIdAbs ( uint8_t offset ) const { return m_gtxFlagCtxSet[1]( offset ); }
unsigned greater2CtxIdAbs ( uint8_t offset ) const { return m_gtxFlagCtxSet[0]( offset ); }
#if JVET_L0274
unsigned templateAbsSum( int scanPos, const TCoeff* coeff )
{
const uint32_t posY = m_scanPosY[scanPos];
const uint32_t posX = m_scanPosX[scanPos];
const TCoeff* pData = coeff + posX + posY * m_width;
int sum = 0;
if (posX < m_width - 1)
{
sum += abs(pData[1]);
if (posX < m_width - 2)
{
sum += abs(pData[2]);
}
if (posY < m_height - 1)
{
sum += abs(pData[m_width + 1]);
}
}
if (posY < m_height - 1)
{
sum += abs(pData[m_width]);
if (posY < m_height - 2)
{
sum += abs(pData[m_width << 1]);
}
}
return std::min(sum, 31);
}
#else
unsigned GoRiceParAbs( int scanPos, const TCoeff* coeff ) const
{
#define UPDATE(x) sum+=abs(x)-!!x
......@@ -185,7 +219,7 @@ public:
int r = g_auiGoRicePars[ std::min( sum, 31 ) ];
return r;
}
#endif
unsigned emtNumSigCoeff() const { return m_emtNumSigCoeff; }
void setEmtNumSigCoeff( unsigned val ) { m_emtNumSigCoeff = val; }
......
......@@ -456,6 +456,44 @@ const CtxSet ContextSetCfg::SigCoeffGroup[] =
const CtxSet ContextSetCfg::SigFlag[] =
{
#if JVET_L0274
ContextSetCfg::addCtxSet
({
{ 120, 152, 167, 153, 168, 169, 119, 167, 197, 183, 183, 170, 209, 213, 183, 183, 169, 185, },
{ 149, 152, 167, 168, 183, 140, 149, 182, 168, 183, 169, 170, 195, 213, 183, 198, 184, 156, },
{ 120, 138, 153, 154, 140, 126, 120, 139, 154, 155, 155, 142, 137, 185, 169, 185, 171, 159, },
}),
ContextSetCfg::addCtxSet
({
{ 148, 167, 153, 139, 154, 140, 166, 199, 183, 184, 184, 157, },
{ 134, 168, 168, 139, 169, 155, 166, 229, 198, 229, 185, 157, },
{ 119, 168, 153, 140, 140, 141, 167, 200, 155, 172, 142, 158, },
}),
ContextSetCfg::addCtxSet
({
{ 152, 127, 173, 201, 187, 173, 226, 188, 188, 217, 188, 174, 182, 223, 223, 223, 223, 223, },
{ 123, 142, 202, 172, 157, 203, 138, 173, 218, 188, 173, 175, 168, 223, 223, 223, 223, 223, },
{ 108, 157, 173, 173, 218, 189, 123, 175, 159, 175, 190, 251, 79, 223, 223, 223, 223, 223, },
}),
ContextSetCfg::addCtxSet
({
{ 196, 156, 143, 158, 172, 216, 168, 223, 223, 223, 191, 223, },
{ 182, 141, 158, 186, 142, 173, 183, 223, 223, 223, 222, 223, },
{ 152, 158, 157, 187, 204, 175, 170, 223, 223, 237, 223, 223, },
}),
ContextSetCfg::addCtxSet
({
{ 137, 142, 189, 173, 187, 174, 241, 175, 175, 174, 174, 204, 210, 223, 223, 223, 223, 223, },
{ 123, 172, 175, 158, 158, 233, 138, 175, 190, 175, 188, 175, 196, 223, 223, 223, 223, 223, },
{ 107, 143, 219, 188, 233, 190, 63, 250, 205, 252, 220, 251, 63, 223, 223, 223, 223, 253, },
}),
ContextSetCfg::addCtxSet
({
{ 167, 185, 159, 158, 159, 189, 196, 223, 223, 223, 223, 223, },
{ 167, 141, 175, 143, 172, 159, 182, 223, 223, 223, 223, 223, },
{ 166, 159, 158, 232, 158, 174, 183, 238, 223, 223, 223, 223, },
}),
#else
ContextSetCfg::addCtxSet
({
{ 106, 167, 182, 124, 139, 169, 134, 167, 197, 183, 183, 184, 209, 198, 168, 168, 183, 170, CNU, CNU, },
......@@ -492,9 +530,55 @@ const CtxSet ContextSetCfg::SigFlag[] =
{ 167, 155, 159, 157, 157, 158, 182, 223, 223, 223, 223, 223, },
{ 181, 159, 143, 232, 143, 173, 169, 237, 223, 223, 238, 253, },
}),
#endif
};
#if JVET_L0274
const CtxSet ContextSetCfg::ParFlag[] =
{
ContextSetCfg::addCtxSet
({
{ 105, 119, 151, 152, 153, 153, 135, 152, 182, 153, 168, 136, 182, 153, 168, 139, 166, 168, 139, 168, 154, },
{ 120, 119, 151, 167, 138, 168, 135, 152, 153, 153, 139, 136, 153, 153, 168, 139, 137, 168, 168, 139, 139, },
{ 135, 150, 152, 138, 153, 153, 151, 123, 153, 168, 139, 152, 153, 153, 139, 139, 138, 168, 139, 154, 139, },
}),
ContextSetCfg::addCtxSet
({
{ 105, 135, 152, 167, 153, 124, 151, 168, 169, 153, 124, },
{ 134, 150, 152, 153, 153, 153, 166, 168, 168, 139, 139, },
{ 135, 121, 167, 168, 138, 153, 167, 139, 154, 139, 154, },
}),
};
const CtxSet ContextSetCfg::GtxFlag[] =
{
ContextSetCfg::addCtxSet
({
{ 73, 0, 58, 119, 150, 137, 42, 73, 120, 136, 123, 58, 149, 151, 152, 153, 134, 136, 152, 153, 125, },
{ 88, 0, 102, 104, 150, 122, 101, 89, 150, 151, 138, 88, 120, 122, 152, 153, 105, 107, 123, 153, 154, },
{ 134, 161, 149, 121, 122, 138, 88, 120, 107, 108, 109, 105, 107, 123, 109, 124, 151, 138, 139, 154, 140, },
}),
ContextSetCfg::addCtxSet
({
{ 87, 57, 90, 107, 107, 63, 119, 91, 152, 124, 140, },
{ 101, 0, 105, 121, 107, 93, 118, 106, 108, 124, 154, },
{ 179, 72, 90, 121, 122, 123, 75, 76, 123, 139, 170, },
}),
ContextSetCfg::addCtxSet
({
{ 89, 103, 121, 137, 138, 139, 119, 137, 138, 139, 125, 135, 167, 168, 154, 140, 136, 153, 183, 155, 185, },
{ 118, 0, 136, 152, 153, 154, 134, 152, 153, 139, 140, 150, 138, 139, 154, 155, 151, 153, 169, 140, 200, },
{ 164, 149, 137, 153, 124, 125, 151, 138, 139, 125, 125, 152, 139, 140, 140, 111, 153, 154, 155, 170, 127, },
}),
ContextSetCfg::addCtxSet
({
{ 27, 149, 137, 153, 139, 125, 151, 154, 170, 127, 127, },
{ 132, 135, 152, 139, 139, 125, 151, 154, 155, 141, 142, },
{ 165, 121, 138, 139, 139, 125, 138, 154, 156, 171, 127, },
}),
};
#else
const CtxSet ContextSetCfg::ParFlag[] =
{
ContextSetCfg::addCtxSet
......@@ -538,6 +622,7 @@ const CtxSet ContextSetCfg::GtxFlag[] =
{ 147, 73, 164, 151, 107, 109, 120, 152, 140, 185, 111, },
}),
};
#endif
const CtxSet ContextSetCfg::LastX[] =
{
......
This diff is collapsed.
This diff is collapsed.
......@@ -91,6 +91,11 @@ private:
const BinFracBits& fracBitsPar,
const BinFracBits& fracBitsGt1,
const BinFracBits& fracBitsGt2,
#if JVET_L0274
const int remGt2Bins,
const int remRegBins,
unsigned goRiceZero,
#endif
uint16_t ui16AbsGoRice,
int iQBits,
double errorScale,
......@@ -101,6 +106,11 @@ private:
const BinFracBits& fracBitsPar,
const BinFracBits& fracBitsGt1,
const BinFracBits& fracBitsGt2,
#if JVET_L0274
const int remGt2Bins,
const int remRegBins,
unsigned goRiceZero,
#endif
const uint16_t ui16AbsGoRice,
const bool useLimitedPrefixLength,
const int maxLog2TrDynamicRange ) const;
......
......@@ -660,6 +660,18 @@ const uint32_t g_uiMinInGroup[LAST_SIGNIFICANT_GROUPS] = { 0,1,2,3,4,6,8,12,16,2
const uint32_t g_uiGroupIdx[MAX_TU_SIZE] = { 0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9, 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11
,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12
,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 };
#if JVET_L0274
const uint32_t g_auiGoRiceParsCoeff[32] =
{
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3
};
const uint32_t g_auiGoRicePosCoeff0[3][32] =
{
{0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8},
{1, 1, 1, 1, 2, 3, 4, 4, 4, 6, 6, 6, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16},
{1, 1, 2, 2, 2, 3, 4, 4, 4, 6, 6, 6, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16}
};
#else
const uint32_t g_auiGoRicePars[ 32 ] =
{
0, 0, 0, 0,
......@@ -667,6 +679,7 @@ const uint32_t g_auiGoRicePars[ 32 ] =
0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 2, 2, 2, 2, 2, 2, 2
};
#endif
const uint32_t g_auiGoRiceRange[MAX_GR_ORDER_RESIDUAL] =
{
6, 5, 6, COEF_REMAIN_BIN_REDUCTION, COEF_REMAIN_BIN_REDUCTION, COEF_REMAIN_BIN_REDUCTION, COEF_REMAIN_BIN_REDUCTION, COEF_REMAIN_BIN_REDUCTION, COEF_REMAIN_BIN_REDUCTION, COEF_REMAIN_BIN_REDUCTION
......
......@@ -90,7 +90,12 @@ extern const uint32_t ctxIndMap4x4[4*4];
extern const uint32_t g_uiGroupIdx[ MAX_TU_SIZE ];
extern const uint32_t g_uiMinInGroup[ LAST_SIGNIFICANT_GROUPS ];
#if JVET_L0274
extern const uint32_t g_auiGoRiceParsCoeff [ 32 ];
extern const uint32_t g_auiGoRicePosCoeff0[ 3 ][ 32 ];
#else
extern const uint32_t g_auiGoRicePars [ 32 ];
#endif
extern const uint32_t g_auiGoRiceRange[ MAX_GR_ORDER_RESIDUAL ]; //!< maximum value coded with Rice codes
// ====================================================================================================================
......
......@@ -50,6 +50,8 @@
#include <assert.h>
#include <cassert>
#define JVET_L0090_PAIR_AVG 1 // Add pairwise average candidates, replace HEVC combined candidates
#define JVET_L0392_ALF_INIT_STATE 1
#define JVET_L0664_ALF_REMOVE_LUMA_5x5 1
......@@ -60,6 +62,15 @@
#define JVET_L0194_ONE_CTX_FOR_MRG_IDX 1 // one context for full-block Merge index
#define JVET_L0274 1
#define JVET_L0274_ENCODER_SPEED_UP ( 1 && JVET_L0274 ) // encoder speed-up by pre-calculating position dependent parameters
......@@ -71,6 +82,8 @@
#define REMOVE_MV_ADAPT_PREC 1 // remove the high precision flag in the MV class
#define JVET_L0093_SIMP_PRUNE 1
#ifndef JVET_B0051_NON_MPM_MODE
#define JVET_B0051_NON_MPM_MODE ( 1 && JEM_TOOLS )
#endif
......@@ -166,7 +179,11 @@
#define HM_EMT_NSST_AS_IN_JEM 1 //
#define HM_MDIS_AS_IN_JEM 1 // *** - PM: not filtering ref. samples for 64xn case and using Planar MDIS condition at encoder
#define HM_JEM_CLIP_PEL 1 // ***
#if JVET_L0093_SIMP_PRUNE
#define HM_JEM_MERGE_CANDS 0 // ***
#else
#define HM_JEM_MERGE_CANDS 1 // ***
#endif
#endif//JEM_COMP
......
......@@ -502,11 +502,16 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
const uint32_t maxNumMergeCand = slice.getMaxNumMergeCand();
const bool canFastExit = pu.cs->pps->getLog2ParallelMergeLevelMinus2() == 0;
#if !JVET_L0090_PAIR_AVG
// this variable is unused if remove HEVC combined candidates
bool isCandInter[MRG_MAX_NUM_CANDS];
#endif
for (uint32_t ui = 0; ui < maxNumMergeCand; ++ui)
{
#if !JVET_L0090_PAIR_AVG
isCandInter[ui] = false;
#endif
#if JVET_L0646_GBI
mrgCtx.GBiIdx[ui] = GBI_DEFAULT;
#endif
......@@ -535,7 +540,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
{
miLeft = puLeft->getMotionInfo( posLB.offset(-1, 0) );
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miLeft.interDir;
......@@ -576,7 +583,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( !isAvailableA1 || ( miAbove != miLeft ) )
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miAbove.interDir;
......@@ -621,7 +630,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( !isAvailableB1 || ( miAbove != miAboveRight ) )
#endif
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miAboveRight.interDir;
......@@ -665,7 +676,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( !isAvailableA1 || ( miBelowLeft != miLeft ) )
#endif
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miBelowLeft.interDir;
......@@ -715,7 +728,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( isAvailableSubPu )
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
mrgCtx.mrgTypeNeighbours[cnt] = MRG_TYPE_SUBPU_ATMVP;
......@@ -751,7 +766,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( ( !isAvailableA1 || ( miLeft != miAboveLeft ) ) && ( !isAvailableB1 || ( miAbove != miAboveLeft ) ) )
#endif
{
#if !JVET_L0090_PAIR_AVG
isCandInter[cnt] = true;
#endif
// get Inter Dir
mrgCtx.interDirNeighbours[cnt] = miAboveLeft.interDir;
......@@ -885,11 +902,12 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
if( addTMvp )
{
mrgCtx.interDirNeighbours[uiArrayAddr] = dir;
#if !JVET_L0090_PAIR_AVG
isCandInter [uiArrayAddr] = true;
#endif
#if JVET_L0646_GBI
mrgCtx.GBiIdx [uiArrayAddr] = GBI_DEFAULT;
mrgCtx.GBiIdx[uiArrayAddr] = GBI_DEFAULT;
#endif
isCandInter [uiArrayAddr] = true;
if( mrgCandIdx == cnt && canFastExit )
{
return;
......@@ -906,7 +924,97 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
return;
}
#if JVET_L0090_PAIR_AVG
// pairwise-average candidates
{
const int cutoff = std::min( cnt, 4 );
const int end = cutoff * (cutoff - 1) / 2;
constexpr int PRIORITY_LIST0[] = { 0, 0, 1, 0, 1, 2 };
constexpr int PRIORITY_LIST1[] = { 1, 2, 2, 3, 3, 3 };
for( int idx = 0; idx < end && cnt != maxNumMergeCand; idx++ )
{
const int i = PRIORITY_LIST0[idx];
const int j = PRIORITY_LIST1[idx];
mrgCtx.mvFieldNeighbours[cnt * 2].setMvField( Mv( 0, 0 ), NOT_VALID );
mrgCtx.mvFieldNeighbours[cnt * 2 + 1].setMvField( Mv( 0, 0 ), NOT_VALID );
// calculate average MV for L0 and L1 seperately
unsigned char interDir = 0;
for( int refListId = 0; refListId < (slice.isInterB() ? 2 : 1); refListId++ )
{
const short refIdxI = mrgCtx.mvFieldNeighbours[i * 2 + refListId].refIdx;
const short refIdxJ = mrgCtx.mvFieldNeighbours[j * 2 + refListId].refIdx;
// both MVs are invalid, skip
if( (refIdxI == NOT_VALID) && (refIdxJ == NOT_VALID) )
{
continue;
}
interDir += 1 << refListId;
// both MVs are valid, average these two MVs
if( (refIdxI != NOT_VALID) && (refIdxJ != NOT_VALID) )
{
const Mv& MvI = mrgCtx.mvFieldNeighbours[i * 2 + refListId].mv;
const Mv& MvJ = mrgCtx.mvFieldNeighbours[j * 2 + refListId].mv;
// average two MVs
Mv avgMv = MvI;
#if !REMOVE_MV_ADAPT_PREC
if( pu.cs->sps->getSpsNext().getUseHighPrecMv() )
{
avgMv.setHighPrec();
}
#endif
avgMv += MvJ;
avgMv.setHor( avgMv.getHor() / 2 );
avgMv.setVer( avgMv.getVer() / 2 );
mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( avgMv, refIdxI );
}
// only one MV is valid, take the only one MV
else if( refIdxI != NOT_VALID )
{
Mv singleMv = mrgCtx.mvFieldNeighbours[i * 2 + refListId].mv;
#if !REMOVE_MV_ADAPT_PREC
if( pu.cs->sps->getSpsNext().getUseHighPrecMv() )
{
singleMv.setHighPrec();
}
#endif
mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxI );
}
else if( refIdxJ != NOT_VALID )
{
Mv singleMv = mrgCtx.mvFieldNeighbours[j * 2 + refListId].mv;
#if !REMOVE_MV_ADAPT_PREC
if( pu.cs->sps->getSpsNext().getUseHighPrecMv() )
{
singleMv.setHighPrec();
}
#endif
mrgCtx.mvFieldNeighbours[cnt * 2 + refListId].setMvField( singleMv, refIdxJ );
}
}
mrgCtx.interDirNeighbours[cnt] = interDir;
if( interDir > 0 )
{
cnt++;
}
}
// early termination
if( cnt == maxNumMergeCand )
{
return;
}
}
#endif
uint32_t uiArrayAddr = cnt;
#if !JVET_L0090_PAIR_AVG
uint32_t uiCutoff = std::min( uiArrayAddr, 4u );
if (slice.isInterB())
......@@ -952,6 +1060,7 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
{
return;
}
#endif
int iNumRefIdx = slice.isInterB() ? std::min(slice.getNumRefIdx(REF_PIC_LIST_0), slice.getNumRefIdx(REF_PIC_LIST_1)) : slice.getNumRefIdx(REF_PIC_LIST_0);
......@@ -959,7 +1068,9 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx, co
int refcnt = 0;
while (uiArrayAddr < maxNumMergeCand)
{
#if !JVET_L0090_PAIR_AVG
isCandInter [uiArrayAddr ] = true;
#endif
mrgCtx.interDirNeighbours [uiArrayAddr ] = 1;
#if JVET_L0646_GBI
mrgCtx.GBiIdx [uiArrayAddr ] = GBI_DEFAULT;
......
......@@ -2216,7 +2216,10 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
}
uint8_t ctxOffset[16];
#if JVET_L0274
#else
unsigned nextPass = 0;
#endif
//===== decode absolute values =====
const int inferSigPos = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
......@@ -2225,9 +2228,20 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
int lastNZPos = -1;
#endif
int numNonZero = 0;
#if JVET_L0274
bool is2x2subblock = ( cctx.log2CGSize() == 2 );
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;
int firstPosMode1 = minSubPos - 1;
#endif
int sigBlkPos[ 1 << MLS_CG_SIZE ];
#if JVET_L0274
for( ; nextSigPos >= minSubPos && remRegBins >= 3; nextSigPos-- )
#else
for( ; nextSigPos >= minSubPos; nextSigPos-- )
#endif
{
int blkPos = cctx.blockPos( nextSigPos );
unsigned sigFlag = ( !numNonZero && nextSigPos == inferSigPos );
......@@ -2237,6 +2251,9 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
const unsigned sigCtxId = cctx.sigCtxIdAbs( nextSigPos, coeff, state );
sigFlag = m_BinDecoder.decodeBin( sigCtxId );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
#if JVET_L0274
remRegBins--;
#endif
}
if( sigFlag )
......@@ -2249,6 +2266,27 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
lastNZPos = std::max<int>( lastNZPos, nextSigPos );
#endif
#if JVET_L0274
RExt__DECODER_DEBUG_BIT_STATISTICS_SET( ctype_gt1 );
unsigned gt1Flag = m_BinDecoder.decodeBin( cctx.greater1CtxIdAbs(ctxOff) );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1Flag, cctx.greater1CtxIdAbs(ctxOff) );
remRegBins--;
unsigned parFlag = 0;
if( gt1Flag )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_SET( ctype_par );
parFlag = m_BinDecoder.decodeBin( cctx.parityCtxIdAbs( ctxOff ) );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", parFlag, cctx.parityCtxIdAbs( ctxOff ) );
remRegBins--;
if( remGt2Bins && !--remGt2Bins )
{
firstPosMode1 = nextSigPos - 1;
}
}
coeff[ blkPos ] += 1 + parFlag + gt1Flag;
#else
RExt__DECODER_DEBUG_BIT_STATISTICS_SET( ctype_par );
unsigned parFlag = m_BinDecoder.decodeBin( cctx.parityCtxIdAbs(ctxOff) );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", parFlag, cctx.parityCtxIdAbs(ctxOff) );
......@@ -2258,11 +2296,85 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1Flag, cctx.greater1CtxIdAbs(ctxOff) );
coeff[blkPos] += 1+parFlag+(gt1Flag<<1);
nextPass |= gt1Flag;
#endif
}
state = ( stateTransTable >> ((state<<2)+((coeff[blkPos]&1)<<1)) ) & 3;
}
#if JVET_L0274
firstPosMode2 = nextSigPos;
firstPosMode1 = ( firstPosMode1 > firstPosMode2 ? firstPosMode1 : firstPosMode2 );
#endif
#if JVET_L0274
//===== 2nd PASS: gt2 =====
for( int scanPos = firstSigPos; scanPos > firstPosMode1; scanPos-- )
{
TCoeff& tcoeff = coeff[ cctx.blockPos( scanPos ) ];
if( tcoeff >= 2 )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_SET( ctype_gt2 );
uint8_t& ctxOff = ctxOffset[ scanPos - minSubPos ];
unsigned gt2Flag = m_BinDecoder.decodeBin( cctx.greater2CtxIdAbs(ctxOff) );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2Flag, cctx.greater2CtxIdAbs(ctxOff) );
tcoeff += (gt2Flag<<1);
}
}
//===== 3rd PASS: Go-rice codes =====
unsigned ricePar = 0;
for( int scanPos = firstSigPos; scanPos > firstPosMode1; scanPos-- )
{
TCoeff& tcoeff = coeff[ cctx.blockPos( scanPos ) ];
if( tcoeff >= 4 )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_SET( ctype_escs );
int rem = m_BinDecoder.decodeRemAbsEP( ricePar, cctx.extPrec(), cctx.maxLog2TrDRange() );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
tcoeff += (rem<<1);
if( ricePar < 3 && rem > (3<<ricePar)-1 )
{
ricePar++;
}
}
}
for( int scanPos = firstPosMode1; scanPos > firstPosMode2; scanPos-- )
{
TCoeff& tcoeff = coeff[ cctx.blockPos( scanPos ) ];
if( tcoeff >= 2 )
{
RExt__DECODER_DEBUG_BIT_STATISTICS_SET( ctype_escs );
int rem = m_BinDecoder.decodeRemAbsEP( ricePar, cctx.extPrec(), cctx.maxLog2TrDRange() );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
tcoeff += (rem<<1);
if( ricePar < 3 && rem > (3<<ricePar)-1 )
{
ricePar++;
}
}
}
//===== coeff bypass ====
for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
{
int sumAll = cctx.templateAbsSum(scanPos, coeff);
int rice = g_auiGoRiceParsCoeff [sumAll];
int pos0 = g_auiGoRicePosCoeff0[std::max(0, state - 1)][sumAll];
int rem = m_BinDecoder.decodeRemAbsEP( rice, cctx.extPrec(), cctx.maxLog2TrDRange() );
DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
TCoeff tcoeff = ( rem == pos0 ? 0 : rem < pos0 ? rem+1 : rem );
state = ( stateTransTable >> ((state<<2)+((tcoeff&1)<<1)) ) & 3;
if( tcoeff )
{
int blkPos = cctx.blockPos( scanPos );
sigBlkPos[ numNonZero++ ] = blkPos;
#if HEVC_USE_SIGN_HIDING
lastNZPos = std::max<int>( lastNZPos, scanPos );
#endif
coeff[blkPos] = tcoeff;
}
}
#else
//===== 2nd PASS: gt2 =====
if( nextPass )
{
......@@ -2298,6 +2410,7 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
}
}
}
#endif
//===== decode sign's =====
RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET_SIZE2( STATS__CABAC_BITS__SIGN_BIT, Size( cctx.width(), cctx.height() ), cctx.compID() );
......
......@@ -2110,7 +2110,10 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
}
uint8_t ctxOffset[16];
#if JVET_L0274
#else
unsigned nextPass = 0;
#endif
//===== encode absolute values =====
const int inferSigPos = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
......@@ -2121,8 +2124,19 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
int remAbsLevel = -1;
int numNonZero = 0;
unsigned signPattern = 0;
#if JVET_L0274
bool is2x2subblock = ( cctx.log2CGSize() == 2 );
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;
int firstPosMode1 = minSubPos - 1;
#endif
#if JVET_L0274
for( ; nextSigPos >= minSubPos && remRegBins >= 3; nextSigPos-- )
#else
for( ; nextSigPos >= minSubPos; nextSigPos-- )
#endif
{
TCoeff Coeff = coeff[ cctx.blockPos( nextSigPos ) ];
unsigned sigFlag = ( Coeff != 0 );
......@@ -2131,6 +2145,9 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
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 );
#if JVET_L0274
remRegBins--;
#endif
}
if( sigFlag )
......@@ -2147,6 +2164,26 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
if( Coeff < 0 ) signPattern++;
#if JVET_L0274
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( remGt2Bins && !--remGt2Bins )
{
firstPosMode1 = nextSigPos - 1;
}
}
#else
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;
......@@ -2155,12 +2192,85 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
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) );
nextPass |= gt1;
#endif
}
state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
}
#if JVET_L0274
firstPosMode2 = nextSigPos;
firstPosMode1 = ( firstPosMode1 > firstPosMode2 ? firstPosMode1 : firstPosMode2 );
#endif
#if JVET_L0274
//===== 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) );
}
}
//===== 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++;
}
}
}
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++;
}
}
}
//===== 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++;
}
}
#else
//===== 2nd PASS: gt2 =====
if( nextPass )
{
......@@ -2194,6 +2304,7 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
}
}
}
#endif
//===== encode sign's =====
#if HEVC_USE_SIGN_HIDING
......