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, collections::HashMap,
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::Instant,
}; };
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
@ -27,7 +28,6 @@ use hbb_common::{
SupportedDecoding, SupportedEncoding, VideoFrame, SupportedDecoding, SupportedEncoding, VideoFrame,
}, },
sysinfo::System, sysinfo::System,
tokio::time::Instant,
ResultType, ResultType,
}; };
@ -990,7 +990,9 @@ fn disable_av1() -> bool {
#[cfg(not(target_os = "ios"))] #[cfg(not(target_os = "ios"))]
pub fn test_av1() { pub fn test_av1() {
use hbb_common::config::keys::OPTION_AV1_TEST; 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() { if disable_av1() || !Config::get_option(OPTION_AV1_TEST).is_empty() {
log::info!("skip test av1"); log::info!("skip test av1");
return; return;
@ -1001,6 +1003,56 @@ pub fn test_av1() {
let f = || { let f = || {
let (width, height, quality, keyframe_interval, i444) = let (width, height, quality, keyframe_interval, i444) =
(1920, 1080, Quality::Balanced, None, false); (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( let Ok(mut av1) = AomEncoder::new(
EncoderCfg::AOM(AomEncoderConfig { EncoderCfg::AOM(AomEncoderConfig {
width, width,
@ -1012,52 +1064,39 @@ pub fn test_av1() {
) else { ) else {
return false; return false;
}; };
let Ok(mut vp9) = VpxEncoder::new( let mut key_frame_time = Duration::ZERO;
EncoderCfg::VPX(VpxEncoderConfig { let mut non_key_frame_time_sum = Duration::ZERO;
codec: VpxVideoCodecId::VP9, let pts = Instant::now();
width, let yuvfmt = av1.yuvfmt();
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();
for i in 0..frame_count { for i in 0..frame_count {
for w in 0..width { let Ok(yuv) = generate_fake_data(i, yuvfmt.clone()) else {
yuv[w as usize] = i as u8; return false;
} };
if av1.encode(0, &yuv, super::STRIDE_ALIGN).is_err() { let start = Instant::now();
if av1
.encode(pts.elapsed().as_millis() as _, &yuv, super::STRIDE_ALIGN)
.is_err()
{
log::debug!("av1 encode failed"); log::debug!("av1 encode failed");
if i == 0 { if i == 0 {
return false; return false;
} }
} }
} if i == 0 {
let av1_time = start.elapsed(); key_frame_time = start.elapsed();
log::info!("av1 time: {:?}", av1_time); } else {
if av1_time < std::time::Duration::from_millis(250) { non_key_frame_time_sum += start.elapsed();
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;
}
} }
} }
let vp9_time = start.elapsed(); let non_key_frame_time = non_key_frame_time_sum / (frame_count - 1);
log::info!("vp9 time: {:?}", vp9_time); log::info!(
av1_time * 2 / 3 < vp9_time "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 || { std::thread::spawn(move || {
let v = f(); let v = f();