WIP : JVET-M0102 -> Intra Sub-Partitions (ISP)

There is a conflict with JVET_M0427_INLOOP_RESHAPER that is triggering a debug assertion that checks that the width is not 1.
parent 6e31833c
......@@ -389,12 +389,14 @@ void AreaBuf<Pel>::rspSignal(std::vector<Pel>& pLUT)
{
Pel* dst = buf;
Pel* src = buf;
#if !JVET_M0102_INTRA_SUBPARTITIONS
if (width == 1)
{
THROW("Blocks of width = 1 not supported");
}
else
{
#endif
for (unsigned y = 0; y < height; y++)
{
for (unsigned x = 0; x < width; x++)
......@@ -404,7 +406,9 @@ void AreaBuf<Pel>::rspSignal(std::vector<Pel>& pLUT)
dst += stride;
src += stride;
}
#if !JVET_M0102_INTRA_SUBPARTITIONS
}
#endif
}
template<>
......@@ -456,13 +460,14 @@ template<>
Pel AreaBuf <Pel> ::computeAvg() const
{
const Pel* src = buf;
#if !JVET_M0102_INTRA_SUBPARTITIONS
if (width == 1)
{
THROW("Blocks of width = 1 not supported");
}
else
{
#endif
int32_t acc = 0;
#define AVG_INC \
src += stride;
......@@ -471,7 +476,9 @@ Pel AreaBuf <Pel> ::computeAvg() const
#undef AVG_INC
#undef AVG_OP
return Pel((acc + (area() >> 1)) / area());
#if !JVET_M0102_INTRA_SUBPARTITIONS
}
#endif
}
#endif
......
......@@ -68,6 +68,10 @@ enum CodingStatisticsType
STATS__CABAC_BITS__MVD_EP,
STATS__CABAC_BITS__AFFINE_FLAG,
STATS__CABAC_BITS__AFFINE_TYPE,
#if JVET_M0102_INTRA_SUBPARTITIONS
STATS__CABAC_BITS__ISP_MODE_FLAG,
STATS__CABAC_BITS__ISP_SPLIT_FLAG,
#endif
STATS__CABAC_BITS__TRANSFORM_SUBDIV_FLAG,
STATS__CABAC_BITS__QT_ROOT_CBF,
STATS__CABAC_BITS__DELTA_QP_EP,
......@@ -150,6 +154,10 @@ static inline const char* getName(CodingStatisticsType name)
"CABAC_BITS__MVD_EP",
"CABAC_BITS__AFFINE_FLAG",
"CABAC_BITS__AFFINE_TYPE",
#if JVET_M0102_INTRA_SUBPARTITIONS
"CABAC_BITS__ISP_MODE_FLAG",
"CABAC_BITS__ISP_SPLIT_FLAG",
#endif
"CABAC_BITS__TRANSFORM_SUBDIV_FLAG",
"CABAC_BITS__QT_ROOT_CBF",
"CABAC_BITS__DELTA_QP_EP",
......
......@@ -259,7 +259,11 @@ const PredictionUnit * CodingStructure::getPU( const Position &pos, const Channe
}
}
#if JVET_M0102_INTRA_SUBPARTITIONS
TransformUnit* CodingStructure::getTU( const Position &pos, const ChannelType effChType, const int subTuIdx )
#else
TransformUnit* CodingStructure::getTU( const Position &pos, const ChannelType effChType )
#endif
{
const CompArea &_blk = area.blocks[effChType];
......@@ -272,13 +276,45 @@ TransformUnit* CodingStructure::getTU( const Position &pos, const ChannelType ef
{
const unsigned idx = m_tuIdx[effChType][rsAddr( pos, _blk.pos(), _blk.width, unitScale[effChType] )];
#if JVET_M0102_INTRA_SUBPARTITIONS
if( idx != 0 )
{
unsigned extraIdx = 0;
if( isLuma( effChType ) )
{
const TransformUnit& tu = *tus[idx - 1];
if( tu.cu->ispMode ) // Intra SubPartitions mode
{
//we obtain the offset to index the corresponding sub-partition
if( subTuIdx != -1 )
{
extraIdx = subTuIdx;
}
else
{
while( pos != tus[idx - 1 + extraIdx]->blocks[getFirstComponentOfChannel( effChType )].pos() )
{
extraIdx++;
}
}
}
}
return tus[idx - 1 + extraIdx];
}
#else
if( idx != 0 ) return tus[ idx - 1 ];
#endif
else if( m_isTuEnc ) return parent->getTU( pos, effChType );
else return nullptr;
}
}
#if JVET_M0102_INTRA_SUBPARTITIONS
const TransformUnit * CodingStructure::getTU( const Position &pos, const ChannelType effChType, const int subTuIdx ) const
#else
const TransformUnit * CodingStructure::getTU( const Position &pos, const ChannelType effChType ) const
#endif
{
const CompArea &_blk = area.blocks[effChType];
......@@ -290,8 +326,34 @@ const TransformUnit * CodingStructure::getTU( const Position &pos, const Channel
else
{
const unsigned idx = m_tuIdx[effChType][rsAddr( pos, _blk.pos(), _blk.width, unitScale[effChType] )];
#if JVET_M0102_INTRA_SUBPARTITIONS
if( idx != 0 )
{
unsigned extraIdx = 0;
if( isLuma( effChType ) )
{
const TransformUnit& tu = *tus[idx - 1];
if( tu.cu->ispMode ) // Intra SubPartitions mode
{
//we obtain the offset to index the corresponding sub-partition
if( subTuIdx != -1 )
{
extraIdx = subTuIdx;
}
else
{
while( pos != tus[idx - 1 + extraIdx]->blocks[effChType].pos() )
{
extraIdx++;
}
}
}
}
return tus[idx - 1 + extraIdx];
}
#else
if( idx != 0 ) return tus[idx - 1];
#endif
else if( m_isTuEnc ) return parent->getTU( pos, effChType );
else return nullptr;
}
......@@ -418,6 +480,9 @@ TransformUnit& CodingStructure::addTU( const UnitArea &unit, const ChannelType c
tu->UnitArea::operator=( unit );
tu->initData();
tu->next = nullptr;
#if JVET_M0102_INTRA_SUBPARTITIONS
tu->prev = nullptr;
#endif
tu->cs = this;
tu->cu = m_isTuEnc ? cus[0] : getCU( unit.blocks[chType].pos(), chType );
tu->chType = chType;
......@@ -433,6 +498,9 @@ TransformUnit& CodingStructure::addTU( const UnitArea &unit, const ChannelType c
if( prevTU && prevTU->cu == tu->cu )
{
prevTU->next = tu;
#if JVET_M0102_INTRA_SUBPARTITIONS
tu->prev = prevTU;
#endif
#if ENABLE_SPLIT_PARALLELISM || ENABLE_WPP_PARALLELISM
CHECK( prevTU->cacheId != tu->cacheId, "Inconsintent cacheId between previous and current TU" );
......@@ -470,11 +538,25 @@ TransformUnit& CodingStructure::addTU( const UnitArea &unit, const ChannelType c
const CompArea &_selfBlk = area.blocks[i];
const CompArea &_blk = tu-> blocks[i];
#if JVET_M0102_INTRA_SUBPARTITIONS
bool isIspTu = tu->cu != nullptr && tu->cu->ispMode && isLuma( _blk.compID );
bool isFirstIspTu = false;
if( isIspTu )
{
isFirstIspTu = CU::isISPFirst( *tu->cu, _blk, getFirstComponentOfChannel( ChannelType( i ) ) );
}
if( !isIspTu || isFirstIspTu )
#endif
{
const UnitScale& scale = unitScale[_blk.compID];
const Area scaledSelf = scale.scale( _selfBlk );
#if JVET_M0102_INTRA_SUBPARTITIONS
const Area scaledBlk = isIspTu ? scale.scale( tu->cu->blocks[i] ) : scale.scale( _blk );
#else
const Area scaledBlk = scale.scale( _blk );
#endif
unsigned *idxPtr = m_tuIdx[i] + rsAddr( scaledBlk.pos(), scaledSelf.pos(), scaledSelf.width );
CHECK( *idxPtr, "Overwriting a pre-existing value, should be '0'!" );
AreaBuf<uint32_t>( idxPtr, scaledSelf.width, scaledBlk.size() ).fill( idx );
......@@ -1000,6 +1082,9 @@ void CodingStructure::initStructData( const int &QP, const bool &_isLosses, cons
fracBits = 0;
dist = 0;
cost = MAX_DOUBLE;
#if JVET_M0102_INTRA_SUBPARTITIONS
lumaCost = MAX_DOUBLE;
#endif
interHad = std::numeric_limits<Distortion>::max();
}
......
......@@ -129,11 +129,19 @@ public:
const CodingUnit *getCU(const Position &pos, const ChannelType _chType) const;
const PredictionUnit *getPU(const Position &pos, const ChannelType _chType) const;
#if JVET_M0102_INTRA_SUBPARTITIONS
const TransformUnit *getTU(const Position &pos, const ChannelType _chType, const int subTuIdx = -1) const;
#else
const TransformUnit *getTU(const Position &pos, const ChannelType _chType) const;
#endif
CodingUnit *getCU(const Position &pos, const ChannelType _chType);
PredictionUnit *getPU(const Position &pos, const ChannelType _chType);
#if JVET_M0102_INTRA_SUBPARTITIONS
TransformUnit *getTU(const Position &pos, const ChannelType _chType, const int subTuIdx = -1);
#else
TransformUnit *getTU(const Position &pos, const ChannelType _chType);
#endif
const CodingUnit *getCU(const ChannelType &_chType) const { return getCU(area.blocks[_chType].pos(), _chType); }
const PredictionUnit *getPU(const ChannelType &_chType) const { return getPU(area.blocks[_chType].pos(), _chType); }
......@@ -171,6 +179,9 @@ public:
static_vector<double, NUM_ENC_FEATURES> features;
double cost;
#if JVET_M0102_INTRA_SUBPARTITIONS
double lumaCost;
#endif
uint64_t fracBits;
Distortion dist;
Distortion interHad;
......
......@@ -72,6 +72,9 @@ struct Size
bool operator!=(const Size &other) const { return (width != other.width) || (height != other.height); }
bool operator==(const Size &other) const { return (width == other.width) && (height == other.height); }
uint32_t area() const { return (uint32_t) width * (uint32_t) height; }
#if REUSE_CU_RESULTS_WITH_MULTIPLE_TUS
void resizeTo(const Size newSize) { width = newSize.width; height = newSize.height; }
#endif
};
struct Area : public Position, public Size
......
......@@ -50,8 +50,13 @@ CoeffCodingContext::CoeffCodingContext(const TransformUnit& tu, ComponentID comp
, m_chType (toChannelType(m_compID))
, m_width (tu.block(m_compID).width)
, m_height (tu.block(m_compID).height)
#if JVET_M0102_INTRA_SUBPARTITIONS
, m_log2CGWidth ( g_log2SbbSize[m_chType][ g_aucLog2[m_width] ][ g_aucLog2[m_height] ][0] )
, m_log2CGHeight ( g_log2SbbSize[m_chType][ g_aucLog2[m_width] ][ g_aucLog2[m_height] ][1] )
#else
, m_log2CGWidth ((m_width & 3) || (m_height & 3) ? 1 : 2)
, m_log2CGHeight ((m_width & 3) || (m_height & 3) ? 1 : 2)
#endif
, m_log2CGSize (m_log2CGWidth + m_log2CGHeight)
#if JVET_M0257
, m_widthInGroups(std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, m_width) >> m_log2CGWidth)
......@@ -74,10 +79,17 @@ CoeffCodingContext::CoeffCodingContext(const TransformUnit& tu, ComponentID comp
#else
, m_scanType (SCAN_DIAG)
#endif
#if JVET_M0102_INTRA_SUBPARTITIONS
, m_scan (g_scanOrder [m_chType][SCAN_GROUPED_4x4][m_scanType][gp_sizeIdxInfo->idxFrom(m_width )][gp_sizeIdxInfo->idxFrom(m_height )])
, m_scanPosX (g_scanOrderPosXY[m_chType][SCAN_GROUPED_4x4][m_scanType][gp_sizeIdxInfo->idxFrom(m_width )][gp_sizeIdxInfo->idxFrom(m_height )][0])
, m_scanPosY (g_scanOrderPosXY[m_chType][SCAN_GROUPED_4x4][m_scanType][gp_sizeIdxInfo->idxFrom(m_width )][gp_sizeIdxInfo->idxFrom(m_height )][1])
, m_scanCG (g_scanOrder [m_chType][SCAN_UNGROUPED ][m_scanType][gp_sizeIdxInfo->idxFrom(m_widthInGroups)][gp_sizeIdxInfo->idxFrom(m_heightInGroups)])
#else
, m_scan (g_scanOrder [SCAN_GROUPED_4x4][m_scanType][gp_sizeIdxInfo->idxFrom(m_width )][gp_sizeIdxInfo->idxFrom(m_height )])
, m_scanPosX (g_scanOrderPosXY[SCAN_GROUPED_4x4][m_scanType][gp_sizeIdxInfo->idxFrom(m_width )][gp_sizeIdxInfo->idxFrom(m_height )][0])
, m_scanPosY (g_scanOrderPosXY[SCAN_GROUPED_4x4][m_scanType][gp_sizeIdxInfo->idxFrom(m_width )][gp_sizeIdxInfo->idxFrom(m_height )][1])
, m_scanCG (g_scanOrder[SCAN_UNGROUPED ][m_scanType][gp_sizeIdxInfo->idxFrom(m_widthInGroups)][gp_sizeIdxInfo->idxFrom(m_heightInGroups)])
#endif
, m_CtxSetLastX (Ctx::LastX[m_chType])
, m_CtxSetLastY (Ctx::LastY[m_chType])
#if JVET_M0257
......@@ -314,8 +326,17 @@ unsigned DeriveCtx::CtxCUsplit( const CodingStructure& cs, Partitioner& partitio
}
#endif
#if JVET_M0102_INTRA_SUBPARTITIONS
unsigned DeriveCtx::CtxQtCbf( const ComponentID compID, const unsigned trDepth, const bool prevCbCbf, const int ispIdx )
{
if( ispIdx && isLuma( compID ) )
{
return 2 + (int)prevCbCbf;
}
#else
unsigned DeriveCtx::CtxQtCbf( const ComponentID compID, const unsigned trDepth, const bool prevCbCbf )
{
#endif
if( compID == COMPONENT_Cr )
{
return ( prevCbCbf ? 1 : 0 );
......
......@@ -308,7 +308,11 @@ void CtxSplit ( const CodingStructure& cs, Partitioner& partitioner, uns
unsigned CtxCUsplit ( const CodingStructure& cs, Partitioner& partitioner );
unsigned CtxBTsplit ( const CodingStructure& cs, Partitioner& partitioner );
#endif
#if JVET_M0102_INTRA_SUBPARTITIONS
unsigned CtxQtCbf ( const ComponentID compID, const unsigned trDepth, const bool prevCbCbf = false, const int ispIdx = 0 );
#else
unsigned CtxQtCbf ( const ComponentID compID, const unsigned trDepth, const bool prevCbCbf );
#endif
unsigned CtxInterDir ( const PredictionUnit& pu );
unsigned CtxSkipFlag ( const CodingUnit& cu );
unsigned CtxIMVFlag ( const CodingUnit& cu );
......
......@@ -745,6 +745,24 @@ const CtxSet ContextSetCfg::QtRootCbf = ContextSetCfg::addCtxSet
const CtxSet ContextSetCfg::QtCbf[] =
{
#if JVET_M0102_INTRA_SUBPARTITIONS
#if JVET_M0453_CABAC_ENGINE
ContextSetCfg::addCtxSet
({
{ 155, 127, CNU, CNU},
{ 141, 127, CNU, CNU},
{ CNU, 126, CNU, CNU},
{ 4, 5, DWS, DWS},
}),
#else
ContextSetCfg::addCtxSet
({
{ 140, 141, CNU, CNU},
{ 155, 127, CNU, CNU},
{ CNU, 126, CNU, CNU},
}),
#endif
#else
ContextSetCfg::addCtxSet
({
#if JVET_M0453_CABAC_ENGINE
......@@ -758,6 +776,7 @@ const CtxSet ContextSetCfg::QtCbf[] =
{ CNU, 126, },
#endif
}),
#endif
ContextSetCfg::addCtxSet
({
#if JVET_M0453_CABAC_ENGINE
......@@ -1208,6 +1227,18 @@ const CtxSet ContextSetCfg::EMTCuFlag = ContextSetCfg::addCtxSet
});
#endif
#if JVET_M0102_INTRA_SUBPARTITIONS
const CtxSet ContextSetCfg::ISPMode = ContextSetCfg::addCtxSet
({
{ CNU, CNU },
{ CNU, CNU },
{ CNU, CNU },
#if JVET_M0453_CABAC_ENGINE
{ DWS, DWS },
#endif
});
#endif
const CtxSet ContextSetCfg::CrossCompPred = ContextSetCfg::addCtxSet
({
{ 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,},
......
......@@ -306,6 +306,9 @@ public:
static const CtxSet TriangleIdx;
#if JVET_M0444_SMVD
static const CtxSet SmvdFlag;
#endif
#if JVET_M0102_INTRA_SUBPARTITIONS
static const CtxSet ISPMode;
#endif
static const unsigned NumberOfContexts;
......
......@@ -128,8 +128,13 @@ namespace DQIntern
Rom() : m_scansInitialized(false) {}
~Rom() { xUninitScanArrays(); }
void init () { xInitScanArrays(); }
#if JVET_M0102_INTRA_SUBPARTITIONS
const NbInfoSbb* getNbInfoSbb( int hd, int vd, int ch ) const { return m_scanId2NbInfoSbbArray[hd][vd][ch]; }
const NbInfoOut* getNbInfoOut( int hd, int vd, int ch ) const { return m_scanId2NbInfoOutArray[hd][vd][ch]; }
#else
const NbInfoSbb* getNbInfoSbb( int hd, int vd ) const { return m_scanId2NbInfoSbbArray[hd][vd]; }
const NbInfoOut* getNbInfoOut( int hd, int vd ) const { return m_scanId2NbInfoOutArray[hd][vd]; }
#endif
const TUParameters* getTUPars ( const CompArea& area, const ComponentID compID ) const
{
return m_tuParameters[g_aucLog2[area.width]][g_aucLog2[area.height]][toChannelType(compID)];
......@@ -139,8 +144,13 @@ namespace DQIntern
void xUninitScanArrays ();
private:
bool m_scansInitialized;
#if JVET_M0102_INTRA_SUBPARTITIONS
NbInfoSbb* m_scanId2NbInfoSbbArray[ MAX_CU_DEPTH+1 ][ MAX_CU_DEPTH+1 ][ MAX_NUM_CHANNEL_TYPE ];
NbInfoOut* m_scanId2NbInfoOutArray[ MAX_CU_DEPTH+1 ][ MAX_CU_DEPTH+1 ][ MAX_NUM_CHANNEL_TYPE ];
#else
NbInfoSbb* m_scanId2NbInfoSbbArray[ MAX_CU_DEPTH+1 ][ MAX_CU_DEPTH+1 ];
NbInfoOut* m_scanId2NbInfoOutArray[ MAX_CU_DEPTH+1 ][ MAX_CU_DEPTH+1 ];
#endif
TUParameters* m_tuParameters [ MAX_CU_DEPTH+1 ][ MAX_CU_DEPTH+1 ][ MAX_NUM_CHANNEL_TYPE ];
};
......@@ -156,26 +166,52 @@ namespace DQIntern
uint32_t raster2id[ MAX_CU_SIZE * MAX_CU_SIZE ];
#if JVET_M0102_INTRA_SUBPARTITIONS
for( int ch = 0; ch < MAX_NUM_CHANNEL_TYPE; ch++ )
{
for( int hd = 0; hd <= MAX_CU_DEPTH; hd++ )
{
for( int vd = 0; vd <= MAX_CU_DEPTH; vd++ )
{
if( (hd == 0 && vd <= 1) || (hd <= 1 && vd == 0) )
{
continue;
}
#else
for( int hd = 1; hd <= MAX_CU_DEPTH; hd++ )
{
for( int vd = 1; vd <= MAX_CU_DEPTH; vd++ )
{
#endif
const uint32_t blockWidth = (1 << hd);
const uint32_t blockHeight = (1 << vd);
const uint32_t totalValues = blockWidth * blockHeight;
#if JVET_M0102_INTRA_SUBPARTITIONS
const uint32_t log2CGWidth = g_log2SbbSize[ch][hd][vd][0];
const uint32_t log2CGHeight = g_log2SbbSize[ch][hd][vd][1];
#else
const uint32_t log2CGWidth = (blockWidth & 3) + (blockHeight & 3) > 0 ? 1 : 2;
const uint32_t log2CGHeight = (blockWidth & 3) + (blockHeight & 3) > 0 ? 1 : 2;
#endif
const uint32_t groupWidth = 1 << log2CGWidth;
const uint32_t groupHeight = 1 << log2CGHeight;
const uint32_t groupSize = groupWidth * groupHeight;
const CoeffScanType scanType = SCAN_DIAG;
const SizeType blkWidthIdx = gp_sizeIdxInfo->idxFrom( blockWidth );
const SizeType blkHeightIdx = gp_sizeIdxInfo->idxFrom( blockHeight );
#if JVET_M0102_INTRA_SUBPARTITIONS
const uint32_t* scanId2RP = g_scanOrder [ch][SCAN_GROUPED_4x4][scanType][blkWidthIdx][blkHeightIdx];
const uint32_t* scanId2X = g_scanOrderPosXY[ch][SCAN_GROUPED_4x4][scanType][blkWidthIdx][blkHeightIdx][0];
const uint32_t* scanId2Y = g_scanOrderPosXY[ch][SCAN_GROUPED_4x4][scanType][blkWidthIdx][blkHeightIdx][1];
NbInfoSbb*& sId2NbSbb = m_scanId2NbInfoSbbArray[hd][vd][ch];
NbInfoOut*& sId2NbOut = m_scanId2NbInfoOutArray[hd][vd][ch];
#else
const uint32_t* scanId2RP = g_scanOrder [SCAN_GROUPED_4x4][scanType][blkWidthIdx][blkHeightIdx];
const uint32_t* scanId2X = g_scanOrderPosXY[SCAN_GROUPED_4x4][scanType][blkWidthIdx][blkHeightIdx][0];
const uint32_t* scanId2Y = g_scanOrderPosXY[SCAN_GROUPED_4x4][scanType][blkWidthIdx][blkHeightIdx][1];
NbInfoSbb*& sId2NbSbb = m_scanId2NbInfoSbbArray[hd][vd];
NbInfoOut*& sId2NbOut = m_scanId2NbInfoOutArray[hd][vd];
#endif
sId2NbSbb = new NbInfoSbb[ totalValues ];
sId2NbOut = new NbInfoOut[ totalValues ];
......@@ -276,12 +312,19 @@ namespace DQIntern
nbOut.maxDist -= scanId;
}
#if JVET_M0102_INTRA_SUBPARTITIONS
m_tuParameters[hd][vd][ch] = new TUParameters( *this, blockWidth, blockHeight, ChannelType(ch) );
#else
for( int chId = 0; chId < MAX_NUM_CHANNEL_TYPE; chId++ )
{
m_tuParameters[hd][vd][chId] = new TUParameters( *this, blockWidth, blockHeight, ChannelType(chId) );
}
#endif
}
}
#if JVET_M0102_INTRA_SUBPARTITIONS
}
#endif
m_scansInitialized = true;
}
......@@ -291,6 +334,32 @@ namespace DQIntern
{
return;
}
#if JVET_M0102_INTRA_SUBPARTITIONS
for( int hd = 0; hd <= MAX_CU_DEPTH; hd++ )
{
for( int vd = 0; vd <= MAX_CU_DEPTH; vd++ )
{
for( int ch = 0; ch < 2; ch++ )
{
NbInfoSbb*& sId2NbSbb = m_scanId2NbInfoSbbArray[hd][vd][ch];
NbInfoOut*& sId2NbOut = m_scanId2NbInfoOutArray[hd][vd][ch];
TUParameters*& tuPars = m_tuParameters [hd][vd][ch];
if( sId2NbSbb )
{
delete [] sId2NbSbb;
}
if( sId2NbOut )
{
delete [] sId2NbOut;
}
if( tuPars )
{
delete tuPars;
}
}
}
}
#else
for( int hd = 0; hd <= MAX_CU_DEPTH; hd++ )
{
for( int vd = 0; vd <= MAX_CU_DEPTH; vd++ )
......@@ -315,6 +384,7 @@ namespace DQIntern
}
}
}
#endif
m_scansInitialized = false;
}
......@@ -328,9 +398,14 @@ namespace DQIntern
m_width = width;
m_height = height;
m_numCoeff = m_width * m_height;
#if JVET_M0102_INTRA_SUBPARTITIONS
m_log2SbbWidth = g_log2SbbSize[m_chType][ g_aucLog2[m_width] ][ g_aucLog2[m_height] ][0];
m_log2SbbHeight = g_log2SbbSize[m_chType][ g_aucLog2[m_width] ][ g_aucLog2[m_height] ][1];
#else
const bool no4x4 = ( ( m_width & 3 ) != 0 || ( m_height & 3 ) != 0 );
m_log2SbbWidth = ( no4x4 ? 1 : 2 );
m_log2SbbHeight = ( no4x4 ? 1 : 2 );
#endif
m_log2SbbSize = m_log2SbbWidth + m_log2SbbHeight;
m_sbbSize = ( 1 << m_log2SbbSize );
m_sbbMask = m_sbbSize - 1;
......@@ -352,6 +427,16 @@ namespace DQIntern
SizeType vsbb = gp_sizeIdxInfo->idxFrom( m_heightInSbb );
SizeType hsId = gp_sizeIdxInfo->idxFrom( m_width );
SizeType vsId = gp_sizeIdxInfo->idxFrom( m_height );
#if JVET_M0102_INTRA_SUBPARTITIONS
m_scanSbbId2SbbPos = g_scanOrder [ chType ][ SCAN_UNGROUPED ][ m_scanType ][ hsbb ][ vsbb ];
m_scanId2BlkPos = g_scanOrder [ chType ][ SCAN_GROUPED_4x4 ][ m_scanType ][ hsId ][ vsId ];
m_scanId2PosX = g_scanOrderPosXY[ chType ][ SCAN_GROUPED_4x4 ][ m_scanType ][ hsId ][ vsId ][ 0 ];
m_scanId2PosY = g_scanOrderPosXY[ chType ][ SCAN_GROUPED_4x4 ][ m_scanType ][ hsId ][ vsId ][ 1 ];
int log2W = g_aucLog2[ m_width ];
int log2H = g_aucLog2[ m_height ];
m_scanId2NbInfoSbb = rom.getNbInfoSbb( log2W, log2H, chType );
m_scanId2NbInfoOut = rom.getNbInfoOut( log2W, log2H, chType );
#else
m_scanSbbId2SbbPos = g_scanOrder [ SCAN_UNGROUPED ][ m_scanType ][ hsbb ][ vsbb ];
m_scanId2BlkPos = g_scanOrder [ SCAN_GROUPED_4x4 ][ m_scanType ][ hsId ][ vsId ];
m_scanId2PosX = g_scanOrderPosXY[ SCAN_GROUPED_4x4 ][ m_scanType ][ hsId ][ vsId ][ 0 ];
......@@ -360,6 +445,7 @@ namespace DQIntern
int log2H = g_aucLog2[ m_height ];
m_scanId2NbInfoSbb = rom.getNbInfoSbb( log2W, log2H );
m_scanId2NbInfoOut = rom.getNbInfoOut( log2W, log2H );
#endif
m_scanInfo = new ScanInfo[ m_numCoeff ];
for( int scanIdx = 0; scanIdx < m_numCoeff; scanIdx++ )
{
......@@ -473,8 +559,44 @@ namespace DQIntern
}
else
{
#if JVET_M0102_INTRA_SUBPARTITIONS
BinFracBits bits;
bool prevLumaCbf = false;
bool lastCbfIsInferred = false;
bool useIntraSubPartitions = tu.cu->ispMode && isLuma(chType);
if( useIntraSubPartitions )
{
bool rootCbfSoFar = false;
bool isLastSubPartition = CU::isISPLast(*tu.cu, tu.Y(), compID);
uint32_t nTus = tu.cu->ispMode == HOR_INTRA_SUBPARTITIONS ? tu.cu->lheight() >> g_aucLog2[tu.lheight()] : tu.cu->lwidth() >> g_aucLog2[tu.lwidth()];
if( isLastSubPartition )
{
TransformUnit* tuPointer = tu.cu->firstTU;
for( int tuIdx = 0; tuIdx < nTus - 1; tuIdx++ )
{
rootCbfSoFar |= TU::getCbfAtDepth(*tuPointer, COMPONENT_Y, tu.depth);
tuPointer = tuPointer->next;
}
if( !rootCbfSoFar )
{
lastCbfIsInferred = true;
}
}
if( !lastCbfIsInferred )
{
prevLumaCbf = TU::getPrevTuCbfAtDepth(tu, compID, tu.depth);
}
bits = fracBitsAccess.getFracBitsArray(Ctx::QtCbf[compID](DeriveCtx::CtxQtCbf(compID, tu.depth, prevLumaCbf, true)));
}
else
{
bits = fracBitsAccess.getFracBitsArray(Ctx::QtCbf[compID](DeriveCtx::CtxQtCbf(compID, tu.depth, tu.cbf[COMPONENT_Cb])));
}
cbfDeltaBits = lastCbfIsInferred ? 0 : int32_t(bits.intBits[1]) - int32_t(bits.intBits[0]);
#else
BinFracBits bits = fracBitsAccess.getFracBitsArray( Ctx::QtCbf[compID]( DeriveCtx::CtxQtCbf( compID, tu.depth, tu.cbf[COMPONENT_Cb] ) ) );
cbfDeltaBits = int32_t( bits.intBits[1] ) - int32_t( bits.intBits[0] );
#endif
}
static const unsigned prefixCtx[] = { 0, 0, 0, 3, 6, 10, 15, 21 };
......@@ -717,7 +839,11 @@ namespace DQIntern
#else
const CoeffScanType scanType = SCAN_DIAG;
#endif
#if JVET_M0102_INTRA_SUBPARTITIONS
const unsigned* scan = g_scanOrder[ toChannelType(compID) ][ SCAN_GROUPED_4x4 ][ scanType ][ hsId ][ vsId ];
#else
const unsigned* scan = g_scanOrder[ SCAN_GROUPED_4x4 ][ scanType ][ hsId ][ vsId ];