From patchwork Tue Apr 16 22:08:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 1021 Return-Path: Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 88FAE60DCE for ; Wed, 17 Apr 2019 00:08:55 +0200 (CEST) Received: from pendragon.bb.dnainternet.fi (dfj612yhrgyx302h3jwwy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:ce28:277f:58d7:3ca4]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2B9832BA for ; Wed, 17 Apr 2019 00:08:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1555452535; bh=9ceZmuZ/MTu5Mhpo/nBsm3sTOyjsUmxf8y++Mtlj+Mk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=eCcD8mgsrbTOKoRuSjALuE3ikw4F4Z98m0Qkj1Z8Un6aigiIM2gwZK7iP1c/A2gDf +P9sbd+tO0q9xoaGfoQxm0tBcWmTQGOJqwARDg0SifJP00+sesrOQPhDz6k9cqfsVM YtQIlAGuPZU03XnakH9fU6UozjgcnLFu6qzO0BIA= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Wed, 17 Apr 2019 01:08:38 +0300 Message-Id: <20190416220839.1577-13-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190416220839.1577-1-laurent.pinchart@ideasonboard.com> References: <20190416220839.1577-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 12/13] libcamera: pipeline: ipu3: Use the new CameraSensor class X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Apr 2019 22:08:56 -0000 Replace the manual handling of sensor formats with usage of the new CameraSensor class. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- Changes since v1: - Move sensor entity function check to CameraSensor class - Verify sensor media bus codes at init time --- src/libcamera/pipeline/ipu3/ipu3.cpp | 107 +++++++++------------------ 1 file changed, 36 insertions(+), 71 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index e3c79f93963e..861c0da7550a 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -5,6 +5,7 @@ * ipu3.cpp - Pipeline handler for Intel IPU3 */ +#include #include #include #include @@ -15,6 +16,7 @@ #include #include +#include "camera_sensor.h" #include "device_enumerator.h" #include "log.h" #include "media_device.h" @@ -124,11 +126,7 @@ public: V4L2Device *output_; V4L2Subdevice *csi2_; - V4L2Subdevice *sensor_; - - /* Maximum sizes and the mbus code used to produce them. */ - unsigned int mbusCode_; - Size maxSize_; + CameraSensor *sensor_; BufferPool pool_; }; @@ -255,8 +253,9 @@ int PipelineHandlerIPU3::configureStreams(Camera *camera, return -EINVAL; } - if (cfg.width > cio2->maxSize_.width || - cfg.height > cio2->maxSize_.height) { + const Size &resolution = cio2->sensor_->resolution(); + if (cfg.width > resolution.width || + cfg.height > resolution.height) { LOG(IPU3, Error) << "Invalid stream size: larger than sensor resolution"; return -EINVAL; @@ -1021,45 +1020,39 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index) MediaLink *link = links[0]; MediaEntity *sensorEntity = link->source()->entity(); - if (sensorEntity->function() != MEDIA_ENT_F_CAM_SENSOR) - return -ENODEV; + sensor_ = new CameraSensor(sensorEntity); + ret = sensor_->init(); + if (ret) + return ret; ret = link->setEnabled(true); if (ret) return ret; /* - * Now that we're sure a sensor subdevice is connected, make sure it - * produces at least one image format compatible with CIO2 requirements - * and cache the camera maximum size. + * Make sure the sensor produces at least one format compatible with + * the CIO2 requirements. * + * utils::set_overlap requires the ranges to be sorted, keep the + * cio2Codes vector sorted in ascending order. + */ + const std::vector cio2Codes{ MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10 }; + const std::vector &sensorCodes = sensor_->mbusCodes(); + if (!utils::set_overlap(sensorCodes.begin(), sensorCodes.end(), + cio2Codes.begin(), cio2Codes.end())) { + LOG(IPU3, Error) + << "Sensor " << sensor_->entity()->name() + << " has not format compatible with the IPU3"; + return -EINVAL; + } + + /* * \todo Define when to open and close video device nodes, as they * might impact on power consumption. */ - sensor_ = new V4L2Subdevice(sensorEntity); - ret = sensor_->open(); - if (ret) - return ret; - - for (auto it : sensor_->formats(0)) { - int mbusCode = mediaBusToFormat(it.first); - if (mbusCode < 0) - continue; - - for (const SizeRange &size : it.second) { - if (maxSize_.width < size.max.width && - maxSize_.height < size.max.height) { - maxSize_ = size.max; - mbusCode_ = mbusCode; - } - } - } - if (maxSize_.width == 0) { - LOG(IPU3, Info) << "Sensor '" << sensor_->entity()->name() - << "' detected, but no supported image format " - << " found: skip camera creation"; - return -ENODEV; - } csi2_ = new V4L2Subdevice(csi2Entity); ret = csi2_->open(); @@ -1085,47 +1078,19 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index) int CIO2Device::configure(const StreamConfiguration &config, V4L2DeviceFormat *outputFormat) { - unsigned int imageSize = config.width * config.height; - V4L2SubdeviceFormat sensorFormat = {}; - unsigned int best = ~0; + V4L2SubdeviceFormat sensorFormat; int ret; - for (auto it : sensor_->formats(0)) { - /* Only consider formats consumable by the CIO2 unit. */ - if (mediaBusToFormat(it.first) < 0) - continue; - - for (const SizeRange &size : it.second) { - /* - * Only select formats bigger than the requested sizes - * as the IPU3 cannot up-scale. - * - * \todo: Unconditionally scale on the sensor as much - * as possible. This will need to be revisited when - * implementing the scaling policy. - */ - if (size.max.width < config.width || - size.max.height < config.height) - continue; - - unsigned int diff = size.max.width * size.max.height - - imageSize; - if (diff >= best) - continue; - - best = diff; - - sensorFormat.width = size.max.width; - sensorFormat.height = size.max.height; - sensorFormat.mbus_code = it.first; - } - } - /* * Apply the selected format to the sensor, the CSI-2 receiver and * the CIO2 output device. */ - ret = sensor_->setFormat(0, &sensorFormat); + sensorFormat = sensor_->getFormat({ MEDIA_BUS_FMT_SBGGR10_1X10, + MEDIA_BUS_FMT_SGBRG10_1X10, + MEDIA_BUS_FMT_SGRBG10_1X10, + MEDIA_BUS_FMT_SRGGB10_1X10 }, + Size(config.width, config.height)); + ret = sensor_->setFormat(&sensorFormat); if (ret) return ret;