Utilisation de plusieurs webcams USB sous Linux

30

L'exécution de plus d'une webcam USB dans Debian / Linux entraîne l'erreur suivante:

libv4l2: error turning on stream: No space left on device
VIDIOC_STREAMON: No space left on device

Ce qui semblait initialement être un problème de programmation dans OpenCV s'est transformé en quête d'un mystérieux problème matériel / logiciel après que les mêmes erreurs ont été produites en exécutant cheese et xawtv.

Apparemment, cela est dû au fait que les webcams demandent toute la bande passante disponible sur le contrôleur hôte USB. Dans cet esprit, j'ai décidé d'exécuter WireShark et Capinfos pour voir la bande passante utilisée par une seule caméra.

4 megabits per second at 320x240
14 megabits per second at 640x480
32 megabits per second at 1280x720

Intéressant! Cela pourrait expliquer pourquoi deux caméras à 320x240 fonctionnent mais toute résolution supérieure échoue. C'est comme si mon contrôleur USB ne fonctionnait qu'à des vitesses USB 1, mais lsusb affiche les deux webcams appartenant à un appareil qui prend en charge soi-disant 480 mégabits par seconde.

Une solution a proposé de forcer les webcams à calculer leur utilisation de bande passante au lieu de demander leur maximum en exécutant les commandes suivantes:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

Malheureusement, cela n'a fait aucune différence, j'ai donc décidé d'essayer une autre solution. Un message sur StackOverflow a suggéré de dire à mes webcams d'utiliser un FPS inférieur ou un format vidéo compressé comme MJPEG, mais après avoir exécuté la liste v4lctl, aucune de mes webcams ne prend en charge la modification de leur mode vidéo.

Et c'est là que je suis coincé. Pourquoi deux webcams fonctionnant bien en dessous de la vitesse maximale d'USB 2 produiraient-elles cette erreur?

ps: Ce n'est pas un problème d'espace disque, df n'affiche aucun changement au démarrage des webcams.

pps: Si cela fait une différence, voici la sortie de lsusb

rachelderp
la source

Réponses:

25

Ding Ding! J'ai réussi à comprendre celui-ci avec l'aide des gens sympas de # v4l sur freenode.

En bref: v4l2-ctl est le meilleur outil pour déboguer les problèmes de caméra USB. Lisez toutes les commandes disponibles et la page de manuel, ce sera amusant je vous le promets. En utilisant v4l2-ctl, j'ai découvert que l'un de mes appareils photo ne prenait en charge aucun mode vidéo compressé. Vous pouvez vérifier les modes pris en charge par vos caméras en exécutant la commande suivante:

v4l2-ctl -d /dev/video0 --list-formats

Ce qui devrait produire quelque chose comme ça.

 ioctl: VIDIOC_ENUM_FMT
 Index       : 0
 Type        : Video Capture
 Pixel Format: 'MJPG' (compressed)
 Name        : MJPEG

 Index       : 1
 Type        : Video Capture
 Pixel Format: 'YUYV'
 Name        : YUV 4:2:2 (YUYV)

Si le seul format de pixel renvoyé est "YUYV", "IUYV", "I420" ou "GBRG", vous ne pourrez exécuter qu'une seule caméra par contrôleur USB * car ces formats ne sont pas compressés. L'utilisation de plusieurs webcams prenant en charge MJPEG ou une autre forme de compression fonctionnera correctement.

Si vous utilisez OpenCV comme moi, ne vous inquiétez pas si le format de pixel par défaut n'est pas compressé car il semble qu'OpenCV utilise par défaut la compression de toute façon.

** Sauf si vous êtes satisfait de la résolution 320x240 ou inférieure. *

rachelderp
la source
1
Salut, si possible, pouvez-vous me dire comment définir le format de pixel de 2 caméras afin de pouvoir capturer les deux à 640x480? J'utilise OpenCV et je vis actuellement la même situation que vous, où les deux caméras ne fonctionneront qu'à 320x240 ou moins
lexma
Ah! v4l2-ctlest en effet un excellent outil de débogage. J'ai beaucoup appris sur mon appareil photo et j'ai pu résoudre le problème. Quoi qu'il en soit, j'ai pu le corriger en forçant la résolution de mon appareil photo 320x240et en l'utilisant YUYVcomme mode de sortie de l'appareil photo. guvcviewa également beaucoup aidé.
Sheharyar
Lorsque j'utilise des résolutions de 320x240 ou moins, j'obtiens des résultats mitigés. J'ai acheté 4 webcams USB bon marché, toutes de même marque / modèle. Lorsque vous tentiez d'exécuter 2 à 160x120, certains d'entre eux fonctionneraient bien ensemble et certains donnaient l'erreur de mémoire. Je n'y vois ni rime ni raison. Certes, ces webcams coûtent 3 $ / chacune, donc je suppose que j'ai eu ce que j'ai payé.
Cerin
La connexion de deux ou plusieurs de ces caméras à USB3.0 fonctionne correctement, même via un concentrateur USB2.0. Vérifié avec YUYV.
Michał Leon
7

La réponse est d'utiliser les modifications uvcvideo écrites par SwDevRefugee et décrites ci-dessus. Lui et moi avons travaillé ensemble pour obtenir le code mod'ed compilé pour OpenWrt, avec succès. La version sur laquelle je l'exécute est OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), sur un routeur tplink wdr3600:

RÉSULTAT: Je peux avoir 3 * c270 (logitech) fonctionnant simultanément à 1280x960 et 15fps au format MJPG, via un hub USB 2.0. Je n'ai pas de quatrième c270 à brancher, désolé.

Je peux également avoir 2 * c270 et 1 * GEMBIRD 640 * 480 * 15fps avec le format YUV, mais l'ajout d'un 2ème GEMBIRD conduit à la redoutable "Impossible de démarrer la capture: il n'y a plus d'espace sur l'appareil" (espace == bande passante ici, comme vous Bien connaître:)). Notez que GEMBIRD (1908: 2311) == http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/ .

L'utilisation du processeur avec 3 * c270 est assez raisonnable sur un wdr3600:

Mem: 50600K used, 75444K free, 320K shrd, 3436K buff, 8800K cached

CPU:  16% usr  27% sys   0% nic  45% idle   0% io   0% irq  10% sirq

Load average: 1.20 0.85 0.44 4/60 2546

  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND

 2240  1679 root     S    15348  12%  17% mjpg_streamer --input input_uvc.so --

 2505  1679 root     S    15368  12%  11% mjpg_streamer --input input_uvc.so --

 2239  1679 root     S    15532  12%  11% mjpg_streamer --input input_uvc.so --

Si la communauté donne une certaine réputation et un certain soutien, je pense que SwDevRefugee est prêt à introduire le code dans uvc-linux.

reikred
la source
4

J'ai regardé le pilote uvcvideo et le paramètre du module quirks = 128 est ignoré si le flux est compressé en mjpeg.

Mes webcams de choix ont été le Logitech C500 et le Logitech C270, et j'ai trouvé que l'image produite par le C500 à 1280x1024 est de 100 Ko et l'image produite par le C270 à 1280x960 est de 200 Ko.

Si j'exécute le C270 à 10fps, le débit requis est 10x200000x8 = 16Mbit / s. Dans Ubuntu 14.04, le module uvcdriver alloue toujours 196 Mbits / s quelle que soit la fréquence d'images. Pour le C500, il se comporte un peu mieux, mais reste un porc de bande passante.

J'ai modifié le pilote uvcvideo afin de pouvoir fournir un facteur de "compression" au pilote via l'interface V4L2. C'est un "petit hacky" en ce que j'ai utilisé l'attribut priv dans la struct v4l2_pix_format pour spécifier la valeur. Dans le pilote, il calcule la taille de l'image non compressée, puis la divise par le facteur de compression pour déterminer la bande passante USB à utiliser.

Par défaut, j'utilise un facteur de compression de 10 qui permet une grande marge si l'appareil photo rencontre une image particulièrement difficile à compresser. Le C270 fonctionnant à 1280x960 et 10fps utilise maintenant 41Mbit / s et je peux facilement exécuter 4 caméras sur un bus.

Si quelqu'un est intéressé par cette fonctionnalité, j'essaierai d'amener les responsables uvcvideo à considérer le concept de facteur de "compression".

SwDevAlien
la source
Moi, et potentiellement d'autres membres de la communauté OpenROV, serions ravis de voir votre mod pour le pilote uvc @SwDevRefugee. Je cherche à intégrer deux webcams dans OpenROV (l'une pour l'odométrie visuelle descendante, l'autre pour le pilotage / visualisation normal), mais je rencontre le même problème BW. Avez-vous pensé à publier votre mod / ou à soumettre une demande de pull pour votre modification?
La manière officielle de demander des modifications au pilote uvc est via cette liste de diffusion: [email protected]. J'ai posté ma demande de changement le 30 décembre 2015 ainsi que d'autres messages ultérieurs contenant de plus amples informations. Je n'ai reçu aucune réponse d'un responsable. Deux autres personnes ont manifesté leur intérêt pour le changement. Je ne sais pas combien sont nécessaires pour obtenir une action. Peut-être que @laughlinb pourrait également publier sur la liste de diffusion.
SwDevAlien
@SwDevRefugee: Je voudrais votre avis unix.stackexchange.com/q/287279/52764
Ragav
@Ragav: Je pense que vous devez isoler le problème en ouvrant toutes les caméras simultanément aux résolutions appropriées en utilisant une application bien comportée comme luvcview qui devrait vous donner des messages d'erreur informatifs en cas de panne.
SwDevAlien
1
Le problème de Ragav est que ses caméras ne prennent en charge que YUYV et lorsqu'il utilise le drapeau quirks = 0x80, le pilote l'oblige à utiliser au moins 1024 octets / microframe (65,5 Mbit / s) par caméra. Cela est aggravé par le fait que la plus grande bande passante la plus faible prise en charge par les caméras est de 2040 octets / microframe, même s'il ne veut que 320x240 à 6 images par seconde, il ne peut avoir que 2 caméras sur un bus USB. La restriction minimale de 1024 octets / microframe a été ajoutée au pilote uvcvideo quelque part entre les versions 2.6.32 et 3.16 du noyau.
SwDevAlien
-1

J'ai aussi obtenu cette erreur d'espace. Ce qui a fonctionné, c'est de débrancher l'une des caméras et de la brancher sur un autre port USB de mon PC fixe - il y a environ 6 ou 7 ports USB dispersés à ce sujet. L'exécution de «show_webcams 0 1» a soudainement fait apparaître les deux images.

Peter Thejll
la source