Android Camera OMXCameraAdapter.cpp初始化分析

来源:互联网 发布:天津网络作家排行榜 编辑:程序博客网 时间:2024/05/29 16:27

原文地址:Android Camera OMXCameraAdapter.cpp初始化分析 作者:xinyuwuxian

Camera相关:http://blog.chinaunix.net/uid/26765074/list/1.html?cid=174478

这几天一直在研究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);    // 4.设置component的初始状态    mComponentState = OMX_StateLoaded;    CAMHAL_LOGVB("OMX_GetHandle -0x%x sensor_index = %lu", eError, mSensorIndex);    initDccFileDataSave(&mCameraAdapterParameters.mHandleComp, mCameraAdapterParameters.mPrevPortIndex);    // 5.disable所以的component    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);    // 6.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;    }    // 7.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);    // 8.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;     }    // 9.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    // 10.初始化默认参数    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;    }    // 11.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;        }    }    // 12.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));    // 13.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);}

这里就是针对上面的这个过程进行全面分析,上面已经很清楚的标出了每一步,下面开始进入正题,唉,这个第二遍写这篇文章了,不知道怎么回事,之前写完了发布了,然后提示要审核,后来就再也没有消息了,我辛辛苦苦写好的文章啊!就这样没了,心痛,一直把这里当做学习的记事本,把自己的技术思路总结出来,希望ChinaUnix改进吧,越做越好!!
现在开始正文:

// 1.OMX_Init
这里从字面就可以知道这个方法到底是干什么的,看看TI给他的说明吧

/** 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);

上面说的很清楚,这个方法用来initialize OMX core,只能调用一次除非使用过了OMX_Diniit


// 2.Initialize the callback handles
callbacks.EventHandler    = android::OMXCameraAdapterEventHandler;
callbacks.EmptyBufferDone = android::OMXCameraAdapterEmptyBufferDone;
callbacks.FillBufferDone  = android::OMXCameraAdapterFillBufferDone;
这里这三个函数的引入很低调,但是却很重要,那叫相当重要啊


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;

第二遍写就是没动力啊,不翻译了,很容易理解的,三个很重要的回调函数


// 3.Get the handle to the OMX Component
通过这个方法获得组件的handle,在相当于应用程序访问文件获得的句柄fd

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;}

上面直接调用接口中的方法获取handle

/** 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.设置component的初始状态
前面介绍OMX的时候已经说过了,使用OMX要按照规矩办事,有指定的流程的
这里就是初始化这个状态,使组件状态为最初状态,就好像睡觉前先脱好衣服一样


// 5.disable所有的component
这里调用了一个方法是我们关注的重点,调用这个方法实现的功能其实已经说的很清楚了,不就是disable 所有组件吗
但是这个还是很有必要分析一下这个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 */


// 6.Register for port enable event
这里还是坚持说一下吧
RegisterForEvent(mCameraAdapterParameters.mHandleComp,
                                 OMX_EventCmdComplete,
                                 OMX_CommandPortEnable,
                                 mCameraAdapterParameters.mPrevPortIndex,
                                 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;}

这里只是把我们传入的数据打包成一个Message,让后把这个消息添加到mEventSignalQ队列中,接着往下看,重点在后面呢?

// 7.Enable PREVIEW Port
这个调用之前分析过的OMX_SendCommand方法enable 组件的preview port

// 8.Wait for the port enable event to occur
这里到了我们的重点了,上面第七步调用了OMX_SendCommand这个方法,组件在完成处理后实际上会给应用层一个应答,这个应答是通过我们上面说过的一个callback来通知应用层的,所以这里我们看看这个处理回调方法的实现:


// 9.Select the sensor

// 10.初始化默认参数

// 11.initialize command handling thread

// 12.initialize omx callback handling thread

// 13.initialize 3A defaults

待填充内容。。。。。。
0 0
原创粉丝点击