#pragma once #include #include #include #include "settings/streamingpreferences.h" #include "input/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 void getDecoderInfo(SDL_Window* window, bool& isHardwareAccelerated, bool& isFullScreenOnly, QSize& maxResolution); static Session* get() { return s_ActiveSession; } Overlay::OverlayManager& getOverlayManager() { return m_OverlayManager; } signals: void stageStarting(QString stage); void stageFailed(QString stage, int errorCode); void connectionStarted(); void displayLaunchError(QString text); void displayLaunchWarning(QString text); void quitStarting(); void sessionFinished(int portTestResult); private: bool initialize(); bool validateLaunch(SDL_Window* testWindow); void emitLaunchWarning(QString text); bool populateDecoderProperties(SDL_Window* window); IAudioRenderer* createAudioRenderer(const POPUS_MULTISTREAM_CONFIGURATION opusConfig); bool testAudio(int audioConfiguration); int getAudioRendererCapabilities(int audioConfiguration); void getWindowDimensions(int& x, int& y, int& width, int& height); void toggleFullscreen(); void notifyMouseEmulationMode(bool enabled); void updateOptimalWindowDisplayMode(); static bool isHardwareDecodeAvailable(SDL_Window* window, StreamingPreferences::VideoDecoderSelection vds, int videoFormat, int width, int height, int frameRate); 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, int errorCode); static void clConnectionTerminated(int 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; AUDIO_RENDERER_CALLBACKS m_AudioCallbacks; 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_MouseEmulationRefCount; int m_TerminationErrorCode; int m_FailedStageId; int m_ActiveVideoFormat; int m_ActiveVideoWidth; int m_ActiveVideoHeight; int m_ActiveVideoFrameRate; OpusMSDecoder* m_OpusDecoder; IAudioRenderer* m_AudioRenderer; OPUS_MULTISTREAM_CONFIGURATION m_AudioConfig; int m_AudioSampleCount; Uint32 m_DropAudioEndTime; Overlay::OverlayManager m_OverlayManager; static CONNECTION_LISTENER_CALLBACKS k_ConnCallbacks; static Session* s_ActiveSession; static QSemaphore s_ActiveSessionSemaphore; };