[libcamera-devel] [PATCH v2 6/9] android: camera_device: Maintain a vector of CameraStream

Jacopo Mondi jacopo at jmondi.org
Fri Jul 3 12:47:40 CEST 2020


Hi Kieran

On Fri, Jul 03, 2020 at 11:36:56AM +0100, Kieran Bingham wrote:
> Hi Jacopo,
>
> On 03/07/2020 11:30, Jacopo Mondi wrote:
> > Hi Kieran
> >
> > On Fri, Jul 03, 2020 at 10:55:22AM +0100, Kieran Bingham wrote:
> >> Hi Jacopo,
> >>
> >> On 03/07/2020 10:35, Jacopo Mondi wrote:
> >>> Hi Kieran,
> >>>
> >>> On Thu, Jul 02, 2020 at 10:36:51PM +0100, Kieran Bingham wrote:
> >>>> Introduce a vector storing a CameraStream to track and maintain
> >>>> state between an Android stream (camera3_stream_t) and a libcamera
> >>>> Stream.
> >>>>
> >>>> Only the index of the libcamera stream is stored, to facilitate identifying
> >>>> the correct index for both the StreamConfiguration and Stream vectors.
> >>>>
> >>>> Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> >>>> ---
> >>>>  src/android/camera_device.cpp | 18 ++++++++++++++++--
> >>>>  src/android/camera_device.h   |  6 ++++++
> >>>>  2 files changed, 22 insertions(+), 2 deletions(-)
> >>>>
> >>>> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> >>>> index 77083219d8a1..fc3962dac230 100644
> >>>> --- a/src/android/camera_device.cpp
> >>>> +++ b/src/android/camera_device.cpp
> >>>> @@ -952,6 +952,14 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
> >>>>  		return -EINVAL;
> >>>>  	}
> >>>>
> >>>> +	streams_.reserve(stream_list->num_streams);
> >>>> +
> >>>> +	/*
> >>>> +	 * Track actually created streams, as there may not be a 1:1 mapping of
> >>>> +	 * camera3 streams to libcamera streams.
> >>>> +	 */
> >>>> +	unsigned int streamIndex = 0;
> >>>> +
> >>>
> >>> I would drop this one
> >>
> >> Drop the newline? Or something else?
> >>
> >
> > yeah, new line
>
>
> Can I disagree here? - I put that there intentionally to not 'hide' the
> streamIndex variable against the for loop, and not associate the comment
> added with it to the loop.
>
> The comment applies to the variable, not the loop.

Your code, your choice :D

>
>
> >
> >>>
> >>>>  	for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
> >>>>  		camera3_stream_t *stream = stream_list->streams[i];
> >>>>
> >>>> @@ -967,6 +975,9 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
> >>>>  		if (!format.isValid())
> >>>>  			return -EINVAL;
> >>>>
> >>>> +		/* Maintain internal state of all stream mappings. */
> >>>> +		streams_[i].androidStream = stream;
> >>>> +
> >>>
> >>> Am I mistaken, or looking at the following patches, this is not used ?
>
>
> Hrm, you might be right. Perhaps maintaining the correct indexing for
> the streams_[] to camera3_stream_t, and (later) putting the pointer in
> is enough.
>
> Wow - this struct is certainly getting small for now then, just storing
> a single index ...
>
> And yet, I still want to make it a class... hrm ... maybe class can come
> later.

Surely a class for single unsigned int would be 'slightly' and
overkill :)

>
>
>
> >>>
> >>>>  		StreamConfiguration streamConfiguration;
> >>>>
> >>>>  		streamConfiguration.size.width = stream->width;
> >>>> @@ -974,6 +985,7 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
> >>>>  		streamConfiguration.pixelFormat = format;
> >>>>
> >>>>  		config_->addConfiguration(streamConfiguration);
> >>>> +		streams_[i].libcameraIndex = streamIndex++;
> >>>
> >>> In that case and the androidStream field is not used, we would just
> >>> need to store a pointer to the StreamConfiguration associated to an
> >>> android stream, don't we ?
> >>
> >>
> >> No, we can't store a pointer to the StreamConfiguration, because it's
> >> not valid to do so.
> >>
> >>
> >> At this point, we have 'added' the configuration to the config_, but it
> >> makes a copy, so /this/ streamConfiguration is the wrong pointer to store.
> >>
> >
> > Right, indeed stream configurations are copied into the camera.
> > Didn't you have a patch to make CameraConfiguration::addConfiguration
> > return a pointer to the stored StreamConfiguration ?
> >
> >
> >> Further more, it could then be suggested that we just obtain the
> >> 'correct' pointer - by using config_->at(n);.
> >>
> >> But we can't do that either, because we are in a loop, adding configs to
> >> a vector, and the vector can re-allocate - so the pointers could change.
> >>
> >> Thus, I am storing an index.
> >
> > Makes sense, then please ignore my comment.
> >
> >>
> >>
> >> Should that be added in a comment or is it ok?
> >
> > If you can capture this in a few lines, why not.
> >
> > My question on the usage of .androidStream remains though
>
> I could store just the index in stream->priv as I think Laurent
> suggested (with casting) at this stage, and later add a struct, but I
> think I'll keep the struct for now.
>

If "later" is after this patch series, I tend to disagree, but I won't
bother too much

>
> >>>>  	}
> >>>>
> >>>>  	switch (config_->validate()) {
> >>>> @@ -991,10 +1003,12 @@ int CameraDevice::configureStreams(camera3_stream_configuration_t *stream_list)
> >>>>
> >>>>  	for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
> >>>>  		camera3_stream_t *stream = stream_list->streams[i];
> >>>> -		StreamConfiguration &streamConfiguration = config_->at(i);
> >>>> +		CameraStream *cameraStream = &streams_[i];
> >>>> +
> >>>> +		StreamConfiguration &cfg = config_->at(cameraStream->libcameraIndex);
> >>>>
> >>>>  		/* Use the bufferCount confirmed by the validation process. */
> >>>> -		stream->max_buffers = streamConfiguration.bufferCount;
> >>>> +		stream->max_buffers = cfg.bufferCount;
> >>>
> >>> I'm not sure I get the purpose of this hunk.
> >>>
> >>> If you're preparing to have less StreamConfiguration than android
> >>> streams (as some streams, as JPEG one, might be hal-only streams),
> >>> why don't you just iterate the camera configuration, as the only
> >>> purpose here is to collect the maximum number of buffers ?
> >>
> >> Because even the HAL only streams need to have the stream->max_buffers
> >> populated ? In the case of a hal-only stream, it gets populated with the
> >> max_buffers of the relevant /source/ stream which will feed that hal
> >> only stream:
> >>
> >>  Stream #1 YUV : MaxBuffers=4
> >>  Stream #2 MJPEG : MaxBuffers=maxBuffersOfStream(1);
> >>
> >> If we iterate over the camera configuration, we would not set the
> >> max_buffers for the hal-only streams, nor perform any other
> >> per-android-stream actions that may be required post-validation.
> >
> > Right, we need to iterate over all the android provided streams to
> > fill their max_buffers field.
> >
> > Now that I look at the code again, I see that in the first loop we store
> > an increasing streamIndex, which is exactly equal to i.
> >
> >
> > 	for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
> >                 ...
> >
> > 		config_->addConfiguration(streamConfiguration);
> > 		streams_[i].libcameraIndex = streamIndex++;
> > 	}
> >
> >         ...
> >
> > In the second loop we use that index, which is exactly equal to the
> > loop counter
> >
> > 	for (unsigned int i = 0; i < stream_list->num_streams; ++i) {
> > 		camera3_stream_t *stream = stream_list->streams[i];
> > 		CameraStream *cameraStream = &streams_[i];
> >
> > 		StreamConfiguration &cfg = config_->at(cameraStream->libcameraIndex);
> >
> > 		/* Use the bufferCount confirmed by the validation process. */
> > 		stream->max_buffers = cfg.bufferCount;
> > 	}
> >
> > Re-phrasing: why do you need that libcamerIdex at all now ?
> >
> > How do you plan to map HAL-only streams to the streamIndex ? There
> > will be one index in the stream_ vector for each of the android
> > stream, will some entries be repeated ? As HAL-only streams will
> > 'point' to the StreamConfiguration of the libcamera Stream that feeds
> > them ?
> >

Missed this part ?


More information about the libcamera-devel mailing list