分享

Android Camera CameraHal.cpp 分析

 风雪夜归人_95 2013-08-13
Android Camera CameraHal.cpp 分析
作为上层和底层的中转站,hal层在android中起到的作用不言而喻,针对camera的研究已经有一段时间了,这里自己还是决定静下心来好好的分析一下CameraHal.cpp这里的代码,
对自己更好的理解hal与上层和底层的交互作用不可小觑,特别对理解hal与kernel driver的交互过程作用很大
不多说废话了,开始今天的主题

我们首先从CameraHal的初始化,那么他是从哪里开始化的呢?这里之前的文章中已经有过,只是没有重点介绍,这里还是说一下吧
是在camera最初open的时候会调用到camerahal_module.cpp中的以下方法进行初始化的

  1. /*******************************************************************
  2. * implementation of camera_module functions
  3. *******************************************************************/

  4. /* open device handle to one of the cameras
  5. *
  6. * assume camera service will keep singleton of each camera
  7. * so this function will always only be called once per camera instance
  8. */

  9. int camera_device_open(const hw_module_t* module, const char* name,
  10. hw_device_t** device)
  11. {
  12. int rv = 0;
  13. int num_cameras = 0;
  14. int cameraid;
  15. ti_camera_device_t* camera_device = NULL;
  16. camera_device_ops_t* camera_ops = NULL;
  17. android::CameraHal* camera = NULL;
  18. android::CameraProperties::Properties* properties = NULL;

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

  20. LOGI("camera_device open");

  21. if (name != NULL) {
  22. cameraid = atoi(name);
  23. num_cameras = gCameraProperties.camerasSupported();

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

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

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

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

  52. memset(camera_device, 0, sizeof(*camera_device));
  53. memset(camera_ops, 0, sizeof(*camera_ops));

  54. camera_device->base.common.tag = HARDWARE_DEVICE_TAG;
  55. camera_device->base.common.version = 0;
  56. camera_device->base.common.module = (hw_module_t *)(module);
  57. camera_device->base.common.close = camera_device_close;
  58. camera_device->base.ops = camera_ops;

  59. camera_ops->set_preview_window = camera_set_preview_window;
  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. *device = &camera_device->base.common;

  83. // -------- TI specific stuff --------

  84. camera_device->cameraid = cameraid;

  85. if(gCameraProperties.getProperties(cameraid, &properties) < 0)
  86. {
  87. LOGE("Couldn't get camera properties");
  88. rv = -ENOMEM;
  89. goto fail;
  90. }

  91. ****************重点就在这里了****************
  92. camera = new android::CameraHal(cameraid);

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

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

  105. gCameraHals[cameraid] = camera;
  106. gCamerasOpen++;


  107. }

  108. return rv;

  109. fail:
  110. if(camera_device) {
  111. free(camera_device);
  112. camera_device = NULL;
  113. }
  114. if(camera_ops) {
  115. free(camera_ops);
  116. camera_ops = NULL;
  117. }
  118. if(camera) {
  119. delete camera;
  120. camera = NULL;
  121. }
  122. *device = NULL;
  123. return rv;
  124. }
上面横线中间的部分就是camerahal的初始化了,首先new camerahal,并且调用initialize方法,最后将实例化好的camerahal保存到gCameraHals这个数组中,之后会通过这个数组找到我们实例化好的camerahal,实现我们对hal层接口的使用
现在我们就开始看看camerahal的initialize方法的实现
  1. /**
  2. @brief Initialize the Camera HAL

  3. Creates CameraAdapter, AppCallbackNotifier, DisplayAdapter and MemoryManager

  4. @param None
  5. @return NO_ERROR - On success
  6. NO_MEMORY - On failure to allocate memory for any of the objects
  7. @remarks Camera Hal internal function

  8. */

  9. status_t CameraHal::initialize(CameraProperties::Properties* properties)
  10. {
  11. LOG_FUNCTION_NAME;

  12. int sensor_index = 0;
  13. const char* sensor_name = NULL;

  14. ///Initialize the event mask used for registering an event provider for AppCallbackNotifier
  15. ///Currently, registering all events as to be coming from CameraAdapter
  16. int32_t eventMask = CameraHalEvent::ALL_EVENTS;

  17. // Get my camera properties
  18. mCameraProperties = properties;

  19. if(!mCameraProperties)
  20. {
  21. goto fail_loop;
  22. }

  23. // Dump the properties of this Camera
  24. // will only print if DEBUG macro is defined
  25. mCameraProperties->dump();

  26. if (strcmp(CameraProperties::DEFAULT_VALUE, mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX)) != 0 )
  27. {
  28. sensor_index = atoi(mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX));
  29. }

  30. if (strcmp(CameraProperties::DEFAULT_VALUE, mCameraProperties->get(CameraProperties::CAMERA_NAME)) != 0 ) {
  31. sensor_name = mCameraProperties->get(CameraProperties::CAMERA_NAME);
  32. }
  33. CAMHAL_LOGDB("Sensor index= %d; Sensor name= %s", sensor_index, sensor_name);
1.这里很重要*******************************************************************************
这里做一个判断决定我们是使用V4LCameraAdapter还是OMXCameraAdapter
接下来将要重点学习OMX机制,这篇文章我们假设走else分支
  1. if (strcmp(sensor_name, V4L_CAMERA_NAME_USB) == 0) {
  2. #ifdef V4L_CAMERA_ADAPTER
  3. mCameraAdapter = V4LCameraAdapter_Factory(sensor_index);
  4. #endif
  5. }
  6. else {
  7. #ifdef OMX_CAMERA_ADAPTER
  8. mCameraAdapter = OMXCameraAdapter_Factory(sensor_index);
  9. #endif
  10. }

  11. if ( ( NULL == mCameraAdapter ) || (mCameraAdapter->initialize(properties)!=NO_ERROR))
  12. {
  13. CAMHAL_LOGEA("Unable to create or initialize CameraAdapter");
  14. mCameraAdapter = NULL;
  15. goto fail_loop;
  16. }

  17. mCameraAdapter->incStrong(mCameraAdapter);
  18. mCameraAdapter->registerImageReleaseCallback(releaseImageBuffers, (void *) this);
  19. mCameraAdapter->registerEndCaptureCallback(endImageCapture, (void *)this);
2.这里很重要*****************************************************************************
这里实例化一个AppCallbackNotifier,并且调用initialize方法进行初始化
  1. if(!mAppCallbackNotifier.get())
  2. {
  3. /// Create the callback notifier
  4. mAppCallbackNotifier = new AppCallbackNotifier();
  5. if( ( NULL == mAppCallbackNotifier.get() ) || ( mAppCallbackNotifier->initialize() != NO_ERROR))
  6. {
  7. CAMHAL_LOGEA("Unable to create or initialize AppCallbackNotifier");
  8. goto fail_loop;
  9. }
  10. }
3.这里很重要*****************************************************************************
这里实例化一个MemoryManager,并且调用initialize方法进行初始化,以及其他一些set 或者初始化
  1. if(!mMemoryManager.get())
  2. {
  3. /// Create Memory Manager
  4. mMemoryManager = new MemoryManager();
  5. if( ( NULL == mMemoryManager.get() ) || ( mMemoryManager->initialize() != NO_ERROR))
  6. {
  7. CAMHAL_LOGEA("Unable to create or initialize MemoryManager");
  8. goto fail_loop;
  9. }
  10. }

  11. ///Setup the class dependencies...

  12. ///AppCallbackNotifier has to know where to get the Camera frames and the events like auto focus lock etc from.
  13. ///CameraAdapter is the one which provides those events
  14. ///Set it as the frame and event providers for AppCallbackNotifier
  15. ///@remarks setEventProvider API takes in a bit mask of events for registering a provider for the different events
  16. /// That way, if events can come from DisplayAdapter in future, we will be able to add it as provider
  17. /// for any event
  18. mAppCallbackNotifier->setEventProvider(eventMask, mCameraAdapter);
  19. mAppCallbackNotifier->setFrameProvider(mCameraAdapter);

  20. ///Any dynamic errors that happen during the camera use case has to be propagated back to the application
  21. ///via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that notifies such errors to the application
  22. ///Set it as the error handler for CameraAdapter
  23. mCameraAdapter->setErrorHandler(mAppCallbackNotifier.get());

  24. ///Start the callback notifier
  25. if(mAppCallbackNotifier->start() != NO_ERROR)
  26. {
  27. CAMHAL_LOGEA("Couldn't start AppCallbackNotifier");
  28. goto fail_loop;
  29. }

  30. CAMHAL_LOGDA("Started AppCallbackNotifier..");
  31. mAppCallbackNotifier->setMeasurements(mMeasurementEnabled);
4.这里很重要*****************************************************************************
这里进行camera参数的设置
  1. ///Initialize default parameters
  2. initDefaultParameters();

  3. if ( setParameters(mParameters) != NO_ERROR )
  4. {
  5. CAMHAL_LOGEA("Failed to set default parameters?!");
  6. }
5.这里很重要*****************************************************************************
这里实例化一个SensorListener,并且调用initialize方法进行初始化,以及其他一些初始设置
  1. // register for sensor events
  2. mSensorListener = new SensorListener();
  3. if (mSensorListener.get()) {
  4. if (mSensorListener->initialize() == NO_ERROR) {
  5. mSensorListener->setCallbacks(orientation_cb, this);
  6. mSensorListener->enableSensor(SensorListener::SENSOR_ORIENTATION);
  7. } else {
  8. CAMHAL_LOGEA("Error initializing SensorListener. not fatal, continuing");
  9. mSensorListener.clear();
  10. mSensorListener = NULL;
  11. }
  12. }

  13. LOG_FUNCTION_NAME_EXIT;

  14. return NO_ERROR;

  15. fail_loop:

  16. ///Free up the resources because we failed somewhere up
  17. deinitialize();
  18. LOG_FUNCTION_NAME_EXIT;

  19. return NO_MEMORY;

  20. }
上面一共五个步骤,接下来将一一分析,自我感觉很有这样的必要

一.OMXCameraAdapter的实例化和初始化
首先看一下OMXCameraAdapter的默认构造函数
  1. OMXCameraAdapter::OMXCameraAdapter(size_t sensor_index)
  2. {
  3. LOG_FUNCTION_NAME;

  4. mOmxInitialized = false;
  5. mComponentState = OMX_StateInvalid;
  6. mSensorIndex = sensor_index;
  7. mPictureRotation = 0;
  8. // Initial values
  9. mTimeSourceDelta = 0;
  10. onlyOnce = true;
  11. mDccData.pData = NULL;

  12. mInitSem.Create(0);
  13. mFlushSem.Create(0);
  14. mUsePreviewDataSem.Create(0);
  15. mUsePreviewSem.Create(0);
  16. mUseCaptureSem.Create(0);
  17. mUseReprocessSem.Create(0);
  18. mStartPreviewSem.Create(0);
  19. mStopPreviewSem.Create(0);
  20. mStartCaptureSem.Create(0);
  21. mStopCaptureSem.Create(0);
  22. mStopReprocSem.Create(0);
  23. mSwitchToLoadedSem.Create(0);
  24. mCaptureSem.Create(0);

  25. mSwitchToExecSem.Create(0);

  26. mCameraAdapterParameters.mHandleComp = 0;

  27. mUserSetExpLock = OMX_FALSE;
  28. mUserSetWbLock = OMX_FALSE;

  29. mFramesWithDucati = 0;
  30. mFramesWithDisplay = 0;
  31. mFramesWithEncoder = 0;

  32. #ifdef CAMERAHAL_OMX_PROFILING

  33. mDebugProfile = 0;

  34. #endif

  35. LOG_FUNCTION_NAME_EXIT;
  36. }
这其中只是对很多参数的默认初始化,接下来看看initialize方法
  1. /*--------------------Camera Adapter Class STARTS here-----------------------------*/

  2. status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps)
  3. {
  4. LOG_FUNCTION_NAME;

  5. char value[PROPERTY_VALUE_MAX];
  6. const char *mountOrientationString = NULL;

  7. property_get("debug.camera.showfps", value, "0");
  8. mDebugFps = atoi(value);
  9. property_get("debug.camera.framecounts", value, "0");
  10. mDebugFcs = atoi(value);

  11. #ifdef CAMERAHAL_OMX_PROFILING

  12. property_get("debug.camera.profile", value, "0");
  13. mDebugProfile = atoi(value);

  14. #endif

  15. TIMM_OSAL_ERRORTYPE osalError = OMX_ErrorNone;
  16. OMX_ERRORTYPE eError = OMX_ErrorNone;
  17. status_t ret = NO_ERROR;

  18. mLocalVersionParam.s.nVersionMajor = 0x1;
  19. mLocalVersionParam.s.nVersionMinor = 0x1;
  20. mLocalVersionParam.s.nRevision = 0x0 ;
  21. mLocalVersionParam.s.nStep = 0x0;

  22. mPending3Asettings = 0;//E3AsettingsAll;
  23. mPendingCaptureSettings = 0;
  24. mPendingPreviewSettings = 0;

  25. if ( 0 != mInitSem.Count() )
  26. {
  27. CAMHAL_LOGEB("Error mInitSem semaphore count %d", mInitSem.Count());
  28. LOG_FUNCTION_NAME_EXIT;
  29. return NO_INIT;
  30. }

  31. ///Update the preview and image capture port indexes
  32. mCameraAdapterParameters.mPrevPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
  33. // temp changed in order to build OMX_CAMERA_PORT_VIDEO_OUT_IMAGE;
  34. mCameraAdapterParameters.mImagePortIndex = OMX_CAMERA_PORT_IMAGE_OUT_IMAGE;
  35. mCameraAdapterParameters.mMeasurementPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT;
  36. //currently not supported use preview port instead
  37. mCameraAdapterParameters.mVideoPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_VIDEO;
  38. mCameraAdapterParameters.mVideoInPortIndex = OMX_CAMERA_PORT_VIDEO_IN_VIDEO;
  39. // 1.OMX_Init
  40. eError = OMX_Init();
  41. if (eError != OMX_ErrorNone) {
  42. CAMHAL_LOGEB("OMX_Init() failed, error: 0x%x", eError);
  43. return ErrorUtils::omxToAndroidError(eError);
  44. }
  45. mOmxInitialized = true;

  46. // 2.Initialize the callback handles
  47. OMX_CALLBACKTYPE callbacks;
  48. callbacks.EventHandler = android::OMXCameraAdapterEventHandler;
  49. callbacks.EmptyBufferDone = android::OMXCameraAdapterEmptyBufferDone;
  50. callbacks.FillBufferDone = android::OMXCameraAdapterFillBufferDone;

  51. // 3.Get the handle to the OMX Component
  52. eError = OMXCameraAdapter::OMXCameraGetHandle(&mCameraAdapterParameters.mHandleComp, this, callbacks);
  53. if(eError != OMX_ErrorNone) {
  54. CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError);
  55. }
  56. GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);

  57. mComponentState = OMX_StateLoaded;

  58. CAMHAL_LOGVB("OMX_GetHandle -0x%x sensor_index = %lu", eError, mSensorIndex);
  59. initDccFileDataSave(&mCameraAdapterParameters.mHandleComp, mCameraAdapterParameters.mPrevPortIndex);

  60. eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
  61. OMX_CommandPortDisable,
  62. OMX_ALL,
  63. NULL);

  64. if(eError != OMX_ErrorNone) {
  65. CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortDisable) -0x%x", eError);
  66. }
  67. GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);

  68. // 4.Register for port enable event
  69. ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
  70. OMX_EventCmdComplete,
  71. OMX_CommandPortEnable,
  72. mCameraAdapterParameters.mPrevPortIndex,
  73. mInitSem);
  74. if(ret != NO_ERROR) {
  75. CAMHAL_LOGEB("Error in registering for event %d", ret);
  76. goto EXIT;
  77. }

  78. // 5.Enable PREVIEW Port
  79. eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
  80. OMX_CommandPortEnable,
  81. mCameraAdapterParameters.mPrevPortIndex,
  82. NULL);
  83. if(eError != OMX_ErrorNone) {
  84. CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError);
  85. }
  86. GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);

  87. // 6.Wait for the port enable event to occur
  88. ret = mInitSem.WaitTimeout(OMX_CMD_TIMEOUT);
  89. if ( NO_ERROR == ret ) {
  90. CAMHAL_LOGDA("-Port enable event arrived");
  91. } else {
  92. ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
  93. OMX_EventCmdComplete,
  94. OMX_CommandPortEnable,
  95. mCameraAdapterParameters.mPrevPortIndex,
  96. NULL);
  97. CAMHAL_LOGEA("Timeout for enabling preview port expired!");
  98. goto EXIT;
  99. }

  100. // 7.Select the sensor
  101. OMX_CONFIG_SENSORSELECTTYPE sensorSelect;
  102. OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
  103. sensorSelect.eSensor = (OMX_SENSORSELECT) mSensorIndex;
  104. eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect);
  105. if ( OMX_ErrorNone != eError ) {
  106. CAMHAL_LOGEB("Error while selecting the sensor index as %d - 0x%x", mSensorIndex, eError);
  107. return BAD_VALUE;
  108. } else {
  109. CAMHAL_LOGDB("Sensor %d selected successfully", mSensorIndex);
  110. }

  111. #ifdef CAMERAHAL_DEBUG

  112. printComponentVersion(mCameraAdapterParameters.mHandleComp);

  113. #endif
  114. // 8.初始化默认参数
  115. mBracketingEnabled = false;
  116. mZoomBracketingEnabled = false;
  117. mBracketingBuffersQueuedCount = 0;
  118. mBracketingRange = 1;
  119. mLastBracetingBufferIdx = 0;
  120. mBracketingBuffersQueued = NULL;
  121. mOMXStateSwitch = false;
  122. mBracketingSet = false;
  123. #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
  124. mRawCapture = false;
  125. mYuvCapture = false;
  126. #endif

  127. mCaptureSignalled = false;
  128. mCaptureConfigured = false;
  129. mReprocConfigured = false;
  130. mRecording = false;
  131. mWaitingForSnapshot = false;
  132. mPictureFormatFromClient = NULL;

  133. mCapabilitiesOpMode = MODE_MAX;
  134. mCapMode = INITIAL_MODE;
  135. mIPP = IPP_NULL;
  136. mVstabEnabled = false;
  137. mVnfEnabled = false;
  138. mBurstFrames = 1;
  139. mBurstFramesAccum = 0;
  140. mCapturedFrames = 0;
  141. mFlushShotConfigQueue = false;
  142. mPictureQuality = 100;
  143. mCurrentZoomIdx = 0;
  144. mTargetZoomIdx = 0;
  145. mPreviousZoomIndx = 0;
  146. mReturnZoomStatus = false;
  147. mZoomInc = 1;
  148. mZoomParameterIdx = 0;
  149. mExposureBracketingValidEntries = 0;
  150. mZoomBracketingValidEntries = 0;
  151. mSensorOverclock = false;
  152. mAutoConv = OMX_TI_AutoConvergenceModeMax;
  153. mManualConv = 0;
  154. mDeviceOrientation = 0;
  155. mCapabilities = caps;
  156. mZoomUpdating = false;
  157. mZoomUpdate = false;
  158. mGBCE = BRIGHTNESS_OFF;
  159. mGLBCE = BRIGHTNESS_OFF;
  160. mParameters3A.ExposureLock = OMX_FALSE;
  161. mParameters3A.WhiteBalanceLock = OMX_FALSE;

  162. mEXIFData.mGPSData.mAltitudeValid = false;
  163. mEXIFData.mGPSData.mDatestampValid = false;
  164. mEXIFData.mGPSData.mLatValid = false;
  165. mEXIFData.mGPSData.mLongValid = false;
  166. mEXIFData.mGPSData.mMapDatumValid = false;
  167. mEXIFData.mGPSData.mProcMethodValid = false;
  168. mEXIFData.mGPSData.mVersionIdValid = false;
  169. mEXIFData.mGPSData.mTimeStampValid = false;
  170. mEXIFData.mModelValid = false;
  171. mEXIFData.mMakeValid = false;

  172. //update the mDeviceOrientation with the sensor mount orientation.
  173. //So that the face detect will work before onOrientationEvent()
  174. //get triggered.
  175. CAMHAL_ASSERT(mCapabilities);
  176. mountOrientationString = mCapabilities->get(CameraProperties::ORIENTATION_INDEX);
  177. CAMHAL_ASSERT(mountOrientationString);
  178. mDeviceOrientation = atoi(mountOrientationString);

  179. if (mSensorIndex != 2) {
  180. mCapabilities->setMode(MODE_HIGH_SPEED);
  181. }

  182. if (mCapabilities->get(CameraProperties::SUPPORTED_ZOOM_STAGES) != NULL) {
  183. mMaxZoomSupported = mCapabilities->getInt(CameraProperties::SUPPORTED_ZOOM_STAGES) + 1;
  184. } else {
  185. mMaxZoomSupported = 1;
  186. }

  187. // 9.initialize command handling thread
  188. if(mCommandHandler.get() == NULL)
  189. mCommandHandler = new CommandHandler(this);

  190. if ( NULL == mCommandHandler.get() )
  191. {
  192. CAMHAL_LOGEA("Couldn't create command handler");
  193. return NO_MEMORY;
  194. }

  195. ret = mCommandHandler->run("CallbackThread", PRIORITY_URGENT_DISPLAY);
  196. if ( ret != NO_ERROR )
  197. {
  198. if( ret == INVALID_OPERATION){
  199. CAMHAL_LOGDA("command handler thread already runnning!!");
  200. ret = NO_ERROR;
  201. } else {
  202. CAMHAL_LOGEA("Couldn't run command handlerthread");
  203. return ret;
  204. }
  205. }

  206. // 10.initialize omx callback handling thread
  207. if(mOMXCallbackHandler.get() == NULL)
  208. mOMXCallbackHandler = new OMXCallbackHandler(this);

  209. if ( NULL == mOMXCallbackHandler.get() )
  210. {
  211. CAMHAL_LOGEA("Couldn't create omx callback handler");
  212. return NO_MEMORY;
  213. }

  214. ret = mOMXCallbackHandler->run("OMXCallbackThread", PRIORITY_URGENT_DISPLAY);
  215. if ( ret != NO_ERROR )
  216. {
  217. if( ret == INVALID_OPERATION){
  218. CAMHAL_LOGDA("omx callback handler thread already runnning!!");
  219. ret = NO_ERROR;
  220. } else {
  221. CAMHAL_LOGEA("Couldn't run omx callback handler thread");
  222. return ret;
  223. }
  224. }

  225. OMX_INIT_STRUCT_PTR (&mRegionPriority, OMX_TI_CONFIG_3A_REGION_PRIORITY);
  226. OMX_INIT_STRUCT_PTR (&mFacePriority, OMX_TI_CONFIG_3A_FACE_PRIORITY);
  227. mRegionPriority.nPortIndex = OMX_ALL;
  228. mFacePriority.nPortIndex = OMX_ALL;

  229. //Setting this flag will that the first setParameter call will apply all 3A settings
  230. //and will not conditionally apply based on current values.
  231. mFirstTimeInit = true;

  232. //Flag to avoid calling setVFramerate() before OMX_SetParameter(OMX_IndexParamPortDefinition)
  233. //Ducati will return an error otherwise.
  234. mSetFormatDone = false;

  235. memset(mExposureBracketingValues, 0, EXP_BRACKET_RANGE*sizeof(int));
  236. memset(mZoomBracketingValues, 0, ZOOM_BRACKET_RANGE*sizeof(int));
  237. mMeasurementEnabled = false;
  238. mFaceDetectionRunning = false;
  239. mFaceDetectionPaused = false;
  240. mFDSwitchAlgoPriority = false;

  241. memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex], 0, sizeof(OMXCameraPortParameters));
  242. memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex], 0, sizeof(OMXCameraPortParameters));
  243. memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex], 0, sizeof(OMXCameraPortParameters));
  244. memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex], 0, sizeof(OMXCameraPortParameters));

  245. // 11.initialize 3A defaults
  246. mParameters3A.Effect = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_EFFECT, EffLUT);
  247. mParameters3A.FlashMode = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_FLASH_MODE, FlashLUT);
  248. mParameters3A.SceneMode = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_SCENE_MODE, SceneLUT);
  249. mParameters3A.EVCompensation = atoi(OMXCameraAdapter::DEFAULT_EV_COMPENSATION);
  250. mParameters3A.Focus = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_FOCUS_MODE, FocusLUT);
  251. mParameters3A.ISO = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_ISO_MODE, IsoLUT);
  252. mParameters3A.Flicker = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_ANTIBANDING, FlickerLUT);
  253. mParameters3A.Brightness = atoi(OMXCameraAdapter::DEFAULT_BRIGHTNESS);
  254. mParameters3A.Saturation = atoi(OMXCameraAdapter::DEFAULT_SATURATION) - SATURATION_OFFSET;
  255. mParameters3A.Sharpness = atoi(OMXCameraAdapter::DEFAULT_SHARPNESS) - SHARPNESS_OFFSET;
  256. mParameters3A.Contrast = atoi(OMXCameraAdapter::DEFAULT_CONTRAST) - CONTRAST_OFFSET;
  257. mParameters3A.WhiteBallance = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_WB, WBalLUT);
  258. mParameters3A.Exposure = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_EXPOSURE_MODE, ExpLUT);
  259. mParameters3A.ExposureLock = OMX_FALSE;
  260. mParameters3A.FocusLock = OMX_FALSE;
  261. mParameters3A.WhiteBalanceLock = OMX_FALSE;

  262. mParameters3A.ManualExposure = 0;
  263. mParameters3A.ManualExposureRight = 0;
  264. mParameters3A.ManualGain = 0;
  265. mParameters3A.ManualGainRight = 0;

  266. mParameters3A.AlgoFixedGamma = OMX_TRUE;
  267. mParameters3A.AlgoNSF1 = OMX_TRUE;
  268. mParameters3A.AlgoNSF2 = OMX_TRUE;
  269. mParameters3A.AlgoSharpening = OMX_TRUE;
  270. mParameters3A.AlgoThreeLinColorMap = OMX_TRUE;
  271. mParameters3A.AlgoGIC = OMX_TRUE;

  272. LOG_FUNCTION_NAME_EXIT;
  273. return ErrorUtils::omxToAndroidError(eError);

  274. EXIT:

  275. CAMHAL_LOGDB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
  276. performCleanupAfterError();
  277. LOG_FUNCTION_NAME_EXIT;
  278. return ErrorUtils::omxToAndroidError(eError);
  279. }
这个initialize的过程做的事情还是比较多的,这里关系到OMX的很多知识点,是之后要研究的,现在只是先知道这里
在完成initialize方法之后,
mCameraAdapter->registerImageReleaseCallback(releaseImageBuffers, (void *) this);
mCameraAdapter->registerEndCaptureCallback(endImageCapture, (void *)this);
这两个方法同样非常重要,首先我们这里调用的是mCameraAdapter的方法,mCameraAdapter是OMXCameraAdapter这个类的实例,但是其实OMXCameraAdapter这个类中是没有以上这两个方法的,但是我们接着看,OMXCameraAdapter这个类的定义
class OMXCameraAdapter : public BaseCameraAdapter
OMXCameraAdapter继承于BaseCameraAdapter
,不错,上面的两个方法是在BaseCameraAdapter这个类中实现的,我们接着看看
  1. status_t BaseCameraAdapter::registerImageReleaseCallback(release_image_buffers_callback callback, void *user_data)
  2. {
  3. status_t ret = NO_ERROR;

  4. LOG_FUNCTION_NAME;

  5. mReleaseImageBuffersCallback = callback;
  6. mReleaseData = user_data;

  7. LOG_FUNCTION_NAME_EXIT;

  8. return ret;
  9. }

  10. status_t BaseCameraAdapter::registerEndCaptureCallback(end_image_capture_callback callback, void *user_data)
  11. {
  12. status_t ret = NO_ERROR;

  13. LOG_FUNCTION_NAME;

  14. mEndImageCaptureCallback= callback;
  15. mEndCaptureData = user_data;

  16. LOG_FUNCTION_NAME_EXIT;

  17. return ret;
  18. }
这两个方法实现方式一模一样,只是将传入的函数指针和user_data保存到其中而已
mEndImageCaptureCallback这个方法会在OMXCameraAdapter的fillThisBuffer中被调用,他的实现在
  1. void releaseImageBuffers(void *userData)
  2. {
  3. LOG_FUNCTION_NAME;

  4. if (NULL != userData) {
  5. CameraHal *c = reinterpret_cast<CameraHal *>(userData);//user_data就是指向我们实例化的OMXCameraAdapter变量mCameraAdapter
  6. c->freeImageBufs();//接着调用mCameraAdapter的freeImageBufs方法
  7. }

  8. LOG_FUNCTION_NAME_EXIT;
  9. }
  1. status_t CameraHal::freeImageBufs()
  2. {
  3. status_t ret = NO_ERROR;

  4. LOG_FUNCTION_NAME;

  5. if ( NO_ERROR == ret )
  6. {

  7. if( NULL != mImageBufs )
  8. {

  9. ///@todo Pluralise the name of this method to freeBuffers
  10. ret = mMemoryManager->freeBuffer(mImageBufs);//通过memoryManager释放内存
  11. mImageBufs = NULL;

  12. }
  13. else
  14. {
  15. ret = -EINVAL;
  16. }

  17. }

  18. LOG_FUNCTION_NAME_EXIT;

  19. return ret;
  20. }
mReleaseImageBuffersCallback 这个方法将在OMXCapture.cpp中被调用,他的实现和上面是相似的,就不再说了

二.AppCallbackNotifier的实例化和初始化
AppCallbackNotifier这个类是没有实现构造函数的,我们就先看看他的initialize方法吧
  1. /**
  2. * NotificationHandler class
  3. */

  4. ///Initialization function for AppCallbackNotifier
  5. status_t AppCallbackNotifier::initialize()
  6. {
  7. LOG_FUNCTION_NAME;

  8. mPreviewMemory = 0;

  9. mMeasurementEnabled = false;

  10. mNotifierState = NOTIFIER_STOPPED;

  11. ///Create the app notifier thread
  12. mNotificationThread = new NotificationThread(this);
  13. if(!mNotificationThread.get())
  14. {
  15. CAMHAL_LOGEA("Couldn't create Notification thread");
  16. return NO_MEMORY;
  17. }

  18. ///Start the display thread
  19. status_t ret = mNotificationThread->run("NotificationThread", PRIORITY_URGENT_DISPLAY);
  20. if(ret!=NO_ERROR)
  21. {
  22. CAMHAL_LOGEA("Couldn't run NotificationThread");
  23. mNotificationThread.clear();
  24. return ret;
  25. }

  26. mUseMetaDataBufferMode = true;
  27. mRawAvailable = false;

  28. mRecording = false;
  29. mPreviewing = false;

  30. LOG_FUNCTION_NAME_EXIT;

  31. return ret;
  32. }
这个initialize方法做的事情相对简单但是有及其重要,他创建了一个notificationthread,然后运行这个thread
这里我们看看这个很忙碌的线程都干了些什么事情,之所以说他忙碌,是因为他一直不停的等待消息,有消息就处理,不能磨叽磨叽的

  1. bool AppCallbackNotifier::notificationThread()
  2. {
  3. bool shouldLive = true;
  4. status_t ret;

  5. LOG_FUNCTION_NAME;

  6. //CAMHAL_LOGDA("Notification Thread waiting for message");
  7. ret = TIUTILS::MessageQueue::waitForMsg(&mNotificationThread->msgQ(),
  8. &mEventQ,
  9. &mFrameQ,
  10. AppCallbackNotifier::NOTIFIER_TIMEOUT);

  11. //CAMHAL_LOGDA("Notification Thread received message");
  12. //上面等待message,消息到来时开始往下运行,之后区分这些消息到底是什么消息,就像邮局收到邮件接着往下分发一样
  13. if (mNotificationThread->msgQ().hasMsg()) {
  14. ///Received a message from CameraHal, process it
  15. CAMHAL_LOGDA("Notification Thread received message from Camera HAL");
  16. shouldLive = processMessage();//先进行消息的筛选,这里跳出有问题的邮件抛弃掉,收到NOTIFIER_EXIT消息则退出
  17. if(!shouldLive) {
  18. CAMHAL_LOGDA("Notification Thread exiting.");
  19. return shouldLive;
  20. }
  21. }

  22. if(mEventQ.hasMsg()) {
  23. ///Received an event from one of the event providers
  24. CAMHAL_LOGDA("Notification Thread received an event from event provider (CameraAdapter)");
  25. notifyEvent();//分类完成就分类处理了,这里是enent 事件的处理
  26. }

  27. if(mFrameQ.hasMsg()) {
  28. ///Received a frame from one of the frame providers
  29. //CAMHAL_LOGDA("Notification Thread received a frame from frame provider (CameraAdapter)");
  30. notifyFrame();//分类完成就分类处理了,这里是frame 事件的处理
  31. }

  32. LOG_FUNCTION_NAME_EXIT;
  33. return shouldLive;
  34. }
这里先看一下notifyEvent方法的处理过程:
  1. void AppCallbackNotifier::notifyEvent()
  2. {
  3. ///Receive and send the event notifications to app
  4. TIUTILS::Message msg;
  5. LOG_FUNCTION_NAME;
  6. {
  7. Mutex::Autolock lock(mLock);
  8. if ( !mEventQ.hasMsg() ) {
  9. return;
  10. } else {
  11. mEventQ.get(&msg);
  12. }
  13. }
  14. bool ret = true;
  15. CameraHalEvent *evt = NULL;
  16. CameraHalEvent::FocusEventData *focusEvtData;
  17. CameraHalEvent::ZoomEventData *zoomEvtData;
  18. CameraHalEvent::MetaEventData metaEvtData;

  19. if(mNotifierState != AppCallbackNotifier::NOTIFIER_STARTED)
  20. {
  21. return;
  22. }

  23. switch(msg.command)
  24. {
  25. case AppCallbackNotifier::NOTIFIER_CMD_PROCESS_EVENT:

  26. evt = ( CameraHalEvent * ) msg.arg1;

  27. if ( NULL == evt )
  28. {
  29. CAMHAL_LOGEA("Invalid CameraHalEvent");
  30. return;
  31. }

  32. switch(evt->mEventType)
  33. {
  34. case CameraHalEvent::EVENT_SHUTTER:

  35. if ( ( NULL != mCameraHal ) &&
  36. ( NULL != mNotifyCb ) &&
  37. ( mCameraHal->msgTypeEnabled(CAMERA_MSG_SHUTTER) ) )
  38. {
  39. mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
  40. }
  41. mRawAvailable = false;

  42. break;

  43. case CameraHalEvent::EVENT_FOCUS_LOCKED:
  44. case CameraHalEvent::EVENT_FOCUS_ERROR:

  45. focusEvtData = &evt->mEventData->focusEvent;
  46. if ( ( focusEvtData->focusStatus == CameraHalEvent::FOCUS_STATUS_SUCCESS ) &&
  47. ( NULL != mCameraHal ) &&
  48. ( NULL != mNotifyCb ) &&
  49. ( mCameraHal->msgTypeEnabled(CAMERA_MSG_FOCUS) ) ) {
  50. mCameraHal->disableMsgType(CAMERA_MSG_FOCUS);
  51. mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie);
  52. } else if ( ( focusEvtData->focusStatus == CameraHalEvent::FOCUS_STATUS_FAIL ) &&
  53. ( NULL != mCameraHal ) &&
  54. ( NULL != mNotifyCb ) &&
  55. ( mCameraHal->msgTypeEnabled(CAMERA_MSG_FOCUS) ) ) {
  56. mCameraHal->disableMsgType(CAMERA_MSG_FOCUS);
  57. mNotifyCb(CAMERA_MSG_FOCUS, false, 0, mCallbackCookie);
  58. }

  59. break;

  60. case CameraHalEvent::EVENT_ZOOM_INDEX_REACHED:

  61. zoomEvtData = &evt->mEventData->zoomEvent;

  62. if ( ( NULL != mCameraHal ) &&
  63. ( NULL != mNotifyCb) &&
  64. ( mCameraHal->msgTypeEnabled(CAMERA_MSG_ZOOM) ) )
  65. {
  66. mNotifyCb(CAMERA_MSG_ZOOM, zoomEvtData->currentZoomIndex, zoomEvtData->targetZoomIndexReached, mCallbackCookie);
  67. }

  68. break;

  69. case CameraHalEvent::EVENT_METADATA:

  70. metaEvtData = evt->mEventData->metadataEvent;

  71. if ( ( NULL != mCameraHal ) &&
  72. ( NULL != mNotifyCb) &&
  73. ( mCameraHal->msgTypeEnabled(CAMERA_MSG_PREVIEW_METADATA) ) )
  74. {
  75. // WA for an issue inside CameraService
  76. camera_memory_t *tmpBuffer = mRequestMemory(-1, 1, 1, NULL);

  77. mDataCb(CAMERA_MSG_PREVIEW_METADATA,
  78. tmpBuffer,
  79. 0,
  80. metaEvtData->getMetadataResult(),
  81. mCallbackCookie);

  82. metaEvtData.clear();

  83. if ( NULL != tmpBuffer ) {
  84. tmpBuffer->release(tmpBuffer);
  85. }

  86. }

  87. break;

  88. case CameraHalEvent::ALL_EVENTS:
  89. break;
  90. default:
  91. break;
  92. }

  93. break;
  94. }

  95. if ( NULL != evt )
  96. {
  97. delete evt;
  98. }


  99. LOG_FUNCTION_NAME_EXIT;

  100. }
针对每个不同消息处理方法基本是相同的,主要通过上次register好的callback方法,这个之前已经在文章中说过,不在多做说明
这里还是比较重要的,但不是这篇文章的重点,之后有机会还会在说
再看一下notifyFrame的处理过程:
算了,我还是不把他的处理过程贴出来,怕吓到人,挺庞大的,处理了很多事件,当然重要,先知道,再看吧

这里你处理了notifyEvent和notifyFrame这里消息,但是这些消息是从哪里来呢?知道了接收者,那么就必须找到发送者
mAppCallbackNotifier->setEventProvider(eventMask, mCameraAdapter);
mAppCallbackNotifier->setFrameProvider(mCameraAdapter);
不错,就是在这里指定了enent和frame消息的提供者(provider)
先看看setEventProvider的实现
  1. void AppCallbackNotifier::setEventProvider(int32_t eventMask, MessageNotifier * eventNotifier)
  2. {

  3. LOG_FUNCTION_NAME;
  4. ///@remarks There is no NULL check here. We will check
  5. ///for NULL when we get start command from CameraHal
  6. ///@Remarks Currently only one event provider (CameraAdapter) is supported
  7. ///@todo Have an array of event providers for each event bitmask
  8. mEventProvider = new EventProvider(eventNotifier, this, eventCallbackRelay);
  9. if ( NULL == mEventProvider )
  10. {
  11. CAMHAL_LOGEA("Error in creating EventProvider");
  12. }
  13. else
  14. {
  15. mEventProvider->enableEventNotification(eventMask);
  16. }

  17. LOG_FUNCTION_NAME_EXIT;
  18. }
实例化了一个EnentProvider的对象,并且enable EventNotification
再看看setFrameProvider的实现吧
  1. void AppCallbackNotifier::setFrameProvider(FrameNotifier *frameNotifier)
  2. {
  3. LOG_FUNCTION_NAME;
  4. ///@remarks There is no NULL check here. We will check
  5. ///for NULL when we get the start command from CameraAdapter
  6. mFrameProvider = new FrameProvider(frameNotifier, this, frameCallbackRelay);
  7. if ( NULL == mFrameProvider )
  8. {
  9. CAMHAL_LOGEA("Error in creating FrameProvider");
  10. }
  11. else
  12. {
  13. //Register only for captured images and RAW for now
  14. //TODO: Register for and handle all types of frames
  15. mFrameProvider->enableFrameNotification(CameraFrame::IMAGE_FRAME);
  16. mFrameProvider->enableFrameNotification(CameraFrame::RAW_FRAME);
  17. }

  18. LOG_FUNCTION_NAME_EXIT;
  19. }
方法基本一致,实例化一个FrameProvider的对象,并且enable FrameNotification
但是这里必须分析一下FrameProvider的构造方法
  1. FrameProvider(FrameNotifier *fn, void* cookie, frame_callback frameCallback)
  2. :mFrameNotifier(fn), mCookie(cookie),mFrameCallback(frameCallback) { }
这里通过传入的参数实例化了mFrameNotifier,初始化了mCookie,初始化了mFrameCallback,看似没什么却至关只要啊,后面你会知道的,同样EventProvider同样的

FrameProvider和EnentProvider接口的实现在CameraHalUtilClasses.cpp文件
接着往下走:Start the callback notifier
mAppCallbackNotifier->start()
  1. status_t AppCallbackNotifier::start()
  2. {
  3. LOG_FUNCTION_NAME;
  4. if(mNotifierState==AppCallbackNotifier::NOTIFIER_STARTED)
  5. {
  6. CAMHAL_LOGDA("AppCallbackNotifier already running");
  7. LOG_FUNCTION_NAME_EXIT;
  8. return ALREADY_EXISTS;
  9. }

  10. ///Check whether initial conditions are met for us to start
  11. ///A frame provider should be available, if not return error
  12. if(!mFrameProvider)
  13. {
  14. ///AppCallbackNotifier not properly initialized
  15. CAMHAL_LOGEA("AppCallbackNotifier not properly initialized - Frame provider is NULL");
  16. LOG_FUNCTION_NAME_EXIT;
  17. return NO_INIT;
  18. }

  19. ///At least one event notifier should be available, if not return error
  20. ///@todo Modify here when there is an array of event providers
  21. if(!mEventProvider)
  22. {
  23. CAMHAL_LOGEA("AppCallbackNotifier not properly initialized - Event provider is NULL");
  24. LOG_FUNCTION_NAME_EXIT;
  25. ///AppCallbackNotifier not properly initialized
  26. return NO_INIT;
  27. }

  28. mNotifierState = AppCallbackNotifier::NOTIFIER_STARTED;
  29. CAMHAL_LOGDA(" --> AppCallbackNotifier NOTIFIER_STARTED \n");

  30. gEncoderQueue.clear();

  31. LOG_FUNCTION_NAME_EXIT;

  32. return NO_ERROR;

  33. }
只是做了一下检查,最后clear了编码队列
接着走:mAppCallbackNotifier->setMeasurements
  1. void AppCallbackNotifier::setMeasurements(bool enable)
  2. {
  3. Mutex::Autolock lock(mLock);

  4. LOG_FUNCTION_NAME;

  5. mMeasurementEnabled = enable;

  6. if ( enable )
  7. {
  8. mFrameProvider->enableFrameNotification(CameraFrame::FRAME_DATA_SYNC);
  9. }

  10. LOG_FUNCTION_NAME_EXIT;
  11. }
AppCallbackNotifier对象实例化以及初始化到这里完成了

三.MemoryManager的实例化和初始化
无疑这个类跟内存有着很密切的关系,这个定义了自己的构造函数,但是这里不说了,是在大财小用了,只一条语句,直接看看他的initialize方法吧
  1. status_t MemoryManager::initialize() {
  2. if ( mIonFd == -1 ) {
  3. mIonFd = ion_open();
  4. if ( mIonFd < 0 ) {
  5. CAMHAL_LOGE("ion_open() failed, error: %d", mIonFd);
  6. mIonFd = -1;
  7. return NO_INIT;
  8. }
  9. }

  10. return OK;
  11. }
只是调用了ion_open这个方法获得了一个fd
  1. int ion_open()
  2. {
  3. int fd = open("/dev/ion", O_RDWR);
  4. if (fd < 0)
  5. LOGE("open /dev/ion failed!\n");
  6. return fd;
  7. }
开始时我晕了,ion到底是什么device啊?赶紧查一查
这里我不做过多说明,可以看看这个分享,同时感谢大牛的分享:http://blog.csdn.net/melody_lu123/article/details/7556820
ION与PMEM类似,管理一或多个内存池,其中有一些会在boot time的时候预先分配,以备给特殊的硬件使用(GPU,显示控制器等)。它通过ION heaps来管理这些pool。
它可以被userspace的process之间或者内核中的模块之间进行内存共享

四.SensorListener的实例化和初始化
在SensorListener的构造函数中对一些参数进行了默认初始化,这里不知说明,直接看看他的initialize方法实现
  1. status_t SensorListener::initialize() {
  2. status_t ret = NO_ERROR;
  3. SensorManager& mgr(SensorManager::getInstance());

  4. LOG_FUNCTION_NAME;

  5. sp<Looper> mLooper;

  6. mSensorEventQueue = mgr.createEventQueue();
  7. if (mSensorEventQueue == NULL) {
  8. CAMHAL_LOGEA("createEventQueue returned NULL");
  9. ret = NO_INIT;
  10. goto out;
  11. }

  12. mLooper = new Looper(false);
  13. mLooper->addFd(mSensorEventQueue->getFd(), 0, ALOOPER_EVENT_INPUT, sensor_events_listener, this);

  14. if (mSensorLooperThread.get() == NULL)
  15. mSensorLooperThread = new SensorLooperThread(mLooper.get());

  16. if (mSensorLooperThread.get() == NULL) {
  17. CAMHAL_LOGEA("Couldn't create sensor looper thread");
  18. ret = NO_MEMORY;
  19. goto out;
  20. }

  21. ret = mSensorLooperThread->run("sensor looper thread", PRIORITY_URGENT_DISPLAY);
  22. if (ret == INVALID_OPERATION){
  23. CAMHAL_LOGDA("thread already running ?!?");
  24. } else if (ret != NO_ERROR) {
  25. CAMHAL_LOGEA("couldn't run thread");
  26. goto out;
  27. }

  28. out:
  29. LOG_FUNCTION_NAME_EXIT;
  30. return ret;
  31. }
看到这里我个人是感觉这里挺抽象的,这里先简单说明一下,这里首先获取到SensorManager,通过这个SensorManager创建一个EventQueue,然后实例化一个Looper对象,将这个EventQueue的fd添加到mLooper中,最后创建一个SensorLooperThread,并启动这个线程
下一步:mSensorListener->setCallbacks(orientation_cb, this);
  1. void SensorListener::setCallbacks(orientation_callback_t orientation_cb, void *cookie) {
  2. LOG_FUNCTION_NAME;

  3. if (orientation_cb) {
  4. mOrientationCb = orientation_cb;
  5. }
  6. mCbCookie = cookie;

  7. LOG_FUNCTION_NAME_EXIT;
  8. }
这里的方法跟上面讲过的setcallback方法其实基本是相通的,注册的这个回调函数是在以下方法中被调用到的
  1. void SensorListener::handleOrientation(uint32_t orientation, uint32_t tilt) {
  2. LOG_FUNCTION_NAME;

  3. Mutex::Autolock lock(&mLock);

  4. if (mOrientationCb && (sensorsEnabled & SENSOR_ORIENTATION)) {
  5. mOrientationCb(orientation, tilt, mCbCookie);
  6. }

  7. LOG_FUNCTION_NAME_EXIT;
  8. }
也就低调用一下方法:

  1. static void orientation_cb(uint32_t orientation, uint32_t tilt, void* cookie) {
  2. CameraHal *camera = NULL;

  3. if (cookie) {
  4. camera = (CameraHal*) cookie;//这个cookie(this)指向我们实例化mCameraAdapter
  5. camera->onOrientationEvent(orientation, tilt);//调用mCameraHal的onOrientationEvent方法
  6. }

  7. }
我们接着跟踪下去:
  1. /**
  2. Callback function to receive orientation events from SensorListener
  3. */
  4. void CameraHal::onOrientationEvent(uint32_t orientation, uint32_t tilt) {
  5. LOG_FUNCTION_NAME;

  6. if ( NULL != mCameraAdapter ) {
  7. mCameraAdapter->onOrientationEvent(orientation, tilt);
  8. }

  9. LOG_FUNCTION_NAME_EXIT;
  10. }
继续,实现在OMXCameraAdapter中
  1. void OMXCameraAdapter::onOrientationEvent(uint32_t orientation, uint32_t tilt)
  2. {
  3. LOG_FUNCTION_NAME;

  4. static const unsigned int DEGREES_TILT_IGNORE = 45;

  5. // if tilt angle is greater than DEGREES_TILT_IGNORE
  6. // we are going to ignore the orientation returned from
  7. // sensor. the orientation returned from sensor is not
  8. // reliable. Value of DEGREES_TILT_IGNORE may need adjusting
  9. if (tilt > DEGREES_TILT_IGNORE) {
  10. return;
  11. }

  12. int mountOrientation = 0;
  13. bool isFront = false;
  14. if (mCapabilities) {
  15. const char * const mountOrientationString =
  16. mCapabilities->get(CameraProperties::ORIENTATION_INDEX);
  17. if (mountOrientationString) {
  18. mountOrientation = atoi(mountOrientationString);
  19. }

  20. const char * const facingString = mCapabilities->get(CameraProperties::FACING_INDEX);
  21. if (facingString) {
  22. isFront = strcmp(facingString, TICameraParameters::FACING_FRONT) == 0;
  23. }
  24. }

  25. // direction is a constant sign for facing, meaning the rotation direction relative to device
  26. // +1 (clockwise) for back sensor and -1 (counter-clockwise) for front sensor
  27. const int direction = isFront ? -1 : 1;

  28. int rotation = mountOrientation + direction*orientation;

  29. // crop the calculated value to [0..360) range
  30. while ( rotation < 0 ) rotation += 360;
  31. rotation %= 360;

  32. if (rotation != mDeviceOrientation) {
  33. mDeviceOrientation = rotation;

  34. // restart face detection with new rotation
  35. setFaceDetectionOrientation(mDeviceOrientation);
  36. }
  37. CAMHAL_LOGVB("orientation = %d tilt = %d device_orientation = %d", orientation, tilt, mDeviceOrientation);

  38. LOG_FUNCTION_NAME_EXIT;
  39. }
这里暂时不做分析

最后一步:mSensorListener->enableSensor(SensorListener::SENSOR_ORIENTATION)
  1. void SensorListener::enableSensor(sensor_type_t type) {
  2. Sensor const* sensor;
  3. SensorManager& mgr(SensorManager::getInstance());

  4. LOG_FUNCTION_NAME;

  5. Mutex::Autolock lock(&mLock);

  6. if ((type & SENSOR_ORIENTATION) && !(sensorsEnabled & SENSOR_ORIENTATION)) {
  7. sensor = mgr.getDefaultSensor(Sensor::TYPE_ACCELEROMETER);
  8. CAMHAL_LOGDB("orientation = %p (%s)", sensor, sensor->getName().string());
  9. mSensorEventQueue->enableSensor(sensor);
  10. mSensorEventQueue->setEventRate(sensor, ms2ns(100));
  11. sensorsEnabled |= SENSOR_ORIENTATION;
  12. }

  13. LOG_FUNCTION_NAME_EXIT;
  14. }
使能sensor
到这里为止CameraHal的这个初始化过程完成了,这里个人感觉十分重要,其他的接口实现固然重要,但是清清楚楚的知道这个初始化过程会让你hal与上层和底层的交互先有一个大体的认知,这比你一头扎进去到处乱撞要高效很多

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多