client side handle codec format
This commit is contained in:
parent
6c9e601c59
commit
5bd08bf0a7
@ -479,18 +479,10 @@ message OptionMessage {
|
||||
}
|
||||
|
||||
message TestDelay {
|
||||
enum CodecFormat {
|
||||
Unknown = 0;
|
||||
VP8 = 1;
|
||||
VP9 = 2;
|
||||
H264 = 3;
|
||||
H265 = 4;
|
||||
}
|
||||
int64 time = 1;
|
||||
bool from_client = 2;
|
||||
uint32 last_delay = 3;
|
||||
uint32 target_bitrate = 4;
|
||||
CodecFormat codec_format = 5;
|
||||
}
|
||||
|
||||
message PublicKey {
|
||||
|
@ -12,7 +12,7 @@ use crate::vpxcodec::*;
|
||||
use hbb_common::{
|
||||
anyhow::anyhow,
|
||||
log,
|
||||
message_proto::{test_delay, video_frame, Message, VP9s, VideoCodecState},
|
||||
message_proto::{video_frame, Message, VP9s, VideoCodecState},
|
||||
ResultType,
|
||||
};
|
||||
#[cfg(feature = "hwcodec")]
|
||||
@ -53,8 +53,6 @@ pub trait EncoderApi {
|
||||
fn use_yuv(&self) -> bool;
|
||||
|
||||
fn set_bitrate(&mut self, bitrate: u32) -> ResultType<()>;
|
||||
|
||||
fn get_codec_format(&self) -> test_delay::CodecFormat;
|
||||
}
|
||||
|
||||
pub struct DecoderCfg {
|
||||
|
@ -6,7 +6,7 @@ use hbb_common::{
|
||||
anyhow::{anyhow, Context},
|
||||
config::HwCodecConfig,
|
||||
lazy_static, log,
|
||||
message_proto::{test_delay, H264s, H265s, Message, VideoFrame, H264, H265},
|
||||
message_proto::{H264s, H265s, Message, VideoFrame, H264, H265},
|
||||
ResultType,
|
||||
};
|
||||
use hwcodec::{
|
||||
@ -143,13 +143,6 @@ impl EncoderApi for HwEncoder {
|
||||
self.encoder.set_bitrate((bitrate * 1000) as _).ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_codec_format(&self) -> test_delay::CodecFormat {
|
||||
match self.format {
|
||||
DataFormat::H264 => test_delay::CodecFormat::H264,
|
||||
DataFormat::H265 => test_delay::CodecFormat::H265,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HwEncoder {
|
||||
|
@ -3,7 +3,7 @@
|
||||
// https://github.com/rust-av/vpx-rs/blob/master/src/decoder.rs
|
||||
|
||||
use hbb_common::anyhow::{anyhow, Context};
|
||||
use hbb_common::message_proto::{test_delay, Message, VP9s, VideoFrame, VP9};
|
||||
use hbb_common::message_proto::{Message, VP9s, VideoFrame, VP9};
|
||||
use hbb_common::ResultType;
|
||||
|
||||
use crate::codec::EncoderApi;
|
||||
@ -27,7 +27,6 @@ impl Default for VpxVideoCodecId {
|
||||
|
||||
pub struct VpxEncoder {
|
||||
ctx: vpx_codec_ctx_t,
|
||||
format: VpxVideoCodecId,
|
||||
width: usize,
|
||||
height: usize,
|
||||
}
|
||||
@ -97,17 +96,14 @@ impl EncoderApi for VpxEncoder {
|
||||
{
|
||||
match cfg {
|
||||
crate::codec::EncoderCfg::VPX(config) => {
|
||||
let format;
|
||||
let i;
|
||||
if cfg!(feature = "VP8") {
|
||||
i = match config.codec {
|
||||
VpxVideoCodecId::VP8 => call_vpx_ptr!(vpx_codec_vp8_cx()),
|
||||
VpxVideoCodecId::VP9 => call_vpx_ptr!(vpx_codec_vp9_cx()),
|
||||
};
|
||||
format = config.codec;
|
||||
} else {
|
||||
i = call_vpx_ptr!(vpx_codec_vp9_cx());
|
||||
format = VpxVideoCodecId::VP9;
|
||||
}
|
||||
let mut c = unsafe { std::mem::MaybeUninit::zeroed().assume_init() };
|
||||
call_vpx!(vpx_codec_enc_config_default(i, &mut c, 0));
|
||||
@ -194,7 +190,6 @@ impl EncoderApi for VpxEncoder {
|
||||
|
||||
Ok(Self {
|
||||
ctx,
|
||||
format,
|
||||
width: config.width as _,
|
||||
height: config.height as _,
|
||||
})
|
||||
@ -233,13 +228,6 @@ impl EncoderApi for VpxEncoder {
|
||||
call_vpx!(vpx_codec_enc_config_set(&mut self.ctx, &new_enc_cfg));
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn get_codec_format(&self) -> test_delay::CodecFormat {
|
||||
match self.format {
|
||||
VpxVideoCodecId::VP8 => test_delay::CodecFormat::VP8,
|
||||
VpxVideoCodecId::VP9 => test_delay::CodecFormat::VP9,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VpxEncoder {
|
||||
|
@ -40,7 +40,7 @@ pub use super::lang::*;
|
||||
pub mod file_trait;
|
||||
pub use file_trait::FileManager;
|
||||
pub mod helper;
|
||||
pub use helper::LatencyController;
|
||||
pub use helper::*;
|
||||
pub const SEC30: Duration = Duration::from_secs(30);
|
||||
|
||||
pub struct Client;
|
||||
|
@ -3,7 +3,7 @@ use std::{
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use hbb_common::log;
|
||||
use hbb_common::{log, message_proto::{VideoFrame, video_frame}};
|
||||
|
||||
const MAX_LATENCY: i64 = 500;
|
||||
const MIN_LATENCY: i64 = 100;
|
||||
@ -57,3 +57,33 @@ impl LatencyController {
|
||||
self.allow_audio
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone)]
|
||||
pub enum CodecFormat {
|
||||
VP9,
|
||||
H264,
|
||||
H265,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl From<&VideoFrame> for CodecFormat {
|
||||
fn from(it: &VideoFrame) -> Self {
|
||||
match it.union {
|
||||
Some(video_frame::Union::vp9s(_)) => CodecFormat::VP9,
|
||||
Some(video_frame::Union::h264s(_)) => CodecFormat::H264,
|
||||
Some(video_frame::Union::h265s(_)) => CodecFormat::H265,
|
||||
_ => CodecFormat::Unknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for CodecFormat {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
CodecFormat::VP9 => "VP9".into(),
|
||||
CodecFormat::H264 => "H264".into(),
|
||||
CodecFormat::H265 => "H265".into(),
|
||||
CodecFormat::Unknown => "Unknow".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +380,6 @@ impl Connection {
|
||||
time,
|
||||
last_delay:qos.current_delay,
|
||||
target_bitrate:qos.target_bitrate,
|
||||
codec_format:qos.codec_format.into(),
|
||||
..Default::default()
|
||||
});
|
||||
conn.inner.send(msg_out.into());
|
||||
|
@ -73,7 +73,6 @@ pub struct VideoQoS {
|
||||
user_image_quality: u32,
|
||||
current_image_quality: u32,
|
||||
enable_abr: bool,
|
||||
pub codec_format: test_delay::CodecFormat,
|
||||
pub current_delay: u32,
|
||||
pub fps: u8, // abr
|
||||
pub target_bitrate: u32, // abr
|
||||
@ -111,7 +110,6 @@ impl Default for VideoQoS {
|
||||
user_image_quality: ImageQuality::Balanced.as_percent(),
|
||||
current_image_quality: ImageQuality::Balanced.as_percent(),
|
||||
enable_abr: false,
|
||||
codec_format: Default::default(),
|
||||
width: 0,
|
||||
height: 0,
|
||||
current_delay: 0,
|
||||
@ -564,7 +562,7 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
let mut spf = video_qos.spf();
|
||||
let bitrate = video_qos.generate_bitrate()?;
|
||||
let abr = video_qos.check_abr_config();
|
||||
|
||||
drop(video_qos);
|
||||
log::info!("init bitrate={}, abr enabled:{}", bitrate, abr);
|
||||
|
||||
let encoder_cfg = match Encoder::current_hw_encoder_name() {
|
||||
@ -589,10 +587,7 @@ fn run(sp: GenericService) -> ResultType<()> {
|
||||
Ok(x) => encoder = x,
|
||||
Err(err) => bail!("Failed to create encoder: {}", err),
|
||||
}
|
||||
|
||||
video_qos.codec_format = encoder.get_codec_format();
|
||||
drop(video_qos);
|
||||
|
||||
|
||||
let privacy_mode_id = *PRIVACY_MODE_CONN_ID.lock().unwrap();
|
||||
#[cfg(not(windows))]
|
||||
let captuerer_privacy_mode_id = privacy_mode_id;
|
||||
|
@ -234,25 +234,13 @@ impl sciter::EventHandler for Handler {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
struct QualityStatus {
|
||||
speed: String,
|
||||
fps: i32,
|
||||
delay: i32,
|
||||
target_bitrate: i32,
|
||||
codec_format: test_delay::CodecFormat,
|
||||
}
|
||||
|
||||
impl Default for QualityStatus {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
speed: Default::default(),
|
||||
fps: -1,
|
||||
delay: -1,
|
||||
target_bitrate: -1,
|
||||
codec_format: test_delay::CodecFormat::Unknown,
|
||||
}
|
||||
}
|
||||
speed: Option<String>,
|
||||
fps: Option<i32>,
|
||||
delay: Option<i32>,
|
||||
target_bitrate: Option<i32>,
|
||||
codec_format: Option<CodecFormat>,
|
||||
}
|
||||
|
||||
impl Handler {
|
||||
@ -271,21 +259,16 @@ impl Handler {
|
||||
}
|
||||
|
||||
fn update_quality_status(&self, status: QualityStatus) {
|
||||
let codec_format = match status.codec_format {
|
||||
test_delay::CodecFormat::Unknown => "Unknown",
|
||||
test_delay::CodecFormat::VP8 => "VP8",
|
||||
test_delay::CodecFormat::VP9 => "VP9",
|
||||
test_delay::CodecFormat::H264 => "H264",
|
||||
test_delay::CodecFormat::H265 => "H265",
|
||||
};
|
||||
self.call2(
|
||||
"updateQualityStatus",
|
||||
&make_args!(
|
||||
status.speed,
|
||||
status.fps,
|
||||
status.delay,
|
||||
status.target_bitrate,
|
||||
codec_format
|
||||
status.speed.map_or(Value::null(), |it| it.into()),
|
||||
status.fps.map_or(Value::null(), |it| it.into()),
|
||||
status.delay.map_or(Value::null(), |it| it.into()),
|
||||
status.target_bitrate.map_or(Value::null(), |it| it.into()),
|
||||
status
|
||||
.codec_format
|
||||
.map_or(Value::null(), |it| it.to_string().into())
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -1365,6 +1348,7 @@ async fn io_loop(handler: Handler) {
|
||||
clipboard_file_context: None,
|
||||
data_count: Arc::new(AtomicUsize::new(0)),
|
||||
frame_count,
|
||||
video_format: CodecFormat::Unknown,
|
||||
};
|
||||
remote.io_loop(&key, &token).await;
|
||||
remote.sync_jobs_status_to_local().await;
|
||||
@ -1417,6 +1401,7 @@ struct Remote {
|
||||
clipboard_file_context: Option<Box<CliprdrClientContext>>,
|
||||
data_count: Arc<AtomicUsize>,
|
||||
frame_count: Arc<AtomicUsize>,
|
||||
video_format: CodecFormat,
|
||||
}
|
||||
|
||||
impl Remote {
|
||||
@ -1506,8 +1491,8 @@ impl Remote {
|
||||
let speed = format!("{:.2}kB/s", speed as f32 / 1024 as f32);
|
||||
let fps = self.frame_count.swap(0, Ordering::Relaxed) as _;
|
||||
self.handler.update_quality_status(QualityStatus {
|
||||
speed,
|
||||
fps,
|
||||
speed:Some(speed),
|
||||
fps:Some(fps),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
@ -2038,6 +2023,14 @@ impl Remote {
|
||||
self.handler.call2("closeSuccess", &make_args!());
|
||||
self.handler.call("adaptSize", &make_args!());
|
||||
}
|
||||
let incomming_format = CodecFormat::from(&vf);
|
||||
if self.video_format != incomming_format {
|
||||
self.video_format = incomming_format.clone();
|
||||
self.handler.update_quality_status(QualityStatus {
|
||||
codec_format: Some(incomming_format),
|
||||
..Default::default()
|
||||
})
|
||||
};
|
||||
self.video_sender.send(MediaData::VideoFrame(vf)).ok();
|
||||
}
|
||||
Some(message::Union::hash(hash)) => {
|
||||
@ -2612,9 +2605,8 @@ impl Interface for Handler {
|
||||
async fn handle_test_delay(&mut self, t: TestDelay, peer: &mut Stream) {
|
||||
if !t.from_client {
|
||||
self.update_quality_status(QualityStatus {
|
||||
delay: t.last_delay as _,
|
||||
target_bitrate: t.target_bitrate as _,
|
||||
codec_format: t.codec_format.enum_value_or_default(),
|
||||
delay: Some(t.last_delay as _),
|
||||
target_bitrate: Some(t.target_bitrate as _),
|
||||
..Default::default()
|
||||
});
|
||||
handle_test_delay(t, peer).await;
|
||||
|
@ -492,10 +492,10 @@ class QualityMonitor: Reactor.Component
|
||||
$(#quality-monitor).content(<QualityMonitor />);
|
||||
handler.updateQualityStatus = function(speed, fps, delay, bitrate, codec_format) {
|
||||
speed ? qualityMonitorData[0] = speed:null;
|
||||
fps > -1 ? qualityMonitorData[1] = fps:null;
|
||||
delay > -1 ? qualityMonitorData[2] = delay:null;
|
||||
bitrate > -1 ? qualityMonitorData[3] = bitrate:null;
|
||||
codec_format != "Unknown" ? qualityMonitorData[4] = codec_format:null;
|
||||
fps ? qualityMonitorData[1] = fps:null;
|
||||
delay ? qualityMonitorData[2] = delay:null;
|
||||
bitrate ? qualityMonitorData[3] = bitrate:null;
|
||||
codec_format ? qualityMonitorData[4] = codec_format:null;
|
||||
qualityMonitor.update();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user