From patchwork Mon Jun 29 11:53:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 8498 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 3DA93BF415 for ; Mon, 29 Jun 2020 11:50:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 199C160A16; Mon, 29 Jun 2020 13:50:17 +0200 (CEST) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CEE52609D6 for ; Mon, 29 Jun 2020 13:50:13 +0200 (CEST) Received: from uno.lan (93-34-118-233.ip49.fastwebnet.it [93.34.118.233]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 3461E100013; Mon, 29 Jun 2020 11:50:13 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Mon, 29 Jun 2020 13:53:28 +0200 Message-Id: <20200629115328.16273-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200629115328.16273-1-jacopo@jmondi.org> References: <20200629105037.14706-1-jacopo@jmondi.org> <20200629115328.16273-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v3 4/4] libcamera: v4l2_videodevice: Use ImageFormats 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" ImageFormats was meant to be used not only for V4L2Subdevice but for video devices as well. Since the introduction of of V4L2PixelFormat the V4L2VideoDevice class and its users have been using a raw map to enumerate and inspect the V4L2VideoDevice formats. Provide a V4L2VideoDevice::Formats type definition as for V4L2Subdevice and use ImageFormats wherever possible in pipeline handlers. Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- include/libcamera/internal/v4l2_videodevice.h | 4 +++- .../pipeline/raspberrypi/raspberrypi.cpp | 21 +++++++++---------- src/libcamera/pipeline/simple/converter.cpp | 2 +- src/libcamera/pipeline/simple/simple.cpp | 7 +++---- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 7 +++---- src/libcamera/v4l2_videodevice.cpp | 14 +++++++++---- 6 files changed, 30 insertions(+), 25 deletions(-) -- 2.27.0 diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h index 4d21f5a01ec8..06c65e863a99 100644 --- a/include/libcamera/internal/v4l2_videodevice.h +++ b/include/libcamera/internal/v4l2_videodevice.h @@ -168,6 +168,8 @@ public: class V4L2VideoDevice : public V4L2Device { public: + using Formats = ImageFormats; + explicit V4L2VideoDevice(const std::string &deviceNode); explicit V4L2VideoDevice(const MediaEntity *entity); V4L2VideoDevice(const V4L2VideoDevice &) = delete; @@ -187,7 +189,7 @@ public: int getFormat(V4L2DeviceFormat *format); int setFormat(V4L2DeviceFormat *format); - std::map> formats(uint32_t code = 0); + Formats formats(uint32_t code = 0); int setSelection(unsigned int target, Rectangle *rect); diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 9d887b706c3f..ffb3c5cc45d9 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -37,8 +37,6 @@ namespace libcamera { LOG_DEFINE_CATEGORY(RPI) -using V4L2PixFmtMap = std::map>; - namespace { bool isRaw(PixelFormat &pixFmt) @@ -67,7 +65,7 @@ double scoreFormat(double desired, double actual) return score; } -V4L2DeviceFormat findBestMode(V4L2PixFmtMap &formatsMap, const Size &req) +V4L2DeviceFormat findBestMode(V4L2VideoDevice::Formats &formatsMap, const Size &req) { double bestScore = 9e9, score; V4L2DeviceFormat bestMode = {}; @@ -79,7 +77,7 @@ V4L2DeviceFormat findBestMode(V4L2PixFmtMap &formatsMap, const Size &req) #define PENALTY_UNPACKED 500.0 /* Calculate the closest/best mode from the user requested size. */ - for (const auto &iter : formatsMap) { + for (const auto &iter : formatsMap.data()) { V4L2PixelFormat v4l2Format = iter.first; PixelFormat pixelFormat = v4l2Format.toPixelFormat(); const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat); @@ -427,7 +425,7 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() * Calculate the best sensor mode we can use based on * the user request. */ - V4L2PixFmtMap fmts = data_->unicam_[Unicam::Image].dev()->formats(); + V4L2VideoDevice::Formats fmts = data_->unicam_[Unicam::Image].dev()->formats(); V4L2DeviceFormat sensorFormat = findBestMode(fmts, cfg.size); PixelFormat sensorPixFormat = sensorFormat.fourcc.toPixelFormat(); if (cfg.size != sensorFormat.size || @@ -481,14 +479,14 @@ CameraConfiguration::Status RPiCameraConfiguration::validate() * */ PixelFormat &cfgPixFmt = config_.at(outSize[i].first).pixelFormat; - V4L2PixFmtMap fmts; + V4L2VideoDevice::Formats fmts; if (i == maxIndex) fmts = data_->isp_[Isp::Output0].dev()->formats(); else fmts = data_->isp_[Isp::Output1].dev()->formats(); - if (fmts.find(V4L2PixelFormat::fromPixelFormat(cfgPixFmt, false)) == fmts.end()) { + if (!fmts.contains(V4L2PixelFormat::fromPixelFormat(cfgPixFmt, false))) { /* If we cannot find a native format, use a default one. */ cfgPixFmt = formats::NV12; status = Adjusted; @@ -518,9 +516,9 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, RPiCameraData *data = cameraData(camera); CameraConfiguration *config = new RPiCameraConfiguration(data); V4L2DeviceFormat sensorFormat; + V4L2VideoDevice::Formats fmts; unsigned int bufferCount; PixelFormat pixelFormat; - V4L2PixFmtMap fmts; Size size; if (roles.empty()) @@ -580,8 +578,9 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, /* Translate the V4L2PixelFormat to PixelFormat. */ std::map> deviceFormats; - std::transform(fmts.begin(), fmts.end(), std::inserter(deviceFormats, deviceFormats.end()), - [&](const decltype(fmts)::value_type &format) { + std::transform(fmts.data().begin(), fmts.data().end(), + std::inserter(deviceFormats, deviceFormats.end()), + [&](const auto &format) { return decltype(deviceFormats)::value_type{ format.first.toPixelFormat(), format.second @@ -638,7 +637,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config) } /* First calculate the best sensor mode we can use based on the user request. */ - V4L2PixFmtMap fmts = data->unicam_[Unicam::Image].dev()->formats(); + V4L2VideoDevice::Formats fmts = data->unicam_[Unicam::Image].dev()->formats(); V4L2DeviceFormat sensorFormat = findBestMode(fmts, rawStream ? sensorSize : maxSize); /* diff --git a/src/libcamera/pipeline/simple/converter.cpp b/src/libcamera/pipeline/simple/converter.cpp index e5e2f0fddb62..701db96138b0 100644 --- a/src/libcamera/pipeline/simple/converter.cpp +++ b/src/libcamera/pipeline/simple/converter.cpp @@ -85,7 +85,7 @@ std::vector SimpleConverter::formats(PixelFormat input) std::vector pixelFormats; - for (const auto &format : m2m_->capture()->formats()) { + for (const auto &format : m2m_->capture()->formats().data()) { PixelFormat pixelFormat = format.first.toPixelFormat(); if (pixelFormat) pixelFormats.push_back(pixelFormat); diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 1ec8d0f7de03..202a7e85375c 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -275,13 +275,12 @@ int SimpleCameraData::init() return ret; } - std::map> videoFormats = - video_->formats(format.mbus_code); + V4L2VideoDevice::Formats videoFormats = video_->formats(format.mbus_code); LOG(SimplePipeline, Debug) << "Adding configuration for " << format.size.toString() << " in pixel formats [ " - << utils::join(videoFormats, ", ", + << utils::join(videoFormats.data(), ", ", [](const auto &f) { return f.first.toString(); }) @@ -294,7 +293,7 @@ int SimpleCameraData::init() * handler currently doesn't care about how a particular * PixelFormat is achieved. */ - for (const auto &videoFormat : videoFormats) { + for (const auto &videoFormat : videoFormats.data()) { PixelFormat pixelFormat = videoFormat.first.toPixelFormat(); if (!pixelFormat) continue; diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp index 80a0e77ba3fc..4c7812d0fb6b 100644 --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp @@ -158,12 +158,11 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera, if (roles.empty()) return config; - std::map> v4l2Formats = - data->video_->formats(); + V4L2VideoDevice::Formats v4l2Formats = data->video_->formats(); std::map> deviceFormats; - std::transform(v4l2Formats.begin(), v4l2Formats.end(), + std::transform(v4l2Formats.data().begin(), v4l2Formats.data().end(), std::inserter(deviceFormats, deviceFormats.begin()), - [&](const decltype(v4l2Formats)::value_type &format) { + [&](const auto &format) { return decltype(deviceFormats)::value_type{ format.first.toPixelFormat(), format.second diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 3614b2ed1cbc..63e09cf9616a 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -461,6 +461,12 @@ const std::string V4L2DeviceFormat::toString() const * \context This class is \threadbound. */ +/** + * \typedef V4L2VideoDevice::Formats + * \brief An ImageFormats specialization mapping V4L2PixelFormat instances to + * image resolutions + */ + /** * \brief Construct a V4L2VideoDevice * \param[in] deviceNode The file-system path to the video device node @@ -925,23 +931,23 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format) * * \return A list of the supported video device formats */ -std::map> V4L2VideoDevice::formats(uint32_t code) +V4L2VideoDevice::Formats V4L2VideoDevice::formats(uint32_t code) { - std::map> formats; + Formats formats; for (V4L2PixelFormat pixelFormat : enumPixelformats(code)) { std::vector sizes = enumSizes(pixelFormat); if (sizes.empty()) return {}; - if (formats.find(pixelFormat) != formats.end()) { + if (!formats.contains(pixelFormat)) { LOG(V4L2, Error) << "Could not add sizes for pixel format " << pixelFormat; return {}; } - formats.emplace(pixelFormat, sizes); + formats.addFormat(pixelFormat, sizes); } return formats;