ioctl(VIDIOC_QUERYCAP) exit with errno 25

Hello!
I try use V4L2 API for work with encoder, for this I use /dev/nvhost-msenc, unfortunately ioctl VIDIOC_QUERYCAP fail with errno 25 (Inappropriate ioctl for device).
What can be reason?
Thank you.

Hi,
We have implemented NvVideoEncoder class. The suggestion is to use the implementation. If you would like to do lower-level programming, other users might have similar experience to help you out.

Hello, DaneLLL!
Yes, I know, I use it as example, unfortunately I can’t use it because it require X11.
May be I can download full documentation at encoder?
Thank you.

Hello, DaneLLL!
I try with sources at board, unfortunately result same

user@user-desktop:/usr/src/nvidia/tegra_multimedia_api$ pwd
/usr/src/nvidia/tegra_multimedia_api
user@user-desktop:/usr/src/nvidia/tegra_multimedia_api$ sudo make
Make in samples/10_camera_recording
make[1]: Entering directory '/usr/src/nvidia/tegra_multimedia_api/samples/10_camera_recording'
Compiling: main.cpp
make[2]: Entering directory '/usr/src/nvidia/tegra_multimedia_api/samples/common/classes'
Compiling: NvElementProfiler.cpp
Compiling: NvElement.cpp
Compiling: NvApplicationProfiler.cpp
Compiling: NvVideoDecoder.cpp
Compiling: NvJpegEncoder.cpp
Compiling: NvVideoConverter.cpp
Compiling: NvDrmRenderer.cpp
Compiling: NvLogging.cpp
Compiling: NvEglRenderer.cpp
Compiling: NvUtils.cpp
Compiling: NvBuffer.cpp
Compiling: NvJpegDecoder.cpp
Compiling: NvVideoEncoder.cpp
Compiling: NvV4l2ElementPlane.cpp
Compiling: NvV4l2Element.cpp
make[2]: Leaving directory '/usr/src/nvidia/tegra_multimedia_api/samples/common/classes'
Compiling: /usr/src/nvidia/tegra_multimedia_api/argus/samples/utils/Thread.cpp
Compiling: /usr/src/nvidia/tegra_multimedia_api/argus/samples/utils/NativeBuffer.cpp
Compiling: /usr/src/nvidia/tegra_multimedia_api/argus/samples/utils/nvmmapi/NvNativeBuffer.cpp
Linking: camera_recording
make[1]: Leaving directory '/usr/src/nvidia/tegra_multimedia_api/samples/10_camera_recording'
user@user-desktop:/usr/src/nvidia/tegra_multimedia_api$ samples/10_camera_recording/camera_recording 
Set governor to performance before enabling profiler
PRODUCER: Creating output stream
PRODUCER: Launching consumer thread
Failed to query video capabilities: Inappropriate ioctl for device
Opening in BLOCKING MODE 
NvMMLiteOpen : Block : BlockType = 4 
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4 
875967048
842091865
create video encoder return true
H264: Profile = 100, Level = 50 
PRODUCER: Starting repeat capture requests.
CONSUMER: Got EOS, exiting...
CONSUMER: Done.
PRODUCER: Done -- exiting.
************************************
Total Profiling Time = 0 sec
************************************
user@user-desktop:/usr/src/nvidia/tegra_multimedia_api$ samples/10_camera_recording/camera_recording -sv
Set governor to performance before enabling profiler
PRODUCER: Creating output stream
PRODUCER: Launching consumer thread
Failed to query video capabilities: Inappropriate ioctl for device
Opening in BLOCKING MODE 
NvMMLiteOpen : Block : BlockType = 4 
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4 
875967048
842091865
create video encoder return true
H264: Profile = 100, Level = 50 
PRODUCER: Starting repeat capture requests.
----------- Element = enc0 -----------
Total Profiling time = 4.85481
Average FPS = 21.0101
Total units processed = 103
Average latency(usec) = 49307
Minimum latency(usec) = 46752
Maximum latency(usec) = 51866
-------------------------------------
CONSUMER: Got EOS, exiting...
CONSUMER: Done.
PRODUCER: Done -- exiting.
************************************
Total Profiling Time = 0 sec
************************************

So this error present at NVidia code also, but it doesn’t critic.

I find the sample in the “video_encode” sample directory to be pretty easy to read.

I took the code, chopped off all the command-line/testing bits that I didn’t need, and was left with a simple encoding module that would open the device, configure it for the appropriate format, and then run a thread that reaps frames from the encoder device.

To be honest, I’ve only tested that code on the Xavier, but there’s no reason it wouldn’t work on the Nano, as long as you keep the data format and size within the limitations of its hardware.

Look for tegra_multimedia_api/samples/01_video_encode and read the code from there!
(If I remember correctly, it also referenced some shared utility files which I had to also do some surgery to to get them to the simple form I like.)

Hi,

Failed to query video capabilities: Inappropriate ioctl for device

This print is harmless and you may ignore it.

Hello, snarky, thank you!
But samples can’t replace documentation, I don’t understand why NVidia doesn’t provide full documenation and developers should reverse samples or modify it, why? Samples is a fine, but doesn’t enough for serious development.
Ok, if at this moment available only samples and forum I will use it.

I run samples/10_camera_recording under strace and I don’t understand how it work.
According to /usr/src/nvidia/tegra_multimedia_api/samples/common/classes/NvVideoEncoder.cpp it use /dev/nvhost-msenc

$ grep ENCODER_DEV -rnI /usr/src/nvidia/tegra_multimedia_api/samples/common/classes
/usr/src/nvidia/tegra_multimedia_api/samples/common/classes/NvVideoEncoder.cpp:36:#define ENCODER_DEV "/dev/nvhost-msenc"
/usr/src/nvidia/tegra_multimedia_api/samples/common/classes/NvVideoEncoder.cpp:75:    :NvV4l2Element(name, ENCODER_DEV, flags, valid_fields)

This device will be open at NvV4l2Element::NvV4l2Element(), for will be used v4l2_open(), if it was success will be checked V4L2_CAP_VIDEO_M2M_MPLANE capability.
Ok, I add some debug to NvV4l2Element::NvV4l2Element()

$ /usr/src/nvidia/tegra_multimedia_api/samples/10_camera_recording/camera_recording 
Set governor to performance before enabling profiler
PRODUCER: Creating output stream
PRODUCER: Launching consumer thread

Open device /dev/nvhost-msenc, flags 0
Failed to query video capabilities: Inappropriate ioctl for device
Opening in BLOCKING MODE 

fd = 15

VIDIOC_QUERYCAP success
NvMMLiteOpen : Block : BlockType = 4 
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4 
875967048
842091865
create video encoder return true
H264: Profile = 100, Level = 50 
PRODUCER: Starting repeat capture requests.
CONSUMER: Got EOS, exiting...
CONSUMER: Done.
PRODUCER: Done -- exiting.
************************************
Total Profiling Time = 0 sec
************************************

But strace output doesn’t contained /dev/nvhost-msenc device

$ grep '/dev/' /tmp/tegra_sample.log 
openat(AT_FDCWD, "/dev/nvhost-ctrl", O_RDWR|O_SYNC|O_CLOEXEC) = 3
openat(AT_FDCWD, "/dev/nvhost-vic", O_RDWR|O_CLOEXEC) = 4
openat(AT_FDCWD, "/dev/nvmap", O_RDWR|O_SYNC|O_CLOEXEC) = 5
openat(AT_FDCWD, "/dev/mods", O_RDWR)   = -1 ENOENT (No such file or directory)
faccessat(AT_FDCWD, "/dev/nvhost-ctrl-gpu", R_OK|W_OK) = 0
openat(AT_FDCWD, "/dev/nvgpu-pci", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/nvhost-ctrl-gpu", O_RDWR|O_CLOEXEC) = 6
faccessat(AT_FDCWD, "/dev/nvhost-dbg-gpu", R_OK|W_OK) = -1 EACCES (Permission denied)
openat(AT_FDCWD, "/dev/dri", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/dev/tegra_dc_ctrl", O_RDWR) = 9
openat(AT_FDCWD, "/dev/tegra_dc_0", O_RDWR) = 10
openat(AT_FDCWD, "/dev/fb0", O_RDWR)    = 11
openat(AT_FDCWD, "/dev/tegra_dc_1", O_RDWR) = 12
openat(AT_FDCWD, "/dev/fb1", O_RDWR)    = 13

This is very strange because /dev/nvhost-msenc is a character device

$ ls -l /dev/nvhost-*
crw-rw---- 1 root video 506,  1 Aug 16 22:23 /dev/nvhost-as-gpu
crw-rw---- 1 root video 242,  0 Aug 16 22:23 /dev/nvhost-ctrl
crw-rw---- 1 root video 506,  2 Aug 16 22:23 /dev/nvhost-ctrl-gpu
crw-rw---- 1 root video 242, 26 Aug 16 22:23 /dev/nvhost-ctrl-isp
crw-rw---- 1 root video 242, 30 Aug 16 22:23 /dev/nvhost-ctrl-isp.1
crw-rw---- 1 root video 242, 10 Aug 16 22:23 /dev/nvhost-ctrl-nvdec
crw-rw---- 1 root video 242, 34 Aug 16 22:23 /dev/nvhost-ctrl-vi
crw-rw---- 1 root video 506,  6 Aug 16 22:23 /dev/nvhost-ctxsw-gpu
crw-rw---- 1 root root  506,  3 Aug 16 22:23 /dev/nvhost-dbg-gpu
crw-rw---- 1 root video 506,  0 Aug 16 22:23 /dev/nvhost-gpu
crw-rw---- 1 root video 242, 25 Aug 16 22:23 /dev/nvhost-isp
crw-rw---- 1 root video 242, 29 Aug 16 22:23 /dev/nvhost-isp.1
crw-rw---- 1 root video 242, 17 Aug 16 22:23 /dev/nvhost-msenc
crw-rw---- 1 root video 242,  9 Aug 16 22:23 /dev/nvhost-nvdec
crw-rw---- 1 root video 242, 21 Aug 16 22:23 /dev/nvhost-nvjpg
crw-rw---- 1 root root  506,  4 Aug 16 22:23 /dev/nvhost-prof-gpu
crw-rw---- 1 root video 506,  7 Aug 16 22:23 /dev/nvhost-sched-gpu
crw-rw---- 1 root video 242,  1 Aug 16 22:23 /dev/nvhost-tsec
crw-rw---- 1 root video 242,  5 Aug 16 22:23 /dev/nvhost-tsecb
crw-rw---- 1 root video 506,  5 Aug 16 22:23 /dev/nvhost-tsg-gpu
crw-rw---- 1 root video 242, 33 Aug 16 22:23 /dev/nvhost-vi
crw-rw---- 1 root video 242, 13 Aug 16 22:23 /dev/nvhost-vic
$ ldd /usr/src/nvidia/tegra_multimedia_api/samples/10_camera_recording    /camera_recording                                                                            
        linux-vdso.so.1 (0x0000007fa34cc000)
        libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000007fa33e2000)
        libv4l2.so => /usr/lib/aarch64-linux-gnu/libv4l2.so (0x0000007fa33a8000)
        libEGL.so.1 => /usr/lib/aarch64-linux-gnu/libEGL.so.1 (0x0000007fa3387000)
        libGLESv2.so.2 => /usr/lib/aarch64-linux-gnu/libGLESv2.so.2 (0x0000007fa3351000)
        libX11.so.6 => /usr/lib/aarch64-linux-gnu/libX11.so.6 (0x0000007fa3227000)
        libnvbuf_utils.so.1.0.0 => /usr/lib/aarch64-linux-gnu/tegra/libnvbuf_utils.so.1.0.0 (0x0000007fa320f000)                                                                      
        libnvjpeg.so => /usr/lib/aarch64-linux-gnu/tegra/libnvjpeg.so (0x0000007fa31b7000)                                                                                            
        libdrm.so.2 => /usr/lib/aarch64-linux-gnu/libdrm.so.2 (0x0000007fa3186000)
        libnvargus_socketclient.so => /usr/lib/aarch64-linux-gnu/tegra/libnvargus_socketclient.so (0x0000007fa302f000)                                                                
        libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000007fa2e9c000)
        libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000007fa2e78000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007fa2d1f000)
        /lib/ld-linux-aarch64.so.1 (0x0000007fa34a1000)
        libv4lconvert.so => /usr/lib/aarch64-linux-gnu/libv4lconvert.so (0x0000007fa2c9a000)                                                                                          
        libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000007fa2c85000)
        libGLdispatch.so.0 => /usr/lib/aarch64-linux-gnu/libGLdispatch.so.0 (0x0000007fa2b59000)
        libxcb.so.1 => /usr/lib/aarch64-linux-gnu/libxcb.so.1 (0x0000007fa2b29000)
        libnvrm.so => /usr/lib/aarch64-linux-gnu/tegra/libnvrm.so (0x0000007fa2ae7000)
        libnvrm_graphics.so => /usr/lib/aarch64-linux-gnu/tegra/libnvrm_graphics.so (0x0000007fa2ac8000)
        libnvddk_vic.so => /usr/lib/aarch64-linux-gnu/tegra/libnvddk_vic.so (0x0000007fa2aaa000)
        libnvddk_2d_v2.so => /usr/lib/aarch64-linux-gnu/tegra/libnvddk_2d_v2.so (0x0000007fa2a86000)
        libnvll.so => /usr/lib/aarch64-linux-gnu/tegra/libnvll.so (0x0000007fa2a6a000)
        libnvcamerautils.so => /usr/lib/aarch64-linux-gnu/tegra/libnvcamerautils.so (0x0000007fa2a2f000)
        libnvcam_imageencoder.so => /usr/lib/aarch64-linux-gnu/tegra/libnvcam_imageencoder.so (0x0000007fa2a0f000)
        libnvos.so => /usr/lib/aarch64-linux-gnu/tegra/libnvos.so (0x0000007fa29f1000)
        libnvmm_utils.so => /usr/lib/aarch64-linux-gnu/tegra/libnvmm_utils.so (0x0000007fa29d0000)
        libnvcameratools.so => /usr/lib/aarch64-linux-gnu/tegra/libnvcameratools.so (0x0000007fa2949000)
        libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000007fa288f000)
        librt.so.1 => /lib/aarch64-linux-gnu/librt.so.1 (0x0000007fa2878000)
        libXau.so.6 => /usr/lib/aarch64-linux-gnu/libXau.so.6 (0x0000007fa2865000)
        libXdmcp.so.6 => /usr/lib/aarch64-linux-gnu/libXdmcp.so.6 (0x0000007fa2850000)
        libnvdc.so => /usr/lib/aarch64-linux-gnu/tegra/libnvdc.so (0x0000007fa2831000)
        libnvcamlog.so => /usr/lib/aarch64-linux-gnu/tegra/libnvcamlog.so (0x0000007fa281a000)
        libnvtvmr.so => /usr/lib/aarch64-linux-gnu/tegra/libnvtvmr.so (0x0000007fa278b000)
        libnvscf.so => /usr/lib/aarch64-linux-gnu/tegra/libnvscf.so (0x0000007fa213f000)
        libbsd.so.0 => /lib/aarch64-linux-gnu/libbsd.so.0 (0x0000007fa211b000)
        libnvimp.so => /usr/lib/aarch64-linux-gnu/tegra/libnvimp.so (0x0000007fa2106000)
        libnvfnetstoredefog.so => /usr/lib/aarch64-linux-gnu/tegra/libnvfnetstoredefog.so (0x0000007fa20c2000)
        libnvfnet.so => /usr/lib/aarch64-linux-gnu/tegra/libnvfnet.so (0x0000007fa2029000)
        libnvfnetstorehdfx.so => /usr/lib/aarch64-linux-gnu/tegra/libnvfnetstorehdfx.so (0x0000007fa1ffb000)
        libnvodm_imager.so => /usr/lib/aarch64-linux-gnu/tegra/libnvodm_imager.so (0x0000007fa1af8000)
        libnvphs.so => /usr/lib/aarch64-linux-gnu/tegra/libnvphs.so (0x0000007fa1ad4000)
        libcuda.so.1 => /usr/lib/aarch64-linux-gnu/tegra/libcuda.so.1 (0x0000007fa0bb0000)
        libexpat.so.1 => /lib/aarch64-linux-gnu/libexpat.so.1 (0x0000007fa0b71000)
        libnvcamv4l2.so => /usr/lib/aarch64-linux-gnu/tegra/libnvcamv4l2.so (0x0000007fa0b4c000)
        libnvrm_gpu.so => /usr/lib/aarch64-linux-gnu/tegra/libnvrm_gpu.so (0x0000007fa0b09000)
        libnvidia-fatbinaryloader.so.32.1.0 => /usr/lib/aarch64-linux-gnu/tegra/libnvidia-fatbinaryloader.so.32.1.0 (0x0000007fa0aa9000)

tegra_sample.log (122 KB)

Hi,
The control of /dev/nvhost-msenc is private. Please refer to NvVideoEncoder. Lower level control is not open.

Are you aware of the documentation that does exist?
For example:
https://docs.nvidia.com/jetson/l4t-multimedia/l4t_mm_01_video_encode_group.html
https://docs.nvidia.com/jetson/l4t-multimedia/l4t_mm_camera_recording.html

Hello, snarky!
This is documentation at public wrapper, it present at samples/common/classes/, this documentation describe wrapper, but doesn’t encoder.
As you can see this is confirmed, so we are don’t control capture and encoder, we are don’t know how it work.
So at this moment we are have one way - modify samples, we are can’t use it as example :(