diff --git a/app/streaming/session.cpp b/app/streaming/session.cpp index 8cca5d7b..1556bb69 100644 --- a/app/streaming/session.cpp +++ b/app/streaming/session.cpp @@ -112,14 +112,14 @@ void Session::clRumble(unsigned short controllerNumber, unsigned short lowFreqMo bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds, SDL_Window* window, int videoFormat, int width, int height, - int frameRate, bool enableVsync, bool enableFramePacing, IVideoDecoder*& chosenDecoder) + int frameRate, bool enableVsync, bool enableFramePacing, bool testOnly, IVideoDecoder*& chosenDecoder) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "V-sync %s", enableVsync ? "enabled" : "disabled"); #ifdef HAVE_SLVIDEO - chosenDecoder = new SLVideoDecoder(); + chosenDecoder = new SLVideoDecoder(testOnly); if (CALL_INITIALIZE(chosenDecoder)) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "SLVideo video decoder chosen"); @@ -134,7 +134,7 @@ bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds, #endif #ifdef HAVE_FFMPEG - chosenDecoder = new FFmpegVideoDecoder(); + chosenDecoder = new FFmpegVideoDecoder(testOnly); if (CALL_INITIALIZE(chosenDecoder)) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "FFmpeg-based video decoder chosen"); @@ -230,7 +230,7 @@ bool Session::isHardwareDecodeAvailable(StreamingPreferences::VideoDecoderSelect return false; } - if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, true, false, decoder)) { + if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, true, false, true, decoder)) { SDL_DestroyWindow(window); SDL_QuitSubSystem(SDL_INIT_VIDEO); return false; @@ -270,7 +270,7 @@ int Session::getDecoderCapabilities(StreamingPreferences::VideoDecoderSelection return false; } - if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, true, false, decoder)) { + if (!chooseDecoder(vds, window, videoFormat, width, height, frameRate, true, false, true, decoder)) { SDL_DestroyWindow(window); SDL_QuitSubSystem(SDL_INIT_VIDEO); return false; @@ -1152,6 +1152,7 @@ void Session::exec(int displayOriginX, int displayOriginY) m_ActiveVideoHeight, m_ActiveVideoFrameRate, enableVsync, enableVsync && m_Preferences->framePacing, + false, s_ActiveSession->m_VideoDecoder)) { SDL_AtomicUnlock(&m_DecoderLock); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, diff --git a/app/streaming/session.h b/app/streaming/session.h index 0a7fb52d..58ecc91e 100644 --- a/app/streaming/session.h +++ b/app/streaming/session.h @@ -83,6 +83,7 @@ private: 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 diff --git a/app/streaming/video/ffmpeg.cpp b/app/streaming/video/ffmpeg.cpp index a925c5df..f7c30058 100644 --- a/app/streaming/video/ffmpeg.cpp +++ b/app/streaming/video/ffmpeg.cpp @@ -59,7 +59,7 @@ enum AVPixelFormat FFmpegVideoDecoder::ffGetFormat(AVCodecContext* context, return AV_PIX_FMT_NONE; } -FFmpegVideoDecoder::FFmpegVideoDecoder() +FFmpegVideoDecoder::FFmpegVideoDecoder(bool testOnly) : m_VideoDecoderCtx(nullptr), m_DecodeBuffer(1024 * 1024, 0), m_HwDecodeCfg(nullptr), @@ -68,7 +68,8 @@ FFmpegVideoDecoder::FFmpegVideoDecoder() m_Pacer(nullptr), m_LastFrameNumber(0), m_StreamFps(0), - m_NeedsSpsFixup(false) + m_NeedsSpsFixup(false), + m_TestOnly(testOnly) { av_init_packet(&m_Pkt); @@ -105,13 +106,22 @@ void FFmpegVideoDecoder::reset() delete m_Renderer; m_Renderer = nullptr; - logVideoStats(m_GlobalVideoStats, "Global video stats"); + if (!m_TestOnly) { + logVideoStats(m_GlobalVideoStats, "Global video stats"); + } + else { + // Test-only decoders can't have any frames submitted + SDL_assert(m_GlobalVideoStats.totalFrames == 0); + } } bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* window, int videoFormat, int width, int height, - int maxFps, bool enableFramePacing, bool testOnly) + int maxFps, bool enableFramePacing, bool testFrame) { + // In test-only mode, we should only see test frames + SDL_assert(!m_TestOnly || testFrame); + auto vsyncConstraint = m_Renderer->getFramePacingConstraint(); if (vsyncConstraint == IFFmpegRenderer::PACING_FORCE_OFF && enableFramePacing) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, @@ -129,9 +139,13 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi } m_StreamFps = maxFps; - m_Pacer = new Pacer(m_Renderer, &m_ActiveWndVideoStats); - if (!m_Pacer->initialize(window, maxFps, enableFramePacing)) { - return false; + + // Don't bother initializing Pacer if we're not actually going to render + if (!testFrame) { + m_Pacer = new Pacer(m_Renderer, &m_ActiveWndVideoStats); + if (!m_Pacer->initialize(window, maxFps, enableFramePacing)) { + return false; + } } m_VideoDecoderCtx = avcodec_alloc_context3(decoder); @@ -189,7 +203,7 @@ bool FFmpegVideoDecoder::completeInitialization(AVCodec* decoder, SDL_Window* wi // our minds on the selected video codec, so we'll do a trial run // now to see if things will actually work when the video stream // comes in. - if (testOnly) { + if (testFrame) { if (videoFormat & VIDEO_FORMAT_MASK_H264) { m_Pkt.data = (uint8_t*)k_H264TestFrame; m_Pkt.size = sizeof(k_H264TestFrame); @@ -380,7 +394,7 @@ bool FFmpegVideoDecoder::initialize( m_Renderer = new SdlRenderer(); if (vds != StreamingPreferences::VDS_FORCE_HARDWARE && m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) && - completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, false)) { + completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, m_TestOnly)) { return true; } else { @@ -397,7 +411,13 @@ bool FFmpegVideoDecoder::initialize( m_HwDecodeCfg = config; // Initialize the hardware codec and submit a test frame if the renderer needs it if (m_Renderer->initialize(window, videoFormat, width, height, maxFps, enableVsync) && - completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, m_Renderer->needsTestFrame())) { + completeInitialization(decoder, window, videoFormat, width, height, maxFps, enableFramePacing, m_TestOnly || m_Renderer->needsTestFrame())) { + if (m_TestOnly) { + // This decoder is only for testing capabilities, so don't bother + // creating a usable renderer + return true; + } + if (m_Renderer->needsTestFrame()) { // The test worked, so now let's initialize it for real reset(); @@ -472,6 +492,8 @@ int FFmpegVideoDecoder::submitDecodeUnit(PDECODE_UNIT du) PLENTRY entry = du->bufferList; int err; + SDL_assert(!m_TestOnly); + if (!m_LastFrameNumber) { m_ActiveWndVideoStats.measurementStartTimestamp = SDL_GetTicks(); m_LastFrameNumber = du->frameNumber; diff --git a/app/streaming/video/ffmpeg.h b/app/streaming/video/ffmpeg.h index c456a897..2792211d 100644 --- a/app/streaming/video/ffmpeg.h +++ b/app/streaming/video/ffmpeg.h @@ -10,8 +10,8 @@ extern "C" { class FFmpegVideoDecoder : public IVideoDecoder { public: - FFmpegVideoDecoder(); - virtual ~FFmpegVideoDecoder(); + FFmpegVideoDecoder(bool testOnly); + virtual ~FFmpegVideoDecoder() override; virtual bool initialize(StreamingPreferences::VideoDecoderSelection vds, SDL_Window* window, int videoFormat, @@ -31,7 +31,7 @@ public: private: bool completeInitialization(AVCodec* decoder, SDL_Window* window, int videoFormat, int width, int height, - int maxFps, bool enableFramePacing, bool testOnly); + int maxFps, bool enableFramePacing, bool testFrame); void stringifyVideoStats(VIDEO_STATS& stats, char* output); @@ -63,6 +63,7 @@ private: int m_LastFrameNumber; int m_StreamFps; bool m_NeedsSpsFixup; + bool m_TestOnly; static const uint8_t k_H264TestFrame[]; static const uint8_t k_HEVCTestFrame[]; diff --git a/app/streaming/video/sl.cpp b/app/streaming/video/sl.cpp index 01d3124a..cbcfb737 100644 --- a/app/streaming/video/sl.cpp +++ b/app/streaming/video/sl.cpp @@ -1,6 +1,6 @@ #include "sl.h" -SLVideoDecoder::SLVideoDecoder() +SLVideoDecoder::SLVideoDecoder(bool) : m_VideoContext(nullptr), m_VideoStream(nullptr) { diff --git a/app/streaming/video/sl.h b/app/streaming/video/sl.h index ca7db53d..a50fd5a3 100644 --- a/app/streaming/video/sl.h +++ b/app/streaming/video/sl.h @@ -7,7 +7,7 @@ class SLVideoDecoder : public IVideoDecoder { public: - SLVideoDecoder(); + SLVideoDecoder(bool testOnly); virtual ~SLVideoDecoder(); virtual bool initialize(StreamingPreferences::VideoDecoderSelection vds, SDL_Window* window,