mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-03-17 00:16:50 +08:00
perf(rustdesk): 优化视频流性能和修复管道重启问题
- 使用 bounded channel(4) 替代 unbounded channel 提供背压控制 - 配置 protobuf 使用 bytes::Bytes 类型实现零拷贝 - 添加 encode_frame_bytes_zero_copy 方法避免帧数据拷贝 - 预分配 128KB 发送缓冲区减少内存分配 - 添加 write_frame_buffered 函数复用缓冲区 - 修复视频管道重启后 RustDesk 连接不恢复的问题 - 实现双层循环自动重新订阅新管道 - 修复 WebRTC set_bitrate_preset 中 video_frame_tx 被清除的问题 - 删除冗余的 RegisterPeer 日志
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
//! RustDesk Frame Adapters
|
||||
//!
|
||||
//! Converts One-KVM video/audio frames to RustDesk protocol format.
|
||||
//! Optimized for zero-copy where possible and buffer reuse.
|
||||
|
||||
use bytes::Bytes;
|
||||
use bytes::{Bytes, BytesMut};
|
||||
use prost::Message as ProstMessage;
|
||||
|
||||
use super::protocol::hbb::{self, message, EncodedVideoFrame, EncodedVideoFrames, AudioFrame, AudioFormat, Misc};
|
||||
@@ -55,8 +56,10 @@ impl VideoFrameAdapter {
|
||||
self.codec = codec;
|
||||
}
|
||||
|
||||
/// Convert encoded video data to RustDesk Message
|
||||
pub fn encode_frame(&mut self, data: &[u8], is_keyframe: bool, timestamp_ms: u64) -> hbb::Message {
|
||||
/// Convert encoded video data to RustDesk Message (zero-copy version)
|
||||
///
|
||||
/// This version takes Bytes directly to avoid copying the frame data.
|
||||
pub fn encode_frame_from_bytes(&mut self, data: Bytes, is_keyframe: bool, timestamp_ms: u64) -> hbb::Message {
|
||||
// Calculate relative timestamp
|
||||
if self.seq == 0 {
|
||||
self.timestamp_base = timestamp_ms;
|
||||
@@ -64,7 +67,7 @@ impl VideoFrameAdapter {
|
||||
let pts = (timestamp_ms - self.timestamp_base) as i64;
|
||||
|
||||
let frame = EncodedVideoFrame {
|
||||
data: data.to_vec(),
|
||||
data, // Zero-copy: Bytes is reference-counted
|
||||
key: is_keyframe,
|
||||
pts,
|
||||
..Default::default()
|
||||
@@ -107,10 +110,24 @@ impl VideoFrameAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert encoded video data to RustDesk Message
|
||||
pub fn encode_frame(&mut self, data: &[u8], is_keyframe: bool, timestamp_ms: u64) -> hbb::Message {
|
||||
self.encode_frame_from_bytes(Bytes::copy_from_slice(data), is_keyframe, timestamp_ms)
|
||||
}
|
||||
|
||||
/// Encode frame to bytes for sending (zero-copy version)
|
||||
///
|
||||
/// Takes Bytes directly to avoid copying the frame data.
|
||||
pub fn encode_frame_bytes_zero_copy(&mut self, data: Bytes, is_keyframe: bool, timestamp_ms: u64) -> Bytes {
|
||||
let msg = self.encode_frame_from_bytes(data, is_keyframe, timestamp_ms);
|
||||
let mut buf = BytesMut::with_capacity(msg.encoded_len());
|
||||
msg.encode(&mut buf).expect("encode should not fail");
|
||||
buf.freeze()
|
||||
}
|
||||
|
||||
/// Encode frame to bytes for sending
|
||||
pub fn encode_frame_bytes(&mut self, data: &[u8], is_keyframe: bool, timestamp_ms: u64) -> Bytes {
|
||||
let msg = self.encode_frame(data, is_keyframe, timestamp_ms);
|
||||
Bytes::from(ProstMessage::encode_to_vec(&msg))
|
||||
self.encode_frame_bytes_zero_copy(Bytes::copy_from_slice(data), is_keyframe, timestamp_ms)
|
||||
}
|
||||
|
||||
/// Get current sequence number
|
||||
@@ -163,7 +180,7 @@ impl AudioFrameAdapter {
|
||||
/// Convert Opus audio data to RustDesk Message
|
||||
pub fn encode_opus_frame(&self, data: &[u8]) -> hbb::Message {
|
||||
let frame = AudioFrame {
|
||||
data: data.to_vec(),
|
||||
data: Bytes::copy_from_slice(data),
|
||||
};
|
||||
|
||||
hbb::Message {
|
||||
@@ -202,7 +219,7 @@ impl CursorAdapter {
|
||||
hoty,
|
||||
width,
|
||||
height,
|
||||
colors,
|
||||
colors: Bytes::from(colors),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user