[x265] [PATCH] PSNR Row wise calculation
santhoshini at multicorewareinc.com
santhoshini at multicorewareinc.com
Tue Oct 15 08:56:58 CEST 2013
# HG changeset patch
# User Santhoshini Sekar <santhoshini at multicorewareinc.com>
# Date 1381817138 -19800
# Tue Oct 15 11:35:38 2013 +0530
# Node ID 957578be76da25eeab8fb0cf5eaf2a5d0471dd24
# Parent 8ae52f2b159c8378e981e369aa15c4c36db48f7c
PSNR Row wise calculation
diff -r 8ae52f2b159c -r 957578be76da source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Thu Oct 10 01:15:11 2013 -0500
+++ b/source/encoder/encoder.cpp Tue Oct 15 11:35:38 2013 +0530
@@ -362,109 +362,6 @@
// (we do not yet have a switch to disable PSNR reporting)
// 2 - it would be better to accumulate SSD of each CTU at the end of processCTU() while it is cache-hot
// in fact, we almost certainly are already measuring the CTU distortion and not accumulating it
-static UInt64 computeSSD(Pel *fenc, Pel *rec, int stride, int width, int height)
-{
- UInt64 ssd = 0;
-
- if ((width | height) & 3)
- {
- /* Slow Path */
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- int diff = (int)(fenc[x] - rec[x]);
- ssd += diff * diff;
- }
-
- fenc += stride;
- rec += stride;
- }
-
- return ssd;
- }
-
- int y = 0;
- /* Consume Y in chunks of 64 */
- for (; y + 64 <= height; y += 64)
- {
- int x = 0;
-
- if (!(stride & 31))
- for (; x + 64 <= width; x += 64)
- {
- ssd += primitives.sse_pp[PARTITION_64x64](fenc + x, stride, rec + x, stride);
- }
-
- if (!(stride & 15))
- for (; x + 16 <= width; x += 16)
- {
- ssd += primitives.sse_pp[PARTITION_16x64](fenc + x, stride, rec + x, stride);
- }
-
- for (; x + 4 <= width; x += 4)
- {
- ssd += primitives.sse_pp[PARTITION_4x64](fenc + x, stride, rec + x, stride);
- }
-
- fenc += stride * 64;
- rec += stride * 64;
- }
-
- /* Consume Y in chunks of 16 */
- for (; y + 16 <= height; y += 16)
- {
- int x = 0;
-
- if (!(stride & 31))
- for (; x + 64 <= width; x += 64)
- {
- ssd += primitives.sse_pp[PARTITION_64x16](fenc + x, stride, rec + x, stride);
- }
-
- if (!(stride & 15))
- for (; x + 16 <= width; x += 16)
- {
- ssd += primitives.sse_pp[PARTITION_16x16](fenc + x, stride, rec + x, stride);
- }
-
- for (; x + 4 <= width; x += 4)
- {
- ssd += primitives.sse_pp[PARTITION_4x16](fenc + x, stride, rec + x, stride);
- }
-
- fenc += stride * 16;
- rec += stride * 16;
- }
-
- /* Consume Y in chunks of 4 */
- for (; y + 4 <= height; y += 4)
- {
- int x = 0;
-
- if (!(stride & 31))
- for (; x + 64 <= width; x += 64)
- {
- ssd += primitives.sse_pp[PARTITION_64x4](fenc + x, stride, rec + x, stride);
- }
-
- if (!(stride & 15))
- for (; x + 16 <= width; x += 16)
- {
- ssd += primitives.sse_pp[PARTITION_16x4](fenc + x, stride, rec + x, stride);
- }
-
- for (; x + 4 <= width; x += 4)
- {
- ssd += primitives.sse_pp[PARTITION_4x4](fenc + x, stride, rec + x, stride);
- }
-
- fenc += stride * 4;
- rec += stride * 4;
- }
-
- return ssd;
-}
/**
* Produce an ascii(hex) representation of picture digest.
@@ -496,27 +393,17 @@
uint64_t Encoder::calculateHashAndPSNR(TComPic* pic, NALUnitEBSP **nalunits)
{
TComPicYuv* recon = pic->getPicYuvRec();
- TComPicYuv* orig = pic->getPicYuvOrg();
- //===== calculate PSNR =====
- int stride = recon->getStride();
int width = recon->getWidth() - getPad(0);
int height = recon->getHeight() - getPad(1);
int size = width * height;
- UInt64 ssdY = computeSSD(orig->getLumaAddr(), recon->getLumaAddr(), stride, width, height);
-
- height >>= 1;
- width >>= 1;
- stride = recon->getCStride();
-
- UInt64 ssdU = computeSSD(orig->getCbAddr(), recon->getCbAddr(), stride, width, height);
- UInt64 ssdV = computeSSD(orig->getCrAddr(), recon->getCrAddr(), stride, width, height);
-
int maxvalY = 255 << (X265_DEPTH - 8);
int maxvalC = 255 << (X265_DEPTH - 8);
double refValueY = (double)maxvalY * maxvalY * size;
double refValueC = (double)maxvalC * maxvalC * size / 4.0;
+ UInt64 ssdY,ssdU,ssdV;
+ m_frameEncoder->reportStatistics(ssdY, ssdU, ssdV);
double psnrY = (ssdY ? 10.0 * log10(refValueY / (double)ssdY) : 99.99);
double psnrU = (ssdU ? 10.0 * log10(refValueC / (double)ssdU) : 99.99);
double psnrV = (ssdV ? 10.0 * log10(refValueC / (double)ssdV) : 99.99);
diff -r 8ae52f2b159c -r 957578be76da source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Thu Oct 10 01:15:11 2013 -0500
+++ b/source/encoder/frameencoder.cpp Tue Oct 15 11:35:38 2013 +0530
@@ -1115,3 +1115,10 @@
return NULL;
}
+
+void FrameEncoder::reportStatistics(UInt64 &ssdY, UInt64 &ssdU, UInt64 &ssdV)
+{
+ ssdY = m_frameFilter.m_SSDY;
+ ssdU = m_frameFilter.m_SSDU;
+ ssdV = m_frameFilter.m_SSDV;
+}
diff -r 8ae52f2b159c -r 957578be76da source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h Thu Oct 10 01:15:11 2013 -0500
+++ b/source/encoder/frameencoder.h Tue Oct 15 11:35:38 2013 +0530
@@ -113,6 +113,8 @@
}
}
+ void reportStatistics(UInt64 &ssdY, UInt64 &ssdU, UInt64 &ssdV);
+
TEncEntropy* getEntropyCoder(int row) { return &this->m_rows[row].m_entropyCoder; }
TEncSbac* getSbacCoder(int row) { return &this->m_rows[row].m_sbacCoder; }
diff -r 8ae52f2b159c -r 957578be76da source/encoder/framefilter.cpp
--- a/source/encoder/framefilter.cpp Thu Oct 10 01:15:11 2013 -0500
+++ b/source/encoder/framefilter.cpp Tue Oct 15 11:35:38 2013 +0530
@@ -36,6 +36,9 @@
: m_cfg(NULL)
, m_pic(NULL)
{
+ m_SSDY = 0;
+ m_SSDU = 0;
+ m_SSDV = 0;
}
void FrameFilter::destroy()
@@ -86,6 +89,9 @@
m_entropyCoder.setEntropyCoder(&m_rdGoOnSbacCoder, pic->getSlice());
m_entropyCoder.setBitstream(&m_bitCounter);
m_rdGoOnBinCodersCABAC.m_fracBits = 0;
+ m_SSDY=0;
+ m_SSDU=0;
+ m_SSDV=0;
if (m_cfg->param.bEnableSAO)
{
@@ -264,6 +270,144 @@
{
m_pic->m_reconRowWait.trigger();
}
+
+ if (m_cfg->param.bEnablePsnr)
+ {
+ calculatePSNR(lineStartCUAddr, row);
+ }
+}
+
+static UInt64 computeSSD(pixel *fenc, pixel *rec, int stride, int width, int height)
+{
+ UInt64 ssd = 0;
+
+ if ((width | height) & 3)
+ {
+ /* Slow Path */
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ int diff = (int)(fenc[x] - rec[x]);
+ ssd += diff * diff;
+ }
+
+ fenc += stride;
+ rec += stride;
+ }
+
+ return ssd;
+ }
+
+ int y = 0;
+ /* Consume Y in chunks of 64 */
+ for (; y + 64 <= height; y += 64)
+ {
+ int x = 0;
+
+ if (!(stride & 31))
+ for (; x + 64 <= width; x += 64)
+ {
+ ssd += primitives.sse_pp[PARTITION_64x64](fenc + x, stride, rec + x, stride);
+ }
+
+ if (!(stride & 15))
+ for (; x + 16 <= width; x += 16)
+ {
+ ssd += primitives.sse_pp[PARTITION_16x64](fenc + x, stride, rec + x, stride);
+ }
+
+ for (; x + 4 <= width; x += 4)
+ {
+ ssd += primitives.sse_pp[PARTITION_4x64](fenc + x, stride, rec + x, stride);
+ }
+
+ fenc += stride * 64;
+ rec += stride * 64;
+ }
+
+ /* Consume Y in chunks of 16 */
+ for (; y + 16 <= height; y += 16)
+ {
+ int x = 0;
+
+ if (!(stride & 31))
+ for (; x + 64 <= width; x += 64)
+ {
+ ssd += primitives.sse_pp[PARTITION_64x16](fenc + x, stride, rec + x, stride);
+ }
+
+ if (!(stride & 15))
+ for (; x + 16 <= width; x += 16)
+ {
+ ssd += primitives.sse_pp[PARTITION_16x16](fenc + x, stride, rec + x, stride);
+ }
+
+ for (; x + 4 <= width; x += 4)
+ {
+ ssd += primitives.sse_pp[PARTITION_4x16](fenc + x, stride, rec + x, stride);
+ }
+
+ fenc += stride * 16;
+ rec += stride * 16;
+ }
+
+ /* Consume Y in chunks of 4 */
+ for (; y + 4 <= height; y += 4)
+ {
+ int x = 0;
+
+ if (!(stride & 31))
+ for (; x + 64 <= width; x += 64)
+ {
+ ssd += primitives.sse_pp[PARTITION_64x4](fenc + x, stride, rec + x, stride);
+ }
+
+ if (!(stride & 15))
+ for (; x + 16 <= width; x += 16)
+ {
+ ssd += primitives.sse_pp[PARTITION_16x4](fenc + x, stride, rec + x, stride);
+ }
+
+ for (; x + 4 <= width; x += 4)
+ {
+ ssd += primitives.sse_pp[PARTITION_4x4](fenc + x, stride, rec + x, stride);
+ }
+
+ fenc += stride * 4;
+ rec += stride * 4;
+ }
+
+ return ssd;
+}
+
+void FrameFilter::calculatePSNR(uint32_t cuAddr, int row)
+{
+ TComPicYuv* recon = m_pic->getPicYuvRec();
+ TComPicYuv* orig = m_pic->getPicYuvOrg();
+
+ //===== calculate PSNR =====
+ int stride = recon->getStride();
+
+ int width = recon->getWidth() - m_cfg->getPad(0);
+ int height;
+ if (row == m_numRows - 1)
+ height = ((recon->getHeight() % g_maxCUHeight) ? (recon->getHeight() % g_maxCUHeight) : g_maxCUHeight);
+ else
+ height = g_maxCUHeight;
+
+ UInt64 ssdY = computeSSD(orig->getLumaAddr(cuAddr), recon->getLumaAddr(cuAddr), stride, width, height);
+
+ height >>= 1;
+ width >>= 1;
+ stride = recon->getCStride();
+
+ UInt64 ssdU = computeSSD(orig->getCbAddr(cuAddr), recon->getCbAddr(cuAddr), stride, width, height);
+ UInt64 ssdV = computeSSD(orig->getCrAddr(cuAddr), recon->getCrAddr(cuAddr), stride, width, height);
+
+ m_SSDY += ssdY;
+ m_SSDU += ssdU;
+ m_SSDV += ssdV;
}
void FrameFilter::processSao(int row)
diff -r 8ae52f2b159c -r 957578be76da source/encoder/framefilter.h
--- a/source/encoder/framefilter.h Thu Oct 10 01:15:11 2013 -0500
+++ b/source/encoder/framefilter.h Tue Oct 15 11:35:38 2013 +0530
@@ -53,7 +53,7 @@
void processRow(int row);
void processRowPost(int row);
void processSao(int row);
-
+ void calculatePSNR(uint32_t cu, int row);
protected:
TEncCfg* m_cfg;
@@ -72,6 +72,9 @@
TEncBinCABACCounter m_rdGoOnBinCodersCABAC;
TComBitCounter m_bitCounter;
TEncSbac* m_rdGoOnSbacCoderRow0; // for bitstream exact only, depends on HM's bug
+ UInt64 m_SSDY;
+ UInt64 m_SSDU;
+ UInt64 m_SSDV;
};
}
More information about the x265-devel
mailing list