[x265] [PATCH 04/10] shifted mcstf from encoder to lookahead
Anusuya Kumarasamy
anusuya.kumarasamy at multicorewareinc.com
Mon Nov 11 14:14:21 UTC 2024
>From 679defdc97e93ed7597623045e8306fcdc29d916 Mon Sep 17 00:00:00 2001
From: AnusuyaKumarasamy <anusuya.kumarasamy at multicorewareinc.com>
Date: Thu, 24 Oct 2024 15:41:44 +0530
Subject: [PATCH 04/10] shifted mcstf from encoder to lookahead
---
source/common/frame.cpp | 3 +
source/common/frame.h | 1 +
source/common/picyuv.cpp | 4 +
source/common/temporalfilter.h | 2 +
source/encoder/encoder.cpp | 55 ++++++++------
source/encoder/frameencoder.cpp | 2 +-
source/encoder/slicetype.cpp | 125 ++++++++++++++++++++++++++++++++
source/encoder/slicetype.h | 7 ++
8 files changed, 175 insertions(+), 24 deletions(-)
diff --git a/source/common/frame.cpp b/source/common/frame.cpp
index 4c800e94e..80f341edf 100644
--- a/source/common/frame.cpp
+++ b/source/common/frame.cpp
@@ -94,6 +94,9 @@ bool Frame::create(x265_param *param, float* quantOffsets)
m_mcstf->m_range = param->mcstfFrameRange;
m_mcstf->init(param);
+ for (int i = 0; i < (m_mcstf->m_range << 1); i++)
+ m_mcstf->createRefPicInfo(&m_mcstfRefList[i], m_param);
+
m_fencPicSubsampled2 = new PicYuv;
m_fencPicSubsampled4 = new PicYuv;
diff --git a/source/common/frame.h b/source/common/frame.h
index 8d330026e..e85727deb 100644
--- a/source/common/frame.h
+++ b/source/common/frame.h
@@ -147,6 +147,7 @@ public:
Frame* m_nextMCSTF; // PicList doubly linked
list pointers
Frame* m_prevMCSTF;
int* m_isSubSampled;
+ TemporalFilterRefPicInfo
m_mcstfRefList[MAX_MCSTF_TEMPORAL_WINDOW_LENGTH];
/*Vbv-End-Flag*/
int vbvEndFlag;
diff --git a/source/common/picyuv.cpp b/source/common/picyuv.cpp
index a0190acc3..df8d666ea 100644
--- a/source/common/picyuv.cpp
+++ b/source/common/picyuv.cpp
@@ -154,6 +154,10 @@ bool PicYuv::createScaledPicYUV(x265_param* param,
uint8_t scaleFactor)
m_param = param;
m_picWidth = m_param->sourceWidth / scaleFactor;
m_picHeight = m_param->sourceHeight / scaleFactor;
+ int maxBlocksInRow = (m_picWidth + X265_LOWRES_CU_SIZE - 1) >>
X265_LOWRES_CU_BITS;
+ int maxBlocksInCol = (m_picHeight + X265_LOWRES_CU_SIZE - 1) >>
X265_LOWRES_CU_BITS;
+ m_picWidth = maxBlocksInRow * X265_LOWRES_CU_SIZE;
+ m_picHeight = maxBlocksInCol * X265_LOWRES_CU_SIZE;
m_picCsp = m_param->internalCsp;
m_hChromaShift = CHROMA_H_SHIFT(m_picCsp);
diff --git a/source/common/temporalfilter.h b/source/common/temporalfilter.h
index 9fe51da8c..1cd8028c7 100644
--- a/source/common/temporalfilter.h
+++ b/source/common/temporalfilter.h
@@ -105,6 +105,8 @@ namespace X265_NS {
int* error;
int* noise;
int poc;
+ pixel* lowres;
+ pixel* lowerRes;
int16_t origOffset;
bool isFilteredFrame;
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index 0a0c09307..d75dcafd8 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -1415,6 +1415,15 @@ inline int enqueueRefFrame(FrameEncoder*
curframeEncoder, Frame* iterFrame, Fram
dest->isFilteredFrame = isPreFiltered;
dest->isSubsampled = iterFrame->m_isSubSampled;
dest->origOffset = i;
+
+ TemporalFilterRefPicInfo* temp =
&curFrame->m_mcstfRefList[curFrame->m_mcstf->m_numRef];
+ temp->poc = iterFrame->m_poc;
+ temp->picBuffer = iterFrame->m_fencPic;
+ temp->lowres = iterFrame->m_lowres.lowresPlane[0];
+ temp->lowerRes = iterFrame->m_lowres.lowerResPlane[0];
+ temp->isFilteredFrame = isPreFiltered;
+ temp->origOffset = i;
+
curFrame->m_mcstf->m_numRef++;
return 1;
@@ -1443,12 +1452,12 @@ bool Encoder::generateMcstfRef(Frame* frameEnc,
FrameEncoder* currEncoder)
TemporalFilter* mcstf = frameEnc->m_mcstf;
while (mcstf->m_numRef)
{
-
memset(currEncoder->m_mcstfRefList[mcstf->m_numRef].mvs0, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 16) * (mcstf->m_sourceHeight / 16)));
-
memset(currEncoder->m_mcstfRefList[mcstf->m_numRef].mvs1, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 16) * (mcstf->m_sourceHeight / 16)));
-
memset(currEncoder->m_mcstfRefList[mcstf->m_numRef].mvs2, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 16) * (mcstf->m_sourceHeight / 16)));
-
memset(currEncoder->m_mcstfRefList[mcstf->m_numRef].mvs, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 4) * (mcstf->m_sourceHeight / 4)));
-
memset(currEncoder->m_mcstfRefList[mcstf->m_numRef].noise, 0, sizeof(int)
* ((mcstf->m_sourceWidth / 4) * (mcstf->m_sourceHeight / 4)));
-
memset(currEncoder->m_mcstfRefList[mcstf->m_numRef].error, 0, sizeof(int)
* ((mcstf->m_sourceWidth / 4) * (mcstf->m_sourceHeight / 4)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].mvs0, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 16) * (mcstf->m_sourceHeight / 16)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].mvs1, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 16) * (mcstf->m_sourceHeight / 16)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].mvs2, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 16) * (mcstf->m_sourceHeight / 16)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].mvs, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 4) * (mcstf->m_sourceHeight / 4)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].noise, 0, sizeof(int) *
((mcstf->m_sourceWidth / 4) * (mcstf->m_sourceHeight / 4)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].error, 0, sizeof(int) *
((mcstf->m_sourceWidth / 4) * (mcstf->m_sourceHeight / 4)));
mcstf->m_numRef--;
}
@@ -1513,7 +1522,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
m_dpb->recycleUnreferenced();
if (m_param->bEnableTemporalFilter)
- m_origPicBuffer->recycleOrigPicList();
+ m_lookahead->m_origPicBuf->recycleOrigPicList();
}
if ((pic_in && (!m_param->chunkEnd || (m_encodedFrameNum <
m_param->chunkEnd))) || (m_param->bEnableFrameDuplication && !pic_in &&
(read < written)))
@@ -1917,7 +1926,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
dupFrame->m_fencPic->m_cuOffsetC =
m_sps.cuOffsetC;
dupFrame->m_fencPic->m_buOffsetC =
m_sps.buOffsetC;
}
- m_origPicBuffer->addEncPicture(dupFrame);
+
m_lookahead->m_origPicBuf->addEncPicture(dupFrame);
}
}
}
@@ -1936,7 +1945,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
extendPicBorder(orig->m_picOrg[2], orig->m_strideC,
orig->m_picWidth >> orig->m_hChromaShift, orig->m_picHeight >>
orig->m_vChromaShift, orig->m_chromaMarginX, orig->m_chromaMarginY);
//TODO: Add subsampling here if required
- m_origPicBuffer->addPicture(inFrame[0]);
+ m_lookahead->m_origPicBuf->addPicture(inFrame[0]);;
}
m_lookahead->addPicture(*inFrame[0], sliceType);
@@ -2188,11 +2197,11 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
if (m_param->bEnableTemporalFilter)
{
- Frame* curFrame =
m_origPicBuffer->m_mcstfPicList.getPOCMCSTF(outFrame->m_poc);
+ Frame* curFrame =
m_lookahead->m_origPicBuf->m_mcstfPicList.getPOCMCSTF(outFrame->m_poc);
X265_CHECK(curFrame, "Outframe not found in DPB's
mcstfPicList");
curFrame->m_refPicCnt[0]--;
curFrame->m_refPicCnt[1]--;
- curFrame =
m_origPicBuffer->m_mcstfOrigPicList.getPOCMCSTF(outFrame->m_poc);
+ curFrame =
m_lookahead->m_origPicBuf->m_mcstfOrigPicList.getPOCMCSTF(outFrame->m_poc);
X265_CHECK(curFrame, "Outframe not found in OPB's
mcstfOrigPicList");
curFrame->m_refPicCnt[1]--;
}
@@ -2203,7 +2212,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
ATOMIC_DEC(&outFrame->m_countRefEncoders);
m_dpb->recycleUnreferenced();
if (m_param->bEnableTemporalFilter)
- m_origPicBuffer->recycleOrigPicList();
+ m_lookahead->m_origPicBuf->recycleOrigPicList();
}
else
m_exportedPic[sLayer] = outFrame;
@@ -2448,9 +2457,9 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
if (m_param->bEnableTemporalFilter)
{
-
X265_CHECK(!m_origPicBuffer->m_mcstfOrigPicFreeList.empty(), "Frames not
available in Encoded OPB");
+
X265_CHECK(!m_lookahead->m_origPicBuf->m_mcstfOrigPicFreeList.empty(),
"Frames not available in Encoded OPB");
- Frame *dupFrame =
m_origPicBuffer->m_mcstfOrigPicFreeList.popBackMCSTF();
+ Frame* dupFrame =
m_lookahead->m_origPicBuf->m_mcstfOrigPicFreeList.popBackMCSTF();
dupFrame->m_fencPic->copyFromFrame(frameEnc[0]->m_fencPic);
dupFrame->m_poc = frameEnc[0]->m_poc;
dupFrame->m_encodeOrder = frameEnc[0]->m_encodeOrder;
@@ -2461,8 +2470,8 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
if (m_param->totalFrames && (dupFrame->m_poc >=
(m_param->totalFrames - dupFrame->m_mcstf->m_range)))
dupFrame->m_refPicCnt[1] -= (uint8_t)(dupFrame->m_poc
+ dupFrame->m_mcstf->m_range - m_param->totalFrames + 1);
- m_origPicBuffer->addEncPictureToPicList(dupFrame);
- m_origPicBuffer->setOrigPicList(frameEnc[0], m_pocLast);
+
m_lookahead->m_origPicBuf->addEncPictureToPicList(dupFrame);
+ m_lookahead->m_origPicBuf->setOrigPicList(frameEnc[0],
m_pocLast);
}
for (int layer = 0; layer < m_param->numLayers; layer++)
@@ -2510,18 +2519,18 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
for (uint8_t i = 1; i <= frameEnc[0]->m_mcstf->m_numRef;
i++)
{
- TemporalFilterRefPicInfo *ref =
&curEncoder->m_mcstfRefList[i - 1];
- Frame* curFrame =
m_origPicBuffer->m_mcstfPicList.getPOCMCSTF(ref->poc);
+ TemporalFilterRefPicInfo* ref =
&frameEnc[0]->m_mcstfRefList[i - 1];
+ Frame* curFrame =
m_lookahead->m_origPicBuf->m_mcstfPicList.getPOCMCSTF(ref->poc);
-
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs0, ref->mvsStride0,
frameEnc[0]->m_lowres.lowerResPlane[0], (frameEnc[0]->m_lowres.lumaStride /
2), frameEnc[0]->m_fencPicSubsampled4->m_picHeight,
frameEnc[0]->m_fencPicSubsampled4->m_picWidth,
curFrame->m_lowres.lowerResPlane[0], 16);
-
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs1, ref->mvsStride1,
frameEnc[0]->m_lowres.lowresPlane[0], frameEnc[0]->m_lowres.lumaStride,
frameEnc[0]->m_fencPicSubsampled2->m_picHeight,
frameEnc[0]->m_fencPicSubsampled2->m_picWidth,
curFrame->m_lowres.lowresPlane[0], 16, ref->mvs0, ref->mvsStride0, 2);
-
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs2, ref->mvsStride2,
frameEnc[0]->m_fencPic->m_picOrg[0], frameEnc[0]->m_fencPic->m_stride,
frameEnc[0]->m_fencPic->m_picHeight, frameEnc[0]->m_fencPic->m_picWidth,
ref->picBuffer->m_picOrg[0], 16, ref->mvs1, ref->mvsStride1, 2);
-
curEncoder->m_frameEncTF->motionEstimationLumaDoubleRes(ref->mvs,
ref->mvsStride, frameEnc[0]->m_fencPic, ref->picBuffer, 8, ref->mvs2,
ref->mvsStride2, 1, ref->error);
+ //curFrame->m_mcstf->motionEstimationLuma(ref->mvs0,
ref->mvsStride0, frameEnc[0]->m_lowres.lowerResPlane[0],
(curFrame->m_lowres.lumaStride / 2), (curFrame->m_lowres.lines / 2),
(curFrame->m_lowres.width / 2), ref->lowerRes, 16);
+ //curFrame->m_mcstf->motionEstimationLuma(ref->mvs1,
ref->mvsStride1, frameEnc[0]->m_lowres.lowresPlane[0],
(curFrame->m_lowres.lumaStride), (curFrame->m_lowres.lines),
(curFrame->m_lowres.width), ref->lowres, 16, ref->mvs0, ref->mvsStride0, 2);
+ curFrame->m_mcstf->motionEstimationLuma(ref->mvs2,
ref->mvsStride2, frameEnc[0]->m_fencPic->m_picOrg[0],
curFrame->m_fencPic->m_stride, curFrame->m_fencPic->m_picHeight,
curFrame->m_fencPic->m_picWidth, ref->picBuffer->m_picOrg[0], 16,
ref->mvs1, ref->mvsStride1, 2);
+
curFrame->m_mcstf->motionEstimationLumaDoubleRes(ref->mvs, ref->mvsStride,
frameEnc[0]->m_fencPic, ref->picBuffer, 8, ref->mvs2, ref->mvsStride2, 1,
ref->error);
}
for (int i = 0; i < frameEnc[0]->m_mcstf->m_numRef; i++)
{
- TemporalFilterRefPicInfo *ref =
&curEncoder->m_mcstfRefList[i];
+ TemporalFilterRefPicInfo* ref =
&frameEnc[0]->m_mcstfRefList[i];
ref->slicetype =
m_lookahead->findSliceType(frameEnc[0]->m_poc + ref->origOffset);
Frame* dpbframePtr =
m_dpb->m_picList.getPOC(frameEnc[0]->m_poc + ref->origOffset, 0);
if (dpbframePtr != NULL)
diff --git a/source/encoder/frameencoder.cpp
b/source/encoder/frameencoder.cpp
index b6f2d6ed1..772810f3d 100644
--- a/source/encoder/frameencoder.cpp
+++ b/source/encoder/frameencoder.cpp
@@ -677,7 +677,7 @@ void FrameEncoder::compressFrame(int layer)
if (m_param->bEnableTemporalFilter)
{
m_frameEncTF->m_QP = qp;
- m_frameEncTF->bilateralFilter(m_frame[layer], m_mcstfRefList,
m_param->temporalFilterStrength);
+ m_frameEncTF->bilateralFilter(m_frame[layer],
m_frame[layer]->m_mcstfRefList, m_param->temporalFilterStrength);
}
if (m_nr)
diff --git a/source/encoder/slicetype.cpp b/source/encoder/slicetype.cpp
index 8bbac8244..19f6d8f53 100644
--- a/source/encoder/slicetype.cpp
+++ b/source/encoder/slicetype.cpp
@@ -991,6 +991,7 @@ Lookahead::Lookahead(x265_param *param, ThreadPool*
pool)
m_isFadeIn = false;
m_fadeCount = 0;
m_fadeStart = -1;
+ m_origPicBuf = 0;
/* Allow the strength to be adjusted via qcompress, since the two
concepts
* are very similar. */
@@ -1126,6 +1127,9 @@ bool Lookahead::create()
m_tld[i].init(m_8x8Width, m_8x8Height, m_8x8Blocks);
m_scratch = X265_MALLOC(int, m_tld[0].widthInCU);
+ if (m_param->bEnableTemporalFilter)
+ m_origPicBuf = new OrigPicBuffer();
+
return m_tld && m_scratch;
}
@@ -1165,6 +1169,9 @@ void Lookahead::destroy()
delete curFrame;
}
+ if (m_param->bEnableTemporalFilter)
+ delete m_origPicBuf;
+
X265_FREE(m_scratch);
delete [] m_tld;
if (m_param->lookaheadThreads > 0)
@@ -1787,6 +1794,108 @@ void Lookahead::compCostBref(Lowres **frames, int
start, int end, int num)
}
}
+void Lookahead::estimatelowresmotion(Frame* curframe)
+{
+
+ for (int i = 1; i <= curframe->m_mcstf->m_numRef; i++)
+ {
+ TemporalFilterRefPicInfo * ref = &curframe->m_mcstfRefList[i - 1];
+
+ curframe->m_mcstf->motionEstimationLuma(ref->mvs0,
ref->mvsStride0, curframe->m_lowres.lowerResPlane[0],
(curframe->m_lowres.lumaStride / 2), (curframe->m_lowres.lines / 2),
(curframe->m_lowres.width / 2), ref->lowerRes, 16);
+ curframe->m_mcstf->motionEstimationLuma(ref->mvs1,
ref->mvsStride1, curframe->m_lowres.lowresPlane[0],
(curframe->m_lowres.lumaStride), (curframe->m_lowres.lines),
(curframe->m_lowres.width), ref->lowres, 16, ref->mvs0, ref->mvsStride0, 2);
+ //curframe->m_mcstf->motionEstimationLuma(ref->mvs2,
ref->mvsStride2, curframe->m_fencPic->m_picOrg[0],
curframe->m_fencPic->m_stride, curframe->m_fencPic->m_picHeight,
curframe->m_fencPic->m_picWidth, ref->picBuffer->m_picOrg[0], 16,
ref->mvs1, ref->mvsStride1, 2);
+ //curframe->m_mcstf->motionEstimationLumaDoubleRes(ref->mvs,
ref->mvsStride, curframe->m_fencPic, ref->picBuffer, 8, ref->mvs2,
ref->mvsStride2, 1, ref->error);
+ }
+
+}
+
+inline int enqueueRefFrame(Frame* iterFrame, Frame* curFrame, bool
isPreFiltered, int16_t i)
+{
+ TemporalFilterRefPicInfo * temp =
&curFrame->m_mcstfRefList[curFrame->m_mcstf->m_numRef];
+ temp->poc = iterFrame->m_poc;
+ temp->picBuffer = iterFrame->m_fencPic;
+ temp->lowres = iterFrame->m_lowres.lowresPlane[0];
+ temp->lowerRes = iterFrame->m_lowres.lowerResPlane[0];
+ temp->isFilteredFrame = isPreFiltered;
+ temp->isSubsampled = iterFrame->m_isSubSampled;
+ temp->origOffset = i;
+ curFrame->m_mcstf->m_numRef++;
+
+ return 1;
+}
+
+bool Lookahead::isFilterThisframe(uint8_t sliceTypeConfig, int
curSliceType)
+{
+ uint8_t newSliceType = 0;
+ switch (curSliceType)
+ {
+ case 1: newSliceType |= 1 << 0;
+ break;
+ case 2: newSliceType |= 1 << 0;
+ break;
+ case 3: newSliceType |= 1 << 1;
+ break;
+ case 4: newSliceType |= 1 << 2;
+ break;
+ case 5: newSliceType |= 1 << 3;
+ break;
+ default: return 0;
+ }
+ return ((sliceTypeConfig & newSliceType) != 0);
+}
+
+bool Lookahead::generatemcstf(Frame * frameEnc, PicList refPic, int
poclast)
+ {
+ frameEnc->m_mcstf->m_numRef = 0;
+
+ for (int iterPOC = (frameEnc->m_poc - frameEnc->m_mcstf->m_range);
+ iterPOC <= (frameEnc->m_poc + frameEnc->m_mcstf->m_range);
iterPOC++)
+ {
+ bool isFound = false;
+ if (iterPOC != frameEnc->m_poc)
+ {
+ //search for the reference frame in the Original Picture
Buffer
+ if (!isFound)
+ {
+ for (int j = 0; j < (2 * frameEnc->m_mcstf->m_range); j++)
+ {
+ if (iterPOC < 0)
+ continue;
+ if (iterPOC >= poclast)
+ {
+
+ TemporalFilter * mcstf = frameEnc->m_mcstf;
+ while (mcstf->m_numRef)
+ {
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].mvs0, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 16) * (mcstf->m_sourceHeight / 16)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].mvs1, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 16) * (mcstf->m_sourceHeight / 16)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].mvs2, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 16) * (mcstf->m_sourceHeight / 16)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].mvs, 0, sizeof(MV) *
((mcstf->m_sourceWidth / 4) * (mcstf->m_sourceHeight / 4)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].noise, 0, sizeof(int) *
((mcstf->m_sourceWidth / 4) * (mcstf->m_sourceHeight / 4)));
+
memset(frameEnc->m_mcstfRefList[mcstf->m_numRef].error, 0, sizeof(int) *
((mcstf->m_sourceWidth / 4) * (mcstf->m_sourceHeight / 4)));
+
+ mcstf->m_numRef--;
+ }
+
+ break;
+ }
+ Frame * iterFrame = refPic.getPOCMCSTF(iterPOC);
+ if (iterFrame->m_poc == iterPOC)
+ {
+ if (!enqueueRefFrame(iterFrame, frameEnc, false,
(int16_t)(iterPOC - frameEnc->m_poc)))
+ {
+ return false;
+ };
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
/* called by API thread or worker thread with inputQueueLock acquired */
void Lookahead::slicetypeDecide()
{
@@ -2047,6 +2156,22 @@ void Lookahead::slicetypeDecide()
}
}
+ Frame* frameEnc = m_inputQueue.first();
+ for (int i = 0; i < m_inputQueue.size(); i++)
+ {
+ if (m_param->bEnableTemporalFilter &&
isFilterThisframe(frameEnc->m_mcstf->m_sliceTypeConfig,
frameEnc->m_lowres.sliceType))
+ {
+ if (!generatemcstf(frameEnc, m_origPicBuf->m_mcstfPicList,
m_inputQueue.last()->m_poc))
+ {
+ x265_log(m_param, X265_LOG_ERROR, "Failed to initialize
MCSTFReferencePicInfo at POC %d\n", frameEnc->m_poc);
+ fflush(stderr);
+ }
+
+ estimatelowresmotion(frameEnc);
+ }
+ frameEnc = frameEnc->m_next;
+ }
+
if (m_param->bEnableTemporalSubLayers > 2)
{
//Split the partial mini GOP into sub mini GOPs when temporal sub
layers are enabled
diff --git a/source/encoder/slicetype.h b/source/encoder/slicetype.h
index f4184e4e2..214e295b7 100644
--- a/source/encoder/slicetype.h
+++ b/source/encoder/slicetype.h
@@ -30,6 +30,7 @@
#include "motion.h"
#include "piclist.h"
#include "threadpool.h"
+#include "temporalfilter.h"
namespace X265_NS {
// private namespace
@@ -202,6 +203,8 @@ public:
int8_t m_gopId;
+ OrigPicBuffer* m_origPicBuf;
+
Lookahead(x265_param *param, ThreadPool *pool);
#if DETAILED_CU_STATS
int64_t m_slicetypeDecideElapsedTime;
@@ -224,6 +227,10 @@ public:
void getEstimatedPictureCost(Frame *pic);
void setLookaheadQueue();
int findSliceType(int poc);
+ void estimatelowresmotion(Frame* frame);
+ bool generatemcstf(Frame * frame, PicList refPic, int poclast);
+ bool isFilterThisframe(uint8_t sliceTypeConfig, int curSliceType);
+
protected:
--
2.36.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20241111/a256aa9a/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0004-shifted-mcstf-from-encoder-to-lookahead.patch
Type: application/octet-stream
Size: 22070 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20241111/a256aa9a/attachment-0001.obj>
More information about the x265-devel
mailing list