From patchwork Fri Sep 25 01:41:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9799 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 A63A3C3B5C for ; Fri, 25 Sep 2020 01:42:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 81F2763017; Fri, 25 Sep 2020 03:42:44 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 851A862FD8 for ; Fri, 25 Sep 2020 03:42:42 +0200 (CEST) X-Halon-ID: 65c8f28a-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 65c8f28a-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:40 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:46 +0200 Message-Id: <20200925014207.1455796-2-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 01/22] libcamera: pipeline: rkisp1: Set number of planes based on format 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 RkISP1 pipeline originally only supported NV formats which have 2 planes. When support for YUV formats was added the plane count on the output format was not made to reflect this. Instead of hard coding the plane count to 2 fetch the number of planes from the format information. Reported-by: Jacopo Mondi Fixes: 2b1a908b5222e263 ("libcamera: camera: Add a validation API to the CameraConfiguration class") Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index a6fc3b8e36f3b00a..009d190d3ec828f0 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -667,10 +667,11 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) LOG(RkISP1, Debug) << "Resizer output pad configured with " << format.toString(); + const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); V4L2DeviceFormat outputFormat = {}; outputFormat.fourcc = video_->toV4L2PixelFormat(cfg.pixelFormat); outputFormat.size = cfg.size; - outputFormat.planesCount = 2; + outputFormat.planesCount = info.numPlanes(); ret = video_->setFormat(&outputFormat); if (ret) From patchwork Fri Sep 25 01:41:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9800 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 7A364C3B5C for ; Fri, 25 Sep 2020 01:42:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D69A86301F; Fri, 25 Sep 2020 03:42:44 +0200 (CEST) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1FB3962FD8 for ; Fri, 25 Sep 2020 03:42:43 +0200 (CEST) X-Halon-ID: 669add1a-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 669add1a-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:41 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:47 +0200 Message-Id: <20200925014207.1455796-3-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 02/22] libcamera: pipeline: rkisp1: Remove redundant check of buffer in Request 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 is no need to check if Request contains a buffer belonging the RkISP1 Camera as this is already done in Camera::queueRequest(), remove the redundant check. Reported-by: Laurent Pinchart Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 009d190d3ec828f0..77a48106ec68cb7b 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -243,11 +243,6 @@ RkISP1FrameInfo *RkISP1Frames::create(unsigned int frame, Request *request, Stre FrameBuffer *statBuffer = pipe_->availableStatBuffers_.front(); FrameBuffer *videoBuffer = request->findBuffer(stream); - if (!videoBuffer) { - LOG(RkISP1, Error) - << "Attempt to queue request with invalid stream"; - return nullptr; - } pipe_->availableParamBuffers_.pop(); pipe_->availableStatBuffers_.pop(); From patchwork Fri Sep 25 01:41:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9801 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 AA6B8C3B5C for ; Fri, 25 Sep 2020 01:42:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6F09C63027; Fri, 25 Sep 2020 03:42:47 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0070262FF3 for ; Fri, 25 Sep 2020 03:42:43 +0200 (CEST) X-Halon-ID: 66fbe9cd-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 66fbe9cd-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:42 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:48 +0200 Message-Id: <20200925014207.1455796-4-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 03/22] libcamera: pipeline: rkisp1: Breakout mainpath size and format constraints 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" Breakout the mainpath size and format constrains as it will be used in more places then just validate(). While at it use the new helpers to validate Size. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- * Changes since v2 - Reduce indentation level of namespace { }. - Remove space before { in array declaration. * Changes since v1 - Use list initializers - Use constexpr instead of static const - Define constants in anonymoys namespace --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 34 +++++++++++++----------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 77a48106ec68cb7b..a5b6bb07e4f8dee2 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -37,6 +37,21 @@ namespace libcamera { LOG_DEFINE_CATEGORY(RkISP1) +namespace { +constexpr Size RKISP1_RSZ_MP_SRC_MIN{ 32, 16 }; +constexpr Size RKISP1_RSZ_MP_SRC_MAX{ 4416, 3312 }; +constexpr std::array RKISP1_RSZ_MP_FORMATS{ + formats::YUYV, + formats::YVYU, + formats::VYUY, + formats::NV16, + formats::NV61, + formats::NV21, + formats::NV12, + /* \todo Add support for 8-bit greyscale to DRM formats */ +}; +} /* namespace */ + class PipelineHandlerRkISP1; class RkISP1ActionQueueBuffers; @@ -456,17 +471,6 @@ RkISP1CameraConfiguration::RkISP1CameraConfiguration(Camera *camera, CameraConfiguration::Status RkISP1CameraConfiguration::validate() { - static const std::array formats{ - formats::YUYV, - formats::YVYU, - formats::VYUY, - formats::NV16, - formats::NV61, - formats::NV21, - formats::NV12, - /* \todo Add support for 8-bit greyscale to DRM formats */ - }; - const CameraSensor *sensor = data_->sensor_; Status status = Valid; @@ -482,8 +486,8 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() StreamConfiguration &cfg = config_[0]; /* Adjust the pixel format. */ - if (std::find(formats.begin(), formats.end(), cfg.pixelFormat) == - formats.end()) { + if (std::find(RKISP1_RSZ_MP_FORMATS.begin(), RKISP1_RSZ_MP_FORMATS.end(), + cfg.pixelFormat) == RKISP1_RSZ_MP_FORMATS.end()) { LOG(RkISP1, Debug) << "Adjusting format to NV12"; cfg.pixelFormat = formats::NV12, status = Adjusted; @@ -520,8 +524,8 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() / sensorFormat_.size.width; } - cfg.size.width = std::max(32U, std::min(4416U, cfg.size.width)); - cfg.size.height = std::max(16U, std::min(3312U, cfg.size.height)); + cfg.size.boundTo(RKISP1_RSZ_MP_SRC_MAX); + cfg.size.expandTo(RKISP1_RSZ_MP_SRC_MIN); if (cfg.size != size) { LOG(RkISP1, Debug) From patchwork Fri Sep 25 01:41:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9802 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 5956EC3B5C for ; Fri, 25 Sep 2020 01:42:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 003016300E; Fri, 25 Sep 2020 03:42:47 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C2CC26300B for ; Fri, 25 Sep 2020 03:42:44 +0200 (CEST) X-Halon-ID: 678b7d9c-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 678b7d9c-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:43 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:49 +0200 Message-Id: <20200925014207.1455796-5-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 04/22] libcamera: pipeline: rkisp1: Setup links as part of configuration 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" In preparation of supporting both the main and self path configure all the media graph links as a part of the configuration step. Before this change the link between ISP and DMA engine was setup at match time as the only supported path was the main path and only the link between sensor and ISP was updated at part of the configuration step. The main path is still the only path between ISP and DMA engine that is possible to enable. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- * Changes since v2 - Simplify link selection per Laurent's suggestion. This is reworked once more in a later patch but makes thins one looks nicer for now. * Changes since v1 - Pass sensor directly to initLinks(). - Remove string variable form link selection. - Rewrite commit message. --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 77 ++++++++++++------------ 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index a5b6bb07e4f8dee2..8bb4582eeb688a4c 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -213,7 +213,8 @@ private: friend RkISP1CameraData; friend RkISP1Frames; - int initLinks(); + int initLinks(const Camera *camera, const CameraSensor *sensor, + const RkISP1CameraConfiguration &config); int createCamera(MediaEntity *sensor); void tryCompleteRequest(Request *request); void bufferReady(FrameBuffer *buffer); @@ -598,28 +599,9 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) CameraSensor *sensor = data->sensor_; int ret; - /* - * Configure the sensor links: enable the link corresponding to this - * camera and disable all the other sensor links. - */ - const MediaPad *pad = isp_->entity()->getPadByIndex(0); - - for (MediaLink *link : pad->links()) { - bool enable = link->source()->entity() == sensor->entity(); - - if (!!(link->flags() & MEDIA_LNK_FL_ENABLED) == enable) - continue; - - LOG(RkISP1, Debug) - << (enable ? "Enabling" : "Disabling") - << " link from sensor '" - << link->source()->entity()->name() - << "' to ISP"; - - ret = link->setEnabled(enable); - if (ret < 0) - return ret; - } + ret = initLinks(camera, sensor, *config); + if (ret) + return ret; /* * Configure the format on the sensor output and propagate it through @@ -922,22 +904,49 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request) * Match and Setup */ -int PipelineHandlerRkISP1::initLinks() +int PipelineHandlerRkISP1::initLinks(const Camera *camera, + const CameraSensor *sensor, + const RkISP1CameraConfiguration &config) { - MediaLink *link; + RkISP1CameraData *data = cameraData(camera); int ret; ret = media_->disableLinks(); if (ret < 0) return ret; - link = media_->link("rkisp1_isp", 2, "rkisp1_resizer_mainpath", 0); - if (!link) - return -ENODEV; + /* + * Configure the sensor links: enable the link corresponding to this + * camera. + */ + const MediaPad *pad = isp_->entity()->getPadByIndex(0); + for (MediaLink *link : pad->links()) { + if (link->source()->entity() != sensor->entity()) + continue; - ret = link->setEnabled(true); - if (ret < 0) - return ret; + LOG(RkISP1, Debug) + << "Enabling link from sensor '" + << link->source()->entity()->name() + << "' to ISP"; + + ret = link->setEnabled(true); + if (ret < 0) + return ret; + } + + for (const StreamConfiguration &cfg : config) { + if (cfg.stream() != &data->stream_) + return -EINVAL; + + MediaLink *link = media_->link("rkisp1_isp", 2, + "rkisp1_resizer_mainpath", 0); + if (!link) + return -ENODEV; + + ret = link->setEnabled(true); + if (ret < 0) + return ret; + } return 0; } @@ -1019,12 +1028,6 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady); param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady); - /* Configure default links. */ - if (initLinks() < 0) { - LOG(RkISP1, Error) << "Failed to setup links"; - return false; - } - /* * Enumerate all sensors connected to the ISP and create one * camera instance for each of them. From patchwork Fri Sep 25 01:41:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9803 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 D8090C3B5C for ; Fri, 25 Sep 2020 01:42:48 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7E6136301D; Fri, 25 Sep 2020 03:42:48 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 813CA6300E for ; Fri, 25 Sep 2020 03:42:45 +0200 (CEST) X-Halon-ID: 67fe2f04-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 67fe2f04-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:44 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:50 +0200 Message-Id: <20200925014207.1455796-6-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 05/22] libcamera: pipeline: rkisp1: Prepare buffer ready handlers for multiple streams 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 ready handlers are designed for a single application facing stream from the main path. To prepare for multiple application facing streams from main and/or self path the handlers need to be prepared. The data keeping tasks of frame number and advancing the timeline can be moved from the application facing buffer ready handler to the statistics handler. For each request processed there will always be a statistic buffer and as the ISP is inline and is the source of both main, self and statistic paths there is no lose in precision from this. The application facing handler no longer needs a special case for cancelled frames and can be made simpler. With this change the handlers are ready to deal with any combinations of application facing streams. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 8bb4582eeb688a4c..d6b5073b2084a9f4 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1070,20 +1070,8 @@ void PipelineHandlerRkISP1::tryCompleteRequest(Request *request) void PipelineHandlerRkISP1::bufferReady(FrameBuffer *buffer) { ASSERT(activeCamera_); - RkISP1CameraData *data = cameraData(activeCamera_); Request *request = buffer->request(); - if (buffer->metadata().status == FrameMetadata::FrameCancelled) { - completeBuffer(activeCamera_, request, buffer); - completeRequest(activeCamera_, request); - return; - } - - data->timeline_.bufferReady(buffer); - - if (data->frame_ <= buffer->metadata().sequence) - data->frame_ = buffer->metadata().sequence + 1; - completeBuffer(activeCamera_, request, buffer); tryCompleteRequest(request); } @@ -1114,6 +1102,11 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer) if (!info) return; + data->timeline_.bufferReady(buffer); + + if (data->frame_ <= buffer->metadata().sequence) + data->frame_ = buffer->metadata().sequence + 1; + IPAOperationData op; op.operation = RKISP1_IPA_EVENT_SIGNAL_STAT_BUFFER; op.data = { info->frame, info->statBuffer->cookie() }; From patchwork Fri Sep 25 01:41:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9804 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 2FE1FC3B5C for ; Fri, 25 Sep 2020 01:42:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0927D6303F; Fri, 25 Sep 2020 03:42:51 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 406B762FD8 for ; Fri, 25 Sep 2020 03:42:46 +0200 (CEST) X-Halon-ID: 686e9ef9-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 686e9ef9-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:45 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:51 +0200 Message-Id: <20200925014207.1455796-7-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 06/22] libcamera: pipeline: rkisp1: Create RkISP1Frames from camera data 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" Create RkISP1Frames from camera data instead of picking information out from it. This is done to prepare for multi stream support where more information from the camera data will be needed. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- * Changes since v1 - Grammar fixes in commit message. --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index d6b5073b2084a9f4..e52aadcfdb9870a3 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -54,6 +54,7 @@ constexpr std::array RKISP1_RSZ_MP_FORMATS{ class PipelineHandlerRkISP1; class RkISP1ActionQueueBuffers; +class RkISP1CameraData; enum RkISP1ActionType { SetSensor, @@ -79,7 +80,7 @@ class RkISP1Frames public: RkISP1Frames(PipelineHandler *pipe); - RkISP1FrameInfo *create(unsigned int frame, Request *request, Stream *stream); + RkISP1FrameInfo *create(const RkISP1CameraData *data, Request *request); int destroy(unsigned int frame); void clear(); @@ -244,8 +245,10 @@ RkISP1Frames::RkISP1Frames(PipelineHandler *pipe) { } -RkISP1FrameInfo *RkISP1Frames::create(unsigned int frame, Request *request, Stream *stream) +RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *request) { + unsigned int frame = data->frame_; + if (pipe_->availableParamBuffers_.empty()) { LOG(RkISP1, Error) << "Parameters buffer underrun"; return nullptr; @@ -258,7 +261,7 @@ RkISP1FrameInfo *RkISP1Frames::create(unsigned int frame, Request *request, Stre } FrameBuffer *statBuffer = pipe_->availableStatBuffers_.front(); - FrameBuffer *videoBuffer = request->findBuffer(stream); + FrameBuffer *videoBuffer = request->findBuffer(&data->stream_); pipe_->availableParamBuffers_.pop(); pipe_->availableStatBuffers_.pop(); @@ -878,10 +881,8 @@ void PipelineHandlerRkISP1::stop(Camera *camera) int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request) { RkISP1CameraData *data = cameraData(camera); - Stream *stream = &data->stream_; - RkISP1FrameInfo *info = data->frameInfo_.create(data->frame_, request, - stream); + RkISP1FrameInfo *info = data->frameInfo_.create(data, request); if (!info) return -ENOENT; From patchwork Fri Sep 25 01:41:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9805 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 81E69C3B5E for ; Fri, 25 Sep 2020 01:42:51 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4A6776301B; Fri, 25 Sep 2020 03:42:51 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D6C1762FD8 for ; Fri, 25 Sep 2020 03:42:46 +0200 (CEST) X-Halon-ID: 68e1dacc-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 68e1dacc-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:45 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:52 +0200 Message-Id: <20200925014207.1455796-8-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 07/22] libcamera: pipeline: rkisp1: Export stream formats to applications 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 information about stream format is available but not exported to applications, fix this. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- * Changes since v1 - Fix s/applicaitons/applications/ in subject - Cap the max resolution reported to the sensor resolution. --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index e52aadcfdb9870a3..27191b18c989aa5e 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -582,7 +582,13 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera if (roles.empty()) return config; - StreamConfiguration cfg{}; + std::map> streamFormats; + for (const PixelFormat &format : RKISP1_RSZ_MP_FORMATS) + streamFormats[format] = + { { RKISP1_RSZ_MP_SRC_MIN, data->sensor_->resolution() } }; + + StreamFormats formats(streamFormats); + StreamConfiguration cfg(formats); cfg.pixelFormat = formats::NV12; cfg.size = data->sensor_->resolution(); From patchwork Fri Sep 25 01:41:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9806 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 0A4F9C3B5C for ; Fri, 25 Sep 2020 01:42:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B8D5E63027; Fri, 25 Sep 2020 03:42:51 +0200 (CEST) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 668B162FD8 for ; Fri, 25 Sep 2020 03:42:47 +0200 (CEST) X-Halon-ID: 693eea2c-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 693eea2c-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:46 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:53 +0200 Message-Id: <20200925014207.1455796-9-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 08/22] libcamera: pipeline: rkisp1: Set the crop rectangle 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" Changing resolutions back and forth can provoke the crop rectangle to go out of sync, set it as part of format configuration. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- * Changes since v2 - Fix s/port/part/ in commit message. --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 27191b18c989aa5e..2f70bf2220fa5c84 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -629,6 +629,11 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) if (ret < 0) return ret; + Rectangle rect(0, 0, format.size); + ret = isp_->setSelection(0, V4L2_SEL_TGT_CROP, &rect); + if (ret < 0) + return ret; + LOG(RkISP1, Debug) << "ISP input pad configured with " << format.toString(); /* YUYV8_2X8 is required on the ISP source path pad for YUV output. */ From patchwork Fri Sep 25 01:41:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9807 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 A24C7C3B5C for ; Fri, 25 Sep 2020 01:42:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5FCAE63032; Fri, 25 Sep 2020 03:42:52 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 68D386300B for ; Fri, 25 Sep 2020 03:42:48 +0200 (CEST) X-Halon-ID: 6996bff3-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6996bff3-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:46 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:54 +0200 Message-Id: <20200925014207.1455796-10-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 09/22] libcamera: pipeline: rkisp1: Prefix main path video and resizer 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" In preparation of supporting both the main and self path prefix the main path specific variables with mainPath. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 80 ++++++++++++------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 2f70bf2220fa5c84..a810e218133e1990 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -68,7 +68,7 @@ struct RkISP1FrameInfo { FrameBuffer *paramBuffer; FrameBuffer *statBuffer; - FrameBuffer *videoBuffer; + FrameBuffer *mainPathBuffer; bool paramFilled; bool paramDequeued; @@ -133,7 +133,7 @@ class RkISP1CameraData : public CameraData public: RkISP1CameraData(PipelineHandler *pipe, V4L2VideoDevice *video) : CameraData(pipe), sensor_(nullptr), frame_(0), - frameInfo_(pipe), video_(video) + frameInfo_(pipe), mainPathVideo_(video) { } @@ -144,14 +144,14 @@ public: int loadIPA(); - Stream stream_; + Stream mainPathStream_; CameraSensor *sensor_; unsigned int frame_; std::vector ipaBuffers_; RkISP1Frames frameInfo_; RkISP1Timeline timeline_; - V4L2VideoDevice *video_; + V4L2VideoDevice *mainPathVideo_; private: void queueFrameAction(unsigned int frame, @@ -227,8 +227,8 @@ private: MediaDevice *media_; V4L2Subdevice *isp_; - V4L2Subdevice *resizer_; - V4L2VideoDevice *video_; + V4L2Subdevice *mainPathResizer_; + V4L2VideoDevice *mainPathVideo_; V4L2VideoDevice *param_; V4L2VideoDevice *stat_; @@ -261,7 +261,7 @@ RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *req } FrameBuffer *statBuffer = pipe_->availableStatBuffers_.front(); - FrameBuffer *videoBuffer = request->findBuffer(&data->stream_); + FrameBuffer *mainPathBuffer = request->findBuffer(&data->mainPathStream_); pipe_->availableParamBuffers_.pop(); pipe_->availableStatBuffers_.pop(); @@ -271,7 +271,7 @@ RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *req info->frame = frame; info->request = request; info->paramBuffer = paramBuffer; - info->videoBuffer = videoBuffer; + info->mainPathBuffer = mainPathBuffer; info->statBuffer = statBuffer; info->paramFilled = false; info->paramDequeued = false; @@ -330,7 +330,7 @@ RkISP1FrameInfo *RkISP1Frames::find(FrameBuffer *buffer) if (info->paramBuffer == buffer || info->statBuffer == buffer || - info->videoBuffer == buffer) + info->mainPathBuffer == buffer) return info; } @@ -402,7 +402,7 @@ protected: pipe_->param_->queueBuffer(info->paramBuffer); pipe_->stat_->queueBuffer(info->statBuffer); - pipe_->video_->queueBuffer(info->videoBuffer); + pipe_->mainPathVideo_->queueBuffer(info->mainPathBuffer); } private: @@ -541,10 +541,10 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() cfg.bufferCount = RKISP1_BUFFER_COUNT; V4L2DeviceFormat format = {}; - format.fourcc = data_->video_->toV4L2PixelFormat(cfg.pixelFormat); + format.fourcc = data_->mainPathVideo_->toV4L2PixelFormat(cfg.pixelFormat); format.size = cfg.size; - int ret = data_->video_->tryFormat(&format); + int ret = data_->mainPathVideo_->tryFormat(&format); if (ret) return Invalid; @@ -555,8 +555,8 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() } PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) - : PipelineHandler(manager), isp_(nullptr), resizer_(nullptr), - video_(nullptr), param_(nullptr), stat_(nullptr) + : PipelineHandler(manager), isp_(nullptr), mainPathResizer_(nullptr), + mainPathVideo_(nullptr), param_(nullptr), stat_(nullptr) { } @@ -564,8 +564,8 @@ PipelineHandlerRkISP1::~PipelineHandlerRkISP1() { delete param_; delete stat_; - delete video_; - delete resizer_; + delete mainPathVideo_; + delete mainPathResizer_; delete isp_; } @@ -646,7 +646,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) LOG(RkISP1, Debug) << "ISP output pad configured with " << format.toString(); - ret = resizer_->setFormat(0, &format); + ret = mainPathResizer_->setFormat(0, &format); if (ret < 0) return ret; @@ -656,7 +656,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) LOG(RkISP1, Debug) << "Configuring resizer output pad with " << format.toString(); - ret = resizer_->setFormat(1, &format); + ret = mainPathResizer_->setFormat(1, &format); if (ret < 0) return ret; @@ -664,16 +664,16 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); V4L2DeviceFormat outputFormat = {}; - outputFormat.fourcc = video_->toV4L2PixelFormat(cfg.pixelFormat); + outputFormat.fourcc = mainPathVideo_->toV4L2PixelFormat(cfg.pixelFormat); outputFormat.size = cfg.size; outputFormat.planesCount = info.numPlanes(); - ret = video_->setFormat(&outputFormat); + ret = mainPathVideo_->setFormat(&outputFormat); if (ret) return ret; if (outputFormat.size != cfg.size || - outputFormat.fourcc != video_->toV4L2PixelFormat(cfg.pixelFormat)) { + outputFormat.fourcc != mainPathVideo_->toV4L2PixelFormat(cfg.pixelFormat)) { LOG(RkISP1, Error) << "Unable to configure capture in " << cfg.toString(); return -EINVAL; @@ -691,7 +691,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) if (ret) return ret; - cfg.setStream(&data->stream_); + cfg.setStream(&data->mainPathStream_); return 0; } @@ -700,17 +700,17 @@ int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, S std::vector> *buffers) { unsigned int count = stream->configuration().bufferCount; - return video_->exportBuffers(count, buffers); + return mainPathVideo_->exportBuffers(count, buffers); } int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) { RkISP1CameraData *data = cameraData(camera); - unsigned int count = data->stream_.configuration().bufferCount; + unsigned int count = data->mainPathStream_.configuration().bufferCount; unsigned int ipaBufferId = 1; int ret; - ret = video_->importBuffers(count); + ret = mainPathVideo_->importBuffers(count); if (ret < 0) goto error; @@ -743,7 +743,7 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) error: paramBuffers_.clear(); statBuffers_.clear(); - video_->releaseBuffers(); + mainPathVideo_->releaseBuffers(); return ret; } @@ -774,8 +774,8 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera) if (stat_->releaseBuffers()) LOG(RkISP1, Error) << "Failed to release stat buffers"; - if (video_->releaseBuffers()) - LOG(RkISP1, Error) << "Failed to release video buffers"; + if (mainPathVideo_->releaseBuffers()) + LOG(RkISP1, Error) << "Failed to release main path buffers"; return 0; } @@ -819,7 +819,7 @@ int PipelineHandlerRkISP1::start(Camera *camera) return ret; } - ret = video_->streamOn(); + ret = mainPathVideo_->streamOn(); if (ret) { param_->streamOff(); stat_->streamOff(); @@ -844,8 +844,8 @@ int PipelineHandlerRkISP1::start(Camera *camera) std::map streamConfig; streamConfig[0] = { - .pixelFormat = data->stream_.configuration().pixelFormat, - .size = data->stream_.configuration().size, + .pixelFormat = data->mainPathStream_.configuration().pixelFormat, + .size = data->mainPathStream_.configuration().size, }; std::map entityControls; @@ -863,7 +863,7 @@ void PipelineHandlerRkISP1::stop(Camera *camera) RkISP1CameraData *data = cameraData(camera); int ret; - ret = video_->streamOff(); + ret = mainPathVideo_->streamOff(); if (ret) LOG(RkISP1, Warning) << "Failed to stop camera " << camera->id(); @@ -947,7 +947,7 @@ int PipelineHandlerRkISP1::initLinks(const Camera *camera, } for (const StreamConfiguration &cfg : config) { - if (cfg.stream() != &data->stream_) + if (cfg.stream() != &data->mainPathStream_) return -EINVAL; MediaLink *link = media_->link("rkisp1_isp", 2, @@ -968,7 +968,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) int ret; std::unique_ptr data = - std::make_unique(this, video_); + std::make_unique(this, mainPathVideo_); ControlInfoMap::Map ctrls; ctrls.emplace(std::piecewise_construct, @@ -989,7 +989,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) if (ret) return ret; - std::set streams{ &data->stream_ }; + std::set streams{ &data->mainPathStream_ }; std::shared_ptr camera = Camera::create(this, data->sensor_->id(), streams); registerCamera(std::move(camera), std::move(data)); @@ -1019,13 +1019,13 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (isp_->open() < 0) return false; - resizer_ = V4L2Subdevice::fromEntityName(media_, "rkisp1_resizer_mainpath"); - if (resizer_->open() < 0) + mainPathResizer_ = V4L2Subdevice::fromEntityName(media_, "rkisp1_resizer_mainpath"); + if (mainPathResizer_->open() < 0) return false; /* Locate and open the capture video node. */ - video_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_mainpath"); - if (video_->open() < 0) + mainPathVideo_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_mainpath"); + if (mainPathVideo_->open() < 0) return false; stat_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_stats"); @@ -1036,7 +1036,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (param_->open() < 0) return false; - video_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); + mainPathVideo_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady); param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady); From patchwork Fri Sep 25 01:41:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9808 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 54545C3B5C for ; Fri, 25 Sep 2020 01:42:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 11A8D62FF3; Fri, 25 Sep 2020 03:42:53 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1A4BA63005 for ; Fri, 25 Sep 2020 03:42:49 +0200 (CEST) X-Halon-ID: 6a2ef3e9-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6a2ef3e9-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:47 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:55 +0200 Message-Id: <20200925014207.1455796-11-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 10/22] libcamera: pipeline: rkisp1: Add self path devices 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 the V4L2 device nodes needed to operate the self path. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 26 ++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index a810e218133e1990..fef4fa813190056e 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -131,9 +131,11 @@ public: class RkISP1CameraData : public CameraData { public: - RkISP1CameraData(PipelineHandler *pipe, V4L2VideoDevice *video) + RkISP1CameraData(PipelineHandler *pipe, V4L2VideoDevice *mainPathVideo, + V4L2VideoDevice *selfPathVideo) : CameraData(pipe), sensor_(nullptr), frame_(0), - frameInfo_(pipe), mainPathVideo_(video) + frameInfo_(pipe), mainPathVideo_(mainPathVideo), + selfPathVideo_(selfPathVideo) { } @@ -152,6 +154,7 @@ public: RkISP1Timeline timeline_; V4L2VideoDevice *mainPathVideo_; + V4L2VideoDevice *selfPathVideo_; private: void queueFrameAction(unsigned int frame, @@ -228,7 +231,9 @@ private: MediaDevice *media_; V4L2Subdevice *isp_; V4L2Subdevice *mainPathResizer_; + V4L2Subdevice *selfPathResizer_; V4L2VideoDevice *mainPathVideo_; + V4L2VideoDevice *selfPathVideo_; V4L2VideoDevice *param_; V4L2VideoDevice *stat_; @@ -556,7 +561,8 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) : PipelineHandler(manager), isp_(nullptr), mainPathResizer_(nullptr), - mainPathVideo_(nullptr), param_(nullptr), stat_(nullptr) + selfPathResizer_(nullptr), mainPathVideo_(nullptr), + selfPathVideo_(nullptr), param_(nullptr), stat_(nullptr) { } @@ -565,7 +571,9 @@ PipelineHandlerRkISP1::~PipelineHandlerRkISP1() delete param_; delete stat_; delete mainPathVideo_; + delete selfPathVideo_; delete mainPathResizer_; + delete selfPathResizer_; delete isp_; } @@ -968,7 +976,8 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) int ret; std::unique_ptr data = - std::make_unique(this, mainPathVideo_); + std::make_unique(this, mainPathVideo_, + selfPathVideo_); ControlInfoMap::Map ctrls; ctrls.emplace(std::piecewise_construct, @@ -1023,11 +1032,19 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (mainPathResizer_->open() < 0) return false; + selfPathResizer_ = V4L2Subdevice::fromEntityName(media_, "rkisp1_resizer_selfpath"); + if (selfPathResizer_->open() < 0) + return false; + /* Locate and open the capture video node. */ mainPathVideo_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_mainpath"); if (mainPathVideo_->open() < 0) return false; + selfPathVideo_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_selfpath"); + if (selfPathVideo_->open() < 0) + return false; + stat_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_stats"); if (stat_->open() < 0) return false; @@ -1037,6 +1054,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) return false; mainPathVideo_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); + selfPathVideo_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady); param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady); From patchwork Fri Sep 25 01:41:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9809 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 E5158C3B5C for ; Fri, 25 Sep 2020 01:42:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A04BD6301D; Fri, 25 Sep 2020 03:42:53 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0FBE060576 for ; Fri, 25 Sep 2020 03:42:50 +0200 (CEST) X-Halon-ID: 6a9799cf-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6a9799cf-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:48 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:56 +0200 Message-Id: <20200925014207.1455796-12-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 11/22] libcamera: pipeline: rkisp1: Configure self path 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" Allow for both the main and self path streams to be configured. This change adds the self path as an internal stream to the pipeline handler. It is not exposed as a Camera stream so it can not yet be used. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- * Changes since v2 - Print which resizer is configured - Use if ...; else if; ... instead of if ...; if ...; in exportFrameBuffers() - Configure main and self streams with separate numbers of buffers while still allocating the max of the two for stats and params. - Improve Warning logs in stop()` --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 227 ++++++++++++++++------- 1 file changed, 161 insertions(+), 66 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index fef4fa813190056e..28e99129498e4a0a 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -135,7 +135,8 @@ public: V4L2VideoDevice *selfPathVideo) : CameraData(pipe), sensor_(nullptr), frame_(0), frameInfo_(pipe), mainPathVideo_(mainPathVideo), - selfPathVideo_(selfPathVideo) + selfPathVideo_(selfPathVideo), mainPathActive_(false), + selfPathActive_(false) { } @@ -147,6 +148,7 @@ public: int loadIPA(); Stream mainPathStream_; + Stream selfPathStream_; CameraSensor *sensor_; unsigned int frame_; std::vector ipaBuffers_; @@ -156,6 +158,9 @@ public: V4L2VideoDevice *mainPathVideo_; V4L2VideoDevice *selfPathVideo_; + bool mainPathActive_; + bool selfPathActive_; + private: void queueFrameAction(unsigned int frame, const IPAOperationData &action); @@ -612,7 +617,6 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) RkISP1CameraConfiguration *config = static_cast(c); RkISP1CameraData *data = cameraData(camera); - StreamConfiguration &cfg = config->at(0); CameraSensor *sensor = data->sensor_; int ret; @@ -654,37 +658,63 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) LOG(RkISP1, Debug) << "ISP output pad configured with " << format.toString(); - ret = mainPathResizer_->setFormat(0, &format); - if (ret < 0) - return ret; - - LOG(RkISP1, Debug) << "Resizer input pad configured with " << format.toString(); - - format.size = cfg.size; - - LOG(RkISP1, Debug) << "Configuring resizer output pad with " << format.toString(); - - ret = mainPathResizer_->setFormat(1, &format); - if (ret < 0) - return ret; - - LOG(RkISP1, Debug) << "Resizer output pad configured with " << format.toString(); - - const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); - V4L2DeviceFormat outputFormat = {}; - outputFormat.fourcc = mainPathVideo_->toV4L2PixelFormat(cfg.pixelFormat); - outputFormat.size = cfg.size; - outputFormat.planesCount = info.numPlanes(); - - ret = mainPathVideo_->setFormat(&outputFormat); - if (ret) - return ret; - - if (outputFormat.size != cfg.size || - outputFormat.fourcc != mainPathVideo_->toV4L2PixelFormat(cfg.pixelFormat)) { - LOG(RkISP1, Error) - << "Unable to configure capture in " << cfg.toString(); - return -EINVAL; + data->mainPathActive_ = false; + data->selfPathActive_ = false; + for (const StreamConfiguration &cfg : *config) { + V4L2SubdeviceFormat ispFormat = format; + V4L2Subdevice *resizer; + V4L2VideoDevice *video; + + if (cfg.stream() == &data->mainPathStream_) { + resizer = mainPathResizer_; + video = mainPathVideo_; + data->mainPathActive_ = true; + } else { + resizer = selfPathResizer_; + video = selfPathVideo_; + data->selfPathActive_ = true; + } + + ret = resizer->setFormat(0, &ispFormat); + if (ret < 0) + return ret; + + const char *name = resizer == mainPathResizer_ ? "main" : "self"; + + LOG(RkISP1, Debug) + << "Configured " << name << " resizer input pad with " + << ispFormat.toString(); + + ispFormat.size = cfg.size; + + LOG(RkISP1, Debug) + << "Configuring " << name << " resizer output pad with " + << ispFormat.toString(); + + ret = resizer->setFormat(1, &ispFormat); + if (ret < 0) + return ret; + + LOG(RkISP1, Debug) + << "Configured " << name << " resizer output pad with " + << ispFormat.toString(); + + const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); + V4L2DeviceFormat outputFormat = {}; + outputFormat.fourcc = video->toV4L2PixelFormat(cfg.pixelFormat); + outputFormat.size = cfg.size; + outputFormat.planesCount = info.numPlanes(); + + ret = video->setFormat(&outputFormat); + if (ret) + return ret; + + if (outputFormat.size != cfg.size || + outputFormat.fourcc != video->toV4L2PixelFormat(cfg.pixelFormat)) { + LOG(RkISP1, Error) + << "Unable to configure capture in " << cfg.toString(); + return -EINVAL; + } } V4L2DeviceFormat paramFormat = {}; @@ -699,34 +729,53 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) if (ret) return ret; - cfg.setStream(&data->mainPathStream_); - return 0; } int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, Stream *stream, std::vector> *buffers) { + RkISP1CameraData *data = cameraData(camera); unsigned int count = stream->configuration().bufferCount; - return mainPathVideo_->exportBuffers(count, buffers); + + if (stream == &data->mainPathStream_) + return mainPathVideo_->exportBuffers(count, buffers); + else if (stream == &data->selfPathStream_) + return selfPathVideo_->exportBuffers(count, buffers); + + return -EINVAL; } int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) { RkISP1CameraData *data = cameraData(camera); - unsigned int count = data->mainPathStream_.configuration().bufferCount; unsigned int ipaBufferId = 1; int ret; - ret = mainPathVideo_->importBuffers(count); - if (ret < 0) - goto error; + unsigned int maxCount = std::max({ + data->mainPathStream_.configuration().bufferCount, + data->selfPathStream_.configuration().bufferCount, + }); + + if (data->mainPathActive_) { + ret = mainPathVideo_->importBuffers( + data->mainPathStream_.configuration().bufferCount); + if (ret < 0) + goto error; + } + + if (data->selfPathActive_) { + ret = selfPathVideo_->importBuffers( + data->selfPathStream_.configuration().bufferCount); + if (ret < 0) + goto error; + } - ret = param_->allocateBuffers(count, ¶mBuffers_); + ret = param_->allocateBuffers(maxCount, ¶mBuffers_); if (ret < 0) goto error; - ret = stat_->allocateBuffers(count, &statBuffers_); + ret = stat_->allocateBuffers(maxCount, &statBuffers_); if (ret < 0) goto error; @@ -752,6 +801,7 @@ error: paramBuffers_.clear(); statBuffers_.clear(); mainPathVideo_->releaseBuffers(); + selfPathVideo_->releaseBuffers(); return ret; } @@ -785,6 +835,9 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera) if (mainPathVideo_->releaseBuffers()) LOG(RkISP1, Error) << "Failed to release main path buffers"; + if (selfPathVideo_->releaseBuffers()) + LOG(RkISP1, Error) << "Failed to release self path buffers"; + return 0; } @@ -827,15 +880,47 @@ int PipelineHandlerRkISP1::start(Camera *camera) return ret; } - ret = mainPathVideo_->streamOn(); - if (ret) { - param_->streamOff(); - stat_->streamOff(); - data->ipa_->stop(); - freeBuffers(camera); - - LOG(RkISP1, Error) - << "Failed to start camera " << camera->id(); + std::map streamConfig; + + if (data->mainPathActive_) { + ret = mainPathVideo_->streamOn(); + if (ret) { + param_->streamOff(); + stat_->streamOff(); + data->ipa_->stop(); + freeBuffers(camera); + + LOG(RkISP1, Error) + << "Failed to start main path " << camera->id(); + return ret; + } + + streamConfig[0] = { + .pixelFormat = data->mainPathStream_.configuration().pixelFormat, + .size = data->mainPathStream_.configuration().size, + }; + } + + if (data->selfPathActive_) { + ret = selfPathVideo_->streamOn(); + if (ret) { + if (data->mainPathActive_) + mainPathVideo_->streamOff(); + + param_->streamOff(); + stat_->streamOff(); + data->ipa_->stop(); + freeBuffers(camera); + + LOG(RkISP1, Error) + << "Failed to start self path " << camera->id(); + return ret; + } + + streamConfig[1] = { + .pixelFormat = data->selfPathStream_.configuration().pixelFormat, + .size = data->selfPathStream_.configuration().size, + }; } activeCamera_ = camera; @@ -850,12 +935,6 @@ int PipelineHandlerRkISP1::start(Camera *camera) ret = 0; } - std::map streamConfig; - streamConfig[0] = { - .pixelFormat = data->mainPathStream_.configuration().pixelFormat, - .size = data->mainPathStream_.configuration().size, - }; - std::map entityControls; entityControls.emplace(0, data->sensor_->controls()); @@ -871,20 +950,31 @@ void PipelineHandlerRkISP1::stop(Camera *camera) RkISP1CameraData *data = cameraData(camera); int ret; - ret = mainPathVideo_->streamOff(); - if (ret) - LOG(RkISP1, Warning) - << "Failed to stop camera " << camera->id(); + if (data->selfPathActive_) { + ret = selfPathVideo_->streamOff(); + if (ret) + LOG(RkISP1, Warning) + << "Failed to stop self path for " + << camera->id(); + } + + if (data->mainPathActive_) { + ret = mainPathVideo_->streamOff(); + if (ret) + LOG(RkISP1, Warning) + << "Failed to stop main path for " + << camera->id(); + } ret = stat_->streamOff(); if (ret) LOG(RkISP1, Warning) - << "Failed to stop statistics " << camera->id(); + << "Failed to stop statistics for " << camera->id(); ret = param_->streamOff(); if (ret) LOG(RkISP1, Warning) - << "Failed to stop parameters " << camera->id(); + << "Failed to stop parameters for " << camera->id(); data->ipa_->stop(); @@ -955,11 +1045,16 @@ int PipelineHandlerRkISP1::initLinks(const Camera *camera, } for (const StreamConfiguration &cfg : config) { - if (cfg.stream() != &data->mainPathStream_) + MediaLink *link; + if (cfg.stream() == &data->mainPathStream_) + link = media_->link("rkisp1_isp", 2, + "rkisp1_resizer_mainpath", 0); + else if (cfg.stream() == &data->selfPathStream_) + link = media_->link("rkisp1_isp", 2, + "rkisp1_resizer_selfpath", 0); + else return -EINVAL; - MediaLink *link = media_->link("rkisp1_isp", 2, - "rkisp1_resizer_mainpath", 0); if (!link) return -ENODEV; From patchwork Fri Sep 25 01:41:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9810 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 E5043C3B5C for ; Fri, 25 Sep 2020 01:42:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B85F26300B; Fri, 25 Sep 2020 03:42:57 +0200 (CEST) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AED2163025 for ; Fri, 25 Sep 2020 03:42:50 +0200 (CEST) X-Halon-ID: 6b264034-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6b264034-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:49 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:57 +0200 Message-Id: <20200925014207.1455796-13-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 12/22] libcamera: pipeline: rkisp1: Track buffers for self path 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" In preparation of supporting both the main and self path extend RkISP1FrameInfo to track buffers from the self path stream. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Reviewed-by: Jacopo Mondi --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 28e99129498e4a0a..cd3049485746edd6 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -69,6 +69,7 @@ struct RkISP1FrameInfo { FrameBuffer *paramBuffer; FrameBuffer *statBuffer; FrameBuffer *mainPathBuffer; + FrameBuffer *selfPathBuffer; bool paramFilled; bool paramDequeued; @@ -272,6 +273,7 @@ RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *req FrameBuffer *statBuffer = pipe_->availableStatBuffers_.front(); FrameBuffer *mainPathBuffer = request->findBuffer(&data->mainPathStream_); + FrameBuffer *selfPathBuffer = request->findBuffer(&data->selfPathStream_); pipe_->availableParamBuffers_.pop(); pipe_->availableStatBuffers_.pop(); @@ -282,6 +284,7 @@ RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *req info->request = request; info->paramBuffer = paramBuffer; info->mainPathBuffer = mainPathBuffer; + info->selfPathBuffer = selfPathBuffer; info->statBuffer = statBuffer; info->paramFilled = false; info->paramDequeued = false; @@ -340,7 +343,8 @@ RkISP1FrameInfo *RkISP1Frames::find(FrameBuffer *buffer) if (info->paramBuffer == buffer || info->statBuffer == buffer || - info->mainPathBuffer == buffer) + info->mainPathBuffer == buffer || + info->selfPathBuffer == buffer) return info; } @@ -412,7 +416,12 @@ protected: pipe_->param_->queueBuffer(info->paramBuffer); pipe_->stat_->queueBuffer(info->statBuffer); - pipe_->mainPathVideo_->queueBuffer(info->mainPathBuffer); + + if (info->mainPathBuffer) + pipe_->mainPathVideo_->queueBuffer(info->mainPathBuffer); + + if (info->selfPathBuffer) + pipe_->selfPathVideo_->queueBuffer(info->selfPathBuffer); } private: From patchwork Fri Sep 25 01:41:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9811 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 A8F31C3B5C for ; Fri, 25 Sep 2020 01:42:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 215C060576; Fri, 25 Sep 2020 03:42:58 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9E89663025 for ; Fri, 25 Sep 2020 03:42:51 +0200 (CEST) X-Halon-ID: 6b8a842d-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6b8a842d-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:50 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:58 +0200 Message-Id: <20200925014207.1455796-14-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 13/22] libcamera: pipeline: rkisp1: Add format validation for self path 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" Extend the format validation to work with both main and self paths. The heuristics honors that the first stream in the configuration has the highest priority while still examining both streams for a best match. It is not possible to capture from the self path as the self stream is not yet exposed to applications. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- * Changes since v2 - Fix spelling in commit message. - Use Span<> instead of turning arrays to vectors. - Keep data_ const and cast 'const Streams*' to non-const using const_cast() to match the IPU3 pipeline. - Rename fitAnyPath() to fitsAllPaths(). - Expand documentation for why second stream is evaluated first if the fist stream can use either stream. - Drop support for RGB888 and RGB656 for selfpath which was present in v2 as the driver delivers odd data when the frames are observed. * Changes since v1 - Store formats in std::vector instead of std::array to avoid template usage for validate function. --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 210 +++++++++++++++++------ 1 file changed, 162 insertions(+), 48 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index cd3049485746edd6..bd53183a034efaff 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include "libcamera/internal/camera_sensor.h" @@ -50,6 +52,19 @@ constexpr std::array RKISP1_RSZ_MP_FORMATS{ formats::NV12, /* \todo Add support for 8-bit greyscale to DRM formats */ }; + +constexpr Size RKISP1_RSZ_SP_SRC_MIN{ 32, 16 }; +constexpr Size RKISP1_RSZ_SP_SRC_MAX{ 1920, 1920 }; +constexpr std::array RKISP1_RSZ_SP_FORMATS{ + formats::YUYV, + formats::YVYU, + formats::VYUY, + formats::NV16, + formats::NV61, + formats::NV21, + formats::NV12, + /* \todo Add support for BGR888 and RGB565 */ +}; } /* namespace */ class PipelineHandlerRkISP1; @@ -181,6 +196,14 @@ public: private: static constexpr unsigned int RKISP1_BUFFER_COUNT = 4; + CameraConfiguration::Status validatePath(StreamConfiguration *cfg, + const Span &formats, + const Size &min, const Size &max, + V4L2VideoDevice *video); + CameraConfiguration::Status validateMainPath(StreamConfiguration *cfg); + CameraConfiguration::Status validateSelfPath(StreamConfiguration *cfg); + bool fitsAllPaths(const StreamConfiguration &cfg); + /* * The RkISP1CameraData instance is guaranteed to be valid as long as the * corresponding Camera instance is valid. In order to borrow a @@ -492,6 +515,69 @@ RkISP1CameraConfiguration::RkISP1CameraConfiguration(Camera *camera, data_ = data; } +CameraConfiguration::Status RkISP1CameraConfiguration::validatePath( + StreamConfiguration *cfg, const Span &formats, + const Size &min, const Size &max, V4L2VideoDevice *video) +{ + const StreamConfiguration reqCfg = *cfg; + Status status = Valid; + + if (std::find(formats.begin(), formats.end(), cfg->pixelFormat) == + formats.end()) + cfg->pixelFormat = formats::NV12; + + cfg->size.boundTo(max); + cfg->size.expandTo(min); + cfg->bufferCount = RKISP1_BUFFER_COUNT; + + V4L2DeviceFormat format = {}; + format.fourcc = video->toV4L2PixelFormat(cfg->pixelFormat); + format.size = cfg->size; + + int ret = video->tryFormat(&format); + if (ret) + return Invalid; + + cfg->stride = format.planes[0].bpl; + cfg->frameSize = format.planes[0].size; + + if (cfg->pixelFormat != reqCfg.pixelFormat || cfg->size != reqCfg.size) { + LOG(RkISP1, Debug) + << "Adjusting format from " << reqCfg.toString() + << " to " << cfg->toString(); + status = Adjusted; + } + + return status; +} + +CameraConfiguration::Status RkISP1CameraConfiguration::validateMainPath(StreamConfiguration *cfg) +{ + return validatePath(cfg, RKISP1_RSZ_MP_FORMATS, RKISP1_RSZ_MP_SRC_MIN, + RKISP1_RSZ_MP_SRC_MAX, data_->mainPathVideo_); +} + +CameraConfiguration::Status RkISP1CameraConfiguration::validateSelfPath(StreamConfiguration *cfg) +{ + return validatePath(cfg, RKISP1_RSZ_SP_FORMATS, RKISP1_RSZ_SP_SRC_MIN, + RKISP1_RSZ_SP_SRC_MAX, data_->selfPathVideo_); +} + +bool RkISP1CameraConfiguration::fitsAllPaths(const StreamConfiguration &cfg) +{ + StreamConfiguration config; + + config = cfg; + if (validateMainPath(&config) != Valid) + return false; + + config = cfg; + if (validateSelfPath(&config) != Valid) + return false; + + return true; +} + CameraConfiguration::Status RkISP1CameraConfiguration::validate() { const CameraSensor *sensor = data_->sensor_; @@ -501,22 +587,87 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() return Invalid; /* Cap the number of entries to the available streams. */ - if (config_.size() > 1) { - config_.resize(1); + if (config_.size() > 2) { + config_.resize(2); status = Adjusted; } - StreamConfiguration &cfg = config_[0]; - - /* Adjust the pixel format. */ - if (std::find(RKISP1_RSZ_MP_FORMATS.begin(), RKISP1_RSZ_MP_FORMATS.end(), - cfg.pixelFormat) == RKISP1_RSZ_MP_FORMATS.end()) { - LOG(RkISP1, Debug) << "Adjusting format to NV12"; - cfg.pixelFormat = formats::NV12, - status = Adjusted; + /* + * If there are more then one stream in the configuration figure out the + * order to evaluate the streams. The first stream has the highest + * priority but if both main path and self path can satisfy it evaluate + * second stream first as the first stream is guaranteed to work with + * whichever path is not used by the second one. + */ + std::vector order(config_.size()); + std::iota(order.begin(), order.end(), 0); + if (config_.size() == 2 && fitsAllPaths(config_[0])) + std::reverse(order.begin(), order.end()); + + bool mainPathAvailable = true; + bool selfPathAvailable = true; + for (unsigned int index : order) { + StreamConfiguration &cfg = config_[index]; + + /* Try to match stream without adjusting configuration. */ + if (mainPathAvailable) { + StreamConfiguration tryCfg = cfg; + if (validateMainPath(&tryCfg) == Valid) { + mainPathAvailable = false; + cfg = tryCfg; + cfg.setStream(const_cast(&data_->mainPathStream_)); + LOG(RkISP1, Debug) << "Exact match main"; + continue; + } + } + + if (selfPathAvailable) { + StreamConfiguration tryCfg = cfg; + if (validateSelfPath(&tryCfg) == Valid) { + selfPathAvailable = false; + cfg = tryCfg; + cfg.setStream(const_cast(&data_->selfPathStream_)); + LOG(RkISP1, Debug) << "Exact match self"; + continue; + } + } + + /* Try to match stream allowing adjusting configuration. */ + if (mainPathAvailable) { + StreamConfiguration tryCfg = cfg; + if (validateMainPath(&tryCfg) == Adjusted) { + mainPathAvailable = false; + cfg = tryCfg; + cfg.setStream(const_cast(&data_->mainPathStream_)); + status = Adjusted; + LOG(RkISP1, Debug) << "Adjust match main"; + continue; + } + } + + if (selfPathAvailable) { + StreamConfiguration tryCfg = cfg; + if (validateSelfPath(&tryCfg) == Adjusted) { + selfPathAvailable = false; + cfg = tryCfg; + cfg.setStream(const_cast(&data_->selfPathStream_)); + status = Adjusted; + LOG(RkISP1, Debug) << "Adjust match self"; + continue; + } + } + + /* All paths rejected configuraiton. */ + LOG(RkISP1, Debug) << "Camera configuration not supported " + << cfg.toString(); + return Invalid; } /* Select the sensor format. */ + Size maxSize; + for (const StreamConfiguration &cfg : config_) + maxSize = std::max(maxSize, cfg.size); + sensorFormat_ = sensor->getFormat({ MEDIA_BUS_FMT_SBGGR12_1X12, MEDIA_BUS_FMT_SGBRG12_1X12, MEDIA_BUS_FMT_SGRBG12_1X12, @@ -529,47 +680,10 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() MEDIA_BUS_FMT_SGBRG8_1X8, MEDIA_BUS_FMT_SGRBG8_1X8, MEDIA_BUS_FMT_SRGGB8_1X8 }, - cfg.size); + maxSize); if (sensorFormat_.size.isNull()) sensorFormat_.size = sensor->resolution(); - /* - * Provide a suitable default that matches the sensor aspect - * ratio and clamp the size to the hardware bounds. - * - * \todo: Check the hardware alignment constraints. - */ - const Size size = cfg.size; - - if (cfg.size.isNull()) { - cfg.size.width = 1280; - cfg.size.height = 1280 * sensorFormat_.size.height - / sensorFormat_.size.width; - } - - cfg.size.boundTo(RKISP1_RSZ_MP_SRC_MAX); - cfg.size.expandTo(RKISP1_RSZ_MP_SRC_MIN); - - if (cfg.size != size) { - LOG(RkISP1, Debug) - << "Adjusting size from " << size.toString() - << " to " << cfg.size.toString(); - status = Adjusted; - } - - cfg.bufferCount = RKISP1_BUFFER_COUNT; - - V4L2DeviceFormat format = {}; - format.fourcc = data_->mainPathVideo_->toV4L2PixelFormat(cfg.pixelFormat); - format.size = cfg.size; - - int ret = data_->mainPathVideo_->tryFormat(&format); - if (ret) - return Invalid; - - cfg.stride = format.planes[0].bpl; - cfg.frameSize = format.planes[0].size; - return status; } From patchwork Fri Sep 25 01:41:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9812 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 2BF7BC3B5C for ; Fri, 25 Sep 2020 01:42:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BBABF6303C; Fri, 25 Sep 2020 03:42:58 +0200 (CEST) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3511A63023 for ; Fri, 25 Sep 2020 03:42:52 +0200 (CEST) X-Halon-ID: 6c16d15b-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6c16d15b-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:51 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:41:59 +0200 Message-Id: <20200925014207.1455796-15-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 14/22] libcamera: pipeline: rkisp1: Expose self path stream 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" Expose the self stream to applications and prefers it for the viewfinder and video roles as it can be extended to produce RGB. Keep preferring the main path for still capture as it could be extended to support RAW formats which makes most sense for still capture. With this change the self path becomes available to applications and a camera backed by this pipeline can produce two streams simultaneously. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- * Changes since v2 - Rework generation logic to grantee a stream is not picked for both roles. --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 55 +++++++++++++++++++----- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index bd53183a034efaff..27a3c44da3805c5f 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -718,17 +718,49 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera if (roles.empty()) return config; - std::map> streamFormats; - for (const PixelFormat &format : RKISP1_RSZ_MP_FORMATS) - streamFormats[format] = - { { RKISP1_RSZ_MP_SRC_MIN, data->sensor_->resolution() } }; + bool mainPathAvailable = true; + bool selfPathAvailable = true; + for (const StreamRole role : roles) { + bool useMainPath; - StreamFormats formats(streamFormats); - StreamConfiguration cfg(formats); - cfg.pixelFormat = formats::NV12; - cfg.size = data->sensor_->resolution(); + switch (role) { + case StreamRole::StillCapture: { + useMainPath = mainPathAvailable; + break; + } + case StreamRole::Viewfinder: + case StreamRole::VideoRecording: { + useMainPath = !selfPathAvailable; + break; + } + default: + LOG(RkISP1, Warning) + << "Requested stream role not supported: " << role; + delete config; + return nullptr; + } - config->addConfiguration(cfg); + std::map> streamFormats; + if (useMainPath) { + mainPathAvailable = false; + for (const PixelFormat &format : RKISP1_RSZ_MP_FORMATS) + streamFormats[format] = + { { RKISP1_RSZ_MP_SRC_MIN, data->sensor_->resolution() } }; + } else { + selfPathAvailable = false; + for (const PixelFormat &format : RKISP1_RSZ_SP_FORMATS) + streamFormats[format] = + { { RKISP1_RSZ_SP_SRC_MIN, data->sensor_->resolution() } }; + } + + StreamFormats formats(streamFormats); + StreamConfiguration cfg(formats); + cfg.pixelFormat = formats::NV12; + cfg.size = data->sensor_->resolution(); + cfg.bufferCount = 4; + + config->addConfiguration(cfg); + } config->validate(); @@ -1216,7 +1248,10 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) if (ret) return ret; - std::set streams{ &data->mainPathStream_ }; + std::set streams{ + &data->mainPathStream_, + &data->selfPathStream_, + }; std::shared_ptr camera = Camera::create(this, data->sensor_->id(), streams); registerCamera(std::move(camera), std::move(data)); From patchwork Fri Sep 25 01:42:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9813 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 A195BC3B5C for ; Fri, 25 Sep 2020 01:42:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4C5096303A; Fri, 25 Sep 2020 03:42:59 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4AD2D63044 for ; Fri, 25 Sep 2020 03:42:53 +0200 (CEST) X-Halon-ID: 6c711096-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6c711096-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:51 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:42:00 +0200 Message-Id: <20200925014207.1455796-16-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 15/22] libcamera: pipeline: rkisp1: Breakout basic path handling to own class 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 self and main paths are very similar and the introduction of support for two paths simulating sly (paths) have made it clear their handling could be abstracted in a separate class. This is the first step to create such an class by breaking out the initialization and storage of the video and subdevices. There is no functional change in this patch. Signed-off-by: Niklas Söderlund Reviewed-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/meson.build | 1 + src/libcamera/pipeline/rkisp1/rkisp1.cpp | 104 ++++++++----------- src/libcamera/pipeline/rkisp1/rkisp1path.cpp | 53 ++++++++++ src/libcamera/pipeline/rkisp1/rkisp1path.h | 46 ++++++++ 4 files changed, 144 insertions(+), 60 deletions(-) create mode 100644 src/libcamera/pipeline/rkisp1/rkisp1path.cpp create mode 100644 src/libcamera/pipeline/rkisp1/rkisp1path.h diff --git a/src/libcamera/pipeline/rkisp1/meson.build b/src/libcamera/pipeline/rkisp1/meson.build index 1ab3964a6db190f0..eddf795e54575956 100644 --- a/src/libcamera/pipeline/rkisp1/meson.build +++ b/src/libcamera/pipeline/rkisp1/meson.build @@ -2,5 +2,6 @@ libcamera_sources += files([ 'rkisp1.cpp', + 'rkisp1path.cpp', 'timeline.cpp', ]) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 27a3c44da3805c5f..e738a7eb19264d79 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -33,6 +33,7 @@ #include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_videodevice.h" +#include "rkisp1path.h" #include "timeline.h" namespace libcamera { @@ -147,12 +148,11 @@ public: class RkISP1CameraData : public CameraData { public: - RkISP1CameraData(PipelineHandler *pipe, V4L2VideoDevice *mainPathVideo, - V4L2VideoDevice *selfPathVideo) + RkISP1CameraData(PipelineHandler *pipe, RkISP1MainPath *mainPath, + RkISP1SelfPath *selfPath) : CameraData(pipe), sensor_(nullptr), frame_(0), - frameInfo_(pipe), mainPathVideo_(mainPathVideo), - selfPathVideo_(selfPathVideo), mainPathActive_(false), - selfPathActive_(false) + frameInfo_(pipe), mainPath_(mainPath), selfPath_(selfPath), + mainPathActive_(false), selfPathActive_(false) { } @@ -171,8 +171,8 @@ public: RkISP1Frames frameInfo_; RkISP1Timeline timeline_; - V4L2VideoDevice *mainPathVideo_; - V4L2VideoDevice *selfPathVideo_; + RkISP1MainPath *mainPath_; + RkISP1SelfPath *selfPath_; bool mainPathActive_; bool selfPathActive_; @@ -259,13 +259,12 @@ private: MediaDevice *media_; V4L2Subdevice *isp_; - V4L2Subdevice *mainPathResizer_; - V4L2Subdevice *selfPathResizer_; - V4L2VideoDevice *mainPathVideo_; - V4L2VideoDevice *selfPathVideo_; V4L2VideoDevice *param_; V4L2VideoDevice *stat_; + RkISP1MainPath mainPath_; + RkISP1SelfPath selfPath_; + std::vector> paramBuffers_; std::vector> statBuffers_; std::queue availableParamBuffers_; @@ -441,10 +440,10 @@ protected: pipe_->stat_->queueBuffer(info->statBuffer); if (info->mainPathBuffer) - pipe_->mainPathVideo_->queueBuffer(info->mainPathBuffer); + pipe_->mainPath_.video_->queueBuffer(info->mainPathBuffer); if (info->selfPathBuffer) - pipe_->selfPathVideo_->queueBuffer(info->selfPathBuffer); + pipe_->selfPath_.video_->queueBuffer(info->selfPathBuffer); } private: @@ -554,13 +553,13 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validatePath( CameraConfiguration::Status RkISP1CameraConfiguration::validateMainPath(StreamConfiguration *cfg) { return validatePath(cfg, RKISP1_RSZ_MP_FORMATS, RKISP1_RSZ_MP_SRC_MIN, - RKISP1_RSZ_MP_SRC_MAX, data_->mainPathVideo_); + RKISP1_RSZ_MP_SRC_MAX, data_->mainPath_->video_); } CameraConfiguration::Status RkISP1CameraConfiguration::validateSelfPath(StreamConfiguration *cfg) { return validatePath(cfg, RKISP1_RSZ_SP_FORMATS, RKISP1_RSZ_SP_SRC_MIN, - RKISP1_RSZ_SP_SRC_MAX, data_->selfPathVideo_); + RKISP1_RSZ_SP_SRC_MAX, data_->selfPath_->video_); } bool RkISP1CameraConfiguration::fitsAllPaths(const StreamConfiguration &cfg) @@ -688,9 +687,8 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() } PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) - : PipelineHandler(manager), isp_(nullptr), mainPathResizer_(nullptr), - selfPathResizer_(nullptr), mainPathVideo_(nullptr), - selfPathVideo_(nullptr), param_(nullptr), stat_(nullptr) + : PipelineHandler(manager), isp_(nullptr), param_(nullptr), + stat_(nullptr) { } @@ -698,10 +696,6 @@ PipelineHandlerRkISP1::~PipelineHandlerRkISP1() { delete param_; delete stat_; - delete mainPathVideo_; - delete selfPathVideo_; - delete mainPathResizer_; - delete selfPathResizer_; delete isp_; } @@ -821,12 +815,12 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) V4L2VideoDevice *video; if (cfg.stream() == &data->mainPathStream_) { - resizer = mainPathResizer_; - video = mainPathVideo_; + resizer = mainPath_.resizer_; + video = mainPath_.video_; data->mainPathActive_ = true; } else { - resizer = selfPathResizer_; - video = selfPathVideo_; + resizer = selfPath_.resizer_; + video = selfPath_.video_; data->selfPathActive_ = true; } @@ -834,7 +828,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) if (ret < 0) return ret; - const char *name = resizer == mainPathResizer_ ? "main" : "self"; + const char *name = resizer == mainPath_.resizer_ ? "main" : "self"; LOG(RkISP1, Debug) << "Configured " << name << " resizer input pad with " @@ -894,9 +888,9 @@ int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, S unsigned int count = stream->configuration().bufferCount; if (stream == &data->mainPathStream_) - return mainPathVideo_->exportBuffers(count, buffers); + return mainPath_.video_->exportBuffers(count, buffers); else if (stream == &data->selfPathStream_) - return selfPathVideo_->exportBuffers(count, buffers); + return selfPath_.video_->exportBuffers(count, buffers); return -EINVAL; } @@ -913,14 +907,14 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) }); if (data->mainPathActive_) { - ret = mainPathVideo_->importBuffers( + ret = mainPath_.video_->importBuffers( data->mainPathStream_.configuration().bufferCount); if (ret < 0) goto error; } if (data->selfPathActive_) { - ret = selfPathVideo_->importBuffers( + ret = selfPath_.video_->importBuffers( data->selfPathStream_.configuration().bufferCount); if (ret < 0) goto error; @@ -955,8 +949,8 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) error: paramBuffers_.clear(); statBuffers_.clear(); - mainPathVideo_->releaseBuffers(); - selfPathVideo_->releaseBuffers(); + mainPath_.video_->releaseBuffers(); + selfPath_.video_->releaseBuffers(); return ret; } @@ -987,10 +981,10 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera) if (stat_->releaseBuffers()) LOG(RkISP1, Error) << "Failed to release stat buffers"; - if (mainPathVideo_->releaseBuffers()) + if (mainPath_.video_->releaseBuffers()) LOG(RkISP1, Error) << "Failed to release main path buffers"; - if (selfPathVideo_->releaseBuffers()) + if (selfPath_.video_->releaseBuffers()) LOG(RkISP1, Error) << "Failed to release self path buffers"; return 0; @@ -1038,7 +1032,7 @@ int PipelineHandlerRkISP1::start(Camera *camera) std::map streamConfig; if (data->mainPathActive_) { - ret = mainPathVideo_->streamOn(); + ret = mainPath_.video_->streamOn(); if (ret) { param_->streamOff(); stat_->streamOff(); @@ -1057,10 +1051,10 @@ int PipelineHandlerRkISP1::start(Camera *camera) } if (data->selfPathActive_) { - ret = selfPathVideo_->streamOn(); + ret = selfPath_.video_->streamOn(); if (ret) { if (data->mainPathActive_) - mainPathVideo_->streamOff(); + mainPath_.video_->streamOff(); param_->streamOff(); stat_->streamOff(); @@ -1106,7 +1100,7 @@ void PipelineHandlerRkISP1::stop(Camera *camera) int ret; if (data->selfPathActive_) { - ret = selfPathVideo_->streamOff(); + ret = selfPath_.video_->streamOff(); if (ret) LOG(RkISP1, Warning) << "Failed to stop self path for " @@ -1114,7 +1108,7 @@ void PipelineHandlerRkISP1::stop(Camera *camera) } if (data->mainPathActive_) { - ret = mainPathVideo_->streamOff(); + ret = mainPath_.video_->streamOff(); if (ret) LOG(RkISP1, Warning) << "Failed to stop main path for " @@ -1226,8 +1220,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) int ret; std::unique_ptr data = - std::make_unique(this, mainPathVideo_, - selfPathVideo_); + std::make_unique(this, &mainPath_, &selfPath_); ControlInfoMap::Map ctrls; ctrls.emplace(std::piecewise_construct, @@ -1281,23 +1274,7 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (isp_->open() < 0) return false; - mainPathResizer_ = V4L2Subdevice::fromEntityName(media_, "rkisp1_resizer_mainpath"); - if (mainPathResizer_->open() < 0) - return false; - - selfPathResizer_ = V4L2Subdevice::fromEntityName(media_, "rkisp1_resizer_selfpath"); - if (selfPathResizer_->open() < 0) - return false; - /* Locate and open the capture video node. */ - mainPathVideo_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_mainpath"); - if (mainPathVideo_->open() < 0) - return false; - - selfPathVideo_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_selfpath"); - if (selfPathVideo_->open() < 0) - return false; - stat_ = V4L2VideoDevice::fromEntityName(media_, "rkisp1_stats"); if (stat_->open() < 0) return false; @@ -1306,8 +1283,15 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (param_->open() < 0) return false; - mainPathVideo_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); - selfPathVideo_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); + /* Locate and open the ISP main and self paths. */ + if (!mainPath_.init(media_)) + return false; + + if (!selfPath_.init(media_)) + return false; + + mainPath_.video_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); + selfPath_.video_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady); param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp new file mode 100644 index 0000000000000000..51a75df86baaaa7b --- /dev/null +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * rkisp1path.cpp - Rockchip ISP1 path helper + */ + +#include "rkisp1path.h" + +#include "libcamera/internal/media_device.h" +#include "libcamera/internal/v4l2_subdevice.h" +#include "libcamera/internal/v4l2_videodevice.h" + +namespace libcamera { + +RkISP1Path::RkISP1Path(const char *name) + : resizer_(nullptr), video_(nullptr), name_(name) +{ +} + +RkISP1Path::~RkISP1Path() +{ + delete video_; + delete resizer_; +} + +bool RkISP1Path::init(MediaDevice *media) +{ + std::string resizer = std::string("rkisp1_resizer_") + name_ + "path"; + std::string video = std::string("rkisp1_") + name_ + "path"; + + resizer_ = V4L2Subdevice::fromEntityName(media, resizer); + if (resizer_->open() < 0) + return false; + + video_ = V4L2VideoDevice::fromEntityName(media, video); + if (video_->open() < 0) + return false; + + return true; +} + +RkISP1MainPath::RkISP1MainPath() + : RkISP1Path("main") +{ +} + +RkISP1SelfPath::RkISP1SelfPath() + : RkISP1Path("self") +{ +} + +} /* namespace libcamera */ diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.h b/src/libcamera/pipeline/rkisp1/rkisp1path.h new file mode 100644 index 0000000000000000..d3172e228a3f67bf --- /dev/null +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2020, Google Inc. + * + * rkisp1path.h - Rockchip ISP1 path helper + */ +#ifndef __LIBCAMERA_PIPELINE_RKISP1_PATH_H__ +#define __LIBCAMERA_PIPELINE_RKISP1_PATH_H__ + +namespace libcamera { + +class MediaDevice; +class V4L2Subdevice; +class V4L2VideoDevice; + +class RkISP1Path +{ +public: + RkISP1Path(const char *name); + ~RkISP1Path(); + + bool init(MediaDevice *media); + + /* \todo Make resizer and video private. */ + V4L2Subdevice *resizer_; + V4L2VideoDevice *video_; + +private: + const char *name_; +}; + +class RkISP1MainPath : public RkISP1Path +{ +public: + RkISP1MainPath(); +}; + +class RkISP1SelfPath : public RkISP1Path +{ +public: + RkISP1SelfPath(); +}; + +} /* namespace libcamera */ + +#endif /* __LIBCAMERA_PIPELINE_RKISP1_PATH_H__ */ From patchwork Fri Sep 25 01:42:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9814 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 3BFE1C3B5C for ; Fri, 25 Sep 2020 01:43:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0027A63019; Fri, 25 Sep 2020 03:42:59 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0354D6303F for ; Fri, 25 Sep 2020 03:42:53 +0200 (CEST) X-Halon-ID: 6d12cf05-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6d12cf05-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:52 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:42:01 +0200 Message-Id: <20200925014207.1455796-17-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 16/22] libcamera: pipeline: rkisp1: Move path configuration to RkISP1Path 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" Move the path configuration to RkISP1Path to increase code reuse and make the V4L2 subdevice resizer private to the path. There is no functional change. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 55 +++----------------- src/libcamera/pipeline/rkisp1/rkisp1path.cpp | 55 +++++++++++++++++++- src/libcamera/pipeline/rkisp1/rkisp1path.h | 10 +++- 3 files changed, 68 insertions(+), 52 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index e738a7eb19264d79..2403eec4691b5ff6 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -810,60 +810,17 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) data->mainPathActive_ = false; data->selfPathActive_ = false; for (const StreamConfiguration &cfg : *config) { - V4L2SubdeviceFormat ispFormat = format; - V4L2Subdevice *resizer; - V4L2VideoDevice *video; - if (cfg.stream() == &data->mainPathStream_) { - resizer = mainPath_.resizer_; - video = mainPath_.video_; + ret = mainPath_.configure(cfg, format); + if (ret) + return ret; data->mainPathActive_ = true; } else { - resizer = selfPath_.resizer_; - video = selfPath_.video_; + ret = selfPath_.configure(cfg, format); + if (ret) + return ret; data->selfPathActive_ = true; } - - ret = resizer->setFormat(0, &ispFormat); - if (ret < 0) - return ret; - - const char *name = resizer == mainPath_.resizer_ ? "main" : "self"; - - LOG(RkISP1, Debug) - << "Configured " << name << " resizer input pad with " - << ispFormat.toString(); - - ispFormat.size = cfg.size; - - LOG(RkISP1, Debug) - << "Configuring " << name << " resizer output pad with " - << ispFormat.toString(); - - ret = resizer->setFormat(1, &ispFormat); - if (ret < 0) - return ret; - - LOG(RkISP1, Debug) - << "Configured " << name << " resizer output pad with " - << ispFormat.toString(); - - const PixelFormatInfo &info = PixelFormatInfo::info(cfg.pixelFormat); - V4L2DeviceFormat outputFormat = {}; - outputFormat.fourcc = video->toV4L2PixelFormat(cfg.pixelFormat); - outputFormat.size = cfg.size; - outputFormat.planesCount = info.numPlanes(); - - ret = video->setFormat(&outputFormat); - if (ret) - return ret; - - if (outputFormat.size != cfg.size || - outputFormat.fourcc != video->toV4L2PixelFormat(cfg.pixelFormat)) { - LOG(RkISP1, Error) - << "Unable to configure capture in " << cfg.toString(); - return -EINVAL; - } } V4L2DeviceFormat paramFormat = {}; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp index 51a75df86baaaa7b..758580934817ed6a 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp @@ -7,14 +7,18 @@ #include "rkisp1path.h" +#include + #include "libcamera/internal/media_device.h" #include "libcamera/internal/v4l2_subdevice.h" #include "libcamera/internal/v4l2_videodevice.h" namespace libcamera { +LOG_DECLARE_CATEGORY(RkISP1) + RkISP1Path::RkISP1Path(const char *name) - : resizer_(nullptr), video_(nullptr), name_(name) + : video_(nullptr), name_(name), resizer_(nullptr) { } @@ -40,6 +44,55 @@ bool RkISP1Path::init(MediaDevice *media) return true; } +int RkISP1Path::configure(const StreamConfiguration &config, + const V4L2SubdeviceFormat &inputFormat) +{ + int ret; + + V4L2SubdeviceFormat ispFormat = inputFormat; + + ret = resizer_->setFormat(0, &ispFormat); + if (ret < 0) + return ret; + + LOG(RkISP1, Debug) + << "Configured " << name_ << " resizer input pad with " + << ispFormat.toString(); + + ispFormat.size = config.size; + + LOG(RkISP1, Debug) + << "Configuring " << name_ << " resizer output pad with " + << ispFormat.toString(); + + ret = resizer_->setFormat(1, &ispFormat); + if (ret < 0) + return ret; + + LOG(RkISP1, Debug) + << "Configured " << name_ << " resizer output pad with " + << ispFormat.toString(); + + const PixelFormatInfo &info = PixelFormatInfo::info(config.pixelFormat); + V4L2DeviceFormat outputFormat = {}; + outputFormat.fourcc = video_->toV4L2PixelFormat(config.pixelFormat); + outputFormat.size = config.size; + outputFormat.planesCount = info.numPlanes(); + + ret = video_->setFormat(&outputFormat); + if (ret) + return ret; + + if (outputFormat.size != config.size || + outputFormat.fourcc != video_->toV4L2PixelFormat(config.pixelFormat)) { + LOG(RkISP1, Error) + << "Unable to configure capture in " << config.toString(); + return -EINVAL; + } + + return 0; +} + RkISP1MainPath::RkISP1MainPath() : RkISP1Path("main") { diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.h b/src/libcamera/pipeline/rkisp1/rkisp1path.h index d3172e228a3f67bf..6eb01529d2fddb1c 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.h @@ -12,6 +12,8 @@ namespace libcamera { class MediaDevice; class V4L2Subdevice; class V4L2VideoDevice; +struct StreamConfiguration; +struct V4L2SubdeviceFormat; class RkISP1Path { @@ -21,12 +23,16 @@ public: bool init(MediaDevice *media); - /* \todo Make resizer and video private. */ - V4L2Subdevice *resizer_; + int configure(const StreamConfiguration &config, + const V4L2SubdeviceFormat &inputFormat); + + /* \todo Make video private. */ V4L2VideoDevice *video_; private: const char *name_; + + V4L2Subdevice *resizer_; }; class RkISP1MainPath : public RkISP1Path From patchwork Fri Sep 25 01:42:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9815 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 D599CC3B5C for ; Fri, 25 Sep 2020 01:43:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8C11C63028; Fri, 25 Sep 2020 03:43:00 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0FC7563017 for ; Fri, 25 Sep 2020 03:42:55 +0200 (CEST) X-Halon-ID: 6d823e3a-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6d823e3a-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:53 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:42:02 +0200 Message-Id: <20200925014207.1455796-18-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 17/22] libcamera: pipeline: rkisp1: Move path configuration generation and validation to RkISP1Path 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" Move the path configuration generation and validation to RkISP1Path. This is done to increase code reuse and to encapsulate the main and self path differences inside the RkISP1Path class. There is no functional change. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 115 ++----------------- src/libcamera/pipeline/rkisp1/rkisp1path.cpp | 88 +++++++++++++- src/libcamera/pipeline/rkisp1/rkisp1path.h | 18 ++- 3 files changed, 112 insertions(+), 109 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 2403eec4691b5ff6..114aee3e180afb77 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include "libcamera/internal/camera_sensor.h" @@ -40,34 +39,6 @@ namespace libcamera { LOG_DEFINE_CATEGORY(RkISP1) -namespace { -constexpr Size RKISP1_RSZ_MP_SRC_MIN{ 32, 16 }; -constexpr Size RKISP1_RSZ_MP_SRC_MAX{ 4416, 3312 }; -constexpr std::array RKISP1_RSZ_MP_FORMATS{ - formats::YUYV, - formats::YVYU, - formats::VYUY, - formats::NV16, - formats::NV61, - formats::NV21, - formats::NV12, - /* \todo Add support for 8-bit greyscale to DRM formats */ -}; - -constexpr Size RKISP1_RSZ_SP_SRC_MIN{ 32, 16 }; -constexpr Size RKISP1_RSZ_SP_SRC_MAX{ 1920, 1920 }; -constexpr std::array RKISP1_RSZ_SP_FORMATS{ - formats::YUYV, - formats::YVYU, - formats::VYUY, - formats::NV16, - formats::NV61, - formats::NV21, - formats::NV12, - /* \todo Add support for BGR888 and RGB565 */ -}; -} /* namespace */ - class PipelineHandlerRkISP1; class RkISP1ActionQueueBuffers; class RkISP1CameraData; @@ -194,14 +165,6 @@ public: const V4L2SubdeviceFormat &sensorFormat() { return sensorFormat_; } private: - static constexpr unsigned int RKISP1_BUFFER_COUNT = 4; - - CameraConfiguration::Status validatePath(StreamConfiguration *cfg, - const Span &formats, - const Size &min, const Size &max, - V4L2VideoDevice *video); - CameraConfiguration::Status validateMainPath(StreamConfiguration *cfg); - CameraConfiguration::Status validateSelfPath(StreamConfiguration *cfg); bool fitsAllPaths(const StreamConfiguration &cfg); /* @@ -514,64 +477,16 @@ RkISP1CameraConfiguration::RkISP1CameraConfiguration(Camera *camera, data_ = data; } -CameraConfiguration::Status RkISP1CameraConfiguration::validatePath( - StreamConfiguration *cfg, const Span &formats, - const Size &min, const Size &max, V4L2VideoDevice *video) -{ - const StreamConfiguration reqCfg = *cfg; - Status status = Valid; - - if (std::find(formats.begin(), formats.end(), cfg->pixelFormat) == - formats.end()) - cfg->pixelFormat = formats::NV12; - - cfg->size.boundTo(max); - cfg->size.expandTo(min); - cfg->bufferCount = RKISP1_BUFFER_COUNT; - - V4L2DeviceFormat format = {}; - format.fourcc = video->toV4L2PixelFormat(cfg->pixelFormat); - format.size = cfg->size; - - int ret = video->tryFormat(&format); - if (ret) - return Invalid; - - cfg->stride = format.planes[0].bpl; - cfg->frameSize = format.planes[0].size; - - if (cfg->pixelFormat != reqCfg.pixelFormat || cfg->size != reqCfg.size) { - LOG(RkISP1, Debug) - << "Adjusting format from " << reqCfg.toString() - << " to " << cfg->toString(); - status = Adjusted; - } - - return status; -} - -CameraConfiguration::Status RkISP1CameraConfiguration::validateMainPath(StreamConfiguration *cfg) -{ - return validatePath(cfg, RKISP1_RSZ_MP_FORMATS, RKISP1_RSZ_MP_SRC_MIN, - RKISP1_RSZ_MP_SRC_MAX, data_->mainPath_->video_); -} - -CameraConfiguration::Status RkISP1CameraConfiguration::validateSelfPath(StreamConfiguration *cfg) -{ - return validatePath(cfg, RKISP1_RSZ_SP_FORMATS, RKISP1_RSZ_SP_SRC_MIN, - RKISP1_RSZ_SP_SRC_MAX, data_->selfPath_->video_); -} - bool RkISP1CameraConfiguration::fitsAllPaths(const StreamConfiguration &cfg) { StreamConfiguration config; config = cfg; - if (validateMainPath(&config) != Valid) + if (data_->mainPath_->validate(&config) != Valid) return false; config = cfg; - if (validateSelfPath(&config) != Valid) + if (data_->selfPath_->validate(&config) != Valid) return false; return true; @@ -611,7 +526,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() /* Try to match stream without adjusting configuration. */ if (mainPathAvailable) { StreamConfiguration tryCfg = cfg; - if (validateMainPath(&tryCfg) == Valid) { + if (data_->mainPath_->validate(&tryCfg) == Valid) { mainPathAvailable = false; cfg = tryCfg; cfg.setStream(const_cast(&data_->mainPathStream_)); @@ -622,7 +537,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() if (selfPathAvailable) { StreamConfiguration tryCfg = cfg; - if (validateSelfPath(&tryCfg) == Valid) { + if (data_->selfPath_->validate(&tryCfg) == Valid) { selfPathAvailable = false; cfg = tryCfg; cfg.setStream(const_cast(&data_->selfPathStream_)); @@ -634,7 +549,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() /* Try to match stream allowing adjusting configuration. */ if (mainPathAvailable) { StreamConfiguration tryCfg = cfg; - if (validateMainPath(&tryCfg) == Adjusted) { + if (data_->mainPath_->validate(&tryCfg) == Adjusted) { mainPathAvailable = false; cfg = tryCfg; cfg.setStream(const_cast(&data_->mainPathStream_)); @@ -646,7 +561,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() if (selfPathAvailable) { StreamConfiguration tryCfg = cfg; - if (validateSelfPath(&tryCfg) == Adjusted) { + if (data_->selfPath_->validate(&tryCfg) == Adjusted) { selfPathAvailable = false; cfg = tryCfg; cfg.setStream(const_cast(&data_->selfPathStream_)); @@ -734,25 +649,17 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera return nullptr; } - std::map> streamFormats; + StreamConfiguration cfg; if (useMainPath) { + cfg = data->mainPath_->generateConfiguration( + data->sensor_->resolution()); mainPathAvailable = false; - for (const PixelFormat &format : RKISP1_RSZ_MP_FORMATS) - streamFormats[format] = - { { RKISP1_RSZ_MP_SRC_MIN, data->sensor_->resolution() } }; } else { + cfg = data->selfPath_->generateConfiguration( + data->sensor_->resolution()); selfPathAvailable = false; - for (const PixelFormat &format : RKISP1_RSZ_SP_FORMATS) - streamFormats[format] = - { { RKISP1_RSZ_SP_SRC_MIN, data->sensor_->resolution() } }; } - StreamFormats formats(streamFormats); - StreamConfiguration cfg(formats); - cfg.pixelFormat = formats::NV12; - cfg.size = data->sensor_->resolution(); - cfg.bufferCount = 4; - config->addConfiguration(cfg); } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp index 758580934817ed6a..0be4d20bb1cd2094 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp @@ -7,6 +7,7 @@ #include "rkisp1path.h" +#include #include #include "libcamera/internal/media_device.h" @@ -17,8 +18,11 @@ namespace libcamera { LOG_DECLARE_CATEGORY(RkISP1) -RkISP1Path::RkISP1Path(const char *name) - : video_(nullptr), name_(name), resizer_(nullptr) +RkISP1Path::RkISP1Path(const char *name, const std::vector &formats, + const Size &minResolution, const Size &maxResolution) + : video_(nullptr), name_(name), formats_(formats), + minResolution_(minResolution), maxResolution_(maxResolution), + resizer_(nullptr) { } @@ -44,6 +48,58 @@ bool RkISP1Path::init(MediaDevice *media) return true; } +StreamConfiguration RkISP1Path::generateConfiguration(const Size &resolution) +{ + Size maxResolution = resolution; + maxResolution.boundTo(maxResolution_); + + std::map> streamFormats; + for (const PixelFormat &format : formats_) + streamFormats[format] = { { minResolution_, maxResolution } }; + + StreamFormats formats(streamFormats); + StreamConfiguration cfg(formats); + cfg.pixelFormat = formats::NV12; + cfg.size = maxResolution; + cfg.bufferCount = RKISP1_BUFFER_COUNT; + + return cfg; +} + +CameraConfiguration::Status RkISP1Path::validate(StreamConfiguration *cfg) +{ + const StreamConfiguration reqCfg = *cfg; + CameraConfiguration::Status status = CameraConfiguration::Valid; + + if (std::find(formats_.begin(), formats_.end(), cfg->pixelFormat) == + formats_.end()) + cfg->pixelFormat = formats::NV12; + + cfg->size.boundTo(maxResolution_); + cfg->size.expandTo(minResolution_); + cfg->bufferCount = RKISP1_BUFFER_COUNT; + + V4L2DeviceFormat format = {}; + format.fourcc = video_->toV4L2PixelFormat(cfg->pixelFormat); + format.size = cfg->size; + + int ret = video_->tryFormat(&format); + if (ret) + return CameraConfiguration::Invalid; + + cfg->stride = format.planes[0].bpl; + cfg->frameSize = format.planes[0].size; + + if (cfg->pixelFormat != reqCfg.pixelFormat || cfg->size != reqCfg.size) { + LOG(RkISP1, Debug) + << "Adjusting format from " << reqCfg.toString() + << " to " << cfg->toString(); + status = CameraConfiguration::Adjusted; + } + + return status; +} + int RkISP1Path::configure(const StreamConfiguration &config, const V4L2SubdeviceFormat &inputFormat) { @@ -94,12 +150,36 @@ int RkISP1Path::configure(const StreamConfiguration &config, } RkISP1MainPath::RkISP1MainPath() - : RkISP1Path("main") + : RkISP1Path("main", + { + formats::YUYV, + formats::YVYU, + formats::VYUY, + formats::NV16, + formats::NV61, + formats::NV21, + formats::NV12, + /* \todo Add support for 8-bit greyscale to DRM formats */ + }, + { 32, 16 }, + { 4416, 3312 }) { } RkISP1SelfPath::RkISP1SelfPath() - : RkISP1Path("self") + : RkISP1Path("self", + { + formats::YUYV, + formats::YVYU, + formats::VYUY, + formats::NV16, + formats::NV61, + formats::NV21, + formats::NV12, + /* \todo Add support for BGR888 and RGB565 */ + }, + { 32, 16 }, + { 1920, 1920 }) { } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.h b/src/libcamera/pipeline/rkisp1/rkisp1path.h index 6eb01529d2fddb1c..5b2917c746ee1d95 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.h @@ -7,9 +7,15 @@ #ifndef __LIBCAMERA_PIPELINE_RKISP1_PATH_H__ #define __LIBCAMERA_PIPELINE_RKISP1_PATH_H__ +#include + +#include + namespace libcamera { class MediaDevice; +class PixelFormat; +class Size; class V4L2Subdevice; class V4L2VideoDevice; struct StreamConfiguration; @@ -18,11 +24,15 @@ struct V4L2SubdeviceFormat; class RkISP1Path { public: - RkISP1Path(const char *name); + RkISP1Path(const char *name, const std::vector &formats, + const Size &minResolution, const Size &maxResolution); ~RkISP1Path(); bool init(MediaDevice *media); + StreamConfiguration generateConfiguration(const Size &resolution); + CameraConfiguration::Status validate(StreamConfiguration *cfg); + int configure(const StreamConfiguration &config, const V4L2SubdeviceFormat &inputFormat); @@ -30,8 +40,14 @@ public: V4L2VideoDevice *video_; private: + static constexpr unsigned int RKISP1_BUFFER_COUNT = 4; + const char *name_; + const std::vector formats_; + const Size minResolution_; + const Size maxResolution_; + V4L2Subdevice *resizer_; }; From patchwork Fri Sep 25 01:42:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9816 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 4B358C3B5E for ; Fri, 25 Sep 2020 01:43:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1801A63034; Fri, 25 Sep 2020 03:43:01 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B208C63012 for ; Fri, 25 Sep 2020 03:42:55 +0200 (CEST) X-Halon-ID: 6e217272-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6e217272-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:54 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:42:03 +0200 Message-Id: <20200925014207.1455796-19-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 18/22] libcamera: pipeline: rkisp1: Add wrappers for accessing the path video device 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" As a step to be able to make RkISP1Path::video_ private add simple wrappers for buffer handling. There is no functional change. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 12 ++++++------ src/libcamera/pipeline/rkisp1/rkisp1path.cpp | 6 ++++++ src/libcamera/pipeline/rkisp1/rkisp1path.h | 10 +++++++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 114aee3e180afb77..7dd4fb11c39dd811 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -403,10 +403,10 @@ protected: pipe_->stat_->queueBuffer(info->statBuffer); if (info->mainPathBuffer) - pipe_->mainPath_.video_->queueBuffer(info->mainPathBuffer); + pipe_->mainPath_.queueBuffer(info->mainPathBuffer); if (info->selfPathBuffer) - pipe_->selfPath_.video_->queueBuffer(info->selfPathBuffer); + pipe_->selfPath_.queueBuffer(info->selfPathBuffer); } private: @@ -752,9 +752,9 @@ int PipelineHandlerRkISP1::exportFrameBuffers([[maybe_unused]] Camera *camera, S unsigned int count = stream->configuration().bufferCount; if (stream == &data->mainPathStream_) - return mainPath_.video_->exportBuffers(count, buffers); + return mainPath_.exportBuffers(count, buffers); else if (stream == &data->selfPathStream_) - return selfPath_.video_->exportBuffers(count, buffers); + return selfPath_.exportBuffers(count, buffers); return -EINVAL; } @@ -1154,8 +1154,8 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (!selfPath_.init(media_)) return false; - mainPath_.video_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); - selfPath_.video_->bufferReady.connect(this, &PipelineHandlerRkISP1::bufferReady); + mainPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady); + selfPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady); stat_->bufferReady.connect(this, &PipelineHandlerRkISP1::statReady); param_->bufferReady.connect(this, &PipelineHandlerRkISP1::paramReady); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp index 0be4d20bb1cd2094..74eaa5d32388184b 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp @@ -149,6 +149,12 @@ int RkISP1Path::configure(const StreamConfiguration &config, return 0; } +int RkISP1Path::exportBuffers(unsigned int bufferCount, + std::vector> *buffers) +{ + return video_->exportBuffers(bufferCount, buffers); +} + RkISP1MainPath::RkISP1MainPath() : RkISP1Path("main", { diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.h b/src/libcamera/pipeline/rkisp1/rkisp1path.h index 5b2917c746ee1d95..1315b2c64feac681 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.h @@ -10,6 +10,9 @@ #include #include +#include + +#include "libcamera/internal/v4l2_videodevice.h" namespace libcamera { @@ -17,7 +20,6 @@ class MediaDevice; class PixelFormat; class Size; class V4L2Subdevice; -class V4L2VideoDevice; struct StreamConfiguration; struct V4L2SubdeviceFormat; @@ -36,6 +38,12 @@ public: int configure(const StreamConfiguration &config, const V4L2SubdeviceFormat &inputFormat); + int exportBuffers(unsigned int bufferCount, + std::vector> *buffers); + + int queueBuffer(FrameBuffer *buffer) { return video_->queueBuffer(buffer); } + Signal &bufferReady() { return video_->bufferReady; } + /* \todo Make video private. */ V4L2VideoDevice *video_; From patchwork Fri Sep 25 01:42:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9817 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 A140DC3B5C for ; Fri, 25 Sep 2020 01:43:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 60F186304E; Fri, 25 Sep 2020 03:43:01 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7667F6301F for ; Fri, 25 Sep 2020 03:42:56 +0200 (CEST) X-Halon-ID: 6e866392-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6e866392-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:55 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:42:04 +0200 Message-Id: <20200925014207.1455796-20-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 19/22] libcamera: pipeline: rkisp1: Move start and stop of path to RkISP1Path 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" Move the start and stop of a path to RkISP1Path. This allows the importing of buffers to be moved closer the path start/stop simplifying the code. Also by adding a simple running tracker the error logic in PipelineHandlerRkISP1 can be simplified as stop() can always be called. This also removes all external users of RkISP1Path::video_ so it can be made private. Signed-off-by: Niklas Söderlund --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 53 ++------------------ src/libcamera/pipeline/rkisp1/rkisp1path.cpp | 42 +++++++++++++++- src/libcamera/pipeline/rkisp1/rkisp1path.h | 8 +-- 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 7dd4fb11c39dd811..6158fbee41339c32 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -770,20 +770,6 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) data->selfPathStream_.configuration().bufferCount, }); - if (data->mainPathActive_) { - ret = mainPath_.video_->importBuffers( - data->mainPathStream_.configuration().bufferCount); - if (ret < 0) - goto error; - } - - if (data->selfPathActive_) { - ret = selfPath_.video_->importBuffers( - data->selfPathStream_.configuration().bufferCount); - if (ret < 0) - goto error; - } - ret = param_->allocateBuffers(maxCount, ¶mBuffers_); if (ret < 0) goto error; @@ -813,8 +799,6 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) error: paramBuffers_.clear(); statBuffers_.clear(); - mainPath_.video_->releaseBuffers(); - selfPath_.video_->releaseBuffers(); return ret; } @@ -845,12 +829,6 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera) if (stat_->releaseBuffers()) LOG(RkISP1, Error) << "Failed to release stat buffers"; - if (mainPath_.video_->releaseBuffers()) - LOG(RkISP1, Error) << "Failed to release main path buffers"; - - if (selfPath_.video_->releaseBuffers()) - LOG(RkISP1, Error) << "Failed to release self path buffers"; - return 0; } @@ -896,15 +874,12 @@ int PipelineHandlerRkISP1::start(Camera *camera) std::map streamConfig; if (data->mainPathActive_) { - ret = mainPath_.video_->streamOn(); + ret = mainPath_.start(); if (ret) { param_->streamOff(); stat_->streamOff(); data->ipa_->stop(); freeBuffers(camera); - - LOG(RkISP1, Error) - << "Failed to start main path " << camera->id(); return ret; } @@ -915,18 +890,13 @@ int PipelineHandlerRkISP1::start(Camera *camera) } if (data->selfPathActive_) { - ret = selfPath_.video_->streamOn(); + ret = selfPath_.start(); if (ret) { - if (data->mainPathActive_) - mainPath_.video_->streamOff(); - + mainPath_.stop(); param_->streamOff(); stat_->streamOff(); data->ipa_->stop(); freeBuffers(camera); - - LOG(RkISP1, Error) - << "Failed to start self path " << camera->id(); return ret; } @@ -963,21 +933,8 @@ void PipelineHandlerRkISP1::stop(Camera *camera) RkISP1CameraData *data = cameraData(camera); int ret; - if (data->selfPathActive_) { - ret = selfPath_.video_->streamOff(); - if (ret) - LOG(RkISP1, Warning) - << "Failed to stop self path for " - << camera->id(); - } - - if (data->mainPathActive_) { - ret = mainPath_.video_->streamOff(); - if (ret) - LOG(RkISP1, Warning) - << "Failed to stop main path for " - << camera->id(); - } + selfPath_.stop(); + mainPath_.stop(); ret = stat_->streamOff(); if (ret) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp index 74eaa5d32388184b..b2dd669f4caf3269 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp @@ -20,9 +20,9 @@ LOG_DECLARE_CATEGORY(RkISP1) RkISP1Path::RkISP1Path(const char *name, const std::vector &formats, const Size &minResolution, const Size &maxResolution) - : video_(nullptr), name_(name), formats_(formats), + : name_(name), running_(false), formats_(formats), minResolution_(minResolution), maxResolution_(maxResolution), - resizer_(nullptr) + resizer_(nullptr), video_(nullptr) { } @@ -155,6 +155,44 @@ int RkISP1Path::exportBuffers(unsigned int bufferCount, return video_->exportBuffers(bufferCount, buffers); } +int RkISP1Path::start() +{ + int ret; + + if (running_) + return -EBUSY; + + ret = video_->importBuffers(RKISP1_BUFFER_COUNT); + if (ret) + return ret; + + ret = video_->streamOn(); + if (ret) { + LOG(RkISP1, Error) + << "Failed to start " << name_ << "path"; + + video_->releaseBuffers(); + return ret; + } + + running_ = true; + + return 0; +} + +void RkISP1Path::stop() +{ + if (!running_) + return; + + if (video_->streamOff()) + LOG(RkISP1, Warning) << "Failed to stop " << name_ << "path"; + + video_->releaseBuffers(); + + running_ = false; +} + RkISP1MainPath::RkISP1MainPath() : RkISP1Path("main", { diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.h b/src/libcamera/pipeline/rkisp1/rkisp1path.h index 1315b2c64feac681..9c2ecb620375683b 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.h @@ -41,22 +41,24 @@ public: int exportBuffers(unsigned int bufferCount, std::vector> *buffers); + int start(); + void stop(); + int queueBuffer(FrameBuffer *buffer) { return video_->queueBuffer(buffer); } Signal &bufferReady() { return video_->bufferReady; } - /* \todo Make video private. */ - V4L2VideoDevice *video_; - private: static constexpr unsigned int RKISP1_BUFFER_COUNT = 4; const char *name_; + bool running_; const std::vector formats_; const Size minResolution_; const Size maxResolution_; V4L2Subdevice *resizer_; + V4L2VideoDevice *video_; }; class RkISP1MainPath : public RkISP1Path From patchwork Fri Sep 25 01:42:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9818 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 E4B6AC3B5C for ; Fri, 25 Sep 2020 01:43:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BFE0B6302C; Fri, 25 Sep 2020 03:43:03 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1CB7F60576 for ; Fri, 25 Sep 2020 03:42:57 +0200 (CEST) X-Halon-ID: 6eff0769-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6eff0769-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:55 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:42:05 +0200 Message-Id: <20200925014207.1455796-21-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 20/22] libcamera: pipeline: rkisp1: Move path link handling to RkISP1Path 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" Move the path link handling to RkISP1Path, there is no functional change. Signed-off-by: Niklas Söderlund Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 11 ++--------- src/libcamera/pipeline/rkisp1/rkisp1path.cpp | 6 +++++- src/libcamera/pipeline/rkisp1/rkisp1path.h | 4 ++++ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 6158fbee41339c32..e41a9a51bda576b0 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1015,20 +1015,13 @@ int PipelineHandlerRkISP1::initLinks(const Camera *camera, } for (const StreamConfiguration &cfg : config) { - MediaLink *link; if (cfg.stream() == &data->mainPathStream_) - link = media_->link("rkisp1_isp", 2, - "rkisp1_resizer_mainpath", 0); + ret = data->mainPath_->enable(); else if (cfg.stream() == &data->selfPathStream_) - link = media_->link("rkisp1_isp", 2, - "rkisp1_resizer_selfpath", 0); + ret = data->selfPath_->enable(); else return -EINVAL; - if (!link) - return -ENODEV; - - ret = link->setEnabled(true); if (ret < 0) return ret; } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp index b2dd669f4caf3269..8010cb92423c8269 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp @@ -22,7 +22,7 @@ RkISP1Path::RkISP1Path(const char *name, const std::vector &formats const Size &minResolution, const Size &maxResolution) : name_(name), running_(false), formats_(formats), minResolution_(minResolution), maxResolution_(maxResolution), - resizer_(nullptr), video_(nullptr) + resizer_(nullptr), video_(nullptr), link_(nullptr) { } @@ -45,6 +45,10 @@ bool RkISP1Path::init(MediaDevice *media) if (video_->open() < 0) return false; + link_ = media->link("rkisp1_isp", 2, resizer, 0); + if (!link_) + return false; + return true; } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.h b/src/libcamera/pipeline/rkisp1/rkisp1path.h index 9c2ecb620375683b..f57f4b646c3a3164 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.h @@ -12,6 +12,7 @@ #include #include +#include "libcamera/internal/media_object.h" #include "libcamera/internal/v4l2_videodevice.h" namespace libcamera { @@ -32,6 +33,8 @@ public: bool init(MediaDevice *media); + int enable() { return link_->setEnabled(true); } + StreamConfiguration generateConfiguration(const Size &resolution); CameraConfiguration::Status validate(StreamConfiguration *cfg); @@ -59,6 +62,7 @@ private: V4L2Subdevice *resizer_; V4L2VideoDevice *video_; + MediaLink *link_; }; class RkISP1MainPath : public RkISP1Path From patchwork Fri Sep 25 01:42:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9819 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 1C4F6C3B5E for ; Fri, 25 Sep 2020 01:43:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id E48786303A; Fri, 25 Sep 2020 03:43:03 +0200 (CEST) Received: from bin-mail-out-06.binero.net (bin-mail-out-06.binero.net [195.74.38.229]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D5C506302E for ; Fri, 25 Sep 2020 03:42:57 +0200 (CEST) X-Halon-ID: 6f5dafd1-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6f5dafd1-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:56 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:42:06 +0200 Message-Id: <20200925014207.1455796-22-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 21/22] libcamera: pipeline: rkisp1: Use the media link to track if a path is enabled 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 manually track if a path is enable or not use the media graph link status. This enables RkISP1Path::start() to check the link status thus allowing it to always be called from PipelineHandlerRkISP1::start() making the code simpler. There is no functional changed. Signed-off-by: Niklas Söderlund --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 82 +++++++++----------- src/libcamera/pipeline/rkisp1/rkisp1path.cpp | 3 + src/libcamera/pipeline/rkisp1/rkisp1path.h | 1 + 3 files changed, 39 insertions(+), 47 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index e41a9a51bda576b0..c6c2e3aa3dc6d0dc 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -122,8 +122,7 @@ public: RkISP1CameraData(PipelineHandler *pipe, RkISP1MainPath *mainPath, RkISP1SelfPath *selfPath) : CameraData(pipe), sensor_(nullptr), frame_(0), - frameInfo_(pipe), mainPath_(mainPath), selfPath_(selfPath), - mainPathActive_(false), selfPathActive_(false) + frameInfo_(pipe), mainPath_(mainPath), selfPath_(selfPath) { } @@ -145,9 +144,6 @@ public: RkISP1MainPath *mainPath_; RkISP1SelfPath *selfPath_; - bool mainPathActive_; - bool selfPathActive_; - private: void queueFrameAction(unsigned int frame, const IPAOperationData &action); @@ -714,20 +710,14 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) LOG(RkISP1, Debug) << "ISP output pad configured with " << format.toString(); - data->mainPathActive_ = false; - data->selfPathActive_ = false; for (const StreamConfiguration &cfg : *config) { - if (cfg.stream() == &data->mainPathStream_) { + if (cfg.stream() == &data->mainPathStream_) ret = mainPath_.configure(cfg, format); - if (ret) - return ret; - data->mainPathActive_ = true; - } else { + else ret = selfPath_.configure(cfg, format); - if (ret) - return ret; - data->selfPathActive_ = true; - } + + if (ret) + return ret; } V4L2DeviceFormat paramFormat = {}; @@ -871,39 +861,23 @@ int PipelineHandlerRkISP1::start(Camera *camera) return ret; } - std::map streamConfig; - - if (data->mainPathActive_) { - ret = mainPath_.start(); - if (ret) { - param_->streamOff(); - stat_->streamOff(); - data->ipa_->stop(); - freeBuffers(camera); - return ret; - } - - streamConfig[0] = { - .pixelFormat = data->mainPathStream_.configuration().pixelFormat, - .size = data->mainPathStream_.configuration().size, - }; + ret = mainPath_.start(); + if (ret) { + param_->streamOff(); + stat_->streamOff(); + data->ipa_->stop(); + freeBuffers(camera); + return ret; } - if (data->selfPathActive_) { - ret = selfPath_.start(); - if (ret) { - mainPath_.stop(); - param_->streamOff(); - stat_->streamOff(); - data->ipa_->stop(); - freeBuffers(camera); - return ret; - } - - streamConfig[1] = { - .pixelFormat = data->selfPathStream_.configuration().pixelFormat, - .size = data->selfPathStream_.configuration().size, - }; + ret = selfPath_.start(); + if (ret) { + mainPath_.stop(); + param_->streamOff(); + stat_->streamOff(); + data->ipa_->stop(); + freeBuffers(camera); + return ret; } activeCamera_ = camera; @@ -918,6 +892,20 @@ int PipelineHandlerRkISP1::start(Camera *camera) ret = 0; } + std::map streamConfig; + if (data->mainPath_->isEnabled()) { + streamConfig[0] = { + .pixelFormat = data->mainPathStream_.configuration().pixelFormat, + .size = data->mainPathStream_.configuration().size, + }; + } + if (data->selfPath_->isEnabled()) { + streamConfig[1] = { + .pixelFormat = data->selfPathStream_.configuration().pixelFormat, + .size = data->selfPathStream_.configuration().size, + }; + } + std::map entityControls; entityControls.emplace(0, data->sensor_->controls()); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp index 8010cb92423c8269..623ee91888acd983 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.cpp @@ -163,6 +163,9 @@ int RkISP1Path::start() { int ret; + if (!isEnabled()) + return 0; + if (running_) return -EBUSY; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1path.h b/src/libcamera/pipeline/rkisp1/rkisp1path.h index f57f4b646c3a3164..01f9c751f9e54c64 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1path.h @@ -34,6 +34,7 @@ public: bool init(MediaDevice *media); int enable() { return link_->setEnabled(true); } + bool isEnabled() { return link_->flags() & MEDIA_LNK_FL_ENABLED; } StreamConfiguration generateConfiguration(const Size &resolution); CameraConfiguration::Status validate(StreamConfiguration *cfg); From patchwork Fri Sep 25 01:42:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Niklas_S=C3=B6derlund?= X-Patchwork-Id: 9820 X-Patchwork-Delegate: niklas.soderlund@ragnatech.se 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 77DF8C3B5F for ; Fri, 25 Sep 2020 01:43:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1CA6463019; Fri, 25 Sep 2020 03:43:04 +0200 (CEST) Received: from bin-mail-out-05.binero.net (bin-mail-out-05.binero.net [195.74.38.228]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6072063034 for ; Fri, 25 Sep 2020 03:42:58 +0200 (CEST) X-Halon-ID: 6fca2bdb-fed0-11ea-92dc-005056917a89 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-01.atm.binero.net (Halon) with ESMTPA id 6fca2bdb-fed0-11ea-92dc-005056917a89; Fri, 25 Sep 2020 03:42:57 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Fri, 25 Sep 2020 03:42:07 +0200 Message-Id: <20200925014207.1455796-23-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> References: <20200925014207.1455796-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 22/22] libcamera: pipeline: rkisp1: Use cleanup error paths for 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" Use a lambda function to make the error paths a bit cleaner in start(), no functional change. Signed-off-by: Niklas Söderlund --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 98 ++++++++++++------------ 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index c6c2e3aa3dc6d0dc..34196af3057b14bb 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -827,58 +827,62 @@ int PipelineHandlerRkISP1::start(Camera *camera) RkISP1CameraData *data = cameraData(camera); int ret; - /* Allocate buffers for internal pipeline usage. */ - ret = allocateBuffers(camera); - if (ret) - return ret; - - ret = data->ipa_->start(); - if (ret) { - freeBuffers(camera); - LOG(RkISP1, Error) - << "Failed to start IPA " << camera->id(); - return ret; - } - - data->frame_ = 0; - - ret = param_->streamOn(); - if (ret) { - data->ipa_->stop(); - freeBuffers(camera); - LOG(RkISP1, Error) - << "Failed to start parameters " << camera->id(); - return ret; - } - - ret = stat_->streamOn(); - if (ret) { - param_->streamOff(); - data->ipa_->stop(); - freeBuffers(camera); - LOG(RkISP1, Error) - << "Failed to start statistics " << camera->id(); - return ret; - } - - ret = mainPath_.start(); - if (ret) { - param_->streamOff(); - stat_->streamOff(); - data->ipa_->stop(); - freeBuffers(camera); - return ret; - } - - ret = selfPath_.start(); - if (ret) { + auto startDevices = [this](Camera *camera, RkISP1CameraData *data) { + int ret; + + /* Allocate buffers for internal pipeline usage. */ + ret = allocateBuffers(camera); + if (ret) + return ret; + + ret = data->ipa_->start(); + if (ret) { + LOG(RkISP1, Error) + << "Failed to start IPA " << camera->id(); + goto err_allocate; + } + + data->frame_ = 0; + + ret = param_->streamOn(); + if (ret) { + LOG(RkISP1, Error) + << "Failed to start parameters " << camera->id(); + goto err_ipa; + } + + ret = stat_->streamOn(); + if (ret) { + LOG(RkISP1, Error) + << "Failed to start statistics " << camera->id(); + goto err_param; + } + + ret = mainPath_.start(); + if (ret) + goto err_stat; + + ret = selfPath_.start(); + if (ret) + goto err_main; + + return 0; + err_main: mainPath_.stop(); - param_->streamOff(); + err_stat: stat_->streamOff(); + err_param: + param_->streamOff(); + err_ipa: data->ipa_->stop(); + err_allocate: freeBuffers(camera); return ret; - } + }; + + ret = startDevices(camera, data); + if (ret) + return ret; activeCamera_ = camera;