diff --git a/app/settings/streamingpreferences.cpp b/app/settings/streamingpreferences.cpp index a10eab0e..d5cad9ab 100644 --- a/app/settings/streamingpreferences.cpp +++ b/app/settings/streamingpreferences.cpp @@ -91,12 +91,26 @@ int StreamingPreferences::getMaximumStreamingFrameRate() return maxFrameRate; } - for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { - SDL_DisplayMode mode; - if (SDL_GetCurrentDisplayMode(i, &mode) == 0) { + SDL_DisplayMode mode, bestMode, desktopMode; + for (int displayIndex = 0; displayIndex < SDL_GetNumVideoDisplays(); displayIndex++) { + // Get the native desktop resolution + if (SDL_GetDesktopDisplayMode(displayIndex, &desktopMode) == 0) { + + // Start at desktop mode and work our way up + bestMode = desktopMode; + for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) { + if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) { + if (mode.w == desktopMode.w && mode.h == desktopMode.h) { + if (mode.refresh_rate > bestMode.refresh_rate) { + bestMode = mode; + } + } + } + } + // Cap the frame rate at 120 FPS. Past this, the encoders start // to max out and drop frames. - maxFrameRate = qMax(maxFrameRate, qMin(120, mode.refresh_rate)); + maxFrameRate = qMax(maxFrameRate, qMin(120, bestMode.refresh_rate)); } } diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index e070a0c9..05604235 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -544,7 +544,7 @@ void Session::getWindowDimensions(bool fullScreen, else if (fullScreen) { for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { SDL_DisplayMode mode; - if (SDL_GetCurrentDisplayMode(i, &mode) == 0 && + if (SDL_GetDesktopDisplayMode(i, &mode) == 0 && m_ActiveVideoWidth == mode.w && m_ActiveVideoHeight == mode.h) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, @@ -597,6 +597,36 @@ void Session::getWindowDimensions(bool fullScreen, } } +void Session::updateOptimalWindowDisplayMode() +{ + SDL_DisplayMode desktopMode, bestMode, mode; + int displayIndex = SDL_GetWindowDisplayIndex(m_Window); + + // Get the native desktop resolution + if (SDL_GetDesktopDisplayMode(displayIndex, &desktopMode) == 0) { + // Start with the native desktop resolution and try to find + // the highest refresh rate that our stream FPS evenly divides. + bestMode = desktopMode; + bestMode.refresh_rate = 0; + for (int i = 0; i < SDL_GetNumDisplayModes(displayIndex); i++) { + if (SDL_GetDisplayMode(displayIndex, i, &mode) == 0) { + if (mode.w == desktopMode.w && mode.h == desktopMode.h && + mode.refresh_rate % m_StreamConfig.fps == 0) { + if (mode.refresh_rate > bestMode.refresh_rate) { + bestMode = mode; + } + } + } + } + + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Chosen best display mode: %dx%dx%d", + bestMode.w, bestMode.h, bestMode.refresh_rate); + + SDL_SetWindowDisplayMode(m_Window, &bestMode); + } +} + void Session::toggleFullscreen() { bool fullScreen = !(SDL_GetWindowFlags(m_Window) & m_FullScreenFlag); @@ -752,10 +782,7 @@ void Session::exec() } else { // Update the window display mode based on our current monitor - SDL_DisplayMode mode; - if (SDL_GetDesktopDisplayMode(SDL_GetWindowDisplayIndex(m_Window), &mode) == 0) { - SDL_SetWindowDisplayMode(m_Window, &mode); - } + updateOptimalWindowDisplayMode(); // Enter full screen SDL_SetWindowFullscreen(m_Window, m_FullScreenFlag); @@ -883,10 +910,7 @@ void Session::exec() SDL_FlushEvent(SDL_WINDOWEVENT); // Update the window display mode based on our current monitor - SDL_DisplayMode mode; - if (SDL_GetDesktopDisplayMode(SDL_GetWindowDisplayIndex(m_Window), &mode) == 0) { - SDL_SetWindowDisplayMode(m_Window, &mode); - } + updateOptimalWindowDisplayMode(); // Now that the old decoder is dead, flush any events it may // have queued to reset itself (if this reset was the result diff --git a/app/streaming/session.hpp b/app/streaming/session.hpp index 2639fb8e..e5f51c45 100644 --- a/app/streaming/session.hpp +++ b/app/streaming/session.hpp @@ -57,6 +57,8 @@ private: void toggleFullscreen(); + void updateOptimalWindowDisplayMode(); + static bool chooseDecoder(StreamingPreferences::VideoDecoderSelection vds, SDL_Window* window, int videoFormat, int width, int height, diff --git a/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp b/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp index bb8b9d31..c42f3077 100644 --- a/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp +++ b/app/streaming/video/ffmpeg-renderers/pacer/pacer.cpp @@ -132,10 +132,27 @@ bool Pacer::initialize(SDL_Window* window, int maxVideoFps, bool enableVsync) } SDL_DisplayMode mode; - if (SDL_GetCurrentDisplayMode(displayIndex, &mode) == 0) { - // May be zero if undefined - m_DisplayFps = mode.refresh_rate; + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN) { + // Use the window display mode for full-screen exclusive mode + if (SDL_GetWindowDisplayMode(window, &mode) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL_GetWindowDisplayMode() failed: %s", + SDL_GetError()); + return false; + } } + else { + // Use the current display mode for windowed and borderless + if (SDL_GetCurrentDisplayMode(displayIndex, &mode) != 0) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL_GetCurrentDisplayMode() failed: %s", + SDL_GetError()); + return false; + } + } + + // May be zero if undefined + m_DisplayFps = mode.refresh_rate; if (m_EnableVsync) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,