<div dir="ltr">This is a nice logical improvement. Anything stopping this patch from being pushed in today?</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 9, 2016 at 8:21 PM, Ashok Kumar Mishra <span dir="ltr"><<a href="mailto:ashok@multicorewareinc.com" target="_blank">ashok@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Below are some test results after using the same qp for encoding the CU and SAO distortion calculation.</div><div> </div><div><b>Before(crowd_run_2160p50, preset - medium, --bitrate 9000)</b></div><div> encoded 500 frames in 262.47s (1.90 fps), 8956.57 kb/s, Avg QP:43.43, Global PSNR: 30.941, SSIM Mean Y: 0.7714149 ( 6.410 dB)</div><div><br></div><div> <b>After</b></div><div> encoded 500 frames in 270.96s (1.85 fps), 8954.41 kb/s, Avg QP:43.43, Global PSNR: 30.978, SSIM Mean Y: 0.7734143 ( 6.448 dB)</div><div>--------------------------------------------------------</div><div><div><br></div><div><b>Before(crowd_run_1080p50, preset - medium)</b></div><div> encoded 500 frames in 81.79s (6.11 fps), 9694.14 kb/s, Avg QP:37.79, Global PSNR: 31.037, SSIM Mean Y: 0.8414618 ( 7.999 dB)</div><div> </div><div> <b>After</b></div><div> encoded 500 frames in 81.04s (6.17 fps), 9686.80 kb/s, Avg QP:37.79, Global PSNR: 31.044, SSIM Mean Y: 0.8417730 ( 8.007 dB)</div><div> ----------------------------------------------- </div><div><br></div><div> <b>Before(</b><b>crowd_run_1080p50, preset - </b><b>veryslow)</b></div><div> encoded 500 frames in 993.57s (0.50 fps), 9519.62 kb/s, Avg QP:37.78, Global PSNR: 31.498, SSIM Mean Y: 0.8494004 ( 8.222 dB)</div><div> </div><div> <b>After</b></div><div> encoded 500 frames in 1000.08s (0.50 fps), 9511.11 kb/s, Avg QP:37.78, Global PSNR: 31.503, SSIM Mean Y: 0.8496846 ( 8.230 dB)</div><div> </div><div> ------------------------------------------------<br></div><div> <b>Before(medium, crowd_run_1080p50, --bitrate 7000)</b></div><div> encoded 500 frames in 78.54s (6.37 fps), 6949.02 kb/s, Avg QP:39.77, Global PSNR: 29.962, SSIM Mean Y: 0.8069742 ( 7.144 dB)</div><div> </div><div><b> After</b></div><div> encoded 500 frames in 75.58s (6.62 fps), 6950.09 kb/s, Avg QP:39.76, Global PSNR: 29.973, SSIM Mean Y: 0.8075229 ( 7.156 dB) </div><div> -------------------------------------------------</div><div><br></div><div> <b>Before(veryslow, crowd_run_1080p50, --bitrate 7000)</b></div><div> Before</div><div> encoded 500 frames in 864.42s (0.58 fps), 6945.49 kb/s, Avg QP:39.73, Global PSNR: 30.418, SSIM Mean Y: 0.8157191 ( 7.345 dB)</div><div><br></div><div> After</div><div> encoded 500 frames in 860.32s (0.58 fps), 6945.18 kb/s, Avg QP:39.73, Global PSNR: 30.429, SSIM Mean Y: 0.8160904 ( 7.354 dB)</div><div> </div><div><br></div></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 9, 2016 at 8:11 PM, <span dir="ltr"><<a href="mailto:ashok@multicorewareinc.com" target="_blank">ashok@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Ashok Kumar Mishra<<a href="mailto:ashok@multicorewareinc.com" target="_blank">ashok@multicorewareinc.com</a>><br>
# Date 1457424244 -19800<br>
# Tue Mar 08 13:34:04 2016 +0530<br>
# Node ID 047095eba0a40f2298df74c37abae7a2e31f4bce<br>
# Parent 88aebc166fa8e16f91d5f0acce77690003be9d91<br>
[REVIEW PATCH]Use qp value of encoded CU, instead slice qp value<br>
When dqp is enabled, qp value applied on CU for encoding is different from slice qp. So in this case the slice qp value<br>
should not be used for SAO offset distortion calculation. That means the same qp value used for encoding CU must be used<br>
for SAO offset distortion calculation.<br>
<br>
diff -r 88aebc166fa8 -r 047095eba0a4 source/encoder/frameencoder.cpp<br>
--- a/source/encoder/frameencoder.cpp Fri Mar 04 16:59:45 2016 +0530<br>
+++ b/source/encoder/frameencoder.cpp Tue Mar 08 13:34:04 2016 +0530<br>
@@ -439,7 +439,7 @@<br>
<br>
m_initSliceContext.resetEntropy(*slice);<br>
<br>
- m_frameFilter.start(m_frame, m_initSliceContext, qp);<br>
+ m_frameFilter.start(m_frame, m_initSliceContext);<br>
<br>
/* ensure all rows are blocked prior to initializing row CTU counters */<br>
WaveFront::clearEnabledRowMask();<br>
diff -r 88aebc166fa8 -r 047095eba0a4 source/encoder/framefilter.cpp<br>
--- a/source/encoder/framefilter.cpp Fri Mar 04 16:59:45 2016 +0530<br>
+++ b/source/encoder/framefilter.cpp Tue Mar 08 13:34:04 2016 +0530<br>
@@ -103,7 +103,7 @@<br>
<br>
}<br>
<br>
-void FrameFilter::start(Frame *frame, Entropy& initState, int qp)<br>
+void FrameFilter::start(Frame *frame, Entropy& initState)<br>
{<br>
m_frame = frame;<br>
<br>
@@ -113,7 +113,7 @@<br>
for(int row = 0; row < m_numRows; row++)<br>
{<br>
if (m_param->bEnableSAO)<br>
- m_parallelFilter[row].m_sao.startSlice(frame, initState, qp);<br>
+ m_parallelFilter[row].m_sao.startSlice(frame, initState);<br>
<br>
m_parallelFilter[row].m_lastCol.set(0);<br>
m_parallelFilter[row].m_allowedCol.set(0);<br>
diff -r 88aebc166fa8 -r 047095eba0a4 source/encoder/framefilter.h<br>
--- a/source/encoder/framefilter.h Fri Mar 04 16:59:45 2016 +0530<br>
+++ b/source/encoder/framefilter.h Tue Mar 08 13:34:04 2016 +0530<br>
@@ -127,7 +127,7 @@<br>
void init(Encoder *top, FrameEncoder *frame, int numRows, uint32_t numCols);<br>
void destroy();<br>
<br>
- void start(Frame *pic, Entropy& initState, int qp);<br>
+ void start(Frame *pic, Entropy& initState);<br>
<br>
void processRow(int row);<br>
void processPostRow(int row);<br>
diff -r 88aebc166fa8 -r 047095eba0a4 source/encoder/sao.cpp<br>
--- a/source/encoder/sao.cpp Fri Mar 04 16:59:45 2016 +0530<br>
+++ b/source/encoder/sao.cpp Tue Mar 08 13:34:04 2016 +0530<br>
@@ -76,8 +76,6 @@<br>
m_countPreDblk = NULL;<br>
m_offsetOrgPreDblk = NULL;<br>
m_refDepth = 0;<br>
- m_lumaLambda = 0;<br>
- m_chromaLambda = 0;<br>
m_param = NULL;<br>
m_clipTable = NULL;<br>
m_clipTableBase = NULL;<br>
@@ -226,17 +224,10 @@<br>
saoParam->ctuParam[i] = new SaoCtuParam[m_numCuInHeight * m_numCuInWidth];<br>
}<br>
<br>
-void SAO::startSlice(Frame* frame, Entropy& initState, int qp)<br>
+void SAO::startSlice(Frame* frame, Entropy& initState)<br>
{<br>
- Slice* slice = frame->m_encData->m_slice;<br>
- int qpCb = qp;<br>
- if (m_param->internalCsp == X265_CSP_I420)<br>
- qpCb = x265_clip3(QP_MIN, QP_MAX_MAX, (int)g_chromaScale[qp + slice->m_pps->chromaQpOffset[0]]);<br>
- else<br>
- qpCb = X265_MIN(qp + slice->m_pps->chromaQpOffset[0], QP_MAX_SPEC);<br>
- m_lumaLambda = x265_lambda2_tab[qp];<br>
- m_chromaLambda = x265_lambda2_tab[qpCb]; // Use Cb QP for SAO chroma<br>
m_frame = frame;<br>
+ Slice* slice = m_frame->m_encData->m_slice;<br>
<br>
switch (slice->m_sliceType)<br>
{<br>
@@ -1197,7 +1188,22 @@<br>
<br>
void SAO::rdoSaoUnitCu(SAOParam* saoParam, int rowBaseAddr, int idxX, int addr)<br>
{<br>
- double lambda[3] = {m_lumaLambda, m_chromaLambda, m_chromaLambda};<br>
+ Slice* slice = m_frame->m_encData->m_slice;<br>
+// int qp = slice->m_sliceQp;<br>
+ const CUData* cu = m_frame->m_encData->getPicCTU(addr);<br>
+ int qp = cu->m_qp[0];<br>
+<br>
+ double lambda[2] = {0.0};<br>
+<br>
+ int qpCb = qp;<br>
+ if (m_param->internalCsp == X265_CSP_I420)<br>
+ qpCb = x265_clip3(QP_MIN, QP_MAX_MAX, (int)g_chromaScale[qp + slice->m_pps->chromaQpOffset[0]]);<br>
+ else<br>
+ qpCb = X265_MIN(qp + slice->m_pps->chromaQpOffset[0], QP_MAX_SPEC);<br>
+<br>
+ lambda[0] = x265_lambda2_tab[qp];<br>
+ lambda[1] = x265_lambda2_tab[qpCb]; // Use Cb QP for SAO chroma<br>
+<br>
const bool allowMerge[2] = {(idxX != 0), (rowBaseAddr != 0)}; // left, up<br>
<br>
const int addrMerge[2] = {(idxX ? addr - 1 : -1), (rowBaseAddr ? addr - m_numCuInWidth : -1)};// left, up<br>
@@ -1242,9 +1248,9 @@<br>
saoStatsInitialOffset(chroma);<br>
<br>
double mergeDist[NUM_MERGE_MODE] = { 0.0 };<br>
- saoLumaComponentParamDist(saoParam, addr, mergeDist);<br>
+ saoLumaComponentParamDist(saoParam, addr, mergeDist, lambda);<br>
if (chroma)<br>
- saoChromaComponentParamDist(saoParam, addr, mergeDist);<br>
+ saoChromaComponentParamDist(saoParam, addr, mergeDist, lambda);<br>
<br>
if (saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1])<br>
{<br>
@@ -1286,10 +1292,9 @@<br>
}<br>
}<br>
<br>
- mergeDist[mergeIdx + 1] += ((double)estDist / lambda[plane]);<br>
+ mergeDist[mergeIdx + 1] += ((double)estDist / lambda[!!plane]);<br>
}<br>
<br>
-<br>
m_entropyCoder.load(m_rdContexts.cur);<br>
m_entropyCoder.resetBits();<br>
if (allowMerge[0])<br>
@@ -1412,7 +1417,7 @@<br>
return bestOffset;<br>
}<br>
<br>
-void SAO::saoLumaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist)<br>
+void SAO::saoLumaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda)<br>
{<br>
int64_t bestDist = 0;<br>
int bestTypeIdx = -1;<br>
@@ -1426,7 +1431,7 @@<br>
m_entropyCoder.resetBits();<br>
m_entropyCoder.codeSaoType(0);<br>
<br>
- double dCostPartBest = m_entropyCoder.getNumberOfWrittenBits() * m_lumaLambda;<br>
+ double dCostPartBest = m_entropyCoder.getNumberOfWrittenBits() * lambda[0];<br>
<br>
//EO distortion calculation<br>
for (int typeIdx = 0; typeIdx < MAX_NUM_SAO_TYPE - 1; typeIdx++)<br>
@@ -1439,7 +1444,7 @@<br>
int32_t& offsetOut = m_offset[0][typeIdx][classIdx];<br>
<br>
if (count)<br>
- offsetOut = estIterOffset(typeIdx, m_lumaLambda, offsetOut, count, offsetOrg, distBOClasses[0], costBOClasses[0]);<br>
+ offsetOut = estIterOffset(typeIdx, lambda[0], offsetOut, count, offsetOrg, distBOClasses[0], costBOClasses[0]);<br>
else<br>
offsetOut = 0;<br>
<br>
@@ -1451,7 +1456,7 @@<br>
m_entropyCoder.codeSaoOffsetEO(m_offset[0][typeIdx] + 1, typeIdx, 0);<br>
<br>
uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();<br>
- double cost = (double)estDist + m_lumaLambda * (double)estRate;<br>
+ double cost = (double)estDist + lambda[0] * (double)estRate;<br>
<br>
if (cost < dCostPartBest)<br>
{<br>
@@ -1479,10 +1484,10 @@<br>
int32_t& offsetOut = m_offset[0][SAO_BO][classIdx];<br>
<br>
distBOClasses[classIdx] = 0;<br>
- costBOClasses[classIdx] = m_lumaLambda;<br>
+ costBOClasses[classIdx] = lambda[0];<br>
<br>
if (count)<br>
- offsetOut = estIterOffset(SAO_BO, m_lumaLambda, offsetOut, count, offsetOrg, distBOClasses[classIdx], costBOClasses[classIdx]);<br>
+ offsetOut = estIterOffset(SAO_BO, lambda[0], offsetOut, count, offsetOrg, distBOClasses[classIdx], costBOClasses[classIdx]);<br>
else<br>
offsetOut = 0;<br>
}<br>
@@ -1513,7 +1518,7 @@<br>
m_entropyCoder.codeSaoOffsetBO(m_offset[0][SAO_BO] + bestClassBO, bestClassBO, 0);<br>
<br>
uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();<br>
- double cost = (double)estDist + m_lumaLambda * (double)estRate;<br>
+ double cost = (double)estDist + lambda[0] * (double)estRate;<br>
<br>
if (cost < dCostPartBest)<br>
{<br>
@@ -1527,13 +1532,13 @@<br>
lclCtuParam->offset[classIdx] = (int)m_offset[0][SAO_BO][classIdx + bestClassBO];<br>
}<br>
<br>
- mergeDist[0] = ((double)bestDist / m_lumaLambda);<br>
+ mergeDist[0] = ((double)bestDist / lambda[0]);<br>
m_entropyCoder.load(m_rdContexts.temp);<br>
m_entropyCoder.codeSaoOffset(*lclCtuParam, 0);<br>
m_entropyCoder.store(m_rdContexts.temp);<br>
}<br>
<br>
-void SAO::saoChromaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist)<br>
+void SAO::saoChromaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda)<br>
{<br>
int64_t bestDist = 0;<br>
int bestTypeIdx = -1;<br>
@@ -1548,7 +1553,7 @@<br>
m_entropyCoder.resetBits();<br>
m_entropyCoder.codeSaoType(0);<br>
<br>
- double costPartBest = m_entropyCoder.getNumberOfWrittenBits() * m_chromaLambda;<br>
+ double costPartBest = m_entropyCoder.getNumberOfWrittenBits() * lambda[1];<br>
<br>
//EO RDO<br>
for (int typeIdx = 0; typeIdx < MAX_NUM_SAO_TYPE - 1; typeIdx++)<br>
@@ -1563,7 +1568,7 @@<br>
int32_t& offsetOut = m_offset[compIdx][typeIdx][classIdx];<br>
<br>
if (count)<br>
- offsetOut = estIterOffset(typeIdx, m_chromaLambda, offsetOut, count, offsetOrg, distBOClasses[0], costBOClasses[0]);<br>
+ offsetOut = estIterOffset(typeIdx, lambda[1], offsetOut, count, offsetOrg, distBOClasses[0], costBOClasses[0]);<br>
else<br>
offsetOut = 0;<br>
<br>
@@ -1578,7 +1583,7 @@<br>
m_entropyCoder.codeSaoOffsetEO(m_offset[compIdx + 1][typeIdx] + 1, typeIdx, compIdx + 1);<br>
<br>
uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();<br>
- double cost = (double)(estDist[0] + estDist[1]) + m_chromaLambda * (double)estRate;<br>
+ double cost = (double)(estDist[0] + estDist[1]) + lambda[1] * (double)estRate;<br>
<br>
if (cost < costPartBest)<br>
{<br>
@@ -1615,10 +1620,10 @@<br>
int32_t& offsetOut = m_offset[compIdx][SAO_BO][classIdx];<br>
<br>
distBOClasses[classIdx] = 0;<br>
- costBOClasses[classIdx] = m_chromaLambda;<br>
+ costBOClasses[classIdx] = lambda[1];<br>
<br>
if (count)<br>
- offsetOut = estIterOffset(SAO_BO, m_chromaLambda, offsetOut, count, offsetOrg, distBOClasses[classIdx], costBOClasses[classIdx]);<br>
+ offsetOut = estIterOffset(SAO_BO, lambda[1], offsetOut, count, offsetOrg, distBOClasses[classIdx], costBOClasses[classIdx]);<br>
else<br>
offsetOut = 0;<br>
}<br>
@@ -1648,7 +1653,7 @@<br>
m_entropyCoder.codeSaoOffsetBO(m_offset[compIdx + 1][SAO_BO] + bestClassBO[compIdx], bestClassBO[compIdx], compIdx + 1);<br>
<br>
uint32_t estRate = m_entropyCoder.getNumberOfWrittenBits();<br>
- double cost = (double)(estDist[0] + estDist[1]) + m_chromaLambda * (double)estRate;<br>
+ double cost = (double)(estDist[0] + estDist[1]) + lambda[1] * (double)estRate;<br>
<br>
if (cost < costPartBest)<br>
{<br>
@@ -1665,7 +1670,7 @@<br>
}<br>
}<br>
<br>
- mergeDist[0] += ((double)bestDist / m_chromaLambda);<br>
+ mergeDist[0] += ((double)bestDist / lambda[1]);<br>
m_entropyCoder.load(m_rdContexts.temp);<br>
m_entropyCoder.codeSaoOffset(*lclCtuParam[0], 1);<br>
m_entropyCoder.codeSaoOffset(*lclCtuParam[1], 2);<br>
diff -r 88aebc166fa8 -r 047095eba0a4 source/encoder/sao.h<br>
--- a/source/encoder/sao.h Fri Mar 04 16:59:45 2016 +0530<br>
+++ b/source/encoder/sao.h Tue Mar 08 13:34:04 2016 +0530<br>
@@ -114,10 +114,6 @@<br>
int m_refDepth;<br>
int m_numNoSao[2];<br>
<br>
- double m_lumaLambda;<br>
- double m_chromaLambda;<br>
- /* TODO: No doubles for distortion */<br>
-<br>
SAO();<br>
<br>
bool create(x265_param* param, int initCommon);<br>
@@ -126,7 +122,7 @@<br>
<br>
void allocSaoParam(SAOParam* saoParam) const;<br>
<br>
- void startSlice(Frame* pic, Entropy& initState, int qp);<br>
+ void startSlice(Frame* pic, Entropy& initState);<br>
void resetStats();<br>
<br>
// CTU-based SAO process without slice granularity<br>
@@ -138,8 +134,8 @@<br>
void calcSaoStatsCu(int addr, int plane);<br>
void calcSaoStatsCu_BeforeDblk(Frame* pic, int idxX, int idxY);<br>
<br>
- void saoLumaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist);<br>
- void saoChromaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist);<br>
+ void saoLumaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda);<br>
+ void saoChromaComponentParamDist(SAOParam* saoParam, int addr, double* mergeDist, double* lambda);<br>
<br>
inline int estIterOffset(int typeIdx, double lambda, int offset, int32_t count, int32_t offsetOrg,<br>
int& currentDistortionTableBo, double& currentRdCostTableBo);<br>
</blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><div>Deepthi Nandakumar<br></div>Engineering Manager, x265<br></div>Multicoreware, Inc<br></div></div>
</div>