ใช้เว็บแคม USB หลายตัวใน Linux


30

การใช้งานเว็บแคม USB มากกว่าหนึ่งตัวใน Debian / Linux จะทำให้เกิดข้อผิดพลาดดังต่อไปนี้:

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

สิ่งแรกที่ดูเหมือนจะเป็นปัญหาการเขียนโปรแกรมใน OpenCV กลายเป็นการแสวงหาปัญหาฮาร์ดแวร์ / ซอฟต์แวร์ลึกลับหลังจากข้อผิดพลาดเดียวกันถูกผลิตโดยใช้ชีสและ xawtv

เห็นได้ชัดว่ามันเกิดจากเว็บแคมที่ร้องขอแบนด์วิดท์ที่มีอยู่ทั้งหมดบนตัวควบคุมโฮสต์ USB เมื่อคำนึงถึงสิ่งนี้ฉันจึงตัดสินใจใช้wiresharkและcapinfosเพื่อดูว่าแบนด์วิธที่กล้องตัวเดียวใช้

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

! ที่น่าสนใจ นั่นอาจอธิบายได้ว่าทำไมกล้องสองตัวที่ความละเอียด 320x240 ทำงาน แต่ความละเอียดที่สูงกว่านั้นล้มเหลว มันเหมือนกับว่าคอนโทรลเลอร์ USB ของฉันทำงานที่ความเร็ว USB 1 เท่านั้น แต่lsusb ก็แสดงให้เห็นทั้งเว็บแคมที่เป็นของอุปกรณ์ที่รองรับ 480 เมกะบิตต่อวินาที

ทางออกหนึ่งที่เสนอให้บังคับให้เว็บแคมคำนวณการใช้แบนด์วิดท์แทนการร้องขอสูงสุดโดยเรียกใช้คำสั่งต่อไปนี้:

sudo rmmod uvcvideo
sudo modprobe uvcvideo quirks=128

น่าเสียดายที่ไม่ได้สร้างความแตกต่างดังนั้นฉันจึงตัดสินใจลองวิธีอื่น โพสต์บน StackOverflowแนะนำให้เว็บแคมของฉันใช้ FPS ที่ต่ำกว่าหรือรูปแบบวิดีโอที่บีบอัดเช่น MJPEG แต่หลังจากเรียกใช้รายการ v4lctlมันไม่ปรากฏว่าเว็บแคมของฉันรองรับการเปลี่ยนโหมดวิดีโอ

และนั่นคือสิ่งที่ฉันติดอยู่ ทำไมเว็บแคมสองเว็บที่ทำงานได้ต่ำกว่าความเร็วสูงสุดของ USB 2 จะทำให้เกิดข้อผิดพลาดนี้หรือไม่

ps: มันไม่ใช่ปัญหาพื้นที่ดิสก์ df ไม่เปลี่ยนแปลงเมื่อเว็บแคมเริ่มทำงาน

pps: ถ้ามันสร้างความแตกต่างนี่คือผลลัพธ์ของ lsusb

คำตอบ:


25

Ding ding! จัดการเพื่อคิดสิ่งนี้ด้วยความช่วยเหลือจากคนดีใน # v4l บน freenode

เรื่องสั้น ๆ สั้น ๆ : v4l2-ctlเป็นเครื่องมือที่ดีที่สุดสำหรับการดีบักปัญหากล้อง USB อ่านคำสั่งทั้งหมดที่มีอยู่และหน้าคนมันจะสนุกที่ฉันสัญญา เมื่อใช้v4l2-ctlฉันพบว่ากล้องตัวหนึ่งของฉันไม่รองรับโหมดวิดีโอที่ถูกบีบอัด คุณสามารถตรวจสอบว่ากล้องของคุณรองรับโหมดใดโดยเรียกใช้คำสั่งต่อไปนี้:

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

ซึ่งควรส่งออกบางสิ่งเช่นนี้

 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)

หากรูปแบบพิกเซลที่ส่งคืนคือ "YUYV", "IUYV", "I420" หรือ "GBRG" คุณจะสามารถเรียกใช้กล้องหนึ่งตัวต่อตัวควบคุม USB * เนื่องจากรูปแบบเหล่านั้นจะไม่ถูกบีบอัด การใช้เว็บแคมหลายตัวที่รองรับ MJPEG หรือรูปแบบการบีบอัดอื่น ๆ จะทำงานได้ดี

หากคุณใช้ OpenCV อย่างฉันไม่ต้องกังวลว่ารูปแบบพิกเซลเริ่มต้นจะไม่ถูกบีบอัดเนื่องจากจะปรากฏเป็นค่าเริ่มต้นของ OpenCV ที่จะใช้การบีบอัดต่อไป

** ถ้าคุณไม่พอใจกับความละเอียด 320x240 หรือต่ำกว่า *


1
สวัสดีถ้าเป็นไปได้คุณจะบอกฉันได้อย่างไรว่าฉันควรตั้งค่ารูปแบบพิกเซลของกล้อง 2 ตัวเพื่อให้สามารถจับภาพทั้งสองได้ที่ 640x480 หรือไม่ ฉันใช้ OpenCV และปัจจุบันประสบสถานการณ์เช่นเดียวกับที่คุณมีซึ่งกล้องทั้งสองจะทำงานที่ 320x240 หรือต่ำกว่า
lexma

Aha! v4l2-ctlแน่นอนเป็นเครื่องมือที่ยอดเยี่ยมสำหรับการแก้จุดบกพร่อง เรียนรู้มากมายเกี่ยวกับกล้องของฉันและสามารถแก้ไขปัญหาได้ อย่างไรก็ตามฉันสามารถแก้ไขได้โดยบังคับให้ความละเอียดกล้องของฉันไปที่320x240และใช้YUYVเป็นโหมดการแสดงผลของกล้อง guvcviewยังช่วยได้มาก
Sheharyar

เมื่อใช้ความละเอียด 320x240 หรือต่ำกว่าฉันจะได้ผลลัพธ์ที่หลากหลาย ฉันซื้อเว็บแคม USB ราคาถูก 4 อันทุกยี่ห้อ / รุ่นเดียวกัน เมื่อพยายามเรียกใช้ 2 ที่ 160x120 บางส่วนจะทำงานร่วมกันได้ดี ฉันไม่เห็นสัมผัสหรือเหตุผลกับมัน ได้รับเว็บแคมเหล่านี้มีค่าใช้จ่าย $ 3 / ต่อคนดังนั้นฉันเดาว่าฉันได้รับสิ่งที่ฉันจ่ายไป
Cerin

การเชื่อมต่อกล้องสองตัวขึ้นไปเข้ากับ USB3.0 นั้นใช้ได้แม้ผ่านฮับ USB2.0 ตรวจสอบกับ YUYV
Michał Leon

7

คำตอบคือใช้การดัดแปลง uvcvideo ที่เขียนโดย SwDevRefugee และอธิบายไว้ข้างต้น เขาและฉันทำงานร่วมกันเพื่อรับรหัส mod'ed ที่รวบรวมสำหรับ OpenWrt ด้วยความสำเร็จ รุ่นที่ฉันเรียกใช้คือ OpenWRT DESIGNATED DRIVER (Bleeding Edge, r48130), บนเราเตอร์ tplink wdr3600:

ผลลัพธ์: ฉันสามารถมี 3 * c270 (logitech) ทำงานพร้อมกันที่ 1280x960 และ 15fps ในรูปแบบ MJPG ผ่านฮับ usb 2.0 ฉันไม่มี c270 ตัวที่สี่ที่จะขอให้ขอโทษด้วย

ฉันยังสามารถมี 2 * c270 และ 1 * GEMBIRD 640 * 480 * 15fps ด้วยรูปแบบ YUV แต่การเพิ่ม GEMBIRD ที่ 2 นำไปสู่ความหวาดกลัว "ไม่สามารถเริ่มจับภาพได้: ไม่มีพื้นที่เหลือบนอุปกรณ์" (space == แบนด์วิดท์ที่นี่ รู้ดี:)). โปรดทราบว่า Gembird (1908: 2311) == http://www.penguin.cz/~utx/hardware/USB_Camera_AX2311/

การใช้ CPU ที่มี 3 * c270 นั้นสมเหตุสมผลใน 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 --

หากชุมชนให้ชื่อเสียงและการสนับสนุนฉันคิดว่า SwDevRefugee ยินดีที่จะรับโค้ดเป็น uvc-linux


4

ฉันดูไดรเวอร์ uvcvideo และพารามิเตอร์โมดูล quirks = 128 จะถูกละเว้นหากสตรีมถูกบีบอัด mjpeg

เว็บแคมที่ฉันเลือกคือ Logitech C500 และ Logitech C270 และฉันพบว่ารูปภาพที่ผลิตโดย C500 ที่ 1280x1024 คือ 100kbytes และภาพที่ผลิตโดย C270 ที่ 1280x960 คือ 200kbytes

ถ้าฉันรัน C270 ที่ 10fps แล้วบิตเรตที่ต้องการคือ 10x200000x8 = 16Mbit / s ใน Ubuntu 14.04 โมดูล uvcdriver จะจัดสรร 196Mbits / s เสมอโดยไม่คำนึงถึงอัตราเฟรม สำหรับ C500 มันมีพฤติกรรมที่ดีขึ้นเล็กน้อย แต่ก็ยังเป็นแบนด์วิธหมู

ฉันได้ปรับเปลี่ยนไดรเวอร์ uvcvideo เพื่อให้ฉันสามารถจัดเตรียมปัจจัย "การบีบอัด" ให้กับไดรเวอร์ผ่านอินเทอร์เฟซ V4L2 มันเป็น "แฮ็กน้อย" ที่ฉันใช้คุณลักษณะส่วนตัวใน struct v4l2_pix_format เพื่อระบุค่า ในไดรเวอร์จะคำนวณขนาดของอิมเมจที่ไม่มีการบีบอัดแล้วหารด้วยปัจจัยการบีบอัดเพื่อกำหนดแบนด์วิธ USB ที่จะใช้

ตามค่าเริ่มต้นฉันใช้อัตราการบีบอัดที่ 10 ซึ่งอนุญาตให้มีระยะขอบขนาดใหญ่หากกล้องพบภาพที่ยากเป็นพิเศษในการบีบอัด C270 ทำงานที่ 1280x960 และ 10fps ตอนนี้ใช้ 41Mbit / s และฉันสามารถเรียกใช้กล้อง 4 ตัวบนบัสเดียวได้อย่างง่ายดาย

หากใครสนใจคุณสมบัตินี้ฉันจะพยายามทำให้ uvcvideo ผู้ดูแลพิจารณาแนวคิดของ "การบีบอัด"


ฉันและคนอื่น ๆ ในชุมชน OpenROVจะกระตือรือร้นที่จะเห็น mod ของคุณไปยังไดรเวอร์ uvc @SwDevRefugee ฉันกำลังพยายามที่จะรวมเว็บแคมสองตัวเข้ากับ OpenROV (อันหนึ่งสำหรับ Odometry ที่มองลงด้านล่างอีกอันสำหรับการนำร่อง / การดูแบบปกติ) แต่ทำงานเป็นประเด็น BW เดียวกัน คุณคิดที่จะโพสต์ mod / หรือส่งคำขอการดึงสำหรับการเปลี่ยนแปลงของคุณหรือไม่?

วิธีการอย่างเป็นทางการในการร้องขอการเปลี่ยนแปลงไดรเวอร์ uvc คือผ่านรายการส่งเมลนี้: linux-uvc-devel@lists.sourceforge.net ฉันโพสต์คำขอเปลี่ยนแปลงของฉันในวันที่ 30 ธันวาคม 2015 พร้อมกับโพสต์อื่น ๆ ที่ตามมาพร้อมข้อมูลเพิ่มเติม ฉันไม่ได้รับคำตอบจากผู้ดูแล อีกสองคนแสดงความสนใจในการเปลี่ยนแปลง ฉันไม่รู้ว่าต้องมีจำนวนเท่าใดในการดำเนินการใด ๆ บางที @laughlinb สามารถโพสต์ลงในรายชื่อผู้รับจดหมายได้เช่นกัน
SwDevAlien

@SwDevRefugee: ฉันต้องการคำแนะนำของคุณunix.stackexchange.com/q/287279/52764
Ragav

@Ragav: ฉันคิดว่าคุณต้องแยกปัญหาด้วยการเปิดกล้องทั้งหมดพร้อมกันด้วยความละเอียดที่เหมาะสมโดยใช้แอพพลิเคชั่นที่มีพฤติกรรมดีเช่น luvcview ซึ่งควรให้ข้อความแสดงข้อผิดพลาดหากมีข้อผิดพลาด
SwDevAlien

1
ปัญหาของ Ragav คือกล้องของเขารองรับเฉพาะ YUYV และเมื่อเขาใช้ quirks = 0x80 ติดธงผู้ขับขี่บังคับให้เขาใช้อย่างน้อย 1024 ไบต์ / microframe (65.5 Mbit / s) ต่อกล้อง นี่คือความจริงที่ว่าแบนด์วิธที่ต่ำที่สุดที่กล้องรองรับคือ 2040 bytes / microframe ดังนั้นถึงแม้ว่าเขาต้องการเพียง 320x240 ที่ 6fps เขาก็สามารถมีกล้องได้ 2 ตัวบนบัส USB หนึ่งบัส ข้อ จำกัด ขั้นต่ำ 1024 ไบต์ / microframe ถูกเพิ่มลงในไดรเวอร์ uvcvideo บางแห่งระหว่างการปล่อยเคอร์เนล 2.6.32 ถึง 3.16
SwDevAlien

-1

ฉันได้รับข้อผิดพลาดนอกพื้นที่เช่นกัน สิ่งที่ใช้ได้คือถอดปลั๊กกล้องตัวใดตัวหนึ่งแล้วต่อเข้ากับพอร์ต USB อื่นบนพีซีที่อยู่กับที่ - มีพอร์ต USB 6 หรือ 7 พอร์ตกระจายอยู่รอบ ๆ เรียกใช้ 'show_webcams 0 1' จากนั้นก็นำภาพทั้งสองขึ้นมา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.