Search code examples
pythonlinux-kernelubuntu-16.04v4l2pixelformat

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


I'm trying to set a V4L2 camera's parameters according to the V4L2 API.
However, seems the API does not display the correct parameters as were set by the OS.

Can you suggest how to debug this issue to figure if the failure of the camera to show the correct parameters is a problem

  • with my code,
  • with the camera,
  • or with the API?



Problem demonstration:

$ 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 code (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()

Environment:

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

Solution

  • Seems my show_format() was incorrect. When I changed it to:

    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)
    

    I get the correct values.


    $ 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