[x265] [PATCH SCC 05/09] Added sao, deblock and temporal-mvp support and disable weight prediction

patoo34 at free.fr patoo34 at free.fr
Wed Aug 7 20:53:32 UTC 2024


STOP STOP STOP STOP STOP
don't send me anything anymore


----- Mail original -----
> 
> 
> From 4101dcf0f15686578b0c981de3df296d91a3ae8f Mon Sep 17 00:00:00
> 2001
> From: AnusuyaKumarasamy < anusuya.kumarasamy at multicorewareinc.com >
> Date: Fri, 19 Jul 2024 16:52:58 +0530
> Subject: [PATCH 5/9] Added sao, deblock and temporal-mvp support and
> disable
> weight prediction
> 
> ---
> source/common/cudata.cpp | 8 ++---
> source/common/deblock.cpp | 4 +--
> source/common/frame.cpp | 55 ++++++++++++++++++++-------------
> source/common/frame.h | 2 +-
> source/common/framedata.h | 2 +-
> source/common/param.cpp | 7 ++++-
> source/common/predict.cpp | 50 +++++++++++++++++++++++-------
> source/common/slice.h | 2 ++
> source/encoder/analysis.cpp | 24 ++++++++------
> source/encoder/dpb.cpp | 19 +++++++++---
> source/encoder/encoder.cpp | 20 ++++++------
> source/encoder/entropy.cpp | 4 +--
> source/encoder/frameencoder.cpp | 8 ++---
> source/encoder/framefilter.cpp | 14 ++++-----
> source/encoder/level.cpp | 9 +++---
> source/encoder/sao.cpp | 10 +++---
> source/encoder/search.cpp | 39 ++++++++++++++---------
> 17 files changed, 173 insertions(+), 104 deletions(-)
> 
> diff --git a/source/common/cudata.cpp b/source/common/cudata.cpp
> index a671df113..23f95288e 100644
> --- a/source/common/cudata.cpp
> +++ b/source/common/cudata.cpp
> @@ -1595,7 +1595,7 @@ uint32_t
> CUData::getInterMergeCandidates(uint32_t absPartIdx, uint32_t puIdx,
> MV
> return maxNumMergeCand;
> }
> }
> - if (m_slice->m_sps->bTemporalMVPEnabled)
> + if (m_slice->m_bTemporalMvp)
> {
> uint32_t partIdxRB = deriveRightBottomIdx(puIdx);
> MV colmv;
> @@ -1822,9 +1822,9 @@ int CUData::getPMV(InterNeighbourMV*
> neighbours, uint32_t picList, uint32_t refI
> // Get the collocated candidate. At this step, either the first
> candidate
> // was found or its value is 0.
> #if ENABLE_MULTIVIEW
> - if (m_slice->m_param->numViews > 1)
> + if (m_slice->m_param->numViews > 1 ||
> !!m_slice->m_param->bEnableSCC)
> {
> - if (m_slice->m_sps->bTemporalMVPEnabled && num < 2)
> + if (m_slice->m_bTemporalMvp && num < 2)
> {
> int refId = refIdx;
> uint32_t absPartAddr = m_absIdxInCTU + absPartIdx;
> @@ -1915,7 +1915,7 @@ void CUData::getNeighbourMV(uint32_t puIdx,
> uint32_t absPartIdx, InterNeighbourM
> getInterNeighbourMV(neighbours + MD_ABOVE, partIdxRT, MD_ABOVE);
> getInterNeighbourMV(neighbours + MD_ABOVE_LEFT, partIdxLT,
> MD_ABOVE_LEFT);
> 
> - if (m_slice->m_sps->bTemporalMVPEnabled &&
> !(m_slice->m_param->numViews > 1))
> + if (m_slice->m_bTemporalMvp && !(!!m_slice->m_param->bEnableSCC ||
> m_slice->m_param->numViews > 1))
> {
> uint32_t absPartAddr = m_absIdxInCTU + absPartIdx;
> uint32_t partIdxRB = deriveRightBottomIdx(puIdx);
> diff --git a/source/common/deblock.cpp b/source/common/deblock.cpp
> index 15ca361b2..0f9bc02dd 100644
> --- a/source/common/deblock.cpp
> +++ b/source/common/deblock.cpp
> @@ -316,7 +316,7 @@ static inline void pelFilterLuma(pixel* src,
> intptr_t srcStep, intptr_t offset,
> 
> void Deblock::edgeFilterLuma(const CUData* cuQ, uint32_t absPartIdx,
> uint32_t depth, int32_t dir, int32_t edge, const uint8_t
> blockStrength[])
> {
> - PicYuv* reconPic = cuQ->m_encData->m_reconPic;
> + PicYuv* reconPic = cuQ->m_encData->m_reconPic[0];
> pixel* src = reconPic->getLumaAddr(cuQ->m_cuAddr, absPartIdx);
> intptr_t stride = reconPic->m_stride;
> const PPS* pps = cuQ->m_slice->m_pps;
> @@ -429,7 +429,7 @@ void Deblock::edgeFilterChroma(const CUData* cuQ,
> uint32_t absPartIdx, uint32_t
> : ((g_zscanToPelY[absPartIdx] + edge * UNIT_SIZE) >>
> cuQ->m_vChromaShift)) % DEBLOCK_SMALLEST_BLOCK == 0,
> "invalid edge\n");
> 
> - PicYuv* reconPic = cuQ->m_encData->m_reconPic;
> + PicYuv* reconPic = cuQ->m_encData->m_reconPic[0];
> intptr_t stride = reconPic->m_strideC;
> intptr_t srcOffset = reconPic->getChromaAddrOffset(cuQ->m_cuAddr,
> absPartIdx);
> bool bCheckNoFilter = pps->bTransquantBypassEnabled;
> diff --git a/source/common/frame.cpp b/source/common/frame.cpp
> index c40093dba..6140021aa 100644
> --- a/source/common/frame.cpp
> +++ b/source/common/frame.cpp
> @@ -37,7 +37,8 @@ Frame::Frame()
> m_reconColCount = NULL;
> m_countRefEncoders = 0;
> m_encData = NULL;
> - m_reconPic = NULL;
> + for (int i = 0; i < 2; i++)
> + m_reconPic[i] = NULL;
> m_quantOffsets = NULL;
> m_next = NULL;
> m_prev = NULL;
> @@ -204,29 +205,35 @@ fail:
> bool Frame::allocEncodeData(x265_param *param, const SPS& sps)
> {
> m_encData = new FrameData;
> - m_reconPic = new PicYuv;
> m_param = param;
> - m_encData->m_reconPic = m_reconPic;
> - bool ok = m_encData->create(*param, sps, m_fencPic->m_picCsp) &&
> m_reconPic->create(param);
> + for (int i = 0; i < !!m_param->bEnableSCC + 1; i++)
> + {
> + m_reconPic[i] = new PicYuv;
> + m_encData->m_reconPic[i] = m_reconPic[i];
> + }
> + bool ok = m_encData->create(*param, sps, m_fencPic->m_picCsp) &&
> m_reconPic[0]->create(param) && (!!param->bEnableSCC ?
> (!!param->bEnableSCC && m_reconPic[1]->create(param)) : 1);
> if (ok)
> {
> - /* initialize right border of m_reconpicYuv as SAO may read beyond
> the
> + /* initialize right border of m_reconPicYuv as SAO may read beyond
> the
> * end of the picture accessing uninitialized pixels */
> int maxHeight = sps.numCuInHeight * param->maxCUSize;
> - memset(m_reconPic->m_picOrg[0], 0, sizeof(pixel)*
> m_reconPic->m_stride * maxHeight);
> -
> - /* use pre-calculated cu/pu offsets cached in the SPS structure */
> - m_reconPic->m_cuOffsetY = sps.cuOffsetY;
> - m_reconPic->m_buOffsetY = sps.buOffsetY;
> + memset(m_reconPic[0]->m_picOrg[0], 0, sizeof(pixel)*
> m_reconPic[0]->m_stride * maxHeight);
> 
> - if (param->internalCsp != X265_CSP_I400)
> + for (int i = 0; i < !!m_param->bEnableSCC + 1; i++)
> {
> - memset(m_reconPic->m_picOrg[1], 0, sizeof(pixel) *
> m_reconPic->m_strideC * (maxHeight >> m_reconPic->m_vChromaShift));
> - memset(m_reconPic->m_picOrg[2], 0, sizeof(pixel) *
> m_reconPic->m_strideC * (maxHeight >> m_reconPic->m_vChromaShift));
> -
> /* use pre-calculated cu/pu offsets cached in the SPS structure */
> - m_reconPic->m_cuOffsetC = sps.cuOffsetC;
> - m_reconPic->m_buOffsetC = sps.buOffsetC;
> + m_reconPic[i]->m_cuOffsetY = sps.cuOffsetY;
> + m_reconPic[i]->m_buOffsetY = sps.buOffsetY;
> +
> + if (param->internalCsp != X265_CSP_I400)
> + {
> + memset(m_reconPic[i]->m_picOrg[1], 0, sizeof(pixel) *
> m_reconPic[i]->m_strideC * (maxHeight >>
> m_reconPic[i]->m_vChromaShift));
> + memset(m_reconPic[i]->m_picOrg[2], 0, sizeof(pixel) *
> m_reconPic[i]->m_strideC * (maxHeight >>
> m_reconPic[i]->m_vChromaShift));
> +
> + /* use pre-calculated cu/pu offsets cached in the SPS structure */
> + m_reconPic[i]->m_cuOffsetC = sps.cuOffsetC;
> + m_reconPic[i]->m_buOffsetC = sps.buOffsetC;
> + }
> }
> }
> return ok;
> @@ -236,7 +243,9 @@ bool Frame::allocEncodeData(x265_param *param,
> const SPS& sps)
> void Frame::reinit(const SPS& sps)
> {
> m_bChromaExtended = false;
> - m_reconPic = m_encData->m_reconPic;
> + m_reconPic[0] = m_encData->m_reconPic[0];
> + if (!!m_param->bEnableSCC)
> + m_reconPic[1] = m_encData->m_reconPic[1];
> m_encData->reinit(sps);
> }
> 
> @@ -306,11 +315,15 @@ void Frame::destroy()
> X265_FREE(m_isSubSampled);
> }
> 
> - if (m_reconPic)
> + int numVersion = !!m_param->bEnableSCC ? 2 : 1;
> + for (int i = 0; i < numVersion; i++)
> {
> - m_reconPic->destroy();
> - delete m_reconPic;
> - m_reconPic = NULL;
> + if (m_reconPic[i])
> + {
> + m_reconPic[i]->destroy();
> + delete m_reconPic[i];
> + m_reconPic[i] = NULL;
> + }
> }
> 
> if (m_reconRowFlag)
> diff --git a/source/common/frame.h b/source/common/frame.h
> index 4ddd8bd46..4e6a4beed 100644
> --- a/source/common/frame.h
> +++ b/source/common/frame.h
> @@ -81,7 +81,7 @@ public:
> /* These two items will be NULL until the Frame begins to be encoded,
> at which point
> * it will be assigned a FrameData instance, which comes with a
> reconstructed image PicYuv */
> FrameData* m_encData;
> - PicYuv* m_reconPic;
> + PicYuv* m_reconPic[2];
> 
> /* Data associated with x265_picture */
> PicYuv* m_fencPic;
> diff --git a/source/common/framedata.h b/source/common/framedata.h
> index 611664ca5..66a00696c 100644
> --- a/source/common/framedata.h
> +++ b/source/common/framedata.h
> @@ -115,7 +115,7 @@ public:
> const x265_param* m_param;
> 
> FrameData* m_freeListNext;
> - PicYuv* m_reconPic;
> + PicYuv* m_reconPic[2];
> bool m_bHasReferences; /* used during DPB/RPS updates */
> int m_frameEncoderID; /* the ID of the FrameEncoder encoding this
> frame */
> JobProvider* m_jobProvider;
> diff --git a/source/common/param.cpp b/source/common/param.cpp
> index 2f4f8084d..bbf33dae9 100755
> --- a/source/common/param.cpp
> +++ b/source/common/param.cpp
> @@ -1476,7 +1476,12 @@ int x265_param_parse(x265_param* p, const
> char* name, const char* value)
> p->numViews = atoi(value);
> }
> #endif
> - OPT("scc") p->bEnableSCC = atoi(value);
> + OPT("scc")
> + {
> + p->bEnableSCC = atoi(value);
> + if (p->bEnableSCC)
> + p->bEnableWeightedPred = false;
> + }
> else
> return X265_PARAM_BAD_NAME;
> }
> diff --git a/source/common/predict.cpp b/source/common/predict.cpp
> index a32bd05f7..e6fc478e3 100644
> --- a/source/common/predict.cpp
> +++ b/source/common/predict.cpp
> @@ -112,10 +112,20 @@ void Predict::motionCompensation(const CUData&
> cu, const PredictionUnit& pu, Yuv
> }
> else
> {
> - if (bLuma)
> - predInterLumaPixel(pu, predYuv,
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> - if (bChroma)
> - predInterChromaPixel(pu, predYuv,
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> + if (!!cu.m_slice->m_param->bEnableSCC && refIdx0 ==
> (cu.m_slice->m_numRefIdx[0] - 1))
> + {
> + if (bLuma)
> + predInterLumaPixel(pu, predYuv,
> *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);
> + if (bChroma)
> + predInterChromaPixel(pu, predYuv,
> *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);
> + }
> + else
> + {
> + if (bLuma)
> + predInterLumaPixel(pu, predYuv,
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> + if (bChroma)
> + predInterChromaPixel(pu, predYuv,
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> + }
> }
> }
> else
> @@ -174,12 +184,18 @@ void Predict::motionCompensation(const CUData&
> cu, const PredictionUnit& pu, Yuv
> 
> if (bLuma)
> {
> - predInterLumaShort(pu, m_predShortYuv[0],
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> + if (!!cu.m_slice->m_param->bEnableSCC && refIdx0 ==
> (cu.m_slice->m_numRefIdx[0] - 1))
> + predInterLumaShort(pu, m_predShortYuv[0],
> *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);
> + else
> + predInterLumaShort(pu, m_predShortYuv[0],
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> predInterLumaShort(pu, m_predShortYuv[1],
> *cu.m_slice->m_refReconPicList[1][refIdx1], mv1);
> }
> if (bChroma)
> {
> - predInterChromaShort(pu, m_predShortYuv[0],
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> + if (!!cu.m_slice->m_param->bEnableSCC && refIdx0 ==
> (cu.m_slice->m_numRefIdx[0] - 1))
> + predInterChromaShort(pu, m_predShortYuv[0],
> *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);
> + else
> + predInterChromaShort(pu, m_predShortYuv[0],
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> predInterChromaShort(pu, m_predShortYuv[1],
> *cu.m_slice->m_refReconPicList[1][refIdx1], mv1);
> }
> 
> @@ -206,10 +222,20 @@ void Predict::motionCompensation(const CUData&
> cu, const PredictionUnit& pu, Yuv
> }
> else
> {
> - if (bLuma)
> - predInterLumaPixel(pu, predYuv,
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> - if (bChroma)
> - predInterChromaPixel(pu, predYuv,
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> + if (!!cu.m_slice->m_param->bEnableSCC && refIdx0 ==
> (cu.m_slice->m_numRefIdx[0] - 1))
> + {
> + if (bLuma)
> + predInterLumaPixel(pu, predYuv,
> *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);
> + if (bChroma)
> + predInterChromaPixel(pu, predYuv,
> *cu.m_slice->m_refFrameList[0][refIdx0]->m_reconPic[1], mv0);
> + }
> + else
> + {
> + if (bLuma)
> + predInterLumaPixel(pu, predYuv,
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> + if (bChroma)
> + predInterChromaPixel(pu, predYuv,
> *cu.m_slice->m_refReconPicList[0][refIdx0], mv0);
> + }
> }
> }
> else
> @@ -602,7 +628,7 @@ void Predict::initAdiPattern(const CUData& cu,
> const CUGeom& cuGeom, uint32_t pu
> int tuSize = 1 << intraNeighbors.log2TrSize;
> int tuSize2 = tuSize << 1;
> 
> - PicYuv* reconPic = cu.m_encData->m_reconPic;
> + PicYuv* reconPic = cu.m_encData->m_reconPic[0];
> pixel* adiOrigin = reconPic->getLumaAddr(cu.m_cuAddr,
> cuGeom.absPartIdx + puAbsPartIdx);
> intptr_t picStride = reconPic->m_stride;
> 
> @@ -651,7 +677,7 @@ void Predict::initAdiPattern(const CUData& cu,
> const CUGeom& cuGeom, uint32_t pu
> 
> void Predict::initAdiPatternChroma(const CUData& cu, const CUGeom&
> cuGeom, uint32_t puAbsPartIdx, const IntraNeighbors& intraNeighbors,
> uint32_t chromaId)
> {
> - PicYuv* reconPic = cu.m_encData->m_reconPic;
> + PicYuv* reconPic = cu.m_encData->m_reconPic[0];
> const pixel* adiOrigin = reconPic->getChromaAddr(chromaId,
> cu.m_cuAddr, cuGeom.absPartIdx + puAbsPartIdx);
> intptr_t picStride = reconPic->m_strideC;
> 
> diff --git a/source/common/slice.h b/source/common/slice.h
> index 2f8872473..57ef1afee 100644
> --- a/source/common/slice.h
> +++ b/source/common/slice.h
> @@ -405,6 +405,7 @@ public:
> 
> Frame* m_lastEncPic;
> bool m_bLMvdL1Zero;
> + bool m_bTemporalMvp;
> 
> Slice()
> {
> @@ -421,6 +422,7 @@ public:
> m_rpsIdx = -1;
> m_chromaQpOffset[0] = m_chromaQpOffset[1] = 0;
> m_fieldNum = 0;
> + m_bTemporalMvp = false;
> }
> 
> void disableWeights();
> diff --git a/source/encoder/analysis.cpp
> b/source/encoder/analysis.cpp
> index 4bbfcbfe3..789069c4c 100644
> --- a/source/encoder/analysis.cpp
> +++ b/source/encoder/analysis.cpp
> @@ -271,7 +271,7 @@ Mode& Analysis::compressCTU(CUData& ctu, Frame&
> frame, const CUGeom& cuGeom, con
> {
> /* In RD Level 0/1, copy source pixels into the reconstructed block
> so
> * they are available for intra predictions */
> - m_modeDepth[0].fencYuv.copyToPicYuv(*m_frame->m_reconPic,
> ctu.m_cuAddr, 0);
> + m_modeDepth[0].fencYuv.copyToPicYuv(*m_frame->m_reconPic[0],
> ctu.m_cuAddr, 0);
> 
> compressInterCU_rd0_4(ctu, cuGeom, qp);
> 
> @@ -508,7 +508,7 @@ void Analysis::qprdRefine(const CUData&
> parentCTU, const CUGeom& cuGeom, int32_t
> 
> /* Copy best data to encData CTU and recon */
> md.bestMode->cu.copyToPic(depth);
> - md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic,
> parentCTU.m_cuAddr, cuGeom.absPartIdx);
> + md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic[0],
> parentCTU.m_cuAddr, cuGeom.absPartIdx);
> }
> 
> uint64_t Analysis::compressIntraCU(const CUData& parentCTU, const
> CUGeom& cuGeom, int32_t qp)
> @@ -816,7 +816,10 @@ uint64_t Analysis::compressIntraCU(const CUData&
> parentCTU, const CUGeom& cuGeom
> /* Copy best data to encData CTU and recon */
> md.bestMode->cu.copyToPic(depth);
> if (md.bestMode != &md.pred[PRED_SPLIT])
> - md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic,
> parentCTU.m_cuAddr, cuGeom.absPartIdx);
> + {
> + for (int i = 0; i < !!m_param->bEnableSCC + 1; i++)
> + md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic[i],
> parentCTU.m_cuAddr, cuGeom.absPartIdx);
> + }
> 
> return md.bestMode->rdCost;
> }
> @@ -1292,7 +1295,7 @@ uint32_t Analysis::compressInterCU_dist(const
> CUData& parentCTU, const CUGeom& c
> 
> /* Copy best data to encData CTU and recon */
> md.bestMode->cu.copyToPic(depth);
> - md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic, cuAddr,
> cuGeom.absPartIdx);
> + md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic[0], cuAddr,
> cuGeom.absPartIdx);
> 
> return refMask;
> }
> @@ -1310,14 +1313,14 @@ SplitData
> Analysis::compressInterCU_rd0_4(const CUData& parentCTU, const
> CUGeom&
> if (m_param->searchMethod == X265_SEA)
> {
> int numPredDir = m_slice->isInterP() ? 1 : 2;
> - int offset =
> (int)(m_frame->m_reconPic->m_cuOffsetY[parentCTU.m_cuAddr] +
> m_frame->m_reconPic->m_buOffsetY[cuGeom.absPartIdx]);
> + int offset =
> (int)(m_frame->m_reconPic[0]->m_cuOffsetY[parentCTU.m_cuAddr] +
> m_frame->m_reconPic[0]->m_buOffsetY[cuGeom.absPartIdx]);
> for (int list = 0; list < numPredDir; list++)
> for (int i = 0; i < m_frame->m_encData->m_slice->m_numRefIdx[list];
> i++)
> for (int planes = 0; planes < INTEGRAL_PLANE_NUM; planes++)
> m_modeDepth[depth].fencYuv.m_integral[list][i][planes] =
> m_frame->m_encData->m_slice->m_refFrameList[list][i]->m_encData->m_meIntegral[planes]
> + offset;
> }
> 
> - PicYuv& reconPic = *m_frame->m_reconPic;
> + PicYuv& reconPic = *m_frame->m_reconPic[0];
> SplitData splitCUData;
> 
> bool bHEVCBlockAnalysis = (m_param->bAnalysisType == AVC_INFO &&
> cuGeom.numPartitions > 16);
> @@ -2026,7 +2029,7 @@ SplitData Analysis::compressInterCU_rd5_6(const
> CUData& parentCTU, const CUGeom&
> if (m_param->searchMethod == X265_SEA)
> {
> int numPredDir = m_slice->isInterP() ? 1 : 2;
> - int offset =
> (int)(m_frame->m_reconPic->m_cuOffsetY[parentCTU.m_cuAddr] +
> m_frame->m_reconPic->m_buOffsetY[cuGeom.absPartIdx]);
> + int offset =
> (int)(m_frame->m_reconPic[0]->m_cuOffsetY[parentCTU.m_cuAddr] +
> m_frame->m_reconPic[0]->m_buOffsetY[cuGeom.absPartIdx]);
> for (int list = 0; list < numPredDir; list++)
> for (int i = 0; i < m_frame->m_encData->m_slice->m_numRefIdx[list];
> i++)
> for (int planes = 0; planes < INTEGRAL_PLANE_NUM; planes++)
> @@ -2708,7 +2711,8 @@ SplitData Analysis::compressInterCU_rd5_6(const
> CUData& parentCTU, const CUGeom&
> 
> /* Copy best data to encData CTU and recon */
> md.bestMode->cu.copyToPic(depth);
> - md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic,
> parentCTU.m_cuAddr, cuGeom.absPartIdx);
> + for (int i = 0; i < !!m_param->bEnableSCC + 1; i++)
> + md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic[i],
> parentCTU.m_cuAddr, cuGeom.absPartIdx);
> }
> else
> {
> @@ -2994,7 +2998,7 @@ void Analysis::recodeCU(const CUData&
> parentCTU, const CUGeom& cuGeom, int32_t q
> 
> /* Copy best data to encData CTU and recon */
> md.bestMode->cu.copyToPic(depth);
> - md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic,
> parentCTU.m_cuAddr, cuGeom.absPartIdx);
> + md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic[0],
> parentCTU.m_cuAddr, cuGeom.absPartIdx);
> }
> if (m_param->bDynamicRefine && bDecidedDepth)
> trainCU(parentCTU, cuGeom, *md.bestMode, td);
> @@ -3580,7 +3584,7 @@ void Analysis::checkBidir2Nx2N(Mode&
> inter2Nx2N, Mode& bidir2Nx2N, const CUGeom&
> {
> CUData& cu = bidir2Nx2N.cu;
> 
> - if (cu.isBipredRestriction() || inter2Nx2N.bestME[0][0].cost ==
> MAX_UINT || inter2Nx2N.bestME[0][1].cost == MAX_UINT)
> + if ((cu.is8x8BipredRestriction(inter2Nx2N.bestME[0][0].mv,
> inter2Nx2N.bestME[0][1].mv, inter2Nx2N.bestME[0][0].ref,
> inter2Nx2N.bestME[0][1].ref) ? (cu.m_cuDepth[0] == 3) :
> cu.isBipredRestriction()) || inter2Nx2N.bestME[0][0].cost ==
> MAX_UINT || inter2Nx2N.bestME[0][1].cost == MAX_UINT)
> {
> bidir2Nx2N.sa8dCost = MAX_INT64;
> bidir2Nx2N.rdCost = MAX_INT64;
> diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp
> index d957008eb..8ef1f7abe 100644
> --- a/source/encoder/dpb.cpp
> +++ b/source/encoder/dpb.cpp
> @@ -53,8 +53,8 @@ DPB::~DPB()
> FrameData* next = m_frameDataFreeList->m_freeListNext;
> m_frameDataFreeList->destroy();
> 
> - m_frameDataFreeList->m_reconPic->destroy();
> - delete m_frameDataFreeList->m_reconPic;
> + m_frameDataFreeList->m_reconPic[0]->destroy();
> + delete m_frameDataFreeList->m_reconPic[0];
> 
> delete m_frameDataFreeList;
> m_frameDataFreeList = next;
> @@ -132,7 +132,8 @@ void DPB::recycleUnreferenced()
> curFrame->m_prevCtuInfoChange = NULL;
> }
> curFrame->m_encData = NULL;
> - curFrame->m_reconPic = NULL;
> + for (int i = 0; i < !!curFrame->m_param->bEnableSCC + 1; i++)
> + curFrame->m_reconPic[i] = NULL;
> }
> }
> }
> @@ -206,7 +207,8 @@ void DPB::prepareEncode(Frame *newFrame)
> // Do decoding refresh marking if any
> decodingRefreshMarking(pocCurr, slice->m_nalUnitType, layer);
> 
> - computeRPS(pocCurr, newFrame->m_tempLayer, slice->isIRAP(),
> &slice->m_rps,
> slice->m_sps->maxDecPicBuffering[newFrame->m_tempLayer], layer);
> + uint32_t maxDecBuffer =
> (slice->m_sps->maxDecPicBuffering[newFrame->m_tempLayer] >= 8 &&
> slice->m_param->bEnableSCC) ? 7 :
> slice->m_sps->maxDecPicBuffering[newFrame->m_tempLayer];
> + computeRPS(pocCurr, newFrame->m_tempLayer, slice->isIRAP(),
> &slice->m_rps, maxDecBuffer, layer);
> bool isTSAPic = ((slice->m_nalUnitType == 2) || (slice->m_nalUnitType
> == 3)) ? true : false;
> // Mark pictures in m_piclist as unreferenced if they are not
> included in RPS
> applyReferencePictureSet(&slice->m_rps, pocCurr,
> newFrame->m_tempLayer, isTSAPic, layer);
> @@ -367,6 +369,15 @@ void DPB::prepareEncode(Frame *newFrame)
> slice->m_bLMvdL1Zero = false;
> }
> 
> + if (!slice->isIntra() && slice->m_param->bEnableTemporalMvp)
> + {
> + const Frame* colPic = slice->m_refFrameList[slice->isInterB() &&
> !slice->m_colFromL0Flag][slice->m_colRefIdx];
> + if (colPic->m_poc == slice->m_poc)
> + slice->m_bTemporalMvp = false;
> + else
> + slice->m_bTemporalMvp = true;
> + }
> +
> // Disable Loopfilter in bound area, because we will do
> slice-parallelism in future
> slice->m_sLFaseFlag = (newFrame->m_param->maxSlices > 1) ? false :
> ((SLFASE_CONSTANT & (1 << (pocCurr % 31))) > 0);
> 
> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
> index f4782f55d..4043342c1 100644
> --- a/source/encoder/encoder.cpp
> +++ b/source/encoder/encoder.cpp
> @@ -624,7 +624,7 @@ int Encoder::getRefFrameList(PicYuv** l0,
> PicYuv** l1, int sliceType, int poc, i
> {
> for (int j = 0; j < framePtr->m_encData->m_slice->m_numRefIdx[0];
> j++) // check only for --ref=n number of frames.
> {
> - if (framePtr->m_encData->m_slice->m_refFrameList[0][j] &&
> framePtr->m_encData->m_slice->m_refFrameList[0][j]->m_reconPic !=
> NULL)
> + if (framePtr->m_encData->m_slice->m_refFrameList[0][j] &&
> framePtr->m_encData->m_slice->m_refFrameList[0][j]->m_reconPic[0] !=
> NULL)
> {
> int l0POC =
> framePtr->m_encData->m_slice->m_refFrameList[0][j]->m_poc;
> pocL0[j] = l0POC;
> @@ -634,19 +634,19 @@ int Encoder::getRefFrameList(PicYuv** l0,
> PicYuv** l1, int sliceType, int poc, i
> while (l0Fp->m_reconRowFlag[l0Fp->m_numRows - 1].get() == 0)
> l0Fp->m_reconRowFlag[l0Fp->m_numRows - 1].waitForChange(0); /* If
> recon is not ready, current frame encoder has to wait. */
> }
> - l0[j] = l0Fp->m_reconPic;
> + l0[j] = l0Fp->m_reconPic[0];
> }
> }
> for (int j = 0; j < framePtr->m_encData->m_slice->m_numRefIdx[1];
> j++) // check only for --ref=n number of frames.
> {
> - if (framePtr->m_encData->m_slice->m_refFrameList[1][j] &&
> framePtr->m_encData->m_slice->m_refFrameList[1][j]->m_reconPic !=
> NULL)
> + if (framePtr->m_encData->m_slice->m_refFrameList[1][j] &&
> framePtr->m_encData->m_slice->m_refFrameList[1][j]->m_reconPic[0] !=
> NULL)
> {
> int l1POC =
> framePtr->m_encData->m_slice->m_refFrameList[1][j]->m_poc;
> pocL1[j] = l1POC;
> Frame* l1Fp = m_dpb->m_picList.getPOC(l1POC, 0);
> while (l1Fp->m_reconRowFlag[l1Fp->m_numRows - 1].get() == 0)
> l1Fp->m_reconRowFlag[l1Fp->m_numRows - 1].waitForChange(0); /* If
> recon is not ready, current frame encoder has to wait. */
> - l1[j] = l1Fp->m_reconPic;
> + l1[j] = l1Fp->m_reconPic[0];
> }
> }
> }
> @@ -1974,7 +1974,7 @@ int Encoder::encode(const x265_picture* pic_in,
> x265_picture** pic_out)
> x265_free_analysis_data(m_param, &outFrame->m_analysisData);
> if (pic_out[sLayer])
> {
> - PicYuv* recpic = outFrame->m_reconPic;
> + PicYuv* recpic = outFrame->m_reconPic[0];
> pic_out[sLayer]->poc = slice->m_poc;
> pic_out[sLayer]->bitDepth = X265_DEPTH;
> pic_out[sLayer]->userData = outFrame->m_userData;
> @@ -2330,15 +2330,15 @@ int Encoder::encode(const x265_picture*
> pic_in, x265_picture** pic_out)
> {
> int padX = m_param->maxCUSize + 32;
> int padY = m_param->maxCUSize + 16;
> - uint32_t numCuInHeight =
> (frameEnc[0]->m_encData->m_reconPic->m_picHeight +
> m_param->maxCUSize - 1) / m_param->maxCUSize;
> + uint32_t numCuInHeight =
> (frameEnc[0]->m_encData->m_reconPic[0]->m_picHeight +
> m_param->maxCUSize - 1) / m_param->maxCUSize;
> int maxHeight = numCuInHeight * m_param->maxCUSize;
> for (int i = 0; i < INTEGRAL_PLANE_NUM; i++)
> {
> - frameEnc[0]->m_encData->m_meBuffer[i] = X265_MALLOC(uint32_t,
> frameEnc[0]->m_reconPic->m_stride * (maxHeight + (2 * padY)));
> + frameEnc[0]->m_encData->m_meBuffer[i] = X265_MALLOC(uint32_t,
> frameEnc[0]->m_reconPic[0]->m_stride * (maxHeight + (2 * padY)));
> if (frameEnc[0]->m_encData->m_meBuffer[i])
> {
> - memset(frameEnc[0]->m_encData->m_meBuffer[i], 0, sizeof(uint32_t)*
> frameEnc[0]->m_reconPic->m_stride * (maxHeight + (2 * padY)));
> - frameEnc[0]->m_encData->m_meIntegral[i] =
> frameEnc[0]->m_encData->m_meBuffer[i] +
> frameEnc[0]->m_encData->m_reconPic->m_stride * padY + padX;
> + memset(frameEnc[0]->m_encData->m_meBuffer[i], 0, sizeof(uint32_t)*
> frameEnc[0]->m_reconPic[0]->m_stride * (maxHeight + (2 * padY)));
> + frameEnc[0]->m_encData->m_meIntegral[i] =
> frameEnc[0]->m_encData->m_meBuffer[i] +
> frameEnc[0]->m_encData->m_reconPic[0]->m_stride * padY + padX;
> }
> else
> x265_log(m_param, X265_LOG_ERROR, "SEA motion search: POC %d Integral
> buffer[%d] unallocated\n", frameEnc[0]->m_poc, i);
> @@ -3072,7 +3072,7 @@ void Encoder::fetchStats(x265_stats *stats,
> size_t statsSizeBytes, int layer)
> 
> void Encoder::finishFrameStats(Frame* curFrame, FrameEncoder
> *curEncoder, x265_frame_stats* frameStats, int inPoc, int layer)
> {
> - PicYuv* reconPic = curFrame->m_reconPic;
> + PicYuv* reconPic = curFrame->m_reconPic[0];
> uint64_t bits = curEncoder->m_accessUnitBits[layer];
> 
> //===== calculate PSNR =====
> diff --git a/source/encoder/entropy.cpp b/source/encoder/entropy.cpp
> index 2ec93ab6a..22408e6f3 100644
> --- a/source/encoder/entropy.cpp
> +++ b/source/encoder/entropy.cpp
> @@ -997,7 +997,7 @@ void Entropy::codeSliceHeader(const Slice& slice,
> FrameData& encData, uint32_t s
> }
> 
> if (slice.m_sps->bTemporalMVPEnabled)
> - WRITE_FLAG(1, "slice_temporal_mvp_enable_flag");
> + WRITE_FLAG(slice.m_bTemporalMvp, "slice_temporal_mvp_enable_flag");
> }
> const SAOParam *saoParam = encData.m_saoParam;
> if (slice.m_bUseSao)
> @@ -1039,7 +1039,7 @@ void Entropy::codeSliceHeader(const Slice&
> slice, FrameData& encData, uint32_t s
> if (slice.isInterB())
> WRITE_FLAG(slice.m_bLMvdL1Zero, "mvd_l1_zero_flag");
> 
> - if (slice.m_sps->bTemporalMVPEnabled)
> + if (slice.m_bTemporalMvp)
> {
> if (slice.m_sliceType == B_SLICE)
> WRITE_FLAG(slice.m_colFromL0Flag, "collocated_from_l0_flag");
> diff --git a/source/encoder/frameencoder.cpp
> b/source/encoder/frameencoder.cpp
> index 0ee3e9a2e..286eb520a 100644
> --- a/source/encoder/frameencoder.cpp
> +++ b/source/encoder/frameencoder.cpp
> @@ -591,7 +591,7 @@ void FrameEncoder::compressFrame(int layer)
> WeightParam *w = NULL;
> if ((bUseWeightP || bUseWeightB) &&
> slice->m_weightPredTable[l][ref][0].wtPresent)
> w = slice->m_weightPredTable[l][ref];
> - slice->m_refReconPicList[l][ref] =
> slice->m_refFrameList[l][ref]->m_reconPic;
> + slice->m_refReconPicList[l][ref] =
> slice->m_refFrameList[l][ref]->m_reconPic[0];
> m_mref[l][ref].init(slice->m_refReconPicList[l][ref], w, *m_param);
> }
> if (m_param->analysisSave && (bUseWeightP || bUseWeightB))
> @@ -988,7 +988,7 @@ void FrameEncoder::compressFrame(int layer)
> 
> if (m_param->maxSlices > 1)
> {
> - PicYuv *reconPic = m_frame[layer]->m_reconPic;
> + PicYuv *reconPic = m_frame[layer]->m_reconPic[0];
> uint32_t height = reconPic->m_picHeight;
> initDecodedPictureHashSEI(0, 0, height, layer);
> }
> @@ -1252,7 +1252,7 @@ void FrameEncoder::compressFrame(int layer)
> 
> void FrameEncoder::initDecodedPictureHashSEI(int row, int cuAddr, int
> height, int layer)
> {
> - PicYuv *reconPic = m_frame[layer]->m_reconPic;
> + PicYuv *reconPic = m_frame[layer]->m_reconPic[0];
> uint32_t width = reconPic->m_picWidth;
> intptr_t stride = reconPic->m_stride;
> uint32_t maxCUHeight = m_param->maxCUSize;
> @@ -2263,7 +2263,7 @@ void
> FrameEncoder::readModel(FilmGrainCharacteristics* m_filmGrain, FILE*
> filmgr
> void FrameEncoder::vmafFrameLevelScore()
> {
> PicYuv *fenc = m_frame->m_fencPic;
> - PicYuv *recon = m_frame->m_reconPic;
> + PicYuv *recon = m_frame->m_reconPic[0];
> 
> x265_vmaf_framedata *vmafframedata =
> (x265_vmaf_framedata*)x265_malloc(sizeof(x265_vmaf_framedata));
> if (!vmafframedata)
> diff --git a/source/encoder/framefilter.cpp
> b/source/encoder/framefilter.cpp
> index da01d0ceb..344ac738d 100644
> --- a/source/encoder/framefilter.cpp
> +++ b/source/encoder/framefilter.cpp
> @@ -256,7 +256,7 @@ static void restoreOrigLosslessYuv(const CUData*
> cu, Frame& frame, uint32_t absP
> const int size = cu->m_log2CUSize[absPartIdx] - 2;
> const uint32_t cuAddr = cu->m_cuAddr;
> 
> - PicYuv* reconPic = frame.m_reconPic;
> + PicYuv* reconPic = frame.m_reconPic[0];
> PicYuv* fencPic = frame.m_fencPic;
> 
> pixel* dst = reconPic->getLumaAddr(cuAddr, absPartIdx);
> @@ -337,7 +337,7 @@ void
> FrameFilter::ParallelFilter::processSaoCTU(SAOParam *saoParam, int
> col)
> 
> uint32_t cuAddr = m_rowAddr + col;
> const CUData* ctu = m_encData->getPicCTU(cuAddr);
> - assert(m_frameFilter->m_frame->m_reconPic ==
> m_encData->m_reconPic);
> + assert(m_frameFilter->m_frame->m_reconPic[0] ==
> m_encData->m_reconPic[0]);
> origCUSampleRestoration(ctu, cuGeoms[ctuGeomMap[cuAddr]],
> *m_frameFilter->m_frame);
> }
> }
> @@ -352,7 +352,7 @@ void
> FrameFilter::ParallelFilter::processPostCu(int col) const
> if ((col != 0) & (col != m_frameFilter->m_numCols - 1) & (m_row != 0)
> & (m_row != m_frameFilter->m_numRows - 1))
> return;
> 
> - PicYuv *reconPic = m_frameFilter->m_frame->m_reconPic;
> + PicYuv *reconPic = m_frameFilter->m_frame->m_reconPic[0];
> const uint32_t lineStartCUAddr = m_rowAddr + col;
> const int realH = getCUHeight();
> const int realW = m_frameFilter->getCUWidth(col);
> @@ -441,7 +441,7 @@ void
> FrameFilter::ParallelFilter::processTasks(int /*workerThreadId*/)
> SAOParam* saoParam = m_encData->m_saoParam;
> const CUGeom* cuGeoms = m_frameFilter->m_frameEncoder->m_cuGeoms;
> const uint32_t* ctuGeomMap =
> m_frameFilter->m_frameEncoder->m_ctuGeomMap;
> - PicYuv* reconPic = m_encData->m_reconPic;
> + PicYuv* reconPic = m_encData->m_reconPic[0];
> const int colStart = m_lastCol.get();
> const int numCols = m_frameFilter->m_numCols;
> // TODO: Waiting previous row finish or simple clip on it?
> @@ -653,7 +653,7 @@ void FrameFilter::processRow(int row, int layer)
> 
> void FrameFilter::processPostRow(int row, int layer)
> {
> - PicYuv *reconPic = m_frame->m_reconPic;
> + PicYuv *reconPic = m_frame->m_reconPic[0];
> const uint32_t numCols =
> m_frame->m_encData->m_slice->m_sps->numCuInWidth;
> const uint32_t lineStartCUAddr = row * numCols;
> 
> @@ -737,7 +737,7 @@ void FrameFilter::computeMEIntegral(int row)
> }
> }
> 
> - int stride = (int)m_frame->m_reconPic->m_stride;
> + int stride = (int)m_frame->m_reconPic[0]->m_stride;
> int padX = m_param->maxCUSize + 32;
> int padY = m_param->maxCUSize + 16;
> int numCuInHeight =
> m_frame->m_encData->m_slice->m_sps->numCuInHeight;
> @@ -763,7 +763,7 @@ void FrameFilter::computeMEIntegral(int row)
> 
> for (int y = startRow; y < height; y++)
> {
> - pixel *pix = m_frame->m_reconPic->m_picOrg[0] + y * stride - padX;
> + pixel *pix = m_frame->m_reconPic[0]->m_picOrg[0] + y * stride -
> padX;
> uint32_t *sum32x32 = m_frame->m_encData->m_meIntegral[0] + (y + 1) *
> stride - padX;
> uint32_t *sum32x24 = m_frame->m_encData->m_meIntegral[1] + (y + 1) *
> stride - padX;
> uint32_t *sum32x8 = m_frame->m_encData->m_meIntegral[2] + (y + 1) *
> stride - padX;
> diff --git a/source/encoder/level.cpp b/source/encoder/level.cpp
> index b5af25b4f..84f407702 100644
> --- a/source/encoder/level.cpp
> +++ b/source/encoder/level.cpp
> @@ -178,7 +178,7 @@ void determineLevel(const x265_param &param, VPS&
> vps)
> uint32_t samplesPerSec = (uint32_t)(lumaSamples *
> ((double)param.fpsNum / param.fpsDenom));
> uint32_t bitrate = param.rc.vbvMaxBitrate ? param.rc.vbvMaxBitrate :
> param.rc.bitrate;
> 
> - const uint32_t MaxDpbPicBuf = 6;
> + const uint32_t MaxDpbPicBuf = !!param.bEnableSCC ? 7 : 6;
> vps.ptl.levelIdc = Level::NONE;
> vps.ptl.tierFlag = Level::MAIN;
> 
> @@ -388,7 +388,7 @@ bool enforceLevel(x265_param& param, VPS& vps)
> for (uint32_t i = 0; i < vps.maxTempSubLayers; i++)
> {
> vps.numReorderPics[i] = (i == 0) ? ((param.bBPyramid && param.bframes
> > 1) ? 2 : !!param.bframes) : i;
> - vps.maxDecPicBuffering[i] = X265_MIN(MAX_NUM_REF,
> X265_MAX(vps.numReorderPics[i] + 2,
> (uint32_t)param.maxNumReferences) + 1);
> + vps.maxDecPicBuffering[i] = X265_MIN(MAX_NUM_REF,
> X265_MAX(vps.numReorderPics[i] + 2,
> (uint32_t)param.maxNumReferences) + 1) + !!param.bEnableSCC;
> }
> 
> if (!!param.bEnableTemporalSubLayers)
> @@ -504,7 +504,7 @@ bool enforceLevel(x265_param& param, VPS& vps)
> }
> 
> /* The value of sps_max_dec_pic_buffering_minus1[ HighestTid ] + 1
> shall be less than or equal to MaxDpbSize */
> - const uint32_t MaxDpbPicBuf = 6;
> + const uint32_t MaxDpbPicBuf = !!param.bEnableSCC ? 7 : 6;
> uint32_t maxDpbSize = MaxDpbPicBuf;
> if (!param.uhdBluray) /* Do not change MaxDpbPicBuf for UHD-Bluray */
> {
> @@ -519,8 +519,7 @@ bool enforceLevel(x265_param& param, VPS& vps)
> int savedRefCount = param.maxNumReferences;
> while (vps.maxDecPicBuffering[vps.maxTempSubLayers - 1] > maxDpbSize
> && param.maxNumReferences > 1)
> {
> - param.maxNumReferences--;
> - vps.maxDecPicBuffering[vps.maxTempSubLayers - 1] =
> X265_MIN(MAX_NUM_REF,
> X265_MAX(vps.numReorderPics[vps.maxTempSubLayers - 1] + 1,
> (uint32_t)param.maxNumReferences) + 1);
> + vps.maxDecPicBuffering[vps.maxTempSubLayers - 1] =
> X265_MIN(MAX_NUM_REF,
> X265_MAX(vps.numReorderPics[vps.maxTempSubLayers - 1] + 1,
> (uint32_t)param.maxNumReferences) + 1 + !!param.bEnableSCC);
> }
> if (param.maxNumReferences != savedRefCount)
> x265_log(&param, X265_LOG_WARNING, "Lowering max references to %d to
> meet level requirement\n", param.maxNumReferences);
> diff --git a/source/encoder/sao.cpp b/source/encoder/sao.cpp
> index 105ec79de..329f36ccf 100644
> --- a/source/encoder/sao.cpp
> +++ b/source/encoder/sao.cpp
> @@ -267,7 +267,7 @@ void SAO::startSlice(Frame* frame, Entropy&
> initState)
> // CTU-based SAO process without slice granularity
> void SAO::applyPixelOffsets(int addr, int typeIdx, int plane)
> {
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> pixel* rec = reconPic->getPlaneAddr(plane, addr);
> intptr_t stride = plane ? reconPic->m_strideC : reconPic->m_stride;
> uint32_t picWidth = m_param->sourceWidth;
> @@ -565,7 +565,7 @@ void SAO::applyPixelOffsets(int addr, int
> typeIdx, int plane)
> /* Process SAO unit */
> void SAO::generateLumaOffsets(SaoCtuParam* ctuParam, int idxY, int
> idxX)
> {
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> intptr_t stride = reconPic->m_stride;
> int ctuWidth = m_param->maxCUSize;
> int ctuHeight = m_param->maxCUSize;
> @@ -625,7 +625,7 @@ void SAO::generateLumaOffsets(SaoCtuParam*
> ctuParam, int idxY, int idxX)
> /* Process SAO unit (Chroma only) */
> void SAO::generateChromaOffsets(SaoCtuParam* ctuParam[3], int idxY,
> int idxX)
> {
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> intptr_t stride = reconPic->m_strideC;
> int ctuWidth = m_param->maxCUSize;
> int ctuHeight = m_param->maxCUSize;
> @@ -729,7 +729,7 @@ void SAO::generateChromaOffsets(SaoCtuParam*
> ctuParam[3], int idxY, int idxX)
> void SAO::calcSaoStatsCTU(int addr, int plane)
> {
> Slice* slice = m_frame->m_encData->m_slice;
> - const PicYuv* reconPic = m_frame->m_reconPic;
> + const PicYuv* reconPic = m_frame->m_reconPic[0];
> const CUData* cu = m_frame->m_encData->getPicCTU(addr);
> const pixel* fenc0 = m_frame->m_fencPic->getPlaneAddr(plane, addr);
> const pixel* rec0 = reconPic->getPlaneAddr(plane, addr);
> @@ -916,7 +916,7 @@ void SAO::calcSaoStatsCu_BeforeDblk(Frame* frame,
> int idxX, int idxY)
> 
> int x, y;
> const CUData* cu = frame->m_encData->getPicCTU(addr);
> - const PicYuv* reconPic = m_frame->m_reconPic;
> + const PicYuv* reconPic = m_frame->m_reconPic[0];
> const pixel* fenc;
> const pixel* rec;
> intptr_t stride = reconPic->m_stride;
> diff --git a/source/encoder/search.cpp b/source/encoder/search.cpp
> index ba220eaa6..3a5c54ffa 100644
> --- a/source/encoder/search.cpp
> +++ b/source/encoder/search.cpp
> @@ -497,7 +497,7 @@ void Search::codeIntraLumaQT(Mode& mode, const
> CUGeom& cuGeom, uint32_t tuDepth,
> }
> 
> // set reconstruction for next intra prediction blocks if full TU
> prediction won
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> pixel* picReconY = reconPic->getLumaAddr(cu.m_cuAddr,
> cuGeom.absPartIdx + absPartIdx);
> intptr_t picStride = reconPic->m_stride;
> primitives.cu [sizeIdx].copy_pp(picReconY, picStride, reconQt,
> reconQtStride);
> @@ -673,7 +673,7 @@ void Search::codeIntraLumaTSkip(Mode& mode, const
> CUGeom& cuGeom, uint32_t tuDep
> }
> 
> // set reconstruction for next intra prediction blocks
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> pixel* picReconY = reconPic->getLumaAddr(cu.m_cuAddr,
> cuGeom.absPartIdx + absPartIdx);
> intptr_t picStride = reconPic->m_stride;
> primitives.cu [sizeIdx].copy_pp(picReconY, picStride, reconQt,
> reconQtStride);
> @@ -724,7 +724,7 @@ void Search::residualTransformQuantIntra(Mode&
> mode, const CUGeom& cuGeom, uint3
> uint32_t sizeIdx = log2TrSize - 2;
> primitives.cu [sizeIdx].calcresidual[stride % 64 == 0](fenc, pred,
> residual, stride);
> 
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> pixel* picReconY = reconPic->getLumaAddr(cu.m_cuAddr,
> cuGeom.absPartIdx + absPartIdx);
> intptr_t picStride = reconPic->m_stride;
> 
> @@ -888,7 +888,7 @@ void Search::codeIntraChromaQt(Mode& mode, const
> CUGeom& cuGeom, uint32_t tuDept
> coeff_t* coeffC = m_rqt[qtLayer].coeffRQT[chromaId] + coeffOffsetC;
> pixel* reconQt = m_rqt[qtLayer].reconQtYuv.getChromaAddr(chromaId,
> absPartIdxC);
> uint32_t reconQtStride = m_rqt[qtLayer].reconQtYuv.m_csize;
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> pixel* picReconC = reconPic->getChromaAddr(chromaId, cu.m_cuAddr,
> cuGeom.absPartIdx + absPartIdxC);
> intptr_t picStride = reconPic->m_strideC;
> 
> @@ -1079,7 +1079,7 @@ void Search::codeIntraChromaTSkip(Mode& mode,
> const CUGeom& cuGeom, uint32_t tuD
> cu.setCbfPartRange(bCbf << tuDepth, ttype, absPartIdxC,
> tuIterator.absPartIdxStep);
> cu.setTransformSkipPartRange(bTSkip, ttype, absPartIdxC,
> tuIterator.absPartIdxStep);
> 
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> pixel* reconPicC = reconPic->getChromaAddr(chromaId, cu.m_cuAddr,
> cuGeom.absPartIdx + absPartIdxC);
> intptr_t picStride = reconPic->m_strideC;
> primitives.cu [sizeIdxC].copy_pp(reconPicC, picStride, reconQt,
> reconQtStride);
> @@ -1186,7 +1186,7 @@ void Search::residualQTIntraChroma(Mode& mode,
> const CUGeom& cuGeom, uint32_t ab
> int16_t* residual = resiYuv.getChromaAddr(chromaId, absPartIdxC);
> uint32_t coeffOffsetC = absPartIdxC << (LOG2_UNIT_SIZE * 2 -
> (m_hChromaShift + m_vChromaShift));
> coeff_t* coeffC = cu.m_trCoeff[ttype] + coeffOffsetC;
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> pixel* picReconC = reconPic->getChromaAddr(chromaId, cu.m_cuAddr,
> cuGeom.absPartIdx + absPartIdxC);
> intptr_t picStride = reconPic->m_strideC;
> 
> @@ -1285,6 +1285,9 @@ void Search::checkIntra(Mode& intraMode, const
> CUGeom& cuGeom, PartSize partSize
> 
> updateModeCost(intraMode);
> checkDQP(intraMode, cuGeom);
> +
> + if (!!m_param->bEnableSCC)
> + intraMode.reconYuv.copyToPicYuv(*m_frame->m_reconPic[1],
> cu.m_cuAddr, cuGeom.absPartIdx);
> }
> 
> /* Note that this function does not save the best intra prediction,
> it must
> @@ -1672,7 +1675,7 @@ sse_t Search::estIntraPredQT(Mode &intraMode,
> const CUGeom& cuGeom, const uint32
> * output recon picture, so it cannot proceed in parallel with
> anything else when doing INTRA_NXN. Also
> * it is not updating m_rdContexts[depth].cur for the later PUs which
> I suspect is slightly wrong. I think
> * that the contexts should be tracked through each PU */
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> pixel* dst = reconPic->getLumaAddr(cu.m_cuAddr, cuGeom.absPartIdx +
> absPartIdx);
> uint32_t dststride = reconPic->m_stride;
> const pixel* src = reconYuv->getLumaAddr(absPartIdx);
> @@ -1845,7 +1848,7 @@ sse_t Search::estIntraPredChromaQT(Mode
> &intraMode, const CUGeom& cuGeom)
> if (!tuIterator.isLastSection())
> {
> uint32_t zorder = cuGeom.absPartIdx + absPartIdxC;
> - PicYuv* reconPic = m_frame->m_reconPic;
> + PicYuv* reconPic = m_frame->m_reconPic[0];
> uint32_t dststride = reconPic->m_strideC;
> const pixel* src;
> pixel* dst;
> @@ -2008,7 +2011,10 @@ int Search::selectMVP(const CUData& cu, const
> PredictionUnit& pu, const MV amvp[
> continue;
> }
> cu.clipMv(mvCand);
> - predInterLumaPixel(pu, tmpPredYuv,
> *m_slice->m_refReconPicList[list][ref], mvCand);
> + if (!!m_slice->m_param->bEnableSCC && !list && ref ==
> m_slice->m_numRefIdx[0] - 1)
> + predInterLumaPixel(pu, tmpPredYuv,
> *m_slice->m_refFrameList[list][ref]->m_reconPic[1], mvCand);
> + else
> + predInterLumaPixel(pu, tmpPredYuv,
> *m_slice->m_refReconPicList[list][ref], mvCand);
> costs[i] = m_me.bufSAD(tmpPredYuv.getLumaAddr(pu.puAbsPartIdx),
> tmpPredYuv.m_size);
> }
> 
> @@ -2263,7 +2269,7 @@ void Search::predInterSearch(Mode& interMode,
> const CUGeom& cuGeom, bool bChroma
> int puX = puIdx & 1;
> int puY = puIdx >> 1;
> for (int planes = 0; planes < INTEGRAL_PLANE_NUM; planes++)
> - m_me.integral[planes] =
> interMode.fencYuv->m_integral[list][ref][planes] + puX * pu.width +
> puY * pu.height *
> m_slice->m_refFrameList[list][ref]->m_reconPic->m_stride;
> + m_me.integral[planes] =
> interMode.fencYuv->m_integral[list][ref][planes] + puX * pu.width +
> puY * pu.height *
> m_slice->m_refFrameList[list][ref]->m_reconPic[0]->m_stride;
> }
> setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);
> MV mvpIn = mvp;
> @@ -2432,7 +2438,7 @@ void Search::predInterSearch(Mode& interMode,
> const CUGeom& cuGeom, bool bChroma
> int puX = puIdx & 1;
> int puY = puIdx >> 1;
> for (int planes = 0; planes < INTEGRAL_PLANE_NUM; planes++)
> - m_me.integral[planes] =
> interMode.fencYuv->m_integral[list][ref][planes] + puX * pu.width +
> puY * pu.height *
> m_slice->m_refFrameList[list][ref]->m_reconPic->m_stride;
> + m_me.integral[planes] =
> interMode.fencYuv->m_integral[list][ref][planes] + puX * pu.width +
> puY * pu.height *
> m_slice->m_refFrameList[list][ref]->m_reconPic[0]->m_stride;
> }
> m_vertRestriction = cu.m_slice->m_refPOCList[list][ref] ==
> cu.m_slice->m_poc;
> setSearchRange(cu, mvp, m_param->searchRange, mvmin, mvmax);
> @@ -2731,12 +2737,12 @@ int Search::intraBCSearchMVChromaRefine(Mode&
> intraBCMode,
> 
> for (uint32_t ch = TEXT_CHROMA_U; ch < MAX_NUM_COMPONENT; ch++)
> {
> - ref = m_slice->m_refFrameList[0][m_slice->m_numRefIdx[0] -
> 1]->m_reconPic->getChromaAddr(ch, cu.m_cuAddr, cu.m_absIdxInCTU +
> partOffset);
> + ref = m_slice->m_refFrameList[0][m_slice->m_numRefIdx[0] -
> 1]->m_reconPic[1]->getChromaAddr(ch, cu.m_cuAddr, cu.m_absIdxInCTU +
> partOffset);
> 
> picOrg = intraBCMode.fencYuv->getChromaAddr(ch, partOffset);
> orgStride = intraBCMode.fencYuv->m_csize;
> 
> - refStride = m_frame->m_reconPic->m_strideC;
> + refStride = m_frame->m_reconPic[1]->m_strideC;
> 
> width = roiWidth >> m_hChromaShift;
> height = roiHeight >> m_vChromaShift;
> @@ -3545,8 +3551,8 @@ void Search::intraBlockCopyEstimate(Mode&
> intraBCMode, const CUGeom& cuGeom, int
> assert(nPSH == roiHeight);
> 
> int ref = m_slice->m_numRefIdx[0] - 1;
> - pixel* refY =
> m_slice->m_refFrameList[0][ref]->m_reconPic->getLumaAddr(cu.m_cuAddr,
> cu.m_absIdxInCTU + partAddr);
> - int strideY =
> m_slice->m_refFrameList[0][ref]->m_reconPic->m_stride;
> + pixel* refY =
> m_slice->m_refFrameList[0][ref]->m_reconPic[1]->getLumaAddr(cu.m_cuAddr,
> cu.m_absIdxInCTU + partAddr);
> + int strideY =
> m_slice->m_refFrameList[0][ref]->m_reconPic[1]->m_stride;
> 
> setIntraSearchRange(intraBCMode, mvPred, puIdx, roiWidth, roiHeight,
> searchRangeLT, searchRangeRB);
> 
> @@ -4769,6 +4775,9 @@ void Search::encodeResAndCalcRdInterCU(Mode&
> interMode, const CUGeom& cuGeom)
> cu.m_distortion[0] = interMode.distortion;
> updateModeCost(interMode);
> checkDQP(interMode, cuGeom);
> +
> + if (!!m_param->bEnableSCC)
> + interMode.reconYuv.copyToPicYuv(*m_frame->m_reconPic[1],
> cu.m_cuAddr, cuGeom.absPartIdx);
> }
> 
> void Search::residualTransformQuantInter(Mode& mode, const CUGeom&
> cuGeom, uint32_t absPartIdx, uint32_t tuDepth, const uint32_t
> depthRange[2])
> --
> 2.36.0.windows.1
> 
> 
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
> 


More information about the x265-devel mailing list