移植原生Android2.3之 - Camera Preview过程

1.  建立连接

前面的Camera sub system的基础知识这里不在赘述,调用流程:

    CameraService->connect

> 判断cameraId是否为有效cameraId,里面的mNumberOfCameras是从HAL里得到的,在CameraService创建时读取HAL的静态结构数据CameraInfo,通常也是实现在对应的CameraHardware里。

        >判断mClient是否已经建立

                如果有mClient,看看其是否正在使用,没有使用的话,将mClient销毁

        >如果mClient存在并且正在使用,则退出

        >打开CameraHardware

                调用的是HAL_openCameraHardware(cameraId),它是HAL必须要实现的一个open函数,代码在对应的CameraHardware.cpp里实现。

                它其实只调用了CameraHardware的createInstance使用了单例模式。

        >创建新的Client,加入到管理数组mClient里

  HAL CameraHardware.cpp的实现

       > 声明CameraInfo,如果是两个摄像头的话,就创建两个元素的结构体

                static CameraInfo sCameraInfo[] = {

                        {  CAMERA_FACING_BACK,   0 /* orientation */ }
                        {  CAMERA_FACING_FRONT,   0 /* orientation */ }

                };

        > 声明HAL_getNumberOfCameras()

                其实就是给上层的接口函数,让上层得到摄像头的个数

                        returen sizeof(sCameraInfo)/sizeof(sCameraInfo[0]);

         > 声明HAL_getCameraInfo(int cameraId, struct CameraInfo * cameraInfo)

                其实就是给上层的接口函数,让上层得到指定摄像头的信息

        > 声明HAL_openCameraHardware(int cameraId)

                给上层的接口函数,打开指定的摄像头,创建HAL实例,就来供上层使用, 打开Camera驱动,设置其CameraParameters

2. Preview

        > 上层最终调用到CameraService::Client::startPreview()

        > 调用到CameraService::Client::startCameraMode(int)

                >> 判断是否有权访问Camera主要是check pid和Hardware

                >> 在该函数里根据int的值,决定是preview还是Recording

                >> 如果是Preview调用CameraService::Client::startPreviewMode()

                        >>> 判断是否hardware正在使用?如果正在使用,退出

                        >>> 判断使用Overlay还是Surface

                           >>> 使用Overlay调用HAL的startPreview()     mHardware->startPreview()   (mHardware是在第1步中的HAL_openCameraHardware(int cameraId)中得到)

                           >>> 如果使用Surface,设置hardware使用flag, 调用startPreview

                                >>> 创建V4L2Camera实例mCamera,这是一个底层的驱动操作封装类,用来和V4L2直接进行操作

                                >>> 设置MemoryHeapBase和MemoryBase,方便远程remote client能够访问到Camera frame data

                                >>> 启动preview thread

                         >>>调用CameraService::Client::registerPreviewBuffers(),注册PreviewBuffers用来将preview数据送到Surface里

                                >>> 创建一个ISurface::BufferHeap类型实例,初始化preview数据的信息,宽,高,显示数据格式,和preview数据位置

                                >>>ISurface::BufferHeap  buffers(w, h, w, h, HAL_PIXEL_FORMAT_RGB_565, mOrientation, 0, mHardware->getPreviewHeap());

                                >>> 调用mSurface->registerBuffers(buffers),将上述数据信息注册到Surface里,用于显示

                                PS:之前写的代码,一起显示白屏,没有采集的图像,最后发现是上述HAL_PIXEL_FORMAT_RGB_565忘记改了,浪费半天时间。

 ++++++ 同时运行的preview thread

                >>1  调用mCamera->GrabRawFrame()从USB摄像头获取一帧原始数据rawFrameData(YUYV格式)

                >>2 将rawFrameData转换为rgb565格式方便显示

                >>3 调用Callback函数mDataCb,将转换好的数据传回到CameraService里

                >>4 回到1继续执行

                >> 数据被送回到CameraService里,回调的是CameraService::Client::dataCallback方法

                >> 调用 CameraService::Client::handlePreviewData(IMemory)

                >> 调用mSurface->postBuffer()显示到Surface上


你可能感兴趣的:(thread,android,struct,System,callback)