1. 程式人生 > >Android Camera 通過V4L2與kernel driver的完整交互過程

Android Camera 通過V4L2與kernel driver的完整交互過程

initial length 詳細 eas handler use orien amp com

http://blog.chinaunix.net/uid-26215986-id-3552456.html

原文地址:Android Camera 通過V4L2與kernel driver的完整交互過程 作者:xinyuwuxian

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 initialized to HARDWARE_MODULE_TAG */
  3. uint32_t tag;
  4. /** major version number for the module */
  5. uint16_t version_major;
  6. /** minor version number of the module */
  7. uint16_t version_minor;
  8. /** Identifier of module */
  9. const char *id;
  10. /** Name of this module */
  11. const char *name;
  12. /** Author/owner/implementor of the module */
  13. const char *author;
  14. /** Modules methods */
  15. struct hw_module_methods_t* methods;
  16. /** module‘s dso */
  17. void* dso;
  18. /** padding to 128 bytes, reserved for future 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)(const struct hw_module_t* module, const char* 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. (const hw_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 (int i = 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. static int camera_device_open(const hw_module_t* module, const char* name,
  2. hw_device_t** device);
  3. static int camera_device_close(hw_device_t* device);
  4. static int camera_get_number_of_cameras(void);
  5. static int camera_get_camera_info(int camera_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 handle to one of the cameras
  2. *
  3. * assume camera service will keep singleton of each camera
  4. * so this function will always only be called once per camera instance
  5. */
  6. int camera_device_open(const hw_module_t* module, const char* name,
  7. hw_device_t** device)
  8. {
  9. int rv = 0;
  10. int num_cameras = 0;
  11. int cameraid;
  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. int camera_start_preview(struct camera_device * device)
  2. {
  3. int rv = -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 switched to VF mode
  5. @todo Update function header with the different errors that are possible
  6. */
  7. status_t CameraHal::startPreview() {
  8. LOG_FUNCTION_NAME;
  9. // When tunneling is enabled during VTC, startPreview happens in 2 steps:
  10. // When the application sends the command CAMERA_CMD_PREVIEW_INITIALIZATION,
  11. // cameraPreviewInitialization() is called, which in turn causes the CameraAdapter
  12. // to move from loaded to idle state. And when the application calls startPreview,
  13. // the CameraAdapter moves from idle to executing state.
  14. //
  15. // If the application calls startPreview() without sending the command
  16. // CAMERA_CMD_PREVIEW_INITIALIZATION, then the function cameraPreviewInitialization()
  17. // AND startPreview() are executed. In other words, if the application calls
  18. // startPreview() without sending the command CAMERA_CMD_PREVIEW_INITIALIZATION,
  19. // then the CameraAdapter moves from loaded to idle to executing state in one shot.
  20. status_t ret = cameraPreviewInitialization();
  21. // The flag mPreviewInitializationDone is set to true at the end of the function
  22. // cameraPreviewInitialization(). Therefore, if everything goes alright, then the
  23. // flag will be set. Sometimes, the function cameraPreviewInitialization() may
  24. // return prematurely if all the resources are not available for starting preview.
  25. // For example, if the preview window is not set, then it would return NO_ERROR.
  26. // Under such circumstances, one should return from startPreview as well and should
  27. // not continue execution. That is why, we check the flag and not the return value.
  28. if (!mPreviewInitializationDone) return ret;
  29. // Once startPreview is called, there is no need to continue to remember whether
  30. // the function cameraPreviewInitialization() was called earlier or not. And so
  31. // the flag mPreviewInitializationDone is reset here. Plus, this preserves the
  32. // current behavior of startPreview under the circumstances where the application
  33. // calls startPreview twice or more.
  34. mPreviewInitializationDone = false;
  35. ///Enable the display adapter if present, actual overlay enable happens when we post the buffer
  36. if(mDisplayAdapter.get() != NULL) {
  37. CAMHAL_LOGDA("Enabling display");
  38. int width, height;
  39. mParameters.getPreviewSize(&width, &height);
  40. #if PPM_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 mStateSwitchLock is locked and unlock is supposed to be called
  48. // only from mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW)
  49. // below. But this will never happen because of goto error. Thus at next
  50. // startPreview() call CameraHAL will be deadlocked.
  51. // Need to revisit mStateSwitch lock, for now just abort the process.
  52. CAMHAL_ASSERT_X(false,
  53. "At this stage mCameraAdapter->mStateSwitchLock is still locked, "
  54. "deadlock is guaranteed");
  55. goto error;
  56. }
  57. }
  58. ///Send START_PREVIEW command to adapter
  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. goto error;
  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. //Do all 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, int value1, int value2, int value3, int value4) {
  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. const char *printState = getLUTvalue_translateHAL(operation, CamCommandsLUT);
  6. mLock.lock();
  7. switch ( mAdapterState )
  8. {
  9. case INTIALIZED_STATE:
  10. ............
  11. case LOADED_PREVIEW_STATE:
  12. switch ( operation )
  13. {
  14. case CAMERA_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 interface class
  3. * Concrete classes derive from this class and provide implementations based on the specific camera h/w interface
  4. */
  5. class CameraAdapter: public FrameNotifier, public virtual 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. int mFd;
  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. virtual int initialize(CameraProperties::Properties*) = 0;
  100. virtual int setErrorHandler(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. //APIs to configure Camera adapter and get the current parameter set
  111. virtual int setParameters(const CameraParameters& params) = 0;
  112. virtual void getParameters(CameraParameters& params) = 0;
  113. //Registers callback for returning image buffers back to CameraHAL
  114. virtual int registerImageReleaseCallback(release_image_buffers_callback callback, void *user_data) = 0;
  115. //Registers callback, which signals a completed image capture
  116. virtual int registerEndCaptureCallback(end_image_capture_callback callback, void *user_data) = 0;
  117. //API to send a command to the camera
  118. virtual status_t sendCommand(CameraCommands operation, int value1=0, int value2=0, int value3=0, int value4=0) = 0;
  119. virtual ~CameraAdapter() {};
  120. //Retrieves the current Adapter state
  121. virtual AdapterState getState() = 0;
  122. //Retrieves the next Adapter 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 back to INTIALIZED_STATE from the current state
  127. virtual status_t rollbackToInitializedState() = 0;
  128. // Retrieves the current Adapter state - for internal use (not locked)
  129. virtual status_t getState(AdapterState &state) = 0;
  130. // Retrieves the next Adapter state - for internal use (not locked)
  131. virtual status_t getNextState(AdapterState &state) = 0;
  132. protected:
  133. //The first two methods will try to switch the adapter state.
  134. //Every call to setState() should be followed by a corresponding
  135. //call to commitState(). If the state switch fails, then it will
  136. //get reset to the 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. class BaseCameraAdapter : public CameraAdapter
  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. virtual int setErrorHandler(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. //APIs to configure Camera adapter and get the current parameter set
  16. virtual status_t setParameters(const CameraParameters& params) = 0;
  17. virtual void getParameters(CameraParameters& params) = 0;
  18. //API to send a command to the camera
  19. virtual status_t sendCommand(CameraCommands operation, int value1 = 0, int value2 = 0, int value3 = 0, int value4 = 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 the next Adapter state
  25. virtual AdapterState getNextState();
  26. // Rolls the state machine back to INTIALIZED_STATE from the current state
  27. virtual status_t rollbackToInitializedState();
  28. protected:
  29. //The first two methods will try to switch the adapter state.
  30. //Every call to setState() should be followed by a corresponding
  31. //call to commitState(). If the state switch fails, then it will
  32. //get reset to the 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 - for internal use (not locked)
  37. virtual status_t getState(AdapterState &state);
  38. // Retrieves the next Adapter state - for internal use (not locked)
  39. virtual status_t getNextState(AdapterState &state);
  40. //-----------Interface that needs to be implemented by deriving classes --------------------
  41. //Should be implmented by deriving classes in order to start image capture
  42. virtual status_t takePicture();
  43. //Should be implmented by deriving classes in order to start image capture
  44. virtual status_t stopImageCapture();
  45. //Should be implmented by deriving classes in order to start temporal bracketing
  46. virtual status_t startBracketing(int range);
  47. //Should be implemented by deriving classes in order to stop temporal bracketing
  48. virtual status_t stopBracketing();
  49. //Should be implemented by deriving classes in oder to initiate autoFocus
  50. virtual status_t autoFocus();
  51. //Should be implemented by deriving classes in oder to initiate autoFocus
  52. virtual status_t cancelAutoFocus();
  53. //Should be called by deriving classes in order to do some bookkeeping
  54. virtual status_t startVideoCapture();
  55. //Should be called by deriving classes in order to do some bookkeeping
  56. virtual status_t stopVideoCapture();
  57. //Should be implemented by deriving classes in order to start camera preview
  58. virtual status_t startPreview();
  59. //Should be implemented by deriving classes in order to stop camera preview
  60. virtual status_t stopPreview();
  61. //Should be implemented by deriving classes in order to start smooth zoom
  62. virtual status_t startSmoothZoom(int targetIdx);
  63. //Should be implemented by deriving classes in order to stop smooth zoom
  64. virtual status_t stopSmoothZoom();
  65. //Should be implemented by deriving classes in order to stop smooth zoom
  66. virtual status_t useBuffers(CameraMode mode, CameraBuffer* bufArr, int num, size_t length, unsigned int queueable);
  67. //Should be implemented by deriving classes in order queue a released buffer in CameraAdapter
  68. virtual status_t fillThisBuffer(CameraBuffer* frameBuf, CameraFrame::FrameType frameType);
  69. //API to get the frame size required to be allocated. This size is used to override the size passed
  70. //by camera service when VSTAB/VNF is turned ON for example
  71. virtual status_t getFrameSize(size_t &width, size_t &height);
  72. //API to get required data frame size
  73. virtual status_t getFrameDataSize(size_t &dataFrameSize, size_t bufferCount);
  74. //API to get required picture buffers size with the current configuration in CameraParameters
  75. virtual status_t getPictureBufferSize(size_t &length, size_t bufferCount);
  76. // Should be implemented by deriving classes in order to start face detection
  77. // ( if supported )
  78. virtual status_t startFaceDetection();
  79. // Should be implemented by deriving classes in order to stop face detection
  80. // ( if supported )
  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(int zoomIdx, bool targetReached);
  92. status_t notifyMetadataSubscribers(sp<CameraMetadataResult> &meta);
  93. //Send the frame to subscribers
  94. status_t sendFrameToSubscribers(CameraFrame *frame);
  95. //Resets the refCount for this particular frame
  96. status_t resetFrameRefCount(CameraFrame &frame);
  97. //A couple of helper functions
  98. void setFrameRefCount(CameraBuffer* frameBuf, CameraFrame::FrameType frameType, int refCount);
  99. int getFrameRefCount(CameraBuffer* frameBuf, CameraFrame::FrameType frameType);
  100. int setInitFrameRefCount(CameraBuffer* buf, unsigned int mask);
  101. static const char* getLUTvalue_translateHAL(int Value, 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. * Class which completely abstracts the camera hardware interaction from camera hal
  3. * TODO: Need to list down here, all the message types that will be supported by this class
  4. Need to implement BufferProvider interface to use AllocateBuffer of OMX if needed
  5. */
  6. class V4LCameraAdapter : public BaseCameraAdapter
  7. {
  8. public:
  9. /*--------------------Constant declarations----------------------------------------*/
  10. static const int32_t MAX_NO_BUFFERS = 20;
  11. [email protected] OMX Camera has six ports - buffer input, time input, preview, image, video, and meta data
  12. static const int MAX_NO_PORTS = 6;
  13. ///Five second timeout
  14. static const int CAMERA_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. //APIs to configure Camera adapter and get the current parameter set
  21. virtual status_t setParameters(const CameraParameters& params);
  22. virtual void getParameters(CameraParameters& params);
  23. // API
  24. virtual status_t UseBuffersPreview(CameraBuffer *bufArr, int num);
  25. virtual status_t UseBuffersCapture(CameraBuffer *bufArr, int num);
  26. static status_t getCaps(const int sensorId, CameraProperties::Properties* params, V4L_HANDLETYPE handle);
  27. protected:
  28. //----------Parent class method 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, int num, size_t length, unsigned int queueable);
  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. class PreviewThread : public Thread {
  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. // loop until we need to quit
  53. return true;
  54. }
  55. };
  56. //Used for calculation of the average frame rate during preview
  57. status_t recalculateFPS();
  58. char * GetFrame(int &index);
  59. int previewThread();
  60. public:
  61. private:
  62. //capabilities data
  63. static const CapPixelformat mPixelformats [];
  64. static const CapResolution mPreviewRes [];
  65. static const CapFramerate mFramerates [];
  66. static const CapResolution mImageCapRes [];
  67. //camera defaults
  68. static const char DEFAULT_PREVIEW_FORMAT[];
  69. static const char DEFAULT_PREVIEW_SIZE[];
  70. static const char DEFAULT_FRAMERATE[];
  71. static const char DEFAULT_NUM_PREV_BUFS[];
  72. static const char DEFAULT_PICTURE_FORMAT[];
  73. static const char DEFAULT_PICTURE_SIZE[];
  74. static const char DEFAULT_FOCUS_MODE[];
  75. static const char * DEFAULT_VSTAB;
  76. static const char * 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(int nBufferCount);
  89. status_t v4lSetFormat(int, int, uint32_t);
  90. status_t restartPreview();
  91. int mPreviewBufferCount;
  92. int mPreviewBufferCountQueueable;
  93. int mCaptureBufferCount;
  94. int mCaptureBufferCountQueueable;
  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. int mFrameCount;
  105. int mLastFrameCount;
  106. unsigned int mIter;
  107. nsecs_t mLastFPSTime;
  108. //variables holding the estimated framerate
  109. float mFPS, mLastFPS;
  110. int mSensorIndex;
  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. goto EXIT;
  9. }
  10. for (int i = 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. goto EXIT;
  18. }
  19. nQueued++;
  20. }
  21. ret = v4lStartStreaming();
  22. // Create and start preview thread for receiving buffers from V4L Camera
  23. if(!mCapturing) {
  24. mPreviewThread = new PreviewThread(this);
  25. CAMHAL_LOGDA("Created preview thread");
  26. }
不錯,這條語句就是我一直找尋的,真是眾裏尋他千百度,驀然回首,那句就在燈火闌珊處
這樣,其他的事情就全部由v4l2去做了,這些過程會單獨分一章去學習
還有就是上面綠的部分,同樣要分一章學習,很重要

待續。。。。。。。。。。。

Android Camera 通過V4L2與kernel driver的完整交互過程