一、命令流程
1.APP
packages/apps/Camera/src/com/android/camera/PhotoModule.java
private void startPreview() { mCameraDevice.setPreviewDisplayAsync(mCameraSurfaceHolder); mCameraDevice.startPreviewAsync(); }
packages/apps/Camera/src/com/android/camera/CameraManager.java
public void setPreviewDisplayAsync(final SurfaceHolder surfaceHolder) { mCameraHandler.obtainMessage(SET_PREVIEW_DISPLAY_ASYNC, surfaceHolder).sendToTarget(); } public void startPreviewAsync() { mCameraHandler.sendEmptyMessage(START_PREVIEW_ASYNC); } public void handleMessage(final Message msg) { switch (msg.what) { case SET_PREVIEW_DISPLAY_ASYNC: try { mCamera.setPreviewDisplay((SurfaceHolder) msg.obj); } catch(IOException e) { throw new RuntimeException(e); } return; // no need to call mSig.open() case START_PREVIEW_ASYNC: mCamera.startPreview(); return; // no need to call mSig.open() } }
2.frameworks
frameworks/base/core/java/android/hardware/Camera.java
public final void setPreviewDisplay(SurfaceHolder holder) throws IOException { setPreviewDisplay(holder.getSurface()); } public native final void startPreview();
frameworks/base/core/jni/android_hardware_Camera.cpp
static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz, jobject jSurface){ sp<Camera> camera = get_native_camera(env, thiz, NULL); if (camera->setPreviewDisplay(surface) != NO_ERROR) { jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed"); } } static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz){ sp<Camera> camera = get_native_camera(env, thiz, NULL); if (camera->startPreview() != NO_ERROR) { jniThrowRuntimeException(env, "startPreview failed"); return; } }
frameworks/av/camera/Camera.cpp
status_t Camera::setPreviewDisplay(const sp<Surface>& surface){ sp <ICamera> c = mCamera; return c->setPreviewDisplay(surface); } status_t Camera::startPreview(){ sp <ICamera> c = mCamera; return c->startPreview(); }
Binder调用
frameworks/av/services/camera/libcameraservice/CameraClient.cpp
status_t CameraClient::setPreviewDisplay(const sp<Surface>& surface) { return setPreviewWindow(binder, window); } status_t CameraClient::startPreview() { return startCameraMode(CAMERA_PREVIEW_MODE); } status_t CameraClient::startCameraMode(camera_mode mode) { switch(mode) { case CAMERA_PREVIEW_MODE: return startPreviewMode(); } } status_t CameraClient::startPreviewMode() { mHardware->setPreviewWindow(mPreviewWindow); result = mHardware->startPreview(); }
frameworks/av/services/camera/libcameraservice/CameraHardwareInterface.h
status_t setPreviewWindow(const sp<ANativeWindow>& buf){ mPreviewWindow = buf; /* #define anw(n) __to_anw(((struct camera_preview_window *)n)->user) static ANativeWindow *__to_anw(void *user){ CameraHardwareInterface *__this = reinterpret_cast<CameraHardwareInterface *>(user); return __this->mPreviewWindow.get(); } */ return mDevice->ops->set_preview_window(mDevice, buf.get() ? &mHalPreviewWindow.nw : 0); /* void initHalPreviewWindow(){ mHalPreviewWindow.nw.cancel_buffer = __cancel_buffer; mHalPreviewWindow.nw.lock_buffer = __lock_buffer; mHalPreviewWindow.nw.dequeue_buffer = __dequeue_buffer; mHalPreviewWindow.nw.enqueue_buffer = __enqueue_buffer; mHalPreviewWindow.nw.set_buffer_count = __set_buffer_count; mHalPreviewWindow.nw.set_buffers_geometry = __set_buffers_geometry; mHalPreviewWindow.nw.set_crop = __set_crop; mHalPreviewWindow.nw.set_timestamp = __set_timestamp; mHalPreviewWindow.nw.set_usage = __set_usage; mHalPreviewWindow.nw.set_swap_interval = __set_swap_interval; mHalPreviewWindow.nw.get_min_undequeued_buffer_count = __get_min_undequeued_buffer_count; } */ } status_t startPreview(){ return mDevice->ops->start_preview(mDevice); }
3.HAL
hardware/amlogic/camera/CameraHal_Module.cpp
int camera_set_preview_window(struct camera_device * device, struct preview_stream_ops *window){ rv = gCameraHals[aml_dev->cameraid]->setPreviewWindow(window); } int camera_start_preview(struct camera_device * device){ rv = gCameraHals[aml_dev->cameraid]->startPreview(); }
hardware/amlogic/camera/CameraHal.cpp
status_t CameraHal::setPreviewWindow(struct preview_stream_ops *window){ mDisplayAdapter = new ANativeWindowDisplayAdapter(); mDisplayAdapter->setFrameProvider(mCameraAdapter); //将frameCallbackRelay设置为BaseCameraAdapter的回调函数 mDisplayAdapter->setErrorHandler(mAppCallbackNotifier.get()); //设置BaseCameraAdapter错误处理函数 ret = mDisplayAdapter->setPreviewWindow(window);//设置post的Surface /* hardware/amlogic/camera/ANativeWindowDisplayAdapter.cpp int ANativeWindowDisplayAdapter::setPreviewWindow(preview_stream_ops_t* window){ mANativeWindow = window; } */ } status_t CameraHal::startPreview(){ //hardware/amlogic/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h //#define DEFAULT_PREVIEW_PIXEL_FORMAT V4L2_PIX_FMT_NV21 ret = allocPreviewBufs(mPreviewWidth, mPreviewHeight, mParameters.getPreviewFormat(), required_buffer_count, max_queueble_buffers); /* status_t CameraHal::allocPreviewBufs(int width, int height, const char* previewFormat, unsigned int buffercount, unsigned int &max_queueable){ mPreviewBufs = (int32_t *) mDisplayAdapter->allocateBuffer(width, height, previewFormat, mPreviewLength, buffercount); } hardware/amlogic/camera/ANativeWindowDisplayAdapter.cpp void* ANativeWindowDisplayAdapter::allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs){ err = mANativeWindow->set_buffers_geometry( mANativeWindow, width, height, mNativeWindowPixelFormat); //NV21 } frameworks/av/services/camera/libcameraservice/CameraHardwareInterface.h static int __set_buffers_geometry(struct preview_stream_ops* w, int width, int height, int format){ ANativeWindow *a = anw(w); //#define anw(n) __to_anw(((struct camera_preview_window *)n)->user) //__this->mPreviewWindow.get(); return native_window_set_buffers_geometry(a, width, height, format); } */ }
二、数据流程
hardware/amlogic/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
int V4LCameraAdapter::previewThread(){ yuyv422_to_nv21(src,dest,width,height); frame.mFrameMask |= CameraFrame::PREVIEW_FRAME_SYNC; frame.mPixelFmt = mPixelFormat; ret = sendFrameToSubscribers(&frame); }
hardware/amlogic/camera/BaseCameraAdapter.cpp
status_t BaseCameraAdapter::sendFrameToSubscribers(CameraFrame *frame){ ret = __sendFrameToSubscribers(frame, &mFrameSubscribers, CameraFrame::PREVIEW_FRAME_SYNC); } status_t BaseCameraAdapter::__sendFrameToSubscribers(CameraFrame* frame, KeyedVector<int, frame_callback> *subscribers, CameraFrame::FrameType frameType){ callback = (frame_callback) subscribers->valueAt(k); callback(frame); }
hardware/amlogic/camera/ANativeWindowDisplayAdapter.cpp
void ANativeWindowDisplayAdapter::frameCallbackRelay(CameraFrame* caFrame){ ANativeWindowDisplayAdapter *da = (ANativeWindowDisplayAdapter*) caFrame->mCookie; da->frameCallback(caFrame); } void ANativeWindowDisplayAdapter::frameCallback(CameraFrame* caFrame){ PostFrame(df); } status_t ANativeWindowDisplayAdapter::PostFrame(ANativeWindowDisplayAdapter::DisplayFrame &dispFrame){ mANativeWindow->set_crop(mANativeWindow, xOff/bytesPerPixel, yOff, (xOff/bytesPerPixel)+mPreviewWidth, yOff+mPreviewHeight); ret = mANativeWindow->enqueue_buffer(mANativeWindow, mBufferHandleMap[i]); }
frameworks/av/services/camera/libcameraservice/CameraHardwareInterface.h
static int __set_crop(struct preview_stream_ops *w, int left, int top, int right, int bottom){ ANativeWindow *a = anw(w); return native_window_set_crop(a, &crop); } static int __enqueue_buffer(struct preview_stream_ops* w, buffer_handle_t* buffer){ ANativeWindow *a = anw(w); return a->queueBuffer(a, container_of(buffer, ANativeWindowBuffer, handle), -1); }