status_t CameraMetadata::append(const camera_metadata_t* other) { if (mLocked) { ALOGE("%s: CameraMetadata is locked", __FUNCTION__); return INVALID_OPERATION; } size_t extraEntries = get_camera_metadata_entry_count(other); size_t extraData = get_camera_metadata_data_count(other); resizeIfNeeded(extraEntries, extraData); return append_camera_metadata(mBuffer, other); }
status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { if (mBuffer == NULL) { mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2); if (mBuffer == NULL) { ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); return NO_MEMORY; } } else { size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer); size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer); size_t newEntryCount = currentEntryCount + extraEntries; newEntryCount = (newEntryCount > currentEntryCap) ? newEntryCount * 2 : currentEntryCap; size_t currentDataCount = get_camera_metadata_data_count(mBuffer); size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer); size_t newDataCount = currentDataCount + extraData; newDataCount = (newDataCount > currentDataCap) ? newDataCount * 2 : currentDataCap; if (newEntryCount > currentEntryCap || newDataCount > currentDataCap) { camera_metadata_t *oldBuffer = mBuffer; mBuffer = allocate_camera_metadata(newEntryCount, newDataCount); if (mBuffer == NULL) { ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); return NO_MEMORY; } append_camera_metadata(mBuffer, oldBuffer); free_camera_metadata(oldBuffer); } } return OK; }
size_t CameraMetadata::entryCount() const { return (mBuffer == NULL) ? 0 : get_camera_metadata_entry_count(mBuffer); }
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); } }