Android Camera Subsystem 架构(Binder机制)及显示分析(3)

对于AP层用户,通过Camera界面, 以最直观的方式能够从Camera显示窗口中看到的Camera Display主要包括三部分。各部分的具体细节如下所示。

(1)Camera Preview Display

Android Camera Subsystem 架构(Binder机制)及显示分析

对于Camera Preview Display, 从Camera应用程序的角度来看,AP层需要实现Android.hardware.Camera(Framework层)类提供给上层应用的preview相关接口,完成相应的逻辑处理。但Preview作为大数据量交换的处理过程,系统不可能通过回调方式,最终将底层Camera硬件设备采集的数据交给AP层来处理。所以,上层应用只需要做一些简单的状态和UI显示处理,AP不需要接收处理真正的Preview数据,而是将数据接收和处理的过程交由ISurface接口来完成,确切的说是由ISurface的实现类SurfaceFlinger来完成。

AP层通过调用android.hardware.Camera类提供的startPreview函数,最终通过libcamera_client.so的Camera类,利用Binder IPC,通知CameraService, CameraService通过调用其内部类Clien,内部类再通过调用HAL层提供的Camera功能完成相应的操作。

CameraService层针对Camera Client端得请求,都将交与其内部类Client来完成。CameraService层的startPreview的具体实现由CameraService::Client类的startPreviewMode函数完成相应的操作。

status_t CameraService::Client::startPreviewMode() {

// if preview has been enabled, nothing needs to be done

if (mHardware->previewEnabled()) {

return NO_ERROR;

}

// start preview mode

status_t ret = NO_ERROR;

if (mUseOverlay) {

….

} else {

mHardware->enableMsgType(CAMERA_MSG_PREVIEW_FRAME);

ret = mHardware->startPreview();

if (ret != NO_ERROR) return ret;

// If preview display has been set, register preview buffers now.

if (mSurface != 0) {

// Unregister here because the surface registered with raw heap.

mSurface->unregisterBuffers();

ret = registerPreviewBuffers();

}

}

return ret;

}

status_t CameraService::Client::registerPreviewBuffers()

{

int width, height;

CameraParameters params(mHardware->getParameters());

params.getPreviewSize(&width, &height);

// don't use a hardcoded format here

ISurface::BufferHeap buffers(width, height, width, height,

PIXEL_FORMAT_RGB_565,

mOrientation, 0,

mHardware->getPreviewHeap());

status_t ret = mSurface->registerBuffers(buffers);

if (ret != NO_ERROR) {

LOGE("registerBuffers failed with status %d", ret);

}

return ret;

}

 
     

从上面的代码我们可以看到,ISurface为Camera Preview Display专门注册了显示缓冲区,该缓冲区映射到mHardware->getPreviewHeap()指向的内存空间,缓冲区接收的数据格式为PIXEL_FORMAT_RGB_565

CameraService已经为Camera Preview Display准备好了显示缓冲区,哪谁为注册的这块Buffer填充Preview数据呢?为了完成Camera Preview,Camera HAL层的CameraHardware类提供了previewThread线程,来完成底层数据到ISurface缓冲区的投递。通过线程Loop最终将Camera硬件设备采集的数据不断送到显示缓冲区,最后显示到AP界面上。

int CameraHardware::previewThread()

{

int width, height;

mParameters.getPreviewSize(&width, &height);

if (!previewStopped && mPreviewBuffer != 0 && mRawBuffer !=0 && mDataFn) {

int delay = (int)(1000000.0f / float(previewFrameRate));

①mCamera.GrabRawFrame(mHeap->getBase());

if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME){

②mCamera.GrabPreviewFrame((mHeap->getBase(),

mPreviewHeap->getBase());

③mDataFn(CAMERA_MSG_PREVIEW_FRAME,

mPreviewBuffer, mUser);

delay-=100;

}

………

}

return NO_ERROR;

}

 
     

从代码中我们可以看到,previewThread线程针对Preview Display,主要完成三个步骤的操作,

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwgysw.html