From patchwork Mon Jun 29 16:29:24 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27080 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 21CB0C3261 for ; Mon, 29 Jun 2026 16:30:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7E42F65F43; Mon, 29 Jun 2026 18:30:25 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="of/RI3n6"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E14B565F20 for ; Mon, 29 Jun 2026 18:30:20 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A1815E91 for ; Mon, 29 Jun 2026 18:29:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750577; bh=JF27yKLGb4qUAtPnnKr3EpVMpRXy00p1y6HlStO3Rf0=; h=From:To:Subject:Date:In-Reply-To:References:From; b=of/RI3n6LkyOhrWnPILqP687KyUPyP0wi9cRAo1D3fq3pqGLErtcElj3+PlKkXXT9 G7lFToOg9gSZ6Dm0/IAbU5iB4ugxs/EOdAMO/DSyChnp0W82hjCXIdq57W1JbxQdrA gwieJLBpE02qvb0UlJdT2LdC3QPMKEaOlM0EXDVM= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 01/54] apps: cam: Simplify buffer reuse Date: Mon, 29 Jun 2026 18:29:24 +0200 Message-ID: <20260629163017.863145-2-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Rename `CameraSession::sinkRelease()` to `requeueRequest()` and remove code duplication by calling it from `processRequest()`. Signed-off-by: Barnabás Pőcze --- src/apps/cam/camera_session.cpp | 11 ++++------- src/apps/cam/camera_session.h | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/apps/cam/camera_session.cpp b/src/apps/cam/camera_session.cpp index 17444a217b..f90800caf8 100644 --- a/src/apps/cam/camera_session.cpp +++ b/src/apps/cam/camera_session.cpp @@ -326,7 +326,7 @@ int CameraSession::start() return ret; } - sink_->requestProcessed.connect(this, &CameraSession::sinkRelease); + sink_->requestProcessed.connect(this, &CameraSession::requeueRequest); } allocator_ = std::make_unique(camera_); @@ -542,14 +542,11 @@ void CameraSession::processRequest(Request *request) * If the frame sink holds on the request, we'll requeue it later in the * complete handler. */ - if (!requeue) - return; - - request->reuse(Request::ReuseBuffers); - queueRequest(request); + if (requeue) + requeueRequest(request); } -void CameraSession::sinkRelease(Request *request) +void CameraSession::requeueRequest(Request *request) { request->reuse(Request::ReuseBuffers); queueRequest(request); diff --git a/src/apps/cam/camera_session.h b/src/apps/cam/camera_session.h index 4442fd9b1a..7ad1b77d62 100644 --- a/src/apps/cam/camera_session.h +++ b/src/apps/cam/camera_session.h @@ -55,7 +55,7 @@ private: int queueRequest(libcamera::Request *request); void requestComplete(libcamera::Request *request); void processRequest(libcamera::Request *request); - void sinkRelease(libcamera::Request *request); + void requeueRequest(libcamera::Request *request); const OptionsParser::Options &options_; std::shared_ptr camera_; From patchwork Mon Jun 29 16:29:25 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27081 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 CAC59C3261 for ; Mon, 29 Jun 2026 16:30:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 26C8865F31; Mon, 29 Jun 2026 18:30:27 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="O/n1U1Ic"; 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 29DF065F21 for ; Mon, 29 Jun 2026 18:30:21 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D50101044; Mon, 29 Jun 2026 18:29:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750578; bh=so6WTDiZP0Yg9iTDyJ0AArtYlJl8k5aH4ItHX611/0k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O/n1U1IcXyAfw4fow2+HIE1GHBgiVKKErqtMxBv1jgwRkfN+vdaVqmn27ysyVdHQX T4WNg71b3n+VMhmRj0p4Hi8T6zddgKniAreTMKFljY+OM4AX1kQYIzXDv77gd8LyKY Ey67K4ZuLXCN6Hig1EdR3yDnXoorwZ0k9XYGYNNY= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , Laurent Pinchart Subject: [RFC PATCH v1 02/54] libcamera: request: Disassociate buffer when cancelling Date: Mon, 29 Jun 2026 18:29:25 +0200 Message-ID: <20260629163017.863145-3-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Match the behaviour of `completeBuffer()` by unsetting the "parent" `Request` pointer of the `FrameBuffer`. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/request.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 163d8cf920..5f983e0ce6 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -143,6 +143,7 @@ void Request::Private::doCancelRequest() for (FrameBuffer *buffer : pending_) { buffer->_d()->cancel(); camera_->bufferCompleted.emit(request, buffer); + buffer->_d()->setRequest(nullptr); } cancelled_ = true; From patchwork Mon Jun 29 16:29:26 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27082 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 7E222C3261 for ; Mon, 29 Jun 2026 16:30:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E14C865F54; Mon, 29 Jun 2026 18:30:27 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="oI1s+ba7"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5B17B65F23 for ; Mon, 29 Jun 2026 18:30:21 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2E5698D4; Mon, 29 Jun 2026 18:29:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750578; bh=V8zgSlNix/rpOp6s0TRutadeoRTwLqXW+pcnKTgSjCA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oI1s+ba7TszZfRMR1TxDd3Ia5HRB7G/D8l1JSNwU4ImthHJfZqa70NbQFrVGAsDzZ N0/JFSbsLsm5WyXM/PQdvEl8ivySmKJqtimNIcZowFeBL3q+LDoUNzId16a5fiYlj0 NJuFMhzu3oG/p5VT5b1UomzUrkdQTFoDUARjsn3s= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Laurent Pinchart Subject: [RFC PATCH v1 03/54] libcamera: pipeline: Replace open-coded request cancellation Date: Mon, 29 Jun 2026 18:29:26 +0200 Message-ID: <20260629163017.863145-4-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Use `PipelineHander::cancelRequest()` instead of manually cancelling, completing each buffer, then completing the request. This has the same behaviour unless the request has no pending buffers. In which case the new behaviour is to always mark the request as cancelled, while it would not have been marked as cancelled previously. This affects e.g. requests waiting for metadata after all buffers have completed. Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 14 ++------------ .../pipeline/rpi/common/pipeline_base.cpp | 16 +--------------- src/libcamera/pipeline/vimc/vimc.cpp | 7 +------ 3 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 0f3e169d3b..af1b79d708 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -790,12 +790,7 @@ void IPU3CameraData::cancelPendingRequests() while (!pendingRequests_.empty()) { Request *request = pendingRequests_.front(); - for (const auto &[stream, buffer] : request->buffers()) { - buffer->_d()->cancel(); - pipe()->completeBuffer(request, buffer); - } - - pipe()->completeRequest(request); + pipe()->cancelRequest(request); pendingRequests_.pop(); } } @@ -1299,13 +1294,8 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer) /* If the buffer is cancelled force a complete of the whole request. */ if (buffer->metadata().status == FrameMetadata::FrameCancelled) { - for (const auto &[stream, b] : request->buffers()) { - b->_d()->cancel(); - pipe()->completeBuffer(request, b); - } - frameInfos_.remove(info); - pipe()->completeRequest(request); + pipe()->cancelRequest(request); return; } diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp index 5a5acf6a16..6a6be5c820 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp @@ -1401,21 +1401,7 @@ void CameraData::clearIncompleteRequests() * back to the application. */ while (!requestQueue_.empty()) { - Request *request = requestQueue_.front(); - - for (auto &b : request->buffers()) { - FrameBuffer *buffer = b.second; - /* - * Has the buffer already been handed back to the - * request? If not, do so now. - */ - if (buffer->request()) { - buffer->_d()->cancel(); - pipe()->completeBuffer(request, buffer); - } - } - - pipe()->completeRequest(request); + pipe()->cancelRequest(requestQueue_.front()); requestQueue_.pop(); } } diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 01d8fb25a2..99ae60785b 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -605,12 +605,7 @@ void VimcCameraData::imageBufferReady(FrameBuffer *buffer) /* If the buffer is cancelled force a complete of the whole request. */ if (buffer->metadata().status == FrameMetadata::FrameCancelled) { - for (const auto &[stream, b] : request->buffers()) { - b->_d()->cancel(); - pipe->completeBuffer(request, b); - } - - pipe->completeRequest(request); + pipe->cancelRequest(request); return; } From patchwork Mon Jun 29 16:29:27 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27083 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 C6E8FC3261 for ; Mon, 29 Jun 2026 16:30:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5767F65F61; Mon, 29 Jun 2026 18:30:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="TAfeecM+"; 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 8DB5065F04 for ; Mon, 29 Jun 2026 18:30:21 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6EF03E91 for ; Mon, 29 Jun 2026 18:29:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750578; bh=PuZgyyAqywl0ytorJi6f1SdmjAFzOagjt5FkHhiy9aw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=TAfeecM+zOBxBP6l9c+4A96nJJPhzBzVst6uvsnAcvsKlg4N4bn32VbYnZXWHVpGi z2l9Wz6sD561EvhbxHndAjYQQXq+lCrnDbQrjUTLdC++AgebqvSnwSwiQXgwVQ5y5j jVgu0qe+IX33I8z20v5cmT5dQLFkb7Sqi3MExVLQ= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 04/54] libcamera: pipeline: mali-c55: Remove `setRequest()` calls Date: Mon, 29 Jun 2026 18:29:27 +0200 Message-ID: <20260629163017.863145-5-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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 buffer completion handler (`PipelineHandlerMaliC55::cruBufferReady()`) does not query the request of the buffer, so setting it is unnecessary. Signed-off-by: Barnabás Pőcze --- src/libcamera/pipeline/mali-c55/mali-c55.cpp | 2 +- src/libcamera/pipeline/mali-c55/rzg2l-cru.cpp | 3 +-- src/libcamera/pipeline/mali-c55/rzg2l-cru.h | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index 599ff88b59..b30455683e 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -1541,7 +1541,7 @@ void PipelineHandlerMaliC55::queueRequestToCru(MaliC55CameraData *data, auto *mem = std::get_if(&data->input_); ASSERT(mem); - FrameBuffer *cruBuffer = mem->cru_->queueBuffer(request); + FrameBuffer *cruBuffer = mem->cru_->queueBuffer(); ASSERT(cruBuffer); auto frameInfo = prepareFrameInfo(request); diff --git a/src/libcamera/pipeline/mali-c55/rzg2l-cru.cpp b/src/libcamera/pipeline/mali-c55/rzg2l-cru.cpp index 9cb7cc3f10..3de4527561 100644 --- a/src/libcamera/pipeline/mali-c55/rzg2l-cru.cpp +++ b/src/libcamera/pipeline/mali-c55/rzg2l-cru.cpp @@ -35,7 +35,7 @@ static const std::map bitDepthToFmt{ LOG_DEFINE_CATEGORY(RZG2LCRU) -FrameBuffer *RZG2LCRU::queueBuffer(Request *request) +FrameBuffer *RZG2LCRU::queueBuffer() { FrameBuffer *buffer; @@ -53,7 +53,6 @@ FrameBuffer *RZG2LCRU::queueBuffer(Request *request) } availableBuffers_.pop_back(); - buffer->_d()->setRequest(request); return buffer; } diff --git a/src/libcamera/pipeline/mali-c55/rzg2l-cru.h b/src/libcamera/pipeline/mali-c55/rzg2l-cru.h index 8bd4c027ad..7ef5e2b5ee 100644 --- a/src/libcamera/pipeline/mali-c55/rzg2l-cru.h +++ b/src/libcamera/pipeline/mali-c55/rzg2l-cru.h @@ -20,7 +20,6 @@ namespace libcamera { class CameraSensor; class FrameBuffer; class MediaDevice; -class Request; class Size; class RZG2LCRU @@ -45,7 +44,7 @@ public: V4L2VideoDevice *output() { return output_.get(); } int configure(V4L2SubdeviceFormat *subdevFormat, V4L2DeviceFormat *inputFormat); - FrameBuffer *queueBuffer(Request *request); + FrameBuffer *queueBuffer(); void returnBuffer(FrameBuffer *buffer); int freeBuffers(); From patchwork Mon Jun 29 16:29:28 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27084 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 263BFC3261 for ; Mon, 29 Jun 2026 16:30:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E8B1165F2E; Mon, 29 Jun 2026 18:30:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="il+3Cpp9"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D162965F20 for ; Mon, 29 Jun 2026 18:30:21 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A1CC38D4; Mon, 29 Jun 2026 18:29:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750578; bh=yVAj9Bv4E+3KPxNZWyQfWEEa281jmw3Oasae8yqgqI4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=il+3Cpp9CIgXuBBPscfBzoXei1GKhEITcDdnsq2D7SR56aNbHqTeLvWJ19SwFuon3 /ZDUMstWMr/frqX8VgX9ihZZ4GGluTVx7/Hv1oHc/tZwKrGW1z7GU89CRDiWGr4Oq0 LpCB69dPyXzJP4tJ0qZ08P5Ep9gsdU7xWv7fju9M= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Laurent Pinchart Subject: [RFC PATCH v1 05/54] libcamera: pipeline: virtual: Make copy of request's buffer map Date: Mon, 29 Jun 2026 18:29:28 +0200 Message-ID: <20260629163017.863145-6-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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 change that moved frame generation to a separate thread introduced a race condition. After the last buffer of a request is completed, the loop in `VirtualCameraData::processRequest()` will reference the buffer map in the loop condition. This is problematic because concurrently the request will be completed, then reused or destroyed. This was mostly hidden by the fact that most application use `ReuseBuffers`, so the buffer map nodes do not change. Fix that by making a copy of the (stream, buffer) pairs locally. Fixes: 6c251ae3ef0e ("libcamera: pipeline: virtual: Move image generation to separate thread") Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/virtual/virtual.cpp | 40 +++++++++++++--------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index 81d2dddab8..a7cd76e226 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -130,33 +130,39 @@ VirtualCameraData::VirtualCameraData(PipelineHandler *pipe, void VirtualCameraData::processRequest(Request *request) { + std::array, kMaxStream> buffers; + size_t bufferCount = 0; + for (const auto &[stream, buffer] : request->buffers()) { bool found = false; - /* map buffer and fill test patterns */ for (auto &streamConfig : streamConfigs_) { if (stream == &streamConfig.stream) { - FrameMetadata &fmd = buffer->_d()->metadata(); - - fmd.status = FrameMetadata::Status::FrameSuccess; - fmd.sequence = streamConfig.seq++; - fmd.timestamp = currentTimestamp(); - - Span planes = buffer->planes(); - for (const auto [i, p] : utils::enumerate(planes)) - fmd.planes()[i].bytesused = p.length; - + buffers[bufferCount++] = { &streamConfig, buffer }; found = true; - - if (streamConfig.frameGenerator->generateFrame( - stream->configuration().size, buffer)) - fmd.status = FrameMetadata::Status::FrameError; - - bufferCompleted.emit(buffer); break; } } ASSERT(found); } + + for (size_t i = 0; i < bufferCount; i++) { + const auto &[stream, buffer] = buffers[i]; + FrameMetadata &fmd = buffer->_d()->metadata(); + + fmd.status = FrameMetadata::Status::FrameSuccess; + fmd.sequence = stream->seq++; + fmd.timestamp = currentTimestamp(); + + Span planes = buffer->planes(); + for (const auto [j, p] : utils::enumerate(planes)) + fmd.planes()[j].bytesused = p.length; + + if (stream->frameGenerator->generateFrame(stream->stream.configuration().size, + buffer)) + fmd.status = FrameMetadata::Status::FrameError; + + bufferCompleted.emit(buffer); + } } VirtualCameraConfiguration::VirtualCameraConfiguration(VirtualCameraData *data) From patchwork Mon Jun 29 16:29:29 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27085 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 E5F52C3261 for ; Mon, 29 Jun 2026 16:30:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6D77465F36; Mon, 29 Jun 2026 18:30:32 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Cz3mBRDp"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1CC5765F29 for ; Mon, 29 Jun 2026 18:30:22 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E0658E91; Mon, 29 Jun 2026 18:29:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750579; bh=A5FPi9pi1Jad1M+o2kl0EVITvDW0V6dnaP6dvzTsv0k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Cz3mBRDpQEMHgvLZs0GsK9i7xpCAwk3nzEC2yxFNhTwX8adBmM9GjQ0pI/ABYjePa ut79Fc1lYNM+ZtDbBuY1L+Nlf+byTrQxyqVlgT5ltF8CKw7AWWfHCpjn1Ku4ekdshE LPacoEF4/lbfBwWJW2jO0gms6/BciiPbSeMh1qec= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Laurent Pinchart Subject: [RFC PATCH v1 06/54] libcamera: request: completeBuffer(): Emit `bufferCompleted` here Date: Mon, 29 Jun 2026 18:29:29 +0200 Message-ID: <20260629163017.863145-7-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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 `Request` class already manages the emission of that signal in `doCancelRequest()`, so let's move the normal emission from the pipeline handler base class while keeping the ordering of things (except the trace point since it probably makes more sense to have the trace point before user code runs). Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline_handler.cpp | 2 -- src/libcamera/request.cpp | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index e7145c1d48..3d49f85cfa 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -562,8 +562,6 @@ void PipelineHandler::doQueueRequests(Camera *camera) */ bool PipelineHandler::completeBuffer(Request *request, FrameBuffer *buffer) { - Camera *camera = request->_d()->camera(); - camera->bufferCompleted.emit(request, buffer); return request->_d()->completeBuffer(buffer); } diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 5f983e0ce6..022a97f169 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -104,6 +104,9 @@ bool Request::Private::completeBuffer(FrameBuffer *buffer) { LIBCAMERA_TRACEPOINT(request_complete_buffer, this, buffer); + Request *request = LIBCAMERA_O_PTR(); + camera_->bufferCompleted.emit(request, buffer); + int ret = pending_.erase(buffer); ASSERT(ret == 1); From patchwork Mon Jun 29 16:29:30 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27086 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 9E188C3261 for ; Mon, 29 Jun 2026 16:30:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 500C465F78; Mon, 29 Jun 2026 18:30:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="O8z1NAW7"; 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 5288565F28 for ; Mon, 29 Jun 2026 18:30:22 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2A2208D4; Mon, 29 Jun 2026 18:29:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750579; bh=EeN+aVQ+3EoPK+5UpjBSjnEyhSEN3Q0wcc7VEyo3LaU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O8z1NAW7BvdRYKeIugp7nEIiqoli4thIwJItHl2ZY7j17ysNRo0VmQ5Q8ECVeM5iY LKcVND4K5jOs84SPKbNhYWkCgF3kWCDR7/hnMIS1efTbI4yk1BSV1NVbzvgBIL8Xfa iJMMq1ZjBfLGimSIAYWCilzT0j5AFBbwPlBP4pV8= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Laurent Pinchart Subject: [RFC PATCH v1 07/54] libcamera: pipeline_handler: completeBuffer(): Inline and `static` Date: Mon, 29 Jun 2026 18:29:30 +0200 Message-ID: <20260629163017.863145-8-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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 function now only calls a method in `Request::Private`, so inline it, and also make it `static` since it needs no access to the pipeline handler members. Signed-off-by: Barnabás Pőcze Reviewed-by: Laurent Pinchart --- include/libcamera/internal/pipeline_handler.h | 7 ++++++- src/libcamera/pipeline_handler.cpp | 5 +---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index 6922ce18ec..cc52c6b045 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -19,6 +19,7 @@ #include "libcamera/internal/camera_manager.h" #include "libcamera/internal/ipa_manager.h" +#include "libcamera/internal/request.h" namespace libcamera { @@ -60,7 +61,11 @@ public: void registerRequest(Request *request); void queueRequest(Request *request); - bool completeBuffer(Request *request, FrameBuffer *buffer); + static bool completeBuffer(Request *request, FrameBuffer *buffer) + { + return request->_d()->completeBuffer(buffer); + } + void completeRequest(Request *request); void cancelRequest(Request *request); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 3d49f85cfa..99f35d1e42 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -544,6 +544,7 @@ void PipelineHandler::doQueueRequests(Camera *camera) */ /** + * \fn PipelineHandler::completeBuffer(Request *request, FrameBuffer *buffer) * \brief Complete a buffer for a request * \param[in] request The request the buffer belongs to * \param[in] buffer The buffer that has completed @@ -560,10 +561,6 @@ void PipelineHandler::doQueueRequests(Camera *camera) * \return True if all buffers contained in the request have completed, false * otherwise */ -bool PipelineHandler::completeBuffer(Request *request, FrameBuffer *buffer) -{ - return request->_d()->completeBuffer(buffer); -} /** * \brief Signal request completion From patchwork Mon Jun 29 16:29:31 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27087 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 51B08C3261 for ; Mon, 29 Jun 2026 16:30:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3C7FD65F39; Mon, 29 Jun 2026 18:30:36 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="TFtEW4wi"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9C8EB65F2E for ; Mon, 29 Jun 2026 18:30:22 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 655381044; Mon, 29 Jun 2026 18:29:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750579; bh=rqqzN5Jhikx2SOBPz/annoESvH/M7mkdiSpqXo8Z40Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TFtEW4wirhpCl4h6ENsOOEEU5+93oYX5Ys7TaORqrRiiygYRF6e9Frq5jeWXVt/0S oGcO3ziSU87obPuF4lTvMpDNjWX23Ufr2lLmJQ/kvgfVqYyVJavfUctvLj12wCO96S Kr7psxTH+RBEjtIHLfG7D6kDbF4d8HZ1botcyJzI= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , Laurent Pinchart , Paul Elder Subject: [RFC PATCH v1 08/54] v4l2: v4l2_camera: Avoid a level of indirection Date: Mon, 29 Jun 2026 18:29:31 +0200 Message-ID: <20260629163017.863145-9-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Convert the `completedBuffers_` container to store the items directly and not via an `std::unique_ptr`. Signed-off-by: Barnabás Pőcze Acked-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Paul Elder --- src/v4l2/v4l2_camera.cpp | 11 ++++------- src/v4l2/v4l2_camera.h | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index 412ab4ea67..648578c22b 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -70,11 +70,10 @@ void V4L2Camera::unbind() std::vector V4L2Camera::completedBuffers() { - std::vector v; - MutexLocker lock(bufferLock_); - for (std::unique_ptr &metadata : completedBuffers_) - v.push_back(*metadata.get()); + std::vector v(std::move_iterator(completedBuffers_.begin()), + std::move_iterator(completedBuffers_.end())); + completedBuffers_.clear(); return v; @@ -88,9 +87,7 @@ void V4L2Camera::requestComplete(Request *request) /* We only have one stream at the moment. */ bufferLock_.lock(); FrameBuffer *buffer = request->buffers().begin()->second; - std::unique_ptr metadata = - std::make_unique(request->cookie(), buffer->metadata()); - completedBuffers_.push_back(std::move(metadata)); + completedBuffers_.emplace_back(request->cookie(), buffer->metadata()); bufferLock_.unlock(); uint64_t data = 1; diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h index 3d09ae7d60..1528f9aad8 100644 --- a/src/v4l2/v4l2_camera.h +++ b/src/v4l2/v4l2_camera.h @@ -85,7 +85,7 @@ private: std::vector> requestPool_; std::deque pendingRequests_; - std::deque> completedBuffers_ + std::deque completedBuffers_ LIBCAMERA_TSA_GUARDED_BY(bufferLock_); int efd_; From patchwork Mon Jun 29 16:29:32 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27088 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 21736C3261 for ; Mon, 29 Jun 2026 16:30:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4BBEC65F3D; Mon, 29 Jun 2026 18:30:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="OKK1vQ77"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CE35465F04 for ; Mon, 29 Jun 2026 18:30:22 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AFAC68D4 for ; Mon, 29 Jun 2026 18:29:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750579; bh=K6Mvvbe+ry8dhA9unPPH9k/Yv6jmPD7iXc8rogky2lU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=OKK1vQ779RneQBfw02WMk+FTyiTDgfl53mGPC7a6g/Vbp7uhb2xbWMG6GxHD36qvX k5EKBAB6R0ihpJbCKy4dLq/+XuByJ3PGVmsDhr2K2Kd11q++hlnPREUUwkbDGt1BeU hEah+OSvW5urjAg1ZFqTK09hFVf8KBPOVsPMSOe4= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 09/54] v4l2: v4l2_camera: Remove repated index checks Date: Mon, 29 Jun 2026 18:29:32 +0200 Message-ID: <20260629163017.863145-10-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Check only once if the buffer index is valid. Signed-off-by: Barnabás Pőcze --- src/v4l2/v4l2_camera_proxy.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index 03cd4810cc..b4f06c1c51 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -582,8 +582,7 @@ int V4L2CameraProxy::vidioc_querybuf(V4L2CameraFile *file, struct v4l2_buffer *a if (arg->index >= bufferCount_) return -EINVAL; - if (!validateBufferType(arg->type) || - arg->index >= bufferCount_) + if (!validateBufferType(arg->type)) return -EINVAL; updateBuffers(); @@ -641,8 +640,7 @@ int V4L2CameraProxy::vidioc_qbuf(V4L2CameraFile *file, struct v4l2_buffer *arg) return -EBUSY; if (!validateBufferType(arg->type) || - !validateMemoryType(arg->memory) || - arg->index >= bufferCount_) + !validateMemoryType(arg->memory)) return -EINVAL; int ret = vcam_->qbuf(arg->index); From patchwork Mon Jun 29 16:29:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27089 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 C6D35C3261 for ; Mon, 29 Jun 2026 16:30:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 644CD65F80; Mon, 29 Jun 2026 18:30:38 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="pEvNkkSr"; 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 10A0B65F30 for ; Mon, 29 Jun 2026 18:30:23 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E1E8E12D6 for ; Mon, 29 Jun 2026 18:29:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750580; bh=aan4wQ65l6eE6m4pO2bt+MtuqPUHjFp7LdA2bFqlQ+s=; h=From:To:Subject:Date:In-Reply-To:References:From; b=pEvNkkSrEz/8UsxcoQpgDc4CnPvukMrp58FeE9IlH91/f/RKuo/QQc2vGfzFJe7AF XllDChZWhyNGDVATNy2+qjaXzDj9ba9xRQBsW9YI87o8XgC4DXgPMI+vzdYM5IE9IT aNExzt0Tu83MIlGafkUr52stTcbLWBvrabOPMGZg= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 10/54] v4l2: v4l2_camera_proxy: Remove `bufferCount_` Date: Mon, 29 Jun 2026 18:29:33 +0200 Message-ID: <20260629163017.863145-11-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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 field always has the same value as `buffers_.size()`, so use that. Signed-off-by: Barnabás Pőcze --- src/v4l2/v4l2_camera_proxy.cpp | 22 ++++++++++------------ src/v4l2/v4l2_camera_proxy.h | 1 - 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index b4f06c1c51..94c0006cf3 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -41,7 +41,7 @@ LOG_DECLARE_CATEGORY(V4L2Compat) V4L2CameraProxy::V4L2CameraProxy(unsigned int index, std::shared_ptr camera) - : refcount_(0), index_(index), bufferCount_(0), currentBuf_(0), + : refcount_(0), index_(index), currentBuf_(0), vcam_(std::make_unique(camera)), owner_(nullptr) { querycap(camera); @@ -393,7 +393,7 @@ int V4L2CameraProxy::vidioc_s_fmt(V4L2CameraFile *file, struct v4l2_format *arg) Size size(arg->fmt.pix.width, arg->fmt.pix.height); V4L2PixelFormat v4l2Format = V4L2PixelFormat(arg->fmt.pix.pixelformat); ret = vcam_->configure(&streamConfig_, size, v4l2Format.toPixelFormat(), - bufferCount_); + buffers_.size()); if (ret < 0) return -EINVAL; @@ -495,7 +495,6 @@ void V4L2CameraProxy::freeBuffers() { vcam_->freeBuffers(); buffers_.clear(); - bufferCount_ = 0; } int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuffers *arg) @@ -533,7 +532,7 @@ int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf return 0; } - if (bufferCount_ > 0) + if (!buffers_.empty()) freeBuffers(); Size size(v4l2PixFormat_.width, v4l2PixFormat_.height); @@ -546,7 +545,6 @@ int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf setFmtFromConfig(streamConfig_); arg->count = streamConfig_.bufferCount; - bufferCount_ = arg->count; ret = vcam_->allocBuffers(arg->count); if (ret < 0) { @@ -579,7 +577,7 @@ int V4L2CameraProxy::vidioc_querybuf(V4L2CameraFile *file, struct v4l2_buffer *a LOG(V4L2Compat, Debug) << "[" << file->description() << "] " << __func__ << "()"; - if (arg->index >= bufferCount_) + if (arg->index >= buffers_.size()) return -EINVAL; if (!validateBufferType(arg->type)) @@ -601,7 +599,7 @@ int V4L2CameraProxy::vidioc_prepare_buf(V4L2CameraFile *file, struct v4l2_buffer if (!hasOwnership(file)) return -EBUSY; - if (arg->index >= bufferCount_) + if (arg->index >= buffers_.size()) return -EINVAL; if (arg->flags & V4L2_BUF_FLAG_REQUEST_FD) @@ -630,7 +628,7 @@ int V4L2CameraProxy::vidioc_qbuf(V4L2CameraFile *file, struct v4l2_buffer *arg) << "[" << file->description() << "] " << __func__ << "(index=" << arg->index << ")"; - if (arg->index >= bufferCount_) + if (arg->index >= buffers_.size()) return -EINVAL; if (buffers_[arg->index].flags & V4L2_BUF_FLAG_QUEUED) @@ -660,7 +658,7 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg, LOG(V4L2Compat, Debug) << "[" << file->description() << "] " << __func__ << "()"; - if (arg->index >= bufferCount_) + if (arg->index >= buffers_.size()) return -EINVAL; if (!hasOwnership(file)) @@ -695,7 +693,7 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg, buf.length = sizeimage_; *arg = buf; - currentBuf_ = (currentBuf_ + 1) % bufferCount_; + currentBuf_ = (currentBuf_ + 1) % buffers_.size(); uint64_t data; int ret = ::read(file->efd(), &data, sizeof(data)); @@ -717,7 +715,7 @@ int V4L2CameraProxy::vidioc_expbuf(V4L2CameraFile *file, struct v4l2_exportbuffe if (!validateBufferType(arg->type)) return -EINVAL; - if (arg->index >= bufferCount_) + if (arg->index >= buffers_.size()) return -EINVAL; if (arg->flags & ~(O_CLOEXEC | O_ACCMODE)) @@ -737,7 +735,7 @@ int V4L2CameraProxy::vidioc_streamon(V4L2CameraFile *file, int *arg) LOG(V4L2Compat, Debug) << "[" << file->description() << "] " << __func__ << "()"; - if (bufferCount_ == 0) + if (buffers_.empty()) return -EINVAL; if (!validateBufferType(*arg)) diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h index 5aa352c36f..6ef23fd82c 100644 --- a/src/v4l2/v4l2_camera_proxy.h +++ b/src/v4l2/v4l2_camera_proxy.h @@ -80,7 +80,6 @@ private: unsigned int index_; libcamera::StreamConfiguration streamConfig_; - unsigned int bufferCount_; unsigned int currentBuf_; unsigned int sizeimage_; From patchwork Mon Jun 29 16:29:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27090 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 5CCEDC3261 for ; Mon, 29 Jun 2026 16:30:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C58DC65F84; Mon, 29 Jun 2026 18:30:40 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cW4UpPIC"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5DEE565F37 for ; Mon, 29 Jun 2026 18:30:23 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 21EAE8D4; Mon, 29 Jun 2026 18:29:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750580; bh=r3Ov2KlKaxR7pacYvNpNxeN12yMks/mdafjXn3FC/mA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cW4UpPICUqDu943Gtm5G3j3kBQq3agO7JQIumTWAFcgGeHP4GyGhMVQFXxLLHANx/ oh53JX9IJQNsSei7Kk95EJCBs48dfRYpGy37QcCd+Ml+RcAxVh0UaBx1pJHByQUg0c MSHoTNSaOc03VnxmIC4C9kYSxhbHbVr+7/ewjsX8= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi Subject: [RFC PATCH v1 11/54] v4l2: v4l2_camera: Use actually allocated buffer count Date: Mon, 29 Jun 2026 18:29:34 +0200 Message-ID: <20260629163017.863145-12-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Make `V4L2Camera::allocBuffers()` simply create as many requests as the number of buffers allocated instead of taking it as an argument. The two should be the same, so no functional changes intended. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi --- src/v4l2/v4l2_camera.cpp | 8 +++++--- src/v4l2/v4l2_camera.h | 2 +- src/v4l2/v4l2_camera_proxy.cpp | 10 +++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index 648578c22b..75428b8adc 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -154,7 +154,7 @@ int V4L2Camera::validateConfiguration(const PixelFormat &pixelFormat, return 0; } -int V4L2Camera::allocBuffers(unsigned int count) +int V4L2Camera::allocBuffers() { Stream *stream = config_->at(0).stream(); @@ -162,7 +162,9 @@ int V4L2Camera::allocBuffers(unsigned int count) if (ret < 0) return ret; - for (unsigned int i = 0; i < count; i++) { + const auto &buffers = bufferAllocator_->buffers(stream); + + for (size_t i = 0; i < buffers.size(); i++) { std::unique_ptr request = camera_->createRequest(i); if (!request) { requestPool_.clear(); @@ -171,7 +173,7 @@ int V4L2Camera::allocBuffers(unsigned int count) requestPool_.push_back(std::move(request)); } - return ret; + return buffers.size(); } void V4L2Camera::freeBuffers() diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h index 1528f9aad8..8a58169d89 100644 --- a/src/v4l2/v4l2_camera.h +++ b/src/v4l2/v4l2_camera.h @@ -54,7 +54,7 @@ public: libcamera::ControlList &controls() { return controls_; } const libcamera::ControlInfoMap &controlInfo() { return camera_->controls(); } - int allocBuffers(unsigned int count); + int allocBuffers(); void freeBuffers(); int getBufferFd(unsigned int index); diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index 94c0006cf3..ee44767bd3 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -542,16 +542,16 @@ int V4L2CameraProxy::vidioc_reqbufs(V4L2CameraFile *file, struct v4l2_requestbuf if (ret < 0) return -EINVAL; - setFmtFromConfig(streamConfig_); - - arg->count = streamConfig_.bufferCount; - - ret = vcam_->allocBuffers(arg->count); + ret = vcam_->allocBuffers(); if (ret < 0) { arg->count = 0; return ret; } + arg->count = ret; + + setFmtFromConfig(streamConfig_); + buffers_.resize(arg->count); for (unsigned int i = 0; i < arg->count; i++) { struct v4l2_buffer buf = {}; From patchwork Mon Jun 29 16:29:35 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27091 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 D0DDDC3261 for ; Mon, 29 Jun 2026 16:30:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2889F65F82; Mon, 29 Jun 2026 18:30:43 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="iGzZ79M9"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 977CC65F39 for ; Mon, 29 Jun 2026 18:30:23 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 60B13E91; Mon, 29 Jun 2026 18:29:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750580; bh=tnSy/eZmIIF5YrJtuFfnYAzv1u7FY/Wjzbz6Ecb77Us=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iGzZ79M92UDDcFQibz8ZKGWkzqLtsXar5p8u5F901qHtb8d1smE4DdLpach9B1IRk gPbFGa05o1wfTP2ukmm77a9aF50LLWrTyeKYvKOtV/LLL+0hiGOFnFv/4fTvBytHNS ccWmTvKerdPj1KC90Asxk3vfrbVvu5rjyOi/waMk= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , Laurent Pinchart Subject: [RFC PATCH v1 12/54] v4l2: v4l2_camera: Use buffer cookie for indexing Date: Mon, 29 Jun 2026 18:29:35 +0200 Message-ID: <20260629163017.863145-13-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Use the buffer cookie to store the index of the buffer instead of relying on the 1-to-1 association between requests and buffers, which will be broken by the split of requests and buffers. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/v4l2/v4l2_camera.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index 75428b8adc..7dd0ea1ef9 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -87,7 +87,7 @@ void V4L2Camera::requestComplete(Request *request) /* We only have one stream at the moment. */ bufferLock_.lock(); FrameBuffer *buffer = request->buffers().begin()->second; - completedBuffers_.emplace_back(request->cookie(), buffer->metadata()); + completedBuffers_.emplace_back(buffer->cookie(), buffer->metadata()); bufferLock_.unlock(); uint64_t data = 1; @@ -171,6 +171,8 @@ int V4L2Camera::allocBuffers() return -ENOMEM; } requestPool_.push_back(std::move(request)); + + buffers[i]->setCookie(i); } return buffers.size(); From patchwork Mon Jun 29 16:29:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27093 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 45064C3261 for ; Mon, 29 Jun 2026 16:31:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2A3E465F70; Mon, 29 Jun 2026 18:30:46 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="l2xXtJLs"; 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 D861865F3B for ; Mon, 29 Jun 2026 18:30:23 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A32D18D4; Mon, 29 Jun 2026 18:29:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750580; bh=LqtsnaMtOlhRDgFmn13fgnQAF7gGluEBp5g0nxaUHuw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l2xXtJLsB39aH3YV7H2abCYJDo14tqk6UFjfFrvXPo1/JVpVujIutMDMHBMxpUOD8 3qk8yFDWCe99J6qrl/jlz+tPGMr9U8ALM5rd5IFy571ZsxxqB8cWy4iqlhS46/fUpE f01dZIAxgxIxcKHCJhE6BaXN4Vs7YnZLH916JkXw= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , Paul Elder Subject: [RFC PATCH v1 13/54] v4l2: v4l2_camera: Rename `Buffer` to `CompletedBuffer` Date: Mon, 29 Jun 2026 18:29:36 +0200 Message-ID: <20260629163017.863145-14-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" This expresses the meaning better. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder --- src/v4l2/v4l2_camera.cpp | 2 +- src/v4l2/v4l2_camera.h | 8 ++++---- src/v4l2/v4l2_camera_proxy.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index 7dd0ea1ef9..e72b73a22a 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -68,7 +68,7 @@ void V4L2Camera::unbind() efd_ = -1; } -std::vector V4L2Camera::completedBuffers() +std::vector V4L2Camera::completedBuffers() { MutexLocker lock(bufferLock_); std::vector v(std::move_iterator(completedBuffers_.begin()), diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h index 8a58169d89..1d90eb43e4 100644 --- a/src/v4l2/v4l2_camera.h +++ b/src/v4l2/v4l2_camera.h @@ -23,8 +23,8 @@ class V4L2Camera { public: - struct Buffer { - Buffer(unsigned int index, const libcamera::FrameMetadata &data) + struct CompletedBuffer { + CompletedBuffer(unsigned int index, const libcamera::FrameMetadata &data) : index_(index), data_(data) { } @@ -41,7 +41,7 @@ public: void bind(int efd); void unbind(); - std::vector completedBuffers() LIBCAMERA_TSA_EXCLUDES(bufferLock_); + std::vector completedBuffers() LIBCAMERA_TSA_EXCLUDES(bufferLock_); int configure(libcamera::StreamConfiguration *streamConfigOut, const libcamera::Size &size, @@ -85,7 +85,7 @@ private: std::vector> requestPool_; std::deque pendingRequests_; - std::deque completedBuffers_ + std::deque completedBuffers_ LIBCAMERA_TSA_GUARDED_BY(bufferLock_); int efd_; diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index ee44767bd3..02b238c81b 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -243,8 +243,8 @@ void V4L2CameraProxy::querycap(std::shared_ptr camera) void V4L2CameraProxy::updateBuffers() { - std::vector completedBuffers = vcam_->completedBuffers(); - for (const V4L2Camera::Buffer &buffer : completedBuffers) { + std::vector completedBuffers = vcam_->completedBuffers(); + for (const V4L2Camera::CompletedBuffer &buffer : completedBuffers) { const FrameMetadata &fmd = buffer.data_; struct v4l2_buffer &buf = buffers_[buffer.index_]; From patchwork Mon Jun 29 16:29:37 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27092 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 4360DC3261 for ; Mon, 29 Jun 2026 16:30:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5AD3B65F43; Mon, 29 Jun 2026 18:30:45 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="r4xXrRYc"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2DE7F65F3C for ; Mon, 29 Jun 2026 18:30:24 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E54C2E91; Mon, 29 Jun 2026 18:29:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750581; bh=/I+305mhXmeCxdVs2UFxxx9WQBByNicLPjGO++BMevY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r4xXrRYcSasJuXzXkGjIXiF9RO2r7AWHCqNQC3owlPBhmKhImboLMJosyxUkCNMsX GmCjALX/uWq7Tpdp5mPpKrwW22pKcr8LwnHKJl/bBRix3VqngczG6BlKwATUs//A8q 5SMb8iAC6Pl/cut4piARHj4sguTHlN7Ag/00cvP4= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , Laurent Pinchart , Paul Elder Subject: [RFC PATCH v1 14/54] v4l2: v4l2_camera: Always clear pending requests Date: Mon, 29 Jun 2026 18:29:37 +0200 Message-ID: <20260629163017.863145-15-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Clear the list of pending requests regardless whether the camera is running or not. The list should only contain entries when `!isRunning_`, in which case it was not cleared previously. Consider the following scenario: * STREAMOFF * QBUF(10) * STREAMOFF // at this point buffer 10 should be dequeued; // but `pendingRequests_` would still have the request // that was added due to QBUF * QBUF(10) // `pendingRequests_` would have the same requests twice * STREAMON // the same request would be tried to be queued twice Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Paul Elder --- src/v4l2/v4l2_camera.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index e72b73a22a..8c7de8e92b 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -226,6 +226,8 @@ int V4L2Camera::streamOn() int V4L2Camera::streamOff() { + pendingRequests_.clear(); + if (!isRunning_) { for (std::unique_ptr &req : requestPool_) req->reuse(); @@ -233,8 +235,6 @@ int V4L2Camera::streamOff() return 0; } - pendingRequests_.clear(); - int ret = camera_->stop(); if (ret < 0) return ret == -EACCES ? -EBUSY : ret; From patchwork Mon Jun 29 16:29:38 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27094 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 BC389C3261 for ; Mon, 29 Jun 2026 16:31:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A964165F35; Mon, 29 Jun 2026 18:30:47 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="mV3ZwC15"; 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 6DB6965F3D for ; Mon, 29 Jun 2026 18:30:24 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3AB5E1044 for ; Mon, 29 Jun 2026 18:29:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750581; bh=Y/1MYfy85QlfUMD+IhTKG4vHPwL0j8jsvwzEosEwqpM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=mV3ZwC15Hh9ULDb+1kYLA2PCvyrZf/6L/bC2VFdHQs1RsaiWQ+wc6llbEjzg54yh7 IcO8yLvzCPR1FtNDQTsqvgHxifqe+FJJs62auR1C2wzKnCjVIECAqb/R11D+pTB9AD 5zXmFx9RhchMgGNVPkqas1gSDomig3aY5UwEbXqs= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 15/54] v4l2: v4l2_camera: Clear completed requests when stopping Date: Mon, 29 Jun 2026 18:29:38 +0200 Message-ID: <20260629163017.863145-16-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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 queue `completedBuffers_` keeps track of the completed buffers for servicing `VIDIOC_DQBUF` calls. It should be cleared when the streaming is stopped otherwise after the next startup stale data might be used. Signed-off-by: Barnabás Pőcze --- src/v4l2/v4l2_camera.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index 8c7de8e92b..99109e93af 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -242,6 +242,7 @@ int V4L2Camera::streamOff() { MutexLocker locker(bufferMutex_); isRunning_ = false; + completedBuffers_.clear(); } bufferCV_.notify_all(); From patchwork Mon Jun 29 16:29:39 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27095 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 226A6C3261 for ; Mon, 29 Jun 2026 16:31:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DDDE265F59; Mon, 29 Jun 2026 18:30:50 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Z9YK/y+r"; 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 AF0AC65F34 for ; Mon, 29 Jun 2026 18:30:24 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7C14112D6; Mon, 29 Jun 2026 18:29:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750581; bh=J9NuhigoP/enSAc70xDw/MeY3GU2o9GiuohE9V5aP10=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z9YK/y+rzdfco2INe9RZPsbzpULFOMD065GwB8IjSceUN1rn0aZjelxCRCOLub1KB rghRgS3W8L/nRC5ztyRkAYE5n7IF3YeoFQjCaYDJTWoM8UUU91fOhEYswmJ3gLvO4L 6HU/PZFTIvEUEdUsDu0qCI8RXecfb57yxqpvpiIA= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Paul Elder Subject: [RFC PATCH v1 16/54] v4l2: v4l2_camera: Provide buffers one by one Date: Mon, 29 Jun 2026 18:29:39 +0200 Message-ID: <20260629163017.863145-17-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Instead of processing a set of buffers at a time and cycling through the buffers using `V4L2CameraProxy::currentBuf_`, add a new function to query just the least recently completed buffer and use that to service `VIDIOC_DQBUF`. This ensures that the reported index will denote the buffer that was actually completed after the request-buffer split. Signed-off-by: Barnabás Pőcze Reviewed-by: Paul Elder --- src/v4l2/v4l2_camera.cpp | 62 ++++++++++--------------- src/v4l2/v4l2_camera.h | 13 ++---- src/v4l2/v4l2_camera_proxy.cpp | 84 +++++++++++++++++----------------- src/v4l2/v4l2_camera_proxy.h | 2 - 4 files changed, 69 insertions(+), 92 deletions(-) diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index 99109e93af..aae9fae68c 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -20,7 +20,7 @@ LOG_DECLARE_CATEGORY(V4L2Compat) V4L2Camera::V4L2Camera(std::shared_ptr camera) : camera_(camera), controls_(controls::controls), isRunning_(false), - efd_(-1), bufferAvailableCount_(0) + efd_(-1) { camera_->requestCompleted.connect(this, &V4L2Camera::requestComplete); } @@ -68,38 +68,25 @@ void V4L2Camera::unbind() efd_ = -1; } -std::vector V4L2Camera::completedBuffers() -{ - MutexLocker lock(bufferLock_); - std::vector v(std::move_iterator(completedBuffers_.begin()), - std::move_iterator(completedBuffers_.end())); - - completedBuffers_.clear(); - - return v; -} - void V4L2Camera::requestComplete(Request *request) { if (request->status() == Request::RequestCancelled) return; /* We only have one stream at the moment. */ - bufferLock_.lock(); - FrameBuffer *buffer = request->buffers().begin()->second; - completedBuffers_.emplace_back(buffer->cookie(), buffer->metadata()); - bufferLock_.unlock(); - - uint64_t data = 1; - int ret = ::write(efd_, &data, sizeof(data)); - if (ret != sizeof(data)) - LOG(V4L2Compat, Error) << "Failed to signal eventfd POLLIN"; - - request->reuse(); { MutexLocker locker(bufferMutex_); - bufferAvailableCount_++; + FrameBuffer *buffer = request->buffers().begin()->second; + completedBuffers_.emplace_back(buffer->cookie(), buffer->metadata()); + + uint64_t data = 1; + int ret = ::write(efd_, &data, sizeof(data)); + if (ret != sizeof(data)) + LOG(V4L2Compat, Error) << "Failed to signal eventfd POLLIN"; + + request->reuse(); } + bufferCV_.notify_all(); } @@ -281,24 +268,23 @@ int V4L2Camera::qbuf(unsigned int index) return 0; } -void V4L2Camera::waitForBufferAvailable() +std::optional V4L2Camera::nextBuffer(bool wait) { MutexLocker locker(bufferMutex_); - bufferCV_.wait(locker, [&]() LIBCAMERA_TSA_REQUIRES(bufferMutex_) { - return bufferAvailableCount_ >= 1 || !isRunning_; - }); - if (isRunning_) - bufferAvailableCount_--; -} -bool V4L2Camera::isBufferAvailable() -{ - MutexLocker locker(bufferMutex_); - if (bufferAvailableCount_ < 1) - return false; + if (wait) { + bufferCV_.wait(locker, [&]() LIBCAMERA_TSA_REQUIRES(bufferMutex_) { + return !completedBuffers_.empty() || !isRunning_; + }); + } + + if (!isRunning_) + return {}; + + auto buffer = std::move(completedBuffers_.front()); + completedBuffers_.pop_front(); - bufferAvailableCount_--; - return true; + return buffer; } bool V4L2Camera::isRunning() diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h index 1d90eb43e4..06e37077b2 100644 --- a/src/v4l2/v4l2_camera.h +++ b/src/v4l2/v4l2_camera.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -41,8 +42,6 @@ public: void bind(int efd); void unbind(); - std::vector completedBuffers() LIBCAMERA_TSA_EXCLUDES(bufferLock_); - int configure(libcamera::StreamConfiguration *streamConfigOut, const libcamera::Size &size, const libcamera::PixelFormat &pixelformat, @@ -63,14 +62,12 @@ public: int qbuf(unsigned int index); - void waitForBufferAvailable() LIBCAMERA_TSA_EXCLUDES(bufferMutex_); - bool isBufferAvailable() LIBCAMERA_TSA_EXCLUDES(bufferMutex_); + std::optional nextBuffer(bool wait) LIBCAMERA_TSA_EXCLUDES(bufferMutex_); bool isRunning(); private: - void requestComplete(libcamera::Request *request) - LIBCAMERA_TSA_EXCLUDES(bufferLock_); + void requestComplete(libcamera::Request *request); std::shared_ptr camera_; std::unique_ptr config_; @@ -79,18 +76,16 @@ private: bool isRunning_; - libcamera::Mutex bufferLock_; std::unique_ptr bufferAllocator_; std::vector> requestPool_; std::deque pendingRequests_; std::deque completedBuffers_ - LIBCAMERA_TSA_GUARDED_BY(bufferLock_); + LIBCAMERA_TSA_GUARDED_BY(bufferMutex_); int efd_; libcamera::Mutex bufferMutex_; libcamera::ConditionVariable bufferCV_; - unsigned int bufferAvailableCount_ LIBCAMERA_TSA_GUARDED_BY(bufferMutex_); }; diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp index 02b238c81b..53ab0f2f5c 100644 --- a/src/v4l2/v4l2_camera_proxy.cpp +++ b/src/v4l2/v4l2_camera_proxy.cpp @@ -39,9 +39,37 @@ using namespace std::literals::chrono_literals; LOG_DECLARE_CATEGORY(V4L2Compat) +namespace { + +void updateBuffer(v4l2_buffer &buf, const FrameMetadata &fmd) +{ + switch (fmd.status) { + case FrameMetadata::FrameSuccess: + buf.bytesused = std::accumulate(fmd.planes().begin(), + fmd.planes().end(), 0, + [](unsigned int total, const auto &plane) { + return total + plane.bytesused; + }); + buf.field = V4L2_FIELD_NONE; + buf.timestamp.tv_sec = fmd.timestamp / 1000000000; + buf.timestamp.tv_usec = (fmd.timestamp / 1000) % 1000000; + buf.sequence = fmd.sequence; + + buf.flags |= V4L2_BUF_FLAG_DONE; + break; + case FrameMetadata::FrameError: + buf.flags |= V4L2_BUF_FLAG_ERROR; + break; + default: + break; + } +} + +} /* namespace */ + V4L2CameraProxy::V4L2CameraProxy(unsigned int index, std::shared_ptr camera) - : refcount_(0), index_(index), currentBuf_(0), + : refcount_(0), index_(index), vcam_(std::make_unique(camera)), owner_(nullptr) { querycap(camera); @@ -241,36 +269,6 @@ void V4L2CameraProxy::querycap(std::shared_ptr camera) memset(capabilities_.reserved, 0, sizeof(capabilities_.reserved)); } -void V4L2CameraProxy::updateBuffers() -{ - std::vector completedBuffers = vcam_->completedBuffers(); - for (const V4L2Camera::CompletedBuffer &buffer : completedBuffers) { - const FrameMetadata &fmd = buffer.data_; - struct v4l2_buffer &buf = buffers_[buffer.index_]; - - switch (fmd.status) { - case FrameMetadata::FrameSuccess: - buf.bytesused = std::accumulate(fmd.planes().begin(), - fmd.planes().end(), 0, - [](unsigned int total, const auto &plane) { - return total + plane.bytesused; - }); - buf.field = V4L2_FIELD_NONE; - buf.timestamp.tv_sec = fmd.timestamp / 1000000000; - buf.timestamp.tv_usec = (fmd.timestamp / 1000) % 1000000; - buf.sequence = fmd.sequence; - - buf.flags |= V4L2_BUF_FLAG_DONE; - break; - case FrameMetadata::FrameError: - buf.flags |= V4L2_BUF_FLAG_ERROR; - break; - default: - break; - } - } -} - int V4L2CameraProxy::vidioc_querycap(V4L2CameraFile *file, struct v4l2_capability *arg) { LOG(V4L2Compat, Debug) @@ -583,8 +581,6 @@ int V4L2CameraProxy::vidioc_querybuf(V4L2CameraFile *file, struct v4l2_buffer *a if (!validateBufferType(arg->type)) return -EINVAL; - updateBuffers(); - *arg = buffers_[arg->index]; return 0; @@ -671,30 +667,34 @@ int V4L2CameraProxy::vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg, !validateMemoryType(arg->memory)) return -EINVAL; + std::optional b; + if (!file->nonBlocking()) { lock->unlock(); - vcam_->waitForBufferAvailable(); + b = vcam_->nextBuffer(true); lock->lock(); - } else if (!vcam_->isBufferAvailable()) - return -EAGAIN; + } else { + b = vcam_->nextBuffer(false); + } /* * We need to check here again in case stream was turned off while we - * were blocked on waitForBufferAvailable(). + * were blocked in nextBuffer(). */ if (!vcam_->isRunning()) return -EINVAL; - updateBuffers(); + if (!b) + return -EAGAIN; + + struct v4l2_buffer &buf = buffers_[b->index_]; - struct v4l2_buffer &buf = buffers_[currentBuf_]; + updateBuffer(buf, b->data_); buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_PREPARED); buf.length = sizeimage_; *arg = buf; - currentBuf_ = (currentBuf_ + 1) % buffers_.size(); - uint64_t data; int ret = ::read(file->efd(), &data, sizeof(data)); if (ret != sizeof(data)) @@ -750,8 +750,6 @@ int V4L2CameraProxy::vidioc_streamon(V4L2CameraFile *file, int *arg) if (vcam_->isRunning()) return 0; - currentBuf_ = 0; - return vcam_->streamOn(); } diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h index 6ef23fd82c..38bfebf9d2 100644 --- a/src/v4l2/v4l2_camera_proxy.h +++ b/src/v4l2/v4l2_camera_proxy.h @@ -44,7 +44,6 @@ private: void querycap(std::shared_ptr camera); int tryFormat(struct v4l2_format *arg); enum v4l2_priority maxPriority(); - void updateBuffers(); void freeBuffers(); int vidioc_querycap(V4L2CameraFile *file, struct v4l2_capability *arg); @@ -80,7 +79,6 @@ private: unsigned int index_; libcamera::StreamConfiguration streamConfig_; - unsigned int currentBuf_; unsigned int sizeimage_; struct v4l2_capability capabilities_; From patchwork Mon Jun 29 16:29:40 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27096 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 DEC96C3261 for ; Mon, 29 Jun 2026 16:31:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C1A0565F41; Mon, 29 Jun 2026 18:30:53 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ZExknirU"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E529165F40 for ; Mon, 29 Jun 2026 18:30:24 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B96471044 for ; Mon, 29 Jun 2026 18:29:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750581; bh=MyO/qqB3NL/584RoEf18An6u2t9CJLkRSA4sgRLZi3Y=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ZExknirUsat7q/iwUFiJG1UB87zsTMZl+UTsiavO10Q1KPCE1belmwLenrEpX+73o nI1SXbqE/g1K0PrtuG6ONExmN1tT9vS2Lilimutji2n69Z90/DyWl17StE9AE/8cff NViOm6+1tacgosJ4sfJlO0tYYTJAM5xhWs7pNBlU= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 17/54] test: fence: Disable temporarily Date: Mon, 29 Jun 2026 18:29:40 +0200 Message-ID: <20260629163017.863145-18-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Disable the test until the buffer pool interface is finalized. Signed-off-by: Barnabás Pőcze --- test/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/meson.build b/test/meson.build index e4450625ee..b51bd6ef66 100644 --- a/test/meson.build +++ b/test/meson.build @@ -80,7 +80,7 @@ internal_tests = [ ] internal_non_parallel_tests = [ - {'name': 'fence', 'sources': ['fence.cpp']}, + # {'name': 'fence', 'sources': ['fence.cpp']}, {'name': 'mapped-buffer', 'sources': ['mapped-buffer.cpp']}, ] From patchwork Mon Jun 29 16:29:41 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27097 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 4A098C3261 for ; Mon, 29 Jun 2026 16:31:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D192165F48; Mon, 29 Jun 2026 18:30:55 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="N9O2Ndy5"; 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 238EE65F41 for ; Mon, 29 Jun 2026 18:30:25 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 023C98D4 for ; Mon, 29 Jun 2026 18:29:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750582; bh=CsaT+i0oyShur8yb1g7Oy/M68CtcBChxeQYfFmNsOX8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=N9O2Ndy5uTU/9/ozwkOVFIMKlrCqm9lY+iTdnGCvOYxd12erMcZf8yhPrlD0iA2Re GGTe3BB+lpdhMCaI3Let+hTa8P0IsSBK0XMIB4+fL5pGQBg/dqS2YECFNisWxnIe/1 4kdRfxntDneaetVGAsCUuuFRvtGU5R2UNQAsOBvc= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 18/54] libcamera: request: Remove `ReuseBuffers` Date: Mon, 29 Jun 2026 18:29:41 +0200 Message-ID: <20260629163017.863145-19-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Remove the implementation of the `ReuseBuffers` flag. With the split of requests and buffers, it is no longer that useful, and having it work in any reasonable capacity requires more compatibility code. For now only the implementation is removed. Signed-off-by: Barnabás Pőcze --- src/libcamera/request.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 022a97f169..b1a81e36ef 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -390,17 +390,12 @@ void Request::reuse(ReuseFlag flags) { LIBCAMERA_TRACEPOINT(request_reuse, this); - _d()->reset(); + if (flags) + LOG(Request, Fatal) << "NOT IMPLEMENTED"; - if (flags & ReuseBuffers) { - for (const auto &[stream, buffer] : bufferMap_) { - buffer->_d()->setRequest(this); - _d()->pending_.insert(buffer); - } - } else { - bufferMap_.clear(); - } + _d()->reset(); + bufferMap_.clear(); status_ = RequestPending; controls_.clear(); From patchwork Mon Jun 29 16:29:42 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27098 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 801D3C3261 for ; Mon, 29 Jun 2026 16:31:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 374FA65F4E; Mon, 29 Jun 2026 18:30:58 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="r+dqhxNS"; 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 5FDDB65F2A for ; Mon, 29 Jun 2026 18:30:25 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 35FF31044 for ; Mon, 29 Jun 2026 18:29:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750582; bh=i6QUviw1gSUZdOE9lYq+QkoZHCUpi+dBmjZE8ArEtxY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=r+dqhxNSG4j6UcsbizozS9wzlVuZYRAMymmzy87l2OgLhaQl1SD4ajQjj4ZAoKvYt Aa+AjRXy17ejbSqV9bhtSsPmeEufFbv+qT1/wp+l5Pi++QONrFjhW1ObcPCg+0DVjI 9ybLs1DPJDun4f9wH/Sd3CU9xoaltHefZU9WSiWk= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 19/54] libcamera: framebuffer: request(): Move to private type Date: Mon, 29 Jun 2026 18:29:42 +0200 Message-ID: <20260629163017.863145-20-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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 `request()` is of not much interest to normal applications, mainly because the request-buffer association is removed when the buffer completes. Therefore the only place where this can actually be used is in the `bufferCompleted` signal, but the request is already provided there by other means. So move the function into the associated `Private` type. Signed-off-by: Barnabás Pőcze --- Documentation/guides/pipeline-handler.rst | 8 ++++- include/libcamera/framebuffer.h | 1 - include/libcamera/internal/framebuffer.h | 2 ++ src/libcamera/framebuffer.cpp | 33 +++++++++----------- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 3 +- src/libcamera/pipeline/mali-c55/mali-c55.cpp | 2 +- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 4 +-- src/libcamera/pipeline/simple/simple.cpp | 15 ++++----- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 3 +- src/libcamera/pipeline/vimc/vimc.cpp | 2 +- src/libcamera/pipeline/virtual/virtual.cpp | 2 +- 11 files changed, 41 insertions(+), 34 deletions(-) diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst index b33d8b8574..2d2231eb68 100644 --- a/Documentation/guides/pipeline-handler.rst +++ b/Documentation/guides/pipeline-handler.rst @@ -1400,12 +1400,18 @@ code-base. void VividCameraData::bufferReady(FrameBuffer *buffer) { - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); pipe_->completeBuffer(request, buffer); pipe_->completeRequest(request); } +The following new include statements are needed for the above: + +.. code-block:: cpp + + #include "libcamera/internal/framebuffer.h" + Testing a pipeline handler ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/libcamera/framebuffer.h b/include/libcamera/framebuffer.h index 723525d052..3ac1609f56 100644 --- a/include/libcamera/framebuffer.h +++ b/include/libcamera/framebuffer.h @@ -63,7 +63,6 @@ public: virtual ~FrameBuffer() {} Span planes() const; - Request *request() const; const FrameMetadata &metadata() const; uint64_t cookie() const; diff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h index 67b090fc30..7e96100b6c 100644 --- a/include/libcamera/internal/framebuffer.h +++ b/include/libcamera/internal/framebuffer.h @@ -27,7 +27,9 @@ public: Private(Span planes, uint64_t cookie = 0); virtual ~Private(); + Request *request() const { return request_; } void setRequest(Request *request) { request_ = request; } + bool isContiguous() const { return isContiguous_; } Fence *fence() const { return fence_.get(); } diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index 6ea4d6ea21..4f23df6482 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -144,6 +144,21 @@ FrameBuffer::Private::~Private() { } +/** + * \fn FrameBuffer::Private::request() + * \brief Retrieve the request this buffer belongs to + * + * The intended callers of this function are buffer completion handlers that + * need to associate a buffer to the request it belongs to. + * + * A FrameBuffer is associated to a request by Request::addBuffer() and the + * association is valid until the buffer completes. The returned request + * pointer is valid only during that interval. + * + * \return The Request the FrameBuffer belongs to, or nullptr if the buffer is + * not associated with a request + */ + /** * \fn FrameBuffer::Private::setRequest() * \brief Set the request this buffer belongs to @@ -364,24 +379,6 @@ Span FrameBuffer::planes() const return _d()->planes_; } -/** - * \brief Retrieve the request this buffer belongs to - * - * The intended callers of this function are buffer completion handlers that - * need to associate a buffer to the request it belongs to. - * - * A FrameBuffer is associated to a request by Request::addBuffer() and the - * association is valid until the buffer completes. The returned request - * pointer is valid only during that interval. - * - * \return The Request the FrameBuffer belongs to, or nullptr if the buffer is - * not associated with a request - */ -Request *FrameBuffer::request() const -{ - return _d()->request_; -} - /** * \brief Retrieve the dynamic metadata * \return Dynamic metadata for the frame contained in the buffer diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index 5f15fbdc08..d3f152aa1e 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -24,6 +24,7 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_sensor.h" #include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/framebuffer.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/media_pipeline.h" #include "libcamera/internal/pipeline_handler.h" @@ -1124,7 +1125,7 @@ PipelineHandlerISI::Pipe *PipelineHandlerISI::pipeFromStream(ISICameraData *data void PipelineHandlerISI::bufferReady(FrameBuffer *buffer) { - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); /* Record the sensor's timestamp in the request metadata. */ ControlList &metadata = request->_d()->metadata(); diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index b30455683e..0c7b7ed370 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -1649,7 +1649,7 @@ void PipelineHandlerMaliC55::tryComplete(MaliC55FrameInfo *info, bool cancelled) void PipelineHandlerMaliC55::imageBufferReady(FrameBuffer *buffer) { - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); MaliC55FrameInfo *info = findFrameInfo(request); ASSERT(info); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 4f9c0aa741..0c1e5767b4 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1695,9 +1695,9 @@ void PipelineHandlerRkISP1::dewarpBufferReady(FrameBuffer *buffer) { ASSERT(activeCamera_); RkISP1CameraData *data = cameraData(activeCamera_); - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); - RkISP1FrameInfo *info = data->frameInfo_.find(buffer->request()); + RkISP1FrameInfo *info = data->frameInfo_.find(request); if (!info) return; diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index e26f438d9a..381f8db3ee 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -40,6 +40,7 @@ #include "libcamera/internal/delayed_controls.h" #include "libcamera/internal/device_enumerator.h" #include "libcamera/internal/formats.h" +#include "libcamera/internal/framebuffer.h" #include "libcamera/internal/global_configuration.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" @@ -887,7 +888,7 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) if (buffer->metadata().status != FrameMetadata::FrameSuccess) { if (!useConversion_ || rawStream_) { /* No conversion, just complete the request. */ - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); pipe->completeBuffer(request, buffer); SimpleFrameInfo *info = frameInfo_.find(request->sequence()); if (info) @@ -927,7 +928,7 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) * \todo The sensor timestamp should be better estimated by connecting * to the V4L2Device::frameStart signal if the platform provides it. */ - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); if (useConversion_ && !conversionQueue_.empty()) { const std::map &outputs = @@ -935,7 +936,7 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) if (!outputs.empty()) { FrameBuffer *outputBuffer = outputs.begin()->second; if (outputBuffer) - request = outputBuffer->request(); + request = outputBuffer->_d()->request(); } } @@ -960,8 +961,8 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer) else /* * request->sequence() cannot be retrieved from `buffer' inside - * queueBuffers because unique_ptr's make buffer->request() invalid - * already here. + * queueBuffers because unique_ptr's make buffer->_d()->request() + * invalid already here. */ swIsp_->queueBuffers(request->sequence(), buffer, conversionQueue_.front().outputs); @@ -1005,7 +1006,7 @@ void SimpleCameraData::conversionInputDone(FrameBuffer *buffer) { if (rawStream_) { /* Complete the input buffer as with raw-only processing. */ - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); if (pipe()->completeBuffer(request, buffer)) tryCompleteRequest(request); } else { @@ -1019,7 +1020,7 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer) SimplePipelineHandler *pipe = SimpleCameraData::pipe(); /* Complete the buffer and the request. */ - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); if (pipe->completeBuffer(request, buffer)) tryCompleteRequest(request); } diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 3435a76046..f8d49d9122 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -28,6 +28,7 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/framebuffer.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/request.h" @@ -892,7 +893,7 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info, void UVCCameraData::imageBufferReady(FrameBuffer *buffer) { - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); /* \todo Use the UVC metadata to calculate a more precise timestamp */ request->_d()->metadata().set(controls::SensorTimestamp, diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 99ae60785b..528022776e 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -601,7 +601,7 @@ void VimcCameraData::imageBufferReady(FrameBuffer *buffer) { PipelineHandlerVimc *pipe = static_cast(this->pipe()); - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); /* If the buffer is cancelled force a complete of the whole request. */ if (buffer->metadata().status == FrameMetadata::FrameCancelled) { diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index a7cd76e226..f9e2cecea3 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -452,7 +452,7 @@ bool PipelineHandlerVirtual::initFrameGenerator(Camera *camera) void PipelineHandlerVirtual::bufferCompleted(FrameBuffer *buffer) { - Request *request = buffer->request(); + Request *request = buffer->_d()->request(); if (completeBuffer(request, buffer)) completeRequest(request); From patchwork Mon Jun 29 16:29:43 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27100 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 C56A3C3261 for ; Mon, 29 Jun 2026 16:31:09 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5223B65F5D; Mon, 29 Jun 2026 18:31:04 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ULN9oESJ"; 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 953A265F35 for ; Mon, 29 Jun 2026 18:30:25 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6B7808D4 for ; Mon, 29 Jun 2026 18:29:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750582; bh=4/PLcbRs+8EHIOon+V3jxlyjcguVLwiBB0QOCOiWP3w=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ULN9oESJed7hs5pDqshUAAI5qPett158uwFfSRI7vKFB/yM1WK957HbPz8LR7GX8q XZT47C62TSKt6H3oS9FW91Iyh2ekXAi0y/PfmbbrbMIwj9/wq+3I12SUSj6+OvJ+ZJ K9w6DVSYlMUhhXIveNbYpwkUvlZsbf/Qi5gRgO2I= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 20/54] libcamera: framebuffer: Store associated Stream Date: Mon, 29 Jun 2026 18:29:43 +0200 Message-ID: <20260629163017.863145-21-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Store the Stream of the Camera that will capture data into the buffer. Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/framebuffer.h | 4 ++++ src/libcamera/framebuffer.cpp | 8 ++++++++ src/libcamera/request.cpp | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/include/libcamera/internal/framebuffer.h b/include/libcamera/internal/framebuffer.h index 7e96100b6c..466ddc1b73 100644 --- a/include/libcamera/internal/framebuffer.h +++ b/include/libcamera/internal/framebuffer.h @@ -19,6 +19,8 @@ namespace libcamera { +class Stream; + class FrameBuffer::Private : public Extensible::Private { LIBCAMERA_DECLARE_PUBLIC(FrameBuffer) @@ -39,6 +41,8 @@ public: FrameMetadata &metadata() { return metadata_; } + const Stream *stream_ = nullptr; + private: std::vector planes_; FrameMetadata metadata_; diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index 4f23df6482..baa298a8e3 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -232,6 +232,14 @@ FrameBuffer::Private::~Private() * \brief Retrieve the dynamic metadata * \return Dynamic metadata for the frame contained in the buffer */ + +/** + * \var FrameBuffer::Private::stream_ + * \brief The Stream the buffer belongs to + * + * This member designates the Stream of the Camera that the buffer belongs + * to at the moment. + */ #endif /* __DOXYGEN_PUBLIC__ */ /** diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index b1a81e36ef..278d993445 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -107,10 +107,13 @@ bool Request::Private::completeBuffer(FrameBuffer *buffer) Request *request = LIBCAMERA_O_PTR(); camera_->bufferCompleted.emit(request, buffer); + ASSERT(request->findBuffer(buffer->_d()->stream_) == buffer); + int ret = pending_.erase(buffer); ASSERT(ret == 1); buffer->_d()->setRequest(nullptr); + buffer->_d()->stream_ = nullptr; if (buffer->metadata().status == FrameMetadata::FrameCancelled) cancelled_ = true; @@ -147,6 +150,7 @@ void Request::Private::doCancelRequest() buffer->_d()->cancel(); camera_->bufferCompleted.emit(request, buffer); buffer->_d()->setRequest(nullptr); + buffer->_d()->stream_ = nullptr; } cancelled_ = true; @@ -495,6 +499,7 @@ int Request::addBuffer(const Stream *stream, FrameBuffer *buffer, } buffer->_d()->setRequest(this); + buffer->_d()->stream_ = stream; _d()->pending_.insert(buffer); if (fence && fence->isValid()) From patchwork Mon Jun 29 16:29:44 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27099 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 8BFFAC3261 for ; Mon, 29 Jun 2026 16:31:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5A42765F96; Mon, 29 Jun 2026 18:31:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Vzzh3iR/"; 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 CC90265F46 for ; Mon, 29 Jun 2026 18:30:25 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A363AE91 for ; Mon, 29 Jun 2026 18:29:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750582; bh=GSAt56pEicC5fChkWf1srdN1G08/7viSQOP33NdqEok=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Vzzh3iR/yFdI6Zg+qsYe9gpv4tWwrHjHLZCH/oB+KWnGwcZu8kGhKgqnpEMWiGbpq B3U1CurYTb5gCGaUCDDuXPmVUu+FcCwJQ5qPHtTbd7limFIw0rGC+E58WKp9WtXIIK 9dkxAQW76/r8u9m3SWHxsdIaDOZaJjDGcov9Qfyg= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 21/54] libcamera: camera: Add `StreamData` Date: Mon, 29 Jun 2026 18:29:44 +0200 Message-ID: <20260629163017.863145-22-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Add an internal `StreamData` type that contains private data about the streams of a camera. This currently replaces the separate `activeStreams_` `std::set`. The `streams_` member is not merged as that is exposed via `Camera::streams()`. Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/camera.h | 7 ++++++- src/libcamera/camera.cpp | 29 ++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h index 8a2e9ed589..43b6a6e4a2 100644 --- a/include/libcamera/internal/camera.h +++ b/include/libcamera/internal/camera.h @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -54,6 +55,10 @@ private: CameraRunning, }; + struct StreamData { + bool active = false; + }; + bool isAcquired() const; bool isRunning() const; int isAccessAllowed(State state, bool allowDisconnected = false, @@ -68,7 +73,7 @@ private: std::shared_ptr pipe_; std::string id_; std::set streams_; - std::set activeStreams_; + std::unordered_map streamData_; bool disconnected_; std::atomic state_; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 93b9e603dd..aa5682f9d7 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -934,6 +934,11 @@ Camera::Camera(std::unique_ptr d, const std::string &id, _d()->properties_.set(properties::PipelineHandler, _d()->pipe_->name()); _d()->streams_ = streams; _d()->validator_ = std::make_unique(this); + + for (const Stream *s : streams) { + [[maybe_unused]] auto [it, inserted] = _d()->streamData_.try_emplace(s); + ASSERT(inserted); + } } Camera::~Camera() @@ -969,10 +974,11 @@ int Camera::exportFrameBuffers(Stream *stream, if (ret < 0) return ret; - if (streams().find(stream) == streams().end()) + auto it = d->streamData_.find(stream); + if (it == d->streamData_.end()) return -EINVAL; - if (d->activeStreams_.find(stream) == d->activeStreams_.end()) + if (!it->second.active) return -EINVAL; return d->pipe_->invokeMethod(&PipelineHandler::exportFrameBuffers, @@ -1220,21 +1226,29 @@ int Camera::configure(CameraConfiguration *config) if (ret) return ret; - d->activeStreams_.clear(); + auto resetStreamData = [&] { + for (auto &[stream, data] : d->streamData_) + data.active = false; + }; + utils::scope_exit streamDataGuard(std::ref(resetStreamData)); + + resetStreamData(); for (const StreamConfiguration &cfg : *config) { Stream *stream = cfg.stream(); - if (!stream) { + auto it = d->streamData_.find(stream); + + if (it == d->streamData_.end() || it->second.active) { LOG(Camera, Fatal) << "Pipeline handler failed to update stream configuration"; - d->activeStreams_.clear(); return -EINVAL; } stream->configuration_ = cfg; - d->activeStreams_.insert(stream); + it->second.active = true; } d->setState(Private::CameraConfigured); + streamDataGuard.release(); return 0; } @@ -1364,7 +1378,8 @@ int Camera::queueRequest(Request *request) } for (const auto &[stream, buffer] : request->buffers()) { - if (d->activeStreams_.find(stream) == d->activeStreams_.end()) { + auto it = d->streamData_.find(stream); + if (it == d->streamData_.end() || !it->second.active) { LOG(Camera, Error) << "Invalid request"; return -EINVAL; } From patchwork Mon Jun 29 16:29:45 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27101 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 17712C3261 for ; Mon, 29 Jun 2026 16:31:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E34A965F8B; Mon, 29 Jun 2026 18:31:06 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="rkkJFwWP"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 09AA565F47 for ; Mon, 29 Jun 2026 18:30:26 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D81B28D4 for ; Mon, 29 Jun 2026 18:29:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750582; bh=YmL2Qa3dHGwYVUaS/614a+cslVnODZwWtg0th56KayI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=rkkJFwWPHuZx55kQxtvZsmXMbO15lJyijGFUZDVFIGDDyTT2YcPMjoRCth25dcX8U xCRgov8sOlwJRrmBi4i8S23Ba3DVw4pGdEPlfE/vxj5+1dRuwYRYnlSuPop+fpVFO2 aVwguBhAXnTh7Ee1IfTYXpzIGOLq03iVOSVMdZ2A= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 22/54] libcamera: camera: Add buffer pool Date: Mon, 29 Jun 2026 18:29:45 +0200 Message-ID: <20260629163017.863145-23-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Use the recently added `StreamData` to store a set of buffers for each stream. Introduce the `Camera::addBuffer()` method that can be used by an application to add buffers. Signed-off-by: Barnabás Pőcze --- include/libcamera/camera.h | 3 + include/libcamera/internal/camera.h | 15 ++++ include/libcamera/internal/pipeline_handler.h | 5 ++ src/libcamera/camera.cpp | 51 +++++++++++ src/libcamera/pipeline_handler.cpp | 88 +++++++++++++++++++ 5 files changed, 162 insertions(+) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 443116b588..471975a890 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -28,6 +28,7 @@ namespace libcamera { +class Fence; class FrameBuffer; class FrameBufferAllocator; class PipelineHandler; @@ -152,6 +153,8 @@ public: int start(const ControlList *controls = nullptr); int stop(); + int addBuffer(const Stream *stream, FrameBuffer *buffer, std::unique_ptr &&fence = {}); + private: LIBCAMERA_DISABLE_COPY(Camera) diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h index 43b6a6e4a2..6ba77eb882 100644 --- a/include/libcamera/internal/camera.h +++ b/include/libcamera/internal/camera.h @@ -15,14 +15,17 @@ #include #include #include +#include #include +#include #include namespace libcamera { class CameraControlValidator; +class Fence; class PipelineHandler; class Stream; @@ -57,6 +60,15 @@ private: struct StreamData { bool active = false; + std::vector buffers; + }; + + struct PendingFence { + EventNotifier notifier; + const Stream *stream; + FrameBuffer *buffer; + + PendingFence(const Stream *s, FrameBuffer *b); }; bool isAcquired() const; @@ -74,11 +86,14 @@ private: std::string id_; std::set streams_; std::unordered_map streamData_; + std::list pendingFences_; bool disconnected_; std::atomic state_; std::unique_ptr validator_; + + friend PipelineHandler; }; } /* namespace libcamera */ diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index cc52c6b045..81ec359981 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -27,6 +27,7 @@ class Camera; class CameraConfiguration; class DeviceEnumerator; class DeviceMatch; +class Fence; class FrameBuffer; class MediaDevice; class PipelineHandler; @@ -69,6 +70,10 @@ public: void completeRequest(Request *request); void cancelRequest(Request *request); + void addBuffer(Camera *camera, + const Stream *stream, FrameBuffer *buffer, + std::unique_ptr &&fence); + std::string configurationFile(const std::string &subdir, const std::string &name, bool silent = false) const; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index aa5682f9d7..31ab59e0b7 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -27,6 +27,7 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_controls.h" +#include "libcamera/internal/framebuffer.h" #include "libcamera/internal/pipeline_handler.h" #include "libcamera/internal/request.h" @@ -746,6 +747,13 @@ void Camera::Private::setState(State state) { state_.store(state, std::memory_order_release); } + +Camera::Private::PendingFence::PendingFence(const Stream *s, FrameBuffer *b) + : notifier(b->_d()->fence()->fd().get(), EventNotifier::Read), + stream(s), + buffer(b) +{ +} #endif /* __DOXYGEN_PUBLIC__ */ /** @@ -1061,6 +1069,9 @@ int Camera::release() d->pipe_->invokeMethod(&PipelineHandler::release, ConnectionTypeBlocking, this); + // \todo clear buffer pool + // \todo empty `pendingBuffers_` and report "cancelled" fences + d->setState(Private::CameraAvailable); return 0; @@ -1448,6 +1459,9 @@ int Camera::start(const ControlList *controls) * This function stops capturing and processing requests immediately. All * pending requests are cancelled and complete synchronously in an error state. * + * All buffers in the camera's buffer pool are returned via the Camera::bufferCompleted + * event synchronously with the \a request parameter equal to \a nullptr. + * * \context This function may be called in any camera state as defined in \ref * camera_operation, and shall be synchronized by the caller with other * functions that affect the camera state. If called when the camera isn't @@ -1486,6 +1500,43 @@ int Camera::stop() return 0; } +/** + * \fn Camera::addBuffer() + * \brief Add a buffer to buffer pool of the camera + * \param[in] stream The stream + * \param[in] buffer The buffer + * \param[in] fence The fence for \a buffer + * + * \context This function may only be called when the camera is + * in the Running state as defined in \ref camera_operation. + * + * \return 0 on success or a negative error code otherwise + * + * \internal + * \todo Add `addBuffers()` that accepts a list of (stream, buffer, fence) tuples. + */ +int Camera::addBuffer(const Stream *stream, FrameBuffer *buffer, std::unique_ptr &&fence) +{ + Private *const d = _d(); + + int ret = d->isAccessAllowed(Private::CameraRunning); + if (ret < 0) + return ret; + + auto it = d->streamData_.find(stream); + if (it == d->streamData_.end() || !it->second.active) + return -EINVAL; + if (!buffer) + return -EINVAL; + if (buffer->_d()->fence()) + return -EINVAL; + + d->pipe_->invokeMethod(&PipelineHandler::addBuffer, ConnectionTypeQueued, + this, stream, buffer, std::move(fence)); + + return 0; +} + /** * \brief Handle request completion and notify application * \param[in] request The request that has completed diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 99f35d1e42..54ef8296a4 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -22,6 +22,7 @@ #include "libcamera/internal/camera.h" #include "libcamera/internal/camera_manager.h" #include "libcamera/internal/device_enumerator.h" +#include "libcamera/internal/framebuffer.h" #include "libcamera/internal/media_device.h" #include "libcamera/internal/request.h" #include "libcamera/internal/tracepoints.h" @@ -394,6 +395,24 @@ void PipelineHandler::stop(Camera *camera) doQueueRequest(request); } + const auto returnBuffer = [&](FrameBuffer *buffer) { + ASSERT(!buffer->_d()->stream_); + buffer->_d()->cancel(); + camera->bufferCompleted.emit(nullptr, buffer); + }; + + for (auto &pf : data->pendingFences_) + returnBuffer(pf.buffer); + + data->pendingFences_.clear(); + + for (auto &[stream, streamData] : data->streamData_) { + for (FrameBuffer *buffer : streamData.buffers) + returnBuffer(buffer); + + streamData.buffers.clear(); + } + /* Make sure no requests are pending. */ ASSERT(data->queuedRequests_.empty()); ASSERT(data->waitingRequests_.empty()); @@ -611,6 +630,75 @@ void PipelineHandler::cancelRequest(Request *request) completeRequest(request); } +/** + * \fn PipelineHandler::addBuffer() + * \brief Add buffers to the buffer pool of the camera + * \param[in] camera The camera + * \param[in] stream The stream of \a camera + * \param[in] buffer The buffer + * \param[in] fence The fence for \a buffer + * + * \context This function may only be called from the CameraManager thread. + */ +void PipelineHandler::addBuffer(Camera *camera, + const Stream *stream, FrameBuffer *buffer, + std::unique_ptr &&fence) +{ + Camera::Private *const d = camera->_d(); + + auto it = d->streamData_.find(stream); + ASSERT(it != d->streamData_.end()); + + [[maybe_unused]] const auto checkUnique = [&] { + for (const auto &[_, data] : d->streamData_) { + for (const auto *b : data.buffers) { + if (b == buffer) + return false; + } + } + + for (const auto &pf : d->pendingFences_) { + if (pf.buffer == buffer) + return false; + + if (fence && fence->isValid()) { + if (pf.buffer->_d()->fence()->fd().get() == fence->fd().get()) + return false; + } + } + + return true; + }; + ASSERT(checkUnique() && "buffer or fence is already present in the pool"); + + if (fence && fence->isValid()) { + buffer->_d()->setFence(std::move(fence)); + + auto it2 = d->pendingFences_.emplace( + d->pendingFences_.end(), + stream, + buffer + ); + + LOG(Pipeline, Debug) + << "Waiting on fence:" << buffer->_d()->fence()->fd().get() + << " for stream:" << stream << " buffer:" << buffer; + + it2->notifier.activated.connect(this, [=] { + LOG(Pipeline, Debug) + << "Activated fence:" << it2->buffer->_d()->fence()->fd().get() + << " for stream:" << it2->stream << " buffer:" << it2->buffer; + + std::ignore = it2->buffer->releaseFence(); + it->second.buffers.push_back(it2->buffer); + d->pendingFences_.erase(it2); + /* Lambda is now destroy, no captured variable should be accessed. */ + }); + } else { + it->second.buffers.push_back(buffer); + } +} + /** * \brief Retrieve the absolute path to a platform configuration file * \param[in] subdir The pipeline handler specific subdirectory name From patchwork Mon Jun 29 16:29:46 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27102 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 42E76C3261 for ; Mon, 29 Jun 2026 16:31:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4D9DC65F5A; Mon, 29 Jun 2026 18:31:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ZLF6hAKB"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3E4CE65F48 for ; Mon, 29 Jun 2026 18:30:26 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 16F0AE91 for ; Mon, 29 Jun 2026 18:29:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750583; bh=PfZX+7AwvmbjHQf/FCMDuEMyKABil9jpmI84bEgektk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ZLF6hAKBM1Zy2yViEkJapMWTjSuMdXysd4zkwI7qijrDyjQ6GIVHeIpFKA8dgQHsb LRj4veJ38Jc4cjaDlVlY+Vq6lgQvAvq0LRhE0lrZurYC0EBwtkN7POQpXBNYAKmIgr 8+EQ3jI0H9pGqckomNFiS4CPpTSEeT1do1uh9PDM= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 23/54] libcamera: request: addBuffer(): Remove impl Date: Mon, 29 Jun 2026 18:29:46 +0200 Message-ID: <20260629163017.863145-24-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" With the separation of requests and buffers, this function will be removed. For now only the implementation is removed because: * there are many external users, and * not to hinder changing implementation details. Signed-off-by: Barnabás Pőcze --- src/libcamera/request.cpp | 62 +++------------------------------------ 1 file changed, 4 insertions(+), 58 deletions(-) diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 278d993445..8a3934add3 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -446,66 +446,12 @@ const ControlList &Request::metadata() const * \param[in] stream The stream the buffer belongs to * \param[in] buffer The FrameBuffer to add to the request * \param[in] fence The optional fence - * - * A reference to the buffer is stored in the request. The caller is responsible - * for ensuring that the buffer will remain valid until the request complete - * callback is called. - * - * A request can only contain one buffer per stream. If a buffer has already - * been added to the request for the same stream, this function returns -EEXIST. - * - * A Fence can be optionally associated with the \a buffer. - * - * When a valid Fence is provided to this function, \a fence is moved to \a - * buffer and this Request will only be queued to the device once the - * fences of all its buffers have been correctly signalled. Ownership of the - * fence will only be taken in case of success, otherwise the fence will - * be left unmodified. - * - * If the \a fence associated with \a buffer isn't signalled, the request will - * fail after a timeout. The buffer will still contain the fence, which - * applications must retrieve with FrameBuffer::releaseFence() before the buffer - * can be reused in another request. Attempting to add a buffer that still - * contains a fence to a request will result in this function returning -EEXIST. - * - * \sa FrameBuffer::releaseFence() - * - * \return 0 on success or a negative error code otherwise - * \retval -EEXIST The request already contains a buffer for the stream - * or the buffer still references a fence - * \retval -EINVAL The buffer does not reference a valid Stream */ -int Request::addBuffer(const Stream *stream, FrameBuffer *buffer, - std::unique_ptr &&fence) +int Request::addBuffer(const Stream *, FrameBuffer *, + std::unique_ptr &&) { - if (!stream) { - LOG(Request, Error) << "Invalid stream reference"; - return -EINVAL; - } - - /* - * Make sure the fence has been extracted from the buffer - * to avoid waiting on a stale fence. - */ - if (buffer->_d()->fence()) { - LOG(Request, Error) << "Can't add buffer that still references a fence"; - return -EEXIST; - } - - auto [it, inserted] = bufferMap_.try_emplace(stream, buffer); - if (!inserted) { - LOG(Request, Error) << "FrameBuffer already set for stream"; - return -EEXIST; - } - - buffer->_d()->setRequest(this); - buffer->_d()->stream_ = stream; - _d()->pending_.insert(buffer); - - if (fence && fence->isValid()) - buffer->_d()->setFence(std::move(fence)); - - return 0; + LOG(Request, Fatal) << "REMOVED"; + return -ENOTSUP; } /** From patchwork Mon Jun 29 16:29:47 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27103 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 782A2C3261 for ; Mon, 29 Jun 2026 16:31:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EE3F165F62; Mon, 29 Jun 2026 18:31:11 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="dBozKsfz"; 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 6911365F4A for ; Mon, 29 Jun 2026 18:30:26 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4AA8E8D4 for ; Mon, 29 Jun 2026 18:29:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750583; bh=12oFyoKAW4MODUKyk8bIBhs5scOxY/rAvy72r05GWkc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=dBozKsfzM35H/sNeSBSXHfj+KjxONVZ9VTX2Aqbn3HkEmoyYndkWz909r8VwppmkN ut50dBaNs7aYBNEQgpqBpIQaARK86H+oEhgurfZ+Aqti2MK5FKrNROVDU5tOs1M1/A 5kl9DQ6oF0chWbb1fk/bJcDyXoTLmmz9m33ilZ2s= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 24/54] libcamera: request: Remove fence support Date: Mon, 29 Jun 2026 18:29:47 +0200 Message-ID: <20260629163017.863145-25-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" With the split of buffers and requests, fences will need to be handled outside of requests. So remove the current fence support, all the miscellaneous things related to it: * Request::{prepared,prepared_} * PipelineHandler::registerRequest() Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/pipeline_handler.h | 1 - include/libcamera/internal/request.h | 15 -- src/libcamera/camera.cpp | 7 +- src/libcamera/fence.cpp | 5 - src/libcamera/framebuffer.cpp | 10 +- src/libcamera/pipeline_handler.cpp | 24 +--- src/libcamera/request.cpp | 131 ------------------ 7 files changed, 5 insertions(+), 188 deletions(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index 81ec359981..f90cae253f 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -59,7 +59,6 @@ public: void stop(Camera *camera); bool hasPendingRequests(const Camera *camera) const; - void registerRequest(Request *request); void queueRequest(Request *request); static bool completeBuffer(Request *request, FrameBuffer *buffer) diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h index 382ed28bca..8f570e4f79 100644 --- a/include/libcamera/internal/request.h +++ b/include/libcamera/internal/request.h @@ -7,19 +7,13 @@ #pragma once -#include -#include -#include #include #include #include -#include #include -using namespace std::chrono_literals; - namespace libcamera { class Camera; @@ -43,26 +37,17 @@ public: void cancel(); void reset(); - void prepare(std::chrono::milliseconds timeout = 0ms); - Signal<> prepared; - private: friend class PipelineHandler; friend std::ostream &operator<<(std::ostream &out, const Request &r); void doCancelRequest(); - void emitPrepareCompleted(); - void notifierActivated(FrameBuffer *buffer); - void timeout(); Camera *camera_; bool cancelled_; uint32_t sequence_ = 0; - bool prepared_ = false; std::unordered_set pending_; - std::map notifiers_; - std::unique_ptr timer_; ControlList metadata_; }; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 31ab59e0b7..27dae3a403 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -1294,12 +1294,7 @@ std::unique_ptr Camera::createRequest(uint64_t cookie) if (ret < 0) return nullptr; - std::unique_ptr request = std::make_unique(this, cookie); - - /* Associate the request with the pipeline handler. */ - d->pipe_->registerRequest(request.get()); - - return request; + return std::make_unique(this, cookie); } /** diff --git a/src/libcamera/fence.cpp b/src/libcamera/fence.cpp index 73299b4027..92d1b37366 100644 --- a/src/libcamera/fence.cpp +++ b/src/libcamera/fence.cpp @@ -28,8 +28,6 @@ namespace libcamera { * the Fence to be signalled before allowing the camera device to actually * access the memory area described by the FrameBuffer. * - * \sa Request::addBuffer() - * * By using a fence, applications can then synchronize between frame buffer * consumers and producers, as for example a display device and a camera, to * guarantee that a new data transfers only happen once the existing frames have @@ -68,9 +66,6 @@ namespace libcamera { * * A failure in waiting for a Fence to complete will result in the Request to * complete in failed state. - * - * \sa Request::prepare() - * \sa PipelineHandler::doQueueRequests() */ /** diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index baa298a8e3..55ca24c8a3 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -191,9 +191,7 @@ FrameBuffer::Private::~Private() * * If buffer with a Fence completes with errors due to a failure in handling * the fence, applications are responsible for releasing the Fence before - * calling Request::addBuffer() again. - * - * \sa Request::addBuffer() + * reusing the buffer. * * \return A const pointer to the Fence if any, nullptr otherwise */ @@ -203,15 +201,13 @@ FrameBuffer::Private::~Private() * \brief Move a \a fence in this buffer * \param[in] fence The Fence * - * This function associates a Fence with this Framebuffer. The intended caller - * is the Request::addBuffer() function. + * This function associates a Fence with this Framebuffer. It is only intended + * to be called by the libcamera core. * * Once a FrameBuffer is associated with a Fence, the FrameBuffer will only be * made available to the hardware device once the Fence has been correctly * signalled. * - * \sa Request::prepare() - * * If the FrameBuffer completes successfully the core releases the Fence and the * Buffer can be reused immediately. If handling of the Fence fails during the * request preparation, the Fence is not released and is left in the diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 54ef8296a4..29a21a0d70 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -7,7 +7,6 @@ #include "libcamera/internal/pipeline_handler.h" -#include #include #include @@ -443,25 +442,6 @@ bool PipelineHandler::hasPendingRequests(const Camera *camera) const return !camera->_d()->queuedRequests_.empty(); } -/** - * \fn PipelineHandler::registerRequest() - * \brief Register a request for use by the pipeline handler - * \param[in] request The request to register - * - * This function is called when the request is created, and allows the pipeline - * handler to perform any one-time initialization it requries for the request. - */ -void PipelineHandler::registerRequest(Request *request) -{ - /* - * Connect the request prepared signal to notify the pipeline handler - * when a request is ready to be processed. - */ - request->_d()->prepared.connect(this, [this, request]() { - doQueueRequests(request->_d()->camera()); - }); -} - /** * \fn PipelineHandler::queueRequest() * \brief Queue a request @@ -493,7 +473,7 @@ void PipelineHandler::queueRequest(Request *request) Camera::Private *data = camera->_d(); data->waitingRequests_.push(request); - request->_d()->prepare(300ms); + doQueueRequests(camera); } /** @@ -533,8 +513,6 @@ void PipelineHandler::doQueueRequests(Camera *camera) break; Request *request = data->waitingRequests_.front(); - if (!request->_d()->prepared_) - break; /* * Pop the request first, in case doQueueRequests() is called diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 8a3934add3..8819ba0ce3 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -7,7 +7,6 @@ #include "libcamera/internal/request.h" -#include #include #include @@ -155,8 +154,6 @@ void Request::Private::doCancelRequest() cancelled_ = true; pending_.clear(); - notifiers_.clear(); - timer_.reset(); } /** @@ -187,135 +184,7 @@ void Request::Private::reset() { sequence_ = 0; cancelled_ = false; - prepared_ = false; pending_.clear(); - notifiers_.clear(); - timer_.reset(); -} - -/* - * Helper function to save some lines of code and make sure prepared_ is set - * to true before emitting the signal. - */ -void Request::Private::emitPrepareCompleted() -{ - prepared_ = true; - prepared.emit(); -} - -/** - * \brief Prepare the Request to be queued to the device - * \param[in] timeout Optional expiration timeout - * - * Prepare a Request to be queued to the hardware device by ensuring it is - * ready for the incoming memory transfers. - * - * This currently means waiting on each frame buffer acquire fence to be - * signalled. An optional expiration timeout can be specified. If not all the - * fences have been signalled correctly before the timeout expires the Request - * is cancelled. - * - * The function immediately emits the prepared signal if all the prepare - * operations have been completed synchronously. If instead the prepare - * operations require to wait the completion of asynchronous events, such as - * fences notifications or timer expiration, the prepared signal is emitted upon - * the asynchronous event completion. - * - * As we currently only handle fences, the function emits the prepared signal - * immediately if there are no fences to wait on. Otherwise the prepared signal - * is emitted when all fences have been signalled or the optional timeout has - * expired. - * - * If not all the fences have been correctly signalled or the optional timeout - * has expired the Request will be cancelled and the Request::prepared signal - * emitted. - * - * The intended user of this function is the PipelineHandler base class, which - * 'prepares' a Request before queuing it to the hardware device. - */ -void Request::Private::prepare(std::chrono::milliseconds timeout) -{ - /* Create and connect one notifier for each synchronization fence. */ - for (FrameBuffer *buffer : pending_) { - const Fence *fence = buffer->_d()->fence(); - if (!fence) - continue; - - auto [it, inserted] = notifiers_.try_emplace(buffer, fence->fd().get(), EventNotifier::Type::Read); - ASSERT(inserted); - - it->second.activated.connect(this, [this, buffer] { - notifierActivated(buffer); - }); - } - - if (notifiers_.empty()) { - emitPrepareCompleted(); - return; - } - - /* - * In case a timeout is specified, create a timer and set it up. - * - * The timer must be created here instead of in the Request constructor, - * in order to be bound to the pipeline handler thread. - */ - if (timeout != 0ms) { - timer_ = std::make_unique(); - timer_->timeout.connect(this, &Request::Private::timeout); - timer_->start(timeout); - } -} - -/** - * \var Request::Private::prepared - * \brief Request preparation completed Signal - * - * The signal is emitted once the request preparation has completed and is ready - * to be queued. The Request might complete with errors in which case it is - * cancelled. - * - * The intended slot for this signal is the PipelineHandler::doQueueRequests() - * function which queues Request after they have been prepared or cancel them - * if they have failed preparing. - */ - -void Request::Private::notifierActivated(FrameBuffer *buffer) -{ - /* Close the fence if successfully signalled. */ - ASSERT(buffer); - buffer->releaseFence(); - - /* Remove the entry from the map and check if other fences are pending. */ - auto it = notifiers_.find(buffer); - ASSERT(it != notifiers_.end()); - notifiers_.erase(it); - - Request *request = _o(); - LOG(Request, Debug) - << "Request " << request->cookie() << " buffer " << buffer - << " fence signalled"; - - if (!notifiers_.empty()) - return; - - /* All fences completed, delete the timer and emit the prepared signal. */ - timer_.reset(); - emitPrepareCompleted(); -} - -void Request::Private::timeout() -{ - /* A timeout can only happen if there are fences not yet signalled. */ - ASSERT(!notifiers_.empty()); - notifiers_.clear(); - - Request *request = _o(); - LOG(Request, Debug) << "Request prepare timeout: " << request->cookie(); - - cancel(); - - emitPrepareCompleted(); } #endif /* __DOXYGEN_PUBLIC__ */ From patchwork Mon Jun 29 16:29:48 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27105 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 4CB21C3261 for ; Mon, 29 Jun 2026 16:31:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AD1FB65FAC; Mon, 29 Jun 2026 18:31:15 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CzL4CWuz"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A342165F4D for ; Mon, 29 Jun 2026 18:30:26 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7C160E91 for ; Mon, 29 Jun 2026 18:29:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750583; bh=pQVAW6iCf58KirUIatCJzbQJHIklbZA5CfRyGTd+i54=; h=From:To:Subject:Date:In-Reply-To:References:From; b=CzL4CWuzeL39rqXVSGOkUtpnrZxDTtEGTUL9I9XsG5d0zTDu0DB54pr8c2JIDGHyu lN/GAt3ON3BhcwgyoJcRD7WWpmpPO/HQFprtgXwKRfSEdIvNuWMbfuq9s7kDb0ANn7 /SMo1TMSREYVwGBc5MSceI5s1hxMWgr+uPi20CRE= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 25/54] libcamera: request: Store count of pending buffers Date: Mon, 29 Jun 2026 18:29:48 +0200 Message-ID: <20260629163017.863145-26-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" With the split of requests and buffers, a request will have no information about which specific buffers are pending for itself, so make the previous set member into a simple integer counter. Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/request.h | 5 ++--- src/libcamera/request.cpp | 19 +++++-------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h index 8f570e4f79..09768c6fcd 100644 --- a/include/libcamera/internal/request.h +++ b/include/libcamera/internal/request.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include @@ -28,7 +27,7 @@ public: ~Private(); Camera *camera() const { return camera_; } - bool hasPendingBuffers() const { return !pending_.empty(); } + bool hasPendingBuffers() const { return pending_ > 0; } ControlList &metadata() { return metadata_; } @@ -47,7 +46,7 @@ private: bool cancelled_; uint32_t sequence_ = 0; - std::unordered_set pending_; + size_t pending_ = 0; ControlList metadata_; }; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 8819ba0ce3..9544a8993d 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -108,8 +108,8 @@ bool Request::Private::completeBuffer(FrameBuffer *buffer) ASSERT(request->findBuffer(buffer->_d()->stream_) == buffer); - int ret = pending_.erase(buffer); - ASSERT(ret == 1); + ASSERT(pending_ > 0); + pending_ -= 1; buffer->_d()->setRequest(nullptr); buffer->_d()->stream_ = nullptr; @@ -143,17 +143,8 @@ void Request::Private::complete() void Request::Private::doCancelRequest() { - Request *request = _o(); - - for (FrameBuffer *buffer : pending_) { - buffer->_d()->cancel(); - camera_->bufferCompleted.emit(request, buffer); - buffer->_d()->setRequest(nullptr); - buffer->_d()->stream_ = nullptr; - } - cancelled_ = true; - pending_.clear(); + pending_ = 0; } /** @@ -184,7 +175,7 @@ void Request::Private::reset() { sequence_ = 0; cancelled_ = false; - pending_.clear(); + pending_ = 0; } #endif /* __DOXYGEN_PUBLIC__ */ @@ -426,7 +417,7 @@ std::ostream &operator<<(std::ostream &out, const Request &r) /* Example Output: Request(55:P:1/2:6523524) */ out << "Request(" << r.sequence() << ":" << statuses[r.status()] << ":" - << r._d()->pending_.size() << "/" << r.buffers().size() << ":" + << r._d()->pending_ << "/" << r.buffers().size() << ":" << r.cookie() << ")"; return out; From patchwork Mon Jun 29 16:29:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27104 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 901E0C3261 for ; Mon, 29 Jun 2026 16:31:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9DA2365F60; Mon, 29 Jun 2026 18:31:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Zbtap92l"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D7A8865F4E for ; Mon, 29 Jun 2026 18:30:26 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id AE5108D4 for ; Mon, 29 Jun 2026 18:29:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750583; bh=gon94y9wMnnMOQcCwsKOys90ovyKUVLz6WnjDA3ne5E=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Zbtap92lhhi4iONe5aNu1F0nmBbhjSGYk4oUlGSXzPXorfX8OXRbNnWgUO+YPWdVc yc6rNhMp4fysXonFv/4OGktGtWbT6PCYzqGdTS/lX5u3enwyr0uUoTS/TjET00t7eD kItgo8dRiEra/QiDtaad3SxZet4GYHkHb/KYqAqI= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 26/54] libcamera: request: doCancelRequest(): Remove Date: Mon, 29 Jun 2026 18:29:49 +0200 Message-ID: <20260629163017.863145-27-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Now that request cancellation does not emit the `bufferCompleted` event for pending buffers (because there are no longer such things), the function need not be called from the destructor and it can be inlined into its only caller. Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/request.h | 2 -- src/libcamera/request.cpp | 10 ++-------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h index 09768c6fcd..922d14f14c 100644 --- a/include/libcamera/internal/request.h +++ b/include/libcamera/internal/request.h @@ -40,8 +40,6 @@ private: friend class PipelineHandler; friend std::ostream &operator<<(std::ostream &out, const Request &r); - void doCancelRequest(); - Camera *camera_; bool cancelled_; uint32_t sequence_ = 0; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 9544a8993d..4df8b0f1ad 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -62,7 +62,6 @@ Request::Private::Private(Camera *camera) Request::Private::~Private() { - doCancelRequest(); } /** @@ -141,12 +140,6 @@ void Request::Private::complete() LIBCAMERA_TRACEPOINT(request_complete, this); } -void Request::Private::doCancelRequest() -{ - cancelled_ = true; - pending_ = 0; -} - /** * \brief Cancel a queued request * @@ -162,7 +155,8 @@ void Request::Private::cancel() Request *request = _o(); ASSERT(request->status() == RequestPending); - doCancelRequest(); + cancelled_ = true; + pending_ = 0; } /** From patchwork Mon Jun 29 16:29:50 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27106 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 D62B8C3261 for ; Mon, 29 Jun 2026 16:31:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6418A65F64; Mon, 29 Jun 2026 18:31:17 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cYiweoaS"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1402D65F2B for ; Mon, 29 Jun 2026 18:30:27 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E0F7B1044 for ; Mon, 29 Jun 2026 18:29:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750584; bh=m199Ycdt1zqJxthRezUaGD9zYzpy0v3FKAV4DN0S9AA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=cYiweoaSDhhOWtMizMJOhmXbdxnai3TOxaB2dIYsQ7ukfA8q14WAcaM0u5ttPClDC fhIFb4TV2fLJ3HcVTdwZBmWex62ES5eQ47IEjZmu6AlckjDG6zoQW89BmZH7UvCJzi u5jmOvCUdBmjAJr+JcY+cCT/nrKEywGSKS/QHk1o= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 27/54] libcamera: pipeline_handler: Move constructor options to a separate type Date: Mon, 29 Jun 2026 18:29:50 +0200 Message-ID: <20260629163017.863145-28-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Add a new `Options` type that stores the optional parameters for the pipeline handler base class. Currently there is only one, which is "maxQueuedRequestsDevice". TODO: `options = {}` does not work in the arg list, should it be worked around or is it fine? Signed-off-by: Barnabás Pőcze --- Documentation/guides/pipeline-handler.rst | 2 +- include/libcamera/internal/pipeline_handler.h | 10 +++-- src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 2 +- src/libcamera/pipeline/ipu3/ipu3.cpp | 2 +- src/libcamera/pipeline/mali-c55/mali-c55.cpp | 3 +- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 3 +- .../pipeline/rpi/common/pipeline_base.h | 2 +- src/libcamera/pipeline/simple/simple.cpp | 2 +- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 2 +- src/libcamera/pipeline/vimc/vimc.cpp | 2 +- src/libcamera/pipeline/virtual/virtual.cpp | 2 +- src/libcamera/pipeline_handler.cpp | 45 ++++++++++--------- 12 files changed, 43 insertions(+), 34 deletions(-) diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst index 2d2231eb68..31affee4af 100644 --- a/Documentation/guides/pipeline-handler.rst +++ b/Documentation/guides/pipeline-handler.rst @@ -217,7 +217,7 @@ stub implementations for the overridden class members. }; PipelineHandlerVivid::PipelineHandlerVivid(CameraManager *manager) - : PipelineHandler(manager) + : PipelineHandler(manager, {}) { } diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index f90cae253f..e978557036 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -37,8 +37,11 @@ class PipelineHandler : public std::enable_shared_from_this, public Object { public: - PipelineHandler(CameraManager *manager, - unsigned int maxQueuedRequestsDevice = 32); + struct Options { + unsigned int maxQueuedRequestsDevice = 32; + }; + + PipelineHandler(CameraManager *manager, const Options &options); virtual ~PipelineHandler(); virtual bool match(DeviceEnumerator *enumerator) = 0; @@ -100,7 +103,6 @@ protected: virtual void releaseDevice(Camera *camera); CameraManager *manager_; - const unsigned int maxQueuedRequestsDevice_; private: void unlockMediaDevices(); @@ -117,6 +119,8 @@ private: const char *name_; unsigned int useCount_; + const Options options_; + friend class PipelineHandlerFactoryBase; }; diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp index d3f152aa1e..f995fa50d5 100644 --- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp +++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp @@ -612,7 +612,7 @@ CameraConfiguration::Status ISICameraConfiguration::validate() */ PipelineHandlerISI::PipelineHandlerISI(CameraManager *manager) - : PipelineHandler(manager) + : PipelineHandler(manager, {}) { } diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index af1b79d708..7e22388d02 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -385,7 +385,7 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() } PipelineHandlerIPU3::PipelineHandlerIPU3(CameraManager *manager) - : PipelineHandler(manager), cio2MediaDev_(nullptr), imguMediaDev_(nullptr) + : PipelineHandler(manager, {}), cio2MediaDev_(nullptr), imguMediaDev_(nullptr) { } diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index 0c7b7ed370..114179f49d 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -786,7 +786,8 @@ private: }; PipelineHandlerMaliC55::PipelineHandlerMaliC55(CameraManager *manager) - : PipelineHandler(manager, kMaliC55BufferCount), dsFitted_(true) + : PipelineHandler(manager, { .maxQueuedRequestsDevice = kMaliC55BufferCount }), + dsFitted_(true) { } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 0c1e5767b4..2aa273d220 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -782,7 +782,8 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() */ PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) - : PipelineHandler(manager, kRkISP1MaxQueuedRequests), hasSelfPath_(true) + : PipelineHandler(manager, { .maxQueuedRequestsDevice = kRkISP1MaxQueuedRequests }), + hasSelfPath_(true) { } diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h index 758155ee0d..1b16a6e6a5 100644 --- a/src/libcamera/pipeline/rpi/common/pipeline_base.h +++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h @@ -203,7 +203,7 @@ class PipelineHandlerBase : public PipelineHandler { public: PipelineHandlerBase(CameraManager *manager) - : PipelineHandler(manager) + : PipelineHandler(manager, {}) { } diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 381f8db3ee..2a4f03df72 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1402,7 +1402,7 @@ CameraConfiguration::Status SimpleCameraConfiguration::validate() */ SimplePipelineHandler::SimplePipelineHandler(CameraManager *manager) - : PipelineHandler(manager, kMaxQueuedRequestsDevice), + : PipelineHandler(manager, { .maxQueuedRequestsDevice = kMaxQueuedRequestsDevice }), converter_(nullptr) { } diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index f8d49d9122..928ee79559 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -230,7 +230,7 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() } PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager) - : PipelineHandler(manager) + : PipelineHandler(manager, {}) { } diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 528022776e..490f693da4 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -196,7 +196,7 @@ CameraConfiguration::Status VimcCameraConfiguration::validate() } PipelineHandlerVimc::PipelineHandlerVimc(CameraManager *manager) - : PipelineHandler(manager) + : PipelineHandler(manager, {}) { } diff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp index f9e2cecea3..011e31d9d5 100644 --- a/src/libcamera/pipeline/virtual/virtual.cpp +++ b/src/libcamera/pipeline/virtual/virtual.cpp @@ -243,7 +243,7 @@ CameraConfiguration::Status VirtualCameraConfiguration::validate() bool PipelineHandlerVirtual::created_ = false; PipelineHandlerVirtual::PipelineHandlerVirtual(CameraManager *manager) - : PipelineHandler(manager), + : PipelineHandler(manager, {}), dmaBufAllocator_(DmaBufAllocator::DmaBufAllocatorFlag::CmaHeap | DmaBufAllocator::DmaBufAllocatorFlag::SystemHeap | DmaBufAllocator::DmaBufAllocatorFlag::UDmaBuf) diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 29a21a0d70..efea534649 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -59,20 +59,37 @@ LOG_DEFINE_CATEGORY(Pipeline) * PipelineHandler class where only the 'this' pointer is available. */ +/** + * \class PipelineHandler::Options + * \brief The collection of optional options of the base class + */ + +/** + * \var PipelineHandler::Options::maxQueuedRequestsDevice + * \brief The maximum number of requests the pipeline handler shall queue to the + * device + * + * maxQueuedRequestsDevice limits the number of request that the + * pipeline handler shall queue to the underlying hardware, in order to + * saturate the pipeline with requests. The application may choose to queue + * as many requests as it desires, however only maxQueuedRequestsDevice + * requests will be queued to the hardware at a given point in time. The + * remaining requests will be kept waiting in the internal waiting + * queue, to be queued at a later stage. + */ + /** * \brief Construct a PipelineHandler instance * \param[in] manager The camera manager - * \param[in] maxQueuedRequestsDevice The maximum number of requests queued to - * the device + * \param[in] options The options options for the pipeline handler base class * * In order to honour the std::enable_shared_from_this<> contract, * PipelineHandler instances shall never be constructed manually, but always * through the PipelineHandlerFactoryBase::create() function. */ PipelineHandler::PipelineHandler(CameraManager *manager, - unsigned int maxQueuedRequestsDevice) - : manager_(manager), maxQueuedRequestsDevice_(maxQueuedRequestsDevice), - useCount_(0) + const Options &options) + : manager_(manager), useCount_(0), options_(options) { } @@ -453,7 +470,7 @@ bool PipelineHandler::hasPendingRequests(const Camera *camera) const * queued to the pipeline handler. * * The queue of waiting requests is iterated and up to \a - * maxQueuedRequestsDevice_ prepared requests are passed to the pipeline handler + * maxQueuedRequestsDevice prepared requests are passed to the pipeline handler * in the same order they have been queued by calling this function. * * If a Request fails during the preparation phase or if the pipeline handler @@ -509,7 +526,7 @@ void PipelineHandler::doQueueRequests(Camera *camera) { Camera::Private *data = camera->_d(); while (!data->waitingRequests_.empty()) { - if (data->queuedRequests_.size() == maxQueuedRequestsDevice_) + if (data->queuedRequests_.size() == options_.maxQueuedRequestsDevice) break; Request *request = data->waitingRequests_.front(); @@ -862,20 +879,6 @@ void PipelineHandler::disconnect() * constant for the whole lifetime of the pipeline handler. */ -/** - * \var PipelineHandler::maxQueuedRequestsDevice_ - * \brief The maximum number of requests the pipeline handler shall queue to the - * device - * - * maxQueuedRequestsDevice_ limits the number of request that the - * pipeline handler shall queue to the underlying hardware, in order to - * saturate the pipeline with requests. The application may choose to queue - * as many requests as it desires, however only maxQueuedRequestsDevice_ - * requests will be queued to the hardware at a given point in time. The - * remaining requests will be kept waiting in the internal waiting - * queue, to be queued at a later stage. - */ - /** * \fn PipelineHandler::name() * \brief Retrieve the pipeline handler name From patchwork Mon Jun 29 16:29:51 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27107 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 84A0CC3261 for ; Mon, 29 Jun 2026 16:31:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0B3E865FA9; Mon, 29 Jun 2026 18:31:19 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HKQYbxnZ"; 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 44E0365F32 for ; Mon, 29 Jun 2026 18:30:27 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 21F2B8D4 for ; Mon, 29 Jun 2026 18:29:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750584; bh=rKHRs0PTnPSsrt/YEvBC7o9qWbw+5n2Y4Q5hgJakESI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=HKQYbxnZVlVhuPODkNQRdMBI8ULPN/qsAEZoa6DoFklSzBAutPg9bysNrHfFh646n LwrzmJrCHa0YsJPdTklueJsC9pprP6iDb0DO4eHscBKT5xhUI5yF6Iok+LDEes7Ui7 zKHRZLZFUXfUC3seTUUJdwGLlw2zrrMMM37gYjM0= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 28/54] libcamera: pipeline_handler: Acquire buffers if not using pool Date: Mon, 29 Jun 2026 18:29:51 +0200 Message-ID: <20260629163017.863145-29-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" If the pipeline handler itself is not using the camera's buffer pool, then ensure that each stream of the request has a buffer by retrieving buffers before `queueRequestDevice()`. Additionally, try to queue the waiting requests if a buffer has been added to the pool. Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/pipeline_handler.h | 4 ++ include/libcamera/internal/request.h | 2 + src/libcamera/pipeline_handler.cpp | 61 ++++++++++++++++++- src/libcamera/request.cpp | 5 ++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index e978557036..d7544642fb 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -39,6 +39,7 @@ class PipelineHandler : public std::enable_shared_from_this, public: struct Options { unsigned int maxQueuedRequestsDevice = 32; + bool usesBufferPool = false; }; PipelineHandler(CameraManager *manager, const Options &options); @@ -110,9 +111,12 @@ private: void mediaDeviceDisconnected(std::shared_ptr media); virtual void disconnect(); + [[nodiscard]] bool prepareRequest(Request *request); void doQueueRequest(Request *request); void doQueueRequests(Camera *camera); + void buffersAdded(Camera *camera); + std::vector> mediaDevices_; std::vector> cameras_; diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h index 922d14f14c..f5aae3c1dc 100644 --- a/include/libcamera/internal/request.h +++ b/include/libcamera/internal/request.h @@ -29,6 +29,8 @@ public: Camera *camera() const { return camera_; } bool hasPendingBuffers() const { return pending_ > 0; } + [[nodiscard]] Request::BufferMap &buffers() { return LIBCAMERA_O_PTR()->bufferMap_; } // \todo fixme suboptimal + ControlList &metadata() { return metadata_; } bool completeBuffer(FrameBuffer *buffer); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index efea534649..36e1509b2b 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -78,6 +78,16 @@ LOG_DEFINE_CATEGORY(Pipeline) * queue, to be queued at a later stage. */ +/** + * \var PipelineHandler::Options::usesBufferPool + * \brief Whether or not the pipeline handler uses the camera's buffer pool + * + * If this option is set to \a false, then the pipeline handler base class + * will ensure that the requests have the necessary buffers when queueRequestDevice() + * is called. Otherwise it is the responsibility of the derived class to + * manage the buffers. + */ + /** * \brief Construct a PipelineHandler instance * \param[in] manager The camera manager @@ -493,6 +503,38 @@ void PipelineHandler::queueRequest(Request *request) doQueueRequests(camera); } +bool PipelineHandler::prepareRequest(Request *request) +{ + if (!options_.usesBufferPool) { + Camera *camera = request->_d()->camera(); + Camera::Private *data = camera->_d(); + auto &buffers = request->_d()->buffers(); + + ASSERT(request->_d()->pending_ == buffers.size()); + + for (auto &[stream, buffer] : buffers) { + auto it = data->streamData_.find(stream); + ASSERT(it != data->streamData_.end()); + ASSERT(it->second.active); + + if (buffer) + continue; + + auto &pool = it->second.buffers; + if (pool.empty()) + return false; + + buffer = pool.back(); + pool.pop_back(); + + buffer->_d()->setRequest(request); + buffer->_d()->stream_ = stream; + } + } + + return true; +} + /** * \brief Queue one requests to the device */ @@ -514,6 +556,9 @@ void PipelineHandler::doQueueRequest(Request *request) int ret = queueRequestDevice(camera, request); if (ret) cancelRequest(request); + // \todo what to do with buffers from pool? probably nothing? + // let's say it's the applications responsibility to process + // *all* buffers in *all* completed requests } /** @@ -530,6 +575,8 @@ void PipelineHandler::doQueueRequests(Camera *camera) break; Request *request = data->waitingRequests_.front(); + if (!prepareRequest(request)) + break; /* * Pop the request first, in case doQueueRequests() is called @@ -625,6 +672,12 @@ void PipelineHandler::cancelRequest(Request *request) completeRequest(request); } +void PipelineHandler::buffersAdded(Camera *camera) +{ + if (!options_.usesBufferPool) + doQueueRequests(camera); +} + /** * \fn PipelineHandler::addBuffer() * \brief Add buffers to the buffer pool of the camera @@ -679,18 +732,24 @@ void PipelineHandler::addBuffer(Camera *camera, << "Waiting on fence:" << buffer->_d()->fence()->fd().get() << " for stream:" << stream << " buffer:" << buffer; - it2->notifier.activated.connect(this, [=] { + it2->notifier.activated.connect(this, [=, this] { LOG(Pipeline, Debug) << "Activated fence:" << it2->buffer->_d()->fence()->fd().get() << " for stream:" << it2->stream << " buffer:" << it2->buffer; + PipelineHandler *self = this; + Camera *cam = camera; + std::ignore = it2->buffer->releaseFence(); it->second.buffers.push_back(it2->buffer); d->pendingFences_.erase(it2); /* Lambda is now destroy, no captured variable should be accessed. */ + + self->buffersAdded(cam); }); } else { it->second.buffers.push_back(buffer); + buffersAdded(camera); } } diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 4df8b0f1ad..5bb1617b51 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -79,6 +79,11 @@ Request::Private::~Private() * otherwise */ +/** + * \fn Request::Private::buffers() + * \copydoc Request::buffers() + */ + /** * \fn Request::Private::metadata() * \brief Retrieve the request's metadata From patchwork Mon Jun 29 16:29:52 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27108 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 B8272C3261 for ; Mon, 29 Jun 2026 16:31:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 56E1B65F92; Mon, 29 Jun 2026 18:31:20 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WjqPwSXp"; 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 7B29E65F33 for ; Mon, 29 Jun 2026 18:30:27 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 540CAE91 for ; Mon, 29 Jun 2026 18:29:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750584; bh=4K1DR+Z1s585oyJz9UXE/kiOJs3cKR4OAQuWD9T9NNU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=WjqPwSXpr/cBqP4Yvdkt6fKvb9v9H/x7OhIzGnF6FF9UIp8DpjtdE90koYPODxoFU Yj8I5ZWRO24zj+ex0qKTbUYb3rI0UVUrp6/h7mmnZOpRUGF31SkF/u+7IDSwXgzlZI 9KMcvvBexI/5jB4LyT0vISijiauduHYB8QTVyW84= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 29/54] libcamera: request: enableStream(): Add Date: Mon, 29 Jun 2026 18:29:52 +0200 Message-ID: <20260629163017.863145-30-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Add a funtion that can enable/disable streams without adding buffers. Specifically, use a `nullptr` as buffer to mark enabled stream. Adjust `completeBuffer()` to set the buffer pointer in the map. Signed-off-by: Barnabás Pőcze --- include/libcamera/request.h | 1 + src/libcamera/request.cpp | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/libcamera/request.h b/include/libcamera/request.h index 290983f613..c86259c59b 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -55,6 +55,7 @@ public: int addBuffer(const Stream *stream, FrameBuffer *buffer, std::unique_ptr &&fence = {}); FrameBuffer *findBuffer(const Stream *stream) const; + void enableStream(const Stream *stream, bool enabled); uint32_t sequence() const; uint64_t cookie() const { return cookie_; } diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 5bb1617b51..d7cf39ae2e 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -110,13 +110,16 @@ bool Request::Private::completeBuffer(FrameBuffer *buffer) Request *request = LIBCAMERA_O_PTR(); camera_->bufferCompleted.emit(request, buffer); - ASSERT(request->findBuffer(buffer->_d()->stream_) == buffer); + auto it = request->bufferMap_.find(buffer->_d()->stream_); + ASSERT(it != request->bufferMap_.end()); + ASSERT(it->second == buffer || !it->second); ASSERT(pending_ > 0); pending_ -= 1; buffer->_d()->setRequest(nullptr); buffer->_d()->stream_ = nullptr; + it->second = buffer; if (buffer->metadata().status == FrameMetadata::FrameCancelled) cancelled_ = true; @@ -337,6 +340,31 @@ FrameBuffer *Request::findBuffer(const Stream *stream) const return it->second; } +/** + * \brief Change whether the particular stream should be captured + * \param[in] stream The stream + * \param[in] enabled Whether to enable or disable the stream + */ +void Request::enableStream(const Stream *stream, bool enabled) +{ + ASSERT(stream); + + Request::Private *const d = _d(); + + if (enabled) { + const auto [it, inserted] = bufferMap_.try_emplace(stream); + + it->second = nullptr; + d->pending_ += inserted; + } else { + d->pending_ -= bufferMap_.erase(stream); + } + + LOG(Request, Debug) + << "request:" << this << " stream:" << stream + << ' ' << (enabled ? "en" : "dis") << "abled pending:" << d->pending_; +} + /** * \brief Retrieve the sequence number for the request * From patchwork Mon Jun 29 16:29:53 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27111 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 451D4C3261 for ; Mon, 29 Jun 2026 16:31:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C1B2C65F6E; Mon, 29 Jun 2026 18:31:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="nRJGZKit"; 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 ACD1E65F52 for ; Mon, 29 Jun 2026 18:30:27 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 889AB8D4 for ; Mon, 29 Jun 2026 18:29:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750584; bh=6zMfW1QrfaD4094EYcb4KWHpwrWoVkq8ywougfxB1r0=; h=From:To:Subject:Date:In-Reply-To:References:From; b=nRJGZKithasI2eBM2mfWr08BTCsZH6c9lzCKVCn/lFIOrrVgbvI/egBCUd2j+Gzy1 H1OUl/ejL/T+4NYULjB7Q20TdoXtg7ibwdrZ56y1amEwzZc2pojVOrwPQoA0jIeVTG co2Ojj6xVfIagNIrp1hIDlAdhRS+JsOf082IopdM= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 30/54] libcamera: camera: acquireBuffer(): Add Date: Mon, 29 Jun 2026 18:29:53 +0200 Message-ID: <20260629163017.863145-31-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Add an internal function for pipeeline handlers that can be used to retrieve a buffer from the pool of a specific stream. Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/camera.h | 11 +++++++++ src/libcamera/camera.cpp | 36 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h index 6ba77eb882..31914075f0 100644 --- a/include/libcamera/internal/camera.h +++ b/include/libcamera/internal/camera.h @@ -49,6 +49,17 @@ public: const CameraControlValidator *validator() const { return validator_.get(); } +#ifndef __DOXYGEN__ + struct FrameBufferPoolDeleter { + std::vector *pool = nullptr; + void operator()(FrameBuffer *buffer) const; + }; +#endif + + using PooledFrameBuffer = std::unique_ptr; + + [[nodiscard]] PooledFrameBuffer acquireBuffer(const Stream *stream); + private: enum State { CameraAvailable, diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 27dae3a403..016f36e796 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -754,6 +754,42 @@ Camera::Private::PendingFence::PendingFence(const Stream *s, FrameBuffer *b) buffer(b) { } + +/** + * \typedef Camera::Private::PooledFrameBuffer + * \brief An std::unique_ptr for automatically returning the FrameBuffer to the pool to simplify error handling. + */ + +#ifndef __DOXYGEN__ +void Camera::Private::FrameBufferPoolDeleter::operator()(FrameBuffer *buffer) const +{ + pool->push_back(buffer); +} +#endif + +/** + * \brief Acquire a buffer for a stream + * \param[in] stream The stream + * + * \return A buffer or an empty handle if not available + */ +Camera::Private::PooledFrameBuffer +Camera::Private::acquireBuffer(const Stream *stream) +{ + auto it = streamData_.find(stream); + if (it == streamData_.end() || !it->second.active || it->second.buffers.empty()) + return {}; + + FrameBuffer *buffer = it->second.buffers.back(); + buffer->_d()->stream_ = stream; + + LOG(Camera, Debug) + << "Camera:" << LIBCAMERA_O_PTR() << " acquired buffer:" + << buffer << " for stream:" << stream; + + it->second.buffers.pop_back(); + return { buffer, { &it->second.buffers } }; +} #endif /* __DOXYGEN_PUBLIC__ */ /** From patchwork Mon Jun 29 16:29:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27109 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 A04AEC3261 for ; Mon, 29 Jun 2026 16:31:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2FF2C65FB4; Mon, 29 Jun 2026 18:31:21 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Xbl3pHIz"; 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 E2A6565F55 for ; Mon, 29 Jun 2026 18:30:27 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BDB9EE91 for ; Mon, 29 Jun 2026 18:29:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750584; bh=IJi/icnrKqaZDiI5CZq7vFXpwDQxSQPkURvjTG1Vu1g=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Xbl3pHIzShpeGuo6cJe7FH79Zvnp+MB1kZVYhDKN01uYWbmyesEJgnNUSV5TYmqog rdO0VoFSrhfD8rhhrgYkBQOe4g3J/tFRwB8mopTBoRpdObMGkpx/25jlhMy3axwgUJ stvmPcxKxyDVWcUZ10raNmD3Mpf9g2dlJg0vf78M= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 31/54] libcamera: camera: rejectBuffer(): Add Date: Mon, 29 Jun 2026 18:29:54 +0200 Message-ID: <20260629163017.863145-32-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Add a function that can be used to signal that a queued buffer is not acceptable and no data has been stored into it. Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/camera.h | 6 ++++++ src/libcamera/camera.cpp | 32 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h index 31914075f0..13b72258ff 100644 --- a/include/libcamera/internal/camera.h +++ b/include/libcamera/internal/camera.h @@ -59,6 +59,12 @@ public: using PooledFrameBuffer = std::unique_ptr; [[nodiscard]] PooledFrameBuffer acquireBuffer(const Stream *stream); + void rejectBuffer(FrameBuffer *buffer); + + void rejectBuffer(PooledFrameBuffer buffer) + { + return rejectBuffer(buffer.release()); + } private: enum State { diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 016f36e796..be55ed72c4 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -790,6 +790,38 @@ Camera::Private::acquireBuffer(const Stream *stream) it->second.buffers.pop_back(); return { buffer, { &it->second.buffers } }; } + +/** + * \brief Return a buffer to the application + * \param[in] buffer The buffer + * + * \note \a buffer must not be in the camera's buffer pool + * \todo return fence on timeout? + */ +void Camera::Private::rejectBuffer(FrameBuffer *buffer) +{ + ASSERT(!buffer->_d()->request()); + ASSERT(buffer->_d()->stream_); + + LOG(Camera, Debug) + << "Camera:" << LIBCAMERA_O_PTR() << " rejects buffer:" + << buffer << " for stream:" << buffer->_d()->stream_; + + /* + * \todo Not `FrameError` because that requires `timestamp` and + * `sequence` to be valid. + */ + buffer->_d()->cancel(); + buffer->_d()->stream_ = nullptr; + + // \todo separate event (with stream) ? + LIBCAMERA_O_PTR()->bufferCompleted.emit(nullptr, buffer); +} + +/** + * \fn Camera::Private::rejectBuffer(PooledFrameBuffer buffer) + * \copydoc Camera::Private::rejectBuffer(FrameBuffer *buffer) + */ #endif /* __DOXYGEN_PUBLIC__ */ /** From patchwork Mon Jun 29 16:29:55 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27110 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 86880C3261 for ; Mon, 29 Jun 2026 16:31:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 02A8965FB8; Mon, 29 Jun 2026 18:31:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Hf2e1wMd"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 25A4365F5B for ; Mon, 29 Jun 2026 18:30:28 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id EFD7F8D4 for ; Mon, 29 Jun 2026 18:29:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750585; bh=yKt850JBOLibER23MkcXsYZCeB/TFGRIQObBLMLjw4c=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Hf2e1wMdpnCupJ2WlVkxwMZeyYgbjEkALR4cLUwkXHtiO6GnqK21EEckAUS4zpyfd 9WYNixs+FuOfy8/3QC8gQC1ApDyq/6v1yAnniGLAzFwjLGE80BXkmSG806oxsIlYmd We103o6HwiBQpja0xJYcjF0A5Eb5+huxDjQLte5E= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 32/54] libcamera: pipeline_handler: buffersAddedDevice(): New virtual function Date: Mon, 29 Jun 2026 18:29:55 +0200 Message-ID: <20260629163017.863145-33-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" This function allows pipeline handlers to be notified every time new buffers are added to the camera's buffer pool. Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/pipeline_handler.h | 2 ++ src/libcamera/pipeline_handler.cpp | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index d7544642fb..d5b8fdb730 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -103,6 +103,8 @@ protected: virtual bool acquireDevice(Camera *camera); virtual void releaseDevice(Camera *camera); + virtual void buffersAddedDevice(Camera *camera); + CameraManager *manager_; private: diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 36e1509b2b..16f218831c 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -672,10 +672,32 @@ void PipelineHandler::cancelRequest(Request *request) completeRequest(request); } +/** + * \brief Notify about buffer addition + * \param[in] camera The camera + * + * Pipeline handlers may override this function in order to be notified + * after buffers have been added to the camera's buffer pool. + * + * \note This function is only called if the pipeline handler has opted into + * using the buffer pool at construction time. + * + * \context This function is called from the CameraManager thread. + * + * \todo more info? + * + * \sa Camera::addBuffer() + */ +void PipelineHandler::buffersAddedDevice([[maybe_unused]] Camera *camera) +{ +} + void PipelineHandler::buffersAdded(Camera *camera) { if (!options_.usesBufferPool) doQueueRequests(camera); + else + buffersAddedDevice(camera); } /** From patchwork Mon Jun 29 16:29:56 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27113 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 26418C3261 for ; Mon, 29 Jun 2026 16:31:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9BFCD65F9D; Mon, 29 Jun 2026 18:31:24 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="T6nfMgIM"; 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 574D165F5D for ; Mon, 29 Jun 2026 18:30:28 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2E488E91 for ; Mon, 29 Jun 2026 18:29:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750585; bh=L5i53BnAprfOLEtDEsx738K9H6ut2Q3E9lZn67Z1evo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=T6nfMgIMsbqecOO2Og80SmRIekHc1LXmw6oyni3K6BXavU4CpG/lNrJxB0MJkptl9 aaJSvUrIiaHBp2b+d5p0dA16wJM6rkEaNaDSPFg7UkZPmmVjNToOwCE1dqrdGc+TLb K76HQL4WPL8UobV65iu32vMfMULrFl2na3DUfKn8= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 33/54] libcamera: pipeline_handler: Use `std::deque` Date: Mon, 29 Jun 2026 18:29:56 +0200 Message-ID: <20260629163017.863145-34-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" `std::queue` already uses `std::deque` as its implementation, so there is no difference there. And getting a specific index of `std::list` is a linear operation, so replace it with an `std::deque`, to enable pipeline handlers to look into the list more easily. Signed-off-by: Barnabás Pőcze --- include/libcamera/internal/camera.h | 7 +++---- src/libcamera/pipeline_handler.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h index 13b72258ff..7298b150e5 100644 --- a/include/libcamera/internal/camera.h +++ b/include/libcamera/internal/camera.h @@ -8,9 +8,8 @@ #pragma once #include -#include +#include #include -#include #include #include #include @@ -40,8 +39,8 @@ public: PipelineHandler *pipe() { return pipe_.get(); } const PipelineHandler *pipe() const { return pipe_.get(); } - std::list queuedRequests_; - std::queue waitingRequests_; + std::deque queuedRequests_; + std::deque waitingRequests_; ControlInfoMap controlInfo_; ControlList properties_; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 16f218831c..ad1174d043 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -399,7 +399,7 @@ void PipelineHandler::stop(Camera *camera) * after the device to keep them in order. */ Camera::Private *data = camera->_d(); - std::queue waitingRequests; + std::deque waitingRequests; waitingRequests.swap(data->waitingRequests_); /* Stop the pipeline handler and let the queued requests complete. */ @@ -408,7 +408,7 @@ void PipelineHandler::stop(Camera *camera) /* Cancel and signal as complete all waiting requests. */ while (!waitingRequests.empty()) { Request *request = waitingRequests.front(); - waitingRequests.pop(); + waitingRequests.pop_front(); /* * Cancel all requests by marking them as cancelled and calling @@ -498,7 +498,7 @@ void PipelineHandler::queueRequest(Request *request) Camera *camera = request->_d()->camera(); Camera::Private *data = camera->_d(); - data->waitingRequests_.push(request); + data->waitingRequests_.push_back(request); doQueueRequests(camera); } @@ -582,7 +582,7 @@ void PipelineHandler::doQueueRequests(Camera *camera) * Pop the request first, in case doQueueRequests() is called * recursively from within doQueueRequest() */ - data->waitingRequests_.pop(); + data->waitingRequests_.pop_front(); doQueueRequest(request); } } From patchwork Mon Jun 29 16:29:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27112 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 03C7BC3303 for ; Mon, 29 Jun 2026 16:31:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 86A9365F7C; Mon, 29 Jun 2026 18:31:23 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ZJ0WJZLu"; 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 89B8065F42 for ; Mon, 29 Jun 2026 18:30:28 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 622998D4 for ; Mon, 29 Jun 2026 18:29:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750585; bh=+vK2SpvNzAluJ1zJKqGtjiQTF+2eigRZ0Q+xrML6KJE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=ZJ0WJZLuGazRqfwuKFNVURvqwCqAOCpFWo68DLBqiC3NtuNQRS8SFD2z+kmWwrlOA Y2DAnvWZ+v4oG2iCYmM+YxziGbTf9LDAKHrrQkSoE1Up7Kv+VYanpNmdqgiosDvBfI zUA/XA7HogghxX69TcJ+RroQKNhTrkqnz+1i7/Us= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 34/54] libcamera: pipeline_handler: completeRequest(): Return request count Date: Mon, 29 Jun 2026 18:29:57 +0200 Message-ID: <20260629163017.863145-35-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Return the number of requests that were consumed from the head of the `queuedRequests_` queue. This can be used by pipeline handlers using the `queuedRequests_` queue for their bookeeing. Reviewed-by: Barnabás Pőcze --- include/libcamera/internal/pipeline_handler.h | 2 +- src/libcamera/pipeline_handler.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index d5b8fdb730..5aced40cea 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -70,7 +70,7 @@ public: return request->_d()->completeBuffer(buffer); } - void completeRequest(Request *request); + size_t completeRequest(Request *request); void cancelRequest(Request *request); void addBuffer(Camera *camera, diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index ad1174d043..755c78b308 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -636,14 +636,18 @@ void PipelineHandler::doQueueRequests(Camera *camera) * without any ordering constraint. * * \context This function shall be called from the CameraManager thread. + * + * \return The number of requests that were removed from the head of the queued + * requests queue. */ -void PipelineHandler::completeRequest(Request *request) +size_t PipelineHandler::completeRequest(Request *request) { Camera *camera = request->_d()->camera(); request->_d()->complete(); Camera::Private *data = camera->_d(); + size_t consumed = 0; while (!data->queuedRequests_.empty()) { Request *req = data->queuedRequests_.front(); @@ -653,10 +657,13 @@ void PipelineHandler::completeRequest(Request *request) ASSERT(!req->hasPendingBuffers()); data->queuedRequests_.pop_front(); camera->requestComplete(req); + consumed += 1; } /* Allow any waiting requests to be queued to the pipeline. */ doQueueRequests(camera); + + return consumed; } /** From patchwork Mon Jun 29 16:29:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27114 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 63327C3261 for ; Mon, 29 Jun 2026 16:31:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EF1D865F9B; Mon, 29 Jun 2026 18:31:25 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="bgoTa776"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BBDEF65F5E for ; Mon, 29 Jun 2026 18:30:28 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 98BEAE91 for ; Mon, 29 Jun 2026 18:29:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750585; bh=Y8L3gSLz9th3JTgFM5GAGAjtCWKQ7oKsE1dmWHmWxUA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=bgoTa776n2SaY58TbMII4ORAnRHA1HZB9sXs3IK9RD9//qmfwJvbtMzpi/TewZKoS jteAxBYP4itLL1gheJ8DTwLrqXwqn+cAyFfPezmuuUIqOZqYQDeunX5B/oqWD4y4r+ o6zeuhVF2IZ68AS7YpanyThIbsC6IktyuetpmIeY= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 35/54] libcamera: pipeline: uvcvideo: Use buffer pool prototype Date: Mon, 29 Jun 2026 18:29:58 +0200 Message-ID: <20260629163017.863145-36-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Convert the uvcvideo pipeline handler to use the buffer pool interface of cameras. Do that by keeping track of the number of queued buffers, and each time * a request is queued, * a buffer is added, or * a buffer is returned from the kernel the pipeline handler tries to consume as many requests as possible. Signed-off-by: Barnabás Pőcze --- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 71 +++++++++++++++----- 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 928ee79559..e70cbe23c3 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -62,6 +62,8 @@ public: std::optional autoExposureMode_; std::optional manualExposureMode_; + size_t processedRequests_ = 0; + private: bool generateId(); @@ -95,6 +97,8 @@ public: void stopDevice(Camera *camera) override; int queueRequestDevice(Camera *camera, Request *request) override; + void buffersAddedDevice(Camera *camera) override; + void tryRunCamera(UVCCameraData *data); bool match(DeviceEnumerator *enumerator) override; @@ -230,7 +234,7 @@ CameraConfiguration::Status UVCCameraConfiguration::validate() } PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager) - : PipelineHandler(manager, {}) + : PipelineHandler(manager, { .usesBufferPool = true }) { } @@ -323,6 +327,9 @@ void PipelineHandlerUVC::stopDevice(Camera *camera) UVCCameraData *data = cameraData(camera); data->video_->streamOff(); data->video_->releaseBuffers(); + + while (!data->queuedRequests_.empty()) + cancelRequest(data->queuedRequests_.front()); } int PipelineHandlerUVC::processControl(const UVCCameraData *data, ControlList *controls, @@ -446,26 +453,49 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, const ControlList & return ret; } -int PipelineHandlerUVC::queueRequestDevice(Camera *camera, Request *request) +int PipelineHandlerUVC::queueRequestDevice(Camera *camera, [[maybe_unused]] Request *request) { - UVCCameraData *data = cameraData(camera); - FrameBuffer *buffer = request->findBuffer(&data->stream_); - if (!buffer) { - LOG(UVC, Error) - << "Attempt to queue request with invalid stream"; + /* `request` is already in `Camera::Private::queuedRequests_` */ + tryRunCamera(cameraData(camera)); + return 0; +} - return -ENOENT; - } +void PipelineHandlerUVC::buffersAddedDevice(Camera *camera) +{ + tryRunCamera(cameraData(camera)); +} - int ret = processControls(data, request->controls()); - if (ret < 0) - return ret; +void PipelineHandlerUVC::tryRunCamera(UVCCameraData *data) +{ + ASSERT(data->processedRequests_ <= data->queuedRequests_.size()); - ret = data->video_->queueBuffer(buffer); - if (ret < 0) - return ret; + auto it = std::next(data->queuedRequests_.begin(), data->processedRequests_); + for (; it != data->queuedRequests_.end(); ++it, data->processedRequests_++) { + Request *request = *it; + ASSERT(request->status() == Request::RequestPending); - return 0; + int ret = processControls(data, request->controls()); + if (ret < 0) { + cancelRequest(request); + continue; + } + +again:; + auto buffer = data->acquireBuffer(&data->stream_); + if (!buffer) + break; + + ret = data->video_->queueBuffer(buffer.get()); + if (ret < 0) { + // \todo do not do this if the error is "too many buffers" + // but that probably shouldn't ever be the case because + // VIDEO_MAX_FRAME == 32 == maxQueuedRequestsDevice + data->rejectBuffer(std::move(buffer)); + goto again; + } + + buffer.release(); + } } bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator) @@ -893,14 +923,19 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info, void UVCCameraData::imageBufferReady(FrameBuffer *buffer) { - Request *request = buffer->_d()->request(); + ASSERT(!queuedRequests_.empty()); + ASSERT(processedRequests_ > 0); + + Request *request = queuedRequests_.front(); /* \todo Use the UVC metadata to calculate a more precise timestamp */ request->_d()->metadata().set(controls::SensorTimestamp, buffer->metadata().timestamp); pipe()->completeBuffer(request, buffer); - pipe()->completeRequest(request); + processedRequests_ -= pipe()->completeRequest(request); + + static_cast(pipe())->tryRunCamera(this); } REGISTER_PIPELINE_HANDLER(PipelineHandlerUVC, "uvcvideo") From patchwork Mon Jun 29 16:29:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27115 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 CA933C3261 for ; Mon, 29 Jun 2026 16:31:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6F91465F96; Mon, 29 Jun 2026 18:31:27 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="kDObMemi"; 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 0071865F60 for ; Mon, 29 Jun 2026 18:30:29 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D034E1044 for ; Mon, 29 Jun 2026 18:29:45 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750585; bh=mNPadciu9eF3j/cPMIbZCENrQJr8XUSe8TAg7lA7gMs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=kDObMemiboYftLsRocaOla0OquvBUMW9GkgEA4lYavRx9MkI5MEo9QY18x0SAjjzI l87iCwldWmwG6sP0vwcu2V+iN5/2YJukgf1qR3V7J3lRod14Oox20MuduRti8Jv41E nQhIMcEt43IbCuV+MRGYAD2KHl/CDf1C2wOSoxi8= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 36/54] libcamera: request: completeBuffer(): Emit `bufferCompleted` last Date: Mon, 29 Jun 2026 18:29:59 +0200 Message-ID: <20260629163017.863145-37-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" To ensure that the application can see the buffer in the request's buffer map. Signed-off-by: Barnabás Pőcze --- src/libcamera/request.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index d7cf39ae2e..ecdf558066 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -108,8 +108,6 @@ bool Request::Private::completeBuffer(FrameBuffer *buffer) LIBCAMERA_TRACEPOINT(request_complete_buffer, this, buffer); Request *request = LIBCAMERA_O_PTR(); - camera_->bufferCompleted.emit(request, buffer); - auto it = request->bufferMap_.find(buffer->_d()->stream_); ASSERT(it != request->bufferMap_.end()); ASSERT(it->second == buffer || !it->second); @@ -124,6 +122,8 @@ bool Request::Private::completeBuffer(FrameBuffer *buffer) if (buffer->metadata().status == FrameMetadata::FrameCancelled) cancelled_ = true; + camera_->bufferCompleted.emit(request, buffer); + return !hasPendingBuffers(); } From patchwork Mon Jun 29 16:30:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27116 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 160A5C3261 for ; Mon, 29 Jun 2026 16:31:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8E11165FAC; Mon, 29 Jun 2026 18:31:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="f9Prlu1Y"; 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 39FD365F5A for ; Mon, 29 Jun 2026 18:30:29 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 14C5FE91 for ; Mon, 29 Jun 2026 18:29:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750586; bh=t85wYxmHMVG+Juya15nQvnb0oywUplTp+vdfjueU+z8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=f9Prlu1YwIRKl2CTvEGHzhyUPxh7bgMCUXo/f73jl4GNT/sm3BPSulkuuBdngWA1S 8sR8S+M0yjHRXimGThudkLoGkA3NJE6iA92ZsoQky9la1IRvvBwfQvknJe5QegULm9 TqUIrWPGHtpMTe92BdhPgEPpkJX6d0PrLVeFZEYw= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 37/54] libcamera: camera: bufferCompleted: Pass `Stream` as well Date: Mon, 29 Jun 2026 18:30:00 +0200 Message-ID: <20260629163017.863145-38-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Provide information about which stream the just completed buffer belongs to. This makes it easier for applications to know how to process the request, since they do not need to have a buffer -> stream mapping or a series of `request->findBuffer(stream) == buffer` conditions. Signed-off-by: Barnabás Pőcze --- include/libcamera/camera.h | 2 +- src/libcamera/camera.cpp | 10 ++++++---- src/libcamera/pipeline_handler.cpp | 8 ++++---- src/libcamera/request.cpp | 5 +++-- test/camera/buffer_import.cpp | 1 + test/camera/capture.cpp | 1 + 6 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 471975a890..0195a9f3a8 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -124,7 +124,7 @@ public: const std::string &id() const; - Signal bufferCompleted; + Signal bufferCompleted; Signal requestCompleted; Signal<> disconnected; diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index be55ed72c4..1bb696566c 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -800,12 +800,14 @@ Camera::Private::acquireBuffer(const Stream *stream) */ void Camera::Private::rejectBuffer(FrameBuffer *buffer) { + const Stream *stream = buffer->_d()->stream_; + ASSERT(!buffer->_d()->request()); - ASSERT(buffer->_d()->stream_); + ASSERT(stream); LOG(Camera, Debug) << "Camera:" << LIBCAMERA_O_PTR() << " rejects buffer:" - << buffer << " for stream:" << buffer->_d()->stream_; + << buffer << " for stream:" << stream; /* * \todo Not `FrameError` because that requires `timestamp` and @@ -814,8 +816,8 @@ void Camera::Private::rejectBuffer(FrameBuffer *buffer) buffer->_d()->cancel(); buffer->_d()->stream_ = nullptr; - // \todo separate event (with stream) ? - LIBCAMERA_O_PTR()->bufferCompleted.emit(nullptr, buffer); + // \todo separate event? + LIBCAMERA_O_PTR()->bufferCompleted.emit(nullptr, stream, buffer); } /** diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 755c78b308..27ce25ad11 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -421,20 +421,20 @@ void PipelineHandler::stop(Camera *camera) doQueueRequest(request); } - const auto returnBuffer = [&](FrameBuffer *buffer) { + const auto returnBuffer = [&](const Stream *stream, FrameBuffer *buffer) { ASSERT(!buffer->_d()->stream_); buffer->_d()->cancel(); - camera->bufferCompleted.emit(nullptr, buffer); + camera->bufferCompleted.emit(nullptr, stream, buffer); }; for (auto &pf : data->pendingFences_) - returnBuffer(pf.buffer); + returnBuffer(pf.stream, pf.buffer); data->pendingFences_.clear(); for (auto &[stream, streamData] : data->streamData_) { for (FrameBuffer *buffer : streamData.buffers) - returnBuffer(buffer); + returnBuffer(stream, buffer); streamData.buffers.clear(); } diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index ecdf558066..4fb8c0a659 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -108,7 +108,8 @@ bool Request::Private::completeBuffer(FrameBuffer *buffer) LIBCAMERA_TRACEPOINT(request_complete_buffer, this, buffer); Request *request = LIBCAMERA_O_PTR(); - auto it = request->bufferMap_.find(buffer->_d()->stream_); + const Stream *stream = buffer->_d()->stream_; + auto it = request->bufferMap_.find(stream); ASSERT(it != request->bufferMap_.end()); ASSERT(it->second == buffer || !it->second); @@ -122,7 +123,7 @@ bool Request::Private::completeBuffer(FrameBuffer *buffer) if (buffer->metadata().status == FrameMetadata::FrameCancelled) cancelled_ = true; - camera_->bufferCompleted.emit(request, buffer); + camera_->bufferCompleted.emit(request, stream, buffer); return !hasPendingBuffers(); } diff --git a/test/camera/buffer_import.cpp b/test/camera/buffer_import.cpp index 5e271ad3d0..c6f35a3135 100644 --- a/test/camera/buffer_import.cpp +++ b/test/camera/buffer_import.cpp @@ -39,6 +39,7 @@ public: protected: void bufferComplete([[maybe_unused]] Request *request, + [[maybe_unused]] const Stream *stream, FrameBuffer *buffer) { if (buffer->metadata().status != FrameMetadata::FrameSuccess) diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index fabe297e53..bc8cf4c59d 100644 --- a/test/camera/capture.cpp +++ b/test/camera/capture.cpp @@ -35,6 +35,7 @@ protected: unsigned int completeRequestsCount_; void bufferComplete([[maybe_unused]] Request *request, + [[maybe_unused]] const Stream *stream, FrameBuffer *buffer) { if (buffer->metadata().status != FrameMetadata::FrameSuccess) From patchwork Mon Jun 29 16:30:01 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27117 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 2D324C3261 for ; Mon, 29 Jun 2026 16:31:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D59A665F64; Mon, 29 Jun 2026 18:31:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="pbVu9vfU"; 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 847B765F62 for ; Mon, 29 Jun 2026 18:30:29 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 48F461044 for ; Mon, 29 Jun 2026 18:29:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750586; bh=M2bGTbr4O0da3jkzbBy+sb7hMqzxMpY0VfCgsPkWnwk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=pbVu9vfUJF1rkFpEkojwLXv+0gcRDqTMOCd361WJlJ6JIaHT0uGTieyQwC8fHNSev ZY/BfuEME59oQnYvTYR07LC6r2anboJKlgFX1vRTRxAHjgbgAQ7H2PxLobpKjeXgpD hXOjzhYGyG0ivx7HfnXwoBntjVySv0UV+a4/7R1U= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 38/54] libcamera: camera: queueRequest(): Adjust buffer map empty error message Date: Mon, 29 Jun 2026 18:30:01 +0200 Message-ID: <20260629163017.863145-39-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" If the buffer map is empty, that means no streams are enabled, so adjust the error message accordingly. Signed-off-by: Barnabás Pőcze --- src/libcamera/camera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index 1bb696566c..a9e6708fbf 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -1449,7 +1449,7 @@ int Camera::queueRequest(Request *request) */ if (request->buffers().empty()) { - LOG(Camera, Error) << "Request contains no buffers"; + LOG(Camera, Error) << "Request contains no enabled streams"; return -EINVAL; } From patchwork Mon Jun 29 16:30:02 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27118 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 5693FC3261 for ; Mon, 29 Jun 2026 16:31:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EFB7665FD0; Mon, 29 Jun 2026 18:31:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="sNjD2Iwp"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E0D9265F38 for ; Mon, 29 Jun 2026 18:30:29 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9C94EE91 for ; Mon, 29 Jun 2026 18:29:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750586; bh=odxPTq4XczUbF5oAC9jgieq8AP5Bba8TWoPc3FRjISk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=sNjD2IwpfMnHpFm/9ETgLyuuxqCMhkzL2v9VWyTGA3sH3l+T9jdUpi8zZWzFE2ERu nmyPSnBcUK5fJq75NjQF9igbEUqfqjCzKxa4k6hqxegqHaFDcyBjk6b8w5LGQVd+ws vyknoiaNqGj9ohCKmgCPr4XTLke7rOLJ7+nW2Dxs= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 39/54] libcamera: camera: queueBuffer(): Reject if it has buffers Date: Mon, 29 Jun 2026 18:30:02 +0200 Message-ID: <20260629163017.863145-40-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" If a request has buffers, it means it was not `reuse()`d properly, so reject those requests. Signed-off-by: Barnabás Pőcze --- src/libcamera/camera.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index a9e6708fbf..a1f90a35c0 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -1459,6 +1459,11 @@ int Camera::queueRequest(Request *request) LOG(Camera, Error) << "Invalid request"; return -EINVAL; } + + if (buffer) { + LOG(Camera, Error) << "Request contains buffers"; + return -EINVAL; + } } /* Pre-process AeEnable. */ From patchwork Mon Jun 29 16:30:03 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27120 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 943C7C3261 for ; Mon, 29 Jun 2026 16:31:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4049165FBC; Mon, 29 Jun 2026 18:31:33 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="kKR63sam"; 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 1BA3A65F64 for ; Mon, 29 Jun 2026 18:30:30 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E98A41044 for ; Mon, 29 Jun 2026 18:29:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750587; bh=rNdZNN7v1xAahbXGvApcE11d2/muHTpm2AxB3CgCdis=; h=From:To:Subject:Date:In-Reply-To:References:From; b=kKR63samUeUtpGv1xhaZil0lnT4Aql6bzUC/mh+8wqXUOyEnO5MQUfMYV+1kI8QpO haZN3+TTqTtqDxl6iPO3hR4Ky9LLq2Nv6bbo7w39WEEx0UjVAuB3UzTF13nyrTK+53 EN6Fn6IhDRLrJKI2bIqVWzShWLYe5g1egV6FrIHo= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 40/54] apps: cam: Use camera buffer pool Date: Mon, 29 Jun 2026 18:30:03 +0200 Message-ID: <20260629163017.863145-41-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Convert the `cam` application to use the new buffer pool interface of cameras. Signed-off-by: Barnabás Pőcze --- src/apps/cam/camera_session.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/apps/cam/camera_session.cpp b/src/apps/cam/camera_session.cpp index f90800caf8..fc91bb312a 100644 --- a/src/apps/cam/camera_session.cpp +++ b/src/apps/cam/camera_session.cpp @@ -388,12 +388,7 @@ int CameraSession::startCapture() allocator_->buffers(stream); const std::unique_ptr &buffer = buffers[i]; - ret = request->addBuffer(stream, buffer.get()); - if (ret < 0) { - std::cerr << "Can't set buffer for request" - << std::endl; - return ret; - } + request->enableStream(stream, true); if (sink_) sink_->mapBuffer(buffer.get()); @@ -418,6 +413,15 @@ int CameraSession::startCapture() return ret; } + for (const StreamConfiguration &cfg : *config_) { + Stream *stream = cfg.stream(); + const std::vector> &buffers = + allocator_->buffers(stream); + + for (const auto &buffer : buffers) + camera_->addBuffer(stream, buffer.get()); + } + for (std::unique_ptr &request : requests_) { ret = queueRequest(request.get()); if (ret < 0) { @@ -548,6 +552,13 @@ void CameraSession::processRequest(Request *request) void CameraSession::requeueRequest(Request *request) { - request->reuse(Request::ReuseBuffers); + for (const auto &[stream, buffer] : request->buffers()) + camera_->addBuffer(stream, buffer); + + request->reuse(); + + for (const auto &cfg : *config_) + request->enableStream(cfg.stream(), true); + queueRequest(request); } From patchwork Mon Jun 29 16:30:04 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27119 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 52613C3261 for ; Mon, 29 Jun 2026 16:31:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EE24D65FC7; Mon, 29 Jun 2026 18:31:31 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="lfeNlG6R"; 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 5362465F2C for ; Mon, 29 Jun 2026 18:30:30 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2B00DE91 for ; Mon, 29 Jun 2026 18:29:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750587; bh=I16+fIsMsBuYE2MczZTvkNlv97XF1oFMoVrjPo25gbQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=lfeNlG6RV1zNe+s4Lz0Bzlll5YnAt43Jbno4Zq9Q2xfJ+741ywwtCFhq6lvpsrAz+ 1qml+51rTP/8aXLqJOn/x306nggpScUgWqiRo2xcoAuLSjHYtsby+zqLOpchZxr1Zz IoseO1s9pRFI5Xgz3kCPdVz21T0R8BnV+1MGrzTo= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 41/54] app: lc-compliance: Use camera buffer pool Date: Mon, 29 Jun 2026 18:30:04 +0200 Message-ID: <20260629163017.863145-42-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Convert the `lc-compliance` application to use the new buffer pool interface of cameras. Signed-off-by: Barnabás Pőcze --- src/apps/lc-compliance/helpers/capture.cpp | 23 ++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/apps/lc-compliance/helpers/capture.cpp b/src/apps/lc-compliance/helpers/capture.cpp index d83269d4a9..2a645b4445 100644 --- a/src/apps/lc-compliance/helpers/capture.cpp +++ b/src/apps/lc-compliance/helpers/capture.cpp @@ -88,6 +88,9 @@ int Capture::queueRequest(libcamera::Request *request) if (queueLimit_ && queueCount_ >= *queueLimit_) return 0; + for (const auto &cfg : *config_) + request->enableStream(cfg.stream(), true); + int ret = camera_->queueRequest(request); if (ret < 0) return ret; @@ -107,7 +110,10 @@ void Capture::requestComplete(Request *request) EXPECT_EQ(request->status(), Request::Status::RequestComplete) << "Request didn't complete successfully"; - request->reuse(Request::ReuseBuffers); + for (const auto &[stream, buffer] : request->buffers()) + camera_->addBuffer(stream, buffer); + + request->reuse(); if (queueRequest(request)) loop_->exit(-EINVAL); } @@ -141,11 +147,6 @@ void Capture::start() const auto &buffers = allocator_.buffers(stream); ASSERT_EQ(buffers.size(), bufferCount) << "Mismatching buffer count"; - - for (std::size_t i = 0; i < bufferCount; i++) { - ASSERT_EQ(requests_[i]->addBuffer(stream, buffers[i].get()), 0) - << "Failed to add buffer to request"; - } } ASSERT_TRUE(allocator_.allocated()); @@ -153,6 +154,16 @@ void Capture::start() camera_->requestCompleted.connect(this, &Capture::requestComplete); ASSERT_EQ(camera_->start(), 0) << "Failed to start camera"; + + for (const auto &cfg : *config_) { + Stream *stream = cfg.stream(); + const auto &buffers = allocator_.buffers(stream); + + for (std::size_t i = 0; i < bufferCount; i++) { + ASSERT_EQ(camera_->addBuffer(stream, buffers[i].get()), 0) + << "Failed to add buffer"; + } + } } void Capture::stop() From patchwork Mon Jun 29 16:30:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27121 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 CBF49C3261 for ; Mon, 29 Jun 2026 16:31:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 63CC065FB4; Mon, 29 Jun 2026 18:31:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HCUbhBuG"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 86F4865F67 for ; Mon, 29 Jun 2026 18:30:30 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6203B1044 for ; Mon, 29 Jun 2026 18:29:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750587; bh=XDpIfMwN9sk/4wblvqoDdLcgCYGwYnvaFy8Y9/2q/aQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=HCUbhBuGCYomCT8qkihyY+W5rLjYaSA9N51gD/ZLEvmGDprCUEGuZwXwwWfD8YFvJ 9RK1E4KMtXALzvMTtuKn4Q1jVrJeN7iQFuzld96FJV34+cTzLHM9JoYh3wPZws03GV 1klJQQ4sO/MNwby0GE/Gxh+ZgZ6va17rHWzQhCHM= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 42/54] apps: lc-compliance: Add buffer pool tests Date: Mon, 29 Jun 2026 18:30:05 +0200 Message-ID: <20260629163017.863145-43-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Add a couple tests that test the functioning of the buffer pool of a camera. Signed-off-by: Barnabás Pőcze --- src/apps/lc-compliance/tests/capture_test.cpp | 261 ++++++++++++++++++ 1 file changed, 261 insertions(+) diff --git a/src/apps/lc-compliance/tests/capture_test.cpp b/src/apps/lc-compliance/tests/capture_test.cpp index d7d6f0626e..f256ec3033 100644 --- a/src/apps/lc-compliance/tests/capture_test.cpp +++ b/src/apps/lc-compliance/tests/capture_test.cpp @@ -8,8 +8,10 @@ #include "capture.h" +#include #include #include +#include #include #include @@ -142,4 +144,263 @@ INSTANTIATE_TEST_SUITE_P(MultiStream, testing::ValuesIn(NUMREQUESTS)), SimpleCapture::nameParameters); +class TestWithCamera : public testing::Test, public CameraHolder +{ +protected: + void SetUp() override { acquireCamera(); } + void TearDown() override { releaseCamera(); } +}; + +class BufferPool : public TestWithCamera +{ +protected: + void SetUp() override + { + TestWithCamera::SetUp(); + + config_ = camera_->generateConfiguration({ StreamRole::Viewfinder }); + ASSERT_TRUE(config_); + ASSERT_FALSE(config_->empty()); + + ASSERT_EQ(camera_->configure(config_.get()), 0); + } + + void TearDown() override + { + config_.reset(); + TestWithCamera::TearDown(); + } + + std::vector> + createRequests(std::size_t count) + { + std::vector> requests; + + for (std::size_t i = 0; i < count; i++) { + auto request = camera_->createRequest(i); + [&] { ASSERT_TRUE(request); }(); + + for (const auto &cfg : *config_) + request->enableStream(cfg.stream(), true); + + requests.push_back(std::move(request)); + } + + return requests; + } + + std::unique_ptr config_; +}; + +template +struct ScopedSignalReceiver { + Signal &signal; + T *object = nullptr; + + template + ScopedSignalReceiver(Signal &s, T *o, Func f) + : signal(s), object(o) + { + signal.connect(o, std::move(f)); + } + + ~ScopedSignalReceiver() + { + signal.disconnect(object); + } +}; + +template +ScopedSignalReceiver(Signal &, T *) -> ScopedSignalReceiver; + +struct ScopedCameraStart { + Camera &camera; + + ScopedCameraStart(Camera &c) + : camera(c) + { + [&]() { ASSERT_EQ(camera.start(), 0); }(); + } + + ~ScopedCameraStart() + { + EXPECT_EQ(camera.stop(), 0); + } +}; + +TEST_F(BufferPool, BufferBeforeRequest) +{ + FrameBufferAllocator fba(camera_); + + std::size_t buffers = -1; + for (const auto &cfg : *config_) { + ASSERT_GT(fba.allocate(cfg.stream()), 0); + buffers = std::min(buffers, fba.buffers(cfg.stream()).size()); + } + + auto requests = createRequests(buffers); + + std::counting_semaphore<> requestCompletedSemaphore(0); + bool requestCompletedOk = true; + unsigned int requestCompleted = 0; + ScopedSignalReceiver rcr(camera_->requestCompleted, this, [&](Request *request) { + if (requestCompleted < requests.size()) + requestCompletedOk &= request == requests[requestCompleted].get(); + + requestCompletedSemaphore.release(1); + requestCompleted += 1; + }); + + { + ScopedCameraStart scs(*camera_); + + for (const auto &cfg : *config_) { + Stream *stream = cfg.stream(); + for (const auto &buffer : fba.buffers(stream)) + EXPECT_EQ(camera_->addBuffer(stream, buffer.get()), 0); + } + + for (const auto &request : requests) + ASSERT_EQ(camera_->queueRequest(request.get()), 0); + + auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(buffers); + + for (size_t i = 0; i < buffers; i++) { + if (!requestCompletedSemaphore.try_acquire_until(deadline)) + break; + } + } + + EXPECT_TRUE(requestCompletedOk); + ASSERT_FALSE(requestCompletedSemaphore.try_acquire()); + EXPECT_EQ(requestCompleted, buffers); +} + +TEST_F(BufferPool, RequestBeforeBuffer) +{ + FrameBufferAllocator fba(camera_); + + std::size_t buffers = -1; + for (const auto &cfg : *config_) { + ASSERT_GT(fba.allocate(cfg.stream()), 0); + buffers = std::min(buffers, fba.buffers(cfg.stream()).size()); + } + + auto requests = createRequests(buffers); + + std::counting_semaphore<> requestCompletedSemaphore(0); + bool requestCompletedOk = true; + unsigned int requestCompleted = 0; + ScopedSignalReceiver rcr(camera_->requestCompleted, this, [&](Request *request) { + if (requestCompleted < requests.size()) + requestCompletedOk &= request == requests[requestCompleted].get(); + + requestCompletedSemaphore.release(1); + requestCompleted += 1; + }); + + { + ScopedCameraStart scs(*camera_); + + for (const auto &request : requests) + ASSERT_EQ(camera_->queueRequest(request.get()), 0); + + std::this_thread::sleep_for(std::chrono::seconds(2)); + ASSERT_FALSE(requestCompletedSemaphore.try_acquire()); + ASSERT_EQ(requestCompleted, 0); + + auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(buffers); + + for (const auto &cfg : *config_) { + Stream *stream = cfg.stream(); + for (const auto &buffer : fba.buffers(stream)) + EXPECT_EQ(camera_->addBuffer(stream, buffer.get()), 0); + } + + for (size_t i = 0; i < buffers; i++) { + if (!requestCompletedSemaphore.try_acquire_until(deadline)) + break; + } + } + + EXPECT_TRUE(requestCompletedOk); + ASSERT_FALSE(requestCompletedSemaphore.try_acquire()); + EXPECT_EQ(requestCompleted, buffers); +} + +TEST_F(BufferPool, BufferWithoutRequest) +{ + FrameBufferAllocator fba(camera_); + std::set> buffers; + + for (const auto &cfg : *config_) { + Stream *stream = cfg.stream(); + ASSERT_GT(fba.allocate(stream), 0); + + for (const auto &buffer : fba.buffers(stream)) + buffers.insert({ stream, buffer.get() }); + } + + unsigned int requestCompleted = 0; + ScopedSignalReceiver rcr(camera_->requestCompleted, this, [&](Request *) { + requestCompleted += 1; + }); + + bool bufferCompletedOk = true; + ScopedSignalReceiver bcr(camera_->bufferCompleted, this, [&](Request *request, const Stream *stream, FrameBuffer *buffer) { + bufferCompletedOk &= !request; + bufferCompletedOk &= buffer->metadata().status == libcamera::FrameMetadata::FrameCancelled; + bufferCompletedOk &= buffers.erase({ stream, buffer }); + }); + + { + ScopedCameraStart scs(*camera_); + + for (const auto &cfg : *config_) { + Stream *stream = cfg.stream(); + for (const auto &buffer : fba.buffers(stream)) + EXPECT_EQ(camera_->addBuffer(stream, buffer.get()), 0); + } + } + + EXPECT_EQ(requestCompleted, 0); + EXPECT_EQ(buffers.size(), 0); + EXPECT_TRUE(bufferCompletedOk); +} + +TEST_F(BufferPool, RequestWithoutBuffers) +{ + constexpr std::size_t kRequestCount = 128; + auto requests = createRequests(kRequestCount); + + unsigned int requestCompleted = 0; + bool requestCompletedOk = true; + ScopedSignalReceiver rcr(camera_->requestCompleted, this, [&](Request *request) { + if (requestCompleted < requests.size()) { + requestCompletedOk &= request == requests[requestCompleted].get(); + requestCompletedOk &= request->status() == Request::Status::RequestCancelled; + } + + requestCompleted += 1; + }); + + unsigned int bufferCompleted = 0; + ScopedSignalReceiver bcr(camera_->bufferCompleted, this, [&](Request *, const Stream *, FrameBuffer *) { + bufferCompleted += 1; + }); + + { + ScopedCameraStart scs(*camera_); + + for (const auto &request : requests) + ASSERT_EQ(camera_->queueRequest(request.get()), 0); + + std::this_thread::sleep_for(std::chrono::seconds(2)); + } + + EXPECT_EQ(requestCompleted, requests.size()); + EXPECT_TRUE(requestCompletedOk); + EXPECT_EQ(bufferCompleted, 0); +} + } /* namespace */ From patchwork Mon Jun 29 16:30:06 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27122 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 D6273C3303 for ; Mon, 29 Jun 2026 16:31:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7FB1465FC1; Mon, 29 Jun 2026 18:31:35 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="lsnPwV1Q"; 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 BEA5065F68 for ; Mon, 29 Jun 2026 18:30:30 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 96621E91 for ; Mon, 29 Jun 2026 18:29:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750587; bh=hLyydRT7gnfRwyUIKcRyO2xfLAfGw2wn7YD6yupxNQo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=lsnPwV1QjOrCmTsb3zFHMTjweiHdUz81VZLu9sc+Wh+RUY01mPK8ih/Y3JYfehpsV 0TG6pWSkAHCQxkTev2jEDWtEPcLnqQeNRVRJYOwBjUlIumXXgJt3oAVfBV56FQwSLp 0+5ro+bl0a0xQUOZ9iWD4XBgxFdYNXOlyrSrMJS0= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 43/54] test: Use camera buffer pool Date: Mon, 29 Jun 2026 18:30:06 +0200 Message-ID: <20260629163017.863145-44-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Port to using the camera's buffer pool. Reviewed-by: Barnabás Pőcze --- test/camera/buffer_import.cpp | 21 +++++++++++++++------ test/camera/camera_reconfigure.cpp | 22 +++++++++++++++------- test/camera/capture.cpp | 23 ++++++++++++++++------- test/camera/statemachine.cpp | 4 +++- 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/test/camera/buffer_import.cpp b/test/camera/buffer_import.cpp index c6f35a3135..0fd1749acc 100644 --- a/test/camera/buffer_import.cpp +++ b/test/camera/buffer_import.cpp @@ -55,7 +55,12 @@ protected: completeRequestsCount_++; - request->reuse(Request::ReuseBuffers); + for (const auto &[stream, buffer] : request->buffers()) + camera_->addBuffer(stream, buffer); + + request->reuse(); + request->enableStream(config_->at(0).stream(), true); + camera_->queueRequest(request); dispatcher_->interrupt(); @@ -98,17 +103,14 @@ protected: if (ret != TestPass) return ret; - for (const std::unique_ptr &buffer : source.buffers()) { + for ([[maybe_unused]] const auto &buffer : source.buffers()) { std::unique_ptr request = camera_->createRequest(); if (!request) { std::cout << "Failed to create request" << std::endl; return TestFail; } - if (request->addBuffer(stream, buffer.get())) { - std::cout << "Failed to associating buffer with request" << std::endl; - return TestFail; - } + request->enableStream(stream, true); requests_.push_back(std::move(request)); } @@ -124,6 +126,13 @@ protected: return TestFail; } + for (const std::unique_ptr &buffer : source.buffers()) { + if (camera_->addBuffer(stream, buffer.get())) { + std::cout << "Failed to add buffer" << std::endl; + return TestFail; + } + } + for (std::unique_ptr &request : requests_) { if (camera_->queueRequest(request.get())) { std::cout << "Failed to queue request" << std::endl; diff --git a/test/camera/camera_reconfigure.cpp b/test/camera/camera_reconfigure.cpp index ae9941c16b..0688a24582 100644 --- a/test/camera/camera_reconfigure.cpp +++ b/test/camera/camera_reconfigure.cpp @@ -46,8 +46,12 @@ private: if (request->status() != Request::RequestComplete) return; - /* Reuse the request and re-queue it with the same buffers. */ - request->reuse(Request::ReuseBuffers); + for (const auto &[stream, buffer] : request->buffers()) + camera_->addBuffer(stream, buffer); + + request->reuse(); + request->enableStream(config_->at(0).stream(), true); + camera_->queueRequest(request); } @@ -80,17 +84,14 @@ private: allocated_ = true; } - for (const unique_ptr &buffer : allocator_->buffers(stream)) { + for ([[maybe_unused]] const auto &buffer : allocator_->buffers(stream)) { unique_ptr request = camera_->createRequest(); if (!request) { cerr << "Failed to create request" << endl; return TestFail; } - if (request->addBuffer(stream, buffer.get())) { - cerr << "Failed to associate buffer with request" << endl; - return TestFail; - } + request->enableStream(stream, true); requests_.push_back(std::move(request)); } @@ -102,6 +103,13 @@ private: return TestFail; } + for (const unique_ptr &buffer : allocator_->buffers(stream)) { + if (camera_->addBuffer(stream, buffer.get())) { + cerr << "Failed to add buffer" << endl; + return TestFail; + } + } + for (unique_ptr &request : requests_) { if (camera_->queueRequest(request.get())) { cerr << "Failed to queue request" << endl; diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index bc8cf4c59d..35ceabf87a 100644 --- a/test/camera/capture.cpp +++ b/test/camera/capture.cpp @@ -51,7 +51,12 @@ protected: completeRequestsCount_++; - request->reuse(Request::ReuseBuffers); + for (const auto &[stream, buffer] : request->buffers()) + camera_->addBuffer(stream, buffer); + + request->reuse(); + request->enableStream(config_->at(0).stream(), true); + camera_->queueRequest(request); dispatcher_->interrupt(); @@ -99,17 +104,14 @@ protected: if (ret < 0) return TestFail; - for (const std::unique_ptr &buffer : allocator_->buffers(stream)) { - std::unique_ptr request = camera_->createRequest(); + for ([[maybe_unused]] const auto &buffer : allocator_->buffers(stream)) { + unique_ptr request = camera_->createRequest(); if (!request) { cout << "Failed to create request" << endl; return TestFail; } - if (request->addBuffer(stream, buffer.get())) { - cout << "Failed to associate buffer with request" << endl; - return TestFail; - } + request->enableStream(stream, true); requests_.push_back(std::move(request)); } @@ -125,6 +127,13 @@ protected: return TestFail; } + for (const unique_ptr &buffer : allocator_->buffers(stream)) { + if (camera_->addBuffer(stream, buffer.get())) { + cout << "Failed to add buffer" << endl; + return TestFail; + } + } + for (std::unique_ptr &request : requests_) { if (camera_->queueRequest(request.get())) { cout << "Failed to queue request" << endl; diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp index 9c2b0c6a7d..97bd5344cd 100644 --- a/test/camera/statemachine.cpp +++ b/test/camera/statemachine.cpp @@ -150,9 +150,11 @@ protected: return TestFail; Stream *stream = *camera_->streams().begin(); - if (request->addBuffer(stream, allocator_->buffers(stream)[0].get())) + if (camera_->addBuffer(stream, allocator_->buffers(stream)[0].get())) return TestFail; + request->enableStream(stream, true); + if (camera_->queueRequest(request.get())) return TestFail; From patchwork Mon Jun 29 16:30:07 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27124 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 E30AEC3303 for ; Mon, 29 Jun 2026 16:31:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8EE5A65FBD; Mon, 29 Jun 2026 18:31:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="huKN8w6Q"; 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 081CB65F5C for ; Mon, 29 Jun 2026 18:30:31 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D01391044 for ; Mon, 29 Jun 2026 18:29:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750587; bh=I4ClZ5ta5pXE4oYt7eSCkwnoeLv+vpjFH1SChap4SfA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=huKN8w6QUiAsBq0CCs85wiS3pAvXjhwD/RwY2eQ40nZKd/rU/70JY0HFbLXEpnNwv mvsCDOiEmP37CLsxzM357MS41tuhK7eWzpr9OcQZSaNz1bZib5f0ZdEsJvlikWay9c R+JXbHezvP92WR4x8meHfqrCmYuKbpo6q7h2h+uc= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 44/54] apps: qcam: Use camera buffer pool Date: Mon, 29 Jun 2026 18:30:07 +0200 Message-ID: <20260629163017.863145-45-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Port to using the camera's buffer pool. Signed-off-by: Barnabás Pőcze --- src/apps/qcam/main_window.cpp | 82 ++++++++++++++--------------------- src/apps/qcam/main_window.h | 1 - 2 files changed, 33 insertions(+), 50 deletions(-) diff --git a/src/apps/qcam/main_window.cpp b/src/apps/qcam/main_window.cpp index 59c2aa66cb..a0d5b0798c 100644 --- a/src/apps/qcam/main_window.cpp +++ b/src/apps/qcam/main_window.cpp @@ -466,30 +466,7 @@ int MainWindow::startCapture() Image::fromFrameBuffer(buffer.get(), Image::MapMode::ReadOnly); assert(image != nullptr); mappedBuffers_[buffer.get()] = std::move(image); - - /* Store buffers on the free list. */ - freeBuffers_[stream].enqueue(buffer.get()); - } - } - - /* Create requests and fill them with buffers from the viewfinder. */ - while (!freeBuffers_[vfStream_].isEmpty()) { - FrameBuffer *buffer = freeBuffers_[vfStream_].dequeue(); - - std::unique_ptr request = camera_->createRequest(); - if (!request) { - qWarning() << "Can't create request"; - ret = -ENOMEM; - goto error; - } - - ret = request->addBuffer(vfStream_, buffer); - if (ret < 0) { - qWarning() << "Can't set buffer for request"; - goto error; } - - requests_.push_back(std::move(request)); } /* Start the title timer and the camera. */ @@ -507,13 +484,36 @@ int MainWindow::startCapture() camera_->requestCompleted.connect(this, &MainWindow::requestComplete); + for (StreamConfiguration &config : *config_) { + Stream *stream = config.stream(); + + for (const std::unique_ptr &buffer : allocator_->buffers(stream)) { + ret = camera_->addBuffer(stream, buffer.get()); + if (ret < 0) { + qWarning() << "Can't add buffer"; + goto error_disconnect; + } + } + } + /* Queue all requests. */ - for (std::unique_ptr &request : requests_) { + for ([[maybe_unused]] const auto &buffer : allocator_->buffers(vfStream_)) { + std::unique_ptr request = camera_->createRequest(); + if (!request) { + qWarning() << "Can't create request"; + ret = -ENOMEM; + goto error_disconnect; + } + + request->enableStream(vfStream_, true); + ret = queueRequest(request.get()); if (ret < 0) { qWarning() << "Can't queue request"; goto error_disconnect; } + + requests_.push_back(std::move(request)); } isCapturing_ = true; @@ -529,8 +529,6 @@ error: mappedBuffers_.clear(); - freeBuffers_.clear(); - allocator_.reset(); return ret; @@ -574,7 +572,6 @@ void MainWindow::stopCapture() * but not processed yet. Clear the queue of done buffers to avoid * racing with the event handler. */ - freeBuffers_.clear(); doneQueue_.clear(); titleTimer_.stop(); @@ -661,11 +658,6 @@ void MainWindow::processRaw(FrameBuffer *buffer, memory); } #endif - - { - QMutexLocker locker(&mutex_); - freeBuffers_[rawStream_].enqueue(buffer); - } } /* ----------------------------------------------------------------------------- @@ -710,8 +702,10 @@ void MainWindow::processCapture() if (request->buffers().count(vfStream_)) processViewfinder(request->buffers().at(vfStream_)); - if (request->buffers().count(rawStream_)) - processRaw(request->buffers().at(rawStream_), request->metadata()); + if (auto it = request->buffers().find(rawStream_); it != request->buffers().end()) { + processRaw(it->second, request->metadata()); + camera_->addBuffer(it->first, it->second); + } request->reuse(); QMutexLocker locker(&mutex_); @@ -744,6 +738,8 @@ void MainWindow::processViewfinder(FrameBuffer *buffer) void MainWindow::renderComplete(FrameBuffer *buffer) { + camera_->addBuffer(vfStream_, buffer); + Request *request; { QMutexLocker locker(&mutex_); @@ -753,23 +749,11 @@ void MainWindow::renderComplete(FrameBuffer *buffer) request = freeQueue_.dequeue(); } - request->addBuffer(vfStream_, buffer); + request->enableStream(vfStream_, true); if (captureRaw_) { - FrameBuffer *rawBuffer = nullptr; - - { - QMutexLocker locker(&mutex_); - if (!freeBuffers_[rawStream_].isEmpty()) - rawBuffer = freeBuffers_[rawStream_].dequeue(); - } - - if (rawBuffer) { - request->addBuffer(rawStream_, rawBuffer); - captureRaw_ = false; - } else { - qWarning() << "No free buffer available for RAW capture"; - } + request->enableStream(rawStream_, true); + captureRaw_ = false; } queueRequest(request); } diff --git a/src/apps/qcam/main_window.h b/src/apps/qcam/main_window.h index 20d369ad23..458c5a63b6 100644 --- a/src/apps/qcam/main_window.h +++ b/src/apps/qcam/main_window.h @@ -119,7 +119,6 @@ private: bool captureRaw_; libcamera::Stream *vfStream_; libcamera::Stream *rawStream_; - std::map> freeBuffers_; QQueue doneQueue_; QQueue freeQueue_; QMutex mutex_; /* Protects freeBuffers_, doneQueue_, and freeQueue_ */ From patchwork Mon Jun 29 16:30:08 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27123 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 F1FBAC3261 for ; Mon, 29 Jun 2026 16:31:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9B31B65FB5; Mon, 29 Jun 2026 18:31:36 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SQLqhFjL"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 53A5265F58 for ; Mon, 29 Jun 2026 18:30:31 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 161DBE91 for ; Mon, 29 Jun 2026 18:29:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750588; bh=aRpYZWGIoniLqjhqzwyxfl+wM9XzsrE02kWnvo9W4Ls=; h=From:To:Subject:Date:In-Reply-To:References:From; b=SQLqhFjL7V73XO++PjUqLb+HswWKpOklzGAbrd1GkmNbT/f1eUWl3+an00KacGCH1 YoOcvLS3fmsM0jgZ/exBKrK3DsE//HDQWQBVBl71BpGZbjTRFlI0mv8daQsXAPz0wO wrRqun1i1N/hapc4rD22QEZMRj5sYi7/gMr82Sec= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 45/54] v4l2: Use camera buffer pool Date: Mon, 29 Jun 2026 18:30:08 +0200 Message-ID: <20260629163017.863145-46-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Port to using the camera's buffer pool. TODO: this is probably suboptimal in multiple respects Signed-off-by: Barnabás Pőcze --- src/v4l2/v4l2_camera.cpp | 84 ++++++++++++++++++++++++++++------------ src/v4l2/v4l2_camera.h | 4 +- 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp index aae9fae68c..3bcf841cd0 100644 --- a/src/v4l2/v4l2_camera.cpp +++ b/src/v4l2/v4l2_camera.cpp @@ -70,24 +70,30 @@ void V4L2Camera::unbind() void V4L2Camera::requestComplete(Request *request) { - if (request->status() == Request::RequestCancelled) - return; + bool hasBuffer = false; /* We only have one stream at the moment. */ { MutexLocker locker(bufferMutex_); - FrameBuffer *buffer = request->buffers().begin()->second; - completedBuffers_.emplace_back(buffer->cookie(), buffer->metadata()); + FrameBuffer *buffer = request->findBuffer(config_->at(0).stream()); - uint64_t data = 1; - int ret = ::write(efd_, &data, sizeof(data)); - if (ret != sizeof(data)) - LOG(V4L2Compat, Error) << "Failed to signal eventfd POLLIN"; + if (buffer) { + completedBuffers_.emplace_back(buffer->cookie(), buffer->metadata()); + + uint64_t data = 1; + int ret = ::write(efd_, &data, sizeof(data)); + if (ret != sizeof(data)) + LOG(V4L2Compat, Error) << "Failed to signal eventfd POLLIN"; + + hasBuffer = true; + } request->reuse(); + freeRequests_.push_back(request); } - bufferCV_.notify_all(); + if (hasBuffer) + bufferCV_.notify_all(); } int V4L2Camera::configure(StreamConfiguration *streamConfigOut, @@ -150,6 +156,7 @@ int V4L2Camera::allocBuffers() return ret; const auto &buffers = bufferAllocator_->buffers(stream); + MutexLocker locker(bufferMutex_); for (size_t i = 0; i < buffers.size(); i++) { std::unique_ptr request = camera_->createRequest(i); @@ -157,6 +164,7 @@ int V4L2Camera::allocBuffers() requestPool_.clear(); return -ENOMEM; } + freeRequests_.push_back(request.get()); requestPool_.push_back(std::move(request)); buffers[i]->setCookie(i); @@ -167,9 +175,15 @@ int V4L2Camera::allocBuffers() void V4L2Camera::freeBuffers() { - pendingRequests_.clear(); + { + MutexLocker locker(bufferMutex_); + freeRequests_.clear(); + } + requestPool_.clear(); + pendingBuffers_.clear(); + Stream *stream = config_->at(0).stream(); bufferAllocator_->free(stream); } @@ -199,21 +213,34 @@ int V4L2Camera::streamOn() isRunning_ = true; - for (Request *req : pendingRequests_) { + Stream *stream = config_->at(0).stream(); + + MutexLocker locker(bufferMutex_); + + for (FrameBuffer *buffer : pendingBuffers_) { + ASSERT(!pendingBuffers_.empty()); + Request *req = freeRequests_.back(); + freeRequests_.pop_back(); + + req->enableStream(stream, true); + /* \todo What should we do if this returns -EINVAL? */ ret = camera_->queueRequest(req); if (ret < 0) return ret == -EACCES ? -EBUSY : ret; + + /* \todo error handling how? */ + std::ignore = camera_->addBuffer(stream, buffer); } - pendingRequests_.clear(); + pendingBuffers_.clear(); return 0; } int V4L2Camera::streamOff() { - pendingRequests_.clear(); + pendingBuffers_.clear(); if (!isRunning_) { for (std::unique_ptr &req : requestPool_) @@ -238,33 +265,42 @@ int V4L2Camera::streamOff() int V4L2Camera::qbuf(unsigned int index) { - if (index >= requestPool_.size()) { + Stream *stream = config_->at(0).stream(); + const auto &buffers = bufferAllocator_->buffers(stream); + + if (index >= buffers.size()) { LOG(V4L2Compat, Error) << "Invalid index"; return -EINVAL; } - Request *request = requestPool_[index].get(); - Stream *stream = config_->at(0).stream(); - FrameBuffer *buffer = bufferAllocator_->buffers(stream)[index].get(); - int ret = request->addBuffer(stream, buffer); - if (ret < 0) { - LOG(V4L2Compat, Error) << "Can't set buffer for request"; - return -ENOMEM; - } + FrameBuffer *buffer = buffers[index].get(); if (!isRunning_) { - pendingRequests_.push_back(request); + pendingBuffers_.push_back(buffer); return 0; } + MutexLocker locker(bufferMutex_); + + if (freeRequests_.empty()) + return -EBUSY; + + Request *request = freeRequests_.back(); + request->controls().merge(std::move(controls_)); + request->enableStream(stream, true); - ret = camera_->queueRequest(request); + int ret = camera_->queueRequest(request); if (ret < 0) { LOG(V4L2Compat, Error) << "Can't queue request"; return ret == -EACCES ? -EBUSY : ret; } + freeRequests_.pop_back(); + + /* \todo error handling how? */ + std::ignore = camera_->addBuffer(stream, buffer); + return 0; } diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h index 06e37077b2..f51313ef36 100644 --- a/src/v4l2/v4l2_camera.h +++ b/src/v4l2/v4l2_camera.h @@ -79,8 +79,10 @@ private: std::unique_ptr bufferAllocator_; std::vector> requestPool_; + std::vector freeRequests_ + LIBCAMERA_TSA_GUARDED_BY(bufferMutex_); - std::deque pendingRequests_; + std::deque pendingBuffers_; std::deque completedBuffers_ LIBCAMERA_TSA_GUARDED_BY(bufferMutex_); From patchwork Mon Jun 29 16:30:09 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27126 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 36E1AC3304 for ; Mon, 29 Jun 2026 16:31:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C7FE665F9B; Mon, 29 Jun 2026 18:31:38 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="oFjDtmbe"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 90E3465F6B for ; Mon, 29 Jun 2026 18:30:31 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 624BD1044 for ; Mon, 29 Jun 2026 18:29:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750588; bh=VXWpR7gmQO/R6CcvpP28AdLvMQoFvogtaR38wHx23MI=; h=From:To:Subject:Date:In-Reply-To:References:From; b=oFjDtmbeBX6oVHTzLyvET4pjZ96GsW12AFIJ1hvKWfjaoJvEisgi1rD63WBARmSBY APCX9sPl0O51J5tw3iJznfe17FDA4aCvCW8GnmfBM5Qzx1gzp0UgwHre65nuZH2z8+ cGKodFxt7IRoDvQtm3nxqyVktAnJvBiDqSO+SeVk= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 46/54] py: Use camera buffer pool Date: Mon, 29 Jun 2026 18:30:09 +0200 Message-ID: <20260629163017.863145-47-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Port to using the camera's buffer pool. Signed-off-by: Barnabás Pőcze --- src/py/cam/cam.py | 20 +++--- src/py/examples/simple-cam.py | 13 +++- src/py/examples/simple-capture.py | 20 +++--- src/py/examples/simple-continuous-capture.py | 32 ++++++---- src/py/libcamera/py_main.cpp | 64 ++++++++++++++------ 5 files changed, 101 insertions(+), 48 deletions(-) diff --git a/src/py/cam/cam.py b/src/py/cam/cam.py index 73764a8af7..1752960030 100755 --- a/src/py/cam/cam.py +++ b/src/py/cam/cam.py @@ -205,13 +205,6 @@ class CameraContext: for buf_num in range(num_bufs): request = self.camera.create_request(self.idx) - - for stream in self.streams: - buffers = self.allocator.buffers(stream) - buffer = buffers[buf_num] - - request.add_buffer(stream, buffer) - requests.append(request) self.requests = requests @@ -223,7 +216,14 @@ class CameraContext: self.camera.stop() def queue_requests(self): + for stream in self.streams: + for buffer in self.allocator.buffers(stream): + self.camera.add_buffer(stream, buffer) + for request in self.requests: + for stream in self.streams: + request.enable_stream(stream, True) + self.camera.queue_request(request) self.reqs_queued += 1 @@ -305,7 +305,13 @@ class CaptureState: # Called from renderer when it has finished with a request def request_processed(self, ctx, req): if ctx.reqs_queued < ctx.opt_capture: + for (stream, buffer) in req.buffers.items(): + ctx.camera.add_buffer(stream, buffer) + req.reuse() + for stream in ctx.streams: + req.enable_stream(stream, True) + ctx.camera.queue_request(req) ctx.reqs_queued += 1 diff --git a/src/py/examples/simple-cam.py b/src/py/examples/simple-cam.py index 1cd1019da9..f2e28a94ef 100755 --- a/src/py/examples/simple-cam.py +++ b/src/py/examples/simple-cam.py @@ -73,7 +73,12 @@ def process_request(request): # must be mapped by the application # Re-queue the Request to the camera. + for (stream, buffer) in request.buffers.items(): + camera.add_buffer(stream, buffer) + request.reuse() + request.enable_stream(stream, True) + camera.queue_request(request) @@ -285,9 +290,6 @@ def main(): for i in range(len(buffers)): request = camera.create_request() - buffer = buffers[i] - request.add_buffer(stream, buffer) - # Controls can be added to a request on a per frame basis. request.set_control(libcam.controls.Brightness, 0.5) @@ -311,7 +313,12 @@ def main(): # be waited upon using e.g. Python's selectors. camera.start() + + for buffer in buffers: + camera.add_buffer(stream, buffer) + for request in requests: + request.enable_stream(stream, True) camera.queue_request(request) sel = selectors.DefaultSelector() diff --git a/src/py/examples/simple-capture.py b/src/py/examples/simple-capture.py index 4b85408fac..00657f78ad 100755 --- a/src/py/examples/simple-capture.py +++ b/src/py/examples/simple-capture.py @@ -69,20 +69,15 @@ def main(): allocator = libcam.FrameBufferAllocator(cam) ret = allocator.allocate(stream) - assert ret > 0 - - num_bufs = len(allocator.buffers(stream)) + buffers = allocator.buffers(stream) + assert ret > 0 and len(buffers) > 0 # Create the requests and assign a buffer for each request reqs = [] - for i in range(num_bufs): + for i in range(len(buffers)): # Use the buffer index as the cookie req = cam.create_request(i) - - buffer = allocator.buffers(stream)[i] - req.add_buffer(stream, buffer) - reqs.append(req) # Start the camera @@ -96,7 +91,11 @@ def main(): # Queue the requests to the camera + for buffer in buffers: + cam.add_buffer(stream, buffer) + for req in reqs: + req.enable_stream(stream, True) cam.queue_request(req) frames_queued += 1 @@ -144,7 +143,12 @@ def main(): # We could create a totally new Request, but it is more efficient # to reuse the existing one that we just received. if frames_queued < TOTAL_FRAMES: + for (stream, buffer) in req.buffers.items(): + cam.add_buffer(stream, buffer) + req.reuse() + req.enable_stream(stream, True) + cam.queue_request(req) frames_queued += 1 diff --git a/src/py/examples/simple-continuous-capture.py b/src/py/examples/simple-continuous-capture.py index 5ae841519e..96cb79b43f 100755 --- a/src/py/examples/simple-continuous-capture.py +++ b/src/py/examples/simple-continuous-capture.py @@ -19,8 +19,10 @@ import sys class CameraCaptureContext: idx: int cam: libcam.Camera + cam_config: libcam.CameraConfiguration reqs: list[libcam.Request] mfbs: dict[libcam.FrameBuffer, libcamera.utils.MappedFrameBuffer] + buffers: list[libcam.FrameBuffer] def __init__(self, cam, idx): self.idx = idx @@ -32,11 +34,11 @@ class CameraCaptureContext: # Configure the camera - cam_config = cam.generate_configuration([libcam.StreamRole.Viewfinder]) + self.cam_config = cam.generate_configuration([libcam.StreamRole.Viewfinder]) - stream_config = cam_config.at(0) + stream_config = self.cam_config.at(0) - cam.configure(cam_config) + cam.configure(self.cam_config) stream = stream_config.stream @@ -44,24 +46,19 @@ class CameraCaptureContext: allocator = libcam.FrameBufferAllocator(cam) ret = allocator.allocate(stream) - assert ret > 0 + self.buffers = allocator.buffers(stream) + assert ret > 0 and len(self.buffers) > 0 - num_bufs = len(allocator.buffers(stream)) - - print(f'cam{idx} ({cam.id}): capturing {num_bufs} buffers with {stream_config}') + print(f'cam{idx} ({cam.id}): capturing {len(self.buffers)} buffers with {stream_config}') # Create the requests and assign a buffer for each request self.reqs = [] self.mfbs = {} - for i in range(num_bufs): + for buffer in self.buffers: # Use the camera index as the "cookie" req = cam.create_request(idx) - - buffer = allocator.buffers(stream)[i] - req.add_buffer(stream, buffer) - self.reqs.append(req) # Save a mmapped buffer so we can calculate the CRC later @@ -127,7 +124,12 @@ class CaptureContext: # a new Request, we re-use the old one. We need to call req.reuse() # to re-initialize the Request before queuing. + for (stream, buffer) in req.buffers.items(): + cam_ctx.cam.add_buffer(stream, buffer) + req.reuse() + req.enable_stream(stream, True) + cam_ctx.cam.queue_request(req) def handle_key_event(self): @@ -139,7 +141,13 @@ class CaptureContext: # Queue the requests to the camera for cam_ctx in self.camera_contexts: + stream = cam_ctx.cam_config.at(0).stream + + for buffer in cam_ctx.buffers: + cam_ctx.cam.add_buffer(stream, buffer) + for req in cam_ctx.reqs: + req.enable_stream(stream, True) cam_ctx.cam.queue_request(req) # Use Selector to wait for events from the camera and from the keyboard diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp index 3b101f9961..26b348ef0e 100644 --- a/src/py/libcamera/py_main.cpp +++ b/src/py/libcamera/py_main.cpp @@ -110,6 +110,16 @@ PYBIND11_MODULE(_libcamera, m) * https://pybind11.readthedocs.io/en/latest/advanced/misc.html#avoiding-c-types-in-docstrings */ + struct RequestDeleter : std::default_delete { + void operator()(Request *request) + { + for (const auto &[stream, buffer] : request->buffers()) + py::cast(buffer).dec_ref(); + + std::default_delete::operator()(request); + } + }; + auto pyCameraManager = py::class_>(m, "CameraManager"); auto pyCamera = py::class_(m, "Camera"); auto pySensorConfiguration = py::class_(m, "SensorConfiguration"); @@ -123,7 +133,7 @@ PYBIND11_MODULE(_libcamera, m) auto pyStream = py::class_(m, "Stream"); auto pyControlId = py::class_(m, "ControlId"); auto pyControlInfo = py::class_(m, "ControlInfo"); - auto pyRequest = py::class_(m, "Request"); + auto pyRequest = py::class_>(m, "Request"); auto pyRequestStatus = py::enum_(pyRequest, "Status"); auto pyRequestReuse = py::enum_(pyRequest, "Reuse"); auto pyFrameMetadata = py::class_(m, "FrameMetadata"); @@ -195,10 +205,21 @@ PYBIND11_MODULE(_libcamera, m) }, py::arg("controls") = std::unordered_map()) .def("stop", [](Camera &self) { + std::vector queued; + + self.bufferCompleted.connect(&queued, [&](Request *request, const Stream *, FrameBuffer *buffer) { + if (!request) + queued.push_back(buffer); + }); + int ret = self.stop(); + self.bufferCompleted.disconnect(&queued); self.requestCompleted.disconnect(); + for (auto *buffer : queued) + py::cast(buffer).dec_ref(); + if (ret) throw std::system_error(-ret, std::generic_category(), "Failed to stop camera"); @@ -221,7 +242,7 @@ PYBIND11_MODULE(_libcamera, m) }) .def("create_request", [](Camera &self, uint64_t cookie) { - std::unique_ptr req = self.createRequest(cookie); + std::unique_ptr req(self.createRequest(cookie).release()); if (!req) throw std::system_error(ENOMEM, std::generic_category(), "Failed to create request"); @@ -246,6 +267,20 @@ PYBIND11_MODULE(_libcamera, m) } }) + /* \todo Fence is not supported */ + .def("add_buffer", [](Camera &self, const Stream *stream, FrameBuffer *buffer) { + py::object py_buf = py::cast(buffer); + + py_buf.inc_ref(); + + int ret = self.addBuffer(stream, buffer); + if (ret) { + py_buf.dec_ref(); + throw std::system_error(-ret, std::generic_category(), + "Failed to add buffer"); + } + }) + .def_property_readonly("streams", [](Camera &self) { py::set set; for (auto &s : self.streams()) { @@ -457,13 +492,6 @@ PYBIND11_MODULE(_libcamera, m) }); pyRequest - /* \todo Fence is not supported, so we cannot expose addBuffer() directly */ - .def("add_buffer", [](Request &self, const Stream *stream, FrameBuffer *buffer) { - int ret = self.addBuffer(stream, buffer); - if (ret) - throw std::system_error(-ret, std::generic_category(), - "Failed to add buffer"); - }, py::keep_alive<1, 3>()) /* Request keeps Framebuffer alive */ .def_property_readonly("status", &Request::status) .def_property_readonly("buffers", &Request::buffers) .def_property_readonly("cookie", &Request::cookie) @@ -485,11 +513,15 @@ PYBIND11_MODULE(_libcamera, m) return ret; }) - /* - * \todo As we add a keep_alive to the fb in addBuffers(), we - * can only allow reuse with ReuseBuffers. - */ - .def("reuse", [](Request &self) { self.reuse(Request::ReuseFlag::ReuseBuffers); }) + .def("reuse", [](Request &self) { + for (const auto &[stream, buffer] : self.buffers()) + py::cast(buffer).dec_ref(); + + self.reuse(); + }) + .def("enable_stream", [](Request &self, const Stream *stream, bool enabled) { + self.enableStream(stream, enabled); + }) .def("__str__", &Request::toString); pyRequestStatus @@ -497,10 +529,6 @@ PYBIND11_MODULE(_libcamera, m) .value("Complete", Request::RequestComplete) .value("Cancelled", Request::RequestCancelled); - pyRequestReuse - .value("Default", Request::ReuseFlag::Default) - .value("ReuseBuffers", Request::ReuseFlag::ReuseBuffers); - pyFrameMetadata .def_readonly("status", &FrameMetadata::status) .def_readonly("sequence", &FrameMetadata::sequence) From patchwork Mon Jun 29 16:30:10 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27125 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 912B7C3261 for ; Mon, 29 Jun 2026 16:31:38 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2E1CD65FA7; Mon, 29 Jun 2026 18:31:38 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="uBb3rZh0"; 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 CD75965F6C for ; Mon, 29 Jun 2026 18:30:31 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A2CA1E91 for ; Mon, 29 Jun 2026 18:29:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750588; bh=A7RzXyNilVle6ZNxDCeLorY7SJjPqpPuLemMS8BMaTg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=uBb3rZh0Ods9LLp4Cr6rkSpvY8pSJtldH54MDmAnzElP616LK8xGNYgyrBkVTYp3w 2OrloXBMZohQhvByUAuMF03pRXfHT30Shwg+aSquYf6SZflzZzv8gpMTpLIDugPG1j 9rziOI5cJpmOy879lIEklrHuRYr7vRHoIleslvUs= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 47/54] gstreamer: Use camera buffer pool Date: Mon, 29 Jun 2026 18:30:10 +0200 Message-ID: <20260629163017.863145-48-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Port to using the camera's buffer pool. TODO: this is a horrible mess, probably incorrect in many places, but this is the best for now. Signed-off-by: Barnabás Pőcze --- src/gstreamer/gstlibcamerasrc.cpp | 136 ++++++++++++++++++++++-------- 1 file changed, 102 insertions(+), 34 deletions(-) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index 9061f9163c..b65422b2a3 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -48,7 +48,6 @@ struct RequestWrap { RequestWrap(std::unique_ptr request); ~RequestWrap(); - void attachBuffer(GstPad *srcpad, GstBuffer *buffer); GstBuffer *detachBuffer(GstPad *srcpad); std::unique_ptr request_; @@ -68,6 +67,9 @@ RequestWrap::~RequestWrap() return; for (const auto &[stream, fb] : request_->buffers()) { + if (!fb) + continue; + auto *buffer = reinterpret_cast(fb->cookie()); if (buffer) gst_buffer_unref(buffer); @@ -76,15 +78,6 @@ RequestWrap::~RequestWrap() } } -void RequestWrap::attachBuffer(GstPad *srcpad, GstBuffer *buffer) -{ - FrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer); - Stream *stream = gst_libcamera_pad_get_stream(srcpad); - - request_->addBuffer(stream, fb); - fb->setCookie(reinterpret_cast(buffer)); -} - GstBuffer *RequestWrap::detachBuffer(GstPad *srcpad) { const Stream *stream = gst_libcamera_pad_get_stream(srcpad); @@ -128,11 +121,80 @@ struct GstLibcameraSrcState { ControlList initControls_; guint group_id_; GstCameraControls controls_; + size_t maxRequests_ = 0; int queueRequest(); void requestCompleted(Request *request); int processRequest(); void clearRequests(); + + void addBuffers(GstLibcameraPool *pool) + { + const Stream *stream = gst_libcamera_pool_get_stream(pool); + + for (;;) { + GstBuffer *buffer = nullptr; + GstFlowReturn ret = gst_buffer_pool_acquire_buffer(GST_BUFFER_POOL(pool), &buffer, nullptr); + if (ret != GST_FLOW_OK) + break; + + FrameBuffer *fb = gst_libcamera_buffer_get_frame_buffer(buffer); + fb->setCookie(reinterpret_cast(buffer)); + + GST_TRACE_OBJECT(src_, "Adding buffer for stream:%p fb:%p buffer:%p", + stream, fb, buffer); + + if (cam_->addBuffer(stream, fb)) { + fb->setCookie(0); + gst_buffer_pool_release_buffer(GST_BUFFER_POOL(pool), buffer); + break; + } + } + } + + void addAllBuffers() + { + for (auto *srcpad : srcpads_) + addBuffers(gst_libcamera_pad_get_pool(srcpad)); + } + + int start() + { + int ret = cam_->start(&initControls_); + if (ret) + return ret; + + addAllBuffers(); + + return 0; + } + + void stop() + { + cam_->bufferCompleted.connect(this, [&](Request *request, const Stream *stream, FrameBuffer *fb) { + if (request) + return; + + // \todo no... just no... + for (auto *pad : srcpads_) { + if (gst_libcamera_pad_get_stream(pad) != stream) + continue; + + auto *pool = gst_libcamera_pad_get_pool(pad); + auto *buffer = reinterpret_cast(fb->cookie()); + fb->setCookie(0); + + gst_buffer_pool_release_buffer(GST_BUFFER_POOL(pool), buffer); + + break; + } + }); + + cam_->stop(); + + cam_->bufferCompleted.disconnect(this); + clearRequests(); + } }; struct _GstLibcameraSrc { @@ -182,6 +244,13 @@ GstStaticPadTemplate request_src_template = { /* Must be called with stream_lock held. */ int GstLibcameraSrcState::queueRequest() { + { + GLibLocker locker(&lock_); + + if (queuedRequests_.size() + completedRequests_.size() >= maxRequests_) + return -EAGAIN; + } + std::unique_ptr request = cam_->createRequest(); if (!request) return -ENOMEM; @@ -189,27 +258,12 @@ int GstLibcameraSrcState::queueRequest() /* Apply controls */ controls_.applyControls(request); + for (auto *srcpad : srcpads_) + request->enableStream(gst_libcamera_pad_get_stream(srcpad), true); + std::unique_ptr wrap = std::make_unique(std::move(request)); - for (GstPad *srcpad : srcpads_) { - GstLibcameraPool *pool = gst_libcamera_pad_get_pool(srcpad); - GstBuffer *buffer; - GstFlowReturn ret; - - ret = gst_buffer_pool_acquire_buffer(GST_BUFFER_POOL(pool), - &buffer, nullptr); - if (ret != GST_FLOW_OK) { - /* - * RequestWrap has ownership of the request, and we - * won't be queueing this one due to lack of buffers. - */ - return -ENOBUFS; - } - - wrap->attachBuffer(srcpad, buffer); - } - GST_TRACE_OBJECT(src_, "Requesting buffers"); { @@ -363,6 +417,8 @@ int GstLibcameraSrcState::processRequest() const StreamConfiguration &stream_cfg = stream->configuration(); GstBufferPool *video_pool = gst_libcamera_pad_get_video_pool(srcpad); + GST_TRACE_OBJECT(src_, "Received fb:%p buffer:%p on stream:%p", fb, buffer, stream); + if (video_pool) { /* Only set video pool when a copy is needed. */ GstBuffer *copy = nullptr; @@ -702,6 +758,18 @@ gst_libcamera_src_negotiate(GstLibcameraSrc *self) gst_pad_check_reconfigure(srcpad); } + state->maxRequests_ = 0; + + for (auto *srcpad : state->srcpads_) { + Stream *stream = gst_libcamera_pad_get_stream(srcpad); + size_t poolSize = gst_libcamera_allocator_get_pool_size(self->allocator, stream); + + state->maxRequests_ = std::max(state->maxRequests_, poolSize); + } + + if (state->maxRequests_ <= 0) + return false; + return true; } @@ -748,17 +816,18 @@ gst_libcamera_src_task_run(gpointer user_data) } if (reconfigure) { - state->cam_->stop(); - state->clearRequests(); + state->stop(); if (!gst_libcamera_src_negotiate(self)) { GST_ELEMENT_FLOW_ERROR(self, GST_FLOW_NOT_NEGOTIATED); gst_task_stop(self->task); } - state->cam_->start(&state->initControls_); + state->start(); } + state->addAllBuffers(); + /* * Create and queue one request. If no buffers are available the * function returns -ENOBUFS, which we ignore here as that's not a @@ -915,7 +984,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, gst_pad_push_event(srcpad, gst_event_new_segment(&segment)); } - ret = state->cam_->start(&state->initControls_); + ret = state->start(); if (ret) { GST_ELEMENT_ERROR(self, RESOURCE, SETTINGS, ("Failed to start the camera: %s", g_strerror(-ret)), @@ -935,8 +1004,7 @@ gst_libcamera_src_task_leave([[maybe_unused]] GstTask *task, GST_DEBUG_OBJECT(self, "Streaming thread is about to stop"); - state->cam_->stop(); - state->clearRequests(); + state->stop(); { GLibRecLocker locker(&self->stream_lock); From patchwork Mon Jun 29 16:30:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27127 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 EB92FC3303 for ; Mon, 29 Jun 2026 16:31:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 811CE65FB9; Mon, 29 Jun 2026 18:31:39 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Iz+4dHQM"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1D7CF65F6E for ; Mon, 29 Jun 2026 18:30:32 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DFD891044 for ; Mon, 29 Jun 2026 18:29:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750589; bh=bUYC0r8e9bSYJn6QBkh+LrbSDZUz/lx8pFWTcpQa/lA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Iz+4dHQMIvbyAfOKfYsZ7wCGGfBhCwnqxX6dZXBafpfvE+O5JRCRbVSQYhhzqfFex 9mJKiPxefDSPjmjLVo87EFMTMUt/FJt0w7l+Mlxkm3zZV+36Y8j811xYEko6LxP4Bn cbxPeyeeiLuINnSoYzaO3lXkU/Zsxk0xA+wS+R74= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 48/54] libcamera: request: Remove `ReuseFlag` Date: Mon, 29 Jun 2026 18:30:11 +0200 Message-ID: <20260629163017.863145-49-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" They are no longer used, so they can be removed. Signed-off-by: Barnabás Pőcze --- .../guides/application-developer.rst | 9 -------- include/libcamera/request.h | 7 +------ src/libcamera/request.cpp | 21 ++----------------- src/py/libcamera/py_main.cpp | 1 - 4 files changed, 3 insertions(+), 35 deletions(-) diff --git a/Documentation/guides/application-developer.rst b/Documentation/guides/application-developer.rst index a9620ca862..9c6191406d 100644 --- a/Documentation/guides/application-developer.rst +++ b/Documentation/guides/application-developer.rst @@ -477,15 +477,6 @@ libcamera repository. .. _FileSink class: https://git.libcamera.org/libcamera/libcamera.git/tree/src/apps/cam/file_sink.cpp -With the handling of this request completed, it is possible to re-use the -request and the associated buffers and re-queue it to the camera -device: - -.. code:: cpp - - request->reuse(Request::ReuseBuffers); - camera->queueRequest(request); - Request queueing ---------------- diff --git a/include/libcamera/request.h b/include/libcamera/request.h index c86259c59b..462611da59 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -37,17 +37,12 @@ public: RequestCancelled, }; - enum ReuseFlag { - Default = 0, - ReuseBuffers = (1 << 0), - }; - using BufferMap = std::map; Request(Camera *camera, uint64_t cookie = 0); ~Request(); - void reuse(ReuseFlag flags = Default); + void reuse(); ControlList &controls() { return controls_; } const ControlList &metadata() const; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 4fb8c0a659..5d28ac80df 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -193,18 +193,6 @@ void Request::Private::reset() * The request has been cancelled due to capture stop */ -/** - * \enum Request::ReuseFlag - * Flags to control the behavior of Request::reuse() - * \var Request::Default - * Don't reuse buffers - * \var Request::ReuseBuffers - * Reuse the buffers that were previously added by addBuffer() - * - * \note Fences associated with the buffers are not reused. - * This flag should not be used if fences are used. - */ - /** * \typedef Request::BufferMap * \brief A map of Stream to FrameBuffer pointers @@ -245,21 +233,16 @@ Request::~Request() /** * \brief Reset the request for reuse - * \param[in] flags Indicate whether or not to reuse the buffers * * Reset the status and controls associated with the request, to allow it to * be reused and requeued without destruction. This function shall be called * prior to queueing the request to the camera, in lieu of constructing a new - * request. The application can reuse the buffers that were previously added - * to the request via addBuffer() by setting \a flags to ReuseBuffers. + * request. */ -void Request::reuse(ReuseFlag flags) +void Request::reuse() { LIBCAMERA_TRACEPOINT(request_reuse, this); - if (flags) - LOG(Request, Fatal) << "NOT IMPLEMENTED"; - _d()->reset(); bufferMap_.clear(); diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp index 26b348ef0e..7196bb0f6d 100644 --- a/src/py/libcamera/py_main.cpp +++ b/src/py/libcamera/py_main.cpp @@ -135,7 +135,6 @@ PYBIND11_MODULE(_libcamera, m) auto pyControlInfo = py::class_(m, "ControlInfo"); auto pyRequest = py::class_>(m, "Request"); auto pyRequestStatus = py::enum_(pyRequest, "Status"); - auto pyRequestReuse = py::enum_(pyRequest, "Reuse"); auto pyFrameMetadata = py::class_(m, "FrameMetadata"); auto pyFrameMetadataStatus = py::enum_(pyFrameMetadata, "Status"); auto pyFrameMetadataPlane = py::class_(pyFrameMetadata, "Plane"); From patchwork Mon Jun 29 16:30:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27133 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 CABF6C3264 for ; Mon, 29 Jun 2026 16:40:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7809E65F4A; Mon, 29 Jun 2026 18:40:43 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="envWavue"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 67E3865F73 for ; Mon, 29 Jun 2026 18:30:33 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4FBF78D4 for ; Mon, 29 Jun 2026 18:29:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750590; bh=0YwRqVc4R63sYZt5n6gxdPiyT3znhwgxNofyeqfF8Js=; h=From:To:Subject:Date:In-Reply-To:References:From; b=envWavuewiUr3oi5ZAFd81dHHYObOHbqEJgQanhtEv1BcIAIg5Zobi3oMLpRPV87q +xUBZModZ+a3vQyzU0q+LqBPdCNPbqSWcX1xQ3PBRkvQSCN70ce0DRcG8bjvrWGcr0 Njbkb5VmWEyC9mM/a44NE7x7hlyLsQJXQ0OXzkMk= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 49/54] android: Update imported files Date: Mon, 29 Jun 2026 18:30:12 +0200 Message-ID: <20260629163017.863145-50-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 X-Mailman-Approved-At: Mon, 29 Jun 2026 18:40:42 +0200 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" Update the android headers and source files from the android repositories: * https://android.googlesource.com/platform/hardware/libhardware/ * https://android.googlesource.com/platform/system/core/ * https://android.googlesource.com/platform/system/logging/ * https://android.googlesource.com/platform/system/media/ all from tag `android-17.0.0_r1`. The SPDX license identifiers are kept or added for new files. Certain new struct members also need to be initialized for the compilation to succeed. Signed-off-by: Barnabás Pőcze --- .../libhardware/include/hardware/camera3.h | 360 +- .../include/hardware/camera_common.h | 304 +- .../libhardware/include/hardware/gralloc.h | 99 +- .../android/metadata/camera_metadata_hidden.h | 11 +- .../android/metadata/system/camera_metadata.h | 41 +- .../metadata/system/camera_metadata_tags.h | 633 +- .../metadata/system/camera_vendor_tags.h | 10 +- .../android/system/core/include/android/log.h | 450 +- .../core/include/cutils/native_handle.h | 62 +- .../system/core/include/system/camera.h | 4 +- .../core/include/system/graphics-base-v1.2.h | 36 + .../core/include/system/graphics-base.h | 1 + .../system/core/include/system/graphics.h | 10 +- src/android/camera3_hal.cpp | 3 + src/android/camera_ops.cpp | 4 +- src/android/metadata/camera_metadata.c | 183 +- .../metadata/camera_metadata_tag_info.c | 5478 ++++++++++++++++- 17 files changed, 7437 insertions(+), 252 deletions(-) create mode 100644 include/android/system/core/include/system/graphics-base-v1.2.h diff --git a/include/android/hardware/libhardware/include/hardware/camera3.h b/include/android/hardware/libhardware/include/hardware/camera3.h index fd1e2072ad..fe7285f904 100644 --- a/include/android/hardware/libhardware/include/hardware/camera3.h +++ b/include/android/hardware/libhardware/include/hardware/camera3.h @@ -22,7 +22,7 @@ #include "camera_common.h" /** - * Camera device HAL 3.5[ CAMERA_DEVICE_API_VERSION_3_5 ] + * Camera device HAL 3.6[ CAMERA_DEVICE_API_VERSION_3_6 ] * * This is the current recommended version of the camera device HAL. * @@ -30,7 +30,7 @@ * android.hardware.camera2 API as LIMITED or above hardware level. * * Camera devices that support this version of the HAL must return - * CAMERA_DEVICE_API_VERSION_3_5 in camera_device_t.common.version and in + * CAMERA_DEVICE_API_VERSION_3_6 in camera_device_t.common.version and in * camera_info_t.device_version (from camera_module_t.get_camera_info). * * CAMERA_DEVICE_API_VERSION_3_3 and above: @@ -184,6 +184,25 @@ * for a logical multi camera, the application has the option to specify individual * settings for a particular physical device. * + * 3.6: Minor revisions to support HAL buffer management APIs: + * + * - Add ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION static metadata, which allows HAL to + * opt in to the new buffer management APIs described below. + * + * - Add request_stream_buffers() and return_stream_buffers() to camera3_callback_ops_t for HAL to + * request and return output buffers from camera service. + * + * - Add signal_stream_flush() to camera3_device_ops_t for camera service to notify HAL an + * upcoming configure_streams() call requires HAL to return buffers of certain streams. + * + * - Add CAMERA3_JPEG_APP_SEGMENTS_BLOB_ID to support BLOB with only JPEG apps + * segments and thumbnail (without main image bitstream). Camera framework + * uses such stream togerther with a HAL YUV_420_888/IMPLEMENTATION_DEFINED + * stream to encode HEIC (ISO/IEC 23008-12) image. + * + * - Add is_reconfiguration_required() to camera3_device_ops_t to enable HAL to skip or + * trigger stream reconfiguration depending on new session parameter values. + * */ /** @@ -1314,7 +1333,7 @@ * To avoid excessive amount of noise reduction and insufficient amount of edge enhancement * being applied to the input buffer, the application can hint the HAL how much effective * exposure time improvement has been done by the application, then the HAL can adjust the - * noise reduction and edge enhancement paramters to get best reprocessed image quality. + * noise reduction and edge enhancement parameters to get best reprocessed image quality. * Below tag can be used for this purpose: * - android.reprocess.effectiveExposureFactor * The value would be exposure time increase factor applied to the original output image, @@ -1737,24 +1756,8 @@ typedef struct camera3_stream { */ const char* physical_camera_id; - /** - * This should be one of the camera3_stream_rotation_t values except for - * CAMERA3_STREAM_ROTATION_180. - * When setting to CAMERA3_STREAM_ROTATION_90 or CAMERA3_STREAM_ROTATION_270, HAL would crop, - * rotate the frame by the specified degrees clockwise and scale it up to original size. - * In Chrome OS, it's possible to have a portrait activity run in a landscape screen with - * landscape-mounted camera. The activity would show stretched or rotated preview because it - * does not expect to receive landscape preview frames. To solve this problem, we ask HAL to - * crop, rotate and scale the frames and modify CameraCharacteristics.SENSOR_ORIENTATION - * accordingly to imitate a portrait camera. - * Setting it to CAMERA3_STREAM_ROTATION_0 means no crop-rotate-scale would be performed. - * |cros_rotate_scale_degrees| in all camera3_stream_t of a configure_streams() call must be - * identical. The HAL should return -EINVAL if the degrees are not the same for all the streams. - */ - int crop_rotate_scale_degrees; - /* reserved for future use */ - void *reserved[5]; + void *reserved[6]; } camera3_stream_t; @@ -1958,21 +1961,25 @@ typedef struct camera3_stream_buffer_set { /** * camera3_jpeg_blob: * - * Transport header for compressed JPEG buffers in output streams. + * Transport header for compressed JPEG or JPEG_APP_SEGMENTS buffers in output streams. * - * To capture JPEG images, a stream is created using the pixel format + * To capture JPEG or JPEG_APP_SEGMENTS images, a stream is created using the pixel format * HAL_PIXEL_FORMAT_BLOB. The buffer size for the stream is calculated by the - * framework, based on the static metadata field android.jpeg.maxSize. Since - * compressed JPEG images are of variable size, the HAL needs to include the - * final size of the compressed image using this structure inside the output - * stream buffer. The JPEG blob ID field must be set to CAMERA3_JPEG_BLOB_ID. + * framework, based on the static metadata field android.jpeg.maxSize for JPEG, + * and android.jpeg.maxAppsSegments for JPEG_APP_SEGMENTS. * - * Transport header should be at the end of the JPEG output stream buffer. That + * Since compressed JPEG/JPEG_APP_SEGMENTS images are of variable size, the HAL needs to + * include the final size of the image using this structure inside the output + * stream buffer. The JPEG blob ID field must be set to CAMERA3_JPEG_BLOB_ID for + * JPEG and CAMERA3_JPEG_APP_SEGMENTS_BLOB_ID for APP segments. + * + * Transport header should be at the end of the output stream buffer. That * means the jpeg_blob_id must start at byte[buffer_size - * sizeof(camera3_jpeg_blob)], where the buffer_size is the size of gralloc buffer. - * Any HAL using this transport header must account for it in android.jpeg.maxSize - * The JPEG data itself starts at the beginning of the buffer and should be - * jpeg_size bytes long. + * The blob data itself starts at the beginning of the buffer and should be + * jpeg_size bytes long. HAL using this transport header for JPEG must account for + * it in android.jpeg.maxSize. For JPEG APP segments, camera framework makes + * sure that the output stream buffer is large enough for the transport header. */ typedef struct camera3_jpeg_blob { uint16_t jpeg_blob_id; @@ -1980,7 +1987,8 @@ typedef struct camera3_jpeg_blob { } camera3_jpeg_blob_t; enum { - CAMERA3_JPEG_BLOB_ID = 0x00FF + CAMERA3_JPEG_BLOB_ID = 0x00FF, + CAMERA3_JPEG_APP_SEGMENTS_BLOB_ID = 0x0100, }; /********************************************************************** @@ -2046,6 +2054,14 @@ typedef enum camera3_error_msg_code { * available. Subsequent requests are unaffected, and the device remains * operational. The frame_number field specifies the request for which * result metadata won't be available. + * + * >= CAMERA_DEVICE_API_VERSION_3_6: + * + * In case the result metadata is absent for a logical camera device, then the + * error_stream pointer must be set to NULL. + * If the result metadata cannot be produced for a physical camera device, then + * error_stream must contain a pointer to a respective stream associated with + * that physical device. */ CAMERA3_MSG_ERROR_RESULT = 3, @@ -2143,6 +2159,153 @@ typedef struct camera3_notify_msg { } camera3_notify_msg_t; + +/********************************************************************** + * + * Types definition for request_stream_buffers() callback. + * + */ + +/** + * camera3_buffer_request_status_t: + * + * The overall buffer request status returned by request_stream_buffers() + */ +typedef enum camera3_buffer_request_status { + /** + * request_stream_buffers() call succeeded and all requested buffers are + * returned. + */ + CAMERA3_BUF_REQ_OK = 0, + + /** + * request_stream_buffers() call failed for some streams. + * Check per stream status for each returned camera3_stream_buffer_ret_t. + */ + CAMERA3_BUF_REQ_FAILED_PARTIAL = 1, + + /** + * request_stream_buffers() call failed for all streams and no buffers are + * returned at all. Camera service is about to or is performing + * configure_streams() call. HAL must wait until next configure_streams() + * call is finished before requesting buffers again. + */ + CAMERA3_BUF_REQ_FAILED_CONFIGURING = 2, + + /** + * request_stream_buffers() call failed for all streams and no buffers are + * returned at all. Failure due to bad camera3_buffer_request input, eg: + * unknown stream or repeated stream in the list of buffer requests. + */ + CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS = 3, + + /** + * request_stream_buffers() call failed for all streams and no buffers are + * returned at all. This can happen for unknown reasons or a combination + * of different failure reasons per stream. For the latter case, caller can + * check per stream failure reason returned in camera3_stream_buffer_ret. + */ + CAMERA3_BUF_REQ_FAILED_UNKNOWN = 4, + + /** + * Number of buffer request status + */ + CAMERA3_BUF_REQ_NUM_STATUS + +} camera3_buffer_request_status_t; + +/** + * camera3_stream_buffer_req_status_t: + * + * The per stream buffer request status returned by request_stream_buffers() + */ +typedef enum camera3_stream_buffer_req_status { + /** + * Get buffer succeeds and all requested buffers are returned. + */ + CAMERA3_PS_BUF_REQ_OK = 0, + + /** + * Get buffer failed due to timeout waiting for an available buffer. This is + * likely due to the client application holding too many buffers, or the + * system is under memory pressure. + * This is not a fatal error. HAL can try to request buffer for this stream + * later. If HAL cannot get a buffer for certain capture request in time + * due to this error, HAL can send an ERROR_REQUEST to camera service and + * drop processing that request. + */ + CAMERA3_PS_BUF_REQ_NO_BUFFER_AVAILABLE = 1, + + /** + * Get buffer failed due to HAL has reached its maxBuffer count. This is not + * a fatal error. HAL can try to request buffer for this stream again after + * it returns at least one buffer of that stream to camera service. + */ + CAMERA3_PS_BUF_REQ_MAX_BUFFER_EXCEEDED = 2, + + /** + * Get buffer failed due to the stream is disconnected by client + * application, has been removed, or not recognized by camera service. + * This means application is no longer interested in this stream. + * Requesting buffer for this stream will never succeed after this error is + * returned. HAL must safely return all buffers of this stream after + * getting this error. If HAL gets another capture request later targeting + * a disconnected stream, HAL must send an ERROR_REQUEST to camera service + * and drop processing that request. + */ + CAMERA3_PS_BUF_REQ_STREAM_DISCONNECTED = 3, + + /** + * Get buffer failed for unknown reason. This is a fatal error and HAL must + * send ERROR_DEVICE to camera service and be ready to be closed. + */ + CAMERA3_PS_BUF_REQ_UNKNOWN_ERROR = 4, + + /** + * Number of buffer request status + */ + CAMERA3_PS_BUF_REQ_NUM_STATUS +} camera3_stream_buffer_req_status_t; + +typedef struct camera3_buffer_request { + /** + * The stream HAL wants to request buffer from + */ + camera3_stream_t *stream; + + /** + * The number of buffers HAL requested + */ + uint32_t num_buffers_requested; +} camera3_buffer_request_t; + +typedef struct camera3_stream_buffer_ret { + /** + * The stream HAL wants to request buffer from + */ + camera3_stream_t *stream; + + /** + * The status of buffer request of this stream + */ + camera3_stream_buffer_req_status_t status; + + /** + * Number of output buffers returned. Must be 0 when above status is not + * CAMERA3_PS_BUF_REQ_OK; otherwise the value must be equal to + * num_buffers_requested in the corresponding camera3_buffer_request_t + */ + uint32_t num_output_buffers; + + /** + * The returned output buffers for the stream. + * Caller of request_stream_buffers() should supply this with enough memory + * (num_buffers_requested * sizeof(camera3_stream_buffer_t)) + */ + camera3_stream_buffer_t *output_buffers; +} camera3_stream_buffer_ret_t; + + /********************************************************************** * * Capture request/result definitions for the HAL process_capture_request() @@ -2660,6 +2823,65 @@ typedef struct camera3_callback_ops { void (*notify)(const struct camera3_callback_ops *, const camera3_notify_msg_t *msg); + /** + * request_stream_buffers: + * + * <= CAMERA_DEVICE_API_VERISON_3_5: + * + * DO NOT USE: not defined and must be NULL. + * + * >= CAMERA_DEVICE_API_VERISON_3_6: + * + * Synchronous callback for HAL to ask for output buffer from camera service. + * + * This call may be serialized in camera service so it is strongly + * recommended to only call this method from one thread. + * + * When camera device advertises + * (android.info.supportedBufferManagementVersion == + * ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5), HAL + * can use this method to request buffers from camera service. + * + * Caller is responsible for allocating enough memory for returned_buf_reqs + * argument (num_buffer_reqs * sizeof(camera3_stream_buffer_ret_t)) bytes + * and also the memory for the output_buffers field in each + * camera3_stream_buffer_ret_t + * (num_buffers_requested * sizeof(camera3_stream_buffer_t)) bytes + * + * Performance requirements: + * This is a blocking call that takes more time with more buffers requested. + * HAL should not request large amount of buffers on a latency critical code + * path. It is highly recommended to use a dedicated thread to perform + * all requestStreamBuffer calls, and adjust the thread priority and/or + * timing of making the call in order for buffers to arrive before HAL is + * ready to fill the buffer. + */ + camera3_buffer_request_status_t (*request_stream_buffers)( + const struct camera3_callback_ops *, + uint32_t num_buffer_reqs, + const camera3_buffer_request_t *buffer_reqs, + /*out*/uint32_t *num_returned_buf_reqs, + /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs); + + /** + * return_stream_buffers: + * + * <= CAMERA_DEVICE_API_VERISON_3_5: + * + * DO NOT USE: not defined and must be NULL. + * + * >= CAMERA_DEVICE_API_VERISON_3_6: + * + * Synchronous callback for HAL to return output buffers to camera service. + * + * If this method is called during a configure_streams() call, it will be + * blocked until camera service finishes the ongoing configure_streams() call. + */ + void (*return_stream_buffers)( + const struct camera3_callback_ops *, + uint32_t num_buffers, + const camera3_stream_buffer_t* const* buffers); + } camera3_callback_ops_t; /********************************************************************** @@ -3238,8 +3460,82 @@ typedef struct camera3_device_ops { */ int (*flush)(const struct camera3_device *); + /** + * signal_stream_flush: + * + * <= CAMERA_DEVICE_API_VERISON_3_5: + * + * Not defined and must be NULL + * + * >= CAMERA_DEVICE_API_VERISON_3_6: + * + * Signaling HAL camera service is about to perform configure_streams() call + * and HAL must return all buffers of designated streams. HAL must finish + * inflight requests normally and return all buffers belonging to the + * designated streams through process_capture_result() or + * return_stream_buffers() API in a timely manner, or camera service will run + * into a fatal error. + * + * Note that this call serves as an optional hint and camera service may + * skip calling this if all buffers are already returned. + * + */ + void (*signal_stream_flush)(const struct camera3_device*, + uint32_t num_streams, + const camera3_stream_t* const* streams); + + /** + * is_reconfiguration_required: + * + * <= CAMERA_DEVICE_API_VERISON_3_5: + * + * Not defined and must be NULL + * + * >= CAMERA_DEVICE_API_VERISON_3_6: + * + * Check whether complete stream reconfiguration is required for possible new session + * parameter values. + * + * This method must be called by the camera framework in case the client changes + * the value of any advertised session parameters. Depending on the specific values + * the HAL can decide whether a complete stream reconfiguration is required. In case + * the HAL returns -ENVAL, the camera framework must skip the internal reconfiguration. + * In case Hal returns 0, the framework must reconfigure the streams and pass the + * new session parameter values accordingly. + * This call may be done by the framework some time before the request with new parameters + * is submitted to the HAL, and the request may be cancelled before it ever gets submitted. + * Therefore, the HAL must not use this query as an indication to change its behavior in any + * way. + * ------------------------------------------------------------------------ + * + * Preconditions: + * + * The framework can call this method at any time after active + * session configuration. There must be no impact on the performance of + * pending camera requests in any way. In particular there must not be + * any glitches or delays during normal camera streaming. + * + * Performance requirements: + * HW and SW camera settings must not be changed and there must not be + * a user-visible impact on camera performance. + * + * @param oldSessionParams The currently applied session parameters. + * @param newSessionParams The new session parameters set by client. + * + * @return Status Status code for the operation, one of: + * 0: In case the stream reconfiguration is required + * + * -EINVAL: In case the stream reconfiguration is not required. + * + * -ENOSYS: In case the camera device does not support the + * reconfiguration query. + */ + int (*is_reconfiguration_required)(const struct camera3_device*, + const camera_metadata_t* old_session_params, + const camera_metadata_t* new_session_params); + /* reserved for future use */ - void *reserved[8]; + void *reserved[6]; } camera3_device_ops_t; /********************************************************************** diff --git a/include/android/hardware/libhardware/include/hardware/camera_common.h b/include/android/hardware/libhardware/include/hardware/camera_common.h index 5c9bc06fe0..1d4a02a199 100644 --- a/include/android/hardware/libhardware/include/hardware/camera_common.h +++ b/include/android/hardware/libhardware/include/hardware/camera_common.h @@ -118,6 +118,22 @@ __BEGIN_DECLS * 4. Module initialization method. This will be called by the camera service * right after the HAL module is loaded, to allow for one-time initialization * of the HAL. It is called before any other module methods are invoked. + * + ******************************************************************************* + * Version: 2.5 [CAMERA_MODULE_API_VERSION_2_5] + * + * This camera module version adds below API changes: + * + * 1. Support to query characteristics of a non-standalone physical camera, which can + * only be accessed as part of a logical camera. It also adds camera stream combination + * query. + * + * 2. Ability to query whether a particular camera stream combination is + * supported by the camera device. + * + * 3. Device state change notification. This module version also supports + * notification about the overall device state change, such as + * folding/unfolding, or covering/uncovering of shutter. */ /** @@ -134,8 +150,9 @@ __BEGIN_DECLS #define CAMERA_MODULE_API_VERSION_2_2 HARDWARE_MODULE_API_VERSION(2, 2) #define CAMERA_MODULE_API_VERSION_2_3 HARDWARE_MODULE_API_VERSION(2, 3) #define CAMERA_MODULE_API_VERSION_2_4 HARDWARE_MODULE_API_VERSION(2, 4) +#define CAMERA_MODULE_API_VERSION_2_5 HARDWARE_MODULE_API_VERSION(2, 5) -#define CAMERA_MODULE_API_VERSION_CURRENT CAMERA_MODULE_API_VERSION_2_4 +#define CAMERA_MODULE_API_VERSION_CURRENT CAMERA_MODULE_API_VERSION_2_5 /** * All device versions <= HARDWARE_DEVICE_API_VERSION(1, 0xFF) must be treated @@ -150,6 +167,7 @@ __BEGIN_DECLS #define CAMERA_DEVICE_API_VERSION_3_3 HARDWARE_DEVICE_API_VERSION(3, 3) #define CAMERA_DEVICE_API_VERSION_3_4 HARDWARE_DEVICE_API_VERSION(3, 4) #define CAMERA_DEVICE_API_VERSION_3_5 HARDWARE_DEVICE_API_VERSION(3, 5) +#define CAMERA_DEVICE_API_VERSION_3_6 HARDWARE_DEVICE_API_VERSION(3, 6) // Device version 3.5 is current, older HAL camera device versions are not // recommended for new devices. @@ -645,6 +663,192 @@ typedef struct camera_module_callbacks { } camera_module_callbacks_t; +/** + * camera_stream_t: + * + * A handle to a single camera input or output stream. A stream is defined by + * the framework by its buffer resolution and format and gralloc usage flags. + * + * The stream structures are owned by the framework and pointers to a + * camera_stream passed into the HAL by is_stream_combination_supported() are + * only valid within the scope of the call. + * + * All camera_stream members are immutable. + */ +typedef struct camera_stream { + /** + * The type of the stream, one of the camera3_stream_type_t values. + */ + int stream_type; + + /** + * The width in pixels of the buffers in this stream + */ + uint32_t width; + + /** + * The height in pixels of the buffers in this stream + */ + uint32_t height; + + /** + * The pixel format for the buffers in this stream. Format is a value from + * the HAL_PIXEL_FORMAT_* list in system/core/include/system/graphics.h, or + * from device-specific headers. + * + * If HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED is used, then the platform + * gralloc module will select a format based on the usage flags provided by + * the camera device and the other endpoint of the stream. + * + */ + int format; + + /** + * The gralloc usage flags for this stream, as needed by the HAL. The usage + * flags are defined in gralloc.h (GRALLOC_USAGE_*), or in device-specific + * headers. + * + * For output streams, these are the HAL's producer usage flags. For input + * streams, these are the HAL's consumer usage flags. The usage flags from + * the producer and the consumer will be combined together and then passed + * to the platform gralloc HAL module for allocating the gralloc buffers for + * each stream. + * + * The usage flag for an output stream may be bitwise + * combination of usage flags for multiple consumers, for the purpose of + * sharing one camera stream between those consumers. The HAL must fail + * the stream combination query call with -EINVAL if the combined flags cannot be + * supported due to imcompatible buffer format, dataSpace, or other hardware + * limitations. + */ + uint32_t usage; + + /** + * A field that describes the contents of the buffer. The format and buffer + * dimensions define the memory layout and structure of the stream buffers, + * while dataSpace defines the meaning of the data within the buffer. + * + * For most formats, dataSpace defines the color space of the image data. + * In addition, for some formats, dataSpace indicates whether image- or + * depth-based data is requested. See system/core/include/system/graphics.h + * for details of formats and valid dataSpace values for each format. + * + * Always set by the camera service. The dataspace values are set + * using the V0 dataspace definitions in graphics.h + */ + android_dataspace_t data_space; + + /** + * The required output rotation of the stream, one of + * the camera3_stream_rotation_t values. This must be inspected by HAL along + * with stream width and height. For example, if the rotation is 90 degree + * and the stream width and height is 720 and 1280 respectively, camera service + * will supply buffers of size 720x1280, and HAL should capture a 1280x720 image + * and rotate the image by 90 degree counterclockwise. The rotation field is + * no-op when the stream type is input. Camera HAL must ignore the rotation + * field for an input stream. + * + * Always set by camera service. HAL must inspect this field during stream + * combination query and return -EINVAL if it cannot perform such rotation. + * HAL must always support CAMERA3_STREAM_ROTATION_0, so a + * is_stream_combination_supported() call must not fail for unsupported rotation if + * rotation field of all streams is CAMERA3_STREAM_ROTATION_0. + * + */ + int rotation; + + /** + * The physical camera id this stream belongs to. + * Always set by camera service. If the camera device is not a logical + * multi camera, or if the camera is a logical multi camera but the stream + * is not a physical output stream, this field will point to a 0-length + * string. + * + * A logical multi camera is a camera device backed by multiple physical + * cameras that are also exposed to the application. And for a logical + * multi camera, a physical output stream is an output stream specifically + * requested on an underlying physical camera. + * + * For an input stream, this field is guaranteed to be a 0-length string. + */ + const char* physical_camera_id; + +} camera_stream_t; + +/** + * camera_stream_combination_t: + * + * A structure of stream definitions, used by is_stream_combination_supported(). This + * structure defines all the input & output streams for specific camera use case. + */ +typedef struct camera_stream_combination { + /** + * The total number of streams by the framework. This includes + * both input and output streams. The number of streams will be at least 1, + * and there will be at least one output-capable stream. + */ + uint32_t num_streams; + + /** + * An array of camera streams, defining the input/output + * stream combination for the camera HAL device. + * + * At most one input-capable stream may be defined. + * + * At least one output-capable stream must be defined. + */ + camera_stream_t *streams; + + /** + * The operation mode of streams in this stream combination, one of the value + * defined in camera3_stream_configuration_mode_t. + * + */ + uint32_t operation_mode; + +} camera_stream_combination_t; + +/** + * device_state_t: + * + * Possible physical states of the overall device, for use with + * notify_device_state_change. + */ +typedef enum device_state { + /** + * The device is in its normal physical configuration. This is the default if the + * device does not support multiple different states. + */ + NORMAL = 0, + + /** + * Camera device(s) facing backward are covered. + */ + BACK_COVERED = 1 << 0, + + /** + * Camera device(s) facing foward are covered. + */ + FRONT_COVERED = 1 << 1, + + /** + * The device is folded. If not set, the device is unfolded or does not + * support folding. + * + * The exact point when this status change happens during the folding + * operation is device-specific. + */ + FOLDED = 1 << 2, + + /** + * First vendor-specific device state. All bits above and including this one + * are for vendor state values. Values below this one must only be used + * for framework-defined states. + */ + VENDOR_STATE_START = 1LL << 32 + +} device_state_t; + typedef struct camera_module { /** * Common methods of the camera module. This *must* be the first member of @@ -910,8 +1114,104 @@ typedef struct camera_module { */ int (*init)(); + /** + * get_physical_camera_info: + * + * Return the static metadata for a physical camera as a part of a logical + * camera device. This function is only called for those physical camera + * ID(s) that are not exposed independently. In other words, camera_id will + * be greater or equal to the return value of get_number_of_cameras(). + * + * Return values: + * + * 0: On a successful operation + * + * -ENODEV: The information cannot be provided due to an internal + * error. + * + * -EINVAL: The input arguments are invalid, i.e. the id is invalid, + * and/or the module is invalid. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3/2_4: + * Not provided by HAL module. Framework will not call this function. + * + * CAMERA_MODULE_API_VERSION_2_5 or higher: + * If any of the camera devices accessible through this camera module is + * a logical multi-camera, and at least one of the physical cameras isn't + * a stand-alone camera device, this function will be called by the camera + * framework. Calling this function with invalid physical_camera_id will + * get -EINVAL, and NULL static_metadata. + */ + int (*get_physical_camera_info)(int physical_camera_id, + camera_metadata_t **static_metadata); + + /** + * is_stream_combination_supported: + * + * Check for device support of specific camera stream combination. + * + * Return values: + * + * 0: In case the stream combination is supported. + * + * -EINVAL: In case the stream combination is not supported. + * + * -ENOSYS: In case stream combination query is not supported. + * + * Version information (based on camera_module_t.common.module_api_version): + * + * CAMERA_MODULE_API_VERSION_1_x/2_0/2_1/2_2/2_3/2_4: + * Not provided by HAL module. Framework will not call this function. + * + * CAMERA_MODULE_API_VERSION_2_5 or higher: + * Valid to be called by the framework. + */ + int (*is_stream_combination_supported)(int camera_id, + const camera_stream_combination_t *streams); + + /** + * notify_device_state_change: + * + * Notify the camera module that the state of the overall device has + * changed in some way that the HAL may want to know about. + * + * For example, a physical shutter may have been uncovered or covered, + * or a camera may have been covered or uncovered by an add-on keyboard + * or other accessory. + * + * The state is a bitfield of potential states, and some physical configurations + * could plausibly correspond to multiple different combinations of state bits. + * The HAL must ignore any state bits it is not actively using to determine + * the appropriate camera configuration. + * + * For example, on some devices the FOLDED state could mean that + * backward-facing cameras are covered by the fold, so FOLDED by itself implies + * BACK_COVERED. But other devices may support folding but not cover any cameras + * when folded, so for those FOLDED would not imply any of the other flags. + * Since these relationships are very device-specific, it is difficult to specify + * a comprehensive policy. But as a recommendation, it is suggested that if a flag + * necessarily implies other flags are set as well, then those flags should be set. + * So even though FOLDED would be enough to infer BACK_COVERED on some devices, the + * BACK_COVERED flag should also be set for clarity. + * + * This method may be invoked by the HAL client at any time. It must not + * cause any active camera device sessions to be closed, but may dynamically + * change which physical camera a logical multi-camera is using for its + * active and future output. + * + * The method must be invoked by the HAL client at least once before the + * client calls ICameraDevice::open on any camera device interfaces listed + * by this provider, to establish the initial device state. + * + * Note that the deviceState is 64-bit bitmask, with system defined states in + * lower 32-bit and vendor defined states in upper 32-bit. + */ + void (*notify_device_state_change)(uint64_t deviceState); + /* reserved for future use */ - void* reserved[5]; + void* reserved[2]; } camera_module_t; __END_DECLS diff --git a/include/android/hardware/libhardware/include/hardware/gralloc.h b/include/android/hardware/libhardware/include/hardware/gralloc.h index 01a7672747..2c5514b8ec 100644 --- a/include/android/hardware/libhardware/include/hardware/gralloc.h +++ b/include/android/hardware/libhardware/include/hardware/gralloc.h @@ -19,8 +19,8 @@ #ifndef ANDROID_GRALLOC_INTERFACE_H #define ANDROID_GRALLOC_INTERFACE_H -#include #include +#include #include #include @@ -28,8 +28,8 @@ #include -#include #include +#include __BEGIN_DECLS @@ -132,6 +132,9 @@ enum { * handle this flag. */ GRALLOC_USAGE_FOREIGN_BUFFERS = 0x00200000U, + /* buffer will be used as input to HW HEIC image encoder */ + GRALLOC_USAGE_HW_IMAGE_ENCODER = 0x08000000U, + /* Mask of all flags which could be passed to a gralloc module for buffer * allocation. Any flags not in this mask do not need to be handled by * gralloc modules. */ @@ -154,20 +157,20 @@ enum { */ typedef struct gralloc_module_t { struct hw_module_t common; - + /* * (*registerBuffer)() must be called before a buffer_handle_t that has not * been created with (*alloc_device_t::alloc)() can be used. - * + * * This is intended to be used with buffer_handle_t's that have been * received in this process through IPC. - * + * * This function checks that the handle is indeed a valid one and prepares * it for use with (*lock)() and (*unlock)(). - * - * It is not necessary to call (*registerBuffer)() on a handle created + * + * It is not necessary to call (*registerBuffer)() on a handle created * with (*alloc_device_t::alloc)(). - * + * * returns an error if this buffer_handle_t is not valid. */ int (*registerBuffer)(struct gralloc_module_t const* module, @@ -177,25 +180,25 @@ typedef struct gralloc_module_t { * (*unregisterBuffer)() is called once this handle is no longer needed in * this process. After this call, it is an error to call (*lock)(), * (*unlock)(), or (*registerBuffer)(). - * + * * This function doesn't close or free the handle itself; this is done * by other means, usually through libcutils's native_handle_close() and - * native_handle_free(). - * + * native_handle_free(). + * * It is an error to call (*unregisterBuffer)() on a buffer that wasn't * explicitly registered first. */ int (*unregisterBuffer)(struct gralloc_module_t const* module, buffer_handle_t handle); - + /* - * The (*lock)() method is called before a buffer is accessed for the + * The (*lock)() method is called before a buffer is accessed for the * specified usage. This call may block, for instance if the h/w needs * to finish rendering or if CPU caches need to be synchronized. - * - * The caller promises to modify only pixels in the area specified + * + * The caller promises to modify only pixels in the area specified * by (l,t,w,h). - * + * * The content of the buffer outside of the specified area is NOT modified * by this call. * @@ -208,9 +211,9 @@ typedef struct gralloc_module_t { * * THREADING CONSIDERATIONS: * - * It is legal for several different threads to lock a buffer from + * It is legal for several different threads to lock a buffer from * read access, none of the threads are blocked. - * + * * However, locking a buffer simultaneously for write or read/write is * undefined, but: * - shall not result in termination of the process @@ -219,21 +222,21 @@ typedef struct gralloc_module_t { * into an indeterminate state. * * If the buffer was created with a usage mask incompatible with the - * requested usage flags here, -EINVAL is returned. - * + * requested usage flags here, -EINVAL is returned. + * */ - + int (*lock)(struct gralloc_module_t const* module, buffer_handle_t handle, int usage, int l, int t, int w, int h, void** vaddr); - + /* * The (*unlock)() method must be called after all changes to the buffer * are completed. */ - + int (*unlock)(struct gralloc_module_t const* module, buffer_handle_t handle); @@ -312,8 +315,38 @@ typedef struct gralloc_module_t { int l, int t, int w, int h, struct android_ycbcr *ycbcr, int fenceFd); + /* getTransportSize(..., outNumFds, outNumInts) + * This function is mandatory on devices running IMapper2.1 or higher. + * + * Get the transport size of a buffer. An imported buffer handle is a raw + * buffer handle with the process-local runtime data appended. This + * function, for example, allows a caller to omit the process-local + * runtime data at the tail when serializing the imported buffer handle. + * + * Note that a client might or might not omit the process-local runtime + * data when sending an imported buffer handle. The mapper must support + * both cases on the receiving end. + */ + int32_t (*getTransportSize)( + struct gralloc_module_t const* module, buffer_handle_t handle, uint32_t *outNumFds, + uint32_t *outNumInts); + + /* validateBufferSize(..., w, h, format, usage, stride) + * This function is mandatory on devices running IMapper2.1 or higher. + * + * Validate that the buffer can be safely accessed by a caller who assumes + * the specified width, height, format, usage, and stride. This must at least validate + * that the buffer size is large enough. Validating the buffer against + * individual buffer attributes is optional. + */ + int32_t (*validateBufferSize)( + struct gralloc_module_t const* device, buffer_handle_t handle, + uint32_t w, uint32_t h, int32_t format, int usage, + uint32_t stride); + /* reserved for future use */ - void* reserved_proc[3]; + void* reserved_proc[1]; + } gralloc_module_t; /*****************************************************************************/ @@ -326,32 +359,32 @@ typedef struct gralloc_module_t { typedef struct alloc_device_t { struct hw_device_t common; - /* + /* * (*alloc)() Allocates a buffer in graphic memory with the requested * parameters and returns a buffer_handle_t and the stride in pixels to * allow the implementation to satisfy hardware constraints on the width - * of a pixmap (eg: it may have to be multiple of 8 pixels). + * of a pixmap (eg: it may have to be multiple of 8 pixels). * The CALLER TAKES OWNERSHIP of the buffer_handle_t. * * If format is HAL_PIXEL_FORMAT_YCbCr_420_888, the returned stride must be * 0, since the actual strides are available from the android_ycbcr * structure. - * + * * Returns 0 on success or -errno on error. */ - + int (*alloc)(struct alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* handle, int* stride); /* - * (*free)() Frees a previously allocated buffer. + * (*free)() Frees a previously allocated buffer. * Behavior is undefined if the buffer is still mapped in any process, * but shall not result in termination of the program or security breaches * (allowing a process to get access to another process' buffers). * THIS FUNCTION TAKES OWNERSHIP of the buffer_handle_t which becomes - * invalid after the call. - * + * invalid after the call. + * * Returns 0 on success or -errno on error. */ int (*free)(struct alloc_device_t* dev, @@ -369,9 +402,9 @@ typedef struct alloc_device_t { /** convenience API for opening and closing a supported device */ -static inline int gralloc_open(const struct hw_module_t* module, +static inline int gralloc_open(const struct hw_module_t* module, struct alloc_device_t** device) { - return module->methods->open(module, + return module->methods->open(module, GRALLOC_HARDWARE_GPU0, TO_HW_DEVICE_T_OPEN(device)); } diff --git a/include/android/metadata/camera_metadata_hidden.h b/include/android/metadata/camera_metadata_hidden.h index 91b11e4346..5629f7981b 100644 --- a/include/android/metadata/camera_metadata_hidden.h +++ b/include/android/metadata/camera_metadata_hidden.h @@ -18,6 +18,9 @@ #ifndef SYSTEM_MEDIA_PRIVATE_INCLUDE_CAMERA_METADATA_HIDDEN_H #define SYSTEM_MEDIA_PRIVATE_INCLUDE_CAMERA_METADATA_HIDDEN_H +#include +#include +#include #include /** @@ -35,14 +38,6 @@ extern "C" { #endif /** **These are private functions for use only by the camera framework.** **/ -/** - * Set the global vendor tag operations object used to define vendor tag - * structure when parsing camera metadata with functions defined in - * system/media/camera/include/camera_metadata.h. - */ -ANDROID_API -int set_camera_metadata_vendor_ops(const vendor_tag_ops_t *query_ops); - /** * Set the global vendor tag cache operations object used to define vendor tag * structure when parsing camera metadata with functions defined in diff --git a/include/android/metadata/system/camera_metadata.h b/include/android/metadata/system/camera_metadata.h index 1672b09ee9..44c836144f 100644 --- a/include/android/metadata/system/camera_metadata.h +++ b/include/android/metadata/system/camera_metadata.h @@ -18,13 +18,13 @@ #ifndef SYSTEM_MEDIA_INCLUDE_ANDROID_CAMERA_METADATA_H #define SYSTEM_MEDIA_INCLUDE_ANDROID_CAMERA_METADATA_H +#include #include #include #include +#include -#ifdef __cplusplus -extern "C" { -#endif +__BEGIN_DECLS /** * Tag hierarchy and enum definitions for camera_metadata_entry @@ -287,7 +287,7 @@ enum { }; /** - * Validate that a metadata is structurally sane. That is, its internal + * Validate that a metadata is structurally correct. That is, its internal * state is such that we won't get buffer overflows or run into other * 'impossible' issues when calling the other API functions. * @@ -481,6 +481,12 @@ ANDROID_API int get_local_camera_metadata_tag_type(uint32_t tag, const camera_metadata_t *meta); +/** + * Retrieve all tags that need permission. + */ +ANDROID_API +const int32_t *get_camera_metadata_permission_needed(uint32_t *tag_count); + /** * Set up vendor-specific tag query methods. These are needed to properly add * entries with vendor-specified tags and to use the @@ -574,8 +580,29 @@ int camera_metadata_enum_snprint(uint32_t tag, char *dst, size_t size); -#ifdef __cplusplus -} -#endif +/** + * Retrieves back the binary value of a given tag enum entry name. Only works for enum tags. + * Returns 0 on success, -1 on failure. + */ +ANDROID_API +int camera_metadata_enum_value(uint32_t tag /*in*/, + const char* name /*in*/, + size_t size /*in*/, + uint32_t *value /*out*/); + +/** + * Set the global vendor tag operations object used to define vendor tag + * structure when parsing camera metadata with functions defined in + * system/media/camera/include/camera_metadata.h. + * + * Note: this is moved from system/media/private/camera/include/camera_metadata_hidden.h. + * Every process that needs to read or write vendor tags has to call this method before + * attempting to use them. The OS will handle standard app and system service processes, + * but OEMs may need to invoke this method in HALs that process camera data. + */ +ANDROID_API +int set_camera_metadata_vendor_ops(const vendor_tag_ops_t *query_ops); + +__END_DECLS #endif diff --git a/include/android/metadata/system/camera_metadata_tags.h b/include/android/metadata/system/camera_metadata_tags.h index e0f2f5a37a..af6d5258ae 100644 --- a/include/android/metadata/system/camera_metadata_tags.h +++ b/include/android/metadata/system/camera_metadata_tags.h @@ -64,6 +64,14 @@ typedef enum camera_metadata_section { ANDROID_DEPTH, ANDROID_LOGICAL_MULTI_CAMERA, ANDROID_DISTORTION_CORRECTION, + ANDROID_HEIC, + ANDROID_HEIC_INFO, + ANDROID_AUTOMOTIVE, + ANDROID_AUTOMOTIVE_LENS, + ANDROID_EXTENSION, + ANDROID_JPEGR, + ANDROID_SHARED_SESSION, + ANDROID_DESKTOP_EFFECTS, ANDROID_SECTION_COUNT, VENDOR_SECTION = 0x8000 @@ -106,6 +114,14 @@ typedef enum camera_metadata_section_start { ANDROID_DISTORTION_CORRECTION_START = ANDROID_DISTORTION_CORRECTION << 16, + ANDROID_HEIC_START = ANDROID_HEIC << 16, + ANDROID_HEIC_INFO_START = ANDROID_HEIC_INFO << 16, + ANDROID_AUTOMOTIVE_START = ANDROID_AUTOMOTIVE << 16, + ANDROID_AUTOMOTIVE_LENS_START = ANDROID_AUTOMOTIVE_LENS << 16, + ANDROID_EXTENSION_START = ANDROID_EXTENSION << 16, + ANDROID_JPEGR_START = ANDROID_JPEGR << 16, + ANDROID_SHARED_SESSION_START = ANDROID_SHARED_SESSION << 16, + ANDROID_DESKTOP_EFFECTS_START = ANDROID_DESKTOP_EFFECTS << 16, VENDOR_SECTION_START = VENDOR_SECTION << 16 } camera_metadata_section_start_t; @@ -123,6 +139,10 @@ typedef enum camera_metadata_tag { ANDROID_COLOR_CORRECTION_ABERRATION_MODE, // enum | public | HIDL v3.2 ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, // byte[] | public | HIDL v3.2 + ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE, // int32 | public | HIDL v3.11 + ANDROID_COLOR_CORRECTION_COLOR_TINT, // int32 | public | HIDL v3.11 + ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE, // int32[] | public | HIDL v3.11 + ANDROID_COLOR_CORRECTION_AVAILABLE_MODES, // byte[] | public | HIDL v3.11 ANDROID_COLOR_CORRECTION_END, ANDROID_CONTROL_AE_ANTIBANDING_MODE = // enum | public | HIDL v3.2 @@ -171,6 +191,30 @@ typedef enum camera_metadata_tag { ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST, // int32 | public | HIDL v3.2 ANDROID_CONTROL_ENABLE_ZSL, // enum | public | HIDL v3.2 ANDROID_CONTROL_AF_SCENE_CHANGE, // enum | public | HIDL v3.3 + ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES, + // int32[] | ndk_public | HIDL v3.5 + ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES, + // float[] | ndk_public | HIDL v3.5 + ANDROID_CONTROL_EXTENDED_SCENE_MODE, // enum | public | HIDL v3.5 + ANDROID_CONTROL_ZOOM_RATIO_RANGE, // float[] | public | HIDL v3.5 + ANDROID_CONTROL_ZOOM_RATIO, // float | public | HIDL v3.5 + ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION, + // int32[] | hidden | HIDL v3.6 + ANDROID_CONTROL_AF_REGIONS_SET, // enum | fwk_only + ANDROID_CONTROL_AE_REGIONS_SET, // enum | fwk_only + ANDROID_CONTROL_AWB_REGIONS_SET, // enum | fwk_only + ANDROID_CONTROL_SETTINGS_OVERRIDE, // enum | public | HIDL v3.9 + ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES, // int32[] | public | HIDL v3.9 + ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER, // int32 | system | HIDL v3.9 + ANDROID_CONTROL_AUTOFRAMING, // enum | public | HIDL v3.9 + ANDROID_CONTROL_AUTOFRAMING_AVAILABLE, // enum | public | HIDL v3.9 + ANDROID_CONTROL_AUTOFRAMING_STATE, // enum | public | HIDL v3.9 + ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE, + // float[] | public | HIDL v3.10 + ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE, // enum | public | HIDL v3.10 + ANDROID_CONTROL_ZOOM_METHOD, // enum | fwk_public + ANDROID_CONTROL_AE_PRIORITY_MODE, // enum | public | HIDL v3.11 + ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES, // byte[] | public | HIDL v3.11 ANDROID_CONTROL_END, ANDROID_DEMOSAIC_MODE = // enum | system | HIDL v3.2 @@ -190,11 +234,18 @@ typedef enum camera_metadata_tag { ANDROID_FLASH_COLOR_TEMPERATURE, // byte | system | HIDL v3.2 ANDROID_FLASH_MAX_ENERGY, // byte | system | HIDL v3.2 ANDROID_FLASH_STATE, // enum | public | HIDL v3.2 + ANDROID_FLASH_STRENGTH_LEVEL, // int32 | public | HIDL v3.10 + ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL, // int32 | public | HIDL v3.10 + ANDROID_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL, // int32 | public | HIDL v3.10 + ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL, // int32 | public | HIDL v3.10 + ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL, // int32 | public | HIDL v3.10 ANDROID_FLASH_END, ANDROID_FLASH_INFO_AVAILABLE = // enum | public | HIDL v3.2 ANDROID_FLASH_INFO_START, ANDROID_FLASH_INFO_CHARGE_DURATION, // int64 | system | HIDL v3.2 + ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL, // int32 | public | HIDL v3.8 + ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL, // int32 | public | HIDL v3.8 ANDROID_FLASH_INFO_END, ANDROID_HOT_PIXEL_MODE = // enum | public | HIDL v3.2 @@ -230,6 +281,9 @@ typedef enum camera_metadata_tag { ANDROID_LENS_RADIAL_DISTORTION, // float[] | public | HIDL v3.2 ANDROID_LENS_POSE_REFERENCE, // enum | public | HIDL v3.3 ANDROID_LENS_DISTORTION, // float[] | public | HIDL v3.3 + ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION, // float[] | public | HIDL v3.6 + ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION, + // float[] | public | HIDL v3.6 ANDROID_LENS_END, ANDROID_LENS_INFO_AVAILABLE_APERTURES = // float[] | public | HIDL v3.2 @@ -277,7 +331,15 @@ typedef enum camera_metadata_tag { ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, // int32[] | ndk_public | HIDL v3.2 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS, // int32[] | ndk_public | HIDL v3.3 ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, - // int32[] | hidden | HIDL v3.3 + // int32[] | ndk_public | HIDL v3.3 + ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION, + // int32[] | hidden | HIDL v3.4 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP, + // enum[] | ndk_public | HIDL v3.8 + ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE, + // int64 | java_public | HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP, + // enum[] | ndk_public | HIDL v3.9 ANDROID_REQUEST_END, ANDROID_SCALER_CROP_REGION = // int32[] | public | HIDL v3.2 @@ -295,6 +357,29 @@ typedef enum camera_metadata_tag { ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, // int64[] | ndk_public | HIDL v3.2 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, // int64[] | ndk_public | HIDL v3.2 ANDROID_SCALER_CROPPING_TYPE, // enum | public | HIDL v3.2 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS, + // enum[] | ndk_public | HIDL v3.4 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP, + // int32 | ndk_public | HIDL v3.4 + ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES, // byte[] | public | HIDL v3.5 + ANDROID_SCALER_ROTATE_AND_CROP, // enum | public | HIDL v3.5 + ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE, // int32[] | public | HIDL v3.6 + ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS, + // enum[] | ndk_public | HIDL v3.6 + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION, + // enum[] | ndk_public | HIDL v3.6 + ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.6 + ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.6 + ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION, + // int32 | hidden | HIDL v3.6 + ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED, // enum | ndk_public | HIDL v3.6 + ANDROID_SCALER_CROP_REGION_SET, // enum | fwk_only + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES, // enum[] | public | HIDL v3.8 + ANDROID_SCALER_RAW_CROP_REGION, // int32[] | public | HIDL v3.9 + ANDROID_SCALER_CONCURRENT_MULTI_RESOLUTION_FORMATS, + // int32[] | ndk_public | HIDL v3.12 ANDROID_SCALER_END, ANDROID_SENSOR_EXPOSURE_TIME = // int64 | public | HIDL v3.2 @@ -329,6 +414,10 @@ typedef enum camera_metadata_tag { ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL, // float[] | public | HIDL v3.2 ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL, // int32 | public | HIDL v3.2 ANDROID_SENSOR_OPAQUE_RAW_SIZE, // int32[] | system | HIDL v3.2 + ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION,// int32[] | system | HIDL v3.6 + ANDROID_SENSOR_PIXEL_MODE, // enum | public | HIDL v3.6 + ANDROID_SENSOR_RAW_BINNING_FACTOR_USED, // enum | public | HIDL v3.6 + ANDROID_SENSOR_READOUT_TIMESTAMP, // enum | java_public | HIDL v3.8 ANDROID_SENSOR_END, ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE = // int32[] | public | HIDL v3.2 @@ -344,6 +433,13 @@ typedef enum camera_metadata_tag { ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED, // enum | public | HIDL v3.2 ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, // int32[] | public | HIDL v3.2 + ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, + // int32[] | public | HIDL v3.6 + ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION, + // int32[] | public | HIDL v3.6 + ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION, + // int32[] | public | HIDL v3.6 + ANDROID_SENSOR_INFO_BINNING_FACTOR, // int32[] | public | HIDL v3.6 ANDROID_SENSOR_INFO_END, ANDROID_SHADING_MODE = // enum | public | HIDL v3.2 @@ -374,9 +470,11 @@ typedef enum camera_metadata_tag { ANDROID_STATISTICS_OIS_TIMESTAMPS, // int64[] | ndk_public | HIDL v3.3 ANDROID_STATISTICS_OIS_X_SHIFTS, // float[] | ndk_public | HIDL v3.3 ANDROID_STATISTICS_OIS_Y_SHIFTS, // float[] | ndk_public | HIDL v3.3 + ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS, // int64[] | ndk_public | HIDL v3.10 + ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES, // float[] | ndk_public | HIDL v3.10 ANDROID_STATISTICS_END, - ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES = + ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES = // byte[] | public | HIDL v3.2 ANDROID_STATISTICS_INFO_START, ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT, // int32 | system | HIDL v3.2 @@ -410,6 +508,11 @@ typedef enum camera_metadata_tag { ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL = // enum | public | HIDL v3.2 ANDROID_INFO_START, ANDROID_INFO_VERSION, // byte | public | HIDL v3.3 + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, // enum | system | HIDL v3.4 + ANDROID_INFO_DEVICE_STATE_ORIENTATIONS, // int64[] | ndk_public | HIDL v3.7 + ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION, // enum | fwk_java_public + ANDROID_INFO_DEVICE_ID, // int32 | fwk_only + ANDROID_INFO_DEVICE_TYPE, // enum | public | HIDL v3.12 ANDROID_INFO_END, ANDROID_BLACK_LEVEL_LOCK = // enum | public | HIDL v3.2 @@ -433,11 +536,35 @@ typedef enum camera_metadata_tag { ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS,// int64[] | ndk_public | HIDL v3.2 ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS, // int64[] | ndk_public | HIDL v3.2 ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE, // enum | public | HIDL v3.2 + ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS, + // int32[] | ndk_public | HIDL v3.4 + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS, + // enum[] | ndk_public | HIDL v3.4 + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS, + // int64[] | ndk_public | HIDL v3.4 + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS, + // int64[] | ndk_public | HIDL v3.4 + ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION, + // enum[] | ndk_public | HIDL v3.6 + ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.6 + ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.6 + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION, + // enum[] | ndk_public | HIDL v3.6 + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.6 + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.6 ANDROID_DEPTH_END, - ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS = // byte[] | hidden | HIDL v3.3 + ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS = // byte[] | ndk_public | HIDL v3.3 ANDROID_LOGICAL_MULTI_CAMERA_START, ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE, // enum | public | HIDL v3.3 + ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID, // byte | public | HIDL v3.4 + ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION, + // int32[] | public | HIDL v3.10 + ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS, // enum | public | HIDL v3.12 ANDROID_LOGICAL_MULTI_CAMERA_END, ANDROID_DISTORTION_CORRECTION_MODE = // enum | public | HIDL v3.3 @@ -445,6 +572,78 @@ typedef enum camera_metadata_tag { ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES, // byte[] | public | HIDL v3.3 ANDROID_DISTORTION_CORRECTION_END, + ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS = + // enum[] | ndk_public | HIDL v3.4 + ANDROID_HEIC_START, + ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS, // int64[] | ndk_public | HIDL v3.4 + ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS, // int64[] | ndk_public | HIDL v3.4 + ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION, + // enum[] | ndk_public | HIDL v3.6 + ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.6 + ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.6 + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS, + // enum[] | ndk_public | HIDL v3.11 + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS, + // int64[] | ndk_public | HIDL v3.11 + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS, + // int64[] | ndk_public | HIDL v3.11 + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION, + // enum[] | ndk_public | HIDL v3.11 + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.11 + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.11 + ANDROID_HEIC_END, + + ANDROID_HEIC_INFO_SUPPORTED = // enum | system | HIDL v3.4 + ANDROID_HEIC_INFO_START, + ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT, // byte | system | HIDL v3.4 + ANDROID_HEIC_INFO_END, + + ANDROID_AUTOMOTIVE_LOCATION = // enum | public | HIDL v3.8 + ANDROID_AUTOMOTIVE_START, + ANDROID_AUTOMOTIVE_END, + + ANDROID_AUTOMOTIVE_LENS_FACING = // enum[] | public | HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_START, + ANDROID_AUTOMOTIVE_LENS_END, + + ANDROID_EXTENSION_STRENGTH = // int32 | extension_passthrough | HIDL v3.9 + ANDROID_EXTENSION_START, + ANDROID_EXTENSION_CURRENT_TYPE, // int32 | fwk_java_public + ANDROID_EXTENSION_NIGHT_MODE_INDICATOR, // enum | public | HIDL v3.11 + ANDROID_EXTENSION_END, + + ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS = + // enum[] | ndk_public | HIDL v3.9 + ANDROID_JPEGR_START, + ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS, + // int64[] | ndk_public | HIDL v3.9 + ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS, // int64[] | ndk_public | HIDL v3.9 + ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION, + // enum[] | ndk_public | HIDL v3.9 + ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.9 + ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION, + // int64[] | ndk_public | HIDL v3.9 + ANDROID_JPEGR_END, + + ANDROID_SHARED_SESSION_COLOR_SPACE = // enum | fwk_only + ANDROID_SHARED_SESSION_START, + ANDROID_SHARED_SESSION_OUTPUT_CONFIGURATIONS, // int64[] | fwk_only + ANDROID_SHARED_SESSION_END, + + ANDROID_DESKTOP_EFFECTS_CAPABILITIES = // enum[] | system | HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_START, + ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODES, // byte[] | system | HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE, // enum | system | HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE, // enum | system | HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_STRENGTH, // byte | system | HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE, // enum | system | HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_END, + } camera_metadata_tag_t; /** @@ -456,6 +655,7 @@ typedef enum camera_metadata_enum_android_color_correction_mode { ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX , // HIDL v3.2 ANDROID_COLOR_CORRECTION_MODE_FAST , // HIDL v3.2 ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY , // HIDL v3.2 + ANDROID_COLOR_CORRECTION_MODE_CCT , // HIDL v3.11 } camera_metadata_enum_android_color_correction_mode_t; // ANDROID_COLOR_CORRECTION_ABERRATION_MODE @@ -488,6 +688,7 @@ typedef enum camera_metadata_enum_android_control_ae_mode { ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH , // HIDL v3.2 ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE , // HIDL v3.2 ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH , // HIDL v3.3 + ANDROID_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY , // HIDL v3.10 } camera_metadata_enum_android_control_ae_mode_t; // ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER @@ -564,6 +765,7 @@ typedef enum camera_metadata_enum_android_control_mode { ANDROID_CONTROL_MODE_AUTO , // HIDL v3.2 ANDROID_CONTROL_MODE_USE_SCENE_MODE , // HIDL v3.2 ANDROID_CONTROL_MODE_OFF_KEEP_STATE , // HIDL v3.2 + ANDROID_CONTROL_MODE_USE_EXTENDED_SCENE_MODE , // HIDL v3.5 } camera_metadata_enum_android_control_mode_t; // ANDROID_CONTROL_SCENE_MODE @@ -596,6 +798,7 @@ typedef enum camera_metadata_enum_android_control_scene_mode { typedef enum camera_metadata_enum_android_control_video_stabilization_mode { ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF , // HIDL v3.2 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON , // HIDL v3.2 + ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION , // HIDL v3.8 } camera_metadata_enum_android_control_video_stabilization_mode_t; // ANDROID_CONTROL_AE_STATE @@ -651,6 +854,78 @@ typedef enum camera_metadata_enum_android_control_af_scene_change { ANDROID_CONTROL_AF_SCENE_CHANGE_DETECTED , // HIDL v3.3 } camera_metadata_enum_android_control_af_scene_change_t; +// ANDROID_CONTROL_EXTENDED_SCENE_MODE +typedef enum camera_metadata_enum_android_control_extended_scene_mode { + ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED = 0, // HIDL v3.5 + ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE , // HIDL v3.5 + ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS , // HIDL v3.5 + ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START = 0x40, // HIDL v3.5 +} camera_metadata_enum_android_control_extended_scene_mode_t; + +// ANDROID_CONTROL_AF_REGIONS_SET +typedef enum camera_metadata_enum_android_control_af_regions_set { + ANDROID_CONTROL_AF_REGIONS_SET_FALSE , + ANDROID_CONTROL_AF_REGIONS_SET_TRUE , +} camera_metadata_enum_android_control_af_regions_set_t; + +// ANDROID_CONTROL_AE_REGIONS_SET +typedef enum camera_metadata_enum_android_control_ae_regions_set { + ANDROID_CONTROL_AE_REGIONS_SET_FALSE , + ANDROID_CONTROL_AE_REGIONS_SET_TRUE , +} camera_metadata_enum_android_control_ae_regions_set_t; + +// ANDROID_CONTROL_AWB_REGIONS_SET +typedef enum camera_metadata_enum_android_control_awb_regions_set { + ANDROID_CONTROL_AWB_REGIONS_SET_FALSE , + ANDROID_CONTROL_AWB_REGIONS_SET_TRUE , +} camera_metadata_enum_android_control_awb_regions_set_t; + +// ANDROID_CONTROL_SETTINGS_OVERRIDE +typedef enum camera_metadata_enum_android_control_settings_override { + ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF , // HIDL v3.9 + ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM , // HIDL v3.9 + ANDROID_CONTROL_SETTINGS_OVERRIDE_VENDOR_START = 0x4000, // HIDL v3.9 +} camera_metadata_enum_android_control_settings_override_t; + +// ANDROID_CONTROL_AUTOFRAMING +typedef enum camera_metadata_enum_android_control_autoframing { + ANDROID_CONTROL_AUTOFRAMING_OFF , // HIDL v3.9 + ANDROID_CONTROL_AUTOFRAMING_ON , // HIDL v3.9 + ANDROID_CONTROL_AUTOFRAMING_AUTO , // HIDL v3.9 +} camera_metadata_enum_android_control_autoframing_t; + +// ANDROID_CONTROL_AUTOFRAMING_AVAILABLE +typedef enum camera_metadata_enum_android_control_autoframing_available { + ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE , // HIDL v3.9 + ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_TRUE , // HIDL v3.9 +} camera_metadata_enum_android_control_autoframing_available_t; + +// ANDROID_CONTROL_AUTOFRAMING_STATE +typedef enum camera_metadata_enum_android_control_autoframing_state { + ANDROID_CONTROL_AUTOFRAMING_STATE_INACTIVE , // HIDL v3.9 + ANDROID_CONTROL_AUTOFRAMING_STATE_FRAMING , // HIDL v3.9 + ANDROID_CONTROL_AUTOFRAMING_STATE_CONVERGED , // HIDL v3.9 +} camera_metadata_enum_android_control_autoframing_state_t; + +// ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE +typedef enum camera_metadata_enum_android_control_low_light_boost_state { + ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE , // HIDL v3.10 + ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE , // HIDL v3.10 +} camera_metadata_enum_android_control_low_light_boost_state_t; + +// ANDROID_CONTROL_ZOOM_METHOD +typedef enum camera_metadata_enum_android_control_zoom_method { + ANDROID_CONTROL_ZOOM_METHOD_AUTO = 0, + ANDROID_CONTROL_ZOOM_METHOD_ZOOM_RATIO = 1, +} camera_metadata_enum_android_control_zoom_method_t; + +// ANDROID_CONTROL_AE_PRIORITY_MODE +typedef enum camera_metadata_enum_android_control_ae_priority_mode { + ANDROID_CONTROL_AE_PRIORITY_MODE_OFF , // HIDL v3.11 + ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_SENSITIVITY_PRIORITY , // HIDL v3.11 + ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_EXPOSURE_TIME_PRIORITY , // HIDL v3.11 +} camera_metadata_enum_android_control_ae_priority_mode_t; + // ANDROID_DEMOSAIC_MODE typedef enum camera_metadata_enum_android_demosaic_mode { @@ -724,6 +999,8 @@ typedef enum camera_metadata_enum_android_lens_state { typedef enum camera_metadata_enum_android_lens_pose_reference { ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA , // HIDL v3.3 ANDROID_LENS_POSE_REFERENCE_GYROSCOPE , // HIDL v3.3 + ANDROID_LENS_POSE_REFERENCE_UNDEFINED , // HIDL v3.5 + ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE , // HIDL v3.8 } camera_metadata_enum_android_lens_pose_reference_t; @@ -780,8 +1057,75 @@ typedef enum camera_metadata_enum_android_request_available_capabilities { ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING , // HIDL v3.3 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA , // HIDL v3.3 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME , // HIDL v3.3 + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA , // HIDL v3.4 + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA , // HIDL v3.5 + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING , // HIDL v3.5 + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR + , // HIDL v3.6 + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING , // HIDL v3.6 + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT , // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE , // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES , // HIDL v3.9 } camera_metadata_enum_android_request_available_capabilities_t; +// ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP +typedef enum camera_metadata_enum_android_request_available_dynamic_range_profiles_map { + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD = 0x1, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10 = 0x2, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10 = 0x4, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS = 0x8, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF + = 0x10, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO + = 0x20, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM + = 0x40, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO + = 0x80, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF + = 0x100, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO + = 0x200, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM + = 0x400, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO + = 0x800, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX = 0x1000, // HIDL v3.8 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD_SMPTE_2094_50 + = 0x2000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10_SMPTE_2094_50 + = 0x4000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_SMPTE_2094_50 + = 0x8000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS_SMPTE_2094_50 + = 0x10000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_SMPTE_2094_50 + = 0x20000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO_SMPTE_2094_50 + = 0x40000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_SMPTE_2094_50 + = 0x80000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO_SMPTE_2094_50 + = 0x100000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_SMPTE_2094_50 + = 0x200000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO_SMPTE_2094_50 + = 0x400000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_SMPTE_2094_50 + = 0x800000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO_SMPTE_2094_50 + = 0x1000000, // HIDL v3.12 + ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX_312 = 0x2000000, // HIDL v3.12 +} camera_metadata_enum_android_request_available_dynamic_range_profiles_map_t; + +// ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP +typedef enum camera_metadata_enum_android_request_available_color_space_profiles_map { + ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED = -1, // HIDL v3.9 + ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB = 0, // HIDL v3.9 + ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3 = 7, // HIDL v3.9 + ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG = 16, // HIDL v3.9 +} camera_metadata_enum_android_request_available_color_space_profiles_map_t; + // ANDROID_SCALER_AVAILABLE_FORMATS typedef enum camera_metadata_enum_android_scaler_available_formats { @@ -792,6 +1136,10 @@ typedef enum camera_metadata_enum_android_scaler_available_formats { ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED = 0x22, // HIDL v3.2 ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888 = 0x23, // HIDL v3.2 ANDROID_SCALER_AVAILABLE_FORMATS_BLOB = 0x21, // HIDL v3.2 + ANDROID_SCALER_AVAILABLE_FORMATS_RAW10 = 0x25, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_FORMATS_RAW12 = 0x26, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_FORMATS_RAW14 = 0x2C, // HIDL v3.12 + ANDROID_SCALER_AVAILABLE_FORMATS_Y8 = 0x20203859, // HIDL v3.4 } camera_metadata_enum_android_scaler_available_formats_t; // ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS @@ -806,6 +1154,79 @@ typedef enum camera_metadata_enum_android_scaler_cropping_type { ANDROID_SCALER_CROPPING_TYPE_FREEFORM , // HIDL v3.2 } camera_metadata_enum_android_scaler_cropping_type_t; +// ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS +typedef enum camera_metadata_enum_android_scaler_available_recommended_stream_configurations { + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW + = 0x0, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD + = 0x1, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT + = 0x2, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT + = 0x3, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL = 0x4, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW = 0x5, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT + = 0x6, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END + = 0x7, // HIDL v3.4 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT + = 0x8, // HIDL v3.8 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8 + = 0x9, // HIDL v3.8 + ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START + = 0x18, // HIDL v3.4 +} camera_metadata_enum_android_scaler_available_recommended_stream_configurations_t; + +// ANDROID_SCALER_ROTATE_AND_CROP +typedef enum camera_metadata_enum_android_scaler_rotate_and_crop { + ANDROID_SCALER_ROTATE_AND_CROP_NONE , // HIDL v3.5 + ANDROID_SCALER_ROTATE_AND_CROP_90 , // HIDL v3.5 + ANDROID_SCALER_ROTATE_AND_CROP_180 , // HIDL v3.5 + ANDROID_SCALER_ROTATE_AND_CROP_270 , // HIDL v3.5 + ANDROID_SCALER_ROTATE_AND_CROP_AUTO , // HIDL v3.5 +} camera_metadata_enum_android_scaler_rotate_and_crop_t; + +// ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS +typedef enum camera_metadata_enum_android_scaler_physical_camera_multi_resolution_stream_configurations { + ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT + , // HIDL v3.6 + ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT + , // HIDL v3.6 +} camera_metadata_enum_android_scaler_physical_camera_multi_resolution_stream_configurations_t; + +// ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION +typedef enum camera_metadata_enum_android_scaler_available_stream_configurations_maximum_resolution { + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT + , // HIDL v3.6 + ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT + , // HIDL v3.6 +} camera_metadata_enum_android_scaler_available_stream_configurations_maximum_resolution_t; + +// ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED +typedef enum camera_metadata_enum_android_scaler_multi_resolution_stream_supported { + ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_FALSE , // HIDL v3.6 + ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE , // HIDL v3.6 +} camera_metadata_enum_android_scaler_multi_resolution_stream_supported_t; + +// ANDROID_SCALER_CROP_REGION_SET +typedef enum camera_metadata_enum_android_scaler_crop_region_set { + ANDROID_SCALER_CROP_REGION_SET_FALSE , + ANDROID_SCALER_CROP_REGION_SET_TRUE , +} camera_metadata_enum_android_scaler_crop_region_set_t; + +// ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES +typedef enum camera_metadata_enum_android_scaler_available_stream_use_cases { + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT = 0x0, // HIDL v3.8 + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW = 0x1, // HIDL v3.8 + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE = 0x2, // HIDL v3.8 + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD = 0x3, // HIDL v3.8 + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL = 0x4, // HIDL v3.8 + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL = 0x5, // HIDL v3.8 + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW = 0x6, // HIDL v3.9 + ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START = 0x10000, // HIDL v3.8 +} camera_metadata_enum_android_scaler_available_stream_use_cases_t; + // ANDROID_SENSOR_REFERENCE_ILLUMINANT1 typedef enum camera_metadata_enum_android_sensor_reference_illuminant1 { @@ -837,9 +1258,28 @@ typedef enum camera_metadata_enum_android_sensor_test_pattern_mode { ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS , // HIDL v3.2 ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY , // HIDL v3.2 ANDROID_SENSOR_TEST_PATTERN_MODE_PN9 , // HIDL v3.2 + ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK , // HIDL v3.6 ANDROID_SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256, // HIDL v3.2 } camera_metadata_enum_android_sensor_test_pattern_mode_t; +// ANDROID_SENSOR_PIXEL_MODE +typedef enum camera_metadata_enum_android_sensor_pixel_mode { + ANDROID_SENSOR_PIXEL_MODE_DEFAULT , // HIDL v3.6 + ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION , // HIDL v3.6 +} camera_metadata_enum_android_sensor_pixel_mode_t; + +// ANDROID_SENSOR_RAW_BINNING_FACTOR_USED +typedef enum camera_metadata_enum_android_sensor_raw_binning_factor_used { + ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_TRUE , // HIDL v3.6 + ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_FALSE , // HIDL v3.6 +} camera_metadata_enum_android_sensor_raw_binning_factor_used_t; + +// ANDROID_SENSOR_READOUT_TIMESTAMP +typedef enum camera_metadata_enum_android_sensor_readout_timestamp { + ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED , // HIDL v3.8 + ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE , // HIDL v3.8 +} camera_metadata_enum_android_sensor_readout_timestamp_t; + // ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT typedef enum camera_metadata_enum_android_sensor_info_color_filter_arrangement { @@ -848,6 +1288,8 @@ typedef enum camera_metadata_enum_android_sensor_info_color_filter_arrangement { ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG , // HIDL v3.2 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR , // HIDL v3.2 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB , // HIDL v3.2 + ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO , // HIDL v3.4 + ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR , // HIDL v3.4 } camera_metadata_enum_android_sensor_info_color_filter_arrangement_t; // ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE @@ -954,6 +1396,30 @@ typedef enum camera_metadata_enum_android_info_supported_hardware_level { ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL , // HIDL v3.3 } camera_metadata_enum_android_info_supported_hardware_level_t; +// ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION +typedef enum camera_metadata_enum_android_info_supported_buffer_management_version { + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5, // HIDL v3.4 + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE + , // HIDL v3.10 +} camera_metadata_enum_android_info_supported_buffer_management_version_t; + +// ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION +typedef enum camera_metadata_enum_android_info_session_configuration_query_version { + ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_UPSIDE_DOWN_CAKE + = 34, + ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_VANILLA_ICE_CREAM + = 35, + ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_BAKLAVA = 36, +} camera_metadata_enum_android_info_session_configuration_query_version_t; + +// ANDROID_INFO_DEVICE_TYPE +typedef enum camera_metadata_enum_android_info_device_type { + ANDROID_INFO_DEVICE_TYPE_BUILT_IN , // HIDL v3.12 + ANDROID_INFO_DEVICE_TYPE_EXTERNAL , // HIDL v3.12 + ANDROID_INFO_DEVICE_TYPE_VIRTUAL , // HIDL v3.12 + ANDROID_INFO_DEVICE_TYPE_UNKNOWN , // HIDL v3.12 +} camera_metadata_enum_android_info_device_type_t; + // ANDROID_BLACK_LEVEL_LOCK typedef enum camera_metadata_enum_android_black_level_lock { @@ -988,6 +1454,30 @@ typedef enum camera_metadata_enum_android_depth_depth_is_exclusive { ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_TRUE , // HIDL v3.2 } camera_metadata_enum_android_depth_depth_is_exclusive_t; +// ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS +typedef enum camera_metadata_enum_android_depth_available_dynamic_depth_stream_configurations { + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT + , // HIDL v3.4 + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT + , // HIDL v3.4 +} camera_metadata_enum_android_depth_available_dynamic_depth_stream_configurations_t; + +// ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION +typedef enum camera_metadata_enum_android_depth_available_depth_stream_configurations_maximum_resolution { + ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT + , // HIDL v3.6 + ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT + , // HIDL v3.6 +} camera_metadata_enum_android_depth_available_depth_stream_configurations_maximum_resolution_t; + +// ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION +typedef enum camera_metadata_enum_android_depth_available_dynamic_depth_stream_configurations_maximum_resolution { + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT + , // HIDL v3.6 + ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT + , // HIDL v3.6 +} camera_metadata_enum_android_depth_available_dynamic_depth_stream_configurations_maximum_resolution_t; + // ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE typedef enum camera_metadata_enum_android_logical_multi_camera_sensor_sync_type { @@ -995,6 +1485,12 @@ typedef enum camera_metadata_enum_android_logical_multi_camera_sensor_sync_type ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED , // HIDL v3.3 } camera_metadata_enum_android_logical_multi_camera_sensor_sync_type_t; +// ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS +typedef enum camera_metadata_enum_android_logical_multi_camera_additional_results { + ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS_OFF , // HIDL v3.12 + ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS_ON , // HIDL v3.12 +} camera_metadata_enum_android_logical_multi_camera_additional_results_t; + // ANDROID_DISTORTION_CORRECTION_MODE typedef enum camera_metadata_enum_android_distortion_correction_mode { @@ -1004,3 +1500,134 @@ typedef enum camera_metadata_enum_android_distortion_correction_mode { } camera_metadata_enum_android_distortion_correction_mode_t; +// ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS +typedef enum camera_metadata_enum_android_heic_available_heic_stream_configurations { + ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT , // HIDL v3.4 + ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT , // HIDL v3.4 +} camera_metadata_enum_android_heic_available_heic_stream_configurations_t; + +// ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION +typedef enum camera_metadata_enum_android_heic_available_heic_stream_configurations_maximum_resolution { + ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT + , // HIDL v3.6 + ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT + , // HIDL v3.6 +} camera_metadata_enum_android_heic_available_heic_stream_configurations_maximum_resolution_t; + +// ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS +typedef enum camera_metadata_enum_android_heic_available_heic_ultra_hdr_stream_configurations { + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_OUTPUT + , // HIDL v3.11 + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_INPUT + , // HIDL v3.11 +} camera_metadata_enum_android_heic_available_heic_ultra_hdr_stream_configurations_t; + +// ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION +typedef enum camera_metadata_enum_android_heic_available_heic_ultra_hdr_stream_configurations_maximum_resolution { + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT + , // HIDL v3.11 + ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT + , // HIDL v3.11 +} camera_metadata_enum_android_heic_available_heic_ultra_hdr_stream_configurations_maximum_resolution_t; + + +// ANDROID_HEIC_INFO_SUPPORTED +typedef enum camera_metadata_enum_android_heic_info_supported { + ANDROID_HEIC_INFO_SUPPORTED_FALSE , // HIDL v3.4 + ANDROID_HEIC_INFO_SUPPORTED_TRUE , // HIDL v3.4 +} camera_metadata_enum_android_heic_info_supported_t; + + +// ANDROID_AUTOMOTIVE_LOCATION +typedef enum camera_metadata_enum_android_automotive_location { + ANDROID_AUTOMOTIVE_LOCATION_INTERIOR , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT , // HIDL v3.8 +} camera_metadata_enum_android_automotive_location_t; + + +// ANDROID_AUTOMOTIVE_LENS_FACING +typedef enum camera_metadata_enum_android_automotive_lens_facing { + ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER , // HIDL v3.8 + ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT , // HIDL v3.8 +} camera_metadata_enum_android_automotive_lens_facing_t; + + +// ANDROID_EXTENSION_NIGHT_MODE_INDICATOR +typedef enum camera_metadata_enum_android_extension_night_mode_indicator { + ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_UNKNOWN , // HIDL v3.11 + ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_OFF , // HIDL v3.11 + ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_ON , // HIDL v3.11 +} camera_metadata_enum_android_extension_night_mode_indicator_t; + + +// ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS +typedef enum camera_metadata_enum_android_jpegr_available_jpeg_r_stream_configurations { + ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_OUTPUT , // HIDL v3.9 + ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_INPUT , // HIDL v3.9 +} camera_metadata_enum_android_jpegr_available_jpeg_r_stream_configurations_t; + +// ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION +typedef enum camera_metadata_enum_android_jpegr_available_jpeg_r_stream_configurations_maximum_resolution { + ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT + , // HIDL v3.9 + ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT + , // HIDL v3.9 +} camera_metadata_enum_android_jpegr_available_jpeg_r_stream_configurations_maximum_resolution_t; + + +// ANDROID_SHARED_SESSION_COLOR_SPACE +typedef enum camera_metadata_enum_android_shared_session_color_space { + ANDROID_SHARED_SESSION_COLOR_SPACE_UNSPECIFIED = -1, + ANDROID_SHARED_SESSION_COLOR_SPACE_SRGB = 0, + ANDROID_SHARED_SESSION_COLOR_SPACE_DISPLAY_P3 = 7, + ANDROID_SHARED_SESSION_COLOR_SPACE_BT2020_HLG = 16, +} camera_metadata_enum_android_shared_session_color_space_t; + + +// ANDROID_DESKTOP_EFFECTS_CAPABILITIES +typedef enum camera_metadata_enum_android_desktop_effects_capabilities { + ANDROID_DESKTOP_EFFECTS_CAPABILITIES_BACKGROUND_BLUR , // HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_CAPABILITIES_FACE_RETOUCH , // HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_CAPABILITIES_PORTRAIT_RELIGHT , // HIDL v3.2 +} camera_metadata_enum_android_desktop_effects_capabilities_t; + +// ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE +typedef enum camera_metadata_enum_android_desktop_effects_background_blur_mode { + ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_OFF , // HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_LIGHT , // HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_FULL , // HIDL v3.2 +} camera_metadata_enum_android_desktop_effects_background_blur_mode_t; + +// ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE +typedef enum camera_metadata_enum_android_desktop_effects_face_retouch_mode { + ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_OFF , // HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_ON , // HIDL v3.2 +} camera_metadata_enum_android_desktop_effects_face_retouch_mode_t; + +// ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE +typedef enum camera_metadata_enum_android_desktop_effects_portrait_relight_mode { + ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_OFF , // HIDL v3.2 + ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_ON , // HIDL v3.2 +} camera_metadata_enum_android_desktop_effects_portrait_relight_mode_t; diff --git a/include/android/metadata/system/camera_vendor_tags.h b/include/android/metadata/system/camera_vendor_tags.h index 167ff7393a..52d0e9bbc0 100644 --- a/include/android/metadata/system/camera_vendor_tags.h +++ b/include/android/metadata/system/camera_vendor_tags.h @@ -18,9 +18,9 @@ #ifndef SYSTEM_MEDIA_INCLUDE_ANDROID_CAMERA_VENDOR_TAGS_H #define SYSTEM_MEDIA_INCLUDE_ANDROID_CAMERA_VENDOR_TAGS_H -#ifdef __cplusplus -extern "C" { -#endif +#include + +__BEGIN_DECLS #define CAMERA_METADATA_VENDOR_TAG_BOUNDARY 0x80000000u #define CAMERA_METADATA_INVALID_VENDOR_ID UINT64_MAX @@ -151,9 +151,7 @@ struct vendor_tag_cache_ops { void* reserved[8]; }; -#ifdef __cplusplus -} /* extern "C" */ -#endif +__END_DECLS #endif /* SYSTEM_MEDIA_INCLUDE_ANDROID_CAMERA_VENDOR_TAGS_H */ diff --git a/include/android/system/core/include/android/log.h b/include/android/system/core/include/android/log.h index dbad9dd18a..b5d725c7db 100644 --- a/include/android/system/core/include/android/log.h +++ b/include/android/system/core/include/android/log.h @@ -15,29 +15,18 @@ * limitations under the License. */ -#ifndef _ANDROID_LOG_H -#define _ANDROID_LOG_H +#pragma once -/****************************************************************** - * - * IMPORTANT NOTICE: - * - * This file is part of Android's set of stable system headers - * exposed by the Android NDK (Native Development Kit) since - * platform release 1.5 - * - * Third-party source AND binary code relies on the definitions - * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES. - * - * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES) - * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS - * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY - * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES +/** + * @addtogroup Logging + * @{ */ -/* - * Support routines to send messages to the Android in-kernel log buffer, - * which can later be accessed through the 'logcat' utility. +/** + * \file + * + * Support routines to send messages to the Android log buffer, + * which can later be accessed through the `logcat` utility. * * Each log message must have * - a priority @@ -48,98 +37,393 @@ * and should be reasonably small. * * Log message text may be truncated to less than an implementation-specific - * limit (e.g. 1023 characters max). + * limit (1023 bytes). * * Note that a newline character ("\n") will be appended automatically to your - * log message, if not already there. It is not possible to send several messages - * and have them appear on a single line in logcat. + * log message, if not already there. It is not possible to send several + * messages and have them appear on a single line in logcat. * - * PLEASE USE LOGS WITH MODERATION: + * Please use logging in moderation: * * - Sending log messages eats CPU and slow down your application and the * system. * - * - The circular log buffer is pretty small (<64KB), sending many messages - * might push off other important log messages from the rest of the system. + * - The circular log buffer is pretty small, so sending many messages + * will hide other important log messages. * * - In release builds, only send log messages to account for exceptional * conditions. - * - * NOTE: These functions MUST be implemented by /system/lib/liblog.so */ #include +#include +#include +#include +#include +#include + +#if !defined(__BIONIC__) && !defined(__INTRODUCED_IN) +#define __INTRODUCED_IN(x) +#endif #ifdef __cplusplus extern "C" { #endif -/* - * Android log priority values, in ascending priority order. +/** + * Android log priority values, in increasing order of priority. */ typedef enum android_LogPriority { - ANDROID_LOG_UNKNOWN = 0, - ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ - ANDROID_LOG_VERBOSE, - ANDROID_LOG_DEBUG, - ANDROID_LOG_INFO, - ANDROID_LOG_WARN, - ANDROID_LOG_ERROR, - ANDROID_LOG_FATAL, - ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ + /** For internal use only. */ + ANDROID_LOG_UNKNOWN = 0, + /** The default priority, for internal use only. */ + ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ + /** Verbose logging. Should typically be disabled for a release apk. */ + ANDROID_LOG_VERBOSE, + /** Debug logging. Should typically be disabled for a release apk. */ + ANDROID_LOG_DEBUG, + /** Informational logging. Should typically be disabled for a release apk. */ + ANDROID_LOG_INFO, + /** Warning logging. For use with recoverable failures. */ + ANDROID_LOG_WARN, + /** Error logging. For use with unrecoverable failures. */ + ANDROID_LOG_ERROR, + /** Fatal logging. For use when aborting. */ + ANDROID_LOG_FATAL, + /** For internal use only. */ + ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ } android_LogPriority; -/* - * Send a simple string to the log. +/** + * Identifies a specific log buffer for __android_log_buf_write() + * and __android_log_buf_print(). */ -int __android_log_write(int prio, const char *tag, const char *text); +typedef enum log_id { + /** For internal use only. */ + LOG_ID_MIN = 0, -/* - * Send a formatted string to the log, used like printf(fmt,...) - */ -int __android_log_print(int prio, const char *tag, const char *fmt, ...) -#if defined(__GNUC__) -#ifdef __USE_MINGW_ANSI_STDIO -#if __USE_MINGW_ANSI_STDIO - __attribute__ ((format(gnu_printf, 3, 4))) -#else - __attribute__ ((format(printf, 3, 4))) -#endif -#else - __attribute__ ((format(printf, 3, 4))) -#endif -#endif - ; + /** The main log buffer. This is the only log buffer available to apps. */ + LOG_ID_MAIN = 0, + /** The radio log buffer. */ + LOG_ID_RADIO = 1, + /** The event log buffer. */ + LOG_ID_EVENTS = 2, + /** The system log buffer. */ + LOG_ID_SYSTEM = 3, + /** The crash log buffer. */ + LOG_ID_CRASH = 4, + /** The statistics log buffer. */ + LOG_ID_STATS = 5, + /** The security log buffer. */ + LOG_ID_SECURITY = 6, + /** The kernel log buffer. */ + LOG_ID_KERNEL = 7, -/* - * A variant of __android_log_print() that takes a va_list to list - * additional parameters. + /** For internal use only. */ + LOG_ID_MAX, + + /** + * Let the logging library choose the best log target in cases where it's + * unclear. This is useful if you're generic library code that can't know + * which log your caller should use. + */ + LOG_ID_DEFAULT = 0x7FFFFFFF +} log_id_t; + +static inline bool __android_log_id_is_valid(log_id_t log_id) { + return log_id >= LOG_ID_MIN && log_id < LOG_ID_MAX; +} + +/** + * Writes the constant string `text` to the main log buffer, + * with priority `prio` (one of the `android_LogPriority` values) and tag `tag`. + * + * See __android_log_buf_write() to write to a different log buffer. + * + * @return 1 if the message was written to the log, or -EPERM if it was not; see + * __android_log_is_loggable(). */ -int __android_log_vprint(int prio, const char *tag, - const char *fmt, va_list ap); +int __android_log_write(int prio, const char* tag, const char* text); -/* - * Log an assertion failure and abort the process to have a chance - * to inspect it if a debugger is attached. This uses the FATAL priority. - */ -void __android_log_assert(const char *cond, const char *tag, - const char *fmt, ...) -#if defined(__GNUC__) - __attribute__ ((noreturn)) -#ifdef __USE_MINGW_ANSI_STDIO -#if __USE_MINGW_ANSI_STDIO - __attribute__ ((format(gnu_printf, 3, 4))) -#else - __attribute__ ((format(printf, 3, 4))) -#endif -#else - __attribute__ ((format(printf, 3, 4))) -#endif -#endif - ; +/** + * Writes the string `text` to the log buffer `log_id` (one of the `log_id_t` values), + * with priority `prio` (one of the `android_LogPriority` values) and tag `tag`. + * + * Apps should use __android_log_write() instead because LOG_ID_MAIN is the + * only log buffer available to them. + * + * @return 1 if the message was written to the log, or -EPERM if it was not; see + * __android_log_is_loggable(). + */ +int __android_log_buf_write(int log_id, int prio, const char* tag, const char* text); + +/** + * Writes a formatted string to the main log buffer, + * with priority `prio` (one of the `android_LogPriority` values) and tag `tag`. + * + * The details of formatting are the same as for + * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html). + * + * See __android_log_buf_print() to write to a different log buffer. + * + * @return 1 if the message was written to the log, or -EPERM if it was not; see + * __android_log_is_loggable(). + */ +int __android_log_print(int prio, const char* tag, const char* fmt, ...) + __attribute__((__format__(printf, 3, 4))); + +/** + * Writes a formatted string to the log buffer `log_id` (one of the `log_id_t` values), + * with priority `prio` (one of the `android_LogPriority` values) and tag `tag`. + * + * The details of formatting are the same as for + * [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html). + * + * Apps should use __android_log_print() instead because LOG_ID_MAIN is the + * only log buffer available to them. + * + * @return 1 if the message was written to the log, or -EPERM if it was not; see + * __android_log_is_loggable(). + */ +int __android_log_buf_print(int log_id, int prio, const char* tag, const char* fmt, ...) + __attribute__((__format__(printf, 4, 5))); + +/** + * Equivalent to __android_log_print(), but taking a `va_list`. + * (If __android_log_print() is like printf(), this is like vprintf().) + * + * @return 1 if the message was written to the log, or -EPERM if it was not; see + * __android_log_is_loggable(). + */ +int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap) + __attribute__((__format__(printf, 3, 0))); + +/** + * Writes an assertion failure to the main log buffer + * with priority `ANDROID_LOG_FATAL` -- and also to stderr -- before calling + * [abort(3)](http://man7.org/linux/man-pages/man3/abort.3.html). + * + * If `fmt` is non-null, `cond` is unused. If `fmt` is null, the string + * `Assertion failed: %s` is used with `cond` as the string argument. + * If both `fmt` and `cond` are null, a default string is provided. + * + * Most callers should use + * [assert(3)](http://man7.org/linux/man-pages/man3/assert.3.html) from + * `<assert.h>` instead, or the `__assert` and `__assert2` functions + * provided by bionic if more control is needed. They support automatically + * including the source filename and line number more conveniently than this + * function. + */ +void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...) + __attribute__((__noreturn__)) __attribute__((__format__(printf, 3, 4))); + +/** + * Logger data struct used for writing log messages to liblog via __android_log_write_logger_data() + * and sending log messages to user defined loggers specified in __android_log_set_logger(). + */ +struct __android_log_message { + /** Must be set to `sizeof(__android_log_message)` and is used for versioning. */ + size_t struct_size; + + /** {@link log_id_t} values. */ + int32_t buffer_id; + + /** {@link android_LogPriority} values. */ + int32_t priority; + + /** The tag for the log message. */ + const char* tag; + + /** Optional file name, may be set to nullptr. */ + const char* file; + + /** Optional line number, ignore if file is nullptr. */ + uint32_t line; + + /** The log message itself. */ + const char* message; +}; + +/** + * Prototype for the 'logger' function that is called for every log message. + */ +typedef void (*__android_logger_function)(const struct __android_log_message* log_message); + +/** + * Prototype for the 'abort' function that is called when liblog will abort due to + * __android_log_assert() failures. + */ +typedef void (*__android_aborter_function)(const char* abort_message); + +/** + * Writes the log message specified by log_message. log_message includes additional file name and + * line number information that a logger may use. log_message is versioned for backwards + * compatibility. + * This assumes that loggability has already been checked through __android_log_is_loggable(). + * Higher level logging libraries, such as libbase, first check loggability, then format their + * buffers, then pass the message to liblog via this function, and therefore we do not want to + * duplicate the loggability check here. + * + * @param log_message the log message itself, see {@link __android_log_message}. + * + * Available since API level 30. + */ +void __android_log_write_log_message(struct __android_log_message* log_message) __INTRODUCED_IN(30); + +/** + * Sets a user defined logger function. All log messages sent to liblog will be set to the + * function pointer specified by logger for processing. It is not expected that log messages are + * already terminated with a new line. This function should add new lines if required for line + * separation. + * + * @param logger the new function that will handle log messages. + * + * Available since API level 30. + */ +void __android_log_set_logger(__android_logger_function logger) __INTRODUCED_IN(30); + +/** + * Writes the log message to logd. This is an {@link __android_logger_function} and can be provided to + * __android_log_set_logger(). It is the default logger when running liblog on a device. + * + * @param log_message the log message to write, see {@link __android_log_message}. + * + * Available since API level 30. + */ +void __android_log_logd_logger(const struct __android_log_message* log_message) __INTRODUCED_IN(30); + +/** + * Writes the log message to logd using the passed in timestamp. The messages are stored + * in logd in the order received not in order by timestamp. When displaying the log, there is no + * guarantee that messages are in timestamp order and might cause messages with different times to + * be interleaved. Filtering the log using a timestamp will work properly even if out of time + * order messages are present. + * + * @param log_message the log message to write, see {@link __android_log_message}. + * @param timestamp the time to use for this log message. The value is interpreted as a + * CLOCK_REALTIME value. + * + * Available since API level 37. + */ +void __android_log_logd_logger_with_timestamp(const struct __android_log_message* log_message, + const struct timespec* timestamp) __INTRODUCED_IN(37); + +/** + * Writes the log message to stderr. This is an {@link __android_logger_function} and can be provided to + * __android_log_set_logger(). It is the default logger when running liblog on host. + * + * @param log_message the log message to write, see {@link __android_log_message}. + * + * Available since API level 30. + */ +void __android_log_stderr_logger(const struct __android_log_message* log_message) + __INTRODUCED_IN(30); + +/** + * Sets a user defined aborter function that is called for __android_log_assert() failures. This + * user defined aborter function is highly recommended to abort and be noreturn, but is not strictly + * required to. + * + * @param aborter the new aborter function, see {@link __android_aborter_function}. + * + * Available since API level 30. + */ +void __android_log_set_aborter(__android_aborter_function aborter) __INTRODUCED_IN(30); + +/** + * Calls the stored aborter function. This allows for other logging libraries to use the same + * aborter function by calling this function in liblog. + * + * @param abort_message an additional message supplied when aborting, for example this is used to + * call android_set_abort_message() in __android_log_default_aborter(). + * + * Available since API level 30. + */ +void __android_log_call_aborter(const char* abort_message) __INTRODUCED_IN(30); + +/** + * Sets android_set_abort_message() on device then aborts(). This is the default aborter. + * + * @param abort_message an additional message supplied when aborting. This functions calls + * android_set_abort_message() with its contents. + * + * Available since API level 30. + */ +void __android_log_default_aborter(const char* abort_message) __attribute__((noreturn)) +__INTRODUCED_IN(30); + +/** + * Use the per-tag properties "log.tag." along with the minimum priority from + * __android_log_set_minimum_priority() to determine if a log message with a given prio and tag will + * be printed. A non-zero result indicates yes, zero indicates false. + * + * If both a priority for a tag and a minimum priority are set by + * __android_log_set_minimum_priority(), then the lowest of the two values are to determine the + * minimum priority needed to log. If only one is set, then that value is used to determine the + * minimum priority needed. If none are set, then default_priority is used. + * + * @param prio the priority to test, takes {@link android_LogPriority} values. + * @param tag the tag to test. + * @param default_prio the default priority to use if no properties or minimum priority are set. + * @return an integer where 1 indicates that the message is loggable and 0 indicates that it is not. + * + * Available since API level 30. + */ +int __android_log_is_loggable(int prio, const char* tag, int default_prio) __INTRODUCED_IN(30); + +/** + * Use the per-tag properties "log.tag." along with the minimum priority from + * __android_log_set_minimum_priority() to determine if a log message with a given prio and tag will + * be printed. A non-zero result indicates yes, zero indicates false. + * + * If both a priority for a tag and a minimum priority are set by + * __android_log_set_minimum_priority(), then the lowest of the two values are to determine the + * minimum priority needed to log. If only one is set, then that value is used to determine the + * minimum priority needed. If none are set, then default_priority is used. + * + * @param prio the priority to test, takes {@link android_LogPriority} values. + * @param tag the tag to test. + * @param len the length of the tag. + * @param default_prio the default priority to use if no properties or minimum priority are set. + * @return an integer where 1 indicates that the message is loggable and 0 indicates that it is not. + * + * Available since API level 30. + */ +int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio) + __INTRODUCED_IN(30); + +/** + * Sets the minimum priority that will be logged for this process. + * + * @param priority the new minimum priority to set, takes {@link android_LogPriority} values. + * @return the previous set minimum priority, or `ANDROID_LOG_DEFAULT` if none was set. + * + * Available since API level 30. + */ +int32_t __android_log_set_minimum_priority(int32_t priority) __INTRODUCED_IN(30); + +/** + * Gets the minimum priority that will be logged for this process. + * + * @return the current minimum priority, or `ANDROID_LOG_DEFAULT` if none is set. + * + * Available since API level 30. + */ +int32_t __android_log_get_minimum_priority(void) __INTRODUCED_IN(30); + +/** + * Sets the default tag if no tag is provided when writing a log message. Defaults to + * getprogname(). This truncates tag to the maximum log message size, though appropriate tags + * should be much smaller. + * + * @param tag the new log tag. + * + * Available since API level 30. + */ +void __android_log_set_default_tag(const char* tag) __INTRODUCED_IN(30); #ifdef __cplusplus } #endif -#endif /* _ANDROID_LOG_H */ +/** @} */ diff --git a/include/android/system/core/include/cutils/native_handle.h b/include/android/system/core/include/cutils/native_handle.h index dbd37672f0..d6014efd92 100644 --- a/include/android/system/core/include/cutils/native_handle.h +++ b/include/android/system/core/include/cutils/native_handle.h @@ -50,18 +50,28 @@ typedef struct native_handle typedef const native_handle_t* buffer_handle_t; /* - * native_handle_close - * - * closes the file descriptors contained in this native_handle_t - * + * Closes the file descriptors contained in this native_handle_t, which may + * either be untagged or tagged for ownership by this native_handle_t via + * native_handle_set_tag(). Mixing untagged and tagged fds in the same + * native_handle_t is not permitted and triggers an fdsan exception, but + * native_handle_set_fdsan_tag() can be used to bring consistency if this is + * intentional. + * + * If it's known that fds are tagged, prefer native_handle_close_with_tag() for + * better safety. + * * return 0 on success, or a negative error code on failure - * */ int native_handle_close(const native_handle_t* h); /* - * native_handle_init - * + * Equivalent to native_handle_close(), but throws an fdsan exception if the fds + * are untagged. Use if it's known that the fds in this native_handle_t were + * previously tagged via native_handle_set_tag(). + */ +int native_handle_close_with_tag(const native_handle_t* h); + +/* * Initializes a native_handle_t from storage. storage must be declared with * NATIVE_HANDLE_DECLARE_STORAGE. numFds and numInts must not respectively * exceed maxFds and maxInts used to declare the storage. @@ -69,32 +79,42 @@ int native_handle_close(const native_handle_t* h); native_handle_t* native_handle_init(char* storage, int numFds, int numInts); /* - * native_handle_create - * - * creates a native_handle_t and initializes it. must be destroyed with - * native_handle_delete(). - * + * Creates a native_handle_t and initializes it. Must be destroyed with + * native_handle_delete(). Note that numFds must be <= NATIVE_HANDLE_MAX_FDS, + * numInts must be <= NATIVE_HANDLE_MAX_INTS, and both must be >= 0. */ native_handle_t* native_handle_create(int numFds, int numInts); /* - * native_handle_clone - * - * creates a native_handle_t and initializes it from another native_handle_t. + * Updates the fdsan tag for any file descriptors contained in the supplied + * handle to indicate that they are owned by this handle and should only be + * closed via native_handle_close()/native_handle_close_with_tag(). Each fd in + * the handle must have a tag of either 0 (unset) or the tag associated with + * this handle, otherwise an fdsan exception will be triggered. + */ +void native_handle_set_fdsan_tag(const native_handle_t* handle); + +/* + * Clears the fdsan tag for any file descriptors contained in the supplied + * native_handle_t. Use if this native_handle_t is giving up ownership of its + * fds, but the fdsan tags were previously set. Each fd in the handle must have + * a tag of either 0 (unset) or the tag associated with this handle, otherwise + * an fdsan exception will be triggered. + */ +void native_handle_unset_fdsan_tag(const native_handle_t* handle); + +/* + * Creates a native_handle_t and initializes it from another native_handle_t. * Must be destroyed with native_handle_delete(). - * */ native_handle_t* native_handle_clone(const native_handle_t* handle); /* - * native_handle_delete - * - * frees a native_handle_t allocated with native_handle_create(). + * Frees a native_handle_t allocated with native_handle_create(). * This ONLY frees the memory allocated for the native_handle_t, but doesn't * close the file descriptors; which can be achieved with native_handle_close(). - * + * * return 0 on success, or a negative error code on failure - * */ int native_handle_delete(native_handle_t* h); diff --git a/include/android/system/core/include/system/camera.h b/include/android/system/core/include/system/camera.h index 9d69588f98..b625aada70 100644 --- a/include/android/system/core/include/system/camera.h +++ b/include/android/system/core/include/system/camera.h @@ -159,8 +159,8 @@ enum { * * When any camera method returns error, the client can use ping command * to see if the camera has been taken away by other clients. If the result - * is NO_ERROR, it means the camera hardware is not released. If the result - * is not NO_ERROR, the camera has been released and the existing client + * is OK, it means the camera hardware is not released. If the result + * is not OK, the camera has been released and the existing client * can silently finish itself or show a dialog. */ CAMERA_CMD_PING = 9, diff --git a/include/android/system/core/include/system/graphics-base-v1.2.h b/include/android/system/core/include/system/graphics-base-v1.2.h new file mode 100644 index 0000000000..372284ad73 --- /dev/null +++ b/include/android/system/core/include/system/graphics-base-v1.2.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +// This file is autogenerated by hidl-gen. Do not edit manually. +// Source: android.hardware.graphics.common@1.2 +// Location: hardware/interfaces/graphics/common/1.2/ + +#ifndef HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_ +#define HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + HAL_HDR_HDR10_PLUS = 4, +} android_hdr_v1_2_t; + +typedef enum { + HAL_DATASPACE_DISPLAY_BT2020 = 142999552 /* STANDARD_BT2020 | TRANSFER_SRGB | RANGE_FULL */, + HAL_DATASPACE_DYNAMIC_DEPTH = 4098 /* 0x1002 */, + HAL_DATASPACE_JPEG_APP_SEGMENTS = 4099 /* 0x1003 */, + HAL_DATASPACE_HEIF = 4100 /* 0x1004 */, +} android_dataspace_v1_2_t; + +typedef enum { + HAL_COLOR_MODE_DISPLAY_BT2020 = 13, +} android_color_mode_v1_2_t; + +typedef enum { + HAL_PIXEL_FORMAT_HSV_888 = 55 /* 0x37 */, +} android_pixel_format_v1_2_t; + +#ifdef __cplusplus +} +#endif + +#endif // HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_ diff --git a/include/android/system/core/include/system/graphics-base.h b/include/android/system/core/include/system/graphics-base.h index d01e9874f9..3db0bbc526 100644 --- a/include/android/system/core/include/system/graphics-base.h +++ b/include/android/system/core/include/system/graphics-base.h @@ -4,5 +4,6 @@ #include "graphics-base-v1.0.h" #include "graphics-base-v1.1.h" +#include "graphics-base-v1.2.h" #endif // SYSTEM_CORE_GRAPHICS_BASE_H_ diff --git a/include/android/system/core/include/system/graphics.h b/include/android/system/core/include/system/graphics.h index 6341e642d5..34159e127a 100644 --- a/include/android/system/core/include/system/graphics.h +++ b/include/android/system/core/include/system/graphics.h @@ -60,12 +60,14 @@ typedef android_hdr_t android_hdr; /* * Structure for describing YCbCr formats for consumption by applications. - * This is used with HAL_PIXEL_FORMAT_YCbCr_*_888. + * This is used with HAL_PIXEL_FORMAT_YCbCr_*. * * Buffer chroma subsampling is defined in the format. * e.g. HAL_PIXEL_FORMAT_YCbCr_420_888 has subsampling 4:2:0. * - * Buffers must have a 8 bit depth. + * Buffers must have a byte aligned channel depth or a byte aligned packed + * channel depth (e.g. 10 bits packed into 16 bits for + * HAL_PIXEL_FORMAT_YCbCr_P010). * * y, cb, and cr point to the first byte of their respective planes. * @@ -76,8 +78,8 @@ typedef android_hdr_t android_hdr; * cstride is the stride of the chroma planes. * * chroma_step is the distance in bytes from one chroma pixel value to the - * next. This is 2 bytes for semiplanar (because chroma values are interleaved - * and each chroma value is one byte) and 1 for planar. + * next. This is `2 * channel depth` bytes for semiplanar (because chroma + * values are interleaved) and `1 * channel depth` bytes for planar. */ struct android_ycbcr { diff --git a/src/android/camera3_hal.cpp b/src/android/camera3_hal.cpp index a5ad2374a9..ce313ebace 100644 --- a/src/android/camera3_hal.cpp +++ b/src/android/camera3_hal.cpp @@ -112,5 +112,8 @@ camera_module_t HAL_MODULE_INFO_SYM = { .open_legacy = hal_open_legacy, .set_torch_mode = hal_set_torch_mode, .init = hal_init, + .get_physical_camera_info = nullptr, + .is_stream_combination_supported = nullptr, + .notify_device_state_change = nullptr, .reserved = {}, }; diff --git a/src/android/camera_ops.cpp b/src/android/camera_ops.cpp index ecaac5a31c..1656fac7ab 100644 --- a/src/android/camera_ops.cpp +++ b/src/android/camera_ops.cpp @@ -99,5 +99,7 @@ camera3_device_ops hal_dev_ops = { .get_metadata_vendor_tag_ops = nullptr, .dump = hal_dev_dump, .flush = hal_dev_flush, - .reserved = { nullptr }, + .signal_stream_flush = nullptr, + .is_reconfiguration_required = nullptr, + .reserved = {}, }; diff --git a/src/android/metadata/camera_metadata.c b/src/android/metadata/camera_metadata.c index b86586a7e6..fc695bcadd 100644 --- a/src/android/metadata/camera_metadata.c +++ b/src/android/metadata/camera_metadata.c @@ -103,10 +103,10 @@ struct camera_metadata { uint32_t version; uint32_t flags; metadata_size_t entry_count; - metadata_size_t entry_capacity; + metadata_size_t entry_capacity; // Number of entries that can be stored metadata_uptrdiff_t entries_start; // Offset from camera_metadata metadata_size_t data_count; - metadata_size_t data_capacity; + metadata_size_t data_capacity; // Number of data bytes that can be stored metadata_uptrdiff_t data_start; // Offset from camera_metadata uint32_t padding; // padding to 8 bytes boundary metadata_vendor_id_t vendor_id; @@ -241,7 +241,7 @@ camera_metadata_t *allocate_copy_camera_metadata_checked( return NULL; } - void *buffer = malloc(src_size); + void *buffer = calloc(1, src_size); memcpy(buffer, src, src_size); camera_metadata_t *metadata = (camera_metadata_t*) buffer; @@ -258,7 +258,7 @@ camera_metadata_t *allocate_camera_metadata(size_t entry_capacity, size_t memory_needed = calculate_camera_metadata_size(entry_capacity, data_capacity); - void *buffer = malloc(memory_needed); + void *buffer = calloc(1, memory_needed); camera_metadata_t *metadata = place_camera_metadata( buffer, memory_needed, entry_capacity, data_capacity); if (!metadata) { @@ -278,7 +278,11 @@ camera_metadata_t *place_camera_metadata(void *dst, size_t memory_needed = calculate_camera_metadata_size(entry_capacity, data_capacity); - if (memory_needed > dst_size) return NULL; + if (memory_needed > dst_size) { + ALOGE("%s: Memory needed to place camera metadata (%zu) > dst size (%zu)", __FUNCTION__, + memory_needed, dst_size); + return NULL; + } camera_metadata_t *metadata = (camera_metadata_t*)dst; metadata->version = CURRENT_METADATA_VERSION; @@ -350,7 +354,11 @@ camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size, size_t memory_needed = get_camera_metadata_compact_size(src); if (dst == NULL) return NULL; - if (dst_size < memory_needed) return NULL; + if (dst_size < memory_needed) { + ALOGE("%s: Memory needed to place camera metadata (%zu) > dst size (%zu)", __FUNCTION__, + memory_needed, dst_size); + return NULL; + } camera_metadata_t *metadata = place_camera_metadata(dst, dst_size, src->entry_count, src->data_count); @@ -433,14 +441,14 @@ int validate_camera_metadata_structure(const camera_metadata_t *metadata, }; for (size_t i = 0; i < sizeof(alignments)/sizeof(alignments[0]); ++i) { - uintptr_t aligned_ptr = ALIGN_TO((uintptr_t) metadata + alignmentOffset, + uintptr_t aligned_ptr_section = ALIGN_TO((uintptr_t) metadata + alignmentOffset, alignments[i].alignment); - if ((uintptr_t)metadata + alignmentOffset != aligned_ptr) { + if ((uintptr_t)metadata + alignmentOffset != aligned_ptr_section) { ALOGE("%s: Metadata pointer is not aligned (actual %p, " "expected %p, offset %" PRIuPTR ") to type %s", __FUNCTION__, metadata, - (void*)aligned_ptr, alignmentOffset, alignments[i].name); + (void*)aligned_ptr_section, alignmentOffset, alignments[i].name); return CAMERA_METADATA_VALIDATION_ERROR; } } @@ -449,56 +457,86 @@ int validate_camera_metadata_structure(const camera_metadata_t *metadata, /** * Check that the metadata contents are correct */ + if (expected_size != NULL && sizeof(camera_metadata_t) > *expected_size) { + ALOGE("%s: Metadata size (%zu) should be <= expected size (%zu)", + __FUNCTION__, sizeof(camera_metadata_t), *expected_size); + return CAMERA_METADATA_VALIDATION_ERROR; + } + + // Create an aligned header + camera_metadata_t headerCopy; + const camera_metadata_t *header; + if (alignmentOffset != 0) { + memcpy(&headerCopy, metadata, sizeof(camera_metadata_t)); + header = &headerCopy; + } else { + header = metadata; + } - if (expected_size != NULL && metadata->size > *expected_size) { + if (expected_size != NULL && header->size > *expected_size) { ALOGE("%s: Metadata size (%" PRIu32 ") should be <= expected size (%zu)", - __FUNCTION__, metadata->size, *expected_size); + __FUNCTION__, header->size, *expected_size); return CAMERA_METADATA_VALIDATION_ERROR; } - if (metadata->entry_count > metadata->entry_capacity) { + if (header->entry_count > header->entry_capacity) { ALOGE("%s: Entry count (%" PRIu32 ") should be <= entry capacity " "(%" PRIu32 ")", - __FUNCTION__, metadata->entry_count, metadata->entry_capacity); + __FUNCTION__, header->entry_count, header->entry_capacity); return CAMERA_METADATA_VALIDATION_ERROR; } - if (metadata->data_count > metadata->data_capacity) { + if (header->data_count > header->data_capacity) { ALOGE("%s: Data count (%" PRIu32 ") should be <= data capacity " "(%" PRIu32 ")", - __FUNCTION__, metadata->data_count, metadata->data_capacity); + __FUNCTION__, header->data_count, header->data_capacity); // android_errorWriteLog(SN_EVENT_LOG_ID, "30591838"); return CAMERA_METADATA_VALIDATION_ERROR; } + // Check for overflow when calculating entry capacity bytes. + // (metadata_size_t)~0 represents the maximum representable value of metadata_size_t. + if (header->entry_capacity > (metadata_size_t)~0 / sizeof(camera_metadata_buffer_entry_t)) { + ALOGE("%s: Entry capacity (%" PRIu32 ") is too large", + __FUNCTION__, header->entry_capacity); + return CAMERA_METADATA_VALIDATION_ERROR; + } + + metadata_size_t entries_capacity_bytes = + sizeof(camera_metadata_buffer_entry_t) * header->entry_capacity; const metadata_uptrdiff_t entries_end = - metadata->entries_start + metadata->entry_capacity; - if (entries_end < metadata->entries_start || // overflow check - entries_end > metadata->data_start) { + header->entries_start + entries_capacity_bytes; + + if (entries_end < header->entries_start) { + ALOGE("%s: Entry start (%" PRIu32 ") + capacity bytes (%" PRIu32 ") " + "overflows", __FUNCTION__, header->entries_start, entries_capacity_bytes); + return CAMERA_METADATA_VALIDATION_ERROR; + } + if (entries_end > header->data_start) { ALOGE("%s: Entry start + capacity (%" PRIu32 ") should be <= data start " "(%" PRIu32 ")", __FUNCTION__, - (metadata->entries_start + metadata->entry_capacity), - metadata->data_start); + entries_end, + header->data_start); return CAMERA_METADATA_VALIDATION_ERROR; } const metadata_uptrdiff_t data_end = - metadata->data_start + metadata->data_capacity; - if (data_end < metadata->data_start || // overflow check - data_end > metadata->size) { + header->data_start + header->data_capacity; + if (data_end < header->data_start || // overflow check + data_end > header->size) { ALOGE("%s: Data start + capacity (%" PRIu32 ") should be <= total size " "(%" PRIu32 ")", __FUNCTION__, - (metadata->data_start + metadata->data_capacity), - metadata->size); + (header->data_start + header->data_capacity), + header->size); return CAMERA_METADATA_VALIDATION_ERROR; } // Validate each entry - const metadata_size_t entry_count = metadata->entry_count; + const metadata_size_t entry_count = header->entry_count; camera_metadata_buffer_entry_t *entries = get_entries(metadata); for (size_t i = 0; i < entry_count; ++i) { @@ -511,7 +549,12 @@ int validate_camera_metadata_structure(const camera_metadata_t *metadata, return CAMERA_METADATA_VALIDATION_ERROR; } - camera_metadata_buffer_entry_t entry = entries[i]; + camera_metadata_buffer_entry_t entry; + if (alignmentOffset != 0) { + memcpy(&entry, entries + i, sizeof(camera_metadata_buffer_entry_t)); + } else { + entry = entries[i]; + } if (entry.type >= NUM_TYPES) { ALOGE("%s: Entry index %zu had a bad type %d", @@ -522,10 +565,10 @@ int validate_camera_metadata_structure(const camera_metadata_t *metadata, // TODO: fix vendor_tag_ops across processes so we don't need to special // case vendor-specific tags uint32_t tag_section = entry.tag >> 16; - int tag_type = get_local_camera_metadata_tag_type(entry.tag, metadata); + int tag_type = get_local_camera_metadata_tag_type(entry.tag, header); if (tag_type != (int)entry.type && tag_section < VENDOR_SECTION) { - ALOGE("%s: Entry index %zu had tag type %d, but the type was %d", - __FUNCTION__, i, tag_type, entry.type); + ALOGE("%s: Entry index %zu (0x%x) had tag type %d, but the type was %d", + __FUNCTION__, i, entry.tag, tag_type, entry.type); return CAMERA_METADATA_VALIDATION_ERROR; } @@ -1005,6 +1048,15 @@ int get_local_camera_metadata_tag_type(uint32_t tag, return get_local_camera_metadata_tag_type_vendor_id(tag, id); } +const int32_t *get_camera_metadata_permission_needed(uint32_t *tag_count) { + if (NULL == tag_count) { + return NULL; + } + + *tag_count = sizeof(tag_permission_needed) / sizeof(tag_permission_needed[0]); + return tag_permission_needed; +} + int set_camera_metadata_vendor_tag_ops(const vendor_tag_query_ops_t* ops) { // **DEPRECATED** (void) ops; @@ -1046,8 +1098,7 @@ metadata_vendor_id_t get_camera_metadata_vendor_id( } static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, int type, - int count, - int indentation); + metadata_vendor_id_t vendor_id, int count, int indentation); void dump_camera_metadata(const camera_metadata_t *metadata, int fd, @@ -1120,12 +1171,13 @@ void dump_indented_camera_metadata(const camera_metadata_t *metadata, int count = entry->count; if (verbosity < 2 && count > 16) count = 16; - print_data(fd, data_ptr, entry->tag, entry->type, count, indentation); + print_data(fd, data_ptr, entry->tag, entry->type, get_camera_metadata_vendor_id(metadata), + count, indentation); } } -static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, - int type, int count, int indentation) { +static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, int type, + metadata_vendor_id_t vendor_id, int count, int indentation) { static int values_per_line[NUM_TYPES] = { [TYPE_BYTE] = 16, [TYPE_INT32] = 4, @@ -1137,6 +1189,33 @@ static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, size_t type_size = camera_metadata_type_size[type]; char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE]; uint32_t value; + size_t value_offset; + size_t entry_size; + // It is possible that the tag value is only found at specific + // offset. The rest of the data must not be enumerated. + switch (tag) { + case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS: + case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: + case ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS: + case ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS: + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS: + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS: + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: + case ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS: + value_offset = 3 * type_size; + entry_size = 4 * type_size; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS: + value_offset = 4 * type_size; + entry_size = 5 * type_size; + break; + default: + value_offset = 0; + entry_size = 0; + } int lines = count / values_per_line[type]; if (count % values_per_line[type] != 0) lines++; @@ -1158,14 +1237,24 @@ static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, sizeof(value_string_tmp)) == OK) { dprintf(fd, "%s ", value_string_tmp); + } else if (tag == ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS) { + if (value != 0) { + dprintf(fd, "%c ", + *(data_ptr + index)); + } } else { dprintf(fd, "%hhu ", *(data_ptr + index)); } break; case TYPE_INT32: - value = - *(int32_t*)(data_ptr + index); + value = *(int32_t*)(data_ptr + index); + + if ((entry_size > 0) && ((index % entry_size ) != value_offset)) { + dprintf(fd, "%" PRId32 " ", value); + break; + } + if (camera_metadata_enum_snprint(tag, value, value_string_tmp, @@ -1173,8 +1262,24 @@ static void print_data(int fd, const uint8_t *data_ptr, uint32_t tag, == OK) { dprintf(fd, "%s ", value_string_tmp); } else { - dprintf(fd, "%" PRId32 " ", - *(int32_t*)(data_ptr + index)); + dprintf(fd, "%" PRId32 " ", value); + if (tag == ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS || + tag == ANDROID_REQUEST_AVAILABLE_RESULT_KEYS || + tag == ANDROID_REQUEST_AVAILABLE_SESSION_KEYS || + tag == ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS || + tag == ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS) { + const char *camera_metadata_tag_name = + get_camera_metadata_tag_name(value); + if (camera_metadata_tag_name != NULL) { + dprintf(fd, "(%s) ", camera_metadata_tag_name); + } else { + const char *camera_metadata_tag_vendor_id = + get_local_camera_metadata_tag_name_vendor_id(value, vendor_id); + if (camera_metadata_tag_vendor_id != NULL) { + dprintf(fd, "(%s) ", camera_metadata_tag_vendor_id); + } + } + } } break; case TYPE_FLOAT: diff --git a/src/android/metadata/camera_metadata_tag_info.c b/src/android/metadata/camera_metadata_tag_info.c index e1b81f6d15..3db3bb7f55 100644 --- a/src/android/metadata/camera_metadata_tag_info.c +++ b/src/android/metadata/camera_metadata_tag_info.c @@ -61,6 +61,14 @@ const char *camera_metadata_section_names[ANDROID_SECTION_COUNT] = { [ANDROID_LOGICAL_MULTI_CAMERA] = "android.logicalMultiCamera", [ANDROID_DISTORTION_CORRECTION] = "android.distortionCorrection", + [ANDROID_HEIC] = "android.heic", + [ANDROID_HEIC_INFO] = "android.heic.info", + [ANDROID_AUTOMOTIVE] = "android.automotive", + [ANDROID_AUTOMOTIVE_LENS] = "android.automotive.lens", + [ANDROID_EXTENSION] = "android.extension", + [ANDROID_JPEGR] = "android.jpegr", + [ANDROID_SHARED_SESSION] = "android.sharedSession", + [ANDROID_DESKTOP_EFFECTS] = "android.desktopEffects", }; unsigned int camera_metadata_section_bounds[ANDROID_SECTION_COUNT][2] = { @@ -121,6 +129,22 @@ unsigned int camera_metadata_section_bounds[ANDROID_SECTION_COUNT][2] = { [ANDROID_DISTORTION_CORRECTION] = { ANDROID_DISTORTION_CORRECTION_START, ANDROID_DISTORTION_CORRECTION_END }, + [ANDROID_HEIC] = { ANDROID_HEIC_START, + ANDROID_HEIC_END }, + [ANDROID_HEIC_INFO] = { ANDROID_HEIC_INFO_START, + ANDROID_HEIC_INFO_END }, + [ANDROID_AUTOMOTIVE] = { ANDROID_AUTOMOTIVE_START, + ANDROID_AUTOMOTIVE_END }, + [ANDROID_AUTOMOTIVE_LENS] = { ANDROID_AUTOMOTIVE_LENS_START, + ANDROID_AUTOMOTIVE_LENS_END }, + [ANDROID_EXTENSION] = { ANDROID_EXTENSION_START, + ANDROID_EXTENSION_END }, + [ANDROID_JPEGR] = { ANDROID_JPEGR_START, + ANDROID_JPEGR_END }, + [ANDROID_SHARED_SESSION] = { ANDROID_SHARED_SESSION_START, + ANDROID_SHARED_SESSION_END }, + [ANDROID_DESKTOP_EFFECTS] = { ANDROID_DESKTOP_EFFECTS_START, + ANDROID_DESKTOP_EFFECTS_END }, }; static tag_info_t android_color_correction[ANDROID_COLOR_CORRECTION_END - @@ -136,6 +160,14 @@ static tag_info_t android_color_correction[ANDROID_COLOR_CORRECTION_END - { "aberrationMode", TYPE_BYTE }, [ ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES - ANDROID_COLOR_CORRECTION_START ] = { "availableAberrationModes", TYPE_BYTE }, + [ ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE - ANDROID_COLOR_CORRECTION_START ] = + { "colorTemperature", TYPE_INT32 }, + [ ANDROID_COLOR_CORRECTION_COLOR_TINT - ANDROID_COLOR_CORRECTION_START ] = + { "colorTint", TYPE_INT32 }, + [ ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE - ANDROID_COLOR_CORRECTION_START ] = + { "colorTemperatureRange", TYPE_INT32 }, + [ ANDROID_COLOR_CORRECTION_AVAILABLE_MODES - ANDROID_COLOR_CORRECTION_START ] = + { "availableModes", TYPE_BYTE }, }; static tag_info_t android_control[ANDROID_CONTROL_END - @@ -229,6 +261,50 @@ static tag_info_t android_control[ANDROID_CONTROL_END - { "enableZsl", TYPE_BYTE }, [ ANDROID_CONTROL_AF_SCENE_CHANGE - ANDROID_CONTROL_START ] = { "afSceneChange", TYPE_BYTE }, + [ ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES - ANDROID_CONTROL_START ] = + { "availableExtendedSceneModeMaxSizes", + TYPE_INT32 }, + [ ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES - ANDROID_CONTROL_START ] = + { "availableExtendedSceneModeZoomRatioRanges", + TYPE_FLOAT }, + [ ANDROID_CONTROL_EXTENDED_SCENE_MODE - ANDROID_CONTROL_START ] = + { "extendedSceneMode", TYPE_BYTE }, + [ ANDROID_CONTROL_ZOOM_RATIO_RANGE - ANDROID_CONTROL_START ] = + { "zoomRatioRange", TYPE_FLOAT }, + [ ANDROID_CONTROL_ZOOM_RATIO - ANDROID_CONTROL_START ] = + { "zoomRatio", TYPE_FLOAT }, + [ ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION - ANDROID_CONTROL_START ] = + { "availableHighSpeedVideoConfigurationsMaximumResolution", + TYPE_INT32 }, + [ ANDROID_CONTROL_AF_REGIONS_SET - ANDROID_CONTROL_START ] = + { "afRegionsSet", TYPE_BYTE }, + [ ANDROID_CONTROL_AE_REGIONS_SET - ANDROID_CONTROL_START ] = + { "aeRegionsSet", TYPE_BYTE }, + [ ANDROID_CONTROL_AWB_REGIONS_SET - ANDROID_CONTROL_START ] = + { "awbRegionsSet", TYPE_BYTE }, + [ ANDROID_CONTROL_SETTINGS_OVERRIDE - ANDROID_CONTROL_START ] = + { "settingsOverride", TYPE_INT32 }, + [ ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES - ANDROID_CONTROL_START ] = + { "availableSettingsOverrides", TYPE_INT32 }, + [ ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER - ANDROID_CONTROL_START ] = + { "settingsOverridingFrameNumber", TYPE_INT32 }, + [ ANDROID_CONTROL_AUTOFRAMING - ANDROID_CONTROL_START ] = + { "autoframing", TYPE_BYTE }, + [ ANDROID_CONTROL_AUTOFRAMING_AVAILABLE - ANDROID_CONTROL_START ] = + { "autoframingAvailable", TYPE_BYTE }, + [ ANDROID_CONTROL_AUTOFRAMING_STATE - ANDROID_CONTROL_START ] = + { "autoframingState", TYPE_BYTE }, + [ ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE - ANDROID_CONTROL_START ] = + { "lowLightBoostInfoLuminanceRange", + TYPE_FLOAT }, + [ ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE - ANDROID_CONTROL_START ] = + { "lowLightBoostState", TYPE_BYTE }, + [ ANDROID_CONTROL_ZOOM_METHOD - ANDROID_CONTROL_START ] = + { "zoomMethod", TYPE_BYTE }, + [ ANDROID_CONTROL_AE_PRIORITY_MODE - ANDROID_CONTROL_START ] = + { "aePriorityMode", TYPE_BYTE }, + [ ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES - ANDROID_CONTROL_START ] = + { "aeAvailablePriorityModes", TYPE_BYTE }, }; static tag_info_t android_demosaic[ANDROID_DEMOSAIC_END - @@ -261,6 +337,16 @@ static tag_info_t android_flash[ANDROID_FLASH_END - { "maxEnergy", TYPE_BYTE }, [ ANDROID_FLASH_STATE - ANDROID_FLASH_START ] = { "state", TYPE_BYTE }, + [ ANDROID_FLASH_STRENGTH_LEVEL - ANDROID_FLASH_START ] = + { "strengthLevel", TYPE_INT32 }, + [ ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL - ANDROID_FLASH_START ] = + { "singleStrengthMaxLevel", TYPE_INT32 }, + [ ANDROID_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL - ANDROID_FLASH_START ] = + { "singleStrengthDefaultLevel", TYPE_INT32 }, + [ ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL - ANDROID_FLASH_START ] = + { "torchStrengthMaxLevel", TYPE_INT32 }, + [ ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL - ANDROID_FLASH_START ] = + { "torchStrengthDefaultLevel", TYPE_INT32 }, }; static tag_info_t android_flash_info[ANDROID_FLASH_INFO_END - @@ -269,6 +355,10 @@ static tag_info_t android_flash_info[ANDROID_FLASH_INFO_END - { "available", TYPE_BYTE }, [ ANDROID_FLASH_INFO_CHARGE_DURATION - ANDROID_FLASH_INFO_START ] = { "chargeDuration", TYPE_INT64 }, + [ ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL - ANDROID_FLASH_INFO_START ] = + { "strengthMaximumLevel", TYPE_INT32 }, + [ ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL - ANDROID_FLASH_INFO_START ] = + { "strengthDefaultLevel", TYPE_INT32 }, }; static tag_info_t android_hot_pixel[ANDROID_HOT_PIXEL_END - @@ -333,6 +423,11 @@ static tag_info_t android_lens[ANDROID_LENS_END - { "poseReference", TYPE_BYTE }, [ ANDROID_LENS_DISTORTION - ANDROID_LENS_START ] = { "distortion", TYPE_FLOAT }, + [ ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION - ANDROID_LENS_START ] = + { "distortionMaximumResolution", TYPE_FLOAT }, + [ ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION - ANDROID_LENS_START ] = + { "intrinsicCalibrationMaximumResolution", + TYPE_FLOAT }, }; static tag_info_t android_lens_info[ANDROID_LENS_INFO_END - @@ -418,6 +513,18 @@ static tag_info_t android_request[ANDROID_REQUEST_END - [ ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS - ANDROID_REQUEST_START ] = { "availablePhysicalCameraRequestKeys", TYPE_INT32 }, + [ ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION - ANDROID_REQUEST_START ] = + { "characteristicKeysNeedingPermission", + TYPE_INT32 }, + [ ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP - ANDROID_REQUEST_START ] = + { "availableDynamicRangeProfilesMap", + TYPE_INT64 }, + [ ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE - ANDROID_REQUEST_START ] = + { "recommendedTenBitDynamicRangeProfile", + TYPE_INT64 }, + [ ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP - ANDROID_REQUEST_START ] = + { "availableColorSpaceProfilesMap", + TYPE_INT64 }, }; static tag_info_t android_scaler[ANDROID_SCALER_END - @@ -452,6 +559,45 @@ static tag_info_t android_scaler[ANDROID_SCALER_END - { "availableStallDurations", TYPE_INT64 }, [ ANDROID_SCALER_CROPPING_TYPE - ANDROID_SCALER_START ] = { "croppingType", TYPE_BYTE }, + [ ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS - ANDROID_SCALER_START ] = + { "availableRecommendedStreamConfigurations", + TYPE_INT32 }, + [ ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP - ANDROID_SCALER_START ] = + { "availableRecommendedInputOutputFormatsMap", + TYPE_INT32 }, + [ ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES - ANDROID_SCALER_START ] = + { "availableRotateAndCropModes", TYPE_BYTE }, + [ ANDROID_SCALER_ROTATE_AND_CROP - ANDROID_SCALER_START ] = + { "rotateAndCrop", TYPE_BYTE }, + [ ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE - ANDROID_SCALER_START ] = + { "defaultSecureImageSize", TYPE_INT32 }, + [ ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS - ANDROID_SCALER_START ] = + { "physicalCameraMultiResolutionStreamConfigurations", + TYPE_INT32 }, + [ ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION - ANDROID_SCALER_START ] = + { "availableStreamConfigurationsMaximumResolution", + TYPE_INT32 }, + [ ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_SCALER_START ] = + { "availableMinFrameDurationsMaximumResolution", + TYPE_INT64 }, + [ ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_SCALER_START ] = + { "availableStallDurationsMaximumResolution", + TYPE_INT64 }, + [ ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION - ANDROID_SCALER_START ] = + { "availableInputOutputFormatsMapMaximumResolution", + TYPE_INT32 }, + [ ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED - ANDROID_SCALER_START ] = + { "multiResolutionStreamSupported", + TYPE_BYTE }, + [ ANDROID_SCALER_CROP_REGION_SET - ANDROID_SCALER_START ] = + { "cropRegionSet", TYPE_BYTE }, + [ ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES - ANDROID_SCALER_START ] = + { "availableStreamUseCases", TYPE_INT64 }, + [ ANDROID_SCALER_RAW_CROP_REGION - ANDROID_SCALER_START ] = + { "rawCropRegion", TYPE_INT32 }, + [ ANDROID_SCALER_CONCURRENT_MULTI_RESOLUTION_FORMATS - ANDROID_SCALER_START ] = + { "concurrentMultiResolutionFormats", + TYPE_INT32 }, }; static tag_info_t android_sensor[ANDROID_SENSOR_END - @@ -526,6 +672,15 @@ static tag_info_t android_sensor[ANDROID_SENSOR_END - { "dynamicWhiteLevel", TYPE_INT32 }, [ ANDROID_SENSOR_OPAQUE_RAW_SIZE - ANDROID_SENSOR_START ] = { "opaqueRawSize", TYPE_INT32 }, + [ ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION - ANDROID_SENSOR_START ] = + { "opaqueRawSizeMaximumResolution", + TYPE_INT32 }, + [ ANDROID_SENSOR_PIXEL_MODE - ANDROID_SENSOR_START ] = + { "pixelMode", TYPE_BYTE }, + [ ANDROID_SENSOR_RAW_BINNING_FACTOR_USED - ANDROID_SENSOR_START ] = + { "rawBinningFactorUsed", TYPE_BYTE }, + [ ANDROID_SENSOR_READOUT_TIMESTAMP - ANDROID_SENSOR_START ] = + { "readoutTimestamp", TYPE_BYTE }, }; static tag_info_t android_sensor_info[ANDROID_SENSOR_INFO_END - @@ -552,6 +707,17 @@ static tag_info_t android_sensor_info[ANDROID_SENSOR_INFO_END - { "lensShadingApplied", TYPE_BYTE }, [ ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE - ANDROID_SENSOR_INFO_START ] = { "preCorrectionActiveArraySize", TYPE_INT32 }, + [ ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION - ANDROID_SENSOR_INFO_START ] = + { "activeArraySizeMaximumResolution", + TYPE_INT32 }, + [ ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION - ANDROID_SENSOR_INFO_START ] = + { "pixelArraySizeMaximumResolution", + TYPE_INT32 }, + [ ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION - ANDROID_SENSOR_INFO_START ] = + { "preCorrectionActiveArraySizeMaximumResolution", + TYPE_INT32 }, + [ ANDROID_SENSOR_INFO_BINNING_FACTOR - ANDROID_SENSOR_INFO_START ] = + { "binningFactor", TYPE_INT32 }, }; static tag_info_t android_shading[ANDROID_SHADING_END - @@ -609,6 +775,10 @@ static tag_info_t android_statistics[ANDROID_STATISTICS_END - { "oisXShifts", TYPE_FLOAT }, [ ANDROID_STATISTICS_OIS_Y_SHIFTS - ANDROID_STATISTICS_START ] = { "oisYShifts", TYPE_FLOAT }, + [ ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS - ANDROID_STATISTICS_START ] = + { "lensIntrinsicTimestamps", TYPE_INT64 }, + [ ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES - ANDROID_STATISTICS_START ] = + { "lensIntrinsicSamples", TYPE_FLOAT }, }; static tag_info_t android_statistics_info[ANDROID_STATISTICS_INFO_END - @@ -667,6 +837,18 @@ static tag_info_t android_info[ANDROID_INFO_END - { "supportedHardwareLevel", TYPE_BYTE }, [ ANDROID_INFO_VERSION - ANDROID_INFO_START ] = { "version", TYPE_BYTE }, + [ ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION - ANDROID_INFO_START ] = + { "supportedBufferManagementVersion", + TYPE_BYTE }, + [ ANDROID_INFO_DEVICE_STATE_ORIENTATIONS - ANDROID_INFO_START ] = + { "deviceStateOrientations", TYPE_INT64 }, + [ ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION - ANDROID_INFO_START ] = + { "sessionConfigurationQueryVersion", + TYPE_INT32 }, + [ ANDROID_INFO_DEVICE_ID - ANDROID_INFO_START ] = + { "deviceId", TYPE_INT32 }, + [ ANDROID_INFO_DEVICE_TYPE - ANDROID_INFO_START ] = + { "deviceType", TYPE_BYTE }, }; static tag_info_t android_black_level[ANDROID_BLACK_LEVEL_END - @@ -705,6 +887,36 @@ static tag_info_t android_depth[ANDROID_DEPTH_END - { "availableDepthStallDurations", TYPE_INT64 }, [ ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE - ANDROID_DEPTH_START ] = { "depthIsExclusive", TYPE_BYTE }, + [ ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS - ANDROID_DEPTH_START ] = + { "availableRecommendedDepthStreamConfigurations", + TYPE_INT32 }, + [ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS - ANDROID_DEPTH_START ] = + { "availableDynamicDepthStreamConfigurations", + TYPE_INT32 }, + [ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS - ANDROID_DEPTH_START ] = + { "availableDynamicDepthMinFrameDurations", + TYPE_INT64 }, + [ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS - ANDROID_DEPTH_START ] = + { "availableDynamicDepthStallDurations", + TYPE_INT64 }, + [ ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION - ANDROID_DEPTH_START ] = + { "availableDepthStreamConfigurationsMaximumResolution", + TYPE_INT32 }, + [ ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_DEPTH_START ] = + { "availableDepthMinFrameDurationsMaximumResolution", + TYPE_INT64 }, + [ ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_DEPTH_START ] = + { "availableDepthStallDurationsMaximumResolution", + TYPE_INT64 }, + [ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION - ANDROID_DEPTH_START ] = + { "availableDynamicDepthStreamConfigurationsMaximumResolution", + TYPE_INT32 }, + [ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_DEPTH_START ] = + { "availableDynamicDepthMinFrameDurationsMaximumResolution", + TYPE_INT64 }, + [ ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_DEPTH_START ] = + { "availableDynamicDepthStallDurationsMaximumResolution", + TYPE_INT64 }, }; static tag_info_t android_logical_multi_camera[ANDROID_LOGICAL_MULTI_CAMERA_END - @@ -713,6 +925,13 @@ static tag_info_t android_logical_multi_camera[ANDROID_LOGICAL_MULTI_CAMERA_END { "physicalIds", TYPE_BYTE }, [ ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE - ANDROID_LOGICAL_MULTI_CAMERA_START ] = { "sensorSyncType", TYPE_BYTE }, + [ ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID - ANDROID_LOGICAL_MULTI_CAMERA_START ] = + { "activePhysicalId", TYPE_BYTE }, + [ ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION - ANDROID_LOGICAL_MULTI_CAMERA_START ] = + { "activePhysicalSensorCropRegion", + TYPE_INT32 }, + [ ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS - ANDROID_LOGICAL_MULTI_CAMERA_START ] = + { "additionalResults", TYPE_BYTE }, }; static tag_info_t android_distortion_correction[ANDROID_DISTORTION_CORRECTION_END - @@ -723,6 +942,120 @@ static tag_info_t android_distortion_correction[ANDROID_DISTORTION_CORRECTION_EN { "availableModes", TYPE_BYTE }, }; +static tag_info_t android_heic[ANDROID_HEIC_END - + ANDROID_HEIC_START] = { + [ ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS - ANDROID_HEIC_START ] = + { "availableHeicStreamConfigurations", + TYPE_INT32 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS - ANDROID_HEIC_START ] = + { "availableHeicMinFrameDurations", + TYPE_INT64 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS - ANDROID_HEIC_START ] = + { "availableHeicStallDurations", TYPE_INT64 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION - ANDROID_HEIC_START ] = + { "availableHeicStreamConfigurationsMaximumResolution", + TYPE_INT32 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_HEIC_START ] = + { "availableHeicMinFrameDurationsMaximumResolution", + TYPE_INT64 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_HEIC_START ] = + { "availableHeicStallDurationsMaximumResolution", + TYPE_INT64 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS - ANDROID_HEIC_START ] = + { "availableHeicUltraHdrStreamConfigurations", + TYPE_INT32 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS - ANDROID_HEIC_START ] = + { "availableHeicUltraHdrMinFrameDurations", + TYPE_INT64 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS - ANDROID_HEIC_START ] = + { "availableHeicUltraHdrStallDurations", + TYPE_INT64 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION - ANDROID_HEIC_START ] = + { "availableHeicUltraHdrStreamConfigurationsMaximumResolution", + TYPE_INT32 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_HEIC_START ] = + { "availableHeicUltraHdrMinFrameDurationsMaximumResolution", + TYPE_INT64 }, + [ ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_HEIC_START ] = + { "availableHeicUltraHdrStallDurationsMaximumResolution", + TYPE_INT64 }, +}; + +static tag_info_t android_heic_info[ANDROID_HEIC_INFO_END - + ANDROID_HEIC_INFO_START] = { + [ ANDROID_HEIC_INFO_SUPPORTED - ANDROID_HEIC_INFO_START ] = + { "supported", TYPE_BYTE }, + [ ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT - ANDROID_HEIC_INFO_START ] = + { "maxJpegAppSegmentsCount", TYPE_BYTE }, +}; + +static tag_info_t android_automotive[ANDROID_AUTOMOTIVE_END - + ANDROID_AUTOMOTIVE_START] = { + [ ANDROID_AUTOMOTIVE_LOCATION - ANDROID_AUTOMOTIVE_START ] = + { "location", TYPE_BYTE }, +}; + +static tag_info_t android_automotive_lens[ANDROID_AUTOMOTIVE_LENS_END - + ANDROID_AUTOMOTIVE_LENS_START] = { + [ ANDROID_AUTOMOTIVE_LENS_FACING - ANDROID_AUTOMOTIVE_LENS_START ] = + { "facing", TYPE_BYTE }, +}; + +static tag_info_t android_extension[ANDROID_EXTENSION_END - + ANDROID_EXTENSION_START] = { + [ ANDROID_EXTENSION_STRENGTH - ANDROID_EXTENSION_START ] = + { "strength", TYPE_INT32 }, + [ ANDROID_EXTENSION_CURRENT_TYPE - ANDROID_EXTENSION_START ] = + { "currentType", TYPE_INT32 }, + [ ANDROID_EXTENSION_NIGHT_MODE_INDICATOR - ANDROID_EXTENSION_START ] = + { "nightModeIndicator", TYPE_INT32 }, +}; + +static tag_info_t android_jpegr[ANDROID_JPEGR_END - + ANDROID_JPEGR_START] = { + [ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS - ANDROID_JPEGR_START ] = + { "availableJpegRStreamConfigurations", + TYPE_INT32 }, + [ ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS - ANDROID_JPEGR_START ] = + { "availableJpegRMinFrameDurations", + TYPE_INT64 }, + [ ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS - ANDROID_JPEGR_START ] = + { "availableJpegRStallDurations", TYPE_INT64 }, + [ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION - ANDROID_JPEGR_START ] = + { "availableJpegRStreamConfigurationsMaximumResolution", + TYPE_INT32 }, + [ ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_JPEGR_START ] = + { "availableJpegRMinFrameDurationsMaximumResolution", + TYPE_INT64 }, + [ ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION - ANDROID_JPEGR_START ] = + { "availableJpegRStallDurationsMaximumResolution", + TYPE_INT64 }, +}; + +static tag_info_t android_shared_session[ANDROID_SHARED_SESSION_END - + ANDROID_SHARED_SESSION_START] = { + [ ANDROID_SHARED_SESSION_COLOR_SPACE - ANDROID_SHARED_SESSION_START ] = + { "colorSpace", TYPE_INT32 }, + [ ANDROID_SHARED_SESSION_OUTPUT_CONFIGURATIONS - ANDROID_SHARED_SESSION_START ] = + { "outputConfigurations", TYPE_INT64 }, +}; + +static tag_info_t android_desktop_effects[ANDROID_DESKTOP_EFFECTS_END - + ANDROID_DESKTOP_EFFECTS_START] = { + [ ANDROID_DESKTOP_EFFECTS_CAPABILITIES - ANDROID_DESKTOP_EFFECTS_START ] = + { "capabilities", TYPE_BYTE }, + [ ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODES - ANDROID_DESKTOP_EFFECTS_START ] = + { "backgroundBlurModes", TYPE_BYTE }, + [ ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE - ANDROID_DESKTOP_EFFECTS_START ] = + { "backgroundBlurMode", TYPE_BYTE }, + [ ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE - ANDROID_DESKTOP_EFFECTS_START ] = + { "faceRetouchMode", TYPE_BYTE }, + [ ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_STRENGTH - ANDROID_DESKTOP_EFFECTS_START ] = + { "faceRetouchStrength", TYPE_BYTE }, + [ ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE - ANDROID_DESKTOP_EFFECTS_START ] = + { "portraitRelightMode", TYPE_BYTE }, +}; + tag_info_t *tag_info[ANDROID_SECTION_COUNT] = { android_color_correction, @@ -753,6 +1086,35 @@ tag_info_t *tag_info[ANDROID_SECTION_COUNT] = { android_depth, android_logical_multi_camera, android_distortion_correction, + android_heic, + android_heic_info, + android_automotive, + android_automotive_lens, + android_extension, + android_jpegr, + android_shared_session, + android_desktop_effects, +}; + +static int32_t tag_permission_needed[18] = { + ANDROID_LENS_POSE_ROTATION, + ANDROID_LENS_POSE_TRANSLATION, + ANDROID_LENS_INTRINSIC_CALIBRATION, + ANDROID_LENS_RADIAL_DISTORTION, + ANDROID_LENS_POSE_REFERENCE, + ANDROID_LENS_DISTORTION, + ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION, + ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION, + ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, + ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, + ANDROID_SENSOR_REFERENCE_ILLUMINANT1, + ANDROID_SENSOR_REFERENCE_ILLUMINANT2, + ANDROID_SENSOR_CALIBRATION_TRANSFORM1, + ANDROID_SENSOR_CALIBRATION_TRANSFORM2, + ANDROID_SENSOR_COLOR_TRANSFORM1, + ANDROID_SENSOR_COLOR_TRANSFORM2, + ANDROID_SENSOR_FORWARD_MATRIX1, + ANDROID_SENSOR_FORWARD_MATRIX2, }; int camera_metadata_enum_snprint(uint32_t tag, @@ -777,6 +1139,10 @@ int camera_metadata_enum_snprint(uint32_t tag, msg = "HIGH_QUALITY"; ret = 0; break; + case ANDROID_COLOR_CORRECTION_MODE_CCT: + msg = "CCT"; + ret = 0; + break; default: msg = "error: enum value out of range"; } @@ -810,6 +1176,18 @@ int camera_metadata_enum_snprint(uint32_t tag, case ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES: { break; } + case ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE: { + break; + } + case ANDROID_COLOR_CORRECTION_COLOR_TINT: { + break; + } + case ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE: { + break; + } + case ANDROID_COLOR_CORRECTION_AVAILABLE_MODES: { + break; + } case ANDROID_CONTROL_AE_ANTIBANDING_MODE: { switch (value) { @@ -878,6 +1256,10 @@ int camera_metadata_enum_snprint(uint32_t tag, msg = "ON_EXTERNAL_FLASH"; ret = 0; break; + case ANDROID_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY: + msg = "ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY"; + ret = 0; + break; default: msg = "error: enum value out of range"; } @@ -1122,6 +1504,10 @@ int camera_metadata_enum_snprint(uint32_t tag, msg = "OFF_KEEP_STATE"; ret = 0; break; + case ANDROID_CONTROL_MODE_USE_EXTENDED_SCENE_MODE: + msg = "USE_EXTENDED_SCENE_MODE"; + ret = 0; + break; default: msg = "error: enum value out of range"; } @@ -1232,6 +1618,10 @@ int camera_metadata_enum_snprint(uint32_t tag, msg = "ON"; ret = 0; break; + case ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION: + msg = "PREVIEW_STABILIZATION"; + ret = 0; + break; default: msg = "error: enum value out of range"; } @@ -1440,6 +1830,222 @@ int camera_metadata_enum_snprint(uint32_t tag, } break; } + case ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES: { + break; + } + case ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES: { + break; + } + case ANDROID_CONTROL_EXTENDED_SCENE_MODE: { + switch (value) { + case ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED: + msg = "DISABLED"; + ret = 0; + break; + case ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE: + msg = "BOKEH_STILL_CAPTURE"; + ret = 0; + break; + case ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS: + msg = "BOKEH_CONTINUOUS"; + ret = 0; + break; + case ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START: + msg = "VENDOR_START"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_ZOOM_RATIO_RANGE: { + break; + } + case ANDROID_CONTROL_ZOOM_RATIO: { + break; + } + case ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_CONTROL_AF_REGIONS_SET: { + switch (value) { + case ANDROID_CONTROL_AF_REGIONS_SET_FALSE: + msg = "FALSE"; + ret = 0; + break; + case ANDROID_CONTROL_AF_REGIONS_SET_TRUE: + msg = "TRUE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_AE_REGIONS_SET: { + switch (value) { + case ANDROID_CONTROL_AE_REGIONS_SET_FALSE: + msg = "FALSE"; + ret = 0; + break; + case ANDROID_CONTROL_AE_REGIONS_SET_TRUE: + msg = "TRUE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_AWB_REGIONS_SET: { + switch (value) { + case ANDROID_CONTROL_AWB_REGIONS_SET_FALSE: + msg = "FALSE"; + ret = 0; + break; + case ANDROID_CONTROL_AWB_REGIONS_SET_TRUE: + msg = "TRUE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_SETTINGS_OVERRIDE: { + switch (value) { + case ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF: + msg = "OFF"; + ret = 0; + break; + case ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM: + msg = "ZOOM"; + ret = 0; + break; + case ANDROID_CONTROL_SETTINGS_OVERRIDE_VENDOR_START: + msg = "VENDOR_START"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES: { + break; + } + case ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER: { + break; + } + case ANDROID_CONTROL_AUTOFRAMING: { + switch (value) { + case ANDROID_CONTROL_AUTOFRAMING_OFF: + msg = "OFF"; + ret = 0; + break; + case ANDROID_CONTROL_AUTOFRAMING_ON: + msg = "ON"; + ret = 0; + break; + case ANDROID_CONTROL_AUTOFRAMING_AUTO: + msg = "AUTO"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_AUTOFRAMING_AVAILABLE: { + switch (value) { + case ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE: + msg = "FALSE"; + ret = 0; + break; + case ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_TRUE: + msg = "TRUE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_AUTOFRAMING_STATE: { + switch (value) { + case ANDROID_CONTROL_AUTOFRAMING_STATE_INACTIVE: + msg = "INACTIVE"; + ret = 0; + break; + case ANDROID_CONTROL_AUTOFRAMING_STATE_FRAMING: + msg = "FRAMING"; + ret = 0; + break; + case ANDROID_CONTROL_AUTOFRAMING_STATE_CONVERGED: + msg = "CONVERGED"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE: { + break; + } + case ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE: { + switch (value) { + case ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE: + msg = "INACTIVE"; + ret = 0; + break; + case ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE: + msg = "ACTIVE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_ZOOM_METHOD: { + switch (value) { + case ANDROID_CONTROL_ZOOM_METHOD_AUTO: + msg = "AUTO"; + ret = 0; + break; + case ANDROID_CONTROL_ZOOM_METHOD_ZOOM_RATIO: + msg = "ZOOM_RATIO"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_AE_PRIORITY_MODE: { + switch (value) { + case ANDROID_CONTROL_AE_PRIORITY_MODE_OFF: + msg = "OFF"; + ret = 0; + break; + case ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_SENSITIVITY_PRIORITY: + msg = "SENSOR_SENSITIVITY_PRIORITY"; + ret = 0; + break; + case ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_EXPOSURE_TIME_PRIORITY: + msg = "SENSOR_EXPOSURE_TIME_PRIORITY"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES: { + break; + } case ANDROID_DEMOSAIC_MODE: { switch (value) { @@ -1545,6 +2151,21 @@ int camera_metadata_enum_snprint(uint32_t tag, } break; } + case ANDROID_FLASH_STRENGTH_LEVEL: { + break; + } + case ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL: { + break; + } + case ANDROID_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL: { + break; + } + case ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL: { + break; + } + case ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL: { + break; + } case ANDROID_FLASH_INFO_AVAILABLE: { switch (value) { @@ -1564,6 +2185,12 @@ int camera_metadata_enum_snprint(uint32_t tag, case ANDROID_FLASH_INFO_CHARGE_DURATION: { break; } + case ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL: { + break; + } + case ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL: { + break; + } case ANDROID_HOT_PIXEL_MODE: { switch (value) { @@ -1705,6 +2332,14 @@ int camera_metadata_enum_snprint(uint32_t tag, msg = "GYROSCOPE"; ret = 0; break; + case ANDROID_LENS_POSE_REFERENCE_UNDEFINED: + msg = "UNDEFINED"; + ret = 0; + break; + case ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE: + msg = "AUTOMOTIVE"; + ret = 0; + break; default: msg = "error: enum value out of range"; } @@ -1713,6 +2348,12 @@ int camera_metadata_enum_snprint(uint32_t tag, case ANDROID_LENS_DISTORTION: { break; } + case ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION: { + break; + } case ANDROID_LENS_INFO_AVAILABLE_APERTURES: { break; @@ -1931,6 +2572,38 @@ int camera_metadata_enum_snprint(uint32_t tag, msg = "MONOCHROME"; ret = 0; break; + case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA: + msg = "SECURE_IMAGE_DATA"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA: + msg = "SYSTEM_CAMERA"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING: + msg = "OFFLINE_PROCESSING"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR: + msg = "ULTRA_HIGH_RESOLUTION_SENSOR"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING: + msg = "REMOSAIC_REPROCESSING"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT: + msg = "DYNAMIC_RANGE_TEN_BIT"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE: + msg = "STREAM_USE_CASE"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES: + msg = "COLOR_SPACE_PROFILES"; + ret = 0; + break; default: msg = "error: enum value out of range"; } @@ -1951,6 +2624,146 @@ int camera_metadata_enum_snprint(uint32_t tag, case ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS: { break; } + case ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION: { + break; + } + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP: { + switch (value) { + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD: + msg = "STANDARD"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10: + msg = "HLG10"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: + msg = "HDR10"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: + msg = "HDR10_PLUS"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF: + msg = "DOLBY_VISION_10B_HDR_REF"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO: + msg = "DOLBY_VISION_10B_HDR_REF_PO"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM: + msg = "DOLBY_VISION_10B_HDR_OEM"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO: + msg = "DOLBY_VISION_10B_HDR_OEM_PO"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF: + msg = "DOLBY_VISION_8B_HDR_REF"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO: + msg = "DOLBY_VISION_8B_HDR_REF_PO"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM: + msg = "DOLBY_VISION_8B_HDR_OEM"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO: + msg = "DOLBY_VISION_8B_HDR_OEM_PO"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX: + msg = "MAX"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD_SMPTE_2094_50: + msg = "STANDARD_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10_SMPTE_2094_50: + msg = "HLG10_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_SMPTE_2094_50: + msg = "HDR10_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS_SMPTE_2094_50: + msg = "HDR10_PLUS_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_SMPTE_2094_50: + msg = "DOLBY_VISION_10B_HDR_REF_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO_SMPTE_2094_50: + msg = "DOLBY_VISION_10B_HDR_REF_PO_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_SMPTE_2094_50: + msg = "DOLBY_VISION_10B_HDR_OEM_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO_SMPTE_2094_50: + msg = "DOLBY_VISION_10B_HDR_OEM_PO_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_SMPTE_2094_50: + msg = "DOLBY_VISION_8B_HDR_REF_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO_SMPTE_2094_50: + msg = "DOLBY_VISION_8B_HDR_REF_PO_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_SMPTE_2094_50: + msg = "DOLBY_VISION_8B_HDR_OEM_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO_SMPTE_2094_50: + msg = "DOLBY_VISION_8B_HDR_OEM_PO_SMPTE_2094_50"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX_312: + msg = "MAX_312"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE: { + break; + } + case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP: { + switch (value) { + case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED: + msg = "UNSPECIFIED"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB: + msg = "SRGB"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3: + msg = "DISPLAY_P3"; + ret = 0; + break; + case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG: + msg = "BT2020_HLG"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } case ANDROID_SCALER_CROP_REGION: { break; @@ -1985,6 +2798,22 @@ int camera_metadata_enum_snprint(uint32_t tag, msg = "BLOB"; ret = 0; break; + case ANDROID_SCALER_AVAILABLE_FORMATS_RAW10: + msg = "RAW10"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_FORMATS_RAW12: + msg = "RAW12"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_FORMATS_RAW14: + msg = "RAW14"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_FORMATS_Y8: + msg = "Y8"; + ret = 0; + break; default: msg = "error: enum value out of range"; } @@ -2050,6 +2879,207 @@ int camera_metadata_enum_snprint(uint32_t tag, } break; } + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS: { + switch (value) { + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW: + msg = "PREVIEW"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD: + msg = "RECORD"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT: + msg = "VIDEO_SNAPSHOT"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT: + msg = "SNAPSHOT"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL: + msg = "ZSL"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW: + msg = "RAW"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT: + msg = "LOW_LATENCY_SNAPSHOT"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END: + msg = "PUBLIC_END"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT: + msg = "10BIT_OUTPUT"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8: + msg = "PUBLIC_END_3_8"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START: + msg = "VENDOR_START"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP: { + break; + } + case ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES: { + break; + } + case ANDROID_SCALER_ROTATE_AND_CROP: { + switch (value) { + case ANDROID_SCALER_ROTATE_AND_CROP_NONE: + msg = "NONE"; + ret = 0; + break; + case ANDROID_SCALER_ROTATE_AND_CROP_90: + msg = "90"; + ret = 0; + break; + case ANDROID_SCALER_ROTATE_AND_CROP_180: + msg = "180"; + ret = 0; + break; + case ANDROID_SCALER_ROTATE_AND_CROP_270: + msg = "270"; + ret = 0; + break; + case ANDROID_SCALER_ROTATE_AND_CROP_AUTO: + msg = "AUTO"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE: { + break; + } + case ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS: { + switch (value) { + case ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + switch (value) { + case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED: { + switch (value) { + case ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_FALSE: + msg = "FALSE"; + ret = 0; + break; + case ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE: + msg = "TRUE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SCALER_CROP_REGION_SET: { + switch (value) { + case ANDROID_SCALER_CROP_REGION_SET_FALSE: + msg = "FALSE"; + ret = 0; + break; + case ANDROID_SCALER_CROP_REGION_SET_TRUE: + msg = "TRUE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES: { + switch (value) { + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT: + msg = "DEFAULT"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW: + msg = "PREVIEW"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE: + msg = "STILL_CAPTURE"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD: + msg = "VIDEO_RECORD"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL: + msg = "PREVIEW_VIDEO_STILL"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL: + msg = "VIDEO_CALL"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW: + msg = "CROPPED_RAW"; + ret = 0; + break; + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START: + msg = "VENDOR_START"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SCALER_RAW_CROP_REGION: { + break; + } + case ANDROID_SCALER_CONCURRENT_MULTI_RESOLUTION_FORMATS: { + break; + } case ANDROID_SENSOR_EXPOSURE_TIME: { break; @@ -2225,6 +3255,10 @@ int camera_metadata_enum_snprint(uint32_t tag, msg = "PN9"; ret = 0; break; + case ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK: + msg = "BLACK"; + ret = 0; + break; case ANDROID_SENSOR_TEST_PATTERN_MODE_CUSTOM1: msg = "CUSTOM1"; ret = 0; @@ -2252,16 +3286,64 @@ int camera_metadata_enum_snprint(uint32_t tag, case ANDROID_SENSOR_OPAQUE_RAW_SIZE: { break; } - - case ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE: { - break; - } - case ANDROID_SENSOR_INFO_SENSITIVITY_RANGE: { + case ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION: { break; } - case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT: { + case ANDROID_SENSOR_PIXEL_MODE: { switch (value) { - case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB: + case ANDROID_SENSOR_PIXEL_MODE_DEFAULT: + msg = "DEFAULT"; + ret = 0; + break; + case ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION: + msg = "MAXIMUM_RESOLUTION"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SENSOR_RAW_BINNING_FACTOR_USED: { + switch (value) { + case ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_TRUE: + msg = "TRUE"; + ret = 0; + break; + case ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_FALSE: + msg = "FALSE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SENSOR_READOUT_TIMESTAMP: { + switch (value) { + case ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED: + msg = "NOT_SUPPORTED"; + ret = 0; + break; + case ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE: + msg = "HARDWARE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + + case ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE: { + break; + } + case ANDROID_SENSOR_INFO_SENSITIVITY_RANGE: { + break; + } + case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT: { + switch (value) { + case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB: msg = "RGGB"; ret = 0; break; @@ -2281,6 +3363,14 @@ int camera_metadata_enum_snprint(uint32_t tag, msg = "RGB"; ret = 0; break; + case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO: + msg = "MONO"; + ret = 0; + break; + case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR: + msg = "NIR"; + ret = 0; + break; default: msg = "error: enum value out of range"; } @@ -2334,6 +3424,18 @@ int camera_metadata_enum_snprint(uint32_t tag, case ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE: { break; } + case ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SENSOR_INFO_BINNING_FACTOR: { + break; + } case ANDROID_SHADING_MODE: { switch (value) { @@ -2516,6 +3618,12 @@ int camera_metadata_enum_snprint(uint32_t tag, case ANDROID_STATISTICS_OIS_Y_SHIFTS: { break; } + case ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS: { + break; + } + case ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES: { + break; + } case ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES: { break; @@ -2663,6 +3771,69 @@ int camera_metadata_enum_snprint(uint32_t tag, case ANDROID_INFO_VERSION: { break; } + case ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION: { + switch (value) { + case ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5: + msg = "HIDL_DEVICE_3_5"; + ret = 0; + break; + case ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE: + msg = "SESSION_CONFIGURABLE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_INFO_DEVICE_STATE_ORIENTATIONS: { + break; + } + case ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION: { + switch (value) { + case ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_UPSIDE_DOWN_CAKE: + msg = "UPSIDE_DOWN_CAKE"; + ret = 0; + break; + case ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_VANILLA_ICE_CREAM: + msg = "VANILLA_ICE_CREAM"; + ret = 0; + break; + case ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_BAKLAVA: + msg = "BAKLAVA"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_INFO_DEVICE_ID: { + break; + } + case ANDROID_INFO_DEVICE_TYPE: { + switch (value) { + case ANDROID_INFO_DEVICE_TYPE_BUILT_IN: + msg = "BUILT_IN"; + ret = 0; + break; + case ANDROID_INFO_DEVICE_TYPE_EXTERNAL: + msg = "EXTERNAL"; + ret = 0; + break; + case ANDROID_INFO_DEVICE_TYPE_VIRTUAL: + msg = "VIRTUAL"; + ret = 0; + break; + case ANDROID_INFO_DEVICE_TYPE_UNKNOWN: + msg = "UNKNOWN"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } case ANDROID_BLACK_LEVEL_LOCK: { switch (value) { @@ -2757,6 +3928,72 @@ int camera_metadata_enum_snprint(uint32_t tag, } break; } + case ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS: { + switch (value) { + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + switch (value) { + case ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + switch (value) { + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } case ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS: { break; @@ -2776,6 +4013,27 @@ int camera_metadata_enum_snprint(uint32_t tag, } break; } + case ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID: { + break; + } + case ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION: { + break; + } + case ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS: { + switch (value) { + case ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS_OFF: + msg = "OFF"; + ret = 0; + break; + case ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS_ON: + msg = "ON"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } case ANDROID_DISTORTION_CORRECTION_MODE: { switch (value) { @@ -2800,13 +4058,4211 @@ int camera_metadata_enum_snprint(uint32_t tag, break; } - } + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS: { + switch (value) { + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + switch (value) { + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS: { + switch (value) { + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + switch (value) { + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } - strncpy(dst, msg, size - 1); - dst[size - 1] = '\0'; + case ANDROID_HEIC_INFO_SUPPORTED: { + switch (value) { + case ANDROID_HEIC_INFO_SUPPORTED_FALSE: + msg = "FALSE"; + ret = 0; + break; + case ANDROID_HEIC_INFO_SUPPORTED_TRUE: + msg = "TRUE"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT: { + break; + } + + case ANDROID_AUTOMOTIVE_LOCATION: { + switch (value) { + case ANDROID_AUTOMOTIVE_LOCATION_INTERIOR: + msg = "INTERIOR"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER: + msg = "EXTERIOR_OTHER"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT: + msg = "EXTERIOR_FRONT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR: + msg = "EXTERIOR_REAR"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT: + msg = "EXTERIOR_LEFT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT: + msg = "EXTERIOR_RIGHT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER: + msg = "EXTRA_OTHER"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT: + msg = "EXTRA_FRONT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR: + msg = "EXTRA_REAR"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT: + msg = "EXTRA_LEFT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT: + msg = "EXTRA_RIGHT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + + case ANDROID_AUTOMOTIVE_LENS_FACING: { + switch (value) { + case ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER: + msg = "EXTERIOR_OTHER"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT: + msg = "EXTERIOR_FRONT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR: + msg = "EXTERIOR_REAR"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT: + msg = "EXTERIOR_LEFT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT: + msg = "EXTERIOR_RIGHT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER: + msg = "INTERIOR_OTHER"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT: + msg = "INTERIOR_SEAT_ROW_1_LEFT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER: + msg = "INTERIOR_SEAT_ROW_1_CENTER"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT: + msg = "INTERIOR_SEAT_ROW_1_RIGHT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT: + msg = "INTERIOR_SEAT_ROW_2_LEFT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER: + msg = "INTERIOR_SEAT_ROW_2_CENTER"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT: + msg = "INTERIOR_SEAT_ROW_2_RIGHT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT: + msg = "INTERIOR_SEAT_ROW_3_LEFT"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER: + msg = "INTERIOR_SEAT_ROW_3_CENTER"; + ret = 0; + break; + case ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT: + msg = "INTERIOR_SEAT_ROW_3_RIGHT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + + case ANDROID_EXTENSION_STRENGTH: { + break; + } + case ANDROID_EXTENSION_CURRENT_TYPE: { + break; + } + case ANDROID_EXTENSION_NIGHT_MODE_INDICATOR: { + switch (value) { + case ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_UNKNOWN: + msg = "UNKNOWN"; + ret = 0; + break; + case ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_OFF: + msg = "OFF"; + ret = 0; + break; + case ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_ON: + msg = "ON"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS: { + switch (value) { + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS: { + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + switch (value) { + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT: + msg = "OUTPUT"; + ret = 0; + break; + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT: + msg = "INPUT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + + case ANDROID_SHARED_SESSION_COLOR_SPACE: { + switch (value) { + case ANDROID_SHARED_SESSION_COLOR_SPACE_UNSPECIFIED: + msg = "UNSPECIFIED"; + ret = 0; + break; + case ANDROID_SHARED_SESSION_COLOR_SPACE_SRGB: + msg = "SRGB"; + ret = 0; + break; + case ANDROID_SHARED_SESSION_COLOR_SPACE_DISPLAY_P3: + msg = "DISPLAY_P3"; + ret = 0; + break; + case ANDROID_SHARED_SESSION_COLOR_SPACE_BT2020_HLG: + msg = "BT2020_HLG"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_SHARED_SESSION_OUTPUT_CONFIGURATIONS: { + break; + } + + case ANDROID_DESKTOP_EFFECTS_CAPABILITIES: { + switch (value) { + case ANDROID_DESKTOP_EFFECTS_CAPABILITIES_BACKGROUND_BLUR: + msg = "BACKGROUND_BLUR"; + ret = 0; + break; + case ANDROID_DESKTOP_EFFECTS_CAPABILITIES_FACE_RETOUCH: + msg = "FACE_RETOUCH"; + ret = 0; + break; + case ANDROID_DESKTOP_EFFECTS_CAPABILITIES_PORTRAIT_RELIGHT: + msg = "PORTRAIT_RELIGHT"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODES: { + break; + } + case ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE: { + switch (value) { + case ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_OFF: + msg = "OFF"; + ret = 0; + break; + case ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_LIGHT: + msg = "LIGHT"; + ret = 0; + break; + case ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_FULL: + msg = "FULL"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE: { + switch (value) { + case ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_OFF: + msg = "OFF"; + ret = 0; + break; + case ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_ON: + msg = "ON"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + case ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_STRENGTH: { + break; + } + case ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE: { + switch (value) { + case ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_OFF: + msg = "OFF"; + ret = 0; + break; + case ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_ON: + msg = "ON"; + ret = 0; + break; + default: + msg = "error: enum value out of range"; + } + break; + } + + } + + strncpy(dst, msg, size - 1); + dst[size - 1] = '\0'; + + return ret; +} + +int camera_metadata_enum_value(uint32_t tag, + const char *name, + size_t size, + uint32_t *value) { + if ((name == NULL) || (value == NULL)) { + return -1; + } + + const char *enumName = NULL; + int ret = -1; + + switch(tag) { + case ANDROID_COLOR_CORRECTION_MODE: { + enumName = "TRANSFORM_MATRIX"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX; + ret = 0; + break; + } + enumName = "FAST"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_COLOR_CORRECTION_MODE_FAST; + ret = 0; + break; + } + enumName = "HIGH_QUALITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY; + ret = 0; + break; + } + enumName = "CCT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_COLOR_CORRECTION_MODE_CCT; + ret = 0; + break; + } + break; + } + case ANDROID_COLOR_CORRECTION_TRANSFORM: { + break; + } + case ANDROID_COLOR_CORRECTION_GAINS: { + break; + } + case ANDROID_COLOR_CORRECTION_ABERRATION_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF; + ret = 0; + break; + } + enumName = "FAST"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_FAST; + ret = 0; + break; + } + enumName = "HIGH_QUALITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY; + ret = 0; + break; + } + break; + } + case ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES: { + break; + } + case ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE: { + break; + } + case ANDROID_COLOR_CORRECTION_COLOR_TINT: { + break; + } + case ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE: { + break; + } + case ANDROID_COLOR_CORRECTION_AVAILABLE_MODES: { + break; + } + + case ANDROID_CONTROL_AE_ANTIBANDING_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF; + ret = 0; + break; + } + enumName = "50HZ"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ; + ret = 0; + break; + } + enumName = "60HZ"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ; + ret = 0; + break; + } + enumName = "AUTO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION: { + break; + } + case ANDROID_CONTROL_AE_LOCK: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_LOCK_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_LOCK_ON; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AE_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_MODE_ON; + ret = 0; + break; + } + enumName = "ON_AUTO_FLASH"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH; + ret = 0; + break; + } + enumName = "ON_ALWAYS_FLASH"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH; + ret = 0; + break; + } + enumName = "ON_AUTO_FLASH_REDEYE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE; + ret = 0; + break; + } + enumName = "ON_EXTERNAL_FLASH"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH; + ret = 0; + break; + } + enumName = "ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_MODE_ON_LOW_LIGHT_BOOST_BRIGHTNESS_PRIORITY; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AE_REGIONS: { + break; + } + case ANDROID_CONTROL_AE_TARGET_FPS_RANGE: { + break; + } + case ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER: { + enumName = "IDLE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + ret = 0; + break; + } + enumName = "START"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START; + ret = 0; + break; + } + enumName = "CANCEL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AF_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_MODE_OFF; + ret = 0; + break; + } + enumName = "AUTO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_MODE_AUTO; + ret = 0; + break; + } + enumName = "MACRO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_MODE_MACRO; + ret = 0; + break; + } + enumName = "CONTINUOUS_VIDEO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; + ret = 0; + break; + } + enumName = "CONTINUOUS_PICTURE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; + ret = 0; + break; + } + enumName = "EDOF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_MODE_EDOF; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AF_REGIONS: { + break; + } + case ANDROID_CONTROL_AF_TRIGGER: { + enumName = "IDLE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_TRIGGER_IDLE; + ret = 0; + break; + } + enumName = "START"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_TRIGGER_START; + ret = 0; + break; + } + enumName = "CANCEL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_TRIGGER_CANCEL; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AWB_LOCK: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_LOCK_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_LOCK_ON; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AWB_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_MODE_OFF; + ret = 0; + break; + } + enumName = "AUTO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_MODE_AUTO; + ret = 0; + break; + } + enumName = "INCANDESCENT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_MODE_INCANDESCENT; + ret = 0; + break; + } + enumName = "FLUORESCENT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_MODE_FLUORESCENT; + ret = 0; + break; + } + enumName = "WARM_FLUORESCENT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT; + ret = 0; + break; + } + enumName = "DAYLIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_MODE_DAYLIGHT; + ret = 0; + break; + } + enumName = "CLOUDY_DAYLIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT; + ret = 0; + break; + } + enumName = "TWILIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_MODE_TWILIGHT; + ret = 0; + break; + } + enumName = "SHADE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_MODE_SHADE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AWB_REGIONS: { + break; + } + case ANDROID_CONTROL_CAPTURE_INTENT: { + enumName = "CUSTOM"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM; + ret = 0; + break; + } + enumName = "PREVIEW"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; + ret = 0; + break; + } + enumName = "STILL_CAPTURE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; + ret = 0; + break; + } + enumName = "VIDEO_RECORD"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; + ret = 0; + break; + } + enumName = "VIDEO_SNAPSHOT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; + ret = 0; + break; + } + enumName = "ZERO_SHUTTER_LAG"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG; + ret = 0; + break; + } + enumName = "MANUAL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL; + ret = 0; + break; + } + enumName = "MOTION_TRACKING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_CAPTURE_INTENT_MOTION_TRACKING; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_EFFECT_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EFFECT_MODE_OFF; + ret = 0; + break; + } + enumName = "MONO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EFFECT_MODE_MONO; + ret = 0; + break; + } + enumName = "NEGATIVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EFFECT_MODE_NEGATIVE; + ret = 0; + break; + } + enumName = "SOLARIZE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EFFECT_MODE_SOLARIZE; + ret = 0; + break; + } + enumName = "SEPIA"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EFFECT_MODE_SEPIA; + ret = 0; + break; + } + enumName = "POSTERIZE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EFFECT_MODE_POSTERIZE; + ret = 0; + break; + } + enumName = "WHITEBOARD"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD; + ret = 0; + break; + } + enumName = "BLACKBOARD"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD; + ret = 0; + break; + } + enumName = "AQUA"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EFFECT_MODE_AQUA; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_MODE_OFF; + ret = 0; + break; + } + enumName = "AUTO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_MODE_AUTO; + ret = 0; + break; + } + enumName = "USE_SCENE_MODE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_MODE_USE_SCENE_MODE; + ret = 0; + break; + } + enumName = "OFF_KEEP_STATE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_MODE_OFF_KEEP_STATE; + ret = 0; + break; + } + enumName = "USE_EXTENDED_SCENE_MODE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_MODE_USE_EXTENDED_SCENE_MODE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_SCENE_MODE: { + enumName = "DISABLED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_DISABLED; + ret = 0; + break; + } + enumName = "FACE_PRIORITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY; + ret = 0; + break; + } + enumName = "ACTION"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_ACTION; + ret = 0; + break; + } + enumName = "PORTRAIT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_PORTRAIT; + ret = 0; + break; + } + enumName = "LANDSCAPE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_LANDSCAPE; + ret = 0; + break; + } + enumName = "NIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_NIGHT; + ret = 0; + break; + } + enumName = "NIGHT_PORTRAIT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT; + ret = 0; + break; + } + enumName = "THEATRE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_THEATRE; + ret = 0; + break; + } + enumName = "BEACH"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_BEACH; + ret = 0; + break; + } + enumName = "SNOW"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_SNOW; + ret = 0; + break; + } + enumName = "SUNSET"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_SUNSET; + ret = 0; + break; + } + enumName = "STEADYPHOTO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO; + ret = 0; + break; + } + enumName = "FIREWORKS"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_FIREWORKS; + ret = 0; + break; + } + enumName = "SPORTS"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_SPORTS; + ret = 0; + break; + } + enumName = "PARTY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_PARTY; + ret = 0; + break; + } + enumName = "CANDLELIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT; + ret = 0; + break; + } + enumName = "BARCODE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_BARCODE; + ret = 0; + break; + } + enumName = "HIGH_SPEED_VIDEO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO; + ret = 0; + break; + } + enumName = "HDR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_HDR; + ret = 0; + break; + } + enumName = "FACE_PRIORITY_LOW_LIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT; + ret = 0; + break; + } + enumName = "DEVICE_CUSTOM_START"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_DEVICE_CUSTOM_START; + ret = 0; + break; + } + enumName = "DEVICE_CUSTOM_END"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SCENE_MODE_DEVICE_CUSTOM_END; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_VIDEO_STABILIZATION_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_ON; + ret = 0; + break; + } + enumName = "PREVIEW_STABILIZATION"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES: { + break; + } + case ANDROID_CONTROL_AE_AVAILABLE_MODES: { + break; + } + case ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES: { + break; + } + case ANDROID_CONTROL_AE_COMPENSATION_RANGE: { + break; + } + case ANDROID_CONTROL_AE_COMPENSATION_STEP: { + break; + } + case ANDROID_CONTROL_AF_AVAILABLE_MODES: { + break; + } + case ANDROID_CONTROL_AVAILABLE_EFFECTS: { + break; + } + case ANDROID_CONTROL_AVAILABLE_SCENE_MODES: { + break; + } + case ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES: { + break; + } + case ANDROID_CONTROL_AWB_AVAILABLE_MODES: { + break; + } + case ANDROID_CONTROL_MAX_REGIONS: { + break; + } + case ANDROID_CONTROL_SCENE_MODE_OVERRIDES: { + break; + } + case ANDROID_CONTROL_AE_PRECAPTURE_ID: { + break; + } + case ANDROID_CONTROL_AE_STATE: { + enumName = "INACTIVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_STATE_INACTIVE; + ret = 0; + break; + } + enumName = "SEARCHING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_STATE_SEARCHING; + ret = 0; + break; + } + enumName = "CONVERGED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_STATE_CONVERGED; + ret = 0; + break; + } + enumName = "LOCKED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_STATE_LOCKED; + ret = 0; + break; + } + enumName = "FLASH_REQUIRED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_STATE_FLASH_REQUIRED; + ret = 0; + break; + } + enumName = "PRECAPTURE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_STATE_PRECAPTURE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AF_STATE: { + enumName = "INACTIVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_STATE_INACTIVE; + ret = 0; + break; + } + enumName = "PASSIVE_SCAN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN; + ret = 0; + break; + } + enumName = "PASSIVE_FOCUSED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED; + ret = 0; + break; + } + enumName = "ACTIVE_SCAN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; + ret = 0; + break; + } + enumName = "FOCUSED_LOCKED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; + ret = 0; + break; + } + enumName = "NOT_FOCUSED_LOCKED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; + ret = 0; + break; + } + enumName = "PASSIVE_UNFOCUSED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_STATE_PASSIVE_UNFOCUSED; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AF_TRIGGER_ID: { + break; + } + case ANDROID_CONTROL_AWB_STATE: { + enumName = "INACTIVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_STATE_INACTIVE; + ret = 0; + break; + } + enumName = "SEARCHING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_STATE_SEARCHING; + ret = 0; + break; + } + enumName = "CONVERGED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_STATE_CONVERGED; + ret = 0; + break; + } + enumName = "LOCKED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_STATE_LOCKED; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS: { + break; + } + case ANDROID_CONTROL_AE_LOCK_AVAILABLE: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_LOCK_AVAILABLE_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AWB_LOCK_AVAILABLE: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_LOCK_AVAILABLE_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AVAILABLE_MODES: { + break; + } + case ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE: { + break; + } + case ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST: { + break; + } + case ANDROID_CONTROL_ENABLE_ZSL: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_ENABLE_ZSL_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_ENABLE_ZSL_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AF_SCENE_CHANGE: { + enumName = "NOT_DETECTED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_SCENE_CHANGE_NOT_DETECTED; + ret = 0; + break; + } + enumName = "DETECTED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_SCENE_CHANGE_DETECTED; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_MAX_SIZES: { + break; + } + case ANDROID_CONTROL_AVAILABLE_EXTENDED_SCENE_MODE_ZOOM_RATIO_RANGES: { + break; + } + case ANDROID_CONTROL_EXTENDED_SCENE_MODE: { + enumName = "DISABLED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EXTENDED_SCENE_MODE_DISABLED; + ret = 0; + break; + } + enumName = "BOKEH_STILL_CAPTURE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_STILL_CAPTURE; + ret = 0; + break; + } + enumName = "BOKEH_CONTINUOUS"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EXTENDED_SCENE_MODE_BOKEH_CONTINUOUS; + ret = 0; + break; + } + enumName = "VENDOR_START"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_EXTENDED_SCENE_MODE_VENDOR_START; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_ZOOM_RATIO_RANGE: { + break; + } + case ANDROID_CONTROL_ZOOM_RATIO: { + break; + } + case ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_CONTROL_AF_REGIONS_SET: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_REGIONS_SET_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AF_REGIONS_SET_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AE_REGIONS_SET: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_REGIONS_SET_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_REGIONS_SET_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AWB_REGIONS_SET: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_REGIONS_SET_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AWB_REGIONS_SET_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_SETTINGS_OVERRIDE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF; + ret = 0; + break; + } + enumName = "ZOOM"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM; + ret = 0; + break; + } + enumName = "VENDOR_START"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_SETTINGS_OVERRIDE_VENDOR_START; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES: { + break; + } + case ANDROID_CONTROL_SETTINGS_OVERRIDING_FRAME_NUMBER: { + break; + } + case ANDROID_CONTROL_AUTOFRAMING: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AUTOFRAMING_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AUTOFRAMING_ON; + ret = 0; + break; + } + enumName = "AUTO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AUTOFRAMING_AUTO; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AUTOFRAMING_AVAILABLE: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AUTOFRAMING_STATE: { + enumName = "INACTIVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AUTOFRAMING_STATE_INACTIVE; + ret = 0; + break; + } + enumName = "FRAMING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AUTOFRAMING_STATE_FRAMING; + ret = 0; + break; + } + enumName = "CONVERGED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AUTOFRAMING_STATE_CONVERGED; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE: { + break; + } + case ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE: { + enumName = "INACTIVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_INACTIVE; + ret = 0; + break; + } + enumName = "ACTIVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE_ACTIVE; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_ZOOM_METHOD: { + enumName = "AUTO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_ZOOM_METHOD_AUTO; + ret = 0; + break; + } + enumName = "ZOOM_RATIO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_ZOOM_METHOD_ZOOM_RATIO; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AE_PRIORITY_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_PRIORITY_MODE_OFF; + ret = 0; + break; + } + enumName = "SENSOR_SENSITIVITY_PRIORITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_SENSITIVITY_PRIORITY; + ret = 0; + break; + } + enumName = "SENSOR_EXPOSURE_TIME_PRIORITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_EXPOSURE_TIME_PRIORITY; + ret = 0; + break; + } + break; + } + case ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES: { + break; + } + + case ANDROID_DEMOSAIC_MODE: { + enumName = "FAST"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEMOSAIC_MODE_FAST; + ret = 0; + break; + } + enumName = "HIGH_QUALITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY; + ret = 0; + break; + } + break; + } + + case ANDROID_EDGE_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_EDGE_MODE_OFF; + ret = 0; + break; + } + enumName = "FAST"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_EDGE_MODE_FAST; + ret = 0; + break; + } + enumName = "HIGH_QUALITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_EDGE_MODE_HIGH_QUALITY; + ret = 0; + break; + } + enumName = "ZERO_SHUTTER_LAG"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_EDGE_MODE_ZERO_SHUTTER_LAG; + ret = 0; + break; + } + break; + } + case ANDROID_EDGE_STRENGTH: { + break; + } + case ANDROID_EDGE_AVAILABLE_EDGE_MODES: { + break; + } + + case ANDROID_FLASH_FIRING_POWER: { + break; + } + case ANDROID_FLASH_FIRING_TIME: { + break; + } + case ANDROID_FLASH_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_MODE_OFF; + ret = 0; + break; + } + enumName = "SINGLE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_MODE_SINGLE; + ret = 0; + break; + } + enumName = "TORCH"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_MODE_TORCH; + ret = 0; + break; + } + break; + } + case ANDROID_FLASH_COLOR_TEMPERATURE: { + break; + } + case ANDROID_FLASH_MAX_ENERGY: { + break; + } + case ANDROID_FLASH_STATE: { + enumName = "UNAVAILABLE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_STATE_UNAVAILABLE; + ret = 0; + break; + } + enumName = "CHARGING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_STATE_CHARGING; + ret = 0; + break; + } + enumName = "READY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_STATE_READY; + ret = 0; + break; + } + enumName = "FIRED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_STATE_FIRED; + ret = 0; + break; + } + enumName = "PARTIAL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_STATE_PARTIAL; + ret = 0; + break; + } + break; + } + case ANDROID_FLASH_STRENGTH_LEVEL: { + break; + } + case ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL: { + break; + } + case ANDROID_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL: { + break; + } + case ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL: { + break; + } + case ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL: { + break; + } + + case ANDROID_FLASH_INFO_AVAILABLE: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_INFO_AVAILABLE_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_FLASH_INFO_AVAILABLE_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_FLASH_INFO_CHARGE_DURATION: { + break; + } + case ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL: { + break; + } + case ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL: { + break; + } + + case ANDROID_HOT_PIXEL_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HOT_PIXEL_MODE_OFF; + ret = 0; + break; + } + enumName = "FAST"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HOT_PIXEL_MODE_FAST; + ret = 0; + break; + } + enumName = "HIGH_QUALITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY; + ret = 0; + break; + } + break; + } + case ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES: { + break; + } + + case ANDROID_JPEG_GPS_COORDINATES: { + break; + } + case ANDROID_JPEG_GPS_PROCESSING_METHOD: { + break; + } + case ANDROID_JPEG_GPS_TIMESTAMP: { + break; + } + case ANDROID_JPEG_ORIENTATION: { + break; + } + case ANDROID_JPEG_QUALITY: { + break; + } + case ANDROID_JPEG_THUMBNAIL_QUALITY: { + break; + } + case ANDROID_JPEG_THUMBNAIL_SIZE: { + break; + } + case ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES: { + break; + } + case ANDROID_JPEG_MAX_SIZE: { + break; + } + case ANDROID_JPEG_SIZE: { + break; + } + + case ANDROID_LENS_APERTURE: { + break; + } + case ANDROID_LENS_FILTER_DENSITY: { + break; + } + case ANDROID_LENS_FOCAL_LENGTH: { + break; + } + case ANDROID_LENS_FOCUS_DISTANCE: { + break; + } + case ANDROID_LENS_OPTICAL_STABILIZATION_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_ON; + ret = 0; + break; + } + break; + } + case ANDROID_LENS_FACING: { + enumName = "FRONT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_FACING_FRONT; + ret = 0; + break; + } + enumName = "BACK"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_FACING_BACK; + ret = 0; + break; + } + enumName = "EXTERNAL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_FACING_EXTERNAL; + ret = 0; + break; + } + break; + } + case ANDROID_LENS_POSE_ROTATION: { + break; + } + case ANDROID_LENS_POSE_TRANSLATION: { + break; + } + case ANDROID_LENS_FOCUS_RANGE: { + break; + } + case ANDROID_LENS_STATE: { + enumName = "STATIONARY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_STATE_STATIONARY; + ret = 0; + break; + } + enumName = "MOVING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_STATE_MOVING; + ret = 0; + break; + } + break; + } + case ANDROID_LENS_INTRINSIC_CALIBRATION: { + break; + } + case ANDROID_LENS_RADIAL_DISTORTION: { + break; + } + case ANDROID_LENS_POSE_REFERENCE: { + enumName = "PRIMARY_CAMERA"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA; + ret = 0; + break; + } + enumName = "GYROSCOPE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_POSE_REFERENCE_GYROSCOPE; + ret = 0; + break; + } + enumName = "UNDEFINED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_POSE_REFERENCE_UNDEFINED; + ret = 0; + break; + } + enumName = "AUTOMOTIVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE; + ret = 0; + break; + } + break; + } + case ANDROID_LENS_DISTORTION: { + break; + } + case ANDROID_LENS_DISTORTION_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_LENS_INTRINSIC_CALIBRATION_MAXIMUM_RESOLUTION: { + break; + } + + case ANDROID_LENS_INFO_AVAILABLE_APERTURES: { + break; + } + case ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES: { + break; + } + case ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS: { + break; + } + case ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION: { + break; + } + case ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE: { + break; + } + case ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE: { + break; + } + case ANDROID_LENS_INFO_SHADING_MAP_SIZE: { + break; + } + case ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION: { + enumName = "UNCALIBRATED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED; + ret = 0; + break; + } + enumName = "APPROXIMATE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE; + ret = 0; + break; + } + enumName = "CALIBRATED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED; + ret = 0; + break; + } + break; + } + + case ANDROID_NOISE_REDUCTION_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_NOISE_REDUCTION_MODE_OFF; + ret = 0; + break; + } + enumName = "FAST"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_NOISE_REDUCTION_MODE_FAST; + ret = 0; + break; + } + enumName = "HIGH_QUALITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY; + ret = 0; + break; + } + enumName = "MINIMAL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_NOISE_REDUCTION_MODE_MINIMAL; + ret = 0; + break; + } + enumName = "ZERO_SHUTTER_LAG"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG; + ret = 0; + break; + } + break; + } + case ANDROID_NOISE_REDUCTION_STRENGTH: { + break; + } + case ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES: { + break; + } + + case ANDROID_QUIRKS_METERING_CROP_REGION: { + break; + } + case ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO: { + break; + } + case ANDROID_QUIRKS_USE_ZSL_FORMAT: { + break; + } + case ANDROID_QUIRKS_USE_PARTIAL_RESULT: { + break; + } + case ANDROID_QUIRKS_PARTIAL_RESULT: { + enumName = "FINAL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_QUIRKS_PARTIAL_RESULT_FINAL; + ret = 0; + break; + } + enumName = "PARTIAL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL; + ret = 0; + break; + } + break; + } + + case ANDROID_REQUEST_FRAME_COUNT: { + break; + } + case ANDROID_REQUEST_ID: { + break; + } + case ANDROID_REQUEST_INPUT_STREAMS: { + break; + } + case ANDROID_REQUEST_METADATA_MODE: { + enumName = "NONE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_METADATA_MODE_NONE; + ret = 0; + break; + } + enumName = "FULL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_METADATA_MODE_FULL; + ret = 0; + break; + } + break; + } + case ANDROID_REQUEST_OUTPUT_STREAMS: { + break; + } + case ANDROID_REQUEST_TYPE: { + enumName = "CAPTURE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_TYPE_CAPTURE; + ret = 0; + break; + } + enumName = "REPROCESS"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_TYPE_REPROCESS; + ret = 0; + break; + } + break; + } + case ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS: { + break; + } + case ANDROID_REQUEST_MAX_NUM_REPROCESS_STREAMS: { + break; + } + case ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS: { + break; + } + case ANDROID_REQUEST_PIPELINE_DEPTH: { + break; + } + case ANDROID_REQUEST_PIPELINE_MAX_DEPTH: { + break; + } + case ANDROID_REQUEST_PARTIAL_RESULT_COUNT: { + break; + } + case ANDROID_REQUEST_AVAILABLE_CAPABILITIES: { + enumName = "BACKWARD_COMPATIBLE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE; + ret = 0; + break; + } + enumName = "MANUAL_SENSOR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR; + ret = 0; + break; + } + enumName = "MANUAL_POST_PROCESSING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING; + ret = 0; + break; + } + enumName = "RAW"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_RAW; + ret = 0; + break; + } + enumName = "PRIVATE_REPROCESSING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING; + ret = 0; + break; + } + enumName = "READ_SENSOR_SETTINGS"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS; + ret = 0; + break; + } + enumName = "BURST_CAPTURE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE; + ret = 0; + break; + } + enumName = "YUV_REPROCESSING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING; + ret = 0; + break; + } + enumName = "DEPTH_OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT; + ret = 0; + break; + } + enumName = "CONSTRAINED_HIGH_SPEED_VIDEO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO; + ret = 0; + break; + } + enumName = "MOTION_TRACKING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING; + ret = 0; + break; + } + enumName = "LOGICAL_MULTI_CAMERA"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA; + ret = 0; + break; + } + enumName = "MONOCHROME"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME; + ret = 0; + break; + } + enumName = "SECURE_IMAGE_DATA"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA; + ret = 0; + break; + } + enumName = "SYSTEM_CAMERA"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA; + ret = 0; + break; + } + enumName = "OFFLINE_PROCESSING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING; + ret = 0; + break; + } + enumName = "ULTRA_HIGH_RESOLUTION_SENSOR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR; + ret = 0; + break; + } + enumName = "REMOSAIC_REPROCESSING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_REMOSAIC_REPROCESSING; + ret = 0; + break; + } + enumName = "DYNAMIC_RANGE_TEN_BIT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT; + ret = 0; + break; + } + enumName = "STREAM_USE_CASE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_STREAM_USE_CASE; + ret = 0; + break; + } + enumName = "COLOR_SPACE_PROFILES"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_CAPABILITIES_COLOR_SPACE_PROFILES; + ret = 0; + break; + } + break; + } + case ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS: { + break; + } + case ANDROID_REQUEST_AVAILABLE_RESULT_KEYS: { + break; + } + case ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS: { + break; + } + case ANDROID_REQUEST_AVAILABLE_SESSION_KEYS: { + break; + } + case ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS: { + break; + } + case ANDROID_REQUEST_CHARACTERISTIC_KEYS_NEEDING_PERMISSION: { + break; + } + case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP: { + enumName = "STANDARD"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD; + ret = 0; + break; + } + enumName = "HLG10"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10; + ret = 0; + break; + } + enumName = "HDR10"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10; + ret = 0; + break; + } + enumName = "HDR10_PLUS"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS; + ret = 0; + break; + } + enumName = "DOLBY_VISION_10B_HDR_REF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF; + ret = 0; + break; + } + enumName = "DOLBY_VISION_10B_HDR_REF_PO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO; + ret = 0; + break; + } + enumName = "DOLBY_VISION_10B_HDR_OEM"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM; + ret = 0; + break; + } + enumName = "DOLBY_VISION_10B_HDR_OEM_PO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO; + ret = 0; + break; + } + enumName = "DOLBY_VISION_8B_HDR_REF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF; + ret = 0; + break; + } + enumName = "DOLBY_VISION_8B_HDR_REF_PO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO; + ret = 0; + break; + } + enumName = "DOLBY_VISION_8B_HDR_OEM"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM; + ret = 0; + break; + } + enumName = "DOLBY_VISION_8B_HDR_OEM_PO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO; + ret = 0; + break; + } + enumName = "MAX"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX; + ret = 0; + break; + } + enumName = "STANDARD_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "HLG10_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "HDR10_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "HDR10_PLUS_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "DOLBY_VISION_10B_HDR_REF_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "DOLBY_VISION_10B_HDR_REF_PO_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "DOLBY_VISION_10B_HDR_OEM_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "DOLBY_VISION_10B_HDR_OEM_PO_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "DOLBY_VISION_8B_HDR_REF_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "DOLBY_VISION_8B_HDR_REF_PO_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "DOLBY_VISION_8B_HDR_OEM_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "DOLBY_VISION_8B_HDR_OEM_PO_SMPTE_2094_50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO_SMPTE_2094_50; + ret = 0; + break; + } + enumName = "MAX_312"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX_312; + ret = 0; + break; + } + break; + } + case ANDROID_REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE: { + break; + } + case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP: { + enumName = "UNSPECIFIED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED; + ret = 0; + break; + } + enumName = "SRGB"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB; + ret = 0; + break; + } + enumName = "DISPLAY_P3"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3; + ret = 0; + break; + } + enumName = "BT2020_HLG"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG; + ret = 0; + break; + } + break; + } + + case ANDROID_SCALER_CROP_REGION: { + break; + } + case ANDROID_SCALER_AVAILABLE_FORMATS: { + enumName = "RAW16"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_RAW16; + ret = 0; + break; + } + enumName = "RAW_OPAQUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_RAW_OPAQUE; + ret = 0; + break; + } + enumName = "YV12"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_YV12; + ret = 0; + break; + } + enumName = "YCrCb_420_SP"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_YCrCb_420_SP; + ret = 0; + break; + } + enumName = "IMPLEMENTATION_DEFINED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED; + ret = 0; + break; + } + enumName = "YCbCr_420_888"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888; + ret = 0; + break; + } + enumName = "BLOB"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB; + ret = 0; + break; + } + enumName = "RAW10"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_RAW10; + ret = 0; + break; + } + enumName = "RAW12"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_RAW12; + ret = 0; + break; + } + enumName = "RAW14"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_RAW14; + ret = 0; + break; + } + enumName = "Y8"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_FORMATS_Y8; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS: { + break; + } + case ANDROID_SCALER_AVAILABLE_JPEG_SIZES: { + break; + } + case ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM: { + break; + } + case ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS: { + break; + } + case ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES: { + break; + } + case ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS: { + break; + } + case ANDROID_SCALER_AVAILABLE_RAW_SIZES: { + break; + } + case ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP: { + break; + } + case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS: { + break; + } + case ANDROID_SCALER_CROPPING_TYPE: { + enumName = "CENTER_ONLY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY; + ret = 0; + break; + } + enumName = "FREEFORM"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_CROPPING_TYPE_FREEFORM; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS: { + enumName = "PREVIEW"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PREVIEW; + ret = 0; + break; + } + enumName = "RECORD"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RECORD; + ret = 0; + break; + } + enumName = "VIDEO_SNAPSHOT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VIDEO_SNAPSHOT; + ret = 0; + break; + } + enumName = "SNAPSHOT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_SNAPSHOT; + ret = 0; + break; + } + enumName = "ZSL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_ZSL; + ret = 0; + break; + } + enumName = "RAW"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_RAW; + ret = 0; + break; + } + enumName = "LOW_LATENCY_SNAPSHOT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_LOW_LATENCY_SNAPSHOT; + ret = 0; + break; + } + enumName = "PUBLIC_END"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END; + ret = 0; + break; + } + enumName = "10BIT_OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_10BIT_OUTPUT; + ret = 0; + break; + } + enumName = "PUBLIC_END_3_8"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_PUBLIC_END_3_8; + ret = 0; + break; + } + enumName = "VENDOR_START"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_RECOMMENDED_STREAM_CONFIGURATIONS_VENDOR_START; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_AVAILABLE_RECOMMENDED_INPUT_OUTPUT_FORMATS_MAP: { + break; + } + case ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES: { + break; + } + case ANDROID_SCALER_ROTATE_AND_CROP: { + enumName = "NONE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_ROTATE_AND_CROP_NONE; + ret = 0; + break; + } + enumName = "90"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_ROTATE_AND_CROP_90; + ret = 0; + break; + } + enumName = "180"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_ROTATE_AND_CROP_180; + ret = 0; + break; + } + enumName = "270"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_ROTATE_AND_CROP_270; + ret = 0; + break; + } + enumName = "AUTO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_ROTATE_AND_CROP_AUTO; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE: { + break; + } + case ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_CROP_REGION_SET: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_CROP_REGION_SET_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_CROP_REGION_SET_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES: { + enumName = "DEFAULT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT; + ret = 0; + break; + } + enumName = "PREVIEW"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW; + ret = 0; + break; + } + enumName = "STILL_CAPTURE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_STILL_CAPTURE; + ret = 0; + break; + } + enumName = "VIDEO_RECORD"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_RECORD; + ret = 0; + break; + } + enumName = "PREVIEW_VIDEO_STILL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_PREVIEW_VIDEO_STILL; + ret = 0; + break; + } + enumName = "VIDEO_CALL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL; + ret = 0; + break; + } + enumName = "CROPPED_RAW"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_CROPPED_RAW; + ret = 0; + break; + } + enumName = "VENDOR_START"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SCALER_AVAILABLE_STREAM_USE_CASES_VENDOR_START; + ret = 0; + break; + } + break; + } + case ANDROID_SCALER_RAW_CROP_REGION: { + break; + } + case ANDROID_SCALER_CONCURRENT_MULTI_RESOLUTION_FORMATS: { + break; + } + + case ANDROID_SENSOR_EXPOSURE_TIME: { + break; + } + case ANDROID_SENSOR_FRAME_DURATION: { + break; + } + case ANDROID_SENSOR_SENSITIVITY: { + break; + } + case ANDROID_SENSOR_REFERENCE_ILLUMINANT1: { + enumName = "DAYLIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT; + ret = 0; + break; + } + enumName = "FLUORESCENT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FLUORESCENT; + ret = 0; + break; + } + enumName = "TUNGSTEN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_TUNGSTEN; + ret = 0; + break; + } + enumName = "FLASH"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FLASH; + ret = 0; + break; + } + enumName = "FINE_WEATHER"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_FINE_WEATHER; + ret = 0; + break; + } + enumName = "CLOUDY_WEATHER"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_CLOUDY_WEATHER; + ret = 0; + break; + } + enumName = "SHADE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_SHADE; + ret = 0; + break; + } + enumName = "DAYLIGHT_FLUORESCENT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT; + ret = 0; + break; + } + enumName = "DAY_WHITE_FLUORESCENT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_DAY_WHITE_FLUORESCENT; + ret = 0; + break; + } + enumName = "COOL_WHITE_FLUORESCENT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT; + ret = 0; + break; + } + enumName = "WHITE_FLUORESCENT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT; + ret = 0; + break; + } + enumName = "STANDARD_A"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A; + ret = 0; + break; + } + enumName = "STANDARD_B"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B; + ret = 0; + break; + } + enumName = "STANDARD_C"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C; + ret = 0; + break; + } + enumName = "D55"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D55; + ret = 0; + break; + } + enumName = "D65"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D65; + ret = 0; + break; + } + enumName = "D75"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D75; + ret = 0; + break; + } + enumName = "D50"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_D50; + ret = 0; + break; + } + enumName = "ISO_STUDIO_TUNGSTEN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN; + ret = 0; + break; + } + break; + } + case ANDROID_SENSOR_REFERENCE_ILLUMINANT2: { + break; + } + case ANDROID_SENSOR_CALIBRATION_TRANSFORM1: { + break; + } + case ANDROID_SENSOR_CALIBRATION_TRANSFORM2: { + break; + } + case ANDROID_SENSOR_COLOR_TRANSFORM1: { + break; + } + case ANDROID_SENSOR_COLOR_TRANSFORM2: { + break; + } + case ANDROID_SENSOR_FORWARD_MATRIX1: { + break; + } + case ANDROID_SENSOR_FORWARD_MATRIX2: { + break; + } + case ANDROID_SENSOR_BASE_GAIN_FACTOR: { + break; + } + case ANDROID_SENSOR_BLACK_LEVEL_PATTERN: { + break; + } + case ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY: { + break; + } + case ANDROID_SENSOR_ORIENTATION: { + break; + } + case ANDROID_SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS: { + break; + } + case ANDROID_SENSOR_TIMESTAMP: { + break; + } + case ANDROID_SENSOR_TEMPERATURE: { + break; + } + case ANDROID_SENSOR_NEUTRAL_COLOR_POINT: { + break; + } + case ANDROID_SENSOR_NOISE_PROFILE: { + break; + } + case ANDROID_SENSOR_PROFILE_HUE_SAT_MAP: { + break; + } + case ANDROID_SENSOR_PROFILE_TONE_CURVE: { + break; + } + case ANDROID_SENSOR_GREEN_SPLIT: { + break; + } + case ANDROID_SENSOR_TEST_PATTERN_DATA: { + break; + } + case ANDROID_SENSOR_TEST_PATTERN_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; + ret = 0; + break; + } + enumName = "SOLID_COLOR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR; + ret = 0; + break; + } + enumName = "COLOR_BARS"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS; + ret = 0; + break; + } + enumName = "COLOR_BARS_FADE_TO_GRAY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY; + ret = 0; + break; + } + enumName = "PN9"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_TEST_PATTERN_MODE_PN9; + ret = 0; + break; + } + enumName = "BLACK"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK; + ret = 0; + break; + } + enumName = "CUSTOM1"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_TEST_PATTERN_MODE_CUSTOM1; + ret = 0; + break; + } + break; + } + case ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES: { + break; + } + case ANDROID_SENSOR_ROLLING_SHUTTER_SKEW: { + break; + } + case ANDROID_SENSOR_OPTICAL_BLACK_REGIONS: { + break; + } + case ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL: { + break; + } + case ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL: { + break; + } + case ANDROID_SENSOR_OPAQUE_RAW_SIZE: { + break; + } + case ANDROID_SENSOR_OPAQUE_RAW_SIZE_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SENSOR_PIXEL_MODE: { + enumName = "DEFAULT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_PIXEL_MODE_DEFAULT; + ret = 0; + break; + } + enumName = "MAXIMUM_RESOLUTION"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION; + ret = 0; + break; + } + break; + } + case ANDROID_SENSOR_RAW_BINNING_FACTOR_USED: { + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_TRUE; + ret = 0; + break; + } + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_RAW_BINNING_FACTOR_USED_FALSE; + ret = 0; + break; + } + break; + } + case ANDROID_SENSOR_READOUT_TIMESTAMP: { + enumName = "NOT_SUPPORTED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED; + ret = 0; + break; + } + enumName = "HARDWARE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE; + ret = 0; + break; + } + break; + } + + case ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE: { + break; + } + case ANDROID_SENSOR_INFO_SENSITIVITY_RANGE: { + break; + } + case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT: { + enumName = "RGGB"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB; + ret = 0; + break; + } + enumName = "GRBG"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG; + ret = 0; + break; + } + enumName = "GBRG"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG; + ret = 0; + break; + } + enumName = "BGGR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR; + ret = 0; + break; + } + enumName = "RGB"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB; + ret = 0; + break; + } + enumName = "MONO"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO; + ret = 0; + break; + } + enumName = "NIR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR; + ret = 0; + break; + } + break; + } + case ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE: { + break; + } + case ANDROID_SENSOR_INFO_MAX_FRAME_DURATION: { + break; + } + case ANDROID_SENSOR_INFO_PHYSICAL_SIZE: { + break; + } + case ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE: { + break; + } + case ANDROID_SENSOR_INFO_WHITE_LEVEL: { + break; + } + case ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE: { + enumName = "UNKNOWN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN; + ret = 0; + break; + } + enumName = "REALTIME"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME; + ret = 0; + break; + } + break; + } + case ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SENSOR_INFO_LENS_SHADING_APPLIED_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE: { + break; + } + case ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_SENSOR_INFO_BINNING_FACTOR: { + break; + } + + case ANDROID_SHADING_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SHADING_MODE_OFF; + ret = 0; + break; + } + enumName = "FAST"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SHADING_MODE_FAST; + ret = 0; + break; + } + enumName = "HIGH_QUALITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SHADING_MODE_HIGH_QUALITY; + ret = 0; + break; + } + break; + } + case ANDROID_SHADING_STRENGTH: { + break; + } + case ANDROID_SHADING_AVAILABLE_MODES: { + break; + } + + case ANDROID_STATISTICS_FACE_DETECT_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; + ret = 0; + break; + } + enumName = "SIMPLE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE; + ret = 0; + break; + } + enumName = "FULL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_FACE_DETECT_MODE_FULL; + ret = 0; + break; + } + break; + } + case ANDROID_STATISTICS_HISTOGRAM_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_HISTOGRAM_MODE_ON; + ret = 0; + break; + } + break; + } + case ANDROID_STATISTICS_SHARPNESS_MAP_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_SHARPNESS_MAP_MODE_ON; + ret = 0; + break; + } + break; + } + case ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_ON; + ret = 0; + break; + } + break; + } + case ANDROID_STATISTICS_FACE_IDS: { + break; + } + case ANDROID_STATISTICS_FACE_LANDMARKS: { + break; + } + case ANDROID_STATISTICS_FACE_RECTANGLES: { + break; + } + case ANDROID_STATISTICS_FACE_SCORES: { + break; + } + case ANDROID_STATISTICS_HISTOGRAM: { + break; + } + case ANDROID_STATISTICS_SHARPNESS_MAP: { + break; + } + case ANDROID_STATISTICS_LENS_SHADING_CORRECTION_MAP: { + break; + } + case ANDROID_STATISTICS_LENS_SHADING_MAP: { + break; + } + case ANDROID_STATISTICS_PREDICTED_COLOR_GAINS: { + break; + } + case ANDROID_STATISTICS_PREDICTED_COLOR_TRANSFORM: { + break; + } + case ANDROID_STATISTICS_SCENE_FLICKER: { + enumName = "NONE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_SCENE_FLICKER_NONE; + ret = 0; + break; + } + enumName = "50HZ"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_SCENE_FLICKER_50HZ; + ret = 0; + break; + } + enumName = "60HZ"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_SCENE_FLICKER_60HZ; + ret = 0; + break; + } + break; + } + case ANDROID_STATISTICS_HOT_PIXEL_MAP: { + break; + } + case ANDROID_STATISTICS_LENS_SHADING_MAP_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_ON; + ret = 0; + break; + } + break; + } + case ANDROID_STATISTICS_OIS_DATA_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_OIS_DATA_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_STATISTICS_OIS_DATA_MODE_ON; + ret = 0; + break; + } + break; + } + case ANDROID_STATISTICS_OIS_TIMESTAMPS: { + break; + } + case ANDROID_STATISTICS_OIS_X_SHIFTS: { + break; + } + case ANDROID_STATISTICS_OIS_Y_SHIFTS: { + break; + } + case ANDROID_STATISTICS_LENS_INTRINSIC_TIMESTAMPS: { + break; + } + case ANDROID_STATISTICS_LENS_INTRINSIC_SAMPLES: { + break; + } + + case ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES: { + break; + } + case ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT: { + break; + } + case ANDROID_STATISTICS_INFO_MAX_FACE_COUNT: { + break; + } + case ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT: { + break; + } + case ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE: { + break; + } + case ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE: { + break; + } + case ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES: { + break; + } + case ANDROID_STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES: { + break; + } + case ANDROID_STATISTICS_INFO_AVAILABLE_OIS_DATA_MODES: { + break; + } + + case ANDROID_TONEMAP_CURVE_BLUE: { + break; + } + case ANDROID_TONEMAP_CURVE_GREEN: { + break; + } + case ANDROID_TONEMAP_CURVE_RED: { + break; + } + case ANDROID_TONEMAP_MODE: { + enumName = "CONTRAST_CURVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_TONEMAP_MODE_CONTRAST_CURVE; + ret = 0; + break; + } + enumName = "FAST"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_TONEMAP_MODE_FAST; + ret = 0; + break; + } + enumName = "HIGH_QUALITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_TONEMAP_MODE_HIGH_QUALITY; + ret = 0; + break; + } + enumName = "GAMMA_VALUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_TONEMAP_MODE_GAMMA_VALUE; + ret = 0; + break; + } + enumName = "PRESET_CURVE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_TONEMAP_MODE_PRESET_CURVE; + ret = 0; + break; + } + break; + } + case ANDROID_TONEMAP_MAX_CURVE_POINTS: { + break; + } + case ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES: { + break; + } + case ANDROID_TONEMAP_GAMMA: { + break; + } + case ANDROID_TONEMAP_PRESET_CURVE: { + enumName = "SRGB"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_TONEMAP_PRESET_CURVE_SRGB; + ret = 0; + break; + } + enumName = "REC709"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_TONEMAP_PRESET_CURVE_REC709; + ret = 0; + break; + } + break; + } + + case ANDROID_LED_TRANSMIT: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LED_TRANSMIT_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LED_TRANSMIT_ON; + ret = 0; + break; + } + break; + } + case ANDROID_LED_AVAILABLE_LEDS: { + enumName = "TRANSMIT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LED_AVAILABLE_LEDS_TRANSMIT; + ret = 0; + break; + } + break; + } + + case ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL: { + enumName = "LIMITED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED; + ret = 0; + break; + } + enumName = "FULL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL; + ret = 0; + break; + } + enumName = "LEGACY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY; + ret = 0; + break; + } + enumName = "3"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_3; + ret = 0; + break; + } + enumName = "EXTERNAL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL; + ret = 0; + break; + } + break; + } + case ANDROID_INFO_VERSION: { + break; + } + case ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION: { + enumName = "HIDL_DEVICE_3_5"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5; + ret = 0; + break; + } + enumName = "SESSION_CONFIGURABLE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE; + ret = 0; + break; + } + break; + } + case ANDROID_INFO_DEVICE_STATE_ORIENTATIONS: { + break; + } + case ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION: { + enumName = "UPSIDE_DOWN_CAKE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_UPSIDE_DOWN_CAKE; + ret = 0; + break; + } + enumName = "VANILLA_ICE_CREAM"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_VANILLA_ICE_CREAM; + ret = 0; + break; + } + enumName = "BAKLAVA"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_BAKLAVA; + ret = 0; + break; + } + break; + } + case ANDROID_INFO_DEVICE_ID: { + break; + } + case ANDROID_INFO_DEVICE_TYPE: { + enumName = "BUILT_IN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_DEVICE_TYPE_BUILT_IN; + ret = 0; + break; + } + enumName = "EXTERNAL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_DEVICE_TYPE_EXTERNAL; + ret = 0; + break; + } + enumName = "VIRTUAL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_DEVICE_TYPE_VIRTUAL; + ret = 0; + break; + } + enumName = "UNKNOWN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_INFO_DEVICE_TYPE_UNKNOWN; + ret = 0; + break; + } + break; + } + + case ANDROID_BLACK_LEVEL_LOCK: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_BLACK_LEVEL_LOCK_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_BLACK_LEVEL_LOCK_ON; + ret = 0; + break; + } + break; + } + + case ANDROID_SYNC_FRAME_NUMBER: { + enumName = "CONVERGING"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SYNC_FRAME_NUMBER_CONVERGING; + ret = 0; + break; + } + enumName = "UNKNOWN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SYNC_FRAME_NUMBER_UNKNOWN; + ret = 0; + break; + } + break; + } + case ANDROID_SYNC_MAX_LATENCY: { + enumName = "PER_FRAME_CONTROL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SYNC_MAX_LATENCY_PER_FRAME_CONTROL; + ret = 0; + break; + } + enumName = "UNKNOWN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SYNC_MAX_LATENCY_UNKNOWN; + ret = 0; + break; + } + break; + } + + case ANDROID_REPROCESS_EFFECTIVE_EXPOSURE_FACTOR: { + break; + } + case ANDROID_REPROCESS_MAX_CAPTURE_STALL: { + break; + } + + case ANDROID_DEPTH_MAX_DEPTH_SAMPLES: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS: { + break; + } + case ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_DEPTH_AVAILABLE_RECOMMENDED_DEPTH_STREAM_CONFIGURATIONS: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + + case ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS: { + break; + } + case ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE: { + enumName = "APPROXIMATE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_APPROXIMATE; + ret = 0; + break; + } + enumName = "CALIBRATED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE_CALIBRATED; + ret = 0; + break; + } + break; + } + case ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID: { + break; + } + case ANDROID_LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_SENSOR_CROP_REGION: { + break; + } + case ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS_ON; + ret = 0; + break; + } + break; + } + + case ANDROID_DISTORTION_CORRECTION_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DISTORTION_CORRECTION_MODE_OFF; + ret = 0; + break; + } + enumName = "FAST"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DISTORTION_CORRECTION_MODE_FAST; + ret = 0; + break; + } + enumName = "HIGH_QUALITY"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DISTORTION_CORRECTION_MODE_HIGH_QUALITY; + ret = 0; + break; + } + break; + } + case ANDROID_DISTORTION_CORRECTION_AVAILABLE_MODES: { + break; + } + + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + + case ANDROID_HEIC_INFO_SUPPORTED: { + enumName = "FALSE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_INFO_SUPPORTED_FALSE; + ret = 0; + break; + } + enumName = "TRUE"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_HEIC_INFO_SUPPORTED_TRUE; + ret = 0; + break; + } + break; + } + case ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT: { + break; + } + + case ANDROID_AUTOMOTIVE_LOCATION: { + enumName = "INTERIOR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_INTERIOR; + ret = 0; + break; + } + enumName = "EXTERIOR_OTHER"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_OTHER; + ret = 0; + break; + } + enumName = "EXTERIOR_FRONT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_FRONT; + ret = 0; + break; + } + enumName = "EXTERIOR_REAR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_REAR; + ret = 0; + break; + } + enumName = "EXTERIOR_LEFT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_LEFT; + ret = 0; + break; + } + enumName = "EXTERIOR_RIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTERIOR_RIGHT; + ret = 0; + break; + } + enumName = "EXTRA_OTHER"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTRA_OTHER; + ret = 0; + break; + } + enumName = "EXTRA_FRONT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTRA_FRONT; + ret = 0; + break; + } + enumName = "EXTRA_REAR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTRA_REAR; + ret = 0; + break; + } + enumName = "EXTRA_LEFT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTRA_LEFT; + ret = 0; + break; + } + enumName = "EXTRA_RIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LOCATION_EXTRA_RIGHT; + ret = 0; + break; + } + break; + } + + case ANDROID_AUTOMOTIVE_LENS_FACING: { + enumName = "EXTERIOR_OTHER"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_OTHER; + ret = 0; + break; + } + enumName = "EXTERIOR_FRONT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_FRONT; + ret = 0; + break; + } + enumName = "EXTERIOR_REAR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_REAR; + ret = 0; + break; + } + enumName = "EXTERIOR_LEFT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_LEFT; + ret = 0; + break; + } + enumName = "EXTERIOR_RIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_EXTERIOR_RIGHT; + ret = 0; + break; + } + enumName = "INTERIOR_OTHER"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_OTHER; + ret = 0; + break; + } + enumName = "INTERIOR_SEAT_ROW_1_LEFT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_LEFT; + ret = 0; + break; + } + enumName = "INTERIOR_SEAT_ROW_1_CENTER"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_CENTER; + ret = 0; + break; + } + enumName = "INTERIOR_SEAT_ROW_1_RIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_1_RIGHT; + ret = 0; + break; + } + enumName = "INTERIOR_SEAT_ROW_2_LEFT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_LEFT; + ret = 0; + break; + } + enumName = "INTERIOR_SEAT_ROW_2_CENTER"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_CENTER; + ret = 0; + break; + } + enumName = "INTERIOR_SEAT_ROW_2_RIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_2_RIGHT; + ret = 0; + break; + } + enumName = "INTERIOR_SEAT_ROW_3_LEFT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_LEFT; + ret = 0; + break; + } + enumName = "INTERIOR_SEAT_ROW_3_CENTER"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_CENTER; + ret = 0; + break; + } + enumName = "INTERIOR_SEAT_ROW_3_RIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_AUTOMOTIVE_LENS_FACING_INTERIOR_SEAT_ROW_3_RIGHT; + ret = 0; + break; + } + break; + } + + case ANDROID_EXTENSION_STRENGTH: { + break; + } + case ANDROID_EXTENSION_CURRENT_TYPE: { + break; + } + case ANDROID_EXTENSION_NIGHT_MODE_INDICATOR: { + enumName = "UNKNOWN"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_UNKNOWN; + ret = 0; + break; + } + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_ON; + ret = 0; + break; + } + break; + } + + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS: { + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS: { + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION: { + enumName = "OUTPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT; + ret = 0; + break; + } + enumName = "INPUT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT; + ret = 0; + break; + } + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + case ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION: { + break; + } + + case ANDROID_SHARED_SESSION_COLOR_SPACE: { + enumName = "UNSPECIFIED"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SHARED_SESSION_COLOR_SPACE_UNSPECIFIED; + ret = 0; + break; + } + enumName = "SRGB"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SHARED_SESSION_COLOR_SPACE_SRGB; + ret = 0; + break; + } + enumName = "DISPLAY_P3"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SHARED_SESSION_COLOR_SPACE_DISPLAY_P3; + ret = 0; + break; + } + enumName = "BT2020_HLG"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_SHARED_SESSION_COLOR_SPACE_BT2020_HLG; + ret = 0; + break; + } + break; + } + case ANDROID_SHARED_SESSION_OUTPUT_CONFIGURATIONS: { + break; + } + + case ANDROID_DESKTOP_EFFECTS_CAPABILITIES: { + enumName = "BACKGROUND_BLUR"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_CAPABILITIES_BACKGROUND_BLUR; + ret = 0; + break; + } + enumName = "FACE_RETOUCH"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_CAPABILITIES_FACE_RETOUCH; + ret = 0; + break; + } + enumName = "PORTRAIT_RELIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_CAPABILITIES_PORTRAIT_RELIGHT; + ret = 0; + break; + } + break; + } + case ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODES: { + break; + } + case ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_OFF; + ret = 0; + break; + } + enumName = "LIGHT"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_LIGHT; + ret = 0; + break; + } + enumName = "FULL"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_FULL; + ret = 0; + break; + } + break; + } + case ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_ON; + ret = 0; + break; + } + break; + } + case ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_STRENGTH: { + break; + } + case ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE: { + enumName = "OFF"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_OFF; + ret = 0; + break; + } + enumName = "ON"; + if (strncmp(name, enumName, size) == 0) { + *value = ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_ON; + ret = 0; + break; + } + break; + } + + } return ret; } -#define CAMERA_METADATA_ENUM_STRING_MAX_SIZE 29 +#define CAMERA_METADATA_ENUM_STRING_MAX_SIZE 42 From patchwork Mon Jun 29 16:30:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27130 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 BFE88C3304 for ; Mon, 29 Jun 2026 16:31:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5588A65FDC; Mon, 29 Jun 2026 18:31:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XQtUNXS3"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9E15065F74 for ; Mon, 29 Jun 2026 18:30:33 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 78676E91 for ; Mon, 29 Jun 2026 18:29:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750590; bh=/PVXLgJoEYbBeWCuVc9dohFWysXp3d0BxILsrqxmbQc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=XQtUNXS3AppT2k4qGgIIv3yJ37OxGsyV81ok87QXSGFKzUXPHUeaZd+ntnlO/UWCj FU2HzQRQFIjMe7zQwqmx74QTRHknYSB9lMK94Fy8ZPFTXl7HVoqUHzY5A2/Sr4Fi0b hx56xEw3W+J+lfpYZ+LOkv7l5IUNBfeFnjsUEw4s= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 50/54] android: camera_request: Add helper for buffer conversion Date: Mon, 29 Jun 2026 18:30:13 +0200 Message-ID: <20260629163017.863145-51-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Add a function to the `StreamBuffer` type that creates an appropriate `camera3_stream_buffer_t` for returning it to the camera framework. Signed-off-by: Barnabás Pőcze --- src/android/camera_device.cpp | 18 ++---------------- src/android/camera_request.cpp | 20 ++++++++++++++++++++ src/android/camera_request.h | 2 ++ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 80ff248c2a..0d5b5b97eb 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1308,22 +1308,8 @@ void CameraDevice::sendCaptureResults() std::vector resultBuffers; resultBuffers.reserve(descriptor->buffers_.size()); - for (auto &buffer : descriptor->buffers_) { - camera3_buffer_status status = CAMERA3_BUFFER_STATUS_ERROR; - - if (buffer.status == Camera3RequestDescriptor::Status::Success) - status = CAMERA3_BUFFER_STATUS_OK; - - /* - * Pass the buffer fence back to the camera framework as - * a release fence. This instructs the framework to wait - * on the acquire fence in case we haven't done so - * ourselves for any reason. - */ - resultBuffers.push_back({ buffer.stream->camera3Stream(), - buffer.camera3Buffer, status, - -1, buffer.fence.release() }); - } + for (auto &buffer : descriptor->buffers_) + resultBuffers.push_back(buffer.prepareToReturn()); captureResult.num_output_buffers = resultBuffers.size(); captureResult.output_buffers = resultBuffers.data(); diff --git a/src/android/camera_request.cpp b/src/android/camera_request.cpp index 0d45960d90..feac7a3e19 100644 --- a/src/android/camera_request.cpp +++ b/src/android/camera_request.cpp @@ -192,3 +192,23 @@ Camera3RequestDescriptor::StreamBuffer::StreamBuffer(StreamBuffer &&) = default; Camera3RequestDescriptor::StreamBuffer & Camera3RequestDescriptor::StreamBuffer::operator=(Camera3RequestDescriptor::StreamBuffer &&) = default; + +camera3_stream_buffer_t Camera3RequestDescriptor::StreamBuffer::prepareToReturn() +{ + /* + * Pass the buffer fence back to the camera framework as + * a release fence. This instructs the framework to wait + * on the acquire fence in case we haven't done so + * ourselves for any reason. + */ + + return { + .stream = stream->camera3Stream(), + .buffer = camera3Buffer, + .status = status == Camera3RequestDescriptor::Status::Success + ? CAMERA3_BUFFER_STATUS_OK + : CAMERA3_BUFFER_STATUS_ERROR, + .acquire_fence = -1, + .release_fence = fence.release(), + }; +} diff --git a/src/android/camera_request.h b/src/android/camera_request.h index 5b479180f0..164b095b28 100644 --- a/src/android/camera_request.h +++ b/src/android/camera_request.h @@ -43,6 +43,8 @@ public: StreamBuffer(StreamBuffer &&); StreamBuffer &operator=(StreamBuffer &&); + [[nodiscard]] camera3_stream_buffer_t prepareToReturn(); + CameraStream *stream; buffer_handle_t *camera3Buffer; std::unique_ptr frameBuffer; From patchwork Mon Jun 29 16:30:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27129 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 111CEC3303 for ; Mon, 29 Jun 2026 16:31:42 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CDE6A65FC3; Mon, 29 Jun 2026 18:31:41 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="X2SGzmWb"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D483A65F75 for ; Mon, 29 Jun 2026 18:30:33 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id ACF3E1044 for ; Mon, 29 Jun 2026 18:29:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750590; bh=XKl2eO1QWEXdNrfLES9PG0IyEzsv415hXcC0a7vSego=; h=From:To:Subject:Date:In-Reply-To:References:From; b=X2SGzmWberaZBNnyg+iQhlIQPEADpozfybXnn0qFXaW1W/kkFsc+SnH3cDeaChgca E2PEus6OKn36N9iLhGH6SJFVtSf4y4RQ3jpJdcW3C5//cT08tWedkt2tFi2Z3H4dW4 YDr7ArLZZQslK2tffdV8bSwMht+8M/SomsLDyATE= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 51/54] android: camera_device: Move fence restoration into `prepareToReturn()` Date: Mon, 29 Jun 2026 18:30:14 +0200 Message-ID: <20260629163017.863145-52-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" It is sufficient to restore the fence for returning it to the camera framework just before the returned `camera3_stream_buffer_t` is constructed, so do that. Signed-off-by: Barnabás Pőcze --- src/android/camera_device.cpp | 19 +------------------ src/android/camera_request.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 0d5b5b97eb..09aa129e0a 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1146,25 +1146,8 @@ void CameraDevice::requestComplete(Request *request) * The buffer status is set to Success and later changed to Error if * post-processing/compression fails. */ - for (auto &buffer : descriptor->buffers_) { - CameraStream *stream = buffer.stream; - - /* - * Streams of type Direct have been queued to the - * libcamera::Camera and their acquire fences have - * already been waited on by the library. - * - * Acquire fences of streams of type Internal and Mapped - * will be handled during post-processing. - */ - if (stream->type() == CameraStream::Type::Direct) { - /* If handling of the fence has failed restore buffer.fence. */ - std::unique_ptr fence = buffer.frameBuffer->releaseFence(); - if (fence) - buffer.fence = fence->release(); - } + for (auto &buffer : descriptor->buffers_) buffer.status = Camera3RequestDescriptor::Status::Success; - } /* * If the Request has failed, abort the request by notifying the error diff --git a/src/android/camera_request.cpp b/src/android/camera_request.cpp index feac7a3e19..6dfe692f09 100644 --- a/src/android/camera_request.cpp +++ b/src/android/camera_request.cpp @@ -10,6 +10,7 @@ #include #include "camera_buffer.h" +#include "camera_stream.h" using namespace libcamera; @@ -195,6 +196,18 @@ Camera3RequestDescriptor::StreamBuffer::operator=(Camera3RequestDescriptor::Stre camera3_stream_buffer_t Camera3RequestDescriptor::StreamBuffer::prepareToReturn() { + /* + * Streams of type Direct have a non-nullptr `frameBuffer` and + * have been queued to the libcamera::Camera and their acquire + * fences have already been waited on by the library. + */ + if (frameBuffer) { + /* If handling of the fence has failed restore buffer.fence. */ + auto f = frameBuffer->releaseFence(); + if (f) + fence = f->release(); + } + /* * Pass the buffer fence back to the camera framework as * a release fence. This instructs the framework to wait From patchwork Mon Jun 29 16:30:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27128 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 41EEDC3261 for ; Mon, 29 Jun 2026 16:31:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CAA6D65FBE; Mon, 29 Jun 2026 18:31:40 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="iK8xCcNk"; 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 272E965F76 for ; Mon, 29 Jun 2026 18:30:34 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E51D18D4 for ; Mon, 29 Jun 2026 18:29:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750591; bh=7YWY/lzWSfNS9Eie2jc2jCVI6xr/Oc8SVJB7lCQTPJg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=iK8xCcNkci743VuOe8KPjQvve206BJehzNns7ZSE0eEtwF4qyiZzYbXpHoWUq/WXn cJBcumGLE6F5Ua5/BcSVrD06KrxBFkPYwjo2mpJkeQrMyYlZ7IBii7A3XpJcTNArfY hSTmCG03640ioDEe7Fn/1CIxJrXf9m+9UxyZiX9U= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 52/54] android: Use camera buffer pool Date: Mon, 29 Jun 2026 18:30:15 +0200 Message-ID: <20260629163017.863145-53-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Convert the Android HAL to use the camera buffer pool. This involves switching to camera device version 3.6, the newer style of buffer management[0], and using `{return,request}_stream_buffers()`, and furthermore implementing the `signal_stream_flush()` function. These changes are largely untested and were written based on the documentation in the header files as well as the code in [1]. TODO: this removes numFds and numInt checks, are those important?! [0]: https://source.android.com/docs/core/camera/buffer-management-api [1]: https://android.googlesource.com/platform/hardware/interfaces/+/refs/tags/android-17.0.0_r1/camera/device/3.5/default/CameraDeviceSession.cpp#174 Signed-off-by: Barnabás Pőcze --- src/android/camera_capabilities.cpp | 3 + src/android/camera_device.cpp | 250 ++++++++++++++++++++++------ src/android/camera_device.h | 4 + src/android/camera_hal_manager.cpp | 2 +- src/android/camera_ops.cpp | 14 +- src/android/camera_request.cpp | 20 +-- src/android/camera_request.h | 9 +- 7 files changed, 227 insertions(+), 75 deletions(-) diff --git a/src/android/camera_capabilities.cpp b/src/android/camera_capabilities.cpp index 6b58dd5548..feb1cae490 100644 --- a/src/android/camera_capabilities.cpp +++ b/src/android/camera_capabilities.cpp @@ -1453,6 +1453,9 @@ int CameraCapabilities::initializeStaticMetadata() LOG(HAL, Info) << "Hardware level: " << hwLevelStrings.find(hwLevel_)->second; + staticMetadata_->addEntry(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, + ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5); + staticMetadata_->addEntry(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, std::vector(availableCharacteristicsKeys_.begin(), availableCharacteristicsKeys_.end())); diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 09aa129e0a..97f2e1c515 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -394,7 +394,7 @@ int CameraDevice::open(const hw_module_t *hardwareModule) /* Initialize the hw_device_t in the instance camera3_module_t. */ camera3Device_.common.tag = HARDWARE_DEVICE_TAG; - camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_3; + camera3Device_.common.version = CAMERA_DEVICE_API_VERSION_3_6; camera3Device_.common.module = (hw_module_t *)hardwareModule; camera3Device_.common.close = hal_dev_close; @@ -434,9 +434,45 @@ void CameraDevice::flush() void CameraDevice::stop() { MutexLocker stateLock(stateMutex_); + std::vector streamBuffers; + + camera_->bufferCompleted.connect(&streamBuffers, [&](libcamera::Request *request, [[maybe_unused]] const libcamera::Stream *stream, libcamera::FrameBuffer *fb) { + if (request) + return; + + /* Collect buffers from the pool that were not used for a request. */ + + std::unique_ptr buffer( + reinterpret_cast(fb->cookie())); + fb->setCookie(0); + + streamBuffers.push_back(std::move(*buffer)); + }); camera_->stop(); + camera_->bufferCompleted.disconnect(&streamBuffers); + + /* Return buffers that were unused by requests. */ + { + std::vector returnBuffers; + returnBuffers.reserve(streamBuffers.size()); + + for (auto &buffer : streamBuffers) { + if (buffer.internalBuffer) + buffer.stream->putBuffer(buffer.internalBuffer); + + buffer.status = Camera3RequestDescriptor::Status::Error; + returnBuffers.push_back(buffer.prepareToReturn()); + } + + auto bufferPtrs = std::make_unique(returnBuffers.size()); + for (const auto &[i, buffers] : utils::enumerate(returnBuffers)) + bufferPtrs[i] = &buffers; + + callbacks_->return_stream_buffers(callbacks_, returnBuffers.size(), bufferPtrs.get()); + } + { MutexLocker descriptorsLock(descriptorsMutex_); descriptors_ = {}; @@ -879,7 +915,7 @@ bool CameraDevice::isValidRequest(camera3_capture_request_t *camera3Request) con if (!camera3Request->num_output_buffers || !camera3Request->output_buffers) { - LOG(HAL, Error) << "No output buffers provided"; + LOG(HAL, Error) << "No streams requested"; return false; } @@ -892,25 +928,8 @@ bool CameraDevice::isValidRequest(camera3_capture_request_t *camera3Request) con for (uint32_t i = 0; i < camera3Request->num_output_buffers; i++) { const camera3_stream_buffer_t &outputBuffer = camera3Request->output_buffers[i]; - if (!outputBuffer.buffer || !(*outputBuffer.buffer)) { - LOG(HAL, Error) << "Invalid native handle"; - return false; - } - - const native_handle_t *handle = *outputBuffer.buffer; - constexpr int kNativeHandleMaxFds = 1024; - if (handle->numFds < 0 || handle->numFds > kNativeHandleMaxFds) { - LOG(HAL, Error) - << "Invalid number of fds (" << handle->numFds - << ") in buffer " << i; - return false; - } - - constexpr int kNativeHandleMaxInts = 1024; - if (handle->numInts < 0 || handle->numInts > kNativeHandleMaxInts) { - LOG(HAL, Error) - << "Invalid number of ints (" << handle->numInts - << ") in buffer " << i; + if (outputBuffer.buffer || *outputBuffer.buffer) { + LOG(HAL, Error) << "Unexpected native buffer handle"; return false; } @@ -940,6 +959,11 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques if (!isValidRequest(camera3Request)) return -EINVAL; + const Span buffers{ + camera3Request->output_buffers, + camera3Request->num_output_buffers + }; + /* * Save the request descriptors for use at completion time. * The descriptor and the associated memory reserved here are freed @@ -960,7 +984,73 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques descriptor->settings_ = lastSettings_; LOG(HAL, Debug) << "Queueing request " << descriptor->request_->cookie() - << " with " << descriptor->buffers_.size() << " streams"; + << " with " << buffers.size() << " streams"; + + std::unordered_map> streamBuffers; + + utils::scope_exit bufferGuard([&] { + std::vector returnBuffers; + + for (auto &[stream, buffer] : streamBuffers) { + if (!buffer) + continue; + + returnBuffers.push_back(buffer->prepareToReturn()); + } + + auto bufferPtrs = std::make_unique(returnBuffers.size()); + for (const auto &[i, buffer] : utils::enumerate(returnBuffers)) + bufferPtrs[i] = &buffer; + + callbacks_->return_stream_buffers(callbacks_, returnBuffers.size(), bufferPtrs.get()); + }); + + { + uint32_t count = buffers.size(); + + auto bufferResults = std::make_unique(count); + auto bufferRequests = std::make_unique(count); + auto returnedBuffers = std::make_unique(count); + + for (size_t i = 0; i < count; i++) { + bufferRequests[i] = { + .stream = buffers[i].stream, + .num_buffers_requested = 1, + }; + + /* Must provide storage for result. */ + bufferResults[i].output_buffers = &returnedBuffers[i]; + } + + auto ret = callbacks_->request_stream_buffers(callbacks_, + count, bufferRequests.get(), + &count, bufferResults.get()); + + for (size_t i = 0; i < count; i++) { + auto &result = bufferResults[i]; + if (result.status != CAMERA3_PS_BUF_REQ_OK) + continue; + + auto *stream = static_cast(result.stream->priv); + ASSERT(result.num_output_buffers == 1); + + [[maybe_unused]] auto [it, inserted] = streamBuffers.try_emplace(stream, + std::make_unique( + stream, result.output_buffers[0] + ) + ); + ASSERT(inserted); + } + + if (ret != CAMERA3_BUF_REQ_OK) { + /* + * \todo Improve error handling. For now every stream must get + * a buffer successfully. This is checked here so that any successfully + * allocated buffer is returned by `bufferGuard`. + */ + return -ENOBUFS; + } + } /* * Process all the Direct and Internal streams first, they map directly @@ -970,8 +1060,8 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * Since requestedStreams is an std:set<>, no duplications can happen. */ std::set requestedStreams; - for (const auto &[i, buffer] : utils::enumerate(descriptor->buffers_)) { - CameraStream *cameraStream = buffer.stream; + for (const auto &[i, buffer] : utils::enumerate(buffers)) { + auto *cameraStream = static_cast(buffer.stream->priv); camera3_stream_t *camera3Stream = cameraStream->camera3Stream(); std::stringstream ss; @@ -986,7 +1076,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * and add them to the Request if required. */ FrameBuffer *frameBuffer = nullptr; - UniqueFD acquireFence; + auto &streamBuffer = *streamBuffers.at(cameraStream); MutexLocker lock(descriptor->streamsProcessMutex_); @@ -1002,12 +1092,11 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * associate it with the Camera3RequestDescriptor for * lifetime management only. */ - buffer.frameBuffer = - createFrameBuffer(*buffer.camera3Buffer, + streamBuffer.frameBuffer = + createFrameBuffer(*streamBuffer.camera3Buffer, cameraStream->configuration().pixelFormat, cameraStream->configuration().size); - frameBuffer = buffer.frameBuffer.get(); - acquireFence = std::move(buffer.fence); + frameBuffer = streamBuffer.frameBuffer.get(); LOG(HAL, Debug) << ss.str() << " (direct)"; break; @@ -1020,11 +1109,10 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * once it has been processed. */ frameBuffer = cameraStream->getBuffer(); - buffer.internalBuffer = frameBuffer; + streamBuffer.internalBuffer = frameBuffer; LOG(HAL, Debug) << ss.str() << " (internal)"; - descriptor->pendingStreamsToProcess_.insert( - { cameraStream, &buffer }); + descriptor->pendingStreamsToProcess_.insert(cameraStream); break; } @@ -1033,10 +1121,6 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques return -ENOMEM; } - auto fence = std::make_unique(std::move(acquireFence)); - descriptor->request_->addBuffer(cameraStream->stream(), - frameBuffer, std::move(fence)); - requestedStreams.insert(cameraStream); } @@ -1045,8 +1129,8 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques * because their corresponding direct source stream is not part of this * particular request, add one here. */ - for (const auto &[i, buffer] : utils::enumerate(descriptor->buffers_)) { - CameraStream *cameraStream = buffer.stream; + for (const auto &[i, buffer] : utils::enumerate(buffers)) { + auto *cameraStream = static_cast(buffer.stream->priv); camera3_stream_t *camera3Stream = cameraStream->camera3Stream(); if (cameraStream->type() != CameraStream::Type::Mapped) @@ -1060,7 +1144,7 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques << " (mapped)"; MutexLocker lock(descriptor->streamsProcessMutex_); - descriptor->pendingStreamsToProcess_.insert({ cameraStream, &buffer }); + descriptor->pendingStreamsToProcess_.insert(cameraStream); /* * Make sure the CameraStream this stream is mapped on has been @@ -1071,15 +1155,14 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques if (requestedStreams.find(sourceStream) != requestedStreams.end()) continue; + auto &streamBuffer = *streamBuffers.at(cameraStream); + /* * If that's not the case, we need to add a buffer to the request * for this stream. */ FrameBuffer *frameBuffer = cameraStream->getBuffer(); - buffer.internalBuffer = frameBuffer; - - descriptor->request_->addBuffer(sourceStream->stream(), - frameBuffer); + streamBuffer.internalBuffer = frameBuffer; requestedStreams.insert(sourceStream); } @@ -1123,6 +1206,38 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques state_ = State::Running; } + for (auto *cameraStream : requestedStreams) { + auto &buffer = streamBuffers.at(cameraStream); + const Stream *stream = nullptr; + FrameBuffer *fb = nullptr; + UniqueFD acquireFence; + + switch (cameraStream->type()) { + case CameraStream::Type::Direct: + stream = cameraStream->stream(); + fb = buffer->frameBuffer.get(); + acquireFence = std::move(buffer->fence); + break; + case CameraStream::Type::Internal: + stream = cameraStream->stream(); + fb = buffer->internalBuffer; + break; + case CameraStream::Type::Mapped: + stream = cameraStream->sourceStream()->stream(); + fb = buffer->internalBuffer; + break; + default: + ASSERT(false); + continue; + } + + + fb->setCookie(reinterpret_cast(buffer.release())); + camera_->addBuffer(stream, fb, std::make_unique(std::move(acquireFence))); + + descriptor->request_->enableStream(stream, true); + } + Request *request = descriptor->request_.get(); { @@ -1140,6 +1255,17 @@ void CameraDevice::requestComplete(Request *request) Camera3RequestDescriptor *descriptor = reinterpret_cast(request->cookie()); + std::vector> buffers; + + for (const auto &[stream, fb] : request->buffers()) { + std::unique_ptr buffer( + reinterpret_cast(fb->cookie())); + fb->setCookie(0); + + buffer->request = descriptor; + descriptor->buffers_.push_back(std::move(*buffer)); + } + /* * Prepare the capture result for the Android camera stack. * @@ -1208,18 +1334,17 @@ void CameraDevice::requestComplete(Request *request) */ auto iter = descriptor->pendingStreamsToProcess_.begin(); while (iter != descriptor->pendingStreamsToProcess_.end()) { - CameraStream *stream = iter->first; - Camera3RequestDescriptor::StreamBuffer *buffer = iter->second; - - FrameBuffer *src = request->findBuffer(stream->stream()); - if (!src) { + CameraStream *stream = *iter; + auto it = std::find_if(descriptor->buffers_.begin(), descriptor->buffers_.end(), + [&](const auto &d) { return d.stream == stream; }); + if (it == descriptor->buffers_.end()) { LOG(HAL, Error) << "Failed to find a source stream buffer"; - setBufferStatus(*buffer, Camera3RequestDescriptor::Status::Error); iter = descriptor->pendingStreamsToProcess_.erase(iter); continue; } - buffer->srcBuffer = src; + auto *buffer = &*it; + buffer->srcBuffer = buffer->internalBuffer; ++iter; int ret = stream->process(buffer); @@ -1276,6 +1401,8 @@ void CameraDevice::completeDescriptor(Camera3RequestDescriptor *descriptor) */ void CameraDevice::sendCaptureResults() { + bool notify = false; + while (!descriptors_.empty() && !descriptors_.front()->isPending()) { auto descriptor = std::move(descriptors_.front()); descriptors_.pop(); @@ -1301,7 +1428,11 @@ void CameraDevice::sendCaptureResults() captureResult.partial_result = 1; callbacks_->process_capture_result(callbacks_, &captureResult); + notify = true; } + + if (notify) + descriptorsCv_.notify_all(); } void CameraDevice::setBufferStatus(Camera3RequestDescriptor::StreamBuffer &streamBuffer, @@ -1357,6 +1488,25 @@ void CameraDevice::streamProcessingComplete(Camera3RequestDescriptor::StreamBuff completeDescriptor(streamBuffer->request); } +void CameraDevice::signalStreamFlush([[maybe_unused]] libcamera::Span streams) +{ + /* + * `streams` is ignored because it is not possible to selectively + * retrieve all buffers a given stream. + */ + + { + libcamera::MutexLocker locker(descriptorsMutex_); + + descriptorsCv_.wait(locker, [&]() LIBCAMERA_TSA_REQUIRES(descriptorsMutex_) { + return descriptors_.empty(); + }); + } + + /* \todo Is stopping ok here? */ + stop(); +} + std::string CameraDevice::logPrefix() const { return "'" + camera_->id() + "'"; diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 194ca30304..c0f8b88ee5 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,8 @@ public: void streamProcessingComplete(Camera3RequestDescriptor::StreamBuffer *bufferStream, Camera3RequestDescriptor::Status status); + void signalStreamFlush(libcamera::Span streams); + protected: std::string logPrefix() const override; @@ -118,6 +121,7 @@ private: std::vector streams_; libcamera::Mutex descriptorsMutex_ LIBCAMERA_TSA_ACQUIRED_AFTER(stateMutex_); + libcamera::ConditionVariable descriptorsCv_; std::queue> descriptors_ LIBCAMERA_TSA_GUARDED_BY(descriptorsMutex_); diff --git a/src/android/camera_hal_manager.cpp b/src/android/camera_hal_manager.cpp index a7a2571754..6b9a1007ee 100644 --- a/src/android/camera_hal_manager.cpp +++ b/src/android/camera_hal_manager.cpp @@ -259,7 +259,7 @@ int CameraHalManager::getCameraInfo(unsigned int id, struct camera_info *info) info->facing = camera->facing(); info->orientation = camera->orientation(); - info->device_version = CAMERA_DEVICE_API_VERSION_3_3; + info->device_version = CAMERA_DEVICE_API_VERSION_3_6; info->resource_cost = 0; info->static_camera_characteristics = camera->getStaticMetadata(); info->conflicting_devices = nullptr; diff --git a/src/android/camera_ops.cpp b/src/android/camera_ops.cpp index 1656fac7ab..d8f0f715b2 100644 --- a/src/android/camera_ops.cpp +++ b/src/android/camera_ops.cpp @@ -77,6 +77,18 @@ static int hal_dev_flush(const struct camera3_device *dev) return 0; } +static void hal_dev_signal_stream_flush(const struct camera3_device *dev, + uint32_t num_streams, + const camera3_stream_t* const* streams) +{ + if (!dev) + return; + + CameraDevice *camera = reinterpret_cast(dev->priv); + + camera->signalStreamFlush({ streams, num_streams }); +} + int hal_dev_close(hw_device_t *hw_device) { if (!hw_device) @@ -99,7 +111,7 @@ camera3_device_ops hal_dev_ops = { .get_metadata_vendor_tag_ops = nullptr, .dump = hal_dev_dump, .flush = hal_dev_flush, - .signal_stream_flush = nullptr, + .signal_stream_flush = hal_dev_signal_stream_flush, .is_reconfiguration_required = nullptr, .reserved = {}, }; diff --git a/src/android/camera_request.cpp b/src/android/camera_request.cpp index 6dfe692f09..91bd618006 100644 --- a/src/android/camera_request.cpp +++ b/src/android/camera_request.cpp @@ -114,21 +114,6 @@ Camera3RequestDescriptor::Camera3RequestDescriptor( { frameNumber_ = camera3Request->frame_number; - /* Copy the camera3 request stream information for later access. */ - const Span buffers{ - camera3Request->output_buffers, - camera3Request->num_output_buffers - }; - - buffers_.reserve(buffers.size()); - - for (const camera3_stream_buffer_t &buffer : buffers) { - CameraStream *stream = - static_cast(buffer.stream->priv); - - buffers_.emplace_back(stream, buffer, this); - } - /* Clone the controls associated with the camera3 request. */ settings_ = CameraMetadata(camera3Request->settings); @@ -180,10 +165,9 @@ Camera3RequestDescriptor::~Camera3RequestDescriptor() = default; * \brief Back pointer to the Camera3RequestDescriptor to which the StreamBuffer belongs */ Camera3RequestDescriptor::StreamBuffer::StreamBuffer( - CameraStream *cameraStream, const camera3_stream_buffer_t &buffer, - Camera3RequestDescriptor *requestDescriptor) + CameraStream *cameraStream, const camera3_stream_buffer_t &buffer) : stream(cameraStream), camera3Buffer(buffer.buffer), - fence(buffer.acquire_fence), request(requestDescriptor) + fence(buffer.acquire_fence) { } diff --git a/src/android/camera_request.h b/src/android/camera_request.h index 164b095b28..1a5393b1d6 100644 --- a/src/android/camera_request.h +++ b/src/android/camera_request.h @@ -7,8 +7,8 @@ #pragma once -#include #include +#include #include #include @@ -36,8 +36,7 @@ public: struct StreamBuffer { StreamBuffer(CameraStream *stream, - const camera3_stream_buffer_t &buffer, - Camera3RequestDescriptor *request); + const camera3_stream_buffer_t &buffer); ~StreamBuffer(); StreamBuffer(StreamBuffer &&); @@ -53,14 +52,14 @@ public: libcamera::FrameBuffer *internalBuffer = nullptr; const libcamera::FrameBuffer *srcBuffer = nullptr; std::unique_ptr dstBuffer; - Camera3RequestDescriptor *request; + Camera3RequestDescriptor *request = nullptr; private: LIBCAMERA_DISABLE_COPY(StreamBuffer) }; /* Keeps track of streams requiring post-processing. */ - std::map pendingStreamsToProcess_ + std::unordered_set pendingStreamsToProcess_ LIBCAMERA_TSA_GUARDED_BY(streamsProcessMutex_); libcamera::Mutex streamsProcessMutex_; From patchwork Mon Jun 29 16:30:16 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27131 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 52955C3261 for ; Mon, 29 Jun 2026 16:31:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DAB8765FDE; Mon, 29 Jun 2026 18:31:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="fGZbTU1N"; 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 6161F65F79 for ; Mon, 29 Jun 2026 18:30:34 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 33F58E91 for ; Mon, 29 Jun 2026 18:29:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750591; bh=GptUHR2d3aB72tskvga2gusJRJ8q9ubPKt1Al1jYqgA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=fGZbTU1NvVAdSBXRPxmSxvFtXFAiONSKyxDN6mEY0ne6DoOphYoBeT2njWgYsA/Am V+o7UENEOnwjVJ+DIav3Gmv0H2uakiH0/7Zy+oYEPJLlfMt5fYxai+Ran3KtaXOtrP sCQZvz5th7bs3+/DuxnpjRzUXjx3gxSNbpF93+Ug= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 53/54] libcamera: request: Remove `addBuffer()` Date: Mon, 29 Jun 2026 18:30:16 +0200 Message-ID: <20260629163017.863145-54-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" There are no callers, so the stub can now be removed. TODO: what of `FrameBuffer::request` ? Signed-off-by: Barnabás Pőcze --- include/libcamera/request.h | 2 -- src/libcamera/fence.cpp | 10 ++++------ src/libcamera/framebuffer.cpp | 8 +++----- src/libcamera/request.cpp | 13 ------------- 4 files changed, 7 insertions(+), 26 deletions(-) diff --git a/include/libcamera/request.h b/include/libcamera/request.h index 462611da59..14b9ee6f12 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -47,8 +47,6 @@ public: ControlList &controls() { return controls_; } const ControlList &metadata() const; const BufferMap &buffers() const { return bufferMap_; } - int addBuffer(const Stream *stream, FrameBuffer *buffer, - std::unique_ptr &&fence = {}); FrameBuffer *findBuffer(const Stream *stream) const; void enableStream(const Stream *stream, bool enabled); diff --git a/src/libcamera/fence.cpp b/src/libcamera/fence.cpp index 92d1b37366..8dc748b176 100644 --- a/src/libcamera/fence.cpp +++ b/src/libcamera/fence.cpp @@ -52,12 +52,10 @@ namespace libcamera { * * A Fence is constructed with a UniqueFD whose ownership is moved in the Fence. * A FrameBuffer can be associated with a Fence by passing it to the - * Request::addBuffer() function, which will move the Fence into the FrameBuffer - * itself. Once a Request is queued to the Camera, a preparation phase - * guarantees that before actually applying the Request to the hardware, all the - * valid fences of the frame buffers in a Request are correctly signalled. Once - * a Fence has completed, the library will release the FrameBuffer fence so that - * application won't be allowed to access it. + * Camera::addBuffer() function, which will move the Fence into the FrameBuffer + * itself. The buffer will not be used in any completed request until the fence + * is signalled. Once a Fence has completed, the library will release the FrameBuffer + * fence so that application won't be allowed to access it. * * An optional timeout can be started while waiting for a fence to complete. If * waiting on a Fence fails for whatever reason, the FrameBuffer's fence is not diff --git a/src/libcamera/framebuffer.cpp b/src/libcamera/framebuffer.cpp index 55ca24c8a3..61a5959a96 100644 --- a/src/libcamera/framebuffer.cpp +++ b/src/libcamera/framebuffer.cpp @@ -151,7 +151,7 @@ FrameBuffer::Private::~Private() * The intended callers of this function are buffer completion handlers that * need to associate a buffer to the request it belongs to. * - * A FrameBuffer is associated to a request by Request::addBuffer() and the + * A FrameBuffer is associated to a request by the libcamera core and the * association is valid until the buffer completes. The returned request * pointer is valid only during that interval. * @@ -164,9 +164,7 @@ FrameBuffer::Private::~Private() * \brief Set the request this buffer belongs to * \param[in] request Request to set * - * For buffers added to requests by applications, this function is called by - * Request::addBuffer() or Request::reuse(). For buffers internal to pipeline - * handlers, it is called by the pipeline handlers themselves. + * For buffers internal to pipeline handlers, it is called by the pipeline handlers themselves. */ /** @@ -439,7 +437,7 @@ void FrameBuffer::setCookie(uint64_t cookie) * * If buffer with a Fence completes with errors due to a failure in handling * the fence, applications are responsible for releasing the Fence before - * calling Request::addBuffer() again. + * reusing the buffer. * * \return A unique pointer to the Fence if set, or nullptr if the fence has * been released already diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 5d28ac80df..f886ec0e4e 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -287,19 +287,6 @@ const ControlList &Request::metadata() const * \return The map of Stream to FrameBuffer */ -/** - * \brief Add a FrameBuffer with its associated Stream to the Request - * \param[in] stream The stream the buffer belongs to - * \param[in] buffer The FrameBuffer to add to the request - * \param[in] fence The optional fence - */ -int Request::addBuffer(const Stream *, FrameBuffer *, - std::unique_ptr &&) -{ - LOG(Request, Fatal) << "REMOVED"; - return -ENOTSUP; -} - /** * \var Request::bufferMap_ * \brief Mapping of streams to buffers for this request From patchwork Mon Jun 29 16:30:17 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 27132 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 E0207C3306 for ; Mon, 29 Jun 2026 16:31:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7101F65FDA; Mon, 29 Jun 2026 18:31:43 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="PAjTMNpp"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9229065F7C for ; Mon, 29 Jun 2026 18:30:34 +0200 (CEST) Received: from pb-laptop.local (185.221.140.128.nat.pool.zt.hu [185.221.140.128]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 6CDBB8D4 for ; Mon, 29 Jun 2026 18:29:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1782750591; bh=EAh0Od/mEcAreY6/dYpAHoMsLxIMULNBQsY6rjYG4HM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=PAjTMNppzc96DM9V7twSUHpRq7Ec6TVkeL+sz+4QudV565RmIjxndeoslDVrG8HNg r/gf8EA/u6r1Tf17+094V7OoVFU+pDP+065631qAKZJ0qNJg//jZ5dQ6weHQw57nbs 4F89WW/djUJMxtjQIpeUayiXnAhAomwn9ZAmtWV4= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Subject: [RFC PATCH v1 54/54] test: fence: Enable Date: Mon, 29 Jun 2026 18:30:17 +0200 Message-ID: <20260629163017.863145-55-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> References: <20260629163017.863145-1-barnabas.pocze@ideasonboard.com> MIME-Version: 1.0 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" Enable the "fence" test and adjust it for the new buffer pool interface. Signed-off-by: Barnabás Pőcze --- test/fence.cpp | 214 +++++++++++++++++++++++------------------------ test/meson.build | 2 +- 2 files changed, 104 insertions(+), 112 deletions(-) diff --git a/test/fence.cpp b/test/fence.cpp index 8095b22895..50ec6cbf11 100644 --- a/test/fence.cpp +++ b/test/fence.cpp @@ -36,10 +36,9 @@ protected: int run() override; private: - int validateExpiredRequest(Request *request); + int validateExpiredBuffer(FrameBuffer *buffer); int validateRequest(Request *request); void requestComplete(Request *request); - void requestRequeue(Request *request); void signalFence(); @@ -55,15 +54,11 @@ private: Stream *stream_; bool expectedCompletionResult_ = true; - bool setFence_ = true; - /* - * Request IDs track the number of requests that have completed. They - * are one-based, and don't wrap. - */ unsigned int completedRequestId_; - unsigned int signalledRequestId_; - unsigned int expiredRequestId_; + unsigned int queuedRequests_ = 0; + FrameBuffer *testBuffer_ = nullptr; + unsigned testBufferSeen_ = 0; unsigned int nbuffers_; int efd2_; @@ -123,38 +118,30 @@ int FenceTest::init() if (allocator_->allocate(stream_) < 0) return TestFail; - nbuffers_ = allocator_->buffers(stream_).size(); + const auto &buffers = allocator_->buffers(stream_); + nbuffers_ = buffers.size(); if (nbuffers_ < 2) { cerr << "Not enough buffers available" << endl; return TestFail; } completedRequestId_ = 0; + queuedRequests_ = 0; /* - * All but two requests are queued without a fence. Request - * expiredRequestId_ will be queued with a fence that we won't signal - * (which is then expected to expire), and request signalledRequestId_ - * will be queued with a fence that gets signalled. Select nbuffers_ - * and nbuffers_ * 2 for those two requests, to space them by a few - * frames while still not requiring a long time for the test to - * complete. + * The buffer to use for testing. It will be queued 3 times: + * * first, without any fence + * * second, with a fence that is signalled + * * third,with a fence that won't be signalled */ - expiredRequestId_ = nbuffers_; - signalledRequestId_ = nbuffers_ * 2; + testBuffer_ = buffers.front().get(); + testBufferSeen_ = 0; return TestPass; } -int FenceTest::validateExpiredRequest(Request *request) +int FenceTest::validateExpiredBuffer(FrameBuffer *buffer) { - /* The last request is expected to fail. */ - if (request->status() != Request::RequestCancelled) { - cerr << "The last request should have failed: " << endl; - return TestFail; - } - - FrameBuffer *buffer = request->buffers().begin()->second; std::unique_ptr fence = buffer->releaseFence(); if (!fence) { cerr << "The expired fence should be present" << endl; @@ -198,50 +185,21 @@ int FenceTest::validateRequest(Request *request) return TestPass; } -void FenceTest::requestRequeue(Request *request) +void FenceTest::requestComplete(Request *request) { const Request::BufferMap &buffers = request->buffers(); const Stream *stream = buffers.begin()->first; FrameBuffer *buffer = buffers.begin()->second; - request->reuse(); - - if (completedRequestId_ == signalledRequestId_ - nbuffers_ && setFence_) { - /* - * This is the request that will be used to test fence - * signalling when it completes next time. Add a fence to it, - * using efd2_. The main loop will signal the fence by using a - * timer to write to the efd2_ file descriptor before the fence - * expires. - */ - std::unique_ptr fence = - std::make_unique(std::move(eventFd2_)); - request->addBuffer(stream, buffer, std::move(fence)); - } else { - /* All the other requests continue to operate without fences. */ - request->addBuffer(stream, buffer); - } - - camera_->queueRequest(request); -} + completedRequestId_ += 1; -void FenceTest::requestComplete(Request *request) -{ - completedRequestId_++; + if (buffer == testBuffer_) + testBufferSeen_ += 1; - /* - * Request expiredRequestId_ is expected to fail as its fence has not - * been signalled. - * - * Validate the fence status but do not re-queue it. - */ - if (completedRequestId_ == expiredRequestId_) { - if (validateExpiredRequest(request) != TestPass) - expectedCompletionResult_ = false; - - dispatcher_->interrupt(); - return; - } + cout << "completedRequestId:" << completedRequestId_ << " " + << "buffer:" << buffer << " " + << "testBufferSeen:" << testBufferSeen_ + << endl; /* Validate all other requests. */ if (validateRequest(request) != TestPass) { @@ -251,12 +209,41 @@ void FenceTest::requestComplete(Request *request) return; } - requestRequeue(request); + if (completedRequestId_ % nbuffers_ == 0) { + for (const auto &b : allocator_->buffers(stream_)) { + std::unique_ptr fence; + + if (b.get() == testBuffer_) { + if (testBufferSeen_ == 1) { + /* This fence will be signalled. */ + assert(eventFd2_.isValid()); + fence = std::make_unique(std::move(eventFd2_)); + } else if (testBufferSeen_ == 2) { + /* This fence won't be signalled. */ + assert(eventFd_.isValid()); + fence = std::make_unique(std::move(eventFd_)); + } + } + + cout << "adding buffer:" << b.get() << " fence:" << (fence ? fence->fd().get() : -1) << endl; + camera_->addBuffer(stream_, b.get(), std::move(fence)); + } + } + + if (testBufferSeen_ == 1 && completedRequestId_ == 2 * nbuffers_ - 1) { + cout << "signalling fence:" << efd2_ << endl; + signalFence(); + } + + request->reuse(); + + if (queuedRequests_ < 3 * nbuffers_ - 1) { + cout << "queueing request:" << request << endl; + request->enableStream(stream, true); + camera_->queueRequest(request); + queuedRequests_ += 1; + } - /* - * Interrupt the dispatcher to return control to the main loop and - * activate the fenceTimer. - */ dispatcher_->interrupt(); } @@ -269,9 +256,6 @@ void FenceTest::signalFence() ret = write(efd2_, &value, sizeof(value)); if (ret != sizeof(value)) cerr << "Failed to signal fence" << endl; - - setFence_ = false; - dispatcher_->processEvents(); } int FenceTest::run() @@ -283,26 +267,7 @@ int FenceTest::run() return TestFail; } - int ret; - if (i == expiredRequestId_ - 1) { - /* This request will have a fence, and it will expire. */ - std::unique_ptr fence = - std::make_unique(std::move(eventFd_)); - if (!fence->isValid()) { - cerr << "Fence should be valid" << endl; - return TestFail; - } - - ret = request->addBuffer(stream_, buffer.get(), std::move(fence)); - } else { - /* All other requests will have no Fence. */ - ret = request->addBuffer(stream_, buffer.get()); - } - - if (ret) { - cerr << "Failed to associate buffer with request" << endl; - return TestFail; - } + request->enableStream(stream_, true); requests_.push_back(std::move(request)); } @@ -314,8 +279,14 @@ int FenceTest::run() return TestFail; } - for (std::unique_ptr &request : requests_) { - if (camera_->queueRequest(request.get())) { + for (const auto &[i, buffer] : utils::enumerate(allocator_->buffers(stream_))) { + int ret = camera_->addBuffer(stream_, buffer.get()); + if (ret) { + cerr << "Failed to associate buffer with request" << endl; + return TestFail; + } + + if (camera_->queueRequest(requests_[i].get())) { cerr << "Failed to queue request" << endl; return TestFail; } @@ -323,38 +294,59 @@ int FenceTest::run() expectedCompletionResult_ = true; - /* This timer serves to signal fences associated with "signalledRequestId_" */ - Timer fenceTimer; - fenceTimer.timeout.connect(this, &FenceTest::signalFence); - /* * Loop long enough for all requests to complete, allowing 500ms per * request. */ Timer timer; - timer.start(500ms * (signalledRequestId_ + 1)); - while (timer.isRunning() && expectedCompletionResult_ && - completedRequestId_ <= signalledRequestId_ + 1) { - if (completedRequestId_ == signalledRequestId_ - 1 && setFence_) - /* - * The request just before signalledRequestId_ has just - * completed. Request signalledRequestId_ has been - * queued with a fence, and libcamera is likely already - * waiting on the fence, or will soon. Start the timer - * to signal the fence in 10 msec. - */ - fenceTimer.start(10ms); + timer.start(500ms * (3 + 1) * nbuffers_); + for (;;) { + if (!timer.isRunning() || !expectedCompletionResult_) + break; + + if (completedRequestId_ == 3 * nbuffers_ - 1 && testBufferSeen_ == 2) + break; dispatcher_->processEvents(); } camera_->requestCompleted.disconnect(); - if (camera_->stop()) { + bool testBufferFound = false; + camera_->bufferCompleted.connect(this, [&](Request *request, [[maybe_unused]] const Stream *stream, FrameBuffer *buffer) { + if (request) + return; + + if (buffer == testBuffer_) { + if (validateExpiredBuffer(buffer) != TestPass) + expectedCompletionResult_ = false; + testBufferFound = true; + } + }); + + int ret = camera_->stop(); + camera_->bufferCompleted.disconnect(this); + + if (ret) { cerr << "Failed to stop camera" << endl; return TestFail; } + if (testBufferSeen_ != 2) { + cerr << "Test buffer not seen exactly twice" << endl; + return TestFail; + } + + if (completedRequestId_ != 3 * nbuffers_ - 1) { + cerr << "Test buffer not seen exactly twice" << endl; + return TestFail; + } + + if (!testBufferFound) { + cerr << "Buffer with non-signalled fence not returned" << endl; + return TestFail; + } + return expectedCompletionResult_ ? TestPass : TestFail; } diff --git a/test/meson.build b/test/meson.build index b51bd6ef66..e4450625ee 100644 --- a/test/meson.build +++ b/test/meson.build @@ -80,7 +80,7 @@ internal_tests = [ ] internal_non_parallel_tests = [ - # {'name': 'fence', 'sources': ['fence.cpp']}, + {'name': 'fence', 'sources': ['fence.cpp']}, {'name': 'mapped-buffer', 'sources': ['mapped-buffer.cpp']}, ]