Commit 2b072617 authored by Karsten Suehring's avatar Karsten Suehring
Browse files

Merge branch 'JVET-Y0077_BIM' into 'master'

JVET-Y0077: Block Importance Mapping

See merge request !56
parents 22c0feeb 5269ce80
Pipeline #7111 passed with stage
in 6 minutes and 3 seconds
......@@ -1536,6 +1536,10 @@ Threshold parameter for controlling amount of QP reduction by the QP reduction m
Periodicity parameter for application of the QP reduction model. 1: all frames, 0: only intra pictures, 2: every second frame, etc.
\\
\Option{BIM} &
\Default{false} &
Enable or disable Block Importance Mapping, QP adaptation depending on estimated propagation of reference samples. Depends on future and past reference frames configured for temporal filter.
\\
\Option{SliceChromaQPOffsetPeriodicity} &
\Default{0} &
......
......@@ -949,7 +949,9 @@ Bool TAppEncCfg::parseCfg( Int argc, TChar* argv[] )
("SmoothQPReductionLimit", m_iSmoothQPReductionLimit, -16, "Threshold parameter for controlling maximum amount of QP reduction by the QP reduction model")
("SmoothQPReductionPeriodicity", m_iSmoothQPReductionPeriodicity, 1, "Periodicity parameter of the QP reduction model, 1: all frames, 0: only intra pictures, 2: every second frame, etc")
#endif
#if JVET_Y0077_BIM
("BIM", m_bimEnabled, false, "Block Importance Mapping QP adaptation depending on estimated propagation of reference samples.")
#endif
("AdaptiveQP,-aq", m_bUseAdaptiveQP, false, "QP adaptation based on a psycho-visual model")
("MaxQPAdaptationRange,-aqr", m_iQPAdaptationRange, 6, "QP adaptation range")
("dQPFile,m", m_dQPFileName, string(""), "dQP file name")
......@@ -3101,6 +3103,12 @@ Void TAppEncCfg::xCheckParameter()
printf("Warning: Number of frames used for temporal prefilter is different from default.\n");
}
}
#if JVET_Y0077_BIM
if (m_bimEnabled)
{
xConfirmPara(m_temporalSubsampleRatio != 1, "Block Importance Mapping only support Temporal sub-sample ratio 1");
}
#endif
#if EXTENSION_360_VIDEO
check_failed |= m_ext360.verifyParameters();
......
......@@ -424,6 +424,9 @@ protected:
Int m_firstValidFrame;
Int m_lastValidFrame;
std::map<Int, Double> m_gopBasedTemporalFilterStrengths; ///< Filter strength per frame for the GOP-based Temporal Filter
#if JVET_Y0077_BIM
Bool m_bimEnabled;
#endif
std::string m_arSEIFileRoot;
Bool m_fisheyeVIdeoInfoSEIEnabled;
......
......@@ -400,6 +400,9 @@ Void TAppEncTop::xInitLibCfg()
m_cTEncTop.setOmniViewportSEIHorRange ( m_omniViewportSEIHorRange );
m_cTEncTop.setOmniViewportSEIVerRange ( m_omniViewportSEIVerRange );
m_cTEncTop.setGopBasedTemporalFilterEnabled ( m_gopBasedTemporalFilterEnabled );
#if JVET_Y0077_BIM
m_cTEncTop.setBIM ( m_bimEnabled );
#endif
m_cTEncTop.setCmpSEIEnabled (m_cmpSEIEnabled);
m_cTEncTop.setCmpSEICmpCancelFlag (m_cmpSEICmpCancelFlag);
m_cTEncTop.setCmpSEICmpPersistenceFlag (m_cmpSEICmpPersistenceFlag);
......@@ -660,13 +663,22 @@ Void TAppEncTop::encode()
TExt360AppEncTop ext360(*this, m_cTEncTop.getGOPEncoder()->getExt360Data(), *(m_cTEncTop.getGOPEncoder()), *pcPicYuvOrg);
#endif
TEncTemporalFilter temporalFilter;
#if JVET_Y0077_BIM
if ( m_gopBasedTemporalFilterEnabled || m_bimEnabled )
#else
if (m_gopBasedTemporalFilterEnabled)
#endif
{
temporalFilter.init(m_FrameSkip, m_inputBitDepth, m_MSBExtendedBitDepth, m_internalBitDepth, m_sourceWidth, m_sourceHeight,
m_sourcePadding, m_framesToBeEncoded, m_bClipInputVideoToRec709Range, m_inputFileName, m_chromaFormatIDC,
m_inputColourSpaceConvert, m_iQP, m_iGOPSize, m_gopBasedTemporalFilterStrengths,
m_gopBasedTemporalFilterPastRefs, m_gopBasedTemporalFilterFutureRefs,
#if !JVET_Y0077_BIM
m_firstValidFrame, m_lastValidFrame);
#else
m_firstValidFrame, m_lastValidFrame,
m_gopBasedTemporalFilterEnabled, m_cTEncTop.getAdaptQPmap(), m_bimEnabled);
#endif
}
while ( !bEos )
{
......@@ -687,7 +699,11 @@ Void TAppEncTop::encode()
m_cTVideoIOYuvInputFile.read( pcPicYuvOrg, &cPicYuvTrueOrg, ipCSC, m_sourcePadding, m_InputChromaFormatIDC, m_bClipInputVideoToRec709Range );
#endif
#if JVET_Y0077_BIM
if ( m_gopBasedTemporalFilterEnabled || m_bimEnabled )
#else
if (m_gopBasedTemporalFilterEnabled)
#endif
{
temporalFilter.filter(pcPicYuvOrg, m_iFrameRcvd);
}
......
......@@ -52,6 +52,7 @@
#define JVET_X0079_MODIFIED_BITRATES 1 // JVET-X0079: Addition of level 6.3
#define JVET_V0078 1 // JVET-V0078: QP control for very smooth blocks
#define JVET_Y0077_BIM 1 // JVET-Y0077: Block Importance Mapping
#define JVET_Y0105_SW_AND_QDF 1 // An adaptive smooth window (SW) size and extension of quality dependency factor (QDF) to low frame rate in rate control
......
......@@ -417,6 +417,10 @@ protected:
std::vector<UInt> m_omniViewportSEIHorRange;
std::vector<UInt> m_omniViewportSEIVerRange;
Bool m_gopBasedTemporalFilterEnabled;
#if JVET_Y0077_BIM
Bool m_bimEnabled;
std::map<Int, Int*> m_adaptQPmap;
#endif
Bool m_cmpSEIEnabled;
Bool m_cmpSEICmpCancelFlag;
Bool m_cmpSEICmpPersistenceFlag;
......@@ -1139,6 +1143,13 @@ public:
UInt getOmniViewportSEIVerRange(Int idx) { return m_omniViewportSEIVerRange[idx]; }
Void setGopBasedTemporalFilterEnabled(Bool flag) { m_gopBasedTemporalFilterEnabled = flag; }
Bool getGopBasedTemporalFilterEnabled() const { return m_gopBasedTemporalFilterEnabled; }
#if JVET_Y0077_BIM
void setBIM(Bool flag) { m_bimEnabled = flag; }
Bool getBIM() const { return m_bimEnabled; }
void setAdaptQPmap(std::map<Int, Int*> map) { m_adaptQPmap = map; }
Int* getAdaptQPmap(Int poc) { return m_adaptQPmap[poc]; }
std::map<Int, Int*> *getAdaptQPmap() { return &m_adaptQPmap; }
#endif
Void setCmpSEIEnabled(Bool b) { m_cmpSEIEnabled = b; }
Bool getCmpSEIEnabled() { return m_cmpSEIEnabled; }
Void setCmpSEICmpCancelFlag(Bool b) { m_cmpSEICmpCancelFlag = b; }
......
......@@ -222,6 +222,9 @@ Void TEncCu::init( TEncTop* pcEncTop )
#if JVET_V0078
m_smoothQPoffset = 0;
#endif
#if JVET_Y0077_BIM
m_BimQPoffset = 0;
#endif
}
// ====================================================================================================================
......@@ -613,6 +616,22 @@ Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const
}
#endif
#if JVET_Y0077_BIM
if( m_pcEncCfg->getBIM() )
{
if ( uiDepth <= pps.getMaxCuDQPDepth() )
{
std::map<Int, Int*> *QPmap = m_pcEncCfg->getAdaptQPmap();
Int iCTUoffset = uiTPelY / MAX_CU_SIZE * pcPic->getFrameWidthInCtus() + uiLPelX / MAX_CU_SIZE;
m_BimQPoffset = ( QPmap->find( pcPic->getPOC() ) == QPmap->end() ) ? 0 : (*QPmap)[pcPic->getPOC()][iCTUoffset];
}
Int idQP = m_pcEncCfg->getMaxDeltaQP();
iMinQP = Clip3( -sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP - idQP - m_lumaQPOffset + m_smoothQPoffset + m_BimQPoffset );
iMaxQP = Clip3( -sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP + idQP - m_lumaQPOffset + m_smoothQPoffset + m_BimQPoffset );
}
#endif
if ( m_pcEncCfg->getUseRateCtrl() )
{
iMinQP = m_pcRateCtrl->getRCQP();
......@@ -647,10 +666,14 @@ Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const
{
iQP = lowestQP;
}
#if JVET_Y0077_BIM
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable() || m_pcEncCfg->getBIM()) && uiDepth <= pps.getMaxCuDQPDepth())
#else
#if JVET_V0078
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable()) && uiDepth <= pps.getMaxCuDQPDepth())
#else
if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() && uiDepth <= pps.getMaxCuDQPDepth() )
#endif
#endif
{
getSliceEncoder()->updateLambda(pcSlice, iQP);
......@@ -936,6 +959,16 @@ Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const
Int idQP = m_pcEncCfg->getMaxDeltaQP();
iMinQP = Clip3( -sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP-idQP );
iMaxQP = Clip3( -sps.getQpBDOffset(CHANNEL_TYPE_LUMA), MAX_QP, iBaseQP+idQP );
#if JVET_Y0077_BIM
if (m_pcEncCfg->getBIM())
{
std::map<Int, Int*> *QPmap = m_pcEncCfg->getAdaptQPmap();
Int iCTUoffset = uiTPelY / MAX_CU_SIZE * pcPic->getFrameWidthInCtus() + uiLPelX / MAX_CU_SIZE;
Int iOffset = ( QPmap->find( pcPic->getPOC() ) == QPmap->end() ) ? 0 : (*QPmap)[pcPic->getPOC()][iCTUoffset];
iMinQP += iOffset;
iMaxQP += iOffset;
}
#endif
}
else if( uiDepth < pps.getMaxCuDQPDepth() )
{
......@@ -1018,10 +1051,14 @@ Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const
rpcTempCU->copyPartFrom( pcSubBestPartCU, uiPartUnitIdx, uhNextDepth ); // Keep best part data to current temporary data.
xCopyYuv2Tmp( pcSubBestPartCU->getTotalNumPart()*uiPartUnitIdx, uhNextDepth );
#if JVET_Y0077_BIM
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable() || m_pcEncCfg->getBIM()) && pps.getMaxCuDQPDepth() >= 1)
#else
#if JVET_V0078
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable()) && pps.getMaxCuDQPDepth() >= 1)
#else
if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() && pps.getMaxCuDQPDepth() >= 1 )
#endif
#endif
{
splitTotalCost += pcSubBestPartCU->getTotalCost();
......@@ -1039,10 +1076,14 @@ Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const
{
m_pcEntropyCoder->resetBits();
m_pcEntropyCoder->encodeSplitFlag( rpcTempCU, 0, uiDepth, true );
#if JVET_Y0077_BIM
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable() || m_pcEncCfg->getBIM()) && pps.getMaxCuDQPDepth() >= 1)
#else
#if JVET_V0078
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable()) && pps.getMaxCuDQPDepth() >= 1)
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable()) && pps.getMaxCuDQPDepth() >= 1)
#else
if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() && pps.getMaxCuDQPDepth() >= 1 )
if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() && pps.getMaxCuDQPDepth() >= 1 )
#endif
#endif
{
Int splitBits = m_pcEntropyCoder->getNumberOfWrittenBits();
......@@ -1054,10 +1095,14 @@ Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, const
rpcTempCU->getTotalBins() += ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
}
#if JVET_Y0077_BIM
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable() || m_pcEncCfg->getBIM()) && pps.getMaxCuDQPDepth() >= 1)
#else
#if JVET_V0078
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable()) && pps.getMaxCuDQPDepth() >= 1)
if ((m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || m_pcEncCfg->getSmoothQPReductionEnable()) && pps.getMaxCuDQPDepth() >= 1)
#else
if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() && pps.getMaxCuDQPDepth() >= 1 )
if ( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() && pps.getMaxCuDQPDepth() >= 1 )
#endif
#endif
{
rpcTempCU->getTotalCost() = splitTotalCost;
......
......@@ -89,6 +89,9 @@ private:
#if JVET_V0078
Int m_smoothQPoffset;
#endif
#if JVET_Y0077_BIM
Int m_BimQPoffset;
#endif
// Access channel
TEncCfg* m_pcEncCfg;
......
......@@ -82,6 +82,10 @@ const Double TEncTemporalFilter::s_refStrengths[2][2] =
{1.20, 1.00}, // w/o future refs
};
#endif
#if JVET_Y0077_BIM
const Int TEncTemporalFilter::s_cuTreeThresh[4] =
{ 75, 60, 30, 15 };
#endif
TEncTemporalFilter::TEncTemporalFilter() :
m_FrameSkip(0),
......@@ -113,7 +117,14 @@ void TEncTemporalFilter::init(const Int frameSkip,
const Int pastRefs,
const Int futureRefs,
const Int firstValidFrame,
#if !JVET_Y0077_BIM
const Int lastValidFrame)
#else
const Int lastValidFrame,
const Bool mctfEnabled,
std::map<Int, Int*> *adaptQPmap,
const Bool bimEnabled)
#endif
{
m_FrameSkip = frameSkip;
for (Int i = 0; i < MAX_NUM_CHANNEL_TYPE; i++)
......@@ -142,6 +153,12 @@ void TEncTemporalFilter::init(const Int frameSkip,
m_futureRefs = futureRefs;
m_firstValidFrame = firstValidFrame;
m_lastValidFrame = lastValidFrame;
#if JVET_Y0077_BIM
m_mctfEnabled = mctfEnabled;
m_bimEnabled = bimEnabled;
m_numCTU = ((width + 63) / 64) * ((height + 63) / 64);
m_ctuAdaptQP = adaptQPmap;
#endif
}
// ====================================================================================================================
......@@ -231,11 +248,86 @@ Bool TEncTemporalFilter::filter(TComPicYuv *orgPic, Int receivedPoc)
overallStrength = strength;
}
}
#if JVET_Y0077_BIM
const int numRefs = Int(srcFrameInfo.size());
if ( m_bimEnabled && ( numRefs > 0 ) )
{
const Int bimFirstFrame = std::max(currentFilePoc - 2, firstFrame);
const Int bimLastFrame = std::min(currentFilePoc + 2, lastFrame);
std::vector<Double> sumError(m_numCTU * 2, 0);
std::vector<Int> blkCount(m_numCTU * 2, 0);
int frameIndex = bimFirstFrame - firstFrame;
Int distFactor[2] = {3,3};
Int* qpMap = new Int[m_numCTU];
for (int poc = bimFirstFrame; poc <= bimLastFrame; poc++)
{
if ((poc < 0) || (poc == currentFilePoc) || (frameIndex >= numRefs))
{
continue;
}
Int dist = abs(poc - currentFilePoc) - 1;
distFactor[dist]--;
TemporalFilterSourcePicInfo &srcPic = srcFrameInfo.at(frameIndex);
for (Int y = 0; y < srcPic.mvs.h() / 2; y++) // going over in 8x8 block steps
{
for (Int x = 0; x < srcPic.mvs.w() / 2; x++)
{
Int blocksPerRow = (srcPic.mvs.w() / 2 + 7) / 8;
Int ctuX = x / 8;
Int ctuY = y / 8;
Int ctuId = ctuY * blocksPerRow + ctuX;
sumError[dist * m_numCTU + ctuId] += srcPic.mvs.get(x, y).error;
blkCount[dist * m_numCTU + ctuId] += 1;
}
}
frameIndex++;
}
Double weight = (receivedPoc % 16) ? 0.6 : 1;
const Double center = 45.0;
for (Int i = 0; i < m_numCTU; i++)
{
Int avgErrD1 = (Int)((sumError[i] / blkCount[i]) * distFactor[0]);
Int avgErrD2 = (Int)((sumError[i + m_numCTU] / blkCount[i + m_numCTU]) * distFactor[1]);
Int weightedErr = std::max(avgErrD1, avgErrD2) + abs(avgErrD2 - avgErrD1) * 3;
weightedErr = (Int)(weightedErr * weight + (1 - weight) * center);
if (weightedErr > s_cuTreeThresh[0])
{
qpMap[i] = 2;
}
else if (weightedErr > s_cuTreeThresh[1])
{
qpMap[i] = 1;
}
else if (weightedErr < s_cuTreeThresh[3])
{
qpMap[i] = -2;
}
else if (weightedErr < s_cuTreeThresh[2])
{
qpMap[i] = -1;
}
else
{
qpMap[i] = 0;
}
}
m_ctuAdaptQP->insert({ receivedPoc, qpMap });
}
if ( m_mctfEnabled && ( numRefs > 0 ) )
{
#endif
bilateralFilter(origPadded, srcFrameInfo, newOrgPic, overallStrength);
// move filtered to orgPic
newOrgPic.copyToPic(orgPic);
#if JVET_Y0077_BIM
}
#endif
yuvFrames.close();
return true;
......@@ -281,7 +373,7 @@ Int TEncTemporalFilter::motionErrorLuma(const TComPicYuv &orig,
Int dx,
Int dy,
const Int bs,
const Int besterror = 8 * 8 * 1024 * 1024) const
const Int besterror /* = 8 * 8 * 1024 * 1024*/) const
{
const Pel* origOrigin = orig.getAddr(COMPONENT_Y);
......@@ -369,7 +461,7 @@ Int TEncTemporalFilter::motionErrorLuma(const TComPicYuv &orig,
Void TEncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const TComPicYuv &orig, const TComPicYuv &buffer, const Int blockSize,
const Array2D<MotionVector> *previous, const Int factor, const Bool doubleRes) const
{
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
Int range = doubleRes ? 0 : 5;
#else
Int range = 5;
......@@ -379,7 +471,7 @@ Void TEncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const
const Int origWidth = orig.getWidth(COMPONENT_Y);
const Int origHeight = orig.getHeight(COMPONENT_Y);
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
for (Int blockY = 0; blockY + blockSize <= origHeight; blockY += stepSize)
{
for (Int blockX = 0; blockX + blockSize <= origWidth; blockX += stepSize)
......@@ -397,14 +489,14 @@ Void TEncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const
}
else
{
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
for (Int py = -1; py <= 1; py++)
#else
for (Int py = -2; py <= 2; py++)
#endif
{
Int testy = blockY / (2 * blockSize) + py;
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
for (Int px = -1; px <= 1; px++)
#else
for (Int px = -2; px <= 2; px++)
......@@ -422,7 +514,7 @@ Void TEncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const
}
}
}
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
Int error = motionErrorLuma(orig, buffer, blockX, blockY, 0, 0, blockSize, best.error);
if (error < best.error)
{
......@@ -472,7 +564,7 @@ Void TEncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const
}
}
}
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
if (blockY > 0)
{
MotionVector aboveMV = mvs.get(blockX / stepSize, (blockY - stepSize) / stepSize);
......@@ -627,7 +719,7 @@ Void TEncTemporalFilter::applyMotion(const Array2D<MotionVector> &mvs, const TCo
}
Void TEncTemporalFilter::bilateralFilter(const TComPicYuv &orgPic,
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo,
#else
const std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo,
......@@ -661,7 +753,7 @@ Void TEncTemporalFilter::bilateralFilter(const TComPicYuv &orgPic,
const Double weightScaling = overallStrength * (isChroma(compID) ? s_chromaFactor : 0.4);
const Pel maxSampleValue = (1<<m_internalBitDepth[toChannelType(compID)])-1;
const Double bitDepthDiffWeighting=1024.0 / (maxSampleValue+1);
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
static const Int lumaBlockSize=8;
const Int csx=getComponentScaleX(compID, m_chromaFormatIDC);
const Int csy=getComponentScaleY(compID, m_chromaFormatIDC);
......@@ -678,7 +770,7 @@ Void TEncTemporalFilter::bilateralFilter(const TComPicYuv &orgPic,
const Int orgVal = (Int) *srcPel;
Double temporalWeightSum = 1.0;
Double newVal = (Double) orgVal;
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
if ((y % blkSizeY == 0) && (x % blkSizeX == 0))
{
for (Int i = 0; i < numRefs; i++)
......@@ -729,7 +821,7 @@ Void TEncTemporalFilter::bilateralFilter(const TComPicYuv &orgPic,
#endif
for (Int i = 0; i < numRefs; i++)
{
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
const Int error = srcFrameInfo[i].mvs.get(x / blkSizeX, y / blkSizeY).error;
const Int noise = srcFrameInfo[i].mvs.get(x / blkSizeX, y / blkSizeY).noise;
#endif
......@@ -738,7 +830,7 @@ Void TEncTemporalFilter::bilateralFilter(const TComPicYuv &orgPic,
Double diff = (Double)(refVal - orgVal);
diff *= bitDepthDiffWeighting;
Double diffSq = diff * diff;
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
const Int index = std::min(3, std::abs(srcFrameInfo[i].origOffset) - 1);
Double ww = 1, sw = 1;
ww *= (noise < 25) ? 1 : 1.2;
......
......@@ -50,7 +50,7 @@ struct MotionVector
{
Int x, y;
Int error;
#if JVET_V0056_MCTF
#if JVET_V0056_MCTF || JVET_Y0077_BIM
Int noise;
MotionVector() : x(0), y(0), error(INT_LEAST32_MAX), noise(0) {}
#else
......@@ -69,6 +69,11 @@ public:
Array2D() : m_width(0), m_height(0), v() { }
Array2D(UInt width, UInt height, const T& value=T()) : m_width(0), m_height(0), v() { allocate(width, height, value); }
#if JVET_Y0077_BIM
UInt w() const { return m_width; }
UInt h() const { return m_height; }
#endif
Void allocate(UInt width, UInt height, const T& value=T())
{
m_width=width;
......@@ -124,7 +129,14 @@ public:
const Int pastRefs,
const Int futureRefs,
const Int firstValidFrame,
#if !JVET_Y0077_BIM
const Int lastValidFrame);
#else
const Int lastValidFrame,
const Bool mctfEnabled,
std::map<Int, Int*> *adaptQPmap,
const Bool bimEnabled);
#endif
Bool filter(TComPicYuv *orgPic, Int frame);
......@@ -141,6 +153,9 @@ private:
#else
static const Double s_refStrengths[2][2];
#endif
#if JVET_Y0077_BIM
static const Int s_cuTreeThresh[4];
#endif
// Private member variables
Int m_FrameSkip;
......@@ -162,10 +177,16 @@ private:
Int m_futureRefs;
Int m_firstValidFrame;
Int m_lastValidFrame;
#if JVET_Y0077_BIM
Bool m_mctfEnabled;
Bool m_bimEnabled;
Int m_numCTU;
std::map<Int, Int*> *m_ctuAdaptQP;
#endif
// Private functions
Void subsampleLuma(const TComPicYuv &input, TComPicYuv &output, const Int factor = 2) const;
Int motionErrorLuma(const TComPicYuv &orig, const TComPicYuv &buffer, const Int x, const Int y, Int dx, Int dy, const Int bs, const Int besterror) const;
Int motionErrorLuma(const TComPicYuv &orig, const TComPicYuv &buffer, const Int x, const Int y, Int dx, Int dy, const Int bs, const Int besterror = 8 * 8 * 1024 * 1024) const;
Void motionEstimationLuma(Array2D<MotionVector> &mvs, const TComPicYuv &orig, const TComPicYuv &buffer, const Int bs,
const Array2D<MotionVector> *previous=0, const Int factor = 1, const Bool doubleRes = false) const;
Void motionEstimation(Array2D<MotionVector> &mvs, const TComPicYuv &orgPic, const TComPicYuv &buffer, const TComPicYuv &origSubsampled2, const TComPicYuv &origSubsampled4) const;
......
......@@ -955,7 +955,13 @@ Void TEncTop::xInitPPS(TComPPS &pps, const TComSPS &sps)
#if JVET_V0078
if (getSmoothQPReductionEnable())
{
bUseDQP = true;
bUseDQP = true;
}
#endif
#if JVET_Y0077_BIM
if (m_bimEnabled)
{
bUseDQP = true;
}
#endif
......@@ -1452,10 +1458,14 @@ Int TEncCfg::getQPForPicture(const UInt gopIndex, const TComSlice *pSlice) const
else
{
// Only adjust QP when not lossless
#if JVET_Y0077_BIM
if (!((getMaxDeltaQP() == 0) && (!getLumaLevelToDeltaQPMapping().isEnabled()) && (!getSmoothQPReductionEnable()) && (!getBIM()) && (qp == -lumaQpBDOffset) && (pSlice->getPPS()->getTransquantBypassEnabledFlag())))
#else
#if JVET_V0078
if (!((getMaxDeltaQP() == 0) && (!getLumaLevelToDeltaQPMapping().isEnabled()) && (!getSmoothQPReductionEnable()) && (qp == -lumaQpBDOffset) && (pSlice->getPPS()->getTransquantBypassEnabledFlag())))
#else
if (!(( getMaxDeltaQP() == 0 ) && (!getLumaLevelToDeltaQPMapping().isEnabled()) && (qp == -lumaQpBDOffset ) && (pSlice->getPPS()->getTransquantBypassEnabledFlag())))
#endif
#endif
{
const GOPEntry &gopEntry=getGOPEntry(gopIndex);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment