Home | History | Annotate | Download | only in utils
      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