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
TagMonitor()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
parseTagsToMonitor(String8 tagNames)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
disableMonitoring()87 void TagMonitor::disableMonitoring() {
88 mMonitoringEnabled = false;
89 mLastMonitoredRequestValues.clear();
90 mLastMonitoredResultValues.clear();
91 }
92
monitorMetadata(eventSource source,int64_t frameNumber,nsecs_t timestamp,const CameraMetadata & metadata)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
dumpMonitoredMetadata(int fd)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
printData(int fd,const uint8_t * data_ptr,uint32_t tag,int type,int count,int indentation)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>
MonitorEvent(eventSource src,uint32_t frameNumber,nsecs_t timestamp,const T & value)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
~MonitorEvent()278 TagMonitor::MonitorEvent::~MonitorEvent() {
279 }
280
281 } // namespace android
282