[libcamera-devel] [PATCH] libcamera: pipeline: rkisp1: configure IPA from configure method instead of start method

Laurent Pinchart laurent.pinchart at ideasonboard.com
Mon Feb 15 04:59:31 CET 2021


Hi Sebastian,

On Sat, Feb 13, 2021 at 10:12:17AM +0100, Sebastian Fricke wrote:
> On 12.02.2021 20:05, Dafna Hirschfeld wrote:
> > Currently the call to the configure method of rkisp1 IPA
> > is called upon the 'start' of the pipeline. This should be done
> > in the 'configure' method instead.
> 
> I assume that the reason for this change is consistency right? I believe
> the raspberry Pi has the most mature pipeline and IPA implementation and
> it makes sense to have some kind of consistent pattern.
> 
> In order to find out why it is necessary to configure the IPA in
> configure instead of start, I first looked into `src/cam/capture.cpp`,
> where both methods are called. In between the configure and the start
> call, the buffers are allocated and the initial set of requests is
> created.
> Additionally, I have compared both the RkISP1 and Raspberry Pi
> implementation of the IPA configure method. Currently, the RkISP1 IPA
> doesn't do a lot so it is difficult to decide, which parts might be added.
> The Raspberry Pi currently does the following actions that are missing in
> the RkISP1:
> - Setup and validate the ISP controls
> - Setup metadata controls
> - Load device specific information from a helper
> - Load the lens shading table
> - Prepare the algorithms by setting the camera mode
> - Load the tuning file for the sensor
> 
> What they both do is initialize the analog gain and exposure controls.
> (With the difference that RkISP1 sets both to their respective minimum
> and Raspberry Pi provides default values).
> 
> This means, that the different order of the IPA configure method can
> only have an impact on the actions happening in between the two states
> configured and start (allocation of buffers and creation of the inital
> requests). So, the current advantage/disadvantage is that the controls
> are reset to their minimum for the initial set of requests as well.

Nice and detailed analysis :-)

>  From my point of view this seems to be a good preparation for the
> following changes to the RkISP1 IPA, even though it currently doesn't
> seem to do to much. Have I missed anything else that makes this order of
> actions essential?

Right now, no, but with Paul's series that implements the IPA IPC
protocol, IPA functions called after start() must be asynchronous. The
IPA configure() function is a synchronous call, so this won't work well.
This patch is in preparation for the IPA IPC (beside improving
consistency, which is usually good).

> Besides that little analysis I have tested the patch by building it and
> performing a test capture. Both works without problems.
> 
> Greetings,
> Sebastian
> 
> I fixed a small typo below that existed before as well.
> 
> > Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
> > ---
> >  src/libcamera/pipeline/rkisp1/rkisp1.cpp | 63 ++++++++++++------------
> >  1 file changed, 31 insertions(+), 32 deletions(-)
> > 
> > diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > index e85979a7..f15efa9f 100644
> > --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
> > @@ -607,11 +607,24 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
> >  		<< "ISP output pad configured with " << format.toString()
> >  		<< " crop " << rect.toString();
> > 
> > +	std::map<unsigned int, IPAStream> streamConfig;
> > +
> >  	for (const StreamConfiguration &cfg : *config) {
> > -		if (cfg.stream() == &data->mainPathStream_)
> > +		if (cfg.stream() == &data->mainPathStream_) {
> >  			ret = mainPath_.configure(cfg, format);
> > -		else
> > +			if (data->mainPath_->isEnabled())
> > +				streamConfig[0] = {
> > +					.pixelFormat = cfg.pixelFormat,
> > +					.size = cfg.size,
> > +				};
> > +		} else {
> >  			ret = selfPath_.configure(cfg, format);
> > +			if (data->selfPath_->isEnabled())
> > +				streamConfig[1] = {
> > +					.pixelFormat = cfg.pixelFormat,
> > +					.size = cfg.size,
> > +				};
> > +		}
> > 
> >  		if (ret)
> >  			return ret;
> > @@ -629,6 +642,22 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
> >  	if (ret)
> >  		return ret;
> > 
> > +	/* Inform IPA of stream configuration and sensor controls. */
> > +	CameraSensorInfo sensorInfo = {};
> > +	ret = data->sensor_->sensorInfo(&sensorInfo);
> > +	if (ret) {
> > +		/* \todo Turn this in an hard failure. */
> 
> s/Turn this in an hard failure./Turn this into a hard failure./
> (or maybe: Make this a hard failure)
> 
> > +		LOG(RkISP1, Warning) << "Camera sensor information not available";
> > +		sensorInfo = {};
> > +		ret = 0;
> > +	}
> > +
> > +	std::map<unsigned int, const ControlInfoMap &> entityControls;
> > +	entityControls.emplace(0, data->sensor_->controls());
> > +
> > +	IPAOperationData ipaConfig;
> > +	data->ipa_->configure(sensorInfo, streamConfig, entityControls, ipaConfig, nullptr);
> > +
> >  	return 0;
> >  }
> > 
> > @@ -759,8 +788,6 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] ControlList *c
> >  		return ret;
> >  	}
> > 
> > -	std::map<unsigned int, IPAStream> streamConfig;
> > -
> >  	if (data->mainPath_->isEnabled()) {
> >  		ret = mainPath_.start();
> >  		if (ret) {
> > @@ -770,11 +797,6 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] ControlList *c
> >  			freeBuffers(camera);
> >  			return ret;
> >  		}
> > -
> > -		streamConfig[0] = {
> > -			.pixelFormat = data->mainPathStream_.configuration().pixelFormat,
> > -			.size = data->mainPathStream_.configuration().size,
> > -		};
> >  	}
> > 
> >  	if (data->selfPath_->isEnabled()) {
> > @@ -787,34 +809,11 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] ControlList *c
> >  			freeBuffers(camera);
> >  			return ret;
> >  		}
> > -
> > -		streamConfig[1] = {
> > -			.pixelFormat = data->selfPathStream_.configuration().pixelFormat,
> > -			.size = data->selfPathStream_.configuration().size,
> > -		};
> >  	}
> > 
> >  	isp_->setFrameStartEnabled(true);
> > 
> >  	activeCamera_ = camera;
> > -
> > -	/* Inform IPA of stream configuration and sensor controls. */
> > -	CameraSensorInfo sensorInfo = {};
> > -	ret = data->sensor_->sensorInfo(&sensorInfo);
> > -	if (ret) {
> > -		/* \todo Turn this in an hard failure. */
> > -		LOG(RkISP1, Warning) << "Camera sensor information not available";
> > -		sensorInfo = {};
> > -		ret = 0;
> > -	}
> > -
> > -	std::map<unsigned int, const ControlInfoMap &> entityControls;
> > -	entityControls.emplace(0, data->sensor_->controls());
> > -
> > -	IPAOperationData ipaConfig;
> > -	data->ipa_->configure(sensorInfo, streamConfig, entityControls,
> > -			      ipaConfig, nullptr);
> > -
> >  	return ret;
> >  }
> > 

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list