From patchwork Wed Jul 1 12:30:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8535 X-Patchwork-Delegate: jacopo@jmondi.org 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 BE446C2E69 for ; Wed, 1 Jul 2020 12:27:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9818860CDD; Wed, 1 Jul 2020 14:27:26 +0200 (CEST) Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DA8FF60C62 for ; Wed, 1 Jul 2020 14:27:23 +0200 (CEST) X-Originating-IP: 93.34.118.233 Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 77E851C0007; Wed, 1 Jul 2020 12:27:23 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Wed, 1 Jul 2020 14:30:29 +0200 Message-Id: <20200701123036.51922-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200701123036.51922-1-jacopo@jmondi.org> References: <20200701123036.51922-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/15] libcamera: ipu3: Assign streams at configure() time 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" Assign streams to StreamConfiguration at configure() time, instead of doing so during validation. This allows easier computation of stream assignement and will allow removing the vector of stream instances from the IPU3CameraConfiguration. Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 146 +++++++++++++-------------- 1 file changed, 69 insertions(+), 77 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 651e0c93a7ab..8f75c5186b13 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -67,8 +67,6 @@ public: const std::vector &streams() { return streams_; } private: - void assignStreams(); - /* * The IPU3CameraData instance is guaranteed to be valid as long as the * corresponding Camera instance is valid. In order to borrow a @@ -133,50 +131,6 @@ IPU3CameraConfiguration::IPU3CameraConfiguration(Camera *camera, data_ = data; } -void IPU3CameraConfiguration::assignStreams() -{ - /* - * Verify and update all configuration entries, and assign a stream to - * each of them. The viewfinder stream can scale, while the output - * stream can crop only, so select the output stream when the requested - * resolution is equal to the sensor resolution, and the viewfinder - * stream otherwise. - */ - std::set availableStreams = { - &data_->outStream_, - &data_->vfStream_, - &data_->rawStream_, - }; - - /* - * The caller is responsible to limit the number of requested streams - * to a number supported by the pipeline before calling this function. - */ - ASSERT(availableStreams.size() >= config_.size()); - - streams_.clear(); - streams_.reserve(config_.size()); - - for (const StreamConfiguration &cfg : config_) { - const PixelFormatInfo &info = - PixelFormatInfo::info(cfg.pixelFormat); - const Stream *stream; - - if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) - stream = &data_->rawStream_; - else if (cfg.size == cio2Configuration_.size) - stream = &data_->outStream_; - else - stream = &data_->vfStream_; - - if (availableStreams.find(stream) == availableStreams.end()) - stream = *availableStreams.begin(); - - streams_.push_back(stream); - availableStreams.erase(stream); - } -} - CameraConfiguration::Status IPU3CameraConfiguration::validate() { Status status = Valid; @@ -209,9 +163,6 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate() if (!cio2Configuration_.pixelFormat.isValid()) return Invalid; - /* Assign streams to each configuration entry. */ - assignStreams(); - /* Verify and adjust configuration if needed. */ unsigned int rawCount = 0; unsigned int outCount = 0; @@ -385,9 +336,6 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) IPU3CameraConfiguration *config = static_cast(c); IPU3CameraData *data = cameraData(camera); - Stream *outStream = &data->outStream_; - Stream *vfStream = &data->vfStream_; - CIO2Device *cio2 = &data->cio2_; ImgUDevice *imgu = data->imgu_; V4L2DeviceFormat outputFormat; int ret; @@ -435,12 +383,36 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) return ret; /* - * Pass the requested stream size to the CIO2 unit and get back the - * adjusted format to be propagated to the ImgU output devices. + * Identify the maximum sizes and the number of non-raw streams + * requested. + */ + unsigned int outCount = 0; + Size maxOut; + for (unsigned int i = 0; i < config->size(); ++i) { + const StreamConfiguration &cfg = (*config)[i]; + const PixelFormatInfo &info = + PixelFormatInfo::info(cfg.pixelFormat); + + /* + * We have validated that only one raw stream can be requested + * and the CIO2 configuration has been set during validation. + */ + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) + continue; + + /* Get the largest size of the two available processed streams. */ + if (maxOut < cfg.size) + maxOut = cfg.size; + outCount++; + } + + /* + * Configure the CIO2 unit with the format computed during validation + * and apply the same format to the ImgU input. */ const Size &sensorSize = config->cio2Format().size; V4L2DeviceFormat cio2Format = {}; - ret = cio2->configure(sensorSize, &cio2Format); + ret = data->cio2_.configure(sensorSize, &cio2Format); if (ret) return ret; @@ -451,40 +423,60 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) /* Apply the format to the configured streams output devices. */ bool outActive = false; bool vfActive = false; - for (unsigned int i = 0; i < config->size(); ++i) { - /* - * Use a const_cast<> here instead of storing a mutable stream - * pointer in the configuration to let the compiler catch - * unwanted modifications of camera data in the configuration - * validate() implementation. - */ - Stream *stream = const_cast(config->streams()[i]); StreamConfiguration &cfg = (*config)[i]; + const PixelFormatInfo &info = + PixelFormatInfo::info(cfg.pixelFormat); + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW) { + /* + * The RAW stream is configured as part of the CIO2 and + * no configuration is needed for the ImgU. + */ + cfg.setStream(&data->rawStream_); + cfg.stride = cio2Format.planes[0].bpl; - cfg.setStream(stream); + LOG(IPU3, Debug) << "Assigned " << cfg.toString() + << " to the raw output"; + continue; + } - if (stream == outStream) { + /* + * The viewfinder stream can scale, while the main output stream + * can crop only. Select the main output for the largest + * non-raw stream only if another smaller one has been + * requested. + */ + if (cfg.size == maxOut && outCount > 1) { ret = imgu->configureOutput(cfg, &outputFormat); if (ret) return ret; cfg.stride = outputFormat.planes[0].bpl; + cfg.setStream(&data->outStream_); outActive = true; - } else if (stream == vfStream) { - ret = imgu->configureViewfinder(cfg, &outputFormat); - if (ret) - return ret; - cfg.stride = outputFormat.planes[0].bpl; - vfActive = true; - } else { - /* - * The RAW stream is configured as part of the CIO2 and - * no configuration is needed for the ImgU. - */ - cfg.stride = cio2Format.planes[0].bpl; + LOG(IPU3, Debug) << "Assigned " << cfg.toString() + << " to the main output"; + continue; } + + /* + * If a single non-raw stream has been requested, assign it to + * the viewfinder output regardless of its size. If more than + * one non-raw stream has been requested, assign to viewfinder + * the smaller one to reduce the cropping required (if any) on + * the main output. + */ + ret = imgu->configureViewfinder(cfg, &outputFormat); + if (ret) + return ret; + + cfg.stride = outputFormat.planes[0].bpl; + cfg.setStream(&data->vfStream_); + vfActive = true; + + LOG(IPU3, Debug) << "Assigned " << cfg.toString() + << " to the viewfinder output"; } /*