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 <pthread.h> 18 #include <system/camera_metadata.h> 19 20 //#define LOG_NDEBUG 0 21 #define LOG_TAG "Metadata" 22 #include <cutils/log.h> 23 24 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL) 25 #include <cutils/trace.h> 26 #include "ScopedTrace.h" 27 28 #include "Metadata.h" 29 30 namespace default_camera_hal { 31 32 Metadata::Metadata() 33 : mHead(NULL), 34 mTail(NULL), 35 mEntryCount(0), 36 mDataCount(0), 37 mGenerated(NULL), 38 mDirty(true) 39 { 40 // NULL (default) pthread mutex attributes 41 pthread_mutex_init(&mMutex, NULL); 42 } 43 44 Metadata::~Metadata() 45 { 46 Entry *current = mHead; 47 48 while (current != NULL) { 49 Entry *tmp = current; 50 current = current->mNext; 51 delete tmp; 52 } 53 54 if (mGenerated != NULL) 55 free_camera_metadata(mGenerated); 56 57 pthread_mutex_destroy(&mMutex); 58 } 59 60 Metadata::Metadata(uint8_t mode, uint8_t intent) 61 : mHead(NULL), 62 mTail(NULL), 63 mEntryCount(0), 64 mDataCount(0), 65 mGenerated(NULL), 66 mDirty(true) 67 { 68 pthread_mutex_init(&mMutex, NULL); 69 70 if (validate(ANDROID_CONTROL_MODE, TYPE_BYTE, 1)) { 71 int res = add(ANDROID_CONTROL_MODE, 1, &mode); 72 if (res != 0) { 73 ALOGE("%s: Unable to add mode to template!", __func__); 74 } 75 } else { 76 ALOGE("%s: Invalid mode constructing template!", __func__); 77 } 78 79 if (validate(ANDROID_CONTROL_CAPTURE_INTENT, TYPE_BYTE, 1)) { 80 int res = add(ANDROID_CONTROL_CAPTURE_INTENT, 1, &intent); 81 if (res != 0) { 82 ALOGE("%s: Unable to add capture intent to template!", __func__); 83 } 84 } else { 85 ALOGE("%s: Invalid capture intent constructing template!", __func__); 86 } 87 } 88 89 int Metadata::addUInt8(uint32_t tag, int count, uint8_t *data) 90 { 91 if (!validate(tag, TYPE_BYTE, count)) return -EINVAL; 92 return add(tag, count, data); 93 } 94 95 int Metadata::addInt32(uint32_t tag, int count, int32_t *data) 96 { 97 if (!validate(tag, TYPE_INT32, count)) return -EINVAL; 98 return add(tag, count, data); 99 } 100 101 int Metadata::addFloat(uint32_t tag, int count, float *data) 102 { 103 if (!validate(tag, TYPE_FLOAT, count)) return -EINVAL; 104 return add(tag, count, data); 105 } 106 107 int Metadata::addInt64(uint32_t tag, int count, int64_t *data) 108 { 109 if (!validate(tag, TYPE_INT64, count)) return -EINVAL; 110 return add(tag, count, data); 111 } 112 113 int Metadata::addDouble(uint32_t tag, int count, double *data) 114 { 115 if (!validate(tag, TYPE_DOUBLE, count)) return -EINVAL; 116 return add(tag, count, data); 117 } 118 119 int Metadata::addRational(uint32_t tag, int count, 120 camera_metadata_rational_t *data) 121 { 122 if (!validate(tag, TYPE_RATIONAL, count)) return -EINVAL; 123 return add(tag, count, data); 124 } 125 126 bool Metadata::validate(uint32_t tag, int tag_type, int count) 127 { 128 if (get_camera_metadata_tag_type(tag) < 0) { 129 ALOGE("%s: Invalid metadata entry tag: %d", __func__, tag); 130 return false; 131 } 132 if (tag_type < 0 || tag_type >= NUM_TYPES) { 133 ALOGE("%s: Invalid metadata entry tag type: %d", __func__, tag_type); 134 return false; 135 } 136 if (tag_type != get_camera_metadata_tag_type(tag)) { 137 ALOGE("%s: Tag %d called with incorrect type: %s(%d)", __func__, tag, 138 camera_metadata_type_names[tag_type], tag_type); 139 return false; 140 } 141 if (count < 1) { 142 ALOGE("%s: Invalid metadata entry count: %d", __func__, count); 143 return false; 144 } 145 return true; 146 } 147 148 int Metadata::add(uint32_t tag, int count, void *tag_data) 149 { 150 int tag_type = get_camera_metadata_tag_type(tag); 151 size_t type_sz = camera_metadata_type_size[tag_type]; 152 153 // Allocate array to hold new metadata 154 void *data = malloc(count * type_sz); 155 if (data == NULL) 156 return -ENOMEM; 157 memcpy(data, tag_data, count * type_sz); 158 159 pthread_mutex_lock(&mMutex); 160 mEntryCount++; 161 mDataCount += calculate_camera_metadata_entry_data_size(tag_type, count); 162 push(new Entry(tag, data, count)); 163 mDirty = true; 164 pthread_mutex_unlock(&mMutex); 165 return 0; 166 } 167 168 camera_metadata_t* Metadata::generate() 169 { 170 pthread_mutex_lock(&mMutex); 171 // Reuse if old generated metadata still valid 172 if (!mDirty && mGenerated != NULL) { 173 ALOGV("%s: Reusing generated metadata at %p", __func__, mGenerated); 174 goto out; 175 } 176 // Destroy old metadata 177 if (mGenerated != NULL) { 178 ALOGV("%s: Freeing generated metadata at %p", __func__, mGenerated); 179 free_camera_metadata(mGenerated); 180 mGenerated = NULL; 181 } 182 // Generate new metadata structure 183 ALOGV("%s: Generating new camera metadata structure, Entries:%d Data:%d", 184 __func__, mEntryCount, mDataCount); 185 mGenerated = allocate_camera_metadata(mEntryCount, mDataCount); 186 if (mGenerated == NULL) { 187 ALOGE("%s: Failed to allocate metadata (%d entries %d data)", 188 __func__, mEntryCount, mDataCount); 189 goto out; 190 } 191 // Walk list of entries adding each one to newly allocated metadata 192 for (Entry *current = mHead; current != NULL; current = current->mNext) { 193 int res = add_camera_metadata_entry(mGenerated, current->mTag, 194 current->mData, current->mCount); 195 if (res != 0) { 196 ALOGE("%s: Failed to add camera metadata: %d", __func__, res); 197 free_camera_metadata(mGenerated); 198 mGenerated = NULL; 199 goto out; 200 } 201 } 202 203 out: 204 pthread_mutex_unlock(&mMutex); 205 return mGenerated; 206 } 207 208 Metadata::Entry::Entry(uint32_t tag, void *data, int count) 209 : mNext(NULL), 210 mPrev(NULL), 211 mTag(tag), 212 mData(data), 213 mCount(count) 214 { 215 } 216 217 void Metadata::push(Entry *e) 218 { 219 if (mHead == NULL) { 220 mHead = mTail = e; 221 } else { 222 mTail->insertAfter(e); 223 mTail = e; 224 } 225 } 226 227 Metadata::Entry::~Entry() 228 { 229 if (mNext != NULL) 230 mNext->mPrev = mPrev; 231 if (mPrev != NULL) 232 mPrev->mNext = mNext; 233 } 234 235 void Metadata::Entry::insertAfter(Entry *e) 236 { 237 if (e == NULL) 238 return; 239 if (mNext != NULL) 240 mNext->mPrev = e; 241 e->mNext = mNext; 242 e->mPrev = this; 243 mNext = e; 244 } 245 246 } // namespace default_camera_hal 247