[x265] [PATCH STABLE] frameencoder: use atomics to determine full completion of wpp and filter work

Steve Borho steve at borho.org
Tue Mar 31 01:42:43 CEST 2015


# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1427758914 18000
#      Mon Mar 30 18:41:54 2015 -0500
# Branch stable
# Node ID cf26d42975db1703a34af112b8a5134c85210fa4
# Parent  64697f08a0472c13b21255003b32a8a89edb6dd3
frameencoder: use atomics to determine full completion of wpp and filter work

This is a more complete solution for the problem described in 7b5d44d7831e.
Since that commit we've seen one encode failure with the same missing four
bytes, demonstrating the race hazard was still possible (though particularly
hard to reproduce).

in this solution, we increment a counter as each row is first compressed and
again when it is filtered and measured for metrics.  In this way we cannot
signal completion until all rows are completely finished, and it should be
impossible for the signal to occur twice.

diff -r 64697f08a047 -r cf26d42975db source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Mon Mar 30 12:43:39 2015 -0500
+++ b/source/encoder/frameencoder.cpp	Mon Mar 30 18:41:54 2015 -0500
@@ -45,6 +45,7 @@
     m_threadActive = true;
     m_slicetypeWaitTime = 0;
     m_activeWorkerCount = 0;
+    m_completionCount = 0;
     m_bAllRowsStop = false;
     m_vbvResetTriggerRow = -1;
     m_outStreams = NULL;
@@ -303,7 +304,7 @@
     m_allRowsAvailableTime = 0;
     m_stallStartTime = 0;
 
-    m_bLastRowCompleted = false;
+    m_completionCount = 0;
     m_bAllRowsStop = false;
     m_vbvResetTriggerRow = -1;
 
@@ -778,16 +779,10 @@
         // NOTE: Active next row
         if (realRow != m_numRows - 1)
             enqueueRowFilter(realRow + 1);
-        else
-            m_bLastRowCompleted = true;
     }
 
     if (ATOMIC_DEC(&m_activeWorkerCount) == 0)
-    {
-        if (m_bLastRowCompleted)
-            m_completionEvent.trigger();
         m_stallStartTime = x265_mdate();
-    }
 
     m_totalWorkerElapsedTime += x265_mdate() - startTime; // not thread safe, but good enough
 }
@@ -1080,6 +1075,9 @@
     }
 
     curRow.busy = false;
+
+    if (ATOMIC_INC(&m_completionCount) == 2 * (int)m_numRows)
+        m_completionEvent.trigger();
 }
 
 void FrameEncoder::collectCTUStatistics(CUData& ctu)
diff -r 64697f08a047 -r cf26d42975db source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h	Mon Mar 30 12:43:39 2015 -0500
+++ b/source/encoder/frameencoder.h	Mon Mar 30 18:41:54 2015 -0500
@@ -135,19 +135,19 @@
     Event                    m_enable;
     Event                    m_done;
     Event                    m_completionEvent;
-    bool                     m_threadActive;
     int                      m_localTldIdx;
 
+    volatile bool            m_threadActive;
+    volatile bool            m_bAllRowsStop;
+    volatile int             m_completionCount;
+    volatile int             m_vbvResetTriggerRow;
+
     uint32_t                 m_numRows;
     uint32_t                 m_numCols;
     uint32_t                 m_filterRowDelay;
     uint32_t                 m_filterRowDelayCus;
     uint32_t                 m_refLagRows;
 
-    volatile bool            m_bAllRowsStop;
-    volatile bool            m_bLastRowCompleted;
-    volatile int             m_vbvResetTriggerRow;
-
     CTURow*                  m_rows;
     RateControlEntry         m_rce;
     SEIDecodedPictureHash    m_seiReconPictureDigest;
diff -r 64697f08a047 -r cf26d42975db source/encoder/framefilter.cpp
--- a/source/encoder/framefilter.cpp	Mon Mar 30 12:43:39 2015 -0500
+++ b/source/encoder/framefilter.cpp	Mon Mar 30 18:41:54 2015 -0500
@@ -303,6 +303,9 @@
         updateChecksum(reconPic->m_picOrg[1], m_frameEncoder->m_checksum[1], height, width, stride, row, cuHeight);
         updateChecksum(reconPic->m_picOrg[2], m_frameEncoder->m_checksum[2], height, width, stride, row, cuHeight);
     }
+
+    if (ATOMIC_INC(&m_frameEncoder->m_completionCount) == 2 * (int)m_frameEncoder->m_numRows)
+        m_frameEncoder->m_completionEvent.trigger();
 }
 
 static uint64_t computeSSD(pixel *fenc, pixel *rec, intptr_t stride, uint32_t width, uint32_t height)


More information about the x265-devel mailing list