[libcamera-devel,RFC,v2] ipa: ipu3: Introduce IPAConfigInfo in IPC
diff mbox series

Message ID 20210427063527.219509-1-umang.jain@ideasonboard.com
State Superseded
Delegated to: Umang Jain
Headers show
Series
  • [libcamera-devel,RFC,v2] ipa: ipu3: Introduce IPAConfigInfo in IPC
Related show

Commit Message

Umang Jain April 27, 2021, 6:35 a.m. UTC
IPAConfigInfo is a consolidated data structure passed from IPU3
pipeline-handler to IPU3 IPA. This provides a streamlined and
extensible way to provide the configuration data to IPA interface.

The IPA interface should be common to both closed-source and
open-source IPU3 IPAs. Hence, the structure encompasses additional
configuration information required to init and configure the
closed-source IPA as well.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
---
Changes in v2:
- Mark as RFC(do not merge) as this is built upon Paul's
  [Fix support for core.mojom structs v3] - waiting for merge to master
- Drop cropRegion_  from structure - this is provided from CameraSensorInfo
  itself.
- Doxygen documentation of IPAConfigInfo.
---
 include/libcamera/ipa/ipu3.mojom     | 46 ++++++++++++++++++++++++++--
 src/ipa/ipu3/ipu3.cpp                | 14 ++++-----
 src/libcamera/pipeline/ipu3/ipu3.cpp |  9 +++++-
 3 files changed, 58 insertions(+), 11 deletions(-)

Comments

Jean-Michel Hautbois April 27, 2021, 11:53 a.m. UTC | #1
Hi Umang,

Thanks for the patch !

On 27/04/2021 08:35, Umang Jain wrote:
> IPAConfigInfo is a consolidated data structure passed from IPU3
> pipeline-handler to IPU3 IPA. This provides a streamlined and
> extensible way to provide the configuration data to IPA interface.
> 
> The IPA interface should be common to both closed-source and
> open-source IPU3 IPAs. Hence, the structure encompasses additional
> configuration information required to init and configure the
> closed-source IPA as well.
> 
> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
> ---
> Changes in v2:
> - Mark as RFC(do not merge) as this is built upon Paul's
>   [Fix support for core.mojom structs v3] - waiting for merge to master
> - Drop cropRegion_  from structure - this is provided from CameraSensorInfo
>   itself.
> - Doxygen documentation of IPAConfigInfo.
> ---
>  include/libcamera/ipa/ipu3.mojom     | 46 ++++++++++++++++++++++++++--
>  src/ipa/ipu3/ipu3.cpp                | 14 ++++-----
>  src/libcamera/pipeline/ipu3/ipu3.cpp |  9 +++++-
>  3 files changed, 58 insertions(+), 11 deletions(-)
> 
> diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom
> index a717b1e6..acd5cfa4 100644
> --- a/include/libcamera/ipa/ipu3.mojom
> +++ b/include/libcamera/ipa/ipu3.mojom
> @@ -25,13 +25,55 @@ struct IPU3Action {
>  	libcamera.ControlList controls;
>  };
>  
> +/**
> + * \struct IPAConfigInfo
> + * \brief Information to be passed from IPU3 pipeline-handler to IPA
> + *
> + * The IPAConfigInfo structure stores the data passed from IPU3 pipeline-handler
> + * to the IPAIPU3Interface::configure(). The structure provides extensibility
> + * for additional configuration data as required, for closed-source or
> + * open-source IPAs' configure() phases.
> + */
> +
> +/**
> + * \var IPAConfigInfo::sensorInfo
> + * \brief Camera sensor information
> + *
> + * Provides the camera sensor information such as model name, pixel-rate,
> + * output-size and so on. Refer to libcamera::CameraSensorInfo for further
> + * details.
> + */
> +
> + /**
> + * \var IPAConfigInfo::entityControls
> + * \brief Controls supported by the sensor
> + *
> + * A map of V4L2 controls supported by the sensor in order to read or write
> + * control values to them.
> + */
> +
> + /**
> + * \var IPAConfigInfo::bdsOutputSize
> + * \brief Size of ImgU BDS rectangle
> + */
> +
> + /**
> + * \var IPAConfigInfo::iif
> + * \brief Size of ImgU input-feeder rectangle
> + */
> +struct IPAConfigInfo {
> +	libcamera.CameraSensorInfo sensorInfo;
> +	map<uint32, ControlInfoMap> entityControls;
> +	libcamera.Size bdsOutputSize;
> +	libcamera.Size iif;
> +};
> +

I think it is interesting, and would like your advice: I would need this
same structure for rkisp1 platform, except that the sizes are obviously
not the same.
And so, I am wondering if we could imagine a more general structure like:
struct IPAConfigInfo {
	libcamera.CameraSensorInfo sensorInfo;
	map<uint32, ControlInfoMap> entityControls;
	libcamera.Size ispInputSize;
	libcamera.Size ispOutputSize;
};

names and all may have to be reworked but that is the base idea.
There is no bds in rkisp1 (afaik) but on both IPU3 and RkIsp1 at least
you have an input an output pad size for the ISP node.

>  interface IPAIPU3Interface {
>  	init(libcamera.IPASettings settings) => (int32 ret);
>  	start() => (int32 ret);
>  	stop();
>  
> -	configure(map<uint32, libcamera.ControlInfoMap> entityControls,
> -		  libcamera.Size bdsOutputSize) => ();
> +	configure(IPAConfigInfo configInfo);
>  
>  	mapBuffers(array<libcamera.IPABuffer> buffers);
>  	unmapBuffers(array<uint32> ids);
> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> index f5343547..769c24d3 100644
> --- a/src/ipa/ipu3/ipu3.cpp
> +++ b/src/ipa/ipu3/ipu3.cpp
> @@ -43,8 +43,7 @@ public:
>  	int start() override;
>  	void stop() override {}
>  
> -	void configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
> -		       const Size &bdsOutputSize) override;
> +	void configure(const IPAConfigInfo &configInfo) override;
>  
>  	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
>  	void unmapBuffers(const std::vector<unsigned int> &ids) override;
> @@ -139,13 +138,12 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
>  			    << (int)bdsGrid_.height << " << " << (int)bdsGrid_.block_height_log2 << ")";
>  }
>  
> -void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
> -			const Size &bdsOutputSize)
> +void IPAIPU3::configure(const IPAConfigInfo &configInfo)
>  {
> -	if (entityControls.empty())
> +	if (configInfo.entityControls.empty())
>  		return;
>  
> -	ctrls_ = entityControls.at(0);
> +	ctrls_ = configInfo.entityControls.at(0);
>  
>  	const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
>  	if (itExp == ctrls_.end()) {
> @@ -169,10 +167,10 @@ void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls
>  
>  	params_ = {};
>  
> -	calculateBdsGrid(bdsOutputSize);
> +	calculateBdsGrid(configInfo.bdsOutputSize);
>  
>  	awbAlgo_ = std::make_unique<IPU3Awb>();
> -	awbAlgo_->initialise(params_, bdsOutputSize, bdsGrid_);
> +	awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
>  
>  	agcAlgo_ = std::make_unique<IPU3Agc>();
>  	agcAlgo_->initialise(bdsGrid_);
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index 73306cea..b1ff1dbe 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -635,7 +635,14 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
>  
>  	std::map<uint32_t, ControlInfoMap> entityControls;
>  	entityControls.emplace(0, data->cio2_.sensor()->controls());
> -	data->ipa_->configure(entityControls, config->imguConfig().bds);
> +
> +	ipa::ipu3::IPAConfigInfo configInfo;
> +	configInfo.sensorInfo = sensorInfo;
> +	configInfo.entityControls = entityControls;
> +	configInfo.bdsOutputSize = config->imguConfig().bds;
> +	configInfo.iif = config->imguConfig().iif;
> +
> +	data->ipa_->configure(configInfo);
>  
>  	return 0;
>  }
>
Umang Jain April 27, 2021, 12:54 p.m. UTC | #2
Hi JM

On 4/27/21 5:23 PM, Jean-Michel Hautbois wrote:
> Hi Umang,
>
> Thanks for the patch !
>
> On 27/04/2021 08:35, Umang Jain wrote:
>> IPAConfigInfo is a consolidated data structure passed from IPU3
>> pipeline-handler to IPU3 IPA. This provides a streamlined and
>> extensible way to provide the configuration data to IPA interface.
>>
>> The IPA interface should be common to both closed-source and
>> open-source IPU3 IPAs. Hence, the structure encompasses additional
>> configuration information required to init and configure the
>> closed-source IPA as well.
>>
>> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
>> ---
>> Changes in v2:
>> - Mark as RFC(do not merge) as this is built upon Paul's
>>    [Fix support for core.mojom structs v3] - waiting for merge to master
>> - Drop cropRegion_  from structure - this is provided from CameraSensorInfo
>>    itself.
>> - Doxygen documentation of IPAConfigInfo.
>> ---
>>   include/libcamera/ipa/ipu3.mojom     | 46 ++++++++++++++++++++++++++--
>>   src/ipa/ipu3/ipu3.cpp                | 14 ++++-----
>>   src/libcamera/pipeline/ipu3/ipu3.cpp |  9 +++++-
>>   3 files changed, 58 insertions(+), 11 deletions(-)
>>
>> diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom
>> index a717b1e6..acd5cfa4 100644
>> --- a/include/libcamera/ipa/ipu3.mojom
>> +++ b/include/libcamera/ipa/ipu3.mojom
>> @@ -25,13 +25,55 @@ struct IPU3Action {
>>   	libcamera.ControlList controls;
>>   };
>>   
>> +/**
>> + * \struct IPAConfigInfo
>> + * \brief Information to be passed from IPU3 pipeline-handler to IPA
>> + *
>> + * The IPAConfigInfo structure stores the data passed from IPU3 pipeline-handler
>> + * to the IPAIPU3Interface::configure(). The structure provides extensibility
>> + * for additional configuration data as required, for closed-source or
>> + * open-source IPAs' configure() phases.
>> + */
>> +
>> +/**
>> + * \var IPAConfigInfo::sensorInfo
>> + * \brief Camera sensor information
>> + *
>> + * Provides the camera sensor information such as model name, pixel-rate,
>> + * output-size and so on. Refer to libcamera::CameraSensorInfo for further
>> + * details.
>> + */
>> +
>> + /**
>> + * \var IPAConfigInfo::entityControls
>> + * \brief Controls supported by the sensor
>> + *
>> + * A map of V4L2 controls supported by the sensor in order to read or write
>> + * control values to them.
>> + */
>> +
>> + /**
>> + * \var IPAConfigInfo::bdsOutputSize
>> + * \brief Size of ImgU BDS rectangle
>> + */
>> +
>> + /**
>> + * \var IPAConfigInfo::iif
>> + * \brief Size of ImgU input-feeder rectangle
>> + */
>> +struct IPAConfigInfo {
>> +	libcamera.CameraSensorInfo sensorInfo;
>> +	map<uint32, ControlInfoMap> entityControls;
>> +	libcamera.Size bdsOutputSize;
>> +	libcamera.Size iif;
>> +};
>> +
> I think it is interesting, and would like your advice: I would need this
> same structure for rkisp1 platform, except that the sizes are obviously
> not the same.
> And so, I am wondering if we could imagine a more general structure like:
> struct IPAConfigInfo {
> 	libcamera.CameraSensorInfo sensorInfo;
> 	map<uint32, ControlInfoMap> entityControls;
> 	libcamera.Size ispInputSize;
> 	libcamera.Size ispOutputSize;
> };
>
> names and all may have to be reworked but that is the base idea.
> There is no bds in rkisp1 (afaik) but on both IPU3 and RkIsp1 at least
> you have an input an output pad size for the ISP node.
Certainly, this might be a good idea. I am not opposed to it.

The question here is, that is the structure core.mojom worthy, in order 
to be shared between multiple IPAs right? If not, I think we need to 
keep them in <platform IPA>.mojom for now.

And if we want to share the data-structures, we need to work out how all 
existing IPAs (for e.g. Raspberry Pi) can be ported to used that 
IPAConfig structure too. We probably, should address this by looking at 
all the common parameters we need for all the existing IPAs and have a 
patch series that ports every IPA to use that data-structure.

However, there are some risky? situations that can happen, for e.g.
  - An IPA X requiring a parameter Y for configuration and the common 
struct IPAConfig doesn't have a placeholder
  - Parameter Y is added to common struct IPAConfig
  - Parameter Y is unused/nullptr for all IPAs except IPA X

I do not know if adding placeholder for Y is fine in the common struct, 
if fine or not, in the codebase purview.

Thinking about it, the chances of various IPA, having exact 
configuration data (common IPAConfig) are slim. Hence, the IPA authors 
will try hacks for other parameters they need for IPA configuration, 
either as function-params or introducing new structures and passing 
alongside with common struct IPAConfig to the IPA. That would not be 
nice, isn't it?

I might be wrong, so I shall keep an open mind about it. Maybe we can 
track this as a task somewhere too?

>
>>   interface IPAIPU3Interface {
>>   	init(libcamera.IPASettings settings) => (int32 ret);
>>   	start() => (int32 ret);
>>   	stop();
>>   
>> -	configure(map<uint32, libcamera.ControlInfoMap> entityControls,
>> -		  libcamera.Size bdsOutputSize) => ();
>> +	configure(IPAConfigInfo configInfo);
>>   
>>   	mapBuffers(array<libcamera.IPABuffer> buffers);
>>   	unmapBuffers(array<uint32> ids);
>> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
>> index f5343547..769c24d3 100644
>> --- a/src/ipa/ipu3/ipu3.cpp
>> +++ b/src/ipa/ipu3/ipu3.cpp
>> @@ -43,8 +43,7 @@ public:
>>   	int start() override;
>>   	void stop() override {}
>>   
>> -	void configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
>> -		       const Size &bdsOutputSize) override;
>> +	void configure(const IPAConfigInfo &configInfo) override;
>>   
>>   	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
>>   	void unmapBuffers(const std::vector<unsigned int> &ids) override;
>> @@ -139,13 +138,12 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
>>   			    << (int)bdsGrid_.height << " << " << (int)bdsGrid_.block_height_log2 << ")";
>>   }
>>   
>> -void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
>> -			const Size &bdsOutputSize)
>> +void IPAIPU3::configure(const IPAConfigInfo &configInfo)
>>   {
>> -	if (entityControls.empty())
>> +	if (configInfo.entityControls.empty())
>>   		return;
>>   
>> -	ctrls_ = entityControls.at(0);
>> +	ctrls_ = configInfo.entityControls.at(0);
>>   
>>   	const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
>>   	if (itExp == ctrls_.end()) {
>> @@ -169,10 +167,10 @@ void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls
>>   
>>   	params_ = {};
>>   
>> -	calculateBdsGrid(bdsOutputSize);
>> +	calculateBdsGrid(configInfo.bdsOutputSize);
>>   
>>   	awbAlgo_ = std::make_unique<IPU3Awb>();
>> -	awbAlgo_->initialise(params_, bdsOutputSize, bdsGrid_);
>> +	awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
>>   
>>   	agcAlgo_ = std::make_unique<IPU3Agc>();
>>   	agcAlgo_->initialise(bdsGrid_);
>> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
>> index 73306cea..b1ff1dbe 100644
>> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
>> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
>> @@ -635,7 +635,14 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
>>   
>>   	std::map<uint32_t, ControlInfoMap> entityControls;
>>   	entityControls.emplace(0, data->cio2_.sensor()->controls());
>> -	data->ipa_->configure(entityControls, config->imguConfig().bds);
>> +
>> +	ipa::ipu3::IPAConfigInfo configInfo;
>> +	configInfo.sensorInfo = sensorInfo;
>> +	configInfo.entityControls = entityControls;
>> +	configInfo.bdsOutputSize = config->imguConfig().bds;
>> +	configInfo.iif = config->imguConfig().iif;
>> +
>> +	data->ipa_->configure(configInfo);
>>   
>>   	return 0;
>>   }
>>
Jean-Michel Hautbois April 29, 2021, 5:30 a.m. UTC | #3
On 27/04/2021 14:54, Umang Jain wrote:
> Hi JM
> 
> On 4/27/21 5:23 PM, Jean-Michel Hautbois wrote:
>> Hi Umang,
>>
>> Thanks for the patch !
>>
>> On 27/04/2021 08:35, Umang Jain wrote:
>>> IPAConfigInfo is a consolidated data structure passed from IPU3
>>> pipeline-handler to IPU3 IPA. This provides a streamlined and
>>> extensible way to provide the configuration data to IPA interface.
>>>
>>> The IPA interface should be common to both closed-source and
>>> open-source IPU3 IPAs. Hence, the structure encompasses additional
>>> configuration information required to init and configure the
>>> closed-source IPA as well.
>>>
>>> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
>>> ---
>>> Changes in v2:
>>> - Mark as RFC(do not merge) as this is built upon Paul's
>>>    [Fix support for core.mojom structs v3] - waiting for merge to master
>>> - Drop cropRegion_  from structure - this is provided from
>>> CameraSensorInfo
>>>    itself.
>>> - Doxygen documentation of IPAConfigInfo.
>>> ---
>>>   include/libcamera/ipa/ipu3.mojom     | 46 ++++++++++++++++++++++++++--
>>>   src/ipa/ipu3/ipu3.cpp                | 14 ++++-----
>>>   src/libcamera/pipeline/ipu3/ipu3.cpp |  9 +++++-
>>>   3 files changed, 58 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/include/libcamera/ipa/ipu3.mojom
>>> b/include/libcamera/ipa/ipu3.mojom
>>> index a717b1e6..acd5cfa4 100644
>>> --- a/include/libcamera/ipa/ipu3.mojom
>>> +++ b/include/libcamera/ipa/ipu3.mojom
>>> @@ -25,13 +25,55 @@ struct IPU3Action {
>>>       libcamera.ControlList controls;
>>>   };
>>>   +/**
>>> + * \struct IPAConfigInfo
>>> + * \brief Information to be passed from IPU3 pipeline-handler to IPA
>>> + *
>>> + * The IPAConfigInfo structure stores the data passed from IPU3
>>> pipeline-handler
>>> + * to the IPAIPU3Interface::configure(). The structure provides
>>> extensibility
>>> + * for additional configuration data as required, for closed-source or
>>> + * open-source IPAs' configure() phases.
>>> + */
>>> +
>>> +/**
>>> + * \var IPAConfigInfo::sensorInfo
>>> + * \brief Camera sensor information
>>> + *
>>> + * Provides the camera sensor information such as model name,
>>> pixel-rate,
>>> + * output-size and so on. Refer to libcamera::CameraSensorInfo for
>>> further
>>> + * details.
>>> + */
>>> +
>>> + /**
>>> + * \var IPAConfigInfo::entityControls
>>> + * \brief Controls supported by the sensor
>>> + *
>>> + * A map of V4L2 controls supported by the sensor in order to read
>>> or write
>>> + * control values to them.
>>> + */
>>> +
>>> + /**
>>> + * \var IPAConfigInfo::bdsOutputSize
>>> + * \brief Size of ImgU BDS rectangle
>>> + */
>>> +
>>> + /**
>>> + * \var IPAConfigInfo::iif
>>> + * \brief Size of ImgU input-feeder rectangle
>>> + */
>>> +struct IPAConfigInfo {
>>> +    libcamera.CameraSensorInfo sensorInfo;
>>> +    map<uint32, ControlInfoMap> entityControls;
>>> +    libcamera.Size bdsOutputSize;
>>> +    libcamera.Size iif;
>>> +};
>>> +
>> I think it is interesting, and would like your advice: I would need this
>> same structure for rkisp1 platform, except that the sizes are obviously
>> not the same.
>> And so, I am wondering if we could imagine a more general structure like:
>> struct IPAConfigInfo {
>>     libcamera.CameraSensorInfo sensorInfo;
>>     map<uint32, ControlInfoMap> entityControls;
>>     libcamera.Size ispInputSize;
>>     libcamera.Size ispOutputSize;
>> };
>>
>> names and all may have to be reworked but that is the base idea.
>> There is no bds in rkisp1 (afaik) but on both IPU3 and RkIsp1 at least
>> you have an input an output pad size for the ISP node.
> Certainly, this might be a good idea. I am not opposed to it.
> 
> The question here is, that is the structure core.mojom worthy, in order
> to be shared between multiple IPAs right? If not, I think we need to
> keep them in <platform IPA>.mojom for now.
> 
> And if we want to share the data-structures, we need to work out how all
> existing IPAs (for e.g. Raspberry Pi) can be ported to used that
> IPAConfig structure too. We probably, should address this by looking at
> all the common parameters we need for all the existing IPAs and have a
> patch series that ports every IPA to use that data-structure.
> 
> However, there are some risky? situations that can happen, for e.g.
>  - An IPA X requiring a parameter Y for configuration and the common
> struct IPAConfig doesn't have a placeholder
>  - Parameter Y is added to common struct IPAConfig
>  - Parameter Y is unused/nullptr for all IPAs except IPA X
> 
> I do not know if adding placeholder for Y is fine in the common struct,
> if fine or not, in the codebase purview.
> 
> Thinking about it, the chances of various IPA, having exact
> configuration data (common IPAConfig) are slim. Hence, the IPA authors
> will try hacks for other parameters they need for IPA configuration,
> either as function-params or introducing new structures and passing
> alongside with common struct IPAConfig to the IPA. That would not be
> nice, isn't it?
> 
> I might be wrong, so I shall keep an open mind about it. Maybe we can
> track this as a task somewhere too?
> 

The idea I had is to have a common structure, and having the IPA
specific ones inherit from this common one.
You would have something like
IPAIPU3ConfigInfo: IPAConfigInfo {
	/* myGreatParameters */
}

That one may not make sense though :-).

>>
>>>   interface IPAIPU3Interface {
>>>       init(libcamera.IPASettings settings) => (int32 ret);
>>>       start() => (int32 ret);
>>>       stop();
>>>   -    configure(map<uint32, libcamera.ControlInfoMap> entityControls,
>>> -          libcamera.Size bdsOutputSize) => ();
>>> +    configure(IPAConfigInfo configInfo);
>>>         mapBuffers(array<libcamera.IPABuffer> buffers);
>>>       unmapBuffers(array<uint32> ids);
>>> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
>>> index f5343547..769c24d3 100644
>>> --- a/src/ipa/ipu3/ipu3.cpp
>>> +++ b/src/ipa/ipu3/ipu3.cpp
>>> @@ -43,8 +43,7 @@ public:
>>>       int start() override;
>>>       void stop() override {}
>>>   -    void configure(const std::map<uint32_t, ControlInfoMap>
>>> &entityControls,
>>> -               const Size &bdsOutputSize) override;
>>> +    void configure(const IPAConfigInfo &configInfo) override;
>>>         void mapBuffers(const std::vector<IPABuffer> &buffers) override;
>>>       void unmapBuffers(const std::vector<unsigned int> &ids) override;
>>> @@ -139,13 +138,12 @@ void IPAIPU3::calculateBdsGrid(const Size
>>> &bdsOutputSize)
>>>                   << (int)bdsGrid_.height << " << " <<
>>> (int)bdsGrid_.block_height_log2 << ")";
>>>   }
>>>   -void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap>
>>> &entityControls,
>>> -            const Size &bdsOutputSize)
>>> +void IPAIPU3::configure(const IPAConfigInfo &configInfo)
>>>   {
>>> -    if (entityControls.empty())
>>> +    if (configInfo.entityControls.empty())
>>>           return;
>>>   -    ctrls_ = entityControls.at(0);
>>> +    ctrls_ = configInfo.entityControls.at(0);
>>>         const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
>>>       if (itExp == ctrls_.end()) {
>>> @@ -169,10 +167,10 @@ void IPAIPU3::configure(const
>>> std::map<uint32_t, ControlInfoMap> &entityControls
>>>         params_ = {};
>>>   -    calculateBdsGrid(bdsOutputSize);
>>> +    calculateBdsGrid(configInfo.bdsOutputSize);
>>>         awbAlgo_ = std::make_unique<IPU3Awb>();
>>> -    awbAlgo_->initialise(params_, bdsOutputSize, bdsGrid_);
>>> +    awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
>>>         agcAlgo_ = std::make_unique<IPU3Agc>();
>>>       agcAlgo_->initialise(bdsGrid_);
>>> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp
>>> b/src/libcamera/pipeline/ipu3/ipu3.cpp
>>> index 73306cea..b1ff1dbe 100644
>>> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
>>> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
>>> @@ -635,7 +635,14 @@ int PipelineHandlerIPU3::configure(Camera
>>> *camera, CameraConfiguration *c)
>>>         std::map<uint32_t, ControlInfoMap> entityControls;
>>>       entityControls.emplace(0, data->cio2_.sensor()->controls());
>>> -    data->ipa_->configure(entityControls, config->imguConfig().bds);
>>> +
>>> +    ipa::ipu3::IPAConfigInfo configInfo;
>>> +    configInfo.sensorInfo = sensorInfo;
>>> +    configInfo.entityControls = entityControls;
>>> +    configInfo.bdsOutputSize = config->imguConfig().bds;
>>> +    configInfo.iif = config->imguConfig().iif;
>>> +
>>> +    data->ipa_->configure(configInfo);
>>>         return 0;
>>>   }
>>>
>
Jacopo Mondi April 29, 2021, 7:45 a.m. UTC | #4
Hi Umang,

On Tue, Apr 27, 2021 at 12:05:27PM +0530, Umang Jain wrote:
> IPAConfigInfo is a consolidated data structure passed from IPU3
> pipeline-handler to IPU3 IPA. This provides a streamlined and
> extensible way to provide the configuration data to IPA interface.
>
> The IPA interface should be common to both closed-source and
> open-source IPU3 IPAs. Hence, the structure encompasses additional
> configuration information required to init and configure the
> closed-source IPA as well.
>
> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
> ---
> Changes in v2:
> - Mark as RFC(do not merge) as this is built upon Paul's
>   [Fix support for core.mojom structs v3] - waiting for merge to master
> - Drop cropRegion_  from structure - this is provided from CameraSensorInfo
>   itself.
> - Doxygen documentation of IPAConfigInfo.
> ---
>  include/libcamera/ipa/ipu3.mojom     | 46 ++++++++++++++++++++++++++--
>  src/ipa/ipu3/ipu3.cpp                | 14 ++++-----
>  src/libcamera/pipeline/ipu3/ipu3.cpp |  9 +++++-
>  3 files changed, 58 insertions(+), 11 deletions(-)
>
> diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom
> index a717b1e6..acd5cfa4 100644
> --- a/include/libcamera/ipa/ipu3.mojom
> +++ b/include/libcamera/ipa/ipu3.mojom
> @@ -25,13 +25,55 @@ struct IPU3Action {
>  	libcamera.ControlList controls;
>  };
>
> +/**
> + * \struct IPAConfigInfo
> + * \brief Information to be passed from IPU3 pipeline-handler to IPA

to 'the' IPA ?

> + *
> + * The IPAConfigInfo structure stores the data passed from IPU3 pipeline-handler
> + * to the IPAIPU3Interface::configure(). The structure provides extensibility
> + * for additional configuration data as required, for closed-source or
> + * open-source IPAs' configure() phases.

What do you mean with extensibility ? That one can add fields to the
structure, like to all structures ? :)
Or are you thinking at some inheritance mechanism ?

In the former case I would say
"The structure can be extended with additional parameters to
accommodate the requirements of different IPA modules"


> + */
> +
> +/**
> + * \var IPAConfigInfo::sensorInfo
> + * \brief Camera sensor information
> + *
> + * Provides the camera sensor information such as model name, pixel-rate,
> + * output-size and so on. Refer to libcamera::CameraSensorInfo for further
> + * details.

I would just:
        \sa CameraSensorInfo

As duplicating the description has limited value imho

> + */
> +
> + /**
> + * \var IPAConfigInfo::entityControls
> + * \brief Controls supported by the sensor
> + *
> + * A map of V4L2 controls supported by the sensor in order to read or write
> + * control values to them.
> + */

The existing entityControls is described as
\param[in] entityControls Controls provided by the pipeline entities

and it does not only include the sensor controls (otherwise it would
have been just a ControlInfoMap not a map). The idea was that each ph-IPA
defines it's own mapping. Ie entityControls[0] = sensor controls,
entityControls[1] = someother entity controls, etc etc).

So far I think only this is only been effectively used to transport
sensor controls, and I would be fine making this a ControlList and
name it 'sensorControls'. Even if we later need to pass to IPA the
ControlInfoMap of another entity, we can add it to this structure with
a more explicit name (much better than hiding it in a map and
establishing what an index maps to like we're doing now)

> +
> + /**
> + * \var IPAConfigInfo::bdsOutputSize
> + * \brief Size of ImgU BDS rectangle
> + */
> +
> + /**
> + * \var IPAConfigInfo::iif
> + * \brief Size of ImgU input-feeder rectangle
> + */

Empty line maybe.

I wonder if it wouldn't be better to pass the full
ImgUDevice::PipeConfig. True that the less data we transport over IPC
the better, so this makes sense. Is it worth wrapping thise two sizes
in an 'ImguSize' structure ?

BTW I don't see iif being used currently. Will you need it in future ?

> +struct IPAConfigInfo {
> +	libcamera.CameraSensorInfo sensorInfo;
> +	map<uint32, ControlInfoMap> entityControls;
> +	libcamera.Size bdsOutputSize;
> +	libcamera.Size iif;
> +};
> +
>  interface IPAIPU3Interface {
>  	init(libcamera.IPASettings settings) => (int32 ret);
>  	start() => (int32 ret);
>  	stop();
>
> -	configure(map<uint32, libcamera.ControlInfoMap> entityControls,
> -		  libcamera.Size bdsOutputSize) => ();
> +	configure(IPAConfigInfo configInfo);

No idea how that works for IPC, but if this was a regular function I
would have made this
        configure(const IPAConfigInfo &configInfo)

>
>  	mapBuffers(array<libcamera.IPABuffer> buffers);
>  	unmapBuffers(array<uint32> ids);
> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> index f5343547..769c24d3 100644
> --- a/src/ipa/ipu3/ipu3.cpp
> +++ b/src/ipa/ipu3/ipu3.cpp
> @@ -43,8 +43,7 @@ public:
>  	int start() override;
>  	void stop() override {}
>
> -	void configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
> -		       const Size &bdsOutputSize) override;
> +	void configure(const IPAConfigInfo &configInfo) override;

Ah

Why the two prototypes are different ?

>
>  	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
>  	void unmapBuffers(const std::vector<unsigned int> &ids) override;
> @@ -139,13 +138,12 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
>  			    << (int)bdsGrid_.height << " << " << (int)bdsGrid_.block_height_log2 << ")";
>  }
>
> -void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
> -			const Size &bdsOutputSize)
> +void IPAIPU3::configure(const IPAConfigInfo &configInfo)
>  {
> -	if (entityControls.empty())
> +	if (configInfo.entityControls.empty())
>  		return;
>
> -	ctrls_ = entityControls.at(0);
> +	ctrls_ = configInfo.entityControls.at(0);
>
>  	const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
>  	if (itExp == ctrls_.end()) {
> @@ -169,10 +167,10 @@ void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls
>
>  	params_ = {};
>
> -	calculateBdsGrid(bdsOutputSize);
> +	calculateBdsGrid(configInfo.bdsOutputSize);
>
>  	awbAlgo_ = std::make_unique<IPU3Awb>();
> -	awbAlgo_->initialise(params_, bdsOutputSize, bdsGrid_);
> +	awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
>
>  	agcAlgo_ = std::make_unique<IPU3Agc>();
>  	agcAlgo_->initialise(bdsGrid_);
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index 73306cea..b1ff1dbe 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -635,7 +635,14 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
>
>  	std::map<uint32_t, ControlInfoMap> entityControls;
>  	entityControls.emplace(0, data->cio2_.sensor()->controls());
> -	data->ipa_->configure(entityControls, config->imguConfig().bds);
> +
> +	ipa::ipu3::IPAConfigInfo configInfo;
> +	configInfo.sensorInfo = sensorInfo;
> +	configInfo.entityControls = entityControls;

Why a copy when you can populate this one directly ?

Overall the idea is good. I would refrain from premature optimizations
like the one suggested by Jean-Micheal for the moment though, it's a
bit too early in my opinion, and the effort for each pipeline handler
to define its own exchange structures is limited.

Thanks
   j

> +	configInfo.bdsOutputSize = config->imguConfig().bds;
> +	configInfo.iif = config->imguConfig().iif;
> +
> +	data->ipa_->configure(configInfo);
>
>  	return 0;
>  }
> --
> 2.26.2
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
Umang Jain April 29, 2021, 8:25 a.m. UTC | #5
Hi Jacopo,

Thanks for comments,

On 4/29/21 1:15 PM, Jacopo Mondi wrote:
> Hi Umang,
>
> On Tue, Apr 27, 2021 at 12:05:27PM +0530, Umang Jain wrote:
>> IPAConfigInfo is a consolidated data structure passed from IPU3
>> pipeline-handler to IPU3 IPA. This provides a streamlined and
>> extensible way to provide the configuration data to IPA interface.
>>
>> The IPA interface should be common to both closed-source and
>> open-source IPU3 IPAs. Hence, the structure encompasses additional
>> configuration information required to init and configure the
>> closed-source IPA as well.
>>
>> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
>> ---
>> Changes in v2:
>> - Mark as RFC(do not merge) as this is built upon Paul's
>>    [Fix support for core.mojom structs v3] - waiting for merge to master
>> - Drop cropRegion_  from structure - this is provided from CameraSensorInfo
>>    itself.
>> - Doxygen documentation of IPAConfigInfo.
>> ---
>>   include/libcamera/ipa/ipu3.mojom     | 46 ++++++++++++++++++++++++++--
>>   src/ipa/ipu3/ipu3.cpp                | 14 ++++-----
>>   src/libcamera/pipeline/ipu3/ipu3.cpp |  9 +++++-
>>   3 files changed, 58 insertions(+), 11 deletions(-)
>>
>> diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom
>> index a717b1e6..acd5cfa4 100644
>> --- a/include/libcamera/ipa/ipu3.mojom
>> +++ b/include/libcamera/ipa/ipu3.mojom
>> @@ -25,13 +25,55 @@ struct IPU3Action {
>>   	libcamera.ControlList controls;
>>   };
>>
>> +/**
>> + * \struct IPAConfigInfo
>> + * \brief Information to be passed from IPU3 pipeline-handler to IPA
> to 'the' IPA ?
>
>> + *
>> + * The IPAConfigInfo structure stores the data passed from IPU3 pipeline-handler
>> + * to the IPAIPU3Interface::configure(). The structure provides extensibility
>> + * for additional configuration data as required, for closed-source or
>> + * open-source IPAs' configure() phases.
> What do you mean with extensibility ? That one can add fields to the
> structure, like to all structures ? :)
> Or are you thinking at some inheritance mechanism ?
>
> In the former case I would say
> "The structure can be extended with additional parameters to
> accommodate the requirements of different IPA modules"
Ok, I meant the former, I shall re-word in next iteration
>
>
>> + */
>> +
>> +/**
>> + * \var IPAConfigInfo::sensorInfo
>> + * \brief Camera sensor information
>> + *
>> + * Provides the camera sensor information such as model name, pixel-rate,
>> + * output-size and so on. Refer to libcamera::CameraSensorInfo for further
>> + * details.
> I would just:
>          \sa CameraSensorInfo
>
> As duplicating the description has limited value imho
Agreed
>
>> + */
>> +
>> + /**
>> + * \var IPAConfigInfo::entityControls
>> + * \brief Controls supported by the sensor
>> + *
>> + * A map of V4L2 controls supported by the sensor in order to read or write
>> + * control values to them.
>> + */
> The existing entityControls is described as
> \param[in] entityControls Controls provided by the pipeline entities
>
> and it does not only include the sensor controls (otherwise it would
> have been just a ControlInfoMap not a map). The idea was that each ph-IPA
> defines it's own mapping. Ie entityControls[0] = sensor controls,
> entityControls[1] = someother entity controls, etc etc).
>
> So far I think only this is only been effectively used to transport
> sensor controls, and I would be fine making this a ControlList and
> name it 'sensorControls'. Even if we later need to pass to IPA the
> ControlInfoMap of another entity, we can add it to this structure with
> a more explicit name (much better than hiding it in a map and
> establishing what an index maps to like we're doing now)
Oh, thanks for the context. I'll take a note of it and tinker on how we 
can address this change and adapt the documentation. Might need some 
cycle of discussion in general with Kieran too!
>
>> +
>> + /**
>> + * \var IPAConfigInfo::bdsOutputSize
>> + * \brief Size of ImgU BDS rectangle
>> + */
>> +
>> + /**
>> + * \var IPAConfigInfo::iif
>> + * \brief Size of ImgU input-feeder rectangle
>> + */
> Empty line maybe.
>
> I wonder if it wouldn't be better to pass the full
> ImgUDevice::PipeConfig. True that the less data we transport over IPC
> the better, so this makes sense. Is it worth wrapping thise two sizes
> in an 'ImguSize' structure ?
Maybe - I see this as an optimization point, so not my highest priority 
as of now.
>
> BTW I don't see iif being used currently. Will you need it in future ?
`iif` is used for closed source IPA. So, the  current issue is we have 
two competing IPAs - Open IPU3 IPA (already merged in-tree) and a closed 
one(probably will be residing in it's own git repo). But the ph-IPA 
interface has to be common to both. This is why you don't see `iif` 
usage here(in open IPA), but is need for the closed one.
>
>> +struct IPAConfigInfo {
>> +	libcamera.CameraSensorInfo sensorInfo;
>> +	map<uint32, ControlInfoMap> entityControls;
>> +	libcamera.Size bdsOutputSize;
>> +	libcamera.Size iif;
>> +};
>> +
>>   interface IPAIPU3Interface {
>>   	init(libcamera.IPASettings settings) => (int32 ret);
>>   	start() => (int32 ret);
>>   	stop();
>>
>> -	configure(map<uint32, libcamera.ControlInfoMap> entityControls,
>> -		  libcamera.Size bdsOutputSize) => ();
>> +	configure(IPAConfigInfo configInfo);
> No idea how that works for IPC, but if this was a regular function I
> would have made this
>          configure(const IPAConfigInfo &configInfo)
These are mojom declarations - hence I believe the framework by-default 
enforces that all function parameters are `const` and passed 
by-reference. These mojom files are used to generated the .cpp interface 
code (see include/libcamera/ipa/meson.build), which matches the 
prototype below (where you have comment (`Why the two prototypes are 
different`).
>
>>   	mapBuffers(array<libcamera.IPABuffer> buffers);
>>   	unmapBuffers(array<uint32> ids);
>> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
>> index f5343547..769c24d3 100644
>> --- a/src/ipa/ipu3/ipu3.cpp
>> +++ b/src/ipa/ipu3/ipu3.cpp
>> @@ -43,8 +43,7 @@ public:
>>   	int start() override;
>>   	void stop() override {}
>>
>> -	void configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
>> -		       const Size &bdsOutputSize) override;
>> +	void configure(const IPAConfigInfo &configInfo) override;
> Ah
>
> Why the two prototypes are different ?
>
>>   	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
>>   	void unmapBuffers(const std::vector<unsigned int> &ids) override;
>> @@ -139,13 +138,12 @@ void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
>>   			    << (int)bdsGrid_.height << " << " << (int)bdsGrid_.block_height_log2 << ")";
>>   }
>>
>> -void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
>> -			const Size &bdsOutputSize)
>> +void IPAIPU3::configure(const IPAConfigInfo &configInfo)
>>   {
>> -	if (entityControls.empty())
>> +	if (configInfo.entityControls.empty())
>>   		return;
>>
>> -	ctrls_ = entityControls.at(0);
>> +	ctrls_ = configInfo.entityControls.at(0);
>>
>>   	const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
>>   	if (itExp == ctrls_.end()) {
>> @@ -169,10 +167,10 @@ void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls
>>
>>   	params_ = {};
>>
>> -	calculateBdsGrid(bdsOutputSize);
>> +	calculateBdsGrid(configInfo.bdsOutputSize);
>>
>>   	awbAlgo_ = std::make_unique<IPU3Awb>();
>> -	awbAlgo_->initialise(params_, bdsOutputSize, bdsGrid_);
>> +	awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
>>
>>   	agcAlgo_ = std::make_unique<IPU3Agc>();
>>   	agcAlgo_->initialise(bdsGrid_);
>> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
>> index 73306cea..b1ff1dbe 100644
>> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
>> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
>> @@ -635,7 +635,14 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
>>
>>   	std::map<uint32_t, ControlInfoMap> entityControls;
>>   	entityControls.emplace(0, data->cio2_.sensor()->controls());
>> -	data->ipa_->configure(entityControls, config->imguConfig().bds);
>> +
>> +	ipa::ipu3::IPAConfigInfo configInfo;
>> +	configInfo.sensorInfo = sensorInfo;
>> +	configInfo.entityControls = entityControls;
> Why a copy when you can populate this one directly ?
Originally it was your suggested way only, but Laurent wanted to use 
named initializers for safety - as there are couple of `Sizes` 
parameters and one can get the ordering wrong in directly populating 
them. IPAConfigInfo is generated from mojom framework and doesn't yet 
support named initiazers hence, this is what I ended up as closest 
implementation.
>
> Overall the idea is good. I would refrain from premature optimizations
> like the one suggested by Jean-Micheal for the moment though, it's a
> bit too early in my opinion, and the effort for each pipeline handler
> to define its own exchange structures is limited.
Yes - overall idea is good, but I would be comfortable doing that when 
we have got some level of stability for the closed source IPA
>
> Thanks
>     j
>
>> +	configInfo.bdsOutputSize = config->imguConfig().bds;
>> +	configInfo.iif = config->imguConfig().iif;
>> +
>> +	data->ipa_->configure(configInfo);
>>
>>   	return 0;
>>   }
>> --
>> 2.26.2
>>
>> _______________________________________________
>> libcamera-devel mailing list
>> libcamera-devel@lists.libcamera.org
>> https://lists.libcamera.org/listinfo/libcamera-devel
Jacopo Mondi April 29, 2021, 8:32 a.m. UTC | #6
Hi Umang,

On Thu, Apr 29, 2021 at 01:55:57PM +0530, Umang Jain wrote:

[snip]

> > > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> > > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> > > @@ -635,7 +635,14 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
> > >
> > >   	std::map<uint32_t, ControlInfoMap> entityControls;
> > >   	entityControls.emplace(0, data->cio2_.sensor()->controls());
> > > -	data->ipa_->configure(entityControls, config->imguConfig().bds);
> > > +
> > > +	ipa::ipu3::IPAConfigInfo configInfo;
> > > +	configInfo.sensorInfo = sensorInfo;
> > > +	configInfo.entityControls = entityControls;
> > Why a copy when you can populate this one directly ?
> Originally it was your suggested way only, but Laurent wanted to use named
> initializers for safety - as there are couple of `Sizes` parameters and one
> can get the ordering wrong in directly populating them. IPAConfigInfo is
> generated from mojom framework and doesn't yet support named initiazers
> hence, this is what I ended up as closest implementation.

What I meant was:

why do this
        std::map<uint32_t, ControlInfoMap> entityControls;
	entityControls.emplace(0, data->cio2_.sensor()->controls());
        ....
        configInfo.entityControls = entityControls;

Instead of
        configInfo.entityControls.emplace(0, data->cio2_.sensor()->controls());

and avoid the copy ?

Thanks
   j


> >
> > Overall the idea is good. I would refrain from premature optimizations
> > like the one suggested by Jean-Micheal for the moment though, it's a
> > bit too early in my opinion, and the effort for each pipeline handler
> > to define its own exchange structures is limited.
> Yes - overall idea is good, but I would be comfortable doing that when we
> have got some level of stability for the closed source IPA
> >
> > Thanks
> >     j
> >
> > > +	configInfo.bdsOutputSize = config->imguConfig().bds;
> > > +	configInfo.iif = config->imguConfig().iif;
> > > +
> > > +	data->ipa_->configure(configInfo);
> > >
> > >   	return 0;
> > >   }
> > > --
> > > 2.26.2
> > >
> > > _______________________________________________
> > > libcamera-devel mailing list
> > > libcamera-devel@lists.libcamera.org
> > > https://lists.libcamera.org/listinfo/libcamera-devel
>
Laurent Pinchart April 30, 2021, 12:40 a.m. UTC | #7
Hi Jean-Michel,

On Thu, Apr 29, 2021 at 07:30:47AM +0200, Jean-Michel Hautbois wrote:
> On 27/04/2021 14:54, Umang Jain wrote:
> > On 4/27/21 5:23 PM, Jean-Michel Hautbois wrote:
> >> On 27/04/2021 08:35, Umang Jain wrote:
> >>> IPAConfigInfo is a consolidated data structure passed from IPU3
> >>> pipeline-handler to IPU3 IPA. This provides a streamlined and
> >>> extensible way to provide the configuration data to IPA interface.
> >>>
> >>> The IPA interface should be common to both closed-source and
> >>> open-source IPU3 IPAs. Hence, the structure encompasses additional
> >>> configuration information required to init and configure the
> >>> closed-source IPA as well.
> >>>
> >>> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
> >>> ---
> >>> Changes in v2:
> >>> - Mark as RFC(do not merge) as this is built upon Paul's
> >>>    [Fix support for core.mojom structs v3] - waiting for merge to master
> >>> - Drop cropRegion_  from structure - this is provided from
> >>> CameraSensorInfo
> >>>    itself.
> >>> - Doxygen documentation of IPAConfigInfo.
> >>> ---
> >>>   include/libcamera/ipa/ipu3.mojom     | 46 ++++++++++++++++++++++++++--
> >>>   src/ipa/ipu3/ipu3.cpp                | 14 ++++-----
> >>>   src/libcamera/pipeline/ipu3/ipu3.cpp |  9 +++++-
> >>>   3 files changed, 58 insertions(+), 11 deletions(-)
> >>>
> >>> diff --git a/include/libcamera/ipa/ipu3.mojom
> >>> b/include/libcamera/ipa/ipu3.mojom
> >>> index a717b1e6..acd5cfa4 100644
> >>> --- a/include/libcamera/ipa/ipu3.mojom
> >>> +++ b/include/libcamera/ipa/ipu3.mojom
> >>> @@ -25,13 +25,55 @@ struct IPU3Action {
> >>>       libcamera.ControlList controls;
> >>>   };
> >>>   +/**
> >>> + * \struct IPAConfigInfo
> >>> + * \brief Information to be passed from IPU3 pipeline-handler to IPA
> >>> + *
> >>> + * The IPAConfigInfo structure stores the data passed from IPU3
> >>> pipeline-handler
> >>> + * to the IPAIPU3Interface::configure(). The structure provides
> >>> extensibility
> >>> + * for additional configuration data as required, for closed-source or
> >>> + * open-source IPAs' configure() phases.
> >>> + */
> >>> +
> >>> +/**
> >>> + * \var IPAConfigInfo::sensorInfo
> >>> + * \brief Camera sensor information
> >>> + *
> >>> + * Provides the camera sensor information such as model name,
> >>> pixel-rate,
> >>> + * output-size and so on. Refer to libcamera::CameraSensorInfo for
> >>> further
> >>> + * details.
> >>> + */
> >>> +
> >>> + /**
> >>> + * \var IPAConfigInfo::entityControls
> >>> + * \brief Controls supported by the sensor
> >>> + *
> >>> + * A map of V4L2 controls supported by the sensor in order to read
> >>> or write
> >>> + * control values to them.
> >>> + */
> >>> +
> >>> + /**
> >>> + * \var IPAConfigInfo::bdsOutputSize
> >>> + * \brief Size of ImgU BDS rectangle
> >>> + */
> >>> +
> >>> + /**
> >>> + * \var IPAConfigInfo::iif
> >>> + * \brief Size of ImgU input-feeder rectangle
> >>> + */
> >>> +struct IPAConfigInfo {
> >>> +    libcamera.CameraSensorInfo sensorInfo;
> >>> +    map<uint32, ControlInfoMap> entityControls;
> >>> +    libcamera.Size bdsOutputSize;
> >>> +    libcamera.Size iif;
> >>> +};
> >>> +
> >> I think it is interesting, and would like your advice: I would need this
> >> same structure for rkisp1 platform, except that the sizes are obviously
> >> not the same.
> >> And so, I am wondering if we could imagine a more general structure like:
> >> struct IPAConfigInfo {
> >>     libcamera.CameraSensorInfo sensorInfo;
> >>     map<uint32, ControlInfoMap> entityControls;
> >>     libcamera.Size ispInputSize;
> >>     libcamera.Size ispOutputSize;
> >> };
> >>
> >> names and all may have to be reworked but that is the base idea.
> >> There is no bds in rkisp1 (afaik) but on both IPU3 and RkIsp1 at least
> >> you have an input an output pad size for the ISP node.
> > Certainly, this might be a good idea. I am not opposed to it.
> > 
> > The question here is, that is the structure core.mojom worthy, in order
> > to be shared between multiple IPAs right? If not, I think we need to
> > keep them in <platform IPA>.mojom for now.
> > 
> > And if we want to share the data-structures, we need to work out how all
> > existing IPAs (for e.g. Raspberry Pi) can be ported to used that
> > IPAConfig structure too. We probably, should address this by looking at
> > all the common parameters we need for all the existing IPAs and have a
> > patch series that ports every IPA to use that data-structure.
> > 
> > However, there are some risky? situations that can happen, for e.g.
> >  - An IPA X requiring a parameter Y for configuration and the common
> > struct IPAConfig doesn't have a placeholder
> >  - Parameter Y is added to common struct IPAConfig
> >  - Parameter Y is unused/nullptr for all IPAs except IPA X
> > 
> > I do not know if adding placeholder for Y is fine in the common struct,
> > if fine or not, in the codebase purview.
> > 
> > Thinking about it, the chances of various IPA, having exact
> > configuration data (common IPAConfig) are slim. Hence, the IPA authors
> > will try hacks for other parameters they need for IPA configuration,
> > either as function-params or introducing new structures and passing
> > alongside with common struct IPAConfig to the IPA. That would not be
> > nice, isn't it?
> > 
> > I might be wrong, so I shall keep an open mind about it. Maybe we can
> > track this as a task somewhere too?
> > 
> 
> The idea I had is to have a common structure, and having the IPA
> specific ones inherit from this common one.
> You would have something like
> IPAIPU3ConfigInfo: IPAConfigInfo {
> 	/* myGreatParameters */
> }
> 
> That one may not make sense though :-).

IPA parameters are very platform-specific, I don't think this would
bring much benefit.

> >>>   interface IPAIPU3Interface {
> >>>       init(libcamera.IPASettings settings) => (int32 ret);
> >>>       start() => (int32 ret);
> >>>       stop();
> >>>   -    configure(map<uint32, libcamera.ControlInfoMap> entityControls,
> >>> -          libcamera.Size bdsOutputSize) => ();
> >>> +    configure(IPAConfigInfo configInfo);
> >>>         mapBuffers(array<libcamera.IPABuffer> buffers);
> >>>       unmapBuffers(array<uint32> ids);
> >>> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> >>> index f5343547..769c24d3 100644
> >>> --- a/src/ipa/ipu3/ipu3.cpp
> >>> +++ b/src/ipa/ipu3/ipu3.cpp
> >>> @@ -43,8 +43,7 @@ public:
> >>>       int start() override;
> >>>       void stop() override {}
> >>>   -    void configure(const std::map<uint32_t, ControlInfoMap>
> >>> &entityControls,
> >>> -               const Size &bdsOutputSize) override;
> >>> +    void configure(const IPAConfigInfo &configInfo) override;
> >>>         void mapBuffers(const std::vector<IPABuffer> &buffers) override;
> >>>       void unmapBuffers(const std::vector<unsigned int> &ids) override;
> >>> @@ -139,13 +138,12 @@ void IPAIPU3::calculateBdsGrid(const Size
> >>> &bdsOutputSize)
> >>>                   << (int)bdsGrid_.height << " << " <<
> >>> (int)bdsGrid_.block_height_log2 << ")";
> >>>   }
> >>>   -void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap>
> >>> &entityControls,
> >>> -            const Size &bdsOutputSize)
> >>> +void IPAIPU3::configure(const IPAConfigInfo &configInfo)
> >>>   {
> >>> -    if (entityControls.empty())
> >>> +    if (configInfo.entityControls.empty())
> >>>           return;
> >>>   -    ctrls_ = entityControls.at(0);
> >>> +    ctrls_ = configInfo.entityControls.at(0);
> >>>         const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
> >>>       if (itExp == ctrls_.end()) {
> >>> @@ -169,10 +167,10 @@ void IPAIPU3::configure(const
> >>> std::map<uint32_t, ControlInfoMap> &entityControls
> >>>         params_ = {};
> >>>   -    calculateBdsGrid(bdsOutputSize);
> >>> +    calculateBdsGrid(configInfo.bdsOutputSize);
> >>>         awbAlgo_ = std::make_unique<IPU3Awb>();
> >>> -    awbAlgo_->initialise(params_, bdsOutputSize, bdsGrid_);
> >>> +    awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
> >>>         agcAlgo_ = std::make_unique<IPU3Agc>();
> >>>       agcAlgo_->initialise(bdsGrid_);
> >>> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp
> >>> b/src/libcamera/pipeline/ipu3/ipu3.cpp
> >>> index 73306cea..b1ff1dbe 100644
> >>> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> >>> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> >>> @@ -635,7 +635,14 @@ int PipelineHandlerIPU3::configure(Camera
> >>> *camera, CameraConfiguration *c)
> >>>         std::map<uint32_t, ControlInfoMap> entityControls;
> >>>       entityControls.emplace(0, data->cio2_.sensor()->controls());
> >>> -    data->ipa_->configure(entityControls, config->imguConfig().bds);
> >>> +
> >>> +    ipa::ipu3::IPAConfigInfo configInfo;
> >>> +    configInfo.sensorInfo = sensorInfo;
> >>> +    configInfo.entityControls = entityControls;
> >>> +    configInfo.bdsOutputSize = config->imguConfig().bds;
> >>> +    configInfo.iif = config->imguConfig().iif;
> >>> +
> >>> +    data->ipa_->configure(configInfo);
> >>>         return 0;
> >>>   }
> >>>
Paul Elder April 30, 2021, 3:22 a.m. UTC | #8
Hello Umang and Jean-Michel,

On Thu, Apr 29, 2021 at 07:30:47AM +0200, Jean-Michel Hautbois wrote:
> 
> 
> On 27/04/2021 14:54, Umang Jain wrote:
> > Hi JM
> > 
> > On 4/27/21 5:23 PM, Jean-Michel Hautbois wrote:
> >> Hi Umang,
> >>
> >> Thanks for the patch !
> >>
> >> On 27/04/2021 08:35, Umang Jain wrote:
> >>> IPAConfigInfo is a consolidated data structure passed from IPU3
> >>> pipeline-handler to IPU3 IPA. This provides a streamlined and
> >>> extensible way to provide the configuration data to IPA interface.
> >>>
> >>> The IPA interface should be common to both closed-source and
> >>> open-source IPU3 IPAs. Hence, the structure encompasses additional
> >>> configuration information required to init and configure the
> >>> closed-source IPA as well.
> >>>
> >>> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
> >>> ---
> >>> Changes in v2:
> >>> - Mark as RFC(do not merge) as this is built upon Paul's
> >>>    [Fix support for core.mojom structs v3] - waiting for merge to master

This has been merged already.

> >>> - Drop cropRegion_  from structure - this is provided from
> >>> CameraSensorInfo
> >>>    itself.
> >>> - Doxygen documentation of IPAConfigInfo.
> >>> ---
> >>>   include/libcamera/ipa/ipu3.mojom     | 46 ++++++++++++++++++++++++++--
> >>>   src/ipa/ipu3/ipu3.cpp                | 14 ++++-----
> >>>   src/libcamera/pipeline/ipu3/ipu3.cpp |  9 +++++-
> >>>   3 files changed, 58 insertions(+), 11 deletions(-)
> >>>
> >>> diff --git a/include/libcamera/ipa/ipu3.mojom
> >>> b/include/libcamera/ipa/ipu3.mojom
> >>> index a717b1e6..acd5cfa4 100644
> >>> --- a/include/libcamera/ipa/ipu3.mojom
> >>> +++ b/include/libcamera/ipa/ipu3.mojom
> >>> @@ -25,13 +25,55 @@ struct IPU3Action {
> >>>       libcamera.ControlList controls;
> >>>   };
> >>>   +/**
> >>> + * \struct IPAConfigInfo
> >>> + * \brief Information to be passed from IPU3 pipeline-handler to IPA
> >>> + *
> >>> + * The IPAConfigInfo structure stores the data passed from IPU3
> >>> pipeline-handler
> >>> + * to the IPAIPU3Interface::configure(). The structure provides
> >>> extensibility
> >>> + * for additional configuration data as required, for closed-source or
> >>> + * open-source IPAs' configure() phases.
> >>> + */
> >>> +
> >>> +/**
> >>> + * \var IPAConfigInfo::sensorInfo
> >>> + * \brief Camera sensor information
> >>> + *
> >>> + * Provides the camera sensor information such as model name,
> >>> pixel-rate,
> >>> + * output-size and so on. Refer to libcamera::CameraSensorInfo for
> >>> further
> >>> + * details.
> >>> + */
> >>> +
> >>> + /**
> >>> + * \var IPAConfigInfo::entityControls
> >>> + * \brief Controls supported by the sensor
> >>> + *
> >>> + * A map of V4L2 controls supported by the sensor in order to read
> >>> or write
> >>> + * control values to them.
> >>> + */
> >>> +
> >>> + /**
> >>> + * \var IPAConfigInfo::bdsOutputSize
> >>> + * \brief Size of ImgU BDS rectangle
> >>> + */
> >>> +
> >>> + /**
> >>> + * \var IPAConfigInfo::iif
> >>> + * \brief Size of ImgU input-feeder rectangle
> >>> + */
> >>> +struct IPAConfigInfo {
> >>> +    libcamera.CameraSensorInfo sensorInfo;
> >>> +    map<uint32, ControlInfoMap> entityControls;
> >>> +    libcamera.Size bdsOutputSize;
> >>> +    libcamera.Size iif;
> >>> +};
> >>> +
> >> I think it is interesting, and would like your advice: I would need this
> >> same structure for rkisp1 platform, except that the sizes are obviously
> >> not the same.
> >> And so, I am wondering if we could imagine a more general structure like:
> >> struct IPAConfigInfo {
> >>     libcamera.CameraSensorInfo sensorInfo;
> >>     map<uint32, ControlInfoMap> entityControls;
> >>     libcamera.Size ispInputSize;
> >>     libcamera.Size ispOutputSize;
> >> };
> >>
> >> names and all may have to be reworked but that is the base idea.
> >> There is no bds in rkisp1 (afaik) but on both IPU3 and RkIsp1 at least
> >> you have an input an output pad size for the ISP node.
> > Certainly, this might be a good idea. I am not opposed to it.
> > 
> > The question here is, that is the structure core.mojom worthy, in order
> > to be shared between multiple IPAs right? If not, I think we need to
> > keep them in <platform IPA>.mojom for now.
> > 
> > And if we want to share the data-structures, we need to work out how all
> > existing IPAs (for e.g. Raspberry Pi) can be ported to used that
> > IPAConfig structure too. We probably, should address this by looking at
> > all the common parameters we need for all the existing IPAs and have a
> > patch series that ports every IPA to use that data-structure.
> > 
> > However, there are some risky? situations that can happen, for e.g.
> >  - An IPA X requiring a parameter Y for configuration and the common
> > struct IPAConfig doesn't have a placeholder
> >  - Parameter Y is added to common struct IPAConfig
> >  - Parameter Y is unused/nullptr for all IPAs except IPA X
> > 
> > I do not know if adding placeholder for Y is fine in the common struct,
> > if fine or not, in the codebase purview.
> > 
> > Thinking about it, the chances of various IPA, having exact
> > configuration data (common IPAConfig) are slim. Hence, the IPA authors
> > will try hacks for other parameters they need for IPA configuration,
> > either as function-params or introducing new structures and passing
> > alongside with common struct IPAConfig to the IPA. That would not be
> > nice, isn't it?

We could have a greatest common divisor for the IPA config info struct
in core.mojom, and then the IPAs could define their own additional
struct.

> > 
> > I might be wrong, so I shall keep an open mind about it. Maybe we can
> > track this as a task somewhere too?
> > 
> 
> The idea I had is to have a common structure, and having the IPA
> specific ones inherit from this common one.
> You would have something like
> IPAIPU3ConfigInfo: IPAConfigInfo {
> 	/* myGreatParameters */
> }

Because mojo doesn't support inheritance :/

Well okay, if you *really* wanted to, in theory, we could use an attribute
to declare inheritance, and then I'd have to expand the code generator
for that (just keeping doors and minds open).


Paul

> 
> That one may not make sense though :-).
> 
> >>
> >>>   interface IPAIPU3Interface {
> >>>       init(libcamera.IPASettings settings) => (int32 ret);
> >>>       start() => (int32 ret);
> >>>       stop();
> >>>   -    configure(map<uint32, libcamera.ControlInfoMap> entityControls,
> >>> -          libcamera.Size bdsOutputSize) => ();
> >>> +    configure(IPAConfigInfo configInfo);
> >>>         mapBuffers(array<libcamera.IPABuffer> buffers);
> >>>       unmapBuffers(array<uint32> ids);
> >>> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> >>> index f5343547..769c24d3 100644
> >>> --- a/src/ipa/ipu3/ipu3.cpp
> >>> +++ b/src/ipa/ipu3/ipu3.cpp
> >>> @@ -43,8 +43,7 @@ public:
> >>>       int start() override;
> >>>       void stop() override {}
> >>>   -    void configure(const std::map<uint32_t, ControlInfoMap>
> >>> &entityControls,
> >>> -               const Size &bdsOutputSize) override;
> >>> +    void configure(const IPAConfigInfo &configInfo) override;
> >>>         void mapBuffers(const std::vector<IPABuffer> &buffers) override;
> >>>       void unmapBuffers(const std::vector<unsigned int> &ids) override;
> >>> @@ -139,13 +138,12 @@ void IPAIPU3::calculateBdsGrid(const Size
> >>> &bdsOutputSize)
> >>>                   << (int)bdsGrid_.height << " << " <<
> >>> (int)bdsGrid_.block_height_log2 << ")";
> >>>   }
> >>>   -void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap>
> >>> &entityControls,
> >>> -            const Size &bdsOutputSize)
> >>> +void IPAIPU3::configure(const IPAConfigInfo &configInfo)
> >>>   {
> >>> -    if (entityControls.empty())
> >>> +    if (configInfo.entityControls.empty())
> >>>           return;
> >>>   -    ctrls_ = entityControls.at(0);
> >>> +    ctrls_ = configInfo.entityControls.at(0);
> >>>         const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
> >>>       if (itExp == ctrls_.end()) {
> >>> @@ -169,10 +167,10 @@ void IPAIPU3::configure(const
> >>> std::map<uint32_t, ControlInfoMap> &entityControls
> >>>         params_ = {};
> >>>   -    calculateBdsGrid(bdsOutputSize);
> >>> +    calculateBdsGrid(configInfo.bdsOutputSize);
> >>>         awbAlgo_ = std::make_unique<IPU3Awb>();
> >>> -    awbAlgo_->initialise(params_, bdsOutputSize, bdsGrid_);
> >>> +    awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
> >>>         agcAlgo_ = std::make_unique<IPU3Agc>();
> >>>       agcAlgo_->initialise(bdsGrid_);
> >>> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp
> >>> b/src/libcamera/pipeline/ipu3/ipu3.cpp
> >>> index 73306cea..b1ff1dbe 100644
> >>> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> >>> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> >>> @@ -635,7 +635,14 @@ int PipelineHandlerIPU3::configure(Camera
> >>> *camera, CameraConfiguration *c)
> >>>         std::map<uint32_t, ControlInfoMap> entityControls;
> >>>       entityControls.emplace(0, data->cio2_.sensor()->controls());
> >>> -    data->ipa_->configure(entityControls, config->imguConfig().bds);
> >>> +
> >>> +    ipa::ipu3::IPAConfigInfo configInfo;
> >>> +    configInfo.sensorInfo = sensorInfo;
> >>> +    configInfo.entityControls = entityControls;
> >>> +    configInfo.bdsOutputSize = config->imguConfig().bds;
> >>> +    configInfo.iif = config->imguConfig().iif;
> >>> +
> >>> +    data->ipa_->configure(configInfo);
> >>>         return 0;
> >>>   }
> >>>
> > 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch
diff mbox series

diff --git a/include/libcamera/ipa/ipu3.mojom b/include/libcamera/ipa/ipu3.mojom
index a717b1e6..acd5cfa4 100644
--- a/include/libcamera/ipa/ipu3.mojom
+++ b/include/libcamera/ipa/ipu3.mojom
@@ -25,13 +25,55 @@  struct IPU3Action {
 	libcamera.ControlList controls;
 };
 
+/**
+ * \struct IPAConfigInfo
+ * \brief Information to be passed from IPU3 pipeline-handler to IPA
+ *
+ * The IPAConfigInfo structure stores the data passed from IPU3 pipeline-handler
+ * to the IPAIPU3Interface::configure(). The structure provides extensibility
+ * for additional configuration data as required, for closed-source or
+ * open-source IPAs' configure() phases.
+ */
+
+/**
+ * \var IPAConfigInfo::sensorInfo
+ * \brief Camera sensor information
+ *
+ * Provides the camera sensor information such as model name, pixel-rate,
+ * output-size and so on. Refer to libcamera::CameraSensorInfo for further
+ * details.
+ */
+
+ /**
+ * \var IPAConfigInfo::entityControls
+ * \brief Controls supported by the sensor
+ *
+ * A map of V4L2 controls supported by the sensor in order to read or write
+ * control values to them.
+ */
+
+ /**
+ * \var IPAConfigInfo::bdsOutputSize
+ * \brief Size of ImgU BDS rectangle
+ */
+
+ /**
+ * \var IPAConfigInfo::iif
+ * \brief Size of ImgU input-feeder rectangle
+ */
+struct IPAConfigInfo {
+	libcamera.CameraSensorInfo sensorInfo;
+	map<uint32, ControlInfoMap> entityControls;
+	libcamera.Size bdsOutputSize;
+	libcamera.Size iif;
+};
+
 interface IPAIPU3Interface {
 	init(libcamera.IPASettings settings) => (int32 ret);
 	start() => (int32 ret);
 	stop();
 
-	configure(map<uint32, libcamera.ControlInfoMap> entityControls,
-		  libcamera.Size bdsOutputSize) => ();
+	configure(IPAConfigInfo configInfo);
 
 	mapBuffers(array<libcamera.IPABuffer> buffers);
 	unmapBuffers(array<uint32> ids);
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index f5343547..769c24d3 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -43,8 +43,7 @@  public:
 	int start() override;
 	void stop() override {}
 
-	void configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
-		       const Size &bdsOutputSize) override;
+	void configure(const IPAConfigInfo &configInfo) override;
 
 	void mapBuffers(const std::vector<IPABuffer> &buffers) override;
 	void unmapBuffers(const std::vector<unsigned int> &ids) override;
@@ -139,13 +138,12 @@  void IPAIPU3::calculateBdsGrid(const Size &bdsOutputSize)
 			    << (int)bdsGrid_.height << " << " << (int)bdsGrid_.block_height_log2 << ")";
 }
 
-void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls,
-			const Size &bdsOutputSize)
+void IPAIPU3::configure(const IPAConfigInfo &configInfo)
 {
-	if (entityControls.empty())
+	if (configInfo.entityControls.empty())
 		return;
 
-	ctrls_ = entityControls.at(0);
+	ctrls_ = configInfo.entityControls.at(0);
 
 	const auto itExp = ctrls_.find(V4L2_CID_EXPOSURE);
 	if (itExp == ctrls_.end()) {
@@ -169,10 +167,10 @@  void IPAIPU3::configure(const std::map<uint32_t, ControlInfoMap> &entityControls
 
 	params_ = {};
 
-	calculateBdsGrid(bdsOutputSize);
+	calculateBdsGrid(configInfo.bdsOutputSize);
 
 	awbAlgo_ = std::make_unique<IPU3Awb>();
-	awbAlgo_->initialise(params_, bdsOutputSize, bdsGrid_);
+	awbAlgo_->initialise(params_, configInfo.bdsOutputSize, bdsGrid_);
 
 	agcAlgo_ = std::make_unique<IPU3Agc>();
 	agcAlgo_->initialise(bdsGrid_);
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 73306cea..b1ff1dbe 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -635,7 +635,14 @@  int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
 
 	std::map<uint32_t, ControlInfoMap> entityControls;
 	entityControls.emplace(0, data->cio2_.sensor()->controls());
-	data->ipa_->configure(entityControls, config->imguConfig().bds);
+
+	ipa::ipu3::IPAConfigInfo configInfo;
+	configInfo.sensorInfo = sensorInfo;
+	configInfo.entityControls = entityControls;
+	configInfo.bdsOutputSize = config->imguConfig().bds;
+	configInfo.iif = config->imguConfig().iif;
+
+	data->ipa_->configure(configInfo);
 
 	return 0;
 }