Android(安卓)Camera OMXCameraAdapter.cpp初始化分析
16lz
2021-12-28
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.OMX_Init
从字面上就可以知道,要使用OMX这个方式,那就要为使用它做准备啊,初始化,但我们还是严谨点,说一说吧,
2.Initialize the callback handles
这里初始化callback handle,那么上面初始化了三个handle,这三个handle具体都实现什么用途呢?
当然一下不是我说的,是TI为方便大家理解,在andriod底层加入了很多很全的注释,一起看看吧
EventHandler方法用来通知应用层一些应用层可能感兴趣的一些事件,事件分很多类型,已经用枚举方式定义在 OMX_EVENTTYPE中, 这个回调方法同样不会提示error信息,所以需要用户端自己去分辨,并处理这些信息,保存错误信息;
FillBufferDone方法用来实现从组件的输出端口获取到经过解码等很多操作的buffer,并且放回给应用层,应用层获取使用后,在通过emptyThisBuffer方法清空buffer再次利用, 这个回调方法同样不会提示error信息,所以需要用户端自己去分辨,并处理这些信息,保存错误信息,这里应用层还有一件很重要的事情要做,应用程序要更新缓冲区header的位置,新数据加入,header后移;
3.Get the handle to the OMX Component
4.设置组件最初状态为OMX_StateLoaded状态,并disable所以command port
mComponentState = OMX_StateLoaded ;
eError = OMX_SendCommand ( mCameraAdapterParameters . mHandleComp , OMX_CommandPortDisable , OMX_ALL , NULL ) ;
这里必须重点说说OMX_SendCommand这个方法
在上面参数中分为以下几种情况:
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);//这个参数是信号量,保证同步
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来应答应用层的,我们就看看这个方法的具体实现方法
我们看看上面的语句到底做了什么,检测到 mEventSignalQ这个消息队列中有消息,而这里在第6步中不是刚刚往这个消息队列中添加了一个消息嘛!看来他们有点暧昧,接着看,进行了遍历查找的操作,那么找的到底是什么呢?上面的判断条件很明确,不同的一点马虎,看看这个消息队列中是是否有和我从组件发来的消息一致的消息,找到了,那就说明消息处理完了,组件成功应答给应用层了,那么就得到了那个信号量,并且发送一个信号给wait方法,wait方法接到信号立即返回,否则一直等待直到超时,超时返回非零值,否则返回零,程序中如果wait超时,调用RemoveEvent方法
这里有一个地方我还是要提及一下,那就是组件回馈的enent类型,直接贴在这里
8.Select the sensor
这里我们首先看看OMX_CONFIG_SENSORSELECTTYPE这个结构
定义在以下目录:hardware\ti\omap4xxx\domx\omx_core\inc\OMX_TI_IVCommon.h
OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
最后调用OMX_SetConfig()这个方法
9.参数初始化
其中最重要的是initialize方法引入的参数传递给了 mCapabilities
mCapabilities = caps;
并且通过mCapabilities->get()方法获得相应的参数初始化
10.initialize command handling thread
这里只是创建了一个CommandHandler线程,并且启动了这个线程,我们重点看看这个线程都干了些甚么
11.initialize omx callback handling thread
这里和上面很类似,创建一个OMXCallbackHandler线程,并启动这个线程,同样看看这个线程都干了些甚么
12.initialize 3A defaults
这里暂不做说明,都是对很多参数的基本初始化
到这里为止,OMXCameraAdapter的初始化就结束了
待续。。。。。
这几天一直在研究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方法都干了些甚么?
- /*--------------------Camera AdapterClassSTARTS here-----------------------------*/
-
- status_t OMXCameraAdapter::initialize(CameraProperties::Properties*caps)
- {
- LOG_FUNCTION_NAME;
-
- char value[PROPERTY_VALUE_MAX];
- constchar*mountOrientationString=NULL;
-
- property_get("debug.camera.showfps",value,"0");
- mDebugFps=atoi(value);
- property_get("debug.camera.framecounts",value,"0");
- mDebugFcs=atoi(value);
-
- #ifdef CAMERAHAL_OMX_PROFILING
-
- property_get("debug.camera.profile",value,"0");
- mDebugProfile=atoi(value);
-
- #endif
-
- TIMM_OSAL_ERRORTYPE osalError=OMX_ErrorNone;
- OMX_ERRORTYPE eError=OMX_ErrorNone;
- status_t ret=NO_ERROR;
-
- mLocalVersionParam.s.nVersionMajor=0x1;
- mLocalVersionParam.s.nVersionMinor=0x1;
- mLocalVersionParam.s.nRevision=0x0;
- mLocalVersionParam.s.nStep=0x0;
-
- mPending3Asettings=0;//E3AsettingsAll;
- mPendingCaptureSettings=0;
- mPendingPreviewSettings=0;
-
- if(0!=mInitSem.Count())
- {
- CAMHAL_LOGEB("Error mInitSem semaphore count %d",mInitSem.Count());
- LOG_FUNCTION_NAME_EXIT;
- return NO_INIT;
- }
-
- ///Update the previewandimage capture port indexes
- mCameraAdapterParameters.mPrevPortIndex=OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
- //temp changedinordertobuild OMX_CAMERA_PORT_VIDEO_OUT_IMAGE;
- mCameraAdapterParameters.mImagePortIndex=OMX_CAMERA_PORT_IMAGE_OUT_IMAGE;
- mCameraAdapterParameters.mMeasurementPortIndex=OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT;
- //currentlynotsupported use preview port instead
- mCameraAdapterParameters.mVideoPortIndex=OMX_CAMERA_PORT_VIDEO_OUT_VIDEO;
- mCameraAdapterParameters.mVideoInPortIndex=OMX_CAMERA_PORT_VIDEO_IN_VIDEO;
- //1.OMX_Init
- eError=OMX_Init();
- if(eError!=OMX_ErrorNone){
- CAMHAL_LOGEB("OMX_Init() failed, error: 0x%x",eError);
- return ErrorUtils::omxToAndroidError(eError);
- }
- mOmxInitialized=true;
-
- //2.Initialize the callback handles
- OMX_CALLBACKTYPE callbacks;
- callbacks.EventHandler=android::OMXCameraAdapterEventHandler;
- callbacks.EmptyBufferDone=android::OMXCameraAdapterEmptyBufferDone;
- callbacks.FillBufferDone=android::OMXCameraAdapterFillBufferDone;
-
- // 3.Getthe handletothe OMX Component
- eError=OMXCameraAdapter::OMXCameraGetHandle(&mCameraAdapterParameters.mHandleComp,this,callbacks);
- if(eError!=OMX_ErrorNone){
- CAMHAL_LOGEB("OMX_GetHandle -0x%x",eError);
- }
- GOTO_EXIT_IF((eError!=OMX_ErrorNone),eError);
-
- mComponentState=OMX_StateLoaded;
-
- CAMHAL_LOGVB("OMX_GetHandle -0x%x sensor_index = %lu",eError,mSensorIndex);
- initDccFileDataSave(&mCameraAdapterParameters.mHandleComp,mCameraAdapterParameters.mPrevPortIndex);
-
- eError=OMX_SendCommand(mCameraAdapterParameters.mHandleComp,OMX_CommandPortDisable,OMX_ALL,NULL);
-
- if(eError!=OMX_ErrorNone){
- CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortDisable) -0x%x",eError);
- }
- GOTO_EXIT_IF((eError!=OMX_ErrorNone),eError);
-
- //4.Registerforport enable event
- ret=RegisterForEvent(mCameraAdapterParameters.mHandleComp,
- OMX_EventCmdComplete,
- OMX_CommandPortEnable,
- mCameraAdapterParameters.mPrevPortIndex,
- mInitSem);
- if(ret!=NO_ERROR){
- CAMHAL_LOGEB("Error in registering for event %d",ret);
- gotoEXIT;
- }
-
- //5.Enable PREVIEW Port
- eError=OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
- OMX_CommandPortEnable,
- mCameraAdapterParameters.mPrevPortIndex,
- NULL);
- if(eError!=OMX_ErrorNone){
- CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x",eError);
- }
- GOTO_EXIT_IF((eError!=OMX_ErrorNone),eError);
-
- //6.Waitforthe port enable eventtooccur
- ret=mInitSem.WaitTimeout(OMX_CMD_TIMEOUT);
- if(NO_ERROR==ret){
- CAMHAL_LOGDA("-Port enable event arrived");
- }else{
- ret|=RemoveEvent(mCameraAdapterParameters.mHandleComp,
- OMX_EventCmdComplete,
- OMX_CommandPortEnable,
- mCameraAdapterParameters.mPrevPortIndex,
- NULL);
- CAMHAL_LOGEA("Timeout for enabling preview port expired!");
- gotoEXIT;
- }
-
- //7.Selectthesensor
- OMX_CONFIG_SENSORSELECTTYPE sensorSelect;
- OMX_INIT_STRUCT_PTR(&sensorSelect,OMX_CONFIG_SENSORSELECTTYPE);
- sensorSelect.eSensor=(OMX_SENSORSELECT)mSensorIndex;
- eError=OMX_SetConfig(mCameraAdapterParameters.mHandleComp,(OMX_INDEXTYPE)OMX_TI_IndexConfigSensorSelect,&sensorSelect);
- if(OMX_ErrorNone!=eError){
- CAMHAL_LOGEB("Error while selecting the sensor index as %d - 0x%x",mSensorIndex,eError);
- return BAD_VALUE;
- }else{
- CAMHAL_LOGDB("Sensor %d selected successfully",mSensorIndex);
- }
-
- #ifdef CAMERAHAL_DEBUG
-
- printComponentVersion(mCameraAdapterParameters.mHandleComp);
-
- #endif
- // 8.初始化默认参数
- mBracketingEnabled=false;
- mZoomBracketingEnabled=false;
- mBracketingBuffersQueuedCount=0;
- mBracketingRange=1;
- mLastBracetingBufferIdx=0;
- mBracketingBuffersQueued=NULL;
- mOMXStateSwitch=false;
- mBracketingSet=false;
- #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
- mRawCapture=false;
- mYuvCapture=false;
- #endif
-
- mCaptureSignalled=false;
- mCaptureConfigured=false;
- mReprocConfigured=false;
- mRecording=false;
- mWaitingForSnapshot=false;
- mPictureFormatFromClient=NULL;
-
- mCapabilitiesOpMode=MODE_MAX;
- mCapMode=INITIAL_MODE;
- mIPP=IPP_NULL;
- mVstabEnabled=false;
- mVnfEnabled=false;
- mBurstFrames=1;
- mBurstFramesAccum=0;
- mCapturedFrames=0;
- mFlushShotConfigQueue=false;
- mPictureQuality=100;
- mCurrentZoomIdx=0;
- mTargetZoomIdx=0;
- mPreviousZoomIndx=0;
- mReturnZoomStatus=false;
- mZoomInc=1;
- mZoomParameterIdx=0;
- mExposureBracketingValidEntries=0;
- mZoomBracketingValidEntries=0;
- mSensorOverclock=false;
- mAutoConv=OMX_TI_AutoConvergenceModeMax;
- mManualConv=0;
- mDeviceOrientation=0;
- mCapabilities=caps;
- mZoomUpdating=false;
- mZoomUpdate=false;
- mGBCE=BRIGHTNESS_OFF;
- mGLBCE=BRIGHTNESS_OFF;
- mParameters3A.ExposureLock=OMX_FALSE;
- mParameters3A.WhiteBalanceLock=OMX_FALSE;
-
- mEXIFData.mGPSData.mAltitudeValid=false;
- mEXIFData.mGPSData.mDatestampValid=false;
- mEXIFData.mGPSData.mLatValid=false;
- mEXIFData.mGPSData.mLongValid=false;
- mEXIFData.mGPSData.mMapDatumValid=false;
- mEXIFData.mGPSData.mProcMethodValid=false;
- mEXIFData.mGPSData.mVersionIdValid=false;
- mEXIFData.mGPSData.mTimeStampValid=false;
- mEXIFData.mModelValid=false;
- mEXIFData.mMakeValid=false;
-
- //update the mDeviceOrientation with the sensor mount orientation.
- //So that the face detect will work before onOrientationEvent()
- //gettriggered.
- CAMHAL_ASSERT(mCapabilities);
- mountOrientationString=mCapabilities->get(CameraProperties::ORIENTATION_INDEX);
- CAMHAL_ASSERT(mountOrientationString);
- mDeviceOrientation=atoi(mountOrientationString);
-
- if(mSensorIndex!=2){
- mCapabilities->setMode(MODE_HIGH_SPEED);
- }
-
- if(mCapabilities->get(CameraProperties::SUPPORTED_ZOOM_STAGES)!=NULL){
- mMaxZoomSupported=mCapabilities->getInt(CameraProperties::SUPPORTED_ZOOM_STAGES)+1;
- }else{
- mMaxZoomSupported=1;
- }
-
- //9.initialize command handling thread
- if(mCommandHandler.get()==NULL)
- mCommandHandler=new CommandHandler(this);
-
- if(NULL==mCommandHandler.get())
- {
- CAMHAL_LOGEA("Couldn't create command handler");
- return NO_MEMORY;
- }
-
- ret=mCommandHandler->run("CallbackThread",PRIORITY_URGENT_DISPLAY);
- if(ret!=NO_ERROR)
- {
- if(ret==INVALID_OPERATION){
- CAMHAL_LOGDA("command handler thread already runnning!!");
- ret=NO_ERROR;
- }else{
- CAMHAL_LOGEA("Couldn't run command handlerthread");
- return ret;
- }
- }
-
- //10.initialize omx callback handling thread
- if(mOMXCallbackHandler.get()==NULL)
- mOMXCallbackHandler=new OMXCallbackHandler(this);
-
- if(NULL==mOMXCallbackHandler.get())
- {
- CAMHAL_LOGEA("Couldn't create omx callback handler");
- return NO_MEMORY;
- }
-
- ret=mOMXCallbackHandler->run("OMXCallbackThread",PRIORITY_URGENT_DISPLAY);
- if(ret!=NO_ERROR)
- {
- if(ret==INVALID_OPERATION){
- CAMHAL_LOGDA("omx callback handler thread already runnning!!");
- ret=NO_ERROR;
- }else{
- CAMHAL_LOGEA("Couldn't run omx callback handler thread");
- return ret;
- }
- }
-
- OMX_INIT_STRUCT_PTR(&mRegionPriority,OMX_TI_CONFIG_3A_REGION_PRIORITY);
- OMX_INIT_STRUCT_PTR(&mFacePriority,OMX_TI_CONFIG_3A_FACE_PRIORITY);
- mRegionPriority.nPortIndex=OMX_ALL;
- mFacePriority.nPortIndex=OMX_ALL;
-
- //Setting this flag will that the first setParametercallwill apply all 3A settings
- //andwillnotconditionally apply basedoncurrent values.
- mFirstTimeInit=true;
-
- //Flagtoavoid calling setVFramerate()before OMX_SetParameter(OMX_IndexParamPortDefinition)
- //Ducati will return anerrorotherwise.
- mSetFormatDone=false;
-
- memset(mExposureBracketingValues,0,EXP_BRACKET_RANGE*sizeof(int));
- memset(mZoomBracketingValues,0,ZOOM_BRACKET_RANGE*sizeof(int));
- mMeasurementEnabled=false;
- mFaceDetectionRunning=false;
- mFaceDetectionPaused=false;
- mFDSwitchAlgoPriority=false;
-
- memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex],0,sizeof(OMXCameraPortParameters));
- memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex],0,sizeof(OMXCameraPortParameters));
- memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex],0,sizeof(OMXCameraPortParameters));
- memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex],0,sizeof(OMXCameraPortParameters));
-
- //11.initialize 3A defaults
- mParameters3A.Effect=getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_EFFECT,EffLUT);
- mParameters3A.FlashMode=getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_FLASH_MODE,FlashLUT);
- mParameters3A.SceneMode=getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_SCENE_MODE,SceneLUT);
- mParameters3A.EVCompensation=atoi(OMXCameraAdapter::DEFAULT_EV_COMPENSATION);
- mParameters3A.Focus=getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_FOCUS_MODE,FocusLUT);
- mParameters3A.ISO=getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_ISO_MODE,IsoLUT);
- mParameters3A.Flicker=getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_ANTIBANDING,FlickerLUT);
- mParameters3A.Brightness=atoi(OMXCameraAdapter::DEFAULT_BRIGHTNESS);
- mParameters3A.Saturation=atoi(OMXCameraAdapter::DEFAULT_SATURATION)-SATURATION_OFFSET;
- mParameters3A.Sharpness=atoi(OMXCameraAdapter::DEFAULT_SHARPNESS)-SHARPNESS_OFFSET;
- mParameters3A.Contrast=atoi(OMXCameraAdapter::DEFAULT_CONTRAST)-CONTRAST_OFFSET;
- mParameters3A.WhiteBallance=getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_WB,WBalLUT);
- mParameters3A.Exposure=getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_EXPOSURE_MODE,ExpLUT);
- mParameters3A.ExposureLock=OMX_FALSE;
- mParameters3A.FocusLock=OMX_FALSE;
- mParameters3A.WhiteBalanceLock=OMX_FALSE;
-
- mParameters3A.ManualExposure=0;
- mParameters3A.ManualExposureRight=0;
- mParameters3A.ManualGain=0;
- mParameters3A.ManualGainRight=0;
-
- mParameters3A.AlgoFixedGamma=OMX_TRUE;
- mParameters3A.AlgoNSF1=OMX_TRUE;
- mParameters3A.AlgoNSF2=OMX_TRUE;
- mParameters3A.AlgoSharpening=OMX_TRUE;
- mParameters3A.AlgoThreeLinColorMap=OMX_TRUE;
- mParameters3A.AlgoGIC=OMX_TRUE;
-
- LOG_FUNCTION_NAME_EXIT;
- return ErrorUtils::omxToAndroidError(eError);
-
- EXIT:
-
- CAMHAL_LOGDB("Exiting function %s because of ret %d eError=%x",__FUNCTION__,ret,eError);
- performCleanupAfterError();
- LOG_FUNCTION_NAME_EXIT;
- return ErrorUtils::omxToAndroidError(eError);
- }
1.OMX_Init
从字面上就可以知道,要使用OMX这个方式,那就要为使用它做准备啊,初始化,但我们还是严谨点,说一说吧,
- /**The OMX_Init methodisusedtoinitialize the OMX core.It shall be the
- firstcallmade into OMXandit should only be executed onetimewithout
- an interviening OMX_Deinitcall.
- The core should return from thiscallwithin 20 msec.
- @return OMX_ERRORTYPE
- Ifthe command successfully executes,the return code will be
- OMX_ErrorNone.Otherwise the appropriate OMXerrorwill be returned.
- @ingroup core
- */
- OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);
2.Initialize the callback handles
这里初始化callback handle,那么上面初始化了三个handle,这三个handle具体都实现什么用途呢?
当然一下不是我说的,是TI为方便大家理解,在andriod底层加入了很多很全的注释,一起看看吧
- typedef struct OMX_CALLBACKTYPE
- {
- /**The EventHandler methodisusedtonotify the application when an
- event of interest occurs.Events are definedinthe OMX_EVENTTYPE
- enumeration.Please see that enumerationfordetails of what will
- be returnedforeachtype of event.Callbacks shouldnotreturn
- anerrortothe component,soifanerroroccurs,the application
- shall handle it internally.Thisisa blockingcall.
- The application should return from thiscallwithin 5 msectoavoid
- blocking the componentforan excessively long period oftime.
- @param hComponent
- handle of the componenttoaccess.Thisisthe component
- handle returned by thecalltothe GetHandlefunction.
- @param pAppData
- pointertoan application defined value that was providedinthe
- pAppData parametertothe OMX_GetHandle methodforthe component.
- This application defined valueisprovided so that the application
- can have a component specific context when receiving the callback.
- @param eEvent
- Event that the component wantstonotify the application about.
- @param nData1
- nData will be the OMX_ERRORTYPEforanerroreventandwill be
- an OMX_COMMANDTYPEfora command complete eventandOMX_INDEXTYPEfora OMX_PortSettingsChanged event.
- @param nData2
- nData2 will hold further information relatedtothe event.Can be OMX_STATETYPEfor
- a OMX_CommandStateSet commandorport indexfora OMX_PortSettingsChanged event.
- Default valueis0ifnotused.)
- @param pEventData
- Pointertoadditional event-specific data(see specformeaning).
- */
- OMX_ERRORTYPE(*EventHandler)(
- OMX_IN OMX_HANDLETYPE hComponent,
- OMX_IN OMX_PTR pAppData,
- OMX_IN OMX_EVENTTYPE eEvent,
- OMX_IN OMX_U32 nData1,
- OMX_IN OMX_U32 nData2,
- OMX_IN OMX_PTR pEventData);
- /**The EmptyBufferDone methodisusedtoreturn emptied buffers from an
- input port backtothe applicationforreuse.Thisisa blockingcall
- so the application shouldnotattempttorefill the buffers during this
- call,but should queue themandrefill theminanother thread.There
- isnoerrorreturn,so the application shall handle any errors generated
- internally.
- The application should return from thiscallwithin 5 msec.
- @param hComponent
- handle of the componenttoaccess.Thisisthe component
- handle returned by thecalltothe GetHandlefunction.
- @param pAppData
- pointertoan application defined value that was providedinthe
- pAppData parametertothe OMX_GetHandle methodforthe component.
- This application defined valueisprovided so that the application
- can have a component specific context when receiving the callback.
- @param pBuffer
- pointertoan OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
- orAllocateBuffer indicating the buffer that was emptied.
- @ingroup buf
- */
- OMX_ERRORTYPE(*EmptyBufferDone)(
- OMX_IN OMX_HANDLETYPE hComponent,
- OMX_IN OMX_PTR pAppData,
- OMX_IN OMX_BUFFERHEADERTYPE*pBuffer);
- /**The FillBufferDone methodisusedtoreturn filled buffers from an
- output port backtothe applicationforemptyingandthenreuse.
- Thisisa blockingcallso the application shouldnotattemptto
- emptythe buffers during thiscall,but should queue the buffers
- andemptytheminanother thread.Thereisnoerrorreturn,so
- the application shall handle any errors generated internally.The
- application shall also update the buffer headertoindicate the
- number of bytes placed into the buffer.
- The application should return from thiscallwithin 5 msec.
- @param hComponent
- handle of the componenttoaccess.Thisisthe component
- handle returned by thecalltothe GetHandlefunction.
- @param pAppData
- pointertoan application defined value that was providedinthe
- pAppData parametertothe OMX_GetHandle methodforthe component.
- This application defined valueisprovided so that the application
- can have a component specific context when receiving the callback.
- @param pBuffer
- pointertoan OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
- orAllocateBuffer indicating the buffer that was filled.
- @ingroup buf
- */
- OMX_ERRORTYPE(*FillBufferDone)(
- OMX_OUT OMX_HANDLETYPE hComponent,
- OMX_OUT OMX_PTR pAppData,
- OMX_OUT OMX_BUFFERHEADERTYPE*pBuffer);
- }OMX_CALLBACKTYPE;
EventHandler方法用来通知应用层一些应用层可能感兴趣的一些事件,事件分很多类型,已经用枚举方式定义在 OMX_EVENTTYPE中, 这个回调方法同样不会提示error信息,所以需要用户端自己去分辨,并处理这些信息,保存错误信息;
FillBufferDone方法用来实现从组件的输出端口获取到经过解码等很多操作的buffer,并且放回给应用层,应用层获取使用后,在通过emptyThisBuffer方法清空buffer再次利用, 这个回调方法同样不会提示error信息,所以需要用户端自己去分辨,并处理这些信息,保存错误信息,这里应用层还有一件很重要的事情要做,应用程序要更新缓冲区header的位置,新数据加入,header后移;
3.Get the handle to the OMX Component
- OMX_ERRORTYPE OMXCameraAdapter::OMXCameraGetHandle(OMX_HANDLETYPE*handle,OMX_PTR pAppData,
- constOMX_CALLBACKTYPE&callbacks)
- {
- OMX_ERRORTYPE eError=OMX_ErrorUndefined;
- for(inti=0;i<5;++i){
- if(i>0){
- //sleepfor100 ms beforenextattempt
- usleep(100000);
- }
- //setup key parameterstosendtoDucati during init
- OMX_CALLBACKTYPE oCallbacks=callbacks;
- //gethandle
- eError=OMX_GetHandle(handle,(OMX_STRING)"OMX.TI.DUCATI1.VIDEO.CAMERA",pAppData,&oCallbacks);
- if(eError==OMX_ErrorNone){
- return OMX_ErrorNone;
- }
- CAMHAL_LOGEB("OMX_GetHandle() failed, error: 0x%x",eError);
- }
- *handle=0;
- return eError;
- }
- /**The OMX_GetHandle method will locate the component specified by the
- component name given,load that component into memoryandtheninvoke
- the component's methodstocreate an instance of the component.
- The core should return from thiscallwithin 20 msec.
- @param[out]pHandle
- pointertoan OMX_HANDLETYPE pointertobe filledinby this method.
- @param[in]cComponentName
- pointertoanullterminatedstringwith the component name.The
- names of the components are strings less than 127 bytesinlength
- plus the trailingnullfora maximum size of 128 bytes.An example
- of a valid component nameis"OMX.TI.AUDIO.DSP.MIXER\0".Names are
- assigned by the vendor,but shall start with"OMX."andthenhave
- the Vendor designationnext.
- @param[in]pAppData
- pointertoan application defined value that will be returned
- during callbacks so that the application can identify the source
- of the callback.
- @param[in]pCallBacks
- pointertoa OMX_CALLBACKTYPE structure that will be passedtothe
- componenttoinitialize it with.
- @return OMX_ERRORTYPE
- Ifthe command successfully executes,the return code will be
- OMX_ErrorNone.Otherwise the appropriate OMXerrorwill be returned.
- @ingroup core
- */
- OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
- OMX_OUT OMX_HANDLETYPE*pHandle,
- OMX_IN OMX_STRING cComponentName,
- OMX_IN OMX_PTR pAppData,
- OMX_IN OMX_CALLBACKTYPE*pCallBacks);
4.设置组件最初状态为OMX_StateLoaded状态,并disable所以command port
mComponentState = OMX_StateLoaded ;
eError = OMX_SendCommand ( mCameraAdapterParameters . mHandleComp , OMX_CommandPortDisable , OMX_ALL , NULL ) ;
这里必须重点说说OMX_SendCommand这个方法
- /**Send a commandtothe component.Thiscallisa non-blockingcall.
- The component should check the parametersandthenqueue the command
- tothe component threadtobe executed.The component thread shall
- send the EventHandler()callback at the conclusion of the command.
- This macro will go directly from the applicationtothe component(via
- a core macro).The component will return from thiscallwithin 5 msec.
- When the commandis"OMX_CommandStateSet"the component will queue a
- state transitiontothe new state idenfiedinnParam.
- When the commandis"OMX_CommandFlush",toflush a port's buffer queues,
- the command will force the componenttoreturn all buffersNOTCURRENTLY
- BEING PROCESSEDtothe application,inthe orderinwhich the buffers
- were received.
- When the commandis"OMX_CommandPortDisable"or
- "OMX_CommandPortEnable",the component's port(given by the value of
- nParam)will be stoppedorrestarted.
- When the command"OMX_CommandMarkBuffer"isusedtomark a buffer,the
- pCmdData will pointtoa OMX_MARKTYPE structure containing the component
- handle of the componenttoexamine the buffer chainforthe mark.nParam1
- contains the index of the portonwhich the buffer markisapplied.
- Specification textformore details.
- @param[in]hComponent
- handle of componenttoexecute the command
- @param[in]Cmd
- Commandforthe componenttoexecute
- @param[in]nParam
- Parameterforthe commandtobe executed.When Cmd has the value
- OMX_CommandStateSet,valueisa member of OMX_STATETYPE.When Cmd has
- the value OMX_CommandFlush,value of nParam indicates which port(s)
- toflush.-1isusedtoflush all ports a single port index will
- only flush that port.When Cmd has the value"OMX_CommandPortDisable"
- or"OMX_CommandPortEnable",the component's portisgiven by
- the value of nParam.When Cmd has the value"OMX_CommandMarkBuffer"
- the components potisgiven by the value of nParam.
- @param[in]pCmdData
- Parameter pointingtothe OMX_MARKTYPE structure when Cmd has the value
- "OMX_CommandMarkBuffer".
- @return OMX_ERRORTYPE
- Ifthe command successfully executes,the return code will be
- OMX_ErrorNone.Otherwise the appropriate OMXerrorwill be returned.
- @ingroup comp
- */
- #define OMX_SendCommand(\
- hComponent,\
- Cmd,\
- nParam,\
- pCmdData)\
- ((OMX_COMPONENTTYPE*)hComponent)->SendCommand(\
- hComponent,\
- Cmd,\
- nParam,\
- pCmdData)/*MacroEnd*/
在上面参数中分为以下几种情况:
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);//这个参数是信号量,保证同步
- status_t OMXCameraAdapter::RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,
- OMX_IN OMX_EVENTTYPE eEvent,
- OMX_IN OMX_U32 nData1,
- OMX_IN OMX_U32 nData2,
- OMX_IN Semaphore&semaphore)
- {
- status_t ret=NO_ERROR;
- ssize_t res;
- Mutex::Autolock lock(mEventLock);
- LOG_FUNCTION_NAME;
- TIUTILS::Message*msg=(struct TIUTILS::Message*)malloc(sizeof(struct TIUTILS::Message));
- if(NULL!=msg)
- {
- msg->command=(unsignedint)eEvent;
- msg->arg1=(void*)nData1;
- msg->arg2=(void*)nData2;
- msg->arg3=(void*)&semaphore;
- msg->arg4=(void*)hComponent;
- res=mEventSignalQ.add(msg);
- if(NO_MEMORY==res)
- {
- CAMHAL_LOGEA("No ressources for inserting OMX events");
- free(msg);
- ret=-ENOMEM;
- }
- }
- LOG_FUNCTION_NAME_EXIT;
- return ret;
- }
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来应答应用层的,我们就看看这个方法的具体实现方法
- /*Application callback Functions*/
- /*========================================================*/
- /*@ fn SampleTest_EventHandler::Application callback*/
- /*========================================================*/
- OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEventHandler(OMX_IN OMX_HANDLETYPE hComponent,
- OMX_IN OMX_EVENTTYPE eEvent,
- OMX_IN OMX_U32 nData1,
- OMX_IN OMX_U32 nData2,
- OMX_IN OMX_PTR pEventData)
- {
- LOG_FUNCTION_NAME;
- OMX_ERRORTYPE eError=OMX_ErrorNone;
- CAMHAL_LOGDB("+OMX_Event %x, %d %d",eEvent,(int)nData1,(int)nData2);
- switch(eEvent){
- caseOMX_EventCmdComplete:
- CAMHAL_LOGDB("+OMX_EventCmdComplete %d %d",(int)nData1,(int)nData2);
- if(OMX_CommandStateSet==nData1){
- mCameraAdapterParameters.mState=(OMX_STATETYPE)nData2;
- }elseif(OMX_CommandFlush==nData1){
- CAMHAL_LOGDB("OMX_CommandFlush received for port %d",(int)nData2);
- }elseif(OMX_CommandPortDisable==nData1){
- CAMHAL_LOGDB("OMX_CommandPortDisable received for port %d",(int)nData2);
- }elseif(OMX_CommandPortEnable==nData1){//我们发送的是OMX_CommandPortEnable命令,所以这了nData1就是command type
- CAMHAL_LOGDB("OMX_CommandPortEnable received for port %d",(int)nData2);
- }elseif(OMX_CommandMarkBuffer==nData1){
- ///Thisisnotused currently
- }
- CAMHAL_LOGDA("-OMX_EventCmdComplete");
- break;
- caseOMX_EventIndexSettingChanged:
- CAMHAL_LOGDB("OMX_EventIndexSettingChanged event received data1 0x%x, data2 0x%x",
- (unsignedint)nData1,(unsignedint)nData2);
- break;
- caseOMX_EventError:
- CAMHAL_LOGDB("OMX interface failed to execute OMX command %d",(int)nData1);
- CAMHAL_LOGDA("See OMX_INDEXTYPE for reference");
- if(NULL!=mErrorNotifier&&((OMX_U32)OMX_ErrorHardware==nData1)&&mComponentState!=OMX_StateInvalid)
- {
- CAMHAL_LOGEA("***Got Fatal Error Notification***\n");
- mComponentState=OMX_StateInvalid;
- /*
- Remove any unhandled eventsand
- unblock any waiting semaphores
- */
- if(!mEventSignalQ.isEmpty())
- {
- for(unsignedinti=0;i<mEventSignalQ.size();i++)
- {
- CAMHAL_LOGEB("***Removing %d EVENTS***** \n",mEventSignalQ.size());
- //remove from queueandfree msg
- TIUTILS::Message*msg=mEventSignalQ.itemAt(i);
- if(NULL!=msg)
- {
- Semaphore*sem=(Semaphore*)msg->arg3;
- if(sem)
- {
- sem->Signal();
- }
- free(msg);
- }
- }
- mEventSignalQ.clear();
- }
- ///ReportErrortoApp
- mErrorNotifier->errorNotify(CAMERA_ERROR_FATAL);
- }
- break;
- caseOMX_EventMark:
- break;
- caseOMX_EventPortSettingsChanged:
- break;
- caseOMX_EventBufferFlag:
- break;
- caseOMX_EventResourcesAcquired:
- break;
- caseOMX_EventComponentResumed:
- break;
- caseOMX_EventDynamicResourcesAvailable:
- break;
- caseOMX_EventPortFormatDetected:
- break;
- default:
- break;
- }
- ///Signaltothe thread(s)waiting that the event has occured
- SignalEvent(hComponent,eEvent,nData1,nData2,pEventData);//这里才是重点
- LOG_FUNCTION_NAME_EXIT;
- return eError;
- EXIT:
- CAMHAL_LOGEB("Exiting function %s because of eError=%x",__FUNCTION__,eError);
- LOG_FUNCTION_NAME_EXIT;
- return eError;
- }
- OMX_ERRORTYPE OMXCameraAdapter::SignalEvent(OMX_IN OMX_HANDLETYPE hComponent,
- OMX_IN OMX_EVENTTYPE eEvent,
- OMX_IN OMX_U32 nData1,
- OMX_IN OMX_U32 nData2,
- OMX_IN OMX_PTR pEventData)
- {
- Mutex::Autolock lock(mEventLock);
- TIUTILS::Message*msg;
- bool eventSignalled=false;
- LOG_FUNCTION_NAME;
- if(!mEventSignalQ.isEmpty())
- {
- CAMHAL_LOGDA("Event queue not empty");
- for(unsignedinti=0;i<mEventSignalQ.size();i++)
- {
- msg=mEventSignalQ.itemAt(i);
- if(NULL!=msg)
- {
- if((msg->command!=0||msg->command==(unsignedint)(eEvent))
- &&(!msg->arg1||(OMX_U32)msg->arg1==nData1)
- &&(!msg->arg2||(OMX_U32)msg->arg2==nData2)
- &&msg->arg3)
- {
- Semaphore*sem=(Semaphore*)msg->arg3;
- CAMHAL_LOGDA("Event matched, signalling sem");
- mEventSignalQ.removeAt(i);
- //Signal the semaphore provided
- sem->Signal();
- free(msg);
- break;
- }
- }
- }
- }
- else
- {
- CAMHAL_LOGDA("Event queue empty!!!");
- }
- //Special handlingforany unregistered events
- if(!eventSignalled){
- //Handlingforfocus callback
- if((nData2==OMX_IndexConfigCommonFocusStatus)&&
- (eEvent==(OMX_EVENTTYPE)OMX_EventIndexSettingChanged)){
- TIUTILS::Message msg;
- msg.command=OMXCallbackHandler::CAMERA_FOCUS_STATUS;
- msg.arg1=NULL;
- msg.arg2=NULL;
- mOMXCallbackHandler->put(&msg);
- }
- }
- LOG_FUNCTION_NAME_EXIT;
- return OMX_ErrorNone;
- }
我们看看上面的语句到底做了什么,检测到 mEventSignalQ这个消息队列中有消息,而这里在第6步中不是刚刚往这个消息队列中添加了一个消息嘛!看来他们有点暧昧,接着看,进行了遍历查找的操作,那么找的到底是什么呢?上面的判断条件很明确,不同的一点马虎,看看这个消息队列中是是否有和我从组件发来的消息一致的消息,找到了,那就说明消息处理完了,组件成功应答给应用层了,那么就得到了那个信号量,并且发送一个信号给wait方法,wait方法接到信号立即返回,否则一直等待直到超时,超时返回非零值,否则返回零,程序中如果wait超时,调用RemoveEvent方法
- OMX_ERRORTYPE OMXCameraAdapter::RemoveEvent(OMX_IN OMX_HANDLETYPE hComponent,
- OMX_IN OMX_EVENTTYPE eEvent,
- OMX_IN OMX_U32 nData1,
- OMX_IN OMX_U32 nData2,
- OMX_IN OMX_PTR pEventData)
- {
- Mutex::Autolock lock(mEventLock);
- TIUTILS::Message*msg;
- LOG_FUNCTION_NAME;
- if(!mEventSignalQ.isEmpty())
- {
- CAMHAL_LOGDA("Event queue not empty");
- for(unsignedinti=0;i<mEventSignalQ.size();i++)
- {
- msg=mEventSignalQ.itemAt(i);
- if(NULL!=msg)
- {
- if((msg->command!=0||msg->command==(unsignedint)(eEvent))
- &&(!msg->arg1||(OMX_U32)msg->arg1==nData1)
- &&(!msg->arg2||(OMX_U32)msg->arg2==nData2)
- &&msg->arg3)
- {
- Semaphore*sem=(Semaphore*)msg->arg3;
- CAMHAL_LOGDA("Event matched, signalling sem");
- mEventSignalQ.removeAt(i);
- free(msg);
- break;
- }
- }
- }
- }
- else
- {
- CAMHAL_LOGEA("Event queue empty!!!");
- }
- LOG_FUNCTION_NAME_EXIT;
- return OMX_ErrorNone;
- }
这里有一个地方我还是要提及一下,那就是组件回馈的enent类型,直接贴在这里
- /**@ingroup comp*/
- typedef enum OMX_EVENTTYPE
- {
- OMX_EventCmdComplete,/**<component has sucessfully completed a command*/
- OMX_EventError,/**<component has detected anerrorcondition*/
- OMX_EventMark,/**<component has detected a buffer mark*/
- OMX_EventPortSettingsChanged,/**<componentisreported a port settings change*/
- OMX_EventBufferFlag,/**<component has detected an EOS*/
- OMX_EventResourcesAcquired,/**<component has been granted resourcesandis
- automatically starting the state change from
- OMX_StateWaitForResourcestoOMX_StateIdle.*/
- OMX_EventComponentResumed,/**<Component resumed duetoreacquisition of resources*/
- OMX_EventDynamicResourcesAvailable,/**<Component has acquired previously unavailable dynamic resources*/
- OMX_EventPortFormatDetected,/**<Component has detected a supported format.*/
- OMX_EventKhronosExtensions=0x6F000000,/**<Reserved regionforintroducing Khronos Standard Extensions*/
- OMX_EventVendorStartUnused=0x7F000000,/**<Reserved regionforintroducing Vendor Extensions*/
- OMX_EventMax=0x7FFFFFFF
- }OMX_EVENTTYPE;
8.Select the sensor
这里我们首先看看OMX_CONFIG_SENSORSELECTTYPE这个结构
定义在以下目录:hardware\ti\omap4xxx\domx\omx_core\inc\OMX_TI_IVCommon.h
- /*
- *SensorSelect
- */
- typedef struct OMX_CONFIG_SENSORSELECTTYPE{
- OMX_U32 nSize;/**<Size of the structureinbytes*/
- OMX_VERSIONTYPE nVersion;/**<OMX specification version info*/
- OMX_U32 nPortIndex;/**<Port that this struct appliesto*/
- OMX_SENSORSELECT eSensor;/**<sensorselect*/
- }OMX_CONFIG_SENSORSELECTTYPE;
OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
- #define OMX_INIT_STRUCT_PTR(_s_,_name_)\
- memset((_s_),0x0,sizeof(_name_));\
- (_s_)->nSize=sizeof(_name_);\
- (_s_)->nVersion.s.nVersionMajor=0x1;\
- (_s_)->nVersion.s.nVersionMinor=0x1;\
- (_s_)->nVersion.s.nRevision=0x0;\
- (_s_)->nVersion.s.nStep=0x0
最后调用OMX_SetConfig()这个方法
- /**The OMX_SetConfig macro will send one of the configuration
- structurestoa component.Eachstructure shall be sent one at atime,
- eachina separate invocation of the macro.This macro can be invoked
- anytime after the component has been loaded.The application shall
- allocate the correct structureandshall fillinthe structure size
- andversion information(as well as the actual data)before invoking
- this macro.The applicationisfreetodispose of this structure after
- thecallas the componentisrequiredtocopy any data it shall retain.
- Thisisa blockingcall.
- The component should return from thiscallwithin 5 msec.
- @param[in]hComponent
- Handle of the componenttobe accessed.Thisisthe component
- handle returned by thecalltothe OMX_GetHandlefunction.
- @param[in]nConfigIndex
- Index of the structuretobe sent.This valueisfrom the
- OMX_INDEXTYPE enumeration above.
- @param[in]pComponentConfigStructure
- pointertoapplication allocated structuretobe usedfor
- initialization by the component.
- @return OMX_ERRORTYPE
- Ifthe command successfully executes,the return code will be
- OMX_ErrorNone.Otherwise the appropriate OMXerrorwill be returned.
- @ingroup comp
- */
- #define OMX_SetConfig(\
- hComponent,\
- nConfigIndex,\
- pComponentConfigStructure)\
- ((OMX_COMPONENTTYPE*)hComponent)->SetConfig(\
- hComponent,\
- nConfigIndex,\
- pComponentConfigStructure)/*MacroEnd*/
9.参数初始化
其中最重要的是initialize方法引入的参数传递给了 mCapabilities
mCapabilities = caps;
并且通过mCapabilities->get()方法获得相应的参数初始化
10.initialize command handling thread
这里只是创建了一个CommandHandler线程,并且启动了这个线程,我们重点看看这个线程都干了些甚么
- bool OMXCameraAdapter::CommandHandler::Handler()
- {
- TIUTILS::Message msg;
- volatileintforever=1;
- status_t stat;
- ErrorNotifier*errorNotify=NULL;
- LOG_FUNCTION_NAME;
- while(forever)
- {
- stat=NO_ERROR;
- CAMHAL_LOGDA("Handler: waiting for messsage...");
- TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ,NULL,NULL,-1);
- {
- Mutex::Autolock lock(mLock);
- mCommandMsgQ.get(&msg);
- }
- CAMHAL_LOGDB("msg.command = %d",msg.command);
- switch(msg.command){
- caseCommandHandler::CAMERA_START_IMAGE_CAPTURE:
- {
- OMXCameraAdapter::CachedCaptureParameters*cap_params=
- static_cast<OMXCameraAdapter::CachedCaptureParameters*>(msg.arg2);
- stat=mCameraAdapter->startImageCapture(false,cap_params);
- delete cap_params;
- break;
- }
- caseCommandHandler::CAMERA_PERFORM_AUTOFOCUS:
- {
- stat=mCameraAdapter->doAutoFocus();
- break;
- }
- caseCommandHandler::COMMAND_EXIT:
- {
- CAMHAL_LOGDA("Exiting command handler");
- forever=0;
- break;
- }
- caseCommandHandler::CAMERA_SWITCH_TO_EXECUTING:
- {
- stat=mCameraAdapter->doSwitchToExecuting();
- break;
- }
- caseCommandHandler::CAMERA_START_REPROCESS:
- {
- OMXCameraAdapter::CachedCaptureParameters*cap_params=
- static_cast<OMXCameraAdapter::CachedCaptureParameters*>(msg.arg2);
- stat=mCameraAdapter->startReprocess();
- stat=mCameraAdapter->startImageCapture(false,cap_params);
- delete cap_params;
- break;
- }
- }
- }
- LOG_FUNCTION_NAME_EXIT;
- returnfalse;
- }
11.initialize omx callback handling thread
这里和上面很类似,创建一个OMXCallbackHandler线程,并启动这个线程,同样看看这个线程都干了些甚么
- bool OMXCameraAdapter::OMXCallbackHandler::Handler()
- {
- TIUTILS::Message msg;
- volatileintforever=1;
- status_t ret=NO_ERROR;
- LOG_FUNCTION_NAME;
- while(forever){
- TIUTILS::MessageQueue::waitForMsg(&mCommandMsgQ,NULL,NULL,-1);
- {
- Mutex::Autolock lock(mLock);
- mCommandMsgQ.get(&msg);
- mIsProcessed=false;
- }
- switch(msg.command){
- caseOMXCallbackHandler::CAMERA_FILL_BUFFER_DONE:
- {
- ret=mCameraAdapter->OMXCameraAdapterFillBufferDone((OMX_HANDLETYPE)msg.arg1,
- (OMX_BUFFERHEADERTYPE*)msg.arg2);
- break;
- }
- caseOMXCallbackHandler::CAMERA_FOCUS_STATUS:
- {
- mCameraAdapter->handleFocusCallback();
- break;
- }
- caseCommandHandler::COMMAND_EXIT:
- {
- CAMHAL_LOGDA("Exiting OMX callback handler");
- forever=0;
- break;
- }
- }
- {
- android::AutoMutex locker(mLock);
- CAMHAL_UNUSED(locker);
- mIsProcessed=mCommandMsgQ.isEmpty();
- if(mIsProcessed)
- mCondition.signal();
- }
- }
- //force the conditiontowake
- {
- android::AutoMutex locker(mLock);
- CAMHAL_UNUSED(locker);
- mIsProcessed=true;
- mCondition.signal();
- }
- LOG_FUNCTION_NAME_EXIT;
- returnfalse;
- }
12.initialize 3A defaults
这里暂不做说明,都是对很多参数的基本初始化
到这里为止,OMXCameraAdapter的初始化就结束了
待续。。。。。
更多相关文章
- Android—高级组件对应属性大全及使用详例
- 安卓-菜单简述
- Android(安卓)开发必读:如何成为一名优秀的Android开发者
- Android布局中margin,padding,align的用法和区别
- Android漏洞,WebView漏洞,Web漏洞与Web安全
- 浅谈Java中Collections.sort对List排序的两种方法
- mybatisplus的坑 insert标签insert into select无参数问题的解决
- Python技巧匿名函数、回调函数和高阶函数
- Python list sort方法的具体使用