mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2025-01-18 14:03:54 +00:00
71 lines
1.5 KiB
C++
71 lines
1.5 KiB
C++
|
#include "pacer.h"
|
||
|
|
||
|
#define FRAME_HISTORY_ENTRIES 8
|
||
|
|
||
|
Pacer::Pacer() :
|
||
|
m_FrameQueueLock(0)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
Pacer::~Pacer()
|
||
|
{
|
||
|
drain();
|
||
|
}
|
||
|
|
||
|
AVFrame* Pacer::getFrameAtVsync()
|
||
|
{
|
||
|
SDL_AtomicLock(&m_FrameQueueLock);
|
||
|
|
||
|
int frameDropTarget;
|
||
|
|
||
|
// If the queue length history entries are large, be strict
|
||
|
// about dropping excess frames.
|
||
|
frameDropTarget = 1;
|
||
|
for (int i = 0; i < m_FrameQueueHistory.count(); i++) {
|
||
|
if (m_FrameQueueHistory[i] <= 1) {
|
||
|
// Be lenient as long as the queue length
|
||
|
// resolves before the end of frame history
|
||
|
frameDropTarget = 3;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_FrameQueueHistory.count() == FRAME_HISTORY_ENTRIES) {
|
||
|
m_FrameQueueHistory.dequeue();
|
||
|
}
|
||
|
|
||
|
m_FrameQueueHistory.enqueue(m_FrameQueue.count());
|
||
|
|
||
|
// Catch up if we're several frames ahead
|
||
|
while (m_FrameQueue.count() > frameDropTarget) {
|
||
|
AVFrame* frame = m_FrameQueue.dequeue();
|
||
|
av_frame_free(&frame);
|
||
|
}
|
||
|
|
||
|
if (m_FrameQueue.isEmpty()) {
|
||
|
SDL_AtomicUnlock(&m_FrameQueueLock);
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
// Grab the first frame
|
||
|
AVFrame* frame = m_FrameQueue.dequeue();
|
||
|
SDL_AtomicUnlock(&m_FrameQueueLock);
|
||
|
|
||
|
return frame;
|
||
|
}
|
||
|
|
||
|
void Pacer::submitFrame(AVFrame* frame)
|
||
|
{
|
||
|
SDL_AtomicLock(&m_FrameQueueLock);
|
||
|
m_FrameQueue.enqueue(frame);
|
||
|
SDL_AtomicUnlock(&m_FrameQueueLock);
|
||
|
}
|
||
|
|
||
|
void Pacer::drain()
|
||
|
{
|
||
|
while (!m_FrameQueue.isEmpty()) {
|
||
|
AVFrame* frame = m_FrameQueue.dequeue();
|
||
|
av_frame_free(&frame);
|
||
|
}
|
||
|
}
|