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
//! Transcoding & adaptive-bitrate contracts.
//!
//! The actual codec work needs native encoders (FFmpeg/GStreamer, NVENC/QSV via
//! [`HwAccelBackend`](crate::HwAccelBackend)) and is intentionally **not** shipped
//! here. This module defines the seams: a [`Transcoder`] turns one input frame
//! into zero or more output frames, and a [`RenditionSpec`] describes one rung
//! of an ABR ladder. A pipeline drives a [`Transcoder`] from a
//! [`Subscription`](crate::Subscription) and republishes each output rendition.

use crate::frame::CodecId;
use crate::{MediaFrame, Result};
use async_trait::async_trait;

/// One target rendition in an adaptive-bitrate ladder.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RenditionSpec {
    /// Human label / variant id (e.g. `"720p"`).
    pub name: String,
    /// Target encoded width in pixels (0 = keep source).
    pub width: u32,
    /// Target encoded height in pixels (0 = keep source).
    pub height: u32,
    /// Target video bitrate in bits/sec.
    pub video_bitrate_bps: u64,
    /// Output video codec.
    pub codec: CodecId,
}

impl RenditionSpec {
    /// A 16:9 rendition of the given height at `video_bitrate_bps`.
    pub fn new(
        name: impl Into<String>,
        height: u32,
        video_bitrate_bps: u64,
        codec: CodecId,
    ) -> Self {
        Self {
            name: name.into(),
            width: height * 16 / 9,
            height,
            video_bitrate_bps,
            codec,
        }
    }
}

/// Transforms frames: decode/scale/encode, packetize, or fan into renditions.
///
/// Returning a `Vec` lets one input frame yield several outputs (e.g. one per
/// ABR rung) or none (e.g. while priming an encoder).
#[async_trait]
pub trait Transcoder: Send + Sync {
    /// Stable identifier (e.g. `"nvenc-abr"`).
    fn id(&self) -> &str;

    /// The renditions this transcoder emits.
    fn renditions(&self) -> &[RenditionSpec];

    /// Process one input frame into zero or more output frames.
    async fn transcode(&mut self, frame: MediaFrame) -> Result<Vec<MediaFrame>>;

    /// Flush any buffered output at end-of-stream.
    async fn flush(&mut self) -> Result<Vec<MediaFrame>> {
        Ok(Vec::new())
    }
}