Hardware acceleration on Pi in docker?

OK, I have it repeatable manual: command and arguments captured are in the script below. Forcing the number of buffers made no change (strace still sees 6 being requested even with the change) Any thoughts on other arguments to change?

#!/bin/sh
args="-hide_banner -nostats -loglevel warning -noautoscale -fflags discardcorrupt+genpts -f mpegts -copyts -probesize 8000000 -i - -num_capture_buffe
rs 3 -num_output_buffers 3 -enc_time_base -1 -max_muxing_queue_size 4096 -muxdelay 0 -map 0:v:0? -map 0:a? -ignore_unknown -sn -c:v h264_v4l2m2m -g:v
 60 -force_key_frames:v source -profile:v high -filter:v fastdeint=blend,scale_v4l2m2m=-2:min(ih\,1080) -b:v 10000k -minrate 9000k -maxrate 11000k -b
ufsize 20000k -c:a aac -ac 2 -b:a 256k -filter:a aresample=async=1 -f hls -hls_time 0.010000 -hls_list_size 360000 -hls_delete_threshold 1 -hls_flags
 temp_file+delete_segments -start_number 1"
curl http://192.168.1.223:5004/auto/v5.1 | sudo /mnt/Media/dvr/config/2021.10.25.1801/ffmpeg ${args} /home/Justin/teststream.m3u8

./test
output VIDIOC_REQBUFS failed: Invalid argument #
no v4l2 output context's buffers
[Parsed_scale_v4l2m2m_1 @ 0x14eb89f0] can't configure encoder
[Parsed_scale_v4l2m2m_1 @ 0x14eb89f0] Failed to configure output pad on Parsed_scale_v4l2m2m_1
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0
[aac @ 0x14b7f3f0] 2 frames left in the queue on closing
[aac @ 0x14d0ebf0] 2 frames left in the queue on closing

Changing from channel 5.1 (1080i) to 6.1 (720p) in the curl results in a success:

./test
[hls @ 0x18833f50] Non-monotonous DTS in output stream 0:0; previous: 5860186884, current: 0; changing to 5860186885. This may result in incorrect timestamps in the output file.
[hls @ 0x18833f50] Non-monotonous DTS in output stream 0:0; previous: 5860276974, current: 0; changing to 5860276975. This may result in incorrect timestamps in the output file.
[hls @ 0x18833f50] Non-monotonous DTS in output stream 0:0; previous: 5860367064, current: 0; changing to 5860367065. This may result in incorrect timestamps in the output file.

Ah, I think those arguments have to go to the scaler, so:

-filter:v fastdeint=blend,scale_v4l2m2m=w=-2:h=min(ih\,1080):num_capture_buffers=3

No luck. Still requesting six:

{type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, memory=V4L2_MEMORY_MMAP, count=6}

Maybe its num_output_buffers=3 then?

That was the right setting, but it still returns an error:

(3, VIDIOC_REQBUFS, {type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, memory=V4L2_MEMORY_MMAP, count=3}) = -1 EINVAL (Invalid argument)

One thing I note that is different from the dedicated Pi image, is that on my Raspian image, there is another video device /dev/video18 - and it is this driver that is being used. v4l2-ctl notes it as card="bcm2835-codec-image_fx". I just took a look at all the video devices on the dedicated pi image, and there are no devices of type bcm2835-codec-image_fx, nor does it have /dev/video18.

Yea the image_fx thing is new. If you update the official image to the latest kernel (click-and-hold the Check for Update button), that will appear there too. I think we're shipping 5.10.64 so its still behind where you're at, but includes all the new bcm codec changes recently.

Does setting both buffers to 3 help? Or to 2 or 1?

Unfortunately no, no change at all changing the buffer count. Trying to think what might be different in the video device behavior between your pi image and stock rasping.I checked the boot configs, and nothing is jumping out for kernel arguments. Stumped at this point.

Ok, more testing (spent way too much time on this) - the problem with ffmpeg dying transcoding 1080i video is reliably reproducible on a clean Raspberry Pi OS with only channels-dvr added. It appears after the OS is updated with the latest packages in the Raspberry Pi OS repo.

I installed a fresh build on Ubuntu 21.10 and the problem does not occur. 20.10 runs 5.13.0 kernel, so whatever the problem is I don't think it is the kernel specifically.

Also, with Ubuntu, there is no new /dev/video18 created as there was in Rasberry Pi OS - so perhaps the bug is with the code that introduced that feature which it looks like Ubuntu didn't take.

1 Like

What do you mean that driver is being used?

In strace it shows ioctl(3, ...) or ioctl(5, ...)

Can you find earlier where it does open(/dev/videoXX) = 3

Yes, in every case it was using /dev/video18; the fd changed at times, but it was /dev/video18 that the fd pointed to.

And in the cases where it works, it's using /dev/video12?

No, it was using 18 then too.

Okay cool I think I understand what the bug is so I'll try to figure out a fix.

It's getting confused and using the new incorrect video device like you guessed.

Can you stick a -loglevel debug near the front and grab the probing phase ("probing device /dev/video")

I can't readily test currently, my Pi is running Ubuntu at the moment and the dvr is in use by the family. To test I used the 28 May 2021 image from Index of /raspios_arm64/images and then updated to the latest packages in the repo; that's when the /dev/video18 device shows up. Running the test script commands in the previous post using a 1080i stream reliably triggers the error for me.

Try the latest prerelease

Will do, likely tomorrow evening.

Confirmed, update the 64-bit Raspberry Pi OS version and the transcoding is now working properly.

2 Likes

Thanks for confirming, and for your help tracking this down!

1 Like

I'm running the 64bit docker image on RPi4 with Ubuntu Server 21.10. I'm updated to the Channels 2022.03.18.1249.

After some trial and error, I was able to get hardware transcoding working by mapping in all of my /dev/video* devices. I don't know too much about how v4l and friends work.

Do I need all of these or just some subset? Are the numeric parts always the same for whatever functions they provide? I want to avoid doing mappings for something that might change out from under me due to some otherwise unrelated change.

Whatever the answer is, do you think the info could be added to the docker section of Channels — Channels DVR Server? (And while someone is updating that, maybe clarify that RPi should avoid the :latest and :tve tags for the docker image.)

devices:
  # need these for hardware transcoding
  - /dev/video10:/dev/video10
  - /dev/video11:/dev/video11
  - /dev/video12:/dev/video12
  - /dev/video13:/dev/video13
  - /dev/video14:/dev/video14
  - /dev/video15:/dev/video15
  - /dev/video16:/dev/video16