Capturando vídeo de câmeras USB em dispositivos Linux

fundo


Algum tempo atrás, fiquei tentado a "melhorar" um tanque do conhecido conjunto "Batalha de tanques", acrescentando a capacidade de jogar como se eu fosse um motorista de tanque. A ideia surgiu depois de ler vários artigos sobre Habré (por exemplo, aqui: geektimes.ru/post/257528), , WiFi- USB-. : , , , . , , . 32024030, 64048030. 1280720 , — . 19201080 . , PC 1920108030 MJPG . , .


  1. FullHD (19201080) HD (1280720) ( ).
  2. , / .

- :




, . :

  1. WiFi .
  2. , , .
  3. MJPG.

HW SW


  1. Logitech B910 HD (http://www.logitech.com/ru-ru/product/b910-hd-webcam).
  2. TP-LINK TL-MR3020. : CPU MIPS 24K 400MHz, RAM 32 MiB, Flash 4 MiB, Ethernet 100 Mbit, USB 2.0 (http://wiki.openwrt.org/ru/toh/tp-link/tl-mr3020).
  3. . OR-WRT (http://roboforum.ru/wiki/OR-WRT), OpenWRT (http://openwrt.org/, 12.07 15.05).
  4. . , .
  5. “ ”.


-, , , YUV420 19201080 4 MiB (2 ). , MJPG . , FullHD < 500 KiB. . , HTTP mjpg-streamer (http://sourceforge.net/projects/mjpg-streamer/). , 1 + . - , . . , mjpg-streamer №1.


mjpg-streamer , Linux v4l2 . mjpg-streamer, , MJPG . , UVC, .


Estudando o código, cheguei à conclusão de que o tamanho do buffer é solicitado pela câmera e ela retornou o tamanho do quadro não compactado. Esta é provavelmente a solução mais segura do ponto de vista dos desenvolvedores de câmeras. Mas também não é o ideal. Decidi que, no meu caso, você pode ajustar o tamanho do buffer necessário usando a taxa de compressão mínima experimental. Eu escolhi k = 5. Com esse valor, tive uma margem de cerca de 20%.

Uma pequena digressão.
, JPG. . , .

UVC “” , , ( uvc_fixup_video_ctrl()). , quirks, UVC. , , .

, 1280720 19201080. ! !


, , mjpg-streamer . - , mjpg-streamer, . uvc2http.

mjpg-streamer . : 1 . non-blocking IO, : . : , . , . > 1, . , . .., 1 , 3- ( , , , ).

Uvc2http


O Uvc2http consiste em dois componentes: UvcGrabber e HttpStreamer. O primeiro é responsável por receber buffers (quadros) da fila e retorná-los de volta à fila. O segundo é responsável por atender os clientes por HTTP. Há mais um código que vincula esses componentes. Detalhes podem ser encontrados na fonte.

Problema inesperado


Tudo foi maravilhoso: o aplicativo funcionou e na resolução de 1280x720 produziu mais de 20 quadros / s. Fiz alterações cosméticas no código. Após outro lote de alterações, medi a taxa de quadros. O resultado foi deprimente - menos de 15 quadros. Corri para procurar o que levou à degradação. Eu provavelmente passei 2 horas durante as quais a frequência diminuiu a cada medição para um valor de 7 quadros / s. Pensamentos diferentes entraram na minha cabeça sobre degradação devido ao longo trabalho do roteador, devido ao superaquecimento. Era algo incompreensível. Em algum momento, eu desliguei o streaming e vi que apenas uma captura (sem streaming) dava os mesmos 7 quadros. Eu até comecei a suspeitar de problemas com a câmera. Em geral, algumas bobagens. Era de tarde e a câmera, fora da janela, mostrava algo cinza. Para mudar a imagem sombria, virei a câmera para dentro da sala. E eis!A taxa de quadros aumentou para 15 e eu entendi tudo. A câmera ajustou automaticamente o tempo de exposição e, em algum momento, esse tempo ficou mais longo que a duração do quadro em uma determinada frequência. Durante essas duas horas, aconteceu o seguinte: no início, estava gradualmente escurecendo (era noite) e depois virei a câmera para dentro da sala iluminada. Apontando a câmera para o candelabro, obtive mais de 20 quadros / s. Viva.


  1. . 1-1.5 .
  2. . , , qv4l2, . : - . .
  3. . USB , ( ) ( ). USB ( ).
  4. O roteador possui muito pouca memória e espaço em disco. Por esse motivo, recusei o OR-WRT e compilei minha imagem OpenWRT, removendo tudo o que era supérfluo.

resultados


Abaixo está uma placa com os resultados da comparação de mjpg-streamer e uvc2http. Em resumo, há um ganho significativo no consumo de memória e um pequeno ganho na taxa de quadros e na utilização da CPU.
1280x7201920x1080
VSZ, KB, 1 clienteVSZ, KB, 2 clientesCPU,%, 1 clienteCPU,%, 2 clientesFPS, f / s, 1 clienteFPS, f / s, 2 clientesVSZ, KB, 1 clienteVSZ, KB, 2 clientesCPU,%, 1 clienteCPU,%, 2 clientesFPS, f / s, 1 clienteFPS, f / s, 2 clientes
Mjpg-streamer1686019040264317,6quinze254562581228.cinquenta13,810
uvc2http3960396026432219,67576757628.4315,512,2

E claro, o vídeo que fiz com as crianças:



Foto do tanque resultante (ficou parecido com um carrinho de cigano):



Usando


As fontes estão aqui . Para uso no PC Linux, você só precisa compilar (desde que não queira corrigir o driver UVC). O utilitário é construído usando o CMake da maneira padrão. Se você precisar usá-lo no OpenWRT, precisará executar etapas adicionais:

  1. Copie o conteúdo do diretório OpenWrt-15.05 para a raiz do repositório OpenWRT. Esses arquivos são apenas para o OpenWRT 15.05. Eles descrevem um novo pacote para o OpenWRT e um patch para o driver UVC.
  2. , quirk UVC_QUIRK_COMPRESSION_RATE uvc_driver.c. UVC. , wiki.openwrt.org/doc/devel/patches. uvc_ids. :

    /* Logitech B910 HD Webcam */
    	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
    				| USB_DEVICE_ID_MATCH_INT_INFO,
    	  .idVendor		= 0x046d,
    	  .idProduct		= 0x0823,
    	  .bInterfaceClass	= USB_CLASS_VIDEO,
    	  .bInterfaceSubClass	= 1,
    	  .bInterfaceProtocol	= 0,
    	  .driver_info		= UVC_QUIRK_RESTORE_CTRLS_ON_INIT
    				| UVC_QUIRK_COMPRESSION_RATE }, // Enable buffer correction for compressed modes
    

  3. OpenWRT (http://wiki.openwrt.org/doc/howto/build). uvc2http Multimedia.
  4. uvc2http ( ) . , .
  5. /


: . , , . , , (, ), , .

CPU ( 50+ MBit ). .

Source: https://habr.com/ru/post/pt386273/


All Articles