Merge branch 'hwcodec' into hwcodec
This commit is contained in:
commit
ce89e7fd8c
@ -1,33 +1,13 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
package hbb;
|
package hbb;
|
||||||
|
|
||||||
message VP9 {
|
message EncodedVideoFrame {
|
||||||
bytes data = 1;
|
bytes data = 1;
|
||||||
bool key = 2;
|
bool key = 2;
|
||||||
int64 pts = 3;
|
int64 pts = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message VP9s { repeated VP9 frames = 1; }
|
message EncodedVideoFrames { repeated EncodedVideoFrame frames = 1; }
|
||||||
|
|
||||||
message H264 {
|
|
||||||
bytes data = 1;
|
|
||||||
bool key = 2;
|
|
||||||
int64 pts = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message H264s {
|
|
||||||
repeated H264 h264s = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message H265 {
|
|
||||||
bytes data = 1;
|
|
||||||
bool key = 2;
|
|
||||||
int64 pts = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
message H265s {
|
|
||||||
repeated H265 h265s = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message RGB { bool compress = 1; }
|
message RGB { bool compress = 1; }
|
||||||
|
|
||||||
@ -39,11 +19,11 @@ message YUV {
|
|||||||
|
|
||||||
message VideoFrame {
|
message VideoFrame {
|
||||||
oneof union {
|
oneof union {
|
||||||
VP9s vp9s = 6;
|
EncodedVideoFrames vp9s = 6;
|
||||||
RGB rgb = 7;
|
RGB rgb = 7;
|
||||||
YUV yuv = 8;
|
YUV yuv = 8;
|
||||||
H264s h264s = 10;
|
EncodedVideoFrames h264s = 10;
|
||||||
H265s h265s = 11;
|
EncodedVideoFrames h265s = 11;
|
||||||
}
|
}
|
||||||
int64 timestamp = 9;
|
int64 timestamp = 9;
|
||||||
}
|
}
|
||||||
@ -454,10 +434,8 @@ enum ImageQuality {
|
|||||||
|
|
||||||
message VideoCodecState {
|
message VideoCodecState {
|
||||||
int32 ScoreVpx = 1;
|
int32 ScoreVpx = 1;
|
||||||
bool H264 = 2;
|
int32 ScoreH264 = 2;
|
||||||
int32 ScoreH264 = 3;
|
int32 ScoreH265 = 3;
|
||||||
bool H265 = 4;
|
|
||||||
int32 ScoreH265 = 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message OptionMessage {
|
message OptionMessage {
|
||||||
|
@ -35,7 +35,6 @@ lazy_static::lazy_static! {
|
|||||||
static ref CONFIG: Arc<RwLock<Config>> = Arc::new(RwLock::new(Config::load()));
|
static ref CONFIG: Arc<RwLock<Config>> = Arc::new(RwLock::new(Config::load()));
|
||||||
static ref CONFIG2: Arc<RwLock<Config2>> = Arc::new(RwLock::new(Config2::load()));
|
static ref CONFIG2: Arc<RwLock<Config2>> = Arc::new(RwLock::new(Config2::load()));
|
||||||
static ref LOCAL_CONFIG: Arc<RwLock<LocalConfig>> = Arc::new(RwLock::new(LocalConfig::load()));
|
static ref LOCAL_CONFIG: Arc<RwLock<LocalConfig>> = Arc::new(RwLock::new(LocalConfig::load()));
|
||||||
static ref HWCODEC_CONFIG: Arc<RwLock<HwCodecConfig>> = Arc::new(RwLock::new(HwCodecConfig::load()));
|
|
||||||
pub static ref ONLINE: Arc<Mutex<HashMap<String, i64>>> = Default::default();
|
pub static ref ONLINE: Arc<Mutex<HashMap<String, i64>>> = Default::default();
|
||||||
pub static ref PROD_RENDEZVOUS_SERVER: Arc<RwLock<String>> = Default::default();
|
pub static ref PROD_RENDEZVOUS_SERVER: Arc<RwLock<String>> = Default::default();
|
||||||
pub static ref APP_NAME: Arc<RwLock<String>> = Arc::new(RwLock::new("RustDesk".to_owned()));
|
pub static ref APP_NAME: Arc<RwLock<String>> = Arc::new(RwLock::new("RustDesk".to_owned()));
|
||||||
@ -887,38 +886,17 @@ impl LanPeers {
|
|||||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||||
pub struct HwCodecConfig {
|
pub struct HwCodecConfig {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
options: HashMap<String, String>,
|
pub options: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HwCodecConfig {
|
impl HwCodecConfig {
|
||||||
fn load() -> HwCodecConfig {
|
pub fn load() -> HwCodecConfig {
|
||||||
Config::load_::<HwCodecConfig>("_hwcodec")
|
Config::load_::<HwCodecConfig>("_hwcodec")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store(&self) {
|
pub fn store(&self) {
|
||||||
Config::store_(self, "_hwcodec");
|
Config::store_(self, "_hwcodec");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_option(k: &str) -> String {
|
|
||||||
if let Some(v) = HWCODEC_CONFIG.read().unwrap().options.get(k) {
|
|
||||||
v.clone()
|
|
||||||
} else {
|
|
||||||
"".to_owned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_option(k: String, v: String) {
|
|
||||||
let mut config = HWCODEC_CONFIG.write().unwrap();
|
|
||||||
let v2 = if v.is_empty() { None } else { Some(&v) };
|
|
||||||
if v2 != config.options.get(&k) {
|
|
||||||
if v2.is_none() {
|
|
||||||
config.options.remove(&k);
|
|
||||||
} else {
|
|
||||||
config.options.insert(k, v);
|
|
||||||
}
|
|
||||||
config.store();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -12,15 +12,11 @@ use crate::vpxcodec::*;
|
|||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
anyhow::anyhow,
|
anyhow::anyhow,
|
||||||
log,
|
log,
|
||||||
message_proto::{video_frame, Message, VP9s, VideoCodecState},
|
message_proto::{video_frame, EncodedVideoFrames, Message, VideoCodecState},
|
||||||
ResultType,
|
ResultType,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "hwcodec")]
|
#[cfg(feature = "hwcodec")]
|
||||||
use hbb_common::{
|
use hbb_common::{config::Config2, lazy_static};
|
||||||
config::Config2,
|
|
||||||
lazy_static,
|
|
||||||
message_proto::{H264s, H265s},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "hwcodec")]
|
#[cfg(feature = "hwcodec")]
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
@ -137,10 +133,12 @@ impl Encoder {
|
|||||||
let current_encoder_name = HwEncoder::current_name();
|
let current_encoder_name = HwEncoder::current_name();
|
||||||
if states.len() > 0 {
|
if states.len() > 0 {
|
||||||
let (best, _) = HwEncoder::best(false, true);
|
let (best, _) = HwEncoder::best(false, true);
|
||||||
let enabled_h264 =
|
let enabled_h264 = best.h264.is_some()
|
||||||
best.h264.is_some() && states.len() > 0 && states.iter().all(|(_, s)| s.H264);
|
&& states.len() > 0
|
||||||
let enabled_h265 =
|
&& states.iter().all(|(_, s)| s.ScoreH264 > 0);
|
||||||
best.h265.is_some() && states.len() > 0 && states.iter().all(|(_, s)| s.H265);
|
let enabled_h265 = best.h265.is_some()
|
||||||
|
&& states.len() > 0
|
||||||
|
&& states.iter().all(|(_, s)| s.ScoreH265 > 0);
|
||||||
|
|
||||||
// score encoder
|
// score encoder
|
||||||
let mut score_vpx = SCORE_VPX;
|
let mut score_vpx = SCORE_VPX;
|
||||||
@ -240,9 +238,7 @@ impl Decoder {
|
|||||||
{
|
{
|
||||||
let mut state = MY_DECODER_STATE.lock().unwrap();
|
let mut state = MY_DECODER_STATE.lock().unwrap();
|
||||||
state.ScoreVpx = SCORE_VPX;
|
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.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);
|
state.ScoreH265 = decoder.hw.h265.as_ref().map_or(0, |d| d.info.score);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +257,7 @@ impl Decoder {
|
|||||||
#[cfg(feature = "hwcodec")]
|
#[cfg(feature = "hwcodec")]
|
||||||
video_frame::Union::h264s(h264s) => {
|
video_frame::Union::h264s(h264s) => {
|
||||||
if let Some(decoder) = &mut self.hw.h264 {
|
if let Some(decoder) = &mut self.hw.h264 {
|
||||||
Decoder::handle_h264s_video_frame(decoder, h264s, rgb, &mut self.i420)
|
Decoder::handle_hw_video_frame(decoder, h264s, rgb, &mut self.i420)
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("don't support h264!"))
|
Err(anyhow!("don't support h264!"))
|
||||||
}
|
}
|
||||||
@ -269,7 +265,7 @@ impl Decoder {
|
|||||||
#[cfg(feature = "hwcodec")]
|
#[cfg(feature = "hwcodec")]
|
||||||
video_frame::Union::h265s(h265s) => {
|
video_frame::Union::h265s(h265s) => {
|
||||||
if let Some(decoder) = &mut self.hw.h265 {
|
if let Some(decoder) = &mut self.hw.h265 {
|
||||||
Decoder::handle_h265s_video_frame(decoder, h265s, rgb, &mut self.i420)
|
Decoder::handle_hw_video_frame(decoder, h265s, rgb, &mut self.i420)
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("don't support h265!"))
|
Err(anyhow!("don't support h265!"))
|
||||||
}
|
}
|
||||||
@ -280,7 +276,7 @@ impl Decoder {
|
|||||||
|
|
||||||
fn handle_vp9s_video_frame(
|
fn handle_vp9s_video_frame(
|
||||||
decoder: &mut VpxDecoder,
|
decoder: &mut VpxDecoder,
|
||||||
vp9s: &VP9s,
|
vp9s: &EncodedVideoFrames,
|
||||||
rgb: &mut Vec<u8>,
|
rgb: &mut Vec<u8>,
|
||||||
) -> ResultType<bool> {
|
) -> ResultType<bool> {
|
||||||
let mut last_frame = Image::new();
|
let mut last_frame = Image::new();
|
||||||
@ -303,14 +299,14 @@ impl Decoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "hwcodec")]
|
#[cfg(feature = "hwcodec")]
|
||||||
fn handle_h264s_video_frame(
|
fn handle_hw_video_frame(
|
||||||
decoder: &mut HwDecoder,
|
decoder: &mut HwDecoder,
|
||||||
h264s: &H264s,
|
frames: &EncodedVideoFrames,
|
||||||
rgb: &mut Vec<u8>,
|
rgb: &mut Vec<u8>,
|
||||||
i420: &mut Vec<u8>,
|
i420: &mut Vec<u8>,
|
||||||
) -> ResultType<bool> {
|
) -> ResultType<bool> {
|
||||||
let mut ret = false;
|
let mut ret = false;
|
||||||
for h264 in h264s.h264s.iter() {
|
for h264 in frames.frames.iter() {
|
||||||
for image in decoder.decode(&h264.data)? {
|
for image in decoder.decode(&h264.data)? {
|
||||||
// TODO: just process the last frame
|
// TODO: just process the last frame
|
||||||
if image.bgra(rgb, i420).is_ok() {
|
if image.bgra(rgb, i420).is_ok() {
|
||||||
@ -320,25 +316,6 @@ impl Decoder {
|
|||||||
}
|
}
|
||||||
return Ok(ret);
|
return Ok(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "hwcodec")]
|
|
||||||
fn handle_h265s_video_frame(
|
|
||||||
decoder: &mut HwDecoder,
|
|
||||||
h265s: &H265s,
|
|
||||||
rgb: &mut Vec<u8>,
|
|
||||||
i420: &mut Vec<u8>,
|
|
||||||
) -> ResultType<bool> {
|
|
||||||
let mut ret = false;
|
|
||||||
for h265 in h265s.h265s.iter() {
|
|
||||||
for image in decoder.decode(&h265.data)? {
|
|
||||||
// TODO: just process the last frame
|
|
||||||
if image.bgra(rgb, i420).is_ok() {
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Ok(ret);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "hwcodec")]
|
#[cfg(feature = "hwcodec")]
|
||||||
|
@ -6,7 +6,7 @@ use hbb_common::{
|
|||||||
anyhow::{anyhow, Context},
|
anyhow::{anyhow, Context},
|
||||||
config::HwCodecConfig,
|
config::HwCodecConfig,
|
||||||
lazy_static, log,
|
lazy_static, log,
|
||||||
message_proto::{H264s, H265s, Message, VideoFrame, H264, H265},
|
message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame},
|
||||||
ResultType,
|
ResultType,
|
||||||
};
|
};
|
||||||
use hwcodec::{
|
use hwcodec::{
|
||||||
@ -17,10 +17,7 @@ use hwcodec::{
|
|||||||
Quality::{self, *},
|
Quality::{self, *},
|
||||||
RateContorl::{self, *},
|
RateContorl::{self, *},
|
||||||
};
|
};
|
||||||
use std::{
|
use std::sync::{Arc, Mutex};
|
||||||
collections::HashMap,
|
|
||||||
sync::{Arc, Mutex},
|
|
||||||
};
|
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
static ref HW_ENCODER_NAME: Arc<Mutex<Option<String>>> = Default::default();
|
static ref HW_ENCODER_NAME: Arc<Mutex<Option<String>>> = Default::default();
|
||||||
@ -91,49 +88,29 @@ impl EncoderApi for HwEncoder {
|
|||||||
) -> ResultType<hbb_common::message_proto::Message> {
|
) -> ResultType<hbb_common::message_proto::Message> {
|
||||||
let mut msg_out = Message::new();
|
let mut msg_out = Message::new();
|
||||||
let mut vf = VideoFrame::new();
|
let mut vf = VideoFrame::new();
|
||||||
match self.format {
|
let mut frames = Vec::new();
|
||||||
DataFormat::H264 => {
|
|
||||||
let mut h264s = Vec::new();
|
|
||||||
for frame in self.encode(frame).with_context(|| "Failed to encode")? {
|
for frame in self.encode(frame).with_context(|| "Failed to encode")? {
|
||||||
h264s.push(H264 {
|
frames.push(EncodedVideoFrame {
|
||||||
data: frame.data,
|
data: frame.data,
|
||||||
pts: frame.pts as _,
|
pts: frame.pts as _,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if h264s.len() > 0 {
|
if frames.len() > 0 {
|
||||||
vf.set_h264s(H264s {
|
let frames = EncodedVideoFrames {
|
||||||
h264s: h264s.into(),
|
frames: frames.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
};
|
||||||
|
match self.format {
|
||||||
|
DataFormat::H264 => vf.set_h264s(frames),
|
||||||
|
DataFormat::H265 => vf.set_h265s(frames),
|
||||||
|
}
|
||||||
msg_out.set_video_frame(vf);
|
msg_out.set_video_frame(vf);
|
||||||
Ok(msg_out)
|
Ok(msg_out)
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("no valid frame"))
|
Err(anyhow!("no valid frame"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataFormat::H265 => {
|
|
||||||
let mut h265s = Vec::new();
|
|
||||||
for frame in self.encode(frame).with_context(|| "Failed to encode")? {
|
|
||||||
h265s.push(H265 {
|
|
||||||
data: frame.data,
|
|
||||||
pts: frame.pts,
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if h265s.len() > 0 {
|
|
||||||
vf.set_h265s(H265s {
|
|
||||||
h265s,
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
msg_out.set_video_frame(vf);
|
|
||||||
Ok(msg_out)
|
|
||||||
} else {
|
|
||||||
Err(anyhow!("no valid frame"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn use_yuv(&self) -> bool {
|
fn use_yuv(&self) -> bool {
|
||||||
false
|
false
|
||||||
@ -174,7 +151,7 @@ impl HwEncoder {
|
|||||||
};
|
};
|
||||||
let encoders = CodecInfo::score(Encoder::avaliable_encoders(ctx));
|
let encoders = CodecInfo::score(Encoder::avaliable_encoders(ctx));
|
||||||
if write {
|
if write {
|
||||||
let _ = set_config(CFG_KEY_ENCODER, &encoders)
|
set_config(CFG_KEY_ENCODER, &encoders)
|
||||||
.map_err(|e| log::error!("{:?}", e))
|
.map_err(|e| log::error!("{:?}", e))
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
@ -326,7 +303,11 @@ impl HwDecoderImage<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_config(k: &str) -> ResultType<CodecInfos> {
|
fn get_config(k: &str) -> ResultType<CodecInfos> {
|
||||||
let v = HwCodecConfig::get_option(k);
|
let v = HwCodecConfig::load()
|
||||||
|
.options
|
||||||
|
.get(k)
|
||||||
|
.unwrap_or(&"".to_owned())
|
||||||
|
.to_owned();
|
||||||
match CodecInfos::deserialize(&v) {
|
match CodecInfos::deserialize(&v) {
|
||||||
Ok(v) => Ok(v),
|
Ok(v) => Ok(v),
|
||||||
Err(_) => Err(anyhow!("Failed to get config:{}", k)),
|
Err(_) => Err(anyhow!("Failed to get config:{}", k)),
|
||||||
@ -336,26 +317,28 @@ fn get_config(k: &str) -> ResultType<CodecInfos> {
|
|||||||
fn set_config(k: &str, v: &CodecInfos) -> ResultType<()> {
|
fn set_config(k: &str, v: &CodecInfos) -> ResultType<()> {
|
||||||
match v.serialize() {
|
match v.serialize() {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
HwCodecConfig::set_option(k.to_owned(), v);
|
let mut config = HwCodecConfig::load();
|
||||||
|
config.options.insert(k.to_owned(), v);
|
||||||
|
config.store();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Err(_) => Err(anyhow!("Failed to set config:{}", k)),
|
Err(_) => Err(anyhow!("Failed to set config:{}", k)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_config() -> Option<HashMap<String, String>> {
|
pub fn check_config() {
|
||||||
let (encoders, update_encoders) = HwEncoder::best(false, false);
|
let (encoders, update_encoders) = HwEncoder::best(false, false);
|
||||||
let (decoders, update_decoders) = HwDecoder::best(false, false);
|
let (decoders, update_decoders) = HwDecoder::best(false, false);
|
||||||
if update_encoders || update_decoders {
|
if update_encoders || update_decoders {
|
||||||
if let Ok(encoders) = encoders.serialize() {
|
if let Ok(encoders) = encoders.serialize() {
|
||||||
if let Ok(decoders) = decoders.serialize() {
|
if let Ok(decoders) = decoders.serialize() {
|
||||||
return Some(HashMap::from([
|
let mut config = HwCodecConfig::load();
|
||||||
(CFG_KEY_ENCODER.to_owned(), encoders),
|
config.options.insert(CFG_KEY_ENCODER.to_owned(), encoders);
|
||||||
(CFG_KEY_DECODER.to_owned(), decoders),
|
config.options.insert(CFG_KEY_DECODER.to_owned(), decoders);
|
||||||
]));
|
config.store();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log::error!("Failed to serialize codec info");
|
log::error!("Failed to serialize codec info");
|
||||||
}
|
}
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// https://github.com/rust-av/vpx-rs/blob/master/src/decoder.rs
|
// https://github.com/rust-av/vpx-rs/blob/master/src/decoder.rs
|
||||||
|
|
||||||
use hbb_common::anyhow::{anyhow, Context};
|
use hbb_common::anyhow::{anyhow, Context};
|
||||||
use hbb_common::message_proto::{Message, VP9s, VideoFrame, VP9};
|
use hbb_common::message_proto::{EncodedVideoFrame, EncodedVideoFrames, Message, VideoFrame};
|
||||||
use hbb_common::ResultType;
|
use hbb_common::ResultType;
|
||||||
|
|
||||||
use crate::codec::EncoderApi;
|
use crate::codec::EncoderApi;
|
||||||
@ -277,10 +277,10 @@ impl VpxEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn create_msg(vp9s: Vec<VP9>) -> Message {
|
fn create_msg(vp9s: Vec<EncodedVideoFrame>) -> Message {
|
||||||
let mut msg_out = Message::new();
|
let mut msg_out = Message::new();
|
||||||
let mut vf = VideoFrame::new();
|
let mut vf = VideoFrame::new();
|
||||||
vf.set_vp9s(VP9s {
|
vf.set_vp9s(EncodedVideoFrames {
|
||||||
frames: vp9s.into(),
|
frames: vp9s.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
@ -289,8 +289,8 @@ impl VpxEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn create_frame(frame: &EncodeFrame) -> VP9 {
|
fn create_frame(frame: &EncodeFrame) -> EncodedVideoFrame {
|
||||||
VP9 {
|
EncodedVideoFrame {
|
||||||
data: frame.data.to_vec(),
|
data: frame.data.to_vec(),
|
||||||
key: frame.key,
|
key: frame.key,
|
||||||
pts: frame.pts,
|
pts: frame.pts,
|
||||||
|
28
src/ipc.rs
28
src/ipc.rs
@ -1,8 +1,6 @@
|
|||||||
use crate::rendezvous_mediator::RendezvousMediator;
|
use crate::rendezvous_mediator::RendezvousMediator;
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
pub use clipboard::ClipbaordFile;
|
pub use clipboard::ClipbaordFile;
|
||||||
#[cfg(feature = "hwcodec")]
|
|
||||||
use hbb_common::config::HwCodecConfig;
|
|
||||||
use hbb_common::{
|
use hbb_common::{
|
||||||
allow_err, bail, bytes,
|
allow_err, bail, bytes,
|
||||||
bytes_codec::BytesCodec,
|
bytes_codec::BytesCodec,
|
||||||
@ -129,8 +127,6 @@ pub enum Data {
|
|||||||
ClipbaordFile(ClipbaordFile),
|
ClipbaordFile(ClipbaordFile),
|
||||||
ClipboardFileEnabled(bool),
|
ClipboardFileEnabled(bool),
|
||||||
PrivacyModeState((i32, PrivacyModeState)),
|
PrivacyModeState((i32, PrivacyModeState)),
|
||||||
#[cfg(feature = "hwcodec")]
|
|
||||||
HwCodecConfig(Option<HashMap<String, String>>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
@ -340,12 +336,7 @@ async fn handle(data: Data, stream: &mut Connection) {
|
|||||||
.await
|
.await
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "hwcodec")]
|
|
||||||
Data::HwCodecConfig(Some(config)) => {
|
|
||||||
for (k, v) in config {
|
|
||||||
HwCodecConfig::set_option(k, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -645,20 +636,3 @@ pub async fn set_socks(value: config::Socks5Server) -> ResultType<()> {
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "hwcodec")]
|
|
||||||
#[tokio::main]
|
|
||||||
pub async fn check_hwcodec_config() {
|
|
||||||
if let Some(config) = scrap::hwcodec::check_config() {
|
|
||||||
match connect(1000, "").await {
|
|
||||||
Ok(mut conn) => {
|
|
||||||
if conn.send(&Data::HwCodecConfig(Some(config))).await.is_err() {
|
|
||||||
log::error!("Failed to send hwcodec config by ipc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
log::info!("Failed to connect ipc: {:?}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
17
src/main.rs
17
src/main.rs
@ -70,15 +70,6 @@ fn main() {
|
|||||||
}
|
}
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
std::thread::spawn(move || start_server(false));
|
std::thread::spawn(move || start_server(false));
|
||||||
#[cfg(feature = "hwcodec")]
|
|
||||||
if let Ok(exe) = std::env::current_exe() {
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
std::process::Command::new(exe)
|
|
||||||
.arg("--check-hwcodec-config")
|
|
||||||
.status()
|
|
||||||
.ok()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
@ -117,10 +108,6 @@ fn main() {
|
|||||||
args.len() > 1,
|
args.len() > 1,
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
} else if args[0] == "--check-hwcodec-config" {
|
|
||||||
#[cfg(feature = "hwcodec")]
|
|
||||||
ipc::check_hwcodec_config();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if args[0] == "--remove" {
|
if args[0] == "--remove" {
|
||||||
@ -164,6 +151,10 @@ fn main() {
|
|||||||
ipc::set_password(args[1].to_owned()).unwrap();
|
ipc::set_password(args[1].to_owned()).unwrap();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
} else if args[0] == "--check-hwcodec-config" {
|
||||||
|
#[cfg(feature = "hwcodec")]
|
||||||
|
scrap::hwcodec::check_config();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ui::start(&mut args[..]);
|
ui::start(&mut args[..]);
|
||||||
|
@ -321,6 +321,15 @@ pub async fn start_server(is_server: bool) {
|
|||||||
std::process::exit(-1);
|
std::process::exit(-1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
#[cfg(feature = "hwcodec")]
|
||||||
|
if let Ok(exe) = std::env::current_exe() {
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
std::process::Command::new(exe)
|
||||||
|
.arg("--check-hwcodec-config")
|
||||||
|
.status()
|
||||||
|
.ok()
|
||||||
|
});
|
||||||
|
}
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
crate::platform::windows::bootstrap();
|
crate::platform::windows::bootstrap();
|
||||||
input_service::fix_key_down_timeout_loop();
|
input_service::fix_key_down_timeout_loop();
|
||||||
|
@ -573,10 +573,10 @@ fn check_privacy_mode_changed(sp: &GenericService, privacy_mode_id: i32) -> Resu
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||||
fn create_msg(vp9s: Vec<VP9>) -> Message {
|
fn create_msg(vp9s: Vec<EncodedVideoFrame>) -> Message {
|
||||||
let mut msg_out = Message::new();
|
let mut msg_out = Message::new();
|
||||||
let mut vf = VideoFrame::new();
|
let mut vf = VideoFrame::new();
|
||||||
vf.set_vp9s(VP9s {
|
vf.set_vp9s(EncodedVideoFrames {
|
||||||
frames: vp9s.into(),
|
frames: vp9s.into(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
@ -622,7 +622,7 @@ pub fn handle_one_frame_encoded(
|
|||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
let mut send_conn_ids: HashSet<i32> = Default::default();
|
let mut send_conn_ids: HashSet<i32> = Default::default();
|
||||||
let vp9_frame = VP9 {
|
let vp9_frame = EncodedVideoFrame {
|
||||||
data: frame.to_vec(),
|
data: frame.to_vec(),
|
||||||
key: true,
|
key: true,
|
||||||
pts: ms,
|
pts: ms,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user