raymanfx / libv4l-rs

Video4Linux2 bindings for Rust
MIT License
152 stars 65 forks source link

Getting zeroes in capture buffers #78

Closed bshubenok-sigma closed 11 months ago

bshubenok-sigma commented 1 year ago

This is less of an issue but more of me seeking help. I'm trying to capture frames with Queue from next branch and getting all frame buffers set to zero. I've checked ffmpeg and it could capture frames as expected.

This is what I'm doing:

let afd = AsyncFd::with_interest(Arc::clone(&handle), Interest::READABLE)?;
        let mut queue =
            Queue::with_mmap(Arc::clone(&handle), Type::VideoCapture, Self::BUFFER_COUNT)?;

        for i in 0..queue.len() {
            let metadata = queue.query_buf(i as u32).unwrap();
            let buf = queue.index_mut(i);
            buf.fill(0);
            queue.enqueue(&metadata).unwrap();
        }

        let queue = queue.start_stream()?;

.............................

loop {
            let mut guard = self.device_poll_handler.ready(Interest::READABLE).await?;
            // remove a buffer from the drivers' outgoing queue
            let metadata @ Metadata { sequence: _, timestamp: _, flags: _, bytesused: _, .. } =
                match self.queue.dequeue() {
                    Ok(buf) => buf,
                    Err(ref err) if err.kind() == ErrorKind::WouldBlock => {
                        guard.clear_ready();
                        continue;
                    }
                    Err(err) => return Err(err),
                };

            let buffer = self.queue.index(metadata.index as _);
                info!(
                    "Frame#{}(index {}/pointer: {:?}): {:?}`",
                    metadata.sequence,
                    metadata.index,
                    buffer.as_ptr(),
                    &buffer[..40],
                );

            let result = Ok(VideoFrame {
                metadata,
                buffer: Bytes::copy_from_slice(&buffer[..metadata.bytesused as _]),
                // queue: &self.queue,
                ntp_timestamp: SystemTime::now(), // .duration_since(self.shift + Duration::from(timestamp))
                                                  // .unwrap().as_millis().into(),
            });
            self.queue.enqueue(&metadata).unwrap();
            return result;
        }

Here what I'm getting in output:

2023-11-07T16:15:17.180491Z  INFO lib::mediaengine: Opened video device 1 with format:
 width          : 1920
height         : 1080
fourcc         : H264
field          : progressive
stride         : 0
size           : 778240
colorspace     : sRGB
quantization   : default
transfer       : default transfer function

 and Parameters:
capabilities : TIME_PER_FRAME
modes        : (empty)
interval     : 30/300 [s]

2023-11-07T16:15:17.883648Z  INFO lib::mediaengine::video: Frame#10090(index 2/pointer: 0x7f8e9fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:17.983515Z  INFO lib::mediaengine::video: Frame#10091(index 3/pointer: 0x7f8d5fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.083395Z  INFO lib::mediaengine::video: Frame#10092(index 4/pointer: 0x7f8c1fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.183530Z  INFO lib::mediaengine::video: Frame#10093(index 5/pointer: 0x7f7ec00000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.283405Z  INFO lib::mediaengine::video: Frame#10094(index 6/pointer: 0x7f7d800000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.384713Z  INFO lib::mediaengine::video: Frame#10095(index 7/pointer: 0x7f7c400000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.486195Z  INFO lib::mediaengine::video: Frame#10096(index 0/pointer: 0x7f96298000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.584187Z  INFO lib::mediaengine::video: Frame#10097(index 1/pointer: 0x7f94e98000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.683948Z  INFO lib::mediaengine::video: Frame#10098(index 2/pointer: 0x7f8e9fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.783278Z  INFO lib::mediaengine::video: Frame#10099(index 3/pointer: 0x7f8d5fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.883003Z  INFO lib::mediaengine::video: Frame#10100(index 4/pointer: 0x7f8c1fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:18.983262Z  INFO lib::mediaengine::video: Frame#10101(index 5/pointer: 0x7f7ec00000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.083439Z  INFO lib::mediaengine::video: Frame#10102(index 6/pointer: 0x7f7d800000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.183494Z  INFO lib::mediaengine::video: Frame#10103(index 7/pointer: 0x7f7c400000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.287652Z  INFO lib::mediaengine::video: Frame#10104(index 0/pointer: 0x7f96298000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.384111Z  INFO lib::mediaengine::video: Frame#10105(index 1/pointer: 0x7f94e98000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.483396Z  INFO lib::mediaengine::video: Frame#10106(index 2/pointer: 0x7f8e9fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.583426Z  INFO lib::mediaengine::video: Frame#10107(index 3/pointer: 0x7f8d5fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.683899Z  INFO lib::mediaengine::video: Frame#10108(index 4/pointer: 0x7f8c1fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.783537Z  INFO lib::mediaengine::video: Frame#10109(index 5/pointer: 0x7f7ec00000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.883382Z  INFO lib::mediaengine::video: Frame#10110(index 6/pointer: 0x7f7d800000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:19.983671Z  INFO lib::mediaengine::video: Frame#10111(index 7/pointer: 0x7f7c400000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:20.083790Z  INFO lib::mediaengine::video: Frame#10112(index 0/pointer: 0x7f96298000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:20.183754Z  INFO lib::mediaengine::video: Frame#10113(index 1/pointer: 0x7f94e98000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:20.283560Z  INFO lib::mediaengine::video: Frame#10114(index 2/pointer: 0x7f8e9fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:20.383660Z  INFO lib::mediaengine::video: Frame#10115(index 3/pointer: 0x7f8d5fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`
2023-11-07T16:15:20.483666Z  INFO lib::mediaengine::video: Frame#10116(index 4/pointer: 0x7f8c1fa000): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`

I'm sure I'm doing something wrong but maybe someone can help me anyway?

bshubenok-sigma commented 11 months ago

Okay, that was "buggy driver" that uses a strange mmap technique.

raymanfx commented 11 months ago

Glad you were able to figure it out. I’m not opposed to including (reasonable) workaround for buggy hardware in this crate.

What was the buggy driver doing in your case that broke the assumptions of the crate?

bshubenok-sigma commented 11 months ago

It returned N buffers, each of which maps the whole device's memory (with some offset), and every time on deque returns a buffer with a new offset but the index of a previously allocated buffer. As I understood, the crate expects offset to be unchanged after buffer allocation and mmap. GStreamer was able to get a stream right, FFmpeg failed.