arcly-stream 0.1.6

An open-extensible live-media streaming kernel: lock-free zero-copy frame fan-out, instant-start GOP cache, a pluggable multi-protocol ingestion layer (RTMP, RTSP, SRT, WHIP/WHEP shipped), and a feature-gated pure-Rust media plane (MPEG-TS/HLS/fMP4) — runtime, config, and metrics free.
Documentation
//! Codec-agnostic parsing contracts shared by every codec module.

use crate::CodecId;
use bytes::Bytes;

/// Video metadata extracted from a parameter set / sequence header.
///
/// Fields are `0` when unknown — matching the convention in
/// [`StreamMetadata`](crate::StreamMetadata).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct VideoParams {
    /// Coded luma width in pixels (after any conformance cropping).
    pub width: u32,
    /// Coded luma height in pixels (after any conformance cropping).
    pub height: u32,
    /// Codec profile (`profile_idc` / `seq_profile`).
    pub profile: u8,
    /// Codec level (e.g. `general_level_idc`, `seq_level_idx`).
    pub level: u8,
    /// Tier (HEVC/VVC `general_tier_flag`; `0` elsewhere).
    pub tier: u8,
    /// Luma bit depth (`8`, `10`, `12`); `0` when not parsed.
    pub bit_depth: u8,
}

/// Decoder configuration handed to a [`Muxer`](crate::packager::Muxer) so it can
/// build an fMP4 init segment and the HLS `CODECS` attribute.
#[derive(Debug, Clone)]
pub struct CodecConfig {
    /// Which codec this configuration describes.
    pub codec: CodecId,
    /// Parsed video parameters.
    pub params: VideoParams,
    /// Raw decoder-configuration record bytes (`avcC`/`hvcC`/`av1C`/`vvcC`), or
    /// the codec's config access unit when no boxed record is available.
    pub config_record: Bytes,
}

/// One parser per codec. Pure, allocation-light, `&[u8]`-in.
///
/// The engine never calls these directly — protocol handlers do, at the ingest
/// boundary, to classify frames ([`FrameType`](crate::FrameType)) and populate
/// metadata. The kernel's GOP cache, segmenter, eviction, and recorder all key
/// on [`is_keyframe`](crate::MediaFrame::is_keyframe), so a correct
/// [`is_random_access_point`] is all that's needed to make a codec "work".
///
/// [`is_random_access_point`]: CodecParser::is_random_access_point
pub trait CodecParser {
    /// The codec this parser handles.
    const CODEC: CodecId;

    /// Parse the parameter set(s) / sequence header into [`VideoParams`].
    /// Returns `None` if no usable header is present or it cannot be decoded.
    fn parse_config(data: &[u8]) -> Option<VideoParams>;

    /// Whether this access unit is a random-access point (IDR/CRA/KEY_FRAME) —
    /// the signal the engine anchors GOP caching and segmentation on.
    fn is_random_access_point(data: &[u8]) -> bool;

    /// Whether this access unit carries decoder configuration (parameter sets /
    /// sequence header) that should be cached for late joiners.
    fn carries_config(data: &[u8]) -> bool;

    /// The HLS `CODECS` attribute for these parameters
    /// (e.g. `"hvc1.1.6.L93.B0"`, `"av01.0.04M.08"`).
    fn hls_codec_string(params: &VideoParams) -> String;
}