Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) 2012 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_NDEBUG 0
     18 
     19 #define LOG_TAG "Camera2-Metadata"
     20 #include <utils/Log.h>
     21 #include <utils/Errors.h>
     22 
     23 #include <camera/CameraMetadata.h>
     24 
     25 namespace android {
     26 
     27 CameraMetadata::CameraMetadata() :
     28         mBuffer(NULL), mLocked(false) {
     29 }
     30 
     31 CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) :
     32         mLocked(false)
     33 {
     34     mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
     35 }
     36 
     37 CameraMetadata::CameraMetadata(const CameraMetadata &other) :
     38         mLocked(false) {
     39     mBuffer = clone_camera_metadata(other.mBuffer);
     40 }
     41 
     42 CameraMetadata::CameraMetadata(camera_metadata_t *buffer) :
     43         mBuffer(NULL), mLocked(false) {
     44     acquire(buffer);
     45 }
     46 
     47 CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
     48     return operator=(other.mBuffer);
     49 }
     50 
     51 CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
     52     if (mLocked) {
     53         ALOGE("%s: Assignment to a locked CameraMetadata!", __FUNCTION__);
     54         return *this;
     55     }
     56 
     57     if (CC_LIKELY(buffer != mBuffer)) {
     58         camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
     59         clear();
     60         mBuffer = newBuffer;
     61     }
     62     return *this;
     63 }
     64 
     65 CameraMetadata::~CameraMetadata() {
     66     mLocked = false;
     67     clear();
     68 }
     69 
     70 const camera_metadata_t* CameraMetadata::getAndLock() {
     71     mLocked = true;
     72     return mBuffer;
     73 }
     74 
     75 status_t CameraMetadata::unlock(const camera_metadata_t *buffer) {
     76     if (!mLocked) {
     77         ALOGE("%s: Can't unlock a non-locked CameraMetadata!", __FUNCTION__);
     78         return INVALID_OPERATION;
     79     }
     80     if (buffer != mBuffer) {
     81         ALOGE("%s: Can't unlock CameraMetadata with wrong pointer!",
     82                 __FUNCTION__);
     83         return BAD_VALUE;
     84     }
     85     mLocked = false;
     86     return OK;
     87 }
     88 
     89 camera_metadata_t* CameraMetadata::release() {
     90     if (mLocked) {
     91         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
     92         return NULL;
     93     }
     94     camera_metadata_t *released = mBuffer;
     95     mBuffer = NULL;
     96     return released;
     97 }
     98 
     99 void CameraMetadata::clear() {
    100     if (mLocked) {
    101         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    102         return;
    103     }
    104     if (mBuffer) {
    105         free_camera_metadata(mBuffer);
    106         mBuffer = NULL;
    107     }
    108 }
    109 
    110 void CameraMetadata::acquire(camera_metadata_t *buffer) {
    111     if (mLocked) {
    112         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    113         return;
    114     }
    115     clear();
    116     mBuffer = buffer;
    117 
    118     ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) != OK,
    119              "%s: Failed to validate metadata structure %p",
    120              __FUNCTION__, buffer);
    121 }
    122 
    123 void CameraMetadata::acquire(CameraMetadata &other) {
    124     if (mLocked) {
    125         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    126         return;
    127     }
    128     acquire(other.release());
    129 }
    130 
    131 status_t CameraMetadata::append(const CameraMetadata &other) {
    132     if (mLocked) {
    133         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    134         return INVALID_OPERATION;
    135     }
    136     return append_camera_metadata(mBuffer, other.mBuffer);
    137 }
    138 
    139 size_t CameraMetadata::entryCount() const {
    140     return (mBuffer == NULL) ? 0 :
    141             get_camera_metadata_entry_count(mBuffer);
    142 }
    143 
    144 bool CameraMetadata::isEmpty() const {
    145     return entryCount() == 0;
    146 }
    147 
    148 status_t CameraMetadata::sort() {
    149     if (mLocked) {
    150         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    151         return INVALID_OPERATION;
    152     }
    153     return sort_camera_metadata(mBuffer);
    154 }
    155 
    156 status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
    157     int tagType = get_camera_metadata_tag_type(tag);
    158     if ( CC_UNLIKELY(tagType == -1)) {
    159         ALOGE("Update metadata entry: Unknown tag %d", tag);
    160         return INVALID_OPERATION;
    161     }
    162     if ( CC_UNLIKELY(tagType != expectedType) ) {
    163         ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
    164                 "got type %s data instead ",
    165                 get_camera_metadata_tag_name(tag), tag,
    166                 camera_metadata_type_names[tagType],
    167                 camera_metadata_type_names[expectedType]);
    168         return INVALID_OPERATION;
    169     }
    170     return OK;
    171 }
    172 
    173 status_t CameraMetadata::update(uint32_t tag,
    174         const int32_t *data, size_t data_count) {
    175     status_t res;
    176     if (mLocked) {
    177         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    178         return INVALID_OPERATION;
    179     }
    180     if ( (res = checkType(tag, TYPE_INT32)) != OK) {
    181         return res;
    182     }
    183     return updateImpl(tag, (const void*)data, data_count);
    184 }
    185 
    186 status_t CameraMetadata::update(uint32_t tag,
    187         const uint8_t *data, size_t data_count) {
    188     status_t res;
    189     if (mLocked) {
    190         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    191         return INVALID_OPERATION;
    192     }
    193     if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
    194         return res;
    195     }
    196     return updateImpl(tag, (const void*)data, data_count);
    197 }
    198 
    199 status_t CameraMetadata::update(uint32_t tag,
    200         const float *data, size_t data_count) {
    201     status_t res;
    202     if (mLocked) {
    203         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    204         return INVALID_OPERATION;
    205     }
    206     if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
    207         return res;
    208     }
    209     return updateImpl(tag, (const void*)data, data_count);
    210 }
    211 
    212 status_t CameraMetadata::update(uint32_t tag,
    213         const int64_t *data, size_t data_count) {
    214     status_t res;
    215     if (mLocked) {
    216         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    217         return INVALID_OPERATION;
    218     }
    219     if ( (res = checkType(tag, TYPE_INT64)) != OK) {
    220         return res;
    221     }
    222     return updateImpl(tag, (const void*)data, data_count);
    223 }
    224 
    225 status_t CameraMetadata::update(uint32_t tag,
    226         const double *data, size_t data_count) {
    227     status_t res;
    228     if (mLocked) {
    229         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    230         return INVALID_OPERATION;
    231     }
    232     if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
    233         return res;
    234     }
    235     return updateImpl(tag, (const void*)data, data_count);
    236 }
    237 
    238 status_t CameraMetadata::update(uint32_t tag,
    239         const camera_metadata_rational_t *data, size_t data_count) {
    240     status_t res;
    241     if (mLocked) {
    242         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    243         return INVALID_OPERATION;
    244     }
    245     if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
    246         return res;
    247     }
    248     return updateImpl(tag, (const void*)data, data_count);
    249 }
    250 
    251 status_t CameraMetadata::update(uint32_t tag,
    252         const String8 &string) {
    253     status_t res;
    254     if (mLocked) {
    255         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    256         return INVALID_OPERATION;
    257     }
    258     if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
    259         return res;
    260     }
    261     return updateImpl(tag, (const void*)string.string(), string.size());
    262 }
    263 
    264 status_t CameraMetadata::updateImpl(uint32_t tag, const void *data,
    265         size_t data_count) {
    266     status_t res;
    267     if (mLocked) {
    268         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    269         return INVALID_OPERATION;
    270     }
    271     int type = get_camera_metadata_tag_type(tag);
    272     if (type == -1) {
    273         ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
    274         return BAD_VALUE;
    275     }
    276     size_t data_size = calculate_camera_metadata_entry_data_size(type,
    277             data_count);
    278 
    279     res = resizeIfNeeded(1, data_size);
    280 
    281     if (res == OK) {
    282         camera_metadata_entry_t entry;
    283         res = find_camera_metadata_entry(mBuffer, tag, &entry);
    284         if (res == NAME_NOT_FOUND) {
    285             res = add_camera_metadata_entry(mBuffer,
    286                     tag, data, data_count);
    287         } else if (res == OK) {
    288             res = update_camera_metadata_entry(mBuffer,
    289                     entry.index, data, data_count, NULL);
    290         }
    291     }
    292 
    293     if (res != OK) {
    294         ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
    295                 __FUNCTION__, get_camera_metadata_section_name(tag),
    296                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    297     }
    298 
    299     IF_ALOGV() {
    300         ALOGE_IF(validate_camera_metadata_structure(mBuffer, /*size*/NULL) !=
    301                  OK,
    302 
    303                  "%s: Failed to validate metadata structure after update %p",
    304                  __FUNCTION__, mBuffer);
    305     }
    306 
    307     return res;
    308 }
    309 
    310 bool CameraMetadata::exists(uint32_t tag) const {
    311     camera_metadata_ro_entry entry;
    312     return find_camera_metadata_ro_entry(mBuffer, tag, &entry) == 0;
    313 }
    314 
    315 camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
    316     status_t res;
    317     camera_metadata_entry entry;
    318     if (mLocked) {
    319         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    320         entry.count = 0;
    321         return entry;
    322     }
    323     res = find_camera_metadata_entry(mBuffer, tag, &entry);
    324     if (CC_UNLIKELY( res != OK )) {
    325         entry.count = 0;
    326         entry.data.u8 = NULL;
    327     }
    328     return entry;
    329 }
    330 
    331 camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
    332     status_t res;
    333     camera_metadata_ro_entry entry;
    334     res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
    335     if (CC_UNLIKELY( res != OK )) {
    336         entry.count = 0;
    337         entry.data.u8 = NULL;
    338     }
    339     return entry;
    340 }
    341 
    342 status_t CameraMetadata::erase(uint32_t tag) {
    343     camera_metadata_entry_t entry;
    344     status_t res;
    345     if (mLocked) {
    346         ALOGE("%s: CameraMetadata is locked", __FUNCTION__);
    347         return INVALID_OPERATION;
    348     }
    349     res = find_camera_metadata_entry(mBuffer, tag, &entry);
    350     if (res == NAME_NOT_FOUND) {
    351         return OK;
    352     } else if (res != OK) {
    353         ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
    354                 __FUNCTION__,
    355                 get_camera_metadata_section_name(tag),
    356                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    357         return res;
    358     }
    359     res = delete_camera_metadata_entry(mBuffer, entry.index);
    360     if (res != OK) {
    361         ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
    362                 __FUNCTION__,
    363                 get_camera_metadata_section_name(tag),
    364                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    365     }
    366     return res;
    367 }
    368 
    369 void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
    370     dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
    371 }
    372 
    373 status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
    374     if (mBuffer == NULL) {
    375         mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
    376         if (mBuffer == NULL) {
    377             ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
    378             return NO_MEMORY;
    379         }
    380     } else {
    381         size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
    382         size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
    383         size_t newEntryCount = currentEntryCount +
    384                 extraEntries;
    385         newEntryCount = (newEntryCount > currentEntryCap) ?
    386                 newEntryCount * 2 : currentEntryCap;
    387 
    388         size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
    389         size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
    390         size_t newDataCount = currentDataCount +
    391                 extraData;
    392         newDataCount = (newDataCount > currentDataCap) ?
    393                 newDataCount * 2 : currentDataCap;
    394 
    395         if (newEntryCount > currentEntryCap ||
    396                 newDataCount > currentDataCap) {
    397             camera_metadata_t *oldBuffer = mBuffer;
    398             mBuffer = allocate_camera_metadata(newEntryCount,
    399                     newDataCount);
    400             if (mBuffer == NULL) {
    401                 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
    402                 return NO_MEMORY;
    403             }
    404             append_camera_metadata(mBuffer, oldBuffer);
    405             free_camera_metadata(oldBuffer);
    406         }
    407     }
    408     return OK;
    409 }
    410 
    411 }; // namespace android
    412