• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TagMonitor()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 
parseTagsToMonitor(String8 tagNames)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 
disableMonitoring()98 void TagMonitor::disableMonitoring() {
99     mMonitoringEnabled = false;
100     mLastMonitoredRequestValues.clear();
101     mLastMonitoredResultValues.clear();
102 }
103 
monitorMetadata(eventSource source,int64_t frameNumber,nsecs_t timestamp,const CameraMetadata & metadata)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 
dumpMonitoredMetadata(int fd)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 
printData(int fd,const uint8_t * data_ptr,uint32_t tag,int type,int count,int indentation)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>
MonitorEvent(eventSource src,uint32_t frameNumber,nsecs_t timestamp,const T & value)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 
~MonitorEvent()307 TagMonitor::MonitorEvent::~MonitorEvent() {
308 }
309 
310 } // namespace android
311