use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use oximedia_gpu::ops::colorspace::{bt601_rgb_to_ycbcr, bt601_ycbcr_to_rgb};
use oximedia_gpu::ops::filter::gaussian_blur_separable;
use oximedia_gpu::ops::scale::ScaleOperation;
use std::hint::black_box;
fn make_rgba_frame(width: usize, height: usize) -> Vec<u8> {
let len = width * height * 4;
let mut buf = Vec::with_capacity(len);
for i in 0..len {
buf.push((i % 256) as u8);
}
buf
}
fn bench_color_convert(c: &mut Criterion) {
let width = 1920usize;
let height = 1080usize;
let frame = make_rgba_frame(width, height);
let mut group = c.benchmark_group("color_convert");
group.bench_function(BenchmarkId::new("bt601_rgb_to_yuv", "1920x1080"), |b| {
b.iter(|| {
let pixels = black_box(&frame);
let mut output = vec![(0u8, 0u8, 0u8); width * height];
for (i, chunk) in pixels.chunks_exact(4).enumerate() {
output[i] = bt601_rgb_to_ycbcr(chunk[0], chunk[1], chunk[2]);
}
output
});
});
group.bench_function(BenchmarkId::new("bt601_yuv_to_rgb", "1920x1080"), |b| {
let yuv = make_rgba_frame(width, height);
b.iter(|| {
let pixels = black_box(&yuv);
let mut output = vec![(0u8, 0u8, 0u8); width * height];
for (i, chunk) in pixels.chunks_exact(4).enumerate() {
output[i] = bt601_ycbcr_to_rgb(chunk[0], chunk[1], chunk[2]);
}
output
});
});
group.finish();
}
fn bench_scale(c: &mut Criterion) {
let src_w = 1920u32;
let src_h = 1080u32;
let dst_w = 960u32;
let dst_h = 540u32;
let input = make_rgba_frame(src_w as usize, src_h as usize);
let mut output = vec![0u8; dst_w as usize * dst_h as usize * 4];
let mut group = c.benchmark_group("scale");
group.bench_function(
BenchmarkId::new("lanczos3_downscale_cpu", "1920x1080_to_960x540"),
|b| {
b.iter(|| {
ScaleOperation::lanczos3_cpu(
black_box(&input),
src_w,
src_h,
black_box(&mut output),
dst_w,
dst_h,
)
.expect("lanczos3_cpu benchmark");
});
},
);
group.finish();
}
fn bench_blur(c: &mut Criterion) {
let width = 512u32;
let height = 512u32;
let sigma = 2.0f32;
let input = make_rgba_frame(width as usize, height as usize);
let mut output = vec![0u8; input.len()];
let mut group = c.benchmark_group("blur");
group.bench_function(
BenchmarkId::new("gaussian_blur_separable_cpu", "512x512_sigma2"),
|b| {
b.iter(|| {
gaussian_blur_separable(
black_box(&input),
black_box(&mut output),
width,
height,
sigma,
)
.expect("gaussian_blur_separable benchmark");
});
},
);
group.finish();
}
criterion_group!(benches, bench_color_convert, bench_scale, bench_blur);
criterion_main!(benches);