From 6b0f1aecc5df5dc8caac9cf6e90089c14cea77c5 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 13 May 2015 21:51:33 -0500 Subject: [PATCH] Allow callers of LiStartConnection() to omit passing callbacks they don't need --- limelight-common/Connection.c | 49 ++---- limelight-common/FakeCallbacks.c | 140 ++++++++++++++++++ limelight-common/Limelight-internal.h | 3 + limelight-common/limelight-common.vcxproj | 1 + .../limelight-common.vcxproj.filters | 3 + 5 files changed, 156 insertions(+), 40 deletions(-) create mode 100644 limelight-common/FakeCallbacks.c diff --git a/limelight-common/Connection.c b/limelight-common/Connection.c index f6e94c8..75d5e3d 100644 --- a/limelight-common/Connection.c +++ b/limelight-common/Connection.c @@ -3,7 +3,7 @@ static int stage = STAGE_NONE; static CONNECTION_LISTENER_CALLBACKS listenerCallbacks; -static CONNECTION_LISTENER_CALLBACKS originalCallbacks; +static ConnListenerConnectionTerminated originalTerminationCallback; // This is used for debug prints so it's not declared static PLATFORM_CALLBACKS platformCallbacks; @@ -101,26 +101,6 @@ void LiStopConnection(void) { LC_ASSERT(stage == STAGE_NONE); } -static void ClInternalStageStarting(int stage) -{ - originalCallbacks.stageStarting(stage); -} - -static void ClInternalStageComplete(int stage) -{ - originalCallbacks.stageComplete(stage); -} - -static void ClInternalStageFailed(int stage, long errorCode) -{ - originalCallbacks.stageFailed(stage, errorCode); -} - -static void ClInternalConnectionStarted(void) -{ - originalCallbacks.connectionStarted(); -} - static void ClInternalConnectionTerminated(long errorCode) { // Avoid recursion and issuing multiple callbacks @@ -129,17 +109,7 @@ static void ClInternalConnectionTerminated(long errorCode) } alreadyTerminated = 1; - originalCallbacks.connectionTerminated(errorCode); -} - -void ClInternalDisplayMessage(char* message) -{ - originalCallbacks.displayMessage(message); -} - -void ClInternalDisplayTransientMessage(char* message) -{ - originalCallbacks.displayTransientMessage(message); + originalTerminationCallback(errorCode); } void LiCompleteThreadStart(void) @@ -155,16 +125,15 @@ int LiStartConnection(IP_ADDRESS host, PSTREAM_CONFIGURATION streamConfig, PCONN serverMajorVersion = _serverMajorVersion; - memcpy(&originalCallbacks, clCallbacks, sizeof(originalCallbacks)); + // Replace missing callbacks with placeholders + fixupMissingCallbacks(&drCallbacks, &arCallbacks, &clCallbacks, &plCallbacks); memcpy(&platformCallbacks, plCallbacks, sizeof(platformCallbacks)); - - listenerCallbacks.stageStarting = ClInternalStageStarting; - listenerCallbacks.stageComplete = ClInternalStageComplete; - listenerCallbacks.stageFailed = ClInternalStageFailed; - listenerCallbacks.connectionStarted = ClInternalConnectionStarted; + + // Hook the termination callback so we can avoid issuing a termination callback + // after LiStopConnection() is called + originalTerminationCallback = clCallbacks->connectionTerminated; + memcpy(&listenerCallbacks, clCallbacks, sizeof(listenerCallbacks)); listenerCallbacks.connectionTerminated = ClInternalConnectionTerminated; - listenerCallbacks.displayMessage = ClInternalDisplayMessage; - listenerCallbacks.displayTransientMessage = ClInternalDisplayTransientMessage; alreadyTerminated = 0; diff --git a/limelight-common/FakeCallbacks.c b/limelight-common/FakeCallbacks.c new file mode 100644 index 0000000..3b8205d --- /dev/null +++ b/limelight-common/FakeCallbacks.c @@ -0,0 +1,140 @@ +#include "Limelight-internal.h" + +static void fakeDrSetup(int width, int height, int redrawRate, void* context, int drFlags) {} +static void fakeDrStart(void) {} +static void fakeDrStop(void) {} +static void fakeDrRelease(void) {} +static int fakeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) { return DR_OK; } + +static DECODER_RENDERER_CALLBACKS fakeDrCallbacks = { + .setup = fakeDrSetup, + .start = fakeDrStart, + .stop = fakeDrStop, + .release = fakeDrRelease, + .submitDecodeUnit = fakeDrSubmitDecodeUnit, +}; + +static void fakeArInit(void) {} +static void fakeArStart(void) {} +static void fakeArStop(void) {} +static void fakeArRelease(void) {} +static void fakeArDecodeAndPlaySample(char* sampleData, int sampleLength) {} + +AUDIO_RENDERER_CALLBACKS fakeArCallbacks = { + .init = fakeArInit, + .start = fakeArStart, + .stop = fakeArStop, + .release = fakeArRelease, + .decodeAndPlaySample = fakeArDecodeAndPlaySample, +}; + +static void fakeClStageStarting(int stage) {} +static void fakeClStageComplete(int stage) {} +static void fakeClStageFailed(int stage, long errorCode) {} +static void fakeClConnectionStarted(void) {} +static void fakeClConnectionTerminated(long errorCode) {} +static void fakeClDisplayMessage(char* message) {} +static void fakeClDisplayTransientMessage(char* message) {} + +static CONNECTION_LISTENER_CALLBACKS fakeClCallbacks = { + .stageStarting = fakeClStageStarting, + .stageComplete = fakeClStageComplete, + .stageFailed = fakeClStageFailed, + .connectionStarted = fakeClConnectionStarted, + .connectionTerminated = fakeClConnectionTerminated, + .displayMessage = fakeClDisplayMessage, + .displayTransientMessage = fakeClDisplayTransientMessage, +}; + +static void fakePlThreadStart(void) {} +static void fakePlDebugPrint(char* string) {} + +static PLATFORM_CALLBACKS fakePlCallbacks = { + .threadStart = fakePlThreadStart, + .debugPrint = fakePlDebugPrint, +}; + +void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS *drCallbacks, PAUDIO_RENDERER_CALLBACKS *arCallbacks, + PCONNECTION_LISTENER_CALLBACKS *clCallbacks, PPLATFORM_CALLBACKS *plCallbacks) +{ + if (*drCallbacks == NULL) { + *drCallbacks = &fakeDrCallbacks; + } + else { + if ((*drCallbacks)->setup == NULL) { + (*drCallbacks)->setup = fakeDrSetup; + } + if ((*drCallbacks)->start == NULL) { + (*drCallbacks)->start = fakeDrStart; + } + if ((*drCallbacks)->stop == NULL) { + (*drCallbacks)->stop = fakeDrStop; + } + if ((*drCallbacks)->release == NULL) { + (*drCallbacks)->release = fakeDrRelease; + } + if ((*drCallbacks)->submitDecodeUnit == NULL) { + (*drCallbacks)->submitDecodeUnit = fakeDrSubmitDecodeUnit; + } + } + + if (*arCallbacks == NULL) { + *arCallbacks = &fakeArCallbacks; + } + else { + if ((*arCallbacks)->init == NULL) { + (*arCallbacks)->init = fakeArInit; + } + if ((*arCallbacks)->start == NULL) { + (*arCallbacks)->start = fakeArStart; + } + if ((*arCallbacks)->stop == NULL) { + (*arCallbacks)->stop = fakeArStop; + } + if ((*arCallbacks)->release == NULL) { + (*arCallbacks)->release = fakeArRelease; + } + if ((*arCallbacks)->decodeAndPlaySample == NULL) { + (*arCallbacks)->decodeAndPlaySample = fakeArDecodeAndPlaySample; + } + } + + if (*clCallbacks == NULL) { + *clCallbacks = &fakeClCallbacks; + } + else { + if ((*clCallbacks)->stageStarting == NULL) { + (*clCallbacks)->stageStarting = fakeClStageStarting; + } + if ((*clCallbacks)->stageComplete == NULL) { + (*clCallbacks)->stageComplete = fakeClStageComplete; + } + if ((*clCallbacks)->stageFailed == NULL) { + (*clCallbacks)->stageFailed = fakeClStageFailed; + } + if ((*clCallbacks)->connectionStarted == NULL) { + (*clCallbacks)->connectionStarted = fakeClConnectionStarted; + } + if ((*clCallbacks)->connectionTerminated == NULL) { + (*clCallbacks)->connectionTerminated = fakeClConnectionTerminated; + } + if ((*clCallbacks)->displayMessage == NULL) { + (*clCallbacks)->displayMessage = fakeClDisplayMessage; + } + if ((*clCallbacks)->displayTransientMessage == NULL) { + (*clCallbacks)->displayTransientMessage = fakeClDisplayTransientMessage; + } + } + + if (*plCallbacks == NULL) { + *plCallbacks = &fakePlCallbacks; + } + else { + if ((*plCallbacks)->threadStart == NULL) { + (*plCallbacks)->threadStart = fakePlThreadStart; + } + if ((*plCallbacks)->debugPrint == NULL) { + (*plCallbacks)->debugPrint = fakePlDebugPrint; + } + } +} \ No newline at end of file diff --git a/limelight-common/Limelight-internal.h b/limelight-common/Limelight-internal.h index dfa8466..e1d322d 100644 --- a/limelight-common/Limelight-internal.h +++ b/limelight-common/Limelight-internal.h @@ -8,6 +8,9 @@ extern int serverMajorVersion; +void fixupMissingCallbacks(PDECODER_RENDERER_CALLBACKS *drCallbacks, PAUDIO_RENDERER_CALLBACKS *arCallbacks, + PCONNECTION_LISTENER_CALLBACKS *clCallbacks, PPLATFORM_CALLBACKS *plCallbacks); + char* getSdpPayloadForStreamConfig(PSTREAM_CONFIGURATION streamConfig, struct in_addr targetAddress, int rtspClientVersion, int *length); diff --git a/limelight-common/limelight-common.vcxproj b/limelight-common/limelight-common.vcxproj index ad60caf..85c6aa3 100644 --- a/limelight-common/limelight-common.vcxproj +++ b/limelight-common/limelight-common.vcxproj @@ -135,6 +135,7 @@ + diff --git a/limelight-common/limelight-common.vcxproj.filters b/limelight-common/limelight-common.vcxproj.filters index ec4a1b9..672f0bc 100644 --- a/limelight-common/limelight-common.vcxproj.filters +++ b/limelight-common/limelight-common.vcxproj.filters @@ -63,6 +63,9 @@ Source Files\OpenAES + + Source Files +