[libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register Exposure control

Laurent Pinchart laurent.pinchart at ideasonboard.com
Tue Jan 19 06:58:37 CET 2021


Hi Jacopo,

On Mon, Jan 18, 2021 at 01:27:32PM +0100, Jacopo Mondi wrote:
> On Mon, Jan 11, 2021 at 12:22:54AM +0200, Laurent Pinchart wrote:
> > Hi Jacopo,
> >
> > Thank you for the patch.
> >
> > > +	 */
> > > +	float pixelRate = sensorInfo.pixelRate / 1e6f;
> > > +	const ControlInfoMap &sensorControls = sensor->controls();
> > > +	const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;
> > > +	int32_t minExposure = v4l2Exposure.min().get<int32_t>()
> > > +			    * sensorInfo.lineLength / pixelRate;
> > > +	int32_t maxExposure = v4l2Exposure.max().get<int32_t>()
> > > +			    * sensorInfo.lineLength / pixelRate;
> > > +	int32_t defExposure = v4l2Exposure.def().get<int32_t>()
> > > +			    * sensorInfo.lineLength / pixelRate;
> >
> > For long exposure time this will overflow as the first two operands are
> > 32-bit integers. How about the following ?
> >
> > 	double lineDuration = sensorInfo.pixelRate / 1e6f /pixelRate;
> 
> did you mean:
>         sensorInfo.lineLength / (sensorInfo.pixelRate / 1e6f)
> or rather
>         sensorInfo.lineLength * 1e6f / sensorInfo.pixelRate

Yes, that's what I meant, sorry.

> but there's an overflow risk as well here.

In your code v4l2Exposure.min().get<int32_t>() is an int32_t, and
sensorInfo.lineLength is an uint32_t. Multiplying the two has a high
risk of overflow. Computing lineDuration as 

	double lineDuration = sensorInfo.lineLength * 1e6f
			    / sensorInfo.pixelRate;

won't overflow as multiplying by 1e6f first will produce a float value.

> > 	...
> > 	int32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;
> > 	int32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;
> > 	int32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;

Then these multiplications may overflow only if the result doesn't fit
in an int32_t, which would happen if the exposure time is larger than
~35 minutes. I think that's unlikely.

> > > +
> > > +	/*
> > > +	 * \todo Report the actual exposure time, use the default for the
> > > +	 * moment.
> > > +	 */
> > > +	data->exposureTime_ = defExposure;
> > > +
> > > +	controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,
> > > +							defExposure);
> > > +
> > > +	data->controlInfo_ = std::move(controls);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  /**
> > >   * \brief Initialise ImgU and CIO2 devices associated with cameras
> > >   *
> > > @@ -776,8 +833,9 @@ int PipelineHandlerIPU3::registerCameras()
> > >  		/* Initialize the camera properties. */
> > >  		data->properties_ = cio2->sensor()->properties();
> > >
> > > -		/* Initialze the camera controls. */
> > > -		data->controlInfo_ = IPU3Controls;
> > > +		ret = initControls(data.get());
> > > +		if (ret)
> > > +			continue;
> > >
> > >  		/**
> > >  		 * \todo Dynamically assign ImgU and output devices to each
> > > @@ -842,6 +900,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)
> > >
> > >  	/* Mark the request as complete. */
> > >  	request->metadata().set(controls::draft::PipelineDepth, 3);
> >
> > 	/* \todo Move the ExposureTime control to the IPA */
> >
> > Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> >
> > > +	request->metadata().set(controls::ExposureTime, exposureTime_);
> > >  	pipe_->completeRequest(request);
> > >  }

-- 
Regards,

Laurent Pinchart


More information about the libcamera-devel mailing list