* Adjust bitrate and fps based on TestDelay messages.
* Bitrate is adjusted every 3 seconds, fps is adjusted every second and when receiving test lag.
* Latency optimized at high resolutions. However, when the network is poor, the delay when just connecting or sliding static pages is still obvious.

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages
2025-01-20 17:59:36 +08:00
committed by GitHub
parent c44803f5b0
commit 5fa8c25e65
10 changed files with 735 additions and 548 deletions

View File

@@ -5,7 +5,7 @@ use std::{
};
use crate::{
codec::{base_bitrate, enable_vram_option, EncoderApi, EncoderCfg, Quality},
codec::{base_bitrate, enable_vram_option, EncoderApi, EncoderCfg},
hwcodec::HwCodecConfig,
AdapterDevice, CodecFormat, EncodeInput, EncodeYuvFormat, Pixfmt,
};
@@ -17,7 +17,7 @@ use hbb_common::{
ResultType,
};
use hwcodec::{
common::{AdapterVendor::*, DataFormat, Driver, MAX_GOP},
common::{DataFormat, Driver, MAX_GOP},
vram::{
decode::{self, DecodeFrame, Decoder},
encode::{self, EncodeFrame, Encoder},
@@ -39,7 +39,7 @@ pub struct VRamEncoderConfig {
pub device: AdapterDevice,
pub width: usize,
pub height: usize,
pub quality: Quality,
pub quality: f32,
pub feature: FeatureContext,
pub keyframe_interval: Option<usize>,
}
@@ -51,7 +51,6 @@ pub struct VRamEncoder {
bitrate: u32,
last_frame_len: usize,
same_bad_len_counter: usize,
config: VRamEncoderConfig,
}
impl EncoderApi for VRamEncoder {
@@ -61,12 +60,12 @@ impl EncoderApi for VRamEncoder {
{
match cfg {
EncoderCfg::VRAM(config) => {
let b = Self::convert_quality(config.quality, &config.feature);
let base_bitrate = base_bitrate(config.width as _, config.height as _);
let mut bitrate = base_bitrate * b / 100;
if bitrate <= 0 {
bitrate = base_bitrate;
}
let bitrate = Self::bitrate(
config.feature.data_format,
config.width,
config.height,
config.quality,
);
let gop = config.keyframe_interval.unwrap_or(MAX_GOP as _) as i32;
let ctx = EncodeContext {
f: config.feature.clone(),
@@ -87,7 +86,6 @@ impl EncoderApi for VRamEncoder {
bitrate,
last_frame_len: 0,
same_bad_len_counter: 0,
config,
}),
Err(_) => Err(anyhow!(format!("Failed to create encoder"))),
}
@@ -172,9 +170,13 @@ impl EncoderApi for VRamEncoder {
true
}
fn set_quality(&mut self, quality: Quality) -> ResultType<()> {
let b = Self::convert_quality(quality, &self.ctx.f);
let bitrate = base_bitrate(self.ctx.d.width as _, self.ctx.d.height as _) * b / 100;
fn set_quality(&mut self, ratio: f32) -> ResultType<()> {
let bitrate = Self::bitrate(
self.ctx.f.data_format,
self.ctx.d.width as _,
self.ctx.d.height as _,
ratio,
);
if bitrate > 0 {
if self.encoder.set_bitrate((bitrate) as _).is_ok() {
self.bitrate = bitrate;
@@ -187,10 +189,6 @@ impl EncoderApi for VRamEncoder {
self.bitrate
}
fn support_abr(&self) -> bool {
self.config.device.vendor_id != ADAPTER_VENDOR_INTEL as u32
}
fn support_changing_quality(&self) -> bool {
true
}
@@ -285,31 +283,8 @@ impl VRamEncoder {
}
}
pub fn convert_quality(quality: Quality, f: &FeatureContext) -> u32 {
match quality {
Quality::Best => {
if f.driver == Driver::MFX && f.data_format == DataFormat::H264 {
200
} else {
150
}
}
Quality::Balanced => {
if f.driver == Driver::MFX && f.data_format == DataFormat::H264 {
150
} else {
100
}
}
Quality::Low => {
if f.driver == Driver::MFX && f.data_format == DataFormat::H264 {
75
} else {
50
}
}
Quality::Custom(b) => b,
}
pub fn bitrate(fmt: DataFormat, width: usize, height: usize, ratio: f32) -> u32 {
crate::hwcodec::HwRamEncoder::calc_bitrate(width, height, ratio, fmt == DataFormat::H264)
}
pub fn set_not_use(display: usize, not_use: bool) {