Skip to content

ipa: rpi: pisp: Add decompand support using PiSP hardware block #284

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

asofam
Copy link

@asofam asofam commented Jul 15, 2025

Summary

This pull request adds support for decompanding sensor data encoded with companding, using the PiSP hardware block
available on Raspberry Pi 5. The decompand operation is applied prior to ISP processing, enabling linearization of pixel values early in the pipeline.

Changes

1. Decompanding Algorithm

  • Introduced a new decompanding algorithm:
    • decompand_algorithm.h (interface)
    • decompand.cpp/h (implementation)
  • Integrated in the controller framework under ipa/rpi/controller/.

2. PiSP Hardware Support

  • The algorithm connects to the PiSP's hardware decompanding block for efficient processing.
  • pisp.cpp was modified to enable and configure this block based on the provided tuning parameters.

3. Sensor Tuning Configuration

  • Included a tuning file: data/imx585.json (based on external source)
    • Contains "rpi.decompand" parameters, including lut and pad
    • The imx585.json tuning file is derived from a version provided by soho-enterprise.co, with modifications limited to the "rpi.decompand" section.
  • The purpose of this file is to validate and integrate the new decompanding algorithm.
    It may be updated or replaced in the future as upstream sensor support becomes available.

4. Architecture Consideration

  • Maintains modular separation between controller logic and hardware interface
  • Designed to be extensible for additional sensors or alternative LUTs

Rationale

Decompanding is a critical early-stage operation in many modern image pipelines,
especially for sensors that output companded pixel values. By enabling this in the PiSP,
we offload the processing to dedicated hardware, improve performance, and lay the foundation
for accurate linear-space ISP tuning.

Notes

  • This patch does not affect existing sensors or pipelines unless the "rpi.decompand" key is defined.
  • The IMX585 sensor was tested using a kernel driver provided by soho-enterprise.co,
    which is not part of the upstream Linux kernel or libcamera.

Testing

  • Verified functional decompanding behavior with test frames and PiSP configuration
  • Confirmed that no impact occurs for sensors lacking "rpi.decompand" configuration

Signed-off-by

Signed-off-by: Sena Asotani [email protected]

This patch integrates a new decompand algorithm that utilizes the PiSP hardware block
available on Raspberry Pi 5. The implementation enables conversion of companded sensor
data into linear format prior to ISP processing.

Changes include:
- Implementation of decompand logic for controller and pipe interfaces
- Enabling decompand block by "rpi.decompand" in tuning.json

Signed-off-by: Sena Asotani <[email protected]>
@naushir
Copy link
Collaborator

naushir commented Jul 15, 2025

Adding @njhollinghurst and @davidplowman for visilbity.

@asofam thank you for this work! We would be happy to include this functionality into the IPA after review.

return;

pisp_fe_decompand_config config = {};
config.pad = decompandStatus->pad;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove the pad field everywhere (except the existing config structure).

Our convention is to set padding/reserved fields to zero. The {} initializer will zero it here, which is all that's needed. fe->SetDecompand() will also replace it with zero.

I don't think we need any such field to exist in the tuning file or the metadata.

Copy link
Collaborator

@njhollinghurst njhollinghurst Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. if you use it for some other purpose, e.g. as a validity flag, please give it a different name!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review! I've removed the pad field from the tuning file, status structure, and controller code as suggested. The PiSP config structure still retains the field, but it's now zero-initialized using {}.

This patch removes it from the tuning file, DecompandStatus, and related code.
As per reviewer feedback, the 'pad' field is unnecessary outside the PiSP hardware config structure.

Signed-off-by: Sena Asotani <[email protected]>
void Decompand::initialValues(uint16_t LUT[])
{
for (size_t i = 0; i < sizeof(decompandLUT_) / sizeof(decompandLUT_[0]); ++i)
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few formatting issues like this that will need to be fixed up before we can merge. There is a handy git commit hook that can be setup to run a check and give you the formatting errors. You can find more details here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for pointing that out. I wasn't aware of such a helpful tool!
I've run checkstyle.py and corrected the formatting issues accordingly.

29696, 31744, 33792, 35840, 37888, 39936, 41984, 44032,
46080, 48128, 50176, 52224, 54272, 56320, 58368, 60416,
62464
]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the "gamma" tuning block, we specify a PWL instead of the hardware LUT. This is easier for users to visualize, manipulate, and tune for. The IPA (pisp.cpp) translates the PWL into the HW LUT needed to be programmed into the registers.

It would be nice if we can do the same with the decompand block as well - and it provides all the advantages of using PWLs instead of hardware specified LUTs. Would it be possible for you to make this change? Sorry, this is more work for you, but I think it will be better in the long run. Feel free to ask questions if things are unclear!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the suggestion!
I will give it a try to switch the decompand block to use a PWL instead of a hardware LUT, following the approach used in the gamma block. It may take a bit of time, but I will look into the gamma implementation and work from there.

If I run into any unclear points along the way, I would appreciate your guidance. Thank you again!

Adjusted indentation and formatting to comply with project style guidelines,as reported by checkstyle.py.

Signed-off-by: Sena Asotani <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants