summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2012-05-16 10:59:11 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-05-16 10:59:11 -0700
commit70b0be3527553d848b7d79ba645eef773acff7fc (patch)
tree2c1196894ba8edb386d3b1348ec93fa830d4e515
parent54221dde289f5f593d3835f09a98fd66025a6b5e (diff)
parentf5fb8a5516876c5a48cc44b4f1c99504e0b9f245 (diff)
downloadandroid_system_media-70b0be3527553d848b7d79ba645eef773acff7fc.tar.gz
android_system_media-70b0be3527553d848b7d79ba645eef773acff7fc.tar.bz2
android_system_media-70b0be3527553d848b7d79ba645eef773acff7fc.zip
Merge "Improvements to camera metadata handling."
-rw-r--r--camera/include/system/camera_metadata.h93
-rw-r--r--camera/src/camera_metadata.c249
-rw-r--r--camera/tests/camera_metadata_tests.cpp943
3 files changed, 1028 insertions, 257 deletions
diff --git a/camera/include/system/camera_metadata.h b/camera/include/system/camera_metadata.h
index 6a11cfb3..a1d19b31 100644
--- a/camera/include/system/camera_metadata.h
+++ b/camera/include/system/camera_metadata.h
@@ -71,10 +71,32 @@ typedef struct camera_metadata_rational {
} camera_metadata_rational_t;
/**
+ * A reference to a metadata entry in a buffer.
+ *
+ * The data union pointers point to the real data in the buffer, and can be
+ * modified in-place if the count does not need to change. The count is the
+ * number of entries in data of the entry's type, not a count of bytes.
+ */
+typedef struct camera_metadata_entry {
+ size_t index;
+ uint32_t tag;
+ uint8_t type;
+ size_t count;
+ union {
+ uint8_t *u8;
+ int32_t *i32;
+ float *f;
+ int64_t *i64;
+ double *d;
+ camera_metadata_rational_t *r;
+ } data;
+} camera_metadata_entry_t;
+
+/**
* Size in bytes of each entry type
*/
ANDROID_API
-extern size_t camera_metadata_type_sizes[NUM_TYPES];
+extern size_t camera_metadata_type_size[NUM_TYPES];
/**
* Main definitions for the metadata entry and array structures
@@ -90,9 +112,9 @@ extern size_t camera_metadata_type_sizes[NUM_TYPES];
* calculate_camera_metadata_entry_data_size() provides the amount of data
* capacity that would be used up by an entry.
*
- * Entries are not sorted, and are not forced to be unique - multiple entries
- * with the same tag are allowed. The packet will not dynamically resize when
- * full.
+ * Entries are not sorted by default, and are not forced to be unique - multiple
+ * entries with the same tag are allowed. The packet will not dynamically resize
+ * when full.
*
* The packet is contiguous in memory, with size in bytes given by
* get_camera_metadata_size(). Therefore, it can be copied safely with memcpy()
@@ -241,46 +263,63 @@ int add_camera_metadata_entry(camera_metadata_t *dst,
size_t data_count);
/**
- * Sort the metadata buffer for fast searching. If already sorted, does
- * nothing. Adding or appending entries to the buffer will place the buffer back
- * into an unsorted state.
+ * Sort the metadata buffer for fast searching. If already marked as sorted,
+ * does nothing. Adding or appending entries to the buffer will place the buffer
+ * back into an unsorted state.
*/
ANDROID_API
int sort_camera_metadata(camera_metadata_t *dst);
/**
- * Get pointers to the fields for a metadata entry at position index in the
- * entry array. The data pointer points either to the entry's data.value field
- * or to the right offset in camera_metadata_t.data. Returns 0 on
- * success. Data_count is the number of entries in the data array when cast to
- * the tag's type, not a count of bytes.
+ * Get metadata entry at position index in the metadata buffer.
*
- * src and index are inputs; tag, type, data, and data_count are outputs. Any of
- * the outputs can be set to NULL to skip reading that value.
+ * src and index are inputs; the passed-in entry is updated with the details of
+ * the entry. The data pointer points to the real data in the buffer, and can be
+ * updated as long as the data count does not change.
*/
ANDROID_API
int get_camera_metadata_entry(camera_metadata_t *src,
- uint32_t index,
- uint32_t *tag,
- uint8_t *type,
- void **data,
- size_t *data_count);
+ size_t index,
+ camera_metadata_entry_t *entry);
/**
* Find an entry with given tag value. If not found, returns -ENOENT. Otherwise,
- * returns entry contents like get_camera_metadata_entry. Any of
- * the outputs can be set to NULL to skip reading that value.
+ * returns entry contents like get_camera_metadata_entry.
*
- * Note: Returns only the first entry with a given tag. To speed up searching
- * for tags, sort the metadata structure first by calling
- * sort_camera_metadata().
+ * If multiple entries with the same tag exist, does not have any guarantees on
+ * which is returned. To speed up searching for tags, sort the metadata
+ * structure first by calling sort_camera_metadata().
*/
ANDROID_API
int find_camera_metadata_entry(camera_metadata_t *src,
uint32_t tag,
- uint8_t *type,
- void **data,
- size_t *data_count);
+ camera_metadata_entry_t *entry);
+
+/**
+ * Delete an entry at given index. This is an expensive operation, since it
+ * requires repacking entries and possibly entry data. This also invalidates any
+ * existing camera_metadata_entry.data pointers to this buffer. Sorting is
+ * maintained.
+ */
+ANDROID_API
+int delete_camera_metadata_entry(camera_metadata_t *dst,
+ size_t index);
+
+/**
+ * Updates a metadata entry with new data. If the data size is changing, may
+ * need to adjust the data array, making this an O(N) operation. If the data
+ * size is the same or still fits in the entry space, this is O(1). Maintains
+ * sorting, but invalidates camera_metadata_entry instances that point to the
+ * updated entry. If a non-NULL value is passed in to entry, the entry structure
+ * is updated to match the new buffer state. Returns a non-zero value if there
+ * is no room for the new data in the buffer.
+ */
+ANDROID_API
+int update_camera_metadata_entry(camera_metadata_t *dst,
+ size_t index,
+ const void *data,
+ size_t data_count,
+ camera_metadata_entry_t *updated_entry);
/**
* Retrieve human-readable name of section the tag is in. Returns NULL if
diff --git a/camera/src/camera_metadata.c b/camera/src/camera_metadata.c
index 1991835a..a16b5b78 100644
--- a/camera/src/camera_metadata.c
+++ b/camera/src/camera_metadata.c
@@ -29,7 +29,7 @@
* array; otherwise, it can found in the parent's data array at index
* data.offset.
*/
-typedef struct camera_metadata_entry {
+typedef struct camera_metadata_buffer_entry {
uint32_t tag;
size_t count;
union {
@@ -38,7 +38,7 @@ typedef struct camera_metadata_entry {
} data;
uint8_t type;
uint8_t reserved[3];
-} __attribute__((packed)) camera_metadata_entry_t;
+} __attribute__((packed)) camera_metadata_buffer_entry_t;
/**
* A packet of metadata. This is a list of entries, each of which may point to
@@ -47,27 +47,27 @@ typedef struct camera_metadata_entry {
* It is assumed by the utility functions that the memory layout of the packet
* is as follows:
*
- * |----------------------------------------|
- * | camera_metadata_t |
- * | |
- * |----------------------------------------|
- * | reserved for future expansion |
- * |----------------------------------------|
- * | camera_metadata_entry_t #0 |
- * |----------------------------------------|
- * | .... |
- * |----------------------------------------|
- * | camera_metadata_entry_t #entry_count-1 |
- * |----------------------------------------|
- * | free space for |
- * | (entry_capacity-entry_count) entries |
- * |----------------------------------------|
- * | start of camera_metadata.data |
- * | |
- * |----------------------------------------|
- * | free space for |
- * | (data_capacity-data_count) bytes |
- * |----------------------------------------|
+ * |-----------------------------------------------|
+ * | camera_metadata_t |
+ * | |
+ * |-----------------------------------------------|
+ * | reserved for future expansion |
+ * |-----------------------------------------------|
+ * | camera_metadata_buffer_entry_t #0 |
+ * |-----------------------------------------------|
+ * | .... |
+ * |-----------------------------------------------|
+ * | camera_metadata_buffer_entry_t #entry_count-1 |
+ * |-----------------------------------------------|
+ * | free space for |
+ * | (entry_capacity-entry_count) entries |
+ * |-----------------------------------------------|
+ * | start of camera_metadata.data |
+ * | |
+ * |-----------------------------------------------|
+ * | free space for |
+ * | (data_capacity-data_count) bytes |
+ * |-----------------------------------------------|
*
* With the total length of the whole packet being camera_metadata.size bytes.
*
@@ -80,7 +80,7 @@ struct camera_metadata {
uint32_t flags;
size_t entry_count;
size_t entry_capacity;
- camera_metadata_entry_t *entries;
+ camera_metadata_buffer_entry_t *entries;
size_t data_count;
size_t data_capacity;
uint8_t *data;
@@ -116,6 +116,7 @@ char *camera_metadata_type_names[NUM_TYPES] = {
[TYPE_INT32] = "int32",
[TYPE_FLOAT] = "float",
[TYPE_INT64] = "int64",
+ [TYPE_DOUBLE] = "double",
[TYPE_RATIONAL] = "rational"
};
@@ -145,7 +146,7 @@ camera_metadata_t *place_camera_metadata(void *dst,
metadata->flags = 0;
metadata->entry_count = 0;
metadata->entry_capacity = entry_capacity;
- metadata->entries = (camera_metadata_entry_t*)(metadata + 1);
+ metadata->entries = (camera_metadata_buffer_entry_t*)(metadata + 1);
metadata->data_count = 0;
metadata->data_capacity = data_capacity;
metadata->size = memory_needed;
@@ -165,7 +166,7 @@ void free_camera_metadata(camera_metadata_t *metadata) {
size_t calculate_camera_metadata_size(size_t entry_count,
size_t data_count) {
size_t memory_needed = sizeof(camera_metadata_t);
- memory_needed += sizeof(camera_metadata_entry_t[entry_count]);
+ memory_needed += sizeof(camera_metadata_buffer_entry_t[entry_count]);
memory_needed += sizeof(uint8_t[data_count]);
return memory_needed;
}
@@ -221,7 +222,7 @@ camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
metadata->flags = src->flags;
metadata->entry_count = src->entry_count;
metadata->entry_capacity = src->entry_count;
- metadata->entries = (camera_metadata_entry_t*)
+ metadata->entries = (camera_metadata_buffer_entry_t*)
((uint8_t *)(metadata + 1) + reserved_size);
metadata->data_count = src->data_count;
metadata->data_capacity = src->data_count;
@@ -232,7 +233,7 @@ camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
memcpy(metadata->reserved, src->reserved, reserved_size);
}
memcpy(metadata->entries, src->entries,
- sizeof(camera_metadata_entry_t[metadata->entry_count]));
+ sizeof(camera_metadata_buffer_entry_t[metadata->entry_count]));
memcpy(metadata->data, src->data,
sizeof(uint8_t[metadata->data_count]));
@@ -247,7 +248,7 @@ int append_camera_metadata(camera_metadata_t *dst,
if (dst->data_capacity < src->data_count + dst->data_count) return ERROR;
memcpy(dst->entries + dst->entry_count, src->entries,
- sizeof(camera_metadata_entry_t[src->entry_count]));
+ sizeof(camera_metadata_buffer_entry_t[src->entry_count]));
memcpy(dst->data + dst->data_count, src->data,
sizeof(uint8_t[src->data_count]));
if (dst->data_count != 0) {
@@ -255,15 +256,23 @@ int append_camera_metadata(camera_metadata_t *dst,
for (i = dst->entry_count;
i < dst->entry_count + src->entry_count;
i++) {
- camera_metadata_entry_t *entry = dst->entries + i;
+ camera_metadata_buffer_entry_t *entry = dst->entries + i;
if ( camera_metadata_type_size[entry->type] * entry->count > 4 ) {
entry->data.offset += dst->data_count;
}
}
}
+ if (dst->entry_count == 0) {
+ // Appending onto empty buffer, keep sorted state
+ dst->flags |= src->flags & FLAG_SORTED;
+ } else if (src->entry_count != 0) {
+ // Both src, dst are nonempty, cannot assume sort remains
+ dst->flags &= ~FLAG_SORTED;
+ } else {
+ // Src is empty, keep dst sorted state
+ }
dst->entry_count += src->entry_count;
dst->data_count += src->data_count;
- dst->flags &= ~FLAG_SORTED;
return OK;
}
@@ -289,7 +298,7 @@ static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
size_t data_bytes =
calculate_camera_metadata_entry_data_size(type, data_count);
- camera_metadata_entry_t *entry = dst->entries + dst->entry_count;
+ camera_metadata_buffer_entry_t *entry = dst->entries + dst->entry_count;
entry->tag = tag;
entry->type = type;
entry->count = data_count;
@@ -326,8 +335,8 @@ int add_camera_metadata_entry(camera_metadata_t *dst,
}
static int compare_entry_tags(const void *p1, const void *p2) {
- uint32_t tag1 = ((camera_metadata_entry_t*)p1)->tag;
- uint32_t tag2 = ((camera_metadata_entry_t*)p2)->tag;
+ uint32_t tag1 = ((camera_metadata_buffer_entry_t*)p1)->tag;
+ uint32_t tag2 = ((camera_metadata_buffer_entry_t*)p2)->tag;
return tag1 < tag2 ? -1 :
tag1 == tag2 ? 0 :
1;
@@ -338,7 +347,7 @@ int sort_camera_metadata(camera_metadata_t *dst) {
if (dst->flags & FLAG_SORTED) return OK;
qsort(dst->entries, dst->entry_count,
- sizeof(camera_metadata_entry_t),
+ sizeof(camera_metadata_buffer_entry_t),
compare_entry_tags);
dst->flags |= FLAG_SORTED;
@@ -346,67 +355,165 @@ int sort_camera_metadata(camera_metadata_t *dst) {
}
int get_camera_metadata_entry(camera_metadata_t *src,
- uint32_t index,
- uint32_t *tag,
- uint8_t *type,
- void **data,
- size_t *data_count) {
- if (src == NULL ) return ERROR;
+ size_t index,
+ camera_metadata_entry_t *entry) {
+ if (src == NULL || entry == NULL) return ERROR;
if (index >= src->entry_count) return ERROR;
- camera_metadata_entry_t *entry = src->entries + index;
+ camera_metadata_buffer_entry_t *buffer_entry = src->entries + index;
- if (tag != NULL) *tag = entry->tag;
- if (type != NULL) *type = entry->type;
- if (data_count != NULL) *data_count = entry->count;
- if (data != NULL) {
- if (entry->count * camera_metadata_type_size[entry->type] > 4) {
- *data = src->data + entry->data.offset;
- } else {
- *data = entry->data.value;
- }
+ entry->index = index;
+ entry->tag = buffer_entry->tag;
+ entry->type = buffer_entry->type;
+ entry->count = buffer_entry->count;
+ if (buffer_entry->count *
+ camera_metadata_type_size[buffer_entry->type] > 4) {
+ entry->data.u8 = src->data + buffer_entry->data.offset;
+ } else {
+ entry->data.u8 = buffer_entry->data.value;
}
return OK;
}
int find_camera_metadata_entry(camera_metadata_t *src,
uint32_t tag,
- uint8_t *type,
- void **data,
- size_t *data_count) {
+ camera_metadata_entry_t *entry) {
if (src == NULL) return ERROR;
- camera_metadata_entry_t *entry = NULL;
+ uint32_t index;
if (src->flags & FLAG_SORTED) {
// Sorted entries, do a binary search
- camera_metadata_entry_t key;
+ camera_metadata_buffer_entry_t *search_entry = NULL;
+ camera_metadata_buffer_entry_t key;
key.tag = tag;
- entry = bsearch(&key,
+ search_entry = bsearch(&key,
src->entries,
src->entry_count,
- sizeof(camera_metadata_entry_t),
+ sizeof(camera_metadata_buffer_entry_t),
compare_entry_tags);
+ if (search_entry == NULL) return NOT_FOUND;
+ index = search_entry - src->entries;
} else {
// Not sorted, linear search
- unsigned int i;
- for (i = 0; i < src->entry_count; i++) {
- if (src->entries[i].tag == tag) {
- entry = src->entries + i;
+ for (index = 0; index < src->entry_count; index++) {
+ if (src->entries[index].tag == tag) {
break;
}
}
+ if (index == src->entry_count) return NOT_FOUND;
}
- if (entry == NULL) return NOT_FOUND;
- if (type != NULL) *type = entry->type;
- if (data_count != NULL) *data_count = entry->count;
- if (data != NULL) {
- if (entry->count * camera_metadata_type_size[entry->type] > 4) {
- *data = src->data + entry->data.offset;
- } else {
- *data = entry->data.value;
+ return get_camera_metadata_entry(src, index,
+ entry);
+}
+
+int delete_camera_metadata_entry(camera_metadata_t *dst,
+ size_t index) {
+ if (dst == NULL) return ERROR;
+ if (index >= dst->entry_count) return ERROR;
+
+ camera_metadata_buffer_entry_t *entry = dst->entries + index;
+ size_t data_bytes = calculate_camera_metadata_entry_data_size(entry->type,
+ entry->count);
+
+ if (data_bytes > 0) {
+ // Shift data buffer to overwrite deleted data
+ uint8_t *start = dst->data + entry->data.offset;
+ uint8_t *end = start + data_bytes;
+ size_t length = dst->data_count - entry->data.offset - data_bytes;
+ memmove(start, end, length);
+
+ // Update all entry indices to account for shift
+ camera_metadata_buffer_entry_t *e = dst->entries;
+ size_t i;
+ for (i = 0; i < dst->entry_count; i++) {
+ if (calculate_camera_metadata_entry_data_size(
+ e->type, e->count) > 0 &&
+ e->data.offset > entry->data.offset) {
+ e->data.offset -= data_bytes;
+ }
+ ++e;
}
+ dst->data_count -= data_bytes;
}
+ // Shift entry array
+ memmove(entry, entry + 1,
+ sizeof(camera_metadata_buffer_entry_t) *
+ (dst->entry_count - index - 1) );
+ dst->entry_count -= 1;
+
+ return OK;
+}
+
+int update_camera_metadata_entry(camera_metadata_t *dst,
+ size_t index,
+ const void *data,
+ size_t data_count,
+ camera_metadata_entry_t *updated_entry) {
+ if (dst == NULL) return ERROR;
+ if (index >= dst->entry_count) return ERROR;
+
+ camera_metadata_buffer_entry_t *entry = dst->entries + index;
+
+ size_t data_bytes =
+ calculate_camera_metadata_entry_data_size(entry->type,
+ data_count);
+ size_t entry_bytes =
+ calculate_camera_metadata_entry_data_size(entry->type,
+ entry->count);
+ if (data_bytes != entry_bytes) {
+ // May need to shift/add to data array
+ if (dst->data_capacity < dst->data_count + data_bytes - entry_bytes) {
+ // No room
+ return ERROR;
+ }
+ if (entry_bytes != 0) {
+ // Remove old data
+ uint8_t *start = dst->data + entry->data.offset;
+ uint8_t *end = start + entry_bytes;
+ size_t length = dst->data_count - entry->data.offset - entry_bytes;
+ memmove(start, end, length);
+ dst->data_count -= entry_bytes;
+
+ // Update all entry indices to account for shift
+ camera_metadata_buffer_entry_t *e = dst->entries;
+ size_t i;
+ for (i = 0; i < dst->entry_count; i++) {
+ if (calculate_camera_metadata_entry_data_size(
+ e->type, e->count) > 0 &&
+ e->data.offset > entry->data.offset) {
+ e->data.offset -= entry_bytes;
+ }
+ ++e;
+ }
+ }
+
+ if (data_bytes != 0) {
+ // Append new data
+ entry->data.offset = dst->data_count;
+
+ memcpy(dst->data + entry->data.offset, data, data_bytes);
+ dst->data_count += data_bytes;
+ }
+ } else if (data_bytes != 0) {
+ // data size unchanged, reuse same data location
+ memcpy(dst->data + entry->data.offset, data, data_bytes);
+ }
+
+ if (data_bytes == 0) {
+ // Data fits into entry
+ memcpy(entry->data.value, data,
+ data_count * camera_metadata_type_size[entry->type]);
+ }
+
+ entry->count = data_count;
+
+ if (updated_entry != NULL) {
+ get_camera_metadata_entry(dst,
+ index,
+ updated_entry);
+ }
+
return OK;
}
@@ -479,7 +586,7 @@ void dump_camera_metadata(const camera_metadata_t *metadata,
fdprintf(fd, " Version: %d, Flags: %08x\n",
metadata->version, metadata->flags);
for (i=0; i < metadata->entry_count; i++) {
- camera_metadata_entry_t *entry = metadata->entries + i;
+ camera_metadata_buffer_entry_t *entry = metadata->entries + i;
const char *tag_name, *tag_section;
tag_section = get_camera_metadata_section_name(entry->tag);
diff --git a/camera/tests/camera_metadata_tests.cpp b/camera/tests/camera_metadata_tests.cpp
index 53a4c456..6bac8db7 100644
--- a/camera/tests/camera_metadata_tests.cpp
+++ b/camera/tests/camera_metadata_tests.cpp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+#define LOG_NDEBUG 1
+#define LOG_TAG "camera_metadata_tests"
+#include "cutils/log.h"
+
#include <errno.h>
#include "gtest/gtest.h"
@@ -226,45 +230,43 @@ TEST(camera_metadata, add_get_normal) {
// Check added entries
- uint32_t tag = 0;
- uint8_t type = 0;
- int32_t *data_int32;
- int64_t *data_int64;
- float *data_float;
- size_t data_count = 0;
-
+ camera_metadata_entry entry;
result = get_camera_metadata_entry(m,
- 0, &tag, &type, (void**)&data_int64, &data_count);
+ 0, &entry);
EXPECT_EQ(OK, result);
- EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, tag);
- EXPECT_EQ(TYPE_INT64, type);
- EXPECT_EQ((size_t)1, data_count);
- EXPECT_EQ(exposure_time, *data_int64);
+ EXPECT_EQ(0, (int)entry.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, entry.tag);
+ EXPECT_EQ(TYPE_INT64, entry.type);
+ EXPECT_EQ((size_t)1, entry.count);
+ EXPECT_EQ(exposure_time, *entry.data.i64);
result = get_camera_metadata_entry(m,
- 1, &tag, &type, (void**)&data_int32, &data_count);
+ 1, &entry);
EXPECT_EQ(OK, result);
- EXPECT_EQ(ANDROID_SENSOR_SENSITIVITY, tag);
- EXPECT_EQ(TYPE_INT32, type);
- EXPECT_EQ((size_t)1, data_count);
- EXPECT_EQ(sensitivity, *data_int32);
+ EXPECT_EQ((size_t)1, entry.index);
+ EXPECT_EQ(ANDROID_SENSOR_SENSITIVITY, entry.tag);
+ EXPECT_EQ(TYPE_INT32, entry.type);
+ EXPECT_EQ((size_t)1, entry.count);
+ EXPECT_EQ(sensitivity, *entry.data.i32);
result = get_camera_metadata_entry(m,
- 2, &tag, &type, (void**)&data_float, &data_count);
+ 2, &entry);
EXPECT_EQ(OK, result);
- EXPECT_EQ(ANDROID_LENS_FOCUS_DISTANCE, tag);
- EXPECT_EQ(TYPE_FLOAT, type);
- EXPECT_EQ((size_t)1, data_count);
- EXPECT_EQ(focusDistance, *data_float);
+ EXPECT_EQ((size_t)2, entry.index);
+ EXPECT_EQ(ANDROID_LENS_FOCUS_DISTANCE, entry.tag);
+ EXPECT_EQ(TYPE_FLOAT, entry.type);
+ EXPECT_EQ((size_t)1, entry.count);
+ EXPECT_EQ(focusDistance, *entry.data.f);
result = get_camera_metadata_entry(m,
- 3, &tag, &type, (void**)&data_float, &data_count);
+ 3, &entry);
EXPECT_EQ(OK, result);
- EXPECT_EQ(ANDROID_COLOR_TRANSFORM, tag);
- EXPECT_EQ(TYPE_FLOAT, type);
- EXPECT_EQ((size_t)9, data_count);
- for (unsigned int i=0; i < data_count; i++) {
- EXPECT_EQ(colorTransform[i], data_float[i] );
+ EXPECT_EQ((size_t)3, entry.index);
+ EXPECT_EQ(ANDROID_COLOR_TRANSFORM, entry.tag);
+ EXPECT_EQ(TYPE_FLOAT, entry.type);
+ EXPECT_EQ((size_t)9, entry.count);
+ for (unsigned int i=0; i < entry.count; i++) {
+ EXPECT_EQ(colorTransform[i], entry.data.f[i] );
}
EXPECT_EQ(calculate_camera_metadata_size(entry_capacity, data_capacity),
@@ -273,7 +275,9 @@ TEST(camera_metadata, add_get_normal) {
EXPECT_EQ(calculate_camera_metadata_size(entries_used, data_used),
get_camera_metadata_compact_size(m) );
- dump_camera_metadata(m, 0, 2);
+ IF_ALOGV() {
+ dump_camera_metadata(m, 0, 2);
+ }
free_camera_metadata(m);
}
@@ -319,33 +323,33 @@ TEST(camera_metadata, add_get_toomany) {
EXPECT_EQ(ERROR, result);
- uint32_t tag = 0;
- uint8_t type = 0;
- int32_t *data_int32;
- size_t data_count = 0;
+ camera_metadata_entry entry;
for (unsigned int i=0; i < entry_capacity; i++) {
int64_t exposure_time = 100 + i * 100;
result = get_camera_metadata_entry(m,
- i, &tag, &type, (void**)&data_int32, &data_count);
+ i, &entry);
EXPECT_EQ(OK, result);
- EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, tag);
- EXPECT_EQ(TYPE_INT64, type);
- EXPECT_EQ((size_t)1, data_count);
- EXPECT_EQ(exposure_time, *data_int32);
+ EXPECT_EQ(i, entry.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, entry.tag);
+ EXPECT_EQ(TYPE_INT64, entry.type);
+ EXPECT_EQ((size_t)1, entry.count);
+ EXPECT_EQ(exposure_time, *entry.data.i64);
}
- tag = 0;
- type = 0;
- data_int32 = NULL;
- data_count = 0;
+ entry.tag = 1234;
+ entry.type = 56;
+ entry.data.u8 = NULL;
+ entry.count = 7890;
result = get_camera_metadata_entry(m,
- entry_capacity, &tag, &type, (void**)&data_int32, &data_count);
+ entry_capacity, &entry);
EXPECT_EQ(ERROR, result);
- EXPECT_EQ((uint32_t)0, tag);
- EXPECT_EQ((uint8_t)0, type);
- EXPECT_EQ((size_t)0, data_count);
- EXPECT_EQ(NULL, data_int32);
+ EXPECT_EQ((uint32_t)1234, entry.tag);
+ EXPECT_EQ((uint8_t)56, entry.type);
+ EXPECT_EQ(NULL, entry.data.u8);
+ EXPECT_EQ((size_t)7890, entry.count);
- dump_camera_metadata(m, 0, 2);
+ IF_ALOGV() {
+ dump_camera_metadata(m, 0, 2);
+ }
free_camera_metadata(m);
}
@@ -380,23 +384,20 @@ TEST(camera_metadata, copy_metadata) {
get_camera_metadata_data_count(m2));
for (unsigned int i=0; i < get_camera_metadata_entry_count(m); i++) {
- uint32_t tag, tag2;
- uint8_t type, type2;
- uint8_t *data, *data2;
- size_t data_count, data_count2;
-
+ camera_metadata_entry e1, e2;
int result;
- result = get_camera_metadata_entry(m,
- i, &tag, &type, (void**)&data, &data_count);
+ result = get_camera_metadata_entry(m, i, &e1);
EXPECT_EQ(OK, result);
- result = get_camera_metadata_entry(m2,
- i, &tag2, &type2, (void**)&data2, &data_count2);
+ result = get_camera_metadata_entry(m2, i, &e2);
EXPECT_EQ(OK, result);
- EXPECT_EQ(tag, tag2);
- EXPECT_EQ(type, type2);
- EXPECT_EQ(data_count, data_count2);
- for (unsigned int j=0; j < data_count; j++) {
- EXPECT_EQ(data[j], data2[j]);
+ EXPECT_EQ(e1.index, e2.index);
+ EXPECT_EQ(e1.tag, e2.tag);
+ EXPECT_EQ(e1.type, e2.type);
+ EXPECT_EQ(e1.count, e2.count);
+ for (unsigned int j=0;
+ j < e1.count * camera_metadata_type_size[e1.type];
+ j++) {
+ EXPECT_EQ(e1.data.u8[j], e2.data.u8[j]);
}
}
@@ -440,23 +441,22 @@ TEST(camera_metadata, copy_metadata_extraspace) {
(uint8_t*)m2 + get_camera_metadata_size(m2) );
for (unsigned int i=0; i < get_camera_metadata_entry_count(m); i++) {
- uint32_t tag, tag2;
- uint8_t type, type2;
- uint8_t *data, *data2;
- size_t data_count, data_count2;
+ camera_metadata_entry e1, e2;
int result;
- result = get_camera_metadata_entry(m,
- i, &tag, &type, (void**)&data, &data_count);
+ result = get_camera_metadata_entry(m, i, &e1);
EXPECT_EQ(OK, result);
- result = get_camera_metadata_entry(m2,
- i, &tag2, &type2, (void**)&data2, &data_count2);
+ EXPECT_EQ(i, e1.index);
+ result = get_camera_metadata_entry(m2, i, &e2);
EXPECT_EQ(OK, result);
- EXPECT_EQ(tag, tag2);
- EXPECT_EQ(type, type2);
- EXPECT_EQ(data_count, data_count2);
- for (unsigned int j=0; j < data_count; j++) {
- EXPECT_EQ(data[j], data2[j]);
+ EXPECT_EQ(e1.index, e2.index);
+ EXPECT_EQ(e1.tag, e2.tag);
+ EXPECT_EQ(e1.type, e2.type);
+ EXPECT_EQ(e1.count, e2.count);
+ for (unsigned int j=0;
+ j < e1.count * camera_metadata_type_size[e1.type];
+ j++) {
+ EXPECT_EQ(e1.data.u8[j], e2.data.u8[j]);
}
}
@@ -512,29 +512,29 @@ TEST(camera_metadata, append_metadata) {
EXPECT_EQ(OK, result);
- EXPECT_EQ(get_camera_metadata_entry_count(m), get_camera_metadata_entry_count(m2));
- EXPECT_EQ(get_camera_metadata_data_count(m), get_camera_metadata_data_count(m2));
+ EXPECT_EQ(get_camera_metadata_entry_count(m),
+ get_camera_metadata_entry_count(m2));
+ EXPECT_EQ(get_camera_metadata_data_count(m),
+ get_camera_metadata_data_count(m2));
EXPECT_EQ(entry_capacity*2, get_camera_metadata_entry_capacity(m2));
EXPECT_EQ(data_capacity*2, get_camera_metadata_data_capacity(m2));
for (unsigned int i=0; i < get_camera_metadata_entry_count(m); i++) {
- uint32_t tag, tag2;
- uint8_t type, type2;
- uint8_t *data, *data2;
- size_t data_count, data_count2;
-
+ camera_metadata_entry e1, e2;
int result;
- result = get_camera_metadata_entry(m,
- i, &tag, &type, (void**)&data, &data_count);
+ result = get_camera_metadata_entry(m, i, &e1);
EXPECT_EQ(OK, result);
- result = get_camera_metadata_entry(m2,
- i, &tag2, &type2, (void**)&data2, &data_count2);
+ EXPECT_EQ(i, e1.index);
+ result = get_camera_metadata_entry(m2, i, &e2);
EXPECT_EQ(OK, result);
- EXPECT_EQ(tag, tag2);
- EXPECT_EQ(type, type2);
- EXPECT_EQ(data_count, data_count2);
- for (unsigned int j=0; j < data_count; j++) {
- EXPECT_EQ(data[j], data2[j]);
+ EXPECT_EQ(e1.index, e2.index);
+ EXPECT_EQ(e1.tag, e2.tag);
+ EXPECT_EQ(e1.type, e2.type);
+ EXPECT_EQ(e1.count, e2.count);
+ for (unsigned int j=0;
+ j < e1.count * camera_metadata_type_size[e1.type];
+ j++) {
+ EXPECT_EQ(e1.data.u8[j], e2.data.u8[j]);
}
}
@@ -542,29 +542,32 @@ TEST(camera_metadata, append_metadata) {
EXPECT_EQ(OK, result);
- EXPECT_EQ(get_camera_metadata_entry_count(m)*2, get_camera_metadata_entry_count(m2));
- EXPECT_EQ(get_camera_metadata_data_count(m)*2, get_camera_metadata_data_count(m2));
+ EXPECT_EQ(get_camera_metadata_entry_count(m)*2,
+ get_camera_metadata_entry_count(m2));
+ EXPECT_EQ(get_camera_metadata_data_count(m)*2,
+ get_camera_metadata_data_count(m2));
EXPECT_EQ(entry_capacity*2, get_camera_metadata_entry_capacity(m2));
EXPECT_EQ(data_capacity*2, get_camera_metadata_data_capacity(m2));
for (unsigned int i=0; i < get_camera_metadata_entry_count(m2); i++) {
- uint32_t tag, tag2;
- uint8_t type, type2;
- uint8_t *data, *data2;
- size_t data_count, data_count2;
+ camera_metadata_entry e1, e2;
int result;
result = get_camera_metadata_entry(m,
- i % entry_capacity, &tag, &type, (void**)&data, &data_count);
+ i % entry_capacity, &e1);
EXPECT_EQ(OK, result);
+ EXPECT_EQ(i % entry_capacity, e1.index);
result = get_camera_metadata_entry(m2,
- i, &tag2, &type2, (void**)&data2, &data_count2);
+ i, &e2);
EXPECT_EQ(OK, result);
- EXPECT_EQ(tag, tag2);
- EXPECT_EQ(type, type2);
- EXPECT_EQ(data_count, data_count2);
- for (unsigned int j=0; j < data_count; j++) {
- EXPECT_EQ(data[j], data2[j]);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(e1.tag, e2.tag);
+ EXPECT_EQ(e1.type, e2.type);
+ EXPECT_EQ(e1.count, e2.count);
+ for (unsigned int j=0;
+ j < e1.count * camera_metadata_type_size[e1.type];
+ j++) {
+ EXPECT_EQ(e1.data.u8[j], e2.data.u8[j]);
}
}
@@ -619,29 +622,30 @@ TEST(camera_metadata, append_metadata_onespace) {
EXPECT_EQ(OK, result);
- EXPECT_EQ(get_camera_metadata_entry_count(m), get_camera_metadata_entry_count(m2));
- EXPECT_EQ(get_camera_metadata_data_count(m), get_camera_metadata_data_count(m2));
+ EXPECT_EQ(get_camera_metadata_entry_count(m),
+ get_camera_metadata_entry_count(m2));
+ EXPECT_EQ(get_camera_metadata_data_count(m),
+ get_camera_metadata_data_count(m2));
EXPECT_EQ(entry_capacity2, get_camera_metadata_entry_capacity(m2));
EXPECT_EQ(data_capacity2, get_camera_metadata_data_capacity(m2));
for (unsigned int i=0; i < get_camera_metadata_entry_count(m); i++) {
- uint32_t tag, tag2;
- uint8_t type, type2;
- uint8_t *data, *data2;
- size_t data_count, data_count2;
+ camera_metadata_entry e1, e2;
int result;
- result = get_camera_metadata_entry(m,
- i, &tag, &type, (void**)&data, &data_count);
+ result = get_camera_metadata_entry(m, i, &e1);
EXPECT_EQ(OK, result);
- result = get_camera_metadata_entry(m2,
- i, &tag2, &type2, (void**)&data2, &data_count2);
+ EXPECT_EQ(i, e1.index);
+ result = get_camera_metadata_entry(m2, i, &e2);
EXPECT_EQ(OK, result);
- EXPECT_EQ(tag, tag2);
- EXPECT_EQ(type, type2);
- EXPECT_EQ(data_count, data_count2);
- for (unsigned int j=0; j < data_count; j++) {
- EXPECT_EQ(data[j], data2[j]);
+ EXPECT_EQ(e1.index, e2.index);
+ EXPECT_EQ(e1.tag, e2.tag);
+ EXPECT_EQ(e1.type, e2.type);
+ EXPECT_EQ(e1.count, e2.count);
+ for (unsigned int j=0;
+ j < e1.count * camera_metadata_type_size[e1.type];
+ j++) {
+ EXPECT_EQ(e1.data.u8[j], e2.data.u8[j]);
}
}
@@ -655,23 +659,23 @@ TEST(camera_metadata, append_metadata_onespace) {
EXPECT_EQ(data_capacity2, get_camera_metadata_data_capacity(m2));
for (unsigned int i=0; i < get_camera_metadata_entry_count(m2); i++) {
- uint32_t tag, tag2;
- uint8_t type, type2;
- uint8_t *data, *data2;
- size_t data_count, data_count2;
+ camera_metadata_entry e1, e2;
int result;
result = get_camera_metadata_entry(m,
- i % entry_capacity, &tag, &type, (void**)&data, &data_count);
+ i % entry_capacity, &e1);
EXPECT_EQ(OK, result);
- result = get_camera_metadata_entry(m2,
- i, &tag2, &type2, (void**)&data2, &data_count2);
+ EXPECT_EQ(i % entry_capacity, e1.index);
+ result = get_camera_metadata_entry(m2, i, &e2);
EXPECT_EQ(OK, result);
- EXPECT_EQ(tag, tag2);
- EXPECT_EQ(type, type2);
- EXPECT_EQ(data_count, data_count2);
- for (unsigned int j=0; j < data_count; j++) {
- EXPECT_EQ(data[j], data2[j]);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(e1.tag, e2.tag);
+ EXPECT_EQ(e1.type, e2.type);
+ EXPECT_EQ(e1.count, e2.count);
+ for (unsigned int j=0;
+ j < e1.count * camera_metadata_type_size[e1.type];
+ j++) {
+ EXPECT_EQ(e1.data.u8[j], e2.data.u8[j]);
}
}
@@ -763,9 +767,11 @@ TEST(camera_metadata, add_all_tags) {
float *data_float = (float *)data;
int64_t *data_int64 = (int64_t *)data;
double *data_double = (double *)data;
- camera_metadata_rational_t *data_rational = (camera_metadata_rational_t *)data;
+ camera_metadata_rational_t *data_rational =
+ (camera_metadata_rational_t *)data;
- camera_metadata_t *m = allocate_camera_metadata(total_tag_count, conservative_data_space);
+ camera_metadata_t *m = allocate_camera_metadata(total_tag_count,
+ conservative_data_space);
ASSERT_NE((void*)NULL, (void*)m);
@@ -826,7 +832,9 @@ TEST(camera_metadata, add_all_tags) {
}
}
- dump_camera_metadata(m, 0, 2);
+ IF_ALOGV() {
+ dump_camera_metadata(m, 0, 2);
+ }
free_camera_metadata(m);
}
@@ -871,55 +879,672 @@ TEST(camera_metadata, sort_metadata) {
EXPECT_EQ(OK, result);
// Test unsorted find
- uint8_t type;
- float *f;
- size_t data_count;
+ camera_metadata_entry_t entry;
result = find_camera_metadata_entry(m,
ANDROID_LENS_FOCUS_DISTANCE,
- &type,
- (void**)&f,
- &data_count);
+ &entry);
EXPECT_EQ(OK, result);
- EXPECT_EQ(TYPE_FLOAT, type);
- EXPECT_EQ(1, (int)data_count);
- EXPECT_EQ(focus_distance, *f);
+ EXPECT_EQ(ANDROID_LENS_FOCUS_DISTANCE, entry.tag);
+ EXPECT_EQ((size_t)1, entry.index);
+ EXPECT_EQ(TYPE_FLOAT, entry.type);
+ EXPECT_EQ((size_t)1, entry.count);
+ EXPECT_EQ(focus_distance, *entry.data.f);
result = find_camera_metadata_entry(m,
ANDROID_NOISE_STRENGTH,
- &type,
- (void**)&f,
- &data_count);
+ &entry);
EXPECT_EQ(NOT_FOUND, result);
+ EXPECT_EQ((size_t)1, entry.index);
+ EXPECT_EQ(ANDROID_LENS_FOCUS_DISTANCE, entry.tag);
+ EXPECT_EQ(TYPE_FLOAT, entry.type);
+ EXPECT_EQ((size_t)1, entry.count);
+ EXPECT_EQ(focus_distance, *entry.data.f);
// Sort
- std::cout << "Pre-sorted metadata" << std::endl;
- dump_camera_metadata(m, 0, 2);
+ IF_ALOGV() {
+ std::cout << "Pre-sorted metadata" << std::endl;
+ dump_camera_metadata(m, 0, 2);
+ }
result = sort_camera_metadata(m);
EXPECT_EQ(OK, result);
- std::cout << "Sorted metadata" << std::endl;
- dump_camera_metadata(m, 0, 2);
+ IF_ALOGV() {
+ std::cout << "Sorted metadata" << std::endl;
+ dump_camera_metadata(m, 0, 2);
+ }
// Test sorted find
result = find_camera_metadata_entry(m,
ANDROID_LENS_FOCUS_DISTANCE,
- &type,
- (void**)&f,
- &data_count);
+ &entry);
EXPECT_EQ(OK, result);
- EXPECT_EQ(TYPE_FLOAT, type);
- EXPECT_EQ(1, (int)data_count);
- EXPECT_EQ(focus_distance, *f);
+ EXPECT_EQ((size_t)0, entry.index);
+ EXPECT_EQ(ANDROID_LENS_FOCUS_DISTANCE, entry.tag);
+ EXPECT_EQ(TYPE_FLOAT, entry.type);
+ EXPECT_EQ((size_t)1, (size_t)entry.count);
+ EXPECT_EQ(focus_distance, *entry.data.f);
result = find_camera_metadata_entry(m,
ANDROID_NOISE_STRENGTH,
- &type,
- (void**)&f,
- &data_count);
+ &entry);
EXPECT_EQ(NOT_FOUND, result);
+ EXPECT_EQ((size_t)0, entry.index);
+ EXPECT_EQ(ANDROID_LENS_FOCUS_DISTANCE, entry.tag);
+ EXPECT_EQ(TYPE_FLOAT, entry.type);
+ EXPECT_EQ((size_t)1, entry.count);
+ EXPECT_EQ(focus_distance, *entry.data.f);
free_camera_metadata(m);
}
+
+TEST(camera_metadata, delete_metadata) {
+ camera_metadata_t *m = NULL;
+ const size_t entry_capacity = 50;
+ const size_t data_capacity = 450;
+
+ int result;
+
+ m = allocate_camera_metadata(entry_capacity, data_capacity);
+
+ size_t num_entries = 5;
+ size_t data_per_entry =
+ calculate_camera_metadata_entry_data_size(TYPE_INT64, 1);
+ size_t num_data = num_entries * data_per_entry;
+
+ // Delete an entry with data
+
+ add_test_metadata(m, num_entries);
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+
+ result = delete_camera_metadata_entry(m, 1);
+ EXPECT_EQ(OK, result);
+ num_entries--;
+ num_data -= data_per_entry;
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(entry_capacity, get_camera_metadata_entry_capacity(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+ EXPECT_EQ(data_capacity, get_camera_metadata_data_capacity(m));
+
+ result = delete_camera_metadata_entry(m, 4);
+ EXPECT_EQ(ERROR, result);
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(entry_capacity, get_camera_metadata_entry_capacity(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+ EXPECT_EQ(data_capacity, get_camera_metadata_data_capacity(m));
+
+ for (size_t i = 0; i < num_entries; i++) {
+ camera_metadata_entry e;
+ result = get_camera_metadata_entry(m, i, &e);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ int64_t exposureTime = i < 1 ? 100 : 200 + 100 * i;
+ EXPECT_EQ(exposureTime, *e.data.i64);
+ }
+
+ // Delete an entry with no data, at end of array
+
+ int32_t frameCount = 12;
+ result = add_camera_metadata_entry(m,
+ ANDROID_REQUEST_FRAME_COUNT,
+ &frameCount, 1);
+ EXPECT_EQ(OK, result);
+ num_entries++;
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(entry_capacity, get_camera_metadata_entry_capacity(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+ EXPECT_EQ(data_capacity, get_camera_metadata_data_capacity(m));
+
+ camera_metadata_entry e;
+ result = get_camera_metadata_entry(m, 4, &e);
+ EXPECT_EQ(OK, result);
+
+ EXPECT_EQ((size_t)4, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(frameCount, *e.data.i32);
+
+ result = delete_camera_metadata_entry(m, 4);
+ EXPECT_EQ(OK, result);
+
+ num_entries--;
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(entry_capacity, get_camera_metadata_entry_capacity(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+ EXPECT_EQ(data_capacity, get_camera_metadata_data_capacity(m));
+
+ result = delete_camera_metadata_entry(m, 4);
+ EXPECT_EQ(ERROR, result);
+
+ result = get_camera_metadata_entry(m, 4, &e);
+ EXPECT_EQ(ERROR, result);
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(entry_capacity, get_camera_metadata_entry_capacity(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+ EXPECT_EQ(data_capacity, get_camera_metadata_data_capacity(m));
+
+ // Delete with extra data on end of array
+ result = delete_camera_metadata_entry(m, 3);
+ EXPECT_EQ(OK, result);
+ num_entries--;
+ num_data -= data_per_entry;
+
+ for (size_t i = 0; i < num_entries; i++) {
+ camera_metadata_entry e2;
+ result = get_camera_metadata_entry(m, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = i < 1 ? 100 : 200 + 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+ // Delete without extra data in front of array
+
+ frameCount = 1001;
+ result = add_camera_metadata_entry(m,
+ ANDROID_REQUEST_FRAME_COUNT,
+ &frameCount, 1);
+ EXPECT_EQ(OK, result);
+ num_entries++;
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(entry_capacity, get_camera_metadata_entry_capacity(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+ EXPECT_EQ(data_capacity, get_camera_metadata_data_capacity(m));
+
+ result = sort_camera_metadata(m);
+ EXPECT_EQ(OK, result);
+
+ result = find_camera_metadata_entry(m,
+ ANDROID_REQUEST_FRAME_COUNT, &e);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(frameCount, *e.data.i32);
+
+ result = delete_camera_metadata_entry(m, e.index);
+ EXPECT_EQ(OK, result);
+ num_entries--;
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(entry_capacity, get_camera_metadata_entry_capacity(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+ EXPECT_EQ(data_capacity, get_camera_metadata_data_capacity(m));
+
+ for (size_t i = 0; i < num_entries; i++) {
+ camera_metadata_entry e2;
+ result = get_camera_metadata_entry(m, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = i < 1 ? 100 : 200 + 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+}
+
+TEST(camera_metadata, update_metadata) {
+ camera_metadata_t *m = NULL;
+ const size_t entry_capacity = 50;
+ const size_t data_capacity = 450;
+
+ int result;
+
+ m = allocate_camera_metadata(entry_capacity, data_capacity);
+
+ size_t num_entries = 5;
+ size_t data_per_entry =
+ calculate_camera_metadata_entry_data_size(TYPE_INT64, 1);
+ size_t num_data = num_entries * data_per_entry;
+
+ add_test_metadata(m, num_entries);
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+
+ // Update with same-size data, doesn't fit in entry
+
+ int64_t newExposureTime = 1000;
+ camera_metadata_entry_t e;
+ result = update_camera_metadata_entry(m,
+ 0, &newExposureTime, 1, &e);
+ EXPECT_EQ(OK, result);
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newExposureTime, *e.data.i64);
+
+ e.count = 0;
+ result = get_camera_metadata_entry(m,
+ 0, &e);
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newExposureTime, *e.data.i64);
+
+ for (size_t i = 1; i < num_entries; i++) {
+ camera_metadata_entry e2;
+ result = get_camera_metadata_entry(m, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = 100 + 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+ // Update with larger data
+ int64_t newExposures[2] = { 5000, 6000 };
+ result = update_camera_metadata_entry(m,
+ 0, newExposures, 2, &e);
+ EXPECT_EQ(OK, result);
+ num_data += data_per_entry;
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)2, e.count);
+ EXPECT_EQ(newExposures[0], e.data.i64[0]);
+ EXPECT_EQ(newExposures[1], e.data.i64[1]);
+
+ e.count = 0;
+ result = get_camera_metadata_entry(m,
+ 0, &e);
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)2, e.count);
+ EXPECT_EQ(newExposures[0], e.data.i64[0]);
+ EXPECT_EQ(newExposures[1], e.data.i64[1]);
+
+ for (size_t i = 1; i < num_entries; i++) {
+ camera_metadata_entry e2;
+ result = get_camera_metadata_entry(m, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = 100 + 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+ // Update with smaller data
+ newExposureTime = 100;
+ result = update_camera_metadata_entry(m,
+ 0, &newExposureTime, 1, &e);
+ EXPECT_EQ(OK, result);
+
+ num_data -= data_per_entry;
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newExposureTime, *e.data.i64);
+
+ e.count = 0;
+ result = get_camera_metadata_entry(m,
+ 0, &e);
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newExposureTime, *e.data.i64);
+
+ for (size_t i = 1; i < num_entries; i++) {
+ camera_metadata_entry e2;
+ result = get_camera_metadata_entry(m, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = 100 + 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+ // Update with size fitting in entry
+
+ int32_t frameCount = 1001;
+ result = add_camera_metadata_entry(m,
+ ANDROID_REQUEST_FRAME_COUNT,
+ &frameCount, 1);
+ EXPECT_EQ(OK, result);
+ num_entries++;
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(entry_capacity, get_camera_metadata_entry_capacity(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+ EXPECT_EQ(data_capacity, get_camera_metadata_data_capacity(m));
+
+ result = sort_camera_metadata(m);
+ EXPECT_EQ(OK, result);
+
+ result = find_camera_metadata_entry(m,
+ ANDROID_REQUEST_FRAME_COUNT, &e);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(frameCount, *e.data.i32);
+
+ int32_t newFrameCount = 0x12349876;
+ result = update_camera_metadata_entry(m,
+ 0, &newFrameCount, 1, &e);
+
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ result = find_camera_metadata_entry(m,
+ ANDROID_REQUEST_FRAME_COUNT, &e);
+
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ for (size_t i = 1; i < num_entries; i++) {
+ camera_metadata_entry e2;
+ result = get_camera_metadata_entry(m, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+ // Update to bigger than entry
+
+ int32_t newFrameCounts[4] = { 0x0, 0x1, 0x10, 0x100 };
+
+ result = update_camera_metadata_entry(m,
+ 0, &newFrameCounts, 4, &e);
+
+ EXPECT_EQ(OK, result);
+
+ num_data += calculate_camera_metadata_entry_data_size(TYPE_INT32,
+ 4);
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)4, e.count);
+ EXPECT_EQ(newFrameCounts[0], e.data.i32[0]);
+ EXPECT_EQ(newFrameCounts[1], e.data.i32[1]);
+ EXPECT_EQ(newFrameCounts[2], e.data.i32[2]);
+ EXPECT_EQ(newFrameCounts[3], e.data.i32[3]);
+
+ e.count = 0;
+
+ result = find_camera_metadata_entry(m,
+ ANDROID_REQUEST_FRAME_COUNT, &e);
+
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)4, e.count);
+ EXPECT_EQ(newFrameCounts[0], e.data.i32[0]);
+ EXPECT_EQ(newFrameCounts[1], e.data.i32[1]);
+ EXPECT_EQ(newFrameCounts[2], e.data.i32[2]);
+ EXPECT_EQ(newFrameCounts[3], e.data.i32[3]);
+
+ for (size_t i = 1; i < num_entries; i++) {
+ camera_metadata_entry e2;
+ result = get_camera_metadata_entry(m, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+ // Update to smaller than entry
+ result = update_camera_metadata_entry(m,
+ 0, &newFrameCount, 1, &e);
+
+ EXPECT_EQ(OK, result);
+
+ num_data -= camera_metadata_type_size[TYPE_INT32] * 4;
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ result = find_camera_metadata_entry(m,
+ ANDROID_REQUEST_FRAME_COUNT, &e);
+
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ for (size_t i = 1; i < num_entries; i++) {
+ camera_metadata_entry_t e2;
+ result = get_camera_metadata_entry(m, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+ // Setup new buffer with no spare data space
+
+ result = update_camera_metadata_entry(m,
+ 1, newExposures, 2, &e);
+ EXPECT_EQ(OK, result);
+
+ num_data += data_per_entry;
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m));
+
+ EXPECT_EQ((size_t)1, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)2, e.count);
+ EXPECT_EQ(newExposures[0], e.data.i64[0]);
+ EXPECT_EQ(newExposures[1], e.data.i64[1]);
+
+ camera_metadata_t *m2;
+ m2 = allocate_camera_metadata(get_camera_metadata_entry_count(m),
+ get_camera_metadata_data_count(m));
+ EXPECT_NOT_NULL(m2);
+
+ result = append_camera_metadata(m2, m);
+ EXPECT_EQ(OK, result);
+
+ result = find_camera_metadata_entry(m2,
+ ANDROID_REQUEST_FRAME_COUNT, &e);
+
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ // Update when there's no more room
+
+ result = update_camera_metadata_entry(m2,
+ 0, &newFrameCounts, 4, &e);
+ EXPECT_EQ(ERROR, result);
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m2));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m2));
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ // Update when there's no data room, but change fits into entry
+
+ newFrameCount = 5;
+ result = update_camera_metadata_entry(m2,
+ 0, &newFrameCount, 1, &e);
+ EXPECT_EQ(OK, result);
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m2));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m2));
+
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ result = find_camera_metadata_entry(m2,
+ ANDROID_REQUEST_FRAME_COUNT, &e);
+
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ result = get_camera_metadata_entry(m2, 1, &e);
+ EXPECT_EQ((size_t)1, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)2, e.count);
+ EXPECT_EQ(newExposures[0], e.data.i64[0]);
+ EXPECT_EQ(newExposures[1], e.data.i64[1]);
+
+ for (size_t i = 2; i < num_entries; i++) {
+ camera_metadata_entry_t e2;
+ result = get_camera_metadata_entry(m2, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+ // Update when there's no data room, but data size doesn't change
+
+ newExposures[0] = 1000;
+
+ result = update_camera_metadata_entry(m2,
+ 1, newExposures, 2, &e);
+ EXPECT_EQ(OK, result);
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m2));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m2));
+
+ EXPECT_EQ((size_t)1, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)2, e.count);
+ EXPECT_EQ(newExposures[0], e.data.i64[0]);
+ EXPECT_EQ(newExposures[1], e.data.i64[1]);
+
+ result = find_camera_metadata_entry(m2,
+ ANDROID_REQUEST_FRAME_COUNT, &e);
+
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ for (size_t i = 2; i < num_entries; i++) {
+ camera_metadata_entry_t e2;
+ result = get_camera_metadata_entry(m2, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+ // Update when there's no data room, but data size shrinks
+
+ result = update_camera_metadata_entry(m2,
+ 1, &newExposureTime, 1, &e);
+ EXPECT_EQ(OK, result);
+
+ num_data -= calculate_camera_metadata_entry_data_size(TYPE_INT64, 2);
+ num_data += calculate_camera_metadata_entry_data_size(TYPE_INT64, 1);
+
+ EXPECT_EQ(num_entries, get_camera_metadata_entry_count(m2));
+ EXPECT_EQ(num_data, get_camera_metadata_data_count(m2));
+
+ EXPECT_EQ((size_t)1, e.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e.tag);
+ EXPECT_EQ(TYPE_INT64, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newExposureTime, e.data.i64[0]);
+
+ result = find_camera_metadata_entry(m2,
+ ANDROID_REQUEST_FRAME_COUNT, &e);
+
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ((size_t)0, e.index);
+ EXPECT_EQ(ANDROID_REQUEST_FRAME_COUNT, e.tag);
+ EXPECT_EQ(TYPE_INT32, e.type);
+ EXPECT_EQ((size_t)1, e.count);
+ EXPECT_EQ(newFrameCount, *e.data.i32);
+
+ for (size_t i = 2; i < num_entries; i++) {
+ camera_metadata_entry_t e2;
+ result = get_camera_metadata_entry(m2, i, &e2);
+ EXPECT_EQ(OK, result);
+ EXPECT_EQ(i, e2.index);
+ EXPECT_EQ(ANDROID_SENSOR_EXPOSURE_TIME, e2.tag);
+ EXPECT_EQ(TYPE_INT64, e2.type);
+ int64_t exposureTime = 100 * i;
+ EXPECT_EQ(exposureTime, *e2.data.i64);
+ }
+
+}