[libcamera-devel] [PATCH v3 3/9] ipu3: Use imgu0 as default

Umang Jain umang.jain at ideasonboard.com
Tue Jul 26 19:36:18 CEST 2022


Hi,

On 6/29/22 16:00, Harvey Yang via libcamera-devel wrote:
> From: Harvey Yang<chenghaoyang at chromium.org>
>
> With only one camera being started, we can always use imgu0 to process
> frames (for video/preview). In the following patches, we'll use imgu1
> for still capture if needed.
>
> Signed-off-by: Harvey Yang<chenghaoyang at chromium.org>
> ---
>   src/libcamera/pipeline/ipu3/ipu3.cpp | 86 ++++++++++++++++------------
>   1 file changed, 48 insertions(+), 38 deletions(-)
>
> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
> index c943ee6a..e219f704 100644
> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp
> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
> @@ -64,7 +64,8 @@ public:
>   	void frameStart(uint32_t sequence);
>   
>   	CIO2Device cio2_;
> -	ImgUDevice *imgu_;
> +	ImgUDevice *imgu0_;
> +	ImgUDevice *imgu1_;

You might also be interested to at 
PipelineHandlerIPU3::registerCameras() which allows registering two 
cameras for IPU3, assigning the 2 exposed IMGUs to each camera.

|/** * \todo Dynamically assign ImgU and output devices to each * stream 
and camera; as of now, limit support to two cameras * only, and assign 
imgu0 to the first one and imgu1 to the * second. */ data->imgu_ = 
numCameras ? &imgu1_ : &imgu0_; |||

This should be addressed as well, I think.

Rest bits of the patch, looks on the right track to me.

>   
>   	Stream outStream_;
>   	Stream vfStream_;
> @@ -406,7 +407,7 @@CameraConfiguration::Status  IPU3CameraConfiguration::validate()
>   
>   	/* Only compute the ImgU configuration if a YUV stream has been requested. */
>   	if (yuvCount) {
> -		pipeConfig_ = data_->imgu_->calculatePipeConfig(&pipe);
> +		pipeConfig_ = data_->imgu0_->calculatePipeConfig(&pipe);
>   		if (pipeConfig_.isNull()) {
>   			LOG(IPU3, Error) << "Failed to calculate pipe configuration: "
>   					 << "unsupported resolutions.";
> @@ -518,7 +519,6 @@ intPipelineHandlerIPU3::configure(Camera  *camera, CameraConfiguration *c)
>   	Stream *outStream = &data->outStream_;
>   	Stream *vfStream = &data->vfStream_;
>   	CIO2Device *cio2 = &data->cio2_;
> -	ImgUDevice *imgu = data->imgu_;
>   	V4L2DeviceFormat outputFormat;
>   	int ret;
>   
> @@ -560,7 +560,7 @@ intPipelineHandlerIPU3::configure(Camera  *camera, CameraConfiguration *c)
>   	 * stream which is for raw capture, in which case no buffers will
>   	 * ever be queued to the ImgU.
>   	 */
> -	ret = data->imgu_->enableLinks(true);
> +	ret = imgu0_.enableLinks(true);
>   	if (ret)
>   		return ret;
>   
> @@ -610,7 +610,7 @@ intPipelineHandlerIPU3::configure(Camera  *camera, CameraConfiguration *c)
>   	if (imguConfig.isNull())
>   		return 0;
>   
> -	ret = imgu->configure(imguConfig, &cio2Format);
> +	ret = imgu0_.configure(imguConfig, &cio2Format);
>   	if (ret)
>   		return ret;
>   
> @@ -624,12 +624,12 @@ intPipelineHandlerIPU3::configure(Camera  *camera, CameraConfiguration *c)
>   
>   		if (stream == outStream) {
>   			mainCfg = &cfg;
> -			ret = imgu->configureOutput(cfg, &outputFormat);
> +			ret = imgu0_.configureOutput(cfg, &outputFormat);
>   			if (ret)
>   				return ret;
>   		} else if (stream == vfStream) {
>   			vfCfg = &cfg;
> -			ret = imgu->configureViewfinder(cfg, &outputFormat);
> +			ret = imgu0_.configureViewfinder(cfg, &outputFormat);
>   			if (ret)
>   				return ret;
>   		}
> @@ -641,13 +641,13 @@ intPipelineHandlerIPU3::configure(Camera  *camera, CameraConfiguration *c)
>   	 * be at least one active stream in the configuration request).
>   	 */
>   	if (!vfCfg) {
> -		ret = imgu->configureViewfinder(*mainCfg, &outputFormat);
> +		ret = imgu0_.configureViewfinder(*mainCfg, &outputFormat);
>   		if (ret)
>   			return ret;
>   	}
>   
>   	/* Apply the "pipe_mode" control to the ImgU subdevice. */
> -	ControlList ctrls(imgu->imgu_->controls());
> +	ControlList ctrls(imgu0_.imgu_->controls());
>   	/*
>   	 * Set the ImgU pipe mode to 'Video' unconditionally to have statistics
>   	 * generated.
> @@ -657,7 +657,7 @@ intPipelineHandlerIPU3::configure(Camera  *camera, CameraConfiguration *c)
>   	 */
>   	ctrls.set(V4L2_CID_IPU3_PIPE_MODE,
>   		  static_cast<int32_t>(IPU3PipeModeVideo));
> -	ret = imgu->imgu_->setControls(&ctrls);
> +	ret = imgu0_.imgu_->setControls(&ctrls);
>   	if (ret) {
>   		LOG(IPU3, Error) << "Unable to set pipe_mode control";
>   		return ret;
> @@ -691,9 +691,9 @@ intPipelineHandlerIPU3::exportFrameBuffers(Camera  *camera, Stream *stream,
>   	unsigned int count = stream->configuration().bufferCount;
>   
>   	if (stream == &data->outStream_)
> -		return data->imgu_->output_->exportBuffers(count, buffers);
> +		return imgu0_.output_->exportBuffers(count, buffers);
>   	else if (stream == &data->vfStream_)
> -		return data->imgu_->viewfinder_->exportBuffers(count, buffers);
> +		return imgu0_.viewfinder_->exportBuffers(count, buffers);
>   	else if (stream == &data->rawStream_)
>   		return data->cio2_.exportBuffers(count, buffers);
>   
> @@ -711,7 +711,6 @@ intPipelineHandlerIPU3::exportFrameBuffers(Camera  *camera, Stream *stream,
>   intPipelineHandlerIPU3::allocateBuffers(Camera  *camera)
>   {
>   	IPU3CameraData *data = cameraData(camera);
> -	ImgUDevice *imgu = data->imgu_;
>   	unsigned int bufferCount;
>   	int ret;
>   
> @@ -721,26 +720,26 @@ intPipelineHandlerIPU3::allocateBuffers(Camera  *camera)
>   		data->rawStream_.configuration().bufferCount,
>   	});
>   
> -	ret = imgu->allocateBuffers(bufferCount);
> +	ret = imgu0_.allocateBuffers(bufferCount);
>   	if (ret < 0)
>   		return ret;
>   
>   	/* Map buffers to the IPA. */
>   	unsigned int ipaBufferId = 1;
>   
> -	for (conststd::unique_ptr<FrameBuffer> &buffer : imgu->paramBuffers_) {
> +	for (conststd::unique_ptr<FrameBuffer> &buffer : imgu0_.paramBuffers_) {
>   		buffer->setCookie(ipaBufferId++);
>   		ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes());
>   	}
>   
> -	for (conststd::unique_ptr<FrameBuffer> &buffer : imgu->statBuffers_) {
> +	for (conststd::unique_ptr<FrameBuffer> &buffer : imgu0_.statBuffers_) {
>   		buffer->setCookie(ipaBufferId++);
>   		ipaBuffers_.emplace_back(buffer->cookie(), buffer->planes());
>   	}
>   
>   	data->ipa_->mapBuffers(ipaBuffers_);
>   
> -	data->frameInfos_.init(imgu->paramBuffers_, imgu->statBuffers_);
> +	data->frameInfos_.init(imgu0_.paramBuffers_, imgu0_.statBuffers_);
>   	data->frameInfos_.bufferAvailable.connect(
>   		data, &IPU3CameraData::queuePendingRequests);
>   
> @@ -760,7 +759,7 @@ intPipelineHandlerIPU3::freeBuffers(Camera  *camera)
>   	data->ipa_->unmapBuffers(ids);
>   	ipaBuffers_.clear();
>   
> -	data->imgu_->freeBuffers();
> +	imgu0_.freeBuffers();
>   
>   	return 0;
>   }
> @@ -777,9 +776,18 @@ intPipelineHandlerIPU3::start(Camera  *camera, [[maybe_unused]] const ControlLis
>   
>   	IPU3CameraData *data = cameraData(camera);
>   	CIO2Device *cio2 = &data->cio2_;
> -	ImgUDevice *imgu = data->imgu_;
>   	int ret;
>   
> +	imgu0_.input_->bufferReady.connect(&data->cio2_,
> +					   &CIO2Device::tryReturnBuffer);
> +	imgu0_.output_->bufferReady.connect(data,
> +					    &IPU3CameraData::imguOutputBufferReady);
> +	imgu0_.viewfinder_->bufferReady.connect(data,
> +						&IPU3CameraData::imguOutputBufferReady);
> +	imgu0_.param_->bufferReady.connect(data,
> +					   &IPU3CameraData::paramBufferReady);
> +	imgu0_.stat_->bufferReady.connect(data,
> +					  &IPU3CameraData::statBufferReady);
>   	/* Disable test pattern mode on the sensor, if any. */
>   	ret = cio2->sensor()->setTestPatternMode(
>   		controls::draft::TestPatternModeEnum::TestPatternModeOff);
> @@ -807,19 +815,24 @@ intPipelineHandlerIPU3::start(Camera  *camera, [[maybe_unused]] const ControlLis
>   	if (ret)
>   		goto error;
>   
> -	ret = imgu->start();
> +	ret = imgu0_.start();
>   	if (ret)
>   		goto error;
>   
>   	return 0;
>   
>   error:
> -	imgu->stop();
> +	imgu0_.stop();
>   	cio2->stop();
>   	data->ipa_->stop();
>   	freeBuffers(camera);
>   	LOG(IPU3, Error) << "Failed to start camera " << camera->id();
>   
> +	imgu0_.input_->bufferReady.disconnect();
> +	imgu0_.output_->bufferReady.disconnect();
> +	imgu0_.viewfinder_->bufferReady.disconnect();
> +	imgu0_.param_->bufferReady.disconnect();
> +	imgu0_.stat_->bufferReady.disconnect();
>   	inUseCamera_ = nullptr;
>   
>   	return ret;
> @@ -834,13 +847,19 @@ voidPipelineHandlerIPU3::stopDevice(Camera  *camera)
>   
>   	data->ipa_->stop();
>   
> -	ret |= data->imgu_->stop();
> +	ret |= imgu0_.stop();
>   	ret |= data->cio2_.stop();
>   	if (ret)
>   		LOG(IPU3, Warning) << "Failed to stop camera " << camera->id();
>   
>   	freeBuffers(camera);
>   
> +	data->imgu0_->input_->bufferReady.disconnect();
> +	data->imgu0_->output_->bufferReady.disconnect();
> +	data->imgu0_->viewfinder_->bufferReady.disconnect();
> +	data->imgu0_->param_->bufferReady.disconnect();
> +	data->imgu0_->stat_->bufferReady.disconnect();
> +
>   	inUseCamera_ = nullptr;
>   }
>   
> @@ -1184,7 +1203,8 @@ intPipelineHandlerIPU3::registerCameras()
>   		 * only, and assign imgu0 to the first one and imgu1 to the
>   		 * second.
>   		 */
> -		data->imgu_ = numCameras ? &imgu1_ : &imgu0_;
> +		data->imgu0_ = &imgu0_;
> +		data->imgu1_ = &imgu1_;
>   
>   		/*
>   		 * Connect video devices' 'bufferReady' signals to their
> @@ -1198,16 +1218,6 @@ intPipelineHandlerIPU3::registerCameras()
>   					&IPU3CameraData::cio2BufferReady);
>   		data->cio2_.bufferAvailable.connect(
>   			data.get(), &IPU3CameraData::queuePendingRequests);
> -		data->imgu_->input_->bufferReady.connect(&data->cio2_,
> -					&CIO2Device::tryReturnBuffer);
> -		data->imgu_->output_->bufferReady.connect(data.get(),
> -					&IPU3CameraData::imguOutputBufferReady);
> -		data->imgu_->viewfinder_->bufferReady.connect(data.get(),
> -					&IPU3CameraData::imguOutputBufferReady);
> -		data->imgu_->param_->bufferReady.connect(data.get(),
> -					&IPU3CameraData::paramBufferReady);
> -		data->imgu_->stat_->bufferReady.connect(data.get(),
> -					&IPU3CameraData::statBufferReady);
>   
>   		/* Create and register the Camera instance. */
>   		conststd::string  &cameraId = cio2->sensor()->id();
> @@ -1300,14 +1310,14 @@ voidIPU3CameraData::paramsBufferReady(unsigned  int id)
>   		FrameBuffer *outbuffer = it.second;
>   
>   		if (stream == &outStream_)
> -			imgu_->output_->queueBuffer(outbuffer);
> +			imgu0_->output_->queueBuffer(outbuffer);
>   		else if (stream == &vfStream_)
> -			imgu_->viewfinder_->queueBuffer(outbuffer);
> +			imgu0_->viewfinder_->queueBuffer(outbuffer);
>   	}
>   
> -	imgu_->param_->queueBuffer(info->paramBuffer);
> -	imgu_->stat_->queueBuffer(info->statBuffer);
> -	imgu_->input_->queueBuffer(info->rawBuffer);
> +	imgu0_->param_->queueBuffer(info->paramBuffer);
> +	imgu0_->stat_->queueBuffer(info->statBuffer);
> +	imgu0_->input_->queueBuffer(info->rawBuffer);
>   }
>   
>   voidIPU3CameraData::metadataReady(unsigned  int id, const ControlList &metadata)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20220726/a13b8e81/attachment.htm>


More information about the libcamera-devel mailing list