Plumb HDR mode information to the decoders

This commit is contained in:
Cameron Gutman 2022-01-28 22:10:50 -06:00
parent ad0afb5fc9
commit 254526a213
8 changed files with 60 additions and 4 deletions

View file

@ -45,7 +45,8 @@ CONNECTION_LISTENER_CALLBACKS Session::k_ConnCallbacks = {
Session::clConnectionTerminated, Session::clConnectionTerminated,
Session::clLogMessage, Session::clLogMessage,
Session::clRumble, Session::clRumble,
Session::clConnectionStatusUpdate Session::clConnectionStatusUpdate,
Session::clSetHdrMode,
}; };
Session* Session::s_ActiveSession; Session* Session::s_ActiveSession;
@ -175,6 +176,20 @@ void Session::clConnectionStatusUpdate(int connectionStatus)
} }
} }
void Session::clSetHdrMode(bool enabled)
{
// If we're in the process of recreating our decoder when we get
// this callback, we'll drop it. The main thread will make the
// callback when it finishes creating the new decoder.
if (SDL_AtomicTryLock(&s_ActiveSession->m_DecoderLock)) {
IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder;
if (decoder != nullptr) {
decoder->setHdrMode(enabled);
}
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock);
}
}
bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds, bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
SDL_Window* window, int videoFormat, int width, int height, SDL_Window* window, int videoFormat, int width, int height,
int frameRate, bool enableVsync, bool enableFramePacing, bool testOnly, IVideoDecoder*& chosenDecoder) int frameRate, bool enableVsync, bool enableFramePacing, bool testOnly, IVideoDecoder*& chosenDecoder)
@ -195,6 +210,10 @@ bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
params.enableFramePacing = enableFramePacing; params.enableFramePacing = enableFramePacing;
params.vds = vds; params.vds = vds;
memset(&params.hdrMetadata, 0, sizeof(params.hdrMetadata));
params.hdrMetadata.eotf = 2; // SMPTE ST 2084
params.hdrMetadata.staticMetadataDescriptorId = 0; // Static Metadata Type 1
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"V-sync %s", "V-sync %s",
enableVsync ? "enabled" : "disabled"); enableVsync ? "enabled" : "disabled");
@ -607,8 +626,6 @@ void Session::emitLaunchWarning(QString text)
bool Session::validateLaunch(SDL_Window* testWindow) bool Session::validateLaunch(SDL_Window* testWindow)
{ {
QStringList warningList;
if (!m_Computer->isSupportedServerVersion) { if (!m_Computer->isSupportedServerVersion) {
emit displayLaunchError(tr("The version of GeForce Experience on %1 is not supported by this build of Moonlight. You must update Moonlight to stream from %1.").arg(m_Computer->name)); emit displayLaunchError(tr("The version of GeForce Experience on %1 is not supported by this build of Moonlight. You must update Moonlight to stream from %1.").arg(m_Computer->name));
return false; return false;
@ -1640,6 +1657,10 @@ void Session::execInternal()
// Request an IDR frame to complete the reset // Request an IDR frame to complete the reset
SDL_AtomicSet(&m_NeedsIdr, 1); SDL_AtomicSet(&m_NeedsIdr, 1);
// Set HDR mode. We may miss the callback if we're in the middle
// of recreating our decoder at the time the HDR transition happens.
m_VideoDecoder->setHdrMode(LiGetCurrentHostDisplayHdrMode());
SDL_AtomicUnlock(&m_DecoderLock); SDL_AtomicUnlock(&m_DecoderLock);
break; break;

View file

@ -117,6 +117,9 @@ private:
static static
void clConnectionStatusUpdate(int connectionStatus); void clConnectionStatusUpdate(int connectionStatus);
static
void clSetHdrMode(bool enabled);
static static
int arInit(int audioConfiguration, int arInit(int audioConfiguration,
const POPUS_MULTISTREAM_CONFIGURATION opusConfig, const POPUS_MULTISTREAM_CONFIGURATION opusConfig,

View file

@ -28,6 +28,23 @@ typedef struct _VIDEO_STATS {
uint32_t measurementStartTimestamp; uint32_t measurementStartTimestamp;
} VIDEO_STATS, *PVIDEO_STATS; } VIDEO_STATS, *PVIDEO_STATS;
typedef struct _HDR_MASTERING_METADATA {
uint8_t eotf;
uint8_t staticMetadataDescriptorId;
struct {
uint16_t x;
uint16_t y;
} displayPrimaries[3];
struct {
uint16_t x;
uint16_t y;
} whitePoint;
uint16_t maxDisplayMasteringLuminance;
uint16_t minDisplayMasteringLuminance;
uint16_t maxContentLightLevel;
uint16_t maxFrameAverageLightLevel;
} HDR_MASTERING_METADATA, *PHDR_MASTERING_METADATA;
typedef struct _DECODER_PARAMETERS { typedef struct _DECODER_PARAMETERS {
SDL_Window* window; SDL_Window* window;
StreamingPreferences::VideoDecoderSelection vds; StreamingPreferences::VideoDecoderSelection vds;
@ -38,6 +55,7 @@ typedef struct _DECODER_PARAMETERS {
int frameRate; int frameRate;
bool enableVsync; bool enableVsync;
bool enableFramePacing; bool enableFramePacing;
HDR_MASTERING_METADATA hdrMetadata;
} DECODER_PARAMETERS, *PDECODER_PARAMETERS; } DECODER_PARAMETERS, *PDECODER_PARAMETERS;
class IVideoDecoder { class IVideoDecoder {
@ -51,4 +69,5 @@ public:
virtual QSize getDecoderMaxResolution() = 0; virtual QSize getDecoderMaxResolution() = 0;
virtual int submitDecodeUnit(PDECODE_UNIT du) = 0; virtual int submitDecodeUnit(PDECODE_UNIT du) = 0;
virtual void renderFrameOnMainThread() = 0; virtual void renderFrameOnMainThread() = 0;
virtual void setHdrMode(bool enabled) = 0;
}; };

View file

@ -150,6 +150,10 @@ public:
return getPreferredPixelFormat(videoFormat) == pixelFormat; return getPreferredPixelFormat(videoFormat) == pixelFormat;
} }
virtual void setHdrMode(bool) {
// Nothing
}
// IOverlayRenderer // IOverlayRenderer
virtual void notifyOverlayUpdated(Overlay::OverlayType) override { virtual void notifyOverlayUpdated(Overlay::OverlayType) override {
// Nothing // Nothing

View file

@ -57,6 +57,11 @@ bool FFmpegVideoDecoder::isAlwaysFullScreen()
return m_FrontendRenderer->getRendererAttributes() & RENDERER_ATTRIBUTE_FULLSCREEN_ONLY; return m_FrontendRenderer->getRendererAttributes() & RENDERER_ATTRIBUTE_FULLSCREEN_ONLY;
} }
void FFmpegVideoDecoder::setHdrMode(bool enabled)
{
m_FrontendRenderer->setHdrMode(enabled);
}
int FFmpegVideoDecoder::getDecoderCapabilities() int FFmpegVideoDecoder::getDecoderCapabilities()
{ {
int capabilities = m_BackendRenderer->getDecoderCapabilities(); int capabilities = m_BackendRenderer->getDecoderCapabilities();

View file

@ -23,6 +23,7 @@ public:
virtual QSize getDecoderMaxResolution() override; virtual QSize getDecoderMaxResolution() override;
virtual int submitDecodeUnit(PDECODE_UNIT du) override; virtual int submitDecodeUnit(PDECODE_UNIT du) override;
virtual void renderFrameOnMainThread() override; virtual void renderFrameOnMainThread() override;
virtual void setHdrMode(bool enabled) override;
virtual IFFmpegRenderer* getBackendRenderer(); virtual IFFmpegRenderer* getBackendRenderer();

View file

@ -20,6 +20,9 @@ public:
// Unused since rendering is done directly from the decode thread // Unused since rendering is done directly from the decode thread
virtual void renderFrameOnMainThread() {} virtual void renderFrameOnMainThread() {}
// HDR is not supported by SLVideo
virtual void setHdrMode(bool) {}
private: private:
static void slLogCallback(void* context, ESLVideoLog logLevel, const char* message); static void slLogCallback(void* context, ESLVideoLog logLevel, const char* message);

@ -1 +1 @@
Subproject commit cfe75eb56952718cdf0855a813b3b7d46d920ae5 Subproject commit abc7acb5e4c219ebcb51031517b01bd266005e3a