-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Libcamera - proper 60fps support missing for rpi HQ camera #30
Comments
Looking at that - the issue is likely that the framerate support in gstreamer still isn't merged I'm afraid. There are patches available that need testing, review and integration. If you can rebuild libcamera on your platform, try adding these two patches and retest. https://patchwork.libcamera.org/project/libcamera/list/?series=3487 |
Thanks for the info, that is good to know. It doesn't explain why libcamera-hello selects an inapropriate sensor format |
It should at least select 1332 × 990 for 720p and 640x480, right ? https://www.raspberrypi.com/documentation/accessories/camera.html (And ideally, 1332 × 990 is binned instead of cropped. Not sure if someone bothered to bring those modes out of the broadcom blob into the linux OS sensor driver(s) though). |
I'll leave the libcamera-hello parts to RPi - I only know the gstreamer side I'm afraid. I have pinged the developers working on framerate support in gstreamer earlier today, so hopefully it would progress. I've wanted it in for a while too. |
(Which actually, if you could test, and report back - would help progress that) |
I did look into the libcamera rpi code.
Looks like the framerate is not even accounted for when selecting the "best" sensor format ? |
Do you know where the "format selection" code from gst libcamerasrc can be found ? Or is it just the same as here in libcamera. In this case, I don't think the patches would change anything on a rpi with the HQ camera. Since HQ 2028 × 1520p40 maxes out at 40fps (at least according to their doc here https://www.raspberrypi.com/documentation/accessories/camera.html ) |
Do not use Yes the mode selection algorithm is always going to have some conditions that are sub-optimal. I thought there had been discussions over including framerate and it had been rejected, but I'm not directly involved.
|
Thanks for these helpfull tipps, while I cannot get rid of the sudo yet both tools you posted really help. I can confirm that manually specifying the sensor resolution "works", aka I get 16.6ms frame delta(s) I understand that the mode selection is not easy, but silently ignoring the fps doesn't sound like a good idea to me ;) |
This probably is a gst-rpicamsrc issue, but nonetheless imporant for here: for some reason, with gst-rpicamsrc I am getting about 15fps (according to my gstreamer fpsdisplaysink running on another x86 pc) Tx pipeline: Rx pipeline: ~15fps (my decoder is well capable of 60fps and also gst doesn't report dropped frames) Quite far away from either 30fps, 50fps or the actually wanted 60fps ;) |
Add "interlace-mode=(string)progressive" to your capsfilter after libcamerasrc, and remove the v4l2convert. You don't want to give gstreamer the opportunity to do any software processing of the image. Otherwise, if you haven't applied the patches I mentioned above, you simply can't specifiy the framerate through the gstlibcamerasrc yet (you can put the filter on, but it won't take effect) - So I could guess that the stream is running at 15FPS perhaps because you're in a dark room, and the AGC is choosing to extend the exposure time to get a higher brightness image. |
Thanks for the info, I can confirm I was in a dark room and when I re-run the pipeline above in a lighter environment I get the (expected) 30fps (here I was just surprised by the 15 fps even though I expected at least 30fps, knowing that setting the fps won't work but libcamera defaults to 30fps). But your explanation makes total sense ;) Yeah we've been wanting to get rid of the v4l2convert for ages, but it just doesn't work. E.g. the following pipeline shows: |
Since we already build gstreamer ourselves to keep gst-rpicamsrc as an option for the users (switching between non-legacy and legacy camera stack) I've asked the dev responsible to apply the patches. I'l let you know if they work. |
Do you know if it is already possible to set the sensor mode (as shown by 6by9 with libcamera-vid) with gst libcamerasrc ? |
I'm not sure, I suspect that feature for explicitly setting a raw sensor mode is not yet implemented in the gstreamer gstlibcamerasrc, and will need explicit investigation. If you are willing to do this, let us know and we'll help, |
Note that currently the gstreamer element for libcamera might need explicit specification for the following properties:
Try adding the colorimetry in there too.
I believe I have tested the example at: https://github.com/kbingham/linux-cameras/wiki/GStreamer-use-cases-with-libcamera#rtp-streaming |
I can confirm that setting both the interlace mode and colorimetry allows you to get rid of v4l2convert. Thanks ! |
Quick question: Is it safe to install libcamera from https://git.libcamera.org/libcamera/libcamera.git and use on a rpi ? Or should we build and install from here. |
I see RPi have a couple of patches on top of libcamera at the moment. To maintain existing behaviour, I think you should probably continue to use this tree for the time being. |
To test the linked patches, I've performed the following steps:
Expected result: measure 30fps at receiver So I can't validate the patche(s) work, at least no yet (will double check) Fresh & latest raspbian, removed libcamera-dev and libcamera-apps. installed gstreamer to compile |
Full log (forgive me the sudo ;) ) |
I've also tried setting 50fps in a light environment - getting 30fps in this case |
Actually, I am not sure if I did everyhting correctly - I've uninstalled the (patched) libcamera build using |
Yeah, okay, my mistake - aparently you have to set Now I can report -
In my humble opinion, the current raspberry pi sensor mode selecton code is suboptimal. After all, hello_video /mmal always had the "feature" of selecting a sensor mode that can fulfill the given framerate request, if there is one. The current behaviour is much less intuitive than previous common mmal solutions,and doesn't even log a warning - an unexperienced user can set 720p60 (for example) , and libcamera will silently output 50fps instead. It is also not compatible with libcamerasrc (unless setting the sensor mode is added there). |
There is no direct API in libcamera to allow sensor mode selection. The system selects a sensor mode based on what output resolution was requested. Again, there is no way to factor framerate into this selection routine with the libcamera API. As an alternative, libcamera-apps have added the |
Since a resolution is always tied to a max (sometimes also min framerate), this sounds like a not ideal design to me. Either libcamera (as a library) should expose the functionality to query all sensor modes and then select a specific sensor mode, |
I think it would be possible to work around this issue specifically here (with the HQ camera) though. What about modifying the (rpi) sensor mode selection code to select 1332 × 990 instead of 2028x1080 when the user selects 720p ? Aka implement the following algorithm: |
I am wondering - should merge requests concerning code in libcamera/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp be done here (since it is rpi-specific) ? |
Some logs on this topic: Requesting 720p withut specifying the sensor mode, I get:
It is not documented in code what's better - a higher or lower score. I'd assume a lower score ? But how can 2028x1080 achieve a better score for a resolution of 720p than 1332x990 ? |
Merge requests for any code in the libcamera tree (e.g. the Raspberry Pi pipeline handler in this case) should be done though the libcamera dev mailing list. You can find the instructions here. |
Unfortunately, this will cause a regression. The 1332x990 mode does not actually use binning, rather it scales in the Bayer domain. This causes a significant loss of image quality when compared with direct binning. The reason for using scaling over binning is to achieve a faster framerate readout because of limitation in the sensor electronics. One approach to make things easier would be for libcamera-apps to essentially duplicate what the pipeline handler does for mode selection, but have framerate accounted for as well, assuming it was provided in the command line. This way, you only need to specify |
Thanks for letting me know. I don't think I'l invest the time to properly go through this hustle - In my opinion, the sensor mode selection code is flawed, but we now have a simple workaround. |
I don't think that's true. The data needs to be cropped anyways before going through the isp. And eliminating those wasted pixels as early as possible should be the standard approach. The only thing in this specific case where one perhaps could make a point is that the 2028x1080 provides 12bpp instead of the 10bpp in 1332x990. But from my testing, this 12bpp is just the default param of libcamera for some reason. Not sure if the ISP actually makes use of 12bpp in video and/or if that makes a difference in quality. Also,sad that here is no pixel binning in the OS imx477 driver for 720p. Quite sure mmal had it. But I know how stubborn those vendors can be in regards to IP. |
actually, I just had a look at the source code - 1332x990 is binned and cropped |
That comment is wrong, the fast fps mode definitely uses scaling together with cropping. |
Seeing that you have an acceptable solution in your fork, I'll close this issue down now. The change at raspberrypi/rpicam-apps#403 will also work by providing a similar mode selection directly in libcamera-apps. |
Our goal is to use use both 1280x720@60 and 640x480@90 fps modes on the rpi default HQ camera with libcamera.
720p60 and 640x480@90 both work flawlessly in the mmal land (we use gst-rpicamsrc for that, but that is just the same as using hello-video or similar).
However, I kinda get the feeling that these 2 modes are still missing in libcamera, or at least not implemented as well as in mmal.
Example 1)
Running libcamera-hello with at 720p60:
sudo libcamera-hello --width 1280 --height 720 --framerate 60 Made DRM preview window [0:17:28.096152832] [8914] INFO Camera camera_manager.cpp:293 libcamera v0.0.1+21-7c855784 [0:17:28.124998782] [8915] INFO RPI raspberrypi.cpp:1414 Registered camera /base/soc/i2c0mux/i2c@1/imx477@1a to Unicam device /dev/media4 and ISP device /dev/media0 [0:17:28.125688685] [8914] INFO Camera camera.cpp:1026 configuring streams: (0) 2028x1140-YUV420 [0:17:28.126073275] [8915] INFO RPI raspberrypi.cpp:800 Sensor: /base/soc/i2c0mux/i2c@1/imx477@1a - Selected sensor format: 2028x1080-SBGGR12_1X12 - Selected unicam format: 2028x1080-pBCC
it shows me that the actual sensor format selected is 2028x1080, and there is no way for the rpi ISP to handle that much data at 60fps. Or the data is cropped before going through the ISP, but that is a much worse solution than mmal had.
Same for 640x480@90:
sudo libcamera-hello --width 640 --height 480 --framerate 90 Made DRM preview window [0:20:57.802223521] [8949] INFO Camera camera_manager.cpp:293 libcamera v0.0.1+21-7c855784 [0:20:57.830808341] [8950] INFO RPI raspberrypi.cpp:1414 Registered camera /base/soc/i2c0mux/i2c@1/imx477@1a to Unicam device /dev/media4 and ISP device /dev/media0 [0:20:57.831491227] [8949] INFO Camera camera.cpp:1026 configuring streams: (0) 2026x1520-YUV420 [0:20:57.831845004] [8950] INFO RPI raspberrypi.cpp:800 Sensor: /base/soc/i2c0mux/i2c@1/imx477@1a - Selected sensor format: 2028x1520-SBGGR12_1X12 - Selected unicam format: 2028x1520-pBCC
I can also observe that when running a gstreamer pipeline with either 720p or 640x480, the output framerate(s) never exceed 30fps.
Example pipeline:
libcamerasrc camera-name=/base/soc/i2c0mux/i2c@1/imx477@1a ! capsfilter caps=video/x-raw,width=1280,height=720,format=NV12,framerate=60/1 ! v4l2convert ! v4l2h264enc extra-controls="controls,repeat_sequence_header=1,h264_profile=1,h264_level=11,video_bitrate=5000000,h264_i_frame_period=30,h264_minimum_qp_value=10" ! video/x-h264,level=(string)4 ! queue ! h264parse config-interval=-1 ! rtph264pay mtu=1024 ! udpsink host=127.0.0.1 port=5600
and the log also shows me
INFO RPI raspberrypi.cpp:800 Sensor: /base/soc/i2c0mux/i2c@1/imx477@1a - Selected sensor format: 2028x1080-SBGGR12_1X12 - Selected unicam format: 2028x1080-pBCC
Am I correct that 720p60 and 640x480@90 has never been properly implemented in libcamera on the rpi, and therefore is still only available from the mmal land ?
The text was updated successfully, but these errors were encountered: