use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::time::{Duration, Instant};
use rslibcamlitelib::{ExternalCallback, LibCamClient, StreamFormat, StreamParams};
#[derive(Default)]
struct Counters {
h264_frames: AtomicU64,
h264_bytes: AtomicU64,
keyframes: AtomicU64,
rgb_frames: AtomicU64,
}
struct Callback(Arc<Counters>);
impl ExternalCallback for Callback {
unsafe fn callbackH264(&self, _bytes: *mut u8, count: usize, _timestamp_us: i64, keyframe: bool) {
self.0.h264_frames.fetch_add(1, Ordering::Relaxed);
self.0.h264_bytes.fetch_add(count as u64, Ordering::Relaxed);
if keyframe {
self.0.keyframes.fetch_add(1, Ordering::Relaxed);
}
}
unsafe fn callbackLowres(&self, _bytes: *mut u8, _count: usize) {
self.0.rgb_frames.fetch_add(1, Ordering::Relaxed);
}
}
fn main() {
let seconds: u64 = std::env::args().nth(1).and_then(|s| s.parse().ok()).unwrap_or(10);
let libcam = LibCamClient::new();
let h264 = StreamParams { width: 1920, height: 1080, format: StreamFormat::STREAM_FORMAT_H264, framerate: 30 };
libcam.client.setupH264(&h264, 30, &"main".to_owned(), &"4mbps".to_owned());
let lowres = StreamParams { width: 300, height: 300, format: StreamFormat::STREAM_FORMAT_RGB, framerate: 30 };
libcam.client.setupLowres(&lowres);
let counters = Arc::new(Counters::default());
libcam.setCallbacks(Box::new(Callback(counters.clone())));
libcam.start(true);
let started = Instant::now();
let (mut h264_prev, mut bytes_prev, mut rgb_prev) = (0, 0, 0);
while started.elapsed() < Duration::from_secs(seconds) {
std::thread::sleep(Duration::from_secs(1));
let h264 = counters.h264_frames.load(Ordering::Relaxed);
let bytes = counters.h264_bytes.load(Ordering::Relaxed);
let rgb = counters.rgb_frames.load(Ordering::Relaxed);
println!(
"h264: {:>3} fps {:>6} kbit/s ({} keyframes total) rgb 300x300: {:>3} fps",
h264 - h264_prev,
(bytes - bytes_prev) * 8 / 1000,
counters.keyframes.load(Ordering::Relaxed),
rgb - rgb_prev,
);
(h264_prev, bytes_prev, rgb_prev) = (h264, bytes, rgb);
}
libcam.stop();
}