Android Camera OMXCameraAdapter.cpp初始化分析
这几天一直在研究android 的omx机制,我针对的android是4.0.3,主要是TI 的4430,4460的omx方式实现,这里还是简单的说一下为什么要研究这个文件
之前有一篇文章已经比较详细的说过了OMAP4系列芯片了,这里这个OMXCameraAdapter其实就是omap4 A9端的omx client,通过这个client与ducati端(也就是omap4的DSP端)的omx进行通信,可以把ducati端的这个omx简单理解为omx servicer,之前已经说了很多了andriod camera了,但是之前文章都是针对V4LCameraAdapter这个适配器进行的,这是大家都比较了解的,就是app通过V4L2这种方式与kernel cameradriver实现交互,进而实现camera 的使用,包括数据回调等过程,但是这里的OMX方法完全颠覆了我之前的想法,开始在研究OMX的时候自己就是调用这个死胡同里了,一直在试图在OMX的实现中找到他到底是在哪么访问设备的,本来我是以后最终他还是通过V4L2这种方式,事实证明我错了,OMX是一种完全不同于V4L2的访问camera的策略,他通过A9端的omx client和DSP端的omx通信,而且最终访问camera的方法是在DSP端omx server接到到A9端的omx client配置后按照指定方法实现camera 的控制的,这里ducati端到底是怎么处理的我暂时没有关注,暂时精力有限啊!
以上是我自己的见解,也许是完全错误的,待确认,这里只是总结我的分析过程
经过上面我的概述,自然A9端的这个OMXCameraAdapter对于我来说就是一切了,分析它是必经之路啊
现在就开始:
首先要知道在哪里实例化了这个类的对象,这个在之前已经说到过了,这个不在说明,重点看看他的initialize方法都干了些甚么?
  1. /*--------------------Camera AdapterClassSTARTS here-----------------------------*/

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

  5. char value[PROPERTY_VALUE_MAX];
  6. constchar*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 previewandimage capture port indexes
  32. mCameraAdapterParameters.mPrevPortIndex=OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
  33. //temp changedinordertobuild 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. //currentlynotsupported 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.Getthe handletothe 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,OMX_CommandPortDisable,OMX_ALL,NULL);

  61. if(eError!=OMX_ErrorNone){
  62. CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortDisable) -0x%x",eError);
  63. }
  64. GOTO_EXIT_IF((eError!=OMX_ErrorNone),eError);

  65. //4.Registerforport enable event
  66. ret=RegisterForEvent(mCameraAdapterParameters.mHandleComp,
  67. OMX_EventCmdComplete,
  68. OMX_CommandPortEnable,
  69. mCameraAdapterParameters.mPrevPortIndex,
  70. mInitSem);
  71. if(ret!=NO_ERROR){
  72. CAMHAL_LOGEB("Error in registering for event %d",ret);
  73. gotoEXIT;
  74. }

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

  84. //6.Waitforthe port enable eventtooccur
  85. ret=mInitSem.WaitTimeout(OMX_CMD_TIMEOUT);
  86. if(NO_ERROR==ret){
  87. CAMHAL_LOGDA("-Port enable event arrived");
  88. }else{
  89. ret|=RemoveEvent(mCameraAdapterParameters.mHandleComp,
  90. OMX_EventCmdComplete,
  91. OMX_CommandPortEnable,
  92. mCameraAdapterParameters.mPrevPortIndex,
  93. NULL);
  94. CAMHAL_LOGEA("Timeout for enabling preview port expired!");
  95. gotoEXIT;
  96. }

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

  108. #ifdef CAMERAHAL_DEBUG

  109. printComponentVersion(mCameraAdapterParameters.mHandleComp);

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

  124. mCaptureSignalled=false;
  125. mCaptureConfigured=false;
  126. mReprocConfigured=false;
  127. mRecording=false;
  128. mWaitingForSnapshot=false;
  129. mPictureFormatFromClient=NULL;

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

  159. mEXIFData.mGPSData.mAltitudeValid=false;
  160. mEXIFData.mGPSData.mDatestampValid=false;
  161. mEXIFData.mGPSData.mLatValid=false;
  162. mEXIFData.mGPSData.mLongValid=false;
  163. mEXIFData.mGPSData.mMapDatumValid=false;
  164. mEXIFData.mGPSData.mProcMethodValid=false;
  165. mEXIFData.mGPSData.mVersionIdValid=false;
  166. mEXIFData.mGPSData.mTimeStampValid=false;
  167. mEXIFData.mModelValid=false;
  168. mEXIFData.mMakeValid=false;

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

  176. if(mSensorIndex!=2){
  177. mCapabilities->setMode(MODE_HIGH_SPEED);
  178. }

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

  184. //9.initialize command handling thread
  185. if(mCommandHandler.get()==NULL)
  186. mCommandHandler=new CommandHandler(this);

  187. if(NULL==mCommandHandler.get())
  188. {
  189. CAMHAL_LOGEA("Couldn't create command handler");
  190. return NO_MEMORY;
  191. }

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

  203. //10.initialize omx callback handling thread
  204. if(mOMXCallbackHandler.get()==NULL)
  205. mOMXCallbackHandler=new OMXCallbackHandler(this);

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

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

  222. OMX_INIT_STRUCT_PTR(&mRegionPriority,OMX_TI_CONFIG_3A_REGION_PRIORITY);
  223. OMX_INIT_STRUCT_PTR(&mFacePriority,OMX_TI_CONFIG_3A_FACE_PRIORITY);
  224. mRegionPriority.nPortIndex=OMX_ALL;
  225. mFacePriority.nPortIndex=OMX_ALL;

  226. //Setting this flag will that the first setParametercallwill apply all 3A settings
  227. //andwillnotconditionally apply basedoncurrent values.
  228. mFirstTimeInit=true;

  229. //Flagtoavoid calling setVFramerate()before OMX_SetParameter(OMX_IndexParamPortDefinition)
  230. //Ducati will return anerrorotherwise.
  231. mSetFormatDone=false;

  232. memset(mExposureBracketingValues,0,EXP_BRACKET_RANGE*sizeof(int));
  233. memset(mZoomBracketingValues,0,ZOOM_BRACKET_RANGE*sizeof(int));
  234. mMeasurementEnabled=false;
  235. mFaceDetectionRunning=false;
  236. mFaceDetectionPaused=false;
  237. mFDSwitchAlgoPriority=false;

  238. memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex],0,sizeof(OMXCameraPortParameters));
  239. memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex],0,sizeof(OMXCameraPortParameters));
  240. memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex],0,sizeof(OMXCameraPortParameters));
  241. memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex],0,sizeof(OMXCameraPortParameters));

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

  259. mParameters3A.ManualExposure=0;
  260. mParameters3A.ManualExposureRight=0;
  261. mParameters3A.ManualGain=0;
  262. mParameters3A.ManualGainRight=0;

  263. mParameters3A.AlgoFixedGamma=OMX_TRUE;
  264. mParameters3A.AlgoNSF1=OMX_TRUE;
  265. mParameters3A.AlgoNSF2=OMX_TRUE;
  266. mParameters3A.AlgoSharpening=OMX_TRUE;
  267. mParameters3A.AlgoThreeLinColorMap=OMX_TRUE;
  268. mParameters3A.AlgoGIC=OMX_TRUE;

  269. LOG_FUNCTION_NAME_EXIT;
  270. return ErrorUtils::omxToAndroidError(eError);

  271. EXIT:

  272. CAMHAL_LOGDB("Exiting function %s because of ret %d eError=%x",__FUNCTION__,ret,eError);
  273. performCleanupAfterError();
  274. LOG_FUNCTION_NAME_EXIT;
  275. return ErrorUtils::omxToAndroidError(eError);
  276. }
就是这里了,下面对上面的方法按步骤一一做分析

1.OMX_Init
从字面上就可以知道,要使用OMX这个方式,那就要为使用它做准备啊,初始化,但我们还是严谨点,说一说吧,
  1. /**The OMX_Init methodisusedtoinitialize the OMX core.It shall be the
  2. firstcallmade into OMXandit should only be executed onetimewithout
  3. an interviening OMX_Deinitcall.

  4. The core should return from thiscallwithin 20 msec.

  5. @return OMX_ERRORTYPE
  6. Ifthe command successfully executes,the return code will be
  7. OMX_ErrorNone.Otherwise the appropriate OMXerrorwill be returned.
  8. @ingroup core
  9. */
  10. OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);

2.Initialize the callback handles
这里初始化callback handle,那么上面初始化了三个handle,这三个handle具体都实现什么用途呢?
当然一下不是我说的,是TI为方便大家理解,在andriod底层加入了很多很全的注释,一起看看吧
  1. typedef struct OMX_CALLBACKTYPE
  2. {
  3. /**The EventHandler methodisusedtonotify the application when an
  4. event of interest occurs.Events are definedinthe OMX_EVENTTYPE
  5. enumeration.Please see that enumerationfordetails of what will
  6. be returnedforeachtype of event.Callbacks shouldnotreturn
  7. anerrortothe component,soifanerroroccurs,the application
  8. shall handle it internally.Thisisa blockingcall.

  9. The application should return from thiscallwithin 5 msectoavoid
  10. blocking the componentforan excessively long period oftime.

  11. @param hComponent
  12. handle of the componenttoaccess.Thisisthe component
  13. handle returned by thecalltothe GetHandlefunction.
  14. @param pAppData
  15. pointertoan application defined value that was providedinthe
  16. pAppData parametertothe OMX_GetHandle methodforthe component.
  17. This application defined valueisprovided so that the application
  18. can have a component specific context when receiving the callback.
  19. @param eEvent
  20. Event that the component wantstonotify the application about.
  21. @param nData1
  22. nData will be the OMX_ERRORTYPEforanerroreventandwill be
  23. an OMX_COMMANDTYPEfora command complete eventandOMX_INDEXTYPEfora OMX_PortSettingsChanged event.
  24. @param nData2
  25. nData2 will hold further information relatedtothe event.Can be OMX_STATETYPEfor
  26. a OMX_CommandStateSet commandorport indexfora OMX_PortSettingsChanged event.
  27. Default valueis0ifnotused.)
  28. @param pEventData
  29. Pointertoadditional event-specific data(see specformeaning).
  30. */

  31. OMX_ERRORTYPE(*EventHandler)(
  32. OMX_IN OMX_HANDLETYPE hComponent,
  33. OMX_IN OMX_PTR pAppData,
  34. OMX_IN OMX_EVENTTYPE eEvent,
  35. OMX_IN OMX_U32 nData1,
  36. OMX_IN OMX_U32 nData2,
  37. OMX_IN OMX_PTR pEventData);

  38. /**The EmptyBufferDone methodisusedtoreturn emptied buffers from an
  39. input port backtothe applicationforreuse.Thisisa blockingcall
  40. so the application shouldnotattempttorefill the buffers during this
  41. call,but should queue themandrefill theminanother thread.There
  42. isnoerrorreturn,so the application shall handle any errors generated
  43. internally.

  44. The application should return from thiscallwithin 5 msec.

  45. @param hComponent
  46. handle of the componenttoaccess.Thisisthe component
  47. handle returned by thecalltothe GetHandlefunction.
  48. @param pAppData
  49. pointertoan application defined value that was providedinthe
  50. pAppData parametertothe OMX_GetHandle methodforthe component.
  51. This application defined valueisprovided so that the application
  52. can have a component specific context when receiving the callback.
  53. @param pBuffer
  54. pointertoan OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
  55. orAllocateBuffer indicating the buffer that was emptied.
  56. @ingroup buf
  57. */
  58. OMX_ERRORTYPE(*EmptyBufferDone)(
  59. OMX_IN OMX_HANDLETYPE hComponent,
  60. OMX_IN OMX_PTR pAppData,
  61. OMX_IN OMX_BUFFERHEADERTYPE*pBuffer);

  62. /**The FillBufferDone methodisusedtoreturn filled buffers from an
  63. output port backtothe applicationforemptyingandthenreuse.
  64. Thisisa blockingcallso the application shouldnotattemptto
  65. emptythe buffers during thiscall,but should queue the buffers
  66. andemptytheminanother thread.Thereisnoerrorreturn,so
  67. the application shall handle any errors generated internally.The
  68. application shall also update the buffer headertoindicate the
  69. number of bytes placed into the buffer.

  70. The application should return from thiscallwithin 5 msec.

  71. @param hComponent
  72. handle of the componenttoaccess.Thisisthe component
  73. handle returned by thecalltothe GetHandlefunction.
  74. @param pAppData
  75. pointertoan application defined value that was providedinthe
  76. pAppData parametertothe OMX_GetHandle methodforthe component.
  77. This application defined valueisprovided so that the application
  78. can have a component specific context when receiving the callback.
  79. @param pBuffer
  80. pointertoan OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
  81. orAllocateBuffer indicating the buffer that was filled.
  82. @ingroup buf
  83. */
  84. OMX_ERRORTYPE(*FillBufferDone)(
  85. OMX_OUT OMX_HANDLETYPE hComponent,
  86. OMX_OUT OMX_PTR pAppData,
  87. OMX_OUT OMX_BUFFERHEADERTYPE*pBuffer);

  88. }OMX_CALLBACKTYPE;
EmptyBufferDone方法用来实现从组件的输入端口获取到空的缓冲区返回给应用层使得可以重新被使用,这是一个阻塞型的调用,这个调用期间你不可以使用fillThisBuffer方法去fill这个缓冲区,你应该在另外一个线程中进行这个工作,这个回调方法不会提示error信息,所以需要用户端自己去分辨,并处理这些信息,保存错误信息;
EventHandler方法用来通知应用层一些应用层可能感兴趣的一些事件,事件分很多类型,已经用枚举方式定义在 OMX_EVENTTYPE中, 这个回调方法同样不会提示error信息,所以需要用户端自己去分辨,并处理这些信息,保存错误信息;
FillBufferDone方法用来实现从组件的输出端口获取到经过解码等很多操作的buffer,并且放回给应用层,应用层获取使用后,在通过emptyThisBuffer方法清空buffer再次利用, 这个回调方法同样不会提示error信息,所以需要用户端自己去分辨,并处理这些信息,保存错误信息,这里应用层还有一件很重要的事情要做,应用程序要更新缓冲区header的位置,新数据加入,header后移;

3.Get the handle to the OMX Component
  1. OMX_ERRORTYPE OMXCameraAdapter::OMXCameraGetHandle(OMX_HANDLETYPE*handle,OMX_PTR pAppData,
  2. constOMX_CALLBACKTYPE&callbacks)
  3. {
  4. OMX_ERRORTYPE eError=OMX_ErrorUndefined;

  5. for(inti=0;i<5;++i){
  6. if(i>0){
  7. //sleepfor100 ms beforenextattempt
  8. usleep(100000);
  9. }

  10. //setup key parameterstosendtoDucati during init
  11. OMX_CALLBACKTYPE oCallbacks=callbacks;

  12. //gethandle
  13. eError=OMX_GetHandle(handle,(OMX_STRING)"OMX.TI.DUCATI1.VIDEO.CAMERA",pAppData,&oCallbacks);
  14. if(eError==OMX_ErrorNone){
  15. return OMX_ErrorNone;
  16. }

  17. CAMHAL_LOGEB("OMX_GetHandle() failed, error: 0x%x",eError);
  18. }

  19. *handle=0;
  20. return eError;
  21. }
这个传入上面初始化的callbacks,是为了获取到handle,这个handle对应一个组件,每个组件同样拥有自己的callbacks方法,所以这里不同的组件公用callbacks,看看这个OMX_GetHandle吧,因为有注释,可以更好理解啊,嘿嘿
  1. /**The OMX_GetHandle method will locate the component specified by the
  2. component name given,load that component into memoryandtheninvoke
  3. the component's methodstocreate an instance of the component.

  4. The core should return from thiscallwithin 20 msec.

  5. @param[out]pHandle
  6. pointertoan OMX_HANDLETYPE pointertobe filledinby this method.
  7. @param[in]cComponentName
  8. pointertoanullterminatedstringwith the component name.The
  9. names of the components are strings less than 127 bytesinlength
  10. plus the trailingnullfora maximum size of 128 bytes.An example
  11. of a valid component nameis"OMX.TI.AUDIO.DSP.MIXER\0".Names are
  12. assigned by the vendor,but shall start with"OMX."andthenhave
  13. the Vendor designationnext.
  14. @param[in]pAppData
  15. pointertoan application defined value that will be returned
  16. during callbacks so that the application can identify the source
  17. of the callback.
  18. @param[in]pCallBacks
  19. pointertoa OMX_CALLBACKTYPE structure that will be passedtothe
  20. componenttoinitialize it with.
  21. @return OMX_ERRORTYPE
  22. Ifthe command successfully executes,the return code will be
  23. OMX_ErrorNone.Otherwise the appropriate OMXerrorwill be returned.
  24. @ingroup core
  25. */
  26. OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
  27. OMX_OUT OMX_HANDLETYPE*pHandle,
  28. OMX_IN OMX_STRING cComponentName,
  29. OMX_IN OMX_PTR pAppData,
  30. OMX_IN OMX_CALLBACKTYPE*pCallBacks);
这个方法会通过name获取到想要的组件,并且加载组件的内存,请求组件中定义的方法实例化组件

4.设置组件最初状态为OMX_StateLoaded状态,并disable所以command port
mComponentState = OMX_StateLoaded ;
eError = OMX_SendCommand ( mCameraAdapterParameters . mHandleComp , OMX_CommandPortDisable , OMX_ALL , NULL ) ;
这里必须重点说说OMX_SendCommand这个方法
  1. /**Send a commandtothe component.Thiscallisa non-blockingcall.
  2. The component should check the parametersandthenqueue the command
  3. tothe component threadtobe executed.The component thread shall
  4. send the EventHandler()callback at the conclusion of the command.
  5. This macro will go directly from the applicationtothe component(via
  6. a core macro).The component will return from thiscallwithin 5 msec.

  7. When the commandis"OMX_CommandStateSet"the component will queue a
  8. state transitiontothe new state idenfiedinnParam.

  9. When the commandis"OMX_CommandFlush",toflush a port's buffer queues,
  10. the command will force the componenttoreturn all buffersNOTCURRENTLY
  11. BEING PROCESSEDtothe application,inthe orderinwhich the buffers
  12. were received.

  13. When the commandis"OMX_CommandPortDisable"or
  14. "OMX_CommandPortEnable",the component's port(given by the value of
  15. nParam)will be stoppedorrestarted.

  16. When the command"OMX_CommandMarkBuffer"isusedtomark a buffer,the
  17. pCmdData will pointtoa OMX_MARKTYPE structure containing the component
  18. handle of the componenttoexamine the buffer chainforthe mark.nParam1
  19. contains the index of the portonwhich the buffer markisapplied.

  20. Specification textformore details.

  21. @param[in]hComponent
  22. handle of componenttoexecute the command
  23. @param[in]Cmd
  24. Commandforthe componenttoexecute
  25. @param[in]nParam
  26. Parameterforthe commandtobe executed.When Cmd has the value
  27. OMX_CommandStateSet,valueisa member of OMX_STATETYPE.When Cmd has
  28. the value OMX_CommandFlush,value of nParam indicates which port(s)
  29. toflush.-1isusedtoflush all ports a single port index will
  30. only flush that port.When Cmd has the value"OMX_CommandPortDisable"
  31. or"OMX_CommandPortEnable",the component's portisgiven by
  32. the value of nParam.When Cmd has the value"OMX_CommandMarkBuffer"
  33. the components potisgiven by the value of nParam.
  34. @param[in]pCmdData
  35. Parameter pointingtothe OMX_MARKTYPE structure when Cmd has the value
  36. "OMX_CommandMarkBuffer".
  37. @return OMX_ERRORTYPE
  38. Ifthe command successfully executes,the return code will be
  39. OMX_ErrorNone.Otherwise the appropriate OMXerrorwill be returned.
  40. @ingroup comp
  41. */
  42. #define OMX_SendCommand(\
  43. hComponent,\
  44. Cmd,\
  45. nParam,\
  46. pCmdData)\
  47. ((OMX_COMPONENTTYPE*)hComponent)->SendCommand(\
  48. hComponent,\
  49. Cmd,\
  50. nParam,\
  51. pCmdData)/*MacroEnd*/
通过这个方法给组件发送一个command,组件接收到command后会检查传入的参数并将这个command压入队列,待组件的处理线程处理,处理完成后会通过上面初始化的EventHandler通知应用层处理结果,最多不会超出5min,超过则超时报错,具体的command type上面注释中已经说明,简单说明一下吧
在上面参数中分为以下几种情况:
1. Cmd 为 OMX_CommandStateSet
这种command用于组件状态之间的切换
这个第三个参数nParam代表参数类型是 OMX_STATETYPE,是组件的状态参数

2.Cmd 为 OMX_CommandFlush
这种command用于刷新组件缓冲区,不管是否缓冲区经过处理,缓冲区数据都会按照接收的顺序交给应用层
这个第三个参数nParam代表参数类型是组件的port,第四个参数pCmdData都为NULL

3.Cmd 为 OMX_CommandPortDisable或者 OMX_CommandPortEnable
这个情况下,第三个参数nParam代表要设置disable或enable的组件的port,OMX_ALL表示所有的组件,第四个参数pCmdData都为NULL

4.Cmd 为 OMX_CommandMarkBuffer
这种command用于标记组件缓冲区
这个第三个参数nParam代表参数类型是组件的port,第四个参数的类型是OMX_MARKTYPE结构

5.Register for port enable event
调用方式如下:
ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,//这个参数指定组件的handle
OMX_EventCmdComplete,//这个参数是EventType
OMX_CommandPortEnable,//nData1
mCameraAdapterParameters.mPrevPortIndex, //nData2
mInitSem);//这个参数是信号量,保证同步

  1. status_t OMXCameraAdapter::RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,
  2. OMX_IN OMX_EVENTTYPE eEvent,
  3. OMX_IN OMX_U32 nData1,
  4. OMX_IN OMX_U32 nData2,
  5. OMX_IN Semaphore&semaphore)
  6. {
  7. status_t ret=NO_ERROR;
  8. ssize_t res;
  9. Mutex::Autolock lock(mEventLock);

  10. LOG_FUNCTION_NAME;
  11. TIUTILS::Message*msg=(struct TIUTILS::Message*)malloc(sizeof(struct TIUTILS::Message));
  12. if(NULL!=msg)
  13. {
  14. msg->command=(unsignedint)eEvent;
  15. msg->arg1=(void*)nData1;
  16. msg->arg2=(void*)nData2;
  17. msg->arg3=(void*)&semaphore;
  18. msg->arg4=(void*)hComponent;
  19. res=mEventSignalQ.add(msg);
  20. if(NO_MEMORY==res)
  21. {
  22. CAMHAL_LOGEA("No ressources for inserting OMX events");
  23. free(msg);
  24. ret=-ENOMEM;
  25. }
  26. }

  27. LOG_FUNCTION_NAME_EXIT;

  28. return ret;
  29. }
这里将传入的数据打包到message结构中,并且添加到mEventSignalQ队列中,这里先不说为什么,之后再说明

6.Enable PREVIEW Port
eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
OMX_CommandPortEnable,
mCameraAdapterParameters.mPrevPortIndex,
NULL);
前面disable了所有组件,这里保证了只有previewPort enable了

7.Wait for the port enable event to occur
调用过程如下:
ret = mInitSem.WaitTimeout(OMX_CMD_TIMEOUT);
这里我自己的感觉还是比较难于理解,因为自己在看这部分一开始也没有吃透
所以这里是我眼中的重点,重点啊
首先上面第6步 sendcommand to 组件,那么组件就该给应用层以反馈,叫做callback也可以,这里是通过我们上面初始化的OMXCameraAdapterEventHandler这个callback来应答应用层的,我们就看看这个方法的具体实现方法
  1. /*Application callback Functions*/
  2. /*========================================================*/
  3. /*@ fn SampleTest_EventHandler::Application callback*/
  4. /*========================================================*/
  5. OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,
  6. OMX_IN OMX_EVENTTYPE eEvent,
  7. OMX_IN OMX_U32 nData1,
  8. OMX_IN OMX_U32 nData2,
  9. OMX_IN OMX_PTR pEventData)
  10. {

  11. LOG_FUNCTION_NAME;

  12. OMX_ERRORTYPE eError=OMX_ErrorNone;
  13. CAMHAL_LOGDB("+OMX_Event %x, %d %d",eEvent,(int)nData1,(int)nData2);

  14. switch(eEvent){
  15. caseOMX_EventCmdComplete:
  16. CAMHAL_LOGDB("+OMX_EventCmdComplete %d %d",(int)nData1,(int)nData2);

  17. if(OMX_CommandStateSet==nData1){
  18. mCameraAdapterParameters.mState=(OMX_STATETYPE)nData2;

  19. }elseif(OMX_CommandFlush==nData1){
  20. CAMHAL_LOGDB("OMX_CommandFlush received for port %d",(int)nData2);

  21. }elseif(OMX_CommandPortDisable==nData1){
  22. CAMHAL_LOGDB("OMX_CommandPortDisable received for port %d",(int)nData2);

  23. }elseif(OMX_CommandPortEnable==nData1){//我们发送的是OMX_CommandPortEnable命令,所以这了nData1就是command type
  24. CAMHAL_LOGDB("OMX_CommandPortEnable received for port %d",(int)nData2);

  25. }elseif(OMX_CommandMarkBuffer==nData1){
  26. ///Thisisnotused currently
  27. }

  28. CAMHAL_LOGDA("-OMX_EventCmdComplete");
  29. break;

  30. caseOMX_EventIndexSettingChanged:
  31. CAMHAL_LOGDB("OMX_EventIndexSettingChanged event received data1 0x%x, data2 0x%x",
  32. (unsignedint)nData1,(unsignedint)nData2);
  33. break;

  34. caseOMX_EventError:
  35. CAMHAL_LOGDB("OMX interface failed to execute OMX command %d",(int)nData1);
  36. CAMHAL_LOGDA("See OMX_INDEXTYPE for reference");
  37. if(NULL!=mErrorNotifier&&((OMX_U32)OMX_ErrorHardware==nData1)&&mComponentState!=OMX_StateInvalid)
  38. {
  39. CAMHAL_LOGEA("***Got Fatal Error Notification***\n");
  40. mComponentState=OMX_StateInvalid;
  41. /*
  42. Remove any unhandled eventsand
  43. unblock any waiting semaphores
  44. */
  45. if(!mEventSignalQ.isEmpty())
  46. {
  47. for(unsignedinti=0;i<mEventSignalQ.size();i++)
  48. {
  49. CAMHAL_LOGEB("***Removing %d EVENTS***** \n",mEventSignalQ.size());
  50. //remove from queueandfree msg
  51. TIUTILS::Message*msg=mEventSignalQ.itemAt(i);
  52. if(NULL!=msg)
  53. {
  54. Semaphore*sem=(Semaphore*)msg->arg3;
  55. if(sem)
  56. {
  57. sem->Signal();
  58. }
  59. free(msg);
  60. }
  61. }
  62. mEventSignalQ.clear();
  63. }
  64. ///ReportErrortoApp
  65. mErrorNotifier->errorNotify(CAMERA_ERROR_FATAL);
  66. }
  67. break;

  68. caseOMX_EventMark:
  69. break;

  70. caseOMX_EventPortSettingsChanged:
  71. break;

  72. caseOMX_EventBufferFlag:
  73. break;

  74. caseOMX_EventResourcesAcquired:
  75. break;

  76. caseOMX_EventComponentResumed:
  77. break;

  78. caseOMX_EventDynamicResourcesAvailable:
  79. break;

  80. caseOMX_EventPortFormatDetected:
  81. break;

  82. default:
  83. break;
  84. }

  85. ///Signaltothe thread(s)waiting that the event has occured
  86. SignalEvent(hComponent,eEvent,nData1,nData2,pEventData);//这里才是重点

  87. LOG_FUNCTION_NAME_EXIT;
  88. return eError;

  89. EXIT:

  90. CAMHAL_LOGEB("Exiting function %s because of eError=%x",__FUNCTION__,eError);
  91. LOG_FUNCTION_NAME_EXIT;
  92. return eError;
  93. }
我们接着看看 SignalEvent的实现
  1. OMX_ERRORTYPE OMXCameraAdapter::SignalEvent(OMX_IN OMX_HANDLETYPE hComponent,
  2. OMX_IN OMX_EVENTTYPE eEvent,
  3. OMX_IN OMX_U32 nData1,
  4. OMX_IN OMX_U32 nData2,
  5. OMX_IN OMX_PTR pEventData)
  6. {
  7. Mutex::Autolock lock(mEventLock);
  8. TIUTILS::Message*msg;
  9. bool eventSignalled=false;

  10. LOG_FUNCTION_NAME;

  11. if(!mEventSignalQ.isEmpty())
  12. {
  13. CAMHAL_LOGDA("Event queue not empty");

  14. for(unsignedinti=0;i<mEventSignalQ.size();i++)
  15. {
  16. msg=mEventSignalQ.itemAt(i);
  17. if(NULL!=msg)
  18. {
  19. if((msg->command!=0||msg->command==(unsignedint)(eEvent))
  20. &&(!msg->arg1||(OMX_U32)msg->arg1==nData1)
  21. &&(!msg->arg2||(OMX_U32)msg->arg2==nData2)
  22. &&msg->arg3)
  23. {
  24. Semaphore*sem=(Semaphore*)msg->arg3;
  25. CAMHAL_LOGDA("Event matched, signalling sem");
  26. mEventSignalQ.removeAt(i);
  27. //Signal the semaphore provided
  28. sem->Signal();
  29. free(msg);
  30. break;
  31. }
  32. }
  33. }
  34. }
  35. else
  36. {
  37. CAMHAL_LOGDA("Event queue empty!!!");
  38. }

  39. //Special handlingforany unregistered events
  40. if(!eventSignalled){
  41. //Handlingforfocus callback
  42. if((nData2==OMX_IndexConfigCommonFocusStatus)&&
  43. (eEvent==(OMX_EVENTTYPE)OMX_EventIndexSettingChanged)){
  44. TIUTILS::Message msg;
  45. msg.command=OMXCallbackHandler::CAMERA_FOCUS_STATUS;
  46. msg.arg1=NULL;
  47. msg.arg2=NULL;
  48. mOMXCallbackHandler->put(&msg);
  49. }
  50. }

  51. LOG_FUNCTION_NAME_EXIT;

  52. return OMX_ErrorNone;
  53. }
这里我们只关注上面的实现,至于下面handle focus callback这里咱不做说明,以后可能会再次碰到
我们看看上面的语句到底做了什么,检测到 mEventSignalQ这个消息队列中有消息,而这里在第6步中不是刚刚往这个消息队列中添加了一个消息嘛!看来他们有点暧昧,接着看,进行了遍历查找的操作,那么找的到底是什么呢?上面的判断条件很明确,不同的一点马虎,看看这个消息队列中是是否有和我从组件发来的消息一致的消息,找到了,那就说明消息处理完了,组件成功应答给应用层了,那么就得到了那个信号量,并且发送一个信号给wait方法,wait方法接到信号立即返回,否则一直等待直到超时,超时返回非零值,否则返回零,程序中如果wait超时,调用RemoveEvent方法
  1. OMX_ERRORTYPE OMXCameraAdapter::RemoveEvent(OMX_IN OMX_HANDLETYPE hComponent,
  2. OMX_IN OMX_EVENTTYPE eEvent,
  3. OMX_IN OMX_U32 nData1,
  4. OMX_IN OMX_U32 nData2,
  5. OMX_IN OMX_PTR pEventData)
  6. {
  7. Mutex::Autolock lock(mEventLock);
  8. TIUTILS::Message*msg;
  9. LOG_FUNCTION_NAME;

  10. if(!mEventSignalQ.isEmpty())
  11. {
  12. CAMHAL_LOGDA("Event queue not empty");

  13. for(unsignedinti=0;i<mEventSignalQ.size();i++)
  14. {
  15. msg=mEventSignalQ.itemAt(i);
  16. if(NULL!=msg)
  17. {
  18. if((msg->command!=0||msg->command==(unsignedint)(eEvent))
  19. &&(!msg->arg1||(OMX_U32)msg->arg1==nData1)
  20. &&(!msg->arg2||(OMX_U32)msg->arg2==nData2)
  21. &&msg->arg3)
  22. {
  23. Semaphore*sem=(Semaphore*)msg->arg3;
  24. CAMHAL_LOGDA("Event matched, signalling sem");
  25. mEventSignalQ.removeAt(i);
  26. free(msg);
  27. break;
  28. }
  29. }
  30. }
  31. }
  32. else
  33. {
  34. CAMHAL_LOGEA("Event queue empty!!!");
  35. }
  36. LOG_FUNCTION_NAME_EXIT;

  37. return OMX_ErrorNone;
  38. }
这个方法检查 mEventSignalQ如果中有成员消息,那么就清除掉 mEventSignalQ其中的所有消息,这个是错误处理,以后还是会接着使用 mEventSignalQ这个消息队列的,这里已经说的很清楚了,为什么在OMX_SendCommand之前要RegisterForEvent,就是为了要判断组件有没有按照我发送给他的命令干活,处理完后给我应答了,我就认为他乖乖的按照我的要求做了事情,这里那叫一个重要,因为后面还会有很多这个机制的使用
这里有一个地方我还是要提及一下,那就是组件回馈的enent类型,直接贴在这里
  1. /**@ingroup comp*/
  2. typedef enum OMX_EVENTTYPE
  3. {
  4. OMX_EventCmdComplete,/**<component has sucessfully completed a command*/
  5. OMX_EventError,/**<component has detected anerrorcondition*/
  6. OMX_EventMark,/**<component has detected a buffer mark*/
  7. OMX_EventPortSettingsChanged,/**<componentisreported a port settings change*/
  8. OMX_EventBufferFlag,/**<component has detected an EOS*/
  9. OMX_EventResourcesAcquired,/**<component has been granted resourcesandis
  10. automatically starting the state change from
  11. OMX_StateWaitForResourcestoOMX_StateIdle.*/
  12. OMX_EventComponentResumed,/**<Component resumed duetoreacquisition of resources*/
  13. OMX_EventDynamicResourcesAvailable,/**<Component has acquired previously unavailable dynamic resources*/
  14. OMX_EventPortFormatDetected,/**<Component has detected a supported format.*/
  15. OMX_EventKhronosExtensions=0x6F000000,/**<Reserved regionforintroducing Khronos Standard Extensions*/
  16. OMX_EventVendorStartUnused=0x7F000000,/**<Reserved regionforintroducing Vendor Extensions*/
  17. OMX_EventMax=0x7FFFFFFF
  18. }OMX_EVENTTYPE;

8.Select the sensor
这里我们首先看看OMX_CONFIG_SENSORSELECTTYPE这个结构
定义在以下目录:hardware\ti\omap4xxx\domx\omx_core\inc\OMX_TI_IVCommon.h
  1. /*
  2. *SensorSelect
  3. */
  4. typedef struct OMX_CONFIG_SENSORSELECTTYPE{
  5. OMX_U32 nSize;/**<Size of the structureinbytes*/
  6. OMX_VERSIONTYPE nVersion;/**<OMX specification version info*/
  7. OMX_U32 nPortIndex;/**<Port that this struct appliesto*/
  8. OMX_SENSORSELECT eSensor;/**<sensorselect*/
  9. }OMX_CONFIG_SENSORSELECTTYPE;
接着来看下面这个方法的实现
OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
  1. #define OMX_INIT_STRUCT_PTR(_s_,_name_)\
  2. memset((_s_),0x0,sizeof(_name_));\
  3. (_s_)->nSize=sizeof(_name_);\
  4. (_s_)->nVersion.s.nVersionMajor=0x1;\
  5. (_s_)->nVersion.s.nVersionMinor=0x1;\
  6. (_s_)->nVersion.s.nRevision=0x0;\
  7. (_s_)->nVersion.s.nStep=0x0
这个方法只是对sensorSelect这个结构进行初始化和填充而已,传入 OMX_CONFIG_SENSORSELECTTYPE结构体只是为了获取他的大小,挺大财小用不是吗??嘿嘿
最后调用OMX_SetConfig()这个方法
  1. /**The OMX_SetConfig macro will send one of the configuration
  2. structurestoa component.Eachstructure shall be sent one at atime,
  3. eachina separate invocation of the macro.This macro can be invoked
  4. anytime after the component has been loaded.The application shall
  5. allocate the correct structureandshall fillinthe structure size
  6. andversion information(as well as the actual data)before invoking
  7. this macro.The applicationisfreetodispose of this structure after
  8. thecallas the componentisrequiredtocopy any data it shall retain.
  9. Thisisa blockingcall.

  10. The component should return from thiscallwithin 5 msec.

  11. @param[in]hComponent
  12. Handle of the componenttobe accessed.Thisisthe component
  13. handle returned by thecalltothe OMX_GetHandlefunction.
  14. @param[in]nConfigIndex
  15. Index of the structuretobe sent.This valueisfrom the
  16. OMX_INDEXTYPE enumeration above.
  17. @param[in]pComponentConfigStructure
  18. pointertoapplication allocated structuretobe usedfor
  19. initialization by the component.
  20. @return OMX_ERRORTYPE
  21. Ifthe command successfully executes,the return code will be
  22. OMX_ErrorNone.Otherwise the appropriate OMXerrorwill be returned.
  23. @ingroup comp
  24. */
  25. #define OMX_SetConfig(\
  26. hComponent,\
  27. nConfigIndex,\
  28. pComponentConfigStructure)\
  29. ((OMX_COMPONENTTYPE*)hComponent)->SetConfig(\
  30. hComponent,\
  31. nConfigIndex,\
  32. pComponentConfigStructure)/*MacroEnd*/

9.参数初始化
其中最重要的是initialize方法引入的参数传递给了 mCapabilities
mCapabilities = caps;
并且通过mCapabilities->get()方法获得相应的参数初始化

10.initialize command handling thread
这里只是创建了一个CommandHandler线程,并且启动了这个线程,我们重点看看这个线程都干了些甚么
  1. bool OMXCameraAdapter::CommandHandler::Handler()
  2. {
  3. TIUTILS::Message msg;
  4. volatileintforever=1;
  5. status_t stat;
  6. ErrorNotifier*errorNotify=NULL;

  7. LOG_FUNCTION_NAME;

  8. while(forever)
  9. {
  10. stat=NO_ERROR;
  11. CAMHAL_LOGDA("Handler: waiting for messsage...");
  12. TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ,NULL,NULL,-1);
  13. {
  14. Mutex::Autolock lock(mLock);
  15. mCommandMsgQ.get(&msg);
  16. }
  17. CAMHAL_LOGDB("msg.command = %d",msg.command);
  18. switch(msg.command){
  19. caseCommandHandler::CAMERA_START_IMAGE_CAPTURE:
  20. {
  21. OMXCameraAdapter::CachedCaptureParameters*cap_params=
  22. static_cast<OMXCameraAdapter::CachedCaptureParameters*>(msg.arg2);
  23. stat=mCameraAdapter->startImageCapture(false,cap_params);
  24. delete cap_params;
  25. break;
  26. }
  27. caseCommandHandler::CAMERA_PERFORM_AUTOFOCUS:
  28. {
  29. stat=mCameraAdapter->doAutoFocus();
  30. break;
  31. }
  32. caseCommandHandler::COMMAND_EXIT:
  33. {
  34. CAMHAL_LOGDA("Exiting command handler");
  35. forever=0;
  36. break;
  37. }
  38. caseCommandHandler::CAMERA_SWITCH_TO_EXECUTING:
  39. {
  40. stat=mCameraAdapter->doSwitchToExecuting();
  41. break;
  42. }
  43. caseCommandHandler::CAMERA_START_REPROCESS:
  44. {
  45. OMXCameraAdapter::CachedCaptureParameters*cap_params=
  46. static_cast<OMXCameraAdapter::CachedCaptureParameters*>(msg.arg2);
  47. stat=mCameraAdapter->startReprocess();
  48. stat=mCameraAdapter->startImageCapture(false,cap_params);
  49. delete cap_params;
  50. break;
  51. }
  52. }

  53. }

  54. LOG_FUNCTION_NAME_EXIT;

  55. returnfalse;
  56. }

11.initialize omx callback handling thread
这里和上面很类似,创建一个OMXCallbackHandler线程,并启动这个线程,同样看看这个线程都干了些甚么
  1. bool OMXCameraAdapter::OMXCallbackHandler::Handler()
  2. {
  3. TIUTILS::Message msg;
  4. volatileintforever=1;
  5. status_t ret=NO_ERROR;

  6. LOG_FUNCTION_NAME;

  7. while(forever){
  8. TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ,NULL,NULL,-1);
  9. {
  10. Mutex::Autolock lock(mLock);
  11. mCommandMsgQ.get(&msg);
  12. mIsProcessed=false;
  13. }

  14. switch(msg.command){
  15. caseOMXCallbackHandler::CAMERA_FILL_BUFFER_DONE:
  16. {
  17. ret=mCameraAdapter->OMXCameraAdapterFillBufferDone((OMX_HANDLETYPE)msg.arg1,
  18. (OMX_BUFFERHEADERTYPE*)msg.arg2);
  19. break;
  20. }
  21. caseOMXCallbackHandler::CAMERA_FOCUS_STATUS:
  22. {
  23. mCameraAdapter->handleFocusCallback();
  24. break;
  25. }
  26. caseCommandHandler::COMMAND_EXIT:
  27. {
  28. CAMHAL_LOGDA("Exiting OMX callback handler");
  29. forever=0;
  30. break;
  31. }
  32. }

  33. {
  34. android::AutoMutex locker(mLock);
  35. CAMHAL_UNUSED(locker);

  36. mIsProcessed=mCommandMsgQ.isEmpty();
  37. if(mIsProcessed)
  38. mCondition.signal();
  39. }
  40. }

  41. //force the conditiontowake
  42. {
  43. android::AutoMutex locker(mLock);
  44. CAMHAL_UNUSED(locker);

  45. mIsProcessed=true;
  46. mCondition.signal();
  47. }

  48. LOG_FUNCTION_NAME_EXIT;
  49. returnfalse;
  50. }

12.initialize 3A defaults
这里暂不做说明,都是对很多参数的基本初始化
到这里为止,OMXCameraAdapter的初始化就结束了
待续。。。。。

更多相关文章

  1. Android—高级组件对应属性大全及使用详例
  2. 安卓-菜单简述
  3. Android(安卓)开发必读:如何成为一名优秀的Android开发者
  4. Android布局中margin,padding,align的用法和区别
  5. Android漏洞,WebView漏洞,Web漏洞与Web安全
  6. 浅谈Java中Collections.sort对List排序的两种方法
  7. mybatisplus的坑 insert标签insert into select无参数问题的解决
  8. Python技巧匿名函数、回调函数和高阶函数
  9. Python list sort方法的具体使用

随机推荐

  1. Android实现局部图片滑动指引效果
  2. Android(安卓)实现真机远程调试并适应7寸
  3. Android 开源项目 eoe 社区 Android 客户
  4. 回望十年Android
  5. 【Android】联通性 -- USB从属模式
  6. 跑 Android(安卓)的 TouchPad 终于真正地
  7. 条码扫描二维码扫描——ZXing android 源
  8. (详解)Eclipse3.6搭建 Android 2.2 开发
  9. 亚马逊面向开发人员推出Android应用商店
  10. Android面试及开发忠告