diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3ae42fe6c62d7cc2516c46717cced183ca8c007e..dfe9498e2ba491633d9147cb89fc1feaf38b9a26 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -502,8 +502,6 @@ if (HAVE_NANOGUI)
 	add_subdirectory(applications/gui2)
 endif()
 
-add_subdirectory(applications/aruco)
-
 ### Generate Build Configuration Files =========================================
 
 configure_file(${CMAKE_SOURCE_DIR}/components/common/cpp/include/ftl/config.h.in
diff --git a/LICENSE b/LICENSE
index 67bf01195f29920b7a39400462f66f75daee1c3a..0343449d145abb8709875a8a93cf35c5c5211009 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,19 @@
-Copyright (c) 2020 Nicolas Pope. All Rights Reserved.
+Copyright (c) 2020 University of Turku, MIT License
 
-Unauthorized copying of the source code within this project, via any medium,
-is strictly prohibited. Private and confidencial.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/applications/aruco/CMakeLists.txt b/applications/aruco/CMakeLists.txt
deleted file mode 100644
index 0975581448490624c343ef55a30d6e9496fc2a12..0000000000000000000000000000000000000000
--- a/applications/aruco/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-set(FTLARUCOSRC
-	src/main.cpp
-)
-
-add_executable(ftl-aruco ${FTLARUCOSRC})
-
-target_include_directories(ftl-aruco PRIVATE src)
-
-target_link_libraries(ftl-aruco ftlcommon Threads::Threads ${OpenCV_LIBS})
-
-
diff --git a/applications/aruco/src/main.cpp b/applications/aruco/src/main.cpp
deleted file mode 100644
index f53c454abefe0bc607575b18af19d46030d11611..0000000000000000000000000000000000000000
--- a/applications/aruco/src/main.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <ftl/timer.hpp>
-#include <ftl/configuration.hpp>
-
-#include <opencv2/highgui.hpp>
-#include <opencv2/aruco.hpp>
-
-#include <vector>
-#include <string>
-
-int main(int argc, char** argv) {
-	std::vector<cv::Mat> tags;
-	unsigned int ntags = 10;
-	cv::Ptr<cv::aruco::Dictionary> dict =
-		cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_50);
-	unsigned int size = 512;
-	unsigned int margin = 64;
-	unsigned int delay = 50;
-
-	argc--;
-	argv++;
-	auto opts = ftl::config::read_options(&argv, &argc);
-
-	if (opts.count("delay"))
-		delay = std::stoi(opts["delay"]);
-	if (opts.count("dict"))
-		dict = cv::aruco::getPredefinedDictionary(std::stoi(opts["dict"]));
-	if (opts.count("ntags"))
-		ntags = std::stoi(opts["ntags"]);
-	if (opts.count("size"))
-		size = std::stoi(opts["size"]);
-	if (opts.count("margin"))
-		margin = std::stoi(opts["margin"]);
-
-	cv::Mat blank = cv::Mat(size + margin*2, size + margin*2, CV_8UC1);
-	blank.setTo(255);
-
-	for (unsigned int i = 0; i < ntags; i++) {
-		auto& tag = tags.emplace_back();
-		tag.create(size + margin*2, size + margin*2, CV_8UC1);
-		tag.setTo(255);
-		cv::aruco::drawMarker(dict, i, size, tag(cv::Rect(margin, margin, size, size)), 1);
-	}
-
-	int id = 0;
-	bool show_blank = false;
-	ftl::timer::setInterval(delay);
-	ftl::timer::setHighPrecision(true);
-	auto h = ftl::timer::add(ftl::timer::kTimerMain, [&](uint64_t){
-		cv::imshow("ArUco", show_blank ? blank : tags[id]);
-		if (cv::waitKey(1) == 27) { ftl::timer::stop(false); }
-		show_blank = !show_blank;
-		id = (id + 1) % ntags;
-		return true;
-	});
-
-	ftl::timer::start(true);
-
-	return 0;
-}
\ No newline at end of file
diff --git a/applications/ftl2mkv/src/main.cpp b/applications/ftl2mkv/src/main.cpp
index b746c8aa4c07551f49f422f76b51da9c4cb4131b..f4d8755ca842e37bc2387217579eee88c14b0c6f 100644
--- a/applications/ftl2mkv/src/main.cpp
+++ b/applications/ftl2mkv/src/main.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file main.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <loguru.hpp>
 #include <ftl/configuration.hpp>
 #include <ftl/codecs/reader.hpp>
diff --git a/applications/gui2/src/inputoutput.cpp b/applications/gui2/src/inputoutput.cpp
index 5ee5e03f8fd748580e2c8eec760419e063d27dc0..c8907933c46d4e5e810ee2dba836bb4512e9f353 100644
--- a/applications/gui2/src/inputoutput.cpp
+++ b/applications/gui2/src/inputoutput.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file inputoutput.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include <loguru.hpp>
 #include <nlohmann/json.hpp>
 #include <ftl/codecs/shapes.hpp>
diff --git a/applications/gui2/src/inputoutput.hpp b/applications/gui2/src/inputoutput.hpp
index 98d6a0dbef6b5205b2b97a57ad324fabbd86741d..186a8b255b121692d35bdc05f52c333a925ad71a 100644
--- a/applications/gui2/src/inputoutput.hpp
+++ b/applications/gui2/src/inputoutput.hpp
@@ -1,3 +1,10 @@
+/**
+ * @file inputoutput.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ * @author Nicolas Pope
+ */
+
 #pragma once
 
 #include <memory>
diff --git a/applications/gui2/src/main.cpp b/applications/gui2/src/main.cpp
index 27b5d1714027d741a3aa985d4fe5831edb899284..63c1005a69b00dd2c000cf062b9e91e78e9eadbf 100644
--- a/applications/gui2/src/main.cpp
+++ b/applications/gui2/src/main.cpp
@@ -1,3 +1,10 @@
+/**
+ * @file main.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ * @author Nicolas Pope
+ */
+
 #include <memory>
 
 #include <loguru.hpp>
diff --git a/applications/gui2/src/module.hpp b/applications/gui2/src/module.hpp
index ca048f124bb306c3fd2c841efa4b9daa46dbde31..df870caaac067e9654e1834148f54d77d385bb77 100644
--- a/applications/gui2/src/module.hpp
+++ b/applications/gui2/src/module.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file module.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "view.hpp"
diff --git a/applications/gui2/src/modules.hpp b/applications/gui2/src/modules.hpp
index 9c17cf769e939cc1b48b4c6588857013814d0e8e..13e92d92b1c4372a11b22519c3e59b1181634d77 100644
--- a/applications/gui2/src/modules.hpp
+++ b/applications/gui2/src/modules.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file modules.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "modules/thumbnails.hpp"
diff --git a/applications/gui2/src/modules/addsource.cpp b/applications/gui2/src/modules/addsource.cpp
index 7ac74b55b45b98b698835f9cdf2642b8310f10d1..4ad01d24853afb507a8470a0662b320e7c6996a5 100644
--- a/applications/gui2/src/modules/addsource.cpp
+++ b/applications/gui2/src/modules/addsource.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file addsource.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include "addsource.hpp"
 
 using ftl::gui2::AddCtrl;
diff --git a/applications/gui2/src/modules/addsource.hpp b/applications/gui2/src/modules/addsource.hpp
index eab8fef9d6fb27f5dc9d03b3c51e437b758f41da..2a28db66148d1f8044e670602c5b5d17da26278a 100644
--- a/applications/gui2/src/modules/addsource.hpp
+++ b/applications/gui2/src/modules/addsource.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file addsource.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #pragma once
 
 #include "../module.hpp"
diff --git a/applications/gui2/src/modules/calibration/calibration.cpp b/applications/gui2/src/modules/calibration/calibration.cpp
index 83627e6fd2ec0b5baccfeaeebf4d818276edf951..7ed698fcb5cc85c9e675528c67bcca42014ac46f 100644
--- a/applications/gui2/src/modules/calibration/calibration.cpp
+++ b/applications/gui2/src/modules/calibration/calibration.cpp
@@ -1,3 +1,8 @@
+/**
+ * @file calibration.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
 
 #include <loguru.hpp>
 
diff --git a/applications/gui2/src/modules/calibration/calibration.hpp b/applications/gui2/src/modules/calibration/calibration.hpp
index cff1b82759b58661d98324f6b767838ad0ce9c53..fa766093a532378dcea414bf3d8edaf604299699 100644
--- a/applications/gui2/src/modules/calibration/calibration.hpp
+++ b/applications/gui2/src/modules/calibration/calibration.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file calibration.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../../module.hpp"
diff --git a/applications/gui2/src/modules/calibration/extrinsic.cpp b/applications/gui2/src/modules/calibration/extrinsic.cpp
index 916ce681f835d3fad75a865fd56681b0ed63cf2f..b6f8602cdb085d2858b8ef9d17281abd871e5183 100644
--- a/applications/gui2/src/modules/calibration/extrinsic.cpp
+++ b/applications/gui2/src/modules/calibration/extrinsic.cpp
@@ -1,3 +1,8 @@
+/**
+ * @file extrinsic.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
 
 #include "calibration.hpp"
 #include "../../screen.hpp"
diff --git a/applications/gui2/src/modules/calibration/intrinsic.cpp b/applications/gui2/src/modules/calibration/intrinsic.cpp
index b91f74f56cf6eacc273368b18bc3332c9f625f3d..3bedbc8ee528421b721f763112a27d8f29b87153 100644
--- a/applications/gui2/src/modules/calibration/intrinsic.cpp
+++ b/applications/gui2/src/modules/calibration/intrinsic.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file intrinsic.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include <loguru.hpp>
 
 #include "calibration.hpp"
diff --git a/applications/gui2/src/modules/calibration/stereo.cpp b/applications/gui2/src/modules/calibration/stereo.cpp
index 148f8abcaa4d484201ec238a4440d01b59ca7700..d6e1d905e7416f0df9f332cae7f38dd47570eb9c 100644
--- a/applications/gui2/src/modules/calibration/stereo.cpp
+++ b/applications/gui2/src/modules/calibration/stereo.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file stereo.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include <loguru.hpp>
 
 #include "calibration.hpp"
diff --git a/applications/gui2/src/modules/camera.cpp b/applications/gui2/src/modules/camera.cpp
index 9cad119ad9a6bfb07977728ddc0991e8c3facc2f..2f5bd78f92b55d897d8382cb2b760bdc0d851b9b 100644
--- a/applications/gui2/src/modules/camera.cpp
+++ b/applications/gui2/src/modules/camera.cpp
@@ -1,3 +1,10 @@
+/**
+ * @file camera.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Sebastian Hahta
+ */
+
 #include "camera.hpp"
 #include "statistics.hpp"
 
diff --git a/applications/gui2/src/modules/camera.hpp b/applications/gui2/src/modules/camera.hpp
index e098bdcec465b9092c836f24259e6d9c4a0aa71f..778dd665051979a716d37a3adc696528d0a27f42 100644
--- a/applications/gui2/src/modules/camera.hpp
+++ b/applications/gui2/src/modules/camera.hpp
@@ -1,3 +1,10 @@
+/**
+ * @file camera.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../module.hpp"
diff --git a/applications/gui2/src/modules/camera_tools.hpp b/applications/gui2/src/modules/camera_tools.hpp
index ebe8386f100fe6b7a624055f61262f03f9752967..a03c7f23ac6d189ef02ba05e0e7645a7d7a50967 100644
--- a/applications/gui2/src/modules/camera_tools.hpp
+++ b/applications/gui2/src/modules/camera_tools.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file camera_tools.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_GUI_CAMERA_TOOLS_HPP_
 #define _FTL_GUI_CAMERA_TOOLS_HPP_
 
diff --git a/applications/gui2/src/modules/config.cpp b/applications/gui2/src/modules/config.cpp
index bfac6664e5a93f4b6579bf1d812e7cc856c91d4b..ac6512f00284c2ce849e63047f21ba0abb6a09b0 100644
--- a/applications/gui2/src/modules/config.cpp
+++ b/applications/gui2/src/modules/config.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file config.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include "config.hpp"
 
 using ftl::gui2::ConfigCtrl;
diff --git a/applications/gui2/src/modules/config.hpp b/applications/gui2/src/modules/config.hpp
index 3a89a17f6ebe86a87427def20c8f057658ab079b..4e66c7ac5285dfb33a44d59ab97f48ed725e4fb0 100644
--- a/applications/gui2/src/modules/config.hpp
+++ b/applications/gui2/src/modules/config.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file config.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../module.hpp"
diff --git a/applications/gui2/src/modules/statistics.cpp b/applications/gui2/src/modules/statistics.cpp
index 7147888298b6e38c58761f4ba2354c31fa24384e..d8428b540617d5fbdd40808ed9898ccf222cd2d8 100644
--- a/applications/gui2/src/modules/statistics.cpp
+++ b/applications/gui2/src/modules/statistics.cpp
@@ -1,3 +1,10 @@
+/**
+ * @file statistics.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Sebastian Hahta
+ */
+
 #include "statistics.hpp"
 
 #include "../screen.hpp"
diff --git a/applications/gui2/src/modules/statistics.hpp b/applications/gui2/src/modules/statistics.hpp
index 608ccacfab9e7232d699ba3d6dbeea181a95ce7b..58b2eeef65461789cc822adca59c7c64e754d323 100644
--- a/applications/gui2/src/modules/statistics.hpp
+++ b/applications/gui2/src/modules/statistics.hpp
@@ -1,3 +1,10 @@
+/**
+ * @file statistics.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../module.hpp"
diff --git a/applications/gui2/src/modules/themes.cpp b/applications/gui2/src/modules/themes.cpp
index 8b0d0ef060112914e6c82a883e7e6b7ce2885b3e..4d22e40f2d6f1bf9e362090b6af94be05524c233 100644
--- a/applications/gui2/src/modules/themes.cpp
+++ b/applications/gui2/src/modules/themes.cpp
@@ -1,3 +1,10 @@
+/**
+ * @file themes.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Sebastian Hahta
+ */
+
 #include "themes.hpp"
 #include "nanogui/theme.h"
 #include "../screen.hpp"
diff --git a/applications/gui2/src/modules/themes.hpp b/applications/gui2/src/modules/themes.hpp
index af5d7337ba4ecbbb20992f765f959de7da9ea049..e9d14705d3c4c830abc63b0d76bc565faec5eead 100644
--- a/applications/gui2/src/modules/themes.hpp
+++ b/applications/gui2/src/modules/themes.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file themes.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../module.hpp"
diff --git a/applications/gui2/src/modules/thumbnails.cpp b/applications/gui2/src/modules/thumbnails.cpp
index f94b446cb8980057bff78e20ba5bb8dc2654aefe..37cfa20b1bae4192733afdf38ab1417dbd3b068f 100644
--- a/applications/gui2/src/modules/thumbnails.cpp
+++ b/applications/gui2/src/modules/thumbnails.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file thumbnails.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include "thumbnails.hpp"
 #include "dev/developer.hpp"
 #include "../views/thumbnails.hpp"
diff --git a/applications/gui2/src/modules/thumbnails.hpp b/applications/gui2/src/modules/thumbnails.hpp
index c24f4641de814670a2523f05091c8e75a614fa34..acd227aa11a393b0465f491a8a6c2549156ebb5f 100644
--- a/applications/gui2/src/modules/thumbnails.hpp
+++ b/applications/gui2/src/modules/thumbnails.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file thumbnails.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../module.hpp"
diff --git a/applications/gui2/src/screen.cpp b/applications/gui2/src/screen.cpp
index 6925df289e3259f6236416a0fc55f942ad167f3a..6281c162bb39781c16391bbc5ed538d82150bc4c 100644
--- a/applications/gui2/src/screen.cpp
+++ b/applications/gui2/src/screen.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file screen.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include <nanogui/opengl.h>
 #include <nanogui/glutil.h>
 #include <nanogui/screen.h>
diff --git a/applications/gui2/src/screen.hpp b/applications/gui2/src/screen.hpp
index a5adee68fc58f6017aaeababb5ec75b0f536fef2..4d0bfe5a6754753fb06d1d2c175e1ff3ac9291d0 100644
--- a/applications/gui2/src/screen.hpp
+++ b/applications/gui2/src/screen.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file screen.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include <nanogui/screen.h>
diff --git a/applications/gui2/src/view.cpp b/applications/gui2/src/view.cpp
index 67297b6b439a7d59bb6617a65ce8914b40a47d1a..4d96c130256be09118e898d7d8ec0425f698bb6e 100644
--- a/applications/gui2/src/view.cpp
+++ b/applications/gui2/src/view.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file view.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include <nanogui/widget.h>
 
 #include "view.hpp"
diff --git a/applications/gui2/src/view.hpp b/applications/gui2/src/view.hpp
index 90687d8516944aa4749ad5424774300067f04db3..5e9b838fabeb1345bb64a0a344dfd75866d144af 100644
--- a/applications/gui2/src/view.hpp
+++ b/applications/gui2/src/view.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file view.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include <nanogui/widget.h>
diff --git a/applications/gui2/src/views/addsource.cpp b/applications/gui2/src/views/addsource.cpp
index 2d0a0209e8db9c82804d62670d9397904dc50f63..e4e9be7b7e6dedfec32c2346fbca15125b12a738 100644
--- a/applications/gui2/src/views/addsource.cpp
+++ b/applications/gui2/src/views/addsource.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file addsource.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include "addsource.hpp"
 #include "../modules/addsource.hpp"
 
diff --git a/applications/gui2/src/views/addsource.hpp b/applications/gui2/src/views/addsource.hpp
index 34e8353fe496454e8146787f00149e390b002cc2..09f3f3b34e8b19784d5e7a66f16c7b41984b0c5e 100644
--- a/applications/gui2/src/views/addsource.hpp
+++ b/applications/gui2/src/views/addsource.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file addsource.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #pragma once
 
 #include <nanogui/window.h>
diff --git a/applications/gui2/src/views/calibration/extrinsicview.cpp b/applications/gui2/src/views/calibration/extrinsicview.cpp
index 2fe214712e4ba993dc071276130696a052a2ee8b..0a3881caefd282f384d99d3549a561e6c66b28a7 100644
--- a/applications/gui2/src/views/calibration/extrinsicview.cpp
+++ b/applications/gui2/src/views/calibration/extrinsicview.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file extrinsicview.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include "extrinsicview.hpp"
 #include "visualization.hpp"
 #include "widgets.hpp"
diff --git a/applications/gui2/src/views/calibration/extrinsicview.hpp b/applications/gui2/src/views/calibration/extrinsicview.hpp
index 7e2b7b490c946a4945b199fb6532b0b4dfd650ab..dcca2ce274d8ce766a27a827b7af79b70d12c502 100644
--- a/applications/gui2/src/views/calibration/extrinsicview.hpp
+++ b/applications/gui2/src/views/calibration/extrinsicview.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file extrinsicview.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include <unordered_set>
diff --git a/applications/gui2/src/views/calibration/intrinsicview.cpp b/applications/gui2/src/views/calibration/intrinsicview.cpp
index cfa9941adf3d88c07d0be8d4076a9259d925cc91..91967eba9c59aea4010d6d0fb9b0deb8a321cb0a 100644
--- a/applications/gui2/src/views/calibration/intrinsicview.cpp
+++ b/applications/gui2/src/views/calibration/intrinsicview.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file intrinsicview.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include <sstream>
 
 #include "visualization.hpp"
diff --git a/applications/gui2/src/views/calibration/intrinsicview.hpp b/applications/gui2/src/views/calibration/intrinsicview.hpp
index 289971b17abcc6809b7ee16e9390a7e375ab2f38..4b2d0f9d425f57e0737d6ecda5d56ad13c34b2b7 100644
--- a/applications/gui2/src/views/calibration/intrinsicview.hpp
+++ b/applications/gui2/src/views/calibration/intrinsicview.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file intrinsicview.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../../modules/calibration/calibration.hpp"
diff --git a/applications/gui2/src/views/calibration/stereoview.cpp b/applications/gui2/src/views/calibration/stereoview.cpp
index e67eb269c6d0a2bfae834fa5a18d68080c2c44ea..88f61b064be47162ada0a0663a7fde0d42187e36 100644
--- a/applications/gui2/src/views/calibration/stereoview.cpp
+++ b/applications/gui2/src/views/calibration/stereoview.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file stereoview.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include <sstream>
 
 #include "visualization.hpp"
diff --git a/applications/gui2/src/views/calibration/stereoview.hpp b/applications/gui2/src/views/calibration/stereoview.hpp
index 194602cb17d5ccd741e5f7237a142b60e8deb23a..7709f05d4d4a0e34c807c1638f8840cebf391251 100644
--- a/applications/gui2/src/views/calibration/stereoview.hpp
+++ b/applications/gui2/src/views/calibration/stereoview.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file stereoview.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../../modules/calibration/calibration.hpp"
diff --git a/applications/gui2/src/views/calibration/visualization.hpp b/applications/gui2/src/views/calibration/visualization.hpp
index 026c40dc20bd12197503909d8f41990261f96834..d68e90df86b390f275d31d5d00fe8d78052e7df4 100644
--- a/applications/gui2/src/views/calibration/visualization.hpp
+++ b/applications/gui2/src/views/calibration/visualization.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file visualization.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../../widgets/imageview.hpp"
diff --git a/applications/gui2/src/views/calibration/widgets.cpp b/applications/gui2/src/views/calibration/widgets.cpp
index 80a4af5d5d4a43ff19b3bf206891af924de456aa..7cc3b2f84e5af19b0e146f754ea511e50ad25aad 100644
--- a/applications/gui2/src/views/calibration/widgets.cpp
+++ b/applications/gui2/src/views/calibration/widgets.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file widgets.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include "widgets.hpp"
 
 #include <nanogui/label.h>
diff --git a/applications/gui2/src/views/calibration/widgets.hpp b/applications/gui2/src/views/calibration/widgets.hpp
index 76ebf2c7d9a69bd289d9db22092ba8dc697ff18e..47f79fdd8735eaee25f41cb8f260a855c325bcc5 100644
--- a/applications/gui2/src/views/calibration/widgets.hpp
+++ b/applications/gui2/src/views/calibration/widgets.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file widgets.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include <nanogui/widget.h>
diff --git a/applications/gui2/src/views/camera.cpp b/applications/gui2/src/views/camera.cpp
index 482a9505cb563e720a93ca7a542ef07eed552a40..7e1e67143bf10c2996c67ac0f171b3f299247814 100644
--- a/applications/gui2/src/views/camera.cpp
+++ b/applications/gui2/src/views/camera.cpp
@@ -1,3 +1,10 @@
+/**
+ * @file camera.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Sebastian Hahta
+ */
+
 #include <nanogui/screen.h>
 #include <nanogui/layout.h>
 #include <nanogui/button.h>
diff --git a/applications/gui2/src/views/camera.hpp b/applications/gui2/src/views/camera.hpp
index 179f4eff2c2bdc49140051ef27ceafdbf385f6ed..d7b23222dcd13557079b6729cf5ae722cda8586e 100644
--- a/applications/gui2/src/views/camera.hpp
+++ b/applications/gui2/src/views/camera.hpp
@@ -1,3 +1,10 @@
+/**
+ * @file camera.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ * @author Nicolas Pope
+ */
+
 #pragma once
 
 #include "../view.hpp"
diff --git a/applications/gui2/src/views/camera3d.cpp b/applications/gui2/src/views/camera3d.cpp
index 5efcb4360ca23b4d982be2cdfbe7efb939e664f0..6f73a1194672eefdf5f427256bf3ce33ab036c93 100644
--- a/applications/gui2/src/views/camera3d.cpp
+++ b/applications/gui2/src/views/camera3d.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file camera3d.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include "camera3d.hpp"
 #include "../modules/camera.hpp"
 
diff --git a/applications/gui2/src/views/camera3d.hpp b/applications/gui2/src/views/camera3d.hpp
index 1d0771ca6e5b9bbb8dc0b26410dceca9f46814bd..7b1f8cef41e4d9528cc0a7b441697061efc95543 100644
--- a/applications/gui2/src/views/camera3d.hpp
+++ b/applications/gui2/src/views/camera3d.hpp
@@ -1,3 +1,10 @@
+/**
+ * @file camera3d.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include "../widgets/window.hpp"
diff --git a/applications/gui2/src/views/config.cpp b/applications/gui2/src/views/config.cpp
index 029b66d65a4fb0ddfa2fc08d2872aa7fb4bf1155..6e5af39dbeff6ebd49a8a969146c36e06a32a20e 100644
--- a/applications/gui2/src/views/config.cpp
+++ b/applications/gui2/src/views/config.cpp
@@ -1,3 +1,10 @@
+/**
+ * @file config.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Iiro Rastas
+ * @author Sebastian Hahta
+ */
 
 #include <loguru.hpp>
 
diff --git a/applications/gui2/src/views/config.hpp b/applications/gui2/src/views/config.hpp
index 45a23b11ded27adafd94629cc987f66592eb439f..1b49175da34640a443eca37f3e8f6977dd1edce2 100644
--- a/applications/gui2/src/views/config.hpp
+++ b/applications/gui2/src/views/config.hpp
@@ -1,3 +1,10 @@
+/**
+ * @file config.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include <nanogui/window.h>
diff --git a/applications/gui2/src/views/statistics.cpp b/applications/gui2/src/views/statistics.cpp
index e72bc160aeff19cea61fb49b606e6a21aef89bb7..ce4876e4ae40a1e3a1585cd1f8fb5456bc86b6cd 100644
--- a/applications/gui2/src/views/statistics.cpp
+++ b/applications/gui2/src/views/statistics.cpp
@@ -1,3 +1,10 @@
+/**
+ * @file statistics.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * @author Sebastian Hahta
+ */
+
 #include "statistics.hpp"
 #include "../modules/statistics.hpp"
 
diff --git a/applications/gui2/src/views/statistics.hpp b/applications/gui2/src/views/statistics.hpp
index f425bf3de57b84dc26d100398125d1b9a6f1ddc4..c77ed680829c87ea2dae48914ba74b233a3ca48a 100644
--- a/applications/gui2/src/views/statistics.hpp
+++ b/applications/gui2/src/views/statistics.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file statistics.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include <nanogui/widget.h>
diff --git a/applications/gui2/src/views/thumbnails.cpp b/applications/gui2/src/views/thumbnails.cpp
index 712264c355fb59aae868564b04b12a11ec4ab91d..2db5798f9f8dc6b7b76c46eb40e7ef72f07d32ff 100644
--- a/applications/gui2/src/views/thumbnails.cpp
+++ b/applications/gui2/src/views/thumbnails.cpp
@@ -1,3 +1,10 @@
+/**
+ * @file thumbnails.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ * @author Nicolas Pope
+ */
+
 #include "thumbnails.hpp"
 #include "../modules/thumbnails.hpp"
 #include <ftl/utility/gltexture.hpp>
diff --git a/applications/gui2/src/views/thumbnails.hpp b/applications/gui2/src/views/thumbnails.hpp
index c9440967de7cd297ee6fef9fa888e7904262f499..aa0c62764f079b67ab7f745120b02dbd898c5bad 100644
--- a/applications/gui2/src/views/thumbnails.hpp
+++ b/applications/gui2/src/views/thumbnails.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file thumbnails.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 #include "../view.hpp"
 
diff --git a/applications/gui2/src/widgets/combobox.cpp b/applications/gui2/src/widgets/combobox.cpp
index fc76210aab4ea1f9194cc4a53ab7ee466e9387a5..23505e590a31aa807fd5c86bdf68b11f9cf462ef 100644
--- a/applications/gui2/src/widgets/combobox.cpp
+++ b/applications/gui2/src/widgets/combobox.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file combobox.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 /*
 	src/combobox.cpp -- simple combo box widget based on a popup button
 
diff --git a/applications/gui2/src/widgets/combobox.hpp b/applications/gui2/src/widgets/combobox.hpp
index b137fd5053cfb4099692102952d7ac026836b0b2..034c99a988605d0850d515d876b6c7cf6db7b139 100644
--- a/applications/gui2/src/widgets/combobox.hpp
+++ b/applications/gui2/src/widgets/combobox.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file combobox.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 /*
 	Modification: Inherits from ftl::gui2::PopupButton
 
diff --git a/applications/gui2/src/widgets/imageview.cpp b/applications/gui2/src/widgets/imageview.cpp
index 2137b1ce9f8124c65234952dfaaa93605323bbb5..81f611377e782e8a9e0831c9e87101b2f20ef5cc 100644
--- a/applications/gui2/src/widgets/imageview.cpp
+++ b/applications/gui2/src/widgets/imageview.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file imageview.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 /*
 	nanogui/imageview.cpp -- Widget used to display images.
 
diff --git a/applications/gui2/src/widgets/imageview.hpp b/applications/gui2/src/widgets/imageview.hpp
index c5d520b628f8fc80a539689ebfea1f0f4638f7ee..34c7ad0ffec5fff48c59228c2d69695566c91888 100644
--- a/applications/gui2/src/widgets/imageview.hpp
+++ b/applications/gui2/src/widgets/imageview.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file imageview.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 /*
 	nanogui/imageview.h -- Widget used to display images.
 
diff --git a/applications/gui2/src/widgets/leftbutton.cpp b/applications/gui2/src/widgets/leftbutton.cpp
index c448ebaf2474674d8acfcaf2a7f783869154dc5f..224fd1211bd417338797a26c072a4e16ad5fc018 100644
--- a/applications/gui2/src/widgets/leftbutton.cpp
+++ b/applications/gui2/src/widgets/leftbutton.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file leftbutton.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include "leftbutton.hpp"
 #include <nanogui/button.h>
 #include <nanogui/theme.h>
diff --git a/applications/gui2/src/widgets/leftbutton.hpp b/applications/gui2/src/widgets/leftbutton.hpp
index 51efe156beb4e3b3ae4ce1b3f5c9d8cb58694cf4..e69a04fd159429d68884c683f5b9f99d07ce962a 100644
--- a/applications/gui2/src/widgets/leftbutton.hpp
+++ b/applications/gui2/src/widgets/leftbutton.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file leftbutton.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 #include <nanogui/button.h>
 
diff --git a/applications/gui2/src/widgets/popupbutton.cpp b/applications/gui2/src/widgets/popupbutton.cpp
index 4276aa2f08dbd16054fafbc685e3c174e199a65f..890dcc205ab1ed54f279bc747d3a35144ec2331e 100644
--- a/applications/gui2/src/widgets/popupbutton.cpp
+++ b/applications/gui2/src/widgets/popupbutton.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file popupbutton.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 /*
 	src/popupbutton.cpp -- Button which launches a popup widget
 
diff --git a/applications/gui2/src/widgets/popupbutton.hpp b/applications/gui2/src/widgets/popupbutton.hpp
index 81519c134b6d45cdc71053215cad98e4d6266697..3e332dd5d691d4c4ec8ad117c43187da70e7855f 100644
--- a/applications/gui2/src/widgets/popupbutton.hpp
+++ b/applications/gui2/src/widgets/popupbutton.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file popupbutton.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 #include <nanogui/button.h>
 #include <nanogui/popup.h>
diff --git a/applications/gui2/src/widgets/soundctrl.cpp b/applications/gui2/src/widgets/soundctrl.cpp
index 4a8d6a08d76569206ad34a8b5d5a618f19b9547d..e7e91c3168dcfb7176336a390439250cbe26739b 100644
--- a/applications/gui2/src/widgets/soundctrl.cpp
+++ b/applications/gui2/src/widgets/soundctrl.cpp
@@ -1,3 +1,10 @@
+/**
+ * @file soundctrl.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ * @author Nicolas Pope
+ */
+
 #include <nanogui/layout.h>
 #include <nanogui/label.h>
 #include <nanogui/slider.h>
diff --git a/applications/gui2/src/widgets/soundctrl.hpp b/applications/gui2/src/widgets/soundctrl.hpp
index 5495edd5c985dd9923c85f4ba1b7264cbdebbb25..0b6debd392a38462c13b7070f95f47a25fe15d4f 100644
--- a/applications/gui2/src/widgets/soundctrl.hpp
+++ b/applications/gui2/src/widgets/soundctrl.hpp
@@ -1,3 +1,10 @@
+/**
+ * @file soundctrl.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ * @author Nicolas Pope
+ */
+
 #pragma once
 
 #include <nanogui/entypo.h>
diff --git a/applications/gui2/src/widgets/window.hpp b/applications/gui2/src/widgets/window.hpp
index 3e568026a454dd6f266e2670d50e65a966fb4a9c..998759cc343633fee1ca4f60924a85e96697821b 100644
--- a/applications/gui2/src/widgets/window.hpp
+++ b/applications/gui2/src/widgets/window.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file window.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 
 #include <nanogui/window.h>
diff --git a/applications/reconstruct/CMakeLists.txt b/applications/reconstruct/CMakeLists.txt
deleted file mode 100644
index 39e4d51f82be600103f91d23e4a0564fff7ca32f..0000000000000000000000000000000000000000
--- a/applications/reconstruct/CMakeLists.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-# Need to include staged files and libs
-#include_directories(${PROJECT_SOURCE_DIR}/reconstruct/include)
-#include_directories(${PROJECT_BINARY_DIR})
-
-set(REPSRC
-	src/main.cpp
-	src/camera_util.cu
-	src/reconstruction.cpp
-)
-
-add_executable(ftl-reconstruct ${REPSRC})
-add_dependencies(ftl-reconstruct ftlnet)
-add_dependencies(ftl-reconstruct ftlcommon)
-
-target_include_directories(ftl-reconstruct PUBLIC
-	$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
-	$<INSTALL_INTERFACE:include>
-	PRIVATE src)
-
-if (CUDA_FOUND)
-set_property(TARGET ftl-reconstruct PROPERTY CUDA_SEPARABLE_COMPILATION ON)
-endif()
-
-#target_include_directories(cv-node PUBLIC ${PROJECT_SOURCE_DIR}/include)
-target_link_libraries(ftl-reconstruct ftlcommon ftlrgbd Threads::Threads ${OpenCV_LIBS} ftlctrl ftlnet ftlrender ftloperators ftlstreams ftlaudio)
-
-
diff --git a/applications/reconstruct/include/ftl/depth_camera.hpp b/applications/reconstruct/include/ftl/depth_camera.hpp
deleted file mode 100644
index 39e037abd90f64e6730577578e09a1f69998b43c..0000000000000000000000000000000000000000
--- a/applications/reconstruct/include/ftl/depth_camera.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-// From: https://github.com/niessner/VoxelHashing/blob/master/DepthSensingCUDA/Source/DepthCameraUtil.h
-
-#pragma once
-
-//#include <cutil_inline.h>
-//#include <cutil_math.h>
-//#include <vector_types.h>
-//#include <cuda_runtime.h>
-
-#include <ftl/cuda_matrix_util.hpp>
-#include <ftl/cuda_common.hpp>
-
-#include <ftl/depth_camera_params.hpp>
-
-#define MAX_CAMERAS 20
-
-
-//extern "C" void updateConstantDepthCameraParams(const DepthCameraParams& params);
-//extern __constant__ DepthCameraParams c_depthCameraParams;
-
-namespace ftl {
-namespace voxhash {
-
-struct __align__(16) DepthCameraCUDA {
-	cudaTextureObject_t depth;
-	cudaTextureObject_t depth2;
-	cudaTextureObject_t points;
-	cudaTextureObject_t colour;
-	cudaTextureObject_t normal;
-	DepthCameraParams params;
-	float4x4 pose;
-	float4x4 poseInverse;
-};
-
-struct DepthCamera {
-
-	///////////////
-	// Host part //
-	///////////////
-
-	__host__ DepthCamera();
-
-	__host__ void alloc(const DepthCameraParams& params, bool withNormals=false);
-
-	__host__ void updateData(const cv::Mat &depth, const cv::Mat &rgb, cv::cuda::Stream &stream);
-
-	__host__ void free();
-
-	__host__ void computeNormals(cudaStream_t stream);
-
-	ftl::cuda::TextureObject<float> *depth_tex_;
-	ftl::cuda::TextureObject<int> *depth2_tex_;
-	ftl::cuda::TextureObject<float4> *points_tex_;
-	ftl::cuda::TextureObject<uchar4> *colour_tex_;
-	ftl::cuda::TextureObject<float4> *normal_tex_;
-
-	// This part is sent to device
-	DepthCameraCUDA data;
-};
-}
-}
diff --git a/applications/reconstruct/include/ftl/depth_camera_params.hpp b/applications/reconstruct/include/ftl/depth_camera_params.hpp
deleted file mode 100644
index c1c3b8e615577e2d4006ad15cfa975a27c5797fe..0000000000000000000000000000000000000000
--- a/applications/reconstruct/include/ftl/depth_camera_params.hpp
+++ /dev/null
@@ -1,106 +0,0 @@
-// From: https://github.com/niessner/VoxelHashing/blob/master/DepthSensingCUDA/Source/CUDADepthCameraParams.h
-
-#pragma once
-
-//#include <cutil_inline.h>
-//#include <cutil_math.h>
-//#include <cuda_runtime.h>
-
-#include <ftl/cuda_matrix_util.hpp>
-#include <ftl/rgbd/camera.hpp>
-
-//#include <vector_types.h>
-
-struct __align__(16) DepthCameraParams {
-	float fx;
-	float fy;
-	float mx;
-	float my;
-
-	unsigned short m_imageWidth;
-	unsigned short m_imageHeight;
-	unsigned int flags;
-
-	float m_sensorDepthWorldMin;
-	float m_sensorDepthWorldMax;
-
-		///////////////////////////////////////////////////////////////
-		// Camera to Screen
-		///////////////////////////////////////////////////////////////
-
-	__device__
-	inline float2 cameraToKinectScreenFloat(const float3& pos) const {
-		//return make_float2(pos.x*c_depthCameraParams.fx/pos.z + c_depthCameraParams.mx, c_depthCameraParams.my - pos.y*c_depthCameraParams.fy/pos.z);
-		return make_float2(
-			pos.x*fx/pos.z + mx,			
-			pos.y*fy/pos.z + my);
-	}
-
-	__device__
-	inline int2 cameraToKinectScreenInt(const float3& pos) const {
-		float2 pImage = cameraToKinectScreenFloat(pos);
-		return make_int2(pImage + make_float2(0.5f, 0.5f));
-	}
-
-	__device__
-	inline uint2 cameraToKinectScreen(const float3& pos) const {
-		int2 p = cameraToKinectScreenInt(pos);
-		return make_uint2(p.x, p.y);
-	}
-
-	__device__
-	inline float cameraToKinectProjZ(float z) const {
-		return (z - m_sensorDepthWorldMin)/(m_sensorDepthWorldMax - m_sensorDepthWorldMin);
-	}
-
-	__device__
-	inline float3 cameraToKinectProj(const float3& pos) const {
-		float2 proj = cameraToKinectScreenFloat(pos);
-
-		float3 pImage = make_float3(proj.x, proj.y, pos.z);
-
-		pImage.x = (2.0f*pImage.x - (m_imageWidth- 1.0f))/(m_imageWidth- 1.0f);
-		//pImage.y = (2.0f*pImage.y - (c_depthCameraParams.m_imageHeight-1.0f))/(c_depthCameraParams.m_imageHeight-1.0f);
-		pImage.y = ((m_imageHeight-1.0f) - 2.0f*pImage.y)/(m_imageHeight-1.0f);
-		pImage.z = cameraToKinectProjZ(pImage.z);
-
-		return pImage;
-	}
-
-		///////////////////////////////////////////////////////////////
-		// Screen to Camera (depth in meters)
-		///////////////////////////////////////////////////////////////
-
-	__device__
-	inline float3 kinectDepthToSkeleton(uint ux, uint uy, float depth) const {
-		const float x = ((float)ux-mx) / fx;
-		const float y = ((float)uy-my) / fy;
-		//const float y = (c_depthCameraParams.my-(float)uy) / c_depthCameraParams.fy;
-		return make_float3(depth*x, depth*y, depth);
-	}
-
-		///////////////////////////////////////////////////////////////
-		// RenderScreen to Camera -- ATTENTION ASSUMES [1,0]-Z range!!!!
-		///////////////////////////////////////////////////////////////
-
-	__device__
-	inline float kinectProjToCameraZ(float z) const {
-		return z * (m_sensorDepthWorldMax - m_sensorDepthWorldMin) + m_sensorDepthWorldMin;
-	}
-
-	// z has to be in [0, 1]
-	__device__
-	inline float3 kinectProjToCamera(uint ux, uint uy, float z) const {
-		float fSkeletonZ = kinectProjToCameraZ(z);
-		return kinectDepthToSkeleton(ux, uy, fSkeletonZ);
-	}
-	
-	__device__
-	inline bool isInCameraFrustumApprox(const float4x4& viewMatrixInverse, const float3& pos) const {
-		float3 pCamera = viewMatrixInverse * pos;
-		float3 pProj = cameraToKinectProj(pCamera);
-		//pProj *= 1.5f;	//TODO THIS IS A HACK FIX IT :)
-		pProj *= 0.95;
-		return !(pProj.x < -1.0f || pProj.x > 1.0f || pProj.y < -1.0f || pProj.y > 1.0f || pProj.z < 0.0f || pProj.z > 1.0f);  
-	}
-};
diff --git a/applications/reconstruct/include/ftl/ray_cast_params.hpp b/applications/reconstruct/include/ftl/ray_cast_params.hpp
deleted file mode 100644
index 78242cf1fda6abae20cd82dc6cb00b9426ec86a6..0000000000000000000000000000000000000000
--- a/applications/reconstruct/include/ftl/ray_cast_params.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <ftl/cuda_util.hpp>
-
-#include <ftl/cuda_matrix_util.hpp>
-#include <ftl/depth_camera_params.hpp>
-
-static const uint kShowBlockBorders = 0x0001;
-
-struct __align__(16) RayCastParams {
-	float4x4 m_viewMatrix;
-	float4x4 m_viewMatrixInverse;
-	float4x4 m_intrinsics;
-	float4x4 m_intrinsicsInverse;
-
-	unsigned int m_width;
-	unsigned int m_height;
-
-	unsigned int m_numOccupiedSDFBlocks;
-	unsigned int m_maxNumVertices;
-	int m_splatMinimum;
-
-	float m_minDepth;
-	float m_maxDepth;
-	float m_rayIncrement;
-	float m_thresSampleDist;
-	float m_thresDist;
-	bool  m_useGradients;
-
-	uint m_flags;
-
-	DepthCameraParams camera;
-};
diff --git a/applications/reconstruct/include/ftl/ray_cast_sdf.hpp b/applications/reconstruct/include/ftl/ray_cast_sdf.hpp
deleted file mode 100644
index 1fb9cc074a39262d25df69998e0a68e6500508e7..0000000000000000000000000000000000000000
--- a/applications/reconstruct/include/ftl/ray_cast_sdf.hpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#pragma once
-
-#include <ftl/configurable.hpp>
-#include <ftl/matrix_conversion.hpp>
-#include <ftl/cuda_matrix_util.hpp>
-#include <ftl/depth_camera.hpp>
-#include <ftl/ray_cast_util.hpp>
-#include <nlohmann/json.hpp>
-
-// #include "DX11RayIntervalSplatting.h"
-
-class CUDARayCastSDF : public ftl::Configurable
-{
-public:
-	CUDARayCastSDF(nlohmann::json& config) : ftl::Configurable(config) {
-		auto &cfg = ftl::config::resolve(config);
-		create(parametersFromConfig(cfg));
-		hash_render_ = value("hash_renderer", false);
-
-		on("hash_renderer", [this](const ftl::config::Event &e) {
-			hash_render_ = value("hash_renderer", false);
-		});
-
-		on("width", [this](const ftl::config::Event &e) {
-			m_params.m_width = value("width", 640);
-		});
-
-		on("height", [this](const ftl::config::Event &e) {
-			m_params.m_height = value("height", 480);
-		});
-
-		on("width", [this](const ftl::config::Event &e) {
-			m_params.m_width = value("width", 640);
-		});
-
-		on("max_depth", [this](const ftl::config::Event &e) {
-			m_params.m_maxDepth = value("max_depth", 20.0f);
-		});
-
-		on("min_depth", [this](const ftl::config::Event &e) {
-			m_params.m_minDepth = value("min_depth", 20.0f);
-		});
-
-		on("showBlockBorders", [this](const ftl::config::Event &e) {
-			if (value("showBlockBorders", false)) m_params.m_flags |= kShowBlockBorders;
-			else m_params.m_flags &= ~kShowBlockBorders;
-		});
-	}
-
-	bool isIntegerDepth() const { return hash_render_; }
-
-	~CUDARayCastSDF(void) {
-		destroy();
-	}
-
-	static RayCastParams parametersFromConfig(const nlohmann::json& gas) {
-		RayCastParams params;
-		params.m_width = gas["width"].get<unsigned int>();
-		params.m_height = gas["height"].get<unsigned int>();
-		params.m_intrinsics = MatrixConversion::toCUDA(Eigen::Matrix4f());
-		params.m_intrinsicsInverse = MatrixConversion::toCUDA(Eigen::Matrix4f());
-		params.m_minDepth = gas["min_depth"].get<float>();
-		params.m_maxDepth = gas["max_depth"].get<float>();
-		params.m_rayIncrement = gas["SDFRayIncrementFactor"].get<float>() * gas["SDFTruncation"].get<float>();
-		params.m_thresSampleDist = gas["SDFRayThresSampleDistFactor"].get<float>() * params.m_rayIncrement;
-		params.m_thresDist = gas["SDFRayThresDistFactor"].get<float>() * params.m_rayIncrement;
-		params.m_useGradients = gas["SDFUseGradients"].get<bool>();
-
-		uint flags = 0;
-		if (gas.value("showBlockBorders", false)) flags |= kShowBlockBorders;
-		params.m_flags = flags;
-
-
-		return params;
-	}
-
-	void render(ftl::voxhash::HashData& hashData, ftl::voxhash::HashParams& hashParams, const DepthCameraParams& cameraParams, const Eigen::Matrix4f& lastRigidTransform, cudaStream_t);
-
-	const RayCastData& getRayCastData(void) {
-		return m_data;
-	}
-	const RayCastParams& getRayCastParams() const {
-		return m_params;
-	}
-
-
-	// debugging
-	void convertToCameraSpace(const DepthCameraData& cameraData);
-
-private:
-
-	void create(const RayCastParams& params);
-	void destroy(void);
-
-	void compactifyHashEntries(ftl::voxhash::HashData& hashData, ftl::voxhash::HashParams& hashParams, cudaStream_t);
-
-	void rayIntervalSplatting(const ftl::voxhash::HashData& hashData, const ftl::voxhash::HashParams& hashParams, const Eigen::Matrix4f& lastRigidTransform); // rasterize
-
-	RayCastParams m_params;
-	RayCastData m_data;
-	bool hash_render_;
-
-	// DX11RayIntervalSplatting m_rayIntervalSplatting;
-};
diff --git a/applications/reconstruct/include/ftl/ray_cast_util.hpp b/applications/reconstruct/include/ftl/ray_cast_util.hpp
deleted file mode 100644
index fdf932a5c6d9342768f7f45e2609e2df3c7539ce..0000000000000000000000000000000000000000
--- a/applications/reconstruct/include/ftl/ray_cast_util.hpp
+++ /dev/null
@@ -1,284 +0,0 @@
-#pragma once
-
-#include <ftl/cuda_matrix_util.hpp>
-#include <ftl/depth_camera.hpp>
-#include <ftl/voxel_hash.hpp>
-
-#include <ftl/ray_cast_params.hpp>
-
-struct RayCastSample
-{
-	float sdf;
-	float alpha;
-	uint weight;
-	//uint3 color;
-};
-
-#ifndef MINF
-#define MINF asfloat(0xff800000)
-#endif
-
-extern __constant__ RayCastParams c_rayCastParams;
-extern "C" void updateConstantRayCastParams(const RayCastParams& params);
-
-
-struct RayCastData {
-
-	///////////////
-	// Host part //
-	///////////////
-
-	__device__ __host__
-	RayCastData() {
-		d_depth = NULL;
-		d_depth3 = NULL;
-		d_normals = NULL;
-		d_colors = NULL;
-
-		//d_vertexBuffer = NULL;
-		point_cloud_ = nullptr;
-
-		d_rayIntervalSplatMinArray = NULL;
-		d_rayIntervalSplatMaxArray = NULL;
-	}
-
-#ifndef __CUDACC__
-	__host__
-	void allocate(const RayCastParams& params) {
-		//point_cloud_ = new cv::cuda::GpuMat(params.m_width*params.m_height, 1, CV_32FC3);
-		cudaSafeCall(cudaMalloc(&d_depth, sizeof(float) * params.m_width * params.m_height));
-		cudaSafeCall(cudaMalloc(&d_depth3, sizeof(float3) * params.m_width * params.m_height));
-		cudaSafeCall(cudaMalloc(&d_normals, sizeof(float4) * params.m_width * params.m_height));
-		cudaSafeCall(cudaMalloc(&d_colors, sizeof(uchar3) * params.m_width * params.m_height));
-		//cudaSafeCall(cudaMalloc(&point_cloud_, sizeof(float3) * params.m_width * params.m_height));
-		//printf("Allocate ray cast data: %lld \n", (unsigned long long)point_cloud_);
-	}
-
-	//__host__
-	//void updateParams(const RayCastParams& params) {
-	//	updateConstantRayCastParams(params);
-	//}
-
-	__host__ void download(int *depth, uchar3 *colours, const RayCastParams& params, cudaStream_t stream) const {
-		//printf("Download: %d,%d\n", params.m_width, params.m_height);
-		if (depth) cudaSafeCall(cudaMemcpyAsync(depth, d_depth_i, sizeof(int) * params.m_width * params.m_height, cudaMemcpyDeviceToHost, stream));
-		if (colours) cudaSafeCall(cudaMemcpyAsync(colours, d_colors, sizeof(uchar3) * params.m_width * params.m_height, cudaMemcpyDeviceToHost, stream));
-	}
-
-	__host__
-		void free() {
-			//cudaFree(point_cloud_);
-			cudaFree(d_depth);
-			cudaFree(d_depth3);
-			cudaFree(d_normals);
-			cudaFree(d_colors);
-	}
-#endif
-
-	/////////////////
-	// Device part //
-	/////////////////
-#ifdef __CUDACC__
-
-	__device__
-		const RayCastParams& params() const {
-			return c_rayCastParams;
-	}
-
-	__device__
-	float frac(float val) const {
-		return (val - floorf(val));
-	}
-	__device__
-	float3 frac(const float3& val) const {
-			return make_float3(frac(val.x), frac(val.y), frac(val.z));
-	}
-	
-	__device__
-	bool trilinearInterpolationSimpleFastFast(const ftl::voxhash::HashData& hash, const float3& pos, float& dist, uchar3& color) const {
-		const float oSet = c_hashParams.m_virtualVoxelSize;
-		const float3 posDual = pos-make_float3(oSet/2.0f, oSet/2.0f, oSet/2.0f);
-		float3 weight = frac(hash.worldToVirtualVoxelPosFloat(pos));
-
-		dist = 0.0f;
-		float3 colorFloat = make_float3(0.0f, 0.0f, 0.0f);
-		ftl::voxhash::Voxel v = hash.getVoxel(posDual+make_float3(0.0f, 0.0f, 0.0f)); if(v.weight == 0) return false; float3 vColor = make_float3(v.color.x, v.color.y, v.color.z); dist+= (1.0f-weight.x)*(1.0f-weight.y)*(1.0f-weight.z)*v.sdf; colorFloat+= (1.0f-weight.x)*(1.0f-weight.y)*(1.0f-weight.z)*vColor;
-		      v = hash.getVoxel(posDual+make_float3(oSet, 0.0f, 0.0f)); if(v.weight == 0) return false;		   vColor = make_float3(v.color.x, v.color.y, v.color.z); dist+=	   weight.x *(1.0f-weight.y)*(1.0f-weight.z)*v.sdf; colorFloat+=	   weight.x *(1.0f-weight.y)*(1.0f-weight.z)*vColor;
-		      v = hash.getVoxel(posDual+make_float3(0.0f, oSet, 0.0f)); if(v.weight == 0) return false;		   vColor = make_float3(v.color.x, v.color.y, v.color.z); dist+= (1.0f-weight.x)*	   weight.y *(1.0f-weight.z)*v.sdf; colorFloat+= (1.0f-weight.x)*	   weight.y *(1.0f-weight.z)*vColor;
-		      v = hash.getVoxel(posDual+make_float3(0.0f, 0.0f, oSet)); if(v.weight == 0) return false;		   vColor = make_float3(v.color.x, v.color.y, v.color.z); dist+= (1.0f-weight.x)*(1.0f-weight.y)*	   weight.z *v.sdf; colorFloat+= (1.0f-weight.x)*(1.0f-weight.y)*	   weight.z *vColor;
-		      v = hash.getVoxel(posDual+make_float3(oSet, oSet, 0.0f)); if(v.weight == 0) return false;		   vColor = make_float3(v.color.x, v.color.y, v.color.z); dist+=	   weight.x *	   weight.y *(1.0f-weight.z)*v.sdf; colorFloat+=	   weight.x *	   weight.y *(1.0f-weight.z)*vColor;
-		      v = hash.getVoxel(posDual+make_float3(0.0f, oSet, oSet)); if(v.weight == 0) return false;		   vColor = make_float3(v.color.x, v.color.y, v.color.z); dist+= (1.0f-weight.x)*	   weight.y *	   weight.z *v.sdf; colorFloat+= (1.0f-weight.x)*	   weight.y *	   weight.z *vColor;
-		      v = hash.getVoxel(posDual+make_float3(oSet, 0.0f, oSet)); if(v.weight == 0) return false;		   vColor = make_float3(v.color.x, v.color.y, v.color.z); dist+=	   weight.x *(1.0f-weight.y)*	   weight.z *v.sdf; colorFloat+=	   weight.x *(1.0f-weight.y)*	   weight.z *vColor;
-		      v = hash.getVoxel(posDual+make_float3(oSet, oSet, oSet)); if(v.weight == 0) return false;		   vColor = make_float3(v.color.x, v.color.y, v.color.z); dist+=	   weight.x *	   weight.y *	   weight.z *v.sdf; colorFloat+=	   weight.x *	   weight.y *	   weight.z *vColor;
-
-		color = make_uchar3(colorFloat.x, colorFloat.y, colorFloat.z);//v.color;
-		
-		return true;
-	}
-	//__device__
-	//bool trilinearInterpolationSimpleFastFast(const HashData& hash, const float3& pos, float& dist, uchar3& color) const {
-	//	const float oSet = c_hashParams.m_virtualVoxelSize;
-	//	const float3 posDual = pos-make_float3(oSet/2.0f, oSet/2.0f, oSet/2.0f);
-	//	float3 weight = frac(hash.worldToVirtualVoxelPosFloat(pos));
-
-	//	dist = 0.0f;
-	//	Voxel v = hash.getVoxel(posDual+make_float3(0.0f, 0.0f, 0.0f)); if(v.weight == 0) return false; dist+= (1.0f-weight.x)*(1.0f-weight.y)*(1.0f-weight.z)*v.sdf;
-	//	v = hash.getVoxel(posDual+make_float3(oSet, 0.0f, 0.0f)); if(v.weight == 0) return false;		dist+=	   weight.x *(1.0f-weight.y)*(1.0f-weight.z)*v.sdf;
-	//	v = hash.getVoxel(posDual+make_float3(0.0f, oSet, 0.0f)); if(v.weight == 0) return false;		dist+= (1.0f-weight.x)*	   weight.y *(1.0f-weight.z)*v.sdf;
-	//	v = hash.getVoxel(posDual+make_float3(0.0f, 0.0f, oSet)); if(v.weight == 0) return false;		dist+= (1.0f-weight.x)*(1.0f-weight.y)*	   weight.z *v.sdf;
-	//	v = hash.getVoxel(posDual+make_float3(oSet, oSet, 0.0f)); if(v.weight == 0) return false;		dist+=	   weight.x *	   weight.y *(1.0f-weight.z)*v.sdf;
-	//	v = hash.getVoxel(posDual+make_float3(0.0f, oSet, oSet)); if(v.weight == 0) return false;		dist+= (1.0f-weight.x)*	   weight.y *	   weight.z *v.sdf;
-	//	v = hash.getVoxel(posDual+make_float3(oSet, 0.0f, oSet)); if(v.weight == 0) return false;		dist+=	   weight.x *(1.0f-weight.y)*	   weight.z *v.sdf;
-	//	v = hash.getVoxel(posDual+make_float3(oSet, oSet, oSet)); if(v.weight == 0) return false;		dist+=	   weight.x *	   weight.y *	   weight.z *v.sdf;
-
-	//	color = v.color;
-
-	//	return true;
-	//}
-
-
-	__device__
-	float findIntersectionLinear(float tNear, float tFar, float dNear, float dFar) const
-	{
-		return tNear+(dNear/(dNear-dFar))*(tFar-tNear);
-	}
-	
-	static const unsigned int nIterationsBisection = 3;
-	
-	// d0 near, d1 far
-	__device__
-		bool findIntersectionBisection(const ftl::voxhash::HashData& hash, const float3& worldCamPos, const float3& worldDir, float d0, float r0, float d1, float r1, float& alpha, uchar3& color) const
-	{
-		float a = r0; float aDist = d0;
-		float b = r1; float bDist = d1;
-		float c = 0.0f;
-
-#pragma unroll 1
-		for(uint i = 0; i<nIterationsBisection; i++)
-		{
-			c = findIntersectionLinear(a, b, aDist, bDist);
-
-			float cDist;
-			if(!trilinearInterpolationSimpleFastFast(hash, worldCamPos+c*worldDir, cDist, color)) return false;
-
-			if(aDist*cDist > 0.0) { a = c; aDist = cDist; }
-			else { b = c; bDist = cDist; }
-		}
-
-		alpha = c;
-
-		return true;
-	}
-	
-	
-	__device__
-	float3 gradientForPoint(const ftl::voxhash::HashData& hash, const float3& pos) const
-	{
-		const float voxelSize = c_hashParams.m_virtualVoxelSize;
-		float3 offset = make_float3(voxelSize, voxelSize, voxelSize);
-
-		float distp00; uchar3 colorp00; trilinearInterpolationSimpleFastFast(hash, pos-make_float3(0.5f*offset.x, 0.0f, 0.0f), distp00, colorp00);
-		float dist0p0; uchar3 color0p0; trilinearInterpolationSimpleFastFast(hash, pos-make_float3(0.0f, 0.5f*offset.y, 0.0f), dist0p0, color0p0);
-		float dist00p; uchar3 color00p; trilinearInterpolationSimpleFastFast(hash, pos-make_float3(0.0f, 0.0f, 0.5f*offset.z), dist00p, color00p);
-
-		float dist100; uchar3 color100; trilinearInterpolationSimpleFastFast(hash, pos+make_float3(0.5f*offset.x, 0.0f, 0.0f), dist100, color100);
-		float dist010; uchar3 color010; trilinearInterpolationSimpleFastFast(hash, pos+make_float3(0.0f, 0.5f*offset.y, 0.0f), dist010, color010);
-		float dist001; uchar3 color001; trilinearInterpolationSimpleFastFast(hash, pos+make_float3(0.0f, 0.0f, 0.5f*offset.z), dist001, color001);
-
-		float3 grad = make_float3((distp00-dist100)/offset.x, (dist0p0-dist010)/offset.y, (dist00p-dist001)/offset.z);
-
-		float l = length(grad);
-		if(l == 0.0f) {
-			return make_float3(0.0f, 0.0f, 0.0f);
-		}
-
-		return -grad/l;
-	}
-
-	__device__
-	void traverseCoarseGridSimpleSampleAll(const ftl::voxhash::HashData& hash, const RayCastParams& rayCastParams, const float3& worldCamPos, const float3& worldDir, const float3& camDir, const int3& dTid, float minInterval, float maxInterval) const
-	{
-		//const RayCastParams& rayCastParams = c_rayCastParams;
-
-		// Last Sample
-		RayCastSample lastSample; lastSample.sdf = 0.0f; lastSample.alpha = 0.0f; lastSample.weight = 0; // lastSample.color = int3(0, 0, 0);
-		const float depthToRayLength = 1.0f/camDir.z; // scale factor to convert from depth to ray length
-		
-		float rayCurrent = depthToRayLength * max(rayCastParams.m_minDepth, minInterval);	// Convert depth to raylength
-		float rayEnd = depthToRayLength * min(rayCastParams.m_maxDepth, maxInterval);		// Convert depth to raylength
-		//float rayCurrent = depthToRayLength * rayCastParams.m_minDepth;	// Convert depth to raylength
-		//float rayEnd = depthToRayLength * rayCastParams.m_maxDepth;		// Convert depth to raylength
-
-		//printf("MINMAX: %f,%f\n", minInterval, maxInterval);
-
-#pragma unroll 1
-		while(rayCurrent < rayEnd)
-		{
-			float3 currentPosWorld = worldCamPos+rayCurrent*worldDir;
-			float dist;	uchar3 color;
-
-			//printf("RAY LOOP: %f,%f,%f\n", currentPosWorld.x, currentPosWorld.y, currentPosWorld.z);
-
-			if(trilinearInterpolationSimpleFastFast(hash, currentPosWorld, dist, color))
-			{
-				if(lastSample.weight > 0 && lastSample.sdf > 0.0f && dist < 0.0f) // current sample is always valid here 
-				{
-
-					float alpha; // = findIntersectionLinear(lastSample.alpha, rayCurrent, lastSample.sdf, dist);
-					uchar3 color2;
-					bool b = findIntersectionBisection(hash, worldCamPos, worldDir, lastSample.sdf, lastSample.alpha, dist, rayCurrent, alpha, color2);
-					
-					float3 currentIso = worldCamPos+alpha*worldDir;
-					if(b && abs(lastSample.sdf - dist) < rayCastParams.m_thresSampleDist)
-					{
-						if(abs(dist) < rayCastParams.m_thresDist)
-						{
-							float depth = alpha / depthToRayLength; // Convert ray length to depth depthToRayLength
-
-							d_depth[dTid.y*rayCastParams.m_width+dTid.x] = depth;
-							d_depth3[dTid.y*rayCastParams.m_width+dTid.x] = rayCastParams.camera.kinectDepthToSkeleton(dTid.x, dTid.y, depth);
-							d_colors[dTid.y*rayCastParams.m_width+dTid.x] = make_uchar3(color2.x, color2.y, color2.z);
-
-							if(rayCastParams.m_useGradients)
-							{
-								float3 normal = -gradientForPoint(hash, currentIso);
-								float4 n = rayCastParams.m_viewMatrix * make_float4(normal, 0.0f);
-								d_normals[dTid.y*rayCastParams.m_width+dTid.x] = make_float4(n.x, n.y, n.z, 1.0f);
-							}
-
-							return;
-						}
-					}
-				}
-
-				lastSample.sdf = dist;
-				lastSample.alpha = rayCurrent;
-				// lastSample.color = color;
-				lastSample.weight = 1;
-				rayCurrent += rayCastParams.m_rayIncrement;
-			} else {
-				lastSample.weight = 0;
-				rayCurrent += rayCastParams.m_rayIncrement;
-			}
-
-			
-		}
-		
-	}
-
-#endif // __CUDACC__
-
-	union {
-	float*  d_depth;
-	int* d_depth_i;
-	};
-	float3* d_depth3;
-	float4* d_normals;
-	uchar3* d_colors;
-
-	//float4* d_vertexBuffer; // ray interval splatting triangles, mapped from directx (memory lives there)
-	float3 *point_cloud_;
-
-	cudaArray* d_rayIntervalSplatMinArray;
-	cudaArray* d_rayIntervalSplatMaxArray;
-};
\ No newline at end of file
diff --git a/applications/reconstruct/include/ftl/sdf_util.hpp b/applications/reconstruct/include/ftl/sdf_util.hpp
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/applications/reconstruct/include/ftl/virtual_source.hpp b/applications/reconstruct/include/ftl/virtual_source.hpp
deleted file mode 100644
index b4162ef9750c867eff78822a9294f5b4f19b7f6e..0000000000000000000000000000000000000000
--- a/applications/reconstruct/include/ftl/virtual_source.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#pragma once
-#ifndef _FTL_RGBD_VIRTUAL_HPP_
-#define _FTL_RGBD_VIRTUAL_HPP_
-
-#include <ftl/rgbd/source.hpp>
-
-class CUDARayCastSDF;
-
-namespace ftl {
-namespace voxhash {
-	class SceneRep;
-}
-
-namespace rgbd {
-
-/**
- * RGBD source from either a stereo video file with left + right images, or
- * direct from two camera devices. A variety of algorithms are included for
- * calculating disparity, before converting to depth.  Calibration of the images
- * is also performed.
- */
-class VirtualSource : public ftl::rgbd::BaseSourceImpl {
-	public:
-	VirtualSource(ftl::rgbd::Source*);
-	~VirtualSource();
-
-	void setScene(ftl::voxhash::SceneRep *);
-
-	bool grab(int n, int b);
-	//void getRGBD(cv::Mat &rgb, cv::Mat &depth);
-	bool isReady();
-
-	private:
-	ftl::voxhash::SceneRep *scene_;
-	CUDARayCastSDF *rays_;
-	bool ready_;
-	cv::Mat idepth_;
-};
-
-}
-}
-
-#endif  // _FTL_RGBD_VIRTUAL_HPP_
diff --git a/applications/reconstruct/include/ftl/voxel_hash_params.hpp b/applications/reconstruct/include/ftl/voxel_hash_params.hpp
deleted file mode 100644
index ac5fcaa726febaff0b56426b6d481d48bae3e421..0000000000000000000000000000000000000000
--- a/applications/reconstruct/include/ftl/voxel_hash_params.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-// From: https://github.com/niessner/VoxelHashing/blob/master/DepthSensingCUDA/Source/CUDAHashParams.h
-
-#pragma once
-
-//#include <cutil_inline.h>
-//#include <cutil_math.h>
-//#include <vector_types.h>
-//#include <cuda_runtime.h>
-
-#include <ftl/cuda_matrix_util.hpp>
-
-namespace ftl {
-namespace voxhash {
-
-static const unsigned int kFlagClipping = 0x00000001;
-static const unsigned int kFlagMLS = 0x00000002;
-
-//TODO might have to be split into static and dynamics
-struct __align__(16) HashParams {
-	HashParams() {
-	}
-
-	unsigned int	m_hashNumBuckets;
-	float			m_virtualVoxelSize;
-	float			m_maxIntegrationDistance;
-	float			m_truncScale;
-	float			m_truncation;
-	unsigned int	m_integrationWeightSample;
-	unsigned int	m_integrationWeightMax;
-
-	float3 m_minBounds;
-	float3 m_maxBounds;
-	float m_spatialSmoothing;
-	float m_colourSmoothing;
-	float m_confidenceThresh;
-
-	unsigned int m_flags;
-};
-
-}  // namespace voxhash
-}  // namespace ftl
diff --git a/applications/reconstruct/include/ftl/voxel_scene.hpp b/applications/reconstruct/include/ftl/voxel_scene.hpp
deleted file mode 100644
index 4ea2d5eb3d98b0a3baac018f2c9ace9b5ad7a6f0..0000000000000000000000000000000000000000
--- a/applications/reconstruct/include/ftl/voxel_scene.hpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// From: https://github.com/niessner/VoxelHashing/blob/master/DepthSensingCUDA/Source/CUDASceneRepHashSDF.h
-
-#pragma once
-
-//#include <cuda_runtime.h>
-
-#include <ftl/cuda_common.hpp>
-#include <ftl/rgbd/source.hpp>
-#include <ftl/configurable.hpp>
-#include <ftl/matrix_conversion.hpp>
-#include <ftl/voxel_hash.hpp>
-#include <ftl/depth_camera.hpp>
-#include <ftl/rgbd/group.hpp>
-#include <unordered_set>
-
-namespace ftl {
-namespace voxhash {
-
-struct Cameras {
-	ftl::rgbd::Source *source;
-	ftl::voxhash::DepthCamera gpu;
-	DepthCameraParams params;
-	cv::cuda::Stream stream;
-};
-
-class SceneRep : public ftl::Configurable {
-	public:
-	SceneRep(nlohmann::json &config);
-	~SceneRep();
-
-	void addSource(ftl::rgbd::Source *);
-
-	/**
-	 * Send all camera frames to GPU and allocate required voxels.
-	 */
-	int upload();
-
-	int upload(ftl::rgbd::FrameSet &);
-
-	/**
-	 * Merge all camera frames into the voxel hash datastructure.
-	 */
-	void integrate();
-
-	/**
-	 * Remove any voxel blocks that are no longer used.
-	 */
-	void garbage();
-
-	// Mark voxels as surfaces
-	// void isosurface();
-
-	void setLastRigidTransform(const Eigen::Matrix4f& lastRigidTransform);
-
-
-	const Eigen::Matrix4f getLastRigidTransform() const;
-
-	/* Nick: To reduce weights between frames */
-	void nextFrame();
-
-	//! resets the hash to the initial state (i.e., clears all data)
-	void reset();
-
-	int cameraCount() const { return (int)cameras_.size(); }
-
-
-	ftl::voxhash::HashData& getHashData() { return m_hashData; } 
-
-	HashParams& getHashParams() { return m_hashParams; }
-
-	unsigned int getOccupiedCount();
-
-	//! debug only!
-	void debugHash();
-
-	cudaStream_t getIntegrationStream() const { return integ_stream_; }
-	int getCUDADevice() const { return cuda_device_; }
-
-	private:
-
-	bool _initCUDA();
-	HashParams _parametersFromConfig();
-	void _create(const HashParams& params);
-	void _destroy();
-	void _alloc(int camid, cudaStream_t);
-	void _compactifyVisible(const DepthCameraParams &camera);
-	void _compactifyAllocated();
-	//void _integrateDepthMap(const DepthCameraData& depthCameraData, const DepthCameraParams& depthCameraParams);
-	void _integrateDepthMaps();
-	void _garbageCollect();
-
-	void _updateCameraConstant();
-
-	HashParams		m_hashParams;
-	ftl::voxhash::HashData		m_hashData;
-
-	//CUDAScan		m_cudaScan;
-	unsigned int	m_numIntegratedFrames;	//used for garbage collect
-	unsigned int	m_frameCount;
-	bool do_reset_;
-	std::vector<Cameras> cameras_;
-	cudaStream_t integ_stream_;
-	bool reg_mode_;
-	int cuda_device_;
-};
-
-};  // namespace voxhash
-};  // namespace ftl
diff --git a/applications/reconstruct/src/camera_util.cu b/applications/reconstruct/src/camera_util.cu
deleted file mode 100644
index e4b434a05792bfa6fe62114118d7b2d40c69f845..0000000000000000000000000000000000000000
--- a/applications/reconstruct/src/camera_util.cu
+++ /dev/null
@@ -1,1769 +0,0 @@
-#ifndef _CAMERA_UTIL_
-#define _CAMERA_UTIL_
-
-#include <ftl/cuda_util.hpp>
-
-#include <ftl/cuda_matrix_util.hpp>
-#include <ftl/depth_camera.hpp>
-
-#ifndef BYTE
-#define BYTE unsigned char
-#endif
-
-#define T_PER_BLOCK 16
-#define MINF __int_as_float(0xff800000)
-
-#ifndef CUDART_PI_F
-#define CUDART_PI_F 3.141592654f
-#endif
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Compute Copy Float Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void copyFloatMapDevice(float* d_output, float* d_input, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	d_output[y*width+x] = d_input[y*width+x];
-}
-
-extern "C" void copyFloatMap(float* d_output, float* d_input, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	copyFloatMapDevice<<<gridSize, blockSize>>>(d_output, d_input, width, height);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-__global__ void copyDepthFloatMapDevice(float* d_output, float* d_input, unsigned int width, unsigned int height, float minDepth, float maxDepth)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	const float depth = d_input[y*width+x];
-	if (depth >= minDepth && depth <= maxDepth) 
-		d_output[y*width+x] = depth;
-	else
-		d_output[y*width+x] = MINF;
-}
-
-extern "C" void copyDepthFloatMap(float* d_output, float* d_input, unsigned int width, unsigned int height, float minDepth, float maxDepth)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	copyDepthFloatMapDevice<<<gridSize, blockSize>>>(d_output, d_input, width, height,minDepth, maxDepth);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Compute Copy Float Map Fill
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void initializeOptimizerMapsDevice(float* d_output, float* d_input, float* d_input2, float* d_mask, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	const float depth = d_input[y*width+x];
-	if(d_mask[y*width+x] != MINF) { d_output[y*width+x] = depth; }
-	else						  { d_output[y*width+x] = MINF; d_input[y*width+x] = MINF; d_input2[y*width+x] = MINF; }
-}
-
-extern "C" void initializeOptimizerMaps(float* d_output, float* d_input, float* d_input2, float* d_mask, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	initializeOptimizerMapsDevice<<<gridSize, blockSize>>>(d_output, d_input, d_input2, d_mask, width, height);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Copy Float4 Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void copyFloat4MapDevice(float4* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	d_output[y*width+x] = d_input[y*width+x];
-}
-
-extern "C" void copyFloat4Map(float4* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	copyFloat4MapDevice<<<gridSize, blockSize>>>(d_output, d_input, width, height);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Convert Raw Color to float
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void convertColorRawToFloatDevice(float4* d_output, BYTE* d_input, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-	
-	//uchar4 c = make_uchar4(d_input[4*(y*width+x)+2], d_input[4*(y*width+x)+1], d_input[4*(y*width+x)+0], d_input[4*(y*width+x)+3]);	//note the flip from BGRW to RGBW
-	uchar4 c = make_uchar4(d_input[4*(y*width+x)+0], d_input[4*(y*width+x)+1], d_input[4*(y*width+x)+2], d_input[4*(y*width+x)+3]);	
-	if (c.x == 0 && c.y == 0 && c.z == 0) {
-		d_output[y*width+x] = make_float4(MINF, MINF, MINF, MINF);
-	} else {
-		d_output[y*width+x] = make_float4(c.x/255.0f, c.y/255.0f, c.z/255.0f, c.w/255);	
-	}
-}
-
-extern "C" void convertColorRawToFloat4(float4* d_output, BYTE* d_input, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	convertColorRawToFloatDevice<<<gridSize, blockSize>>>(d_output, d_input, width, height);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Convert Float4 Color to UCHAR4
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void convertColorFloat4ToUCHAR4Device(uchar4* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	float4 color = d_input[y*width+x];
-	d_output[y*width+x] = make_uchar4(color.x*255.0f, color.y*255.0f, color.z*255.0f, color.w*255.0f);	
-}
-
-extern "C" void convertColorFloat4ToUCHAR4(uchar4* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const dim3 blockSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 gridSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	convertColorFloat4ToUCHAR4Device<<<blockSize, gridSize>>>(d_output, d_input, width, height);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Mask Color Map using Depth
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void maskColorMapFloat4MapDevice(float4* d_inputColor, float4* d_inputDepth, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	float4 color = d_inputColor[y*width+x];
-	
-	if(d_inputDepth[y*width+x].x != MINF)	d_inputColor[y*width+x] = color;	
-	else									d_inputColor[y*width+x] = make_float4(MINF, MINF, MINF, MINF);
-}
-
-extern "C" void maskColorMapFloat4Map(float4* d_inputColor, float4* d_inputDepth, unsigned int width, unsigned int height)
-{
-	const dim3 blockSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 gridSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	maskColorMapFloat4MapDevice<<<blockSize, gridSize>>>(d_inputColor, d_inputDepth, width, height);
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Convert Color to Intensity Float4
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void convertColorToIntensityFloat4Device(float4* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	const float4 color = d_input[y*width+x];
-	const float I = 0.299f*color.x + 0.587f*color.y + 0.114f*color.z;
-
-	d_output[y*width+x] = make_float4(I, I, I, 1.0f);
-}
-
-extern "C" void convertColorToIntensityFloat4(float4* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	convertColorToIntensityFloat4Device<<<gridSize, blockSize>>>(d_output, d_input, width, height);
-
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Convert Color to Intensity
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void convertColorToIntensityFloatDevice(float* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	const float4 color = d_input[y*width+x];
-	d_output[y*width+x] = 0.299f*color.x + 0.587f*color.y + 0.114f*color.z;
-}
-
-extern "C" void convertColorToIntensityFloat(float* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	convertColorToIntensityFloatDevice<<<gridSize, blockSize>>>(d_output, d_input, width, height);
-
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Convert depth map to color map view
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void convertDepthToColorSpaceDevice(float* d_output, float* d_input, float4x4 depthIntrinsicsInv, float4x4 colorIntrinsics, float4x4 depthExtrinsicsInv, float4x4 colorExtrinsics, unsigned int depthWidth, unsigned int depthHeight, unsigned int colorWidth, unsigned int colorHeight)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x < depthWidth && y < depthHeight)
-	{
-		const float depth = d_input[y*depthWidth+x];
-
-		if(depth != MINF && depth < 1.0f)
-		{
-			// Cam space depth
-			float4 depthCamSpace = depthIntrinsicsInv*make_float4((float)x*depth, (float)y*depth, depth, depth);
-			depthCamSpace = make_float4(depthCamSpace.x, depthCamSpace.y, depthCamSpace.w, 1.0f);
-
-			// World Space
-			const float4 worldSpace = depthExtrinsicsInv*depthCamSpace;
-
-			// Cam space color
-			float4 colorCamSpace = colorExtrinsics*worldSpace;
-			//colorCamSpace = make_float4(colorCamSpace.x, colorCamSpace.y, 0.0f, colorCamSpace.z);
-			colorCamSpace = make_float4(colorCamSpace.x, colorCamSpace.y, colorCamSpace.z, 1.0f);
-
-			// Get coordinates in color image and set pixel to new depth
-			const float4 screenSpaceColor  = colorIntrinsics*colorCamSpace;
-			//const unsigned int cx = (unsigned int)(screenSpaceColor.x/screenSpaceColor.w + 0.5f);
-			//const unsigned int cy = (unsigned int)(screenSpaceColor.y/screenSpaceColor.w + 0.5f);
-			const unsigned int cx = (unsigned int)(screenSpaceColor.x/screenSpaceColor.z + 0.5f);
-			const unsigned int cy = (unsigned int)(screenSpaceColor.y/screenSpaceColor.z + 0.5f);
-
-			//if(cx < colorWidth && cy < colorHeight) d_output[cy*colorWidth+cx] = screenSpaceColor.w; // Check for minimum !!!
-			if(cx < colorWidth && cy < colorHeight) d_output[cy*colorWidth+cx] = screenSpaceColor.z; // Check for minimum !!!
-		}
-	}
-}
-
-extern "C" void convertDepthToColorSpace(float* d_output, float* d_input, float4x4 depthIntrinsicsInv, float4x4 colorIntrinsics, float4x4 depthExtrinsicsInv, float4x4 colorExtrinsics, unsigned int depthWidth, unsigned int depthHeight, unsigned int colorWidth, unsigned int colorHeight)
-{
-	const dim3 gridSize((depthWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (depthHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	convertDepthToColorSpaceDevice<<<gridSize, blockSize>>>(d_output, d_input, depthIntrinsicsInv, colorIntrinsics, depthExtrinsicsInv, colorExtrinsics, depthWidth, depthHeight, colorWidth, colorHeight);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Set invalid float map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void setInvalidFloatMapDevice(float* d_output, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	d_output[y*width+x] = MINF;
-}
-
-extern "C" void setInvalidFloatMap(float* d_output, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	setInvalidFloatMapDevice<<<gridSize, blockSize>>>(d_output, width, height);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Set invalid float4 map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void setInvalidFloat4MapDevice(float4* d_output, unsigned int width, unsigned int height)
-{
-	const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	d_output[y*width+x] = make_float4(MINF, MINF, MINF ,MINF);
-}
-
-extern "C" void setInvalidFloat4Map(float4* d_output, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	setInvalidFloat4MapDevice<<<gridSize, blockSize>>>(d_output, width, height);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Convert Depth to Camera Space Positions
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/*__global__ void convertDepthFloatToCameraSpaceFloat3Device(float3* d_output, float* d_input, float4x4 intrinsicsInv, unsigned int width, unsigned int height, DepthCameraData depthCameraData)
-{
-	const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if (x < width && y < height) {
-		d_output[y*width+x] = make_float3(MINF, MINF, MINF);
-
-		float depth = d_input[y*width+x];
-
-		if(depth != MINF)
-		{
-			//float4 cameraSpace(intrinsicsInv*make_float4((float)x*depth, (float)y*depth, depth, depth));
-			//d_output[y*width+x] = make_float4(cameraSpace.x, cameraSpace.y, cameraSpace.w, 1.0f);
-			d_output[y*width+x] = depthCameraData.kinectDepthToSkeleton(x, y, depth);
-		}
-	}
-}
-
-extern "C" void convertDepthFloatToCameraSpaceFloat3(float3* d_output, float* d_input, float4x4 intrinsicsInv, unsigned int width, unsigned int height, const DepthCameraData& depthCameraData)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	convertDepthFloatToCameraSpaceFloat3Device<<<gridSize, blockSize>>>(d_output, d_input, intrinsicsInv, width, height, depthCameraData);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}*/
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Bilateral Filter Float Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-inline __device__ float gaussR(float sigma, float dist)
-{
-	return exp(-(dist*dist)/(2.0*sigma*sigma));
-}
-
-inline __device__ float linearR(float sigma, float dist)
-{
-	return max(1.0f, min(0.0f, 1.0f-(dist*dist)/(2.0*sigma*sigma)));
-}
-
-inline __device__ float gaussD(float sigma, int x, int y)
-{
-	return exp(-((x*x+y*y)/(2.0f*sigma*sigma)));
-}
-
-inline __device__ float gaussD(float sigma, int x)
-{
-	return exp(-((x*x)/(2.0f*sigma*sigma)));
-}
-
-__global__ void bilateralFilterFloatMapDevice(float* d_output, float* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	const int kernelRadius = (int)ceil(2.0*sigmaD);
-
-	d_output[y*width+x] = MINF;
-
-	float sum = 0.0f;
-	float sumWeight = 0.0f;
-
-	const float depthCenter = d_input[y*width+x];
-	if(depthCenter != MINF)
-	{
-		for(int m = x-kernelRadius; m <= x+kernelRadius; m++)
-		{
-			for(int n = y-kernelRadius; n <= y+kernelRadius; n++)
-			{		
-				if(m >= 0 && n >= 0 && m < width && n < height)
-				{
-					const float currentDepth = d_input[n*width+m];
-
-					if (currentDepth != MINF) {
-						const float weight = gaussD(sigmaD, m-x, n-y)*gaussR(sigmaR, currentDepth-depthCenter);
-
-						sumWeight += weight;
-						sum += weight*currentDepth;
-					}
-				}
-			}
-		}
-
-		if(sumWeight > 0.0f) d_output[y*width+x] = sum / sumWeight;
-	}
-}
-
-extern "C" void bilateralFilterFloatMap(float* d_output, float* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	bilateralFilterFloatMapDevice<<<gridSize, blockSize>>>(d_output, d_input, sigmaD, sigmaR, width, height);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Bilateral Filter Float4 Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void bilateralFilterFloat4MapDevice(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	const int kernelRadius = (int)ceil(2.0*sigmaD);
-
-	//d_output[y*width+x] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-	d_output[y*width+x] = make_float4(MINF, MINF, MINF, MINF);
-
-	float4 sum = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-	float sumWeight = 0.0f;
-
-	const float4 depthCenter = d_input[y*width+x];
-	if (depthCenter.x != MINF) {
-		for(int m = x-kernelRadius; m <= x+kernelRadius; m++)
-		{
-			for(int n = y-kernelRadius; n <= y+kernelRadius; n++)
-			{		
-				if(m >= 0 && n >= 0 && m < width && n < height)
-				{
-					const float4 currentDepth = d_input[n*width+m];
-
-					if (currentDepth.x != MINF) {
-						const float weight = gaussD(sigmaD, m-x, n-y)*gaussR(sigmaR, length(currentDepth-depthCenter));
-
-						sum += weight*currentDepth;
-						sumWeight += weight;
-					}
-				}
-			}
-		}
-	}
-	if(sumWeight > 0.0f) d_output[y*width+x] = sum / sumWeight;
-}
-
-extern "C" void bilateralFilterFloat4Map(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize(T_PER_BLOCK, T_PER_BLOCK);	
-	const dim3 blockSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);	
-
-	bilateralFilterFloat4MapDevice<<<gridSize, blockSize>>>(d_output, d_input, sigmaD, sigmaR, width, height);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Gauss Filter Float Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void gaussFilterFloatMapDevice(float* d_output, float* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	const int kernelRadius = (int)ceil(2.0*sigmaD);
-
-	d_output[y*width+x] = MINF;
-
-	float sum = 0.0f;
-	float sumWeight = 0.0f;
-
-	const float depthCenter = d_input[y*width+x];
-	if(depthCenter != MINF)
-	{
-		for(int m = x-kernelRadius; m <= x+kernelRadius; m++)
-		{
-			for(int n = y-kernelRadius; n <= y+kernelRadius; n++)
-			{		
-				if(m >= 0 && n >= 0 && m < width && n < height)
-				{
-					const float currentDepth = d_input[n*width+m];
-
-					if(currentDepth != MINF && fabs(depthCenter-currentDepth) < sigmaR)
-					{
-						const float weight = gaussD(sigmaD, m-x, n-y);
-
-						sumWeight += weight;
-						sum += weight*currentDepth;
-					}
-				}
-			}
-		}
-	}
-
-	if(sumWeight > 0.0f) d_output[y*width+x] = sum / sumWeight;
-}
-
-extern "C" void gaussFilterFloatMap(float* d_output, float* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	gaussFilterFloatMapDevice<<<gridSize, blockSize>>>(d_output, d_input, sigmaD, sigmaR, width, height);
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Gauss Filter Float4 Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void gaussFilterFloat4MapDevice(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	const int kernelRadius = (int)ceil(2.0*sigmaD);
-
-	//d_output[y*width+x] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-	d_output[y*width+x] = make_float4(MINF, MINF, MINF, MINF);
-
-	float4 sum = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-	float sumWeight = 0.0f;
-
-	const float4 depthCenter = d_input[y*width+x];
-	if (depthCenter.x != MINF) {
-		for(int m = x-kernelRadius; m <= x+kernelRadius; m++)
-		{
-			for(int n = y-kernelRadius; n <= y+kernelRadius; n++)
-			{		
-				if(m >= 0 && n >= 0 && m < width && n < height)
-				{
-					const float4 currentDepth = d_input[n*width+m];
-
-					if (currentDepth.x != MINF) {
-						if(length(depthCenter-currentDepth) < sigmaR)
-						{
-							const float weight = gaussD(sigmaD, m-x, n-y);
-
-							sumWeight += weight;
-							sum += weight*currentDepth;
-						}
-					}
-				}
-			}
-		}
-	}
-
-	if(sumWeight > 0.0f) d_output[y*width+x] = sum / sumWeight;
-}
-
-extern "C" void gaussFilterFloat4Map(float4* d_output, float4* d_input, float sigmaD, float sigmaR, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	gaussFilterFloat4MapDevice<<<gridSize, blockSize>>>(d_output, d_input, sigmaD, sigmaR, width, height);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Compute Normal Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void computeNormalsDevice(float4* d_output, float3* d_input, unsigned int width, unsigned int height)
-{
-	const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	d_output[y*width+x] = make_float4(MINF, MINF, MINF, MINF);
-
-	if(x > 0 && x < width-1 && y > 0 && y < height-1)
-	{
-		const float3 CC = d_input[(y+0)*width+(x+0)];
-		const float3 PC = d_input[(y+1)*width+(x+0)];
-		const float3 CP = d_input[(y+0)*width+(x+1)];
-		const float3 MC = d_input[(y-1)*width+(x+0)];
-		const float3 CM = d_input[(y+0)*width+(x-1)];
-
-		if(CC.x != MINF && PC.x != MINF && CP.x != MINF && MC.x != MINF && CM.x != MINF)
-		{
-			const float3 n = cross(PC-MC, CP-CM);
-			const float  l = length(n);
-
-			if(l > 0.0f)
-			{
-				d_output[y*width+x] = make_float4(n/-l, 1.0f);
-			}
-		}
-	}
-}
-
-extern "C" void computeNormals(float4* d_output, float3* d_input, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeNormalsDevice<<<gridSize, blockSize>>>(d_output, d_input, width, height);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Compute Normal Map 2
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void computeNormalsDevice2(float4* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	d_output[y*width+x] = make_float4(MINF, MINF, MINF, MINF);
-
-	if(x > 0 && x < width-1 && y > 0 && y < height-1)
-	{
-		const float4 CC = d_input[(y+0)*width+(x+0)];
-		const float4 MC = d_input[(y-1)*width+(x+0)];
-		const float4 CM = d_input[(y+0)*width+(x-1)];
-
-		if(CC.x != MINF && MC.x != MINF && CM.x != MINF)
-		{
-			const float3 n = cross(make_float3(MC)-make_float3(CC), make_float3(CM)-make_float3(CC));
-			const float  l = length(n);
-
-			if(l > 0.0f)
-			{
-				d_output[y*width+x] = make_float4(n/-l, 1.0f);
-			}
-		}
-	}
-}
-
-extern "C" void computeNormals2(float4* d_output, float4* d_input, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeNormalsDevice2<<<gridSize, blockSize>>>(d_output, d_input, width, height);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Compute Shading Value
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-inline __device__ void evaluateLightingModelTerms(float* d_out, float4 n)
-{
-	d_out[0] = 1.0;
-	d_out[1] = n.y;
-	d_out[2] = n.z;
-	d_out[3] = n.x;
-	d_out[4] = n.x*n.y;
-	d_out[5] = n.y*n.z;
-	d_out[6] = 3*n.z*n.z - 1;
-	d_out[7] = n.z*n.x;
-	d_out[8] = n.x*n.x-n.y*n.y;
-}
-
-inline __device__ float evaluateLightingModel(float* d_lit, float4 n)
-{
-	float tmp[9];
-	evaluateLightingModelTerms(tmp, n);
-
-	float sum = 0.0f;
-	for(unsigned int i = 0; i<9; i++) sum += tmp[i]*d_lit[i];
-
-	return sum;
-}
-
-__global__ void computeShadingValueDevice(float* d_outShading, float* d_indepth, float4* d_normals, float* d_clusterIDs, float* d_albedoEstimates, float4x4 Intrinsic, float* d_litcoeff, unsigned int width, unsigned int height)
-{
-	const unsigned int posx = blockIdx.x*blockDim.x + threadIdx.x;
-	const unsigned int posy = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(posx >= width || posy >= height) return;
-
-	d_outShading[posy*width+posx] = 0;
-
-	if(posx > 0 && posx < width-1 && posy > 0 && posy < height-1)
-	{
-		float4 n = d_normals[posy*width+posx];
-
-		if(n.x != MINF)
-		{
-			n.x = -n.x; // Change handedness
-			n.z = -n.z;
-
-			float albedo = d_albedoEstimates[(unsigned int)(d_clusterIDs[posy*width+posx]+0.5f)];
-			float shadingval = albedo*evaluateLightingModel(d_litcoeff, n);
-
-			if(shadingval<0.0f) shadingval = 0.0f;
-			if(shadingval>1.0f) shadingval = 1.0f;
-
-			d_outShading[posy*width+posx] = shadingval;
-		}
-	}
-}
-
-extern "C" void computeShadingValue(float* d_outShading, float* d_indepth, float4* d_normals, float* d_clusterIDs, float* d_albedoEstimates, float4x4 &Intrinsic, float* d_lighting, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeShadingValueDevice<<<gridSize, blockSize>>>(d_outShading, d_indepth, d_normals, d_clusterIDs, d_albedoEstimates, Intrinsic, d_lighting, width, height);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Simple Segmentation
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void computeSimpleSegmentationDevice(float* d_output, float* d_input, float depthThres, unsigned int width, unsigned int height)
-{
-	const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	const float inputDepth = d_input[y*width+x];
-	if(inputDepth != MINF && inputDepth < depthThres) d_output[y*width+x] = inputDepth;
-	else											  d_output[y*width+x] = MINF;
-}
-
-extern "C" void computeSimpleSegmentation(float* d_output, float* d_input, float depthThres, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeSimpleSegmentationDevice<<<gridSize, blockSize>>>(d_output, d_input, depthThres, width, height);
-
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Compute Edge Mask
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void computeMaskEdgeMapFloat4Device(unsigned char* d_output, float4* d_input, float* d_indepth, float threshold, unsigned int width, unsigned int height)
-{
-	const unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	d_output[y*width+x] = 1;
-	d_output[width*height+y*width+x] = 1;
-
-	const float thre = threshold *threshold *3.0f;
-	if(x > 0 && y > 0 && x < width-1 && y < height-1)
-	{	
-		if(d_indepth[y*width+x] == MINF)
-		{
-			d_output[y*width+x] = 0;
-			d_output[y*width+x-1] = 0;
-			d_output[width*height+y*width+x] = 0;
-			d_output[width*height+(y-1)*width+x] = 0;
-
-			return;
-		}
-
-		const float4& p0 = d_input[(y+0)*width+(x+0)];
-		const float4& p1 = d_input[(y+0)*width+(x+1)];
-		const float4& p2 = d_input[(y+1)*width+(x+0)];
-
-		float dU = sqrt(((p1.x-p0.x)*(p1.x-p0.x) + (p1.y-p0.y) * (p1.y-p0.y) + (p1.z-p0.z)*(p1.z-p0.z))/3.0f);
-		float dV = sqrt(((p2.x-p0.x)*(p2.x-p0.x) + (p2.y-p0.y) * (p2.y-p0.y) + (p2.z-p0.z)*(p2.z-p0.z))/3.0f);
-
-		//float dgradx = abs(d_indepth[y*width+x-1] + d_indepth[y*width+x+1] - 2.0f * d_indepth[y*width+x]);
-		//float dgrady = abs(d_indepth[y*width+x-width] + d_indepth[y*width+x+width] - 2.0f * d_indepth[y*width+x]);
-
-
-		if(dU > thre ) d_output[y*width+x] = 0;
-		if(dV > thre ) d_output[width*height+y*width+x] = 0;
-
-		//remove depth discontinuities
-		const int r = 1;
-		const float thres = 0.01f;
-
-		const float pCC = d_indepth[y*width+x];
-		for(int i = -r; i<=r; i++)
-		{
-			for(int j = -r; j<=r; j++)
-			{
-				int currentX = x+j;
-				int currentY = y+i;
-
-				if(currentX >= 0 && currentX < width && currentY >= 0 && currentY < height)
-				{
-					float d = d_indepth[currentY*width+currentX];
-
-					if(d != MINF && abs(pCC-d) > thres)
-					{
-						d_output[y*width+x] = 0;
-						d_output[width*height+y*width+x] = 0;
-						return;
-					}
-				}
-			}
-		}
-	}
-}
-
-extern "C" void computeMaskEdgeMapFloat4(unsigned char* d_output, float4* d_input, float* d_indepth, float threshold, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeMaskEdgeMapFloat4Device<<<gridSize, blockSize>>>(d_output, d_input, d_indepth, threshold,width, height);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Clear Decission Array for Patch Depth Mask
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void clearDecissionArrayPatchDepthMaskDevice(int* d_output, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= 0 && x < inputWidth && y >= 0 && y < inputHeight) d_output[y*inputWidth+x] = 0;
-}
-
-extern "C" void clearDecissionArrayPatchDepthMask(int* d_output, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const dim3 gridSize((inputWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (inputHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	clearDecissionArrayPatchDepthMaskDevice<<<gridSize, blockSize>>>(d_output, inputWidth, inputHeight);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Decission Array for Patch Depth Mask
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void computeDecissionArrayPatchDepthMaskDevice(int* d_output, float* d_input, unsigned int patchSize, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= 0 && x < inputWidth && y >= 0 && y < inputHeight)
-	{
-		const int patchId_x = x/patchSize;
-		const int patchId_y = y/patchSize;
-		const int nPatchesWidth = (inputWidth+patchSize-1)/patchSize;
-
-		const float d = d_input[y*inputWidth+x];
-		if(d != MINF) atomicMax(&d_output[patchId_y*nPatchesWidth+patchId_x], 1);
-	}
-}
-
-extern "C" void computeDecissionArrayPatchDepthMask(int* d_output, float* d_input, unsigned int patchSize, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const dim3 gridSize((inputWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (inputHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeDecissionArrayPatchDepthMaskDevice<<<gridSize, blockSize>>>(d_output, d_input, patchSize, inputWidth, inputHeight);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Compute Remapping Array for Patch Depth Mask
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void computeRemappingArrayPatchDepthMaskDevice(int* d_output, float* d_input, int* d_prefixSum, unsigned int patchSize, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= 0 && x < inputWidth && y >= 0 && y < inputHeight)
-	{
-		const int patchId_x = x/patchSize;
-		const int patchId_y = y/patchSize;
-
-		const int nPatchesWidth = (inputWidth+patchSize-1)/patchSize;
-
-		const float d = d_input[y*inputWidth+x];
-		if(d != MINF) d_output[d_prefixSum[patchId_y*nPatchesWidth+patchId_x]-1] = patchId_y*nPatchesWidth+patchId_x;
-	}
-}
-
-extern "C" void computeRemappingArrayPatchDepthMask(int* d_output, float* d_input, int* d_prefixSum, unsigned int patchSize, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const dim3 gridSize((inputWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (inputHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeRemappingArrayPatchDepthMaskDevice<<<gridSize, blockSize>>>(d_output, d_input, d_prefixSum, patchSize, inputWidth, inputHeight);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Debug Patch Remap Array
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void DebugPatchRemapArrayDevice(float* d_mask, int* d_remapArray, unsigned int patchSize, unsigned int numElements, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-
-	if(x < numElements)
-	{
-		int patchID = d_remapArray[x];
-
-		const int nPatchesWidth = (inputWidth+patchSize-1)/patchSize;
-		const int patchId_x = patchID%nPatchesWidth;
-		const int patchId_y = patchID/nPatchesWidth;
-
-		for(unsigned int i = 0; i<patchSize; i++)
-		{
-			for(unsigned int j = 0; j<patchSize; j++)
-			{
-				const int pixel_x = patchId_x*patchSize;
-				const int pixel_y = patchId_y*patchSize;
-
-				d_mask[(pixel_y+i)*inputWidth+(pixel_x+j)] = 3.0f;
-			}
-		}
-	}
-}
-
-extern "C" void DebugPatchRemapArray(float* d_mask, int* d_remapArray, unsigned int patchSize, unsigned int numElements, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const dim3 gridSize((numElements + T_PER_BLOCK*T_PER_BLOCK - 1)/(T_PER_BLOCK*T_PER_BLOCK));
-	const dim3 blockSize(T_PER_BLOCK*T_PER_BLOCK);
-
-	DebugPatchRemapArrayDevice<<<gridSize, blockSize>>>(d_mask, d_remapArray, patchSize, numElements, inputWidth, inputHeight);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Resample Float Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-inline __device__ float bilinearInterpolationFloat(float x, float y, float* d_input, unsigned int imageWidth, unsigned int imageHeight)
-{
-	const int2 p00 = make_int2(floor(x), floor(y));
-	const int2 p01 = p00 + make_int2(0.0f, 1.0f);
-	const int2 p10 = p00 + make_int2(1.0f, 0.0f);
-	const int2 p11 = p00 + make_int2(1.0f, 1.0f);
-
-	const float alpha = x - p00.x;
-	const float beta  = y - p00.y;
-
-	float s0 = 0.0f; float w0 = 0.0f;
-	if(p00.x < imageWidth && p00.y < imageHeight) { float v00 = d_input[p00.y*imageWidth + p00.x]; if(v00 != MINF) { s0 += (1.0f-alpha)*v00; w0 += (1.0f-alpha); } }
-	if(p10.x < imageWidth && p10.y < imageHeight) { float v10 = d_input[p10.y*imageWidth + p10.x]; if(v10 != MINF) { s0 +=		 alpha *v10; w0 +=		 alpha ; } }
-
-	float s1 = 0.0f; float w1 = 0.0f;
-	if(p01.x < imageWidth && p01.y < imageHeight) { float v01 = d_input[p01.y*imageWidth + p01.x]; if(v01 != MINF) { s1 += (1.0f-alpha)*v01; w1 += (1.0f-alpha);} }
-	if(p11.x < imageWidth && p11.y < imageHeight) { float v11 = d_input[p11.y*imageWidth + p11.x]; if(v11 != MINF) { s1 +=		 alpha *v11; w1 +=		 alpha ;} }
-
-	const float p0 = s0/w0;
-	const float p1 = s1/w1;
-
-	float ss = 0.0f; float ww = 0.0f;
-	if(w0 > 0.0f) { ss += (1.0f-beta)*p0; ww += (1.0f-beta); }
-	if(w1 > 0.0f) { ss +=		beta *p1; ww +=		  beta ; }
-
-	if(ww > 0.0f) return ss/ww;
-	else		  return MINF;
-}
-
-__global__ void resampleFloatMapDevice(float* d_colorMapResampledFloat, float* d_colorMapFloat, unsigned int inputWidth, unsigned int inputHeight, unsigned int outputWidth, unsigned int outputHeight)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x < outputWidth && y < outputHeight)
-	{
-		const float scaleWidth  = (float)(inputWidth-1) /(float)(outputWidth-1);
-		const float scaleHeight = (float)(inputHeight-1)/(float)(outputHeight-1);
-
-		const unsigned int xInput = (unsigned int)(x*scaleWidth +0.5f);
-		const unsigned int yInput = (unsigned int)(y*scaleHeight+0.5f);
-
-		if(xInput < inputWidth && yInput < inputHeight)
-		{
-			d_colorMapResampledFloat[y*outputWidth+x] = bilinearInterpolationFloat(x*scaleWidth, y*scaleHeight, d_colorMapFloat, inputWidth, inputHeight);
-		}
-	}
-}
-
-extern "C" void resampleFloatMap(float* d_colorMapResampledFloat, unsigned int outputWidth, unsigned int outputHeight, float* d_colorMapFloat, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const dim3 gridSize((outputWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (outputHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	resampleFloatMapDevice<<<gridSize, blockSize>>>(d_colorMapResampledFloat, d_colorMapFloat, inputWidth, inputHeight, outputWidth, outputHeight);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Resample Float4 Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-inline __device__ float4 bilinearInterpolationFloat4(float x, float y, float4* d_input, unsigned int imageWidth, unsigned int imageHeight)
-{
-	const int2 p00 = make_int2(floor(x), floor(y));
-	const int2 p01 = p00 + make_int2(0.0f, 1.0f);
-	const int2 p10 = p00 + make_int2(1.0f, 0.0f);
-	const int2 p11 = p00 + make_int2(1.0f, 1.0f);
-
-	const float alpha = x - p00.x;
-	const float beta  = y - p00.y;
-
-	//const float INVALID = 0.0f;
-	const float INVALID = MINF;
-
-	float4 s0 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float w0 = 0.0f;
-	if(p00.x < imageWidth && p00.y < imageHeight) { float4 v00 = d_input[p00.y*imageWidth + p00.x]; if(v00.x != INVALID && v00.y != INVALID && v00.z != INVALID) { s0 += (1.0f-alpha)*v00; w0 += (1.0f-alpha); } }
-	if(p10.x < imageWidth && p10.y < imageHeight) { float4 v10 = d_input[p10.y*imageWidth + p10.x]; if(v10.x != INVALID && v10.y != INVALID && v10.z != INVALID) { s0 +=		alpha *v10; w0 +=		alpha ; } }
-
-	float4 s1 = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float w1 = 0.0f;
-	if(p01.x < imageWidth && p01.y < imageHeight) { float4 v01 = d_input[p01.y*imageWidth + p01.x]; if(v01.x != INVALID && v01.y != INVALID && v01.z != INVALID) { s1 += (1.0f-alpha)*v01; w1 += (1.0f-alpha);} }
-	if(p11.x < imageWidth && p11.y < imageHeight) { float4 v11 = d_input[p11.y*imageWidth + p11.x]; if(v11.x != INVALID && v11.y != INVALID && v11.z != INVALID) { s1 +=		alpha *v11; w1 +=		alpha ;} }
-
-	const float4 p0 = s0/w0;
-	const float4 p1 = s1/w1;
-
-	float4 ss = make_float4(0.0f, 0.0f, 0.0f, 0.0f); float ww = 0.0f;
-	if(w0 > 0.0f) { ss += (1.0f-beta)*p0; ww += (1.0f-beta); }
-	if(w1 > 0.0f) { ss +=		beta *p1; ww +=		  beta ; }
-
-	if(ww > 0.0f) return ss/ww;
-	else		  return make_float4(MINF, MINF, MINF, MINF);
-}
-
-__global__ void resampleFloat4MapDevice(float4* d_colorMapResampledFloat4, float4* d_colorMapFloat4, unsigned int inputWidth, unsigned int inputHeight, unsigned int outputWidth, unsigned int outputHeight)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x < outputWidth && y < outputHeight)
-	{
-		const float scaleWidth  = (float)(inputWidth-1) /(float)(outputWidth-1);
-		const float scaleHeight = (float)(inputHeight-1)/(float)(outputHeight-1);
-
-		const unsigned int xInput = (unsigned int)(x*scaleWidth +0.5f);
-		const unsigned int yInput = (unsigned int)(y*scaleHeight+0.5f);
-
-		if(xInput < inputWidth && yInput < inputHeight)
-		{
-			d_colorMapResampledFloat4[y*outputWidth+x] = bilinearInterpolationFloat4(x*scaleWidth, y*scaleHeight, d_colorMapFloat4, inputWidth, inputHeight);
-		}
-	}
-}
-
-extern "C" void resampleFloat4Map(float4* d_colorMapResampledFloat4, unsigned int outputWidth, unsigned int outputHeight, float4* d_colorMapFloat4, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const dim3 gridSize((outputWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (outputHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	resampleFloat4MapDevice<<<gridSize, blockSize>>>(d_colorMapResampledFloat4, d_colorMapFloat4, inputWidth, inputHeight, outputWidth, outputHeight);
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Resample Unsigned Char Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void downsampleUnsignedCharMapDevice(unsigned char* d_MapResampled, unsigned char* d_Map, unsigned int inputWidth, unsigned int inputHeight, unsigned int outputWidth, unsigned int outputHeight, unsigned int layerOffsetInput, unsigned int layerOffsetOutput)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= outputWidth || y >= outputHeight) return;
-
-	unsigned char res = 0;
-
-	const unsigned int inputX = 2*x;
-	const unsigned int inputY = 2*y;
-
-	if((inputY+0) < inputHeight && (inputX+0) < inputWidth)	res += d_Map[layerOffsetInput + ((inputY+0)*inputWidth + (inputX+0))];
-	if((inputY+0) < inputHeight && (inputX+1) < inputWidth)	res += d_Map[layerOffsetInput + ((inputY+0)*inputWidth + (inputX+1))];
-	if((inputY+1) < inputHeight && (inputX+0) < inputWidth)	res += d_Map[layerOffsetInput + ((inputY+1)*inputWidth + (inputX+0))];
-	if((inputY+1) < inputHeight && (inputX+1) < inputWidth) res += d_Map[layerOffsetInput + ((inputY+1)*inputWidth + (inputX+1))];
-
-	if(res == 4) d_MapResampled[layerOffsetOutput+(y*outputWidth+x)] = 1;
-	else		 d_MapResampled[layerOffsetOutput+(y*outputWidth+x)] = 0;
-}
-
-extern "C" void downsampleUnsignedCharMap(unsigned char* d_MapResampled, unsigned int outputWidth, unsigned int outputHeight, unsigned char* d_Map, unsigned int inputWidth, unsigned int inputHeight)
-{
-	const dim3 gridSize((outputWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (outputHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	downsampleUnsignedCharMapDevice<<<gridSize, blockSize>>>(d_MapResampled, d_Map, inputWidth, inputHeight, outputWidth, outputHeight, 0, 0);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-
-	downsampleUnsignedCharMapDevice<<<gridSize, blockSize>>>(d_MapResampled, d_Map, inputWidth, inputHeight, outputWidth, outputHeight, inputWidth*inputHeight, outputWidth*outputHeight);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Convert Edge Mask to Float Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void convertEdgeMaskToFloatDevice(float* d_output, unsigned char* d_input, unsigned int width, unsigned int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= width || y >= height) return;
-
-	d_output[y*width+x] = min(d_input[y*width+x], d_input[width*height+y*width+x]);
-}
-
-extern "C" void convertEdgeMaskToFloat(float* d_output, unsigned char* d_input, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	convertEdgeMaskToFloatDevice<<<gridSize, blockSize>>>(d_output, d_input, width, height);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Dilate Depth Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void dilateDepthMapDevice(float* d_output, float* d_input, float* d_inputOrig, int structureSize, int width, int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if(x >= 0 && x < width && y >= 0 && y < height)
-	{
-		float sum = 0.0f;
-		float count = 0.0f;
-		float oldDepth = d_inputOrig[y*width+x];
-		if(oldDepth != MINF && oldDepth != 0)
-		{
-			for(int i = -structureSize; i<=structureSize; i++)
-			{
-				for(int j = -structureSize; j<=structureSize; j++)
-				{
-					if(x+j >= 0 && x+j < width && y+i >= 0 && y+i < height)
-					{
-						const float d = d_input[(y+i)*width+(x+j)];
-
-						if(d != MINF && d != 0.0f && fabs(d-oldDepth) < 0.05f)
-						{
-							sum += d;
-							count += 1.0f;
-						}
-					}
-				}
-			}
-		}
-
-		if(count > ((2*structureSize+1)*(2*structureSize+1))/36) d_output[y*width+x] = 1.0f;
-		else			 d_output[y*width+x] = MINF;
-	}
-}
-
-extern "C" void dilateDepthMapMask(float* d_output, float* d_input, float* d_inputOrig, int structureSize, int width, int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	dilateDepthMapDevice<<<gridSize, blockSize>>>(d_output, d_input, d_inputOrig, structureSize, width, height);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Mean Filter Depth Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void removeDevMeanMapMaskDevice(float* d_output, float* d_input, int structureSize, int width, int height)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	d_output[y*width+x] = d_input[y*width+x];
-
-	if(x >= 0 && x < width && y >= 0 && y < height)
-	{
-		float oldDepth = d_input[y*width+x];
-
-		float mean = 0.0f;
-		float meanSquared = 0.0f;
-		float count = 0.0f;
-		for(int i = -structureSize; i<=structureSize; i++)
-		{
-			for(int j = -structureSize; j<=structureSize; j++)
-			{
-				if(x+j >= 0 && x+j < width && y+i >= 0 && y+i < height)
-				{
-					float depth = d_input[(y+i)*width+(x+j)];
-					if(depth == MINF)
-					{
-						depth = 8.0f;
-					}
-
-					if(depth > 0.0f)
-					{
-						mean		+= depth;
-						meanSquared += depth*depth;
-						count		+= 1.0f;
-					}
-				}
-			}
-		}
-
-		mean/=count;
-		meanSquared/=count;
-
-		float stdDev = sqrt(meanSquared-mean*mean);
-
-		if(fabs(oldDepth-mean) > 0.5f*stdDev)// || stdDev> 0.005f)
-		{
-			d_output[y*width+x] = MINF;
-		}
-	}
-}
-
-extern "C" void removeDevMeanMapMask(float* d_output, float* d_input, int structureSize, unsigned int width, unsigned int height)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	removeDevMeanMapMaskDevice<<<gridSize, blockSize>>>(d_output, d_input, structureSize, width, height);
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-
-
-
-// Nearest neighbour
-inline __device__ bool getValueNearestNeighbourNoCheck(const float2& p, const float4* inputMap, unsigned int imageWidth, unsigned int imageHeight, float4* outValue)
-{
-	const int u = (int)(p.x + 0.5f);
-	const int v = (int)(p.y + 0.5f);
-
-	if(u < 0 || u > imageWidth || v < 0 || v > imageHeight) return false;
-
-	*outValue = inputMap[v*imageWidth + u];
-
-	return true;
-}
-
-inline __device__ bool getValueNearestNeighbour(const float2& p, const float4* inputMap, unsigned int imageWidth, unsigned int imageHeight, float4* outValue)
-{
-	bool valid = getValueNearestNeighbourNoCheck(p, inputMap, imageWidth, imageHeight, outValue);
-	return valid && (outValue->x != MINF && outValue->y != MINF && outValue->z != MINF);
-}
-
-// Nearest neighbour
-inline __device__ bool getValueNearestNeighbourFloatNoCheck(const float2& p, const float* inputMap, unsigned int imageWidth, unsigned int imageHeight, float* outValue)
-{
-	const int u = (int)(p.x + 0.5f);
-	const int v = (int)(p.y + 0.5f);
-
-	if(u < 0 || u > imageWidth || v < 0 || v > imageHeight) return false;
-
-	*outValue = inputMap[v*imageWidth + u];
-
-	return true;
-}
-
-inline __device__ bool getValueNearestNeighbourFloat(const float2& p, const float* inputMap, unsigned int imageWidth, unsigned int imageHeight, float* outValue)
-{
-	bool valid = getValueNearestNeighbourFloatNoCheck(p, inputMap, imageWidth, imageHeight, outValue);
-	return valid && (*outValue != MINF);
-}
-
-/////////////////////////////////////////////
-// Compute derivatives in camera space
-/////////////////////////////////////////////
-
-__global__ void computeDerivativesCameraSpaceDevice(float4* d_positions, unsigned int imageWidth, unsigned int imageHeight, float4* d_positionsDU, float4* d_positionsDV)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	const int index = y*imageWidth+x;
-
-	if(x >= 0 && x < imageWidth && y >= 0 && y < imageHeight)
-	{
-		d_positionsDU[index] = make_float4(MINF, MINF, MINF, MINF);
-		d_positionsDV[index] = make_float4(MINF, MINF, MINF, MINF);
-	
-		if(x > 0 && x < imageWidth - 1 && y > 0 && y < imageHeight - 1)
-		{
-			float4 pos00; bool valid00 = getValueNearestNeighbour(make_float2(x-1, y-1), d_positions, imageWidth, imageHeight, &pos00); if(!valid00) return;
-			float4 pos01; bool valid01 = getValueNearestNeighbour(make_float2(x-1, y-0), d_positions, imageWidth, imageHeight, &pos01); if(!valid01) return;
-			float4 pos02; bool valid02 = getValueNearestNeighbour(make_float2(x-1, y+1), d_positions, imageWidth, imageHeight, &pos02); if(!valid02) return;
-			
-			float4 pos10; bool valid10 = getValueNearestNeighbour(make_float2(x-0, y-1), d_positions, imageWidth, imageHeight, &pos10); if(!valid10) return;
-			float4 pos11; bool valid11 = getValueNearestNeighbour(make_float2(x-0, y-0), d_positions, imageWidth, imageHeight, &pos11); if(!valid11) return;
-			float4 pos12; bool valid12 = getValueNearestNeighbour(make_float2(x-0, y+1), d_positions, imageWidth, imageHeight, &pos12); if(!valid12) return;
-
-			float4 pos20; bool valid20 = getValueNearestNeighbour(make_float2(x+1, y-1), d_positions, imageWidth, imageHeight, &pos20); if(!valid20) return;
-			float4 pos21; bool valid21 = getValueNearestNeighbour(make_float2(x+1, y-0), d_positions, imageWidth, imageHeight, &pos21); if(!valid21) return;
-			float4 pos22; bool valid22 = getValueNearestNeighbour(make_float2(x+1, y+1), d_positions, imageWidth, imageHeight, &pos22); if(!valid22) return;
-
-			float4 resU = (-1.0f)*pos00 + (1.0f)*pos20 +
-						  (-2.0f)*pos01 + (2.0f)*pos21 +
-						  (-1.0f)*pos02 + (1.0f)*pos22;
-			resU /= 8.0f;
-			
-			float4 resV = (-1.0f)*pos00 + (-2.0f)*pos10 + (-1.0f)*pos20 + 
-						  ( 1.0f)*pos02 + ( 2.0f)*pos12 + ( 1.0f)*pos22;
-			resV /= 8.0f;
-
-			//if(mat3x1(make_float3(resU)).norm1D() > 0.02f) return;
-			//if(mat3x1(make_float3(resV)).norm1D() > 0.02f) return;
-
-			d_positionsDU[index] = resU;
-			d_positionsDV[index] = resV;
-		}
-	}
-}
-
-extern "C" void computeDerivativesCameraSpace(float4* d_positions, unsigned int imageWidth, unsigned int imageHeight, float4* d_positionsDU, float4* d_positionsDV)
-{
-
-	const dim3 gridSize((imageWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (imageHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeDerivativesCameraSpaceDevice<<<gridSize, blockSize>>>(d_positions, imageWidth, imageHeight, d_positionsDU, d_positionsDV);
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-
-/////////////////////////////////////////////
-// Compute Intensity and Derivatives
-/////////////////////////////////////////////
-
-__global__ void computeIntensityAndDerivativesDevice(float* d_intensity, unsigned int imageWidth, unsigned int imageHeight, float4* d_intensityAndDerivatives)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	const int index = y*imageWidth+x;
-
-	if(x >= 0 && x < imageWidth && y >= 0 && y < imageHeight)
-	{
-		d_intensityAndDerivatives[index] = make_float4(MINF, MINF, MINF, MINF);
-			
-		if(x > 0 && x < imageWidth - 1 && y > 0 && y < imageHeight - 1)
-		{
-			float pos00; bool valid00 = getValueNearestNeighbourFloat(make_float2(x-1, y-1), d_intensity, imageWidth, imageHeight, &pos00); if(!valid00) return;
-			float pos01; bool valid01 = getValueNearestNeighbourFloat(make_float2(x-1, y-0), d_intensity, imageWidth, imageHeight, &pos01); if(!valid01) return;
-			float pos02; bool valid02 = getValueNearestNeighbourFloat(make_float2(x-1, y+1), d_intensity, imageWidth, imageHeight, &pos02); if(!valid02) return;
-			
-			float pos10; bool valid10 = getValueNearestNeighbourFloat(make_float2(x-0, y-1), d_intensity, imageWidth, imageHeight, &pos10); if(!valid10) return;
-			float pos11; bool valid11 = getValueNearestNeighbourFloat(make_float2(x-0, y-0), d_intensity, imageWidth, imageHeight, &pos11); if(!valid11) return;
-			float pos12; bool valid12 = getValueNearestNeighbourFloat(make_float2(x-0, y+1), d_intensity, imageWidth, imageHeight, &pos12); if(!valid12) return;
-
-			float pos20; bool valid20 = getValueNearestNeighbourFloat(make_float2(x+1, y-1), d_intensity, imageWidth, imageHeight, &pos20); if(!valid20) return;
-			float pos21; bool valid21 = getValueNearestNeighbourFloat(make_float2(x+1, y-0), d_intensity, imageWidth, imageHeight, &pos21); if(!valid21) return;
-			float pos22; bool valid22 = getValueNearestNeighbourFloat(make_float2(x+1, y+1), d_intensity, imageWidth, imageHeight, &pos22); if(!valid22) return;
-
-			float resU = (-1.0f)*pos00 + (1.0f)*pos20 +
-						  (-2.0f)*pos01 + (2.0f)*pos21 +
-						  (-1.0f)*pos02 + (1.0f)*pos22;
-			resU /= 8.0f;
-			
-			float resV = (-1.0f)*pos00 + (-2.0f)*pos10 + (-1.0f)*pos20 + 
-						  ( 1.0f)*pos02 + ( 2.0f)*pos12 + ( 1.0f)*pos22;
-			resV /= 8.0f;
-
-			d_intensityAndDerivatives[index] = make_float4(pos11, resU, resV, 1.0f);
-		}
-	}
-}
-
-extern "C" void computeIntensityAndDerivatives(float* d_intensity, unsigned int imageWidth, unsigned int imageHeight, float4* d_intensityAndDerivatives)
-{
-	const dim3 gridSize((imageWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (imageHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeIntensityAndDerivativesDevice<<<gridSize, blockSize>>>(d_intensity, imageWidth, imageHeight, d_intensityAndDerivatives);
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-
-/////////////////////////////////////////////
-// Compute grdient intensity magnitude
-/////////////////////////////////////////////
-
-__global__ void computeGradientIntensityMagnitudeDevice(float4* d_inputDU, float4* d_inputDV, unsigned int imageWidth, unsigned int imageHeight, float4* d_ouput)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	const int index = y*imageWidth+x;
-
-	d_ouput[index] = make_float4(MINF, MINF, MINF, MINF);
-
-	float4 DU = d_inputDU[index];
-	float4 DV = d_inputDV[index];
-
-	if(DU.x != MINF && DV.x != MINF)
-	{
-		float m = sqrtf(DU.x*DU.x+DV.x*DV.x);
-
-		if(m > 0.005f)
-		{
-			d_ouput[index] = make_float4(m, m, m, 1.0f);
-		}
-	}
-}
-
-extern "C" void computeGradientIntensityMagnitude(float4* d_inputDU, float4* d_inputDV, unsigned int imageWidth, unsigned int imageHeight, float4* d_ouput)
-{
-	const dim3 gridSize((imageWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (imageHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	computeGradientIntensityMagnitudeDevice<<<gridSize, blockSize>>>(d_inputDU, d_inputDV, imageWidth, imageHeight, d_ouput);
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-/////////////////////////////////////////////
-// Transform
-/////////////////////////////////////////////
-
-__global__ void transformCameraSpaceMapDevice(float4* d_positions, unsigned int imageWidth, unsigned int imageHeight,  float4* d_output)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	const int index = y*imageWidth+x;
-
-	if(x >= 0 && x < imageWidth && y >= 0 && y < imageHeight)
-	{
-		d_output[index] = d_positions[index];
-
-		if(d_positions[index].x != MINF && d_positions[index].y != MINF && d_positions[index].z != MINF)
-		{
-			d_output[index] =  d_positions[index]+make_float4(0.0f, 0.0f, 0.0f, 0.0f);
-		}		
-	}
-}
-
-extern "C" void transformCameraSpaceMap(float4* d_positions, unsigned int imageWidth, unsigned int imageHeight,  float4* d_output)
-{
-	const dim3 gridSize((imageWidth + T_PER_BLOCK - 1)/T_PER_BLOCK, (imageHeight + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	transformCameraSpaceMapDevice<<<gridSize, blockSize>>>(d_positions, imageWidth, imageHeight, d_output);
-	#ifdef _DEBUG
-		cudaSafeCall(cudaDeviceSynchronize());
-		//cutilCheckMsg(__FUNCTION__);
-	#endif
-}
-
-
-
-
-
-
-
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Erode Depth Map
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-__global__ void erodeDepthMapDevice(float* d_output, float* d_input, int structureSize, int width, int height, float dThresh, float fracReq)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-
-	if(x >= 0 && x < width && y >= 0 && y < height)
-	{
-		
-
-		unsigned int count = 0;
-
-		float oldDepth = d_input[y*width+x];
-		for(int i = -structureSize; i<=structureSize; i++)
-		{
-			for(int j = -structureSize; j<=structureSize; j++)
-			{
-				if(x+j >= 0 && x+j < width && y+i >= 0 && y+i < height)
-				{
-					float depth = d_input[(y+i)*width+(x+j)];
-					if(depth == MINF || depth == 0.0f || fabs(depth-oldDepth) > dThresh)
-					{
-						count++;
-						//d_output[y*width+x] = MINF;
-						//return;
-					}
-				}
-			}
-		}
-
-		unsigned int sum = (2*structureSize+1)*(2*structureSize+1);
-		if ((float)count/(float)sum >= fracReq) {
-			d_output[y*width+x] = MINF;
-		} else {
-			d_output[y*width+x] = d_input[y*width+x];
-		}
-	}
-}
-
-extern "C" void erodeDepthMap(float* d_output, float* d_input, int structureSize, unsigned int width, unsigned int height, float dThresh, float fracReq)
-{
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	erodeDepthMapDevice<<<gridSize, blockSize>>>(d_output, d_input, structureSize, width, height, dThresh, fracReq);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-
-
-
-////////////////////////////////////
-// Depth to HSV map conversion /////
-////////////////////////////////////
-
-__device__ float3 convertHSVToRGB(const float3& hsv) {
-	float H = hsv.x;
-	float S = hsv.y;
-	float V = hsv.z;
-
-	float hd = H/60.0f;
-	unsigned int h = (unsigned int)hd;
-	float f = hd-h;
-
-	float p = V*(1.0f-S);
-	float q = V*(1.0f-S*f);
-	float t = V*(1.0f-S*(1.0f-f));
-
-	if(h == 0 || h == 6)
-	{
-		return make_float3(V, t, p);
-	}
-	else if(h == 1)
-	{
-		return make_float3(q, V, p);
-	}
-	else if(h == 2)
-	{
-		return make_float3(p, V, t);
-	}
-	else if(h == 3)
-	{
-		return make_float3(p, q, V);
-	}
-	else if(h == 4)
-	{
-		return make_float3(t, p, V);
-	}
-	else
-	{
-		return make_float3(V, p, q);
-	}
-}
-
-
-__device__ float3 convertDepthToRGB(float depth, float depthMin, float depthMax) {
-	float depthZeroOne = (depth - depthMin)/(depthMax - depthMin);
-	float x = 1.0f-depthZeroOne;
-	if (x < 0.0f)	x = 0.0f;
-	if (x > 1.0f)	x = 1.0f;
-	//return convertHSVToRGB(make_float3(240.0f*x, 1.0f, 0.5f));
-	x = 360.0f*x - 120.0f;
-	if (x < 0.0f) x += 359.0f;
-	return convertHSVToRGB(make_float3(x, 1.0f, 0.5f));
-}
-
-__global__ void depthToHSVDevice(float4* d_output, float* d_input, unsigned int width, unsigned int height, float minDepth, float maxDepth)
-{
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-	
-	if (x >= 0 && x < width && y >= 0 && y < height) {
-		
-		float depth = d_input[y*width + x];
-		if (depth != MINF && depth != 0.0f && depth >= minDepth && depth <= maxDepth) {
-			float3 c = convertDepthToRGB(depth, minDepth, maxDepth);
-			d_output[y*width + x] = make_float4(c, 1.0f);
-		} else {
-			d_output[y*width + x] = make_float4(0.0f);
-		}
-	}
-}
-
-extern "C" void depthToHSV(float4* d_output, float* d_input, unsigned int width, unsigned int height, float minDepth, float maxDepth) {
-	const dim3 gridSize((width + T_PER_BLOCK - 1)/T_PER_BLOCK, (height + T_PER_BLOCK - 1)/T_PER_BLOCK);
-	const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-	depthToHSVDevice<<<gridSize, blockSize>>>(d_output, d_input, width, height, minDepth, maxDepth);
-#ifdef _DEBUG
-	cudaSafeCall(cudaDeviceSynchronize());
-	//cutilCheckMsg(__FUNCTION__);
-#endif
-}
-
-
-
-
-
-#endif // _CAMERA_UTIL_
\ No newline at end of file
diff --git a/applications/reconstruct/src/main.cpp b/applications/reconstruct/src/main.cpp
deleted file mode 100644
index 5f37c0961e9e03b9885aede975bee0319fad93f4..0000000000000000000000000000000000000000
--- a/applications/reconstruct/src/main.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright 2019 Nicolas Pope. All rights reserved.
- *
- * See LICENSE.
- */
-
-#define LOGURU_WITH_STREAMS 1
-#include <loguru.hpp>
-#include <ftl/config.h>
-#include <ftl/configuration.hpp>
-#include <ftl/depth_camera.hpp>
-#include <ftl/rgbd.hpp>
-#include <ftl/master.hpp>
-#include <ftl/rgbd/group.hpp>
-#include <ftl/threads.hpp>
-#include <ftl/codecs/writer.hpp>
-#include <ftl/codecs/reader.hpp>
-
-#include "reconstruction.hpp"
-
-#include <fstream>
-#include <string>
-#include <vector>
-#include <thread>
-#include <chrono>
-
-//#include <opencv2/opencv.hpp>
-#include <ftl/net/universe.hpp>
-
-#include <ftl/operators/smoothing.hpp>
-#include <ftl/operators/colours.hpp>
-#include <ftl/operators/normals.hpp>
-#include <ftl/operators/filling.hpp>
-#include <ftl/operators/segmentation.hpp>
-#include <ftl/operators/mask.hpp>
-#include <ftl/operators/antialiasing.hpp>
-#include <ftl/operators/mvmls.hpp>
-#include <ftl/operators/clipping.hpp>
-
-#include <ftl/cuda/normals.hpp>
-
-#include <ftl/codecs/h264.hpp>
-#include <ftl/codecs/hevc.hpp>
-
-#include <ftl/streams/filestream.hpp>
-#include <ftl/streams/receiver.hpp>
-#include <ftl/streams/sender.hpp>
-#include <ftl/streams/netstream.hpp>
-
-#include <ftl/audio/source.hpp>
-
-#include <cuda_profiler_api.h>
-
-#include <nlohmann/json.hpp>
-
-#ifdef WIN32
-#pragma comment(lib, "Rpcrt4.lib")
-#endif
-
-using ftl::net::Universe;
-using std::string;
-using std::vector;
-using ftl::rgbd::Source;
-using ftl::config::json_t;
-using ftl::codecs::Channel;
-
-using json = nlohmann::json;
-using std::this_thread::sleep_for;
-using std::chrono::milliseconds;
-
-
-/* Build a generator using a deprecated list of source objects. */
-static ftl::rgbd::Generator *createSourceGenerator(const std::vector<ftl::rgbd::Source*> &srcs) {
-	
-	auto *grp = new ftl::rgbd::Group();
-	for (auto s : srcs) {
-		s->setChannel(Channel::Depth);
-		grp->addSource(s);
-	}
-	return grp;
-}
-
-static ftl::rgbd::Generator *createFileGenerator(ftl::Configurable *root, const std::string &filename) {
-	ftl::stream::File *stream = ftl::create<ftl::stream::File>(root, "player");
-	stream->set("filename", filename);
-
-	ftl::stream::Receiver *gen = ftl::create<ftl::stream::Receiver>(root, "receiver");
-	gen->setStream(stream);
-
-	stream->begin();
-	stream->select(0, Channel::Colour + Channel::Depth);  // TODO: Choose these elsewhere
-	return gen;
-}
-
-static void threadSetCUDADevice() {
-	// Ensure all threads have correct cuda device
-	std::atomic<int> ijobs = 0;
-	for (int i=0; i<ftl::pool.size(); ++i) {
-		ftl::pool.push([&ijobs](int id) {
-			ftl::cuda::setDevice();
-			++ijobs;
-			while (ijobs < ftl::pool.size()) std::this_thread::sleep_for(std::chrono::milliseconds(10));
-		});
-	}
-	while (ijobs < ftl::pool.size()) std::this_thread::sleep_for(std::chrono::milliseconds(10));
-}
-
-static void run(ftl::Configurable *root) {
-	// Use other GPU if available.
-	ftl::cuda::setDevice(ftl::cuda::deviceCount()-1);
-	threadSetCUDADevice();
-	ftl::timer::setClockSlave(false);  // don't sync clocks.
-	
-
-	Universe *net = ftl::create<Universe>(root, "net");
-	ftl::ctrl::Master ctrl(root, net);
-
-	net->start();
-	net->waitConnections();
-
-	// TODO temporary fix to for set_pose_adjustment from gui->reconstruct->vision
-	net->bind("set_pose_adjustment",
-		[net](cv::Mat T){ net->broadcast("set_pose_adjustment", T); }
-	);
-
-	vector<ftl::Reconstruction*> groups;
-
-	ftl::codecs::Channels channels;
-
-	ftl::stream::Sender *sender = ftl::create<ftl::stream::Sender>(root, "sender");
-	ftl::stream::Net *outstream = ftl::create<ftl::stream::Net>(root, "stream", net);
-	outstream->set("uri", "ftl://test.utu.fi");
-	outstream->begin();
-	sender->setStream(outstream);
-
-	ftl::audio::Source *audioSrc = nullptr;
-	// TODO: Temporary reconstruction local audio source for testing
-	audioSrc = ftl::create<ftl::audio::Source>(root, "audio_test");
-
-	audioSrc->onFrameSet([sender](ftl::audio::FrameSet &fs) {
-		sender->post(fs);
-		return true;
-	});
-
-	std::vector<Source*> sources;
-	// Create a vector of all input RGB-Depth sources
-	if (root->getConfig()["sources"].size() > 0) {
-		sources = ftl::createArray<Source>(root, "sources", net);
-		auto *gen = createSourceGenerator(sources);
-		auto reconstr = ftl::create<ftl::Reconstruction>(root, "0", "0");
-		reconstr->setGenerator(gen);
-		reconstr->onFrameSet([sender](ftl::rgbd::FrameSet &fs) {
-			fs.id = 0;
-			sender->post(fs);
-			return true;
-		});
-		groups.push_back(reconstr);
-	}
-
-	// Check paths for FTL files to load.
-	auto paths = (*root->get<nlohmann::json>("paths"));
-	int i = groups.size();
-	for (auto &x : paths.items()) {
-		std::string path = x.value().get<std::string>();
-		auto eix = path.find_last_of('.');
-		auto ext = path.substr(eix+1);
-
-		// Command line path is ftl file
-		if (ext == "ftl") {
-			// Create temp reader to count number of sources found in file
-			std::ifstream file;
-			file.open(path);
-			ftl::codecs::Reader reader(file);
-			reader.begin();
-
-			int max_stream = 0;
-			reader.read(reader.getStartTime()+100, [&max_stream,&channels](const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) {
-				max_stream = max(max_stream, spkt.streamID);
-				if ((int)spkt.channel < 32) channels |= spkt.channel;
-			});
-			reader.end();
-
-			LOG(INFO) << "Found " << (max_stream+1) << " sources in " << path;
-
-			auto *gen = createFileGenerator(root, path);
-
-			auto reconstr = ftl::create<ftl::Reconstruction>(root, std::string("recon")+std::to_string(i), std::to_string(i));
-			reconstr->setGenerator(gen);
-			reconstr->onFrameSet([sender,i](ftl::rgbd::FrameSet &fs) {
-				fs.id = i;
-				//fs.frames[0].create(Channel::Data, 44);
-				sender->post(fs);
-				return true;
-			});
-			groups.push_back(reconstr);
-			++i;
-		} else {
-			ftl::URI uri(path);
-			if (uri.getScheme() == ftl::URI::SCHEME_TCP || uri.getScheme() == ftl::URI::SCHEME_WS) {
-				net->connect(path)->waitConnection();
-			}
-		}
-	}
-
-	if (groups.size() == 0) {
-		LOG(ERROR) << "No sources configured!";
-
-		auto stream_uris = net->findAll<std::string>("list_streams");
-
-		if (stream_uris.size() > 0) {
-			ftl::stream::Muxer *stream = ftl::create<ftl::stream::Muxer>(root, "muxstream");
-			ftl::stream::Receiver *gen = ftl::create<ftl::stream::Receiver>(root, "receiver");
-			gen->setStream(stream);
-
-			sender->onRequest([stream](const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt) {
-				if (spkt.channel == Channel::Colour) {
-					stream->reset();
-				}
-			});
-
-			int count = 0;
-			for (auto &s : stream_uris) {
-				LOG(INFO) << " --- found stream: " << s;
-				auto *nstream = ftl::create<ftl::stream::Net>(stream, std::string("netstream")+std::to_string(count), net);
-				nstream->set("uri", s);
-				stream->add(nstream);
-				++count;
-			}
-
-			auto reconstr = ftl::create<ftl::Reconstruction>(root, std::string("recon")+std::to_string(i), std::to_string(i));
-			//reconstr->setGenerator(gen);
-			gen->onFrameSet([stream, reconstr](ftl::rgbd::FrameSet &fs) {
-				stream->select(fs.id, Channel::Colour + Channel::Depth);
-				return reconstr->post(fs);
-			});
-
-			gen->onAudio([sender](ftl::audio::FrameSet &fs) {
-				sender->post(fs);
-				return true;
-			});
-
-			int i = groups.size();
-			reconstr->onFrameSet([sender,i](ftl::rgbd::FrameSet &fs) {
-				fs.id = i;
-				sender->post(fs);
-				return true;
-			});
-			groups.push_back(reconstr);
-			stream->begin();
-		} else {
-			return;
-		}
-	}
-
-	LOG(INFO) << "Start timer";
-	ftl::timer::start(true);
-
-	if (audioSrc) delete audioSrc;
-
-	LOG(INFO) << "Shutting down...";
-	ftl::timer::stop();
-	ftl::pool.stop(true);
-	ctrl.stop();
-	net->shutdown();
-
-	//cudaProfilerStop();
-
-	LOG(INFO) << "Deleting...";
-
-	delete sender;
-	delete outstream;
-	delete net;
-	for (auto g : groups) {
-		delete g;
-	}
-
-	ftl::config::cleanup();  // Remove any last configurable objects.
-	LOG(INFO) << "Done.";
-}
-
-int main(int argc, char **argv) {
-	run(ftl::configure(argc, argv, "reconstruction_default"));
-}
diff --git a/applications/reconstruct/src/reconstruction.cpp b/applications/reconstruct/src/reconstruction.cpp
deleted file mode 100644
index a0c69b754f5bdd5b7e3e6d463e42eaa94ed87d0d..0000000000000000000000000000000000000000
--- a/applications/reconstruct/src/reconstruction.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-#include "reconstruction.hpp"
-
-#include "ftl/operators/smoothing.hpp"
-#include "ftl/operators/colours.hpp"
-#include "ftl/operators/normals.hpp"
-#include "ftl/operators/filling.hpp"
-#include "ftl/operators/segmentation.hpp"
-#include "ftl/operators/mask.hpp"
-#include "ftl/operators/antialiasing.hpp"
-#include "ftl/operators/mvmls.hpp"
-#include "ftl/operators/clipping.hpp"
-#include <ftl/operators/disparity.hpp>
-#include <ftl/operators/poser.hpp>
-#include <ftl/operators/detectandtrack.hpp>
-
-using ftl::Reconstruction;
-using ftl::codecs::Channel;
-
-Reconstruction::Reconstruction(nlohmann::json &config, const std::string name) :
-	ftl::Configurable(config), busy_(false), rbusy_(false), new_frame_(false), fs_render_(), fs_align_() {
-	gen_ = nullptr;
-
-	//renderer_ = ftl::create<ftl::render::Triangular>(this, "renderer", &fs_render_);
-
-	pipeline_ = ftl::config::create<ftl::operators::Graph>(this, "pre_filters");
-	pipeline_->append<ftl::operators::DepthChannel>("depth");  // Ensure there is a depth channel
-	pipeline_->append<ftl::operators::DisparityBilateralFilter>("bilateral_filter")->value("enabled", false);
-	pipeline_->append<ftl::operators::DisparityToDepth>("calculate_depth")->value("enabled", false);
-	pipeline_->append<ftl::operators::ColourChannels>("colour");  // Convert BGR to BGRA
-	pipeline_->append<ftl::operators::ClipScene>("clipping")->value("enabled", false);
-	//pipeline_->append<ftl::operators::HFSmoother>("hfnoise");  // Remove high-frequency noise
-	pipeline_->append<ftl::operators::Normals>("normals");  // Estimate surface normals
-	//pipeline_->append<ftl::operators::SmoothChannel>("smoothing");  // Generate a smoothing channel
-	//pipeline_->append<ftl::operators::ScanFieldFill>("filling");  // Generate a smoothing channel
-	pipeline_->append<ftl::operators::CrossSupport>("cross");
-	pipeline_->append<ftl::operators::DiscontinuityMask>("discontinuity");
-	pipeline_->append<ftl::operators::CrossSupport>("cross2")->value("discon_support", true);
-	pipeline_->append<ftl::operators::BorderMask>("border_mask")->value("enabled", false);
-	pipeline_->append<ftl::operators::CullDiscontinuity>("remove_discontinuity")->set("enabled", false);
-	//pipeline_->append<ftl::operators::AggreMLS>("mls");  // Perform MLS (using smoothing channel)
-	pipeline_->append<ftl::operators::VisCrossSupport>("viscross")->value("enabled", false);
-	pipeline_->append<ftl::operators::MultiViewMLS>("mvmls");
-	pipeline_->append<ftl::operators::Poser>("poser")->value("enabled", false);
-	pipeline_->append<ftl::operators::DetectAndTrack>("facedetection")->value("enabled", false);
-	pipeline_->append<ftl::operators::ArUco>("aruco")->value("enabled", false);
-	//pipeline_->set("enabled", false);
-}
-
-Reconstruction::~Reconstruction() {
-	// TODO delete
-}
-
-size_t Reconstruction::size() {
-	UNIQUE_LOCK(exchange_mtx_, lk);
-	return fs_align_.frames.size();
-}
-
-
-ftl::rgbd::FrameState &Reconstruction::state(size_t ix) {
-	UNIQUE_LOCK(exchange_mtx_, lk);
-	if (ix < fs_align_.frames.size()) {
-		return *fs_align_.frames[ix].origin();
-	}
-	throw FTL_Error("State index out-of-bounds");
-}
-
-void Reconstruction::onFrameSet(const ftl::rgbd::VideoCallback &cb) {
-	cb_ = cb;
-}
-
-bool Reconstruction::post(ftl::rgbd::FrameSet &fs) {
-	pipeline_->apply(fs, fs, 0);
-
-	/*for (size_t i=0; i<fs.frames.size(); ++i) {
-		fs.frames[i].create<cv::cuda::GpuMat>(Channel::Depth);
-	}*/
-
-	{
-		//UNIQUE_LOCK(exchange_mtx_, lk);
-		//if (new_frame_ == true) LOG(WARNING) << "Frame lost";
-		fs.swapTo(fs_align_);
-		new_frame_ = true;
-	}
-
-	if (cb_) {
-		ftl::pool.push([this](int id) {
-			UNIQUE_LOCK(fs_align_.mtx, lk);
-			if (new_frame_) {
-				//{
-					//UNIQUE_LOCK(exchange_mtx_, lk);
-					new_frame_ = false;
-					fs_align_.swapTo(fs_render_);
-				//}
-
-				UNIQUE_LOCK(fs_render_.mtx, lk2);
-				lk.unlock();
-
-				if (cb_) cb_(fs_render_);
-			}
-		});
-	}
-
-	return true;
-}
-
-void Reconstruction::setGenerator(ftl::rgbd::Generator *gen) {
-	if (gen_) {
-		throw FTL_Error("Reconstruction already has generator");
-	}
-
-	gen_ = gen;
-	gen_->onFrameSet([this](ftl::rgbd::FrameSet &fs) -> bool {
-		return post(fs);
-	});
-}
-
-/*void Reconstruction::addSource(ftl::rgbd::Source *src) {
-	//src->setChannel(Channel::Depth);
-	group_->addSource(src); // TODO: check if source is already in group?
-}
-
-void Reconstruction::addRawCallback(const std::function<void(ftl::rgbd::Source *src, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt)> &cb) {
-	group_->addRawCallback(cb);
-}*/
-
-/*bool Reconstruction::render(ftl::rgbd::VirtualSource *vs, ftl::rgbd::Frame &out) {
-	{
-		UNIQUE_LOCK(exchange_mtx_, lk);
-		if (new_frame_) {
-			new_frame_ = false;
-			fs_align_.swapTo(fs_render_);
-		}
-	}
-
-
-	// Create scene transform, intended for axis aligning the walls and floor
-	Eigen::Matrix4d transform;
-	//if (getConfig()["transform"].is_object()) {
-		//auto &c = getConfig()["transform"];
-		float rx = value("transform_pitch", 0.0f);
-		float ry = value("transform_yaw", 0.0f);
-		float rz = value("transform_roll", 0.0f);
-		float x = value("transform_x", 0.0f);
-		float y = value("transform_y", 0.0f);
-		float z = value("transform_z", 0.0f);
-
-		Eigen::Affine3d r = create_rotation_matrix(rx, ry, rz);
-		Eigen::Translation3d trans(Eigen::Vector3d(x,y,z));
-		Eigen::Affine3d t(trans);
-		transform = t.matrix() * r.matrix();
-		//LOG(INFO) << "Set transform: " << transform;
-	//} else {
-	//	transform.setIdentity();
-	//}
-
-	//Eigen::Affine3d sm = Eigen::Affine3d(Eigen::Scaling(double(value("scale", 1.0f))));
-	bool res = false; //renderer_->render(vs, out, sm.matrix() * transform);
-	//fs_render_.resetFull();
-	return res;
-}*/
\ No newline at end of file
diff --git a/applications/reconstruct/src/reconstruction.hpp b/applications/reconstruct/src/reconstruction.hpp
deleted file mode 100644
index 4e545cf8520158e23891d6d37819f354768c95b9..0000000000000000000000000000000000000000
--- a/applications/reconstruct/src/reconstruction.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef _FTL_RECONSTRUCTION_HPP_
-#define _FTL_RECONSTRUCTION_HPP_
-
-#include "ftl/configurable.hpp"
-#include "ftl/rgbd/source.hpp"
-#include "ftl/rgbd/frame.hpp"
-#include "ftl/rgbd/group.hpp"
-#include "ftl/rgbd/frameset.hpp"
-#include "ftl/operators/operator.hpp"
-
-namespace ftl {
-
-class Reconstruction : public ftl::Configurable, public ftl::rgbd::Generator {
-	public:
-	Reconstruction(nlohmann::json &config, const std::string name);
-	~Reconstruction();
-
-	//void addSource(ftl::rgbd::Source *);
-
-	//void addRawCallback(const std::function<void(ftl::rgbd::Source *src, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt)> &cb);
-
-	void setGenerator(ftl::rgbd::Generator *);
-
-	/** Number of frames in last frameset. This can change over time. */
-	size_t size() override;
-
-	/**
-	 * Get the persistent state object for a frame. An exception is thrown
-	 * for a bad index.
-	 */
-	ftl::rgbd::FrameState &state(size_t ix) override;
-
-	/** Register a callback to receive new frame sets. */
-	void onFrameSet(const ftl::rgbd::VideoCallback &) override;
-
-	bool post(ftl::rgbd::FrameSet &fs);
-
-	private:
-	bool busy_;
-	bool rbusy_;
-	bool new_frame_;
-	MUTEX exchange_mtx_;
-	
-	ftl::rgbd::FrameSet fs_render_;
-	ftl::rgbd::FrameSet fs_align_;
-	ftl::rgbd::Generator *gen_;
-	ftl::operators::Graph *pipeline_;
-
-	ftl::rgbd::VideoCallback cb_;
-
-	std::vector<cv::cuda::GpuMat> rgb_;
-};
-
-}
-
-#endif  // _FTL_RECONSTRUCTION_HPP_
diff --git a/applications/tools/middlebury_gen/src/main.cpp b/applications/tools/middlebury_gen/src/main.cpp
index db7e380ba9aa89af9ad3561bb6420e4460cff4b1..542dfbae3529ebd97562dfb95546b7fc491d876e 100644
--- a/applications/tools/middlebury_gen/src/main.cpp
+++ b/applications/tools/middlebury_gen/src/main.cpp
@@ -15,7 +15,6 @@
 #include <loguru.hpp>
 
 using ftl::codecs::Channel;
-using ftl::codecs::definition_t;
 using ftl::codecs::codec_t;
 using std::string;
 
@@ -221,7 +220,7 @@ int main(int argc, char **argv) {
 
 	ftl::operators::DisparityToDepth disp2depth(nullptr, ftl::create<ftl::Configurable>(root, "disparity"));
 
-	ftl::codecs::OpenCVEncoder encoder(ftl::codecs::definition_t::Any, ftl::codecs::definition_t::Any);
+	ftl::codecs::OpenCVEncoder encoder;
 
 	int i=0;
 	for (auto &x : paths.items()) {
@@ -260,24 +259,13 @@ int main(int argc, char **argv) {
 			cv::resize(c1, c1, cv::Size(int(aspect*float(height)),height));
 			cv::resize(c2, c2, cv::Size(int(aspect*float(height)),height));
 
-			int original_width = c1.cols;
-			int desired_width = ftl::codecs::getWidth(ftl::codecs::findDefinition(height));
-			int border_size = (desired_width - c1.cols) / 2;
-			cv::copyMakeBorder(c1, c1, 0, 0, border_size, desired_width - border_size - c1.cols, cv::BORDER_CONSTANT, cv::Scalar(0));
-			cv::copyMakeBorder(c2, c2, 0, 0, border_size, desired_width - border_size - c2.cols, cv::BORDER_CONSTANT, cv::Scalar(0));
-			cv::copyMakeBorder(disp, disp, 0, 0, border_size, desired_width - border_size - disp.cols, cv::BORDER_CONSTANT, cv::Scalar(0));
-
 			// TODO: Adjust principle points (cx)
 
 			LOG(INFO) << "Disparity scaling: " << scaling;
 			LOG(INFO) << "Depth range: " << intrin1.minDepth << " to " << intrin1.maxDepth;
 			LOG(INFO) << "Resolution: " << c1.cols << "x" << c1.rows;
 			disp.convertTo(disp, CV_32F, scaling);
-
-			intrin1 = intrin1.scaled(original_width, c1.rows);
-			intrin2 = intrin2.scaled(original_width, c2.rows);
-			intrin1.cx -= border_size;
-			intrin2.cx -= border_size;
+			
 			intrin1.width = c1.cols;
 			intrin2.width = c2.cols;
 
diff --git a/applications/tools/simple_viewer/main.cpp b/applications/tools/simple_viewer/main.cpp
index 6a3883749e9aaadbd5df0ba1c011a0bb75a55cec..5369393505dea3a5b163343bbf1da1bbd033f25a 100644
--- a/applications/tools/simple_viewer/main.cpp
+++ b/applications/tools/simple_viewer/main.cpp
@@ -47,7 +47,6 @@ using std::vector;
 using ftl::config::json_t;
 using ftl::codecs::Channel;
 using ftl::codecs::codec_t;
-using ftl::codecs::definition_t;
 
 using json = nlohmann::json;
 using std::this_thread::sleep_for;
diff --git a/applications/vision/CMakeLists.txt b/applications/vision/CMakeLists.txt
index bdd0a80eec872fb95d8a70feb0289b0dc206816c..089324e5dbbf051e2beaeec4cfef46cf864e43fc 100644
--- a/applications/vision/CMakeLists.txt
+++ b/applications/vision/CMakeLists.txt
@@ -1,27 +1,14 @@
-# Need to include staged files and libs
-#include_directories(${PROJECT_SOURCE_DIR}/vision/include)
-#include_directories(${PROJECT_BINARY_DIR})
-
-#add_subdirectory(lib)
-
 set(CVNODESRC
 	src/main.cpp
-	#src/middlebury.cpp
 )
 
 add_executable(voltu-vision ${CVNODESRC})
 install(TARGETS voltu-vision RUNTIME COMPONENT vision)
 
-target_include_directories(voltu-vision PUBLIC
-	$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
-	$<INSTALL_INTERFACE:include>
-	PRIVATE src)
-
 if (CUDA_FOUND)
 set_property(TARGET voltu-vision PROPERTY CUDA_SEPARABLE_COMPILATION OFF)
 endif()
 
-#target_include_directories(cv-node PUBLIC ${PROJECT_SOURCE_DIR}/include)
 target_link_libraries(voltu-vision ftlrgbd ftlcommon ftlstreams ftlctrl ${OpenCV_LIBS} ${CUDA_LIBRARIES} ftlnet ftlaudio)
 
 target_precompile_headers(voltu-vision REUSE_FROM ftldata)
diff --git a/applications/vision/include/elas.h b/applications/vision/include/elas.h
deleted file mode 100644
index e10acf0c7009273a020b21b49063c72e42f9ab88..0000000000000000000000000000000000000000
--- a/applications/vision/include/elas.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
-Copyright 2011. All rights reserved.
-Institute of Measurement and Control Systems
-Karlsruhe Institute of Technology, Germany
-
-This file is part of libelas.
-Authors: Andreas Geiger
-
-libelas is free software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the Free Software
-Foundation; either version 3 of the License, or any later version.
-
-libelas is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with
-libelas; if not, write to the Free Software Foundation, Inc., 51 Franklin
-Street, Fifth Floor, Boston, MA 02110-1301, USA 
-*/
-
-// Main header file. Include this to use libelas in your code.
-
-#ifndef __ELAS_H__
-#define __ELAS_H__
-
-#include <iostream>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <vector>
-#include <emmintrin.h>
-
-// define fixed-width datatypes for Visual Studio projects
-#ifndef _MSC_VER
-  #include <stdint.h>
-#else
-//  typedef __int8            int8_t;
-//  typedef __int16           int16_t;
-//  typedef __int32           int32_t;
-//  typedef __int64           int64_t;
-//  typedef unsigned __int8   uint8_t;
-//  typedef unsigned __int16  uint16_t;
-//  typedef unsigned __int32  uint32_t;
-//  typedef unsigned __int64  uint64_t;
-#endif
-
-#ifdef PROFILE
-#include "timer.h"
-#endif
-
-class Elas {
-  
-public:
-  
-  enum setting {ROBOTICS,MIDDLEBURY};
-  
-  // parameter settings
-  struct parameters {
-    int32_t disp_min;               // min disparity
-    int32_t disp_max;               // max disparity
-    float   support_threshold;      // max. uniqueness ratio (best vs. second best support match)
-    int32_t support_texture;        // min texture for support points
-    int32_t candidate_stepsize;     // step size of regular grid on which support points are matched
-    int32_t incon_window_size;      // window size of inconsistent support point check
-    int32_t incon_threshold;        // disparity similarity threshold for support point to be considered consistent
-    int32_t incon_min_support;      // minimum number of consistent support points
-    bool    add_corners;            // add support points at image corners with nearest neighbor disparities
-    int32_t grid_size;              // size of neighborhood for additional support point extrapolation
-    float   beta;                   // image likelihood parameter
-    float   gamma;                  // prior constant
-    float   sigma;                  // prior sigma
-    float   sradius;                // prior sigma radius
-    int32_t match_texture;          // min texture for dense matching
-    int32_t lr_threshold;           // disparity threshold for left/right consistency check
-    float   speckle_sim_threshold;  // similarity threshold for speckle segmentation
-    int32_t speckle_size;           // maximal size of a speckle (small speckles get removed)
-    int32_t ipol_gap_width;         // interpolate small gaps (left<->right, top<->bottom)
-    bool    filter_median;          // optional median filter (approximated)
-    bool    filter_adaptive_mean;   // optional adaptive mean filter (approximated)
-    bool    postprocess_only_left;  // saves time by not postprocessing the right image
-    bool    subsampling;            // saves time by only computing disparities for each 2nd pixel
-                                    // note: for this option D1 and D2 must be passed with size
-                                    //       width/2 x height/2 (rounded towards zero)
-    
-    // constructor
-    parameters (setting s=ROBOTICS) {
-      
-      // default settings in a robotics environment
-      // (do not produce results in half-occluded areas
-      //  and are a bit more robust towards lighting etc.)
-      if (s==ROBOTICS) {
-        disp_min              = 0;
-        disp_max              = 255;
-        support_threshold     = 0.85;
-        support_texture       = 10;
-        candidate_stepsize    = 5;
-        incon_window_size     = 5;
-        incon_threshold       = 5;
-        incon_min_support     = 5;
-        add_corners           = 0;
-        grid_size             = 20;
-        beta                  = 0.02;
-        gamma                 = 3;
-        sigma                 = 1;
-        sradius               = 2;
-        match_texture         = 1;
-        lr_threshold          = 2;
-        speckle_sim_threshold = 1;
-        speckle_size          = 200;
-        ipol_gap_width        = 3;
-        filter_median         = 0;
-        filter_adaptive_mean  = 1;
-        postprocess_only_left = 1;
-        subsampling           = 0;
-        
-      // default settings for middlebury benchmark
-      // (interpolate all missing disparities)
-      } else {
-        disp_min              = 0;
-        disp_max              = 255;
-        support_threshold     = 0.95;
-        support_texture       = 10;
-        candidate_stepsize    = 5;
-        incon_window_size     = 5;
-        incon_threshold       = 5;
-        incon_min_support     = 5;
-        add_corners           = 1;
-        grid_size             = 20;
-        beta                  = 0.02;
-        gamma                 = 5;
-        sigma                 = 1;
-        sradius               = 3;
-        match_texture         = 0;
-        lr_threshold          = 2;
-        speckle_sim_threshold = 1;
-        speckle_size          = 200;
-        ipol_gap_width        = 5000;
-        filter_median         = 1;
-        filter_adaptive_mean  = 0;
-        postprocess_only_left = 0;
-        subsampling           = 0;
-      }
-    }
-  };
-
-  // constructor, input: parameters  
-  Elas (parameters param) : param(param) {}
-
-  // deconstructor
-  ~Elas () {}
-  
-  // matching function
-  // inputs: pointers to left (I1) and right (I2) intensity image (uint8, input)
-  //         pointers to left (D1) and right (D2) disparity image (float, output)
-  //         dims[0] = width of I1 and I2
-  //         dims[1] = height of I1 and I2
-  //         dims[2] = bytes per line (often equal to width, but allowed to differ)
-  //         note: D1 and D2 must be allocated before (bytes per line = width)
-  //               if subsampling is not active their size is width x height,
-  //               otherwise width/2 x height/2 (rounded towards zero)
-  void process (uint8_t* I1,uint8_t* I2,float* D1,float* D2,const int32_t* dims);
-  
-private:
-  
-  struct support_pt {
-    int32_t u;
-    int32_t v;
-    int32_t d;
-    support_pt(int32_t u,int32_t v,int32_t d):u(u),v(v),d(d){}
-  };
-
-  struct triangle {
-    int32_t c1,c2,c3;
-    float   t1a,t1b,t1c;
-    float   t2a,t2b,t2c;
-    triangle(int32_t c1,int32_t c2,int32_t c3):c1(c1),c2(c2),c3(c3){}
-  };
-
-  inline uint32_t getAddressOffsetImage (const int32_t& u,const int32_t& v,const int32_t& width) {
-    return v*width+u;
-  }
-
-  inline uint32_t getAddressOffsetGrid (const int32_t& x,const int32_t& y,const int32_t& d,const int32_t& width,const int32_t& disp_num) {
-    return (y*width+x)*disp_num+d;
-  }
-
-  // support point functions
-  void removeInconsistentSupportPoints (int16_t* D_can,int32_t D_can_width,int32_t D_can_height);
-  void removeRedundantSupportPoints (int16_t* D_can,int32_t D_can_width,int32_t D_can_height,
-                                     int32_t redun_max_dist, int32_t redun_threshold, bool vertical);
-  void addCornerSupportPoints (std::vector<support_pt> &p_support);
-  inline int16_t computeMatchingDisparity (const int32_t &u,const int32_t &v,uint8_t* I1_desc,uint8_t* I2_desc,const bool &right_image);
-  std::vector<support_pt> computeSupportMatches (uint8_t* I1_desc,uint8_t* I2_desc);
-
-  // triangulation & grid
-  std::vector<triangle> computeDelaunayTriangulation (std::vector<support_pt> p_support,int32_t right_image);
-  void computeDisparityPlanes (std::vector<support_pt> p_support,std::vector<triangle> &tri,int32_t right_image);
-  void createGrid (std::vector<support_pt> p_support,int32_t* disparity_grid,int32_t* grid_dims,bool right_image);
-
-  // matching
-  inline void updatePosteriorMinimum (__m128i* I2_block_addr,const int32_t &d,const int32_t &w,
-                                      const __m128i &xmm1,__m128i &xmm2,int32_t &val,int32_t &min_val,int32_t &min_d);
-  inline void updatePosteriorMinimum (__m128i* I2_block_addr,const int32_t &d,
-                                      const __m128i &xmm1,__m128i &xmm2,int32_t &val,int32_t &min_val,int32_t &min_d);
-  inline void findMatch (int32_t &u,int32_t &v,float &plane_a,float &plane_b,float &plane_c,
-                         int32_t* disparity_grid,int32_t *grid_dims,uint8_t* I1_desc,uint8_t* I2_desc,
-                         int32_t *P,int32_t &plane_radius,bool &valid,bool &right_image,float* D);
-  void computeDisparity (std::vector<support_pt> p_support,std::vector<triangle> tri,int32_t* disparity_grid,int32_t* grid_dims,
-                         uint8_t* I1_desc,uint8_t* I2_desc,bool right_image,float* D);
-
-  // L/R consistency check
-  void leftRightConsistencyCheck (float* D1,float* D2);
-  
-  // postprocessing
-  void removeSmallSegments (float* D);
-  void gapInterpolation (float* D);
-
-  // optional postprocessing
-  void adaptiveMean (float* D);
-  void median (float* D);
-  
-  // parameter set
-  parameters param;
-  
-  // memory aligned input images + dimensions
-  uint8_t *I1,*I2;
-  int32_t width,height,bpl;
-  
-  // profiling timer
-#ifdef PROFILE
-  Timer timer;
-#endif
-};
-
-#endif
diff --git a/applications/vision/include/ftl/middlebury.hpp b/applications/vision/include/ftl/middlebury.hpp
deleted file mode 100644
index 7accb7111d8aa2dc7d3c07459732474c429004cf..0000000000000000000000000000000000000000
--- a/applications/vision/include/ftl/middlebury.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _FTL_MIDDLEBURY_HPP_
-#define _FTL_MIDDLEBURY_HPP_
-
-#include <opencv2/core/mat.hpp>
-#include <string>
-#include <nlohmann/json_fwd.hpp>
-
-namespace ftl {
-namespace middlebury {
-	void test(nlohmann::json &config);
-	
-	void evaldisp(const cv::Mat &disp, const cv::Mat &gtdisp,
-			const cv::Mat &mask, float badthresh, int maxdisp, int rounddisp);
-			
-	void readFilePFM(cv::Mat &img, const std::string &filename);
-	void writeFilePFM(const cv::Mat &img, const char* filename, float scalefactor=1/255.0);
-}
-}
-
-#endif // _FTL_MIDDLEBURY_HPP_
-
diff --git a/applications/vision/include/ftl/streamer.hpp b/applications/vision/include/ftl/streamer.hpp
deleted file mode 100644
index 71010362a7a22fc804a4493d7bc8f868bf554c80..0000000000000000000000000000000000000000
--- a/applications/vision/include/ftl/streamer.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef _FTL_STREAMER_HPP_
-#define _FTL_STREAMER_HPP_
-
-#include <ftl/net/universe.hpp>
-#include <nlohmann/json.hpp>
-#include <opencv2/core/mat.hpp>
-#include <string>
-
-namespace ftl {
-
-class Streamer {
-	public:
-	Streamer(ftl::net::Universe &net, nlohmann::json &config);
-	~Streamer();
-	
-	void send(const cv::Mat &rgb, const cv::Mat &depth);
-	
-	private:
-	ftl::net::Universe &net_;
-	nlohmann::json config_;
-	std::string uri_;
-};
-
-};
-
-#endif  // _FTL_STREAMER_HPP_
-
diff --git a/applications/vision/include/ftl/synched.hpp b/applications/vision/include/ftl/synched.hpp
deleted file mode 100644
index 75aafcd451f2d15e7dc1018dd02564250b98057a..0000000000000000000000000000000000000000
--- a/applications/vision/include/ftl/synched.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _FTL_SYNCHED_HPP_
-#define _FTL_SYNCHED_HPP_
-
-#include <opencv2/opencv.hpp>
-#include <string>
-#include <vector>
-
-namespace ftl {
-
-static const int LEFT = 0;
-static const int RIGHT = 1;
-
-class SyncSource {
-	public:
-	SyncSource();
-	
-	void addChannel(const std::string &c);
-	void feed(int channel, cv::Mat &m, double ts);
-	bool get(int channel, cv::Mat &m);
-	double latency() const;
-	
-	private:
-	std::vector<cv::Mat> channels_;
-};
-};
-
-#endif // _FTL_SYNCHED_HPP_
-
diff --git a/applications/vision/src/main.cpp b/applications/vision/src/main.cpp
index 40531fa3ac4a18847e7f16699a483d34a4ea86c1..b8880e2f5750acff7eacf834ac99b988191b31b7 100644
--- a/applications/vision/src/main.cpp
+++ b/applications/vision/src/main.cpp
@@ -1,7 +1,7 @@
-/*
- * Copyright 2019 Nicolas Pope. All rights reserved.
- *
- * See LICENSE.
+/**
+ * @file main.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
  */
 
 #define LOGURU_WITH_STREAMS 1
@@ -20,7 +20,6 @@
 #include <ftl/rgbd.hpp>
 #include <ftl/data/framepool.hpp>
 #include <ftl/streams/builder.hpp>
-//#include <ftl/middlebury.hpp>
 #include <ftl/net/universe.hpp>
 #include <ftl/master.hpp>
 #include <nlohmann/json.hpp>
diff --git a/components/audio/include/ftl/audio/audio.hpp b/components/audio/include/ftl/audio/audio.hpp
index 967d1f2c1242436fd1dc7d3929d2834d99e7826f..12de54bb6f532e7b50f567cdd0176d7cddf3c4a6 100644
--- a/components/audio/include/ftl/audio/audio.hpp
+++ b/components/audio/include/ftl/audio/audio.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file audio.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_AUDIO_HPP_
 #define _FTL_AUDIO_AUDIO_HPP_
 
@@ -6,6 +12,10 @@
 namespace ftl {
 namespace audio {
 
+/**
+ * Raw storage for one or more audio frames. Used within a `Frame` channel.
+ * The data here is already decoded / uncompressed.
+ */
 class Audio {
 	public:
 	Audio() {};
@@ -22,11 +32,13 @@ class Audio {
 }
 }
 
+/* Helper for the `Frame` class */
 template <>
 inline bool ftl::data::make_type<std::list<ftl::audio::Audio>>() {
 	return false;
 }
 
+/* Prevent raw decode */
 template <>
 inline bool ftl::data::decode_type<std::list<ftl::audio::Audio>>(std::any &a, const std::vector<uint8_t> &data) {
 	return false;
diff --git a/components/audio/include/ftl/audio/buffer.hpp b/components/audio/include/ftl/audio/buffer.hpp
index e3001d63d7580732462aff6e06882c8501e1dc8f..2208660e2cef98d646cb8da10d0a2d1d09ff20b8 100644
--- a/components/audio/include/ftl/audio/buffer.hpp
+++ b/components/audio/include/ftl/audio/buffer.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file buffer.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_BUFFER_HPP_
 #define _FTL_AUDIO_BUFFER_HPP_
 
@@ -5,12 +11,15 @@
 #include <cmath>
 #include <Eigen/Eigen>
 
-//#define LOGURU_REPLACE_GLOG 1
-//#include <loguru.hpp>
-
 namespace ftl {
 namespace audio {
 
+/**
+ * Generic audio frame buffer abstract class. Classes implementing this allow
+ * asynchronous read and write of audio frames with an adjustable delay to
+ * change the amount of data being buffered. If writes cannot keep up with
+ * reads, or are bursty in nature, then more buffering is required.
+ */
 template <typename T>
 class Buffer {
 	public:
@@ -19,13 +28,25 @@ class Buffer {
 	Buffer(int channels, int framesize, int rate) : rate_(rate), cur_delay_(0.0f), req_delay_(0.0f), channels_(channels), frame_size_(framesize) {}
 	virtual ~Buffer() {}
 
+	/** Write one or more audio frames. */
 	virtual void write(const std::vector<T> &in)=0;
+
+	/** Read a given number of audio frames. */
 	virtual void read(std::vector<T> &out, int)=0;
 
+	/** Either 1 for mono, or 2 for stereo. */
 	inline int channels() const { return channels_; }
+
+	/** Number of samples per frame. */
 	inline int frameSize() const { return frame_size_; }
+
+	/** Number of samples per second. */
 	inline int sampleRate() const { return rate_; }
 
+	/**
+	 * Change the buffering delay.
+	 * @param d Seconds
+	 */
 	void setDelay(float d) {
 		req_delay_ = d  * static_cast<float>(rate_);
 		// Big jumps should be instant
@@ -35,6 +56,7 @@ class Buffer {
 		}
 	}
 
+	/** Get the current buffering delay in seconds. */
 	float delay() const { return cur_delay_ / static_cast<float>(rate_); }
 
 	inline void setGain(float g) { gain_ = g; }
@@ -75,6 +97,9 @@ class FixedBuffer : public ftl::audio::Buffer<T> {
 
 	inline int maxFrames() const { return SIZE; }
 
+	/**
+	 * Fast safe single frame write. Used by audio interrupt.
+	 */
 	inline void writeFrame(const T *d) {
 		const T *in = d;
 		T *out = data_[(write_position_++) % SIZE];
@@ -82,11 +107,11 @@ class FixedBuffer : public ftl::audio::Buffer<T> {
 		if (write_position_ > 5 && read_position_ < 0) read_position_ = 0;
 	}
 
+	/**
+	 * Fast safe single frame read. Used by audio interrupt.
+	 */
 	inline void readFrame(T *d) {
 		T* __restrict out = d;
-		//if ((size_t(out) & 0x1f) == 0) out_alignment_ = 32;
-		//else if ((size_t(out) & 0xf) == 0) out_alignment_ = 16;
-		//else if ((size_t(out) & 0x7) == 0) out_alignment_ = 8;
 
 		if (read_position_ < 0 || read_position_ >= write_position_-1) {
 			for (size_t i=0; i<CHAN*FRAME; ++i) *out++ = 0;
@@ -119,6 +144,9 @@ class FixedBuffer : public ftl::audio::Buffer<T> {
 
 	void read(std::vector<T> &out, int frames) override;
 
+	/**
+	 * Clear all buffer data.
+	 */
 	void reset() override {
 		Buffer<T>::reset();
 		write_position_ = 0; //int(this->cur_delay_);
@@ -161,17 +189,8 @@ void FixedBuffer<T,CHAN,FRAME,SIZE>::write(const std::vector<T> &in) {
 		for (int c=0; c<CHAN; ++c) *ptr++ = fracIndex<T,CHAN>(in, i, c);
 
 		const float d = 0.6f*clamp((this->req_delay_ - this->cur_delay_) / static_cast<float>(this->rate_), 0.5f);
-		i += 1.0f - d;  // FIXME: Is this correct? Seems to function but perhaps not ideal
-		//LOG(INFO) << "D " << this->req_delay_ << " - " << this->cur_delay_;
-
-		/*if (d > 0.0f) {	// Increase delay = oversample with increment < 1.0
-			//i += 1.0f * (1.0f - d);
-			i += 1.0f - d;
-		} else {		// Decrease delay = undersample with increment > 1.0
-			//i += 1.0f / (1.0f + d);
-			i += 1.0f - d;
-		}*/
-		this->cur_delay_ += d; //* static_cast<float>(this->rate_);
+		i += 1.0f - d;
+		this->cur_delay_ += d;
 
 		offset_+= CHAN;
 		if (offset_ == CHAN*FRAME) {
diff --git a/components/audio/include/ftl/audio/decoder.hpp b/components/audio/include/ftl/audio/decoder.hpp
index 30929daaf6aad886fe499dc1d1fbbba7aa42fe3b..fa601931889a092b26118ee5b6a93d9f13bf0124 100644
--- a/components/audio/include/ftl/audio/decoder.hpp
+++ b/components/audio/include/ftl/audio/decoder.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file decoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_DECODER_HPP_
 #define _FTL_AUDIO_DECODER_HPP_
 
@@ -8,13 +14,27 @@
 namespace ftl {
 namespace audio {
 
+/**
+ * Abstract audio decoder class. Specific codec implementations inherit this
+ * base class, the codec being determined from the `Packet` structure.
+ */
 class Decoder {
 	public:
 	Decoder() { };
 	virtual ~Decoder() { };
 
+	/**
+	 * Convert an encoded `Packet` to a raw decoded audio frame(s). The output
+	 * is always a multiple of a fixed frame size.
+	 * 
+	 * @param pkt Encoded packet structure.
+	 * @param out Vector to populate with decoded audio frames.
+	 */
 	virtual bool decode(const ftl::codecs::Packet &pkt, std::vector<float> &out)=0;
 
+	/**
+	 * Check if a decoder instance can decode a packet.
+	 */
 	virtual bool accepts(const ftl::codecs::Packet &)=0;
 };
 
diff --git a/components/audio/include/ftl/audio/encoder.hpp b/components/audio/include/ftl/audio/encoder.hpp
index c68c799420e1dff28650b12a086ec8b10545a6dc..8beb950c3cb72cb0d1cad35568484e3bad677a02 100644
--- a/components/audio/include/ftl/audio/encoder.hpp
+++ b/components/audio/include/ftl/audio/encoder.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file encoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_ENCODER_HPP_
 #define _FTL_AUDIO_ENCODER_HPP_
 
@@ -8,11 +14,20 @@
 namespace ftl {
 namespace audio {
 
+/**
+ * Abstract base class for an audio encoder.
+ */
 class Encoder {
 	public:
 	Encoder() {};
 	virtual ~Encoder() {};
 
+	/**
+	 * Encode one or more audio frames into a data packet.
+	 * 
+	 * @param in Audio frame data, must be a multiple of frame size.
+	 * @param pkt `Packet` to populate with codec info and encoded data.
+	 */
 	virtual bool encode(const std::vector<float> &in, ftl::codecs::Packet &pkt)=0;
 
 	virtual void reset() {}
diff --git a/components/audio/include/ftl/audio/frame.hpp b/components/audio/include/ftl/audio/frame.hpp
index 720a02d1f2d1cf47af9e36beb2c061464bb786cf..30a1c5eef5f456bcb8251ee1d417ac10270255f3 100644
--- a/components/audio/include/ftl/audio/frame.hpp
+++ b/components/audio/include/ftl/audio/frame.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file frame.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #pragma once
 #ifndef _FTL_AUDIO_FRAME_HPP_
 #define _FTL_AUDIO_FRAME_HPP_
diff --git a/components/audio/include/ftl/audio/frameset.hpp b/components/audio/include/ftl/audio/frameset.hpp
index ba18d2fe611b82802aca85aedd0bac443ecbe0da..5358c311cd8282b23b07eeca2d1ec453e6c25e38 100644
--- a/components/audio/include/ftl/audio/frameset.hpp
+++ b/components/audio/include/ftl/audio/frameset.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file frameset.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_FRAMESET_HPP_
 #define _FTL_AUDIO_FRAMESET_HPP_
 
diff --git a/components/audio/include/ftl/audio/mixer.hpp b/components/audio/include/ftl/audio/mixer.hpp
index 231b399850481a697d13cbf4a7e8c2edc8ab5378..47e639b9113579a8d280184be02d8dda457b74ba 100644
--- a/components/audio/include/ftl/audio/mixer.hpp
+++ b/components/audio/include/ftl/audio/mixer.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file mixer.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_MIXER_HPP_
 #define _FTL_AUDIO_MIXER_HPP_
 
@@ -9,8 +15,6 @@
 namespace ftl {
 namespace audio {
 
-//static constexpr int kBufferCount = 100;
-
 /**
  * A fast circular buffer to capture, play and manipulate audio data.
  * This class can be used directly with portaudio. The hardware uses
@@ -138,18 +142,6 @@ void FixedMixer<T,CHAN,FRAME,SIZE>::read(std::vector<T> &out, int count) {
 	}
 }
 
-/*template <typename T, int CHAN, int FRAME, int SIZE>
-void FixedMixer<T,CHAN,FRAME,SIZE>::resize(int t) {
-	if (track_num_ == t) return;
-	
-	track_num_ = t;
-	tracks_.reserve(t);
-	while (static_cast<int>(tracks_.size()) < t) {
-		auto &tr = tracks_.emplace_back();
-		tr.setWritePosition(write_position_);
-	}
-}*/
-
 template <typename T, int CHAN, int FRAME, int SIZE>
 int FixedMixer<T,CHAN,FRAME,SIZE>::add(const std::string &name) {
 	names_.push_back(name);
diff --git a/components/audio/include/ftl/audio/portaudio.hpp b/components/audio/include/ftl/audio/portaudio.hpp
index 64b285115f4d3cef364893a94acd1c093523d3c1..cc96e666cc22c974f042d97e561d848f66b77e0b 100644
--- a/components/audio/include/ftl/audio/portaudio.hpp
+++ b/components/audio/include/ftl/audio/portaudio.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file portaudio.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_PORTAUDIO_HPP_
 #define _FTL_AUDIO_PORTAUDIO_HPP_
 
diff --git a/components/audio/include/ftl/audio/software_decoder.hpp b/components/audio/include/ftl/audio/software_decoder.hpp
index 40d47fe45c2377f2d754dfc6d2071d717a5d612e..e22c86a85916387717e096acad249193656272c2 100644
--- a/components/audio/include/ftl/audio/software_decoder.hpp
+++ b/components/audio/include/ftl/audio/software_decoder.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file software_decoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_SOFTWARE_DECODER_HPP_
 #define _FTL_AUDIO_SOFTWARE_DECODER_HPP_
 
@@ -8,6 +14,9 @@ struct OpusMSDecoder;
 namespace ftl {
 namespace audio {
 
+/**
+ * Implement the OPUS decoder.
+ */
 class SoftwareDecoder : public ftl::audio::Decoder {
 	public:
 	SoftwareDecoder();
@@ -20,7 +29,6 @@ class SoftwareDecoder : public ftl::audio::Decoder {
 	private:
 	OpusMSDecoder *opus_decoder_;
 	bool cur_stereo_;
-	ftl::codecs::definition_t cur_definition_;
 
 	bool _decodeOpus(const ftl::codecs::Packet &pkt, std::vector<float> &out);
 	bool _decodeRaw(const ftl::codecs::Packet &pkt, std::vector<float> &out);
diff --git a/components/audio/include/ftl/audio/software_encoder.hpp b/components/audio/include/ftl/audio/software_encoder.hpp
index 35b7fb10826b429d546bffe6e57e662f9a6e1da3..306c0a7c88cce701b36f184f61f2c51013dac457 100644
--- a/components/audio/include/ftl/audio/software_encoder.hpp
+++ b/components/audio/include/ftl/audio/software_encoder.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file software_encoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_SOFTWARE_ENCODER_HPP_
 #define _FTL_AUDIO_SOFTWARE_ENCODER_HPP_
 
@@ -8,6 +14,9 @@ struct OpusMSEncoder;
 namespace ftl {
 namespace audio {
 
+/**
+ * Implement the OPUS encoder.
+ */
 class SoftwareEncoder : public ftl::audio::Encoder {
 	public:
 	SoftwareEncoder();
@@ -22,7 +31,6 @@ class SoftwareEncoder : public ftl::audio::Encoder {
 	private:
 	OpusMSEncoder *opus_encoder_;
 	bool cur_stereo_;
-	ftl::codecs::definition_t cur_definition_;
 	uint8_t cur_bitrate_;
 
 	bool _encodeRaw(const std::vector<float> &in, ftl::codecs::Packet &pkt);
diff --git a/components/audio/include/ftl/audio/source.hpp b/components/audio/include/ftl/audio/source.hpp
index 823846d2cb08d9bb4bf7b18946a2f1fe38cf66a6..4e7999de89557fd5977748f9687c12462506848d 100644
--- a/components/audio/include/ftl/audio/source.hpp
+++ b/components/audio/include/ftl/audio/source.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file source.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_SOURCE_HPP_
 #define _FTL_AUDIO_SOURCE_HPP_
 
@@ -14,13 +20,26 @@
 namespace ftl {
 namespace audio {
 
+/**
+ * Allow audio to act as a general data source for `Frame` objects. Instances
+ * of this class can be treated like any other source and will add incoming
+ * audio data (from a microphone or other input device) to a `Frame` object
+ * at specific timestamps.
+ */
 class Source : public ftl::Configurable, public ftl::data::DiscreteSource {
     public:
     explicit Source(nlohmann::json &config);
     ~Source();
 
+	/**
+	 * Accurately record a timestamp and freeze the data at this time.
+	 */
 	bool capture(int64_t ts) override;
 
+	/**
+	 * Get the already captured audio frames and insert them into the frame
+	 * object. Frames arriving after the call to `capture` are not included.
+	 */
 	bool retrieve(ftl::data::Frame &) override;
 
     private:
diff --git a/components/audio/include/ftl/audio/speaker.hpp b/components/audio/include/ftl/audio/speaker.hpp
index d03e552761f0512e2b3f982d68ef852460f9cd8b..b7ba88e1a9c9d7c6e470ec3d4f4d69098ee910df 100644
--- a/components/audio/include/ftl/audio/speaker.hpp
+++ b/components/audio/include/ftl/audio/speaker.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file speaker.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_AUDIO_SPEAKER_HPP_
 #define _FTL_AUDIO_SPEAKER_HPP_
 
@@ -13,11 +19,17 @@
 namespace ftl {
 namespace audio {
 
+/**
+ * Take data frames, extract the audio data and send to a hardware or other
+ * speaker device. Received audio frames are buffered by this class and so this
+ * class provides some control of the buffering process also.
+ */
 class Speaker : public ftl::Configurable {
 	public:
 	explicit Speaker(nlohmann::json &config);
 	~Speaker();
 
+	/** Append new audio frames to internal buffer. */
 	void queue(int64_t ts, ftl::audio::Frame &fs);
 	void queue(int64_t ts, const ftl::audio::Audio &af);
 
diff --git a/components/audio/src/frame.cpp b/components/audio/src/frame.cpp
index a73e7847c981598bd11d76ec40e9a02df4b491ff..7014f33dbec96222b2ee72c18ce9d2d02dace651 100644
--- a/components/audio/src/frame.cpp
+++ b/components/audio/src/frame.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file frame.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/audio/frame.hpp>
 #include <ftl/audio/audio.hpp>
 
diff --git a/components/audio/src/portaudio.cpp b/components/audio/src/portaudio.cpp
index 74e209386900a61c0d29d17c5965660557a33df0..5ae76273d2a9d442b68676b04a8c82e913638971 100644
--- a/components/audio/src/portaudio.cpp
+++ b/components/audio/src/portaudio.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file portaudio.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/audio/portaudio.hpp>
 #include <ftl/config.h>
 #include <ftl/threads.hpp>
diff --git a/components/audio/src/software_decoder.cpp b/components/audio/src/software_decoder.cpp
index 3a1d0bd918b3a24bd4feba3b6391f2c4b417edaa..279be20b819f001ea4f2990c900f432a7866b80b 100644
--- a/components/audio/src/software_decoder.cpp
+++ b/components/audio/src/software_decoder.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file software_decoder.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/audio/software_decoder.hpp>
 #include <ftl/config.h>
 
@@ -26,10 +32,13 @@ SoftwareDecoder::~SoftwareDecoder() {
 bool SoftwareDecoder::_createOpus(const ftl::codecs::Packet &pkt) {
 	#ifdef HAVE_OPUS
 	bool stereo = pkt.flags & ftl::codecs::kFlagStereo;
+
+	// If the current decoder matches, don't create a new one
 	if (opus_decoder_ && stereo == cur_stereo_) return true;
 
 	cur_stereo_ = stereo;
 
+	// Existing decoder is invalid so destroy it first
 	if (opus_decoder_) {
 		opus_multistream_decoder_destroy(opus_decoder_);
 		opus_decoder_ = nullptr;
@@ -63,6 +72,7 @@ bool SoftwareDecoder::_decodeOpus(const ftl::codecs::Packet &pkt, std::vector<fl
 
 	int channels = (cur_stereo_) ? 2 : 1;
 
+	// FIXME: (nick) Find another way to allow for more than 10 audio frames
 	out.resize(10*FRAME_SIZE*channels);
 
 	const unsigned char *inptr = pkt.data.data();
@@ -71,9 +81,10 @@ bool SoftwareDecoder::_decodeOpus(const ftl::codecs::Packet &pkt, std::vector<fl
 	int frames = 0;
 
 	for (size_t i=0; i<pkt.data.size(); ) {
+		// First 2 bytes indicate encoded frame size
 		const short *len = (const short*)inptr;
 		if (*len == 0) break;
-		if (frames == 10) break;
+		if (frames == 10) break; // Max frames reached
 
 		inptr += 2;
 		i += (*len)+2;
@@ -81,7 +92,6 @@ bool SoftwareDecoder::_decodeOpus(const ftl::codecs::Packet &pkt, std::vector<fl
 
 		if (samples != FRAME_SIZE) {
 			LOG(ERROR) << "Failed to Opus decode: " << samples;
-			//return false;
 			break;
 		}
 
@@ -91,8 +101,8 @@ bool SoftwareDecoder::_decodeOpus(const ftl::codecs::Packet &pkt, std::vector<fl
 		++frames;
 	}
 
+	// Shrink back down to fit actual data received.
 	out.resize(count*channels);
-	//LOG(INFO) << "Received " << frames << " Opus frames";
 	return true;
 
 	#else
@@ -110,5 +120,6 @@ bool SoftwareDecoder::_decodeRaw(const ftl::codecs::Packet &pkt, std::vector<flo
 }
 
 bool SoftwareDecoder::accepts(const ftl::codecs::Packet &) {
+	// TODO: Implement if ever needed
 	return false;
 }
diff --git a/components/audio/src/software_encoder.cpp b/components/audio/src/software_encoder.cpp
index 2b17d85469acd26a2acc77a56c2edbc6309a3cc5..2c658352c6e0a45927b23af47457c2957dd7c970 100644
--- a/components/audio/src/software_encoder.cpp
+++ b/components/audio/src/software_encoder.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file software_encoder.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/audio/software_encoder.hpp>
 #include <ftl/config.h>
 
@@ -13,7 +19,7 @@ struct OpusMSEncoder {};
 using ftl::audio::SoftwareEncoder;
 using ftl::codecs::codec_t;
 
-#define FRAME_SIZE 960
+#define FRAME_SIZE 960  // Currently fixed system wide
 #define MAX_PACKET_SIZE (3*2*FRAME_SIZE)
 
 SoftwareEncoder::SoftwareEncoder() : ftl::audio::Encoder(), opus_encoder_(nullptr), cur_stereo_(false), cur_bitrate_(0) {
@@ -44,10 +50,13 @@ bool SoftwareEncoder::encode(const std::vector<float> &in, ftl::codecs::Packet &
 bool SoftwareEncoder::_createOpus(ftl::codecs::Packet &pkt) {
 	#ifdef HAVE_OPUS
 	bool stereo = pkt.flags & ftl::codecs::kFlagStereo;
+
+	// If existing encoder matches, just use that
 	if (opus_encoder_ && stereo == cur_stereo_) return true;
 
 	cur_stereo_ = stereo;
 
+	// Existing encoder is wrong so destroy it first
 	if (opus_encoder_) {
 		opus_multistream_encoder_destroy(opus_encoder_);
 		opus_encoder_ = nullptr;
@@ -93,16 +102,13 @@ bool SoftwareEncoder::_encodeOpus(const std::vector<float> &in, ftl::codecs::Pac
 
 	unsigned char *outptr = pkt.data.data()+insize;
 
-	//LOG(INFO) << "Encode " << (in.size() / (channels*FRAME_SIZE)) << " audio frames";
-
 	for (unsigned int i=0; i<in.size(); i+=channels*FRAME_SIZE) {
 		short *len = (short*)outptr;
 		outptr += 2;
 		int nbBytes = opus_multistream_encode_float(opus_encoder_, &in.data()[i], FRAME_SIZE, outptr, MAX_PACKET_SIZE);
 		if (nbBytes <= 0) return false;
 
-		//if (nbBytes > 32000) LOG(WARNING) << "Packet exceeds size limit";
-
+		// Two bytes used to store encoded frame size in bytes
 		*len = nbBytes;
 
 		count += nbBytes+2;
@@ -111,7 +117,6 @@ bool SoftwareEncoder::_encodeOpus(const std::vector<float> &in, ftl::codecs::Pac
 	}
 
 	pkt.data.resize(insize+count);
-	//LOG(INFO) << "Opus Encode = " << pkt.data.size() << ", " << frames;
 	return true;
 
 	#else
diff --git a/components/audio/src/source.cpp b/components/audio/src/source.cpp
index e1dd8693b876d26823056bcbefc66da47d027d33..5cb01bcb20848649aa9582f014960294adfad451 100644
--- a/components/audio/src/source.cpp
+++ b/components/audio/src/source.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file source.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/audio/source.hpp>
 #include <ftl/audio/audio.hpp>
 #include <ftl/audio/portaudio.hpp>
@@ -12,9 +18,7 @@ using ftl::codecs::Channel;
 
 #ifdef HAVE_PORTAUDIO
 
-//static double ltime = 0.0;
-
-/* Portaudio callback to receive audio data. */
+/* Portaudio callback to receive audio data. Interrupt handler. */
 template <typename BUFFER>
 static int pa_source_callback(const void *input, void *output,
         unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo,
@@ -136,7 +140,6 @@ Source::Source(nlohmann::json &config) : ftl::Configurable(config), buffer_(null
 	settings_.channels = channels;
 	settings_.sample_rate = 48000;
 	settings_.frame_size = 960;
-	//state_.setLeft(settings);
 
 	LOG(INFO) << "Microphone ready.";
 
@@ -179,9 +182,6 @@ bool Source::capture(int64_t ts) {
 }
 
 bool Source::retrieve(ftl::data::Frame &frame) {
-	// Remove one interval since the audio starts from the last frame
-		//frameset_.timestamp = ts - ftl::timer::getInterval() + latency_;
-
     if (to_read_ < 1 || !buffer_) return true;
 	auto alist = frame.create<std::list<Audio>>((buffer_->channels() == 2) ? Channel::AudioStereo : Channel::AudioMono);
 	Audio aframe;
diff --git a/components/audio/src/speaker.cpp b/components/audio/src/speaker.cpp
index 61935c31519b10ce7f6605513325dbfef83ab0ef..dcf34f3244a641591fdc620fc4684c2b50512725 100644
--- a/components/audio/src/speaker.cpp
+++ b/components/audio/src/speaker.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file speaker.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/audio/speaker.hpp>
 #include <ftl/audio/audio.hpp>
 #include <ftl/audio/portaudio.hpp>
@@ -92,7 +98,6 @@ void Speaker::_open(int fsize, int sample, int channels) {
 	outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
 	outputParameters.hostApiSpecificStreamInfo = NULL;
 
-	//LOG(INFO) << "OUTPUT LATENCY: " << outputParameters.suggestedLatency;
 	latency_ = int64_t(outputParameters.suggestedLatency * 1000.0);
 
 	auto err = Pa_OpenStream(
@@ -137,11 +142,9 @@ void Speaker::queue(int64_t ts, ftl::audio::Frame &frame) {
 	}
 	if (!buffer_) return;
 
-	//LOG(INFO) << "Buffer Fullness (" << ts << "): " << buffer_->size() << " - " << audio.size();
 	for (const auto &d : audio) {
 		buffer_->write(d.data());
 	}
-	//LOG(INFO) << "Audio delay: " << buffer_.delay() << "s";
 }
 
 void Speaker::queue(int64_t ts, const ftl::audio::Audio &d) {
@@ -150,9 +153,7 @@ void Speaker::queue(int64_t ts, const ftl::audio::Audio &d) {
 	}
 	if (!buffer_) return;
 
-	//LOG(INFO) << "Buffer Fullness (" << ts << "): " << buffer_->size() << " - " << audio.size();
 	buffer_->write(d.data());
-	//LOG(INFO) << "Audio delay: " << buffer_.delay() << "s";
 }
 
 void Speaker::setDelay(int64_t ms) {
diff --git a/components/audio/test/mixer_unit.cpp b/components/audio/test/mixer_unit.cpp
index dc98685be903634d20f570b2d48f43ea7bf90f49..44d8342e68ddbb230c3db6e19a08692d3ec5a43f 100644
--- a/components/audio/test/mixer_unit.cpp
+++ b/components/audio/test/mixer_unit.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file mixer_unit.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include "catch.hpp"
 #include <ftl/audio/mixer.hpp>
 
diff --git a/components/codecs/CMakeLists.txt b/components/codecs/CMakeLists.txt
index 821a11ed93a11f2075bdd1517468a84e0a9ef9a3..4ee073ad7e4a669ec77dd5a60b854480e0c57a65 100644
--- a/components/codecs/CMakeLists.txt
+++ b/components/codecs/CMakeLists.txt
@@ -1,5 +1,4 @@
 add_library(BaseCodec OBJECT
-	src/bitrates.cpp
 	src/encoder.cpp
 	src/decoder.cpp
 	src/generate.cpp
@@ -64,7 +63,6 @@ target_include_directories(ftlcodecs PUBLIC
 	$<INSTALL_INTERFACE:include>
 	PRIVATE src)
 
-#target_include_directories(cv-node PUBLIC ${PROJECT_SOURCE_DIR}/include)
 target_link_libraries(ftlcodecs ftlcommon ${OpenCV_LIBS} ${CUDA_LIBRARIES} Eigen3::Eigen nvcuvid cuda)
 
 target_precompile_headers(ftlcodecs REUSE_FROM ftlcommon)
diff --git a/components/codecs/include/ftl/codecs/channels.hpp b/components/codecs/include/ftl/codecs/channels.hpp
index db0db3b679e96fd5993240b535ba1703e5ef6b04..9b5546c72896abb8041e9ebbd5c3dc5fb4997672 100644
--- a/components/codecs/include/ftl/codecs/channels.hpp
+++ b/components/codecs/include/ftl/codecs/channels.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file channels.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_RGBD_CHANNELS_HPP_
 #define _FTL_RGBD_CHANNELS_HPP_
 
@@ -7,7 +13,11 @@
 namespace ftl {
 namespace codecs {
 
+// TODO: (nick) Move Channel enum to data component.
+
+/** Frame channel identifier. */
 enum struct Channel : int {
+	/* Video Channels */
 	None			= -1,
 	Colour			= 0,	// 8UC3 or 8UC4
 	Left			= 0,
@@ -16,7 +26,7 @@ enum struct Channel : int {
 	Colour2			= 2,
 	Depth2			= 3,
 	Deviation		= 4,
-	Screen			= 4,
+	Screen			= 4,	// 16SC2
 	Normals			= 5,	// 16FC4
 	Weights			= 6,	// short
 	Confidence		= 7,	// 32F
@@ -38,14 +48,16 @@ enum struct Channel : int {
 	Overlay			= 21,   // 8UC4
 	GroundTruth		= 22,	// 32F
 
+	/* Audio Channels */
 	AudioMono		= 32,	// Deprecated, will always be stereo
 	AudioStereo		= 33,
 	Audio			= 33,
 
+	/* Special data channels */
 	Configuration	= 64,	// JSON Data
 	Settings1		= 65,
 	Calibration		= 65,	// Camera Parameters Object
-	Pose			= 66,	// Eigen::Matrix4d
+	Pose			= 66,	// Eigen::Matrix4d, camera transform
 	Settings2		= 67,
 	Calibration2	= 67,	// Right camera parameters
 	Index           = 68,
@@ -56,6 +68,7 @@ enum struct Channel : int {
 	CalibrationData = 73,	// Just for stereo intrinsics/extrinsics etc
 	Thumbnail		= 74,	// Small JPG thumbnail, sometimes updated
 
+	/* Custom / user data channels */
 	Data			= 2048,	// Do not use
 	EndFrame		= 2048, // Signify the last packet
 	Faces			= 2049, // Data about detected faces
@@ -70,11 +83,15 @@ inline bool isVideo(Channel c) { return (int)c < 32; };
 inline bool isAudio(Channel c) { return (int)c >= 32 && (int)c < 64; };
 inline bool isData(Channel c) { return (int)c >= 64; };
 
+/** Obtain a string name for channel. */
 std::string name(Channel c);
+
+/** Obtain OpenCV type for channel. */
 int type(Channel c);
 
+/** @deprecated */
 template <int BASE=0>
-class Channels {
+class Channels {  // TODO: Add [[deprecated]]
 	public:
 
 	class iterator {
@@ -153,6 +170,7 @@ inline Channels<BASE> Channels<BASE>::All() {
 static const Channels kNoChannels;
 static const Channels kAllChannels(0xFFFFFFFFu);
 
+/** @deprecated */
 inline bool isFloatChannel(ftl::codecs::Channel chan) {
 	switch (chan) {
 	case Channel::GroundTruth:
@@ -171,14 +189,4 @@ inline bool isFloatChannel(ftl::codecs::Channel chan) {
 
 MSGPACK_ADD_ENUM(ftl::codecs::Channel);
 
-/*template <int BASE=0>
-inline ftl::codecs::Channels<BASE> operator|(ftl::codecs::Channel a, ftl::codecs::Channel b) {
-	return ftl::codecs::Channels<BASE>(a) | b;
-}
-
-template <int BASE=0>
-inline ftl::codecs::Channels<BASE> operator+(ftl::codecs::Channel a, ftl::codecs::Channel b) {
-	return ftl::codecs::Channels<BASE>(a) | b;
-}*/
-
 #endif  // _FTL_RGBD_CHANNELS_HPP_
diff --git a/components/codecs/include/ftl/codecs/codecs.hpp b/components/codecs/include/ftl/codecs/codecs.hpp
index ddd418b27dab8ea8812b0e5dc62801bd95d65a8b..f954fe0189ad797b6132ff5c837b83a275e6e56a 100644
--- a/components/codecs/include/ftl/codecs/codecs.hpp
+++ b/components/codecs/include/ftl/codecs/codecs.hpp
@@ -1,116 +1,70 @@
-#ifndef _FTL_CODECS_BITRATES_HPP_
-#define _FTL_CODECS_BITRATES_HPP_
+/**
+ * @file codecs.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
+#ifndef _FTL_CODECS_CODECS_HPP_
+#define _FTL_CODECS_CODECS_HPP_
 
 #include <cstdint>
 #include <msgpack.hpp>
 
 namespace ftl {
+
+/**
+ * Video and data encoding / decoding components are located in this namespace. 
+ * Audio codecs are for now in `ftl::audio` namespace.
+ */
 namespace codecs {
 
-enum struct format_t {
-	BGRA8,
-	RGBA8,
-	VUYA16,
-	F32,
-	U16
-};
+// TODO: (nick) Some of these have or should be moved to encoder/decoder implementation
 
-static constexpr uint8_t kFlagFlipRGB = 0x01;		// Swap blue and red channels [deprecated]
-static constexpr uint8_t kFlagMappedDepth = 0x02;	// Use Yuv mapping for float [deprecated]
-static constexpr uint8_t kFlagFloat = 0x04;			// Floating point output
-static constexpr uint8_t kFlagPartial = 0x10;		// This frameset is not complete
-static constexpr uint8_t kFlagStereo = 0x20;		// Left-Right stereo in single channel
-static constexpr uint8_t kFlagMultiple = 0x80;		// Multiple video frames in single packet
+static constexpr uint8_t kFlagFlipRGB = 0x01;		///< Swap blue and red channels [deprecated]
+static constexpr uint8_t kFlagMappedDepth = 0x02;	///< Use Yuv mapping for float [deprecated]
+static constexpr uint8_t kFlagFloat = 0x04;			///< Floating point output
+static constexpr uint8_t kFlagPartial = 0x10;		///< This frameset is not complete
+static constexpr uint8_t kFlagStereo = 0x20;		///< Left-Right stereo in single channel
+static constexpr uint8_t kFlagMultiple = 0x80;		///< Multiple video frames in single packet
 
-static constexpr uint8_t kFlagRequest = 0x01;		// Used for empty data packets to mark a request for data
-static constexpr uint8_t kFlagCompleted = 0x02;		// Last packet for timestamp
+static constexpr uint8_t kFlagRequest = 0x01;		///< Used for empty data packets to mark a request for data
+static constexpr uint8_t kFlagCompleted = 0x02;		///< Last packet for timestamp
 static constexpr uint8_t kFlagReset = 0x04;
 
 /**
  * Compression format used.
  */
-enum struct codec_t : uint8_t {
+enum struct codec_t : uint8_t {  // TODO: Rename to Codec?
+	/* Video (image) codecs */
 	JPG = 0,
 	PNG,
 	H264,
-	HEVC,  // H265
+	HEVC,  			// H265
 	H264_LOSSLESS,
 	HEVC_LOSSLESS,
 
+	/* Audio codecs */
 	WAV=32,
 	OPUS,
 
+	/* Data "codecs" */
 	JSON = 100,		// A JSON string
 	CALIBRATION,	// Camera parameters object
 	POSE,			// 4x4 eigen matrix
 	MSGPACK,
 	STRING,			// Null terminated string
-	RAW,				// Some unknown binary format
+	RAW,			// Some unknown binary format
 
 	Invalid = 254,
 	Any = 255
 };
 
-/**
- * Resolution of encoding.
- */
-enum struct definition_t : uint8_t {
-	UHD8k = 0,
-	UHD4k = 1,
-	HD1080 = 2,
-	HD720 = 3,
-	SD576 = 4,
-	SD480 = 5,
-	LD360 = 6,
-	Any = 7,
-
-	HTC_VIVE = 8,
-	OLD_SKOOL = 9,
-	MIDDLEBURY = 10,
-	MIDDLEBURY_HD = 11,
-
-	hz48000 = 32,
-	hz44100 = 33,
-
-	Invalid
-};
-
-/**
- * Find exact match definition.
- */
-definition_t findDefinition(int width, int height);
-
-/**
- * Find a definition that matches the requested height.
- */
-definition_t findDefinition(int height);
-
-/**
- * Get width in pixels of definition.
- */
-int getWidth(definition_t);
-
-/**
- * Get height in pixels of definition.
- */
-int getHeight(definition_t);
-
-/**
- * General indication of desired quality. Exact bitrate numbers depends also
- * upon chosen definition and codec.
- */
-enum struct bitrate_t {
-	High,
-	Standard,
-	Low
-};
-
+/** Given a frame count, return a width x height tile configuration. */
 std::pair<int,int> chooseTileConfig(int size);
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
 MSGPACK_ADD_ENUM(ftl::codecs::codec_t);
-MSGPACK_ADD_ENUM(ftl::codecs::definition_t);
 
-#endif  // _FTL_CODECS_BITRATES_HPP_
+#endif  // _FTL_CODECS_CODECS_HPP_
diff --git a/components/codecs/include/ftl/codecs/decoder.hpp b/components/codecs/include/ftl/codecs/decoder.hpp
index b649f63a8e67c76a6882bd489b4e2eba9d2970ec..ec7a7495804f2448c5bf0687c85e66357480d8e6 100644
--- a/components/codecs/include/ftl/codecs/decoder.hpp
+++ b/components/codecs/include/ftl/codecs/decoder.hpp
@@ -1,7 +1,12 @@
+/**
+ * @file decoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_DECODER_HPP_
 #define _FTL_CODECS_DECODER_HPP_
 
-//#include <opencv2/opencv.hpp>
 #include <opencv2/core/cuda.hpp>
 #include <opencv2/core/cuda_stream_accessor.hpp>
 
diff --git a/components/codecs/include/ftl/codecs/depth_convert_cuda.hpp b/components/codecs/include/ftl/codecs/depth_convert_cuda.hpp
index 7fca125dbf5ec87bd9745dabbcf67801cc25ecb4..5baaf92dd3e65635683cddced1528221bb2247f2 100644
--- a/components/codecs/include/ftl/codecs/depth_convert_cuda.hpp
+++ b/components/codecs/include/ftl/codecs/depth_convert_cuda.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file depth_convert_cuda.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_DEPTH_CONVERT_HPP_
 #define _FTL_CODECS_DEPTH_CONVERT_HPP_
 
@@ -6,23 +12,101 @@
 namespace ftl {
 namespace cuda {
 
+/*
+ * See: Pece F., Kautz J., Weyrich T. 2011. Adapting standard video codecs for
+ *      depth streaming. Joint Virtual Reality Conference of EGVE 2011 -
+ *      The 17th Eurographics Symposium on Virtual Environments, EuroVR 2011 -
+ *      The 8th EuroVR (INTUITION) Conference, , pp. 59-66.
+ *
+ */
+
+/**
+ * Convert a float depth image into a Yuv colour image (4 channel). In this
+ * version, the colour data is packed together, not planar.
+ * 
+ * @param depth float 32 depth image
+ * @param rgba Storage of same size as depth image for vuY(a) data output
+ * @param maxdepth Used to normalise depth from 0 to maxdepth into 0 to 1.
+ * 
+ * @deprecated
+ */
 void depth_to_vuya(const cv::cuda::PtrStepSz<float> &depth, const cv::cuda::PtrStepSz<uchar4> &rgba, float maxdepth, cv::cuda::Stream &stream);
 
+/**
+ * Convert a float depth image into a 10bit NV12 colour image. The channels are
+ * stored as 16bit, although only the upper 10bits are used. The format is
+ * 4:2:0, so full resolution luminance but both chroma channels are packed to
+ * cover 4 pixels. Chroma therefore has same width as depth but half the height.
+ * 
+ * @param depth float 32 depth image
+ * @param luminance Luminance output.
+ * @param chroma Both chroma outputs.
+ * @param pitch Pitch in pixels of luma and chroma buffer.
+ * @param maxdepth Used to normalise depth from 0 to maxdepth into 0 to 1.
+ */
 void depth_to_nv12_10(const cv::cuda::PtrStepSz<float> &depth, ushort* luminance, ushort* chroma, int pitch, float maxdepth, cv::cuda::Stream &stream);
 
+/**
+ * Convert a Yuv (4 channel) colour image to float depth image. Non-planar.
+ * 
+ * @param depth Output buffer for float depth.
+ * @param rgba vuY(a) input (chroma first).
+ * @param maxdepth Used to undo normalisation and scale result.
+ * 
+ * @deprecated
+ */
 void vuya_to_depth(const cv::cuda::PtrStepSz<float> &depth, const cv::cuda::PtrStepSz<ushort4> &rgba, float maxdepth, cv::cuda::Stream &stream);
 
+/**
+ * Convert NV12 10bit colour image to float depth.
+ * @see depth_to_nv12_10
+ * 
+ * @param depth Output for float data.
+ * @param luminance Luminance plane input, same resolution as depth.
+ * @param chroma Both chroma channels in 4:2:0 plane.
+ * @param maxdepth Used to undo normalisation and scale result.
+ */
 void vuya_to_depth(const cv::cuda::PtrStepSz<float> &depth, const cv::cuda::PtrStepSz<ushort> &luminance, const cv::cuda::PtrStepSz<ushort> &chroma, float maxdepth, cv::cuda::Stream &stream);
 
+// TODO: (nick) Remove.
+/** @deprecated and unused? */
 void smooth_y(const cv::cuda::PtrStepSz<ushort4> &rgba, cv::cuda::Stream &stream);
 
+/**
+ * For lossless depth decode using NV12 input data (8bit). The input frame is
+ * double width where the first half is the lower 8bits of the depth data and
+ * the second half contains the upper 8bits. Therefore depth is stored 16bit
+ * and is scaled by 1000.
+ * 
+ * @param src Raw NV12 buffer data
+ * @param srcPitch Input pitch in bytes
+ * @param dst Float depth output buffer
+ * @param dstPitch Output pitch in pixels (4bpp)
+ * @param width Image width
+ * @param height Image height
+ */
 void nv12_to_float(const uint8_t* src, uint32_t srcPitch, float* dst, uint32_t dstPitch, uint32_t width, uint32_t height, cudaStream_t s);
 
+// FIXME: Is the following correct? The code seems to be 8bit?
+/**
+ * Lossless encode of depth data to NV12. The encoding is 10bit and hence the
+ * output is stored in 16bit form.
+ * 
+ * @see nv12_to_float
+ * 
+ * @param src Float depth image bufer
+ * @param srcPitch Depth pitch in pixels (4bpp)
+ * @param dst NV12 (16bit) output buffer.
+ * @param dstPitch NV12 pitch in bytes.
+ * @param width Image width.
+ * @param height Image height.
+ */
 void float_to_nv12_16bit(const float* src, uint32_t srcPitch, uchar* dst, uint32_t dstPitch, uint32_t width, uint32_t height, cudaStream_t s);
 
 }
 }
 
+// Taken from defunct NvPipe library.
 template <class COLOR32>
 void Nv12ToColor32(uint8_t *dpNv12, int nNv12Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, cudaStream_t s=0);
 
diff --git a/components/codecs/include/ftl/codecs/encoder.hpp b/components/codecs/include/ftl/codecs/encoder.hpp
index c2ed5ed9f5ba0ad7e60e6d58c06ef5924fbe4f7f..c167065d32d0ae75b495886743f37836f30fd9b4 100644
--- a/components/codecs/include/ftl/codecs/encoder.hpp
+++ b/components/codecs/include/ftl/codecs/encoder.hpp
@@ -1,8 +1,13 @@
+/**
+ * @file encoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_ENCODER_HPP_
 #define _FTL_CODECS_ENCODER_HPP_
 
 #include <ftl/cuda_util.hpp>
-//#include <opencv2/core/mat.hpp>
 #include <opencv2/core/cuda.hpp>
 
 #include <ftl/codecs/codecs.hpp>
@@ -11,10 +16,15 @@
 namespace ftl {
 namespace codecs {
 
+/// Default 10Mb encoded data buffer size.
 static const unsigned int kVideoBufferSize = 10*1024*1024;
 
 class Encoder;
 
+/**
+ * Given the resource limitations with respect to encoding, it is useful to
+ * know or choose which resource is being or to be used.
+ */
 enum class device_t {
 	Any = 0,
 	Hardware,
@@ -32,7 +42,6 @@ enum class device_t {
  * high quality encoders are available.
  */
 Encoder *allocateEncoder(
-		ftl::codecs::definition_t maxdef=ftl::codecs::definition_t::HD1080,
 		ftl::codecs::device_t dev=ftl::codecs::device_t::Any,
 		ftl::codecs::codec_t codec=ftl::codecs::codec_t::Any);
 
@@ -47,14 +56,11 @@ void free(Encoder *&e);
  */
 class Encoder {
 	public:
-	friend Encoder *allocateEncoder(ftl::codecs::definition_t,
-			ftl::codecs::device_t, ftl::codecs::codec_t);
+	friend Encoder *allocateEncoder(ftl::codecs::device_t, ftl::codecs::codec_t);
 	friend void free(Encoder *&);
 
 	public:
-	Encoder(ftl::codecs::definition_t maxdef,
-			ftl::codecs::definition_t mindef,
-			ftl::codecs::device_t dev);
+	explicit Encoder(ftl::codecs::device_t dev);
 	virtual ~Encoder();
 
 	/**
@@ -71,8 +77,15 @@ class Encoder {
 	 */
 	virtual bool encode(const cv::cuda::GpuMat &in, ftl::codecs::Packet &pkt)=0;
 
+	/**
+	 * Use to reset encoder. This will force an i-frame and should be used
+	 * if new viewers connect or the contents change.
+	 */
 	virtual void reset() {}
 
+	/**
+	 * @return true if codec is supported by this encoder.
+	 */
 	virtual bool supports(ftl::codecs::codec_t codec)=0;
 
 	inline ftl::codecs::device_t device() const { return device_; };
@@ -81,13 +94,11 @@ class Encoder {
 
 	protected:
 	bool available;
-	const ftl::codecs::definition_t max_definition;
-	const ftl::codecs::definition_t min_definition;
 	const ftl::codecs::device_t device_;
 	cv::cuda::Stream stream_;
 };
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
 #endif  // _FTL_CODECS_ENCODER_HPP_
diff --git a/components/codecs/include/ftl/codecs/faces.hpp b/components/codecs/include/ftl/codecs/faces.hpp
index 5f17e3bad6297a111eed5e0b2d4d00aa1f8cd612..b0138d820788330bd1b176e6a777dd660b60959d 100644
--- a/components/codecs/include/ftl/codecs/faces.hpp
+++ b/components/codecs/include/ftl/codecs/faces.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file faces.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_FACE_HPP_
 #define _FTL_CODECS_FACE_HPP_
 
@@ -7,10 +13,10 @@
 
 namespace ftl {
 namespace codecs {
+
+/** Face data item for Faces channel. */
 struct Face {
 	Face() {};
-	//Face(const int &id, const cv::Vec3d &rvec, const cv::Vec3d &tvec) :
-	//	id(id), rvec(rvec), tvec(tvec) {}
 
 	int id;
 	cv::Rect2d box;
@@ -19,7 +25,7 @@ struct Face {
 	MSGPACK_DEFINE_ARRAY(id, box, depth);
 };
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
-#endif
+#endif  // _FTL_CODECS_FACE_HPP_
diff --git a/components/codecs/include/ftl/codecs/h264.hpp b/components/codecs/include/ftl/codecs/h264.hpp
index c4eddd7c10c4871246ecd3de5d66c6591a2332db..2b7f7c34d1900b5057c7e087871590db03ac46ba 100644
--- a/components/codecs/include/ftl/codecs/h264.hpp
+++ b/components/codecs/include/ftl/codecs/h264.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file h264.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_H264_HPP_
 #define _FTL_CODECS_H264_HPP_
 
@@ -63,8 +69,8 @@ inline bool isIFrame(const unsigned char *data, size_t size) {
 	return getNALType(data, size) == NALType::SPS;
 }
 
-}
-}
-}
+}  // namespace h264
+}  // namespace codecs
+}  // namespace ftl
 
 #endif  // _FTL_CODECS_H264_HPP_
diff --git a/components/codecs/include/ftl/codecs/hevc.hpp b/components/codecs/include/ftl/codecs/hevc.hpp
index fa436d9904f098bb39556a27f3ea5b21a2963873..faf436bca37d5161d2ee6a4d9ed57ed72c653758 100644
--- a/components/codecs/include/ftl/codecs/hevc.hpp
+++ b/components/codecs/include/ftl/codecs/hevc.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file hevc.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_HEVC_HPP_
 #define _FTL_CODECS_HEVC_HPP_
 
@@ -109,8 +115,8 @@ inline bool isIFrame(const unsigned char *data, size_t size) {
 	return getNALType(data, size) == NALType::VPS;
 }
 
-}
-}
-}
+}  // namespace hevc
+}  // namespace codecs
+}  // namespace ftl
 
 #endif  // _FTL_CODECS_HEVC_HPP_
diff --git a/components/codecs/include/ftl/codecs/nvidia_decoder.hpp b/components/codecs/include/ftl/codecs/nvidia_decoder.hpp
index d904ba1b64218653d4751e4da453fcd3242159a7..9fbe6c59d4c84dbedf784abd758fd7e28ee01ce2 100644
--- a/components/codecs/include/ftl/codecs/nvidia_decoder.hpp
+++ b/components/codecs/include/ftl/codecs/nvidia_decoder.hpp
@@ -1,14 +1,24 @@
+/**
+ * @file nvidia_decoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_NVIDIA_DECODER_HPP_
 #define _FTL_CODECS_NVIDIA_DECODER_HPP_
 
 #include <ftl/codecs/decoder.hpp>
 #include <ftl/threads.hpp>
 
-class NvDecoder;
+class NvDecoder;  // From Nvidia Video SDK
 
 namespace ftl {
 namespace codecs {
 
+/**
+ * Use NVIDIA hardware decoder. Utilises Nvidia Video SDK 9.1.23 and supports
+ * H.264 and HEVC. In principle this supports other codecs but we don't use them.
+ */
 class NvidiaDecoder : public ftl::codecs::Decoder {
 	public:
 	NvidiaDecoder();
@@ -21,7 +31,6 @@ class NvidiaDecoder : public ftl::codecs::Decoder {
 	private:
 	NvDecoder *nv_decoder_;
 	bool is_float_channel_;
-	ftl::codecs::definition_t last_definition_;
 	ftl::codecs::codec_t last_codec_;
 	MUTEX mutex_;
 	bool seen_iframe_;
@@ -37,7 +46,7 @@ class NvidiaDecoder : public ftl::codecs::Decoder {
 	bool _checkIFrame(ftl::codecs::codec_t codec, const unsigned char *data, size_t size);
 };
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
 #endif  // _FTL_CODECS_NVIDIA_DECODER_HPP_
diff --git a/components/codecs/include/ftl/codecs/nvidia_encoder.hpp b/components/codecs/include/ftl/codecs/nvidia_encoder.hpp
index 5bff3adfdcc145d958c76ca941d76e426f3ee6b5..4e13d938f49484206327fdc14bf793a065d9d11a 100644
--- a/components/codecs/include/ftl/codecs/nvidia_encoder.hpp
+++ b/components/codecs/include/ftl/codecs/nvidia_encoder.hpp
@@ -1,17 +1,26 @@
+/**
+ * @file nvidia_encoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_NVIDIA_ENCODER_HPP_
 #define _FTL_CODECS_NVIDIA_ENCODER_HPP_
 
 #include <ftl/codecs/encoder.hpp>
 
-class NvEncoderCuda;
+class NvEncoderCuda;  // From Nvidia Video SDK
 
 namespace ftl {
 namespace codecs {
 
+/**
+ * Uses Nvidia hardware encoder. Utilises Nvidia Video SDK 9.1.23 and supports
+ * H.264 and HEVC.
+ */
 class NvidiaEncoder : public ftl::codecs::Encoder {
 	public:
-	NvidiaEncoder(ftl::codecs::definition_t maxdef,
-			ftl::codecs::definition_t mindef);
+	NvidiaEncoder();
 	~NvidiaEncoder();
 
 	bool encode(const cv::cuda::GpuMat &in, ftl::codecs::Packet &pkt) override;
@@ -46,7 +55,6 @@ class NvidiaEncoder : public ftl::codecs::Encoder {
 	int64_t frame_count_ = 0;
 
 	bool _createEncoder(const cv::cuda::GpuMat &in, const ftl::codecs::Packet &pkt);
-	ftl::codecs::definition_t _verifiedDefinition(ftl::codecs::definition_t def, const cv::cuda::GpuMat &in);
 	uint64_t _encode(uint8_t* dst, uint64_t dstSize, bool forceIFrame);
 };
 
diff --git a/components/codecs/include/ftl/codecs/opencv_decoder.hpp b/components/codecs/include/ftl/codecs/opencv_decoder.hpp
index 0f96cc7eebe9a6e21209aa814a90af0903f6957c..68e56b3c1683000d4ba18a776d31f8c74abcabcc 100644
--- a/components/codecs/include/ftl/codecs/opencv_decoder.hpp
+++ b/components/codecs/include/ftl/codecs/opencv_decoder.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file opencv_decoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_OPENCV_DECODER_HPP_
 #define _FTL_CODECS_OPENCV_DECODER_HPP_
 
@@ -6,6 +12,10 @@
 namespace ftl {
 namespace codecs {
 
+/**
+ * Use OpenCV to do image decoding. This does not support video but uses images
+ * instead, such as jpg or png, and is entirely CPU software based.
+ */
 class OpenCVDecoder : public ftl::codecs::Decoder {
 	public:
 	OpenCVDecoder();
@@ -16,10 +26,10 @@ class OpenCVDecoder : public ftl::codecs::Decoder {
 	bool accepts(const ftl::codecs::Packet &pkt);
 
 	private:
-	//cv::Mat tmp_;
+	//cv::Mat tmp_;  // TODO: Use this!?
 };
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
 #endif  // _FTL_CODECS_OPENCV_DECODER_HPP_
diff --git a/components/codecs/include/ftl/codecs/opencv_encoder.hpp b/components/codecs/include/ftl/codecs/opencv_encoder.hpp
index d500e3c5e64bb8d65f4fcd30d69d838bf8626819..9bf6cd584a3caeb2a95eccd48f60235e4feb8d8b 100644
--- a/components/codecs/include/ftl/codecs/opencv_encoder.hpp
+++ b/components/codecs/include/ftl/codecs/opencv_encoder.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file opencv_encoder.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_OPENCV_ENCODER_HPP_
 #define _FTL_CODECS_OPENCV_ENCODER_HPP_
 
@@ -16,8 +22,7 @@ namespace codecs {
  */
 class OpenCVEncoder : public ftl::codecs::Encoder {
     public:
-    OpenCVEncoder(ftl::codecs::definition_t maxdef,
-			ftl::codecs::definition_t mindef);
+    OpenCVEncoder();
     ~OpenCVEncoder();
 
 	bool encode(const cv::cuda::GpuMat &in, ftl::codecs::Packet &pkt) override;
@@ -29,7 +34,6 @@ class OpenCVEncoder : public ftl::codecs::Encoder {
 	private:
 	int chunk_count_;
 	int chunk_dim_;
-	ftl::codecs::definition_t current_definition_;
 	std::atomic<int> jobs_;
 	std::mutex job_mtx_;
 	std::condition_variable job_cv_;
@@ -38,7 +42,7 @@ class OpenCVEncoder : public ftl::codecs::Encoder {
 	bool _encodeBlock(const cv::Mat &in, ftl::codecs::Packet &pkt);
 };
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
 #endif  // _FTL_CODECS_OPENCV_ENCODER_HPP_
diff --git a/components/codecs/include/ftl/codecs/packet.hpp b/components/codecs/include/ftl/codecs/packet.hpp
index 8f2359d5be4b77cf166ab797700831d17e730588..6600fd3b2b97171655adba16f0fbb4262ca64d51 100644
--- a/components/codecs/include/ftl/codecs/packet.hpp
+++ b/components/codecs/include/ftl/codecs/packet.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file packet.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_PACKET_HPP_
 #define _FTL_CODECS_PACKET_HPP_
 
@@ -115,7 +121,7 @@ struct PacketPair {
 	const Packet &pkt;
 };
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
 #endif  // _FTL_CODECS_PACKET_HPP_
diff --git a/components/codecs/include/ftl/codecs/reader.hpp b/components/codecs/include/ftl/codecs/reader.hpp
index 498be4f76347c65ae6a9f8d3eb057c753f407956..798b3da809d8c09ac8967b3c6de5664286cfc5b5 100644
--- a/components/codecs/include/ftl/codecs/reader.hpp
+++ b/components/codecs/include/ftl/codecs/reader.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file reader.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_READER_HPP_
 #define _FTL_CODECS_READER_HPP_
 
@@ -12,6 +18,13 @@
 namespace ftl {
 namespace codecs {
 
+/**
+ * FTL file reader. Deprecated so use ftl::stream::File instead. It reads
+ * `StreamPacket` and `Packet` structures sequentially from the file.
+ * 
+ * @see ftl::stream::File
+ * @deprecated
+ */
 class Reader {
 	public:
 	explicit Reader(std::istream &);
@@ -24,8 +37,12 @@ class Reader {
 	 * otherwise (end-of-file). Timestamps are in local (clock adjusted) time
 	 * and the timestamps stored in the file are aligned to the time when open
 	 * was called.
+	 * 
+	 * @param ts Milliseconds timestamp, read all packets up to this point
+	 * @param cb Callback for each read packet.
+	 * @return true if there are more packets to read.
 	 */
-	bool read(int64_t ts, const std::function<void(const ftl::codecs::StreamPacket &, ftl::codecs::Packet &)> &);
+	bool read(int64_t ts, const std::function<void(const ftl::codecs::StreamPacket &, ftl::codecs::Packet &)> &cb);
 
 	/**
 	 * An alternative version of read where packet events are generated for
@@ -57,7 +74,7 @@ class Reader {
 	std::vector<std::function<void(const ftl::codecs::StreamPacket &, ftl::codecs::Packet &)>> handlers_;
 };
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
 #endif  // _FTL_CODECS_READER_HPP_
diff --git a/components/codecs/include/ftl/codecs/shapes.hpp b/components/codecs/include/ftl/codecs/shapes.hpp
index 2368660e526a294a468e19bcd8ebf105a4fa9263..16c40f00d86cb2c2f69d5b0fe7e8c123b5983179 100644
--- a/components/codecs/include/ftl/codecs/shapes.hpp
+++ b/components/codecs/include/ftl/codecs/shapes.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file shapes.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_SHAPES_HPP_
 #define _FTL_CODECS_SHAPES_HPP_
 
@@ -21,6 +27,10 @@ enum class Shape3DType {
 	CURSOR
 };
 
+/**
+ * Shape data item for Shapes3D channel. Used for various tracking, bounding and
+ * general 3D positional data.
+ */
 struct Shape3D {
 	int id;
 	Shape3DType type;
@@ -31,8 +41,8 @@ struct Shape3D {
 	MSGPACK_DEFINE_ARRAY(id, type, size, pose, label);
 };
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
 MSGPACK_ADD_ENUM(ftl::codecs::Shape3DType);
 
diff --git a/components/codecs/include/ftl/codecs/touch.hpp b/components/codecs/include/ftl/codecs/touch.hpp
index a48ba834ad3820e355e42362ae80c1fcc0006012..3c96b0e3d04a5a6ec34ffb337a2a310f0caef87f 100644
--- a/components/codecs/include/ftl/codecs/touch.hpp
+++ b/components/codecs/include/ftl/codecs/touch.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file touch.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_TOUCH_HPP_
 #define _FTL_CODECS_TOUCH_HPP_
 
@@ -14,6 +20,10 @@ enum class TouchType {
 	COLLISION=16
 };
 
+/**
+ * Data item for touch channel. Represents screen touch or 3D collision data.
+ * Currently experimental and incomplete.
+ */
 struct Touch {
 	Touch() {};
 
@@ -27,8 +37,8 @@ struct Touch {
 	MSGPACK_DEFINE(id, type, strength, x, y, d);
 };
 
-}
-}
+}  // namespace codecs
+}  // namespace ftl
 
 MSGPACK_ADD_ENUM(ftl::codecs::TouchType);
 
diff --git a/components/codecs/include/ftl/codecs/transformation.hpp b/components/codecs/include/ftl/codecs/transformation.hpp
index dfc8ef09957cb5ee03fb49660b32abb18693c1de..537dca016499d41ac766af5a79b89d51b36645ef 100644
--- a/components/codecs/include/ftl/codecs/transformation.hpp
+++ b/components/codecs/include/ftl/codecs/transformation.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file transformation.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #pragma once
 #ifndef _FTL_TRANSFORMATION_HPP_
 #define _FTL_TRANSFORMATION_HPP_
diff --git a/components/codecs/include/ftl/codecs/writer.hpp b/components/codecs/include/ftl/codecs/writer.hpp
index e2b30c8ae5b48ee02a8c55e0ed31334e335b473f..c7ada6881bd33b6fd64a7f5bc17d909bcefb4f5d 100644
--- a/components/codecs/include/ftl/codecs/writer.hpp
+++ b/components/codecs/include/ftl/codecs/writer.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file writer.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CODECS_WRITER_HPP_
 #define _FTL_CODECS_WRITER_HPP_
 
@@ -11,6 +17,12 @@
 namespace ftl {
 namespace codecs {
 
+/**
+ * Generate FTL file from packet data.
+ * 
+ * @see ftl::stream::File
+ * @deprecated
+ */
 class Writer {
 	public:
 	explicit Writer(std::ostream &);
diff --git a/components/codecs/src/bitrates.cpp b/components/codecs/src/bitrates.cpp
deleted file mode 100644
index 654fb865d5549c91543adfda761bdde703dacf7a..0000000000000000000000000000000000000000
--- a/components/codecs/src/bitrates.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-
-#include <ftl/codecs/codecs.hpp>
-#include <cmath>
-
-using ftl::codecs::definition_t;
-using ftl::codecs::codec_t;
-
-
-static const float kAspectRatio = 1.777778f;
-
-struct Resolution {
-	int width;
-	int height;
-};
-
-static const Resolution resolutions[] = {
-	7680, 4320,		// UHD8k
-	3840, 2160,		// UHD4k
-	1920, 1080,		// HD1080
-	1280, 720,		// HD720
-	1024, 576,		// SD576
-	854, 480,		// SD480
-	640, 360,		// LD360
-	0, 0,			// ANY
-	1852, 2056,		// HTC_VIVE
-	640, 480,		// Old school 4:3
-	3000, 1920,		// Middlebury
-	1687, 1080,		// Middlebury smaller
-	0, 0
-};
-
-int ftl::codecs::getWidth(definition_t d) {
-	return resolutions[static_cast<int>(d)].width;
-}
-
-int ftl::codecs::getHeight(definition_t d) {
-	return resolutions[static_cast<int>(d)].height;
-}
-
-definition_t ftl::codecs::findDefinition(int width, int height) {
-	int best = 0;
-
-	for(const Resolution res : resolutions) {
-		if ((res.width == width) && (res.height == height)) {
-			return static_cast<definition_t>(best);
-		}
-		best++;
-	}
-
-	return definition_t::Invalid;
-}
-
-definition_t ftl::codecs::findDefinition(int height) {
-	int best = 0;
-
-	for(const Resolution res : resolutions) {
-		if (res.height == height) {
-			return static_cast<definition_t>(best);
-		}
-		best++;
-	}
-
-	return definition_t::Invalid;
-}
-
diff --git a/components/codecs/src/channels.cpp b/components/codecs/src/channels.cpp
index 458541d5f1b2ffe94166faf828efa9f827e2c983..bb0308b74b63edf455f699845ba4a901c86087dc 100644
--- a/components/codecs/src/channels.cpp
+++ b/components/codecs/src/channels.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file channels.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/codecs/channels.hpp>
 #include <unordered_map>
 #include <opencv2/opencv.hpp>
@@ -9,6 +15,7 @@ struct ChannelInfo {
 	int type;
 };
 
+/* Name and type lookup table for channels */
 static const std::unordered_map<Channel,ChannelInfo> info = {
     {Channel::Colour, {"Left", CV_8UC4}},
 	{Channel::Depth, {"Depth", CV_32F}},
diff --git a/components/codecs/src/decoder.cpp b/components/codecs/src/decoder.cpp
index dcaf17a78f6bb07eea871eb876ccb2e7ff96ed32..2161a447b30182a43714c50d7df05ad22bdfdf35 100644
--- a/components/codecs/src/decoder.cpp
+++ b/components/codecs/src/decoder.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file decoder.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/codecs/decoder.hpp>
 
 #include <ftl/codecs/opencv_decoder.hpp>
@@ -8,6 +14,7 @@ using ftl::codecs::codec_t;
 using std::string;
 using std::to_string;
 
+/* Debug utility function to print stream packets */
 ftl::codecs::StreamPacket::operator std::string() const {
 	return string("[\n  timestamp=") + to_string(timestamp) + string(",\n  frameset=") +
 		to_string(streamID) + string(",\n  frame=") + to_string(frame_number) +
@@ -15,6 +22,7 @@ ftl::codecs::StreamPacket::operator std::string() const {
 }
 
 Decoder *ftl::codecs::allocateDecoder(const ftl::codecs::Packet &pkt) {
+	// TODO: (nick) Add other decoder libraries and codecs.
 	switch(pkt.codec) {
 	case codec_t::JPG		:
 	case codec_t::PNG		: return new ftl::codecs::OpenCVDecoder;
@@ -26,9 +34,6 @@ Decoder *ftl::codecs::allocateDecoder(const ftl::codecs::Packet &pkt) {
 	}
 }
 
-/**
- * Release a decoder to be reused by some other stream.
- */
 void ftl::codecs::free(Decoder *&e) {
 	delete e;
 	e = nullptr;
diff --git a/components/codecs/src/depth_convert.cu b/components/codecs/src/depth_convert.cu
index b71913b7ba0c38f7e10d03d05ba072d3686d5df7..d4b95a098dc6611d7d2eb994ec7da5b6a409f3e8 100644
--- a/components/codecs/src/depth_convert.cu
+++ b/components/codecs/src/depth_convert.cu
@@ -1,9 +1,13 @@
+/**
+ * @file depth_convert.cu
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/codecs/depth_convert_cuda.hpp>
 #include "../Utils/ColorSpace.h"
 #include <opencv2/core/cuda_stream_accessor.hpp>
 
-#define T_PER_BLOCK 8
-
 // Encoding
 
 __device__ inline float clamp(float v) {
@@ -22,10 +26,12 @@ __device__ inline float clampC(float v, float t=255.0f) {
  *
  */
 
-  // Assumes 8 bit output channels and 14bit depth
+  // Assumes 8 (256) bit output channels and 14bit (16384) depth
   static constexpr float P = (2.0f * 256.0f) / 16384.0f;
 
+  /* Convert single float to L Ha Hb. */
  __device__ inline float3 depth2yuv(float depth, float maxdepth) {
+	 // Normalise
 	float d = max(0.0f,depth);
 	if (d >= maxdepth) d = 0.0f;
 	float L = d / maxdepth;
@@ -51,20 +57,23 @@ __global__ void depth_to_vuya_kernel(cv::cuda::PtrStepSz<float> depth, cv::cuda:
 }
 
 void ftl::cuda::depth_to_vuya(const cv::cuda::PtrStepSz<float> &depth, const cv::cuda::PtrStepSz<uchar4> &rgba, float maxdepth, cv::cuda::Stream &stream) {
-	const dim3 gridSize((depth.cols + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth.rows + T_PER_BLOCK - 1)/T_PER_BLOCK);
-    const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
+	static constexpr int THREADS_X = 8;
+	static constexpr int THREADS_Y = 8;
+
+	const dim3 gridSize((depth.cols + THREADS_X - 1)/THREADS_X, (depth.rows + THREADS_Y - 1)/THREADS_Y);
+    const dim3 blockSize(THREADS_X, THREADS_Y);
 
 	depth_to_vuya_kernel<<<gridSize, blockSize, 0, cv::cuda::StreamAccessor::getStream(stream)>>>(depth, rgba, maxdepth);
 	cudaSafeCall( cudaGetLastError() );
 }
 
-// Planar 10bit version
-
+/* Planar 10bit version */
 __global__ void depth_to_nv12_10_kernel(cv::cuda::PtrStepSz<float> depth, ushort* luminance, ushort* chroma, int pitch, float maxdepth) {
 	const unsigned int x = (blockIdx.x*blockDim.x + threadIdx.x) * 2;
 	const unsigned int y = (blockIdx.y*blockDim.y + threadIdx.y) * 2;
 
 	if (x < depth.cols && y < depth.rows) {
+		// Process all 4 pixels at same time, due to 4:2:0 format
 		float3 yuv1 = depth2yuv(depth(y,x), maxdepth);
 		float3 yuv2 = depth2yuv(depth(y,x+1), maxdepth);
 		float3 yuv3 = depth2yuv(depth(y+1,x), maxdepth);
@@ -75,6 +84,7 @@ __global__ void depth_to_nv12_10_kernel(cv::cuda::PtrStepSz<float> depth, ushort
 		float Ha = (yuv1.y+yuv2.y+yuv3.y+yuv4.y) / 4.0f * 255.0f;
 		float Hb = (yuv1.z+yuv2.z+yuv3.z+yuv4.z) / 4.0f * 255.0f;
 		
+		// Use upper 8 bits only for luma
 		luminance[y*pitch+x] = ushort(yuv1.x*255.0f) << 8;
 		luminance[y*pitch+x+1] = ushort(yuv2.x*255.0f) << 8;
 		luminance[(y+1)*pitch+x] = ushort(yuv3.x*255.0f) << 8;
@@ -86,8 +96,11 @@ __global__ void depth_to_nv12_10_kernel(cv::cuda::PtrStepSz<float> depth, ushort
 }
 
 void ftl::cuda::depth_to_nv12_10(const cv::cuda::PtrStepSz<float> &depth, ushort* luminance, ushort* chroma, int pitch, float maxdepth, cv::cuda::Stream &stream) {
-	const dim3 gridSize((depth.cols/2 + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth.rows/2 + T_PER_BLOCK - 1)/T_PER_BLOCK);
-    const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
+	static constexpr int THREADS_X = 8;  // TODO: (nick) tune
+	static constexpr int THREADS_Y = 8;
+
+	const dim3 gridSize((depth.cols/2 + THREADS_X - 1)/THREADS_X, (depth.rows/2 + THREADS_Y - 1)/THREADS_Y);
+    const dim3 blockSize(THREADS_X, THREADS_Y);
 
 	depth_to_nv12_10_kernel<<<gridSize, blockSize, 0, cv::cuda::StreamAccessor::getStream(stream)>>>(depth, luminance, chroma, pitch, maxdepth);
 	cudaSafeCall( cudaGetLastError() );
@@ -113,6 +126,7 @@ void ftl::cuda::depth_to_nv12_10(const cv::cuda::PtrStepSz<float> &depth, ushort
 
  __device__ inline uchar round8(uchar v) { return v; }
 
+ /* Convert single L Ha Hb to float depth */
  __device__ inline float yuv2depth(float L, float Ha, float Hb) {
 	const float p = P;
         
@@ -125,7 +139,7 @@ void ftl::cuda::depth_to_nv12_10(const cv::cuda::PtrStepSz<float> &depth, ushort
 	if (m == 2) s = (p/2.0f)*(1.0f - Ha);
 	if (m == 3) s = (p/2.0f)*(1.0f - Hb);
 
-	return (L0+s);
+	return (L0+s);  // Not denormalised!
  }
 
  // Video is assumed to be 10bit encoded, returning ushort instead of uchar.
@@ -146,21 +160,26 @@ __global__ void vuya_to_depth_kernel(cv::cuda::PtrStepSz<float> depth, cv::cuda:
 }
 
 void ftl::cuda::vuya_to_depth(const cv::cuda::PtrStepSz<float> &depth, const cv::cuda::PtrStepSz<ushort4> &rgba, float maxdepth, cv::cuda::Stream &stream) {
-	const dim3 gridSize((depth.cols + T_PER_BLOCK - 1)/T_PER_BLOCK, (depth.rows + T_PER_BLOCK - 1)/T_PER_BLOCK);
-    const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
+	static constexpr int THREADS_X = 8;
+	static constexpr int THREADS_Y = 8;
+
+	const dim3 gridSize((depth.cols + THREADS_X - 1)/THREADS_X, (depth.rows + THREADS_Y - 1)/THREADS_Y);
+    const dim3 blockSize(THREADS_X, THREADS_Y);
 
 	vuya_to_depth_kernel<<<gridSize, blockSize, 0, cv::cuda::StreamAccessor::getStream(stream)>>>(depth, rgba, maxdepth);
 	cudaSafeCall( cudaGetLastError() );
 }
 
-// ==== Planar version =========================================================
+// ==== Planar 4:2:0 version ===================================================
 
+// Typed pair to combine memory read
 template <typename T>
 struct T2 {
 	T x;
 	T y;
 };
 
+/* Read both chroma values together. */
 template <typename T>
 __device__ inline ushort2 readChroma(const T* __restrict__ chroma, int pitch, uint x, uint y) {
 	T2<T> c = *(T2<T>*)(&chroma[(y/2)*pitch+x]);
@@ -174,6 +193,14 @@ __device__ inline float2 norm_float(const ushort2 &v) {
 	return make_float2(float(v.x)/255.0f, float(v.y)/255.0f);
 }
 
+/*
+ * Interpolate the chroma, but only if the luminance is the same. This smooths
+ * the decoded output but without crossing discontinuities. If luma values are
+ * themselves inconsistent then the data is marked invalid as it has been
+ * corrupted by the compression.
+ *
+ * Unused, has been rewritten into kernel directly.
+ */
 template <typename T>
 __device__ inline float2 bilinChroma(const T* __restrict__ chroma, const T* __restrict__ luminance, int pitch, uchar L, uint x, uint y, const ushort2 &D, int dx, int dy, int width, int height, bool consistent) {
 	if (uint(x+dx) >= width || uint(y+dy) >= height) return {float(D.x)/255.0f, float(D.y)/255.0f};
@@ -196,6 +223,7 @@ __device__ inline float2 bilinChroma(const T* __restrict__ chroma, const T* __re
 		w += 0.1875f;
 	}
 
+	// TODO: (nick) Find way to correct data rather than discard it.
 	if (consistent) {
 		R.x += 0.5625f * (float(D.x) / 255.0f);
 		R.y += 0.5625f * (float(D.y) / 255.0f);
@@ -266,6 +294,10 @@ __device__ inline float2 bilinChroma(const T* __restrict__ chroma, const T* __re
 	float w;
 	bool consistent = consistent_s[threadIdx.y+1][threadIdx.x+1];
 
+	// Do a bilinear interpolation of chroma, combined with a luma consistency
+	// check to not smooth over boundaries, and to remove inconsistent values
+	// that can be assumed to have been corrupted by the compression.
+
 	w = 0.0f; H2 = {0.0f,0.0f};
 	if (consistent_s[threadIdx.y+1-1][threadIdx.x+1-1] && L.x == lum_s[threadIdx.y+1-1][threadIdx.x+1-1].w) { H2 += 0.0625f * norm_float(chroma_s[threadIdx.y+1-1][threadIdx.x+1-1]); w += 0.0625f; }
 	if (consistent_s[threadIdx.y+1-1][threadIdx.x+1] && L.x == lum_s[threadIdx.y+1-1][threadIdx.x+1].z) { H2 += 0.1875f * norm_float(chroma_s[threadIdx.y+1-1][threadIdx.x+1]); w += 0.1875f; }
@@ -313,106 +345,16 @@ void ftl::cuda::vuya_to_depth(const cv::cuda::PtrStepSz<float> &depth, const cv:
 	cudaSafeCall( cudaGetLastError() );
 }
 
-// ==== Decode filters =========================================================
-
- // Video is assumed to be 10bit encoded, returning ushort instead of uchar.
- template <int RADIUS>
- __global__ void discon_y_kernel(cv::cuda::PtrStepSz<ushort4> vuya) {
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if (x >= RADIUS && x < vuya.cols-RADIUS && y >= RADIUS && y < vuya.rows-RADIUS) {
-        ushort4 in = vuya(y,x);
-        ushort inY = round8(in.z);
-        bool isdiscon = false;
-
-        #pragma unroll
-        for (int v=-1; v<=1; ++v) {
-            #pragma unroll
-            for (int u=-1; u<=1; ++u) {
-                ushort inn = round8(vuya(y+v,x+u).z);
-                isdiscon |= (abs(int(inY)-int(inn)) > 1);
-            }
-        }
-
-		if (isdiscon) vuya(y,x).w = 1;
-		/*if (isdiscon) {
-			#pragma unroll
-			for (int v=-RADIUS; v<=RADIUS; ++v) {
-				#pragma unroll
-				for (int u=-RADIUS; u<=RADIUS; ++u) {
-					vuya(y+v,x+u).w = 1;
-				}
-			}
-		}*/
-	}
-}
-
- // Video is assumed to be 10bit encoded, returning ushort instead of uchar.
- template <int RADIUS>
- __global__ void smooth_y_kernel(cv::cuda::PtrStepSz<ushort4> vuya) {
-	const int x = blockIdx.x*blockDim.x + threadIdx.x;
-	const int y = blockIdx.y*blockDim.y + threadIdx.y;
-
-	if (x >= RADIUS && y >= RADIUS && x < vuya.cols-RADIUS-1 && y < vuya.rows-RADIUS-1) {
-        ushort4 in = vuya(y,x);
-		ushort best = in.z;
-		float mcost = 1.e10f;
-
-		// 1) In small radius, is there a discontinuity?
-		
-		if (in.w == 1) {
-			//vuya(y,x).z = 30000;
-			//return;
-
-			#pragma unroll
-			for (int v=-RADIUS; v<=RADIUS; ++v) {
-				#pragma unroll
-				for (int u=-RADIUS; u<=RADIUS; ++u) {
-					ushort4 inn = vuya(y+v,x+u);
-					if (inn.w == 0) {
-						float err = fabsf(float(in.z) - float(inn.z));
-						float cost = err*err; //err*err*dist;
-						if (mcost > cost) {
-							mcost = cost;
-							best = inn.z;
-						}
-						//minerr = min(minerr, err);
-						//if (err == minerr) best = inn.z;
-						//miny = min(miny, inn.z);
-						//sumY += float(in.z);
-						//weights += 1.0f;
-					}
-				}
-			}
-
-			//printf("Min error: %d\n",minerr);
-		
-			vuya(y,x).z = best; //ushort(sumY / weights);
-		}
-        
-		// 2) If yes, use minimum Y value
-		// This acts only to remove discon values... instead a correction is needed
-		// Weight based on distance from discon and difference from current value
-		//     - points further from discon are more reliable
-		//     - most similar Y is likely to be correct depth.
-		//     - either use Y with strongest weight or do weighted average.
-        //if (isdiscon) in.z = maxy;
-        //if (isdiscon) vuya(y,x) = in;
-	}
-}
 
 void ftl::cuda::smooth_y(const cv::cuda::PtrStepSz<ushort4> &rgba, cv::cuda::Stream &stream) {
-	const dim3 gridSize((rgba.cols + T_PER_BLOCK - 1)/T_PER_BLOCK, (rgba.rows + T_PER_BLOCK - 1)/T_PER_BLOCK);
-    const dim3 blockSize(T_PER_BLOCK, T_PER_BLOCK);
-
-    discon_y_kernel<1><<<gridSize, blockSize, 0, cv::cuda::StreamAccessor::getStream(stream)>>>(rgba);
-	smooth_y_kernel<6><<<gridSize, blockSize, 0, cv::cuda::StreamAccessor::getStream(stream)>>>(rgba);
-	cudaSafeCall( cudaGetLastError() );
+	// REMOVED!!
 }
 
 // ==== Colour conversions =====================================================
 
+// Some of the following comes from the defunct NvPipe library. It has been
+// modified by us.
+
 __constant__ float matYuv2Rgb[3][3];
 __constant__ float matRgb2Yuv[3][3];
 
@@ -451,23 +393,6 @@ static void SetMatYuv2Rgb(int iMatrix) {
     cudaMemcpyToSymbol(matYuv2Rgb, mat, sizeof(mat));
 }
 
-/*static void SetMatRgb2Yuv(int iMatrix) {
-    float wr, wb;
-    int black, white, max;
-    GetConstants(iMatrix, wr, wb, black, white, max);
-    float mat[3][3] = {
-        wr, 1.0f - wb - wr, wb,
-        -0.5f * wr / (1.0f - wb), -0.5f * (1 - wb - wr) / (1.0f - wb), 0.5f,
-        0.5f, -0.5f * (1.0f - wb - wr) / (1.0f - wr), -0.5f * wb / (1.0f - wr),
-    };
-    for (int i = 0; i < 3; i++) {
-        for (int j = 0; j < 3; j++) {
-            mat[i][j] = (float)(1.0 * (white - black) / max * mat[i][j]);
-        }
-    }
-    cudaMemcpyToSymbol(matRgb2Yuv, mat, sizeof(mat));
-}*/
-
 template<class T>
 __device__ static T Clamp(T x, T lower, T upper) {
     return x < lower ? lower : (x > upper ? upper : x);
diff --git a/components/codecs/src/encoder.cpp b/components/codecs/src/encoder.cpp
index 3d8f8aac189ae5425c7f9a992454d0e5781fe034..374ec4c64dcf16502d016539cb178462e96c19ba 100644
--- a/components/codecs/src/encoder.cpp
+++ b/components/codecs/src/encoder.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file encoder.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/codecs/encoder.hpp>
 #include <ftl/threads.hpp>
 
@@ -7,7 +13,6 @@
 #include <loguru.hpp>
 
 using ftl::codecs::Encoder;
-using ftl::codecs::definition_t;
 using ftl::codecs::device_t;
 using ftl::codecs::codec_t;
 
@@ -29,8 +34,7 @@ using namespace ftl::codecs::internal;
 
 static MUTEX mutex;
 
-Encoder *ftl::codecs::allocateEncoder(ftl::codecs::definition_t maxdef,
-		ftl::codecs::device_t dev, ftl::codecs::codec_t codec) {
+Encoder *ftl::codecs::allocateEncoder(ftl::codecs::device_t dev, ftl::codecs::codec_t codec) {
 	UNIQUE_LOCK(mutex, lk);
 	if (!has_been_init) init_encoders();
 
@@ -38,7 +42,6 @@ Encoder *ftl::codecs::allocateEncoder(ftl::codecs::definition_t maxdef,
 		auto *e = *i;
 		if (!e->available) continue;
 		if (dev != device_t::Any && dev != e->device_) continue;
-		if (maxdef != definition_t::Any && (maxdef < e->max_definition || maxdef > e->min_definition)) continue;
 		if (codec != codec_t::Any && !e->supports(codec)) continue;
 		
 		e->available = false;
@@ -56,8 +59,8 @@ void ftl::codecs::free(Encoder *&enc) {
 	enc = nullptr;
 }
 
-Encoder::Encoder(definition_t maxdef, definition_t mindef, device_t dev) :
-		available(true), max_definition(maxdef), min_definition(mindef), device_(dev) {
+Encoder::Encoder(device_t dev) :
+		available(true), device_(dev) {
 
 }
 
diff --git a/components/codecs/src/generate.cpp b/components/codecs/src/generate.cpp
index f6a021fbc0fc893a1d19916dee657a2952939d7e..b7f4ac1cb8ae210b76025ee0a59b386c72c68d69 100644
--- a/components/codecs/src/generate.cpp
+++ b/components/codecs/src/generate.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file generate.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/codecs/encoder.hpp>
 #include <ftl/codecs/opencv_encoder.hpp>
 #include <ftl/configurable.hpp>
@@ -19,19 +25,21 @@ void fin_encoders() {
     for (auto *s : encoders) delete s;
 }
 
+/* Encoders are a limited resource so precreate a limited number of them. */
 void init_encoders() {
-    encoders.push_back(new ftl::codecs::NvidiaEncoder(definition_t::UHD4k, definition_t::HD720));
-    encoders.push_back(new ftl::codecs::NvidiaEncoder(definition_t::UHD4k, definition_t::HD720));
-
-    encoders.push_back(new ftl::codecs::OpenCVEncoder(definition_t::HD1080, definition_t::HD720));
-    encoders.push_back(new ftl::codecs::OpenCVEncoder(definition_t::HD1080, definition_t::HD720));
-	encoders.push_back(new ftl::codecs::OpenCVEncoder(definition_t::HD1080, definition_t::HD720));
-	encoders.push_back(new ftl::codecs::OpenCVEncoder(definition_t::HD1080, definition_t::HD720));
-	encoders.push_back(new ftl::codecs::OpenCVEncoder(definition_t::HD1080, definition_t::HD720));
-    encoders.push_back(new ftl::codecs::OpenCVEncoder(definition_t::SD576, definition_t::LD360));
-    encoders.push_back(new ftl::codecs::OpenCVEncoder(definition_t::SD576, definition_t::LD360));
-	encoders.push_back(new ftl::codecs::OpenCVEncoder(definition_t::SD576, definition_t::LD360));
-    encoders.push_back(new ftl::codecs::OpenCVEncoder(definition_t::SD576, definition_t::LD360));
+	// Nvidia GeForce drivers are limited to 2
+    encoders.push_back(new ftl::codecs::NvidiaEncoder);
+    encoders.push_back(new ftl::codecs::NvidiaEncoder);
+
+    encoders.push_back(new ftl::codecs::OpenCVEncoder);
+    encoders.push_back(new ftl::codecs::OpenCVEncoder);
+	encoders.push_back(new ftl::codecs::OpenCVEncoder);
+	encoders.push_back(new ftl::codecs::OpenCVEncoder);
+	encoders.push_back(new ftl::codecs::OpenCVEncoder);
+    encoders.push_back(new ftl::codecs::OpenCVEncoder);
+    encoders.push_back(new ftl::codecs::OpenCVEncoder);
+	encoders.push_back(new ftl::codecs::OpenCVEncoder);
+    encoders.push_back(new ftl::codecs::OpenCVEncoder);
 
     has_been_init = true;
 
diff --git a/components/codecs/src/nvidia_decoder.cpp b/components/codecs/src/nvidia_decoder.cpp
index 063bc384998e1fb10a28db3dc589cc6b859de073..401ecb4026add2b8d16125d4a5a912cce7ddf4d0 100644
--- a/components/codecs/src/nvidia_decoder.cpp
+++ b/components/codecs/src/nvidia_decoder.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file nvidia_decoder.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/codecs/nvidia_decoder.hpp>
 #include <ftl/codecs/nvidia_encoder.hpp>
 #include <ftl/exception.hpp>
@@ -124,16 +130,6 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
 	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) {
-		LOG(ERROR) << "Invalid buffer for float frame";
-		return false;
-	}
-
-	if (!is_float_frame && out.type() != CV_8UC4) {
-		LOG(ERROR) << "Invalid buffer for lossy colour frame: " << out.type();
-		return false;
-	}*/
-
 	_create(pkt);
 
 	is_float_channel_ = is_float_frame;
@@ -151,8 +147,6 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
 		const unsigned char *ptr = pkt.data.data();
 		const unsigned char *eptr = ptr+pkt.data.size();
 
-		//LOG(WARNING) << "Decode of multiple frames";
-
 		while (ptr < eptr) {
 			int size = readValue<int>(&ptr);
 
@@ -178,11 +172,6 @@ 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_) {
-		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;
 	if (is_float_frame && !islossless) surface = cv::cuda::GpuMat(height_+height_/2, width_, CV_16U, decodedPtr, width_*2);
@@ -218,8 +207,6 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
 		}
 	}
 
-	//stream_.waitForCompletion();
-
 	return true;
 }
 
diff --git a/components/codecs/src/nvidia_encoder.cpp b/components/codecs/src/nvidia_encoder.cpp
index 65b9ec32013b58fe9267aaf00151e6f3e0dc5082..148f8b90a611acfca10fb8e6aba998aa7e94513b 100644
--- a/components/codecs/src/nvidia_encoder.cpp
+++ b/components/codecs/src/nvidia_encoder.cpp
@@ -1,3 +1,11 @@
+/**
+ * @file nvidia_encoder.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
+// Some of this file is inspired by or taken from the defunct NvPipe library
+
 #include <ftl/codecs/nvidia_encoder.hpp>
 #include <loguru.hpp>
 #include <ftl/timer.hpp>
@@ -14,10 +22,7 @@
 #include "NvEncoder/NvEncoderCuda.h"
 
 using ftl::codecs::NvidiaEncoder;
-using ftl::codecs::bitrate_t;
 using ftl::codecs::codec_t;
-using ftl::codecs::definition_t;
-using ftl::codecs::format_t;
 using ftl::codecs::Packet;
 using ftl::codecs::kFlagFloat;
 using ftl::codecs::kFlagFlipRGB;
@@ -60,8 +65,7 @@ static inline std::string EncErrorCodeToString(NVENCSTATUS code)
     return "Unknown error code";
 }
 
-NvidiaEncoder::NvidiaEncoder(definition_t maxdef,
-			definition_t mindef) : Encoder(maxdef, mindef, ftl::codecs::device_t::NVIDIA) {
+NvidiaEncoder::NvidiaEncoder() : Encoder(ftl::codecs::device_t::NVIDIA) {
 	nvenc_ = nullptr;
 	was_reset_ = false;
 }
diff --git a/components/codecs/src/opencv_decoder.cpp b/components/codecs/src/opencv_decoder.cpp
index 9133d394478cc8f9f709020833b0f6d74bf1f539..1f5ae2e008257ade65b33f959fa4743ec3dc701f 100644
--- a/components/codecs/src/opencv_decoder.cpp
+++ b/components/codecs/src/opencv_decoder.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file opencv_decoder.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/codecs/opencv_decoder.hpp>
 
 #include <opencv2/opencv.hpp>
@@ -20,17 +26,9 @@ bool OpenCVDecoder::accepts(const ftl::codecs::Packet &pkt) {
 }
 
 bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out) { 
-	/*int chunk_dim = 1; //std::sqrt(pkt.frame_count);
-	int chunk_width = out.cols / chunk_dim;
-	int chunk_height = out.rows / chunk_dim;
-
-	// Build chunk head
-	int cx = 0; //(pkt.block_number % chunk_dim) * chunk_width;
-	int cy = 0; //(pkt.block_number / chunk_dim) * chunk_height;
-	cv::Rect roi(cx,cy,chunk_width,chunk_height);
-	cv::cuda::GpuMat chunkHead = out(roi);*/
-
+	// TODO: (nick) Move to member variables
 	cv::Mat tmp2_, tmp_;
+
 	// Decode in temporary buffers to prevent long locks
 	cv::imdecode(pkt.data, cv::IMREAD_UNCHANGED, &tmp2_);
 
@@ -46,40 +44,19 @@ bool OpenCVDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
 		}
 	}
 
-	// Apply colour correction to chunk
-	//ftl::rgbd::colourCorrection(tmp_rgb, gamma_, temperature_);
-
-	// TODO:(Nick) Decode directly into double buffer if no scaling
-	// Can either check JPG/PNG headers or just use pkt definition.
-
-	// Original size so just copy
-	//if (tmp_.cols == chunkHead.cols) {
-		if (!tmp_.empty() && tmp_.type() == CV_16U) {
-			tmp_.convertTo(tmp_, CV_32FC1, 1.0f/1000.0f);
-			out.upload(tmp_);
-		} else if (!tmp_.empty() && tmp_.type() == CV_8UC4) {
-			//tmp_.copyTo(chunkHead);
-			out.upload(tmp_);
-		} else if (!tmp_.empty() && tmp_.type() == CV_16U) {
-			out.upload(tmp_);
-		} else if (!tmp_.empty() && tmp_.type() == CV_8UC1) {
-			out.upload(tmp_);
-		} else {
-			// Silent ignore?
-		}
-	// Downsized so needs a scale up
-	/*} else {
-		if (!tmp_.empty() && tmp_.type() == CV_16U && chunkHead.type() == CV_32F) {
-			tmp_.convertTo(tmp_, CV_32FC1, 1.0f/1000.0f); //(16.0f*10.0f));
-			cv::resize(tmp_, tmp_, chunkHead.size(), 0, 0, cv::INTER_NEAREST);
-			chunkHead.upload(tmp_);
-		} else if (!tmp_.empty() && tmp_.type() == CV_8UC4 && chunkHead.type() == CV_8UC4) {
-			cv::resize(tmp_, tmp_, chunkHead.size());
-			chunkHead.upload(tmp_);
-		} else {
-			// Silent ignore?
-		}
-	}*/
+	if (!tmp_.empty() && tmp_.type() == CV_16U) {
+		tmp_.convertTo(tmp_, CV_32FC1, 1.0f/1000.0f);
+		out.upload(tmp_);
+	} else if (!tmp_.empty() && tmp_.type() == CV_8UC4) {
+		out.upload(tmp_);
+	} else if (!tmp_.empty() && tmp_.type() == CV_16U) {
+		out.upload(tmp_);
+	} else if (!tmp_.empty() && tmp_.type() == CV_8UC1) {
+		out.upload(tmp_);
+	} else {
+		// Silent ignore?
+	}
+	
 
 	return true;
 }
diff --git a/components/codecs/src/opencv_encoder.cpp b/components/codecs/src/opencv_encoder.cpp
index aa41b2b4a11598a294106594a707298e416e64a4..7e1b3d7ec39a509a6a5ebbbb3fec41f1d9fdad90 100644
--- a/components/codecs/src/opencv_encoder.cpp
+++ b/components/codecs/src/opencv_encoder.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file opencv_encoder.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/codecs/opencv_encoder.hpp>
 
 #include <opencv2/opencv.hpp>
@@ -5,13 +11,11 @@
 #include <loguru.hpp>
 #include <vector>
 
-using ftl::codecs::definition_t;
 using ftl::codecs::codec_t;
 using ftl::codecs::OpenCVEncoder;
 using std::vector;
 
-OpenCVEncoder::OpenCVEncoder(ftl::codecs::definition_t maxdef,
-			ftl::codecs::definition_t mindef) : Encoder(maxdef, mindef, ftl::codecs::device_t::OpenCV) {
+OpenCVEncoder::OpenCVEncoder() : Encoder(ftl::codecs::device_t::OpenCV) {
 	jobs_ = 0;
 }
 
@@ -44,45 +48,16 @@ bool OpenCVEncoder::encode(const cv::cuda::GpuMat &in, ftl::codecs::Packet &pkt)
 		tmp_.convertTo(tmp_, CV_16U, 1000.0f);
 	}
 
-	//for (int i=0; i<chunk_count_; ++i) {
-		// Add chunk job to thread pool
-		//ftl::pool.push([this,i,cb,is_colour,bitrate](int id) {
-			//ftl::codecs::Packet pkt;
-			//pkt.bitrate = 0;
-			//pkt.frame_count = 1;
-			//pkt.definition = current_definition_;
-			//pkt.codec = (is_colour) ? codec_t::JPG : codec_t::PNG;
-
-			try {
-				_encodeBlock(tmp_, pkt);
-			} catch(...) {
-				LOG(ERROR) << "OpenCV encode block exception: ";
-			}
-
-			//std::unique_lock<std::mutex> lk(job_mtx_);
-			//--jobs_;
-			//if (jobs_ == 0) job_cv_.notify_one();
-		//});
-	//}
-
-	//std::unique_lock<std::mutex> lk(job_mtx_);
-	//job_cv_.wait_for(lk, std::chrono::seconds(20), [this]{ return jobs_ == 0; });
-	//if (jobs_ != 0) {
-	//	LOG(FATAL) << "Deadlock detected (" << jobs_ << ")";
-	//}
+	try {
+		_encodeBlock(tmp_, pkt);
+	} catch(...) {
+		LOG(ERROR) << "OpenCV encode block exception: ";
+	}
 
 	return true;
 }
 
 bool OpenCVEncoder::_encodeBlock(const cv::Mat &in, ftl::codecs::Packet &pkt) {
-	//int chunk_width = in.cols / 1;
-	//int chunk_height = in.rows / 1;
-
-	// Build chunk heads
-	//int cx = 0; //(pkt.block_number % chunk_dim_) * chunk_width;
-	//int cy = 0; //(pkt.block_number / chunk_dim_) * chunk_height;
-	//cv::Rect roi(cx,cy,chunk_width,chunk_height);
-
 	cv::Mat chunkHead = in;
 
 	if (pkt.codec == codec_t::PNG) {
diff --git a/components/codecs/src/reader.cpp b/components/codecs/src/reader.cpp
index 26d4f58f4a82f5a160d0050e40581996d8dc97d4..d93817c4c24a91f6e7a0fd5ca12b0abeee3c8d07 100644
--- a/components/codecs/src/reader.cpp
+++ b/components/codecs/src/reader.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file reader.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <loguru.hpp>
 #include <ftl/codecs/reader.hpp>
 #include <ftl/timer.hpp>
@@ -18,10 +24,12 @@ Reader::~Reader() {
 }
 
 bool Reader::begin() {
+	// Verify header code
 	ftl::codecs::Header h;
 	(*stream_).read((char*)&h, sizeof(h));
 	if (h.magic[0] != 'F' || h.magic[1] != 'T' || h.magic[2] != 'L' || h.magic[3] != 'F') return false;
 
+	// Header is larger from version 2 onwards...
 	if (h.version >= 2) {
 		ftl::codecs::IndexHeader ih;
 		(*stream_).read((char*)&ih, sizeof(ih));
@@ -37,22 +45,6 @@ bool Reader::begin() {
 	return true;
 }
 
-/*static void printMsgpack(msgpack::object &obj) {
-	switch (obj.type) {
-	case msgpack::type::NIL: return;
-	case msgpack::type::BOOLEAN: LOG(INFO) << "BOOL " << obj.as<bool>(); return;
-	case msgpack::type::POSITIVE_INTEGER:
-	case msgpack::type::NEGATIVE_INTEGER: LOG(INFO) << "INT " << obj.as<int>(); return;
-	case msgpack::type::FLOAT32: LOG(INFO) << "FLOAT " << obj.as<float>(); return;
-	case msgpack::type::FLOAT64: LOG(INFO) << "DOUBLE " << obj.as<double>(); return;
-	case msgpack::type::STR: LOG(INFO) << "STRING " << obj.as<std::string>(); return;
-	case msgpack::type::BIN: return;
-	case msgpack::type::EXT: return;
-	case msgpack::type::ARRAY: LOG(INFO) << "ARRAY: "; return;
-	case msgpack::type::MAP: LOG(INFO) << "MAP: "; return;
-	}
-}*/
-
 bool Reader::read(int64_t ts, const std::function<void(const ftl::codecs::StreamPacket &, ftl::codecs::Packet &)> &f) {
 	#ifdef DEBUG_MUTEX
 	UNIQUE_LOCK(mtx_, lk);
@@ -95,8 +87,6 @@ bool Reader::read(int64_t ts, const std::function<void(const ftl::codecs::Stream
 		//std::tuple<StreamPacket,Packet> data;
 		msgpack::object obj = msg.get();
 
-		//printMsgpack(obj);
-
 		try {
 			obj.convert(data_.emplace_back());
 		} catch (std::exception &e) {
diff --git a/components/codecs/src/writer.cpp b/components/codecs/src/writer.cpp
index dba5853ac985fe71028db6152d4c74028e2d91b6..dea920788a039c831fcf9a59b66fef83b7d32e4f 100644
--- a/components/codecs/src/writer.cpp
+++ b/components/codecs/src/writer.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file writer.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/codecs/writer.hpp>
 #include <ftl/timer.hpp>
 #include <loguru.hpp>
@@ -14,7 +20,6 @@ Writer::~Writer() {
 
 bool Writer::begin() {
 	ftl::codecs::Header h;
-	//h.version = 2;
 	(*stream_).write((const char*)&h, sizeof(h));
 
 	ftl::codecs::IndexHeader ih;
diff --git a/components/codecs/test/CMakeLists.txt b/components/codecs/test/CMakeLists.txt
index 34753db970a0acab275621de7aa4ceca6020b59c..757ec0e2e6a465a8b13e76f318c772aec671fc68 100644
--- a/components/codecs/test/CMakeLists.txt
+++ b/components/codecs/test/CMakeLists.txt
@@ -1,7 +1,6 @@
 ### OpenCV Codec Unit ################################################################
 add_executable(opencv_codec_unit
 $<TARGET_OBJECTS:CatchTest>
-	../src/bitrates.cpp
 	../src/encoder.cpp
 	../src/opencv_encoder.cpp
 	../src/opencv_decoder.cpp
@@ -18,10 +17,7 @@ add_test(OpenCVCodecUnitTest opencv_codec_unit)
 ### Nvidia Codec Unit ################################################################
 add_executable(nvidia_codec_unit
 $<TARGET_OBJECTS:CatchTest>
-	../src/bitrates.cpp
 	../src/encoder.cpp
-	#../src/nvpipe_encoder.cpp
-	#../src/nvpipe_decoder.cpp
 	$<TARGET_OBJECTS:NvidiaCodec>
 	../src/depth_convert.cu
 	./nvidia_codec_unit.cpp
@@ -44,6 +40,9 @@ set_property(TARGET nvidia_codec_unit PROPERTY CUDA_ARCHITECTURES OFF)
 
 add_test(NvidiaCodecUnitTest nvidia_codec_unit)
 
+
+# REMOVED as these are deprecated
+
 ### Reader Writer Unit ################################################################
 #add_executable(rw_unit
 #	./tests.cpp
diff --git a/components/codecs/test/nvidia_codec_unit.cpp b/components/codecs/test/nvidia_codec_unit.cpp
index 937106bb3891736e0c7c37eba7c1c8da7e3489ae..86f5d5ced00a4923158808e0aa6f6c2ac9663042 100644
--- a/components/codecs/test/nvidia_codec_unit.cpp
+++ b/components/codecs/test/nvidia_codec_unit.cpp
@@ -6,9 +6,7 @@
 
 #include <opencv2/cudaarithm.hpp>
 
-using ftl::codecs::definition_t;
 using ftl::codecs::codec_t;
-using ftl::codecs::format_t;
 
 ctpl::thread_pool ftl::pool(4);
 
@@ -26,7 +24,7 @@ namespace ftl {
 
 
 TEST_CASE( "NvidiaEncoder::encode() - A valid colour image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	cv::cuda::GpuMat m(cv::Size(1920,1080), CV_8UC4, cv::Scalar(0,0,0,0));
 
 	ftl::codecs::Packet pkt;
@@ -87,7 +85,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A valid colour image" ) {
 }
 
 TEST_CASE( "NvidiaEncoder::encode() - A tiled colour image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	cv::cuda::GpuMat m(cv::Size(2560,720), CV_8UC4, cv::Scalar(0,0,0,0));
 
 	SECTION("auto codec and definition, 2x1 frames") {
@@ -108,7 +106,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A tiled colour image" ) {
 }
 
 TEST_CASE( "NvidiaEncoder::encode() - A valid lossless float image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	cv::cuda::GpuMat m(cv::Size(1280,720), CV_32F, cv::Scalar(0.0f));
 
 	SECTION("auto codec and definition, single frame") {
@@ -143,7 +141,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A valid lossless float image" ) {
 }
 
 TEST_CASE( "NvidiaEncoder::encode() - A valid lossy float image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	cv::cuda::GpuMat m(cv::Size(1280,720), CV_32F, cv::Scalar(0.0f));
 
 	SECTION("auto codec and definition, single frame") {
@@ -164,7 +162,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A valid lossy float image" ) {
 }
 
 TEST_CASE( "NvidiaEncoder::encode() - A tiled lossy float image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	cv::cuda::GpuMat m(cv::Size(2560,720), CV_32F, cv::Scalar(0));
 
 	SECTION("auto codec and definition, 2x1 frame") {
@@ -185,7 +183,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A tiled lossy float image" ) {
 }
 
 TEST_CASE( "NvidiaEncoder::encode() - A large tiled lossy float image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	cv::cuda::GpuMat m(cv::Size(5120,1440), CV_32F, cv::Scalar(0));
 
 	SECTION("auto codec and definition, 4x2 frame") {
@@ -206,7 +204,7 @@ TEST_CASE( "NvidiaEncoder::encode() - A large tiled lossy float image" ) {
 }
 
 TEST_CASE( "NvidiaDecoder::decode() - A colour test image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	ftl::codecs::NvidiaDecoder decoder;
 
 	cv::cuda::GpuMat in;
@@ -233,7 +231,7 @@ TEST_CASE( "NvidiaDecoder::decode() - A colour test image" ) {
 }
 
 TEST_CASE( "NvidiaDecoder::decode() - A tiled colour image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	ftl::codecs::NvidiaDecoder decoder;
 
 	cv::cuda::GpuMat in;
@@ -260,7 +258,7 @@ TEST_CASE( "NvidiaDecoder::decode() - A tiled colour image" ) {
 }
 
 TEST_CASE( "NvidiaDecoder::decode() - A lossless depth image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	ftl::codecs::NvidiaDecoder decoder;
 
 	cv::cuda::GpuMat in;
@@ -285,7 +283,7 @@ TEST_CASE( "NvidiaDecoder::decode() - A lossless depth image" ) {
 }
 
 TEST_CASE( "NvidiaDecoder::decode() - A lossy depth image" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	ftl::codecs::NvidiaDecoder decoder;
 
 	cv::cuda::GpuMat in;
@@ -310,7 +308,7 @@ TEST_CASE( "NvidiaDecoder::decode() - A lossy depth image" ) {
 }
 
 TEST_CASE( "NvidiaDecoder::decode() - corrupted packet" ) {
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 	ftl::codecs::NvidiaDecoder decoder;
 
 	cv::cuda::GpuMat in;
diff --git a/components/codecs/test/opencv_codec_unit.cpp b/components/codecs/test/opencv_codec_unit.cpp
index 43c94304fafe06166c016de06e1002c78b6f4574..aa44fedef7926526aca8a4a12cacb19359343bf1 100644
--- a/components/codecs/test/opencv_codec_unit.cpp
+++ b/components/codecs/test/opencv_codec_unit.cpp
@@ -5,8 +5,6 @@
 
 #include <opencv2/cudaarithm.hpp>
 
-using ftl::codecs::format_t;
-using ftl::codecs::definition_t;
 using ftl::codecs::codec_t;
 
 ctpl::thread_pool ftl::pool(4);
@@ -83,7 +81,7 @@ TEST_CASE( "OpenCVEncoder::encode() - A depth test image at preset 0" ) {
 }
 */
 TEST_CASE( "OpenCVDecoder::decode() - A colour test image no resolution change" ) {
-	ftl::codecs::OpenCVEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::OpenCVEncoder encoder;
 	ftl::codecs::OpenCVDecoder decoder;
 	cv::cuda::GpuMat in(cv::Size(1024,576), CV_8UC4, cv::Scalar(255,0,0,0));
 	cv::cuda::GpuMat out(cv::Size(1024,576), CV_8UC4, cv::Scalar(0,0,0,0));
diff --git a/components/common/cpp/include/ftl/config.h.in b/components/common/cpp/include/ftl/config.h.in
index 99db4ca42536f6ebdfd4415ccb0d0e6a7c135344..85098389791a9454150e6f05afc8dcb00a4c2008 100644
--- a/components/common/cpp/include/ftl/config.h.in
+++ b/components/common/cpp/include/ftl/config.h.in
@@ -1,3 +1,11 @@
+/**
+ * @file config.h
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * 
+ * To be CMake processed
+ */
+
 #ifndef __FTL_CONFIG_H__
 #define __FTL_CONFIG_H__
 
diff --git a/components/common/cpp/include/ftl/configurable.hpp b/components/common/cpp/include/ftl/configurable.hpp
index 3d2a115e670e977fc45e4b8fdb32ff055789dd6c..39c9e4868263fe6f190bdb0aab31fa7b1ac6061c 100644
--- a/components/common/cpp/include/ftl/configurable.hpp
+++ b/components/common/cpp/include/ftl/configurable.hpp
@@ -1,9 +1,13 @@
+/**
+ * @file configurable.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #pragma once
 #ifndef _FTL_CONFIGURABLE_HPP_
 #define _FTL_CONFIGURABLE_HPP_
 
-//#define LOGURU_REPLACE_GLOG 1
-//#include <loguru.hpp>
 #include <ftl/exception.hpp>
 #include <nlohmann/json_fwd.hpp>
 #include <string>
@@ -16,7 +20,7 @@
 
 #define REQUIRED(...) required(__func__, __VA_ARGS__)
 
-// TODO: Find a better place for this
+// TODO: Find a better place for this or use std version
 #define UNUSED(A) (void)(A)
 
 namespace ftl {
@@ -24,6 +28,7 @@ namespace ftl {
 class Configurable;
 
 namespace config {
+/** unused */
 struct Event {
 	Configurable *entity;
 	std::string name;
@@ -162,17 +167,12 @@ class Configurable {
 	void _trigger(const std::string &name);
 };
 
-/*template <>
-void Configurable::set<const std::string&>(const std::string &name, const std::string &value) {
-	config_[name] = value;
-	if (name == "uri") __changeURI(value, this);
-	_trigger(name);
-}*/
-
 }
 
 #include <ftl/configuration.hpp>
 
+/* Optimised compile by externally compiling these specific templates. */
+
 extern template float ftl::Configurable::value<float>(const std::string &name, const float &def);
 extern template bool ftl::Configurable::value<bool>(const std::string &name, const bool &def);
 extern template int ftl::Configurable::value<int>(const std::string &name, const int &def);
diff --git a/components/common/cpp/include/ftl/configuration.hpp b/components/common/cpp/include/ftl/configuration.hpp
index 821eb3386db355f8eb8d3df6ac43916f8427c0c4..bbdba40d68d48b1602566c89f8c059dc7062c5a7 100644
--- a/components/common/cpp/include/ftl/configuration.hpp
+++ b/components/common/cpp/include/ftl/configuration.hpp
@@ -1,11 +1,14 @@
+/**
+ * @file configuration.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #pragma once
 #ifndef _FTL_COMMON_CONFIGURATION_HPP_
 #define _FTL_COMMON_CONFIGURATION_HPP_
 
-//#define LOGURU_REPLACE_GLOG 1
-//#include <loguru.hpp>
 #include <nlohmann/json_fwd.hpp>
-//#include <ftl/configurable.hpp>
 #include <string>
 #include <vector>
 #include <optional>
@@ -13,9 +16,9 @@
 
 namespace ftl {
 
-extern bool running;
-extern int exit_code;
-extern std::string branch_name;
+extern bool running;				///< Set to false to bring the system down
+extern int exit_code;				///< Specify exit code to eventually use
+extern std::string branch_name;		///< Print out desired git branch name to use at restart
 
 class Configurable;
 
@@ -38,6 +41,11 @@ std::optional<std::string> locateFile(const std::string &name);
 
 std::map<std::string, std::string> read_options(char ***argv, int *argc);
 
+/**
+ * Called first to set up the entire system.
+ * 
+ * @param root The initial key in the config file to use as root config.
+ */
 Configurable *configure(int argc, char **argv, const std::string &root, const std::unordered_set<std::string> &restoreable={});
 
 Configurable *configure(json_t &);
@@ -166,6 +174,8 @@ using config::configure;
 
 #include <ftl/configurable.hpp>
 
+// ==== Impl ===================================================================
+
 extern template std::optional<float> ftl::config::getJSON<float>(nlohmann::json *config, const std::string &name);
 extern template std::optional<int> ftl::config::getJSON<int>(nlohmann::json *config, const std::string &name);
 extern template std::optional<std::string> ftl::config::getJSON<std::string>(nlohmann::json *config, const std::string &name);
diff --git a/components/common/cpp/include/ftl/cuda_buffer.hpp b/components/common/cpp/include/ftl/cuda_buffer.hpp
index 45abe03c733d222deec030873753dfa7c6b7c900..59f69d481ac1f869583af588f0a31c99250f5a15 100644
--- a/components/common/cpp/include/ftl/cuda_buffer.hpp
+++ b/components/common/cpp/include/ftl/cuda_buffer.hpp
@@ -1,3 +1,11 @@
+/**
+ * @file cuda_buffer.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * 
+ * UNUSED currently
+ */
+
 #ifndef _FTL_CUDA_BUFFER_HPP_
 #define _FTL_CUDA_BUFFER_HPP_
 
diff --git a/components/common/cpp/include/ftl/cuda_common.hpp b/components/common/cpp/include/ftl/cuda_common.hpp
index 10f03281b4cecd689435b00866423fe8dd6839d1..d94ef141bd6d0bcfd39f9fae881271f7368866d0 100644
--- a/components/common/cpp/include/ftl/cuda_common.hpp
+++ b/components/common/cpp/include/ftl/cuda_common.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file cuda_common.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CUDA_COMMON_HPP_
 #define _FTL_CUDA_COMMON_HPP_
 
diff --git a/components/common/cpp/include/ftl/cuda_half.hpp b/components/common/cpp/include/ftl/cuda_half.hpp
index d35be793be30023d59f9c38014e9e6e97a1db718..296f6e0b031240baf7fbde61ee6dd92b8ca35859 100644
--- a/components/common/cpp/include/ftl/cuda_half.hpp
+++ b/components/common/cpp/include/ftl/cuda_half.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file cuda_half.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CUDA_HALF_HPP_
 #define _FTL_CUDA_HALF_HPP_
 
diff --git a/components/common/cpp/include/ftl/cuda_operators.hpp b/components/common/cpp/include/ftl/cuda_operators.hpp
index 304818b58a55610f17ec44dc4e2f714a151b8267..d4d52e1ed0de92209d00560dec301298b02abbe9 100644
--- a/components/common/cpp/include/ftl/cuda_operators.hpp
+++ b/components/common/cpp/include/ftl/cuda_operators.hpp
@@ -9,6 +9,8 @@
  * 
  */
 
+// TODO: Nick, check that license above ^^^^
+
 /*
     This file implements common mathematical operations on vector types
     (float3, float4 etc.) since these are not provided as standard by CUDA.
diff --git a/components/common/cpp/include/ftl/cuda_texture.hpp b/components/common/cpp/include/ftl/cuda_texture.hpp
index 6f29a80bf1b9cb8409026c0da2cc812b5b41fc15..76e5a5bf396f16282edbb16663b3438f473d314e 100644
--- a/components/common/cpp/include/ftl/cuda_texture.hpp
+++ b/components/common/cpp/include/ftl/cuda_texture.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file cuda_texture.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_CUDA_TEXTURE_HPP_
 #define _FTL_CUDA_TEXTURE_HPP_
 
diff --git a/components/common/cpp/include/ftl/cuda_util.hpp b/components/common/cpp/include/ftl/cuda_util.hpp
index e55c1430c1c013780e4b5d9fc0381492da281e49..a96d127191c18a966680e6ca1d50ae400a642903 100644
--- a/components/common/cpp/include/ftl/cuda_util.hpp
+++ b/components/common/cpp/include/ftl/cuda_util.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file cuda_util.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #pragma once
 
 #ifndef _CUDA_UTIL_
diff --git a/components/common/cpp/include/ftl/exception.hpp b/components/common/cpp/include/ftl/exception.hpp
index e78fe3854c2ebdd97073ceb85fb531673b568f45..a5d2768f12888d765cac99555523ec52da06ddfd 100644
--- a/components/common/cpp/include/ftl/exception.hpp
+++ b/components/common/cpp/include/ftl/exception.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file exception.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_EXCEPTION_HPP_
 #define _FTL_EXCEPTION_HPP_
 
@@ -32,6 +38,9 @@ private:
 	Formatter & operator = (Formatter &);
 };
 
+/**
+ * Main FTL internal exception class. Use via Macro below.
+ */
 class exception : public std::exception
 {
 	public:
diff --git a/components/common/cpp/include/ftl/file.hpp b/components/common/cpp/include/ftl/file.hpp
index 765607974d520d270e67acf0b9d7a15f33c8fda1..6b6064724d7540e812d3988ee98a196574eeabdc 100644
--- a/components/common/cpp/include/ftl/file.hpp
+++ b/components/common/cpp/include/ftl/file.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file file.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #ifndef _FTL_FILES_HPP_
 #define _FTL_FILES_HPP_
 
diff --git a/components/common/cpp/include/ftl/handle.hpp b/components/common/cpp/include/ftl/handle.hpp
index 1e7ca32cf2564f58c872127697a23959f68fd0c7..29f8a834bb05fba16db8434113c871eea9a6728f 100644
--- a/components/common/cpp/include/ftl/handle.hpp
+++ b/components/common/cpp/include/ftl/handle.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file handle.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_HANDLE_HPP_
 #define _FTL_HANDLE_HPP_
 
diff --git a/components/common/cpp/include/ftl/profiler.hpp b/components/common/cpp/include/ftl/profiler.hpp
index f33ff0e5b90225db24ed29af25fcf271df3ab59a..3e4344294f838f61fbf62c01f9c4e921be9194f9 100644
--- a/components/common/cpp/include/ftl/profiler.hpp
+++ b/components/common/cpp/include/ftl/profiler.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file profiler.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_PROFILER_HPP_
 #define _FTL_PROFILER_HPP_
 
@@ -6,6 +12,7 @@
 
 namespace ftl {
 
+/** RAII Profile object for easy internal timing of statement blocks. */
 class Profiler {
 	public:
 	Profiler(const std::string &id, const std::string &label, double limit);
diff --git a/components/common/cpp/include/ftl/threads.hpp b/components/common/cpp/include/ftl/threads.hpp
index c40ed095b5075afe0b4df7409c48ace45b8328cc..2e736d25c173a730dac53d466acfafdbd1e6cc9d 100644
--- a/components/common/cpp/include/ftl/threads.hpp
+++ b/components/common/cpp/include/ftl/threads.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file threads.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_THREADS_HPP_
 #define _FTL_THREADS_HPP_
 
diff --git a/components/common/cpp/include/ftl/timer.hpp b/components/common/cpp/include/ftl/timer.hpp
index 1dd3ff76fb93d22975b663134ea42285c85be449..d4b29d4ffa6b1411bbc163dae246761482984d88 100644
--- a/components/common/cpp/include/ftl/timer.hpp
+++ b/components/common/cpp/include/ftl/timer.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file timer.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_COMMON_TIMER_HPP_
 #define _FTL_COMMON_TIMER_HPP_
 
diff --git a/components/common/cpp/include/ftl/traits.hpp b/components/common/cpp/include/ftl/traits.hpp
index df44e36c7e3d4eeb2ebb31bf740841affab7b180..c2ed3a91f22d437aff9dfa00f984fc582238b6ff 100644
--- a/components/common/cpp/include/ftl/traits.hpp
+++ b/components/common/cpp/include/ftl/traits.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file traits.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_TRAITS_HPP_
 #define _FTL_TRAITS_HPP_
 
@@ -8,6 +14,8 @@
 namespace ftl {
 namespace traits {
 
+// TODO: Use OpenCV provided traits?
+
 template <typename T>
 struct AlwaysFalse : std::false_type {};
 
diff --git a/components/common/cpp/include/ftl/transactional.hpp b/components/common/cpp/include/ftl/transactional.hpp
index 54659b1d35706f150e19e14eb0e5d5e4b1b54296..5b7f8026b66c5ce7cf3b630b9be0f0931d85b0e1 100644
--- a/components/common/cpp/include/ftl/transactional.hpp
+++ b/components/common/cpp/include/ftl/transactional.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file transactional.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_TRANSACTIONAL_HPP_
 #define _FTL_TRANSACTIONAL_HPP_
 
@@ -9,6 +15,8 @@ namespace ftl {
  * Use RAII style transactional objects with shared locking. This wraps an
  * object with a lock and provides a release notification mechanism to allow
  * completion code.
+ * 
+ * Used by ftl::stream::Receiver and Builder.
  */
 template <typename T>
 class Transactional {
diff --git a/components/common/cpp/include/ftl/uri.hpp b/components/common/cpp/include/ftl/uri.hpp
index 455d4f84594fb7630613f24a98cadda63a259735..7bf635c0263a0ad5b331bc5b7d4880eef2ab56d0 100644
--- a/components/common/cpp/include/ftl/uri.hpp
+++ b/components/common/cpp/include/ftl/uri.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file uri.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_URI_HPP_
 #define _FTL_URI_HPP_
 
diff --git a/components/common/cpp/include/ftl/utility/image_debug.hpp b/components/common/cpp/include/ftl/utility/image_debug.hpp
index 5547e6f01fe0c2d152faa45e65a65ed68492b5fe..ed7d6c3e8039b6af4a4c98f915c7c98965c57248 100644
--- a/components/common/cpp/include/ftl/utility/image_debug.hpp
+++ b/components/common/cpp/include/ftl/utility/image_debug.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file image_debug.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_UTILITY_IMAGE_DEBUG_HPP_
 #define _FTL_UTILITY_IMAGE_DEBUG_HPP_
 
@@ -11,6 +17,14 @@ enum class ImageVisualisation {
 	HEAT_MAPPED
 };
 
+/**
+ * Display a GpuMat in a window with a particular colorisation.
+ * 
+ * @param m GPU Mat input
+ * @param name OpenCV window name.
+ * @param scale Image resolution scale, 1 = full resolution
+ * @param iv How to colour convert the image
+ */
 void show_image(
 	const cv::cuda::GpuMat &m,
 	const std::string &name,
diff --git a/components/common/cpp/include/ftl/utility/intrinsics.hpp b/components/common/cpp/include/ftl/utility/intrinsics.hpp
index 304156b7952f605a7a0e1f8408e31687aeb2475f..e1bab7d3de37d20b653af66d7a17a3f4ff3e0b01 100644
--- a/components/common/cpp/include/ftl/utility/intrinsics.hpp
+++ b/components/common/cpp/include/ftl/utility/intrinsics.hpp
@@ -1,8 +1,15 @@
+/**
+ * @file intrinsics.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_UTILITY_INTRINSICS_HPP_
 #define _FTL_UTILITY_INTRINSICS_HPP_
 
 namespace ftl {
 
+/** Count number of set bits in 64bit unsigned int. */
 inline unsigned int popcount(uint64_t bits) {
 	#if defined(_MSC_VER)
 		return __popcnt64(bits);
@@ -18,6 +25,7 @@ inline unsigned int popcount(uint64_t bits) {
 	#endif
 }
 
+/** Count number o set bits in 32bit unsigned int */
 inline unsigned int popcount(uint32_t bits) {
 	#if defined(_MSC_VER)
 		return __popcnt(bits);
diff --git a/components/common/cpp/include/ftl/utility/msgpack.hpp b/components/common/cpp/include/ftl/utility/msgpack.hpp
index 3e13df14462ea4edc3210a6c0b8aae55ca6e5649..9371e0026323ed950b7e70406216a03cf8f6c60a 100644
--- a/components/common/cpp/include/ftl/utility/msgpack.hpp
+++ b/components/common/cpp/include/ftl/utility/msgpack.hpp
@@ -1,3 +1,11 @@
+/**
+ * @file msgpack.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
+/* Extend msgpack for OpenCV and Eigen types */
+
 #ifndef _FTL_MSGPACK_HPP_
 #define _FTL_MSGPACK_HPP_
 
diff --git a/components/common/cpp/include/ftl/utility/rollingavg.hpp b/components/common/cpp/include/ftl/utility/rollingavg.hpp
index 42d3123d8d55f12cf538a3ccd4ff2e312a9d4956..f97fdec24b4413c6b205124db2b6a6bfd7bcc3e6 100644
--- a/components/common/cpp/include/ftl/utility/rollingavg.hpp
+++ b/components/common/cpp/include/ftl/utility/rollingavg.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file rollingavg.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_ROLLING_AVERAGE_HPP_
 #define _FTL_ROLLING_AVERAGE_HPP_
 
@@ -9,6 +15,8 @@ namespace utility {
  * average over. This is a fast version which may possibily have issues with
  * floating point errors, however these should average out as well. A more
  * accurate version would be much slower.
+ * 
+ * Unused?
  */
 template <typename T, size_t SIZE>
 struct RollingAvg {
diff --git a/components/common/cpp/include/ftl/utility/string.hpp b/components/common/cpp/include/ftl/utility/string.hpp
index d88aa11532a649702fa4325970e60c2fac16ca7c..f3b1c0ce23c0b811dab4fd593bb84b76cf574a84 100644
--- a/components/common/cpp/include/ftl/utility/string.hpp
+++ b/components/common/cpp/include/ftl/utility/string.hpp
@@ -1,6 +1,15 @@
+/**
+ * @file string.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_UTILITY_STRING_HPP_
 #define _FTL_UTILITY_STRING_HPP_
 
+/**
+ * Numeric value to string fix specified precision.
+ */
 template <typename T>
 std::string to_string_with_precision(const T a_value, const int n = 6) {
 	std::ostringstream out;
diff --git a/components/common/cpp/include/ftl/utility/vectorbuffer.hpp b/components/common/cpp/include/ftl/utility/vectorbuffer.hpp
index 0e33ff9356975750ab09040475b39392334cd0e0..be77fac120388c9681a8862d4962bf1e5f91a5b7 100644
--- a/components/common/cpp/include/ftl/utility/vectorbuffer.hpp
+++ b/components/common/cpp/include/ftl/utility/vectorbuffer.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file vectorbuffer.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_UTILITY_VECTORBUFFER_HPP_
 #define _FTL_UTILITY_VECTORBUFFER_HPP_
 
@@ -5,6 +11,10 @@
 
 namespace ftl {
 namespace util {
+
+/**
+ * Used for msgpack encoding into an existing std::vector object.
+ */
 class FTLVectorBuffer {
 	public:
 	inline explicit FTLVectorBuffer(std::vector<unsigned char> &v) : vector_(v) {}
diff --git a/components/common/cpp/include/ftl/uuid.hpp b/components/common/cpp/include/ftl/uuid.hpp
index afe5eb7de4df271b9698297a619d7651f1f1d5f8..abe7a781bb1f1dd31b2181ae0aa4561514f993c7 100644
--- a/components/common/cpp/include/ftl/uuid.hpp
+++ b/components/common/cpp/include/ftl/uuid.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file uuid.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_UUID_HPP_
 #define _FTL_UUID_HPP_
 
diff --git a/components/common/cpp/src/configurable.cpp b/components/common/cpp/src/configurable.cpp
index c5f6d9d868806dbe3dc87f64f1069d887bf26b01..f7f69088ed4674a6620fa8b5c536ac986af97fc5 100644
--- a/components/common/cpp/src/configurable.cpp
+++ b/components/common/cpp/src/configurable.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file configurable.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #define LOGURU_REPLACE_GLOG 1
 #include <loguru.hpp>
 #include <ftl/configurable.hpp>
@@ -22,10 +28,6 @@ Configurable::Configurable(nlohmann::json &config) : config_(&config) {
 		LOG(FATAL) << "Configurable json is not an object: " << config;
 	}
 
-	/*if (!config.contains("$id")) {
-		config["$id"] = "ftl://utu.fi";
-	}*/
-
 	ftl::config::registerConfigurable(this);
 }
 
diff --git a/components/common/cpp/src/configuration.cpp b/components/common/cpp/src/configuration.cpp
index 698eee780aa648d07f00e25ac3566b1efeeb5341..e141ed5b85d23a05301923ef29f08b483badaede 100644
--- a/components/common/cpp/src/configuration.cpp
+++ b/components/common/cpp/src/configuration.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file configuration.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #define LOGURU_REPLACE_GLOG 1
 #include <loguru.hpp>
 #include <ftl/config.h>
@@ -58,7 +64,6 @@ json_t config;
 };
 
 using ftl::config::config;
-//using ftl::config::root_config;
 
 static Configurable *rootCFG = nullptr;
 
@@ -66,6 +71,7 @@ bool ftl::running = true;
 int ftl::exit_code = 0;
 std::string ftl::branch_name = FTL_BRANCH;
 
+// TODO: Use std::filesystem
 bool ftl::is_directory(const std::string &path) {
 #ifdef WIN32
 	DWORD attrib = GetFileAttributesA(path.c_str());
@@ -375,22 +381,15 @@ bool ftl::config::update(const std::string &puri, const json_t &value) {
 	string tail = "";
 	string head = "";
 	string uri = preprocessURI(puri);
-	//size_t last_hash = uri.find_last_of('/');
-	//if (last_hash != string::npos) {
-		size_t last = uri.find_last_of('/');
-		if (last != string::npos) {
-			tail = uri.substr(last+1);
-			head = uri.substr(0, last);
-		} else {
-		//	tail = uri.substr(last_hash+1);
-		//	head = uri.substr(0, last_hash);
-			LOG(WARNING) << "Expected a URI path: " << uri;
-			return false;
-		}
-	//} else {
-	//	LOG(WARNING) << "Expected a # in an update URI: " << uri;
-	//	return false;
-	//}
+	size_t last = uri.find_last_of('/');
+
+	if (last != string::npos) {
+		tail = uri.substr(last+1);
+		head = uri.substr(0, last);
+	} else {
+		LOG(WARNING) << "Expected a URI path: " << uri;
+		return false;
+	}
 
 	Configurable *cfg = find(head);
 
@@ -453,7 +452,7 @@ json_t &ftl::config::get(const std::string &puri) {
 json_t &ftl::config::resolve(const std::string &puri, bool eager) {
 	string uri_str = puri;
 
-	// TODO(Nick) Must support alternative root (last $id)
+	// TODO: (Nick) Must support alternative root (last $id)
 	if (uri_str.at(0) == '#') {
 		string id_str = config["$id"].get<string>();
 		if (id_str.find('#') != string::npos) {
@@ -549,12 +548,7 @@ static bool findConfiguration(const string &file, const vector<string> &paths) {
 		}
 	}
 
-	if (found) {
-		//_indexConfig(config);
-		return true;
-	} else {
-		return false;
-	}
+	return found;
 }
 
 /**
@@ -608,19 +602,6 @@ static void process_options(Configurable *root, const map<string, string> &opts)
 		}
 
 		try {
-			/* //auto ptr = nlohmann::json::json_pointer("/"+opt.first);
-			auto ptr = ftl::config::resolve(*root->get<string>("$id") + string("/") + opt.first);
-
-			LOG(INFO) << "PARAM RES TO " << (*root->get<string>("$id") + string("/") + opt.first);
-
-			auto v = nlohmann::json::parse(opt.second);
-			std::string type = ptr.type_name();
-			if (type != "null" && v.type_name() != type) {
-				LOG(ERROR) << "Incorrect type for argument " << opt.first << " - expected '" << type << "', got '" << v.type_name() << "'";
-				continue;
-			}
-			ptr.swap(v);*/
-
 			auto v = nlohmann::json::parse(opt.second);
 			ftl::config::update(*root->get<string>("$id") + string("/") + opt.first, v);
 		} catch(...) {
@@ -735,22 +716,16 @@ std::vector<nlohmann::json*> ftl::config::_createArray(ftl::Configurable *parent
 			if (entity.is_object()) {
 				if (!entity["$id"].is_string()) {
 					std::string id_str = *parent->get<std::string>("$id");
-					//if (id_str.find('#') != std::string::npos) {
-						entity["$id"] = id_str + std::string("/") + name + std::string("/") + std::to_string(i);
-					//} else {
-					//	entity["$id"] = id_str + std::string("#") + name + std::string("/") + std::to_string(i);
-					//}
+				
+					entity["$id"] = id_str + std::string("/") + name + std::string("/") + std::to_string(i);
 				}
 
 				result.push_back(&entity);
 			} else if (entity.is_null()) {
 				// Must create the object from scratch...
 				std::string id_str = *parent->get<std::string>("$id");
-				//if (id_str.find('#') != std::string::npos) {
-					id_str = id_str + std::string("/") + name + std::string("/") + std::to_string(i);
-				//} else {
-				//	id_str = id_str + std::string("#") + name + std::string("/") + std::to_string(i);
-				//}
+				id_str = id_str + std::string("/") + name + std::string("/") + std::to_string(i);
+				
 				parent->getConfig()[name] = {
 					// cppcheck-suppress constStatement
 					{"$id", id_str}
@@ -762,7 +737,7 @@ std::vector<nlohmann::json*> ftl::config::_createArray(ftl::Configurable *parent
 			i++;
 		}
 	} else {
-		//LOG(WARNING) << "Expected an array for '" << name << "' in " << parent->getID();
+		
 	}
 
 	return result;
@@ -776,22 +751,15 @@ nlohmann::json &ftl::config::_create(ftl::Configurable *parent, const std::strin
 	if (entity.is_object()) {
 		if (!entity["$id"].is_string()) {
 			std::string id_str = *parent->get<std::string>("$id");
-			//if (id_str.find('#') != std::string::npos) {
-				entity["$id"] = id_str + std::string("/") + name;
-			//} else {
-			//	entity["$id"] = id_str + std::string("#") + name;
-			//}
+			entity["$id"] = id_str + std::string("/") + name;
 		}
 
 		return entity;
 	} else if (entity.is_null()) {
 		// Must create the object from scratch...
 		std::string id_str = *parent->get<std::string>("$id");
-		//if (id_str.find('#') != std::string::npos) {
-			id_str = id_str + std::string("/") + name;
-		//} else {
-		//	id_str = id_str + std::string("#") + name;
-		//}
+		id_str = id_str + std::string("/") + name;
+		
 		parent->getConfig()[name] = {
 			// cppcheck-suppress constStatement
 			{"$id", id_str}
@@ -921,10 +889,6 @@ Configurable *ftl::config::configure(int argc, char **argv, const std::string &r
 	int pool_size = int(rootcfg->value("thread_pool_factor", 2.0f)*float(std::thread::hardware_concurrency()));
 	if (pool_size != ftl::pool.size()) ftl::pool.resize(pool_size);
 
-
-	//LOG(INFO) << "CONFIG: " << config["vision_default"];
-	//CHECK_EQ( &config, config_index["ftl://utu.fi"] );
-
 	return rootcfg;
 }
 
diff --git a/components/common/cpp/src/cuda_common.cpp b/components/common/cpp/src/cuda_common.cpp
index 949a22704fa1e7454f5094d92296c93f7731190a..9fe40b181d63ea46070831ed6b194ed5603138c0 100644
--- a/components/common/cpp/src/cuda_common.cpp
+++ b/components/common/cpp/src/cuda_common.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file cuda_common.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #define LOGURU_REPLACE_GLOG 1
 #include <loguru.hpp>
 #include <ftl/cuda_common.hpp>
@@ -62,7 +68,6 @@ static void _cudaCallback(void *ud) {
 	delete cb;
 }
 
-// TODO: Move this to a common location
 void cudaCallback(cudaStream_t stream, const std::function<void()> &cb) {
 	cudaSafeCall(cudaLaunchHostFunc(stream, _cudaCallback, (void*)(new std::function<void()>(cb))));
 }
diff --git a/components/common/cpp/src/exception.cpp b/components/common/cpp/src/exception.cpp
index 19edc276e8db8fd3dc2888bdec1a98e2b189f6e2..ec977c425e290abee4b07a1d08b3e90ea7b9f3bd 100644
--- a/components/common/cpp/src/exception.cpp
+++ b/components/common/cpp/src/exception.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file exception.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/exception.hpp>
 
 #define LOGURU_REPLACE_GLOG 1
diff --git a/components/common/cpp/src/file.cpp b/components/common/cpp/src/file.cpp
index b99936b86eeb6f167737afa96c3a2d6f699da9aa..7c6444273a0006cb1ee8812410c950b6d475f80f 100644
--- a/components/common/cpp/src/file.cpp
+++ b/components/common/cpp/src/file.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file file.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Sebastian Hahta
+ */
+
 #include "ftl/file.hpp"
 
 #include <cstdlib>
diff --git a/components/common/cpp/src/profiler.cpp b/components/common/cpp/src/profiler.cpp
index d2298874cde95e553509e2aa22a51a0ba6ea45b8..acf71402b2420e61b75fb0e6f1aa3872b3c6a97f 100644
--- a/components/common/cpp/src/profiler.cpp
+++ b/components/common/cpp/src/profiler.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file profiler.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/profiler.hpp>
 #include <ftl/timer.hpp>
 #include <loguru.hpp>
diff --git a/components/common/cpp/src/timer.cpp b/components/common/cpp/src/timer.cpp
index e9587355e7452ea2841473c0493f606f9d7705aa..52e75a3630aea92ff31863d76f64647595773e59 100644
--- a/components/common/cpp/src/timer.cpp
+++ b/components/common/cpp/src/timer.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file timer.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/timer.hpp>
 #include <ftl/threads.hpp>
 #include <ftl/uuid.hpp>
@@ -75,8 +81,6 @@ static void waitTimePoint() {
 	if (hprec_ && sincelast > mspf) LOG(WARNING) << "Frame " << "(" << (target-last_frame) << ") dropped by " << (sincelast-mspf) << "ms";
 
 	// Use sleep_for for larger delays
-	
-	//LOG(INFO) << "Required Delay: " << (now / 40) << " = " << msdelay;
 	while (msdelay >= 35 && sincelast != mspf) {
 		sleep_for(milliseconds(10));
 		now = get_time();
@@ -109,12 +113,6 @@ static void waitTimePoint() {
 		}
 	}
 
-	/*while (msdelay >= 10 && sincelast != mspf) {
-		sleep_for(milliseconds(5));
-		now = get_time();
-		msdelay = mspf - (now % mspf);
-	}*/
-
 	if (msdelay >= 2 && sincelast != mspf) {
 		UNIQUE_LOCK(mtx, lk);
 		auto idle_job = jobs[kTimerIdle1].begin();
diff --git a/components/common/cpp/src/uri.cpp b/components/common/cpp/src/uri.cpp
index eb0bc3d1d9bd69a3fe221cdf637ecf48f4356085..fcec5597d223086a4db1ead9b43b05c9a5d2eddb 100644
--- a/components/common/cpp/src/uri.cpp
+++ b/components/common/cpp/src/uri.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file uri.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/uri.hpp>
 #include <nlohmann/json.hpp>
 // #include <filesystem>  TODO When available
diff --git a/components/common/cpp/src/utility/image_debug.cpp b/components/common/cpp/src/utility/image_debug.cpp
index d9321e8a6a65e5b50d9418f66f71a0e6a35ffca3..dd5345413b4d039991606b8ab777d2f6a65ae30e 100644
--- a/components/common/cpp/src/utility/image_debug.cpp
+++ b/components/common/cpp/src/utility/image_debug.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file image_debug.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/utility/image_debug.hpp>
 
 #include <opencv2/core.hpp>
diff --git a/components/net/cpp/include/ftl/net.hpp b/components/net/cpp/include/ftl/net.hpp
index 70cced863a2d2faec17a8f4a4b1b1dd1832beb50..ac1043d2fcdc37084aaee110b13c57a8bdfcc759 100644
--- a/components/net/cpp/include/ftl/net.hpp
+++ b/components/net/cpp/include/ftl/net.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file net.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_HPP_
 #define _FTL_NET_HPP_
 
diff --git a/components/net/cpp/include/ftl/net/common.hpp b/components/net/cpp/include/ftl/net/common.hpp
index 1ff4c5bbd73f5888b7141a7be988e162d7e279a6..1955bfaca1fb7c3e13e7addd21e17314e258b49f 100644
--- a/components/net/cpp/include/ftl/net/common.hpp
+++ b/components/net/cpp/include/ftl/net/common.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file common.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_COMMON_HPP_
 #define _FTL_NET_COMMON_HPP_
 
diff --git a/components/net/cpp/include/ftl/net/common_fwd.hpp b/components/net/cpp/include/ftl/net/common_fwd.hpp
index 0c2957b01ee96154cb0dcf2b0d652866d9b3745a..d0f2bc6b7e4ddddb2e12a2b2ec8955b9b07e238c 100644
--- a/components/net/cpp/include/ftl/net/common_fwd.hpp
+++ b/components/net/cpp/include/ftl/net/common_fwd.hpp
@@ -1,18 +1,13 @@
+/**
+ * @file common_fwd.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_COMMON_FORWARD_HPP_
 #define _FTL_NET_COMMON_FORWARD_HPP_
 
 #ifndef WIN32
-
-/*#include <unistd.h>
-#include <sys/poll.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#define SOCKET_ERROR -1*/
-
 #define INVALID_SOCKET -1
 #define SOCKET int
 
diff --git a/components/net/cpp/include/ftl/net/dispatcher.hpp b/components/net/cpp/include/ftl/net/dispatcher.hpp
index ea136483f7982756cf3c5fb9888afea9180f54a4..dea27b2566a07a2d5ab2672902de97fe176bbe85 100644
--- a/components/net/cpp/include/ftl/net/dispatcher.hpp
+++ b/components/net/cpp/include/ftl/net/dispatcher.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file dispatcher.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_DISPATCHER_HPP_
 #define _FTL_NET_DISPATCHER_HPP_
 
@@ -58,18 +64,31 @@ namespace internal {
 
 namespace net {
 
+/**
+ * Allows binding and dispatching of RPC calls. Uses type traits to generate
+ * dispatch functions from the type of the binding function (return and
+ * arguments). Used by ftl::net::Peer and Universe.
+ */
 class Dispatcher {
 	public:
 	explicit Dispatcher(Dispatcher *parent=nullptr) : parent_(parent) {
-		// FIXME threading and funcs_; hack use large size
+		// FIXME: threading and funcs_; hack use large size
 		funcs_.reserve(1024);
 	}
 
-	//void dispatch(Peer &, const std::string &msg);
+	/**
+	 * Primary method by which a peer dispatches a msgpack object that this
+	 * class then decodes to find correct handler and types.
+	 */
 	void dispatch(Peer &, const msgpack::object &msg);
 
 	// Without peer object =====================================================
 
+	/**
+	 * Associate a C++ function woth a string name. Use type traits of that
+	 * function to build a dispatch function that knows how to decode msgpack.
+	 * This is the no arguments and no result case.
+	 */
 	template <typename F>
 	void bind(std::string const &name, F func,
 		                  ftl::internal::tags::void_result const &,
@@ -84,6 +103,11 @@ class Dispatcher {
 		    }));
 	}
 
+	/**
+	 * Associate a C++ function woth a string name. Use type traits of that
+	 * function to build a dispatch function that knows how to decode msgpack.
+	 * This is the arguments but no result case.
+	 */
 	template <typename F>
 	void bind(std::string const &name, F func,
 		                  ftl::internal::tags::void_result const &,
@@ -104,6 +128,11 @@ class Dispatcher {
 		    }));
 	}
 
+	/**
+	 * Associate a C++ function woth a string name. Use type traits of that
+	 * function to build a dispatch function that knows how to decode msgpack.
+	 * This is the no arguments but with result case.
+	 */
 	template <typename F>
 	void bind(std::string const &name, F func,
 		                  ftl::internal::tags::nonvoid_result const &,
@@ -121,6 +150,11 @@ class Dispatcher {
 		}));
 	}
 
+	/**
+	 * Associate a C++ function woth a string name. Use type traits of that
+	 * function to build a dispatch function that knows how to decode msgpack.
+	 * This is the with arguments and with result case.
+	 */
 	template <typename F>
 	void bind(std::string const &name, F func,
 		                  ftl::internal::tags::nonvoid_result const &,
@@ -218,6 +252,9 @@ class Dispatcher {
 
 	//==========================================================================
 
+	/**
+	 * Remove a previous bound function by name.
+	 */
 	void unbind(const std::string &name) {
 		auto i = funcs_.find(name);
 		if (i != funcs_.end()) {
@@ -225,10 +262,20 @@ class Dispatcher {
 		}
 	}
 
+	/**
+	 * @return All bound function names.
+	 */
 	std::vector<std::string> getBindings() const;
 
+	/**
+	 * @param name Function name.
+	 * @return True if the given name is bound to a function.
+	 */
 	bool isBound(const std::string &name) const;
 
+
+	//==== Types ===============================================================
+
 	using adaptor_type = std::function<std::unique_ptr<msgpack::object_handle>(
         ftl::net::Peer &, msgpack::object const &)>;
 
diff --git a/components/net/cpp/include/ftl/net/handlers.hpp b/components/net/cpp/include/ftl/net/handlers.hpp
index e1af54a783cc48d68fecfaa1fd7413e5716ae698..c103e7a9d102ebc0ed1a6b40df0c2d517e256b08 100644
--- a/components/net/cpp/include/ftl/net/handlers.hpp
+++ b/components/net/cpp/include/ftl/net/handlers.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file handlers.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_HANDLERS_HPP_
 #define _FTL_NET_HANDLERS_HPP_
 
diff --git a/components/net/cpp/include/ftl/net/ice.hpp b/components/net/cpp/include/ftl/net/ice.hpp
index 22a4f5f3cf40fae067c82af09107d4fcdabccad1..a112a5e0e1c3675aac1bfceb0d9c4e189a6b8836 100644
--- a/components/net/cpp/include/ftl/net/ice.hpp
+++ b/components/net/cpp/include/ftl/net/ice.hpp
@@ -1,3 +1,12 @@
+/**
+ * @file ice.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * 
+ * @deprecated
+ * Unused.
+ */
+
 #ifndef _FTL_NET_ICE_HPP_
 #define _FTL_NET_ICE_HPP_
 
diff --git a/components/net/cpp/include/ftl/net/listener.hpp b/components/net/cpp/include/ftl/net/listener.hpp
index bbf6d0c6aa02623430bc16833a7f0f7cc0bf64da..42abd01e1f7f1ebefa0cd9256089fed48d39073b 100644
--- a/components/net/cpp/include/ftl/net/listener.hpp
+++ b/components/net/cpp/include/ftl/net/listener.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file listener.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_LISTENER_HPP_
 #define _FTL_NET_LISTENER_HPP_
 
@@ -11,11 +17,24 @@
 namespace ftl {
 namespace net {
 
-class Protocol;
+class Protocol;  ///< Unused?
 
+/**
+ * Listener for new peer connections on specified port.
+ */
 class Listener {
 	public:
+	/**
+	 * Use a URI to specify interface address, port and protocol.
+	 * 
+	 * Example:
+	 *  * tcp://localhost:9000
+	 */
 	explicit Listener(const char *uri);
+
+	/**
+	 * Use already provided Socket to listen on.
+	 */
 	explicit Listener(SOCKET sfd) : descriptor_(sfd), default_proto_(nullptr) {}
 	virtual ~Listener();
 	
@@ -23,9 +42,17 @@ class Listener {
 	void close();
 	SOCKET _socket() { return descriptor_; }
 	
+	/** @deprecated */
 	void setProtocol(Protocol *p) { default_proto_ = p; }
 	
+	/**
+	 * Unused
+	 */
 	void connection(std::shared_ptr<Peer> &s);
+
+	/**
+	 * Unused
+	 */
 	void onConnection(connecthandler_t h) { handler_connect_.push_back(h); };
 
 	inline int port() const { return port_; }
diff --git a/components/net/cpp/include/ftl/net/p2p.hpp b/components/net/cpp/include/ftl/net/p2p.hpp
index 8c956fd2685b1512872c40b837268cd97c16810b..94617b08a478b157f5d335d62419451faef62c97 100644
--- a/components/net/cpp/include/ftl/net/p2p.hpp
+++ b/components/net/cpp/include/ftl/net/p2p.hpp
@@ -1,3 +1,11 @@
+/**
+ * @file p2p.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * 
+ * Old file, unused.
+ */
+
 #ifndef _FTL_NET_P2P_HPP_
 #define _FTL_NET_P2P_HPP_
 
diff --git a/components/net/cpp/include/ftl/net/peer.hpp b/components/net/cpp/include/ftl/net/peer.hpp
index e1ef7b5d59c89c1b7f78239c185d1effbcee1fbe..1eb8b75051fd792e1c08bc00ea56bc25a6a1e948 100644
--- a/components/net/cpp/include/ftl/net/peer.hpp
+++ b/components/net/cpp/include/ftl/net/peer.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file peer.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_PEER_HPP_
 #define _FTL_NET_PEER_HPP_
 
@@ -10,7 +16,6 @@
 #include <ftl/net/common_fwd.hpp>
 #include <ftl/exception.hpp>
 
-//#define GLOG_NO_ABBREVIATED_SEVERITIES
 #include <ftl/net/protocol.hpp>
 #include <ftl/net/dispatcher.hpp>
 #include <ftl/uri.hpp>
@@ -51,12 +56,6 @@ struct caller : virtual_caller {
 	std::function<void(const T&)> f_;
 };
 
-//typedef std::tuple<const char*,size_t> array;
-/*struct compress{};
-struct encrypt{};
-struct decompress{};
-struct decrypt{};*/
-
 /**
  * A single socket connection object, to be constructed using the connect()
  * function and not to be created directly.
diff --git a/components/net/cpp/include/ftl/net/protocol.hpp b/components/net/cpp/include/ftl/net/protocol.hpp
index 6ae76c0541684a119ee525f484c4b60ecd2d0393..69cc2e2eb0fdd587bce46629604707a7691de882 100644
--- a/components/net/cpp/include/ftl/net/protocol.hpp
+++ b/components/net/cpp/include/ftl/net/protocol.hpp
@@ -1,3 +1,11 @@
+/**
+ * @file protocol.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ * 
+ * Unused?
+ */
+
 #ifndef _FTL_NET_PROTOCOL_HPP_
 #define _FTL_NET_PROTOCOL_HPP_
 
diff --git a/components/net/cpp/include/ftl/net/universe.hpp b/components/net/cpp/include/ftl/net/universe.hpp
index 58f23053a7107f8e279a684fa4d9a400e1031f0b..4135897a8c157fe17404457541124e1b0c6ffa9d 100644
--- a/components/net/cpp/include/ftl/net/universe.hpp
+++ b/components/net/cpp/include/ftl/net/universe.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file universe.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_UNIVERSE_HPP_
 #define _FTL_NET_UNIVERSE_HPP_
 
diff --git a/components/net/cpp/include/ftl/net/ws_internal.hpp b/components/net/cpp/include/ftl/net/ws_internal.hpp
index fb457578ecd1e6a4f0bb5e35819eb161acdbe837..f449560ef1855db8a64cb2d6fa8b0e45b4c61c31 100644
--- a/components/net/cpp/include/ftl/net/ws_internal.hpp
+++ b/components/net/cpp/include/ftl/net/ws_internal.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file ws_internal.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_WS_INTERNAL_HPP_
 #define _FTL_NET_WS_INTERNAL_HPP_
 
diff --git a/components/net/cpp/include/ftl/net_configurable.hpp b/components/net/cpp/include/ftl/net_configurable.hpp
index 2c6495410321c03b62e18a83f214d00b807bccdb..4e21ae5a574f32164a104cb8e3d6a9d29992efc9 100644
--- a/components/net/cpp/include/ftl/net_configurable.hpp
+++ b/components/net/cpp/include/ftl/net_configurable.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file net_configurable.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Iiro Rastas
+ */
+
 #pragma once
 #ifndef _FTL_NETCONFIGURABLE_HPP_
 #define _FTL_NETCONFIGURABLE_HPP_
diff --git a/components/net/cpp/src/dispatcher.cpp b/components/net/cpp/src/dispatcher.cpp
index 2be0055ae59924296562976e9d2db612d136aabd..32ceeda5a08e48320ee43d191ffb7e6da95281d0 100644
--- a/components/net/cpp/src/dispatcher.cpp
+++ b/components/net/cpp/src/dispatcher.cpp
@@ -1,4 +1,9 @@
-//#define GLOG_NO_ABBREVIATED_SEVERITIES
+/**
+ * @file dispatcher.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <loguru.hpp>
 #include <ftl/net/dispatcher.hpp>
 #include <ftl/net/peer.hpp>
@@ -11,23 +16,6 @@ using std::vector;
 using std::string;
 using std::optional;
 
-/*static std::string hexStr(const std::string &s)
-{
-	const char *data = s.data();
-	int len = s.size();
-    std::stringstream ss;
-    ss << std::hex;
-    for(int i=0;i<len;++i)
-        ss << std::setw(2) << std::setfill('0') << (int)data[i];
-    return ss.str();
-}*/
-
-//void ftl::net::Dispatcher::dispatch(Peer &s, const std::string &msg) {
-	//std::cout << "Received dispatch : " << hexStr(msg) << std::endl;
-//    auto unpacked = msgpack::unpack(msg.data(), msg.size());
-//    dispatch(s, unpacked.get());
-//}
-
 vector<string> Dispatcher::getBindings() const {
 	vector<string> res;
 	for (auto x : funcs_) {
@@ -78,17 +66,9 @@ void ftl::net::Dispatcher::dispatch_call(Peer &s, const msgpack::object &msg) {
 		    try {
 		        auto result = (*func)(s, args); //->get();
 		        s._sendResponse(id, name, result->get());
-		        /*response_t res_obj = std::make_tuple(1,id,msgpack::object(),result->get());
-				std::stringstream buf;
-				msgpack::pack(buf, res_obj);			
-				s.send("__return__", buf.str());*/
 			} catch (const std::exception &e) {
 				//throw;
 				LOG(ERROR) << "Exception when attempting to call RPC (" << e.what() << ")";
-		        /*response_t res_obj = std::make_tuple(1,id,msgpack::object(e.what()),msgpack::object());
-				std::stringstream buf;
-				msgpack::pack(buf, res_obj);			
-				s.send("__return__", buf.str());*/
 			}
 		} else {
 			LOG(WARNING) << "No binding found for " << name;
@@ -128,7 +108,6 @@ void ftl::net::Dispatcher::dispatch_notification(Peer &s, msgpack::object const
     auto &&args = std::get<2>(the_call);
 
     auto binding = _locateHandler(name);
-	//LOG(INFO) << "NOTIFICATION " << name << "() <- " << s.getURI();
 
     if (binding) {
         try {
diff --git a/components/net/cpp/src/ice.cpp b/components/net/cpp/src/ice.cpp
index 0929eaba638a241a6870bb797e8461a227d113cb..b2a5b49ba52fa5b56777396a34714c97b917f602 100644
--- a/components/net/cpp/src/ice.cpp
+++ b/components/net/cpp/src/ice.cpp
@@ -1,4 +1,10 @@
-//#define _GNU_SOURCE
+/**
+ * @file ice.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
+
 #include <ftl/net/ice.hpp>
 #include <ftl/net/stun.hpp>
 #include <ftl/uri.hpp>
diff --git a/components/net/cpp/src/listener.cpp b/components/net/cpp/src/listener.cpp
index 90ec540f4de09cfb82c763e9b3bf591ad8cf9314..2a407b9213a230aaf3688f9b301ac13cb707fb44 100644
--- a/components/net/cpp/src/listener.cpp
+++ b/components/net/cpp/src/listener.cpp
@@ -1,4 +1,9 @@
-//#define GLOG_NO_ABBREVIATED_SEVERITIES
+/**
+ * @file listener.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <loguru.hpp>
 
 #include <ftl/uri.hpp>
@@ -116,22 +121,7 @@ Listener::~Listener() {
 }
 
 void Listener::connection(shared_ptr<Peer> &s) {
-	/*Handshake hs1;
-	hs1.magic = ftl::net::MAGIC;
-	memset(hs1.id, 0, 16);
-	
-	if (default_proto_) {
-		s->setProtocol(default_proto_);
-		hs1.proto_size = default_proto_->id().size();
-		s->send(FTL_PROTOCOL_HS1, hs1, default_proto_->id());
-	} else {
-		s->setProtocol(NULL);
-		hs1.proto_size = 0;
-		s->send(FTL_PROTOCOL_HS1, hs1);
-	}
-	
-	LOG(INFO) << "Handshake initiated with " << s->getURI();
-	for (auto h : handler_connect_) h(s);*/
+
 }
 
 void Listener::close() {
diff --git a/components/net/cpp/src/main.cpp b/components/net/cpp/src/main.cpp
deleted file mode 100644
index 7999e37b771c21fb380441fab72c55ccdcf10e9b..0000000000000000000000000000000000000000
--- a/components/net/cpp/src/main.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-#include <string>
-#include <iostream>
-#include <map>
-//#include <vector>
-#include <fstream>
-#include <ftl/net.hpp>
-
-#ifndef WIN32
-#include <readline/readline.h>
-#endif
-
-#ifdef WIN32
-#pragma comment(lib, "Ws2_32.lib")
-#pragma comment(lib, "Rpcrt4.lib")
-#endif
-
-using std::string;
-using ftl::net::Universe;
-using json = nlohmann::json;
-using std::ifstream;
-using std::map;
-
-static Universe *universe;
-static volatile bool stop = false;
-
-// Store loaded configuration
-static json config;
-
-/**
- * Find and load a JSON configuration file
- */
-static bool findConfiguration(const string &file) {
-	ifstream i;
-	
-	if (file != "") i.open(file);
-	if (!i.is_open()) i.open("./config.json");
-	if (!i.is_open()) i.open(FTL_LOCAL_CONFIG_ROOT "/config.json");
-	if (!i.is_open()) i.open(FTL_GLOBAL_CONFIG_ROOT "/config.json");
-	if (!i.is_open()) return false;
-	i >> config;
-	return true;
-}
-
-/**
- * Generate a map from command line option to value
- */
-map<string, string> read_options(char ***argv, int *argc) {
-	map<string, string> opts;
-
-	while (*argc > 0) {
-		string cmd((*argv)[0]);
-		if (cmd[0] != '-') break;
-
-		size_t p;
-		if ((p = cmd.find("=")) == string::npos) {
-			opts[cmd.substr(2)] = "true";
-		} else {
-			opts[cmd.substr(2, p-2)] = cmd.substr(p+1);
-		}
-
-		(*argc)--;
-		(*argv)++;
-	}
-
-	return opts;
-}
-
-/**
- * Put command line options into json config. If config element does not exist
- * or is of a different type then report an error.
- */
-static void process_options(const map<string, string> &opts) {
-	for (auto opt : opts) {
-		if (opt.first == "config") continue;
-
-		if (opt.first == "version") {
-			std::cout << "FTL Vision Node - v" << FTL_VERSION << std::endl;
-			std::cout << FTL_VERSION_LONG << std::endl;
-			exit(0);
-		}
-
-		try {
-			auto ptr = json::json_pointer("/"+opt.first);
-			// TODO(nick) Allow strings without quotes
-			auto v = json::parse(opt.second);
-			if (v.type() != config.at(ptr).type()) {
-				LOG(ERROR) << "Incorrect type for argument " << opt.first;
-				continue;
-			}
-			config.at(ptr) = v;
-		} catch(...) {
-			LOG(ERROR) << "Unrecognised option: " << opt.first;
-		}
-	}
-}
-
-void handle_command(const char *l) {
-	string cmd = string(l);
-	
-	if (cmd == "exit") {
-		stop = true;
-	} else if (cmd.find("peer ") == 0) {
-		cmd = cmd.substr(cmd.find(" ")+1);
-		universe->connect(cmd);
-	} else if (cmd.find("list ") == 0) {
-		cmd = cmd.substr(cmd.find(" ")+1);
-		if (cmd == "peers") {
-			//auto res = p2p->getPeers();
-			//for (auto r : res) std::cout << "  " << r->to_string() << std::endl;
-		}
-	}
-}
-
-int main(int argc, char **argv) {
-	argc--;
-	argv++;
-
-	// Process Arguments
-	auto options = read_options(&argv, &argc);
-	if (!findConfiguration(options["config"])) {
-		LOG(FATAL) << "Could not find any configuration!";
-	}
-	process_options(options);
-	
-	universe = new Universe(config);
-	
-	while (!stop) {
-#ifndef WIN32
-		char *line = readline("> ");
-#else
-		char line[300];
-		fgets(line, 299, stdin);
-#endif
-		if (!line) break;
-		
-		handle_command(line);
-		
-#ifndef WIN32
-		free(line);
-#endif
-	}
-	stop = true;
-	
-	delete universe;
-	return 0;
-}
-
diff --git a/components/net/cpp/src/net_internal.hpp b/components/net/cpp/src/net_internal.hpp
index fa116a675af38f18e99a6ff31db0b3d13b1464cd..7ba305ade7cef465195323843efee4253bf74a77 100644
--- a/components/net/cpp/src/net_internal.hpp
+++ b/components/net/cpp/src/net_internal.hpp
@@ -1,3 +1,9 @@
+/**
+ * @file net_internal.hpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #ifndef _FTL_NET_INTERNAL_HPP_
 #define _FTL_NET_INTERNAL_HPP_
 
diff --git a/components/net/cpp/src/peer.cpp b/components/net/cpp/src/peer.cpp
index 1bf4b3d7e340c19afe40be40d4045a9ddc83dbd4..0dad3b02b3b31b0bef3d8a69fb62a3b58d5583f2 100644
--- a/components/net/cpp/src/peer.cpp
+++ b/components/net/cpp/src/peer.cpp
@@ -1,4 +1,9 @@
-//#define GLOG_NO_ABBREVIATED_SEVERITIES
+/**
+ * @file peer.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <loguru.hpp>
 #include <ctpl_stl.h>
 
@@ -222,8 +227,6 @@ Peer::Peer(SOCKET s, Universe *u, Dispatcher *d) : sock_(s), can_reconnect_(fals
 		});
 
 		bind("__ping__", [this]() {
-			//auto now = std::chrono::high_resolution_clock::now();
-			//return std::chrono::time_point_cast<std::chrono::milliseconds>(now).time_since_epoch().count();
 			return ftl::timer::get_time();
 		});
 
@@ -300,8 +303,6 @@ Peer::Peer(const char *pUri, Universe *u, Dispatcher *d) : can_reconnect_(true),
 		});
 
 		bind("__ping__", [this]() {
-			//auto now = std::chrono::high_resolution_clock::now();
-			//return std::chrono::time_point_cast<std::chrono::milliseconds>(now).time_since_epoch().count();
 			return ftl::timer::get_time();
 		});
 	}
@@ -389,9 +390,6 @@ void Peer::_badClose(bool retry) {
 		closesocket(sock_);
 		#endif
 		sock_ = INVALID_SOCKET;
-		
-		//auto i = find(sockets.begin(),sockets.end(),this);
-		//sockets.erase(i);
 
 		universe_->_notifyDisconnect(this);
 		status_ = kDisconnected;
@@ -428,12 +426,8 @@ void Peer::error(int e) {
 
 void Peer::data() {
 	{
-		//auto start = std::chrono::high_resolution_clock::now();
-		//int64_t startts = std::chrono::time_point_cast<std::chrono::milliseconds>(start).time_since_epoch().count();
 		UNIQUE_LOCK(recv_mtx_,lk);
 
-		//LOG(INFO) << "Pool size: " << ftl::pool.q_size();
-
 		int rc=0;
 
 		recv_buf_.reserve_buffer(kMaxMessage);
@@ -447,15 +441,6 @@ void Peer::data() {
 		auto buf = recv_buf_.buffer();
 		lk.unlock();
 
-		/*#ifndef WIN32
-		int n;
-		unsigned int m = sizeof(n);
-		getsockopt(sock_,SOL_SOCKET,SO_RCVBUF,(void *)&n, &m);
-
-		int pending;
-		ioctl(sock_, SIOCINQ, &pending);
-		if (pending > 100000) LOG(INFO) << "Buffer usage: " << float(pending) / float(n);
-		#endif*/
 		rc = ftl::net::internal::recv(sock_, buf, cap, 0);
 
 		if (rc >= cap-1) {
@@ -474,10 +459,6 @@ void Peer::data() {
 		lk.lock();
 		recv_buf_.buffer_consumed(rc);
 
-		//auto end = std::chrono::high_resolution_clock::now();
-		//int64_t endts = std::chrono::time_point_cast<std::chrono::milliseconds>(end).time_since_epoch().count();
-		//if (endts - startts > 50) LOG(ERROR) << "Excessive delay";
-
 		if (is_waiting_) {
 			is_waiting_ = false;
 			lk.unlock();
@@ -649,14 +630,6 @@ bool Peer::waitConnection() {
 	return status_ == kConnected;
 }
 
-/*void Peer::onConnect(const std::function<void(Peer&)> &f) {
-	if (status_ == kConnected) {
-		f(*this);
-	} else {
-		open_handlers_.push_back(f);
-	}
-}*/
-
 void Peer::_connected() {
 	status_ = kConnected;
 
@@ -683,8 +656,6 @@ int Peer::_send() {
 		if (sendvec[0].iov_len != 0) {
 			LOG(FATAL) << "CORRUPTION in websocket header buffer";
 		}
-
-		//LOG(INFO) << "SEND SIZE = " << len;
 		
 		// Pack correct websocket header into buffer
 		int rc = ws_prepare(wsheader_type::BINARY_FRAME, false, len, buf, 20);
@@ -706,7 +677,6 @@ int Peer::_send() {
 		}
 
 		DWORD bytessent;
-		//c = WSASend(sock_, wsabuf.data(), static_cast<DWORD>(send_size), (LPDWORD)&bytessent, 0, NULL, NULL);
 		c = ftl::net::internal::writev(sock_, wsabuf.data(), static_cast<DWORD>(send_size), (LPDWORD)&bytessent);
 #else
 		c = ftl::net::internal::writev(sock_, send_buf_.vector(), (int)send_buf_.vector_size());
@@ -725,7 +695,6 @@ int Peer::_send() {
 		}
 
 		DWORD bytessent;
-		//c = WSASend(sock_, wsabuf.data(), static_cast<DWORD>(send_size), (LPDWORD)&bytessent, 0, NULL, NULL);
 		c = ftl::net::internal::writev(sock_, wsabuf.data(), static_cast<DWORD>(send_size), (LPDWORD)&bytessent);
 #else
 		c = ftl::net::internal::writev(sock_, send_buf_.vector(), (int)send_buf_.vector_size());
diff --git a/components/net/cpp/src/universe.cpp b/components/net/cpp/src/universe.cpp
index 3dbcd58876e27367106ecb683c4b10188498aa33..bb2a612c0b5c3567ef29b1e35b8b4e23d1cc7a2d 100644
--- a/components/net/cpp/src/universe.cpp
+++ b/components/net/cpp/src/universe.cpp
@@ -1,3 +1,9 @@
+/**
+ * @file universe.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
+ */
+
 #include <ftl/net/universe.hpp>
 #include <ftl/timer.hpp>
 #include <chrono>
@@ -38,9 +44,7 @@ struct NetImplDetail {
 }
 }
 
-//#define TCP_SEND_BUFFER_SIZE	(512*1024)
-//#define TCP_RECEIVE_BUFFER_SIZE	(1024*1024*1)
-
+// Defaults, should be changed in config
 #define TCP_SEND_BUFFER_SIZE	(512*1024)
 #define TCP_RECEIVE_BUFFER_SIZE	(1024*1024)  // Perhaps try 24K?
 #define WS_SEND_BUFFER_SIZE	(512*1024)
@@ -71,8 +75,6 @@ Universe::Universe(nlohmann::json &config) :
 		this_peer(ftl::net::this_peer),
 		impl_(new ftl::net::NetImplDetail),
 		phase_(0),
-		//send_size_(value("tcp_send_buffer",TCP_SEND_BUFFER_SIZE)),
-		//recv_size_(value("tcp_recv_buffer",TCP_RECEIVE_BUFFER_SIZE)),
 		periodic_time_(value("periodics", 1.0)),
 		reconnect_attempts_(value("reconnect_attempts",50)),
 		thread_(Universe::__start, this) {
diff --git a/components/net/cpp/src/ws_internal.cpp b/components/net/cpp/src/ws_internal.cpp
index 28318ab5b3291e2941298f1ebb7defd0636d134e..064dca24ecb02d33f26d7ec964b1a167436be713 100644
--- a/components/net/cpp/src/ws_internal.cpp
+++ b/components/net/cpp/src/ws_internal.cpp
@@ -1,8 +1,9 @@
-/*
- * Copyright 2019 Nicolas Pope.
+/**
+ * @file ws_internal.cpp
+ * @copyright Copyright (c) 2020 University of Turku, MIT License
+ * @author Nicolas Pope
  */
 
-//#define GLOG_NO_ABBREVIATED_SEVERITIES
 #include <loguru.hpp>
 
 #include <cstring>
diff --git a/components/rgbd-sources/include/ftl/rgbd/format.hpp b/components/rgbd-sources/include/ftl/rgbd/format.hpp
index 11390f14cfeea5cfddbc5a29dd08fb091101b04d..afc5d623ecce8e8cc2cbba205b125f70f88e1acb 100644
--- a/components/rgbd-sources/include/ftl/rgbd/format.hpp
+++ b/components/rgbd-sources/include/ftl/rgbd/format.hpp
@@ -28,11 +28,6 @@ struct Format : public ftl::rgbd::FormatBase {
 	Format(size_t w, size_t h) : FormatBase(
 			w, h, ftl::traits::OpenCVType<T>::value) {}
 
-	explicit Format(ftl::codecs::definition_t d) : FormatBase(
-			ftl::codecs::getWidth(d),
-			ftl::codecs::getHeight(d),
-			ftl::traits::OpenCVType<T>::value) {}
-
 	explicit Format(const cv::Size &s) : FormatBase(
 			s.width,
 			s.height,
diff --git a/components/rgbd-sources/src/sources/screencapture/screencapture.cpp b/components/rgbd-sources/src/sources/screencapture/screencapture.cpp
index dff3510141530c014c22414e8cd79b23e495cc59..3587423ceabcc0831563c308e7e47ae800da2dc7 100644
--- a/components/rgbd-sources/src/sources/screencapture/screencapture.cpp
+++ b/components/rgbd-sources/src/sources/screencapture/screencapture.cpp
@@ -126,10 +126,7 @@ ScreenCapture::ScreenCapture(ftl::rgbd::Source *host)
 	full_height_ = s.window_attributes.height;
 	offset_x_ = host_->value("offset_x",0);
 	offset_y_ = host_->value("offset_y",0);
-
-	// Choose a correct aspect ratio
-	int awidth = ftl::codecs::getWidth(ftl::codecs::findDefinition(full_height_));
-	params_.width = awidth;
+	params_.width = full_width_;
 	params_.height = full_height_;
 
 	LOG(INFO) << "Screen capture: " << params_.width << "x" << params_.height;
diff --git a/components/streams/src/sender.cpp b/components/streams/src/sender.cpp
index 99713e9082c06dc4586bcd0cc17d691b9680d678..fedacc249ac407025f551a2b50c5db73b43acc75 100644
--- a/components/streams/src/sender.cpp
+++ b/components/streams/src/sender.cpp
@@ -15,10 +15,8 @@ using ftl::codecs::StreamPacket;
 using ftl::codecs::Packet;
 using ftl::codecs::Channels;
 using ftl::codecs::Channel;
-using ftl::codecs::definition_t;
 using ftl::codecs::device_t;
 using ftl::codecs::codec_t;
-using ftl::codecs::format_t;
 using ftl::stream::injectCalibration;
 using ftl::stream::injectPose;
 using ftl::stream::injectConfig;
@@ -519,8 +517,7 @@ void Sender::_encodeVideoChannel(ftl::data::FrameSet &fs, Channel c, bool reset)
 
 		ftl::codecs::Encoder *enc = tile.encoder[encoder_number];
 		if (!enc) {
-			enc = ftl::codecs::allocateEncoder(
-				definition_t::HD1080, device, codec);
+			enc = ftl::codecs::allocateEncoder(device, codec);
 			tile.encoder[encoder_number] = enc;
 		}
 
diff --git a/components/streams/test/receiver_unit.cpp b/components/streams/test/receiver_unit.cpp
index 29bf0b241f1f4563202987cc3656e377cf889acd..8b51304f8511674cc15012b30850d3a898476bb0 100644
--- a/components/streams/test/receiver_unit.cpp
+++ b/components/streams/test/receiver_unit.cpp
@@ -9,7 +9,6 @@
 
 #include <loguru.hpp>
 
-using ftl::codecs::definition_t;
 using ftl::codecs::codec_t;
 using ftl::stream::Receiver;
 using ftl::rgbd::Frame;
@@ -112,7 +111,7 @@ TEST_CASE( "Receiver generating onFrameSet" ) {
 	receiver->setStream(&stream);
 	receiver->set("frameset_buffer_size", 0);
 
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 
 	ftl::codecs::Packet pkt;
 	pkt.codec = codec_t::Any;
@@ -326,7 +325,7 @@ TEST_CASE( "Receiver sync bugs" ) {
 	receiver->setStream(&stream);
 	receiver->set("frameset_buffer_size", 0);
 
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 
 	ftl::codecs::Packet pkt;
 	pkt.codec = codec_t::Any;
@@ -415,7 +414,7 @@ TEST_CASE( "Receiver non zero buffer" ) {
 	receiver->setStream(&stream);
 	receiver->set("frameset_buffer_size", 1);
 
-	ftl::codecs::NvidiaEncoder encoder(definition_t::HD1080, definition_t::SD480);
+	ftl::codecs::NvidiaEncoder encoder;
 
 	ftl::codecs::Packet pkt;
 	pkt.codec = codec_t::Any;
diff --git a/components/streams/test/recsend_unit.cpp b/components/streams/test/recsend_unit.cpp
index 9a3e71fe9c4e88ad3a35cd20682cf5afb4522233..bc866dc488702af64a66dd4ebceafe2d402805e1 100644
--- a/components/streams/test/recsend_unit.cpp
+++ b/components/streams/test/recsend_unit.cpp
@@ -8,7 +8,6 @@
 
 #include <loguru.hpp>
 
-using ftl::codecs::definition_t;
 using ftl::codecs::codec_t;
 using ftl::stream::Receiver;
 using ftl::stream::Sender;
diff --git a/components/streams/test/sender_unit.cpp b/components/streams/test/sender_unit.cpp
index 11c44ae33bad5ac61bbb01f90a45c6002372868f..f2a45eafb1395d0e867ba84562dfcdbcddad2530 100644
--- a/components/streams/test/sender_unit.cpp
+++ b/components/streams/test/sender_unit.cpp
@@ -8,7 +8,6 @@
 
 #include <loguru.hpp>
 
-using ftl::codecs::definition_t;
 using ftl::codecs::codec_t;
 using ftl::stream::Sender;
 using ftl::data::Frame;