sync codec format
This commit is contained in:
parent
75fc49b301
commit
eaaeefd90b
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user