Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1108736
  • 博文数量: 254
  • 博客积分: 1242
  • 博客等级: 少尉
  • 技术积分: 1581
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-03 21:49
文章分类

全部博文(254)

文章存档

2017年(16)

2016年(4)

2013年(94)

2012年(140)

分类: Android平台

2013-11-19 15:22: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 camera driver实现交互,进而实现camera 的使用,包括数据回调等过程,但是这里的OMX方法完全颠覆了我之前的想法,开始在研究OMX的时候自己就是调用这个死胡同里了,一直在试图在OMX的实现中找到他到底是在哪么访问设备的,本来我是以后最终他还是通过V4L2这种方式,事实证明我错了,OMX是一种完全不同于V4L2 的访问camera的策略,他通过A9端的omx client和DSP端的omx通信,而且最终访问camera的方法是在DSP端omx server接到到A9端的omx client配置后按照指定方法实现camera 的控制的,这里ducati端到底是怎么处理的我暂时没有关注,暂时精力有限啊!
以上是我自己的见解,也许是完全错误的,待确认,这里只是总结我的分析过程
经过上面我的概述,自然A9端的这个OMXCameraAdapter对于我来说就是一切了,分析它是必经之路啊
现在就开始:
首先要知道在哪里实例化了这个类的对象,这个在之前已经说到过了,这个不在说明,重点看看他的initialize方法都干了些甚么

  1. /*--------------------Camera Adapter Class STARTS here-----------------------------*/

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

  5.     char value[PROPERTY_VALUE_MAX];
  6.     const char *mountOrientationString = NULL;

  7.     property_get("debug.camera.showfps", value, "0");
  8.     mDebugFps = atoi(value);
  9.     property_get("debug.camera.framecounts", value, "0");
  10.     mDebugFcs = atoi(value);

  11. #ifdef CAMERAHAL_OMX_PROFILING

  12.     property_get("debug.camera.profile", value, "0");
  13.     mDebugProfile = atoi(value);

  14. #endif

  15.     TIMM_OSAL_ERRORTYPE osalError = OMX_ErrorNone;
  16.     OMX_ERRORTYPE eError = OMX_ErrorNone;
  17.     status_t ret = NO_ERROR;

  18.     mLocalVersionParam.s.nVersionMajor = 0x1;
  19.     mLocalVersionParam.s.nVersionMinor = 0x1;
  20.     mLocalVersionParam.s.nRevision = 0x0 ;
  21.     mLocalVersionParam.s.nStep = 0x0;

  22.     mPending3Asettings = 0;//E3AsettingsAll;
  23.     mPendingCaptureSettings = 0;
  24.     mPendingPreviewSettings = 0;

  25.     if ( 0 != mInitSem.Count() )
  26.         {
  27.         CAMHAL_LOGEB("Error mInitSem semaphore count %d", mInitSem.Count());
  28.         LOG_FUNCTION_NAME_EXIT;
  29.         return NO_INIT;
  30.         }

  31.     ///Update the preview and image capture port indexes
  32.     mCameraAdapterParameters.mPrevPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_PREVIEW;
  33.     // temp changed in order to build OMX_CAMERA_PORT_VIDEO_OUT_IMAGE;
  34.     mCameraAdapterParameters.mImagePortIndex = OMX_CAMERA_PORT_IMAGE_OUT_IMAGE;
  35.     mCameraAdapterParameters.mMeasurementPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT;
  36.     //currently not supported use preview port instead
  37.     mCameraAdapterParameters.mVideoPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_VIDEO;
  38.     mCameraAdapterParameters.mVideoInPortIndex = OMX_CAMERA_PORT_VIDEO_IN_VIDEO;
  39.     // 1.OMX_Init
  40.     eError = OMX_Init();
  41.     if (eError != OMX_ErrorNone) {
  42.         CAMHAL_LOGEB("OMX_Init() failed, error: 0x%x", eError);
  43.         return ErrorUtils::omxToAndroidError(eError);
  44.     }
  45.     mOmxInitialized = true;

  46.     // 2.Initialize the callback handles
  47.     OMX_CALLBACKTYPE callbacks;
  48.     callbacks.EventHandler = android::OMXCameraAdapterEventHandler;
  49.     callbacks.EmptyBufferDone = android::OMXCameraAdapterEmptyBufferDone;
  50.     callbacks.FillBufferDone = android::OMXCameraAdapterFillBufferDone;

  51.     // 3.Get the handle to the OMX Component
  52.     eError = OMXCameraAdapter::OMXCameraGetHandle(&mCameraAdapterParameters.mHandleComp, this, callbacks);
  53.     if(eError != OMX_ErrorNone) {
  54.         CAMHAL_LOGEB("OMX_GetHandle -0x%x", eError);
  55.     }
  56.     GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);

  57.     // 4.设置component的初始状态
  58.     mComponentState = OMX_StateLoaded;

  59.     CAMHAL_LOGVB("OMX_GetHandle -0x%x sensor_index = %lu", eError, mSensorIndex);
  60.     initDccFileDataSave(&mCameraAdapterParameters.mHandleComp, mCameraAdapterParameters.mPrevPortIndex);

  61.     // 5.disable所以的component
  62.     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
  63.                                   OMX_CommandPortDisable,
  64.                                   OMX_ALL,
  65.                                   NULL);

  66.     if(eError != OMX_ErrorNone) {
  67.          CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortDisable) -0x%x", eError);
  68.     }
  69.     GOTO_EXIT_IF((eError != OMX_ErrorNone), eError);

  70.     // 6.Register for port enable event
  71.     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
  72.                                  OMX_EventCmdComplete,
  73.                                  OMX_CommandPortEnable,
  74.                                  mCameraAdapterParameters.mPrevPortIndex,
  75.                                  mInitSem);
  76.     if(ret != NO_ERROR) {
  77.          CAMHAL_LOGEB("Error in registering for event %d", ret);
  78.          goto EXIT;
  79.     }

  80.     // 7.Enable PREVIEW Port
  81.     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
  82.                                  OMX_CommandPortEnable,
  83.                                  mCameraAdapterParameters.mPrevPortIndex,
  84.                                  NULL);
  85.     if(eError != OMX_ErrorNone) {
  86.         CAMHAL_LOGEB("OMX_SendCommand(OMX_CommandPortEnable) -0x%x", eError);
  87.     }
  88.     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);

  89.     // 8.Wait for the port enable event to occur
  90.     ret = mInitSem.WaitTimeout(OMX_CMD_TIMEOUT);
  91.     if ( NO_ERROR == ret ) {
  92.          CAMHAL_LOGDA("-Port enable event arrived");
  93.     } else {
  94.          ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
  95.                             OMX_EventCmdComplete,
  96.                             OMX_CommandPortEnable,
  97.                             mCameraAdapterParameters.mPrevPortIndex,
  98.                             NULL);
  99.          CAMHAL_LOGEA("Timeout for enabling preview port expired!");
  100.          goto EXIT;
  101.      }

  102.     // 9.Select the sensor
  103.     OMX_CONFIG_SENSORSELECTTYPE sensorSelect;
  104.     OMX_INIT_STRUCT_PTR (&sensorSelect, OMX_CONFIG_SENSORSELECTTYPE);
  105.     sensorSelect.eSensor = (OMX_SENSORSELECT) mSensorIndex;
  106.     eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, ( OMX_INDEXTYPE ) OMX_TI_IndexConfigSensorSelect, &sensorSelect);
  107.     if ( OMX_ErrorNone != eError ) {
  108.         CAMHAL_LOGEB("Error while selecting the sensor index as %d - 0x%x", mSensorIndex, eError);
  109.         return BAD_VALUE;
  110.     } else {
  111.         CAMHAL_LOGDB("Sensor %d selected successfully", mSensorIndex);
  112.     }

  113. #ifdef CAMERAHAL_DEBUG

  114.     printComponentVersion(mCameraAdapterParameters.mHandleComp);

  115. #endif
  116.     // 10.初始化默认参数
  117.     mBracketingEnabled = false;
  118.     mZoomBracketingEnabled = false;
  119.     mBracketingBuffersQueuedCount = 0;
  120.     mBracketingRange = 1;
  121.     mLastBracetingBufferIdx = 0;
  122.     mBracketingBuffersQueued = NULL;
  123.     mOMXStateSwitch = false;
  124.     mBracketingSet = false;
  125. #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING
  126.     mRawCapture = false;
  127.     mYuvCapture = false;
  128. #endif

  129.     mCaptureSignalled = false;
  130.     mCaptureConfigured = false;
  131.     mReprocConfigured = false;
  132.     mRecording = false;
  133.     mWaitingForSnapshot = false;
  134.     mPictureFormatFromClient = NULL;

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

  164.     mEXIFData.mGPSData.mAltitudeValid = false;
  165.     mEXIFData.mGPSData.mDatestampValid = false;
  166.     mEXIFData.mGPSData.mLatValid = false;
  167.     mEXIFData.mGPSData.mLongValid = false;
  168.     mEXIFData.mGPSData.mMapDatumValid = false;
  169.     mEXIFData.mGPSData.mProcMethodValid = false;
  170.     mEXIFData.mGPSData.mVersionIdValid = false;
  171.     mEXIFData.mGPSData.mTimeStampValid = false;
  172.     mEXIFData.mModelValid = false;
  173.     mEXIFData.mMakeValid = false;

  174.     //update the mDeviceOrientation with the sensor mount orientation.
  175.     //So that the face detect will work before onOrientationEvent()
  176.     //get triggered.
  177.     CAMHAL_ASSERT(mCapabilities);
  178.     mountOrientationString = mCapabilities->get(CameraProperties::ORIENTATION_INDEX);
  179.     CAMHAL_ASSERT(mountOrientationString);
  180.     mDeviceOrientation = atoi(mountOrientationString);

  181.     if (mSensorIndex != 2) {
  182.         mCapabilities->setMode(MODE_HIGH_SPEED);
  183.     }

  184.     if (mCapabilities->get(CameraProperties::SUPPORTED_ZOOM_STAGES) != NULL) {
  185.         mMaxZoomSupported = mCapabilities->getInt(CameraProperties::SUPPORTED_ZOOM_STAGES) + 1;
  186.     } else {
  187.         mMaxZoomSupported = 1;
  188.     }

  189.     // 11.initialize command handling thread
  190.     if(mCommandHandler.get() == NULL)
  191.         mCommandHandler = new CommandHandler(this);

  192.     if ( NULL == mCommandHandler.get() )
  193.     {
  194.         CAMHAL_LOGEA("Couldn't create command handler");
  195.         return NO_MEMORY;
  196.     }

  197.     ret = mCommandHandler->run("CallbackThread", PRIORITY_URGENT_DISPLAY);
  198.     if ( ret != NO_ERROR )
  199.     {
  200.         if( ret == INVALID_OPERATION){
  201.             CAMHAL_LOGDA("command handler thread already runnning!!");
  202.             ret = NO_ERROR;
  203.         } else {
  204.             CAMHAL_LOGEA("Couldn't run command handlerthread");
  205.             return ret;
  206.         }
  207.     }

  208.     // 12.initialize omx callback handling thread
  209.     if(mOMXCallbackHandler.get() == NULL)
  210.         mOMXCallbackHandler = new OMXCallbackHandler(this);

  211.     if ( NULL == mOMXCallbackHandler.get() )
  212.     {
  213.         CAMHAL_LOGEA("Couldn't create omx callback handler");
  214.         return NO_MEMORY;
  215.     }

  216.     ret = mOMXCallbackHandler->run("OMXCallbackThread", PRIORITY_URGENT_DISPLAY);
  217.     if ( ret != NO_ERROR )
  218.     {
  219.         if( ret == INVALID_OPERATION){
  220.             CAMHAL_LOGDA("omx callback handler thread already runnning!!");
  221.             ret = NO_ERROR;
  222.         } else {
  223.             CAMHAL_LOGEA("Couldn't run omx callback handler thread");
  224.             return ret;
  225.         }
  226.     }

  227.     OMX_INIT_STRUCT_PTR (&mRegionPriority, OMX_TI_CONFIG_3A_REGION_PRIORITY);
  228.     OMX_INIT_STRUCT_PTR (&mFacePriority, OMX_TI_CONFIG_3A_FACE_PRIORITY);
  229.     mRegionPriority.nPortIndex = OMX_ALL;
  230.     mFacePriority.nPortIndex = OMX_ALL;

  231.     //Setting this flag will that the first setParameter call will apply all 3A settings
  232.     //and will not conditionally apply based on current values.
  233.     mFirstTimeInit = true;

  234.     //Flag to avoid calling setVFramerate() before OMX_SetParameter(OMX_IndexParamPortDefinition)
  235.     //Ducati will return an error otherwise.
  236.     mSetFormatDone = false;

  237.     memset(mExposureBracketingValues, 0, EXP_BRACKET_RANGE*sizeof(int));
  238.     memset(mZoomBracketingValues, 0, ZOOM_BRACKET_RANGE*sizeof(int));
  239.     mMeasurementEnabled = false;
  240.     mFaceDetectionRunning = false;
  241.     mFaceDetectionPaused = false;
  242.     mFDSwitchAlgoPriority = false;

  243.     memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex], 0, sizeof(OMXCameraPortParameters));
  244.     memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex], 0, sizeof(OMXCameraPortParameters));
  245.     memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex], 0, sizeof(OMXCameraPortParameters));
  246.     memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex], 0, sizeof(OMXCameraPortParameters));

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

  264.     mParameters3A.ManualExposure = 0;
  265.     mParameters3A.ManualExposureRight = 0;
  266.     mParameters3A.ManualGain = 0;
  267.     mParameters3A.ManualGainRight = 0;

  268.     mParameters3A.AlgoFixedGamma = OMX_TRUE;
  269.     mParameters3A.AlgoNSF1 = OMX_TRUE;
  270.     mParameters3A.AlgoNSF2 = OMX_TRUE;
  271.     mParameters3A.AlgoSharpening = OMX_TRUE;
  272.     mParameters3A.AlgoThreeLinColorMap = OMX_TRUE;
  273.     mParameters3A.AlgoGIC = OMX_TRUE;

  274.     LOG_FUNCTION_NAME_EXIT;
  275.     return ErrorUtils::omxToAndroidError(eError);

  276.     EXIT:

  277.     CAMHAL_LOGDB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
  278.     performCleanupAfterError();
  279.     LOG_FUNCTION_NAME_EXIT;
  280.     return ErrorUtils::omxToAndroidError(eError);
  281. }
这里就是针对上面的这个过程进行全面分析,上面已经很清楚的标出了每一步,下面开始进入正题,唉,这个第二遍写这篇文章了,不知道怎么回事,之前写完了发布了,然后提示要审核,后来就再也没有消息了,我辛辛苦苦写好的文章啊!就这样没了,心痛,一直把这里当做学习的记事本,把自己的技术思路总结出来,希望ChinaUnix改进吧,越做越好!!
现在开始正文:

// 1.OMX_Init
这里从字面就可以知道这个方法到底是干什么的,看看TI给他的说明吧
  1. /** The OMX_Init method is used to initialize the OMX core. It shall be the
  2.     first call made into OMX and it should only be executed one time without
  3.     an interviening OMX_Deinit call.
  4.     
  5.     The core should return from this call within 20 msec.

  6.     @return OMX_ERRORTYPE
  7.         If the command successfully executes, the return code will be
  8.         OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
  9.     @ingroup core
  10.  */
  11. OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);
上面说的很清楚,这个方法用来initialize OMX core,只能调用一次除非使用过了OMX_Diniit


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

  1. typedef struct OMX_CALLBACKTYPE
  2. {
  3.     /** The EventHandler method is used to notify the application when an
  4.         event of interest occurs. Events are defined in the OMX_EVENTTYPE
  5.         enumeration. Please see that enumeration for details of what will
  6.         be returned for each type of event. Callbacks should not return
  7.         an error to the component, so if an error occurs, the application
  8.         shall handle it internally. This is a blocking call.

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

  11.         @param hComponent
  12.             handle of the component to access. This is the component
  13.             handle returned by the call to the GetHandle function.
  14.         @param pAppData
  15.             pointer to an application defined value that was provided in the
  16.             pAppData parameter to the OMX_GetHandle method for the component.
  17.             This application defined value is provided so that the application
  18.             can have a component specific context when receiving the callback.
  19.         @param eEvent
  20.             Event that the component wants to notify the application about.
  21.         @param nData1
  22.             nData will be the OMX_ERRORTYPE for an error event and will be
  23.             an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event.
  24.          @param nData2
  25.             nData2 will hold further information related to the event. Can be OMX_STATETYPE for
  26.             a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event.
  27.             Default value is 0 if not used. )
  28.         @param pEventData
  29.             Pointer to additional event-specific data (see spec for meaning).
  30.       */

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

  38.     /** The EmptyBufferDone method is used to return emptied buffers from an
  39.         input port back to the application for reuse. This is a blocking call
  40.         so the application should not attempt to refill the buffers during this
  41.         call, but should queue them and refill them in another thread. There
  42.         is no error return, so the application shall handle any errors generated
  43.         internally.
  44.         
  45.         The application should return from this call within 5 msec.
  46.         
  47.         @param hComponent
  48.             handle of the component to access. This is the component
  49.             handle returned by the call to the GetHandle function.
  50.         @param pAppData
  51.             pointer to an application defined value that was provided in the
  52.             pAppData parameter to the OMX_GetHandle method for the component.
  53.             This application defined value is provided so that the application
  54.             can have a component specific context when receiving the callback.
  55.         @param pBuffer
  56.             pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
  57.             or AllocateBuffer indicating the buffer that was emptied.
  58.         @ingroup buf
  59.      */
  60.     OMX_ERRORTYPE (*EmptyBufferDone)(
  61.         OMX_IN OMX_HANDLETYPE hComponent,
  62.         OMX_IN OMX_PTR pAppData,
  63.         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);

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

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

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


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

  1. OMX_ERRORTYPE OMXCameraAdapter::OMXCameraGetHandle(OMX_HANDLETYPE *handle, OMX_PTR pAppData,
  2.         const OMX_CALLBACKTYPE & callbacks)
  3. {
  4.     OMX_ERRORTYPE eError = OMX_ErrorUndefined;

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

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

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

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

  19.     *handle = 0;
  20.     return eError;
  21. }
上面直接调用接口中的方法获取handle

  1. /** The OMX_GetHandle method will locate the component specified by the
  2.     component name given, load that component into memory and then invoke
  3.     the component's methods to create an instance of the component.
  4.     
  5.     The core should return from this call within 20 msec.
  6.     
  7.     @param [out] pHandle
  8.         pointer to an OMX_HANDLETYPE pointer to be filled in by this method.
  9.     @param [in] cComponentName
  10.         pointer to a null terminated string with the component name. The
  11.         names of the components are strings less than 127 bytes in length
  12.         plus the trailing null for a maximum size of 128 bytes. An example
  13.         of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are
  14.         assigned by the vendor, but shall start with "OMX." and then have
  15.         the Vendor designation next.
  16.     @param [in] pAppData
  17.         pointer to an application defined value that will be returned
  18.         during callbacks so that the application can identify the source
  19.         of the callback.
  20.     @param [in] pCallBacks
  21.         pointer to a OMX_CALLBACKTYPE structure that will be passed to the
  22.         component to initialize it with.
  23.     @return OMX_ERRORTYPE
  24.         If the command successfully executes, the return code will be
  25.         OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
  26.     @ingroup core
  27.  */
  28. OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
  29.     OMX_OUT OMX_HANDLETYPE* pHandle,
  30.     OMX_IN OMX_STRING cComponentName,
  31.     OMX_IN OMX_PTR pAppData,
  32.     OMX_IN OMX_CALLBACKTYPE* pCallBacks);
自己看注释吧


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


// 5.disable所有的component
这里调用了一个方法是我们关注的重点,调用这个方法实现的功能其实已经说的很清楚了,不就是disable 所有组件吗
但是这个还是很有必要分析一下这个OMX_SendCommand的,算了还是看注释吧,之前我也只是翻译总结一下而已

  1. /** Send a command to the component. This call is a non-blocking call.
  2.     The component should check the parameters and then queue the command
  3.     to the component thread to be executed. The component thread shall
  4.     send the EventHandler() callback at the conclusion of the command.
  5.     This macro will go directly from the application to the component (via
  6.     a core macro). The component will return from this call within 5 msec.
  7.     
  8.     When the command is "OMX_CommandStateSet" the component will queue a
  9.     state transition to the new state idenfied in nParam.
  10.     
  11.     When the command is "OMX_CommandFlush", to flush a port's buffer queues,
  12.     the command will force the component to return all buffers NOT CURRENTLY
  13.     BEING PROCESSED to the application, in the order in which the buffers
  14.     were received.
  15.     
  16.     When the command is "OMX_CommandPortDisable" or
  17.     "OMX_CommandPortEnable", the component's port (given by the value of
  18.     nParam) will be stopped or restarted.
  19.     
  20.     When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the
  21.     pCmdData will point to a OMX_MARKTYPE structure containing the component
  22.     handle of the component to examine the buffer chain for the mark. nParam1
  23.     contains the index of the port on which the buffer mark is applied.

  24.     Specification text for more details.
  25.     
  26.     @param [in] hComponent
  27.         handle of component to execute the command
  28.     @param [in] Cmd
  29.         Command for the component to execute
  30.     @param [in] nParam
  31.         Parameter for the command to be executed. When Cmd has the value
  32.         OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has
  33.         the value OMX_CommandFlush, value of nParam indicates which port(s)
  34.         to flush. -1 is used to flush all ports a single port index will
  35.         only flush that port. When Cmd has the value "OMX_CommandPortDisable"
  36.         or "OMX_CommandPortEnable", the component's port is given by
  37.         the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer"
  38.         the components pot is given by the value of nParam.
  39.     @param [in] pCmdData
  40.         Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value
  41.         "OMX_CommandMarkBuffer".
  42.     @return OMX_ERRORTYPE
  43.         If the command successfully executes, the return code will be
  44.         OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
  45.     @ingroup comp
  46.  */
  47. #define OMX_SendCommand( \
  48.          hComponent, \
  49.          Cmd, \
  50.          nParam, \
  51.          pCmdData) \
  52.      ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \
  53.          hComponent, \
  54.          Cmd, \
  55.          nParam, \
  56.          pCmdData) /* Macro End */

// 6.Register for port enable event
这里还是坚持说一下吧

RegisterForEvent(mCameraAdapterParameters.mHandleComp,
                                 OMX_EventCmdComplete,
                                 OMX_CommandPortEnable,
                                 mCameraAdapterParameters.mPrevPortIndex,
                                 mInitSem);

上面的这几个传入的参数还是先有个印象吧,之后要有用的

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

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

  27.     LOG_FUNCTION_NAME_EXIT;

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

// 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



待填充内容。。。。。。















阅读(1496) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~