這幾天一直在研究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方法都幹了些甚麼?
-
/*--------------------Camera
Adapter Class STARTS here-----------------------------*/
-
-
status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps)
-
{
-
LOG_FUNCTION_NAME;
-
-
char value[PROPERTY_VALUE_MAX];
-
const char *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 preview and image
capture port indexes
-
mCameraAdapterParameters.mPrevPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
-
// temp changed in order to build
OMX_CAMERA_PORT_VIDEO_OUT_IMAGE;
-
mCameraAdapterParameters.mImagePortIndex = OMX_CAMERA_PORT_IMAGE_OUT_IMAGE;
-
mCameraAdapterParameters.mMeasurementPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT;
-
//currently not supported 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.Get the
handle to the 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.Register for port
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);
-
goto EXIT;
-
}
-
-
// 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.Wait for the
port enable event to occur
-
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!");
-
goto EXIT;
-
}
-
-
// 7.Select the sensor
-
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()
-
//get triggered.
-
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 setParameter call will apply
all 3A settings
-
//and will not conditionally
apply based on current values.
-
mFirstTimeInit = true;
-
-
//Flag to avoid calling setVFramerate() before
OMX_SetParameter(OMX_IndexParamPortDefinition)
-
//Ducati will return an error otherwise.
-
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 method is used to initialize
the OMX core. It shall be the
-
first call made into OMX and it should only be executed one time without
-
an interviening OMX_Deinit call.
-
-
The core should return from this call within 20 msec.
-
-
@return OMX_ERRORTYPE
-
If the command successfully executes, the return code will be
-
OMX_ErrorNone. Otherwise the appropriate OMX error will 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 method is used to notify
the application when an
-
event of interest occurs. Events are defined in the OMX_EVENTTYPE
-
enumeration. Please see that enumeration for details of what will
-
be returned for each type of event. Callbacks should not return
-
an error to the component, so if an error occurs, the
application
-
shall handle it internally. This is a blocking call.
-
-
The application should return from this call within 5 msec to avoid
-
blocking the component for an excessively long period of time.
-
-
@param hComponent
-
handle of the component to access. This is the component
-
handle returned by the call to the GetHandle function.
-
@param pAppData
-
pointer to an application defined value that was provided in the
-
pAppData parameter to the OMX_GetHandle method for the component.
-
This application defined value is provided so that the application
-
can have a component specific context when receiving the callback.
-
@param eEvent
-
Event that the component wants to notify the application about.
-
@param nData1
-
nData will be the OMX_ERRORTYPE for an error event and will
be
-
an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a
OMX_PortSettingsChanged event.
-
@param nData2
-
nData2 will hold further information related to the event. Can be OMX_STATETYPE for
-
a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event.
-
Default value is 0 if not used. )
-
@param pEventData
-
Pointer to additional event-specific data (see spec for meaning).
-
*/
-
-
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 method is used to return
emptied buffers from an
-
input port back to the application for reuse. This is a
blocking call
-
so the application should not attempt to refill the buffers during this
-
call, but should queue them and refill them in another
thread. There
-
is no error return, so the application shall handle any errors
generated
-
internally.
-
-
The application should return from this call within 5 msec.
-
-
@param hComponent
-
handle of the component to access. This is the component
-
handle returned by the call to the GetHandle function.
-
@param pAppData
-
pointer to an application defined value that was provided in the
-
pAppData parameter to the OMX_GetHandle method for the component.
-
This application defined value is provided so that the application
-
can have a component specific context when receiving the callback.
-
@param pBuffer
-
pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
-
or AllocateBuffer 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 method is used to return
filled buffers from an
-
output port back to the application for emptying and then reuse.
-
This is a blocking call so the application should not attempt to
-
empty the buffers during this call, but should queue the buffers
-
and empty them in another thread. There is no error return, so
-
the application shall handle any errors generated internally. The
-
application shall also update the buffer header to indicate the
-
number of bytes placed into the buffer.
-
-
The application should return from this call within 5 msec.
-
-
@param hComponent
-
handle of the component to access. This is the component
-
handle returned by the call to the GetHandle function.
-
@param pAppData
-
pointer to an application defined value that was provided in the
-
pAppData parameter to the OMX_GetHandle method for the component.
-
This application defined value is provided so that the application
-
can have a component specific context when receiving the callback.
-
@param pBuffer
-
pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
-
or AllocateBuffer 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,
-
const OMX_CALLBACKTYPE & callbacks)
-
{
-
OMX_ERRORTYPE eError = OMX_ErrorUndefined;
-
-
for ( int i = 0; i < 5; ++i ) {
-
if ( i > 0 ) {
-
// sleep for 100 ms before next attempt
-
usleep(100000);
-
}
-
-
// setup key parameters to send to Ducati
during init
-
OMX_CALLBACKTYPE oCallbacks = callbacks;
-
-
// get handle
-
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 memory and then invoke
-
the component's methods to create an instance of the component.
-
-
The core should return from this call within 20 msec.
-
-
@param [out] pHandle
-
pointer to an OMX_HANDLETYPE pointer to be filled in by this method.
-
@param [in] cComponentName
-
pointer to a null terminated string with the component name. The
-
names of the components are strings less than 127 bytes in length
-
plus the trailing null for a maximum size of 128 bytes. An example
-
of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names
are
-
assigned by the vendor, but shall start with "OMX." and then have
-
the Vendor designation next.
-
@param [in] pAppData
-
pointer to an application defined value that will be returned
-
during callbacks so that the application can identify the source
-
of the callback.
-
@param [in] pCallBacks
-
pointer to a OMX_CALLBACKTYPE structure that will be passed to the
-
component to initialize it with.
-
@return OMX_ERRORTYPE
-
If the command successfully executes, the return code will be
-
OMX_ErrorNone. Otherwise the appropriate OMX error will 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 command to the
component. This call is a non-blocking call.
-
The component should check the parameters and then queue the command
-
to the component thread to be executed. The component thread shall
-
send the EventHandler() callback at the conclusion of the command.
-
This macro will go directly from the application to the component (via
-
a core macro). The component will return from this call within 5 msec.
-
-
When the command is "OMX_CommandStateSet" the component will queue a
-
state transition to the new state idenfied in nParam.
-
-
When the command is "OMX_CommandFlush", to flush
a port's buffer queues,
-
the command will force the component to return all buffers NOT CURRENTLY
-
BEING PROCESSED to the application, in the order in which
the buffers
-
were received.
-
-
When the command is "OMX_CommandPortDisable" or
-
"OMX_CommandPortEnable", the component's port (given
by the value of
-
nParam) will be stopped or restarted.
-
-
When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the
-
pCmdData will point to a OMX_MARKTYPE structure containing the component
-
handle of the component to examine the buffer chain for the mark. nParam1
-
contains the index of the port on which the buffer mark is applied.
-
-
Specification text for more details.
-
-
@param [in] hComponent
-
handle of component to execute the command
-
@param [in] Cmd
-
Command for the component to execute
-
@param [in] nParam
-
Parameter for the command to be executed. When Cmd has the value
-
OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd
has
-
the value OMX_CommandFlush, value of nParam indicates which port(s)
-
to flush. -1 is used to flush
all ports a single port index will
-
only flush that port. When Cmd has the value "OMX_CommandPortDisable"
-
or "OMX_CommandPortEnable", the component's
port is given by
-
the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer"
-
the components pot is given by the value of nParam.
-
@param [in] pCmdData
-
Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value
-
"OMX_CommandMarkBuffer".
-
@return OMX_ERRORTYPE
-
If the command successfully executes, the return code will be
-
OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
-
@ingroup comp
-
*/
-
#define OMX_SendCommand( \
-
hComponent, \
-
Cmd, \
-
nParam, \
-
pCmdData) \
-
((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \
-
hComponent, \
-
Cmd, \
-
nParam, \
- pCmdData) /* Macro End */
在上面參數中分爲以下幾種情況:
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 = ( unsigned int ) 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) {
-
case OMX_EventCmdComplete:
-
CAMHAL_LOGDB("+OMX_EventCmdComplete %d %d", (int)nData1, (int)nData2);
-
-
if (OMX_CommandStateSet == nData1) {
-
mCameraAdapterParameters.mState = (OMX_STATETYPE) nData2;
-
-
} else if (OMX_CommandFlush == nData1) {
-
CAMHAL_LOGDB("OMX_CommandFlush received for port %d", (int)nData2);
-
-
} else if (OMX_CommandPortDisable == nData1) {
-
CAMHAL_LOGDB("OMX_CommandPortDisable received for port %d", (int)nData2);
-
-
} else if (OMX_CommandPortEnable == nData1) {//我們發送的是OMX_CommandPortEnable命令,所以這了nData1就是command
type
-
CAMHAL_LOGDB("OMX_CommandPortEnable
received for port %d", (int)nData2);
-
-
} else if (OMX_CommandMarkBuffer == nData1) {
-
///This is not used
currently
-
}
-
-
CAMHAL_LOGDA("-OMX_EventCmdComplete");
-
break;
-
-
case OMX_EventIndexSettingChanged:
-
CAMHAL_LOGDB("OMX_EventIndexSettingChanged event received data1 0x%x, data2 0x%x",
-
( unsigned int ) nData1, ( unsigned int ) nData2);
-
break;
-
-
case OMX_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 events and
-
unblock any waiting semaphores
-
*/
-
if ( !mEventSignalQ.isEmpty() )
-
{
-
for (unsigned int i = 0 ; i < mEventSignalQ.size(); i++ )
-
{
-
CAMHAL_LOGEB("***Removing %d EVENTS***** \n", mEventSignalQ.size());
-
//remove from queue and free msg
-
TIUTILS::Message *msg = mEventSignalQ.itemAt(i);
-
if ( NULL != msg )
-
{
-
Semaphore *sem = (Semaphore*) msg->arg3;
-
if ( sem )
-
{
-
sem->Signal();
-
}
-
free(msg);
-
}
-
}
-
mEventSignalQ.clear();
-
}
-
///Report Error to App
-
mErrorNotifier->errorNotify(CAMERA_ERROR_FATAL);
-
}
-
break;
-
-
case OMX_EventMark:
-
break;
-
-
case OMX_EventPortSettingsChanged:
-
break;
-
-
case OMX_EventBufferFlag:
-
break;
-
-
case OMX_EventResourcesAcquired:
-
break;
-
-
case OMX_EventComponentResumed:
-
break;
-
-
case OMX_EventDynamicResourcesAvailable:
-
break;
-
-
case OMX_EventPortFormatDetected:
-
break;
-
-
default:
-
break;
-
}
-
-
///Signal to the
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 ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
-
{
-
msg = mEventSignalQ.itemAt(i);
-
if ( NULL != msg )
-
{
-
if( ( msg->command != 0 || msg->command == ( unsigned int ) ( 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 handling for any unregistered events
-
if (!eventSignalled) {
-
// Handling for focus 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 ( unsigned int i = 0 ; i < mEventSignalQ.size() ; i++ )
-
{
-
msg = mEventSignalQ.itemAt(i);
-
if ( NULL != msg )
-
{
-
if( ( msg->command != 0 || msg->command == ( unsigned int ) ( 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 an error condition */
-
OMX_EventMark, /**< component
has detected a buffer mark */
-
OMX_EventPortSettingsChanged, /**< component is reported
a port settings change */
-
OMX_EventBufferFlag, /**< component
has detected an EOS */
-
OMX_EventResourcesAcquired, /**< component
has been granted resources and is
-
automatically starting the state change from
-
OMX_StateWaitForResources to OMX_StateIdle. */
-
OMX_EventComponentResumed, /**< Component
resumed due to reacquisition of resources */
-
OMX_EventDynamicResourcesAvailable, /**< Component
has acquired previously unavailable dynamic resources */
-
OMX_EventPortFormatDetected, /**< Component
has detected a supported format. */
-
OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved
region for introducing Khronos Standard Extensions */
-
OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved
region for introducing 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
-
/*
-
* Sensor Select
-
*/
-
typedef struct OMX_CONFIG_SENSORSELECTTYPE {
-
OMX_U32 nSize; /**< Size
of the structure in bytes */
-
OMX_VERSIONTYPE nVersion; /**< OMX
specification version info */
-
OMX_U32 nPortIndex; /**< Port
that this struct applies to */
-
OMX_SENSORSELECT eSensor; /**< sensor select */
- } 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
-
structures to a component. Each structure shall be sent one at a time,
-
each in a separate invocation of the macro. This macro can be invoked
-
anytime after the component has been loaded. The application shall
-
allocate the correct structure and shall fill in the structure size
-
and version information (as well as the actual data) before invoking
-
this macro. The application is free to dispose of this structure after
-
the call as the component is required to copy any data it shall retain.
-
This is a blocking call.
-
-
The component should return from this call within 5 msec.
-
-
@param [in] hComponent
-
Handle of the component to be accessed. This is the component
-
handle returned by the call to the OMX_GetHandle function.
-
@param [in] nConfigIndex
-
Index of the structure to be sent. This value is from the
-
OMX_INDEXTYPE enumeration above.
-
@param [in] pComponentConfigStructure
-
pointer to application allocated structure to be used for
-
initialization by the component.
-
@return OMX_ERRORTYPE
-
If the command successfully executes, the return code will be
-
OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
-
@ingroup comp
-
*/
-
#define OMX_SetConfig( \
-
hComponent, \
-
nConfigIndex, \
-
pComponentConfigStructure) \
-
((OMX_COMPONENTTYPE*)hComponent)->SetConfig( \
-
hComponent, \
-
nConfigIndex, \
- pComponentConfigStructure) /* Macro End */
9.參數初始化
其中最重要的是initialize方法引入的參數傳遞給了mCapabilities
mCapabilities = caps;
並且通過mCapabilities->get()方法獲得相應的參數初始化
10.initialize command handling thread
這裏只是創建了一個CommandHandler線程,並且啓動了這個線程,我們重點看看這個線程都幹了些甚麼
-
bool OMXCameraAdapter::CommandHandler::Handler()
-
{
-
TIUTILS::Message msg;
-
volatile int forever = 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 ) {
-
case CommandHandler::CAMERA_START_IMAGE_CAPTURE:
-
{
-
OMXCameraAdapter::CachedCaptureParameters* cap_params =
-
static_cast<OMXCameraAdapter::CachedCaptureParameters*>(msg.arg2);
-
stat = mCameraAdapter->startImageCapture(false, cap_params);
-
delete cap_params;
-
break;
-
}
-
case CommandHandler::CAMERA_PERFORM_AUTOFOCUS:
-
{
-
stat = mCameraAdapter->doAutoFocus();
-
break;
-
}
-
case CommandHandler::COMMAND_EXIT:
-
{
-
CAMHAL_LOGDA("Exiting command handler");
-
forever = 0;
-
break;
-
}
-
case CommandHandler::CAMERA_SWITCH_TO_EXECUTING:
-
{
-
stat = mCameraAdapter->doSwitchToExecuting();
-
break;
-
}
-
case CommandHandler::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;
-
-
return false;
- }
11.initialize omx callback handling thread
這裏和上面很類似,創建一個OMXCallbackHandler線程,並啓動這個線程,同樣看看這個線程都幹了些甚麼
-
bool OMXCameraAdapter::OMXCallbackHandler::Handler()
-
{
-
TIUTILS::Message msg;
-
volatile int forever = 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 ) {
-
case OMXCallbackHandler::CAMERA_FILL_BUFFER_DONE:
-
{
-
ret = mCameraAdapter->OMXCameraAdapterFillBufferDone(( OMX_HANDLETYPE ) msg.arg1,
-
( OMX_BUFFERHEADERTYPE *) msg.arg2);
-
break;
-
}
-
case OMXCallbackHandler::CAMERA_FOCUS_STATUS:
-
{
-
mCameraAdapter->handleFocusCallback();
-
break;
-
}
-
case CommandHandler::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 condition to wake
-
{
-
android::AutoMutex locker(mLock);
-
CAMHAL_UNUSED(locker);
-
-
mIsProcessed = true;
-
mCondition.signal();
-
}
-
-
LOG_FUNCTION_NAME_EXIT;
-
return false;
- }
12.initialize 3A defaults
這裏暫不做說明,都是對很多參數的基本初始化
到這裏爲止,OMXCameraAdapter的初始化就結束了
待續。。。。。