sync codec format

This commit is contained in:
csf 2022-06-29 23:36:45 +08:00
parent 75fc49b301
commit eaaeefd90b
8 changed files with 61 additions and 10 deletions

View File

@ -479,10 +479,18 @@ message OptionMessage {
} }
message TestDelay { message TestDelay {
enum CodecFormat {
Unknown = 0;
VP8 = 1;
VP9 = 2;
H264 = 3;
H265 = 4;
}
int64 time = 1; int64 time = 1;
bool from_client = 2; bool from_client = 2;
uint32 last_delay = 3; uint32 last_delay = 3;
uint32 target_bitrate = 4; uint32 target_bitrate = 4;
CodecFormat codec_format = 5;
} }
message PublicKey { message PublicKey {

View File

@ -12,7 +12,7 @@ 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, Message, VP9s, VideoCodecState, test_delay},
ResultType, ResultType,
}; };
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
@ -52,6 +52,8 @@ pub trait EncoderApi {
fn use_yuv(&self) -> bool; fn use_yuv(&self) -> bool;
fn set_bitrate(&mut self, bitrate: u32) -> ResultType<()>; fn set_bitrate(&mut self, bitrate: u32) -> ResultType<()>;
fn get_codec_format(&self) -> test_delay::CodecFormat;
} }
pub struct DecoderCfg { pub struct DecoderCfg {

View File

@ -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::{test_delay, H264s, H265s, Message, VideoFrame, H264, H265},
ResultType, ResultType,
}; };
use hwcodec::{ use hwcodec::{
@ -143,6 +143,13 @@ impl EncoderApi for HwEncoder {
self.encoder.set_bitrate((bitrate * 1000) as _).ok(); self.encoder.set_bitrate((bitrate * 1000) as _).ok();
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 { impl HwEncoder {

View File

@ -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::{Message, VP9s, VideoFrame, VP9, test_delay};
use hbb_common::ResultType; use hbb_common::ResultType;
use crate::codec::EncoderApi; use crate::codec::EncoderApi;
@ -27,6 +27,7 @@ impl Default for VpxVideoCodecId {
pub struct VpxEncoder { pub struct VpxEncoder {
ctx: vpx_codec_ctx_t, ctx: vpx_codec_ctx_t,
format: VpxVideoCodecId,
width: usize, width: usize,
height: usize, height: usize,
} }
@ -96,14 +97,17 @@ impl EncoderApi for VpxEncoder {
{ {
match cfg { match cfg {
crate::codec::EncoderCfg::VPX(config) => { crate::codec::EncoderCfg::VPX(config) => {
let format;
let i; let i;
if cfg!(feature = "VP8") { if cfg!(feature = "VP8") {
i = match config.codec { i = match config.codec {
VpxVideoCodecId::VP8 => call_vpx_ptr!(vpx_codec_vp8_cx()), VpxVideoCodecId::VP8 => call_vpx_ptr!(vpx_codec_vp8_cx()),
VpxVideoCodecId::VP9 => call_vpx_ptr!(vpx_codec_vp9_cx()), VpxVideoCodecId::VP9 => call_vpx_ptr!(vpx_codec_vp9_cx()),
}; };
format = config.codec;
} else { } else {
i = call_vpx_ptr!(vpx_codec_vp9_cx()); i = call_vpx_ptr!(vpx_codec_vp9_cx());
format = VpxVideoCodecId::VP9;
} }
let mut c = unsafe { std::mem::MaybeUninit::zeroed().assume_init() }; let mut c = unsafe { std::mem::MaybeUninit::zeroed().assume_init() };
call_vpx!(vpx_codec_enc_config_default(i, &mut c, 0)); call_vpx!(vpx_codec_enc_config_default(i, &mut c, 0));
@ -190,6 +194,7 @@ impl EncoderApi for VpxEncoder {
Ok(Self { Ok(Self {
ctx, ctx,
format,
width: config.width as _, width: config.width as _,
height: config.height as _, height: config.height as _,
}) })
@ -228,6 +233,13 @@ impl EncoderApi for VpxEncoder {
call_vpx!(vpx_codec_enc_config_set(&mut self.ctx, &new_enc_cfg)); call_vpx!(vpx_codec_enc_config_set(&mut self.ctx, &new_enc_cfg));
return Ok(()); 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 { impl VpxEncoder {

View File

@ -380,6 +380,7 @@ impl Connection {
time, time,
last_delay:qos.current_delay, last_delay:qos.current_delay,
target_bitrate:qos.target_bitrate, target_bitrate:qos.target_bitrate,
codec_format:qos.codec_format.into(),
..Default::default() ..Default::default()
}); });
conn.inner.send(msg_out.into()); conn.inner.send(msg_out.into());

View File

@ -72,11 +72,11 @@ pub struct VideoQoS {
height: u32, height: u32,
user_image_quality: u32, user_image_quality: u32,
current_image_quality: u32, current_image_quality: u32,
enable_abr: bool,
pub codec_format: test_delay::CodecFormat,
pub current_delay: u32, pub current_delay: u32,
pub fps: u8, // abr pub fps: u8, // abr
pub target_bitrate: u32, // abr pub target_bitrate: u32, // abr
updated: bool, updated: bool,
state: DelayState, state: DelayState,
debounce_count: u32, debounce_count: u32,
@ -110,6 +110,8 @@ impl Default for VideoQoS {
fps: FPS, fps: FPS,
user_image_quality: ImageQuality::Balanced.as_percent(), user_image_quality: ImageQuality::Balanced.as_percent(),
current_image_quality: ImageQuality::Balanced.as_percent(), current_image_quality: ImageQuality::Balanced.as_percent(),
enable_abr: false,
codec_format: Default::default(),
width: 0, width: 0,
height: 0, height: 0,
current_delay: 0, current_delay: 0,
@ -145,14 +147,16 @@ impl VideoQoS {
self.current_delay = delay / 2 + self.current_delay / 2; self.current_delay = delay / 2 + self.current_delay / 2;
log::trace!( log::trace!(
"VideoQoS update_network_delay:{}, {}, state:{:?},count:{}", "VideoQoS update_network_delay:{}, {}, state:{:?}",
self.current_delay, self.current_delay,
delay, delay,
self.state, self.state,
self.debounce_count
); );
// ABR // ABR
if !self.enable_abr {
return;
}
let current_state = DelayState::from_delay(self.current_delay); let current_state = DelayState::from_delay(self.current_delay);
if current_state != self.state && self.debounce_count > 5 { if current_state != self.state && self.debounce_count > 5 {
log::debug!( log::debug!(
@ -544,7 +548,6 @@ fn run(sp: GenericService) -> ResultType<()> {
video_qos.set_size(width as _, height as _); video_qos.set_size(width as _, height as _);
let mut spf = video_qos.spf(); let mut spf = video_qos.spf();
let bitrate = video_qos.generate_bitrate()?; let bitrate = video_qos.generate_bitrate()?;
drop(video_qos);
log::info!("init bitrate={}", bitrate); log::info!("init bitrate={}", bitrate);
@ -571,6 +574,9 @@ fn run(sp: GenericService) -> ResultType<()> {
Err(err) => bail!("Failed to create encoder: {}", err), 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(); let privacy_mode_id = *PRIVACY_MODE_CONN_ID.lock().unwrap();
#[cfg(not(windows))] #[cfg(not(windows))]
let captuerer_privacy_mode_id = privacy_mode_id; let captuerer_privacy_mode_id = privacy_mode_id;

View File

@ -240,6 +240,7 @@ struct QualityStatus {
fps: i32, fps: i32,
delay: i32, delay: i32,
target_bitrate: i32, target_bitrate: i32,
codec_format: test_delay::CodecFormat,
} }
impl Default for QualityStatus { impl Default for QualityStatus {
@ -249,6 +250,7 @@ impl Default for QualityStatus {
fps: -1, fps: -1,
delay: -1, delay: -1,
target_bitrate: -1, target_bitrate: -1,
codec_format: test_delay::CodecFormat::Unknown,
} }
} }
} }
@ -269,13 +271,21 @@ impl Handler {
} }
fn update_quality_status(&self, status: QualityStatus) { 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( self.call2(
"updateQualityStatus", "updateQualityStatus",
&make_args!( &make_args!(
status.speed, status.speed,
status.fps, status.fps,
status.delay, status.delay,
status.target_bitrate status.target_bitrate,
codec_format
), ),
); );
} }
@ -2604,6 +2614,7 @@ impl Interface for Handler {
self.update_quality_status(QualityStatus { self.update_quality_status(QualityStatus {
delay: t.last_delay as _, delay: t.last_delay as _,
target_bitrate: t.target_bitrate as _, target_bitrate: t.target_bitrate as _,
codec_format: t.codec_format.enum_value_or_default(),
..Default::default() ..Default::default()
}); });
let mut msg_out = Message::new(); let mut msg_out = Message::new();

View File

@ -482,16 +482,20 @@ class QualityMonitor: Reactor.Component
<div> <div>
Target Bitrate: {qualityMonitorData[3]}kb Target Bitrate: {qualityMonitorData[3]}kb
</div> </div>
<div>
Codec: {qualityMonitorData[4]}
</div>
</div>; </div>;
} }
} }
$(#quality-monitor).content(<QualityMonitor />); $(#quality-monitor).content(<QualityMonitor />);
handler.updateQualityStatus = function(speed, fps, delay, bitrate) { handler.updateQualityStatus = function(speed, fps, delay, bitrate, codec_format) {
speed ? qualityMonitorData[0] = speed:null; speed ? qualityMonitorData[0] = speed:null;
fps > -1 ? qualityMonitorData[1] = fps:null; fps > -1 ? qualityMonitorData[1] = fps:null;
delay > -1 ? qualityMonitorData[2] = delay:null; delay > -1 ? qualityMonitorData[2] = delay:null;
bitrate > -1 ? qualityMonitorData[3] = bitrate:null; bitrate > -1 ? qualityMonitorData[3] = bitrate:null;
codec_format != "Unknown" ? qualityMonitorData[4] = codec_format:null;
qualityMonitor.update(); qualityMonitor.update();
} }