[x265] [PATCH 8/14] Made separate functions for low res and full res planes
Snehaa Giridharan
snehaa at multicorewareinc.com
Wed Oct 19 07:30:41 UTC 2022
>From 38b58fad3d88b09647ebcd41649cb3791ed6bcda Mon Sep 17 00:00:00 2001
From: ashok2022 <ashok at multicorewareinc.com>
Date: Thu, 29 Sep 2022 12:46:06 +0530
Subject: [PATCH] Made separate functions for low res and full res planes
---
source/common/temporalfilter.cpp | 169 ++++++++++++++++++++++++++-----
source/common/temporalfilter.h | 5 +-
source/encoder/encoder.cpp | 2 +-
3 files changed, 150 insertions(+), 26 deletions(-)
diff --git a/source/common/temporalfilter.cpp
b/source/common/temporalfilter.cpp
index b286fc235..1d7e670e1 100644
--- a/source/common/temporalfilter.cpp
+++ b/source/common/temporalfilter.cpp
@@ -746,10 +746,10 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
/*New Version: motionEstimationLuma*/
void TemporalFilter::motionEstimationLuma(MV *mvs, uint32_t mvStride,
PicYuv *orig, PicYuv *buffer, int blockSize,
- MV *previous, uint32_t prevMvStride, int factor, bool doubleRes, int*
minError)
+ MV *previous, uint32_t prevMvStride, int factor)
{
- int range = doubleRes ? 0 : 5;
+ int range = 5;
const int stepSize = blockSize;
@@ -817,39 +817,161 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
}
}
- if (doubleRes)
- { // merge into one loop, probably with precision array (here
[12, 3] or maybe [4, 1]) with setable number of iterations
- prevBest = best;
- int doubleRange = 3 * 4;
- for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y +
doubleRange; y2 += 4)
+ if (blockY > 0)
+ {
+ MV aboveMV = mvs[(blockX / stepSize, (blockY - stepSize) /
stepSize)];
+ int error = motionErrorLuma(orig, buffer, blockX, blockY,
aboveMV.x, aboveMV.y, blockSize, leastError);
+ if (error < leastError)
{
- for (int x2 = prevBest.x - doubleRange; x2 <=
prevBest.x + doubleRange; x2 += 4)
+ best.set(aboveMV.x, aboveMV.y);
+ leastError = error;
+ }
+ }
+ if (blockX > 0)
+ {
+ MV leftMV = mvs[((blockX - stepSize) / stepSize, blockY /
stepSize)];
+ int error = motionErrorLuma(orig, buffer, blockX, blockY,
leftMV.x, leftMV.y, blockSize, leastError);
+ if (error < leastError)
+ {
+ best.set(leftMV.x, leftMV.y);
+ leastError = error;
+ }
+ }
+
+ // calculate average
+ double avg = 0.0;
+ for (int x1 = 0; x1 < blockSize; x1++)
+ {
+ for (int y1 = 0; y1 < blockSize; y1++)
+ {
+ avg = avg + *(orig->m_picOrg[0] + (blockX + x1 +
orig->m_stride * (blockY + y1)));
+ }
+ }
+ avg = avg / (blockSize * blockSize);
+
+ // calculate variance
+ double variance = 0;
+ for (int x1 = 0; x1 < blockSize; x1++)
+ {
+ for (int y1 = 0; y1 < blockSize; y1++)
+ {
+ int pix = *(orig->m_picOrg[0] + (blockX + x1 +
orig->m_stride * (blockY + y1)));
+ variance = variance + (pix - avg) * (pix - avg);
+ }
+ }
+
+ leastError = (int)(20 * ((leastError + 5.0) / (variance +
5.0)) + (leastError / (blockSize * blockSize)) / 50);
+
+ int mvIdx = (blockY / stepSize) * mvStride + (blockX /
stepSize);
+ mvs[mvIdx] = best;
+ }
+ }
+}
+
+
+void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t
mvStride, PicYuv *orig, PicYuv *buffer, int blockSize,
+ MV *previous, uint32_t prevMvStride, int factor, int* minError)
+{
+
+ int range = 0;
+
+
+ const int stepSize = blockSize;
+
+ const int origWidth = orig->m_picWidth;
+ const int origHeight = orig->m_picHeight;
+
+
+ for (int blockY = 0; blockY + blockSize <= origHeight; blockY +=
stepSize)
+ {
+ for (int blockX = 0; blockX + blockSize <= origWidth; blockX +=
stepSize)
+ {
+ MV best(0, 0);
+ int leastError = INT_MAX;
+
+ if (previous == NULL)
+ {
+ range = 8;
+ }
+ else
+ {
+
+ for (int py = -1; py <= 1; py++)
+ {
+ int testy = blockY / (2 * blockSize) + py;
+
+ for (int px = -1; px <= 1; px++)
{
- int error = motionErrorLuma(orig, buffer, blockX,
blockY, x2, y2, blockSize, leastError);
- if (error < leastError)
+
+ int testx = blockX / (2 * blockSize) + px;
+ if ((testx >= 0) && (testx < origWidth / (2 *
blockSize)) && (testy >= 0) && (testy < origHeight / (2 * blockSize)))
{
- best.set(x2, y2);
- leastError = error;
+ int mvIdx = testy * prevMvStride + testx;
+ MV old = previous[mvIdx];
+ int error = motionErrorLuma(orig, buffer,
blockX, blockY, old.x * factor, old.y * factor, blockSize, leastError);
+ if (error < leastError)
+ {
+ best.set(old.x * factor, old.y * factor);
+ leastError = error;
+ }
}
}
}
- prevBest = best;
- doubleRange = 3;
- for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y +
doubleRange; y2++)
+ int error = motionErrorLuma(orig, buffer, blockX, blockY,
0, 0, blockSize, leastError);
+ if (error < leastError)
{
- for (int x2 = prevBest.x - doubleRange; x2 <=
prevBest.x + doubleRange; x2++)
+ best.set(0, 0);
+ leastError = error;
+ }
+
+ }
+
+ MV prevBest = best;
+ for (int y2 = prevBest.y / s_motionVectorFactor - range; y2 <=
prevBest.y / s_motionVectorFactor + range; y2++)
+ {
+ for (int x2 = prevBest.x / s_motionVectorFactor - range;
x2 <= prevBest.x / s_motionVectorFactor + range; x2++)
+ {
+ int error = motionErrorLuma(orig, buffer, blockX,
blockY, x2 * s_motionVectorFactor, y2 * s_motionVectorFactor, blockSize,
leastError);
+ if (error < leastError)
{
- int error = motionErrorLuma(orig, buffer, blockX,
blockY, x2, y2, blockSize, leastError);
- if (error < leastError)
- {
- best.set(x2, y2);
- leastError = error;
- }
+ best.set(x2 * s_motionVectorFactor, y2 *
s_motionVectorFactor);
+ leastError = error;
}
}
}
+ prevBest = best;
+ int doubleRange = 3 * 4;
+ for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y +
doubleRange; y2 += 4)
+ {
+ for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x +
doubleRange; x2 += 4)
+ {
+ int error = motionErrorLuma(orig, buffer, blockX,
blockY, x2, y2, blockSize, leastError);
+ if (error < leastError)
+ {
+ best.set(x2, y2);
+ leastError = error;
+ }
+ }
+ }
+
+ prevBest = best;
+ doubleRange = 3;
+ for (int y2 = prevBest.y - doubleRange; y2 <= prevBest.y +
doubleRange; y2++)
+ {
+ for (int x2 = prevBest.x - doubleRange; x2 <= prevBest.x +
doubleRange; x2++)
+ {
+ int error = motionErrorLuma(orig, buffer, blockX,
blockY, x2, y2, blockSize, leastError);
+ if (error < leastError)
+ {
+ best.set(x2, y2);
+ leastError = error;
+ }
+ }
+ }
+
+
if (blockY > 0)
{
MV aboveMV = mvs[(blockX / stepSize, (blockY - stepSize) /
stepSize)];
@@ -897,8 +1019,7 @@ void TemporalFilter::motionEstimationLuma(MV *mvs,
uint32_t mvStride, PicYuv *or
int mvIdx = (blockY / stepSize) * mvStride + (blockX /
stepSize);
mvs[mvIdx] = best;
- if (doubleRes)
- minError[mvIdx] = leastError;
+ minError[mvIdx] = leastError;
}
}
}
diff --git a/source/common/temporalfilter.h b/source/common/temporalfilter.h
index 14d59c396..003630994 100644
--- a/source/common/temporalfilter.h
+++ b/source/common/temporalfilter.h
@@ -161,7 +161,10 @@ public:
void bilateralFilter(Frame* frame, MCTFReferencePicInfo* mctfRefList,
double overallStrength);
void motionEstimationLuma(MV *mvs, uint32_t mvStride, PicYuv *orig,
PicYuv *buffer, int bs,
- MV *previous = 0, uint32_t prevmvStride = 0, int factor = 1, bool
doubleRes = false, int *minError = 0);
+ MV *previous = 0, uint32_t prevmvStride = 0, int factor = 1);
+
+ void TemporalFilter::motionEstimationLumaDoubleRes(MV *mvs, uint32_t
mvStride, PicYuv *orig, PicYuv *buffer, int blockSize,
+ MV *previous, uint32_t prevMvStride, int factor, int* minError);
int motionErrorLuma(PicYuv *orig,
PicYuv *buffer,
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp
index 790503d80..53094cdf1 100644
--- a/source/encoder/encoder.cpp
+++ b/source/encoder/encoder.cpp
@@ -2726,7 +2726,7 @@ int Encoder::encode(const x265_picture* pic_in,
x265_picture* pic_out)
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs0, ref->mvsStride0,
frameEnc->m_fencPicSubsampled4, ref->picBufferSubSampled4, 16);
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs1, ref->mvsStride1,
frameEnc->m_fencPicSubsampled2, ref->picBufferSubSampled2, 16, ref->mvs0,
ref->mvsStride0, 2);
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs2, ref->mvsStride2,
frameEnc->m_fencPic, ref->picBuffer, 16, ref->mvs1, ref->mvsStride1, 2);
-
curEncoder->m_frameEncTF->motionEstimationLuma(ref->mvs, ref->mvsStride,
frameEnc->m_fencPic, ref->picBuffer, 8, ref->mvs2, ref->mvsStride2, 1,
true, ref->error);
+
curEncoder->m_frameEncTF->motionEstimationLumaDoubleRes(ref->mvs,
ref->mvsStride, frameEnc->m_fencPic, ref->picBuffer, 8, ref->mvs2,
ref->mvsStride2, 1, ref->error);
}
for (int i = 0; i < frameEnc->m_mcstf->m_numRef; i++)
--
2.34.1.windows.1
*Thanks and Regards,*
*Snehaa.GVideo Codec Engineer,Media & AI analytics
<https://multicorewareinc.com/>*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20221019/a509edb9/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mcstf_patch_08.diff
Type: application/octet-stream
Size: 11152 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20221019/a509edb9/attachment-0001.obj>
More information about the x265-devel
mailing list