fix(record): fall back to millimeter for unknown depth unit

This commit is contained in:
2026-03-12 11:00:25 +08:00
parent 59ff8b79d9
commit a21d4b6769
3 changed files with 81 additions and 26 deletions
+21 -14
View File
@@ -39,6 +39,14 @@ struct EncodedDepthPayload {
std::vector<std::uint8_t> bytes{};
};
[[nodiscard]]
ipc::DepthUnit normalize_depth_source_unit(ipc::DepthUnit unit) {
if (unit == ipc::DepthUnit::Unknown) {
return ipc::DepthUnit::Millimeter;
}
return unit;
}
[[nodiscard]]
mcap::Compression to_mcap_compression(McapCompression compression) {
switch (compression) {
@@ -227,7 +235,7 @@ std::expected<std::vector<std::uint8_t>, std::string> decoder_config_to_annexb(
[[nodiscard]]
bool can_encode_lossless_u16_mm(const RawDepthMapView &depth_map) {
if (depth_map.source_unit != ipc::DepthUnit::Millimeter) {
if (normalize_depth_source_unit(depth_map.source_unit) != ipc::DepthUnit::Millimeter) {
return false;
}
@@ -249,18 +257,16 @@ bool can_encode_lossless_u16_mm(const RawDepthMapView &depth_map) {
[[nodiscard]]
std::expected<EncodedDepthPayload, std::string> encode_depth_payload(const RawDepthMapView &depth_map) {
const auto pixel_count = static_cast<std::size_t>(depth_map.width) * static_cast<std::size_t>(depth_map.height);
const auto source_unit = normalize_depth_source_unit(depth_map.source_unit);
if (depth_map.width == 0 || depth_map.height == 0) {
return std::unexpected("depth map dimensions must be non-zero");
}
if (pixel_count != depth_map.pixels.size()) {
return std::unexpected("depth map dimensions do not match the pixel buffer");
}
if (depth_map.source_unit == ipc::DepthUnit::Unknown) {
return std::unexpected("depth source unit is unknown");
}
try {
if (can_encode_lossless_u16_mm(depth_map)) {
if (source_unit == ipc::DepthUnit::Millimeter && can_encode_lossless_u16_mm(depth_map)) {
std::vector<std::uint16_t> pixels(pixel_count, 0);
for (std::size_t index = 0; index < pixel_count; ++index) {
const float sample = depth_map.pixels[index];
@@ -277,14 +283,14 @@ std::expected<EncodedDepthPayload, std::string> encode_depth_payload(const RawDe
};
}
std::vector<float> depth_m(pixel_count, std::numeric_limits<float>::quiet_NaN());
float finite_max_m = 0.0f;
for (std::size_t index = 0; index < pixel_count; ++index) {
float sample = depth_map.pixels[index];
if (depth_map.source_unit == ipc::DepthUnit::Millimeter && std::isfinite(sample)) {
sample *= 0.001f;
}
if (!std::isfinite(sample) || sample <= 0.0f) {
std::vector<float> depth_m(pixel_count, std::numeric_limits<float>::quiet_NaN());
float finite_max_m = 0.0f;
for (std::size_t index = 0; index < pixel_count; ++index) {
float sample = depth_map.pixels[index];
if (source_unit == ipc::DepthUnit::Millimeter && std::isfinite(sample)) {
sample *= 0.001f;
}
if (!std::isfinite(sample) || sample <= 0.0f) {
continue;
}
@@ -443,6 +449,7 @@ std::expected<void, std::string> McapRecordSink::write_depth_map(const RawDepthM
if (state_ == nullptr) {
return std::unexpected("MCAP sink is not open");
}
const auto source_unit = normalize_depth_source_unit(depth_map.source_unit);
auto encoded = encode_depth_payload(depth_map);
if (!encoded) {
@@ -454,7 +461,7 @@ std::expected<void, std::string> McapRecordSink::write_depth_map(const RawDepthM
message.set_frame_id(state_->frame_id);
message.set_width(depth_map.width);
message.set_height(depth_map.height);
message.set_source_unit(to_proto_depth_unit(depth_map.source_unit));
message.set_source_unit(to_proto_depth_unit(source_unit));
message.set_storage_unit(to_proto_storage_unit(encoded->storage_unit));
message.set_encoding(to_proto_depth_encoding(encoded->encoding));
message.set_data(