I’m not sure if this should be a new thread or not, I’m happy to start one if required.
As a result of the above, I bought a new webcam that is USB3 based and can therefore work at up to 60fps @1920x1080 which I initially thought would solve all my problems as I could just ask ffmpeg to run at 50fps.
root@starfive:~# v4l2-ctl --list-formats-ext -d /dev/video4
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'MJPG' (Motion-JPEG, compressed)
Size: Discrete 1920x1080
Interval: Discrete 0.017s (60.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.017s (60.000 fps)
Size: Discrete 640x480
Interval: Discrete 0.017s (60.000 fps)
[1]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 1920x1080
Interval: Discrete 0.017s (60.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.017s (60.000 fps)
Size: Discrete 640x480
Interval: Discrete 0.017s (60.000 fps)
I thought that something along the lines of ffmpeg -r 30 -f v4l2 -video_size 1920x1080 -y -i /dev/video4 -c:v hevc_omx ./test.mp4
would work, however after the following output and googling, it turns out that the 60fps listed above isn’t a maximum output figure, it’s the only supported frame rate.
ffmpeg version 4.4.1 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 11 (Debian 11.3.0-3)
configuration: --prefix=/code_mm_20221111/target/usr --arch=riscv64 --target-os=linux --enable-gpl --disable-stripping --disable-static --enable-shared --enable-avfilter --disable-version3 --enable-logging --disable-extra-warnings --enable-avdevice --enable-avcodec --enable-avformat --enable-network --disable-gray --enable-swscale-alpha --disable-small --enable-dct --enable-fft --enable-mdct --enable-rdft --enable-libv4l2 --enable-alsa --enable-outdevs --enable-pthreads --enable-zlib --enable-indevs --enable-runtime-cpudetect --enable-pic --cpu=rv64imafd --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-librsvg --enable-libdc1394 --enable-libdrm --enable-chromaprint --enable-libx264 --disable-frei0r --disable-gnutls --disable-ladspa --disable-libiec61883 --enable-omx --extra-ldflags=-L/code_mm_20221111/target/usr/lib --extra-cflags=-I/code_mm_20221111/target/usr/include/omx-il --extra-libs=-lOMX_Core
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
[video4linux2,v4l2 @ 0x2ab4594f10] The driver changed the time per frame from 1/30 to 1/60
At which point ffmpeg hangs (not even responding to the q command) with htop showing 1 core pinned at 100%.
Ctrl-C does quit ffmpeg and produces the following:
Input #0, video4linux2,v4l2, from '/dev/video4':
Duration: N/A, bitrate: 1990656 kb/s
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1920x1080, 1990656 kb/s, 60 fps, 60 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> hevc (hevc_omx))
Press [q] to stop, [?] for help
Finishing stream 0:0 without any data written to it.
[hevc_omx @ 0x2ab4598240] Using OMX.sf.video_encoder.hevc
Output #0, mp4, to './test.mp4':
Metadata:
encoder : Lavf58.76.100
Stream #0:0: Video: hevc (hev1 / 0x31766568), yuv420p, 1920x1080, q=2-31, 200 kb/s, 30 fps, 15360 tbn
Metadata:
encoder : Lavc58.134.100 hevc_omx
frame= 0 fps=0.0 q=0.0 Lsize= 0kB time=00:00:00.00 bitrate=N/A speed= 0x
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Exiting normally, received signal 2.
I’m assuming that ffmpeg is trying to use the CPU to encode at the full 60fps, so my question is, how do I force ffmpeg to drop frames before firing them at the hardware encoder?
According to this page ChangingFrameRate – FFmpeg -r takes effect after all filtering, but before encoding of the video stream has taken place. which would appear to do exactly what I want to do, however even running the command ffmpeg -f v4l2 -video_size 1920x1080 -y -i /dev/video4 -r 30 -c:v hevc_omx ./test.mp4
i.e. moving the -r
switch from the input to the output still produces the same result.