Home | History | Annotate | Download | only in camera2
      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_TAG "Camera2-Metadata"
     18 #include <utils/Log.h>
     19 #include <utils/Errors.h>
     20 
     21 #include "CameraMetadata.h"
     22 
     23 namespace android {
     24 
     25 namespace camera2 {
     26 CameraMetadata::CameraMetadata() :
     27         mBuffer(NULL) {
     28 }
     29 
     30 CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity)
     31 {
     32     mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity);
     33 }
     34 
     35 CameraMetadata::CameraMetadata(const CameraMetadata &other) {
     36     mBuffer = clone_camera_metadata(other.mBuffer);
     37 }
     38 
     39 CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) {
     40     return operator=(other.mBuffer);
     41 }
     42 
     43 CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) {
     44     if (CC_LIKELY(buffer != mBuffer)) {
     45         camera_metadata_t *newBuffer = clone_camera_metadata(buffer);
     46         clear();
     47         mBuffer = newBuffer;
     48     }
     49     return *this;
     50 }
     51 
     52 CameraMetadata::~CameraMetadata() {
     53     clear();
     54 }
     55 
     56 camera_metadata_t* CameraMetadata::release() {
     57     camera_metadata_t *released = mBuffer;
     58     mBuffer = NULL;
     59     return released;
     60 }
     61 
     62 void CameraMetadata::clear() {
     63     if (mBuffer) {
     64         free_camera_metadata(mBuffer);
     65         mBuffer = NULL;
     66     }
     67 }
     68 
     69 void CameraMetadata::acquire(camera_metadata_t *buffer) {
     70     clear();
     71     mBuffer = buffer;
     72 }
     73 
     74 void CameraMetadata::acquire(CameraMetadata &other) {
     75     acquire(other.release());
     76 }
     77 
     78 status_t CameraMetadata::append(const CameraMetadata &other) {
     79     return append_camera_metadata(mBuffer, other.mBuffer);
     80 }
     81 
     82 size_t CameraMetadata::entryCount() const {
     83     return (mBuffer == NULL) ? 0 :
     84             get_camera_metadata_entry_count(mBuffer);
     85 }
     86 
     87 bool CameraMetadata::isEmpty() const {
     88     return entryCount() == 0;
     89 }
     90 
     91 status_t CameraMetadata::sort() {
     92     return sort_camera_metadata(mBuffer);
     93 }
     94 
     95 status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) {
     96     int tagType = get_camera_metadata_tag_type(tag);
     97     if ( CC_UNLIKELY(tagType == -1)) {
     98         ALOGE("Update metadata entry: Unknown tag %d", tag);
     99         return INVALID_OPERATION;
    100     }
    101     if ( CC_UNLIKELY(tagType != expectedType) ) {
    102         ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; "
    103                 "got type %s data instead ",
    104                 get_camera_metadata_tag_name(tag), tag,
    105                 camera_metadata_type_names[tagType],
    106                 camera_metadata_type_names[expectedType]);
    107         return INVALID_OPERATION;
    108     }
    109     return OK;
    110 }
    111 
    112 status_t CameraMetadata::update(uint32_t tag,
    113         const int32_t *data, size_t data_count) {
    114     status_t res;
    115     if ( (res = checkType(tag, TYPE_INT32)) != OK) {
    116         return res;
    117     }
    118     return update(tag, (const void*)data, data_count);
    119 }
    120 
    121 status_t CameraMetadata::update(uint32_t tag,
    122         const uint8_t *data, size_t data_count) {
    123     status_t res;
    124     if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
    125         return res;
    126     }
    127     return update(tag, (const void*)data, data_count);
    128 }
    129 
    130 status_t CameraMetadata::update(uint32_t tag,
    131         const float *data, size_t data_count) {
    132     status_t res;
    133     if ( (res = checkType(tag, TYPE_FLOAT)) != OK) {
    134         return res;
    135     }
    136     return update(tag, (const void*)data, data_count);
    137 }
    138 
    139 status_t CameraMetadata::update(uint32_t tag,
    140         const int64_t *data, size_t data_count) {
    141     status_t res;
    142     if ( (res = checkType(tag, TYPE_INT64)) != OK) {
    143         return res;
    144     }
    145     return update(tag, (const void*)data, data_count);
    146 }
    147 
    148 status_t CameraMetadata::update(uint32_t tag,
    149         const double *data, size_t data_count) {
    150     status_t res;
    151     if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) {
    152         return res;
    153     }
    154     return update(tag, (const void*)data, data_count);
    155 }
    156 
    157 status_t CameraMetadata::update(uint32_t tag,
    158         const camera_metadata_rational_t *data, size_t data_count) {
    159     status_t res;
    160     if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) {
    161         return res;
    162     }
    163     return update(tag, (const void*)data, data_count);
    164 }
    165 
    166 status_t CameraMetadata::update(uint32_t tag,
    167         const String8 &string) {
    168     status_t res;
    169     if ( (res = checkType(tag, TYPE_BYTE)) != OK) {
    170         return res;
    171     }
    172     return update(tag, (const void*)string.string(), string.size());
    173 }
    174 
    175 status_t CameraMetadata::update(uint32_t tag, const void *data,
    176         size_t data_count) {
    177     status_t res;
    178     int type = get_camera_metadata_tag_type(tag);
    179     if (type == -1) {
    180         ALOGE("%s: Tag %d not found", __FUNCTION__, tag);
    181         return BAD_VALUE;
    182     }
    183     size_t data_size = calculate_camera_metadata_entry_data_size(type,
    184             data_count);
    185 
    186     res = resizeIfNeeded(1, data_size);
    187 
    188     if (res == OK) {
    189         camera_metadata_entry_t entry;
    190         res = find_camera_metadata_entry(mBuffer, tag, &entry);
    191         if (res == NAME_NOT_FOUND) {
    192             res = add_camera_metadata_entry(mBuffer,
    193                     tag, data, data_count);
    194         } else if (res == OK) {
    195             res = update_camera_metadata_entry(mBuffer,
    196                     entry.index, data, data_count, NULL);
    197         }
    198     }
    199 
    200     if (res != OK) {
    201         ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
    202                 __FUNCTION__, get_camera_metadata_section_name(tag),
    203                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    204     }
    205     return res;
    206 }
    207 
    208 camera_metadata_entry_t CameraMetadata::find(uint32_t tag) {
    209     status_t res;
    210     camera_metadata_entry entry;
    211     res = find_camera_metadata_entry(mBuffer, tag, &entry);
    212     if (CC_UNLIKELY( res != OK )) {
    213         entry.count = 0;
    214         entry.data.u8 = NULL;
    215     }
    216     return entry;
    217 }
    218 
    219 camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const {
    220     status_t res;
    221     camera_metadata_ro_entry entry;
    222     res = find_camera_metadata_ro_entry(mBuffer, tag, &entry);
    223     if (CC_UNLIKELY( res != OK )) {
    224         entry.count = 0;
    225         entry.data.u8 = NULL;
    226     }
    227     return entry;
    228 }
    229 
    230 status_t CameraMetadata::erase(uint32_t tag) {
    231     camera_metadata_entry_t entry;
    232     status_t res;
    233     res = find_camera_metadata_entry(mBuffer, tag, &entry);
    234     if (res == NAME_NOT_FOUND) {
    235         return OK;
    236     } else if (res != OK) {
    237         ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
    238                 __FUNCTION__,
    239                 get_camera_metadata_section_name(tag),
    240                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    241         return res;
    242     }
    243     res = delete_camera_metadata_entry(mBuffer, entry.index);
    244     if (res != OK) {
    245         ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
    246                 __FUNCTION__,
    247                 get_camera_metadata_section_name(tag),
    248                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
    249     }
    250     return res;
    251 }
    252 
    253 void CameraMetadata::dump(int fd, int verbosity, int indentation) const {
    254     dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation);
    255 }
    256 
    257 status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) {
    258     if (mBuffer == NULL) {
    259         mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2);
    260         if (mBuffer == NULL) {
    261             ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
    262             return NO_MEMORY;
    263         }
    264     } else {
    265         size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer);
    266         size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer);
    267         size_t newEntryCount = currentEntryCount +
    268                 extraEntries;
    269         newEntryCount = (newEntryCount > currentEntryCap) ?
    270                 newEntryCount * 2 : currentEntryCap;
    271 
    272         size_t currentDataCount = get_camera_metadata_data_count(mBuffer);
    273         size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer);
    274         size_t newDataCount = currentDataCount +
    275                 extraData;
    276         newDataCount = (newDataCount > currentDataCap) ?
    277                 newDataCount * 2 : currentDataCap;
    278 
    279         if (newEntryCount > currentEntryCap ||
    280                 newDataCount > currentDataCap) {
    281             camera_metadata_t *oldBuffer = mBuffer;
    282             mBuffer = allocate_camera_metadata(newEntryCount,
    283                     newDataCount);
    284             if (mBuffer == NULL) {
    285                 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__);
    286                 return NO_MEMORY;
    287             }
    288             append_camera_metadata(mBuffer, oldBuffer);
    289             free_camera_metadata(oldBuffer);
    290         }
    291     }
    292     return OK;
    293 }
    294 
    295 }; // namespace camera2
    296 }; // namespace android
    297