Hardware video transcoding with FFMEG

Ahhh that’s helped alot thank you. I originally installed ffmpeg using APT.

Having installed debian-packs → download ffmpeg_gstreamer_riscv64.deb the .so not found errors have now gone. Progress! I also installed the extra packages noted in the Readme.md file in debian-packs.

The next error that I’m chasing down is

[h264_omx @ 0x2ad9799d40] No component for role video_encoder.avc found
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
1 Like

I’m starting to wonder if I should install the full version and see if it works there, then chase down issues with minimal later.

1 Like

At time like this a spare SD card or two is useful.

I’ve installed that many random packages onto this one now that it’ll almost certainly end up getting nuked soon anyway, but yes in hindsight I probably should have bought a few to chop and change.

1 Like

So I’ve nuked the SD card and installed the full version of image-69. FFMPEG was already installed this time, I didn’t have to install it which was good. I ran the command again ffmpeg -i /dev/video4 -c:v h264_omx ./test.mp4 with the same error message as before.

[h264_omx @ 0x2ace8e0d40] No component for role video_encoder.avc found
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

This is promising for the minimal image at least once this error is solved.

Some more debugging info just in case it helps anyone.

root@starfive:~# lsmod
Module                  Size  Used by
jpu                    24576  0
vdec                   28672  0
venc                   28672  0
root@starfive:~# ls /dev
autofs		 i2c-6	       mtd2ro	  ptyb4  ptyd0	ptyec  ptyq8  ptys4  ptyu0  ptyvc  ptyx8  ptyz4      tty14  tty4   tty8   ttyb4  ttyd0	ttyec	   ttyq7  ttys3  ttytf	ttyvb  ttyx7  ttyz3    vcsa5
block		 i2c-7	       mtdblock0  ptyb5  ptyd1	ptyed  ptyq9  ptys5  ptyu1  ptyvd  ptyx9  ptyz5      tty15  tty40  tty9   ttyb5  ttyd1	ttyed	   ttyq8  ttys4  ttyu0	ttyvc  ttyx8  ttyz4    vcsa6
bus		 initctl       mtdblock1  ptyb6  ptyd2	ptyee  ptyqa  ptys6  ptyu2  ptyve  ptyxa  ptyz6      tty16  tty41  ttyS0  ttyb6  ttyd2	ttyee	   ttyq9  ttys5  ttyu1	ttyvd  ttyx9  ttyz5    vcsa7
char		 input	       mtdblock2  ptyb7  ptyd3	ptyef  ptyqb  ptys7  ptyu3  ptyvf  ptyxb  ptyz7      tty17  tty42  ttyS1  ttyb7  ttyd3	ttyef	   ttyqa  ttys6  ttyu2	ttyve  ttyxa  ttyz6    vcsu
console		 jpu	       null	  ptyb8  ptyd4	ptyp0  ptyqc  ptys8  ptyu4  ptyw0  ptyxc  ptyz8      tty18  tty43  ttyS2  ttyb8  ttyd4	ttyp0	   ttyqb  ttys7  ttyu3	ttyvf  ttyxb  ttyz7    vcsu1
cpu_dma_latency  kmsg	       port	  ptyb9  ptyd5	ptyp1  ptyqd  ptys9  ptyu5  ptyw1  ptyxd  ptyz9      tty19  tty44  ttyS3  ttyb9  ttyd5	ttyp1	   ttyqc  ttys8  ttyu4	ttyw0  ttyxc  ttyz8    vcsu2
cuse		 log	       ptmx	  ptyba  ptyd6	ptyp2  ptyqe  ptysa  ptyu6  ptyw2  ptyxe  ptyza      tty2   tty45  ttyS4  ttyba  ttyd6	ttyp2	   ttyqd  ttys9  ttyu5	ttyw1  ttyxd  ttyz9    vcsu3
disk		 loop-control  pts	  ptybb  ptyd7	ptyp3  ptyqf  ptysb  ptyu7  ptyw3  ptyxf  ptyzb      tty20  tty46  ttyS5  ttybb  ttyd7	ttyp3	   ttyqe  ttysa  ttyu6	ttyw2  ttyxe  ttyza    vcsu4
dri		 loop0	       ptya0	  ptybc  ptyd8	ptyp4  ptyr0  ptysc  ptyu8  ptyw4  ptyy0  ptyzc      tty21  tty47  ttya0  ttybc  ttyd8	ttyp4	   ttyqf  ttysb  ttyu7	ttyw3  ttyxf  ttyzb    vcsu5
dwdma		 loop1	       ptya1	  ptybd  ptyd9	ptyp5  ptyr1  ptysd  ptyu9  ptyw5  ptyy1  ptyzd      tty22  tty48  ttya1  ttybd  ttyd9	ttyp5	   ttyr0  ttysc  ttyu8	ttyw4  ttyy0  ttyzc    vcsu6
fd		 loop2	       ptya2	  ptybe  ptyda	ptyp6  ptyr2  ptyse  ptyua  ptyw6  ptyy2  ptyze      tty23  tty49  ttya2  ttybe  ttyda	ttyp6	   ttyr1  ttysd  ttyu9	ttyw5  ttyy1  ttyzd    vcsu7
full		 loop3	       ptya3	  ptybf  ptydb	ptyp7  ptyr3  ptysf  ptyub  ptyw7  ptyy3  ptyzf      tty24  tty5   ttya3  ttybf  ttydb	ttyp7	   ttyr2  ttyse  ttyua	ttyw6  ttyy2  ttyze    vdec
fuse		 loop4	       ptya4	  ptyc0  ptydc	ptyp8  ptyr4  ptyt0  ptyuc  ptyw8  ptyy4  random     tty25  tty50  ttya4  ttyc0  ttydc	ttyp8	   ttyr3  ttysf  ttyub	ttyw7  ttyy3  ttyzf    venc
gpiochip0	 loop5	       ptya5	  ptyc1  ptydd	ptyp9  ptyr5  ptyt1  ptyud  ptyw9  ptyy5  rtc	     tty26  tty51  ttya5  ttyc1  ttydd	ttyp9	   ttyr4  ttyt0  ttyuc	ttyw8  ttyy4  urandom  vga_arbiter
gpiochip1	 loop6	       ptya6	  ptyc2  ptyde	ptypa  ptyr6  ptyt2  ptyue  ptywa  ptyy6  rtc0	     tty27  tty52  ttya6  ttyc2  ttyde	ttypa	   ttyr5  ttyt1  ttyud	ttyw9  ttyy5  v4l      video0
hugepages	 loop7	       ptya7	  ptyc3  ptydf	ptypb  ptyr7  ptyt3  ptyuf  ptywb  ptyy7  shm	     tty28  tty53  ttya7  ttyc3  ttydf	ttypb	   ttyr6  ttyt2  ttyue	ttywa  ttyy6  vcs      video1
hvc0		 media0        ptya8	  ptyc4  ptye0	ptypc  ptyr8  ptyt4  ptyv0  ptywc  ptyy8  snd	     tty29  tty54  ttya8  ttyc4  ttye0	ttypc	   ttyr7  ttyt3  ttyuf	ttywb  ttyy7  vcs1     video2
hvc1		 mem	       ptya9	  ptyc5  ptye1	ptypd  ptyr9  ptyt5  ptyv1  ptywd  ptyy9  spidev1.0  tty3   tty55  ttya9  ttyc5  ttye1	ttypd	   ttyr8  ttyt4  ttyv0	ttywc  ttyy8  vcs2     video3
hvc2		 mmcblk1       ptyaa	  ptyc6  ptye2	ptype  ptyra  ptyt6  ptyv2  ptywe  ptyya  stderr     tty30  tty56  ttyaa  ttyc6  ttye2	ttype	   ttyr9  ttyt5  ttyv1	ttywd  ttyy9  vcs3     video4
hvc3		 mmcblk1p1     ptyab	  ptyc7  ptye3	ptypf  ptyrb  ptyt7  ptyv3  ptywf  ptyyb  stdin      tty31  tty57  ttyab  ttyc7  ttye3	ttypf	   ttyra  ttyt6  ttyv2	ttywe  ttyya  vcs4     video5
hvc4		 mmcblk1p2     ptyac	  ptyc8  ptye4	ptyq0  ptyrc  ptyt8  ptyv4  ptyx0  ptyyc  stdout     tty32  tty58  ttyac  ttyc8  ttye4	ttyprintk  ttyrb  ttyt7  ttyv3	ttywf  ttyyb  vcs5     video6
hvc5		 mmcblk1p3     ptyad	  ptyc9  ptye5	ptyq1  ptyrd  ptyt9  ptyv5  ptyx1  ptyyd  tty	     tty33  tty59  ttyad  ttyc9  ttye5	ttyq0	   ttyrc  ttyt8  ttyv4	ttyx0  ttyyc  vcs6     video7
hvc6		 mqueue        ptyae	  ptyca  ptye6	ptyq2  ptyre  ptyta  ptyv6  ptyx2  ptyye  tty0	     tty34  tty6   ttyae  ttyca  ttye6	ttyq1	   ttyrd  ttyt9  ttyv5	ttyx1  ttyyd  vcs7     watchdog
hvc7		 mtd0	       ptyaf	  ptycb  ptye7	ptyq3  ptyrf  ptytb  ptyv7  ptyx3  ptyyf  tty1	     tty35  tty60  ttyaf  ttycb  ttye7	ttyq2	   ttyre  ttyta  ttyv6	ttyx2  ttyye  vcsa     watchdog0
hwrng		 mtd0ro        ptyb0	  ptycc  ptye8	ptyq4  ptys0  ptytc  ptyv8  ptyx4  ptyz0  tty10      tty36  tty61  ttyb0  ttycc  ttye8	ttyq3	   ttyrf  ttytb  ttyv7	ttyx3  ttyyf  vcsa1    zero
i2c-0		 mtd1	       ptyb1	  ptycd  ptye9	ptyq5  ptys1  ptytd  ptyv9  ptyx5  ptyz1  tty11      tty37  tty62  ttyb1  ttycd  ttye9	ttyq4	   ttys0  ttytc  ttyv8	ttyx4  ttyz0  vcsa2
i2c-2		 mtd1ro        ptyb2	  ptyce  ptyea	ptyq6  ptys2  ptyte  ptyva  ptyx6  ptyz2  tty12      tty38  tty63  ttyb2  ttyce  ttyea	ttyq5	   ttys1  ttytd  ttyv9	ttyx5  ttyz1  vcsa3
i2c-5		 mtd2	       ptyb3	  ptycf  ptyeb	ptyq7  ptys3  ptytf  ptyvb  ptyx7  ptyz3  tty13      tty39  tty7   ttyb3  ttycf  ttyeb	ttyq6	   ttys2  ttyte  ttyva	ttyx6  ttyz2  vcsa4
root@starfive:~# uname -a
Linux starfive 5.15.0-starfive #1 SMP Mon Dec 19 07:56:37 EST 2022 riscv64 GNU/Linux

This looks to me like an “normal” ffmpeg error. Meaning: The programm functions like it should be (no crashes or librarys missing) but there is an error in the parameters the user sent or something is missing. It feels like you missing a parameter or something but i would say the programm itself works as it should.

Google turns up this:

1 Like

hi,magicsmoke,
Glad to receive your question,and I can understand what you’re confusion.
Now let me answer your question:
In your command , the encoder used is h264_omx.But VPU didn’t support h264 encoding,so you can change h264_omx to hevc_omx.

ffmpeg -i /dev/video4 -c:v hevc_omx test.mp4

And then you can get test.mp4,you can use ffplay to play it on the desktop

ffplay -i test.mp4

I hope this reply will help you

4 Likes

Thanks, makes total sense.
From the JH7110 datasheet:
Video Decode H264/H265 4k@60 fps
Video Encode H265 1080p@30 fps

1 Like

Ahhh that makes sense.
Thank you for the response it worked perfectly.

Encoding at 10fps with virtually no CPU loading at all. I’m not sure why its 10fps for the moment, it could be my camera, or a setting that needs changing etc. but it’s not a problem right now for my application.

When I get a second I’ll try again with the minimal distribution, though I’m not expecting any issues now I have it running.

Thank you to everyone for your help, so far I’m loving the VisionFive 2 board :slight_smile:

1 Like

I’d try:
$ 4l2-ctl --device=/dev/video4 --list-formats
$ v4l2-ctl --device=/dev/video4 --list-formats-ext
(you may need to do a “sudo apt install v4l-utils”, not sure)
And see what is supported.

Hi mzs, my appologies, time seems to have flown by this week.

It turns out that the webcam was indeed limited to 10fps @1280x720.

root@starfive:~# v4l2-ctl --list-formats-ext -d /dev/video4
ioctl: VIDIOC_ENUM_FMT
	Type: Video Capture

	[0]: 'MJPG' (Motion-JPEG, compressed)
		Size: Discrete 3264x2448
			Interval: Discrete 0.067s (15.000 fps)
		Size: Discrete 2592x1944
			Interval: Discrete 0.050s (20.000 fps)
		Size: Discrete 2048x1536
			Interval: Discrete 0.050s (20.000 fps)
		Size: Discrete 1920x1080
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1600x1200
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
	[1]: 'YUYV' (YUYV 4:2:2)
		Size: Discrete 640x480
			Interval: Discrete 0.033s (30.000 fps)
		Size: Discrete 800x600
			Interval: Discrete 0.050s (20.000 fps)
		Size: Discrete 1280x720
			Interval: Discrete 0.100s (10.000 fps)
1 Like

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.

I’ve just tried the command at 640x480 resolution and it appears to get close, though I’m not sure if that is more luck than judgement as the output talks about dropping frames.

root@starfive:~# ffmpeg -f v4l2 -video_size 640x480 -y -i /dev/video4 -r 30 -c:v hevc_omx  ./test.mp4
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
Input #0, video4linux2,v4l2, from '/dev/video4':
  Duration: N/A, start: 4205.032346, bitrate: 294912 kb/s
  Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x480, 294912 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
[hevc_omx @ 0x2ae85c4db0] 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(tv, progressive), 640x480, q=2-31, 200 kb/s, 30 fps, 15360 tbn
    Metadata:
      encoder         : Lavc58.134.100 hevc_omx
frame=  446 fps= 31 q=-0.0 Lsize=     361kB time=00:00:14.86 bitrate= 199.1kbits/s dup=7 drop=269 speed=1.02x    
video:359kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.734619%
Exiting normally, received signal 2.

With the above command, htop reports around 25-30% CPU usage on a single core.

1 Like

A quick though popped into my head, is the camera actually plugged into a USB 2.0 port and therefore it’s actually the USB subsystem that’s the problem? However a quick lsusb confirmed that the camera is connected at 5000Mbps.

root@starfive:~# lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
    |__ Port 1: Dev 3, If 0, Class=Video, Driver=uvcvideo, 5000M
    |__ Port 1: Dev 3, If 1, Class=Video, Driver=uvcvideo, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
1 Like

If you look at the message for every 1 frame out the the camera it was sending 2 to the encoder!

I’d try:
$ ffmpeg -t 60 -f v4l2 -input_format yuyv422 -video_size 1920x1080 -y -r 60 -i /dev/video4 -r 30 -c:v hevc_omx ./test.mp4
or to use 4 CPU threads, which may help if it is CPU bound:
$ ffmpeg -t 60 -f v4l2 -input_format yuyv422 -video_size 1920x1080 -y -i /dev/video4 -filter_threads 4 -filter:v fps=30 -c:v hevc_omx ./test.mp4

(“The default number of filter_threads is the number of available CPUs”, but that may not be detected correctly, always best to assume nothing). Are all 4 hart’s (HARware Threads) being used, or is just one CPU ? Maybe you need to add a “-cpucount 4” and remove the “-filter_threads 4”

I would test with a 60 second long output file (“-t 60”), it is long enough to see if you have a problem, and short enough that it will hopefully exit after 60 seconds.

Because “yuyv422” is raw uncompressed, but “mjpeg” is compressed, and I have no idea if it is defaulting to mjpeg or yuyv422. Let’s pick the simpler one to process since I have no idea how much CPU is involved in dropping frames from a compressed stream, or how much extra is involved in ffmpeg modifying each frame to be compatible with the encoder.

And explicitly tell it that the input rate is 60 fps and we want only 30 fps at the output.

EDIT: Looking at your output it does default to raw, but there is no harm in being specific.

EDIT(5): No idea how much CPU it would require to decompress mjpeg and convert it into raw at 30 fps but you could also try your old camera with:
$ ffmpeg -t 60 -cpucount 4 -f v4l2 -input_format mjpeg -video_size 1920x1080 -y -i /dev/video4 -c:v hevc_omx ./test.mp4

My gut feeling would be that it should take more resources, than simply dropping frames. But that jpeg decoding could, at least in theory, happen with hardware acceleration! And use less resources to get each where it needs to be processed further, so I do not know. It is worth a try.

I was ready to sing your name from the roof tops and buy you a beer until I realised that I was still testing it at 640x480 :man_facepalming:
Sadly, when I tried to run it at 1920x1080 neither adding -r 60 to the input nor changing -filter_threads to 4 made any difference. In both cases ffmpeg hung with just a single HART at 100% the others were 0, 0, < 10% even with -filter_threads 4. I did also try -cpucount - and recieved the following message:

Unrecognized option 'cpucount'.
Error splitting the argument list: Option not found

Interestingly, the final solution
$ ffmpeg -t 60 -cpucount 4 -f v4l2 -input_format mjpeg -video_size 1920x1080 -y -i /dev/video4 -c:v hevc_omx ./test.mp4 did actually produce some meaningful result. I had to remove -cpucount as it wasn’t recognised, but other than that ffmpeg ran for 60 seconds slowly ramping up to a maximum if 30fps and used ~ 25,51,0,0 % across the 4 HARTS

I believe that the JH7110 also has hardware JPEG decoding, so I might look at that next.

Interestingly, I tried -c:v mjpeg_omx on the input, ffmpeg printed the message:

[mjpeg_omx @ 0x2ae9efe1f0] OMX port 1 settings changed

Not only does it use more CPU, the single HART is now 100%, even if I subsequently try without specifying the omx decoder, it still uses 100% until I reboot.

Break it down, and split the tasks in three and see where the CPU is being chewed up.
Read 60 fps from the the camera for for 5 seconds (Because 5 seconds x 60 fps x 1920x1080 x 16 bits per pixel for yuyv422 would be ~1187 MiB. Writing data at about ~237 MiB/sec, maybe make a quick 2 GiB RAM disk just for the 5 second test!).

$ mkdir /tmp/ramdisk
$ sudo mount -t tmpfs -o size=2g tmpfs /tmp/ramdisk
$ sudo chmod 1777 /tmp/ramdisk

$ ffmpeg -t 5 -f v4l2 -input_format yuyv422 -video_size 1920x1080 -y -r 60 -i /dev/video4 /tmp/ramdisk/test_60.yuyv422
$ ffmpeg -s 1920x1080 -y -r 60 -i /tmp/ramdisk/test_60.yuyv422 -r 30 /tmp/ramdisk/test_30.yuyv422
$ ffmpeg -s 1920x1080 -y -r 30 -i /tmp/ramdisk/test_30.yuyv422 -c:v hevc_omx /tmp/ramdisk/test_30.mp4
$ sudo umount /tmp/ramdisk
$ sudo rmdir /tmp/ramdisk

The above ffmpeg commands probably have mistakes in them, but they should be close enough that you can work out where I messed up. The RAM disk stuff should be fine, just do not forget to move any files you want to keep to real storage before you power off or umount. umount gives back the RAM to the OS.

1 Like

Now that’s thinking outside of the box, I love it!
The ram disk was created fine,
$ ffmpeg -t 5 -f v4l2 -input_format yuyv422 -video_size 1920x1080 -y -r 60 -i /dev/video4 /tmp/ramdisk/test_60.yuyv422 didn’t run, it did the same as before, however when I hit Ctrl-C, it printed the following message:

[NULL @ 0x2ac263ab10] Unable to find a suitable output format for '/tmp/ramdisk/test_60.yuyv422'
/tmp/ramdisk/test_60.yuyv422: Invalid argument

So I added -f rawvideo to the output:
ffmpeg -t 5 -f v4l2 -input_format yuyv422 -video_size 1920x1080 -y -r 60 -i /dev/video4 -f rawvideo /tmp/ramdisk/test_60.yuyv422
which at least removed that error, however ultimately the output was the same, ffmpeg hangs, 1 HART 100%

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
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) -> rawvideo (native))
Press [q] to stop, [?] for help
Finishing stream 0:0 without any data written to it.
Output #0, rawvideo, to '/tmp/ramdisk/test_60.yuyv422':
  Metadata:
    encoder         : Lavf58.76.100
  Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1920x1080, q=2-31, 1990656 kb/s, 60 fps, 60 tbn
    Metadata:
      encoder         : Lavc58.134.100 rawvideo
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
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
Exiting normally, received signal 2.

Running the same command on an i5 laptop gives:
frame= 300 fps= 49 q=-0.0 Lsize= 1215000kB time=00:00:05.00 bitrate=1990656.0kbits/s speed=0.81x

This allowed me to at least generate the raw file which I then scp’d to the SBC and ran the other two commands.
ffmpeg -f rawvideo -pix_fmt yuyv422 -s 1920x1080 -y -r 60 -i /tmp/ramdisk/test_60.yuyv422 -r 30 -f rawvideo /tmp/ramdisk/test_30.yuyv422 converted at about 40 fps
ffmpeg -f rawvideo -s 1920x1080 -y -r 30 -i /tmp/ramdisk/test_30.yuyv422 -c:v hevc_omx /tmp/ramdisk/test_30.mp4 converted at about 35fps.
It quit with an “Invalid buffer size error”, but I’m assuming that is related to the random input file size or similar.

All of this is making me think that there is an issue else where, for example in the USB kernel driver or similar.
Whilst capturing the initial file on the laptop, I also ran usbtop which confirmed a transfer speed of 202299.42 kb/s so about what we were expecting.

1 Like