Increase frame drop threshold

This commit is contained in:
Cameron Gutman 2019-02-15 23:51:20 -08:00
parent a1956350b1
commit 80a40ac5f9
2 changed files with 30 additions and 11 deletions

View file

@ -14,8 +14,6 @@
#include "dxvsyncsource.h"
#endif
#define PACING_HISTORY_ENTRIES 8
// We may be woken up slightly late so don't go all the way
// up to the next V-sync since we may accidentally step into
// the next V-sync period. It also takes some amount of time
@ -135,7 +133,8 @@ void Pacer::vsyncCallback(int timeUntilNextVsyncMillis)
}
}
if (m_PacingQueueHistory.count() == PACING_HISTORY_ENTRIES) {
// Keep a rolling 500 ms window of pacing queue history
if (m_PacingQueueHistory.count() == m_DisplayFps / 2) {
m_PacingQueueHistory.dequeue();
}
@ -220,19 +219,38 @@ void Pacer::renderFrame(AVFrame* frame)
m_VideoStats->renderedFrames++;
av_frame_free(&frame);
// If a frame has arrived while rendering, our renderer probably
// was blocked waiting on V-Sync. Drop a frame to allow the
// queued frame to drain.
// Drop frames if we have too many queued up for a while
m_FrameQueueLock.lock();
if (!m_RenderQueue.isEmpty()) {
frame = m_RenderQueue.dequeue();
int frameDropTarget = 0;
for (int queueHistoryEntry : m_RenderQueueHistory) {
if (queueHistoryEntry == 0) {
// Be lenient as long as the queue length
// resolves before the end of frame history
frameDropTarget = 2;
break;
}
}
// Keep a rolling 500 ms window of render queue history
if (m_RenderQueueHistory.count() == m_MaxVideoFps / 2) {
m_RenderQueueHistory.dequeue();
}
m_RenderQueueHistory.enqueue(m_RenderQueue.count());
// Catch up if we're several frames ahead
while (m_RenderQueue.count() > frameDropTarget) {
AVFrame* frame = m_RenderQueue.dequeue();
// Drop the lock while we call av_frame_free()
m_FrameQueueLock.unlock();
m_VideoStats->pacerDroppedFrames++;
av_frame_free(&frame);
m_FrameQueueLock.lock();
}
else {
m_FrameQueueLock.unlock();
}
m_FrameQueueLock.unlock();
}
void Pacer::submitFrame(AVFrame* frame)

View file

@ -34,6 +34,7 @@ private:
QQueue<AVFrame*> m_RenderQueue;
QQueue<AVFrame*> m_PacingQueue;
QQueue<int> m_PacingQueueHistory;
QQueue<int> m_RenderQueueHistory;
QMutex m_FrameQueueLock;
QWaitCondition m_RenderQueueNotEmpty;
QWaitCondition m_PacingQueueNotEmpty;