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 #include <camera_metadata_hidden.h>
     27 
     28 namespace android {
     29 
     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 
     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 
     98 void TagMonitor::disableMonitoring() {
     99     mMonitoringEnabled = false;
    100     mLastMonitoredRequestValues.clear();
    101     mLastMonitoredResultValues.clear();
    102 }
    103 
    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 
    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 
    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>
    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 
    307 TagMonitor::MonitorEvent::~MonitorEvent() {
    308 }
    309 
    310 } // namespace android
    311