adder_codec_core/codec/
decoder.rs

1use crate::codec::{CodecError, CodecMetadata, EncoderType, ReadCompression, ReadCompressionEnum};
2use crate::SourceType::*;
3use crate::{Event, PlaneSize, SourceCamera, SourceType};
4
5// #[cfg(feature = "compression")]
6// use crate::codec::compressed::adu::frame::Adu;
7#[cfg(feature = "compression")]
8use crate::codec::compressed::stream::CompressedInput;
9
10use crate::codec::header::{
11    EventStreamHeader, EventStreamHeaderExtensionV1, EventStreamHeaderExtensionV2,
12    EventStreamHeaderExtensionV3, MAGIC_COMPRESSED,
13};
14use crate::codec::raw::stream::RawInput;
15use crate::codec::CodecError::Deserialize;
16use bincode::config::{FixintEncoding, WithOtherEndian, WithOtherIntEncoding};
17use bincode::{DefaultOptions, Options};
18use bitstream_io::{BigEndian, BitRead, BitReader};
19use std::io::{Read, Seek, SeekFrom};
20
21/// Struct for decoding [`Event`]s from a stream
22pub struct Decoder<R: Read + Seek> {
23    input: ReadCompressionEnum<R>,
24    bincode: WithOtherEndian<
25        WithOtherIntEncoding<DefaultOptions, FixintEncoding>,
26        bincode::config::BigEndian,
27    >,
28    _phantom: std::marker::PhantomData<R>,
29}
30
31#[allow(dead_code)]
32impl<R: Read + Seek> Decoder<R> {
33    /// Create a new decoder with the given compression scheme
34    #[cfg(feature = "compression")]
35    pub fn new_compressed(
36        compression: CompressedInput<R>,
37        reader: &mut BitReader<R, BigEndian>,
38    ) -> Result<Self, CodecError>
39    where
40        Self: Sized,
41    {
42        let mut decoder = Self {
43            input: ReadCompressionEnum::CompressedInput(compression),
44            bincode: DefaultOptions::new()
45                .with_fixint_encoding()
46                .with_big_endian(),
47            _phantom: std::marker::PhantomData,
48        };
49        decoder.decode_header(reader)?;
50        Ok(decoder)
51    }
52
53    /// Create a new decoder with the given compression scheme
54    pub fn new_raw(
55        compression: RawInput<R>,
56        reader: &mut BitReader<R, BigEndian>,
57    ) -> Result<Self, CodecError>
58    where
59        Self: Sized,
60    {
61        let mut decoder = Self {
62            input: ReadCompressionEnum::RawInput(compression),
63            bincode: DefaultOptions::new()
64                .with_fixint_encoding()
65                .with_big_endian(),
66            _phantom: std::marker::PhantomData,
67        };
68        decoder.decode_header(reader)?;
69        Ok(decoder)
70    }
71
72    /// Returns a reference to the metadata of the underlying compression scheme
73    #[inline]
74    pub fn meta(&self) -> &CodecMetadata {
75        self.input.meta()
76    }
77
78    /// Returns a mutable reference to the metadata of the underlying compression scheme
79    #[inline]
80    pub fn meta_mut(&mut self) -> &mut CodecMetadata {
81        self.input.meta_mut()
82    }
83
84    /// Get the source data representation, based on the source camera
85    #[allow(clippy::match_same_arms)]
86    pub fn get_source_type(&self) -> SourceType {
87        match self.input.meta().source_camera {
88            SourceCamera::FramedU8 => U8,
89            SourceCamera::FramedU16 => U16,
90            SourceCamera::FramedU32 => U32,
91            SourceCamera::FramedU64 => U64,
92            SourceCamera::FramedF32 => F32,
93            SourceCamera::FramedF64 => F64,
94            SourceCamera::Dvs => U8,
95            SourceCamera::DavisU8 => U8,
96            SourceCamera::Atis => U8,
97            SourceCamera::Asint => F64,
98        }
99    }
100
101    /// Decode the header and its extensions
102    fn decode_header(&mut self, reader: &mut BitReader<R, BigEndian>) -> Result<usize, CodecError> {
103        let header_size = bincode::serialized_size(&EventStreamHeader::default())?;
104        let mut buffer: Vec<u8> = vec![0; header_size as usize];
105        reader.read_bytes(&mut buffer)?;
106
107        let header = match self
108            .bincode
109            .deserialize_from::<_, EventStreamHeader>(&*buffer)
110        {
111            Ok(header) => header,
112            Err(_) => return Err(Deserialize),
113        };
114
115        {
116            if header.magic != self.input.magic() {
117                return Err(CodecError::WrongMagic);
118            }
119            let meta = self.input.meta_mut();
120            *meta = CodecMetadata {
121                codec_version: header.version,
122                header_size: header_size as usize,
123                time_mode: Default::default(),
124                plane: PlaneSize::new(header.width, header.height, header.channels)?,
125                tps: header.tps,
126                ref_interval: header.ref_interval,
127                delta_t_max: header.delta_t_max,
128                event_size: header.event_size,
129                source_camera: Default::default(), // Gets filled by decoding the V2 header extension
130                adu_interval: Default::default(), // Gets filled by decoding the V3 header extension
131            };
132
133            // Manual fix for malformed files with old software
134            if meta.event_size == 10 {
135                meta.event_size = 11;
136            }
137        }
138        self.decode_header_extension(reader)?;
139        Ok(self.input.meta().header_size)
140    }
141
142    fn decode_header_extension(
143        &mut self,
144        reader: &mut BitReader<R, BigEndian>,
145    ) -> Result<(), CodecError> {
146        let codec_version = self.input.meta().codec_version;
147        if codec_version == 0 {
148            return Ok(());
149        }
150        let mut extension_size =
151            bincode::serialized_size(&EventStreamHeaderExtensionV1::default())?;
152        let mut buffer: Vec<u8> = vec![0; extension_size as usize];
153        reader.read_bytes(&mut buffer)?;
154        let extension_v1 = match self
155            .bincode
156            .deserialize_from::<_, EventStreamHeaderExtensionV1>(&*buffer)
157        {
158            Ok(header) => header,
159            Err(_) => return Err(Deserialize),
160        };
161        self.input.meta_mut().source_camera = extension_v1.source;
162        self.input.meta_mut().header_size += extension_size as usize;
163
164        if codec_version == 1 {
165            return Ok(());
166        }
167
168        extension_size = bincode::serialized_size(&EventStreamHeaderExtensionV2::default())?;
169        buffer = vec![0; extension_size as usize];
170        reader.read_bytes(&mut buffer)?;
171        let extension_v2 = match self
172            .bincode
173            .deserialize_from::<_, EventStreamHeaderExtensionV2>(&*buffer)
174        {
175            Ok(header) => header,
176            Err(_) => return Err(Deserialize),
177        };
178        self.input.meta_mut().time_mode = extension_v2.time_mode;
179        self.input.meta_mut().header_size += extension_size as usize;
180
181        if codec_version == 2 {
182            return Ok(());
183        }
184
185        extension_size = bincode::serialized_size(&EventStreamHeaderExtensionV3::default())?;
186        buffer = vec![0; extension_size as usize];
187        reader.read_bytes(&mut buffer)?;
188        let extension_v3 = match self
189            .bincode
190            .deserialize_from::<_, EventStreamHeaderExtensionV3>(&*buffer)
191        {
192            Ok(header) => header,
193            Err(_) => return Err(Deserialize),
194        };
195        self.input.meta_mut().adu_interval = extension_v3.adu_interval as usize;
196        self.input.meta_mut().header_size += extension_size as usize;
197
198        if codec_version == 3 {
199            return Ok(());
200        }
201
202        Err(CodecError::UnsupportedVersion(codec_version))
203    }
204
205    /// Read and decode the next event from the input stream
206    #[inline]
207    pub fn digest_event(
208        &mut self,
209        reader: &mut BitReader<R, BigEndian>,
210    ) -> Result<Event, CodecError> {
211        self.input.digest_event(reader)
212    }
213
214    // Read and decode the next event from the input stream
215    // #[cfg(feature = "compression")]
216    // #[inline]
217    // pub fn digest_event_debug(
218    //     &mut self,
219    //     reader: &mut BitReader<R, BigEndian>,
220    // ) -> Result<(Option<Adu>, Event), CodecError> {
221    //     self.input.digest_event_debug(reader)
222    // }
223
224    /// Sets the input stream position to the given absolute byte position
225    pub fn set_input_stream_position(
226        &mut self,
227        reader: &mut BitReader<R, BigEndian>,
228        position: u64,
229    ) -> Result<(), CodecError> {
230        self.input.set_input_stream_position(reader, position)
231    }
232
233    /// Returns the current position of the input stream in bytes
234    pub fn get_input_stream_position(
235        &self,
236        reader: &mut BitReader<R, BigEndian>,
237    ) -> Result<u64, CodecError> {
238        Ok(reader.position_in_bits()? / 8)
239    }
240
241    /// Returns the EOF position, in bytes. This is the position of the first byte of the raw event
242    /// which demarcates the end of the stream.
243    pub fn get_eof_position(
244        &mut self,
245        reader: &mut BitReader<R, BigEndian>,
246    ) -> Result<u64, CodecError> {
247        for i in self.input.meta().event_size as i64..10 {
248            // TODO: Make this work differently on raw vs. compressed stream
249            reader.seek_bits(SeekFrom::End(
250                i * self.input.meta().plane.volume() as i64 * 8,
251            ))?;
252            if matches!(self.digest_event(reader), Err(CodecError::Eof)) {
253                break;
254            }
255        }
256
257        Ok(self.get_input_stream_position(reader)? - self.input.meta().event_size as u64)
258    }
259
260    pub fn get_compression_type(&self) -> EncoderType {
261        #[cfg(feature = "compression")]
262        if self.input.magic() == MAGIC_COMPRESSED {
263            return EncoderType::Compressed;
264        }
265        EncoderType::Raw
266    }
267}
268
269#[cfg(test)]
270mod tests {
271    use super::*;
272
273    use crate::codec::encoder::Encoder;
274    use crate::codec::raw::stream::{RawInput, RawOutput};
275
276    use crate::codec::rate_controller::Crf;
277    use crate::codec::{EncoderOptions, EventOrder};
278    use crate::Coord;
279    use std::io::{BufReader, BufWriter, Cursor, Write};
280
281    fn stock_event() -> Event {
282        Event {
283            coord: Coord {
284                x: 0,
285                y: 0,
286                c: None,
287            },
288            d: 0,
289            t: 0,
290        }
291    }
292
293    fn setup_encoded_raw(codec_version: u8) -> Vec<u8> {
294        let output = Vec::new();
295
296        let bufwriter = BufWriter::new(output);
297        let compression = RawOutput::new(
298            CodecMetadata {
299                codec_version,
300                header_size: 0,
301                time_mode: Default::default(),
302                plane: Default::default(),
303                tps: 0,
304                ref_interval: 255,
305                delta_t_max: 255,
306                event_size: 0,
307                source_camera: Default::default(),
308                adu_interval: 1,
309            },
310            bufwriter,
311        );
312        let mut encoder: Encoder<BufWriter<Vec<u8>>> = Encoder::new_raw(
313            compression,
314            EncoderOptions::default(PlaneSize {
315                width: 100,
316                height: 100,
317                channels: 1,
318            }),
319        );
320
321        let event = stock_event();
322        encoder.ingest_event(event).unwrap();
323        let mut writer = encoder.close_writer().unwrap().unwrap();
324
325        writer.flush().unwrap();
326
327        writer.into_inner().unwrap()
328    }
329
330    fn setup_encoded_raw_interleaved(codec_version: u8) -> Vec<u8> {
331        let output = Vec::new();
332
333        let bufwriter = BufWriter::new(output);
334        let compression = RawOutput::new(
335            CodecMetadata {
336                codec_version,
337                header_size: 0,
338                time_mode: Default::default(),
339                plane: Default::default(),
340                tps: 0,
341                ref_interval: 255,
342                delta_t_max: 255,
343                event_size: 0,
344                source_camera: Default::default(),
345                adu_interval: 1,
346            },
347            bufwriter,
348        );
349        let mut encoder: Encoder<BufWriter<Vec<u8>>> = Encoder::new_raw(
350            compression,
351            EncoderOptions {
352                event_drop: Default::default(),
353                event_order: EventOrder::Interleaved,
354                crf: Crf::new(
355                    None,
356                    PlaneSize {
357                        width: 100,
358                        height: 100,
359                        channels: 1,
360                    },
361                ),
362            },
363        );
364
365        let event = stock_event();
366        encoder.ingest_event(event).unwrap();
367        let mut writer = encoder.close_writer().unwrap().unwrap();
368
369        writer.flush().unwrap();
370
371        writer.into_inner().unwrap()
372    }
373
374    #[cfg(feature = "compression")]
375    fn setup_encoded_compressed(codec_version: u8) -> Vec<u8> {
376        use crate::codec::CompressedOutput;
377
378        let output = Vec::new();
379
380        let bufwriter = BufWriter::new(output);
381        let compression = CompressedOutput::new(
382            CodecMetadata {
383                codec_version,
384                header_size: 0,
385                time_mode: Default::default(),
386                plane: Default::default(),
387                tps: 0,
388                ref_interval: 255,
389                delta_t_max: 255,
390                event_size: 0,
391                source_camera: Default::default(),
392                adu_interval: 1,
393            },
394            bufwriter,
395        );
396        let encoder: Encoder<BufWriter<Vec<u8>>> = Encoder::new_compressed(
397            compression,
398            EncoderOptions::default(PlaneSize {
399                width: 100,
400                height: 100,
401                channels: 1,
402            }),
403        );
404
405        // let event = stock_event();
406        //
407        // encoder.ingest_event(&event).unwrap();
408        let mut writer = encoder.close_writer().unwrap().unwrap();
409        writer.flush().unwrap();
410
411        writer.into_inner().unwrap()
412    }
413
414    #[test]
415    fn header_v0_raw() {
416        let output = setup_encoded_raw(0);
417        let tmp = Cursor::new(&*output);
418
419        let bufreader = BufReader::new(tmp);
420
421        let compression = RawInput::new();
422
423        let mut bitreader = BitReader::endian(bufreader, BigEndian);
424        let reader = Decoder::new_raw(compression, &mut bitreader).unwrap();
425        assert_eq!(reader.input.meta().header_size, 25);
426    }
427
428    #[test]
429    fn header_v1_raw() {
430        let output = setup_encoded_raw(1);
431        let tmp = Cursor::new(&*output);
432        let bufreader = BufReader::new(tmp);
433        let compression = RawInput::new();
434        let mut bitreader = BitReader::endian(bufreader, BigEndian);
435
436        let reader = Decoder::new_raw(compression, &mut bitreader).unwrap();
437        assert_eq!(reader.input.meta().header_size, 29);
438    }
439
440    #[test]
441    fn header_v2_raw() {
442        let output = setup_encoded_raw(2);
443        let tmp = Cursor::new(&*output);
444        let bufreader = BufReader::new(tmp);
445        let compression = RawInput::new();
446
447        let mut bitreader = BitReader::endian(bufreader, BigEndian);
448        let reader = Decoder::new_raw(compression, &mut bitreader).unwrap();
449        assert_eq!(reader.input.meta().header_size, 33);
450    }
451
452    #[test]
453    #[cfg(feature = "compression")]
454    fn header_v0_compressed() {
455        let output = setup_encoded_compressed(0);
456        let tmp = Cursor::new(&*output);
457        let bufreader = BufReader::new(tmp);
458        let compression = CompressedInput::new(255, 255, 1);
459
460        let mut bitreader = BitReader::endian(bufreader, BigEndian);
461        let reader = Decoder::new_compressed(compression, &mut bitreader).unwrap();
462        assert_eq!(reader.input.meta().header_size, 25);
463    }
464
465    #[test]
466    #[cfg(feature = "compression")]
467    fn header_v1_compressed() {
468        let output = setup_encoded_compressed(1);
469        let tmp = Cursor::new(&*output);
470        let bufreader = BufReader::new(tmp);
471        let compression = CompressedInput::new(255, 255, 1);
472
473        let mut bitreader = BitReader::endian(bufreader, BigEndian);
474        let reader = Decoder::new_compressed(compression, &mut bitreader).unwrap();
475        assert_eq!(reader.input.meta().header_size, 29);
476    }
477
478    #[test]
479    #[cfg(feature = "compression")]
480    fn header_v2_compressed() {
481        let output = setup_encoded_compressed(2);
482        let tmp = Cursor::new(&*output);
483        let bufreader = BufReader::new(tmp);
484        let compression = CompressedInput::new(255, 255, 1);
485
486        let mut bitreader = BitReader::endian(bufreader, BigEndian);
487        let reader = Decoder::new_compressed(compression, &mut bitreader).unwrap();
488        assert_eq!(reader.input.meta().header_size, 33);
489    }
490
491    #[test]
492    fn digest_event_raw() {
493        let output = setup_encoded_raw(2);
494        let tmp = Cursor::new(&*output);
495        let bufreader = BufReader::new(tmp);
496        let compression = RawInput::new();
497
498        let mut bitreader = BitReader::endian(bufreader, BigEndian);
499        let mut reader = Decoder::new_raw(compression, &mut bitreader).unwrap();
500        let event = reader.digest_event(&mut bitreader).unwrap();
501        assert_eq!(event, stock_event());
502    }
503}