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