# DeepStream「Failed to create EGLImage」完整故障排除筆記(Docker + NoMachine + Jetson Orin) > 適用:**Jetson Orin(JetPack 6.x)** / **DeepStream 7.1** / **Docker 容器** / **NoMachine 遠端桌面**;要在遠端**看到畫面**執行 `deepstream-test1` 等 sample。 > > 若只做推論不看畫面,建議改走 **Headless(不開窗)**,更穩更省事(見第 6 章)。 --- ## TL;DR(五行結論) 1. `nvbufsurface: Failed to create EGLImage` 幾乎一定是**容器內沒有可用的 EGL + 顯示**(NoMachine 的虛擬 X display 預設沒有硬體 EGL)。 2. DeepStream sample 預設用 `nveglglessink` 開窗,**必須**能建立 EGLContext/EGLImage,否則就炸。 3. 解法 A:**Headless** → 把 sink 改成 `fakesink`/`filesink`,完全不走 EGL。 4. 解法 B(本文主線):要看畫面 → 用 **VirtualGL(EGL back end)**,讓 GPU 在伺服器端繪圖,畫面由 NoMachine 傳輸。 5. 關鍵點:`DISPLAY=:1`(NoMachine)、**xhost/Xauthority 授權**、容器掛載 `/dev/dri`、用 `vglrun -d egl`(或 `-d /dev/dri/card1`)。 --- ## 1. 問題現象與成因 ### 1.1 你可能看到的訊息 * `libEGL warning: DRI2 failed to authenticate` * `nvbufsurface: Failed to create EGLImage` * `Failed to set buffer pool to active` * `Unknown or legacy key 'nvbuf-memory-type'` * `/bin/bash: lsmod: command not found`, `/bin/bash: modprobe: command not found` ### 1.2 代表什麼? * **EGL/顯示路徑問題(主因)** * NoMachine 會開自己的虛擬 X display(常見 `:1`),預設**沒有**直通硬體 EGL/DRI;容器內若直接用 `nveglglessink`,會在建立 `EGLImage` 時失敗。 * `DRI2 failed to authenticate` 通常是 X 授權/DRI 權限或顯示環境不對。 * **非致命訊息(可忽略)** * `Unknown or legacy key 'nvbuf-memory-type'`:DeepStream 7.1 對舊 key 的提醒。 * `lsmod/modprobe not found`:容器是精簡版,沒有 kmod;不影響 sample 執行。 > 一句話:**顯示/EGL 沒打通 → `EGLImage` 建立失敗 → `nvinfer` buffer pool 啟不動 → pipeline 掛**。 --- ## 2. 解法地圖(挑一條) * **A. Headless(不開窗)**:把 sink 改 `fakesink` 或 `filesink`,完全不走 EGL,最省心(見第 6 章)。 * **B. 有畫面(本文主線)**:NoMachine + **VirtualGL(EGL back end)**。 * 主機(Jetson)裝 VirtualGL、設定 `vglusers` 與 `/dev/dri` 權限、放行 X 授權。 * 容器裝 VirtualGL user-space,用 `vglrun` 包住 DeepStream。 > 下文以 **方法 B** 詳述;方法 A 請直接跳第 6 章。 --- ## 3. 架構概念(方法 B:VirtualGL) ``` Client(你) ⇐ NoMachine 傳輸視覺畫面 ⇐ VirtualGL 將 GPU 繪圖結果截取並送出 ⇐ DeepStream 在 Docker 內用 EGL/GPU 繪圖 Jetson Orin /dev/dri/card1 提供 EGL/GPU 能力 ``` * 你連到 Jetson → NoMachine 啟一個 X Display `:1`(2D 桌面)。 * DeepStream 在容器內由 VirtualGL 代理 OpenGL/EGL 呼叫,用 **伺服器端 GPU** 繪圖,再把畫面回送到 `:1` 顯示。 --- ## 4. 實作步驟(一步步照做) > 以 **Jetson Orin + Ubuntu 22.04 + DeepStream 7.1 + NoMachine** 為例。 ### 4.1 主機(Jetson)前置檢查 ```bash nvidia-smi # Jetson 會顯示 Orin (nvgpu) echo $DISPLAY # 透過 NoMachine 通常是 :1 echo $XDG_SESSION_TYPE # 多半是 tty 或 x11 ls -l /tmp/.X11-unix # 常見 X1 / X1001 等 socket ``` ### 4.2 主機安裝與設定 VirtualGL(EGL only) > ARM64 上 apt 沒 `virtualgl`,用官方 .deb;設定時選「EGL back end only」。 ```bash # 安裝 VirtualGL (ARM64) wget -O ~/virtualgl_3.1_arm64.deb \ https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_arm64.deb sudo dpkg -i ~/virtualgl_3.1_arm64.deb || \ (sudo apt -f install -y && sudo dpkg -i ~/virtualgl_3.1_arm64.deb) # 啟用伺服器設定(互動精靈) sudo /opt/VirtualGL/bin/vglserver_config # 在選單中選:3) Configure server for use with VirtualGL (EGL back end only) # 問到下列選項時一律選 Enable/Yes: # - 建立 vglusers、限制 /dev/dri 給 vglusers # - 啟用安全設定 / Turbo # 把登入帳號加入 vglusers 並生效 sudo usermod -aG vglusers $USER newgrp vglusers # 放行 X11 給容器內的 root(常見 DeepStream 以 root 跑) DISPLAY=:1 xhost +local:root # 找出可用 EGL 裝置(Jetson 常見是 /dev/dri/card1) /opt/VirtualGL/bin/eglinfo -e ``` > **注意**:如果 `eglinfo -e` 顯示 `egl0 → /dev/dri/card1`,等下容器內建議用 `-d egl` 自動選或直接用 `-d /dev/dri/card1`。 ### 4.3 啟動 Docker 容器(要看畫面) ```bash docker run -it --rm --net=host --ipc=host \ --gpus all \ -e DISPLAY=:1 \ -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video,graphics \ -v /tmp/.X11-unix:/tmp/.X11-unix:rw \ --device=/dev/dri \ --group-add video \ --name ds71 \ nvcr.io/nvidia/deepstream:7.1-triton-multiarch ``` **參數說明** * `--gpus all`:新版 Docker 推薦寫法(相當於舊的 `--runtime=nvidia`)。 * `DISPLAY=:1`:明確把容器指到 NoMachine 的 X 顯示。 * `-v /tmp/.X11-unix`:把 X socket 映進容器。 * `--device=/dev/dri`:把 DRI 裝置帶進容器(EGL 需要)。 * `--ipc=host`:DeepStream/GStreamer 場景常用(共享 IPC)。 ### 4.4 容器內安裝 VirtualGL(user-space) ```bash apt-get update && apt-get install -y wget wget -O /tmp/virtualgl_3.1_arm64.deb \ https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_arm64.deb dpkg -i /tmp/virtualgl_3.1_arm64.deb || \ (apt-get -f install -y && dpkg -i /tmp/virtualgl_3.1_arm64.deb) ``` ### 4.5 容器內視覺小測試(彩色球) ```bash /opt/VirtualGL/bin/vglrun -d egl /opt/VirtualGL/bin/eglxspheres64 -f 240 -w 800x600 # 若不穩或裝置對不準,可強制用卡: /opt/VirtualGL/bin/vglrun -d /dev/dri/card1 /opt/VirtualGL/bin/eglxspheres64 -f 240 -w 800x600 ``` > 看得到小視窗 + 有 FPS ⇒ **EGL 路徑暢通**。 ### 4.6 容器內執行 DeepStream Sample(test1) ```bash cd /opt/nvidia/deepstream/deepstream-7.1/sources/apps/sample_apps/deepstream-test1 make # 若尚未編譯出 deepstream-test1-app # 自動選擇 EGL 裝置 /opt/VirtualGL/bin/vglrun -d egl ./deepstream-test1-app ./dstest1_config.yml # 或強制指定 /opt/VirtualGL/bin/vglrun -d /dev/dri/card1 ./deepstream-test1-app ./dstest1_config.yml ``` --- ## 5. 常見錯誤 → 對應手法 | 症狀/錯誤 | 可能原因 | 處置 | | ------------------------------------------- | --------------------------------- | -------------------------------------------------------------------- | | `nvbufsurface: Failed to create EGLImage` | 容器內沒有可用 EGL(NoMachine 虛擬 X 沒硬體加速) | 走 **VirtualGL(EGL)** 或改 **Headless** | | `DRI2 failed to authenticate` | 缺 X 授權 / DRI 權限 | 主機 `xhost +local:root` 或改掛 `$XAUTHORITY` 進容器 | | `invalid EGL device` | 指錯 DRI 裝置 | `eglinfo -e` 找正確 `/dev/dri/cardX`;用 `-d /dev/dri/card1` | | 有視窗但黑畫面 | NoMachine 端未啟用硬體加速/合成 | 到 NoMachine Server 設定啟用「Use acceleration for display processing」或類似項 | | `Unknown or legacy key 'nvbuf-memory-type'` | 參數舊名 | 通常可忽略;必要時對照 DS 7.1 新鍵名 | | `lsmod/modprobe not found` | 容器精簡 | 可忽略 | | `DISPLAY=:0` 仍不行 | 機器沒有實體 Xorg/螢幕 | 遠端情境請用 `:1` + VirtualGL;本地螢幕才用 `:0` | --- ## 6. \*\*Headless(不開窗)\*\*作法(最穩定) ### 6.1 用 `deepstream-app` 的 config ```ini [sink0] enable=1 type=5 # fakesink(不顯示) sync=0 ``` Docker 指令也更簡單(不用掛 X 與 DISPLAY): ```bash docker run -it --rm --net=host --ipc=host \ --gpus all \ -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video \ --device=/dev/dri \ nvcr.io/nvidia/deepstream:7.1-triton-multiarch \ deepstream-app -c /path/to/your_config.txt ``` ### 6.2 若要沿用 test1 程式 * 把 pipeline 的末端 `nveglglessink` 換成 `fakesink`/`filesink`(需改 sample 或其 YAML/INI)。 * 核心 idea:**不經過 EGL**,就不會有 `EGLImage` 問題。 --- ## 7. 安全與維運注意 * `xhost +local:root` 只允許本機 root 連入 X,簡單但安全性一般。要更嚴格可改用 **Xauthority cookie**: * Docker 加:`-v $XAUTHORITY:/root/.Xauthority:ro -e XAUTHORITY=/root/.Xauthority` * 確保 `DISPLAY` 與 `/tmp/.X11-unix` 相符。 * Jetson/驅動更新後,`/dev/dri` 權限可能被重置;出問題重跑: * `sudo /opt/VirtualGL/bin/vglserver_config -config +s +f -t -egl` * 版本相容性:DeepStream 7.1 / JetPack 6.x / 驅動(如 535/540+)需互相匹配,混裝常見各式 EGL 問題。 * 效能:`vglrun` 可調整壓縮品質(`-q`)、幀率限制(`-fps`)等;若追求低延遲/高畫質,可考慮 **TurboVNC + VirtualGL** 搭配。 --- ## 8. 快速指令卡(可直接貼到 README) ```bash # Host(Jetson) wget -O ~/virtualgl_3.1_arm64.deb https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_arm64.deb sudo dpkg -i ~/virtualgl_3.1_arm64.deb || (sudo apt -f install -y && sudo dpkg -i ~/virtualgl_3.1_arm64.deb) sudo /opt/VirtualGL/bin/vglserver_config # 選 3) EGL only,選項全 Yes sudo usermod -aG vglusers $USER && newgrp vglusers DISPLAY=:1 xhost +local:root /opt/VirtualGL/bin/eglinfo -e # 確認 card1/egl0 # Docker(要顯示畫面) docker run -it --rm --net=host --ipc=host --gpus all \ -e DISPLAY=:1 -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,video,graphics \ -v /tmp/.X11-unix:/tmp/.X11-unix:rw \ --device=/dev/dri --group-add video \ --name ds71 nvcr.io/nvidia/deepstream:7.1-triton-multiarch # Container 內(裝 VGL + 驗證 + 跑 DeepStream) apt-get update && apt-get install -y wget wget -O /tmp/virtualgl_3.1_arm64.deb https://downloads.sourceforge.net/project/virtualgl/3.1/virtualgl_3.1_arm64.deb dpkg -i /tmp/virtualgl_3.1_arm64.deb || (apt-get -f install -y && dpkg -i /tmp/virtualgl_3.1_arm64.deb) /opt/VirtualGL/bin/vglrun -d egl /opt/VirtualGL/bin/eglxspheres64 -f 240 -w 800x600 cd /opt/nvidia/deepstream/deepstream-7.1/sources/apps/sample_apps/deepstream-test1 make /opt/VirtualGL/bin/vglrun -d egl ./deepstream-test1-app ./dstest1_config.yml # 或:/opt/VirtualGL/bin/vglrun -d /dev/dri/card1 ./deepstream-test1-app ./dstest1_config.yml ``` --- ## 9. 快速決策樹(遇到同類問題時) 1. **需要視窗嗎?** * 不需要 → **Headless**(改 `fakesink`/`filesink`) → Done。 * 需要 → 2。 2. **遠端(NoMachine/VNC)或本機螢幕?** * 本機實體螢幕 → `DISPLAY=:0` + X 授權;通常可用。 * 遠端 NoMachine → **VirtualGL(EGL)** 路線(本文)。 3. **還是報 `EGLImage` 失敗?** * 檢查 `xhost +local:root`、容器是否有 `/dev/dri`、`vglrun -d egl eglxspheres64` 能跑。 * 不穩就強制 `-d /dev/dri/card1`。 * 仍不行 → 先走 **Headless** 完成工作,再回頭查 NoMachine/驅動/權限。 --- ### 備註 * 本筆記以 Jetson Orin/Ubuntu 22.04/DeepStream 7.1/NoMachine 為範例實測;x86\_64 環境僅需更換對應架構的 VirtualGL 套件。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up