Android之Camera预览

一、命令流程


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);
}

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值