fix: 修复无信号状态同步与采集管线阻塞

- 使用非阻塞 V4L2 句柄并类型化采集错误
- 完善视频管线生命周期,避免复用停止中的管线
- 区分音视频事件并支持 REST/WebSocket 状态快照
- 修复信号丢失后保留最后一帧及刷新后黑屏问题
- 优化无信号提示、状态展示优先级及相关界面细节
- 降低重复 OTG 错误日志级别
This commit is contained in:
mofeng-git
2026-07-30 22:43:59 +08:00
parent ce1712ff2e
commit 6fdcf5c7c9
24 changed files with 406 additions and 165 deletions

View File

@@ -1,10 +1,51 @@
//! Video capture implementations and capture-state helpers.
use std::fmt;
use std::io;
pub(crate) mod runtime;
pub(crate) mod status;
pub const DEFAULT_CAPTURE_BUFFER_COUNT: u32 = 4;
/// Expected source changes are control flow, not stringly typed I/O errors.
#[derive(Debug)]
pub enum CaptureReadError {
SourceChanged,
Io(io::Error),
}
impl CaptureReadError {
pub fn as_io_error(&self) -> Option<&io::Error> {
match self {
Self::SourceChanged => None,
Self::Io(error) => Some(error),
}
}
}
impl From<io::Error> for CaptureReadError {
fn from(error: io::Error) -> Self {
Self::Io(error)
}
}
impl fmt::Display for CaptureReadError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::SourceChanged => formatter.write_str("capture source changed"),
Self::Io(error) => error.fmt(formatter),
}
}
}
impl std::error::Error for CaptureReadError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.as_io_error()
.map(|error| error as &(dyn std::error::Error + 'static))
}
}
#[cfg(unix)]
mod linux;
#[cfg(windows)]