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 27 namespace android { 28 29 TagMonitor::TagMonitor(): 30 mMonitoringEnabled(false), 31 mMonitoringEvents(kMaxMonitorEvents) 32 {} 33 34 const char* TagMonitor::k3aTags = 35 "android.control.aeMode, android.control.afMode, android.control.awbMode," 36 "android.control.aeState, android.control.afState, android.control.awbState," 37 "android.control.aePrecaptureTrigger, android.control.afTrigger," 38 "android.control.aeRegions, android.control.awbRegions, android.control.afRegions," 39 "android.control.aeExposureCompensation, android.control.aeLock, android.control.awbLock," 40 "android.control.aeAntibandingMode, android.control.aeTargetFpsRange," 41 "android.control.effectMode, android.control.mode, android.control.sceneMode," 42 "android.control.videoStabilizationMode"; 43 44 void TagMonitor::parseTagsToMonitor(String8 tagNames) { 45 std::lock_guard<std::mutex> lock(mMonitorMutex); 46 47 // Expand shorthands 48 if (ssize_t idx = tagNames.find("3a") != -1) { 49 ssize_t end = tagNames.find(",", idx); 50 char* start = tagNames.lockBuffer(tagNames.size()); 51 start[idx] = '\0'; 52 char* rest = (end != -1) ? (start + end) : (start + tagNames.size()); 53 tagNames = String8::format("%s%s%s", start, k3aTags, rest); 54 } 55 56 sp<VendorTagDescriptor> vTags = 57 VendorTagDescriptor::getGlobalVendorTagDescriptor(); 58 59 bool gotTag = false; 60 61 char *tokenized = tagNames.lockBuffer(tagNames.size()); 62 char *savePtr; 63 char *nextTagName = strtok_r(tokenized, ", ", &savePtr); 64 while (nextTagName != nullptr) { 65 uint32_t tag; 66 status_t res = CameraMetadata::getTagFromName(nextTagName, vTags.get(), &tag); 67 if (res != OK) { 68 ALOGW("%s: Unknown tag %s, ignoring", __FUNCTION__, nextTagName); 69 } else { 70 if (!gotTag) { 71 mMonitoredTagList.clear(); 72 gotTag = true; 73 } 74 mMonitoredTagList.push_back(tag); 75 } 76 nextTagName = strtok_r(nullptr, ", ", &savePtr); 77 } 78 79 tagNames.unlockBuffer(); 80 81 if (gotTag) { 82 // Got at least one new tag 83 mMonitoringEnabled = true; 84 } 85 } 86 87 void TagMonitor::disableMonitoring() { 88 mMonitoringEnabled = false; 89 mLastMonitoredRequestValues.clear(); 90 mLastMonitoredResultValues.clear(); 91 } 92 93 void TagMonitor::monitorMetadata(eventSource source, int64_t frameNumber, nsecs_t timestamp, 94 const CameraMetadata& metadata) { 95 if (!mMonitoringEnabled) return; 96 97 std::lock_guard<std::mutex> lock(mMonitorMutex); 98 99 if (timestamp == 0) { 100 timestamp = systemTime(SYSTEM_TIME_BOOTTIME); 101 } 102 103 for (auto tag : mMonitoredTagList) { 104 camera_metadata_ro_entry entry = metadata.find(tag); 105 CameraMetadata &lastValues = (source == REQUEST) ? 106 mLastMonitoredRequestValues : mLastMonitoredResultValues; 107 camera_metadata_entry lastEntry = lastValues.find(tag); 108 109 if (entry.count > 0) { 110 bool isDifferent = false; 111 if (lastEntry.count > 0) { 112 // Have a last value, compare to see if changed 113 if (lastEntry.type == entry.type && 114 lastEntry.count == entry.count) { 115 // Same type and count, compare values 116 size_t bytesPerValue = camera_metadata_type_size[lastEntry.type]; 117 size_t entryBytes = bytesPerValue * lastEntry.count; 118 int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes); 119 if (cmp != 0) { 120 isDifferent = true; 121 } 122 } else { 123 // Count or type has changed 124 isDifferent = true; 125 } 126 } else { 127 // No last entry, so always consider to be different 128 isDifferent = true; 129 } 130 131 if (isDifferent) { 132 ALOGV("%s: Tag %s changed", __FUNCTION__, get_camera_metadata_tag_name(tag)); 133 lastValues.update(entry); 134 mMonitoringEvents.emplace(source, frameNumber, timestamp, entry); 135 } 136 } else if (lastEntry.count > 0) { 137 // Value has been removed 138 ALOGV("%s: Tag %s removed", __FUNCTION__, get_camera_metadata_tag_name(tag)); 139 lastValues.erase(tag); 140 entry.tag = tag; 141 entry.type = get_camera_metadata_tag_type(tag); 142 entry.count = 0; 143 mMonitoringEvents.emplace(source, frameNumber, timestamp, entry); 144 } 145 } 146 } 147 148 void TagMonitor::dumpMonitoredMetadata(int fd) { 149 std::lock_guard<std::mutex> lock(mMonitorMutex); 150 151 if (mMonitoringEnabled) { 152 dprintf(fd, " Tag monitoring enabled for tags:\n"); 153 for (uint32_t tag : mMonitoredTagList) { 154 dprintf(fd, " %s.%s\n", 155 get_camera_metadata_section_name(tag), 156 get_camera_metadata_tag_name(tag)); 157 } 158 } else { 159 dprintf(fd, " Tag monitoring disabled (enable with -m <name1,..,nameN>)\n"); 160 } 161 if (mMonitoringEvents.size() > 0) { 162 dprintf(fd, " Monitored tag event log:\n"); 163 for (const auto& event : mMonitoringEvents) { 164 int indentation = (event.source == REQUEST) ? 15 : 30; 165 dprintf(fd, " f%d:%" PRId64 "ns: %*s%s.%s: ", 166 event.frameNumber, event.timestamp, 167 indentation, 168 event.source == REQUEST ? "REQ:" : "RES:", 169 get_camera_metadata_section_name(event.tag), 170 get_camera_metadata_tag_name(event.tag)); 171 if (event.newData.size() == 0) { 172 dprintf(fd, " (Removed)\n"); 173 } else { 174 printData(fd, event.newData.data(), event.tag, 175 event.type, event.newData.size() / camera_metadata_type_size[event.type], 176 indentation + 18); 177 } 178 } 179 } 180 181 } 182 183 // TODO: Consolidate with printData from camera_metadata.h 184 185 #define CAMERA_METADATA_ENUM_STRING_MAX_SIZE 29 186 187 void TagMonitor::printData(int fd, const uint8_t *data_ptr, uint32_t tag, 188 int type, int count, int indentation) { 189 static int values_per_line[NUM_TYPES] = { 190 [TYPE_BYTE] = 16, 191 [TYPE_INT32] = 8, 192 [TYPE_FLOAT] = 8, 193 [TYPE_INT64] = 4, 194 [TYPE_DOUBLE] = 4, 195 [TYPE_RATIONAL] = 4, 196 }; 197 size_t type_size = camera_metadata_type_size[type]; 198 char value_string_tmp[CAMERA_METADATA_ENUM_STRING_MAX_SIZE]; 199 uint32_t value; 200 201 int lines = count / values_per_line[type]; 202 if (count % values_per_line[type] != 0) lines++; 203 204 int index = 0; 205 int j, k; 206 for (j = 0; j < lines; j++) { 207 dprintf(fd, "%*s[", (j != 0) ? indentation + 4 : 0, ""); 208 for (k = 0; 209 k < values_per_line[type] && count > 0; 210 k++, count--, index += type_size) { 211 212 switch (type) { 213 case TYPE_BYTE: 214 value = *(data_ptr + index); 215 if (camera_metadata_enum_snprint(tag, 216 value, 217 value_string_tmp, 218 sizeof(value_string_tmp)) 219 == OK) { 220 dprintf(fd, "%s ", value_string_tmp); 221 } else { 222 dprintf(fd, "%hhu ", 223 *(data_ptr + index)); 224 } 225 break; 226 case TYPE_INT32: 227 value = 228 *(int32_t*)(data_ptr + index); 229 if (camera_metadata_enum_snprint(tag, 230 value, 231 value_string_tmp, 232 sizeof(value_string_tmp)) 233 == OK) { 234 dprintf(fd, "%s ", value_string_tmp); 235 } else { 236 dprintf(fd, "%" PRId32 " ", 237 *(int32_t*)(data_ptr + index)); 238 } 239 break; 240 case TYPE_FLOAT: 241 dprintf(fd, "%0.8f ", 242 *(float*)(data_ptr + index)); 243 break; 244 case TYPE_INT64: 245 dprintf(fd, "%" PRId64 " ", 246 *(int64_t*)(data_ptr + index)); 247 break; 248 case TYPE_DOUBLE: 249 dprintf(fd, "%0.8f ", 250 *(double*)(data_ptr + index)); 251 break; 252 case TYPE_RATIONAL: { 253 int32_t numerator = *(int32_t*)(data_ptr + index); 254 int32_t denominator = *(int32_t*)(data_ptr + index + 4); 255 dprintf(fd, "(%d / %d) ", 256 numerator, denominator); 257 break; 258 } 259 default: 260 dprintf(fd, "??? "); 261 } 262 } 263 dprintf(fd, "]\n"); 264 } 265 } 266 267 template<typename T> 268 TagMonitor::MonitorEvent::MonitorEvent(eventSource src, uint32_t frameNumber, nsecs_t timestamp, 269 const T &value) : 270 source(src), 271 frameNumber(frameNumber), 272 timestamp(timestamp), 273 tag(value.tag), 274 type(value.type), 275 newData(value.data.u8, value.data.u8 + camera_metadata_type_size[value.type] * value.count) { 276 } 277 278 TagMonitor::MonitorEvent::~MonitorEvent() { 279 } 280 281 } // namespace android 282