[x265] [PATCH] Use mixed bitmap between FrameEncoder and FrameFilter to Fix crash and hash mistake in WPP mode
# HG changeset patch # User Min Chen chenm...@163.com # Date 1379321243 -28800 # Node ID 5ff15bbb2bda4fedca72c9093374de6dd8c262b3 # Parent 6bab41a554b36133865fe3378964cb9e76c24ebd Use mixed bitmap between FrameEncoder and FrameFilter to Fix crash and hash mistake in WPP mode I change task schedult bitmap to mixed FrameEncoder and FrameFilter because there catch two bugs, and I want to reduce latency of Frame Parallelism. The new bitmap mapping 2N+0 to FrameEncoder and 2N+1 to FrameFilter. Side effect: 1. We can remove the lock from FrameFilter. 2. Mixed bitmap let us do Filter early, so reduce latency of Frame Parallelism Solved bugs: 1. CRASH: the reason is sometime two of threads finish in same time, so they will enter Filter in wrong order and sent Finished Event early. when main thread dequeue JobProvider and execute FrameFilter, we will catch a crash! 2. HASH MISTAKE: the reason is same as below, but last row is right order, we will got worng reconst image. diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Fri Sep 13 17:24:05 2013 +0530 +++ b/source/encoder/frameencoder.cpp Mon Sep 16 16:47:23 2013 +0800 @@ -98,7 +98,8 @@ m_rows[i].create(top); } -if (!WaveFront::init(m_numRows)) +// NOTE: 2 times of numRows because both Encoder and Filter in same queue +if (!WaveFront::init(m_numRows * 2)) { assert(!Unable to initialize job queue.); m_pool = NULL; @@ -870,9 +871,9 @@ } } -WaveFront::enableRow(row); +enableRowEncoder(row); if (row == 0) -WaveFront::enqueueRow(row); +enqueueRowEncoder(0); else m_pool-pokeIdleThread(); } @@ -883,7 +884,7 @@ } else { -for (int i = 0; i this-m_numRows; i++) +for (int i = 0; i this-m_numRows * 2; i++) { // block until all reference frames have reconstructed the rows we need for (int l = 0; l numPredDir; l++) @@ -904,10 +905,12 @@ } } -void FrameEncoder::processRow(int row) +void FrameEncoder::processRowEncoder(int row) { PPAScopeEvent(Thread_ProcessRow); +//printf(Encoder(%2d)\n, row); + // Called by worker threads CTURow curRow = m_rows[row]; CTURow codeRow = m_rows[m_cfg-param.bEnableWavefront ? row : 0]; @@ -941,7 +944,7 @@ m_rows[row + 1].m_completed + 2 = m_rows[row].m_completed) { m_rows[row + 1].m_active = true; -WaveFront::enqueueRow(row + 1); +enqueueRowEncoder(row + 1); } } @@ -957,13 +960,16 @@ // Run row-wise loop filters if (row = m_filterRowDelay) { -m_frameFilter.processRow(row - m_filterRowDelay); +enqueueRowFilter(row - m_filterRowDelay); + +// NOTE: Active Filter to first row (row 0) +if (row == m_filterRowDelay) +enableRowFilter(0); } if (row == m_numRows - 1) { for(int i = m_numRows - m_filterRowDelay; i m_numRows; i++) -m_frameFilter.processRow(i); -m_completionEvent.trigger(); +enqueueRowFilter(i); } } diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Fri Sep 13 17:24:05 2013 +0530 +++ b/source/encoder/frameencoder.h Mon Sep 16 16:47:23 2013 +0800 @@ -64,7 +64,54 @@ void destroy(); -void processRow(int row); +void processRowEncoder(int row); + +void processRowFilter(int row) +{ +m_frameFilter.processRow(row); +} + +void enqueueRowEncoder(int row) +{ +WaveFront::enqueueRow(row * 2 + 0); +} + +void enqueueRowFilter(int row) +{ +WaveFront::enqueueRow(row * 2 + 1); +} + +void enableRowEncoder(int row) +{ +WaveFront::enableRow(row * 2 + 0); +} + +void enableRowFilter(int row) +{ +WaveFront::enableRow(row * 2 + 1); +} + +void processRow(int row) +{ +const int realRow = row 1; +const int typeNum = row 1; + +// TODO: use switch when more type +if (typeNum == 0) +{ +processRowEncoder(realRow); +} +else +{ +processRowFilter(realRow); + +// NOTE: Active next row +if (realRow != m_numRows - 1) +enableRowFilter(realRow + 1); +else +m_completionEvent.trigger(); +} +} TEncEntropy* getEntropyCoder(int row) { return this-m_rows[row].m_entropyCoder; } diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/framefilter.cpp --- a/source/encoder/framefilter.cppFri Sep 13 17:24:05 2013 +0530 +++ b/source/encoder/framefilter.cppMon Sep 16 16:47:23 2013 +0800 @@ -102,8 +102,6 @@ {
Re: [x265] [PATCH] Use mixed bitmap between FrameEncoder and FrameFilter to Fix crash and hash mistake in WPP mode
Excuse me, this is wrong patch, I will send a new one soon. At 2013-09-16 16:51:58,Min Chen chenm...@163.com wrote: # HG changeset patch # User Min Chen chenm...@163.com # Date 1379321243 -28800 # Node ID 5ff15bbb2bda4fedca72c9093374de6dd8c262b3 # Parent 6bab41a554b36133865fe3378964cb9e76c24ebd Use mixed bitmap between FrameEncoder and FrameFilter to Fix crash and hash mistake in WPP mode I change task schedult bitmap to mixed FrameEncoder and FrameFilter because there catch two bugs, and I want to reduce latency of Frame Parallelism. The new bitmap mapping 2N+0 to FrameEncoder and 2N+1 to FrameFilter. Side effect: 1. We can remove the lock from FrameFilter. 2. Mixed bitmap let us do Filter early, so reduce latency of Frame Parallelism Solved bugs: 1. CRASH: the reason is sometime two of threads finish in same time, so they will enter Filter in wrong order and sent Finished Event early. when main thread dequeue JobProvider and execute FrameFilter, we will catch a crash! 2. HASH MISTAKE: the reason is same as below, but last row is right order, we will got worng reconst image. diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Fri Sep 13 17:24:05 2013 +0530 +++ b/source/encoder/frameencoder.cpp Mon Sep 16 16:47:23 2013 +0800 @@ -98,7 +98,8 @@ m_rows[i].create(top); } -if (!WaveFront::init(m_numRows)) +// NOTE: 2 times of numRows because both Encoder and Filter in same queue +if (!WaveFront::init(m_numRows * 2)) { assert(!Unable to initialize job queue.); m_pool = NULL; @@ -870,9 +871,9 @@ } } -WaveFront::enableRow(row); +enableRowEncoder(row); if (row == 0) -WaveFront::enqueueRow(row); +enqueueRowEncoder(0); else m_pool-pokeIdleThread(); } @@ -883,7 +884,7 @@ } else { -for (int i = 0; i this-m_numRows; i++) +for (int i = 0; i this-m_numRows * 2; i++) { // block until all reference frames have reconstructed the rows we need for (int l = 0; l numPredDir; l++) @@ -904,10 +905,12 @@ } } -void FrameEncoder::processRow(int row) +void FrameEncoder::processRowEncoder(int row) { PPAScopeEvent(Thread_ProcessRow); +//printf(Encoder(%2d)\n, row); + // Called by worker threads CTURow curRow = m_rows[row]; CTURow codeRow = m_rows[m_cfg-param.bEnableWavefront ? row : 0]; @@ -941,7 +944,7 @@ m_rows[row + 1].m_completed + 2 = m_rows[row].m_completed) { m_rows[row + 1].m_active = true; -WaveFront::enqueueRow(row + 1); +enqueueRowEncoder(row + 1); } } @@ -957,13 +960,16 @@ // Run row-wise loop filters if (row = m_filterRowDelay) { -m_frameFilter.processRow(row - m_filterRowDelay); +enqueueRowFilter(row - m_filterRowDelay); + +// NOTE: Active Filter to first row (row 0) +if (row == m_filterRowDelay) +enableRowFilter(0); } if (row == m_numRows - 1) { for(int i = m_numRows - m_filterRowDelay; i m_numRows; i++) -m_frameFilter.processRow(i); -m_completionEvent.trigger(); +enqueueRowFilter(i); } } diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/frameencoder.h --- a/source/encoder/frameencoder.h Fri Sep 13 17:24:05 2013 +0530 +++ b/source/encoder/frameencoder.h Mon Sep 16 16:47:23 2013 +0800 @@ -64,7 +64,54 @@ void destroy(); -void processRow(int row); +void processRowEncoder(int row); + +void processRowFilter(int row) +{ +m_frameFilter.processRow(row); +} + +void enqueueRowEncoder(int row) +{ +WaveFront::enqueueRow(row * 2 + 0); +} + +void enqueueRowFilter(int row) +{ +WaveFront::enqueueRow(row * 2 + 1); +} + +void enableRowEncoder(int row) +{ +WaveFront::enableRow(row * 2 + 0); +} + +void enableRowFilter(int row) +{ +WaveFront::enableRow(row * 2 + 1); +} + +void processRow(int row) +{ +const int realRow = row 1; +const int typeNum = row 1; + +// TODO: use switch when more type +if (typeNum == 0) +{ +processRowEncoder(realRow); +} +else +{ +processRowFilter(realRow); + +// NOTE: Active next row +if (realRow != m_numRows - 1) +enableRowFilter(realRow + 1); +else +m_completionEvent.trigger(); +} +} TEncEntropy* getEntropyCoder(int row) { return this-m_rows[row].m_entropyCoder; } diff -r 6bab41a554b3 -r 5ff15bbb2bda source/encoder/framefilter.cpp --- a/source/encoder/framefilter.cpp Fri Sep 13 17:24:05 2013 +0530 +++
[x265] [PATCH] Use mixed bitmap between FrameEncoder and FrameFilter to Fix crash and hash mistake in WPP mode
# HG changeset patch # User Min Chen chenm...@163.com # Date 1379336600 -28800 # Node ID 7669e48568743a927c5f1ee14c8adf76d5e3a406 # Parent 62964b3d57d9e47cf68aad57808bab568b105d61 Use mixed bitmap between FrameEncoder and FrameFilter to Fix crash and hash mistake in WPP mode I change task schedult bitmap to mixed FrameEncoder and FrameFilter because there catch two bugs, and I want to reduce latency of Frame Parallelism. The new bitmap mapping 2N+0 to FrameEncoder and 2N+1 to FrameFilter. Side effect: 1. We can remove the lock from FrameFilter. 2. Mixed bitmap let us do Filter early, so reduce latency of Frame Parallelism Solved bugs: 1. CRASH: the reason is sometime two of threads finish in same time, so they will enter Filter in wrong order and sent Finished Event early. when main thread dequeue JobProvider and execute FrameFilter, we will catch a crash! 2. HASH MISTAKE: the reason is same as below, but last row is right order, we will got worng reconst image. diff -r 62964b3d57d9 -r 7669e4856874 source/encoder/frameencoder.cpp --- a/source/encoder/frameencoder.cpp Mon Sep 16 21:01:47 2013 +0800 +++ b/source/encoder/frameencoder.cpp Mon Sep 16 21:03:20 2013 +0800 @@ -919,8 +919,6 @@ { PPAScopeEvent(Thread_ProcessRow); -//printf(Encoder(%2d)\n, row); - // Called by worker threads CTURow curRow = m_rows[row]; CTURow codeRow = m_rows[m_cfg-param.bEnableWavefront ? row : 0]; @@ -954,7 +952,7 @@ m_rows[row + 1].m_completed + 2 = m_rows[row].m_completed) { m_rows[row + 1].m_active = true; -enqueueRowEncoder(row + 1); +WaveFront::enqueueRow(row + 1); } } @@ -970,16 +968,13 @@ // Run row-wise loop filters if (row = m_filterRowDelay) { -enqueueRowFilter(row - m_filterRowDelay); - -// NOTE: Active Filter to first row (row 0) -if (row == m_filterRowDelay) -enableRowFilter(0); +m_frameFilter.processRow(row - m_filterRowDelay); } if (row == m_numRows - 1) { for(int i = m_numRows - m_filterRowDelay; i m_numRows; i++) -enqueueRowFilter(i); +m_frameFilter.processRow(i); +m_completionEvent.trigger(); } } ___ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel