fix(local-agent): camera pixel format + rawvideo decoder(實測出畫面)
avfoundation 修好後實測發現兩層問題(camera 三層根因的後兩層): - 改動1(args):darwin buildCaptureArgs 加 -pixel_format uyvy422(放 -i 前)。 攝影機只支援 uyvy422/yuyv422/nv12(非 yuv420p),不指定→協商失敗 I/O error。 - 改動2(ffmpeg):Makefile decoder 白名單加 rawvideo。攝影機吐 raw uyvy422 codec=rawvideo,轉 mjpeg 前要解,精簡 build 漏了→ no decoder found→EOF。 本機真攝影機端到端實測:/tmp/cam_ok.jpg = JPEG 640x480(rawvideo native→ mjpeg native 全鏈通、真的出畫面)。reviewer 通過(0C/0M)。只影響 camera (video/image/batch 解既有壓縮檔、不碰 rawvideo/avfoundation)。只改 macOS (Windows/Linux full build 內建 rawvideo;pixel_format 待實機 follow-up)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a6c94e21c5
commit
e27d8e3bd2
@ -181,7 +181,7 @@ vendor-ffmpeg-macos-build: ## macOS:從源碼 build LGPL v3 decoder-only ffmpe
|
|||||||
--enable-avfoundation \
|
--enable-avfoundation \
|
||||||
--enable-indev=avfoundation \
|
--enable-indev=avfoundation \
|
||||||
--enable-demuxer=mov,avi,mpegps,mpegts,matroska,image2 \
|
--enable-demuxer=mov,avi,mpegps,mpegts,matroska,image2 \
|
||||||
--enable-decoder=h264,hevc,mpeg1video,mpeg2video,mpeg4,mjpeg,prores,vp8,vp9,aac,mp2,mp3,pcm_s16le,pcm_s16be \
|
--enable-decoder=h264,hevc,mpeg1video,mpeg2video,mpeg4,mjpeg,prores,vp8,vp9,aac,mp2,mp3,pcm_s16le,pcm_s16be,rawvideo \
|
||||||
--enable-parser=h264,hevc,mpeg4video,mpegaudio,aac \
|
--enable-parser=h264,hevc,mpeg4video,mpegaudio,aac \
|
||||||
--enable-filter=scale,format,fps,null,anull \
|
--enable-filter=scale,format,fps,null,anull \
|
||||||
--enable-muxer=image2pipe,image2,null \
|
--enable-muxer=image2pipe,image2,null \
|
||||||
|
|||||||
@ -223,9 +223,18 @@ func buildCaptureArgsForOS(goos string, cameraIndex int, cameraName string, widt
|
|||||||
"-i", fmt.Sprintf("/dev/video%d", cameraIndex),
|
"-i", fmt.Sprintf("/dev/video%d", cameraIndex),
|
||||||
})
|
})
|
||||||
case "darwin":
|
case "darwin":
|
||||||
// AVFoundation on macOS: -f avfoundation -i "index:none"
|
// AVFoundation on macOS: -f avfoundation -pixel_format uyvy422 -i "index:none"
|
||||||
|
//
|
||||||
|
// 必須明確指定攝影機支援的 input pixel format。攝影機只支援
|
||||||
|
// uyvy422/yuyv422/nv12/0rgb/bgr0;不指定時 avfoundation 會嘗試 yuv420p
|
||||||
|
// → 協商失敗(Input/output error)。指定 uyvy422(攝影機原生格式)→ 攝影機成功打開。
|
||||||
|
//
|
||||||
|
// 位置關鍵:-pixel_format 是 input 選項,必須放在 -i 之前(跟 -framerate/
|
||||||
|
// -video_size 同段)。放到 -i 之後會被當成 output 轉碼目標、不解決 input 協商。
|
||||||
|
// 對照見根因文件 .autoflow/05-implementation/camera-pixel-format-rootcause.md。
|
||||||
return captureTail([]string{
|
return captureTail([]string{
|
||||||
"-f", "avfoundation",
|
"-f", "avfoundation",
|
||||||
|
"-pixel_format", "uyvy422",
|
||||||
"-framerate", fps,
|
"-framerate", fps,
|
||||||
"-video_size", videoSize,
|
"-video_size", videoSize,
|
||||||
"-i", fmt.Sprintf("%d:none", cameraIndex),
|
"-i", fmt.Sprintf("%d:none", cameraIndex),
|
||||||
|
|||||||
@ -24,12 +24,15 @@ func TestBuildCaptureArgsForOS(t *testing.T) {
|
|||||||
wantIndev string
|
wantIndev string
|
||||||
// wantInputArg 是 "-i" 後面的值
|
// wantInputArg 是 "-i" 後面的值
|
||||||
wantInputArg string
|
wantInputArg string
|
||||||
|
// wantPixelFormat 若非空,斷言 "-pixel_format <值>" 存在且位於 -i 之前(input 選項)。
|
||||||
|
wantPixelFormat string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "macOS uses avfoundation with index:none",
|
name: "macOS uses avfoundation with index:none and uyvy422 input pixel format",
|
||||||
goos: "darwin",
|
goos: "darwin",
|
||||||
wantIndev: "avfoundation",
|
wantIndev: "avfoundation",
|
||||||
wantInputArg: "0:none",
|
wantInputArg: "0:none",
|
||||||
|
wantPixelFormat: "uyvy422",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Windows uses dshow with video=name",
|
name: "Windows uses dshow with video=name",
|
||||||
@ -60,6 +63,20 @@ func TestBuildCaptureArgsForOS(t *testing.T) {
|
|||||||
t.Errorf("input = %q, want %q\nargs: %v", gotInput, tt.wantInputArg, args)
|
t.Errorf("input = %q, want %q\nargs: %v", gotInput, tt.wantInputArg, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// macOS avfoundation 必須帶 -pixel_format uyvy422,且它是 input 選項、
|
||||||
|
// 必須位於 -i 之前(放到 -i 之後會被當 output 轉碼目標、不解決 input 協商)。
|
||||||
|
if tt.wantPixelFormat != "" {
|
||||||
|
gotPixFmt := valueAfterFlag(args, "-pixel_format")
|
||||||
|
if gotPixFmt != tt.wantPixelFormat {
|
||||||
|
t.Errorf("pixel_format = %q, want %q\nargs: %v", gotPixFmt, tt.wantPixelFormat, args)
|
||||||
|
}
|
||||||
|
pixIdx := indexOfFlag(args, "-pixel_format")
|
||||||
|
iIdx := indexOfFlag(args, "-i")
|
||||||
|
if pixIdx < 0 || iIdx < 0 || pixIdx > iIdx {
|
||||||
|
t.Errorf("-pixel_format (idx %d) must appear before -i (idx %d)\nargs: %v", pixIdx, iIdx, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 三平台後段皆須為 image2pipe / mjpeg,MJPEG pipe 架構共用。
|
// 三平台後段皆須為 image2pipe / mjpeg,MJPEG pipe 架構共用。
|
||||||
if !containsSeq(args, "-f", "image2pipe") {
|
if !containsSeq(args, "-f", "image2pipe") {
|
||||||
t.Errorf("missing image2pipe output, args: %v", args)
|
t.Errorf("missing image2pipe output, args: %v", args)
|
||||||
@ -162,6 +179,16 @@ func valueAfterFlag(args []string, flag string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// indexOfFlag 回傳 args 中第一個等於 flag 的元素的索引;不存在回 -1。
|
||||||
|
func indexOfFlag(args []string, flag string) int {
|
||||||
|
for i, a := range args {
|
||||||
|
if a == flag {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
// containsSeq 判斷 args 是否包含連續的 a b 兩個元素。
|
// containsSeq 判斷 args 是否包含連續的 a b 兩個元素。
|
||||||
func containsSeq(args []string, a, b string) bool {
|
func containsSeq(args []string, a, b string) bool {
|
||||||
for i := 0; i < len(args)-1; i++ {
|
for i := 0; i < len(args)-1; i++ {
|
||||||
|
|||||||
73
local-agent/vendor/ffmpeg/macos/BUILD.md
vendored
73
local-agent/vendor/ffmpeg/macos/BUILD.md
vendored
@ -18,9 +18,20 @@ LGPL static build 來源,採「自 build decoder-only」策略,binary 直接
|
|||||||
| Toolchain | Apple clang 16.0.0 (clang-1600.0.26.6), Command Line Tools |
|
| Toolchain | Apple clang 16.0.0 (clang-1600.0.26.6), Command Line Tools |
|
||||||
| Assembler | nasm 3.01(Homebrew bottle,compiled 2025-10-11) |
|
| Assembler | nasm 3.01(Homebrew bottle,compiled 2025-10-11) |
|
||||||
| Homebrew | 5.1.6 |
|
| Homebrew | 5.1.6 |
|
||||||
| Build date | 2026-08-02(ADR-020 rebuild:加回 avfoundation indev) |
|
| Build date | 2026-08-03(camera raw capture fix:decoder 白名單加 `rawvideo`) |
|
||||||
| Build flags | 見下方 Configure flags 區塊(與 `Makefile` 的 `vendor-ffmpeg-macos-build` target 一致) |
|
| Build flags | 見下方 Configure flags 區塊(與 `Makefile` 的 `vendor-ffmpeg-macos-build` target 一致) |
|
||||||
|
|
||||||
|
> **camera raw capture fix(2026-08-03)**:decoder 白名單加 `rawvideo`。
|
||||||
|
> avfoundation 攝影機吐 raw `uyvy422`(codec = `rawvideo`),要轉成 MJPEG pipe 必須先「解碼 rawvideo」,
|
||||||
|
> 但先前 decoder-only 白名單沒有 `rawvideo` → `Decoding requested, but no decoder found for: rawvideo` → EOF。
|
||||||
|
> 這是 ADR-020(avfoundation indev)之後 camera 白名單的**第二個盲點**:ADR-020 讓攝影機「能被開啟」,
|
||||||
|
> 但沒處理「攝影機 raw 輸出的解碼」。
|
||||||
|
> **未來 rebuild 別漏**:camera raw capture 需 `rawvideo` decoder + `avfoundation` indev **兩者**齊全。
|
||||||
|
> `rawvideo` 是 libavcodec 內建 native decoder、LGPL-safe(僅 byte 重排 / format 標記、無演算法),不引入任何 GPL 元件;
|
||||||
|
> swscale 已 enable(`rawvideo(uyvy422) decode → swscale 轉 → mjpeg encode` 轉碼鏈齊)。
|
||||||
|
> 只加 macOS(Windows/Linux 用 BtbN full build 內建 rawvideo,不需改)。
|
||||||
|
> 詳見 `.autoflow/05-implementation/camera-pixel-format-rootcause.md`。
|
||||||
|
|
||||||
> **ADR-020 變更(2026-08-02)**:configure 加 `--enable-avfoundation` + `--enable-indev=avfoundation`,
|
> **ADR-020 變更(2026-08-02)**:configure 加 `--enable-avfoundation` + `--enable-indev=avfoundation`,
|
||||||
> 讓 camera 即時推論可用 avfoundation 抓實體攝影機。詳見
|
> 讓 camera 即時推論可用 avfoundation 抓實體攝影機。詳見
|
||||||
> `docs/autoflow/04-architecture/adr/adr-020-ffmpeg-camera-indev.md`。
|
> `docs/autoflow/04-architecture/adr/adr-020-ffmpeg-camera-indev.md`。
|
||||||
@ -30,11 +41,12 @@ LGPL static build 來源,採「自 build decoder-only」策略,binary 直接
|
|||||||
|
|
||||||
| 檔案 | sha256 |
|
| 檔案 | sha256 |
|
||||||
|------|--------|
|
|------|--------|
|
||||||
| `ffmpeg` | `1afa56dabb4ba4fb45323e37510602309ffd544d9e7ecb2d8267697a7cc16626` |
|
| `ffmpeg` | `cb42312fa89d2dc8443ae0dab810d42e18d3efefd9b62cf0a2e18762f7a8cdb7` |
|
||||||
| `ffprobe` | `501ec3fbe450c44f4c28cd7534940c6a16a42f8584e852b4f315de565aba414e` |
|
| `ffprobe` | `e7eb9e61a6bd77549cd6e2da9fec25beb67e71c3c3c4b1356ee395c591c0b3e9` |
|
||||||
| `COPYING.LGPLv3` | `da7eabb7bafdf7d3ae5e9f223aa5bdc1eece45ac569dc21b3b037520b4464768` |
|
| `COPYING.LGPLv3` | `da7eabb7bafdf7d3ae5e9f223aa5bdc1eece45ac569dc21b3b037520b4464768` |
|
||||||
|
|
||||||
> 舊值(2026-04-15 decoder-only、無 indev):ffmpeg `c3cb9f1d…992c` / ffprobe `bd388fb4…0c5e`。
|
> 舊值(2026-08-02 ADR-020、加 avfoundation indev、無 rawvideo):ffmpeg `1afa56da…6626` / ffprobe `501ec3fb…414e`。
|
||||||
|
> 更舊(2026-04-15 decoder-only、無 indev):ffmpeg `c3cb9f1d…992c` / ffprobe `bd388fb4…0c5e`。
|
||||||
|
|
||||||
計算指令:
|
計算指令:
|
||||||
```bash
|
```bash
|
||||||
@ -45,21 +57,24 @@ shasum -a 256 vendor/ffmpeg/macos/ffmpeg vendor/ffmpeg/macos/ffprobe
|
|||||||
|
|
||||||
| 檔案 | Bytes | 人類可讀 |
|
| 檔案 | Bytes | 人類可讀 |
|
||||||
|------|-------|---------|
|
|------|-------|---------|
|
||||||
| `ffmpeg` | 6,030,224 | 5.8 MB |
|
| `ffmpeg` | 6,034,432 | 5.8 MB |
|
||||||
| `ffprobe` | 5,892,384 | 5.6 MB |
|
| `ffprobe` | 5,896,624 | 5.6 MB |
|
||||||
|
|
||||||
實測比 TDD 原估 10–15 MB 小一半,因為 `--disable-everything` + 白名單僅啟用必要 decoder/demuxer/filter,無 GPL 元件。
|
實測比 TDD 原估 10–15 MB 小一半,因為 `--disable-everything` + 白名單僅啟用必要 decoder/demuxer/filter,無 GPL 元件。
|
||||||
|
|
||||||
|
> **rawvideo decoder 體積增量(2026-08-03)**:ffmpeg 6,030,224 → 6,034,432 bytes,僅
|
||||||
|
> **+4,208 bytes(< 0.005 MB)**。rawvideo decoder 只做 byte 重排 / format 標記、無演算法,體積增量極小。
|
||||||
|
|
||||||
> **avfoundation indev 體積增量(ADR-020)**:ffmpeg 6,007,520 → 6,030,224 bytes,僅
|
> **avfoundation indev 體積增量(ADR-020)**:ffmpeg 6,007,520 → 6,030,224 bytes,僅
|
||||||
> **+22,704 bytes(+0.02 MB)**,遠低於 ADR-020 估的 < 0.5 MB。因 avfoundation indev 是薄封裝,
|
> **+22,704 bytes(+0.02 MB)**,遠低於 ADR-020 估的 < 0.5 MB。因 avfoundation indev 是薄封裝,
|
||||||
> 呼叫系統 AVFoundation / CoreMedia / CoreVideo framework,不自帶任何 codec。
|
> 呼叫系統 AVFoundation / CoreMedia / CoreVideo framework,不自帶任何 codec。
|
||||||
|
|
||||||
### Build 實測耗時
|
### Build 實測耗時
|
||||||
|
|
||||||
- **3 分 57 秒**(2026-08-02 ADR-020 rebuild,`make vendor-ffmpeg-macos-build` 的 `time` 量測)
|
- **2 分 17 秒**(2026-08-03 加 rawvideo decoder rebuild,`make vendor-ffmpeg-macos-build` 的 `time` 量測)
|
||||||
- user: 870.32s,system: 92.27s,wall-clock: 236.62s
|
- user: 548.43s,system: 52.22s,wall-clock: 137.43s
|
||||||
- CPU 使用率:~406%(macOS x86_64,8 核 Intel)
|
- CPU 使用率:~437%(macOS x86_64,8 核 Intel)
|
||||||
- (2026-04-15 首次 decoder-only build 為 2 分 44 秒;本次略增因多編 avfoundation indev)
|
- (2026-08-02 ADR-020 rebuild 為 3 分 57 秒;2026-04-15 首次 decoder-only build 為 2 分 44 秒。本次較快為 build cache / 系統負載差異,rawvideo decoder 本身編譯成本極低)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
@ -73,7 +88,11 @@ build 不 link 以下 GPL-only 元件:
|
|||||||
- 無 `libfaac`(non-free)
|
- 無 `libfaac`(non-free)
|
||||||
|
|
||||||
僅使用 libavcodec 內建的 LGPL native decoder(h264 / hevc / mpeg1video / mpeg2video /
|
僅使用 libavcodec 內建的 LGPL native decoder(h264 / hevc / mpeg1video / mpeg2video /
|
||||||
mpeg4 / mjpeg / prores / vp8 / vp9 / aac / mp2 / mp3 / pcm_*)。
|
mpeg4 / mjpeg / prores / vp8 / vp9 / aac / mp2 / mp3 / pcm_* / rawvideo)。
|
||||||
|
|
||||||
|
**`rawvideo` decoder(2026-08-03)為 LGPL-safe**:libavcodec 內建 native decoder,僅做 byte 重排 /
|
||||||
|
pixel format 標記、無壓縮演算法,不引入任何 GPL / 第三方元件。加 `rawvideo` 後 `ffmpeg -version` 的
|
||||||
|
configuration line 仍**不含** `--enable-gpl` / `libx264` / `libx265`(已實測驗證),LGPL v3 合規未破。
|
||||||
|
|
||||||
**avfoundation indev(ADR-020)為 LGPL-safe,不引入任何 GPL 元件**:avfoundation input device
|
**avfoundation indev(ADR-020)為 LGPL-safe,不引入任何 GPL 元件**:avfoundation input device
|
||||||
只是薄封裝、透過 macOS 系統的 AVFoundation / CoreMedia / CoreVideo framework 抓實體攝影機 frame,
|
只是薄封裝、透過 macOS 系統的 AVFoundation / CoreMedia / CoreVideo framework 抓實體攝影機 frame,
|
||||||
@ -103,7 +122,7 @@ Foundation / CoreGraphics / libobjc),非第三方 dylib。
|
|||||||
--enable-avfoundation \
|
--enable-avfoundation \
|
||||||
--enable-indev=avfoundation \
|
--enable-indev=avfoundation \
|
||||||
--enable-demuxer=mov,avi,mpegps,mpegts,matroska,image2 \
|
--enable-demuxer=mov,avi,mpegps,mpegts,matroska,image2 \
|
||||||
--enable-decoder=h264,hevc,mpeg1video,mpeg2video,mpeg4,mjpeg,prores,vp8,vp9,aac,mp2,mp3,pcm_s16le,pcm_s16be \
|
--enable-decoder=h264,hevc,mpeg1video,mpeg2video,mpeg4,mjpeg,prores,vp8,vp9,aac,mp2,mp3,pcm_s16le,pcm_s16be,rawvideo \
|
||||||
--enable-parser=h264,hevc,mpeg4video,mpegaudio,aac \
|
--enable-parser=h264,hevc,mpeg4video,mpegaudio,aac \
|
||||||
--enable-filter=scale,format,fps,null,anull \
|
--enable-filter=scale,format,fps,null,anull \
|
||||||
--enable-muxer=image2pipe,image2,null \
|
--enable-muxer=image2pipe,image2,null \
|
||||||
@ -132,7 +151,7 @@ Foundation / CoreGraphics / libobjc),非第三方 dylib。
|
|||||||
| `--enable-avfoundation` | **(ADR-020)** camera 抓實體攝影機需 AVFoundation framework。因本 build 用 `--disable-autodetect`(連 AVFoundation 框架都不自動偵測),必須顯式 `--enable-avfoundation` 才能讓下面的 `avfoundation` indev 的依賴(`avfoundation corevideo coremedia pthreads`)被滿足。**少了這行、`--enable-indev=avfoundation` 會被 configure 靜默 disable(`WARNING: Disabled avfoundation_indev because not all dependencies are satisfied`)** |
|
| `--enable-avfoundation` | **(ADR-020)** camera 抓實體攝影機需 AVFoundation framework。因本 build 用 `--disable-autodetect`(連 AVFoundation 框架都不自動偵測),必須顯式 `--enable-avfoundation` 才能讓下面的 `avfoundation` indev 的依賴(`avfoundation corevideo coremedia pthreads`)被滿足。**少了這行、`--enable-indev=avfoundation` 會被 configure 靜默 disable(`WARNING: Disabled avfoundation_indev because not all dependencies are satisfied`)** |
|
||||||
| `--enable-indev=avfoundation` | **(ADR-020)** camera 即時推論的 macOS input device。ffmpeg `-f avfoundation -i "<index>:none"` 從實體攝影機抓 raw frame → MJPEG pipe。少了它會 `Unknown input format: 'avfoundation'`。LGPL-safe 薄封裝、體積增量 < 0.03MB |
|
| `--enable-indev=avfoundation` | **(ADR-020)** camera 即時推論的 macOS input device。ffmpeg `-f avfoundation -i "<index>:none"` 從實體攝影機抓 raw frame → MJPEG pipe。少了它會 `Unknown input format: 'avfoundation'`。LGPL-safe 薄封裝、體積增量 < 0.03MB |
|
||||||
| `--enable-demuxer=mov,avi,mpegps,mpegts,matroska,image2` | 對齊 PRD v2 支援的上傳格式 `.mp4 / .avi / .mov / .mpeg / .mpg` |
|
| `--enable-demuxer=mov,avi,mpegps,mpegts,matroska,image2` | 對齊 PRD v2 支援的上傳格式 `.mp4 / .avi / .mov / .mpeg / .mpg` |
|
||||||
| `--enable-decoder=h264,hevc,...` | 涵蓋常見 codec:H.264 / H.265 / MPEG1/2/4 / mjpeg / prores / vp8/9 / AAC / MP2/3 / PCM |
|
| `--enable-decoder=h264,hevc,...,rawvideo` | 涵蓋常見 codec:H.264 / H.265 / MPEG1/2/4 / mjpeg / prores / vp8/9 / AAC / MP2/3 / PCM。**`rawvideo`(2026-08-03)**:camera 經 avfoundation 抓出的 frame 是 raw `uyvy422`(codec = `rawvideo`),轉 MJPEG pipe 前必須先解碼;少了它 → `no decoder found for: rawvideo` → EOF。LGPL-safe native decoder |
|
||||||
| `--enable-parser=...` | 必要,否則某些 decoder 會在碼流切分階段 fail |
|
| `--enable-parser=...` | 必要,否則某些 decoder 會在碼流切分階段 fail |
|
||||||
| `--enable-muxer=image2pipe,image2,null` | 輸出單張 JPEG 或 NULL(測試用) |
|
| `--enable-muxer=image2pipe,image2,null` | 輸出單張 JPEG 或 NULL(測試用) |
|
||||||
| `--enable-encoder=mjpeg` | `-f image2pipe -vcodec mjpeg` 需要 mjpeg encoder(LGPL-safe) |
|
| `--enable-encoder=mjpeg` | `-f image2pipe -vcodec mjpeg` 需要 mjpeg encoder(LGPL-safe) |
|
||||||
@ -334,6 +353,34 @@ $ vendor/ffmpeg/macos/ffmpeg -hide_banner -f avfoundation -list_devices true -i
|
|||||||
- ✅ 不再出現 `Unknown input format: 'avfoundation'`(camera 開不了的根因已解)
|
- ✅ 不再出現 `Unknown input format: 'avfoundation'`(camera 開不了的根因已解)
|
||||||
- 註:`-list_devices true` 列完裝置後以非 0 退出(`Error opening input`)屬正常行為,非失敗。
|
- 註:`-list_devices true` 列完裝置後以非 0 退出(`Error opening input`)屬正常行為,非失敗。
|
||||||
|
|
||||||
|
### 7. rawvideo decoder(2026-08-03,本次 rebuild 新增)
|
||||||
|
|
||||||
|
```
|
||||||
|
$ vendor/ffmpeg/macos/ffmpeg -hide_banner -decoders 2>&1 | grep -i rawvideo
|
||||||
|
V..... rawvideo
|
||||||
|
```
|
||||||
|
|
||||||
|
- ✅ `rawvideo` decoder 已編入白名單。
|
||||||
|
|
||||||
|
### 8. Camera raw capture 端到端(2026-08-03,決定性驗證)
|
||||||
|
|
||||||
|
```
|
||||||
|
$ vendor/ffmpeg/macos/ffmpeg -f avfoundation -pixel_format uyvy422 \
|
||||||
|
-framerate 30 -video_size 640x480 -i "0:none" \
|
||||||
|
-f image2pipe -vcodec mjpeg -q:v 5 -an -frames:v 1 -y /tmp/cam_ok.jpg
|
||||||
|
Input #0, avfoundation, from '0:none':
|
||||||
|
Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 640x480, 30 tbr
|
||||||
|
Stream mapping:
|
||||||
|
Stream #0:0 -> #0:0 (rawvideo (native) -> mjpeg (native))
|
||||||
|
frame= 1 ... Lsize= 15KiB
|
||||||
|
|
||||||
|
$ file /tmp/cam_ok.jpg
|
||||||
|
/tmp/cam_ok.jpg: JPEG image data, baseline, precision 8, 640x480, components 3
|
||||||
|
```
|
||||||
|
|
||||||
|
- ✅ 攝影機成功打開(`-pixel_format uyvy422`)+ `rawvideo (native) -> mjpeg (native)` 轉碼鏈全通
|
||||||
|
- ✅ 真的從實體攝影機出一張 640x480 JPEG(15 KiB),兩層根因(args pixel_format + rawvideo decoder)都修好。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Commit 清單(只允許這四個檔進 git)
|
## Commit 清單(只允許這四個檔進 git)
|
||||||
|
|||||||
BIN
local-agent/vendor/ffmpeg/macos/ffmpeg
vendored
BIN
local-agent/vendor/ffmpeg/macos/ffmpeg
vendored
Binary file not shown.
BIN
local-agent/vendor/ffmpeg/macos/ffprobe
vendored
BIN
local-agent/vendor/ffmpeg/macos/ffprobe
vendored
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user