[libcamera-devel,v4,8/9] android: camera_device: Use libcamera buffer pool

Message ID 20200930132707.19367-9-jacopo@jmondi.org
State Superseded
Headers show
Series
  • android: camera_device: Add support for internal buffers
Related show

Commit Message

Jacopo Mondi Sept. 30, 2020, 1:27 p.m. UTC
Now that we have reserved and made available to the camera HAL a
pool of libcamera allocated buffers, use them when a CameraStream
instance that requires internal allocation is processed.

Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 src/android/camera_device.cpp | 57 +++++++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 13 deletions(-)

Comments

Laurent Pinchart Oct. 2, 2020, 12:52 a.m. UTC | #1
Hi Jacopo,

Thank you for the patch.

On Wed, Sep 30, 2020 at 03:27:06PM +0200, Jacopo Mondi wrote:
> Now that we have reserved and made available to the camera HAL a
> pool of libcamera allocated buffers, use them when a CameraStream
> instance that requires internal allocation is processed.
> 
> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> ---
>  src/android/camera_device.cpp | 57 +++++++++++++++++++++++++++--------
>  1 file changed, 44 insertions(+), 13 deletions(-)
> 
> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
> index 2ebc3fcc336e..dc19faf8edd7 100644
> --- a/src/android/camera_device.cpp
> +++ b/src/android/camera_device.cpp
> @@ -1479,6 +1479,8 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
>  	for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
>  		CameraStream *cameraStream =
>  			static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
> +		const StreamConfiguration &config = config_->at(cameraStream->index());
> +		Stream *stream = config.stream();
>  
>  		/*
>  		 * Keep track of which stream the request belongs to and store
> @@ -1487,27 +1489,49 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
>  		descriptor->buffers[i].stream = camera3Buffers[i].stream;
>  		descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
>  
> -		/* Software streams are handled after hardware streams complete. */
> -		if (cameraStream->format() == formats::MJPEG)
> -			continue;
> -
>  		/*
> -		 * Create a libcamera buffer using the dmabuf descriptors of
> -		 * the camera3Buffer for each stream. The FrameBuffer is
> -		 * directly associated with the Camera3RequestDescriptor for
> -		 * lifetime management only.
> +		 * Inspect the camera stream type, create buffers opportunely
> +		 * and add them to the Request if required.
>  		 */
> -		FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
> +		FrameBuffer *buffer;
> +		switch (cameraStream->type()) {
> +		case CameraStream::Type::Mapped:
> +			/*
> +			 * Mapped streams don't need buffers added to the
> +			 * Request.
> +			 */
> +			continue;
> +
> +		case CameraStream::Type::Direct:
> +			/*
> +			 * Create a libcamera buffer using the dmabuf
> +			 * descriptors of the camera3Buffer for each stream and
> +			 * associate it with the Camera3RequestDescriptor for
> +			 * lifetime management only.
> +			 */
> +			buffer = createFrameBuffer(*camera3Buffers[i].buffer);
> +			descriptor->frameBuffers.emplace_back(buffer);
> +			break;
> +
> +		case CameraStream::Type::Internal:
> +			/*
> +			 * Get the frame buffer from the CameraStream internal
> +			 * buffer pool. The lifetime management of internal
> +			 * buffers is connected to the one of the
> +			 * FrameBufferAllocator instance.
> +			 *
> +			 * The retrieved buffer has to be returned to the
> +			 * allocator once it has been processed.
> +			 */
> +			buffer = getBuffer(stream);
> +			break;
> +		}

I'd add a blank line here.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

>  		if (!buffer) {
>  			LOG(HAL, Error) << "Failed to create buffer";
>  			delete request;
>  			delete descriptor;
>  			return -ENOMEM;
>  		}
> -		descriptor->frameBuffers.emplace_back(buffer);
> -
> -		StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index());
> -		Stream *stream = streamConfiguration->stream();
>  
>  		request->addBuffer(stream, buffer);
>  	}
> @@ -1634,6 +1658,13 @@ void CameraDevice::requestComplete(Request *request)
>  		const uint32_t jpeg_orientation = 0;
>  		resultMetadata->addEntry(ANDROID_JPEG_ORIENTATION,
>  					 &jpeg_orientation, 1);
> +
> +		/*
> +		 * Return the FrameBuffer to the CameraStream now that we're
> +		 * done processing it.
> +		 */
> +		if (cameraStream->type() == CameraStream::Type::Internal)
> +			returnBuffer(stream, buffer);
>  	}
>  
>  	/* Prepare to call back the Android camera stack. */

Patch

diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 2ebc3fcc336e..dc19faf8edd7 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -1479,6 +1479,8 @@  int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 	for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
 		CameraStream *cameraStream =
 			static_cast<CameraStream *>(camera3Buffers[i].stream->priv);
+		const StreamConfiguration &config = config_->at(cameraStream->index());
+		Stream *stream = config.stream();
 
 		/*
 		 * Keep track of which stream the request belongs to and store
@@ -1487,27 +1489,49 @@  int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
 		descriptor->buffers[i].stream = camera3Buffers[i].stream;
 		descriptor->buffers[i].buffer = camera3Buffers[i].buffer;
 
-		/* Software streams are handled after hardware streams complete. */
-		if (cameraStream->format() == formats::MJPEG)
-			continue;
-
 		/*
-		 * Create a libcamera buffer using the dmabuf descriptors of
-		 * the camera3Buffer for each stream. The FrameBuffer is
-		 * directly associated with the Camera3RequestDescriptor for
-		 * lifetime management only.
+		 * Inspect the camera stream type, create buffers opportunely
+		 * and add them to the Request if required.
 		 */
-		FrameBuffer *buffer = createFrameBuffer(*camera3Buffers[i].buffer);
+		FrameBuffer *buffer;
+		switch (cameraStream->type()) {
+		case CameraStream::Type::Mapped:
+			/*
+			 * Mapped streams don't need buffers added to the
+			 * Request.
+			 */
+			continue;
+
+		case CameraStream::Type::Direct:
+			/*
+			 * Create a libcamera buffer using the dmabuf
+			 * descriptors of the camera3Buffer for each stream and
+			 * associate it with the Camera3RequestDescriptor for
+			 * lifetime management only.
+			 */
+			buffer = createFrameBuffer(*camera3Buffers[i].buffer);
+			descriptor->frameBuffers.emplace_back(buffer);
+			break;
+
+		case CameraStream::Type::Internal:
+			/*
+			 * Get the frame buffer from the CameraStream internal
+			 * buffer pool. The lifetime management of internal
+			 * buffers is connected to the one of the
+			 * FrameBufferAllocator instance.
+			 *
+			 * The retrieved buffer has to be returned to the
+			 * allocator once it has been processed.
+			 */
+			buffer = getBuffer(stream);
+			break;
+		}
 		if (!buffer) {
 			LOG(HAL, Error) << "Failed to create buffer";
 			delete request;
 			delete descriptor;
 			return -ENOMEM;
 		}
-		descriptor->frameBuffers.emplace_back(buffer);
-
-		StreamConfiguration *streamConfiguration = &config_->at(cameraStream->index());
-		Stream *stream = streamConfiguration->stream();
 
 		request->addBuffer(stream, buffer);
 	}
@@ -1634,6 +1658,13 @@  void CameraDevice::requestComplete(Request *request)
 		const uint32_t jpeg_orientation = 0;
 		resultMetadata->addEntry(ANDROID_JPEG_ORIENTATION,
 					 &jpeg_orientation, 1);
+
+		/*
+		 * Return the FrameBuffer to the CameraStream now that we're
+		 * done processing it.
+		 */
+		if (cameraStream->type() == CameraStream::Type::Internal)
+			returnBuffer(stream, buffer);
 	}
 
 	/* Prepare to call back the Android camera stack. */