diff options
author | Tyler Luu <tluu@ti.com> | 2012-07-31 17:05:17 -0500 |
---|---|---|
committer | Daniel Levin <dendy@ti.com> | 2012-10-10 18:55:47 +0300 |
commit | 3abab7b47cf5a2766df8f8b7dcaf1a21f261b8e9 (patch) | |
tree | fc1b75ae1d513f370295d8353c4bb9c27dd95786 /cpcam | |
parent | e041a9a9e6f06fa875c5427391861f067422c45c (diff) | |
download | hardware_ti_omap4-3abab7b47cf5a2766df8f8b7dcaf1a21f261b8e9.zip hardware_ti_omap4-3abab7b47cf5a2766df8f8b7dcaf1a21f261b8e9.tar.gz hardware_ti_omap4-3abab7b47cf5a2766df8f8b7dcaf1a21f261b8e9.tar.bz2 |
CPCam: Add CPCamMetadata
Added new class CPCamMetadata.
Removed obsolete class CPCamUtils.
Change-Id: I69b652ae827ffc583c69a678d8efce96ed9e75ce
Signed-off-by: Emilian Peev <epeev@mm-sol.com>
Signed-off-by: Vladimir Petrov <vppetrov@mm-sol.com>
Diffstat (limited to 'cpcam')
-rw-r--r-- | cpcam/java/com/ti/omap/android/cpcam/CPCamMetadata.java | 449 | ||||
-rw-r--r-- | cpcam/java/com/ti/omap/android/cpcam/CPCamUtils.java | 27 | ||||
-rw-r--r-- | cpcam/jni/Android.mk | 4 | ||||
-rw-r--r-- | cpcam/jni/com_ti_omap_android_cpcam_CPCam.cpp | 7 | ||||
-rw-r--r-- | cpcam/jni/com_ti_omap_android_cpcam_CPCamMetadata.cpp | 610 |
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; +} |