use crate::codec::Magic;
use crate::codec::{CodecError, CodecMetadata, EncoderType, ReadCompression, ReadCompressionEnum};
use crate::SourceType::*;
use crate::{Event, PlaneSize, SourceCamera, SourceType};
#[cfg(feature = "compression")]
use crate::codec::compressed::stream::CompressedInput;
use crate::codec::encoder::Encoder;
use crate::codec::header::{
EventStreamHeader, EventStreamHeaderExtensionV1, EventStreamHeaderExtensionV2,
EventStreamHeaderExtensionV3, MAGIC_COMPRESSED,
};
use crate::codec::raw::stream::RawInput;
use crate::codec::CodecError::Deserialize;
use crate::SourceType::U8;
use bincode::config::{FixintEncoding, WithOtherEndian, WithOtherIntEncoding};
use bincode::{DefaultOptions, Options};
use bitstream_io::{BigEndian, BitRead, BitReader};
use std::io::{Read, Seek, SeekFrom};
pub struct Decoder<R: Read + Seek> {
input: ReadCompressionEnum<R>,
bincode: WithOtherEndian<
WithOtherIntEncoding<DefaultOptions, FixintEncoding>,
bincode::config::BigEndian,
>,
_phantom: std::marker::PhantomData<R>,
}
#[allow(dead_code)]
impl<R: Read + Seek> Decoder<R> {
#[cfg(feature = "compression")]
pub fn new_compressed(
compression: CompressedInput<R>,
reader: &mut BitReader<R, BigEndian>,
) -> Result<Self, CodecError>
where
Self: Sized,
{
let mut decoder = Self {
input: ReadCompressionEnum::CompressedInput(compression),
bincode: DefaultOptions::new()
.with_fixint_encoding()
.with_big_endian(),
_phantom: std::marker::PhantomData,
};
decoder.decode_header(reader)?;
Ok(decoder)
}
pub fn new_raw(
compression: RawInput<R>,
reader: &mut BitReader<R, BigEndian>,
) -> Result<Self, CodecError>
where
Self: Sized,
{
let mut decoder = Self {
input: ReadCompressionEnum::RawInput(compression),
bincode: DefaultOptions::new()
.with_fixint_encoding()
.with_big_endian(),
_phantom: std::marker::PhantomData,
};
decoder.decode_header(reader)?;
Ok(decoder)
}
#[inline]
pub fn meta(&self) -> &CodecMetadata {
self.input.meta()
}
#[inline]
pub fn meta_mut(&mut self) -> &mut CodecMetadata {
self.input.meta_mut()
}
#[allow(clippy::match_same_arms)]
pub fn get_source_type(&self) -> SourceType {
match self.input.meta().source_camera {
SourceCamera::FramedU8 => U8,
SourceCamera::FramedU16 => U16,
SourceCamera::FramedU32 => U32,
SourceCamera::FramedU64 => U64,
SourceCamera::FramedF32 => F32,
SourceCamera::FramedF64 => F64,
SourceCamera::Dvs => U8,
SourceCamera::DavisU8 => U8,
SourceCamera::Atis => U8,
SourceCamera::Asint => F64,
}
}
fn decode_header(&mut self, reader: &mut BitReader<R, BigEndian>) -> Result<usize, CodecError> {
let header_size = bincode::serialized_size(&EventStreamHeader::default())?;
let mut buffer: Vec<u8> = vec![0; header_size as usize];
reader.read_bytes(&mut buffer)?;
let header = match self
.bincode
.deserialize_from::<_, EventStreamHeader>(&*buffer)
{
Ok(header) => header,
Err(_) => return Err(Deserialize),
};
{
if header.magic != self.input.magic() {
return Err(CodecError::WrongMagic);
}
let meta = self.input.meta_mut();
*meta = CodecMetadata {
codec_version: header.version,
header_size: header_size as usize,
time_mode: Default::default(),
plane: PlaneSize::new(header.width, header.height, header.channels)?,
tps: header.tps,
ref_interval: header.ref_interval,
delta_t_max: header.delta_t_max,
event_size: header.event_size,
source_camera: Default::default(), adu_interval: Default::default(), };
if meta.event_size == 10 {
meta.event_size = 11;
}
}
self.decode_header_extension(reader)?;
Ok(self.input.meta().header_size)
}
fn decode_header_extension(
&mut self,
reader: &mut BitReader<R, BigEndian>,
) -> Result<(), CodecError> {
let codec_version = self.input.meta().codec_version;
if codec_version == 0 {
return Ok(());
}
let mut extension_size =
bincode::serialized_size(&EventStreamHeaderExtensionV1::default())?;
let mut buffer: Vec<u8> = vec![0; extension_size as usize];
reader.read_bytes(&mut buffer)?;
let extension_v1 = match self
.bincode
.deserialize_from::<_, EventStreamHeaderExtensionV1>(&*buffer)
{
Ok(header) => header,
Err(_) => return Err(Deserialize),
};
self.input.meta_mut().source_camera = extension_v1.source;
self.input.meta_mut().header_size += extension_size as usize;
if codec_version == 1 {
return Ok(());
}
extension_size = bincode::serialized_size(&EventStreamHeaderExtensionV2::default())?;
buffer = vec![0; extension_size as usize];
reader.read_bytes(&mut buffer)?;
let extension_v2 = match self
.bincode
.deserialize_from::<_, EventStreamHeaderExtensionV2>(&*buffer)
{
Ok(header) => header,
Err(_) => return Err(Deserialize),
};
self.input.meta_mut().time_mode = extension_v2.time_mode;
self.input.meta_mut().header_size += extension_size as usize;
if codec_version == 2 {
return Ok(());
}
extension_size = bincode::serialized_size(&EventStreamHeaderExtensionV3::default())?;
buffer = vec![0; extension_size as usize];
reader.read_bytes(&mut buffer)?;
let extension_v3 = match self
.bincode
.deserialize_from::<_, EventStreamHeaderExtensionV3>(&*buffer)
{
Ok(header) => header,
Err(_) => return Err(Deserialize),
};
self.input.meta_mut().adu_interval = extension_v3.adu_interval as usize;
self.input.meta_mut().header_size += extension_size as usize;
if codec_version == 3 {
return Ok(());
}
Err(CodecError::UnsupportedVersion(codec_version))
}
#[inline]
pub fn digest_event(
&mut self,
reader: &mut BitReader<R, BigEndian>,
) -> Result<Event, CodecError> {
self.input.digest_event(reader)
}
pub fn set_input_stream_position(
&mut self,
reader: &mut BitReader<R, BigEndian>,
position: u64,
) -> Result<(), CodecError> {
self.input.set_input_stream_position(reader, position)
}
pub fn get_input_stream_position(
&self,
reader: &mut BitReader<R, BigEndian>,
) -> Result<u64, CodecError> {
Ok(reader.position_in_bits()? / 8)
}
pub fn get_eof_position(
&mut self,
reader: &mut BitReader<R, BigEndian>,
) -> Result<u64, CodecError> {
for i in self.input.meta().event_size as i64..10 {
reader.seek_bits(SeekFrom::End(
i * self.input.meta().plane.volume() as i64 * 8,
))?;
if let Err(CodecError::Eof) = self.digest_event(reader) {
break;
}
}
Ok(self.get_input_stream_position(reader)? - self.input.meta().event_size as u64)
}
pub fn get_compression_type(&self) -> EncoderType {
#[cfg(feature = "compression")]
if self.input.magic() == MAGIC_COMPRESSED {
return EncoderType::Compressed;
}
EncoderType::Raw
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::codec::encoder::Encoder;
use crate::codec::raw::stream::{RawInput, RawOutput};
use crate::codec::rate_controller::Crf;
use crate::codec::{EncoderOptions, EventOrder};
use crate::Coord;
use std::io::{BufReader, BufWriter, Cursor, Write};
fn stock_event() -> Event {
Event {
coord: Coord {
x: 0,
y: 0,
c: None,
},
d: 0,
t: 0,
}
}
fn setup_encoded_raw(codec_version: u8) -> Vec<u8> {
let output = Vec::new();
let bufwriter = BufWriter::new(output);
let compression = RawOutput::new(
CodecMetadata {
codec_version,
header_size: 0,
time_mode: Default::default(),
plane: Default::default(),
tps: 0,
ref_interval: 255,
delta_t_max: 255,
event_size: 0,
source_camera: Default::default(),
adu_interval: 1,
},
bufwriter,
);
let mut encoder: Encoder<BufWriter<Vec<u8>>> = Encoder::new_raw(
compression,
EncoderOptions::default(PlaneSize {
width: 100,
height: 100,
channels: 1,
}),
);
let event = stock_event();
encoder.ingest_event(event).unwrap();
let mut writer = encoder.close_writer().unwrap().unwrap();
writer.flush().unwrap();
writer.into_inner().unwrap()
}
fn setup_encoded_raw_interleaved(codec_version: u8) -> Vec<u8> {
let output = Vec::new();
let bufwriter = BufWriter::new(output);
let compression = RawOutput::new(
CodecMetadata {
codec_version,
header_size: 0,
time_mode: Default::default(),
plane: Default::default(),
tps: 0,
ref_interval: 255,
delta_t_max: 255,
event_size: 0,
source_camera: Default::default(),
adu_interval: 1,
},
bufwriter,
);
let mut encoder: Encoder<BufWriter<Vec<u8>>> = Encoder::new_raw(
compression,
EncoderOptions {
event_drop: Default::default(),
event_order: EventOrder::Interleaved,
crf: Crf::new(
None,
PlaneSize {
width: 100,
height: 100,
channels: 1,
},
),
},
);
let event = stock_event();
encoder.ingest_event(event).unwrap();
let mut writer = encoder.close_writer().unwrap().unwrap();
writer.flush().unwrap();
writer.into_inner().unwrap()
}
#[cfg(feature = "compression")]
fn setup_encoded_compressed(codec_version: u8) -> Vec<u8> {
use crate::codec::CompressedOutput;
let output = Vec::new();
let bufwriter = BufWriter::new(output);
let compression = CompressedOutput::new(
CodecMetadata {
codec_version,
header_size: 0,
time_mode: Default::default(),
plane: Default::default(),
tps: 0,
ref_interval: 255,
delta_t_max: 255,
event_size: 0,
source_camera: Default::default(),
adu_interval: 1,
},
bufwriter,
);
let encoder: Encoder<BufWriter<Vec<u8>>> = Encoder::new_compressed(
compression,
EncoderOptions::default(PlaneSize {
width: 100,
height: 100,
channels: 1,
}),
);
let mut writer = encoder.close_writer().unwrap().unwrap();
writer.flush().unwrap();
writer.into_inner().unwrap()
}
#[test]
fn header_v0_raw() {
let output = setup_encoded_raw(0);
let tmp = Cursor::new(&*output);
let bufreader = BufReader::new(tmp);
let compression = RawInput::new();
let mut bitreader = BitReader::endian(bufreader, BigEndian);
let reader = Decoder::new_raw(compression, &mut bitreader).unwrap();
assert_eq!(reader.input.meta().header_size, 25);
}
#[test]
fn header_v1_raw() {
let output = setup_encoded_raw(1);
let tmp = Cursor::new(&*output);
let bufreader = BufReader::new(tmp);
let compression = RawInput::new();
let mut bitreader = BitReader::endian(bufreader, BigEndian);
let reader = Decoder::new_raw(compression, &mut bitreader).unwrap();
assert_eq!(reader.input.meta().header_size, 29);
}
#[test]
fn header_v2_raw() {
let output = setup_encoded_raw(2);
let tmp = Cursor::new(&*output);
let bufreader = BufReader::new(tmp);
let compression = RawInput::new();
let mut bitreader = BitReader::endian(bufreader, BigEndian);
let reader = Decoder::new_raw(compression, &mut bitreader).unwrap();
assert_eq!(reader.input.meta().header_size, 33);
}
#[test]
#[cfg(feature = "compression")]
fn header_v0_compressed() {
let output = setup_encoded_compressed(0);
let tmp = Cursor::new(&*output);
let bufreader = BufReader::new(tmp);
let compression = CompressedInput::new(255, 255, 1);
let mut bitreader = BitReader::endian(bufreader, BigEndian);
let reader = Decoder::new_compressed(compression, &mut bitreader).unwrap();
assert_eq!(reader.input.meta().header_size, 25);
}
#[test]
#[cfg(feature = "compression")]
fn header_v1_compressed() {
let output = setup_encoded_compressed(1);
let tmp = Cursor::new(&*output);
let bufreader = BufReader::new(tmp);
let compression = CompressedInput::new(255, 255, 1);
let mut bitreader = BitReader::endian(bufreader, BigEndian);
let reader = Decoder::new_compressed(compression, &mut bitreader).unwrap();
assert_eq!(reader.input.meta().header_size, 29);
}
#[test]
#[cfg(feature = "compression")]
fn header_v2_compressed() {
let output = setup_encoded_compressed(2);
let tmp = Cursor::new(&*output);
let bufreader = BufReader::new(tmp);
let compression = CompressedInput::new(255, 255, 1);
let mut bitreader = BitReader::endian(bufreader, BigEndian);
let reader = Decoder::new_compressed(compression, &mut bitreader).unwrap();
assert_eq!(reader.input.meta().header_size, 33);
}
#[test]
fn digest_event_raw() {
let output = setup_encoded_raw(2);
let tmp = Cursor::new(&*output);
let bufreader = BufReader::new(tmp);
let compression = RawInput::new();
let mut bitreader = BitReader::endian(bufreader, BigEndian);
let mut reader = Decoder::new_raw(compression, &mut bitreader).unwrap();
let event = reader.digest_event(&mut bitreader).unwrap();
assert_eq!(event, stock_event());
}
}