mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-06-17 06:11:03 +00:00
Add HDR mode APIs
This commit is contained in:
@@ -49,6 +49,7 @@ static int lastSeenFrame;
|
|||||||
static bool stopping;
|
static bool stopping;
|
||||||
static bool disconnectPending;
|
static bool disconnectPending;
|
||||||
static bool encryptedControlStream;
|
static bool encryptedControlStream;
|
||||||
|
static bool hdrEnabled;
|
||||||
|
|
||||||
static int intervalGoodFrameCount;
|
static int intervalGoodFrameCount;
|
||||||
static int intervalTotalFrameCount;
|
static int intervalTotalFrameCount;
|
||||||
@@ -76,6 +77,7 @@ static PPLT_CRYPTO_CONTEXT decryptionCtx;
|
|||||||
#define IDX_INPUT_DATA 5
|
#define IDX_INPUT_DATA 5
|
||||||
#define IDX_RUMBLE_DATA 6
|
#define IDX_RUMBLE_DATA 6
|
||||||
#define IDX_TERMINATION 7
|
#define IDX_TERMINATION 7
|
||||||
|
#define IDX_HDR_INFO 8
|
||||||
|
|
||||||
#define CONTROL_STREAM_TIMEOUT_SEC 10
|
#define CONTROL_STREAM_TIMEOUT_SEC 10
|
||||||
#define CONTROL_STREAM_LINGER_TIMEOUT_SEC 2
|
#define CONTROL_STREAM_LINGER_TIMEOUT_SEC 2
|
||||||
@@ -89,6 +91,7 @@ static const short packetTypesGen3[] = {
|
|||||||
-1, // Input data (unused)
|
-1, // Input data (unused)
|
||||||
-1, // Rumble data (unused)
|
-1, // Rumble data (unused)
|
||||||
-1, // Termination (unused)
|
-1, // Termination (unused)
|
||||||
|
-1, // HDR mode (unused)
|
||||||
};
|
};
|
||||||
static const short packetTypesGen4[] = {
|
static const short packetTypesGen4[] = {
|
||||||
0x0606, // Request IDR frame
|
0x0606, // Request IDR frame
|
||||||
@@ -99,6 +102,7 @@ static const short packetTypesGen4[] = {
|
|||||||
-1, // Input data (unused)
|
-1, // Input data (unused)
|
||||||
-1, // Rumble data (unused)
|
-1, // Rumble data (unused)
|
||||||
-1, // Termination (unused)
|
-1, // Termination (unused)
|
||||||
|
-1, // HDR mode (unused)
|
||||||
};
|
};
|
||||||
static const short packetTypesGen5[] = {
|
static const short packetTypesGen5[] = {
|
||||||
0x0305, // Start A
|
0x0305, // Start A
|
||||||
@@ -109,6 +113,7 @@ static const short packetTypesGen5[] = {
|
|||||||
0x0207, // Input data
|
0x0207, // Input data
|
||||||
-1, // Rumble data (unused)
|
-1, // Rumble data (unused)
|
||||||
-1, // Termination (unused)
|
-1, // Termination (unused)
|
||||||
|
-1, // HDR mode (unknown)
|
||||||
};
|
};
|
||||||
static const short packetTypesGen7[] = {
|
static const short packetTypesGen7[] = {
|
||||||
0x0305, // Start A
|
0x0305, // Start A
|
||||||
@@ -119,6 +124,7 @@ static const short packetTypesGen7[] = {
|
|||||||
0x0206, // Input data
|
0x0206, // Input data
|
||||||
0x010b, // Rumble data
|
0x010b, // Rumble data
|
||||||
0x0100, // Termination
|
0x0100, // Termination
|
||||||
|
0x010e, // HDR mode
|
||||||
};
|
};
|
||||||
static const short packetTypesGen7Enc[] = {
|
static const short packetTypesGen7Enc[] = {
|
||||||
0x0302, // Request IDR frame
|
0x0302, // Request IDR frame
|
||||||
@@ -129,6 +135,7 @@ static const short packetTypesGen7Enc[] = {
|
|||||||
0x0206, // Input data
|
0x0206, // Input data
|
||||||
0x010b, // Rumble data
|
0x010b, // Rumble data
|
||||||
0x0109, // Termination (extended)
|
0x0109, // Termination (extended)
|
||||||
|
0x010e, // HDR mode
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char requestIdrFrameGen3[] = { 0, 0 };
|
static const char requestIdrFrameGen3[] = { 0, 0 };
|
||||||
@@ -267,6 +274,7 @@ int initializeControlStream(void) {
|
|||||||
usePeriodicPing = APP_VERSION_AT_LEAST(7, 1, 415);
|
usePeriodicPing = APP_VERSION_AT_LEAST(7, 1, 415);
|
||||||
encryptionCtx = PltCreateCryptoContext();
|
encryptionCtx = PltCreateCryptoContext();
|
||||||
decryptionCtx = PltCreateCryptoContext();
|
decryptionCtx = PltCreateCryptoContext();
|
||||||
|
hdrEnabled = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -799,6 +807,19 @@ static void controlReceiveThreadFunc(void* context) {
|
|||||||
|
|
||||||
ListenerCallbacks.rumble(controllerNumber, lowFreqRumble, highFreqRumble);
|
ListenerCallbacks.rumble(controllerNumber, lowFreqRumble, highFreqRumble);
|
||||||
}
|
}
|
||||||
|
else if (ctlHdr->type == packetTypes[IDX_HDR_INFO]) {
|
||||||
|
BYTE_BUFFER bb;
|
||||||
|
uint8_t enableByte;
|
||||||
|
|
||||||
|
BbInitializeWrappedBuffer(&bb, (char*)ctlHdr, sizeof(*ctlHdr), packetLength - sizeof(*ctlHdr), BYTE_ORDER_LITTLE);
|
||||||
|
|
||||||
|
// FIXME: There are 7 additional bytes that appear to always be all zeros. What do they mean?
|
||||||
|
// Is there some way that GFE tells us the HDR mastering metadata (NV_HDR_COLOR_DATA) set by the game?
|
||||||
|
BbGet8(&bb, &enableByte);
|
||||||
|
|
||||||
|
hdrEnabled = (enableByte != 0);
|
||||||
|
ListenerCallbacks.setHdrMode(hdrEnabled);
|
||||||
|
}
|
||||||
else if (ctlHdr->type == packetTypes[IDX_TERMINATION]) {
|
else if (ctlHdr->type == packetTypes[IDX_TERMINATION]) {
|
||||||
BYTE_BUFFER bb;
|
BYTE_BUFFER bb;
|
||||||
|
|
||||||
@@ -1396,3 +1417,7 @@ int startControlStream(void) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LiGetCurrentHostDisplayHdrMode(void) {
|
||||||
|
return hdrEnabled;
|
||||||
|
}
|
||||||
|
|||||||
+6
-1
@@ -36,6 +36,7 @@ static void fakeClConnectionTerminated(int errorCode) {}
|
|||||||
static void fakeClLogMessage(const char* format, ...) {}
|
static void fakeClLogMessage(const char* format, ...) {}
|
||||||
static void fakeClRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor) {}
|
static void fakeClRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor) {}
|
||||||
static void fakeClConnectionStatusUpdate(int connectionStatus) {}
|
static void fakeClConnectionStatusUpdate(int connectionStatus) {}
|
||||||
|
static void fakeClSetHdrMode(bool enabled) {}
|
||||||
|
|
||||||
static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
||||||
.stageStarting = fakeClStageStarting,
|
.stageStarting = fakeClStageStarting,
|
||||||
@@ -45,7 +46,8 @@ static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
|||||||
.connectionTerminated = fakeClConnectionTerminated,
|
.connectionTerminated = fakeClConnectionTerminated,
|
||||||
.logMessage = fakeClLogMessage,
|
.logMessage = fakeClLogMessage,
|
||||||
.rumble = fakeClRumble,
|
.rumble = fakeClRumble,
|
||||||
.connectionStatusUpdate = fakeClConnectionStatusUpdate
|
.connectionStatusUpdate = fakeClConnectionStatusUpdate,
|
||||||
|
.setHdrMode = fakeClSetHdrMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_RENDERER_CALLBACKS* arCallbacks,
|
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_RENDERER_CALLBACKS* arCallbacks,
|
||||||
@@ -121,5 +123,8 @@ void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_REND
|
|||||||
if ((*clCallbacks)->connectionStatusUpdate == NULL) {
|
if ((*clCallbacks)->connectionStatusUpdate == NULL) {
|
||||||
(*clCallbacks)->connectionStatusUpdate = fakeClConnectionStatusUpdate;
|
(*clCallbacks)->connectionStatusUpdate = fakeClConnectionStatusUpdate;
|
||||||
}
|
}
|
||||||
|
if ((*clCallbacks)->setHdrMode == NULL) {
|
||||||
|
(*clCallbacks)->setHdrMode = fakeClSetHdrMode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -421,6 +421,12 @@ typedef void(*ConnListenerRumble)(unsigned short controllerNumber, unsigned shor
|
|||||||
#define CONN_STATUS_POOR 1
|
#define CONN_STATUS_POOR 1
|
||||||
typedef void(*ConnListenerConnectionStatusUpdate)(int connectionStatus);
|
typedef void(*ConnListenerConnectionStatusUpdate)(int connectionStatus);
|
||||||
|
|
||||||
|
// This callback is invoked to notify the client of a change in HDR mode on
|
||||||
|
// the host. The client will probably want to update the local display mode
|
||||||
|
// to match the state of HDR on the host. This callback may be invoked even
|
||||||
|
// if enableHdr is false in the stream configuration.
|
||||||
|
typedef void(*ConnListenerSetHdrMode)(bool hdrEnabled);
|
||||||
|
|
||||||
typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
||||||
ConnListenerStageStarting stageStarting;
|
ConnListenerStageStarting stageStarting;
|
||||||
ConnListenerStageComplete stageComplete;
|
ConnListenerStageComplete stageComplete;
|
||||||
@@ -430,6 +436,7 @@ typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
|||||||
ConnListenerLogMessage logMessage;
|
ConnListenerLogMessage logMessage;
|
||||||
ConnListenerRumble rumble;
|
ConnListenerRumble rumble;
|
||||||
ConnListenerConnectionStatusUpdate connectionStatusUpdate;
|
ConnListenerConnectionStatusUpdate connectionStatusUpdate;
|
||||||
|
ConnListenerSetHdrMode setHdrMode;
|
||||||
} CONNECTION_LISTENER_CALLBACKS, *PCONNECTION_LISTENER_CALLBACKS;
|
} CONNECTION_LISTENER_CALLBACKS, *PCONNECTION_LISTENER_CALLBACKS;
|
||||||
|
|
||||||
// Use this function to zero the connection callbacks when allocated on the stack or heap
|
// Use this function to zero the connection callbacks when allocated on the stack or heap
|
||||||
@@ -654,6 +661,10 @@ bool LiPeekNextVideoFrame(PDECODE_UNIT* decodeUnit);
|
|||||||
void LiWakeWaitForVideoFrame(void);
|
void LiWakeWaitForVideoFrame(void);
|
||||||
void LiCompleteVideoFrame(VIDEO_FRAME_HANDLE handle, int drStatus);
|
void LiCompleteVideoFrame(VIDEO_FRAME_HANDLE handle, int drStatus);
|
||||||
|
|
||||||
|
// This function returns the last reported HDR mode from the host PC.
|
||||||
|
// See ConnListenerSetHdrMode() for more details.
|
||||||
|
bool LiGetCurrentHostDisplayHdrMode(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user