From patchwork Mon Jun 24 13:48:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 20363 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 93640BD87C for ; Mon, 24 Jun 2024 13:49:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id AF209654AF; Mon, 24 Jun 2024 15:49:18 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="TaCUJXz4"; dkim-atps=neutral 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 06115654A3 for ; Mon, 24 Jun 2024 15:49:15 +0200 (CEST) Received: from fedora.local (unknown [IPv6:2405:201:2015:f873:55d7:c02e:b2eb:ee3f]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 844B3FF3; Mon, 24 Jun 2024 15:48:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1719236933; bh=KljAcoauDhQh5SXtUaCy5unCijNv6v91D/evORqfcq8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TaCUJXz4bWNCZwjRcYyssRDEn0kNDjs7GgnytM4Kq4dBC7wpvX18VXw1joyNcgnDn 88tK9zDSWHeWxMtFT0CDHuc90mOSUq/iTCG2bCUfwlXSVrq+RCwmyugJ8jo/DgjXAY GuqUQDHBGh/djZxGrYGIeOlWquYxmqlrkVfXwhDg= From: Umang Jain To: libcamera-devel@lists.libcamera.org Cc: Umang Jain , Kieran Bingham Subject: [PATCH v4 1/4] converter: converter_v4l2_m2m: Rectify streams sanity check Date: Mon, 24 Jun 2024 19:18:56 +0530 Message-ID: <20240624134859.171969-2-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240624134859.171969-1-umang.jain@ideasonboard.com> References: <20240624134859.171969-1-umang.jain@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" The streams sanity check tries to determine if all the stream indexes passed in outputs std::map<> are unique. However, since the data container is std::map<>, all its keys (stream indexes in this case), are already unique. Instead, rectify the sanity check to ensure all the framebuffers passed in the outputs std::map<> are unique to each index. Hence, no two stream indexes should have same framebuffer. Update the comment to reflect the change. Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder --- src/libcamera/converter/converter_v4l2_m2m.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp index d8929fc5..27a50e34 100644 --- a/src/libcamera/converter/converter_v4l2_m2m.cpp +++ b/src/libcamera/converter/converter_v4l2_m2m.cpp @@ -403,13 +403,13 @@ void V4L2M2MConverter::stop() int V4L2M2MConverter::queueBuffers(FrameBuffer *input, const std::map &outputs) { - unsigned int mask = 0; + std::set outputBufs; int ret; /* * Validate the outputs as a sanity check: at least one output is * required, all outputs must reference a valid stream and no two - * outputs can reference the same stream. + * streams can reference same output framebuffers. */ if (outputs.empty()) return -EINVAL; @@ -419,12 +419,13 @@ int V4L2M2MConverter::queueBuffers(FrameBuffer *input, return -EINVAL; if (index >= streams_.size()) return -EINVAL; - if (mask & (1 << index)) - return -EINVAL; - mask |= 1 << index; + outputBufs.insert(buffer); } + if (outputBufs.size() != streams_.size()) + return -EINVAL; + /* Queue the input and output buffers to all the streams. */ for (auto [index, buffer] : outputs) { ret = streams_[index].queueBuffers(input, buffer); From patchwork Mon Jun 24 13:48:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 20364 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 EBDE5BD87C for ; Mon, 24 Jun 2024 13:49:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BA13B654B1; Mon, 24 Jun 2024 15:49:20 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="vU0aFoJO"; dkim-atps=neutral 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 AF9A2654A3 for ; Mon, 24 Jun 2024 15:49:16 +0200 (CEST) Received: from fedora.local (unknown [IPv6:2405:201:2015:f873:55d7:c02e:b2eb:ee3f]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id BACC87E0; Mon, 24 Jun 2024 15:48:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1719236934; bh=k1pNL9ibnmaP85g55/kdshlcCKbBLVbAo2d62DeoC00=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vU0aFoJOW5do9s19vK7+xk/FTga5DzxS9UNLpFzj6clXZB4bdw+m4+oysJ4sSoFKu UIlT+IebUFkGr+9+eGT9gzZ0TSAAPPctJXBCCanQexfVosGz95UXI+j0G04jzZuv8s X0T6dkpb3tb+QLtvKFQmUSKoT2LkIZZoF00RssIo= From: Umang Jain To: libcamera-devel@lists.libcamera.org Cc: Umang Jain , Kieran Bingham Subject: [PATCH v4 2/4] libcamera: software_isp: Drop unnecessary sanity check Date: Mon, 24 Jun 2024 19:18:57 +0530 Message-ID: <20240624134859.171969-3-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240624134859.171969-1-umang.jain@ideasonboard.com> References: <20240624134859.171969-1-umang.jain@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" Currently the soft-isp outputs a single output stream. Hence, drop the unnecessary check for stream indexes. Another reason to drop is actually the stream indexes is meant to be unique in outputs std::map<>, hence checking for unique stream indexes is redundant. Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder --- src/libcamera/software_isp/software_isp.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 20fb6f48..3fb7ec8c 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -287,12 +287,9 @@ int SoftwareIsp::exportBuffers(unsigned int output, unsigned int count, int SoftwareIsp::queueBuffers(FrameBuffer *input, const std::map &outputs) { - unsigned int mask = 0; - /* * Validate the outputs as a sanity check: at least one output is - * required, all outputs must reference a valid stream and no two - * outputs can reference the same stream. + * required, all outputs must reference a valid stream. */ if (outputs.empty()) return -EINVAL; @@ -302,10 +299,6 @@ int SoftwareIsp::queueBuffers(FrameBuffer *input, return -EINVAL; if (index >= 1) /* only single stream atm */ return -EINVAL; - if (mask & (1 << index)) - return -EINVAL; - - mask |= 1 << index; } process(input, outputs.at(0)); From patchwork Mon Jun 24 13:48:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 20365 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 A02ABBD87C for ; Mon, 24 Jun 2024 13:49:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9448F654AE; Mon, 24 Jun 2024 15:49:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="k4tuaFX2"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 74E7A654A3 for ; Mon, 24 Jun 2024 15:49:17 +0200 (CEST) Received: from fedora.local (unknown [IPv6:2405:201:2015:f873:55d7:c02e:b2eb:ee3f]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F1B92FF3; Mon, 24 Jun 2024 15:48:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1719236935; bh=qlpDe/l9JvS3gchhyhnyleRHkYRrJEMiMbliuPGps50=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k4tuaFX2E2nDGq0RrMxekhF36QQRsKY8RIMaasm3gzCFUCyrohF5YMTbARLgtW9L5 CxVePwDkXHhEbYfovlDVzmLw0sznkHjYpdHcLV2E+m+tMtde8UPbtyt6CwapVzzTaB gchTx767igADbZIx4NtMB+neCdndWejjV/pfxx38= From: Umang Jain To: libcamera-devel@lists.libcamera.org Cc: Umang Jain , Kieran Bingham Subject: [PATCH v4 3/4] converter: converter_v4l2_m2m: Rename private Stream class Date: Mon, 24 Jun 2024 19:18:58 +0530 Message-ID: <20240624134859.171969-4-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240624134859.171969-1-umang.jain@ideasonboard.com> References: <20240624134859.171969-1-umang.jain@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" Rename the private Stream class from V4L2M2MConverter::Stream to V4L2M2MConverter::V4L2M2MStream. This is done to improve readability of the code when we drop the handling of stream by indexes in a subsequent patch. Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder --- .../internal/converter/converter_v4l2_m2m.h | 6 ++-- .../converter/converter_v4l2_m2m.cpp | 34 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h index 1126050c..0da62290 100644 --- a/include/libcamera/internal/converter/converter_v4l2_m2m.h +++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h @@ -57,10 +57,10 @@ public: const std::map &outputs); private: - class Stream : protected Loggable + class V4L2M2MStream : protected Loggable { public: - Stream(V4L2M2MConverter *converter, unsigned int index); + V4L2M2MStream(V4L2M2MConverter *converter, unsigned int index); bool isValid() const { return m2m_ != nullptr; } @@ -91,7 +91,7 @@ private: std::unique_ptr m2m_; - std::vector streams_; + std::vector streams_; std::map queue_; }; diff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp index 27a50e34..6309a0c0 100644 --- a/src/libcamera/converter/converter_v4l2_m2m.cpp +++ b/src/libcamera/converter/converter_v4l2_m2m.cpp @@ -32,24 +32,24 @@ namespace libcamera { LOG_DECLARE_CATEGORY(Converter) /* ----------------------------------------------------------------------------- - * V4L2M2MConverter::Stream + * V4L2M2MConverter::V4L2M2MStream */ -V4L2M2MConverter::Stream::Stream(V4L2M2MConverter *converter, unsigned int index) +V4L2M2MConverter::V4L2M2MStream::V4L2M2MStream(V4L2M2MConverter *converter, unsigned int index) : converter_(converter), index_(index) { m2m_ = std::make_unique(converter->deviceNode()); - m2m_->output()->bufferReady.connect(this, &Stream::outputBufferReady); - m2m_->capture()->bufferReady.connect(this, &Stream::captureBufferReady); + m2m_->output()->bufferReady.connect(this, &V4L2M2MStream::outputBufferReady); + m2m_->capture()->bufferReady.connect(this, &V4L2M2MStream::captureBufferReady); int ret = m2m_->open(); if (ret < 0) m2m_.reset(); } -int V4L2M2MConverter::Stream::configure(const StreamConfiguration &inputCfg, - const StreamConfiguration &outputCfg) +int V4L2M2MConverter::V4L2M2MStream::configure(const StreamConfiguration &inputCfg, + const StreamConfiguration &outputCfg) { V4L2PixelFormat videoFormat = m2m_->output()->toV4L2PixelFormat(inputCfg.pixelFormat); @@ -101,13 +101,13 @@ int V4L2M2MConverter::Stream::configure(const StreamConfiguration &inputCfg, return 0; } -int V4L2M2MConverter::Stream::exportBuffers(unsigned int count, - std::vector> *buffers) +int V4L2M2MConverter::V4L2M2MStream::exportBuffers(unsigned int count, + std::vector> *buffers) { return m2m_->capture()->exportBuffers(count, buffers); } -int V4L2M2MConverter::Stream::start() +int V4L2M2MConverter::V4L2M2MStream::start() { int ret = m2m_->output()->importBuffers(inputBufferCount_); if (ret < 0) @@ -134,7 +134,7 @@ int V4L2M2MConverter::Stream::start() return 0; } -void V4L2M2MConverter::Stream::stop() +void V4L2M2MConverter::V4L2M2MStream::stop() { m2m_->capture()->streamOff(); m2m_->output()->streamOff(); @@ -142,7 +142,7 @@ void V4L2M2MConverter::Stream::stop() m2m_->output()->releaseBuffers(); } -int V4L2M2MConverter::Stream::queueBuffers(FrameBuffer *input, FrameBuffer *output) +int V4L2M2MConverter::V4L2M2MStream::queueBuffers(FrameBuffer *input, FrameBuffer *output) { int ret = m2m_->output()->queueBuffer(input); if (ret < 0) @@ -155,12 +155,12 @@ int V4L2M2MConverter::Stream::queueBuffers(FrameBuffer *input, FrameBuffer *outp return 0; } -std::string V4L2M2MConverter::Stream::logPrefix() const +std::string V4L2M2MConverter::V4L2M2MStream::logPrefix() const { return "stream" + std::to_string(index_); } -void V4L2M2MConverter::Stream::outputBufferReady(FrameBuffer *buffer) +void V4L2M2MConverter::V4L2M2MStream::outputBufferReady(FrameBuffer *buffer) { auto it = converter_->queue_.find(buffer); if (it == converter_->queue_.end()) @@ -172,7 +172,7 @@ void V4L2M2MConverter::Stream::outputBufferReady(FrameBuffer *buffer) } } -void V4L2M2MConverter::Stream::captureBufferReady(FrameBuffer *buffer) +void V4L2M2MConverter::V4L2M2MStream::captureBufferReady(FrameBuffer *buffer) { converter_->outputBufferReady.emit(buffer); } @@ -336,7 +336,7 @@ int V4L2M2MConverter::configure(const StreamConfiguration &inputCfg, streams_.reserve(outputCfgs.size()); for (unsigned int i = 0; i < outputCfgs.size(); ++i) { - Stream &stream = streams_.emplace_back(this, i); + V4L2M2MStream &stream = streams_.emplace_back(this, i); if (!stream.isValid()) { LOG(Converter, Error) @@ -377,7 +377,7 @@ int V4L2M2MConverter::start() { int ret; - for (Stream &stream : streams_) { + for (V4L2M2MStream &stream : streams_) { ret = stream.start(); if (ret < 0) { stop(); @@ -393,7 +393,7 @@ int V4L2M2MConverter::start() */ void V4L2M2MConverter::stop() { - for (Stream &stream : utils::reverse(streams_)) + for (V4L2M2MStream &stream : utils::reverse(streams_)) stream.stop(); } From patchwork Mon Jun 24 13:48:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 20366 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 71455BD87C for ; Mon, 24 Jun 2024 13:49:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 20B60654AE; Mon, 24 Jun 2024 15:49:27 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="mfltiTeb"; dkim-atps=neutral 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 46763654A1 for ; Mon, 24 Jun 2024 15:49:19 +0200 (CEST) Received: from fedora.local (unknown [IPv6:2405:201:2015:f873:55d7:c02e:b2eb:ee3f]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 329097E0; Mon, 24 Jun 2024 15:48:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1719236937; bh=OqbOOW+LEl9BI1qr2cmy1I35+Qa6mUdgr85dNsj9bzc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mfltiTebNOGoRUZCCTYYcV6DZY6fFmw/GoxdSeM5g5Z5RpiWCmGgH6CulPFl/FVpo lxt78RPsvh8c++RUUaBcPh+MavGGorUieGdR8nyMluYENWoopARBPkTQVmlRT3BXM0 ygWmGZzXVqTyQDwNJKa84IWdk2LyJnGLPjJX8oJM= From: Umang Jain To: libcamera-devel@lists.libcamera.org Cc: Umang Jain , Kieran Bingham Subject: [PATCH v4 4/4] libcamera: converter: Replace usage of stream index by Stream pointer Date: Mon, 24 Jun 2024 19:18:59 +0530 Message-ID: <20240624134859.171969-5-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240624134859.171969-1-umang.jain@ideasonboard.com> References: <20240624134859.171969-1-umang.jain@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" The converter interface uses the unsigned int output stream index to map to the output frame buffers. This is cumbersome to implement new converters because one has to keep around additional book keeping to track the streams with their correct indexes. The v4l2_converter_m2m and simple pipeline handler are adapted to use the new interface. This work roped in software ISP as well, which also seems to use indexes (although it doesn't implement converter interface) because of a common conversionQueue_ queue used for converter_ and swIsp_. The logPrefix is no longer able to generate an index from a stream, and is updated to be more expressive by reporting the stream configuration instead, for example, reporting "1920x1080-MJPEG" in place of "stream0". Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham Reviewed-by: Paul Elder --- include/libcamera/internal/converter.h | 5 ++- .../internal/converter/converter_v4l2_m2m.h | 11 ++--- .../internal/software_isp/software_isp.h | 5 ++- src/libcamera/converter.cpp | 6 +-- .../converter/converter_v4l2_m2m.cpp | 42 ++++++++++--------- src/libcamera/pipeline/simple/simple.cpp | 14 +++---- src/libcamera/software_isp/software_isp.cpp | 17 ++++---- 7 files changed, 52 insertions(+), 48 deletions(-) diff --git a/include/libcamera/internal/converter.h b/include/libcamera/internal/converter.h index 5d74db6b..b51563d7 100644 --- a/include/libcamera/internal/converter.h +++ b/include/libcamera/internal/converter.h @@ -26,6 +26,7 @@ namespace libcamera { class FrameBuffer; class MediaDevice; class PixelFormat; +class Stream; struct StreamConfiguration; class Converter @@ -46,14 +47,14 @@ public: virtual int configure(const StreamConfiguration &inputCfg, const std::vector> &outputCfgs) = 0; - virtual int exportBuffers(unsigned int output, unsigned int count, + virtual int exportBuffers(const Stream *stream, unsigned int count, std::vector> *buffers) = 0; virtual int start() = 0; virtual void stop() = 0; virtual int queueBuffers(FrameBuffer *input, - const std::map &outputs) = 0; + const std::map &outputs) = 0; Signal inputBufferReady; Signal outputBufferReady; diff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h index 0da62290..b9e59899 100644 --- a/include/libcamera/internal/converter/converter_v4l2_m2m.h +++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h @@ -28,6 +28,7 @@ class FrameBuffer; class MediaDevice; class Size; class SizeRange; +class Stream; struct StreamConfiguration; class V4L2M2MDevice; @@ -47,20 +48,20 @@ public: int configure(const StreamConfiguration &inputCfg, const std::vector> &outputCfg); - int exportBuffers(unsigned int output, unsigned int count, + int exportBuffers(const Stream *stream, unsigned int count, std::vector> *buffers); int start(); void stop(); int queueBuffers(FrameBuffer *input, - const std::map &outputs); + const std::map &outputs); private: class V4L2M2MStream : protected Loggable { public: - V4L2M2MStream(V4L2M2MConverter *converter, unsigned int index); + V4L2M2MStream(V4L2M2MConverter *converter, const Stream *stream); bool isValid() const { return m2m_ != nullptr; } @@ -82,7 +83,7 @@ private: void outputBufferReady(FrameBuffer *buffer); V4L2M2MConverter *converter_; - unsigned int index_; + const Stream *stream_; std::unique_ptr m2m_; unsigned int inputBufferCount_; @@ -91,7 +92,7 @@ private: std::unique_ptr m2m_; - std::vector streams_; + std::map> streams_; std::map queue_; }; diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index c5338c05..f8e00003 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -37,6 +37,7 @@ namespace libcamera { class DebayerCpu; class FrameBuffer; class PixelFormat; +class Stream; struct StreamConfiguration; LOG_DECLARE_CATEGORY(SoftwareIsp) @@ -62,7 +63,7 @@ public: const std::vector> &outputCfgs, const ControlInfoMap &sensorControls); - int exportBuffers(unsigned int output, unsigned int count, + int exportBuffers(const Stream *stream, unsigned int count, std::vector> *buffers); void processStats(const ControlList &sensorControls); @@ -71,7 +72,7 @@ public: void stop(); int queueBuffers(FrameBuffer *input, - const std::map &outputs); + const std::map &outputs); void process(FrameBuffer *input, FrameBuffer *output); diff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp index d3d38c1b..c5e38937 100644 --- a/src/libcamera/converter.cpp +++ b/src/libcamera/converter.cpp @@ -111,12 +111,12 @@ Converter::~Converter() /** * \fn Converter::exportBuffers() * \brief Export buffers from the converter device - * \param[in] output Output stream index exporting the buffers + * \param[in] stream Output stream pointer exporting the buffers * \param[in] count Number of buffers to allocate * \param[out] buffers Vector to store allocated buffers * * This function operates similarly to V4L2VideoDevice::exportBuffers() on the - * output stream indicated by the \a output index. + * output stream indicated by the \a output. * * \return The number of allocated buffers on success or a negative error code * otherwise @@ -137,7 +137,7 @@ Converter::~Converter() * \fn Converter::queueBuffers() * \brief Queue buffers to converter device * \param[in] input The frame buffer to apply the conversion - * \param[out] outputs The container holding the output stream indexes and + * \param[out] outputs The container holding the output stream pointer and * their respective frame buffer outputs. * * This function queues the \a input frame buffer on the output streams of the diff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp index 6309a0c0..2e77872e 100644 --- a/src/libcamera/converter/converter_v4l2_m2m.cpp +++ b/src/libcamera/converter/converter_v4l2_m2m.cpp @@ -35,8 +35,8 @@ LOG_DECLARE_CATEGORY(Converter) * V4L2M2MConverter::V4L2M2MStream */ -V4L2M2MConverter::V4L2M2MStream::V4L2M2MStream(V4L2M2MConverter *converter, unsigned int index) - : converter_(converter), index_(index) +V4L2M2MConverter::V4L2M2MStream::V4L2M2MStream(V4L2M2MConverter *converter, const Stream *stream) + : converter_(converter), stream_(stream) { m2m_ = std::make_unique(converter->deviceNode()); @@ -157,7 +157,7 @@ int V4L2M2MConverter::V4L2M2MStream::queueBuffers(FrameBuffer *input, FrameBuffe std::string V4L2M2MConverter::V4L2M2MStream::logPrefix() const { - return "stream" + std::to_string(index_); + return stream_->configuration().toString(); } void V4L2M2MConverter::V4L2M2MStream::outputBufferReady(FrameBuffer *buffer) @@ -333,21 +333,24 @@ int V4L2M2MConverter::configure(const StreamConfiguration &inputCfg, int ret = 0; streams_.clear(); - streams_.reserve(outputCfgs.size()); for (unsigned int i = 0; i < outputCfgs.size(); ++i) { - V4L2M2MStream &stream = streams_.emplace_back(this, i); + const StreamConfiguration &cfg = outputCfgs[i]; + std::unique_ptr stream = + std::make_unique(this, cfg.stream()); - if (!stream.isValid()) { + if (!stream->isValid()) { LOG(Converter, Error) << "Failed to create stream " << i; ret = -EINVAL; break; } - ret = stream.configure(inputCfg, outputCfgs[i]); + ret = stream->configure(inputCfg, cfg); if (ret < 0) break; + + streams_.emplace(cfg.stream(), std::move(stream)); } if (ret < 0) { @@ -361,13 +364,14 @@ int V4L2M2MConverter::configure(const StreamConfiguration &inputCfg, /** * \copydoc libcamera::Converter::exportBuffers */ -int V4L2M2MConverter::exportBuffers(unsigned int output, unsigned int count, +int V4L2M2MConverter::exportBuffers(const Stream *stream, unsigned int count, std::vector> *buffers) { - if (output >= streams_.size()) + auto iter = streams_.find(stream); + if (iter == streams_.end()) return -EINVAL; - return streams_[output].exportBuffers(count, buffers); + return iter->second->exportBuffers(count, buffers); } /** @@ -377,8 +381,8 @@ int V4L2M2MConverter::start() { int ret; - for (V4L2M2MStream &stream : streams_) { - ret = stream.start(); + for (auto &iter : streams_) { + ret = iter.second->start(); if (ret < 0) { stop(); return ret; @@ -393,15 +397,15 @@ int V4L2M2MConverter::start() */ void V4L2M2MConverter::stop() { - for (V4L2M2MStream &stream : utils::reverse(streams_)) - stream.stop(); + for (auto &iter : streams_) + iter.second->stop(); } /** * \copydoc libcamera::Converter::queueBuffers */ int V4L2M2MConverter::queueBuffers(FrameBuffer *input, - const std::map &outputs) + const std::map &outputs) { std::set outputBufs; int ret; @@ -414,11 +418,9 @@ int V4L2M2MConverter::queueBuffers(FrameBuffer *input, if (outputs.empty()) return -EINVAL; - for (auto [index, buffer] : outputs) { + for (auto [stream, buffer] : outputs) { if (!buffer) return -EINVAL; - if (index >= streams_.size()) - return -EINVAL; outputBufs.insert(buffer); } @@ -427,8 +429,8 @@ int V4L2M2MConverter::queueBuffers(FrameBuffer *input, return -EINVAL; /* Queue the input and output buffers to all the streams. */ - for (auto [index, buffer] : outputs) { - ret = streams_[index].queueBuffers(input, buffer); + for (auto [stream, buffer] : outputs) { + ret = streams_.at(stream)->queueBuffers(input, buffer); if (ret < 0) return ret; } diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index eb36578e..5eb1dd21 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -277,7 +277,7 @@ public: std::map> formats_; std::vector> conversionBuffers_; - std::queue> conversionQueue_; + std::queue> conversionQueue_; bool useConversion_; std::unique_ptr converter_; @@ -836,7 +836,7 @@ void SimpleCameraData::bufferReady(FrameBuffer *buffer) Request *request = buffer->request(); if (useConversion_ && !conversionQueue_.empty()) { - const std::map &outputs = + const std::map &outputs = conversionQueue_.front(); if (!outputs.empty()) { FrameBuffer *outputBuffer = outputs.begin()->second; @@ -1303,10 +1303,8 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, */ if (data->useConversion_) return data->converter_ - ? data->converter_->exportBuffers(data->streamIndex(stream), - count, buffers) - : data->swIsp_->exportBuffers(data->streamIndex(stream), - count, buffers); + ? data->converter_->exportBuffers(stream, count, buffers) + : data->swIsp_->exportBuffers(stream, count, buffers); else return data->video_->exportBuffers(count, buffers); } @@ -1398,7 +1396,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request) SimpleCameraData *data = cameraData(camera); int ret; - std::map buffers; + std::map buffers; for (auto &[stream, buffer] : request->buffers()) { /* @@ -1407,7 +1405,7 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request) * completion handler. */ if (data->useConversion_) { - buffers.emplace(data->streamIndex(stream), buffer); + buffers.emplace(stream, buffer); } else { ret = data->video_->queueBuffer(buffer); if (ret < 0) diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 3fb7ec8c..f7a518c0 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -241,19 +241,19 @@ int SoftwareIsp::configure(const StreamConfiguration &inputCfg, /** * \brief Export the buffers from the Software ISP - * \param[in] output Output stream index exporting the buffers + * \param[in] stream Output stream exporting the buffers * \param[in] count Number of buffers to allocate * \param[out] buffers Vector to store the allocated buffers * \return The number of allocated buffers on success or a negative error code * otherwise */ -int SoftwareIsp::exportBuffers(unsigned int output, unsigned int count, +int SoftwareIsp::exportBuffers(const Stream *stream, unsigned int count, std::vector> *buffers) { ASSERT(debayer_ != nullptr); /* single output for now */ - if (output >= 1) + if (stream == nullptr) return -EINVAL; for (unsigned int i = 0; i < count; i++) { @@ -280,12 +280,12 @@ int SoftwareIsp::exportBuffers(unsigned int output, unsigned int count, /** * \brief Queue buffers to Software ISP * \param[in] input The input framebuffer - * \param[in] outputs The container holding the output stream indexes and + * \param[in] outputs The container holding the output stream pointer and * their respective frame buffer outputs * \return 0 on success, a negative errno on failure */ int SoftwareIsp::queueBuffers(FrameBuffer *input, - const std::map &outputs) + const std::map &outputs) { /* * Validate the outputs as a sanity check: at least one output is @@ -294,14 +294,15 @@ int SoftwareIsp::queueBuffers(FrameBuffer *input, if (outputs.empty()) return -EINVAL; - for (auto [index, buffer] : outputs) { + for (auto [stream, buffer] : outputs) { if (!buffer) return -EINVAL; - if (index >= 1) /* only single stream atm */ + if (outputs.size() != 1) /* only single stream atm */ return -EINVAL; } - process(input, outputs.at(0)); + for (auto iter = outputs.begin(); iter != outputs.end(); iter++) + process(input, iter->second); return 0; }