<div style="line-height:1.7;color:#000000;font-size:14px;font-family:arial"><DIV>Excuse me, this is wrong patch, I will send a new one soon.</DIV>
<DIV><BR>At 2013-09-16 16:51:58,"Min Chen" <chenm003@163.com> wrote:<BR>># HG changeset patch<BR>># User Min Chen <chenm003@163.com><BR>># Date 1379321243 -28800<BR>># Node ID 5ff15bbb2bda4fedca72c9093374de6dd8c262b3<BR>># Parent 6bab41a554b36133865fe3378964cb9e76c24ebd<BR>>Use mixed bitmap between FrameEncoder and FrameFilter to Fix crash and hash mistake in WPP mode<BR>><BR>>I change task schedult bitmap to mixed FrameEncoder and FrameFilter<BR>>because there catch two bugs, and I want to reduce latency of Frame<BR>>Parallelism.<BR>>The new bitmap mapping 2N+0 to FrameEncoder and 2N+1 to FrameFilter.<BR>>
<BR>>Side effect:<BR>>1. We can remove the lock from FrameFilter.<BR>>2. Mixed bitmap let us do Filter early, so reduce latency of Frame<BR>> Parallelism<BR>><BR>><BR>>Solved bugs:<BR>>1. CRASH: the reason is sometime two of threads finish in same time,<BR>> so they will enter Filter in wrong order and sent Finished Event<BR>> early.<BR>> when main thread dequeue JobProvider and execute FrameFilter, we<BR>> will catch a crash!<BR>><BR>>2. HASH MISTAKE: the reason is same as below, but last row is right<BR>> &nb
sp;order, we will got worng reconst image.<BR>><BR>>diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/frameencoder.cpp<BR>>--- a/source/encoder/frameencoder.cpp Fri Sep 13 17:24:05 2013 +0530<BR>>+++ b/source/encoder/frameencoder.cpp Mon Sep 16 16:47:23 2013 +0800<BR>>@@ -98,7 +98,8 @@<BR>> m_rows[i].create(top);<BR>> }<BR>> <BR>>- if (!WaveFront::init(m_numRows))<BR>>+ // NOTE: 2 times of numRows because both Encoder and Filter in same queue<BR>>+ if (!WaveFront::init(m_numRows * 2))<BR>> {<BR>> a
ssert(!"Unable to initialize job queue.");<BR>> m_pool = NULL;<BR>>@@ -870,9 +871,9 @@<BR>> }<BR>> }<BR>> <BR>>- WaveFront::enableRow(row);<BR>>+ enableRowEncoder(row);<BR>> if (row == 0)<BR>>- WaveFront::enqueueRow(row);<BR>>+ enqueueRowEncoder(0);<BR>> 
; else<BR>> m_pool->pokeIdleThread();<BR>> }<BR>>@@ -883,7 +884,7 @@<BR>> }<BR>> else<BR>> {<BR>>- for (int i = 0; i < this->m_numRows; i++)<BR>>+ for (int i = 0; i < this->m_numRows * 2; i++)<BR>> {<BR>> // block until all reference frames have reconstructed the ro
ws we need<BR>> for (int l = 0; l < numPredDir; l++)<BR>>@@ -904,10 +905,12 @@<BR>> }<BR>> }<BR>> <BR>>-void FrameEncoder::processRow(int row)<BR>>+void FrameEncoder::processRowEncoder(int row)<BR>> {<BR>> PPAScopeEvent(Thread_ProcessRow);<BR>> <BR>>+ //printf("Encoder(%2d)\n", row);<BR>>+<BR>> // Called by worker threads<BR>> CTURow& curRow = m_rows[row];<BR>> CTURow& codeRow = m_rows[m_cfg->param.bEnableWavefront ? row : 0];<BR>>@@ -941,7 +944,7 @@<BR>> &nb
sp; m_rows[row + 1].m_completed + 2 <= m_rows[row].m_completed)<BR>> {<BR>> m_rows[row + 1].m_active = true;<BR>>- WaveFront::enqueueRow(row + 1);<BR>>+ enqueueRowEncoder(row + 1);<BR>> }<BR>> }<BR>> <BR>>@@ -957,13 +960,16 @@<BR>> // Run row-wise loop filter
s<BR>> if (row >= m_filterRowDelay)<BR>> {<BR>>- m_frameFilter.processRow(row - m_filterRowDelay);<BR>>+ enqueueRowFilter(row - m_filterRowDelay);<BR>>+<BR>>+ // NOTE: Active Filter to first row (row 0)<BR>>+ if (row == m_filterRowDelay)<BR>>+ enableRowFilter(0);<BR>> }<BR>> if (row == m_numRows - 1)<BR>> {<BR>> for(int i = m_numRows - m_filterRowDelay;
i < m_numRows; i++)<BR>>- m_frameFilter.processRow(i);<BR>>- m_completionEvent.trigger();<BR>>+ enqueueRowFilter(i);<BR>> }<BR>> }<BR>> <BR>>diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/frameencoder.h<BR>>--- a/source/encoder/frameencoder.h Fri Sep 13 17:24:05 2013 +0530<BR>>+++ b/source/encoder/frameencoder.h Mon Sep 16 16:47:23 2013 +0800<BR>>@@ -64,7 +64,54 @@<BR>> <BR>> void destroy();<BR>> <BR>>- void processRow(int row);<BR>>+ void processRowEncoder(int row);<BR>>+<BR>>+&n
bsp; void processRowFilter(int row)<BR>>+ {<BR>>+ m_frameFilter.processRow(row);<BR>>+ }<BR>>+<BR>>+ void enqueueRowEncoder(int row)<BR>>+ {<BR>>+ WaveFront::enqueueRow(row * 2 + 0);<BR>>+ }<BR>>+<BR>>+ void enqueueRowFilter(int row)<BR>>+ {<BR>>+ WaveFront::enqueueRow(row * 2 + 1);<BR>>+ }<BR>>+<BR>>+ void enableRowEncoder(int row)<BR>>+ {<BR>>+ WaveFront::enableRow(row * 2 + 0);<BR>>+ &
nbsp;}<BR>>+<BR>>+ void enableRowFilter(int row)<BR>>+ {<BR>>+ WaveFront::enableRow(row * 2 + 1);<BR>>+ }<BR>>+<BR>>+ void processRow(int row)<BR>>+ {<BR>>+ const int realRow = row >> 1;<BR>>+ const int typeNum = row & 1;<BR>>+<BR>>+ // TODO: use switch when more type<BR>>+ if (typeNum == 0)<BR>>+ {<BR>>+ processRowEncoder(real
Row);<BR>>+ }<BR>>+ else<BR>>+ {<BR>>+ processRowFilter(realRow);<BR>>+<BR>>+ // NOTE: Active next row<BR>>+ if (realRow != m_numRows - 1)<BR>>+ enableRowFilter(realRow + 1);<BR>>+ else<BR>>+ m_completionEvent.trigger();<BR>>+ }<BR>>+ &nbs
p; }<BR>> <BR>> TEncEntropy* getEntropyCoder(int row) { return &this->m_rows[row].m_entropyCoder; }<BR>> <BR>>diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/framefilter.cpp<BR>>--- a/source/encoder/framefilter.cpp Fri Sep 13 17:24:05 2013 +0530<BR>>+++ b/source/encoder/framefilter.cpp Mon Sep 16 16:47:23 2013 +0800<BR>>@@ -102,8 +102,6 @@<BR>> {<BR>> PPAScopeEvent(Thread_filterCU);<BR>> <BR>>- ScopedLock s(m_filterLock); // Only allow one row to be filtered at a time<BR>>-<BR>> if (!m_cfg->param.bEnableLoopFilter)<BR>> {<BR>>  
; processRowPost(row);<BR>>diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/framefilter.h<BR>>--- a/source/encoder/framefilter.h Fri Sep 13 17:24:05 2013 +0530<BR>>+++ b/source/encoder/framefilter.h Mon Sep 16 16:47:23 2013 +0800<BR>>@@ -70,8 +70,6 @@<BR>> TEncBinCABACCounter m_rdGoOnBinCodersCABAC;<BR>> TComBitCounter m_bitCounter;<BR>> TEncSbac* m_rdGoOnSbacCoderRow0; // for bitstream exact only, depends on HM's bug<BR>>-<BR>>-
Lock m_filterLock;<BR>> };<BR>> }<BR>> <BR>><BR>>_______________________________________________<BR>>x265-devel mailing list<BR>>x265-devel@videolan.org<BR>>https://mailman.videolan.org/listinfo/x265-devel<BR></DIV></div>