mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-10-28 00:10:50 +08:00
perf(video): 优化视频流水线并统一使用 vendored OpenSSL
使用固定采集、解码和编码线程及同步最新帧槽,减少同步异步跨界和无效 MJPEG 解码。 编码前预留消费者容量,以完整批次投递编码结果并隔离慢客户端,避免丢失 H.264 参考帧;保留 PTS 修正,不增加 IDR 节流。 复用 Annex-B 缓冲并增加低频发送分项统计,默认启用 vendored OpenSSL SRTP AES-CM 后端。 HTTP 客户端、HTTPS 服务端和本地 DTLS 证书验证迁移至 OpenSSL,移除 rustls TLS 引擎依赖,保留证书验证、媒体加密和原有协议协商。
This commit is contained in:
100
src/video/pipeline/delivery.rs
Normal file
100
src/video/pipeline/delivery.rs
Normal file
@@ -0,0 +1,100 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use super::frame_mailbox::FrameMailbox;
|
||||
use super::EncodedVideoFrame;
|
||||
use crate::video::frame::VideoFrame;
|
||||
|
||||
pub(super) type EncodedBatch = Arc<[Arc<EncodedVideoFrame>]>;
|
||||
pub(super) type FrameMailboxHandle = Arc<Mutex<Option<Arc<FrameMailbox<Arc<VideoFrame>>>>>>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(super) struct DeliveryStats {
|
||||
pub sent_frames: AtomicU64,
|
||||
pub send_time_ns: AtomicU64,
|
||||
pub send_errors: AtomicU64,
|
||||
}
|
||||
|
||||
pub(super) struct VideoSubscriber {
|
||||
pub sender: mpsc::Sender<EncodedBatch>,
|
||||
pub needs_keyframe: AtomicBool,
|
||||
pub recovery_requested: AtomicBool,
|
||||
}
|
||||
|
||||
pub(super) struct VideoFrameReservation {
|
||||
pub subscriber: Arc<VideoSubscriber>,
|
||||
pub permit: mpsc::OwnedPermit<EncodedBatch>,
|
||||
}
|
||||
|
||||
pub struct EncodedVideoFrameReceiver {
|
||||
receiver: mpsc::Receiver<EncodedBatch>,
|
||||
pending: VecDeque<Arc<EncodedVideoFrame>>,
|
||||
mailbox: FrameMailboxHandle,
|
||||
stats: Arc<DeliveryStats>,
|
||||
}
|
||||
|
||||
impl EncodedVideoFrameReceiver {
|
||||
pub(super) fn new(
|
||||
receiver: mpsc::Receiver<EncodedBatch>,
|
||||
mailbox: FrameMailboxHandle,
|
||||
stats: Arc<DeliveryStats>,
|
||||
) -> Self {
|
||||
Self {
|
||||
receiver,
|
||||
pending: VecDeque::new(),
|
||||
mailbox,
|
||||
stats,
|
||||
}
|
||||
}
|
||||
|
||||
fn notify_capacity(&self) {
|
||||
if let Some(mailbox) = self.mailbox.lock().as_ref() {
|
||||
mailbox.notify();
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn recv(&mut self) -> Option<Arc<EncodedVideoFrame>> {
|
||||
loop {
|
||||
if let Some(frame) = self.pending.pop_front() {
|
||||
return Some(frame);
|
||||
}
|
||||
let batch = self.receiver.recv().await?;
|
||||
self.pending.extend(batch.iter().cloned());
|
||||
self.notify_capacity();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_recv(&mut self) -> Result<Arc<EncodedVideoFrame>, mpsc::error::TryRecvError> {
|
||||
loop {
|
||||
if let Some(frame) = self.pending.pop_front() {
|
||||
return Ok(frame);
|
||||
}
|
||||
let batch = self.receiver.try_recv()?;
|
||||
self.pending.extend(batch.iter().cloned());
|
||||
self.notify_capacity();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn record_send(&self, elapsed: Duration, succeeded: bool) {
|
||||
self.stats
|
||||
.send_time_ns
|
||||
.fetch_add(elapsed.as_nanos() as u64, Ordering::Relaxed);
|
||||
if succeeded {
|
||||
self.stats.sent_frames.fetch_add(1, Ordering::Relaxed);
|
||||
} else {
|
||||
self.stats.send_errors.fetch_add(1, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EncodedVideoFrameReceiver {
|
||||
fn drop(&mut self) {
|
||||
self.receiver.close();
|
||||
self.notify_capacity();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user