Add a connection status callback to notify when the connection becomes lossy

This commit is contained in:
Cameron Gutman 2019-03-17 01:37:09 -07:00
parent 4a7d28038d
commit 71a69204e9
3 changed files with 47 additions and 0 deletions

View File

@ -37,9 +37,17 @@ static long lastSeenFrame;
static int stopping;
static int disconnectPending;
static int intervalGoodFrameCount;
static int intervalTotalFrameCount;
static uint64_t intervalStartTimeMs;
static int lastConnectionStatusUpdate;
static int idrFrameRequired;
static LINKED_BLOCKING_QUEUE invalidReferenceFrameTuples;
#define CONN_POOR_LOSS_RATE 40
#define CONN_OKAY_LOSS_RATE 5
#define IDX_START_A 0
#define IDX_REQUEST_IDR_FRAME 0
#define IDX_START_B 1
@ -190,6 +198,10 @@ int initializeControlStream(void) {
lastSeenFrame = 0;
lossCountSinceLastReport = 0;
disconnectPending = 0;
intervalGoodFrameCount = 0;
intervalTotalFrameCount = 0;
intervalStartTimeMs = 0;
lastConnectionStatusUpdate = CONN_STATUS_OKAY;
return 0;
}
@ -257,9 +269,31 @@ void connectionDetectedFrameLoss(int startFrame, int endFrame) {
// When we receive a frame, update the number of our current frame
void connectionReceivedCompleteFrame(int frameIndex) {
lastGoodFrame = frameIndex;
intervalGoodFrameCount++;
}
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;
}

View File

@ -35,6 +35,7 @@ static void fakeClConnectionStarted(void) {}
static void fakeClConnectionTerminated(long errorCode) {}
static void fakeClLogMessage(const char* format, ...) {}
static void fakeClRumble(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor) {}
static void fakeClConnectionStatusUpdate(int connectionStatus) {}
static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
.stageStarting = fakeClStageStarting,
@ -44,6 +45,7 @@ static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = {
.connectionTerminated = fakeClConnectionTerminated,
.logMessage = fakeClLogMessage,
.rumble = fakeClRumble,
.connectionStatusUpdate = fakeClConnectionStatusUpdate
};
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) {
(*clCallbacks)->rumble = fakeClRumble;
}
if ((*clCallbacks)->connectionStatusUpdate == NULL) {
(*clCallbacks)->connectionStatusUpdate = fakeClConnectionStatusUpdate;
}
}
}

View File

@ -304,6 +304,13 @@ typedef void(*ConnListenerLogMessage)(const char* format, ...);
// physically present, so your callback should handle this possibility.
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 {
ConnListenerStageStarting stageStarting;
ConnListenerStageComplete stageComplete;
@ -314,6 +321,7 @@ typedef struct _CONNECTION_LISTENER_CALLBACKS {
void* deprecated2; // was displayTransientMessage()
ConnListenerLogMessage logMessage;
ConnListenerRumble rumble;
ConnListenerConnectionStatusUpdate connectionStatusUpdate;
} CONNECTION_LISTENER_CALLBACKS, *PCONNECTION_LISTENER_CALLBACKS;
// Use this function to zero the connection callbacks when allocated on the stack or heap