[x265] [PATCH SCC 05/09] Added sao, deblock and temporal-mvp support and disable weight prediction
Andrey Semashev
andrey.semashev at gmail.com
Wed Aug 7 21:00:30 UTC 2024
On 8/7/24 23:53, patoo34 at free.fr wrote:
> STOP STOP STOP STOP STOP
> don't send me anything anymore
There's a link at the bottom for managing your mailing list subscription.
> ----- 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 ¶m, 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(¶m, 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
>>
>
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
More information about the x265-devel
mailing list