From patchwork Mon Oct 18 13:29:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 14166 X-Patchwork-Delegate: umang.jain@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 207B9C323E for ; Mon, 18 Oct 2021 13:29:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D57B468F58; Mon, 18 Oct 2021 15:29:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="JwMZqnVh"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A71EA68F5E for ; Mon, 18 Oct 2021 15:29:40 +0200 (CEST) Received: from perceval.ideasonboard.com (unknown [103.238.109.14]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AF7418C6; Mon, 18 Oct 2021 15:29:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1634563780; bh=w/Z4OmnWPQDYNit8Zmqa+zbucJgMOBfdfcxeoI1atWU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JwMZqnVhK0wrBLv4QuWWTLiAMiiivEm7xwJlWP0rkSGFyESTSdMkS0/Uyz0or03Rv IrWTwgnCChu5bpR9NSaDAMEMoXAHpLSfxIEFbC0rxefz93s3kLZ5EysAB7M0eAT1eq HsaESrPYaPn0gwExxehHSV8Nt2Aex1xWscOSndAU= From: Umang Jain To: libcamera-devel@lists.libcamera.org Date: Mon, 18 Oct 2021 18:59:17 +0530 Message-Id: <20211018132923.476242-6-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211018132923.476242-1-umang.jain@ideasonboard.com> References: <20211018132923.476242-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 05/11] android: camera_device: Create struct to track per stream buffer X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The Camera3RequestDescriptor structure stores, for each stream, the camera3_stream_buffer_t and the libcamera FrameBuffer in two separate vectors. This complicates buffer handling, as the code needs to keep both vectors in sync. Create a new structure to group all data about per-stream buffers to simplify this. As a side effect, we need to create a local vector of camera3_stream_buffer_t in CameraDevice::sendCaptureResults() as the camera3_stream_buffer_t instances stored in the new structure in Camera3RequestDescriptor are not contiguous anymore. This is a small price to pay for easier handling of buffers, and will be refactored in subsequent commits anyway. Signed-off-by: Umang Jain Signed-off-by: Laurent Pinchart Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 75 ++++++++++++++++++---------------- src/android/camera_request.cpp | 9 +--- src/android/camera_request.h | 15 ++++++- 3 files changed, 55 insertions(+), 44 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 3bddb292..59557358 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -831,9 +831,9 @@ void CameraDevice::abortRequest(Camera3RequestDescriptor *descriptor) const notifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_REQUEST); for (auto &buffer : descriptor->buffers_) { - buffer.release_fence = buffer.acquire_fence; - buffer.acquire_fence = -1; - buffer.status = CAMERA3_BUFFER_STATUS_ERROR; + buffer.buffer.release_fence = buffer.buffer.acquire_fence; + buffer.buffer.acquire_fence = -1; + buffer.buffer.status = CAMERA3_BUFFER_STATUS_ERROR; } descriptor->status_ = Camera3RequestDescriptor::Status::Error; @@ -931,8 +931,8 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques LOG(HAL, Debug) << "Queueing request " << descriptor->request_->cookie() << " with " << descriptor->buffers_.size() << " streams"; - for (const auto &[i, camera3Buffer] : utils::enumerate(descriptor->buffers_)) { - camera3_stream *camera3Stream = camera3Buffer.stream; + for (const auto &[i, buffer] : utils::enumerate(descriptor->buffers_)) { + camera3_stream *camera3Stream = buffer.buffer.stream; CameraStream *cameraStream = static_cast(camera3Stream->priv); std::stringstream ss; @@ -949,7 +949,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * while fences for streams of type Internal and Mapped are * handled at post-processing time. */ - FrameBuffer *buffer = nullptr; + FrameBuffer *frameBuffer = nullptr; int acquireFence = -1; switch (cameraStream->type()) { case CameraStream::Type::Mapped: @@ -967,13 +967,12 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * associate it with the Camera3RequestDescriptor for * lifetime management only. */ - descriptor->frameBuffers_.push_back( - createFrameBuffer(*camera3Buffer.buffer, + buffer.frameBuffer = + createFrameBuffer(*buffer.buffer.buffer, cameraStream->configuration().pixelFormat, - cameraStream->configuration().size)); - - buffer = descriptor->frameBuffers_.back().get(); - acquireFence = camera3Buffer.acquire_fence; + cameraStream->configuration().size); + frameBuffer = buffer.frameBuffer.get(); + acquireFence = buffer.buffer.acquire_fence; LOG(HAL, Debug) << ss.str() << " (direct)"; break; @@ -985,18 +984,18 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * The buffer has to be returned to the CameraStream * once it has been processed. */ - buffer = cameraStream->getBuffer(); + frameBuffer = cameraStream->getBuffer(); LOG(HAL, Debug) << ss.str() << " (internal)"; break; } - if (!buffer) { - LOG(HAL, Error) << "Failed to create buffer"; + if (!frameBuffer) { + LOG(HAL, Error) << "Failed to create frame buffer"; return -ENOMEM; } - descriptor->request_->addBuffer(cameraStream->stream(), buffer, - acquireFence); + descriptor->request_->addBuffer(cameraStream->stream(), + frameBuffer, acquireFence); } /* @@ -1082,9 +1081,9 @@ void CameraDevice::requestComplete(Request *request) * The buffer status is set to OK and later changed to ERROR if * post-processing/compression fails. */ - for (camera3_stream_buffer_t &buffer : descriptor->buffers_) { + for (auto &buffer : descriptor->buffers_) { CameraStream *cameraStream = - static_cast(buffer.stream->priv); + static_cast(buffer.buffer.stream->priv); /* * Streams of type Direct have been queued to the @@ -1098,9 +1097,9 @@ void CameraDevice::requestComplete(Request *request) * fence to -1 once it has handled it and remove this check. */ if (cameraStream->type() == CameraStream::Type::Direct) - buffer.acquire_fence = -1; - buffer.release_fence = -1; - buffer.status = CAMERA3_BUFFER_STATUS_OK; + buffer.buffer.acquire_fence = -1; + buffer.buffer.release_fence = -1; + buffer.buffer.status = CAMERA3_BUFFER_STATUS_OK; } /* @@ -1115,15 +1114,15 @@ void CameraDevice::requestComplete(Request *request) notifyError(descriptor->frameNumber_, nullptr, CAMERA3_MSG_ERROR_REQUEST); - for (camera3_stream_buffer_t &buffer : descriptor->buffers_) { + for (auto &buffer : descriptor->buffers_) { /* * Signal to the framework it has to handle fences that * have not been waited on by setting the release fence * to the acquire fence value. */ - buffer.release_fence = buffer.acquire_fence; - buffer.acquire_fence = -1; - buffer.status = CAMERA3_BUFFER_STATUS_ERROR; + buffer.buffer.release_fence = buffer.buffer.acquire_fence; + buffer.buffer.acquire_fence = -1; + buffer.buffer.status = CAMERA3_BUFFER_STATUS_ERROR; } descriptor->status_ = Camera3RequestDescriptor::Status::Error; @@ -1160,9 +1159,9 @@ void CameraDevice::requestComplete(Request *request) } /* Handle post-processing. */ - for (camera3_stream_buffer_t &buffer : descriptor->buffers_) { + for (auto &buffer : descriptor->buffers_) { CameraStream *cameraStream = - static_cast(buffer.stream->priv); + static_cast(buffer.buffer.stream->priv); if (cameraStream->type() == CameraStream::Type::Direct) continue; @@ -1170,13 +1169,13 @@ void CameraDevice::requestComplete(Request *request) FrameBuffer *src = request->findBuffer(cameraStream->stream()); if (!src) { LOG(HAL, Error) << "Failed to find a source stream buffer"; - buffer.status = CAMERA3_BUFFER_STATUS_ERROR; - notifyError(descriptor->frameNumber_, buffer.stream, + buffer.buffer.status = CAMERA3_BUFFER_STATUS_ERROR; + notifyError(descriptor->frameNumber_, buffer.buffer.stream, CAMERA3_MSG_ERROR_BUFFER); continue; } - int ret = cameraStream->process(*src, buffer, descriptor); + int ret = cameraStream->process(*src, buffer.buffer, descriptor); /* * Return the FrameBuffer to the CameraStream now that we're @@ -1186,8 +1185,8 @@ void CameraDevice::requestComplete(Request *request) cameraStream->putBuffer(src); if (ret) { - buffer.status = CAMERA3_BUFFER_STATUS_ERROR; - notifyError(descriptor->frameNumber_, buffer.stream, + buffer.buffer.status = CAMERA3_BUFFER_STATUS_ERROR; + notifyError(descriptor->frameNumber_, buffer.buffer.stream, CAMERA3_MSG_ERROR_BUFFER); } } @@ -1213,10 +1212,16 @@ void CameraDevice::sendCaptureResults() camera3_capture_result_t captureResult = {}; captureResult.frame_number = descriptor->frameNumber_; + if (descriptor->resultMetadata_) captureResult.result = descriptor->resultMetadata_->get(); - captureResult.num_output_buffers = descriptor->buffers_.size(); - captureResult.output_buffers = descriptor->buffers_.data(); + + std::vector resultBuffers; + for (const auto &buffer : descriptor->buffers_) + resultBuffers.emplace_back(buffer.buffer); + + captureResult.num_output_buffers = resultBuffers.size(); + captureResult.output_buffers = resultBuffers.data(); if (descriptor->status_ == Camera3RequestDescriptor::Status::Success) captureResult.partial_result = 1; diff --git a/src/android/camera_request.cpp b/src/android/camera_request.cpp index 16a632b3..614baed4 100644 --- a/src/android/camera_request.cpp +++ b/src/android/camera_request.cpp @@ -23,15 +23,10 @@ Camera3RequestDescriptor::Camera3RequestDescriptor( /* Copy the camera3 request stream information for later access. */ const uint32_t numBuffers = camera3Request->num_output_buffers; + buffers_.resize(numBuffers); for (uint32_t i = 0; i < numBuffers; i++) - buffers_[i] = camera3Request->output_buffers[i]; - - /* - * FrameBuffer instances created by wrapping a camera3 provided dmabuf - * are emplaced in this vector of unique_ptr<> for lifetime management. - */ - frameBuffers_.reserve(numBuffers); + buffers_[i].buffer = camera3Request->output_buffers[i]; /* Clone the controls associated with the camera3 request. */ settings_ = CameraMetadata(camera3Request->settings); diff --git a/src/android/camera_request.h b/src/android/camera_request.h index db13f624..a030febf 100644 --- a/src/android/camera_request.h +++ b/src/android/camera_request.h @@ -29,6 +29,16 @@ public: Error, }; + struct StreamBuffer { + camera3_stream_buffer_t buffer; + /* + * FrameBuffer instances created by wrapping a camera3 provided + * dmabuf are emplaced in this vector of unique_ptr<> for + * lifetime management. + */ + std::unique_ptr frameBuffer; + }; + Camera3RequestDescriptor(libcamera::Camera *camera, const camera3_capture_request_t *camera3Request); ~Camera3RequestDescriptor(); @@ -36,8 +46,9 @@ public: bool isPending() const { return status_ == Status::Pending; } uint32_t frameNumber_ = 0; - std::vector buffers_; - std::vector> frameBuffers_; + + std::vector buffers_; + CameraMetadata settings_; std::unique_ptr request_; std::unique_ptr resultMetadata_;