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
Handling of 16-bit bayer Endianness #99
Comments
Same issue noted here, but for the CM4/Pi4: |
That was a misinterpretation of the captured data. The produced data should match https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/pixfmt-srggb16.html and has to be processed accordingly. For this issue am I reading that when using The FE is always producing compressed or 16bpc data, so it seems unlikely that the back end is misinterpreting the data. |
#5806 includes a patch to add the csi_dt value for 16bit formats, but I need others to confirm whether that is needed or not. I have a suspicion that all CSI2 data (including metadata) will be going through the CFE without that. |
Not sure if the csi_dt change will make a difference, but does no harm to try it out. I'm pretty sure the ISP Backend correctly reads in 16-bit Bayer as that's one of the normal modes of operation. Can you try asking for 16-bit compressed to 8-bit Bayer and see if that makes any difference? You can do this by using Also, have you managed to verify this 3856x2180 16-bit mode is correctly streaming from the sensor? Possibly the easiest way to verify this is to use a CM4 and drive Unicam directly via |
Any update on this? |
Closing this now due to inactivity.... Feel free to reopen if this is still an issue. |
Ok, now having time to revisit this; I'm able to better present the issue at hand; and hopefully there is a mechanism somewhere in this software/hardware stack to handle it: the IMX585 has a clearHDR mode that combines pixel readings at 2 different gains within the same exposure into a single 16-bit frame. Now that I am able to capture uncompressed 16-bit bayer frames, I have been able to confirm the issue has to do with endianness as originally suspected. Shown from the datasheet: I can further confirm with a python script that will display the bayer raw as a 16-bit mono image, when I perform a byte swap the image is rendered correctly ( albeit possessing some artifacts / noise / clipping ) Now outside of my python script, I can perform the same operation within a libcamera based app by doing:
How to configure libcamera to interpret the big-endian data appropriately? can it be done via the Pi5 ISP via libpisp? Can it be done in software before it gets further down the ISP pipeline ( RGB pipe ) ? As it stands the ISP / preview is rendered unusable: EDIT: if it's of any use, I have attached the SRGGB16 bayer raw frame. ( 7744 byte stride x 2180 rows ) |
Unfortunately, there is no HW mechanism to endian swap directly in the ISP pipeline - we only deal with little endian for 16-bits. Are you able to do an endian swap in the sensor itself? Or perhaps get the sensor to write out 14-bit RAW (losing 2-bits of precision) which ought to be handled correctly? |
This seems to be a hardware issue, and is not something that can easily be fixed in libcamera.
|
If not in hardware, are there any avenues in software for accomplishing this? I noticed there are already a number of format conversions happening with CPU and not on ISP when I investigated a couple months back: #93
Understandably those happen after the fact once the image is out of the ISP, It would need to perform a byte swap on the raw image while it is in memory before it is processed by the ISP |
This might be possible, we will explore the options. However, you end up in a situation where you cannot rely on the statistics for the 3A algorithms. This may not be a problem if you want to control everything (exposure/gain/white balance) manually. |
Yes, My application is full manual control, losing 3A would not be a major concern. Thank you for looking into this, I eagerly await a solution and hope to test soon. |
Hi, following up to see if you've had the chance to look into this further. thanks! |
Not yet unfortunately. I will try to get to it next week if I can. |
@schoolpost I've attempted to add the SW endian swap code here: 9c80dba (from the next tree). Unfortunately, I can't really try it out properly since I don't have a 16-bit sensor. Would you be able to give it a try and let me know if it works. Note that you must run in fully manual mode as statistics will not be functional in this mode. |
Thanks @naushir, I have been able to test and can confirm that it does in fact seem to bring me closer to a working preview. I'm only now realizing how many other ISP functions depend on the 3A for their function, because even though I set the:
colors and such are way off, maybe there are some things I'll need to address via a tuning.json file? |
You are definitely going to have to switch off alsc in the config. In the tuning config file, under the |
@naushir can you comment on where in the FE process the byte swap is happening? Like you mention before 3A would be broken still, so I imagine the byte swap is happening at the AXI point at the end not at the input? Is it possible the FE processing is messing with the bayer pixels before the byteswap? i.e. DPC mis-identifying pixels and correcting? I notice a ton of speckly white noise in my RAW image... Again I can only speculate at this point... I'd love to know your thoughts |
Have you tried taking the captured 16-bit raw frame and processing it through something like
The byte swap to correct the endiness is happening entirely in software after the FE has written the buffer to memory, so not in the hardware pipeline at all. If things are setup correctly (which I think is the case), the FE will not be doing any pixel processing at all, so the wrong endianness in the pipeline should not matter. You could try disabling some ISP stages and see if that improves things. To do this, remove (or simply rename) the blocks in the json config file to disable the pipeline stages. For example, rename |
Also, what command are you using for the preview? |
Byte swap is not happening in ISP-FE -- what is happening is that big-endian RAW16 data are being passed into ISP-FE input, which assumes little-endian. This is due to an omission from the specification of the preceding (CSI2AXI) block. In order to write out the RAW16 data unchanged, it is important that Front End Decompand, BLA, DPC, Downscale and Compress stages are all disabled (or if BLA is enabled, it must be configured as a no-op; which I think is the default setup). Edit; If you've changed the black level, make sure BLA is disabled here. Software byte-swap now happens after ISP-FE output. |
Turns out in addition to disabling BLA/BLC on the FE, there some peculiarities with bayer order with the this specific sensor mode. I am now able to get a proper ISP preview: @naushir I am using a custom EGL/OpenGL app for preview. |
Glad to see you got things working. However, I'm a bit curious on the details.
How did you disable the FE BLA/BLC? Did you remove the |
I tried a variety of black levels in the tuning file, but all produced visible artifacts in the resulting image. Anything below ~4000 would reveal strange white grain / speckle noise. At first I thought this may have been the FE DPC. At & above 4096, the noise artifacts would be gone, but the image had a very clearly reduced dynamic range and crushed shadow region. So that didn't seem right either. Wasn't until I turned of Bla / Blc via modifying the pisp.cpp in the libcamera ipa module that my suspicions were confirmed. So now rpi.black_level has no effect whatsoever; which isn't ideal but it is a workaround for the moment. |
So this implies that the actual black level of the sensor is not 4096 but higher. This in turn means that what you did to disable BLA/BLC is the only solution. If you remove the |
Trying to get the ClearHDR 16bit mode of an IMX585 working with Raspberry Pi 5 through libcamera.
Here is a capture from libcamera-hello with default viewfinder mode:
Here is a capture from libcamera-hello, with a forced 16-bit unpacked viewfinder mode:
How can libcamera / libpisp be configured to handle this?
EDIT: or is this related to the compressed RAW format in some way?
The text was updated successfully, but these errors were encountered: