Solución de Problemas Automática: Por Qué nvv4l2h264enc Falla en Docker en Jetson Orin NX
La codificación por hardware H.264 mediante nvv4l2h264enc funciona en el sistema anfitrión Jetson Orin NX con JetPack 6.2.2, pero falla dentro de contenedores Docker. La canalización de GStreamer videotestsrc ! nvvidconv ! 'video/x-raw(memory:NVMM), framerate=5/1' ! nvv4l2h264enc ! fakesink en el anfitrión genera registros de inicialización NVENC: NvMMLiteOpen, NvVideo: NVENC. En un contenedor con --runtime=nvidia --privileged, se bloquea con: ENC_CTX(...) Error in initializing nvenc context y Could not get/set settings from/on resource. Device is in streaming mode.
Configuración: Jetson Orin NX, JetPack 6.2.2 (L4T R36.5.0, kernel 5.15.185-tegra), contenedor nvcr.io/nvidia/deepstream-l4t:7.1-samples-multiarch.
Causas Excluidas
Las pruebas mostraron entornos idénticos:
- Los dispositivos
/dev/nvmap,/dev/host1x-fence,/dev/dri/renderD128,/dev/nvgpu/igpu0/*,/dev/v4l2-nvencson accesibles con números mayor/menor coincidentes. - Las sumas de verificación de bibliotecas (
libnvtvmr.so,libnvrm_host1x.so,libtegrav4l2.so,libv4l2_nvvideocodec.so,libnvmmlite_video.so) son idénticas entre anfitrión y contenedor. - La prueba DRM para
DRM_IOCTL_TEGRA_CHANNEL_OPEN(clase NVENC 0x21) tiene éxito: contexto=1, versión=35, capacidades=1. --privilegeddesactiva seccomp/AppArmor/cgroups;NVIDIA_VISIBLE_DEVICES=allno tiene efecto.- sysfs (
/sys/bus/nvmem/devices/fuse/nvmem,/sys/devices/soc0/*) es legible; el chip se identifica como Tegra234 (soc_id=35).
Diagnóstico mediante strace
El rastreo con strace -f -e trace=ioctl reveló una diferencia:
| Métrica | Anfitrión | Contenedor |
|---------------------------|-----------|------------|
| Total ioctl | 2016 | 1644 |
| DRM_IOCTL | 236 | 36 |
| DRM_IOCTL_TEGRA_CHANNEL_OPEN | Sí | No |
En el anfitrión, el hilo del codificador abre un canal DRM para NVENC. En el contenedor—solo DRM_IOCTL_VERSION, sin proceder al canal. El rastreo completo strace -f mostró: el hilo del contenedor genera procesos hijos lsmod (salida 127) y grep nvgpu (tubería vacía, salida 1).
La biblioteca NVMM verifica el módulo nvgpu mediante el comando de shell lsmod | grep nvgpu. La ausencia de lsmod conduce al fallo de inicialización de NVENC.
Cadena:
libnvv4l2.so
└─ libv4l2_nvvideocodec.so
└─ libnvtvmr.so (Tegra Video Resource Manager)
└─ system("lsmod | grep nvgpu")
└─ sh: lsmod: not found
└─ grep lee tubería vacía → salida 1
└─ libnvtvmr: sin GPU → cancelación de NVENC
Solución
Instalar el paquete kmod resuelve el problema:
apt-get install -y kmod
En Dockerfile:
RUN apt-get update && apt-get install -y kmod && rm -rf /var/lib/apt/lists/*
Después de la instalación, la canalización se inicializa:
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 ...
Causas y Contexto
En JetPack 5.x (Xavier), los contenedores incluían kmod como dependencia. DeepStream L4T 7.1 para JetPack 6.x usa una base compacta sin él. En el anfitrión Ubuntu, kmod está instalado por defecto.
El error Error in initializing nvenc context no es informativo. La advertencia sh: lsmod: not found de gst-plugin-scanner se pierde entre los registros, con stderr redirigido a /dev/null.
Conclusiones Clave
--privilegedno compensa binarios faltantes: DRM/sysfs son accesibles, pero la biblioteca los ignora.- La dependencia de NVMM en llamadas de shell (
lsmod) complica la depuración de bibliotecas cerradas—requiere strace. - Instale
kmoden contenedores Jetson para tareas NVMM (codificación/decodificación H.264/AV1, VIC). - Ignorar
lsmod: not founden gst-plugin-scanner conduce a fallos en la canalización. - El problema es específico de JetPack 6.x: verificaciones de módulos mediante utilidades en lugar de
/proc/moduleso sysfs.
— Editorial Team
Aún no hay comentarios.