Files
cvmmap-streamer/include/cvmmap_streamer/ipc/contracts.hpp
T
crosstyan 56e874ab6d feat(downstream): add cvmmap downstream runtime implementation
This commit introduces the full downstream runtime implementation needed to ingest, transform, and publish streams.

It preserves the original upstream request boundary by packaging the entire cvmmap-streamer module (build config, public API, protocol and IPC glue, and simulator/tester entrypoints) in one coherent core unit.

Keeping this group isolated enables reviewers to validate runtime behavior and correctness without mixing test evidence or process documentation changes.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-05 20:31:58 +08:00

182 lines
4.8 KiB
C++

#pragma once
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <expected>
#include <functional>
#include <span>
#include <string_view>
namespace cvmmap_streamer::ipc {
constexpr std::size_t kLabelLenMax = 24;
constexpr std::size_t kShmPayloadOffset = 256;
constexpr std::uint8_t kFrameTopicMagic = 0x7d;
constexpr std::uint8_t kModuleStatusMagic = 0x5a;
constexpr std::uint8_t kControlRequestMagic = 0x3c;
constexpr std::uint8_t kControlResponseMagic = 0x3d;
constexpr std::uint8_t kVersionMajor = 1;
constexpr std::uint8_t kVersionMinor = 0;
constexpr std::array<std::uint8_t, 8> kFrameMetadataMagic{
'C', 'V', '-', 'M', 'M', 'A', 'P', '\0'};
enum class Depth : std::uint8_t {
U8 = 0,
S8 = 1,
U16 = 2,
S16 = 3,
S32 = 4,
F32 = 5,
F64 = 6,
F16 = 7,
};
enum class PixelFormat : std::uint8_t {
RGB = 0,
BGR,
RGBA,
BGRA,
GRAY,
YUV,
YUYV,
};
enum class ModuleStatus : std::int32_t {
Online = 0xa1,
Offline = 0xa0,
StreamReset = 0xb0,
};
enum class ParseError {
BufferTooSmall,
InvalidSize,
InvalidMagic,
UnsupportedVersion,
InvalidDepth,
InvalidPixelFormat,
InvalidModuleStatus,
PayloadLengthMismatch,
};
enum class SnapshotError {
InvalidShmLayout,
DestinationTooSmall,
TornRead,
};
std::string_view to_string(ParseError error);
std::string_view to_string(SnapshotError error);
struct FrameInfo {
std::uint16_t width;
std::uint16_t height;
std::uint8_t channels;
Depth depth;
PixelFormat pixel_format;
std::uint32_t buffer_size;
};
struct FrameMetadata {
std::array<std::uint8_t, kFrameMetadataMagic.size()> magic;
std::uint8_t versions_major;
std::uint8_t versions_minor;
std::uint32_t frame_count;
std::uint64_t timestamp_ns;
FrameInfo info;
};
struct SyncMessage {
std::uint8_t versions_major;
std::uint8_t versions_minor;
std::uint32_t frame_count;
std::uint64_t timestamp_ns;
std::array<std::uint8_t, kLabelLenMax> label_bytes;
[[nodiscard]]
std::string_view label() const {
const auto end = std::find(label_bytes.begin(), label_bytes.end(), static_cast<std::uint8_t>(0));
return std::string_view{
reinterpret_cast<const char *>(label_bytes.data()),
static_cast<std::size_t>(std::distance(label_bytes.begin(), end))};
}
};
struct ModuleStatusMessage {
std::uint8_t versions_major;
std::uint8_t versions_minor;
ModuleStatus module_status;
std::array<std::uint8_t, kLabelLenMax> label_bytes;
[[nodiscard]]
std::string_view label() const {
const auto end = std::find(label_bytes.begin(), label_bytes.end(), static_cast<std::uint8_t>(0));
return std::string_view{
reinterpret_cast<const char *>(label_bytes.data()),
static_cast<std::size_t>(std::distance(label_bytes.begin(), end))};
}
};
struct ControlRequestMessage {
std::uint8_t versions_major;
std::uint8_t versions_minor;
std::int32_t command_id;
std::array<std::uint8_t, kLabelLenMax> label_bytes;
std::span<const std::uint8_t> request_payload;
[[nodiscard]]
std::string_view label() const {
const auto end = std::find(label_bytes.begin(), label_bytes.end(), static_cast<std::uint8_t>(0));
return std::string_view{
reinterpret_cast<const char *>(label_bytes.data()),
static_cast<std::size_t>(std::distance(label_bytes.begin(), end))};
}
};
struct ControlResponseMessage {
std::uint8_t versions_major;
std::uint8_t versions_minor;
std::int32_t command_id;
std::int32_t response_code;
std::array<std::uint8_t, kLabelLenMax> label_bytes;
std::span<const std::uint8_t> response_payload;
[[nodiscard]]
std::string_view label() const {
const auto end = std::find(label_bytes.begin(), label_bytes.end(), static_cast<std::uint8_t>(0));
return std::string_view{
reinterpret_cast<const char *>(label_bytes.data()),
static_cast<std::size_t>(std::distance(label_bytes.begin(), end))};
}
};
struct ValidatedShmView {
FrameMetadata metadata;
std::span<const std::uint8_t> payload;
};
struct CoherentSnapshot {
FrameMetadata metadata;
std::size_t bytes_copied;
};
using SnapshotReadHook = std::function<void()>;
std::expected<FrameMetadata, ParseError> parse_frame_metadata(std::span<const std::uint8_t> bytes);
std::expected<SyncMessage, ParseError> parse_sync_message(std::span<const std::uint8_t> bytes);
std::expected<ModuleStatusMessage, ParseError> parse_module_status_message(std::span<const std::uint8_t> bytes);
std::expected<ControlRequestMessage, ParseError> parse_control_request_message(std::span<const std::uint8_t> bytes);
std::expected<ControlResponseMessage, ParseError> parse_control_response_message(std::span<const std::uint8_t> bytes);
std::expected<ValidatedShmView, ParseError> validate_shm_region(std::span<const std::uint8_t> shm_region);
std::expected<CoherentSnapshot, SnapshotError> read_coherent_snapshot(
std::span<const std::uint8_t> shm_region,
std::span<std::uint8_t> destination,
const SnapshotReadHook &before_second_metadata_read = {});
}