CAMERA学习(二)--------HAL

上一篇文章中学习到加载camera.mt8127.so这个库文档,跟踪的是camera.open.下面我们来看下camera.mt8127.so中open的实现,继续上篇文章的跟进。

 

STEP 1:

\vendor\mediatek\proprietary\hardware\mtkcam\common\module_hal\module\module.h

 

static

camera_module

get_camera_module()

{

   camera_module module = {

       common:{

            tag                    :HARDWARE_MODULE_TAG,

            #if (PLATFORM_SDK_VERSION >= 21)

            module_api_version     :CAMERA_MODULE_API_VERSION_2_4,

            #else

            module_api_version     :CAMERA_DEVICE_API_VERSION_1_0,

            #endif

            hal_api_version        :HARDWARE_HAL_API_VERSION,

            id                     :CAMERA_HARDWARE_MODULE_ID,

            name                   : "MediaTek CameraModule",

            author                 :"MediaTek",

            methods                : get_module_methods(),

            dso                    : NULL,

            reserved               : {0},

       },

       get_number_of_cameras       :get_number_of_cameras,

       get_camera_info             :get_camera_info,

       set_callbacks               :set_callbacks,

       get_vendor_tag_ops          :get_vendor_tag_ops,

       #if (PLATFORM_SDK_VERSION >= 21)

       open_legacy                 :open_legacy,

       #endif

       set_torch_mode              :set_torch_mode,

       init                        :NULL,

       reserved                    : {0},

   };

   return  module;

};

 

STEP 2:

 

static

hw_module_methods_t*

get_module_methods()

{

   static

   hw_module_methods_t

   _methods =

    {

       open: open_device

   };

 

   return  &_methods;

}

 

 

Step 3:

 

static

int

open_device(hw_module_t const* module,const char* name, hw_device_t** device)

{

   return  NSCam::getCamDeviceManager()->open(device, module, name);

}

/*

getCamDeviceManager()->open在其父类CamDeviceManagerBase 中实现的;

classCamDeviceManagerImp : public CamDeviceManagerBase

namespace

{

    CamDeviceManagerImp gCamDeviceManager;

}   //namespace

 

 

/******************************************************************************

 *

 ******************************************************************************/

namespace NSCam {

ICamDeviceManager*

getCamDeviceManager()

{

    return &gCamDeviceManager;

}

}

*/

Step 4:

\vendor\mediatek\proprietary\hardware\mtkcam\common\module_hal\devicemgr\CamDeviceManagerBase.cpp

 

status_t

CamDeviceManagerBase::

open(

   hw_device_t** device,

   hw_module_t const* module,

   char const* name,

   uint32_t device_version

)

{

   int32_t const i4OpenId = (name != NULL) ? ::atoi(name) : -1;

   if  ( 0 == device_version ) {

       camera_info info;

       status_t status;

       if  ( OK != (status =getDeviceInfo(i4OpenId, info)) ) {

           return status;

       }

       device_version = info.device_version;

    }

   //

   RWLock::AutoWLock _l(mRWLock);

#if MTKCAM_HAVE_CAMERAMOUNT

   MY_LOGD("i4OpenId:%d mEnumMap.size:%d", i4OpenId,mEnumMap.size());

   if (i4OpenId >= mEnumMap.size() - 1) {

       return openExternalDevice(device, module, i4OpenId, device_version);

    }

#endif

   return  openDeviceLocked(device,module, i4OpenId, device_version);

}

 

Step 5:

\vendor\mediatek\proprietary\hardware\mtkcam\common\module_hal\devicemgr\

CamDeviceManagerBase.openDevice.cpp

status_t

CamDeviceManagerBase::

openDeviceLocked(

   hw_device_t** device,

   hw_module_t const* module,

   int32_t const i4OpenId,

   uint32_t device_version

)

{

   status_t status = OK;

   sp<ICamDevice> pDevice = NULL;

   //

   String8 const s8ClientAppMode = queryClientAppMode();

   //

   MY_LOGD(

       "+ OpenId:%d with version 0x%x - mOpenMap.size:%zumEnumMap.size:%zu",

       i4OpenId, device_version, mOpenMap.size(), mEnumMap.size()

   );

   //

   //  [1] check to see whether it'sready to open.

   if  ( OK != (status =validateOpenLocked(i4OpenId, device_version)) )

    {

       return  status;

    }

   //

   //  [2] get platform

   IPlatform*const pPlatform = getPlatform();

   if  ( ! pPlatform )

    {

       MY_LOGE("No Platform");

       return  -ENODEV;

    }

   //

   //  [3] create device based ondevice version.

   if  ( device_version ==CAMERA_DEVICE_API_VERSION_1_0 )

    {

       int i4DebugOpenID = -1;

       // try get property from system property

       char value[PROPERTY_VALUE_MAX] = {'\0'};

       property_get( "debug.camera.open", value, "-1");

       i4DebugOpenID = atoi(value);

       if( i4DebugOpenID != -1 )

       {

           pDevice =pPlatform->createCam1Device(s8ClientAppMode.string(), i4DebugOpenID);

/*

mDevice这里获取到的这个,就是对应\frameworks\av\services\camera\libcameraservice\device1\CameraHardwareInterface.hmDevice

 

也就是mDevice->ops对应于mDevice.ops    = (camera_device_ops*)&mDeviceOps;后面又将mDeviceOps      =gCameraDevOps;所有就是对应gCameraDevOps的相关操作:

staticmtk_camera_device_ops const

gCameraDevOps =

{

    #define OPS(name) name: camera_##name

 

    {

        OPS(set_preview_window),

        OPS(set_callbacks),

        OPS(enable_msg_type),

        OPS(disable_msg_type),

        OPS(msg_type_enabled),

        OPS(start_preview),

        OPS(stop_preview),

        OPS(preview_enabled),

        OPS(store_meta_data_in_buffers),

        OPS(start_recording),

        OPS(stop_recording),

        OPS(recording_enabled),

        OPS(release_recording_frame),

        OPS(auto_focus),

        OPS(cancel_auto_focus),

        OPS(take_picture),

        OPS(cancel_picture),

        OPS(set_parameters),

        OPS(get_parameters),

        OPS(put_parameters),

        OPS(send_command),

        OPS(release),

        OPS(dump)

    },

    OPS(mtk_set_callbacks),

 

    #undef OPS

};

*/

           MY_LOGD("force to open camera:%d", i4DebugOpenID);

       }

       else

       {

           // try get property from AP

           int i4DebugOpenID = -1;

           Utils::Property::tryGet(String8("debug.camera.open"),i4DebugOpenID);

           pDevice = pPlatform->createCam1Device(s8ClientAppMode.string(),i4DebugOpenID == -1 ? i4OpenId:i4DebugOpenID);

       }

      …..

   //  [4] open device successfully.

    {

       *device =const_cast<hw_device_t*>(pDevice->get_hw_device());

       //

       pDevice->set_hw_module(module);

       pDevice->set_module_callbacks(mpModuleCallbacks);

       pDevice->setDeviceManager(this);

       //

       attachDeviceLocked(pDevice, device_version);

    }

   //

   return  OK;

}

 

获取到了pDevice,意味着以后的操作都可以通过pDevice来完成,open的工作也就结束了。

 

 

下面我们再来跟进下JAVA里面的:mCameraDevice.startPreview();

 

Step 1:

 

mCameraDevice.startPreview();

/*

上篇文章已经有知道这个mCameraDevice就是对应的CameraClient的客户端,所以这个的startPreview就是CameraClient::startPreview()

*/

 

step 2:

\frameworks\av\services\camera\libcameraservice\api1\CameraClient.cpp

// start preview mode

status_t CameraClient::startPreview() {

   LOG1("startPreview (pid %d)", getCallingPid());

   return startCameraMode(CAMERA_PREVIEW_MODE);

}

 

Step 3:

 

// start preview or recording

status_tCameraClient::startCameraMode(camera_mode mode) {

   LOG1("startCameraMode(%d)", mode);

   Mutex::Autolock lock(mLock);

   status_t result = checkPidAndHardware();

   if (result != NO_ERROR) return result;

 

   switch(mode) {

       case CAMERA_PREVIEW_MODE:

           if (mSurface == 0 && mPreviewWindow == 0) {

                LOG1("mSurface is not setyet.");

                // still able to start previewin this case.

           }

           return startPreviewMode();

       case CAMERA_RECORDING_MODE:

           if (mSurface == 0 && mPreviewWindow == 0) {

                ALOGE("mSurface ormPreviewWindow must be set before startRecordingMode.");

                return INVALID_OPERATION;

           }

           return startRecordingMode();

       default:

           return UNKNOWN_ERROR;

    }

}

 

Step 4:

 

 

status_t CameraClient::startPreviewMode() {

   LOG1("startPreviewMode");

   status_t result = NO_ERROR;

 

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

   if (mHardware->previewEnabled()) {

       return NO_ERROR;

    }

 

   if (mPreviewWindow != 0) {

       native_window_set_scaling_mode(mPreviewWindow.get(),

               NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);

       native_window_set_buffers_transform(mPreviewWindow.get(),

                mOrientation);

    }

    mHardware->setPreviewWindow(mPreviewWindow);

    result = mHardware->startPreview();

/*

这里仅仅学习CAMERA的控制流程,数据的流程以后在学习,这个不讨论,前面有知道这个mHardware就是对应的CameraHardwareInterface

CameraClient.h中的定义:

    sp<CameraHardwareInterface>     mHardware;       // cleared after disconnect()

*/

   return result;

}

 

Step 5:

\frameworks\av\services\camera\libcameraservice\device1\CameraHardwareInterface.h

   status_t startPreview()

    {

       ALOGV("%s(%s)", __FUNCTION__, mName.string());

       if (mDevice->ops->start_preview)

           return mDevice->ops->start_preview(mDevice);

/*

上篇已经分析过了,这个mDevice对应的就是Cam1Device

\vendor\mediatek\proprietary\hardware\mtkcam\middleware\common\v1\device\Cam1Device.cpp

进入到HAL层。

*/

       return INVALID_OPERATION;

}

 

Step 6:

 

\vendor\mediatek\proprietary\hardware\mtkcam\middleware\common\v1\device\Cam1Device.cpp

 

 

staticmtk_camera_device_ops const

gCameraDevOps =

{

    #define OPS(name) name: camera_##name

 

    {

        OPS(set_preview_window),

        OPS(set_callbacks),

        OPS(enable_msg_type),

        OPS(disable_msg_type),

        OPS(msg_type_enabled),

        OPS(start_preview),

        OPS(stop_preview),

        OPS(preview_enabled),

        OPS(store_meta_data_in_buffers),

        OPS(start_recording),

        OPS(stop_recording),

        OPS(recording_enabled),

        OPS(release_recording_frame),

        OPS(auto_focus),

        OPS(cancel_auto_focus),

        OPS(take_picture),

        OPS(cancel_picture),

        OPS(set_parameters),

        OPS(get_parameters),

        OPS(put_parameters),

        OPS(send_command),

        OPS(release),

        OPS(dump)

    },

    OPS(mtk_set_callbacks),

 

    #undef OPS

};

 

Step 7:

\vendor\mediatek\proprietary\hardware\mtkcam\middleware\common\v1\device\Cam1DeviceBase.cpp

 

/*

在其父类中实现

*/

status_t

Cam1DeviceBase::

startPreview()

{

    CAM_TRACE_CALL();

    MY_LOGI("+");

    //

    status_t status = OK;

    bool usePreviewThread = false;

    //

    if(mpParamsMgr->getIfFirstPreviewFrameAsBlack() &&

        mbWindowReady == false)

    {

        usePreviewThread = true;

        disableWaitSensorThread(true);

    }

    //

    {

       CAM_TRACE_NAME("deviceStartPreview");

        if ( mpCamAdapter != 0 && mpCamAdapter->isTakingPicture() )

        {

            MY_LOGE("Capture is notdone");

            status = INVALID_OPERATION;

            return  status;

        }

        //

        if ( previewEnabled() )

        {

            MY_LOGD("Preview alreadyrunning");

            status = ALREADY_EXISTS;

            return  status;

        }

        //

        if ( ! onStartPreview() )

        {

           MY_LOGE("onStartPreviewLocked() fail");

            status = INVALID_OPERATION;

            goto lbExit;

        }

    }

    //

    {

       CAM_TRACE_NAME("clientStartPreview");

        if ( mpDisplayClient == 0 )

        {

            MY_LOGD("DisplayClient is notready.");

        }

        else if ( OK != (status =enableDisplayClient()) )

        {

            goto lbExit;

        }

        //

        if ( mpCamClient != 0 )

        {

            if ( ! mpCamClient->startPreview() )

            {

                status = INVALID_OPERATION;

                goto lbExit;

            }

        }

       …….

 

Step 8:

\vendor\mediatek\proprietary\hardware\mtkcam\middleware\common\v1\client\CamClient\CamClient.cpp

 

bool

CamClient::

startPreview()

{

    bool ret = false;

    //

    MY_LOGD("+");

    // (1) Lock

    Mutex::Autolock _l(mModuleMtx);

    //

    if  (mpFDClient != 0 )

    {

        mpFDClient->startPreview();

    }

    if  (mpPreviewClient != 0 && ! mpPreviewClient->startPreview())

    {

        goto lbExit;

    }

    //

    if  (mpRecordClient != 0 && ! mpRecordClient->startPreview() )

    {

        goto lbExit;

    }

    //

    mbPreviewEnabled = true;

    ret = true;

lbExit:

    MY_LOGD("- ret(%d)", ret);

    return ret;

}

Step 9:

\vendor\mediatek\proprietary\hardware\mtkcam\middleware\common\v1\client\CamClient\PreviewCallback\PreviewClient.cpp

 

bool

PreviewClient::

startPreview()

{

    {

        Mutex::Autolock _l(mModuleMtx);

        MY_LOGD("+ currentmIsPrvStarted=%d", mIsPrvStarted);

        ::android_atomic_write(1,&mIsPrvStarted);

        //

        ms8PrvTgtFmt = mpParamsMgr->getPreviewFormat();

       mpParamsMgr->getPreviewSize(&mi4PrvWidth, &mi4PrvHeight);

        //

        MY_LOGD("+ preview: WxH=%dx%d,format(%s)", mi4PrvWidth, mi4PrvHeight, ms8PrvTgtFmt.string());

    }

    //

    initBuffers();

    //

    return  onStateChanged();

}

 

转了这么一大圈,好像也没有搞明白到底是如何预留图像的。还有疑问的有下面几点:

1,  HAL层中如何与KERNEL的驱动关联起来的。

2,  数据是如何传输的。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值