From 995bcebacdb35459a59b0bd3a86b95a1ac409787 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nwpope@utu.fi>
Date: Sun, 17 May 2020 14:59:05 +0300
Subject: [PATCH] Add the forcing of iframes

---
 applications/gui/src/camera.cpp                   | 11 +++++++++++
 components/codecs/src/nvpipe_encoder.cpp          |  6 +++---
 components/streams/include/ftl/streams/sender.hpp |  2 ++
 components/streams/src/sender.cpp                 | 11 ++++++++++-
 4 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/applications/gui/src/camera.cpp b/applications/gui/src/camera.cpp
index c207073c7..8686a6080 100644
--- a/applications/gui/src/camera.cpp
+++ b/applications/gui/src/camera.cpp
@@ -111,6 +111,16 @@ ftl::gui::Camera::Camera(ftl::gui::Screen *screen, int fsmask, int fid, ftl::cod
 		state_.getLeft() = ftl::rgbd::Camera::from(intrinsics_);
 		state_.getRight() = state_.getLeft();
 
+		intrinsics_->on("width", [this](const ftl::config::Event &e) {
+			state_.getLeft() = ftl::rgbd::Camera::from(intrinsics_);
+			state_.getRight() = state_.getLeft();
+		});
+
+		intrinsics_->on("focal", [this](const ftl::config::Event &e) {
+			state_.getLeft() = ftl::rgbd::Camera::from(intrinsics_);
+			state_.getRight() = state_.getLeft();
+		});
+
 		{
 			Eigen::Matrix4d pose;
 			pose.setIdentity();
@@ -831,6 +841,7 @@ void ftl::gui::Camera::startVideoRecording(const std::string &filename) {
 		record_sender_ = ftl::create<ftl::stream::Sender>(screen_->root(), "videoEncode");
 		record_sender_->setStream(record_stream_);
 		record_sender_->value("codec", 2);  // Default H264
+		record_sender_->set("iframes", 50);  // Add iframes by default
 		record_sender_->value("stereo", true);  // If both channels, then default to stereo
 	}
 
diff --git a/components/codecs/src/nvpipe_encoder.cpp b/components/codecs/src/nvpipe_encoder.cpp
index 5e28fd4b0..98d2c47a7 100644
--- a/components/codecs/src/nvpipe_encoder.cpp
+++ b/components/codecs/src/nvpipe_encoder.cpp
@@ -112,10 +112,10 @@ bool NvPipeEncoder::encode(const cv::cuda::GpuMat &in, ftl::codecs::Packet &pkt)
 		return false;
 	}
 
-	bool is_stereo = pkt.flags & ftl::codecs::kFlagStereo;
+	//bool is_stereo = pkt.flags & ftl::codecs::kFlagStereo;
 
 	auto [tx,ty] = ftl::codecs::chooseTileConfig(pkt.frame_count);
-	pkt.definition = (pkt.definition == definition_t::Any) ? ftl::codecs::findDefinition((is_stereo) ? in.cols/tx/2 : in.cols/tx, in.rows/ty) : pkt.definition;
+	pkt.definition = (pkt.definition == definition_t::Any) ? ftl::codecs::findDefinition(in.cols/tx, in.rows/ty) : pkt.definition;
 	if (pkt.definition == definition_t::Invalid || pkt.definition == definition_t::Any) {
 		LOG(ERROR) << "Could not find appropriate definition";
 		return false;
@@ -135,7 +135,7 @@ bool NvPipeEncoder::encode(const cv::cuda::GpuMat &in, ftl::codecs::Packet &pkt)
 		return false;
 	}
 
-	if (((is_stereo) ? tx*width*2 : tx*width) != in.cols || ty*height != in.rows) {
+	if (tx*width != in.cols || ty*height != in.rows) {
 		// TODO: Resize if lower definition requested...
 		LOG(ERROR) << "Input size does not match expected: " << in.cols << " != " << tx*width;
 		pkt.definition = definition_t::Invalid;
diff --git a/components/streams/include/ftl/streams/sender.hpp b/components/streams/include/ftl/streams/sender.hpp
index 70d485172..677990711 100644
--- a/components/streams/include/ftl/streams/sender.hpp
+++ b/components/streams/include/ftl/streams/sender.hpp
@@ -44,6 +44,8 @@ class Sender : public ftl::Configurable {
 	std::atomic_flag do_inject_;
 	//std::function<void(ftl::codecs::Channel, int, int)> state_cb_;
 	ftl::stream::StreamCallback reqcb_;
+	int add_iframes_;
+	int iframe_;
 
 	struct EncodingState {
 		uint8_t bitrate;
diff --git a/components/streams/src/sender.cpp b/components/streams/src/sender.cpp
index 204e29e11..8277a73d9 100644
--- a/components/streams/src/sender.cpp
+++ b/components/streams/src/sender.cpp
@@ -24,6 +24,12 @@ using ftl::stream::injectConfig;
 
 Sender::Sender(nlohmann::json &config) : ftl::Configurable(config), stream_(nullptr) {
 	do_inject_.test_and_set();
+	iframe_ = 1;
+	add_iframes_ = value("iframes", 0);
+
+	on("iframes", [this](const ftl::config::Event &e) {
+		add_iframes_ = value("iframes", 0);
+	});
 }
 
 Sender::~Sender() {
@@ -137,6 +143,9 @@ void Sender::post(ftl::rgbd::FrameSet &fs) {
 
 	bool do_inject = !do_inject_.test_and_set();
 
+	// Add an iframe at the requested frequency.
+	if (add_iframes_ > 0) iframe_ = (iframe_+1) % add_iframes_;
+
 	FTL_Profile("SenderPost", 0.02);
 
 	// Send any frameset data channels
@@ -249,7 +258,7 @@ void Sender::post(ftl::rgbd::FrameSet &fs) {
 
 	for (auto c : needencoding) {
 		// TODO: One thread per channel.
-		_encodeChannel(fs, c, do_inject);
+		_encodeChannel(fs, c, do_inject || iframe_ == 0);
 	}
 
 	//do_inject_ = false;
-- 
GitLab