diff --git a/components/codecs/include/ftl/codecs/nvidia_decoder.hpp b/components/codecs/include/ftl/codecs/nvidia_decoder.hpp
index 2c3ad8efaa7be45eedd831eb6d1341c3963576a6..d904ba1b64218653d4751e4da453fcd3242159a7 100644
--- a/components/codecs/include/ftl/codecs/nvidia_decoder.hpp
+++ b/components/codecs/include/ftl/codecs/nvidia_decoder.hpp
@@ -25,7 +25,7 @@ class NvidiaDecoder : public ftl::codecs::Decoder {
 	ftl::codecs::codec_t last_codec_;
 	MUTEX mutex_;
 	bool seen_iframe_;
-	cv::cuda::GpuMat tmp_;
+	cv::cuda::GpuMat buffer_;
 	int width_;
 	int height_;
 	int last_width_;
diff --git a/components/codecs/src/nvidia_decoder.cpp b/components/codecs/src/nvidia_decoder.cpp
index b4638ad048c3e7aa5cf65f021bbcffd73e62540a..063bc384998e1fb10a28db3dc589cc6b859de073 100644
--- a/components/codecs/src/nvidia_decoder.cpp
+++ b/components/codecs/src/nvidia_decoder.cpp
@@ -115,13 +115,16 @@ uint8_t* NvidiaDecoder::_decode(const uint8_t* src, uint64_t srcSize) {
 bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out) {
 	//cudaSetDevice(0);
 	UNIQUE_LOCK(mutex_,lk);
-	if (pkt.codec != codec_t::HEVC && pkt.codec != codec_t::H264 && pkt.codec != codec_t::HEVC_LOSSLESS && pkt.codec != codec_t::H264_LOSSLESS) return false;
+	if (pkt.codec != codec_t::HEVC && pkt.codec != codec_t::H264 && pkt.codec != codec_t::HEVC_LOSSLESS && pkt.codec != codec_t::H264_LOSSLESS) {
+		LOG(ERROR) << "Bad codec: " << int(pkt.codec);
+		return false;
+	}
 
 	bool is_float_frame = pkt.flags & ftl::codecs::kFlagFloat;
 	bool islossless = ((pkt.codec == ftl::codecs::codec_t::HEVC || pkt.codec == ftl::codecs::codec_t::H264) && is_float_frame &&
 		!(pkt.flags & 0x2)) || pkt.codec == ftl::codecs::codec_t::HEVC_LOSSLESS || pkt.codec == ftl::codecs::codec_t::H264_LOSSLESS; 
 
-	if (is_float_frame && out.type() != CV_32F) {
+	/*if (is_float_frame && out.type() != CV_32F) {
 		LOG(ERROR) << "Invalid buffer for float frame";
 		return false;
 	}
@@ -129,7 +132,7 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
 	if (!is_float_frame && out.type() != CV_8UC4) {
 		LOG(ERROR) << "Invalid buffer for lossy colour frame: " << out.type();
 		return false;
-	}
+	}*/
 
 	_create(pkt);
 
@@ -175,10 +178,10 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
 	width_ = nv_decoder_->GetWidth();
 	height_ = nv_decoder_->GetHeight();
 
-	if (out.cols != ((is_float_frame && islossless) ? width_/2 : width_) || out.rows != height_) {
+	/*if (out.cols != ((is_float_frame && islossless) ? width_/2 : width_) || out.rows != height_) {
 		LOG(ERROR) << "Decoded frame not same size as buffer: " << width_ << "x" << height_ << " -> " << out.cols << "x" << out.rows;
 		return false;
-	}
+	}*/
 
 	// OpenCV GpuMat for YCbCr 4:2:0
 	cv::cuda::GpuMat surface;
@@ -190,14 +193,23 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
 
 	if (is_float_frame) {
 		if (!islossless) {
+			buffer_.create(height_, width_, CV_32F);
+			out = buffer_;
+		
 			cv::cuda::GpuMat sroi = surface(cv::Rect(0,0,width_, height_));
 			cv::cuda::GpuMat csroi = surface(cv::Rect(0,height_,width_, height_/2));
 
 			ftl::cuda::vuya_to_depth(out, sroi, csroi, 16.0f, cvstream);
 		} else {
+			buffer_.create(height_, width_/2, CV_32F);
+			out = buffer_;
+
 			ftl::cuda::nv12_to_float(decodedPtr, width_, (float*)out.data, static_cast<uint32_t>(out.step1()), width_/2, height_, stream_);
 		}
 	} else {
+		buffer_.create(height_, width_, CV_8UC4);
+		out = buffer_;
+
 		// Flag 0x1 means frame is in RGB so needs conversion to BGR
 		if (pkt.flags & 0x1) {
 			Nv12ToColor32<BGRA32>(decodedPtr, width_, out.data, static_cast<int>(out.step1()), width_, height_, 0, stream_);
diff --git a/components/codecs/test/nvidia_codec_unit.cpp b/components/codecs/test/nvidia_codec_unit.cpp
index f72ef049b9774f865963f8b4d2b16179c09dc046..937106bb3891736e0c7c37eba7c1c8da7e3489ae 100644
--- a/components/codecs/test/nvidia_codec_unit.cpp
+++ b/components/codecs/test/nvidia_codec_unit.cpp
@@ -316,21 +316,6 @@ TEST_CASE( "NvidiaDecoder::decode() - corrupted packet" ) {
 	cv::cuda::GpuMat in;
 	cv::cuda::GpuMat out;
 
-	SECTION("Bad output size") {
-		in = cv::cuda::GpuMat(cv::Size(2560,720), CV_8UC4, cv::Scalar(255,0,0,0));
-		out = cv::cuda::GpuMat(cv::Size(2500,720), CV_8UC4, cv::Scalar(0,0,0,0));
-
-		ftl::codecs::Packet pkt;
-		pkt.codec = codec_t::Any;
-		pkt.bitrate = 255;
-		pkt.frame_count = 2;
-		pkt.flags = 0;
-		bool r = encoder.encode(in, pkt);
-
-		REQUIRE( r );
-		REQUIRE( !decoder.decode(pkt, out) );
-	}
-
 	SECTION("Corrupted but supported codec") {
 		in = cv::cuda::GpuMat(cv::Size(2560,720), CV_8UC4, cv::Scalar(255,0,0,0));
 		out = cv::cuda::GpuMat(cv::Size(2560,720), CV_8UC4, cv::Scalar(0,0,0,0));
@@ -379,7 +364,8 @@ TEST_CASE( "NvidiaDecoder::decode() - corrupted packet" ) {
 		pkt.flags = ftl::codecs::kFlagFloat;
 
 		REQUIRE( r );
-		REQUIRE( !decoder.decode(pkt, out) );
+		REQUIRE( decoder.decode(pkt, out) );
+		REQUIRE( out.type() == CV_32F );
 	}
 
 	SECTION("Corrupted float mapped flags") {
@@ -414,7 +400,9 @@ TEST_CASE( "NvidiaDecoder::decode() - corrupted packet" ) {
 		pkt.flags = 0;
 
 		REQUIRE( r );
-		REQUIRE( !decoder.decode(pkt, out) );
+		REQUIRE( decoder.decode(pkt, out) );
+		REQUIRE( out.type() == CV_8UC4 );
+		REQUIRE( out.cols == 2*in.cols );
 	}
 
 	SECTION("Missing data") {
diff --git a/components/streams/src/receiver.cpp b/components/streams/src/receiver.cpp
index dc13bc52987c9e41e8fe701594221e7faee3912a..c0cdbf04f890d5beea81b1873059a1257cb7e610 100644
--- a/components/streams/src/receiver.cpp
+++ b/components/streams/src/receiver.cpp
@@ -255,38 +255,13 @@ void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) {
 
 	auto [tx,ty] = ftl::codecs::chooseTileConfig(pkt.frame_count);
 
-	int width = ividstate.width; //calibration.width;
-	int height = ividstate.height; //calibration.height;
-
-	if (width <= 0 || height <= 0 || width > 9000 || height > 9000) {
-		// Attempt to retry the decode later
-		// Make a copy of the packets into a thread job
-		// FIXME: Check that thread pool does not explode
-		if (spkt.retry_count < 10) {
-			LOG(WARNING) << "No calibration, retrying: " << spkt.timestamp;
-			ftl::pool.push([this, spkt, pkt](int id) mutable {
-				++const_cast<StreamPacket&>(spkt).retry_count;
-				std::this_thread::sleep_for(std::chrono::milliseconds(10));
-				_processVideo(spkt, pkt);
-			});
-		} else {
-			LOG(WARNING) << "No calibration, failed frame: " << spkt.timestamp;
-		}
-		return;
-	}
-
 	if (tx == 0 || ty == 0) {
 		LOG(ERROR) << "No Packets";
 		return;
 	}
 
-	auto &surface = ividstate.surface[static_cast<int>(spkt.channel)];
-
-	// Allocate a decode surface, this is a tiled image to be split later
-	int cvtype = ftl::codecs::type(spkt.channel);
-	surface.create(height*ty, width*tx, cvtype);
-
-	bool is_static = ividstate.decoders[channum] && (spkt.hint_capability & ftl::codecs::kStreamCap_Static);
+	cv::cuda::GpuMat surface;
+	//bool is_static = ividstate.decoders[channum] && (spkt.hint_capability & ftl::codecs::kStreamCap_Static);
 
 	// Find or create the decoder
 	_createDecoder(ividstate, channum, pkt);
@@ -297,17 +272,30 @@ void Receiver::_processVideo(const StreamPacket &spkt, const Packet &pkt) {
 	}
 
 	// Do the actual decode into the surface buffer
-	if (!is_static) {
-		try {
-			FTL_Profile("Decode", 0.015);
-			if (!decoder->decode(pkt, surface)) {
-				LOG(ERROR) << "Decode failed on channel " << (int)spkt.channel;
-				return;
-			}
-		} catch (std::exception &e) {
-			LOG(ERROR) << "Decode failed for " << spkt.timestamp << ": " << e.what();
+	try {
+		FTL_Profile("Decode", 0.015);
+		if (!decoder->decode(pkt, surface)) {
+			LOG(ERROR) << "Decode failed on channel " << (int)spkt.channel;
 			return;
 		}
+	} catch (std::exception &e) {
+		LOG(ERROR) << "Decode failed for " << spkt.timestamp << ": " << e.what();
+		return;
+	}
+
+	int width = surface.cols / tx;
+	int height = surface.rows / ty;
+
+	if (width == 0 || height == 0) {
+		LOG(ERROR) << "Invalid decoded size: " << surface.cols << "x" << surface.rows << " (" << tx << "," << ty << ")";
+		return;
+	}
+
+	int cvtype = ftl::codecs::type(spkt.channel);
+
+	if (surface.type() != cvtype) {
+		LOG(ERROR) << "Invalid video format received";
+		return;
 	}
 
 	// Get the frameset