diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 1d508ce9b06fff3460b4e9fe34adb8aae1969849..d5a41490e546733a46f4712f84eb34d539938ec0 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1701,8 +1701,7 @@ void EncGOP::xPicInitRateControl(int &estimatedBits, int gopId, double &lambda, } else if ( frameLevel == 0 ) // intra case, but use the model { - m_pcSliceEncoder->calCostSliceI(pic); // TODO: This only analyses the first slice segment - what about the others? - + m_pcSliceEncoder->calCostPictureI(pic); if ( m_pcCfg->getIntraPeriod() != 1 ) // do not refine allocated bits for all intra case { int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits(); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 46aa69ba7d5922ebee933821c8b612dc591fdfc0..c821cdbe78ee9a95f5181fc9cca78ee8d70ea6cf 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1268,6 +1268,30 @@ void EncSlice::calCostSliceI(Picture* pcPic) // TODO: this only analyses the fir m_pcRateCtrl->getRCPic()->setTotalIntraCost(iSumHadSlice); } +void EncSlice::calCostPictureI(Picture* picture) +{ + double sumHadPicture = 0; + Slice * const slice = picture->slices[getSliceSegmentIdx()]; + const PreCalcValues& pcv = *picture->cs->pcv; + const SPS &sps = *(slice->getSPS()); + const int shift = sps.getBitDepth(CHANNEL_TYPE_LUMA) - 8; + const int offset = (shift>0) ? (1 << (shift - 1)) : 0; + + for (uint32_t ctuIdx = 0; ctuIdx < picture->m_ctuNums; ctuIdx++) + { + Position pos((ctuIdx % pcv.widthInCtus) * pcv.maxCUWidth, (ctuIdx / pcv.widthInCtus) * pcv.maxCUHeight); + + const int height = std::min(pcv.maxCUHeight, pcv.lumaHeight - pos.y); + const int width = std::min(pcv.maxCUWidth, pcv.lumaWidth - pos.x); + const CompArea blk(COMPONENT_Y, pcv.chrFormat, pos, Size(width, height)); + int sumHad = m_pcCuEncoder->updateCtuDataISlice(picture->getOrigBuf(blk)); + + (m_pcRateCtrl->getRCPic()->getLCU(ctuIdx)).m_costIntra = (sumHad + offset) >> shift; + sumHadPicture += (m_pcRateCtrl->getRCPic()->getLCU(ctuIdx)).m_costIntra; + } + m_pcRateCtrl->getRCPic()->setTotalIntraCost(sumHadPicture); +} + /** \param pcPic picture class */ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP ) diff --git a/source/Lib/EncoderLib/EncSlice.h b/source/Lib/EncoderLib/EncSlice.h index aeff8eb1c0c5d88ce9a3b3578a7376e697986c43..be28672cc3f1eb065b7569a2070b3370029b2968 100644 --- a/source/Lib/EncoderLib/EncSlice.h +++ b/source/Lib/EncoderLib/EncSlice.h @@ -128,10 +128,10 @@ public: void precompressSlice ( Picture* pcPic ); ///< precompress slice for multi-loop slice-level QP opt. void compressSlice ( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP ); ///< analysis stage of slice void calCostSliceI ( Picture* pcPic ); + void calCostPictureI ( Picture* picture ); #if JVET_R0110_MIXED_LOSSLESS void setLosslessSlice(Picture* pcPic, bool b); ///< Set if the slice is lossless or not #endif - void encodeSlice ( Picture* pcPic, OutputBitstream* pcSubstreams, uint32_t &numBinsCoded ); void encodeCtus ( Picture* pcPic, const bool bCompressEntireSlice, const bool bFastDeltaQP, EncLib* pcEncLib ); void checkDisFracMmvd ( Picture* pcPic, uint32_t startCtuTsAddr, uint32_t boundingCtuTsAddr ); diff --git a/source/Lib/EncoderLib/RateCtrl.cpp b/source/Lib/EncoderLib/RateCtrl.cpp index d3d8682746c06f2535dd5f0f1e846b1ea8f03f01..38ce50ac957edde264fef1ed4f1f28a2406c7432 100644 --- a/source/Lib/EncoderLib/RateCtrl.cpp +++ b/source/Lib/EncoderLib/RateCtrl.cpp @@ -319,6 +319,11 @@ void EncRCGOP::create( EncRCSeq* encRCSeq, int numPic ) { destroy(); int targetBits = xEstGOPTargetBits( encRCSeq, numPic ); + int bitdepth_luma_scale = + 2 * (encRCSeq->getbitDepth() - 8 + - DISTORTION_PRECISION_ADJUSTMENT(encRCSeq->getbitDepth())); + m_minEstLambda = 0.1; + m_maxEstLambda = 10000.0 * pow(2.0, bitdepth_luma_scale); if ( encRCSeq->getAdaptiveBits() > 0 && encRCSeq->getLastLambda() > 0.1 ) { @@ -328,7 +333,7 @@ void EncRCGOP::create( EncRCSeq* encRCSeq, int numPic ) double* equaCoeffA = new double[encRCSeq->getGOPSize()]; double* equaCoeffB = new double[encRCSeq->getGOPSize()]; - if ( encRCSeq->getAdaptiveBits() == 1 ) // for GOP size =4, low delay case + if ( encRCSeq->getAdaptiveBits() == 1 && encRCSeq->getGOPSize() == 4) // for GOP size =4, low delay case { if ( encRCSeq->getLastLambda() < 120.0 ) { @@ -345,6 +350,31 @@ void EncRCGOP::create( EncRCSeq* encRCSeq, int numPic ) lambdaRatio[3] = 1.0; } } + else if (encRCSeq->getAdaptiveBits() == 1 && encRCSeq->getGOPSize() == 8) // for GOP size =8, low delay case + { + if (encRCSeq->getLastLambda() < 120.0) + { + lambdaRatio[1] = 0.725 * log(encRCSeq->getLastLambda()) + 0.5793; + lambdaRatio[3] = 0.725 * log(encRCSeq->getLastLambda()) + 0.5793; + lambdaRatio[5] = 0.725 * log(encRCSeq->getLastLambda()) + 0.5793; + lambdaRatio[0] = 1.3 * lambdaRatio[1]; + lambdaRatio[2] = 1.3 * lambdaRatio[1]; + lambdaRatio[4] = 1.3 * lambdaRatio[1]; + lambdaRatio[6] = 1.3 * lambdaRatio[1]; + lambdaRatio[7] = 1.0; + } + else + { + lambdaRatio[0] = 5.0; + lambdaRatio[1] = 4.0; + lambdaRatio[2] = 5.0; + lambdaRatio[3] = 4.0; + lambdaRatio[4] = 5.0; + lambdaRatio[5] = 4.0; + lambdaRatio[6] = 5.0; + lambdaRatio[7] = 1.0; + } + } else if ( encRCSeq->getAdaptiveBits() == 2 ) // for GOP size = 8, random access case { if ( encRCSeq->getLastLambda() < 90.0 ) @@ -449,6 +479,10 @@ void EncRCGOP::create( EncRCSeq* encRCSeq, int numPic ) lambdaRatio[15] = lambdaLev5 / lambdaLev1; } } + else + { + msg( WARNING, "Warning: Current rate control does not support this coding configuration." ); + } xCalEquaCoeff( encRCSeq, lambdaRatio, equaCoeffA, equaCoeffB, encRCSeq->getGOPSize() ); basicLambda = xSolveEqua(encRCSeq, targetBpp, equaCoeffA, equaCoeffB, encRCSeq->getGOPSize()); @@ -478,11 +512,7 @@ void EncRCGOP::create( EncRCSeq* encRCSeq, int numPic ) m_targetBits = targetBits; m_picLeft = m_numPic; m_bitsLeft = m_targetBits; - int bitdepth_luma_scale = - 2 * (encRCSeq->getbitDepth() - 8 - - DISTORTION_PRECISION_ADJUSTMENT(encRCSeq->getbitDepth())); - m_minEstLambda = 0.1; - m_maxEstLambda = 10000.0 * pow(2.0, bitdepth_luma_scale); + } void EncRCGOP::xCalEquaCoeff( EncRCSeq* encRCSeq, double* lambdaRatio, double* equaCoeffA, double* equaCoeffB, int GOPSize ) @@ -1351,7 +1381,7 @@ double EncRCPic::clipRcAlpha(const int bitdepth, const double alpha) int bitdepth_luma_scale = 2 * (bitdepth - 8 - - DISTORTION_PRECISION_ADJUSTMENT(m_encRCSeq->getbitDepth())); + - DISTORTION_PRECISION_ADJUSTMENT(bitdepth)); return Clip3(g_RCAlphaMinValue, g_RCAlphaMaxValue * pow(2.0, bitdepth_luma_scale), alpha); } @@ -1566,6 +1596,58 @@ void RateCtrl::init(int totalFrames, int targetBitrate, int frameRate, int GOPSi adaptiveBit = 1; } } + else if (GOPSize == 8 && isLowdelay) + { + if (bpp > 0.2) + { + bitsRatio[0] = 2; + bitsRatio[1] = 3; + bitsRatio[2] = 2; + bitsRatio[3] = 3; + bitsRatio[4] = 2; + bitsRatio[5] = 3; + bitsRatio[6] = 2; + bitsRatio[7] = 6; + } + else if (bpp > 0.1) + { + bitsRatio[0] = 2; + bitsRatio[1] = 3; + bitsRatio[2] = 2; + bitsRatio[3] = 3; + bitsRatio[4] = 2; + bitsRatio[5] = 3; + bitsRatio[6] = 2; + bitsRatio[7] = 10; + } + else if (bpp > 0.05) + { + bitsRatio[0] = 2; + bitsRatio[1] = 3; + bitsRatio[2] = 2; + bitsRatio[3] = 3; + bitsRatio[4] = 2; + bitsRatio[5] = 3; + bitsRatio[6] = 2; + bitsRatio[7] = 12; + } + else + { + bitsRatio[0] = 2; + bitsRatio[1] = 3; + bitsRatio[2] = 2; + bitsRatio[3] = 3; + bitsRatio[4] = 2; + bitsRatio[5] = 3; + bitsRatio[6] = 2; + bitsRatio[7] = 14; + } + + if (keepHierBits == 2) + { + adaptiveBit = 1; + } + } else if ( GOPSize == 8 && !isLowdelay ) { if ( bpp > 0.2 ) @@ -1727,6 +1809,17 @@ void RateCtrl::init(int totalFrames, int targetBitrate, int frameRate, int GOPSi GOPID2Level[2] = 3; GOPID2Level[3] = 1; } + if (GOPSize == 8 && isLowdelay) + { + GOPID2Level[0] = 3; + GOPID2Level[1] = 2; + GOPID2Level[2] = 3; + GOPID2Level[3] = 2; + GOPID2Level[4] = 3; + GOPID2Level[5] = 2; + GOPID2Level[6] = 3; + GOPID2Level[7] = 1; + } else if ( GOPSize == 8 && !isLowdelay ) { GOPID2Level[0] = 1;