Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) 2013 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 #include <system/camera_metadata.h>
     18 
     19 //#define LOG_NDEBUG 0
     20 #define LOG_TAG "Metadata"
     21 #include <cutils/log.h>
     22 
     23 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
     24 #include <utils/Trace.h>
     25 
     26 #include "Metadata.h"
     27 
     28 namespace default_camera_hal {
     29 
     30 Metadata::Metadata():
     31     mData(NULL)
     32 {
     33 }
     34 
     35 Metadata::~Metadata()
     36 {
     37     replace(NULL);
     38 }
     39 
     40 void Metadata::replace(camera_metadata_t *m)
     41 {
     42     if (m == mData) {
     43         ALOGE("%s: Replacing metadata with itself?!", __func__);
     44         return;
     45     }
     46     if (mData)
     47         free_camera_metadata(mData);
     48     mData = m;
     49 }
     50 
     51 int Metadata::init(const camera_metadata_t *metadata)
     52 {
     53     camera_metadata_t* tmp;
     54 
     55     if (!validate_camera_metadata_structure(metadata, NULL))
     56         return -EINVAL;
     57 
     58     tmp = clone_camera_metadata(metadata);
     59     if (tmp == NULL)
     60         return -EINVAL;
     61 
     62     replace(tmp);
     63     return 0;
     64 }
     65 
     66 int Metadata::addUInt8(uint32_t tag, int count, const uint8_t *data)
     67 {
     68     if (!validate(tag, TYPE_BYTE, count)) return -EINVAL;
     69     return add(tag, count, data);
     70 }
     71 
     72 int Metadata::add1UInt8(uint32_t tag, const uint8_t data)
     73 {
     74     return addUInt8(tag, 1, &data);
     75 }
     76 
     77 int Metadata::addInt32(uint32_t tag, int count, const int32_t *data)
     78 {
     79     if (!validate(tag, TYPE_INT32, count)) return -EINVAL;
     80     return add(tag, count, data);
     81 }
     82 
     83 int Metadata::addFloat(uint32_t tag, int count, const float *data)
     84 {
     85     if (!validate(tag, TYPE_FLOAT, count)) return -EINVAL;
     86     return add(tag, count, data);
     87 }
     88 
     89 int Metadata::addInt64(uint32_t tag, int count, const int64_t *data)
     90 {
     91     if (!validate(tag, TYPE_INT64, count)) return -EINVAL;
     92     return add(tag, count, data);
     93 }
     94 
     95 int Metadata::addDouble(uint32_t tag, int count, const double *data)
     96 {
     97     if (!validate(tag, TYPE_DOUBLE, count)) return -EINVAL;
     98     return add(tag, count, data);
     99 }
    100 
    101 int Metadata::addRational(uint32_t tag, int count,
    102         const camera_metadata_rational_t *data)
    103 {
    104     if (!validate(tag, TYPE_RATIONAL, count)) return -EINVAL;
    105     return add(tag, count, data);
    106 }
    107 
    108 bool Metadata::validate(uint32_t tag, int tag_type, int count)
    109 {
    110     if (get_camera_metadata_tag_type(tag) < 0) {
    111         ALOGE("%s: Invalid metadata entry tag: %d", __func__, tag);
    112         return false;
    113     }
    114     if (tag_type < 0 || tag_type >= NUM_TYPES) {
    115         ALOGE("%s: Invalid metadata entry tag type: %d", __func__, tag_type);
    116         return false;
    117     }
    118     if (tag_type != get_camera_metadata_tag_type(tag)) {
    119         ALOGE("%s: Tag %d called with incorrect type: %s(%d)", __func__, tag,
    120                 camera_metadata_type_names[tag_type], tag_type);
    121         return false;
    122     }
    123     if (count < 1) {
    124         ALOGE("%s: Invalid metadata entry count: %d", __func__, count);
    125         return false;
    126     }
    127     return true;
    128 }
    129 
    130 int Metadata::add(uint32_t tag, int count, const void *tag_data)
    131 {
    132     int res;
    133     camera_metadata_t* tmp;
    134     int tag_type = get_camera_metadata_tag_type(tag);
    135     size_t size = calculate_camera_metadata_entry_data_size(tag_type, count);
    136     size_t entry_capacity = get_camera_metadata_entry_count(mData) + 1;
    137     size_t data_capacity = get_camera_metadata_data_count(mData) + size;
    138 
    139     // Opportunistically attempt to add if metadata has room for it
    140     if (!add_camera_metadata_entry(mData, tag, tag_data, count))
    141         return 0;
    142 
    143     // Double new dimensions to minimize future reallocations
    144     tmp = allocate_camera_metadata(entry_capacity * 2, data_capacity * 2);
    145     if (tmp == NULL) {
    146         ALOGE("%s: Failed to allocate new metadata with %zu entries, %zu data",
    147                 __func__, entry_capacity, data_capacity);
    148         return -ENOMEM;
    149     }
    150     // Append the current metadata to the new (empty) metadata
    151     res = append_camera_metadata(tmp, mData);
    152     if (res) {
    153         ALOGE("%s: Failed to append old metadata %p to new %p",
    154                 __func__, mData, tmp);
    155         return res;
    156     }
    157     // Add the remaining new item
    158     res = add_camera_metadata_entry(tmp, tag, tag_data, count);
    159     if (res) {
    160         ALOGE("%s: Failed to add new entry (%d, %p, %d) to metadata %p",
    161                 __func__, tag, tag_data, count, tmp);
    162         return res;
    163     }
    164 
    165     replace(tmp);
    166     return 0;
    167 }
    168 
    169 camera_metadata_t* Metadata::get()
    170 {
    171     return mData;
    172 }
    173 
    174 } // namespace default_camera_hal
    175