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

Merge branch 'feature/msgpack-codec' into 'main'

Add msgpack codec helpers

See merge request beyondaka/beyond-protocol!47
parents 63164b1c 268ac1e4
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.
Please register or to comment