[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