Skip to main content

Decoder

Struct Decoder 

Source
pub struct Decoder { /* private fields */ }
Expand description

Decoder for MCRAW container files.

Opens a .mcraw file via memory-mapped I/O and provides access to container metadata, raw frame data, and audio chunks.

Implementations§

Source§

impl Decoder

Source

pub fn from_path(path: impl AsRef<Path>) -> Result<Self>

Open and decode an MCRAW file at the given path.

Examples found in repository?
examples/decode.rs (line 47)
33fn main() {
34    let args: Vec<String> = env::args().collect();
35    if args.len() < 2 {
36        eprintln!("Usage: decode <input.mcraw> [-n <num_frames>]");
37        std::process::exit(1);
38    }
39
40    let input_path = &args[1];
41    let mut end_frame: Option<usize> = None;
42
43    if args.len() > 3 && args[2] == "-n" {
44        end_frame = Some(args[3].parse().expect("invalid frame count"));
45    }
46
47    let decoder = Decoder::from_path(input_path).expect("failed to open decoder");
48
49    let timestamps: Vec<i64> = decoder.frame_timestamps().collect();
50
51    println!("Found {} frames", timestamps.len());
52
53    let end = end_frame.unwrap_or(timestamps.len()).min(timestamps.len());
54
55    //
56    // Audio
57    //
58    {
59        let audio_chunks = decoder.load_audio().expect("failed to load audio");
60        if !audio_chunks.is_empty() {
61            println!(
62                "Audio: {} chunks, {} Hz, {} channels",
63                audio_chunks.len(),
64                decoder.audio_sample_rate_hz(),
65                decoder.num_audio_channels()
66            );
67            write_audio(&audio_chunks, "audio.raw");
68        } else {
69            println!("Audio: none");
70        }
71    }
72
73    //
74    // Frames
75    //
76    for i in 0..end {
77        let (pixels, meta) = decoder
78            .load_frame(timestamps[i])
79            .unwrap_or_else(|e| panic!("failed to decode frame {}: {}", i, e));
80
81        let width = meta["width"].as_u64().unwrap_or(0) as usize;
82        let height = meta["height"].as_u64().unwrap_or(0) as usize;
83
84        let filename = format!("frame_{:06}.raw", i);
85        println!("Frame {}: {} (ts={})", i, fmt_metadata(&meta), timestamps[i]);
86        write_raw_frame(&pixels, width, height, &filename);
87    }
88}
Source

pub fn container_metadata(&self) -> &Value

Returns a reference to the container-level metadata (JSON).

Source

pub fn prefetch(&self, timestamp: i64)

Hint the OS to prefetch a frame’s compressed bytes into the page cache.

Uses madvise(MADV_WILLNEED) on Unix to bring the frame’s mmap range into the page cache ahead of the actual read. Platform-specific implementation — this is a no-op on non-Unix targets.

Source

pub fn frame_timestamps(&self) -> impl Iterator<Item = i64> + '_

Returns an iterator over all frame timestamps in the container.

Examples found in repository?
examples/decode.rs (line 49)
33fn main() {
34    let args: Vec<String> = env::args().collect();
35    if args.len() < 2 {
36        eprintln!("Usage: decode <input.mcraw> [-n <num_frames>]");
37        std::process::exit(1);
38    }
39
40    let input_path = &args[1];
41    let mut end_frame: Option<usize> = None;
42
43    if args.len() > 3 && args[2] == "-n" {
44        end_frame = Some(args[3].parse().expect("invalid frame count"));
45    }
46
47    let decoder = Decoder::from_path(input_path).expect("failed to open decoder");
48
49    let timestamps: Vec<i64> = decoder.frame_timestamps().collect();
50
51    println!("Found {} frames", timestamps.len());
52
53    let end = end_frame.unwrap_or(timestamps.len()).min(timestamps.len());
54
55    //
56    // Audio
57    //
58    {
59        let audio_chunks = decoder.load_audio().expect("failed to load audio");
60        if !audio_chunks.is_empty() {
61            println!(
62                "Audio: {} chunks, {} Hz, {} channels",
63                audio_chunks.len(),
64                decoder.audio_sample_rate_hz(),
65                decoder.num_audio_channels()
66            );
67            write_audio(&audio_chunks, "audio.raw");
68        } else {
69            println!("Audio: none");
70        }
71    }
72
73    //
74    // Frames
75    //
76    for i in 0..end {
77        let (pixels, meta) = decoder
78            .load_frame(timestamps[i])
79            .unwrap_or_else(|e| panic!("failed to decode frame {}: {}", i, e));
80
81        let width = meta["width"].as_u64().unwrap_or(0) as usize;
82        let height = meta["height"].as_u64().unwrap_or(0) as usize;
83
84        let filename = format!("frame_{:06}.raw", i);
85        println!("Frame {}: {} (ts={})", i, fmt_metadata(&meta), timestamps[i]);
86        write_raw_frame(&pixels, width, height, &filename);
87    }
88}
Source

pub fn audio_sample_rate_hz(&self) -> i64

Audio sample rate in Hz, read from container metadata.

Examples found in repository?
examples/decode.rs (line 64)
33fn main() {
34    let args: Vec<String> = env::args().collect();
35    if args.len() < 2 {
36        eprintln!("Usage: decode <input.mcraw> [-n <num_frames>]");
37        std::process::exit(1);
38    }
39
40    let input_path = &args[1];
41    let mut end_frame: Option<usize> = None;
42
43    if args.len() > 3 && args[2] == "-n" {
44        end_frame = Some(args[3].parse().expect("invalid frame count"));
45    }
46
47    let decoder = Decoder::from_path(input_path).expect("failed to open decoder");
48
49    let timestamps: Vec<i64> = decoder.frame_timestamps().collect();
50
51    println!("Found {} frames", timestamps.len());
52
53    let end = end_frame.unwrap_or(timestamps.len()).min(timestamps.len());
54
55    //
56    // Audio
57    //
58    {
59        let audio_chunks = decoder.load_audio().expect("failed to load audio");
60        if !audio_chunks.is_empty() {
61            println!(
62                "Audio: {} chunks, {} Hz, {} channels",
63                audio_chunks.len(),
64                decoder.audio_sample_rate_hz(),
65                decoder.num_audio_channels()
66            );
67            write_audio(&audio_chunks, "audio.raw");
68        } else {
69            println!("Audio: none");
70        }
71    }
72
73    //
74    // Frames
75    //
76    for i in 0..end {
77        let (pixels, meta) = decoder
78            .load_frame(timestamps[i])
79            .unwrap_or_else(|e| panic!("failed to decode frame {}: {}", i, e));
80
81        let width = meta["width"].as_u64().unwrap_or(0) as usize;
82        let height = meta["height"].as_u64().unwrap_or(0) as usize;
83
84        let filename = format!("frame_{:06}.raw", i);
85        println!("Frame {}: {} (ts={})", i, fmt_metadata(&meta), timestamps[i]);
86        write_raw_frame(&pixels, width, height, &filename);
87    }
88}
Source

pub fn num_audio_channels(&self) -> i64

Number of audio channels, read from container metadata.

Examples found in repository?
examples/decode.rs (line 65)
33fn main() {
34    let args: Vec<String> = env::args().collect();
35    if args.len() < 2 {
36        eprintln!("Usage: decode <input.mcraw> [-n <num_frames>]");
37        std::process::exit(1);
38    }
39
40    let input_path = &args[1];
41    let mut end_frame: Option<usize> = None;
42
43    if args.len() > 3 && args[2] == "-n" {
44        end_frame = Some(args[3].parse().expect("invalid frame count"));
45    }
46
47    let decoder = Decoder::from_path(input_path).expect("failed to open decoder");
48
49    let timestamps: Vec<i64> = decoder.frame_timestamps().collect();
50
51    println!("Found {} frames", timestamps.len());
52
53    let end = end_frame.unwrap_or(timestamps.len()).min(timestamps.len());
54
55    //
56    // Audio
57    //
58    {
59        let audio_chunks = decoder.load_audio().expect("failed to load audio");
60        if !audio_chunks.is_empty() {
61            println!(
62                "Audio: {} chunks, {} Hz, {} channels",
63                audio_chunks.len(),
64                decoder.audio_sample_rate_hz(),
65                decoder.num_audio_channels()
66            );
67            write_audio(&audio_chunks, "audio.raw");
68        } else {
69            println!("Audio: none");
70        }
71    }
72
73    //
74    // Frames
75    //
76    for i in 0..end {
77        let (pixels, meta) = decoder
78            .load_frame(timestamps[i])
79            .unwrap_or_else(|e| panic!("failed to decode frame {}: {}", i, e));
80
81        let width = meta["width"].as_u64().unwrap_or(0) as usize;
82        let height = meta["height"].as_u64().unwrap_or(0) as usize;
83
84        let filename = format!("frame_{:06}.raw", i);
85        println!("Frame {}: {} (ts={})", i, fmt_metadata(&meta), timestamps[i]);
86        write_raw_frame(&pixels, width, height, &filename);
87    }
88}
Source

pub fn load_frame_metadata(&self, timestamp: i64) -> Result<Value>

Load metadata for a specific frame without decoding pixel data.

Source

pub fn load_frame(&self, timestamp: i64) -> Result<(Vec<u16>, Value)>

Load and decode a single frame by timestamp.

Returns (pixels, metadata) where pixels is a Vec<u16> in row-major order (Bayer raw data).

Examples found in repository?
examples/decode.rs (line 78)
33fn main() {
34    let args: Vec<String> = env::args().collect();
35    if args.len() < 2 {
36        eprintln!("Usage: decode <input.mcraw> [-n <num_frames>]");
37        std::process::exit(1);
38    }
39
40    let input_path = &args[1];
41    let mut end_frame: Option<usize> = None;
42
43    if args.len() > 3 && args[2] == "-n" {
44        end_frame = Some(args[3].parse().expect("invalid frame count"));
45    }
46
47    let decoder = Decoder::from_path(input_path).expect("failed to open decoder");
48
49    let timestamps: Vec<i64> = decoder.frame_timestamps().collect();
50
51    println!("Found {} frames", timestamps.len());
52
53    let end = end_frame.unwrap_or(timestamps.len()).min(timestamps.len());
54
55    //
56    // Audio
57    //
58    {
59        let audio_chunks = decoder.load_audio().expect("failed to load audio");
60        if !audio_chunks.is_empty() {
61            println!(
62                "Audio: {} chunks, {} Hz, {} channels",
63                audio_chunks.len(),
64                decoder.audio_sample_rate_hz(),
65                decoder.num_audio_channels()
66            );
67            write_audio(&audio_chunks, "audio.raw");
68        } else {
69            println!("Audio: none");
70        }
71    }
72
73    //
74    // Frames
75    //
76    for i in 0..end {
77        let (pixels, meta) = decoder
78            .load_frame(timestamps[i])
79            .unwrap_or_else(|e| panic!("failed to decode frame {}: {}", i, e));
80
81        let width = meta["width"].as_u64().unwrap_or(0) as usize;
82        let height = meta["height"].as_u64().unwrap_or(0) as usize;
83
84        let filename = format!("frame_{:06}.raw", i);
85        println!("Frame {}: {} (ts={})", i, fmt_metadata(&meta), timestamps[i]);
86        write_raw_frame(&pixels, width, height, &filename);
87    }
88}
Source

pub fn load_frame_into( &self, timestamp: i64, out: &mut [u16], ) -> Result<[f32; 3]>

Decode a single frame by timestamp into a caller-owned buffer.

Avoids the per-frame allocation that load_frame does. Returns only asShotNeutral as [f32; 3] — if you need other metadata fields, use load_frame instead.

Source

pub fn load_all_frames_parallel(&self) -> Result<Vec<(i64, Vec<u16>, Value)>>

Decode all frames in parallel using rayon.

Only available when the parallel feature is enabled (default).

Source

pub fn load_audio(&self) -> Result<Vec<AudioChunk>>

Load all audio chunks from the container.

Examples found in repository?
examples/decode.rs (line 59)
33fn main() {
34    let args: Vec<String> = env::args().collect();
35    if args.len() < 2 {
36        eprintln!("Usage: decode <input.mcraw> [-n <num_frames>]");
37        std::process::exit(1);
38    }
39
40    let input_path = &args[1];
41    let mut end_frame: Option<usize> = None;
42
43    if args.len() > 3 && args[2] == "-n" {
44        end_frame = Some(args[3].parse().expect("invalid frame count"));
45    }
46
47    let decoder = Decoder::from_path(input_path).expect("failed to open decoder");
48
49    let timestamps: Vec<i64> = decoder.frame_timestamps().collect();
50
51    println!("Found {} frames", timestamps.len());
52
53    let end = end_frame.unwrap_or(timestamps.len()).min(timestamps.len());
54
55    //
56    // Audio
57    //
58    {
59        let audio_chunks = decoder.load_audio().expect("failed to load audio");
60        if !audio_chunks.is_empty() {
61            println!(
62                "Audio: {} chunks, {} Hz, {} channels",
63                audio_chunks.len(),
64                decoder.audio_sample_rate_hz(),
65                decoder.num_audio_channels()
66            );
67            write_audio(&audio_chunks, "audio.raw");
68        } else {
69            println!("Audio: none");
70        }
71    }
72
73    //
74    // Frames
75    //
76    for i in 0..end {
77        let (pixels, meta) = decoder
78            .load_frame(timestamps[i])
79            .unwrap_or_else(|e| panic!("failed to decode frame {}: {}", i, e));
80
81        let width = meta["width"].as_u64().unwrap_or(0) as usize;
82        let height = meta["height"].as_u64().unwrap_or(0) as usize;
83
84        let filename = format!("frame_{:06}.raw", i);
85        println!("Frame {}: {} (ts={})", i, fmt_metadata(&meta), timestamps[i]);
86        write_raw_frame(&pixels, width, height, &filename);
87    }
88}

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.