Menggunakan beberapa webcam USB di Linux

28

Menjalankan lebih dari satu webcam USB di Debian / Linux menghasilkan kesalahan berikut:

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

Apa yang awalnya tampak sebagai masalah pemrograman di OpenCV berubah menjadi pencarian untuk masalah hardware / software misterius setelah kesalahan yang sama dihasilkan oleh menjalankan keju dan xawtv.

Tampaknya itu disebabkan oleh webcam yang meminta semua bandwidth yang tersedia pada pengontrol host USB. Dengan pemikiran itu aku memutuskan untuk berlari wireshark dan capinfos untuk melihat seberapa banyak bandwidth yang digunakan kamera tunggal.

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

Menarik! Itu mungkin menjelaskan mengapa dua kamera pada 320x240 berfungsi tetapi resolusi yang lebih tinggi gagal. Sepertinya kontroler USB saya hanya beroperasi pada kecepatan USB 1, belum lsusb menunjukkan kedua kamera web milik perangkat yang seharusnya mendukung 480 megabit per detik.

Salah satu solusi yang diusulkan memaksa webcam untuk menghitung penggunaan bandwidth mereka alih-alih meminta maksimum dengan menjalankan perintah berikut:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

Sayangnya itu tidak ada bedanya, jadi saya memutuskan untuk mencoba solusi lain. Pos di StackOverflow disarankan memberi tahu webcam saya untuk menggunakan FPS yang lebih rendah atau format video terkompresi seperti MJPEG, tetapi setelah berjalan daftar v4lctl tidak muncul salah satu webcam saya yang mendukung perubahan mode video mereka.

Dan di situlah saya terjebak. Mengapa dua webcam beroperasi jauh di bawah kecepatan maksimum USB 2 akan menghasilkan kesalahan ini?

ps: Ini bukan masalah ruang disk, df menampilkan tidak ada perubahan saat webcam dimulai.

pps: Jika ada bedanya, ini dia output dari lsusb

rachelderp
sumber

Jawaban:

24

Ding ding! Berhasil menemukan yang satu ini dengan bantuan dari orang-orang baik di # v4l di freenode.

Singkat cerita: v4l2-ctl adalah alat terbaik untuk debugging masalah kamera USB. Baca semua perintah yang tersedia dan halaman manual, itu akan menyenangkan aku janji. Menggunakan v4l2-ctl Saya menemukan salah satu kamera saya tidak mendukung mode video terkompresi. Anda dapat memeriksa mode apa yang didukung kamera Anda dengan menjalankan perintah berikut:

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

Yang seharusnya menghasilkan sesuatu seperti ini.

 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)

Jika satu-satunya format piksel yang dikembalikan adalah "YUYV", "IUYV", "I420", atau "GBRG" Anda hanya dapat menjalankan satu kamera per pengontrol USB * karena format tersebut tidak terkompresi. Menggunakan beberapa webcam yang mendukung MJPEG atau bentuk kompresi lainnya akan berfungsi dengan baik.

Jika Anda menggunakan OpenCV seperti saya, jangan khawatir jika format piksel default tidak dikompresi karena tampaknya OpenCV tetap menggunakan kompresi.

** Kecuali Anda senang dengan resolusi 320x240 atau lebih rendah. *

rachelderp
sumber
1
Hai, jika mungkin, dapatkah Anda memberi tahu saya cara menetapkan format piksel 2 kamera sehingga saya dapat menangkap keduanya pada 640x480? Saya menggunakan OpenCV dan saat ini mengalami situasi yang sama seperti yang Anda miliki di mana kedua kamera hanya akan bekerja pada 320x240 atau lebih rendah
lexma
Aha! v4l2-ctl memang alat yang luar biasa untuk debugging. Mengetahui banyak tentang kamera saya, dan dapat memperbaiki masalah ini. Bagaimanapun, saya dapat memperbaikinya dengan memaksa resolusi kamera saya 320x240 dan menggunakan YUYV sebagai mode keluaran kamera. guvcview juga banyak membantu.
Sheharyar
Saat menggunakan resolusi 320x240 atau lebih rendah, saya mendapatkan hasil yang beragam. Saya membeli 4 webcam USB murah, semua merek / model yang sama. Ketika mencoba menjalankan 2 pada 160x120, beberapa dari mereka akan bekerja dengan baik bersama-sama dan beberapa memberikan kesalahan memori. Saya tidak melihat sajak atau alasan untuk itu. Memang, webcam ini harganya $ 3 / masing-masing, jadi saya kira saya mendapatkan apa yang saya bayar.
Cerin
Menghubungkan dua kamera atau lebih ke USB3.0 berfungsi dengan baik, bahkan melalui hub USB2.0. Diperiksa dengan YUYV.
Michał Leon
6

Jawabannya adalah menggunakan modifikasi uvcvideo yang ditulis oleh SwDevRefugee, dan dijelaskan di atas. Dia dan saya telah bekerja bersama untuk mendapatkan kode mod'ed dikompilasi untuk OpenWrt, dengan sukses. Versi yang saya gunakan adalah OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), pada router wdr3600 tplink:

HASIL: Saya dapat menjalankan 3 * c270 (logitech) secara simultan pada 1280x960 dan 15fps dalam format MJPG, melalui hub usb 2.0. Saya tidak memiliki c270 keempat untuk dihubungkan, maaf.

Saya juga dapat memiliki 2 * c270 dan 1 * GEMBIRD 640 * 480 * 15fps dengan format YUV, tetapi menambahkan GEMBIRD ke-2 mengarah ke "Tidak dapat memulai penangkapan: Tidak ada ruang yang tersisa di perangkat" (space == bandwidth di sini, seperti Anda kenal baik :)). Perhatikan bahwa GEMBIRD (1908: 2311) == http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/ .

Penggunaan CPU dengan 3 * c270 cukup masuk akal pada 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 --

Jika komunitas memberikan beberapa reputasi dan dukungan, saya pikir SwDevRefugee bersedia memasukkan kodenya ke uvc-linux.

reikred
sumber
3

Saya melihat driver uvcvideo dan quirks = 128 parameter modul diabaikan jika aliran dikompresi mjpeg.

Webcam pilihan saya adalah Logitech C500 dan Logitech C270, dan saya menemukan bahwa gambar yang dihasilkan oleh C500 pada 1280x1024 adalah 100kbytes dan gambar yang dihasilkan oleh C270 pada 1280x960 adalah 200kbytes.

Jika saya menjalankan C270 pada 10fps maka bitrate yang diperlukan adalah 10x200000x8 = 16Mbit / s. Di Ubuntu 14.04 modul uvcdriver selalu mengalokasikan 196Mbit / s terlepas dari frame rate. Untuk C500 itu berperilaku sedikit lebih baik, tetapi masih babi bandwidth.

Saya telah memodifikasi driver uvcvideo sehingga saya dapat memberikan faktor "kompresi" ke driver melalui antarmuka V4L2. Ini adalah "sedikit hacky" di mana saya menggunakan atribut priv di struct v4l2_pix_format untuk menentukan nilai. Dalam driver itu menghitung ukuran gambar yang tidak terkompresi dan kemudian membaginya dengan faktor kompresi untuk mengetahui bandwidth USB yang digunakan.

Secara default saya menggunakan faktor kompresi 10 yang memungkinkan margin besar jika kamera menemukan gambar yang sangat sulit untuk dikompres. C270 berjalan pada 1280x960 dan 10fps sekarang menggunakan 41Mbit / s dan saya dapat dengan mudah menjalankan 4 kamera di satu bus.

Jika ada yang tertarik dengan fitur ini maka saya akan mencoba untuk mendapatkan pengelola uvcvideo untuk mempertimbangkan konsep faktor "kompresi".

SwDevAlien
sumber
Saya, dan berpotensi orang lain dalam Komunitas OpenROV akan tertarik untuk melihat mod Anda ke driver uvc @SwDevRefugee. Saya sedang berusaha untuk mengintegrasikan dua webcam ke dalam OpenROV (satu untuk odometri visual yang tampak ke bawah, yang lain untuk uji coba / tampilan normal), tetapi mengalami masalah BW yang sama. Sudahkah Anda memikirkan untuk mengirim mod / atau mengirimkan permintaan tarik untuk perubahan Anda?
Cara resmi untuk meminta perubahan pada driver uvc adalah melalui milis ini: [email protected]. Saya memposting permintaan perubahan saya pada 30 Desember 2015 bersama dengan beberapa posting berikutnya lainnya dengan informasi lebih lanjut. Saya tidak mendapat tanggapan dari pengelola. Dua orang lainnya telah menyatakan minatnya terhadap perubahan itu. Saya tidak tahu berapa banyak yang diperlukan untuk melakukan tindakan apa pun. Mungkin @laughlinb juga bisa memposting ke milis.
SwDevAlien
@SwDevRefugee: Saya ingin saran Anda unix.stackexchange.com/q/287279/52764
Ragav
@ Ragav: Saya pikir Anda perlu mengisolasi masalah dengan membuka semua kamera secara bersamaan pada resolusi yang sesuai menggunakan aplikasi yang berperilaku baik seperti luvcview yang akan memberi Anda pesan kesalahan informatif jika ada kegagalan.
SwDevAlien
1
Masalah Ragav adalah bahwa kameranya hanya mendukung YUYV dan ketika ia menggunakan quirks = 0x80, pengendara memaksanya untuk menggunakan setidaknya 1024 bytes / mikroframe (65,5 Mbit / s) per kamera. Ini diperparah oleh kenyataan bahwa bandwidth terbesar yang lebih rendah yang didukung kamera adalah 2040 bytes / mikroframe jadi meskipun ia hanya ingin 320x240 pada 6fps ia hanya dapat memiliki 2 kamera pada satu bus USB. Pembatasan minimum 1024 bytes / mikroframe ditambahkan ke driver uvcvideo di suatu tempat antara 2.6.32 dan 3.16 rilis kernel.
SwDevAlien
-1

Saya mendapatkan itu dari kesalahan ruang juga. Apa yang berhasil adalah mencabut salah satu kamera dan menancapkannya ke port USB lain pada PC stasioner saya - ada sekitar 6 atau 7 port USB yang tersebar tentang hal itu. Menjalankan 'show_webcams 0 1' lalu tiba-tiba memunculkan dua gambar.

Peter Thejll
sumber