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>
This commit is contained in:
2026-03-05 20:31:58 +08:00
commit 56e874ab6d
27 changed files with 8483 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include <cstddef>
#include <string_view>
namespace cvmmap_streamer {
void print_help(std::string_view executable);
bool has_help_flag(int argc, char **argv);
std::size_t sample_ipc_payload_size();
void pipeline_tick();
void protocol_step();
}
@@ -0,0 +1,84 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <expected>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
namespace cvmmap_streamer {
enum class CodecType {
H264,
H265,
};
enum class RunMode {
Pipeline,
Ingest,
};
enum class RtmpMode {
Enhanced,
Domestic,
};
struct InputConfig {
std::string shm_name{"cvmmap_default"};
std::string zmq_endpoint{"ipc:///tmp/cvmmap_default"};
};
struct RtmpOutputConfig {
bool enabled{false};
std::vector<std::string> urls{};
RtmpMode mode{RtmpMode::Enhanced};
};
struct RtpOutputConfig {
bool enabled{false};
std::optional<std::string> endpoint{std::nullopt};
std::optional<std::string> host{std::nullopt};
std::optional<std::uint16_t> port{std::nullopt};
std::uint8_t payload_type{96};
std::optional<std::string> sdp_path{std::nullopt};
};
struct OutputsConfig {
RtmpOutputConfig rtmp{};
RtpOutputConfig rtp{};
};
struct LatencyConfig {
std::size_t queue_size{1};
std::uint32_t gop{30};
std::uint32_t b_frames{0};
bool realtime_sync{true};
bool force_idr_on_reset{true};
std::uint32_t ingest_max_frames{0};
std::uint32_t ingest_idle_timeout_ms{1000};
std::uint32_t ingest_consumer_delay_ms{0};
std::uint32_t snapshot_copy_delay_us{0};
std::uint32_t emit_stall_ms{0};
};
struct RuntimeConfig {
InputConfig input{};
RunMode run_mode{RunMode::Pipeline};
CodecType codec{CodecType::H264};
OutputsConfig outputs{};
LatencyConfig latency{};
static RuntimeConfig defaults();
};
std::string_view to_string(CodecType codec);
std::string_view to_string(RunMode mode);
std::string_view to_string(RtmpMode mode);
std::expected<RuntimeConfig, std::string> parse_runtime_config(int argc, char **argv);
std::expected<void, std::string> validate_runtime_config(const RuntimeConfig &config);
std::string summarize_runtime_config(const RuntimeConfig &config);
}
+181
View File
@@ -0,0 +1,181 @@
#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 = {});
}
@@ -0,0 +1,40 @@
#pragma once
#include <cstdint>
#include <deque>
#include <vector>
namespace cvmmap_streamer::metrics {
struct LatencySummary {
std::uint64_t samples{0};
std::uint64_t min_us{0};
std::uint64_t max_us{0};
std::uint64_t avg_us{0};
std::uint64_t p50_us{0};
std::uint64_t p95_us{0};
std::uint64_t p99_us{0};
};
class IngestEmitLatencyTracker {
public:
void note_ingest();
void note_emit();
void note_emit_stall();
[[nodiscard]]
std::uint64_t emit_stall_events() const;
[[nodiscard]]
std::uint64_t pending_frames() const;
[[nodiscard]]
LatencySummary summarize() const;
private:
std::deque<std::uint64_t> ingest_queue_ns_{};
std::vector<std::uint64_t> samples_us_{};
std::uint64_t emit_stall_events_{0};
};
}
@@ -0,0 +1,84 @@
#pragma once
#include "cvmmap_streamer/config/runtime_config.hpp"
#include <chrono>
#include <cstdint>
#include <expected>
#include <span>
#include <string>
#include <string_view>
#include <vector>
namespace cvmmap_streamer::protocol {
struct RtmpPublisherStats {
std::uint64_t access_units{0};
std::uint64_t access_unit_bytes{0};
std::uint64_t video_messages{0};
std::uint64_t bytes_sent{0};
std::uint64_t send_errors{0};
std::uint64_t publish_failures{0};
std::uint64_t reconnect_attempts{0};
std::uint64_t reconnect_successes{0};
std::uint64_t reconnect_failures{0};
};
class RtmpPublisher {
public:
RtmpPublisher() = default;
~RtmpPublisher();
RtmpPublisher(const RtmpPublisher &) = delete;
RtmpPublisher &operator=(const RtmpPublisher &) = delete;
RtmpPublisher(RtmpPublisher &&other) noexcept;
RtmpPublisher &operator=(RtmpPublisher &&other) noexcept;
[[nodiscard]]
static std::expected<RtmpPublisher, std::string> create(const RuntimeConfig &config);
[[nodiscard]]
std::expected<void, std::string> publish_access_unit(std::span<const std::uint8_t> access_unit, std::uint64_t pts_ns);
[[nodiscard]]
const RtmpPublisherStats &stats() const;
void on_stream_reset();
void log_metrics() const;
private:
struct Session {
std::string original_url{};
std::string host{};
std::uint16_t port{1935};
std::string app{};
std::string stream{};
std::string tc_url{};
int socket_fd{-1};
std::uint32_t out_chunk_size{128};
std::uint32_t stream_id{1};
bool sequence_header_sent{false};
std::uint32_t reconnect_backoff_ms{250};
std::uint32_t consecutive_reconnect_failures{0};
std::chrono::steady_clock::time_point reconnect_due_at{};
bool in_cooldown{false};
};
[[nodiscard]]
std::expected<void, std::string> connect_session(Session &session);
void schedule_reconnect(Session &session, std::string_view reason, bool startup_path);
void close_session(Session &session);
CodecType codec_{CodecType::H264};
RtmpMode mode_{RtmpMode::Enhanced};
std::vector<Session> sessions_{};
RtmpPublisherStats stats_{};
bool had_successful_video_message_{false};
bool warned_all_sessions_closed_{false};
};
}
@@ -0,0 +1,67 @@
#pragma once
#include "cvmmap_streamer/config/runtime_config.hpp"
#include <cstdint>
#include <expected>
#include <span>
#include <string>
#include <string_view>
#include <sys/socket.h>
namespace cvmmap_streamer::protocol {
struct RtpPublisherStats {
std::uint64_t access_units{0};
std::uint64_t access_unit_bytes{0};
std::uint64_t packets_sent{0};
std::uint64_t packets_dropped{0};
std::uint64_t bytes_sent{0};
std::uint64_t send_errors{0};
};
class UdpRtpPublisher {
public:
UdpRtpPublisher() = default;
~UdpRtpPublisher();
UdpRtpPublisher(const UdpRtpPublisher &) = delete;
UdpRtpPublisher &operator=(const UdpRtpPublisher &) = delete;
UdpRtpPublisher(UdpRtpPublisher &&other) noexcept;
UdpRtpPublisher &operator=(UdpRtpPublisher &&other) noexcept;
[[nodiscard]]
static std::expected<UdpRtpPublisher, std::string> create(const RuntimeConfig &config);
void publish_access_unit(std::span<const std::uint8_t> access_unit, std::uint64_t pts_ns);
[[nodiscard]]
const RtpPublisherStats &stats() const;
[[nodiscard]]
std::string_view sdp_path() const;
[[nodiscard]]
std::string_view destination() const;
void log_metrics() const;
private:
int socket_fd_{-1};
std::string destination_host_{};
std::string destination_ip_{};
std::uint16_t destination_port_{0};
std::uint8_t payload_type_{96};
CodecType codec_{CodecType::H264};
std::uint16_t sequence_{0};
std::uint32_t ssrc_{0};
std::string sdp_path_{};
RtpPublisherStats stats_{};
sockaddr_storage endpoint_addr_{};
socklen_t endpoint_addr_len_{0};
};
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <cstdint>
#include <expected>
#include <optional>
#include <string>
#include "cvmmap_streamer/ipc/contracts.hpp"
namespace cvmmap_streamer::sim {
struct RuntimeConfig {
std::uint32_t frames{360};
std::uint32_t fps{60};
std::uint16_t width{64};
std::uint16_t height{48};
std::optional<std::uint32_t> emit_reset_at{};
std::optional<std::uint32_t> emit_reset_every{};
std::optional<std::uint32_t> switch_format_at{};
std::optional<std::uint16_t> switch_width{};
std::optional<std::uint16_t> switch_height{};
std::string label{"sim"};
std::string shm_name{"cvmmap_sim"};
std::string zmq_endpoint{"ipc:///tmp/cvmmap_sim"};
std::uint8_t channels{3};
ipc::Depth depth{ipc::Depth::U8};
ipc::PixelFormat pixel_format{ipc::PixelFormat::BGR};
[[nodiscard]]
std::uint32_t payload_size_bytes() const;
};
std::expected<RuntimeConfig, std::string> parse_runtime_config(int argc, char **argv);
void print_help();
}
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#include <cstdint>
#include <span>
#include <string_view>
#include "cvmmap_streamer/ipc/contracts.hpp"
namespace cvmmap_streamer::sim {
constexpr std::size_t kSyncMessageBytes = 48;
constexpr std::size_t kModuleStatusMessageBytes = 32;
void write_frame_metadata(
std::span<std::uint8_t> metadata,
const ipc::FrameInfo &info,
std::uint32_t frame_count,
std::uint64_t timestamp_ns);
void write_sync_message(
std::span<std::uint8_t> out,
std::string_view label,
std::uint32_t frame_count,
std::uint64_t timestamp_ns);
void write_module_status_message(
std::span<std::uint8_t> out,
std::string_view label,
ipc::ModuleStatus status);
void write_deterministic_payload(
std::span<std::uint8_t> out,
std::uint32_t frame_count,
std::uint16_t width,
std::uint16_t height,
std::uint8_t channels);
}