我正在尝试为V4L相机分配一个小缓冲区,但我收到了
mmap.error: [Errno 22] Invalid argument
你能建议如何调试和查找哪个是无效参数,那么 mmap
会成功吗?
MCVE code:
from __future__ import print_function
import fcntl
import mmap
import os
import psutil
import v4l2
def alocate_buf(buf):
print("Trying to allocate a buffer of size {}".format(buf.length))
print("vd.fileno():", vd.fileno(), type(vd.fileno()))
print("buf.length:", buf.length, type(buf.length))
print("buf.m.offset:", buf.m.offset, type(buf.m.offset))
mm = mmap.mmap(vd.fileno(), buf.length, mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE, offset=buf.m.offset)
if __name__ == "__main__":
mem = psutil.virtual_memory()
print("available memory:", mem.available)
vd = open("/dev/video3", 'rb+', buffering=0)
buf = v4l2.v4l2_buffer()
buf.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
buf.memory = v4l2.V4L2_MEMORY_MMAP
buf.index = 0
buf.length = 1024
alocate_buf(buf)
Code run:
$ python find_max_mmap.py
available memory: 6439845888
Trying to allocate a buffer of size 1024
vd.fileno(): 3 <type 'int'>
buf.length: 1024 <type 'long'>
buf.m.offset: 0 <type 'long'>
Traceback (most recent call last):
File "find_max_mmap.py", line 30, in <module>
alocate_buf(buf)
File "find_max_mmap.py", line 15, in alocate_buf
mm = mmap.mmap(vd.fileno(), buf.length, mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE, offset=buf.m.offset)
mmap.error: [Errno 22] Invalid argument
环境:
-
操作系统:Ubuntu 16.04,Linux 4.4.0-64-generic,#85-Ubuntu SMP x86_64 GNU / Linux
-
UVC设备:英特尔实感410
Edit 1:
请注意,将相关行更改为:
mm = mmap.mmap(vd.fileno(), buf.length)
仍然给出:
$ python mmap_SO.with_0.py
available memory: 6418022400
Trying to allocate a buffer of size 0
vd.fileno(): 3 <type 'int'>
buf.length: 0 <type 'long'>
buf.m.offset: 0 <type 'long'>
Traceback (most recent call last):
File "mmap_SO.with_0.py", line 30, in <module>
alocate_buf(buf)
File "mmap_SO.with_0.py", line 15, in alocate_buf
mm = mmap.mmap(vd.fileno(), buf.length)
mmap.error: [Errno 22] Invalid argument
2 回答
我自己没有使用过Python v4l2模块,但是在测试MMAP和USERPTR分配方法时,我确实首先点击了EINVAL . 我的问题原来是我在该文件描述符上调用mmap()之前没有设置图像格式 .
鉴于我在您的代码中没有看到
v4l2_format()
或fnctl.ioctl(vd, VIDIOC_S_FORMAT, ...)
的任何构造,这似乎也是您的问题 . 如果您尝试设置格式,您仍然可以获得EINVAL吗?要确保指定与/ dev / video3兼容的分辨率和像素格式,可以通过
guvcview
或其他网络摄像头工具进行检查 .而不是
open("/dev/video3", 'rb+', buffering=0)
使用os.open("/dev/video3",os.O_RDWR|os.O_NONBLOCK)