diff --git a/components/rgbd-sources/include/ftl/rgbd/detail/source.hpp b/components/rgbd-sources/include/ftl/rgbd/detail/source.hpp index 25e19e39641b1643eb9ba8cdc3240a4a719834b3..a75fb1879f5e919cc306ca9b96a3f9562051f549 100644 --- a/components/rgbd-sources/include/ftl/rgbd/detail/source.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/detail/source.hpp @@ -10,6 +10,10 @@ namespace rgbd { class Source; +// TODO: frame.hpp has to know the exact amount of channels +// (remove hardcoded value by providing exact value elsewhere). +// Possibly move channels to frame.hpp? + typedef unsigned int channel_t; static const channel_t kChanNone = 0; diff --git a/components/rgbd-sources/include/ftl/rgbd/frame.hpp b/components/rgbd-sources/include/ftl/rgbd/frame.hpp index 41eb7509541f40dd15d9ae121a30139edf311311..a97a1f17b5bdf7afd64921727be69ce1039eca6a 100644 --- a/components/rgbd-sources/include/ftl/rgbd/frame.hpp +++ b/components/rgbd-sources/include/ftl/rgbd/frame.hpp @@ -4,24 +4,6 @@ #include <ftl/configuration.hpp> #include <opencv2/core.hpp> -// https://stackoverflow.com/a/31718095/ -static uint32_t msbDeBruijn32(uint32_t v) -{ - static const int MultiplyDeBruijnBitPosition[32] = - { - 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, - 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 - }; - - v |= v >> 1; // first round down to one less than a power of 2 - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - - return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27]; -} - namespace ftl { namespace rgbd { @@ -38,21 +20,66 @@ public: std::fill(available_.begin(), available_.end(), false); } - /* @brief Is there valid data in channel + /* @brief Is there valid data in channel. Must be checked if user + * is not providing the data and it is uncertain that valid data is + * available. */ bool hasChannel(const ftl::rgbd::channel_t& channel) { - return available_[msbDeBruijn32(channel)]; + return available_[_channelIdx(channel)]; } - /* @brief Get reference to the channel GpuMat + /* @brief Get reference to the channel GpuMat and marks it valid. + * If hasChannel() was false, user of this method must set + * valid data to the returned reference. */ cv::cuda::GpuMat& getChannel(const ftl::rgbd::channel_t& channel) { - return channels_[msbDeBruijn32(channel)]; + auto idx = _channelIdx(channel); + available_[idx] = true; + return channels_[idx]; } private: + + static size_t _channelIdx(const ftl::rgbd::channel_t& channel) + { + switch(channel) + { + case kChanNone: return 0; + case kChanLeft: return 1; + case kChanDepth: return 2; + case kChanRight: return 3; + case kChanDisparity: return 4; + case kChanDeviation: return 5; + case kChanNormals: return 6; + case kChanConfidence: return 7; + case kChanFlow: return 8; + case kChanEnergy: return 9; + default: return 0; // should not happen + } + } + + // https://stackoverflow.com/a/31718095/ + // Indices for channels, requirs channels to have bitmask format + // (values are power of 2 and no missing values/gaps). + static uint32_t _msbDeBruijn32(uint32_t v) + { + static const int MultiplyDeBruijnBitPosition[32] = + { + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 + }; + + v |= v >> 1; // first round down to one less than a power of 2 + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + + return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27]; + } + std::vector<cv::cuda::GpuMat> channels_; std::vector<bool> available_; };