<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Sep 30, 2013 at 1:23 AM, Min Chen <span dir="ltr"><<a href="mailto:chenm003@163.com" target="_blank">chenm003@163.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"># HG changeset patch<br>
# User Min Chen <<a href="mailto:chenm003@163.com">chenm003@163.com</a>><br>
# Date 1380521904 -28800<br>
# Node ID cd4d431e292d0935c154daf0917dbb6816cdbca8<br>
# Parent  55edc34e253c14d3eccb83a7d1db43774349ff9a<br>
get same output between single and multi threading<br>
<br>
Output mistake reasons:<br>
<br>
1. CABAC Table Initialize<br>
   The HM have decide best table for CABAC, but in frame parallelism,<br>
   we can't get this information before thread start, we have to<br>
   disable it now.<br>
Side effect: maybe lost some compress performance<br>
<br>
2. SAO Global Disable<br>
   The HM decide SAO global disable flag depend previous same type of<br>
   slice. but here, we can get right statistics informat before start,<br>
   so we have to disable it.<br>
Side effect: more computer cost since we always try SAO on every LCU<br>
<br>
3. CABAC status m_frac not reset.<br>
    This HM bug still alive, we found more here.<br>
<br>
diff -r 55edc34e253c -r cd4d431e292d source/Lib/TLibEncoder/TEncTop.cpp<br>
--- a/source/Lib/TLibEncoder/TEncTop.cpp        Sat Sep 28 22:54:44 2013 -0500<br>
+++ b/source/Lib/TLibEncoder/TEncTop.cpp        Mon Sep 30 14:18:24 2013 +0800<br>
@@ -823,7 +823,7 @@<br>
     pps->setDeblockingFilterOverrideEnabledFlag(!m_loopFilterOffsetInPPS);<br>
     pps->setPicDisableDeblockingFilterFlag(!param.bEnableLoopFilter);<br>
     pps->setLog2ParallelMergeLevelMinus2(m_log2ParallelMergeLevelMinus2);<br>
-    pps->setCabacInitPresentFlag(CABAC_INIT_PRESENT_FLAG);<br>
+    pps->setCabacInitPresentFlag(param.frameNumThreads > 1 ? 0 : CABAC_INIT_PRESENT_FLAG);<br>
<br>
     pps->setNumRefIdxL0DefaultActive(1);<br>
     pps->setNumRefIdxL1DefaultActive(1);<br>
diff -r 55edc34e253c -r cd4d431e292d source/encoder/cturow.h<br>
--- a/source/encoder/cturow.h   Sat Sep 28 22:54:44 2013 -0500<br>
+++ b/source/encoder/cturow.h   Mon Sep 30 14:18:24 2013 +0800<br>
@@ -63,9 +63,22 @@<br>
<br>
     void destroy();<br>
<br>
-    void init()<br>
+    void init(TComSlice *slice)<br>
     {<br>
         m_active = 0;<br>
+<br>
+        // Note: Reset status to avoid frame parallelism output mistake on different thread number<br>
+        for (UInt depth = 0; depth < g_maxCUDepth + 1; depth++)<br>
+        {<br>
+            for (int ciIdx = 0; ciIdx < CI_NUM; ciIdx++)<br>
+            {<br>
+                m_rdSbacCoders[depth][ciIdx]->setSlice(slice);<br>
+                m_rdSbacCoders[depth][ciIdx]->resetEntropy();<br>
+                m_binCodersCABAC[depth][ciIdx]->m_fracBits = 0;<br>
+            }<br>
+        }<br>
+        m_rdGoOnSbacCoder.setSlice(slice);<br>
+        m_rdGoOnSbacCoder.resetEntropy();<br>
     }<br>
<br>
     void processCU(TComDataCU *cu, TComSlice *slice, TEncSbac *bufferSBac, bool bSaveCabac);<br>
diff -r 55edc34e253c -r cd4d431e292d source/encoder/frameencoder.cpp<br>
--- a/source/encoder/frameencoder.cpp   Sat Sep 28 22:54:44 2013 -0500<br>
+++ b/source/encoder/frameencoder.cpp   Mon Sep 30 14:18:24 2013 +0800<br>
@@ -877,12 +877,14 @@<br>
 void FrameEncoder::compressCTURows()<br>
 {<br>
     PPAScopeEvent(FrameEncoder_compressRows);<br>
+    TComSlice* slice = m_pic->getSlice();<br>
+<br>
     // reset entropy coders<br>
     m_sbacCoder.init(&m_binCoderCABAC);<br>
     for (int i = 0; i < this->m_numRows; i++)<br>
     {<br>
-        m_rows[i].init();<br>
-        m_rows[i].m_entropyCoder.setEntropyCoder(&m_sbacCoder, m_pic->getSlice());<br>
+        m_rows[i].init(slice);<br>
+        m_rows[i].m_entropyCoder.setEntropyCoder(&m_sbacCoder, slice);<br>
         m_rows[i].m_entropyCoder.resetEntropy();<br>
<br>
         m_rows[i].m_rdSbacCoders[0][CI_CURR_BEST]->load(&m_sbacCoder);<br>
@@ -891,7 +893,6 @@<br>
     }<br>
<br>
     UInt refLagRows = ((m_cfg->param.searchRange + NTAPS_LUMA/2 + g_maxCUHeight - 1) / g_maxCUHeight) + 1;<br>
-    TComSlice* slice = m_pic->getSlice();<br>
     int numPredDir = slice->isInterP() ? 1 : slice->isInterB() ? 2 : 0;<br>
<br>
     m_frameFilter.start(m_pic);<br>
diff -r 55edc34e253c -r cd4d431e292d source/encoder/framefilter.cpp<br>
--- a/source/encoder/framefilter.cpp    Sat Sep 28 22:54:44 2013 -0500<br>
+++ b/source/encoder/framefilter.cpp    Mon Sep 30 14:18:24 2013 +0800<br>
@@ -98,6 +98,13 @@<br>
         SAOParam* saoParam = pic->getPicSym()->getSaoParam();<br>
         m_sao.resetSAOParam(saoParam);<br>
         m_sao.rdoSaoUnitRowInit(saoParam);<br>
+<br>
+        // NOTE: Disable SAO automatic turn off when Frame Parallelism for output exact<br>
+        if (m_cfg->param.frameNumThreads)<br></blockquote><div><br></div><div>param.frameNumThreads is always != 0.  should this be checking for > 1?<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

+        {<br>
+            saoParam->bSaoFlag[0] = true;<br>
+            saoParam->bSaoFlag[1] = true;<br>
+        }<br>
     }<br>
 }<br>
<br></blockquote><div><br></div></div>-- <br>Steve Borho
</div></div>