]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/omapdrmtest.git/blob - omx_cam/OMXVisionCam.cpp
omx cam: add test app
[glsdk/omapdrmtest.git] / omx_cam / OMXVisionCam.cpp
1 /* Copyright (C) 2010 Texas Instruments, Inc. All rights reserved. */
3 #include <autolock.h>
4 #include <output.h>
5 #include <OMXVisionCam.h>
7 #undef VCAM_SET_FORMAT_ROTATION
8 #define USE_WB_GAIN_PATCH // enable the hardcoded WB gain get/set apis
10 #ifdef USE_WB_GAIN_PATCH
11     #include "OMXVisionCam_WB_patch.h"
12 #endif
14 //#define _USE_GAMMA_RESET_HC_ // enable the hard coded reset system for gamma tables
16 #include "OMXVisionCam_Gamma_Tbl.h"
18 #define HERE {printf("=======> OMX - %d <=======", __LINE__);fflush(stdout);}
20 #ifdef USE_WB_GAIN_PATCH
21     #define RED 0
22     #define GREEN_RED 1
23     #define GREEN_BLUE 2
24     #define BLUE 3
26     #define CALCULATE_WB_GAINS_OFFSET(type,in,out) out = (type *)(in + 4 + in[4] + in[8])
27 #endif // USE_WB_GAIN_PATCH
29 #define GAMMA_TABLE_SIZE 1024*sizeof(uint16_t)
31 #define OMX_CHECK(error, function)  {\
32     error = function;\
33     if (error != OMX_ErrorNone) {\
34         ERROR("OMX Error 0x%08x in "#function" on line # %u", error, __LINE__);\
35     }\
36 }
38 #define OMX_CONVERT_RETURN_IF_ERROR(error, function) {\
39     error = function;\
40     if (error != OMX_ErrorNone) {\
41         ERROR("OMX Error 0x%08x in "#function" on line # %u", error, __LINE__);\
42         return ConvertError(error);\
43     }\
44 }
46 #define OMX_STRUCT_INIT(str, type, pVersion)  {\
47     memset(&str, 0, sizeof(type));\
48     str.nSize = sizeof(type);\
49     memcpy(&str.nVersion, pVersion, sizeof(OMX_VERSIONTYPE));\
50     str.nPortIndex = OMX_ALL;\
51 }
53 #define OMX_STRUCT_INIT_PTR(ptr, type, pVersion) {\
54     memset(ptr, 0, sizeof(type));\
55     ptr->nSize = sizeof(type);\
56     memcpy(&ptr->nVersion, pVersion, sizeof(OMX_VERSIONTYPE));\
57     ptr->nPortIndex = OMX_ALL;\
58 }
60 #define LOOP_PORTS( port, cnt ) \
61         for(    cnt = ( VCAM_PORT_ALL == port ? VCAM_PORT_PREVIEW : port ); \
62                 cnt < ( VCAM_PORT_ALL == port ? VCAM_PORT_MAX : port + 1 ); \
63                 cnt++ \
64             )
66 void* FocusThreadLauncher(void *arg)
67 {
68     OMXVisionCam *pCam = reinterpret_cast<OMXVisionCam *>(arg);
69     pCam->waitForFocus();
70     return 0;
71 }
73 void* PreemptionThreadLauncher( void *arg )
74 {
75     OMXVisionCam *pCam = reinterpret_cast<OMXVisionCam *>(arg);
76     pCam->PreemptionService();
77     return 0;
78 }
80 void* FrameThreadFunc(void* user) {
81   OMXVisionCam* pCam = static_cast<OMXVisionCam*>(user);
82   OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader;
83   do {
84     if (pCam->mFrameCbData.frames.empty()){
85       pthread_mutex_lock(&pCam->mFrameCbData.mutex);
86     } else {
87       pBuffHeader = pCam->mFrameCbData.frames.front();
88       pCam->mFrameCbData.frames.pop_front();
89       if (pBuffHeader != NULL) {
90         pCam->frameReceivedSrvc(pBuffHeader);
91       }
92     }
93   } while (pBuffHeader != NULL);
95   return NULL;
96 }
98 static void PrintOMXState(OMX_STATETYPE state)
99 {
100     const char *state_names[] = {
101         "OMX_StateInvalid",
102         "OMX_StateLoaded",
103         "OMX_StateIdle",
104         "OMX_StateExecuting",
105         "OMX_StatePause",
106         "OMX_StateWaitForResources"
107     };
108     if (state < (sizeof(state_names) / sizeof(const char*))) {
109         MSG("OMX-CAMERA is in state %s", state_names[state]);
110     }
113 OMX_U32 frameRates[] = {1, 5, 15, 24, 30, 60};
116 /* Constructor - Open the Shared Library, containing the Camera Adapter and
117 * gen an instance of the Adapter.
118 */
119 OMXVisionCam::OMXVisionCam()
121     m_callback = NULL;
122     m_focuscallback = NULL;
123     pthread_mutex_init(&mFrameBufferLock, NULL);
124     pthread_mutex_init(&mUserRequestLock, NULL);
125     memset(&mCurGreContext, 0, sizeof(mCurGreContext));
128 int OMXVisionCam::init(void *cookie)
130     mFlushInProcess = false;
131     OMX_ERRORTYPE omxError = OMX_ErrorNone;
132     int greError = 0;
134 #if TIME_PROFILE
135     PopulateTimeProfiler();
136 #endif // TIME_PROFILE
138     MSG("OMXVisionCam::OMXVisionCam");
139     MSG("OMXVisionCam compiled: %s, %s", __DATE__, __TIME__ );
140     mLocalVersion = new OMX_VERSIONTYPE();
141     m_callback = NULL;
142     m_focuscallback = NULL;
144     m_cookie = cookie; // save the cookie value;
146     mLocalVersion->s.nVersionMajor = 1;
147     mLocalVersion->s.nVersionMinor = 1;
148     mLocalVersion->s.nRevision = 0 ;
149     mLocalVersion->s.nStep =  0;
151     sem_init(&mGreLocalSem, 0, 1); // set the max count
152     sem_wait(&mGreLocalSem); // pre-decrement the current count otherwise the first wait will pass early
153     sem_init(&mGreFocusSem, 0, 1); // set the max count
154     sem_wait(&mGreFocusSem); // pre-decrement the current count otherwise the first wait will pass early
156     // Initialize the Vision Core
157     MSG("Calling OMX_Init()");
158     OMX_CONVERT_RETURN_IF_ERROR(omxError, OMX_Init());
160     OMX_CALLBACKTYPE omxCallbacks;
161     omxCallbacks.EventHandler    = OMXVisionCam::EventHandler;
162     omxCallbacks.EmptyBufferDone = OMXVisionCam::EmptyBufferDone;
163     omxCallbacks.FillBufferDone  = OMXVisionCam::FillBufferDone;
165     memset( &(mCurGreContext), 0, sizeof( VCAM_ComponentContext ) );
167     mCurGreContext.mPortsInUse[VCAM_PORT_ALL] = OMX_ALL;
168     mCurGreContext.mPortsInUse[VCAM_PORT_PREVIEW] = VCAM_CAMERA_PORT_VIDEO_OUT_PREVIEW;
169     mCurGreContext.mPortsInUse[VCAM_PORT_VIDEO]   = VCAM_CAMERA_PORT_VIDEO_OUT_VIDEO;
171     for( int i = VCAM_PORT_PREVIEW; i < VCAM_PORT_MAX; i++ )
172     {
173         mBuffersInUse[i].mBuffers = NULL;
174         mBuffersInUse[i].mNumberBuffers = 0;
175         mCurGreContext.mCameraPortParams[i].mColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
176         mCurGreContext.mCameraPortParams[i].mWidth = QVGA_WIDTH;
177         mCurGreContext.mCameraPortParams[i].mHeight = QVGA_HEIGHT;
178         mCurGreContext.mCameraPortParams[i].mFrameRate = INITIAL_FRAMERATE;
179         for(uint32_t buf = 0; buf < VCAM_NUM_BUFFERS; buf++ )
180             mCurGreContext.mCameraPortParams[i].mBufferHeader[buf] = NULL;
181         mFrameDescriptors[i] = NULL;
182     }
184     mCurGreContext.mHandleComp = NULL;
186     MSG("Calling OMX_GetHandle()");
187     OMX_CONVERT_RETURN_IF_ERROR(omxError,OMX_GetHandle(&( mCurGreContext.mHandleComp ),
188                                          (OMX_STRING)"OMX.TI.DUCATI1.VIDEO.CAMERA",
189                                          this ,
190                                          &omxCallbacks));
191     GetDucatiVersion();
193     OMX_CONVERT_RETURN_IF_ERROR(omxError,OMX_SendCommand(mCurGreContext.mHandleComp,
194                                                          OMX_CommandPortDisable,
195                                                          OMX_ALL,
196                                                          NULL));
199 // #if defined(BLAZE) || defined(SDP) || defined(BLAZE_TABLET)
200     {
201         OMX_U32 pr = 4;
203         memcpy( &mVisionCamPriority.nVersion, mLocalVersion, sizeof(OMX_VERSIONTYPE));
204         mVisionCamPriority.nGroupID = CAMERA_GROUP_ID;
205         mVisionCamPriority.nGroupPriority = pr;
206         mVisionCamPriority.nSize = sizeof(OMX_PRIORITYMGMTTYPE);
208         omxError = OMX_SetParameter(mCurGreContext.mHandleComp, OMX_IndexParamPriorityMgmt ,&mVisionCamPriority);
209     }
210 // #else
211 //     ERROR("No Priority Management is enabled on this platform!");
212 // #endif
214     pthread_mutex_lock(&mFrameCbData.mutex);
215     pthread_create(&mFrameThread, NULL, FrameThreadFunc, this);
216     mUseFramePackaging = false;
218     m_frameNum = 0;
219     mPreemptionState = VCAM_PREEMPT_INACTIVE;
220     mFaceDetectionEnabled = false;
221     mReturnToExecuting = false;
222 #ifdef _USE_GAMMA_RESET_HC_
223     mGammaResetPolulated = false;
224 #endif // _USE_GAMMA_RESET_HC_
226     return greError;
229 int OMXVisionCam::deinit()
231     int greError = 0;
232     OMX_ERRORTYPE omxError = OMX_ErrorNone;
234     // Free the handle for the Camera component
235     if (mCurGreContext.mHandleComp)
236     {
237         // free the handle
238         MSG("Calling OMX_FreeHandle(0x%08x)", (unsigned)(mCurGreContext.mHandleComp));
239         omxError = OMX_FreeHandle(mCurGreContext.mHandleComp);
240         greError = ConvertError(omxError);
241         mCurGreContext.mHandleComp = 0;
242         if( 0 != greError )
243         {
244             ERROR("ERROR: error freeing OMX handle.OMX_FreeHandle() returned 0x%x", omxError);
245         }
247         // Deinitialize the OMX Core
248         MSG("Calling OMX_Deinit()");
249         omxError = OMX_Deinit();
250         greError = ConvertError(omxError);
251         if( 0 != greError )
252         {
253             ERROR("ERROR: error in OMX_Deinit.OMX err: 0x%x", omxError);
254         }
255     }
257     mFrameCbData.frames.push_back(NULL);
258     pthread_mutex_unlock(&mFrameCbData.mutex);
259     pthread_join(mFrameThread, NULL);
261 #if TIME_PROFILE
262     for(int i = 0; i < VCAM_TIME_TARGET_MAX; i++)
263         if( mTimeProfiler[i] )      // dump and clear
264             delete mTimeProfiler[i];
265 #endif
267     delete mLocalVersion;
269     sem_destroy(&mGreLocalSem);
270     sem_destroy(&mGreFocusSem);
272     return greError;
275 /* Destructor - free all recources used by Vision Cam and from us */
276 OMXVisionCam::~OMXVisionCam()
278     pthread_mutex_destroy(&mFrameBufferLock);
279     pthread_mutex_destroy(&mUserRequestLock);
280     MSG("OMX Vision Cam is destroyed!");
283 /**
284 * This is used to get esier the state of component.
285 */
286 inline OMX_STATETYPE OMXVisionCam::getComponentState()
288     OMX_STATETYPE state = OMX_StateInvalid;
290     if( mCurGreContext.mHandleComp )
291     {
292         OMX_GetState( mCurGreContext.mHandleComp, &state );
293     }
294     PrintOMXState(state);
295     return state;
298 /**
299 * Initialisation of OMX_PARAM_PORTDEFINITIONTYPE
300 * needed for various configurations
301 */
302 inline OMX_ERRORTYPE OMXVisionCam::initPortCheck( OMX_PARAM_PORTDEFINITIONTYPE * portCheck , OMX_U32 portIndex )
304     OMX_ERRORTYPE omxError = OMX_ErrorNone;
305     OMX_STRUCT_INIT_PTR(portCheck, OMX_PARAM_PORTDEFINITIONTYPE, mLocalVersion)
307     if( VCAM_PORT_ALL < portIndex && VCAM_PORT_MAX > portIndex )
308     {
309         portCheck->nPortIndex = mCurGreContext.mPortsInUse[portIndex];
310         omxError = OMX_GetParameter(mCurGreContext.mHandleComp,
311                                     OMX_IndexParamPortDefinition,
312                                     portCheck);
313         MSG("PORT CHECK[%u], E:%d P:%d B#:%u %ux%u C:%d",
314                   (uint32_t)portCheck->nPortIndex,
315                   portCheck->bEnabled,
316                   portCheck->bPopulated,
317                   (uint32_t)portCheck->nBufferCountActual,
318                   (uint32_t)portCheck->format.video.nFrameWidth,
319                   (uint32_t)portCheck->format.video.nFrameHeight,
320                   portCheck->format.video.eColorFormat);
322     }
323     else
324         omxError = OMX_ErrorBadParameter;
326     if( omxError != OMX_ErrorNone )
327     {
328         ERROR("OMX_GetParameter - 0x%x in initPortCheck(%lu)",
329                   omxError, mCurGreContext.mPortsInUse[portIndex]);
330     }
331     return omxError;
333 /**
334    @brief Method to convert from OMX_ERRORTYPE to GesturError_e
335    @param error Any of the standard OMX error codes defined in the OpenMAX 1.x Specification.
336    @return int
337  */
338 int OMXVisionCam::ConvertError(OMX_ERRORTYPE error)
340     int status = 0;
341     switch(error)
342     {
343         case OMX_ErrorNone:
344             status = 0;
345             break;
346         case OMX_ErrorBadParameter:
347             status = -EINVAL;
348             break;
349         case OMX_ErrorIncorrectStateOperation:
350             status = -EBADE;
351             break;
352         case OMX_ErrorHardware:
353             status = -EIO;
354             break;
355         default:
356             status = -ESTALE; /* Something stupid */
357             break;
358     }
359     if (error != OMX_ErrorNone) {
360         ERROR("Converting OMX Error 0x%08x to int %d", error, status);
361     }
362     return status;
365 int OMXVisionCam::getLutValue( int searchVal, ValueTypeOrigin origin, const int lut[][2], int lutSize)
367     int idxToGet = (origin == VCAM_VALUE_TYPE ? OMX_VALUE_TYPE : VCAM_VALUE_TYPE );
368     for( int i = 0; i < lutSize; i++ )
369     {
370         if( lut[i][origin] == searchVal )
371             return lut[i][idxToGet];
372     }
374     return -EINVAL;
377 void OMXVisionCam::GetDucatiVersion()
379     if( mCurGreContext.mHandleComp )
380     {
381         OMX_VERSIONTYPE compVersion;
382         OMX_VERSIONTYPE specVersion;
383         char compName[128];
384         OMX_UUIDTYPE compUUID[128];
385         OMX_ERRORTYPE omxError = OMX_ErrorNone;
386         MSG("Querying Component Version!");
387         omxError = OMX_GetComponentVersion(mCurGreContext.mHandleComp,
388                                            compName,
389                                            &compVersion,
390                                            &specVersion,
391                                            compUUID);
392         if (omxError == OMX_ErrorNone)
393         {
394             MSG("\tComponent Name:    [%s]",   compName);
395             MSG("\tComponent Version: [%u]",   (unsigned int)compVersion.nVersion);
396             MSG("\tSpec Version:      [%u]",   (unsigned int)specVersion.nVersion);
397             MSG("\tComponent UUID:    [%s]", (char*)compUUID);
398         }
399     }
402 int OMXVisionCam::transitToState(OMX_STATETYPE targetState, serviceFunc transitionService, void * data )
404     int greError = 0;
405     OMX_ERRORTYPE omxError = OMX_ErrorNone;
406     sem_t sem; // this semaphore does not need to be global
408     if( OMX_StateInvalid == targetState )
409         return -EINVAL;
411     sem_init(&sem, 0, 1);
412     sem_wait(&sem); // predecrement so that the later wait will actually block
414     omxError = RegisterForEvent( mCurGreContext.mHandleComp,
415                                     OMX_EventCmdComplete,
416                                     OMX_CommandStateSet,
417                                     targetState,
418                                     &sem,
419                                     -1 // Infinite timeout
420                                 );
422     if( OMX_ErrorNone == omxError )
423     {
424         omxError = OMX_SendCommand( mCurGreContext.mHandleComp ,
425                                                    OMX_CommandStateSet,
426                                                    targetState,
427                                                    NULL );
428         switch( omxError )
429         {
430             case OMX_ErrorNone:
431             {
432                 if( transitionService )
433                 {
434                     greError = transitionService( this, data );
435                 }
436                 break;
437             }
439             case OMX_ErrorIncorrectStateTransition:
440             {
441                 greError = -EINVAL;
442                 break;
443             }
445             case OMX_ErrorInsufficientResources:
446             {
447                 if( OMX_StateIdle == targetState )
448                 {
449                     mPreemptionState = VCAM_PREEMPT_WAIT_TO_START;
450                     greError = PreemptionService();
451                 }
452                 break;
453             }
455             case OMX_ErrorSameState:
456                 break;
458             default:
459                 greError = ConvertError(omxError);
460                 break;
461         }
463         if( greError != 0 || OMX_ErrorSameState == omxError )
464         {
465             // unregister the event
466             EventHandler( mCurGreContext.mHandleComp,
467                           this,
468                           (OMX_EVENTTYPE)OMX_EventCmdComplete,
469                           (OMX_U32)OMX_CommandStateSet,
470                           (OMX_U32)targetState,
471                           NULL
472                         );
473         }
474         else //( 0 == greError )
475         {
476             MSG("Waiting for state transition. State requested: %d", (int)targetState);
477             sem_wait(&sem);
478             MSG("Camera is now in state %d", (int)targetState);
479         }
480     }
482     sem_destroy(&sem);
484     return greError;
487 int OMXVisionCam::portEnableDisable( OMX_COMMANDTYPE enCmd, serviceFunc enablementService, VisionCamPort_e port )
489     int greError = 0;
490     OMX_ERRORTYPE omxError = OMX_ErrorNone;
492     OMX_PARAM_PORTDEFINITIONTYPE portCheck;
493     VCAM_PortParameters * portData = NULL;
495     mCurGreContext.mCameraPortParams[VCAM_PORT_ALL].mIsActive = true;
497     int32_t p;
498     LOOP_PORTS( port , p )
499     {
500         initPortCheck(&portCheck, p);
501         portData = &mCurGreContext.mCameraPortParams[p];
503         // check to see if the port is already enabled/disabled and that we wanted that state
504         if( (OMX_TRUE == portCheck.bEnabled) && (enCmd == OMX_CommandPortEnable) )
505         {
506             portData->mIsActive = true;
507             continue;
508         }
510         if( (OMX_FALSE == portCheck.bEnabled) && (enCmd == OMX_CommandPortDisable) )
511         {
512             portData->mIsActive = false;
513             continue;
514         }
516         // we wanted to transition from one state to the other
518         // ports with no buffers can't be enabled or disabled.
519         if( portData->mNumBufs == 0 )
520             continue;
522         // we have buffers, so enable/disable the port!
523         MSG("Registering for port enable/disable event");
524         omxError = RegisterForEvent(    mCurGreContext.mHandleComp,
525                                         OMX_EventCmdComplete,
526                                         enCmd,
527                                         mCurGreContext.mPortsInUse[p],
528                                         &mGreLocalSem,
529                                         -1 /*Infinite timeout */
530                                     );
532         if( OMX_ErrorNone == omxError )
533         {
534             omxError = OMX_SendCommand( mCurGreContext.mHandleComp,
535                                         enCmd,
536                                         mCurGreContext.mPortsInUse[p],
537                                         NULL
538                                         );
539         }
541         if( enablementService && OMX_ErrorNone == omxError )
542         {
543             greError = enablementService( this, (void*)(&p) );
544         }
546         if( OMX_ErrorNone == omxError && 0 == greError )
547         {
548             sem_wait(&mGreLocalSem);
549         }
550         else
551         {
552             // unregister event
553             EventHandler( mCurGreContext.mHandleComp,
554                         this,
555                         (OMX_EVENTTYPE)OMX_EventCmdComplete,
556                         (OMX_U32)enCmd,
557                         (OMX_U32)mCurGreContext.mPortsInUse[p],
558                         NULL
559                         );
560         }
562         initPortCheck(&portCheck, p);
564         if( OMX_TRUE == portCheck.bEnabled )
565         {
566             portData->mIsActive = true;
567             mFramePackage.mExpectedFrames[p] = true;
568         }
569         else
570         {
571             portData->mIsActive = false;
572             mFramePackage.mExpectedFrames[p] = false;
573         }
574     }
576     mCurGreContext.mCameraPortParams[VCAM_PORT_ALL].mIsActive = true;
577     int32_t p2;
578     LOOP_PORTS(VCAM_PORT_ALL, p2)
579     {
580         if( mCurGreContext.mCameraPortParams[p2].mIsActive == false )
581         {
582             mCurGreContext.mCameraPortParams[VCAM_PORT_ALL].mIsActive = false;
583             break;
584         }
585     }
587     return greError;
590 int OMXVisionCam::fillPortBuffers( VisionCamPort_e port )
592     int greError = 0;
593     OMX_ERRORTYPE omxError = OMX_ErrorNone;
594     VCAM_PortParameters *portData = NULL;
596     portData = &mCurGreContext.mCameraPortParams[port];
597     if (portData->mIsActive == true) {
599         for( int index = 0; index < portData->mNumBufs; index++ )
600         {
601             if( portData && portData->mBufferHeader[index] )
602             {
603                 MSG("FILL BUFF HDR[%d]:%p PORT:%u", index, portData->mBufferHeader[index], (uint32_t)mCurGreContext.mPortsInUse[port]);
604                 omxError = OMX_FillThisBuffer(mCurGreContext.mHandleComp,
605                                               (OMX_BUFFERHEADERTYPE*)( portData->mBufferHeader[index]));
606                 if (omxError != OMX_ErrorNone)
607                 {
608                     ERROR("OMX_FillThisBuffer() returned error  0x%x", omxError );
609                     greError = ConvertError(omxError);
610                     break;
611                 }
612             }
613             else
614             {
615                 greError = -ENOMEM;
616             }
617         }
618     }
619     else
620     {
621         greError = -EBADE;
622     }
623     if (omxError != OMX_ErrorNone)
624     {
625         greError = ConvertError(omxError);
626     }
628     return greError;
631 int OMXVisionCam::freePortBuffers( VisionCamPort_e port )
633     int greError = 0;
634     OMX_ERRORTYPE omxError = OMX_ErrorNone;
635     VCAM_PortParameters *portData = NULL;
637     AutoLock lock(&mFrameBufferLock);
639     int32_t p;
640     LOOP_PORTS( port , p )
641     {
642         portData = &mCurGreContext.mCameraPortParams[p];
643         for( int buff = 0; buff < portData->mNumBufs; buff++ )
644         {
645             omxError = OMX_FreeBuffer( mCurGreContext.mHandleComp,
646                                         mCurGreContext.mPortsInUse[p],
647                                         portData->mBufferHeader[buff]
648                                       );
649             portData->mBufferHeader[buff] = NULL;
650             if (omxError != OMX_ErrorNone)
651             {
652                 ERROR("OMX_FreeBuffer() returned error  0x%x", omxError );
653                 greError = ConvertError(omxError);
654                 break;
655             }
656         }
657     }
659     return greError;
662 int OMXVisionCam::populatePort( VisionCamPort_e port )
664     int greError = 0;
665     OMX_ERRORTYPE omxError = OMX_ErrorNone;
666     VCAM_PortParameters * data = NULL;
668     int32_t p;
669     LOOP_PORTS( port , p )
670     {
671         OMX_TI_PARAM_USEBUFFERDESCRIPTOR desc;
672         OMX_STRUCT_INIT(desc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR, mLocalVersion);
673         // No idea
674         desc.nPortIndex = mCurGreContext.mPortsInUse[p];
675         // For 2D buffer
676         desc.bEnabled = OMX_FALSE;
677         omxError = OMX_SetParameter(mCurGreContext.mHandleComp, (OMX_INDEXTYPE) OMX_TI_IndexUseDmaBuffers, &desc);
678         MSG("Configuring port %u for DMAbuf handles (err=0x%08x)", p, omxError);
679         data = &mCurGreContext.mCameraPortParams[p];
681         for( int indBuff = 0; indBuff < data->mNumBufs; indBuff++ )
682         {
683             OMX_BUFFERHEADERTYPE *pBufferHdr;
684             OMX_U8 *buffer = NULL;
686             // Pass array of file descriptors
687             buffer = (OMX_U8*)mBuffersInUse[p].mBuffers[indBuff].fd;
688             MSG("VCAM: Using FDs %d and %d", ((int*) buffer)[0], ((int*) buffer)[1]);
689             omxError = OMX_UseBuffer( mCurGreContext.mHandleComp,
690                                         &pBufferHdr,
691                                         mCurGreContext.mPortsInUse[p],
692                                         0,
693                                         data->mBufSize,
694                                         buffer );
696             if( OMX_ErrorNone != omxError )
697             {
698                 ERROR("VCAM: ERROR: OMX_UseBuffer() returned 0x%x ( %d )", omxError, omxError);
699                 greError = ConvertError(omxError);
700                 break;
701             }
703             pBufferHdr->pAppPrivate = (OMX_PTR)&mBuffersInUse[p].mBuffers[indBuff];
704             MSG("pAppPrivate=%p mBuffers[indBuff]=%p", pBufferHdr->pAppPrivate, &mBuffersInUse[p].mBuffers[indBuff]);
705             pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
706             memcpy( &(pBufferHdr->nVersion), mLocalVersion, sizeof( OMX_VERSIONTYPE ) );
708             data->mBufferHeader[indBuff] = pBufferHdr;
710             if( NULL == mFrameDescriptors[p][indBuff]->mFrameBuff )
711                     mFrameDescriptors[p][indBuff]->mFrameBuff = pBufferHdr->pAppPrivate;
712         }
713     }
715     return greError;
718 int OMXVisionCam::useBuffers(BufferMeta* meta, uint32_t numImages, VisionCamPort_e port )
720     int greError = 0;
722     if ( numImages == 0  || port <= VCAM_PORT_ALL || port >= VCAM_PORT_MAX)
723     {
724         ERROR("Invalid parameters to useBuffers()");
725         return -EINVAL;
726     }
728     // alloc the array for frame descriptors
729     if( !mFrameDescriptors[port] )
730     {
731         mFrameDescriptors[port] = new VisionCamFrame* [numImages];
732         if( NULL == mFrameDescriptors[port] )
733         {
734             greError = -ENOMEM;
735         }
737         for( uint32_t i = 0; i < numImages && 0 == greError; i++ )
738         {
739             mFrameDescriptors[port][i] = new VisionCamFrame();
741             if( mFrameDescriptors[port][i] )
742             {
743                 mFrameDescriptors[port][i]->clear();
744             }
745             else
746             {
747                 while( i )
748                     delete mFrameDescriptors[port][--i];
750                 delete [] mFrameDescriptors[port];
751                 mFrameDescriptors[port] = NULL;
753                 greError = -ENOMEM;
754             }
755         }
756     }
758     if( 0 == greError )
759     {
760         VCAM_PortParameters * data = &mCurGreContext.mCameraPortParams[port];
762         mBuffersInUse[port].mBuffers = meta;
763         mBuffersInUse[port].mNumberBuffers = (unsigned)numImages;
765         data->mNumBufs = mBuffersInUse[port].mNumberBuffers;
766         data->mStride = mBuffersInUse[port].mBuffers[0].buffer->pitches[0];
768         if( OMX_StateIdle != getComponentState() )
769         {
770             greError = transitToState( OMX_StateIdle );
771         }
772     }
774     return greError;
777 int OMXVisionCam::flushBuffers( VisionCamPort_e port)
779     int greError = 0;
780     OMX_ERRORTYPE omxError = OMX_ErrorNone;
782     if( OMX_StateExecuting != getComponentState() )
783     {
784         return greError;
785     }
787     int32_t p;
788     LOOP_PORTS( port , p )
789     {
790         sem_t sem;
791         sem_init(&sem, 0, 1);
792         sem_wait(&sem); // predecrement so that the next wait won't fire ahead of time.
793         omxError = RegisterForEvent(mCurGreContext.mHandleComp,
794                                     OMX_EventCmdComplete,
795                                     OMX_CommandFlush,
796                                     mCurGreContext.mPortsInUse[p],
797                                     &sem,
798                                     -1 /*Infinite timeout*/
799                                     );
801         if( OMX_ErrorNone == omxError )
802         {
803             omxError = OMX_SendCommand( mCurGreContext.mHandleComp,
804                                         OMX_CommandFlush,
805                                         mCurGreContext.mPortsInUse[p],
806                                         NULL );
807         }
809         if( OMX_ErrorNone == omxError )
810         {
811             sem_wait(&sem);
812         }
814         sem_destroy(&sem);
815     }
816     return greError;
819 /* Send command to Camera */
820 int OMXVisionCam::sendCommand( VisionCamCmd_e cmdId, void *param, uint32_t size, VisionCamPort_e port)
822     int greError = 0;
823     OMX_ERRORTYPE omxError = OMX_ErrorNone;
825     AutoLock lock(&mUserRequestLock);
827     MSG("SEND CMD: 0x%04x, %p, %zu, %d", cmdId, param, size, port);
829     switch (cmdId)
830     {
831         case VCAM_CMD_PREVIEW_START:
832         {
833             greError = startPreview(port);
834             break;
835         }
837         case VCAM_CMD_PREVIEW_STOP:
838         {
839             if( OMX_StateExecuting == getComponentState() )
840                 greError = stopPreview(port);
841             else
842                 greError = -EBADE;
843             break;
844         }
846         case VCAM_EXTRA_DATA_START:
847         {
848             int i, EDataType;
849             for( i = 0; i < VCAM_EXTRA_DATA_TYPE_MAX; i++ )
850             {
851                 if( ExtraDataTypeLUT[ i ][ 0 ]  == *( (int*)param ) )
852                 {
853                     EDataType = ExtraDataTypeLUT[ i ][ 1 ];
854                     break;
855                 }
856             }
857             if( i == VCAM_EXTRA_DATA_TYPE_MAX )
858             {
859                 greError = -EINVAL;
860                 break;
861             }
863             OMX_CONFIG_EXTRADATATYPE xData;
864             OMX_STRUCT_INIT(xData, OMX_CONFIG_EXTRADATATYPE, mLocalVersion);
865 #if defined(TUNA) || defined(MAGURO)
866             xData.eCameraView       = OMX_2D_Prv;
867 #endif
868             if( OMX_ExtraDataNone == EDataType )
869             {
870               for( int i = 1; i < VCAM_EXTRA_DATA_TYPE_MAX; i++ )
871               {// stop extra data transfer for all types of data
872                   if( 0 == greError )
873                   {
874                     xData.eExtraDataType = (OMX_EXT_EXTRADATATYPE)ExtraDataTypeLUT[i][1];
875                     xData.bEnable = OMX_FALSE;
876                     int32_t p;
877                     LOOP_PORTS( port, p )
878                     {
879                         xData.nPortIndex = p;
880                         omxError = OMX_SetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
881                     }
882                   }
883               }
884             }
885             else
886             {
887                 if( 0 == greError )
888                 {
889                     xData.eExtraDataType = ( OMX_EXT_EXTRADATATYPE )EDataType;
890                     xData.bEnable = OMX_TRUE;
892                     omxError = OMX_SetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
893                 }
894             }
895             break;
896         }
898         case VCAM_EXTRA_DATA_STOP:
899         {
900             int i, EDataType;
901             for( i = 0; i < VCAM_EXTRA_DATA_TYPE_MAX; i++ )
902             {
903                 if( ExtraDataTypeLUT[ i ][ 0 ]  == *( (int*)param ) )
904                 {
905                     EDataType = ExtraDataTypeLUT[ i ][ 1 ];
906                     break;
907                 }
908             }
909             if( i == VCAM_EXTRA_DATA_TYPE_MAX )
910             {
911                 greError = -EINVAL;
912                 break;
913             }
915             OMX_CONFIG_EXTRADATATYPE xData;
916             OMX_STRUCT_INIT(xData, OMX_CONFIG_EXTRADATATYPE, mLocalVersion);
917 #if defined(TUNA) || defined(MAGURO)
918             xData.eCameraView       = OMX_2D_Prv;
919 #endif
920             if( OMX_ExtraDataNone == EDataType )
921             {
922                   for( int i = 1; i < VCAM_EXTRA_DATA_TYPE_MAX; i++ )
923                   {
924     //                   greError = OMX_GetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
925                       if( 0 == greError )
926                       {
927                           xData.eExtraDataType = (OMX_EXT_EXTRADATATYPE)ExtraDataTypeLUT[i][1];
928                           xData.bEnable = OMX_FALSE;
929                           int32_t p;
930                           LOOP_PORTS(port, p)
931                           {
932                                 xData.nPortIndex = p;
933                                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
934                           }
935                       }
936                   }
937             }
938             else
939             {
940                 if( 0 == greError )
941                 {
942                     xData.eExtraDataType = ( OMX_EXT_EXTRADATATYPE )EDataType;
943 //                     greError = OMX_GetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
945                     xData.bEnable = OMX_FALSE;
947                     omxError = OMX_SetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
948                 }
949             }
950             break;
951         }
953         case VCAM_CMD_LOCK_AE:
954         case VCAM_CMD_LOCK_AWB:
955         {
956             OMX_INDEXTYPE index;
957             OMX_IMAGE_CONFIG_LOCKTYPE lockCfg;
958             OMX_STRUCT_INIT(lockCfg, OMX_IMAGE_CONFIG_LOCKTYPE, mLocalVersion);
959             if (VCAM_CMD_LOCK_AE == cmdId)
960             {
961                 index = (OMX_INDEXTYPE)OMX_IndexConfigImageExposureLock;
962             }
963             else if (VCAM_CMD_LOCK_AWB == cmdId)
964             {
965                 index = (OMX_INDEXTYPE)OMX_IndexConfigImageWhiteBalanceLock;
966             }
967             else
968             {
969                 greError = -EINVAL;
970                 break;
971             }
972             OMX_GetConfig(mCurGreContext.mHandleComp, index, &lockCfg);
973             lockCfg.bLock = *((OMX_BOOL*)param);
974             OMX_SetConfig(mCurGreContext.mHandleComp, index, &lockCfg);
975             break;
976         }
977 #if TIME_PROFILE
978         case VCAM_DUMP_TIMES:
979         {
980             for( int i = 0; i < VCAM_TIME_TARGET_MAX; i++ )
981                 if( mTimeProfiler[i] )
982                     mTimeProfiler[i]->dump();
983             break;
984         }
985 #endif // TIME_PROFILE
986         case VCAM_CMD_FACE_DETECTION:
987         {
988             mFaceDetectionEnabled = *((bool*)(param));
989             enableFaceDetect(port);
990             break;
991         }
992 #if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
993         case VCAM_CMD_FREEZE_AWB_PARAMS:
994         {
995             OMX_TI_CONFIG_FREEZE_AWB wbFreeze;
996             OMX_STRUCT_INIT( wbFreeze, OMX_TI_CONFIG_FREEZE_AWB, mLocalVersion);
997             wbFreeze.nTimeDelay = *((uint32_t*)param);
999             omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigFreezeAWB, &wbFreeze );
1000             break;
1001         }
1003         case VCAM_CMD_FREEZE_AGC_PARAMS:
1004         {
1005             OMX_TI_CONFIG_FREEZE_AE aeFreeze;
1006             OMX_STRUCT_INIT( aeFreeze, OMX_TI_CONFIG_FREEZE_AE, mLocalVersion);
1007             aeFreeze.nTimeDelay = *((uint32_t*)param);
1009             omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigFreezeAutoExp, &aeFreeze );
1010             break;
1011         }
1012 #endif
1013         case VCAM_CMD_SET_CLIENT_NOTIFICATION_CALLBACK:
1014         {
1015             mClientNotifier.mNotificationCallback = (VisionCamClientNotifier::VisionCamClientNotifierCallback)(param);
1016             break;
1017         }
1019         case VCAM_CMD_PACK_FRAMES:
1020         {
1021             mUseFramePackaging = *((bool*)param);
1022             break;
1023         }
1025         default:
1026         {
1027             ERROR("Impossible command id requested: %d", cmdId);
1028             ERROR("see VisionCamParam_e for possible command ids");
1029             greError = -EINVAL;
1030         }
1031     }
1033     if (greError == 0)
1034         greError = ConvertError(omxError);
1036     if (greError != 0)
1037     {
1038         ERROR("OMXVisionCam::sendCommand() exits with error %d for command id %d", greError, cmdId);
1039     }
1041     return greError;
1044 /*
1045 *  APIs to configure Vision Cam
1046 */
1047 int OMXVisionCam::setParameter( VisionCamParam_e paramId, void* param, uint32_t size, VisionCamPort_e port)
1049     int greError = 0;
1050     OMX_ERRORTYPE omxError = OMX_ErrorNone;
1052     AutoLock lock(&mUserRequestLock);
1054     if (param == NULL || size == 0 || port >= VCAM_PORT_MAX)
1055     {
1056         ERROR("NULL param pointer passed to %s()",__func__);
1057         return -EINVAL;
1058     }
1059     else
1060     {
1061         MSG("SET PARAM: 0x%04x, %p, %zu (0x%08x), %d", paramId, param, size, (size==4?*(uint32_t *)param:0), port);
1062     }
1064     if (getComponentState() == OMX_StateInvalid)
1065         return -EBADE;
1067     switch( paramId )
1068     {
1069         case VCAM_PARAM_HEIGHT:
1070         {
1071             int32_t p;
1072             LOOP_PORTS( port , p )
1073                 mCurGreContext.mCameraPortParams[p].mHeight = *((OMX_U32*)param);
1074             break;
1075         }
1077         case VCAM_PARAM_WIDTH:
1078         {
1079             int32_t p;
1080             LOOP_PORTS( port , p )
1081                     mCurGreContext.mCameraPortParams[p].mWidth = *((OMX_U32*)param);
1082             break;
1083         }
1086         case VCAM_PARAM_COLOR_SPACE_FOURCC:
1087         {
1088             uint32_t color = *((uint32_t*)param);
1089             switch (color) {
1090                 case FOURCC('U','Y','V','Y'):
1091                 case FOURCC('Y','U','Y','V'):
1092                     mCurGreContext.mCameraPortParams[port].mColorFormat =
1093                         OMX_COLOR_FormatCbYCrY;
1094                     break;
1095                 case FOURCC('N','V','1','2'):
1096                     mCurGreContext.mCameraPortParams[port].mColorFormat =
1097                         OMX_COLOR_FormatYUV420SemiPlanar;
1098                     break;
1099                 default:
1100                     greError = -EINVAL;
1101             }
1102             if (greError == 0) {
1103                 int32_t p;
1104                 LOOP_PORTS(port , p) {
1105                     OMX_PARAM_PORTDEFINITIONTYPE portCheck;
1106                     omxError = initPortCheck( &portCheck, p );
1107                     portCheck.format.video.eColorFormat =
1108                         mCurGreContext.mCameraPortParams[port].mColorFormat;
1109                     omxError = OMX_SetParameter(mCurGreContext.mHandleComp,
1110                         OMX_IndexParamPortDefinition, &portCheck);
1111                 }
1112             }
1113             break;
1114         }
1116         case VCAM_PARAM_DO_AUTOFOCUS:
1117         {
1118             if (OMX_StateExecuting == getComponentState())
1119             {
1120                 greError = startAutoFocus( *((VisionCamFocusMode*)param) );
1121             }
1122             else
1123             {
1124                 greError = ConvertError(OMX_ErrorIncorrectStateOperation);
1125             }
1126             break;
1127         }
1129         case VCAM_PARAM_DO_MANUALFOCUS:
1130         {
1131             if (OMX_StateExecuting == getComponentState())
1132             {
1133                 mManualFocusDistance = *((uint32_t*)param);
1134                 greError = startAutoFocus( VCAM_FOCUS_CONTROL_ON );
1135             }
1136             else
1137             {
1138                 greError = ConvertError(OMX_ErrorIncorrectStateOperation);
1139             }
1140             break;
1141         }
1143         case VCAM_PARAM_BRIGHTNESS:
1144         {
1145             OMX_CONFIG_BRIGHTNESSTYPE brightness;
1146             brightness.nSize = sizeof(OMX_CONFIG_BRIGHTNESSTYPE);
1147             brightness.nBrightness = *((int*)param);
1148             memcpy( &brightness.nVersion, mLocalVersion, sizeof(mLocalVersion) );
1150             int32_t p = port;
1151 //            LOOP_PORTS( port , p )
1152             {
1153                 brightness.nPortIndex = mCurGreContext.mPortsInUse[p];
1154                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonBrightness, &brightness);
1155             }
1156             break;
1157         }
1159         case VCAM_PARAM_CONTRAST:
1160         {
1161             OMX_CONFIG_CONTRASTTYPE contrast;
1162             contrast.nSize = sizeof( OMX_CONFIG_CONTRASTTYPE );
1163             contrast.nContrast = *((int*)param);
1164             memcpy( &contrast.nVersion, mLocalVersion, sizeof(mLocalVersion) );
1166             int32_t p = port;
1167 //            LOOP_PORTS( port , p )
1168             {
1169                 contrast.nPortIndex = mCurGreContext.mPortsInUse[p];
1170                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonContrast, &contrast);
1171             }
1172             break;
1173         }
1175         case VCAM_PARAM_SHARPNESS:
1176         {
1177             OMX_IMAGE_CONFIG_PROCESSINGLEVELTYPE procSharpness;
1178             procSharpness.nSize = sizeof( OMX_IMAGE_CONFIG_PROCESSINGLEVELTYPE );
1179             procSharpness.nLevel = *((int*)param);
1180             memcpy( &procSharpness.nVersion, mLocalVersion, sizeof(mLocalVersion) );
1182             if( procSharpness.nLevel == 0 )
1183                 procSharpness.bAuto = OMX_TRUE;
1184             else
1185                 procSharpness.bAuto = OMX_FALSE;
1187             int32_t p = port;
1188 //            LOOP_PORTS( port , p )
1189             {
1190                 procSharpness.nPortIndex = mCurGreContext.mPortsInUse[p];
1191                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigSharpeningLevel, &procSharpness);
1192             }
1193             break;
1194         }
1196         case VCAM_PARAM_SATURATION:
1197         {
1198             OMX_CONFIG_SATURATIONTYPE saturation;
1199             saturation.nSize = sizeof(OMX_CONFIG_SATURATIONTYPE);
1200             saturation.nSaturation = *((int*)param);
1201             memcpy( &saturation.nVersion, mLocalVersion, sizeof(mLocalVersion) );
1203             int32_t p = port;
1204 //            LOOP_PORTS( port , p )
1205             {
1206                 saturation.nPortIndex = mCurGreContext.mPortsInUse[p];
1207                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1208                                           OMX_IndexConfigCommonSaturation,
1209                                           &saturation
1210                                         );
1211             }
1212             break;
1213         }
1215         case VCAM_PARAM_FPS_FIXED:
1216         {
1217             bool enableAgain[VCAM_PORT_MAX];
1219             int32_t p;
1220             LOOP_PORTS(VCAM_PORT_ALL , p)
1221                 enableAgain[p] = mCurGreContext.mCameraPortParams[p].mIsActive;
1223             stopPreview(VCAM_PORT_ALL);
1224             int32_t i;
1225             LOOP_PORTS(VCAM_PORT_ALL , i)
1226             {
1227                 mCurGreContext.mCameraPortParams[i].mFrameRate = (*((int*)param));
1228                 if( enableAgain[i] )
1229                     startPreview( (VisionCamPort_e)i );
1230             }
1232             break;
1233         }
1235         case VCAM_PARAM_FPS_VAR:
1236         {
1237             VisionCamVarFramerateType varFrate;
1238             memcpy( &varFrate , param , sizeof( VisionCamVarFramerateType ) );
1240             bool enableAgain[VCAM_PORT_MAX];
1242             int32_t p;
1243             LOOP_PORTS( VCAM_PORT_ALL , p )
1244             {
1245                 enableAgain[p] = mCurGreContext.mCameraPortParams[p].mIsActive;
1246             }
1248             stopPreview(VCAM_PORT_ALL);
1250             if( varFrate.mMin != 0 )
1251             {
1252               // @todo implement when needed OMX interface is present
1253                 varFrate = varFrate;
1254             }
1256             int32_t i;
1257             LOOP_PORTS( VCAM_PORT_ALL , i )
1258             {
1259                 mCurGreContext.mCameraPortParams[i].mFrameRate = varFrate.mMax;
1260                 if( enableAgain[i] )
1261                     startPreview( (VisionCamPort_e)i );
1262             }
1263             break;
1264         }
1266         case VCAM_PARAM_FLICKER:
1267         {
1268             OMX_CONFIG_FLICKERCANCELTYPE flicker;
1269             flicker.nSize = sizeof( OMX_CONFIG_FLICKERCANCELTYPE );
1270             memcpy( &flicker.nVersion, mLocalVersion, sizeof(mLocalVersion) );
1271             flicker.eFlickerCancel = *(OMX_COMMONFLICKERCANCELTYPE *)param;
1273             int32_t p = port;
1274 //            LOOP_PORTS( VCAM_PORT_ALL , p )
1275             {
1276                 flicker.nPortIndex = mCurGreContext.mPortsInUse[p];
1277                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigFlickerCancel, &flicker );
1278             }
1279             break;
1280         }
1282         case VCAM_PARAM_CROP:
1283         {
1284             OMX_CONFIG_RECTTYPE crop;
1285             crop.nSize = sizeof( OMX_CONFIG_RECTTYPE );
1286             crop.nLeft = ((VisionCamRectType*)param)->mLeft;
1287             crop.nTop = ((VisionCamRectType*)param)->mTop;
1288             crop.nWidth = ((VisionCamRectType*)param)->mWidth;
1289             crop.nHeight = ((VisionCamRectType*)param)->mHeight;
1290             memcpy( &crop.nVersion,  mLocalVersion, sizeof(mLocalVersion) );
1292             int32_t p = port;
1293 //            LOOP_PORTS( port , p )
1294             {
1295                 crop.nPortIndex = mCurGreContext.mPortsInUse[p];
1296                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonOutputCrop, &crop );
1297             }
1298             break;
1299         }
1301         case VCAM_PARAM_STEREO_INFO:
1302         {
1303             VisionCamStereoInfo *info = (VisionCamStereoInfo *)param;
1304             OMX_TI_FRAMELAYOUTTYPE frameLayout;
1305             OMX_STRUCT_INIT(frameLayout, OMX_TI_FRAMELAYOUTTYPE, mLocalVersion);
1306             OMX_TI_CONFIG_CONVERGENCETYPE acParams;
1307             OMX_STRUCT_INIT(acParams, OMX_TI_CONFIG_CONVERGENCETYPE, mLocalVersion);
1308             if ( info && size == sizeof(VisionCamStereoInfo))
1309             {
1310                 int32_t p = port;
1311 //                LOOP_PORTS( port , p )
1312                 {
1313                     frameLayout.nPortIndex = mCurGreContext.mPortsInUse[p];
1314                     MSG("Stereo Info: Layout %u, SubSampling: %u", info->layout, info->subsampling);
1316                     frameLayout.eFrameLayout = (OMX_TI_STEREOFRAMELAYOUTTYPE)getLutValue( (int)info->layout, VCAM_VALUE_TYPE,
1317                                                                                             StereoLayoutLUT, ARR_SIZE(StereoLayoutLUT)
1318                                                                                         );
1319                     if (info->layout == VCAM_STEREO_LAYOUT_TOPBOTTOM)
1320                         frameLayout.eFrameLayout = OMX_TI_StereoFrameLayoutTopBottom;
1321                     else if (info->layout == VCAM_STEREO_LAYOUT_LEFTRIGHT)
1322                         frameLayout.eFrameLayout = OMX_TI_StereoFrameLayoutLeftRight;
1323                     frameLayout.nSubsampleRatio = info->subsampling << 7; // in Q15.7 format
1324                     omxError = OMX_SetParameter( mCurGreContext.mHandleComp,
1325                                                  (OMX_INDEXTYPE)OMX_TI_IndexParamStereoFrmLayout,
1326                                                  &frameLayout
1327                                                 );
1329                     if( OMX_ErrorNone == omxError )
1330                     {
1331                         acParams.nPortIndex = mCurGreContext.mPortsInUse[p];
1333                         acParams.nManualConverence = 0;
1334                         acParams.eACMode = OMX_TI_AutoConvergenceModeDisable;
1336                         omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1337                                                   (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoConvergence,
1338                                                   &acParams
1339                                                  );
1340                         if( OMX_ErrorNone != omxError )
1341                         {
1342                             ERROR("ERROR OMXVisionCam: Failed to disable auto convergence.");
1343                         }
1344                     }
1345                     else
1346                     {
1347                         ERROR("ERROR OMXVisionCam: Failed to set stero layout");
1348                     }
1349                 }
1350             }
1351             else
1352             {
1353                 ERROR("ERROR OMXVisionCam: attempt to set param with id VCAM_PARAM_STEREO_INFO with an invalid args");
1354                 greError = -EINVAL;
1355             }
1356             break;
1357         }
1359         case VCAM_PARAM_CAP_MODE:
1360         {
1361             if (param != NULL)
1362             {
1363                 VisionCamCaptureMode mode = *(VisionCamCaptureMode *)param;
1365                 OMX_CONFIG_CAMOPERATINGMODETYPE opMode;
1366                 opMode.nSize = sizeof( OMX_CONFIG_CAMOPERATINGMODETYPE );
1367                 memcpy( &opMode.nVersion, mLocalVersion, sizeof(mLocalVersion) );
1369                 opMode.eCamOperatingMode = (OMX_CAMOPERATINGMODETYPE)getLutValue(mode, VCAM_VALUE_TYPE, CaptureModeLUT, ARR_SIZE(CaptureModeLUT) );
1371                 MSG("Requested VisionCamCaptureMode %d", mode);
1372                 MSG("Requested OMX_CAMOPERATINGMODETYPE %d", opMode.eCamOperatingMode);
1374                 bool enableAgain[VCAM_PORT_MAX];
1376                 int32_t p;// mark and stop all working ports
1377                 LOOP_PORTS( VCAM_PORT_ALL , p )
1378                 {
1379                     enableAgain[p] = mCurGreContext.mCameraPortParams[p].mIsActive;
1380                     if( mCurGreContext.mCameraPortParams[p].mIsActive )
1381                         portEnableDisable(OMX_CommandPortDisable, freePortBuffersSrvc, (VisionCamPort_e)p );
1382                 }
1384                 int32_t oldstate = getComponentState();
1385                 for(int32_t st = oldstate - 1; st >= OMX_StateLoaded; st--)
1386                 {
1387                     if( OMX_StatePause == oldstate  && OMX_StateExecuting == st )
1388                         continue;
1390                     transitToState( (OMX_STATETYPE)st );
1391                 }
1393                 if( OMX_StateLoaded == getComponentState() || OMX_StateWaitForResources == getComponentState() )
1394                 {
1395                     omxError = OMX_SetParameter( mCurGreContext.mHandleComp,
1396                                                  (OMX_INDEXTYPE)OMX_IndexCameraOperatingMode,
1397                                                  &opMode );
1399                     greError = ConvertError(omxError);
1400                 }
1402                 for(int32_t st = (1 + getComponentState()); st <= oldstate; st++)
1403                 {
1404                     if( OMX_StatePause == oldstate && OMX_StateExecuting == st)
1405                         continue;
1407                     transitToState( (OMX_STATETYPE)st );
1408                 }
1410                 int32_t por;
1411                 LOOP_PORTS( VCAM_PORT_ALL , por )
1412                     if( enableAgain[por])
1413                     {
1414                         portEnableDisable(OMX_CommandPortEnable, populatePortSrvc, (VisionCamPort_e)por);
1415                         fillPortBuffers((VisionCamPort_e)por);
1416                     }
1417             }
1418             else
1419                 greError = -EINVAL;
1420             break;
1421         }
1423         case VCAM_PARAM_SENSOR_SELECT:
1424         {
1425             if (param != NULL)
1426             {
1427                 OMX_CONFIG_SENSORSELECTTYPE sensor;
1428                 OMX_STRUCT_INIT(sensor, OMX_CONFIG_SENSORSELECTTYPE, mLocalVersion);
1429                 sensor.nPortIndex = mCurGreContext.mPortsInUse[VCAM_PORT_ALL];
1430                 sensor.eSensor = *((OMX_SENSORSELECT*)param);
1431                 MSG("Selecting sensor index = %u", sensor.eSensor);
1432                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigSensorSelect, &sensor);
1433             }
1434             else
1435                 greError = -EINVAL;
1436             break;
1437         }
1439         case VCAM_PARAM_EXPOSURE_COMPENSATION:
1440         {
1441             OMX_CONFIG_EXPOSUREVALUETYPE expValues;
1442             OMX_STRUCT_INIT(expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion);
1444             memcpy( &expValues.nVersion , mLocalVersion , sizeof( *mLocalVersion ) );
1445             omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
1447             if( OMX_ErrorNone == omxError )
1448             {
1449                 int compVal = *((int*)param);
1450                 expValues.xEVCompensation = ( compVal * ( 1 << 16 ) )  / 10;
1452                 int32_t p = port;
1453 //                LOOP_PORTS( port , p )
1454                 {
1455                     expValues.nPortIndex = mCurGreContext.mPortsInUse[p];
1456                     omxError = OMX_SetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
1457                 }
1458             }
1459             break;
1460         }
1462         case VCAM_PARAM_RESOLUTION:
1463         {
1464             if( param != NULL )
1465             {
1466                 int res;
1468                 if( *((int*)param) < 0 || *((int*)param) >= VCAM_RESOL_MAX )
1469                 {
1470                    greError = -EINVAL;
1471                    break;
1472                 }
1474                 int32_t p = port;
1475                 LOOP_PORTS( port , p )
1476                 {
1477                     res = *((int*)param);
1478                     if( 0 == greError )
1479                         if( mCurGreContext.mCameraPortParams[p].mIsActive )
1480                             greError = -EBADE;
1482                     if( 0 == greError )
1483                     {
1484                             if( VCAM_PORT_VIDEO == p
1485                                 && ( VisionCamResolutions[res].mWidth > VisionCamResolutions[VCAM_RES_VGA].mWidth
1486                                 || VisionCamResolutions[res].mHeight > VisionCamResolutions[VCAM_RES_VGA].mHeight ) )
1487                             {
1488                                 res = VCAM_RES_VGA;
1489                             }
1491                         mCurGreContext.mCameraPortParams[p].mWidth = VisionCamResolutions[res].mWidth;
1492                         mCurGreContext.mCameraPortParams[p].mHeight = VisionCamResolutions[res].mHeight;
1493                     }
1494                 }
1495             }
1496             else
1497                 greError = -EINVAL;
1499             break;
1500         }
1502         case VCAM_PARAM_MANUAL_EXPOSURE:
1503         {
1504             OMX_CONFIG_EXPOSUREVALUETYPE expValues;
1505             OMX_STRUCT_INIT(expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion);
1506             int32_t p = port;
1508 //            LOOP_PORTS( port , p )
1509             {
1510                 expValues.nPortIndex = mCurGreContext.mPortsInUse[p];
1511                 omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
1513                 if( OMX_ErrorNone == omxError )
1514                 {
1515                     if( *(OMX_U32*)param )
1516                     {
1517                         expValues.nShutterSpeedMsec = *(OMX_U32*)param;
1518                         expValues.bAutoShutterSpeed = OMX_FALSE;
1519                     }
1520                     else
1521                         expValues.bAutoShutterSpeed = OMX_TRUE;
1523                     omxError = OMX_SetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
1524                 }
1525             }
1526             break;
1527         }
1529         case VCAM_PARAM_EXPOSURE_ISO:
1530         {
1531             OMX_CONFIG_EXPOSUREVALUETYPE expValues;
1532             OMX_STRUCT_INIT(expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion);
1533             int32_t p = port;
1534 //            LOOP_PORTS( port , p )
1535             {
1537                 expValues.nPortIndex = mCurGreContext.mPortsInUse[p];
1538                 omxError = OMX_GetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigCommonExposureValue, &expValues);
1539                 if( OMX_ErrorNone == omxError )
1540                 {
1541                     if( *(OMX_U32*)param )
1542                     {
1543                         expValues.nSensitivity = *(OMX_U32*)param;
1544                         expValues.bAutoSensitivity = OMX_FALSE;
1545                     }
1546                     else
1547                         expValues.bAutoSensitivity = OMX_TRUE;
1549                     omxError = OMX_SetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
1550                 }
1551             }
1552             break;
1553         }
1555         case VCAM_PARAM_AWB_MODE:
1556         {
1557             OMX_CONFIG_WHITEBALCONTROLTYPE wb;
1558             OMX_STRUCT_INIT(wb, OMX_CONFIG_WHITEBALCONTROLTYPE, mLocalVersion);
1560             int32_t p = port;
1561 //            LOOP_PORTS( port , p )
1562             {
1563                 wb.nPortIndex = mCurGreContext.mPortsInUse[p];
1564                 wb.eWhiteBalControl = *(OMX_WHITEBALCONTROLTYPE *)param;
1565                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1566                                         OMX_IndexConfigCommonWhiteBalance,
1567                                         &wb);
1568             }
1569             break;
1570         }
1572         case VCAM_PARAM_COLOR_TEMP:
1573         {
1574             OMX_CONFIG_WHITEBALCONTROLTYPE wb;
1575             OMX_STRUCT_INIT(wb, OMX_CONFIG_WHITEBALCONTROLTYPE, mLocalVersion);
1577             if( 0 == *(int*)param )
1578                 wb.eWhiteBalControl = OMX_WhiteBalControlAuto;
1579             else
1580                 wb.eWhiteBalControl = OMX_WhiteBalControlOff; // @todo change to manual when proper OMX headers arrive
1582             int32_t p = port;
1583 //            LOOP_PORTS( port , p )
1584             {
1585                 wb.nPortIndex = mCurGreContext.mPortsInUse[p];
1586                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1587                                      OMX_IndexConfigCommonWhiteBalance,
1588                                      &wb );
1589             }
1590             break;
1591         }
1593         case VCAM_PARAM_WB_COLOR_GAINS:
1594         {
1595 #ifdef USE_WB_GAIN_PATCH
1596             VisionCamWhiteBalGains wbGains = *((VisionCamWhiteBalGains*)param);
1597             uint16_t * tmp;
1598             CALCULATE_WB_GAINS_OFFSET(uint16_t,mWBbuffer,tmp);
1600             tmp[ RED ] = wbGains.mRed;
1601             tmp[ GREEN_RED ] = wbGains.mGreen_r;
1602             tmp[ GREEN_BLUE ] = wbGains.mGreen_b;
1603             tmp[ BLUE ] = wbGains.mBlue;
1605             OMX_TI_CONFIG_SHAREDBUFFER skipBuffer;
1606             skipBuffer.nSize = sizeof( OMX_TI_CONFIG_SHAREDBUFFER );
1607             memcpy( &skipBuffer.nVersion , mLocalVersion , sizeof(mLocalVersion) );
1609             if( wbGains.mRed >= COLOR_GAIN_MIN &&  wbGains.mRed <= COLOR_GAIN_MAX
1610                 && wbGains.mGreen_b >= COLOR_GAIN_MIN && wbGains.mGreen_b <= COLOR_GAIN_MAX
1611                 && wbGains.mGreen_r >= COLOR_GAIN_MIN && wbGains.mGreen_r <= COLOR_GAIN_MAX
1612                 && wbGains.mBlue >= COLOR_GAIN_MIN && wbGains.mBlue <= COLOR_GAIN_MAX )
1613             {
1614                 skipBuffer.pSharedBuff = (OMX_U8*)mWBbuffer;
1615                 skipBuffer.nSharedBuffSize = sizeof(mWBbuffer);
1616             }
1617             else if( !wbGains.mRed && !wbGains.mGreen_b && !wbGains.mGreen_r && !wbGains.mBlue )
1618             {   /// all gains are zero => auto mode
1619                 skipBuffer.pSharedBuff = (OMX_U8*)mWBresetBuffer;
1620                 skipBuffer.nSharedBuffSize = sizeof(mWBresetBuffer);
1621             }
1622             else
1623             {
1624                 greError = -EINVAL;
1625                 break;
1626             }
1628             int32_t p = port;
1629 //            LOOP_PORTS(port, p)
1630             {
1631                 skipBuffer.nPortIndex = p;
1632                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1633                                         (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
1634                                         &skipBuffer );
1635             }
1636 #endif // USE_WB_GAIN_PATCH
1637             break;
1638         }
1640         case VCAM_PARAM_GAMMA_TBLS:
1641         {
1642             VisionCamGammaTableType *gammaTbl = (VisionCamGammaTableType*)(param);
1643             OMX_TI_CONFIG_SHAREDBUFFER skipBuffer;
1644             OMX_STRUCT_INIT(skipBuffer, OMX_TI_CONFIG_SHAREDBUFFER, mLocalVersion);
1646             uint32_t* base = (uint32_t *)(mGammaTablesBuf + 12); // 12 bytes offset for first table
1647             uint16_t *redTbl      = (uint16_t*)(base[0] + (uint32_t)&base[2]);
1648             uint16_t *blueTbl     = (uint16_t*)(base[1] + (uint32_t)&base[2]);
1649             uint16_t *greenTbl    = (uint16_t*)(base[2] + (uint32_t)&base[2]);
1651 #ifdef _USE_GAMMA_RESET_HC_
1652             if( !mGammaResetPolulated )
1653             {
1654                 skipBuffer.pSharedBuff = (OMX_U8*)mGammaResetTablesBuf;
1655                 skipBuffer.nSharedBuffSize = sizeof(mGammaResetTablesBuf);
1656                 omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
1657                                     (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
1658                                     &skipBuffer );
1660                 if( OMX_ErrorNone == omxError )
1661                     mGammaResetPolulated = true;
1662             }
1663 #endif // _USE_GAMMA_RESET_HC_
1665             if( gammaTbl->mRedTable && gammaTbl->mGreenTable && gammaTbl->mBlueTable )
1666             {
1667                 if( gammaTbl->mRedTable != redTbl )
1668                 {
1669                     memcpy(redTbl, gammaTbl->mRedTable, GAMMA_TABLE_SIZE );
1670                 }
1672                 if( gammaTbl->mGreenTable != greenTbl )
1673                 {
1674                     memcpy(greenTbl, gammaTbl->mGreenTable, GAMMA_TABLE_SIZE );
1675                 }
1677                 if( gammaTbl->mBlueTable != blueTbl )
1678                 {
1679                     memcpy(blueTbl, gammaTbl->mBlueTable, GAMMA_TABLE_SIZE );
1680                 }
1682                 skipBuffer.pSharedBuff = (OMX_U8*)mGammaTablesBuf;
1683                 skipBuffer.nSharedBuffSize = sizeof(mGammaTablesBuf)/sizeof(mGammaTablesBuf[0]);
1684             }
1685             else
1686             {
1687 #ifdef _USE_GAMMA_RESET_HC_
1688                 if( mGammaResetPolulated )
1689                 {
1690                     skipBuffer.pSharedBuff = (OMX_U8*)mGammaResetTablesBuf;
1691                     skipBuffer.nSharedBuffSize = sizeof(mGammaResetTablesBuf)/sizeof(mGammaResetTablesBuf[0]);
1692                 }
1693                 else
1694                 {
1695                     ERROR("No data present in reset Gamma Tables. Leaving Gamma unchanged!!!");
1696                 }
1697 #else
1698                 skipBuffer.pSharedBuff = (OMX_U8*)mGammaResetTablesBuf;
1699                 skipBuffer.nSharedBuffSize = sizeof(mGammaResetTablesBuf)/sizeof(mGammaResetTablesBuf[0]);
1700 #endif // _USE_GAMMA_RESET_HC_
1701             }
1703             omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1704                                     (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
1705                                     &skipBuffer );
1707             break;
1708         }
1710 #if defined(VCAM_SET_FORMAT_ROTATION)
1711         case VCAM_PARAM_ROTATION:
1712         {
1713             int32_t p;
1714             LOOP_PORTS( port , p )
1715             {
1716                 mCurGreContext.mCameraPortParams[p].mRotation = *((OMX_S32 *)param);
1717             }
1718             break;
1719         }
1720 #else
1721         case VCAM_PARAM_ROTATION:
1722         {
1723             OMX_CONFIG_ROTATIONTYPE rotation;
1724             OMX_STRUCT_INIT(rotation, OMX_CONFIG_ROTATIONTYPE, mLocalVersion);
1725             rotation.nRotation = *((OMX_S32*)param);
1727             int32_t p;
1728             LOOP_PORTS( port , p )
1729             {
1730                 rotation.nPortIndex = mCurGreContext.mPortsInUse[p];
1731                 OMX_CHECK(omxError, OMX_SetConfig(mCurGreContext.mHandleComp,
1732                                                   OMX_IndexConfigCommonRotate,
1733                                                   &rotation));
1734                 MSG("Setting Rotation to %ld (size: %u)", rotation.nRotation, sizeof(rotation));
1735             }
1736             break;
1737         }
1738 #endif
1739         case VCAM_PARAM_MIRROR:
1740         {
1741             int i;
1742             OMX_CONFIG_MIRRORTYPE mirror;
1743             OMX_STRUCT_INIT(mirror, OMX_CONFIG_MIRRORTYPE, mLocalVersion);
1745             for( i = 0; i < VCAM_MIRROR_MAX; i++ )
1746             {
1747                 if( MirrorTypeLUT[i][0] == *((VisionCamMirrorType*)param) )
1748                 {
1749                   mirror.eMirror = (OMX_MIRRORTYPE) MirrorTypeLUT[i][1];
1750                   break;
1751                 }
1752             }
1754             if( i < VCAM_MIRROR_MAX )
1755             {
1756                 int32_t p;
1757                 LOOP_PORTS( port , p )
1758                 {
1759                     mirror.nPortIndex = mCurGreContext.mPortsInUse[p];
1760                     omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1761                                             OMX_IndexConfigCommonMirror,
1762                                             &mirror );
1763                 }
1764             }
1765             else
1766                 greError = -EINVAL;
1767             break;
1768         }
1770 #if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
1771         case VCAM_PARAM_AWB_MIN_DELAY_TIME:
1772         {
1773             uint32_t timeDelay = *((uint32_t*)param);
1774             if( timeDelay > AE_Delay_Time_Max )
1775             {
1776                 greError = -EINVAL;
1777             }
1778             else
1779             {
1780                 OMX_TI_CONFIG_AE_DELAY aeDelay;
1781                 OMX_STRUCT_INIT( aeDelay, OMX_TI_CONFIG_AE_DELAY, mLocalVersion );
1782                 aeDelay.nDelayTime = timeDelay;
1784                 int32_t p = port;
1785 //                LOOP_PORTS( port , p )
1786                 {
1787                     aeDelay.nPortIndex = p;
1788                     omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1789                                                 ( OMX_INDEXTYPE )OMX_TI_IndexConfigAutoExpMinDelayTime,
1790                                                 &aeDelay
1791                                             );
1792                 }
1793             }
1794             break;
1795         }
1796 #endif
1797 #if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_GESTURES)
1798         case VCAM_PARAM_GESTURES_INFO:
1799         {
1800             VisionCamGestureInfo *info = (VisionCamGestureInfo*)param;
1801             if( info->mGestureType >= VCAM_GESTURE_EVENT_MAX || info->mGestureType < VCAM_GESTURE_EVENT_INVALID )
1802             {
1803                 greError= -EINVAL;
1804             }
1806             if( info->mRegionsNum >= VCAM_Max_Gesture_Per_Frame )
1807             {
1808                 greError= -EINVAL;
1809             }
1811             if( 0 == greError )
1812             {
1813                 OMX_TI_CONFIG_GESTURES_INFO gestInfo;
1814                 OMX_STRUCT_INIT( gestInfo, OMX_TI_CONFIG_GESTURES_INFO , mLocalVersion );
1816                 gestInfo.nTimeStamp = info->timeStamp;
1817                 gestInfo.nNumDetectedGestures = info->mRegionsNum;
1818                 gestInfo.eType = (OMX_TI_GESTURES_TYPE)getLutValue( info->mGestureType, VCAM_VALUE_TYPE,
1819                                                                     GestureTypeLUT, ARR_SIZE(GestureTypeLUT)
1820                                                                     );
1822                 for(uint32_t i = 0; i < info->mRegionsNum ; i++ )
1823                 {
1824                       OMX_STRUCT_INIT(gestInfo.nGestureAreas[i], OMX_CONFIG_OBJECT_RECT_TYPE , mLocalVersion );
1825                       gestInfo.nGestureAreas[i].eType = (OMX_TI_OBJECT_TYPE)getLutValue( (int)(info->mRegions[i].mObjType), VCAM_VALUE_TYPE,
1826                                                                                          ObjectTypeLUT, ARR_SIZE(ObjectTypeLUT)
1827                                                                                         );
1829                       gestInfo.nGestureAreas[i].nTop = info->mRegions[i].mTop;
1830                       gestInfo.nGestureAreas[i].nLeft = info->mRegions[i].mLeft;
1831                       gestInfo.nGestureAreas[i].nWidth = info->mRegions[i].mWidth;
1832                       gestInfo.nGestureAreas[i].nHeight = info->mRegions[i].mHeight;
1833                 }
1835                 if( OMX_TI_GESTURE_NO_GESTURE != gestInfo.eType)
1836                 {
1837                     int32_t p = port;
1838 //                    LOOP_PORTS( port , p )
1839                     {
1840                         gestInfo.nPortIndex = mCurGreContext.mPortsInUse[p];
1841                         omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1842                                                 (OMX_INDEXTYPE)OMX_TI_IndexConfigDetectedGesturesInfo,
1843                                                 &gestInfo
1844                                               );
1845                     }
1846                 }
1847                 else
1848                     greError = -EINVAL;
1849             }
1851             break;
1852         }
1853 #endif
1854 #if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
1855         case VCAM_PARAM_AGC_MIN_DELAY_TIME:
1856         {
1857             int32_t delay = *((int32_t*)param);
1858             OMX_TI_CONFIG_AE_DELAY agcDelTime;
1859             OMX_STRUCT_INIT( agcDelTime, OMX_TI_CONFIG_AE_DELAY, mLocalVersion );
1860             agcDelTime.nDelayTime = delay;
1862             int32_t p = port;
1863 //            LOOP_PORTS( port , p )
1864             {
1865                 agcDelTime.nPortIndex = p;
1866                 omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
1867                                         (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpMinDelayTime,
1868                                         &agcDelTime );
1869             }
1870             break;
1871         }
1873         case VCAM_PARAM_AGC_LOW_TH:
1874         {
1875             int32_t lowTH = *((int32_t*)param);
1876             OMX_TI_CONFIG_AE_THRESHOLD ae;
1878             OMX_STRUCT_INIT( ae, OMX_TI_CONFIG_AE_THRESHOLD, mLocalVersion );
1880             int32_t p = port;
1881 //            LOOP_PORTS( port , p )
1882             {
1883                 ae.nPortIndex = p;
1884                 omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
1886                 if( OMX_ErrorNone == omxError )
1887                 {
1888                     ae.uMinTH = lowTH;
1889                     omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
1890                 }
1891             }
1892             break;
1893         }
1894         case VCAM_PARAM_AGC_HIGH_TH:
1895         {
1896             int32_t highTH = *((int32_t*)param);
1898             OMX_TI_CONFIG_AE_THRESHOLD ae;
1899             OMX_STRUCT_INIT( ae, OMX_TI_CONFIG_AE_THRESHOLD, mLocalVersion );
1901             int32_t p = port;
1902 //            LOOP_PORTS( port , p )
1903             {
1904                 ae.nPortIndex = p;
1905                 omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
1907                 if( OMX_ErrorNone == omxError )
1908                 {
1909                     ae.uMaxTH = highTH;
1910                     omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
1911                 }
1912             }
1913             break;
1914         }
1915 #endif
1916         case VCAM_PARAM_NAME:
1917             // do nothing as this is not supported but it should not fail either
1918             break;
1919         default:
1920         {
1921             ERROR("Impossible parameter id requested: %d", paramId);
1922             ERROR("see VisionCamParam_e for possible parameter ids");
1923             greError = -ENOSYS;
1924             if(paramId < VCAM_PARAM_MIN || paramId > VCAM_PARAM_MAX)
1925                 greError = -EINVAL;
1926         }
1927     }
1929     if( OMX_ErrorNone != omxError )
1930     {
1931         greError = ConvertError(omxError);
1932     }
1934     if( greError != 0 )
1935     {
1936         ERROR("setParameter() exits with error 0x%x (dec: %d) [OMX:0x%08x] for param id 0x%x",
1937                 greError, greError, omxError, paramId);
1938     }
1940     return greError;
1943 /*
1944 *  APIs to get configured Vision Cam parameters
1945 */
1946 int OMXVisionCam::getParameter( VisionCamParam_e paramId, void* param, uint32_t size, VisionCamPort_e port)
1948     int greError = 0;
1949     OMX_ERRORTYPE omxError = OMX_ErrorNone;
1951     AutoLock lock(&mUserRequestLock);
1953     if (param == NULL || size == 0 || port >= VCAM_PORT_MAX)
1954     {
1955         ERROR("NULL param pointer passed to %s", __func__);
1956         return -EINVAL;
1957     }
1958     else
1959     {
1960         MSG("GET PARAM: 0x%04x, %p, %u (0x%08x)", paramId, param, size, (size==4?*(uint32_t *)param:0));
1961     }
1963     if( VCAM_PORT_ALL == port)
1964     {
1965         ERROR("%s called on port ALL. Please specifu a port!", __func__);
1966         return -EINVAL;
1967     }
1968     switch( paramId )
1969     {
1970         case VCAM_PARAM_HEIGHT:
1971         {
1972             OMX_PARAM_PORTDEFINITIONTYPE portCheck;
1973             omxError = initPortCheck( &portCheck , port );
1975             if( OMX_ErrorNone == omxError )
1976             {
1977                 *(int*)param = portCheck.format.video.nFrameHeight;
1978             }
1979             break;
1980         }
1982         case VCAM_PARAM_WIDTH:
1983         {
1984             OMX_PARAM_PORTDEFINITIONTYPE portCheck;
1985             omxError = initPortCheck( &portCheck , port );
1987             if( OMX_ErrorNone == omxError )
1988             {
1989                 *(int*)param = portCheck.format.video.nFrameWidth;
1990             }
1991             break;
1992         }
1994         case VCAM_PARAM_COLOR_SPACE_FOURCC:
1995         {
1996             OMX_PARAM_PORTDEFINITIONTYPE portCheck;
1997             omxError = initPortCheck(&portCheck, port);
1999             switch (portCheck.format.video.eColorFormat) {
2000                 case OMX_COLOR_FormatCbYCrY:
2001                     *((int*)param) = FOURCC('Y','U','Y','V');
2002                     break;
2003                 case OMX_COLOR_FormatYUV420SemiPlanar:
2004                     *((int*)param) = FOURCC('N','V','1','2');
2005                     break;
2006                 default:
2007                     greError = -EINVAL;
2008             }
2009             break;
2010         }
2012         case VCAM_PARAM_DO_AUTOFOCUS:
2013         {
2014             int i = 0;
2015             OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focus;
2016             OMX_STRUCT_INIT(focus, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE, mLocalVersion);
2018             omxError = OMX_GetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigFocusControl, &focus);
2019             if( OMX_ErrorNone == omxError )
2020             {
2021                 for( i = 0; i < VCAM_FOCUS_CONTROL_MAX; i++ )
2022                 {
2023                     if ( FocusModeLUT[ i ][ 1 ] == focus.eFocusControl )
2024                     {
2025                         *(int*)param = FocusModeLUT[ i ][ 0 ];
2026                         break;
2027                     }
2028                 }
2029                 if( VCAM_FOCUS_CONTROL_MAX == i )
2030                     greError = -EINVAL;
2031             }
2033             break;
2034         }
2036         case VCAM_PARAM_DO_MANUALFOCUS:
2037         {
2038             OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focus;
2039             OMX_STRUCT_INIT(focus, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE, mLocalVersion);
2041             omxError = OMX_GetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigFocusControl, &focus);
2042             if( OMX_ErrorNone == omxError )
2043             {
2044                 (*(int*)param) = focus.nFocusSteps;
2045             }
2046             break;
2047         }
2049         case VCAM_PARAM_BRIGHTNESS:
2050         {
2051             OMX_CONFIG_BRIGHTNESSTYPE brightness;
2052             OMX_STRUCT_INIT(brightness, OMX_CONFIG_BRIGHTNESSTYPE, mLocalVersion );
2054             omxError = OMX_GetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonBrightness, &brightness);
2055             if( OMX_ErrorNone == omxError )
2056             {
2057                 *((uint32_t*)param) = brightness.nBrightness;
2058             }
2059             break;
2060         }
2062         case VCAM_PARAM_CONTRAST:
2063         {
2064             OMX_CONFIG_CONTRASTTYPE contrast;
2065             OMX_STRUCT_INIT(contrast, OMX_CONFIG_CONTRASTTYPE, mLocalVersion );
2067             omxError = OMX_GetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonContrast, &contrast);
2068             if( OMX_ErrorNone == omxError )
2069             {
2070                 *((int*)param) = contrast.nContrast;
2071             }
2072             break;
2073         }
2075         case VCAM_PARAM_SHARPNESS:
2076         {
2077             OMX_IMAGE_CONFIG_PROCESSINGLEVELTYPE procSharpness;
2078             OMX_STRUCT_INIT( procSharpness, OMX_IMAGE_CONFIG_PROCESSINGLEVELTYPE, mLocalVersion );
2080             omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigSharpeningLevel, &procSharpness);
2082             if( OMX_ErrorNone == omxError )
2083             {
2084                 if( OMX_TRUE == procSharpness.bAuto )
2085                     *((int*)param) = 0;
2086                 else
2087                     *((int*)param) = procSharpness.nLevel;
2088             }
2089             break;
2090         }
2092         case VCAM_PARAM_SATURATION:
2093         {
2094             OMX_CONFIG_SATURATIONTYPE saturation;
2095             OMX_STRUCT_INIT(saturation, OMX_CONFIG_SATURATIONTYPE, mLocalVersion);
2096             omxError = OMX_GetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonSaturation, &saturation);
2098             if( OMX_ErrorNone == omxError )
2099             {
2100                 *((int*)param) = saturation.nSaturation;
2101             }
2102             break;
2103         }
2105         case VCAM_PARAM_FPS_FIXED:
2106         {
2107             OMX_PARAM_PORTDEFINITIONTYPE portCheck;
2108             omxError = initPortCheck( &portCheck , port );
2110             if( OMX_ErrorNone == omxError )
2111             {
2112                 *((uint32_t*)param) = portCheck.format.video.xFramerate >> 16;
2113             }
2114             break;
2115         }
2117         case VCAM_PARAM_FPS_VAR:
2118         {
2119             ERROR("No Getting Api for this Parameter %d", paramId);
2120             break;
2121         }
2123         case VCAM_PARAM_FLICKER:
2124         {
2125             OMX_CONFIG_FLICKERCANCELTYPE flicker;
2126             OMX_STRUCT_INIT( flicker, OMX_CONFIG_FLICKERCANCELTYPE, mLocalVersion );
2127             omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigFlickerCancel, &flicker );
2129             if( OMX_ErrorNone == omxError )
2130             {
2131                 *((int*)param) = flicker.eFlickerCancel;
2132             }
2133             break;
2134         }
2136         case VCAM_PARAM_CROP:
2137         {
2138             OMX_CONFIG_RECTTYPE crop;
2139             OMX_STRUCT_INIT(crop, OMX_CONFIG_RECTTYPE, mLocalVersion);
2141             omxError = OMX_GetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonOutputCrop, &crop );
2143             if( OMX_ErrorNone == omxError )
2144             {
2145                 ((VisionCamRectType*)param)->mLeft = crop.nLeft;
2146                 ((VisionCamRectType*)param)->mTop = crop.nTop;
2147                 ((VisionCamRectType*)param)->mWidth = crop.nWidth;
2148                 ((VisionCamRectType*)param)->mHeight = crop.nHeight;
2149             }
2150           break;
2151         }
2153         case VCAM_PARAM_CAP_MODE:
2154         {
2155             if (param != NULL)
2156             {
2157                 int i = 0;
2158                 OMX_CONFIG_CAMOPERATINGMODETYPE opMode;
2159                 opMode.nSize = sizeof(OMX_CONFIG_CAMOPERATINGMODETYPE);
2160                 memcpy(&opMode .nVersion, mLocalVersion , sizeof(OMX_VERSIONTYPE));
2162                 omxError = OMX_GetParameter( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexCameraOperatingMode, &opMode );
2164                 if( OMX_ErrorNone == omxError )
2165                 {
2166                     for (i = 0; i < VCAM_CAP_MODE_MAX; i++)
2167                     {
2168                         if (CaptureModeLUT[i][1] == opMode.eCamOperatingMode)
2169                         {
2170                             memcpy( param, &CaptureModeLUT[i][0], sizeof(int) );
2171                             break;
2172                         }
2173                     }
2175                     if( VCAM_CAP_MODE_MAX == CaptureModeLUT[i][0])
2176                     {
2177                         greError = -EINVAL;
2178                         break;
2179                     }
2180                 }
2181             }
2182             break;
2183         }
2185         case VCAM_PARAM_SENSOR_SELECT:
2186         {
2187             OMX_CONFIG_SENSORSELECTTYPE sensor;
2188             OMX_STRUCT_INIT(sensor, OMX_CONFIG_SENSORSELECTTYPE, mLocalVersion);
2190             omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigSensorSelect, &sensor);
2192             if( OMX_ErrorNone == omxError)
2193             {
2194                 *((int*)param) = sensor.eSensor;
2195             }
2196             break;
2197         }
2199         case VCAM_PARAM_EXPOSURE_COMPENSATION:
2200         {
2201             OMX_CONFIG_EXPOSUREVALUETYPE expValues;
2202             OMX_STRUCT_INIT( expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion );
2203             omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
2205             if( OMX_ErrorNone == omxError )
2206             {
2207                 expValues.xEVCompensation *= 10;
2208                 int compVal = expValues.xEVCompensation / (1 << 16);
2209                 *((int*)param) = compVal;
2210             }
2211             break;
2212         }
2214         case VCAM_PARAM_RESOLUTION:
2215         {
2216             int i = VCAM_RESOL_MAX;
2217             unsigned int width, height;
2218             OMX_PARAM_PORTDEFINITIONTYPE portCheck;
2219             omxError = initPortCheck( &portCheck , port );
2221             if( OMX_ErrorNone == omxError )
2222             {
2223                 width = portCheck.format.video.nFrameWidth;
2224                 height = portCheck.format.video.nFrameHeight;
2225                 for( i = 0; i < VCAM_RESOL_MAX; i++)
2226                 {
2227                     if( VisionCamResolutions[i].mWidth == width
2228                         && VisionCamResolutions[i].mHeight == height)
2229                     {
2230                         *((int*)param) = i;
2231                         break;
2232                     }
2233                 }
2234                 if( VCAM_RESOL_MAX == i )
2235                 {
2236                     greError = -EINVAL;
2237                 }
2238             }
2239             break;
2240         }
2242         case VCAM_PARAM_2DBUFFER_DIM:
2243         {
2244             OMX_CONFIG_RECTTYPE frame;
2245             OMX_STRUCT_INIT(frame, OMX_CONFIG_RECTTYPE, mLocalVersion);
2246             VisionCamResType *pRes = (VisionCamResType *)param;
2248             frame.nPortIndex = mCurGreContext.mPortsInUse[port];
2249             if (pRes && size == sizeof(VisionCamResType))
2250             {
2251                 // Set the port definition to update width and height first.
2252                 omxError = setPortDef( port );
2254                 if( OMX_ErrorNone == omxError )
2255                 {
2256                     omxError = OMX_GetParameter(mCurGreContext.mHandleComp,
2257                                                 (OMX_INDEXTYPE)OMX_TI_IndexParam2DBufferAllocDimension,
2258                                                 &frame);
2259                 }
2261                 if (OMX_ErrorNone == omxError)
2262                 {
2263                     pRes->mWidth = frame.nWidth;
2264                     pRes->mHeight = frame.nHeight;
2265                 }
2266                 else
2267                 {
2268                     ERROR("Failed to query the 2D Buffer Dimensions! (err=0x%08x)", omxError);
2269                     memset(pRes, 0, sizeof(VisionCamResType));
2270                     // omxError will convert to greError
2271                 }
2272             }
2273             else
2274                 greError = -EINVAL;
2275             break;
2276         }
2278         case VCAM_PARAM_MANUAL_EXPOSURE:
2279         {
2280             OMX_CONFIG_EXPOSUREVALUETYPE expValues;
2281             OMX_STRUCT_INIT(expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion);
2283             omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
2285             if( OMX_ErrorNone == omxError )
2286             {
2287                 if( OMX_TRUE == expValues.bAutoShutterSpeed )
2288                 {
2289                     *(OMX_U32*)param = 0;
2290                 }
2291                 else
2292                 {
2293                     *(OMX_U32*)param = expValues.nShutterSpeedMsec;
2294                 }
2295             }
2296             break;
2297         }
2299         case VCAM_PARAM_EXPOSURE_ISO:
2300         {
2301             OMX_CONFIG_EXPOSUREVALUETYPE expValues;
2302             OMX_STRUCT_INIT( expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion );
2304             omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
2306             if( OMX_ErrorNone == omxError )
2307             {
2308                 if( OMX_TRUE == expValues.bAutoSensitivity )
2309                 {
2310                     *(uint32_t*)param = 0;
2311                 }
2312                 else
2313                     *(uint32_t*)param = expValues.nSensitivity;
2314             }
2315             break;
2316         }
2318         case VCAM_PARAM_AWB_MODE:
2319         {
2320             OMX_CONFIG_WHITEBALCONTROLTYPE wb;
2321             OMX_STRUCT_INIT(wb, OMX_CONFIG_WHITEBALCONTROLTYPE, mLocalVersion );
2323             omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
2324                                  OMX_IndexConfigCommonWhiteBalance,
2325                                  &wb);
2327             if( OMX_ErrorNone == omxError )
2328             {
2329                 *(int *)param = (int)wb.eWhiteBalControl;
2330             }
2331             break;
2332         }
2334         case VCAM_PARAM_COLOR_TEMP:
2335         {
2336             ERROR("No Getting Api for this Parameter %d", paramId);
2337             break;
2338         }
2339         case VCAM_PARAM_WB_COLOR_GAINS:
2340         {
2341 #ifdef USE_WB_GAIN_PATCH
2342             OMX_TI_CONFIG_SHAREDBUFFER skipBuffer;
2344             skipBuffer.nSize = sizeof( OMX_TI_CONFIG_SHAREDBUFFER );
2345             memcpy( &skipBuffer.nVersion , mLocalVersion , sizeof(mLocalVersion) );
2346             skipBuffer.pSharedBuff = (OMX_U8*)mWBbuffer;
2347             skipBuffer.nSharedBuffSize = sizeof(mWBbuffer);
2349             omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
2350                                     (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
2351                                     &skipBuffer );
2353             if( OMX_ErrorNone == omxError )
2354             {
2355                 VisionCamWhiteBalGains wbGains;
2356                 uint16_t * tmp;
2357                 CALCULATE_WB_GAINS_OFFSET(uint16_t, mWBbuffer, tmp );
2359                 wbGains.mRed = tmp[ RED ];
2360                 wbGains.mGreen_r = tmp[ GREEN_RED ];
2361                 wbGains.mGreen_b = tmp[ GREEN_BLUE ];
2362                 wbGains.mBlue = tmp[ BLUE ];
2364                 *((VisionCamWhiteBalGains*)param) = wbGains;
2365             }
2366 #endif // USE_WB_GAIN_PATCH
2367             break;
2368         }
2370         case VCAM_PARAM_GAMMA_TBLS:
2371         {
2373             VisionCamGammaTableType *gammaTbl = (VisionCamGammaTableType*)param;
2374             OMX_TI_CONFIG_SHAREDBUFFER skipBuffer;
2375             skipBuffer.nSize = sizeof( OMX_TI_CONFIG_SHAREDBUFFER );
2376             memcpy( &skipBuffer.nVersion , mLocalVersion , sizeof(mLocalVersion) );
2378             skipBuffer.pSharedBuff = (OMX_U8*)mGammaTablesBuf;
2379             skipBuffer.nSharedBuffSize = sizeof(mGammaTablesBuf);
2381             omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
2382                                 (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
2383                                 &skipBuffer );
2385             if( OMX_ErrorNone == omxError )
2386             {
2387                 gammaTbl->mTableSize     = GAMMA_TABLE_SIZE;
2389                 uint32_t* base = (uint32_t *)(mGammaTablesBuf + 12); // 12 bytes offset for red table
2390                 gammaTbl->mRedTable      = (uint16_t*)(base[0] + (uint32_t)&base[2]);
2391                 gammaTbl->mBlueTable     = (uint16_t*)(base[1] + (uint32_t)&base[2]);
2392                 gammaTbl->mGreenTable    = (uint16_t*)(base[2] + (uint32_t)&base[2]);
2393             }
2394             break;
2395         }
2397         case VCAM_PARAM_ROTATION:
2398         {
2399             OMX_CONFIG_ROTATIONTYPE rotation;
2400             OMX_STRUCT_INIT(rotation, OMX_CONFIG_ROTATIONTYPE, mLocalVersion);
2401             omxError = OMX_GetConfig(mCurGreContext.mHandleComp,
2402                                      OMX_IndexConfigCommonRotate,
2403                                      &rotation);
2404             if (OMX_ErrorNone == omxError)
2405                 *((OMX_S32*)param) = rotation.nRotation;
2406             break;
2407         }
2409         case VCAM_PARAM_MIRROR:
2410         {
2411             if( VCAM_PORT_ALL == port )
2412             {
2413                 greError = -EINVAL;
2414             }
2415             else
2416             {
2417                 int i;
2418                 OMX_CONFIG_MIRRORTYPE mirror;
2419                 mirror.nSize = sizeof( OMX_CONFIG_MIRRORTYPE );
2420                 mirror.nPortIndex = mCurGreContext.mPortsInUse[port];
2421                 memcpy( &mirror.nVersion, mLocalVersion, sizeof(mLocalVersion));
2423                 omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
2424                                         OMX_IndexConfigCommonMirror,
2425                                         &mirror );
2427                 if( OMX_ErrorNone == omxError )
2428                 {
2429                     for( i = 0; i < VCAM_MIRROR_MAX; i++ )
2430                     {
2431                         if( MirrorTypeLUT[i][1] == mirror.eMirror )
2432                         {
2433                           *((VisionCamMirrorType*)param) = (VisionCamMirrorType) MirrorTypeLUT[i][0];
2434                           break;
2435                         }
2436                     }
2438                 if( i >= VCAM_MIRROR_MAX )
2439                     greError = -EINVAL;
2440                 }
2441             }
2442             break;
2443         }
2445 #if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
2446         case VCAM_PARAM_AWB_MIN_DELAY_TIME:
2447         {
2448             uint32_t *timeDelay = (uint32_t*)param;
2449             OMX_TI_CONFIG_AE_DELAY aeDelay;
2450             OMX_STRUCT_INIT( aeDelay, OMX_TI_CONFIG_AE_DELAY, mLocalVersion );
2452             omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
2453                                     ( OMX_INDEXTYPE )OMX_TI_IndexConfigAutoExpMinDelayTime,
2454                                     &aeDelay
2455                                   );
2456             if( OMX_ErrorNone == omxError )
2457             {
2458                 *timeDelay = aeDelay.nDelayTime;
2459             }
2460             break;
2461         }
2462 #endif
2463 #if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_GESTURES)
2464         case VCAM_PARAM_GESTURES_INFO:
2465         {
2466             VisionCamGestureInfo *info = (VisionCamGestureInfo *)param;
2467             OMX_TI_CONFIG_GESTURES_INFO gestInfo;
2468             int ret = 0;
2470             OMX_STRUCT_INIT( gestInfo, OMX_TI_CONFIG_GESTURES_INFO , mLocalVersion );
2472             omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
2473                                     (OMX_INDEXTYPE)OMX_TI_IndexConfigDetectedGesturesInfo,
2474                                     &gestInfo
2475                                   );
2477             if( OMX_ErrorNone != omxError )
2478                 break;
2480             ret = (VisionCamGestureEvent_e)getLutValue( gestInfo.eType, OMX_VALUE_TYPE,
2481                                                         GestureTypeLUT, ARR_SIZE(GestureTypeLUT)
2482                                                         );
2484             if( -EINVAL == (int)ret )
2485             {
2486                 greError = -EINVAL;
2487             }
2488             else
2489             {
2490                 info->mGestureType = (VisionCamGestureEvent_e)ret;
2491                 info->mRegionsNum = gestInfo.nNumDetectedGestures;
2492                 if( info->mRegionsNum >= VCAM_Max_Gesture_Per_Frame )
2493                 {
2494                     greError= -EINVAL;
2495                     break;
2496                 }
2498             #ifdef __cplusplus
2499                 info->mRegions = new VisionCamObjectRectType[ info->mRegionsNum ];
2500             #else
2501                 if( NULL == info->mRegions )
2502                 {
2503                     ERROR("Please allocate the mRegions buffer");
2504                     ERROR("Check for necessery size in mRegionsNum");
2506                     greError= STATUS_NO_RESOURCES;
2507                     break;
2508                 }
2509             #endif
2511                 for(uint32_t i = 0; i < info->mRegionsNum; i++ )
2512                 {
2513                     info->mRegions[i].mObjType= (VisionCamObjectType)getLutValue(
2514                                                                                     (int)(gestInfo.nGestureAreas[i].eType),
2515                                                                                     OMX_VALUE_TYPE,
2516                                                                                     ObjectTypeLUT,
2517                                                                                     ARR_SIZE(ObjectTypeLUT)
2518                                                                                 );
2520                     gestInfo.nGestureAreas[i].nTop = info->mRegions[i].mTop;
2521                     gestInfo.nGestureAreas[i].nLeft = info->mRegions[i].mLeft;
2522                     gestInfo.nGestureAreas[i].nWidth = info->mRegions[i].mWidth;
2523                     gestInfo.nGestureAreas[i].nHeight = info->mRegions[i].mHeight;
2524                 }
2526                 info->timeStamp = gestInfo.nTimeStamp;
2527             }
2529             break;
2530         }
2531 #endif
2532 #if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
2533         case VCAM_PARAM_AGC_MIN_DELAY_TIME:
2534         {
2535             uint32_t *delay = (uint32_t*)param;
2536             OMX_TI_CONFIG_AE_DELAY agcDelTime;
2537             OMX_STRUCT_INIT( agcDelTime, OMX_TI_CONFIG_AE_DELAY, mLocalVersion );
2539             omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
2540                                     (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpMinDelayTime,
2541                                     &agcDelTime );
2543             if( OMX_ErrorNone != omxError )
2544                 break;
2546             *delay = agcDelTime.nDelayTime;
2547             break;
2548         }
2550         case VCAM_PARAM_AGC_LOW_TH:
2551         {
2552             uint32_t *lowTH = (uint32_t*)param;
2553             OMX_TI_CONFIG_AE_THRESHOLD ae;
2555             OMX_STRUCT_INIT( ae, OMX_TI_CONFIG_AE_THRESHOLD, mLocalVersion );
2557             omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
2559             if( OMX_ErrorNone != omxError )
2560                 break;
2562             *lowTH = ae.uMinTH;
2563             break;
2564         }
2566         case VCAM_PARAM_AGC_HIGH_TH:
2567         {
2568             uint32_t *highTH = (uint32_t*)param;
2570             OMX_TI_CONFIG_AE_THRESHOLD ae;
2571             OMX_STRUCT_INIT( ae, OMX_TI_CONFIG_AE_THRESHOLD, mLocalVersion );
2573             omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
2575             if( OMX_ErrorNone != omxError )
2576                 break;
2578             *highTH = ae.uMaxTH;
2579             break;
2580         }
2581 #endif
2583         default:
2584         {
2585             ERROR("Impossible parameter id requested: %d", paramId);
2586             ERROR("see VisionCamParam_e for possible parameter ids");
2587             greError = -EINVAL;
2588         }
2589     }
2591     if( OMX_ErrorNone != omxError )
2592     {
2593         greError = ConvertError(omxError);
2594     }
2596     if( greError != 0 )
2597     {
2598         ERROR("getParameter() exits with error 0x%x (dec: %d) for param id %d", greError, greError, paramId);
2599     }
2601     return greError;
2604 OMX_ERRORTYPE OMXVisionCam::getFocusStatus(OMX_FOCUSSTATUSTYPE *status)
2606     OMX_ERRORTYPE eError = OMX_ErrorNone;
2607     OMX_PARAM_FOCUSSTATUSTYPE focusStatus;
2608     OMX_STRUCT_INIT(focusStatus, OMX_PARAM_FOCUSSTATUSTYPE, mLocalVersion);
2610     // Get the focus status
2611     OMX_CHECK(eError,OMX_GetConfig(mCurGreContext.mHandleComp,
2612                                    OMX_IndexConfigCommonFocusStatus,
2613                                    &focusStatus));
2614     if (eError == OMX_ErrorNone)
2615         *status = focusStatus.eFocusStatus;
2616     return eError;
2619 int OMXVisionCam::waitForFocus()
2621     OMX_ERRORTYPE omxError = OMX_ErrorNone;
2622     OMX_FOCUSSTATUSTYPE focusStatus;
2624     omxError = RegisterForEvent(mCurGreContext.mHandleComp,
2625                               (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
2626                               OMX_ALL,
2627                               OMX_IndexConfigCommonFocusStatus,
2628                               &mGreFocusSem,
2629                               -1);
2630     if (OMX_ErrorNone == omxError)
2631     {
2632         OMX_CONFIG_CALLBACKREQUESTTYPE focusRequestCallback;
2633         OMX_STRUCT_INIT(focusRequestCallback, OMX_CONFIG_CALLBACKREQUESTTYPE, mLocalVersion);
2634         focusRequestCallback.bEnable = OMX_TRUE;
2635         focusRequestCallback.nIndex = OMX_IndexConfigCommonFocusStatus;
2637         // subscribe for focus state changes
2638         OMX_CHECK(omxError,OMX_SetConfig(mCurGreContext.mHandleComp,
2639                                        (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest,
2640                                        &focusRequestCallback));
2641 #ifdef VCAM_CAUTIOUS
2642         // make sure it's been registered
2643         OMX_CHECK(omxError,OMX_GetConfig(mCurGreContext.mHandleComp,
2644                                        (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest,
2645                                        &focusRequestCallback));
2647 #endif
2648         if (OMX_ErrorNone == omxError && focusRequestCallback.bEnable == OMX_TRUE)
2649         {
2650             MSG("Waiting for Focus Callback!");
2651             // wait for focus to arrive
2652             sem_wait(&mGreFocusSem);
2654             // Give the client the focus greError
2655             omxError = getFocusStatus(&focusStatus);
2656             MSG("Focus Status: %u", focusStatus);
2657             if (OMX_ErrorNone == omxError)
2658             {
2659                 if (m_focuscallback)
2660                     m_focuscallback((int)focusStatus);
2661             }
2662         }
2663     }
2664     return ConvertError(omxError);
2667 int OMXVisionCam::startAutoFocus( VisionCamFocusMode focusMode )
2669     int i;
2670     OMX_ERRORTYPE omxError = OMX_ErrorNone;
2671     bool haveEvent = true;
2672     OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focus;
2674     if (focusMode == VCAM_FOCUS_CONTROL_OFF ||
2675         focusMode == VCAM_FOCUS_CONTROL_AUTO ||
2676         focusMode == VCAM_FOCUS_CONTROL_CONTINOUS_NORMAL ||
2677         focusMode == VCAM_FOCUS_CONTROL_CONTINOUS_EXTENDED)
2678     {
2679         haveEvent = false;
2680     }
2682     // initialize the structure
2683     OMX_STRUCT_INIT(focus, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE, mLocalVersion);
2684     for( i = 0 ; i < VCAM_FOCUS_CONTROL_MAX ; i++ )
2685     {
2686         if( FocusModeLUT[ i ][ 0 ] == focusMode )
2687         {
2688             focus.eFocusControl = ( OMX_IMAGE_FOCUSCONTROLTYPE )FocusModeLUT[ i ][ 1 ];
2689             if( focus.eFocusControl == OMX_IMAGE_FocusControlOn )
2690                 focus.nFocusSteps = mManualFocusDistance;
2691             break;
2692         }
2693     }
2695     if (i == VCAM_FOCUS_CONTROL_MAX)
2696     {
2697         ERROR("Unsupported focus mode requested: %d", focusMode );
2698         return -EINVAL;
2699     }
2701     MSG("Focus Requested Steps @ %lu, Index @ %lu", focus.nFocusSteps, focus.nFocusStepIndex);
2703     // tell the OMX component to change the focus control mode
2704     OMX_CHECK(omxError,OMX_SetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigFocusControl, &focus));
2705 #ifdef VCAM_CAUTIOUS
2706     // ask it what mode it's in now
2707     OMX_CHECK(omxError, OMX_GetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigFocusControl, &focus));
2708 #endif
2709     MSG("Focus Control Mode = 0x%08x", focus.eFocusControl);
2710     if (OMX_ErrorNone == omxError && focus.eFocusControl != OMX_IMAGE_FocusControlOff)
2711     {
2712         if (haveEvent)
2713         {
2714             pthread_t thread;
2715             pthread_create(&thread, NULL, FocusThreadLauncher, this);
2716             // the thread will die by itself, we don't need to join it.
2717         }
2718     }
2720     return ConvertError(omxError);
2723 /* This will set the preview buffer sizzes, format, etc.
2724     */
2725 OMX_ERRORTYPE OMXVisionCam::setPortDef( int port )
2727     OMX_ERRORTYPE omxError = OMX_ErrorNone;
2729         VCAM_PortParameters * portData = NULL;
2730         OMX_PARAM_PORTDEFINITIONTYPE portCheck;
2732         int32_t p;
2733         LOOP_PORTS( port , p )
2734         {
2735             omxError = initPortCheck(&portCheck, p);
2737             if( omxError == OMX_ErrorNone )
2738             {
2739                 portData =  &mCurGreContext.mCameraPortParams[p];
2740                 portCheck.format.video.nFrameWidth  = portData->mWidth;
2741                 portCheck.format.video.nFrameHeight = portData->mHeight;
2742                 portCheck.format.video.eColorFormat = portData->mColorFormat;
2743                 portCheck.format.video.nStride      = portData->mStride;
2744                 portCheck.format.video.xFramerate   = portData->mFrameRate << 16;
2745                 portCheck.nBufferCountActual        = portData->mNumBufs;
2747                 omxError = OMX_SetParameter(mCurGreContext.mHandleComp,
2748                                           OMX_IndexParamPortDefinition,
2749                                           &portCheck);
2750             }
2752             if( omxError == OMX_ErrorNone )
2753                 omxError = initPortCheck(&portCheck, p);
2755             if( omxError == OMX_ErrorNone )
2756                 portData->mBufSize = portCheck.nBufferSize;
2758 #if defined(VCAM_SET_FORMAT_ROTATION)
2759 // set the rotation type on the port
2760 if ( omxError == OMX_ErrorNone)
2762     OMX_CONFIG_ROTATIONTYPE rotType;
2763     OMX_STRUCT_INIT(rotType, OMX_CONFIG_ROTATIONTYPE, mLocalVersion);
2764     rotType.nRotation = mCurGreContext.mCameraPortParams[p].mRotation;
2765     rotType.nPortIndex = mCurGreContext.mPortsInUse[p];
2766     MSG("VCAM: Configuring for Rotation %li",rotType.nRotation);
2767     OMX_CHECK(omxError, OMX_SetConfig(mCurGreContext.mHandleComp,
2768                                       OMX_IndexConfigCommonRotate,
2769                                       &rotType));
2771 #endif
2772         }
2774     return omxError;
2777 /* This will start the preview.
2778  * Before that setParameter() sould be called, to configure the preview port.
2779  * This method is only called internal for OMXVisionCam
2780  * by sendCommand().
2781  */
2782 int OMXVisionCam::startPreview( VisionCamPort_e port )
2784     int greError = 0;
2786     if( port < VCAM_PORT_ALL || port > VCAM_PORT_MAX - 1 )
2787     {
2788         ERROR("startPreview() called, but port is not specified properly.");
2789         return -EINVAL;
2790     }
2792     mFlushInProcess = false;
2794     switch((int)getComponentState())
2795     {
2796         case OMX_StateIdle:
2797         {
2798             greError = transitToState( OMX_StateExecuting );
2799             mReturnToExecuting = true;
2800             break;
2801         }
2802         case OMX_StateLoaded:
2803         case OMX_StateWaitForResources:
2804         case OMX_StateInvalid:
2805         {
2806             ERROR("Calling startPreview() in an inproper state.");
2807             greError = -EBADE;
2808             break;
2809         }
2810         case OMX_StateExecuting:
2811         case OMX_StatePause:
2812         {
2813             break;
2814         }
2815         default:
2816             break;
2817     }
2819     AutoLock lock(&mFrameBufferLock);
2821     OMX_ERRORTYPE omxError;
2822     omxError = setPortDef( port );
2823     greError = ConvertError(omxError);
2825     if( 0 == greError )
2826     {
2827         greError = portEnableDisable( OMX_CommandPortEnable, populatePortSrvc, port);
2828     }
2830     if( 0 == greError )
2831     {
2832         // first fill the video port buffers, then preview port
2833         // otherwise preview port will start working right after it receive its frames
2834         // so it won't wait for video port to get ready
2835         if( VCAM_PORT_ALL == port || VCAM_PORT_VIDEO == port )
2836         {
2837             greError = fillPortBuffers(VCAM_PORT_VIDEO);
2838         }
2840         if( VCAM_PORT_ALL == port || VCAM_PORT_PREVIEW == port )
2841         {
2842             greError = fillPortBuffers(VCAM_PORT_PREVIEW);
2843         }
2844     }
2846     return greError;
2849 /**
2850   * This will stop the preview
2851   *
2852   */
2853 int OMXVisionCam::stopPreview( VisionCamPort_e port )
2855     int greError = 0;
2856     bool goToIdle = true;
2858     mFlushInProcess = true;
2860     flushBuffers( port );
2861     greError = portEnableDisable( OMX_CommandPortDisable, freePortBuffersSrvc, port );
2863     if( 0 == greError )
2864     {
2865         for( int p = VCAM_PORT_PREVIEW; p < VCAM_PORT_MAX; p++)
2866         {
2867             if( mCurGreContext.mCameraPortParams[p].mIsActive )
2868             {
2869                 goToIdle = false;
2870                 break;
2871             }
2872         }
2874         if ( goToIdle && OMX_StateExecuting == getComponentState() )
2875         {
2876             transitToState( OMX_StateIdle );
2877         }
2878     }
2880     return greError;
2883 /**
2884   * This will free all the buffers on the preview port
2885   * and switch to loaded state.
2886   */
2887 int OMXVisionCam::releaseBuffers( VisionCamPort_e port)
2889     int greError = 0;
2891     OMX_PARAM_PORTDEFINITIONTYPE portCheck[ VCAM_PORT_MAX ];
2893     int32_t p;
2894     LOOP_PORTS( port , p )
2895     {
2896         initPortCheck(&portCheck[p], p);
2898         for( uint32_t indBuff = 0; indBuff < portCheck[p].nBufferCountActual; indBuff++ )
2899         {
2900             if( mFrameDescriptors && mFrameDescriptors[p] && mFrameDescriptors[p][indBuff] )
2901                 delete mFrameDescriptors[p][indBuff];
2902         }
2904         if( mFrameDescriptors && mFrameDescriptors[p] )
2905         {
2906             delete mFrameDescriptors[p];
2907             mFrameDescriptors[p] = NULL;
2908         }
2909     }
2911     if (OMX_StateIdle == getComponentState())
2912         transitToState( OMX_StateLoaded, NULL, NULL );
2914     return greError;
2917 /** This will configure the component to start/stop face detection.
2918  * Will also start/stop face detection extra data
2919  * faces coordinates will be written into camera frame received
2920  * in preview callback
2921  */
2922 int OMXVisionCam::enableFaceDetect(VisionCamPort_e port)
2924     OMX_ERRORTYPE omxError = OMX_ErrorNone;
2925     OMX_CONFIG_OBJDETECTIONTYPE objDetection;
2926     OMX_STRUCT_INIT( objDetection, OMX_CONFIG_OBJDETECTIONTYPE ,mLocalVersion);
2927     objDetection.nPortIndex = mCurGreContext.mPortsInUse[port];
2929     if (mFaceDetectionEnabled)
2930         objDetection.bEnable = OMX_TRUE;
2931     else
2932         objDetection.bEnable = OMX_FALSE;
2934     omxError = OMX_SetConfig(mCurGreContext.mHandleComp, (OMX_INDEXTYPE) OMX_IndexConfigImageFaceDetection, &objDetection);
2935     if( OMX_ErrorNone == omxError )
2936     {
2937         OMX_CONFIG_EXTRADATATYPE xData;
2938         OMX_STRUCT_INIT(xData, OMX_CONFIG_EXTRADATATYPE, mLocalVersion);
2940         xData.nPortIndex        = mCurGreContext.mPortsInUse[port];
2941         xData.eExtraDataType    = OMX_FaceDetection;
2942 #if defined(TUNA) || defined(MAGURO)
2943         xData.eCameraView       = OMX_2D_Prv;
2944 #endif
2945         if (mFaceDetectionEnabled)
2946             xData.bEnable = OMX_TRUE;
2947         else
2948             xData.bEnable = OMX_FALSE;
2950         OMX_CHECK(omxError,OMX_SetConfig(mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigOtherExtraDataControl, &xData));
2951     }
2952     return ConvertError(omxError);
2955 /** Fill the face coordinates field in camera frame,
2956  *  which will be received by OMXVisionCam client at each frame.
2957  */
2958 void OMXVisionCam::getFacesCoordinates( VisionCamFrame *frame)
2960     OMX_OTHER_EXTRADATATYPE* extraData = (OMX_OTHER_EXTRADATATYPE*)frame->mExtraDataBuf;
2961     OMX_U8 *pExtraLimit = (OMX_U8 *)extraData + frame->mExtraDataLength;
2962     OMX_FACEDETECTIONTYPE *facesData;
2963     if( extraData == NULL )
2964     {
2965         frame->mDetectedFacesNum = 0;
2966         return;
2967     }
2969     // find the faces data buffers
2970     while( (OMX_EXTRADATATYPE)OMX_FaceDetection != extraData->eType && extraData->data )
2971     {
2972         MSG("Current Extra Data Section Size: %lu", extraData->nDataSize);
2973         extraData = (OMX_OTHER_EXTRADATATYPE*)(extraData->data + extraData->nDataSize);
2975         if( (OMX_U8 *)extraData >= pExtraLimit )
2976         {
2977             ERROR("ERROR: METADATA: Bad size field in metadata. %p >= %p", extraData, pExtraLimit);
2978             return;
2979         }
2981         if( 0 == extraData->nDataSize )
2982         {
2983             ERROR("METADATA: No face data detected!");
2984             frame->mDetectedFacesNum = 0;
2985             memset( frame->mFaces, 0, MAX_FACES_COUNT*sizeof(VisionCamFaceType) );
2986             return;
2987         }
2988     }
2990     if( extraData->data )
2991     {
2992         facesData = (OMX_FACEDETECTIONTYPE *)(extraData->data);
2994         frame->mDetectedFacesNum = facesData->ulFaceCount;
2996         MSG("METADATA: FACE # %d!", frame->mDetectedFacesNum);
2998         for(uint32_t i = 0; i < frame->mDetectedFacesNum; i++)
2999         {
3000             memcpy( &(frame->mFaces[i]), &(facesData->tFacePosition[i].nScore), sizeof(VisionCamFaceType)) ;
3001         }
3002     }
3005 /** Parse through the extra data type structure to find the pointer to the relevent
3006  *  data type.  This is to abstract the port number, version, and packet structure from the client.
3007  */
3008 void OMXVisionCam::getMetadataPtrs( VisionCamFrame *frame)
3010     OMX_OTHER_EXTRADATATYPE* extraData = (OMX_OTHER_EXTRADATATYPE*)frame->mExtraDataBuf;
3011     OMX_U8 *pExtraLimit = (OMX_U8 *)extraData + frame->mExtraDataLength;
3012     frame->mMetadata.mAutoWBGains = NULL;
3013     frame->mMetadata.mManualWBGains = NULL;
3014     frame->mMetadata.mAncillary = NULL;
3015     frame->mMetadata.mHistogram2D = NULL;
3016     frame->mMetadata.mHistogramL = NULL;
3017     frame->mMetadata.mHistogramR = NULL;
3019     if( extraData == NULL )
3020     {
3021         return;
3022     }
3024     while( extraData->eType && extraData->nDataSize && extraData->data )   // keep looping while there is more extra data and double check size
3025     {
3026         switch( extraData->eType )
3027         {
3028             case OMX_AncillaryData:
3029             {
3030                 OMX_TI_ANCILLARYDATATYPE *ancillaryData = NULL;
3031                 MSG("METADATA: Found Ancillary Data Section!");
3032                 ancillaryData =  (OMX_TI_ANCILLARYDATATYPE  *)(extraData->data);
3033                 frame->mMetadata.mAncillary= (VisionCamAncillary*)&ancillaryData->nAncillaryDataVersion;
3034                 break;
3035             }
3037             case OMX_WhiteBalance:
3038             {
3039                 OMX_TI_WHITEBALANCERESULTTYPE *wbData = NULL;
3040                 MSG("METADATA: Found White Balance Result Data Section!");
3041                 wbData =  (OMX_TI_WHITEBALANCERESULTTYPE  *)(extraData->data);
3042                 frame->mMetadata.mAutoWBGains = (VisionCamWhiteBalGains*)&wbData->nGainR;
3043                 break;
3044             }
3045 #ifndef __QNX__
3046             case OMX_TI_WhiteBalanceOverWrite:
3047             {
3048                 OMX_TI_WHITEBALANCERESULTTYPE *wbManData = NULL;
3049                 MSG("METADATA: Found White Balance Overwrite Data Section!");
3050                 wbManData =  (OMX_TI_WHITEBALANCERESULTTYPE  *)(extraData->data);
3051                 frame->mMetadata.mManualWBGains = (VisionCamWhiteBalGains*)&wbManData->nGainR;
3052                 break;
3053             }
3054 #endif
3055 #if defined(DUCATI_2_0)
3056             case OMX_Histogram:
3057             {
3058                 OMX_TI_HISTOGRAMTYPE *histData = NULL;
3059                 MSG("METADATA: Found Histogram Result Data Section!");
3060                 histData =  (OMX_TI_HISTOGRAMTYPE  *)(extraData->data);
3061 #if defined(TUNA) || defined(MAGURO) || 1
3062                 if((OMX_TI_CAMERAVIEWTYPE)(histData->eCameraView) == OMX_2D_Prv)
3063                     frame->mMetadata.mHistogram2D = (VisionCamHistogram*)&histData->nBins;
3064                 else if((OMX_TI_CAMERAVIEWTYPE)(histData->eCameraView) == OMX_3D_Left_Prv)
3065                     frame->mMetadata.mHistogramL = (VisionCamHistogram*)&histData->nBins;
3066                 else if((OMX_TI_CAMERAVIEWTYPE)(histData->eCameraView) == OMX_3D_Right_Prv)
3067                     frame->mMetadata.mHistogramR = (VisionCamHistogram*)&histData->nBins;
3068 #else
3069                 frame->mMetadata.mHistogram2D = (VisionCamHistogram*)&histData->nBins;
3070 #endif
3071                 break;
3072             }
3073 #endif
3074             default:
3075             {
3076                 break;
3077             }
3078         }
3079         MSG("Current Extra Data Section Size: %lu", extraData->nDataSize);
3080         extraData = (OMX_OTHER_EXTRADATATYPE*)(extraData->data + extraData->nDataSize);
3081         if( (OMX_U8 *)extraData >= pExtraLimit )
3082         {
3083             ERROR("ERROR: METADATA: Bad size field in metadata. %p >= %p", extraData, pExtraLimit);
3084             break;
3085         }
3086     }
3089 /** This shall be called by the user of this class when it finishes working
3090  * with the frame and to notify VisionCam that the frame buffer is
3091  * free.
3092  */
3093 int OMXVisionCam::returnFrame(VisionCamFrame *cameraFrame)
3095     OMX_ERRORTYPE omxError = OMX_ErrorNone;
3096     int32_t i = 0;
3097     if (mFlushInProcess)
3098         return 0;
3100     if (cameraFrame == NULL)
3101         return -EINVAL;
3103     if (OMX_StateExecuting == getComponentState())
3104     {
3105         VisionCamPort_e port = cameraFrame->mFrameSource;
3106         VCAM_PortParameters * portData = &mCurGreContext.mCameraPortParams[port];
3107         for (i = 0; i < portData->mNumBufs; i++)
3108         {
3109             if (portData->mBufferHeader[i] &&
3110                 portData->mBufferHeader[i]->pAppPrivate == cameraFrame->mFrameBuff)
3111             {
3112                 omxError = OMX_FillThisBuffer(mCurGreContext.mHandleComp,
3113                                               mCurGreContext.mCameraPortParams[port].mBufferHeader[i]);
3114                 if (OMX_ErrorNone != omxError)
3115                 {
3116                     ERROR("ERROR: OMX_FillThisBuffer() returned 0x%x in %s", omxError, __func__);
3117                 }
3118                 else
3119                 {
3120                     MSG("frame returned successfully in %s", __func__);
3121                 }
3122                 break;
3123             }
3124         }
3125         if( i == portData->mNumBufs)
3126         {
3127             ERROR("ERROR: returned frame not found in %s", __func__);
3128         }
3129     }
3130     else
3131     {
3132         ERROR("Returning Frame when OMX-CAMERA is in the wrong state or image is NULL");
3133     }
3135     return ConvertError(omxError);
3138 int OMXVisionCam::PreemptionService(/*VisionCamPreemptionActivity_e activity*/)
3140     OMX_ERRORTYPE omxError = OMX_ErrorNone;
3141     VCAM_PortParameters * portData = NULL;
3143     switch( mPreemptionState )
3144     {
3145         case VCAM_PREEMPT_SUSPEND:
3146         {
3147             // Register for Loaded state switch event
3148             omxError = RegisterForEvent(mCurGreContext.mHandleComp,
3149                                          OMX_EventCmdComplete,
3150                                          OMX_CommandStateSet,
3151                                          OMX_StateLoaded,
3152                                          &mGreLocalSem,
3153                                          -1); // Infinite timeout
3155             if( OMX_ErrorNone == omxError )
3156             {
3157                 for( int port = VCAM_PORT_PREVIEW; port < VCAM_PORT_MAX; port++ )
3158                 {
3159                     // Free the OMX Buffers
3160                     portData = &mCurGreContext.mCameraPortParams[port];
3161                     for( int i = 0; i < portData->mNumBufs; i++ )
3162                     {
3163                         omxError = OMX_FreeBuffer(mCurGreContext.mHandleComp,
3164                                                         mCurGreContext.mPortsInUse[port],
3165                                                         portData->mBufferHeader[i]);
3167                         portData->mBufferHeader[i] = NULL;
3169                         if( OMX_ErrorNone != omxError )
3170                         {
3171                             ERROR("Preemption Service: Error 0x%x while freeing buffers!", omxError);
3172                             break;
3173                         }
3174                     }
3175                 }
3176             }
3178             if( OMX_ErrorNone == omxError )
3179                 sem_wait(&mGreLocalSem);
3181             if( mClientNotifier.mNotificationCallback && OMX_ErrorNone == omxError )
3182                 mClientNotifier.mNotificationCallback(VisionCamClientNotifier::VCAM_MESSAGE_PREEMPT_SUSPEND_ACTIVITY);
3184             // Register for WAIT state switch event
3185             omxError = RegisterForEvent(mCurGreContext.mHandleComp,
3186                                          OMX_EventCmdComplete,
3187                                          OMX_CommandStateSet,
3188                                          OMX_StateWaitForResources,
3189                                          &mGreLocalSem,
3190                                          -1); // Infinite timeout
3192             if( OMX_ErrorNone == omxError  )
3193             {
3194               omxError = OMX_SendCommand(mCurGreContext.mHandleComp,
3195                                             OMX_CommandStateSet,
3196                                             OMX_StateWaitForResources,
3197                                             NULL);
3198             }
3200             if( OMX_ErrorNone == omxError  )
3201               sem_wait(&mGreLocalSem);
3203             break;
3204         }
3205         case VCAM_PREEMPT_RESUME:
3206         {
3207             if( mClientNotifier.mNotificationCallback )
3208                 mClientNotifier.mNotificationCallback(VisionCamClientNotifier::VCAM_MESSAGE_PREEMPT_RESUME_ACTIVITY);
3210             // Register for IDLE state switch event
3211             omxError = RegisterForEvent(mCurGreContext.mHandleComp,
3212                                            OMX_EventCmdComplete,
3213                                            OMX_CommandStateSet,
3214                                            OMX_StateIdle,
3215                                            &mGreLocalSem,
3216                                            -1); //Infinite timeout
3217             if( OMX_ErrorNone != omxError )
3218             {
3219                 ERROR("Preemption Service: Error 0x%x while registering for Idle state wait.", omxError);
3220                 break;
3221             }
3223             for( int port = VCAM_PORT_PREVIEW; port < VCAM_PORT_MAX; port++ )
3224             {
3225                 portData = &mCurGreContext.mCameraPortParams[port];
3226                 for( int buff = 0; buff < portData->mNumBufs; buff++ )
3227                 {
3228                     OMX_BUFFERHEADERTYPE *pBufferHdr;
3229                     OMX_U8 *buffer = (OMX_U8*)mBuffersInUse[port].mBuffers[buff].fd;
3231                     omxError = OMX_UseBuffer(   mCurGreContext.mHandleComp,
3232                                                 &pBufferHdr,
3233                                                 mCurGreContext.mPortsInUse[port],
3234                                                 0,
3235                                                 portData->mBufSize,
3236                                                 buffer
3237                                             );
3239                     if( OMX_ErrorNone != omxError )
3240                     {
3241                         ERROR("Preemption Service: Error 0x%x while passing buffers to OMX Component.", omxError);
3242                         break;
3243                     }
3245                     pBufferHdr->pAppPrivate = (OMX_PTR)&mBuffersInUse[port].mBuffers[buff];
3247                     pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
3249                     memcpy( &(pBufferHdr->nVersion), mLocalVersion, sizeof( OMX_VERSIONTYPE ) );
3251                     portData->mBufferHeader[buff] = pBufferHdr;
3252                 }
3253             }
3255             sem_wait(&mGreLocalSem);
3257 //            if (mReturnToExecuting)
3258 //            {
3259                 for( int port = VCAM_PORT_PREVIEW; port < VCAM_PORT_MAX; port++ )
3260                 {
3261                     if( mCurGreContext.mCameraPortParams[port].mIsActive )
3262                         startPreview( (VisionCamPort_e)port );
3263                 }
3264 //            }
3265             break;
3266         }
3268         case VCAM_PREEMPT_WAIT_TO_START:
3269         {
3270             if( mClientNotifier.mNotificationCallback && OMX_ErrorNone == omxError )
3271                 mClientNotifier.mNotificationCallback(VisionCamClientNotifier::VCAM_MESSAGE_PREEMPT_WAIT_RESOURCES);
3273             // Register for WAIT state switch event
3274             omxError = RegisterForEvent(mCurGreContext.mHandleComp,
3275                                            OMX_EventCmdComplete,
3276                                            OMX_CommandStateSet,
3277                                            OMX_StateWaitForResources,
3278                                            &mGreLocalSem,
3279                                            -1); // Infinite timeout
3281            if( OMX_ErrorNone == omxError  )
3282            {
3283                omxError = OMX_SendCommand(mCurGreContext.mHandleComp,
3284                                              OMX_CommandStateSet,
3285                                              OMX_StateWaitForResources,
3286                                              NULL);
3287            }
3289            if( OMX_ErrorNone == omxError  )
3290                sem_wait(&mGreLocalSem);
3292            // Register for WAIT state switch event
3293            omxError = RegisterForEvent(mCurGreContext.mHandleComp,
3294                                           OMX_EventResourcesAcquired,
3295                                           0,
3296                                           0,
3297                                           &mGreLocalSem,
3298                                           -1); // Infinite timeout
3300            if( OMX_ErrorNone == omxError  )
3301                sem_wait(&mGreLocalSem);
3303            if( mClientNotifier.mNotificationCallback && OMX_ErrorNone == omxError )
3304                mClientNotifier.mNotificationCallback(VisionCamClientNotifier::VCAM_MESSAGE_PREAMPT_REASOURCES_READY);
3306             break;
3307         }
3308         default:
3310             break;
3311     }
3313     if( OMX_ErrorNone == omxError  )
3314         mPreemptionState = VCAM_PREEMPT_INACTIVE;
3316     return ConvertError(omxError);
3319 OMX_ERRORTYPE OMXVisionCam::RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,
3320                                              OMX_IN OMX_EVENTTYPE eEvent,
3321                                              OMX_IN OMX_U32 nData1,
3322                                              OMX_IN OMX_U32 nData2,
3323                                              OMX_IN sem_t *semaphore,
3324                                              OMX_IN OMX_U32 timeout)
3326     OMXVCAM_Msg_t *msg = (OMXVCAM_Msg_t *)calloc(1, sizeof(OMXVCAM_Msg_t));
3327     OMX_ERRORTYPE err = OMX_ErrorNone;
3328     if (msg)
3329     {
3330         msg->eEvent = eEvent;
3331         msg->nData1 = nData1;
3332         msg->nData2 = nData2;
3333         msg->semaphore = semaphore;
3334         msg->hComponent = hComponent;
3335         msg->timeout = timeout;
3336         mEventSignalQ.push_back(msg);
3337         MSG("Registering for Event %d (0x%08x)", eEvent,eEvent);
3338     }
3339     else
3340     {
3341         err = OMX_ErrorInsufficientResources;
3342     }
3343     return err;
3347 extern "C" int node_compare_vcam_msg(void* a, void* b)
3349     OMXVCAM_Msg_t *msgA = (OMXVCAM_Msg_t *)a;
3350     OMXVCAM_Msg_t *msgB = (OMXVCAM_Msg_t *)b;
3352     MSG("Comparing Node %p and Node %p",msgA, msgB);
3354     if (msgA->eEvent == msgB->eEvent &&
3355         msgA->nData1 == msgB->nData1 &&
3356         msgA->nData2 == msgB->nData2 &&
3357         msgA->hComponent == msgB->hComponent)
3358         return 0;
3359     else if (msgA->eEvent < msgB->eEvent)
3360         return -1;
3361     else // if (msgA->event > msgB->event)
3362         return 1;
3365 /** OMXVisionCam Event Handler from OMX-CAMERA */
3366 OMX_ERRORTYPE OMXVisionCam::EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
3367                                          OMX_IN OMX_PTR pAppData,
3368                                          OMX_IN OMX_EVENTTYPE eEvent,
3369                                          OMX_IN OMX_U32 nData1,
3370                                          OMX_IN OMX_U32 nData2,
3371                                          OMX_IN OMX_PTR pEventData)
3373     // make a local pointer to the instance class which registered this callback.
3374     OMXVisionCam *pOMXCam = (OMXVisionCam*)pAppData;
3375     size_t len = pOMXCam->mEventSignalQ.size();
3377     MSG("OMXVisionCam::EventHandler() event=%d arg1=%08x arg2=%08x ptr=%p (len=%zu)", eEvent, (uint32_t)nData1, (uint32_t)nData2, pEventData, len);
3378     // check the queue to see if we were waiting on an event
3379     if (len > 0)
3380     {
3381         OMXVCAM_Msg_t* msg = NULL;
3382         std::list<OMXVCAM_Msg_t*>::iterator it;
3383         for (it = pOMXCam->mEventSignalQ.begin(); it != pOMXCam->mEventSignalQ.end(); ++it) {
3384           if ((*it)->eEvent > eEvent) {
3385             break;
3386           }
3387           if (((*it)->eEvent == eEvent) &&
3388               ((*it)->nData1 == nData1) &&
3389               ((*it)->nData2 == nData2) &&
3390               ((*it)->hComponent == hComponent)) {
3391             msg = *it;
3392             break;
3393           }
3394         }
3396         // find the list event which matches this event
3397         if (msg != NULL)
3398         {
3399             MSG("Found Event in List which matches incoming event!");
3400             if (msg->semaphore)
3401                 sem_post(msg->semaphore);
3403             pOMXCam->mEventSignalQ.erase(it);
3404             free(msg);
3405         }
3406         else
3407         {
3408             MSG("No matching event found in list!");
3409         }
3410     }
3412     switch( eEvent )
3413     {
3414         case OMX_EventError:
3415         {
3416             switch( nData1 )
3417             {
3418                 case OMX_ErrorResourcesPreempted:
3419                     break;
3420                 case OMX_ErrorResourcesLost:
3421                 {
3422                     pthread_t thread;
3423                     ERROR("OMXVisionCam lost resources!");
3424                     pOMXCam->mPreemptionState = VCAM_PREEMPT_SUSPEND;
3425                     pthread_create(&thread, NULL, PreemptionThreadLauncher, pOMXCam);
3426                     break;
3427                 }
3428                 case OMX_ErrorInsufficientResources:
3429                 {
3430                     pthread_t thread;
3431                     ERROR("OMXVisionCam has insufficient resources!");
3432                     pOMXCam->mPreemptionState = VCAM_PREEMPT_SUSPEND;
3433                     pthread_create(&thread, NULL, PreemptionThreadLauncher, pOMXCam);
3434                     break;
3435                 }
3436                 case OMX_ErrorIncorrectStateOperation:
3437                 {
3438                     break;
3439                 }
3440                 case OMX_ErrorInvalidState:
3441                 {
3442                     break;
3443                 }
3444                 default:
3446                     break;
3447             }
3448             break;
3449         }
3450         case OMX_EventResourcesAcquired:
3451         {
3452             break;
3453         }
3454         case OMX_EventCmdComplete:
3455         {
3456             switch (nData1)
3457             {
3458                 case OMX_CommandStateSet:
3459                     PrintOMXState((OMX_STATETYPE)nData2);
3460                     break;
3461                 case OMX_CommandFlush:
3462                 case OMX_CommandPortDisable:
3463                 case OMX_CommandPortEnable:
3464                     break;
3465             }
3466             break;
3467         }
3468         case OMX_EventPortSettingsChanged:
3469         case OMX_EventIndexSettingChanged:
3470             MSG("*** Port/Index Settings have Changed!");
3471             break;
3472         default:
3473           break;
3474     }
3475     return OMX_ErrorNone;
3478 //GRE Empty buffer done callback
3479 OMX_ERRORTYPE OMXVisionCam::EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
3480                                              OMX_IN OMX_PTR pAppData,
3481                                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
3483 //     OMXVisionCam *pOMXCam = (OMXVisionCam *)pAppData;
3484     pAppData = pAppData;
3485     hComponent = hComponent;
3486     pBuffHeader = pBuffHeader;
3487     return OMX_ErrorNotImplemented;
3490 //GRE fill buffer done callback
3491 OMX_ERRORTYPE OMXVisionCam::FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
3492                                             OMX_IN OMX_PTR pAppData,
3493                                             OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) {
3494     OMXVisionCam* pCam = static_cast<OMXVisionCam*>(pAppData);
3495     MSG("OMX-CAMERA has returned a frame (%p) offset=%lu!", pBuffHeader->pAppPrivate, pBuffHeader->nOffset);
3496     pCam->mFrameCbData.frames.push_back(pBuffHeader);
3497     pthread_mutex_unlock(&pCam->mFrameCbData.mutex);
3498     return OMX_ErrorNone;
3501 void OMXVisionCam::frameReceivedSrvc(void *data)
3503     OMX_BUFFERHEADERTYPE* pBuffHeader = (OMX_BUFFERHEADERTYPE* )data;
3504     VisionCamFrame *cFrame = NULL;
3505     VisionCamPort_e portInd = VCAM_PORT_MAX;
3507     if( !data )
3508     {
3509         return;
3510     }
3512     if( mFlushInProcess )
3513     {
3514         return;
3515     }
3517     AutoLock lock(&mFrameBufferLock);
3519     switch(pBuffHeader->nOutputPortIndex)
3520     {
3521         case VCAM_CAMERA_PORT_VIDEO_OUT_PREVIEW:
3522         {
3523             portInd = VCAM_PORT_PREVIEW;
3524             break;
3525         }
3526         case VCAM_CAMERA_PORT_VIDEO_OUT_VIDEO:
3527         {
3528             portInd = VCAM_PORT_VIDEO;
3529             break;
3530         }
3531         default:
3532         {
3533             portInd = VCAM_PORT_MAX;
3534             break;
3535         }
3536     }
3538     if( portInd > VCAM_PORT_ALL && portInd < VCAM_PORT_MAX && mCurGreContext.mCameraPortParams[portInd].mIsActive )
3539     {
3540         // find the frame descriptor corresponding to received buffer
3541         for( int i = 0; i < mCurGreContext.mCameraPortParams[portInd].mNumBufs; i++ )
3542         {
3543             if( mFrameDescriptors[portInd][i]->mFrameBuff == pBuffHeader->pAppPrivate )
3544             {
3545                 cFrame = mFrameDescriptors[portInd][i];
3546                 break;
3547             }
3548         }
3549     }
3551     if( cFrame )
3552     {
3553         cFrame->mFrameSource     = portInd;
3554         cFrame->mLength          = pBuffHeader->nFilledLen;
3555         cFrame->mTimestamp       = pBuffHeader->nTimeStamp;
3556         cFrame->mWidth           = mCurGreContext.mCameraPortParams[portInd].mWidth;
3557         cFrame->mHeight          = mCurGreContext.mCameraPortParams[portInd].mHeight;
3558         cFrame->mCookie          = m_cookie;
3559         cFrame->mContext         = this;
3560         cFrame->mMetadata.mAutoWBGains = NULL;
3561         cFrame->mMetadata.mManualWBGains = NULL;
3562         cFrame->mMetadata.mAncillary = NULL;
3563         cFrame->mMetadata.mHistogram2D = NULL;
3564         cFrame->mMetadata.mHistogramL = NULL;
3565         cFrame->mMetadata.mHistogramR = NULL;
3566         cFrame->mExtraDataBuf    = NULL;
3567         cFrame->mExtraDataLength = 0;
3568         cFrame->mDetectedFacesNum = 0;
3569         memset( cFrame->mFaces, 0, MAX_FACES_COUNT * sizeof(VisionCamFaceType) );
3571         if( VCAM_PORT_PREVIEW == cFrame->mFrameSource )
3572             m_frameNum++;
3574         if (m_callback != NULL)
3575         {
3576             m_callback(cFrame);
3577         }
3578     }
3579     else
3580     {
3581         ERROR("ERROR: a frame buffer is received, but there is no matching buffer." );
3582     }
3585 #if TIME_PROFILE
3586 void OMXVisionCam::PopulateTimeProfiler()
3588     mTimeProfiler[ first ] = new VisionCamTimePtofile("first");
3589     mTimeProfiler[ second ] = new VisionCamTimePtofile();
3590     mTimeProfiler[ last ] = new VisionCamTimePtofile();
3593 VisionCamTimePtofile::VisionCamTimePtofile( const char * name ){
3594   memset( &mStart, 0, sizeof(struct timeval) );
3595   memset( &mEnd, 0, sizeof(struct timeval) );
3597   if( name )
3598     mName = name;
3599   else
3600     mName = "unknown";
3601 };
3603 VisionCamTimePtofile::~VisionCamTimePtofile(){
3604     dump();
3605 };
3607 void VisionCamTimePtofile::dump() {
3608     if( mEnd.tv_usec && mStart.tv_usec )
3609     {
3610         double time = (double)(mEnd.tv_usec = mStart.tv_usec) / (double)1000;
3611         printf("TIME: %s - %g [ms]\r", mName, time );
3612         memset( &mStart, 0, sizeof(struct timeval) );
3613         memset( &mEnd, 0, sizeof(struct timeval) );
3614     }
3617 #endif // TIME_PROFILE