opt av1 test data (#9954)

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages 2024-11-18 15:05:23 +08:00 committed by GitHub
parent a07392e6b8
commit 0707e791e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -2,6 +2,7 @@ use std::{
collections::HashMap,
ops::{Deref, DerefMut},
sync::{Arc, Mutex},
time::Instant,
};
#[cfg(feature = "hwcodec")]
@ -27,7 +28,6 @@ use hbb_common::{
SupportedDecoding, SupportedEncoding, VideoFrame,
},
sysinfo::System,
tokio::time::Instant,
ResultType,
};
@ -990,7 +990,9 @@ fn disable_av1() -> bool {
#[cfg(not(target_os = "ios"))]
pub fn test_av1() {
use hbb_common::config::keys::OPTION_AV1_TEST;
use std::sync::Once;
use hbb_common::rand::Rng;
use std::{sync::Once, time::Duration};
if disable_av1() || !Config::get_option(OPTION_AV1_TEST).is_empty() {
log::info!("skip test av1");
return;
@ -1001,6 +1003,56 @@ pub fn test_av1() {
let f = || {
let (width, height, quality, keyframe_interval, i444) =
(1920, 1080, Quality::Balanced, None, false);
let frame_count = 10;
let block_size = 300;
let move_step = 50;
let generate_fake_data =
|frame_index: u32, dst_fmt: EncodeYuvFormat| -> ResultType<Vec<u8>> {
let mut rng = hbb_common::rand::thread_rng();
let mut bgra = vec![0u8; (width * height * 4) as usize];
let gradient = frame_index as f32 / frame_count as f32;
// floating block
let x0 = (frame_index * move_step) % (width - block_size);
let y0 = (frame_index * move_step) % (height - block_size);
// Fill the block with random colors
for y in 0..block_size {
for x in 0..block_size {
let index = (((y0 + y) * width + x0 + x) * 4) as usize;
if index + 3 < bgra.len() {
let noise = rng.gen_range(0..255) as f32 / 255.0;
let value = (255.0 * gradient + noise * 50.0) as u8;
bgra[index] = value;
bgra[index + 1] = value;
bgra[index + 2] = value;
bgra[index + 3] = 255;
}
}
}
let dst_stride_y = dst_fmt.stride[0];
let dst_stride_uv = dst_fmt.stride[1];
let mut dst = vec![0u8; (dst_fmt.h * dst_stride_y * 2) as usize];
let dst_y = dst.as_mut_ptr();
let dst_u = dst[dst_fmt.u..].as_mut_ptr();
let dst_v = dst[dst_fmt.v..].as_mut_ptr();
let res = unsafe {
crate::ARGBToI420(
bgra.as_ptr(),
(width * 4) as _,
dst_y,
dst_stride_y as _,
dst_u,
dst_stride_uv as _,
dst_v,
dst_stride_uv as _,
width as _,
height as _,
)
};
if res != 0 {
bail!("ARGBToI420 failed: {}", res);
}
Ok(dst)
};
let Ok(mut av1) = AomEncoder::new(
EncoderCfg::AOM(AomEncoderConfig {
width,
@ -1012,52 +1064,39 @@ pub fn test_av1() {
) else {
return false;
};
let Ok(mut vp9) = VpxEncoder::new(
EncoderCfg::VPX(VpxEncoderConfig {
codec: VpxVideoCodecId::VP9,
width,
height,
quality,
keyframe_interval,
}),
i444,
) else {
return true;
};
let frame_count = 10;
let mut yuv = vec![0u8; (width * height * 3 / 2) as usize];
let start = Instant::now();
let mut key_frame_time = Duration::ZERO;
let mut non_key_frame_time_sum = Duration::ZERO;
let pts = Instant::now();
let yuvfmt = av1.yuvfmt();
for i in 0..frame_count {
for w in 0..width {
yuv[w as usize] = i as u8;
}
if av1.encode(0, &yuv, super::STRIDE_ALIGN).is_err() {
let Ok(yuv) = generate_fake_data(i, yuvfmt.clone()) else {
return false;
};
let start = Instant::now();
if av1
.encode(pts.elapsed().as_millis() as _, &yuv, super::STRIDE_ALIGN)
.is_err()
{
log::debug!("av1 encode failed");
if i == 0 {
return false;
}
}
}
let av1_time = start.elapsed();
log::info!("av1 time: {:?}", av1_time);
if av1_time < std::time::Duration::from_millis(250) {
return true;
}
let start = Instant::now();
for i in 0..frame_count {
for w in 0..width {
yuv[w as usize] = i as u8;
}
if vp9.encode(0, &yuv, super::STRIDE_ALIGN).is_err() {
log::debug!("vp9 encode failed");
if i == 0 {
return true;
}
if i == 0 {
key_frame_time = start.elapsed();
} else {
non_key_frame_time_sum += start.elapsed();
}
}
let vp9_time = start.elapsed();
log::info!("vp9 time: {:?}", vp9_time);
av1_time * 2 / 3 < vp9_time
let non_key_frame_time = non_key_frame_time_sum / (frame_count - 1);
log::info!(
"av1 time: key: {:?}, non-key: {:?}, consume: {:?}",
key_frame_time,
non_key_frame_time,
pts.elapsed()
);
key_frame_time < Duration::from_millis(90)
&& non_key_frame_time < Duration::from_millis(30)
};
std::thread::spawn(move || {
let v = f();