O V4L2 não usa uma taxa de quadros anunciada mais baixa


1

Estou capturando imagens no Linux (Pi 3B +, Stretch lite). A câmera relata que é capaz de fornecer imagens a 30 qps ou 60 qps. Aqui está a saída dev4l2-ctl

v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'YU12'
        Name        : Planar YUV 4:2:0
                Size: Discrete 640x512
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'Y16 '
        Name        : 16-bit Greyscale
                Size: Discrete 640x512
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)

        Index       : 2
        Type        : Video Capture
        Pixel Format: 'NV12'
        Name        : Y/CbCr 4:2:0
                Size: Discrete 640x512
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)

        Index       : 3
        Type        : Video Capture
        Pixel Format: ''
        Name        : 3132564e-0000-0010-8000-00aa003
                Size: Discrete 640x512
                        Interval: Discrete 0.017s (60.000 fps)
                        Interval: Discrete 0.033s (30.000 fps)

Mas se eu tentar mudar para 30fps:

v4l2-ctl -d /dev/video0 --set-parm=30 --set-fmt-video=width=640,height=512,pixelformat="Y16 " --stream-mmap --stream-count=240 --stream-to=video.raw
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 59.40 fps
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 59.70 fps

A taxa de quadros é simplesmente ignorada.

Posso verificar isso usando usbmon(ferramenta incrível):

Capturando aos 60:

Bus ID 1 (USB bus number 1)     To device       From device
  Device ID 1 :                 0.00 kb/s       0.00 kb/s
  Device ID 2 :                 0.00 kb/s       0.00 kb/s
  Device ID 3 :                 0.00 kb/s       0.00 kb/s
  Device ID 4 :                 0.00 kb/s       0.00 kb/s
  Device ID 6 :                 155.67 kb/s     39075.21 kb/s

Capturando em "30":

Bus ID 1 (USB bus number 1)     To device       From device
  Device ID 1 :                 0.00 kb/s       0.00 kb/s
  Device ID 2 :                 0.00 kb/s       0.00 kb/s
  Device ID 3 :                 0.00 kb/s       0.00 kb/s
  Device ID 4 :                 0.00 kb/s       0.00 kb/s
  Device ID 6 :                 148.34 kb/s     39056.18 kb/s

Isso é consistente com 640x512x2x60 = 39,3 MB por segundo.

O problema é que, se a câmera está se forçando a usar 60fps, está alocando mais largura de banda de barramento do que precisa (e outras câmeras não funcionam porque alegam que não há largura de banda suficiente disponível). Portanto, embora eu possa acelerar o fluxo, no nível do hardware, isso não ajuda.

O Gstreamer também não parece funcionar, mas acho que está usando o V4L2 para captura. Por exemplo:

timeout 15s gst-launch-1.0 -v v4l2src device=/dev/video0 ! video/x-raw,format=GRAY16_LE,framerate=30/1 ! videoconvert ! filesink location=video_30.raw

Existe algum outro back-end de vídeo que eu possa tentar? Ou existe uma maneira melhor de definir a taxa de quadros?


Eu compilaria v4l-utils com impressões de depuração, verificando especificamente se o ioctl VIDIOC_S_PARMfoi bem-sucedido.
dafnahaktana
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.