204 lines
7.0 KiB
C++
204 lines
7.0 KiB
C++
/*
|
|
* Copyright (C) 2023 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <memory>
|
|
#include <numeric>
|
|
|
|
#include <system/camera_metadata.h>
|
|
|
|
#include "debug.h"
|
|
#include "metadata_utils.h"
|
|
|
|
namespace android {
|
|
namespace hardware {
|
|
namespace camera {
|
|
namespace provider {
|
|
namespace implementation {
|
|
namespace {
|
|
|
|
struct CameraMetadataDeleter {
|
|
void operator()(camera_metadata_t* p) const {
|
|
free_camera_metadata(p);
|
|
}
|
|
};
|
|
|
|
using CameraMetadataPtr = std::unique_ptr<camera_metadata_t, CameraMetadataDeleter>;
|
|
|
|
CameraMetadata metadataCompactRaw(const camera_metadata_t* raw) {
|
|
const size_t size = get_camera_metadata_compact_size(raw);
|
|
CameraMetadata r;
|
|
r.metadata.resize(size);
|
|
copy_camera_metadata(r.metadata.data(), size, raw);
|
|
return r;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
CameraMetadata metadataCompact(const CameraMetadata& m) {
|
|
return metadataCompactRaw(reinterpret_cast<const camera_metadata_t*>(m.metadata.data()));
|
|
}
|
|
|
|
std::optional<CameraMetadata> serializeCameraMetadataMap(const CameraMetadataMap& m) {
|
|
const size_t dataSize = std::accumulate(m.begin(), m.end(), 0,
|
|
[](const size_t z, const CameraMetadataMap::value_type& kv) {
|
|
return z + ((kv.second.count > 0) ? ((kv.second.data.size() + 7) & ~7U) : 0);
|
|
}
|
|
);
|
|
|
|
CameraMetadataPtr cm(allocate_camera_metadata(m.size() * 5 / 4, dataSize * 3 / 2));
|
|
|
|
for (const auto& [tag, value] : m) {
|
|
if (value.count > 0) {
|
|
if (add_camera_metadata_entry(cm.get(), tag, value.data.data(), value.count)) {
|
|
return FAILURE_V(std::nullopt, "failed to add tag=%s.%s(%u), count=%u",
|
|
get_camera_metadata_section_name(tag),
|
|
get_camera_metadata_tag_name(tag), tag,
|
|
value.count);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sort_camera_metadata(cm.get())) {
|
|
return FAILURE(std::nullopt);
|
|
}
|
|
|
|
return metadataCompactRaw(cm.get());
|
|
}
|
|
|
|
CameraMetadataMap parseCameraMetadataMap(const CameraMetadata& m) {
|
|
const camera_metadata_t* const raw =
|
|
reinterpret_cast<const camera_metadata_t*>(m.metadata.data());
|
|
const size_t n = get_camera_metadata_entry_count(raw);
|
|
|
|
CameraMetadataMap r;
|
|
for (size_t i = 0; i < n; ++i) {
|
|
camera_metadata_ro_entry_t e;
|
|
if (get_camera_metadata_ro_entry(raw, i, &e)) {
|
|
ALOGW("%s:%d get_camera_metadata_ro_entry(%zu) failed",
|
|
__func__, __LINE__, i);
|
|
} else {
|
|
auto& v = r[e.tag];
|
|
v.count = e.count;
|
|
const size_t sz = camera_metadata_type_size[e.type] * e.count;
|
|
v.data.assign(e.data.u8, e.data.u8 + sz);
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
void metadataSetShutterTimestamp(CameraMetadata* m, const int64_t shutterTimestampNs) {
|
|
if (m->metadata.empty()) {
|
|
return;
|
|
}
|
|
|
|
camera_metadata_t* const raw =
|
|
reinterpret_cast<camera_metadata_t*>(m->metadata.data());
|
|
|
|
camera_metadata_ro_entry_t entry;
|
|
if (find_camera_metadata_ro_entry(raw, ANDROID_SENSOR_TIMESTAMP, &entry)) {
|
|
ALOGW("%s:%d: find_camera_metadata_ro_entry(ANDROID_SENSOR_TIMESTAMP) failed",
|
|
__func__, __LINE__);
|
|
} else if (update_camera_metadata_entry(raw, entry.index, &shutterTimestampNs, 1, nullptr)) {
|
|
ALOGW("%s:%d: update_camera_metadata_entry(ANDROID_SENSOR_TIMESTAMP) failed",
|
|
__func__, __LINE__);
|
|
}
|
|
}
|
|
|
|
void prettyPrintCameraMetadata(const CameraMetadata& m) {
|
|
const camera_metadata_t* const raw =
|
|
reinterpret_cast<const camera_metadata_t*>(m.metadata.data());
|
|
const size_t n = get_camera_metadata_entry_count(raw);
|
|
|
|
for (size_t i = 0; i < n; ++i) {
|
|
camera_metadata_ro_entry_t e;
|
|
get_camera_metadata_ro_entry(raw, i, &e);
|
|
char value[256];
|
|
|
|
if (e.count > 0) {
|
|
switch (e.type) {
|
|
case TYPE_BYTE: {
|
|
char* s = value;
|
|
for (unsigned j = 0; j < e.count; ++j) {
|
|
s += snprintf(s, sizeof(value), "%s%u",
|
|
((j > 0) ? "," : ""), e.data.u8[j]);
|
|
}
|
|
}
|
|
break;
|
|
case TYPE_INT32: {
|
|
char* s = value;
|
|
for (unsigned j = 0; j < e.count; ++j) {
|
|
s += snprintf(s, sizeof(value), "%s%d",
|
|
((j > 0) ? "," : ""), e.data.i32[j]);
|
|
}
|
|
}
|
|
break;
|
|
case TYPE_FLOAT: {
|
|
char* s = value;
|
|
for (unsigned j = 0; j < e.count; ++j) {
|
|
s += snprintf(s, sizeof(value), "%s%g",
|
|
((j > 0) ? "," : ""), e.data.f[j]);
|
|
}
|
|
}
|
|
break;
|
|
case TYPE_INT64: {
|
|
char* s = value;
|
|
for (unsigned j = 0; j < e.count; ++j) {
|
|
s += snprintf(s, sizeof(value), "%s%" PRId64,
|
|
((j > 0) ? "," : ""), e.data.i64[j]);
|
|
}
|
|
}
|
|
break;
|
|
case TYPE_DOUBLE: {
|
|
char* s = value;
|
|
for (unsigned j = 0; j < e.count; ++j) {
|
|
s += snprintf(s, sizeof(value), "%s%g",
|
|
((j > 0) ? "," : ""), e.data.d[j]);
|
|
}
|
|
}
|
|
break;
|
|
case TYPE_RATIONAL: {
|
|
char* s = value;
|
|
for (unsigned j = 0; j < e.count; ++j) {
|
|
s += snprintf(s, sizeof(value), "%s%d/%d",
|
|
((j > 0) ? "," : ""),
|
|
e.data.r[j].numerator,
|
|
e.data.r[j].denominator);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
snprintf(value, sizeof(value), "%s", "bad type");
|
|
break;
|
|
}
|
|
} else {
|
|
snprintf(value, sizeof(value), "%s", "empty");
|
|
}
|
|
|
|
ALOGD("%s:%d i=%zu tag=%s.%s(%u),%s[%zu]: %s", __func__, __LINE__, i,
|
|
get_camera_metadata_section_name(e.tag),
|
|
get_camera_metadata_tag_name(e.tag),
|
|
e.tag, camera_metadata_type_names[e.type], e.count, value);
|
|
}
|
|
}
|
|
|
|
} // namespace implementation
|
|
} // namespace provider
|
|
} // namespace camera
|
|
} // namespace hardware
|
|
} // namespace android
|