From 185b9d7ed53ca755b27f2ce17e660d072fe6c115 Mon Sep 17 00:00:00 2001
From: Sebastian Hahta <joseha@utu.fi>
Date: Fri, 30 Aug 2019 15:33:01 +0300
Subject: [PATCH] updated interface with automatic cpu/gpu transfer

---
 .../rgbd-sources/include/ftl/rgbd/frame.hpp   | 53 ++++++++++---------
 components/rgbd-sources/src/stereovideo.cpp   | 16 +++---
 2 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/components/rgbd-sources/include/ftl/rgbd/frame.hpp b/components/rgbd-sources/include/ftl/rgbd/frame.hpp
index fa87424ad..e41d8d188 100644
--- a/components/rgbd-sources/include/ftl/rgbd/frame.hpp
+++ b/components/rgbd-sources/include/ftl/rgbd/frame.hpp
@@ -27,55 +27,57 @@ public:
 		return available_[_channelIdx(channel)];
 	}
 
-	/* @brief	Get reference to the channel data.
-	 * @param	Channel type
-	 * @param	Output parameter
-	 * @param	User of the method sets data. NOTE: Only works on unused
-	 * 			channels or if reset() was called previously (TODO).
-	 * @returns	True, if output parameter contains valid data
+	/* @brief	get reference to the channel contents
+	 * @param	channel type
+	 * @returns	const reference to channel data
 	 * 
 	 * Methods automatically copy between host/gpu if the data is only available
-	 * in the other. Results are cached.
+	 * in the other. Results are cached. Result is valid only if hasChannel() is
+	 * true.
 	 */
 
-	bool getChannel(const ftl::rgbd::channel_t& channel, cv::Mat& out, bool set=false)
+	const cv::Mat& getChannel(const ftl::rgbd::channel_t& channel)
 	{
 		auto idx = _channelIdx(channel);
-		bool retval = available_[idx] & mask_host;
-		if (!retval)
+		if (!(available_[idx] & mask_host))
 		{
 			if (available_[idx] & mask_gpu)
 			{
 				channels_gpu_[idx].download(channels_host_[idx]);
-				retval = true;
-				set = true;
+				available_[idx] |= mask_host;
 			}
 		}
 
-		if (set) { available_[idx] |= mask_host; }
+		return channels_host_[idx];
+	}
 
-		out = channels_host_[idx];
-		return retval;
+	cv::Mat& setChannel(const ftl::rgbd::channel_t& channel)
+	{
+		auto idx = _channelIdx(channel);
+		available_[idx] = mask_host;
+		return channels_host_[idx];
 	}
 
-	bool getChannel(const ftl::rgbd::channel_t& channel, cv::cuda::GpuMat& out, bool set=false)
+	const cv::cuda::GpuMat& getChannelGpu(const ftl::rgbd::channel_t& channel)
 	{
 		auto idx = _channelIdx(channel);
-		bool retval = available_[idx] & mask_gpu;
-		if (!retval)
+		if (!(available_[idx] & mask_gpu))
 		{
 			if (available_[idx] & mask_host)
 			{
 				channels_gpu_[idx].upload(channels_host_[idx]);
-				retval = true;
-				set = true;
+				available_[idx] |= mask_gpu;
 			}
 		}
-
-		if (set) { available_[idx] |= mask_host; }
 		
-		out = channels_gpu_[idx];
-		return retval;
+		return channels_gpu_[idx];
+	}
+
+	cv::cuda::GpuMat& setChannelGpu(const ftl::rgbd::channel_t& channel)
+	{
+		auto idx = _channelIdx(channel);
+		available_[idx] = mask_gpu;
+		return channels_gpu_[idx];
 	}
 
 private:
@@ -94,7 +96,8 @@ private:
 			case kChanConfidence:		return 7;
 			case kChanFlow:				return 8;
 			case kChanEnergy:			return 9;
-			default:					return 0; // should not happen (error)
+			// should not happen (error); returned index is kChanNone
+			default:					return 0;
 		}
 	}
 
diff --git a/components/rgbd-sources/src/stereovideo.cpp b/components/rgbd-sources/src/stereovideo.cpp
index a4c19767c..75ed21230 100644
--- a/components/rgbd-sources/src/stereovideo.cpp
+++ b/components/rgbd-sources/src/stereovideo.cpp
@@ -173,9 +173,8 @@ bool StereoVideoSource::capture(int64_t ts) {
 bool StereoVideoSource::retrieve() {
 	auto &frame = frames_[0];
 	frame.reset();
-	cv::cuda::GpuMat left, right;
-	frame.getChannel(ftl::rgbd::kChanLeft, left, true);
-	frame.getChannel(ftl::rgbd::kChanRight, right, true);
+	auto &left = frame.setChannelGpu(ftl::rgbd::kChanLeft);
+	auto &right = frame.setChannelGpu(ftl::rgbd::kChanRight);
 	lsrc_->get(left, right, calib_, stream2_);
 
 #ifdef HAVE_OPTFLOW
@@ -209,18 +208,15 @@ void StereoVideoSource::swap() {
 
 bool StereoVideoSource::compute(int n, int b) {
 	auto &frame = frames_[1];
-	cv::cuda::GpuMat left, right, disp, depth;
-	frame.getChannel(ftl::rgbd::kChanLeft, left);
-	frame.getChannel(ftl::rgbd::kChanRight, right);
+	auto &left = frame.getChannelGpu(ftl::rgbd::kChanLeft);
+	auto &right = frame.getChannelGpu(ftl::rgbd::kChanRight);
 
 	const ftl::rgbd::channel_t chan = host_->getChannel();
 	if (left.empty() || right.empty()) return false;
 
-
-
 	if (chan == ftl::rgbd::kChanDepth) {
-		frame.getChannel(ftl::rgbd::kChanDepth, depth, true);
-		frame.getChannel(ftl::rgbd::kChanDisparity, disp, true);
+		auto &depth = frame.setChannelGpu(ftl::rgbd::kChanDepth);
+		auto &disp = frame.setChannelGpu(ftl::rgbd::kChanDisparity);
 
 		if (depth.empty()) depth = cv::cuda::GpuMat(left.size(), CV_32FC1);
 		if (disp.empty()) disp = cv::cuda::GpuMat(left.size(), CV_32FC1);
-- 
GitLab