返回首页

nvv4l2h264enc 在 Docker Jetson Orin 中:故障排除

本文分析了 Jetson Orin NX 上 JetPack 6.2.2 的 Docker 容器中通过 nvv4l2h264enc 的硬件 H.264 编码失败。通过 strace 诊断揭示了 NVMM 库对 lsmod 实用程序的依赖,用于检查 nvgpu 模块。解决方案 — 安装 kmod 包。

Docker Jetson 中的 NVENC 失败:lsmod 救场
Advertisement 728x90

自动故障排除:为何nvv4l2h264enc在Jetson Orin NX的Docker中失败

在Jetson Orin NX主机上,通过nvv4l2h264enc进行H.264硬件编码在JetPack 6.2.2下工作正常,但在Docker容器内失败。主机上的GStreamer管道videotestsrc ! nvvidconv ! 'video/x-raw(memory:NVMM), framerate=5/1' ! nvv4l2h264enc ! fakesink输出NVENC初始化日志:NvMMLiteOpenNvVideo: NVENC。在带有--runtime=nvidia --privileged的容器中,它崩溃并显示:ENC_CTX(...) Error in initializing nvenc contextCould not get/set settings from/on resource. Device is in streaming mode

配置:Jetson Orin NX,JetPack 6.2.2(L4T R36.5.0,内核5.15.185-tegra),容器nvcr.io/nvidia/deepstream-l4t:7.1-samples-multiarch

排除的原因

测试显示环境相同:

Google AdInline article slot
  • 设备/dev/nvmap/dev/host1x-fence/dev/dri/renderD128/dev/nvgpu/igpu0/*/dev/v4l2-nvenc可访问,主次设备号匹配。
  • 库校验和(libnvtvmr.solibnvrm_host1x.solibtegrav4l2.solibv4l2_nvvideocodec.solibnvmmlite_video.so)在主机和容器间相同。
  • DRM测试DRM_IOCTL_TEGRA_CHANNEL_OPEN(NVENC类0x21)成功:context=1,version=35,capabilities=1。
  • --privileged禁用seccomp/AppArmor/cgroups;NVIDIA_VISIBLE_DEVICES=all无效。
  • sysfs(/sys/bus/nvmem/devices/fuse/nvmem/sys/devices/soc0/*)可读;芯片识别为Tegra234(soc_id=35)。

通过strace诊断

使用strace -f -e trace=ioctl追踪发现差异:

| 指标 | 主机 | 容器 |

|---------------------------|------|-----------|

Google AdInline article slot

| 总ioctl | 2016 | 1644 |

| DRM_IOCTL | 236 | 36 |

| DRM_IOCTL_TEGRA_CHANNEL_OPEN | 是 | 否 |

Google AdInline article slot

在主机上,编码器线程为NVENC打开一个DRM通道。在容器中——仅DRM_IOCTL_VERSION,未继续到通道。完整的strace -f追踪显示:容器线程生成子进程lsmod(退出127)和grep nvgpu(空管道,退出1)。

NVMM库通过shell命令lsmod | grep nvgpu检查nvgpu模块。缺少lsmod导致NVENC初始化失败。

链式过程:

libnvv4l2.so
  └─ libv4l2_nvvideocodec.so
       └─ libnvtvmr.so(Tegra视频资源管理器)
            └─ system("lsmod | grep nvgpu")
                 └─ sh: lsmod: not found
                      └─ grep读取空管道 → 退出1
                           └─ libnvtvmr: 无GPU → NVENC取消

修复方法

安装kmod包解决问题:

apt-get install -y kmod

在Dockerfile中:

RUN apt-get update && apt-get install -y kmod && rm -rf /var/lib/apt/lists/*

安装后,管道初始化:

Opening in BLOCKING MODE
NvMMLiteOpen : Block : BlockType = 4
===== NvVideo: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4
H264: Profile = 66 Level = 0
NVMEDIA: Need to set EMC bandwidth : 21000
NvVideo: bBlitMode is set to TRUE
Pipeline is PREROLLED ...

原因和背景

在JetPack 5.x(Xavier)中,容器将kmod作为依赖项拉取。DeepStream L4T 7.1 for JetPack 6.x使用紧凑基础镜像,未包含它。在主机Ubuntu上,kmod默认安装。

错误Error in initializing nvenc context信息不足。来自gst-plugin-scanner的警告sh: lsmod: not found在日志中丢失,stderr被重定向到/dev/null

关键要点

  • --privileged无法弥补缺失的二进制文件:DRM/sysfs可访问,但库忽略它们。
  • NVMM依赖shell调用(lsmod)使调试闭源库复杂化——需要strace。
  • 在Jetson容器中安装kmod以支持NVMM任务(H.264/AV1编码/解码,VIC)。
  • 忽略gst-plugin-scanner中的lsmod: not found会导致管道失败。
  • 此问题特定于JetPack 6.x:通过实用程序而非/proc/modules或sysfs检查模块。

— Editorial Team

Advertisement 728x90

继续阅读