use std::time::Instant;
use videostream::{camera, encoder, fourcc::FourCC, frame::Frame, host, timestamp};
fn bitrate_to_profile(bitrate_kbps: u32) -> u8 {
match bitrate_kbps {
0..=1000 => 0, 1001..=3000 => 1, 3001..=7000 => 2, _ => 3, }
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let socket_path = std::env::args()
.nth(1)
.unwrap_or_else(|| "/tmp/vsl_separate_process_test.sock".to_string());
let frame_count: usize = std::env::args()
.nth(2)
.and_then(|s| s.parse().ok())
.unwrap_or(100);
println!("[HOST] Starting host process");
println!("[HOST] Socket: {}", socket_path);
println!("[HOST] Frame count: {}", frame_count);
println!("[HOST] Creating encoder...");
let profile = bitrate_to_profile(5000);
let codec_fourcc = u32::from_le_bytes(*b"H264");
let enc = encoder::Encoder::create(profile as u32, codec_fourcc, 30)?;
println!("[HOST] Encoder created");
println!("[HOST] Opening camera...");
let camera_device =
std::env::var("CAMERA_DEVICE").unwrap_or_else(|_| "/dev/video3".to_string());
let cam = camera::create_camera()
.with_device(&camera_device)
.with_resolution(1280, 720)
.with_format(FourCC(*b"YUYV"))
.open()?;
cam.start()?;
println!("[HOST] Camera started");
println!("[HOST] Creating host...");
let host = host::Host::new(&socket_path)?;
println!("[HOST] Host created at {}", socket_path);
std::thread::sleep(std::time::Duration::from_millis(1000));
let start = Instant::now();
for i in 0..frame_count {
let before_capture = Instant::now();
let buffer = cam.read()?;
let capture_time = before_capture.elapsed();
let before_encode = Instant::now();
let input_frame: Frame = (&buffer).try_into()?;
let output_frame = enc.new_output_frame(1280, 720, -1, -1, -1)?;
let crop = encoder::VSLRect::new(0, 0, 1280, 720);
let mut keyframe: i32 = 0;
unsafe {
enc.frame(&input_frame, &output_frame, &crop, &mut keyframe)?;
}
let encode_time = before_encode.elapsed();
let before_post = Instant::now();
let now = timestamp()?;
let expires = now + 5_000_000_000; host.post(output_frame, expires, -1, -1, -1)?;
let post_time = before_post.elapsed();
host.poll(100)?;
host.process()?;
if i < 5 || i % 20 == 0 {
println!(
"[HOST] Frame {}: capture={}ms, encode={}ms, post={}μs",
i + 1,
capture_time.as_millis(),
encode_time.as_millis(),
post_time.as_micros()
);
}
}
let duration = start.elapsed();
println!(
"[HOST] Completed {} frames in {:.2}s ({:.1} FPS)",
frame_count,
duration.as_secs_f64(),
frame_count as f64 / duration.as_secs_f64()
);
println!("[HOST] Waiting for client to finish receiving...");
for _ in 0..100 {
host.poll(10)?;
host.process()?;
std::thread::sleep(std::time::Duration::from_millis(50));
}
println!("[HOST] Done");
Ok(())
}