[x265] [PATCH 02/10] Make use of halfpel and quarterpel source frames from lookahead for mcstf
Anusuya Kumarasamy
anusuya.kumarasamy at multicorewareinc.com
Mon Nov 11 13:08:44 UTC 2024
>From 378b56a91aafc13dec3882e96905b8478d27a566 Mon Sep 17 00:00:00 2001
From: AnusuyaKumarasamy <anusuya.kumarasamy at multicorewareinc.com>
Date: Thu, 24 Oct 2024 12:46:40 +0530
Subject: [PATCH 02/10] Make use of halfpel and quarterpel source frames from
lookahead for mcstf
---
source/common/lowres.cpp | 4 +-
source/common/temporalfilter.cpp | 76 ++++++++++++++++----------------
source/common/temporalfilter.h | 8 ++--
source/encoder/encoder.cpp | 18 ++------
4 files changed, 50 insertions(+), 56 deletions(-)
diff --git a/source/common/lowres.cpp b/source/common/lowres.cpp
index 857414e91..14d1e03f4 100644
--- a/source/common/lowres.cpp
+++ b/source/common/lowres.cpp
@@ -162,7 +162,7 @@ bool Lowres::create(x265_param* param, PicYuv *origPic,
uint32_t qgSize)
lowresPlane[2] = buffer[2] + padoffset;
lowresPlane[3] = buffer[3] + padoffset;
- if (bEnableHME)
+ if (bEnableHME || param->bEnableTemporalFilter)
{
intptr_t lumaStrideHalf = lumaStride / 2;
if (lumaStrideHalf & 31)
@@ -375,7 +375,7 @@ void Lowres::init(PicYuv *origPic, int poc)
extendPicBorder(lowresPlane[2], lumaStride, width, lines,
origPic->m_lumaMarginX, origPic->m_lumaMarginY);
extendPicBorder(lowresPlane[3], lumaStride, width, lines,
origPic->m_lumaMarginX, origPic->m_lumaMarginY);
- if (origPic->m_param->bEnableHME)
+ if (origPic->m_param->bEnableHME ||
origPic->m_param->bEnableTemporalFilter)
{
primitives.frameInitLowerRes(lowresPlane[0],
lowerResPlane[0], lowerResPlane[1], lowerResPlane[2],
lowerResPlane[3],
diff --git a/source/common/temporalfilter.cpp
b/source/common/temporalfilter.cpp
index 5b75517ee..235379b63 100644
--- a/source/common/temporalfilter.cpp
+++ b/source/common/temporalfilter.cpp
@@ -192,7 +192,8 @@ fail:
}
int TemporalFilter::motionErrorLumaSAD(
- PicYuv *orig,
+ pixel* src,
+ int stride,
PicYuv *buffer,
int x,
int y,
@@ -202,8 +203,8 @@ int TemporalFilter::motionErrorLumaSAD(
int besterror)
{
- pixel* origOrigin = orig->m_picOrg[0];
- intptr_t origStride = orig->m_stride;
+ pixel* origOrigin = src;
+ intptr_t origStride = stride;
pixel *buffOrigin = buffer->m_picOrg[0];
intptr_t buffStride = buffer->m_stride;
int error = 0;// dx * 10 + dy * 10;
@@ -296,7 +297,8 @@ int TemporalFilter::motionErrorLumaSAD(
}
int TemporalFilter::motionErrorLumaSSD(
- PicYuv *orig,
+ pixel* src,
+ int stride,
PicYuv *buffer,
int x,
int y,
@@ -306,8 +308,8 @@ int TemporalFilter::motionErrorLumaSSD(
int besterror)
{
- pixel* origOrigin = orig->m_picOrg[0];
- intptr_t origStride = orig->m_stride;
+ pixel* origOrigin = src;
+ intptr_t origStride = stride;
pixel *buffOrigin = buffer->m_picOrg[0];
intptr_t buffStride = buffer->m_stride;
int error = 0;// dx * 10 + dy * 10;
@@ -646,7 +648,7 @@ void TemporalFilter::bilateralFilter(Frame* frame,
}
}
-void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride,
PicYuv *orig, PicYuv *buffer, int blockSize,
+void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride,
pixel* src,int stride, int height, int width, PicYuv *buffer, int blockSize,
MV *previous, uint32_t prevMvStride, int factor)
{
@@ -655,8 +657,8 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
const int stepSize = blockSize;
- const int origWidth = orig->m_picWidth;
- const int origHeight = orig->m_picHeight;
+ const int origWidth = width;
+ const int origHeight = height;
int error;
@@ -664,8 +666,8 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
{
for (int blockX = 0; blockX + blockSize <= origWidth; blockX +=
stepSize)
{
- const intptr_t pelOffset = blockY * orig->m_stride + blockX;
- m_metld->me.setSourcePU(orig->m_picOrg[0], orig->m_stride,
pelOffset, blockSize, blockSize, X265_HEX_SEARCH, 1);
+ const intptr_t pelOffset = blockY * stride + blockX;
+ m_metld->me.setSourcePU(src, stride, pelOffset, blockSize,
blockSize, X265_HEX_SEARCH, 1);
MV best(0, 0);
@@ -692,9 +694,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
MV old = previous[mvIdx];
if (m_useSADinME)
- error = motionErrorLumaSAD(orig, buffer,
blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);
+ error = motionErrorLumaSAD(src, stride,
buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize,
leastError);
else
- error = motionErrorLumaSSD(orig, buffer,
blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);
+ error = motionErrorLumaSSD(src, stride,
buffer, blockX, blockY, old.x * factor, old.y * factor, blockSize,
leastError);
if (error < leastError)
{
@@ -706,9 +708,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
}
if (m_useSADinME)
- error = motionErrorLumaSAD(orig, buffer, blockX,
blockY, 0, 0, blockSize, leastError);
+ error = motionErrorLumaSAD(src, stride, buffer,
blockX, blockY, 0, 0, blockSize, leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, 0, 0, blockSize, leastError);
+ error = motionErrorLumaSSD(src, stride, buffer,
blockX, blockY, 0, 0, blockSize, leastError);
if (error < leastError)
{
@@ -724,9 +726,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
for (int x2 = prevBest.x / m_motionVectorFactor - range;
x2 <= prevBest.x / m_motionVectorFactor + range; x2++)
{
if (m_useSADinME)
- error = motionErrorLumaSAD(orig, buffer, blockX,
blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize,
leastError);
+ error = motionErrorLumaSAD(src, stride, buffer,
blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor,
blockSize, leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize,
leastError);
+ error = motionErrorLumaSSD(src, stride, buffer,
blockX, blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor,
blockSize, leastError);
if (error < leastError)
{
best.set(x2 * m_motionVectorFactor, y2 *
m_motionVectorFactor);
@@ -741,9 +743,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
MV aboveMV = mvs[idx];
if (m_useSADinME)
- error = motionErrorLumaSAD(orig, buffer, blockX,
blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
+ error = motionErrorLumaSAD(src, stride, buffer,
blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
+ error = motionErrorLumaSSD(src, stride, buffer,
blockX, blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
if (error < leastError)
{
@@ -758,9 +760,9 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
MV leftMV = mvs[idx];
if (m_useSADinME)
- error = motionErrorLumaSAD(orig, buffer, blockX,
blockY, leftMV.x, leftMV.y, blockSize, leastError);
+ error = motionErrorLumaSAD(src, stride, buffer,
blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, leftMV.x, leftMV.y, blockSize, leastError);
+ error = motionErrorLumaSSD(src, stride, buffer,
blockX, blockY, leftMV.x, leftMV.y, blockSize, leastError);
if (error < leastError)
{
@@ -775,7 +777,7 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
{
for (int y1 = 0; y1 < blockSize; y1++)
{
- avg = avg + *(orig->m_picOrg[0] + (blockX + x1 +
orig->m_stride * (blockY + y1)));
+ avg = avg + *(src + (blockX + x1 + stride * (blockY +
y1)));
}
}
avg = avg / (blockSize * blockSize);
@@ -786,7 +788,7 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
{
for (int y1 = 0; y1 < blockSize; y1++)
{
- int pix = *(orig->m_picOrg[0] + (blockX + x1 +
orig->m_stride * (blockY + y1)));
+ int pix = *(src + (blockX + x1 + stride * (blockY +
y1)));
variance = variance + (pix - avg) * (pix - avg);
}
}
@@ -846,9 +848,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
MV old = previous[mvIdx];
if (m_useSADinME)
- error = motionErrorLumaSAD(orig, buffer,
blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);
+ error =
motionErrorLumaSAD(orig->m_picOrg[0], orig->m_stride, buffer, blockX,
blockY, old.x * factor, old.y * factor, blockSize, leastError);
else
- error = motionErrorLumaSSD(orig, buffer,
blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);
+ error =
motionErrorLumaSSD(orig->m_picOrg[0], orig->m_stride, buffer, blockX,
blockY, old.x * factor, old.y * factor, blockSize, leastError);
if (error < leastError)
{
@@ -860,9 +862,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
}
if (m_useSADinME)
- error = motionErrorLumaSAD(orig, buffer, blockX,
blockY, 0, 0, blockSize, leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, 0, 0, blockSize, leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, 0, 0, blockSize, leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, 0, 0, blockSize, leastError);
if (error < leastError)
{
@@ -878,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, buffer, blockX,
blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize,
leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2 * m_motionVectorFactor, y2 *
m_motionVectorFactor, blockSize, leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, x2 * m_motionVectorFactor, y2 * m_motionVectorFactor, blockSize,
leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2 * m_motionVectorFactor, y2 *
m_motionVectorFactor, blockSize, leastError);
if (error < leastError)
{
@@ -897,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, buffer, blockX,
blockY, x2, y2, blockSize, leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, x2, y2, blockSize, leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);
if (error < leastError)
{
@@ -916,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, buffer, blockX,
blockY, x2, y2, blockSize, leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, x2, y2, blockSize, leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, x2, y2, blockSize, leastError);
if (error < leastError)
{
@@ -935,9 +937,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
MV aboveMV = mvs[idx];
if (m_useSADinME)
- error = motionErrorLumaSAD(orig, buffer, blockX,
blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize,
leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, aboveMV.x, aboveMV.y, blockSize, leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, aboveMV.x, aboveMV.y, blockSize,
leastError);
if (error < leastError)
{
@@ -952,9 +954,9 @@ void TemporalFilter::motionEstimationLumaDoubleRes(MV
*mvs, uint32_t mvStride, P
MV leftMV = mvs[idx];
if (m_useSADinME)
- error = motionErrorLumaSAD(orig, buffer, blockX,
blockY, leftMV.x, leftMV.y, blockSize, leastError);
+ error = motionErrorLumaSAD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize,
leastError);
else
- error = motionErrorLumaSSD(orig, buffer, blockX,
blockY, leftMV.x, leftMV.y, blockSize, leastError);
+ error = motionErrorLumaSSD(orig->m_picOrg[0],
orig->m_stride, buffer, blockX, blockY, leftMV.x, leftMV.y, blockSize,
leastError);
if (error < leastError)
{
diff --git a/source/common/temporalfilter.h b/source/common/temporalfilter.h
index 723644633..ae60c77f8 100644
--- a/source/common/temporalfilter.h
+++ b/source/common/temporalfilter.h
@@ -152,13 +152,14 @@ namespace X265_NS {
void bilateralFilter(Frame* frame, TemporalFilterRefPicInfo*
mctfRefList, double overallStrength);
- void motionEstimationLuma(MV *mvs, uint32_t mvStride, PicYuv
*orig, PicYuv *buffer, int bs,
+ void motionEstimationLuma(MV *mvs, uint32_t mvStride, pixel* src,
int stride, int height, int width, PicYuv *buffer, 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,
MV *previous, uint32_t prevMvStride, int factor, int*
minError);
- int motionErrorLumaSSD(PicYuv *orig,
+ int motionErrorLumaSSD(pixel* src,
+ int stride,
PicYuv *buffer,
int x,
int y,
@@ -167,7 +168,8 @@ namespace X265_NS {
int bs,
int besterror = 8 * 8 * 1024 * 1024);
- int motionErrorLumaSAD(PicYuv *orig,
+ int motionErrorLumaSAD(pixel* src,
+ int stride,
PicYuv *buffer,
int x,
int y,
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index 5e715b713..58818379a 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -2507,16 +2507,6 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
return -1;
}
-
- if (!*frameEnc[0]->m_isSubSampled)
- {
- primitives.frameSubSampleLuma((const pixel
*)frameEnc[0]->m_fencPic->m_picOrg[0],frameEnc[0]->m_fencPicSubsampled2->m_picOrg[0],
frameEnc[0]->m_fencPic->m_stride,
frameEnc[0]->m_fencPicSubsampled2->m_stride,
frameEnc[0]->m_fencPicSubsampled2->m_picWidth,
frameEnc[0]->m_fencPicSubsampled2->m_picHeight);
-
extendPicBorder(frameEnc[0]->m_fencPicSubsampled2->m_picOrg[0],
frameEnc[0]->m_fencPicSubsampled2->m_stride,
frameEnc[0]->m_fencPicSubsampled2->m_picWidth,
frameEnc[0]->m_fencPicSubsampled2->m_picHeight,
frameEnc[0]->m_fencPicSubsampled2->m_lumaMarginX,
frameEnc[0]->m_fencPicSubsampled2->m_lumaMarginY);
- primitives.frameSubSampleLuma((const pixel
*)frameEnc[0]->m_fencPicSubsampled2->m_picOrg[0],frameEnc[0]->m_fencPicSubsampled4->m_picOrg[0],
frameEnc[0]->m_fencPicSubsampled2->m_stride,
frameEnc[0]->m_fencPicSubsampled4->m_stride,
frameEnc[0]->m_fencPicSubsampled4->m_picWidth,
frameEnc[0]->m_fencPicSubsampled4->m_picHeight);
-
extendPicBorder(frameEnc[0]->m_fencPicSubsampled4->m_picOrg[0],
frameEnc[0]->m_fencPicSubsampled4->m_stride,
frameEnc[0]->m_fencPicSubsampled4->m_picWidth,
frameEnc[0]->m_fencPicSubsampled4->m_picHeight,
frameEnc[0]->m_fencPicSubsampled4->m_lumaMarginX,
frameEnc[0]->m_fencPicSubsampled4->m_lumaMarginY);
- *frameEnc[0]->m_isSubSampled = true;
- }
-
for (uint8_t i = 1; i <= frameEnc[0]->m_mcstf->m_numRef;
i++)
{
TemporalFilterRefPicInfo *ref =
&curEncoder->m_mcstfRefList[i - 1];
@@ -2534,10 +2524,10 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
{
TemporalFilterRefPicInfo *ref =
&curEncoder->m_mcstfRefList[i - 1];
-
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs0, ref->mvsStride0,
frameEnc[0]->m_fencPicSubsampled4, ref->picBufferSubSampled4, 16);
-
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs1, ref->mvsStride1,
frameEnc[0]->m_fencPicSubsampled2, ref->picBufferSubSampled2, 16,
ref->mvs0, ref->mvsStride0, 2);
-
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs2, ref->mvsStride2,
frameEnc[0]->m_fencPic, ref->picBuffer, 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);
+
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->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++)
--
2.36.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20241111/190a489d/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Make-use-of-halfpel-and-quarterpel-source-frames-fro.patch
Type: application/octet-stream
Size: 21053 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20241111/190a489d/attachment-0001.obj>
More information about the x265-devel
mailing list