Skip to main content

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}