From daf5f6e4ed1c3c06d256d587feccbc9757601639 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Tue, 16 Jun 2020 08:56:33 +0300
Subject: [PATCH] Mostly working sender test

---
 components/rgbd-sources/CMakeLists.txt        |  1 +
 components/rgbd-sources/src/init.cpp          | 16 ++++
 components/rgbd-sources/src/source.cpp        |  1 -
 components/streams/test/CMakeLists.txt        | 24 +++---
 components/streams/test/receiver_unit.cpp     | 16 ++--
 components/streams/test/sender_unit.cpp       | 82 ++++++++++++-------
 .../structures/include/ftl/data/channels.hpp  |  6 +-
 .../include/ftl/data/new_frameset.hpp         |  2 +
 components/structures/src/frameset.cpp        |  7 ++
 components/structures/src/new_frame.cpp       | 35 +++++---
 10 files changed, 125 insertions(+), 65 deletions(-)
 create mode 100644 components/rgbd-sources/src/init.cpp

diff --git a/components/rgbd-sources/CMakeLists.txt b/components/rgbd-sources/CMakeLists.txt
index 30f9cb3cb..4238c5755 100644
--- a/components/rgbd-sources/CMakeLists.txt
+++ b/components/rgbd-sources/CMakeLists.txt
@@ -11,6 +11,7 @@ set(RGBDSRC
 	#src/abr.cpp
 	src/sources/screencapture/screencapture.cpp
 	src/camera.cpp
+	src/init.cpp
 )
 
 if (HAVE_REALSENSE)
diff --git a/components/rgbd-sources/src/init.cpp b/components/rgbd-sources/src/init.cpp
new file mode 100644
index 000000000..4633d3e93
--- /dev/null
+++ b/components/rgbd-sources/src/init.cpp
@@ -0,0 +1,16 @@
+#include <ftl/data/new_frame.hpp>
+#include <ftl/rgbd/camera.hpp>
+#include <ftl/codecs/channels.hpp>
+
+using ftl::codecs::Channel;
+using ftl::data::StorageMode;
+
+bool ftl_video_init =
+	ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Calibration, "calibration", ftl::data::StorageMode::PERSISTENT) &&
+	ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Pose, "pose", ftl::data::StorageMode::PERSISTENT) &&
+	ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Calibration2, "calibration_right", ftl::data::StorageMode::PERSISTENT) &&
+	ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Name, "name", ftl::data::StorageMode::PERSISTENT);
+
+bool ftl_video_initialised() {
+	return ftl_video_init;
+}
diff --git a/components/rgbd-sources/src/source.cpp b/components/rgbd-sources/src/source.cpp
index 4ca4534df..6adedd3e8 100644
--- a/components/rgbd-sources/src/source.cpp
+++ b/components/rgbd-sources/src/source.cpp
@@ -31,7 +31,6 @@ using ftl::codecs::Channel;
 //using ftl::rgbd::detail::FileSource;
 using ftl::rgbd::Camera;
 
-
 Source::Source(ftl::config::json_t &cfg) : Configurable(cfg), pose_(Eigen::Matrix4d::Identity()), net_(nullptr) {
 	impl_ = nullptr;
 	//params_ = {};
diff --git a/components/streams/test/CMakeLists.txt b/components/streams/test/CMakeLists.txt
index fb22160de..d0f2c8a82 100644
--- a/components/streams/test/CMakeLists.txt
+++ b/components/streams/test/CMakeLists.txt
@@ -36,19 +36,19 @@ add_test(FileStreamUnitTest filestream_unit)
 #add_test(NetStreamUnitTest netstream_unit)
 
 ### Sender Unit ################################################################
-#add_executable(sender_unit
-#$<TARGET_OBJECTS:CatchTest>
-#	./sender_unit.cpp
-#	../src/sender.cpp
-#	../src/stream.cpp
-#	../src/injectors.cpp
-#	../src/parsers.cpp
-#)
-#target_include_directories(sender_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include")
-#target_link_libraries(sender_unit
-#	ftlcommon ftlcodecs ftlrgbd ftlaudio)
+add_executable(sender_unit
+$<TARGET_OBJECTS:CatchTest>
+	./sender_unit.cpp
+	../src/sender.cpp
+	../src/stream.cpp
+	../src/injectors.cpp
+	../src/parsers.cpp
+)
+target_include_directories(sender_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include")
+target_link_libraries(sender_unit
+	ftlcommon ftlcodecs ftlrgbd ftlaudio)
 
-#add_test(SenderUnitTest sender_unit)
+add_test(SenderUnitTest sender_unit)
 
 ### Receiver Unit ##############################################################
 add_executable(receiver_unit
diff --git a/components/streams/test/receiver_unit.cpp b/components/streams/test/receiver_unit.cpp
index 567fffeb8..240f1d92c 100644
--- a/components/streams/test/receiver_unit.cpp
+++ b/components/streams/test/receiver_unit.cpp
@@ -19,6 +19,8 @@ using ftl::codecs::Channels;
 using ftl::config::json_t;
 using ftl::data::FrameID;
 
+extern bool ftl_video_initialised();
+
 class TestStream : public ftl::stream::Stream {
 	public:
 	explicit TestStream(nlohmann::json &config) : ftl::stream::Stream(config) {};
@@ -54,7 +56,9 @@ class TestStream : public ftl::stream::Stream {
 
 
 TEST_CASE( "Receiver generating onFrameSet" ) {
-	ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Calibration, "calibration", ftl::data::StorageMode::PERSISTENT);
+	ftl_video_initialised();
+
+	//ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Calibration, "calibration", ftl::data::StorageMode::PERSISTENT);
 	json_t global = json_t{{"$id","ftl://test"}};
 	ftl::config::configure(global);
 
@@ -253,11 +257,11 @@ TEST_CASE( "Receiver generating onFrameSet" ) {
 	//while (ftl::pool.n_idle() != ftl::pool.size()) std::this_thread::sleep_for(std::chrono::milliseconds(10));
 	delete receiver;
 	//ftl::config::cleanup();
-	ftl::data::clearRegistry();
+	//ftl::data::clearRegistry();
 }
 
 TEST_CASE( "Receiver sync bugs" ) {
-	ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Calibration, "calibration", ftl::data::StorageMode::PERSISTENT);
+	//ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Calibration, "calibration", ftl::data::StorageMode::PERSISTENT);
 	json_t global = json_t{{"$id","ftl://test"}};
 	ftl::config::configure(global);
 
@@ -342,11 +346,11 @@ TEST_CASE( "Receiver sync bugs" ) {
 	ftl::timer::stop(true);
 	//while (ftl::pool.n_idle() != ftl::pool.size()) std::this_thread::sleep_for(std::chrono::milliseconds(10));
 	delete receiver;
-	ftl::data::clearRegistry();
+	//ftl::data::clearRegistry();
 }
 
 TEST_CASE( "Receiver non zero buffer" ) {
-	ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Calibration, "calibration", ftl::data::StorageMode::PERSISTENT);
+	//ftl::data::make_channel<ftl::rgbd::Camera>(Channel::Calibration, "calibration", ftl::data::StorageMode::PERSISTENT);
 	json_t global = json_t{{"$id","ftl://test"}};
 	ftl::config::configure(global);
 
@@ -420,5 +424,5 @@ TEST_CASE( "Receiver non zero buffer" ) {
 	ftl::timer::stop(true);
 	//while (ftl::pool.n_idle() != ftl::pool.size()) std::this_thread::sleep_for(std::chrono::milliseconds(10));
 	delete receiver;
-	ftl::data::clearRegistry();
+	//ftl::data::clearRegistry();
 }
diff --git a/components/streams/test/sender_unit.cpp b/components/streams/test/sender_unit.cpp
index 8e646957d..538b582d6 100644
--- a/components/streams/test/sender_unit.cpp
+++ b/components/streams/test/sender_unit.cpp
@@ -2,14 +2,17 @@
 
 #include <ftl/streams/sender.hpp>
 #include <ftl/codecs/hevc.hpp>
+#include <ftl/data/framepool.hpp>
 
 #include <nlohmann/json.hpp>
 
+#include <loguru.hpp>
+
 using ftl::codecs::definition_t;
 using ftl::codecs::codec_t;
 using ftl::stream::Sender;
-using ftl::rgbd::Frame;
-using ftl::rgbd::FrameSet;
+using ftl::data::Frame;
+using ftl::data::FrameSet;
 using ftl::codecs::Channel;
 using ftl::codecs::Channels;
 using ftl::config::json_t;
@@ -64,9 +67,11 @@ TEST_CASE( "Sender::post() video frames" ) {
 	};
 	auto *sender = ftl::create<Sender>(cfg);
 	
-	FrameSet fs;
-	fs.frames.emplace_back();
-	fs.timestamp = 1000;
+	ftl::data::Pool pool(4,6);
+	Frame f = pool.allocate(ftl::data::FrameID(0,0), 1000);
+	f.store();
+	auto fsptr = FrameSet::fromFrame(f);
+	FrameSet &fs = *fsptr;
 
 	json_t cfg2 = json_t{
 		{"$id","ftl://test/2"}
@@ -90,9 +95,9 @@ TEST_CASE( "Sender::post() video frames" ) {
 		fs.count = 1;
 		fs.mask = 1;
 		fs.frames[0].create<cv::cuda::GpuMat>(Channel::Colour).create(cv::Size(1280,720), CV_8UC4);
-		fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
+		fs.frames[0].set<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
 
-		sender->post(fs);
+		sender->post(fs, Channel::Colour);
 
 		REQUIRE( count == 1 );
 		REQUIRE( spkt.version == 4 );
@@ -109,15 +114,17 @@ TEST_CASE( "Sender::post() video frames" ) {
 	SECTION("two colour frames tiled") {
 		stream.select(0, Channels(Channel::Colour), true);
 
+		fs.resize(2);
+		fs.frames[1].store();
+
 		fs.count = 2;
 		fs.mask = 3;
 		fs.frames[0].create<cv::cuda::GpuMat>(Channel::Colour).create(cv::Size(1280,720), CV_8UC4);
-		fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
-		fs.frames.emplace_back();
+		fs.frames[0].set<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
 		fs.frames[1].create<cv::cuda::GpuMat>(Channel::Colour).create(cv::Size(1280,720), CV_8UC4);
-		fs.frames[1].get<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
+		fs.frames[1].set<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
 
-		sender->post(fs);
+		sender->post(fs, Channel::Colour);
 
 		REQUIRE( count == 1 );
 		REQUIRE( spkt.version == 4 );
@@ -134,15 +141,17 @@ TEST_CASE( "Sender::post() video frames" ) {
 	SECTION("two depth frames tiled") {
 		stream.select(0, Channels(Channel::Depth), true);
 
+		fs.resize(2);
+		fs.frames[1].store();
+
 		fs.count = 2;
 		fs.mask = 3;
 		fs.frames[0].create<cv::cuda::GpuMat>(Channel::Depth).create(cv::Size(1280,720), CV_32F);
-		fs.frames[0].get<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
-		fs.frames.emplace_back();
+		fs.frames[0].set<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
 		fs.frames[1].create<cv::cuda::GpuMat>(Channel::Depth).create(cv::Size(1280,720), CV_32F);
-		fs.frames[1].get<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
+		fs.frames[1].set<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
 
-		sender->post(fs);
+		sender->post(fs, Channel::Depth);
 
 		REQUIRE( count == 1 );
 		REQUIRE( spkt.version == 4 );
@@ -160,18 +169,20 @@ TEST_CASE( "Sender::post() video frames" ) {
 	SECTION("10 depth frames tiled") {
 		stream.select(0, Channels(Channel::Depth), true);
 
+		fs.resize(10);
+
 		fs.count = 10;
 		fs.mask = 0x3FF;
 		fs.frames[0].create<cv::cuda::GpuMat>(Channel::Depth).create(cv::Size(1280,720), CV_32F);
-		fs.frames[0].get<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
+		fs.frames[0].set<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
 
 		for (int i=1; i<10; ++i) {
-			fs.frames.emplace_back();
+			fs.frames[i].store();
 			fs.frames[i].create<cv::cuda::GpuMat>(Channel::Depth).create(cv::Size(1280,720), CV_32F);
-			fs.frames[i].get<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
+			fs.frames[i].set<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
 		}
 
-		sender->post(fs);
+		sender->post(fs, Channel::Depth);
 
 		REQUIRE( count == 2 );
 		REQUIRE( spkt.version == 4 );
@@ -189,16 +200,18 @@ TEST_CASE( "Sender::post() video frames" ) {
 	SECTION("two lossless depth frames tiled") {
 		stream.select(0, Channels(Channel::Depth), true);
 
+		fs.resize(2);
+		fs.frames[1].store();
+
 		fs.count = 2;
 		fs.mask = 3;
 		fs.frames[0].create<cv::cuda::GpuMat>(Channel::Depth).create(cv::Size(1280,720), CV_32F);
-		fs.frames[0].get<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
-		fs.frames.emplace_back();
+		fs.frames[0].set<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
 		fs.frames[1].create<cv::cuda::GpuMat>(Channel::Depth).create(cv::Size(1280,720), CV_32F);
-		fs.frames[1].get<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
+		fs.frames[1].set<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
 
 		sender->set("codec", (int)codec_t::HEVC_LOSSLESS);
-		sender->post(fs);
+		sender->post(fs, Channel::Depth);
 
 		REQUIRE( count == 1 );
 		REQUIRE( spkt.version == 4 );
@@ -219,11 +232,12 @@ TEST_CASE( "Sender::post() video frames" ) {
 		fs.count = 1;
 		fs.mask = 1;
 		fs.frames[0].create<cv::cuda::GpuMat>(Channel::Colour).create(cv::Size(1280,720), CV_8UC4);
-		fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
+		fs.frames[0].set<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
 		fs.frames[0].create<cv::cuda::GpuMat>(Channel::Depth).create(cv::Size(1280,720), CV_32F);
-		fs.frames[0].get<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
+		fs.frames[0].set<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
 
-		sender->post(fs);
+		sender->post(fs, Channel::Colour);
+		sender->post(fs, Channel::Depth);
 
 		REQUIRE( count == 2 );
 		REQUIRE( spkt.version == 4 );
@@ -250,9 +264,11 @@ TEST_CASE( "Sender request to control encoding" ) {
 	};
 	auto *sender = ftl::create<Sender>(cfg);
 	
-	FrameSet fs;
-	fs.frames.emplace_back();
-	fs.timestamp = 1000;
+	ftl::data::Pool pool(4,6);
+	Frame f = pool.allocate(ftl::data::FrameID(0,0), 1000);
+	f.store();
+	auto fsptr = FrameSet::fromFrame(f);
+	FrameSet &fs = *fsptr;
 
 	json_t cfg2 = json_t{
 		{"$id","ftl://test/2"}
@@ -271,6 +287,7 @@ TEST_CASE( "Sender request to control encoding" ) {
 	});
 
 	SECTION("a single colour frame request") {
+		try {
 		//stream.select(0, Channels(Channel::Colour), true);
 
 		stream.post({
@@ -282,10 +299,10 @@ TEST_CASE( "Sender request to control encoding" ) {
 		fs.count = 1;
 		fs.mask = 1;
 		fs.frames[0].create<cv::cuda::GpuMat>(Channel::Colour).create(cv::Size(1280,720), CV_8UC4);
-		fs.frames[0].get<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
+		fs.frames[0].set<cv::cuda::GpuMat>(Channel::Colour).setTo(cv::Scalar(0));
 
 		count = 0;
-		sender->post(fs);
+		sender->post(fs, Channel::Colour);
 
 		REQUIRE( count == 5 );
 		REQUIRE( spkt.version == 4 );
@@ -297,5 +314,8 @@ TEST_CASE( "Sender request to control encoding" ) {
 		REQUIRE( pkt.data.size() > 0 );
 		REQUIRE( pkt.frame_count == 1 );
 		REQUIRE( ftl::codecs::hevc::validNAL(pkt.data.data(), pkt.data.size()) );
+		} catch (const ftl::exception &e) {
+			LOG(ERROR) << e.trace();
+		}
 	}
 }
diff --git a/components/structures/include/ftl/data/channels.hpp b/components/structures/include/ftl/data/channels.hpp
index 0f2b79b77..ab041c0ec 100644
--- a/components/structures/include/ftl/data/channels.hpp
+++ b/components/structures/include/ftl/data/channels.hpp
@@ -82,14 +82,16 @@ ftl::codecs::Channel getChannelByName(const std::string &name);
  * Helper to register a channel using a template specified type.
  */
 template <typename T>
-void make_channel(ftl::codecs::Channel c, const std::string &name, StorageMode mode) {
+bool make_channel(ftl::codecs::Channel c, const std::string &name, StorageMode mode) {
 	// TODO: Generate packer + unpacker?
 	registerChannel(c, {name, mode, typeid(T).hash_code()});
+	return true;
 }
 
 template <>
-inline void make_channel<void>(ftl::codecs::Channel c, const std::string &name, StorageMode mode) {
+inline bool make_channel<void>(ftl::codecs::Channel c, const std::string &name, StorageMode mode) {
 	registerChannel(c, {name, mode, 0});
+	return true;
 }
 
 }
diff --git a/components/structures/include/ftl/data/new_frameset.hpp b/components/structures/include/ftl/data/new_frameset.hpp
index 29e04d38d..95d80377c 100644
--- a/components/structures/include/ftl/data/new_frameset.hpp
+++ b/components/structures/include/ftl/data/new_frameset.hpp
@@ -87,6 +87,8 @@ class FrameSet : public ftl::data::Frame {
 	 */
 	void flush(ftl::codecs::Channel);
 
+	void resize(size_t s);
+
 	/**
 	 * Make a frameset from a single frame. It borrows the pool, id and
 	 * timestamp from the frame and creates a wrapping frameset instance.
diff --git a/components/structures/src/frameset.cpp b/components/structures/src/frameset.cpp
index 8df74adfb..44584d131 100644
--- a/components/structures/src/frameset.cpp
+++ b/components/structures/src/frameset.cpp
@@ -8,6 +8,13 @@ FrameSet::FrameSet(Pool *ppool, FrameID pid, int64_t ts) : Frame(ppool->allocate
 
 }
 
+void ftl::data::FrameSet::resize(size_t s) {
+	while (frames.size() < s) {
+		frames.push_back(std::move(pool()->allocate(FrameID(frameset(), frames.size()), timestamp())));
+	}
+	while (frames.size() > s) frames.pop_back();
+}
+
 void ftl::data::FrameSet::moveTo(ftl::data::FrameSet &fs) {
 	//UNIQUE_LOCK(fs.mtx, lk);
 	std::unique_lock<std::mutex> lk(fs.mutex());  // FIXME: was a shared mutex
diff --git a/components/structures/src/new_frame.cpp b/components/structures/src/new_frame.cpp
index 4e9b5b340..ae56a7a20 100644
--- a/components/structures/src/new_frame.cpp
+++ b/components/structures/src/new_frame.cpp
@@ -11,48 +11,57 @@ using ftl::data::FrameStatus;
 #define LOGURU_REPLACE_GLOG 1
 #include <loguru.hpp>
 
-static std::unordered_map<ftl::codecs::Channel, ChannelConfig> reg_channels;
+static std::unordered_map<ftl::codecs::Channel, ChannelConfig> *reg_channels=nullptr;
 
 void ftl::data::registerChannel(ftl::codecs::Channel c, const ChannelConfig &config) {
-	auto i = reg_channels.find(c);
-	if (i != reg_channels.end()) {
+	if (!reg_channels) reg_channels = new std::unordered_map<ftl::codecs::Channel, ChannelConfig>;
+
+	auto i = reg_channels->find(c);
+	if (i != reg_channels->end()) {
 		if (i->second.mode == config.mode && i->second.type_id == config.type_id && i->second.name == config.name) {
 			return;
 		}
 		throw FTL_Error("Channel " << static_cast<unsigned int>(c) << " already registered");
 	}
 
-	reg_channels[c] = config;
+	(*reg_channels)[c] = config;
 }
 
 void ftl::data::clearRegistry() {
-	reg_channels.clear();
+	if (!reg_channels) return;
+	reg_channels->clear();
 }
 
 bool ftl::data::isPersistent(ftl::codecs::Channel c) {
-	auto i = reg_channels.find(c);
-	return (i != reg_channels.end()) ? i->second.mode == StorageMode::PERSISTENT : false;
+	if (!reg_channels) return false;
+	auto i = reg_channels->find(c);
+	return (i != reg_channels->end()) ? i->second.mode == StorageMode::PERSISTENT : false;
 }
 
 bool ftl::data::isAggregate(ftl::codecs::Channel c) {
-	auto i = reg_channels.find(c);
-	return (i != reg_channels.end()) ? i->second.mode == StorageMode::AGGREGATE : false;
+	if (!reg_channels) return false;
+	auto i = reg_channels->find(c);
+	return (i != reg_channels->end()) ? i->second.mode == StorageMode::AGGREGATE : false;
 }
 
 size_t ftl::data::getChannelType(ftl::codecs::Channel c) {
-	auto i = reg_channels.find(c);
-	return (i != reg_channels.end()) ? i->second.type_id : 0;
+	if (!reg_channels) return 0;
+	auto i = reg_channels->find(c);
+	return (i != reg_channels->end()) ? i->second.type_id : 0;
 }
 
 std::string ftl::data::getChannelName(ftl::codecs::Channel c) {
-	auto i = reg_channels.find(c);
-	return (i != reg_channels.end()) ? i->second.name : "";
+	if (!reg_channels) return "";
+	auto i = reg_channels->find(c);
+	return (i != reg_channels->end()) ? i->second.name : "";
 }
 
 ftl::codecs::Channel ftl::data::getChannelByName(const std::string &name) {
 	return ftl::codecs::Channel::Colour;
 }
 
+//==============================================================================
+
 Frame::~Frame() {
 	if (status_ == FrameStatus::CREATED) store();
 	if (status_ == FrameStatus::STORED) flush();
-- 
GitLab