Как найти, какой аргумент mmap вызывает [Errno 22] Исключение недопустимого аргумента?

Я пытаюсь выделить небольшой буфер для камеры V4L, но я получаю

mmap.error: [Errno 22] Invalid argument

Можете ли вы предложить, как отладить и найти недопустимый аргумент, поэтому mmap преуспеет?


Код MCVE:

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)

Выполнение кода:

$ 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: Intel RealSense 410


Изменить 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

1 ответ

Я сам не использовал модуль 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)

Другие вопросы по тегам