[RK3288][Android6.0] Camera HAL流程小结

Platform: RK3288
OS: Android 6.0

Kernel: 3.10.92


虽然是Android6.0, 但是rockchip用的是Camera HAL 1.0的架构,没有更新到3.x.

开机:(MediaServer会调用)
camera_get_number_of_cameras ->        CameraHal_Module.cpp
    camera_board_profiles::getInstance ->
        createInstance ->
            new camera_board_profiles
            fopen    //打开/etc/cam_board.xml
            XML_ParserCreate
            fread
            XML_ParseBuffer    //解析文件
    LoadSensor ->
        OpenAndRegistALLSensor    //第一次会去尝试注册所有cam_board.xml里的sensor.
            OpenAndRegistOneSensor ->
                RegisterSensorDevice    //通过ioctl来执行sensor的初始化过程。
        ReadDevNameFromXML ->    //如果已经初始化过,那么直接读取/data/camera/media_profiles.xml里被第一次初始化添加进去的sensor.
            OpenAndRegistOneSensor //注册只在cam_board.xml中存在的sensor,uvc camera除外。
    open    //打开/dev/videox
    ioctl    //cmd VIDIOC_QUERYCAP, 获取driver name, front/back, orientation, capabilityies(capture, streming等), version.
        v4l_querycap    ->     v4l2-ioctl.c
        ops->vidioc_querycap ->
            soc_camera_querycap     ->    soc_camera.c
                ici->ops->querycap ->
                    rk29_camera_querycap ->    rk30_camera_oneframe.c
    ioctl -> CameraHal_module.cpp    //cmd: VIDIOC_TRY_FMT type:V4L2_BUF_TYPE_VIDEO_CAPTURE
        v4l_try_fmt ->    v4l2-ioctl.c
            ops->vidioc_try_fmt_vid_cap ->    //type: V4L2_BUF_TYPE_VIDEO_CAPTURE
                soc_camera_try_fmt_vid_cap ->     soc_camera.c
                    soc_camera_try_fmt ->
                        ici->ops->try_fmt ->
                            rk_camera_try_fmt ->    rk30_camera_oneframe.c
                                v4l2_subdev_call -> //args: try_mbus_fmt
                                    generic_sensor_try_fmt    //generic_sensor.c    
    new rk_cam_total_info    //所有sensor的信息都放在里面。
    new rk_DV_info     //每个分辨率都会new一个出来。
    ioctl ->     //cmd VIDIOC_ENUM_FRAMEINTERVALS    获取一个sensor各个分辨率对应的fps。
    ProduceNewXml    //重新生成 media_profiles.xml
                       
APP打开Camera:                        
camera_device_open -> CameraHal_Module.cpp    //提供上层ops,
    new android::CameraHal ->    //HAL层和上层的处理都用这个类实现了。
        commandThreadCommandQ //创建commandCmdQ的message queue.
        new IonMemManager    //申请ion内存
        new PreviewBufferProvider    //preview buffer
        new BufferProvider        //video buffer
        new BufferProvider        //Raw buffer
        new BufferProvider    //jpeg buffer
        new CameraSOCAdapter    //一般的isp camera, uvc camera是new CameraUSBAdapter
            CameraAdapter    //各种adapter的父类。
        new DisplayAdapter ->    //new一个显示相关的adapter
            displayThreadCommandQ    //创建名为displayCmdQ的message queue.
            new DisplayThread    //处理显示相关事物。
        new AppMsgNotifier ->
            encProcessThreadCommandQ //创建名字为pictureEncThreadQ的message queue.
            eventThreadCommandQ    //创建名字为eventThreadQ的message queue.
            create_vpu_memory_pool_allocator
            new CameraAppMsgThread
            new EncProcessThread
            new CameraAppFaceDetThread
            new CameraAppCallbackThread
        mCameraAdapter->initialize ->    
            CameraAdapter::initialize -> CameraAdapter.cpp
                cameraCreate ->    //找vpu, jpeg相关的库
                    open
                    ioctl     //cmd: VIDIOC_QUERYCAP
                    ioctl    //cmd: VIDIOC_ENUM_FMT
                        v4l_enum_fmt ->
                            ops->vidioc_enum_fmt_vid_cap -> //type: V4L2_BUF_TYPE_VIDEO_CAPTURE
                                soc_camera_enum_fmt_vid_cap soc_camera.c
                    mCamDriverPreviewFmt = CameraHal_SupportFmt    //找到hal和kernel都支持的preview format.
                    new AutoFocusThread
                initDefaultParameters ->    
                    CameraSOCAdapter::initDefaultParameters -> CameraSocAdapter.cpp    //初始化各个参数,preview size, picture size, zoom等。
                        ioctl ->  //cmd: VIDIOC_TRY_FMT
            new CommandThread ->
                CameraHal::commandThread    //loop线程。

设置参数:
CameraHal::setParameters    //参数是char*
    setParameters ->     //参数是CameraParameters
        commandThreadCommandQ.put    //cmd是 CMD_SET_PARAMETERS
            commandThread ->    
                mCameraAdapter->setParameters    
                    CameraSOCAdapter::setParameters ->    
                        mRefEventNotifier->setPreviewDataCbRes
                        cameraConfig

设置显示窗口:
CameraHal::setPreviewWindow ->
    commandThreadCommandQ.put ->    //cmd: CMD_SET_PREVIEW_WINDOW
        commandThread ->
            mDisplayAdapter->setPreviewWindow


Start preview:
CameraHal::startPreview ->
    new SensorListener
    mSensorListener->initialize ->
        SensorListener::initialize ->
                new Looper
                mLooper->addFd    //listener是sensor_events_listener
                new SensorLooperThread ->
                    threadLoop    ->
                        mLooper->pollOnce    //循环查询是否有event上报,有就会运行sensor_events_listener()获取Orientation。
                        
        mSensorListener->setCallbacks    //cb是gsensor_orientation_cb, 在handleOrientation()中调用,而sensor_events_listener()又会调用前者。
        mSensorListener->enableSensor  ->
            SensorManager::getInstanceForPackage
            mgr.getDefaultSensor    //不知道这里是如何获取的?
    commandThreadCommandQ.put -> //cmd: CMD_PREVIEW_START
        commandThread ->    
            mEventNotifier->stopReceiveFrame ->
                AppMsgNotifier::stopReceiveFrame ->
                    flushPicture ->
                        encProcessThreadCommandQ.put -> //cmd: EncProcessThread::CMD_ENCPROCESS_PAUSE
                            AppMsgNotifier::encProcessThread
                    pausePreviewCBFrameProcess ->
                        eventThreadCommandQ.put ->    //cmd: CameraAppMsgThread::CMD_EVENT_PAUSE
                            AppMsgNotifier::eventThread
                    stopFaceDection    //同上。
            mCameraAdapter->startPreview ->
                CameraAdapter::startPreview ->
                    mPreviewBufProvider->createBuffer ->    //type: PREVIEWBUFFER
                        mCamBuffer->createPreviewBuffer ->
                            IonMemManager::createPreviewBuffer ->
                                createIonBuffer
                    cameraSetSize ->
                        ioctl    //cmd: VIDIOC_S_FMT
                    cameraStart ->
                        ioctl //cmd:VIDIOC_REQBUFS
                        ioctl    //cmd: VIDIOC_QUERYBUF
                        mmap
                        ioctl    //cmd: VIDIOC_QBUF
                        cameraStream ->    //on
                            ioctl    //cmd: VIDIOC_STREAMON
                    new CameraPreviewThread ->
                        threadLoop ->
                            mPreivewCameraAdapter->previewThread     //进入preview thread loop
            mEventNotifier->startReceiveFrame
            mDisplayAdapter->startDisplay ->
                DisplayAdapter::startDisplay ->
                    displayThreadCommandQ.put ->    //cmd: CMD_DISPLAY_START
                        displayThread ->
                            cameraDisplayBufferDestory
                            cameraDisplayBufferCreate    //准备display buffer放frame,然后thread进入休眠等待frame的到来。
ioctl stream on后frame就会从kernel上来,接着调用previewthread:
CameraAdapter::previewThread ->
    getFrame ->    //获取一帧frame
        ioctl //cmd:VIDIOC_DQBUF    //过滤掉前面FILTER_FRAME_NUMBER 帧。
    mRefDisplayAdapter->notifyNewFrame ->
        DisplayAdapter::notifyNewFrame ->
            displayThreadCommandQ.put ->    //cmd: CMD_DISPLAY_FRAME
                DisplayAdapter::displayThread ->
                    mANativeWindow->dequeue_buffer
                    mANativeWindow->lock_buffer
                    mANativeWindow->enqueue_buffer
                    mFrameProvider->returnFrame
    returnFrame ->
        adapterReturnFrame //把使用好的buffer还给系统。
            
Stop preview:
camera_stop_preview ->
    gCameraHals[rk_dev->cameraid]->stopPreview ->
        CameraHal::stopPreview ->
            commandThreadCommandQ.put ->    //cmd: CMD_PREVIEW_STOP
                mDisplayAdapter->pauseDisplay ->
                    DisplayAdapter::pauseDisplay ->
                        displayThreadCommandQ.put ->    //cmd: CMD_DISPLAY_PAUSE
                            DisplayAdapter::displayThread ->
                                cameraDisplayBufferDestory ->
                                    mANativeWindow->cancel_buffer
                    mEventNotifier->stopReceiveFrame
                    mCameraAdapter->stopPreview ->
                        cameraStream ->    //off
                            ioctl    //cmd:VIDIOC_STREAMOFF
                        mCameraPreviewThread->requestExitAndWait    //等待preview thread 退出。
                        mPreviewBufProvider->freeBuffer

Take picture:(需要先执行上面的stop preview)
camera_disable_msg_type ->
    disableMsgType
camera_enable_msg_type ->
    enableMsgType
camera_take_picture ->
    gCameraHals[rk_dev->cameraid]->takePicture ->
        commandThreadCommandQ.put ->    //cmd: CMD_CONTINUOS_PICTURE
            CameraHal::commandThread ->    
                mDisplayAdapter->pauseDisplay ->
                    displayThreadCommandQ.put-> //cmd:CMD_DISPLAY_PAUSE
                        cameraDisplayBufferDestory
                selectPreferedDrvSize     //选择picture size, 如果和preview 分辨率不一样,那需要stop preview再start preview.
                mDisplayAdapter->pauseDisplay        //参照前面
                mEventNotifier->stopReceiveFrame    //参照前面
                mCameraAdapter->stopPreview        //参照上面stop preview流程
                mCameraAdapter->startPreview    //参照上面start preview流程
                fillPicturInfo
                mEventNotifier->takePicture ->
                    AppMsgNotifier::takePicture     //设置running state为STA_RECEIVE_PIC_FRAME,等着previewThread去get frame
                //previewThread接到frame之后
                CameraAdapter::previewThread ->
                    getFrame    //参照前面
                    mRefEventNotifier->isNeedSendToPicture      //此时条件成立
                    mRefEventNotifier->notifyNewPicFrame ->
                        AppMsgNotifier::notifyNewPicFrame ->
                            encProcessThreadCommandQ.put ->    //cmd: EncProcessThread::CMD_ENCPROCESS_SNAPSHOT
                                captureEncProcessPicture ->
                                    callback_notify_shutter ->    // 如果enable了CAMERA_MSG_SHUTTER的话调用此函数。
                                        AppMsgNotifier::callback_notify_shutter ->
                                            callbackThreadCommandQ.put    //cmd: CameraAppCallbackThread::CMD_MSG_SHUTTER
                                                AppMsgNotifier::callbackThread ->
                                                    mNotifyCb    //CAMERA_MSG_SHUTTER
                                    copyAndSendCompressedImage ->
                                        callback_compressed_image ->
                                            callbackThreadCommandQ.put ->    //cmd: CameraAppCallbackThread::CMD_MSG_COMPRESSED_IMAGE
                                                AppMsgNotifier::callbackThread ->
                                                    mDataCb    //CAMERA_MSG_COMPRESSED_IMAGE
                                                    frame->release
                                mFrameProvider->returnFrame

Record video:
CameraAdapter::previewThread ->
    getFrame
    mRefEventNotifier->notifyNewVideoFrame
        eventThreadCommandQ.put ->    //cmd: CameraAppMsgThread::CMD_EVENT_VIDEO_ENCING
            AppMsgNotifier::eventThread ->
                processVideoCb ->
                    AppMsgNotifier::processVideoCb ->
                        callback_video_frame ->
                            callbackThreadCommandQ.put ->    //cmd: CameraAppCallbackThread::CMD_MSG_VIDEO_FRAME
                                AppMsgNotifier::callbackThread ->
                                    mDataCbTimestamp
                    
                    
                    
Preview datacallback:
CameraAdapter::previewThread ->
    mRefEventNotifier->notifyNewPreviewCbFrame    ->    //前提是设置了callback回调函数
        AppMsgNotifier::notifyNewPreviewCbFrame ->
            eventThreadCommandQ.put ->    //cmd: CameraAppMsgThread::CMD_EVENT_PREVIEW_DATA_CB
                AppMsgNotifier::eventThread ->
                    processPreviewDataCb ->
                        AppMsgNotifier::processPreviewDataCb ->    //格式转换在这里完成
                            cameraFormatConvert
                            callback_preview_frame ->
                                callbackThreadCommandQ.put    ->    //cmd: CameraAppCallbackThread::CMD_MSG_PREVIEW_FRAME
                                    AppMsgNotifier::callbackThread ->
                                        mDataCb    //调用上层传递下来的callback.
                                        frame->release    //release buffer.
                    mFrameProvider->returnFrame


参考:

API版本: http://blog.csdn.net/gzzaigcnforever/article/details/48974523  

你可能感兴趣的:(子类__Camera)