private unsafe NewImageBufferReadyEventArgs GetFrameDataPooled(InteropVideodev2.V4l2FrameBuffer *buffers) { // Get one frame from the buffer InteropVideodev2.v4l2_buffer frame = new InteropVideodev2.v4l2_buffer { type = InteropVideodev2.v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE, memory = InteropVideodev2.v4l2_memory.V4L2_MEMORY_MMAP, }; V4l2Struct(InteropVideodev2.V4l2Request.VIDIOC_DQBUF, ref frame); // Get data from pointer IntPtr intptr = buffers[frame.index].Start; var length = (int)buffers[frame.index].Length; byte[] dataBuffer = Array.Empty <byte>(); if (ImageBufferPoolingEnabled) { dataBuffer = ArrayPool <byte> .Shared.Rent(length); } else { dataBuffer = new byte[length]; } Marshal.Copy(source: intptr, destination: dataBuffer, startIndex: 0, length: (int)buffers[frame.index].Length); // Requeue the buffer V4l2Struct(InteropVideodev2.V4l2Request.VIDIOC_QBUF, ref frame); return(new NewImageBufferReadyEventArgs(dataBuffer, length)); }
private unsafe InteropVideodev2.V4l2FrameBuffer[] ApplyFrameBuffers() { // Apply for buffers, use memory mapping InteropVideodev2.v4l2_requestbuffers req = new InteropVideodev2.v4l2_requestbuffers { count = BufferCount, type = InteropVideodev2.v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE, memory = InteropVideodev2.v4l2_memory.V4L2_MEMORY_MMAP }; V4l2Struct(InteropVideodev2.V4l2Request.VIDIOC_REQBUFS, ref req); // Mapping the applied buffer to user space InteropVideodev2.V4l2FrameBuffer[] buffers = new InteropVideodev2.V4l2FrameBuffer[BufferCount]; for (uint i = 0; i < BufferCount; i++) { InteropVideodev2.v4l2_buffer buffer = new InteropVideodev2.v4l2_buffer { index = i, type = InteropVideodev2.v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE, memory = InteropVideodev2.v4l2_memory.V4L2_MEMORY_MMAP }; V4l2Struct(InteropVideodev2.V4l2Request.VIDIOC_QUERYBUF, ref buffer); buffers[i].Length = buffer.length; buffers[i].Start = Interop.mmap(IntPtr.Zero, (int)buffer.length, Interop.MemoryMappedProtections.PROT_READ | Interop.MemoryMappedProtections.PROT_WRITE, Interop.MemoryMappedFlags.MAP_SHARED, _deviceFileDescriptor, (int)buffer.m.offset); } // Put the buffer in the processing queue for (uint i = 0; i < BufferCount; i++) { InteropVideodev2.v4l2_buffer buffer = new InteropVideodev2.v4l2_buffer { index = i, type = InteropVideodev2.v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE, memory = InteropVideodev2.v4l2_memory.V4L2_MEMORY_MMAP }; V4l2Struct(InteropVideodev2.V4l2Request.VIDIOC_QBUF, ref buffer); } return(buffers); }
private unsafe byte[] GetFrameData(InteropVideodev2.V4l2FrameBuffer *buffers) { // Get one frame from the buffer InteropVideodev2.v4l2_buffer frame = new InteropVideodev2.v4l2_buffer { type = InteropVideodev2.v4l2_buf_type.V4L2_BUF_TYPE_VIDEO_CAPTURE, memory = InteropVideodev2.v4l2_memory.V4L2_MEMORY_MMAP, }; V4l2Struct(InteropVideodev2.V4l2Request.VIDIOC_DQBUF, ref frame); // Get data from pointer IntPtr intptr = buffers[frame.index].Start; byte[] dataBuffer = new byte[buffers[frame.index].Length]; Marshal.Copy(source: intptr, destination: dataBuffer, startIndex: 0, length: (int)buffers[frame.index].Length); // Requeue the buffer V4l2Struct(InteropVideodev2.V4l2Request.VIDIOC_QBUF, ref frame); return(dataBuffer); }