feat(record): add depth RVL recording to MCAP

This commit is contained in:
2026-03-11 21:15:25 +08:00
parent 782af9481c
commit 59ff8b79d9
15 changed files with 826 additions and 35 deletions
+92 -1
View File
@@ -97,6 +97,19 @@ namespace {
return static_cast<PixelFormat>(pixel_format_raw);
}
[[nodiscard]]
DepthUnit from_core_depth_unit(const cvmmap::DepthUnit unit) {
switch (unit) {
case cvmmap::DepthUnit::Millimeter:
return DepthUnit::Millimeter;
case cvmmap::DepthUnit::Meter:
return DepthUnit::Meter;
case cvmmap::DepthUnit::Unknown:
default:
return DepthUnit::Unknown;
}
}
[[nodiscard]]
std::expected<ModuleStatus, ParseError> validate_module_status(std::int32_t status_raw) {
switch (status_raw) {
@@ -119,6 +132,9 @@ namespace {
if (error.contains("version")) {
return ParseError::UnsupportedVersion;
}
if (error.contains("depth_unit")) {
return ParseError::InvalidDepthUnit;
}
if (error.contains("depth")) {
return ParseError::InvalidDepth;
}
@@ -145,6 +161,58 @@ namespace {
return converted;
}
[[nodiscard]]
FrameInfo from_core_frame_info(const cvmmap::frame_info_t &info) {
FrameInfo converted{};
converted.width = info.width;
converted.height = info.height;
converted.channels = info.channels;
converted.depth = static_cast<Depth>(info.depth);
converted.pixel_format = static_cast<PixelFormat>(info.pixel_format);
converted.buffer_size = info.buffer_size;
return converted;
}
[[nodiscard]]
std::size_t span_offset(
const std::span<const std::uint8_t> outer,
const std::span<const std::uint8_t> inner) {
if (inner.empty()) {
return 0;
}
return static_cast<std::size_t>(inner.data() - outer.data());
}
[[nodiscard]]
std::size_t payload_bytes_for(
const std::span<const std::uint8_t> payload_region,
const cvmmap::parsed_frame_metadata_t &metadata) {
std::size_t payload_bytes = metadata.left_plane.size();
const auto consider = [&](std::span<const std::uint8_t> plane) {
if (plane.empty()) {
return;
}
payload_bytes = std::max(
payload_bytes,
span_offset(payload_region, plane) + plane.size());
};
consider(metadata.depth_plane);
consider(metadata.confidence_plane);
return payload_bytes;
}
[[nodiscard]]
std::span<const std::uint8_t> translate_span(
const std::span<const std::uint8_t> source_payload,
const std::span<const std::uint8_t> destination_payload,
const std::span<const std::uint8_t> source_plane) {
if (source_plane.empty()) {
return {};
}
const auto offset = span_offset(source_payload, source_plane);
return destination_payload.subspan(offset, source_plane.size());
}
}
std::string_view to_string(ParseError error) {
@@ -159,6 +227,8 @@ std::string_view to_string(ParseError error) {
return "unsupported version";
case ParseError::InvalidDepth:
return "invalid depth";
case ParseError::InvalidDepthUnit:
return "invalid depth unit";
case ParseError::InvalidPixelFormat:
return "invalid pixel format";
case ParseError::InvalidModuleStatus:
@@ -344,9 +414,22 @@ std::expected<ValidatedShmView, ParseError> validate_shm_region(std::span<const
return std::unexpected(map_core_parser_error(metadata_result.error()));
}
const auto payload_region = shm_region.subspan(kShmPayloadOffset);
const auto payload_bytes = payload_bytes_for(payload_region, *metadata_result);
return ValidatedShmView{
.metadata = from_core_metadata(metadata_result->normalized_metadata),
.payload = metadata_result->left_plane};
.depth_unit = from_core_depth_unit(metadata_result->depth_unit),
.payload = payload_region.first(payload_bytes),
.left = metadata_result->left_plane,
.depth_info = metadata_result->depth_info
? std::optional<FrameInfo>(from_core_frame_info(*metadata_result->depth_info))
: std::nullopt,
.depth = metadata_result->depth_plane,
.confidence_info = metadata_result->confidence_info
? std::optional<FrameInfo>(from_core_frame_info(*metadata_result->confidence_info))
: std::nullopt,
.confidence = metadata_result->confidence_plane};
}
std::expected<CoherentSnapshot, SnapshotError> read_coherent_snapshot(
@@ -378,8 +461,16 @@ std::expected<CoherentSnapshot, SnapshotError> read_coherent_snapshot(
return std::unexpected(SnapshotError::TornRead);
}
const auto copied_payload = std::span<const std::uint8_t>(destination.data(), first->payload.size());
return CoherentSnapshot{
.metadata = first->metadata,
.depth_unit = first->depth_unit,
.left = translate_span(first->payload, copied_payload, first->left),
.depth_info = first->depth_info,
.depth = translate_span(first->payload, copied_payload, first->depth),
.confidence_info = first->confidence_info,
.confidence = translate_span(first->payload, copied_payload, first->confidence),
.bytes_copied = first->payload.size()};
}