[RFC v2 4/4] libcamera: pipeline_handler: Use YamlEmitter
Jacopo Mondi
jacopo.mondi at ideasonboard.com
Thu Oct 17 14:52:19 CEST 2024
Replace raw output usage with YamlEmitter.
Signed-off-by: Jacopo Mondi <jacopo.mondi at ideasonboard.com>
---
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 <libcamera/controls.h>
#include <libcamera/stream.h>
+#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<YamlRoot> controlsEmitter_;
+ std::unique_ptr<YamlDict> controlsDict_;
+ std::unique_ptr<YamlList> controlsList_;
+
+ std::unique_ptr<YamlRoot> metadataEmitter_;
+ std::unique_ptr<YamlDict> metadataDict_;
+ std::unique_ptr<YamlList> 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<MediaDevice> 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<const Stream *> &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<YamlDict> 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();
}
/**
--
2.47.0
More information about the libcamera-devel
mailing list