feat: 深入适配 RK628D CSI 采集卡的设备识别、参数读取、自恢复和音频采集

This commit is contained in:
mofeng-git
2026-04-19 11:26:21 +08:00
parent 8eac31f69f
commit 7c703b8b4b
39 changed files with 3261 additions and 769 deletions

View File

@@ -4,6 +4,7 @@
pub mod codec_constraints;
pub mod convert;
pub mod csi_bridge;
pub mod decoder;
pub mod device;
pub mod encoder;
@@ -25,6 +26,55 @@ pub use shared_video_pipeline::{
pub use stream_manager::VideoStreamManager;
pub use streamer::{Streamer, StreamerState};
/// Fine-grained signal status reported by CSI/HDMI bridge devices.
///
/// Only `rk_hdmirx` / `rkcif` / tc358743-class bridges can distinguish these
/// via `VIDIOC_QUERY_DV_TIMINGS` errno; USB UVC devices always report `Ok`
/// until they fail with a generic timeout.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SignalStatus {
/// HDMI cable physically disconnected (`ENOLINK`).
NoCable,
/// TMDS signal present but timings cannot be locked (`ENOLCK`).
NoSync,
/// Timings outside of hardware capability (`ERANGE`).
OutOfRange,
/// Generic "no usable source" (fallback for EINVAL / EIO / unknown errnos).
NoSignal,
}
impl SignalStatus {
pub fn as_str(self) -> &'static str {
match self {
SignalStatus::NoCable => "no_cable",
SignalStatus::NoSync => "no_sync",
SignalStatus::OutOfRange => "out_of_range",
SignalStatus::NoSignal => "no_signal",
}
}
pub fn from_str(s: &str) -> Option<Self> {
Some(match s {
"no_cable" => SignalStatus::NoCable,
"no_sync" => SignalStatus::NoSync,
"out_of_range" => SignalStatus::OutOfRange,
"no_signal" => SignalStatus::NoSignal,
_ => return None,
})
}
}
impl From<SignalStatus> for streamer::StreamerState {
fn from(value: SignalStatus) -> Self {
match value {
SignalStatus::NoCable => streamer::StreamerState::NoCable,
SignalStatus::NoSync => streamer::StreamerState::NoSync,
SignalStatus::OutOfRange => streamer::StreamerState::OutOfRange,
SignalStatus::NoSignal => streamer::StreamerState::NoSignal,
}
}
}
pub(crate) fn is_rk_hdmirx_driver(driver: &str, card: &str) -> bool {
driver.eq_ignore_ascii_case("rk_hdmirx") || card.eq_ignore_ascii_case("rk_hdmirx")
}
@@ -32,3 +82,13 @@ pub(crate) fn is_rk_hdmirx_driver(driver: &str, card: &str) -> bool {
pub(crate) fn is_rk_hdmirx_device(device: &device::VideoDeviceInfo) -> bool {
is_rk_hdmirx_driver(&device.driver, &device.card)
}
pub(crate) fn is_rkcif_driver(driver: &str) -> bool {
driver.eq_ignore_ascii_case("rkcif")
}
/// Unified check for CSI/HDMI bridge devices (rk_hdmirx, rkcif, etc.)
/// that require special enumeration and format-selection logic.
pub(crate) fn is_csi_hdmi_bridge(device: &device::VideoDeviceInfo) -> bool {
is_rk_hdmirx_device(device) || is_rkcif_driver(&device.driver)
}