diff --git a/CMakeLists.txt b/CMakeLists.txt index 8050737383bbddd74ee73e10dc79998ae70e33e5..5261bea739d11c17e649470777565c17d5db8ae9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -191,6 +191,7 @@ add_library(beyond-protocol STATIC src/self.cpp src/protocol.cpp src/rpc.cpp + src/channelUtils.cpp ) target_include_directories(beyond-protocol PUBLIC diff --git a/include/ftl/protocol/channelUtils.hpp b/include/ftl/protocol/channelUtils.hpp index 7c6a061cde5f4f776bf43b9f8b60455b1a0043a6..6606e1ddbda3437b3c51477fb0f9f357bf1e682e 100644 --- a/include/ftl/protocol/channelUtils.hpp +++ b/include/ftl/protocol/channelUtils.hpp @@ -19,6 +19,14 @@ inline bool isData(Channel c) { return static_cast<int>(c) >= 64; } /** Obtain a string name for channel. */ std::string name(Channel c); +/** + * @brief Get the channel ID from a name. + * + * @param name + * @return Channel + */ +Channel fromName(const std::string &name); + /** Obtain OpenCV type for channel. */ int type(Channel c); diff --git a/include/ftl/protocol/channels.hpp b/include/ftl/protocol/channels.hpp index 49a4e1763e41c230b868eaa4675348c2d8a818e7..e4bf601bdbc248c4f80d335f29b9e9ac9e041f3d 100644 --- a/include/ftl/protocol/channels.hpp +++ b/include/ftl/protocol/channels.hpp @@ -117,6 +117,24 @@ enum struct Channel : int { kPipeline_EnableMVMLS = 501, kPipeline_EnableAruco = 502, + /* Stereo video settings */ + kSGMResolution = 600, + kStereoRectify = 601, + kStereoRightPose = 602, + kStereoRectifyCubic = 603, + kVideoOffsetZ = 604, + kVideoSize = 605, + + /* Sender settings */ + kSenderLosslessFloat = 700, + kSenderLosslessColour = 701, + kSenderIFrames = 702, + kSenderCodecFloat = 703, + kSenderCodecColour = 704, + kSenderMaxBitrate = 705, + kSenderFloatBitrateScale = 706, + + /* Custom / user data channels */ kData = 2048, // Do not use kEndFrame = 2048, // Signify the last packet diff --git a/include/ftl/protocol/node.hpp b/include/ftl/protocol/node.hpp index b041836a304d87e385816862368d3b82a8fb67a3..be580adc0ae063c3285e8235f1c29ae17049befa 100644 --- a/include/ftl/protocol/node.hpp +++ b/include/ftl/protocol/node.hpp @@ -173,5 +173,7 @@ class Node { ftl::net::PeerPtr peer_; }; +using NodePtr = std::shared_ptr<Node>; + } // namespace protocol } // namespace ftl diff --git a/src/channelUtils.cpp b/src/channelUtils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..50dabb76826a38485a6934dabf0ecb7e43a18095 --- /dev/null +++ b/src/channelUtils.cpp @@ -0,0 +1,222 @@ +/** + * @file channelUtils.cpp + * @copyright Copyright (c) 2022 University of Turku, MIT License + * @author Nicolas Pope + */ + +#include <ftl/protocol/config.h> +#include <string> +#include <unordered_map> +#include <ftl/protocol/channelUtils.hpp> + +using ftl::protocol::Channel; + +#ifndef CV_8U +#define CV_CN_SHIFT 3 +#define CV_DEPTH_MAX (1 << CV_CN_SHIFT) + +#define CV_8U 0 +#define CV_8S 1 +#define CV_16U 2 +#define CV_16S 3 +#define CV_32S 4 +#define CV_32F 5 +#define CV_64F 6 +#define CV_16F 7 + +#define CV_MAT_DEPTH_MASK (CV_DEPTH_MAX - 1) +#define CV_MAT_DEPTH(flags) ((flags) & CV_MAT_DEPTH_MASK) + +#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT)) +#define CV_MAKE_TYPE CV_MAKETYPE + +#define CV_8UC1 CV_MAKETYPE(CV_8U,1) +#define CV_8UC2 CV_MAKETYPE(CV_8U,2) +#define CV_8UC3 CV_MAKETYPE(CV_8U,3) +#define CV_8UC4 CV_MAKETYPE(CV_8U,4) +#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n)) + +#define CV_8SC1 CV_MAKETYPE(CV_8S,1) +#define CV_8SC2 CV_MAKETYPE(CV_8S,2) +#define CV_8SC3 CV_MAKETYPE(CV_8S,3) +#define CV_8SC4 CV_MAKETYPE(CV_8S,4) +#define CV_8SC(n) CV_MAKETYPE(CV_8S,(n)) + +#define CV_16UC1 CV_MAKETYPE(CV_16U,1) +#define CV_16UC2 CV_MAKETYPE(CV_16U,2) +#define CV_16UC3 CV_MAKETYPE(CV_16U,3) +#define CV_16UC4 CV_MAKETYPE(CV_16U,4) +#define CV_16UC(n) CV_MAKETYPE(CV_16U,(n)) + +#define CV_16SC1 CV_MAKETYPE(CV_16S,1) +#define CV_16SC2 CV_MAKETYPE(CV_16S,2) +#define CV_16SC3 CV_MAKETYPE(CV_16S,3) +#define CV_16SC4 CV_MAKETYPE(CV_16S,4) +#define CV_16SC(n) CV_MAKETYPE(CV_16S,(n)) + +#define CV_32SC1 CV_MAKETYPE(CV_32S,1) +#define CV_32SC2 CV_MAKETYPE(CV_32S,2) +#define CV_32SC3 CV_MAKETYPE(CV_32S,3) +#define CV_32SC4 CV_MAKETYPE(CV_32S,4) +#define CV_32SC(n) CV_MAKETYPE(CV_32S,(n)) + +#define CV_32FC1 CV_MAKETYPE(CV_32F,1) +#define CV_32FC2 CV_MAKETYPE(CV_32F,2) +#define CV_32FC3 CV_MAKETYPE(CV_32F,3) +#define CV_32FC4 CV_MAKETYPE(CV_32F,4) +#define CV_32FC(n) CV_MAKETYPE(CV_32F,(n)) + +#define CV_64FC1 CV_MAKETYPE(CV_64F,1) +#define CV_64FC2 CV_MAKETYPE(CV_64F,2) +#define CV_64FC3 CV_MAKETYPE(CV_64F,3) +#define CV_64FC4 CV_MAKETYPE(CV_64F,4) +#define CV_64FC(n) CV_MAKETYPE(CV_64F,(n)) + +#define CV_16FC1 CV_MAKETYPE(CV_16F,1) +#define CV_16FC2 CV_MAKETYPE(CV_16F,2) +#define CV_16FC3 CV_MAKETYPE(CV_16F,3) +#define CV_16FC4 CV_MAKETYPE(CV_16F,4) +#define CV_16FC(n) CV_MAKETYPE(CV_16F,(n)) +#endif + +struct ChannelInfo { + const char *name; + int cvtype = -1; +}; + +/* Name and type lookup table for channels */ +static const std::unordered_map<Channel,ChannelInfo> info = { + {Channel::kColour, {"Left", CV_8UC4}}, + {Channel::kDepth, {"Depth", CV_32F}}, + {Channel::kRight, {"Right", CV_8UC4}}, + {Channel::kDepth2, {"Depth Right", CV_32F}}, + {Channel::kDeviation, {"Deviation", CV_32F}}, + {Channel::kNormals, {"Normals", CV_32FC4}}, + {Channel::kWeights, {"Weights", CV_32F}}, + {Channel::kConfidence, {"Confidence", CV_32F}}, + {Channel::kEnergyVector, {"Energy Vector", CV_32FC4}}, + {Channel::kFlow, {"Flow", CV_32F}}, + {Channel::kEnergy, {"Energy", CV_32F}}, + {Channel::kMask, {"Mask", CV_8U}}, + {Channel::kDensity, {"Density", CV_32F}}, + {Channel::kSupport1, {"Support1", CV_8UC4}}, + {Channel::kSupport2, {"Support2", CV_8UC4}}, + {Channel::kSegmentation, {"Segmentation", CV_8U}}, + {Channel::kNormals2, {"Normals Right", CV_32FC4}}, + {Channel::kUNUSED1, {"Unused", CV_8UC4}}, + {Channel::kDisparity, {"Disparity", CV_16S}}, + {Channel::kSmoothing, {"Smoothing", CV_32F}}, + {Channel::kUNUSED2, {"Unused", CV_8UC4}}, + {Channel::kOverlay, {"Overlay", CV_8UC4}}, + {Channel::kGroundTruth, {"Ground Truth", CV_32F}}, + + {Channel::kAudioMono, {"Audio (Mono)", -1}}, + {Channel::kAudioStereo, {"Audio (Stereo)", -1}}, + + {Channel::kConfiguration, {"Configuration", -1}}, + {Channel::kCalibration, {"Calibration", -1}}, + {Channel::kPose, {"Pose", -1}}, + {Channel::kCalibration2, {"CalibrationHR", -1}}, + {Channel::kMetaData, {"Meta Data", -1}}, + {Channel::kCapabilities, {"Capabilities", -1}}, + {Channel::kCalibrationData, {"CalibrationData", -1}}, + {Channel::kThumbnail, {"Thumbnail", -1}}, + {Channel::kOverlaySelect, {"OverlaySelect", -1}}, + {Channel::kStartTime, {"StartTime", -1}}, + {Channel::kUser, {"User", -1}}, + + {Channel::kBrightness, {"Brightness", -1}}, + {Channel::kContrast, {"Contrast", -1}}, + {Channel::kExposure, {"Exposure", -1}}, + {Channel::kGain, {"Gain", -1}}, + {Channel::kWhiteBalance, {"WhiteBalance", -1}}, + {Channel::kAutoExposure, {"AutoExposure", -1}}, + {Channel::kAutoWhiteBalance, {"AutoWhiteBalance", -1}}, + {Channel::kCameraTemperature, {"CameraTemperature", -1}}, + + {Channel::kRS2_LaserPower, {"RS2LaserPower", -1}}, + {Channel::kRS2_MinDistance, {"RS2MinDistance", -1}}, + {Channel::kRS2_MaxDistance, {"RS2MaxDistance", -1}}, + {Channel::kRS2_InterCamSync, {"RS2InterCamSync", -1}}, + {Channel::kRS2_PostSharpening, {"RS2PostSharpening", -1}}, + + {Channel::kRenderer_CameraType, {"RenderCameraType", -1}}, + {Channel::kRenderer_Visualisation, {"RenderVisualisation", -1}}, + {Channel::kRenderer_Engine, {"RenderEngine", -1}}, + {Channel::kRenderer_FPS, {"RenderFPS", -1}}, + {Channel::kRenderer_View, {"RenderView", -1}}, + {Channel::kRenderer_Channel, {"RenderChannel", -1}}, + {Channel::kRenderer_Opacity, {"RenderOpacity", -1}}, + {Channel::kRenderer_Sources, {"RenderSources", -1}}, + {Channel::kRenderer_Projection, {"RenderProjection", -1}}, + {Channel::kRenderer_Background, {"RenderBackground", -1}}, + {Channel::kRenderer_ShowBadColour, {"RenderShowBadColour", -1}}, + {Channel::kRenderer_CoolEffect, {"RenderCoolEffect", -1}}, + {Channel::kRenderer_EffectColour, {"RenderEffectColour", -1}}, + {Channel::kRenderer_ShowColourWeights, {"RenderShowColourWeights", -1}}, + {Channel::kRenderer_TriangleLimit, {"RenderTriangleLimit", -1}}, + {Channel::kRenderer_DisconDisparities, {"RenderDisconDisparities", -1}}, + {Channel::kRenderer_NormalWeightColour, {"RenderNormalWeightColour", -1}}, + {Channel::kRenderer_ChannelWeights, {"RenderChannelWeights", -1}}, + {Channel::kRenderer_AccumFunc, {"RenderAccumFunc", -1}}, + + {Channel::kSGMResolution, {"SGMResolution", -1}}, + {Channel::kStereoRectify, {"StereoRectify", -1}}, + {Channel::kStereoRightPose, {"StereoRightPose", -1}}, + {Channel::kStereoRectifyCubic, {"StereoRectifyCubic", -1}}, + {Channel::kVideoOffsetZ, {"VideoOffsetZ", -1}}, + {Channel::kVideoSize, {"VideoSize", -1}}, + + {Channel::kSenderLosslessFloat, {"SenderLosslessFloat", -1}}, + {Channel::kSenderLosslessColour, {"SenderLosslessColour", -1}}, + {Channel::kSenderIFrames, {"SenderIFrames", -1}}, + {Channel::kSenderCodecFloat, {"SenderCodecFloat", -1}}, + {Channel::kSenderCodecColour, {"SenderCodecColour", -1}}, + {Channel::kSenderMaxBitrate, {"SenderMaxBitrate", -1}}, + {Channel::kSenderFloatBitrateScale, {"SenderFloatBitrateScale", -1}}, + + {Channel::kData, {"Generic Data", -1}}, + {Channel::kFaces, {"Faces", -1}}, + {Channel::kShapes3D, {"Shapes 3D", -1}}, + {Channel::kMessages, {"Messages", -1}}, + {Channel::kTouch, {"Touch", -1}} +}; + +static std::unordered_map<std::string, Channel> indexNames() { + std::unordered_map<std::string, Channel> result; + for (const auto &i : info) { + result[std::string(i.second.name)] = i.first; + } + return result; +} + +static const std::unordered_map<std::string, Channel> nameIndex = indexNames(); + +std::string ftl::protocol::name(Channel c) { + if (c == Channel::kNone) return "None"; + auto i = info.find(c); + if (i != info.end()) { + return i->second.name; + } else { + return "Unknown"; + } +} + +Channel ftl::protocol::fromName(const std::string &name) { + auto i = nameIndex.find(name); + if (i != nameIndex.end()) { + return i->second; + } else { + return Channel::kNone; + } +} + +int ftl::protocol::type(Channel c) { + if (c == Channel::kNone) return -1; + auto i = info.find(c); + if (i != info.end()) { + return i->second.cvtype; + } else { + return -1; + } +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 17aed1cce0f2837757414c26eef0b13dddebcf95..5788d7966ae1d67db2ac76ba8430239e8c037ec4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -17,6 +17,16 @@ target_link_libraries(uri_unit beyond-protocol add_test(URIUnitTest uri_unit) +### Util ####################################################################### +add_executable(util_unit + $<TARGET_OBJECTS:CatchTest> + ./utils_unit.cpp) +target_include_directories(util_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include") +target_link_libraries(util_unit beyond-protocol + Threads::Threads ${OS_LIBS}) + +add_test(UtilUnitTest util_unit) + ### Handle Unit ################################################################ add_executable(handle_unit $<TARGET_OBJECTS:CatchTest> diff --git a/test/utils_unit.cpp b/test/utils_unit.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e2bc869f4a6bf0522a000427a3236874c6f28db7 --- /dev/null +++ b/test/utils_unit.cpp @@ -0,0 +1,19 @@ +#include "catch.hpp" +#include <ftl/protocol/channelUtils.hpp> + +using ftl::protocol::Channel; +using std::string; + +SCENARIO( "Channel names", "[utility]" ) { + GIVEN( "a valid channel name" ) { + REQUIRE( ftl::protocol::fromName("User") == Channel::kUser ); + } + + GIVEN( "an invalid channel name" ) { + REQUIRE( ftl::protocol::fromName("RandomWord") == Channel::kNone ); + } + + GIVEN( "a channel, get a name" ) { + REQUIRE( ftl::protocol::name(Channel::kUser) == "User" ); + } +} \ No newline at end of file