From patchwork Mon Sep 14 14:21: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: 9602 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 4B637BF01C for ; Mon, 14 Sep 2020 14:22:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 204BF62E0D; Mon, 14 Sep 2020 16:22:17 +0200 (CEST) Received: from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net [195.74.38.227]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2935162DF9 for ; Mon, 14 Sep 2020 16:22:14 +0200 (CEST) X-Halon-ID: ae99bf3c-f695-11ea-a39b-005056917f90 Authorized-sender: niklas.soderlund@fsdn.se Received: from bismarck.berto.se (p54ac52a8.dip0.t-ipconnect.de [84.172.82.168]) by bin-vsp-out-02.atm.binero.net (Halon) with ESMTPA id ae99bf3c-f695-11ea-a39b-005056917f90; Mon, 14 Sep 2020 16:22:13 +0200 (CEST) From: =?utf-8?q?Niklas_S=C3=B6derlund?= To: libcamera-devel@lists.libcamera.org Date: Mon, 14 Sep 2020 16:21:46 +0200 Message-Id: <20200914142149.63857-11-niklas.soderlund@ragnatech.se> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200914142149.63857-1-niklas.soderlund@ragnatech.se> References: <20200914142149.63857-1-niklas.soderlund@ragnatech.se> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 10/13] 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 --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 200 ++++++++++++++++------- 1 file changed, 141 insertions(+), 59 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 5aa01f87afd71183..01cd461427e3a6dc 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); @@ -617,7 +622,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; @@ -659,37 +663,55 @@ 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; + + LOG(RkISP1, Debug) << "Resizer input pad configured with " << ispFormat.toString(); + + ispFormat.size = cfg.size; + + LOG(RkISP1, Debug) << "Configuring resizer output pad with " << ispFormat.toString(); + + ret = resizer->setFormat(1, &ispFormat); + if (ret < 0) + return ret; + + LOG(RkISP1, Debug) << "Resizer output pad configured 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 = {}; @@ -704,28 +726,46 @@ 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); + + 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 count = std::max({ + data->mainPathStream_.configuration().bufferCount, + data->selfPathStream_.configuration().bufferCount, + }); + + if (data->mainPathActive_) { + ret = mainPathVideo_->importBuffers(count); + if (ret < 0) + goto error; + } + + if (data->selfPathActive_) { + ret = selfPathVideo_->importBuffers(count); + if (ret < 0) + goto error; + } ret = param_->allocateBuffers(count, ¶mBuffers_); if (ret < 0) @@ -757,6 +797,7 @@ error: paramBuffers_.clear(); statBuffers_.clear(); mainPathVideo_->releaseBuffers(); + selfPathVideo_->releaseBuffers(); return ret; } @@ -790,6 +831,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; } @@ -832,15 +876,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; @@ -855,12 +931,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()); @@ -876,10 +946,19 @@ 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 " << camera->id(); + } + + if (data->mainPathActive_) { + ret = mainPathVideo_->streamOff(); + if (ret) + LOG(RkISP1, Warning) + << "Failed to stop main path " << camera->id(); + } ret = stat_->streamOff(); if (ret) @@ -964,6 +1043,9 @@ int PipelineHandlerRkISP1::initLinks(const Camera *camera, 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;