diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 55e624649adaec26da58f6f91ee29bfc95a1a8f4..8af59c7fab7bbb38045894981730f09d20bd3bd4 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -54,6 +54,8 @@ //########### place macros to be removed in next cycle below this line ############### +#define JVET_V0056 1 // MCTF changes as presented in JVET-V0056 + #define JVET_S0096_RPL_CONSTRAINT 1// JVET-S0096 aspect 1: When pps_rpl_info_in_ph_flag is equal to 1 and ph_inter_slice_allowed_flag is equal to 1, the value of num_ref_entries[ 0 ][ RplsIdx[ 0 ] ] shall be greater than 0. #define JVET_S0078_NOOUTPUTPRIORPICFLAG 0 // JVET-S0078: Handling of NoOutputOfPriorPicsFlag in output process #define JVET_S0219_ASPECT1 1 // JVET-S0219 aspect1 : removal non-referred APS parameter set in the non-output layer. diff --git a/source/Lib/EncoderLib/EncTemporalFilter.cpp b/source/Lib/EncoderLib/EncTemporalFilter.cpp index c9c74336ff102cc7074193b3fbf0262267fea1ab..18ae4e37dc2142cf154a4ff2e66910b16d6627b3 100644 --- a/source/Lib/EncoderLib/EncTemporalFilter.cpp +++ b/source/Lib/EncoderLib/EncTemporalFilter.cpp @@ -43,10 +43,14 @@ // Constructor / destructor / initialization / destroy // ==================================================================================================================== +#if JVET_V0056 +const int EncTemporalFilter::m_range = 4; +#else const int EncTemporalFilter::m_range = 2; -const double EncTemporalFilter::m_chromaFactor = 0.55; -const double EncTemporalFilter::m_sigmaMultiplier = 9.0; -const double EncTemporalFilter::m_sigmaZeroPoint = 10.0; +#endif +const double EncTemporalFilter::m_chromaFactor = 0.55; +const double EncTemporalFilter::m_sigmaMultiplier = 9.0; +const double EncTemporalFilter::m_sigmaZeroPoint = 10.0; const int EncTemporalFilter::m_motionVectorFactor = 16; const int EncTemporalFilter::m_padding = 128; const int EncTemporalFilter::m_interpolationFilter[16][8] = @@ -69,6 +73,15 @@ const int EncTemporalFilter::m_interpolationFilter[16][8] = { 0, 0, -2, 4, 64, -3, 1, 0 } //15-->--> }; +#if JVET_V0056 +const double EncTemporalFilter::m_refStrengths[3][4] = +{ // abs(POC offset) + // 1, 2 3 4 + {0.85, 0.57, 0.41, 0.33}, // m_range * 2 + {1.13, 0.97, 0.81, 0.57}, // m_range + {0.30, 0.30, 0.30, 0.30} // otherwise +}; +#else const double EncTemporalFilter::m_refStrengths[3][2] = { // abs(POC offset) // 1, 2 @@ -76,6 +89,7 @@ const double EncTemporalFilter::m_refStrengths[3][2] = {1.20, 1.00}, // m_range {0.30, 0.30} // otherwise }; +#endif EncTemporalFilter::EncTemporalFilter() : m_FrameSkip(0), @@ -105,23 +119,23 @@ void EncTemporalFilter::init(const int frameSkip, m_FrameSkip = frameSkip; for (int i = 0; i < MAX_NUM_CHANNEL_TYPE; i++) { - m_inputBitDepth[i] = inputBitDepth[i]; + m_inputBitDepth[i] = inputBitDepth[i]; m_MSBExtendedBitDepth[i] = msbExtendedBitDepth[i]; - m_internalBitDepth[i] = internalBitDepth[i]; + m_internalBitDepth[i] = internalBitDepth[i]; } - m_sourceWidth = width; + m_sourceWidth = width; m_sourceHeight = height; for (int i = 0; i < 2; i++) { m_pad[i] = pad[i]; } m_clipInputVideoToRec709Range = rec709; - m_inputFileName = filename; + m_inputFileName = filename; m_chromaFormatIDC = inputChromaFormatIDC; m_inputColourSpaceConvert = colorSpaceConv; m_area = Area(0, 0, width, height); - m_QP = qp; + m_QP = qp; m_temporalFilterStrengths = temporalFilterStrengths; m_gopBasedTemporalFilterFutureReference = gopBasedTemporalFilterFutureReference; } @@ -153,11 +167,10 @@ bool EncTemporalFilter::filter(PelStorage *orgPic, int receivedPoc) yuvFrames.open(m_inputFileName, false, m_inputBitDepth, m_MSBExtendedBitDepth, m_internalBitDepth); yuvFrames.skipFrames(std::max(offset + receivedPoc - m_range, 0), m_sourceWidth - m_pad[0], m_sourceHeight - m_pad[1], m_chromaFormatIDC); - std::deque<TemporalFilterSourcePicInfo> srcFrameInfo; int firstFrame = receivedPoc + offset - m_range; - int lastFrame = receivedPoc + offset + m_range; + int lastFrame = receivedPoc + offset + m_range; if (!m_gopBasedTemporalFilterFutureReference) { lastFrame = receivedPoc + offset - 1; @@ -192,7 +205,7 @@ bool EncTemporalFilter::filter(PelStorage *orgPic, int receivedPoc) continue; } srcFrameInfo.push_back(TemporalFilterSourcePicInfo()); - TemporalFilterSourcePicInfo &srcPic=srcFrameInfo.back(); + TemporalFilterSourcePicInfo &srcPic = srcFrameInfo.back(); PelStorage dummyPicBufferTO; // Only used temporary in yuvFrames.read srcPic.picBuffer.create(m_chromaFormatIDC, m_area, 0, m_padding); @@ -240,20 +253,20 @@ bool EncTemporalFilter::filter(PelStorage *orgPic, int receivedPoc) void EncTemporalFilter::subsampleLuma(const PelStorage &input, PelStorage &output, const int factor) const { - const int newWidth = input.Y().width / factor; + const int newWidth = input.Y().width / factor; const int newHeight = input.Y().height / factor; output.create(m_chromaFormatIDC, Area(0, 0, newWidth, newHeight), 0, m_padding); - const Pel* srcRow = input.Y().buf; + const Pel* srcRow = input.Y().buf; const int srcStride = input.Y().stride; - Pel *dstRow = output.Y().buf; + Pel *dstRow = output.Y().buf; const int dstStride = output.Y().stride; - for (int y = 0; y < newHeight; y++, srcRow+=factor*srcStride, dstRow+=dstStride) + for (int y = 0; y < newHeight; y++, srcRow += factor * srcStride, dstRow += dstStride) { const Pel *inRow = srcRow; - const Pel *inRowBelow = srcRow+srcStride; - Pel *target = dstRow; + const Pel *inRowBelow = srcRow + srcStride; + Pel *target = dstRow; for (int x = 0; x < newWidth; x++) { @@ -275,19 +288,19 @@ int EncTemporalFilter::motionErrorLuma(const PelStorage &orig, const int besterror = 8 * 8 * 1024 * 1024) const { const Pel* origOrigin = orig.Y().buf; - const int origStride = orig.Y().stride; - const Pel *buffOrigin = buffer.Y().buf; - const int buffStride = buffer.Y().stride; + const int origStride = orig.Y().stride; + const Pel* buffOrigin = buffer.Y().buf; + const int buffStride = buffer.Y().stride; - int error = 0;// dx * 10 + dy * 10; + int error = 0; if (((dx | dy) & 0xF) == 0) { dx /= m_motionVectorFactor; dy /= m_motionVectorFactor; for (int y1 = 0; y1 < bs; y1++) { - const Pel* origRowStart = origOrigin + (y+y1)*origStride + x; - const Pel* bufferRowStart = buffOrigin + (y+y1+dy)*buffStride + (x+dx); + const Pel* origRowStart = origOrigin + (y + y1) * origStride + x; + const Pel* bufferRowStart = buffOrigin + (y + y1 + dy) * buffStride + (x + dx); for (int x1 = 0; x1 < bs; x1 += 2) { int diff = origRowStart[x1] - bufferRowStart[x1]; @@ -311,7 +324,7 @@ int EncTemporalFilter::motionErrorLuma(const PelStorage &orig, for (int y1 = 1; y1 < bs + 7; y1++) { const int yOffset = y + y1 + (dy >> 4) - 3; - const Pel *sourceRow = buffOrigin + (yOffset)*buffStride + 0; + const Pel *sourceRow = buffOrigin + yOffset * buffStride + 0; for (int x1 = 0; x1 < bs; x1++) { sum = 0; @@ -329,10 +342,10 @@ int EncTemporalFilter::motionErrorLuma(const PelStorage &orig, } } - const Pel maxSampleValue = (1<<m_internalBitDepth[CHANNEL_TYPE_LUMA])-1; + const Pel maxSampleValue = (1 << m_internalBitDepth[CHANNEL_TYPE_LUMA]) - 1; for (int y1 = 0; y1 < bs; y1++) { - const Pel *origRow = origOrigin + (y+y1)*origStride + 0; + const Pel *origRow = origOrigin + (y + y1) * origStride; for (int x1 = 0; x1 < bs; x1++) { sum = 0; @@ -360,15 +373,25 @@ int EncTemporalFilter::motionErrorLuma(const PelStorage &orig, void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const PelStorage &orig, const PelStorage &buffer, const int blockSize, const Array2D<MotionVector> *previous, const int factor, const bool doubleRes) const { +#if JVET_V0056 + int range = doubleRes ? 0 : 5; +#else int range = 5; +#endif const int stepSize = blockSize; const int origWidth = orig.Y().width; const int origHeight = orig.Y().height; +#if JVET_V0056 + for (int blockY = 0; blockY + blockSize <= origHeight; blockY += stepSize) + { + for (int blockX = 0; blockX + blockSize <= origWidth; blockX += stepSize) +#else for (int blockY = 0; blockY + blockSize < origHeight; blockY += stepSize) { for (int blockX = 0; blockX + blockSize < origWidth; blockX += stepSize) +#endif { MotionVector best; @@ -378,10 +401,18 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P } else { +#if JVET_V0056 + 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 + for (int px = -1; px <= 1; px++) +#else for (int px = -2; px <= 2; px++) +#endif { int testx = blockX / (2 * blockSize) + px; if ((testx >= 0) && (testx < origWidth / (2 * blockSize)) && (testy >= 0) && (testy < origHeight / (2 * blockSize))) @@ -395,6 +426,13 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P } } } +#if JVET_V0056 + int error = motionErrorLuma(orig, buffer, blockX, blockY, 0, 0, blockSize, best.error); + if (error < best.error) + { + best.set(0, 0, error); + } +#endif } MotionVector prevBest = best; for (int y2 = prevBest.y / m_motionVectorFactor - range; y2 <= prevBest.y / m_motionVectorFactor + range; y2++) @@ -409,7 +447,7 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P } } if (doubleRes) - { // merge into one loop, probably with precision array (here [12, 3] or maybe [4, 1]) with setable number of iterations + { prevBest = best; int doubleRange = 3 * 4; for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y + doubleRange; y2 += 4) @@ -421,7 +459,6 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P { best.set(x2, y2, error); } - } } @@ -436,11 +473,53 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P { best.set(x2, y2, error); } - } } + } +#if JVET_V0056 + if (blockY > 0) + { + MotionVector aboveMV = mvs.get(blockX / stepSize, (blockY - stepSize) / stepSize); + int error = motionErrorLuma(orig, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize, best.error); + if (error < best.error) + { + best.set(aboveMV.x, aboveMV.y, error); + } + } + if (blockX > 0) + { + MotionVector leftMV = mvs.get((blockX - stepSize) / stepSize, blockY / stepSize); + int error = motionErrorLuma(orig, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize, best.error); + if (error < best.error) + { + best.set(leftMV.x, leftMV.y, error); + } } + + // calculate average + double avg = 0.0; + for (int x1 = 0; x1 < blockSize; x1++) + { + for (int y1 = 0; y1 < blockSize; y1++) + { + avg = avg + orig.Y().at(blockX + x1, blockY + y1); + } + } + avg = avg / (blockSize * blockSize); + + // calculate variance + double variance = 0; + for (int x1 = 0; x1 < blockSize; x1++) + { + for (int y1 = 0; y1 < blockSize; y1++) + { + int pix = orig.Y().at(blockX + x1, blockY + y1); + variance = variance + (pix - avg) * (pix - avg); + } + } + best.error = (int)(20 * ((best.error + 5.0) / (variance + 5.0)) + (best.error / (blockSize * blockSize)) / 50); +#endif mvs.get(blockX / stepSize, blockY / stepSize) = best; } } @@ -448,7 +527,7 @@ void EncTemporalFilter::motionEstimationLuma(Array2D<MotionVector> &mvs, const P void EncTemporalFilter::motionEstimation(Array2D<MotionVector> &mv, const PelStorage &orgPic, const PelStorage &buffer, const PelStorage &origSubsampled2, const PelStorage &origSubsampled4) const { - const int width = m_sourceWidth; + const int width = m_sourceWidth; const int height = m_sourceHeight; Array2D<MotionVector> mv_0(width / 16, height / 16); Array2D<MotionVector> mv_1(width / 16, height / 16); @@ -469,25 +548,25 @@ void EncTemporalFilter::motionEstimation(Array2D<MotionVector> &mv, const PelSto void EncTemporalFilter::applyMotion(const Array2D<MotionVector> &mvs, const PelStorage &input, PelStorage &output) const { - static const int lumaBlockSize=8; + static const int lumaBlockSize = 8; - for(int c=0; c< getNumberValidComponents(m_chromaFormatIDC); c++) + for(int c = 0; c < getNumberValidComponents(m_chromaFormatIDC); c++) { - const ComponentID compID=(ComponentID)c; - const int csx=getComponentScaleX(compID, m_chromaFormatIDC); - const int csy=getComponentScaleY(compID, m_chromaFormatIDC); - const int blockSizeX = lumaBlockSize>>csx; - const int blockSizeY = lumaBlockSize>>csy; + const ComponentID compID = (ComponentID)c; + const int csx = getComponentScaleX(compID, m_chromaFormatIDC); + const int csy = getComponentScaleY(compID, m_chromaFormatIDC); + const int blockSizeX = lumaBlockSize >> csx; + const int blockSizeY = lumaBlockSize >> csy; const int height = input.bufs[c].height; const int width = input.bufs[c].width; - const Pel maxValue = (1<<m_internalBitDepth[toChannelType(compID)])-1; + const Pel maxValue = (1 << m_internalBitDepth[toChannelType(compID)]) - 1; const Pel *srcImage = input.bufs[c].buf; - const int srcStride = input.bufs[c].stride; + const int srcStride = input.bufs[c].stride; Pel *dstImage = output.bufs[c].buf; - int dstStride = output.bufs[c].stride; + int dstStride = output.bufs[c].stride; for (int y = 0, blockNumY = 0; y + blockSizeY <= height; y += blockSizeY, blockNumY++) { @@ -496,23 +575,23 @@ void EncTemporalFilter::applyMotion(const Array2D<MotionVector> &mvs, const PelS const MotionVector &mv = mvs.get(blockNumX,blockNumY); const int dx = mv.x >> csx ; const int dy = mv.y >> csy ; - const int xInt = mv.x >> (4+csx) ; - const int yInt = mv.y >> (4+csy) ; + const int xInt = mv.x >> (4 + csx) ; + const int yInt = mv.y >> (4 + csy) ; const int *xFilter = m_interpolationFilter[dx & 0xf]; const int *yFilter = m_interpolationFilter[dy & 0xf]; // will add 6 bit. - const int numFilterTaps=7; - const int centreTapOffset=3; + const int numFilterTaps = 7; + const int centerTapOffset = 3; int tempArray[lumaBlockSize + numFilterTaps][lumaBlockSize]; for (int by = 1; by < blockSizeY + numFilterTaps; by++) { - const int yOffset = y + by + yInt - centreTapOffset; - const Pel *sourceRow = srcImage+yOffset*srcStride; + const int yOffset = y + by + yInt - centerTapOffset; + const Pel *sourceRow = srcImage + yOffset * srcStride; for (int bx = 0; bx < blockSizeX; bx++) { - int base = x + bx + xInt - centreTapOffset; + int base = x + bx + xInt - centerTapOffset; const Pel *rowStart = sourceRow + base; int sum = 0; @@ -527,10 +606,10 @@ void EncTemporalFilter::applyMotion(const Array2D<MotionVector> &mvs, const PelS } } - Pel *dstRow = dstImage+y*dstStride; - for (int by = 0; by < blockSizeY; by++, dstRow+=dstStride) + Pel *dstRow = dstImage + y * dstStride; + for (int by = 0; by < blockSizeY; by++, dstRow += dstStride) { - Pel *dstPel=dstRow+x; + Pel *dstPel = dstRow + x; for (int bx = 0; bx < blockSizeX; bx++, dstPel++) { int sum = 0; @@ -553,7 +632,11 @@ void EncTemporalFilter::applyMotion(const Array2D<MotionVector> &mvs, const PelS } void EncTemporalFilter::bilateralFilter(const PelStorage &orgPic, +#if JVET_V0056 + std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, +#else const std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, +#endif PelStorage &newOrgPic, double overallStrength) const { @@ -566,7 +649,7 @@ void EncTemporalFilter::bilateralFilter(const PelStorage &orgPic, } int refStrengthRow = 2; - if (numRefs == m_range*2) + if (numRefs == m_range * 2) { refStrengthRow = 0; } @@ -578,44 +661,101 @@ void EncTemporalFilter::bilateralFilter(const PelStorage &orgPic, const double lumaSigmaSq = (m_QP - m_sigmaZeroPoint) * (m_QP - m_sigmaZeroPoint) * m_sigmaMultiplier; const double chromaSigmaSq = 30 * 30; - for(int c=0; c< getNumberValidComponents(m_chromaFormatIDC); c++) + for(int c = 0; c < getNumberValidComponents(m_chromaFormatIDC); c++) { - const ComponentID compID=(ComponentID)c; + const ComponentID compID = (ComponentID)c; const int height = orgPic.bufs[c].height; const int width = orgPic.bufs[c].width; - const Pel *srcPelRow = orgPic.bufs[c].buf; - const int srcStride = orgPic.bufs[c].stride; - Pel *dstPelRow = newOrgPic.bufs[c].buf; - const int dstStride = newOrgPic.bufs[c].stride; - const double sigmaSq = isChroma(compID)? chromaSigmaSq : lumaSigmaSq; + const Pel* srcPelRow = orgPic.bufs[c].buf; + const int srcStride = orgPic.bufs[c].stride; + Pel* dstPelRow = newOrgPic.bufs[c].buf; + const int dstStride = newOrgPic.bufs[c].stride; + const double sigmaSq = isChroma(compID) ? chromaSigmaSq : lumaSigmaSq; const double weightScaling = overallStrength * (isChroma(compID) ? m_chromaFactor : 0.4); - const Pel maxSampleValue = (1<<m_internalBitDepth[toChannelType(compID)])-1; - const double bitDepthDiffWeighting=1024.0 / (maxSampleValue+1); - - for (int y = 0; y < height; y++, srcPelRow+=srcStride, dstPelRow+=dstStride) + const Pel maxSampleValue = (1 << m_internalBitDepth[toChannelType(compID)]) - 1; + const double bitDepthDiffWeighting = 1024.0 / (maxSampleValue + 1); +#if JVET_V0056 + const int lumaBlockSize = 8; + const int csx = getComponentScaleX(compID, m_chromaFormatIDC); + const int csy = getComponentScaleY(compID, m_chromaFormatIDC); + const int blockSizeX = lumaBlockSize >> csx; + const int blockSizeY = lumaBlockSize >> csy; +#endif + + for (int y = 0; y < height; y++, srcPelRow += srcStride, dstPelRow += dstStride) { - const Pel *srcPel=srcPelRow; - Pel *dstPel=dstPelRow; + const Pel *srcPel = srcPelRow; + Pel *dstPel = dstPelRow; for (int x = 0; x < width; x++, srcPel++, dstPel++) { const int orgVal = (int) *srcPel; double temporalWeightSum = 1.0; double newVal = (double) orgVal; +#if JVET_V0056 + if ((y % blockSizeY == 0) && (x % blockSizeX == 0)) + { + for (int i = 0; i < numRefs; i++) + { + double variance = 0, diffsum = 0; + for (int y1 = 0; y1 < blockSizeY - 1; y1++) + { + for (int x1 = 0; x1 < blockSizeX - 1; x1++) + { + int pix = *(srcPel + x1); + int pixR = *(srcPel + x1 + 1); + int pixD = *(srcPel + x1 + srcStride); + int ref = *(correctedPics[i].bufs[c].buf + ((y + y1) * correctedPics[i].bufs[c].stride + x + x1)); + int refR = *(correctedPics[i].bufs[c].buf + ((y + y1) * correctedPics[i].bufs[c].stride + x + x1 + 1)); + int refD = *(correctedPics[i].bufs[c].buf + ((y + y1 + 1) * correctedPics[i].bufs[c].stride + x + x1)); + + int diff = pix - ref; + int diffR = pixR - refR; + int diffD = pixD - refD; + + variance += diff * diff; + diffsum += (diffR - diff) * (diffR - diff); + diffsum += (diffD - diff) * (diffD - diff); + } + } + srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).noise = (int) round((300 * variance + 50) / (10 * diffsum + 50)); + } + } + double minError = 9999999; + for (int i = 0; i < numRefs; i++) + { + minError = std::min(minError, (double) srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).error); + } +#endif for (int i = 0; i < numRefs; i++) { - const Pel *pCorrectedPelPtr=correctedPics[i].bufs[c].buf+(y*correctedPics[i].bufs[c].stride+x); +#if JVET_V0056 + const int error = srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).error; + const int noise = srcFrameInfo[i].mvs.get(x / blockSizeX, y / blockSizeY).noise; +#endif + const Pel *pCorrectedPelPtr = correctedPics[i].bufs[c].buf + (y * correctedPics[i].bufs[c].stride + x); const int refVal = (int) *pCorrectedPelPtr; double diff = (double)(refVal - orgVal); diff *= bitDepthDiffWeighting; double diffSq = diff * diff; +#if JVET_V0056 + const int index = std::min(3, std::abs(srcFrameInfo[i].origOffset) - 1); + double ww = 1, sw = 1; + ww *= (noise < 25) ? 1.0 : 0.6; + sw *= (noise < 25) ? 1.0 : 0.8; + ww *= (error < 50) ? 1.2 : ((error > 100) ? 0.6 : 1.0); + sw *= (error < 50) ? 1.0 : 0.8; + ww *= ((minError + 1) / (error + 1)); + double weight = weightScaling * m_refStrengths[refStrengthRow][index] * ww * exp(-diffSq / (2 * sw * sigmaSq)); +#else const int index = std::min(1, std::abs(srcFrameInfo[i].origOffset) - 1); const double weight = weightScaling * m_refStrengths[refStrengthRow][index] * exp(-diffSq / (2 * sigmaSq)); +#endif newVal += weight * refVal; temporalWeightSum += weight; } newVal /= temporalWeightSum; Pel sampleVal = (Pel)round(newVal); - sampleVal=(sampleVal<0?0 : (sampleVal>maxSampleValue ? maxSampleValue : sampleVal)); + sampleVal = (sampleVal < 0 ? 0 : (sampleVal > maxSampleValue ? maxSampleValue : sampleVal)); *dstPel = sampleVal; } } diff --git a/source/Lib/EncoderLib/EncTemporalFilter.h b/source/Lib/EncoderLib/EncTemporalFilter.h index b46b265dc783b548290155278be0aa3708ab5f41..01848881097f24a87e515850e9c8aa49dfa3cdfd 100644 --- a/source/Lib/EncoderLib/EncTemporalFilter.h +++ b/source/Lib/EncoderLib/EncTemporalFilter.h @@ -51,7 +51,12 @@ struct MotionVector { int x, y; int error; +#if JVET_V0056 + int noise; + MotionVector() : x(0), y(0), error(INT_LEAST32_MAX), noise(0) {} +#else MotionVector() : x(0), y(0), error(INT_LEAST32_MAX) {} +#endif void set(int vectorX, int vectorY, int errorValue) { x = vectorX; y = vectorY; error = errorValue; } }; @@ -67,21 +72,21 @@ public: void allocate(int width, int height, const T& value=T()) { - m_width=width; - m_height=height; - v.resize(std::size_t(m_width*m_height), value); + m_width = width; + m_height = height; + v.resize(std::size_t(m_width * m_height), value); } T& get(int x, int y) { - assert(x<m_width && y<m_height); - return v[y*m_width+x]; + assert(x < m_width && y < m_height); + return v[y * m_width + x]; } const T& get(int x, int y) const { - assert(x<m_width && y<m_height); - return v[y*m_width+x]; + assert(x < m_width && y < m_height); + return v[y * m_width + x]; } }; @@ -129,7 +134,11 @@ private: static const int m_motionVectorFactor; static const int m_padding; static const int m_interpolationFilter[16][8]; +#if JVET_V0056 + static const double m_refStrengths[3][4]; +#else static const double m_refStrengths[3][2]; +#endif // Private member variables int m_FrameSkip; @@ -155,7 +164,11 @@ private: const Array2D<MotionVector> *previous=0, const int factor = 1, const bool doubleRes = false) const; void motionEstimation(Array2D<MotionVector> &mvs, const PelStorage &orgPic, const PelStorage &buffer, const PelStorage &origSubsampled2, const PelStorage &origSubsampled4) const; +#if JVET_V0056 + void bilateralFilter(const PelStorage &orgPic, std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, PelStorage &newOrgPic, double overallStrength) const; +#else void bilateralFilter(const PelStorage &orgPic, const std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, PelStorage &newOrgPic, double overallStrength) const; +#endif void applyMotion(const Array2D<MotionVector> &mvs, const PelStorage &input, PelStorage &output) const; }; // END CLASS DEFINITION EncTemporalFilter