visionA/docs/autoflow/04-architecture/adr/adr-020-ffmpeg-camera-indev.md
jim800121chen f6d15b7b14 docs(arch): B 設備管理 + C 模型共享 + camera ADR-020 規劃文件
- feature-device-mgmt-tdd.md + api-device-mgmt.md(B 設備管理 TDD)
- feature-model-sharing-tdd.md + api-model-sharing.md + PRD feature + 設計規格(C 模型共享三方規劃)
- adr-020-ffmpeg-camera-indev.md(camera 三平台 indev)
- PRD.md / TDD.md 索引增補

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-02 16:31:38 +08:00

11 KiB
Raw Blame History

ADR-020: vendor ffmpeg 加回 camera input deviceindev— 三平台 avfoundation / dshow / v4l2

狀態

Proposed。

待「三平台 ffmpeg rebuild / 驗證 + buildCaptureArgs 補 Linux 分支 + 三平台實機驗(需實體攝影機)」全數完成後,轉 Accepted。 使用者目前僅有 macOS 機器可測Windows / Linux 標為「待實機驗證」。

日期

2026-08-02

作者

Architect Agent

相關

  • 根因評估:local-tool/.autoflow/05-implementation/camera-ffmpeg-avfoundation-eval.md
  • 打破的前提v2 TDD §2decoder-only ffmpeg 決策)、vendor/ffmpeg/macos/BUILD.md
  • 相關實作:local-tool/server/internal/camera/ffmpeg_camera.goffmpeg_detect.go

1. 背景與範圍 (Context)

1.1 觸發問題

camera 即時推論在真機報錯camera 修 bug 讓「吞錯誤」不再發生後,底層錯誤終於浮現):

failed to open camera (index=0): camera did not start:
ffmpeg exited before producing a frame: ffmpeg stream ended: EOF
...
Unknown input format: 'avfoundation'
Error opening input file 0:none

Unknown input format: 'avfoundation' = 這顆 ffmpeg binary 沒有編進 avfoundation input deviceindev

1.2 根因(已 100% 確認,非推測)

camera 抓實體攝影機是 Go 端 os/exec 起 ffmpeg subprocess(非 Python指令形如 ffmpeg -f avfoundation -i "0:none" ... -f image2pipe -vcodec mjpeg -ffmpeg 把攝影機輸出成連續 MJPEG stream 到 stdoutGo 端掃 JPEG SOI/EOI marker 切 frame。

問題在 vendor 的 macOS ffmpeg 是「decoder-only」自 buildv2 TDD §2 決策、vendor/ffmpeg/macos/BUILD.mdconfigure flags 為縮體積 --disable-everything,白名單只 re-enable 了「解碼既有檔案」需要的元件:

--disable-everything
--enable-protocol=file,pipe
--enable-demuxer=mov,avi,mpegps,mpegts,matroska,image2
--enable-decoder=h264,hevc,...,mjpeg,...
--enable-parser=... --enable-filter=... --enable-muxer=image2pipe,image2,null
--enable-encoder=mjpeg
--disable-network

白名單裡完全沒有任何 --enable-indev=... --disable-everything 一併關掉所有 input device而白名單沒把 camera 需要的 indev 加回來 → avfoundation 認不得 → camera 開不了。

1.3 為什麼只有 camera 壞、影片 / 圖片 / 批次正常

功能 用到的 ffmpeg 能力 白名單有無 結果
影片 / 圖片 / 批次推論 demuxer + decoder解碼既有檔案 正常
camera 即時推論 indev(從實體裝置抓 raw frame 沒有

這是純「build 白名單漏了 indev」的問題不是程式碼邏輯錯

1.4 跨平台現況(讀 code 確認)

camera 三平台共用同一套 MJPEG pipe 抓取架構,但每平台用不同 indev

平台 抓取 indev ffmpeg 來源 ffmpeg indev 現況 camera code 現況
macOS avfoundation 自 build decoder-only 缺 avfoundation根因 完整
Windows dshow BtbN n7.1 完整 LGPL build ⚠️ 大概率已含 dshow待實機驗 完整dshow 路徑齊全)
Linux v4l2(應為) BtbN n7.1 完整 LGPL build ⚠️ 大概率已含 v4l2待實機驗 缺 Linux 分支

附帶 code bug獨立於 ffmpegbuildCaptureArgsffmpeg_camera.go)的 switch runtime.GOOS 只有 windowsdefaultdefault 分支用 avfoundation。Linux 會誤落 default → 對 Linux 攝影機用 avfoundation → 必錯。即使 macOS ffmpeg 修好Linux camera 仍會壞。


2. 決策 (Decision)

方案 Arebuild / 驗證三平台 ffmpeg 加回對應 indev並補 Linux camera code 分支

2.1 三平台 ffmpeg indev

平台 動作 具體
macOS rebuild 加 indev vendor-ffmpeg-macos-build 的 configure 加 --enable-indev=avfoundationrebuild重算 sha256更新 BUILD.mdcommit 新 binary
Windows 驗證(大概率零改動) 實機 ffmpeg -f dshow -list_devices true -i dummy 確認 BtbN build 已含 dshow若缺才需換含 dshow 的 build
Linux 驗證(大概率零改動) 實機 ffmpeg -devices 確認 BtbN build 已含 v4l2若缺才需換 build 或補 --enable-indev=v4l2

BtbN 官方 LGPL 完整 buildwin64-lgpl / linux64-lgpl)預設含 dshow / v4l2 indev故 Windows / Linux 預期零 ffmpeg 改動、只需實機驗證。macOS 是自 build 精簡版,是唯一確定要 rebuild 的。

2.2 補 Linux camera code 分支(獨立必補項)

buildCaptureArgsffmpeg_camera.go)與 ListFFmpegDevicesffmpeg_detect.go)補 Linux 分支,三平台 capture args 對照:

平台 列裝置 抓 framecapture args
macOS -f avfoundation -list_devices true -i "" -f avfoundation -i "<index>:none"
Windows -f dshow -list_devices true -i dummy -f dshow -i video="<name>"
Linux新增 -f v4l2 -list_devices true -i "" 或列舉 /dev/video* -f v4l2 -i /dev/video<N>

三平台後段皆接 -f image2pipe -vcodec mjpeg -q:v 5 -an -MJPEG pipe 架構不動。


3. 考慮過的替代方案 (Alternatives Considered)

方案 優點 缺點 排除原因
A. rebuild 加 indev採用 成本最低macOS 加一行 flag不推翻 decoder-onlyLGPL 乾淨;架構不動 需 rebuild macOS binary + 補 Linux code 分支
B. 換完整版 ffmpeg 省事、一次到位所有格式 體積爆增4070MB vs 現 5.7MB);推翻 v2 TDD §2 decoder-onlymacOS 無現成 LGPL static 完整 build正是當初自 build 的理由) 唯一好處「省事」在 A 只加一個 flag 前提下不成立
C. camera 改用平台原生 APIAVFoundation / Media Foundation / V4L2 ioctl + cgo 不依賴 ffmpeg subprocess 三平台各寫一套原生 + cgo複雜度爆炸 = 重寫 camera 子系統 解「build flag 少一行」不該砍掉可用的抓取架構
D. macOS 專用第二顆含 avfoundation 的 ffmpeg 主 binary 維持純解碼 多一顆 binary + 兩套 build 維護 A 加一個 flag 就能讓同一顆 binary 兼顧indev 增量 < 0.5MBD 無意義

4. 後果 (Consequences)

4.1 打破的既有前提

本 ADR 打破 v2 TDD §2 decoder-only「不含 indev」的前提。原決策的假設是「local-tool 只處理本地檔案解碼」,但 camera 即時推論需要從實體裝置抓 frameindev該假設對 camera 情境不成立。本 ADR 確立新契約:

camera indev 是 ffmpeg build 白名單的必要一部分。 未來升級 ffmpeg 版本 rebuild 時,三平台的 indevavfoundation / dshow / v4l2不得再遺漏。

4.2 體積影響

平台 增量 說明
macOS < 0.5 MB(現 5.7MB avfoundation indev 是薄封裝,呼叫系統 AVFoundation / CoreMedia frameworkotool -L 已顯示 binary 已 link 這些 framework不自帶 codec
Windows / Linux 0若零改動 BtbN build 已含 indev不重 build

4.3 LGPL 合規

  • avfoundation / dshow / v4l2 皆為 LGPL-safe indev不引入任何 GPL 元件
  • macOS 維持 --enable-version3LGPL v3rebuild 後仍須通過既有驗證(ffmpeg -version 不含 --enable-gpl / libx264 / libx265)。
  • Windows / Linux 沿用 BtbN LGPL build合規不變。

4.4 三平台 indev 對照(契約,供未來 rebuild 參照)

平台 indev ffmpeg 來源 build 需求
macOS avfoundation 自 build decoder-only configure 白名單須含 --enable-indev=avfoundation
Windows dshow BtbN 完整 LGPL build 沿用 upstream含 dshow
Linux v4l2 BtbN 完整 LGPL build 沿用 upstream含 v4l2

4.5 風險

  • 低。macOS 改的是 build flag + 補一個 OS 分支Linux code不動 MJPEG pipe 抓取架構。
  • 主要不確定性在「Windows / Linux BtbN build 是否已含 indev」透過實機 -list_devices / -devices 驗證即可消除;若不含則退化為「換 build」+1h

5. 合規性 Checklist

實作與轉 Accepted 前須全數完成:

  • macOS ffmpeg rebuildconfigure 加 --enable-indev=avfoundation、rebuild、重算 sha256、更新 vendor/ffmpeg/macos/BUILD.md(含新 configure line / sha256 / 大小、commit 新 binary
  • macOS LGPL 驗證rebuild 後 ffmpeg -version 不含 --enable-gpl / libx264 / libx265ffmpeg -devices 列出 avfoundation
  • Windows dshow 驗證:實機 ffmpeg -f dshow -list_devices true -i dummy 有列裝置(若缺 → 換含 dshow 的 build
  • Linux v4l2 驗證:實機 ffmpeg -devices 含 v4l2若缺 → 換 build 或補 flag
  • buildCaptureArgs 補 Linux 分支ffmpeg_camera.go + ffmpeg_detect.gocase "linux": -f v4l2(列裝置 + 抓 frame
  • 三平台實機驗各平台接實體攝影機camera 即時推論從「開不了」變「出 frame」
  • 體積 / LGPL 確認macOS binary 增量 < 0.5MB、LGPL v3 合規未破
  • v2 TDD ffmpeg 章節交叉引用增補不覆蓋註記「camera indev 為 build 白名單必要部分、三平台 indev 對照見 ADR-020」
  • 與 Tech Lead / 使用者確認
  • 成本影響已評估(體積增量微、無新增基礎設施成本)

6. WP 拆解(供 Orchestrator 排期)

WP 內容 派誰 需實機 前置 估時
WP-1 macOSconfigure 加 --enable-indev=avfoundation、rebuild、重算 sha256、更新 BUILD.md、commit binary devopsbuild/vendor macOS使用者有 11.5h(含 ~3 分 rebuild
WP-2 buildCaptureArgs / ListFFmpegDevices 補 Linux v4l2 分支(三平台 capture args 對照) backendGo camera code 可先寫、Linux 驗證階段測) 11.5h
WP-3 Windows實機 -f dshow -list_devices 驗證 dshow若缺才換 build devops Windows待實機 0.5h(順利)/ +1h換 build
WP-4 Linux實機驗證 v4l2 + camera 即時推論測試 devops + backend Linux待實機 WP-2 11.5h
WP-5 v2 TDD ffmpeg 章節交叉引用增補ADR-020 轉 Accepted architect 否(待 WP-1~4 完成) WP-1~4 0.5h

平行 / 接力WP-1macOS ffmpeg與 WP-2Linux code平行互不相依、不同檔。WP-3Windows 驗獨立可平行。WP-4Linux 驗)接力 WP-2。WP-5 收尾,等前四個。 關鍵路徑WP-2 → WP-4 → WP-5Linux 驗需先有 code 分支)。 使用者只有 macOSWP-1 可立即做並驗證WP-3 / WP-4 的實機驗證需 Windows / Linux 機器,標為「待實機」,先寫好 code / build 再擇機驗。


7. 等級與後續

  • 等級M 級(跨多檔 + 跨三平台 + 動 vendor build 策略,但非新 user story / 新架構)。
  • 後續ADR 定稿後由 Orchestrator 派 devopsffmpeg rebuild / 驗證)+ backendLinux camera code 分支落地。camera 不阻擋 B+C 主線,可獨立排期。