• 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 
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