2. ? Camera Framework
? Camera Architecture
? From java to hardware: Camera.open
flow
? startPreview()
? From hardware to Java: Jpeg Callback
flow
Contents
6. Application
Framework/SDK
Java Classes Exposed to the
application for interacting with the
hardware
frameworks/base/core/java/androi
d/hardware
JNI Glue Code between Java
Classes and Native Classes
frameworks/base/core/jni/android
_hardware_Camera.cpp
Native
Framework
Native counterpart of the Java
Camera Classes. Manages all
Binder Interactions
frameworks/av/camera/Camera.c
pp
IPC Binder 3 Binder Interfaces
ICameraService and Icamera
from Application to Framework.
ICameraClient for callbacks into
the Application
frameworks/av/camera
Camera Service The Camera Service that
manages permissions and
lifecycle of the Camera Devices
frameworks/av/services/camera/li
bcameraservice/CameraService.c
pp
HAL Interface Hardware Interface. platform/hardware/libhardware/inc
lude
HAL
Implementation
Hardware specific
implementations. Depends on
host processor, ISP and Sensor
platform/hardware/<vendor>/<plat
form>
Kernel drivers
8. Camera keynote
¡ñ Camera uses binderized classes
¡ð ICamera -- proxy to camera hardware
¡ð ICameraClient -- receives callbacks
¡ð ICameraService -- creates and controls Icamera
¡ñ ICameraService, like ICamera and ICameraClient, are binder
interfaces(proxy)
¡ñ Defined in frameworks/av/:
¡ð include/camera/ICamera*.h
¡ð camera/ICamera*.cpp
¡ð service/camera/libcameraservice/CameraService.cpp
¡ñ Camera class:
¡ð is a BnCameraClient
¡ð contains an Icamera
10. Step 1: open()
(1)frameworks/base/core/java/android/hardware/Camera.java
public class Camera {
public static Camera open(int cameraId) {
return new Camera(cameraId);
}
Camera(int cameraId) {
.................
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else {
mEventHandler = null;
}
native_setup(new WeakReference<Camera>(this), cameraId);
}
}
11. Step 2:Use JNI to call Native
function
(2) frameworks/base/core/jni/android_hardware_Camera.cpp
static JNINativeMethod camMethods[] = {
{ ¡°native_setup¡±,
¡°(Ljava/lang/Object;I)V¡±,
(void*)android_hardware_Camera_native_setup },
/*use Camera.cpp to connect CameraService*/
¡...
};
12. Step 3: call connect ,
set call back listener
(3) framework/av/camera/Camera.cpp
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject
jobject weak_this, jint cameraId)
{
sp<Camera> camera = Camera::connect(cameraId);
¡
jclass clazz = env->GetObjectClass(thiz);
// We use a weak reference so the Camera object can be garbage colle
// The reference is only used as a proxy for callbacks.
sp<JNICameraContext> context = new JNICameraContext(env, weak_th
camera);
context->incStrong(thiz);
camera->setListener(context);//CameraListener.
// ICamera and encapsulates it
into a Camera object, which it returns to JNI
env->SetIntField(thiz, fields.context, (int)context.get());
}
13. Step 4: get Camera from
BpCameraService
(4) framework/av/camera/CameraBase.cpp
sp<Camera> Camera::connect(int cameraId)
{
ALOGV("connect");
sp<Camera> c = new Camera();//BnCameraClient
const sp<ICameraService>& cs =
getCameraService();//return BpCameraService
if (cs != 0) {//Used for processing all kinds of events
c->mCamera = cs->connect(c, cameraId);//return
BpCamera
}
if (c->mCamera != 0) {
c->mCamera->asBinder()->linkToDeath(c);
c->mStatus = NO_ERROR;
} else {
c.clear();
}
return c;
}
14. Step 5: Use IPC binder between BnCameraService and
BpCameraService
(5)framework/av/service/camera/libcameraservice/ICameraService.cpp
class BpCameraService: public BpInterface<ICameraService>
{
public:
// connect to camera service
virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int
cameraId)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
data.writeStrongBinder(cameraClient->asBinder());//ÞD“Q³ÉIBinderÀà
ÐÍBpCameraClient
data.writeInt32(cameraId);
remote()->transact(BnCameraService::CONNECT, data, &reply);
return interface_cast<ICamera>(reply.readStrongBinder());//BpCamera
}
};
20. Callback Interfaces
Java Framework
Camera
JNI
Client
Camera
CameraService
CameraLinstener
1. call back from hardward , flow start from camera client ex:jpeg call back
void CameraClient::dataCallback(int32_t msgType,
const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
CameraClient* client =
static_cast<CameraClient*>(getClientFromCookie(user));
switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
¡....
case CAMERA_MSG_COMPRESSED_IMAGE:
client->handleCompressedPicture(dataPtr);
Break;
¡.....
}
}
ICameraClientJNIEnv
AP
Camera
xxxListener
2. use ipc binder ¡°bpcameraclient , bncameraclient in IcameraClient to send
data , and implement in Camera.cpp
void CameraClient::handleCompressedPicture(const sp<IMemory>& mem) {
sp<ICameraClient> c = mRemoteCallback;
mLock.unlock();
if (c != 0) {
c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
}
12
21. Callback Interfaces
Java Framework
Camera
JNI
Client
Camera
CameraService
CameraLinstener
3. use ipc binder ¡°bpcameraclient , bncameraclient in IcameraClient to send
data , and implement in Camera.cpp
void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
camera_frame_metadata_t *metadata)
{
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
listener = mListener;
}
if (listener != NULL) {
listener->postData(msgType, dataPtr, metadata);
}
}
ICameraClientJNIEnv
AP
Camera
xxxListener
3
22. Callback Interfaces
Java Framework
Camera
JNI
Client
Camera
CameraService
CameraLinstener
class CameraListener: virtual public RefBase
{
public:
virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr,
camera_frame_metadata_t *metadata) = 0;
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType,
const sp<IMemory>& dataPtr) = 0;
};
ICameraClientJNIEnv
Note:
msgType enum values and data structures, ex: ¡°camera_frame_metadata_t¡±
are defined in ¡°systemcoreincludesystemcamera.h¡±.
AP
Camera
xxxListener
23. Callback Interfaces
Java Framework
Camera
JNI
Client
Camera
CameraService
CameraLinstener
4.Implement cameraListener post data in android_haradware_camera.cpp
void JNICameraContext::postData(int32_t msgType, const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata)
{
¡.......
JNIEnv *env = AndroidRuntime::getJNIEnv();
.....
int32_t dataMsgType = msgType
& ~CAMERA_MSG_PREVIEW_METADATA;
switch (dataMsgType) {
¡....
case CAMERA_MSG_RAW_IMAGE:
ALOGV("rawCallback");
if (mRawImageCallbackBuffers.isEmpty()) {
env->CallStaticVoidMethod(mCameraJClass,
fields.post_event,
mCameraJObjectWeak, dataMsgType, 0, 0, NULL);
} else {
copyAndPost(env, dataPtr, dataMsgType);
}
Break;
}
ICameraClientJNIEnv
AP
Camera
xxxListener
5.post image data to Java by JNI
void JNICameraContext::copyAndPost(JNIEnv* env, const
sp<IMemory>& dataPtr, int msgType)
{
obj = env->NewByteArray(size);
env->CallStaticVoidMethod(mCameraJClass,
fields.post_event,
mCameraJObjectWeak, msgType, 0, 0, obj);
}
//jclass clazz = env->FindClass("android/hardware/Camera");
fields.post_event = env->GetStaticMethodID(clazz,
"postEventFromNative",
"(Ljava/lang/Object;IIILjava/lang/Object;)V");
45
24. Callback Interfaces
Java Framework
Camera
JNI
Client
Camera
CameraService
CameraLinstener
5. Call back to ap level :Framework/base/core/java/android/hardware/camera.java
private class EventHandler extends Handler
{
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case CAMERA_MSG_COMPRESSED_IMAGE:
if (mJpegCallback != null) {
mJpegCallback.onPictureTaken((byte[])msg.obj, mCamera);
}
Return;
}
ICameraClientJNIEnv
AP
Camera
xxxListener
6