From 7d260277521b27d9a259e0c09a67def31c556fd6 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Tue, 28 May 2019 14:24:48 +1000 Subject: [PATCH] [c-host] resend the last on client reconnect if a timeout occurs --- VERSION | 2 +- .../platform/Windows/capture/DXGI/src/dxgi.c | 7 +-- .../Windows/capture/NVFBC/src/nvfbc.c | 7 +-- c-host/src/app.c | 57 +++++++++++++------ 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/VERSION b/VERSION index 78c38d26..5949baca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -B1-rc3-5-gb31e8e1cee+1 \ No newline at end of file +B1-rc3-6-g3d426ccef8+1 \ No newline at end of file diff --git a/c-host/platform/Windows/capture/DXGI/src/dxgi.c b/c-host/platform/Windows/capture/DXGI/src/dxgi.c index 56ef3f15..827749a4 100644 --- a/c-host/platform/Windows/capture/DXGI/src/dxgi.c +++ b/c-host/platform/Windows/capture/DXGI/src/dxgi.c @@ -774,11 +774,8 @@ static CaptureResult dxgi_getFrame(CaptureFrame * frame) assert(this->initialized); Texture * tex = &this->texture[this->texRIndex]; - if (!os_waitEvent(tex->mapped, TIMEOUT_INFINITE)) - { - DEBUG_ERROR("Failed to wait on the texture map event"); - return CAPTURE_RESULT_ERROR; - } + if (!os_waitEvent(tex->mapped, 1000)) + return CAPTURE_RESULT_TIMEOUT; if (this->stop) return CAPTURE_RESULT_REINIT; diff --git a/c-host/platform/Windows/capture/NVFBC/src/nvfbc.c b/c-host/platform/Windows/capture/NVFBC/src/nvfbc.c index dd8a88f3..8c76f138 100644 --- a/c-host/platform/Windows/capture/NVFBC/src/nvfbc.c +++ b/c-host/platform/Windows/capture/NVFBC/src/nvfbc.c @@ -238,11 +238,8 @@ static CaptureResult nvfbc_capture() static CaptureResult nvfbc_getFrame(CaptureFrame * frame) { - if (!os_waitEvent(this->frameEvent, TIMEOUT_INFINITE)) - { - DEBUG_ERROR("Failed to wait on the frame event"); - return CAPTURE_RESULT_ERROR; - } + if (!os_waitEvent(this->frameEvent, 1000)) + return CAPTURE_RESULT_TIMEOUT; if (this->stop) return CAPTURE_RESULT_REINIT; diff --git a/c-host/src/app.c b/c-host/src/app.c index e3e4c9e5..4c925a0f 100644 --- a/c-host/src/app.c +++ b/c-host/src/app.c @@ -86,13 +86,14 @@ static int pointerThread(void * opaque) case CAPTURE_RESULT_REINIT: { app.reinit = true; - break; + DEBUG_INFO("Pointer thread reinit"); + return 0; } case CAPTURE_RESULT_ERROR: { DEBUG_ERROR("Failed to get the pointer"); - break; + return 0; } case CAPTURE_RESULT_TIMEOUT: @@ -155,29 +156,50 @@ static int frameThread(void * opaque) { DEBUG_INFO("Frame thread started"); - int frameIndex = 0; volatile KVMFRFrame * fi = &(app.shmHeader->frame); + bool frameValid = false; + int frameIndex = 0; + unsigned int clientInstance = 0; + CaptureFrame frame = { 0 }; + while(app.running) { - CaptureResult result; - CaptureFrame frame = - { - .data = app.frame[frameIndex] - }; + frame.data = app.frame[frameIndex]; - result = app.iface->getFrame(&frame); - if (result == CAPTURE_RESULT_REINIT) + switch(app.iface->getFrame(&frame)) { - app.reinit = true; - break; + case CAPTURE_RESULT_OK: + break; + + case CAPTURE_RESULT_REINIT: + { + app.reinit = true; + DEBUG_INFO("Frame thread reinit"); + return 0; + } + + case CAPTURE_RESULT_ERROR: + { + DEBUG_ERROR("Failed to get the frame"); + return 0; + } + + case CAPTURE_RESULT_TIMEOUT: + { + if (frameValid && clientInstance != app.clientInstance) + { + // resend the last frame + if (--frameIndex < 0) + frameIndex = MAX_FRAMES - 1; + break; + } + + continue; + } } - if (result == CAPTURE_RESULT_ERROR) - { - DEBUG_ERROR("Failed to get the frame"); - break; - } + clientInstance = app.clientInstance; // wait for the client to finish with the previous frame while(fi->flags & KVMFR_FRAME_FLAG_UPDATE && app.running) @@ -199,6 +221,7 @@ static int frameThread(void * opaque) fi->stride = frame.stride; fi->pitch = frame.pitch; fi->dataPos = app.frameOffset[frameIndex]; + frameValid = true; INTERLOCKED_OR8(&fi->flags, KVMFR_FRAME_FLAG_UPDATE);