argus / HSB 取流
argus_camera --mode 0 --duration 1 v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=NV12
# Holoscan Operator 設定感測器源(HSB 通道) # 經乙太網路接收感測器資料進 GPU 管線
⚠️ HSB 取流 API 以 NVIDIA Holoscan 最新文件為準。
# 確認 media 管線 media-ctl -p -d /dev/media0 # 取一幀 v4l2-ctl -d /dev/video0 --stream-mmap=1 --stream-count=1 --stream-to=f.yuv # 檢查格式 v4l2-ctl -d /dev/video0 --list-formats-ext
V4L2 取流不是「一下就開始」,而是一串狀態:idle → initialized(設定 format)→ streaming(buffer 來回)。了解狀態才能看懂錯誤訊息。
| 狀態 | 現象 | 錯誤徵兆 |
|---|---|---|
| streaming 前 | 無幀 | — |
| STREAMON 失敗 | 取流卡住 | format 不被支援、driver 沒準備好 |
| buffer 不足 | 偶發掉幀 | DQ 逾時、EIO |
v4l2-ctl -d /dev/video0 \ --set-fmt-video=width=1280,height=800,pixelformat=NV12 \ --stream-mmap=3 --stream-count=1 --stream-to=frame.nv12 # 驗證檔案大小(NV12 = W×H×1.5 bytes) ls -l frame.nv12 # 期望 ≈ 1280×800×1.5 = 1,536,000 B # 檢查 fourcc 是否真的支援 v4l2-ctl -d /dev/video0 --list-formats-ext
1. media graph 完整且 link 啟用(unit-04)? ├─ 否 → 先修 graph └─ 是 ─┐ 2. format 在支援清單內? ├─ 否 → 換 --list-formats-ext 內的值 └─ 是 ─┐ 3. STREAMON 回傳錯誤? ├─ 是 → 看 dmesg(感測器/CSI 錯誤) └─ 否 ─┐ 4. (HSB) Holoscan 端是否也開始收? └─ 否 → 確認 host/sensor 兩端格式與通道一致
NV12 不是 NV21,YUYV 不是 YU12。寫錯時 driver 多半拒絕或 fallback,要回讀確認。V4L2 取流 buffer 主要有兩種:mmap(driver 分配、應用映射)與 DMABUF(外部/GPU buffer 傳給 driver)。NVIDIA 平台的 GPU 直連管線偏好 DMABUF,讓感測器資料直接落地 GPU 記憶體。
| 方式 | 誰分配 | 適合 |
|---|---|---|
| mmap | driver | 簡單取流、驗證 |
| DMABUF | 應用/GPU | GPU 管線、零拷貝 |
--stream-mmap 驗證鏈路,再用 DMABUF 做效能。場景:Thor T5000 同時接 4 顆 OV9281(各 1280×800 RAW10 @ 120 fps),全部走 CSI。目標:4 路同時取流不掉幀。
# 單顆 OV9281:每幀 1280×800×10/8 = 1,280,000 bytes ≈ 1.22 MB # 4 顆 = 4.88 MB/幀 × 120 fps = 585.6 MB/s # Thor DDR 頻寬 > 100 GB/s → 資料面不是瓶頸 # 瓶頸在:4 組 V4L2 queue 的 DMA 對齊與 buffer 分配 # 方案:DMABUF + 3-buffer deep queue v4l2-ctl -d /dev/video0 --stream-mmap=3 --stream-count=-1 # continuous v4l2-ctl -d /dev/video1 --stream-mmap=3 --stream-count=-1 v4l2-ctl -d /dev/video2 --stream-mmap=3 --stream-count=-1 v4l2-ctl -d /dev/video3 --stream-mmap=3 --stream-count=-1 # 每路 3 buffers × 1.22 MB = 3.66 MB × 4 路 = 14.6 MB # GPU DMABUF 池共需 ~15 MB # 驗證:4 路跑 10 分鐘,監控: cat /sys/kernel/debug/v4l2/video*/queue_status # 每路 queue 的 queued_count 應穩定在 1-2,不持續增加 # 若某路 queued_count 持續上升 → 該路 buffer 被 GPU 占用太久 → 降該路 fps
標準 V4L2 取流是「被動的」:driver 推帧、app 接。Thor 引入了 request API(media request)的增強版:app 可以「預先提交」下一幀的控制參數(曝光、增益),ISP 在該幀被取走時自動套用。這讓多感測器同步曝光成為可能——app 同時對 4 個 video node 提交相同時間戳的 request。
| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
| v4l2-ctl 取流後檔案大小為 0 | stream-count 設定為 0 或 format 未設定就取流 | 先 --set-fmt-video 再 --stream-mmap;確認 stream-count ≥ 1 |
| 4 路同時取流中有一路偶發 timeout | 該路的 DMA buffer 被其他路或 GPU 佔用 | 增加該路 buffer deep queue;確認 DMABUF 池夠大;降低該路 fps |
| NV12 輸出檔案大小不等於 W×H×1.5 | format 設定未生效,driver fallback 到其他 format | 回讀 format(V4L2_QUERYBUF)確認實際 fourcc;用 --list-formats-ext 確認支援 |
| argus_camera 出圖但 v4l2-ctl 取流畫面全黑 | Argus 與 V4L2 使用不同的 buffer 路徑(DMABUF vs mmap) | 統一 buffer 分配方式;或用 argus 做取流、v4l2-ctl 只做 format 驗證 |
| HSB 路徑的取流延遲比 CSI 高 5 ms | 乙太網路封包 + 橋接解包延遲 | 這是正常行為;若延遲不可接受,改用 CSI 或在 HSB 端減少封包大小 |
場景:新開發板到手,目標在 30 分鐘內「取到第一張圖」並確認格式正確,為後續 RAW 分析打基礎。
M1 環境確認(2 min) ├─ media graph 完整(unit-04) └─ 通過:四層 node 全啟用 M2 第一次取流(5 min) ├─ v4l2-ctl --stream-mmap=3 --stream-count=1 --stream-to=first.nv12 └─ 通過:檔案大小 = W×H×1.5 M3 顯示檢查(5 min) ├─ ffplay / 轉 PNG 目視 └─ 通過:畫面非全黑/全綠、無明顯撕裂 M4 格式清單(5 min) ├─ v4l2-ctl --list-formats-ext └─ 通過:記錄 fourcc 與解析度組合 M5 RAW 取樣(5 min) ├─ 以 SRGGB10 取 1 幀 └─ 通過:大小 = W×H×10/8 M6 收尾(8 min) └─ 通過:三份檔案(NV12/RAW/格式清單)進 repo 驗證命令: ls -l first.nv12 # 1280×800 NV12 → 1,536,000 B;SRGGB10 → 1,280,000 B
Step 1 格式查詢 v4l2-ctl -d /dev/video0 --list-formats-ext Step 2 設定格式 v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=800,pixelformat=NV12 Step 3 回讀確認 v4l2-ctl -d /dev/video0 --get-fmt-video # 確認實際套用的格式(可能 fallback) Step 4 取流 v4l2-ctl -d /dev/video0 --stream-mmap=3 --stream-count=1 --stream-to=f.nv12 Step 5 檔案驗證 ls -l f.nv12 # NV12: W×H×1.5;RAW10: W×H×10/8 Step 6 連續性測試 v4l2-ctl -d /dev/video0 --stream-mmap=3 --stream-count=300 --stream-to=f2.nv12 # 300 幀無 timeout 判讀指標: 檔案大小不符 → format fallback(回 Step 2 改) timeout/掉幀 → buffer 深度或頻寬
| 面向 | Thor T5000 | RPi5 | Orange Pi | Orin Nano |
|---|---|---|---|---|
| 標準取流 | v4l2-ctl / argus_camera | libcamera-still / rpicam | v4l2-ctl | v4l2-ctl / argus_camera |
| RAW 取樣 | v4l2-ctl + Holoscan | rpicam --raw | v4l2-ctl | argus raw |
| 連續壓力測試 | --stream-count | --timelapse / burst | --stream-count | --stream-count |
| GPU 路徑取流 | ✅ Holoscan(DMABUF) | ❌ | ❌ | ⚠️ Argus 內部 |
| HSB 網路取流 | ✅ 支援 | ❌ | ❌ | ❌ |
本單元涉及的關鍵 register,以及「讀→改→寫→驗證」的完整位元級操作序列:
| Register | 位址 | 功能 | Bit Field 說明 |
|---|---|---|---|
CSI_PHY_CTRL | 0x0c090000 | CSI PHY 控制 | bit[0]=enable, bit[2:1]=data rate mode, bit[3]=lane power down |
# Step 1: 讀取目前值 $ devmem2 0x0c090000 w # 記錄 current_value # Step 2: 計算新值 $ new_value=$(current_value | 0x0001) # Step 3: 寫入 $ devmem2 0x0c090000 w $new_value # Step 4: 驗證讀回值與預期一致 $ devmem2 0x0c090000 w $ [ "$(devmem2 0x0c090000 w | grep Read)" = "expected" ] && echo "PASS" || echo "FAIL"
1. `nvgstcapture` 無輸出?
├─ 檢查 sensor 是否 streaming:`v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1`
│ ├─ 成功 → argus 設定問題,檢查 sensor_mode ID
│ └─ 失敗 → 回到 sensor bring-up 流程
└─ stream 動但 argus 無輸出 → CSI PHY 未啟用
└─ 檢查 CSI_PHY_CTRL bit[0]1. 延遲 > 100ms? ├─ 網路層延遲:`ping -c 100` 看 avg/max │ ├─ ping > 1ms → cable/switch 問題 │ └─ ping < 1ms → 應用層問題 └─ 應用層:Holoscan queue size 過大,減少 buffer 數
首次取流完整 SOP:
| 步驟 | 動作 | 指令/方法 | 預期輸出 |
|---|---|---|---|
| Step 1 | 硬件就緒確認 | 排線接好、sensor 電源穩定、I2C 可通 | i2cdetect 可見 |
| Step 2 | DT overlay apply | `sudo ubootOverlayApply && sudo reboot` | dmesg 出現 CSI init |
| Step 3 | V4L2 raw stream | `v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=raw.raw` | 檔案非零 |
| Step 4 | argus stream | `nvgstcapture-1.0 -m 1 -E 1` | JPEG 檔案產生 |
| Step 5 | HSB stream(如適用) | Holoscan sensor → GPU pipeline | GPU memory 有分配 |
| Step 6 | 延遲測量 | HSB timestamp - sensor timestamp | < 50ms |
| 面向 | Thor T5000 | RPi5 | Orange Pi | Orin Nano |
|---|---|---|---|---|
| 取流工具 | `nvgstcapture` / Holoscan | `libcamera-hello` | `v4l2-ctl` / `ffplay` | `nvgstcapture` |
| Buffer 管理 | NVMM buffer + GPU direct | V4L2 MMAP | V4L2 MMAP | NVMM buffer |
| 多感測器取流 | Holoscan graph 同步 | `libcamera-hello -c 2` | 需手動 multiplex | nvgst 多 pipeline |
| 延遲目標(sensor→display) | < 30ms(HSB) | < 80ms | < 100ms | < 50ms |
| GPU 直連取流 | ✅ | ❌ | ❌ | ✅ |
| HSB setup 複雜度 | 中(需 config yaml) | N/A | N/A | N/A |
針對「第一個鏡頭跑起來」主題的完整 bring-up 步驟清單: