zoomでWebミーティングに参加してみたら、
画面が真っ白。
C270自体は正常に動作しているので、USB2.0が遅いのかなぁ...。
とりあえず試したことをメモしておく。
2022.7.10追記 EMEET C970L(60fps)に変更したところ問題なくZoomで使えるようになりました。
ハード構成
もう10年近く使っているPC。ほんとよく働いてくれています。
外部テスト
ZoomでC270からキャプチャーできない
試しにCheeseでキャプチャーしてみる
どうもカメラ自体は生きているらしい。
というわけで面倒だがOSから調査してみる。
デバイスまわりの調査
USBとデバイスの関係
まずはWebcam C270がUSBデバイスとして認識されているかを確認する。
$ lsusb
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 006: ID 07ca:1513 AVerMedia Technologies, Inc. Live Gamer Portable 2 Plus
Bus 001 Device 005: ID 046d:0825 Logitech, Inc. Webcam C270
Bus 001 Device 003: ID 0bda:4938 Realtek Semiconductor Corp. Realtek Audio USB
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 002: ID 04f2:0939 Chicony Electronics Co., Ltd Amazon Basics mouse
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 002: ID 04f3:0103 Elan Microelectronics Corp. ActiveJet K-2024 Multimedia Keyboard
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
USBバス1番のポート5番(Device 5番)にWebcam 270が繋がっていることがわかる。
つぎにWebcam 270がどのスペシャルファイル(/dev/videoX)として認識されているか確認する。
$ v4l2-ctl --list-devices
UVC Camera (046d:0825) (usb-0000:00:1a.7-5):
/dev/video0
/dev/video1
Webcamは汎用的なWebカメラであるUVCカメラとして認識されており、/dev/video0,/dev/video1という2つのデバイスとして認識されている。
/dev/video0はビデオデータそのもので、/dev/video1はメタデータが格納されている。通常は/dev/video0の方をビデオデバイスとして扱う。
一応確認しておこう。
$ v4l2-ctl -d /dev/video0 --all | grep Format | grep Capture Format Video Capture: $ v4l2-ctl -d /dev/video1 --all | grep Format | grep Capture Format Metadata Capture:
/dev/video0がどんなデバイスとして認識されているのか
/dev/video0がWebcamだとわかったので、どんな仕様なのか確認してみる。
確認すべきポイントは画像の形式、解像度とフレームレートの3つ。
$ v4l2-ctl -d /dev/video0 --list-formats [0]: 'YUYV' (YUYV 4:2;2) [1]: 'MJPG' (Motion-JPEG, compressed)
どうやらWebcam C270でキャプチャーしたデータはYUYVかJMPG形式で出力されるらしい。最近はやりのH264やH265は扱えない模様。
つぎに解像度を調べてみる
$ v4l2-ctl -d /dev/video0 --list-formats-ext ioctl: VIDIOC_ENUM_FMT Type: Video Capture[0]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 160x120
Interval: Discrete 0.033s (30.000 fps)
(以下略) [1]: 'MJPG' (Motion-JPEG, compressed)Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Interval: Discrete 0.050s (20.000 fps)
Interval: Discrete 0.067s (15.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Interval: Discrete 0.200s (5.000 fps)
(以下略)
画像の形式ごとに使用できる解像度とフレームレートが表示される。
C270は160x120〜1280x960の解像度を扱うことができ、YUYV形式の場合は解像度が上がるとフレームレートは下がるが、MJPG形式であれば30fpsを維持できることがわかる。
ソフトウェアが要求しているスペックを確認してみる
Zoomの場合
Zoomでミーティングに参加してみる。当然先ほどと同様に真っ白の画面が表示される。
一旦Zoomを終了して、/dev/video0がどの様に使われたか確認してみる。
まずは画像タイプと解像度。
$ v4l2-ctl -d /dev/video0 -V Format Video Capture: Width/Height : 640/480 Pixel Format : 'MJPG' (Motion-JPEG) Field : None Bytes per Line : 0 Size Image : 341333 Colorspace : sRGB Transfer Function : Default (maps to sRGB) YCbCr/HSV Encoding: Default (maps to ITU-R 601) Quantization : Default (maps to Full Range) Flags :
次にフレームレート
$ v4l2-ctl -d /dev/video0 --get-parm
Streaming Parameters Video Capture:
Capabilities : timeperframe
Frames per second: 30.000 (30/1)
Read buffers : 0
上記から、Zoomは MJPG形式で640x480 (30fps)の性能を要求していることがわかる。
C270はこのスペックを満たしているので、本来であれば問題なく映像が表示されるはずだ。しかし実際には真っ白。(カラーバランスも調整してみたが変わらず。)
Chesseの場合
同様にCheeseを起動して要求スペックを確認したところ、YUYV形式で800x600(20fps)であることがわかった。
C270はこのスペックを満たしており、正常に表示できている。
Ubuntu 22.04ではCheeseでも表示できなくなりました。フレームレートが30fpsになった様です
何となく原因がわかった
フレームレートが足りていない説
Zoomが30fpsを要求しているがC270は表示できない。
Cheeseは20fpsを要求しておりC270は表示できている。
ということは、C270が30fpsを実現できていないか、USB2.0のバススピードが30fpsについていけて無いのではないか?
V4L2 Test Benchでテストしてみた
かつてv4l2ucpという優れたツールがあり、他のアプリケーションがキャプチャーしている映像の解像度をリアルタイムで変更することができた。
現在はその様なツールは無い。残念。
v4l2-ctlツールで以下の様にして設定することも一応は可能。
$ v4l2-ctl -d /dev/video0 --set-fmt-video width=1280,height=720,pixelformat='YUYV' $ v4l2-ctl -d /dev/video0 --set-parm=25 ←フレームレート
ただ、この方法では他のアプリケーションが使用している時に割り込むことはできない。(Device busyでエラーになる)
仕方ないのであくまでシミュレーションとしてV4L2 Test Bench(qv4l2)を使う。
その結果は以下の通り。
MJPG 960x720 (30fps) → 表示できない MJPG 960x720 (25fps) → 表示できた MJPG 800x600 (30fps) → 表示できない MJPG 800x600 (20fps) → 表示できた Cheeseと同じ結果 MJPG 640x480 (30fps) → 表示できない。 Zoomと同じ結果 MJPG 640x480 (25fps) → 表示できた MJPG 160x120 (30fps) → 表示できない MJPG 160x120 (25fps) → 表示できた
原因はC270か?
原因として3つ考えてみた。
- PCの処理が追いついていない。
PCを再起動した直後にZoomを使うと砂嵐の様になりながらも一応カメラとして何かの表示はされる。しかし時間が経つと全く表示されなくなる。
topを見る限り負荷はそれほどかかっていなさそうだが、ガベレージコレクション的な何かが溜まっているのかも知れない。 - USBの速度が遅い
解像度を960x720に上げても25fpsなら表示できる。逆に160x120に落としても30fpsで表示できない。転送データを少なくしても30fpsで表示できないということは転送量/転送速度の問題ではないと思う。 - C270の故障
スペック的には30fpsと記載があるのですが、個体差があるようです。消去法でこの可能性が高そう。
念の為ノートPCの内蔵カメラを使えば問題なくZoomを使える。もちろんOSは同じUbuntu 20.10。
カメラを買い直すかZoomが要求するスペックが20fpsくらいまで落ちれば問題なく使えるはず。次のボーナスで買い換えるかな。