#pragma once #include #include #include #include "settings/streamingpreferences.h" #include "input.h" #include "video/decoder.h" #include "audio/renderers/renderer.h" #include "video/overlaymanager.h" class Session : public QObject { Q_OBJECT friend class SdlInputHandler; friend class DeferredSessionCleanupTask; public: explicit Session(NvComputer* computer, NvApp& app, StreamingPreferences *preferences = nullptr); virtual ~Session(); Q_INVOKABLE void exec(int displayOriginX, int displayOriginY); static bool isHardwareDecodeAvailable(SDL_Window* window, StreamingPreferences::VideoDecoderSelection vds, int videoFormat, int width, int height, int frameRate); static Session* get() { return s_ActiveSession; } Overlay::OverlayManager& getOverlayManager() { return m_OverlayManager; } signals: void stageStarting(QString stage); void stageFailed(QString stage, long errorCode); void connectionStarted(); void displayLaunchError(QString text); void displayLaunchWarning(QString text); void quitStarting(); void sessionFinished(); private: bool initialize(); bool validateLaunch(SDL_Window* testWindow); void emitLaunchWarning(QString text); static int getDecoderCapabilities(SDL_Window* window, StreamingPreferences::VideoDecoderSelection vds, int videoFormat, int width, int height, int frameRate); IAudioRenderer* createAudioRenderer(); int detectAudioConfiguration(); bool testAudio(int audioConfiguration); void getWindowDimensions(int& x, int& y, int& width, int& height); void toggleFullscreen(); void updateOptimalWindowDisplayMode(); static bool chooseDecoder(StreamingPreferences::VideoDecoderSelection vds, SDL_Window* window, int videoFormat, int width, int height, int frameRate, bool enableVsync, bool enableFramePacing, bool testOnly, IVideoDecoder*& chosenDecoder); static void clStageStarting(int stage); static void clStageFailed(int stage, long errorCode); static void clConnectionTerminated(long errorCode); static void clLogMessage(const char* format, ...); static void clRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor); static void clConnectionStatusUpdate(int connectionStatus); static int arInit(int audioConfiguration, const POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* arContext, int arFlags); static void arCleanup(); static void arDecodeAndPlaySample(char* sampleData, int sampleLength); static int drSetup(int videoFormat, int width, int height, int frameRate, void*, int); static void drCleanup(); static int drSubmitDecodeUnit(PDECODE_UNIT du); StreamingPreferences* m_Preferences; STREAM_CONFIGURATION m_StreamConfig; DECODER_RENDERER_CALLBACKS m_VideoCallbacks; NvComputer* m_Computer; NvApp m_App; SDL_Window* m_Window; IVideoDecoder* m_VideoDecoder; SDL_SpinLock m_DecoderLock; bool m_NeedsIdr; bool m_AudioDisabled; Uint32 m_FullScreenFlag; int m_DisplayOriginX; int m_DisplayOriginY; bool m_PendingWindowedTransition; bool m_UnexpectedTermination; SdlInputHandler* m_InputHandler; SDL_SpinLock m_InputHandlerLock; int m_ActiveVideoFormat; int m_ActiveVideoWidth; int m_ActiveVideoHeight; int m_ActiveVideoFrameRate; OpusMSDecoder* m_OpusDecoder; short m_OpusDecodeBuffer[MAX_CHANNELS * SAMPLES_PER_FRAME]; IAudioRenderer* m_AudioRenderer; OPUS_MULTISTREAM_CONFIGURATION m_AudioConfig; int m_AudioSampleCount; Uint32 m_DropAudioEndTime; Overlay::OverlayManager m_OverlayManager; static AUDIO_RENDERER_CALLBACKS k_AudioCallbacks; static CONNECTION_LISTENER_CALLBACKS k_ConnCallbacks; static Session* s_ActiveSession; static QSemaphore s_ActiveSessionSemaphore; };