[x265] [PATCH] framepp: fix bug with '--sao-lcu-bounds 1' and move part of sao into compress loop
Min Chen
chenm003 at 163.com
Fri Aug 16 14:16:06 CEST 2013
# HG changeset patch
# User Min Chen <chenm003 at 163.com>
# Date 1376655357 -28800
# Node ID fd7740c9441317b47fd8f986d3bf29f1e411bc8f
# Parent c2f5275ecb4986da2a1116dd7445cc2536fa19fd
framepp: fix bug with '--sao-lcu-bounds 1' and move part of sao into compress loop
diff -r c2f5275ecb49 -r fd7740c94413 source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp
--- a/source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp Fri Aug 16 07:02:26 2013 -0500
+++ b/source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp Fri Aug 16 20:15:57 2013 +0800
@@ -119,7 +119,7 @@
/** convert Level Row Col to Idx
* \param level, row, col
*/
-Int TComSampleAdaptiveOffset::convertLevelRowCol2Idx(Int level, Int row, Int col)
+Int TComSampleAdaptiveOffset::convertLevelRowCol2Idx(Int level, Int row, Int col) const
{
Int idx;
@@ -336,7 +336,7 @@
/** allocate memory for SAO parameters
* \param *saoParam
*/
-Void TComSampleAdaptiveOffset::allocSaoParam(SAOParam *saoParam)
+Void TComSampleAdaptiveOffset::allocSaoParam(SAOParam *saoParam) const
{
saoParam->maxSplitLevel = m_maxSplitLevel;
saoParam->saoPart[0] = new SAOQTPart[m_numCulPartsLevel[saoParam->maxSplitLevel]];
@@ -355,7 +355,7 @@
/** initialize SAO parameters
* \param *saoParam, iPartLevel, iPartRow, iPartCol, iParentPartIdx, StartCUX, EndCUX, StartCUY, EndCUY, yCbCr
*/
-Void TComSampleAdaptiveOffset::initSAOParam(SAOParam *saoParam, Int partLevel, Int partRow, Int partCol, Int parentPartIdx, Int startCUX, Int endCUX, Int startCUY, Int endCUY, Int yCbCr)
+Void TComSampleAdaptiveOffset::initSAOParam(SAOParam *saoParam, Int partLevel, Int partRow, Int partCol, Int parentPartIdx, Int startCUX, Int endCUX, Int startCUY, Int endCUY, Int yCbCr) const
{
Int j;
Int partIdx = convertLevelRowCol2Idx(partLevel, partRow, partCol);
diff -r c2f5275ecb49 -r fd7740c94413 source/Lib/TLibCommon/TComSampleAdaptiveOffset.h
--- a/source/Lib/TLibCommon/TComSampleAdaptiveOffset.h Fri Aug 16 07:02:26 2013 -0500
+++ b/source/Lib/TLibCommon/TComSampleAdaptiveOffset.h Fri Aug 16 20:15:57 2013 +0800
@@ -186,10 +186,10 @@
Void create(UInt sourceWidth, UInt sourceHeight, UInt maxCUWidth, UInt maxCUHeight);
Void destroy();
- Int convertLevelRowCol2Idx(Int level, Int row, Int col);
+ Int convertLevelRowCol2Idx(Int level, Int row, Int col) const;
- Void initSAOParam(SAOParam* saoParam, Int partLevel, Int partRow, Int partCol, Int parentPartIdx, Int startCUX, Int endCUX, Int startCUY, Int endCUY, Int yCbCr);
- Void allocSaoParam(SAOParam* saoParam);
+ Void initSAOParam(SAOParam* saoParam, Int partLevel, Int partRow, Int partCol, Int parentPartIdx, Int startCUX, Int endCUX, Int startCUY, Int endCUY, Int yCbCr) const;
+ Void allocSaoParam(SAOParam* saoParam) const;
Void resetSAOParam(SAOParam* saoParam);
static Void freeSaoParam(SAOParam* saoParam);
diff -r c2f5275ecb49 -r fd7740c94413 source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp
--- a/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp Fri Aug 16 07:02:26 2013 -0500
+++ b/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp Fri Aug 16 20:15:57 2013 +0800
@@ -73,6 +73,12 @@
{}
// ====================================================================================================================
+// Static
+// ====================================================================================================================
+Int64 ****TEncSampleAdaptiveOffset::m_countPreDblk = NULL;
+Int64 ****TEncSampleAdaptiveOffset::m_offsetOrgPreDblk = NULL;
+
+// ====================================================================================================================
// Constants
// ====================================================================================================================
@@ -466,53 +472,56 @@
}
Int numLcu = m_numCuInWidth * m_numCuInHeight;
- for (Int i = 0; i < numLcu; i++)
+ if (m_countPreDblk)
{
- for (Int j = 0; j < 3; j++)
+ for (Int i = 0; i < numLcu; i++)
{
- for (Int k = 0; k < MAX_NUM_SAO_TYPE; k++)
+ for (Int j = 0; j < 3; j++)
{
- if (m_countPreDblk[i][j][k])
+ for (Int k = 0; k < MAX_NUM_SAO_TYPE; k++)
{
- delete [] m_countPreDblk[i][j][k];
+ if (m_countPreDblk[i][j][k])
+ {
+ delete [] m_countPreDblk[i][j][k];
+ }
+ if (m_offsetOrgPreDblk[i][j][k])
+ {
+ delete [] m_offsetOrgPreDblk[i][j][k];
+ }
}
- if (m_offsetOrgPreDblk[i][j][k])
+
+ if (m_countPreDblk[i][j])
{
- delete [] m_offsetOrgPreDblk[i][j][k];
+ delete [] m_countPreDblk[i][j];
+ }
+ if (m_offsetOrgPreDblk[i][j])
+ {
+ delete [] m_offsetOrgPreDblk[i][j];
}
}
- if (m_countPreDblk[i][j])
+ if (m_countPreDblk[i])
{
- delete [] m_countPreDblk[i][j];
+ delete [] m_countPreDblk[i];
}
- if (m_offsetOrgPreDblk[i][j])
+ if (m_offsetOrgPreDblk[i])
{
- delete [] m_offsetOrgPreDblk[i][j];
+ delete [] m_offsetOrgPreDblk[i];
}
}
- if (m_countPreDblk[i])
+ if (m_countPreDblk)
{
- delete [] m_countPreDblk[i];
+ delete [] m_countPreDblk;
+ m_countPreDblk = NULL;
}
- if (m_offsetOrgPreDblk[i])
+ if (m_offsetOrgPreDblk)
{
- delete [] m_offsetOrgPreDblk[i];
+ delete [] m_offsetOrgPreDblk;
+ m_offsetOrgPreDblk = NULL;
}
}
- if (m_countPreDblk)
- {
- delete [] m_countPreDblk;
- m_countPreDblk = NULL;
- }
- if (m_offsetOrgPreDblk)
- {
- delete [] m_offsetOrgPreDblk;
- m_offsetOrgPreDblk = NULL;
- }
-
Int maxDepth = 4;
Int depth;
for (depth = 0; depth < maxDepth + 1; depth++)
@@ -570,22 +579,27 @@
}
Int numLcu = m_numCuInWidth * m_numCuInHeight;
- m_countPreDblk = new Int64 * **[numLcu];
- m_offsetOrgPreDblk = new Int64 * **[numLcu];
- for (Int i = 0; i < numLcu; i++)
+ if (m_countPreDblk == NULL)
{
- m_countPreDblk[i] = new Int64 * *[3];
- m_offsetOrgPreDblk[i] = new Int64 * *[3];
+ assert(m_offsetOrgPreDblk == NULL);
- for (Int j = 0; j < 3; j++)
+ m_countPreDblk = new Int64 * **[numLcu];
+ m_offsetOrgPreDblk = new Int64 * **[numLcu];
+ for (Int i = 0; i < numLcu; i++)
{
- m_countPreDblk[i][j] = new Int64 *[MAX_NUM_SAO_TYPE];
- m_offsetOrgPreDblk[i][j] = new Int64 *[MAX_NUM_SAO_TYPE];
+ m_countPreDblk[i] = new Int64 * *[3];
+ m_offsetOrgPreDblk[i] = new Int64 * *[3];
- for (Int k = 0; k < MAX_NUM_SAO_TYPE; k++)
+ for (Int j = 0; j < 3; j++)
{
- m_countPreDblk[i][j][k] = new Int64[MAX_NUM_SAO_CLASS];
- m_offsetOrgPreDblk[i][j][k] = new Int64[MAX_NUM_SAO_CLASS];
+ m_countPreDblk[i][j] = new Int64 *[MAX_NUM_SAO_TYPE];
+ m_offsetOrgPreDblk[i][j] = new Int64 *[MAX_NUM_SAO_TYPE];
+
+ for (Int k = 0; k < MAX_NUM_SAO_TYPE; k++)
+ {
+ m_countPreDblk[i][j][k] = new Int64[MAX_NUM_SAO_CLASS];
+ m_offsetOrgPreDblk[i][j][k] = new Int64[MAX_NUM_SAO_CLASS];
+ }
}
}
}
@@ -1488,6 +1502,307 @@
}
}
+Void TEncSampleAdaptiveOffset::calcSaoStatsLCu_BeforeDblk(TComPic* pic, Int addr)
+{
+ Int yCbCr;
+ Int x, y;
+ TComSPS *pTmpSPS = pic->getSlice()->getSPS();
+
+ Pel* fenc;
+ Pel* pRec;
+ Int stride;
+ Int lcuHeight = pTmpSPS->getMaxCUHeight();
+ Int lcuWidth = pTmpSPS->getMaxCUWidth();
+ UInt rPelX;
+ UInt bPelY;
+ Int64* stats;
+ Int64* count;
+ Int classIdx;
+ Int picWidthTmp = 0;
+ Int picHeightTmp = 0;
+ Int startX;
+ Int startY;
+ Int endX;
+ Int endY;
+ Int firstX, firstY;
+
+ Int j, k;
+
+ Int isChroma;
+ Int numSkipLine, numSkipLineRight;
+
+ UInt lPelX, tPelY;
+ TComDataCU *pTmpCu;
+ Pel* pTableBo;
+
+ lcuHeight = pTmpSPS->getMaxCUHeight();
+ lcuWidth = pTmpSPS->getMaxCUWidth();
+ pTmpCu = pic->getCU(addr);
+ lPelX = pTmpCu->getCUPelX();
+ tPelY = pTmpCu->getCUPelY();
+ for (yCbCr = 0; yCbCr < 3; yCbCr++)
+ {
+ isChroma = (yCbCr != 0) ? 1 : 0;
+
+ for (j = 0; j < MAX_NUM_SAO_TYPE; j++)
+ {
+ for (k = 0; k < MAX_NUM_SAO_CLASS; k++)
+ {
+ TEncSampleAdaptiveOffset::m_countPreDblk[addr][yCbCr][j][k] = 0;
+ TEncSampleAdaptiveOffset::m_offsetOrgPreDblk[addr][yCbCr][j][k] = 0;
+ }
+ }
+
+ if (yCbCr == 0)
+ {
+ picWidthTmp = m_picWidth;
+ picHeightTmp = m_picHeight;
+ }
+ else if (yCbCr == 1)
+ {
+ picWidthTmp = m_picWidth >> isChroma;
+ picHeightTmp = m_picHeight >> isChroma;
+ lcuWidth = lcuWidth >> isChroma;
+ lcuHeight = lcuHeight >> isChroma;
+ lPelX = lPelX >> isChroma;
+ tPelY = tPelY >> isChroma;
+ }
+ rPelX = lPelX + lcuWidth;
+ bPelY = tPelY + lcuHeight;
+ rPelX = rPelX > picWidthTmp ? picWidthTmp : rPelX;
+ bPelY = bPelY > picHeightTmp ? picHeightTmp : bPelY;
+ lcuWidth = rPelX - lPelX;
+ lcuHeight = bPelY - tPelY;
+
+ stride = (yCbCr == 0) ? pic->getStride() : pic->getCStride();
+ pTableBo = (yCbCr == 0) ? m_lumaTableBo : m_chromaTableBo;
+
+ //if(iSaoType == BO)
+
+ numSkipLine = isChroma ? 1 : 3;
+ numSkipLineRight = isChroma ? 2 : 4;
+
+ stats = TEncSampleAdaptiveOffset::m_offsetOrgPreDblk[addr][yCbCr][SAO_BO];
+ count = TEncSampleAdaptiveOffset::m_countPreDblk[addr][yCbCr][SAO_BO];
+
+ fenc = getPicYuvAddr(pic->getPicYuvOrg(), yCbCr, addr);
+ pRec = getPicYuvAddr(pic->getPicYuvRec(), yCbCr, addr);
+
+ startX = (rPelX == picWidthTmp) ? lcuWidth : lcuWidth - numSkipLineRight;
+ startY = (bPelY == picHeightTmp) ? lcuHeight : lcuHeight - numSkipLine;
+
+ for (y = 0; y < lcuHeight; y++)
+ {
+ for (x = 0; x < lcuWidth; x++)
+ {
+ if (x < startX && y < startY)
+ continue;
+
+ classIdx = pTableBo[pRec[x]];
+ if (classIdx)
+ {
+ stats[classIdx] += (fenc[x] - pRec[x]);
+ count[classIdx]++;
+ }
+ }
+
+ fenc += stride;
+ pRec += stride;
+ }
+
+ Int signLeft;
+ Int signRight;
+ Int signDown;
+ Int signDown1;
+ Int signDown2;
+
+ UInt uiEdgeType;
+
+ //if (iSaoType == EO_0)
+
+ numSkipLine = isChroma ? 1 : 3;
+ numSkipLineRight = isChroma ? 3 : 5;
+
+ stats = TEncSampleAdaptiveOffset::m_offsetOrgPreDblk[addr][yCbCr][SAO_EO_0];
+ count = TEncSampleAdaptiveOffset::m_countPreDblk[addr][yCbCr][SAO_EO_0];
+
+ fenc = getPicYuvAddr(pic->getPicYuvOrg(), yCbCr, addr);
+ pRec = getPicYuvAddr(pic->getPicYuvRec(), yCbCr, addr);
+
+ startX = (rPelX == picWidthTmp) ? lcuWidth - 1 : lcuWidth - numSkipLineRight;
+ startY = (bPelY == picHeightTmp) ? lcuHeight : lcuHeight - numSkipLine;
+ firstX = (lPelX == 0) ? 1 : 0;
+ endX = (rPelX == picWidthTmp) ? lcuWidth - 1 : lcuWidth;
+
+ for (y = 0; y < lcuHeight; y++)
+ {
+ signLeft = xSign(pRec[firstX] - pRec[firstX - 1]);
+ for (x = firstX; x < endX; x++)
+ {
+ signRight = xSign(pRec[x] - pRec[x + 1]);
+ uiEdgeType = signRight + signLeft + 2;
+ signLeft = -signRight;
+
+ if (x < startX && y < startY)
+ continue;
+
+ stats[m_eoTable[uiEdgeType]] += (fenc[x] - pRec[x]);
+ count[m_eoTable[uiEdgeType]]++;
+ }
+
+ fenc += stride;
+ pRec += stride;
+ }
+
+ //if (iSaoType == EO_1)
+
+ numSkipLine = isChroma ? 2 : 4;
+ numSkipLineRight = isChroma ? 2 : 4;
+
+ stats = TEncSampleAdaptiveOffset::m_offsetOrgPreDblk[addr][yCbCr][SAO_EO_1];
+ count = TEncSampleAdaptiveOffset::m_countPreDblk[addr][yCbCr][SAO_EO_1];
+
+ fenc = getPicYuvAddr(pic->getPicYuvOrg(), yCbCr, addr);
+ pRec = getPicYuvAddr(pic->getPicYuvRec(), yCbCr, addr);
+
+ startX = (rPelX == picWidthTmp) ? lcuWidth : lcuWidth - numSkipLineRight;
+ startY = (bPelY == picHeightTmp) ? lcuHeight - 1 : lcuHeight - numSkipLine;
+ firstY = (tPelY == 0) ? 1 : 0;
+ endY = (bPelY == picHeightTmp) ? lcuHeight - 1 : lcuHeight;
+ if (firstY == 1)
+ {
+ fenc += stride;
+ pRec += stride;
+ }
+
+ for (x = 0; x < lcuWidth; x++)
+ {
+ m_upBuff1[x] = xSign(pRec[x] - pRec[x - stride]);
+ }
+
+ for (y = firstY; y < endY; y++)
+ {
+ for (x = 0; x < lcuWidth; x++)
+ {
+ signDown = xSign(pRec[x] - pRec[x + stride]);
+ uiEdgeType = signDown + m_upBuff1[x] + 2;
+ m_upBuff1[x] = -signDown;
+
+ if (x < startX && y < startY)
+ continue;
+
+ stats[m_eoTable[uiEdgeType]] += (fenc[x] - pRec[x]);
+ count[m_eoTable[uiEdgeType]]++;
+ }
+
+ fenc += stride;
+ pRec += stride;
+ }
+
+ //if (iSaoType == EO_2)
+
+ numSkipLine = isChroma ? 2 : 4;
+ numSkipLineRight = isChroma ? 3 : 5;
+
+ stats = TEncSampleAdaptiveOffset::m_offsetOrgPreDblk[addr][yCbCr][SAO_EO_2];
+ count = TEncSampleAdaptiveOffset::m_countPreDblk[addr][yCbCr][SAO_EO_2];
+
+ fenc = getPicYuvAddr(pic->getPicYuvOrg(), yCbCr, addr);
+ pRec = getPicYuvAddr(pic->getPicYuvRec(), yCbCr, addr);
+
+ startX = (rPelX == picWidthTmp) ? lcuWidth - 1 : lcuWidth - numSkipLineRight;
+ startY = (bPelY == picHeightTmp) ? lcuHeight - 1 : lcuHeight - numSkipLine;
+ firstX = (lPelX == 0) ? 1 : 0;
+ firstY = (tPelY == 0) ? 1 : 0;
+ endX = (rPelX == picWidthTmp) ? lcuWidth - 1 : lcuWidth;
+ endY = (bPelY == picHeightTmp) ? lcuHeight - 1 : lcuHeight;
+ if (firstY == 1)
+ {
+ fenc += stride;
+ pRec += stride;
+ }
+
+ for (x = firstX; x < endX; x++)
+ {
+ m_upBuff1[x] = xSign(pRec[x] - pRec[x - stride - 1]);
+ }
+
+ for (y = firstY; y < endY; y++)
+ {
+ signDown2 = xSign(pRec[stride + startX] - pRec[startX - 1]);
+ for (x = firstX; x < endX; x++)
+ {
+ signDown1 = xSign(pRec[x] - pRec[x + stride + 1]);
+ uiEdgeType = signDown1 + m_upBuff1[x] + 2;
+ m_upBufft[x + 1] = -signDown1;
+
+ if (x < startX && y < startY)
+ continue;
+
+ stats[m_eoTable[uiEdgeType]] += (fenc[x] - pRec[x]);
+ count[m_eoTable[uiEdgeType]]++;
+ }
+
+ m_upBufft[firstX] = signDown2;
+ m_swap = m_upBuff1;
+ m_upBuff1 = m_upBufft;
+ m_upBufft = m_swap;
+
+ pRec += stride;
+ fenc += stride;
+ }
+
+ //if (iSaoType == EO_3)
+
+ numSkipLine = isChroma ? 2 : 4;
+ numSkipLineRight = isChroma ? 3 : 5;
+
+ stats = TEncSampleAdaptiveOffset::m_offsetOrgPreDblk[addr][yCbCr][SAO_EO_3];
+ count = TEncSampleAdaptiveOffset::m_countPreDblk[addr][yCbCr][SAO_EO_3];
+
+ fenc = getPicYuvAddr(pic->getPicYuvOrg(), yCbCr, addr);
+ pRec = getPicYuvAddr(pic->getPicYuvRec(), yCbCr, addr);
+
+ startX = (rPelX == picWidthTmp) ? lcuWidth - 1 : lcuWidth - numSkipLineRight;
+ startY = (bPelY == picHeightTmp) ? lcuHeight - 1 : lcuHeight - numSkipLine;
+ firstX = (lPelX == 0) ? 1 : 0;
+ firstY = (tPelY == 0) ? 1 : 0;
+ endX = (rPelX == picWidthTmp) ? lcuWidth - 1 : lcuWidth;
+ endY = (bPelY == picHeightTmp) ? lcuHeight - 1 : lcuHeight;
+ if (firstY == 1)
+ {
+ fenc += stride;
+ pRec += stride;
+ }
+
+ for (x = firstX - 1; x < endX; x++)
+ {
+ m_upBuff1[x] = xSign(pRec[x] - pRec[x - stride + 1]);
+ }
+
+ for (y = firstY; y < endY; y++)
+ {
+ for (x = firstX; x < endX; x++)
+ {
+ signDown1 = xSign(pRec[x] - pRec[x + stride - 1]);
+ uiEdgeType = signDown1 + m_upBuff1[x] + 2;
+ m_upBuff1[x - 1] = -signDown1;
+
+ if (x < startX && y < startY)
+ continue;
+
+ stats[m_eoTable[uiEdgeType]] += (fenc[x] - pRec[x]);
+ count[m_eoTable[uiEdgeType]]++;
+ }
+
+ m_upBuff1[endX - 1] = xSign(pRec[endX - 1 + stride] - pRec[endX]);
+
+ pRec += stride;
+ fenc += stride;
+ }
+ }
+}
+
/** get SAO statistics
* \param *psQTPart, yCbCr
*/
@@ -1834,8 +2149,8 @@
m_offset[compIdx][j][k] = 0;
if (m_saoLcuBasedOptimization && m_saoLcuBoundary)
{
- m_count[compIdx][j][k] = m_countPreDblk[addr][compIdx][j][k];
- m_offsetOrg[compIdx][j][k] = m_offsetOrgPreDblk[addr][compIdx][j][k];
+ m_count[compIdx][j][k] = TEncSampleAdaptiveOffset::m_countPreDblk[addr][compIdx][j][k];
+ m_offsetOrg[compIdx][j][k] = TEncSampleAdaptiveOffset::m_offsetOrgPreDblk[addr][compIdx][j][k];
}
else
{
diff -r c2f5275ecb49 -r fd7740c94413 source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h
--- a/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h Fri Aug 16 07:02:26 2013 -0500
+++ b/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h Fri Aug 16 20:15:57 2013 +0800
@@ -65,8 +65,8 @@
Int64 ***m_count; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS];
Int64 ***m_offset; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS];
Int64 ***m_offsetOrg; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE];
- Int64 ****m_countPreDblk; //[LCU][YCbCr][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS];
- Int64 ****m_offsetOrgPreDblk; //[LCU][YCbCr][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS];
+ static Int64 ****m_countPreDblk; //[LCU][YCbCr][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS];
+ static Int64 ****m_offsetOrgPreDblk; //[LCU][YCbCr][MAX_NUM_SAO_TYPE][MAX_NUM_SAO_CLASS];
Int64 **m_rate; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE];
Int64 **m_dist; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE];
Double **m_cost; //[MAX_NUM_SAO_PART][MAX_NUM_SAO_TYPE];
@@ -96,6 +96,7 @@
Void calcSaoStatsBlock(Pel* recStart, Pel* orgStart, Int stride, Int64** stats, Int64** counts, UInt width, UInt height, Bool* bBorderAvail, Int yCbCr);
Void calcSaoStatsCuOrg(Int addr, Int partIdx, Int yCbCr);
Void calcSaoStatsCu_BeforeDblk(TComPic* pic);
+ Void calcSaoStatsLCu_BeforeDblk(TComPic* pic, Int addr);
Void destroyEncBuffer();
Void createEncBuffer();
Void assignSaoUnitSyntax(SaoLcuParam* saoLcuParam, SAOQTPart* saoPart, Bool &oneUnitFlag);
diff -r c2f5275ecb49 -r fd7740c94413 source/Lib/TLibEncoder/TEncTop.cpp
--- a/source/Lib/TLibEncoder/TEncTop.cpp Fri Aug 16 07:02:26 2013 -0500
+++ b/source/Lib/TLibEncoder/TEncTop.cpp Fri Aug 16 20:15:57 2013 +0800
@@ -167,6 +167,7 @@
if (param.bEnableSAO)
{
// TODO: these should be allocated on demand within the encoder
+ // NOTE: the SAO pointer from m_frameEncoder for read m_maxSplitLevel, etc, we can remove it later
pic->getPicSym()->allocSaoParam(m_frameEncoder->getSAO());
}
pic->getSlice()->setPOC(MAX_INT);
diff -r c2f5275ecb49 -r fd7740c94413 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Fri Aug 16 07:02:26 2013 -0500
+++ b/source/encoder/frameencoder.cpp Fri Aug 16 20:15:57 2013 +0800
@@ -71,11 +71,6 @@
delete[] m_rows;
}
- if (m_cfg->param.bEnableSAO)
- {
- m_sao.destroy();
- m_sao.destroyEncBuffer();
- }
m_frameFilter.destroy();
}
@@ -85,14 +80,6 @@
m_cfg = top;
m_numRows = numRows;
- if (m_cfg->param.bEnableSAO)
- {
- m_sao.setSaoLcuBoundary(m_cfg->param.saoLcuBoundary);
- m_sao.setSaoLcuBasedOptimization(m_cfg->param.saoLcuBasedOptimization);
- m_sao.setMaxNumOffsetsPerPic(m_cfg->getMaxNumOffsetsPerPic());
- m_sao.create(m_cfg->param.sourceWidth, m_cfg->param.sourceHeight, g_maxCUWidth, g_maxCUHeight);
- m_sao.createEncBuffer();
- }
m_frameFilter.init(top, numRows);
m_rows = new CTURow[m_numRows];
@@ -467,6 +454,11 @@
cntIntraNxN = 0;
#endif // if CU_STAT_LOGFILE
+ if (m_sps.getUseSAO())
+ {
+ pic->createNonDBFilterInfo(slice->getSliceCurEndCUAddr(), 0);
+ }
+
// Analyze CTU rows, most of the hard work is done here
// frame is compressed in a wave-front pattern if WPP is enabled. Loop filter runs as a
// wave-front behind the CU compression and reconstruction
@@ -491,13 +483,6 @@
}
#endif // if LOGGING
- // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
- if (m_cfg->param.saoLcuBasedOptimization && m_cfg->param.saoLcuBoundary)
- {
- m_sao.resetStats();
- m_sao.calcSaoStatsCu_BeforeDblk(pic);
- }
-
// wait for loop filter completion
if (m_cfg->param.bEnableLoopFilter)
{
@@ -505,12 +490,6 @@
m_frameFilter.dequeue();
}
- if (m_sps.getUseSAO())
- {
- pic->createNonDBFilterInfo(slice->getSliceCurEndCUAddr(), 0);
- m_sao.createPicSaoInfo(pic);
- }
-
if (m_cfg->param.bEnableWavefront)
{
slice->setNextSlice(true);
@@ -556,11 +535,11 @@
entropyCoder->setBitstream(&m_bitCounter);
// CHECK_ME: I think the SAO uses a temp Sbac only, so I always use [0], am I right?
- m_sao.startSaoEnc(pic, entropyCoder, getRDGoOnSbacCoder(0));
+ getSAO()->startSaoEnc(pic, entropyCoder, getRDGoOnSbacCoder(0));
SAOParam* saoParam = pic->getPicSym()->getSaoParam();
- m_sao.SAOProcess(saoParam, slice->getLambdaLuma(), slice->getLambdaChroma(), slice->getDepth());
- m_sao.endSaoEnc();
+ getSAO()->SAOProcess(saoParam, slice->getLambdaLuma(), slice->getLambdaChroma(), slice->getDepth());
+ getSAO()->endSaoEnc();
PCMLFDisableProcess(pic);
slice->setSaoEnabledFlag((saoParam->bSaoFlag[0] == 1) ? true : false);
@@ -686,7 +665,7 @@
if (m_sps.getUseSAO())
{
- m_sao.destroyPicSaoInfo();
+ m_frameFilter.end();
pic->destroyNonDBFilterInfo();
}
pic->compressMotion();
diff -r c2f5275ecb49 -r fd7740c94413 source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h Fri Aug 16 07:02:26 2013 -0500
+++ b/source/encoder/frameencoder.h Fri Aug 16 20:15:57 2013 +0800
@@ -136,7 +136,7 @@
/* Frame singletons, last the life of the encoder */
TEncSbac* getSingletonSbac() { return &m_sbacCoder; }
- TEncSampleAdaptiveOffset* getSAO() { return &m_sao; }
+ TEncSampleAdaptiveOffset* getSAO() { return &m_frameFilter.m_sao[0]; }
TEncCavlc* getCavlcCoder() { return &m_cavlcCoder; }
@@ -187,7 +187,6 @@
TEncBinCABAC m_binCoderCABAC;
TEncCavlc m_cavlcCoder;
FrameFilter m_frameFilter;
- TEncSampleAdaptiveOffset m_sao;
TComBitCounter m_bitCounter;
TComPic* m_pic;
diff -r c2f5275ecb49 -r fd7740c94413 source/encoder/framefilter.cpp
--- a/source/encoder/framefilter.cpp Fri Aug 16 07:02:26 2013 -0500
+++ b/source/encoder/framefilter.cpp Fri Aug 16 20:15:57 2013 +0800
@@ -40,6 +40,7 @@
, m_rows_active(NULL)
, m_locks(NULL)
, m_loopFilter(NULL)
+ , m_sao(NULL)
{}
void FrameFilter::destroy()
@@ -63,12 +64,17 @@
if (m_cfg->param.bEnableLoopFilter)
{
+ assert(m_cfg->param.bEnableSAO);
for (int i = 0; i < m_numRows; ++i)
{
m_loopFilter[i].destroy();
+ // NOTE: I don't check sao flag since loopfilter and sao have same control status
+ m_sao[i].destroy();
+ m_sao[i].destroyEncBuffer();
}
delete[] m_loopFilter;
+ delete[] m_sao;
}
}
@@ -84,9 +90,15 @@
if (top->param.bEnableLoopFilter)
{
m_loopFilter = new TComLoopFilter[numRows];
+ m_sao = new TEncSampleAdaptiveOffset[numRows];
for (int i = 0; i < m_numRows; ++i)
{
m_loopFilter[i].create(g_maxCUDepth);
+ m_sao[i].setSaoLcuBoundary(top->param.saoLcuBoundary);
+ m_sao[i].setSaoLcuBasedOptimization(top->param.saoLcuBasedOptimization);
+ m_sao[i].setMaxNumOffsetsPerPic(top->getMaxNumOffsetsPerPic());
+ m_sao[i].create(top->param.sourceWidth, top->param.sourceHeight, g_maxCUWidth, g_maxCUHeight);
+ m_sao[i].createEncBuffer();
}
}
@@ -111,6 +123,10 @@
m_pic->m_complete_lft[i] = 0;
m_rows_active[i] = false;
m_complete_lftV[i] = 0;
+
+ if (m_cfg->param.saoLcuBasedOptimization && m_cfg->param.saoLcuBoundary)
+ m_sao[i].resetStats();
+ m_sao[i].createPicSaoInfo(pic);
}
else
{
@@ -131,6 +147,17 @@
WaveFront::dequeue();
}
+void FrameFilter::end()
+{
+ if (m_cfg->param.bEnableLoopFilter)
+ {
+ for (int i = 0; i < m_numRows; i++)
+ {
+ m_sao[i].destroyPicSaoInfo();
+ }
+ }
+}
+
void FrameFilter::enqueueRow(int row)
{
ScopedLock self(m_locks[row]);
@@ -174,6 +201,12 @@
const uint32_t cuAddr = lineStartCUAddr + col;
TComDataCU* cu = m_pic->getCU(cuAddr);
+ // SAO parameter estimation using non-deblocked pixels for LCU bottom and right boundary areas
+ if (m_cfg->param.saoLcuBasedOptimization && m_cfg->param.saoLcuBoundary)
+ {
+ m_sao[row].calcSaoStatsLCu_BeforeDblk(m_pic, cuAddr);
+ }
+
m_loopFilter[row].loopFilterCU(cu, EDGE_VER);
m_complete_lftV[row]++;
diff -r c2f5275ecb49 -r fd7740c94413 source/encoder/framefilter.h
--- a/source/encoder/framefilter.h Fri Aug 16 07:02:26 2013 -0500
+++ b/source/encoder/framefilter.h Fri Aug 16 20:15:57 2013 +0800
@@ -27,6 +27,7 @@
#include "TLibCommon/TComPic.h"
#include "TLibCommon/TComLoopFilter.h"
+#include "TLibEncoder/TEncSampleAdaptiveOffset.h"
#include "threading.h"
#include "wavefront.h"
@@ -52,6 +53,7 @@
void destroy();
void start(TComPic *pic);
+ void end();
void wait();
@@ -69,9 +71,10 @@
public:
- TComLoopFilter* m_loopFilter;
- int m_numRows;
- Event m_completionEvent;
+ TComLoopFilter* m_loopFilter;
+ TEncSampleAdaptiveOffset* m_sao;
+ int m_numRows;
+ Event m_completionEvent;
};
}
More information about the x265-devel
mailing list