seyd_core/channels.rs
1// Copyright 2026 Anton Gravestam
2// SPDX-License-Identifier: Apache-2.0
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(rename_all = "kebab-case")]
7pub enum ChannelKind {
8 Video,
9 Sensor,
10 Command,
11}
12
13/// A declared channel; serialises to the `{id, kind, name, codec, fps}` shape
14/// used by `welcome` and `announce`, plus `layers` where the publisher offers
15/// more than one encoding of the same picture (ADR 0008).
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub struct ChannelSpec {
18 pub id: u8,
19 pub kind: ChannelKind,
20 pub name: String,
21 /// WebCodecs identifier, carried to the pilot's decoder untouched. With
22 /// simulcast it must admit the *highest* layer: the pilot configures once,
23 /// and `avc1.42001f` is Baseline level 3.1, whose 3600-macroblock ceiling is
24 /// exactly 1280x720.
25 pub codec: String,
26 #[serde(default)]
27 pub fps: u32,
28 /// Simulcast layers, lowest first. Empty or one-element means a single
29 /// stream and no selection ever happens — the pre-simulcast behaviour.
30 #[serde(default, skip_serializing_if = "Vec::is_empty")]
31 pub layers: Vec<seyd_qos::simulcast::VideoLayer>,
32 /// The most a video channel's publisher can encode, in kbps; 0 = no limit
33 /// of its own. When it is below the QoS profile's ceiling, the rate
34 /// controller's whole range — ceiling, floor, backlog budget and every
35 /// `video-config` request — is scaled to it, so Seyd never asks for a
36 /// bitrate the encoder cannot produce. Local to the agent: not announced.
37 #[serde(default, skip_serializing)]
38 pub max_bitrate_kbps: u32,
39}