From patchwork Tue Jan 6 16:57:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 25652 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 E5F94C32EA for ; Tue, 6 Jan 2026 16:58:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8997361FD8; Tue, 6 Jan 2026 17:58:20 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="WYIZcnJJ"; 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 E617861FA0 for ; Tue, 6 Jan 2026 17:58:03 +0100 (CET) Received: from pb-laptop.local (185.221.143.114.nat.pool.zt.hu [185.221.143.114]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B5224F01; Tue, 6 Jan 2026 17:57:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1767718663; bh=MKRS+mbV0xAQWRTd1xmlBg2eQGM/fgI+I7K9liDd4hM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WYIZcnJJOTd+FTCMeoV0gdzzely+XSJlqN7lwjUwU21y2cKcTCFkOFrk3AxzjrhQE v0pxCOL78K0slOtHmVgNBONvzd/wMDa8pA73MKnzjHVfhAnCR3YgmTH8E+SkhWoROp mLfQhELZ7IVSIZg8OLuo5WWYPWTa4bzEfKPJrMi0= From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi , Paul Elder Subject: [PATCH v4 22/22] libcamera: request: Swap the two metadata lists Date: Tue, 6 Jan 2026 17:57:54 +0100 Message-ID: <20260106165754.1759831-23-barnabas.pocze@ideasonboard.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260106165754.1759831-1-barnabas.pocze@ideasonboard.com> References: <20260106165754.1759831-1-barnabas.pocze@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" Swap `metadata_` and `metadata2_`, so `MetadataList` is used as the primary metadata list of a request. Signed-off-by: Barnabás Pőcze Reviewed-by: Jacopo Mondi Reviewed-by: Paul Elder --- include/libcamera/internal/pipeline_handler.h | 10 +++++----- include/libcamera/internal/request.h | 8 ++++---- include/libcamera/request.h | 4 ++-- src/android/camera_device.cpp | 2 +- src/apps/cam/camera_session.cpp | 7 +++---- src/apps/cam/file_sink.cpp | 2 +- src/apps/cam/file_sink.h | 4 ++-- src/apps/common/dng_writer.cpp | 2 +- src/apps/common/dng_writer.h | 4 ++-- src/apps/qcam/main_window.cpp | 2 +- src/apps/qcam/main_window.h | 3 ++- src/gstreamer/gstlibcamera-controls.cpp.in | 4 ++-- src/libcamera/pipeline_handler.cpp | 4 ++-- src/libcamera/request.cpp | 8 ++++---- src/py/libcamera/py_helpers.cpp | 4 ++-- src/py/libcamera/py_helpers.h | 2 +- src/py/libcamera/py_main.cpp | 2 +- 17 files changed, 36 insertions(+), 36 deletions(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index 10206945d..60811ce33 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -71,11 +71,11 @@ public: { Request::Private *d = request->_d(); - auto &m = d->metadata2(); + auto &m = d->metadata(); const auto c = m.checkpoint(); std::ignore = m.set(ctrl, value); - d->metadata().set(ctrl, value); + d->metadata2().set(ctrl, value); const auto diff = c.diffSince(); if (diff) @@ -90,8 +90,8 @@ public: void operator()(const Control &ctrl, const internal::cxx20::type_identity_t &value) const { - d->metadata().set(ctrl, value); - std::ignore = d->metadata2().set(ctrl, value); + std::ignore = d->metadata().set(ctrl, value); + d->metadata2().set(ctrl, value); } }; @@ -102,7 +102,7 @@ public: void metadataAvailable(Request *request, Func func) { Request::Private *d = request->_d(); - const auto c = d->metadata2().checkpoint(); + const auto c = d->metadata().checkpoint(); std::invoke(func, MetadataSetter{ d }); diff --git a/include/libcamera/internal/request.h b/include/libcamera/internal/request.h index 3e10ae051..bd03f4e40 100644 --- a/include/libcamera/internal/request.h +++ b/include/libcamera/internal/request.h @@ -37,9 +37,9 @@ public: Camera *camera() const { return camera_; } bool hasPendingBuffers() const; - ControlList &metadata() { return metadata_; } + [[nodiscard]] MetadataList &metadata() { return metadata_; } #ifndef __DOXYGEN__ - [[nodiscard]] MetadataList &metadata2() { return metadata2_; } + ControlList &metadata2() { return metadata2_; } #endif bool completeBuffer(FrameBuffer *buffer); @@ -67,8 +67,8 @@ private: std::unordered_set pending_; std::map notifiers_; std::unique_ptr timer_; - ControlList metadata_; - MetadataList metadata2_; + MetadataList metadata_; + ControlList metadata2_; }; } /* namespace libcamera */ diff --git a/include/libcamera/request.h b/include/libcamera/request.h index 96755a655..fb7d1e55c 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -51,9 +51,9 @@ public: void reuse(ReuseFlag flags = Default); ControlList &controls() { return controls_; } - const ControlList &metadata() const; + [[nodiscard]] const MetadataList &metadata() const; #ifndef __DOXYGEN__ - [[nodiscard]] const MetadataList &metadata2() const; + const ControlList &metadata2() const; #endif const BufferMap &buffers() const { return bufferMap_; } diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 80ff248c2..fa0cf1d23 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1423,7 +1423,7 @@ void CameraDevice::notifyError(uint32_t frameNumber, camera3_stream_t *stream, std::unique_ptr CameraDevice::getResultMetadata(const Camera3RequestDescriptor &descriptor) const { - const ControlList &metadata = descriptor.request_->metadata(); + const MetadataList &metadata = descriptor.request_->metadata(); const CameraMetadata &settings = descriptor.settings_; camera_metadata_ro_entry_t entry; bool found; diff --git a/src/apps/cam/camera_session.cpp b/src/apps/cam/camera_session.cpp index ba43220d1..e930c75ee 100644 --- a/src/apps/cam/camera_session.cpp +++ b/src/apps/cam/camera_session.cpp @@ -547,19 +547,18 @@ void CameraSession::processRequest(Request *request) std::cout << info.str() << std::endl; if (printMetadata_) { - const ControlList &requestMetadata = request->metadata(); + const MetadataList &requestMetadata = request->metadata(); std::cout << "Metadata (" << requestMetadata.size() << " entries):\n"; for (const auto &[key, value] : requestMetadata) { const ControlId *id = controls::controls.at(key); - std::cout << "\t" << id->name() << " = " - << value.toString() << std::endl; + std::cout << '\t' << id->name() << " = " << value << std::endl; } const auto &requestMetadata2 = request->metadata2(); std::cout << "Metadata2 (" << requestMetadata2.size() << " entries):\n"; for (const auto &[key, value] : requestMetadata2) { const ControlId *id = controls::controls.at(key); - std::cout << '\t' << id->name() << " = " << value << std::endl; + std::cout << '\t' << id->name() << " = " << value.toString() << std::endl; } } diff --git a/src/apps/cam/file_sink.cpp b/src/apps/cam/file_sink.cpp index 65794a2f9..7149d782c 100644 --- a/src/apps/cam/file_sink.cpp +++ b/src/apps/cam/file_sink.cpp @@ -102,7 +102,7 @@ bool FileSink::processRequest(Request *request) } void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer, - [[maybe_unused]] const ControlList &metadata) + [[maybe_unused]] const MetadataList &metadata) { std::string filename = pattern_; size_t pos; diff --git a/src/apps/cam/file_sink.h b/src/apps/cam/file_sink.h index 26cd61b36..1f973f2e6 100644 --- a/src/apps/cam/file_sink.h +++ b/src/apps/cam/file_sink.h @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include "frame_sink.h" @@ -44,7 +44,7 @@ private: void writeBuffer(const libcamera::Stream *stream, libcamera::FrameBuffer *buffer, - const libcamera::ControlList &metadata); + const libcamera::MetadataList &metadata); #ifdef HAVE_TIFF const libcamera::Camera *camera_; diff --git a/src/apps/common/dng_writer.cpp b/src/apps/common/dng_writer.cpp index 8d57023e1..431979564 100644 --- a/src/apps/common/dng_writer.cpp +++ b/src/apps/common/dng_writer.cpp @@ -521,7 +521,7 @@ const std::map formatInfo = { int DNGWriter::write(const char *filename, const Camera *camera, const StreamConfiguration &config, - const ControlList &metadata, + const MetadataList &metadata, [[maybe_unused]] const FrameBuffer *buffer, const void *data) { diff --git a/src/apps/common/dng_writer.h b/src/apps/common/dng_writer.h index aaa8a852b..741f78a75 100644 --- a/src/apps/common/dng_writer.h +++ b/src/apps/common/dng_writer.h @@ -10,8 +10,8 @@ #ifdef HAVE_TIFF #include -#include #include +#include #include class DNGWriter @@ -19,7 +19,7 @@ class DNGWriter public: static int write(const char *filename, const libcamera::Camera *camera, const libcamera::StreamConfiguration &config, - const libcamera::ControlList &metadata, + const libcamera::MetadataList &metadata, const libcamera::FrameBuffer *buffer, const void *data); }; diff --git a/src/apps/qcam/main_window.cpp b/src/apps/qcam/main_window.cpp index 96a2d5090..2a678c19a 100644 --- a/src/apps/qcam/main_window.cpp +++ b/src/apps/qcam/main_window.cpp @@ -646,7 +646,7 @@ void MainWindow::captureRaw() } void MainWindow::processRaw(FrameBuffer *buffer, - [[maybe_unused]] const ControlList &metadata) + [[maybe_unused]] const MetadataList &metadata) { #ifdef HAVE_TIFF QString defaultPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); diff --git a/src/apps/qcam/main_window.h b/src/apps/qcam/main_window.h index 81fcf915a..278de1d44 100644 --- a/src/apps/qcam/main_window.h +++ b/src/apps/qcam/main_window.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -66,7 +67,7 @@ private Q_SLOTS: void saveImageAs(); void captureRaw(); void processRaw(libcamera::FrameBuffer *buffer, - const libcamera::ControlList &metadata); + const libcamera::MetadataList &metadata); void renderComplete(libcamera::FrameBuffer *buffer); diff --git a/src/gstreamer/gstlibcamera-controls.cpp.in b/src/gstreamer/gstlibcamera-controls.cpp.in index 6faf3ee7a..b42eade9b 100644 --- a/src/gstreamer/gstlibcamera-controls.cpp.in +++ b/src/gstreamer/gstlibcamera-controls.cpp.in @@ -282,6 +282,6 @@ void GstCameraControls::applyControls(std::unique_ptr &reque void GstCameraControls::readMetadata(libcamera::Request *request) { - controls_acc_.merge(request->metadata(), - ControlList::MergePolicy::OverwriteExisting); + for (const auto &[k, v] : request->metadata()) + controls_acc_.set(k, ControlValue(v)); } diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 1b9e18a04..afc9d09bd 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -572,9 +572,9 @@ void PipelineHandler::metadataAvailable(Request *request, const ControlList &met { Request::Private *d = request->_d(); - d->metadata().merge(metadata); + d->metadata2().merge(metadata); - const auto diff = d->metadata2().merge(metadata); + const auto diff = d->metadata().merge(metadata); if (!diff) LOG(Pipeline, Fatal) << "Tried to add incompatible metadata items"; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 6d44c6749..57b294ec6 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -57,8 +57,8 @@ LOG_DEFINE_CATEGORY(Request) * \todo Add a validator for metadata controls. */ Request::Private::Private(Camera *camera) - : camera_(camera), cancelled_(false), metadata_(controls::controls), - metadata2_(camera->metadata()) + : camera_(camera), cancelled_(false), metadata_(camera->metadata()), + metadata2_(controls::controls) { } @@ -429,13 +429,13 @@ void Request::reuse(ReuseFlag flags) * \brief Retrieve the request's metadata * \return The a const reference to the metadata associated with the request */ -const ControlList &Request::metadata() const +const MetadataList &Request::metadata() const { return _d()->metadata_; } #ifndef __DOXYGEN__ -const MetadataList &Request::metadata2() const +const ControlList &Request::metadata2() const { return _d()->metadata2_; } diff --git a/src/py/libcamera/py_helpers.cpp b/src/py/libcamera/py_helpers.cpp index 8c55ef845..a994c90b7 100644 --- a/src/py/libcamera/py_helpers.cpp +++ b/src/py/libcamera/py_helpers.cpp @@ -16,7 +16,7 @@ namespace py = pybind11; using namespace libcamera; template -static py::object valueOrTuple(const ControlValue &cv) +static py::object valueOrTuple(const ControlValueView &cv) { if (cv.isArray()) { const T *v = reinterpret_cast(cv.data().data()); @@ -31,7 +31,7 @@ static py::object valueOrTuple(const ControlValue &cv) return py::cast(cv.get()); } -py::object controlValueToPy(const ControlValue &cv) +py::object controlValueToPy(const ControlValueView &cv) { switch (cv.type()) { case ControlTypeNone: diff --git a/src/py/libcamera/py_helpers.h b/src/py/libcamera/py_helpers.h index 983969dff..895006d0c 100644 --- a/src/py/libcamera/py_helpers.h +++ b/src/py/libcamera/py_helpers.h @@ -9,5 +9,5 @@ #include -pybind11::object controlValueToPy(const libcamera::ControlValue &cv); +pybind11::object controlValueToPy(const libcamera::ControlValueView &cv); libcamera::ControlValue pyToControlValue(const pybind11::object &ob, libcamera::ControlType type); diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp index a983ea75c..77e0ead68 100644 --- a/src/py/libcamera/py_main.cpp +++ b/src/py/libcamera/py_main.cpp @@ -466,7 +466,7 @@ PYBIND11_MODULE(_libcamera, m) self.controls().set(id.id(), pyToControlValue(value, id.type())); }) .def_property_readonly("metadata", [](Request &self) { - /* Convert ControlList to std container */ + /* Convert MetadataList to std container */ std::unordered_map ret;