diff --git a/limelight-common/Connection.c b/limelight-common/Connection.c index a76b6a1..ba76343 100644 --- a/limelight-common/Connection.c +++ b/limelight-common/Connection.c @@ -2,7 +2,10 @@ #include "Platform.h" static int stage = STAGE_NONE; -static CONNECTION_LISTENER_CALLBACKS ListenerCallbacks; +static CONNECTION_LISTENER_CALLBACKS listenerCallbacks; +static CONNECTION_LISTENER_CALLBACKS originalCallbacks; + +static int alreadyTerminated = 0; static const char* stageNames[STAGE_MAX] = { "none", @@ -87,136 +90,185 @@ void LiStopConnection(void) { LC_ASSERT(stage == STAGE_NONE); } +static void ClStageStarting(int stage) +{ + originalCallbacks.stageStarting(stage); +} + +static void ClStageComplete(int stage) +{ + originalCallbacks.stageComplete(stage); +} + +static void ClStageFailed(int stage, long errorCode) +{ + originalCallbacks.stageFailed(stage, errorCode); +} + +static void ClConnectionStarted(void) +{ + originalCallbacks.connectionStarted(); +} + +static void ClConnectionTerminated(long errorCode) +{ + // Avoid recursion and issuing multiple callbacks + if (alreadyTerminated) { + return; + } + + alreadyTerminated = 1; + originalCallbacks.connectionTerminated(errorCode); +} + +void ClDisplayMessage(char* message) +{ + originalCallbacks.displayMessage(message); +} + +void ClDisplayTransientMessage(char* message) +{ + originalCallbacks.displayTransientMessage(message); +} + int LiStartConnection(IP_ADDRESS host, PSTREAM_CONFIGURATION streamConfig, PCONNECTION_LISTENER_CALLBACKS clCallbacks, PDECODER_RENDERER_CALLBACKS drCallbacks, PAUDIO_RENDERER_CALLBACKS arCallbacks, void* renderContext, int drFlags) { int err; - memcpy(&ListenerCallbacks, clCallbacks, sizeof(ListenerCallbacks)); + memcpy(&originalCallbacks, clCallbacks, sizeof(originalCallbacks)); + + listenerCallbacks.stageStarting = ClStageStarting; + listenerCallbacks.stageComplete = ClStageComplete; + listenerCallbacks.stageFailed = ClStageFailed; + listenerCallbacks.connectionStarted = ClConnectionStarted; + listenerCallbacks.connectionTerminated = ClConnectionTerminated; + listenerCallbacks.displayMessage = ClDisplayMessage; + listenerCallbacks.displayTransientMessage = ClDisplayTransientMessage; Limelog("Initializing platform..."); - ListenerCallbacks.stageStarting(STAGE_PLATFORM_INIT); + listenerCallbacks.stageStarting(STAGE_PLATFORM_INIT); err = initializePlatformSockets(); if (err != 0) { Limelog("failed: %d\n", err); - ListenerCallbacks.stageFailed(STAGE_PLATFORM_INIT, err); + listenerCallbacks.stageFailed(STAGE_PLATFORM_INIT, err); goto Cleanup; } err = initializePlatformThreads(); if (err != 0) { Limelog("failed: %d\n", err); - ListenerCallbacks.stageFailed(STAGE_PLATFORM_INIT, err); + listenerCallbacks.stageFailed(STAGE_PLATFORM_INIT, err); goto Cleanup; } stage++; LC_ASSERT(stage == STAGE_PLATFORM_INIT); - ListenerCallbacks.stageComplete(STAGE_PLATFORM_INIT); + listenerCallbacks.stageComplete(STAGE_PLATFORM_INIT); Limelog("done\n"); Limelog("Starting RTSP handshake..."); - ListenerCallbacks.stageStarting(STAGE_RTSP_HANDSHAKE); + listenerCallbacks.stageStarting(STAGE_RTSP_HANDSHAKE); err = performRtspHandshake(host, streamConfig); if (err != 0) { Limelog("failed: %d\n", err); - ListenerCallbacks.stageFailed(STAGE_RTSP_HANDSHAKE, err); + listenerCallbacks.stageFailed(STAGE_RTSP_HANDSHAKE, err); goto Cleanup; } stage++; LC_ASSERT(stage == STAGE_RTSP_HANDSHAKE); - ListenerCallbacks.stageComplete(STAGE_RTSP_HANDSHAKE); + listenerCallbacks.stageComplete(STAGE_RTSP_HANDSHAKE); Limelog("done\n"); Limelog("Initializing control stream..."); - ListenerCallbacks.stageStarting(STAGE_CONTROL_STREAM_INIT); - err = initializeControlStream(host, streamConfig, &ListenerCallbacks); + listenerCallbacks.stageStarting(STAGE_CONTROL_STREAM_INIT); + err = initializeControlStream(host, streamConfig, &listenerCallbacks); if (err != 0) { Limelog("failed: %d\n", err); - ListenerCallbacks.stageFailed(STAGE_CONTROL_STREAM_INIT, err); + listenerCallbacks.stageFailed(STAGE_CONTROL_STREAM_INIT, err); goto Cleanup; } stage++; LC_ASSERT(stage == STAGE_CONTROL_STREAM_INIT); - ListenerCallbacks.stageComplete(STAGE_CONTROL_STREAM_INIT); + listenerCallbacks.stageComplete(STAGE_CONTROL_STREAM_INIT); Limelog("done\n"); Limelog("Initializing video stream..."); - ListenerCallbacks.stageStarting(STAGE_VIDEO_STREAM_INIT); - initializeVideoStream(host, streamConfig, drCallbacks, &ListenerCallbacks); + listenerCallbacks.stageStarting(STAGE_VIDEO_STREAM_INIT); + initializeVideoStream(host, streamConfig, drCallbacks, &listenerCallbacks); stage++; LC_ASSERT(stage == STAGE_VIDEO_STREAM_INIT); - ListenerCallbacks.stageComplete(STAGE_VIDEO_STREAM_INIT); + listenerCallbacks.stageComplete(STAGE_VIDEO_STREAM_INIT); Limelog("done\n"); Limelog("Initializing audio stream..."); - ListenerCallbacks.stageStarting(STAGE_AUDIO_STREAM_INIT); - initializeAudioStream(host, arCallbacks, &ListenerCallbacks); + listenerCallbacks.stageStarting(STAGE_AUDIO_STREAM_INIT); + initializeAudioStream(host, arCallbacks, &listenerCallbacks); stage++; LC_ASSERT(stage == STAGE_AUDIO_STREAM_INIT); - ListenerCallbacks.stageComplete(STAGE_AUDIO_STREAM_INIT); + listenerCallbacks.stageComplete(STAGE_AUDIO_STREAM_INIT); Limelog("done\n"); Limelog("Initializing input stream..."); - ListenerCallbacks.stageStarting(STAGE_INPUT_STREAM_INIT); - initializeInputStream(host, &ListenerCallbacks, + listenerCallbacks.stageStarting(STAGE_INPUT_STREAM_INIT); + initializeInputStream(host, &listenerCallbacks, streamConfig->remoteInputAesKey, sizeof(streamConfig->remoteInputAesKey), streamConfig->remoteInputAesIv, sizeof(streamConfig->remoteInputAesIv)); stage++; LC_ASSERT(stage == STAGE_INPUT_STREAM_INIT); - ListenerCallbacks.stageComplete(STAGE_INPUT_STREAM_INIT); + listenerCallbacks.stageComplete(STAGE_INPUT_STREAM_INIT); Limelog("done\n"); Limelog("Starting control stream..."); - ListenerCallbacks.stageStarting(STAGE_CONTROL_STREAM_START); + listenerCallbacks.stageStarting(STAGE_CONTROL_STREAM_START); err = startControlStream(); if (err != 0) { Limelog("failed: %d\n", err); - ListenerCallbacks.stageFailed(STAGE_CONTROL_STREAM_START, err); + listenerCallbacks.stageFailed(STAGE_CONTROL_STREAM_START, err); goto Cleanup; } stage++; LC_ASSERT(stage == STAGE_CONTROL_STREAM_START); - ListenerCallbacks.stageComplete(STAGE_CONTROL_STREAM_START); + listenerCallbacks.stageComplete(STAGE_CONTROL_STREAM_START); Limelog("done\n"); Limelog("Starting video stream..."); - ListenerCallbacks.stageStarting(STAGE_VIDEO_STREAM_START); + listenerCallbacks.stageStarting(STAGE_VIDEO_STREAM_START); err = startVideoStream(renderContext, drFlags); if (err != 0) { Limelog("Video stream start failed: %d\n", err); - ListenerCallbacks.stageFailed(STAGE_VIDEO_STREAM_START, err); + listenerCallbacks.stageFailed(STAGE_VIDEO_STREAM_START, err); goto Cleanup; } stage++; LC_ASSERT(stage == STAGE_VIDEO_STREAM_START); - ListenerCallbacks.stageComplete(STAGE_VIDEO_STREAM_START); + listenerCallbacks.stageComplete(STAGE_VIDEO_STREAM_START); Limelog("done\n"); Limelog("Starting audio stream..."); - ListenerCallbacks.stageStarting(STAGE_AUDIO_STREAM_START); + listenerCallbacks.stageStarting(STAGE_AUDIO_STREAM_START); err = startAudioStream(); if (err != 0) { Limelog("Audio stream start failed: %d\n", err); - ListenerCallbacks.stageFailed(STAGE_AUDIO_STREAM_START, err); + listenerCallbacks.stageFailed(STAGE_AUDIO_STREAM_START, err); goto Cleanup; } stage++; LC_ASSERT(stage == STAGE_AUDIO_STREAM_START); - ListenerCallbacks.stageComplete(STAGE_AUDIO_STREAM_START); + listenerCallbacks.stageComplete(STAGE_AUDIO_STREAM_START); Limelog("done\n"); Limelog("Starting input stream..."); - ListenerCallbacks.stageStarting(STAGE_INPUT_STREAM_START); + listenerCallbacks.stageStarting(STAGE_INPUT_STREAM_START); err = startInputStream(); if (err != 0) { Limelog("Input stream start failed: %d\n", err); - ListenerCallbacks.stageFailed(STAGE_INPUT_STREAM_START, err); + listenerCallbacks.stageFailed(STAGE_INPUT_STREAM_START, err); goto Cleanup; } stage++; LC_ASSERT(stage == STAGE_INPUT_STREAM_START); - ListenerCallbacks.stageComplete(STAGE_INPUT_STREAM_START); + listenerCallbacks.stageComplete(STAGE_INPUT_STREAM_START); Limelog("done\n"); - ListenerCallbacks.connectionStarted(); + listenerCallbacks.connectionStarted(); Cleanup: return err;