[x265] [PATCH SCC 05/09] Added sao, deblock and temporal-mvp support and disable weight prediction
Anusuya Kumarasamy
anusuya.kumarasamy at multicorewareinc.com
Wed Aug 7 17:21:51 UTC 2024
>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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240807/7a0053ab/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0005-Added-sao-deblock-and-temporal-mvp-support-and-disab.patch
Type: application/octet-stream
Size: 49054 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20240807/7a0053ab/attachment-0001.obj>
More information about the x265-devel
mailing list