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     size_t entry_capacity = 0;
    134     size_t data_capacity = 0;
    135     camera_metadata_t* tmp;
    136     int tag_type = get_camera_metadata_tag_type(tag);
    137     size_t size = calculate_camera_metadata_entry_data_size(tag_type, count);
    138 
    139     if (NULL == mData) {
    140         entry_capacity = 1;
    141         data_capacity = size;
    142     } else {
    143         entry_capacity = get_camera_metadata_entry_count(mData) + 1;
    144         data_capacity = get_camera_metadata_data_count(mData) + size;
    145     }
    146 
    147     // Opportunistically attempt to add if metadata exists and has room for it
    148     if (mData && !add_camera_metadata_entry(mData, tag, tag_data, count))
    149         return 0;
    150     // Double new dimensions to minimize future reallocations
    151     tmp = allocate_camera_metadata(entry_capacity * 2, data_capacity * 2);
    152     if (tmp == NULL) {
    153         ALOGE("%s: Failed to allocate new metadata with %zu entries, %zu data",
    154                 __func__, entry_capacity, data_capacity);
    155         return -ENOMEM;
    156     }
    157     // Append the current metadata to the new (empty) metadata, if any
    158     if (NULL != mData) {
    159       res = append_camera_metadata(tmp, mData);
    160       if (res) {
    161           ALOGE("%s: Failed to append old metadata %p to new %p",
    162                   __func__, mData, tmp);
    163           return res;
    164       }
    165     }
    166     // Add the remaining new item to tmp and replace mData
    167     res = add_camera_metadata_entry(tmp, tag, tag_data, count);
    168     if (res) {
    169         ALOGE("%s: Failed to add new entry (%d, %p, %d) to metadata %p",
    170                 __func__, tag, tag_data, count, tmp);
    171         return res;
    172     }
    173     replace(tmp);
    174 
    175     return 0;
    176 }
    177 
    178 camera_metadata_t* Metadata::get()
    179 {
    180     return mData;
    181 }
    182 
    183 } // namespace default_camera_hal
    184