[x265] [PATCH] SAO: fix for output mismatch in linux
ashok at multicorewareinc.com
ashok at multicorewareinc.com
Mon Apr 18 13:04:09 CEST 2016
# HG changeset patch
# User Ashok Kumar Mishra<ashok at multicorewareinc.com>
# Date 1460973467 -19800
# Mon Apr 18 15:27:47 2016 +0530
# Node ID e038716af1b84f81e0123e75e1d016af31a0c505
# Parent 02d79be487d7f825c961d15535a8681a201da3b1
SAO: fix for output mismatch in linux
diff -r 02d79be487d7 -r e038716af1b8 source/encoder/sao.cpp
--- a/source/encoder/sao.cpp Sun Apr 17 21:07:28 2016 +0000
+++ b/source/encoder/sao.cpp Mon Apr 18 15:27:47 2016 +0530
@@ -1249,13 +1249,12 @@
m_entropyCoder.codeSaoMerge(0);
m_entropyCoder.store(m_rdContexts.temp);
- double mergeDist[NUM_MERGE_MODE] = { 0.0 };
+ // Estimate distortion and cost of new SAO params
double bestCost = 0.0;
-
- // Estimate distortion and cost of new SAO params
- saoLumaComponentParamDist(saoParam, addr, mergeDist, lambda, bestCost);
- if (chroma && saoParam->bSaoFlag[1])
- saoChromaComponentParamDist(saoParam, addr, mergeDist, lambda, bestCost);
+ double rateDist = 0.0;
+ saoLumaComponentParamDist(saoParam, addr, rateDist, lambda, bestCost);
+ if (chroma)
+ saoChromaComponentParamDist(saoParam, addr, rateDist, lambda, bestCost);
if (saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1])
{
@@ -1265,6 +1264,7 @@
if (!allowMerge[mergeIdx])
continue;
+ double mergeDist = 0;
for (int plane = 0; plane < 3; plane++)
{
int64_t estDist = 0;
@@ -1280,7 +1280,7 @@
}
}
- mergeDist[mergeIdx + 1] += ((double)estDist / lambda[!!plane]);
+ mergeDist += ((double)estDist / lambda[!!plane]);
}
m_entropyCoder.load(m_rdContexts.cur);
@@ -1290,8 +1290,8 @@
if (allowMerge[1] && (mergeIdx == 1))
m_entropyCoder.codeSaoMerge(1);
- int32_t rate = m_entropyCoder.getNumberOfWrittenBits();
- double mergeCost = mergeDist[mergeIdx + 1] + (double)rate;
+ uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();
+ double mergeCost = mergeDist + (double)estRate;
if (mergeCost < bestCost)
{
SaoMergeMode mergeMode = mergeIdx ? SAO_MERGE_UP : SAO_MERGE_LEFT;
@@ -1374,7 +1374,7 @@
}
}
-void SAO::estIterOffset(int typeIdx, double lambda, int32_t count, int32_t offsetOrg, int& offset, int& distClasses, double& costClasses)
+inline void SAO::estIterOffset(int typeIdx, double lambda, int& offset, int32_t count, int32_t offsetOrg, int& distClasses, double& costClasses)
{
int bestOffset = 0;
distClasses = 0;
@@ -1405,15 +1405,13 @@
offset = bestOffset;
}
-void SAO::saoLumaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda, double &bestCost)
+void SAO::saoLumaComponentParamDist(SAOParam* saoParam, int addr, double& rateDist, double* lambda, double &bestCost)
{
int64_t bestDist = 0;
int bestTypeIdx = -1;
SaoCtuParam* lclCtuParam = &saoParam->ctuParam[0][addr];
- int distClasses[MAX_NUM_SAO_CLASS];
- double costClasses[MAX_NUM_SAO_CLASS];
// RDO SAO_NA
m_entropyCoder.load(m_rdContexts.temp);
@@ -1423,6 +1421,8 @@
double dCostPartBest = m_entropyCoder.getNumberOfWrittenBits() * lambda[0];
//EO distortion calculation
+ int distEOClasses;
+ double costEOClasses;
for (int typeIdx = 0; typeIdx < MAX_NUM_SAO_TYPE - 1; typeIdx++)
{
int64_t estDist = 0;
@@ -1431,11 +1431,11 @@
int32_t count = m_count[0][typeIdx][classIdx];
int32_t& offsetOrg = m_offsetOrg[0][typeIdx][classIdx];
int32_t& offsetOut = m_offset[0][typeIdx][classIdx];
+ if (count)
+ estIterOffset(typeIdx, lambda[0], offsetOut, count, offsetOrg, distEOClasses, costEOClasses);
- estIterOffset(typeIdx, lambda[0], count, offsetOrg, offsetOut, distClasses[classIdx], costClasses[classIdx]);
-
- //Calculate distortion
- estDist += distClasses[classIdx];
+ estDist += estSaoDist(count, (int)offsetOut << SAO_BIT_INC, offsetOrg);
+
}
m_entropyCoder.load(m_rdContexts.temp);
@@ -1463,6 +1463,8 @@
}
//BO RDO
+ int distBOClasses[MAX_NUM_SAO_CLASS];
+ double costBOClasses[MAX_NUM_SAO_CLASS];
int64_t estDist = 0;
for (int classIdx = 0; classIdx < MAX_NUM_SAO_CLASS; classIdx++)
{
@@ -1470,7 +1472,7 @@
int32_t& offsetOrg = m_offsetOrg[0][SAO_BO][classIdx];
int32_t& offsetOut = m_offset[0][SAO_BO][classIdx];
- estIterOffset(SAO_BO, lambda[0], count, offsetOrg, offsetOut, distClasses[classIdx], costClasses[classIdx]);
+ estIterOffset(SAO_BO, lambda[0], offsetOut, count, offsetOrg, distBOClasses[classIdx], costBOClasses[classIdx]);
}
// Estimate Best Position
@@ -1481,7 +1483,7 @@
{
double currentRDCost = 0.0;
for (int j = i; j < i + SAO_NUM_OFFSET; j++)
- currentRDCost += costClasses[j];
+ currentRDCost += costBOClasses[j];
if (currentRDCost < bestRDCostBO)
{
@@ -1492,7 +1494,7 @@
estDist = 0;
for (int classIdx = bestClassBO; classIdx < bestClassBO + SAO_NUM_OFFSET; classIdx++)
- estDist += distClasses[classIdx];
+ estDist += distBOClasses[classIdx];
m_entropyCoder.load(m_rdContexts.temp);
m_entropyCoder.resetBits();
@@ -1513,33 +1515,35 @@
lclCtuParam->offset[classIdx] = (int)m_offset[0][SAO_BO][classIdx + bestClassBO];
}
- mergeDist[0] = ((double)bestDist / lambda[0]);
+ rateDist = ((double)bestDist / lambda[0]);
m_entropyCoder.load(m_rdContexts.temp);
m_entropyCoder.codeSaoOffset(*lclCtuParam, 0);
m_entropyCoder.store(m_rdContexts.temp);
- uint32_t rate = m_entropyCoder.getNumberOfWrittenBits();
- bestCost = mergeDist[0] + (double)rate;
+ if (m_param->internalCsp == X265_CSP_I400)
+ {
+ uint32_t rate = m_entropyCoder.getNumberOfWrittenBits();
+ bestCost = rateDist + (double)rate;
+ }
}
-void SAO::saoChromaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda, double &bestCost)
+void SAO::saoChromaComponentParamDist(SAOParam* saoParam, int addr, double& rateDist, double* lambda, double &bestCost)
{
int64_t bestDist = 0;
int bestTypeIdx = -1;
SaoCtuParam* lclCtuParam[2] = { &saoParam->ctuParam[1][addr], &saoParam->ctuParam[2][addr] };
- double costClasses[MAX_NUM_SAO_CLASS];
- int distClasses[MAX_NUM_SAO_CLASS];
- int bestClassBO[2] = { 0, 0 };
m_entropyCoder.load(m_rdContexts.temp);
m_entropyCoder.resetBits();
m_entropyCoder.codeSaoType(0);
- double dCostPartBest = m_entropyCoder.getNumberOfWrittenBits() * lambda[1];
+ double costPartBest = m_entropyCoder.getNumberOfWrittenBits() * lambda[1];
//EO RDO
+ double costEOClasses;
+ int distEOClasses;
for (int typeIdx = 0; typeIdx < MAX_NUM_SAO_TYPE - 1; typeIdx++)
{
int64_t estDist[2] = {0, 0};
@@ -1551,9 +1555,10 @@
int32_t& offsetOrg = m_offsetOrg[compIdx][typeIdx][classIdx];
int32_t& offsetOut = m_offset[compIdx][typeIdx][classIdx];
- estIterOffset(typeIdx, lambda[1], count, offsetOrg, offsetOut, distClasses[classIdx], costClasses[classIdx]);
+ if (count)
+ estIterOffset(typeIdx, lambda[1], offsetOut, count, offsetOrg, distEOClasses, costEOClasses);
- estDist[compIdx - 1] += distClasses[classIdx];
+ estDist[compIdx - 1] += estSaoDist(count, (int)offsetOut << SAO_BIT_INC, offsetOrg);
}
}
@@ -1566,9 +1571,9 @@
uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();
double cost = (double)(estDist[0] + estDist[1]) + lambda[1] * (double)estRate;
- if (cost < dCostPartBest)
+ if (cost < costPartBest)
{
- dCostPartBest = cost;
+ costPartBest = cost;
bestDist = (estDist[0] + estDist[1]);
bestTypeIdx = typeIdx;
}
@@ -1587,6 +1592,9 @@
}
// BO RDO
+ double costBOClasses[MAX_NUM_SAO_CLASS];
+ int distBOClasses[MAX_NUM_SAO_CLASS];
+ int bestClassBO[2] = { 0, 0 };
int64_t estDist[2];
// Estimate Best Position
@@ -1600,14 +1608,14 @@
int32_t& offsetOrg = m_offsetOrg[compIdx][SAO_BO][classIdx];
int32_t& offsetOut = m_offset[compIdx][SAO_BO][classIdx];
- estIterOffset(SAO_BO, lambda[1], count, offsetOrg, offsetOut, distClasses[classIdx], costClasses[classIdx]);
+ estIterOffset(SAO_BO, lambda[1], offsetOut, count, offsetOrg, distBOClasses[classIdx], costBOClasses[classIdx]);
}
for (int i = 0; i < MAX_NUM_SAO_CLASS - SAO_NUM_OFFSET + 1; i++)
{
double currentRDCost = 0.0;
for (int j = i; j < i + SAO_NUM_OFFSET; j++)
- currentRDCost += costClasses[j];
+ currentRDCost += costBOClasses[j];
if (currentRDCost < bestRDCostBO)
{
@@ -1618,7 +1626,7 @@
estDist[compIdx - 1] = 0;
for (int classIdx = bestClassBO[compIdx - 1]; classIdx < bestClassBO[compIdx - 1] + SAO_NUM_OFFSET; classIdx++)
- estDist[compIdx - 1] += distClasses[classIdx];
+ estDist[compIdx - 1] += distBOClasses[classIdx];
}
m_entropyCoder.load(m_rdContexts.temp);
@@ -1630,9 +1638,9 @@
uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();
double cost = (double)(estDist[0] + estDist[1]) + lambda[1] * (double)estRate;
- if (cost < dCostPartBest)
+ if (cost < costPartBest)
{
- dCostPartBest = cost;
+ costPartBest = cost;
bestDist = (estDist[0] + estDist[1]);
for (int compIdx = 0; compIdx < 2; compIdx++)
@@ -1645,15 +1653,20 @@
}
}
- mergeDist[0] += ((double)bestDist / lambda[1]);
+ rateDist += ((double)bestDist / lambda[1]);
m_entropyCoder.load(m_rdContexts.temp);
+ uint32_t rate = m_entropyCoder.getNumberOfWrittenBits();
+ if (saoParam->bSaoFlag[1])
+ {
+ m_entropyCoder.codeSaoOffset(*lclCtuParam[0], 1);
+ m_entropyCoder.codeSaoOffset(*lclCtuParam[1], 2);
+ m_entropyCoder.store(m_rdContexts.temp);
- m_entropyCoder.codeSaoOffset(*lclCtuParam[0], 1);
- m_entropyCoder.codeSaoOffset(*lclCtuParam[1], 2);
- m_entropyCoder.store(m_rdContexts.temp);
-
- uint32_t rate = m_entropyCoder.getNumberOfWrittenBits();
- bestCost = mergeDist[0] + (double)rate;
+ rate = m_entropyCoder.getNumberOfWrittenBits();
+ bestCost = rateDist + (double)rate;
+ }
+ else
+ bestCost = rateDist + (double)rate;
}
// NOTE: must put in namespace X265_NS since we need class SAO
diff -r 02d79be487d7 -r e038716af1b8 source/encoder/sao.h
--- a/source/encoder/sao.h Sun Apr 17 21:07:28 2016 +0000
+++ b/source/encoder/sao.h Mon Apr 18 15:27:47 2016 +0530
@@ -46,7 +46,6 @@
class SAO
{
public:
-
enum { SAO_MAX_DEPTH = 4 };
enum { SAO_BO_BITS = 5 };
enum { MAX_NUM_SAO_CLASS = 32 };
@@ -54,7 +53,6 @@
enum { OFFSET_THRESH = 1 << X265_MIN(X265_DEPTH - 5, 5) };
enum { NUM_EDGETYPE = 5 };
enum { NUM_PLANE = 3 };
- enum { NUM_MERGE_MODE = 3 };
enum { SAO_DEPTHRATE_SIZE = 4 };
static const uint32_t s_eoTable[NUM_EDGETYPE];
@@ -127,10 +125,11 @@
void calcSaoStatsCu(int addr, int plane);
void calcSaoStatsCu_BeforeDblk(Frame* pic, int idxX, int idxY);
- void saoLumaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda, double &bestCost);
- void saoChromaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda, double &bestCost);
+ void saoLumaComponentParamDist(SAOParam* saoParam, int addr, double& rateDist, double* lambda, double &bestCost);
+ void saoChromaComponentParamDist(SAOParam* saoParam, int addr, double& rateDist, double* lambda, double &bestCost);
- void estIterOffset(int typeIdx, double lambda, int32_t count, int32_t offsetOrg, int& offset, int& distClasses, double& costClasses);
+ void estIterOffset(int typeIdx, double lambda, int& offset, int32_t count, int32_t offsetOrg,
+ int& distClasses, double& costClasses);
void rdoSaoUnitRowEnd(const SAOParam* saoParam, int numctus);
void rdoSaoUnitCu(SAOParam* saoParam, int rowBaseAddr, int idxX, int addr);
More information about the x265-devel
mailing list