blob: b90d6a0d8acf7453a7d49994e8548f76697e3640 [file] [log] [blame]
/*
* Copyright 2021 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "common/metadata_logger.h"
#include <utility>
#include <base/files/file_util.h>
#include <base/json/json_writer.h>
#include "cros-camera/common.h"
namespace cros {
namespace {
constexpr char kKeyFrameNumber[] = "frame_number";
} // namespace
MetadataLogger::MetadataLogger(Options options) : options_(options) {}
MetadataLogger::~MetadataLogger() {
if (options_.auto_dump_on_destruction) {
DumpMetadata();
}
}
template <>
void MetadataLogger::Log(int frame_number, std::string key, uint8_t value) {
base::Value& entry = GetOrCreateEntry(frame_number);
entry.SetIntKey(key, value);
}
template <>
void MetadataLogger::Log(int frame_number, std::string key, int32_t value) {
base::Value& entry = GetOrCreateEntry(frame_number);
entry.SetIntKey(key, value);
}
template <>
void MetadataLogger::Log(int frame_number, std::string key, float value) {
base::Value& entry = GetOrCreateEntry(frame_number);
entry.SetDoubleKey(key, value);
}
template <>
void MetadataLogger::Log(int frame_number, std::string key, int64_t value) {
base::Value& entry = GetOrCreateEntry(frame_number);
// JSON does not support int64, so let's use double instead.
entry.SetDoubleKey(key, value);
}
template <>
void MetadataLogger::Log(int frame_number, std::string key, double value) {
base::Value& entry = GetOrCreateEntry(frame_number);
entry.SetDoubleKey(key, value);
}
template <>
void MetadataLogger::Log(int frame_number, std::string key, Rational value) {
base::Value& entry = GetOrCreateEntry(frame_number);
entry.SetDoubleKey(key,
static_cast<double>(value.numerator) / value.denominator);
}
template <>
void MetadataLogger::Log(int frame_number,
std::string key,
base::span<const uint8_t> values) {
base::Value& entry = GetOrCreateEntry(frame_number);
std::vector<base::Value> value_list;
for (const auto& v : values) {
value_list.emplace_back(static_cast<int>(v));
}
entry.SetKey(key, base::Value(std::move(value_list)));
}
template <>
void MetadataLogger::Log(int frame_number,
std::string key,
base::span<const int32_t> values) {
base::Value& entry = GetOrCreateEntry(frame_number);
std::vector<base::Value> value_list;
for (const auto& v : values) {
value_list.emplace_back(v);
}
entry.SetKey(key, base::Value(std::move(value_list)));
}
template <>
void MetadataLogger::Log(int frame_number,
std::string key,
base::span<const float> values) {
base::Value& entry = GetOrCreateEntry(frame_number);
std::vector<base::Value> value_list;
for (const auto& v : values) {
value_list.emplace_back(static_cast<double>(v));
}
entry.SetKey(key, base::Value(std::move(value_list)));
}
template <>
void MetadataLogger::Log(int frame_number,
std::string key,
base::span<const int64_t> values) {
base::Value& entry = GetOrCreateEntry(frame_number);
std::vector<base::Value> value_list;
for (const auto& v : values) {
value_list.emplace_back(static_cast<double>(v));
}
entry.SetKey(key, base::Value(std::move(value_list)));
}
template <>
void MetadataLogger::Log(int frame_number,
std::string key,
base::span<const double> values) {
base::Value& entry = GetOrCreateEntry(frame_number);
std::vector<base::Value> value_list;
for (const auto& v : values) {
value_list.emplace_back(v);
}
entry.SetKey(key, base::Value(std::move(value_list)));
}
template <>
void MetadataLogger::Log(int frame_number,
std::string key,
base::span<const Rational> values) {
base::Value& entry = GetOrCreateEntry(frame_number);
std::vector<base::Value> value_list;
for (const auto& v : values) {
value_list.emplace_back(static_cast<double>(v.numerator) / v.denominator);
}
entry.SetKey(key, base::Value(std::move(value_list)));
}
template <>
void MetadataLogger::Log(int frame_number,
std::string key,
base::span<const camera_metadata_rational_t> values) {
base::Value& entry = GetOrCreateEntry(frame_number);
std::vector<base::Value> value_list;
for (const auto& v : values) {
value_list.emplace_back(static_cast<double>(v.numerator) / v.denominator);
}
entry.SetKey(key, base::Value(std::move(value_list)));
}
bool MetadataLogger::DumpMetadata() {
std::vector<base::Value> metadata_to_dump;
for (const auto& entry : frame_metadata_) {
metadata_to_dump.emplace_back(entry.second.Clone());
}
std::string json_string;
if (!base::JSONWriter::WriteWithOptions(
base::Value(metadata_to_dump), base::JSONWriter::OPTIONS_PRETTY_PRINT,
&json_string)) {
LOGF(WARNING) << "Can't jsonify frame metadata";
return false;
}
if (!base::WriteFile(options_.dump_path, json_string)) {
LOGF(WARNING) << "Can't write frame metadata";
return false;
}
return true;
}
base::Value& MetadataLogger::GetOrCreateEntry(int frame_number) {
if (frame_metadata_.count(frame_number) == 0) {
if (frame_metadata_.size() == options_.ring_buffer_capacity) {
frame_metadata_.erase(frame_metadata_.begin());
}
base::Value entry(base::Value::Type::DICTIONARY);
entry.SetIntKey(kKeyFrameNumber, frame_number);
frame_metadata_.insert({frame_number, std::move(entry)});
}
return frame_metadata_[frame_number];
}
} // namespace cros