feat: 支持 rtsp 功能

This commit is contained in:
mofeng-git
2026-02-11 16:06:06 +08:00
parent 261deb1303
commit 3824e57fc5
23 changed files with 2154 additions and 37 deletions

View File

@@ -23,6 +23,9 @@ use tracing::{debug, error, info, warn};
use crate::audio::AudioController;
use crate::hid::{HidController, KeyEventType, KeyboardEvent, KeyboardModifiers};
use crate::video::codec_constraints::{
encoder_codec_to_id, encoder_codec_to_video_codec, video_codec_to_encoder_codec,
};
use crate::video::encoder::registry::{EncoderRegistry, VideoEncoderType};
use crate::video::encoder::BitratePreset;
use crate::video::stream_manager::VideoStreamManager;
@@ -627,7 +630,7 @@ impl Connection {
// Select the best available video codec
// Priority: H264 > H265 > VP8 > VP9 (H264/H265 leverage hardware encoding)
let negotiated = self.negotiate_video_codec();
let negotiated = self.negotiate_video_codec().await;
self.negotiated_codec = Some(negotiated);
info!("Negotiated video codec: {:?}", negotiated);
@@ -641,28 +644,49 @@ impl Connection {
/// Negotiate video codec - select the best available encoder
/// Priority: H264 > H265 > VP8 > VP9 (H264/H265 leverage hardware encoding on embedded devices)
fn negotiate_video_codec(&self) -> VideoEncoderType {
async fn negotiate_video_codec(&self) -> VideoEncoderType {
let registry = EncoderRegistry::global();
let constraints = self.current_codec_constraints().await;
// Check availability in priority order
// H264 is preferred because it has the best hardware encoder support (RKMPP, VAAPI, etc.)
// and most RustDesk clients support H264 hardware decoding
if registry.is_format_available(VideoEncoderType::H264, false) {
if constraints.is_webrtc_codec_allowed(crate::video::encoder::VideoCodecType::H264)
&& registry.is_format_available(VideoEncoderType::H264, false)
{
return VideoEncoderType::H264;
}
if registry.is_format_available(VideoEncoderType::H265, false) {
if constraints.is_webrtc_codec_allowed(crate::video::encoder::VideoCodecType::H265)
&& registry.is_format_available(VideoEncoderType::H265, false)
{
return VideoEncoderType::H265;
}
if registry.is_format_available(VideoEncoderType::VP8, false) {
if constraints.is_webrtc_codec_allowed(crate::video::encoder::VideoCodecType::VP8)
&& registry.is_format_available(VideoEncoderType::VP8, false)
{
return VideoEncoderType::VP8;
}
if registry.is_format_available(VideoEncoderType::VP9, false) {
if constraints.is_webrtc_codec_allowed(crate::video::encoder::VideoCodecType::VP9)
&& registry.is_format_available(VideoEncoderType::VP9, false)
{
return VideoEncoderType::VP9;
}
// Fallback to H264 (should be available via hardware or software encoder)
warn!("No video encoder available, defaulting to H264");
VideoEncoderType::H264
// Fallback to preferred allowed codec
let preferred = constraints.preferred_webrtc_codec();
warn!(
"No allowed encoder available in priority order, falling back to {}",
encoder_codec_to_id(video_codec_to_encoder_codec(preferred))
);
video_codec_to_encoder_codec(preferred)
}
async fn current_codec_constraints(&self) -> crate::video::codec_constraints::StreamCodecConstraints {
if let Some(ref video_manager) = self.video_manager {
video_manager.codec_constraints().await
} else {
crate::video::codec_constraints::StreamCodecConstraints::unrestricted()
}
}
/// Handle misc message with Arc writer
@@ -747,6 +771,17 @@ impl Connection {
if let Some(new_codec) = requested_codec {
// Check if this codec is different from current and available
if self.negotiated_codec != Some(new_codec) {
let constraints = self.current_codec_constraints().await;
if !constraints
.is_webrtc_codec_allowed(encoder_codec_to_video_codec(new_codec))
{
warn!(
"Client requested codec {:?} but it's blocked by constraints: {}",
new_codec, constraints.reason
);
return Ok(());
}
let registry = EncoderRegistry::global();
if registry.is_format_available(new_codec, false) {
info!(
@@ -1080,12 +1115,21 @@ impl Connection {
if success {
// Dynamically detect available encoders
let registry = EncoderRegistry::global();
let constraints = self.current_codec_constraints().await;
// Check which encoders are available (include software fallback)
let h264_available = registry.is_format_available(VideoEncoderType::H264, false);
let h265_available = registry.is_format_available(VideoEncoderType::H265, false);
let vp8_available = registry.is_format_available(VideoEncoderType::VP8, false);
let vp9_available = registry.is_format_available(VideoEncoderType::VP9, false);
let h264_available = constraints
.is_webrtc_codec_allowed(crate::video::encoder::VideoCodecType::H264)
&& registry.is_format_available(VideoEncoderType::H264, false);
let h265_available = constraints
.is_webrtc_codec_allowed(crate::video::encoder::VideoCodecType::H265)
&& registry.is_format_available(VideoEncoderType::H265, false);
let vp8_available = constraints
.is_webrtc_codec_allowed(crate::video::encoder::VideoCodecType::VP8)
&& registry.is_format_available(VideoEncoderType::VP8, false);
let vp9_available = constraints
.is_webrtc_codec_allowed(crate::video::encoder::VideoCodecType::VP9)
&& registry.is_format_available(VideoEncoderType::VP9, false);
info!(
"Server encoding capabilities: H264={}, H265={}, VP8={}, VP9={}",