mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-06-17 14:21:30 +00:00
Add a connection status callback to notify when the connection becomes lossy
This commit is contained in:
@@ -37,9 +37,17 @@ static long lastSeenFrame;
|
|||||||
static int stopping;
|
static int stopping;
|
||||||
static int disconnectPending;
|
static int disconnectPending;
|
||||||
|
|
||||||
|
static int intervalGoodFrameCount;
|
||||||
|
static int intervalTotalFrameCount;
|
||||||
|
static uint64_t intervalStartTimeMs;
|
||||||
|
static int lastConnectionStatusUpdate;
|
||||||
|
|
||||||
static int idrFrameRequired;
|
static int idrFrameRequired;
|
||||||
static LINKED_BLOCKING_QUEUE invalidReferenceFrameTuples;
|
static LINKED_BLOCKING_QUEUE invalidReferenceFrameTuples;
|
||||||
|
|
||||||
|
#define CONN_POOR_LOSS_RATE 40
|
||||||
|
#define CONN_OKAY_LOSS_RATE 5
|
||||||
|
|
||||||
#define IDX_START_A 0
|
#define IDX_START_A 0
|
||||||
#define IDX_REQUEST_IDR_FRAME 0
|
#define IDX_REQUEST_IDR_FRAME 0
|
||||||
#define IDX_START_B 1
|
#define IDX_START_B 1
|
||||||
@@ -190,6 +198,10 @@ int initializeControlStream(void) {
|
|||||||
lastSeenFrame = 0;
|
lastSeenFrame = 0;
|
||||||
lossCountSinceLastReport = 0;
|
lossCountSinceLastReport = 0;
|
||||||
disconnectPending = 0;
|
disconnectPending = 0;
|
||||||
|
intervalGoodFrameCount = 0;
|
||||||
|
intervalTotalFrameCount = 0;
|
||||||
|
intervalStartTimeMs = 0;
|
||||||
|
lastConnectionStatusUpdate = CONN_STATUS_OKAY;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -257,9 +269,31 @@ void connectionDetectedFrameLoss(int startFrame, int endFrame) {
|
|||||||
// When we receive a frame, update the number of our current frame
|
// When we receive a frame, update the number of our current frame
|
||||||
void connectionReceivedCompleteFrame(int frameIndex) {
|
void connectionReceivedCompleteFrame(int frameIndex) {
|
||||||
lastGoodFrame = frameIndex;
|
lastGoodFrame = frameIndex;
|
||||||
|
intervalGoodFrameCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connectionSawFrame(int frameIndex) {
|
void connectionSawFrame(int frameIndex) {
|
||||||
|
uint64_t now = PltGetMillis();
|
||||||
|
if (now - intervalStartTimeMs >= 1000) {
|
||||||
|
if (intervalTotalFrameCount != 0) {
|
||||||
|
// Notify the client of connection status changes based on frame loss rate
|
||||||
|
int frameLossPercent = 100 - (intervalGoodFrameCount * 100) / intervalTotalFrameCount;
|
||||||
|
if (frameLossPercent >= CONN_POOR_LOSS_RATE && lastConnectionStatusUpdate != CONN_STATUS_POOR) {
|
||||||
|
ListenerCallbacks.connectionStatusUpdate(CONN_STATUS_POOR);
|
||||||
|
lastConnectionStatusUpdate = CONN_STATUS_POOR;
|
||||||
|
}
|
||||||
|
else if (frameLossPercent <= CONN_OKAY_LOSS_RATE && lastConnectionStatusUpdate != CONN_STATUS_OKAY) {
|
||||||
|
ListenerCallbacks.connectionStatusUpdate(CONN_STATUS_OKAY);
|
||||||
|
lastConnectionStatusUpdate = CONN_STATUS_OKAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset interval
|
||||||
|
intervalStartTimeMs = now;
|
||||||
|
intervalGoodFrameCount = intervalTotalFrameCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
intervalTotalFrameCount += frameIndex - lastSeenFrame;
|
||||||
lastSeenFrame = frameIndex;
|
lastSeenFrame = frameIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ static void fakeClConnectionStarted(void) {}
|
|||||||
static void fakeClConnectionTerminated(long errorCode) {}
|
static void fakeClConnectionTerminated(long 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 CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
||||||
.stageStarting = fakeClStageStarting,
|
.stageStarting = fakeClStageStarting,
|
||||||
@@ -44,6 +45,7 @@ static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
|
|||||||
.connectionTerminated = fakeClConnectionTerminated,
|
.connectionTerminated = fakeClConnectionTerminated,
|
||||||
.logMessage = fakeClLogMessage,
|
.logMessage = fakeClLogMessage,
|
||||||
.rumble = fakeClRumble,
|
.rumble = fakeClRumble,
|
||||||
|
.connectionStatusUpdate = fakeClConnectionStatusUpdate
|
||||||
};
|
};
|
||||||
|
|
||||||
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_RENDERER_CALLBACKS* arCallbacks,
|
void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_RENDERER_CALLBACKS* arCallbacks,
|
||||||
@@ -116,5 +118,8 @@ void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS* drCallbacks, PAUDIO_REND
|
|||||||
if ((*clCallbacks)->rumble == NULL) {
|
if ((*clCallbacks)->rumble == NULL) {
|
||||||
(*clCallbacks)->rumble = fakeClRumble;
|
(*clCallbacks)->rumble = fakeClRumble;
|
||||||
}
|
}
|
||||||
|
if ((*clCallbacks)->connectionStatusUpdate == NULL) {
|
||||||
|
(*clCallbacks)->connectionStatusUpdate = fakeClConnectionStatusUpdate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -304,6 +304,13 @@ typedef void(*ConnListenerLogMessage)(const char* format, ...);
|
|||||||
// physically present, so your callback should handle this possibility.
|
// physically present, so your callback should handle this possibility.
|
||||||
typedef void(*ConnListenerRumble)(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor);
|
typedef void(*ConnListenerRumble)(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor);
|
||||||
|
|
||||||
|
// This callback is used to notify the client of a connection status change.
|
||||||
|
// Consider displaying an overlay for the user to notify them why their stream
|
||||||
|
// is not performing as expected.
|
||||||
|
#define CONN_STATUS_OKAY 0
|
||||||
|
#define CONN_STATUS_POOR 1
|
||||||
|
typedef void(*ConnListenerConnectionStatusUpdate)(int connectionStatus);
|
||||||
|
|
||||||
typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
||||||
ConnListenerStageStarting stageStarting;
|
ConnListenerStageStarting stageStarting;
|
||||||
ConnListenerStageComplete stageComplete;
|
ConnListenerStageComplete stageComplete;
|
||||||
@@ -314,6 +321,7 @@ typedef struct _CONNECTION_LISTENER_CALLBACKS {
|
|||||||
void* deprecated2; // was displayTransientMessage()
|
void* deprecated2; // was displayTransientMessage()
|
||||||
ConnListenerLogMessage logMessage;
|
ConnListenerLogMessage logMessage;
|
||||||
ConnListenerRumble rumble;
|
ConnListenerRumble rumble;
|
||||||
|
ConnListenerConnectionStatusUpdate connectionStatusUpdate;
|
||||||
} 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
|
||||||
|
|||||||
Reference in New Issue
Block a user