summaryrefslogtreecommitdiffstats
path: root/cpcam
diff options
context:
space:
mode:
Diffstat (limited to 'cpcam')
-rw-r--r--cpcam/java/com/ti/omap/android/cpcam/CPCamMetadata.java449
-rw-r--r--cpcam/java/com/ti/omap/android/cpcam/CPCamUtils.java27
-rw-r--r--cpcam/jni/Android.mk4
-rw-r--r--cpcam/jni/com_ti_omap_android_cpcam_CPCam.cpp7
-rw-r--r--cpcam/jni/com_ti_omap_android_cpcam_CPCamMetadata.cpp610
5 files changed, 1069 insertions, 28 deletions
diff --git a/cpcam/java/com/ti/omap/android/cpcam/CPCamMetadata.java b/cpcam/java/com/ti/omap/android/cpcam/CPCamMetadata.java
new file mode 100644
index 0000000..e1945e2
--- /dev/null
+++ b/cpcam/java/com/ti/omap/android/cpcam/CPCamMetadata.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.ti.omap.android.cpcam;
+
+import android.graphics.*;
+import java.nio.ByteBuffer;
+
+/**
+ * Used for passing camera related metadata
+ */
+public class CPCamMetadata {
+
+ protected CPCamMetadata() {
+ }
+
+ public static CPCamMetadata getMetadata(SurfaceTexture st) {
+ return nativeRetrieveMetadata(st);
+ }
+
+ public static class BSCPosition {
+
+ /**
+ * The number of row/column sums cannot exceed 1920, implies:
+ * - (vectors + 1) * (vertical_number) <=1920, for row sums
+ * - (vectors + 1) * (horizontal_number) <=1920, for column sums
+ */
+ BSCPosition () {
+ }
+
+ /**
+ * vectors : number of row/column sum vectors. Max value = 4
+ */
+ public int vectors;
+
+ /**
+ * shift : down-shift of input data
+ */
+ public int shift;
+
+ /**
+ * vertical_position : vertical position of first pixel to be summed
+ */
+ public int verticalPosition;
+
+ /**
+ * horizontal_position : horizontal position of first pixel to be summed
+ */
+ public int horizontalPosition;
+
+ /**
+ * vertical_number : number of pixels sampled vertically
+ */
+ public int verticalNumber;
+
+ /**
+ * horizontal_number : number of pixels sampled horizontally
+ */
+ public int horizontalNumber;
+
+ /**
+ * vertical_skip : vertical spacing between adjacent pixels to be summed
+ */
+ public int verticalSkip;
+
+ /**
+ * horizontal_skip : horizontal pixel spacing between adjacent pixels to be summed
+ */
+ public int horizontalSkip;
+ }
+
+ public static class H3AConfig {
+
+ H3AConfig () {
+ }
+
+ /**
+ * vertical_position: vertical start point of paxel grid
+ * w.r.t first pixel of input image frame
+ */
+ public int verticalPosition;
+
+ /**
+ * vertical_size: vertical paxel size
+ */
+ public int verticalSize;
+
+ /**
+ * horizontal_position: horizontal start point of paxel grid
+ * w.r.t first pixel of input image frame
+ */
+ public int horizontalPosition;
+
+ /**
+ * horizontal_size: horizontal paxel size
+ */
+ public int horizontalSize;
+
+ /**
+ * vertical_count: num of vert paxels. AF/AEWB paxels
+ * are always adjacent to each other
+ */
+ public int verticalCount;
+
+ /**
+ * vetical_increment: num of pixels to skip within a paxel, vertically
+ */
+ public int veticalIncrement;
+
+ /**
+ * horizontal_count: num of horz paxels.
+ * AF/AEWB paxels are always adjacent to each other
+ */
+ public int horizontalCount;
+
+ /**
+ * horizontal_increment: num of pixels to skip within a paxel,
+ * horizontally
+ */
+ public int horizontalIncrement;
+ }
+
+ /**
+ * Used to store the information about frame
+ * number in processing sequence (i.e preview)
+ */
+ public int frameNumber;
+
+ /**
+ * Used to store the information about shot number
+ * in a burst sequence.
+ */
+ public int shotNumber;
+
+ /**
+ * Used to store analog gain information for
+ * current frame. Metadata is represented as 100*EV.
+ */
+ public int analogGain;
+
+ /**
+ * Used for storing analog gain information
+ * requested by application for current frame. Metadata is represented as 100*EV.
+ */
+ public int analogGainReq;
+
+ /**
+ * Used for storing the analog gain
+ * lower limit for current frame. Metadata is represented as 100*EV.
+ */
+ public int analogGainMin;
+
+ /**
+ * Used for storing the analog gain
+ * upper limit for current frame. Metadata is represented as 100*EV.
+ */
+ public int analogGainMax;
+
+ /**
+ * Used for storing the analog gain
+ * deviation after flicker reduction for current frame. Metadata is represented as 100*EV.
+ */
+ public int analogGainDev;
+
+ /**
+ * Used for storing analog gain error for
+ * current frame. Represents the difference between requested value and actual value.
+ */
+ public int analogGainError;
+
+ /**
+ * Used for storing the exposure time for current frame.
+ * Metadata is represented in us.
+ */
+ public int exposureTime;
+
+ /**
+ * Used for storing the exposure time requested by
+ * application for current frame. Metadata is represented in us.
+ */
+ public int exposureTimeReq;
+
+ /**
+ * Used for storing the exposure time lower limit for
+ * current frame. Metadata is represented in us.
+ */
+ public int exposureTimeMin;
+
+ /**
+ * Used for storing the exposure time upper limit for
+ * current frame. Metadata is represented in us.
+ */
+ public int exposureTimeMax;
+
+ /**
+ * Used for storing the exposure time
+ * deviation after flicker reduction for current frame. Metadata is represented in us.
+ */
+ public int exposureTimeDev;
+
+ /**
+ * Used for storing the time difference between
+ * requested exposure time and actual exposure time.
+ */
+ public int exposureTimeError;
+
+ /**
+ * Used for storing the current total exposure
+ * compensation requested by application for current frame. Metadata is represented as 100*EV.
+ */
+ public int exposureCompensationReq;
+
+ /**
+ * Used for storing current total exposure
+ * deviation for current frame. Metadata is represented as 100*EV.
+ */
+ public int exposureDev;
+
+ /**
+ * Represents the timestamp in terms of a reference clock.
+ */
+ public long timestamp;
+
+ /**
+ * Represents the temperature of current scene in Kelvin
+ */
+ public int awbTemp;
+
+ /**
+ * Represent gains applied to each RGGB color channel.
+ */
+ public int gainR;
+ public int gainGR;
+ public int gainGB;
+ public int gainB;
+
+ /**
+ * Represent offsets applied to each RGGB color channel.
+ */
+ public int offsetR;
+ public int offsetGR;
+ public int offsetGB;
+ public int offsetB;
+
+ /**
+ * Used to store the current
+ * lens shading correction table. The table consists of an
+ * N by M array of elements. Each element has 4 integer values
+ * ranging from 0 to 1000, corresponding to a multiplier for
+ * each of the Bayer color filter channels (R, Gr, Gb, B).
+ * Correction is performed on pixels in a Bayer image by interpolating
+ * the corresponding color filter channel in the array, and then
+ * multiplying by (value/1000).
+ */
+ public ByteBuffer lscTable;
+
+ /**
+ * Indicates whether LSC table is applied or not
+ */
+ public int lscTableApplied;
+
+ /**
+ * An array of the detected faces. The length is numberOfFaces.
+ * The Face rectangles have to following layout:
+ * int top - Top coordinate of the face rectangle,
+ * int left - Left coordinate of the face rectangle,
+ * int bottom - Bottom coordinate of the face rectangle.
+ * int right - Right coordnate of the face rectangle.
+ */
+ public ByteBuffer faces;
+
+ public int numberOfFaces;
+
+ /**
+ * Width of the auxiliary image
+ */
+ public int auxImageWidth;
+
+ /**
+ * Height of the auxiliary image
+ */
+ public int auxImageHeight;
+
+ /**
+ * Auxiliary image buffer NV12 pixelformat
+ */
+ public ByteBuffer auxImage;
+
+ /**
+ * Element to be summed
+ * Y = 0,
+ * Cb = 1,
+ * Cr = 2,
+ */
+ public int bscColorElement;
+
+ /**
+ * BSC row sum descriptor
+ */
+ BSCPosition bscRowPosition;
+
+ /**
+ * BSC column sum descriptor
+ */
+ BSCPosition bscColPosition;
+
+ /**
+ * Each value corresponds to sum value in a row.
+ * Num of row sums = row_position.vectors * row_position.vertical_number
+ */
+ public ByteBuffer bscRowSum;
+
+ /**
+ * Each value corresponds to sum value in a row.
+ * Num of row sums = row_position.vectors * row_position.vertical_number
+ */
+ public ByteBuffer bscColSum;
+
+ /**
+ * When Vertical focus is disabled, R,G,B location w.r.t.
+ * to paxel start location is specified by this field.
+ * AF_RGBPOSITION_BAYER_GR_GB = 0
+ * AF_RGBPOSITION_BAYER_RG_GB = 1
+ * AF_RGBPOSITION_BAYER_GR_BG = 2
+ * AF_RGBPOSITION_BAYER_RG_BG = 3
+ * AF_RGBPOSITION_CUSTOM_GG_RB = 4
+ * AF_RGBPOSITION_CUSTOM_RB_GG = 5
+ */
+ public int afBayeRGBPosition;
+
+ /**
+ * If enabled, peak for FV, FV^2 is computed for a paxel.
+ * If disabled, average of FV, FV^2 is computed for a paxel.
+ */
+ public int afEnableAFPeakMode;
+
+ /**
+ * Whether vertical focus is enabled.
+ */
+ public int afEnableAFVertical;
+
+ /**
+ * AF paxel description
+ */
+ public H3AConfig afPaxelWindow;
+
+ /**
+ * Output AF buffer. Data is ordered in paxels:
+ *
+ * g_paxel - Paxel information for green color
+ * rb_paxel - Paxel information for red/blue color
+ * br_paxel - Paxel information for blue/red color
+ *
+ * Each paxel consists of :
+ * int sum - Sum of the pixels used to arrive at
+ * the statistics for a paxel
+ * int focus_value_sum - Focus Value (sum/peak)
+ * for a paxel
+ * int focus_value_sqr_sum - Focus Value Squared
+ * (sum/peak) for a paxel
+ * int reserved - To be ignored
+ * ------------------------------------
+ * | G paxel |
+ * | ------ ------ ------ ------ |
+ * || | | | | | | | |
+ * || sum | |f_sum | |f_sum | | rsv | |
+ * || | | | |sqr | | | |
+ * | ------ ------ ------ ------ |
+ * ------------------------------------
+ *
+ * ------------------------------------
+ * | RB paxel |
+ * | ------ ------ ------ ------ |
+ * || | | | | | | | |
+ * || sum | |f_sum | |f_sum | | rsv | |
+ * || | | | |sqr | | | |
+ * | ------ ------ ------ ------ |
+ * ------------------------------------
+ *
+ * ------------------------------------
+ * | BR paxel |
+ * | ------ ------ ------ ------ |
+ * || | | | | | | | |
+ * || sum | |f_sum | |f_sum | | rsv | |
+ * || | | | |sqr | | | |
+ * | ------ ------ ------ ------ |
+ * ------------------------------------
+ */
+ public ByteBuffer afPaxelStatistics;
+
+ /**
+ * AEWB mode :
+ * AEWB_MODE_SUM_OF_SQUARE = 0 - Sum of square calculated
+ * across sub-samples in a paxel.
+ * AEWB_MODE_MINMAX = 1 - Min-max calculted across sub-samples
+ * in a paxel.
+ * AEWB_MODE_SUM_ONLY = 2 - Only Sum calculated across sub-samples
+ * in a paxel.
+ */
+ public int aewbMode;
+
+ /**
+ * Threshold against which pixel values are compared
+ */
+ public int aewbThresholdPixelValue;
+
+ /**
+ * Right shift value applied on result of pixel accumulation
+ */
+ public int aewbAccumulationShift;
+
+ /**
+ * AE/AWB paxel description
+ */
+ public H3AConfig aewbPaxelWindow;
+
+ /**
+ * Output AE/AWB buffer, containing:
+ * subsampled_acc_values[4] - Sub sample accumulator(s), not-clipped.
+ * Separate for each pixel in 2x2 sub-sample.
+ * saturator_acc_values[4] - Saturator accumulator(s), clipped based upon threshold.
+ * Separate for each pixel in 2x2 sub-sample.
+ * nUnsaturatedCount[2] - Count of unsaturated 2x2 sub-samples in a paxel.
+ * (LS 16-bits stored in [0], MS stored in [1])
+ */
+ public ByteBuffer aewbPaxelStatistics;
+
+ private static native CPCamMetadata nativeRetrieveMetadata(SurfaceTexture st);
+
+ /*
+ * We use a class initializer to allow the native code to cache some
+ * field offsets.
+ */
+ private static native void nativeClassInit();
+ static { nativeClassInit(); }
+}
diff --git a/cpcam/java/com/ti/omap/android/cpcam/CPCamUtils.java b/cpcam/java/com/ti/omap/android/cpcam/CPCamUtils.java
deleted file mode 100644
index f7e5023..0000000
--- a/cpcam/java/com/ti/omap/android/cpcam/CPCamUtils.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.ti.omap.android.cpcam;
-
-import android.graphics.SurfaceTexture;
-
-public class CPCamUtils {
-
- public static String getMetadata(SurfaceTexture st) {
- return st.getMetadata();
- }
-
-}
diff --git a/cpcam/jni/Android.mk b/cpcam/jni/Android.mk
index d0a9b99..3ca6e01 100644
--- a/cpcam/jni/Android.mk
+++ b/cpcam/jni/Android.mk
@@ -42,7 +42,8 @@ LOCAL_MODULE:= libcpcam_jni
# All of the source files that we will compile.
LOCAL_SRC_FILES:= \
- com_ti_omap_android_cpcam_CPCam.cpp
+ com_ti_omap_android_cpcam_CPCam.cpp \
+ com_ti_omap_android_cpcam_CPCamMetadata.cpp
# All of the shared libraries we link against.
LOCAL_SHARED_LIBRARIES := \
@@ -52,6 +53,7 @@ LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libui \
+ libbinder \
libgui
# No static libraries.
diff --git a/cpcam/jni/com_ti_omap_android_cpcam_CPCam.cpp b/cpcam/jni/com_ti_omap_android_cpcam_CPCam.cpp
index d3a2f71..240e55e 100644
--- a/cpcam/jni/com_ti_omap_android_cpcam_CPCam.cpp
+++ b/cpcam/jni/com_ti_omap_android_cpcam_CPCam.cpp
@@ -59,6 +59,8 @@
using namespace android;
+extern int register_com_ti_omap_android_cpcam_CPCamMetadata(JNIEnv* env);
+
struct fields_t {
jfieldID context;
jfieldID surface;
@@ -1142,6 +1144,11 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
goto bail;
}
+ if ( register_com_ti_omap_android_cpcam_CPCamMetadata(env) != 0 ) {
+ LOGE("ERROR: PlatformLibrary native Metadata registration failed\n");
+ goto bail;
+ }
+
/* success -- return valid version number */
result = JNI_VERSION_1_4;
diff --git a/cpcam/jni/com_ti_omap_android_cpcam_CPCamMetadata.cpp b/cpcam/jni/com_ti_omap_android_cpcam_CPCamMetadata.cpp
new file mode 100644
index 0000000..fac2df8
--- /dev/null
+++ b/cpcam/jni/com_ti_omap_android_cpcam_CPCamMetadata.cpp
@@ -0,0 +1,610 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include "android_runtime/AndroidRuntime.h"
+
+#include <gui/SurfaceTexture.h>
+
+#include <binder/IMemory.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+
+using namespace android;
+
+const char* const kMetadataClassPathName = "com/ti/omap/android/cpcam/CPCamMetadata";
+
+struct fields_t {
+ jmethodID metadataInit;
+ jmethodID rectInit;
+ jmethodID bscPositionInit;
+ jmethodID h3aInit;
+ jfieldID frameNumber;
+ jfieldID shotNumber;
+ jfieldID analogGain;
+ jfieldID analogGainReq;
+ jfieldID analogGainMin;
+ jfieldID analogGainMax;
+ jfieldID analogGainDev;
+ jfieldID analogGainError;
+ jfieldID exposureTime;
+ jfieldID exposureTimeReq;
+ jfieldID exposureTimeMin;
+ jfieldID exposureTimeMax;
+ jfieldID exposureTimeDev;
+ jfieldID exposureTimeError;
+ jfieldID exposureCompensationReq;
+ jfieldID exposureDev;
+ jfieldID timestamp;
+ jfieldID awbTemp;
+ jfieldID gainR;
+ jfieldID gainGR;
+ jfieldID gainGB;
+ jfieldID gainB;
+ jfieldID offsetR;
+ jfieldID offsetGR;
+ jfieldID offsetGB;
+ jfieldID offsetB;
+ jfieldID lscTableApplied;
+ jfieldID faces;
+ jfieldID numberOfFaces;
+ jfieldID auxImageWidth;
+ jfieldID auxImageHeight;
+ jfieldID bscColorElement;
+ jfieldID bscRowPosition;
+ jfieldID bscColPosition;
+ jfieldID afBayeRGBPosition;
+ jfieldID afEnableAFPeakMode;
+ jfieldID afEnableAFVertical;
+ jfieldID afPaxelWindow;
+ jfieldID aewbMode;
+ jfieldID aewbThresholdPixelValue;
+ jfieldID aewbPaxelWindow;
+ jfieldID aewbAccumulationShift;
+ jfieldID lscTable;
+ jfieldID auxImage;
+ jfieldID bscRowSum;
+ jfieldID bscColSum;
+ jfieldID afPaxelStatistics;
+ jfieldID aewbPaxelStatistics;
+ jfieldID bscPositionVectors;
+ jfieldID bscPositionShift;
+ jfieldID bscPositionVerticalPosition;
+ jfieldID bscPositionHorizontalPosition;
+ jfieldID bscPositionVerticalNumber;
+ jfieldID bscPositionHorizontalNumber;
+ jfieldID bscPositionVerticalSkip;
+ jfieldID bscPositionHorizontalSkip;
+ jfieldID h3aVerticalPosition;
+ jfieldID h3aVerticalSize;
+ jfieldID h3aHorizontalPosition;
+ jfieldID h3aHorizontalSize;
+ jfieldID h3aVerticalCount;
+ jfieldID h3aVeticalIncrement;
+ jfieldID h3aHorizontalCount;
+ jfieldID h3aHorizontalIncrement;
+
+};
+
+static fields_t fields;
+
+static void Metadata_Init(JNIEnv* env, jclass clazz)
+{
+
+ jclass metaDataClazz = env->FindClass("com/ti/omap/android/cpcam/CPCamMetadata");
+ if ( NULL == metaDataClazz ) {
+ LOGE("Couldn't find CPCamMetadata class");
+ }
+
+ fields.metadataInit = env->GetMethodID(metaDataClazz, "<init>", "()V");
+ if ( NULL == fields.metadataInit ) {
+ LOGE("Couldn't find Metadata constructor");
+ }
+
+ jclass rectClazz = env->FindClass("android/graphics/Rect");
+ if ( NULL == rectClazz ) {
+ LOGE("Couldn't find Rect class");
+ }
+
+ fields.rectInit = env->GetMethodID(rectClazz, "<init>", "(IIII)V");
+ if ( NULL == fields.rectInit ) {
+ LOGE("Couldn't find Rect constructor");
+ }
+
+ fields.frameNumber = env->GetFieldID(metaDataClazz, "frameNumber", "I");
+ if ( NULL == fields.frameNumber ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.shotNumber = env->GetFieldID(metaDataClazz, "shotNumber", "I");
+ if ( NULL == fields.shotNumber ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.analogGain = env->GetFieldID(metaDataClazz, "analogGain", "I");
+ if ( NULL == fields.analogGain ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.analogGainReq = env->GetFieldID(metaDataClazz, "analogGainReq", "I");
+ if ( NULL == fields.analogGainReq ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.analogGainMin = env->GetFieldID(metaDataClazz, "analogGainMin", "I");
+ if ( NULL == fields.analogGainMin ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.analogGainMax = env->GetFieldID(metaDataClazz, "analogGainMax", "I");
+ if ( NULL == fields.analogGainMax ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.analogGainDev = env->GetFieldID(metaDataClazz, "analogGainDev", "I");
+ if ( NULL == fields.analogGainDev ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.analogGainError = env->GetFieldID(metaDataClazz, "analogGainError", "I");
+ if ( NULL == fields.analogGainError ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.exposureTime = env->GetFieldID(metaDataClazz, "exposureTime", "I");
+ if ( NULL == fields.exposureTime ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.exposureTimeReq = env->GetFieldID(metaDataClazz, "exposureTimeReq", "I");
+ if ( NULL == fields.exposureTimeReq ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.exposureTimeMin = env->GetFieldID(metaDataClazz, "exposureTimeMin", "I");
+ if ( NULL == fields.exposureTimeMin ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.exposureTimeMax = env->GetFieldID(metaDataClazz, "exposureTimeMax", "I");
+ if ( NULL == fields.exposureTimeMax ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.exposureTimeDev = env->GetFieldID(metaDataClazz, "exposureTimeDev", "I");
+ if ( NULL == fields.exposureTimeDev ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.exposureTimeError = env->GetFieldID(metaDataClazz, "exposureTimeError", "I");
+ if ( NULL == fields.exposureTimeError ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.exposureCompensationReq = env->GetFieldID(metaDataClazz, "exposureCompensationReq", "I");
+ if ( NULL == fields.exposureCompensationReq ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.exposureDev = env->GetFieldID(metaDataClazz, "exposureDev", "I");
+ if ( NULL == fields.exposureDev ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.timestamp = env->GetFieldID(metaDataClazz, "timestamp", "J");
+ if ( NULL == fields.timestamp ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.awbTemp = env->GetFieldID(metaDataClazz, "awbTemp", "I");
+ if ( NULL == fields.awbTemp ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.gainR = env->GetFieldID(metaDataClazz, "gainR", "I");
+ if ( NULL == fields.gainR ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.gainGR = env->GetFieldID(metaDataClazz, "gainGR", "I");
+ if ( NULL == fields.gainGR ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.gainGB = env->GetFieldID(metaDataClazz, "gainGB", "I");
+ if ( NULL == fields.gainGB ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.gainB = env->GetFieldID(metaDataClazz, "gainB", "I");
+ if ( NULL == fields.gainB ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.offsetR = env->GetFieldID(metaDataClazz, "offsetR", "I");
+ if ( NULL == fields.offsetR ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.offsetGR = env->GetFieldID(metaDataClazz, "offsetGR", "I");
+ if ( NULL == fields.offsetGR ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.offsetGB = env->GetFieldID(metaDataClazz, "offsetGB", "I");
+ if ( NULL == fields.offsetGB ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.offsetB = env->GetFieldID(metaDataClazz, "offsetB", "I");
+ if ( NULL == fields.offsetB ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.lscTableApplied = env->GetFieldID(metaDataClazz, "lscTableApplied", "I");
+ if ( NULL == fields.lscTableApplied ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.faces = env->GetFieldID(metaDataClazz, "faces", "Ljava/nio/ByteBuffer;");
+ if ( NULL == fields.faces ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.numberOfFaces = env->GetFieldID(metaDataClazz, "numberOfFaces", "I");
+ if ( NULL == fields.numberOfFaces ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.auxImageWidth = env->GetFieldID(metaDataClazz, "auxImageWidth", "I");
+ if ( NULL == fields.auxImageWidth ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.auxImageHeight = env->GetFieldID(metaDataClazz, "auxImageHeight", "I");
+ if ( NULL == fields.auxImageHeight ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.bscColorElement = env->GetFieldID(metaDataClazz, "bscColorElement", "I");
+ if ( NULL == fields.bscColorElement ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ jclass bscPositionClazz = env->FindClass("com/ti/omap/android/cpcam/CPCamMetadata$BSCPosition");
+ if ( NULL == bscPositionClazz ) {
+ LOGE("Couldn't find BSCPosition class");
+ }
+
+ fields.bscPositionInit = env->GetMethodID(bscPositionClazz, "<init>", "()V");
+ if ( NULL == fields.bscPositionInit ) {
+ LOGE("Couldn't find BSCPosition constructor");
+ }
+
+ fields.bscPositionVectors = env->GetFieldID(bscPositionClazz, "vectors", "I");
+ if ( NULL == fields.bscPositionVectors ) {
+ LOGE("Couldn't allocate BSCPosition field");
+ }
+
+ fields.bscPositionShift = env->GetFieldID(bscPositionClazz, "shift", "I");
+ if ( NULL == fields.bscPositionShift ) {
+ LOGE("Couldn't allocate BSCPosition field");
+ }
+
+ fields.bscPositionVerticalPosition = env->GetFieldID(bscPositionClazz,
+ "verticalPosition",
+ "I");
+ if ( NULL == fields.bscPositionVerticalPosition ) {
+ LOGE("Couldn't allocate BSCPosition field");
+ }
+
+ fields.bscPositionHorizontalPosition = env->GetFieldID(bscPositionClazz,
+ "horizontalPosition",
+ "I");
+ if ( NULL == fields.bscPositionHorizontalPosition ) {
+ LOGE("Couldn't allocate BSCPosition field");
+ }
+
+ fields.bscPositionVerticalNumber = env->GetFieldID(bscPositionClazz,
+ "verticalNumber",
+ "I");
+ if ( NULL == fields.bscPositionVerticalNumber ) {
+ LOGE("Couldn't allocate BSCPosition field");
+ }
+
+ fields.bscPositionHorizontalNumber = env->GetFieldID(bscPositionClazz,
+ "horizontalNumber",
+ "I");
+ if ( NULL == fields.bscPositionHorizontalNumber ) {
+ LOGE("Couldn't allocate BSCPosition field");
+ }
+
+ fields.bscPositionVerticalSkip = env->GetFieldID(bscPositionClazz,
+ "verticalSkip",
+ "I");
+ if ( NULL == fields.bscPositionVerticalSkip ) {
+ LOGE("Couldn't allocate BSCPosition field");
+ }
+
+ fields.bscPositionHorizontalSkip = env->GetFieldID(bscPositionClazz,
+ "horizontalSkip",
+ "I");
+ if ( NULL == fields.bscPositionHorizontalSkip ) {
+ LOGE("Couldn't allocate BSCPosition field");
+ }
+
+ fields.bscRowPosition = env->GetFieldID(metaDataClazz,
+ "bscRowPosition",
+ "Lcom/ti/omap/android/cpcam/CPCamMetadata$BSCPosition;");
+ if ( NULL == fields.bscRowPosition ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.bscColPosition = env->GetFieldID(metaDataClazz,
+ "bscColPosition",
+ "Lcom/ti/omap/android/cpcam/CPCamMetadata$BSCPosition;");
+ if ( NULL == fields.bscColPosition ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.afBayeRGBPosition = env->GetFieldID(metaDataClazz, "afBayeRGBPosition", "I");
+ if ( NULL == fields.afBayeRGBPosition ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.afEnableAFPeakMode = env->GetFieldID(metaDataClazz, "afEnableAFPeakMode", "I");
+ if ( NULL == fields.afEnableAFPeakMode ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.afEnableAFVertical = env->GetFieldID(metaDataClazz, "afEnableAFVertical", "I");
+ if ( NULL == fields.afEnableAFVertical ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.afPaxelWindow = env->GetFieldID(metaDataClazz,
+ "afPaxelWindow",
+ "Lcom/ti/omap/android/cpcam/CPCamMetadata$H3AConfig;");
+ if ( NULL == fields.afPaxelWindow ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ jclass h3aConfigClazz = env->FindClass("com/ti/omap/android/cpcam/CPCamMetadata$H3AConfig");
+ if ( NULL == h3aConfigClazz ) {
+ LOGE("Couldn't find H3AConfig class");
+ }
+
+ fields.h3aVerticalPosition = env->GetFieldID(h3aConfigClazz, "verticalPosition", "I");
+ if ( NULL == fields.h3aVerticalPosition ) {
+ LOGE("Couldn't allocate H3AConfig field");
+ }
+
+ fields.h3aVerticalSize = env->GetFieldID(h3aConfigClazz, "verticalSize", "I");
+ if ( NULL == fields.h3aVerticalSize ) {
+ LOGE("Couldn't allocate H3AConfig field");
+ }
+
+ fields.h3aHorizontalPosition = env->GetFieldID(h3aConfigClazz, "horizontalPosition", "I");
+ if ( NULL == fields.h3aHorizontalPosition ) {
+ LOGE("Couldn't allocate H3AConfig field");
+ }
+
+ fields.h3aHorizontalSize = env->GetFieldID(h3aConfigClazz, "horizontalSize", "I");
+ if ( NULL == fields.h3aHorizontalSize ) {
+ LOGE("Couldn't allocate H3AConfig field");
+ }
+
+ fields.h3aVerticalCount = env->GetFieldID(h3aConfigClazz, "verticalCount", "I");
+ if ( NULL == fields.h3aVerticalCount ) {
+ LOGE("Couldn't allocate H3AConfig field");
+ }
+
+ fields.h3aVeticalIncrement = env->GetFieldID(h3aConfigClazz, "veticalIncrement", "I");
+ if ( NULL == fields.h3aVeticalIncrement ) {
+ LOGE("Couldn't allocate H3AConfig field");
+ }
+
+ fields.h3aHorizontalCount = env->GetFieldID(h3aConfigClazz, "horizontalCount", "I");
+ if ( NULL == fields.h3aHorizontalCount ) {
+ LOGE("Couldn't allocate H3AConfig field");
+ }
+
+ fields.h3aHorizontalIncrement = env->GetFieldID(h3aConfigClazz, "horizontalIncrement", "I");
+ if ( NULL == fields.h3aHorizontalIncrement ) {
+ LOGE("Couldn't allocate H3AConfig field");
+ }
+
+ fields.h3aInit = env->GetMethodID(h3aConfigClazz, "<init>", "()V");
+ if ( NULL == fields.h3aInit ) {
+ LOGE("Couldn't find H3AConfig constructor");
+ }
+
+ fields.aewbMode = env->GetFieldID(metaDataClazz, "aewbMode", "I");
+ if ( NULL == fields.aewbMode ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.aewbThresholdPixelValue = env->GetFieldID(metaDataClazz, "aewbThresholdPixelValue", "I");
+ if ( NULL == fields.aewbThresholdPixelValue ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.aewbAccumulationShift = env->GetFieldID(metaDataClazz, "aewbAccumulationShift", "I");
+ if ( NULL == fields.aewbAccumulationShift ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.aewbPaxelWindow = env->GetFieldID(metaDataClazz,
+ "aewbPaxelWindow",
+ "Lcom/ti/omap/android/cpcam/CPCamMetadata$H3AConfig;");
+ if ( NULL == fields.aewbPaxelWindow ) {
+ LOGE("Couldn't allocate Metadata field");
+ }
+
+ fields.lscTable = env->GetFieldID(metaDataClazz, "lscTable", "Ljava/nio/ByteBuffer;");
+ if ( NULL == fields.lscTable ) {
+ LOGE("Couldn't find Metadata field");
+ }
+
+ fields.auxImage = env->GetFieldID(metaDataClazz, "auxImage", "Ljava/nio/ByteBuffer;");
+ if ( NULL == fields.auxImage ) {
+ LOGE("Couldn't find Metadata field");
+ }
+
+ fields.bscRowSum = env->GetFieldID(metaDataClazz, "bscRowSum", "Ljava/nio/ByteBuffer;");
+ if ( NULL == fields.bscRowSum ) {
+ LOGE("Couldn't find Metadata field");
+ }
+
+ fields.bscColSum = env->GetFieldID(metaDataClazz, "bscColSum", "Ljava/nio/ByteBuffer;");
+ if ( NULL == fields.bscColSum ) {
+ LOGE("Couldn't find Metadata field");
+ }
+
+ fields.afPaxelStatistics = env->GetFieldID(metaDataClazz,
+ "afPaxelStatistics",
+ "Ljava/nio/ByteBuffer;");
+ if ( NULL == fields.afPaxelStatistics ) {
+ LOGE("Couldn't find Metadata field");
+ }
+
+ fields.aewbPaxelStatistics = env->GetFieldID(metaDataClazz,
+ "aewbPaxelStatistics",
+ "Ljava/nio/ByteBuffer;");
+ if ( NULL == fields.aewbPaxelStatistics ) {
+ LOGE("Couldn't find Metadata field");
+ }
+
+}
+
+static jobject Metadata_retrieveMetadata(JNIEnv* env, jclass clazz, jobject st)
+{
+
+ jclass stClazz = env->FindClass("android/graphics/SurfaceTexture");
+ if (stClazz == NULL) {
+ return NULL;
+ }
+
+ jfieldID context = env->GetFieldID(stClazz,
+ ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID,
+ "I");
+ if ( context == NULL ) {
+ return NULL;
+ }
+
+ sp<SurfaceTexture> surfaceTexture = NULL;
+ if ( st != NULL ) {
+ surfaceTexture = reinterpret_cast<SurfaceTexture*>(env->GetIntField(st, context));
+ }
+
+ sp<IMemory> data = surfaceTexture->getMetadata();
+ ssize_t offset;
+ size_t size;
+
+ if ( NULL == data.get() ) {
+ return NULL;
+ }
+
+ sp<IMemoryHeap> heap = data->getMemory(&offset, &size);
+ camera_metadata_t * meta = static_cast<camera_metadata_t *> (heap->base());
+
+ jclass h3aConfigClazz = env->FindClass("com/ti/omap/android/cpcam/CPCamMetadata$H3AConfig");
+ if ( NULL == h3aConfigClazz ) {
+ LOGE("Couldn't find H3AConfig class");
+ return NULL;
+ }
+
+ jclass metaDataClazz = env->FindClass(kMetadataClassPathName);
+ if ( NULL == metaDataClazz ) {
+ LOGE("Couldn't find Metadata class");
+ return NULL;
+ }
+
+ jobject objMeta = (jobject) env->NewObject(metaDataClazz,
+ fields.metadataInit);
+ if ( NULL == objMeta ) {
+ LOGE("Couldn't allocate Metadata object");
+ return NULL;
+ }
+
+ if ( 0 < meta->lsc_table_size ) {
+ jobject nioLSCTable = env->NewDirectByteBuffer((uint8_t *)meta + meta->lsc_table_offset,
+ meta->lsc_table_size);
+ if ( NULL == nioLSCTable ) {
+ LOGE("Couldn't allocate NIO LSC table");
+ return NULL;
+ }
+ env->SetObjectField(objMeta, fields.lscTable, nioLSCTable);
+ env->DeleteLocalRef(nioLSCTable);
+ env->SetIntField(objMeta, fields.lscTableApplied, meta->lsc_table_applied);
+ }
+
+ jobject nioFaces = env->NewDirectByteBuffer((uint8_t *)meta + meta->faces_offset,
+ meta->number_of_faces * sizeof(camera_metadata_face_t));
+ if ( NULL == nioFaces ) {
+ LOGE("Couldn't allocate NIO Face array");
+ return NULL;
+ }
+ env->SetObjectField(objMeta, fields.faces, nioFaces);
+ env->DeleteLocalRef(nioFaces);
+
+ env->SetIntField(objMeta, fields.numberOfFaces, meta->number_of_faces);
+ env->SetIntField(objMeta, fields.frameNumber, meta->frame_number);
+ env->SetIntField(objMeta, fields.shotNumber, meta->shot_number);
+ env->SetIntField(objMeta, fields.analogGain, meta->analog_gain);
+ env->SetIntField(objMeta, fields.analogGainReq, meta->analog_gain_req);
+ env->SetIntField(objMeta, fields.analogGainMin, meta->analog_gain_min);
+ env->SetIntField(objMeta, fields.analogGainMax, meta->analog_gain_max);
+ env->SetIntField(objMeta, fields.analogGainDev, meta->analog_gain_dev);
+ env->SetIntField(objMeta, fields.analogGainError, meta->analog_gain_error);
+ env->SetIntField(objMeta, fields.exposureTime, meta->exposure_time);
+ env->SetIntField(objMeta, fields.exposureTimeReq, meta->exposure_time_req);
+ env->SetIntField(objMeta, fields.exposureTimeMin, meta->exposure_time_min);
+ env->SetIntField(objMeta, fields.exposureTimeMax, meta->exposure_time_max);
+ env->SetIntField(objMeta, fields.exposureTimeDev, meta->exposure_time_dev);
+ env->SetIntField(objMeta, fields.exposureTimeError, meta->exposure_time_error);
+ env->SetIntField(objMeta, fields.exposureCompensationReq, meta->exposure_compensation_req);
+ env->SetIntField(objMeta, fields.exposureDev, meta->exposure_dev);
+ env->SetLongField(objMeta, fields.timestamp, meta->timestamp);
+ env->SetIntField(objMeta, fields.awbTemp, meta->awb_temp);
+ env->SetIntField(objMeta, fields.gainR, meta->gain_r);
+ env->SetIntField(objMeta, fields.gainGR, meta->gain_gr);
+ env->SetIntField(objMeta, fields.gainGB, meta->gain_gb);
+ env->SetIntField(objMeta, fields.gainB, meta->gain_b);
+ env->SetIntField(objMeta, fields.offsetR, meta->offset_r);
+ env->SetIntField(objMeta, fields.offsetGR, meta->offset_gr);
+ env->SetIntField(objMeta, fields.offsetGB, meta->offset_gb);
+ env->SetIntField(objMeta, fields.offsetB, meta->offset_b);
+
+ return objMeta;
+}
+
+static JNINativeMethod gMetadataMethods[] = {
+ {"nativeClassInit", "()V", (void*)Metadata_Init },
+ {"nativeRetrieveMetadata", "(Landroid/graphics/SurfaceTexture;)Lcom/ti/omap/android/cpcam/CPCamMetadata;", (void*)Metadata_retrieveMetadata },
+};
+
+int register_com_ti_omap_android_cpcam_CPCamMetadata(JNIEnv* env)
+{
+ int err = 0;
+ err = AndroidRuntime::registerNativeMethods(env,
+ kMetadataClassPathName,
+ gMetadataMethods,
+ NELEM(gMetadataMethods));
+ return err;
+}