From e071e15ce28c85ee95773398ddb7f0afbe8e06c5 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Thu, 20 Aug 2020 16:16:34 +0300
Subject: [PATCH] Fix for receiver error handling

---
 components/renderers/cpp/src/clipping.cu          | 13 ++++++++-----
 .../streams/include/ftl/streams/receiver.hpp      |  1 +
 components/streams/src/receiver.cpp               | 15 +++++++++++++++
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/components/renderers/cpp/src/clipping.cu b/components/renderers/cpp/src/clipping.cu
index 016e08855..d73e7a50b 100644
--- a/components/renderers/cpp/src/clipping.cu
+++ b/components/renderers/cpp/src/clipping.cu
@@ -27,12 +27,15 @@ __global__ void clipping_kernel(ftl::cuda::TextureObject<float> depth, ftl::cuda
 	const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
 	const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
 
-	if (x < depth.width() && y < depth.height()) {
-		float d = depth(x,y);
-		float4 p = make_float4(camera.screenToCam(x,y,d), 0.0f);
+	const float sx = float(x) / float(colour.width()) * float(depth.width());
+	const float sy = float(y) / float(colour.height()) * float(depth.height());
+
+	if (sx >= 0.0f && sx < depth.width() && sy < depth.height() && sy >= 0.0f) {
+		float d = depth(sx,sy);
+		float4 p = make_float4(camera.screenToCam(sx,sy,d), 0.0f);
 
 		if (d <= camera.minDepth || d >= camera.maxDepth || isClipped(p, clip)) {
-			depth(x,y) = 0.0f;
+			depth(sx,sy) = 0.0f;
 			colour(x,y) = make_uchar4(0,0,0,0);
 		}
 	}
@@ -54,7 +57,7 @@ void ftl::cuda::clipping(ftl::cuda::TextureObject<float> &depth,
 		const ftl::rgbd::Camera &camera,
 		const ClipSpace &clip, cudaStream_t stream) {
 
-	const dim3 gridSize((depth.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth.height() + T_PER_BLOCK - 1)/T_PER_BLOCK);
+	const dim3 gridSize((colour.width() + T_PER_BLOCK - 1)/T_PER_BLOCK, (colour.height() + T_PER_BLOCK - 1)/T_PER_BLOCK);
 	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
 
 	clipping_kernel<<<gridSize, blockSize, 0, stream>>>(depth, colour, camera, clip);
diff --git a/components/streams/include/ftl/streams/receiver.hpp b/components/streams/include/ftl/streams/receiver.hpp
index 7febc9e41..07f90efee 100644
--- a/components/streams/include/ftl/streams/receiver.hpp
+++ b/components/streams/include/ftl/streams/receiver.hpp
@@ -93,6 +93,7 @@ class Receiver : public ftl::Configurable, public ftl::data::Generator {
 	InternalVideoStates &_getVideoFrame(const ftl::codecs::StreamPacket &spkt, int ix=0);
 	InternalAudioStates &_getAudioFrame(const ftl::codecs::StreamPacket &spkt, int ix=0);
 	void _finishPacket(ftl::streams::LockedFrameSet &fs, size_t fix);
+	void _terminateVideoPacket(const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt);
 };
 
 }
diff --git a/components/streams/src/receiver.cpp b/components/streams/src/receiver.cpp
index 9775d184e..b53fc49a7 100644
--- a/components/streams/src/receiver.cpp
+++ b/components/streams/src/receiver.cpp
@@ -247,6 +247,15 @@ namespace sgm {
 	}
 }
 
+void Receiver::_terminateVideoPacket(const StreamPacket &spkt, const Packet &pkt) {
+	auto &build = builder(spkt.streamID);
+	auto fs = build.get(spkt.timestamp, spkt.frame_number+pkt.frame_count-1);
+	if (fs) {
+		fs->localTimestamp = spkt.localTimestamp;
+		_finishPacket(fs, spkt.frame_number);
+	}
+}
+
 void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) {
 	FTL_Profile("VideoPacket", 0.02);
 
@@ -257,6 +266,7 @@ void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) {
 
 	if (tx == 0 || ty == 0) {
 		LOG(ERROR) << "No Packets";
+		_terminateVideoPacket(spkt, pkt);
 		return;
 	}
 
@@ -268,6 +278,7 @@ void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) {
 	auto *decoder = ividstate.decoders[channum];
 	if (!decoder) {
 		LOG(ERROR) << "No frame decoder available";
+		_terminateVideoPacket(spkt, pkt);
 		return;
 	}
 
@@ -276,10 +287,12 @@ void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) {
 		FTL_Profile("Decode", 0.015);
 		if (!decoder->decode(pkt, surface)) {
 			LOG(ERROR) << "Decode failed on channel " << (int)spkt.channel;
+			_terminateVideoPacket(spkt, pkt);
 			return;
 		}
 	} catch (std::exception &e) {
 		LOG(ERROR) << "Decode failed for " << spkt.timestamp << ": " << e.what();
+		_terminateVideoPacket(spkt, pkt);
 		return;
 	}
 
@@ -288,6 +301,7 @@ void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) {
 
 	if (width == 0 || height == 0) {
 		LOG(ERROR) << "Invalid decoded size: " << surface.cols << "x" << surface.rows << " (" << tx << "," << ty << ")";
+		_terminateVideoPacket(spkt, pkt);
 		return;
 	}
 
@@ -295,6 +309,7 @@ void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) {
 
 	if (surface.type() != cvtype) {
 		LOG(ERROR) << "Invalid video format received";
+		_terminateVideoPacket(spkt, pkt);
 		return;
 	}
 
-- 
GitLab