Camera metadata: Check source metadata size am: 489bbd13bf am: 90045db6e6 am: 6dc0f83407 am: e1d6665905 am: 7a854a6066 am: c5fe6aefeb am: 3fdaebe730 am: 9b1ebd3fba am: a98aeeb454 am: 852082d995 am: 451248f8cf am: ad0fcdf98e am: 76107db984
am: 620bb1bd8c

Change-Id: I774b39090ec78b021d33e722f41ac625c8d88256
diff --git a/alsa_utils/alsa_device_profile.c b/alsa_utils/alsa_device_profile.c
index 734edd7..10ab3e4 100644
--- a/alsa_utils/alsa_device_profile.c
+++ b/alsa_utils/alsa_device_profile.c
@@ -79,16 +79,16 @@
     profile_reset(profile);
 }
 
-bool profile_is_initialized(alsa_device_profile* profile)
+bool profile_is_initialized(const alsa_device_profile* profile)
 {
     return profile->card >= 0 && profile->device >= 0;
 }
 
-bool profile_is_valid(alsa_device_profile* profile) {
+bool profile_is_valid(const alsa_device_profile* profile) {
     return profile->is_valid;
 }
 
-bool profile_is_cached_for(alsa_device_profile* profile, int card, int device) {
+bool profile_is_cached_for(const alsa_device_profile* profile, int card, int device) {
     return card == profile->card && device == profile->device;
 }
 
@@ -107,7 +107,7 @@
 /*
  * Returns the system defined minimum period size based on the supplied sample rate.
  */
-unsigned profile_calc_min_period_size(alsa_device_profile* profile, unsigned sample_rate)
+unsigned profile_calc_min_period_size(const alsa_device_profile* profile, unsigned sample_rate)
 {
     ALOGV("profile_calc_min_period_size(%p, rate:%d)", profile, sample_rate);
     if (profile == NULL) {
@@ -123,7 +123,7 @@
     }
 }
 
-unsigned int profile_get_period_size(alsa_device_profile* profile, unsigned sample_rate)
+unsigned int profile_get_period_size(const alsa_device_profile* profile, unsigned sample_rate)
 {
     unsigned int period_size = profile_calc_min_period_size(profile, sample_rate);
     ALOGV("profile_get_period_size(rate:%d) = %d", sample_rate, period_size);
@@ -133,7 +133,7 @@
 /*
  * Sample Rate
  */
-unsigned profile_get_default_sample_rate(alsa_device_profile* profile)
+unsigned profile_get_default_sample_rate(const alsa_device_profile* profile)
 {
     /*
      * TODO this won't be right in general. we should store a preferred rate as we are scanning.
@@ -142,7 +142,7 @@
     return profile_is_valid(profile) ? profile->sample_rates[0] : DEFAULT_SAMPLE_RATE;
 }
 
-bool profile_is_sample_rate_valid(alsa_device_profile* profile, unsigned rate)
+bool profile_is_sample_rate_valid(const alsa_device_profile* profile, unsigned rate)
 {
     if (profile_is_valid(profile)) {
         size_t index;
@@ -161,7 +161,7 @@
 /*
  * Format
  */
-enum pcm_format profile_get_default_format(alsa_device_profile* profile)
+enum pcm_format profile_get_default_format(const alsa_device_profile* profile)
 {
     /*
      * TODO this won't be right in general. we should store a preferred format as we are scanning.
@@ -169,7 +169,7 @@
     return profile_is_valid(profile) ? profile->formats[0] : DEFAULT_SAMPLE_FORMAT;
 }
 
-bool profile_is_format_valid(alsa_device_profile* profile, enum pcm_format fmt) {
+bool profile_is_format_valid(const alsa_device_profile* profile, enum pcm_format fmt) {
     if (profile_is_valid(profile)) {
         size_t index;
         for (index = 0; profile->formats[index] != PCM_FORMAT_INVALID; index++) {
@@ -187,12 +187,12 @@
 /*
  * Channels
  */
-unsigned profile_get_default_channel_count(alsa_device_profile* profile)
+unsigned profile_get_default_channel_count(const alsa_device_profile* profile)
 {
     return profile_is_valid(profile) ? profile->channel_counts[0] : DEFAULT_CHANNEL_COUNT;
 }
 
-unsigned profile_get_closest_channel_count(alsa_device_profile* profile, unsigned count)
+unsigned profile_get_closest_channel_count(const alsa_device_profile* profile, unsigned count)
 {
     if (profile_is_valid(profile)) {
         if (count < profile->min_channel_count) {
@@ -207,7 +207,7 @@
     }
 }
 
-bool profile_is_channel_count_valid(alsa_device_profile* profile, unsigned count)
+bool profile_is_channel_count_valid(const alsa_device_profile* profile, unsigned count)
 {
     if (profile_is_initialized(profile)) {
         return count >= profile->min_channel_count && count <= profile->max_channel_count;
@@ -216,7 +216,7 @@
     }
 }
 
-static bool profile_test_sample_rate(alsa_device_profile* profile, unsigned rate)
+static bool profile_test_sample_rate(const alsa_device_profile* profile, unsigned rate)
 {
     struct pcm_config config = profile->default_config;
     config.rate = rate;
@@ -418,7 +418,7 @@
     return true;
 }
 
-char * profile_get_sample_rate_strs(alsa_device_profile* profile)
+char * profile_get_sample_rate_strs(const alsa_device_profile* profile)
 {
     /* if we assume that rate strings are about 5 characters (48000 is 5), plus ~1 for a
      * delimiter "|" this buffer has room for about 22 rate strings which seems like
@@ -451,7 +451,7 @@
     return strdup(buffer);
 }
 
-char * profile_get_format_strs(alsa_device_profile* profile)
+char * profile_get_format_strs(const alsa_device_profile* profile)
 {
     /* if we assume that format strings are about 24 characters (AUDIO_FORMAT_PCM_16_BIT is 23),
      * plus ~1 for a delimiter "|" this buffer has room for about 10 format strings which seems
@@ -482,7 +482,7 @@
     return strdup(buffer);
 }
 
-char * profile_get_channel_count_strs(alsa_device_profile* profile)
+char * profile_get_channel_count_strs(const alsa_device_profile* profile)
 {
     // FIXME implicit fixed channel count assumption here (FCC_8).
     // we use only the canonical even number channel position masks.
diff --git a/alsa_utils/alsa_device_proxy.c b/alsa_utils/alsa_device_proxy.c
index 300ed22..e64a42e 100644
--- a/alsa_utils/alsa_device_proxy.c
+++ b/alsa_utils/alsa_device_proxy.c
@@ -41,7 +41,7 @@
     3, /* PCM_FORMAT_S24_3LE */
 };
 
-int proxy_prepare(alsa_device_proxy * proxy, alsa_device_profile* profile,
+int proxy_prepare(alsa_device_proxy * proxy, const alsa_device_profile* profile,
                    struct pcm_config * config)
 {
     int ret = 0;
@@ -126,7 +126,7 @@
 
 int proxy_open(alsa_device_proxy * proxy)
 {
-    alsa_device_profile* profile = proxy->profile;
+    const alsa_device_profile* profile = proxy->profile;
     ALOGV("proxy_open(card:%d device:%d %s)", profile->card, profile->device,
           profile->direction == PCM_OUT ? "PCM_OUT" : "PCM_IN");
 
@@ -262,8 +262,8 @@
     }
 }
 
-int proxy_scan_rates(alsa_device_proxy * proxy, unsigned sample_rates[]) {
-    alsa_device_profile* profile = proxy->profile;
+int proxy_scan_rates(alsa_device_proxy * proxy, const unsigned sample_rates[]) {
+    const alsa_device_profile* profile = proxy->profile;
     if (profile->card < 0 || profile->device < 0) {
         return -EINVAL;
     }
diff --git a/alsa_utils/include/alsa_device_profile.h b/alsa_utils/include/alsa_device_profile.h
index 8307d0a..8f581d9 100644
--- a/alsa_utils/include/alsa_device_profile.h
+++ b/alsa_utils/include/alsa_device_profile.h
@@ -60,34 +60,34 @@
 } alsa_device_profile;
 
 void profile_init(alsa_device_profile* profile, int direction);
-bool profile_is_initialized(alsa_device_profile* profile);
-bool profile_is_valid(alsa_device_profile* profile);
-bool profile_is_cached_for(alsa_device_profile* profile, int card, int device);
+bool profile_is_initialized(const alsa_device_profile* profile);
+bool profile_is_valid(const alsa_device_profile* profile);
+bool profile_is_cached_for(const alsa_device_profile* profile, int card, int device);
 void profile_decache(alsa_device_profile* profile);
 
 bool profile_read_device_info(alsa_device_profile* profile);
 
 /* Audio Config Strings Methods */
-char * profile_get_sample_rate_strs(alsa_device_profile* profile);
-char * profile_get_format_strs(alsa_device_profile* profile);
-char * profile_get_channel_count_strs(alsa_device_profile* profile);
+char * profile_get_sample_rate_strs(const alsa_device_profile* profile);
+char * profile_get_format_strs(const alsa_device_profile* profile);
+char * profile_get_channel_count_strs(const alsa_device_profile* profile);
 
 /* Sample Rate Methods */
-unsigned profile_get_default_sample_rate(alsa_device_profile* profile);
-bool profile_is_sample_rate_valid(alsa_device_profile* profile, unsigned rate);
+unsigned profile_get_default_sample_rate(const alsa_device_profile* profile);
+bool profile_is_sample_rate_valid(const alsa_device_profile* profile, unsigned rate);
 
 /* Format Methods */
-enum pcm_format profile_get_default_format(alsa_device_profile* profile);
-bool profile_is_format_valid(alsa_device_profile* profile, enum pcm_format fmt);
+enum pcm_format profile_get_default_format(const alsa_device_profile* profile);
+bool profile_is_format_valid(const alsa_device_profile* profile, enum pcm_format fmt);
 
 /* Channel Methods */
-unsigned profile_get_default_channel_count(alsa_device_profile* profile);
-unsigned profile_get_closest_channel_count(alsa_device_profile* profile, unsigned count);
-bool profile_is_channel_count_valid(alsa_device_profile* profile, unsigned count);
+unsigned profile_get_default_channel_count(const alsa_device_profile* profile);
+unsigned profile_get_closest_channel_count(const alsa_device_profile* profile, unsigned count);
+bool profile_is_channel_count_valid(const alsa_device_profile* profile, unsigned count);
 
 /* Utility */
-unsigned profile_calc_min_period_size(alsa_device_profile* profile, unsigned sample_rate);
-unsigned int profile_get_period_size(alsa_device_profile* profile, unsigned sample_rate);
+unsigned profile_calc_min_period_size(const alsa_device_profile* profile, unsigned sample_rate);
+unsigned int profile_get_period_size(const alsa_device_profile* profile, unsigned sample_rate);
 
 /* Debugging */
 void profile_dump(const alsa_device_profile* profile, int fd);
diff --git a/alsa_utils/include/alsa_device_proxy.h b/alsa_utils/include/alsa_device_proxy.h
index 677bb5e..64565e1 100644
--- a/alsa_utils/include/alsa_device_proxy.h
+++ b/alsa_utils/include/alsa_device_proxy.h
@@ -22,7 +22,7 @@
 #include "alsa_device_profile.h"
 
 typedef struct {
-    alsa_device_profile* profile;
+    const alsa_device_profile* profile;
 
     struct pcm_config alsa_config;
 
@@ -34,7 +34,7 @@
 
 
 /* State */
-int proxy_prepare(alsa_device_proxy * proxy, alsa_device_profile * profile,
+int proxy_prepare(alsa_device_proxy * proxy, const alsa_device_profile * profile,
                    struct pcm_config * config);
 int proxy_open(alsa_device_proxy * proxy);
 void proxy_close(alsa_device_proxy * proxy);
@@ -54,7 +54,7 @@
  * returns the index of the first rate for which the ALSA device can be opened.
  * return negative value if none work or an error occurs.
  */
-int proxy_scan_rates(alsa_device_proxy * proxy, unsigned sample_rates[]);
+int proxy_scan_rates(alsa_device_proxy * proxy, const unsigned sample_rates[]);
 
 /* I/O */
 int proxy_write(alsa_device_proxy * proxy, const void *data, unsigned int count);
diff --git a/audio_utils/include/audio_utils/primitives.h b/audio_utils/include/audio_utils/primitives.h
index e0f952e..95eaffb 100644
--- a/audio_utils/include/audio_utils/primitives.h
+++ b/audio_utils/include/audio_utils/primitives.h
@@ -578,6 +578,78 @@
         uint32_t dst_mask, uint32_t src_mask);
 
 /**
+ * Add and clamp signed 16-bit samples.
+ *
+ *  \param dst     Destination buffer
+ *  \param src     Source buffer
+ *  \param count   Number of samples to add
+ *
+ * The destination and source buffers must either be completely separate (non-overlapping), or
+ * they must both start at the same address.  Partially overlapping buffers are not supported.
+ */
+void accumulate_i16(int16_t *dst, const int16_t *src, size_t count);
+
+/**
+ * Add and clamp unsigned 8-bit samples.
+ *
+ *  \param dst     Destination buffer
+ *  \param src     Source buffer
+ *  \param count   Number of samples to add
+ *
+ * The destination and source buffers must either be completely separate (non-overlapping), or
+ * they must both start at the same address.  Partially overlapping buffers are not supported.
+ */
+void accumulate_u8(uint8_t *dst, const uint8_t *src, size_t count);
+
+/**
+ * Add and clamp packed 24-bit Q0.23 samples.
+ *
+ *  \param dst     Destination buffer
+ *  \param src     Source buffer
+ *  \param count   Number of samples to add
+ *
+ * The destination and source buffers must either be completely separate (non-overlapping), or
+ * they must both start at the same address.  Partially overlapping buffers are not supported.
+ */
+void accumulate_p24(uint8_t *dst, const uint8_t *src, size_t count);
+
+/**
+ * Add and clamp 32-bit Q8.23 samples.
+ *
+ *  \param dst     Destination buffer
+ *  \param src     Source buffer
+ *  \param count   Number of samples to add
+ *
+ * The destination and source buffers must either be completely separate (non-overlapping), or
+ * they must both start at the same address.  Partially overlapping buffers are not supported.
+ */
+void accumulate_q8_23(int32_t *dst, const int32_t *src, size_t count);
+
+/**
+ * Add and clamp signed 32-bit Q0.31 samples.
+ *
+ *  \param dst     Destination buffer
+ *  \param src     Source buffer
+ *  \param count   Number of samples to add
+ *
+ * The destination and source buffers must either be completely separate (non-overlapping), or
+ * they must both start at the same address.  Partially overlapping buffers are not supported.
+ */
+void accumulate_i32(int32_t *dst, const int32_t *src, size_t count);
+
+/**
+ * Add float samples. Result is not clamped.
+ *
+ *  \param dst     Destination buffer
+ *  \param src     Source buffer
+ *  \param count   Number of samples to add
+ *
+ * The destination and source buffers must either be completely separate (non-overlapping), or
+ * they must both start at the same address.  Partially overlapping buffers are not supported.
+ */
+void accumulate_float(float *dst, const float *src, size_t count);
+
+/**
  * Clamp (aka hard limit or clip) a signed 32-bit sample to 16-bit range.
  */
 static inline int16_t clamp16(int32_t sample)
@@ -588,6 +660,16 @@
 }
 
 /**
+ * Clamp (aka hard limit or clip) a signed 64-bit sample to 32-bit range.
+ */
+static inline int32_t clamp32(int64_t sample)
+{
+    if ((sample>>31) ^ (sample>>63))
+        sample = 0x7fffffff ^ (sample>>63);
+    return sample;
+}
+
+/**
  * Convert a IEEE 754 single precision float [-1.0, 1.0) to int16_t [-32768, 32767]
  * with clamping.  Note the open bound at 1.0, values within 1/65536 of 1.0 map
  * to 32767 instead of 32768 (early clamping due to the smaller positive integer subrange).
diff --git a/audio_utils/primitives.c b/audio_utils/primitives.c
index f4bd645..9a4cc3b 100644
--- a/audio_utils/primitives.c
+++ b/audio_utils/primitives.c
@@ -524,3 +524,58 @@
     }
     return dst_idx;
 }
+
+void accumulate_i16(int16_t *dst, const int16_t *src, size_t count) {
+    while (count--) {
+        *dst = clamp16((int32_t)*dst + *src++);
+        ++dst;
+    }
+}
+
+void accumulate_u8(uint8_t *dst, const uint8_t *src, size_t count) {
+    int32_t sum;
+    while (count--) {
+        // 8-bit samples are centered around 0x80.
+        sum = *dst + *src++ - 0x80;
+        // Clamp to [0, 0xff].
+        *dst++ = (sum & 0x100) ? (~sum >> 9) : sum;
+    }
+}
+
+void accumulate_p24(uint8_t *dst, const uint8_t *src, size_t count) {
+    while (count--) {
+        // Unpack.
+        int32_t dst_q8_23 = 0;
+        int32_t src_q8_23 = 0;
+        memcpy_to_q8_23_from_p24(&dst_q8_23, dst, 1);
+        memcpy_to_q8_23_from_p24(&src_q8_23, src, 1);
+
+        // Accumulate and overwrite.
+        dst_q8_23 += src_q8_23;
+        memcpy_to_p24_from_q8_23(dst, &dst_q8_23, 1);
+
+        // Move on to next sample.
+        dst += 3;
+        src += 3;
+  }
+}
+
+void accumulate_q8_23(int32_t *dst, const int32_t *src, size_t count) {
+    while (count--) {
+        *dst = clamp24_from_q8_23(*dst + *src++);
+        ++dst;
+    }
+}
+
+void accumulate_i32(int32_t *dst, const int32_t *src, size_t count) {
+    while (count--) {
+        *dst = clamp32((int64_t)*dst + *src++);
+        ++dst;
+    }
+}
+
+void accumulate_float(float *dst, const float *src, size_t count) {
+    while (count--) {
+        *dst++ += *src++;
+    }
+}
diff --git a/audio_utils/tests/primitives_tests.cpp b/audio_utils/tests/primitives_tests.cpp
index 44ba6b8..fadcdf7 100644
--- a/audio_utils/tests/primitives_tests.cpp
+++ b/audio_utils/tests/primitives_tests.cpp
@@ -35,6 +35,8 @@
 static const int32_t lim16neg = -(1 << 15);
 static const int32_t lim24pos = (1 << 23) - 1;
 static const int32_t lim24neg = -(1 << 23);
+static const int64_t lim32pos = 0x000000007fffffff;
+static const int64_t lim32neg = 0xffffffff80000000;
 
 inline void testClamp8(float f)
 {
@@ -689,3 +691,161 @@
     delete[] u16expand;
     delete[] u16ary;
 }
+
+template<typename T, typename TComparison>
+void checkAddedClamped(T *out, const T *in1, const T *in2, size_t size,
+        TComparison limNeg, TComparison limPos)
+{
+    for (size_t i = 0; i < size; ++i) {
+        TComparison added = (TComparison)in1[i] + in2[i];
+        if (added <= limNeg) {
+            EXPECT_EQ(limNeg, out[i]);
+        } else if (added >= limPos) {
+            EXPECT_EQ(limPos, out[i]);
+        } else {
+            EXPECT_EQ(added, out[i]);
+        }
+    }
+}
+
+void checkAddedClampedp24(uint8_t *pary, const uint8_t *in1,
+        const uint8_t *in2, size_t size) {
+    // Convert to q8_23 for comparison.
+    int32_t *outi32ary = new int32_t[size];
+    int32_t *in1i32ary = new int32_t[size];
+    int32_t *in2i32ary = new int32_t[size];
+    memcpy_to_q8_23_from_p24(outi32ary, pary, size);
+    memcpy_to_q8_23_from_p24(in1i32ary, in1, size);
+    memcpy_to_q8_23_from_p24(in2i32ary, in2, size);
+    checkAddedClamped(
+            outi32ary, in1i32ary, in2i32ary, size, lim24neg, lim24pos);
+    delete[] in2i32ary;
+    delete[] in1i32ary;
+    delete[] outi32ary;
+}
+
+void checkAddedClampedu8(uint8_t *out, const uint8_t *in1,
+        const uint8_t *in2, size_t size) {
+    // uint8_t data is centered around 0x80, not 0, so checkAddedClamped
+    // won't work. Convert to i16 first.
+    int16_t *outi16ary = new int16_t[size];
+    int16_t *in1i16ary = new int16_t[size];
+    int16_t *in2i16ary = new int16_t[size];
+    memcpy_to_i16_from_u8(outi16ary, out, size);
+    memcpy_to_i16_from_u8(in1i16ary, in1, size);
+    memcpy_to_i16_from_u8(in2i16ary, in2, size);
+    // Only the higher order bits are used.
+    checkAddedClamped(outi16ary, in1i16ary, in2i16ary, size,
+            -0x8000, 0x7f00);
+    delete[] in2i16ary;
+    delete[] in1i16ary;
+    delete[] outi16ary;
+}
+
+TEST(audio_utils_primitives, accumulate) {
+    int16_t *i16ref = new int16_t[65536];
+    int16_t *i16add = new int16_t[65536];
+    int16_t *i16ary = new int16_t[65536];
+
+    for (size_t i = 0; i < 65536; ++i) {
+        i16ref[i] = i16ary[i] = i16add[(i+1) % 65536] = i - 32768;
+    }
+
+    // Test i16.
+    accumulate_i16(i16ary, i16add, 65536);
+    checkAddedClamped(i16ary, i16ref, i16add, 65536, lim16neg,
+            lim16pos);
+
+    // Test i32.
+    int32_t *i32ary = new int32_t[65536];
+    int32_t *i32add = new int32_t[65536];
+    int32_t *i32ref = new int32_t[65536];
+    // Convert sample data to i32 to perform accumulate function.
+    memcpy_to_i32_from_i16(i32ary, i16ref, 65536);
+    memcpy_to_i32_from_i16(i32add, i16add, 65536);
+    // Ensure the reference matches the inital output after conversion.
+    memcpy(i32ref, i32ary, 65536 * sizeof(i32ary[0]));
+    // Accumulate and check.
+    accumulate_i32(i32ary, i32add, 65536);
+    checkAddedClamped(
+            i32ary, i32ref, i32add, 65536, lim32neg, lim32pos);
+    // Cleanup
+    delete[] i32ref;
+    delete[] i32add;
+    delete[] i32ary;
+
+    // Test u8.
+    uint8_t *u8ary = new uint8_t[65536];
+    uint8_t *u8add = new uint8_t[65536];
+    uint8_t *u8ref = new uint8_t[65536];
+    // Convert sample data to u8 to perform accumulate function.
+    memcpy_to_u8_from_i16(u8ary, i16ref, 65536);
+    memcpy_to_u8_from_i16(u8add, i16add, 65536);
+    // Ensure the reference matches the inital output after conversion.
+    memcpy(u8ref, u8ary, 65536 * sizeof(u8ary[0]));
+    // Accumulate and check.
+    accumulate_u8(u8ary, u8add, 65536);
+    checkAddedClampedu8(u8ary, u8ref, u8add, 65536);
+    // Cleanup.
+    delete[] u8ref;
+    delete[] u8add;
+    delete[] u8ary;
+
+    // Test 24 bit packed.
+    uint8_t *pary = new uint8_t[65536 * 3];
+    uint8_t *padd = new uint8_t[65536 * 3];
+    uint8_t *pref = new uint8_t[65536 * 3];
+    // Convert sample data to p24 to perform accumulate function.
+    memcpy_to_p24_from_i16(pary, i16ref, 65536);
+    memcpy_to_p24_from_i16(padd, i16add, 65536);
+    // Ensure the reference matches the inital output after conversion.
+    memcpy(pref, pary, 65536 * sizeof(pary[0]) * 3);
+    // Accumulate and check.
+    accumulate_p24(pary, padd, 65536);
+    checkAddedClampedp24(pary, pref, padd, 65536);
+    // Cleanup.
+    delete[] pref;
+    delete[] padd;
+    delete[] pary;
+
+    // Test 24 bit unpacked.
+    int32_t *q8_23ary = new int32_t[65536];
+    int32_t *q8_23add = new int32_t[65536];
+    int32_t *q8_23ref = new int32_t[65536];
+    // Convert sample data to q8_23 to perform accumulate function.
+    memcpy_to_q8_23_from_i16(q8_23ary, i16ref, 65536);
+    memcpy_to_q8_23_from_i16(q8_23add, i16add, 65536);
+    // Ensure the reference matches the inital output after conversion.
+    memcpy(q8_23ref, q8_23ary, 65536 * sizeof(q8_23ary[0]));
+    // Accumulate and check.
+    accumulate_q8_23(q8_23ary, q8_23add, 65536);
+    checkAddedClamped(
+            q8_23ary, q8_23ref, q8_23add, 65536, lim24neg, lim24pos);
+    // Cleanup.
+    delete[] q8_23ref;
+    delete[] q8_23add;
+    delete[] q8_23ary;
+
+    // Test float.
+    float *fary = new float[65536];
+    float *fadd = new float[65536];
+    float *fref = new float[65536];
+    // Convert sample data to float to perform accumulate function.
+    memcpy_to_float_from_i16(fary, i16ref, 65536);
+    memcpy_to_float_from_i16(fadd, i16add, 65536);
+    // Ensure the reference matches the inital output after conversion.
+    memcpy(fref, fary, 65536 * sizeof(fary[0]));
+    // Accumulate and check. Floats aren't clamped by accumulate,
+    // but given the input is in the [-1.0, 1.0) range output should be in
+    // [-2.0, 2.0) range.
+    accumulate_float(fary, fadd, 65536);
+    checkAddedClamped(fary, fref, fadd, 65536, -2.0f, 2.0f);
+    // Cleanup.
+    delete[] fref;
+    delete[] fadd;
+    delete[] fary;
+
+    delete[] i16ary;
+    delete[] i16add;
+    delete[] i16ref;
+}
diff --git a/camera/docs/CameraMetadataEnums.mako b/camera/docs/CameraMetadataEnums.mako
index b61fcc4..8d9daac 100644
--- a/camera/docs/CameraMetadataEnums.mako
+++ b/camera/docs/CameraMetadataEnums.mako
@@ -42,6 +42,9 @@
      * @deprecated Please refer to this API documentation to find the alternatives
     % endif
      */
+    % if value.deprecated:
+    @Deprecated
+    % endif
     public static final int ${jenum_value(entry, value)} = ${enum_calculate_value_string(value)};
 
   % endfor