From patchwork Thu Oct 23 14:48:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 24745 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 03B18C333C for ; Thu, 23 Oct 2025 14:49:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5DA3B6081D; Thu, 23 Oct 2025 16:49:41 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Kr5+X9sk"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A3F8B60805 for ; Thu, 23 Oct 2025 16:49:40 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:7328:357b:4ce1:72b6]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id A3C7E591; Thu, 23 Oct 2025 16:47:55 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761230875; bh=pd+DFxuBTqdfIbDhvLPeoBe2m2oY+1pIzgQ0LsDtZz8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Kr5+X9skKniY8p7UGXojnuCkhkaXcwDeXJ8HxQ/M1+C6BiJAfEbBE47q0BicFVlP0 UD08tIcLcuKqyrfwIgzKwUI3S0pzcg2FGoxA3qmJWqAqsKzuj7Jgee2yIdoyU8V3Hu 9TnohXoiCRmb7uhMOiFOi0hR5wSoxCF6CEdF+TiU= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v2 18/35] libcamera: converter_m2m: Make some parts protected Date: Thu, 23 Oct 2025 16:48:19 +0200 Message-ID: <20251023144841.403689-19-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20251023144841.403689-1-stefan.klug@ideasonboard.com> References: <20251023144841.403689-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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 order to derive from V4L2M2MConverter and also from V4L2M2MStream in a subclass, raise the visibility of most of the private parts to protected and document them. Signed-off-by: Stefan Klug --- Changes in v2: - Added this patch --- .../internal/converter/converter_v4l2_m2m.h | 7 +- .../converter/converter_v4l2_m2m.cpp | 107 ++++++++++++++++++ 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h index 2d6f361c17e1..79d008fc6918 100644 --- a/include/libcamera/internal/converter/converter_v4l2_m2m.h +++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h @@ -81,7 +81,7 @@ public: bool supportsRequests(); -private: +protected: class V4L2M2MStream : protected Loggable { public: @@ -130,12 +130,13 @@ private: virtual std::unique_ptr makeStream(const Stream *stream); std::unique_ptr m2m_; + std::shared_ptr media_; std::map> streams_; + +private: std::map queue_; std::pair inputCropBounds_; - - std::shared_ptr media_; }; } /* namespace libcamera */ diff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp index 2e3966444361..3a05e45ac33c 100644 --- a/src/libcamera/converter/converter_v4l2_m2m.cpp +++ b/src/libcamera/converter/converter_v4l2_m2m.cpp @@ -86,6 +86,28 @@ int getCropBounds(V4L2VideoDevice *device, Rectangle &minCrop, * V4L2M2MConverter::V4L2M2MStream */ +/** + * \class libcamera::V4L2M2MConverter::V4L2M2MStream + * \brief The V4L2 M2M stream represents a stream in a V4L2M2MConverter + * + * The Converter interface allows to create multiple output image streams from + * a single input image stream. This class represents one such stream. + */ + +/** + * \fn V4L2M2MConverter::V4L2M2MStream::isValid + * \brief Checks if the stream is valid + * + * This function checks if the underlying m2m device is valid. + * + * \return True if the stream is valid, false otherwise + */ + +/** + * \brief Constructs a V4L2M2MStream + * \param[in] converter The converter this stream belongs to + * \param[in] stream The stream this V4L2M2MStream represents + */ V4L2M2MConverter::V4L2M2MStream::V4L2M2MStream(V4L2M2MConverter *converter, const Stream *stream) : converter_(converter), stream_(stream) { @@ -99,6 +121,13 @@ V4L2M2MConverter::V4L2M2MStream::V4L2M2MStream(V4L2M2MConverter *converter, cons m2m_.reset(); } +/** + * \brief Configure the stream + * \param[in] inputCfg The input config + * \param[in] outputCfg The output config + * + * \return 0 on success or a negative error code otherwise + */ int V4L2M2MConverter::V4L2M2MStream::configure(const StreamConfiguration &inputCfg, const StreamConfiguration &outputCfg) { @@ -161,12 +190,24 @@ int V4L2M2MConverter::V4L2M2MStream::configure(const StreamConfiguration &inputC return 0; } +/** + * \brief Export buffers + * \param[in] count The number of buffers + * \param[out] buffers The exported buffers + * + * \return 0 on success or a negative error code otherwise + */ int V4L2M2MConverter::V4L2M2MStream::exportBuffers(unsigned int count, std::vector> *buffers) { return m2m_->capture()->exportBuffers(count, buffers); } +/** + * \brief Start the stream + * + * \return 0 on success or a negative error code otherwise + */ int V4L2M2MConverter::V4L2M2MStream::start() { int ret = m2m_->output()->importBuffers(inputBufferCount_); @@ -194,6 +235,9 @@ int V4L2M2MConverter::V4L2M2MStream::start() return 0; } +/** + * \brief Stop the stream + */ void V4L2M2MConverter::V4L2M2MStream::stop() { m2m_->capture()->streamOff(); @@ -202,6 +246,14 @@ void V4L2M2MConverter::V4L2M2MStream::stop() m2m_->output()->releaseBuffers(); } +/** + * \brief Queue buffers + * \param[in] input The input buffer + * \param[in] output The output buffer + * \param[in] request An optional request + * + * \return 0 on success or a negative error code otherwise + */ int V4L2M2MConverter::V4L2M2MStream::queueBuffers(FrameBuffer *input, FrameBuffer *output, const V4L2Request *request) @@ -217,16 +269,35 @@ int V4L2M2MConverter::V4L2M2MStream::queueBuffers(FrameBuffer *input, return 0; } +/** + * \brief Get the input selection rectangle + * \param[in] target The selection target + * \param[out] rect The selection rectangle + * + * \return 0 on success or a negative error code otherwise + */ int V4L2M2MConverter::V4L2M2MStream::getInputSelection(unsigned int target, Rectangle *rect) { return m2m_->output()->getSelection(target, rect); } +/** + * \brief Set the input selection rectangle + * \param[in] target The selection target + * \param[in] rect The selection rectangle + * + * \return 0 on success or a negative error code otherwise + */ int V4L2M2MConverter::V4L2M2MStream::setInputSelection(unsigned int target, Rectangle *rect) { return m2m_->output()->setSelection(target, rect); } +/** + * \brief Get the input crop bounds + * + * \return A pair of rectangles representing the min and max input crop bounds + */ std::pair V4L2M2MConverter::V4L2M2MStream::inputCropBounds() { return inputCropBounds_; @@ -461,6 +532,19 @@ Size V4L2M2MConverter::adjustOutputSize(const PixelFormat &pixFmt, return adjustSizes(size, it->second, align); } +/** + * \brief Adjust the converter output \a size to a valid value + * \param[in] cfgSize The requested size + * \param[in] ranges The possible sizes + * \param[in] align The desired alignment + * + * Selects the best fitting size from \a ranges according to \a align and + * returns that. + * + * \return The adjusted converter output size or a null Size if \a size cannot + * be adjusted + * \see libcamera::Converter::adjustOutputSize + */ Size V4L2M2MConverter::adjustSizes(const Size &cfgSize, const std::vector &ranges, Alignment align) @@ -810,11 +894,34 @@ bool V4L2M2MConverter::supportsRequests() return ret; } +/** + * \brief Create a V4L2M2MStream + * \param[in] stream The stream to wrap + * + * This function creates a new V4L2M2MConverter::V4L2M2MStream for this + * converter and the provided \a stream. + * + * This function can be overwritten by subclasses to be able provide their own + * stream implementation. + * + * \return The created V4L2M2MStream + */ std::unique_ptr V4L2M2MConverter::makeStream(const Stream *stream) { return std::make_unique(this, stream); } +/** + * \var V4L2M2MConverter::m2m_ + * \brief The underlying m2m device + * + * \var V4L2M2MConverter::media_ + * \brief The underlying media device + * + * \var V4L2M2MConverter::streams_ + * \brief Map of Stream pointers to V4L2M2MStream unique pointers + */ + /* * \todo This should be extended to include Feature::Flag to denote * what each converter supports feature-wise.