为什么 V4L2 API 不显示正确的 pixel-format/width/height 参数?

Why doesn't V4L2 API display correct pixel-format/width/height parameters?

我正在尝试根据 V4L2 API.
设置 V4L2 相机的 参数 但是,API 似乎没有显示 OS.

设置的正确参数

您能否建议如何调试此问题,以确定相机无法显示正确参数是否是一个问题



问题演示:

$ v4l2-ctl -d2 --set-fmt-video=width=424,height=240,pixelformat=1
$ v4l2-ctl -d2 --get-fmt-video | egrep 'Pixel Format|Width/Height'
        Width/Height      : 424/240
        Pixel Format      : 'UYVY'
$ python incorrect_pix_format.SO.py                             
>> device capabilities
Driver: uvcvideo
Camera: Intel(R) RealSense(TM) 410
video capture device?    True
Supports read() call?    False
Supports streaming?      True
>> format parameters
pix_format.width: 0
pix_format.height: 0
pix_format.pixelformat: 0
>> Stop streaming
$ v4l2-ctl --list-formats-ext -d 2                              
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: ''
        Name        : 00000032-0000-0010-8000-00aa003
                Size: Discrete 424x240
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 480x270
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 640x360
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 640x480
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 848x480
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 1280x720
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'UYVY'
        Name        : UYVY 4:2:2
                Size: Discrete 424x240
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 480x270
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 640x360
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 640x480
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 848x480
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 1280x720
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)

        Index       : 2
        Type        : Video Capture
        Pixel Format: 'Y8I '
        Name        : Greyscale 8 L/R (Y8I)
                Size: Discrete 424x240
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 480x270
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 640x360
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 640x480
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 848x480
                        Interval: Discrete 0.011s (90.000 fps)
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 1280x720
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                        Interval: Discrete 0.167s (6.000 fps)
                Size: Discrete 1920x1080
                        Interval: Discrete 0.033s (30.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)

        Index       : 3
        Type        : Video Capture
        Pixel Format: 'Y12I'
        Name        : Greyscale 12 L/R (Y12I)
                Size: Discrete 960x540
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)
                Size: Discrete 1920x1080
                        Interval: Discrete 0.040s (25.000 fps)
                        Interval: Discrete 0.067s (15.000 fps)

Python代码(mcve):

$ cat incorrect_pix_format.SO.py
#!/usr/bin/env python3

from __future__ import print_function

import fcntl
import v4l2

def get_capability(vd):
    cp = v4l2.v4l2_capability()
    fcntl.ioctl(vd, v4l2.VIDIOC_QUERYCAP, cp)
    return cp

def show_capability(cp):
    print("Driver:", cp.driver)
    print("Camera:", cp.card)
    print("video capture device?\t", bool(cp.capabilities & v4l2.V4L2_CAP_VIDEO_CAPTURE))
    print("Supports read() call?\t", bool(cp.capabilities &  v4l2.V4L2_CAP_READWRITE))
    print("Supports streaming?\t", bool(cp.capabilities & v4l2.V4L2_CAP_STREAMING))

def show_format(vd):
    fmt = v4l2.v4l2_format()
    pix_format = v4l2.v4l2_pix_format()
    print("pix_format.width:", pix_format.width)
    print("pix_format.height:", pix_format.height)
    print("pix_format.pixelformat:", pix_format.pixelformat)

if __name__ == "__main__":
    vd = open('/dev/video2', 'rb+', buffering=0)
    print(">> device capabilities")
    cp = get_capability(vd)
    show_capability(cp)
    print(">> format parameters")
    show_format(vd)
    print(">> Stop streaming")
    vd.close()

环境:

OS: Ubuntu 16.04
V4L2 calls based on https://www.linuxtv.org/downloads/legacy/video4linux/API/V4L2_API/spec-single/v4l2.html

看来我的 show_format() 不正确。当我将其更改为:

def show_format(vd):
    fmt = v4l2.v4l2_format()
    fmt.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
    fcntl.ioctl(vd, v4l2.VIDIOC_G_FMT, fmt)
    print("width:", fmt.fmt.pix.width)
    print("height", fmt.fmt.pix.height)
    print("pixelformat", fmt.fmt.pix.pixelformat)

我得到了正确的值。


$ cat incorrect_pix_format.SO.py
#!/usr/bin/env python3

from __future__ import print_function

import fcntl
import v4l2

def get_capability(vd):
    cp = v4l2.v4l2_capability()
    fcntl.ioctl(vd, v4l2.VIDIOC_QUERYCAP, cp)
    return cp

def show_capability(cp):
    print("Driver:", cp.driver)
    print("Camera:", cp.card)
    print("video capture device?\t", bool(cp.capabilities & v4l2.V4L2_CAP_VIDEO_CAPTURE))
    print("Supports read() call?\t", bool(cp.capabilities &  v4l2.V4L2_CAP_READWRITE))
    print("Supports streaming?\t", bool(cp.capabilities & v4l2.V4L2_CAP_STREAMING))

def show_OS_format(vd, type, index):
    fmtdesc = v4l2.v4l2_fmtdesc()
    fmtdesc.type = type
    fmtdesc.index = index
    fcntl.ioctl(vd, v4l2.VIDIOC_ENUM_FMT, fmtdesc)
    print("fmtdesc.description:", fmtdesc.description)
    print("fmtdesc.pixelformat:", fmtdesc.pixelformat)

def show_format(vd):
    fmt = v4l2.v4l2_format()
    fmt.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE
    fcntl.ioctl(vd, v4l2.VIDIOC_G_FMT, fmt)
    print("width:", fmt.fmt.pix.width)
    print("height", fmt.fmt.pix.height)
    print("pixelformat", fmt.fmt.pix.pixelformat)

if __name__ == "__main__":
    vd = open('/dev/video2', 'rb+', buffering=0)
    print(">> device capabilities")
    cp = get_capability(vd)
    show_capability(cp)
    print(">> OS set format")
    show_OS_format(vd, type=v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE, index=1)
    print(">> format parameters")
    show_format(vd)
    print(">> Stop streaming")
    vd.close()
$ python incorrect_pix_format.SO.py
>> device capabilities
Driver: uvcvideo
Camera: Intel(R) RealSense(TM) 410
video capture device?    True
Supports read() call?    False
Supports streaming?      True
>> OS set format
fmtdesc.description: UYVY 4:2:2
fmtdesc.pixelformat: 1498831189
>> format parameters
width: 424
height 240
pixelformat 1498831189
>> Stop streaming