diff --git a/components/streams/src/sender.cpp b/components/streams/src/sender.cpp
index ee79773d0093d46e379aa9c56195b49afa7b3b54..7429bce945dec4f958bd7096048558cd4a89a7d5 100644
--- a/components/streams/src/sender.cpp
+++ b/components/streams/src/sender.cpp
@@ -484,6 +484,7 @@ void Sender::_encodeVideoChannel(ftl::data::FrameSet &fs, Channel c, bool reset)
 	bool is_stereo = value("stereo", false) && c == Channel::Colour && fs.firstFrame().hasChannel(Channel::Colour2);
 
 	uint32_t offset = 0;
+	int encoder_number = 0;
 	while (offset < fs.frames.size()) {
 		Channel cc = c;
 		//if ((cc == Channel::Colour) && fs.firstFrame().hasChannel(Channel::ColourHighRes)) {
@@ -510,11 +511,11 @@ void Sender::_encodeVideoChannel(ftl::data::FrameSet &fs, Channel c, bool reset)
 
 		auto &tile = _getTile(fs.id(), cc);
 
-		ftl::codecs::Encoder *enc = tile.encoder[(offset==0)?0:1];
+		ftl::codecs::Encoder *enc = tile.encoder[encoder_number];
 		if (!enc) {
 			enc = ftl::codecs::allocateEncoder(
 				definition_t::HD1080, device, codec);
-			tile.encoder[(offset==0)?0:1] = enc;
+			tile.encoder[encoder_number] = enc;
 		}
 
 		if (!enc) {
@@ -582,6 +583,7 @@ void Sender::_encodeVideoChannel(ftl::data::FrameSet &fs, Channel c, bool reset)
 		}
 
 		offset += count;
+		++encoder_number;
 	}
 }
 
@@ -713,7 +715,7 @@ void Sender::_encodeChannel(ftl::data::Frame &frame, Channel c, bool reset) {
 }
 
 cv::Rect Sender::_generateROI(const ftl::rgbd::FrameSet &fs, ftl::codecs::Channel c, int offset, bool stereo) {
-	const ftl::data::Frame &cframe = fs.firstFrame();
+	const ftl::data::Frame &cframe = fs.firstFrame(c);
 	int rwidth = cframe.get<cv::cuda::GpuMat>(c).cols;
 	if (stereo) rwidth *= 2;
 	int rheight = cframe.get<cv::cuda::GpuMat>(c).rows;
@@ -754,7 +756,7 @@ int Sender::_generateTiles(const ftl::rgbd::FrameSet &fs, int offset, Channel c,
 
 	const ftl::data::Frame *cframe = nullptr; //&fs.frames[offset];
 
-	const auto &m = fs.firstFrame().get<cv::cuda::GpuMat>(c);
+	const auto &m = fs.firstFrame(c).get<cv::cuda::GpuMat>(c);
 
 	// Choose tile configuration and allocate memory
 	auto [tx,ty] = ftl::codecs::chooseTileConfig(fs.frames.size());
diff --git a/components/streams/test/sender_unit.cpp b/components/streams/test/sender_unit.cpp
index 847fbe8bca7d9cbe8088ac33fb389c75584331ae..f16abf8ade90057d682c6604128ac23d670e5e46 100644
--- a/components/streams/test/sender_unit.cpp
+++ b/components/streams/test/sender_unit.cpp
@@ -190,6 +190,36 @@ TEST_CASE( "Sender::post() video frames" ) {
 		REQUIRE( ftl::codecs::hevc::validNAL(pkt.data.data(), pkt.data.size()) );
 	}
 
+	SECTION("4 depth frames tiled, missing first") {
+		stream.select(0, {Channel::Depth}, true);
+
+		fs.resize(4);
+
+		fs.mask = 0xF;
+		//fs.frames[0].create<cv::cuda::GpuMat>(Channel::Depth).create(cv::Size(1280,720), CV_32F);
+		//fs.frames[0].set<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
+
+		for (int i=1; i<4; ++i) {
+			fs.frames[i].store();
+			fs.frames[i].create<cv::cuda::GpuMat>(Channel::Depth).create(cv::Size(1280,720), CV_32F);
+			fs.frames[i].set<cv::cuda::GpuMat>(Channel::Depth).setTo(cv::Scalar(0.0f));
+		}
+
+		sender->post(fs, Channel::Depth);
+
+		REQUIRE( count == 1 );
+		REQUIRE( spkt.version == 5 );
+		REQUIRE( spkt.timestamp == 1000 );
+		REQUIRE( (int)spkt.frame_number == 1 );
+		REQUIRE( spkt.streamID == 0 );
+		REQUIRE( spkt.channel == Channel::Depth );
+		REQUIRE( pkt.codec == codec_t::HEVC );
+		REQUIRE( pkt.data.size() > 0 );
+		REQUIRE( pkt.flags == (ftl::codecs::kFlagFloat | ftl::codecs::kFlagMappedDepth) );
+		REQUIRE( pkt.frame_count == 3 );
+		REQUIRE( ftl::codecs::hevc::validNAL(pkt.data.data(), pkt.data.size()) );
+	}
+
 	SECTION("two lossless depth frames tiled") {
 		stream.select(0, {Channel::Depth}, true);
 
diff --git a/components/structures/include/ftl/data/new_frameset.hpp b/components/structures/include/ftl/data/new_frameset.hpp
index f40fd085bebc98dae9779d10720cc9f9461ae280..8dcc4b3b27f332139e5c18b9d42312cc2af9ccba 100644
--- a/components/structures/include/ftl/data/new_frameset.hpp
+++ b/components/structures/include/ftl/data/new_frameset.hpp
@@ -93,6 +93,8 @@ class FrameSet : public ftl::data::Frame {
 
 	const Frame &firstFrame() const;
 
+	const Frame &firstFrame(ftl::codecs::Channel) const;
+
 	inline Frame &operator[](int ix) { return frames[ix]; }
 	inline const Frame &operator[](int ix) const { return frames[ix]; }
 
diff --git a/components/structures/src/frameset.cpp b/components/structures/src/frameset.cpp
index 81848289e21eca9b57688c107caf0c194a007d71..cba77a2136cb6222f6fea9f2d6f77a2debb5eb2a 100644
--- a/components/structures/src/frameset.cpp
+++ b/components/structures/src/frameset.cpp
@@ -64,6 +64,13 @@ const ftl::data::Frame &ftl::data::FrameSet::firstFrame() const {
 	throw FTL_Error("No frames in frameset");
 }
 
+const ftl::data::Frame &ftl::data::FrameSet::firstFrame(ftl::codecs::Channel c) const {
+	for (size_t i=0; i<frames.size(); ++i) {
+		if (hasFrame(i) && frames[i].hasChannel(c)) return frames[i];
+	}
+	throw FTL_Error("No matching frames in frameset");
+}
+
 bool ftl::data::FrameSet::hasAnyChanged(ftl::codecs::Channel c) const {
 	for (size_t i=0; i<frames.size(); ++i) {
 		if (frames[i].changed(c)) return true;