From patchwork Mon Oct 21 09:49:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 21715 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 BA129C3304 for ; Mon, 21 Oct 2024 09:50:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CAC7E65395; Mon, 21 Oct 2024 11:50:23 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Da0oR1Fc"; 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 0A48265395 for ; Mon, 21 Oct 2024 11:50:14 +0200 (CEST) Received: from ideasonboard.com (mob-5-90-62-78.net.vodafone.it [5.90.62.78]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0611319F8; Mon, 21 Oct 2024 11:48:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1729504109; bh=YnaqdHf4COiwyOo9ZyS6UvZnQLokg1OBDK6AnEZiopo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Da0oR1FcRRFj4UhGgSl/bpTJCkiWZEF2GrNF0LI6PcnZ/Lbq6CH6oRcWBUUtzUE12 2dFaZfWqUV8szqDxaJyE4T+spl4JrxWAum7x3V36xi4kKC9x7cfcpNqNOm3dJoPAM7 jsrX02y/RjbraUMdWVQkqTHXkBdN75ZBFwpi6lDA= From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi Subject: [RFC v3 4/4] libcamera: pipeline_handler: Use YamlEmitter Date: Mon, 21 Oct 2024 11:49:52 +0200 Message-ID: <20241021094955.26991-5-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241021094955.26991-1-jacopo.mondi@ideasonboard.com> References: <20241021094955.26991-1-jacopo.mondi@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" Replace raw output usage with YamlEmitter. Signed-off-by: Jacopo Mondi --- include/libcamera/internal/pipeline_handler.h | 11 ++- src/libcamera/pipeline_handler.cpp | 99 +++++++++---------- 2 files changed, 58 insertions(+), 52 deletions(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index fb3914185a01..89d10b373cfa 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -19,6 +19,8 @@ #include #include +#include "libcamera/internal/yaml_emitter.h" + namespace libcamera { enum class Orientation; @@ -110,8 +112,13 @@ private: const char *name_; unsigned int useCount_; - std::ostream *dumpCaptureScript_; - std::ostream *dumpMetadata_; + YamlRoot controlsEmitter_; + YamlDict controlsDict_; + YamlList controlsList_; + + YamlRoot metadataEmitter_; + YamlDict metadataDict_; + YamlList metadataList_; friend class PipelineHandlerFactoryBase; }; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 7002b4323bdd..b5d613f630a2 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -69,36 +69,31 @@ LOG_DEFINE_CATEGORY(Pipeline) * through the PipelineHandlerFactoryBase::create() function. */ PipelineHandler::PipelineHandler(CameraManager *manager) - : manager_(manager), useCount_(0), - dumpCaptureScript_(nullptr), dumpMetadata_(nullptr) + : manager_(manager), useCount_(0) { /* TODO Print notification that we're dumping capture script */ const char *file = utils::secure_getenv("LIBCAMERA_DUMP_CAPTURE_SCRIPT"); if (!file) return; - dumpCaptureScript_ = new std::ofstream(file); + std::string filePath(file); + controlsEmitter_ = YamlEmitter::root(filePath); + controlsDict_ = controlsEmitter_.dict(); /* * Metadata needs to go into a separate file because otherwise it'll * flood the capture script */ - dumpMetadata_ = new std::ofstream(std::string(file) + ".metadata"); - std::string str = "frames:\n"; - dumpMetadata_->write(str.c_str(), str.size()); - dumpMetadata_->flush(); + std::string metadataFilePath = filePath + ".metadata"; + metadataEmitter_ = YamlEmitter::root(metadataFilePath); + metadataDict_ = metadataEmitter_.dict(); + metadataList_ = metadataDict_.list("frames"); } PipelineHandler::~PipelineHandler() { for (std::shared_ptr media : mediaDevices_) media->release(); - - if (dumpCaptureScript_) - delete dumpCaptureScript_; - - if (dumpMetadata_) - delete dumpMetadata_; } /** @@ -785,68 +780,72 @@ void PipelineHandler::disconnect() * \return The CameraManager for this pipeline handler */ +/** + * \brief todo + */ void PipelineHandler::dumpConfiguration(const std::set &streams, const Orientation &orientation) { - if (!dumpCaptureScript_) + if (!controlsEmitter_.initialized()) return; - std::stringstream ss; - ss << "configuration:" << std::endl; - ss << " orientation: " << orientation << std::endl; + YamlDict configurationDict = controlsDict_.dict("configuration"); + + std::stringstream o; + o << orientation; + configurationDict["orientation"] = o.str(); /* TODO Dump Sensor configuration */ - ss << " streams:" << std::endl; + YamlList streamsList = configurationDict.list("streams"); + for (const auto &stream : streams) { const StreamConfiguration &streamConfig = stream->configuration(); - ss << " - pixelFormat: " << streamConfig.pixelFormat << std::endl; - ss << " size: " << streamConfig.size << std::endl; - ss << " stride: " << streamConfig.stride << std::endl; - ss << " frameSize: " << streamConfig.frameSize << std::endl; - ss << " bufferCount: " << streamConfig.bufferCount << std::endl; - if (streamConfig.colorSpace) - ss << " colorSpace: " << streamConfig.colorSpace->toString() << std::endl; - } + YamlDict yamlStream = streamsList.dict(); - dumpCaptureScript_->write(ss.str().c_str(), ss.str().size()); + yamlStream["pixelformat"] = streamConfig.pixelFormat.toString(); + yamlStream["size"] = streamConfig.size.toString(); + yamlStream["stride"] = std::to_string(streamConfig.stride); + yamlStream["frameSize"] = std::to_string(streamConfig.frameSize); + yamlStream["bufferCount"] = std::to_string(streamConfig.bufferCount); - std::string str = "frames:\n"; - dumpCaptureScript_->write(str.c_str(), str.size()); - dumpCaptureScript_->flush(); + if (streamConfig.colorSpace) + yamlStream["colorSpace"] = + streamConfig.colorSpace->toString(); + } } void PipelineHandler::dumpRequest(Request *request, DumpMode mode) { - ControlList &controls = - mode == DumpMode::Controls ? request->controls() - : request->metadata(); - std::ostream *output = - mode == DumpMode::Controls ? dumpCaptureScript_ - : dumpMetadata_; - - if (!output || controls.empty()) + if (!controlsEmitter_.initialized()) return; - std::stringstream ss; + ControlList &controls = mode == DumpMode::Controls ? request->controls() + : request->metadata(); + if (controls.empty()) + return; + + YamlDict yamlFrame; + if (mode == DumpMode::Controls) { + if (!controlsList_.initialized()) + controlsList_ = controlsDict_.list("frames"); + + yamlFrame = controlsList_.dict(); + } else { + yamlFrame = metadataList_.dict(); + } + + YamlDict yamlCtrls = yamlFrame.dict(std::to_string(request->sequence())); + /* TODO Figure out PFC */ - ss << " - " << request->sequence() << ":" << std::endl; const ControlIdMap *idMap = controls.idMap(); for (const auto &pair : controls) { const ControlId *ctrlId = idMap->at(pair.first); + /* TODO Prettify enums (probably by upgrading ControlValue::toString()) */ - ss << " " << ctrlId->name() << ": " << pair.second.toString() << std::endl; + yamlCtrls[ctrlId->name()] = pair.second.toString(); } - - /* - * TODO Investigate the overhead of flushing this frequently - * Controls aren't going to be queued too frequently so it should be - * fine to dump controls every frame. Metadata on the other hand needs - * to be investigated. - */ - output->write(ss.str().c_str(), ss.str().size()); - output->flush(); } /**