Android Camera Architecture

Embed Size (px)

Citation preview

Android Camera Architecture

Author: Picker

Architecture

Architecture
Path of the Source Code

frameworks/base/core/java/android/hardware/

frameworks/base/core/jni/

frameworks/base/libs/camera/

frameworks/base/services/camera/libcameraservice/

vendor/nvidia/tegra/hal/libnvomxcamera/

Proxy Pattern

Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides

A Possible Object Diagram of Proxy Structure at Run-Time

Proxy Structure

Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides

Implementation

- Design a Abstract Class for Proxy and Server to Extend it.

- Give an RealObject Instance for Proxy. Execute these Methods by Proxy.

- The Client just Need to Face the Proxy.

Singleton Pattern

Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides

Singleton Structure

Reference to: Design Patterns by Gamma, Helm, Johnson, Vlissides

Singleton* Singleton::_instance = 0; Singleton* Singleton::Instance () { if (_instance == 0) { _instance = new Singleton; } return _instance; }

Implementation

Architecture Diagram

Proxy Pattern

Singleton Pattern

33 // client singleton for camera service binder interface 34 Mutex Camera::mLock; 35 sp Camera::mCameraService; 36 sp Camera::mDeathNotifier;

Singleton Pattern

Camera.cpp

frameworks/base/libs/camera/

38 // establish binder interface to camera service 39 const sp& Camera::getCameraService() 40 { 41 Mutex::Autolock _l(mLock); 42 if (mCameraService.get() == 0) { 43 sp sm = defaultServiceManager(); 44 sp binder; 45 do { 46 binder = sm->getService(String16("media.camera")); 47 if (binder != 0) 48 break; 49 LOGW("CameraService not published, waiting..."); 50 usleep(500000); // 0.5 s 51 } while(true); 52 if (mDeathNotifier == NULL) { 53 mDeathNotifier = new DeathNotifier(); 54 } 55 binder->linkToDeath(mDeathNotifier); 56 mCameraService = interface_cast(binder); 57 } 58 LOGE_IF(mCameraService==0, "no CameraService!?"); 59 return mCameraService; 60 }

Camera.cpp

frameworks/base/libs/camera/

53 class BpCamera: public BpInterface 54 { 55 public: 56 BpCamera(const sp& impl) 57 : BpInterface(impl) 58 { 59 } 60 61 // disconnect from camera service 62 void disconnect() 63 { 64 LOGV("disconnect"); 65 Parcel data, reply; 66 data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); 67 remote()->transact(DISCONNECT, data, &reply); 68 }

ICamera.cpp

frameworks/base/libs/camera/

Proxy Pattern - Sender

34 class CameraService : 35 public BinderService, 36 public BnCameraService 37 { 38 class Client; 39 friend class BinderService;

82 class Client : public BnCamera 83 { 84 public: 85 // ICamera interface (see ICamera for details) 86 virtual void disconnect(); 87 virtual status_t connect(const sp& client); 88 virtual status_t lock(); 89 virtual status_t unlock();206 }

Proxy Pattern - Receiver

CameraService.h

frameworks/base/services/camera/libcameraservice/

A Simple Workflow of Starting the Camera Preview

An Example: Set the Preview Display

349 public final void setPreviewDisplay(SurfaceHolder holder) throws IOException { 350 if (holder != null) { 351 setPreviewDisplay(holder.getSurface()); 352 } else { 353 setPreviewDisplay((Surface)null); 354 } 355 }

Camera.java

frameworks/base/core/java/android/hardware/

android_hardware_Camera.cpp

381 static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz, jobject jSurface)382 {383 LOGV("setPreviewDisplay");384 sp camera = get_native_camera(env, thiz, NULL);385 if (camera == 0) return;386 387 sp surface = NULL; 388 if (jSurface != NULL) {389 surface = reinterpret_cast(env->GetIntField(jSurface, fields.surface));390 }391 if (camera->setPreviewDisplay(surface) != NO_ERROR) {392 jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed");393 }394 }

frameworks/base/core/jni/

Camera.cpp

frameworks/base/libs/camera/

171 // pass the buffered ISurface to the camera service172 status_t Camera::setPreviewDisplay(const sp& surface)173 { 174 LOGV("setPreviewDisplay");175 sp c = mCamera;176 if (c == 0) return NO_INIT; 177 if (surface != 0) {178 return c->setPreviewDisplay(surface->getISurface());179 } else {180 LOGD("app passed NULL surface");181 return c->setPreviewDisplay(0);182 }183 }

ICamera.cpp

70 // pass the buffered ISurface to the camera service 71 status_t setPreviewDisplay(const sp& surface) 72 { 73 LOGV("setPreviewDisplay"); 74 Parcel data, reply; 75 data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); 76 data.writeStrongBinder(surface->asBinder()); 77 remote()->transact(SET_PREVIEW_DISPLAY, data, &reply); 78 return reply.readInt32(); 79 }

frameworks/base/libs/camera/

CameraService.cpp

frameworks/base/libs/camera/

485 status_t CameraService::Client::setPreviewDisplay(const sp& surface) { 486 LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());

510 mSurface = surface; 511 mOverlayRef = 0; 512 // If preview has been already started, set overlay or register preview 513 // buffers now. 514 if (mHardware->previewEnabled()) { 515 if (mUseOverlay) { 516 result = setOverlay(); 517 } else if (mSurface != 0) { 518 result = registerPreviewBuffers(); 519 } 520 }

frameworks/base/libs/camera/

CameraService.cpp

525 status_t CameraService::Client::registerPreviewBuffers() { 526 int w, h; 527 CameraParameters params(mHardware->getParameters()); 528 params.getPreviewSize(&w, &h); 529 530 // FIXME: don't use a hardcoded format here. 531 ISurface::BufferHeap buffers(w, h, w, h, 532 HAL_PIXEL_FORMAT_YCrCb_420_SP, 533 mOrientation, 534 0, 535 mHardware->getPreviewHeap()); 536 537 status_t result = mSurface->registerBuffers(buffers); 538 if (result != NO_ERROR) { 539 LOGE("registerBuffers failed with status %d", result); 540 } 541 return result; 542 }

frameworks/base/libs/camera/

CameraHardwareStub.cpp

104 sp CameraHardwareStub::getPreviewHeap() const105 { 106 return mPreviewHeap;107 }