Skip to content
Snippets Groups Projects
Commit 268ac1e4 authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Add msgpack codec helpers

parent 63164b1c
No related branches found
No related tags found
No related merge requests found
......@@ -196,6 +196,7 @@ add_library(beyond-protocol STATIC
src/service.cpp
src/codecs/golomb.cpp
src/codecs/h264.cpp
src/codecs/data.cpp
)
target_include_directories(beyond-protocol PUBLIC
......
#pragma once
#include <vector>
#include <string>
#include <tuple>
#include <cstdint>
#include <ftl/data/camera.hpp>
#include <ftl/protocol/channels.hpp>
namespace ftl {
namespace data {
using Pose = std::vector<double>;
using StereoPose = std::tuple<Pose, Pose>;
using Intrinsics = std::tuple<ftl::data::Camera, int, int>;
}
namespace codec {
template <typename T>
void pack(const T &v, std::vector<uint8_t> &out);
template <typename T>
T unpack(const std::vector<uint8_t> &in);
}
}
#pragma once
#include <msgpack.hpp>
#include <ftl/codec/data.hpp>
#include <ftl/utility/vectorbuffer.hpp>
template <typename T>
void ftl::codec::pack(const T &v, std::vector<uint8_t> &out) {
out.resize(0);
ftl::util::FTLVectorBuffer buf(out);
msgpack::pack(buf, v);
}
template <typename T>
T ftl::codec::unpack(const std::vector<uint8_t> &in) {
auto unpacked = msgpack::unpack((const char*)in.data(), in.size());
T t;
unpacked.get().convert<T>(t);
return t;
}
#pragma once
namespace ftl {
namespace data {
/**
* All properties associated with cameras. This structure is designed to
* operate on CPU and GPU.
*/
struct Camera {
float fx; // Focal length X
float fy; // Focal length Y (usually same as fx)
float cx; // Principle point Y
float cy; // Principle point Y
unsigned int width; // Pixel width
unsigned int height; // Pixel height
float minDepth; // Near clip in meters
float maxDepth; // Far clip in meters
float baseline; // For stereo pair
float doffs; // Disparity offset
};
} // namespace data
} // namespace ftl
#pragma once
namespace ftl {
namespace data {
/**
* To be added to the capabilities channel to indicate what the source device
* is capable of. These properties should be features of the source that
* cannot be determined by simply checking for channels, and may include
* status information about processing that has been performed.
*/
enum class Capability : int {
MOVABLE = 0, // Is a pose controllable camera
ACTIVE, // An active depth sensor
VIDEO, // Is video and not just static
ADJUSTABLE, // Camera properties can be changed (exposure etc)
VIRTUAL, // Is not a physical camera
TOUCH, // Touch related feedback supported
VR, // Is a VR device, so provides own active pose etc
LIVE, // Live, not recorded (removed from ftl file sources)
FUSED, // Reconstruction has been performed
STREAMED, // Means it came from a stream and not device
EQUI_RECT, // 360 rendered (Equirectangular Render)
STEREO // Side-by-side stereo render
};
} // namespace data
} // namespace ftl
/**
* @file vectorbuffer.hpp
* @copyright Copyright (c) 2020 University of Turku, MIT License
* @author Nicolas Pope
*/
#pragma once
#include <vector>
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) {}
inline void write(const char *data, std::size_t size) {
vector_.insert(vector_.end(), (const unsigned char*)data, (const unsigned char*)data+size);
}
private:
std::vector<unsigned char> &vector_;
};
} // namespace util
} // namespace ftl
#include <ftl/codec/msgpack.hpp>
using ftl::codec::pack;
using ftl::codec::unpack;
struct CameraMSGPACK : public ftl::data::Camera {
MSGPACK_DEFINE(fx, fy, cx, cy, width, height, minDepth, maxDepth, baseline, doffs);
};
// Instantiations supported without the msgpack.hpp header
template void pack<int>(const int &v, std::vector<uint8_t> &out);
template void pack<float>(const float &v, std::vector<uint8_t> &out);
template void pack<std::string>(const std::string &v, std::vector<uint8_t> &out);
template void pack<double>(const double &v, std::vector<uint8_t> &out);
template void pack<std::vector<float>>(const std::vector<float> &v, std::vector<uint8_t> &out);
template void pack<ftl::data::Pose>(const ftl::data::Pose &v, std::vector<uint8_t> &out);
template void pack<std::vector<int>>(const std::vector<int> &v, std::vector<uint8_t> &out);
template void pack<std::vector<std::string>>(const std::vector<std::string> &v, std::vector<uint8_t> &out);
template void pack<ftl::data::StereoPose>(const ftl::data::StereoPose &v, std::vector<uint8_t> &out);
template <> void ftl::codec::pack(const ftl::data::Intrinsics &v, std::vector<uint8_t> &out) {
std::tuple<CameraMSGPACK, int, int> data;
reinterpret_cast<ftl::data::Camera&>(std::get<0>(data)) = std::get<0>(v);
std::get<1>(data) = std::get<1>(v);
std::get<2>(data) = std::get<2>(v);
pack(data, out);
}
template void pack<ftl::data::Intrinsics>(const ftl::data::Intrinsics &v, std::vector<uint8_t> &out);
template int unpack<int>(const std::vector<uint8_t> &in);
template float unpack<float>(const std::vector<uint8_t> &in);
template std::string unpack<std::string>(const std::vector<uint8_t> &in);
template double unpack<double>(const std::vector<uint8_t> &in);
template std::vector<float> unpack<std::vector<float>>(const std::vector<uint8_t> &in);
template ftl::data::Pose unpack<ftl::data::Pose>(const std::vector<uint8_t> &in);
template std::vector<int> unpack<std::vector<int>>(const std::vector<uint8_t> &in);
template std::vector<std::string> unpack<std::vector<std::string>>(const std::vector<uint8_t> &in);
template ftl::data::StereoPose unpack<ftl::data::StereoPose>(const std::vector<uint8_t> &in);
template <> ftl::data::Intrinsics ftl::codec::unpack(const std::vector<uint8_t> &in) {
auto data = unpack<std::tuple<CameraMSGPACK, int, int>>(in);
return data;
}
template ftl::data::Intrinsics unpack<ftl::data::Intrinsics>(const std::vector<uint8_t> &in);
......@@ -151,3 +151,14 @@ target_link_libraries(rpc_integration beyond-protocol
${URIPARSER_LIBRARIES})
add_test(RPCIntegrationTest rpc_integration)
### Data Codec Unit ############################################################
add_executable(datacodec_unit
$<TARGET_OBJECTS:CatchTestFTL>
./datacodec.cpp)
target_include_directories(datacodec_unit PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include")
target_link_libraries(datacodec_unit beyond-protocol
Threads::Threads ${OS_LIBS}
${URIPARSER_LIBRARIES})
add_test(DataCodecTest datacodec_unit)
#include "catch.hpp"
#include <ftl/codec/data.hpp>
SCENARIO( "Intrinsics pack/unpack" ) {
GIVEN( "a valid instrincs object it packs" ) {
ftl::data::Intrinsics intrin;
std::get<0>(intrin).fx = 10.0f;
std::vector<uint8_t> buffer;
ftl::codec::pack(intrin, buffer);
REQUIRE(buffer.size() > 0);
auto result = ftl::codec::unpack<ftl::data::Intrinsics>(buffer);
REQUIRE(std::get<0>(result).fx == 10.0f);
}
}
SCENARIO( "Vector of strings pack/unpack" ) {
GIVEN( "a valid instrincs object it packs" ) {
std::vector<std::string> data = {"hello", "world"};
std::vector<uint8_t> buffer;
ftl::codec::pack(data, buffer);
REQUIRE(buffer.size() > 0);
auto result = ftl::codec::unpack<std::vector<std::string>>(buffer);
REQUIRE(result[0] == "hello");
REQUIRE(result[1] == "world");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment