mirror of
https://github.com/rustdesk/rustdesk.git
synced 2024-11-24 12:29:04 +08:00
scrap: ensure video_handler's creation before client start
Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
2a91fb842d
commit
feaadcfc96
@ -23,8 +23,10 @@ use hbb_common::{
|
||||
|
||||
#[cfg(feature = "hwcodec")]
|
||||
lazy_static::lazy_static! {
|
||||
static ref VIDEO_CODEC_STATES: Arc<Mutex<HashMap<i32, VideoCodecState>>> = Default::default();
|
||||
static ref PEER_DECODER_STATES: Arc<Mutex<HashMap<i32, VideoCodecState>>> = Default::default();
|
||||
static ref MY_DECODER_STATE: Arc<Mutex<VideoCodecState>> = Default::default();
|
||||
}
|
||||
const SCORE_VPX: i32 = 90;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct HwEncoderConfig {
|
||||
@ -96,9 +98,15 @@ impl Encoder {
|
||||
}),
|
||||
|
||||
#[cfg(feature = "hwcodec")]
|
||||
EncoderCfg::HW(_) => Ok(Encoder {
|
||||
codec: Box::new(HwEncoder::new(config)?),
|
||||
}),
|
||||
EncoderCfg::HW(_) => match HwEncoder::new(config) {
|
||||
Ok(hw) => Ok(Encoder {
|
||||
codec: Box::new(hw),
|
||||
}),
|
||||
Err(e) => {
|
||||
HwEncoder::best(true);
|
||||
Err(e)
|
||||
}
|
||||
},
|
||||
#[cfg(not(feature = "hwcodec"))]
|
||||
_ => Err(anyhow!("unsupported encoder type")),
|
||||
}
|
||||
@ -109,7 +117,7 @@ impl Encoder {
|
||||
log::info!("update video encoder:{:?}", update);
|
||||
#[cfg(feature = "hwcodec")]
|
||||
{
|
||||
let mut states = VIDEO_CODEC_STATES.lock().unwrap();
|
||||
let mut states = PEER_DECODER_STATES.lock().unwrap();
|
||||
match update {
|
||||
EncoderUpdate::State(state) => {
|
||||
states.insert(id, state);
|
||||
@ -125,14 +133,14 @@ impl Encoder {
|
||||
}
|
||||
let current_encoder_name = HwEncoder::current_name();
|
||||
if states.len() > 0 {
|
||||
let best = HwEncoder::best();
|
||||
let best = HwEncoder::best(false);
|
||||
let enabled_h264 =
|
||||
best.h264.is_some() && states.len() > 0 && states.iter().all(|(_, s)| s.H264);
|
||||
let enabled_h265 =
|
||||
best.h265.is_some() && states.len() > 0 && states.iter().all(|(_, s)| s.H265);
|
||||
|
||||
// score encoder
|
||||
let mut score_vpx = 90;
|
||||
let mut score_vpx = SCORE_VPX;
|
||||
let mut score_h264 = best.h264.as_ref().map_or(0, |c| c.score);
|
||||
let mut score_h265 = best.h265.as_ref().map_or(0, |c| c.score);
|
||||
|
||||
@ -181,33 +189,50 @@ impl Encoder {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "hwcodec")]
|
||||
impl Drop for Decoder {
|
||||
fn drop(&mut self) {
|
||||
*MY_DECODER_STATE.lock().unwrap() = VideoCodecState {
|
||||
ScoreVpx: SCORE_VPX,
|
||||
..Default::default()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl Decoder {
|
||||
// TODO
|
||||
pub fn video_codec_state() -> VideoCodecState {
|
||||
let mut state = VideoCodecState::default();
|
||||
state.ScoreVpx = 90;
|
||||
|
||||
// video_codec_state is mainted by creation and destruction of Decoder.
|
||||
// It has been ensured to use after Decoder's creation.
|
||||
#[cfg(feature = "hwcodec")]
|
||||
{
|
||||
let best = super::hwcodec::HwDecoder::best(false);
|
||||
state.H264 = best.h264.is_some();
|
||||
state.ScoreH264 = best.h264.map_or(0, |c| c.score);
|
||||
state.H265 = best.h265.is_some();
|
||||
state.ScoreH265 = best.h265.map_or(0, |c| c.score);
|
||||
return MY_DECODER_STATE.lock().unwrap().clone();
|
||||
#[cfg(not(feature = "hwcodec"))]
|
||||
VideoCodecState {
|
||||
ScoreVpx: SCORE_VPX,
|
||||
..Default::default()
|
||||
}
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
pub fn new(config: DecoderCfg) -> Decoder {
|
||||
let vpx = VpxDecoder::new(config.vpx).unwrap();
|
||||
Decoder {
|
||||
let decoder = Decoder {
|
||||
vpx,
|
||||
#[cfg(feature = "hwcodec")]
|
||||
hw: HwDecoder::new_decoders(),
|
||||
#[cfg(feature = "hwcodec")]
|
||||
i420: vec![],
|
||||
};
|
||||
|
||||
#[cfg(feature = "hwcodec")]
|
||||
{
|
||||
let mut state = MY_DECODER_STATE.lock().unwrap();
|
||||
state.ScoreVpx = SCORE_VPX;
|
||||
state.H264 = decoder.hw.h264.is_some();
|
||||
state.ScoreH264 = decoder.hw.h264.as_ref().map_or(0, |d| d.info.score);
|
||||
state.H265 = decoder.hw.h265.is_some();
|
||||
state.ScoreH265 = decoder.hw.h265.as_ref().map_or(0, |d| d.info.score);
|
||||
}
|
||||
|
||||
decoder
|
||||
}
|
||||
|
||||
pub fn handle_video_frame(
|
||||
|
@ -137,29 +137,30 @@ impl EncoderApi for HwEncoder {
|
||||
}
|
||||
|
||||
impl HwEncoder {
|
||||
pub fn best() -> CodecInfos {
|
||||
pub fn best(force_reset: bool) -> CodecInfos {
|
||||
let key = "bestHwEncoders";
|
||||
match get_config(key) {
|
||||
Ok(config) => config,
|
||||
Err(_) => {
|
||||
let ctx = EncodeContext {
|
||||
name: String::from(""),
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
pixfmt: DEFAULT_PIXFMT,
|
||||
align: HW_STRIDE_ALIGN as _,
|
||||
bitrate: 0,
|
||||
timebase: DEFAULT_TIME_BASE,
|
||||
gop: DEFAULT_GOP,
|
||||
quality: DEFAULT_HW_QUALITY,
|
||||
rc: DEFAULT_RC,
|
||||
};
|
||||
let encoders = CodecInfo::score(Encoder::avaliable_encoders(ctx));
|
||||
let _ = set_config(key, &encoders)
|
||||
.map_err(|e| log::error!("{:?}", e))
|
||||
.ok();
|
||||
encoders
|
||||
}
|
||||
|
||||
let config = get_config(key);
|
||||
if !force_reset && config.is_ok() {
|
||||
config.unwrap()
|
||||
} else {
|
||||
let ctx = EncodeContext {
|
||||
name: String::from(""),
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
pixfmt: DEFAULT_PIXFMT,
|
||||
align: HW_STRIDE_ALIGN as _,
|
||||
bitrate: 0,
|
||||
timebase: DEFAULT_TIME_BASE,
|
||||
gop: DEFAULT_GOP,
|
||||
quality: DEFAULT_HW_QUALITY,
|
||||
rc: DEFAULT_RC,
|
||||
};
|
||||
let encoders = CodecInfo::score(Encoder::avaliable_encoders(ctx));
|
||||
let _ = set_config(key, &encoders)
|
||||
.map_err(|e| log::error!("{:?}", e))
|
||||
.ok();
|
||||
encoders
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,7 +235,7 @@ pub struct HwDecoders {
|
||||
|
||||
impl HwDecoder {
|
||||
/// H264, H265 decoder info with the highest score.
|
||||
pub fn best(force_reset: bool) -> CodecInfos {
|
||||
fn best(force_reset: bool) -> CodecInfos {
|
||||
let key = "bestHwDecoders";
|
||||
let config = get_config(key);
|
||||
if !force_reset && config.is_ok() {
|
||||
@ -268,7 +269,6 @@ impl HwDecoder {
|
||||
}
|
||||
if fail {
|
||||
HwDecoder::best(true);
|
||||
// TODO: notify encoder
|
||||
}
|
||||
|
||||
if h264.is_some() {
|
||||
|
@ -1159,9 +1159,11 @@ where
|
||||
|
||||
let latency_controller = LatencyController::new();
|
||||
let latency_controller_cl = latency_controller.clone();
|
||||
// Create video_handler out of the thread below to ensure that the handler exists before client start.
|
||||
// It will take a few tenths of a second for the first time, and then tens of milliseconds.
|
||||
let mut video_handler = VideoHandler::new(latency_controller);
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let mut video_handler = VideoHandler::new(latency_controller);
|
||||
loop {
|
||||
if let Ok(data) = video_receiver.recv() {
|
||||
match data {
|
||||
|
Loading…
Reference in New Issue
Block a user