mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
Merge pull request #5282 from 21pages/record
enable keyframe interval when recording
This commit is contained in:
@@ -174,6 +174,12 @@ pub fn session_record_screen(session_id: SessionID, start: bool, width: usize, h
|
||||
}
|
||||
}
|
||||
|
||||
pub fn session_record_status(session_id: SessionID, status: bool) {
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
|
||||
session.record_status(status);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn session_reconnect(session_id: SessionID, force_relay: bool) {
|
||||
if let Some(session) = SESSIONS.read().unwrap().get(&session_id) {
|
||||
session.reconnect(force_relay);
|
||||
|
||||
@@ -1907,6 +1907,10 @@ impl Connection {
|
||||
.lock()
|
||||
.unwrap()
|
||||
.user_auto_adjust_fps(self.inner.id(), fps),
|
||||
Some(misc::Union::ClientRecordStatus(status)) => video_service::VIDEO_QOS
|
||||
.lock()
|
||||
.unwrap()
|
||||
.user_record(self.inner.id(), status),
|
||||
_ => {}
|
||||
},
|
||||
Some(message::Union::AudioFrame(frame)) => {
|
||||
|
||||
@@ -36,6 +36,7 @@ struct UserData {
|
||||
quality: Option<(i64, Quality)>, // (time, quality)
|
||||
delay: Option<Delay>,
|
||||
response_delayed: bool,
|
||||
record: bool,
|
||||
}
|
||||
|
||||
pub struct VideoQoS {
|
||||
@@ -114,6 +115,10 @@ impl VideoQoS {
|
||||
self.quality
|
||||
}
|
||||
|
||||
pub fn record(&self) -> bool {
|
||||
self.users.iter().any(|u| u.1.record)
|
||||
}
|
||||
|
||||
pub fn abr_enabled() -> bool {
|
||||
"N" != Config::get_option("enable-abr")
|
||||
}
|
||||
@@ -388,6 +393,12 @@ impl VideoQoS {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn user_record(&mut self, id: i32, v: bool) {
|
||||
if let Some(user) = self.users.get_mut(&id) {
|
||||
user.record = v;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_connection_close(&mut self, id: i32) {
|
||||
self.users.remove(&id);
|
||||
self.refresh(None);
|
||||
|
||||
@@ -36,7 +36,7 @@ use hbb_common::{
|
||||
use scrap::Capturer;
|
||||
use scrap::{
|
||||
aom::AomEncoderConfig,
|
||||
codec::{Encoder, EncoderCfg, HwEncoderConfig},
|
||||
codec::{Encoder, EncoderCfg, HwEncoderConfig, Quality},
|
||||
record::{Recorder, RecorderContext},
|
||||
vpxcodec::{VpxEncoderConfig, VpxVideoCodecId},
|
||||
CodecName, Display, TraitCapturer,
|
||||
@@ -518,37 +518,13 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
let mut spf;
|
||||
let mut quality = video_qos.quality();
|
||||
let abr = VideoQoS::abr_enabled();
|
||||
drop(video_qos);
|
||||
log::info!("init quality={:?}, abr enabled:{}", quality, abr);
|
||||
|
||||
let encoder_cfg = match Encoder::negotiated_codec() {
|
||||
scrap::CodecName::H264(name) | scrap::CodecName::H265(name) => {
|
||||
EncoderCfg::HW(HwEncoderConfig {
|
||||
name,
|
||||
width: c.width,
|
||||
height: c.height,
|
||||
quality,
|
||||
})
|
||||
}
|
||||
name @ (scrap::CodecName::VP8 | scrap::CodecName::VP9) => {
|
||||
EncoderCfg::VPX(VpxEncoderConfig {
|
||||
width: c.width as _,
|
||||
height: c.height as _,
|
||||
timebase: [1, 1000], // Output timestamp precision
|
||||
quality,
|
||||
codec: if name == scrap::CodecName::VP8 {
|
||||
VpxVideoCodecId::VP8
|
||||
} else {
|
||||
VpxVideoCodecId::VP9
|
||||
},
|
||||
})
|
||||
}
|
||||
scrap::CodecName::AV1 => EncoderCfg::AOM(AomEncoderConfig {
|
||||
width: c.width as _,
|
||||
height: c.height as _,
|
||||
quality,
|
||||
}),
|
||||
};
|
||||
let codec_name = Encoder::negotiated_codec();
|
||||
let recorder = get_recorder(c.width, c.height, &codec_name);
|
||||
let last_recording =
|
||||
(recorder.lock().unwrap().is_some() || video_qos.record()) && codec_name != CodecName::AV1;
|
||||
drop(video_qos);
|
||||
let encoder_cfg = get_encoder_config(&c, quality, last_recording);
|
||||
|
||||
let mut encoder;
|
||||
match Encoder::new(encoder_cfg) {
|
||||
@@ -597,8 +573,6 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
let mut try_gdi = 1;
|
||||
#[cfg(windows)]
|
||||
log::info!("gdi: {}", c.is_gdi());
|
||||
let codec_name = Encoder::negotiated_codec();
|
||||
let recorder = get_recorder(c.width, c.height, &codec_name);
|
||||
#[cfg(windows)]
|
||||
start_uac_elevation_check();
|
||||
|
||||
@@ -617,6 +591,11 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
allow_err!(encoder.set_quality(quality));
|
||||
video_qos.store_bitrate(encoder.bitrate());
|
||||
}
|
||||
let recording = (recorder.lock().unwrap().is_some() || video_qos.record())
|
||||
&& codec_name != CodecName::AV1;
|
||||
if recording != last_recording {
|
||||
bail!("SWITCH");
|
||||
}
|
||||
drop(video_qos);
|
||||
|
||||
if *SWITCH.lock().unwrap() {
|
||||
@@ -789,6 +768,41 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_encoder_config(c: &CapturerInfo, quality: Quality, recording: bool) -> EncoderCfg {
|
||||
// https://www.wowza.com/community/t/the-correct-keyframe-interval-in-obs-studio/95162
|
||||
let keyframe_interval = if recording { Some(240) } else { None };
|
||||
match Encoder::negotiated_codec() {
|
||||
scrap::CodecName::H264(name) | scrap::CodecName::H265(name) => {
|
||||
EncoderCfg::HW(HwEncoderConfig {
|
||||
name,
|
||||
width: c.width,
|
||||
height: c.height,
|
||||
quality,
|
||||
keyframe_interval,
|
||||
})
|
||||
}
|
||||
name @ (scrap::CodecName::VP8 | scrap::CodecName::VP9) => {
|
||||
EncoderCfg::VPX(VpxEncoderConfig {
|
||||
width: c.width as _,
|
||||
height: c.height as _,
|
||||
quality,
|
||||
codec: if name == scrap::CodecName::VP8 {
|
||||
VpxVideoCodecId::VP8
|
||||
} else {
|
||||
VpxVideoCodecId::VP9
|
||||
},
|
||||
keyframe_interval,
|
||||
})
|
||||
}
|
||||
scrap::CodecName::AV1 => EncoderCfg::AOM(AomEncoderConfig {
|
||||
width: c.width as _,
|
||||
height: c.height as _,
|
||||
quality,
|
||||
keyframe_interval,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_recorder(
|
||||
width: usize,
|
||||
height: usize,
|
||||
|
||||
@@ -297,6 +297,7 @@ class Header: Reactor.Component {
|
||||
event click $(span#recording) (_, me) {
|
||||
recording = !recording;
|
||||
header.update();
|
||||
handler.record_status(recording);
|
||||
if (recording)
|
||||
handler.refresh_video();
|
||||
else
|
||||
|
||||
@@ -451,6 +451,7 @@ impl sciter::EventHandler for SciterSession {
|
||||
fn save_custom_image_quality(i32);
|
||||
fn refresh_video();
|
||||
fn record_screen(bool, i32, i32);
|
||||
fn record_status(bool);
|
||||
fn get_toggle_option(String);
|
||||
fn is_privacy_mode_supported();
|
||||
fn toggle_option(String);
|
||||
|
||||
@@ -240,6 +240,14 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
self.send(Data::RecordScreen(start, w, h, self.id.clone()));
|
||||
}
|
||||
|
||||
pub fn record_status(&self, status: bool) {
|
||||
let mut misc = Misc::new();
|
||||
misc.set_client_record_status(status);
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
self.send(Data::Message(msg));
|
||||
}
|
||||
|
||||
pub fn save_custom_image_quality(&mut self, custom_image_quality: i32) {
|
||||
let msg = self
|
||||
.lc
|
||||
|
||||
Reference in New Issue
Block a user