summaryrefslogtreecommitdiffstats
path: root/core/jni/android_hardware_Camera.cpp
diff options
context:
space:
mode:
authorWu-cheng Li <wuchengli@google.com>2011-07-30 05:00:37 +0800
committerWu-cheng Li <wuchengli@google.com>2011-08-02 15:48:41 +0800
commitbb1e275c0e684dd213f124da77110cdd9d6f090c (patch)
tree0a20f8da5c8e09ca8663053ae39e544bfd315243 /core/jni/android_hardware_Camera.cpp
parent0175028b73eefc503f67d5686b71e1957677e0de (diff)
downloadframeworks_base-bb1e275c0e684dd213f124da77110cdd9d6f090c.zip
frameworks_base-bb1e275c0e684dd213f124da77110cdd9d6f090c.tar.gz
frameworks_base-bb1e275c0e684dd213f124da77110cdd9d6f090c.tar.bz2
Pass camera frame metadata from camera service to Java.
bug:4460717 Change-Id: I2fae6e1dfca6b8f3a5ee5716fc7817f5417bf657
Diffstat (limited to 'core/jni/android_hardware_Camera.cpp')
-rw-r--r--core/jni/android_hardware_Camera.cpp94
1 files changed, 85 insertions, 9 deletions
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 3dcaa37..884fa78 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -45,6 +45,8 @@ struct fields_t {
jfieldID rect_right;
jfieldID rect_bottom;
jmethodID post_event;
+ jmethodID rect_constructor;
+ jmethodID face_constructor;
};
static fields_t fields;
@@ -57,8 +59,10 @@ public:
JNICameraContext(JNIEnv* env, jobject weak_this, jclass clazz, const sp<Camera>& camera);
~JNICameraContext() { release(); }
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
- virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr);
+ virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata);
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
+ void postMetadata(JNIEnv *env, int32_t msgType, camera_frame_metadata_t *metadata);
void addCallbackBuffer(JNIEnv *env, jbyteArray cbb, int msgType);
void setCallbackMode(JNIEnv *env, bool installed, bool manualMode);
sp<Camera> getCamera() { Mutex::Autolock _l(mLock); return mCamera; }
@@ -74,6 +78,8 @@ private:
jobject mCameraJObjectWeak; // weak reference to java object
jclass mCameraJClass; // strong reference to java class
sp<Camera> mCamera; // strong reference to native object
+ jclass mFaceClass; // strong reference to Face class
+ jclass mRectClass; // strong reference to Rect class
Mutex mLock;
/*
@@ -124,6 +130,12 @@ JNICameraContext::JNICameraContext(JNIEnv* env, jobject weak_this, jclass clazz,
mCameraJClass = (jclass)env->NewGlobalRef(clazz);
mCamera = camera;
+ jclass faceClazz = env->FindClass("android/hardware/Camera$Face");
+ mFaceClass = (jclass) env->NewGlobalRef(faceClazz);
+
+ jclass rectClazz = env->FindClass("android/graphics/Rect");
+ mRectClass = (jclass) env->NewGlobalRef(rectClazz);
+
mManualBufferMode = false;
mManualCameraCallbackSet = false;
}
@@ -142,6 +154,14 @@ void JNICameraContext::release()
env->DeleteGlobalRef(mCameraJClass);
mCameraJClass = NULL;
}
+ if (mFaceClass != NULL) {
+ env->DeleteGlobalRef(mFaceClass);
+ mFaceClass = NULL;
+ }
+ if (mRectClass != NULL) {
+ env->DeleteGlobalRef(mRectClass);
+ mRectClass = NULL;
+ }
clearCallbackBuffers_l(env);
mCamera.clear();
}
@@ -263,7 +283,8 @@ void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int
}
}
-void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr)
+void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata)
{
// VM pointer will be NULL if object is released
Mutex::Autolock _l(mLock);
@@ -273,8 +294,10 @@ void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr)
return;
}
+ int32_t dataMsgType = msgType & ~CAMERA_MSG_PREVIEW_METADATA;
+
// return data based on callback type
- switch (msgType) {
+ switch (dataMsgType) {
case CAMERA_MSG_VIDEO_FRAME:
// should never happen
break;
@@ -285,23 +308,63 @@ void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr)
LOGV("rawCallback");
if (mRawImageCallbackBuffers.isEmpty()) {
env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
- mCameraJObjectWeak, msgType, 0, 0, NULL);
+ mCameraJObjectWeak, dataMsgType, 0, 0, NULL);
} else {
- copyAndPost(env, dataPtr, msgType);
+ copyAndPost(env, dataPtr, dataMsgType);
}
break;
+ // There is no data.
+ case 0:
+ break;
+
default:
- LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
- copyAndPost(env, dataPtr, msgType);
+ LOGV("dataCallback(%d, %p)", dataMsgType, dataPtr.get());
+ copyAndPost(env, dataPtr, dataMsgType);
break;
}
+
+ // post frame metadata to Java
+ if (metadata && (msgType & CAMERA_MSG_PREVIEW_METADATA)) {
+ postMetadata(env, CAMERA_MSG_PREVIEW_METADATA, metadata);
+ }
}
void JNICameraContext::postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
{
// TODO: plumb up to Java. For now, just drop the timestamp
- postData(msgType, dataPtr);
+ postData(msgType, dataPtr, NULL);
+}
+
+void JNICameraContext::postMetadata(JNIEnv *env, int32_t msgType, camera_frame_metadata_t *metadata)
+{
+ jobjectArray obj = NULL;
+ obj = (jobjectArray) env->NewObjectArray(metadata->number_of_faces,
+ mFaceClass, NULL);
+ if (obj == NULL) {
+ LOGE("Couldn't allocate face metadata array");
+ return;
+ }
+
+ for (int i = 0; i < metadata->number_of_faces; i++) {
+ jobject face = env->NewObject(mFaceClass, fields.face_constructor);
+ env->SetObjectArrayElement(obj, i, face);
+
+ jobject rect = env->NewObject(mRectClass, fields.rect_constructor);
+ env->SetIntField(rect, fields.rect_left, metadata->faces[i].rect[0]);
+ env->SetIntField(rect, fields.rect_top, metadata->faces[i].rect[1]);
+ env->SetIntField(rect, fields.rect_right, metadata->faces[i].rect[2]);
+ env->SetIntField(rect, fields.rect_bottom, metadata->faces[i].rect[3]);
+
+ env->SetObjectField(face, fields.face_rect, rect);
+ env->SetIntField(face, fields.face_score, metadata->faces[i].score);
+
+ env->DeleteLocalRef(face);
+ env->DeleteLocalRef(rect);
+ }
+ env->CallStaticVoidMethod(mCameraJClass, fields.post_event,
+ mCameraJObjectWeak, msgType, 0, 0, obj);
+ env->DeleteLocalRef(obj);
}
void JNICameraContext::setCallbackMode(JNIEnv *env, bool installed, bool manualMode)
@@ -715,7 +778,7 @@ static void android_hardware_Camera_setDisplayOrientation(JNIEnv *env, jobject t
}
static void android_hardware_Camera_startFaceDetection(JNIEnv *env, jobject thiz,
- jint type, jobjectArray face)
+ jint type)
{
LOGV("startFaceDetection");
JNICameraContext* context;
@@ -878,6 +941,19 @@ int register_android_hardware_Camera(JNIEnv *env)
return -1;
}
+ clazz = env->FindClass("android/graphics/Rect");
+ fields.rect_constructor = env->GetMethodID(clazz, "<init>", "()V");
+ if (fields.rect_constructor == NULL) {
+ LOGE("Can't find android/graphics/Rect.Rect()");
+ return -1;
+ }
+
+ clazz = env->FindClass("android/hardware/Camera$Face");
+ fields.face_constructor = env->GetMethodID(clazz, "<init>", "()V");
+ if (fields.face_constructor == NULL) {
+ LOGE("Can't find android/hardware/Camera$Face.Face()");
+ return -1;
+ }
// Register native functions
return AndroidRuntime::registerNativeMethods(env, "android/hardware/Camera",