From c1020f924a071d714cac5141e54d7cd42a3791e9 Mon Sep 17 00:00:00 2001
From: Iiro Rastas <iitara@utu.fi>
Date: Mon, 9 Dec 2019 17:04:40 +0200
Subject: [PATCH] Fix reconstruction recording from the GUI

Reconstruction recording can again be started by using the GUI buttons.
Taking a reconstrution snapshot no longer crashes the application, but
it's still not functional.
---
 applications/reconstruct/src/main.cpp | 44 ++++++++++++---------------
 1 file changed, 20 insertions(+), 24 deletions(-)

diff --git a/applications/reconstruct/src/main.cpp b/applications/reconstruct/src/main.cpp
index ad14c1288..0f45f363e 100644
--- a/applications/reconstruct/src/main.cpp
+++ b/applications/reconstruct/src/main.cpp
@@ -233,7 +233,9 @@ static void run(ftl::Configurable *root) {
 	//ftl::voxhash::SceneRep *scene = ftl::create<ftl::voxhash::SceneRep>(root, "voxelhash");
 	ftl::rgbd::Streamer *stream = ftl::create<ftl::rgbd::Streamer>(root, "stream", net);
 	ftl::rgbd::VirtualSource *vs = ftl::create<ftl::rgbd::VirtualSource>(root, "virtual");
-	//root->set("tags", nlohmann::json::array({ root->getID()+"/virtual" }));
+	auto tags = root->value<std::vector<std::string>>("tags", nlohmann::json::array({}));
+	tags.push_back(root->getID()+"/virtual");
+	root->set("tags", tags);
 
 	int o = root->value("origin_pose", 0) % sources.size();
 	vs->setPose(sources[o]->getPose());
@@ -269,19 +271,29 @@ static void run(ftl::Configurable *root) {
 
 	root->set("record", false);
 
+	int64_t timestamp = 0;
+	std::vector<std::pair<ftl::codecs::StreamPacket, ftl::codecs::Packet>> currentFrame, completeFrame;
 	// Add a recording callback to all reconstruction scenes
 	for (size_t i=0; i<sources.size(); ++i) {
-		sources[i]->addRawCallback([&writer,&groups,i](ftl::rgbd::Source *src, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) {
+		sources[i]->addRawCallback([&writer,&groups,&timestamp,&currentFrame,&completeFrame,i](ftl::rgbd::Source *src, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) {
 			ftl::codecs::StreamPacket s = spkt;
 
 			// Patch stream ID to match order in group
 			s.streamID = i;
 			writer.write(s, pkt);
+
+			if (s.timestamp > timestamp) {
+				timestamp = s.timestamp;
+				completeFrame = currentFrame;
+				currentFrame = std::vector<std::pair<ftl::codecs::StreamPacket, ftl::codecs::Packet>>({ std::make_pair(s, pkt) });
+			} else if (s.timestamp == timestamp) {
+				currentFrame.push_back(std::make_pair(s, pkt));
+			}
 		});
 	}
 
 	// Allow stream recording
-	root->on("record", [&groups,&fileout,&writer,&sources](const ftl::config::Event &e) {
+	root->on("record", [&fileout,&writer,&sources](const ftl::config::Event &e) {
 		if (e.entity->value("record", false)) {
 			char timestamp[18];
 			std::time_t t=std::time(NULL);
@@ -306,7 +318,7 @@ static void run(ftl::Configurable *root) {
 	std::ofstream snapshotout;
 	ftl::codecs::Writer snapshotwriter(snapshotout);
 
-	root->on("3D-snapshot", [&group,&snapshotout,&snapshotwriter,&scene_A](const ftl::config::Event &e) {
+	root->on("3D-snapshot", [&snapshotout,&snapshotwriter,&sources,&currentFrame](const ftl::config::Event &e) {
 		char timestamp[18];
 		std::time_t t=std::time(NULL);
 		std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
@@ -314,34 +326,18 @@ static void run(ftl::Configurable *root) {
 
 		snapshotwriter.begin();
 
-		auto sources = group->sources();
 		for (size_t i=0; i<sources.size(); ++i) {
 			auto packet_pair = sources[i]->make_packet(Channel::Calibration, sources[i]->parameters(), Channel::Left, sources[i]->getCapabilities());
-			packet_pair.first.streamID = group->streamID(sources[i]);
+			packet_pair.first.streamID = i;
 			snapshotwriter.write(packet_pair.first, packet_pair.second);
 
 			packet_pair = sources[i]->make_packet(sources[i]->getPose());
-			packet_pair.first.streamID = group->streamID(sources[i]);
+			packet_pair.first.streamID = i;
 			snapshotwriter.write(packet_pair.first, packet_pair.second);
 		}
 
-		for (auto &frame : scene_A.frames) {
-			// Write frames of each source as std::vector<uint8_t>.
-			frame.download(Channel::Left);
-			cv::Mat image = frame.get<cv::Mat>(Channel::Left);
-			cv::Mat flat = image.reshape(1, image.total()*image.channels());
-			std::vector<uint8_t> vec = image.isContinuous()? flat : flat.clone();
-			auto packet_pair = frame.source()->make_packet(Channel::Left, vec);
-			packet_pair.first.streamID = group->streamID(frame.source());
-			snapshotwriter.write(packet_pair.first, packet_pair.second);
-
-			frame.download(Channel::Depth);
-			image = frame.get<cv::Mat>(Channel::Depth);
-			flat = image.reshape(1, image.total()*image.channels());
-			vec = image.isContinuous()? flat : flat.clone();
-			packet_pair = frame.source()->make_packet(Channel::Depth, vec);
-			packet_pair.first.streamID = group->streamID(frame.source());
-			snapshotwriter.write(packet_pair.first, packet_pair.second);
+		for (auto &p : currentFrame) {
+			snapshotwriter.write(p.first, p.second);
 		}
 
 		snapshotwriter.end();
-- 
GitLab