diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp index a02938fe7de5cebc30b2c4079eb236121c2f71e4..c4c3b030a7b307697972466fee050798ce80be1e 100644 --- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp +++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.cpp @@ -217,7 +217,11 @@ void EncAdaptiveLoopFilter::initCABACEstimator( CABACEncoder* cabacEncoder, CtxC m_CABACEstimator->resetBits(); } -void EncAdaptiveLoopFilter::ALFProcess( CodingStructure& cs, const double *lambdas, AlfSliceParam& alfSliceParam ) +void EncAdaptiveLoopFilter::ALFProcess( CodingStructure& cs, const double *lambdas, +#if ENABLE_QPA + const double lambdaChromaWeight, +#endif + AlfSliceParam& alfSliceParam ) { // set available filter shapes alfSliceParam.filterShapes = m_filterShapes; @@ -254,16 +258,28 @@ void EncAdaptiveLoopFilter::ALFProcess( CodingStructure& cs, const double *lambd deriveStatsForFiltering( orgYuv, recYuv ); // derive filter (luma) - alfEncoder( cs, alfSliceParam, orgYuv, recYuv, cs.getRecoBuf(), CHANNEL_TYPE_LUMA ); + alfEncoder( cs, alfSliceParam, orgYuv, recYuv, cs.getRecoBuf(), CHANNEL_TYPE_LUMA +#if ENABLE_QPA + , lambdaChromaWeight +#endif + ); // derive filter (chroma) if( alfSliceParam.enabledFlag[COMPONENT_Y] ) { - alfEncoder( cs, alfSliceParam, orgYuv, recYuv, cs.getRecoBuf(), CHANNEL_TYPE_CHROMA ); + alfEncoder( cs, alfSliceParam, orgYuv, recYuv, cs.getRecoBuf(), CHANNEL_TYPE_CHROMA +#if ENABLE_QPA + , lambdaChromaWeight +#endif + ); } } -double EncAdaptiveLoopFilter::deriveCtbAlfEnableFlags( CodingStructure& cs, const int iShapeIdx, ChannelType channel, const int numClasses, const int numCoeff, double& distUnfilter ) +double EncAdaptiveLoopFilter::deriveCtbAlfEnableFlags( CodingStructure& cs, const int iShapeIdx, ChannelType channel, +#if ENABLE_QPA + const double chromaWeight, +#endif + const int numClasses, const int numCoeff, double& distUnfilter ) { TempCtx ctxTempStart( m_CtxCache ); TempCtx ctxTempBest( m_CtxCache ); @@ -274,6 +290,9 @@ double EncAdaptiveLoopFilter::deriveCtbAlfEnableFlags( CodingStructure& cs, cons distUnfilter = 0; setEnableFlag(m_alfSliceParamTemp, channel, true); +#if ENABLE_QPA + CHECK ((chromaWeight > 0.0) && (cs.slice->getSliceCurStartCtuTsAddr() != 0), "incompatible start CTU address, must be 0"); +#endif for( int ctuIdx = 0; ctuIdx < m_numCTUsInPic; ctuIdx++ ) { @@ -286,14 +305,19 @@ double EncAdaptiveLoopFilter::deriveCtbAlfEnableFlags( CodingStructure& cs, cons m_ctuEnableFlag[compID][ctuIdx] = 1; m_CABACEstimator->codeAlfCtuEnableFlag( cs, ctuIdx, compID, &m_alfSliceParamTemp ); double costOn = distUnfilterCtu + getFilteredDistortion( m_alfCovariance[compID][iShapeIdx][ctuIdx], numClasses, m_alfSliceParamTemp.numLumaFilters - 1, numCoeff ); - costOn += m_lambda[compID] * FracBitsScale*(double)m_CABACEstimator->getEstFracBits(); +#if ENABLE_QPA + const double ctuLambda = chromaWeight > 0.0 ? (isLuma (channel) ? cs.picture->m_uEnerHpCtu[ctuIdx] : cs.picture->m_uEnerHpCtu[ctuIdx] / chromaWeight) : m_lambda[compID]; +#else + const double ctuLambda = m_lambda[compID]; +#endif + costOn += ctuLambda * FracBitsScale*(double)m_CABACEstimator->getEstFracBits(); ctxTempBest = AlfCtx( m_CABACEstimator->getCtx() ); m_CABACEstimator->getCtx() = AlfCtx( ctxTempStart ); m_CABACEstimator->resetBits(); m_ctuEnableFlag[compID][ctuIdx] = 0; m_CABACEstimator->codeAlfCtuEnableFlag( cs, ctuIdx, compID, &m_alfSliceParamTemp); - double costOff = distUnfilterCtu + m_lambda[compID] * FracBitsScale*(double)m_CABACEstimator->getEstFracBits(); + double costOff = distUnfilterCtu + ctuLambda * FracBitsScale*(double)m_CABACEstimator->getEstFracBits(); if( costOn < costOff ) { @@ -320,7 +344,11 @@ double EncAdaptiveLoopFilter::deriveCtbAlfEnableFlags( CodingStructure& cs, cons return cost; } -void EncAdaptiveLoopFilter::alfEncoder( CodingStructure& cs, AlfSliceParam& alfSliceParam, const PelUnitBuf& orgUnitBuf, const PelUnitBuf& recExtBuf, const PelUnitBuf& recBuf, const ChannelType channel ) +void EncAdaptiveLoopFilter::alfEncoder( CodingStructure& cs, AlfSliceParam& alfSliceParam, const PelUnitBuf& orgUnitBuf, const PelUnitBuf& recExtBuf, const PelUnitBuf& recBuf, const ChannelType channel +#if ENABLE_QPA + , const double lambdaChromaWeight // = 0.0 +#endif + ) { const TempCtx ctxStart( m_CtxCache, AlfCtx( m_CABACEstimator->getCtx() ) ); TempCtx ctxBest( m_CtxCache ); @@ -383,7 +411,11 @@ void EncAdaptiveLoopFilter::alfEncoder( CodingStructure& cs, AlfSliceParam& alfS { m_CABACEstimator->getCtx() = AlfCtx(ctxStart); cost = m_lambda[channel] * uiCoeffBits; - cost += deriveCtbAlfEnableFlags(cs, iShapeIdx, channel, numClasses, alfFilterShape[iShapeIdx].numCoeff, distUnfilter); + cost += deriveCtbAlfEnableFlags(cs, iShapeIdx, channel, +#if ENABLE_QPA + lambdaChromaWeight, +#endif + numClasses, alfFilterShape[iShapeIdx].numCoeff, distUnfilter); if (cost < costMin) { costMin = cost; @@ -718,10 +750,10 @@ int EncAdaptiveLoopFilter::getNonFilterCoeffRate( AlfSliceParam& alfSliceParam ) int len = 1 // alf_coefficients_delta_flag #else int len = 1 // filter_type - + 1 // alf_coefficients_delta_flag + + 1 // alf_coefficients_delta_flag #endif - + lengthTruncatedUnary( 0, 3 ) // chroma_idc = 0, it is signalled when ALF is enabled for luma - + getTBlength( alfSliceParam.numLumaFilters - 1, MAX_NUM_ALF_CLASSES ); //numLumaFilters + + lengthTruncatedUnary( 0, 3 ) // chroma_idc = 0, it is signalled when ALF is enabled for luma + + getTBlength( alfSliceParam.numLumaFilters - 1, MAX_NUM_ALF_CLASSES ); //numLumaFilters if( alfSliceParam.numLumaFilters > 1 ) { @@ -818,8 +850,8 @@ int EncAdaptiveLoopFilter::getCostFilterCoeffForce0( AlfFilterShape& alfShape, i // Coding parameters int len = kMin //min_golomb_order - + maxGolombIdx //golomb_order_increase_flag - + numFilters; //filter_coefficient_flag[i] + + maxGolombIdx //golomb_order_increase_flag + + numFilters; //filter_coefficient_flag[i] // Filter coefficients for( int ind = 0; ind < numFilters; ++ind ) diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h index 85c0797af63e0f9b53957b652b6078cfeb61d611..a2f92708bdf70f3db2295e71af0688c93109c0e1 100644 --- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h +++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h @@ -176,7 +176,11 @@ public: EncAdaptiveLoopFilter(); virtual ~EncAdaptiveLoopFilter() {} - void ALFProcess( CodingStructure& cs, const double *lambdas, AlfSliceParam& alfSliceParam ); + void ALFProcess( CodingStructure& cs, const double *lambdas, +#if ENABLE_QPA + const double lambdaChromaWeight, +#endif + AlfSliceParam& alfSliceParam ); void initCABACEstimator( CABACEncoder* cabacEncoder, CtxCache* ctxCache, Slice* pcSlice ); void create( const int picWidth, const int picHeight, const ChromaFormat chromaFormatIDC, const int maxCUWidth, const int maxCUHeight, const int maxCUDepth, const int inputBitDepth[MAX_NUM_CHANNEL_TYPE], const int internalBitDepth[MAX_NUM_CHANNEL_TYPE] ); void destroy(); @@ -184,7 +188,11 @@ public: static int getGolombKMin( AlfFilterShape& alfShape, const int numFilters, int kMinTab[MAX_NUM_ALF_LUMA_COEFF], int bitsCoeffScan[m_MAX_SCAN_VAL][m_MAX_EXP_GOLOMB] ); private: - void alfEncoder( CodingStructure& cs, AlfSliceParam& alfSliceParam, const PelUnitBuf& orgUnitBuf, const PelUnitBuf& recExtBuf, const PelUnitBuf& recBuf, const ChannelType channel ); + void alfEncoder( CodingStructure& cs, AlfSliceParam& alfSliceParam, const PelUnitBuf& orgUnitBuf, const PelUnitBuf& recExtBuf, const PelUnitBuf& recBuf, const ChannelType channel +#if ENABLE_QPA + , const double lambdaChromaWeight = 0.0 +#endif + ); void copyAlfSliceParam( AlfSliceParam& alfSliceParamDst, AlfSliceParam& alfSliceParamSrc, ChannelType channel ); double mergeFiltersAndCost( AlfSliceParam& alfSliceParam, AlfFilterShape& alfShape, AlfCovariance* covFrame, AlfCovariance* covMerged, int& uiCoeffBits ); @@ -202,7 +210,11 @@ private: double deriveFilterCoeffs( AlfCovariance* cov, AlfCovariance* covMerged, AlfFilterShape& alfShape, short* filterIndices, int numFilters, double errorTabForce0Coeff[MAX_NUM_ALF_CLASSES][2] ); int deriveFilterCoefficientsPredictionMode( AlfFilterShape& alfShape, int **filterSet, int** filterCoeffDiff, const int numFilters, int& predMode ); double deriveCoeffQuant( int *filterCoeffQuant, double **E, double *y, const int numCoeff, std::vector<int>& weights, const int bitDepth, const bool bChroma = false ); - double deriveCtbAlfEnableFlags( CodingStructure& cs, const int iShapeIdx, ChannelType channel, const int numClasses, const int numCoeff, double& distUnfilter ); + double deriveCtbAlfEnableFlags( CodingStructure& cs, const int iShapeIdx, ChannelType channel, +#if ENABLE_QPA + const double chromaWeight, +#endif + const int numClasses, const int numCoeff, double& distUnfilter ); void roundFiltCoeff( int *filterCoeffQuant, double *filterCoeff, const int numCoeff, const int factor ); double getDistCoeffForce0( bool* codedVarBins, double errorForce0CoeffTab[MAX_NUM_ALF_CLASSES][2], int* bitsVarBin, const int numFilters ); diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 29b659ed7d2b3e46d3e63ad6f09630b76f08e718..567787f0ee0e85a28ef23822460574d1b02e1b95 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -2123,10 +2123,15 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, { bool sliceEnabled[MAX_NUM_COMPONENT]; m_pcSAO->initCABACEstimator( m_pcEncLib->getCABACEncoder(), m_pcEncLib->getCtxCache(), pcSlice ); + + m_pcSAO->SAOProcess( cs, sliceEnabled, pcSlice->getLambdas(), +#if ENABLE_QPA + (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP() ? m_pcEncLib->getRdCost (PARL_PARAM0 (0))->getChromaWeight() : 0.0), +#endif #if K0238_SAO_GREEDY_MERGE_ENCODING - m_pcSAO->SAOProcess(cs, sliceEnabled, pcSlice->getLambdas(), m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary(), m_pcCfg->getSaoGreedyMergeEnc()); + m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary(), m_pcCfg->getSaoGreedyMergeEnc() ); #else - m_pcSAO->SAOProcess(cs, sliceEnabled, pcSlice->getLambdas(), m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary()); + m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary() ); #endif //assign SAO slice header for(int s=0; s< uiNumSliceSegments; s++) @@ -2141,7 +2146,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, { AlfSliceParam alfSliceParam; m_pcALF->initCABACEstimator( m_pcEncLib->getCABACEncoder(), m_pcEncLib->getCtxCache(), pcSlice ); - m_pcALF->ALFProcess( cs, pcSlice->getLambdas(), alfSliceParam ); + + m_pcALF->ALFProcess( cs, pcSlice->getLambdas(), +#if ENABLE_QPA + (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP() ? m_pcEncLib->getRdCost (PARL_PARAM0 (0))->getChromaWeight() : 0.0), +#endif + alfSliceParam ); //assign ALF slice header for( int s = 0; s< uiNumSliceSegments; s++ ) { @@ -2157,6 +2167,17 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, { pcSlice->setSliceQpBase( pcSlice->getSliceQp() ); +#if ENABLE_QPA + if (m_pcCfg->getUsePerceptQPA() && !m_pcCfg->getUseRateCtrl() && pcSlice->getPPS()->getUseDQP()) + { + const double picLambda = pcSlice->getLambdas()[0]; + + for (uint32_t ctuRsAddr = 0; ctuRsAddr < numberOfCtusInFrame; ctuRsAddr++) + { + pcPic->m_uEnerHpCtu[ctuRsAddr] = picLambda; // initialize to slice lambda (just for safety) + } + } +#endif if( pcSlice->getSPS()->getUseSAO() ) { m_pcSAO->disabledRate( *pcPic->cs, pcPic->getSAO(1), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma()); diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp index 5b103f9e3362086c1111a90d5b75bf57a153c0e3..2bffb12478f260c44c617f66c450d2faa117bd31 100644 --- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp +++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp @@ -206,10 +206,14 @@ void EncSampleAdaptiveOffset::initCABACEstimator( CABACEncoder* cabacEncoder, Ct } +void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnabled, const double* lambdas, +#if ENABLE_QPA + const double lambdaChromaWeight, +#endif #if K0238_SAO_GREEDY_MERGE_ENCODING -void EncSampleAdaptiveOffset::SAOProcess(CodingStructure& cs, bool* sliceEnabled, const double *lambdas, const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, bool isPreDBFSamplesUsed, bool isGreedymergeEncoding ) + const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, const bool isPreDBFSamplesUsed, bool isGreedyMergeEncoding ) #else -void EncSampleAdaptiveOffset::SAOProcess(CodingStructure& cs, bool* sliceEnabled, const double *lambdas, const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, bool isPreDBFSamplesUsed ) + const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, const bool isPreDBFSamplesUsed ) #endif { PelUnitBuf org = cs.getOrgBuf(); @@ -231,10 +235,14 @@ void EncSampleAdaptiveOffset::SAOProcess(CodingStructure& cs, bool* sliceEnabled //block on/off std::vector<SAOBlkParam> reconParams(cs.pcv->sizeInCtus); + decideBlkParams( cs, sliceEnabled, m_statData, src, res, &reconParams[0], cs.picture->getSAO(), bTestSAODisableAtPictureLevel, +#if ENABLE_QPA + lambdaChromaWeight, +#endif #if K0238_SAO_GREEDY_MERGE_ENCODING - decideBlkParams(cs, sliceEnabled, m_statData, src, res, &reconParams[0], cs.picture->getSAO(), bTestSAODisableAtPictureLevel, saoEncodingRate, saoEncodingRateChroma, isGreedymergeEncoding); + saoEncodingRate, saoEncodingRateChroma, isGreedyMergeEncoding ); #else - decideBlkParams(cs, sliceEnabled, m_statData, src, res, &reconParams[0], cs.picture->getSAO(), bTestSAODisableAtPictureLevel, saoEncodingRate, saoEncodingRateChroma); + saoEncodingRate, saoEncodingRateChroma ); #endif DTRACE_UPDATE(g_trace_ctx, (std::make_pair("poc", cs.slice->getPOC()))); @@ -765,6 +773,9 @@ void EncSampleAdaptiveOffset::deriveModeMergeRDO(const BitDepths &bitDepths, int void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEnabled, std::vector<SAOStatData**>& blkStats, PelUnitBuf& srcYuv, PelUnitBuf& resYuv, SAOBlkParam* reconParams, SAOBlkParam* codedParams, const bool bTestSAODisableAtPictureLevel, +#if ENABLE_QPA + const double chromaWeight, +#endif #if K0238_SAO_GREEDY_MERGE_ENCODING const double saoEncodingRate, const double saoEncodingRateChroma, const bool isGreedymergeEncoding) #else @@ -818,6 +829,10 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn double totalCost = 0; // Used if bTestSAODisableAtPictureLevel==true int ctuRsAddr = 0; +#if ENABLE_QPA + CHECK ((chromaWeight > 0.0) && (cs.slice->getSliceCurStartCtuTsAddr() != 0), "incompatible start CTU address, must be 0"); +#endif + for( uint32_t yPos = 0; yPos < pcv.lumaHeight; yPos += pcv.maxCUHeight ) { for( uint32_t xPos = 0; xPos < pcv.lumaWidth; xPos += pcv.maxCUWidth ) @@ -847,6 +862,15 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn getMergeList(cs, ctuRsAddr, reconParams, mergeList); minCost = MAX_DOUBLE; +#if ENABLE_QPA + if (chromaWeight > 0.0) // temporarily adopt local (CTU-wise) lambdas from QPA + { + for (int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++) + { + m_lambda[compIdx] = isLuma ((ComponentID)compIdx) ? cs.picture->m_uEnerHpCtu[ctuRsAddr] : cs.picture->m_uEnerHpCtu[ctuRsAddr] / chromaWeight; + } + } +#endif for(int mode=1; mode < NUM_SAO_MODES; mode++) { if( mode > 1 ) @@ -1020,6 +1044,12 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn ctuRsAddr++; } //ctuRsAddr } + +#if ENABLE_QPA + // restore global lambdas (might be unnecessary) + if (chromaWeight > 0.0) memcpy (m_lambda, cs.slice->getLambdas(), sizeof (m_lambda)); + +#endif #if K0238_SAO_GREEDY_MERGE_ENCODING //reconstruct if (isGreedymergeEncoding) diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h index 15610f99afcc414d409fad1690dda509b8cf9fda..4bee5330eece7c52f25668b2fae38aaa5b4d96d1 100644 --- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h +++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h @@ -89,10 +89,14 @@ public: void createEncData(bool isPreDBFSamplesUsed, uint32_t numCTUsPic); void destroyEncData(); void initCABACEstimator( CABACEncoder* cabacEncoder, CtxCache* ctxCache, Slice* pcSlice ); + void SAOProcess( CodingStructure& cs, bool* sliceEnabled, const double* lambdas, +#if ENABLE_QPA + const double lambdaChromaWeight, +#endif #if K0238_SAO_GREEDY_MERGE_ENCODING - void SAOProcess(CodingStructure& cs, bool* sliceEnabled, const double *lambdas, const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, bool isPreDBFSamplesUsed, bool isGreedymergeEncoding); + const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, const bool isPreDBFSamplesUsed, bool isGreedyMergeEncoding ); #else - void SAOProcess(CodingStructure& cs, bool* sliceEnabled, const double *lambdas, const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, bool isPreDBFSamplesUsed); + const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, const bool isPreDBFSamplesUsed ); #endif void disabledRate( CodingStructure& cs, SAOBlkParam* reconParams, const double saoEncodingRate, const double saoEncodingRateChroma ); @@ -102,10 +106,14 @@ private: //methods void deriveLoopFilterBoundaryAvailibility(CodingStructure& cs, const Position &pos, bool& isLeftAvail, bool& isAboveAvail, bool& isAboveLeftAvail) const; void getStatistics(std::vector<SAOStatData**>& blkStats, PelUnitBuf& orgYuv, PelUnitBuf& srcYuv, CodingStructure& cs, bool isCalculatePreDeblockSamples = false); void decidePicParams(const Slice& slice, bool* sliceEnabled, const double saoEncodingRate, const double saoEncodingRateChroma); + void decideBlkParams( CodingStructure& cs, bool* sliceEnabled, std::vector<SAOStatData**>& blkStats, PelUnitBuf& srcYuv, PelUnitBuf& resYuv, SAOBlkParam* reconParams, SAOBlkParam* codedParams, const bool bTestSAODisableAtPictureLevel, +#if ENABLE_QPA + const double chromaWeight, +#endif #if K0238_SAO_GREEDY_MERGE_ENCODING - void decideBlkParams(CodingStructure& cs, bool* sliceEnabled, std::vector<SAOStatData**>& blkStats, PelUnitBuf& srcYuv, PelUnitBuf& resYuv, SAOBlkParam* reconParams, SAOBlkParam* codedParams, const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma, const bool isGreedymergeEncoding); + const double saoEncodingRate, const double saoEncodingRateChroma, const bool isGreedymergeEncoding ); #else - void decideBlkParams(CodingStructure& cs, bool* sliceEnabled, std::vector<SAOStatData**>& blkStats, PelUnitBuf& srcYuv, PelUnitBuf& resYuv, SAOBlkParam* reconParams, SAOBlkParam* codedParams, const bool bTestSAODisableAtPictureLevel, const double saoEncodingRate, const double saoEncodingRateChroma); + const double saoEncodingRate, const double saoEncodingRateChroma ); #endif void getBlkStats(const ComponentID compIdx, const int channelBitDepth, SAOStatData* statsDataTypes, Pel* srcBlk, Pel* orgBlk, int srcStride, int orgStride, int width, int height, bool isLeftAvail, bool isRightAvail, bool isAboveAvail, bool isBelowAvail, bool isAboveLeftAvail, bool isAboveRightAvail, bool isCalculatePreDeblockSamples); void deriveModeNewRDO(const BitDepths &bitDepths, int ctuRsAddr, SAOBlkParam* mergeList[NUM_SAO_MERGE_TYPES], bool* sliceEnabled, std::vector<SAOStatData**>& blkStats, SAOBlkParam& modeParam, double& modeNormCost ); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index b8678d4b742bbef5392d3cecfa747331fb259908..36242f620eb43d8c781c74c734bcc258eb9e64f2 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1636,6 +1636,7 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons { iSrcOffset = pcPic->m_iOffsetCtu[ctuRsAddr]; const double newLambda = oldLambda * pow (2.0, double(iSrcOffset - iQPIndex) / 3.0); + pcPic->m_uEnerHpCtu[ctuRsAddr] = newLambda; #if RDOQ_CHROMA_LAMBDA pTrQuant->getLambdas (oldLambdaArray); // save the old lambdas const double chromaLambda = newLambda / pRdCost->getChromaWeight();