如何限制 USB 裝置在 Linux 上可以分配的頻寬量?
我有幾個便宜的 USB 網路攝影機,我試圖同時運行它們。運行v4l2-ctl --list-formats-ext --device=/dev/videoN
表明它們都支援 30 FPS 和 15 FPS 的多種未壓縮分辨率。
然而,即使我將一個設備配置為以 15 FPS、160x120 解析度進行捕捉,它仍然會分配 480 Mbps 的頻寬,通常會阻止我使用任何其他 USB 設備,更不用說第二個網路攝影機了。嘗試以相同的 FPS/解析度從第二個網路攝影機進行擷取會導致錯誤:
libv4l2: error turning on stream: No space left on device
VIDIOC_STREAMON: No space left on device
谷歌搜尋這個錯誤通常會得到類似這樣的答案:「你是 SOL,也許買一台支援 MJPG 的相機?」。
但這完全沒有意義。
捕捉未壓縮的 160x120 RGB 等於每幀 160*120*3 = 57600 位元組。在 15 FPS 下,每秒至少需要 864000 位元組的頻寬(即高達0.864Mbps或者6.912 兆比特)!我有 USB2 集線器,支持480兆位元/秒。我應該有足夠的頻寬來同時運行數十個這樣的網路攝像頭,但運行一個攝像頭幾乎消耗了我 USB 集線器的全部 480 Mb!
由於相機不需要 480 Mbps 來傳輸 160x120,但它告訴驅動程式分配那麼多,有沒有辦法在作業系統層級強制驅動程式分配一定的數量?
答案1
這傢伙提供一個辦法這似乎對某些人有用。就我而言,我已經嘗試過了,但它沒有改變任何東西,但它非常依賴硬體。
uvcvideo 核心模組可以設定為忽略請求的頻寬,並計算正確的頻寬。嘗試:
sudo rmmod uvcvideo sudo modprobe uvcvideo quirks=128
每次重新啟動都會重置此值。如果有效,請建立以下文件:
sudo vi /etc/modprobe.d/uvcvideo.conf
包含行:
options uvcvideo quirks=128
確實,在這一頁他們說這可能並不總是有效,他們甚至提供了更改驅動程式的函數 uvc_init_video() 中的程式碼的選項:
/* Isochronous endpoint, select the alternate setting. */ bandwidth = stream->ctrl.dwMaxPayloadTransferSize;