Android Camera 通过V4L2与kernel driver的完整交互过程


之前在 Android Camera 的执行流程 http://blog.chinaunix.net/uid-26765074-id-3499537.html 这篇文章中已经详细介绍了
Android Camera app到调用open打开camera 设备的完成过程,但是只是到此为止,并未对较底层的操作控制等做任何分析,
今天就要进入这个环节了

这里就直接从open那个方法开始了,先说一下这个open是怎么被调用的

实例化Camera Hal接口 hardware,hardware调用initialize()进入HAL层打开Camear驱动。
CameraHardwareInterface中initialize()定义在以下路径:frameworks/base/services/camera/libcameraservice/CameraHardwareInterface.h

代码如下:

status_t initialize(hw_module_t *module)
{
LOGI("Opening camera %s", mName.string());
int rc = module->methods->open(module, mName.string(),(hw_device_t **)&mDevice);
if (rc != OK) {
LOGE("Could not open camera %s: %d", mName.string(), rc);
return rc;
}
#ifdef OMAP_ENHANCEMENT_CPCAM
initHalPreviewWindow(&mHalPreviewWindow);
initHalPreviewWindow(&mHalTapin);
initHalPreviewWindow(&mHalTapout);
#else
initHalPreviewWindow();
#endif
return rc;
}
此处通过module->method->open()方法真正打开Camera设备,

其中module的定义在以下路径:frameworks/base/services/camera/libcameraservice/CameraService.h

class CameraService :
public BinderService<CameraService>,
public BnCameraService
{

class Client : public BnCamera
{
public:
......

private:

.....

};

camera_module_t *mModule;

};

此处还必须找到camera_module_t的定,以更好的理解整个运行流程,通过追根溯源找到了camera_module_t定义,

camera_module_t的定义在以下路径:hardware/libhardware/include/hardware/camera.h

typedef struct camera_module {
hw_module_t common;
int (*get_number_of_cameras)(void);
int (*get_camera_info)(int camera_id, struct camera_info *info);
} camera_module_t;
其中包含get_number_of_cameras方法和get_camera_info方法用于获取camera info

另外hw_module_t common;这个选项十分重要,此处应重点关注,因为是使用hw_module_t结构体中的open()方法打开设备文件的

继续找到hw_module_t 结构体的定义.在以下路径:hardware/libhardware/include/hardware/hardware.h


  1. typedef struct hw_module_t{
  2. /**tag must be initializedtoHARDWARE_MODULE_TAG*/
  3. uint32_t tag;

  4. /**major version numberforthe module*/
  5. uint16_t version_major;

  6. /**minor version number of the module*/
  7. uint16_t version_minor;

  8. /**Identifier of module*/
  9. constchar*id;

  10. /**Name of this module*/
  11. constchar*name;

  12. /**Author/owner/implementor of the module*/
  13. constchar*author;

  14. /**Modules methods*/
  15. struct hw_module_methods_t*methods;

  16. /**module's dso*/
  17. void*dso;

  18. /**paddingto128 bytes,reservedforfuture use*/
  19. uint32_t reserved[32-7];

  20. }hw_module_t;
  1. typedef struct hw_module_methods_t{
  2. /**Open a specific device*/
  3. int(*open)(conststruct hw_module_t*module,constchar*id,
  4. struct hw_device_t**device);

  5. }hw_module_methods_t;

这里的这个open方法才是我们真正调用的open方法,那么这里只是定义,他又是在哪里实现的呢??
这个问题我们还是需要往前面追溯啊,当然这在上一篇文章中也没有提到,不卖关子了,其实重点就是我们调用了这个module->methods->open(module, mName.string(),(hw_device_t **)&mDevice)方法
但是这个module是在哪里初始化的呢?看看CameraService类里的这个方法吧,路径:frameworks/base/services/camera/libcameraservice/CameraService.cpp

  1. void CameraService::onFirstRef()
  2. {
  3. BnCameraService::onFirstRef();

  4. if(hw_get_module(CAMERA_HARDWARE_MODULE_ID,
  5. (consthw_module_t**)&mModule)<0){
  6. LOGE("Could not load camera HAL module");
  7. mNumberOfCameras=0;
  8. }
  9. else{
  10. mNumberOfCameras=mModule->get_number_of_cameras();
  11. if(mNumberOfCameras>MAX_CAMERAS){
  12. LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
  13. mNumberOfCameras,MAX_CAMERAS);
  14. mNumberOfCameras=MAX_CAMERAS;
  15. }
  16. for(inti=0;i<mNumberOfCameras;i++){
  17. setCameraFree(i);
  18. }
  19. }
  20. }

不错,这个module正是通过这个 hw_get_module方法获得的,其实他是通过方法中的 CAMERA_HARDWARE_MODULE_ID作为flag最终找到已经定义好的module,那么这个已经定义好的module又在哪呢,是什么样子的呢?
这里我就直接放在这里,不在拐弯抹角了,方法路径: hardware/ti/omap4xxx/camera/CameraHal_Module.cpp

  1. staticintcamera_device_open(consthw_module_t*module,constchar*name,
  2. hw_device_t**device);
  3. staticintcamera_device_close(hw_device_t*device);
  4. staticintcamera_get_number_of_cameras(void);
  5. staticintcamera_get_camera_info(intcamera_id,struct camera_info*info);

  6. static struct hw_module_methods_t camera_module_methods={
  7. open:camera_device_open
  8. };

  9. camera_module_t HAL_MODULE_INFO_SYM={
  10. common:{
  11. tag:HARDWARE_MODULE_TAG,
  12. version_major:1,
  13. version_minor:0,
  14. id:CAMERA_HARDWARE_MODULE_ID,
  15. name:"TI OMAP CameraHal Module",
  16. author:"TI",
  17. methods:&camera_module_methods,
  18. dso:NULL,/*remove compilation warnings*/
  19. reserved:{0},/*remove compilation warnings*/
  20. },
  21. get_number_of_cameras:camera_get_number_of_cameras,
  22. get_camera_info:camera_get_camera_info,
  23. };

这里还是很关键的,通过id: CAMERA_HARDWARE_MODULE_ID 作为识别码找到这个module,get module完成任务,大家可以看到,这个定义好的module实现了methods中的open方法,
实现了 camera_get_number_of_cameras camera_get_camera_info ,当然还包括了其他一些变量的初始化
这里开始我们找到了我们真正需要的open方法,万里长征走完一大步了,现在就去看看这个open方法干了些什么吧

  1. /*open device handletoone of the cameras
  2. *
  3. *assume camera service will keep singleton ofeachcamera
  4. *so thisfunctionwill always only be called once per camera instance
  5. */

  6. intcamera_device_open(consthw_module_t*module,constchar*name,
  7. hw_device_t**device)
  8. {
  9. intrv=0;
  10. intnum_cameras=0;
  11. intcameraid;
  12. ti_camera_device_t*camera_device=NULL;
  13. camera_device_ops_t*camera_ops=NULL;
  14. android::CameraHal*camera=NULL;
  15. android::CameraProperties::Properties*properties=NULL;

  16. android::Mutex::Autolock lock(gCameraHalDeviceLock);

  17. CAMHAL_LOGI("camera_device open");

  18. if(name!=NULL){
  19. cameraid=atoi(name);
  20. num_cameras=gCameraProperties.camerasSupported();

  21. if(cameraid>num_cameras)
  22. {
  23. LOGE("camera service provided cameraid out of bounds, "
  24. "cameraid = %d, num supported = %d",
  25. cameraid,num_cameras);
  26. rv=-EINVAL;
  27. goto fail;
  28. }

  29. if(gCamerasOpen>=MAX_SIMUL_CAMERAS_SUPPORTED)
  30. {
  31. LOGE("maximum number of cameras already open");
  32. rv=-ENOMEM;
  33. goto fail;
  34. }

  35. camera_device=(ti_camera_device_t*)malloc(sizeof(*camera_device));
  36. if(!camera_device)
  37. {
  38. LOGE("camera_device allocation fail");
  39. rv=-ENOMEM;
  40. goto fail;
  41. }

  42. camera_ops=(camera_device_ops_t*)malloc(sizeof(*camera_ops));
  43. if(!camera_ops)
  44. {
  45. LOGE("camera_ops allocation fail");
  46. rv=-ENOMEM;
  47. goto fail;
  48. }

  49. memset(camera_device,0,sizeof(*camera_device));
  50. memset(camera_ops,0,sizeof(*camera_ops));

  51. camera_device->base.common.tag=HARDWARE_DEVICE_TAG;
  52. camera_device->base.common.version=0;
  53. camera_device->base.common.module=(hw_module_t*)(module);
  54. camera_device->base.common.close=camera_device_close;
  55. camera_device->base.ops=camera_ops;

  56. camera_ops->set_preview_window=camera_set_preview_window;
  57. #ifdef OMAP_ENHANCEMENT_CPCAM
  58. camera_ops->set_buffer_source=camera_set_buffer_source;
  59. #endif
  60. camera_ops->set_callbacks=camera_set_callbacks;
  61. camera_ops->enable_msg_type=camera_enable_msg_type;
  62. camera_ops->disable_msg_type=camera_disable_msg_type;
  63. camera_ops->msg_type_enabled=camera_msg_type_enabled;
  64. camera_ops->start_preview=camera_start_preview;
  65. camera_ops->stop_preview=camera_stop_preview;
  66. camera_ops->preview_enabled=camera_preview_enabled;
  67. camera_ops->store_meta_data_in_buffers=camera_store_meta_data_in_buffers;
  68. camera_ops->start_recording=camera_start_recording;
  69. camera_ops->stop_recording=camera_stop_recording;
  70. camera_ops->recording_enabled=camera_recording_enabled;
  71. camera_ops->release_recording_frame=camera_release_recording_frame;
  72. camera_ops->auto_focus=camera_auto_focus;
  73. camera_ops->cancel_auto_focus=camera_cancel_auto_focus;
  74. camera_ops->take_picture=camera_take_picture;
  75. camera_ops->cancel_picture=camera_cancel_picture;
  76. camera_ops->set_parameters=camera_set_parameters;
  77. camera_ops->get_parameters=camera_get_parameters;
  78. camera_ops->put_parameters=camera_put_parameters;
  79. camera_ops->send_command=camera_send_command;
  80. camera_ops->release=camera_release;
  81. camera_ops->dump=camera_dump;
  82. #ifdef OMAP_ENHANCEMENT_CPCAM
  83. camera_ops->reprocess=camera_reprocess;
  84. camera_ops->cancel_reprocess=camera_cancel_reprocess;
  85. #endif

  86. *device=&camera_device->base.common;

  87. //--------TI specific stuff--------

  88. camera_device->cameraid=cameraid;

  89. if(gCameraProperties.getProperties(cameraid,&properties)<0)
  90. {
  91. LOGE("Couldn't get camera properties");
  92. rv=-ENOMEM;
  93. goto fail;
  94. }

  95. camera=new android::CameraHal(cameraid);

  96. if(!camera)
  97. {
  98. LOGE("Couldn't create instance of CameraHal class");
  99. rv=-ENOMEM;
  100. goto fail;
  101. }

  102. if(properties&&(camera->initialize(properties)!=android::NO_ERROR))
  103. {
  104. LOGE("Couldn't initialize camera instance");
  105. rv=-ENODEV;
  106. goto fail;
  107. }

  108. gCameraHals[cameraid]=camera;
  109. gCamerasOpen++;
  110. }

  111. return rv;

  112. fail:
  113. if(camera_device){
  114. free(camera_device);
  115. camera_device=NULL;
  116. }
  117. if(camera_ops){
  118. free(camera_ops);
  119. camera_ops=NULL;
  120. }
  121. if(camera){
  122. delete camera;
  123. camera=NULL;
  124. }
  125. *device=NULL;
  126. return rv;
  127. }

看看这么长的代码,open的任务还是比较中的,没办法,能者多劳嘛,红色部分是最重点的部分
从这里可以知道,这里就像一个控制中心,上传调用到这里被分发出去,实现各自的操作,我们就以 startPreview 为例进行分析

  1. intcamera_start_preview(struct camera_device*device)
  2. {
  3. intrv=-EINVAL;
  4. ti_camera_device_t*ti_dev=NULL;

  5. LOGV("%s",__FUNCTION__);

  6. if(!device)
  7. return rv;

  8. ti_dev=(ti_camera_device_t*)device;

  9. rv=gCameraHals[ti_dev->cameraid]->startPreview();

  10. return rv;
  11. }

这里每open一个device就会相应的创建并且初始化一个CameraHal 对象,定义在: hardware/ti/omap4xxx/camera/CameraHal.cpp
并且把这个对象保存在gCameraHals这个数组中,正因为这样这里 camera_start_preview 才可以通过这个数据检索对象调用方法
现在我们就看看这个 startPreview ( ) 方法是怎样实现的

  1. /**
  2. @brief Start preview mode.

  3. @param none
  4. @return NO_ERROR Camera switchedtoVF mode
  5. @todo Updatefunctionheader with the different errors that are possible

  6. */
  7. status_t CameraHal::startPreview(){
  8. LOG_FUNCTION_NAME;

  9. //When tunnelingisenabled during VTC,startPreview happensin2 steps:
  10. //When the application sends the command CAMERA_CMD_PREVIEW_INITIALIZATION,
  11. //cameraPreviewInitialization()iscalled,whichinturn causes the CameraAdapter
  12. //tomove from loadedtoidle state.Andwhen the application calls startPreview,
  13. //the CameraAdapter moves from idletoexecuting state.
  14. //
  15. //Ifthe application calls startPreview()without sending the command
  16. //CAMERA_CMD_PREVIEW_INITIALIZATION,thenthefunctioncameraPreviewInitialization()
  17. //ANDstartPreview()are executed.Inother words,ifthe application calls
  18. //startPreview()without sending the command CAMERA_CMD_PREVIEW_INITIALIZATION,
  19. //thenthe CameraAdapter moves from loadedtoidletoexecuting stateinone shot.
  20. status_t ret=cameraPreviewInitialization();

  21. //The flag mPreviewInitializationDoneissettotrueat theendof thefunction
  22. //cameraPreviewInitialization().Therefore,ifeverything goes alright,thenthe
  23. //flag will beset.Sometimes,thefunctioncameraPreviewInitialization()may
  24. //return prematurelyifall the resources arenotavailableforstarting preview.
  25. //Forexample,ifthe previewwindowisnotset,thenit would return NO_ERROR.
  26. //Under such circumstances,one should return from startPreview as wellandshould
  27. //notcontinue execution.Thatiswhy,we check the flagandnotthe return value.
  28. if(!mPreviewInitializationDone)return ret;

  29. //Once startPreviewiscalled,thereisno needtocontinuetoremember whether
  30. //thefunctioncameraPreviewInitialization()was called earlierornot.Andso
  31. //the flag mPreviewInitializationDoneisreset here.Plus,this preserves the
  32. //current behavior of startPreview under the circumstances where the application
  33. //calls startPreview twiceormore.
  34. mPreviewInitializationDone=false;

  35. ///Enable the display adapterifpresent,actual overlay enable happens when we post the buffer
  36. if(mDisplayAdapter.get()!=NULL){
  37. CAMHAL_LOGDA("Enabling display");
  38. intwidth,height;
  39. mParameters.getPreviewSize(&width,&height);

  40. #ifPPM_INSTRUMENTATION||PPM_INSTRUMENTATION_ABS
  41. ret=mDisplayAdapter->enableDisplay(width,height,&mStartPreview);
  42. #else
  43. ret=mDisplayAdapter->enableDisplay(width,height,NULL);
  44. #endif

  45. if(ret!=NO_ERROR){
  46. CAMHAL_LOGEA("Couldn't enable display");

  47. //FIXME:At this stage mStateSwitchLockislockedandunlockissupposedtobe called
  48. //only from mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW)
  49. //below.But this will never happen because of gotoerror.Thus atnext
  50. //startPreview()callCameraHAL will be deadlocked.
  51. //Needtorevisit mStateSwitch lock,fornowjust abort the process.
  52. CAMHAL_ASSERT_X(false,
  53. "At this stage mCameraAdapter->mStateSwitchLock is still locked, "
  54. "deadlock is guaranteed");

  55. gotoerror;
  56. }

  57. }

  58. ///Send START_PREVIEW commandtoadapter
  59. CAMHAL_LOGDA("Starting CameraAdapter preview mode");

  60. ret=mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW);

  61. if(ret!=NO_ERROR){
  62. CAMHAL_LOGEA("Couldn't start preview w/ CameraAdapter");
  63. gotoerror;
  64. }
  65. CAMHAL_LOGDA("Started preview");

  66. mPreviewEnabled=true;
  67. mPreviewStartInProgress=false;
  68. return ret;

  69. error:

  70. CAMHAL_LOGEA("Performing cleanup after error");

  71. //Doall the cleanup
  72. freePreviewBufs();
  73. mCameraAdapter->sendCommand(CameraAdapter::CAMERA_STOP_PREVIEW);
  74. if(mDisplayAdapter.get()!=NULL){
  75. mDisplayAdapter->disableDisplay(false);
  76. }
  77. mAppCallbackNotifier->stop();
  78. mPreviewStartInProgress=false;
  79. mPreviewEnabled=false;
  80. LOG_FUNCTION_NAME_EXIT;

  81. return ret;
  82. }

在我的理解看来上面标注的部分是这个方法的关键,这个地方可是会让初次研究这里的人晕头转向的,因为我就在这里犯了错误,走岔道了,下面会说明到底是怎么走岔道的
先说一下吧,这里调用 mCameraAdapter 对象的 sendCommand 方法

  1. status_t BaseCameraAdapter::sendCommand(CameraCommands operation,intvalue1,intvalue2,intvalue3,intvalue4){
  2. status_t ret=NO_ERROR;
  3. struct timeval*refTimestamp;
  4. BuffersDescriptor*desc=NULL;
  5. CameraFrame*frame=NULL;

  6. LOG_FUNCTION_NAME;

  7. switch(operation){
  8. case:
  9. ...............
  10. case CameraAdapter::CAMERA_START_PREVIEW:
    {
    CAMHAL_LOGDA("Start Preview");
    if ( ret == NO_ERROR )
    {
    ret = setState(operation);
    }

    if ( ret == NO_ERROR )
    {
    ret = startPreview();
    }

    if ( ret == NO_ERROR )
    {
    ret = commitState();
    }else{
    ret |= rollbackState();
    }
    break;
    }
  11. }
  12. }
  1. status_t BaseCameraAdapter::setState(CameraCommands operation)
  2. {
  3. status_t ret=NO_ERROR;

  4. LOG_FUNCTION_NAME;

  5. constchar*printState=getLUTvalue_translateHAL(operation,CamCommandsLUT);

  6. mLock.lock();

  7. switch(mAdapterState)
  8. {

  9. caseINTIALIZED_STATE:
  10. ............

  11. caseLOADED_PREVIEW_STATE:

  12. switch(operation)
  13. {

  14. caseCAMERA_START_PREVIEW:
  15. CAMHAL_LOGDB("Adapter state switch LOADED_PREVIEW_STATE->PREVIEW_STATE event = %s",
  16. printState);
  17. mNextState=PREVIEW_STATE;
  18. break;
  19. }
  20. }
  21. }
  1. status_t BaseCameraAdapter::startPreview()
  2. {
  3. status_t ret=NO_ERROR;

  4. LOG_FUNCTION_NAME;

  5. LOG_FUNCTION_NAME_EXIT;

  6. return ret;
  7. }

就是这里了,所以我用可很醒目的颜色标注出来,很多人会想当然的理解,你不是调用了 startPreview 方法嘛,那就是他了啊!可是这里为什么什么动作都没做呢??
于是就卡在这里不知所措了,那个纠结啊
现在就来解开这个谜团吧!!!

这个我们还是要往前追溯了,追溯到哪里呢??那就从这里开始吧
mCameraAdapter - > sendCommand ( CameraAdapter : : CAMERA_START_PREVIEW ) ;
这个方式是在 CameraHal startPreview ( ) 方法中 被调用的
所以我要知道这个 mCameraAdapter 对象原型是什么啊,他从哪里而来,原来他是 CameraHal 这个类的一个成员,定义在: hardware/ti/omap4xxx/camera/inc/CameraHal.h
CameraAdapter *mCameraAdapter;
这里必须打破砂锅追到底,找到 CameraAdapter 这个类的定义,他的定义同样这这个.h文件中

  1. /**
  2. *CameraAdapter interfaceclass
  3. *Concrete classes derive from thisclassandprovide implementations basedonthe specific camera h/w interface
  4. */

  5. classCameraAdapter:publicFrameNotifier,publicvirtual RefBase
  6. {
  7. protected:
  8. enum AdapterActiveStates{
  9. INTIALIZED_ACTIVE=1<<0,
  10. LOADED_PREVIEW_ACTIVE=1<<1,
  11. PREVIEW_ACTIVE=1<<2,
  12. LOADED_CAPTURE_ACTIVE=1<<3,
  13. CAPTURE_ACTIVE=1<<4,
  14. BRACKETING_ACTIVE=1<<5,
  15. AF_ACTIVE=1<<6,
  16. ZOOM_ACTIVE=1<<7,
  17. VIDEO_ACTIVE=1<<8,
  18. LOADED_REPROCESS_ACTIVE=1<<9,
  19. REPROCESS_ACTIVE=1<<10,
  20. };
  21. public:
  22. typedef struct
  23. {
  24. CameraBuffer*mBuffers;
  25. uint32_t*mOffsets;
  26. intmFd;
  27. size_t mLength;
  28. size_t mCount;
  29. size_t mMaxQueueable;
  30. }BuffersDescriptor;

  31. enum CameraCommands
  32. {
  33. CAMERA_START_PREVIEW=0,
  34. CAMERA_STOP_PREVIEW=1,
  35. CAMERA_START_VIDEO=2,
  36. CAMERA_STOP_VIDEO=3,
  37. CAMERA_START_IMAGE_CAPTURE=4,
  38. CAMERA_STOP_IMAGE_CAPTURE=5,
  39. CAMERA_PERFORM_AUTOFOCUS=6,
  40. CAMERA_CANCEL_AUTOFOCUS=7,
  41. CAMERA_PREVIEW_FLUSH_BUFFERS=8,
  42. CAMERA_START_SMOOTH_ZOOM=9,
  43. CAMERA_STOP_SMOOTH_ZOOM=10,
  44. CAMERA_USE_BUFFERS_PREVIEW=11,
  45. CAMERA_SET_TIMEOUT=12,
  46. CAMERA_CANCEL_TIMEOUT=13,
  47. CAMERA_START_BRACKET_CAPTURE=14,
  48. CAMERA_STOP_BRACKET_CAPTURE=15,
  49. CAMERA_QUERY_RESOLUTION_PREVIEW=16,
  50. CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE=17,
  51. CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA=18,
  52. CAMERA_USE_BUFFERS_IMAGE_CAPTURE=19,
  53. CAMERA_USE_BUFFERS_PREVIEW_DATA=20,
  54. CAMERA_TIMEOUT_EXPIRED=21,
  55. CAMERA_START_FD=22,
  56. CAMERA_STOP_FD=23,
  57. CAMERA_SWITCH_TO_EXECUTING=24,
  58. CAMERA_USE_BUFFERS_VIDEO_CAPTURE=25,
  59. #ifdef OMAP_ENHANCEMENT_CPCAM
  60. CAMERA_USE_BUFFERS_REPROCESS=26,
  61. CAMERA_START_REPROCESS=27,
  62. #endif
  63. #ifdef OMAP_ENHANCEMENT_VTC
  64. CAMERA_SETUP_TUNNEL=28,
  65. CAMERA_DESTROY_TUNNEL=29,
  66. #endif
  67. CAMERA_PREVIEW_INITIALIZATION=30,
  68. };

  69. enum CameraMode
  70. {
  71. CAMERA_PREVIEW,
  72. CAMERA_IMAGE_CAPTURE,
  73. CAMERA_VIDEO,
  74. CAMERA_MEASUREMENT,
  75. CAMERA_REPROCESS,
  76. };

  77. enum AdapterState{
  78. INTIALIZED_STATE=INTIALIZED_ACTIVE,
  79. LOADED_PREVIEW_STATE=LOADED_PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  80. PREVIEW_STATE=PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  81. LOADED_CAPTURE_STATE=LOADED_CAPTURE_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  82. CAPTURE_STATE=CAPTURE_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  83. BRACKETING_STATE=BRACKETING_ACTIVE|CAPTURE_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  84. AF_STATE=AF_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  85. ZOOM_STATE=ZOOM_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  86. VIDEO_STATE=VIDEO_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  87. VIDEO_AF_STATE=VIDEO_ACTIVE|AF_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  88. VIDEO_ZOOM_STATE=VIDEO_ACTIVE|ZOOM_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  89. VIDEO_LOADED_CAPTURE_STATE=VIDEO_ACTIVE|LOADED_CAPTURE_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  90. VIDEO_CAPTURE_STATE=VIDEO_ACTIVE|CAPTURE_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  91. AF_ZOOM_STATE=AF_ACTIVE|ZOOM_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  92. BRACKETING_ZOOM_STATE=BRACKETING_ACTIVE|ZOOM_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  93. LOADED_REPROCESS_STATE=LOADED_REPROCESS_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  94. LOADED_REPROCESS_CAPTURE_STATE=LOADED_REPROCESS_ACTIVE|LOADED_CAPTURE_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  95. REPROCESS_STATE=REPROCESS_ACTIVE|CAPTURE_ACTIVE|PREVIEW_ACTIVE|INTIALIZED_ACTIVE,
  96. };


  97. public:

  98. ///Initialzes the camera adapter creates any resources required
  99. virtualintinitialize(CameraProperties::Properties*)=0;

  100. virtualintsetErrorHandler(ErrorNotifier*errorNotifier)=0;

  101. //Message/Frame notification APIs
  102. virtual void enableMsgType(int32_t msgs,
  103. frame_callback callback=NULL,
  104. event_callback eventCb=NULL,
  105. void*cookie=NULL)=0;
  106. virtual void disableMsgType(int32_t msgs,void*cookie)=0;
  107. virtual void returnFrame(CameraBuffer*frameBuf,CameraFrame::FrameType frameType)=0;
  108. virtual void addFramePointers(CameraBuffer*frameBuf,void*buf)=0;
  109. virtual void removeFramePointers()=0;

  110. //APIstoconfigure Camera adapterandgetthe current parameterset
  111. virtualintsetParameters(constCameraParameters&params)=0;
  112. virtual void getParameters(CameraParameters&params)=0;

  113. //Registers callbackforreturning image buffers backtoCameraHAL
  114. virtualintregisterImageReleaseCallback(release_image_buffers_callback callback,void*user_data)=0;

  115. //Registers callback,which signals a completed image capture
  116. virtualintregisterEndCaptureCallback(end_image_capture_callback callback,void*user_data)=0;

  117. //APItosend a commandtothe camera
  118. virtual status_t sendCommand(CameraCommands operation,intvalue1=0,intvalue2=0,intvalue3=0,intvalue4=0)=0;

  119. virtual~CameraAdapter(){};

  120. //Retrieves the current Adapter state
  121. virtual AdapterState getState()=0;

  122. //Retrieves thenextAdapter state
  123. virtual AdapterState getNextState()=0;

  124. //Receive orientation events from CameraHal
  125. virtual void onOrientationEvent(uint32_t orientation,uint32_t tilt)=0;

  126. //Rolls the state machine backtoINTIALIZED_STATE from the current state
  127. virtual status_t rollbackToInitializedState()=0;

  128. //Retrieves the current Adapter state-forinternal use(notlocked)
  129. virtual status_t getState(AdapterState&state)=0;
  130. //Retrieves thenextAdapter state-forinternal use(notlocked)
  131. virtual status_t getNextState(AdapterState&state)=0;

  132. protected:
  133. //The first two methods will trytoswitch the adapter state.
  134. //EverycalltosetState()should be followed by a corresponding
  135. //calltocommitState().Ifthe state switch fails,thenit will
  136. //getresettothe previous state via rollbackState().
  137. virtual status_t setState(CameraCommands operation)=0;
  138. virtual status_t commitState()=0;
  139. virtual status_t rollbackState()=0;
  140. };

看一下我标出的这是红色部分啊,为什么我要把它们标注成红色呢??
懂C++面向对象思想应该都知道 virtual这个关键字是干什么的,
如果一个类的方法被定义为 virtual 如果该类的子类实现了同样的方法,则这个方法被调用的时候,会忽略父类的实现,而直接调用子类的实现, 前提是方法名,包括变量类型,个数必须一致
那么这里有没有类继承了 CameraAdapter 这个类,并且实现了其中的一些虚拟函数呢??答案是肯定的,我可是吃了苦头才发现的
不过也是赖自己,这是只有定义是没有实现的,肯定是由子类来实现这是方法的,不,还是不赖自己,让我吃苦头的是这里是双层继承的,双层继承啊,我怎么知道
不卖关子了,那么谁继承了
CameraAdapter 这个类呢? 先给路径:hardware/ti/omap4xxx/camera/inc/BaseCameraAdapter.h

  1. classBaseCameraAdapter:publicCameraAdapter
  2. {

  3. public:

  4. BaseCameraAdapter();
  5. virtual~BaseCameraAdapter();

  6. ///Initialzes the camera adapter creates any resources required
  7. virtual status_t initialize(CameraProperties::Properties*)=0;

  8. virtualintsetErrorHandler(ErrorNotifier*errorNotifier);

  9. //Message/Frame notification APIs
  10. virtual void enableMsgType(int32_t msgs,frame_callback callback=NULL,event_callback eventCb=NULL,void*cookie=NULL);
  11. virtual void disableMsgType(int32_t msgs,void*cookie);
  12. virtual void returnFrame(CameraBuffer*frameBuf,CameraFrame::FrameType frameType);
  13. virtual void addFramePointers(CameraBuffer*frameBuf,void*y_uv);
  14. virtual void removeFramePointers();

  15. //APIstoconfigure Camera adapterandgetthe current parameterset
  16. virtual status_t setParameters(constCameraParameters&params)=0;
  17. virtual void getParameters(CameraParameters&params)=0;

  18. //APItosend a commandtothe camera
  19. virtual status_t sendCommand(CameraCommands operation,intvalue1=0,intvalue2=0,intvalue3=0,intvalue4=0);

  20. virtual status_t registerImageReleaseCallback(release_image_buffers_callback callback,void*user_data);

  21. virtual status_t registerEndCaptureCallback(end_image_capture_callback callback,void*user_data);

  22. //Retrieves the current Adapter state
  23. virtual AdapterState getState();
  24. //Retrieves thenextAdapter state
  25. virtual AdapterState getNextState();

  26. //Rolls the state machine backtoINTIALIZED_STATE from the current state
  27. virtual status_t rollbackToInitializedState();

  28. protected:
  29. //The first two methods will trytoswitch the adapter state.
  30. //EverycalltosetState()should be followed by a corresponding
  31. //calltocommitState().Ifthe state switch fails,thenit will
  32. //getresettothe previous state via rollbackState().
  33. virtual status_t setState(CameraCommands operation);
  34. virtual status_t commitState();
  35. virtual status_t rollbackState();

  36. //Retrieves the current Adapter state-forinternal use(notlocked)
  37. virtual status_t getState(AdapterState&state);
  38. //Retrieves thenextAdapter state-forinternal use(notlocked)
  39. virtual status_t getNextState(AdapterState&state);

  40. //-----------Interface that needstobe implemented by deriving classes--------------------

  41. //Should be implmented by deriving classesinordertostart image capture
  42. virtual status_t takePicture();

  43. //Should be implmented by deriving classesinordertostart image capture
  44. virtual status_t stopImageCapture();

  45. //Should be implmented by deriving classesinordertostart temporal bracketing
  46. virtual status_t startBracketing(intrange);

  47. //Should be implemented by deriving classesinordertostop temporal bracketing
  48. virtual status_t stopBracketing();

  49. //Should be implemented by deriving classesinodertoinitiate autoFocus
  50. virtual status_t autoFocus();

  51. //Should be implemented by deriving classesinodertoinitiate autoFocus
  52. virtual status_t cancelAutoFocus();

  53. //Should be called by deriving classesinordertodosome bookkeeping
  54. virtual status_t startVideoCapture();

  55. //Should be called by deriving classesinordertodosome bookkeeping
  56. virtual status_t stopVideoCapture();

  57. //Should be implemented by deriving classesinordertostart camera preview
  58. virtual status_t startPreview();

  59. //Should be implemented by deriving classesinordertostop camera preview
  60. virtual status_t stopPreview();

  61. //Should be implemented by deriving classesinordertostart smooth zoom
  62. virtual status_t startSmoothZoom(inttargetIdx);

  63. //Should be implemented by deriving classesinordertostop smooth zoom
  64. virtual status_t stopSmoothZoom();

  65. //Should be implemented by deriving classesinordertostop smooth zoom
  66. virtual status_t useBuffers(CameraMode mode,CameraBuffer*bufArr,intnum,size_t length,unsignedintqueueable);

  67. //Should be implemented by deriving classesinorder queue a released bufferinCameraAdapter
  68. virtual status_t fillThisBuffer(CameraBuffer*frameBuf,CameraFrame::FrameType frameType);

  69. //APItogetthe frame size requiredtobe allocated.This sizeisusedtooverride the size passed
  70. //by camera service when VSTAB/VNFisturnedONforexample
  71. virtual status_t getFrameSize(size_t&width,size_t&height);

  72. //APItogetrequired data frame size
  73. virtual status_t getFrameDataSize(size_t&dataFrameSize,size_t bufferCount);

  74. //APItogetrequired picture buffers size with the current configurationinCameraParameters
  75. virtual status_t getPictureBufferSize(size_t&length,size_t bufferCount);

  76. //Should be implemented by deriving classesinordertostart face detection
  77. //(ifsupported)
  78. virtual status_t startFaceDetection();

  79. //Should be implemented by deriving classesinordertostop face detection
  80. //(ifsupported)
  81. virtual status_t stopFaceDetection();

  82. virtual status_t switchToExecuting();

  83. virtual status_t setupTunnel(uint32_t SliceHeight,uint32_t EncoderHandle,uint32_t width,uint32_t height);

  84. virtual status_t destroyTunnel();

  85. virtual status_t cameraPreviewInitialization();

  86. //Receive orientation events from CameraHal
  87. virtual void onOrientationEvent(uint32_t orientation,uint32_t tilt);

  88. //---------------------Interface ends-----------------------------------

  89. status_t notifyFocusSubscribers(CameraHalEvent::FocusStatus status);
  90. status_t notifyShutterSubscribers();
  91. status_t notifyZoomSubscribers(intzoomIdx,bool targetReached);
  92. status_t notifyMetadataSubscribers(sp<CameraMetadataResult>&meta);

  93. //Send the frametosubscribers
  94. status_t sendFrameToSubscribers(CameraFrame*frame);

  95. //Resets the refCountforthis particular frame
  96. status_t resetFrameRefCount(CameraFrame&frame);

  97. //A couple of helper functions
  98. void setFrameRefCount(CameraBuffer*frameBuf,CameraFrame::FrameType frameType,intrefCount);
  99. intgetFrameRefCount(CameraBuffer*frameBuf,CameraFrame::FrameType frameType);
  100. intsetInitFrameRefCount(CameraBuffer*buf,unsignedintmask);
  101. staticconstchar*getLUTvalue_translateHAL(intValue,LUTtypeHAL LUT);

  102. .................
  103. .................
  104. }

这里我只列出了一部分代码,不过大家清楚了, BaseCameraAdapter继承 CameraAdapter,不过这里还没完呢,看看这个类中定义的方法
那么多的 virtual 方法,后来自己才发现的,他还是被别的类继承了,而且其中的很多方法被子类重新实现了
所以实现上上面调用的 startPreview方法其实不是 BaseCameraAdapter.cpp中实现的那个 startPreview方法
那挺调用的 startPreview方法在哪里呢,自然是继承了 BaseCameraAdapter 类的那个子类实现的 startPreview
现在就把这个罪魁祸首拉上来,先看定义:hardware/ti/omap4xxx/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h

  1. /**
  2. *Classwhich completely abstracts the camera hardware interaction from camera hal
  3. *TODO:Needtolist down here,all the message types that will be supported by thisclass
  4. Needtoimplement BufferProvider interfacetouse AllocateBuffer of OMXifneeded
  5. */
  6. classV4LCameraAdapter:publicBaseCameraAdapter
  7. {
  8. public:

  9. /*--------------------Constant declarations----------------------------------------*/
  10. staticconstint32_t MAX_NO_BUFFERS=20;

  11. ///@remarks OMX Camera has six ports-buffer input,timeinput,preview,image,video,andmeta data
  12. staticconstintMAX_NO_PORTS=6;

  13. ///Fivesecondtimeout
  14. staticconstintCAMERA_ADAPTER_TIMEOUT=5000*1000;

  15. public:

  16. V4LCameraAdapter(size_t sensor_index);
  17. ~V4LCameraAdapter();


  18. ///Initialzes the camera adapter creates any resources required
  19. virtual status_t initialize(CameraProperties::Properties*);

  20. //APIstoconfigure Camera adapterandgetthe current parameterset
  21. virtual status_t setParameters(constCameraParameters&params);
  22. virtual void getParameters(CameraParameters&params);

  23. //API
  24. virtual status_t UseBuffersPreview(CameraBuffer*bufArr,intnum);
  25. virtual status_t UseBuffersCapture(CameraBuffer*bufArr,intnum);

  26. static status_t getCaps(constintsensorId,CameraProperties::Properties*params,V4L_HANDLETYPE handle);

  27. protected:

  28. //----------Parentclassmethod implementation------------------------------------//看看人家这里说的很清楚,这是父类的方法
  29. virtual status_t startPreview();
  30. virtual status_t stopPreview();
  31. virtual status_t takePicture();
  32. virtual status_t stopImageCapture();
  33. virtual status_t autoFocus();
  34. virtual status_t useBuffers(CameraMode mode,CameraBuffer*bufArr,intnum,size_t length,unsignedintqueueable);
  35. virtual status_t fillThisBuffer(CameraBuffer*frameBuf,CameraFrame::FrameType frameType);
  36. virtual status_t getFrameSize(size_t&width,size_t&height);
  37. virtual status_t getPictureBufferSize(size_t&length,size_t bufferCount);
  38. virtual status_t getFrameDataSize(size_t&dataFrameSize,size_t bufferCount);
  39. virtual void onOrientationEvent(uint32_t orientation,uint32_t tilt);
  40. //-----------------------------------------------------------------------------


  41. private:

  42. classPreviewThread:publicThread{
  43. V4LCameraAdapter*mAdapter;
  44. public:
  45. PreviewThread(V4LCameraAdapter*hw):
  46. Thread(false),mAdapter(hw){}
  47. virtual void onFirstRef(){
  48. run("CameraPreviewThread",PRIORITY_URGENT_DISPLAY);
  49. }
  50. virtual bool threadLoop(){
  51. mAdapter->previewThread();
  52. //loopuntilwe needtoquit
  53. returntrue;
  54. }
  55. };

  56. //Usedforcalculation of the average frame rate during preview
  57. status_t recalculateFPS();

  58. char*GetFrame(int&index);

  59. intpreviewThread();

  60. public:

  61. private:
  62. //capabilities data
  63. staticconstCapPixelformat mPixelformats[];
  64. staticconstCapResolution mPreviewRes[];
  65. staticconstCapFramerate mFramerates[];
  66. staticconstCapResolution mImageCapRes[];

  67. //camera defaults
  68. staticconstchar DEFAULT_PREVIEW_FORMAT[];
  69. staticconstchar DEFAULT_PREVIEW_SIZE[];
  70. staticconstchar DEFAULT_FRAMERATE[];
  71. staticconstchar DEFAULT_NUM_PREV_BUFS[];

  72. staticconstchar DEFAULT_PICTURE_FORMAT[];
  73. staticconstchar DEFAULT_PICTURE_SIZE[];
  74. staticconstchar DEFAULT_FOCUS_MODE[];
  75. staticconstchar*DEFAULT_VSTAB;
  76. staticconstchar*DEFAULT_VNF;

  77. static status_t insertDefaults(CameraProperties::Properties*,V4L_TI_CAPTYPE&);
  78. static status_t insertCapabilities(CameraProperties::Properties*,V4L_TI_CAPTYPE&);
  79. static status_t insertPreviewFormats(CameraProperties::Properties*,V4L_TI_CAPTYPE&);
  80. static status_t insertPreviewSizes(CameraProperties::Properties*,V4L_TI_CAPTYPE&);
  81. static status_t insertImageSizes(CameraProperties::Properties*,V4L_TI_CAPTYPE&);
  82. static status_t insertFrameRates(CameraProperties::Properties*,V4L_TI_CAPTYPE&);
  83. static status_t sortAscend(V4L_TI_CAPTYPE&,uint16_t);

  84. status_t v4lIoctl(int,int,void*);
  85. status_t v4lInitMmap(int&);
  86. status_t v4lInitUsrPtr(int&);
  87. status_t v4lStartStreaming();
  88. status_t v4lStopStreaming(intnBufferCount);
  89. status_t v4lSetFormat(int,int,uint32_t);
  90. status_t restartPreview();


  91. intmPreviewBufferCount;
  92. intmPreviewBufferCountQueueable;
  93. intmCaptureBufferCount;
  94. intmCaptureBufferCountQueueable;
  95. KeyedVector<CameraBuffer*,int>mPreviewBufs;
  96. KeyedVector<CameraBuffer*,int>mCaptureBufs;
  97. mutable Mutex mPreviewBufsLock;
  98. mutable Mutex mCaptureBufsLock;
  99. mutable Mutex mStopPreviewLock;

  100. CameraParameters mParams;

  101. bool mPreviewing;
  102. bool mCapturing;
  103. Mutex mLock;

  104. intmFrameCount;
  105. intmLastFrameCount;
  106. unsignedintmIter;
  107. nsecs_t mLastFPSTime;

  108. //variables holding the estimated framerate
  109. float mFPS,mLastFPS;

  110. intmSensorIndex;

  111. //protected by mLoc

大家看到了 V4LCameraAdapter 又继承了 BaseCameraAdapter,双层继承,实现了父类的一些方法
所有这里算是媳妇熬着婆了,终于找到了我们想要的 startPreview
不过看到终于进入了 V4LCameraAdapter 这个类,我知道,离成功已经很近了,V4L2就是直接去和driver谈判的
那么我们就看看
V4LCameraAdapter 这个类中的startPreview方法吧,路径: ardware/ti/omap4xxx/camera/V4LCameraAdapter/V4LCameraAdapter.cpp

  1. status_t V4LCameraAdapter::startPreview()
  2. {
  3. status_t ret=NO_ERROR;

  4. LOG_FUNCTION_NAME;
  5. Mutex::Autolock lock(mPreviewBufsLock);

  6. if(mPreviewing){
  7. ret=BAD_VALUE;
  8. gotoEXIT;
  9. }

  10. for(inti=0;i<mPreviewBufferCountQueueable;i++){

  11. mVideoInfo->buf.index=i;
  12. mVideoInfo->buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
  13. mVideoInfo->buf.memory=V4L2_MEMORY_MMAP;

  14. ret=v4lIoctl(mCameraHandle,VIDIOC_QBUF,&mVideoInfo->buf);
  15. if(ret<0){
  16. CAMHAL_LOGEA("VIDIOC_QBUF Failed");
  17. gotoEXIT;
  18. }
  19. nQueued++;
  20. }

  21. ret=v4lStartStreaming();

  22. //Createandstart preview threadforreceiving buffers from V4L Camera
  23. if(!mCapturing){
  24. mPreviewThread=new PreviewThread(this);
  25. CAMHAL_LOGDA("Created preview thread");
  26. }

不错,这条语句就是我一直找寻的,真是众里寻他千百度,蓦然回首,那句就在灯火阑珊处
这样,其他的事情就全部由v4l2去做了,这些过程会单独分一章去学习
还有就是上面绿的部分,同样要分一章学习,很重要

待续。。。。。。。。。。。

更多相关文章

  1. Android蓝牙栈bluez使用方法
  2. HwServiceManager篇-Android10.0 HwBinder通信原理(五)
  3. Timer TimerTask Handler三剑合一
  4. 【起航计划 014】2015 起航计划 Android(安卓)APIDemo的魔鬼步伐
  5. android中不同activity之间共享数据
  6. Android(安卓)开发艺术探索笔记(18)
  7. Android(安卓)进阶——代码插桩必知必会之初识ASM7字节码操作库
  8. android 有关毫秒转时间的方法,及时间间隔等
  9. Android数据库升级、降级、创建(onCreate() onUpgrade() onDowng

随机推荐

  1. LGame(Android及J2SE游戏引擎)入门示例—
  2. 2019-11-07 Android谷歌支付SDK集成问题
  3. StagefrightPlayer&&AwesomePlayer 初步
  4. cvc-complex-type.2.4.d: 发现了以元素 '
  5. Laravel 创建可以传递参数 Console服务的
  6. laravel 根据不同组织加载不同视图的实现
  7. laravel 实现划分admin和home 模块分组
  8. laravel在中间件内生成参数并且传递到控
  9. laravel通过a标签从视图向控制器实现传值
  10. linux文本处理三剑客之awk