From patchwork Mon Sep 27 21:37:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 13958 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 C38A8BDC71 for ; Mon, 27 Sep 2021 21:36:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A050E6918E; Mon, 27 Sep 2021 23:36:21 +0200 (CEST) Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E4C9A69189 for ; Mon, 27 Sep 2021 23:36:17 +0200 (CEST) Received: (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 7B8DBC0005; Mon, 27 Sep 2021 21:36:17 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 27 Sep 2021 23:37:00 +0200 Message-Id: <20210927213700.25365-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210927213700.25365-1-jacopo@jmondi.org> References: <20210927213700.25365-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/2] android: Wait on fences in CameraStream::process() 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" Acquisition fences for streams of type Mapped generated by post-processing, are not correctly handled and are currently ignored by the camera HAL. Fix this by adding CameraStream::waitFence(), executed before starting the post-processing in CameraStream::process(). The change applies to all streams generated by post-processing (Mapped and Internal) but currently acquire fences of Internal streams are handled by the camera worker. Post-pone that to post-processing time by passing -1 to the worker for Internal streams. The CameraStream::waitFence() implementation is copied from the CameraWorker::Worker::waitFence() one, and both should be replaced by a libcamera core mechanism. Signed-off-by: Jacopo Mondi Reviewed-by: Hirokazu Honda --- src/android/camera_device.cpp | 6 +++-- src/android/camera_stream.cpp | 48 +++++++++++++++++++++++++++++++++-- src/android/camera_stream.h | 4 ++- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 3c9609d74402..8b0caf2bda7d 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -973,6 +973,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques const camera3_stream_buffer_t &camera3Buffer = descriptor.buffers_[i]; camera3_stream *camera3Stream = camera3Buffer.stream; CameraStream *cameraStream = static_cast(camera3Stream->priv); + int acquireFence = -1; std::stringstream ss; ss << i << " - (" << camera3Stream->width << "x" @@ -1008,6 +1009,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques cameraStream->configuration().size)); buffer = descriptor.frameBuffers_.back().get(); + acquireFence = camera3Buffer.acquire_fence; LOG(HAL, Debug) << ss.str() << " (direct)"; break; @@ -1030,7 +1032,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques } descriptor.request_->addBuffer(cameraStream->stream(), buffer, - camera3Buffer.acquire_fence); + acquireFence); } /* @@ -1186,7 +1188,7 @@ void CameraDevice::requestComplete(Request *request) continue; } - int ret = cameraStream->process(*src, *buffer.buffer, + int ret = cameraStream->process(*src, buffer, descriptor.settings_, resultMetadata.get()); /* diff --git a/src/android/camera_stream.cpp b/src/android/camera_stream.cpp index e30c7ee4fcb3..40dcb361749f 100644 --- a/src/android/camera_stream.cpp +++ b/src/android/camera_stream.cpp @@ -7,7 +7,10 @@ #include "camera_stream.h" +#include #include +#include +#include #include @@ -109,11 +112,52 @@ int CameraStream::configure() return 0; } +int CameraStream::waitFence(int fence) +{ + /* + * \todo The implementation here is copied from camera_worker.cpp + * and both should be removed once libcamera is instrumented to handle + * fences waiting in the core. + * + * \todo Better characterize the timeout. Currently equal to the one + * used by the Rockchip Camera HAL on ChromeOS. + */ + constexpr unsigned int timeoutMs = 300; + struct pollfd fds = { fence, POLLIN, 0 }; + + do { + int ret = poll(&fds, 1, timeoutMs); + if (ret == 0) + return -ETIME; + + if (ret > 0) { + if (fds.revents & (POLLERR | POLLNVAL)) + return -EINVAL; + + return 0; + } + } while (errno == EINTR || errno == EAGAIN); + + return -errno; +} + int CameraStream::process(const FrameBuffer &source, - buffer_handle_t camera3Dest, + camera3_stream_buffer_t &camera3Buffer, const CameraMetadata &requestMetadata, CameraMetadata *resultMetadata) { + /* Handle waiting on fences on the destination buffer. */ + int fence = camera3Buffer.acquire_fence; + if (fence != -1) { + int ret = waitFence(fence); + ::close(fence); + if (ret < 0) { + LOG(HAL, Error) << "Failed waiting for fence: " + << fence << ": " << strerror(-ret); + return ret; + } + } + if (!postProcessor_) return 0; @@ -122,7 +166,7 @@ int CameraStream::process(const FrameBuffer &source, * separate thread. */ const StreamConfiguration &output = configuration(); - CameraBuffer dest(camera3Dest, formats::MJPEG, output.size, + CameraBuffer dest(*camera3Buffer.buffer, formats::MJPEG, output.size, PROT_READ | PROT_WRITE); if (!dest.isValid()) { LOG(HAL, Error) << "Failed to map android blob buffer"; diff --git a/src/android/camera_stream.h b/src/android/camera_stream.h index 2dab6c3a37d1..454a33dcdaaa 100644 --- a/src/android/camera_stream.h +++ b/src/android/camera_stream.h @@ -119,7 +119,7 @@ public: int configure(); int process(const libcamera::FrameBuffer &source, - buffer_handle_t camera3Dest, + camera3_stream_buffer_t &camera3Buffer, const CameraMetadata &requestMetadata, CameraMetadata *resultMetadata); libcamera::FrameBuffer *getBuffer(); @@ -140,6 +140,8 @@ private: */ std::unique_ptr mutex_; std::unique_ptr postProcessor_; + + int waitFence(int fence); }; #endif /* __ANDROID_CAMERA_STREAM__ */