[x265] [PATCH 03/10] Make use of halfpel & quarterpel resolution reference frame from lookahead for mcstf
Anusuya Kumarasamy
anusuya.kumarasamy at multicorewareinc.com
Mon Nov 11 14:13:25 UTC 2024
>From 0a3736655de21539cd7c302af18a46ec05c41b43 Mon Sep 17 00:00:00 2001
From: AnusuyaKumarasamy <anusuya.kumarasamy at multicorewareinc.com>
Date: Thu, 24 Oct 2024 12:57:53 +0530
Subject: [PATCH 03/10] Make use of halfpel & quarterpel resolution reference
frame from lookahead for mcstf
---
source/common/temporalfilter.cpp | 62 ++++++++++++++++----------------
source/common/temporalfilter.h | 7 ++--
source/encoder/encoder.cpp | 21 +++--------
3 files changed, 40 insertions(+), 50 deletions(-)
diff --git a/source/common/temporalfilter.cpp
b/source/common/temporalfilter.cpp
index 235379b63..7c1be767e 100644
--- a/source/common/temporalfilter.cpp
+++ b/source/common/temporalfilter.cpp
@@ -194,7 +194,7 @@ fail:
int TemporalFilter::motionErrorLumaSAD(
pixel* src,
int stride,
- PicYuv *buffer,
+ pixel* buf,
int x,
int y,
int dx,
@@ -205,8 +205,8 @@ int TemporalFilter::motionErrorLumaSAD(
pixel* origOrigin = src;
intptr_t origStride = stride;
- pixel *buffOrigin = buffer->m_picOrg[0];
- intptr_t buffStride = buffer->m_stride;
+ pixel *buffOrigin = buf;
+ intptr_t buffStride = stride;
int error = 0;// dx * 10 + dy * 10;
if (((dx | dy) & 0xF) == 0)
{
@@ -299,7 +299,7 @@ int TemporalFilter::motionErrorLumaSAD(
int TemporalFilter::motionErrorLumaSSD(
pixel* src,
int stride,
- PicYuv *buffer,
+ pixel* buf,
int x,
int y,
int dx,
@@ -310,8 +310,8 @@ int TemporalFilter::motionErrorLumaSSD(
pixel* origOrigin = src;
intptr_t origStride = stride;
- pixel *buffOrigin = buffer->m_picOrg[0];
- intptr_t buffStride = buffer->m_stride;
+ pixel *buffOrigin = buf;
+ intptr_t buffStride = stride;
int error = 0;// dx * 10 + dy * 10;
if (((dx | dy) & 0xF) == 0)
{
@@ -648,7 +648,7 @@ void TemporalFilter::bilateralFilter(Frame* frame,
}
}
-void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride,
pixel* src,int stride, int height, int width, PicYuv *buffer, int blockSize,
+void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride,
pixel* src,int stride, int height, int width, pixel* buf, int blockSize,
MV *previous, uint32_t prevMvStride, int factor)
{
@@ -694,9 +694,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, pixel* src
MV old = previous[mvIdx];
if (m_useSADinME)
- error = motionErrorLumaSAD(src, stride,
buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize,
leastError);
+ error = motionErrorLumaSAD(src, stride,
buf, blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);
else
- error = motionErrorLumaSSD(src, stride,
buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize,
leastError);
+ error = motionErrorLumaSSD(src, stride,
buf, blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);
if (error < leastError)
{
@@ -708,9 +708,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, pixel* src
}
if (m_useSADinME)
- error = motionErrorLumaSAD(src, stride, buffer,
blockX, blockY, 0, 0, blockSize, leastError);
+ error = motionErrorLumaSAD(src, stride, buf, blockX,
blockY, 0, 0, blockSize, leastError);
else
- error = motionErrorLumaSSD(src, stride, buffer,
blockX, blockY, 0, 0, blockSize, leastError);
+ error = motionErrorLumaSSD(src, stride, buf, blockX,
blockY, 0, 0, blockSize, leastError);
if (error < leastError)
{
@@ -726,9 +726,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, pixel* src
for (int x2 = prevBest.x / m_motionVectorFactor - range;
x2 <= prevBest.x / m_motionVectorFactor + range; x2++)
{
if (m_useSADinME)
- error = motionErrorLumaSAD(src, stride, buffer,
blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor,
blockSize, leastError);
+ error = motionErrorLumaSAD(src, stride, buf,
blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor,
blockSize, leastError);
else
- error = motionErrorLumaSSD(src, stride, buffer,
blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor,
blockSize, leastError);
+ error = motionErrorLumaSSD(src, stride, buf,
blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor,
blockSize, leastError);
if (error < leastError)
{
best.set(x2 * m_motionVectorFactor, y2 *
m_motionVectorFactor);
@@ -743,9 +743,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, pixel* src
MV aboveMV = mvs[idx];
if (m_useSADinME)
- error = motionErrorLumaSAD(src, stride, buffer,
blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
+ error = motionErrorLumaSAD(src, stride, buf, blockX,
blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
else
- error = motionErrorLumaSSD(src, stride, buffer,
blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
+ error = motionErrorLumaSSD(src, stride, buf, blockX,
blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
if (error < leastError)
{
@@ -760,9 +760,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, pixel* src
MV leftMV = mvs[idx];
if (m_useSADinME)
- error = motionErrorLumaSAD(src, stride, buffer,
blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);
+ error = motionErrorLumaSAD(src, stride, buf, blockX,
blockY, leftMV.x, leftMV.y, blockSize, leastError);
else
- error = motionErrorLumaSSD(src, stride, buffer,
blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);
+ error = motionErrorLumaSSD(src, stride, buf, blockX,
blockY, leftMV.x, leftMV.y, blockSize, leastError);
if (error < leastError)
{
@@ -848,9 +848,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
MV old = previous[mvIdx];
if (m_useSADinME)
- error =
motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer, blockX,
blockY, old.x * factor, old.y * factor, blockSize, leastError);
+ error =
motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0],
blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);
else
- error =
motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer, blockX,
blockY, old.x * factor, old.y * factor, blockSize, leastError);
+ error =
motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer->m_picOrg[0],
blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);
if (error < leastError)
{
@@ -862,9 +862,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
}
if (m_useSADinME)
- error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, 0, 0, blockSize, leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, 0, 0, blockSize,
leastError);
else
- error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, 0, 0, blockSize, leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, 0, 0, blockSize,
leastError);
if (error < leastError)
{
@@ -880,9 +880,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
for (int x2 = prevBest.x / m_motionVectorFactor - range;
x2 <= prevBest.x / m_motionVectorFactor + range; x2++)
{
if (m_useSADinME)
- error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2 * m_motionVectorFactor, y2 *
m_motionVectorFactor, blockSize, leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2 *
m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);
else
- error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2 * m_motionVectorFactor, y2 *
m_motionVectorFactor, blockSize, leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2 *
m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize, leastError);
if (error < leastError)
{
@@ -899,9 +899,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x +
doubleRange; x2 += 4)
{
if (m_useSADinME)
- error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2, y2, blockSize,
leastError);
else
- error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2, y2, blockSize,
leastError);
if (error < leastError)
{
@@ -918,9 +918,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x +
doubleRange; x2++)
{
if (m_useSADinME)
- error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2, y2, blockSize,
leastError);
else
- error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, x2, y2, blockSize,
leastError);
if (error < leastError)
{
@@ -937,9 +937,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
MV aboveMV = mvs[idx];
if (m_useSADinME)
- error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize,
leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, aboveMV.x, aboveMV.y,
blockSize, leastError);
else
- error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize,
leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, aboveMV.x, aboveMV.y,
blockSize, leastError);
if (error < leastError)
{
@@ -954,9 +954,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
MV leftMV = mvs[idx];
if (m_useSADinME)
- error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize,
leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, leftMV.x, leftMV.y,
blockSize, leastError);
else
- error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize,
leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer->m_picOrg[0], blockX, blockY, leftMV.x, leftMV.y,
blockSize, leastError);
if (error < leastError)
{
diff --git a/source/common/temporalfilter.h b/source/common/temporalfilter.h
index ae60c77f8..9fe51da8c 100644
--- a/source/common/temporalfilter.h
+++ b/source/common/temporalfilter.h
@@ -104,6 +104,7 @@ namespace X265_NS {
uint32_t mvsStride2;
int* error;
int* noise;
+ int poc;
int16_t origOffset;
bool isFilteredFrame;
@@ -152,7 +153,7 @@ namespace X265_NS {
void bilateralFilter(Frame* frame, TemporalFilterRefPicInfo*
mctfRefList, double overallStrength);
- void motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src,
int stride, int height, int width, PicYuv *buffer, int bs,
+ void motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src,
int stride, int height, int width, pixel* buf, int bs,
MV *previous = 0, uint32_t prevmvStride = 0, int factor = 1);
void motionEstimationLumaDoubleRes(MV *mvs, uint32_t mvStride,
PicYuv *orig, PicYuv *buffer, int blockSize,
@@ -160,7 +161,7 @@ namespace X265_NS {
int motionErrorLumaSSD(pixel* src,
int stride,
- PicYuv *buffer,
+ pixel* buf,
int x,
int y,
int dx,
@@ -170,7 +171,7 @@ namespace X265_NS {
int motionErrorLumaSAD(pixel* src,
int stride,
- PicYuv *buffer,
+ pixel* buf,
int x,
int y,
int dx,
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index 58818379a..0a0c09307 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -1408,6 +1408,7 @@ bool Encoder::isFilterThisframe(uint8_t
sliceTypeConfig, int curSliceType)
inline int enqueueRefFrame(FrameEncoder* curframeEncoder, Frame*
iterFrame, Frame* curFrame, bool isPreFiltered, int16_t i)
{
TemporalFilterRefPicInfo* dest =
&curframeEncoder->m_mcstfRefList[curFrame->m_mcstf->m_numRef];
+ dest->poc = iterFrame->m_poc;
dest->picBuffer = iterFrame->m_fencPic;
dest->picBufferSubSampled2 = iterFrame->m_fencPicSubsampled2;
dest->picBufferSubSampled4 = iterFrame->m_fencPicSubsampled4;
@@ -2510,23 +2511,11 @@ 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];
- if (!*ref->isSubsampled)
- {
- primitives.frameSubSampleLuma((const pixel
*)ref->picBuffer->m_picOrg[0], ref->picBufferSubSampled2->m_picOrg[0],
ref->picBuffer->m_stride, ref->picBufferSubSampled2->m_stride,
ref->picBufferSubSampled2->m_picWidth,
ref->picBufferSubSampled2->m_picHeight);
-
extendPicBorder(ref->picBufferSubSampled2->m_picOrg[0],
ref->picBufferSubSampled2->m_stride, ref->picBufferSubSampled2->m_picWidth,
ref->picBufferSubSampled2->m_picHeight,
ref->picBufferSubSampled2->m_lumaMarginX,
ref->picBufferSubSampled2->m_lumaMarginY);
- primitives.frameSubSampleLuma((const pixel
*)ref->picBufferSubSampled2->m_picOrg[0],ref->picBufferSubSampled4->m_picOrg[0],
ref->picBufferSubSampled2->m_stride, ref->picBufferSubSampled4->m_stride,
ref->picBufferSubSampled4->m_picWidth,
ref->picBufferSubSampled4->m_picHeight);
-
extendPicBorder(ref->picBufferSubSampled4->m_picOrg[0],
ref->picBufferSubSampled4->m_stride, ref->picBufferSubSampled4->m_picWidth,
ref->picBufferSubSampled4->m_picHeight,
ref->picBufferSubSampled4->m_lumaMarginX,
ref->picBufferSubSampled4->m_lumaMarginY);
- *ref->isSubsampled = true;
- }
- }
-
- 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);
-
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, ref->picBufferSubSampled4,
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, ref->picBufferSubSampled2,
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, 16, ref->mvs1, ref->mvsStride1, 2);
+
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);
}
--
2.36.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20241111/f4481a4c/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-Make-use-of-halfpel-quarterpel-resolution-reference-.patch
Type: application/octet-stream
Size: 19445 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20241111/f4481a4c/attachment-0001.obj>
More information about the x265-devel
mailing list