status_t CameraMetadata::erase(uint32_t tag) { camera_metadata_entry_t entry; status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } res = find_camera_metadata_entry(mBuffer, tag, &entry); if (res == NAME_NOT_FOUND) { return OK; } else if (res != OK) { ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", __FUNCTION__, get_camera_metadata_section_name(tag), get_camera_metadata_tag_name(tag), tag, strerror(-res), res); return res; } res = delete_camera_metadata_entry(mBuffer, entry.index); if (res != OK) { ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", __FUNCTION__, get_camera_metadata_section_name(tag), get_camera_metadata_tag_name(tag), tag, strerror(-res), res); } return res; }
status_t CameraMetadata::update(uint32_t tag, const void *data, size_t data_count) { status_t res; int type = get_camera_metadata_tag_type(tag); if (type == -1) { ALOGE("%s: Tag %d not found", __FUNCTION__, tag); return BAD_VALUE; } size_t data_size = calculate_camera_metadata_entry_data_size(type, data_count); res = resizeIfNeeded(1, data_size); if (res == OK) { camera_metadata_entry_t entry; res = find_camera_metadata_entry(mBuffer, tag, &entry); if (res == NAME_NOT_FOUND) { res = add_camera_metadata_entry(mBuffer, tag, data, data_count); } else if (res == OK) { res = update_camera_metadata_entry(mBuffer, entry.index, data, data_count, NULL); } } if (res != OK) { ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", __FUNCTION__, get_camera_metadata_section_name(tag), get_camera_metadata_tag_name(tag), tag, strerror(-res), res); } return res; }
bool FrameProcessor::get3aResult(const CameraMetadata& result, int32_t tag, T* value, int32_t frameNumber, int cameraId) { camera_metadata_ro_entry_t entry; if (value == NULL) { ALOGE("%s: Camera %d: Value to write to is NULL", __FUNCTION__, cameraId); return false; } entry = result.find(tag); if (entry.count == 0) { ALOGE("%s: Camera %d: No %s provided by HAL for frame %d!", __FUNCTION__, cameraId, get_camera_metadata_tag_name(tag), frameNumber); return false; } else { switch(sizeof(Src)){ case sizeof(uint8_t): *value = static_cast<T>(entry.data.u8[0]); break; case sizeof(int32_t): *value = static_cast<T>(entry.data.i32[0]); break; default: ALOGE("%s: Camera %d: Unsupported source", __FUNCTION__, cameraId); return false; } } return true; }
status_t CameraMetadata::updateImpl(uint32_t tag, const void *data, size_t data_count) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } int type = get_camera_metadata_tag_type(tag); if (type == -1) { ALOGE("%s: Tag %d not found", __FUNCTION__, tag); return BAD_VALUE; } // Safety check - ensure that data isn't pointing to this metadata, since // that would get invalidated if a resize is needed size_t bufferSize = get_camera_metadata_size(mBuffer); uintptr_t bufAddr = reinterpret_cast<uintptr_t>(mBuffer); uintptr_t dataAddr = reinterpret_cast<uintptr_t>(data); if (dataAddr > bufAddr && dataAddr < (bufAddr + bufferSize)) { ALOGE("%s: Update attempted with data from the same metadata buffer!", __FUNCTION__); return INVALID_OPERATION; } size_t data_size = calculate_camera_metadata_entry_data_size(type, data_count); res = resizeIfNeeded(1, data_size); if (res == OK) { camera_metadata_entry_t entry; res = find_camera_metadata_entry(mBuffer, tag, &entry); if (res == NAME_NOT_FOUND) { res = add_camera_metadata_entry(mBuffer, tag, data, data_count); } else if (res == OK) { res = update_camera_metadata_entry(mBuffer, entry.index, data, data_count, NULL); } } if (res != OK) { ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", __FUNCTION__, get_camera_metadata_section_name(tag), get_camera_metadata_tag_name(tag), tag, strerror(-res), res); } IF_ALOGV() { ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK, "%s: Failed to validate metadata structure after update %p", __FUNCTION__, mBuffer); } return res; }
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 NULL; } 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 NULL; } if (count) * count = entry.count; return entry.data.u8; }
const void * getMetadataValues(const CameraMetadata &metadata, uint32_t tag, int type, int * count) { camera_metadata_ro_entry entry = metadata.find(tag); 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 NULL; } if (count) * count = entry.count; return entry.data.u8; }
status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { int tagType = get_camera_metadata_tag_type(tag); if ( CC_UNLIKELY(tagType == -1)) { ALOGE("Update metadata entry: Unknown tag %d", tag); return INVALID_OPERATION; } if ( CC_UNLIKELY(tagType != expectedType) ) { ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; " "got type %s data instead ", get_camera_metadata_tag_name(tag), tag, camera_metadata_type_names[tagType], camera_metadata_type_names[expectedType]); return INVALID_OPERATION; } return OK; }
status_t CameraMetadata::updateImpl(uint32_t tag, const void *data, size_t data_count) { status_t res; if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } int type = get_camera_metadata_tag_type(tag); if (type == -1) { ALOGE("%s: Tag %d not found", __FUNCTION__, tag); return BAD_VALUE; } size_t data_size = calculate_camera_metadata_entry_data_size(type, data_count); res = resizeIfNeeded(1, data_size); if (res == OK) { camera_metadata_entry_t entry; res = find_camera_metadata_entry(mBuffer, tag, &entry); if (res == NAME_NOT_FOUND) { res = add_camera_metadata_entry(mBuffer, tag, data, data_count); } else if (res == OK) { res = update_camera_metadata_entry(mBuffer, entry.index, data, data_count, NULL); } } if (res != OK) { ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", __FUNCTION__, get_camera_metadata_section_name(tag), get_camera_metadata_tag_name(tag), tag, strerror(-res), res); } IF_ALOGV() { ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK, "%s: Failed to validate metadata structure after update %p", __FUNCTION__, mBuffer); } return res; }
status_t CameraMetadata::getTagFromName(const char *name, const VendorTagDescriptor* vTags, uint32_t *tag) { if (name == nullptr || tag == nullptr) return BAD_VALUE; size_t nameLength = strlen(name); const SortedVector<String8> *vendorSections; size_t vendorSectionCount = 0; if (vTags != NULL) { vendorSections = vTags->getAllSectionNames(); vendorSectionCount = vendorSections->size(); } // First, find the section by the longest string match const char *section = NULL; size_t sectionIndex = 0; size_t sectionLength = 0; size_t totalSectionCount = ANDROID_SECTION_COUNT + vendorSectionCount; for (size_t i = 0; i < totalSectionCount; ++i) { const char *str = (i < ANDROID_SECTION_COUNT) ? camera_metadata_section_names[i] : (*vendorSections)[i - ANDROID_SECTION_COUNT].string(); ALOGV("%s: Trying to match against section '%s'", __FUNCTION__, str); if (strstr(name, str) == name) { // name begins with the section name size_t strLength = strlen(str); ALOGV("%s: Name begins with section name", __FUNCTION__); // section name is the longest we've found so far if (section == NULL || sectionLength < strLength) { section = str; sectionIndex = i; sectionLength = strLength; ALOGV("%s: Found new best section (%s)", __FUNCTION__, section); } } } // TODO: Make above get_camera_metadata_section_from_name ? if (section == NULL) { return NAME_NOT_FOUND; } else { ALOGV("%s: Found matched section '%s' (%zu)", __FUNCTION__, section, sectionIndex); } // Get the tag name component of the name const char *nameTagName = name + sectionLength + 1; // x.y.z -> z if (sectionLength + 1 >= nameLength) { return BAD_VALUE; } // Match rest of name against the tag names in that section only uint32_t candidateTag = 0; if (sectionIndex < ANDROID_SECTION_COUNT) { // Match built-in tags (typically android.*) uint32_t tagBegin, tagEnd; // [tagBegin, tagEnd) tagBegin = camera_metadata_section_bounds[sectionIndex][0]; tagEnd = camera_metadata_section_bounds[sectionIndex][1]; for (candidateTag = tagBegin; candidateTag < tagEnd; ++candidateTag) { const char *tagName = get_camera_metadata_tag_name(candidateTag); if (strcmp(nameTagName, tagName) == 0) { ALOGV("%s: Found matched tag '%s' (%d)", __FUNCTION__, tagName, candidateTag); break; } } if (candidateTag == tagEnd) { return NAME_NOT_FOUND; } } else if (vTags != NULL) { // Match vendor tags (typically com.*) const String8 sectionName(section); const String8 tagName(nameTagName); status_t res = OK; if ((res = vTags->lookupTag(tagName, sectionName, &candidateTag)) != OK) { return NAME_NOT_FOUND; } } *tag = candidateTag; return OK; }
void dumpMetadata(const camera_metadata_t * meta) { if (!meta) return; if ((gLogLevel & CAMERA_DEBUG_LOG_LEVEL2) != CAMERA_DEBUG_LOG_LEVEL2) 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 == NULL) { tagSection = "unknownSection"; } tagName = get_camera_metadata_tag_name(entry.tag); if (tagName == NULL) { tagName = "unknownTag"; } const char *typeName; if (entry.type >= NUM_TYPES) { typeName = "unknown"; } else { typeName = camera_metadata_type_names[entry.type]; } LOG2("(%d)%s.%s (%05x): %s[%d], type: %d\n", i, tagSection, tagName, entry.tag, typeName, entry.count, entry.type); // Print data #define MAX_DATA_COUNT 512 size_t j; int length = 0; char str[64 + 8 * (MAX_DATA_COUNT)] = {0}; const uint8_t *u8; const int32_t *i32; const float *f; const int64_t *i64; const double *d; const camera_metadata_rational_t *r; length = sprintf(str+length,"["); if (length < 0) { LOGW("%s sprintf failed at %d", __FUNCTION__, __LINE__); return; } switch (entry.type) { case TYPE_BYTE: u8 = entry.data.u8; for (j = 0; j < entry.count; j++) { length += sprintf(str+length, "%d ", u8[j]); } break; case TYPE_INT32: i32 = entry.data.i32; for (j = 0; j < entry.count; j++) length += sprintf(str+length, " %d ", i32[j]); break; case TYPE_FLOAT: f = entry.data.f; for (j = 0; j < entry.count; j++) length += sprintf(str+length, " %0.2f ", f[j]); break; case TYPE_INT64: i64 = entry.data.i64; for (j = 0; j < entry.count; j++) length += sprintf(str+length, " %lld ", i64[j]); break; case TYPE_DOUBLE: d = entry.data.d; for (j = 0; j < entry.count; j++) length += sprintf(str+length, " %0.2f ", d[j]); break; case TYPE_RATIONAL: r = entry.data.r; for (j = 0; j < entry.count; j++) length += sprintf(str+length, " (%d, %d) ", r[j].numerator, r[j].denominator); break; } if (length < 0) { LOGW("%s sprintf failed at %d", __FUNCTION__, __LINE__); return; } length += sprintf(str+length, "]"); LOG2("%s", str); } }