278 lines
8.4 KiB
C++
278 lines
8.4 KiB
C++
/*
|
|
* Copyright (C) 2014-2017 Intel Corporation
|
|
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#define LOG_TAG "MetadataHelper"
|
|
#include "CameraMetadataHelper.h"
|
|
#include "LogHelper.h"
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
NAMESPACE_DECLARATION {
|
|
namespace MetadataHelper {
|
|
|
|
#define CHECK_AND_GET(TYPE, UNION_FIELD) \
|
|
camera_metadata_ro_entry entry = metadata.find(tag); \
|
|
if (entry.count == 0) { \
|
|
LOGI("tag %s.%s is not set.", \
|
|
get_camera_metadata_section_name(tag), \
|
|
get_camera_metadata_tag_name(tag)); \
|
|
return false; \
|
|
} else if (count > 0 && entry.count != (size_t)count) { \
|
|
LOGE("Bad count %d for tag %s.%s! Should be %zu", \
|
|
count, \
|
|
get_camera_metadata_section_name(tag), \
|
|
get_camera_metadata_tag_name(tag), \
|
|
entry.count); \
|
|
return false; \
|
|
} else if (entry.type != (TYPE)) { \
|
|
LOGE("Bad type %d for tag %s.%s! Should be %d", \
|
|
TYPE, \
|
|
get_camera_metadata_section_name(tag), \
|
|
get_camera_metadata_tag_name(tag), \
|
|
entry.type); \
|
|
return false; \
|
|
}\
|
|
value = *entry.data.UNION_FIELD; \
|
|
return true;
|
|
|
|
bool getMetadataValue(const CameraMetadata &metadata, uint32_t tag, uint8_t & value, int count)
|
|
{
|
|
CHECK_AND_GET(TYPE_BYTE, u8);
|
|
}
|
|
bool getMetadataValue(const CameraMetadata &metadata, uint32_t tag, int32_t & value, int count)
|
|
{
|
|
CHECK_AND_GET(TYPE_INT32, i32);
|
|
}
|
|
bool getMetadataValue(const CameraMetadata &metadata, uint32_t tag, int64_t & value, int count)
|
|
{
|
|
CHECK_AND_GET(TYPE_INT64, i64);
|
|
}
|
|
bool getMetadataValue(const CameraMetadata &metadata, uint32_t tag, float & value, int count)
|
|
{
|
|
CHECK_AND_GET(TYPE_FLOAT, f);
|
|
}
|
|
bool getMetadataValue(const CameraMetadata &metadata, uint32_t tag, double & value, int count)
|
|
{
|
|
CHECK_AND_GET(TYPE_DOUBLE, d);
|
|
}
|
|
|
|
const void * getMetadataValues(const CameraMetadata &metadata, uint32_t tag, int type, int * count)
|
|
{
|
|
camera_metadata_ro_entry entry = metadata.find(tag);
|
|
|
|
if (count)
|
|
*count = entry.count;
|
|
|
|
if (entry.count == 0) {
|
|
LOGI("Tag %s.%s is not set.",
|
|
get_camera_metadata_section_name(tag),
|
|
get_camera_metadata_tag_name(tag));
|
|
return nullptr;
|
|
}
|
|
|
|
if (entry.type != type) {
|
|
LOGE("Bad type %d for tag %s.%s! Should be %d",
|
|
type,
|
|
get_camera_metadata_section_name(tag),
|
|
get_camera_metadata_tag_name(tag),
|
|
entry.type);
|
|
return nullptr;
|
|
}
|
|
|
|
return entry.data.u8;
|
|
}
|
|
|
|
/**
|
|
* Convenience getter for an entry. Difference to the framework version is that
|
|
* the tag is always written to the entry, even if no entry is found.
|
|
*
|
|
* \param[in] metadata The camera metadata to get tag info for
|
|
* \param[in] tag Tag of the queried metadata
|
|
* \param[in] printError If set to \e true, Prints an error if no metadata
|
|
* for given tag found. Default: true.
|
|
*
|
|
* \return The metadata entry corresponding to \e tag.
|
|
*/
|
|
camera_metadata_ro_entry_t getMetadataEntry(const camera_metadata_t *metadata, uint32_t tag, bool printError)
|
|
{
|
|
camera_metadata_ro_entry entry;
|
|
CLEAR(entry);
|
|
entry.tag = tag;
|
|
find_camera_metadata_ro_entry(metadata, tag, &entry);
|
|
|
|
if (printError && entry.count <= 0)
|
|
LOGW("Metadata error, check camera3_profile. Tag %s", get_camera_metadata_tag_name(tag));
|
|
|
|
return entry;
|
|
}
|
|
|
|
void getValueByType(const camera_metadata_ro_entry_t& setting, int idx, uint8_t* value)
|
|
{
|
|
*value = setting.data.u8[idx];
|
|
}
|
|
|
|
void getValueByType(const camera_metadata_ro_entry_t& setting, int idx, int32_t* value)
|
|
{
|
|
*value = setting.data.i32[idx];
|
|
}
|
|
|
|
void getValueByType(const camera_metadata_ro_entry_t& setting, int idx, float* value)
|
|
{
|
|
*value = setting.data.f[idx];
|
|
}
|
|
|
|
void getValueByType(const camera_metadata_ro_entry_t& setting, int idx, int64_t* value)
|
|
{
|
|
*value = setting.data.i64[idx];
|
|
}
|
|
|
|
void getValueByType(const camera_metadata_ro_entry_t& setting, int idx, double* value)
|
|
{
|
|
*value = setting.data.d[idx];
|
|
}
|
|
|
|
const void * getMetadataValues(const camera_metadata_t * metadata, uint32_t tag, int type, int * count)
|
|
{
|
|
status_t res = NO_ERROR;
|
|
camera_metadata_ro_entry entry;
|
|
res = find_camera_metadata_ro_entry(metadata, tag, &entry);
|
|
if (res != OK) {
|
|
LOGE("Failed to find %s.%s",
|
|
get_camera_metadata_section_name(tag),
|
|
get_camera_metadata_tag_name(tag));
|
|
return nullptr;
|
|
}
|
|
if (entry.type != type) {
|
|
LOGE("Bad type %d for tag %s.%s! Should be %d",
|
|
type,
|
|
get_camera_metadata_section_name(tag),
|
|
get_camera_metadata_tag_name(tag),
|
|
entry.type);
|
|
return nullptr;
|
|
}
|
|
if (count)
|
|
* count = entry.count;
|
|
|
|
return entry.count ? entry.data.u8 : nullptr;
|
|
}
|
|
|
|
status_t updateMetadata(camera_metadata_t * metadata, uint32_t tag, const void* data, size_t data_count)
|
|
{
|
|
status_t res = NO_ERROR;
|
|
camera_metadata_entry_t entry;
|
|
res = find_camera_metadata_entry(metadata, tag, &entry);
|
|
if (res == NAME_NOT_FOUND) {
|
|
res = add_camera_metadata_entry(metadata,
|
|
tag, data, data_count);
|
|
} else if (res == OK) {
|
|
res = update_camera_metadata_entry(metadata,
|
|
entry.index, data, data_count, nullptr);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
void dumpMetadata(const camera_metadata_t * meta)
|
|
{
|
|
if (!meta)
|
|
return;
|
|
|
|
int entryCount = get_camera_metadata_entry_count(meta);
|
|
|
|
for (int i = 0; i < entryCount; i++) {
|
|
camera_metadata_entry_t entry;
|
|
if (get_camera_metadata_entry((camera_metadata_t *)meta, i, &entry)) {
|
|
continue;
|
|
}
|
|
|
|
// Print tag & type
|
|
const char *tagName, *tagSection;
|
|
tagSection = get_camera_metadata_section_name(entry.tag);
|
|
if (tagSection == nullptr) {
|
|
tagSection = "unknownSection";
|
|
}
|
|
tagName = get_camera_metadata_tag_name(entry.tag);
|
|
if (tagName == nullptr) {
|
|
tagName = "unknownTag";
|
|
}
|
|
const char *typeName;
|
|
if (entry.type >= NUM_TYPES) {
|
|
typeName = "unknown";
|
|
} else {
|
|
typeName = camera_metadata_type_names[entry.type];
|
|
}
|
|
LOGD("(%d)%s.%s (%05x): %s[%zu], type: %d",
|
|
i,
|
|
tagSection,
|
|
tagName,
|
|
entry.tag,
|
|
typeName,
|
|
entry.count,
|
|
entry.type);
|
|
|
|
// Print data
|
|
size_t j;
|
|
const uint8_t *u8;
|
|
const int32_t *i32;
|
|
const float *f;
|
|
const int64_t *i64;
|
|
const double *d;
|
|
const camera_metadata_rational_t *r;
|
|
std::ostringstream stringStream;
|
|
stringStream << "[";
|
|
|
|
switch (entry.type) {
|
|
case TYPE_BYTE:
|
|
u8 = entry.data.u8;
|
|
for (j = 0; j < entry.count; j++)
|
|
stringStream << (int32_t)u8[j] << " ";
|
|
break;
|
|
case TYPE_INT32:
|
|
i32 = entry.data.i32;
|
|
for (j = 0; j < entry.count; j++)
|
|
stringStream << " " << i32[j] << " ";
|
|
break;
|
|
case TYPE_FLOAT:
|
|
f = entry.data.f;
|
|
for (j = 0; j < entry.count; j++)
|
|
stringStream << " " << f[j] << " ";
|
|
break;
|
|
case TYPE_INT64:
|
|
i64 = entry.data.i64;
|
|
for (j = 0; j < entry.count; j++)
|
|
stringStream << " " << i64[j] << " ";
|
|
break;
|
|
case TYPE_DOUBLE:
|
|
d = entry.data.d;
|
|
for (j = 0; j < entry.count; j++)
|
|
stringStream << " " << d[j] << " ";
|
|
break;
|
|
case TYPE_RATIONAL:
|
|
r = entry.data.r;
|
|
for (j = 0; j < entry.count; j++)
|
|
stringStream << " (" << r[j].numerator << ", " << r[j].denominator << ") ";
|
|
break;
|
|
}
|
|
stringStream << "]";
|
|
std::string str = stringStream.str();
|
|
LOGD("%s", str.c_str());
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
} NAMESPACE_DECLARATION_END
|