diff --git a/applications/gui/src/camera.hpp b/applications/gui/src/camera.hpp
index be7b21476bce47b4d66fe5e1ee29012975cc5a45..a14be629490f86a791778b42ffbf62f9e23a23ae 100644
--- a/applications/gui/src/camera.hpp
+++ b/applications/gui/src/camera.hpp
@@ -82,7 +82,7 @@ class Camera {
 	inline int64_t getFrameTimeMS() const { return int64_t(delta_ * 1000.0f); }
 
 	const ftl::rgbd::Camera &getIntrinsics() const { return state_.getLeft(); }
-	const Eigen::Matrix4d &getPose() const { return state_.getPose(); }
+	const Eigen::Matrix4d getPose() const { UNIQUE_LOCK(mutex_, lk); return state_.getPose(); }
 
 	/**
 	 * @internal. Used to inform the camera if it is the active camera or not.
@@ -183,7 +183,7 @@ class Camera {
 	std::array<Eigen::Matrix4d,ftl::stream::kMaxStreams> transforms_;  // Frameset transforms for virtual cam
 	Eigen::Matrix4d T_ = Eigen::Matrix4d::Identity();
 
-	MUTEX mutex_;
+	mutable MUTEX mutex_;
 
 	#ifdef HAVE_OPENVR
 	vr::TrackedDevicePose_t rTrackedDevicePose_[ vr::k_unMaxTrackedDeviceCount ];
diff --git a/applications/gui/src/src_window.cpp b/applications/gui/src/src_window.cpp
index d397285fe6fdbf90415a39b325e1a4146bd6eabe..fc9f92b640085b4e01cb3003177c2a4a86781736 100644
--- a/applications/gui/src/src_window.cpp
+++ b/applications/gui/src/src_window.cpp
@@ -6,6 +6,8 @@
 #include "frameset_mgr.hpp"
 
 #include <ftl/profiler.hpp>
+#include <ftl/codecs/shapes.hpp>
+#include <ftl/utility/vectorbuffer.hpp>
 
 #include <nanogui/imageview.h>
 #include <nanogui/textbox.h>
@@ -112,7 +114,36 @@ SourceWindow::SourceWindow(ftl::gui::Screen *screen)
 
 	interceptor_->onIntercept([this] (const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) {
 		//LOG(INFO) << (std::string)spkt;
-		if (recorder_->active() && pkt.data.size() > 0) recorder_->post(spkt, pkt);
+		if (recorder_->active() && pkt.data.size() > 0) {
+
+			if (spkt.channel == Channel::Shapes3D && spkt.frame_number == 255) {
+				// Decode the shapes channel to insert the virtual camera...
+				std::vector<ftl::codecs::Shape3D> shapes;
+				auto unpacked = msgpack::unpack((const char*)pkt.data.data(), pkt.data.size());
+				unpacked.get().convert(shapes);
+
+				auto *cam = screen_->activeCamera();
+
+				if (cam) {
+					// Modify shapes
+					auto &s = shapes.emplace_back();
+					s.id = shapes.size();
+					s.label = std::string("virtual-")+std::to_string(shapes.size());
+					s.type = ftl::codecs::Shape3DType::CAMERA;
+					s.pose = cam->getPose().cast<float>();
+					//LOG(INFO) << "Inject virtual : " << shapes.size();
+				}
+
+				auto npkt = pkt;
+				npkt.data.resize(0);
+				ftl::util::FTLVectorBuffer buf(npkt.data);
+				msgpack::pack(buf, shapes);
+
+				recorder_->post(spkt, npkt);
+			} else {
+				recorder_->post(spkt, pkt);
+			}
+		}
 	});
 
 	paused_ = false;
diff --git a/components/operators/src/poser.cpp b/components/operators/src/poser.cpp
index 0c60db87ba7e1dceb8737f3e19cc95ea8f0531f0..3d136e1c9f2138695ed802e2b550cdd54e4270b3 100644
--- a/components/operators/src/poser.cpp
+++ b/components/operators/src/poser.cpp
@@ -27,7 +27,7 @@ bool Poser::apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out, cudaStream_
 		//LOG(INFO) << "Found shapes 3D global: " << (int)transforms.size();
 
         //for (auto &t : transforms) {
-            //LOG(INFO) << "Have FS transform: " << t.id;
+        //    LOG(INFO) << "Have FS transform: " << t.label;
         //}
     }