diff --git a/components/rgbd-sources/include/ftl/rgbd/source.hpp b/components/rgbd-sources/include/ftl/rgbd/source.hpp
index 9640456130669735cef134042258c565fe47a3f2..55cb8554e9eded1b661a89cdf917025369467ad2 100644
--- a/components/rgbd-sources/include/ftl/rgbd/source.hpp
+++ b/components/rgbd-sources/include/ftl/rgbd/source.hpp
@@ -68,15 +68,27 @@ class Source : public ftl::Configurable {
 
 	channel_t getChannel() const { return channel_; }
 
+	/**
+	 * Perform the hardware or virtual frame grab operation. 
+	 */
 	bool capture();
 
+	/**
+	 * Between frames, do any required buffer swaps.
+	 */
 	void swap() { if (impl_) impl_->swap(); }
 
 	/**
-	 * Perform the hardware or virtual frame grab operation. 
+	 * Do any post-grab processing. This function
+	 * may take considerable time to return, especially for sources requiring
+	 * software stereo correspondance.
 	 */
 	bool compute(int N=-1, int B=-1);
 
+	/**
+	 * Wrapper grab that performs capture, swap and computation steps in one.
+	 * It is more optimal to perform capture and compute in parallel.
+	 */
 	bool grab(int N=-1, int B=-1) {
 		bool c = capture();
 		swap();
@@ -84,16 +96,9 @@ class Source : public ftl::Configurable {
 	}
 
 	/**
-	 * Do any post-grab processing. This function
-	 * may take considerable time to return, especially for sources requiring
-	 * software stereo correspondance. If `process` is not called manually
-	 * after a `grab` and before a `get`, then it will be called automatically
-	 * on first `get`.
-	 */
-	//void process();
-
-	/**
-	 * Get a copy of both colour and depth frames.
+	 * Get a copy of both colour and depth frames. Note that this does a buffer
+	 * swap rather than a copy, so the parameters should be persistent buffers for
+	 * best performance.
 	 */
 	void getFrames(cv::Mat &c, cv::Mat &d);
 
diff --git a/components/rgbd-sources/src/source.cpp b/components/rgbd-sources/src/source.cpp
index 0b43ce7d991c4d771756d8597b75e6bc5ff1f242..4a3b7093ba8a4a5863c67dc51693cdbe1276c1b4 100644
--- a/components/rgbd-sources/src/source.cpp
+++ b/components/rgbd-sources/src/source.cpp
@@ -167,8 +167,16 @@ void Source::getFrames(cv::Mat &rgb, cv::Mat &depth) {
 	SHARED_LOCK(mutex_,lk);
 	//rgb_.copyTo(rgb);
 	//depth_.copyTo(depth);
+	//rgb = rgb_;
+	//depth = depth_;
+
+	cv::Mat tmp;
+	tmp = rgb;
 	rgb = rgb_;
+	rgb_ = tmp;
+	tmp = depth;
 	depth = depth_;
+	depth_ = tmp;
 }
 
 Eigen::Vector4d Source::point(uint ux, uint uy) {
@@ -236,7 +244,7 @@ bool Source::compute(int N, int B) {
 		return true;
 	} else if (impl_ && impl_->compute(N,B)) {
 		timestamp_ = impl_->timestamp_;
-		/*cv::Mat tmp;
+		cv::Mat tmp;
 		rgb_.create(impl_->rgb_.size(), impl_->rgb_.type());
 		depth_.create(impl_->depth_.size(), impl_->depth_.type());
 		tmp = rgb_;
@@ -244,9 +252,10 @@ bool Source::compute(int N, int B) {
 		impl_->rgb_ = tmp;
 		tmp = depth_;
 		depth_ = impl_->depth_;
-		impl_->depth_ = tmp;*/
-		impl_->rgb_.copyTo(rgb_);
-		impl_->depth_.copyTo(depth_);
+		impl_->depth_ = tmp;
+
+		//impl_->rgb_.copyTo(rgb_);
+		//impl_->depth_.copyTo(depth_);
 		return true;
 	}
 	return false;