From patchwork Fri Dec 4 15:31:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10560 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 EBE03BE177 for ; Fri, 4 Dec 2020 15:31:29 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B81F0635F1; Fri, 4 Dec 2020 16:31:29 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="lHn2nQXH"; dkim-atps=neutral Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 42CA1635D6 for ; Fri, 4 Dec 2020 16:31:27 +0100 (CET) Received: by mail-wr1-x430.google.com with SMTP id k14so5734280wrn.1 for ; Fri, 04 Dec 2020 07:31:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1HtdDSULhK9SeVwOWHg5T+PVgm3b5ORCZg0yBjiniz8=; b=lHn2nQXHOHjRSYre4SjxY22Av6ifqxOJKBDBs3rjDipeJX4qiL1DNjkAgFzvMwU4Sg 0bGRT+SbJwn7zYEhHj46xJwwMKWrf7iI7/nEZFzEwIIo/Ax7IXeWIUSXipIwxog15Nk8 Vw9kYTgS1FDaz5k0t/pVwglI6h5ti95CLWTZhZvcjDhkz0CoGKZDFfFCLKXhYzWy+eyP +FZCryANHWKADVxHEHhBT5xK8jOjIumVs6KBv8rJUOVa3EhTO18Vs0MfUp6XnrBFae4f /sRZLv8n8HNtRHp3mE7+eSW43qDWv4OF7m2IkFSOGMFKFGHQ1+aQeM+CEEkqDiZRCvZ5 zX2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1HtdDSULhK9SeVwOWHg5T+PVgm3b5ORCZg0yBjiniz8=; b=IH4JccblpmkoDjsWibwaub8VKt8yUQHF5sD/KDcUzWFF81ORvc/4idLqb30B9qEYNs JZfIC9D51/eV7nweKtS9lEn7RjVGOYgJdJcGs36MffQOBxap8XQyocaDOFu6cjJbIRyN kXyq4IN8FxuSpoenQfb1QdkrC6LC9AZzH0PE2NKDL0iGrXK2FsTpnU6GWh9gQkgBXSJ0 MZMWAMBqbzPVQ+duyESI5mUdG3Jp7nZPvZztNiyNH9ReukQ8U1pJajZIJjmSvyJPP4JZ mR4CvJ5/D2Dp6iZU0cYzLKacZu7mLgYodjkkxHRCGJ3yWOFD6qO2tO39WQBdN5RcB2Dp fdxw== X-Gm-Message-State: AOAM533rmhF6mNTx3Q9fP+GudSVvyT3Wutnx7mr4SeKjVewZYsrJohEY uLQuexSXtz376skCM+CL4hU7O4mup9Wp0g== X-Google-Smtp-Source: ABdhPJzoNeJ5xHPr9JvCJszF7nOMfkakINQLLEyb1DuHTLLUMCRUkQ5+rhka2G3fG+un257y3781NA== X-Received: by 2002:a5d:4b09:: with SMTP id v9mr5697824wrq.394.1607095886244; Fri, 04 Dec 2020 07:31:26 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id x66sm3465426wmg.26.2020.12.04.07.31.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Dec 2020 07:31:25 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Fri, 4 Dec 2020 15:31:19 +0000 Message-Id: <20201204153121.66136-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201204153121.66136-1-naush@raspberrypi.com> References: <20201204153121.66136-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 1/3] libcamera: pipeline: Pass libcamera controls into pipeline_handler::start() 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" Applications now have the ability to pass in controls that need to be applied on startup, rather than doing it through Request where there might be some frames of delay in getting the controls applied. This commit adds the ability to pass in a set of libcamera controls into the pipeline handlers through the pipeline_handler::start() method. These controls are provided by the application through the camera::start() public API. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Tested-by: David Plowman Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- Documentation/guides/pipeline-handler.rst | 4 ++-- include/libcamera/camera.h | 2 +- include/libcamera/internal/pipeline_handler.h | 2 +- src/libcamera/camera.cpp | 11 ++++++----- src/libcamera/pipeline/ipu3/ipu3.cpp | 4 ++-- src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 4 ++-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 4 ++-- src/libcamera/pipeline/simple/simple.cpp | 4 ++-- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 4 ++-- src/libcamera/pipeline/vimc/vimc.cpp | 4 ++-- src/libcamera/pipeline_handler.cpp | 1 + 11 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst index 57aee455..63275a12 100644 --- a/Documentation/guides/pipeline-handler.rst +++ b/Documentation/guides/pipeline-handler.rst @@ -209,7 +209,7 @@ methods for the overridden class members. int exportFrameBuffers(Camera *camera, Stream *stream, std::vector> *buffers) override; - int start(Camera *camera) override; + int start(Camera *camera, ControlList *controls) override; void stop(Camera *camera) override; int queueRequestDevice(Camera *camera, Request *request) override; @@ -239,7 +239,7 @@ methods for the overridden class members. return -1; } - int PipelineHandlerVivid::start(Camera *camera) + int PipelineHandlerVivid::start(Camera *camera, ControlList *controls) { return -1; } diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h index 5c5f1a05..f94f8599 100644 --- a/include/libcamera/camera.h +++ b/include/libcamera/camera.h @@ -103,7 +103,7 @@ public: std::unique_ptr createRequest(uint64_t cookie = 0); int queueRequest(Request *request); - int start(); + int start(ControlList *controls = nullptr); int stop(); private: diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index c12c8904..bd3c4a81 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -78,7 +78,7 @@ public: virtual int exportFrameBuffers(Camera *camera, Stream *stream, std::vector> *buffers) = 0; - virtual int start(Camera *camera) = 0; + virtual int start(Camera *camera, ControlList *controls) = 0; virtual void stop(Camera *camera) = 0; int queueRequest(Camera *camera, Request *request); diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp index bcb7b046..ffb63fb2 100644 --- a/src/libcamera/camera.cpp +++ b/src/libcamera/camera.cpp @@ -1003,9 +1003,10 @@ int Camera::queueRequest(Request *request) /** * \brief Start capture from camera * - * Start the camera capture session. Once the camera is started the application - * can queue requests to the camera to process and return to the application - * until the capture session is terminated with \a stop(). + * Start the camera capture session, optionally providing a list of controls to + * action before starting. Once the camera is started the application can queue + * requests to the camera to process and return to the application until the + * capture session is terminated with \a stop(). * * \context This function may only be called when the camera is in the * Configured state as defined in \ref camera_operation, and shall be @@ -1016,7 +1017,7 @@ int Camera::queueRequest(Request *request) * \retval -ENODEV The camera has been disconnected from the system * \retval -EACCES The camera is not in a state where it can be started */ -int Camera::start() +int Camera::start(ControlList *controls) { Private *const d = LIBCAMERA_D_PTR(); @@ -1027,7 +1028,7 @@ int Camera::start() LOG(Camera, Debug) << "Starting capture"; ret = d->pipe_->invokeMethod(&PipelineHandler::start, - ConnectionTypeBlocking, this); + ConnectionTypeBlocking, this, controls); if (ret) return ret; diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 4cedb32b..8a1918d5 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -105,7 +105,7 @@ public: int exportFrameBuffers(Camera *camera, Stream *stream, std::vector> *buffers) override; - int start(Camera *camera) override; + int start(Camera *camera, ControlList *controls) override; void stop(Camera *camera) override; int queueRequestDevice(Camera *camera, Request *request) override; @@ -596,7 +596,7 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera) return 0; } -int PipelineHandlerIPU3::start(Camera *camera) +int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] ControlList *controls) { IPU3CameraData *data = cameraData(camera); CIO2Device *cio2 = &data->cio2_; diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 6fcdf557..9937db73 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -242,7 +242,7 @@ public: int exportFrameBuffers(Camera *camera, Stream *stream, std::vector> *buffers) override; - int start(Camera *camera) override; + int start(Camera *camera, ControlList *controls) override; void stop(Camera *camera) override; int queueRequestDevice(Camera *camera, Request *request) override; @@ -731,7 +731,7 @@ int PipelineHandlerRPi::exportFrameBuffers([[maybe_unused]] Camera *camera, Stre return ret; } -int PipelineHandlerRPi::start(Camera *camera) +int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *controls) { RPiCameraData *data = cameraData(camera); int ret; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 6e74a49a..4e959fde 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -187,7 +187,7 @@ public: int exportFrameBuffers(Camera *camera, Stream *stream, std::vector> *buffers) override; - int start(Camera *camera) override; + int start(Camera *camera, ControlList *controls) override; void stop(Camera *camera) override; int queueRequestDevice(Camera *camera, Request *request) override; @@ -832,7 +832,7 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera) return 0; } -int PipelineHandlerRkISP1::start(Camera *camera) +int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] ControlList *controls) { RkISP1CameraData *data = cameraData(camera); int ret; diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 0d3078f7..b047aeb9 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -126,7 +126,7 @@ public: int exportFrameBuffers(Camera *camera, Stream *stream, std::vector> *buffers) override; - int start(Camera *camera) override; + int start(Camera *camera, ControlList *controls) override; void stop(Camera *camera) override; bool match(DeviceEnumerator *enumerator) override; @@ -646,7 +646,7 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, return data->video_->exportBuffers(count, buffers); } -int SimplePipelineHandler::start(Camera *camera) +int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] ControlList *controls) { SimpleCameraData *data = cameraData(camera); V4L2VideoDevice *video = data->video_; diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 0f3241cc..87b0f03d 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -76,7 +76,7 @@ public: int exportFrameBuffers(Camera *camera, Stream *stream, std::vector> *buffers) override; - int start(Camera *camera) override; + int start(Camera *camera, ControlList *controls) override; void stop(Camera *camera) override; int queueRequestDevice(Camera *camera, Request *request) override; @@ -236,7 +236,7 @@ int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream, return data->video_->exportBuffers(count, buffers); } -int PipelineHandlerUVC::start(Camera *camera) +int PipelineHandlerUVC::start(Camera *camera, [[maybe_unused]] ControlList *controls) { UVCCameraData *data = cameraData(camera); unsigned int count = data->stream_.configuration().bufferCount; diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index 914b6b54..d81b8598 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -92,7 +92,7 @@ public: int exportFrameBuffers(Camera *camera, Stream *stream, std::vector> *buffers) override; - int start(Camera *camera) override; + int start(Camera *camera, ControlList *controls) override; void stop(Camera *camera) override; int queueRequestDevice(Camera *camera, Request *request) override; @@ -313,7 +313,7 @@ int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream, return data->video_->exportBuffers(count, buffers); } -int PipelineHandlerVimc::start(Camera *camera) +int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] ControlList *controls) { VimcCameraData *data = cameraData(camera); unsigned int count = data->stream_.configuration().bufferCount; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 894200ee..c75ebbd5 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -351,6 +351,7 @@ const ControlList &PipelineHandler::properties(const Camera *camera) const * \fn PipelineHandler::start() * \brief Start capturing from a group of streams * \param[in] camera The camera to start + * \param[in] controls Controls to be applied before starting the Camera * * Start the group of streams that have been configured for capture by * \a configure(). The intended caller of this method is the Camera class which From patchwork Fri Dec 4 15:31:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10562 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 137E2BE178 for ; Fri, 4 Dec 2020 15:31:31 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5F48B635FA; Fri, 4 Dec 2020 16:31:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="PhrssKzj"; dkim-atps=neutral Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 457CC635D6 for ; Fri, 4 Dec 2020 16:31:29 +0100 (CET) Received: by mail-wr1-x42f.google.com with SMTP id g14so5690012wrm.13 for ; Fri, 04 Dec 2020 07:31:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JNvPjsKqf/Ia/ymHimIOfo8y4FhZtcQ109ptuF8ZPzE=; b=PhrssKzjAScSl1m7RmmQbst8C74ANFrlNJIrt5VlsSegMcENPc4Y8ZLZKSGNwAcqqQ 5sIhLDL2h72NerlJeyLcd7rXpw7vwOUFie2cVFX4VPOCT3+AyHSsnqje4KAhd/1JeJy3 rDtXzvnmJMcQ54e1xht49EVfw4u969XJR4AduKOJaRR1dTxMiOPgS3Hf7FTMYwfTodb4 HSIul2qtsex8hGiZtezWL+JosGuvW0idMbkjX1Y6xP+nX9oahmORJRRwXRuk+J7VSA6j gSOPru0GSApPYBuxkbblmRbgbtGAwsqR5UCpWKZFBuZm/duk4DeMTwzPPuiBsyjVgSIR rSxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JNvPjsKqf/Ia/ymHimIOfo8y4FhZtcQ109ptuF8ZPzE=; b=kpkhzxIyCQaWM08Lzl7uDuqBtfjYGeIc4nduJg6KoGxhHXsrzsJlSXmVzZMuln54g1 fdE3+UEt7ItmTt6bVzwBaovxVomYLohR/csM063B3UVcUbQAS1G87IMgg0CW9dhydoIr xa1mi7t2vj6E7nu1d51/1MwgDXc0XMBS3kSxVnwD3MKpb+/ih4dajDUE5vDtbgMaMVY+ FB/bUJjsCCXQZL3rDxLdFURg11z7s0x3TefbmR4j21JS2FP8Ot40j0Q6F6Car+JoGIYT 7atzEFucsWXtgwVVoZcpIzAv6URRx7rZDE+IdtReIw1huuKkfw4QtSTz5+db6vrM4HAc n2+A== X-Gm-Message-State: AOAM5308Q7ukoilyVtnRpRxlYS98cqktB6Zoxf1EUzv0PX7OorXImmVa 6+R853D30E1UySGIkngR9R2YjlRE5kT7fQ== X-Google-Smtp-Source: ABdhPJxSTpZm06d7NW8RrkLwj1zNROjNI56vySwQeHIqZC2TUUOwBXSSpDGSYwbpqNGMHsz/PpULOg== X-Received: by 2002:adf:f9c5:: with SMTP id w5mr5452508wrr.69.1607095887171; Fri, 04 Dec 2020 07:31:27 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id x66sm3465426wmg.26.2020.12.04.07.31.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Dec 2020 07:31:26 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Fri, 4 Dec 2020 15:31:20 +0000 Message-Id: <20201204153121.66136-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201204153121.66136-1-naush@raspberrypi.com> References: <20201204153121.66136-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 2/3] libcamera: ipa: Pass a set of controls and return results from ipa::start() 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 change allows controls passed into PipelineHandler::start to be forwarded onto IPAInterface::start(). We also add a return channel if the pipeline handler must action any of these controls, e.g. setting the analogue gain or shutter speed in the sensor device. todo: The IPA interface wrapper needs a translation for passing IPAOperationData into start() and configure() Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Tested-by: David Plowman Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- include/libcamera/internal/ipa_context_wrapper.h | 3 ++- include/libcamera/ipa/ipa_interface.h | 3 ++- src/ipa/libipa/ipa_interface_wrapper.cpp | 4 +++- src/ipa/raspberrypi/raspberrypi.cpp | 5 +++-- src/ipa/rkisp1/rkisp1.cpp | 3 ++- src/ipa/vimc/vimc.cpp | 6 ++++-- src/libcamera/ipa_context_wrapper.cpp | 5 +++-- src/libcamera/ipa_interface.cpp | 7 +++++++ src/libcamera/pipeline/raspberrypi/raspberrypi.cpp | 7 +++++-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 3 ++- src/libcamera/pipeline/vimc/vimc.cpp | 3 ++- src/libcamera/proxy/ipa_proxy_linux.cpp | 3 ++- src/libcamera/proxy/ipa_proxy_thread.cpp | 13 ++++++++----- test/ipa/ipa_interface_test.cpp | 3 ++- test/ipa/ipa_wrappers_test.cpp | 5 +++-- 15 files changed, 50 insertions(+), 23 deletions(-) diff --git a/include/libcamera/internal/ipa_context_wrapper.h b/include/libcamera/internal/ipa_context_wrapper.h index 8f767e84..ec27e48e 100644 --- a/include/libcamera/internal/ipa_context_wrapper.h +++ b/include/libcamera/internal/ipa_context_wrapper.h @@ -20,7 +20,8 @@ public: ~IPAContextWrapper(); int init(const IPASettings &settings) override; - int start() override; + int start(const IPAOperationData &data, + IPAOperationData *result) override; void stop() override; void configure(const CameraSensorInfo &sensorInfo, const std::map &streamConfig, diff --git a/include/libcamera/ipa/ipa_interface.h b/include/libcamera/ipa/ipa_interface.h index 322b7079..df12f9ce 100644 --- a/include/libcamera/ipa/ipa_interface.h +++ b/include/libcamera/ipa/ipa_interface.h @@ -153,7 +153,8 @@ public: virtual ~IPAInterface() = default; virtual int init(const IPASettings &settings) = 0; - virtual int start() = 0; + virtual int start(const IPAOperationData &data, + IPAOperationData *result) = 0; virtual void stop() = 0; virtual void configure(const CameraSensorInfo &sensorInfo, diff --git a/src/ipa/libipa/ipa_interface_wrapper.cpp b/src/ipa/libipa/ipa_interface_wrapper.cpp index cee532e3..40628489 100644 --- a/src/ipa/libipa/ipa_interface_wrapper.cpp +++ b/src/ipa/libipa/ipa_interface_wrapper.cpp @@ -95,7 +95,9 @@ int IPAInterfaceWrapper::start(struct ipa_context *_ctx) { IPAInterfaceWrapper *ctx = static_cast(_ctx); - return ctx->ipa_->start(); + /* \todo Translate the data and result. */ + IPAOperationData data = {}; + return ctx->ipa_->start(data, nullptr); } void IPAInterfaceWrapper::stop(struct ipa_context *_ctx) diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 29d48b1b..b8c0f955 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -78,13 +78,14 @@ public: } int init(const IPASettings &settings) override; - int start() override { return 0; } + int start([[maybe_unused]] const IPAOperationData &data, + [[maybe_unused]] IPAOperationData *result) override { return 0; } void stop() override {} void configure(const CameraSensorInfo &sensorInfo, const std::map &streamConfig, const std::map &entityControls, - const IPAOperationData &data, + const IPAOperationData &ipaConfig, IPAOperationData *response) override; void mapBuffers(const std::vector &buffers) override; void unmapBuffers(const std::vector &ids) override; diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp index 07d7f1b2..39783abd 100644 --- a/src/ipa/rkisp1/rkisp1.cpp +++ b/src/ipa/rkisp1/rkisp1.cpp @@ -37,7 +37,8 @@ public: { return 0; } - int start() override { return 0; } + int start([[maybe_unused]] const IPAOperationData &data, + [[maybe_unused]] IPAOperationData *result) override { return 0; } void stop() override {} void configure(const CameraSensorInfo &info, diff --git a/src/ipa/vimc/vimc.cpp b/src/ipa/vimc/vimc.cpp index cf841135..074902ee 100644 --- a/src/ipa/vimc/vimc.cpp +++ b/src/ipa/vimc/vimc.cpp @@ -34,7 +34,8 @@ public: int init(const IPASettings &settings) override; - int start() override; + int start(const IPAOperationData &data, + IPAOperationData *result) override; void stop() override; void configure([[maybe_unused]] const CameraSensorInfo &sensorInfo, @@ -82,7 +83,8 @@ int IPAVimc::init(const IPASettings &settings) return 0; } -int IPAVimc::start() +int IPAVimc::start([[maybe_unused]] const IPAOperationData &data, + [[maybe_unused]] IPAOperationData *result) { trace(IPAOperationStart); diff --git a/src/libcamera/ipa_context_wrapper.cpp b/src/libcamera/ipa_context_wrapper.cpp index 231300ce..19c44ad8 100644 --- a/src/libcamera/ipa_context_wrapper.cpp +++ b/src/libcamera/ipa_context_wrapper.cpp @@ -86,10 +86,11 @@ int IPAContextWrapper::init(const IPASettings &settings) return 0; } -int IPAContextWrapper::start() +int IPAContextWrapper::start(const IPAOperationData &data, + IPAOperationData *result) { if (intf_) - return intf_->start(); + return intf_->start(data, result); if (!ctx_) return 0; diff --git a/src/libcamera/ipa_interface.cpp b/src/libcamera/ipa_interface.cpp index 23fc56d7..5be6f787 100644 --- a/src/libcamera/ipa_interface.cpp +++ b/src/libcamera/ipa_interface.cpp @@ -536,10 +536,17 @@ namespace libcamera { /** * \fn IPAInterface::start() * \brief Start the IPA + * \param[in] data Protocol-specific data for the start operation + * \param[out] result Result of the start operation * * This method informs the IPA module that the camera is about to be started. * The IPA module shall prepare any resources it needs to operate. * + * The \a data and \a result parameters carry custom data passed by the + * pipeline handler to the IPA and back. The pipeline handler may set the \a + * result parameter to null if the IPA protocol doesn't need to pass a result + * back through the start() function. + * * \return 0 on success or a negative error code otherwise */ diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 9937db73..bafd0b2d 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -752,7 +752,10 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont } /* Start the IPA. */ - ret = data->ipa_->start(); + IPAOperationData ipaData = {}, result = {}; + if (controls) + ipaData.controls.emplace_back(*controls); + ret = data->ipa_->start(ipaData, &result); if (ret) { LOG(RPI, Error) << "Failed to start IPA for " << camera->id(); @@ -1189,7 +1192,7 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config) } /* Ready the IPA - it must know about the sensor resolution. */ - IPAOperationData result; + IPAOperationData result = {}; ipa_->configure(sensorInfo_, streamConfig, entityControls, ipaConfig, &result); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 4e959fde..eaa10f9f 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -842,7 +842,8 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] ControlList *c if (ret) return ret; - ret = data->ipa_->start(); + IPAOperationData ipaData = {}; + ret = data->ipa_->start(ipaData, nullptr); if (ret) { freeBuffers(camera); LOG(RkISP1, Error) diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp index d81b8598..2a5054a8 100644 --- a/src/libcamera/pipeline/vimc/vimc.cpp +++ b/src/libcamera/pipeline/vimc/vimc.cpp @@ -322,7 +322,8 @@ int PipelineHandlerVimc::start(Camera *camera, [[maybe_unused]] ControlList *con if (ret < 0) return ret; - ret = data->ipa_->start(); + IPAOperationData ipaData = {}; + ret = data->ipa_->start(ipaData, nullptr); if (ret) { data->video_->releaseBuffers(); return ret; diff --git a/src/libcamera/proxy/ipa_proxy_linux.cpp b/src/libcamera/proxy/ipa_proxy_linux.cpp index b78a0e45..ea6f3e5e 100644 --- a/src/libcamera/proxy/ipa_proxy_linux.cpp +++ b/src/libcamera/proxy/ipa_proxy_linux.cpp @@ -30,7 +30,8 @@ public: { return 0; } - int start() override { return 0; } + int start([[maybe_unused]] const IPAOperationData &data, + [[maybe_unused]] IPAOperationData *result) override { return 0; } void stop() override {} void configure([[maybe_unused]] const CameraSensorInfo &sensorInfo, [[maybe_unused]] const std::map &streamConfig, diff --git a/src/libcamera/proxy/ipa_proxy_thread.cpp b/src/libcamera/proxy/ipa_proxy_thread.cpp index eead2883..a5fda2c8 100644 --- a/src/libcamera/proxy/ipa_proxy_thread.cpp +++ b/src/libcamera/proxy/ipa_proxy_thread.cpp @@ -26,7 +26,8 @@ public: IPAProxyThread(IPAModule *ipam); int init(const IPASettings &settings) override; - int start() override; + int start(const IPAOperationData &data, + IPAOperationData *result) override; void stop() override; void configure(const CameraSensorInfo &sensorInfo, @@ -50,9 +51,9 @@ private: ipa_ = ipa; } - int start() + int start(const IPAOperationData &data, IPAOperationData *result) { - return ipa_->start(); + return ipa_->start(data, result); } void stop() @@ -111,12 +112,14 @@ int IPAProxyThread::init(const IPASettings &settings) return 0; } -int IPAProxyThread::start() +int IPAProxyThread::start(const IPAOperationData &data, + IPAOperationData *result) { running_ = true; thread_.start(); - return proxy_.invokeMethod(&ThreadProxy::start, ConnectionTypeBlocking); + return proxy_.invokeMethod(&ThreadProxy::start, ConnectionTypeBlocking, + data, result); } void IPAProxyThread::stop() diff --git a/test/ipa/ipa_interface_test.cpp b/test/ipa/ipa_interface_test.cpp index 9f575f93..dbb6727f 100644 --- a/test/ipa/ipa_interface_test.cpp +++ b/test/ipa/ipa_interface_test.cpp @@ -120,7 +120,8 @@ protected: } /* Test start of IPA module. */ - ipa_->start(); + IPAOperationData data = {}; + ipa_->start(data, nullptr); timer.start(1000); while (timer.isRunning() && trace_ != IPAOperationStart) dispatcher->processEvents(); diff --git a/test/ipa/ipa_wrappers_test.cpp b/test/ipa/ipa_wrappers_test.cpp index 59d991cb..47533d10 100644 --- a/test/ipa/ipa_wrappers_test.cpp +++ b/test/ipa/ipa_wrappers_test.cpp @@ -56,7 +56,8 @@ public: return 0; } - int start() override + int start([[maybe_unused]] const IPAOperationData &data, + [[maybe_unused]] IPAOperationData *result) override { report(Op_start, TestPass); return 0; @@ -376,7 +377,7 @@ protected: return TestFail; } - ret = INVOKE(start); + ret = INVOKE(start, ipaConfig, nullptr); if (ret == TestFail) { cerr << "Failed to run start()"; return TestFail; From patchwork Fri Dec 4 15:31:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 10561 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 A1362BE177 for ; Fri, 4 Dec 2020 15:31:30 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1BD3E635F8; Fri, 4 Dec 2020 16:31:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="cw2hQg02"; dkim-atps=neutral Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 948BC635D6 for ; Fri, 4 Dec 2020 16:31:28 +0100 (CET) Received: by mail-wm1-x335.google.com with SMTP id g185so7404293wmf.3 for ; Fri, 04 Dec 2020 07:31:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0PV2Y5oXqUFKFkSmsjE6h2mwWzE30CUw3vNPsXz+F/M=; b=cw2hQg025wombO8odwyKU7iDFApHYVLjhosBLHNH9kUfqzDFtUetlxq41L1PxjhGnx tLwoxLKjiHHifIWb0cLbeB3zbVi5DUa/Ad++bflZ43hw4EsjtYFMJAYNfoPLvx4cnRA6 L1rtobsztDQLC7EeWO/YRb0UvJpJmE9Ossbf3lfEhanvAKfoBkQDtq8mWXYGEjoJsgF+ FQ0p9/r5foNaW/ug/a14kOB558l34klpkEGvnqil3YaNTE1YzAjjNoqcBUoiqtsTf3EC Wb8OPyRoKqDrjrlTSaN2MTm2+QJEISk30GQ1sjiqmylFnhGadXvh5s3TMo/zRyNeYWXM zotQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0PV2Y5oXqUFKFkSmsjE6h2mwWzE30CUw3vNPsXz+F/M=; b=KTgc+yEK9Ok5ngLw5LmVBDx1BPKJVujgblQjFLA+8MUd9GWmcoSATAuNhv+3f76esU yAUdkPHylpWBI6tMfNoIbNqiOUHqwuIYQAlTowgtn21xtsy9MaJkg3Gce/7HVR7lnTi2 fPAy7yqAWbO/liK+M1up91qe6OFjNMY6phLrV/9aluuvH4fOxVA/c06J7+E5PH2BVTO1 LDIE3b8lACZ/7ADjJLpBdS9H9aRFejkKxA4w95Rdr2NKUADNZUvbo6gycBGx3QVUMGqD oAir3OFTtLm8XoKofjdw46wZuP/kld8mwgGP8i8N7Y5bduNUgp+IPelcBFVNOIAtYaw6 WSAw== X-Gm-Message-State: AOAM530N7Um/tJW5wj6hStBcdOUjZ6xMQvpbZ/iT3sMy+OPluGw+ubUK Uf2uD6RmEHpztP3wCmGflVvvEWoI3kmhvA== X-Google-Smtp-Source: ABdhPJx9YLoE0u8f2RA1uZAZrKzTxdQt6qAkfXsiEOUImXZpB+oM3+V5g9tzBdn8qo19cu2XOsZIQQ== X-Received: by 2002:a1c:5f83:: with SMTP id t125mr4944212wmb.82.1607095887960; Fri, 04 Dec 2020 07:31:27 -0800 (PST) Received: from naushir-VirtualBox.pitowers.org ([2a00:1098:3142:14:a00:27ff:fe4d:f6a2]) by smtp.gmail.com with ESMTPSA id x66sm3465426wmg.26.2020.12.04.07.31.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Dec 2020 07:31:27 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Fri, 4 Dec 2020 15:31:21 +0000 Message-Id: <20201204153121.66136-4-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201204153121.66136-1-naush@raspberrypi.com> References: <20201204153121.66136-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 3/3] pipeline: ipa: raspberrypi: Pass controls to IPA on start 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" Forward any controls passed into the pipeline handler to the IPA. The IPA then sets up the Raspberry Pi controller with these settings appropriately, and passes back any V4L2 sensor controls that need to be applied. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Tested-by: David Plowman Reviewed-by: Jacopo Mondi --- include/libcamera/ipa/raspberrypi.h | 1 + src/ipa/raspberrypi/raspberrypi.cpp | 54 ++++++++++++------- .../pipeline/raspberrypi/raspberrypi.cpp | 13 ++++- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h index 2b55dbfc..c91a14bd 100644 --- a/include/libcamera/ipa/raspberrypi.h +++ b/include/libcamera/ipa/raspberrypi.h @@ -21,6 +21,7 @@ enum ConfigParameters { IPA_CONFIG_STAGGERED_WRITE = (1 << 1), IPA_CONFIG_SENSOR = (1 << 2), IPA_CONFIG_DROP_FRAMES = (1 << 3), + IPA_CONFIG_STARTUP = (1 << 4) }; enum Operations { diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index b8c0f955..ff95580e 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -78,8 +78,7 @@ public: } int init(const IPASettings &settings) override; - int start([[maybe_unused]] const IPAOperationData &data, - [[maybe_unused]] IPAOperationData *result) override { return 0; } + int start(const IPAOperationData &data, IPAOperationData *result) override; void stop() override {} void configure(const CameraSensorInfo &sensorInfo, @@ -154,6 +153,36 @@ int IPARPi::init(const IPASettings &settings) return 0; } +int IPARPi::start(const IPAOperationData &data, IPAOperationData *result) +{ + RPiController::Metadata metadata; + + ASSERT(result); + result->operation = 0; + if (data.operation & RPi::IPA_CONFIG_STARTUP) { + /* We have been given some controls to action before start. */ + queueRequest(data.controls[0]); + } + + controller_.SwitchMode(mode_, &metadata); + + /* SwitchMode may supply updated exposure/gain values to use. */ + AgcStatus agcStatus; + agcStatus.shutter_time = 0.0; + agcStatus.analogue_gain = 0.0; + + /* SwitchMode may supply updated exposure/gain values to use. */ + metadata.Get("agc.status", agcStatus); + if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) { + ControlList ctrls(unicamCtrls_); + applyAGC(&agcStatus, ctrls); + result->controls.emplace_back(ctrls); + result->operation |= RPi::IPA_CONFIG_SENSOR; + } + + return 0; +} + void IPARPi::setMode(const CameraSensorInfo &sensorInfo) { mode_.bitdepth = sensorInfo.bitsPerPixel; @@ -229,7 +258,6 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, result->data.push_back(gainDelay); result->data.push_back(exposureDelay); result->data.push_back(sensorMetadata); - result->operation |= RPi::IPA_CONFIG_STAGGERED_WRITE; } @@ -285,11 +313,6 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, result->data.push_back(dropFrame); result->operation |= RPi::IPA_CONFIG_DROP_FRAMES; - /* These zero values mean not program anything (unless overwritten). */ - struct AgcStatus agcStatus; - agcStatus.shutter_time = 0.0; - agcStatus.analogue_gain = 0.0; - if (!controllerInit_) { /* Load the tuning file for this sensor. */ controller_.Read(tuningFile_.c_str()); @@ -297,20 +320,13 @@ void IPARPi::configure(const CameraSensorInfo &sensorInfo, controllerInit_ = true; /* Supply initial values for gain and exposure. */ + ControlList ctrls(unicamCtrls_); + AgcStatus agcStatus; agcStatus.shutter_time = DefaultExposureTime; agcStatus.analogue_gain = DefaultAnalogueGain; - } - - RPiController::Metadata metadata; - controller_.SwitchMode(mode_, &metadata); - - /* SwitchMode may supply updated exposure/gain values to use. */ - metadata.Get("agc.status", agcStatus); - if (agcStatus.shutter_time != 0.0 && agcStatus.analogue_gain != 0.0) { - ControlList ctrls(unicamCtrls_); applyAGC(&agcStatus, ctrls); - result->controls.push_back(ctrls); + result->controls.emplace_back(ctrls); result->operation |= RPi::IPA_CONFIG_SENSOR; } @@ -824,7 +840,7 @@ void IPARPi::processStats(unsigned int bufferId) IPAOperationData op; op.operation = RPi::IPA_ACTION_V4L2_SET_STAGGERED; - op.controls.push_back(ctrls); + op.controls.emplace_back(ctrls); queueFrameAction.emit(0, op); } } diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index bafd0b2d..bc7c56f8 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -753,8 +753,10 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont /* Start the IPA. */ IPAOperationData ipaData = {}, result = {}; - if (controls) + if (controls) { + ipaData.operation = RPi::IPA_CONFIG_STARTUP; ipaData.controls.emplace_back(*controls); + } ret = data->ipa_->start(ipaData, &result); if (ret) { LOG(RPI, Error) @@ -763,6 +765,14 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont return ret; } + /* Apply any gain/exposure settings that the IPA may have passed back. */ + ASSERT(data->staggeredCtrl_); + if (result.operation & RPi::IPA_CONFIG_SENSOR) { + const ControlList &ctrls = result.controls[0]; + if (!data->staggeredCtrl_.set(ctrls)) + LOG(RPI, Error) << "V4L2 staggered set failed"; + } + /* * IPA configure may have changed the sensor flips - hence the bayer * order. Get the sensor format and set the ISP input now. @@ -783,7 +793,6 @@ int PipelineHandlerRPi::start(Camera *camera, [[maybe_unused]] ControlList *cont * starting. First check that the staggered ctrl has been initialised * by configure(). */ - ASSERT(data->staggeredCtrl_); data->staggeredCtrl_.reset(); data->staggeredCtrl_.write(); data->expectedSequence_ = 0;