Skip to content

MemoryMappedFrameBuffer::data()` returns full allocated buffer, not actual frame bytes #85

Description

@PrarthanaPurohit

Problem

When capturing compressed formats like MJPEG, data() gives you the entire allocated plane buffer — not just the bytes the camera actually wrote. A 1080p MJPEG frame might sit in a 4 MB buffer but only use 80 KB of it. The real length lives in metadata().planes()[i].bytes_used.

So right now every caller has to do this manually:

let planes = framebuffer.data();
let frame_data = planes.first().unwrap();
let bytes_used = framebuffer.metadata().unwrap()
    .planes().get(0).unwrap()
    .bytes_used as usize;

// hope bytes_used <= frame_data.len(), otherwise: panic
let actual = &frame_data[..bytes_used];

This is what both jpeg_capture.rs and video_capture.rs currently do. It is easy to forget, and has no bounds check — if a driver ever returns a bad bytes_used, you get a panic.

What can be done:

A data_used() method that trims automatically:

pub fn data_used(&self) -> Option<Vec<&[u8]>> {
    let meta = self.fb.metadata()?;
    let full_planes = self.data();
    Some(
        full_planes
            .into_iter()
            .zip(meta.planes().into_iter())
            .map(|(slice, plane_meta)| {
                let used = (plane_meta.bytes_used as usize).min(slice.len());
                &slice[..used]
            })
            .collect(),
    )
}
  • Returns None if the request has not completed yet (consistent with metadata())
  • Clamps to slice.len() so bad driver values never panic
  • Zero-copy, no allocation

The call sites then simplify to:

let planes = framebuffer.data_used().expect("frame not ready");
let frame_data = planes.first().expect("no planes");
file.write_all(frame_data)?;

Happy to open a PR for this if the approach looks good.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions