From patchwork Thu Oct 17 12:52:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 21658 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 62A4CC326C for ; Thu, 17 Oct 2024 12:52:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 53B9D6538A; Thu, 17 Oct 2024 14:52:42 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SrlWD+nU"; 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 9C3786538C for ; Thu, 17 Oct 2024 14:52:34 +0200 (CEST) Received: from ideasonboard.com (unknown [5.77.64.27]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F062C6DC; Thu, 17 Oct 2024 14:50:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1729169451; bh=p0lwCGrwbm63cvKfCrEcu3tKK5/Lq8nEjhETfACwRfg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SrlWD+nUoR1Hg4YiqTfJOXkOG0ksOO4r+yGYCZdI9NZ+bFvSl0ZVwaCXZEc9AaKX9 Jv1BMs0c5GsoEJSJSwaFsD5rG7452h5Km+p5S+nUv43IoENdSF8hmj88oK/KXPfFPF vZPMcnZRp8fKt4RcZ4nc2jLI6BdaWQKLYbLnlk+c= From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Cc: Jacopo Mondi Subject: [RFC v2 4/4] libcamera: pipeline_handler: Use YamlEmitter Date: Thu, 17 Oct 2024 14:52:19 +0200 Message-ID: <20241017125220.60567-5-jacopo.mondi@ideasonboard.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241017125220.60567-1-jacopo.mondi@ideasonboard.com> References: <20241017125220.60567-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 | 102 +++++++++--------- 2 files changed, 61 insertions(+), 52 deletions(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index fb3914185a01..a10d7b1fab8c 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_; + std::unique_ptr controlsEmitter_; + std::unique_ptr controlsDict_; + std::unique_ptr controlsList_; + + std::unique_ptr metadataEmitter_; + std::unique_ptr metadataDict_; + std::unique_ptr metadataList_; friend class PipelineHandlerFactoryBase; }; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 7002b4323bdd..533d0f8fc132 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_; } /** @@ -788,65 +783,72 @@ void PipelineHandler::disconnect() void PipelineHandler::dumpConfiguration(const std::set &streams, const Orientation &orientation) { - if (!dumpCaptureScript_) + if (!controlsEmitter_) return; - std::stringstream ss; - ss << "configuration:" << std::endl; - ss << " orientation: " << orientation << std::endl; + auto configurationDict = controlsDict_->dict("configuration"); + + std::stringstream o; + o << orientation; + (*configurationDict)["orientation"] = o.str(); /* TODO Dump Sensor configuration */ - ss << " streams:" << std::endl; + auto 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; - } + auto 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_) return; - std::stringstream ss; + ControlList &controls = mode == DumpMode::Controls ? request->controls() + : request->metadata(); + if (controls.empty()) + return; + + std::unique_ptr yamlFrame; + if (mode == DumpMode::Controls) { + if (!controlsEmitter_) + return; + + if (!controlsList_) + controlsList_ = controlsDict_->list("frames"); + + yamlFrame = controlsList_->dict(); + } else { + if (!metadataEmitter_) + return; + + yamlFrame = metadataList_->dict(); + } + + auto 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(); } /**