pub mod csi;
pub mod parquet_sink;
use std::sync::Arc;
use csi::ChipVariant;
use parquet_sink::{ParquetSink, ParquetSinkError};
use crate::profile::ClientProfile;
pub struct Recorder {
sink: ParquetSink,
chip: ChipVariant,
pub frames_written: u64,
pub decode_errors: u64,
}
impl Recorder {
pub fn start(
path: &str,
chip: &str,
profile: Arc<dyn ClientProfile>,
) -> Result<Self, String> {
let variant = ChipVariant::from_chip_str(chip)
.ok_or_else(|| format!("unknown chip '{chip}'; cannot decode CSI frames"))?;
let sink = ParquetSink::open(path, chip, profile).map_err(|e| e.to_string())?;
Ok(Self {
sink,
chip: variant,
frames_written: 0,
decode_errors: 0,
})
}
pub fn path(&self) -> &str {
self.sink.path()
}
pub fn record_frame(&mut self, bytes: &[u8], host_rx_micros: i64) -> Result<(), ParquetSinkError> {
match csi::decode(bytes, self.chip) {
Ok(decoded) => {
self.sink.push(decoded, host_rx_micros)?;
self.frames_written += 1;
}
Err(_) => {
self.decode_errors += 1;
}
}
Ok(())
}
pub fn finish(mut self) -> Result<(), ParquetSinkError> {
self.sink.finish()
}
}