moonlight-qt/app/streaming/video/ffmpeg-renderers/pacer/pacer.h

71 lines
1.7 KiB
C++

#pragma once
#include "../../decoder.h"
#include "../renderer.h"
#include <QQueue>
#include <QMutex>
#include <QWaitCondition>
class IVsyncSource {
public:
virtual ~IVsyncSource() {}
virtual bool initialize(SDL_Window* window, int displayFps) = 0;
// Asynchronous sources produce callbacks on their own, while synchronous
// sources require calls to waitForVsync().
virtual bool isAsync() = 0;
virtual void waitForVsync() {
// Synchronous sources must implement waitForVsync()!
SDL_assert(false);
}
};
class Pacer
{
public:
Pacer(IFFmpegRenderer* renderer, PVIDEO_STATS videoStats);
~Pacer();
void submitFrame(AVFrame* frame);
bool initialize(SDL_Window* window, int maxVideoFps, bool enablePacing);
void signalVsync();
void renderOnMainThread();
private:
static int vsyncThread(void* context);
static int renderThread(void* context);
void handleVsync(int timeUntilNextVsyncMillis);
void enqueueFrameForRenderingAndUnlock(AVFrame* frame);
void renderFrame(AVFrame* frame);
void dropFrameForEnqueue(QQueue<AVFrame*>& queue);
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;
QWaitCondition m_VsyncSignalled;
SDL_Thread* m_RenderThread;
SDL_Thread* m_VsyncThread;
bool m_Stopping;
IVsyncSource* m_VsyncSource;
IFFmpegRenderer* m_VsyncRenderer;
int m_MaxVideoFps;
int m_DisplayFps;
PVIDEO_STATS m_VideoStats;
int m_RendererAttributes;
};