Android Camera OMXCameraAdapter.cpp初始化分析

来源:互联网 发布:什么小说软件免费 编辑:程序博客网 时间:2024/05/20 03:07
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 camera driver实现交互,进而实现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 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, 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.Register for port 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.          goto EXIT;
  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.Wait for the port enable event to occur
  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.          goto EXIT;
  96.      }

  97.     // 7.Select the sensor
  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.     //get triggered.
  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 setParameter call will apply all 3A settings
  227.     //and will not conditionally apply based on current values.
  228.     mFirstTimeInit = true;

  229.     //Flag to avoid calling setVFramerate() before OMX_SetParameter(OMX_IndexParamPortDefinition)
  230.     //Ducati will return an error otherwise.
  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 method is used to initialize the OMX core. It shall be the
  2.     first call made into OMX and it should only be executed one time without
  3.     an interviening OMX_Deinit call. 
  4.     
  5.     The core should return from this call within 20 msec.

  6.     @return OMX_ERRORTYPE
  7.         If the command successfully executes, the return code will be
  8.         OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
  9.     @ingroup core
  10.  */
  11. 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 method is used to notify the application when an
  4.         event of interest occurs. Events are defined in the OMX_EVENTTYPE
  5.         enumeration. Please see that enumeration for details of what will
  6.         be returned for each type of event. Callbacks should not return
  7.         an error to the component, so if an error occurs, the application 
  8.         shall handle it internally. This is a blocking call.

  9.         The application should return from this call within 5 msec to avoid
  10.         blocking the component for an excessively long period of time.

  11.         @param hComponent
  12.             handle of the component to access. This is the component
  13.             handle returned by the call to the GetHandle function.
  14.         @param pAppData
  15.             pointer to an application defined value that was provided in the 
  16.             pAppData parameter to the OMX_GetHandle method for the component.
  17.             This application defined value is provided so that the application 
  18.             can have a component specific context when receiving the callback.
  19.         @param eEvent
  20.             Event that the component wants to notify the application about.
  21.         @param nData1
  22.             nData will be the OMX_ERRORTYPE for an error event and will be 
  23.             an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event.
  24.          @param nData2
  25.             nData2 will hold further information related to the event. Can be OMX_STATETYPE for
  26.             a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event.
  27.             Default value is 0 if not used. )
  28.         @param pEventData
  29.             Pointer to additional event-specific data (see spec for meaning).
  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 method is used to return emptied buffers from an
  39.         input port back to the application for reuse. This is a blocking call 
  40.         so the application should not attempt to refill the buffers during this
  41.         call, but should queue them and refill them in another thread. There
  42.         is no error return, so the application shall handle any errors generated
  43.         internally. 
  44.         
  45.         The application should return from this call within 5 msec.
  46.         
  47.         @param hComponent
  48.             handle of the component to access. This is the component
  49.             handle returned by the call to the GetHandle function.
  50.         @param pAppData
  51.             pointer to an application defined value that was provided in the 
  52.             pAppData parameter to the OMX_GetHandle method for the component.
  53.             This application defined value is provided so that the application 
  54.             can have a component specific context when receiving the callback.
  55.         @param pBuffer
  56.             pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
  57.             or AllocateBuffer indicating the buffer that was emptied.
  58.         @ingroup buf
  59.      */
  60.     OMX_ERRORTYPE (*EmptyBufferDone)(
  61.         OMX_IN OMX_HANDLETYPE hComponent,
  62.         OMX_IN OMX_PTR pAppData,
  63.         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);

  64.     /** The FillBufferDone method is used to return filled buffers from an
  65.         output port back to the application for emptying and then reuse. 
  66.         This is a blocking call so the application should not attempt to 
  67.         empty the buffers during this call, but should queue the buffers 
  68.         and empty them in another thread. There is no error return, so 
  69.         the application shall handle any errors generated internally. The 
  70.         application shall also update the buffer header to indicate the
  71.         number of bytes placed into the buffer. 

  72.         The application should return from this call within 5 msec.
  73.         
  74.         @param hComponent
  75.             handle of the component to access. This is the component
  76.             handle returned by the call to the GetHandle function.
  77.         @param pAppData
  78.             pointer to an application defined value that was provided in the 
  79.             pAppData parameter to the OMX_GetHandle method for the component.
  80.             This application defined value is provided so that the application 
  81.             can have a component specific context when receiving the callback.
  82.         @param pBuffer
  83.             pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
  84.             or AllocateBuffer indicating the buffer that was filled.
  85.         @ingroup buf
  86.      */
  87.     OMX_ERRORTYPE (*FillBufferDone)(
  88.         OMX_OUT OMX_HANDLETYPE hComponent,
  89.         OMX_OUT OMX_PTR pAppData,
  90.         OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);

  91. } 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.         const OMX_CALLBACKTYPE & callbacks)
  3. {
  4.     OMX_ERRORTYPE eError = OMX_ErrorUndefined;

  5.     for ( int i = 0; i < 5; ++) {
  6.         if ( i > 0 ) {
  7.             // sleep for 100 ms before next attempt
  8.             usleep(100000);
  9.         }

  10.         // setup key parameters to send to Ducati during init
  11.         OMX_CALLBACKTYPE oCallbacks = callbacks;

  12.         // get handle
  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 memory and then invoke
  3.     the component's methods to create an instance of the component. 
  4.     
  5.     The core should return from this call within 20 msec.
  6.     
  7.     @param [out] pHandle
  8.         pointer to an OMX_HANDLETYPE pointer to be filled in by this method.
  9.     @param [in] cComponentName
  10.         pointer to a null terminated string with the component name. The
  11.         names of the components are strings less than 127 bytes in length
  12.         plus the trailing null for a maximum size of 128 bytes. An example 
  13.         of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are 
  14.         assigned by the vendor, but shall start with "OMX." and then have 
  15.         the Vendor designation next.
  16.     @param [in] pAppData
  17.         pointer to an application defined value that will be returned
  18.         during callbacks so that the application can identify the source
  19.         of the callback.
  20.     @param [in] pCallBacks
  21.         pointer to a OMX_CALLBACKTYPE structure that will be passed to the
  22.         component to initialize it with. 
  23.     @return OMX_ERRORTYPE
  24.         If the command successfully executes, the return code will be
  25.         OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
  26.     @ingroup core
  27.  */
  28. OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
  29.     OMX_OUT OMX_HANDLETYPE* pHandle, 
  30.     OMX_IN OMX_STRING cComponentName,
  31.     OMX_IN OMX_PTR pAppData,
  32.     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 command to the component. This call is a non-blocking call.
  2.     The component should check the parameters and then queue the command
  3.     to the component thread to be executed. The component thread shall 
  4.     send the EventHandler() callback at the conclusion of the command. 
  5.     This macro will go directly from the application to the component (via
  6.     a core macro). The component will return from this call within 5 msec.
  7.     
  8.     When the command is "OMX_CommandStateSet" the component will queue a
  9.     state transition to the new state idenfied in nParam.
  10.     
  11.     When the command is "OMX_CommandFlush", to flush a port's buffer queues,
  12.     the command will force the component to return all buffers NOT CURRENTLY 
  13.     BEING PROCESSED to the application, in the order in which the buffers 
  14.     were received.
  15.     
  16.     When the command is "OMX_CommandPortDisable" or 
  17.     "OMX_CommandPortEnable", the component's port (given by the value of
  18.     nParam) will be stopped or restarted. 
  19.     
  20.     When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the
  21.     pCmdData will point to a OMX_MARKTYPE structure containing the component
  22.     handle of the component to examine the buffer chain for the mark. nParam1
  23.     contains the index of the port on which the buffer mark is applied.

  24.     Specification text for more details. 
  25.     
  26.     @param [in] hComponent
  27.         handle of component to execute the command
  28.     @param [in] Cmd
  29.         Command for the component to execute
  30.     @param [in] nParam
  31.         Parameter for the command to be executed. When Cmd has the value 
  32.         OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has 
  33.         the value OMX_CommandFlush, value of nParam indicates which port(s) 
  34.         to flush. -is used to flush all ports a single port index will 
  35.         only flush that port. When Cmd has the value "OMX_CommandPortDisable"
  36.         or "OMX_CommandPortEnable", the component's port is given by 
  37.         the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer"
  38.         the components pot is given by the value of nParam.
  39.     @param [in] pCmdData
  40.         Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value
  41.         "OMX_CommandMarkBuffer". 
  42.     @return OMX_ERRORTYPE
  43.         If the command successfully executes, the return code will be
  44.         OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
  45.     @ingroup comp
  46.  */
  47. #define OMX_SendCommand( \
  48.          hComponent, \
  49.          Cmd, \
  50.          nParam, \
  51.          pCmdData) \
  52.      ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \
  53.          hComponent, \
  54.          Cmd, \
  55.          nParam, \
  56.          pCmdData) /* Macro End */
通过这个方法给组件发送一个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 = ( unsigned int ) 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.         case OMX_EventCmdComplete:
  16.             CAMHAL_LOGDB("+OMX_EventCmdComplete %d %d", (int)nData1, (int)nData2);

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

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

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

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

  25.             } else if (OMX_CommandMarkBuffer == nData1) {
  26.                 ///This is not used currently
  27.             }

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

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

  34.         case OMX_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 events and
  43.                 unblock any waiting semaphores
  44.                 */
  45.                 if ( !mEventSignalQ.isEmpty() )
  46.                   {
  47.                     for (unsigned int i = 0 ; i < mEventSignalQ.size(); i++ )
  48.                       {
  49.                         CAMHAL_LOGEB("***Removing %d EVENTS***** \n", mEventSignalQ.size());
  50.                         //remove from queue and free 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.                 ///Report Error to App
  65.                 mErrorNotifier->errorNotify(CAMERA_ERROR_FATAL);
  66.               }
  67.             break;

  68.         case OMX_EventMark:
  69.         break;

  70.         case OMX_EventPortSettingsChanged:
  71.         break;

  72.         case OMX_EventBufferFlag:
  73.         break;

  74.         case OMX_EventResourcesAcquired:
  75.         break;

  76.         case OMX_EventComponentResumed:
  77.         break;

  78.         case OMX_EventDynamicResourcesAvailable:
  79.         break;

  80.         case OMX_EventPortFormatDetected:
  81.         break;

  82.         default:
  83.         break;
  84.     }

  85.     ///Signal to the 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 ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
  15.             {
  16.             msg = mEventSignalQ.itemAt(i);
  17.             if ( NULL != msg )
  18.                 {
  19.                 if( ( msg->command != 0 || msg->command == ( unsigned int ) ( 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 handling for any unregistered events
  40.     if (!eventSignalled) {
  41.         // Handling for focus 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 ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
  14.         {
  15.           msg = mEventSignalQ.itemAt(i);
  16.           if ( NULL != msg )
  17.             {
  18.               if( ( msg->command != 0 || msg->command == ( unsigned int ) ( 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 an error condition */
  6.     OMX_EventMark, /**< component has detected a buffer mark */
  7.     OMX_EventPortSettingsChanged, /**< component is reported a port settings change */
  8.     OMX_EventBufferFlag, /**< component has detected an EOS */ 
  9.     OMX_EventResourcesAcquired, /**< component has been granted resources and is
  10.                                        automatically starting the state change from
  11.                                        OMX_StateWaitForResources to OMX_StateIdle. */
  12.    OMX_EventComponentResumed, /**< Component resumed due to reacquisition 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 region for introducing Khronos Standard Extensions */ 
  16.    OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing 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.  * Sensor Select
  3.  */
  4. typedef struct OMX_CONFIG_SENSORSELECTTYPE {
  5. OMX_U32 nSize; /**< Size of the structure in bytes */
  6. OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
  7. OMX_U32 nPortIndex; /**< Port that this struct applies to */
  8. OMX_SENSORSELECT eSensor; /**< sensor select */
  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.     structures to a component. Each structure shall be sent one at a time,
  3.     each in a 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 structure and shall fill in the structure size 
  6.     and version information (as well as the actual data) before invoking 
  7.     this macro. The application is free to dispose of this structure after 
  8.     the call as the component is required to copy any data it shall retain. 
  9.     This is a blocking call. 
  10.     
  11.     The component should return from this call within 5 msec.
  12.     
  13.     @param [in] hComponent
  14.         Handle of the component to be accessed. This is the component
  15.         handle returned by the call to the OMX_GetHandle function.
  16.     @param [in] nConfigIndex
  17.         Index of the structure to be sent. This value is from the
  18.         OMX_INDEXTYPE enumeration above.
  19.     @param [in] pComponentConfigStructure
  20.         pointer to application allocated structure to be used for
  21.         initialization by the component.
  22.     @return OMX_ERRORTYPE
  23.         If the command successfully executes, the return code will be
  24.         OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
  25.     @ingroup comp
  26.  */
  27. #define OMX_SetConfig( \
  28.         hComponent, \
  29.         nConfigIndex, \
  30.         pComponentConfigStructure) \
  31.     ((OMX_COMPONENTTYPE*)hComponent)->SetConfig( \
  32.         hComponent, \
  33.         nConfigIndex, \
  34.         pComponentConfigStructure) /* Macro End */

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

10.initialize command handling thread
这里只是创建了一个CommandHandler线程,并且启动了这个线程,我们重点看看这个线程都干了些甚么
  1. bool OMXCameraAdapter::CommandHandler::Handler()
  2. {
  3.     TIUTILS::Message msg;
  4.     volatile int forever = 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.             case CommandHandler::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.             case CommandHandler::CAMERA_PERFORM_AUTOFOCUS:
  28.             {
  29.                 stat = mCameraAdapter->doAutoFocus();
  30.                 break;
  31.             }
  32.             case CommandHandler::COMMAND_EXIT:
  33.             {
  34.                 CAMHAL_LOGDA("Exiting command handler");
  35.                 forever = 0;
  36.                 break;
  37.             }
  38.             case CommandHandler::CAMERA_SWITCH_TO_EXECUTING:
  39.             {
  40.                 stat = mCameraAdapter->doSwitchToExecuting();
  41.                 break;
  42.             }
  43.             case CommandHandler::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.     return false;
  56. }

11.initialize omx callback handling thread
这里和上面很类似,创建一个OMXCallbackHandler线程,并启动这个线程,同样看看这个线程都干了些甚么
  1. bool OMXCameraAdapter::OMXCallbackHandler::Handler()
  2. {
  3.     TIUTILS::Message msg;
  4.     volatile int forever = 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.             case OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE:
  16.             {
  17.                 ret = mCameraAdapter->OMXCameraAdapterFillBufferDone(( OMX_HANDLETYPE ) msg.arg1,
  18.                                                                      ( OMX_BUFFERHEADERTYPE *) msg.arg2);
  19.                 break;
  20.             }
  21.             case OMXCallbackHandler::CAMERA_FOCUS_STATUS:
  22.             {
  23.                 mCameraAdapter->handleFocusCallback();
  24.                 break;
  25.             }
  26.             case CommandHandler::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 condition to wake
  42.     {
  43.         android::AutoMutex locker(mLock);
  44.         CAMHAL_UNUSED(locker);

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

  48.     LOG_FUNCTION_NAME_EXIT;
  49.     return false;
  50. }

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