Commit 0fffdf5b authored by Christian Helmrich's avatar Christian Helmrich Committed by Xiang Li

JVET-O0105 with JVET-O0543: joint chroma coding extension

parent c81b8ade
...@@ -111,8 +111,10 @@ struct AreaBuf : public Size ...@@ -111,8 +111,10 @@ struct AreaBuf : public Size
void copyClip ( const AreaBuf<const T> &src, const ClpRng& clpRng); void copyClip ( const AreaBuf<const T> &src, const ClpRng& clpRng);
void subtract ( const AreaBuf<const T> &other ); void subtract ( const AreaBuf<const T> &other );
#if !JVET_O0105_ICT
void copyAndNegate ( const AreaBuf<const T> &other ); void copyAndNegate ( const AreaBuf<const T> &other );
void subtractAndHalve ( const AreaBuf<const T> &other ); void subtractAndHalve ( const AreaBuf<const T> &other );
#endif
void extendSingleBorderPel(); void extendSingleBorderPel();
void extendBorderPel ( unsigned margin ); void extendBorderPel ( unsigned margin );
void addWeightedAvg ( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng, const int8_t gbiIdx); void addWeightedAvg ( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng, const int8_t gbiIdx);
...@@ -357,6 +359,7 @@ void AreaBuf<T>::subtract( const AreaBuf<const T> &other ) ...@@ -357,6 +359,7 @@ void AreaBuf<T>::subtract( const AreaBuf<const T> &other )
#undef SUBS_INC #undef SUBS_INC
} }
#if !JVET_O0105_ICT
template<typename T> template<typename T>
void AreaBuf<T>::copyAndNegate( const AreaBuf<const T> &other ) void AreaBuf<T>::copyAndNegate( const AreaBuf<const T> &other )
{ {
...@@ -398,6 +401,7 @@ void AreaBuf<T>::subtractAndHalve( const AreaBuf<const T> &other ) ...@@ -398,6 +401,7 @@ void AreaBuf<T>::subtractAndHalve( const AreaBuf<const T> &other )
#undef SUBS_OP #undef SUBS_OP
#undef SUBS_INC #undef SUBS_INC
} }
#endif
template<typename T> template<typename T>
void AreaBuf<T>::copyClip( const AreaBuf<const T> &src, const ClpRng& clpRng ) void AreaBuf<T>::copyClip( const AreaBuf<const T> &src, const ClpRng& clpRng )
...@@ -924,5 +928,27 @@ private: ...@@ -924,5 +928,27 @@ private:
Pel *m_origin[MAX_NUM_COMPONENT]; Pel *m_origin[MAX_NUM_COMPONENT];
}; };
#if JVET_O0105_ICT
struct CompStorage : public PelBuf
{
CompStorage () { m_memory = nullptr; }
~CompStorage() { if (valid()) delete [] m_memory; }
void create( const Size& size )
{
CHECK( m_memory, "Trying to re-create an already initialized buffer" );
m_memory = new Pel [ size.area() ];
*static_cast<PelBuf*>(this) = PelBuf( m_memory, size );
}
void destroy()
{
if (valid()) delete [] m_memory;
m_memory = nullptr;
}
bool valid() { return m_memory != nullptr; }
private:
Pel* m_memory;
};
#endif
#endif #endif
...@@ -784,10 +784,17 @@ const CtxSet ContextSetCfg::IBCFlag = ContextSetCfg::addCtxSet ...@@ -784,10 +784,17 @@ const CtxSet ContextSetCfg::IBCFlag = ContextSetCfg::addCtxSet
const CtxSet ContextSetCfg::JointCbCrFlag = ContextSetCfg::addCtxSet const CtxSet ContextSetCfg::JointCbCrFlag = ContextSetCfg::addCtxSet
({ ({
#if JVET_O0105_ICT
{ 156, 156, 156, },
{ 156, 156, 156, },
{ 184, 184, 184, },
{ 1, 1, 1, },
#else
{ 156, }, { 156, },
{ 156, }, { 156, },
{ 184, }, { 184, },
{ 1, }, { 1, },
#endif
}); });
const CtxSet ContextSetCfg::TsSigCoeffGroup = ContextSetCfg::addCtxSet const CtxSet ContextSetCfg::TsSigCoeffGroup = ContextSetCfg::addCtxSet
......
...@@ -667,12 +667,20 @@ unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const De ...@@ -667,12 +667,20 @@ unsigned LoopFilter::xGetBoundaryStrengthSingle ( const CodingUnit& cu, const De
tmpBs += BsSet(1, COMPONENT_Y); tmpBs += BsSet(1, COMPONENT_Y);
} }
// U // U
#if JVET_O0105_ICT
if (m_aapucBS[edgeDir][rasterIdx] && (TU::getCbf(tuQ, COMPONENT_Cb) || TU::getCbf(tuP, COMPONENT_Cb) || tuQ.jointCbCr || tuP.jointCbCr))
#else
if (m_aapucBS[edgeDir][rasterIdx] && (TU::getCbf(tuQ, COMPONENT_Cb) || TU::getCbf(tuP, COMPONENT_Cb))) if (m_aapucBS[edgeDir][rasterIdx] && (TU::getCbf(tuQ, COMPONENT_Cb) || TU::getCbf(tuP, COMPONENT_Cb)))
#endif
{ {
tmpBs += BsSet(1, COMPONENT_Cb); tmpBs += BsSet(1, COMPONENT_Cb);
} }
// V // V
#if JVET_O0105_ICT
if (m_aapucBS[edgeDir][rasterIdx] && (TU::getCbf(tuQ, COMPONENT_Cr) || TU::getCbf(tuP, COMPONENT_Cr) || tuQ.jointCbCr || tuP.jointCbCr))
#else
if (m_aapucBS[edgeDir][rasterIdx] && (TU::getCbf(tuQ, COMPONENT_Cr) || TU::getCbf(tuP, COMPONENT_Cr))) if (m_aapucBS[edgeDir][rasterIdx] && (TU::getCbf(tuQ, COMPONENT_Cr) || TU::getCbf(tuP, COMPONENT_Cr)))
#endif
{ {
tmpBs += BsSet(1, COMPONENT_Cr); tmpBs += BsSet(1, COMPONENT_Cr);
} }
......
...@@ -103,8 +103,15 @@ QpParam::QpParam(const TransformUnit& tu, const ComponentID &compIDX, const int ...@@ -103,8 +103,15 @@ QpParam::QpParam(const TransformUnit& tu, const ComponentID &compIDX, const int
if (isChroma(compID)) if (isChroma(compID))
{ {
#if JVET_O0105_ICT
const bool useJQP = ( abs(TU::getICTMode(tu)) == 2 );
chromaQpOffset += tu.cs->pps->getQpOffset ( useJQP ? JOINT_CbCr : compID );
chromaQpOffset += tu.cs->slice->getSliceChromaQpDelta( useJQP ? JOINT_CbCr : compID );
#else
chromaQpOffset += tu.cs->pps->getQpOffset ( tu.jointCbCr ? JOINT_CbCr : compID ); chromaQpOffset += tu.cs->pps->getQpOffset ( tu.jointCbCr ? JOINT_CbCr : compID );
chromaQpOffset += tu.cs->slice->getSliceChromaQpDelta( tu.jointCbCr ? JOINT_CbCr : compID ); chromaQpOffset += tu.cs->slice->getSliceChromaQpDelta( tu.jointCbCr ? JOINT_CbCr : compID );
#endif
chromaQpOffset += tu.cs->pps->getPpsRangeExtension().getChromaQpOffsetListEntry( tu.cu->chromaQpAdj ).u.offset[int( compID ) - 1]; chromaQpOffset += tu.cs->pps->getPpsRangeExtension().getChromaQpOffsetListEntry( tu.cu->chromaQpAdj ).u.offset[int( compID ) - 1];
} }
......
...@@ -585,6 +585,10 @@ int8_t g_aucLog2 [MAX_CU_SIZE + 1]; ...@@ -585,6 +585,10 @@ int8_t g_aucLog2 [MAX_CU_SIZE + 1];
int8_t g_aucNextLog2[MAX_CU_SIZE + 1]; int8_t g_aucNextLog2[MAX_CU_SIZE + 1];
int8_t g_aucPrevLog2[MAX_CU_SIZE + 1]; int8_t g_aucPrevLog2[MAX_CU_SIZE + 1];
#if JVET_O0105_ICT
const int g_ictModes[2][4] = { { 0, 3, 1, 2 }, { 0, -3, -1, -2 } };
#endif
UnitScale g_miScaling( MIN_CU_LOG2, MIN_CU_LOG2 ); UnitScale g_miScaling( MIN_CU_LOG2, MIN_CU_LOG2 );
......
...@@ -146,6 +146,10 @@ extern int8_t g_aucLog2 [MAX_CU_SIZE + 1]; ...@@ -146,6 +146,10 @@ extern int8_t g_aucLog2 [MAX_CU_SIZE + 1];
extern int8_t g_aucNextLog2 [MAX_CU_SIZE + 1]; extern int8_t g_aucNextLog2 [MAX_CU_SIZE + 1];
extern int8_t g_aucPrevLog2 [MAX_CU_SIZE + 1]; extern int8_t g_aucPrevLog2 [MAX_CU_SIZE + 1];
#if JVET_O0105_ICT
extern const int g_ictModes[2][4];
#endif
inline bool is34( const SizeType& size ) inline bool is34( const SizeType& size )
{ {
return ( size & ( ( int64_t ) 1 << ( g_aucLog2[size] - 1 ) ) ); return ( size & ( ( int64_t ) 1 << ( g_aucLog2[size] - 1 ) ) );
......
...@@ -97,6 +97,9 @@ Slice::Slice() ...@@ -97,6 +97,9 @@ Slice::Slice()
, m_bTestWeightBiPred ( false ) , m_bTestWeightBiPred ( false )
, m_substreamSizes ( ) , m_substreamSizes ( )
, m_cabacInitFlag ( false ) , m_cabacInitFlag ( false )
#if JVET_O0105_ICT
, m_jointCbCrSignFlag ( false )
#endif
, m_bLMvdL1Zero ( false ) , m_bLMvdL1Zero ( false )
, m_LFCrossSliceBoundaryFlag ( false ) , m_LFCrossSliceBoundaryFlag ( false )
, m_enableTMVPFlag ( true ) , m_enableTMVPFlag ( true )
...@@ -192,6 +195,9 @@ void Slice::initSlice() ...@@ -192,6 +195,9 @@ void Slice::initSlice()
m_disFracMMVD = false; m_disFracMMVD = false;
m_substreamSizes.clear(); m_substreamSizes.clear();
m_cabacInitFlag = false; m_cabacInitFlag = false;
#if JVET_O0105_ICT
m_jointCbCrSignFlag = false;
#endif
m_enableTMVPFlag = true; m_enableTMVPFlag = true;
} }
...@@ -672,6 +678,9 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll) ...@@ -672,6 +678,9 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
} }
m_cabacInitFlag = pSrc->m_cabacInitFlag; m_cabacInitFlag = pSrc->m_cabacInitFlag;
#if JVET_O0105_ICT
m_jointCbCrSignFlag = pSrc->m_jointCbCrSignFlag;
#endif
memcpy(m_alfApss, pSrc->m_alfApss, sizeof(m_alfApss)); // this might be quite unsafe memcpy(m_alfApss, pSrc->m_alfApss, sizeof(m_alfApss)); // this might be quite unsafe
memcpy( m_tileGroupAlfEnabledFlag, pSrc->m_tileGroupAlfEnabledFlag, sizeof(m_tileGroupAlfEnabledFlag)); memcpy( m_tileGroupAlfEnabledFlag, pSrc->m_tileGroupAlfEnabledFlag, sizeof(m_tileGroupAlfEnabledFlag));
m_tileGroupNumAps = pSrc->m_tileGroupNumAps; m_tileGroupNumAps = pSrc->m_tileGroupNumAps;
......
...@@ -1467,6 +1467,10 @@ private: ...@@ -1467,6 +1467,10 @@ private:
bool m_cabacInitFlag; bool m_cabacInitFlag;
#if JVET_O0105_ICT
bool m_jointCbCrSignFlag;
#endif
bool m_bLMvdL1Zero; bool m_bLMvdL1Zero;
bool m_LFCrossSliceBoundaryFlag; bool m_LFCrossSliceBoundaryFlag;
...@@ -1739,6 +1743,12 @@ public: ...@@ -1739,6 +1743,12 @@ public:
void setCabacInitFlag( bool val ) { m_cabacInitFlag = val; } //!< set CABAC initial flag void setCabacInitFlag( bool val ) { m_cabacInitFlag = val; } //!< set CABAC initial flag
bool getCabacInitFlag() const { return m_cabacInitFlag; } //!< get CABAC initial flag bool getCabacInitFlag() const { return m_cabacInitFlag; } //!< get CABAC initial flag
#if JVET_O0105_ICT
void setJointCbCrSignFlag( bool b ) { m_jointCbCrSignFlag = b; }
bool getJointCbCrSignFlag() const { return m_jointCbCrSignFlag; }
#endif
void setLFCrossSliceBoundaryFlag( bool val ) { m_LFCrossSliceBoundaryFlag = val; } void setLFCrossSliceBoundaryFlag( bool val ) { m_LFCrossSliceBoundaryFlag = val; }
bool getLFCrossSliceBoundaryFlag() const { return m_LFCrossSliceBoundaryFlag; } bool getLFCrossSliceBoundaryFlag() const { return m_LFCrossSliceBoundaryFlag; }
......
...@@ -83,6 +83,80 @@ InvTrans *fastInvTrans[NUM_TRANS_TYPE][g_numTransformMatrixSizes] = ...@@ -83,6 +83,80 @@ InvTrans *fastInvTrans[NUM_TRANS_TYPE][g_numTransformMatrixSizes] =
//! \ingroup CommonLib //! \ingroup CommonLib
//! \{ //! \{
#if JVET_O0105_ICT
static inline int64_t square( const int d ) { return d * (int64_t)d; }
template<int signedMode> std::pair<int64_t,int64_t> fwdTransformCbCr( const PelBuf &resCb, const PelBuf &resCr, PelBuf& resC1, PelBuf& resC2 )
{
const Pel* cb = resCb.buf;
const Pel* cr = resCr.buf;
Pel* c1 = resC1.buf;
Pel* c2 = resC2.buf;
int64_t d1 = 0;
int64_t d2 = 0;
for( SizeType y = 0; y < resCb.height; y++, cb += resCb.stride, cr += resCr.stride, c1 += resC1.stride, c2 += resC2.stride )
{
for( SizeType x = 0; x < resCb.width; x++ )
{
int cbx = cb[x], crx = cr[x];
if ( signedMode == 1 )
{
c1[x] = Pel( ( 4*cbx + 2*crx ) / 5 );
d1 += square( cbx - c1[x] ) + square( crx - (c1[x]>>1) );
}
else if ( signedMode == -1 )
{
c1[x] = Pel( ( 4*cbx - 2*crx ) / 5 );
d1 += square( cbx - c1[x] ) + square( crx - (-c1[x]>>1) );
}
else if ( signedMode == 2 )
{
c1[x] = Pel( ( cbx + crx ) / 2 );
d1 += square( cbx - c1[x] ) + square( crx - c1[x] );
}
else if ( signedMode == -2 )
{
c1[x] = Pel( ( cbx - crx ) / 2 );
d1 += square( cbx - c1[x] ) + square( crx + c1[x] );
}
else if ( signedMode == 3 )
{
c2[x] = Pel( ( 4*crx + 2*cbx ) / 5 );
d1 += square( cbx - (c2[x]>>1) ) + square( crx - c2[x] );
}
else if ( signedMode == -3 )
{
c2[x] = Pel( ( 4*crx - 2*cbx ) / 5 );
d1 += square( cbx - (-c2[x]>>1) ) + square( crx - c2[x] );
}
else
{
d1 += square( cbx );
d2 += square( crx );
}
}
}
return std::make_pair(d1,d2);
}
template<int signedMode> void invTransformCbCr( PelBuf &resCb, PelBuf &resCr )
{
Pel* cb = resCb.buf;
Pel* cr = resCr.buf;
for( SizeType y = 0; y < resCb.height; y++, cb += resCb.stride, cr += resCr.stride )
{
for( SizeType x = 0; x < resCb.width; x++ )
{
if ( signedMode == 1 ) { cr[x] = cb[x] >> 1; }
else if ( signedMode == -1 ) { cr[x] = -cb[x] >> 1; }
else if ( signedMode == 2 ) { cr[x] = cb[x]; }
else if ( signedMode == -2 ) { cr[x] = -cb[x]; }
else if ( signedMode == 3 ) { cb[x] = cr[x] >> 1; }
else if ( signedMode == -3 ) { cb[x] = -cr[x] >> 1; }
}
}
}
#endif
// ==================================================================================================================== // ====================================================================================================================
// TrQuant class member functions // TrQuant class member functions
...@@ -96,6 +170,26 @@ TrQuant::TrQuant() : m_quant( nullptr ) ...@@ -96,6 +170,26 @@ TrQuant::TrQuant() : m_quant( nullptr )
{ {
m_mtsCoeffs[i] = (TCoeff*) xMalloc( TCoeff, MAX_CU_SIZE * MAX_CU_SIZE ); m_mtsCoeffs[i] = (TCoeff*) xMalloc( TCoeff, MAX_CU_SIZE * MAX_CU_SIZE );
} }
#if JVET_O0105_ICT
{
m_invICT = m_invICTMem + maxAbsIctMode;
m_invICT[ 0] = invTransformCbCr< 0>;
m_invICT[ 1] = invTransformCbCr< 1>;
m_invICT[-1] = invTransformCbCr<-1>;
m_invICT[ 2] = invTransformCbCr< 2>;
m_invICT[-2] = invTransformCbCr<-2>;
m_invICT[ 3] = invTransformCbCr< 3>;
m_invICT[-3] = invTransformCbCr<-3>;
m_fwdICT = m_fwdICTMem + maxAbsIctMode;
m_fwdICT[ 0] = fwdTransformCbCr< 0>;
m_fwdICT[ 1] = fwdTransformCbCr< 1>;
m_fwdICT[-1] = fwdTransformCbCr<-1>;
m_fwdICT[ 2] = fwdTransformCbCr< 2>;
m_fwdICT[-2] = fwdTransformCbCr<-2>;
m_fwdICT[ 3] = fwdTransformCbCr< 3>;
m_fwdICT[-3] = fwdTransformCbCr<-3>;
}
#endif
} }
TrQuant::~TrQuant() TrQuant::~TrQuant()
...@@ -556,6 +650,83 @@ void TrQuant::invRdpcmNxN(TransformUnit& tu, const ComponentID &compID, PelBuf & ...@@ -556,6 +650,83 @@ void TrQuant::invRdpcmNxN(TransformUnit& tu, const ComponentID &compID, PelBuf &
} }
} }
#if JVET_O0105_ICT
std::pair<int64_t,int64_t> TrQuant::fwdTransformICT( const TransformUnit &tu, const PelBuf &resCb, const PelBuf &resCr, PelBuf &resC1, PelBuf &resC2, int jointCbCr )
{
CHECK( Size(resCb) != Size(resCr), "resCb and resCr have different sizes" );
CHECK( Size(resCb) != Size(resC1), "resCb and resC1 have different sizes" );
CHECK( Size(resCb) != Size(resC2), "resCb and resC2 have different sizes" );
return (*m_fwdICT[ TU::getICTMode(tu, jointCbCr) ])( resCb, resCr, resC1, resC2 );
}
void TrQuant::invTransformICT( const TransformUnit &tu, PelBuf &resCb, PelBuf &resCr )
{
CHECK( Size(resCb) != Size(resCr), "resCb and resCr have different sizes" );
(*m_invICT[ TU::getICTMode(tu) ])( resCb, resCr );
}
std::vector<int> TrQuant::selectICTCandidates( const TransformUnit &tu, CompStorage* resCb, CompStorage* resCr )
{
CHECK( !resCb[0].valid() || !resCr[0].valid(), "standard components are not valid" );
#if JVET_O0543_ICT_ICU_ONLY
if( !CU::isIntra( *tu.cu ) )
{
int cbfMask = 3;
resCb[cbfMask].create( tu.blocks[COMPONENT_Cb] );
resCr[cbfMask].create( tu.blocks[COMPONENT_Cr] );
fwdTransformICT( tu, resCb[0], resCr[0], resCb[cbfMask], resCr[cbfMask], cbfMask );
std::vector<int> cbfMasksToTest;
cbfMasksToTest.push_back( cbfMask );
return cbfMasksToTest;
}
#endif
std::pair<int64_t,int64_t> pairDist[4];
for( int cbfMask = 0; cbfMask < 4; cbfMask++ )
{
if( cbfMask )
{
CHECK( resCb[cbfMask].valid() || resCr[cbfMask].valid(), "target components for cbfMask=" << cbfMask << " are already present" );
resCb[cbfMask].create( tu.blocks[COMPONENT_Cb] );
resCr[cbfMask].create( tu.blocks[COMPONENT_Cr] );
}
pairDist[cbfMask] = fwdTransformICT( tu, resCb[0], resCr[0], resCb[cbfMask], resCr[cbfMask], cbfMask );
}
std::vector<int> cbfMasksToTest;
int64_t minDist1 = std::min<int64_t>( pairDist[0].first, pairDist[0].second );
int64_t minDist2 = std::numeric_limits<int64_t>::max();
int cbfMask1 = 0;
int cbfMask2 = 0;
for( int cbfMask : { 1, 2, 3 } )
{
if( pairDist[cbfMask].first < minDist1 )
{
cbfMask2 = cbfMask1; minDist2 = minDist1;
cbfMask1 = cbfMask; minDist1 = pairDist[cbfMask1].first;
}
else if( pairDist[cbfMask].first < minDist2 )
{
cbfMask2 = cbfMask; minDist2 = pairDist[cbfMask2].first;
}
}
if( cbfMask1 )
{
cbfMasksToTest.push_back( cbfMask1 );
}
if( cbfMask2 && ( ( minDist2 < (9*minDist1)/8 ) || ( !cbfMask1 && minDist2 < (3*minDist1)/2 ) ) )
{
cbfMasksToTest.push_back( cbfMask2 );
}
return cbfMasksToTest;
}
#endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Logical transform // Logical transform
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
......
...@@ -103,6 +103,12 @@ public: ...@@ -103,6 +103,12 @@ public:
void transformSkipQuantOneSample(TransformUnit &tu, const ComponentID &compID, const TCoeff &resiDiff, TCoeff &coeff, const uint32_t &uiPos, const QpParam &cQP, const bool bUseHalfRoundingPoint); void transformSkipQuantOneSample(TransformUnit &tu, const ComponentID &compID, const TCoeff &resiDiff, TCoeff &coeff, const uint32_t &uiPos, const QpParam &cQP, const bool bUseHalfRoundingPoint);
void invTrSkipDeQuantOneSample (TransformUnit &tu, const ComponentID &compID, const TCoeff &pcCoeff, Pel &reconSample, const uint32_t &uiPos, const QpParam &cQP); void invTrSkipDeQuantOneSample (TransformUnit &tu, const ComponentID &compID, const TCoeff &pcCoeff, Pel &reconSample, const uint32_t &uiPos, const QpParam &cQP);
#if JVET_O0105_ICT
void invTransformICT ( const TransformUnit &tu, PelBuf &resCb, PelBuf &resCr );
std::pair<int64_t,int64_t> fwdTransformICT ( const TransformUnit &tu, const PelBuf &resCb, const PelBuf &resCr, PelBuf& resC1, PelBuf& resC2, int jointCbCr = -1 );
std::vector<int> selectICTCandidates ( const TransformUnit &tu, CompStorage* resCb, CompStorage* resCr );
#endif
void invRdpcmNxN(TransformUnit& tu, const ComponentID &compID, PelBuf &pcResidual); void invRdpcmNxN(TransformUnit& tu, const ComponentID &compID, PelBuf &pcResidual);
#if RDOQ_CHROMA_LAMBDA #if RDOQ_CHROMA_LAMBDA
void setLambdas ( const double lambdas[MAX_NUM_COMPONENT] ) { m_quant->setLambdas( lambdas ); } void setLambdas ( const double lambdas[MAX_NUM_COMPONENT] ) { m_quant->setLambdas( lambdas ); }
...@@ -128,10 +134,17 @@ protected: ...@@ -128,10 +134,17 @@ protected:
bool m_scalingListEnabledFlag; bool m_scalingListEnabledFlag;
private: private:
DepQuant *m_quant; //!< Quantizer DepQuant *m_quant; //!< Quantizer
TCoeff** m_mtsCoeffs; TCoeff** m_mtsCoeffs;
TCoeff m_tempInMatrix [ 48 ]; TCoeff m_tempInMatrix [ 48 ];
TCoeff m_tempOutMatrix[ 48 ]; TCoeff m_tempOutMatrix[ 48 ];
#if JVET_O0105_ICT
static const int maxAbsIctMode = 3;
void (*m_invICTMem[1+2*maxAbsIctMode])(PelBuf&,PelBuf&);
std::pair<int64_t,int64_t>(*m_fwdICTMem[1+2*maxAbsIctMode])(const PelBuf&,const PelBuf&,PelBuf&,PelBuf&);
void (**m_invICT)(PelBuf&,PelBuf&);
std::pair<int64_t,int64_t>(**m_fwdICT)(const PelBuf&,const PelBuf&,PelBuf&,PelBuf&);
#endif
// forward Transform // forward Transform
......
...@@ -52,6 +52,9 @@ ...@@ -52,6 +52,9 @@
#define JVET_O0052_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT 1 // JVET-O0052 Method-1: TU-level context coded bin constraint #define JVET_O0052_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT 1 // JVET-O0052 Method-1: TU-level context coded bin constraint
#define JVET_O0105_ICT 1 // JVET-O0105: inter-chroma transform (ICT) as extension of joint chroma coding (JCC)
#define JVET_O0543_ICT_ICU_ONLY 1 // JVET-O0543: ICT only in Intra CUs (was Intra slices, modified during adoption)
#define JVET_O0216_ALF_COEFF_EG3 1 // JVET-O0216/O0302/O0648: using EG3 for ALF coefficients coding #define JVET_O0216_ALF_COEFF_EG3 1 // JVET-O0216/O0302/O0648: using EG3 for ALF coefficients coding
#define JVET_O0256_ADJUST_THD_DEPQUANT 1 // JVET-O0256: Fast encoder with adjusted threshold in dependent quantization #define JVET_O0256_ADJUST_THD_DEPQUANT 1 // JVET-O0256: Fast encoder with adjusted threshold in dependent quantization
......
...@@ -4497,6 +4497,17 @@ bool TU::isMTSAllowed(const TransformUnit &tu, const ComponentID compID) ...@@ -4497,6 +4497,17 @@ bool TU::isMTSAllowed(const TransformUnit &tu, const ComponentID compID)
return mtsAllowed; return mtsAllowed;
} }
#if JVET_O0105_ICT
int TU::getICTMode( const TransformUnit& tu, int jointCbCr )
{
if( jointCbCr < 0 )
{
jointCbCr = tu.jointCbCr;
}
return g_ictModes[ tu.cs->slice->getJointCbCrSignFlag() ][ jointCbCr ];
}
#endif
uint32_t TU::getGolombRiceStatisticsIndex(const TransformUnit &tu, const ComponentID &compID) uint32_t TU::getGolombRiceStatisticsIndex(const TransformUnit &tu, const ComponentID &compID)
{ {
const bool transformSkip = tu.mtsIdx==MTS_SKIP; const bool transformSkip = tu.mtsIdx==MTS_SKIP;
......
...@@ -213,7 +213,9 @@ namespace TU ...@@ -213,7 +213,9 @@ namespace TU
bool needsBlockSizeTrafoScale ( const TransformUnit &tu, const ComponentID &compID ); bool needsBlockSizeTrafoScale ( const TransformUnit &tu, const ComponentID &compID );
TransformUnit* getPrevTU ( const TransformUnit &tu, const ComponentID compID ); TransformUnit* getPrevTU ( const TransformUnit &tu, const ComponentID compID );
bool getPrevTuCbfAtDepth( const TransformUnit &tu, const ComponentID compID, const int trDepth ); bool getPrevTuCbfAtDepth( const TransformUnit &tu, const ComponentID compID, const int trDepth );
#if JVET_O0105_ICT
int getICTMode ( const TransformUnit &tu, int jointCbCr = -1 );
#endif
} }
uint32_t getCtuAddr (const Position& pos, const PreCalcValues &pcv); uint32_t getCtuAddr (const Position& pos, const PreCalcValues &pcv);
......
...@@ -2328,6 +2328,13 @@ void CABACReader::transform_unit( TransformUnit& tu, CUCtx& cuCtx, ChromaCbfs& c ...@@ -2328,6 +2328,13 @@ void CABACReader::transform_unit( TransformUnit& tu, CUCtx& cuCtx, ChromaCbfs& c
bool cbfLuma = ( tu.cbf[ COMPONENT_Y ] != 0 ); bool cbfLuma = ( tu.cbf[ COMPONENT_Y ] != 0 );
bool cbfChroma = ( lumaOnly ? false : ( chromaCbfs.Cb || chromaCbfs.Cr ) ); bool cbfChroma = ( lumaOnly ? false : ( chromaCbfs.Cb || chromaCbfs.Cr ) );
#if JVET_O0105_ICT
if( !lumaOnly )
{
joint_cb_cr( tu, ( tu.cbf[COMPONENT_Cb] ? 2 : 0 ) + ( tu.cbf[COMPONENT_Cr] ? 1 : 0 ) );
}
#endif
if( cbfLuma || cbfChroma ) if( cbfLuma || cbfChroma )
{ {
if( cu.cs->pps->getUseDQP() && !cuCtx.isDQPCoded ) if( cu.cs->pps->getUseDQP() && !cuCtx.isDQPCoded )
...@@ -2419,17 +2426,36 @@ void CABACReader::cu_chroma_qp_offset( CodingUnit& cu ) ...@@ -2419,17 +2426,36 @@ void CABACReader::cu_chroma_qp_offset( CodingUnit& cu )
// void residual_coding_subblock( coeffCtx ) // void residual_coding_subblock( coeffCtx )
//================================================================================ //================================================================================
#if JVET_O0105_ICT
void CABACReader::joint_cb_cr( TransformUnit& tu, const int cbfMask )
{
#if JVET_O0543_ICT_ICU_ONLY
if( ( CU::isIntra( *tu.cu ) && cbfMask ) || ( cbfMask == 3 ) )
#else
if( cbfMask )
#endif