1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #define LOG_TAG "Camera3-TagMonitor" 18 #define ATRACE_TAG ATRACE_TAG_CAMERA 19 //#define LOG_NDEBUG 0 20 21 #include "TagMonitor.h" 22 23 #include <inttypes.h> 24 #include <utils/Log.h> 25 #include <camera/VendorTagDescriptor.h> 26 #include <camera_metadata_hidden.h> 27 28 namespace android { 29 30 TagMonitor::TagMonitor(): 31 mMonitoringEnabled(false), 32 mMonitoringEvents(kMaxMonitorEvents), 33 mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID) 34 {} 35 36 const String16 TagMonitor::kMonitorOption = String16("-m"); 37 38 const char* TagMonitor::k3aTags = 39 "android.control.aeMode, android.control.afMode, android.control.awbMode," 40 "android.control.aeState, android.control.afState, android.control.awbState," 41 "android.control.aePrecaptureTrigger, android.control.afTrigger," 42 "android.control.aeRegions, android.control.awbRegions, android.control.afRegions," 43 "android.control.aeExposureCompensation, android.control.aeLock, android.control.awbLock," 44 "android.control.aeAntibandingMode, android.control.aeTargetFpsRange," 45 "android.control.effectMode, android.control.mode, android.control.sceneMode," 46 "android.control.videoStabilizationMode"; 47 48 void TagMonitor::parseTagsToMonitor(String8 tagNames) { 49 std::lock_guard<std::mutex> lock(mMonitorMutex); 50 51 // Expand shorthands 52 if (ssize_t idx = tagNames.find("3a") != -1) { 53 ssize_t end = tagNames.find(",", idx); 54 char* start = tagNames.lockBuffer(tagNames.size()); 55 start[idx] = '\0'; 56 char* rest = (end != -1) ? (start + end) : (start + tagNames.size()); 57 tagNames = String8::format("%s%s%s", start, k3aTags, rest); 58 } 59 60 sp<VendorTagDescriptor> vTags = 61 VendorTagDescriptor::getGlobalVendorTagDescriptor(); 62 if ((nullptr == vTags.get()) || (0 >= vTags->getTagCount())) { 63 sp<VendorTagDescriptorCache> cache = 64 VendorTagDescriptorCache::getGlobalVendorTagCache(); 65 if (cache.get()) { 66 cache->getVendorTagDescriptor(mVendorTagId, &vTags); 67 } 68 } 69 70 bool gotTag = false; 71 72 char *tokenized = tagNames.lockBuffer(tagNames.size()); 73 char *savePtr; 74 char *nextTagName = strtok_r(tokenized, ", ", &savePtr); 75 while (nextTagName != nullptr) { 76 uint32_t tag; 77 status_t res = CameraMetadata::getTagFromName(nextTagName, vTags.get(), &tag); 78 if (res != OK) { 79 ALOGW("%s: Unknown tag %s, ignoring", __FUNCTION__, nextTagName); 80 } else { 81 if (!gotTag) { 82 mMonitoredTagList.clear(); 83 gotTag = true; 84 } 85 mMonitoredTagList.push_back(tag); 86 } 87 nextTagName = strtok_r(nullptr, ", ", &savePtr); 88 } 89 90 tagNames.unlockBuffer(); 91 92 if (gotTag) { 93 // Got at least one new tag 94 mMonitoringEnabled = true; 95 } 96 } 97 98 void TagMonitor::disableMonitoring() { 99 mMonitoringEnabled = false; 100 mLastMonitoredRequestValues.clear(); 101 mLastMonitoredResultValues.clear(); 102 } 103 104 void TagMonitor::monitorMetadata(eventSource source, int64_t frameNumber, nsecs_t timestamp, 105 const CameraMetadata& metadata) { 106 if (!mMonitoringEnabled) return; 107 108 std::lock_guard<std::mutex> lock(mMonitorMutex); 109 110 if (timestamp == 0) { 111 timestamp = systemTime(SYSTEM_TIME_BOOTTIME); 112 } 113 114 for (auto tag : mMonitoredTagList) { 115 camera_metadata_ro_entry entry = metadata.find(tag); 116 CameraMetadata &lastValues = (source == REQUEST) ? 117 mLastMonitoredRequestValues : mLastMonitoredResultValues; 118 if (lastValues.isEmpty()) { 119 lastValues = CameraMetadata(mMonitoredTagList.size()); 120 const camera_metadata_t *metaBuffer = 121 lastValues.getAndLock(); 122 set_camera_metadata_vendor_id( 123 const_cast<camera_metadata_t *> (metaBuffer), mVendorTagId); 124 lastValues.unlock(metaBuffer); 125 } 126 127 camera_metadata_entry lastEntry = lastValues.find(tag); 128 129 if (entry.count > 0) { 130 bool isDifferent = false; 131 if (lastEntry.count > 0) { 132 // Have a last value, compare to see if changed 133 if (lastEntry.type == entry.type && 134 lastEntry.count == entry.count) { 135 // Same type and count, compare values 136 size_t bytesPerValue = camera_metadata_type_size[lastEntry.type]; 137 size_t entryBytes = bytesPerValue * lastEntry.count; 138 int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes); 139 if (cmp != 0) { 140 isDifferent = true; 141 } 142 } else { 143 // Count or type has changed 144 isDifferent = true; 145 } 146 } else { 147 // No last entry, so always consider to be different 148 isDifferent = true; 149 } 150 151 if (isDifferent) { 152 ALOGV("%s: Tag %s changed", __FUNCTION__, 153 get_local_camera_metadata_tag_name_vendor_id( 154 tag, mVendorTagId)); 155 lastValues.update(entry); 156 mMonitoringEvents.emplace(source, frameNumber, timestamp, entry); 157 } 158 } else if (lastEntry.count > 0) { 159 // Value has been removed 160 ALOGV("%s: Tag %s removed", __FUNCTION__, 161 get_local_camera_metadata_tag_name_vendor_id( 162 tag, mVendorTagId)); 163 lastValues.erase(tag); 164 entry.tag = tag; 165 entry.type = get_local_camera_metadata_tag_type_vendor_id(tag, 166 mVendorTagId); 167 entry.count = 0; 168 mMonitoringEvents.emplace(source, frameNumber, timestamp, entry); 169 } 170 } 171 } 172 173 void TagMonitor::dumpMonitoredMetadata(int fd) { 174 std::lock_guard<std::mutex> lock(mMonitorMutex); 175 176 if (mMonitoringEnabled) { 177 dprintf(fd, " Tag monitoring enabled for tags:\n"); 178 for (uint32_t tag : mMonitoredTagList) { 179 dprintf(fd, " %s.%s\n", 180 get_local_camera_metadata_section_name_vendor_id(tag, 181 mVendorTagId), 182 get_local_camera_metadata_tag_name_vendor_id(tag, 183 mVendorTagId)); 184 } 185 } else { 186 dprintf(fd, " Tag monitoring disabled (enable with -m <name1,..,nameN>)\n"); 187 } 188 if (mMonitoringEvents.size() > 0) { 189 dprintf(fd, " Monitored tag event log:\n"); 190 for (const auto& event : mMonitoringEvents) { 191 int indentation = (event.source == REQUEST) ? 15 : 30; 192 dprintf(fd, " f%d:%" PRId64 "ns: %*s%s.%s: ", 193 event.frameNumber, event.timestamp, 194 indentation, 195 event.source == REQUEST ? "REQ:" : "RES:", 196 get_local_camera_metadata_section_name_vendor_id(event.tag, 197 mVendorTagId), 198 get_local_camera_metadata_tag_name_vendor_id(event.tag, 199 mVendorTagId)); 200 if (event.newData.size() == 0) { 201 dprintf(fd, " (Removed)\n"); 202 } else { 203 printData(fd, event.newData.data(), event.tag, 204 event.type, event.newData.size() / camera_metadata_type_size[event.type], 205 indentation + 18); 206 } 207 } 208 } 209 210 } 211 212 // TODO: Consolidate with printData from camera_metadata.h 213 214 #define CAMERA_METADATA_ENUM_STRING_MAX_SIZE 29 215 216 void TagMonitor::printData(int fd, const uint8_t *data_ptr, uint32_t tag, 217 int type, int count, int indentation) { 218 static int values_per_line[NUM_TYPES] = { 219 [TYPE_BYTE] = 16, 220 [TYPE_INT32] = 8, 221 [TYPE_FLOAT] = 8, 222 [TYPE_INT64] = 4, 223 [TYPE_DOUBLE] = 4, 224 [TYPE_RATIONAL] = 4, 225 }; 226 size_t type_size = camera_metadata_type_size[type]; 227 char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE]; 228 uint32_t value; 229 230 int lines = count / values_per_line[type]; 231 if (count % values_per_line[type] != 0) lines++; 232 233 int index = 0; 234 int j, k; 235 for (j = 0; j < lines; j++) { 236 dprintf(fd, "%*s[", (j != 0) ? indentation + 4 : 0, ""); 237 for (k = 0; 238 k < values_per_line[type] && count > 0; 239 k++, count--, index += type_size) { 240 241 switch (type) { 242 case TYPE_BYTE: 243 value = *(data_ptr + index); 244 if (camera_metadata_enum_snprint(tag, 245 value, 246 value_string_tmp, 247 sizeof(value_string_tmp)) 248 == OK) { 249 dprintf(fd, "%s ", value_string_tmp); 250 } else { 251 dprintf(fd, "%hhu ", 252 *(data_ptr + index)); 253 } 254 break; 255 case TYPE_INT32: 256 value = 257 *(int32_t*)(data_ptr + index); 258 if (camera_metadata_enum_snprint(tag, 259 value, 260 value_string_tmp, 261 sizeof(value_string_tmp)) 262 == OK) { 263 dprintf(fd, "%s ", value_string_tmp); 264 } else { 265 dprintf(fd, "%" PRId32 " ", 266 *(int32_t*)(data_ptr + index)); 267 } 268 break; 269 case TYPE_FLOAT: 270 dprintf(fd, "%0.8f ", 271 *(float*)(data_ptr + index)); 272 break; 273 case TYPE_INT64: 274 dprintf(fd, "%" PRId64 " ", 275 *(int64_t*)(data_ptr + index)); 276 break; 277 case TYPE_DOUBLE: 278 dprintf(fd, "%0.8f ", 279 *(double*)(data_ptr + index)); 280 break; 281 case TYPE_RATIONAL: { 282 int32_t numerator = *(int32_t*)(data_ptr + index); 283 int32_t denominator = *(int32_t*)(data_ptr + index + 4); 284 dprintf(fd, "(%d / %d) ", 285 numerator, denominator); 286 break; 287 } 288 default: 289 dprintf(fd, "??? "); 290 } 291 } 292 dprintf(fd, "]\n"); 293 } 294 } 295 296 template<typename T> 297 TagMonitor::MonitorEvent::MonitorEvent(eventSource src, uint32_t frameNumber, nsecs_t timestamp, 298 const T &value) : 299 source(src), 300 frameNumber(frameNumber), 301 timestamp(timestamp), 302 tag(value.tag), 303 type(value.type), 304 newData(value.data.u8, value.data.u8 + camera_metadata_type_size[value.type] * value.count) { 305 } 306 307 TagMonitor::MonitorEvent::~MonitorEvent() { 308 } 309 310 } // namespace android 311